diff --git a/UnblockNeteaseMusic-Go/Makefile b/UnblockNeteaseMusic-Go/Makefile new file mode 100644 index 00000000..04b69b24 --- /dev/null +++ b/UnblockNeteaseMusic-Go/Makefile @@ -0,0 +1,83 @@ +# SPDX-Identifier-License: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=UnblockNeteaseMusic-Go +PKG_VERSION:=0.2.13 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/cnsilvan/UnblockNeteaseMusic/tar.gz/$(PKG_VERSION)? +PKG_HASH:=92201b7f04ab1015c806c672b98a29b97d0f137d9b60e6d35d279c2064ed86a4 + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_CONFIG_DEPENDS:= \ + CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_GOPROXY \ + CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_UPX + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(firstword $(subst -, ,$(PKG_NAME)))-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=golang/host upx/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/cnsilvan/UnblockNeteaseMusic +GO_PKG_BUILD_PKG:=$$(GO_PKG) +GO_PKG_LDFLAGS:=-s -w +COMPILE_TIME:= $(shell TZ=UTC-8 date '+%Y-%m-%d %H:%M:%S') +GO_PKG_LDFLAGS+= \ + -X '$(GO_PKG)/version.Version=$(PKG_VERSION)' \ + -X '$(GO_PKG)/version.BuildTime=$(COMPILE_TIME)' \ + -X '$(GO_PKG)/version.ExGoVersionInfo=$(GO_ARM) $(GO_MIPS)$(GO_MIPS64)' + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/UnblockNeteaseMusic-Go/config +config UNBLOCKNETEASEMUSIC_GO_COMPRESS_GOPROXY + bool "Compiling with GOPROXY proxy" + default n + +config UNBLOCKNETEASEMUSIC_GO_COMPRESS_UPX + bool "Compress executable files with UPX" + depends on !mips64 + default n +endef + +ifeq ($(CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_GOPROXY),y) + export GO111MODULE=on + export GOPROXY=https://goproxy.io +endif + +define Package/UnblockNeteaseMusic-Go + SECTION:=multimedia + CATEGORY:=Multimedia + TITLE:=Revive Netease Cloud Music (Golang) + URL:=https://github.com/cnsilvan/UnblockNeteaseMusic + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Build/Compile + $(call GoPackage/Build/Compile) +ifeq ($(CONFIG_UNBLOCKNETEASEMUSIC_GO_COMPRESS_UPX),y) + $(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/UnblockNeteaseMusic +endif +endef + +define Package/UnblockNeteaseMusic-Go/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/UnblockNeteaseMusic $(1)/usr/bin/UnblockNeteaseMusic + + $(INSTALL_DIR) $(1)/usr/share/UnblockNeteaseMusicGo + $(CP) ./files/* $(1)/usr/share/UnblockNeteaseMusicGo/ + +endef + +$(eval $(call GoBinPackage,UnblockNeteaseMusic-Go)) +$(eval $(call BuildPackage,UnblockNeteaseMusic-Go)) diff --git a/UnblockNeteaseMusic-Go/files/ca.crt b/UnblockNeteaseMusic-Go/files/ca.crt new file mode 100644 index 00000000..bea3f7b0 --- /dev/null +++ b/UnblockNeteaseMusic-Go/files/ca.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICIjCCAaigAwIBAgIUTc9HQDej5hLCQ74u436a5yE4MDcwCgYIKoZIzj0EAwMw +SDELMAkGA1UEBhMCQ04xJDAiBgNVBAMMG1VuYmxvY2tOZXRlYXNlTXVzaWMgUm9v +dCBDQTETMBEGA1UECgwKMTcxNTE3MzMyOTAeFw0yMTA0MzAwNzIzMDJaFw0yNjA0 +MjkwNzIzMDJaMEgxCzAJBgNVBAYTAkNOMSQwIgYDVQQDDBtVbmJsb2NrTmV0ZWFz +ZU11c2ljIFJvb3QgQ0ExEzARBgNVBAoMCjE3MTUxNzMzMjkwdjAQBgcqhkjOPQIB +BgUrgQQAIgNiAASIyI7lYgGlq49qWtY1O2/XNDeowYf7W/Z+l7C14bphxAJ9jSDo +tLwbFPWy5VPENc0rB0/yeHA2z7LU67POL2gGgp+17y7scLkkBk3Q7wRMETrtP44Z +ITBstZ0wzVyyQEKjUzBRMB0GA1UdDgQWBBQ2F7+t8cPHJaWuCD8RHTSdLugKYzAf +BgNVHSMEGDAWgBQ2F7+t8cPHJaWuCD8RHTSdLugKYzAPBgNVHRMBAf8EBTADAQH/ +MAoGCCqGSM49BAMDA2gAMGUCMQDqaRX2e01e0U+f0As/KUKDhmG5ElkK5CjYK9jk +kXLNGFXJLGta6CDvjtMLBPc20qkCMBvDs+JnJKVBEJNZVsRBBs+v2YxNU/u2aYJa +dMwXuFveSDWOS7mBeRztX/geEggiSw== +-----END CERTIFICATE----- diff --git a/UnblockNeteaseMusic-Go/files/server.crt b/UnblockNeteaseMusic-Go/files/server.crt new file mode 100644 index 00000000..73e2fa6e --- /dev/null +++ b/UnblockNeteaseMusic-Go/files/server.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRDCCAcqgAwIBAgIUeVqRrT2mHG5Mc8JD+ErphiAmlgkwCgYIKoZIzj0EAwMw +SDELMAkGA1UEBhMCQ04xJDAiBgNVBAMMG1VuYmxvY2tOZXRlYXNlTXVzaWMgUm9v +dCBDQTETMBEGA1UECgwKMTcxNTE3MzMyOTAeFw0yMTA0MzAwNzIzMDJaFw0yMjA0 +MzAwNzIzMDJaMHsxCzAJBgNVBAYTAkNOMREwDwYDVQQHDAhIYW5nemhvdTEsMCoG +A1UECgwjTmV0RWFzZSAoSGFuZ3pob3UpIE5ldHdvcmsgQ28uLCBMdGQxETAPBgNV +BAsMCElUIERlcHQuMRgwFgYDVQQDDA8qLm11c2ljLjE2My5jb20wdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAQTPyU9RQ1pAFMLmozi+c4pEC1rrxAlPGwO9Em+qV+a5qLW +gQjjsJeabMqJ/UQ7hDtdKVxWuXiAjMiDcXwL63I71MZKPTAEKXdCmNQwb4kXvRUn +oOR4r7BMxEpGlf0CULWjQjBAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMCkGA1UdEQQi +MCCCDW11c2ljLjE2My5jb22CDyoubXVzaWMuMTYzLmNvbTAKBggqhkjOPQQDAwNo +ADBlAjEAs5bdgnNP/DiK919RiWscC0kyuY0ugG1C8m8F2Yod4MI3oTyrkVcag21o +NSzm802uAjBoPuKEbjjFP4ics0BQdICiVd6WCVAsE69FnlmqRteAJqxvdKGpVLi+ +Qi3arfomrrc= +-----END CERTIFICATE----- diff --git a/UnblockNeteaseMusic-Go/files/server.key b/UnblockNeteaseMusic-Go/files/server.key new file mode 100644 index 00000000..6bd769c1 --- /dev/null +++ b/UnblockNeteaseMusic-Go/files/server.key @@ -0,0 +1,9 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBfW3twxGaQmMzP9p0/UU5EvHFVCbBw4piVFJ+pm/uFY6CKZkC5LGMa +Uc9vn/KiewGgBwYFK4EEACKhZANiAAQTPyU9RQ1pAFMLmozi+c4pEC1rrxAlPGwO +9Em+qV+a5qLWgQjjsJeabMqJ/UQ7hDtdKVxWuXiAjMiDcXwL63I71MZKPTAEKXdC +mNQwb4kXvRUnoOR4r7BMxEpGlf0CULU= +-----END EC PRIVATE KEY----- \ No newline at end of file diff --git a/UnblockNeteaseMusic-Go/patches/01-fix-block-ad.patch b/UnblockNeteaseMusic-Go/patches/01-fix-block-ad.patch new file mode 100644 index 00000000..3aa24d70 --- /dev/null +++ b/UnblockNeteaseMusic-Go/patches/01-fix-block-ad.patch @@ -0,0 +1,144 @@ +From f4f5d11b578a1ab2c3d089bbe5453052b43892bb Mon Sep 17 00:00:00 2001 +From: tofuliang +Date: Mon, 24 Jan 2022 18:53:11 +0800 +Subject: [PATCH] fix block ad,add web traffic logs + +--- + app.go | 1 + + config/config.go | 1 + + processor/processor.go | 55 +++++++++++++++++++++++++++++++++--------- + 3 files changed, 45 insertions(+), 12 deletions(-) + +diff --git a/app.go b/app.go +index 73a6070..1018d75 100644 +--- a/app.go ++++ b/app.go +@@ -45,6 +45,7 @@ func main() { + log.Println("EnableLocalVip=", *config.EnableLocalVip) + log.Println("UnlockSoundEffects=", *config.UnlockSoundEffects) + log.Println("QQCookieFile=", *config.QQCookieFile) ++ log.Println("LogWebTraffic=", *config.LogWebTraffic) + if host.InitHosts() == nil { + //go func() { + // // // terminal: $ go tool pprof -http=:8081 http://localhost:6060/debug/pprof/heap +diff --git a/config/config.go b/config/config.go +index 6c07873..a653cdf 100644 +--- a/config/config.go ++++ b/config/config.go +@@ -31,6 +31,7 @@ var ( + EnableLocalVip = flag.Bool("lv", false, "enable local vip") + UnlockSoundEffects = flag.Bool("sef", false, "unlock SoundEffects") + QQCookieFile = flag.String("qc", "./qq.cookie", "specify cookies file ,such as : \"qq.cookie\"") ++ LogWebTraffic = flag.Bool("wl", false, "log request url and response") + ) + + func ValidParams() bool { +diff --git a/processor/processor.go b/processor/processor.go +index 8d09dbf..d07b9d3 100644 +--- a/processor/processor.go ++++ b/processor/processor.go +@@ -6,14 +6,6 @@ import ( + "crypto/md5" + "encoding/hex" + "encoding/json" +- "github.com/cnsilvan/UnblockNeteaseMusic/cache" +- "github.com/cnsilvan/UnblockNeteaseMusic/common" +- "github.com/cnsilvan/UnblockNeteaseMusic/config" +- "github.com/cnsilvan/UnblockNeteaseMusic/network" +- "github.com/cnsilvan/UnblockNeteaseMusic/processor/crypto" +- "github.com/cnsilvan/UnblockNeteaseMusic/provider" +- "github.com/cnsilvan/UnblockNeteaseMusic/utils" +- "golang.org/x/text/width" + "io" + "io/ioutil" + "log" +@@ -22,6 +14,15 @@ import ( + "regexp" + "strconv" + "strings" ++ ++ "github.com/cnsilvan/UnblockNeteaseMusic/cache" ++ "github.com/cnsilvan/UnblockNeteaseMusic/common" ++ "github.com/cnsilvan/UnblockNeteaseMusic/config" ++ "github.com/cnsilvan/UnblockNeteaseMusic/network" ++ "github.com/cnsilvan/UnblockNeteaseMusic/processor/crypto" ++ "github.com/cnsilvan/UnblockNeteaseMusic/provider" ++ "github.com/cnsilvan/UnblockNeteaseMusic/utils" ++ "golang.org/x/text/width" + ) + + var ( +@@ -188,6 +189,9 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea + if ok { + code = codeN.String() + } ++ ++ logResponse(netease) ++ + if strings.EqualFold(netease.Path, "/api/osx/version") { + modified = disableUpdate(netease) + } else if strings.Contains(netease.Path, "/usertool/sound/") { +@@ -197,9 +201,24 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea + for key, resp := range netease.JsonBody { + if strings.Contains(key, "/usertool/sound/") { + modified = unblockSoundEffects(resp.(map[string]interface{})) +- } else if *config.BlockAds && strings.Contains(netease.Path, "api/ad/") { ++ } else if *config.BlockAds && strings.Contains(key, "api/ad/") { ++ log.Println("block Ad has been triggered(" + key + ").") + resp = &common.MapType{} + modified = true ++ } else if *config.BlockAds && strings.EqualFold(key, "/api/v2/banner/get") { ++ newInfo := make(common.SliceType, 0) ++ info := netease.JsonBody[key] ++ for _, data := range info.(common.MapType)["banners"].(common.SliceType) { ++ if banner, ok := data.(common.MapType); ok { ++ if banner["adid"] == nil { ++ newInfo = append(newInfo, banner) ++ } else { ++ log.Println("block banner Ad has been triggered.") ++ modified = true ++ } ++ } ++ } ++ info.(common.MapType)["banners"] = newInfo + } + } + } else if !netease.Web && (code == "401" || code == "512") && strings.Contains(netease.Path, "manipulate") { +@@ -220,7 +239,9 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea + // log.Println("NeedRepackage") + modifiedJson, _ := json.Marshal(netease.JsonBody) + // log.Println(netease) +- // log.Println(string(modifiedJson)) ++ if *config.LogWebTraffic { ++ log.Println("modified =>\n" + string(modifiedJson)) ++ } + if netease.Encrypted { + modifiedJson = crypto.AesEncryptECB(modifiedJson, []byte(aeskey)) + } +@@ -258,14 +279,24 @@ func disableUpdate(netease *Netease) bool { + if len(value.(common.SliceType)) > 0 { + modified = true + jsonBody["updateFiles"] = make(common.SliceType, 0) ++ log.Println("disable update has been triggered.") + } + default: + } + } +- // modifiedJson, _ := json.Marshal(jsonBody) +- // log.Println(string(modifiedJson)) + return modified + } ++ ++func logResponse(netease *Netease) { ++ if *config.LogWebTraffic { ++ reqUrl := netease.Path ++ jsonBody := netease.JsonBody ++ modifiedJson, _ := json.Marshal(jsonBody) ++ sep := "===================================\n" ++ log.Println(sep + reqUrl + " => \n" + string(modifiedJson) + "\n") ++ } ++} ++ + func localVIP(netease *Netease) bool { + if !*config.EnableLocalVip { + return false diff --git a/UnblockNeteaseMusic-Go/patches/02-avoid-unnecessary-decryption.patch b/UnblockNeteaseMusic-Go/patches/02-avoid-unnecessary-decryption.patch new file mode 100644 index 00000000..ad2e8db7 --- /dev/null +++ b/UnblockNeteaseMusic-Go/patches/02-avoid-unnecessary-decryption.patch @@ -0,0 +1,29 @@ +From 6c009953d357d1cc03478cf65fc05701fb1966d6 Mon Sep 17 00:00:00 2001 +From: ameansone +Date: Sun, 5 Dec 2021 19:18:20 +0800 +Subject: [PATCH] fix(processor): avoid unnecessary decryption + +--- + processor/processor.go | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/processor/processor.go b/processor/processor.go +index 8d09dbf..011571b 100644 +--- a/processor/processor.go ++++ b/processor/processor.go +@@ -177,9 +177,13 @@ func RequestAfter(request *http.Request, response *http.Response, netease *Netea + if netease.Forward { + aeskey = linuxApiKey + } +- decryptECBBytes, encrypted := crypto.AesDecryptECB(decryptECBBytes, []byte(aeskey)) +- netease.Encrypted = encrypted + result := utils.ParseJson(decryptECBBytes) ++ netease.Encrypted = false; ++ if result == nil { ++ decryptECBBytes, encrypted := crypto.AesDecryptECB(decryptECBBytes, []byte(aeskey)) ++ netease.Encrypted = encrypted ++ result = utils.ParseJson(decryptECBBytes) ++ } + netease.JsonBody = result + + modified := false diff --git a/UnblockNeteaseMusic/Makefile b/UnblockNeteaseMusic/Makefile new file mode 100644 index 00000000..8ac09ff3 --- /dev/null +++ b/UnblockNeteaseMusic/Makefile @@ -0,0 +1,47 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=UnblockNeteaseMusic +PKG_VERSION:=0.28.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/UnblockNeteaseMusic/server/tar.gz/v${PKG_VERSION}? +PKG_HASH:=0a1e843ffaa7b8ce65cc221daec07b63754473f0430019acb228f5b254602318 + +PKG_SOURCE_SUBDIR:=$(PKG_NAME) +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/UnblockNeteaseMusic + SECTION:=multimedia + CATEGORY:=Multimedia + TITLE:=Revive Netease Cloud Music (NodeJS) + URL:=https://github.com/nondanee/UnblockNeteaseMusic + DEPENDS:=+node + PKGARCH:=all +endef + +define Package/$(PKG_NAME)/description +Revive Netease Cloud Music (NodeJS) +endef + +define Build/Prepare + tar -xzvf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) + mkdir -p $(PKG_BUILD_DIR)/$(PKG_NAME) + echo -e $(PKG_VERSION) > $(PKG_BUILD_DIR)/$(PKG_NAME)/core_ver +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/share/$(PKG_NAME) + $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)/* $(1)/usr/share/$(PKG_NAME) +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/alist/Makefile b/alist/Makefile new file mode 100644 index 00000000..87d427d3 --- /dev/null +++ b/alist/Makefile @@ -0,0 +1,96 @@ +# +# Copyright (C) 2015-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=alist +PKG_VERSION:=3.60.0 +PKG_WEB_VERSION:=3.60.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/AlistGo/alist/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=beccffdfba65a168e796a1789b6bea11ca225101cbc4276451e02b9ad8751a82 + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=sbwml + +define Download/$(PKG_NAME)-web + FILE:=$(PKG_NAME)-web-$(PKG_WEB_VERSION).tar.gz + URL_FILE:=dist.tar.gz + URL:=https://github.com/AlistGo/alist-web/releases/download/$(PKG_WEB_VERSION)/ +HASH:=35c4a218fce07c9ef5113b70ec93e385c57c2910de8852b2d0973129c12b0843 +endef + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/AlistGo/alist +GO_PKG_LDFLAGS:= \ + -X '$(GO_PKG)/v3/internal/conf.BuiltAt=$(shell date '+%Y-%m-%d %H:%M:%S %z')' \ + -X '$(GO_PKG)/v3/internal/conf.GoVersion=$(shell $(STAGING_DIR_HOSTPKG)/bin/go version | sed 's/go version //')' \ + -X '$(GO_PKG)/v3/internal/conf.GitAuthor=Xhofe ' \ + -X '$(GO_PKG)/v3/internal/conf.GitCommit=tarball/$(shell echo $(PKG_HASH) | cut -c 1-7)' \ + -X '$(GO_PKG)/v3/internal/conf.Version=v$(PKG_VERSION) (OpenWrt $(ARCH_PACKAGES))' \ + -X '$(GO_PKG)/v3/internal/conf.WebVersion=$(PKG_WEB_VERSION)' + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=A file list program that supports multiple storage + URL:=https://alist.nn.ci/ + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/$(PKG_NAME)/conffiles +/etc/alist +/etc/config/alist +endef + +define Package/$(PKG_NAME)/description + A file list program that supports multiple storage, powered by Gin and Solidjs. +endef + +ifeq ($(ARCH),arm) + ARM_CPU_FEATURES:=$(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE)))) + ifeq ($(ARM_CPU_FEATURES),) + TARGET_CFLAGS:= + TARGET_LDFLAGS:= + endif +endif + +ifneq ($(CONFIG_USE_MUSL),) + TARGET_CFLAGS += -D_LARGEFILE64_SOURCE +endif + +define Build/Prepare + $(call Build/Prepare/Default) + $(TAR) --strip-components=1 -C $(PKG_BUILD_DIR)/public/dist -xzf $(DL_DIR)/$(PKG_NAME)-web-$(PKG_WEB_VERSION).tar.gz + $(SED) 's_https://jsd.nn.ci/gh/alist-org/logo@main/logo.png_/assets/logo.png_g' $(PKG_BUILD_DIR)/public/dist/index.html +ifneq ($(CONFIG_ARCH_64BIT),y) + $(RM) -rf $(PKG_BUILD_DIR)/drivers/{lark,lark.go} +endif +endef + +define Package/$(PKG_NAME)/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/alist $(1)/usr/bin + $(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d $(1)/etc/alist + $(INSTALL_CONF) $(CURDIR)/files/alist.config $(1)/etc/config/alist + $(INSTALL_BIN) $(CURDIR)/files/alist.init $(1)/etc/init.d/alist + $(INSTALL_DATA) $(CURDIR)/files/data.db $(1)/etc/alist/data.db +endef + +$(eval $(call Download,$(PKG_NAME)-web)) +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/alist/files/alist.config b/alist/files/alist.config new file mode 100644 index 00000000..bca32f59 --- /dev/null +++ b/alist/files/alist.config @@ -0,0 +1,31 @@ + +config alist + option enabled '0' + option port '5244' + option delayed_start '0' + option allow_wan '0' + option force '1' + option token_expires_in '48' + option max_connections '0' + option tls_insecure_skip_verify '1' + option data_dir '/etc/alist' + option temp_dir '/tmp/alist' + option log '1' + option log_max_size '10' + option log_max_backups '5' + option log_max_age '28' + option log_compress '0' + option database_type 'sqlite3' + option ssl '0' + option download_workers '5' + option download_max_retry '1' + option transfer_workers '5' + option transfer_max_retry '2' + option upload_workers '5' + option upload_max_retry '0' + option copy_workers '5' + option copy_max_retry '2' + option cors_allow_origins '*' + option cors_allow_methods '*' + option cors_allow_headers '*' + option s3 '0' diff --git a/alist/files/alist.init b/alist/files/alist.init new file mode 100755 index 00000000..dc98bc7f --- /dev/null +++ b/alist/files/alist.init @@ -0,0 +1,246 @@ +#!/bin/sh /etc/rc.common + +. /usr/share/libubox/jshn.sh + +START=99 +USE_PROCD=1 +PROG=/usr/bin/alist +LOG_FILE=/var/log/alist.log + +get_config() { + config_get_bool enabled $1 enabled 1 + config_get port $1 port 5244 + config_get allow_wan $1 allow_wan 0 + config_get delayed_start $1 delayed_start 0 + + config_get force $1 force 1 + config_get site_url $1 site_url "" + config_get cdn $1 cdn "" + config_get jwt_secret $1 jwt_secret "" + config_get data_dir $1 data_dir "/etc/alist" + config_get temp_dir $1 temp_dir "/tmp/alist" + config_get token_expires_in $1 token_expires_in 48 + config_get max_connections $1 max_connections 0 + config_get tls_insecure_skip_verify $1 tls_insecure_skip_verify 1 + + # log + config_get log $1 log 1 + config_get log_max_size $1 log_max_size 10 + config_get log_max_backups $1 log_max_backups 5 + config_get log_max_age $1 log_max_age 28 + config_get log_compress $1 log_compress 0 + + # scheme + config_get ssl $1 ssl 0 + config_get force_https $1 force_https 0 + config_get ssl_cert $1 ssl_cert "" + config_get ssl_key $1 ssl_key "" + + # database + config_get database_type $1 database_type "sqlite3" + config_get mysql_host $1 mysql_host "" + config_get mysql_port $1 mysql_port "3306" + config_get mysql_username $1 mysql_username "" + config_get mysql_password $1 mysql_password "" + config_get mysql_database $1 mysql_database "" + config_get mysql_table_prefix $1 mysql_table_prefix "x_" + config_get mysql_ssl_mode $1 mysql_ssl_mode "" + config_get mysql_dsn $1 mysql_dsn "" + + # tasks + config_get download_workers $1 download_workers 5 + config_get download_max_retry $1 download_max_retry 1 + config_get transfer_workers $1 transfer_workers 5 + config_get transfer_max_retry $1 transfer_max_retry 2 + config_get upload_workers $1 upload_workers 5 + config_get upload_max_retry $1 upload_max_retry 0 + config_get copy_workers $1 copy_workers 5 + config_get copy_max_retry $1 copy_max_retry 2 + + # cors + config_get cors_allow_origins $1 cors_allow_origins '*' + config_get cors_allow_methods $1 cors_allow_methods '*' + config_get cors_allow_headers $1 cors_allow_headers '*' + + # s3 + config_get s3 $1 s3 0 + config_get s3_port $1 s3_port 5246 + config_get s3_ssl $1 s3_ssl 0 + + config_load network + config_get lan_addr lan ipaddr "0.0.0.0" + if echo "${lan_addr}" | grep -Fq ' '; then + lan_addr="0.0.0.0" + else + lan_addr=${lan_addr%%/*} + fi + + # init jwt_secret + [ -z "$jwt_secret" ] && jwt_secret=$(tr -cd "a-zA-Z0-9" < "/dev/urandom" | head -c16) + uci -q set alist.@alist[0].jwt_secret="$jwt_secret" + uci commit alist +} + +set_firewall() { + if [ "$external_access" = "allow" ]; then + uci -q delete firewall.alist + uci set firewall.alist=rule + uci set firewall.alist.name="alist" + uci set firewall.alist.target="ACCEPT" + uci set firewall.alist.src="wan" + uci set firewall.alist.proto="tcp" + uci set firewall.alist.dest_port="$port" + uci set firewall.alist.enabled="1" + uci commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 + elif [ "$external_access" = "deny" ]; then + uci -q delete firewall.alist + uci commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 + fi +} + +start_service() { + config_load alist + config_foreach get_config alist + [ $enabled -ne 1 ] && return 1 + mkdir -p "$temp_dir" "$data_dir" + [ "$ssl" -eq 1 ] && https_port=$port http_port="-1" || https_port="-1" http_port=$port + if [ -e /proc/uptime ]; then + [ $(awk -F. '{print $1}' /proc/uptime) -lt "120" ] && delayed_start=$delayed_start || delayed_start=0 + else + delayed_start=$delayed_start + fi + if [ "$allow_wan" -eq "1" ]; then + listen_addr="0.0.0.0" + external_access="allow" + else + listen_addr=$lan_addr + external_access="deny" + fi + + set_firewall + > $LOG_FILE + + # init config + json_init + json_add_boolean "force" "$force" + json_add_string "site_url" "$site_url" + json_add_string "cdn" "$cdn" + json_add_string "jwt_secret" "$jwt_secret" + json_add_int "token_expires_in" "$token_expires_in" + + # database + json_add_object 'database' + json_add_string "type" "$database_type" + json_add_string "host" "$mysql_host" + json_add_int "port" "$mysql_port" + json_add_string "user" "$mysql_username" + json_add_string "password" "$mysql_password" + json_add_string "name" "$mysql_database" + json_add_string "db_file" "$data_dir/data.db" + json_add_string "table_prefix" "$mysql_table_prefix" + json_add_string "ssl_mode" "$mysql_ssl_mode" + json_add_string "dsn" "$mysql_dsn" + json_close_object + + # meilisearch + json_add_object "meilisearch" + json_add_string "host" "http://localhost:7700" + json_add_string "api_key" "" + json_add_string "index_prefix" "" + json_close_object + + # scheme + json_add_object "scheme" + json_add_string "address" "$listen_addr" + json_add_int "http_port" "$http_port" + json_add_int "https_port" "$https_port" + json_add_boolean "force_https" "$force_https" + json_add_string "cert_file" "$ssl_cert" + json_add_string "key_file" "$ssl_key" + json_add_string "unix_file" "" + json_add_string "unix_file_perm" "" + json_close_object + + json_add_string "temp_dir" "$temp_dir" + json_add_string "bleve_dir" "$data_dir/bleve" + json_add_string "dist_dir" "" + + # log + json_add_object "log" + json_add_boolean "enable" "$log" + json_add_string "name" "$LOG_FILE" + json_add_int "max_size" "$log_max_size" + json_add_int "max_backups" "$log_max_backups" + json_add_int "max_age" "$log_max_age" + json_add_boolean "compress" "$log_compress" + json_close_object + + json_add_int "delayed_start" "$delayed_start" + json_add_int "max_connections" "$max_connections" + json_add_boolean "tls_insecure_skip_verify" "$tls_insecure_skip_verify" + + # tasks + json_add_object "tasks" + json_add_object "download" + json_add_int "workers" "$download_workers" + json_add_int "max_retry" "$download_max_retry" + json_close_object + json_add_object "transfer" + json_add_int "workers" "$transfer_workers" + json_add_int "max_retry" "$transfer_max_retry" + json_close_object + json_add_object "upload" + json_add_int "workers" "$upload_workers" + json_add_int "max_retry" "$upload_max_retry" + json_close_object + json_add_object "copy" + json_add_int "workers" "$copy_workers" + json_add_int "max_retry" "$copy_max_retry" + json_close_object + json_close_object + + # cors + json_add_object "cors" + json_add_array "allow_origins" + json_add_string "" "$cors_allow_origins" + json_close_array + json_add_array "allow_methods" + json_add_string "" "$cors_allow_methods" + json_close_array + json_add_array "allow_headers" + json_add_string "" "$cors_allow_headers" + json_close_array + json_close_object + + # s3 + json_add_object "s3" + json_add_boolean "enable" "$s3" + json_add_int "port" "$s3_port" + json_add_boolean "ssl" "$s3_ssl" + json_close_object + + json_dump > "$data_dir/config.json" + + procd_open_instance alist + procd_set_param command $PROG + procd_append_param command server + procd_append_param command --data "$data_dir" + procd_set_param file "$data_dir/config.json" + procd_set_param stdout 0 + procd_set_param stderr 0 + procd_set_param respawn + procd_set_param limits core="unlimited" + procd_set_param limits nofile="200000 200000" + procd_close_instance alist +} + +service_triggers() { + procd_add_reload_trigger "alist" +} + +stop_service() { + external_access="deny" + set_firewall +} diff --git a/alist/files/data.db b/alist/files/data.db new file mode 100644 index 00000000..e1bb40dd Binary files /dev/null and b/alist/files/data.db differ diff --git a/alist/src/public/dist/assets/logo.svg b/alist/src/public/dist/assets/logo.svg new file mode 100644 index 00000000..37d5fdcd --- /dev/null +++ b/alist/src/public/dist/assets/logo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/baidupcs-go/Makefile b/baidupcs-go/Makefile new file mode 100644 index 00000000..52d7d2ce --- /dev/null +++ b/baidupcs-go/Makefile @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2009-2013 OpenWrt.org +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=BaiduPCS-Go +PKG_VERSION:=3.9.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/qjfoidnh/BaiduPCS-Go/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=de71666e961a3eeb90f8aca7b11934c3f0296d1870e036a7c086ba1decfca8ab + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/qjfoidnh/BaiduPCS-Go +GO_PKG_LDFLAGS_X:=main.Version=v$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/BaiduPCS-Go + SECTION:=net + CATEGORY:=Network + SUBMENU:=Download Manager + TITLE:=Terminal utility for Baidu Network Disk + URL:=https://github.com/qjfoidnh/BaiduPCS-Go + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/BaiduPCS-Go/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + + $(INSTALL_DIR) $(1)/usr/bin/ + $(CP) $(PKG_INSTALL_DIR)/usr/bin/BaiduPCS-Go $(1)/usr/bin/ +endef + +$(eval $(call GoBinPackage,BaiduPCS-Go)) +$(eval $(call BuildPackage,BaiduPCS-Go)) diff --git a/brlaser/Makefile b/brlaser/Makefile new file mode 100644 index 00000000..36c083bb --- /dev/null +++ b/brlaser/Makefile @@ -0,0 +1,57 @@ +# +# Copyright (C) 2006-2009 OpenWrt.org +# Copyright (C) 2005-2016 Weijie Gao +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=brlaser +PKG_VERSION:=v3 +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/pdewacht/brlaser.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=2a49e3287c70c254e7e3ac9dabe9d6a07218c3fa +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/brlaser + SECTION:=print + CATEGORY:=Printing and Imaging + TITLE:=Driver for (some) Brother laster printers + DEPENDS:=+libcupsimage +libstdcpp + MAINTAINER:=Weijie Gao + URL:=https://github.com/pdewacht/brlaser +endef + +define Package/brlaser/description + Driver for Brother DCP-7030 / Brother DCP-7055 / Brother DCP-7065DN +endef + +define Package/brlaser/install + $(INSTALL_DIR) $(1)/usr/lib/cups/filter + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/cups/filter/rastertobrlaser $(1)/usr/lib/cups/filter/ + + $(INSTALL_DIR) $(1)/usr/share/cups/drv + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/cups/drv/brlaser.drv $(1)/usr/share/cups/drv/ + + (cd $(PKG_BUILD_DIR) && ppdc brlaser.drv) + + $(INSTALL_DIR) $(1)/usr/share/ppd/Brother + $(CP) $(PKG_BUILD_DIR)/ppd/*.ppd $(1)/usr/share/ppd/Brother + + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/brlaser-set-cups-filter-permission $(1)/etc/uci-defaults/ +endef + +$(eval $(call BuildPackage,brlaser)) diff --git a/brlaser/files/brlaser-set-cups-filter-permission b/brlaser/files/brlaser-set-cups-filter-permission new file mode 100644 index 00000000..3d216177 --- /dev/null +++ b/brlaser/files/brlaser-set-cups-filter-permission @@ -0,0 +1,3 @@ +#!/bin/sh + +[ -d /usr/lib/cups/filter ] && chmod 0754 /usr/lib/cups/filter/* diff --git a/brook/Makefile b/brook/Makefile new file mode 100644 index 00000000..037b88ab --- /dev/null +++ b/brook/Makefile @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021-2023 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=brook +PKG_VERSION:=20260101.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/txthinking/brook/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=8ddba4ed9ae9d10928e169f8121c6791e0e3c2907fa27d6e0055fe434f6e700e + +PKG_MAINTAINER:=Tianling Shen +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/txthinking/brook +GO_PKG_BUILD_PKG:=$(GO_PKG)/cli/brook + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/brook + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=A cross-platform proxy software + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle + URL:=https://github.com/txthinking/brook +endef + +define Package/brook/description + Brook is a cross-platform strong encryption and not detectable proxy. + Zero-Configuration. +endef + +$(eval $(call GoBinPackage,brook)) +$(eval $(call BuildPackage,brook)) diff --git a/chinadns-ng/Makefile b/chinadns-ng/Makefile new file mode 100644 index 00000000..5c2162ef --- /dev/null +++ b/chinadns-ng/Makefile @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include $(TOPDIR)/rules.mk + +PKG_NAME:=chinadns-ng +PKG_VERSION:=2025.08.09 +PKG_RELEASE:=1 + +ifeq ($(ARCH),aarch64) + ifeq ($(BOARD),rockchip) + PKG_ARCH:=chinadns-ng+wolfssl@aarch64-linux-musl@generic+v8a@fast+lto + PKG_HASH:=3fe0217615dd7060b7287d2b6b31d2a0b364137398bfb335a03bead322eac716 + else + PKG_ARCH:=chinadns-ng+wolfssl_noasm@aarch64-linux-musl@generic+v8a@fast+lto + PKG_HASH:=42ddd494200ec6d88b35902927688d316bc23e06e6c08d9e01eb2412196ab845 + endif +else ifeq ($(ARCH),arm) + ARM_CPU_FEATURES:=$(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE)))) + ifeq ($(ARM_CPU_FEATURES),) + PKG_ARCH:=chinadns-ng+wolfssl@arm-linux-musleabi@generic+v6+soft_float@fast+lto + PKG_HASH:=0a401d1dc11129481b2baf86f847d55d66bd7e725cba4bf57875fdad27ef0052 + else + PKG_ARCH:=chinadns-ng+wolfssl@arm-linux-musleabihf@generic+v7a@fast+lto + PKG_HASH:=dfa1f6ba80fb0925613822f4c4e00df8da68e7b8b772048d26a0d1a9d07d346b + endif +else ifeq ($(ARCH),mips) + PKG_ARCH:=chinadns-ng+wolfssl@mips-linux-musl@mips32+soft_float@fast+lto + PKG_HASH:=b610821a8f61b0ed3c8c7e82e10d401348a9de17f900988589024a37c4099c8e +else ifeq ($(ARCH),mipsel) + PKG_ARCH:=chinadns-ng+wolfssl@mipsel-linux-musl@mips32+soft_float@fast+lto + PKG_HASH:=760544a88724e3b1b9eac79c9400231e81aa8786f8f00a979229e175811ffe6d +else ifeq ($(ARCH),mips64) + PKG_ARCH:=chinadns-ng+wolfssl@mips64-linux-musl@mips64+soft_float@fast+lto + PKG_HASH:=2d0fce18a7ef1d74fdc12738767e66998a52c2b30d8790da760933853fe8726e +else ifeq ($(ARCH),i386) + PKG_ARCH:=chinadns-ng+wolfssl@i386-linux-musl@i686@fast+lto + PKG_HASH:=85e057dd0a0e8913b30471737436ab8b71834c494ed9f9e53544261b1ffdc8d6 +else ifeq ($(ARCH),x86_64) + PKG_ARCH:=chinadns-ng+wolfssl@x86_64-linux-musl@x86_64@fast+lto + PKG_HASH:=842ea4e9816efd91d39bc76ead5c4a42e79011757e37c521b4270b675cfcb30c +else + PKG_HASH:=dummy +endif + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_ARCH) +PKG_SOURCE_URL:=https://github.com/zfl9/chinadns-ng/releases/download/$(PKG_VERSION)/$(PKG_ARCH)? +UNPACK_CMD=$(CP) $(DL_DIR)/$(PKG_SOURCE) $(PKG_BUILD_DIR)/$(PKG_NAME) + +PKG_LICENSE:=AGPL-3.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=sbwml + +include $(INCLUDE_DIR)/package.mk + +define Package/chinadns-ng + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE:=ChinaDNS next generation, refactoring with epoll and ipset. + URL:=https://github.com/zfl9/chinadns-ng + DEPENDS:=@(aarch64||arm||i386||mips||mipsel||mips64||x86_64) +ipset +endef + +define Build/Compile +endef + +define Package/chinadns-ng/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/chinadns-ng $(1)/usr/bin +endef + +$(eval $(call BuildPackage,chinadns-ng)) diff --git a/daemonlogger/Makefile b/daemonlogger/Makefile new file mode 100644 index 00000000..ba81a7bc --- /dev/null +++ b/daemonlogger/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (C) 2007-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=daemonlogger +PKG_VERSION:=1.2.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/daemonlogger +PKG_HASH:=79fcd34d815e9c671ffa1ea3c7d7d50f895bb7a79b4448c4fd1c37857cf44a0b + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING + +PKG_MAINTAINER:=Mirko Vogt + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/daemonlogger + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libpcap +libdnet + TITLE:=Software Network Tap + URL:=http://www.snort.org/snort-downloads/additional-downloads +endef + +CONFIGURE_VARS += \ + BUILD_CC="$(TARGET_CC)" \ + HOSTCC="$(HOSTCC)" + +MAKE_FLAGS := CCOPT="$(TARGET_CFLAGS)" INCLS="-I. $(TARGET_CPPFLAGS)" + +define Package/daemonlogger/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/daemonlogger $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,daemonlogger)) diff --git a/dns2socks-rust/Makefile b/dns2socks-rust/Makefile new file mode 100644 index 00000000..ac520516 --- /dev/null +++ b/dns2socks-rust/Makefile @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017-2024 Zxlhhyccc +# Copyright (C) 2021-2024 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=dns2socks-rust +PKG_VERSION:=0.2.5 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/tun2proxy/dns2socks/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=53f62c38df51bc5f11c519549213a7fd0dcb33b595410b662ea63d480faced9a +PKG_BUILD_DIR:=$(BUILD_DIR)/dns2socks-$(PKG_VERSION) + +PKG_MAINTAINER:=Zxlhhyccc +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_PARALLEL:=1 + +PKG_BUILD_DEPENDS:=rust/host +PKG_BUILD_PARALLEL:=1 + +#RUST_PKG:=dns2socks + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/rust/rust-package.mk + +define Package/dns2socks-rust + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE:=DNS forwards to SOCKS5 server + URL:=https://github.com/tun2proxy/dns2socks.git + DEPENDS:=$$(RUST_ARCH_DEPENDS) +endef + +define Package/dns2socks-rust/description + This is a DNS server that forwards DNS requests to a SOCKS5 server. +endef + +define Build/Compile + $(call Build/Compile/Cargo,,--all-features) +endef + +define Package/dns2socks-rust/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/target/$(RUSTC_TARGET_ARCH)/release/dns2socks $(1)/usr/bin/dns2socks-rust +endef + +$(eval $(call BuildPackage,dns2socks-rust)) diff --git a/dns2socks/Makefile b/dns2socks/Makefile new file mode 100644 index 00000000..99e7f37d --- /dev/null +++ b/dns2socks/Makefile @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021-2026 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=dns2socks +PKG_VERSION:=2.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/dns2socks/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=790f7ca5ec07677a699121eb071c9e66cdafe65a22bb229eed7fd3cf215631d2 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=ghostmaker + +include $(INCLUDE_DIR)/package.mk + +define Package/dns2socks + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE:=DNS to SOCKS or HTTP proxy + URL:=https://github.com/kenzok8/dns2socks + DEPENDS:=+libpthread +endef + +define Package/dns2socks/description + This is a command line utility to resolve DNS requests via + a SOCKS tunnel like Tor or a HTTP proxy. +endef + +define Build/Compile + $(TARGET_CC) \ + $(TARGET_CFLAGS) \ + $(TARGET_CPPFLAGS) \ + $(FPIC) \ + -o $(PKG_BUILD_DIR)/dns2socks \ + $(PKG_BUILD_DIR)/src/dns2socks.c \ + $(TARGET_LDFLAGS) -pthread +endef + +define Package/dns2socks/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/dns2socks $(1)/usr/bin/dns2socks +endef + +$(eval $(call BuildPackage,dns2socks)) diff --git a/dns2tcp/Makefile b/dns2tcp/Makefile new file mode 100644 index 00000000..108d04ca --- /dev/null +++ b/dns2tcp/Makefile @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=dns2tcp +PKG_VERSION:=1.1.2 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/zfl9/dns2tcp/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=5e8c6302a1d32c16ae7d4b8e39cd9aad1f2d7e68fe18813e76cb1e48ec5940d2 + +PKG_MAINTAINER:=Tianling Shen +PKG_LICENSE:=AGPL-3.0-only +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 gc-sections lto + +include $(INCLUDE_DIR)/package.mk + +define Package/dns2tcp + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE:=utility to convert dns query from udp to tcp + URL:=https://github.com/zfl9/dns2tcp +endef + +TARGET_CFLAGS+= $(FPIC) +MAKE_FLAGS+= \ + CFLAGS="-std=c99 $(TARGET_CFLAGS)" \ + EVCFLAGS="$(TARGET_CFLAGS)" + +define Package/dns2tcp/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/dns2tcp $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,dns2tcp)) diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 00000000..2e9f7d5e --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,74 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=docker +PKG_VERSION:=29.5.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/docker/cli/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=e5cf80d9e0b6630bb2e97decf664ad5f0c732b296b7c47030044c3a7287bbddb +PKG_BUILD_DIR:=$(BUILD_DIR)/cli-$(PKG_VERSION) +PKG_GIT_SHORT_COMMIT:=$(shell $(CURDIR)/git-short-commit.sh 'github.com/docker/cli' 'v$(PKG_VERSION)' '$(TMP_DIR)/git-short-commit/$(PKG_NAME)-$(PKG_VERSION)') + +PKG_MAINTAINER:=Gerard Ryan +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/docker/cli + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/docker + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Docker Community Edition CLI + URL:=https://www.docker.com/ + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Package/docker/description +The CLI used in the Docker CE and Docker EE products. +endef + +GO_PKG_INSTALL_EXTRA:=\ + cli/compose/schema/data \ + vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb + +TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS) +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) +TARGET_LDFLAGS += $(if $(CONFIG_USE_GLIBC),-lc -lgcc_eh) + +define Build/Prepare + $(Build/Prepare/Default) + + # Verify PKG_GIT_SHORT_COMMIT + ( \ + EXPECTED_PKG_GIT_SHORT_COMMIT=$$$$( $(CURDIR)/git-short-commit.sh 'github.com/docker/cli' 'v$(PKG_VERSION)' '$(TMP_DIR)/git-short-commit/$(PKG_NAME)-$(PKG_VERSION)' ); \ + if [ "$$$${EXPECTED_PKG_GIT_SHORT_COMMIT}" != "$(strip $(PKG_GIT_SHORT_COMMIT))" ]; then \ + echo "ERROR: Expected 'PKG_GIT_SHORT_COMMIT:=$$$${EXPECTED_PKG_GIT_SHORT_COMMIT}', found 'PKG_GIT_SHORT_COMMIT:=$(strip $(PKG_GIT_SHORT_COMMIT))'"; \ + exit 1; \ + fi \ + ) +endef + +define Build/Compile + ( \ + cd $(PKG_BUILD_DIR); \ + $(GO_PKG_VARS) \ + GITCOMMIT=$(PKG_GIT_SHORT_COMMIT) \ + VERSION=$(PKG_VERSION) \ + ./scripts/build/binary; \ + ) +endef + +define Package/docker/install + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/docker $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,docker)) diff --git a/docker/git-short-commit.sh b/docker/git-short-commit.sh new file mode 100644 index 00000000..5edc7ff2 --- /dev/null +++ b/docker/git-short-commit.sh @@ -0,0 +1,49 @@ + +#!/bin/sh +# +# USAGE: git-short-commit.sh +# + +set -e + +error() { + echo "ERROR: ${*}" >&2 + exit 1 +} + +GIT_URL="${1}" +if [ -z "${GIT_URL}" ]; then + error "Git URL not specified" +fi + +GIT_REF="${2}" +if [ -z "${GIT_REF}" ]; then + error "Git reference not specified" +fi + +GIT_DIR="${3}" +if [ -z "${GIT_DIR}" ]; then + error "Git clone directory not specified" +fi + +clean_up() { + rm -rf "${GIT_DIR}" +} +trap clean_up EXIT + +git init --quiet "${GIT_DIR}" +( + cd "${GIT_DIR}" + for PREFIX in "" "https://" "http://" "git@"; do + echo "Trying remote '${PREFIX}${GIT_URL}'" >&2 + git remote add origin "${PREFIX}${GIT_URL}" + + if git fetch --depth 1 origin "${GIT_REF}"; then + git checkout --detach FETCH_HEAD -- + git rev-parse --short HEAD + break + fi + + git remote remove origin + done +) diff --git a/dockerd/Config.in b/dockerd/Config.in new file mode 100644 index 00000000..2e7502a7 --- /dev/null +++ b/dockerd/Config.in @@ -0,0 +1,87 @@ +config DOCKER_CHECK_CONFIG + bool "Installs check-config.sh with dependencies" + default n + depends on PACKAGE_dockerd + select PACKAGE_bash + select PACKAGE_kmod-ikconfig + +# These options are mostly specified by https://github.com/moby/moby/blob/master/contrib/check-config.sh + +config DOCKER_CGROUP_OPTIONS + bool "Enable available kernel support for CGroupsV1" + default y + depends on PACKAGE_dockerd + select KERNEL_CGROUP_DEVICE + select KERNEL_CGROUP_FREEZER + select KERNEL_NET_CLS_CGROUP + select KERNEL_CGROUP_NET_PRIO + select PACKAGE_cgroupfs-mount + help + Selects kernel options to enable CGroups V1. + +config DOCKER_OPTIONAL_FEATURES + bool "Enable optional kernel support for Docker" + default n + depends on PACKAGE_dockerd + select KERNEL_MEMCG_SWAP_ENABLED + select KERNEL_CFQ_GROUP_IOSCHED + select KERNEL_CGROUP_PERF + select KERNEL_CGROUP_HUGETLB + help + Select 'Optional Features' kernel options for Docker that are unselected. + See https://github.com/moby/moby/blob/master/contrib/check-config.sh + +menu "Network" + depends on PACKAGE_dockerd + + config DOCKER_NET_OVERLAY + bool "Includes the Overlay network feature" + default n + select PACKAGE_kmod-vxlan + help + Selects kmod-vxlan for the Overlay network feature. + + config DOCKER_NET_ENCRYPT + bool "Includes encrypted networking kernel modules" + depends on DOCKER_NET_OVERLAY + default n + select PACKAGE_kmod-crypto-gcm + select PACKAGE_kmod-crypto-seqiv + select PACKAGE_kmod-crypto-ghash + select PACKAGE_kmod-ipsec + help + Select needed kernel modules for encrypted networking support. + + config DOCKER_NET_MACVLAN + bool "Includes macvlan kernel modules" + default y + select PACKAGE_kmod-macvlan + select PACKAGE_kmod-dummy + + config DOCKER_NET_TFTP + bool "Includes ftp/tftp client kernel modules" + default n + select PACKAGE_kmod-nf-nathelper + select PACKAGE_kmod-nf-nathelper-extra +endmenu + +menu "Storage" + depends on PACKAGE_dockerd + + config DOCKER_STO_DEVMAPPER + bool "Enables support for devmapper snapshotting" + default n + select PACKAGE_libdevmapper + + config DOCKER_STO_EXT4 + bool "Enables support for ext3 or ext4 as the backing filesystem" + default y + select KERNEL_EXT4_FS_POSIX_ACL + select KERNEL_EXT4_FS_SECURITY + + config DOCKER_STO_BTRFS + bool "Enables support for btrfs as the backing filesystem" + default n + select KERNEL_BTRFS_FS_POSIX_ACL + select PACKAGE_btrfs-progs +endmenu diff --git a/dockerd/Makefile b/dockerd/Makefile new file mode 100644 index 00000000..21298883 --- /dev/null +++ b/dockerd/Makefile @@ -0,0 +1,182 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=dockerd +PKG_VERSION:=29.5.2 +PKG_RELEASE:=1 +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_GIT_URL:=github.com/moby/moby +PKG_GIT_REF:=docker-v$(PKG_VERSION) +PKG_SOURCE_URL:=https://codeload.$(PKG_GIT_URL)/tar.gz/$(PKG_GIT_REF)? +PKG_HASH:=1235ed325d324c76f52e52beaa1dac85c92a073bf2f9fcc5bb9f67e35a668028 +PKG_GIT_SHORT_COMMIT:=$(shell $(CURDIR)/git-short-commit.sh '$(PKG_GIT_URL)' '$(PKG_GIT_REF)' '$(TMP_DIR)/git-short-commit/$(PKG_NAME)-$(PKG_VERSION)') + +PKG_MAINTAINER:=Gerard Ryan + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/docker/docker + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/dockerd/config + source "$(SOURCE)/Config.in" +endef + +define Package/dockerd + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Docker Community Edition Daemon + URL:=https://www.docker.com/ + DEPENDS:=$(GO_ARCH_DEPENDS) \ + +ca-certificates \ + +containerd \ + +iptables \ + +iptables-mod-extra \ + +IPV6:ip6tables \ + +IPV6:kmod-ipt-nat6 \ + +KERNEL_SECCOMP:libseccomp \ + +kmod-ipt-nat \ + +kmod-ipt-physdev \ + +kmod-nf-ipvs \ + +kmod-veth \ + +tini \ + +uci-firewall \ + @!(mips||mips64||mipsel) + USERID:=docker:docker + MENU:=1 +endef + +define Package/dockerd/conffiles +/etc/config/dockerd +endef + +define Package/dockerd/description +The Docker CE Engine. +endef + +TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS) +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) +TARGET_LDFLAGS += $(if $(CONFIG_USE_GLIBC),-lc -lgcc_eh) + +# $(1) = path to dependent package 'Makefile' +# $(2) = relevant dependency '.installer' file +define EnsureVendoredVersion + ( \ + DEP_VER=$$$$( grep --only-matching --perl-regexp '(?<=PKG_VERSION:=)(.*)' "$(1)" ); \ + VEN_VER=$$$$( grep --only-matching --perl-regexp '(?<=_VERSION:=v)(.*)(?=})' "$(PKG_BUILD_DIR)/hack/dockerfile/install/$(2)" ); \ + if [ "$$$${VEN_VER}" != "$$$${DEP_VER}" ]; then \ + echo "ERROR: Expected 'PKG_VERSION:=$$$${VEN_VER}' in '$(1)', found 'PKG_VERSION:=$$$${DEP_VER}'"; \ + exit 1; \ + fi \ + ) +endef + +# $(1) = path to dependent package 'Makefile' +# $(2) = relevant dependency '.installer' file +define EnsureVendoredCommit + ( \ + DEP_VER=$$$$( grep --only-matching --perl-regexp '(?<=PKG_SOURCE_VERSION:=)(.*)' "$(1)" ); \ + VEN_VER=$$$$( grep --only-matching --perl-regexp '(?<=_COMMIT:=)(.*)(?=})' "$(PKG_BUILD_DIR)/hack/dockerfile/install/$(2)" ); \ + if [ "$$$${VEN_VER}" != "$$$${DEP_VER}" ]; then \ + echo "ERROR: Expected 'PKG_SOURCE_VERSION:=$$$${VEN_VER}' in '$(1)', found 'PKG_SOURCE_VERSION:=$$$${DEP_VER}'"; \ + exit 1; \ + fi \ + ) +endef + +define Build/Prepare + $(Build/Prepare/Default) + + # Verify dependencies are the vendored version + $(call EnsureVendoredVersion,../containerd/Makefile,containerd.installer) + $(call EnsureVendoredVersion,../runc/Makefile,runc.installer) + $(call EnsureVendoredVersion,../tini/Makefile,tini.installer) + + # Verify CLI is the same version + ( \ + CLI_MAKEFILE="../docker/Makefile"; \ + CLI_VERSION=$$$$( grep --only-matching --perl-regexp '(?<=PKG_VERSION:=)(.*)' "$$$${CLI_MAKEFILE}" ); \ + if [ "$$$${CLI_VERSION}" != "$(PKG_VERSION)" ]; then \ + echo "ERROR: Expected 'PKG_VERSION:=$(PKG_VERSION)' in '$$$${CLI_MAKEFILE}', found 'PKG_VERSION:=$$$${CLI_VERSION}'"; \ + exit 1; \ + fi \ + ) + + # Verify PKG_GIT_SHORT_COMMIT + ( \ + EXPECTED_PKG_GIT_SHORT_COMMIT=$$$$( $(CURDIR)/git-short-commit.sh '$(PKG_GIT_URL)' '$(PKG_GIT_REF)' '$(TMP_DIR)/git-short-commit/$(PKG_NAME)-$(PKG_VERSION)' ); \ + if [ "$$$${EXPECTED_PKG_GIT_SHORT_COMMIT}" != "$(strip $(PKG_GIT_SHORT_COMMIT))" ]; then \ + echo "ERROR: Expected 'PKG_GIT_SHORT_COMMIT:=$$$${EXPECTED_PKG_GIT_SHORT_COMMIT}', found 'PKG_GIT_SHORT_COMMIT:=$(strip $(PKG_GIT_SHORT_COMMIT))'"; \ + exit 1; \ + fi \ + ) +endef + +BUILDTAGS:= +ifeq ($(KERNEL_SECCOMP),y) +BUILDTAGS += seccomp +endif +ifeq ($(CONFIG_SELINUX),y) +BUILDTAGS += selinux +endif + +define Build/Compile + ( \ + cd $(PKG_BUILD_DIR); \ + $(GO_PKG_VARS) \ + DOCKER_GITCOMMIT=$(PKG_GIT_SHORT_COMMIT) \ + DOCKER_BUILDTAGS='$(BUILDTAGS)' \ + VERSION=$(PKG_VERSION) \ + ./hack/make.sh binary; \ + ) +endef + +define Package/dockerd/install + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bundles/binary-daemon/dockerd $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bundles/binary-daemon/docker-proxy $(1)/usr/bin/ + + $(INSTALL_DIR) $(1)/opt/docker/ + + ifeq ($(CONFIG_DOCKER_CHECK_CONFIG),y) + $(INSTALL_DIR) $(1)/usr/share/docker/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/check-config.sh $(1)/usr/share/docker/ + endif + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/dockerd.init $(1)/etc/init.d/dockerd + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/dockerd $(1)/etc/config/dockerd + + # Must be after systcl 11-br-netfilter.conf from kmod-br-netfilter + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DATA) ./files/etc/sysctl.d/sysctl-br-netfilter-ip.conf \ + $(1)/etc/sysctl.d/12-br-netfilter-ip.conf +endef + +define Package/dockerd/postinst +#!/bin/sh +[ -n "$$IPKG_INSTROOT" ] || { + /etc/init.d/dockerd enable + /etc/init.d/dockerd uciadd + /etc/init.d/dockerd start +} +endef + +define Package/dockerd/prerm +#!/bin/sh +[ -n "$$IPKG_INSTROOT" ] || { + /etc/init.d/dockerd disable + /etc/init.d/dockerd stop + /etc/init.d/dockerd ucidel +} +endef + +$(eval $(call BuildPackage,dockerd)) diff --git a/dockerd/files/dockerd.init b/dockerd/files/dockerd.init new file mode 100755 index 00000000..111e2cd8 --- /dev/null +++ b/dockerd/files/dockerd.init @@ -0,0 +1,285 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 +START=99 + +extra_command "uciadd" " Add docker bridge configuration to network and firewall uci config" +extra_command "ucidel" " Delete docker bridge configuration from network and firewall uci config" + +DOCKER_CONF_DIR="/tmp/dockerd" +DOCKERD_CONF="${DOCKER_CONF_DIR}/daemon.json" + +uci_quiet() { + uci -q "${@}" >/dev/null +} + +json_add_array_string() { + json_add_string "" "${1}" +} + +find_network_device() { + local device="${1}" + local device_section="" + + check_device() { + local cfg="${1}" + local device="${2}" + + local type name + config_get type "${cfg}" type + config_get name "${cfg}" name + + [ "${type}" = "bridge" ] && [ "${name}" = "${device}" ] \ + && device_section="${cfg}" + } + + config_load network + config_foreach check_device device "${device}" + + echo "${device_section}" +} + +boot() { + uciadd + rc_procd start_service +} + +uciadd() { + local iface="${1}" + local device="${2}" + local zone="${3}" + + [ -z "${iface}" ] && { + iface="docker" + device="docker0" + zone="docker" + } + + /etc/init.d/dockerd running && { + echo "Please stop dockerd service first" + exit 0 + } + + # Add network interface + if ! uci_quiet get network.${iface}; then + logger -t "dockerd-init" -p notice "Adding interface '${iface}' to network config" + uci_quiet add network interface + uci_quiet rename network.@interface[-1]="${iface}" + uci_quiet set network.@interface[-1].device="${device}" + uci_quiet set network.@interface[-1].proto="none" + uci_quiet set network.@interface[-1].auto="0" + uci_quiet commit network + fi + + # Add docker bridge device + if [ "$(find_network_device "$device")" = "" ]; then + logger -t "dockerd-init" -p notice "Adding bridge device '${device}' to network config" + uci_quiet add network device + uci_quiet set network.@device[-1].type="bridge" + uci_quiet set network.@device[-1].name="${device}" + uci_quiet commit network + else + logger -t "dockerd-init" -p notice "Bridge device '${device}' already defined in network config" + fi + + # Add firewall zone + if ! uci_quiet get firewall.${zone}; then + logger -t "dockerd-init" -p notice "Adding firewall zone '${zone}' to firewall config" + uci_quiet add firewall zone + uci_quiet rename firewall.@zone[-1]="${zone}" + uci_quiet set firewall.@zone[-1].input="ACCEPT" + uci_quiet set firewall.@zone[-1].output="ACCEPT" + uci_quiet set firewall.@zone[-1].forward="ACCEPT" + uci_quiet set firewall.@zone[-1].name="${zone}" + uci_quiet commit firewall + fi + + # Add interface to firewall zone + if uci_quiet get firewall.${zone}; then + uci_quiet del_list firewall.${zone}.network="${iface}" + uci_quiet add_list firewall.${zone}.network="${iface}" + uci_quiet commit firewall + fi + + reload_config +} + +ucidel() { + local iface="${1}" + local device="${2}" + local zone="${3}" + + [ -z "${iface}" ] && { + iface="docker" + device="docker0" + zone="docker" + } + + /etc/init.d/dockerd running && { + echo "Please stop dockerd service first" + exit 0 + } + + # Remove network device + if uci_quiet delete network.$(find_network_device "${device}"); then + logger -t "dockerd-init" -p notice "Deleting bridge device '${device}' from network config" + uci_quiet commit network + fi + + # Remove network interface + if uci_quiet get network.${iface}; then + logger -t "dockerd-init" -p notice "Deleting interface '${iface}' from network config" + uci_quiet delete network.${iface} + uci_quiet commit network + fi + + # Remove interface from firewall zone + if uci_quiet get firewall.${zone}; then + logger -t "dockerd-init" -p notice "Deleting network interface '${iface}' in zone '${zone}' from firewall config" + uci_quiet del_list firewall.${zone}.network="${iface}" + uci_quiet commit firewall + # Remove Firewall zone if network is empty + if ! uci_quiet get firewall.${zone}.network; then + logger -t "dockerd-init" -p notice "Deleting firewall zone '${zone}' from firewall config" + uci_quiet delete firewall.${zone} + fi + uci_quiet commit firewall + fi + + reload_config +} + +process_config() { + local alt_config_file data_root log_level iptables bip + + [ -f /etc/config/dockerd ] || { + # Use the daemon default configuration + DOCKERD_CONF="" + return 0 + } + + # reset configuration + rm -fr "${DOCKER_CONF_DIR}" + mkdir -p "${DOCKER_CONF_DIR}" + + config_load 'dockerd' + config_get alt_config_file globals alt_config_file + [ -n "${alt_config_file}" ] && [ -f "${alt_config_file}" ] && { + ln -s "${alt_config_file}" "${DOCKERD_CONF}" + return 0 + } + + config_get data_root globals data_root "/opt/docker/" + config_get log_level globals log_level "warn" + config_get_bool iptables globals iptables "1" + + # Don't add these options by default + # omission == docker defaults + config_get log_driver globals log_driver "" + config_get bip globals bip "" + config_get registry_mirrors globals registry_mirrors "" + config_get hosts globals hosts "" + config_get dns globals dns "" + config_get_bool ipv6 globals ipv6 "" + config_get ip globals ip "" + config_get fixed_cidr globals fixed_cidr "" + config_get fixed_cidr_v6 globals fixed_cidr_v6 "" + + . /usr/share/libubox/jshn.sh + json_init + json_add_string "data-root" "${data_root}" + json_add_string "log-level" "${log_level}" + json_add_boolean "iptables" "${iptables}" + [ -z "${log_driver}" ] || json_add_string "log-driver" "${log_driver}" + [ -z "${bip}" ] || json_add_string "bip" "${bip}" + [ -z "${registry_mirrors}" ] || json_add_array "registry-mirrors" + [ -z "${registry_mirrors}" ] || config_list_foreach globals registry_mirrors json_add_array_string + [ -z "${registry_mirrors}" ] || json_close_array + [ -z "${hosts}" ] || json_add_array "hosts" + [ -z "${hosts}" ] || config_list_foreach globals hosts json_add_array_string + [ -z "${hosts}" ] || json_close_array + [ -z "${dns}" ] || json_add_array "dns" + [ -z "${dns}" ] || config_list_foreach globals dns json_add_array_string + [ -z "${dns}" ] || json_close_array + [ -z "${ipv6}" ] || json_add_boolean "ipv6" "${ipv6}" + [ -z "${ip}" ] || json_add_string "ip" "${ip}" + [ -z "${fixed_cidr}" ] || json_add_string "fixed-cidr" "${fixed_cidr}" + [ -z "${fixed_cidr_v6}" ] || json_add_string "fixed-cidr-v6" "${fixed_cidr_v6}" + json_dump > "${DOCKERD_CONF}" + + [ "${iptables}" -eq "1" ] && config_foreach iptables_add_blocking_rule firewall +} + +start_service() { + local nofile=$(cat /proc/sys/fs/nr_open) + + process_config + + procd_open_instance + procd_set_param stderr 1 + if [ -z "${DOCKERD_CONF}" ]; then + procd_set_param command /usr/bin/dockerd + else + procd_set_param command /usr/bin/dockerd --config-file="${DOCKERD_CONF}" + fi + procd_set_param limits nofile="${nofile} ${nofile}" + procd_close_instance +} + +reload_service() { + process_config + procd_send_signal dockerd +} + +service_triggers() { + procd_add_reload_trigger 'dockerd' +} + +iptables_add_blocking_rule() { + local cfg="${1}" + + local device="" + local extra_iptables_args="" + + handle_iptables_rule() { + local interface="${1}" + local outbound="${2}" + local extra_iptables_args="${3}" + + local inbound="" + + . /lib/functions/network.sh + network_get_physdev inbound "${interface}" + + [ -z "${inbound}" ] && { + logger -t "dockerd-init" -p notice "Unable to get physical device for interface ${interface}" + return + } + + # Wait for a maximum of 10 second per command, retrying every millisecond + local iptables_wait_args="--wait 10 --wait-interval 1000" + + # Ignore errors as it might already be present + iptables ${iptables_wait_args} --table filter --new DOCKER-USER 2>/dev/null + if ! iptables ${iptables_wait_args} --table filter --check DOCKER-USER --in-interface "${inbound}" --out-interface "${outbound}" ${extra_iptables_args} --jump REJECT 2>/dev/null; then + logger -t "dockerd-init" -p notice "Drop traffic from ${inbound} to ${outbound}" + iptables ${iptables_wait_args} --table filter --insert DOCKER-USER --in-interface "${inbound}" --out-interface "${outbound}" ${extra_iptables_args} --jump REJECT + fi + } + + config_get device "${cfg}" device + + [ -z "${device}" ] && { + logger -t "dockerd-init" -p notice "No device configured for ${cfg}" + return + } + + config_get extra_iptables_args "${cfg}" extra_iptables_args + config_list_foreach "${cfg}" blocked_interfaces handle_iptables_rule "${device}" "${extra_iptables_args}" +} + +stop_service() { + if /etc/init.d/dockerd running; then + service_stop "/usr/bin/dockerd" + fi +} diff --git a/dockerd/files/etc/config/dockerd b/dockerd/files/etc/config/dockerd new file mode 100644 index 00000000..dd752354 --- /dev/null +++ b/dockerd/files/etc/config/dockerd @@ -0,0 +1,38 @@ +# The following settings require a restart of docker to take full effect, A reload will only have partial or no effect: +# log_driver +# bip +# blocked_interfaces +# extra_iptables_args +# device + +config globals 'globals' +# option alt_config_file '/etc/docker/daemon.json' + option data_root '/opt/docker/' +# option log_driver 'local' + option log_level 'warn' + option iptables '1' +# list hosts 'unix:///var/run/docker.sock' +# option bip '172.18.0.1/24' +# option fixed_cidr '172.17.0.0/16' +# option fixed_cidr_v6 'fc00:1::/80' +# option ipv6 '1' +# option ip '::ffff:0.0.0.0' +# list dns '172.17.0.1' +# list registry_mirrors 'https://' +# list registry_mirrors 'https://hub.docker.com' + +# Docker doesn't work well out of the box with fw4. This is because Docker relies on a compatibility layer that +# naively translates iptables rules. For the best compatibility replace the following dependencies: +# `firewall4` -> `firewall` +# `iptables-nft` -> `iptables-legacy` +# `ip6tables-nft` -> `ip6tables-legacy` + +# Docker undermines the fw3 rules. By default all external source IPs are allowed to connect to the Docker host. +# See https://docs.docker.com/network/iptables/ for more details. + +# firewall config changes are only additive i.e firewall will need to be restarted first to clear old changes, +# then docker restarted to load in new changes. +config firewall 'firewall' + option device 'docker0' + list blocked_interfaces 'wan' +# option extra_iptables_args '--match conntrack ! --ctstate RELATED,ESTABLISHED' # allow outbound connections diff --git a/dockerd/files/etc/sysctl.d/sysctl-br-netfilter-ip.conf b/dockerd/files/etc/sysctl.d/sysctl-br-netfilter-ip.conf new file mode 100644 index 00000000..7b488607 --- /dev/null +++ b/dockerd/files/etc/sysctl.d/sysctl-br-netfilter-ip.conf @@ -0,0 +1,7 @@ +# Do not edit, changes to this file will be lost on upgrades +# /etc/sysctl.conf can be used to customize sysctl settings + +# enable bridge firewalling for docker +net.bridge.bridge-nf-call-ip6tables=1 +net.bridge.bridge-nf-call-iptables=1 + diff --git a/dockerd/git-short-commit.sh b/dockerd/git-short-commit.sh new file mode 100755 index 00000000..133ee260 --- /dev/null +++ b/dockerd/git-short-commit.sh @@ -0,0 +1,52 @@ + +#!/bin/sh +# +# USAGE: git-short-commit.sh +# + +set -e + +error() { + echo "ERROR: ${*}" >&2 + exit 1 +} + +GIT_URL="${1}" +if [ -z "${GIT_URL}" ]; then + error "Git URL not specified" +fi + +GIT_REF="${2}" +if [ -z "${GIT_REF}" ]; then + error "Git reference not specified" +fi + +# Remove docker- prefix if present (e.g., docker-v29.2.1 -> v29.2.1) +GIT_REF=$(echo "$GIT_REF" | sed 's/^docker-//') + +GIT_DIR="${3}" +if [ -z "${GIT_DIR}" ]; then + error "Git clone directory not specified" +fi + +clean_up() { + rm -rf "${GIT_DIR}" +} +trap clean_up EXIT + +git init --quiet "${GIT_DIR}" +( + cd "${GIT_DIR}" + for PREFIX in "" "https://" "http://" "git@"; do + echo "Trying remote '${PREFIX}${GIT_URL}'" >&2 + git remote add origin "${PREFIX}${GIT_URL}" + + if git fetch --depth 1 origin "${GIT_REF}"; then + git checkout --detach FETCH_HEAD -- + git rev-parse --short HEAD + break + fi + + git remote remove origin + done +) diff --git a/geoview/Makefile b/geoview/Makefile new file mode 100644 index 00000000..c74ad611 --- /dev/null +++ b/geoview/Makefile @@ -0,0 +1,48 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=geoview +PKG_VERSION:=0.2.6 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/snowie2000/geoview/tar.gz/$(PKG_VERSION)? +PKG_HASH:=1b46d4255ab22ec433a14f804e9487885cc2693323579c1385d51919838db132 + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=snowie2000 + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/snowie2000/geoview +GO_PKG_BUILD_PKG:=$(GO_PKG) + +GO_PKG_LDFLAGS:=-s -w + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/geoview + TITLE:=A geofile toolkit + URL:=https://github.com/snowie2000/geoview + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + DEPENDS+= $(GO_ARCH_DEPENDS) +endef + +define Package/geoview/description + geoview is a handy tool to extract useful information from geo* files. +endef + +define Package/geoview/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/geoview $(1)/usr/bin/ +endef + +$(eval $(call GoBinPackage,geoview)) +$(eval $(call BuildPackage,geoview)) diff --git a/geth/Makefile b/geth/Makefile new file mode 100644 index 00000000..373cf48e --- /dev/null +++ b/geth/Makefile @@ -0,0 +1,58 @@ +# +# Copyright (C) 2018 Sartura Ltd. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=go-ethereum +PKG_VERSION:=1.10.20 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/ethereum/go-ethereum/tar.gz/v${PKG_VERSION}? +PKG_HASH:=15ff54f0a4444eb9faa7c1f6219d3a1db5d547178b4eef6679bb601abc681f9d + +PKG_MAINTAINER:=Mislav Novakovic +PKG_LICENSE:=GPL-3.0-or-later LGPL-3.0-or-later +PKG_LICENSE_FILES:=COPYING COPYING.LESSER + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_CONFIG_DEPENDS:=CONFIG_BUILD_NLS + +GO_PKG:=github.com/ethereum/go-ethereum +GO_PKG_BUILD_PKG:=github.com/ethereum/go-ethereum/cmd/geth + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk +include ../../lang/golang/golang-package.mk + +define Package/geth + SECTION:=net + CATEGORY:=Network + TITLE:=Ethereum Go client + URL:=https://geth.ethereum.org/ + DEPENDS:=$(GO_ARCH_DEPENDS) $(ICONV_DEPENDS) +endef + +define Package/geth/description +Ethereum is a decentralized platform that runs smart contracts, applications +that run exactly as programmed without possibility of downtime, censorship, +fraud or third party interference. +endef + +TARGET_LDFLAGS += $(if $(ICONV_FULL),-liconv) + +define Package/geth/install + $(call GoPackage/Package/Install/Bin,$(1)) + + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/geth.init $(1)/etc/init.d/geth +endef + +$(eval $(call GoBinPackage,geth)) +$(eval $(call BuildPackage,geth)) diff --git a/geth/files/geth.init b/geth/files/geth.init new file mode 100644 index 00000000..154c11fc --- /dev/null +++ b/geth/files/geth.init @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common + +START=90 +STOP=10 + +USE_PROCD=1 +PROG=/usr/bin/geth + +start_service() { + procd_open_instance + procd_set_param command ${PROG} + procd_append_param command --syncmode "light" --cache 1024 + procd_set_param respawn + procd_close_instance +} diff --git a/gn/Makefile b/gn/Makefile new file mode 100644 index 00000000..5a6c4f7d --- /dev/null +++ b/gn/Makefile @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=gn +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://gn.googlesource.com/gn.git +PKG_SOURCE_DATE:=2026-05-21 +PKG_SOURCE_VERSION:=e44942b445d9376451f7d519965dae036efde5bc +PKG_MIRROR_HASH:=8d41089dd918aa94a5f8ab6ac78b056220e353755e5b97f2f2cc70ff634c1f1c + +PKG_LICENSE:=BSD 3-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_HOST_ONLY:=1 +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk + +define Package/gn + SECTION:=devel + CATEGORY:=Development + TITLE:=A meta-build system that generates build files for Ninja + URL:=https://gn.googlesource.com/gn/ + BUILDONLY:=1 +endef + +define Package/gn/description + GN can generate Ninja build files for C, C++, Rust, Objective C, + and Swift source on most popular platforms. +endef + +define Host/Configure + $(PYTHON) $(HOST_BUILD_DIR)/build/gen.py \ + --no-last-commit-position \ + --allow-warnings +endef + +define Host/Compile + +$(NINJA) -C $(HOST_BUILD_DIR)/out +endef + +define Host/Install + $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin/ + $(INSTALL_BIN) $(HOST_BUILD_DIR)/out/gn $(STAGING_DIR_HOSTPKG)/bin/ +endef + +define Host/Clean + $(RM) $(STAGING_DIR_HOSTPKG)/bin/gn +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,gn)) diff --git a/gn/src/out/last_commit_position.h b/gn/src/out/last_commit_position.h new file mode 100644 index 00000000..2eac9b05 --- /dev/null +++ b/gn/src/out/last_commit_position.h @@ -0,0 +1,9 @@ +// Generated by build/gen.py. + +#ifndef OUT_LAST_COMMIT_POSITION_H_ +#define OUT_LAST_COMMIT_POSITION_H_ + +#define LAST_COMMIT_POSITION_NUM 2406 +#define LAST_COMMIT_POSITION "2406 (e44942b445d9)" + +#endif // OUT_LAST_COMMIT_POSITION_H_ diff --git a/gnurl/Makefile b/gnurl/Makefile new file mode 100644 index 00000000..dd171430 --- /dev/null +++ b/gnurl/Makefile @@ -0,0 +1,118 @@ +# +# Copyright (C) 2007-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=gnurl +PKG_VERSION:=7.72.0 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/gnunet +PKG_HASH:=b1e72be03fcf9b3fdaf01ae0702c686e9de10f67ef538918447c9e81555694f8 + +PKG_MAINTAINER:=Daniel Golle +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=COPYING + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/gnurl/Default + SECTION:=net + CATEGORY:=Network + URL:=https://gnunet.org/en/gnurl.html +endef + +define Package/gnurl + $(call Package/gnurl/Default) + SUBMENU:=File Transfer + DEPENDS:=+libgnurl + TITLE:=A client-side HTTP/HTTPS transfer utility +endef + +define Package/libgnurl + $(call Package/gnurl/Default) + SECTION:=libs + CATEGORY:=Libraries + DEPENDS:=+libgnutls +libidn2 +zlib + TITLE:=A client-side HTTP/HTTPS transfer library +endef + +TARGET_CFLAGS += $(FPIC) + +CONFIGURE_ARGS += \ + $(call autoconf_bool,CONFIG_IPV6,ipv6) \ + --with-gnutls="$(STAGING_DIR)/usr" \ + --with-libidn="$(STAGING_DIR)/usr" \ + --with-zlib="$(STAGING_DIR)/usr" \ + --with-ca-path="/etc/ssl/certs/" \ + --enable-shared \ + --enable-static \ + --without-axtls \ + --without-brotli \ + --without-libssh2 \ + --without-libmetalink \ + --without-winidn \ + --without-librtmp \ + --without-nghttp2 \ + --without-nss \ + --without-cyassl \ + --without-libpsl \ + --without-polarssl \ + --without-ssl \ + --without-winssl \ + --without-darwinssl \ + --without-zstd \ + --disable-ares \ + --disable-sspi \ + --disable-crypto-auth \ + --disable-ntlm-wb \ + --disable-tls-srp \ + --disable-ldap \ + --disable-ldaps \ + --disable-rtsp \ + --disable-dict \ + --disable-telnet \ + --disable-tftp \ + --disable-pop3 \ + --disable-imap \ + --disable-smtp \ + --disable-gopher \ + --disable-file \ + --disable-ftp \ + --disable-smb \ + --disable-debug \ + --disable-manual \ + --disable-verbose + +define Build/InstallDev + $(INSTALL_DIR) $(2)/bin $(1)/usr/bin $(1)/usr/include/gnurl $(1)/usr/lib $(1)/usr/lib/pkgconfig + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gnurl-config $(1)/usr/bin/ + $(CP) $(PKG_INSTALL_DIR)/usr/include/gnurl/*.h $(1)/usr/include/gnurl + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgnurl.{a,so*} $(1)/usr/lib/ + $(CP) $(PKG_BUILD_DIR)/libgnurl.pc $(1)/usr/lib/pkgconfig/ + $(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/gnurl-config + [ -n "$(TARGET_LDFLAGS)" ] && $(SED) 's#$(TARGET_LDFLAGS)##g' $(1)/usr/lib/pkgconfig/libgnurl.pc || true + $(LN) $(STAGING_DIR)/usr/bin/gnurl-config $(2)/bin/ +endef + +define Package/gnurl/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gnurl $(1)/usr/bin/ +endef + +define Package/libgnurl/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgnurl.so.* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,gnurl)) +$(eval $(call BuildPackage,libgnurl)) diff --git a/gost/Makefile b/gost/Makefile new file mode 100644 index 00000000..3c72ebbe --- /dev/null +++ b/gost/Makefile @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=gost +PKG_VERSION:=3.2.6 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/go-gost/gost/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=79874354530b899576dd4866d3b1400651d0b17c1e7a90ad30c44686a0642600 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/go-gost/gost +GO_PKG_BUILD_PKG:=$(GO_PKG)/cmd/gost +GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/gost + SECTION:=net + CATEGORY:=Network + TITLE:=GO Simple Tunnel + URL:=https://gost.run/ + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle + USERID:=gost:gost +endef + +define Package/gost/conffiles +/etc/config/gost +/etc/gost/ +endef + +define Package/gost/install + $(call GoPackage/Package/Install/Bin,$(1)) + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) $(CURDIR)/files/gost.config $(1)/etc/config/gost + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(CURDIR)/files/gost.init $(1)/etc/init.d/gost + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) $(CURDIR)/files/gost.uci $(1)/etc/uci-defaults/99-gost-migrate +endef + +$(eval $(call GoBinPackage,gost)) +$(eval $(call BuildPackage,gost)) diff --git a/gost/files/gost.config b/gost/files/gost.config new file mode 100644 index 00000000..129445ba --- /dev/null +++ b/gost/files/gost.config @@ -0,0 +1,6 @@ + +config gost 'config' + option enabled '0' + option config_file '' + #list arguments '' + diff --git a/gost/files/gost.init b/gost/files/gost.init new file mode 100644 index 00000000..3a0e5b77 --- /dev/null +++ b/gost/files/gost.init @@ -0,0 +1,46 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 +START=99 + +CONF="gost" +PROG="/usr/bin/gost" + +start_service() { + local enabled + + config_load "gost" + config_get_bool enabled "config" "enabled" 0 + [ "$enabled" -eq 1 ] || return 1 + + local config_file arguments + config_get config_file "config" "config_file" + config_get arguments "config" "arguments" + + procd_open_instance + + procd_set_param command "$PROG" + if [ -n "$config_file" ]; then + procd_append_param command -C "$config_file" + procd_set_param file "$config_file" + fi + if [ -n "$arguments" ]; then + set -- $arguments + procd_append_param command "$@" + fi + + procd_set_param user gost + procd_set_param group gost + + procd_set_param limits core="unlimited" + procd_set_param limits nofile="1000000 1000000" + procd_set_param stderr 1 + + procd_set_param respawn + + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "$CONF" +} diff --git a/gost/files/gost.uci b/gost/files/gost.uci new file mode 100644 index 00000000..b8389cb6 --- /dev/null +++ b/gost/files/gost.uci @@ -0,0 +1,10 @@ +#!/bin/sh + +grep -q "config gost$" "/etc/config/gost" || exit 0 + +sed -e "s,config gost,config gost 'config'," \ + -e "s,option enable ,option enabled ," \ + -e "s,option run_command,list arguments," \ + -i "/etc/config/gost" + +exit 0 diff --git a/gowebdav/Makefile b/gowebdav/Makefile new file mode 100644 index 00000000..ec2fa34e --- /dev/null +++ b/gowebdav/Makefile @@ -0,0 +1,56 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=gowebdav +PKG_VERSION:=5.7.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/hacdias/webdav/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=5462eaf18292727e7af66d77c1723f729c97a31d4dfe4b47343f0644a5e63454 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=ElonH + +PKG_BUILD_DIR:=$(BUILD_DIR)/webdav-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/hacdias/webdav +GO_PKG_LDFLAGS:=-s -w + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/gowebdav + SECTION:=net + CATEGORY:=Network + SUBMENU:=File Transfer + TITLE:=Simple Go WebDAV server + URL:=https://github.com/hacdias/webdav + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Package/gowebdav/description +Webdav command line interface is really easy to use so you can easily create +a WebDAV server for your own user. By default, it runs on a random free port +and supports JSON, YAML and TOML configuration. +endef + +define Package/gowebdav/install + $(call GoPackage/Package/Install/Bin,$(1)) + +# $(INSTALL_DIR) $(1)/etc/config/ $(1)/etc/init.d/ $(1)/etc/webdav/ +# $(INSTALL_BIN) $(CURDIR)/files/webdav.init $(1)/etc/init.d/webdav +# $(INSTALL_CONF) $(CURDIR)/files/webdav.config $(1)/etc/config/webdav +# $(INSTALL_CONF) $(CURDIR)/files/webdav.yaml $(1)/etc/webdav/webdav.yaml +endef + +$(eval $(call GoBinPackage,gowebdav)) +$(eval $(call BuildPackage,gowebdav)) diff --git a/gowebdav/files/webdav.config b/gowebdav/files/webdav.config new file mode 100644 index 00000000..38e8c891 --- /dev/null +++ b/gowebdav/files/webdav.config @@ -0,0 +1,3 @@ + +config webdav 'config' + option enabled '0' diff --git a/gowebdav/files/webdav.init b/gowebdav/files/webdav.init new file mode 100644 index 00000000..95372952 --- /dev/null +++ b/gowebdav/files/webdav.init @@ -0,0 +1,22 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 ImmortalWrt + +START=90 +STOP=10 + +WEBDAV="/usr/bin/webdav" + +WEBDAVCONFIG="/etc/webdav/webdav.yaml" + +start() { + local enabled="$(uci get webdav.config.enabled)" + stop + [ "${enabled}" == "1" ] || exit 0 + export HOME="/root/" + "${WEBDAV}" -c "${WEBDAVCONFIG}" >/dev/null 2>&1 & +} + +stop() { + killall -9 pgrep "${WEBDAV}" >/dev/null 2>&1 +} + diff --git a/gowebdav/files/webdav.yaml b/gowebdav/files/webdav.yaml new file mode 100644 index 00000000..bf592201 --- /dev/null +++ b/gowebdav/files/webdav.yaml @@ -0,0 +1,37 @@ +# Server related settings +address: 0.0.0.0 +port: 10880 +auth: true +tls: false +cert: cert.pem +key: key.pem +prefix: / + +# Default user settings (will be merged) +scope: . +modify: true +rules: [] + +# CORS configuration +cors: + enabled: true + credentials: true + allowed_headers: + - Depth + allowed_hosts: + - http://localhost:8999 + allowed_methods: + - GET + exposed_headers: + - Content-Length + - Content-Range + +users: + - username: video + password: 123 + scope: /mnt/sdb1 + modify: true + rules: + - regex: false + allow: false + path: /some/file diff --git a/headscale/Makefile b/headscale/Makefile new file mode 100644 index 00000000..ce798b28 --- /dev/null +++ b/headscale/Makefile @@ -0,0 +1,63 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=headscale +PKG_VERSION:=0.21.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/juanfont/headscale/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=2afbdc038508cb694be496db9ba6b63bbc611b7038e8299e60eef0f1b227f12f + +PKG_LICENSE:=BSD-3-clause +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/juanfont/headscale +GO_PKG_BUILD_PKG:=$(GO_PKG)/cmd/headscale +GO_PKG_LDFLAGS:=-s -w +GO_PKG_LDFLAGS+= \ + -X '$(GO_PKG_BUILD_PKG)/cli.Version=v$(PKG_VERSION)' + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/headscale + SECTION:=net + CATEGORY:=Network + SUBMENU:=VPN + TITLE:=A Tailscale control server + URL:=https://github.com/juanfont/headscale + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Package/headscale/description +An open source, self-hosted implementation of the Tailscale control server. +endef + +define Package/headscale/conffiles +/etc/headscale/config.yaml +/etc/headscale/db.sqlite +/etc/headscale/derp.yaml +/etc/headscale/noise_private.key +/etc/headscale/private.key +endef + +define Package/headscale/install + $(call GoPackage/Package/Install/Bin,$(1)) + + $(INSTALL_DIR) $(1)/etc/headscale + touch $(1)/etc/headscale/db.sqlite + $(INSTALL_CONF) $(PKG_BUILD_DIR)/config-example.yaml $(1)/etc/headscale/config.yaml + $(INSTALL_CONF) $(PKG_BUILD_DIR)/derp-example.yaml $(1)/etc/headscale/derp.yaml +endef + +$(eval $(call GoBinPackage,headscale)) +$(eval $(call BuildPackage,headscale)) diff --git a/hysteria/Makefile b/hysteria/Makefile new file mode 100644 index 00000000..e6c35033 --- /dev/null +++ b/hysteria/Makefile @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=hysteria +PKG_VERSION:=2.9.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/apernet/hysteria/tar.gz/app/v$(PKG_VERSION)? +PKG_HASH:=d3d0e7b2e49f0cebb861fb215aa1625e4efa895a902d768db7ea45227d88b555 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-app-v$(PKG_VERSION) + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/apernet/hysteria +GO_PKG_BUILD_PKG:=$(GO_PKG)/app/v2 +GO_PKG_LDFLAGS_X = \ + $(GO_PKG)/app/v2/cmd.appVersion=v$(PKG_VERSION) \ + $(GO_PKG)/app/v2/cmd.appType=release \ + $(GO_PKG)/app/v2/cmd.appPlatform=$(GO_OS) \ + $(GO_PKG)/app/v2/cmd.appArch=$(GO_ARCH) + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/hysteria + SECTION:=net + CATEGORY:=Network + TITLE:=A feature-packed network utility optimized for networks of poor quality + URL:=https://github.com/tobyxdd/hysteria + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/hysteria/description + Hysteria is a feature-packed network utility optimized for networks + of poor quality (e.g. satellite connections, congested public Wi-Fi, + connecting from China to servers abroad) powered by a custom version + of QUIC protocol. +endef + +define Package/hysteria/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/app $(1)/usr/bin/hysteria +endef + +$(eval $(call GoBinPackage,hysteria)) +$(eval $(call BuildPackage,hysteria)) diff --git a/internet-detector-mod-email/Makefile b/internet-detector-mod-email/Makefile new file mode 100644 index 00000000..a904f9fc --- /dev/null +++ b/internet-detector-mod-email/Makefile @@ -0,0 +1,41 @@ +# +# (Ñ) 2026 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector) +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=internet-detector-mod-email +PKG_VERSION:=1.7.3 +PKG_RELEASE:=1 +PKG_MAINTAINER:=gSpot + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Email module for internet-detector + URL:=https://github.com/gSpotx2f/luci-app-internet-detector + PKGARCH:=all + DEPENDS:=+internet-detector +mailsend +endef + +define Package/$(PKG_NAME)/description + Email support for internet-detector. +endef + +define Package/$(PKG_NAME)/conffiles +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib/lua/internet-detector/modules + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_email.lua $(1)/usr/lib/lua/internet-detector/modules/mod_email.lua +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/internet-detector-mod-email/files/usr/lib/lua/internet-detector/modules/mod_email.lua b/internet-detector-mod-email/files/usr/lib/lua/internet-detector/modules/mod_email.lua new file mode 100644 index 00000000..e078ae6a --- /dev/null +++ b/internet-detector-mod-email/files/usr/lib/lua/internet-detector/modules/mod_email.lua @@ -0,0 +1,226 @@ +--[[ + Dependences: + mailsend +--]] +local unistd = require("posix.unistd") + +local Module = { + name = "mod_email", + runPrio = 60, + config = { + debug = false, + }, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + deadPeriod = 0, + alivePeriod = 0, + mode = 0, -- 0: connected, 1: disconnected, 2: both + hostAlias = "OpenWrt", + mta = "/usr/bin/mailsend", + mtaConnectTimeout = 5, + mtaReadTimeout = 5, + mailRecipient = nil, + mailSender = nil, + mailUser = nil, + mailPassword = nil, + mailSmtp = nil, + mailSmtpPort = nil, + mailSecurity = "tls", + msgTextPattern = "[%s] (%s) @ %s", -- Message (host, instance, message) + msgSubPattern = "%s notification", -- Subject (host) + msgConnectPattern = "Connected: %s", + msgDisconnectPattern = "Disconnected: %s", + msgSeparator = " | ", + msgMaxItems = 50, + msgSendAttempts = 3, + msgSendTimeout = 5, + status = nil, + _enabled = false, + _deadCounter = 0, + _aliveCounter = 0, + _msgSentDisconnect = true, + _disconnected = true, + _msgSentConnect = true, + _connected = true, + _msgBuffer = {}, + _msgSendCounter = 3, + _msgTimeoutCounter = 5, +} + +function Module:init(t) + if t.mode ~= nil then + self.mode = tonumber(t.mode) + end + if t.dead_period ~= nil then + self.deadPeriod = tonumber(t.dead_period) + end + if t.alive_period ~= nil then + self.alivePeriod = tonumber(t.alive_period) + end + if t.host_alias then + self.hostAlias = t.host_alias + else + self.hostAlias = self.config.hostname + end + + self.mailRecipient = t.mail_recipient + self.mailSender = t.mail_sender + self.mailUser = t.mail_user + self.mailPassword = t.mail_password + self.mailSmtp = t.mail_smtp + self.mailSmtpPort = t.mail_smtp_port + + if t.mail_security ~= nil then + self.mailSecurity = t.mail_security + end + if tonumber(t.message_at_startup) == 1 then + self._msgSentDisconnect = false + self._disconnected = false + self._msgSentConnect = false + self._connected = false + end + + if unistd.access(self.mta, "x") then + self._enabled = true + else + self._enabled = false + self.syslog("err", string.format("%s: %s is not available", self.name, self.mta)) + end + + if (not self.mailRecipient or + not self.mailSender or + not self.mailUser or + not self.mailPassword or + not self.mailSmtp or + not self.mailSmtpPort) then + self._enabled = false + self.syslog("warning", string.format( + "%s: Insufficient data to connect to the SMTP server", self.name)) + end + + self._msgSendCounter = self.msgSendAttempts +end + +function Module:appendNotice(str) + self._msgBuffer[#self._msgBuffer + 1] = str + if #self._msgBuffer > self.msgMaxItems then + local t = {} + for i = #self._msgBuffer - self.msgMaxItems + 1, #self._msgBuffer do + t[#t + 1] = self._msgBuffer[i] + end + self._msgBuffer = t + end +end + +function Module:sendMessage(msg, textPattern) + local retVal = 1 + local verboseArg = "" + local emailMsg = string.format( + textPattern, self.hostAlias, self.config.serviceConfig.instance, msg) + + -- Debug + if self.config.debug then + verboseArg = " -v" + end + self.debugOutput(string.format("--- %s ---", self.name)) + + local securityArgs = "-starttls -auth-login" + if self.mailSecurity == "ssl" then + securityArgs = "-ssl -auth" + end + + local mtaCmd = string.format( + '%s%s %s -smtp "%s" -port %s -ct %s -read-timeout %s -cs utf-8 -user "%s" -pass "%s" -f "%s" -t "%s" -sub "%s" -M "%s"', + self.mta, verboseArg, securityArgs, self.mailSmtp, self.mailSmtpPort, + self.mtaConnectTimeout, self.mtaReadTimeout, + self.mailUser, self.mailPassword, self.mailSender, self.mailRecipient, + string.format(self.msgSubPattern, self.hostAlias), + emailMsg) + + -- Debug + self.debugOutput(string.format("%s: %s", self.name, mtaCmd)) + self.syslog("debug", string.format("%s: %s", self.name, mtaCmd)) + + retVal = os.execute(mtaCmd) + if retVal == 0 then + self.syslog("info", string.format( + "%s: Message sent to %s", self.name, self.mailRecipient)) + self._msgBuffer = {} + else + self.syslog("err", string.format( + "%s: An error occured while sending message", self.name)) + end + + return retVal +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if not self._enabled then + return + end + + if currentStatus == 1 then + self._aliveCounter = 0 + self._msgSentConnect = false + + if not self._disconnected then + self._disconnected = true + self:appendNotice(string.format( + self.msgDisconnectPattern, os.date("%Y.%m.%d %H:%M:%S", os.time()))) + end + + if not self._msgSentDisconnect and (self.mode == 1 or self.mode == 2) then + if self._deadCounter >= self.deadPeriod then + self._msgSendCounter = 0 + self._msgSentDisconnect = true + else + self._deadCounter = self._deadCounter + timeDiff + end + end + self._connected = false + elseif currentStatus == 0 then + self._deadCounter = 0 + self._msgSentDisconnect = false + + if not self._connected then + self._connected = true + self:appendNotice(string.format( + self.msgConnectPattern, os.date("%Y.%m.%d %H:%M:%S", os.time()))) + end + + if not self._msgSentConnect and (self.mode == 0 or self.mode == 2) then + if self._aliveCounter >= self.alivePeriod then + self._msgSendCounter = 0 + self._msgSentConnect = true + else + self._aliveCounter = self._aliveCounter + timeDiff + end + end + self._disconnected = false + end + + if self._msgSendCounter < self.msgSendAttempts then + if self._msgTimeoutCounter >= self.msgSendTimeout then + if #self._msgBuffer > 0 then + if self:sendMessage(table.concat(self._msgBuffer, self.msgSeparator), self.msgTextPattern) == 0 then + self._msgSendCounter = self.msgSendAttempts + else + self._msgSendCounter = self._msgSendCounter + 1 + end + end + self._msgTimeoutCounter = 0 + else + self._msgTimeoutCounter = self._msgTimeoutCounter + timeDiff + end + else + self._msgTimeoutCounter = self.msgSendTimeout + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector-mod-modem-restart/Makefile b/internet-detector-mod-modem-restart/Makefile new file mode 100644 index 00000000..af76c45e --- /dev/null +++ b/internet-detector-mod-modem-restart/Makefile @@ -0,0 +1,41 @@ +# +# (Ñ) 2026 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector) +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=internet-detector-mod-modem-restart +PKG_VERSION:=1.7.3 +PKG_RELEASE:=1 +PKG_MAINTAINER:=gSpot + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Modem restart module for internet-detector + URL:=https://github.com/gSpotx2f/luci-app-internet-detector + PKGARCH:=all + DEPENDS:=+internet-detector +modemmanager +endef + +define Package/$(PKG_NAME)/description + Support modem restart for internet detector. +endef + +define Package/$(PKG_NAME)/conffiles +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib/lua/internet-detector/modules + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_modem_restart.lua $(1)/usr/lib/lua/internet-detector/modules/mod_modem_restart.lua +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/internet-detector-mod-modem-restart/files/usr/lib/lua/internet-detector/modules/mod_modem_restart.lua b/internet-detector-mod-modem-restart/files/usr/lib/lua/internet-detector/modules/mod_modem_restart.lua new file mode 100644 index 00000000..7afeb5a0 --- /dev/null +++ b/internet-detector-mod-modem-restart/files/usr/lib/lua/internet-detector/modules/mod_modem_restart.lua @@ -0,0 +1,152 @@ +--[[ + Dependences: + modemmanager +--]] +local unistd = require("posix.unistd") + +local Module = { + name = "mod_modem_restart", + runPrio = 40, + config = {}, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + mmcli = "/usr/bin/mmcli", + mmInit = "/etc/init.d/modemmanager", + deadPeriod = 600, + attempts = 1, + attemptInterval = 15, + ifaceTimeout = 0, + iface = nil, + anyBand = false, + status = nil, + _enabled = false, + _attemptsCounter = 0, + _attemptIntervalCounter = 0, + _deadCounter = 0, + _firstAttempt = true, + _ifaceRestarting = false, + _ifaceRestartCounter = 0, + _disconnectedAtStartup = false, +} + +function Module:toggleIface(flag) + if not self.iface then + return + end + return os.execute( + string.format("%s %s", (flag and "/sbin/ifup" or "/sbin/ifdown"), self.iface) + ) +end + +function Module:init(t) + if t.dead_period ~= nil then + self.deadPeriod = tonumber(t.dead_period) + end + if t.attempts ~= nil then + self.attempts = tonumber(t.attempts) + end + if t.attempt_interval ~= nil then + self.attemptInterval = tonumber(t.attempt_interval) + end + if t.iface ~= nil then + self.iface = t.iface + end + if t.iface_timeout ~= nil then + self.ifaceTimeout = tonumber(t.iface_timeout) + end + if t.any_band ~= nil then + self.anyBand = (tonumber(t.any_band) ~= 0) + end + if tonumber(t.disconnected_at_startup) == 1 then + self._disconnectedAtStartup = true + end + + if not unistd.access(self.mmcli, "x") then + self.anyBand = false + end + + if (unistd.access(self.mmInit, "x") + and os.execute(string.format("%s enabled", self.mmInit)) == 0) then + self._enabled = true + else + self._enabled = false + self.syslog("err", string.format( + "%s: modemmanager service is not available", self.name)) + end +end + +function Module:restartMM() + if os.execute(string.format("%s enabled", self.mmInit)) == 0 then + if self.anyBand then + self.syslog("info", string.format( + "%s: resetting current-bands to 'any'", self.name)) + os.execute(string.format("%s -m any --set-current-bands=any", self.mmcli)) + end + + self.syslog("info", string.format("%s: reconnecting modem", self.name)) + os.execute(string.format("%s restart", self.mmInit)) + + if self.iface then + self.syslog("info", string.format( + "%s: restarting network interface '%s'", self.name, self.iface)) + self:toggleIface(false) + if self.ifaceTimeout < 1 then + self:toggleIface(true) + else + self._ifaceRestarting = true + end + end + else + self.syslog("warning", string.format( + "%s: modemmanager service is disabled", self.name)) + end + if self.attempts > 0 then + self._attemptsCounter = self._attemptsCounter + 1 + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if not self._enabled then + return + end + if self.iface and self._ifaceRestarting then + if self._ifaceRestartCounter >= self.ifaceTimeout then + self:toggleIface(true) + self._ifaceRestarting = false + self._ifaceRestartCounter = 0 + else + self._ifaceRestartCounter = self._ifaceRestartCounter + timeDiff + end + else + if currentStatus == 1 then + if self._disconnectedAtStartup and self._deadCounter >= self.deadPeriod then + if self.attempts == 0 or self._attemptsCounter < self.attempts then + if self._firstAttempt or self._attemptIntervalCounter >= self.attemptInterval then + self:restartMM() + self._attemptIntervalCounter = 0 + self._firstAttempt = false + else + self._attemptIntervalCounter = self._attemptIntervalCounter + timeDiff + end + end + else + self._deadCounter = self._deadCounter + timeDiff + end + else + self._attemptsCounter = 0 + self._attemptIntervalCounter = 0 + self._deadCounter = 0 + self._disconnectedAtStartup = true + self._firstAttempt = true + end + self._ifaceRestartCounter = 0 + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector-mod-telegram/Makefile b/internet-detector-mod-telegram/Makefile new file mode 100644 index 00000000..89cb020c --- /dev/null +++ b/internet-detector-mod-telegram/Makefile @@ -0,0 +1,45 @@ +# +# (Ñ) 2026 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector) +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=internet-detector-mod-telegram +PKG_VERSION:=1.7.3 +PKG_RELEASE:=1 +PKG_MAINTAINER:=gSpot + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Telegram messenger module for internet-detector + URL:=https://github.com/gSpotx2f/luci-app-internet-detector + PKGARCH:=all + DEPENDS:=+internet-detector +curl +ucode +ucode-mod-fs +endef + +define Package/$(PKG_NAME)/description + Telegram messenger support for internet-detector. +endef + +define Package/$(PKG_NAME)/conffiles +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib/lua/internet-detector/modules + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_telegram.lua $(1)/usr/lib/lua/internet-detector/modules/mod_telegram.lua + $(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d + $(INSTALL_DATA) ./files/usr/share/rpcd/acl.d/luci-app-internet-detector-mod-telegram.json $(1)/usr/share/rpcd/acl.d/luci-app-internet-detector-mod-telegram.json + $(INSTALL_DIR) $(1)/usr/share/rpcd/ucode + $(INSTALL_DATA) ./files/usr/share/rpcd/ucode/luci.internet-detector-mod-telegram $(1)/usr/share/rpcd/ucode/luci.internet-detector-mod-telegram +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/internet-detector-mod-telegram/files/usr/lib/lua/internet-detector/modules/mod_telegram.lua b/internet-detector-mod-telegram/files/usr/lib/lua/internet-detector/modules/mod_telegram.lua new file mode 100644 index 00000000..942c19c6 --- /dev/null +++ b/internet-detector-mod-telegram/files/usr/lib/lua/internet-detector/modules/mod_telegram.lua @@ -0,0 +1,306 @@ +--[[ + Dependences: + curl +--]] + +local unistd = require("posix.unistd") + +local Module = { + name = "mod_telegram", + runPrio = 70, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + deadPeriod = 0, + alivePeriod = 0, + mode = 0, -- 0: connected, 1: disconnected, 2: both + hostAlias = "OpenWrt", + connectTimeout = 5, + tgAPIToken = nil, + tgChatId = nil, + tgMsgURLpattern = "https://api.telegram.org/bot%s/sendMessage?chat_id=%s&parse_mode=html&text=%s", + msgTextPattern = "[%s] (%s) @ %s", -- Message (host, instance, message) + msgConnectPattern = "Connected: %s", + msgDisconnectPattern = "Disconnected: %s", + msgSeparator = " | ", + msgMaxItems = 50, + msgSendAttempts = 3, + msgSendTimeout = 5, + curlExec = "/usr/bin/curl", + curlParams = "-s -g --no-keepalive", + proxyAuthString = "", + proxyString = "", + ifaceString = "", + status = nil, + _enabled = false, + _deadCounter = 0, + _aliveCounter = 0, + _msgSentDisconnect = true, + _disconnected = true, + _msgSentConnect = true, + _connected = true, + _msgBuffer = {}, + _msgSendCounter = 3, + _msgTimeoutCounter = 5, +} + +local function prequire(package) + local retVal, pkg = pcall(require, package) + return retVal and pkg +end + +function Module:init(t) + self._enabled = true + if t.mode ~= nil then + self.mode = tonumber(t.mode) + end + if t.dead_period ~= nil then + self.deadPeriod = tonumber(t.dead_period) + end + if t.alive_period ~= nil then + self.alivePeriod = tonumber(t.alive_period) + end + if t.host_alias then + self.hostAlias = t.host_alias + else + self.hostAlias = self.config.hostname + end + if t.api_token ~= nil then + self.tgAPIToken = t.api_token + end + if t.chat_id ~= nil then + self.tgChatId = t.chat_id + end + if (t.proxy_type and t.proxy_host and t.proxy_port) then + if t.proxy_user and t.proxy_passwd then + self.proxyAuthString = string.format( + ' --proxy-user "%s:%s"', + t.proxy_user, + t.proxy_passwd) + end + self.proxyString = string.format( + " --proxy %s://%s:%d%s", + t.proxy_type, + t.proxy_host, + t.proxy_port, + self.proxyAuthString) + end + if t.iface then + self.ifaceString = " --interface " .. t.iface + end + if tonumber(t.message_at_startup) == 1 then + self._msgSentDisconnect = false + self._disconnected = false + self._msgSentConnect = false + self._connected = false + end + + if unistd.access(self.curlExec, "x") then + self._enabled = true + else + self._enabled = false + self.syslog("err", string.format("%s: %s is not available", self.name, self.curlExec)) + end + if not self.tgAPIToken then + self._enabled = false + self.syslog("err", string.format("%s: Telegram bot API token not specified.", self.name)) + end + if not self.tgChatId then + self._enabled = false + self.syslog("err", string.format("%s: Telegram chat ID not specified.", self.name)) + end + + self._msgSendCounter = self.msgSendAttempts +end + +function Module:escape(str) + local t = {} + for i in str:gmatch(".") do + if i:match("[^%w_]") then + t[#t + 1] = "%" .. string.format("%x", string.byte(i)) + else + t[#t + 1] = i + end + end + return table.concat(t) +end + +function Module:appendNotice(str) + self._msgBuffer[#self._msgBuffer + 1] = str + if #self._msgBuffer > self.msgMaxItems then + local t = {} + for i = #self._msgBuffer - self.msgMaxItems + 1, #self._msgBuffer do + t[#t + 1] = self._msgBuffer[i] + end + self._msgBuffer = t + end +end + +function Module:httpRequest(url) + local retCode = 1, data + + self.debugOutput(string.format("--- %s ---", self.name)) + + local curl = string.format( + '%s%s%s --connect-timeout %s %s "%s"; printf "\n$?";', + self.curlExec, + self.ifaceString, + self.proxyString, + self.connectTimeout, + self.curlParams, + url + ) + + self.debugOutput(curl) + + local fh = io.popen(curl, "r") + if fh then + data = fh:read("*a") + fh:close() + if data ~= nil then + local s, e = data:find("[0-9]+\n?$") + retCode = tonumber(data:sub(s)) + data = data:sub(0, s - 2) + if not data or data == "" then + data = nil + end + end + else + retCode = 1 + end + + self.debugOutput(string.format( + "data = %s; retCode = %s\n", + tostring(data), + tostring(retCode))) + + return retCode, data +end + +function Module:parseResponse(str) + local ok, errCode, desc + ok = str:match('"ok":(%w+)') + if ok == "false" then + errCode = tonumber(str:match('"error_code":(%d+)')) + if errCode then + desc = str:match('"description":"([%w%s%p_]+)"') + end + end + return ok, errCode, desc +end + +function Module:messageRequest(msg, textPattern) + local retVal = 1 + local tgMsg = string.format( + textPattern, self.hostAlias, self.config.serviceConfig.instance, msg) + local url = string.format( + self.tgMsgURLpattern, self.tgAPIToken, self.tgChatId, self:escape(tgMsg)) + + local ok, errCode, desc + local retCode, data = self:httpRequest(url) + if data then + ok, errCode, desc = self:parseResponse(data) + end + if retCode == 0 and ok == "true" then + retVal = 0 + self.syslog("info", string.format( + "%s: Message sent to chat %s", self.name, self.tgChatId)) + else + if errCode == 400 or errCode == 406 then + retVal = 2 + elseif (errCode == 401 or + errCode == 403 or + errCode == 404 or + errCode == 420) then + retVal = 3 + end + if errCode and desc then + self.syslog("warning", string.format( + "%s: %s %s", self.name, tostring(errCode), tostring(desc))) + end + end + return retVal +end + +function Module:sendMessage(msg, textPattern) + local retVal = self:messageRequest(msg, textPattern) + if retVal == 0 then + self._msgBuffer = {} + elseif retVal == 2 then + self.syslog("err", string.format( + "%s: Server error (invalid API token or chat ID)", self.name)) + else + self.syslog("err", string.format( + "%s: An error occured while sending message", self.name)) + end + return retVal +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if not self._enabled then + return + end + + if currentStatus == 1 then + self._aliveCounter = 0 + self._msgSentConnect = false + + if not self._disconnected then + self._disconnected = true + self:appendNotice(string.format( + self.msgDisconnectPattern, os.date("%Y.%m.%d %H:%M:%S", os.time()))) + end + if not self._msgSentDisconnect and (self.mode == 1 or self.mode == 2) then + if self._deadCounter >= self.deadPeriod then + self._msgSendCounter = 0 + self._msgSentDisconnect = true + else + self._deadCounter = self._deadCounter + timeDiff + end + end + self._connected = false + elseif currentStatus == 0 then + self._deadCounter = 0 + self._msgSentDisconnect = false + + if not self._connected then + self._connected = true + self:appendNotice(string.format( + self.msgConnectPattern, os.date("%Y.%m.%d %H:%M:%S", os.time()))) + end + if not self._msgSentConnect and (self.mode == 0 or self.mode == 2) then + if self._aliveCounter >= self.alivePeriod then + self._msgSendCounter = 0 + self._msgSentConnect = true + else + self._aliveCounter = self._aliveCounter + timeDiff + end + end + self._disconnected = false + end + + if self._msgSendCounter < self.msgSendAttempts then + if self._msgTimeoutCounter >= self.msgSendTimeout then + if #self._msgBuffer > 0 then + local retVal = self:sendMessage(table.concat(self._msgBuffer, self.msgSeparator), self.msgTextPattern) + if retVal == 1 then + self._msgSendCounter = self._msgSendCounter + 1 + else + self._msgSendCounter = self.msgSendAttempts + end + end + self._msgTimeoutCounter = 0 + else + self._msgTimeoutCounter = self._msgTimeoutCounter + timeDiff + end + else + self._msgTimeoutCounter = self.msgSendTimeout + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector-mod-telegram/files/usr/share/rpcd/acl.d/luci-app-internet-detector-mod-telegram.json b/internet-detector-mod-telegram/files/usr/share/rpcd/acl.d/luci-app-internet-detector-mod-telegram.json new file mode 100644 index 00000000..9bac2d4b --- /dev/null +++ b/internet-detector-mod-telegram/files/usr/share/rpcd/acl.d/luci-app-internet-detector-mod-telegram.json @@ -0,0 +1,10 @@ +{ + "luci-app-internet-detector-mod-telegram": { + "description": "Grant access to internet-detector-mod-telegram procedures", + "read": { + "ubus": { + "luci.internet-detector-mod-telegram": [ "GetTgChatId" ] + } + } + } +} diff --git a/internet-detector-mod-telegram/files/usr/share/rpcd/ucode/luci.internet-detector-mod-telegram b/internet-detector-mod-telegram/files/usr/share/rpcd/ucode/luci.internet-detector-mod-telegram new file mode 100644 index 00000000..e9e80cc2 --- /dev/null +++ b/internet-detector-mod-telegram/files/usr/share/rpcd/ucode/luci.internet-detector-mod-telegram @@ -0,0 +1,128 @@ + +'use strict'; + +import { popen, stat } from 'fs'; + +const curlPath = '/usr/bin/curl'; +const curlExec = (stat(curlPath)?.perm?.user_exec) ? curlPath : null; +const curlParams = '-s -g --no-keepalive'; +const curlConnectTimeout = 15; +const tgUpdatesURLPattern = 'https://api.telegram.org/bot%s/getUpdates'; + +if(!curlExec) { + die('Error! Curl not found!'); +} + +function httpRequest(url, proxyType, proxyHost, proxyPort, proxyUser, proxyPasswd, iface) { + let retCode = 1; + let data = ''; + let proxyAuthString = ''; + let proxyString = ''; + let ifaceString = iface ? (' --interface ' + iface) : ''; + + if(!url) { + return { retCode: 1, data }; + } + + if(proxyType && proxyHost && proxyPort) { + if(proxyUser && proxyPasswd) { + proxyAuthString = sprintf( + ' --proxy-user "%s:%s"', + proxyUser, + proxyPasswd); + } + proxyString = sprintf( + ' --proxy %s://%s:%d%s', + proxyType, + proxyHost, + proxyPort, + proxyAuthString); + } + const curl = sprintf( + '%s%s%s --connect-timeout %s %s "%s"; printf "\n$?";', + curlExec, + ifaceString, + proxyString, + curlConnectTimeout, + curlParams, + url + ); + const fd = popen(curl, 'r'); + if(fd) { + data = fd.read('all'); + fd.close(); + if(data) { + const retCodeRegexp = /[0-9]+\n?$/; + const r = match(data, retCodeRegexp); + if(length(r) > 0) { + retCode = r[0]; + } + data = replace(data, retCodeRegexp, ''); + } + } + return { retCode, data }; +} + +function parseResponse(str) { + let ok = null; + let chatId = []; + let errCode = null; + let errDesc = null; + + const data = json(str); + ok = data.ok; + if(ok == false) { + errCode = data.error_code; + errDesc = data.description; + } else { + let chats = []; + if(data.result) { + for(let i in data.result) { + if(i.message && i.message.chat && i.message.chat.id) { + push(chats, i.message.chat.id); + } + } + } + if(length(chats) > 0) { + chatId = uniq(chats); + } + } + return { ok, chatId, errCode, errDesc }; +} + +const methods = { + GetTgChatId: { + args: { + botToken : 'String', + proxyType : 'String', + proxyHost : 'String', + proxyPort : 'String', + proxyUser : 'String', + proxyPasswd: 'String', + iface : 'String', + }, + call: function(request) { + const botToken = request.args?.botToken; + if(botToken) { + const ret = httpRequest( + sprintf(tgUpdatesURLPattern, botToken), + request.args.proxyType, + request.args.proxyHost, + request.args.proxyPort, + request.args.proxyUser, + request.args.proxyPasswd, + request.args.iface + ); + if(ret.retCode == 0 && length(ret.data) > 0) { + return parseResponse(ret.data); + } else { + return { ok: null, chatId: [], errCode: ret.retCode, errDesc: 'Network request error' }; + } + } else { + return { ok: null, chatId: [], errCode: 1, errDesc: 'Bot token missing' }; + } + }, + }, +}; + +return { 'luci.internet-detector-mod-telegram': methods }; diff --git a/internet-detector/Makefile b/internet-detector/Makefile new file mode 100644 index 00000000..6b7a7ca2 --- /dev/null +++ b/internet-detector/Makefile @@ -0,0 +1,67 @@ +# +# (Ñ) 2026 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector) +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=internet-detector +PKG_VERSION:=1.7.3 +PKG_RELEASE:=1 +PKG_MAINTAINER:=gSpot + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Internet detector + URL:=https://github.com/gSpotx2f/luci-app-internet-detector + PKGARCH:=all + DEPENDS:=+lua +luaposix +libuci-lua +endef + +define Package/$(PKG_NAME)/description + Internet-detector is a small daemon + for checking Internet availability. + Written in Lua using the luaposix library. +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/internet-detector +/etc/internet-detector/down-script.internet +/etc/internet-detector/up-script.internet +/etc/internet-detector/public-ip-script.internet +/etc/internet-detector/regular-script.internet +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/internet-detector $(1)/etc/config/internet-detector + $(INSTALL_DIR) $(1)/etc/internet-detector + $(INSTALL_DATA) ./files/etc/internet-detector/down-script.internet $(1)/etc/internet-detector/down-script.internet + $(INSTALL_DATA) ./files/etc/internet-detector/up-script.internet $(1)/etc/internet-detector/up-script.internet + $(INSTALL_DATA) ./files/etc/internet-detector/public-ip-script.internet $(1)/etc/internet-detector/public-ip-script.internet + $(INSTALL_DATA) ./files/etc/internet-detector/regular-script.internet $(1)/etc/internet-detector/regular-script.internet + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/etc/init.d/internet-detector $(1)/etc/init.d/internet-detector + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) ./files/usr/bin/internet-detector $(1)/usr/bin/internet-detector + $(INSTALL_DIR) $(1)/usr/lib/lua/internet-detector + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/main.lua $(1)/usr/lib/lua/internet-detector/main.lua + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/init.lua $(1)/usr/lib/lua/internet-detector/init.lua + $(INSTALL_DIR) $(1)/usr/lib/lua/internet-detector/modules + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_led_control.lua $(1)/usr/lib/lua/internet-detector/modules/mod_led_control.lua + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_reboot.lua $(1)/usr/lib/lua/internet-detector/modules/mod_reboot.lua + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_network_restart.lua $(1)/usr/lib/lua/internet-detector/modules/mod_network_restart.lua + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_public_ip.lua $(1)/usr/lib/lua/internet-detector/modules/mod_public_ip.lua + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_user_scripts.lua $(1)/usr/lib/lua/internet-detector/modules/mod_user_scripts.lua + $(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_regular_script.lua $(1)/usr/lib/lua/internet-detector/modules/mod_regular_script.lua +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/internet-detector/files/etc/config/internet-detector b/internet-detector/files/etc/config/internet-detector new file mode 100644 index 00000000..7cc47850 --- /dev/null +++ b/internet-detector/files/etc/config/internet-detector @@ -0,0 +1,65 @@ + +config main 'config' + option mode '1' + option logging_level '6' + +config instance 'internet' + option enabled '1' + option description 'Default instance' + list hosts '8.8.8.8' + list hosts '1.1.1.1' + list urls 'https://www.google.com' + option check_type '0' + option tcp_port '53' + option interval_up '30' + option interval_down '5' + option connection_attempts '2' + option connection_timeout '2' + option mod_led_control_enabled '0' + option mod_reboot_enabled '0' + option mod_reboot_disconnected_at_startup '0' + option mod_reboot_dead_period '3600' + option mod_reboot_force_reboot_delay '300' + option mod_network_restart_enabled '0' + option mod_network_restart_disconnected_at_startup '0' + option mod_network_restart_dead_period '900' + option mod_network_restart_attempts '1' + option mod_network_restart_attempt_interval '60' + option mod_network_restart_device_timeout '0' + option mod_modem_restart_enabled '0' + option mod_modem_restart_disconnected_at_startup '0' + option mod_modem_restart_dead_period '600' + option mod_modem_restart_attempts '1' + option mod_modem_restart_attempt_interval '60' + option mod_modem_restart_iface_timeout '0' + option mod_modem_restart_any_band '0' + option mod_public_ip_enabled '0' + option mod_public_ip_provider 'opendns1' + option mod_public_ip_qtype '0' + option mod_public_ip_interval '600' + option mod_public_ip_interval_failed '60' + option mod_public_ip_request_attempts '2' + option mod_public_ip_timeout '2' + option mod_public_ip_enable_ip_script '0' + option mod_email_enabled '0' + option mod_email_message_at_startup '0' + option mod_email_mode '0' + option mod_email_alive_period '0' + option mod_email_mail_security 'tls' + option mod_telegram_enabled '0' + option mod_telegram_message_at_startup '0' + option mod_telegram_mode '0' + option mod_telegram_dead_period '0' + option mod_telegram_alive_period '0' + option mod_user_scripts_enabled '0' + option mod_user_scripts_alive_period '0' + option mod_user_scripts_up_script_attempts '1' + option mod_user_scripts_up_script_attempt_interval '60' + option mod_user_scripts_connected_at_startup '0' + option mod_user_scripts_dead_period '0' + option mod_user_scripts_down_script_attempts '1' + option mod_user_scripts_down_script_attempt_interval '60' + option mod_user_scripts_disconnected_at_startup '0' + option mod_regular_script_enabled '0' + option mod_regular_script_inet_state '2' + option mod_regular_script_interval '3600' diff --git a/internet-detector/files/etc/init.d/internet-detector b/internet-detector/files/etc/init.d/internet-detector new file mode 100755 index 00000000..5b5ffd13 --- /dev/null +++ b/internet-detector/files/etc/init.d/internet-detector @@ -0,0 +1,39 @@ +#!/bin/sh /etc/rc.common + +START=97 +STOP=01 + +USE_PROCD=1 +PROG="/usr/bin/internet-detector" + +run_instance() { + config_get enabled "$1" enabled "0" + if [ $enabled = "1" ]; then + procd_open_instance "$1" + procd_set_param command "$PROG" "-a" "nodaemon" "-i" "$1" + procd_set_param respawn + procd_set_param term_timeout 60 + procd_close_instance + fi +} + +start_service() { + config_load "internet-detector" + config_get mode "config" mode "0" + if [ $mode = "1" ]; then + config_foreach run_instance "instance" + fi +} + +stop_service() { + $PROG -a stop +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "internet-detector" +} diff --git a/internet-detector/files/etc/internet-detector/down-script.internet b/internet-detector/files/etc/internet-detector/down-script.internet new file mode 100644 index 00000000..e1f53ea4 --- /dev/null +++ b/internet-detector/files/etc/internet-detector/down-script.internet @@ -0,0 +1 @@ +# Shell commands to run when disconnected from the Internet diff --git a/internet-detector/files/etc/internet-detector/public-ip-script.internet b/internet-detector/files/etc/internet-detector/public-ip-script.internet new file mode 100644 index 00000000..cb9723f1 --- /dev/null +++ b/internet-detector/files/etc/internet-detector/public-ip-script.internet @@ -0,0 +1,2 @@ +# Shell commands that run when the public IP address changes. +# New IP is available as value of the $PUBLIC_IP variable. diff --git a/internet-detector/files/etc/internet-detector/regular-script.internet b/internet-detector/files/etc/internet-detector/regular-script.internet new file mode 100644 index 00000000..94df551c --- /dev/null +++ b/internet-detector/files/etc/internet-detector/regular-script.internet @@ -0,0 +1 @@ +# Shell commands that are run regularly diff --git a/internet-detector/files/etc/internet-detector/up-script.internet b/internet-detector/files/etc/internet-detector/up-script.internet new file mode 100644 index 00000000..b4962409 --- /dev/null +++ b/internet-detector/files/etc/internet-detector/up-script.internet @@ -0,0 +1 @@ +# Shell commands that run when connected to the Internet diff --git a/internet-detector/files/usr/bin/internet-detector b/internet-detector/files/usr/bin/internet-detector new file mode 100755 index 00000000..15a45233 --- /dev/null +++ b/internet-detector/files/usr/bin/internet-detector @@ -0,0 +1,98 @@ +#!/usr/bin/env lua + +--[[ + Internet detector daemon for OpenWrt. + + Dependences: + lua + luaposix + libuci-lua + + (Ñ) 2025 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector) +--]] + +local getopt = require("posix.unistd").getopt +local InternetDetector = require("internet-detector.main") + +local function help() + return table.concat({ + [1] = string.format( + "Usage: %s -a daemon -i | -a nodaemon -i | -a debug -i | -a stop | -S | -I | -U | -h", + arg[0]), + [2] = " -a ARG action: daemon | nodaemon | debug | stop", + [3] = " -i ARG instance: UCI instance name", + [4] = " -S status", + [5] = " -I inet status", + [6] = " -U uipoll", + [7] = " -h print this help text" + }, "\n") +end + +local action, instance +local params = {} +local last_index = 1 +for r, optarg, optind in getopt(arg, "a:i:SIUh") do + if r == "?" then + print("Error! Unrecognized option") + os.exit(1) + end + last_index = optind + if r == "a" then + action = optarg + elseif r == "i" then + instance = optarg + else + params[#params + 1] = r + end +end +if action == "stop" then + InternetDetector:stop() +elseif action then + if not instance then + print("Error! Instance not specified [-i]") + os.exit(1) + end + if action == "daemon" then + if InternetDetector:setServiceConfig(instance) then + InternetDetector:daemon() + else + os.exit(126) + end + elseif action == "nodaemon" then + if InternetDetector:setServiceConfig(instance) then + InternetDetector:noDaemon() + else + os.exit(126) + end + elseif action == "debug" then + if InternetDetector:setServiceConfig(instance) then + InternetDetector.debug = true + InternetDetector:noDaemon() + else + os.exit(126) + end + else + print("Error! Wrong action [-a]") + os.exit(1) + end +else + if params[1] == "S" then + print(InternetDetector:status()) + elseif params[1] == "I" then + print(InternetDetector:inetStatus()) + elseif params[1] == "U" then + if InternetDetector:status() == "stoped" then + os.exit(126) + else + InternetDetector:setSIGUSR() + print(InternetDetector:inetStatus()) + end + elseif params[1] == "h" then + print(help()) + else + print(help()) + os.exit(1) + end +end + +os.exit(0) diff --git a/internet-detector/files/usr/lib/lua/internet-detector/init.lua b/internet-detector/files/usr/lib/lua/internet-detector/init.lua new file mode 100644 index 00000000..74c7342d --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/init.lua @@ -0,0 +1 @@ +return require("internet-detector.main") diff --git a/internet-detector/files/usr/lib/lua/internet-detector/main.lua b/internet-detector/files/usr/lib/lua/internet-detector/main.lua new file mode 100644 index 00000000..d4c90cb1 --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/main.lua @@ -0,0 +1,806 @@ + +local dirent = require("posix.dirent") +local fcntl = require("posix.fcntl") +local signal = require("posix.signal") +local socket = require("posix.sys.socket") +local stat = require("posix.sys.stat") +local syslog = require("posix.syslog") +local time = require("posix.time") +local unistd = require("posix.unistd") +local uci = require("uci") + +-- Default settings + +local InternetDetector = { + appName = "internet-detector", + libDir = "/usr/lib/lua", + logLevels = { + emerg = { level = syslog.LOG_EMERG, num = 0 }, + alert = { level = syslog.LOG_ALERT, num = 1 }, + crit = { level = syslog.LOG_CRIT, num = 2 }, + err = { level = syslog.LOG_ERR, num = 3 }, + warning = { level = syslog.LOG_WARNING, num = 4 }, + notice = { level = syslog.LOG_NOTICE, num = 5 }, + info = { level = syslog.LOG_INFO, num = 6 }, + debug = { level = syslog.LOG_DEBUG, num = 7 }, + }, + pingCmd = "/bin/ping", + pingParams = "-c 1", + curlExec = "/usr/bin/curl", + curlParams = '-s -g --no-keepalive --head --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0"', + mode = 0, -- 0: disabled, 1: Service, 2: UI detector + loggingLevel = 6, + hostname = "OpenWrt", + uiRunTime = 30, + noModules = false, + uiAvailModules = { mod_public_ip = true }, + debug = false, + serviceConfig = { + hosts = { + [1] = "8.8.8.8", + [2] = "1.1.1.1", + }, + urls = { + [1] = "https://www.google.com", + }, + check_type = 0, -- 0: TCP, 1: ICMP + tcp_port = 53, + icmp_packet_size = 56, + interval_up = 30, + interval_down = 5, + connection_attempts = 2, + connection_timeout = 2, + proxy_type = nil, + proxy_host = nil, + proxy_port = nil, + proxy_user = nil, + proxy_passwd = nil, + iface = nil, + instance = nil, + }, + modules = {}, + parsedHosts = {}, + proxyAuthString = "", + proxyString = "", + uiCounter = 0, + pidFile = nil, + statusFile = nil, +} +InternetDetector.configDir = string.format("/etc/%s", InternetDetector.appName) +InternetDetector.modulesDir = string.format( + "%s/%s/modules", InternetDetector.libDir, InternetDetector.appName) +InternetDetector.commonDir = string.format("/tmp/run/%s", InternetDetector.appName) +InternetDetector.appNamePattern = InternetDetector.appName:gsub("-", "%%-") +InternetDetector.pidFilePattern = "^" .. InternetDetector.appNamePattern .. ".-%.pid$" + +-- Loading settings from UCI + +local uciCursor = uci.cursor() +local mode, err = uciCursor:get(InternetDetector.appName, "config", "mode") +if mode ~= nil then + InternetDetector.mode = tonumber(mode) +elseif err then + io.stderr:write(string.format("Error: %s\n", err)) +end +local loggingLevel, err = uciCursor:get(InternetDetector.appName, "config", "logging_level") +if loggingLevel ~= nil then + InternetDetector.loggingLevel = tonumber(loggingLevel) +elseif err then + io.stderr:write(string.format("Error: %s\n", err)) +end +local hostname, err = uciCursor:get("system", "@[0]", "hostname") +if hostname ~= nil then + InternetDetector.hostname = hostname +elseif err then + io.stderr:write(string.format("Error: %s\n", err)) +end + +function InternetDetector:prequire(package) + local ok, pkg = pcall(require, package) + return ok and pkg +end + +function InternetDetector:loadInstanceConfig(instance) + local sections = uciCursor:get_all(self.appName) + local t = sections[instance] + if t then + for k, v in pairs(t) do + if type(v) == "string" and v:match("^[%d]+$") then + v = tonumber(v) + end + self.serviceConfig[k] = v + end + self.serviceConfig.instance = instance + self.serviceConfig.instanceNum = t[".index"] + return true + end + return false +end + +function InternetDetector:writeValueToFile(filePath, str) + local retValue = false + local fh = io.open(filePath, "w") + if fh then + fh:setvbuf("no") + fh:write(string.format("%s\n", str)) + fh:close() + retValue = true + end + return retValue +end + +function InternetDetector:readValueFromFile(filePath) + local retValue + local fh = io.open(filePath, "r") + if fh then + retValue = fh:read("*l") + fh:close() + end + return retValue +end + +function InternetDetector:statusJson(inet, instance, t) + local lines = { [1] = string.format( + '{"instance":"%s","num":"%d","inet":%d', + instance, + self.serviceConfig.instanceNum, + inet)} + if t then + for k, v in pairs(t) do + lines[#lines + 1] = string.format('"%s":"%s"', k, v) + end + end + return table.concat(lines, ",") .. "}" +end + +function InternetDetector:writeLogMessage(level, msg) + local levelItem = self.logLevels[level] + local levelValue = (levelItem and levelItem.level) or self.logLevels["info"].level + local num = (levelItem and levelItem.num) or self.logLevels["info"].num + if num <= self.loggingLevel then + syslog.syslog(levelValue, string.format( + "%s: %s", self.serviceConfig.instance or "", msg)) + end +end + +function InternetDetector:debugOutput(msg) + if self.debug then + io.stdout:write(string.format("[%s] %s\n", os.date("%Y.%m.%d-%H:%M:%S"), msg)) + io.stdout:flush() + end +end + +function InternetDetector:loadModules() + self.modules = {} + local ok, modulesDir = pcall(dirent.files, self.modulesDir) + if ok then + for item in modulesDir do + if item:match("^mod_") then + local modName = item:gsub("%.lua$", "") + if self.noModules and not self.uiAvailModules[modName] then + else + local modConfig = {} + for k, v in pairs(self.serviceConfig) do + if k:match("^" .. modName) then + modConfig[k:gsub("^" .. modName .. "_", "")] = v + end + end + if modConfig.enabled == 1 then + local m + if self.debug then + m = require(string.format("%s.modules.%s", self.appName, modName)) + else + m = self:prequire(string.format("%s.modules.%s", self.appName, modName)) + end + if m then + m.config = self + m.syslog = function(level, msg) self:writeLogMessage(level, msg) end + m.debugOutput = function(msg) self:debugOutput(msg) end + m.writeValue = function(filePath, str) return self:writeValueToFile(filePath, str) end + m.readValue = function(filePath) return self:readValueFromFile(filePath) end + m:init(modConfig) + self.modules[#self.modules + 1] = m + end + end + end + end + end + table.sort(self.modules, function(a, b) return a.runPrio < b.runPrio end) + end +end + +function InternetDetector:parseHost(host) + local addr, port = host:match("^([^%[%]:]+):?(%d?%d?%d?%d?%d?)$") + if not addr then + addr, port = host:match("^%[?([^%[%]]+)%]?:?(%d?%d?%d?%d?%d?)$") + end + return addr, tonumber(port) +end + +function InternetDetector:parseHosts() + self.parsedHosts = {} + for k, v in ipairs(self.serviceConfig.hosts) do + local addr, port = self:parseHost(v) + self.parsedHosts[k] = { addr = addr, port = port } + end +end + +function InternetDetector:parseUrls() + self.parsedHosts = {} + for k, v in ipairs(self.serviceConfig.urls) do + self.parsedHosts[k] = { addr = v } + end +end + +function InternetDetector:pingHost(host) + local ping = string.format( + "%s %s -W %d -s %d%s %s > /dev/null 2>&1", + self.pingCmd, + self.pingParams, + self.serviceConfig.connection_timeout, + self.serviceConfig.icmp_packet_size, + self.serviceConfig.iface and (" -I " .. self.serviceConfig.iface) or "", + host + ) + local retCode = os.execute(ping) + + self:debugOutput(string.format( + "--- Ping ---\ntime = %s\n%s\nretCode = %s", os.time(), ping, retCode)) + + return retCode +end + +function InternetDetector:TCPConnectionToHost(host, port) + local retCode = 1 + local saTable, errMsg, errNum = socket.getaddrinfo(host, port or self.serviceConfig.tcp_port) + + if not saTable then + self:debugOutput(string.format( + "GETADDRINFO ERROR: %s, %s", errMsg, errNum)) + else + local family = saTable[1].family + + if family then + local sock, errMsg, errNum = socket.socket(family, socket.SOCK_STREAM, 0) + + if not sock then + self:debugOutput(string.format( + "SOCKET ERROR: %s, %s", errMsg, errNum)) + return retCode + end + + socket.setsockopt(sock, socket.SOL_SOCKET, + socket.SO_SNDTIMEO, self.serviceConfig.connection_timeout, 0) + socket.setsockopt(sock, socket.SOL_SOCKET, + socket.SO_RCVTIMEO, self.serviceConfig.connection_timeout, 0) + + if self.serviceConfig.iface then + local ok, errMsg, errNum = socket.setsockopt(sock, socket.SOL_SOCKET, + socket.SO_BINDTODEVICE, self.serviceConfig.iface) + if not ok then + self:debugOutput(string.format( + "SOCKET ERROR: %s, %s", errMsg, errNum)) + + unistd.close(sock) + return retCode + end + end + + local success = socket.connect(sock, saTable[1]) + + if self.debug then + if not success then + self:debugOutput(string.format( + "SOCKET CONNECT ERROR: %s", tostring(success))) + end + local sockTable, err_s, e_s = socket.getsockname(sock) + local peerTable, err_p, e_p = socket.getpeername(sock) + if not sockTable then + sockTable = {} + self:debugOutput( + string.format("SOCKET ERROR: %s, %s", err_s, e_s)) + end + if not peerTable then + peerTable = {} + self:debugOutput( + string.format("SOCKET ERROR: %s, %s", err_p, e_p)) + end + self:debugOutput(string.format( + "--- TCP ---\ntime = %s\nconnection_timeout = %s\niface = %s\nhost:port = [%s]:%s\nsockname = [%s]:%s\npeername = [%s]:%s\nsuccess = %s", + os.time(), + self.serviceConfig.connection_timeout, + tostring(self.serviceConfig.iface), + host, + port or self.serviceConfig.tcp_port, + tostring(sockTable.addr), + tostring(sockTable.port), + tostring(peerTable.addr), + tostring(peerTable.port), + tostring(success)) + ) + end + + socket.shutdown(sock, socket.SHUT_RDWR) + unistd.close(sock) + retCode = success and 0 or 1 + end + end + return retCode +end + +function InternetDetector:httpRequest(url) + local retCode = 1, data + local curl = string.format( + '%s%s%s --connect-timeout %s %s "%s"; printf "\n$?";', + self.curlExec, + self.serviceConfig.iface and (" --interface " .. self.serviceConfig.iface) or "", + self.proxyString, + self.serviceConfig.connection_timeout, + self.curlParams, + url + ) + local fh = io.popen(curl, "r") + if fh then + data = fh:read("*a") + fh:close() + if data ~= nil then + local s, e = data:find("[0-9]+\n?$") + retCode = tonumber(data:sub(s)) + data = data:sub(0, s - 2) + if not data or data == "" then + data = nil + end + end + else + retCode = 1 + end + + self:debugOutput(string.format( + "--- Curl ---\ntime = %s\n%s\nretCode = %s\ndata = [\n%s]\n", + os.time(), + curl, + retCode, + tostring(data))) + + return retCode, data +end + +function InternetDetector:getHTTPCode(data) + local httpCode + local respHeader = data:match("^HTTP/[^%c]+") + if respHeader then + httpCode = respHeader:match("%d%d%d") + end + return tonumber(httpCode) +end + +function InternetDetector:checkURL(url) + local httpCode + local retCode, data = self:httpRequest(url) + if retCode == 0 and data then + httpCode = self:getHTTPCode(data) + end + return (httpCode ~= 200) and 1 or 0 +end + +function InternetDetector:exit() + for _, e in ipairs(self.modules) do + e:onExit() + end + self:removeProcessFiles() + if self.loggingLevel > 0 then + self:writeLogMessage("info", "stoped") + syslog.closelog() + end + os.exit(0) +end + +function InternetDetector:resetUiCounter(signo) + self.uiCounter = 0 +end + +function InternetDetector:mainLoop() + signal.signal(signal.SIGTERM, function(signo) self:exit(signo) end) + signal.signal(signal.SIGINT, function(signo) self:exit(signo) end) + signal.signal(signal.SIGQUIT, function(signo) self:exit(signo) end) + signal.signal(signal.SIGUSR1, function(signo) self:resetUiCounter(signo) end) + + local mTimeNow, mTimeDiff, mLastTime, uiTimeNow, uiLastTime + local lastStatus = -1 + local currentStatus = -1 + local interval = self.serviceConfig.interval_up + local modulesStatus = {} + local counter = 0 + local inetChecked = false + local checking = false + local hostNum = 1 + local attempt = 1 + + local checkFunc = self.TCPConnectionToHost + if self.serviceConfig.check_type == 1 then + checkFunc = self.pingHost + self:parseHosts() + elseif self.serviceConfig.check_type == 2 then + checkFunc = self.checkURL + self:parseUrls() + if (self.serviceConfig.proxy_type and self.serviceConfig.proxy_host and + self.serviceConfig.proxy_port) then + if self.serviceConfig.proxy_user and self.serviceConfig.proxy_passwd then + self.proxyAuthString = string.format( + ' --proxy-user "%s:%s"', + self.serviceConfig.proxy_user, + self.serviceConfig.proxy_passwd) + end + self.proxyString = string.format( + " --proxy %s://%s:%d%s", + self.serviceConfig.proxy_type, + self.serviceConfig.proxy_host, + self.serviceConfig.proxy_port, + self.proxyAuthString) + end + else + self:parseHosts() + end + + self:writeValueToFile( + self.statusFile, self:statusJson(currentStatus, self.serviceConfig.instance)) + + while true do + if counter == 0 or counter >= interval then + checking = true + end + + inetChecked = false + + if checking then + local newStatus = 1 + if hostNum <= #self.parsedHosts then + if attempt <= self.serviceConfig.connection_attempts then + local addr = self.parsedHosts[hostNum].addr + local port = self.parsedHosts[hostNum].port + local retCode = 1 + if self.debug then + retCode = checkFunc(self, addr, port) + else + local ok, status = pcall(checkFunc, self, addr, port) + if ok then + retCode = status + else + self:writeLogMessage("err", string.format( + "An error occurred while checking the host %s: %s", + tostring(addr), + tostring(status)) + ) + end + end + if retCode == 0 then + attempt = 1 + hostNum = 1 + checking = false + newStatus = 0 + counter = 0 + inetChecked = true + else + attempt = attempt + 1 + if attempt > self.serviceConfig.connection_attempts then + attempt = 1 + hostNum = hostNum + 1 + end + end + else + attempt = 1 + hostNum = hostNum + 1 + end + if hostNum > #self.parsedHosts then + hostNum = 1 + checking = false + counter = 0 + inetChecked = true + end + else + hostNum = 1 + checking = false + counter = 0 + inetChecked = true + end + + if inetChecked then + currentStatus = newStatus + if not stat.stat(self.statusFile) then + self:writeValueToFile(self.statusFile, self:statusJson( + currentStatus, self.serviceConfig.instance)) + end + if currentStatus == 0 then + interval = self.serviceConfig.interval_up + if currentStatus ~= lastStatus then + self:writeValueToFile(self.statusFile, self:statusJson( + currentStatus, self.serviceConfig.instance)) + self:writeLogMessage("notice", "Connected") + end + elseif currentStatus == 1 then + interval = self.serviceConfig.interval_down + if currentStatus ~= lastStatus then + self:writeValueToFile(self.statusFile, self:statusJson( + currentStatus, self.serviceConfig.instance)) + self:writeLogMessage("notice", "Disconnected") + end + end + end + end + + mTimeDiff = 0 + for _, e in ipairs(self.modules) do + mTimeNow = time.clock_gettime(time.CLOCK_MONOTONIC).tv_sec + if mLastTime then + mTimeDiff = mTimeDiff + mTimeNow - mLastTime + else + mTimeDiff = 1 + end + mLastTime = mTimeNow + + if self.debug then + e:run(currentStatus, lastStatus, mTimeDiff, mTimeNow, inetChecked) + else + local ok, err = pcall(e.run, e, currentStatus, lastStatus, mTimeDiff, mTimeNow, inetChecked) + if not ok then + self:writeLogMessage("err", string.format( + "%s: Module error: %s", e.name, tostring(err))) + end + end + end + + local modStatusChanged = false + for k, v in ipairs(self.modules) do + if modulesStatus[v.name] ~= v.status then + modulesStatus[v.name] = v.status + modStatusChanged = true + end + end + if modStatusChanged and next(modulesStatus) then + self:writeValueToFile(self.statusFile, self:statusJson( + currentStatus, self.serviceConfig.instance, modulesStatus)) + end + + unistd.sleep(1) + + if not checking then + lastStatus = currentStatus + counter = counter + 1 + end + + if self.mode == 2 then + uiTimeNow = time.clock_gettime(time.CLOCK_MONOTONIC).tv_sec + if uiLastTime then + self.uiCounter = self.uiCounter + uiTimeNow - uiLastTime + else + self.uiCounter = self.uiCounter + 1 + end + uiLastTime = uiTimeNow + if self.uiCounter >= self.uiRunTime then + self:exit(signal.SIGTERM) + end + end + end +end + +function InternetDetector:removeProcessFiles() + os.remove(self.statusFile) + os.remove(self.pidFile) +end + +function InternetDetector:status() + local ok, commonDir = pcall(dirent.files, self.commonDir) + if ok then + for item in commonDir do + if item:match(self.pidFilePattern) then + return "running" + end + end + end + return "stoped" +end + +function InternetDetector:inetStatus() + local inetStat = '{"instances":[]}' + local ok, commonDir = pcall(dirent.files, self.commonDir) + if ok then + local statusFilePattern = "^" .. self.appNamePattern .. ".-%.status$" + local lines = {} + for item in commonDir do + if item:match(statusFilePattern) then + lines[#lines + 1] = self:readValueFromFile( + string.format("%s/%s", self.commonDir, item)) + end + end + inetStat = '{"instances":[' .. table.concat(lines, ",") .. "]}" + end + return inetStat +end + +function InternetDetector:stopInstance(pidFile) + local retVal = false, pidValue + if stat.stat(pidFile) then + pidValue = self:readValueFromFile(pidFile) + if pidValue then + local ok, errMsg, errNum + for i = 0, 10 do + ok, errMsg, errNum = signal.kill(tonumber(pidValue), signal.SIGTERM) + if ok then + break + end + end + if not ok then + io.stderr:write(string.format( + 'Process stopping error: %s (%s). PID: "%s"\n', errMsg, errNum, pidValue)) + end + if errNum == 3 then + os.remove(pidFile) + end + retVal = true + else + os.remove(pidFile) + end + end + if not pidValue then + io.stderr:write( + string.format('PID file "%s" does not exists. Is the %s not running?\n', + pidFile, self.appName)) + end + return retVal +end + +function InternetDetector:stop() + local nopids = false + for i = 0, 100 do + nopids = true + local ok, commonDir = pcall(dirent.files, self.commonDir) + if ok then + for item in commonDir do + if item:match(self.pidFilePattern) then + if self:stopInstance(string.format("%s/%s", self.commonDir, item)) then + nopids = false + end + end + end + if nopids then + break + end + time.nanosleep({ tv_sec = 0, tv_nsec = 10000000 }) + else + break + end + end +end + +function InternetDetector:setSIGUSR() + local ok, commonDir = pcall(dirent.files, self.commonDir) + if ok then + for item in commonDir do + if item:match(self.pidFilePattern) then + pidValue = self:readValueFromFile(string.format("%s/%s", self.commonDir, item)) + if pidValue then + signal.kill(tonumber(pidValue), signal.SIGUSR1) + end + end + end + end +end + +function InternetDetector:preRun() + -- Exit if internet-detector mode != (1 or 2) + if self.mode ~= 1 and self.mode ~= 2 then + io.stderr:write(string.format('Start failed, mode != (1 or 2)\n', self.appName)) + os.exit(0) + end + local s = stat.stat(self.commonDir) + if not s or not (stat.S_ISDIR(s.st_mode) ~= 0) then + if not stat.mkdir(self.commonDir) then + io.stderr:write( + string.format('Error occurred while creating %s. Exit.\n', self.commonDir)) + os.exit(1) + end + end + if self.serviceConfig.check_type == 2 and not unistd.access(self.curlExec, "x") then + io.stderr:write(string.format( + "Error, %s is not available. You need to install curl.\n", self.curlExec)) + os.exit(1) + end + local ok, commonDir = pcall(dirent.files, self.commonDir) + if ok then + local instancePattern = "^" .. self.appNamePattern .. "%." .. self.serviceConfig.instance .. "%.[%d]+%.pid$" + for item in commonDir do + if item:match(instancePattern) then + self:stopInstance(string.format("%s/%s", self.commonDir, item)) + end + end + end +end + +function InternetDetector:run() + local pidValue = unistd.getpid() + self.pidFile = string.format( + "%s/%s.%s.%s.pid", self.commonDir, self.appName, self.serviceConfig.instance, pidValue) + self.statusFile = string.format( + "%s/%s.%s.status", self.commonDir, self.appName, self.serviceConfig.instance) + self:writeValueToFile(self.pidFile, pidValue) + + if self.loggingLevel > 0 then + syslog.openlog(self.appName, syslog.LOG_PID, syslog.LOG_DAEMON) + end + self:writeLogMessage("info", "started") + self:loadModules() + + -- Loaded modules + local modules = {} + for _, v in ipairs(self.modules) do + modules[#modules + 1] = string.format("%s", v.name) + end + if #modules > 0 then + self:writeLogMessage( + "info", string.format("Loaded modules: %s", table.concat(modules, ", ")) + ) + end + + if self.debug then + local function inspectTable() + local tables = {}, f + f = function(t, prefix) + tables[t] = true + for k, v in pairs(t) do + self:debugOutput(string.format( + "%s%s = %s", prefix, k, tostring(v)) + ) + if type(v) == "table" and not tables[v] then + f(v, string.format("%s%s.", prefix, k)) + end + end + end + return f + end + + self:debugOutput("--- Config ---") + inspectTable()(self, "self.") + end + + self:mainLoop() + self:exit() +end + +function InternetDetector:noDaemon() + self:preRun() + self:run() +end + +function InternetDetector:daemon() + self:preRun() + -- UNIX double fork + if unistd.fork() == 0 then + unistd.setpid("s") + if unistd.fork() == 0 then + unistd.chdir("/") + stat.umask(0) + local devnull = fcntl.open("/dev/null", fcntl.O_RDWR) + io.stdout:flush() + io.stderr:flush() + unistd.dup2(devnull, 0) -- io.stdin + unistd.dup2(devnull, 1) -- io.stdout + unistd.dup2(devnull, 2) -- io.stderr + self:run() + unistd.close(devnull) + end + os.exit(0) + end + os.exit(0) +end + +function InternetDetector:setServiceConfig(instance) + if self:loadInstanceConfig(instance) then + if self.mode == 2 then + self.loggingLevel = 0 + self.noModules = true + end + return true + end +end + +return InternetDetector diff --git a/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_led_control.lua b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_led_control.lua new file mode 100644 index 00000000..f99b810a --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_led_control.lua @@ -0,0 +1,334 @@ + +local dirent = require("posix.dirent") +local time = require("posix.time") +local unistd = require("posix.unistd") + +local Module = { + name = "mod_led_control", + runPrio = 10, + config = {}, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + runInterval = 5, + sysLedsDir = "/sys/class/leds", + ledsPerInstance = 3, + ledAction1Default = 1, -- 1: off, 2: on, 3: blinking, 4: netdev + ledAction2Default = 1, + ledBlinkDelayDefault = 500, + ledNetlinkDeviceDefault = nil, + ledNetdevModeLinkDefault = "1", + ledNetdevModeRxDefault = "0", + ledNetdevModeTxDefault = "0", + status = nil, + _enabled = false, + _leds = {}, + _counter = 0, + _exit = false, +} + +function Module:setLedAttrs(t) + t.ledDir = string.format("%s/%s", self.sysLedsDir, t.ledName) + t.ledMaxBrightnessFile = string.format("%s/max_brightness", t.ledDir) + t.ledBrightnessFile = string.format("%s/brightness", t.ledDir) + t.ledMaxBrightness = self.readValue(t.ledMaxBrightnessFile) or "1" + t.ledTriggerFile = string.format("%s/trigger", t.ledDir) + t.ledDelayOnFile = string.format("%s/delay_on", t.ledDir) + t.ledDelayOffFile = string.format("%s/delay_off", t.ledDir) + t.ledDeviceNameFile = string.format("%s/device_name", t.ledDir) + t.ledLinkFile = string.format("%s/link", t.ledDir) + t.ledRxFile = string.format("%s/rx", t.ledDir) + t.ledTxFile = string.format("%s/tx", t.ledDir) + t.ledPrevState = { + brightness = self.readValue(t.ledBrightnessFile), + trigger = self.readValue(t.ledTriggerFile), + } + if t.ledPrevState.trigger then + local val = t.ledPrevState.trigger:match("%[[%w%-_]+%]") + if val then + t.ledPrevState.trigger = val:gsub("[%]%[]", "") + end + end +end + +function Module:checkLed(t) + return (unistd.access(t.ledDir, "r") and + unistd.access(t.ledBrightnessFile, "rw") and + unistd.access(t.ledTriggerFile, "rw")) +end + +function Module:init(t) + for i = 1, self.ledsPerInstance do + self._leds[i] = {} + end + if t.led1_name then + self._enabled = true + else + return + end + for i, l in ipairs(self._leds) do + local led = "led" .. i + if t[led .. "_name"] ~= nil then + l.ledName = t[led .. "_name"] + l.ledAction1 = tonumber(t[led .. "_action_1"]) or self.ledAction1Default + l.ledAction2 = tonumber(t[led .. "_action_2"]) or self.ledAction2Default + l.ledBlinkOnDelay1 = tonumber(t[led .. "_blink_on_delay_1"]) or self.ledBlinkDelayDefault + l.ledBlinkOffDelay1 = tonumber(t[led .. "_blink_off_delay_1"]) or self.ledBlinkDelayDefault + l.ledBlinkOnDelay2 = tonumber(t[led .. "_blink_on_delay_2"]) or self.ledBlinkDelayDefault + l.ledBlinkOffDelay2 = tonumber(t[led .. "_blink_off_delay_2"]) or self.ledBlinkDelayDefault + l.ledNetlinkDevice1 = t[led .. "_netdev_device_1"] or self.ledNetlinkDeviceDefault + l.ledNetlinkDevice2 = t[led .. "_netdev_device_2"] or self.ledNetlinkDeviceDefault + l.ledNetdevModeLink1 = self.ledNetdevModeLinkDefault + l.ledNetdevModeTx1 = self.ledNetdevModeTxDefault + l.ledNetdevModeRx1 = self.ledNetdevModeRxDefault + l.ledNetdevModeLink2 = self.ledNetdevModeLinkDefault + l.ledNetdevModeTx2 = self.ledNetdevModeTxDefault + l.ledNetdevModeRx2 = self.ledNetdevModeRxDefault + local ndm1 = t[led .. "_netdev_mode_1"] + if ndm1 ~= nil and type(ndm1) == "table" then + local enabledFlags = {} + for _, v in ipairs(ndm1) do + enabledFlags[v] = "1" + end + l.ledNetdevModeLink1 = enabledFlags.link or "0" + l.ledNetdevModeTx1 = enabledFlags.tx or "0" + l.ledNetdevModeRx1 = enabledFlags.rx or "0" + end + local ndm2 = t[led .. "_netdev_mode_2"] + if ndm2 ~= nil and type(ndm2) == "table" then + local enabledFlags = {} + for _, v in ipairs(ndm2) do + enabledFlags[v] = "1" + end + l.ledNetdevModeLink2 = enabledFlags.link or "0" + l.ledNetdevModeTx2 = enabledFlags.tx or "0" + l.ledNetdevModeRx2 = enabledFlags.rx or "0" + end + self:setLedAttrs(l) + l.enabled = true + else + l.enabled = false + end + if l.enabled and not self:checkLed(l) then + self._enabled = false + self.syslog("err", string.format( + "%s: module disabled. LED '%s' is not available", self.name, l.ledName)) + end + self._exit = false + end +end + +function Module:checkLedTimer(t) + return (unistd.access(t.ledDelayOnFile, "rw") and unistd.access(t.ledDelayOffFile, "rw")) +end + +function Module:checkLedNetdev(t) + return (unistd.access(t.ledDeviceNameFile, "rw") and + unistd.access(t.ledLinkFile, "rw") and + unistd.access(t.ledRxFile, "rw") and + unistd.access(t.ledTxFile, "rw")) +end + +function Module:setTriggerNone(t) + self.writeValue(t.ledTriggerFile, "none") + self.debugOutput(string.format( + "%s: LED TRIGGER SET: none, %s", self.name, t.ledTriggerFile)) +end + +function Module:setTriggerTimer(t, delayOn, delayOff) + if not delayOn then + delayOn = self.ledBlinkDelayDefault + end + if not delayOff then + delayOff = self.ledBlinkDelayDefault + end + + self.writeValue(t.ledTriggerFile, "timer") + + for i = 0, 10 do + if self:checkLedTimer(t) then + self.writeValue(t.ledDelayOnFile, delayOn) + self.writeValue(t.ledDelayOffFile, delayOff) + break + else + time.nanosleep({ tv_sec = 0, tv_nsec = 500000 }) + end + end + + self.debugOutput(string.format( + "%s: LED TRIGGER SET: timer, %s; delayOn = %s, delayOff = %s", + self.name, t.ledTriggerFile, tostring(delayOn), tostring(delayOff)) + ) +end + +function Module:setTriggerNetdev(t, device, link, tx, rx) + if not device then + return + end + + self.writeValue(t.ledTriggerFile, "netdev") + + for i = 0, 10 do + if self:checkLedNetdev(t) then + self.writeValue(t.ledDeviceNameFile, device) + self.writeValue(t.ledLinkFile, link) + self.writeValue(t.ledTxFile, tx) + self.writeValue(t.ledRxFile, rx) + break + else + time.nanosleep({ tv_sec = 0, tv_nsec = 500000 }) + end + end + + self.debugOutput(string.format( + "%s: LED TRIGGER SET: netdev, %s; device = %s, link = %s, rx = %s, tx = %s", + self.name, t.ledTriggerFile, tostring(device), tostring(link), tostring(rx), tostring(tx)) + ) +end + +function Module:getCurrentTrigger(t) + local trigger = self.readValue(t.ledTriggerFile) + if trigger then + if trigger:match("%[timer%]") then + return "timer" + elseif trigger:match("%[netdev%]") then + return "netdev" + end + end +end + +function Module:getTriggerValues(t, trigger) + local currentTrigger = self:getCurrentTrigger(t) + if trigger == currentTrigger then + if trigger == "timer" then + return { + trigger = currentTrigger, + delayOn = tonumber(self.readValue(t.ledDelayOnFile)), + delayOff = tonumber(self.readValue(t.ledDelayOffFile)), + } + elseif trigger == "netdev" then + return { + trigger = currentTrigger, + device = self.readValue(t.ledDeviceNameFile), + link = self.readValue(t.ledLinkFile), + tx = self.readValue(t.ledTxFile), + rx = self.readValue(t.ledRxFile), + } + end + end + return {} +end + +function Module:on(t) + self:setTriggerNone(t) + self.writeValue(t.ledBrightnessFile, t.ledMaxBrightness) + + self.debugOutput(string.format("%s: LED ON: %s", self.name, t.ledBrightnessFile)) +end + +function Module:off(t) + self:setTriggerNone(t) + self.writeValue(t.ledBrightnessFile, "0") + + self.debugOutput(string.format("%s: LED OFF: %s", self.name, t.ledBrightnessFile)) +end + +function Module:getCurrentState(t) + local state = self.readValue(t.ledBrightnessFile) + if state and tonumber(state) > 0 then + return tonumber(state) + end +end + +function Module:ledRunFunc(t, currentStatus) + if currentStatus == 0 then + if t.ledAction1 == 1 then + if self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:off(t) + end + elseif t.ledAction1 == 2 then + if not self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:on(t) + end + elseif t.ledAction1 == 3 then + local triggerValues = self:getTriggerValues(t, "timer") + if (not next(triggerValues)) or (triggerValues.delayOn ~= t.ledBlinkOnDelay1 or + triggerValues.delayOff ~= t.ledBlinkOffDelay1) then + self:setTriggerTimer(t, t.ledBlinkOnDelay1, t.ledBlinkOffDelay1) + end + elseif t.ledAction1 == 4 then + local triggerValues = self:getTriggerValues(t, "netdev") + if (not next(triggerValues)) or (triggerValues.device ~= t.ledNetlinkDevice1 or + triggerValues.link ~= t.ledNetdevModeLink1 or + triggerValues.tx ~= t.ledNetdevModeTx1 or + triggerValues.rx ~= t.ledNetdevModeRx1) then + self:setTriggerNetdev(t, + t.ledNetlinkDevice1, t.ledNetdevModeLink1, + t.ledNetdevModeTx1, t.ledNetdevModeRx1 + ) + end + end + elseif currentStatus == 1 then + if t.ledAction2 == 1 then + if self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:off(t) + end + elseif t.ledAction2 == 2 then + if not self:getCurrentState(t) or self:getCurrentTrigger(t) then + self:on(t) + end + elseif t.ledAction2 == 3 then + local triggerValues = self:getTriggerValues(t, "timer") + if (not next(triggerValues)) or (triggerValues.delayOn ~= t.ledBlinkOnDelay2 or + triggerValues.delayOff ~= t.ledBlinkOffDelay2) then + self:setTriggerTimer(t, t.ledBlinkOnDelay2, t.ledBlinkOffDelay2) + end + elseif t.ledAction2 == 4 then + local triggerValues = self:getTriggerValues(t, "netdev") + if (not next(triggerValues)) or (triggerValues.device ~= t.ledNetlinkDevice2 or + triggerValues.link ~= t.ledNetdevModeLink2 or + triggerValues.tx ~= t.ledNetdevModeTx2 or + triggerValues.rx ~= t.ledNetdevModeRx2) then + self:setTriggerNetdev(t, + t.ledNetlinkDevice2, t.ledNetdevModeLink2, + t.ledNetdevModeTx2, t.ledNetdevModeRx2 + ) + end + end + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if not self._enabled then + return + end + if self._counter == 0 or self._counter >= self.runInterval or currentStatus ~= lastStatus then + for _, t in ipairs(self._leds) do + if self._exit then + break + end + if t.enabled then + self:ledRunFunc(t, currentStatus) + end + end + self._counter = 0 + end + self._counter = self._counter + timeDiff +end + +function Module:onExit() + self._exit = true + for _, l in ipairs(self._leds) do + if l.ledPrevState then + if l.ledPrevState.brightness then + self.writeValue(l.ledBrightnessFile, l.ledPrevState.brightness) + end + if l.ledPrevState.trigger then + self.writeValue(l.ledTriggerFile, l.ledPrevState.trigger) + end + end + end +end + +return Module diff --git a/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_network_restart.lua b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_network_restart.lua new file mode 100644 index 00000000..0b136cba --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_network_restart.lua @@ -0,0 +1,160 @@ + +local unistd = require("posix.unistd") + +local Module = { + name = "mod_network_restart", + runPrio = 30, + config = {}, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + deadPeriod = 900, + attempts = 1, + attemptInterval = 15, + deviceTimeout = 0, + status = nil, + _attemptsCounter = 0, + _attemptIntervalCounter = 0, + _deadCounter = 0, + _firstAttempt = true, + _ifaceRestarting = false, + _ifaceRestartCounter = 0, + _netIfaces = {}, + _netDevices = {}, + _netItemsNum = 0, + _disconnectedAtStartup = false, +} + +function Module:toggleDevices(flag) + if #self._netDevices == 0 then + return + end + local ip = "/sbin/ip" + if unistd.access(ip, "x") then + for _, v in ipairs(self._netDevices) do + os.execute(string.format("%s link set dev %s %s", ip, v, (flag and "up" or "down"))) + end + end +end + +function Module:toggleIfaces(flag) + if #self._netIfaces == 0 then + return + end + for _, v in ipairs(self._netIfaces) do + os.execute(string.format("%s %s", (flag and "/sbin/ifup" or "/sbin/ifdown"), v)) + end +end + +function Module:netItemsUp() + self:toggleDevices(true) + self:toggleIfaces(true) +end + +function Module:netItemsDown() + self:toggleIfaces(false) + self:toggleDevices(false) +end + +function Module:restartNetworkService() + return os.execute("/etc/init.d/network restart") +end + +function Module:init(t) + if t.ifaces ~= nil and type(t.ifaces) == "table" then + self._netIfaces = {} + self._netDevices = {} + self._netItemsNum = 0 + for k, v in ipairs(t.ifaces) do + if v:match("^@") then + self._netIfaces[#self._netIfaces + 1] = v:gsub("^@", "") + else + self._netDevices[#self._netDevices + 1] = v + end + self._netItemsNum = self._netItemsNum + 1 + end + end + if t.dead_period ~= nil then + self.deadPeriod = tonumber(t.dead_period) + end + if t.attempts ~= nil then + self.attempts = tonumber(t.attempts) + end + if t.attempt_interval ~= nil then + self.attemptInterval = tonumber(t.attempt_interval) + end + if t.device_timeout ~= nil then + self.deviceTimeout = tonumber(t.device_timeout) + end + if tonumber(t.disconnected_at_startup) == 1 then + self._disconnectedAtStartup = true + end +end + +function Module:networkRestartFunc() + if self._netItemsNum > 0 then + if #self._netIfaces > 0 then + self.syslog("info", string.format("%s: restarting interfaces: %s", + self.name, table.concat(self._netIfaces, ", "))) + end + if #self._netDevices > 0 then + self.syslog("info", string.format("%s: restarting devices: %s", + self.name, table.concat(self._netDevices, ", "))) + end + self:netItemsDown() + if self.deviceTimeout < 1 then + self:netItemsUp() + else + self._ifaceRestarting = true + end + else + self.syslog("info", string.format( + "%s: restarting network", self.name)) + self:restartNetworkService() + end + if self.attempts > 0 then + self._attemptsCounter = self._attemptsCounter + 1 + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if self._ifaceRestarting then + if self._ifaceRestartCounter >= self.deviceTimeout then + self:netItemsUp() + self._ifaceRestarting = false + self._ifaceRestartCounter = 0 + else + self._ifaceRestartCounter = self._ifaceRestartCounter + timeDiff + end + else + if currentStatus == 1 then + if self._disconnectedAtStartup and self._deadCounter >= self.deadPeriod then + if self.attempts == 0 or self._attemptsCounter < self.attempts then + if self._firstAttempt or self._attemptIntervalCounter >= self.attemptInterval then + self:networkRestartFunc() + self._attemptIntervalCounter = 0 + self._firstAttempt = false + else + self._attemptIntervalCounter = self._attemptIntervalCounter + timeDiff + end + end + else + self._deadCounter = self._deadCounter + timeDiff + end + else + self._attemptsCounter = 0 + self._attemptIntervalCounter = 0 + self._deadCounter = 0 + self._disconnectedAtStartup = true + self._firstAttempt = true + end + self._ifaceRestartCounter = 0 + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_public_ip.lua b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_public_ip.lua new file mode 100644 index 00000000..1affda95 --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_public_ip.lua @@ -0,0 +1,533 @@ + +local socket = require("posix.sys.socket") +local stdlib = require("posix.stdlib") +local unistd = require("posix.unistd") + +local Module = { + name = "mod_public_ip", + runPrio = 50, + config = { + noModules = false, + debug = false, + serviceConfig = { + iface = nil, + proxy_type = nil, + proxy_host = nil, + proxy_port = nil, + }, + }, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + port = 53, + runInterval = 600, + runIntervalFailed = 60, + runIntervalIPFailed = 1, + requestAttempts = 2, + timeout = 3, + curlExec = "/usr/bin/curl", + curlParams = '-s -g --no-keepalive --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0"', + providers = { + opendns1 = { + name = "opendns1", type = "dns", host = "myip.opendns.com", + server = "208.67.222.222", server6 = "2620:119:35::35", + port = 53, queryType = "A", queryType6 = "AAAA", + }, + opendns2 = { + name = "opendns2", type = "dns", host = "myip.opendns.com", + server = "208.67.220.220", server6 = "2620:119:35::35", + port = 53, queryType = "A", queryType6 = "AAAA", + }, + opendns3 = { + name = "opendns3", type = "dns", host = "myip.opendns.com", + server = "208.67.222.220", server6 = "2620:119:35::35", + port = 53, queryType = "A", queryType6 = "AAAA", + }, + opendns4 = { + name = "opendns4", type = "dns", host = "myip.opendns.com", + server = "208.67.220.222", server6 = "2620:119:35::35", + port = 53, queryType = "A", queryType6 = "AAAA", + }, + google = { + name = "google", type = "dns", host = "o-o.myaddr.l.google.com", + server = "ns1.google.com", server6 = "ns1.google.com", + port = 53, queryType = "TXT", queryType6 = "TXT", + }, + akamai = { + name = "akamai", type = "dns", host = "whoami.akamai.net", + server = "ns1-1.akamaitech.net", server6 = "ns1-1.akamaitech.net", + port = 53, queryType = "A", queryType6 = "AAAA", + }, + akamai_http = { + name = "akamai_http", type = "http", url = "http://whatismyip.akamai.com/", + parseResponseFunc = nil, + }, + amazonaws= { + name = "amazonaws", type = "http", url = "http://checkip.amazonaws.com/", + parseResponseFunc = nil, + }, + wgetip= { + name = "wgetip", type = "http", url = "http://wgetip.com/", + parseResponseFunc = nil, + }, + ifconfig= { + name = "ifconfig", type = "http", url = "http://ifconfig.me/", + parseResponseFunc = nil, + }, + ipecho= { + name = "ipecho", type = "http", url = "http://ipecho.net/plain", + parseResponseFunc = nil, + }, + canhazip= { + name = "canhazip", type = "http", url = "http://canhazip.com/", + parseResponseFunc = nil, + }, + icanhazip = { + name = "icanhazip", type = "http", url = "http://icanhazip.com/", + parseResponseFunc = nil, + }, + }, + ipScript = "", + enableIpScript = false, + status = nil, + _proxyString = "", + _provider = nil, + _qtype = false, + _currentIp = nil, + _lastResolvedIp = nil, + _enabled = false, + _counter = 0, + _IPFalseCounter = 0, + _interval = 600, + _DNSPacket = nil, + _requestIP = nil, +} + +function Module:runIpScript() + if not self.config.noModules and self.enableIpScript and unistd.access(self.ipScript, "r") then + stdlib.setenv("PUBLIC_IP", self.status) + os.execute(string.format('/bin/sh "%s" &', self.ipScript)) + end +end + +function Module:getQueryType(type) + local types = { + A = 1, + NS = 2, + MD = 3, + MF = 4, + CNAME = 5, + SOA = 6, + MB = 7, + MG = 8, + MR = 9, + NULL = 10, + WKS = 11, + PTS = 12, + HINFO = 13, + MINFO = 14, + MX = 15, + TXT = 16, + AAAA = 28, + } + return types[type] +end + +function Module:buildMessage(address, queryType) + if not queryType then + queryType = "A" + end + queryType = self:getQueryType(queryType) + + local addressString = "" + for part in address:gmatch("[^.]+") do + local t = {} + for i in part:gmatch(".") do + t[#t + 1] = i + end + addrLen = #part + addrPart = table.concat(t) + addressString = addressString .. string.char(addrLen) .. addrPart + end + + local data = ( + string.char( + 0xaa, 0xaa, + 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ) .. + addressString .. + string.char( + 0x00, + 0x00, queryType, + 0x00, 0x01 + ) + ) + return data +end + +function Module:sendUDPMessage(message, server, port) + local success + local retCode = 1 + local data + + self.debugOutput(string.format("--- %s ---", self.name)) + + local saTable, errMsg, errNum = socket.getaddrinfo(server, port) + + if not saTable then + self.debugOutput(string.format( + "GETADDRINFO ERROR: %s, %s", errMsg, errNum)) + else + local family = saTable[1].family + + if family then + local sock, errMsg, errNum = socket.socket(family, socket.SOCK_DGRAM, 0) + + if not sock then + self.debugOutput(string.format( + "SOCKET ERROR: %s, %s", errMsg, errNum)) + return retCode + end + + socket.setsockopt(sock, socket.SOL_SOCKET, + socket.SO_SNDTIMEO, self.timeout, 0) + socket.setsockopt(sock, socket.SOL_SOCKET, + socket.SO_RCVTIMEO, self.timeout, 0) + + if self.config.serviceConfig.iface then + local ok, errMsg, errNum = socket.setsockopt(sock, socket.SOL_SOCKET, + socket.SO_BINDTODEVICE, self.config.serviceConfig.iface) + if not ok then + self.debugOutput(string.format( + "SOCKET ERROR: %s, %s", errMsg, errNum)) + unistd.close(sock) + return retCode + end + end + + local ok, errMsg, errNum = socket.sendto(sock, message, saTable[1]) + + local response = {} + if ok then + local ret, resp, errNum = socket.recvfrom(sock, 1024) + data = ret + if data then + success = true + response = resp + else + self.debugOutput(string.format( + "SOCKET RECV ERROR: %s, %s", tostring(resp), tostring(errNum))) + end + else + self.debugOutput(string.format( + "SOCKET SEND ERROR: %s, %s", tostring(errMsg), tostring(errNum))) + end + + self.debugOutput(string.format( + "--- UDP ---\ntime = %s\nconnection_timeout = %s\niface = %s\nserver = %s:%s\nsockname = %s:%s\nsuccess = %s", + os.time(), + self.timeout, + tostring(self.config.serviceConfig.iface), + server, + tostring(port), + tostring(response.addr), + tostring(response.port), + tostring(success)) + ) + + unistd.close(sock) + retCode = success and 0 or 1 + end + end + return retCode, tostring(data) +end + +function Module:parseParts(message, start, parts) + local partStart = start + 2 + local partLen = message:sub(start, start + 1) + if #partLen == 0 then + return parts + end + local partEnd = partStart + (tonumber(partLen, 16) * 2) + parts[#parts + 1] = message:sub(partStart, partEnd - 1) + if message:sub(partEnd, partEnd + 1) == "00" or partEnd > #message then + return parts + else + return self:parseParts(message, partEnd, parts) + end +end + +function Module:decodeMessage(message) + local retTable = {} + local t = {} + for i = 1, #message do + t[#t + 1] = string.format("%.2x", string.byte(message, i)) + end + message = table.concat(t) + + local ANCOUNT = message:sub(13, 16) + local NSCOUNT = message:sub(17, 20) + local ARCOUNT = message:sub(21, 24) + + -- Question section + local questionSectionStarts = 25 + local questionParts = self:parseParts(message, questionSectionStarts, {}) + local qtypeStarts = questionSectionStarts + (#table.concat(questionParts)) + (#questionParts * 2) + 1 + local qclassStarts = qtypeStarts + 4 + + -- Answer section + local answerSectionStarts = qclassStarts + 4 + local numAnswers = math.max( + tonumber(ANCOUNT, 16), tonumber(NSCOUNT, 16), tonumber(ARCOUNT, 16)) + + if numAnswers > 0 then + for answerCount = 1, numAnswers do + if answerSectionStarts < #message then + local ATYPE = tonumber( + message:sub(answerSectionStarts + 5, answerSectionStarts + 8), 16) + local RDLENGTH = tonumber( + message:sub(answerSectionStarts + 21, answerSectionStarts + 24), 16) + local RDDATA = message:sub( + answerSectionStarts + 25, answerSectionStarts + 24 + (RDLENGTH * 2)) + local RDDATA_decoded = "" + + if #RDDATA > 0 then + if ATYPE == self:getQueryType("A") or ATYPE == self:getQueryType("AAAA") then + local octets = {} + local sep = "." + if #RDDATA > 8 then + sep = ":" + for i = 1, #RDDATA, 4 do + local string = RDDATA:sub(i, i + 3) + string = string:gsub("^00?0?", "") + octets[#octets + 1] = string + end + else + for i = 1, #RDDATA, 2 do + octets[#octets + 1] = tonumber(RDDATA:sub(i, i + 1), 16) + end + end + RDDATA_decoded = table.concat(octets, sep):gsub("0:[0:]+", "::", 1):gsub("::+", "::") + else + local rdata_t = {} + for _, v in ipairs(self:parseParts(RDDATA, 1, {})) do + local t = {} + for i = 1, #v, 2 do + t[#t + 1] = string.char(tonumber(v:sub(i, i + 1), 16)) + end + rdata_t[#rdata_t + 1] = table.concat(t) + end + RDDATA_decoded = table.concat(rdata_t) + end + end + answerSectionStarts = answerSectionStarts + 24 + (RDLENGTH * 2) + + if RDDATA_decoded:match("^[a-fA-F0-9.:]+$") then + retTable[#retTable + 1] = RDDATA_decoded + end + end + end + end + return retTable +end + +function Module:requestIPDNS() + local res + local qtype = self._qtype and self._provider.queryType6 or self._provider.queryType + local server = self._qtype and self._provider.server6 or self._provider.server + local port = self._provider.port or self.port + if not self._DNSPacket then + self._DNSPacket = self:buildMessage(self._provider.host, qtype) + end + local retCode, response = self:sendUDPMessage(self._DNSPacket, server, port) + if retCode == 0 and response then + local retTable = self:decodeMessage(response) + if #retTable > 0 then + res = table.concat(retTable, ", ") + end + else + self.syslog("warning", string.format( + "%s: UDP error when requesting an IP address", self.name)) + end + return res +end + +function Module:httpRequest(url) + local retCode = 1, data + local curl = string.format( + '%s%s%s --connect-timeout %s %s "%s"; printf "\n$?";', + self.curlExec, + self.config.serviceConfig.iface and (" --interface " .. self.config.serviceConfig.iface) or "", + self._proxyString, + self.timeout, + self.curlParams, + url + ) + local fh = io.popen(curl, "r") + if fh then + data = fh:read("*a") + fh:close() + if data ~= nil then + local s, e = data:find("[0-9]+\n?$") + retCode = tonumber(data:sub(s)) + data = data:sub(0, s - 2) + if not data or data == "" then + data = nil + end + end + else + retCode = 1 + end + + self.debugOutput(string.format( + "--- Curl ---\ntime = %s\n%s\nretCode = %s\ndata = [\n%s]\n", + os.time(), + curl, + retCode, + tostring(data)) + ) + return retCode, data +end + +function Module:parseHTTPResponse(data) + data = data:gsub("^[%s%c]+", ""):gsub("[%s%c]+$", "") + if data:match("^[a-fA-F0-9.:]+$") then + return data + end + return +end + +function Module:requestIPHTTP() + local res + local url = self._provider.url + local parseResponseFunc = self._provider.parseResponseFunc + if url then + local retCode, data = self:httpRequest(url) + if retCode == 0 and data then + if type(parseResponseFunc) == "function" then + res = parseResponseFunc(data) + else + res = self:parseHTTPResponse(data) + end + else + self.syslog("warning", string.format( + "%s: HTTP error when requesting an IP address", self.name)) + end + end + return res +end + +function Module:init(t) + if t.interval ~= nil then + self.runInterval = tonumber(t.interval) + end + if t.interval_failed ~= nil then + self.runIntervalFailed = tonumber(t.interval_failed) + end + if t.request_attempts ~= nil then + self.requestAttempts = tonumber(t.request_attempts) + end + if t.timeout ~= nil then + self.timeout = tonumber(t.timeout) + end + if t.provider ~= nil then + self._provider = self.providers[t.provider] + else + self._provider = self.providers.opendns1 + end + if self.config.configDir then + self.ipScript = string.format( + "%s/public-ip-script.%s", self.config.configDir, self.config.serviceConfig.instance) + if t.enable_ip_script ~= nil then + self.enableIpScript = (tonumber(t.enable_ip_script) ~= 0) + end + end + if t.qtype ~= nil then + self._qtype = (tonumber(t.qtype) ~= 0) + end + self._currentIp = nil + self._lastResolvedIp = nil + self._DNSPacket = nil + self._interval = self.runInterval + self._IPFalseCounter = 0 + self._enabled = true + if not self._provider then + self._enabled = false + else + if self._provider.url and not unistd.access(self.curlExec, "x") then + self._enabled = false + self.syslog("err", string.format( + "%s: %s is not available. You need to install curl.", self.name, self.curlExec)) + end + if self._provider.type == "dns" then + self._requestIP = self.requestIPDNS + elseif self._provider.type == "http" then + self._requestIP = self.requestIPHTTP + else + self._enabled = false + end + end + if (self.config.serviceConfig.proxy_type and + self.config.serviceConfig.proxy_host and + self.config.serviceConfig.proxy_port) then + self._proxyString = string.format( + " --proxy %s://%s:%d", + self.config.serviceConfig.proxy_type, + self.config.serviceConfig.proxy_host, + self.config.serviceConfig.proxy_port) + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if not self._enabled then + return + end + if currentStatus == 0 then + if self._counter == 0 or self._counter >= self._interval or currentStatus ~= lastStatus then + local ip = self:_requestIP() + if not ip then + ip = "" + self._IPFalseCounter = self._IPFalseCounter + 1 + if self._IPFalseCounter >= self.requestAttempts then + self._interval = self.runIntervalFailed + self._IPFalseCounter = 0 + else + self._interval = self.runIntervalIPFailed + end + else + self._interval = self.runInterval + self._IPFalseCounter = 0 + end + if ip ~= self._currentIp then + self.status = ip + if ip ~= "" then + if self._counter > 0 and ip ~= self._lastResolvedIp then + self.syslog( + "notice", + string.format("%s: public IP address changed to %s", self.name, ip) + ) + self:runIpScript() + end + self._lastResolvedIp = ip + end + end + self._currentIp = ip + self._counter = 0 + end + else + self._currentIp = nil + self.status = self._currentIp + self._IPFalseCounter = 0 + self._counter = 0 + self._interval = self.runInterval + end + self._counter = self._counter + timeDiff +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_reboot.lua b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_reboot.lua new file mode 100644 index 00000000..f3c4f9c5 --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_reboot.lua @@ -0,0 +1,63 @@ + +local unistd = require("posix.unistd") + +local Module = { + name = "mod_reboot", + runPrio = 20, + config = {}, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + deadPeriod = 3600, + forceRebootDelay = 300, + antiBootloopDelay = 300, + status = nil, + _deadCounter = 0, + _rebooted = true, +} + +function Module:rebootDevice() + self.syslog("warning", string.format("%s: reboot", self.name)) + os.execute("/sbin/reboot &") + if self.forceRebootDelay > 0 then + unistd.sleep(self.forceRebootDelay) + self.syslog("warning", string.format("%s: force reboot", self.name)) + self.writeValue("/proc/sys/kernel/sysrq", "1") + self.writeValue("/proc/sysrq-trigger", "b") + end +end + +function Module:init(t) + if t.dead_period ~= nil then + self.deadPeriod = tonumber(t.dead_period) + end + if t.force_reboot_delay ~= nil then + self.forceRebootDelay = tonumber(t.force_reboot_delay) + end + if tonumber(t.disconnected_at_startup) == 1 then + self._rebooted = false + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if currentStatus == 1 then + if not self._rebooted then + if timeNow >= self.antiBootloopDelay and self._deadCounter >= self.deadPeriod then + self:rebootDevice() + self._rebooted = true + else + self._deadCounter = self._deadCounter + timeDiff + end + end + else + self._deadCounter = 0 + self._rebooted = false + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_regular_script.lua b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_regular_script.lua new file mode 100644 index 00000000..d0332d91 --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_regular_script.lua @@ -0,0 +1,67 @@ + +local stdlib = require("posix.stdlib") +local time = require("posix.time") +local unistd = require("posix.unistd") + +local Module = { + name = "mod_regular_script", + runPrio = 90, + config = {}, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + inetState = 2, -- 0: connected, 1: disconnected, 2: both + runInterval = 3600, + script = "", + status = nil, + _nextTime = nil, + _firstRun = true, +} + +function Module:runExternalScript(scriptPath, currentStatus) + if unistd.access(scriptPath, "r") then + stdlib.setenv("INET_STATE", currentStatus) + os.execute(string.format('/bin/sh "%s" &', scriptPath)) + end +end + +function Module:init(t) + if t.inet_state ~= nil then + self.inetState = tonumber(t.inet_state) + end + if t.interval ~= nil then + self.runInterval = tonumber(t.interval) + end + if self.config.configDir then + self.script = string.format( + "%s/regular-script.%s", self.config.configDir, self.config.serviceConfig.instance) + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if not self._nextTime then + if timeNow < self.runInterval then + self._nextTime = self.runInterval + else + self._nextTime = timeNow - (timeNow % self.runInterval) + self.runInterval + end + end + if self._firstRun then + self.status = time.strftime ("%Y-%m-%d %H:%M:%S %z", time.localtime(time.time() + self._nextTime - timeNow)) + self._firstRun = false + end + if timeNow >= self._nextTime then + self._nextTime = self._nextTime + self.runInterval + if self.inetState == 2 or (self.inetState == 0 and currentStatus == 0) or (self.inetState == 1 and currentStatus == 1) then + self.status = time.strftime ("%Y-%m-%d %H:%M:%S %z", time.localtime(time.time() + self._nextTime - timeNow)) + self:runExternalScript(self.script, currentStatus) + end + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_user_scripts.lua b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_user_scripts.lua new file mode 100644 index 00000000..04eee690 --- /dev/null +++ b/internet-detector/files/usr/lib/lua/internet-detector/modules/mod_user_scripts.lua @@ -0,0 +1,134 @@ + +local unistd = require("posix.unistd") + +local Module = { + name = "mod_user_scripts", + runPrio = 80, + config = {}, + syslog = function(level, msg) return true end, + debugOutput = function(msg) return true end, + writeValue = function(filePath, str) return false end, + readValue = function(filePath) return nil end, + deadPeriod = 0, + alivePeriod = 0, + upScript = "", + downScript = "", + upScriptAttempts = 1, + upScriptAttemptInterval = 15, + downScriptAttempts = 1, + downScriptAttemptInterval = 15, + status = nil, + _deadCounter = 0, + _aliveCounter = 0, + _upScriptAttemptsCounter = 0, + _upScriptAttemptIntervalCounter = 0, + _downScriptAttemptsCounter = 0, + _downScriptAttemptIntervalCounter = 0, + _upScriptFirstAttempt = true, + _downScriptFirstAttempt = true, + _disconnectedAtStartup = false, + _connectedAtStartup = false, +} + +function Module:runExternalScript(scriptPath) + if unistd.access(scriptPath, "r") then + os.execute(string.format('/bin/sh "%s" &', scriptPath)) + end +end + +function Module:init(t) + if t.dead_period ~= nil then + self.deadPeriod = tonumber(t.dead_period) + end + if t.alive_period ~= nil then + self.alivePeriod = tonumber(t.alive_period) + end + if t.up_script_attempts ~= nil then + self.upScriptAttempts = tonumber(t.up_script_attempts) + end + if t.up_script_attempt_interval ~= nil then + self.upScriptAttemptInterval = tonumber(t.up_script_attempt_interval) + end + if t.down_script_attempts ~= nil then + self.downScriptAttempts = tonumber(t.down_script_attempts) + end + if t.down_script_attempt_interval ~= nil then + self.downScriptAttemptInterval = tonumber(t.down_script_attempt_interval) + end + if self.config.configDir then + self.upScript = string.format( + "%s/up-script.%s", self.config.configDir, self.config.serviceConfig.instance) + self.downScript = string.format( + "%s/down-script.%s", self.config.configDir, self.config.serviceConfig.instance) + end + if tonumber(t.connected_at_startup) == 1 then + self._connectedAtStartup = true + end + if tonumber(t.disconnected_at_startup) == 1 then + self._disconnectedAtStartup = true + end +end + +function Module:runUpScriptFunc() + self:runExternalScript(self.upScript) + if self.upScriptAttempts > 0 then + self._upScriptAttemptsCounter = self._upScriptAttemptsCounter + 1 + end +end + +function Module:runDownScriptFunc() + self:runExternalScript(self.downScript) + if self.downScriptAttempts > 0 then + self._downScriptAttemptsCounter = self._downScriptAttemptsCounter + 1 + end +end + +function Module:run(currentStatus, lastStatus, timeDiff, timeNow, inetChecked) + if currentStatus == 1 then + self._upScriptAttemptsCounter = 0 + self._upScriptAttemptIntervalCounter = 0 + self._aliveCounter = 0 + self._connectedAtStartup = true + self._upScriptFirstAttempt = true + + if self._disconnectedAtStartup and self._deadCounter >= self.deadPeriod then + if self.downScriptAttempts == 0 or self._downScriptAttemptsCounter < self.downScriptAttempts then + if self._downScriptFirstAttempt or self._downScriptAttemptIntervalCounter >= self.downScriptAttemptInterval then + self:runDownScriptFunc() + self._downScriptAttemptIntervalCounter = 0 + self._downScriptFirstAttempt = false + else + self._downScriptAttemptIntervalCounter = self._downScriptAttemptIntervalCounter + timeDiff + end + end + else + self._deadCounter = self._deadCounter + timeDiff + end + elseif currentStatus == 0 then + self._downScriptAttemptsCounter = 0 + self._downScriptAttemptIntervalCounter = 0 + self._deadCounter = 0 + self._disconnectedAtStartup = true + self._downScriptFirstAttempt = true + + if self._connectedAtStartup and self._aliveCounter >= self.alivePeriod then + if self.upScriptAttempts == 0 or self._upScriptAttemptsCounter < self.upScriptAttempts then + if self._upScriptFirstAttempt or self._upScriptAttemptIntervalCounter >= self.upScriptAttemptInterval then + self:runUpScriptFunc() + self._upScriptAttemptIntervalCounter = 0 + self._upScriptFirstAttempt = false + else + self._upScriptAttemptIntervalCounter = self._upScriptAttemptIntervalCounter + timeDiff + end + end + else + self._aliveCounter = self._aliveCounter + timeDiff + end + end +end + +function Module:onExit() + return true +end + +return Module diff --git a/ipt2socks/Makefile b/ipt2socks/Makefile new file mode 100644 index 00000000..80676677 --- /dev/null +++ b/ipt2socks/Makefile @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ipt2socks +PKG_VERSION:=1.1.4 +PKG_RELEASE:=3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/zfl9/ipt2socks/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=68dc76e63951d655c2fd9b420e175b5a75a50014d6db6e729398b41f2c988356 + +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +PKG_LICENSE:=AGPL-3.0 +PKG_LICENSE_FILE:=LICENSE + +include $(INCLUDE_DIR)/package.mk + +define Package/ipt2socks + SECTION:=net + CATEGORY:=Network + TITLE:=Convert iptables to socks5 + URL:=https://github.com/zfl9/ipt2socks + DEPENDS:=+libpthread +endef + +define Package/ipt2socks/description + Utility for converting iptables (redirect/tproxy) to socks5. +endef + +TARGET_CFLAGS+= $(FPIC) -flto +MAKE_FLAGS+= \ + CFLAGS="-std=c99 -pthread $(TARGET_CFLAGS)" \ + EVCFLAGS="$(TARGET_CFLAGS)" + +define Package/ipt2socks/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ipt2socks $(1)/usr/bin +endef + +$(eval $(call BuildPackage,ipt2socks)) diff --git a/kismet/Makefile b/kismet/Makefile new file mode 100644 index 00000000..c42838a7 --- /dev/null +++ b/kismet/Makefile @@ -0,0 +1,142 @@ +# +# Copyright (C) 2006-2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=kismet +PKG_VERSION:=2016-07-R1 +PKG_RELEASE:=6 + +PKG_LICENSE:=LGPLv2.1 +PKG_CPE_ID:=cpe:/a:kismet:kismet + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=http://www.kismetwireless.net/code +PKG_HASH:=bdb21f153311f1ff3b16621bf0d6740f66369bf0982b0a289c9a12af8847e237 + +include $(INCLUDE_DIR)/package.mk + +define Package/kismet/Default + SECTION:=net + CATEGORY:=Network + TITLE:=Kismet + MAINTAINER:=Jean-Michel lacroix + DEPENDS:= +libstdcpp +libnl @BROKEN + URL:=http://www.kismetwireless.net/ + SUBMENU:=Wireless +endef + +define Package/kismet/Default/description + An 802.11 layer2 wireless network detector, sniffer, and intrusion + detection system. +endef + +define Package/kismet-client/conffiles +/etc/kismet/kismet.conf +endef + +define Package/kismet-drone/conffiles +/etc/config/kismet_drone +/etc/kismet/kismet_drone.conf +endef + +define Package/kismet-server/conffiles +/etc/config/kismet_server +/etc/kismet/kismet.conf +endef + +define Package/kismet-client +$(call Package/kismet/Default) + TITLE+= client + DEPENDS+= +libncurses +endef + +define Package/kismet-client/description +$(call Package/kismet/Default/description) + This package contains the kismet text interface client. +endef + +define Package/kismet-drone +$(call Package/kismet/Default) + DEPENDS+= +libpcap +libpcre +libcap +wireless-tools + TITLE+= drone +endef + +define Package/kismet-drone/description +$(call Package/kismet/Default/description) + This package contains the kismet remote sniffing.and monitoring drone. +endef + +define Package/kismet-server +$(call Package/kismet/Default) + DEPENDS+= +libpcap +libpcre +libcap +wireless-tools + TITLE+= server +endef + +define Package/kismet-server/description +$(call Package/kismet/Default/description) + This package contains the kismet server. +endef + +CONFIGURE_ARGS += \ + --sysconfdir=/etc/kismet \ + +CONFIGURE_VARS += \ + CXXFLAGS="$$$$CXXFLAGS -fno-rtti" \ + LIBS="-lm" \ + CLIENTCLIBS="-lm" + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + LD="$(TARGET_CXX)" \ + all +endef + +define Package/kismet/install + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/kismet $(1)/usr/bin/kismet +endef + +define Package/kismet-client/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/kismet_client $(1)/usr/bin/ + + $(INSTALL_DIR) $(1)/etc/kismet/ + $(INSTALL_CONF) ./files/kismet.conf $(1)/etc/kismet/ +endef + +define Package/kismet-drone/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/kismet_drone $(1)/usr/bin/ + + $(INSTALL_DIR) $(1)/etc/kismet/ + $(INSTALL_CONF) ./files/kismet_drone.conf $(1)/etc/kismet/ + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/kismet_drone.config $(1)/etc/config/kismet_drone + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/kismet_drone.init $(1)/etc/init.d/kismet_drone +endef + +define Package/kismet-server/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/kismet_server $(1)/usr/bin/ + + $(INSTALL_DIR) $(1)/etc/kismet/ + $(INSTALL_CONF) ./files/kismet.conf $(1)/etc/kismet/ + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/kismet_server.config $(1)/etc/config/kismet_server + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/kismet_server.init $(1)/etc/init.d/kismet_server +endef + +$(eval $(call BuildPackage,kismet-client)) +$(eval $(call BuildPackage,kismet-drone)) +$(eval $(call BuildPackage,kismet-server)) diff --git a/kismet/files/kismet.conf b/kismet/files/kismet.conf new file mode 100644 index 00000000..1528a156 --- /dev/null +++ b/kismet/files/kismet.conf @@ -0,0 +1,304 @@ +# Kismet config file +# Most of the "static" configs have been moved to here -- the command line +# config was getting way too crowded and cryptic. We want functionality, +# not continually reading --help! + +# Version of Kismet config +version=2009-newcore + +# Name of server (Purely for organizational purposes) +# If commented out, defaults to host name of system +# servername=Kismet Server + +# Prefix of where we log (as used in the logtemplate later) +logprefix=/tmp + +# Do we process the contents of data frames? If this is enabled, data +# frames will be truncated to the headers only immediately after frame type +# detection. This will disable IP detection, etc, however it is likely +# safer (and definitely more polite) if monitoring networks you do not own. +# hidedata=true + +# Do we allow plugins to be used? This will load plugins from the system +# and user plugin directiories when set to true (See the README for the default +# plugin locations). +allowplugins=false + +# See the README for full information on the new source format +# ncsource=interface:options +# for example: +# ncsource=wifi0:type=madwifi +# ncsource=wlan0:name=intel,hop=false,channel=11 +ncsource=wlan0 + +# Comma-separated list of sources to enable. This is only needed if you defined +# multiple sources and only want to enable some of them. By default, all defined +# sources are enabled. +# For example, if sources with name=prismsource and name=ciscosource are defined, +# and you only want to enable those two: +# enablesources=prismsource,ciscosource + +# Control which channels we like to spend more time on. By default, the list +# of channels is pulled from the driver automatically. By setting preferred channels, +# if they are present in the channel list, they'll be set with a timing delay so that +# more time is spent on them. Since 1, 6, 11 are the common default channels, it makes +# sense to spend more time monitoring them. +# For finer control, see further down in the config for the channellist= directives. +preferredchannels=1,6,11 + +# How many channels per second do we hop? (1-10) +channelvelocity=3 + +# By setting the dwell time for channel hopping we override the channelvelocity +# setting above and dwell on each channel for the given number of seconds. +#channeldwell=10 + +# Channels are defined as: +# channellist=name:ch1,ch2,ch3 +# or +# channellist=name:range-start-end-width-offset,ch,range,ch,... +# +# Channels may be a numeric channel or a frequency +# +# Channels may specify an additional wait period. For common default channels, +# an additional wait period can be useful. Wait periods delay for that number +# of times per second - so a configuration hopping 10 times per second with a +# channel of 6:3 would delay 3/10ths of a second on channel 6. +# +# Channel lists may have up to 256 channels and ranges (combined). For power +# users scanning more than 256 channels with a single card, ranges must be used. +# +# Ranges are meant for "power users" who wish to define a very large number of +# channels. A range may specify channels or frequencies, and will automatically +# sort themselves to cover channels in a non-overlapping fashion. An example +# range for the normal 802.11b/g spectrum would be: +# +# range-1-11-3-1 +# +# which indicates starting at 1, ending at 11, a channel width of 3 channels, +# incrementing by one. A frequency based definition would be: +# +# range-2412-2462-22-5 +# +# since 11g channels are 22 mhz wide and 5 mhz apart. +# +# Ranges have the flaw that they cannot be shared between sources in a non-overlapping +# way, so multiple sources using the same range may hop in lockstep with each other +# and duplicate the coverage. +# +# channellist=demo:1:3,6:3,11:3,range-5000-6000-20-10 + +# Default channel lists +# These channel lists MUST BE PRESENT for Kismet to work properly. While it is +# possible to change these, it is not recommended. These are used when the supported +# channel list can not be found for the source; to force using these instead of +# the detected supported channels, override with channellist= in the source definition +# +# IN GENERAL, if you think you want to modify these, what you REALLY want to do is +# copy them and use channellist= in the packet source. +channellist=IEEE80211b:1:3,6:3,11:3,2,7,3,8,4,9,5,10 +channellist=IEEE80211a:36,40,44,48,52,56,60,64,149,153,157,161,165 +channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64,149,153,157,161,165 + +# Client/server listen config +listen=tcp://127.0.0.1:2501 +#listen=tcp://0.0.0.0:2501 + +# People allowed to connect, comma separated IP addresses or network/mask +# blocks. Netmasks can be expressed as dotted quad (/255.255.255.0) or as +# numbers (/24) +allowedhosts=127.0.0.1 +# Maximum number of concurrent GUI's +maxclients=5 +# Maximum backlog before we start throwing out or killing clients. The +# bigger this number, the more memory and the more power it will use. +maxbacklog=5000 + +# Server + Drone config options. To have a Kismet server export live packets +# as if it were a drone, uncomment these. +# dronelisten=tcp://127.0.0.1:3501 +# droneallowedhosts=127.0.0.1 +# dronemaxclients=5 +# droneringlen=65535 + +# OUI file, expected format 00:11:22manufname +# IEEE OUI file used to look up manufacturer info. We default to the +# wireshark one since most people have that. +#ouifile=/usr/share/manuf + +# Do we have a GPS? +gps=false +# Do we use a locally serial attached GPS, or use a gpsd server, or +# use a fixed virtual gps? +# (Pick only one) +gpstype=gpsd +# Host:port that GPSD is running on. This can be localhost OR remote! +gpshost=localhost:2947 + + +# gpstype=serial +# What serial device do we look for the GPS on? +# gpsdevice=/dev/rfcomm0 + +# gpstype=virtual +# gpsposition=100,-50 +# gpsaltitude=1234 + +# Do we lock the mode? This overrides coordinates of lock "0", which will +# generate some bad information until you get a GPS lock, but it will +# fix problems with GPS units with broken NMEA that report lock 0 +gpsmodelock=false +# Do we try to reconnect if we lose our link to the GPS, or do we just +# let it die and be disabled? +gpsreconnect=true + +# Do we export packets over tun/tap virtual interfaces? +tuntap_export=false +# What virtual interface do we use +tuntap_device=kistap0 + +# Packet filtering options: +# filter_tracker - Packets filtered from the tracker are not processed or +# recorded in any way. +# filter_export - Controls what packets influence the exported CSV, network, +# xml, gps, etc files. +# All filtering options take arguments containing the type of address and +# addresses to be filtered. Valid address types are 'ANY', 'BSSID', +# 'SOURCE', and 'DEST'. Filtering can be inverted by the use of '!' before +# the address. For example, +# filter_tracker=ANY(!"00:00:DE:AD:BE:EF") +# has the same effect as the previous mac_filter config file option. +# filter_tracker=... +# filter_dump=... +# filter_export=... +# filter_netclient=... + +# Alerts to be reported and the throttling rates. +# alert=name,throttle/unit,burst +# The throttle/unit describes the number of alerts of this type that are +# sent per time unit. Valid time units are second, minute, hour, and day. +# Burst describes the number of alerts sent before throttling takes place. +# For example: +# alert=FOO,10/min,5 +# Would allow 5 alerts through before throttling is enabled, and will then +# limit the number of alerts to 10 per minute. +# A throttle rate of 0 disables throttling of the alert. +# See the README for a list of alert types. +alert=ADHOCCONFLICT,5/min,1/sec +alert=AIRJACKSSID,5/min,1/sec +alert=APSPOOF,10/min,1/sec +alert=BCASTDISCON,5/min,2/sec +alert=BSSTIMESTAMP,5/min,1/sec +alert=CHANCHANGE,5/min,1/sec +alert=CRYPTODROP,5/min,1/sec +alert=DISASSOCTRAFFIC,10/min,1/sec +alert=DEAUTHFLOOD,5/min,2/sec +alert=DEAUTHCODEINVALID,5/min,1/sec +alert=DISCONCODEINVALID,5/min,1/sec +alert=DHCPNAMECHANGE,5/min,1/sec +alert=DHCPOSCHANGE,5/min,1/sec +alert=DHCPCLIENTID,5/min,1/sec +alert=DHCPCONFLICT,10/min,1/sec +alert=NETSTUMBLER,5/min,1/sec +alert=LUCENTTEST,5/min,1/sec +alert=LONGSSID,5/min,1/sec +alert=MSFBCOMSSID,5/min,1/sec +alert=MSFDLINKRATE,5/min,1/sec +alert=MSFNETGEARBEACON,5/min,1/sec +alert=NULLPROBERESP,5/min,1/sec +alert=PROBENOJOIN,5/min,1/sec + +# Controls behavior of the APSPOOF alert. SSID may be a literal match (ssid=) or +# a regex (ssidregex=) if PCRE was available when kismet was built. The allowed +# MAC list must be comma-separated and enclosed in quotes if there are multiple +# MAC addresses allowed. MAC address masks are allowed. +#apspoof=Foo1:ssidregex="(?i:foobar)",validmacs=00:11:22:33:44:55 +#apspoof=Foo2:ssid="Foobar",validmacs="00:11:22:33:44:55,aa:bb:cc:dd:ee:ff" + +# Known WEP keys to decrypt, bssid,hexkey. This is only for networks where +# the keys are already known, and it may impact throughput on slower hardware. +# Multiple wepkey lines may be used for multiple BSSIDs. +# wepkey=00:DE:AD:C0:DE:00,FEEDFACEDEADBEEF01020304050607080900 + +# Is transmission of the keys to the client allowed? This may be a security +# risk for some. If you disable this, you will not be able to query keys from +# a client. +allowkeytransmit=true + +# How often (in seconds) do we write all our data files (0 to disable) +writeinterval=10 + +# Do we use sound? +# Not to be confused with GUI sound parameter, this controls wether or not the +# server itself will play sound. Primarily for headless or automated systems. +enablesound=false +# Path to sound player +soundbin=play + +sound=newnet,true +sound=newcryptnet,true +sound=packet,true +sound=gpslock,true +sound=gpslost,true +sound=alert,true + +# Does the server have speech? (Again, not to be confused with the GUI's speech) +enablespeech=false +# Binary used for speech (if not in path, full path must be specified) +speechbin=flite +# Specify raw or festival; Flite (and anything else that doesn't need formatting +# around the string to speak) is 'raw', festival requires the string be wrapped in +# SayText("...") +speechtype=raw + +# How do we speak? Valid options: +# speech Normal speech +# nato NATO spellings (alpha, bravo, charlie) +# spell Spell the letters out (aye, bee, sea) +speechencoding=nato + +speech=new,"New network detected s.s.i.d. %1 channel %2" +speech=alert,"Alert %1" +speech=gpslost,"G.P.S. signal lost" +speech=gpslock,"G.P.S. signal O.K." + +# How many alerts do we backlog for new clients? Only change this if you have +# a -very- low memory system and need those extra bytes, or if you have a high +# memory system and a huge number of alert conditions. +alertbacklog=50 + +# File types to log, comma separated. Built-in log file types: +# alert Text file of alerts +# gpsxml XML per-packet GPS log +# nettxt Networks in text format +# netxml Networks in XML format +# pcapdump tcpdump/wireshark compatible pcap log file +# string All strings seen (increases CPU load) +logtypes=pcapdump,gpsxml,netxml,alert + +# Format of the pcap dump (PPI or 80211) +pcapdumpformat=ppi +# pcapdumpformat=80211 + +# Default log title +logdefault=Kismet + +# logtemplate - Filename logging template. +# This is, at first glance, really nasty and ugly, but you'll hardly ever +# have to touch it so don't complain too much. +# +# %p is replaced by the logging prefix + '/' +# %n is replaced by the logging instance name +# %d is replaced by the starting date as Mon-DD-YYYY +# %D is replaced by the current date as YYYYMMDD +# %t is replaced by the starting time as HH-MM-SS +# %i is replaced by the increment log in the case of multiple logs +# %l is replaced by the log type (pcapdump, strings, etc) +# %h is replaced by the home directory + +logtemplate=%p%n-%D-%t-%i.%l + +# Where state info, etc, is stored. You shouldn't ever need to change this. +# This is a directory. +configdir=%h/.kismet/ + diff --git a/kismet/files/kismet_drone.conf b/kismet/files/kismet_drone.conf new file mode 100644 index 00000000..bd165403 --- /dev/null +++ b/kismet/files/kismet_drone.conf @@ -0,0 +1,69 @@ +# Kismet drone config file + +version=newcore.1 + +# Name of drone server (informational) +servername=Kismet-Drone + +# Drone configuration +# Protocol, interface, and port to listen on +dronelisten=tcp://127.0.0.1:2502 +# Hosts allowed to connect, comma separated. May include netmasks. +# allowedhosts=127.0.0.1,10.10.10.0/255.255.255.0 +droneallowedhosts=127.0.0.1 +# Maximum number of drone clients +dronemaxclients=10 +droneringlen=65535 + +# Do we have a GPS? +gps=true +# Do we use a locally serial attached GPS, or use a gpsd server? +# (Pick only one) +gpstype=gpsd +# gpstype=serial +# What serial device do we look for the GPS on? +gpsdevice=/dev/rfcomm0 +# Host:port that GPSD is running on. This can be localhost OR remote! +gpshost=localhost:2947 +# Do we lock the mode? This overrides coordinates of lock "0", which will +# generate some bad information until you get a GPS lock, but it will +# fix problems with GPS units with broken NMEA that report lock 0 +gpsmodelock=false +# Do we try to reconnect if we lose our link to the GPS, or do we just +# let it die and be disabled? +gpsreconnect=true + +# See the README for full information on the new source format +# ncsource=interface:options +ncsource=null +# for example: +# ncsource=wlan0 +# ncsource=wifi0:type=madwifi +# ncsource=wlan0:name=intel,hop=false,channel=11 + +# Special per-source options +# sourceopts=[sourcename|*]:opt1,opt2 +# sourceopts=*:fuzzycrypt,weakvalidate + +# Comma-separated list of sources to enable, if you don't want to enable all +# the sources you defined. +# enablesource=source1,source2 + +# How many channels per second do we hop? (1-10) +channelvelocity=5 + +# By setting the dwell time for channel hopping we override the channelvelocity +# setting above and dwell on each channel for the given number of seconds. +#channeldwell=10 + +# Users outside the US might want to use this list: +# channellist=IEEE80211b:1,7,13,2,8,3,14,9,4,10,5,11,6,12 +channellist=IEEE80211b:1:3,6:3,11:3,2,7,3,8,4,9,5,10 + +# US IEEE 80211a +channellist=IEEE80211a:36,40,44,48,52,56,60,64,149,153,157,161,165 + +# Combo +channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64,149,153,157,161,165 + + diff --git a/kismet/files/kismet_drone.config b/kismet/files/kismet_drone.config new file mode 100644 index 00000000..749505d1 --- /dev/null +++ b/kismet/files/kismet_drone.config @@ -0,0 +1,2 @@ +config kismet_drone + option enabled 0 diff --git a/kismet/files/kismet_drone.init b/kismet/files/kismet_drone.init new file mode 100755 index 00000000..2cbbe7ed --- /dev/null +++ b/kismet/files/kismet_drone.init @@ -0,0 +1,26 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013-2014 OpenWrt.org + +START=99 +STOP=99 + +USE_PROCD=1 +PROG=/usr/bin/kismet_drone +NAME=kismet_drone + +kismet_drone_instance() { + procd_open_instance + procd_set_param command "${PROG}" + procd_append_param command -f /etc/kismet/kismet_drone.conf -s + procd_set_param respawn + procd_close_instance +} + +start_service() { + config_load "${NAME}" + config_foreach kismet_drone_instance +} + +stop_service() { + service_stop "${PROG}" +} diff --git a/kismet/files/kismet_server.config b/kismet/files/kismet_server.config new file mode 100644 index 00000000..ad39f3e1 --- /dev/null +++ b/kismet/files/kismet_server.config @@ -0,0 +1,2 @@ +config kismet_server + option enabled 0 diff --git a/kismet/files/kismet_server.init b/kismet/files/kismet_server.init new file mode 100755 index 00000000..7d731e77 --- /dev/null +++ b/kismet/files/kismet_server.init @@ -0,0 +1,26 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013-2014 OpenWrt.org + +START=99 +STOP=99 + +USE_PROCD=1 +PROG=/usr/bin/kismet_server +NAME=kismet_server + +kismet_server_instance() { + procd_open_instance + procd_set_param command "${PROG}" + procd_append_param command -f /etc/kismet/kismet.conf -s + procd_set_param respawn + procd_close_instance +} + +start_service() { + config_load "${NAME}" + config_foreach kismet_server_instance +} + +stop_service() { + service_stop "${PROG}" +} diff --git a/kismet/patches/010-dont-add-host-include-paths.patch b/kismet/patches/010-dont-add-host-include-paths.patch new file mode 100644 index 00000000..62acd02b --- /dev/null +++ b/kismet/patches/010-dont-add-host-include-paths.patch @@ -0,0 +1,12 @@ +--- a/configure ++++ b/configure +@@ -5981,9 +5981,6 @@ fi + + + +-# Add additional cflags since some distros bury panel.h +-CPPFLAGS="$CPPFLAGS -I/usr/include/ncurses" +- + termcontrol="none"; + + if test "$wantclient" = "yes"; then diff --git a/kismet/patches/020-musl-include-fixes.patch b/kismet/patches/020-musl-include-fixes.patch new file mode 100644 index 00000000..d3346fd7 --- /dev/null +++ b/kismet/patches/020-musl-include-fixes.patch @@ -0,0 +1,32 @@ +--- a/configfile.cc ++++ b/configfile.cc +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include "configfile.h" + #include "util.h" + +--- a/dumpfile_tuntap.cc ++++ b/dumpfile_tuntap.cc +@@ -20,8 +20,8 @@ + + #include + +-#include "dumpfile_tuntap.h" + #include "ifcontrol.h" ++#include "dumpfile_tuntap.h" + #include "ipc_remote.h" + + #ifndef SYS_CYGWIN +--- a/ifcontrol.h ++++ b/ifcontrol.h +@@ -39,7 +39,6 @@ + #include + #include + #include +-#include + #include + #endif + diff --git a/kismet/patches/030-libcxx.patch b/kismet/patches/030-libcxx.patch new file mode 100644 index 00000000..5c1f63e0 --- /dev/null +++ b/kismet/patches/030-libcxx.patch @@ -0,0 +1,64 @@ +--- a/ipc_remote.cc ++++ b/ipc_remote.cc +@@ -914,7 +914,7 @@ int RootIPCRemote::OpenFDPassSock() { + return -1; + } + +- if (bind(ipc_fd_fd, (const struct sockaddr *) &unixsock, sizeof(unixsock))) { ++ if (::bind(ipc_fd_fd, (const struct sockaddr *) &unixsock, sizeof(unixsock))) { + close(ipc_fd_fd); + _MSG("Failed to bind socket to pass file descriptors: " + + string(strerror(errno)), MSGFLAG_ERROR); +--- a/packetsource_wext.cc ++++ b/packetsource_wext.cc +@@ -405,7 +405,7 @@ void PacketSource_Wext::OpenWpaSupplican + wpa_local.sun_family = AF_UNIX; + snprintf(wpa_local.sun_path, sizeof(wpa_local.sun_path), + "%s", wpa_local_path.c_str()); +- if (bind(wpa_sock, (struct sockaddr *) &wpa_local, sizeof(wpa_local)) < 0) { ++ if (::bind(wpa_sock, (struct sockaddr *) &wpa_local, sizeof(wpa_local)) < 0) { + _MSG("Source '" + parent + "' failed to bind local socket for " + "wpa_supplicant, disabling scan_wpa: " + string(strerror(errno)), + MSGFLAG_PRINTERROR); +--- a/tcpclient.cc ++++ b/tcpclient.cc +@@ -75,7 +75,7 @@ int TcpClient::Connect(const char *in_re + local_sock.sin_addr.s_addr = htonl(INADDR_ANY); + local_sock.sin_port = htons(0); + +- if (bind(cli_fd, (struct sockaddr *) &local_sock, sizeof(local_sock)) < 0) { ++ if (::bind(cli_fd, (struct sockaddr *) &local_sock, sizeof(local_sock)) < 0) { + snprintf(errstr, 1024, "TCP client bind() failed: %s", strerror(errno)); + globalreg->messagebus->InjectMessage(errstr, MSGFLAG_ERROR); + close(cli_fd); +@@ -170,7 +170,7 @@ int TcpClient::ConnectSync(const char *i + local_sock.sin_addr.s_addr = htonl(INADDR_ANY); + local_sock.sin_port = htons(0); + +- if (bind(cli_fd, (struct sockaddr *) &local_sock, sizeof(local_sock)) < 0) { ++ if (::bind(cli_fd, (struct sockaddr *) &local_sock, sizeof(local_sock)) < 0) { + snprintf(errstr, 1024, "TCP client bind() failed: %s", strerror(errno)); + globalreg->messagebus->InjectMessage(errstr, MSGFLAG_ERROR); + close(cli_fd); +--- a/tcpserver.cc ++++ b/tcpserver.cc +@@ -84,7 +84,7 @@ int TcpServer::EnableServer() { + } + + // Bind the socket +- if (bind(serv_fd, (struct sockaddr *) &serv_sock, sizeof(serv_sock)) < 0) { ++ if (::bind(serv_fd, (struct sockaddr *) &serv_sock, sizeof(serv_sock)) < 0) { + snprintf(errstr, STATUS_MAX, "TCP server bind() failed: %s", + strerror(errno)); + globalreg->messagebus->InjectMessage(errstr, MSGFLAG_ERROR); +--- a/unixdomainserver.cc ++++ b/unixdomainserver.cc +@@ -64,7 +64,7 @@ int UnixDomainServer::EnableServer() { + } + + // Bind the socket +- if (bind(serv_fd, (struct sockaddr *) &serv_sock, sizeof(serv_sock)) < 0) { ++ if (::bind(serv_fd, (struct sockaddr *) &serv_sock, sizeof(serv_sock)) < 0) { + _MSG("Unix domain server bind() failed: " + string(strerror(errno)), + MSGFLAG_ERROR); + return -1; diff --git a/kismet/patches/040-uclibc.patch b/kismet/patches/040-uclibc.patch new file mode 100644 index 00000000..f63a5da5 --- /dev/null +++ b/kismet/patches/040-uclibc.patch @@ -0,0 +1,12 @@ +--- a/ipc_remote.cc ++++ b/ipc_remote.cc +@@ -941,8 +941,8 @@ int RootIPCRemote::OpenFDPassSock() { + } + + typedef struct { +- struct cmsghdr header; + int fd; ++ struct cmsghdr header; + } __attribute__((packed)) cmsg_fd; + + int RootIPCRemote::SendDescriptor(int in_fd) { diff --git a/lua-neturl/Makefile b/lua-neturl/Makefile new file mode 100644 index 00000000..246dcf71 --- /dev/null +++ b/lua-neturl/Makefile @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022-2023 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=neturl +PKG_VERSION:=1.2-1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/golgote/neturl/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=fc4ea1b114125ae821bef385936cd12429485204576e77b6283692bd0cc9b1ab + +PKG_MAINTAINER:=Tianling Shen +PKG_LICENSE:=MIT +PKG_LICNESE_FILES:=LICENSE.txt + +include $(INCLUDE_DIR)/package.mk + +define Package/lua-neturl + SUBMENU:=Lua + SECTION:=lang + CATEGORY:=Languages + TITLE:=URL and Query string parser, builder, normalizer for Lua + URL:=https://github.com/golgote/neturl + DEPENDS:=+lua + PKGARCH:=all +endef + +define Package/lua-neturl/description + This small Lua library provides a few functions to parse URL with + querystring and build new URL easily. +endef + +define Build/Compile +endef + +define Package/lua-neturl/install + $(INSTALL_DIR) $(1)/usr/lib/lua + $(CP) $(PKG_BUILD_DIR)/lib/net/url.lua $(1)/usr/lib/lua/ +endef + +$(eval $(call BuildPackage,lua-neturl)) diff --git a/lua-neturl/patches/010-userinfo-regex.patch b/lua-neturl/patches/010-userinfo-regex.patch new file mode 100644 index 00000000..9dbd91cc --- /dev/null +++ b/lua-neturl/patches/010-userinfo-regex.patch @@ -0,0 +1,20 @@ +--- a/lib/net/url.lua ++++ b/lib/net/url.lua +@@ -340,7 +340,7 @@ function M:setAuthority(authority) + self.password = v + return '' + end) +- if string.find(userinfo, "^[%w%+%.]+$") then ++ if string.find(userinfo, "^[%p%w%+%.]+$") then + self.user = userinfo + else + -- incorrect userinfo +@@ -369,7 +369,7 @@ function M.parse(url) + comp.fragment = v + return '' + end) +- url =url:gsub('^([%w][%w%+%-%.]*)%:', function(v) ++ url =url:gsub('^([%w][%w%+%-%_%.]*)%:', function(v) + comp.scheme = v:lower() + return '' + end) diff --git a/luci-app-bandix/Makefile b/luci-app-bandix/Makefile new file mode 100644 index 00000000..d5384fed --- /dev/null +++ b/luci-app-bandix/Makefile @@ -0,0 +1,18 @@ +# See /LICENSE for more information. +# This is free software, licensed under the GNU General Public License v2. + +include $(TOPDIR)/rules.mk + +PKG_LICENSE:=Apache-2.0 + +LUCI_TITLE:=LuCI Bandix app for network traffic monitoring +LUCI_DEPENDS:=+luci-base +luci-lib-jsonc +curl +bandix + +PKG_MAINTAINER:=timsaya + +PKG_VERSION:=0.12.8 +PKG_RELEASE:=1 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature \ No newline at end of file diff --git a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js new file mode 100644 index 00000000..8aa3df5c --- /dev/null +++ b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/connection.js @@ -0,0 +1,1364 @@ +'use strict'; +'require view'; +'require ui'; +'require uci'; +'require rpc'; +'require poll'; + +var BANDIX_MODAL_BG_OPENWRT2020_LIGHT = '#ffffff'; +var BANDIX_MODAL_BG_OPENWRT2020_DARK = '#2a2a2a'; +var BANDIX_MODAL_BG_MATERIAL_LIGHT = '#ffffff'; +var BANDIX_MODAL_BG_MATERIAL_DARK = '#303030'; +var BANDIX_MODAL_BG_BOOTSTRAP_LIGHT = '#ffffff'; +var BANDIX_MODAL_BG_BOOTSTRAP_DARK = '#303030'; +var BANDIX_MODAL_BG_ARGON_LIGHT = '#F4F5F7'; +var BANDIX_MODAL_BG_ARGON_DARK = '#252526'; +var BANDIX_MODAL_BG_AURORA_LIGHT = '#ffffff'; +var BANDIX_MODAL_BG_AURORA_DARK = '#0E172B'; +var BANDIX_MODAL_BG_KUCAT_LIGHT = '#ffffff'; +var BANDIX_MODAL_BG_KUCAT_DARK = '#222D3C'; + +function getThemeMode() { + var theme = uci.get('luci', 'main', 'mediaurlbase'); + + if (theme === '/luci-static/openwrt2020' || + theme === '/luci-static/material' || + theme === '/luci-static/bootstrap-light') { + return 'light'; + } + + if (theme === '/luci-static/bootstrap-dark') { + return 'dark'; + } + + if (theme === '/luci-static/argon') { + var argonMode = uci.get('argon', '@global[0]', 'mode'); + if (argonMode === 'light') { + return 'light'; + } + if (argonMode === 'dark') { + return 'dark'; + } + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + } + + if (theme === '/luci-static/bootstrap' || theme === '/luci-static/aurora') { + var htmlElement = document.documentElement; + var darkMode = htmlElement.getAttribute('data-darkmode'); + return darkMode === 'true' ? 'dark' : 'light'; + } + + if (theme === '/luci-static/kucat') { + var kucatMode = uci.get('kucat', '@basic[0]', 'mode'); + if (kucatMode === 'light') { + return 'light'; + } + if (kucatMode === 'dark') { + return 'dark'; + } + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + } + + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; +} + +function getThemeType() { + // èŽ·å– LuCI 主题设置 + var mediaUrlBase = uci.get('luci', 'main', 'mediaurlbase'); + + if (!mediaUrlBase) { + // 如果无法获å–,å°è¯•从 DOM 中检测 + var linkTags = document.querySelectorAll('link[rel="stylesheet"]'); + for (var i = 0; i < linkTags.length; i++) { + var href = linkTags[i].getAttribute('href') || ''; + if (href.toLowerCase().includes('argon')) { + return 'wide'; + } + } + // 默认返回窄主题 + return 'narrow'; + } + + var mediaUrlBaseLower = mediaUrlBase.toLowerCase(); + + // 宽主题关键è¯åˆ—表(å¯ä»¥æ ¹æ®éœ€è¦æ‰©å±•) + var wideThemeKeywords = ['argon', 'material', 'design', 'edge']; + + // æ£€æŸ¥æ˜¯å¦æ˜¯å®½ä¸»é¢˜ + for (var i = 0; i < wideThemeKeywords.length; i++) { + if (mediaUrlBaseLower.includes(wideThemeKeywords[i])) { + return 'wide'; + } + } + + // 默认是窄主题(Bootstrap 等) + return 'narrow'; +} + +function getThemeColors() { + var theme = uci.get('luci', 'main', 'mediaurlbase'); + var mode = getThemeMode(); + if (theme === '/luci-static/openwrt2020') { + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_OPENWRT2020_DARK : BANDIX_MODAL_BG_OPENWRT2020_LIGHT }; + } + if (theme === '/luci-static/material') { + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_MATERIAL_DARK : BANDIX_MODAL_BG_MATERIAL_LIGHT }; + } + if (theme === '/luci-static/bootstrap-light' || theme === '/luci-static/bootstrap') { + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_BOOTSTRAP_DARK : BANDIX_MODAL_BG_BOOTSTRAP_LIGHT }; + } + if (theme === '/luci-static/bootstrap-dark') { + return { modalBg: BANDIX_MODAL_BG_BOOTSTRAP_DARK }; + } + if (theme === '/luci-static/argon') { + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_ARGON_DARK : BANDIX_MODAL_BG_ARGON_LIGHT }; + } + if (theme === '/luci-static/aurora') { + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_AURORA_DARK : BANDIX_MODAL_BG_AURORA_LIGHT }; + } + if (theme === '/luci-static/kucat') { + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_KUCAT_DARK : BANDIX_MODAL_BG_KUCAT_LIGHT }; + } + return { modalBg: mode === 'dark' ? BANDIX_MODAL_BG_OPENWRT2020_DARK : BANDIX_MODAL_BG_OPENWRT2020_LIGHT }; +} + +function formatSize(bytes) { + if (!bytes || bytes === 0) return '0 B'; + var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; + var i = Math.floor(Math.log(bytes) / Math.log(1024)); + return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + ' ' + units[i]; +} + +// æ ¼å¼åŒ–设备åç§° +function formatDeviceName(device) { + if (device.host && device.host !== '') { + return device.host; + } + return device.ip4 || device.mac || _('Unknown Device'); +} + +// RPC调用 +var callGetConnection = rpc.declare({ + object: 'luci.bandix', + method: 'getConnection', + expect: {} +}); + +var callGetConnectionFlows = rpc.declare({ + object: 'luci.bandix', + method: 'getConnectionFlows', + params: ['ip', 'protocol', 'state', 'page', 'page_size'], + expect: {} +}); + +return view.extend({ + load: function () { + return Promise.all([ + uci.load('bandix'), + uci.load('luci'), + uci.load('argon').catch(function () { + return null; + }) + ]); + }, + + render: function (data) { + var connectionEnabled = uci.get('bandix', 'connections', 'enabled') === '1'; + var themeColors = getThemeColors(); + + // åˆ›å»ºæ ·å¼ + var style = E('style', {}, ` + .bandix-connection-container { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + } + + .bandix-header { + display: flex; + align-items: center; + justify-content: space-between; + } + + .bandix-title { + font-size: 1.5rem; + font-weight: 600; + margin: 0; + } + + .bandix-badge { + border-radius: 4px; + padding: 4px 10px; + font-size: 0.875rem; + } + + .bandix-alert { + border-radius: 4px; + padding: 10px 12px; + display: flex; + align-items: center; + gap: 10px; + font-size: 0.875rem; + } + + /* åªåœ¨å®½æ¨¡å¼ä¸‹åº”ç”¨è­¦å‘Šæ ·å¼ */ + .bandix-alert.wide-theme { + background-color: rgba(251, 191, 36, 0.1); + border: 1px solid rgba(251, 191, 36, 0.3); + color: #92400e; + } + + .theme-dark .bandix-alert.wide-theme { + background-color: rgba(251, 191, 36, 0.15); + border-color: rgba(251, 191, 36, 0.4); + color: #fbbf24; + } + + .bandix-alert-icon { + font-size: 0.875rem; + font-weight: 700; + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + flex-shrink: 0; + } + + .stats-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + margin-top: 0; + } + + /* 移动端统计å¡ç‰‡å¸ƒå±€ */ + @media (max-width: 768px) { + .stats-grid { + grid-template-columns: 1fr; + gap: 12px; + } + + .stats-grid .cbi-section { + padding: 12px; + } + + .stats-card-main-value { + font-size: 1.75rem; + } + + /* 移动端设备列表å¡ç‰‡å¼å¸ƒå±€ */ + .bandix-table { + display: none; /* 移动端éšè—表格 */ + } + + .device-list-cards { + display: block; + } + + .device-card { + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + padding: 12px; + margin-bottom: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); + } + + .device-card-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; + padding-bottom: 12px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + + .device-card-name { + flex: 1; + min-width: 0; + } + + .device-card-name .device-name { + font-weight: 600; + margin-bottom: 4px; + } + + .device-card-name .device-ip { + font-size: 0.75rem; + opacity: 0.7; + } + + .device-card-name .device-mac { + font-size: 0.7rem; + opacity: 0.6; + margin-top: 2px; + } + + .device-card-stats { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + margin-bottom: 12px; + } + + .device-card-stat-item { + display: flex; + flex-direction: column; + gap: 4px; + } + + .device-card-stat-label { + font-size: 0.75rem; + opacity: 0.7; + font-weight: 500; + } + + .device-card-stat-value { + font-size: 1.125rem; + font-weight: 700; + } + + .device-card-tcp-details { + display: flex; + flex-direction: column; + gap: 6px; + margin-bottom: 12px; + padding: 12px; + background-color: rgba(0, 0, 0, 0.02); + border-radius: 6px; + } + + .device-card-tcp-details-label { + font-size: 0.75rem; + opacity: 0.7; + font-weight: 500; + margin-bottom: 4px; + } + + .device-card-tcp-status-row { + display: flex; + align-items: center; + gap: 8px; + font-size: 0.875rem; + } + + .device-card-tcp-status-label { + display: inline-block; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.7rem; + font-weight: 600; + color: white; + min-width: 45px; + text-align: center; + } + + .device-card-tcp-status-label.established { + background-color: #10b981; + } + + .device-card-tcp-status-label.time-wait { + background-color: #f59e0b; + } + + .device-card-tcp-status-label.closed { + background-color: #6b7280; + } + + .device-card-tcp-status-value { + font-weight: 600; + } + + .device-card-total { + display: flex; + justify-content: space-between; + align-items: center; + padding-top: 12px; + border-top: 1px solid rgba(0, 0, 0, 0.1); + } + } + + .theme-dark .device-card { + border-color: rgba(255, 255, 255, 0.15); + } + + .theme-dark .device-card-header { + border-bottom-color: rgba(255, 255, 255, 0.15); + } + + .theme-dark .device-card-tcp-details { + background-color: rgba(255, 255, 255, 0.05); + } + + .theme-dark .device-card-total { + border-top-color: rgba(255, 255, 255, 0.15); + } + + /* PC端显示表格,éšè—å¡ç‰‡ */ + @media (min-width: 769px) { + .bandix-table { + display: table; + } + + .device-list-cards { + display: none; + } + } + + + .bandix-connection-container > .cbi-section:first-of-type { + margin-top: 0; + } + + .bandix-connection-container > .cbi-section:last-of-type { + margin-bottom: 0; + } + + .stats-card-title { + font-size: 0.875rem; + font-weight: 600; + opacity: 0.7; + margin: 0 0 12px 0; + text-transform: uppercase; + letter-spacing: 0.025em; + } + + .stats-grid .cbi-section { + padding: 16px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease; + } + + .theme-dark .stats-grid .cbi-section { + border-color: rgba(255, 255, 255, 0.15); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + } + + .stats-card-main-value { + font-size: 2.25rem; + font-weight: 700; + margin: 0 0 8px 0; + line-height: 1; + } + + .stats-card-details { + margin-top: 12px; + display: flex; + flex-direction: column; + gap: 6px; + width: 100%; + } + + .stats-detail-row { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 0.875rem; + } + + .stats-detail-label { + opacity: 0.7; + font-weight: 500; + } + + .stats-detail-value { + font-weight: 600; + } + + .bandix-table { + width: 100%; + table-layout: fixed; + } + + .bandix-table th { + padding: 12px 16px; + text-align: left; + font-weight: 600; + border: none; + font-size: 0.875rem; + white-space: nowrap; + } + + .bandix-table th:nth-child(1) { width: 26%; } + .bandix-table th:nth-child(2) { width: 10%; } + .bandix-table th:nth-child(3) { width: 10%; } + .bandix-table th:nth-child(4) { width: 28%; } + .bandix-table th:nth-child(5) { width: 13%; } + .bandix-table th:nth-child(6) { width: 13%; } + + .bandix-table td { + padding: 12px 16px; + vertical-align: middle; + word-break: break-word; + overflow-wrap: break-word; + } + + + .device-info { + display: flex; + align-items: center; + gap: 12px; + } + + .device-status { + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; + } + + .device-status.online { + background-color: #10b981; + } + + .device-status.offline { + background-color: #9ca3af; + } + + .device-details { + min-width: 0; + flex: 1; + } + + .device-name { + font-weight: 600; + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 4px; + } + + .device-ip { + opacity: 0.7; + font-size: 0.875rem; + } + + .device-mac { + opacity: 0.6; + font-size: 0.75rem; + } + + + .tcp-status-details { + display: flex; + flex-direction: column; + gap: 6px; + font-size: 0.875rem; + } + + .tcp-status-item { + display: flex; + align-items: center; + gap: 8px; + } + + .tcp-status-label { + display: inline-block; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; + color: white; + min-width: 50px; + text-align: center; + } + + .tcp-status-label.established { + background-color: #10b981; + } + + .tcp-status-label.time-wait { + background-color: #f59e0b; + } + + .tcp-status-label.closed { + background-color: #6b7280; + } + + .tcp-status-value { + font-weight: 600; + } + + .loading-state { + text-align: center; + padding: 40px; + opacity: 0.7; + font-style: italic; + } + + .error-state { + text-align: center; + padding: 40px; + } + + .flows-view-btn { + padding: 4px 10px; + font-size: 0.8rem; + } + + .flows-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,0); + display: flex; + align-items: center; + justify-content: center; + z-index: 1100; + opacity: 0; + visibility: hidden; + transition: opacity 0.2s ease, visibility 0.2s ease, background-color 0.2s ease; + } + + .flows-modal-overlay.show { + background-color: rgba(0,0,0,0.5); + opacity: 1; + visibility: visible; + } + + .flows-modal-overlay .flows-modal-content { + margin: 16px; + width: 95vw; + max-width: 1200px; + max-height: 85vh; + display: flex; + flex-direction: column; + overflow: hidden; + border-radius: 8px; + box-shadow: 0 10px 25px rgba(0,0,0,0.2); + box-sizing: border-box; + background-color: ${themeColors.modalBg}; + } + + .flows-modal-content.theme-light { + color: #111827; + } + + .flows-modal-content.theme-dark { + color: #e5e5e5; + } + + .flows-modal-content.theme-dark .flows-modal-header { + border-bottom-color: rgba(255,255,255,0.15); + } + + .flows-modal-content.theme-dark .flows-filters { + border-bottom-color: rgba(255,255,255,0.15); + } + + .flows-modal-content.theme-dark .flows-table th, + .flows-modal-content.theme-dark .flows-table td { + border-color: rgba(255,255,255,0.1); + } + + .flows-modal-content.theme-dark .flows-table-body { + background-color: transparent; + } + + .flows-modal-content .flows-modal-header { + padding: 12px 16px; + border-bottom: 1px solid rgba(0,0,0,0.1); + flex-shrink: 0; + } + + .flows-modal-content .flows-modal-title { + font-size: 1.1rem; + font-weight: 600; + margin: 0 0 4px 0; + } + + .flows-modal-content .flows-modal-subtitle { + font-size: 0.85rem; + opacity: 0.7; + } + + .flows-modal-content .flows-filters { + padding: 12px 16px; + display: flex; + gap: 12px; + align-items: center; + flex-wrap: wrap; + border-bottom: 1px solid rgba(0,0,0,0.1); + flex-shrink: 0; + } + + .flows-modal-content .flows-filters select, + .flows-modal-content .flows-footer select { + padding: 6px 10px; + border-radius: 4px; + border: 1px solid rgba(0,0,0,0.2); + font-size: 0.875rem; + } + + .flows-modal-content.theme-dark .flows-filters select, + .flows-modal-content.theme-dark .flows-footer select { + background-color: #3a3a3a; + border-color: rgba(255,255,255,0.2); + color: #e5e5e5; + } + + .flows-modal-content .flows-table-wrap { + overflow: auto; + flex: 1; + min-height: 200px; + } + + .flows-modal-content .flows-table { + width: 100%; + table-layout: fixed; + border-collapse: collapse; + font-size: 0.85rem; + } + + .flows-modal-content .flows-table th:nth-child(1), + .flows-modal-content .flows-table td:nth-child(1) { width: 5%; } + .flows-modal-content .flows-table th:nth-child(2), + .flows-modal-content .flows-table td:nth-child(2) { width: 8%; } + .flows-modal-content .flows-table th:nth-child(3), + .flows-modal-content .flows-table td:nth-child(3) { width: 14%; } + .flows-modal-content .flows-table th:nth-child(4), + .flows-modal-content .flows-table td:nth-child(4) { width: 14%; } + .flows-modal-content .flows-table th:nth-child(5), + .flows-modal-content .flows-table td:nth-child(5) { width: 10%; } + .flows-modal-content .flows-table th:nth-child(6), + .flows-modal-content .flows-table td:nth-child(6) { width: 14%; } + .flows-modal-content .flows-table th:nth-child(7), + .flows-modal-content .flows-table td:nth-child(7) { width: 14%; } + .flows-modal-content .flows-table th:nth-child(8), + .flows-modal-content .flows-table td:nth-child(8) { width: 10%; } + .flows-modal-content .flows-table th:nth-child(9), + .flows-modal-content .flows-table td:nth-child(9) { width: 11%; } + + .flows-modal-content .flows-table th, + .flows-modal-content .flows-table td { + padding: 8px 12px; + text-align: left; + border-bottom: 1px solid rgba(0,0,0,0.08); + } + + .flows-modal-content .flows-table th { + font-weight: 600; + white-space: nowrap; + } + + .flows-modal-content .flows-addr-cell { + word-break: break-all; + font-size: 0.8rem; + } + + .flows-modal-content .flows-protocol-tcp { + color: #10b981; + font-weight: 600; + } + + .flows-modal-content .flows-protocol-udp { + color: #06b6d4; + font-weight: 600; + } + + .flows-modal-content .flows-state-est { + color: #10b981; + } + + .flows-modal-content .flows-state-wait { + color: #f59e0b; + } + + .flows-modal-content .flows-state-close { + color: #6b7280; + } + + .flows-modal-content .flows-footer { + padding: 12px 16px; + border-top: 1px solid rgba(0,0,0,0.1); + flex-shrink: 0; + display: flex; + justify-content: flex-end; + align-items: center; + gap: 8px; + flex-wrap: wrap; + } + + .flows-modal-content .flows-footer .flows-page-size-select { + min-width: 92px; + } + + .flows-modal-content.theme-dark .flows-footer { + border-top-color: rgba(255,255,255,0.15); + } + `); + document.head.appendChild(style); + + var themeMode = getThemeMode(); + var container = E('div', { 'class': 'bandix-connection-container theme-' + themeMode }); + + // 页颿 ‡é¢˜ + var header = E('div', { 'class': 'bandix-header' }, [ + E('h1', { 'class': 'bandix-title' }, _('Bandix Connection Monitor')) + ]); + container.appendChild(header); + + // 检查连接监控是å¦å¯ç”¨ + if (!connectionEnabled) { + var alertDiv = E('div', { + 'class': 'bandix-alert' + (getThemeType() === 'wide' ? ' wide-theme' : '') + }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [ + E('span', { 'style': 'font-size: 1rem;' }, 'âš '), + E('div', {}, [ + E('strong', {}, _('Connection Monitor Disabled')), + E('p', { 'style': 'margin: 4px 0 0 0;' }, + _('Please enable connection monitoring in settings')) + ]) + ]) + ]); + container.appendChild(alertDiv); + + var settingsCard = E('div', { 'class': 'cbi-section' }, [ + E('div', { 'style': 'text-align: center; padding: 16px;' }, [ + E('a', { + 'href': '/cgi-bin/luci/admin/network/bandix/settings', + 'class': 'btn btn-primary' + }, _('Go to Settings')) + ]) + ]); + container.appendChild(settingsCard); + return container; + } + + // 添加æç¤ºä¿¡æ¯ + var infoAlert = E('div', { + 'class': 'bandix-alert' + (getThemeType() === 'wide' ? ' wide-theme' : '') + }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [ + E('span', { 'style': 'font-size: 1rem;' }, 'âš '), + E('span', {}, _('List only shows LAN device connections, data may differ from total connections.')) + ]) + ]); + container.appendChild(infoAlert); + + // 全局统计å¡ç‰‡ + var statsGrid = E('div', { 'class': 'stats-grid' }, [ + E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Total Connections')), + E('div', { 'class': 'stats-card-main-value', 'id': 'total-connections' }, '-') + ]), + E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('TCP Connections')), + E('div', { 'class': 'stats-card-main-value', 'id': 'tcp-connections' }, '-'), + E('div', { 'class': 'stats-card-details' }, [ + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, 'ESTABLISHED'), + E('span', { 'class': 'stats-detail-value', 'id': 'established-tcp' }, '-') + ]), + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, 'TIME_WAIT'), + E('span', { 'class': 'stats-detail-value', 'id': 'time-wait-tcp' }, '-') + ]), + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, 'CLOSE_WAIT'), + E('span', { 'class': 'stats-detail-value', 'id': 'close-wait-tcp' }, '-') + ]) + ]) + ]), + E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('UDP Connections')), + E('div', { 'class': 'stats-card-main-value', 'id': 'udp-connections' }, '-') + ]) + ]); + container.appendChild(statsGrid); + + // 设备连接统计表格 + var deviceCard = E('div', { 'class': 'cbi-section' }, [ + E('h3', {}, _('Device Connection Statistics')), + E('div', {}, [ + E('div', { 'id': 'device-table-container' }, [ + E('table', { 'class': 'bandix-table' }, [ + E('thead', {}, [ + E('tr', {}, [ + E('th', {}, _('Device')), + E('th', {}, 'TCP'), + E('th', {}, 'UDP'), + E('th', {}, _('TCP Status Details')), + E('th', {}, _('Total Connections')), + E('th', { 'style': 'width: 80px;' }, _('Actions')) + ]) + ]), + E('tbody', {}) + ]) + ]) + ]) + ]); + container.appendChild(deviceCard); + + // 更新全局统计 + function updateGlobalStats(stats) { + if (!stats) return; + + document.getElementById('total-connections').textContent = stats.total || 0; + document.getElementById('tcp-connections').textContent = stats.tcp || 0; + document.getElementById('udp-connections').textContent = stats.udp || 0; + document.getElementById('established-tcp').textContent = stats.tcp_est || 0; + document.getElementById('time-wait-tcp').textContent = stats.tcp_tw || 0; + document.getElementById('close-wait-tcp').textContent = stats.tcp_cw || 0; + } + + // 更新设备表格 + function updateDeviceTable(devices) { + var container = document.getElementById('device-table-container'); + + if (!devices || devices.length === 0) { + container.innerHTML = ''; + container.appendChild(E('div', { 'class': 'loading-state' }, + _('No Data'))); + return; + } + + // 创建表格(PC端) + var table = E('table', { 'class': 'bandix-table' }, [ + E('thead', {}, [ + E('tr', {}, [ + E('th', {}, _('Device')), + E('th', {}, 'TCP'), + E('th', {}, 'UDP'), + E('th', {}, _('TCP Status Details')), + E('th', {}, _('Total Connections')), + E('th', {}, _('Actions')) + ]) + ]), + E('tbody', {}, devices.map(function (device) { + var viewBtn = E('button', { + 'class': 'cbi-button cbi-button-reset flows-view-btn', + 'data-ip': device.ip4 || '', + 'data-device': JSON.stringify({ ip4: device.ip4, host: device.host, mac: device.mac }) + }, _('Details')); + return E('tr', {}, [ + E('td', {}, [ + E('div', { 'class': 'device-info' }, [ + E('div', { 'class': 'device-status online' }), + E('div', { 'class': 'device-details' }, [ + E('div', { 'class': 'device-name' }, formatDeviceName(device)), + E('div', { 'class': 'device-ip' }, device.ip4 || '-'), + E('div', { 'class': 'device-mac' }, device.mac || '-') + ]) + ]) + ]), + E('td', { 'style': 'font-weight: 600; font-size: 1.25rem;' }, device.tcp || 0), + E('td', { 'style': 'font-weight: 600; font-size: 1.25rem;' }, device.udp || 0), + E('td', {}, [ + E('div', { 'class': 'tcp-status-details' }, [ + E('div', { 'class': 'tcp-status-item' }, [ + E('span', { 'class': 'tcp-status-label established' }, 'EST'), + E('span', { 'class': 'tcp-status-value' }, device.tcp_est || 0) + ]), + E('div', { 'class': 'tcp-status-item' }, [ + E('span', { 'class': 'tcp-status-label time-wait' }, 'WAIT'), + E('span', { 'class': 'tcp-status-value' }, device.tcp_tw || 0) + ]), + E('div', { 'class': 'tcp-status-item' }, [ + E('span', { 'class': 'tcp-status-label closed' }, 'CLOSE'), + E('span', { 'class': 'tcp-status-value' }, device.tcp_cw || 0) + ]) + ]) + ]), + E('td', {}, E('strong', { 'style': 'font-size: 1.25rem;' }, device.total || 0)), + E('td', {}, viewBtn) + ]); + })) + ]); + + // 创建å¡ç‰‡å®¹å™¨ï¼ˆç§»åŠ¨ç«¯ï¼‰ + var cardsContainer = E('div', { 'class': 'device-list-cards' }); + + devices.forEach(function (device) { + var card = E('div', { 'class': 'device-card' }, [ + // å¡ç‰‡å¤´éƒ¨ï¼šè®¾å¤‡ä¿¡æ¯ + E('div', { 'class': 'device-card-header' }, [ + E('div', { 'class': 'device-status online' }), + E('div', { 'class': 'device-card-name' }, [ + E('div', { 'class': 'device-name' }, formatDeviceName(device)), + E('div', { 'class': 'device-ip' }, device.ip4 || '-'), + E('div', { 'class': 'device-mac' }, device.mac || '-') + ]) + ]), + // 统计信æ¯ï¼šTCP å’Œ UDP + E('div', { 'class': 'device-card-stats' }, [ + E('div', { 'class': 'device-card-stat-item' }, [ + E('div', { 'class': 'device-card-stat-label' }, 'TCP'), + E('div', { 'class': 'device-card-stat-value' }, device.tcp || 0) + ]), + E('div', { 'class': 'device-card-stat-item' }, [ + E('div', { 'class': 'device-card-stat-label' }, 'UDP'), + E('div', { 'class': 'device-card-stat-value' }, device.udp || 0) + ]) + ]), + // TCP 状æ€è¯¦æƒ… + E('div', { 'class': 'device-card-tcp-details' }, [ + E('div', { 'class': 'device-card-tcp-details-label' }, _('TCP Status Details')), + E('div', { 'class': 'device-card-tcp-status-row' }, [ + E('span', { 'class': 'device-card-tcp-status-label established' }, 'EST'), + E('span', { 'class': 'device-card-tcp-status-value' }, device.tcp_est || 0) + ]), + E('div', { 'class': 'device-card-tcp-status-row' }, [ + E('span', { 'class': 'device-card-tcp-status-label time-wait' }, 'WAIT'), + E('span', { 'class': 'device-card-tcp-status-value' }, device.tcp_tw || 0) + ]), + E('div', { 'class': 'device-card-tcp-status-row' }, [ + E('span', { 'class': 'device-card-tcp-status-label closed' }, 'CLOSE'), + E('span', { 'class': 'device-card-tcp-status-value' }, device.tcp_cw || 0) + ]) + ]), + // 总连接数 + E('div', { 'class': 'device-card-total' }, [ + E('div', { 'style': 'font-size: 0.875rem; opacity: 0.7; font-weight: 500;' }, _('Total Connections')), + E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [ + E('span', { 'style': 'font-size: 1.25rem; font-weight: 700;' }, device.total || 0), + E('button', { + 'class': 'cbi-button cbi-button-reset flows-view-btn', + 'data-ip': device.ip4 || '', + 'data-device': JSON.stringify({ ip4: device.ip4, host: device.host, mac: device.mac }) + }, _('Details')) + ]) + ]) + ]); + + cardsContainer.appendChild(card); + }); + + container.innerHTML = ''; + container.appendChild(table); + container.appendChild(cardsContainer); + } + + // æ˜¾ç¤ºé”™è¯¯ä¿¡æ¯ + function showError(message) { + var container = document.getElementById('device-table-container'); + container.innerHTML = ''; + container.appendChild(E('div', { 'class': 'error-state' }, message)); + } + + // 定义更新连接数æ®çš„函数 + function updateConnectionData() { + return callGetConnection().then(function (result) { + if (result && result.status === 'success' && result.data) { + updateGlobalStats(result.data.g); + updateDeviceTable(result.data.d); + } else { + showError(_('Unable to fetch data')); + } + }).catch(function (error) { + console.error('Failed to load connection data:', error); + showError(_('Unable to fetch data')); + }); + } + + function showFlowsModal(deviceIp, deviceInfo) { + var currentTheme = getThemeMode(); + var currentPage = 1; + var totalPages = 1; + var totalItems = 0; + var currentPageSize = 100; + + var protocolSelect = E('select', { 'class': 'cbi-input-select', 'id': 'flows-protocol' }, [ + E('option', { 'value': '' }, _('All')), + E('option', { 'value': 'tcp' }, 'TCP'), + E('option', { 'value': 'udp' }, 'UDP') + ]); + var stateSelect = E('select', { 'class': 'cbi-input-select', 'id': 'flows-state' }, [ + E('option', { 'value': '' }, _('All')), + E('option', { 'value': 'ESTABLISHED' }, 'ESTABLISHED'), + E('option', { 'value': 'SYN_SENT' }, 'SYN_SENT'), + E('option', { 'value': 'SYN_RECV' }, 'SYN_RECV'), + E('option', { 'value': 'FIN_WAIT' }, 'FIN_WAIT'), + E('option', { 'value': 'FIN_WAIT2' }, 'FIN_WAIT2'), + E('option', { 'value': 'TIME_WAIT' }, 'TIME_WAIT'), + E('option', { 'value': 'CLOSE_WAIT' }, 'CLOSE_WAIT'), + E('option', { 'value': 'LAST_ACK' }, 'LAST_ACK'), + E('option', { 'value': 'CLOSE' }, 'CLOSE') + ]); + var pageSizeSelect = E('select', { 'class': 'cbi-input-select flows-page-size-select', 'id': 'flows-page-size' }, [ + E('option', { 'value': '50' }, '50'), + E('option', { 'value': '100', 'selected': 'selected' }, '100'), + E('option', { 'value': '200' }, '200'), + E('option', { 'value': '500' }, '500') + ]); + var pageInfo = E('span', { 'style': 'font-size: 0.85rem; opacity: 0.85; margin: 0 14px;' }, ''); + var prevPageBtn = E('button', { 'class': 'cbi-button cbi-button-action', 'style': 'margin-right: 8px;' }, _('Previous')); + var nextPageBtn = E('button', { 'class': 'cbi-button cbi-button-action' }, _('Next')); + var tableBody = E('tbody', { 'class': 'flows-table-body' }); + var tableWrap = E('div', { 'class': 'flows-table-wrap' }, [ + E('table', { 'class': 'flows-table' }, [ + E('thead', {}, [ + E('tr', {}, [ + E('th', {}, _('Protocol')), + E('th', {}, _('State')), + E('th', {}, _('Orig Src')), + E('th', {}, _('Orig Dst')), + E('th', {}, _('Send')), + E('th', {}, _('Repl Src')), + E('th', {}, _('Repl Dst')), + E('th', {}, _('Reply')), + E('th', {}, _('Flags')) + ]) + ]), + tableBody + ]) + ]); + + function updatePaginationUi() { + if (pageInfo) { + pageInfo.textContent = _('Page') + ' ' + currentPage + '/' + totalPages + ' · ' + _('Total') + ': ' + totalItems; + } + if (prevPageBtn) { + prevPageBtn.disabled = currentPage <= 1; + } + if (nextPageBtn) { + nextPageBtn.disabled = currentPage >= totalPages; + } + } + + function normalizeFlowsResponse(res) { + if (!res || res.status !== 'success') { + return { items: [], total: 0, page: currentPage, page_size: currentPageSize, total_pages: 1 }; + } + + if (Array.isArray(res.data)) { + // 兼容旧åŽç«¯ï¼šdata 直接是数组 + return { + items: res.data, + total: res.data.length, + page: 1, + page_size: res.data.length || currentPageSize, + total_pages: 1 + }; + } + + if (res.data && Array.isArray(res.data.items)) { + // æ–°åŽç«¯ï¼šåˆ†é¡µå¯¹è±¡ + return { + items: res.data.items, + total: res.data.total || 0, + page: res.data.page || currentPage, + page_size: res.data.page_size || currentPageSize, + total_pages: res.data.total_pages || 1 + }; + } + + return { items: [], total: 0, page: currentPage, page_size: currentPageSize, total_pages: 1 }; + } + + function loadFlows(resetPage) { + if (resetPage) { + currentPage = 1; + } + var protocol = protocolSelect.value || ''; + var state = stateSelect.value || ''; + currentPageSize = parseInt(pageSizeSelect.value, 10) || 100; + tableBody.innerHTML = ''; + tableBody.appendChild(E('tr', {}, [ + E('td', { 'colspan': 9, 'class': 'loading-state' }, _('Loading…')) + ])); + return callGetConnectionFlows(deviceIp, protocol || null, state || null, currentPage, currentPageSize).then(function (res) { + tableBody.innerHTML = ''; + var normalized = normalizeFlowsResponse(res); + var flows = normalized.items; + totalItems = normalized.total; + currentPage = normalized.page; + totalPages = Math.max(1, normalized.total_pages); + updatePaginationUi(); + + if (!flows || flows.length === 0) { + tableBody.appendChild(E('tr', {}, [ + E('td', { 'colspan': 9, 'class': 'loading-state' }, _('No connections')) + ])); + return; + } + flows.forEach(function (f) { + var stateCls = ''; + if (f.state) { + if (f.state.indexOf('ESTABLISHED') >= 0) stateCls = 'flows-state-est'; + else if (f.state.indexOf('TIME_WAIT') >= 0) stateCls = 'flows-state-wait'; + else if (f.state.indexOf('CLOSE') >= 0) stateCls = 'flows-state-close'; + } + var origSrc = f.orig ? (f.orig.src || '-') + ':' + (f.orig.sport || '-') : '-'; + var origDst = f.orig ? (f.orig.dst || '-') + ':' + (f.orig.dport || '-') : '-'; + var replSrc = f.repl ? (f.repl.src || '-') + ':' + (f.repl.sport || '-') : '-'; + var replDst = f.repl ? (f.repl.dst || '-') + ':' + (f.repl.dport || '-') : '-'; + var sendStr = (f.orig_packets || 0) + ' ' + _('pkts') + ' / ' + formatSize(f.orig_bytes || 0); + var replyStr = (f.repl_packets || 0) + ' ' + _('pkts') + ' / ' + formatSize(f.repl_bytes || 0); + var flagsStr = (f.flags && f.flags.length) ? f.flags.join(' ') : '-'; + var protoCls = (f.protocol || '').toLowerCase() === 'tcp' ? 'flows-protocol-tcp' : 'flows-protocol-udp'; + tableBody.appendChild(E('tr', {}, [ + E('td', { 'class': protoCls }, (f.protocol || '-').toUpperCase()), + E('td', { 'class': stateCls }, f.state || '-'), + E('td', { 'class': 'flows-addr-cell' }, origSrc), + E('td', { 'class': 'flows-addr-cell' }, origDst), + E('td', {}, sendStr), + E('td', { 'class': 'flows-addr-cell' }, replSrc), + E('td', { 'class': 'flows-addr-cell' }, replDst), + E('td', {}, replyStr), + E('td', { 'style': 'font-size: 0.8rem;' }, flagsStr) + ])); + }); + }).catch(function (err) { + totalItems = 0; + totalPages = 1; + currentPage = 1; + updatePaginationUi(); + tableBody.innerHTML = ''; + tableBody.appendChild(E('tr', {}, [ + E('td', { 'colspan': 9, 'class': 'error-state' }, _('Failed to load') + ': ' + (err.message || err) + ' · ' + _('Try using filters or smaller page size')) + ])); + }); + } + + function onFilterChange() { + loadFlows(true); + } + + function hideFlowsModal() { + var overlay = document.getElementById('flows-modal-overlay'); + if (overlay) overlay.classList.remove('show'); + } + + prevPageBtn.addEventListener('click', function () { + if (currentPage > 1) { + currentPage -= 1; + loadFlows(false); + } + }); + nextPageBtn.addEventListener('click', function () { + if (currentPage < totalPages) { + currentPage += 1; + loadFlows(false); + } + }); + pageSizeSelect.addEventListener('change', function () { + loadFlows(true); + }); + + var modalContent = E('div', { 'class': 'flows-modal-content theme-' + currentTheme }, [ + E('div', { 'class': 'flows-modal-header' }, [ + E('div', { 'class': 'flows-modal-title' }, _('Connection Details') + ' - ' + (deviceInfo.host || deviceInfo.ip4 || deviceIp)), + E('div', { 'class': 'flows-modal-subtitle' }, (deviceInfo.ip4 || '') + (deviceInfo.mac ? ' · ' + deviceInfo.mac : '')) + ]), + E('div', { 'class': 'flows-filters' }, [ + E('label', {}, _('Protocol') + ':'), + protocolSelect, + E('label', {}, _('State') + ':'), + stateSelect, + E('button', { 'class': 'cbi-button cbi-button-apply', 'click': loadFlows }, _('Refresh')) + ]), + tableWrap, + E('div', { 'class': 'flows-footer' }, [ + pageSizeSelect, + prevPageBtn, + nextPageBtn, + pageInfo, + E('button', { 'class': 'cbi-button cbi-button-reset', 'click': hideFlowsModal }, _('Close')) + ]) + ]); + + if (protocolSelect && protocolSelect.addEventListener) { + protocolSelect.addEventListener('change', onFilterChange); + } + if (stateSelect && stateSelect.addEventListener) { + stateSelect.addEventListener('change', onFilterChange); + } + + var overlay = document.getElementById('flows-modal-overlay'); + if (!overlay) { + overlay = E('div', { 'class': 'flows-modal-overlay', 'id': 'flows-modal-overlay' }); + document.body.appendChild(overlay); + } + overlay.innerHTML = ''; + overlay.appendChild(modalContent); + overlay.classList.add('show'); + modalContent.addEventListener('click', function (e) { e.stopPropagation(); }); + updatePaginationUi(); + loadFlows(true); + } + + container.addEventListener('click', function (ev) { + var btn = ev.target; + if (btn && btn.classList && btn.classList.contains('flows-view-btn')) { + var ip = btn.getAttribute('data-ip'); + var deviceStr = btn.getAttribute('data-device'); + var deviceInfo = {}; + try { + if (deviceStr) deviceInfo = JSON.parse(deviceStr); + } catch (e) {} + if (ip) showFlowsModal(ip, deviceInfo); + } + }); + + // è½®è¯¢èŽ·å–æ•°æ® + poll.add(updateConnectionData, 1); + + // ç«‹å³æ‰§è¡Œä¸€æ¬¡ï¼Œä¸ç­‰å¾…轮询 + updateConnectionData(); + + // 自动适应主题背景色和文字颜色的函数 + function applyThemeColors() { + try { + var mainElement = document.querySelector('.main') || document.body; + var computedStyle = window.getComputedStyle(mainElement); + var bgColor = computedStyle.backgroundColor; + + // 如果父元素有背景色,应用到容器和å¡ç‰‡ + if (bgColor && bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent') { + var containerEl = document.querySelector('.bandix-connection-container'); + if (containerEl) { + containerEl.style.backgroundColor = bgColor; + } + + // 应用到表格表头 + var tableHeaders = document.querySelectorAll('.bandix-table th'); + tableHeaders.forEach(function (th) { + th.style.backgroundColor = bgColor; + }); + } + + // 检测文字颜色并应用 + var textColor = computedStyle.color; + if (textColor && textColor !== 'rgba(0, 0, 0, 0)') { + var containerEl = document.querySelector('.bandix-connection-container'); + if (containerEl) { + containerEl.style.color = textColor; + } + } + } catch (e) { + // 如果检测失败,使用默认值 + console.log('Theme adaptation:', e); + } + } + + // åˆå§‹åº”用主题颜色 + setTimeout(applyThemeColors, 100); + + // ç›‘å¬ DOM å˜åŒ–,自动应用到新创建的元素 + if (typeof MutationObserver !== 'undefined') { + var observer = new MutationObserver(function (mutations) { + applyThemeColors(); + }); + + setTimeout(function () { + var container = document.querySelector('.bandix-connection-container'); + if (container) { + observer.observe(container, { + childList: true, + subtree: true + }); + } + }, 200); + } + + return container; + } +}); diff --git a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/dns.js b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/dns.js new file mode 100644 index 00000000..1bdfcffb --- /dev/null +++ b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/dns.js @@ -0,0 +1,1525 @@ +'use strict'; +'require view'; +'require ui'; +'require uci'; +'require rpc'; +'require poll'; + + +function getThemeMode() { + var theme = uci.get('luci', 'main', 'mediaurlbase'); + + if (theme === '/luci-static/openwrt2020' || + theme === '/luci-static/material' || + theme === '/luci-static/bootstrap-light') { + return 'light'; + } + + if (theme === '/luci-static/bootstrap-dark') { + return 'dark'; + } + + if (theme === '/luci-static/argon') { + var argonMode = uci.get('argon', '@global[0]', 'mode'); + if (argonMode === 'light') { + return 'light'; + } + if (argonMode === 'dark') { + return 'dark'; + } + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + } + + if (theme === '/luci-static/bootstrap' || theme === '/luci-static/aurora') { + var htmlElement = document.documentElement; + var darkMode = htmlElement.getAttribute('data-darkmode'); + return darkMode === 'true' ? 'dark' : 'light'; + } + + if (theme === '/luci-static/kucat') { + var kucatMode = uci.get('kucat', '@basic[0]', 'mode'); + if (kucatMode === 'light') { + return 'light'; + } + if (kucatMode === 'dark') { + return 'dark'; + } + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + } + + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; +} + +function getThemeType() { + // èŽ·å– LuCI 主题设置 + var mediaUrlBase = uci.get('luci', 'main', 'mediaurlbase'); + + if (!mediaUrlBase) { + // 如果无法获å–,å°è¯•从 DOM 中检测 + var linkTags = document.querySelectorAll('link[rel="stylesheet"]'); + for (var i = 0; i < linkTags.length; i++) { + var href = linkTags[i].getAttribute('href') || ''; + if (href.toLowerCase().includes('argon')) { + return 'wide'; + } + } + // 默认返回窄主题 + return 'narrow'; + } + + var mediaUrlBaseLower = mediaUrlBase.toLowerCase(); + + // 宽主题关键è¯åˆ—表(å¯ä»¥æ ¹æ®éœ€è¦æ‰©å±•) + var wideThemeKeywords = ['argon', 'material', 'design', 'edge']; + + // æ£€æŸ¥æ˜¯å¦æ˜¯å®½ä¸»é¢˜ + for (var i = 0; i < wideThemeKeywords.length; i++) { + if (mediaUrlBaseLower.includes(wideThemeKeywords[i])) { + return 'wide'; + } + } + + // 默认是窄主题(Bootstrap 等) + return 'narrow'; +} + + + +function formatDeviceName(device) { + var parts = []; + if (device && device.device_name && device.device_name !== '') { + parts.push(device.device_name); + } + // 显示IPåœ°å€ + // 查询时使用source_ip(查询设备的IP) + // å“应时使用destination_ip(目标IPï¼Œå³æŸ¥è¯¢è®¾å¤‡çš„IPï¼‰ï¼Œè€Œä¸æ˜¯source_ip(DNSæœåŠ¡å™¨çš„IP) + var ip = null; + if (device && device.is_query) { + // 查询记录:使用source_ip + ip = device.source_ip; + } else { + // å“应记录:使用destination_ip(目标IP) + ip = device.destination_ip; + } + if (ip) { + parts.push(ip); + } + if (parts.length === 0) { + return _('Unknown Device'); + } + return parts.join(' / '); +} + +function formatDnsServer(query) { + if (!query) return '-'; + // 查询时显示目标IP(destination_ip),å“应时显示æºIP(source_ip) + if (query.is_query) { + return query.destination_ip || '-'; + } else { + return query.source_ip || '-'; + } +} + +function formatResponseResult(query) { + if (!query) return { display: [], full: [] }; + + // 显示å“应记录(response_records),它是一个字符串数组 + if (query.response_records && Array.isArray(query.response_records) && query.response_records.length > 0) { + var maxDisplay = 5; // 最多显示5æ¡ + var displayRecords = query.response_records.slice(0, maxDisplay); + var fullRecords = query.response_records; + + return { + display: displayRecords, + full: fullRecords, + hasMore: fullRecords.length > maxDisplay + }; + } + + return { display: [], full: [] }; +} + +var callGetDnsQueries = rpc.declare({ + object: 'luci.bandix', + method: 'getDnsQueries', + params: ['domain', 'device', 'is_query', 'dns_server', 'query_type', 'page', 'page_size'], + expect: {} +}); + +var callGetDnsStats = rpc.declare({ + object: 'luci.bandix', + method: 'getDnsStats', + expect: {} +}); + +return view.extend({ + load: function () { + return Promise.all([ + uci.load('bandix'), + uci.load('luci'), + uci.load('argon').catch(function () { + return null; + }) + ]); + }, + + render: function (data) { + var dnsEnabled = uci.get('bandix', 'dns', 'enabled') === '1'; + + var style = E('style', {}, ` + .bandix-dns-container { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + } + + .bandix-header { + display: flex; + align-items: center; + justify-content: space-between; + } + + .bandix-title { + font-size: 1.5rem; + font-weight: 600; + margin: 0; + } + + .bandix-alert { + border-radius: 4px; + padding: 10px 12px; + display: flex; + align-items: center; + gap: 10px; + font-size: 0.875rem; + } + + /* åªåœ¨å®½æ¨¡å¼ä¸‹åº”ç”¨è­¦å‘Šæ ·å¼ */ + .bandix-alert.wide-theme { + background-color: rgba(251, 191, 36, 0.1); + border: 1px solid rgba(251, 191, 36, 0.3); + color: #92400e; + } + + .theme-dark .bandix-alert.wide-theme { + background-color: rgba(251, 191, 36, 0.15); + border-color: rgba(251, 191, 36, 0.4); + color: #fbbf24; + } + + .bandix-alert-icon { + font-size: 0.875rem; + font-weight: 700; + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + flex-shrink: 0; + } + + + .filter-section { + display: flex; + flex-wrap: wrap; + gap: 12px; + padding: 16px; + align-items: center; + } + + .filter-group { + display: flex; + align-items: center; + gap: 8px; + } + + .filter-label { + font-size: 0.875rem; + font-weight: 500; + white-space: nowrap; + } + + .filter-input { + padding: 6px 12px; + border-radius: 4px; + font-size: 0.875rem; + min-width: 120px; + max-width: 200px; + width: 120px; + opacity: 1; + } + + .filter-section .cbi-input-select { + min-width: 120px; + max-width: 200px; + width: 120px; + } + + .bandix-table { + width: 100%; + font-size: 0.875rem; + } + + .bandix-table th { + padding: 10px 12px; + text-align: left; + font-weight: 600; + opacity: 1; + white-space: nowrap; + } + + .bandix-table td { + padding: 10px 12px; + word-break: break-word; + } + + .query-badge { + display: inline-block; + padding: 2px 8px; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; + } + + .query-badge.query { + background-color: #3b82f6; + color: white; + } + + .query-badge.response { + background-color: #10b981; + color: white; + } + + .response-code { + display: inline-block; + padding: 2px 8px; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; + } + + .response-code.success { + background-color: #10b981; + color: white; + } + + .response-code.error { + background-color: #ef4444; + color: white; + } + + .response-code.warning { + background-color: #f59e0b; + color: white; + } + + .pagination { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px; + flex-wrap: wrap; + gap: 12px; + } + + .pagination-info { + font-size: 0.875rem; + opacity: 0.7; + } + + .pagination-controls { + display: flex; + align-items: center; + gap: 8px; + } + + /* åˆ·æ–°æŒ‰é’®åŠ è½½çŠ¶æ€ */ + .refresh-btn-loading { + position: relative; + pointer-events: none; + opacity: 0.8; + } + + .refresh-btn-loading::before { + content: ''; + display: inline-block; + width: 14px; + height: 14px; + border: 2px solid currentColor; + border-top-color: transparent; + border-right-color: transparent; + border-radius: 50%; + animation: refresh-btn-spin 0.6s linear infinite; + margin-right: 8px; + vertical-align: middle; + } + + @keyframes refresh-btn-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + + .loading-state { + text-align: center; + padding: 40px; + opacity: 0.7; + font-style: italic; + } + + .error-state { + text-align: center; + padding: 40px; + } + + .refresh-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + backdrop-filter: blur(2px); + -webkit-backdrop-filter: blur(2px); + } + + .response-ips { + display: flex; + flex-wrap: wrap; + gap: 4px; + } + + .response-ip-badge { + display: inline-block; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.75rem; + } + + .stats-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + margin-bottom: 16px; + } + + @media (max-width: 1200px) { + .stats-grid { + grid-template-columns: repeat(2, 1fr); + } + } + + @media (max-width: 768px) { + .stats-grid { + grid-template-columns: 1fr; + } + } + + .stats-card-title { + font-size: 0.875rem; + font-weight: 600; + opacity: 0.7; + margin: 0 0 12px 0; + text-transform: uppercase; + letter-spacing: 0.025em; + } + + .stats-grid .cbi-section { + padding: 16px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease; + } + + .theme-dark .stats-grid .cbi-section { + border-color: rgba(255, 255, 255, 0.15); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + } + + .stats-card-main-value { + font-size: 2.25rem; + font-weight: 700; + margin: 0 0 8px 0; + line-height: 1; + } + + .stats-card-sub-value { + font-size: 0.875rem; + opacity: 0.7; + margin: 0; + } + + .stats-card-details { + margin-top: 16px; + display: flex; + flex-direction: column; + gap: 8px; + } + + .stats-detail-row { + display: flex; + align-items: center; + gap: 8px; + font-size: 0.875rem; + } + + .stats-detail-label { + opacity: 0.7; + font-weight: 500; + } + + .stats-detail-value { + font-weight: 600; + } + + .stats-list-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 4px 0; + font-size: 0.875rem; + } + + .stats-list-name { + opacity: 0.8; + } + + .stats-list-count { + font-weight: 600; + opacity: 0.9; + } + + /* 移动端优化 */ + @media (max-width: 768px) { + /* 移动端éšè—表格,显示å¡ç‰‡ */ + .bandix-table { + display: none; + } + + .dns-query-cards { + display: block; + } + + /* 移动端å¡ç‰‡æ ·å¼ */ + .dns-query-card { + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + padding: 12px; + margin-bottom: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); + } + + .dns-query-card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; + padding-bottom: 12px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + + .dns-query-card-time { + font-size: 0.75rem; + opacity: 0.7; + font-weight: 500; + } + + .dns-query-card-type { + display: inline-block; + padding: 2px 8px; + border-radius: 4px; + font-size: 0.7rem; + font-weight: 600; + } + + .dns-query-card-body { + display: flex; + flex-direction: column; + gap: 10px; + } + + .dns-query-card-row { + display: flex; + flex-direction: column; + gap: 4px; + } + + .dns-query-card-label { + font-size: 0.75rem; + opacity: 0.7; + font-weight: 500; + } + + .dns-query-card-value { + font-size: 0.875rem; + font-weight: 600; + word-break: break-word; + } + + .dns-query-card-domain { + font-size: 0.9375rem; + font-weight: 600; + color: #3b82f6; + word-break: break-word; + } + + .dns-query-card-response-result { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin-top: 4px; + } + + .dns-query-card-response-badge { + display: inline-block; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.7rem; + background-color: rgba(0, 0, 0, 0.05); + } + + /* 移动端过滤器优化 */ + .filter-section { + flex-direction: column; + align-items: stretch; + padding: 12px; + gap: 10px; + } + + .filter-group { + width: 100%; + flex-direction: column; + align-items: stretch; + gap: 6px; + } + + .filter-label { + font-size: 0.8125rem; + } + + .filter-input, + .filter-section .cbi-input-select { + width: 100%; + max-width: 100%; + min-width: 100%; + } + + /* 移动端分页优化 */ + .pagination { + flex-direction: column; + align-items: stretch; + gap: 12px; + padding: 12px; + } + + .pagination-info { + text-align: center; + font-size: 0.8125rem; + } + + .pagination-controls { + width: 100%; + justify-content: center; + flex-wrap: wrap; + } + + .pagination-controls .cbi-input-select { + width: 100%; + margin-right: 0; + margin-bottom: 8px; + } + + .pagination-controls button { + flex: 1; + min-width: 100px; + } + } + + .theme-dark .dns-query-card { + border-color: rgba(255, 255, 255, 0.15); + } + + .theme-dark .dns-query-card-header { + border-bottom-color: rgba(255, 255, 255, 0.15); + } + + .theme-dark .dns-query-card-response-badge { + background-color: rgba(255, 255, 255, 0.1); + } + + /* PC端显示表格,éšè—å¡ç‰‡ */ + @media (min-width: 769px) { + .bandix-table { + display: table; + } + + .dns-query-cards { + display: none; + } + } + `); + document.head.appendChild(style); + + var themeMode = getThemeMode(); + var container = E('div', { 'class': 'bandix-dns-container theme-' + themeMode }); + + var header = E('div', { 'class': 'bandix-header' }, [ + E('h1', { 'class': 'bandix-title' }, _('Bandix DNS Monitor')) + ]); + container.appendChild(header); + + if (!dnsEnabled) { + var alertDiv = E('div', { + 'class': 'bandix-alert' + (getThemeType() === 'wide' ? ' wide-theme' : '') + }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [ + E('span', { 'style': 'font-size: 1rem;' }, 'âš '), + E('div', {}, [ + E('strong', {}, _('DNS Monitoring Disabled')), + E('p', { 'style': 'margin: 4px 0 0 0;' }, + _('Please enable DNS monitoring in settings')) + ]) + ]) + ]); + container.appendChild(alertDiv); + + var settingsCard = E('div', { 'class': 'cbi-section' }, [ + E('div', { 'style': 'text-align: center; padding: 16px;' }, [ + E('a', { + 'href': '/cgi-bin/luci/admin/network/bandix/settings', + 'class': 'btn btn-primary' + }, _('Go to Settings')) + ]) + ]); + container.appendChild(settingsCard); + return container; + } + + // 添加æç¤ºä¿¡æ¯ + var infoAlert = E('div', { + 'class': 'bandix-alert' + (getThemeType() === 'wide' ? ' wide-theme' : '') + }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [ + E('span', { 'style': 'font-size: 1rem;' }, 'âš '), + E('span', {}, _('Does not include DoH and DoT')) + ]) + ]); + container.appendChild(infoAlert); + + // DNS 统计信æ¯å¡ç‰‡ + var statsGrid = E('div', { 'class': 'stats-grid', 'id': 'dns-stats-grid' }); + container.appendChild(statsGrid); + + // DNS 查询记录 + var queriesSection = E('div', { 'class': 'cbi-section' }, [ + E('h3', {}, _('DNS Query Records')), + E('div', {}, [ + E('div', { 'class': 'filter-section' }, [ + E('div', { 'class': 'filter-group' }, [ + E('label', { 'class': 'filter-label' }, _('Type Filter') + ':'), + E('select', { 'class': 'cbi-input-select', 'id': 'type-filter' }, [ + E('option', { 'value': '' }, _('All')), + E('option', { 'value': 'true' }, _('Queries Only')), + E('option', { 'value': 'false' }, _('Responses Only')) + ]) + ]), + E('div', { 'class': 'filter-group' }, [ + E('label', { 'class': 'filter-label' }, _('Domain Filter') + ':'), + E('input', { + 'type': 'text', + 'class': 'filter-input', + 'id': 'domain-filter', + 'placeholder': _('Domain') + }) + ]), + E('div', { 'class': 'filter-group' }, [ + E('label', { 'class': 'filter-label' }, _('Query Type') + ':'), + E('select', { 'class': 'cbi-input-select', 'id': 'query-type-filter' }, [ + E('option', { 'value': '' }, _('All')), + E('option', { 'value': 'A' }, 'A'), + E('option', { 'value': 'AAAA' }, 'AAAA'), + E('option', { 'value': 'CNAME' }, 'CNAME'), + E('option', { 'value': 'MX' }, 'MX'), + E('option', { 'value': 'TXT' }, 'TXT'), + E('option', { 'value': 'NS' }, 'NS'), + E('option', { 'value': 'PTR' }, 'PTR'), + E('option', { 'value': 'SOA' }, 'SOA'), + E('option', { 'value': 'SRV' }, 'SRV'), + E('option', { 'value': 'HTTPS' }, 'HTTPS'), + E('option', { 'value': 'SVCB' }, 'SVCB') + ]) + ]), + E('div', { 'class': 'filter-group' }, [ + E('label', { 'class': 'filter-label' }, _('Device Filter') + ':'), + E('input', { + 'type': 'text', + 'class': 'filter-input', + 'id': 'device-filter', + 'placeholder': _('Device') + }) + ]), + E('div', { 'class': 'filter-group' }, [ + E('label', { 'class': 'filter-label' }, _('DNS Server Filter') + ':'), + E('input', { + 'type': 'text', + 'class': 'filter-input', + 'id': 'dns-server-filter', + 'placeholder': _('DNS Server') + }) + ]), + E('div', { 'class': 'filter-group', 'style': 'margin-left: auto;' }, [ + E('button', { + 'class': 'cbi-button cbi-button-action', + 'id': 'refresh-queries-btn' + }, _('Refresh')) + ]) + ]), + E('div', { 'id': 'dns-queries-container' }, [ + E('div', { 'class': 'loading-state' }, _('Loading data...')) + ]) + ]) + ]); + container.appendChild(queriesSection); + + // 状æ€å˜é‡ + var currentPage = 1; + var pageSize = 20; + var currentFilters = { + domain: '', + device: '', + is_query: '', + dns_server: '', + query_type: '' + }; + + + // 更新查询记录 + function updateQueries() { + var container = document.getElementById('dns-queries-container'); + if (!container) return Promise.resolve(); + + // æ£€æŸ¥æ˜¯å¦æœ‰çŽ°æœ‰å†…å®¹ + var hasContent = container.querySelector('.bandix-table') || container.querySelector('.loading-state') || container.querySelector('.error-state'); + + // ä¿å­˜å½“å‰å®¹å™¨é«˜åº¦ï¼Œé¿å…跳动(åªåœ¨æœ‰å†…容时) + var currentHeight = container.offsetHeight; + if (currentHeight > 0 && hasContent) { + container.style.minHeight = currentHeight + 'px'; + } + + // 显示加载状æ€ï¼Œä½†ä¿æŒå®¹å™¨ç»“构(åªåœ¨æœ‰å†…容时显示é®ç½©å±‚) + var loadingDiv = container.querySelector('.loading-overlay'); + if (hasContent) { + if (!loadingDiv) { + loadingDiv = E('div', { + 'class': 'loading-overlay', + 'style': 'position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; z-index: 10;' + }, _('Loading data...')); + container.style.position = 'relative'; + container.appendChild(loadingDiv); + // 应用主题背景色 + setTimeout(function() { + applyThemeColors(); + }, 50); + } else { + loadingDiv.style.display = 'flex'; + } + } else { + // 如果没有内容,使用简å•çš„åŠ è½½çŠ¶æ€ + container.innerHTML = ''; + container.appendChild(E('div', { 'class': 'loading-state' }, + _('Loading data...'))); + // 应用主题背景色 + setTimeout(function() { + applyThemeColors(); + }, 50); + } + + return callGetDnsQueries( + currentFilters.domain, + currentFilters.device, + currentFilters.is_query, + currentFilters.dns_server, + currentFilters.query_type, + currentPage, + pageSize + ).then(function (result) { + // éšè—æˆ–ç§»é™¤åŠ è½½çŠ¶æ€ + if (loadingDiv) { + loadingDiv.remove(); + } + + // 移除刷新蒙版 + var refreshOverlay = container.querySelector('.refresh-overlay'); + if (refreshOverlay) { + refreshOverlay.remove(); + } + + // æ¢å¤æœ€å°é«˜åº¦å’Œå®šä½ + container.style.minHeight = ''; + if (!hasContent) { + container.style.position = ''; + } + + if (!result || result.status !== 'success' || !result.data) { + container.innerHTML = ''; + container.appendChild(E('div', { 'class': 'error-state' }, + _('Unable to fetch data'))); + // 应用主题背景色 + setTimeout(function() { + applyThemeColors(); + }, 50); + return; + } + + var queries = result.data.queries || []; + var total = result.data.total || 0; + var totalPages = result.data.total_pages || 1; + + if (queries.length === 0) { + container.innerHTML = ''; + container.appendChild(E('div', { 'class': 'loading-state' }, + _('No Data'))); + // 应用主题背景色 + setTimeout(function() { + applyThemeColors(); + }, 50); + return; + } + + // 移除旧的表格ã€å¡ç‰‡å’Œåˆ†é¡µ + var oldTable = container.querySelector('.bandix-table'); + var oldCards = container.querySelector('.dns-query-cards'); + var oldPagination = container.querySelector('.pagination'); + var oldLoadingState = container.querySelector('.loading-state'); + if (oldTable) oldTable.remove(); + if (oldCards) oldCards.remove(); + if (oldPagination) oldPagination.remove(); + if (oldLoadingState) oldLoadingState.remove(); + + // ç¡®ä¿å®¹å™¨æ˜¯ç›¸å¯¹å®šä½ï¼ˆç”¨äºŽé®ç½©å±‚) + container.style.position = 'relative'; + + // 创建表格(PC端) + var table = E('table', { 'class': 'bandix-table' }, [ + E('thead', {}, [ + E('tr', {}, [ + E('th', { 'style': 'width: 180px;' }, _('Time')), + E('th', { 'style': 'width: 200px;' }, _('Domain')), + E('th', { 'style': 'width: 100px;' }, _('Query Type')), + E('th', { 'style': 'width: 100px;' }, _('Type')), + E('th', { 'style': 'width: 100px;' }, _('Response Time')), + E('th', { 'style': 'width: 200px;' }, _('Device')), + E('th', { 'style': 'width: 140px;' }, _('DNS Server')), + E('th', { 'style': 'width: 200px;' }, _('Response Result')) + ]) + ]), + E('tbody', {}, queries.map(function (query) { + return E('tr', {}, [ + E('td', {}, query.timestamp_formatted || '-'), + E('td', {}, query.domain || '-'), + E('td', {}, query.query_type || '-'), + E('td', {}, [ + E('span', { + 'class': 'query-badge ' + (query.is_query ? 'query' : 'response') + }, query.is_query ? _('Query') : _('Response')) + ]), + E('td', {}, query.response_time_ms ? query.response_time_ms + ' ' + _('ms') : '-'), + E('td', {}, formatDeviceName(query)), + E('td', {}, formatDnsServer(query)), + E('td', {}, [ + E('div', { + 'class': 'response-ips', + 'title': (function() { + var result = formatResponseResult(query); + if (result.full.length === 0) { + return ''; + } + return result.full.join('\n'); + })() + }, (function() { + var result = formatResponseResult(query); + if (result.display.length === 0) { + return [E('span', { 'class': 'response-ip-badge' }, '-')]; + } + var badges = result.display.map(function (item) { + return E('span', { 'class': 'response-ip-badge' }, item); + }); + if (result.hasMore) { + badges.push(E('span', { 'class': 'response-ip-badge', 'style': 'opacity: 0.7;' }, '...')); + } + return badges; + })()) + ]) + ]); + })) + ]); + + // 创建移动端å¡ç‰‡å®¹å™¨ + var cardsContainer = E('div', { 'class': 'dns-query-cards' }); + + // 为æ¯ä¸ªæŸ¥è¯¢åˆ›å»ºå¡ç‰‡ + queries.forEach(function (query) { + var result = formatResponseResult(query); + var responseResultBadges = []; + if (result.display.length === 0) { + responseResultBadges.push(E('span', { 'class': 'dns-query-card-response-badge' }, '-')); + } else { + result.display.forEach(function (item) { + responseResultBadges.push(E('span', { 'class': 'dns-query-card-response-badge' }, item)); + }); + if (result.hasMore) { + responseResultBadges.push(E('span', { + 'class': 'dns-query-card-response-badge', + 'style': 'opacity: 0.7;' + }, '...')); + } + } + + var card = E('div', { 'class': 'dns-query-card' }, [ + // å¡ç‰‡å¤´éƒ¨ï¼šæ—¶é—´å’Œç±»åž‹ + E('div', { 'class': 'dns-query-card-header' }, [ + E('div', { 'class': 'dns-query-card-time' }, query.timestamp_formatted || '-'), + E('span', { + 'class': 'query-badge ' + (query.is_query ? 'query' : 'response') + }, query.is_query ? _('Query') : _('Response')) + ]), + // å¡ç‰‡ä¸»ä½“ + E('div', { 'class': 'dns-query-card-body' }, [ + // 域å + E('div', { 'class': 'dns-query-card-row' }, [ + E('div', { 'class': 'dns-query-card-label' }, _('Domain')), + E('div', { 'class': 'dns-query-card-value dns-query-card-domain' }, query.domain || '-') + ]), + // 查询类型 + E('div', { 'class': 'dns-query-card-row' }, [ + E('div', { 'class': 'dns-query-card-label' }, _('Query Type')), + E('div', { 'class': 'dns-query-card-value' }, query.query_type || '-') + ]), + // å“应时间 + E('div', { 'class': 'dns-query-card-row' }, [ + E('div', { 'class': 'dns-query-card-label' }, _('Response Time')), + E('div', { 'class': 'dns-query-card-value' }, query.response_time_ms ? query.response_time_ms + ' ' + _('ms') : '-') + ]), + // 设备 + E('div', { 'class': 'dns-query-card-row' }, [ + E('div', { 'class': 'dns-query-card-label' }, _('Device')), + E('div', { 'class': 'dns-query-card-value' }, formatDeviceName(query)) + ]), + // DNSæœåС噍 + E('div', { 'class': 'dns-query-card-row' }, [ + E('div', { 'class': 'dns-query-card-label' }, _('DNS Server')), + E('div', { 'class': 'dns-query-card-value' }, formatDnsServer(query)) + ]), + // å“应结果 + E('div', { 'class': 'dns-query-card-row' }, [ + E('div', { 'class': 'dns-query-card-label' }, _('Response Result')), + E('div', { + 'class': 'dns-query-card-value', + 'title': result.full.length > 0 ? result.full.join('\n') : '' + }, [ + E('div', { 'class': 'dns-query-card-response-result' }, responseResultBadges) + ]) + ]) + ]) + ]); + + cardsContainer.appendChild(card); + }); + + var pagination = E('div', { 'class': 'pagination' }, [ + E('div', { 'class': 'pagination-info' }, + _('Page') + ' ' + currentPage + ' ' + _('of') + ' ' + totalPages + ',' + _('Total') + ' ' + total + ' ' + _('records') + ), + E('div', { 'class': 'pagination-controls' }, [ + E('select', { + 'class': 'cbi-input-select', + 'id': 'page-size-select', + 'style': 'margin-right: 8px;' + }, [ + E('option', { 'value': '10', 'selected': pageSize === 10 }, '10'), + E('option', { 'value': '20', 'selected': pageSize === 20 }, '20'), + E('option', { 'value': '50', 'selected': pageSize === 50 }, '50'), + E('option', { 'value': '100', 'selected': pageSize === 100 }, '100') + ]), + E('button', { + 'class': 'cbi-button cbi-button-action', + 'id': 'prev-page-btn', + 'disabled': currentPage <= 1 ? 'disabled' : null + }, _('Previous')), + E('button', { + 'class': 'cbi-button cbi-button-action', + 'id': 'next-page-btn', + 'disabled': currentPage >= totalPages ? 'disabled' : null + }, _('Next')) + ]) + ]); + + container.appendChild(table); + container.appendChild(cardsContainer); + container.appendChild(pagination); + + // 绑定分页事件 + var prevBtn = document.getElementById('prev-page-btn'); + var nextBtn = document.getElementById('next-page-btn'); + var pageSizeSelect = document.getElementById('page-size-select'); + + // 设置按钮的 disabled çŠ¶æ€ + if (prevBtn) { + if (currentPage <= 1) { + prevBtn.setAttribute('disabled', 'disabled'); + } else { + prevBtn.removeAttribute('disabled'); + } + prevBtn.onclick = function (e) { + e.preventDefault(); + e.stopPropagation(); + if (currentPage > 1) { + currentPage--; + updateQueries(); + } + }; + } + + if (nextBtn) { + if (currentPage >= totalPages) { + nextBtn.setAttribute('disabled', 'disabled'); + } else { + nextBtn.removeAttribute('disabled'); + } + nextBtn.onclick = function (e) { + e.preventDefault(); + e.stopPropagation(); + if (currentPage < totalPages) { + currentPage++; + updateQueries(); + } + }; + } + + if (pageSizeSelect) { + pageSizeSelect.value = pageSize.toString(); + pageSizeSelect.onchange = function (e) { + e.preventDefault(); + e.stopPropagation(); + pageSize = parseInt(this.value); + currentPage = 1; + updateQueries(); + }; + } + }).catch(function (error) { + console.error('Failed to load DNS queries:', error); + var container = document.getElementById('dns-queries-container'); + if (!container) return; + + // 移除刷新蒙版 + var refreshOverlay = container.querySelector('.refresh-overlay'); + if (refreshOverlay) { + refreshOverlay.remove(); + } + + container.innerHTML = ''; + container.appendChild(E('div', { 'class': 'error-state' }, + _('Unable to fetch data'))); + // 应用主题背景色 + setTimeout(function() { + applyThemeColors(); + }, 50); + }); + } + + // 更新统计信æ¯å¡ç‰‡ + function updateStats() { + var statsGrid = document.getElementById('dns-stats-grid'); + if (!statsGrid) return Promise.resolve(); + + return callGetDnsStats().then(function (result) { + if (!result || result.status !== 'success' || !result.data || !result.data.stats) { + statsGrid.innerHTML = ''; + return; + } + + var stats = result.data.stats; + statsGrid.innerHTML = ''; + + // æ ¼å¼åŒ–时间范围 + function formatTimeRange(start, end, durationMinutes) { + if (!start || !end) return '-'; + var startDate = new Date(start); + var endDate = new Date(end); + var startStr = startDate.toLocaleString('zh-CN', { + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + var endStr = endDate.toLocaleString('zh-CN', { + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }); + return startStr + ' - ' + endStr + ' (' + durationMinutes + ' ' + _('minutes') + ')'; + } + + // æ ¼å¼åŒ–百分比 + function formatPercent(value) { + if (typeof value !== 'number') return '-'; + return (value * 100).toFixed(2) + '%'; + } + + // 查询和å“应数é‡å¡ç‰‡ + // 使用åŽç«¯è¿”回的 total_queries å’Œ total_responses + var queryCount = stats.total_queries || 0; + var responseCount = stats.total_responses || 0; + + var totalQueriesCard = E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Query & Response')), + E('div', { 'class': 'stats-card-main-value' }, (queryCount + responseCount || 0).toLocaleString()), + E('div', { 'class': 'stats-card-details' }, [ + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, _('Queries') + ':'), + E('span', { 'class': 'stats-detail-value' }, queryCount.toLocaleString()) + ]), + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, _('Responses') + ':'), + E('span', { 'class': 'stats-detail-value' }, responseCount.toLocaleString()) + ]) + ]) + ]); + + statsGrid.appendChild(totalQueriesCard); + + // å“应时间å¡ç‰‡ + statsGrid.appendChild(E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Response Time')), + E('div', { 'class': 'stats-card-main-value' }, Math.round(stats.latest_response_time_ms || 0) + ' ' + _('ms')), + E('div', { 'class': 'stats-card-details' }, [ + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, _('Average Response Time') + ':'), + E('span', { 'class': 'stats-detail-value' }, (stats.avg_response_time_ms || 0).toFixed(2) + ' ' + _('ms')) + ]), + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, _('Min Response Time') + ':'), + E('span', { 'class': 'stats-detail-value' }, (stats.min_response_time_ms || 0) + ' ' + _('ms')) + ]), + E('div', { 'class': 'stats-detail-row' }, [ + E('span', { 'class': 'stats-detail-label' }, _('Max Response Time') + ':'), + E('span', { 'class': 'stats-detail-value' }, (stats.max_response_time_ms || 0) + ' ' + _('ms')) + ]) + ]) + ])); + + // 最常用查询类型å¡ç‰‡ + if (stats.top_query_types && stats.top_query_types.length > 0) { + var queryTypesList = stats.top_query_types.map(function(item) { + return E('div', { 'class': 'stats-list-item' }, [ + E('span', { 'class': 'stats-list-name' }, item.name || '-'), + E('span', { 'class': 'stats-list-count' }, (item.count || 0).toLocaleString()) + ]); + }); + + var queryTypesCard = E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Top Query Types')), + E('div', { 'class': 'stats-card-details' }) + ]); + + queryTypesList.forEach(function(item) { + queryTypesCard.querySelector('.stats-card-details').appendChild(item); + }); + + statsGrid.appendChild(queryTypesCard); + } + + // 最常查询域åå¡ç‰‡ + if (stats.top_domains && stats.top_domains.length > 0) { + var domainsList = stats.top_domains.map(function(item) { + return E('div', { 'class': 'stats-list-item' }, [ + E('span', { 'class': 'stats-list-name' }, item.name || '-'), + E('span', { 'class': 'stats-list-count' }, (item.count || 0).toLocaleString()) + ]); + }); + + statsGrid.appendChild(E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Top Domains')), + E('div', { 'class': 'stats-card-details' }, domainsList) + ])); + } + + // 最活跃设备å¡ç‰‡ + if (stats.top_devices && stats.top_devices.length > 0) { + var devicesList = stats.top_devices.map(function(item) { + return E('div', { 'class': 'stats-list-item' }, [ + E('span', { 'class': 'stats-list-name' }, item.name || '-'), + E('span', { 'class': 'stats-list-count' }, (item.count || 0).toLocaleString()) + ]); + }); + + statsGrid.appendChild(E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Top Devices')), + E('div', { 'class': 'stats-card-details' }, devicesList) + ])); + } + + // 最常用DNSæœåС噍å¡ç‰‡ + if (stats.top_dns_servers && stats.top_dns_servers.length > 0) { + var serversList = stats.top_dns_servers.map(function(item) { + return E('div', { 'class': 'stats-list-item' }, [ + E('span', { 'class': 'stats-list-name' }, item.name || '-'), + E('span', { 'class': 'stats-list-count' }, (item.count || 0).toLocaleString()) + ]); + }); + + statsGrid.appendChild(E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Top DNS Servers')), + E('div', { 'class': 'stats-card-details' }, serversList) + ])); + } + + // 应用主题颜色 + setTimeout(function() { + applyThemeColors(); + }, 50); + }).catch(function (error) { + console.error('Failed to load DNS stats:', error); + var statsGrid = document.getElementById('dns-stats-grid'); + if (statsGrid) { + statsGrid.innerHTML = ''; + } + }); + } + + // åˆå§‹åŒ–æ•°æ®åŠ è½½ - å»¶è¿Ÿæ‰§è¡Œç¡®ä¿ DOM 元素已添加 + setTimeout(function () { + updateStats(); + updateQueries(); + + // 轮询更新统计数æ®ï¼ˆæ¯5秒) + poll.add(function() { + return updateStats(); + }, 1); + + // 实时æœç´¢åŠŸèƒ½ï¼ˆå¸¦é˜²æŠ–ï¼‰ + var domainFilter = document.getElementById('domain-filter'); + var deviceFilter = document.getElementById('device-filter'); + var dnsServerFilter = document.getElementById('dns-server-filter'); + var typeFilter = document.getElementById('type-filter'); + var queryTypeFilter = document.getElementById('query-type-filter'); + var refreshBtn = document.getElementById('refresh-queries-btn'); + + if (domainFilter && deviceFilter && dnsServerFilter && typeFilter && queryTypeFilter) { + var searchTimer = null; + + function performSearch() { + currentFilters.domain = domainFilter.value.trim(); + currentFilters.device = deviceFilter.value.trim(); + currentFilters.dns_server = dnsServerFilter.value.trim(); + currentFilters.is_query = typeFilter.value; + currentFilters.query_type = queryTypeFilter.value; + currentPage = 1; + updateQueries(); + } + + // 防抖函数 + function debounceSearch() { + if (searchTimer) { + clearTimeout(searchTimer); + } + searchTimer = setTimeout(performSearch, 300); + } + + // 输入框实时æœç´¢ï¼ˆå¸¦é˜²æŠ–) + domainFilter.addEventListener('input', debounceSearch); + deviceFilter.addEventListener('input', debounceSearch); + dnsServerFilter.addEventListener('input', debounceSearch); + + // ä¸‹æ‹‰æ¡†ç«‹å³æœç´¢ï¼ˆä¸éœ€è¦é˜²æŠ–) + typeFilter.addEventListener('change', performSearch); + queryTypeFilter.addEventListener('change', performSearch); + + // 刷新按钮 + if (refreshBtn) { + var originalBtnText = refreshBtn.textContent || refreshBtn.innerText || _('Refresh'); + + refreshBtn.addEventListener('click', function () { + // ä¿å­˜åŽŸå§‹æŒ‰é’®æ–‡æœ¬ï¼ˆå¦‚æžœè¿˜æ²¡æœ‰ä¿å­˜ï¼‰ + if (!originalBtnText) { + originalBtnText = refreshBtn.textContent || refreshBtn.innerText || _('Refresh'); + } + + // è®¾ç½®æŒ‰é’®ä¸ºåŠ è½½çŠ¶æ€ + refreshBtn.classList.add('refresh-btn-loading'); + refreshBtn.textContent = _('Loading...'); + refreshBtn.disabled = true; + + // åŒæ—¶åˆ·æ–°ç»Ÿè®¡æ•°æ®å’ŒæŸ¥è¯¢è®°å½• + updateStats(); + + var container = document.getElementById('dns-queries-container'); + if (!container) { + updateQueries().finally(function() { + // æ¢å¤æŒ‰é’®çŠ¶æ€ + refreshBtn.classList.remove('refresh-btn-loading'); + refreshBtn.textContent = originalBtnText; + refreshBtn.disabled = false; + }); + return; + } + + // ç¡®ä¿å®¹å™¨æ˜¯ç›¸å¯¹å®šä½ + container.style.position = 'relative'; + + // 移除旧的蒙版 + var oldOverlay = container.querySelector('.refresh-overlay'); + if (oldOverlay) { + oldOverlay.remove(); + } + + // 创建新的刷新蒙版 + var overlay = E('div', { + 'class': 'refresh-overlay' + }); + container.appendChild(overlay); + + // 应用主题背景色到蒙版 + setTimeout(function() { + applyThemeColors(); + }, 50); + + // 刷新数æ®ï¼ˆè’™ç‰ˆä¼šåœ¨ updateQueries 中自动移除) + updateQueries().finally(function() { + // æ¢å¤æŒ‰é’®çŠ¶æ€ + refreshBtn.classList.remove('refresh-btn-loading'); + refreshBtn.textContent = originalBtnText; + refreshBtn.disabled = false; + }); + }); + } + } + }, 10); + + // 自动适应主题背景色和文字颜色的函数 + function applyThemeColors() { + try { + var mainElement = document.querySelector('.main') || document.body; + var computedStyle = window.getComputedStyle(mainElement); + var bgColor = computedStyle.backgroundColor; + + // 如果父元素有背景色,应用到容器和å¡ç‰‡ + if (bgColor && bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent') { + var containerEl = document.querySelector('.bandix-dns-container'); + if (containerEl) { + containerEl.style.backgroundColor = bgColor; + } + + + // 应用到表格表头 + var tableHeaders = document.querySelectorAll('.bandix-table th'); + tableHeaders.forEach(function(th) { + th.style.backgroundColor = bgColor; + }); + + // 应用到 Response Result 字段的 badge + var badges = document.querySelectorAll('.response-ip-badge'); + badges.forEach(function(badge) { + badge.style.backgroundColor = bgColor; + }); + + // 应用到æœç´¢æ¡†ï¼ˆä¸åŒ…括 cbi-input-select,因为它使用官方样å¼ï¼‰ + var inputs = document.querySelectorAll('.filter-input'); + inputs.forEach(function(input) { + input.style.backgroundColor = bgColor; + }); + + // 应用到统计å¡ç‰‡ + var statsCards = document.querySelectorAll('.stats-grid .cbi-section'); + statsCards.forEach(function(card) { + card.style.backgroundColor = bgColor; + }); + + // 应用到加载状æ€å’Œé”™è¯¯çŠ¶æ€ + var loadingStates = document.querySelectorAll('.loading-state'); + loadingStates.forEach(function(el) { + el.style.backgroundColor = bgColor; + }); + + var errorStates = document.querySelectorAll('.error-state'); + errorStates.forEach(function(el) { + el.style.backgroundColor = bgColor; + }); + + // 应用到加载é®ç½©å±‚(使用åŠé€æ˜ŽèƒŒæ™¯ï¼‰ + var loadingOverlays = document.querySelectorAll('.loading-overlay'); + loadingOverlays.forEach(function(el) { + // 将背景色转æ¢ä¸º rgbaï¼Œå¹¶æ·»åŠ é€æ˜Žåº¦ + var rgb = bgColor.match(/\d+/g); + if (rgb && rgb.length >= 3) { + el.style.backgroundColor = 'rgba(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ', 0.8)'; + } + }); + + // 应用到刷新蒙版(使用åŠé€æ˜ŽèƒŒæ™¯å’Œæ¨¡ç³Šæ•ˆæžœï¼‰ + var refreshOverlays = document.querySelectorAll('.refresh-overlay'); + refreshOverlays.forEach(function(el) { + // 将背景色转æ¢ä¸º rgbaï¼Œå¹¶æ·»åŠ é€æ˜Žåº¦ + var rgb = bgColor.match(/\d+/g); + if (rgb && rgb.length >= 3) { + el.style.backgroundColor = 'rgba(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ', 0.6)'; + } + }); + } + + // 检测文字颜色并应用 + var textColor = computedStyle.color; + if (textColor && textColor !== 'rgba(0, 0, 0, 0)') { + var containerEl = document.querySelector('.bandix-dns-container'); + if (containerEl) { + containerEl.style.color = textColor; + } + + // 应用到æœç´¢æ¡†çš„æ–‡å­—颜色(ä¸åŒ…括 cbi-input-select) + var inputs = document.querySelectorAll('.filter-input'); + inputs.forEach(function(input) { + input.style.color = textColor; + }); + } + } catch (e) { + // 如果检测失败,使用默认值 + console.log('Theme adaptation:', e); + } + } + + // åˆå§‹åº”用主题颜色 + setTimeout(applyThemeColors, 100); + + // ç›‘å¬ DOM å˜åŒ–,自动应用到新创建的元素 + if (typeof MutationObserver !== 'undefined') { + var observer = new MutationObserver(function(mutations) { + applyThemeColors(); + }); + + setTimeout(function() { + var container = document.querySelector('.bandix-dns-container'); + if (container) { + observer.observe(container, { + childList: true, + subtree: true + }); + } + }, 200); + } + + return container; + } +}); + diff --git a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/index.js b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/index.js new file mode 100644 index 00000000..251b0855 --- /dev/null +++ b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/index.js @@ -0,0 +1,8053 @@ +'use strict'; +'require view'; +'require ui'; +'require uci'; +'require rpc'; +'require poll'; + +// 颜色常é‡å®šä¹‰ +var BANDIX_COLOR_UPLOAD = '#f97316'; // 橙色 - 上传/上行 +var BANDIX_COLOR_DOWNLOAD = '#06b6d4'; // é’色 - 下载/下行 + +// 悬浮框背景色定义 +var BANDIX_TOOLTIP_BG_OPENWRT2020_LIGHT = '#ffffff'; // OpenWrt 2020 浅色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_OPENWRT2020_DARK = '#2a2a2a'; // OpenWrt 2020 深色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_MATERIAL_LIGHT = '#ffffff'; // Material 浅色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_MATERIAL_DARK = '#303030'; // Material 深色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_BOOTSTRAP_LIGHT = '#ffffff'; // Bootstrap 浅色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_BOOTSTRAP_DARK = '#303030'; // Bootstrap 深色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_ARGON_LIGHT = '#ffffff'; // Argon 浅色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_ARGON_DARK = '#252526'; // Argon 深色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_AURORA_LIGHT = '#ffffff'; // Aurora 浅色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_AURORA_DARK = '#0E172B'; // Aurora 深色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_KUCAT_LIGHT = '#ffffff'; // Kucat 浅色主题悬浮框背景 +var BANDIX_TOOLTIP_BG_KUCAT_DARK = '#222D3C'; // Kucat 深色主题悬浮框背景 + +// Modal 背景色定义 +var BANDIX_MODAL_BG_OPENWRT2020_LIGHT = '#ffffff'; // OpenWrt 2020 浅色主题 Modal 背景 +var BANDIX_MODAL_BG_OPENWRT2020_DARK = '#2a2a2a'; // OpenWrt 2020 深色主题 Modal 背景 +var BANDIX_MODAL_BG_MATERIAL_LIGHT = '#ffffff'; // Material 浅色主题 Modal 背景 +var BANDIX_MODAL_BG_MATERIAL_DARK = '#303030'; // Material 深色主题 Modal 背景 +var BANDIX_MODAL_BG_BOOTSTRAP_LIGHT = '#ffffff'; // Bootstrap 浅色主题 Modal 背景 +var BANDIX_MODAL_BG_BOOTSTRAP_DARK = '#303030'; // Bootstrap 深色主题 Modal 背景 +var BANDIX_MODAL_BG_ARGON_LIGHT = '#F4F5F7'; // Argon 浅色主题 Modal 背景 +var BANDIX_MODAL_BG_ARGON_DARK = '#252526'; // Argon 深色主题 Modal 背景 +var BANDIX_MODAL_BG_AURORA_LIGHT = '#ffffff'; // Aurora 浅色主题 Modal 背景 +var BANDIX_MODAL_BG_AURORA_DARK = '#0E172B'; // Aurora 深色主题 Modal 背景 +var BANDIX_MODAL_BG_KUCAT_LIGHT = '#222D3C'; // Kucat 浅色主题 Modal 背景 +var BANDIX_MODAL_BG_KUCAT_DARK = '#222D3C'; // Kucat 深色主题 Modal 背景 + +// 兼容性定义(å‘åŽå…¼å®¹ï¼‰ +var BANDIX_TOOLTIP_BG_LIGHT = '#ffffff'; // æµ…è‰²æ¨¡å¼æ‚¬æµ®çª—背景色 +var BANDIX_TOOLTIP_BG_DARK = '#333333'; // æ·±è‰²æ¨¡å¼æ‚¬æµ®çª—背景色 + +function getThemeMode() { + // 使用 uci 获å–主题 + var theme = L.uci.get('luci', 'main', 'mediaurlbase'); + + // æ ¹æ®ä¸»é¢˜åˆ¤æ–­ + if (theme === '/luci-static/openwrt2020' || + theme === '/luci-static/material' || + theme === '/luci-static/bootstrap-light') { + return 'light'; + } + + if (theme === '/luci-static/bootstrap-dark') { + return 'dark'; + } + + if (theme === '/luci-static/argon') { + // èŽ·å– argon çš„å…·ä½“æ¨¡å¼ + var argonMode = L.uci.get('argon', '@global[0]', 'mode'); + if (argonMode === 'light') { + return 'light'; + } + if (argonMode === 'dark') { + return 'dark'; + } + // 如果是其他值(包括auto),使用æµè§ˆå™¨åª’体查询 + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + } + + if (theme === '/luci-static/bootstrap' || theme === '/luci-static/aurora') { + // èŽ·å– html 标签上的 data-darkmode 属性 + var htmlElement = document.documentElement; + var darkMode = htmlElement.getAttribute('data-darkmode'); + return darkMode === 'true' ? 'dark' : 'light'; + } + + if (theme === '/luci-static/kucat') { + // èŽ·å– kucat çš„å…·ä½“æ¨¡å¼ + var kucatMode = L.uci.get('kucat', '@basic[0]', 'mode'); + if (kucatMode === 'light') { + return 'light'; + } + if (kucatMode === 'dark') { + return 'dark'; + } + // 如果是其他值(包括auto),使用æµè§ˆå™¨åª’体查询 + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + } + + // 其他主题使用æµè§ˆå™¨åª’体查询 + var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; +} + +function getThemeColors() { + // 获å–当å‰ä¸»é¢˜å’Œæ¨¡å¼ + var theme = L.uci.get('luci', 'main', 'mediaurlbase'); + var mode = getThemeMode(); + + // æ ¹æ®ä¸»é¢˜å’Œæ¨¡å¼è¿”回对应的颜色 + if (theme === '/luci-static/openwrt2020') { + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_OPENWRT2020_DARK : BANDIX_TOOLTIP_BG_OPENWRT2020_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_OPENWRT2020_DARK : BANDIX_MODAL_BG_OPENWRT2020_LIGHT + }; + } + + if (theme === '/luci-static/material') { + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_MATERIAL_DARK : BANDIX_TOOLTIP_BG_MATERIAL_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_MATERIAL_DARK : BANDIX_MODAL_BG_MATERIAL_LIGHT + }; + } + + if (theme === '/luci-static/bootstrap-light' || theme === '/luci-static/bootstrap') { + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_BOOTSTRAP_DARK : BANDIX_TOOLTIP_BG_BOOTSTRAP_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_BOOTSTRAP_DARK : BANDIX_MODAL_BG_BOOTSTRAP_LIGHT + }; + } + + if (theme === '/luci-static/bootstrap-dark') { + return { + tooltipBg: BANDIX_TOOLTIP_BG_BOOTSTRAP_DARK, + modalBg: BANDIX_MODAL_BG_BOOTSTRAP_DARK + }; + } + + if (theme === '/luci-static/argon') { + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_ARGON_DARK : BANDIX_TOOLTIP_BG_ARGON_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_ARGON_DARK : BANDIX_MODAL_BG_ARGON_LIGHT + }; + } + + if (theme === '/luci-static/aurora') { + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_AURORA_DARK : BANDIX_TOOLTIP_BG_AURORA_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_AURORA_DARK : BANDIX_MODAL_BG_AURORA_LIGHT + }; + } + + if (theme === '/luci-static/kucat') { + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_KUCAT_DARK : BANDIX_TOOLTIP_BG_KUCAT_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_KUCAT_DARK : BANDIX_MODAL_BG_KUCAT_LIGHT + }; + } + + // 默认使用 OpenWrt 2020 的颜色 + return { + tooltipBg: mode === 'dark' ? BANDIX_TOOLTIP_BG_OPENWRT2020_DARK : BANDIX_TOOLTIP_BG_OPENWRT2020_LIGHT, + modalBg: mode === 'dark' ? BANDIX_MODAL_BG_OPENWRT2020_DARK : BANDIX_MODAL_BG_OPENWRT2020_LIGHT + }; +} + +function getThemeType() { + var mediaUrlBase = L.uci.get('luci', 'main', 'mediaurlbase'); + + if (!mediaUrlBase) { + var linkTags = document.querySelectorAll('link[rel="stylesheet"]'); + for (var i = 0; i < linkTags.length; i++) { + var href = linkTags[i].getAttribute('href') || ''; + if (href.toLowerCase().includes('argon')) { + return 'wide'; + } + } + return 'narrow'; + } + + var mediaUrlBaseLower = mediaUrlBase.toLowerCase(); + + var wideThemeKeywords = ['argon', 'material', 'design', 'edge']; + + for (var i = 0; i < wideThemeKeywords.length; i++) { + if (mediaUrlBaseLower.includes(wideThemeKeywords[i])) { + return 'wide'; + } + } + + return 'narrow'; +} + +function formatSize(bytes) { + if (bytes === 0) return '0 B'; + const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; + const i = Math.floor(Math.log(bytes) / Math.log(1024)); + return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + ' ' + units[i]; +} + +function formatByterate(bytes_per_sec, unit) { + if (bytes_per_sec === 0) { + return unit === 'bits' ? '0 bps' : '0 B/s'; + } + + if (unit === 'bits') { + // 转æ¢ä¸ºæ¯”特å•ä½ + const bits_per_sec = bytes_per_sec * 8; + const units = ['bps', 'Kbps', 'Mbps', 'Gbps', 'Tbps']; + const i = Math.floor(Math.log(bits_per_sec) / Math.log(1000)); + return parseFloat((bits_per_sec / Math.pow(1000, i)).toFixed(2)) + ' ' + units[i]; + } else { + // 默认字节å•ä½ + const units = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s']; + const i = Math.floor(Math.log(bytes_per_sec) / Math.log(1024)); + return parseFloat((bytes_per_sec / Math.pow(1024, i)).toFixed(2)) + ' ' + units[i]; + } +} + +function getConnectionTypeIcon(connectionType) { + if (!connectionType) return null; + + var iconSize = 14; + + if (connectionType === 'wifi') { + var wifiIcon = E('img', { + 'src': 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXdpZmktaWNvbiBsdWNpZGUtd2lmaSI+PHBhdGggZD0iTTEyIDIwaC4wMSIvPjxwYXRoIGQ9Ik0yIDguODJhMTUgMTUgMCAwIDEgMjAgMCIvPjxwYXRoIGQ9Ik01IDEyLjg1OWExMCAxMCAwIDAgMSAxNCAwIi8+PHBhdGggZD0iTTguNSAxNi40MjlhNSA1IDAgMCAxIDcgMCIvPjwvc3ZnPg==', + 'width': iconSize, + 'height': iconSize, + 'alt': 'WiFi', + 'style': 'vertical-align: middle; display: inline-block; opacity: 0.8;' + }); + return wifiIcon; + } else if (connectionType === 'router') { + var routerIcon = E('img', { + 'src': 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXJvdXRlci1pY29uIGx1Y2lkZS1yb3V0ZXIiPjxyZWN0IHdpZHRoPSIyMCIgaGVpZ2h0PSI4IiB4PSIyIiB5PSIxNCIgcng9IjIiLz48cGF0aCBkPSJNNi4wMSAxOEg2Ii8+PHBhdGggZD0iTTEwLjAxIDE4SDEwIi8+PHBhdGggZD0iTTE1IDEwdjQiLz48cGF0aCBkPSJNMTcuODQgNy4xN2E0IDQgMCAwIDAtNS42NiAwIi8+PHBhdGggZD0iTTIwLjY2IDQuMzRhOCA4IDAgMCAwLTExLjMxIDAiLz48L3N2Zz4=', + 'width': iconSize, + 'height': iconSize, + 'alt': 'Router', + 'style': 'vertical-align: middle; display: inline-block; opacity: 0.8;' + }); + return routerIcon; + } else { + var ethernetIcon = E('img', { + 'src': 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLWV0aGVybmV0LXBvcnQtaWNvbiBsdWNpZGUtZXRoZXJuZXQtcG9ydCI+PHBhdGggZD0ibTE1IDIwIDMtM2gyYTIgMiAwIDAgMCAyLTJWNmEyIDIgMCAwIDAtMi0ySDRhMiAyIDAgMCAwLTIgMnY5YTIgMiAwIDAgMCAyIDJoMmwzIDN6Ii8+PHBhdGggZD0iTTYgOHYxIi8+PHBhdGggZD0iTTEwIDh2MSIvPjxwYXRoIGQ9Ik0xNCA4djEiLz48cGF0aCBkPSJNMTggOHYxIi8+PC9zdmc+', + 'width': iconSize, + 'height': iconSize, + 'alt': 'Ethernet', + 'style': 'vertical-align: middle; display: inline-block; opacity: 0.8;' + }); + return ethernetIcon; + } +} + +// è§£æžé€Ÿåº¦å­—符串为字节/ç§’ +function parseSpeed(speedStr) { + if (!speedStr || speedStr === '0' || speedStr === '0 B/s' || speedStr === '0 bps') return 0; + + // 匹é…字节å•ä½ + const bytesMatch = speedStr.match(/^([\d.]+)\s*([KMGT]?B\/s)$/i); + if (bytesMatch) { + const value = parseFloat(bytesMatch[1]); + const unit = bytesMatch[2].toUpperCase(); + + const bytesMultipliers = { + 'B/S': 1, + 'KB/S': 1024, + 'MB/S': 1024 * 1024, + 'GB/S': 1024 * 1024 * 1024, + 'TB/S': 1024 * 1024 * 1024 * 1024 + }; + + return value * (bytesMultipliers[unit] || 1); + } + + // åŒ¹é…æ¯”特å•ä½ + const bitsMatch = speedStr.match(/^([\d.]+)\s*([KMGT]?bps)$/i); + if (bitsMatch) { + const value = parseFloat(bitsMatch[1]); + const unit = bitsMatch[2].toLowerCase(); + + const bitsMultipliers = { + 'bps': 1, + 'kbps': 1000, + 'mbps': 1000 * 1000, + 'gbps': 1000 * 1000 * 1000, + 'tbps': 1000 * 1000 * 1000 * 1000 + }; + + // 转æ¢ä¸ºå­—节/ç§’ + return (value * (bitsMultipliers[unit] || 1)) / 8; + } + + return 0; +} + +// 过滤 LAN IPv6 地å€ï¼ˆæŽ’除本地链路地å€ï¼‰ +function filterLanIPv6(ipv6Addresses) { + if (!ipv6Addresses || !Array.isArray(ipv6Addresses)) return []; + + const lanPrefixes = [ + 'fd', // ULA + 'fc' // ULA + ]; + + const lanAddresses = ipv6Addresses.filter(addr => { + const lowerAddr = addr.toLowerCase(); + return lanPrefixes.some(prefix => lowerAddr.startsWith(prefix)); + }); + + // 最多返回 2 个 LAN IPv6 åœ°å€ + return lanAddresses.slice(0, 2); +} + +function getTimeRangeForPeriod(period) { + if (period === 'all') { + return { start_ms: null, end_ms: null }; + } + + var now = new Date(); + var startDate; + var endDate; + + switch (period) { + case 'today': + startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0); + endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999); + break; + case 'week': + var day = now.getDay(); + var diff = day === 0 ? 6 : day - 1; + startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() - diff, 0, 0, 0, 0); + endDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + 6, 23, 59, 59, 999); + break; + case 'month': + startDate = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0, 0); + endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999); + break; + case 'year': + startDate = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0); + endDate = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999); + break; + default: + return { start_ms: null, end_ms: null }; + } + + return { + start_ms: startDate.getTime(), + end_ms: endDate.getTime() + }; +} + +var callStatus = rpc.declare({ + object: 'luci.bandix', + method: 'getStatus', + params: ['start_ms', 'end_ms'], + expect: {} +}); + +var callSetHostname = rpc.declare({ + object: 'luci.bandix', + method: 'setHostname', + params: ['mac', 'hostname'], + expect: { success: true } +}); + +// åŽ†å²æŒ‡æ ‡ RPC +var callGetMetrics = rpc.declare({ + object: 'luci.bandix', + method: 'getMetrics', + params: ['mac'], + expect: {} +}); + +// 定时é™é€Ÿ RPC +var callGetScheduleLimits = rpc.declare({ + object: 'luci.bandix', + method: 'getScheduleLimits', + expect: {} +}); + +var callSetScheduleLimit = rpc.declare({ + object: 'luci.bandix', + method: 'setScheduleLimit', + params: ['mac', 'start_time', 'end_time', 'days', 'wan_tx_rate_limit', 'wan_rx_rate_limit'], + expect: { success: true } +}); + +var callUpdateScheduleLimit = rpc.declare({ + object: 'luci.bandix', + method: 'updateScheduleLimit', + params: ['id', 'mac', 'start_time', 'end_time', 'days', 'wan_rx_rate_limit', 'wan_tx_rate_limit'], + expect: { success: true } +}); + +var callDeleteScheduleLimit = rpc.declare({ + object: 'luci.bandix', + method: 'deleteScheduleLimit', + params: ['id'], + expect: { success: true } +}); + +// 版本和更新检查 RPC +var callGetVersion = rpc.declare({ + object: 'luci.bandix', + method: 'getVersion', + expect: {} +}); + +var callCheckUpdate = rpc.declare({ + object: 'luci.bandix', + method: 'checkUpdate', + expect: {} +}); + +// æµé‡ç»Ÿè®¡ RPC +// Ranking 接å£å‚数: +// - start_ms: u64, å¯é€‰, 默认值: 365å¤©å‰ +// - end_ms: u64, å¯é€‰, 默认值: 当剿—¶é—´ +var callGetTrafficUsageRanking = rpc.declare({ + object: 'luci.bandix', + method: 'getTrafficUsageRanking', + params: ['start_ms', 'end_ms', 'network_type'] +}); + +// Increments 接å£å‚数: +// - start_ms: u64, å¯é€‰, 默认值: 365å¤©å‰ +// - end_ms: u64, å¯é€‰, 默认值: 当剿—¶é—´ +// - aggregation: String, å¯é€‰, 默认值: "hourly" (å¯é€‰å€¼: "hourly" 或 "daily") +// - mac: String, å¯é€‰, 默认值: "all" (MAC åœ°å€æˆ– "all" 查询所有设备) +var callGetTrafficUsageIncrements = rpc.declare({ + object: 'luci.bandix', + method: 'getTrafficUsageIncrements', + params: ['start_ms', 'end_ms', 'aggregation', 'mac', 'network_type'] +}); + +// é™é€Ÿç™½åå• RPC +var callGetRateLimitWhitelist = rpc.declare({ + object: 'luci.bandix', + method: 'getRateLimitWhitelist', + expect: {} +}); + +var callSetRateLimitWhitelistEnabled = rpc.declare({ + object: 'luci.bandix', + method: 'setRateLimitWhitelistEnabled', + params: ['enabled'], + expect: {} +}); + +var callAddRateLimitWhitelist = rpc.declare({ + object: 'luci.bandix', + method: 'addRateLimitWhitelist', + params: ['mac'], + expect: {} +}); + +var callDeleteRateLimitWhitelist = rpc.declare({ + object: 'luci.bandix', + method: 'deleteRateLimitWhitelist', + params: ['mac'], + expect: {} +}); + +var callDeleteDevice = rpc.declare({ + object: 'luci.bandix', + method: 'deleteDevice', + params: ['mac'], + expect: {} +}); + +var callSetDefaultRateLimit = rpc.declare({ + object: 'luci.bandix', + method: 'setDefaultRateLimit', + params: ['wan_rx_rate_limit', 'wan_tx_rate_limit'], + expect: {} +}); + +return view.extend({ + load: function () { + return Promise.all([ + uci.load('bandix'), + uci.load('luci'), + uci.load('argon').catch(function () { + // argon é…ç½®å¯èƒ½ä¸å­˜åœ¨ï¼Œå¿½ç•¥é”™è¯¯ + return null; + }) + ]); + }, + + render: function (data) { + + // ç”Ÿæˆæ ·å¼å­—符串的函数 + function generateStyles(colorScheme) { + var scheme = colorScheme || 'light'; + var themeColors = getThemeColors(); + var tooltipTextColor = scheme === 'dark' ? '#f9fafb' : '#1f2937'; + var tooltipDividerColor = scheme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'currentColor'; + var tooltipDividerOpacity = 1; + var css = ` + .bandix-container { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + } + + .bandix-header { + display: flex; + align-items: center; + justify-content: space-between; + } + + .bandix-title { + font-size: 1.5rem; + font-weight: 600; + margin: 0; + } + + .bandix-header-right { + display: flex; + align-items: center; + gap: 12px; + } + + .bandix-title-wrapper { + display: flex; + align-items: center; + gap: 12px; + } + + .bandix-version { + font-size: 0.875rem; + opacity: 0.5; + font-weight: 400; + } + + .bandix-version-wrapper { + display: inline-flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + } + + .bandix-version-item { + display: inline-flex; + align-items: center; + gap: 4px; + } + + .bandix-update-badge { + display: inline-block; + cursor: pointer; + padding: 2px 8px; + margin-left: 8px; + background-color: rgba(239, 68, 68, 0.1); + color: #ef4444; + border-radius: 4px; + font-size: 0.75rem; + font-weight: 600; + transition: all 0.2s ease; + } + + .bandix-update-badge:hover { + background-color: rgba(239, 68, 68, 0.2); + transform: translateY(-1px); + } + + + /* 移动端éšè—版本信æ¯å’Œæ›´æ–°å¾½ç«  */ + @media (max-width: 768px) { + .bandix-version-wrapper { + display: none; + } + } + + .device-mode-group { + display: inline-flex; + align-items: center; + gap: 12px; + } + + .device-toolbar { + display: inline-flex; + align-items: center; + justify-content: flex-end; + gap: 16px; + flex-wrap: wrap; + } + + .device-toolbar .device-group { + display: inline-flex; + align-items: center; + gap: 10px; + padding-left: 12px; + border-left: 1px solid rgba(107, 114, 128, 0.35); + } + + .device-toolbar .device-group:first-child { + padding-left: 0; + border-left: none; + } + + .device-toolbar .device-group-label { + font-size: 0.75rem; + opacity: 0.7; + white-space: nowrap; + } + + .device-toolbar .cbi-input-select { + height: auto; + font-size: 0.875rem; + } + + .device-mode-group .device-mode-item { + display: inline-flex; + align-items: center; + gap: 6px; + } + + .device-mode-group .cbi-input-radio { + margin: 0; + } + + .device-mode-group .device-mode-item label { + margin: 0; + } + + .bandix-badge { + border-radius: 4px; + padding: 4px 10px; + font-size: 0.875rem; + } + + #history-retention { + border: 1px solid rgba(107, 114, 128, 0.4); + } + + .bandix-alert { + border-radius: 4px; + padding: 10px 12px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + font-size: 0.875rem; + } + + .bandix-alert.wide-theme { + background-color: rgba(251, 191, 36, 0.1); + border: 1px solid rgba(251, 191, 36, 0.3); + color: #92400e; + } + + .theme-dark .bandix-alert.wide-theme { + background-color: rgba(251, 191, 36, 0.15); + border-color: rgba(251, 191, 36, 0.4); + color: #fbbf24; + } + + .bandix-alert-icon { + font-size: 0.875rem; + font-weight: 700; + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + flex-shrink: 0; + } + + + .bandix-table { + width: 100%; + table-layout: fixed; + } + + .bandix-table th { + padding: 10px 16px; + text-align: left; + font-weight: 600; + border: none; + font-size: 0.875rem; + cursor: pointer; + user-select: none; + position: relative; + transition: background-color 0.15s ease; + } + + .bandix-table th:hover { + opacity: 0.7; + } + + .bandix-table th.sortable::after { + content: '⇅'; + margin-left: 6px; + opacity: 0.3; + font-size: 0.75rem; + } + + .bandix-table th.sortable.active::after { + opacity: 1; + color: #3b82f6; + } + + .bandix-table th.sortable.asc::after { + content: '↑'; + } + + .bandix-table th.sortable.desc::after { + content: '↓'; + } + + .th-split-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + } + + .th-split-section { + display: flex; + align-items: center; + gap: 4px; + cursor: pointer; + padding: 2px 6px; + border-radius: 4px; + transition: background-color 0.2s ease; + } + + .th-split-section:hover { + opacity: 0.7; + } + + .th-split-section.active { + opacity: 0.7; + } + + .th-split-icon { + font-size: 0.7rem; + opacity: 0.5; + } + + .th-split-section.active .th-split-icon { + opacity: 1; + color: #3b82f6; + } + + .th-split-divider { + width: 1px; + height: 16px; + background-color: currentColor; + opacity: 0.5; + } + + .bandix-table td { + padding: 12px 16px; + border: none; + vertical-align: middle; + word-wrap: break-word; + overflow-wrap: break-word; + } + + .bandix-table th:nth-child(1), + .bandix-table td:nth-child(1) { + width: 27%; + } + + .bandix-table th:nth-child(2), + .bandix-table td:nth-child(2) { + width: 22%; + } + + .bandix-table th:nth-child(3), + .bandix-table td:nth-child(3) { + width: 22%; + } + + .bandix-table th:nth-child(4), + .bandix-table td:nth-child(4) { + width: 12.5%; + } + + .bandix-table th:nth-child(5), + .bandix-table td:nth-child(5) { + width: 16.5%; + } + + .device-actions { + display: flex; + gap: 6px; + } + + .device-actions .cbi-button { + min-width: 32px; + min-height: 32px; + padding: 6px; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + } + .schedule-rules-info { + display: flex; + flex-direction: column; + gap: 2px; + } + + /* 类型è”动的高亮与弱化 */ + + + .device-info { + display: flex; + flex-direction: column; + gap: 2px; + } + + .device-name { + font-weight: 600; + display: flex; + align-items: center; + gap: 8px; + } + + .device-connection-type { + font-size: 0.75rem; + opacity: 1.0; + cursor: help; + display: inline-flex; + align-items: center; + margin-right: 4px; + } + + .device-connection-type img { + opacity: 0.8; + } + + .theme-dark .device-connection-type img { + filter: invert(1); + } + + .device-status { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; + } + + .device-status.online { + background-color: #10b981; + } + + .device-status.offline { + background-color: #9ca3af; + } + + .device-ip { + opacity: 0.7; + font-size: 0.875rem; + } + + .device-uplink-badges { + display: inline-flex; + flex-wrap: wrap; + gap: 4px; + align-items: center; + margin-left: 6px; + vertical-align: middle; + } + + .device-uplink-badge, + .device-ch-badge { + display: inline-block; + padding: 2px 6px; + border-radius: 4px; + font-size: 0.7rem; + font-weight: 600; + line-height: 1.2; + } + + .device-uplink-badge { + background: rgba(107, 114, 128, 0.2); + color: #4b5563; + } + + .theme-dark .device-uplink-badge { + background: rgba(156, 163, 175, 0.25); + color: #9ca3af; + } + + .device-ch-badge.device-ch-g24 { + background: rgba(245, 158, 11, 0.2); + color: #b45309; + } + + .theme-dark .device-ch-badge.device-ch-g24 { + background: rgba(251, 191, 36, 0.2); + color: #fbbf24; + } + + .device-ch-badge.device-ch-g5 { + background: rgba(59, 130, 246, 0.2); + color: #2563eb; + } + + .theme-dark .device-ch-badge.device-ch-g5 { + background: rgba(96, 165, 250, 0.2); + color: #60a5fa; + } + + .device-ch-badge.device-ch-g6 { + background: rgba(139, 92, 246, 0.2); + color: #6d28d9; + } + + .theme-dark .device-ch-badge.device-ch-g6 { + background: rgba(167, 139, 250, 0.2); + color: #a78bfa; + } + + .device-uplink-badges-wrap { + display: flex; + flex-wrap: wrap; + gap: 4px; + align-items: center; + } + + .device-ipv6 { + opacity: 0.7; + font-size: 0.75rem; + font-family: monospace; + } + + .device-mac { + opacity: 0.6; + font-size: 0.75rem; + } + + .device-last-online { + font-size: 0.75rem; + color: #6b7280; + } + + .device-last-online-value { + color: #9ca3af; + } + + .device-last-online-exact { + display: none; + color: #9ca3af; + } + + /* 悬浮在整个设备信æ¯åŒºåŸŸæ—¶æ˜¾ç¤ºç²¾ç¡®æ—¶é—´ */ + .device-info:hover .device-last-online-value { + display: none; + } + + .device-info:hover .device-last-online-exact { + display: inline; + } + + .traffic-info { + display: flex; + flex-direction: column; + gap: 4px; + } + + .traffic-row { + display: flex; + align-items: center; + gap: 4px; + } + + .traffic-icon { + font-size: 0.75rem; + font-weight: bold; + } + + .traffic-icon.upload { + color: ${BANDIX_COLOR_UPLOAD}; + } + + .traffic-icon.download { + color: ${BANDIX_COLOR_DOWNLOAD}; + } + + .traffic-speed { + font-weight: 600; + font-size: 0.875rem; + } + + .traffic-total { + font-size: 0.75rem; + opacity: 0.6; + margin-left: 4px; + } + + + + .error { + text-align: center; + padding: 40px; + } + + .stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 16px; + margin-bottom: 0; + margin-top: 0; + } + + + .bandix-container > .cbi-section:last-of-type { + margin-bottom: 0; + } + + .stats-card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; + } + + .stats-card-title { + font-size: 0.875rem; + font-weight: 600; + opacity: 0.7; + margin: 0 0 12px 0; + text-transform: uppercase; + letter-spacing: 0.025em; + } + + .stats-grid .cbi-section { + padding: 16px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease; + margin: 0 0 0 0 !important; + } + + + .stats-card-icon { + font-size: 0.875rem; + font-weight: 600; + padding: 4px 8px; + border-radius: 4px; + background-color: currentColor; + opacity: 0.1; + } + + .stats-card-main-value { + font-size: 2.25rem; + font-weight: 700; + margin: 0 0 8px 0; + line-height: 1; + } + + .stats-card-sub-value { + font-size: 0.875rem; + opacity: 0.7; + margin: 0; + } + + .stats-card-details { + margin-top: 16px; + display: flex; + flex-direction: column; + gap: 8px; + } + + .stats-detail-row { + display: flex; + align-items: center; + gap: 8px; + font-size: 0.875rem; + } + + .stats-detail-label { + opacity: 0.7; + font-weight: 500; + } + + .stats-detail-value { + font-weight: 600; + } + + + /* æ¨¡æ€æ¡†æ ·å¼ */ + .bandix-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + visibility: hidden; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + } + + #confirm-dialog-bandix-modal { + z-index: 1105; + } + + .bandix-modal-overlay.show { + background-color: rgba(0, 0, 0, 0.5); + opacity: 1; + visibility: visible; + } + + /* 通用 modal 尺寸设置 */ + .modal-content { + max-width: 500px; + width: 90%; + max-height: 90vh; + overflow-y: auto; + } + + .bandix-modal { + opacity: 0; + transition: opacity 0.2s ease; + background-color: ${themeColors.modalBg} !important; + border-radius: 8px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); + } + + .bandix-modal-overlay.show .bandix-modal { + opacity: 1; + } + + .bandix-modal { + background-color: ${themeColors.modalBg}; + border-radius: 8px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); + } + + .bandix-modal-header { + padding: 20px; + } + + .bandix-modal-title { + font-size: 1.25rem; + font-weight: 600; + margin: 0; + } + + .bandix-modal-body { + padding: 20px; + } + + .bandix-modal-footer { + padding: 16px 20px 20px 20px; + display: flex; + gap: 10px; + justify-content: flex-end; + } + + /* 白åå•å¼¹çª—æ ·å¼ */ + .whitelist-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0); + display: flex; + align-items: center; + justify-content: center; + z-index: 1002; + opacity: 0; + visibility: hidden; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + } + + .whitelist-modal-overlay.show { + background-color: rgba(0, 0, 0, 0.5); + opacity: 1; + visibility: visible; + } + + .whitelist-modal { + max-width: 560px; + width: 92%; + max-height: 90vh; + overflow-y: auto; + opacity: 0; + transition: opacity 0.2s ease; + } + + .whitelist-modal-overlay.show .whitelist-modal { + opacity: 1; + } + + + .whitelist-modal-header { + padding: 16px 20px 0 20px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + } + + .whitelist-modal-title { + font-size: 1.1rem; + font-weight: 600; + margin: 0; + } + + .whitelist-modal-body { + padding: 16px 20px; + } + + .whitelist-modal-footer { + padding: 0 20px 18px 20px; + display: flex; + gap: 10px; + justify-content: flex-end; + } + + .whitelist-modal-row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-bottom: 12px; + } + + .whitelist-modal-list { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 8px; + } + + .whitelist-modal-item { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 10px; + padding: 8px 10px; + border-radius: 8px; + } + + + .whitelist-modal-mac { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-size: 0.875rem; + } + + .whitelist-modal-hint { + font-size: 0.75rem; + opacity: 0.7; + margin-top: 6px; + } + + .whitelist-modal-error { + font-size: 0.8125rem; + color: #ef4444; + margin-top: 10px; + display: none; + } + + .form-group { + margin-bottom: 20px; + } + + .form-label { + display: block; + font-weight: 600; + margin-bottom: 8px; + font-size: 0.875rem; + } + + .form-input { + width: 100%; + border-radius: 4px; + padding: 8px 12px; + font-size: 0.875rem; + transition: border-color 0.15s ease; + box-sizing: border-box; + } + + .form-input:focus { + outline: none; + } + + + .schedule-time-row { + display: flex; + gap: 12px; + align-items: center; + margin-bottom: 16px; + } + + .schedule-time-input { + flex: 1; + border-radius: 4px; + padding: 8px 12px; + font-size: 0.875rem; + transition: border-color 0.15s ease; + box-sizing: border-box; + } + + .schedule-days { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin-bottom: 16px; + } + + .schedule-day-btn { + flex: 1; + min-width: 40px; + padding: 6px 8px; + border-radius: 4px; + border: 1px solid rgba(0, 0, 0, 0.2); + background: transparent; + cursor: pointer; + font-size: 0.75rem; + transition: all 0.15s ease; + text-align: center; + } + + + .schedule-day-btn:hover { + background-color: rgba(0, 0, 0, 0.05); + } + + + .schedule-day-btn.active { + background-color: #3b82f6; + color: white; + border-color: #3b82f6; + } + + .schedule-rules-list { + min-height: 200px; + max-height: 400px; + overflow-y: auto; + border-radius: 4px; + padding: 16px; + } + + + .schedule-rules-empty { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 200px; + text-align: center; + font-size: 0.875rem; + } + + + .schedule-rule-item { + padding: 12px; + border: 1px solid; + border-radius: 4px; + margin-bottom: 8px; + display: flex; + justify-content: space-between; + align-items: center; + } + + + .schedule-rule-info { + flex: 1; + } + + .schedule-rule-time { + font-weight: 600; + margin-bottom: 4px; + } + + .schedule-rule-days { + font-size: 0.75rem; + opacity: 0.7; + margin-bottom: 4px; + } + + .schedule-rule-limits { + font-size: 0.75rem; + opacity: 0.7; + } + + .schedule-rule-delete { + padding: 6px 12px; + font-size: 0.75rem; + cursor: pointer; + border-radius: 4px; + border: 1px solid rgba(239, 68, 68, 0.3); + background-color: rgba(239, 68, 68, 0.1); + color: #ef4444; + transition: all 0.15s ease; + } + + .schedule-rule-delete:hover { + background-color: rgba(239, 68, 68, 0.2); + } + + .schedule-rule-actions { + display: flex; + gap: 8px; + flex-shrink: 0; + } + + .schedule-rule-edit { + padding: 6px 12px; + font-size: 0.75rem; + cursor: pointer; + border-radius: 4px; + border: 1px solid rgba(59, 130, 246, 0.3); + background-color: rgba(59, 130, 246, 0.1); + color: #3b82f6; + transition: all 0.15s ease; + } + + .schedule-rule-edit:hover { + background-color: rgba(59, 130, 246, 0.2); + } + + .device-summary { + border-radius: 4px; + padding: 12px; + margin-bottom: 16px; + } + + .device-summary-name { + font-weight: 600; + margin-bottom: 4px; + } + + .device-summary-details { + opacity: 0.7; + font-size: 0.875rem; + } + + .device-summary-badges { + margin-top: 8px; + } + + /* 加载动画 */ + .loading-spinner { + display: inline-block; + width: 16px; + height: 16px; + border: 2px solid transparent; + border-radius: 50%; + border-top-color: #3b82f6; + animation: spin 1s ease-in-out infinite; + margin-right: 8px; + } + + @keyframes spin { + to { transform: rotate(360deg); } + } + + .btn-loading { + opacity: 0.7; + pointer-events: none; + } + + /* ç¡®è®¤å¯¹è¯æ¡† */ + .confirm-dialog { + max-width: 400px; + } + + .confirm-dialog .bandix-modal-body { + padding: 24px; + } + + .confirm-dialog-title { + font-size: 1.125rem; + font-weight: 600; + margin-bottom: 12px; + } + + .confirm-dialog-message { + font-size: 0.875rem; + line-height: 1.5; + margin-bottom: 20px; + } + + + .confirm-dialog-footer { + display: flex; + gap: 10px; + justify-content: flex-end; + } + + /* 历å²è¶‹åŠ¿ */ + .history-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16px; + } + @media (max-width: 768px) { + .history-header { + flex-direction: column; + align-items: flex-start; + gap: 12px; + } + } + .history-controls { + display: flex; + flex-wrap: wrap; + gap: 12px; + align-items: center; + padding: 12px 16px; + } + .history-controls .cbi-input-select { + width: auto; + min-width: 160px; + } + .history-card-body { + padding: 16px; + position: relative; + } + .history-legend { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + padding-right: 16px; + } + .legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.875rem; } + .legend-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; } + .legend-up { background-color: ${BANDIX_COLOR_UPLOAD}; } + .legend-down { background-color: ${BANDIX_COLOR_DOWNLOAD}; } + #history-canvas { width: 100%; height: 200px; display: block; } /* å˜çª„的高度 */ + + /* 移动端优化 */ + @media (max-width: 768px) { + .bandix-alert { + flex-direction: column; + align-items: flex-start; + gap: 8px; + } + + .bandix-alert > div:first-child { + width: 100%; + } + + .bandix-alert #device-count { + width: 100%; + text-align: left; + } + + .stats-card-info-icon { + display: none; + } + + #history-canvas { + height: 300px; /* 移动端增加高度 */ + } + .history-controls { + flex-direction: column; + align-items: stretch; + gap: 8px; + padding: 12px; + } + .history-controls .cbi-input-select { + width: 100%; + min-width: 0; + } + .history-controls .form-label { + margin-bottom: 4px; + } + .history-legend { + margin-left: 0; + margin-top: 8px; + width: 100%; + justify-content: center; + padding-right: 0; + } + .history-header { + flex-direction: column; + align-items: flex-start; + gap: 8px; + } + .history-card-body { + padding: 12px; + } + .device-card { + margin-left: 12px; + margin-right: 12px; + } + .history-tooltip { + width: calc(100vw - 32px); + max-width: 320px; + font-size: 0.75rem; + padding: 10px; + } + .history-tooltip .ht-kpis { + grid-template-columns: 1fr; + gap: 8px; + } + .history-tooltip .ht-kpi .ht-k-value { + font-size: 0.875rem; + } + #history-retention { + display: none !important; + } + #history-time-range { + display: none !important; + } + + /* 移动端éšè—设备模å¼åˆ‡æ¢æŒ‰é’® */ + .device-mode-group { + display: none !important; + } + + /* 移动端设备列表å¡ç‰‡å¼å¸ƒå±€ */ + .bandix-table { + display: none; /* 移动端éšè—表格 */ + } + + .device-list-cards { + display: block; + } + + .device-card { + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + padding: 12px; + margin-bottom: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); + } + + + .device-card-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; + padding-bottom: 12px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + + + .device-card-name { + flex: 1; + display: flex; + align-items: center; + gap: 8px; + } + + .device-card-name .device-status { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; + flex-shrink: 0; + } + + .device-card-name .device-status.online { + background-color: #10b981; + } + + .device-card-name .device-status.offline { + background-color: #9ca3af; + } + + .device-card-ip { + font-size: 0.75rem; + opacity: 0.7; + margin-top: 4px; + } + + .device-card-ip .device-uplink-badges .device-uplink-badge, + .device-card-ip .device-uplink-badges .device-ch-badge { + padding: 1px 5px; + font-size: 0.65rem; + } + + .device-card-action { + flex-shrink: 0; + display: flex; + gap: 6px; + } + + .device-card-action .cbi-button { + min-width: 32px; + min-height: 32px; + padding: 6px; + font-size: 0.875rem; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + } + + .device-card-content { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 12px; + } + + .device-card-section { + display: flex; + flex-direction: column; + gap: 4px; + } + + .device-card-section-label { + font-size: 0.75rem; + opacity: 0.7; + font-weight: 500; + margin-bottom: 4px; + } + + .device-card-traffic { + display: flex; + flex-direction: column; + gap: 4px; + } + + .device-card-traffic-row { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.875rem; + } + + /* LANæµé‡æ ·å¼ï¼ˆç§»åŠ¨ç«¯ç›´æŽ¥æ˜¾ç¤ºï¼‰ */ + .device-card-lan { + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid rgba(0, 0, 0, 0.1); + } + + + /* è§„åˆ™æ˜¾ç¤ºæ ·å¼ */ + .device-card-rules { + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid rgba(0, 0, 0, 0.1); + } + + + .device-card-rules-content { + display: flex; + flex-direction: column; + gap: 6px; + padding: 8px 0; + } + + .device-card-rules-empty { + font-size: 0.75rem; + opacity: 0.6; + padding: 4px 0; + } + + .device-card-rules-count { + font-size: 0.8125rem; + font-weight: 600; + color: inherit; + margin-bottom: 2px; + } + + .device-card-rules-active-time { + font-size: 0.8125rem; + color: #10b981; + display: flex; + flex-direction: row; + align-items: center; + flex-wrap: wrap; + gap: 8px; + line-height: 1.4; + } + + .device-card-rules-limits { + font-size: 0.75rem; + opacity: 0.8; + margin-top: 2px; + word-break: break-word; + } + + .device-card-rules-more { + font-size: 0.7rem; + opacity: 0.6; + margin-top: 2px; + } + + .device-card-rules-inactive { + font-size: 0.8125rem; + opacity: 0.5; + margin-top: 4px; + } + } + + /* PC端显示表格,éšè—å¡ç‰‡ */ + @media (min-width: 769px) { + .bandix-table { + display: table; + } + + .device-list-cards { + display: none; + } + } + .history-tooltip { + position: fixed; + display: none; + width: 320px; + box-sizing: border-box; + padding: 12px; + z-index: 10; + pointer-events: none; + font-size: 0.8125rem; + line-height: 1.5; + white-space: nowrap; + background-color: ${themeColors.tooltipBg} !important; + border-radius: 6px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + color: ${tooltipTextColor} !important; + } + + .history-tooltip .ht-title { font-weight: 700; margin-bottom: 6px; } + .history-tooltip .ht-row { display: flex; justify-content: space-between; gap: 12px; } + .history-tooltip .ht-key { opacity: 0.7; } + .history-tooltip .ht-val { } + .history-tooltip .ht-device { margin-top: 4px; margin-bottom: 6px; opacity: 0.7; font-size: 0.75rem; } + /* 强调关键信æ¯çš„æŽ’版 */ + .history-tooltip .ht-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 2px; margin-bottom: 6px; } + .history-tooltip .ht-kpi .ht-k-label { opacity: 0.7; font-size: 0.75rem; } + .history-tooltip .ht-kpi .ht-k-value { font-size: 1rem; font-weight: 700; } + .history-tooltip .ht-kpi.down .ht-k-value { color: ${BANDIX_COLOR_DOWNLOAD}; } + .history-tooltip .ht-kpi.up .ht-k-value { color: ${BANDIX_COLOR_UPLOAD}; } + .history-tooltip .ht-divider { height: 1px; background-color: ${tooltipDividerColor}; opacity: ${tooltipDividerOpacity}; margin: 8px 0; } + .history-tooltip .ht-section-title { font-weight: 600; font-size: 0.75rem; opacity: 0.7; margin: 4px 0 6px 0; } + + /* Traffic Timeline Tooltip - 使用与 History Tooltip 相åŒçš„æ ·å¼ */ + .traffic-increments-tooltip .ht-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 2px; margin-bottom: 6px; } + .traffic-increments-tooltip .ht-kpi .ht-k-label { opacity: 0.7; font-size: 0.75rem; } + .traffic-increments-tooltip .ht-kpi .ht-k-value { font-size: 1rem; font-weight: 700; } + .traffic-increments-tooltip .ht-kpi.down .ht-k-value { color: ${BANDIX_COLOR_DOWNLOAD}; } + .traffic-increments-tooltip .ht-kpi.up .ht-k-value { color: ${BANDIX_COLOR_UPLOAD}; } + .traffic-increments-tooltip .ht-divider { height: 1px; background-color: ${tooltipDividerColor}; opacity: ${tooltipDividerOpacity}; margin: 8px 0; } + .traffic-increments-tooltip .ht-section-title { font-weight: 600; font-size: 0.75rem; opacity: 0.7; margin: 4px 0 6px 0; } + .traffic-increments-tooltip .ht-row { display: flex; justify-content: space-between; gap: 12px; } + .traffic-increments-tooltip .ht-key { opacity: 0.7; } + .traffic-increments-tooltip .ht-val { } + + /* Schedule Rules Tooltip */ + .schedule-rules-tooltip { + position: fixed; + display: none; + width: 360px; + max-width: 90vw; + box-sizing: border-box; + padding: 12px; + z-index: 10000; + pointer-events: none; + font-size: 0.8125rem; + line-height: 1.5; + background-color: ${themeColors.tooltipBg} !important; + border-radius: 6px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + color: ${tooltipTextColor} !important; + } + + + .schedule-rules-tooltip .srt-title { + font-weight: 700; + margin-bottom: 8px; + font-size: 0.875rem; + } + + .schedule-rules-tooltip .srt-rule-item { + padding: 8px 0; + border-bottom: 1px solid ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)'}; + } + + + .schedule-rules-tooltip .srt-rule-item:last-child { + border-bottom: none; + } + + .schedule-rules-tooltip .srt-rule-time { + font-weight: 600; + margin-bottom: 4px; + font-size: 0.75rem; + } + + .schedule-rules-tooltip .srt-rule-days { + font-size: 0.75rem; + font-weight: 500; + opacity: 0.7; + margin-bottom: 4px; + } + + .schedule-rules-tooltip .srt-rule-limits { + font-size: 0.875rem; + font-weight: 600; + opacity: 0.8; + } + + .schedule-rules-tooltip .srt-rule-limits .srt-arrow { + font-size: 0.75rem; + font-weight: bold; + } + + .schedule-rules-info { + } + + /* ç»Ÿè®¡åŒºåŸŸæ ·å¼ */ + .traffic-stats-container { + display: flex; + flex-direction: column; + gap: 20px; + margin-top: 16px; + } + + .traffic-stats-section { + padding: 16px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 8px; + } + + + .traffic-stats-section h4 { + margin: 0 0 16px 0; + font-size: 1rem; + font-weight: 600; + } + + .usage-ranking-header { + display: flex; + align-items: center; + justify-content: space-between; + } + + .usage-ranking-title { + font-size: 1rem; + font-weight: 600; + } + + .usage-ranking-timerange { + font-size: 0.8125rem; + opacity: 0.6; + font-weight: 400; + } + + .usage-ranking-query { + margin-bottom: 16px; + padding: 16px; + background-color: rgba(0, 0, 0, 0.02); + border-radius: 8px; + } + + + .usage-ranking-date-range-row { + display: flex; + align-items: flex-end; + gap: 16px; + margin-bottom: 16px; + flex-wrap: wrap; + } + + .usage-ranking-date-picker-wrapper { + display: flex; + flex-direction: column; + gap: 6px; + flex: 1; + min-width: 160px; + } + + .usage-ranking-network-type-wrapper { + display: flex; + flex-direction: column; + gap: 6px; + flex: 0 0 auto; + min-width: 140px; + } + + .usage-ranking-network-label { + font-size: 0.8125rem; + font-weight: 500; + opacity: 0.7; + color: inherit; + } + + + .usage-ranking-date-label { + font-size: 0.8125rem; + font-weight: 500; + opacity: 0.7; + color: inherit; + } + + .usage-ranking-query-presets { + display: flex; + gap: 8px; + margin-bottom: 12px; + flex-wrap: wrap; + } + + + .usage-ranking-custom-range { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + } + + .usage-ranking-date-picker { + position: relative; + } + + + .usage-ranking-date-separator { + font-size: 1.25rem; + opacity: 0.4; + margin-bottom: 28px; + font-weight: 300; + } + + .usage-ranking-query-actions { + display: flex; + gap: 8px; + margin-left: auto; + } + + /* 查询按钮 loading çŠ¶æ€æ ·å¼ï¼ˆé¿å…与 LuCI/主题的 .loading 冲çªï¼‰ */ + .usage-ranking-query-btn.bandix-loading { + position: relative; + opacity: 0.7; + } + + .usage-ranking-query-btn.bandix-loading::after { + content: ''; + position: absolute; + width: 14px; + height: 14px; + top: 50%; + left: 50%; + margin-left: -7px; + margin-top: -7px; + border: 2px solid rgba(59, 130, 246, 0.3); + border-top-color: #3b82f6; + border-radius: 50%; + animation: spin 1s linear infinite; + } + + .usage-ranking-query-btn.bandix-loading span { + opacity: 0; + } + + + + .usage-ranking-query-reset { + padding: 8px 12px; + background-color: transparent; + color: #6b7280; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + cursor: pointer; + font-size: 0.875rem; + transition: all 0.2s ease; + } + + .usage-ranking-query-reset:hover { + background-color: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.25); + } + + + .usage-ranking-timeline { + margin-top: 12px; + height: 4px; + background-color: rgba(0, 0, 0, 0.1); + border-radius: 2px; + position: relative; + } + + + .usage-ranking-timeline-range { + position: absolute; + height: 100%; + background-color: #3b82f6; + border-radius: 2px; + transition: all 0.3s ease; + } + + .usage-ranking-list { + display: flex; + flex-direction: column; + gap: 8px; + overflow-y: auto; + padding-right: 4px; + } + + /* æ»šåŠ¨æ¡æ ·å¼ */ + .usage-ranking-list::-webkit-scrollbar { + width: 6px; + } + + .usage-ranking-list::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.05); + border-radius: 3px; + } + + .usage-ranking-list::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.2); + border-radius: 3px; + } + + .usage-ranking-list::-webkit-scrollbar-thumb:hover { + background: rgba(0, 0, 0, 0.3); + } + + + .usage-ranking-controls { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 12px; + padding: 12px; + background-color: rgba(0, 0, 0, 0.02); + border-radius: 6px; + font-size: 0.875rem; + } + + + .usage-ranking-info-text { + opacity: 0.6; + } + + .usage-ranking-toggle-btn { + padding: 6px 12px; + background-color: rgba(59, 130, 246, 0.1); + color: #3b82f6; + border: 1px solid rgba(59, 130, 246, 0.2); + border-radius: 4px; + cursor: pointer; + font-size: 0.875rem; + font-weight: 500; + transition: all 0.2s ease; + } + + .usage-ranking-toggle-btn:hover { + background-color: rgba(59, 130, 246, 0.15); + border-color: rgba(59, 130, 246, 0.3); + } + + + .usage-ranking-item { + position: relative; + display: flex; + align-items: center; + gap: 10px; + padding: 10px; + border-radius: 8px; + background-color: rgba(0, 0, 0, 0.02); + border: 1px solid rgba(0, 0, 0, 0.06); + overflow: hidden; + } + + + .usage-ranking-item:hover { + background-color: rgba(0, 0, 0, 0.04); + border-color: rgba(0, 0, 0, 0.1); + } + + + /* èƒŒæ™¯è¿›åº¦æ¡ */ + .usage-ranking-item::before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: var(--progress-width, 0%); + background: linear-gradient(90deg, rgba(59, 130, 246, 0.18) 0%, rgba(59, 130, 246, 0.10) 100%); + z-index: 0; + } + + + .usage-ranking-item > * { + position: relative; + z-index: 1; + } + + .usage-ranking-rank { + display: flex; + align-items: center; + justify-content: center; + min-width: 24px; + height: 24px; + font-weight: 700; + font-size: 0.75rem; + border-radius: 6px; + background-color: rgba(59, 130, 246, 0.1); + color: #3b82f6; + flex-shrink: 0; + } + + + .usage-ranking-info { + flex: 1; + min-width: 0; + display: flex; + align-items: flex-start; + gap: 12px; + } + + .usage-ranking-device { + flex: 1; + min-width: 0; + } + + .usage-ranking-name { + font-weight: 600; + font-size: 0.875rem; + margin-bottom: 2px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .usage-ranking-meta { + display: flex; + gap: 8px; + font-size: 0.75rem; + opacity: 0.5; + font-family: monospace; + } + + .usage-ranking-meta > span { + flex-shrink: 0; + white-space: nowrap; + } + + .usage-ranking-stats { + display: flex; + align-items: center; + gap: 16px; + } + + .usage-ranking-traffic { + display: flex; + align-items: center; + gap: 10px; + } + + .usage-ranking-traffic-item { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.875rem; + font-weight: 500; + } + + .usage-ranking-traffic-item.rx { + color: ${BANDIX_COLOR_DOWNLOAD}; + } + + .usage-ranking-traffic-item.tx { + color: ${BANDIX_COLOR_UPLOAD}; + } + + .usage-ranking-traffic-item.total { + color: #6b7280; + font-weight: 600; + } + + + .usage-ranking-traffic-arrow { + font-weight: 700; + font-size: 1rem; + } + + .usage-ranking-percentage { + font-size: 1.25rem; + font-weight: 700; + color: #3b82f6; + min-width: 70px; + text-align: right; + } + + + .traffic-increments-filters { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; + flex-wrap: wrap; + } + + .traffic-increments-filter-group { + display: flex; + align-items: center; + gap: 8px; + } + + .traffic-increments-filter-label { + font-size: 0.8125rem; + opacity: 0.7; + white-space: nowrap; + } + + .traffic-increments-filters .cbi-input-select { + min-width: 120px; + } + + .traffic-increments-query { + margin-bottom: 16px; + padding: 16px; + background-color: rgba(0, 0, 0, 0.02); + border-radius: 8px; + } + + + + .traffic-increments-chart { + position: relative; + width: 100%; + height: 300px; + cursor: pointer; + } + + .traffic-increments-tooltip { + position: fixed; + background-color: ${themeColors.tooltipBg} !important; + color: ${tooltipTextColor} !important; + padding: 12px; + border-radius: 6px; + font-size: 0.8125rem; + pointer-events: none; + z-index: 1000; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + display: none; + min-width: 280px; + max-width: 400px; + } + + + .traffic-increments-tooltip-title { + font-weight: 600; + margin-bottom: 8px; + border-bottom: 1px solid ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)'}; + padding-bottom: 4px; + font-size: 0.875rem; + } + + + .traffic-increments-tooltip-section { + margin-bottom: 8px; + } + + .traffic-increments-tooltip-section:last-child { + margin-bottom: 0; + } + + .traffic-increments-tooltip-section-title { + font-weight: 600; + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-bottom: 4px; + color: ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.7)' : 'rgba(0, 0, 0, 0.7)'}; + border-bottom: 1px solid ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)'}; + padding-bottom: 2px; + } + + + .traffic-increments-tooltip-item { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-bottom: 2px; + font-size: 0.75rem; + } + + .traffic-increments-tooltip-item:last-child { + margin-bottom: 0; + } + + .traffic-increments-tooltip-item-label { + display: flex; + align-items: center; + gap: 6px; + flex: 1; + } + + .traffic-increments-tooltip-item-value { + font-weight: 500; + text-align: right; + } + + .traffic-increments-tooltip-dot { + width: 6px; + height: 6px; + border-radius: 50%; + flex-shrink: 0; + } + + .traffic-increments-tooltip-dot.rx { + background-color: ${BANDIX_COLOR_DOWNLOAD}; + } + + .traffic-increments-tooltip-dot.tx { + background-color: ${BANDIX_COLOR_UPLOAD}; + } + + .traffic-increments-tooltip-dot.wan { + background-color: #8b5cf6; + } + + .traffic-increments-tooltip-dot.lan { + background-color: #10b981; + } + + .stats-card-info-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)'}; + color: ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.7)' : 'rgba(0, 0, 0, 0.6)'}; + font-size: 0.75rem; + font-weight: 600; + cursor: help; + margin-left: 6px; + vertical-align: middle; + line-height: 1; + transition: background-color 0.2s ease, color 0.2s ease; + } + + .stats-card-info-icon:hover { + background-color: ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.15)'}; + color: ${scheme === 'dark' ? 'rgba(255, 255, 255, 0.9)' : 'rgba(0, 0, 0, 0.8)'}; + } + + .lan-traffic-tooltip { + position: absolute; + background-color: ${themeColors.tooltipBg} !important; + color: ${tooltipTextColor} !important; + padding: 12px; + border-radius: 6px; + font-size: 0.8125rem; + pointer-events: none; + z-index: 1000; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + display: none; + min-width: 280px; + max-width: 400px; + line-height: 1.5; + } + + .traffic-increments-summary { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; + margin-top: 16px; + } + + .traffic-increments-summary-item { + text-align: center; + padding: 12px; + border-radius: 6px; + background-color: rgba(0, 0, 0, 0.02); + } + + + .traffic-increments-summary-label { + font-size: 0.75rem; + opacity: 0.7; + margin-bottom: 4px; + } + + .traffic-increments-summary-value { + font-weight: 600; + font-size: 0.875rem; + } + + /* 统计区域头部和控制 */ + .traffic-stats-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16px; + } + + /* 图例 */ + .traffic-stats-legend { + display: flex; + align-items: center; + justify-content: center; + gap: 16px; + margin-top: 12px; + padding: 8px; + } + + .traffic-stats-legend-item { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.875rem; + } + + .traffic-stats-legend-dot { + width: 10px; + height: 10px; + border-radius: 50%; + display: inline-block; + } + + .traffic-stats-legend-dot.rx { + background-color: ${BANDIX_COLOR_DOWNLOAD}; + } + + .traffic-stats-legend-dot.tx { + background-color: ${BANDIX_COLOR_UPLOAD}; + } + + /* 移动端å“åº”å¼æ ·å¼ */ + @media (max-width: 768px) { + /* Traffic Statistics 容器 */ + .traffic-stats-container { + gap: 16px; + } + + .traffic-stats-section { + padding: 12px; + } + + /* Header 布局 - 垂直排列 */ + .usage-ranking-header { + flex-direction: column; + align-items: flex-start; + gap: 8px; + } + + .usage-ranking-title { + font-size: 0.9375rem; + } + + .usage-ranking-timerange { + font-size: 0.75rem; + width: 100%; + } + + /* 查询区域 */ + .usage-ranking-query { + padding: 12px; + margin-bottom: 12px; + } + + /* 日期选择器区域 */ + .usage-ranking-date-range-row { + flex-direction: column; + gap: 12px; + margin-bottom: 12px; + } + + .usage-ranking-date-picker-wrapper { + min-width: 100%; + } + + .usage-ranking-date-label { + font-size: 0.75rem; + } + + .usage-ranking-date-separator { + display: none; + } + + /* å¿«æ·æŒ‰é’® */ + .usage-ranking-query-presets { + gap: 6px; + margin-bottom: 10px; + } + + /* 查询æ“作按钮 */ + .usage-ranking-query-actions { + width: 100%; + margin-left: 0; + justify-content: stretch; + } + + /* 设备列表项 - 垂直布局 */ + .usage-ranking-item { + flex-direction: column; + align-items: flex-start; + gap: 10px; + padding: 10px; + } + + .usage-ranking-rank { + min-width: 24px; + height: 24px; + font-size: 0.75rem; + } + + .usage-ranking-info { + flex-direction: column; + align-items: flex-start; + gap: 8px; + width: 100%; + } + + .usage-ranking-device { + width: 100%; + } + + .usage-ranking-name { + font-size: 0.875rem; + margin-bottom: 2px; + } + + .usage-ranking-meta { + font-size: 0.6875rem; + gap: 8px; + flex-wrap: nowrap; + display: flex; + align-items: center; + width: 100%; + justify-content: space-between; + } + + .usage-ranking-meta > span:first-child { + flex: 0 1 auto; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .usage-ranking-meta > span:nth-child(2) { + display: none; + } + + .usage-ranking-meta > .usage-ranking-meta-total { + font-size: 0.8125rem; + font-weight: 600; + color: #6b7280; + margin-left: 8px; + flex-shrink: 0; + } + + + .usage-ranking-stats { + flex-direction: column; + align-items: flex-start; + gap: 8px; + width: 100%; + } + + .usage-ranking-traffic { + flex-wrap: wrap; + gap: 8px; + width: 100%; + } + + /* éšè—ç§»åŠ¨ç«¯ä¸‹çš„æ€»é‡æ˜¾ç¤ºï¼ˆå› ä¸ºå·²ç»åœ¨ meta 中显示) */ + .usage-ranking-traffic-item.total { + display: none; + } + + .usage-ranking-traffic-item { + font-size: 0.8125rem; + } + + .usage-ranking-traffic-arrow { + font-size: 0.875rem; + } + + .usage-ranking-percentage { + font-size: 1.25rem; + min-width: auto; + text-align: left; + width: 100%; + } + + /* 控制按钮 */ + .usage-ranking-controls { + flex-direction: column; + gap: 8px; + align-items: stretch; + } + + .usage-ranking-info-text { + font-size: 0.75rem; + text-align: center; + } + + .usage-ranking-toggle-btn { + width: 100%; + padding: 8px 12px; + font-size: 0.8125rem; + } + + /* Traffic Timeline 筛选器 */ + .traffic-increments-filters { + flex-direction: column; + align-items: stretch; + gap: 10px; + margin-bottom: 12px; + } + + .traffic-increments-filter-group { + flex-direction: column; + align-items: stretch; + gap: 6px; + } + + .traffic-increments-filter-label { + font-size: 0.75rem; + } + + .traffic-increments-filters .cbi-input-select { + width: 100%; + min-width: auto; + padding: 8px 10px; + font-size: 0.8125rem; + } + + /* Traffic Timeline 查询区域 */ + .traffic-increments-query { + padding: 12px; + margin-bottom: 12px; + } + + /* Traffic Timeline 的日期选择器使用相åŒçš„ usage-ranking-* ç±»å,已在上é¢è¦†ç›– */ + + /* 图表 */ + .traffic-increments-chart { + height: 250px; + } + + /* 摘è¦å¡ç‰‡ */ + .traffic-increments-summary { + grid-template-columns: 1fr; + gap: 8px; + margin-top: 12px; + } + + .traffic-increments-summary-item { + padding: 10px; + } + + .traffic-increments-summary-label { + font-size: 0.6875rem; + } + + .traffic-increments-summary-value { + font-size: 0.8125rem; + } + + /* 图例 - 移动端éšè— */ + .traffic-stats-legend { + display: none; + } + } + + `; + return css; + } + + // 添加现代化样å¼ï¼ŒèŽ·å–当å‰ä¸»é¢˜æ¨¡å¼ + var initialScheme = getThemeMode(); + + var oldStyle = document.getElementById('bandix-styles'); + if (oldStyle && oldStyle.parentNode) oldStyle.parentNode.removeChild(oldStyle); + + var style = E('style', { 'id': 'bandix-styles' }, generateStyles(initialScheme)); + document.head.appendChild(style); + + // 创建主题更新函数 + function updateThemeStyles() { + var newScheme = getThemeMode(); + var oldStyle = document.getElementById('bandix-styles'); + if (oldStyle) { + oldStyle.textContent = generateStyles(newScheme); + } + } + + // 监å¬ç³»ç»Ÿä¸»é¢˜å˜åŒ–(所有主题都å“应) + if (window.matchMedia) { + var colorSchemeMedia = window.matchMedia('(prefers-color-scheme: dark)'); + colorSchemeMedia.addEventListener('change', function (e) { + updateThemeStyles(); + }); + } + + // 定期检查主题é…ç½®å˜åŒ–(æ¯5秒检查一次,所有主题) + var lastThemeMode = getThemeMode(); + setInterval(function () { + try { + var currentThemeMode = getThemeMode(); + if (currentThemeMode !== lastThemeMode) { + lastThemeMode = currentThemeMode; + updateThemeStyles(); + } + } catch (e) { + // é™é»˜å¤±è´¥ + } + }, 5000); + + var themeMode = getThemeMode(); + var view = E('div', { 'class': 'bandix-container theme-' + themeMode }, [ + // 头部 + E('div', { 'class': 'bandix-header' }, [ + E('div', { 'class': 'bandix-title-wrapper' }, [ + E('h1', { 'class': 'bandix-title' }, _('Bandix Traffic Monitor')), + E('div', { 'class': 'bandix-version-wrapper' }, [ + E('div', { 'class': 'bandix-version-item' }, [ + E('span', { 'class': 'bandix-version', 'id': 'bandix-luci-version' }, ''), + ]), + E('div', { 'class': 'bandix-version-item' }, [ + E('span', { 'class': 'bandix-version', 'id': 'bandix-core-version' }, ''), + ]), + E('span', { 'class': 'bandix-update-badge', 'id': 'bandix-update-badge', 'style': 'display: none;' }, _('Update available')) + ]) + ]) + ]), + + // 警告æç¤ºï¼ˆåŒ…å«åœ¨çº¿è®¾å¤‡æ•°ï¼‰ + E('div', { + 'class': 'bandix-alert' + (getThemeType() === 'wide' ? ' wide-theme' : '') + }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [ + E('span', { 'style': 'font-size: 1rem;' }, 'âš '), + E('span', {}, _("Rate limiting only applies to WAN traffic.")) + ]), + E('div', { 'class': 'bandix-badge', 'id': 'device-count' }, _('Online Devices') + ': 0 / 0') + ]), + + // 统计å¡ç‰‡ + E('div', { 'class': 'stats-grid', 'id': 'stats-grid' }), + + // 实时æµé‡è¶‹åŠ¿ + E('div', { 'class': 'cbi-section', 'id': 'history-card' }, [ + E('h3', { 'style': 'display: flex; align-items: center; justify-content: space-between;' }, [ + E('span', {}, _('Realtime Traffic Trends')), + E('div', { 'class': 'history-legend' }, [ + E('div', { 'class': 'legend-item' }, [ + E('span', { 'class': 'legend-dot legend-up' }), + _('Upload Rate') + ]), + E('div', { 'class': 'legend-item' }, [ + E('span', { 'class': 'legend-dot legend-down' }), + _('Download Rate') + ]) + ]) + ]), + E('div', { 'class': 'history-controls' }, [ + E('label', { 'class': 'form-label', 'style': 'margin: 0;' }, _('Select Device')), + E('select', { 'class': 'cbi-input-select', 'id': 'history-device-select' }, [ + E('option', { 'value': '' }, _('All Devices')) + ]), + E('label', { 'class': 'form-label', 'style': 'margin: 0;' }, _('Type')), + E('select', { 'class': 'cbi-input-select', 'id': 'history-type-select' }, [ + E('option', { 'value': 'total' }, _('Total')), + E('option', { 'value': 'lan' }, _('LAN Traffic')), + E('option', { 'value': 'wan' }, _('WAN Traffic')) + ]), + E('span', { 'class': 'bandix-badge', 'id': 'history-zoom-level', 'style': 'margin-left: 16px; display: none;' }, ''), + E('span', { 'class': 'bandix-badge', 'id': 'history-time-range', 'style': 'margin-left: 16px; display: none;' }, ''), + E('span', { 'class': 'bandix-badge', 'id': 'history-retention', 'style': 'margin-left: auto;' }, '') + ]), + E('div', { 'class': 'history-card-body' }, [ + E('canvas', { 'id': 'history-canvas', 'height': '240' }), + E('div', { 'class': 'history-tooltip', 'id': 'history-tooltip' }) + ]) + ]), + + // 主è¦å†…容å¡ç‰‡ + E('div', { 'class': 'cbi-section' }, [ + E('h3', { 'class': 'history-header', 'style': 'display: flex; align-items: center; justify-content: space-between;' }, [ + E('span', {}, _('Device List')), + E('div', { 'class': 'device-toolbar' }, [ + E('div', { 'class': 'device-group' }, [ + E('span', { 'class': 'device-group-label' }, _('Period')), + E('select', { 'class': 'cbi-input-select', 'id': 'bandix_device_period_select' }, [ + E('option', { 'value': 'all', 'selected': ((localStorage.getItem('bandix_device_period') || 'all') === 'all') ? 'selected' : null }, _('All')), + E('option', { 'value': 'today', 'selected': ((localStorage.getItem('bandix_device_period') || 'all') === 'today') ? 'selected' : null }, _('Today')), + E('option', { 'value': 'week', 'selected': ((localStorage.getItem('bandix_device_period') || 'all') === 'week') ? 'selected' : null }, _('This Week')), + E('option', { 'value': 'month', 'selected': ((localStorage.getItem('bandix_device_period') || 'all') === 'month') ? 'selected' : null }, _('This Month')), + E('option', { 'value': 'year', 'selected': ((localStorage.getItem('bandix_device_period') || 'all') === 'year') ? 'selected' : null }, _('This Year')) + ]) + ]), + E('div', { 'class': 'device-group' }, [ + E('span', { 'class': 'device-group-label' }, _('Display Mode')), + E('select', { 'class': 'cbi-input-select', 'id': 'bandix_device_mode_select' }, [ + E('option', { 'value': 'simple', 'selected': (localStorage.getItem('bandix_device_mode') !== 'detailed') ? 'selected' : null }, _('Simple Mode')), + E('option', { 'value': 'detailed', 'selected': (localStorage.getItem('bandix_device_mode') === 'detailed') ? 'selected' : null }, _('Detailed Mode')) + ]) + ]), + E('div', { 'class': 'device-group' }, [ + E('span', { 'class': 'device-group-label' }, _('Global Rate Limit')), + E('span', { 'class': 'cbi-button cbi-button-action', 'id': 'bandix_whitelist_badge', 'style': 'cursor: pointer; user-select: none;' }, _('Loading...')) + ]) + ]) + ]), + E('div', { 'id': 'traffic-status' }, [ + E('table', { 'class': 'bandix-table' }, [ + E('thead', {}, [ + E('tr', {}, [ + E('th', {}, _('Device Info')), + E('th', {}, _('LAN Traffic')), + E('th', {}, _('WAN Traffic')), + E('th', {}, _('Rate Limit')), + E('th', {}, _('Actions')) + ]) + ]), + E('tbody', {}) + ]) + ]) + ]), + + // 统计区域 + E('div', { 'class': 'cbi-section' }, [ + E('h3', { 'class': 'traffic-stats-header' }, [ + E('span', {}, _('Traffic Statistics')) + ]), + E('div', { 'id': 'traffic-statistics' }, [ + E('div', { 'class': 'traffic-stats-container' }, [ + // è®¾å¤‡ç”¨é‡æŽ’è¡ŒåŒºåŸŸ + E('div', { 'class': 'traffic-stats-section' }, [ + E('div', { 'class': 'usage-ranking-header' }, [ + E('h4', { 'class': 'usage-ranking-title' }, [ + E('span', {}, _('Device Usage Ranking')) + ]), + E('span', { 'class': 'usage-ranking-timerange', 'id': 'usage-ranking-timerange' }, '') + ]), + E('div', { 'class': 'usage-ranking-query' }, [ + E('div', { 'class': 'usage-ranking-date-range-row' }, [ + E('div', { 'class': 'usage-ranking-date-picker-wrapper' }, [ + E('label', { 'class': 'usage-ranking-date-label' }, _('Start Date')), + E('div', { 'class': 'usage-ranking-date-picker', 'id': 'usage-ranking-start-picker' }, [ + E('input', { + 'type': 'date', + 'id': 'usage-ranking-start-date', + 'class': 'cbi-input-date' + }) + ]) + ]), + E('span', { 'class': 'usage-ranking-date-separator' }, '→'), + E('div', { 'class': 'usage-ranking-date-picker-wrapper' }, [ + E('label', { 'class': 'usage-ranking-date-label' }, _('End Date')), + E('div', { 'class': 'usage-ranking-date-picker', 'id': 'usage-ranking-end-picker' }, [ + E('input', { + 'type': 'date', + 'id': 'usage-ranking-end-date', + 'class': 'cbi-input-date' + }) + ]) + ]), + E('div', { 'class': 'usage-ranking-network-type-wrapper' }, [ + E('label', { 'class': 'usage-ranking-network-label' }, _('Network Type')), + E('select', { + 'class': 'cbi-input-select', + 'id': 'usage-ranking-network-type' + }, [ + E('option', { 'value': 'wan' }, _('WAN Traffic')), + E('option', { 'value': 'lan' }, _('LAN Traffic')), + E('option', { 'value': 'all' }, _('Total')) + ]) + ]), + E('div', { 'class': 'usage-ranking-query-actions' }, [ + E('button', { + 'class': 'cbi-button cbi-button-action usage-ranking-query-btn', + 'id': 'usage-ranking-query-btn' + }, E('span', {}, _('Query'))), + E('button', { + 'class': 'cbi-button cbi-button-reset', + 'id': 'usage-ranking-reset-btn' + }, _('Reset')) + ]) + ]), + E('div', { 'class': 'usage-ranking-query-presets' }, [ + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'today' }, _('Today')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thisweek' }, _('This Week')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'lastweek' }, _('Last Week')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thismonth' }, _('This Month')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'lastmonth' }, _('Last Month')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '7days' }, _('Last 7 Days')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '30days' }, _('Last 30 Days')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '90days' }, _('Last 90 Days')), + E('button', { 'class': 'cbi-button cbi-button-positive', 'data-preset': '1year' }, _('Last Year')) + ]), + E('div', { 'class': 'usage-ranking-timeline', 'id': 'usage-ranking-timeline' }, [ + E('div', { 'class': 'usage-ranking-timeline-range', 'id': 'usage-ranking-timeline-range' }) + ]) + ]), + E('div', { 'id': 'usage-ranking-container' }, [ + E('div', { 'class': 'loading-state' }, _('Loading...')) + ]) + ]), + // æ—¶é—´åºåˆ—图表区域 + E('div', { 'class': 'traffic-stats-section' }, [ + E('div', { 'class': 'usage-ranking-header' }, [ + E('h4', { 'class': 'usage-ranking-title' }, [ + E('span', {}, _('Traffic Timeline')) + ]), + E('span', { 'class': 'usage-ranking-timerange', 'id': 'traffic-increments-timerange' }, '') + ]), + E('div', { 'class': 'traffic-increments-query' }, [ + E('div', { 'class': 'usage-ranking-date-range-row' }, [ + E('div', { 'class': 'usage-ranking-date-picker-wrapper' }, [ + E('label', { 'class': 'usage-ranking-date-label' }, _('Start Date')), + E('div', { 'class': 'usage-ranking-date-picker' }, [ + E('input', { + 'type': 'date', + 'id': 'traffic-increments-start-date', + 'class': 'cbi-input-date' + }) + ]) + ]), + E('span', { 'class': 'usage-ranking-date-separator' }, '→'), + E('div', { 'class': 'usage-ranking-date-picker-wrapper' }, [ + E('label', { 'class': 'usage-ranking-date-label' }, _('End Date')), + E('div', { 'class': 'usage-ranking-date-picker' }, [ + E('input', { + 'type': 'date', + 'id': 'traffic-increments-end-date', + 'class': 'cbi-input-date' + }) + ]) + ]), + E('div', { 'class': 'usage-ranking-network-type-wrapper' }, [ + E('label', { 'class': 'usage-ranking-network-label' }, _('Network Type')), + E('select', { + 'class': 'cbi-input-select', + 'id': 'traffic-increments-network-type' + }, [ + E('option', { 'value': 'wan' }, _('WAN Traffic')), + E('option', { 'value': 'lan' }, _('LAN Traffic')), + E('option', { 'value': 'all' }, _('Total')) + ]) + ]), + E('div', { 'class': 'usage-ranking-query-actions' }, [ + E('button', { + 'class': 'cbi-button cbi-button-action usage-ranking-query-btn', + 'id': 'traffic-increments-query-btn' + }, E('span', {}, _('Query'))), + E('button', { + 'class': 'cbi-button cbi-button-reset', + 'id': 'traffic-increments-reset-btn' + }, _('Reset')) + ]) + ]), + E('div', { 'class': 'usage-ranking-query-presets' }, [ + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'today' }, _('Today')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thisweek' }, _('This Week')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'lastweek' }, _('Last Week')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'thismonth' }, _('This Month')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': 'lastmonth' }, _('Last Month')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '7days' }, _('Last 7 Days')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '30days' }, _('Last 30 Days')), + E('button', { 'class': 'cbi-button cbi-button-neutral', 'data-preset': '90days' }, _('Last 90 Days')), + E('button', { 'class': 'cbi-button cbi-button-positive', 'data-preset': '1year' }, _('Last Year')) + ]), + E('div', { 'class': 'usage-ranking-timeline', 'id': 'traffic-increments-timeline' }, [ + E('div', { 'class': 'usage-ranking-timeline-range', 'id': 'traffic-increments-timeline-range' }) + ]) + ]), + E('div', { 'class': 'traffic-increments-filters' }, [ + E('div', { 'class': 'traffic-increments-filter-group' }, [ + E('label', { 'class': 'traffic-increments-filter-label' }, _('Aggregation:')), + E('select', { 'class': 'cbi-input-select', 'id': 'traffic-increments-aggregation' }, [ + E('option', { 'value': 'hourly' }, _('Hourly')), + E('option', { 'value': 'daily' }, _('Daily')) + ]) + ]), + E('div', { 'class': 'traffic-increments-filter-group' }, [ + E('label', { 'class': 'traffic-increments-filter-label' }, _('Device:')), + E('select', { 'class': 'cbi-input-select', 'id': 'traffic-increments-mac' }, [ + E('option', { 'value': 'all' }, _('All Devices')) + ]) + ]) + ]), + E('div', { 'id': 'traffic-increments-container' }, [ + E('div', { 'class': 'loading-state' }, _('Loading...')) + ]) + ]) + ]) + ]) + ]) + ]); + + // 创建全局的 Schedule Rules Tooltip 元素 + var scheduleRulesTooltip = E('div', { 'class': 'schedule-rules-tooltip', 'id': 'schedule-rules-tooltip' }); + document.body.appendChild(scheduleRulesTooltip); + + // 创建全局的 LAN Traffic Tooltip 元素 + var lanTrafficTooltip = E('div', { 'class': 'lan-traffic-tooltip', 'id': 'lan-traffic-tooltip' }); + document.body.appendChild(lanTrafficTooltip); + + // 构建规则列表的 HTML(用于 tooltip) + function buildScheduleRulesTooltipHtml(allRules, activeRules, speedUnit) { + if (!allRules || allRules.length === 0) { + return ''; + } + + var lines = []; + lines.push('
' + _('Schedule Rules') + ' (' + allRules.length + ')
'); + + allRules.forEach(function (rule, index) { + var startTime = rule.time_slot && rule.time_slot.start ? rule.time_slot.start : ''; + var endTime = rule.time_slot && rule.time_slot.end ? rule.time_slot.end : ''; + var days = rule.time_slot && rule.time_slot.days ? rule.time_slot.days : []; + + var dayNames = { + 1: _('Mon'), + 2: _('Tue'), + 3: _('Wed'), + 4: _('Thu'), + 5: _('Fri'), + 6: _('Sat'), + 7: _('Sun') + }; + var daysText = days.length > 0 ? days.map(function (d) { return dayNames[d] || d; }).join(', ') : '-'; + + var uploadLimit = rule.wan_tx_rate_limit || 0; + var downloadLimit = rule.wan_rx_rate_limit || 0; + + // 使用 isRuleActive å‡½æ•°æ£€æŸ¥è§„åˆ™æ˜¯å¦æ¿€æ´» + var isActive = isRuleActive(rule); + + // 箭头固定颜色(橙色和é’色),样å¼ä¸Ž WAN 字段一致 + var uploadLimitText = '↑' + (uploadLimit > 0 ? formatByterate(uploadLimit, speedUnit) : _('Unlimited')); + var downloadLimitText = '↓' + (downloadLimit > 0 ? formatByterate(downloadLimit, speedUnit) : _('Unlimited')); + + var activeMark = isActive ? 'â—' : ''; + + lines.push( + '
' + + '
' + activeMark + startTime + ' - ' + endTime + '
' + + '
' + daysText + '
' + + '
' + uploadLimitText + ' ' + downloadLimitText + '
' + + '
' + ); + }); + + return lines.join(''); + } + + var devicePeriodInit = localStorage.getItem('bandix_device_period'); + if (!devicePeriodInit || !/^(today|week|month|year|all)$/.test(devicePeriodInit)) { + localStorage.setItem('bandix_device_period', 'all'); + } + + var deviceModeSelect = view.querySelector('#bandix_device_mode_select'); + if (deviceModeSelect) { + deviceModeSelect.addEventListener('change', function () { + localStorage.setItem('bandix_device_mode', this.value); + updateDeviceData(); + }); + } + + var devicePeriodSelect = view.querySelector('#bandix_device_period_select'); + if (devicePeriodSelect) { + devicePeriodSelect.addEventListener('change', function () { + localStorage.setItem('bandix_device_period', this.value); + updateDeviceData(); + }); + } + + var whitelistBadge = view.querySelector('#bandix_whitelist_badge'); + if (whitelistBadge) { + whitelistBadge.addEventListener('click', function () { + showWhitelistModal(); + }); + } + + // 创建é™é€Ÿè®¾ç½®æ¨¡æ€æ¡† + var bandixModal = E('div', { 'class': 'bandix-modal-overlay', 'id': 'rate-limit-bandix-modal' }, [ + E('div', { 'class': 'modal-content bandix-modal' }, [ + E('div', { 'class': 'bandix-modal-body', }, [ + E('div', { 'class': 'device-summary', 'id': 'bandix-modal-device-summary' }), + E('div', { 'class': 'form-group' }, [ + E('label', { 'class': 'form-label' }, _('Hostname')), + E('div', { 'style': 'display: flex; gap: 8px; align-items: center;' }, [ + E('input', { 'type': 'text', 'class': 'form-input', 'id': 'device-hostname-input', 'placeholder': _('Please enter hostname'), 'style': 'flex: 1;' }), + E('button', { 'class': 'cbi-button cbi-button-positive', 'id': 'hostname-save-btn', 'style': 'flex-shrink: 0;' }, _('Save')) + ]), + E('div', { 'style': 'font-size: 0.75rem; color: #6b7280; margin-top: 4px;' }, _('Set Hostname')) + ]), + // 定时é™é€Ÿ + E('div', { 'id': 'schedule-limit-tab' }, [ + // æè¿°å’Œæ·»åŠ è§„åˆ™æŒ‰é’® + E('div', { 'style': 'display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px;' }, [ + E('span', { 'style': 'font-size: 0.875rem; opacity: 0.7;' }, _('Set rate limit rules for different time periods')), + E('button', { + 'type': 'button', + 'class': 'cbi-button cbi-button-action', + 'id': 'schedule-add-rule-btn', + 'style': 'display: flex; align-items: center; gap: 4px;' + }, [ + E('span', {}, '+'), + _('Add Rule') + ]) + ]), + // 规则列表区域 + E('div', { 'class': 'schedule-rules-list', 'id': 'schedule-rules-list' }) + ]) + ]), + E('div', { 'class': 'bandix-modal-footer' }, [ + E('button', { 'class': 'cbi-button cbi-button-reset', 'id': 'bandix-modal-close' }, _('Close')) + ]) + ]) + ]); + + document.body.appendChild(bandixModal); + + // åˆ›å»ºæ·»åŠ è§„åˆ™æ¨¡æ€æ¡† + var addRuleModal = E('div', { 'class': 'bandix-modal-overlay', 'id': 'add-rule-bandix-modal' }, [ + E('div', { 'class': 'modal-content bandix-modal' }, [ + E('div', { 'class': 'bandix-modal-header' }, [ + E('h3', { 'class': 'bandix-modal-title' }, _('Add Schedule Rule')) + ]), + E('div', { 'class': 'bandix-modal-body' }, [ + E('div', { 'class': 'form-group' }, [ + E('label', { 'class': 'form-label' }, _('Time Slot')), + E('div', { 'class': 'schedule-time-row' }, [ + E('input', { 'type': 'time', 'class': 'schedule-time-input', 'id': 'add-rule-start-time' }), + E('span', {}, ' - '), + E('input', { 'type': 'time', 'class': 'schedule-time-input', 'id': 'add-rule-end-time' }) + ]) + ]), + E('div', { 'class': 'form-group' }, [ + E('label', { 'class': 'form-label' }, _('Days of Week')), + E('div', { 'class': 'schedule-days', 'id': 'add-rule-days' }, [ + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '1' }, _('Mon')), + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '2' }, _('Tue')), + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '3' }, _('Wed')), + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '4' }, _('Thu')), + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '5' }, _('Fri')), + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '6' }, _('Sat')), + E('button', { 'type': 'button', 'class': 'schedule-day-btn', 'data-day': '7' }, _('Sun')) + ]) + ]), + E('div', { 'class': 'form-group' }, [ + E('label', { 'class': 'form-label' }, _('Upload Limit')), + E('div', { 'style': 'display: flex; gap: 8px;' }, [ + E('input', { 'type': 'number', 'class': 'form-input', 'id': 'add-rule-upload-limit-value', 'min': '0', 'step': '1', 'placeholder': '0' }), + E('select', { 'class': 'cbi-input-select', 'id': 'add-rule-upload-limit-unit', 'style': 'width: 100px;' }) + ]), + E('div', { 'style': 'font-size: 0.75rem; color: #6b7280; margin-top: 4px;' }, _('Tip: Enter 0 for unlimited')) + ]), + E('div', { 'class': 'form-group', 'style': 'margin-bottom: 0;' }, [ + E('label', { 'class': 'form-label' }, _('Download Limit')), + E('div', { 'style': 'display: flex; gap: 8px;' }, [ + E('input', { 'type': 'number', 'class': 'form-input', 'id': 'add-rule-download-limit-value', 'min': '0', 'step': '1', 'placeholder': '0' }), + E('select', { 'class': 'cbi-input-select', 'id': 'add-rule-download-limit-unit', 'style': 'width: 100px;' }) + ]), + E('div', { 'style': 'font-size: 0.75rem; color: #6b7280; margin-top: 4px;' }, _('Tip: Enter 0 for unlimited')) + ]) + ]), + E('div', { 'class': 'bandix-modal-footer' }, [ + E('button', { 'class': 'cbi-button cbi-button-reset', 'id': 'add-rule-cancel' }, _('Cancel')), + E('button', { 'class': 'cbi-button cbi-button-positive', 'id': 'add-rule-save' }, _('Add')) + ]) + ]) + ]); + + document.body.appendChild(addRuleModal); + + // åˆ›å»ºç¡®è®¤å¯¹è¯æ¡† + var confirmDialog = E('div', { 'class': 'bandix-modal-overlay', 'id': 'confirm-dialog-bandix-modal' }, [ + E('div', { 'class': 'modal-content bandix-modal confirm-dialog', "aria-modal": true }, [ + E('div', { 'class': 'bandix-modal-body' }, [ + E('div', { 'class': 'confirm-dialog-title', 'id': 'confirm-dialog-title' }, _('Confirm')), + E('div', { 'class': 'confirm-dialog-message', 'id': 'confirm-dialog-message' }, ''), + E('div', { 'class': 'confirm-dialog-footer' }, [ + E('button', { 'class': 'cbi-button cbi-button-reset', 'id': 'confirm-dialog-cancel' }, _('Cancel')), + E('button', { 'class': 'cbi-button cbi-button-negative', 'id': 'confirm-dialog-confirm' }, _('Confirm')) + ]) + ]) + ]) + ]); + + document.body.appendChild(confirmDialog); + + // 创建白åå•管ç†å¼¹çª— + var whitelistModal = E('div', { 'class': 'whitelist-modal-overlay', 'id': 'whitelist-modal' }, [ + E('div', { 'class': 'whitelist-modal bandix-modal' }, [ + E('div', { 'class': 'whitelist-modal-header' }, [ + E('h3', { 'class': 'whitelist-modal-title' }, _('Global Rate Limit')) + ]), + E('div', { 'class': 'whitelist-modal-body' }, [ + E('div', { 'class': 'whitelist-modal-row' }, [ + E('div', {}, [ + E('div', { 'style': 'font-weight: 600;' }, _('Enabled')), + E('div', { 'class': 'whitelist-modal-hint' }, _('When enabled, all devices will be rate limited. Devices in the list are exempt (whitelist).')) + ]), + E('input', { 'type': 'checkbox', 'id': 'whitelist_enabled_checkbox' }) + ]), + E('div', { 'style': 'margin-top: 14px; font-weight: 600;' }, _('Default Rate Limit')), + E('div', { 'class': 'form-group', 'style': 'margin-top: 12px;' }, [ + E('label', { 'class': 'form-label' }, _('Upload Limit')), + E('div', { 'style': 'display: flex; gap: 8px;' }, [ + E('input', { 'type': 'number', 'min': '0', 'step': '0.01', 'class': 'form-input', 'id': 'whitelist_default_wan_tx', 'placeholder': '0', 'style': 'flex: 1;' }), + E('select', { 'class': 'cbi-input-select', 'id': 'whitelist_default_wan_tx_unit', 'style': 'width: 110px; flex-shrink: 0;' }, [ + E('option', { 'value': '1024' }, 'KB/s'), + E('option', { 'value': '1048576' }, 'MB/s'), + E('option', { 'value': '1073741824' }, 'GB/s'), + E('option', { 'value': '125' }, 'Kbps'), + E('option', { 'value': '125000' }, 'Mbps'), + E('option', { 'value': '125000000' }, 'Gbps') + ]) + ]), + E('div', { 'style': 'font-size: 0.75rem; color: #6b7280; margin-top: 4px;' }, _('Tip: Enter 0 for unlimited')) + ]), + E('div', { 'class': 'form-group', 'style': 'margin-top: 12px;' }, [ + E('label', { 'class': 'form-label' }, _('Download Limit')), + E('div', { 'style': 'display: flex; gap: 8px;' }, [ + E('input', { 'type': 'number', 'min': '0', 'step': '0.01', 'class': 'form-input', 'id': 'whitelist_default_wan_rx', 'placeholder': '0', 'style': 'flex: 1;' }), + E('select', { 'class': 'cbi-input-select', 'id': 'whitelist_default_wan_rx_unit', 'style': 'width: 110px; flex-shrink: 0;' }, [ + E('option', { 'value': '1024' }, 'KB/s'), + E('option', { 'value': '1048576' }, 'MB/s'), + E('option', { 'value': '1073741824' }, 'GB/s'), + E('option', { 'value': '125' }, 'Kbps'), + E('option', { 'value': '125000' }, 'Mbps'), + E('option', { 'value': '125000000' }, 'Gbps') + ]) + ]), + E('div', { 'style': 'font-size: 0.75rem; color: #6b7280; margin-top: 4px;' }, _('Tip: Enter 0 for unlimited')) + ]), + E('div', { 'style': 'display: flex; justify-content: flex-end; margin-top: 8px;' }, [ + E('button', { 'class': 'cbi-button cbi-button-action', 'id': 'whitelist_default_save_btn' }, _('Save')) + ]), + E('div', { 'style': 'margin-top: 8px; font-weight: 600;' }, _('Exempt Devices (Whitelist)')), + E('div', { 'class': 'whitelist-modal-list', 'id': 'whitelist_macs_list' }, [ + E('div', { 'style': 'text-align: center; opacity: 0.7; padding: 12px 0;' }, _('Loading...')) + ]), + E('div', { 'style': 'margin-top: 14px;' }, [ + E('div', { 'class': 'whitelist-modal-row', 'style': 'justify-content: flex-start;' }, [ + E('select', { 'class': 'cbi-input-select', 'id': 'whitelist_device_select', 'style': 'width: 200px; flex-shrink: 0;' }, [ + E('option', { 'value': '' }, _('Select Device')) + ]), + E('input', { 'type': 'text', 'class': 'form-input', 'id': 'whitelist_add_mac_input', 'placeholder': 'aa:bb:cc:dd:ee:ff', 'style': 'flex: 1;' }), + E('button', { 'class': 'cbi-button cbi-button-positive', 'id': 'whitelist_add_mac_btn', 'style': 'flex-shrink: 0;' }, _('Add')) + ]), + E('div', { 'class': 'whitelist-modal-error', 'id': 'whitelist-modal-error' }, '') + ]) + ]), + E('div', { 'class': 'whitelist-modal-footer' }, [ + E('button', { 'class': 'cbi-button cbi-button-reset', 'id': 'whitelist-modal-close' }, _('Close')) + ]) + ]) + ]); + + document.body.appendChild(whitelistModal); + + // ç¡®è®¤å¯¹è¯æ¡†ç›¸å…³å˜é‡ + var confirmDialogCallback = null; + + // æ˜¾ç¤ºç¡®è®¤å¯¹è¯æ¡† + function showConfirmDialog(title, message, onConfirm) { + document.getElementById('confirm-dialog-title').textContent = title || _('Confirm'); + document.getElementById('confirm-dialog-message').textContent = message || ''; + confirmDialogCallback = onConfirm; + + + confirmDialog.classList.add('show'); + } + + // éšè—ç¡®è®¤å¯¹è¯æ¡† + function hideConfirmDialog() { + confirmDialog.classList.remove('show'); + confirmDialogCallback = null; + } + + // ç¡®è®¤å¯¹è¯æ¡†äº‹ä»¶å¤„ç† + document.getElementById('confirm-dialog-confirm').addEventListener('click', function () { + if (confirmDialogCallback) { + confirmDialogCallback(); + } + hideConfirmDialog(); + }); + + document.getElementById('confirm-dialog-cancel').addEventListener('click', hideConfirmDialog); + + // ç‚¹å‡»ç¡®è®¤å¯¹è¯æ¡†èƒŒæ™¯å…³é—­ + confirmDialog.addEventListener('click', function (e) { + if (e.target === this) { + hideConfirmDialog(); + } + }); + + function parseWhitelistState(res) { + if (!res) return { enabled: false, macs: [] }; + if (res.success === false || res.error) { + throw new Error(res.error || _('Failed to load whitelist')); + } + if (res.status && res.status !== 'success') { + throw new Error(res.error || _('Failed to load whitelist')); + } + var data = res.data ? res.data : res; + return { + enabled: !!data.enabled, + macs: Array.isArray(data.macs) ? data.macs : [], + default_wan_rx_rate_limit: data.default_wan_rx_rate_limit, + default_wan_tx_rate_limit: data.default_wan_tx_rate_limit + }; + } + + function pickUnit(bytes) { + var n = parseFloat(bytes); + if (isNaN(n) || n < 0) return { value: '', unit: '1024' }; + if (n === 0) return { value: 0, unit: '1024' }; + + if (n >= 125000000 && Math.abs(n / 125000000 - Math.round(n / 125000000)) < 1e-9) return { value: Math.round(n / 125000000), unit: '125000000' }; + if (n >= 125000 && Math.abs(n / 125000 - Math.round(n / 125000)) < 1e-9) return { value: Math.round(n / 125000), unit: '125000' }; + if (n >= 125 && Math.abs(n / 125 - Math.round(n / 125)) < 1e-9) return { value: Math.round(n / 125), unit: '125' }; + + if (n >= 1073741824) return { value: +(n / 1073741824).toFixed(2), unit: '1073741824' }; + if (n >= 1048576) return { value: +(n / 1048576).toFixed(2), unit: '1048576' }; + return { value: +(n / 1024).toFixed(2), unit: '1024' }; + } + + function unitToBytes(valStr, unitStr) { + var v = parseFloat((valStr || '').trim()); + var u = parseFloat(unitStr); + if (isNaN(v) || v < 0 || isNaN(u) || u <= 0) return null; + return Math.round(v * u); + } + + function getDeviceLabel(d) { + var name = d && (d.host || d.name) ? (d.host || d.name) : ''; + var ip = d && d.ip4 ? d.ip4 : ''; + var mac = d && d.mac ? d.mac : ''; + var left = name || ip || mac || ''; + var right = mac && left !== mac ? (' ' + mac) : ''; + return (left + right).trim(); + } + + function populateWhitelistDeviceSelect() { + var sel = document.getElementById('whitelist_device_select'); + if (!sel) return; + + var keep = sel.value; + sel.innerHTML = ''; + sel.appendChild(E('option', { 'value': '' }, _('Select Device'))); + + var devices = []; + try { devices = (latestDevices && latestDevices.length) ? latestDevices : []; } catch (e) { devices = []; } + if (!devices.length) { + sel.value = ''; + return; + } + + devices.slice().sort(function (a, b) { + return getDeviceLabel(a).localeCompare(getDeviceLabel(b)); + }).forEach(function (d) { + if (!d || !d.mac) return; + sel.appendChild(E('option', { 'value': d.mac }, getDeviceLabel(d))); + }); + + sel.value = keep; + } + + function setWhitelistError(msg) { + var el = document.getElementById('whitelist-modal-error'); + if (!el) return; + if (msg) { + el.textContent = msg; + el.style.display = 'block'; + } else { + el.textContent = ''; + el.style.display = 'none'; + } + } + + function updateWhitelistBadge(state) { + var badge = view.querySelector('#bandix_whitelist_badge'); + if (!badge) return; + if (!state) { + badge.textContent = _('Unavailable'); + badge.style.backgroundColor = ''; + return; + } + var text = state.enabled ? _('Enabled') : _('Disabled'); + var count = (state.macs && state.macs.length) ? state.macs.length : 0; + badge.textContent = text + ' (' + count + ')'; + // badge.style.backgroundColor = state.enabled ? '#10b981' : '#6b7280'; + // badge.style.color = '#fff'; + } + + function renderWhitelistList(macs) { + var listEl = document.getElementById('whitelist_macs_list'); + if (!listEl) return; + listEl.innerHTML = ''; + + if (!macs || macs.length === 0) { + listEl.appendChild(E('div', { 'style': 'text-align: center; opacity: 0.7; padding: 12px 0;' }, _('No devices'))); + return; + } + + var deviceMap = {}; + try { + (latestDevices || []).forEach(function (d) { + if (d && d.mac) deviceMap[d.mac] = d; + }); + } catch (e) { deviceMap = {}; } + + macs.slice().sort().forEach(function (mac) { + var d = deviceMap[mac]; + var hostname = d && d.host ? d.host : ''; + var ip = d && d.ip4 ? d.ip4 : ''; + var title = hostname || ip || mac; + + var item = E('div', { 'class': 'whitelist-modal-item' }, [ + E('div', { 'style': 'display: flex; flex-direction: column; gap: 2px;' }, [ + E('div', { 'style': 'font-weight: 600;' }, title), + E('div', { 'style': 'font-size: 0.75rem; opacity: 0.7;' }, [ + ip ? (ip + ' · ') : '', + E('span', { 'class': 'whitelist-modal-mac' }, mac) + ]) + ]), + E('button', { 'class': 'cbi-button cbi-button-negative', 'style': 'padding: 4px 10px;' }, _('Delete')) + ]); + + item.querySelector('button').addEventListener('click', function () { + showConfirmDialog( + _('Delete'), + _('Remove this device from the list?'), + function () { + callDeleteRateLimitWhitelist(mac).then(function () { + return loadWhitelistModal(); + }).then(function () { + return refreshWhitelistStatus(); + }).catch(function (e) { + setWhitelistError(e && e.message ? e.message : _('Failed')); + }); + } + ); + }); + + listEl.appendChild(item); + }); + } + + function loadWhitelistModal() { + setWhitelistError(''); + var listEl = document.getElementById('whitelist_macs_list'); + if (listEl) listEl.innerHTML = '
' + _('Loading...') + '
'; + + return callGetRateLimitWhitelist().then(function (res) { + var state = parseWhitelistState(res); + var checkbox = document.getElementById('whitelist_enabled_checkbox'); + if (checkbox) checkbox.checked = !!state.enabled; + var rxEl = document.getElementById('whitelist_default_wan_rx'); + var txEl = document.getElementById('whitelist_default_wan_tx'); + var rxUnitEl = document.getElementById('whitelist_default_wan_rx_unit'); + var txUnitEl = document.getElementById('whitelist_default_wan_tx_unit'); + var rxPicked = pickUnit(state.default_wan_rx_rate_limit); + var txPicked = pickUnit(state.default_wan_tx_rate_limit); + if (rxEl) rxEl.value = (rxPicked.value !== '') ? String(rxPicked.value) : ''; + if (txEl) txEl.value = (txPicked.value !== '') ? String(txPicked.value) : ''; + if (rxUnitEl) rxUnitEl.value = rxPicked.unit; + if (txUnitEl) txUnitEl.value = txPicked.unit; + renderWhitelistList(state.macs); + return state; + }).catch(function (e) { + var msg = (e && e.message) ? e.message : _('Failed to load whitelist'); + setWhitelistError(msg); + if (listEl) listEl.innerHTML = '
' + _('Failed') + '
'; + return null; + }); + } + + function refreshWhitelistStatus() { + return callGetRateLimitWhitelist().then(function (res) { + var state = parseWhitelistState(res); + updateWhitelistBadge(state); + return state; + }).catch(function () { + updateWhitelistBadge(null); + return null; + }); + } + + function showWhitelistModal() { + whitelistModal.classList.add('show'); + populateWhitelistDeviceSelect(); + try { + var sel = document.getElementById('whitelist_device_select'); + if (sel && !sel.__bandixBound) { + sel.addEventListener('change', function () { + var macInput = document.getElementById('whitelist_add_mac_input'); + if (macInput && this.value) macInput.value = this.value; + }); + sel.__bandixBound = true; + } + } catch (e) { } + loadWhitelistModal(); + } + + function hideWhitelistModal() { + whitelistModal.classList.remove('show'); + setWhitelistError(''); + } + + document.getElementById('whitelist-modal-close').addEventListener('click', hideWhitelistModal); + + document.getElementById('whitelist_enabled_checkbox').addEventListener('change', function () { + var checkbox = this; + checkbox.disabled = true; + setWhitelistError(''); + callSetRateLimitWhitelistEnabled(checkbox.checked ? 1 : 0).then(function () { + return loadWhitelistModal(); + }).then(function () { + return refreshWhitelistStatus(); + }).catch(function (e) { + setWhitelistError(e && e.message ? e.message : _('Failed')); + }).finally(function () { + checkbox.disabled = false; + }); + }); + + document.getElementById('whitelist_add_mac_btn').addEventListener('click', function () { + var input = document.getElementById('whitelist_add_mac_input'); + if (!input) return; + var sel = document.getElementById('whitelist_device_select'); + var mac = (input.value || '').trim(); + if (!mac && sel && sel.value) mac = sel.value; + var macRe = /^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/; + if (!macRe.test(mac)) { + setWhitelistError(_('Invalid MAC address')); + return; + } + + var btn = this; + btn.disabled = true; + setWhitelistError(''); + + callAddRateLimitWhitelist(mac).then(function () { + input.value = ''; + if (sel) sel.value = ''; + return loadWhitelistModal(); + }).then(function () { + return refreshWhitelistStatus(); + }).catch(function (e) { + setWhitelistError(e && e.message ? e.message : _('Failed')); + }).finally(function () { + btn.disabled = false; + }); + }); + + document.getElementById('whitelist_default_save_btn').addEventListener('click', function () { + var rxEl = document.getElementById('whitelist_default_wan_rx'); + var txEl = document.getElementById('whitelist_default_wan_tx'); + var rxUnitEl = document.getElementById('whitelist_default_wan_rx_unit'); + var txUnitEl = document.getElementById('whitelist_default_wan_tx_unit'); + if (!rxEl || !txEl || !rxUnitEl || !txUnitEl) return; + + var rxBytes = unitToBytes(rxEl.value, rxUnitEl.value); + var txBytes = unitToBytes(txEl.value, txUnitEl.value); + if (rxBytes == null || txBytes == null) { + setWhitelistError(_('Invalid value')); + return; + } + + var btn = this; + btn.disabled = true; + setWhitelistError(''); + + callSetDefaultRateLimit(rxBytes, txBytes).then(function () { + return loadWhitelistModal(); + }).then(function () { + return refreshWhitelistStatus(); + }).catch(function (e) { + setWhitelistError(e && e.message ? e.message : _('Failed')); + }).finally(function () { + btn.disabled = false; + }); + }); + + // 日期选择按钮事件处ç†ï¼ˆæ·»åŠ è§„åˆ™æ¨¡æ€æ¡†ï¼‰ + var addRuleDayButtons = addRuleModal.querySelectorAll('.schedule-day-btn'); + addRuleDayButtons.forEach(function (btn) { + btn.addEventListener('click', function () { + this.classList.toggle('active'); + }); + }); + + // 显示添加/ç¼–è¾‘è§„åˆ™æ¨¡æ€æ¡† + function showAddRuleModal(rule) { + if (!currentDevice) return; + + editingRule = rule || null; + + var addRuleModalEl = document.getElementById('add-rule-bandix-modal'); + var modalTitle = addRuleModalEl.querySelector('.bandix-modal-title'); + var saveButton = document.getElementById('add-rule-save'); + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + + // 更新标题和按钮文本 + if (editingRule) { + modalTitle.textContent = _('Edit Schedule Rule'); + saveButton.textContent = _('Save'); + } else { + modalTitle.textContent = _('Add Schedule Rule'); + saveButton.textContent = _('Add'); + } + + // 动æ€å¡«å……å•ä½é€‰æ‹©å™¨ + var uploadUnitSelect = document.getElementById('add-rule-upload-limit-unit'); + var downloadUnitSelect = document.getElementById('add-rule-download-limit-unit'); + + uploadUnitSelect.innerHTML = ''; + downloadUnitSelect.innerHTML = ''; + + if (speedUnit === 'bits') { + uploadUnitSelect.appendChild(E('option', { 'value': '125' }, 'Kbps')); + uploadUnitSelect.appendChild(E('option', { 'value': '125000' }, 'Mbps')); + uploadUnitSelect.appendChild(E('option', { 'value': '125000000' }, 'Gbps')); + + downloadUnitSelect.appendChild(E('option', { 'value': '125' }, 'Kbps')); + downloadUnitSelect.appendChild(E('option', { 'value': '125000' }, 'Mbps')); + downloadUnitSelect.appendChild(E('option', { 'value': '125000000' }, 'Gbps')); + } else { + uploadUnitSelect.appendChild(E('option', { 'value': '1024' }, 'KB/s')); + uploadUnitSelect.appendChild(E('option', { 'value': '1048576' }, 'MB/s')); + uploadUnitSelect.appendChild(E('option', { 'value': '1073741824' }, 'GB/s')); + + downloadUnitSelect.appendChild(E('option', { 'value': '1024' }, 'KB/s')); + downloadUnitSelect.appendChild(E('option', { 'value': '1048576' }, 'MB/s')); + downloadUnitSelect.appendChild(E('option', { 'value': '1073741824' }, 'GB/s')); + } + + if (editingRule) { + // å¡«å……ç¼–è¾‘æ•°æ® + document.getElementById('add-rule-start-time').value = editingRule.time_slot && editingRule.time_slot.start ? editingRule.time_slot.start : '00:00'; + document.getElementById('add-rule-end-time').value = editingRule.time_slot && editingRule.time_slot.end ? editingRule.time_slot.end : '23:59'; + + // 设置选中的天数 + var dayButtons = addRuleModal.querySelectorAll('.schedule-day-btn'); + var selectedDays = editingRule.time_slot && editingRule.time_slot.days ? editingRule.time_slot.days : []; + dayButtons.forEach(function (btn) { + var day = parseInt(btn.getAttribute('data-day')); + if (selectedDays.indexOf(day) !== -1) { + btn.classList.add('active'); + } else { + btn.classList.remove('active'); + } + }); + + // 设置é™é€Ÿå€¼ + var uploadLimit = editingRule.wan_tx_rate_limit || 0; + var downloadLimit = editingRule.wan_rx_rate_limit || 0; + + // æ ¹æ®é™é€Ÿå€¼é€‰æ‹©åˆé€‚çš„å•ä½ + var uploadUnit, uploadValue, downloadUnit, downloadValue; + if (speedUnit === 'bits') { + if (uploadLimit >= 125000000 && uploadLimit % 125000000 === 0) { + uploadUnit = '125000000'; uploadValue = uploadLimit / 125000000; + } else if (uploadLimit >= 125000 && uploadLimit % 125000 === 0) { + uploadUnit = '125000'; uploadValue = uploadLimit / 125000; + } else { + uploadUnit = '125'; uploadValue = Math.round(uploadLimit / 125); + } + if (downloadLimit >= 125000000 && downloadLimit % 125000000 === 0) { + downloadUnit = '125000000'; downloadValue = downloadLimit / 125000000; + } else if (downloadLimit >= 125000 && downloadLimit % 125000 === 0) { + downloadUnit = '125000'; downloadValue = downloadLimit / 125000; + } else { + downloadUnit = '125'; downloadValue = Math.round(downloadLimit / 125); + } + } else { + if (uploadLimit >= 1073741824 && uploadLimit % 1073741824 === 0) { + uploadUnit = '1073741824'; uploadValue = uploadLimit / 1073741824; + } else if (uploadLimit >= 1048576 && uploadLimit % 1048576 === 0) { + uploadUnit = '1048576'; uploadValue = uploadLimit / 1048576; + } else { + uploadUnit = '1024'; uploadValue = Math.round(uploadLimit / 1024); + } + if (downloadLimit >= 1073741824 && downloadLimit % 1073741824 === 0) { + downloadUnit = '1073741824'; downloadValue = downloadLimit / 1073741824; + } else if (downloadLimit >= 1048576 && downloadLimit % 1048576 === 0) { + downloadUnit = '1048576'; downloadValue = downloadLimit / 1048576; + } else { + downloadUnit = '1024'; downloadValue = Math.round(downloadLimit / 1024); + } + } + + document.getElementById('add-rule-upload-limit-value').value = uploadValue; + document.getElementById('add-rule-upload-limit-unit').value = uploadUnit; + document.getElementById('add-rule-download-limit-value').value = downloadValue; + document.getElementById('add-rule-download-limit-unit').value = downloadUnit; + } else { + // é‡ç½®è¡¨å• + resetAddRuleForm(); + } + + // æ˜¾ç¤ºæ¨¡æ€æ¡† + addRuleModalEl.classList.add('show'); + } + + // éšè—æ·»åŠ è§„åˆ™æ¨¡æ€æ¡† + function hideAddRuleModal() { + var addRuleModalEl = document.getElementById('add-rule-bandix-modal'); + addRuleModalEl.classList.remove('show'); + editingRule = null; + } + + // é‡ç½®æ·»åŠ è§„åˆ™è¡¨å• + function resetAddRuleForm() { + document.getElementById('add-rule-start-time').value = '00:00'; + document.getElementById('add-rule-end-time').value = '23:59'; + // 默认选中所有7天 - 釿–°èŽ·å–æŒ‰é’®å¼•用 + var dayButtons = addRuleModal.querySelectorAll('.schedule-day-btn'); + dayButtons.forEach(function (btn) { + btn.classList.add('active'); + }); + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + document.getElementById('add-rule-upload-limit-value').value = '0'; + document.getElementById('add-rule-download-limit-value').value = '0'; + document.getElementById('add-rule-upload-limit-unit').value = speedUnit === 'bits' ? '125' : '1024'; + document.getElementById('add-rule-download-limit-unit').value = speedUnit === 'bits' ? '125' : '1024'; + } + + // æ·»åŠ è§„åˆ™æŒ‰é’®äº‹ä»¶å¤„ç† + var scheduleAddRuleBtn = document.getElementById('schedule-add-rule-btn'); + if (scheduleAddRuleBtn) { + scheduleAddRuleBtn.addEventListener('click', function () { + showAddRuleModal(); + }); + } + + // æ·»åŠ è§„åˆ™æ¨¡æ€æ¡†å–消按钮 + document.getElementById('add-rule-cancel').addEventListener('click', hideAddRuleModal); + + // ä¿å­˜å®šæ—¶é™é€Ÿè§„åˆ™ï¼ˆä»Žæ·»åŠ è§„åˆ™æ¨¡æ€æ¡†ï¼‰ + document.getElementById('add-rule-save').addEventListener('click', function () { + if (!currentDevice) { + console.error('No current device selected'); + return; + } + + var saveButton = this; + var originalText = saveButton.textContent; + + // æ˜¾ç¤ºåŠ è½½çŠ¶æ€ + saveButton.innerHTML = '' + _('Adding...'); + saveButton.classList.add('btn-loading'); + saveButton.disabled = true; + + var startTime = document.getElementById('add-rule-start-time').value; + var endTime = document.getElementById('add-rule-end-time').value; + + // 釿–°èŽ·å–æ—¥æœŸæŒ‰é’®å¼•用,确ä¿èŽ·å–æœ€æ–°çŠ¶æ€ + var addRuleModalEl = document.getElementById('add-rule-bandix-modal'); + var dayButtons = addRuleModalEl.querySelectorAll('.schedule-day-btn'); + var selectedDays = []; + dayButtons.forEach(function (btn) { + if (btn.classList.contains('active')) { + selectedDays.push(parseInt(btn.getAttribute('data-day'))); + } + }); + + if (!startTime || !endTime) { + ui.addNotification(null, E('p', {}, _('Please set time slot')), 'error'); + saveButton.innerHTML = originalText; + saveButton.classList.remove('btn-loading'); + saveButton.disabled = false; + return; + } + + if (selectedDays.length === 0) { + ui.addNotification(null, E('p', {}, _('Please select at least one day')), 'error'); + saveButton.innerHTML = originalText; + saveButton.classList.remove('btn-loading'); + saveButton.disabled = false; + return; + } + + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + var scheduleUploadValue = parseInt(document.getElementById('add-rule-upload-limit-value').value) || 0; + var scheduleUploadUnit = parseInt(document.getElementById('add-rule-upload-limit-unit').value); + var scheduleUploadLimit = scheduleUploadValue > 0 ? scheduleUploadValue * scheduleUploadUnit : 0; + + var scheduleDownloadValue = parseInt(document.getElementById('add-rule-download-limit-value').value) || 0; + var scheduleDownloadUnit = parseInt(document.getElementById('add-rule-download-limit-unit').value); + var scheduleDownloadLimit = scheduleDownloadValue > 0 ? scheduleDownloadValue * scheduleDownloadUnit : 0; + + var apiCall; + if (editingRule) { + console.log('Calling updateScheduleLimit:', { + id: editingRule.id, + mac: currentDevice.mac, + startTime: startTime, + endTime: endTime, + days: selectedDays, + downloadLimit: scheduleDownloadLimit, + uploadLimit: scheduleUploadLimit + }); + apiCall = callUpdateScheduleLimit( + editingRule.id, + currentDevice.mac, + startTime, + endTime, + JSON.stringify(selectedDays), + scheduleDownloadLimit, + scheduleUploadLimit + ); + } else { + console.log('Calling setScheduleLimit:', { + mac: currentDevice.mac, + startTime: startTime, + endTime: endTime, + days: selectedDays, + uploadLimit: scheduleUploadLimit, + downloadLimit: scheduleDownloadLimit + }); + apiCall = callSetScheduleLimit( + currentDevice.mac, + startTime, + endTime, + JSON.stringify(selectedDays), + scheduleUploadLimit, + scheduleDownloadLimit + ); + } + + apiCall.then(function (result) { + console.log('Schedule limit result:', result); + saveButton.innerHTML = originalText; + saveButton.classList.remove('btn-loading'); + saveButton.disabled = false; + + hideAddRuleModal(); + resetAddRuleForm(); + editingRule = null; + + loadScheduleRules(); + updateDeviceData(); + }).catch(function (error) { + console.error('Failed to save schedule rule:', error); + saveButton.innerHTML = originalText; + saveButton.classList.remove('btn-loading'); + saveButton.disabled = false; + ui.addNotification(null, E('p', {}, _('Failed to save schedule rule: ') + (error.message || error)), 'error'); + }); + }); + + // æ¨¡æ€æ¡†äº‹ä»¶å¤„ç† + var currentDevice = null; + var editingRule = null; + var showRateLimitModal; + + // æ˜¾ç¤ºæ¨¡æ€æ¡† + showRateLimitModal = function (device) { + currentDevice = device; + var bandixModal = document.getElementById('rate-limit-bandix-modal'); + var deviceSummary = document.getElementById('bandix-modal-device-summary'); + // 清空定时é™é€Ÿè§„则列表并加载 + var rulesList = document.getElementById('schedule-rules-list'); + if (rulesList) { + rulesList.innerHTML = '
' + + _('No scheduled rules yet, click "Add Rule" to start setting') + + '
'; + } + + // 加载定时é™é€Ÿè§„则列表 + loadScheduleRules(); + + var modalContent = [ + E('div', { 'class': 'device-summary-name' }, device.host || device.ip4), + E('div', { 'class': 'device-summary-details' }, device.ip4 + ' (' + device.mac + ')') + ]; + var modalBadges = buildDeviceUplinkChBadges(device); + if (modalBadges.length) { + modalContent.push(E('div', { 'class': 'device-summary-badges device-uplink-badges-wrap' }, modalBadges)); + } + deviceSummary.innerHTML = E('div', {}, modalContent).innerHTML; + + // 设置当å‰hostname值 + document.getElementById('device-hostname-input').value = device.host || ''; + + + // æ˜¾ç¤ºæ¨¡æ€æ¡†å¹¶æ·»åŠ åŠ¨ç”» + bandixModal.classList.add('show'); + } + + // éšè—æ¨¡æ€æ¡† + function hideRateLimitModal() { + var bandixModal = document.getElementById('rate-limit-bandix-modal'); + bandixModal.classList.remove('show'); + + // 等待动画完æˆåŽæ¸…ç† + setTimeout(function () { + currentDevice = null; + }, 300); + } + + // 加载定时é™é€Ÿè§„则列表 + function loadScheduleRules() { + if (!currentDevice) return; + + var rulesList = document.getElementById('schedule-rules-list'); + if (!rulesList) return; + + rulesList.innerHTML = '
' + _('Loading...') + '
'; + + callGetScheduleLimits().then(function (res) { + // 检查å“åº”æ ¼å¼ + if (!res) { + rulesList.innerHTML = '
' + _('No schedule rules') + '
'; + return; + } + + // æ£€æŸ¥æ˜¯å¦æœ‰é”™è¯¯ + if (res.success === false || res.error) { + var errorMsg = res.error || _('Failed to load schedule rules'); + rulesList.innerHTML = '
' + errorMsg + '
'; + return; + } + + // æ£€æŸ¥æ•°æ®æ ¼å¼ + var limits = []; + if (res.data && res.data.limits && Array.isArray(res.data.limits)) { + limits = res.data.limits; + } else if (Array.isArray(res.limits)) { + // 兼容ä¸åŒçš„å“åº”æ ¼å¼ + limits = res.limits; + } else if (Array.isArray(res)) { + // 如果直接返回数组 + limits = res; + } + + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + + // 过滤出当å‰è®¾å¤‡çš„规则 + var deviceRules = limits.filter(function (rule) { + return rule && rule.mac === currentDevice.mac; + }); + + // 清空列表 + rulesList.innerHTML = ''; + + if (deviceRules.length === 0) { + rulesList.innerHTML = '
' + + _('No scheduled rules yet, click "Add Rule" to start setting') + + '
'; + return; + } + + // 显示所有规则(支æŒå¤šä¸ªè§„则) + deviceRules.forEach(function (rule) { + var daysText = ''; + // days 范围是 1-7 (Monday-Sunday) + var dayNames = { + 1: _('Mon'), + 2: _('Tue'), + 3: _('Wed'), + 4: _('Thu'), + 5: _('Fri'), + 6: _('Sat'), + 7: _('Sun') + }; + if (rule.time_slot && rule.time_slot.days && Array.isArray(rule.time_slot.days)) { + daysText = rule.time_slot.days.map(function (d) { return dayNames[d] || d; }).join(', '); + } + + var startTime = rule.time_slot && rule.time_slot.start ? rule.time_slot.start : ''; + var endTime = rule.time_slot && rule.time_slot.end ? rule.time_slot.end : ''; + var uploadLimit = rule.wan_tx_rate_limit || 0; + var downloadLimit = rule.wan_rx_rate_limit || 0; + + var ruleItem = E('div', { 'class': 'schedule-rule-item' }, [ + E('div', { 'class': 'schedule-rule-info' }, [ + E('div', { 'class': 'schedule-rule-time' }, startTime + ' - ' + endTime), + E('div', { 'class': 'schedule-rule-days' }, daysText), + E('div', { 'class': 'schedule-rule-limits' }, + '↑ ' + formatByterate(uploadLimit, speedUnit) + + ' / ↓ ' + formatByterate(downloadLimit, speedUnit) + ) + ]), + E('div', { 'class': 'schedule-rule-actions' }, [ + E('button', { + 'class': 'schedule-rule-edit', + 'title': _('Edit') + }, _('Edit')), + E('button', { + 'class': 'schedule-rule-delete', + 'title': _('Delete') + }, _('Delete')) + ]) + ]); + + ruleItem.querySelector('.schedule-rule-edit').addEventListener('click', function () { + showAddRuleModal(rule); + }); + + ruleItem.querySelector('.schedule-rule-delete').addEventListener('click', function () { + showConfirmDialog( + _('Delete Schedule Rule'), + _('Are you sure you want to delete this schedule rule?'), + function () { + callDeleteScheduleLimit(rule.id).then(function () { + loadScheduleRules(); + updateDeviceData(); + }).catch(function (error) { + ui.addNotification(null, E('p', {}, _('Failed to delete schedule rule')), 'error'); + }); + } + ); + }); + + rulesList.appendChild(ruleItem); + }); + }).catch(function (error) { + console.error('Failed to load schedule rules:', error); + var errorMsg = _('Failed to load schedule rules'); + if (error && error.message) { + errorMsg += ': ' + error.message; + } + rulesList.innerHTML = '
' + errorMsg + '
'; + }); + } + + // ä¿å­˜ hostname + function saveHostname() { + if (!currentDevice) return; + + var saveButton = document.getElementById('hostname-save-btn'); + var originalText = saveButton.textContent; + + // 获å–hostname值 + var newHostname = document.getElementById('device-hostname-input').value.trim(); + + // 如果hostname没有å˜åŒ–,ä¸éœ€è¦ä¿å­˜ + if (newHostname === (currentDevice.host || '')) { + return; + } + + // æ˜¾ç¤ºåŠ è½½çŠ¶æ€ + saveButton.innerHTML = '' + _('Saving...'); + saveButton.classList.add('btn-loading'); + saveButton.disabled = true; + + callSetHostname(currentDevice.mac, newHostname).then(function (result) { + // æ¢å¤æŒ‰é’®çŠ¶æ€ + saveButton.innerHTML = originalText; + saveButton.classList.remove('btn-loading'); + saveButton.disabled = false; + + // 更新当å‰è®¾å¤‡ä¿¡æ¯ + currentDevice.host = newHostname; + + // åˆ·æ–°è®¾å¤‡æ•°æ® + updateDeviceData(); + }).catch(function (error) { + // æ¢å¤æŒ‰é’®çŠ¶æ€ + saveButton.innerHTML = originalText; + saveButton.classList.remove('btn-loading'); + saveButton.disabled = false; + ui.addNotification(null, E('p', {}, _('Failed to set hostname')), 'error'); + }); + } + + // 绑定 hostname ä¿å­˜æŒ‰é’®äº‹ä»¶ + document.getElementById('hostname-save-btn').addEventListener('click', saveHostname); + + // 绑定关闭按钮事件 + document.getElementById('bandix-modal-close').addEventListener('click', hideRateLimitModal); + + // 历å²è¶‹åŠ¿ï¼šçŠ¶æ€ä¸Žå·¥å…· + var latestDevices = []; + var lastHistoryData = null; // 最近一次拉å–的原始 metrics æ•°æ® + var isHistoryLoading = false; // 防止轮询é‡å…¥ + + // 定时é™é€Ÿè§„则:全局存储 + var allScheduleRules = []; // 存储所有设备的定时é™é€Ÿè§„则 + var isScheduleRulesLoading = false; // 防止轮询é‡å…¥ + + // èŽ·å–æ‰€æœ‰å®šæ—¶é™é€Ÿè§„则 + function fetchAllScheduleRules() { + if (isScheduleRulesLoading) return Promise.resolve(); + isScheduleRulesLoading = true; + + return callGetScheduleLimits().then(function (res) { + isScheduleRulesLoading = false; + + if (!res) { + allScheduleRules = []; + return; + } + + // æ£€æŸ¥æ˜¯å¦æœ‰é”™è¯¯ + if (res.success === false || res.error) { + allScheduleRules = []; + return; + } + + // æ£€æŸ¥æ•°æ®æ ¼å¼ + var limits = []; + if (res.data && res.data.limits && Array.isArray(res.data.limits)) { + limits = res.data.limits; + } else if (Array.isArray(res.limits)) { + limits = res.limits; + } else if (Array.isArray(res)) { + limits = res; + } + + allScheduleRules = limits || []; + }).catch(function (error) { + isScheduleRulesLoading = false; + console.error('Failed to fetch schedule rules:', error); + allScheduleRules = []; + }); + } + + // 判断规则是å¦åœ¨å½“剿—¶é—´ç”Ÿæ•ˆ + function isRuleActive(rule) { + if (!rule || !rule.time_slot) return false; + + var now = new Date(); + var currentDay = now.getDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday + // 转æ¢ä¸º 1-7 (Monday-Sunday) + var dayOfWeek = currentDay === 0 ? 7 : currentDay; + + // 检查是å¦åœ¨è§„则指定的日期中 + var days = rule.time_slot.days || []; + if (!Array.isArray(days) || days.length === 0) return false; + if (days.indexOf(dayOfWeek) === -1) return false; + + // 获å–当剿—¶é—´ï¼ˆHH:MMæ ¼å¼ï¼‰ + var currentTime = ('0' + now.getHours()).slice(-2) + ':' + ('0' + now.getMinutes()).slice(-2); + var startTime = rule.time_slot.start || ''; + var endTime = rule.time_slot.end || ''; + + if (!startTime || !endTime) return false; + + // 比较时间 + if (startTime <= endTime) { + // 正常情况:开始时间 <= ç»“æŸæ—¶é—´ + return currentTime >= startTime && currentTime <= endTime; + } else { + // 跨天情况:开始时间 > ç»“æŸæ—¶é—´ï¼ˆä¾‹å¦‚ 22:00 - 06:00) + return currentTime >= startTime || currentTime <= endTime; + } + } + + // 获å–设备当å‰ç”Ÿæ•ˆçš„规则 + function getActiveRulesForDevice(mac) { + if (!allScheduleRules || allScheduleRules.length === 0) return []; + + return allScheduleRules.filter(function (rule) { + return rule && rule.mac === mac && isRuleActive(rule); + }); + } + + // åˆå¹¶å¤šä¸ªç”Ÿæ•ˆè§„则的é™åˆ¶å€¼ + // 返回åˆå¹¶åŽçš„上传和下载é™åˆ¶ï¼ˆå–所有规则中éžé›¶çš„æœ€å°å€¼ï¼‰ + function mergeActiveRulesLimits(activeRules) { + if (!activeRules || activeRules.length === 0) { + return { uploadLimit: 0, downloadLimit: 0 }; + } + + var uploadLimits = []; + var downloadLimits = []; + + activeRules.forEach(function (rule) { + var uploadLimit = rule.wan_tx_rate_limit || 0; + var downloadLimit = rule.wan_rx_rate_limit || 0; + + // åªæ”¶é›†éžé›¶çš„é™åˆ¶å€¼ + if (uploadLimit > 0) { + uploadLimits.push(uploadLimit); + } + if (downloadLimit > 0) { + downloadLimits.push(downloadLimit); + } + }); + + // å–æœ€å°å€¼ï¼ˆå¦‚果有多个规则都有é™åˆ¶ï¼Œå–最严格的é™åˆ¶ï¼‰ + var mergedUploadLimit = uploadLimits.length > 0 ? Math.min.apply(Math, uploadLimits) : 0; + var mergedDownloadLimit = downloadLimits.length > 0 ? Math.min.apply(Math, downloadLimits) : 0; + + return { + uploadLimit: mergedUploadLimit, + downloadLimit: mergedDownloadLimit + }; + } + + // 获å–多个规则的时间段显示文本 + // 如果所有规则的时间段相åŒï¼Œæ˜¾ç¤ºæ—¶é—´æ®µï¼›å¦‚æžœä¸åŒï¼Œæ˜¾ç¤º"多个时间段" + function getTimeSlotDisplayText(activeRules) { + if (!activeRules || activeRules.length === 0) { + return ''; + } + + if (activeRules.length === 1) { + // å•个规则,直接显示时间段 + var rule = activeRules[0]; + var startTime = rule.time_slot && rule.time_slot.start ? rule.time_slot.start : ''; + var endTime = rule.time_slot && rule.time_slot.end ? rule.time_slot.end : ''; + return startTime + '-' + endTime; + } + + // 多个规则,检查时间段是å¦ç›¸åŒ + var firstRule = activeRules[0]; + var firstStartTime = firstRule.time_slot && firstRule.time_slot.start ? firstRule.time_slot.start : ''; + var firstEndTime = firstRule.time_slot && firstRule.time_slot.end ? firstRule.time_slot.end : ''; + + var allSame = true; + for (var i = 1; i < activeRules.length; i++) { + var rule = activeRules[i]; + var startTime = rule.time_slot && rule.time_slot.start ? rule.time_slot.start : ''; + var endTime = rule.time_slot && rule.time_slot.end ? rule.time_slot.end : ''; + + if (startTime !== firstStartTime || endTime !== firstEndTime) { + allSame = false; + break; + } + } + + if (allSame) { + // 所有规则时间段相åŒï¼Œæ˜¾ç¤ºæ—¶é—´æ®µå’Œè§„åˆ™æ•°é‡ + return firstStartTime + '-' + firstEndTime + ' (' + activeRules.length + ' ' + _('rules') + ')'; + } else { + // 时间段ä¸åŒï¼Œæ˜¾ç¤º"多个时间段" + return _('Multiple time slots') + ' (' + activeRules.length + ' ' + _('rules') + ')'; + } + } + + // 排åºçжæ€ç®¡ç† + var currentSortBy = localStorage.getItem('bandix_sort_by') || 'online'; // é»˜è®¤æŒ‰åœ¨çº¿çŠ¶æ€æŽ’åº + var currentSortOrder = localStorage.getItem('bandix_sort_order') === 'true'; // false = é™åº, true = å‡åº + // 当鼠标悬åœåœ¨åކå²å›¾è¡¨ä¸Šæ—¶ï¼Œç½®ä¸º true,轮询将暂åœåˆ·æ–°ï¼ˆå®žçް"鼠标在趋势图上时ä¸è‡ªåŠ¨æ»šåŠ¨") + var historyHover = false; + // é¼ æ ‡æ‚¬åœæ—¶çš„索引(独立于 canvas.__bandixChart,é¿å…é‡ç»˜è¦†ç›–问题) + var historyHoverIndex = null; + // 缩放功能相关å˜é‡ + var zoomEnabled = false; // 缩放是å¦å¯ç”¨ + var zoomScale = 1; // 缩放比例 + var zoomOffsetX = 0; // Xè½´åç§» + var zoomTimer = null; // 延迟å¯ç”¨ç¼©æ”¾çš„计时器 + + function updateDeviceOptions(devices) { + var select = document.getElementById('history-device-select'); + if (!select) return; + + // 对设备列表进行排åºï¼šåœ¨çº¿è®¾å¤‡åœ¨å‰ï¼Œç¦»çº¿è®¾å¤‡åœ¨åŽï¼Œç„¶åŽæŒ‰IP地å€ä»Žå°åˆ°å¤§æŽ’åº + var sortedDevices = devices.slice().sort(function (a, b) { + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + + // é¦–å…ˆæŒ‰åœ¨çº¿çŠ¶æ€æŽ’åºï¼šåœ¨çº¿è®¾å¤‡åœ¨å‰ + if (aOnline && !bOnline) return -1; + if (!aOnline && bOnline) return 1; + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åº + var aIp = a.ip4 || ''; + var bIp = b.ip4 || ''; + + // å°†IP地å€è½¬æ¢ä¸ºæ•°å­—进行比较 + var aIpParts = aIp.split('.').map(function (part) { return parseInt(part) || 0; }); + var bIpParts = bIp.split('.').map(function (part) { return parseInt(part) || 0; }); + + // 逿®µæ¯”较IPåœ°å€ + for (var i = 0; i < 4; i++) { + var aPart = aIpParts[i] || 0; + var bPart = bIpParts[i] || 0; + if (aPart !== bPart) { + return aPart - bPart; + } + } + + // IP地å€ç›¸åŒæ—¶ï¼ŒæŒ‰MACåœ°å€æŽ’åº + return (a.mac || '').localeCompare(b.mac || ''); + }); + + // 对比是å¦éœ€è¦æ›´æ–° + var currentValues = Array.from(select.options).map(o => o.value); + var desiredValues = [''].concat(sortedDevices.map(d => d.mac)); + var same = currentValues.length === desiredValues.length && currentValues.every((v, i) => v === desiredValues[i]); + if (same) return; + + var prev = select.value; + // é‡å»ºé€‰é¡¹ + select.innerHTML = ''; + select.appendChild(E('option', { 'value': '' }, _('All Devices'))); + sortedDevices.forEach(function (d) { + var label = (d.host || d.ip4 || d.mac || '-') + (d.ip4 ? ' (' + d.ip4 + ')' : '') + (d.mac ? ' [' + d.mac + ']' : ''); + select.appendChild(E('option', { 'value': d.mac }, label)); + }); + // å°½é‡ä¿ç•™ä¹‹å‰é€‰æ‹© + if (desiredValues.indexOf(prev) !== -1) select.value = prev; + } + + function getTypeKeys(type) { + if (type === 'lan') return { up: 'lan_tx_rate', down: 'lan_rx_rate' }; + if (type === 'wan') return { up: 'wan_tx_rate', down: 'wan_rx_rate' }; + return { up: 'total_tx_rate', down: 'total_rx_rate' }; + } + + // 历å²å›¾è¡¨ä½¿ç”¨å®žæ—¶æ•°æ® + + function fetchMetricsData(mac) { + // 通过 ubus RPC 获å–,é¿å…跨域与鉴æƒé—®é¢˜ + return callGetMetrics(mac || '').then(function (res) { return res || { metrics: [] }; }); + } + + // 将数组数组格å¼è½¬æ¢ä¸ºå¯¹è±¡æ•°ç»„æ ¼å¼ï¼ˆå®žæ—¶æ•°æ®æ ¼å¼ï¼š13个字段) + // 输入格å¼: [[ts_ms, total_rx_rate, total_tx_rate, lan_rx_rate, lan_tx_rate, wan_rx_rate, wan_tx_rate, total_rx_bytes, total_tx_bytes, lan_rx_bytes, lan_tx_bytes, wan_rx_bytes, wan_tx_bytes], ...] + // 输出格å¼: [{ts_ms, total_rx_rate, total_tx_rate, ...}, ...] + function convertMetricsArrayToObjects(metricsArray) { + if (!Array.isArray(metricsArray)) { + return []; + } + + return metricsArray.map(function (arr) { + // å®žæ—¶æ•°æ®æ ¼å¼ï¼ˆ13个字段) + return { + ts_ms: arr[0] || 0, + total_rx_rate: arr[1] || 0, + total_tx_rate: arr[2] || 0, + lan_rx_rate: arr[3] || 0, + lan_tx_rate: arr[4] || 0, + wan_rx_rate: arr[5] || 0, + wan_tx_rate: arr[6] || 0, + total_rx_bytes: arr[7] || 0, + total_tx_bytes: arr[8] || 0, + lan_rx_bytes: arr[9] || 0, + lan_tx_bytes: arr[10] || 0, + wan_rx_bytes: arr[11] || 0, + wan_tx_bytes: arr[12] || 0, + is_aggregated: false + }; + }).filter(function (item) { return item !== null; }); + } + + // 辅助函数:使用当å‰ç¼©æ”¾è®¾ç½®ç»˜åˆ¶å›¾è¡¨ + function drawHistoryChartWithZoom(canvas, labels, upSeries, downSeries) { + drawHistoryChart(canvas, labels, upSeries, downSeries, zoomScale, zoomOffsetX); + } + + // 更新缩放å€çŽ‡æ˜¾ç¤º + function updateZoomLevelDisplay() { + var zoomLevelElement = document.getElementById('history-zoom-level'); + if (!zoomLevelElement) return; + + // 默认éšè— zoom 显示(窄主题样å¼ï¼‰ + zoomLevelElement.style.display = 'none'; + return; + + if (zoomScale <= 1) { + zoomLevelElement.style.display = 'none'; + } else { + zoomLevelElement.style.display = 'inline-block'; + zoomLevelElement.textContent = _('Zoom') + ': ' + zoomScale.toFixed(1) + 'x'; + } + } + + function drawHistoryChart(canvas, labels, upSeries, downSeries, scale, offsetX) { + if (!canvas) return; + + // ç¼©æ”¾å‚æ•°é»˜è®¤å€¼ + scale = scale || 1; + offsetX = offsetX || 0; + + var dpr = window.devicePixelRatio || 1; + var rect = canvas.getBoundingClientRect(); + var cssWidth = rect.width; + var cssHeight = rect.height; + canvas.width = Math.max(1, Math.floor(cssWidth * dpr)); + canvas.height = Math.max(1, Math.floor(cssHeight * dpr)); + var ctx = canvas.getContext('2d'); + ctx.scale(dpr, dpr); + + var width = cssWidth; + var height = cssHeight; + + // 检测是å¦ä¸ºç§»åŠ¨ç«¯ + var isMobile = width <= 768; + + // 预留更大边è·ï¼Œé¿å…标签被è£å‰ªï¼ˆç§»åŠ¨ç«¯ä½¿ç”¨æ›´å°çš„è¾¹è·ï¼‰ + var padding = isMobile + ? { left: 50, right: 20, top: 12, bottom: 28 } + : { left: 90, right: 50, top: 16, bottom: 36 }; + + // 背景 + ctx.clearRect(0, 0, width, height); + + // æ ¹æ®ç¼©æ”¾å’Œåç§»å¤„ç†æ•°æ® + var originalLabels = labels; + var originalUpSeries = upSeries; + var originalDownSeries = downSeries; + + if (scale > 1) { + var totalLen = labels.length; + var visibleLen = Math.ceil(totalLen / scale); + var startIdx = Math.max(0, Math.floor(offsetX)); + var endIdx = Math.min(totalLen, startIdx + visibleLen); + + labels = labels.slice(startIdx, endIdx); + upSeries = upSeries.slice(startIdx, endIdx); + downSeries = downSeries.slice(startIdx, endIdx); + } + + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + var maxVal = 0; + for (var i = 0; i < upSeries.length; i++) maxVal = Math.max(maxVal, upSeries[i] || 0); + for (var j = 0; j < downSeries.length; j++) maxVal = Math.max(maxVal, downSeries[j] || 0); + if (!isFinite(maxVal) || maxVal <= 0) maxVal = 1; + + // åŠ¨æ€æµ‹é‡Yè½´æœ€å¤§æ ‡ç­¾å®½åº¦ï¼Œå¢žå¤§å·¦è¾¹è· + var fontSize = isMobile ? 10 : 12; + ctx.font = fontSize + 'px sans-serif'; + var maxLabelText = formatByterate(maxVal, speedUnit); + var zeroLabelText = formatByterate(0, speedUnit); + var maxLabelWidth = Math.max(ctx.measureText(maxLabelText).width, ctx.measureText(zeroLabelText).width); + padding.left = Math.max(padding.left, Math.ceil(maxLabelWidth) + (isMobile ? 20 : 30)); + // ä¿è¯å³ä¾§æ—¶é—´ä¸è¢«è£å‰ª + var rightMin = isMobile ? 20 : 50; // 最å°å³è¾¹è· + padding.right = Math.max(padding.right, rightMin); + + var innerW = Math.max(1, width - padding.left - padding.right); + var innerH = Math.max(1, height - padding.top - padding.bottom); + + // 记录用于交互的几何信æ¯ï¼›ä¿ç•™å·²æœ‰çš„ hoverIndex é¿å…在é‡ç»˜æ—¶ä¸¢å¤± + var prevHover = (canvas.__bandixChart && typeof canvas.__bandixChart.hoverIndex === 'number') ? canvas.__bandixChart.hoverIndex : undefined; + canvas.__bandixChart = { + padding: padding, + innerW: innerW, + innerH: innerH, + width: width, + height: height, + labels: labels, + upSeries: upSeries, + downSeries: downSeries, + // ç¼©æ”¾ç›¸å…³ä¿¡æ¯ + scale: scale, + offsetX: offsetX, + originalLabels: originalLabels, + originalUpSeries: originalUpSeries, + originalDownSeries: originalDownSeries + }; + if (typeof prevHover === 'number') canvas.__bandixChart.hoverIndex = prevHover; + + // 网格与Y轴刻度(更细更淡) + var gridLines = 4; + ctx.strokeStyle = 'rgba(148,163,184,0.08)'; + ctx.lineWidth = 0.8; + for (var g = 0; g <= gridLines; g++) { + var y = padding.top + (innerH * g / gridLines); + ctx.beginPath(); + ctx.moveTo(padding.left, y); + ctx.lineTo(width - padding.right, y); + ctx.stroke(); + var val = Math.round(maxVal * (gridLines - g) / gridLines); + ctx.fillStyle = '#9ca3af'; + ctx.font = fontSize + 'px sans-serif'; + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + var yLabelY = (g === gridLines) ? y - 4 : y; // 底部刻度上移,é¿å…è´´è¿‘Xè½´ + ctx.fillText(formatByterate(val, speedUnit), padding.left - (isMobile ? 6 : 8), yLabelY); + } + + function drawAreaSeries(series, color, gradientFrom, gradientTo) { + if (!series || series.length === 0) return; + var n = series.length; + var stepX = n > 1 ? (innerW / (n - 1)) : 0; + + // 先绘制填充区域路径 + ctx.beginPath(); + for (var k = 0; k < n; k++) { + var v = Math.max(0, series[k] || 0); + var x = padding.left + (n > 1 ? stepX * k : innerW / 2); + var y = padding.top + innerH - (v / maxVal) * innerH; + if (k === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); + } + // 关闭到底部以形æˆåŒºåŸŸ + ctx.lineTo(padding.left + innerW, padding.top + innerH); + ctx.lineTo(padding.left, padding.top + innerH); + ctx.closePath(); + + // 创建æ¸å˜å¡«å…… + var grad = ctx.createLinearGradient(0, padding.top, 0, padding.top + innerH); + grad.addColorStop(0, gradientFrom); + grad.addColorStop(1, gradientTo); + ctx.fillStyle = grad; + ctx.fill(); + + // ç„¶åŽç»˜åˆ¶ç»†çº¿ + ctx.beginPath(); + for (var k2 = 0; k2 < n; k2++) { + var v2 = Math.max(0, series[k2] || 0); + var x2 = padding.left + (n > 1 ? stepX * k2 : innerW / 2); + var y2 = padding.top + innerH - (v2 / maxVal) * innerH; + if (k2 === 0) ctx.moveTo(x2, y2); else ctx.lineTo(x2, y2); + } + ctx.strokeStyle = color; + // 移动端使用ç¨ç²—的线æ¡ä»¥ä¾¿æ›´å¥½åœ°æ˜¾ç¤º + ctx.lineWidth = isMobile ? 1.5 : 1.2; + ctx.stroke(); + + // 圆点已移除,åªä¿ç•™çº¿æ¡ + } + + // 橙色上行,é’色下行,使用åŠé€æ˜Žæ¸å˜ + drawAreaSeries(upSeries, BANDIX_COLOR_UPLOAD, 'rgba(249,115,22,0.16)', 'rgba(249,115,22,0.02)'); + drawAreaSeries(downSeries, BANDIX_COLOR_DOWNLOAD, 'rgba(6,182,212,0.12)', 'rgba(6,182,212,0.02)'); + + // X 轴时间标签(首尾) + if (labels && labels.length > 0) { + ctx.fillStyle = '#9ca3af'; + ctx.font = fontSize + 'px sans-serif'; + ctx.textBaseline = 'top'; + var firstX = padding.left; + var lastX = width - padding.right; + var yBase = height - padding.bottom + (isMobile ? 2 : 4); + // 左侧时间é å·¦å¯¹é½ + ctx.textAlign = 'left'; + ctx.fillText(labels[0], firstX, yBase); + // å³ä¾§æ—¶é—´é å³å¯¹é½ï¼Œé¿å…被è£å‰ª + if (labels.length > 1) { + ctx.textAlign = 'right'; + ctx.fillText(labels[labels.length - 1], lastX, yBase); + } + } + + // 如果存在 hoverIndex,则绘制垂直虚线(鼠标对ç€çš„ x 轴) + // 移动端ä¸ç»˜åˆ¶è™šçº¿ + try { + if (isMobile) return; // 移动端ä¸ç»˜åˆ¶æ‚¬æµ®è™šçº¿ + + var info = canvas.__bandixChart || {}; + var useIdx = null; + if (typeof historyHoverIndex === 'number') useIdx = historyHoverIndex; + else if (typeof info.hoverIndex === 'number') useIdx = info.hoverIndex; + if (useIdx !== null && info.labels && info.labels.length > 0) { + var n = info.labels.length; + var stepX = n > 1 ? (innerW / (n - 1)) : 0; + var hoverIdx = useIdx; + + // 在缩放状æ€ä¸‹ï¼Œéœ€è¦å°†åŽŸå§‹ç´¢å¼•è½¬æ¢ä¸ºæ˜¾ç¤ºç´¢å¼• + if (scale > 1 && originalLabels && originalLabels.length > 0) { + var startIdx = Math.floor(offsetX || 0); + hoverIdx = useIdx - startIdx; + // 检查索引是å¦åœ¨å½“剿˜¾ç¤ºèŒƒå›´å†… + if (hoverIdx < 0 || hoverIdx >= n) { + hoverIdx = null; // ä¸åœ¨æ˜¾ç¤ºèŒƒå›´å†…,ä¸ç»˜åˆ¶è™šçº¿ + } + } + + if (hoverIdx !== null) { + hoverIdx = Math.max(0, Math.min(n - 1, hoverIdx)); + var hoverX = info.padding.left + (n > 1 ? stepX * hoverIdx : innerW / 2); + ctx.save(); + ctx.strokeStyle = 'rgba(156,163,175,0.9)'; + ctx.lineWidth = 1; + ctx.setLineDash([6, 4]); + ctx.beginPath(); + ctx.moveTo(hoverX, padding.top); + ctx.lineTo(hoverX, padding.top + innerH); + ctx.stroke(); + ctx.setLineDash([]); + ctx.restore(); + } + } + } catch (e) { /* 安全兜底 */ } + } + + function msToTimeLabel(ts) { + var d = new Date(ts); + var hh = ('' + d.getHours()).padStart(2, '0'); + var mm = ('' + d.getMinutes()).padStart(2, '0'); + var ss = ('' + d.getSeconds()).padStart(2, '0'); + return hh + ':' + mm + ':' + ss; + } + + // 完整日期时间格å¼ï¼ˆç”¨äºŽèšåˆæ•°æ®ï¼‰ + function msToFullDateTimeLabel(ts) { + var d = new Date(ts); + var year = d.getFullYear(); + var month = ('' + (d.getMonth() + 1)).padStart(2, '0'); + var day = ('' + d.getDate()).padStart(2, '0'); + var hh = ('' + d.getHours()).padStart(2, '0'); + var mm = ('' + d.getMinutes()).padStart(2, '0'); + var ss = ('' + d.getSeconds()).padStart(2, '0'); + return year + '-' + month + '-' + day + ' ' + hh + ':' + mm + ':' + ss; + } + + function buildTooltipHtml(point) { + if (!point) return ''; + var lines = []; + var typeSel = (typeof document !== 'undefined' ? document.getElementById('history-type-select') : null); + var selType = (typeSel && typeSel.value) ? typeSel.value : 'total'; + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + var isAggregated = point.is_aggregated || false; + + function row(label, val) { + lines.push('
' + label + '' + val + '
'); + } + + function rateValue(key) { + return formatByterate(point[key] || 0, speedUnit); + } + + function bytesValue(key) { + return formatSize(point[key] || 0); + } + + function labelsFor(type) { + if (type === 'lan') return { up: _('LAN Upload'), down: _('LAN Download') }; + if (type === 'wan') return { up: _('WAN Upload'), down: _('WAN Download') }; + return { up: _('Total Upload'), down: _('Total Download') }; + } + + function rateKeysFor(type) { + if (type === 'lan') return { up: 'lan_tx_rate', down: 'lan_rx_rate' }; + if (type === 'wan') return { up: 'wan_tx_rate', down: 'wan_rx_rate' }; + return { up: 'total_tx_rate', down: 'total_rx_rate' }; + } + + function bytesKeysFor(type) { + if (type === 'lan') return { up: 'lan_tx_bytes', down: 'lan_rx_bytes' }; + if (type === 'wan') return { up: 'wan_tx_bytes', down: 'wan_rx_bytes' }; + return { up: 'total_tx_bytes', down: 'total_rx_bytes' }; + } + + // 标题:èšåˆæ•°æ®æ˜¾ç¤ºå®Œæ•´æ—¥æœŸæ—¶é—´ï¼Œå®žæ—¶æ•°æ®åªæ˜¾ç¤ºæ—¶é—´ + if (isAggregated) { + lines.push('
' + msToFullDateTimeLabel(point.ts_ms) + '
'); + // 注æ„:当å‰ç‰ˆæœ¬åªæ”¯æŒå®žæ—¶æ•°æ®ï¼Œä¸æ˜¾ç¤ºèšåˆç»Ÿè®¡æ ‡ç­¾ + } else { + lines.push('
' + msToTimeLabel(point.ts_ms) + '
'); + } + + // 关键信æ¯ï¼šé€‰ä¸­ç±»åž‹çš„ä¸Šä¸‹è¡Œé€ŸçŽ‡ï¼ˆå¤§å·æ˜¾ç¤ºï¼‰ + var kpiLabels = labelsFor(selType); + var kpiRateKeys = rateKeysFor(selType); + + if (isAggregated) { + // èšåˆæ•°æ®ï¼šæ˜¾ç¤º P95 å€¼ï¼ˆä¸»è¦æŒ‡æ ‡ï¼‰ + lines.push( + '
' + + '
' + + '
' + _('WAN Upload') + ' (P95)
' + + '
' + formatByterate(point.w_tx_p95 || 0, speedUnit) + '
' + + '
' + + '
' + + '
' + _('WAN Download') + ' (P95)
' + + '
' + formatByterate(point.w_rx_p95 || 0, speedUnit) + '
' + + '
' + + '
' + ); + + // è¯¦ç»†ç»Ÿè®¡ä¿¡æ¯ + lines.push('
'); + lines.push('
' + _('Upload Statistics') + '
'); + row(_('Average'), formatByterate(point.w_tx_avg || 0, speedUnit)); + row(_('Maximum'), formatByterate(point.w_tx_max || 0, speedUnit)); + row(_('Minimum'), formatByterate(point.w_tx_min || 0, speedUnit)); + row('P90', formatByterate(point.w_tx_p90 || 0, speedUnit)); + row('P95', formatByterate(point.w_tx_p95 || 0, speedUnit)); + row('P99', formatByterate(point.w_tx_p99 || 0, speedUnit)); + + lines.push('
' + _('Download Statistics') + '
'); + row(_('Average'), formatByterate(point.w_rx_avg || 0, speedUnit)); + row(_('Maximum'), formatByterate(point.w_rx_max || 0, speedUnit)); + row(_('Minimum'), formatByterate(point.w_rx_min || 0, speedUnit)); + row('P90', formatByterate(point.w_rx_p90 || 0, speedUnit)); + row('P95', formatByterate(point.w_rx_p95 || 0, speedUnit)); + row('P99', formatByterate(point.w_rx_p99 || 0, speedUnit)); + + // 累计æµé‡ï¼ˆåªæ˜¾ç¤º WAN) + lines.push('
'); + lines.push('
' + _('Cumulative Traffic') + '
'); + row(_('WAN Uploaded'), bytesValue('wan_tx_bytes')); + row(_('WAN Downloaded'), bytesValue('wan_rx_bytes')); + } else { + // 实时数æ®ï¼šæ˜¾ç¤ºå®žæ—¶é€Ÿçއ + lines.push( + '
' + + '
' + + '
' + kpiLabels.up + '
' + + '
' + rateValue(kpiRateKeys.up) + '
' + + '
' + + '
' + + '
' + kpiLabels.down + '
' + + '
' + rateValue(kpiRateKeys.down) + '
' + + '
' + + '
' + ); + + // 次è¦ä¿¡æ¯ï¼šå…¶ä½™ç±»åž‹çš„速率(精简展示) + var otherTypes = ['total', 'lan', 'wan'].filter(function (t) { return t !== selType; }); + if (otherTypes.length) { + lines.push('
' + _('Other Rates') + '
'); + otherTypes.forEach(function (t) { + var lbs = labelsFor(t); + var ks = rateKeysFor(t); + row(lbs.up, rateValue(ks.up)); + row(lbs.down, rateValue(ks.down)); + }); + } + + // 累计:区分LAN æµé‡ä¸Žå…¬ç½‘ + lines.push('
'); + lines.push('
' + _('Cumulative') + '
'); + row(_('LAN Uploaded'), bytesValue('lan_tx_bytes')); + row(_('LAN Downloaded'), bytesValue('lan_rx_bytes')); + row(_('WAN Uploaded'), bytesValue('wan_tx_bytes')); + row(_('WAN Downloaded'), bytesValue('wan_rx_bytes')); + row(_('Total Uploaded'), bytesValue('total_tx_bytes')); + row(_('Total Downloaded'), bytesValue('total_rx_bytes')); + } + + return lines.join(''); + } + + // 辅助函数:比较IP地å€ï¼ˆå°çš„在å‰ï¼‰ + function compareIP(aIp, bIp) { + var aIpParts = (aIp || '').split('.').map(function (part) { return parseInt(part) || 0; }); + var bIpParts = (bIp || '').split('.').map(function (part) { return parseInt(part) || 0; }); + + for (var i = 0; i < 4; i++) { + var aPart = aIpParts[i] || 0; + var bPart = bIpParts[i] || 0; + if (aPart !== bPart) { + return aPart - bPart; // å°çš„IPåœ¨å‰ + } + } + return 0; + } + + // 排åºé€»è¾‘函数 + function sortDevices(devices, sortBy, ascending) { + if (!devices || !Array.isArray(devices)) return devices; + + var sortedDevices = devices.slice(); + + switch (sortBy) { + case 'online': + sortedDevices.sort(function (a, b) { + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + + // 如果在线状æ€ä¸åŒï¼Œåœ¨çº¿è®¾å¤‡ä¼˜å…ˆ + if (aOnline !== bOnline) { + return ascending ? (aOnline ? 1 : -1) : (aOnline ? -1 : 1); + } + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åºï¼ˆå°çš„在å‰ï¼‰ + var ipCompare = compareIP(a.ip4, b.ip4); + if (ipCompare !== 0) return ipCompare; + + // IP地å€ä¹Ÿç›¸åŒæ—¶ï¼ŒæŒ‰MACåœ°å€æŽ’åº + return (a.mac || '').localeCompare(b.mac || ''); + }); + break; + + case 'lan_speed': + sortedDevices.sort(function (a, b) { + // å…ˆæŒ‰åœ¨çº¿çŠ¶æ€æŽ’åºï¼ˆåœ¨çº¿åœ¨å‰ï¼‰ + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + if (aOnline !== bOnline) { + return aOnline ? -1 : 1; + } + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰LANé€Ÿåº¦æŽ’åº + var aSpeed = (a.l_tx_r || 0) + (a.l_rx_r || 0); + var bSpeed = (b.l_tx_r || 0) + (b.l_rx_r || 0); + if (aSpeed !== bSpeed) { + return ascending ? (aSpeed - bSpeed) : (bSpeed - aSpeed); + } + + // é€Ÿåº¦ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åº + return compareIP(a.ip4, b.ip4); + }); + break; + + case 'wan_speed': + sortedDevices.sort(function (a, b) { + // å…ˆæŒ‰åœ¨çº¿çŠ¶æ€æŽ’åºï¼ˆåœ¨çº¿åœ¨å‰ï¼‰ + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + if (aOnline !== bOnline) { + return aOnline ? -1 : 1; + } + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰WANé€Ÿåº¦æŽ’åº + var aSpeed = (a.w_tx_r || 0) + (a.w_rx_r || 0); + var bSpeed = (b.w_tx_r || 0) + (b.w_rx_r || 0); + if (aSpeed !== bSpeed) { + return ascending ? (aSpeed - bSpeed) : (bSpeed - aSpeed); + } + + // é€Ÿåº¦ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åº + return compareIP(a.ip4, b.ip4); + }); + break; + + case 'lan_traffic': + sortedDevices.sort(function (a, b) { + // å…ˆæŒ‰åœ¨çº¿çŠ¶æ€æŽ’åºï¼ˆåœ¨çº¿åœ¨å‰ï¼‰ + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + if (aOnline !== bOnline) { + return aOnline ? -1 : 1; + } + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰LANæµé‡æŽ’åº + var aTraffic = (a.l_tx_b || 0) + (a.l_rx_b || 0); + var bTraffic = (b.l_tx_b || 0) + (b.l_rx_b || 0); + if (aTraffic !== bTraffic) { + return ascending ? (aTraffic - bTraffic) : (bTraffic - aTraffic); + } + + // æµé‡ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åº + return compareIP(a.ip4, b.ip4); + }); + break; + + case 'wan_traffic': + sortedDevices.sort(function (a, b) { + // å…ˆæŒ‰åœ¨çº¿çŠ¶æ€æŽ’åºï¼ˆåœ¨çº¿åœ¨å‰ï¼‰ + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + if (aOnline !== bOnline) { + return aOnline ? -1 : 1; + } + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰WANæµé‡æŽ’åº + var aTraffic = (a.w_tx_b || 0) + (a.w_rx_b || 0); + var bTraffic = (b.w_tx_b || 0) + (b.w_rx_b || 0); + if (aTraffic !== bTraffic) { + return ascending ? (aTraffic - bTraffic) : (bTraffic - aTraffic); + } + + // æµé‡ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åº + return compareIP(a.ip4, b.ip4); + }); + break; + + default: + // 默认按在线状æ€å’ŒIPåœ°å€æŽ’åº + sortedDevices.sort(function (a, b) { + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + + if (aOnline !== bOnline) { + return aOnline ? -1 : 1; + } + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åºï¼ˆå°çš„在å‰ï¼‰ + var ipCompare = compareIP(a.ip4, b.ip4); + if (ipCompare !== 0) return ipCompare; + + // IPç›¸åŒæ—¶ï¼ŒæŒ‰MACåœ°å€æŽ’åº + return (a.mac || '').localeCompare(b.mac || ''); + }); + } + + return sortedDevices; + } + + // 判断设备是å¦åœ¨çº¿ï¼ˆåŸºäºŽ last_online_ts) + function isDeviceOnline(device) { + // 如果没有 last_online_ts 字段,使用原有的 online 字段 + if (typeof device.last === 'undefined') { + return device.online !== false; + } + + // 如果 last_online_ts 为 0 或无效值,认为离线 + if (!device.last || device.last <= 0) { + return false; + } + + // è®¡ç®—å½“å‰æ—¶é—´ä¸Žæœ€åŽåœ¨çº¿æ—¶é—´çš„差值(毫秒) + var currentTime = Date.now(); + // 如果时间戳å°äºŽ1000000000000,说明是秒级时间戳,需è¦è½¬æ¢ä¸ºæ¯«ç§’ + var lastOnlineTime = device.last < 1000000000000 ? device.last * 1000 : device.last; + var timeDiff = currentTime - lastOnlineTime; + + // 从UCIé…置获å–离线超时时间(秒),默认10分钟 + var offlineTimeoutSeconds = uci.get('bandix', 'traffic', 'offline_timeout') || 600; + var offlineThreshold = offlineTimeoutSeconds * 1000; // 转æ¢ä¸ºæ¯«ç§’ + + return timeDiff <= offlineThreshold; + } + + function channelToBand(ch) { + var c = Number(ch); + if (c < 1) return null; + if (c <= 14) return '2.4 GHz'; + if (c <= 165) return '5 GHz'; + if (c <= 233) return '6 GHz'; + return null; + } + + function channelToBandClass(ch) { + var c = Number(ch); + if (c <= 14) return 'g24'; + if (c <= 165) return 'g5'; + if (c <= 233) return 'g6'; + return ''; + } + + function buildDeviceUplinkChBadges(device) { + var badges = []; + if (device.uplink && String(device.uplink).trim() !== '') { + badges.push(E('span', { 'class': 'device-uplink-badge', 'title': _('Interface') }, device.uplink.trim())); + } + if (device.w_ch && Number(device.w_ch) > 0) { + var ch = Number(device.w_ch); + var band = channelToBand(ch); + var bandClass = channelToBandClass(ch); + if (band && bandClass) { + badges.push(E('span', { + 'class': 'device-ch-badge device-ch-' + bandClass, + 'title': _('WiFi Channel') + ' ' + ch + }, band)); + } + } + return badges; + } + + function formatDeviceUplinkCh(device) { + var parts = []; + if (device.uplink && String(device.uplink).trim() !== '') parts.push(device.uplink.trim()); + if (device.w_ch && Number(device.w_ch) > 0) { + var band = channelToBand(Number(device.w_ch)); + if (band) parts.push(band); + } + return parts.join(' · '); + } + + // æ ¼å¼åŒ–最åŽä¸Šçº¿æ—¶é—´ + function formatLastOnlineTime(lastOnlineTs) { + if (!lastOnlineTs || lastOnlineTs <= 0) { + return _('Never Online'); + } + + // 如果时间戳å°äºŽ1000000000000,说明是秒级时间戳,需è¦è½¬æ¢ä¸ºæ¯«ç§’ + var lastOnlineTime = lastOnlineTs < 1000000000000 ? lastOnlineTs * 1000 : lastOnlineTs; + var currentTime = Date.now(); + var timeDiff = currentTime - lastOnlineTime; + + // 转æ¢ä¸ºåˆ†é’Ÿ + var minutesDiff = Math.floor(timeDiff / (60 * 1000)); + + // 1分钟以内显示"刚刚" + if (minutesDiff < 1) { + return _('Just Now'); + } + + // 10分钟以内显示具体的"几分钟å‰" + if (minutesDiff <= 10) { + return minutesDiff + _('min ago'); + } + + // 转æ¢ä¸ºå°æ—¶ + var hoursDiff = Math.floor(timeDiff / (60 * 60 * 1000)); + + // å¦‚æžœä¸æ»¡1å°æ—¶ï¼Œæ˜¾ç¤ºåˆ†é’Ÿ + if (hoursDiff < 1) { + return minutesDiff + _('min ago'); + } + + // 转æ¢ä¸ºå¤© + var daysDiff = Math.floor(timeDiff / (24 * 60 * 60 * 1000)); + + // å¦‚æžœä¸æ»¡1å¤©ï¼Œæ˜¾ç¤ºå°æ—¶ï¼ˆå¿½ç•¥åˆ†é’Ÿï¼‰ + if (daysDiff < 1) { + return hoursDiff + _('h ago'); + } + + // 转æ¢ä¸ºæœˆï¼ˆæŒ‰30天计算) + var monthsDiff = Math.floor(daysDiff / 30); + + // å¦‚æžœä¸æ»¡1ä¸ªæœˆï¼Œæ˜¾ç¤ºå¤©ï¼ˆå¿½ç•¥å°æ—¶ï¼‰ + if (monthsDiff < 1) { + return daysDiff + _('days ago'); + } + + // 转æ¢ä¸ºå¹´ï¼ˆæŒ‰365天计算) + var yearsDiff = Math.floor(daysDiff / 365); + + // å¦‚æžœä¸æ»¡1年,显示月(忽略天) + if (yearsDiff < 1) { + return monthsDiff + _('months ago'); + } + + // 超过1年,显示年(忽略月) + return yearsDiff + _('years ago'); + } + + // ç²¾ç¡®æ—¶é—´æ ¼å¼ + function formatLastOnlineExactTime(lastOnlineTs) { + if (!lastOnlineTs || lastOnlineTs <= 0) { + return '-'; + } + + var lastOnlineTime = lastOnlineTs < 1000000000000 ? lastOnlineTs * 1000 : lastOnlineTs; + var date = new Date(lastOnlineTime); + + if (isNaN(date.getTime())) { + return '-'; + } + + function pad(value) { + return value < 10 ? '0' + value : value; + } + + return date.getFullYear() + '-' + + pad(date.getMonth() + 1) + '-' + + pad(date.getDate()) + ' ' + + pad(date.getHours()) + ':' + + pad(date.getMinutes()) + ':' + + pad(date.getSeconds()); + } + + function formatRetentionSeconds(seconds) { + if (!seconds || seconds <= 0) return ''; + + // 固定值映射 + if (seconds === 600) { + return _('Last 10 Minutes'); + } + if (seconds === 900) { + return _('Last 15 Minutes'); + } + if (seconds === 1800) { + return _('Last 30 Minutes'); + } + if (seconds === 3600) { + return _('Last 1 Hour'); + } + if (seconds === 86400) { + return _('Last 24 Hours'); + } + if (seconds === 604800) { + return _('Last 7 Days'); + } + if (seconds === 2592000) { + return _('Last 30 Days'); + } + + var value; + var unitKey; + if (seconds < 60) { + value = Math.round(seconds); + unitKey = _('seconds'); + } else if (seconds < 3600) { + value = Math.round(seconds / 60); + if (value < 1) value = 1; + unitKey = _('minutes'); + } else if (seconds < 86400) { + value = Math.round(seconds / 3600); + if (value < 1) value = 1; + unitKey = _('hours'); + } else if (seconds < 604800) { + value = Math.round(seconds / 86400); + if (value < 1) value = 1; + unitKey = _('days'); + } else { + value = Math.round(seconds / 604800); + if (value < 1) value = 1; + unitKey = _('weeks'); + } + + return _('Last') + ' ' + value + ' ' + unitKey; + } + + // 移动端数æ®é‡‡æ ·å‡½æ•°ï¼šæœ€å¤šæ˜¾ç¤ºæŒ‡å®šæ•°é‡çš„点,ä¿ç•™é¦–尾点 + function downsampleForMobile(data, labels, upSeries, downSeries, maxPoints) { + if (!data || data.length <= maxPoints) { + return { + data: data, + labels: labels, + upSeries: upSeries, + downSeries: downSeries, + indices: data.map(function (_, i) { return i; }) // 原始索引映射 + }; + } + + var n = data.length; + var sampledData = []; + var sampledLabels = []; + var sampledUp = []; + var sampledDown = []; + var indices = []; // 记录æ¯ä¸ªé‡‡æ ·ç‚¹å¯¹åº”的原始数æ®ç´¢å¼• + + // å‡åŒ€é‡‡æ ·ï¼Œä¿ç•™é¦–尾点 + var step = (n - 1) / (maxPoints - 1); + + for (var i = 0; i < maxPoints; i++) { + var idx = Math.round(i * step); + // ç¡®ä¿ç´¢å¼•在有效范围内 + idx = Math.min(idx, n - 1); + + sampledData.push(data[idx]); + sampledLabels.push(labels[idx]); + sampledUp.push(upSeries[idx]); + sampledDown.push(downSeries[idx]); + indices.push(idx); // ä¿å­˜åŽŸå§‹ç´¢å¼• + } + + // ç¡®ä¿é¦–å°¾ç‚¹è¢«åŒ…å« + if (indices[0] !== 0) { + sampledData[0] = data[0]; + sampledLabels[0] = labels[0]; + sampledUp[0] = upSeries[0]; + sampledDown[0] = downSeries[0]; + indices[0] = 0; + } + if (indices[indices.length - 1] !== n - 1) { + var lastIdx = sampledData.length - 1; + sampledData[lastIdx] = data[n - 1]; + sampledLabels[lastIdx] = labels[n - 1]; + sampledUp[lastIdx] = upSeries[lastIdx]; + sampledDown[lastIdx] = downSeries[lastIdx]; + indices[lastIdx] = n - 1; + } + + return { + data: sampledData, + labels: sampledLabels, + upSeries: sampledUp, + downSeries: sampledDown, + indices: indices + }; + } + + function refreshHistory() { + // 若鼠标在历å²å›¾ä¸Šæ‚¬åœï¼Œåˆ™æš‚åœåˆ·æ–°ä»¥é¿å…自动滚动 + if (historyHover) return Promise.resolve(); + var mac = document.getElementById('history-device-select')?.value || ''; + var type = document.getElementById('history-type-select')?.value || 'total'; + var canvas = document.getElementById('history-canvas'); + var tooltip = document.getElementById('history-tooltip'); + if (!canvas) return Promise.resolve(); + + if (isHistoryLoading) return Promise.resolve(); + isHistoryLoading = true; + + + + return fetchMetricsData(mac).then(function (res) { + // 将数组数组格å¼è½¬æ¢ä¸ºå¯¹è±¡æ•°ç»„æ ¼å¼ + var rawMetrics = res && res.metrics ? res.metrics : []; + var data = convertMetricsArrayToObjects(rawMetrics); + lastHistoryData = data; + + var retentionBadge = document.getElementById('history-retention'); + if (retentionBadge) { + var text = formatRetentionSeconds(res && res.retention_seconds); + retentionBadge.textContent = text || ''; + } + + if (!data.length) { + var ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawHistoryChart(canvas, [], [], [], 1, 0); + return; + } + + // 按时间å‡åºæŽ’åº + var filtered = data.slice(); + filtered.sort(function (a, b) { return (a.ts_ms || 0) - (b.ts_ms || 0); }); + + // 检测是å¦ä¸ºç§»åŠ¨ç«¯ + var screenWidth = window.innerWidth || document.documentElement.clientWidth; + var isMobileScreen = screenWidth <= 768; + + var displayData = filtered; // 用于 tooltip æ˜¾ç¤ºçš„åŽŸå§‹æ•°æ® + var indexMapping = null; // 采样åŽçš„索引映射到原始数æ®çš„索引 + var timeRangeBadge = document.getElementById('history-time-range'); + + // ç§»åŠ¨ç«¯ï¼šåªæ˜¾ç¤ºæœ€è¿‘ 20 ç§’çš„æ•°æ® + if (isMobileScreen && filtered.length > 0) { + var currentTime = Date.now(); + var twentySecondsAgo = currentTime - 20000; // 20 ç§’å‰ + + // 过滤出最近 20 ç§’çš„æ•°æ® + var recentData = filtered.filter(function (item) { + var ts = item.ts_ms || 0; + // 如果时间戳是秒级,转æ¢ä¸ºæ¯«ç§’ + if (ts < 1000000000000) ts = ts * 1000; + return ts >= twentySecondsAgo; + }); + + // 如果没有最近 20 秒的数æ®ï¼Œä½¿ç”¨æœ€åŽ 20 个数æ®ç‚¹ï¼ˆæˆ–全部,如果少于 20 个) + if (recentData.length === 0 && filtered.length > 0) { + recentData = filtered.slice(-20); // å–æœ€åŽ 20 个点 + } + + // 如果数æ®ç‚¹è¶…过 20 个,进行采样 + if (recentData.length > 20) { + var keys = getTypeKeys(type); + var tempUpSeries = recentData.map(function (x) { return x[keys.up] || 0; }); + var tempDownSeries = recentData.map(function (x) { return x[keys.down] || 0; }); + var tempLabels = recentData.map(function (x) { return msToTimeLabel(x.ts_ms); }); + + var sampled = downsampleForMobile(recentData, tempLabels, tempUpSeries, tempDownSeries, 20); + filtered = sampled.data; + // 索引映射:sampled.indices 是 recentData 中的索引,直接使用å³å¯ + indexMapping = sampled.indices; + } else { + filtered = recentData; + // 创建完整的索引映射(1:1),索引直接对应 recentData 的索引 + indexMapping = recentData.map(function (_, i) { return i; }); + } + + // ä¿å­˜åŽŸå§‹æ•°æ®ç”¨äºŽ tooltip(recentData 的索引与 indexMapping 对应) + displayData = recentData; + } else { + // PC端:显示所有数æ®ï¼Œåˆ›å»ºå®Œæ•´çš„索引映射(1:1) + indexMapping = filtered.map(function (_, i) { return i; }); + } + + var keys = getTypeKeys(type); + var upSeries = filtered.map(function (x) { return x[keys.up] || 0; }); + var downSeries = filtered.map(function (x) { return x[keys.down] || 0; }); + var labels = filtered.map(function (x) { return msToTimeLabel(x.ts_ms); }); + + // ä¿å­˜ç´¢å¼•映射到 canvas,供 tooltip 使用 + if (canvas) { + canvas.__bandixIndexMapping = indexMapping; + canvas.__bandixDisplayData = displayData; // ä¿å­˜ç”¨äºŽ tooltip çš„åŽŸå§‹æ•°æ® + } + + drawHistoryChartWithZoom(canvas, labels, upSeries, downSeries); + + // 绑定或更新鼠标事件用于展示浮窗 + function findNearestIndex(evt) { + var rect = canvas.getBoundingClientRect(); + var x = evt.clientX - rect.left; + var info = canvas.__bandixChart; + if (!info || !info.labels || info.labels.length === 0) return -1; + + // 当剿˜¾ç¤ºçš„æ•°æ®é•¿åº¦ï¼ˆç¼©æ”¾åŽï¼‰ + var n = info.labels.length; + var stepX = n > 1 ? (info.innerW / (n - 1)) : 0; + var minIdx = 0; + var minDist = Infinity; + + // åœ¨å½“å‰æ˜¾ç¤ºçš„æ•°æ®èŒƒå›´å†…找最近的点 + for (var k = 0; k < n; k++) { + var px = info.padding.left + (n > 1 ? stepX * k : info.innerW / 2); + var dist = Math.abs(px - x); + if (dist < minDist) { minDist = dist; minIdx = k; } + } + + // 如果处于缩放状æ€ï¼Œéœ€è¦å°†æ˜¾ç¤ºç´¢å¼•映射回原始数æ®ç´¢å¼• + if (info.scale && info.scale > 1 && info.originalLabels) { + var startIdx = Math.floor(info.offsetX || 0); + minIdx = startIdx + minIdx; + } + + // 使用索引映射将显示索引转æ¢ä¸ºåŽŸå§‹æ•°æ®ç´¢å¼•(移动端采样åŽéœ€è¦ï¼‰ + var indexMapping = canvas.__bandixIndexMapping; + if (indexMapping && indexMapping[minIdx] !== undefined) { + return indexMapping[minIdx]; + } + + return minIdx; + } + + function onMove(evt) { + // 移动端ç¦ç”¨æ‚¬æµ®åŠŸèƒ½ + var screenWidth = window.innerWidth || document.documentElement.clientWidth; + if (screenWidth <= 768) { + if (tooltip) tooltip.style.display = 'none'; + return; + } + + if (!tooltip) return; + var idx = findNearestIndex(evt); + + // 优先使用 displayData(移动端过滤åŽçš„æ•°æ®ï¼‰ï¼Œå¦åˆ™ä½¿ç”¨ lastHistoryData + var dataSource = (canvas && canvas.__bandixDisplayData) ? canvas.__bandixDisplayData : lastHistoryData; + + if (idx < 0 || !dataSource || !dataSource[idx]) { + tooltip.style.display = 'none'; + // 清除 hover 状æ€å¹¶è¯·æ±‚é‡ç»˜åŽ»æŽ‰è™šçº¿ + historyHover = false; + try { if (canvas && canvas.__bandixChart) { delete canvas.__bandixChart.hoverIndex; drawHistoryChart(canvas, canvas.__bandixChart.originalLabels || [], canvas.__bandixChart.originalUpSeries || [], canvas.__bandixChart.originalDownSeries || [], zoomScale, zoomOffsetX); } } catch (e) { } + return; + } + var point = dataSource[idx]; + // 设置 hover 状æ€ï¼Œæš‚åœåކå²è½®è¯¢åˆ·æ–° + historyHover = true; + historyHoverIndex = idx; + // ç«‹å³é‡ç»˜ä»¥æ˜¾ç¤ºåž‚直虚线 + try { drawHistoryChart(canvas, canvas.__bandixChart && canvas.__bandixChart.originalLabels ? canvas.__bandixChart.originalLabels : labels, canvas.__bandixChart && canvas.__bandixChart.originalUpSeries ? canvas.__bandixChart.originalUpSeries : upSeries, canvas.__bandixChart && canvas.__bandixChart.originalDownSeries ? canvas.__bandixChart.originalDownSeries : downSeries, zoomScale, zoomOffsetX); } catch (e) { } + tooltip.innerHTML = buildTooltipHtml(point); + + + // 先显示以计算尺寸 + tooltip.style.display = 'block'; + tooltip.style.left = '-9999px'; + tooltip.style.top = '-9999px'; + var tw = tooltip.offsetWidth || 0; + var th = tooltip.offsetHeight || 0; + var padding = 20; + var maxX = (typeof window !== 'undefined' ? window.innerWidth : document.documentElement.clientWidth) - 4; + var maxY = (typeof window !== 'undefined' ? window.innerHeight : document.documentElement.clientHeight) - 4; + var cx = evt.clientX; + var cy = evt.clientY; + + // 检测是å¦ä¸ºç§»åŠ¨ç«¯ + var isMobileScreen = maxX <= 768; + + var baseX, baseY; + if (isMobileScreen) { + // 移动端:居中显示在触摸点下方 + baseX = Math.max(4, Math.min(maxX - tw - 4, cx - tw / 2)); + baseY = cy + padding; // 显示在触摸点下方 + // 如果下方空间ä¸è¶³ï¼Œæ˜¾ç¤ºåœ¨ä¸Šæ–¹ + if (baseY + th > maxY) { + baseY = cy - th - padding; + } + } else { + // PC端:å³ä¸Šï¼ˆæ°´å¹³å‘å³ï¼‰ + baseX = cx + padding; + baseY = cy - th - padding; // 上方 + // è‹¥å³ä¾§æº¢å‡ºï¼Œæ”¹ä¸ºå·¦ä¸Š + if (baseX + tw > maxX) { + baseX = cx - tw - padding; + } + } + // 边界收缩 + if (baseX < 4) baseX = 4; + if (baseY < 4) baseY = 4; + + tooltip.style.left = baseX + 'px'; + tooltip.style.top = baseY + 'px'; + } + + function onLeave() { + if (tooltip) tooltip.style.display = 'none'; + // 清除 hover 状æ€å¹¶è¯·æ±‚é‡ç»˜åŽ»æŽ‰è™šçº¿ + historyHover = false; + historyHoverIndex = null; + // é‡ç½®ç¼©æ”¾çŠ¶æ€ + if (zoomTimer) { + clearTimeout(zoomTimer); + zoomTimer = null; + } + zoomEnabled = false; + zoomScale = 1; + zoomOffsetX = 0; + // 更新缩放å€çŽ‡æ˜¾ç¤º + updateZoomLevelDisplay(); + // 清除canvas中的hoverä¿¡æ¯ + if (canvas && canvas.__bandixChart) { + delete canvas.__bandixChart.hoverIndex; + } + try { drawHistoryChart(canvas, canvas.__bandixChart && canvas.__bandixChart.originalLabels ? canvas.__bandixChart.originalLabels : labels, canvas.__bandixChart && canvas.__bandixChart.originalUpSeries ? canvas.__bandixChart.originalUpSeries : upSeries, canvas.__bandixChart && canvas.__bandixChart.originalDownSeries ? canvas.__bandixChart.originalDownSeries : downSeries, 1, 0); } catch (e) { } + } + + // 鼠标进入事件:å¯åŠ¨å»¶è¿Ÿè®¡æ—¶å™¨ + canvas.onmouseenter = function () { + if (zoomTimer) clearTimeout(zoomTimer); + zoomTimer = setTimeout(function () { + zoomEnabled = true; + zoomTimer = null; + }, 1000); // 1ç§’åŽå¯ç”¨ç¼©æ”¾ + }; + + // 鼠标滚轮事件:处ç†ç¼©æ”¾ + canvas.onwheel = function (evt) { + if (!zoomEnabled) return; + evt.preventDefault(); + + var delta = evt.deltaY > 0 ? 0.9 : 1.1; + var newScale = zoomScale * delta; + + // é™åˆ¶ç¼©æ”¾èŒƒå›´ + if (newScale < 1) newScale = 1; + if (newScale > 10) newScale = 10; + + var rect = canvas.getBoundingClientRect(); + var mouseX = evt.clientX - rect.left; + var info = canvas.__bandixChart; + if (!info || !info.originalLabels) return; + + // 计算鼠标在数æ®ä¸­çš„相对ä½ç½® + var relativeX = (mouseX - info.padding.left) / info.innerW; + var totalLen = info.originalLabels.length; + var mouseDataIndex = relativeX * totalLen; + + // 调整åç§»ä»¥ä¿æŒé¼ æ ‡ä½ç½®ä¸ºç¼©æ”¾ä¸­å¿ƒ + var oldVisibleLen = totalLen / zoomScale; + var newVisibleLen = totalLen / newScale; + var centerShift = (oldVisibleLen - newVisibleLen) * (mouseDataIndex / totalLen); + + zoomScale = newScale; + zoomOffsetX = Math.max(0, Math.min(totalLen - newVisibleLen, zoomOffsetX + centerShift)); + + // 更新缩放å€çŽ‡æ˜¾ç¤º + updateZoomLevelDisplay(); + + // é‡ç»˜å›¾è¡¨ - ä¿æŒå½“å‰çš„hoverçŠ¶æ€ + try { + drawHistoryChart(canvas, info.originalLabels, info.originalUpSeries, info.originalDownSeries, zoomScale, zoomOffsetX); + // 如果有当å‰çš„hoverç´¢å¼•ï¼Œé‡æ–°ç»˜åˆ¶è™šçº¿ + if (typeof historyHoverIndex === 'number' && canvas.__bandixChart) { + canvas.__bandixChart.hoverIndex = historyHoverIndex; + } + } catch (e) { } + }; + + // 检测是å¦ä¸ºç§»åŠ¨ç«¯ + var screenWidth = window.innerWidth || document.documentElement.clientWidth; + var isMobileScreen = screenWidth <= 768; + + // 移动端ç¦ç”¨æ‚¬æµ®åŠŸèƒ½ï¼ŒPC端å¯ç”¨ + if (!isMobileScreen) { + canvas.onmousemove = onMove; + canvas.onmouseleave = onLeave; + } else { + // 移动端:ä¸ç»‘定任何悬浮相关事件 + // ç¡®ä¿ tooltip åœ¨ç§»åŠ¨ç«¯ä¸æ˜¾ç¤º + if (tooltip) { + tooltip.style.display = 'none'; + } + } + }).catch(function () { + var ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawHistoryChart(canvas, [], [], [], 1, 0); + // ui.addNotification(null, E('p', {}, _('Unable to fetch history data')), 'error'); + }).finally(function () { + isHistoryLoading = false; + }); + } + + // 历å²è¶‹åŠ¿ï¼šäº‹ä»¶ç»‘å®šï¼ˆå»¶è¿Ÿæ‰§è¡Œä»¥ç¡®ä¿ DOM 已加载) + function initHistoryControls() { + var typeSel = document.getElementById('history-type-select'); + var devSel = document.getElementById('history-device-select'); + if (typeSel) typeSel.value = 'total'; + + // åˆå§‹åŒ–缩放å€çŽ‡æ˜¾ç¤º + updateZoomLevelDisplay(); + + // 历å²å›¾è¡¨å§‹ç»ˆæ˜¾ç¤ºå®žæ—¶æ•°æ® + + function onFilterChange() { + refreshHistory(); + // åŒæ­¥åˆ·æ–°è¡¨æ ¼ï¼ˆç«‹å³ç”Ÿæ•ˆï¼Œä¸ç­‰è½®è¯¢ï¼‰ + try { window.__bandixRenderTable && window.__bandixRenderTable(); } catch (e) { } + } + if (typeSel) typeSel.addEventListener('change', onFilterChange); + if (devSel) devSel.addEventListener('change', onFilterChange); + + window.addEventListener('resize', function () { + // 窗å£å¤§å°æ”¹å˜æ—¶ï¼Œé‡æ–°åˆ·æ–°åކ岿•°æ®ä»¥åº”用移动端过滤逻辑 + refreshHistory(); + }); + + // 首次加载 + refreshHistory(); + } + + // å»¶è¿Ÿæ‰§è¡Œä»¥ç¡®ä¿ DOM 已加载 + setTimeout(initHistoryControls, 0); + + // 历å²è¶‹åŠ¿è½®è¯¢ï¼ˆå®žæ—¶æ•°æ®æ¯1秒,其他时间范围æ¯30秒) + // 使用 poll.add ä½†æ ¹æ®æ—¶é—´èŒƒå›´åЍæ€è°ƒæ•´ + poll.add(function () { + return refreshHistory(); + }, 1); + + + + // 存储移动端å¡ç‰‡å±•开状æ€ï¼ˆè®¾å¤‡MAC地å€é›†åˆï¼‰ + var expandedDeviceCards = new Set(); + + // é¢„å…ˆèŽ·å– LAN Traffic tooltip 翻译文本 + var lanTrafficTooltipText = _('LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable.'); + + // 定义更新设备数æ®çš„函数 + function updateDeviceData() { + var devicePeriod = localStorage.getItem('bandix_device_period') || 'all'; + if (!/^(today|week|month|year|all)$/.test(devicePeriod)) devicePeriod = 'all'; + + var timeRange = getTimeRangeForPeriod(devicePeriod); + + return Promise.all([ + (devicePeriod === 'all') ? callStatus() : callStatus(timeRange.start_ms, timeRange.end_ms), + fetchAllScheduleRules() + ]).then(function (results) { + var result = results[0]; + var trafficDiv = document.getElementById('traffic-status'); + var deviceCountDiv = document.getElementById('device-count'); + var statsGrid = document.getElementById('stats-grid'); + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + + var stats = result; + if (!stats || !stats.d) { + if (trafficDiv) { + trafficDiv.innerHTML = '
' + _('Unable to fetch data') + '
'; + } + return; + } + + // 更新设备计数 + if (deviceCountDiv) { + var onlineCount = stats.d.filter(d => isDeviceOnline(d)).length; + deviceCountDiv.textContent = _('Online Devices') + ': ' + onlineCount + ' / ' + stats.d.length; + } + + // 计算统计数æ®ï¼ˆåŒ…嫿‰€æœ‰è®¾å¤‡ï¼‰ + var totalLanUp = stats.d.reduce((sum, d) => sum + (d.l_tx_b || 0), 0); + var totalLanDown = stats.d.reduce((sum, d) => sum + (d.l_rx_b || 0), 0); + var totalWanUp = stats.d.reduce((sum, d) => sum + (d.w_tx_b || 0), 0); + var totalWanDown = stats.d.reduce((sum, d) => sum + (d.w_rx_b || 0), 0); + var totalLanSpeedUp = stats.d.reduce((sum, d) => sum + (d.l_tx_r || 0), 0); + var totalLanSpeedDown = stats.d.reduce((sum, d) => sum + (d.l_rx_r || 0), 0); + var totalWanSpeedUp = stats.d.reduce((sum, d) => sum + (d.w_tx_r || 0), 0); + var totalWanSpeedDown = stats.d.reduce((sum, d) => sum + (d.w_rx_r || 0), 0); + var totalSpeedUp = totalLanSpeedUp + totalWanSpeedUp; + var totalSpeedDown = totalLanSpeedDown + totalWanSpeedDown; + var totalUp = totalLanUp + totalWanUp; + var totalDown = totalLanDown + totalWanDown; + + // 更新统计å¡ç‰‡ + statsGrid.innerHTML = ''; + + // LAN æµé‡å¡ç‰‡ + var lanTrafficCard = E('div', { 'class': 'cbi-section', 'id': 'lan-traffic-card' }, [ + E('div', { 'class': 'stats-card-title' }, [ + E('span', {}, _('LAN Traffic')), + E('span', { 'class': 'stats-card-info-icon' }, '?') + ]), + E('div', { 'style': 'display: flex; flex-direction: column; gap: 8px;' }, [ + // 上传行 + E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↑'), + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 1.125rem; font-weight: 700;' }, formatByterate(totalLanSpeedUp, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; color: #64748b; margin-left: 4px;' }, '(' + formatSize(totalLanUp) + ')') + ]), + // 下载行 + E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↓'), + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 1.125rem; font-weight: 700;' }, formatByterate(totalLanSpeedDown, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; color: #64748b; margin-left: 4px;' }, '(' + formatSize(totalLanDown) + ')') + ]) + ]) + ]); + statsGrid.appendChild(lanTrafficCard); + + // 设置 LAN Traffic å¡ç‰‡çš„ tooltip + setTimeout(function() { + var lanTrafficCardEl = document.getElementById('lan-traffic-card'); + var tooltip = document.getElementById('lan-traffic-tooltip'); + if (lanTrafficCardEl && tooltip) { + var isMobile = window.innerWidth <= 768; + if (isMobile) return; + + var tooltipTextSet = false; + + function updateTooltipPosition(e) { + if (!tooltipTextSet) { + tooltip.textContent = lanTrafficTooltipText; + tooltipTextSet = true; + } + tooltip.style.display = 'block'; + tooltip.style.left = '-9999px'; + tooltip.style.top = '-9999px'; + var tw = tooltip.offsetWidth || 0; + var th = tooltip.offsetHeight || 0; + + var tooltipX = e.clientX + 15; + var tooltipY = e.clientY - th - 15; + + if (tooltipY < 0) { + tooltipY = e.clientY + 15; + } + + if (tooltipX + tw > window.innerWidth) { + tooltipX = e.clientX - tw - 15; + } + if (tooltipX < 0) { + tooltipX = 10; + } + if (tooltipY + th > window.innerHeight) { + tooltipY = window.innerHeight - th - 10; + } + + tooltip.style.left = tooltipX + 'px'; + tooltip.style.top = tooltipY + 'px'; + } + + lanTrafficCardEl.addEventListener('mouseenter', function(e) { + updateTooltipPosition(e); + }); + + lanTrafficCardEl.addEventListener('mouseleave', function() { + tooltip.style.display = 'none'; + }); + + lanTrafficCardEl.addEventListener('mousemove', function(e) { + updateTooltipPosition(e); + }); + + lanTrafficCardEl.addEventListener('wheel', function() { + tooltip.style.display = 'none'; + }); + } + }, 100); + + // WAN æµé‡å¡ç‰‡ + statsGrid.appendChild(E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('WAN Traffic')), + E('div', { 'style': 'display: flex; flex-direction: column; gap: 8px;' }, [ + // 上传行 + E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↑'), + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 1.125rem; font-weight: 700;' }, formatByterate(totalWanSpeedUp, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; color: #64748b; margin-left: 4px;' }, '(' + formatSize(totalWanUp) + ')') + ]), + // 下载行 + E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↓'), + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 1.125rem; font-weight: 700;' }, formatByterate(totalWanSpeedDown, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; color: #64748b; margin-left: 4px;' }, '(' + formatSize(totalWanDown) + ')') + ]) + ]) + ])); + + // 总æµé‡å¡ç‰‡ + statsGrid.appendChild(E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'stats-card-title' }, _('Total')), + E('div', { 'style': 'display: flex; flex-direction: column; gap: 8px;' }, [ + // 上传行 + E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↑'), + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 1.125rem; font-weight: 700;' }, formatByterate(totalSpeedUp, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; color: #64748b; margin-left: 4px;' }, '(' + formatSize(totalUp) + ')') + ]), + // 下载行 + E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↓'), + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 1.125rem; font-weight: 700;' }, formatByterate(totalSpeedDown, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; color: #64748b; margin-left: 4px;' }, '(' + formatSize(totalDown) + ')') + ]) + ]) + ])); + + // 创建表头点击处ç†å‡½æ•° + function createSortableHeader(text, sortKey) { + var th = E('th', { + 'class': 'sortable' + (currentSortBy === sortKey ? ' active ' + (currentSortOrder ? 'asc' : 'desc') : ''), + 'data-sort': sortKey + }, text); + + th.addEventListener('click', function () { + var newSortBy = this.getAttribute('data-sort'); + if (currentSortBy === newSortBy) { + // åŒä¸€åˆ—,切æ¢å‡é™åº + currentSortOrder = !currentSortOrder; + } else { + // ä¸åŒåˆ—,默认é™åºï¼ˆå¯¹äºŽé€Ÿåº¦å’Œæµé‡ï¼Œé™åºæ›´æœ‰æ„义) + currentSortBy = newSortBy; + currentSortOrder = false; // 所有排åºé»˜è®¤é™åº + } + + // ä¿å­˜çŠ¶æ€ + localStorage.setItem('bandix_sort_by', currentSortBy); + localStorage.setItem('bandix_sort_order', currentSortOrder.toString()); + + // 触å‘釿–°æ¸²æŸ“ + if (window.__bandixRenderTable) { + window.__bandixRenderTable(); + } + }); + + return th; + } + + // 创建分æ è¡¨å¤´ï¼ˆé€Ÿåº¦ | 用é‡ï¼‰ + function createSplitHeader(text, speedKey, trafficKey) { + var th = E('th', {}); + + var header = E('div', { 'class': 'th-split-header' }, [ + E('span', {}, text) + ]); + + var controls = E('div', { 'style': 'display: flex; align-items: center; gap: 4px;' }); + + // é€Ÿåº¦æŽ’åºæŒ‰é’® + var speedBtn = E('div', { + 'class': 'th-split-section' + (currentSortBy === speedKey ? ' active' : ''), + 'data-sort': speedKey, + 'title': _('Sort by Speed') + }, [ + E('span', { 'class': 'th-split-icon' }, 'âš¡'), + E('span', { 'style': 'font-size: 0.75rem;' }, currentSortBy === speedKey ? (currentSortOrder ? '↑' : '↓') : '') + ]); + + // 分隔线 + var divider = E('div', { 'class': 'th-split-divider' }); + + // ç”¨é‡æŽ’åºæŒ‰é’® + var trafficBtn = E('div', { + 'class': 'th-split-section' + (currentSortBy === trafficKey ? ' active' : ''), + 'data-sort': trafficKey, + 'title': _('Sort by Traffic') + }, [ + E('span', { 'class': 'th-split-icon' }, '∑'), + E('span', { 'style': 'font-size: 0.75rem;' }, currentSortBy === trafficKey ? (currentSortOrder ? '↑' : '↓') : '') + ]); + + controls.appendChild(speedBtn); + controls.appendChild(divider); + controls.appendChild(trafficBtn); + header.appendChild(controls); + th.appendChild(header); + + // 速度按钮点击事件 + speedBtn.addEventListener('click', function (e) { + e.stopPropagation(); + var newSortBy = this.getAttribute('data-sort'); + if (currentSortBy === newSortBy) { + currentSortOrder = !currentSortOrder; + } else { + currentSortBy = newSortBy; + currentSortOrder = false; // 速度默认é™åº + } + localStorage.setItem('bandix_sort_by', currentSortBy); + localStorage.setItem('bandix_sort_order', currentSortOrder.toString()); + if (window.__bandixRenderTable) { + window.__bandixRenderTable(); + } + }); + + // ç”¨é‡æŒ‰é’®ç‚¹å‡»äº‹ä»¶ + trafficBtn.addEventListener('click', function (e) { + e.stopPropagation(); + var newSortBy = this.getAttribute('data-sort'); + if (currentSortBy === newSortBy) { + currentSortOrder = !currentSortOrder; + } else { + currentSortBy = newSortBy; + currentSortOrder = false; // 用é‡é»˜è®¤é™åº + } + localStorage.setItem('bandix_sort_by', currentSortBy); + localStorage.setItem('bandix_sort_order', currentSortOrder.toString()); + if (window.__bandixRenderTable) { + window.__bandixRenderTable(); + } + }); + + return th; + } + + // 创建表格 + var table = E('table', { 'class': 'bandix-table' }, [ + E('thead', {}, [ + E('tr', {}, [ + createSortableHeader(_('Device Info'), 'online'), + createSplitHeader(_('LAN Traffic'), 'lan_speed', 'lan_traffic'), + createSplitHeader(_('WAN Traffic'), 'wan_speed', 'wan_traffic'), + E('th', {}, _('Schedule Rules')), + E('th', {}, _('Actions')) + ]) + ]), + E('tbody', {}) + ]); + + var tbody = table.querySelector('tbody'); + + // 创建移动端å¡ç‰‡å®¹å™¨ + var cardsContainer = E('div', { 'class': 'device-list-cards' }); + + // 过滤:按选择设备 + var selectedMac = (typeof document !== 'undefined' ? (document.getElementById('history-device-select')?.value || '') : ''); + var filteredDevices = (!selectedMac) ? stats.d : stats.d.filter(function (d) { return (d.mac === selectedMac); }); + + // åº”ç”¨æŽ’åº + filteredDevices = sortDevices(filteredDevices, currentSortBy, currentSortOrder); + + // æ£€æŸ¥æ˜¯å¦æœ‰ä»»ä½•设备有 IPv6 åœ°å€ + var hasAnyIPv6 = filteredDevices.some(function (device) { + var lanIPv6 = filterLanIPv6(device.ip6); + return lanIPv6.length > 0; + }); + + // å¡«å……æ•°æ® + filteredDevices.forEach(function (device) { + var isOnline = isDeviceOnline(device); + + // é»˜è®¤ä½¿ç”¨çª„ä¸»é¢˜æ ·å¼ + var buttonText = 'âš™'; + + var actionButton = E('button', { + 'class': 'cbi-button cbi-button-action', + 'title': _('Settings') + }, buttonText); + + actionButton.addEventListener('click', function () { + showRateLimitModal(device); + }); + + var deleteButton = E('button', { + 'class': 'cbi-button cbi-button-reset', + 'title': _('Delete Device') + }, '\u2715'); + deleteButton.addEventListener('click', function (e) { + e.stopPropagation(); + showConfirmDialog( + _('Delete Device'), + _('Are you sure you want to delete this device? Traffic history will be removed.'), + function () { + callDeleteDevice(device.mac).then(function () { + updateDeviceData(); + }).catch(function (err) { + ui.addNotification(null, E('p', {}, _('Failed to delete device')), 'error'); + }); + } + ); + }); + + // 获å–当剿˜¾ç¤ºæ¨¡å¼ + // 移动端强制使用 SimpleMode + var screenWidth = window.innerWidth || document.documentElement.clientWidth; + var isMobileScreen = screenWidth <= 768; + var deviceMode = isMobileScreen ? 'simple' : (localStorage.getItem('bandix_device_mode') || 'simple'); + var isDetailedMode = deviceMode === 'detailed'; + + var uplinkChBadges = buildDeviceUplinkChBadges(device); + var deviceInfoElements = [ + E('div', { 'class': 'device-name' }, [ + E('span', { + 'class': 'device-status ' + (isOnline ? 'online' : 'offline') + }), + device.host || '-' + ]), + E('div', { 'class': 'device-ip' }, [ + device.conn ? E('span', { + 'class': 'device-connection-type', + 'title': device.conn === 'wifi' ? _('Wireless') : (device.conn === 'router' ? _('Router') : _('Wired')) + }, getConnectionTypeIcon(device.conn)) : '', + device.ip4, + uplinkChBadges.length ? E('span', { 'class': 'device-uplink-badges' }, uplinkChBadges) : '' + ]) + ]; + + // 详细模å¼ä¸‹æ˜¾ç¤ºæ›´å¤šä¿¡æ¯ + if (isDetailedMode) { + // åªæœ‰å½“有设备有 IPv6 æ—¶æ‰æ·»åŠ  IPv6 行 + if (hasAnyIPv6) { + var lanIPv6 = filterLanIPv6(device.ip6); + if (lanIPv6.length > 0) { + var allIPv6 = device.ip6 ? device.ip6.join(', ') : ''; + deviceInfoElements.push(E('div', { + 'class': 'device-ipv6', + 'title': allIPv6 + }, lanIPv6.join(', '))); + } else { + deviceInfoElements.push(E('div', { 'class': 'device-ipv6' }, '-')); + } + } + + // 添加 MAC 和最åŽä¸Šçº¿ä¿¡æ¯ + deviceInfoElements.push( + E('div', { 'class': 'device-mac' }, device.mac), + E('div', { 'class': 'device-last-online' }, [ + E('span', {}, _('Last Online') + ': '), + E('span', { 'class': 'device-last-online-value' }, formatLastOnlineTime(device.last)), + E('span', { 'class': 'device-last-online-exact' }, formatLastOnlineExactTime(device.last)) + ]) + ); + } + + var row = E('tr', {}, [ + // è®¾å¤‡ä¿¡æ¯ + E('td', {}, [ + E('div', { 'class': 'device-info' }, deviceInfoElements) + ]), + + // LAN æµé‡ + E('td', {}, [ + E('div', { 'class': 'traffic-info' }, [ + E('div', { 'class': 'traffic-row' }, [ + E('span', { 'class': 'traffic-icon upload' }, '↑'), + E('span', { 'class': 'traffic-speed lan' }, formatByterate(device.l_tx_r || 0, speedUnit)), + E('span', { 'class': 'traffic-total' }, '(' + formatSize(device.l_tx_b || 0) + ')') + ]), + E('div', { 'class': 'traffic-row' }, [ + E('span', { 'class': 'traffic-icon download' }, '↓'), + E('span', { 'class': 'traffic-speed lan' }, formatByterate(device.l_rx_r || 0, speedUnit)), + E('span', { 'class': 'traffic-total' }, '(' + formatSize(device.l_rx_b || 0) + ')') + ]) + ]) + ]), + + // WAN æµé‡ + E('td', {}, [ + E('div', { 'class': 'traffic-info' }, [ + E('div', { 'class': 'traffic-row' }, [ + E('span', { 'class': 'traffic-icon upload' }, '↑'), + E('span', { 'class': 'traffic-speed wan' }, formatByterate(device.w_tx_r || 0, speedUnit)), + E('span', { 'class': 'traffic-total' }, '(' + formatSize(device.w_tx_b || 0) + ')') + ]), + E('div', { 'class': 'traffic-row' }, [ + E('span', { 'class': 'traffic-icon download' }, '↓'), + E('span', { 'class': 'traffic-speed wan' }, formatByterate(device.w_rx_r || 0, speedUnit)), + E('span', { 'class': 'traffic-total' }, '(' + formatSize(device.w_rx_b || 0) + ')') + ]) + ]) + ]), + + // 定时é™é€Ÿè§„则 + (function () { + var activeRules = getActiveRulesForDevice(device.mac); + var allDeviceRules = allScheduleRules.filter(function (r) { return r && r.mac === device.mac; }); + + var rulesInfo = E('div', { 'class': 'schedule-rules-info' }, []); + + if (allDeviceRules.length === 0) { + rulesInfo.appendChild(E('div', { 'style': 'font-size: 0.75rem; opacity: 0.6;' }, '-')); + } else { + // 显示规则总数 + rulesInfo.appendChild(E('div', { + 'style': 'font-size: 0.75rem; font-weight: 600; margin-bottom: 4px;' + }, allDeviceRules.length + ' ' + (allDeviceRules.length === 1 ? _('rule') : _('rules')))); + + // 显示当å‰ç”Ÿæ•ˆçš„规则 + if (activeRules.length > 0) { + // åˆå¹¶å¤šä¸ªè§„则的é™åˆ¶å€¼ + var mergedLimits = mergeActiveRulesLimits(activeRules); + var uploadLimit = mergedLimits.uploadLimit; + var downloadLimit = mergedLimits.downloadLimit; + + // 显示é™é€Ÿå€¼ï¼ˆç®­å¤´å›ºå®šé¢œè‰²ï¼Œæ–‡å­—默认颜色) + var limitsContainer = E('div', { + 'style': 'font-size: 0.75rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;' + }); + + // 上传é™é€Ÿï¼ˆæ©™è‰²ç®­å¤´ï¼‰ + var uploadSpan = E('span', {}); + uploadSpan.appendChild(E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + ';' }, '↑')); + uploadSpan.appendChild(document.createTextNode(uploadLimit > 0 ? formatByterate(uploadLimit, speedUnit) : _('Unlimited'))); + limitsContainer.appendChild(uploadSpan); + + // 下载é™é€Ÿï¼ˆé’色箭头) + var downloadSpan = E('span', {}); + downloadSpan.appendChild(E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + ';' }, '↓')); + downloadSpan.appendChild(document.createTextNode(downloadLimit > 0 ? formatByterate(downloadLimit, speedUnit) : _('Unlimited'))); + limitsContainer.appendChild(downloadSpan); + + rulesInfo.appendChild(limitsContainer); + } else { + rulesInfo.appendChild(E('div', { + 'style': 'font-size: 0.75rem; opacity: 0.5;' + }, _('No active rule'))); + } + } + + // PC 端添加鼠标悬浮事件(显示所有规则)- åªè¦æœ‰è§„则就绑定事件 + var screenWidth = window.innerWidth || document.documentElement.clientWidth; + if (screenWidth > 768 && allDeviceRules.length > 0) { + rulesInfo.onmouseenter = function (evt) { + var tooltip = document.getElementById('schedule-rules-tooltip'); + if (!tooltip) return; + + var html = buildScheduleRulesTooltipHtml(allDeviceRules, activeRules, speedUnit); + if (!html) return; + + tooltip.innerHTML = html; + + + // å…ˆéšè—,设置内容åŽå†æ˜¾ç¤ºä»¥è®¡ç®—尺寸 + tooltip.style.display = 'block'; + tooltip.style.visibility = 'hidden'; + tooltip.style.left = '-9999px'; + tooltip.style.top = '-9999px'; + + // 强制æµè§ˆå™¨è®¡ç®—尺寸 + var tw = tooltip.offsetWidth || 0; + var th = tooltip.offsetHeight || 0; + + if (tw === 0 || th === 0) { + tooltip.style.display = 'none'; + return; + } + + tooltip.style.visibility = 'visible'; + + var padding = 12; + var maxX = window.innerWidth - 4; + var maxY = window.innerHeight - 4; + + var rect = evt.currentTarget.getBoundingClientRect(); + var cx = rect.left + rect.width / 2; + var cy = rect.top + rect.height / 2; + + // 计算ä½ç½®ï¼šä¼˜å…ˆæ˜¾ç¤ºåœ¨å³ä¾§ï¼Œå¦‚果空间ä¸è¶³åˆ™æ˜¾ç¤ºåœ¨å·¦ä¾§ + var baseX = cx + padding; + var baseY = cy - th / 2; + + if (baseX + tw > maxX) { + baseX = cx - tw - padding; + } + + if (baseY < 4) baseY = 4; + if (baseY + th > maxY) baseY = maxY - th - 4; + + tooltip.style.left = baseX + 'px'; + tooltip.style.top = baseY + 'px'; + }; + + rulesInfo.onmouseleave = function () { + var tooltip = document.getElementById('schedule-rules-tooltip'); + if (tooltip) { + tooltip.style.display = 'none'; + tooltip.style.visibility = 'visible'; + } + }; + + rulesInfo.onmousemove = function (evt) { + var tooltip = document.getElementById('schedule-rules-tooltip'); + if (!tooltip || tooltip.style.display === 'none') return; + + var tw = tooltip.offsetWidth || 0; + var th = tooltip.offsetHeight || 0; + var padding = 12; + var maxX = window.innerWidth - 4; + var maxY = window.innerHeight - 4; + + var rect = evt.currentTarget.getBoundingClientRect(); + var cx = rect.left + rect.width / 2; + var cy = rect.top + rect.height / 2; + + var baseX = cx + padding; + var baseY = cy - th / 2; + + if (baseX + tw > maxX) { + baseX = cx - tw - padding; + } + + if (baseY < 4) baseY = 4; + if (baseY + th > maxY) baseY = maxY - th - 4; + + tooltip.style.left = baseX + 'px'; + tooltip.style.top = baseY + 'px'; + }; + } + + return E('td', {}, rulesInfo); + })(), + + // æ“作 + E('td', { 'class': 'device-actions' }, [ + actionButton, + deleteButton + ]) + ]); + + tbody.appendChild(row); + + // 创建移动端å¡ç‰‡ + var card = E('div', { 'class': 'device-card' }, [ + // å¡ç‰‡å¤´éƒ¨ + E('div', { 'class': 'device-card-header' }, [ + E('div', { 'class': 'device-card-name' }, [ + E('span', { 'class': 'device-status ' + (isOnline ? 'online' : 'offline') }), + E('div', {}, [ + E('div', { 'style': 'font-weight: 600;' }, device.host || '-'), + E('div', { 'class': 'device-card-ip' }, [ + device.conn ? E('span', { + 'class': 'device-connection-type', + 'title': device.conn === 'wifi' ? _('Wireless') : (device.conn === 'router' ? _('Router') : _('Wired')) + }, getConnectionTypeIcon(device.conn)) : '', + device.ip4, + (function () { + var badges = buildDeviceUplinkChBadges(device); + return badges.length ? E('span', { 'class': 'device-uplink-badges' }, badges) : ''; + })() + ]) + ]) + ]), + E('div', { 'class': 'device-card-action' }, [ + (function () { + var cardActionBtn = E('button', { + 'class': 'cbi-button cbi-button-action', + 'title': _('Settings') + }, buttonText); + cardActionBtn.addEventListener('click', function () { + showRateLimitModal(device); + }); + return cardActionBtn; + })(), + (function () { + var cardDeleteBtn = E('button', { + 'class': 'cbi-button cbi-button-reset', + 'title': _('Delete Device') + }, '\u2715'); + cardDeleteBtn.addEventListener('click', function (e) { + e.stopPropagation(); + showConfirmDialog( + _('Delete Device'), + _('Are you sure you want to delete this device? Traffic history will be removed.'), + function () { + callDeleteDevice(device.mac).then(function () { + updateDeviceData(); + }).catch(function (err) { + ui.addNotification(null, E('p', {}, _('Failed to delete device')), 'error'); + }); + } + ); + }); + return cardDeleteBtn; + })() + ]) + ]), + // å¡ç‰‡ä¸»è¦å†…容(WANæµé‡ï¼‰ + E('div', { 'class': 'device-card-content' }, [ + // WANæµé‡ + E('div', { 'class': 'device-card-section' }, [ + E('div', { 'class': 'device-card-section-label' }, _('WAN Traffic')), + E('div', { 'class': 'device-card-traffic' }, [ + E('div', { 'class': 'device-card-traffic-row' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↑'), + E('span', { 'style': 'font-weight: 600;' }, formatByterate(device.w_tx_r || 0, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; opacity: 0.7;' }, '(' + formatSize(device.w_tx_b || 0) + ')') + ]), + E('div', { 'class': 'device-card-traffic-row' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↓'), + E('span', { 'style': 'font-weight: 600;' }, formatByterate(device.w_rx_r || 0, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; opacity: 0.7;' }, '(' + formatSize(device.w_rx_b || 0) + ')') + ]) + ]) + ]) + ]), + // 定时é™é€Ÿè§„则 + (function () { + var activeRules = getActiveRulesForDevice(device.mac); + var allDeviceRules = allScheduleRules.filter(function (r) { return r && r.mac === device.mac; }); + + if (allDeviceRules.length === 0) { + return E('div', { 'class': 'device-card-section device-card-rules' }, [ + E('div', { 'class': 'device-card-section-label' }, _('Schedule Rules')), + E('div', { 'class': 'device-card-rules-empty' }, '-') + ]); + } + + var rulesContent = E('div', { 'class': 'device-card-rules-content' }); + + // 显示规则总数 + rulesContent.appendChild(E('div', { + 'class': 'device-card-rules-count' + }, allDeviceRules.length + ' ' + (allDeviceRules.length === 1 ? _('rule') : _('rules')))); + + if (activeRules.length > 0) { + // åˆå¹¶å¤šä¸ªè§„则的é™åˆ¶å€¼ + var mergedLimits = mergeActiveRulesLimits(activeRules); + var uploadLimit = mergedLimits.uploadLimit; + var downloadLimit = mergedLimits.downloadLimit; + + // 显示é™é€Ÿå€¼ + var limitsText = []; + limitsText.push('↑' + (uploadLimit > 0 ? formatByterate(uploadLimit, speedUnit) : _('Unlimited'))); + limitsText.push('↓' + (downloadLimit > 0 ? formatByterate(downloadLimit, speedUnit) : _('Unlimited'))); + + rulesContent.appendChild(E('div', { + 'class': 'device-card-rules-active-time' + }, limitsText.join(' '))); + } else { + rulesContent.appendChild(E('div', { + 'class': 'device-card-rules-inactive' + }, _('No active rule'))); + } + + return E('div', { 'class': 'device-card-section device-card-rules' }, [ + E('div', { 'class': 'device-card-section-label' }, _('Schedule Rules')), + rulesContent + ]); + })(), + // LANæµé‡ï¼ˆç›´æŽ¥æ˜¾ç¤ºï¼Œä¸éœ€è¦å±•å¼€/收起) + E('div', { 'class': 'device-card-section', 'style': 'margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(0, 0, 0, 0.1);' }, [ + E('div', { 'class': 'device-card-section-label' }, _('LAN Traffic')), + E('div', { 'class': 'device-card-traffic' }, [ + E('div', { 'class': 'device-card-traffic-row' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_UPLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↑'), + E('span', { 'style': 'font-weight: 600;' }, formatByterate(device.l_tx_r || 0, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; opacity: 0.7;' }, '(' + formatSize(device.l_tx_b || 0) + ')') + ]), + E('div', { 'class': 'device-card-traffic-row' }, [ + E('span', { 'style': 'color: ' + BANDIX_COLOR_DOWNLOAD + '; font-size: 0.75rem; font-weight: bold;' }, '↓'), + E('span', { 'style': 'font-weight: 600;' }, formatByterate(device.l_rx_r || 0, speedUnit)), + E('span', { 'style': 'font-size: 0.75rem; opacity: 0.7;' }, '(' + formatSize(device.l_rx_b || 0) + ')') + ]) + ]) + ]) + ]); + + cardsContainer.appendChild(card); + }); + + // 更新表格内容 + trafficDiv.innerHTML = ''; + trafficDiv.appendChild(table); + trafficDiv.appendChild(cardsContainer); + // 暴露一个立å³é‡ç»˜è¡¨æ ¼çš„函数,供筛选å˜åŒ–时调用 + try { + window.__bandixRenderTable = function () { + // 釿–°è§¦å‘å®Œæ•´çš„æ•°æ®æ›´æ–°å’Œæ¸²æŸ“ + updateDeviceData(); + }; + } catch (e) { } + + // 更新历å²è¶‹åŠ¿ä¸­çš„è®¾å¤‡ä¸‹æ‹‰ + try { + latestDevices = stats.d || []; + updateDeviceOptions(latestDevices); + } catch (e) { } + }); + } + + // åˆå§‹åŒ–ç»Ÿè®¡æŽ§ä»¶ï¼ˆå»¶è¿Ÿæ‰§è¡Œï¼Œç¡®ä¿ DOM 已渲染) + + // æ›´æ–°ç»Ÿè®¡æ•°æ® + var usageRankingShowAll = false; + var usageRankingData = []; + var USAGE_RANKING_DEFAULT_LIMIT = 10; + var usageRankingCustomRange = null; // 存储自定义时间范围 + + // Traffic Timeline ç‹¬ç«‹çš„æ—¶é—´èŒƒå›´ç®¡ç† + var trafficIncrementsCustomRange = null; + + // æ ¼å¼åŒ–时间范围显示 - 总是显示完整日期时间 + function formatTimeRange(startMs, endMs) { + if (!startMs || !endMs) return ''; + + var startDate = new Date(startMs); + var endDate = new Date(endMs); + + var formatDateTime = function (date) { + var year = date.getFullYear(); + var month = (date.getMonth() + 1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + var hours = date.getHours().toString().padStart(2, '0'); + var minutes = date.getMinutes().toString().padStart(2, '0'); + return year + '/' + month + '/' + day + ' ' + hours + ':' + minutes; + }; + + return formatDateTime(startDate) + ' - ' + formatDateTime(endDate); + } + + function renderUsageRanking(data, showAll) { + var container = document.getElementById('usage-ranking-container'); + if (!container) return; + + if (data.length === 0) { + container.innerHTML = '
' + _('No data') + '
'; + return; + } + + var displayData = showAll ? data : data.slice(0, USAGE_RANKING_DEFAULT_LIMIT); + var rankingList = E('div', { 'class': 'usage-ranking-list' }); + + displayData.forEach(function (item) { + var rankingItem = E('div', { + 'class': 'usage-ranking-item', + 'style': '--progress-width: ' + (item.pct || 0) + '%;' + }, [ + E('div', { 'class': 'usage-ranking-rank' }, (item.r || '-')), + E('div', { 'class': 'usage-ranking-info' }, [ + E('div', { 'class': 'usage-ranking-device' }, [ + E('div', { 'class': 'usage-ranking-name' }, item.host || item.ip4 || item.mac || '-'), + E('div', { 'class': 'usage-ranking-meta' }, [ + E('span', {}, item.ip4 || '-'), + E('span', {}, item.mac || '-'), + E('span', { 'class': 'usage-ranking-meta-total' }, formatSize(item.t_b || 0)) + ]) + ]), + E('div', { 'class': 'usage-ranking-stats' }, [ + E('div', { 'class': 'usage-ranking-traffic' }, [ + E('span', { 'class': 'usage-ranking-traffic-item tx' }, [ + E('span', { 'class': 'usage-ranking-traffic-arrow' }, '↑'), + E('span', {}, formatSize(item.tx_b || 0)) + ]), + E('span', { 'class': 'usage-ranking-traffic-item rx' }, [ + E('span', { 'class': 'usage-ranking-traffic-arrow' }, '↓'), + E('span', {}, formatSize(item.rx_b || 0)) + ]), + E('span', { 'class': 'usage-ranking-traffic-item total' }, [ + E('span', {}, formatSize(item.t_b || 0)) + ]) + ]), + E('div', { 'class': 'usage-ranking-percentage' }, (item.pct || 0).toFixed(1) + '%') + ]) + ]) + ]); + + rankingList.appendChild(rankingItem); + }); + + container.innerHTML = ''; + container.appendChild(rankingList); + + // 如果设备数é‡è¶…过默认é™åˆ¶ï¼Œæ˜¾ç¤ºæŽ§åˆ¶æ  + if (data.length > USAGE_RANKING_DEFAULT_LIMIT) { + var toggleBtn = E('button', { + 'class': 'usage-ranking-toggle-btn' + }, showAll ? _('Show Top %d').format(USAGE_RANKING_DEFAULT_LIMIT) : _('Show All')); + + toggleBtn.addEventListener('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + usageRankingShowAll = !usageRankingShowAll; + renderUsageRanking(usageRankingData, usageRankingShowAll); + }); + + var controls = E('div', { 'class': 'usage-ranking-controls' }, [ + E('span', { 'class': 'usage-ranking-info-text' }, + showAll + ? _('Showing all %d devices').format(data.length) + : _('Showing top %d of %d devices').format(displayData.length, data.length) + ), + toggleBtn + ]); + container.appendChild(controls); + } + } + + function updateTrafficStatistics(customRange, callback) { + // å‡†å¤‡æŸ¥è¯¢å‚æ•° + var startMs = null; + var endMs = null; + var networkTypeSelect = document.getElementById('usage-ranking-network-type'); + var networkType = networkTypeSelect ? networkTypeSelect.value : 'wan'; + if (customRange && customRange.start_ms && customRange.end_ms) { + startMs = customRange.start_ms; + endMs = customRange.end_ms; + console.log('Querying with custom range:', { start_ms: startMs, end_ms: endMs, network_type: networkType }); + } else { + console.log('Querying with default range (no params), network_type:', networkType); + } + + // 获å–è®¾å¤‡ç”¨é‡æŽ’è¡Œ + callGetTrafficUsageRanking(startMs, endMs, networkType).then(function (result) { + console.log('Query result:', result); + if (!result || !result.r) { + return; + } + + usageRankingData = result.r; + + // 更新时间范围显示(包å«ä¸Šä¸‹è¡Œæµé‡å’Œæ€»æµé‡ï¼‰ + var timeRangeEl = document.getElementById('usage-ranking-timerange'); + if (timeRangeEl && result.start && result.end) { + var timeRangeText = formatTimeRange(result.start, result.end); + var parts = []; + if (result.t_tx_b !== undefined && result.t_tx_b !== null) { + parts.push('↑' + formatSize(result.t_tx_b)); + } + if (result.t_rx_b !== undefined && result.t_rx_b !== null) { + parts.push('↓' + formatSize(result.t_rx_b)); + } + if (result.t_b !== undefined && result.t_b !== null) { + parts.push(formatSize(result.t_b)); + } + if (parts.length > 0) { + timeRangeText += ' · ' + parts.join(' · '); + } + timeRangeEl.textContent = timeRangeText; + } + + // 更新设备下拉框 - 获å–完整的设备列表 + if (typeof latestDevices !== 'undefined' && latestDevices.length > 0) { + updateDeviceSelectForIncrements(latestDevices); + } else { + // 如果还没有设备数æ®ï¼Œå…ˆèŽ·å–è®¾å¤‡æ•°æ® + callStatus().then(function (deviceResult) { + if (deviceResult && deviceResult.d) { + latestDevices = deviceResult.d; + updateDeviceSelectForIncrements(latestDevices); + } + }).catch(function (err) { + console.error('Failed to load device list for timeline:', err); + }); + } + + renderUsageRanking(usageRankingData, usageRankingShowAll); + + // 调用回调函数 + if (callback) callback(); + }).catch(function (err) { + console.error('Failed to load usage ranking:', err); + var container = document.getElementById('usage-ranking-container'); + if (container) { + container.innerHTML = '
' + _('Failed to load data') + '
'; + } + + // 调用回调函数(å³ä½¿å¤±è´¥ä¹Ÿè¦ç§»é™¤ loading) + if (callback) callback(); + }); + + } + + function normalizeTrafficIncrementItem(item) { + if (!item) return null; + + var tsMs = item.ts_ms; + if (!tsMs && item.start) tsMs = item.start; + if (!tsMs && item.end) tsMs = item.end; + + var rxBytes = (item.rx_bytes !== undefined && item.rx_bytes !== null) ? item.rx_bytes : null; + var txBytes = (item.tx_bytes !== undefined && item.tx_bytes !== null) ? item.tx_bytes : null; + var totalBytes = (item.total_bytes !== undefined && item.total_bytes !== null) ? item.total_bytes : null; + + if (rxBytes === null) { + rxBytes = (item.w_rx_b || 0) + (item.l_rx_b || 0); + } + if (txBytes === null) { + txBytes = (item.w_tx_b || 0) + (item.l_tx_b || 0); + } + if (totalBytes === null) { + totalBytes = rxBytes + txBytes; + } + + return Object.assign({}, item, { + ts_ms: tsMs || 0, + rx_bytes: rxBytes || 0, + tx_bytes: txBytes || 0, + total_bytes: totalBytes || 0 + }); + } + + function normalizeTrafficIncrementsList(increments) { + if (!Array.isArray(increments)) return []; + return increments.map(normalizeTrafficIncrementItem).filter(function (x) { return x; }); + } + + // ä¸ºäº†è§„é¿ ubus 1MB å“应é™åˆ¶ï¼Œé•¿æ—¶é—´èŒƒå›´æŒ‰å—分段请求 + var TRAFFIC_INCREMENT_CHUNK_MS_HOURLY = 14 * 24 * 60 * 60 * 1000; // 14 天 + var TRAFFIC_INCREMENT_CHUNK_MS_DAILY = 60 * 24 * 60 * 60 * 1000; // 60 天 + + function mergeIncrementsResponse(base, part) { + if (!part) return base; + if (Array.isArray(part.inc)) { + base.inc = base.inc.concat(part.inc); + } + + if (part.start && (!base.start || part.start < base.start)) { + base.start = part.start; + } + if (part.end && (!base.end || part.end > base.end)) { + base.end = part.end; + } + + base.t_rx_b = (base.t_rx_b || 0) + (part.t_rx_b || 0); + base.t_tx_b = (base.t_tx_b || 0) + (part.t_tx_b || 0); + base.t_b = (base.t_b || 0) + (part.t_b || 0); + + if (!base.agg && part.agg) base.agg = part.agg; + if (!base.mac && part.mac) base.mac = part.mac; + if (!base.net && part.net) base.net = part.net; + if (!base.network_type && part.network_type) base.network_type = part.network_type; + + return base; + } + + function buildTrafficIncrementsChunks(startMs, endMs, aggregation) { + if (!startMs || !endMs || endMs <= startMs) { + return null; + } + + var chunkMs = aggregation === 'daily' ? TRAFFIC_INCREMENT_CHUNK_MS_DAILY : TRAFFIC_INCREMENT_CHUNK_MS_HOURLY; + var totalRange = endMs - startMs; + if (totalRange <= chunkMs) { + return null; + } + + var chunks = []; + for (var s = startMs; s < endMs; s += chunkMs) { + chunks.push({ start: s, end: Math.min(s + chunkMs, endMs) }); + } + return chunks; + } + + function fetchTrafficIncrementsChunked(startMs, endMs, aggregation, mac, networkType, onProgress) { + var chunks = buildTrafficIncrementsChunks(startMs, endMs, aggregation); + if (!chunks) { + return callGetTrafficUsageIncrements(startMs, endMs, aggregation, mac, networkType); + } + + if (typeof onProgress === 'function') { + onProgress(0, chunks.length); + } + + var merged = { + start: startMs, + end: endMs, + agg: aggregation, + inc: [], + t_rx_b: 0, + t_tx_b: 0, + t_b: 0 + }; + + var chain = Promise.resolve(merged); + var finished = 0; + chunks.forEach(function (chunk) { + chain = chain.then(function (acc) { + return callGetTrafficUsageIncrements(chunk.start, chunk.end, aggregation, mac, networkType).then(function (part) { + finished += 1; + if (typeof onProgress === 'function') { + onProgress(finished, chunks.length); + } + return mergeIncrementsResponse(acc, part || {}); + }); + }); + }); + + return chain.then(function (result) { + if (Array.isArray(result.inc)) { + result.inc.sort(function (a, b) { + var aTs = (a && (a.start || a.ts_ms || a.end)) || 0; + var bTs = (b && (b.start || b.ts_ms || b.end)) || 0; + return aTs - bTs; + }); + } + return result; + }); + } + + // æ›´æ–°æ—¶é—´åºåˆ—å¢žé‡æ•°æ®ï¼ˆä½¿ç”¨ Traffic Timeline 自己的时间范围) + // Traffic Timeline 缩放å˜é‡ + var incrementsZoomEnabled = false; + var incrementsZoomScale = 1; + var incrementsZoomOffsetX = 0; + var incrementsZoomTimer = null; + + function updateTrafficIncrements(startMs, endMs, aggregation, mac, callback) { + // 如果没有传入时间范围,使用独立的时间范围å˜é‡ + if (!startMs || !endMs) { + if (trafficIncrementsCustomRange) { + startMs = trafficIncrementsCustomRange.start_ms; + endMs = trafficIncrementsCustomRange.end_ms; + } + } + + // 获å–筛选æ¡ä»¶ + var aggregationSelect = document.getElementById('traffic-increments-aggregation'); + var macSelect = document.getElementById('traffic-increments-mac'); + var networkTypeSelect = document.getElementById('traffic-increments-network-type'); + + var selectedAggregation = aggregation || (aggregationSelect ? aggregationSelect.value : 'hourly'); + var selectedMac = mac || (macSelect ? macSelect.value : 'all'); + var selectedNetworkType = networkTypeSelect ? networkTypeSelect.value : 'all'; + + // 如果选择的是 "all",传递 null 使用默认值 + if (selectedMac === 'all') { + selectedMac = null; + } + if (!selectedNetworkType) { + selectedNetworkType = null; + } + + var container = document.getElementById('traffic-increments-container'); + var chunks = buildTrafficIncrementsChunks(startMs, endMs, selectedAggregation); + if (container) { + if (chunks && chunks.length > 1) { + container.innerHTML = '
' + _('Loading in chunks, please wait... (%d/%d)').format(0, chunks.length) + '
'; + } else { + container.innerHTML = '
' + _('Loading...') + '
'; + } + } + + fetchTrafficIncrementsChunked( + startMs, + endMs, + selectedAggregation, + selectedMac, + selectedNetworkType, + function (done, total) { + var progressContainer = document.getElementById('traffic-increments-container'); + if (progressContainer && total > 1) { + progressContainer.innerHTML = '
' + _('Loading in chunks, please wait... (%d/%d)').format(done, total) + '
'; + } + } + ).then(function (result) { + if (!result || !result.inc) { + var container = document.getElementById('traffic-increments-container'); + if (container) { + container.innerHTML = '
' + _('No data') + '
'; + } + // 调用回调函数以移除 loading çŠ¶æ€ + if (callback) callback(); + return; + } + + var normalizedIncrements = normalizeTrafficIncrementsList(result.inc); + + // 更新时间范围显示(包å«ä¸Šä¸‹è¡Œæµé‡å’Œæ€»æµé‡ï¼‰ + var timeRangeEl = document.getElementById('traffic-increments-timerange'); + if (timeRangeEl && result.start && result.end) { + var timeRangeText = formatTimeRange(result.start, result.end); + var parts = []; + if (result.t_tx_b !== undefined && result.t_tx_b !== null) { + parts.push('↑' + formatSize(result.t_tx_b)); + } + if (result.t_rx_b !== undefined && result.t_rx_b !== null) { + parts.push('↓' + formatSize(result.t_rx_b)); + } + if (result.t_b !== undefined && result.t_b !== null) { + parts.push(formatSize(result.t_b)); + } + if (parts.length > 0) { + timeRangeText += ' · ' + parts.join(' · '); + } + timeRangeEl.textContent = timeRangeText; + } + + var container = document.getElementById('traffic-increments-container'); + if (!container) { + // 调用回调函数以移除 loading çŠ¶æ€ + if (callback) callback(); + return; + } + + if (normalizedIncrements.length === 0) { + container.innerHTML = '
' + _('No data') + '
'; + // 调用回调函数以移除 loading çŠ¶æ€ + if (callback) callback(); + return; + } + + // 创建图表容器 + var chartContainer = E('div', { 'class': 'traffic-increments-chart' }); + var canvas = E('canvas', { 'id': 'traffic-increments-chart-canvas' }); + var tooltip = E('div', { 'class': 'traffic-increments-tooltip', 'id': 'traffic-increments-tooltip' }); + chartContainer.appendChild(canvas); + chartContainer.appendChild(tooltip); + + // 创建图例 + var legend = E('div', { 'class': 'traffic-stats-legend' }, [ + E('div', { 'class': 'traffic-stats-legend-item' }, [ + E('span', { 'class': 'traffic-stats-legend-dot tx' }), + E('span', {}, _('Upload')) + ]), + E('div', { 'class': 'traffic-stats-legend-item' }, [ + E('span', { 'class': 'traffic-stats-legend-dot rx' }), + E('span', {}, _('Download')) + ]) + ]); + + // åˆ›å»ºæ±‡æ€»ä¿¡æ¯ + var summary = E('div', { 'class': 'traffic-increments-summary' }, [ + E('div', { 'class': 'traffic-increments-summary-item' }, [ + E('div', { 'class': 'traffic-increments-summary-label' }, _('Total Upload')), + E('div', { 'class': 'traffic-increments-summary-value' }, formatSize(result.t_tx_b || 0)) + ]), + E('div', { 'class': 'traffic-increments-summary-item' }, [ + E('div', { 'class': 'traffic-increments-summary-label' }, _('Total Download')), + E('div', { 'class': 'traffic-increments-summary-value' }, formatSize(result.t_rx_b || 0)) + ]), + E('div', { 'class': 'traffic-increments-summary-item' }, [ + E('div', { 'class': 'traffic-increments-summary-label' }, _('Total')), + E('div', { 'class': 'traffic-increments-summary-value' }, formatSize(result.t_b || 0)) + ]) + ]); + + container.innerHTML = ''; + container.appendChild(chartContainer); + container.appendChild(legend); + container.appendChild(summary); + + // 绘制图表 + setTimeout(function () { + var aggregation = result.agg || 'hourly'; + + // é‡ç½®ç¼©æ”¾çŠ¶æ€ + if (incrementsZoomTimer) { + clearTimeout(incrementsZoomTimer); + incrementsZoomTimer = null; + } + incrementsZoomEnabled = false; + incrementsZoomScale = 1; + incrementsZoomOffsetX = 0; + + drawIncrementsChart(canvas, normalizedIncrements, aggregation, incrementsZoomScale, incrementsZoomOffsetX); + + // 添加鼠标悬浮事件 + setupChartTooltip(canvas, tooltip, normalizedIncrements, aggregation, selectedNetworkType); + + // 添加缩放功能 + canvas.onmouseenter = function () { + if (incrementsZoomTimer) clearTimeout(incrementsZoomTimer); + incrementsZoomTimer = setTimeout(function () { + incrementsZoomEnabled = true; + incrementsZoomTimer = null; + }, 1000); + }; + + canvas.onmouseleave = function () { + if (incrementsZoomTimer) { + clearTimeout(incrementsZoomTimer); + incrementsZoomTimer = null; + } + incrementsZoomEnabled = false; + incrementsZoomScale = 1; + incrementsZoomOffsetX = 0; + drawIncrementsChart(canvas, normalizedIncrements, aggregation, incrementsZoomScale, incrementsZoomOffsetX); + }; + + canvas.onwheel = function (evt) { + if (!incrementsZoomEnabled) return; + evt.preventDefault(); + + var delta = evt.deltaY > 0 ? 0.9 : 1.1; + var newScale = incrementsZoomScale * delta; + + // é™åˆ¶ç¼©æ”¾èŒƒå›´ + if (newScale < 1) newScale = 1; + if (newScale > 10) newScale = 10; + + var rect = canvas.getBoundingClientRect(); + var mouseX = evt.clientX - rect.left; + var info = canvas.__bandixIncrements; + if (!info || !info.originalIncrements) return; + + var padding = { top: 20, right: 20, bottom: 40, left: 80 }; + var chartWidth = rect.width - padding.left - padding.right; + var relativeX = (mouseX - padding.left) / chartWidth; + var totalLen = info.originalIncrements.length; + var mouseDataIndex = relativeX * totalLen; + + // 调整åç§»ä»¥ä¿æŒé¼ æ ‡ä½ç½®ä¸ºç¼©æ”¾ä¸­å¿ƒ + var oldVisibleLen = totalLen / incrementsZoomScale; + var newVisibleLen = totalLen / newScale; + var centerShift = (oldVisibleLen - newVisibleLen) * (mouseDataIndex / totalLen); + + incrementsZoomScale = newScale; + incrementsZoomOffsetX = Math.max(0, Math.min(totalLen - newVisibleLen, incrementsZoomOffsetX + centerShift)); + + // é‡ç»˜å›¾è¡¨ + try { + drawIncrementsChart(canvas, info.originalIncrements, aggregation, incrementsZoomScale, incrementsZoomOffsetX); + // 釿–°è®¾ç½® tooltip(使用原始数æ®ï¼‰ + setupChartTooltip(canvas, tooltip, info.originalIncrements, aggregation, selectedNetworkType); + } catch (e) { + console.error('Zoom error:', e); + } + }; + + // 调用回调函数 + if (callback) callback(); + }, 100); + }).catch(function (err) { + console.error('Failed to load traffic increments:', err); + var container = document.getElementById('traffic-increments-container'); + if (container) { + container.innerHTML = '
' + _('Failed to load data') + '
'; + } + + // 调用回调函数(å³ä½¿å¤±è´¥ä¹Ÿè¦ç§»é™¤ loading) + if (callback) callback(); + }); + } + + // 更新设备下拉框 + function updateDeviceSelectForIncrements(devices) { + var macSelect = document.getElementById('traffic-increments-mac'); + if (!macSelect) return; + + // ä¿å­˜å½“å‰é€‰ä¸­çš„值 + var currentValue = macSelect.value; + + // 清空现有选项(ä¿ç•™ "All Devices") + macSelect.innerHTML = ''; + macSelect.appendChild(E('option', { 'value': 'all' }, _('All Devices'))); + + // 对设备列表进行排åºï¼šåœ¨çº¿è®¾å¤‡åœ¨å‰ï¼Œç¦»çº¿è®¾å¤‡åœ¨åŽï¼Œç„¶åŽæŒ‰IP地å€ä»Žå°åˆ°å¤§æŽ’åº + var sortedDevices = devices.slice().sort(function (a, b) { + var aOnline = isDeviceOnline(a); + var bOnline = isDeviceOnline(b); + + // é¦–å…ˆæŒ‰åœ¨çº¿çŠ¶æ€æŽ’åºï¼šåœ¨çº¿è®¾å¤‡åœ¨å‰ + if (aOnline && !bOnline) return -1; + if (!aOnline && bOnline) return 1; + + // 在线状æ€ç›¸åŒæ—¶ï¼ŒæŒ‰IPåœ°å€æŽ’åº + var aIp = a.ip4 || ''; + var bIp = b.ip4 || ''; + + // å°†IP地å€è½¬æ¢ä¸ºæ•°å­—进行比较 + var aIpParts = aIp.split('.').map(function (part) { return parseInt(part) || 0; }); + var bIpParts = bIp.split('.').map(function (part) { return parseInt(part) || 0; }); + + // 逿®µæ¯”较IPåœ°å€ + for (var i = 0; i < 4; i++) { + var aPart = aIpParts[i] || 0; + var bPart = bIpParts[i] || 0; + if (aPart !== bPart) { + return aPart - bPart; + } + } + + // IP地å€ç›¸åŒæ—¶ï¼ŒæŒ‰MACåœ°å€æŽ’åº + return (a.mac || '').localeCompare(b.mac || ''); + }); + + // 添加设备选项 + sortedDevices.forEach(function (device) { + if (device.mac) { + var label = (device.host || device.ip4 || device.mac || '-') + (device.ip4 ? ' (' + device.ip4 + ')' : '') + (device.mac ? ' [' + device.mac + ']' : ''); + var option = E('option', { 'value': device.mac }, label); + macSelect.appendChild(option); + } + }); + + // æ¢å¤ä¹‹å‰é€‰ä¸­çš„值(如果还在列表中) + if (currentValue && currentValue !== 'all') { + var optionExists = false; + for (var i = 0; i < macSelect.options.length; i++) { + if (macSelect.options[i].value === currentValue) { + optionExists = true; + break; + } + } + if (optionExists) { + macSelect.value = currentValue; + } else { + macSelect.value = 'all'; + } + } + } + + // 绘制时间åºåˆ—增é‡å›¾è¡¨ + function drawIncrementsChart(canvas, increments, aggregation, scale, offsetX) { + if (!canvas || !increments || increments.length === 0) return; + + // ç¼©æ”¾å‚æ•°é»˜è®¤å€¼ + scale = scale || 1; + offsetX = offsetX || 0; + + var dpr = window.devicePixelRatio || 1; + var cssWidth = canvas.parentElement.offsetWidth || 600; + var cssHeight = 300; + + canvas.style.width = cssWidth + 'px'; + canvas.style.height = cssHeight + 'px'; + + canvas.width = Math.max(1, Math.floor(cssWidth * dpr)); + canvas.height = Math.max(1, Math.floor(cssHeight * dpr)); + + var ctx = canvas.getContext('2d'); + ctx.scale(dpr, dpr); + + var width = cssWidth; + var height = cssHeight; + + // 计算最大值(使用原始数æ®ï¼Œç¡®ä¿ç¼©æ”¾æ—¶Y轴范围ä¸å˜ï¼‰ + var originalIncrements = canvas.__bandixIncrementsOriginal || increments; + var maxValue = 0; + originalIncrements.forEach(function (item) { + maxValue = Math.max(maxValue, item.total_bytes || 0); + }); + + if (maxValue === 0) { + ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; + ctx.font = '14px sans-serif'; + ctx.textAlign = 'center'; + ctx.fillText(_('No data'), width / 2, height / 2); + return; + } + + // åŠ¨æ€æµ‹é‡Yè½´æœ€å¤§æ ‡ç­¾å®½åº¦ï¼Œå¢žå¤§å·¦è¾¹è· + var fontSize = 12; + ctx.font = fontSize + 'px sans-serif'; + var maxLabelText = formatSize(maxValue); + var zeroLabelText = formatSize(0); + var maxLabelWidth = Math.max(ctx.measureText(maxLabelText).width, ctx.measureText(zeroLabelText).width); + + var padding = { top: 20, right: 20, bottom: 40, left: 80 }; + padding.left = Math.max(padding.left, Math.ceil(maxLabelWidth) + 30); // ç¡®ä¿å³ä¾§æ—¶é—´ä¸è¢«è£å‰ª + var chartWidth = width - padding.left - padding.right; + var chartHeight = height - padding.top - padding.bottom; + + // ä¿å­˜åŽŸå§‹æ•°æ®åˆ° canvas + if (!canvas.__bandixIncrementsOriginal) { + canvas.__bandixIncrementsOriginal = increments; + } + + // åº”ç”¨ç¼©æ”¾ï¼šåªæ˜¾ç¤ºéƒ¨åˆ†æ•°æ® + var totalLen = increments.length; + var displayIncrements = increments; + var displayStartIndex = 0; + var displayEndIndex = totalLen; + + if (scale > 1) { + var visibleLen = Math.ceil(totalLen / scale); + displayStartIndex = Math.floor(offsetX); + displayEndIndex = Math.min(totalLen, displayStartIndex + visibleLen); + displayIncrements = increments.slice(displayStartIndex, displayEndIndex); + } + + // 清空画布 + ctx.clearRect(0, 0, width, height); + + // 轴与网格样å¼ï¼šå¯¹é½ Realtime Traffic Trends + var axisTextColor = '#9ca3af'; + var gridColor = 'rgba(148,163,184,0.08)'; + ctx.font = '12px sans-serif'; + + // 绘制网格线和标签 + var gridLines = 4; + ctx.strokeStyle = gridColor; + ctx.lineWidth = 0.8; + for (var i = 0; i <= gridLines; i++) { + var y = padding.top + (chartHeight / gridLines) * i; + var value = maxValue * (1 - i / gridLines); + + ctx.beginPath(); + ctx.moveTo(padding.left, y); + ctx.lineTo(width - padding.right, y); + ctx.stroke(); + + ctx.fillStyle = axisTextColor; + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + var yLabelY = (i === gridLines) ? y - 4 : y; + ctx.fillText(formatSize(value), padding.left - 8, yLabelY); + } + + // ç»˜åˆ¶å †å æŸ±çж图 + var barWidth = chartWidth / displayIncrements.length; + var barDisplayWidth = barWidth * 0.7; // æŸ±å­æ˜¾ç¤ºå®½åº¦ï¼ˆç•™å‡ºé—´è·ï¼‰ + + var baseY = height - padding.bottom; + + function px(v) { return Math.round(v); } + function pxStroke(v) { return Math.round(v) + 0.5; } + + displayIncrements.forEach(function (item, index) { + var barX = padding.left + barWidth * index + (barWidth - barDisplayWidth) / 2; + var rxHeight = chartHeight * ((item.rx_bytes || 0) / maxValue); + var txHeight = chartHeight * ((item.tx_bytes || 0) / maxValue); + var totalHeight = rxHeight + txHeight; + + var x = px(barX); + var w = Math.max(1, px(barDisplayWidth)); + var totalH = px(totalHeight); + var rxH = px(rxHeight); + var txH = px(txHeight); + var yBase = px(baseY); + + // 绘制 RX 柱å­ï¼ˆä¸‹è½½ï¼Œé’色)- 底部 + if (rxH > 0) { + var rxY = yBase - rxH; + ctx.fillStyle = BANDIX_COLOR_DOWNLOAD; + ctx.fillRect(x, rxY, w, rxH); + + // 添加边框 + ctx.strokeStyle = '#0891b2'; + ctx.lineWidth = 1; + ctx.strokeRect(pxStroke(x), pxStroke(rxY), w, rxH); + } + + // 绘制 TX 柱å­ï¼ˆä¸Šä¼ ï¼Œæ©™è‰²ï¼‰- å †å åœ¨ RX ä¸Šé¢ + if (txH > 0) { + var txY = yBase - totalH; + ctx.fillStyle = BANDIX_COLOR_UPLOAD; + ctx.fillRect(x, txY, w, txH); + + // 添加边框 + ctx.strokeStyle = '#ea580c'; + ctx.lineWidth = 1; + ctx.strokeRect(pxStroke(x), pxStroke(txY), w, txH); + } + }); + + // ä¿å­˜æŸ±å­çš„ä½ç½®ä¿¡æ¯ï¼Œç”¨äºŽé¼ æ ‡æ‚¬æµ®æ£€æµ‹ + canvas.barPositions = []; + displayIncrements.forEach(function (item, index) { + var barX = padding.left + barWidth * index + (barWidth - barDisplayWidth) / 2; + var originalIndex = displayStartIndex + index; + canvas.barPositions.push({ + x: px(barX), + width: Math.max(1, px(barDisplayWidth)), + index: originalIndex, + item: item + }); + }); + canvas.__bandixIncrements = { + increments: displayIncrements, + originalIncrements: canvas.__bandixIncrementsOriginal || increments, + aggregation: aggregation, + scale: scale, + offsetX: offsetX, + displayStartIndex: displayStartIndex, + displayEndIndex: displayEndIndex + }; + + // 绘制时间标签 - 固定显示 7 个刻度 + ctx.fillStyle = axisTextColor; + ctx.textAlign = 'center'; + var isMobile = window.innerWidth <= 768; + var isDaily = aggregation === 'daily'; + var barWidth = chartWidth / displayIncrements.length; + + // è®¡ç®—è¦æ˜¾ç¤ºçš„æ ‡ç­¾ç´¢å¼•ä½ç½®ï¼ˆå›ºå®š 7 个,包括第一个和最åŽä¸€ä¸ªï¼‰ + var maxLabels = 7; + var labelIndices = []; + if (displayIncrements.length <= maxLabels) { + // 如果数æ®ç‚¹å°‘于等于 7 个,全部显示 + for (var i = 0; i < displayIncrements.length; i++) { + labelIndices.push(i); + } + } else { + // å‡åŒ€åˆ†å¸ƒ 7 个标签 + for (var i = 0; i < maxLabels; i++) { + var idx = Math.round((i / (maxLabels - 1)) * (displayIncrements.length - 1)); + labelIndices.push(idx); + } + } + + // ç§»åŠ¨ç«¯åªæ˜¾ç¤ºç¬¬ä¸€ä¸ªå’Œæœ€åŽä¸€ä¸ª + if (isMobile && displayIncrements.length > 2) { + labelIndices = [0, displayIncrements.length - 1]; + } + + labelIndices.forEach(function (index) { + if (index < 0 || index >= displayIncrements.length) return; + + var item = displayIncrements[index]; + // 标签居中显示在æ¯ä¸ªæŸ±å­ç»„的中心 + var x = padding.left + barWidth * (index + 0.5); + var date = new Date(item.ts_ms); + var timeStr; + + if (isDaily) { + // 按天èšåˆï¼šåªæ˜¾ç¤ºæ—¥æœŸ + var year = date.getFullYear(); + var month = (date.getMonth() + 1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + timeStr = month + '/' + day; + } else { + // æŒ‰å°æ—¶èšåˆï¼šæ˜¾ç¤ºæ•´ç‚¹å°æ—¶ + // 使用 start_ts_ms æ¥ç¡®å®šè¿™ä¸ªæ—¶é—´æ®µä»£è¡¨å“ªä¸ªå°æ—¶ + var startTs = item.start || item.ts_ms; + var startDate = new Date(startTs); + + // ä½¿ç”¨å¼€å§‹æ—¶é—´çš„æ•´ç‚¹å°æ—¶ + var hour = startDate.getHours(); + timeStr = (hour < 10 ? '0' : '') + hour + ':00'; + } + + // æµ‹é‡æ–‡æœ¬å®½åº¦ï¼Œç¡®ä¿ä¸ä¼šè¶…出边界 + var textWidth = ctx.measureText(timeStr).width; + var labelX = x; + + // 检查å³ä¾§è¾¹ç•Œ + if (labelX + textWidth / 2 > width - padding.right) { + labelX = width - padding.right - textWidth / 2; + } + + // 检查左侧边界 + if (labelX - textWidth / 2 < padding.left) { + labelX = padding.left + textWidth / 2; + } + + ctx.fillText(timeStr, labelX, height - padding.bottom + 20); + }); + + // 如果存在 hoverIndex,则绘制垂直虚线(鼠标对ç€çš„æŸ±å­ï¼‰ + // 移动端ä¸ç»˜åˆ¶è™šçº¿ + try { + if (isMobile) return; // 移动端ä¸ç»˜åˆ¶æ‚¬æµ®è™šçº¿ + + var hoverIndex = canvas.__bandixIncrementsHoverIndex; + if (typeof hoverIndex === 'number' && hoverIndex >= 0) { + // 计算在显示数æ®ä¸­çš„索引 + var displayIndex = hoverIndex - displayStartIndex; + if (displayIndex >= 0 && displayIndex < displayIncrements.length) { + var barX = padding.left + barWidth * displayIndex + (barWidth - barDisplayWidth) / 2; + var hoverX = barX + barDisplayWidth / 2; // 虚线在柱å­ä¸­å¿ƒ + + ctx.save(); + ctx.strokeStyle = 'rgba(156,163,175,0.9)'; + ctx.lineWidth = 1; + ctx.setLineDash([6, 4]); + ctx.beginPath(); + ctx.moveTo(hoverX, padding.top); + ctx.lineTo(hoverX, height - padding.bottom); + ctx.stroke(); + ctx.setLineDash([]); + ctx.restore(); + } + } + } catch (e) { /* 安全兜底 */ } + } + + // 设置图表 tooltip + function setupChartTooltip(canvas, tooltip, increments, aggregation, networkType) { + if (!canvas || !tooltip || !increments || increments.length === 0) return; + + var formatTime = function (tsMs, isDaily) { + var date = new Date(tsMs); + if (isDaily) { + var year = date.getFullYear(); + var month = (date.getMonth() + 1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + return year + '/' + month + '/' + day; + } else { + var year = date.getFullYear(); + var month = (date.getMonth() + 1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + var hours = date.getHours().toString().padStart(2, '0'); + var minutes = date.getMinutes().toString().padStart(2, '0'); + return year + '/' + month + '/' + day + ' ' + hours + ':' + minutes; + } + }; + + var formatTimeRange = function (startTsMs, endTsMs, isDaily) { + var startTime = formatTime(startTsMs, isDaily); + var endTime = formatTime(endTsMs, isDaily); + + if (isDaily) { + return startTime + ' - ' + endTime; + } else { + // 如果是åŒä¸€æ—¥æœŸï¼Œåªæ˜¾ç¤ºä¸€æ¬¡æ—¥æœŸ + var startDate = new Date(startTsMs); + var endDate = new Date(endTsMs); + if (startDate.toDateString() === endDate.toDateString()) { + var year = startDate.getFullYear(); + var month = (startDate.getMonth() + 1).toString().padStart(2, '0'); + var day = startDate.getDate().toString().padStart(2, '0'); + var startTimeOnly = startDate.getHours().toString().padStart(2, '0') + ':' + + startDate.getMinutes().toString().padStart(2, '0'); + var endTimeOnly = endDate.getHours().toString().padStart(2, '0') + ':' + + endDate.getMinutes().toString().padStart(2, '0'); + return year + '/' + month + '/' + day + ' ' + startTimeOnly + ' - ' + endTimeOnly; + } else { + return startTime + ' - ' + endTime; + } + } + }; + + var isDaily = aggregation === 'daily'; + var padding = { top: 20, right: 20, bottom: 40, left: 80 }; + var chartWidth = (canvas.parentElement.offsetWidth || 600) - padding.left - padding.right; + var barWidth = chartWidth / increments.length; + var barDisplayWidth = barWidth * 0.7; + + canvas.addEventListener('mousemove', function (e) { + var rect = canvas.getBoundingClientRect(); + var x = e.clientX - rect.left; + var y = e.clientY - rect.top; + + // 检查鼠标是å¦åœ¨å›¾è¡¨åŒºåŸŸå†… + if (x < padding.left || x > rect.width - padding.right || + y < padding.top || y > rect.height - padding.bottom) { + // æ¸…é™¤æ‚¬æµ®ç´¢å¼•å¹¶é‡æ–°ç»˜åˆ¶å›¾è¡¨ä»¥æ¸…除虚线 + delete canvas.__bandixIncrementsHoverIndex; + var info = canvas.__bandixIncrements; + if (info && info.originalIncrements) { + drawIncrementsChart(canvas, info.originalIncrements, aggregation, info.scale || 1, info.offsetX || 0); + } else { + drawIncrementsChart(canvas, increments, aggregation); + } + tooltip.style.display = 'none'; + return; + } + + // æ‰¾åˆ°å¯¹åº”çš„æŸ±å­ + var barIndex = -1; + if (canvas.barPositions) { + for (var i = 0; i < canvas.barPositions.length; i++) { + var bar = canvas.barPositions[i]; + if (x >= bar.x && x <= bar.x + bar.width) { + barIndex = bar.index; + break; + } + } + } + + // 使用原始数æ®èŽ·å– item + var info = canvas.__bandixIncrements; + var originalIncrements = (info && info.originalIncrements) ? info.originalIncrements : increments; + + if (barIndex >= 0 && barIndex < originalIncrements.length) { + // 设置悬浮索引,用于绘制垂直虚线 + var prevHoverIndex = canvas.__bandixIncrementsHoverIndex; + canvas.__bandixIncrementsHoverIndex = barIndex; + + // åªæœ‰å½“ hoverIndex å‘生å˜åŒ–æ—¶æ‰é‡æ–°ç»˜åˆ¶ + if (prevHoverIndex !== barIndex) { + if (info && info.originalIncrements) { + drawIncrementsChart(canvas, info.originalIncrements, aggregation, info.scale || 1, info.offsetX || 0); + } else { + drawIncrementsChart(canvas, increments, aggregation); + } + } + + var item = originalIncrements[barIndex]; + var timeStr = formatTimeRange(item.start || item.ts_ms, item.end || item.ts_ms, isDaily); + + // Get speed unit from UCI config + var speedUnit = uci.get('bandix', 'traffic', 'speed_unit') || 'bytes'; + + var tooltipContent = '
' + timeStr + '
'; + + // æ ¹æ®ç½‘络类型显示相应的section + if (networkType === 'wan') { + tooltipContent += + // WAN Traffic Section + '
' + + '
' + _('WAN Traffic') + '
' + + + // ç”¨é‡æ•°æ®ï¼ˆå¤§å­—体,带颜色) + '
' + + '
' + + '
WAN Upload
' + + '
' + formatSize(item.w_tx_b || 0) + '
' + + '
' + + '
' + + '
WAN Download
' + + '
' + formatSize(item.w_rx_b || 0) + '
' + + '
' + + '
' + + + // 速度统计分组 + '
' + + '
' + _('Upload Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.w_tx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.w_tx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.w_tx_max || 0, speedUnit) + '
' + + + '
' + _('Download Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.w_rx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.w_rx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.w_rx_max || 0, speedUnit) + '
' + + '
'; + } else if (networkType === 'lan') { + tooltipContent += + // LAN Traffic Section + '
' + + '
' + _('LAN Traffic') + '
' + + + // ç”¨é‡æ•°æ®ï¼ˆå¤§å­—体,带颜色) + '
' + + '
' + + '
LAN Upload
' + + '
' + formatSize(item.l_tx_b || 0) + '
' + + '
' + + '
' + + '
LAN Download
' + + '
' + formatSize(item.l_rx_b || 0) + '
' + + '
' + + '
' + + + // 速度统计分组 + '
' + + '
' + _('Upload Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.l_tx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.l_tx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.l_tx_max || 0, speedUnit) + '
' + + + '
' + _('Download Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.l_rx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.l_rx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.l_rx_max || 0, speedUnit) + '
' + + '
'; + } else { + // networkType === 'all' 或其他情况,显示所有section + tooltipContent += + // WAN Traffic Section + '
' + + '
' + _('WAN Traffic') + '
' + + + // ç”¨é‡æ•°æ®ï¼ˆå¤§å­—体,带颜色) + '
' + + '
' + + '
WAN Upload
' + + '
' + formatSize(item.w_tx_b || 0) + '
' + + '
' + + '
' + + '
WAN Download
' + + '
' + formatSize(item.w_rx_b || 0) + '
' + + '
' + + '
' + + + // 速度统计分组 + '
' + + '
' + _('Upload Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.w_tx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.w_tx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.w_tx_max || 0, speedUnit) + '
' + + + '
' + _('Download Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.w_rx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.w_rx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.w_rx_max || 0, speedUnit) + '
' + + '
' + + + // LAN Traffic Section + '
' + + '
' + _('LAN Traffic') + '
' + + + // ç”¨é‡æ•°æ®ï¼ˆå¤§å­—体,带颜色) + '
' + + '
' + + '
LAN Upload
' + + '
' + formatSize(item.l_tx_b || 0) + '
' + + '
' + + '
' + + '
LAN Download
' + + '
' + formatSize(item.l_rx_b || 0) + '
' + + '
' + + '
' + + + // 速度统计分组 + '
' + + '
' + _('Upload Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.l_tx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.l_tx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.l_tx_max || 0, speedUnit) + '
' + + + '
' + _('Download Statistics') + '
' + + '
' + _('Average') + '' + formatByterate(item.l_rx_avg || 0, speedUnit) + '
' + + '
P95' + formatByterate(item.l_rx_p95 || 0, speedUnit) + '
' + + '
' + _('Maximum') + '' + formatByterate(item.l_rx_max || 0, speedUnit) + '
' + + '
'; + } + + tooltip.innerHTML = tooltipContent; + + tooltip.style.display = 'block'; + + // å¼ºåˆ¶é‡æ–°è®¡ç®—å¸ƒå±€ä»¥èŽ·å–æ­£ç¡®çš„尺寸 + tooltip.offsetHeight; // 触å‘釿–°è®¡ç®— + + // 获å–tooltip的实际尺寸 + var tooltipWidth = tooltip.offsetWidth || 280; + var tooltipHeight = tooltip.offsetHeight || 200; + + // ä½¿ç”¨å…¨å±€åæ ‡ï¼ˆfixed 定ä½ï¼‰ + // 默认ä½ç½®ï¼šé¼ æ ‡å³ä¸Šè§’(增加è·ç¦»ï¼Œä¸è¦å¤ªè¿‘) + var tooltipX = e.clientX + 20; + var tooltipY = e.clientY - tooltipHeight - 20; + + // 如果上方空间ä¸è¶³ï¼Œæ˜¾ç¤ºåœ¨é¼ æ ‡ä¸‹æ–¹ + if (tooltipY < 0) { + tooltipY = e.clientY + 20; + } + + // 如果å³ä¾§ç©ºé—´ä¸è¶³ï¼Œæ˜¾ç¤ºåœ¨é¼ æ ‡å·¦ä¾§ + if (tooltipX + tooltipWidth > window.innerWidth) { + tooltipX = e.clientX - tooltipWidth - 20; + } + + // ç¡®ä¿tooltipä¸ä¼šè¶…出左侧边界 + if (tooltipX < 0) { + tooltipX = 10; + } + // ç¡®ä¿tooltipä¸ä¼šè¶…出顶部边界 + if (tooltipY < 0) { + tooltipY = 10; + } + // ç¡®ä¿tooltipä¸ä¼šè¶…出底部边界 + if (tooltipY + tooltipHeight > window.innerHeight) { + tooltipY = window.innerHeight - tooltipHeight - 10; + } + + tooltip.style.left = tooltipX + 'px'; + tooltip.style.top = tooltipY + 'px'; + } else { + // 清除悬浮索引 + delete canvas.__bandixIncrementsHoverIndex; + tooltip.style.display = 'none'; + } + }); + + canvas.addEventListener('mouseleave', function () { + // æ¸…é™¤æ‚¬æµ®ç´¢å¼•å¹¶é‡æ–°ç»˜åˆ¶å›¾è¡¨ä»¥æ¸…除虚线 + delete canvas.__bandixIncrementsHoverIndex; + drawIncrementsChart(canvas, increments, aggregation); + tooltip.style.display = 'none'; + }); + } + + // è½®è¯¢èŽ·å–æ•°æ® + poll.add(updateDeviceData, 1); + + // 轮询获å–定时é™é€Ÿè§„则(æ¯5秒) + poll.add(function () { + return fetchAllScheduleRules().then(function () { + // 规则更新åŽï¼Œé‡æ–°æ¸²æŸ“è¡¨æ ¼ä»¥æ˜¾ç¤ºæœ€æ–°çš„è§„åˆ™çŠ¶æ€ + if (window.__bandixRenderTable) { + window.__bandixRenderTable(); + } + }); + }, 5000); + + // Traffic Statistics ä¸å†è‡ªåŠ¨åˆ·æ–°ï¼Œæ”¹ä¸ºæ‰‹åŠ¨æŸ¥è¯¢ + + // ç«‹å³æ‰§è¡Œä¸€æ¬¡ï¼Œä¸ç­‰å¾…轮询 + updateDeviceData(); + refreshWhitelistStatus(); + fetchAllScheduleRules(); + updateTrafficStatistics(); + + // åˆå§‹åŒ–时间范围查询功能 + setTimeout(function () { + var startDateInput = document.getElementById('usage-ranking-start-date'); + var endDateInput = document.getElementById('usage-ranking-end-date'); + var queryBtn = document.getElementById('usage-ranking-query-btn'); + var resetBtn = document.getElementById('usage-ranking-reset-btn'); + var networkTypeSelect = document.getElementById('usage-ranking-network-type'); + var timeline = document.getElementById('usage-ranking-timeline'); + var timelineRange = document.getElementById('usage-ranking-timeline-range'); + var sectionEl = startDateInput ? (startDateInput.closest('.traffic-stats-section') || document) : document; + var presetBtns = sectionEl.querySelectorAll('.usage-ranking-query-presets .cbi-button[data-preset]'); + + if (!presetBtns.length || !startDateInput || !endDateInput || !queryBtn || !resetBtn) { + console.error('Time range query elements not found'); + return; + } + + var today = new Date(); + today.setHours(0, 0, 0, 0); + var todayMs = today.getTime(); + + var formatDateInput = function (date) { + var year = date.getFullYear(); + var month = (date.getMonth() + 1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + return year + '-' + month + '-' + day; + }; + + // 设置最大日期为今天(ä¸èƒ½é€‰æ‹©æœªæ¥ï¼‰ + var todayStr = formatDateInput(today); + startDateInput.max = todayStr; + endDateInput.max = todayStr; + + var updateTimeline = function (startDate, endDate) { + if (!timeline || !timelineRange || !startDate || !endDate) return; + + var startMs = new Date(startDate + 'T00:00:00').getTime(); + var endMs = new Date(endDate + 'T23:59:59').getTime(); + + // 计算时间范围在时间轴上的ä½ç½®ï¼ˆå‡è®¾æ—¶é—´è½´ä»£è¡¨æœ€è¿‘一年) + var oneYearAgoMs = todayMs - 365 * 24 * 60 * 60 * 1000; + var totalRange = todayMs - oneYearAgoMs; + var selectedRange = endMs - startMs; + + var leftPercent = Math.max(0, ((startMs - oneYearAgoMs) / totalRange) * 100); + var widthPercent = Math.min(100, (selectedRange / totalRange) * 100); + + timelineRange.style.left = leftPercent + '%'; + timelineRange.style.width = widthPercent + '%'; + }; + + var setDateRange = function (startDate, endDate, preset) { + startDateInput.value = formatDateInput(new Date(startDate)); + endDateInput.value = formatDateInput(new Date(endDate)); + + // æ›´æ–°å¿«æ·æŒ‰é’®çŠ¶æ€ + presetBtns.forEach(function (btn) { + btn.className = 'cbi-button cbi-button-neutral'; + }); + if (preset) { + var presetBtn = sectionEl.querySelector('.usage-ranking-query-presets .cbi-button[data-preset="' + preset + '"]'); + if (presetBtn) presetBtn.className = 'cbi-button cbi-button-positive'; + } + + // æ›´æ–°æ—¶é—´è½´ + updateTimeline(startDateInput.value, endDateInput.value); + }; + + var queryData = function () { + var startDate = startDateInput.value; + var endDate = endDateInput.value; + + if (!startDate || !endDate) { + alert(_('Please select both start and end dates')); + return; + } + + var startMs = new Date(startDate + 'T00:00:00').getTime(); + var endMs = new Date(endDate + 'T23:59:59').getTime(); + + if (startMs > endMs) { + alert(_('Start date must be earlier than end date')); + return; + } + + usageRankingCustomRange = { + start_ms: startMs, + end_ms: endMs + }; + + // 设置 loading 状æ€ï¼ˆä½¿ç”¨ bandix-loading,é¿å…与主题的 loading 冲çªå¯¼è‡´å°ºå¯¸å˜åŒ–) + if (queryBtn) { + queryBtn.disabled = true; + queryBtn.classList.add('bandix-loading'); + } + + console.log('Querying with range:', usageRankingCustomRange); + + // ç¡®ä¿æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥ï¼Œéƒ½ä¼šç§»é™¤ loading çŠ¶æ€ + var removeLoading = function () { + if (queryBtn) { + queryBtn.disabled = false; + queryBtn.classList.remove('bandix-loading'); + } + }; + + try { + updateTrafficStatistics(usageRankingCustomRange, removeLoading); + } catch (error) { + console.error('Query failed:', error); + removeLoading(); + } + }; + + // å¿«æ·é€‰é¡¹æŒ‰é’®äº‹ä»¶ + presetBtns.forEach(function (btn) { + btn.addEventListener('click', function () { + var preset = this.getAttribute('data-preset'); + var startDate, endDate; + + switch (preset) { + case 'today': + startDate = new Date(today); + endDate = new Date(today); + break; + case 'thisweek': + // 本周:周一到今天 + var dayOfWeek = today.getDay(); // 0=周日, 1=周一, ..., 6=周六 + var mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // 计算到本周一的å移天数 + startDate = new Date(todayMs + mondayOffset * 24 * 60 * 60 * 1000); + startDate.setHours(0, 0, 0, 0); + endDate = new Date(today); + break; + case 'lastweek': + // 上周:周一到周日(完整的一周) + var lastWeekDayOfWeek = today.getDay(); + // 计算到上周一的å移天数 + var lastWeekMondayOffset = lastWeekDayOfWeek === 0 ? -13 : -6 - lastWeekDayOfWeek; + startDate = new Date(todayMs + lastWeekMondayOffset * 24 * 60 * 60 * 1000); + startDate.setHours(0, 0, 0, 0); + endDate = new Date(startDate); + endDate.setDate(endDate.getDate() + 6); // 上周日(周一+6天) + endDate.setHours(23, 59, 59, 999); + break; + case 'thismonth': + // 本月:1å·åˆ°ä»Šå¤© + startDate = new Date(today.getFullYear(), today.getMonth(), 1); + endDate = new Date(today); + break; + case 'lastmonth': + // 上月:1å·åˆ°æœ€åŽä¸€å¤© + var lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1); + startDate = new Date(lastMonth.getFullYear(), lastMonth.getMonth(), 1); + endDate = new Date(lastMonth.getFullYear(), lastMonth.getMonth() + 1, 0); // 上个月的最åŽä¸€å¤© + break; + case '7days': + startDate = new Date(todayMs - 6 * 24 * 60 * 60 * 1000); + endDate = new Date(today); + break; + case '30days': + startDate = new Date(todayMs - 29 * 24 * 60 * 60 * 1000); + endDate = new Date(today); + break; + case '90days': + startDate = new Date(todayMs - 89 * 24 * 60 * 60 * 1000); + endDate = new Date(today); + break; + case '1year': + startDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + endDate = new Date(today); + break; + } + + setDateRange(startDate, endDate, preset); + queryData(); + }); + }); + + // 日期输入å˜åŒ–事件 + startDateInput.addEventListener('change', function () { + updateTimeline(this.value, endDateInput.value); + }); + + endDateInput.addEventListener('change', function () { + updateTimeline(startDateInput.value, this.value); + }); + + // 查询按钮 + if (queryBtn) { + queryBtn.addEventListener('click', queryData); + } + + // 网络类型切æ¢åŽè‡ªåŠ¨æŸ¥è¯¢ï¼ˆä¸Ž Traffic Timeline 行为一致) + if (networkTypeSelect) { + networkTypeSelect.addEventListener('change', function () { + if (queryBtn) { + queryBtn.disabled = true; + queryBtn.classList.add('bandix-loading'); + } + + var removeLoading = function () { + if (queryBtn) { + queryBtn.disabled = false; + queryBtn.classList.remove('bandix-loading'); + } + }; + + try { + updateTrafficStatistics(usageRankingCustomRange, removeLoading); + } catch (e) { + removeLoading(); + } + }); + } + + // é‡ç½®æŒ‰é’® + if (resetBtn) { + resetBtn.addEventListener('click', function () { + var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + setDateRange(oneYearAgo, today, '1year'); + queryData(); + }); + } + + // åˆå§‹åŒ–:默认选择最近一年 + var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + setDateRange(oneYearAgo, today, '1year'); + + // 设置åˆå§‹æ—¶é—´èŒƒå›´å¹¶è‡ªåŠ¨åŠ è½½æ•°æ®ï¼ˆç»“æŸæ—¶é—´ä¸ºå½“天的 23:59:59) + var startMs = oneYearAgo.getTime(); + var endToday = new Date(today); + endToday.setHours(23, 59, 59, 999); + var endMs = endToday.getTime(); + usageRankingCustomRange = { + start_ms: startMs, + end_ms: endMs + }; + // 使用åˆå§‹æ—¶é—´èŒƒå›´é‡æ–°åŠ è½½æ•°æ® + updateTrafficStatistics(usageRankingCustomRange); + }, 500); + + // åˆå§‹åŒ–æ—¶é—´åºåˆ—筛选æ¡ä»¶ + setTimeout(function () { + var aggregationSelect = document.getElementById('traffic-increments-aggregation'); + var macSelect = document.getElementById('traffic-increments-mac'); + var networkTypeSelect = document.getElementById('traffic-increments-network-type'); + + if (aggregationSelect) { + aggregationSelect.addEventListener('change', function () { + // 使用 Traffic Timeline 自己的时间范围 + updateTrafficIncrements(); + }); + } + + if (macSelect) { + macSelect.addEventListener('change', function () { + // 使用 Traffic Timeline 自己的时间范围 + updateTrafficIncrements(); + }); + } + + if (networkTypeSelect) { + networkTypeSelect.addEventListener('change', function () { + updateTrafficIncrements(); + }); + } + }, 600); + + // åˆå§‹åŒ– Traffic Timeline 时间范围选择功能 + setTimeout(function () { + var startDateInput = document.getElementById('traffic-increments-start-date'); + var endDateInput = document.getElementById('traffic-increments-end-date'); + var queryBtn = document.getElementById('traffic-increments-query-btn'); + var resetBtn = document.getElementById('traffic-increments-reset-btn'); + var sectionEl = startDateInput ? (startDateInput.closest('.traffic-stats-section') || document) : document; + var presetBtns = sectionEl.querySelectorAll('.usage-ranking-query-presets .cbi-button[data-preset]'); + var timeline = document.getElementById('traffic-increments-timeline'); + var timelineRange = document.getElementById('traffic-increments-timeline-range'); + + if (!presetBtns.length || !startDateInput || !endDateInput || !queryBtn || !resetBtn) { + console.error('Traffic Timeline time range query elements not found'); + return; + } + + var today = new Date(); + today.setHours(0, 0, 0, 0); + var todayMs = today.getTime(); + + var formatDateInput = function (date) { + var year = date.getFullYear(); + var month = (date.getMonth() + 1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + return year + '-' + month + '-' + day; + }; + + // 设置最大日期为今天(ä¸èƒ½é€‰æ‹©æœªæ¥ï¼‰ + var todayStr = formatDateInput(today); + startDateInput.max = todayStr; + endDateInput.max = todayStr; + + var updateTimeline = function (startDate, endDate) { + if (!timeline || !timelineRange || !startDate || !endDate) return; + + var startMs = new Date(startDate + 'T00:00:00').getTime(); + var endMs = new Date(endDate + 'T23:59:59').getTime(); + + var oneYearAgoMs = todayMs - 365 * 24 * 60 * 60 * 1000; + var totalRange = todayMs - oneYearAgoMs; + var selectedRange = endMs - startMs; + + var leftPercent = Math.max(0, ((startMs - oneYearAgoMs) / totalRange) * 100); + var widthPercent = Math.min(100, (selectedRange / totalRange) * 100); + + timelineRange.style.left = leftPercent + '%'; + timelineRange.style.width = widthPercent + '%'; + }; + + var setDateRange = function (startDate, endDate, preset) { + startDateInput.value = formatDateInput(new Date(startDate)); + endDateInput.value = formatDateInput(new Date(endDate)); + + // æ›´æ–°å¿«æ·æŒ‰é’®çŠ¶æ€ + presetBtns.forEach(function (btn) { + btn.className = 'cbi-button cbi-button-neutral'; + }); + if (preset) { + var presetBtn = sectionEl.querySelector('.usage-ranking-query-presets .cbi-button[data-preset="' + preset + '"]'); + if (presetBtn) presetBtn.className = 'cbi-button cbi-button-positive'; + } + + updateTimeline(startDateInput.value, endDateInput.value); + }; + + var queryData = function () { + var startDate = startDateInput.value; + var endDate = endDateInput.value; + + if (!startDate || !endDate) { + alert(_('Please select both start and end dates')); + return; + } + + var startMs = new Date(startDate + 'T00:00:00').getTime(); + var endMs = new Date(endDate + 'T23:59:59').getTime(); + + if (startMs > endMs) { + alert(_('Start date must be earlier than end date')); + return; + } + + trafficIncrementsCustomRange = { + start_ms: startMs, + end_ms: endMs + }; + + // 设置 loading 状æ€ï¼ˆä½¿ç”¨ bandix-loading,é¿å…与主题的 loading 冲çªå¯¼è‡´å°ºå¯¸å˜åŒ–) + if (queryBtn) { + queryBtn.disabled = true; + queryBtn.classList.add('bandix-loading'); + } + + console.log('Traffic Timeline querying with range:', trafficIncrementsCustomRange); + + // ç¡®ä¿æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥ï¼Œéƒ½ä¼šç§»é™¤ loading çŠ¶æ€ + var removeLoading = function () { + if (queryBtn) { + queryBtn.disabled = false; + queryBtn.classList.remove('bandix-loading'); + } + }; + + try { + updateTrafficIncrements(startMs, endMs, null, null, removeLoading); + } catch (error) { + console.error('Traffic Timeline query failed:', error); + removeLoading(); + } + }; + + // å¿«æ·é€‰é¡¹æŒ‰é’®äº‹ä»¶ + presetBtns.forEach(function (btn) { + btn.addEventListener('click', function () { + var preset = this.getAttribute('data-preset'); + var startDate, endDate; + + switch (preset) { + case 'today': + startDate = new Date(today); + endDate = new Date(today); + break; + case 'thisweek': + var dayOfWeek = today.getDay(); + var mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; + startDate = new Date(todayMs + mondayOffset * 24 * 60 * 60 * 1000); + startDate.setHours(0, 0, 0, 0); + endDate = new Date(today); + break; + case 'lastweek': + var lastWeekDayOfWeek = today.getDay(); + var lastWeekMondayOffset = lastWeekDayOfWeek === 0 ? -13 : -6 - lastWeekDayOfWeek; + startDate = new Date(todayMs + lastWeekMondayOffset * 24 * 60 * 60 * 1000); + startDate.setHours(0, 0, 0, 0); + endDate = new Date(startDate); + endDate.setDate(endDate.getDate() + 6); + endDate.setHours(23, 59, 59, 999); + break; + case 'thismonth': + startDate = new Date(today.getFullYear(), today.getMonth(), 1); + endDate = new Date(today); + break; + case 'lastmonth': + var lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1); + startDate = new Date(lastMonth.getFullYear(), lastMonth.getMonth(), 1); + endDate = new Date(lastMonth.getFullYear(), lastMonth.getMonth() + 1, 0); + break; + case '7days': + startDate = new Date(todayMs - 6 * 24 * 60 * 60 * 1000); + endDate = new Date(today); + break; + case '30days': + startDate = new Date(todayMs - 29 * 24 * 60 * 60 * 1000); + endDate = new Date(today); + break; + case '90days': + startDate = new Date(todayMs - 89 * 24 * 60 * 60 * 1000); + endDate = new Date(today); + break; + case '1year': + startDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + endDate = new Date(today); + break; + } + + setDateRange(startDate, endDate, preset); + queryData(); + }); + }); + + // 查询按钮 + if (queryBtn) { + queryBtn.addEventListener('click', queryData); + } + + // é‡ç½®æŒ‰é’® + if (resetBtn) { + resetBtn.addEventListener('click', function () { + var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + setDateRange(oneYearAgo, today, '1year'); + queryData(); + }); + } + + // åˆå§‹åŒ–:默认选择最近一年 + var oneYearAgo = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + setDateRange(oneYearAgo, today, '1year'); + + startDateInput.addEventListener('change', function () { + updateTimeline(this.value, endDateInput.value); + }); + + endDateInput.addEventListener('change', function () { + updateTimeline(startDateInput.value, this.value); + }); + + // 设置åˆå§‹æ—¶é—´èŒƒå›´å¹¶è‡ªåŠ¨åŠ è½½æ•°æ®ï¼ˆä¸æ˜¾ç¤º loading) + var startMs = oneYearAgo.getTime(); + var endToday = new Date(today); + endToday.setHours(23, 59, 59, 999); + var endMs = endToday.getTime(); + trafficIncrementsCustomRange = { + start_ms: startMs, + end_ms: endMs + }; + // 自动加载数æ®ï¼Œä½†ä¸è®¾ç½® loading çŠ¶æ€ + updateTrafficIncrements(startMs, endMs, null, null); + }, 700); + + // 异步加载版本信æ¯ï¼ˆä¸é˜»å¡žä¸»æµç¨‹ï¼‰ + (function () { + // 延迟执行,确ä¿é¡µé¢å…ˆå®Œæˆåˆå§‹åŒ– + setTimeout(function () { + callGetVersion().then(function (result) { + if (result) { + // 显示 luci-app-bandix 版本 + var luciVersionEl = document.getElementById('bandix-luci-version'); + if (luciVersionEl && result.luci_app_version) { + luciVersionEl.textContent = result.luci_app_version; + } + + // 显示 bandix 版本 + var coreVersionEl = document.getElementById('bandix-core-version'); + if (coreVersionEl && result.bandix_version) { + coreVersionEl.textContent = result.bandix_version; + } + } + }).catch(function (err) { + // é™é»˜å¤±è´¥ï¼Œä¸å½±å“页é¢åŠŸèƒ½ + console.debug('Failed to load version:', err); + }); + }, 100); + })(); + + // 异步检查更新(ä¸é˜»å¡žä¸»æµç¨‹ï¼‰ + (function () { + // 延迟执行,确ä¿é¡µé¢å…ˆå®Œæˆåˆå§‹åŒ–,更新检查å¯èƒ½éœ€è¦ç½‘络请求 + setTimeout(function () { + callCheckUpdate().then(function (result) { + if (!result) return; + + // æ£€æŸ¥æ˜¯å¦æœ‰æ›´æ–°ï¼ˆluci-app-bandix 或 bandix) + var hasUpdate = false; + if (result.luci_has_update === true || result.luci_has_update === '1' || result.luci_has_update === 1) { + hasUpdate = true; + } + if (result.bandix_has_update === true || result.bandix_has_update === '1' || result.bandix_has_update === 1) { + hasUpdate = true; + } + + // 显示或éšè—æ›´æ–°æç¤º + var updateBadge = document.getElementById('bandix-update-badge'); + if (updateBadge) { + if (hasUpdate) { + updateBadge.style.display = 'inline-block'; + // ç‚¹å‡»è·³è½¬åˆ°è®¾ç½®é¡µé¢ + updateBadge.onclick = function () { + window.location.href = '/cgi-bin/luci/admin/network/bandix/settings'; + }; + updateBadge.title = _('Update available, click to go to settings'); + } else { + updateBadge.style.display = 'none'; + } + } + }).catch(function (err) { + // é™é»˜å¤±è´¥ï¼Œä¸å½±å“页é¢åŠŸèƒ½ + console.debug('Failed to check update:', err); + }); + }, 500); + })(); + + + + + return view; + } +}); diff --git a/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js new file mode 100644 index 00000000..70659560 --- /dev/null +++ b/luci-app-bandix/htdocs/luci-static/resources/view/bandix/settings.js @@ -0,0 +1,831 @@ +'use strict'; +'require view'; +'require form'; +'require ui'; +'require uci'; +'require rpc'; +'require tools.widgets as widgets'; + + +// æš—è‰²æ¨¡å¼æ£€æµ‹å·²æ”¹ä¸ºä½¿ç”¨ CSS 媒体查询 @media (prefers-color-scheme: dark) + +// 简å•çš„ Markdown è§£æžå‡½æ•° +function parseMarkdown(text) { + if (!text) return ''; + + // 转义 HTML 特殊字符 + function escapeHtml(html) { + var div = document.createElement('div'); + div.textContent = html; + return div.innerHTML; + } + + // 先处ç†ä»£ç å—(é¿å…å…¶ä»–æ ¼å¼åŒ–å½±å“代ç ï¼‰ + var codeBlocks = []; + var codeBlockIndex = 0; + text = text.replace(/```([\s\S]*?)```/g, function (match, code) { + var id = 'CODE_BLOCK_' + codeBlockIndex++; + codeBlocks.push({ + id: id, + content: escapeHtml(code.trim()) + }); + return id; + }); + + // 处ç†è¡Œå†…ä»£ç  + text = text.replace(/`([^`]+)`/g, function (match, code) { + return '' + escapeHtml(code) + ''; + }); + + // å¤„ç†æ¢è¡Œï¼ˆGitHub markdown 使用 \r\n) + text = text.replace(/\r\n/g, '\n'); + + // å¤„ç†æ ‡é¢˜ + text = text.replace(/^### (.*$)/gm, '

$1

'); + text = text.replace(/^## (.*$)/gm, '

$1

'); + text = text.replace(/^# (.*$)/gm, '

$1

'); + + // 处ç†ç²—体 + text = text.replace(/\*\*(.+?)\*\*/g, '$1'); + text = text.replace(/__(.+?)__/g, '$1'); + + // å¤„ç†æ–œä½“ + text = text.replace(/\*(.+?)\*/g, function (match, content) { + // é¿å…匹é…代ç å—中的 * + if (match.indexOf('') === -1) { + return '' + content + ''; + } + return match; + }); + text = text.replace(/_(.+?)_/g, function (match, content) { + // é¿å…匹é…代ç å—中的 _ + if (match.indexOf('') === -1) { + return '' + content + ''; + } + return match; + }); + + // 处ç†é“¾æŽ¥ + text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); + + // 处ç†å›¾ç‰‡ + text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '$1'); + + // å¤„ç†æ— åºåˆ—表 + var lines = text.split('\n'); + var inList = false; + var result = []; + + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + var listMatch = line.match(/^[\s]*[-*+]\s+(.+)$/); + + if (listMatch) { + if (!inList) { + result.push('
    '); + inList = true; + } + result.push('
  • ' + listMatch[1] + '
  • '); + } else { + if (inList) { + result.push('
'); + inList = false; + } + result.push(line); + } + } + if (inList) { + result.push(''); + } + text = result.join('\n'); + + // å¤„ç†æœ‰åºåˆ—表 + lines = text.split('\n'); + inList = false; + result = []; + + for (i = 0; i < lines.length; i++) { + line = lines[i]; + var orderedMatch = line.match(/^[\s]*\d+\.\s+(.+)$/); + + if (orderedMatch) { + if (!inList) { + result.push('
    '); + inList = true; + } + result.push('
  1. ' + orderedMatch[1] + '
  2. '); + } else { + if (inList) { + result.push('
'); + inList = false; + } + result.push(line); + } + } + if (inList) { + result.push(''); + } + text = result.join('\n'); + + // å¤„ç†æ®µè½ï¼ˆç©ºè¡Œåˆ†éš”) + text = text.split(/\n\s*\n/).map(function (para) { + para = para.trim(); + if (para && !para.match(/^<[h|u|o|l|i]/)) { + return '

' + para + '

'; + } + return para; + }).join('\n'); + + // 处ç†å•行æ¢è¡Œï¼ˆä¸¤ä¸ªç©ºæ ¼æˆ–åæ–œæ ç»“尾) + text = text.replace(/ \n/g, '
\n'); + text = text.replace(/\\\n/g, '
\n'); + + // æ¢å¤ä»£ç å— + for (var j = 0; j < codeBlocks.length; j++) { + var block = codeBlocks[j]; + text = text.replace(block.id, '
' + block.content + '
'); + } + + return text; +} + +// 声明 RPC 调用方法 +var callClearData = rpc.declare({ + object: 'luci.bandix', + method: 'clearData', + expect: {} +}); + +var callRestartService = rpc.declare({ + object: 'luci.bandix', + method: 'restartService', + expect: {} +}); + +var callGetVersion = rpc.declare({ + object: 'luci.bandix', + method: 'getVersion', + expect: {} +}); + +var callCheckUpdate = rpc.declare({ + object: 'luci.bandix', + method: 'checkUpdate', + expect: {} +}); + +var callInstallUpdate = rpc.declare({ + object: 'luci.bandix', + method: 'installUpdate', + params: ['package_type', 'download_url'] +}); + +return view.extend({ + load: function () { + var self = this; + return Promise.all([ + uci.load('bandix'), + uci.load('network'), + uci.load('luci'), + uci.load('argon').catch(function () { + // argon é…ç½®å¯èƒ½ä¸å­˜åœ¨ï¼Œå¿½ç•¥é”™è¯¯ + return null; + }), + callGetVersion().then(function (result) { + // 存储版本信æ¯åˆ° view 实例 + self.versionInfo = result || {}; + return result; + }).catch(function (err) { + // 如果获å–失败,使用默认值 + self.versionInfo = { + luci_app_version: _('Unknown'), + bandix_version: _('Unknown') + }; + return null; + }) + ]); + }, + + render: function (data) { + var m, s, o; + + // ç¡®ä¿UCI section存在,å¦åˆ™è¡¨å•ä¸ä¼šæ˜¾ç¤º + if (!uci.get('bandix', 'general')) { + uci.add('bandix', 'general', 'general'); + } + if (!uci.get('bandix', 'traffic')) { + uci.add('bandix', 'traffic', 'traffic'); + } + if (!uci.get('bandix', 'connections')) { + uci.add('bandix', 'connections', 'connections'); + } + if (!uci.get('bandix', 'dns')) { + uci.add('bandix', 'dns', 'dns'); + } + + // åˆ›å»ºè¡¨å• + m = new form.Map('bandix'); + + // 1. 基本设置部分 (general) + s = m.section(form.NamedSection, 'general', 'general', _('Basic Settings')); + s.description = _('Configure basic parameters for Bandix service'); + s.addremove = false; + + // 添加端å£è®¾ç½®é€‰é¡¹ + o = s.option(form.Value, 'port', _('Port'), + _('Port for Bandix service to listen on')); + o.default = '8686'; + o.datatype = 'port'; + o.placeholder = '8686'; + o.rmempty = false; + + // 使用 OpenWrt 自带的设备选择器 + o = s.option(widgets.DeviceSelect, 'iface', _('Monitor Interface'), + _('Select the LAN network interface to monitor')); + o.rmempty = false; + o.noaliases = true; + o.nobridges = false; + o.nocreate = true; + + // 添加日志级别选择选项 + o = s.option(form.ListValue, 'log_level', _('Log Level'), + _('Set the log level for Bandix service')); + o.value('trace', 'Trace'); + o.value('debug', 'Debug'); + o.value('info', 'Info'); + o.value('warn', 'Warn'); + o.value('error', 'Error'); + o.default = 'info'; + o.rmempty = false; + + // 添加数æ®ç›®å½•设置 + o = s.option(form.Value, 'data_dir', _('Data Directory'), + _('If you change the directory, please manually add it to the backup directory')); + o.default = '/usr/share/bandix'; + o.datatype = 'string'; + o.placeholder = '/usr/share/bandix'; + o.rmempty = false; + + o = s.option(form.ListValue, 'tc_backend', _('TC backend'), + _('Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels.')); + o.value('auto', 'auto'); + o.value('tcx', 'tcx'); + o.value('netlink', 'netlink'); + o.default = 'auto'; + o.rmempty = false; + + o = s.option(form.ListValue, 'tc_order', _('TC order')); + o.value('first', 'first'); + o.value('default', 'default'); + o.value('last', 'last'); + o.value('before', 'before'); + o.value('after', 'after'); + o.default = 'default'; + o.rmempty = false; + o.depends('tc_backend', 'tcx'); + + o = s.option(form.Value, 'netlink_priority', _('Netlink priority'), + _('Only used when backend is netlink. Range: 0..65535 (0 means default).')); + o.datatype = 'range(0,65535)'; + o.default = '0'; + o.placeholder = '0'; + o.rmempty = false; + o.depends('tc_backend', 'netlink'); + + o = s.option(form.Value, 'tcx_anchor_ingress_id', _('TCX ingress anchor program id'), + _('Used when tc_order is before/after. Must be a valid ingress program id on the same interface.')); + o.datatype = 'uinteger'; + o.rmempty = true; + o.depends({ tc_backend: 'tcx', tc_order: 'before' }); + o.depends({ tc_backend: 'tcx', tc_order: 'after' }); + + o = s.option(form.Value, 'tcx_anchor_egress_id', _('TCX egress anchor program id'), + _('Used when tc_order is before/after. Must be a valid egress program id on the same interface.')); + o.datatype = 'uinteger'; + o.rmempty = true; + o.depends({ tc_backend: 'tcx', tc_order: 'before' }); + o.depends({ tc_backend: 'tcx', tc_order: 'after' }); + + // æ·»åŠ ç‰ˆæœ¬ä¿¡æ¯æ˜¾ç¤ºï¼ˆåˆå¹¶æ˜¾ç¤ºï¼‰ + o = s.option(form.DummyValue, 'version', _('Version')); + o.cfgvalue = function () { + var versionInfo = this.map.view.versionInfo || {}; + var luciVersion = versionInfo.luci_app_version || _('Unknown'); + var bandixVersion = versionInfo.bandix_version || _('Unknown'); + return 'luci-app-bandix: ' + luciVersion + ' / bandix: ' + bandixVersion; + }; + + // 添加检查更新按钮 + var checkUpdateOption = s.option(form.Button, 'check_update', _('Check for Updates')); + checkUpdateOption.inputtitle = _('Check for Updates'); + checkUpdateOption.inputstyle = 'apply'; + checkUpdateOption.onclick = function () { + var button = this; + var originalText = button.inputtitle; + + // æ˜¾ç¤ºåŠ è½½çŠ¶æ€ + button.inputtitle = _('Checking...'); + button.disabled = true; + + return callCheckUpdate().then(function (result) { + // æ¢å¤æŒ‰é’®çŠ¶æ€ + button.inputtitle = originalText; + button.disabled = false; + + if (!result) { + ui.addNotification(null, E('p', _('Failed to check for updates')), 'error'); + return; + } + + var messages = []; + var hasUpdate = false; + + // 显示调试信æ¯ï¼ˆæž¶æž„ã€åŒ…管ç†å™¨å’Œèµ„产数é‡ï¼‰ + if (result.detected_arch) { + var debugInfo = E('div', { + 'style': 'font-size: 0.75rem; color: #6b7280; margin-bottom: 12px; padding: 8px; background: rgba(0,0,0,0.02); border-radius: 4px;' + }, [ + E('div', {}, _('Detected Architecture') + ': ' + result.detected_arch), + E('div', {}, _('Package Manager') + ': ' + (result.detected_pkg_manager || _('Unknown'))), + E('div', {}, _('LuCI Assets') + ': ' + (result.luci_asset_count || 0)), + E('div', {}, _('Bandix Assets') + ': ' + (result.bandix_asset_count || 0)) + ]); + messages.push(debugInfo); + } + + // 检查 luci-app-bandix æ›´æ–° + if (result.luci_has_update === true || result.luci_has_update === '1' || result.luci_has_update === 1) { + hasUpdate = true; + var luciContainer = E('div', { 'style': 'margin-bottom: 20px;' }); + + var luciMsg = E('p', { 'style': 'font-weight: 600; margin-bottom: 8px;' }, + _('LuCI App has update: ') + (result.current_luci_version || _('Unknown')) + + ' → ' + (result.latest_luci_version || _('Unknown')) + ); + luciContainer.appendChild(luciMsg); + + // æ˜¾ç¤ºæ›´æ–°æ—¥å¿—ï¼ˆè§£æž Markdown) + if (result.luci_release_body) { + var changelogDiv = E('div', { + 'style': 'background: rgba(0,0,0,0.05); padding: 12px; border-radius: 4px; margin: 8px 0; max-height: 300px; overflow-y: auto; font-size: 0.875rem; line-height: 1.6;' + }); + changelogDiv.innerHTML = parseMarkdown(result.luci_release_body); + luciContainer.appendChild(changelogDiv); + } + + // æ£€æŸ¥æ˜¯å¦æœ‰é”™è¯¯ï¼ˆæ‰¾ä¸åˆ°åŒ¹é…æ ¼å¼çš„包) + if (result.luci_error) { + var errorMsg = E('div', { + 'style': 'background: rgba(239, 68, 68, 0.1); color: #dc2626; padding: 10px; border-radius: 4px; margin: 8px 0; font-size: 0.875rem;' + }, result.luci_error); + luciContainer.appendChild(errorMsg); + } + + // æ·»åŠ ä¸‹è½½å®‰è£…æŒ‰é’®ï¼ˆåªæœ‰åœ¨æœ‰ä¸‹è½½é“¾æŽ¥æ—¶æ‰æ˜¾ç¤ºï¼‰ + if (result.luci_download_url) { + // åˆ›å»ºçŠ¶æ€æç¤ºåŒºåŸŸ + var statusDiv = E('div', { + 'style': 'margin-top: 8px; padding: 10px; border-radius: 4px; display: none;' + }); + luciContainer.appendChild(statusDiv); + + var installBtn = E('button', { + 'class': 'btn cbi-button-action', + 'style': 'margin-top: 8px;', + 'click': function () { + var installButton = this; + var originalBtnText = installButton.textContent; + + installButton.textContent = _('Installing...'); + installButton.disabled = true; + + // 显示开始安装的æç¤º + statusDiv.style.display = 'block'; + statusDiv.style.background = 'rgba(59, 130, 246, 0.1)'; + statusDiv.style.color = '#1e40af'; + statusDiv.textContent = _('Starting installation... The page will refresh automatically in 30 seconds.'); + + // 对于 luci-app-bandix 安装,由于会é‡å¯ uhttpd/rpcd 导致连接断开, + // ä¸ç­‰å¾…å“应,固定 30 ç§’åŽåˆ·æ–°é¡µé¢ï¼Œé¿å…刷新过早未完æˆå®‰è£… + callInstallUpdate('luci', result.luci_download_url).catch(function (err) { + }); + + setTimeout(function () { + window.location.reload(); + }, 30000); + } + }, _('Download and Install')); + luciContainer.appendChild(installBtn); + } + + // 添加手动下载链接 + if (result.luci_update_url) { + var manualLink = E('a', { + 'href': result.luci_update_url, + 'target': '_blank', + 'style': 'display: inline-block; margin-left: 8px; margin-top: 8px;' + }, _('Manual Download')); + luciContainer.appendChild(manualLink); + } + + messages.push(luciContainer); + } else { + messages.push(E('p', {}, _('LuCI App is up to date: ') + (result.current_luci_version || result.latest_luci_version || _('Unknown')))); + } + + // 检查 bandix æ›´æ–° + if (result.bandix_has_update === true || result.bandix_has_update === '1' || result.bandix_has_update === 1) { + hasUpdate = true; + var bandixContainer = E('div', { 'style': 'margin-bottom: 20px;' }); + + var bandixMsg = E('p', { 'style': 'font-weight: 600; margin-bottom: 8px;' }, + _('Bandix has update: ') + (result.current_bandix_version || _('Unknown')) + + ' → ' + (result.latest_bandix_version || _('Unknown')) + ); + bandixContainer.appendChild(bandixMsg); + + // æ˜¾ç¤ºæ›´æ–°æ—¥å¿—ï¼ˆè§£æž Markdown) + if (result.bandix_release_body) { + var changelogDiv = E('div', { + 'style': 'background: rgba(0,0,0,0.05); padding: 12px; border-radius: 4px; margin: 8px 0; max-height: 300px; overflow-y: auto; font-size: 0.875rem; line-height: 1.6;' + }); + changelogDiv.innerHTML = parseMarkdown(result.bandix_release_body); + bandixContainer.appendChild(changelogDiv); + } + + // æ£€æŸ¥æ˜¯å¦æœ‰é”™è¯¯ï¼ˆæ‰¾ä¸åˆ°åŒ¹é…æ ¼å¼çš„包) + if (result.bandix_error) { + var errorMsg = E('div', { + 'style': 'background: rgba(239, 68, 68, 0.1); color: #dc2626; padding: 10px; border-radius: 4px; margin: 8px 0; font-size: 0.875rem;' + }, result.bandix_error); + bandixContainer.appendChild(errorMsg); + } + + // æ·»åŠ ä¸‹è½½å®‰è£…æŒ‰é’®ï¼ˆåªæœ‰åœ¨æœ‰ä¸‹è½½é“¾æŽ¥æ—¶æ‰æ˜¾ç¤ºï¼‰ + if (result.bandix_download_url) { + // åˆ›å»ºçŠ¶æ€æç¤ºåŒºåŸŸ + var statusDiv = E('div', { + 'style': 'margin-top: 8px; padding: 10px; border-radius: 4px; display: none;' + }); + bandixContainer.appendChild(statusDiv); + + var installBtn = E('button', { + 'class': 'btn cbi-button-action', + 'style': 'margin-top: 8px;', + 'click': function () { + var installButton = this; + var originalBtnText = installButton.textContent; + + installButton.textContent = _('Installing...'); + installButton.disabled = true; + + // 显示开始安装的æç¤º + statusDiv.style.display = 'block'; + statusDiv.style.background = 'rgba(59, 130, 246, 0.1)'; + statusDiv.style.color = '#1e40af'; + statusDiv.textContent = _('Starting installation...'); + + return callInstallUpdate('bandix', result.bandix_download_url).then(function (installResult) { + // 判断æˆåŠŸï¼šsuccess 为 true 或 step 为 completed + var isSuccess = installResult && ( + installResult.success === true || + installResult.success === 1 || + installResult.success === "true" || + installResult.success === "1" || + installResult.step === "completed" + ); + + if (isSuccess) { + installButton.textContent = originalBtnText; + installButton.disabled = false; + // 显示æˆåŠŸæç¤º + var successMsg = _('Bandix updated successfully!'); + if (installResult.message) { + successMsg = installResult.message; + } + if (installResult.restart_exit_code !== undefined) { + if (installResult.restart_exit_code === 0) { + successMsg += ' ' + _('Service restarted successfully.'); + } else { + successMsg += ' ' + _('Service restart may have failed. Please check manually.'); + } + } else { + successMsg += ' ' + _('Please restart the service.'); + } + statusDiv.style.background = 'rgba(34, 197, 94, 0.1)'; + statusDiv.style.color = '#15803d'; + statusDiv.textContent = successMsg + ' ' + _('Page will refresh in 3 seconds.'); + // 3ç§’åŽåˆ·æ–°é¡µé¢ + setTimeout(function () { + window.location.reload(); + }, 3000); + } else { + installButton.textContent = originalBtnText; + installButton.disabled = false; + var errorMsg = installResult && installResult.error ? installResult.error : _('Installation failed'); + if (installResult && installResult.step) { + errorMsg = _('Installation failed at step: ') + installResult.step + '. ' + errorMsg; + } + if (installResult && installResult.output) { + // 截å–输出信æ¯çš„å‰500个字符,é¿å…æç¤ºè¿‡é•¿ + var output = installResult.output; + if (output.length > 500) { + output = output.substring(0, 500) + '...'; + } + errorMsg += '\n' + _('Details: ') + output; + } + statusDiv.style.background = 'rgba(239, 68, 68, 0.1)'; + statusDiv.style.color = '#dc2626'; + statusDiv.innerHTML = errorMsg.replace(/\n/g, '
'); + } + }).catch(function (err) { + installButton.textContent = originalBtnText; + installButton.disabled = false; + var errorMsg = _('Installation failed: ') + (err.message || err || _('Unknown error')); + statusDiv.style.background = 'rgba(239, 68, 68, 0.1)'; + statusDiv.style.color = '#dc2626'; + statusDiv.textContent = errorMsg; + }); + } + }, _('Download and Install')); + bandixContainer.appendChild(installBtn); + } + + // 添加手动下载链接 + if (result.bandix_update_url) { + var manualLink = E('a', { + 'href': result.bandix_update_url, + 'target': '_blank', + 'style': 'display: inline-block; margin-left: 8px; margin-top: 8px;' + }, _('Manual Download')); + bandixContainer.appendChild(manualLink); + } + + messages.push(bandixContainer); + } else { + messages.push(E('p', {}, _('Bandix is up to date: ') + (result.current_bandix_version || result.latest_bandix_version || _('Unknown')))); + } + + // 显示结果(添加关闭按钮) + var title = hasUpdate ? _('Updates Available') : _('No Updates Available'); + + // 添加红色æç¤ºæ–‡å­—(如果有更新) + if (hasUpdate) { + var warningMsg = E('div', { + 'style': 'background: rgba(239, 68, 68, 0.1); color: #dc2626; padding: 12px; border-radius: 4px; margin-bottom: 16px; font-weight: 600;' + }, _('Please clear your browser cache manually after updating.')); + messages.unshift(warningMsg); + } + + // 创建弹窗内容,包å«å…³é—­æŒ‰é’® + var modalContent = E('div', {}, messages); + + // 添加关闭按钮 + var closeBtn = E('button', { + 'class': 'btn', + 'style': 'margin-top: 16px;', + 'click': ui.hideModal + }, _('Close')); + + modalContent.appendChild(closeBtn); + + ui.showModal(title, modalContent); + }).catch(function (err) { + // æ¢å¤æŒ‰é’®çŠ¶æ€ + button.inputtitle = originalText; + button.disabled = false; + ui.addNotification(null, E('p', _('Failed to check for updates: ') + (err.message || err)), 'error'); + }); + }; + + + // æ·»åŠ æ¸…ç©ºæ•°æ®æŒ‰é’® + o = s.option(form.Button, 'clear_data', _('Clear Traffic Data')); + o.inputtitle = _('Clear Traffic Data'); + o.inputstyle = 'reset'; + o.onclick = function () { + return ui.showModal(_('Clear Traffic Data'), [ + E('p', _('Are you sure you want to clear all traffic data? This action cannot be undone.')), + E('div', { 'class': 'right' }, [ + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Cancel')), + ' ', + E('button', { + 'class': 'btn cbi-button-negative', + 'click': function () { + ui.hideModal(); + return callClearData() + .then(function (result) { + if (result && !result.success) { + ui.addNotification(null, E('p', _('Failed to clear traffic data: ') + (result.error || 'Unknown error')), 'error'); + } + }) + .catch(function (err) { + ui.addNotification(null, E('p', _('Failed to clear traffic data: ') + err.message), 'error'); + }); + } + }, _('Confirm')) + ]) + ]); + }; + + // 添加é‡å¯æœåŠ¡æŒ‰é’® + o = s.option(form.Button, 'restart_service', _('Restart Service')); + o.inputtitle = _('Restart Bandix Service'); + o.inputstyle = 'apply'; + o.onclick = function () { + return ui.showModal(_('Restart Service'), [ + E('p', _('Are you sure you want to restart the Bandix service?')), + E('div', { 'class': 'right' }, [ + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Cancel')), + ' ', + E('button', { + 'class': 'btn cbi-button-action', + 'click': function () { + ui.hideModal(); + return callRestartService() + .then(function (result) { + if (result && !result.success) { + ui.addNotification(null, E('p', _('Failed to restart service: ') + (result.error || 'Unknown error')), 'error'); + } + }) + .catch(function (err) { + ui.addNotification(null, E('p', _('Failed to restart service: ') + err.message), 'error'); + }); + } + }, _('Confirm')) + ]) + ]); + }; + + + // 添加æ„è§åé¦ˆä¿¡æ¯ + o = s.option(form.Button, 'feedback_info', _('Feedback')); + o.inputtitle = _('Feedback'); + o.inputstyle = 'link'; + o.onclick = function () { + window.open('https://github.com/timsaya', '_blank'); + return false; + }; + + // 2. æµé‡ç›‘控设置部分 (traffic) + s = m.section(form.NamedSection, 'traffic', 'traffic', _('Traffic Monitor Settings')); + s.description = _('Configure traffic monitoring related parameters'); + s.addremove = false; + + o = s.option(form.Flag, 'enabled', _('Enable Traffic Monitoring'), + _('Enable Bandix Traffic Monitor Service')); + o.default = '0'; + o.rmempty = false; + + // 添加网速å•ä½é€‰æ‹©é€‰é¡¹ + o = s.option(form.ListValue, 'speed_unit', _('Speed Units'), + _('Select the speed display unit format')); + o.value('bytes', _('Bytes Units (B/s, KB/s, MB/s)')); + o.value('bits', _('Bits Units (bps, Kbps, Mbps)')); + o.default = 'bytes'; + o.rmempty = false; + + // 添加离线超时时间(秒) + // o = s.option(form.Value, 'offline_timeout', _('Offline Timeout'), + // _('Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline')); + // o.datatype = 'uinteger'; + // o.placeholder = '120'; + // o.default = '120'; + // o.rmempty = true; + + // 添加æŒä¹…åŒ–åŽ†å²æ•°æ®é€‰é¡¹ + o = s.option(form.Flag, 'traffic_enable_storage', _('Persist History Data'), + _('Enable data persistence functionality, data will only be persisted to disk when this option is enabled')); + o.default = '0'; + o.rmempty = false; + + // æ·»åŠ æ•°æ® flush 间隔(秒) + o = s.option(form.ListValue, 'traffic_flush_interval', _('Data Flush Interval'), + _('Set the interval for flushing data to disk')); + o.value('60', _('1 minute')); + o.value('300', _('5 minutes')); + o.value('600', _('10 minutes')); + o.value('900', _('15 minutes')); + o.value('1800', _('30 minutes')); + o.value('3600', _('1 hour')); + o.value('7200', _('2 hours')); + o.value('43200', _('12 hours')); + o.value('86400', _('24 hours')); + o.default = '600'; + o.rmempty = false; + o.depends('traffic_enable_storage', '1'); + + o = s.option(form.Flag, 'traffic_neighbor_flush_enable', _('Enable Neighbor Flush'), + _('Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally.')); + o.default = '0'; + o.rmempty = false; + + o = s.option(form.ListValue, 'traffic_neighbor_flush_interval', _('Neighbor Flush Interval'), + _('Set the interval for flushing neighbor table data')); + o.value('600', _('10 minutes')); + o.value('900', _('15 minutes')); + o.value('1800', _('30 minutes')); + o.value('3600', _('1 hour')); + o.value('7200', _('2 hours')); + o.value('43200', _('12 hours')); + o.value('86400', _('24 hours')); + o.default = '600'; + o.rmempty = false; + o.depends('traffic_neighbor_flush_enable', '1'); + + // æ·»åŠ åŽ†å²æµé‡å‘¨æœŸï¼ˆç§’) + o = s.option(form.ListValue, 'traffic_realtime_window', _('Realtime Traffic Period'), + _('Does not occupy storage space, stored only in memory')); + o.value('600', _('10 minutes')); + o.value('900', _('15 minutes')); + o.value('1800', _('30 minutes')); + o.value('3600', _('1 hour')); + o.default = '600'; + o.rmempty = false; + + // 添加æµé‡å¯¼å‡ºURL选项 + o = s.option(form.Value, 'traffic_export_url', _('Traffic Push URL'), + _('Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable.')); + o.datatype = 'string'; + o.placeholder = ''; + o.rmempty = true; + + // 添加设备事件导出URL选项 + o = s.option(form.Value, 'traffic_event_url', _('Device Event Push URL'), + _('Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable.')); + o.datatype = 'string'; + o.placeholder = ''; + o.rmempty = true; + + // 添加é¢å¤–å­ç½‘选项 + o = s.option(form.Value, 'traffic_additional_subnets', _('Additional Subnets'), + _('Additional local subnets (comma-separated CIDR notation, e.g. \'192.168.2.0/24,10.0.0.0/8\'). Leave empty to use only interface subnet.')); + o.datatype = 'string'; + o.placeholder = '192.168.2.0/24,10.0.0.0/8'; + o.rmempty = true; + + o = s.option(form.Flag, 'traffic_exclude_iface_device', _('Exclude Interface Device'), + _('Exclude the router itself (interface device) from traffic statistics')); + o.default = '0'; + o.rmempty = false; + + // 3. 连接监控设置部分 (connections) + s = m.section(form.NamedSection, 'connections', 'connections', _('Connection Monitor Settings')); + s.description = _('Configure connection monitoring related parameters'); + s.addremove = false; + + o = s.option(form.Flag, 'enabled', _('Enable Connection Monitoring'), + _('Enable Bandix connection monitoring')); + o.default = '0'; + o.rmempty = false; + + // 4. DNS监控设置部分 (dns) + s = m.section(form.NamedSection, 'dns', 'dns', _('DNS Monitor Settings')); + s.description = _('Configure DNS monitoring related parameters'); + s.addremove = false; + + o = s.option(form.Flag, 'enabled', _('Enable DNS Monitoring'), + _('Enable Bandix DNS monitoring')); + o.default = '0'; + o.rmempty = false; + + // 添加DNS最大记录数选项 + o = s.option(form.Value, 'dns_max_records', _('DNS Max Records'), + _('Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded')); + o.datatype = 'uinteger'; + o.placeholder = '10000'; + o.default = '10000'; + o.rmempty = false; + + o = s.option(form.Flag, 'dns_enable_storage', _('Persist DNS Data'), + _('Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled')); + o.default = '0'; + o.rmempty = false; + + o = s.option(form.ListValue, 'dns_flush_interval', _('DNS Data Flush Interval'), + _('Set the interval for flushing DNS data to disk')); + o.value('60', _('1 minute')); + o.value('300', _('5 minutes')); + o.value('600', _('10 minutes')); + o.value('900', _('15 minutes')); + o.value('1800', _('30 minutes')); + o.value('3600', _('1 hour')); + o.value('7200', _('2 hours')); + o.value('43200', _('12 hours')); + o.value('86400', _('24 hours')); + o.default = '900'; + o.rmempty = false; + o.depends('dns_enable_storage', '1'); + + // å°† view 实例关è”到 form map,以便在 cfgvalue 中访问 + m.view = this; + + return m.render(); + } +}); diff --git a/luci-app-bandix/po/es/bandix.po b/luci-app-bandix/po/es/bandix.po new file mode 100644 index 00000000..7160b6ee --- /dev/null +++ b/luci-app-bandix/po/es/bandix.po @@ -0,0 +1,1257 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Monitor de Tráfico Bandix" + +msgid "Loading data..." +msgstr "Cargando datos..." + +msgid "Unable to fetch data" +msgstr "No se pueden obtener los datos" + +msgid "Unable to fetch history data" +msgstr "No se pueden obtener los datos del historial" + +msgid "Hostname" +msgstr "Nombre de host" + +msgid "IP Address" +msgstr "Dirección IP" + +msgid "MAC Address" +msgstr "Dirección MAC" + +msgid "Download Speed" +msgstr "Velocidad de descarga" + +msgid "Upload Speed" +msgstr "Velocidad de carga" + +msgid "Total Download" +msgstr "Descarga total" + +msgid "Total Upload" +msgstr "Carga total" + +msgid "Download Limit" +msgstr "Límite de descarga" + +msgid "Upload Limit" +msgstr "Límite de carga" + +msgid "Interface Language" +msgstr "Idioma de la interfaz" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "Seleccione el idioma de visualización para el Monitor de Tráfico Bandix" + +msgid "Device Info" +msgstr "Información del dispositivo" + +msgid "Device List" +msgstr "Lista de dispositivos" + +msgid "LAN Traffic" +msgstr "Tráfico LAN" + +msgid "WAN Traffic" +msgstr "Tráfico WAN" + +msgid "Network Type" +msgstr "Tipo de Red" + +msgid "Rate Limit" +msgstr "Límite de velocidad" + +msgid "Actions" +msgstr "Acciones" + +msgid "Online Devices" +msgstr "Dispositivos en línea" + +msgid "WAN Only" +msgstr "Solo WAN" + +msgid "Settings" +msgstr "Configuración" + +msgid "Device Settings" +msgstr "Configuración del dispositivo" + +msgid "Rate Limits" +msgstr "Límites de velocidad" + +msgid "Remove Rate Limit" +msgstr "Eliminar límite de velocidad" + +msgid "Save" +msgstr "Guardar" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Set Rate Limit" +msgstr "Establecer límite de velocidad" + +msgid "Device" +msgstr "Dispositivo" + +msgid "Set Hostname" +msgstr "Establecer nombre de host" + +msgid "Please enter hostname" +msgstr "Por favor ingrese el nombre de host" + +msgid "Hostname set successfully" +msgstr "Nombre de host establecido correctamente" + +msgid "Failed to set hostname" +msgstr "Error al establecer el nombre de host" + +msgid "Unlimited" +msgstr "Ilimitado" + +msgid "Settings saved successfully" +msgstr "Configuración guardada correctamente" + +msgid "Failed to save settings" +msgstr "Error al guardar la configuración" + +msgid "Please enter a valid speed value" +msgstr "Por favor ingrese un valor de velocidad válido" + +msgid "Speed value must be greater than 0" +msgstr "El valor de velocidad debe ser mayor que 0" + +msgid "Saving..." +msgstr "Guardando..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "La limitación de velocidad solo se aplica al tráfico WAN. Algunos tráficos internos de LAN pueden no ser monitoreados debido a la aceleración de conmutación por hardware." + +msgid "Tip: Enter 0 for unlimited" +msgstr "Consejo: Ingrese 0 para ilimitado" + +msgid "Traffic History" +msgstr "Historial de tráfico" + +msgid "Realtime Traffic Trends" +msgstr "Tendencias de Tráfico en Tiempo Real" + +msgid "Select Device" +msgstr "Seleccionar dispositivo" + +msgid "All Devices" +msgstr "Todos los dispositivos" + +msgid "Time Range" +msgstr "Rango de tiempo" + +msgid "Last 5 minutes" +msgstr "Últimos 5 minutos" + +msgid "Last 30 minutes" +msgstr "Últimos 30 minutos" + +msgid "Last 2 hours" +msgstr "Últimas 2 horas" + +msgid "Type" +msgstr "Tipo" + +msgid "Total" +msgstr "Total" + +msgid "LAN" +msgstr "Tráfico LAN" + +msgid "WAN" +msgstr "Tráfico WAN" + +msgid "Refresh" +msgstr "Actualizar" + +msgid "Upload Rate" +msgstr "Velocidad de carga" + +msgid "Download Rate" +msgstr "Velocidad de descarga" + +msgid "Last" +msgstr "Último" + +msgid "second" +msgstr "segundo" + +msgid "minute" +msgstr "minuto" + +msgid "hour" +msgstr "hora" + +msgid "day" +msgstr "día" + +msgid "week" +msgstr "semana" + +msgid "Other Rates" +msgstr "Otras velocidades" + +msgid "Cumulative" +msgstr "Acumulado" + +msgid "Total Uploaded" +msgstr "Total cargado" + +msgid "Total Downloaded" +msgstr "Total descargado" + +msgid "LAN Uploaded" +msgstr "LAN cargado" + +msgid "LAN Downloaded" +msgstr "LAN descargado" + +msgid "WAN Uploaded" +msgstr "WAN cargado" + +msgid "WAN Downloaded" +msgstr "WAN descargado" + +msgid "Total Upload" +msgstr "Carga total" + +msgid "Total Download" +msgstr "Descarga total" + +msgid "LAN Upload" +msgstr "Carga LAN" + +msgid "LAN Download" +msgstr "Descarga LAN" + +msgid "WAN Upload" +msgstr "Carga WAN" + +msgid "WAN Download" +msgstr "Descarga WAN" + +msgid "Never Online" +msgstr "Nunca en línea" + +msgid "Just Now" +msgstr "Ahora mismo" + +msgid "min ago" +msgstr "min hace" + +msgid "h ago" +msgstr "h hace" + +msgid "days ago" +msgstr "días hace" + +msgid "months ago" +msgstr "meses hace" + +msgid "years ago" +msgstr "años hace" + +msgid "Last Online" +msgstr "Última vez en línea" + +msgid "Zoom" +msgstr "Zoom" + +msgid "Sort By" +msgstr "Ordenar por" + +msgid "Online Status" +msgstr "Estado en línea" + +msgid "Total Traffic" +msgstr "Tráfico total" + +msgid "Ascending" +msgstr "Ascendente" + +msgid "Descending" +msgstr "Descendente" + +msgid "Sort by Speed" +msgstr "Ordenar por velocidad" + +msgid "Sort by Traffic" +msgstr "Ordenar por tráfico" + +msgid "Simple Mode" +msgstr "Modo simple" + +msgid "Detailed Mode" +msgstr "Modo detallado" + +msgid "Bandix DNS Monitor" +msgstr "Monitor DNS Bandix" + +msgid "DNS Monitor" +msgstr "Monitor DNS" + +msgid "DNS Query Records" +msgstr "Registros de consultas DNS" + +msgid "DNS Statistics" +msgstr "Estadísticas DNS" + +msgid "DNS Monitoring Disabled" +msgstr "Monitoreo DNS deshabilitado" + +msgid "Please enable DNS monitoring in settings" +msgstr "Por favor habilite el monitoreo DNS en la configuración" + +msgid "Go to Settings" +msgstr "Ir a configuración" + +msgid "No Data" +msgstr "Sin datos" + +msgid "Time" +msgstr "Hora" + +msgid "Domain" +msgstr "Dominio" + +msgid "Query Type" +msgstr "Tipo de consulta" + +msgid "Response Code" +msgstr "Código de respuesta" + +msgid "Response Time" +msgstr "Tiempo de respuesta" + +msgid "Source IP" +msgstr "IP de origen" + +msgid "Destination IP" +msgstr "IP de destino" + +msgid "Response IPs" +msgstr "IPs de respuesta" + +msgid "Response Result" +msgstr "Resultado de respuesta" + +msgid "DNS Server" +msgstr "Servidor DNS" + +msgid "Query" +msgstr "Consulta" + +msgid "Response" +msgstr "Respuesta" + +msgid "Filter" +msgstr "Filtro" + +msgid "Domain Filter" +msgstr "Filtro de dominio" + +msgid "Device Filter" +msgstr "Filtro de dispositivo" + +msgid "DNS Server Filter" +msgstr "Filtro de servidor DNS" + +msgid "Type Filter" +msgstr "Filtro de tipo" + +msgid "All" +msgstr "Todos" + +msgid "Period" +msgstr "Período" + +msgid "Display Mode" +msgstr "Modo de Visualización" + +msgid "This Year" +msgstr "Este Año" + +msgid "Week" +msgstr "Esta Semana" + +msgid "Month" +msgstr "Este Mes" + +msgid "Year" +msgstr "Este Año" + +msgid "Queries Only" +msgstr "Solo consultas" + +msgid "Responses Only" +msgstr "Solo respuestas" + +msgid "Search" +msgstr "Buscar" + +msgid "Search Domain" +msgstr "Buscar dominio" + +msgid "Search Device" +msgstr "Buscar dispositivo" + +msgid "Search DNS Server" +msgstr "Buscar servidor DNS" + +msgid "Clear" +msgstr "Limpiar" + +msgid "Previous" +msgstr "Anterior" + +msgid "Next" +msgstr "Siguiente" + +msgid "Page" +msgstr "Página" + +msgid "of" +msgstr "de" + +msgid "Total" +msgstr "Total" + +msgid "records" +msgstr "registros" + +msgid "Per Page" +msgstr "Por página" + +msgid "" +msgstr "" + +msgid "Total Queries" +msgstr "Total de consultas" + +msgid "Total Responses" +msgstr "Total de respuestas" + +msgid "Queries with Response" +msgstr "Consultas con respuesta" + +msgid "Queries without Response" +msgstr "Consultas sin respuesta" + +msgid "Avg Response Time" +msgstr "Tiempo de respuesta promedio" + +msgid "Min Response Time" +msgstr "Tiempo de respuesta mínimo" + +msgid "Max Response Time" +msgstr "Tiempo de respuesta máximo" + +msgid "Success Rate" +msgstr "Tasa de éxito" + +msgid "Success" +msgstr "Éxito" + +msgid "Failure" +msgstr "Fallo" + +msgid "Top Domains" +msgstr "Dominios principales" + +msgid "Top Query Types" +msgstr "Tipos de consulta principales" + +msgid "Top Devices" +msgstr "Dispositivos principales" + +msgid "Top DNS Servers" +msgstr "Servidores DNS principales" + +msgid "Unique Devices" +msgstr "Dispositivos únicos" + +msgid "ms" +msgstr "ms" + +msgid "minutes" +msgstr "minutos" + +msgid "Unknown Device" +msgstr "Dispositivo desconocido" + +msgid "Domain not found" +msgstr "Dominio no encontrado" + +msgid "Server error" +msgstr "Error del servidor" + +msgid "Format error" +msgstr "Error de formato" + +msgid "Refused" +msgstr "Rechazado" + +msgid "Other" +msgstr "Otro" + +msgid "Does not include DoH and DoT" +msgstr "No incluye DoH y DoT" + +msgid "Latest Response Time" +msgstr "Último tiempo de respuesta" + +msgid "Response Code Distribution" +msgstr "Distribución de códigos de respuesta" + +msgid "Response Time Percentiles" +msgstr "Percentiles de tiempo de respuesta" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Monitor de Conexión Bandix" + +msgid "Connection Monitor" +msgstr "Monitor de conexión" + +msgid "Device Connection Statistics" +msgstr "Estadísticas de conexión de dispositivos" + +msgid "Global Connection Statistics" +msgstr "Estadísticas de conexión global" + +msgid "Active TCP" +msgstr "TCP activo" + +msgid "Active UDP" +msgstr "UDP activo" + +msgid "Closed TCP" +msgstr "TCP cerrado" + +msgid "Total Connections" +msgstr "Total de conexiones" + +msgid "Last Updated" +msgstr "Última actualización" + +msgid "TCP Connections" +msgstr "Conexiones TCP" + +msgid "UDP Connections" +msgstr "Conexiones UDP" + +msgid "Established TCP" +msgstr "TCP establecido" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "Total de dispositivos" + +msgid "Connection Monitor Disabled" +msgstr "Monitor de conexión deshabilitado" + +msgid "Please enable connection monitoring in settings" +msgstr "Por favor habilite el monitoreo de conexión en la configuración" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "La lista solo muestra conexiones de dispositivos LAN, los datos pueden diferir del total de conexiones." + +msgid "TCP Status Details" +msgstr "Detalles del estado TCP" + +msgid "Basic Settings" +msgstr "Configuración básica" + +msgid "Traffic Monitor Settings" +msgstr "Configuración del monitor de tráfico" + +msgid "Connection Monitor Settings" +msgstr "Configuración del monitor de conexión" + +msgid "DNS Monitor Settings" +msgstr "Configuración del monitor DNS" + +msgid "Bandix Basic Configuration" +msgstr "Configuración básica de Bandix" + +msgid "Configure basic parameters for Bandix service" +msgstr "Configurar parámetros básicos para el servicio Bandix" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "Configuración del Monitor de Tráfico Bandix" + +msgid "Configure traffic monitoring related parameters" +msgstr "Configurar parámetros relacionados con el monitoreo de tráfico" + +msgid "Bandix Connection Monitor Configuration" +msgstr "Configuración del Monitor de Conexión Bandix" + +msgid "Configure connection monitoring related parameters" +msgstr "Configurar parámetros relacionados con el monitoreo de conexión" + +msgid "Bandix DNS Monitor Configuration" +msgstr "Configuración del Monitor DNS Bandix" + +msgid "Configure DNS monitoring related parameters" +msgstr "Configurar parámetros relacionados con el monitoreo DNS" + +msgid "Enable" +msgstr "Habilitar" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "Habilitar servicio del Monitor de Tráfico Bandix" + +msgid "Enable Traffic Monitoring" +msgstr "Habilitar monitoreo de tráfico" + +msgid "Enable Connection Monitoring" +msgstr "Habilitar monitoreo de conexión" + +msgid "Enable DNS Monitoring" +msgstr "Habilitar monitoreo DNS" + +msgid "Simplified Chinese" +msgstr "Chino simplificado" + +msgid "Traditional Chinese" +msgstr "Chino tradicional" + +msgid "Port" +msgstr "Puerto" + +msgid "Port for Bandix service to listen on" +msgstr "Puerto para que el servicio Bandix escuche" + +msgid "TC Priority" +msgstr "Prioridad TC" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "Establecer la prioridad del filtro TC para coexistir mejor con otros programas eBPF TC. Los números más bajos indican mayor prioridad. 0 significa asignado por el sistema." + +msgid "Monitor Interface" +msgstr "Interfaz de monitoreo" + +msgid "Select the LAN network interface to monitor" +msgstr "Seleccione la interfaz de red LAN para monitorear" + +msgid "Speed Units" +msgstr "Unidades de velocidad" + +msgid "Select the speed display unit format" +msgstr "Seleccione el formato de unidad de visualización de velocidad" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "Unidades de bytes (B/s, KB/s, MB/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "Unidades de bits (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "Tema de la interfaz" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "Seleccione el tema de visualización para el Monitor de Tráfico Bandix" + +msgid "Follow System" +msgstr "Seguir sistema" + +msgid "Light Mode" +msgstr "Modo claro" + +msgid "Dark Mode" +msgstr "Modo oscuro" + +msgid "Feedback" +msgstr "Comentarios" + +msgid "Log Level" +msgstr "Nivel de registro" + +msgid "Set the log level for Bandix service" +msgstr "Establecer el nivel de registro para el servicio Bandix" + +msgid "Offline Timeout" +msgstr "Tiempo de espera sin conexión" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "Establecer el tiempo de espera para la detección de dispositivos sin conexión (segundos). Los dispositivos inactivos por más tiempo serán marcados como sin conexión" + +msgid "Realtime Traffic Period" +msgstr "Período de tráfico en tiempo real" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "Intervalo de 10 minutos usa aproximadamente 60 KB por dispositivo" + +msgid "Data Flush Interval" +msgstr "Intervalo de vaciado de datos" + +msgid "Set the interval for flushing data to disk" +msgstr "Establecer el intervalo para vaciar datos al disco" + +msgid "1 minute" +msgstr "1 minuto" + +msgid "5 minutes" +msgstr "5 minutos" + +msgid "10 minutes" +msgstr "10 minutos" + +msgid "15 minutes" +msgstr "15 minutos" + +msgid "20 minutes" +msgstr "20 minutos" + +msgid "25 minutes" +msgstr "25 minutos" + +msgid "30 minutes" +msgstr "30 minutos" + +msgid "1 hour" +msgstr "1 hora" + +msgid "2 hours" +msgstr "2 horas" + +msgid "12 hours" +msgstr "12 horas" + +msgid "24 hours" +msgstr "24 horas" + +msgid "Data Directory" +msgstr "Directorio de datos" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "Si cambia el directorio, por favor agréguelo manualmente al directorio de respaldo" + +msgid "Bandix data storage directory" +msgstr "Directorio de almacenamiento de datos de Bandix" + +msgid "Enable Bandix connection monitoring" +msgstr "Habilitar monitoreo de conexión Bandix" + +msgid "Enable Bandix DNS monitoring" +msgstr "Habilitar monitoreo DNS Bandix" + +msgid "DNS Max Records" +msgstr "Registros DNS máximos" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "Establecer el número máximo de registros de consulta DNS para mantener. Los registros más antiguos se eliminarán cuando se exceda este límite" + +msgid "Persist DNS Data" +msgstr "Persistir datos DNS" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Habilitar funcionalidad de persistencia de datos DNS, los datos solo se persistirán en el disco cuando esta opción esté habilitada" + +msgid "DNS Data Flush Interval" +msgstr "Intervalo de descarga de datos DNS" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "Establecer el intervalo para descargar datos DNS al disco" + +msgid "Persist History Data" +msgstr "Persistir datos del historial" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Habilitar funcionalidad de persistencia de datos, los datos solo se persistirán en el disco cuando esta opción esté habilitada" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "No ocupa espacio de almacenamiento, almacenado solo en memoria" + +msgid "Query & Response" +msgstr "Consulta y Respuesta" + +msgid "Queries" +msgstr "Consultas" + +msgid "Responses" +msgstr "Respuestas" + +msgid "Average Response Time" +msgstr "Tiempo de Respuesta Promedio" + +msgid "Show More" +msgstr "Mostrar más" + +msgid "Show Less" +msgstr "Mostrar menos" + +msgid "Add Schedule Rule" +msgstr "Agregar regla de limitación programada" + +msgid "Add Rule" +msgstr "Agregar regla" + +msgid "Set rate limit rules for different time periods" +msgstr "Establecer reglas de limitación para diferentes períodos de tiempo" + +msgid "Time Slot" +msgstr "Franja horaria" + +msgid "Days of Week" +msgstr "Días de la semana" + +msgid "Mon" +msgstr "Lun" + +msgid "Tue" +msgstr "Mar" + +msgid "Wed" +msgstr "Mié" + +msgid "Thu" +msgstr "Jue" + +msgid "Fri" +msgstr "Vie" + +msgid "Sat" +msgstr "Sáb" + +msgid "Sun" +msgstr "Dom" + +msgid "Adding..." +msgstr "Agregando..." + +msgid "Failed to add schedule rule: " +msgstr "Error al agregar regla programada: " + +msgid "Please set time slot" +msgstr "Por favor establezca la franja horaria" + +msgid "Please select at least one day" +msgstr "Por favor seleccione al menos un día" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "Aún no hay reglas programadas, haga clic en \"Agregar regla\" para comenzar" + +msgid "Loading..." +msgstr "Cargando..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "Carga por fragmentos, espere... (%d/%d)" + +msgid "No schedule rules" +msgstr "No hay reglas programadas" + +msgid "Failed to load schedule rules" +msgstr "Error al cargar reglas programadas" + +msgid "Delete Schedule Rule" +msgstr "Eliminar regla programada" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "¿Está seguro de que desea eliminar esta regla programada?" + +msgid "Failed to delete schedule rule" +msgstr "Error al eliminar regla programada" + +msgid "Delete Device" +msgstr "Eliminar dispositivo" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "¿Está seguro de que desea eliminar este dispositivo? El historial de tráfico será eliminado." + +msgid "Failed to delete device" +msgstr "Error al eliminar dispositivo" + +msgid "Confirm" +msgstr "Confirmar" + +msgid "Close" +msgstr "Cerrar" + +msgid "rule" +msgstr "regla" + +msgid "rules" +msgstr "reglas" + +msgid "more" +msgstr "más" + +msgid "No active rule" +msgstr "Sin regla activa" + +msgid "Schedule Rules" +msgstr "Reglas de limitación programada" + +msgid "Upload Statistics" +msgstr "Estadísticas de subida" + +msgid "Download Statistics" +msgstr "Estadísticas de descarga" + +msgid "Cumulative Traffic" +msgstr "Tráfico acumulado" + +msgid "Daily" +msgstr "Diario" + +msgid "Weekly" +msgstr "Semanal" + +msgid "Monthly" +msgstr "Mensual" + +msgid "Statistics" +msgstr "Estadísticas" + +msgid "Average" +msgstr "Promedio" + +msgid "Maximum" +msgstr "Máximo" + +msgid "Minimum" +msgstr "Mínimo" + +msgid "WAN Upload" +msgstr "Subida WAN" + +msgid "WAN Download" +msgstr "Descarga WAN" + +msgid "WAN Uploaded" +msgstr "Subido WAN" + +msgid "WAN Downloaded" +msgstr "Descargado WAN" + +msgid "Clear Traffic Data" +msgstr "Borrar datos de tráfico" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "¿Está seguro de que desea borrar todos los datos de tráfico? Esta acción no se puede deshacer." + +msgid "Failed to clear traffic data: " +msgstr "Error al borrar los datos de tráfico: " + +msgid "Restart Service" +msgstr "Reiniciar servicio" + +msgid "Restart Bandix Service" +msgstr "Reiniciar servicio Bandix" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "¿Está seguro de que desea reiniciar el servicio Bandix?" + +msgid "Failed to restart service: " +msgstr "Error al reiniciar el servicio: " + +msgid "Realtime" +msgstr "Tiempo real" + +msgid "Last 24 Hours" +msgstr "Últimas 24 horas" + +msgid "Last 7 Days" +msgstr "Últimos 7 días" + +msgid "Last 30 Days" +msgstr "Últimos 30 días" + +msgid "Last 10 Minutes" +msgstr "Últimos 10 minutos" + +msgid "Last 15 Minutes" +msgstr "Últimos 15 minutos" + +msgid "Last 30 Minutes" +msgstr "Últimos 30 minutos" + +msgid "Last 1 Hour" +msgstr "Última 1 hora" + +msgid "Starting installation..." +msgstr "Iniciando instalación..." + +msgid "Page will refresh in 3 seconds." +msgstr "La página se actualizará en 3 segundos." + +msgid "Installation failed" +msgstr "Instalación fallida" + +msgid "Installation failed at step: " +msgstr "Instalación fallida en el paso: " + +msgid "Details: " +msgstr "Detalles: " + +msgid "Installation failed: " +msgstr "Instalación fallida: " + +msgid "Unknown error" +msgstr "Error desconocido" + +msgid "Service restarted successfully." +msgstr "Servicio reiniciado exitosamente." + +msgid "Service restart may have failed. Please check manually." +msgstr "El reinicio del servicio puede haber fallado. Por favor, verifique manualmente." + +msgid "Please restart the service." +msgstr "Por favor, reinicie el servicio." + +msgid "LuCI App updated successfully!" +msgstr "¡Aplicación LuCI actualizada exitosamente!" + +msgid "Bandix updated successfully!" +msgstr "¡Bandix actualizado exitosamente!" + +msgid "LuCI App has update: " +msgstr "La aplicación LuCI tiene actualización: " + +msgid "Bandix has update: " +msgstr "Bandix tiene actualización: " + +msgid "LuCI App is up to date: " +msgstr "La aplicación LuCI está actualizada: " + +msgid "Bandix is up to date: " +msgstr "Bandix está actualizado: " + +msgid "Updates Available" +msgstr "Actualizaciones Disponibles" + +msgid "No Updates Available" +msgstr "No Hay Actualizaciones Disponibles" + +msgid "Detected Architecture" +msgstr "Arquitectura Detectada" + +msgid "Package Manager" +msgstr "Gestor de Paquetes" + +msgid "LuCI Assets" +msgstr "Recursos de LuCI" + +msgid "Bandix Assets" +msgstr "Recursos de Bandix" + +msgid "Failed to check for updates" +msgstr "Error al verificar actualizaciones" + +msgid "Failed to check for updates: " +msgstr "Error al verificar actualizaciones: " + +msgid "Checking..." +msgstr "Verificando..." + +msgid "Check for Updates" +msgstr "Buscar Actualizaciones" + +msgid "Installing..." +msgstr "Instalando..." + +msgid "Download and Install" +msgstr "Descargar e Instalar" + +msgid "Manual Download" +msgstr "Descarga Manual" + +msgid "Close" +msgstr "Cerrar" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "Iniciando instalación... La página se actualizará automáticamente en 30 segundos." + +msgid "Please clear your browser cache manually after updating." +msgstr "Por favor, borre manualmente la caché del navegador después de actualizar." + +msgid "Traffic Statistics" +msgstr "Estadísticas de Tráfico" + +msgid "Traffic Statistics" +msgstr "Estadísticas de Tráfico" + +msgid "Device Usage Ranking" +msgstr "Clasificación de Uso de Dispositivos" + +msgid "Start Date" +msgstr "Fecha de Inicio" + +msgid "End Date" +msgstr "Fecha de Fin" + +msgid "Reset" +msgstr "Restablecer" + +msgid "Today" +msgstr "Hoy" + +msgid "This Week" +msgstr "Esta Semana" + +msgid "Last Week" +msgstr "Semana Pasada" + +msgid "This Month" +msgstr "Este Mes" + +msgid "Last Month" +msgstr "Mes Pasado" + +msgid "Last 90 Days" +msgstr "Últimos 90 Días" + +msgid "Last Year" +msgstr "Último Año" + +msgid "Traffic Timeline" +msgstr "Línea de Tiempo de Tráfico" + +msgid "Aggregation:" +msgstr "Agregación:" + +msgid "Hourly" +msgstr "Por Hora" + +msgid "Device:" +msgstr "Dispositivo:" + +msgid "Traffic Push URL" +msgstr "URL de envío de tráfico" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "Enviar datos de tráfico a un endpoint HTTP remoto (POST JSON). Dejar vacío para deshabilitar." + +msgid "Device Event Push URL" +msgstr "URL de envío de eventos de dispositivo" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "Enviar eventos de conexión/desconexión de dispositivo a un endpoint HTTP remoto (POST JSON en cambio de estado). Dejar vacío para deshabilitar." + +msgid "Additional Subnets" +msgstr "Subredes adicionales" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "Subredes locales adicionales (notación CIDR separada por comas, ej. '192.168.2.0/24,10.0.0.0/8'). Dejar vacío para usar solo la subred de interfaz." + +msgid "Exclude Interface Device" +msgstr "Excluir dispositivo de interfaz" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "Excluir el propio router (dispositivo de interfaz) de las estadísticas de tráfico" + +msgid "Enable Neighbor Flush" +msgstr "Habilitar vaciado de tabla de vecinos" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "Habilitar vaciado periódico de datos de la tabla de vecinos. Generalmente no se recomienda si la lista de dispositivos funciona con normalidad." + +msgid "Neighbor Flush Interval" +msgstr "Intervalo de vaciado de tabla de vecinos" + +msgid "Set the interval for flushing neighbor table data" +msgstr "Establecer el intervalo de vaciado de datos de la tabla de vecinos" + +msgid "No devices" +msgstr "Sin dispositivos" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "El tráfico LAN se ve desde la perspectiva de toda la subred, por lo que la carga y descarga siempre son iguales, formando un bucle cerrado. Además, debido a la presencia de chips de conmutación de hardware dedicados, el tráfico LAN entre 2 dispositivos (p. ej., PC - NAS) dentro de la red local puede no ser monitoreable." + +msgid "Protocol" +msgstr "Protocolo" + +msgid "State" +msgstr "Estado" + +msgid "Send" +msgstr "Enviar" + +msgid "Reply" +msgstr "Respuesta" + +msgid "Flags" +msgstr "Marcas" + +msgid "Loading…" +msgstr "Cargando…" + +msgid "No connections" +msgstr "Sin conexiones" + +msgid "pkts" +msgstr "paquetes" + +msgid "Failed to load" +msgstr "Error al cargar" + +msgid "Connection Details" +msgstr "Detalles de conexión" + +msgid "Details" +msgstr "Detalles" + +msgid "Orig Src" +msgstr "Origen orig." + +msgid "Orig Dst" +msgstr "Destino orig." + +msgid "Repl Src" +msgstr "Origen resp." + +msgid "Repl Dst" +msgstr "Destino resp." + +msgid "TC backend" +msgstr "Backend de TC" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "Seleccione el backend de adjuncion TC. Recomendacion: use auto por defecto; tcx es preferible en kernel >= 6.6; netlink es mas seguro en kernels antiguos." + +msgid "TC order" +msgstr "Orden de TC" + +msgid "Netlink priority" +msgstr "Prioridad de Netlink" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "Solo se usa cuando el backend es netlink. Rango: 0..65535 (0 significa predeterminado)." + +msgid "TCX ingress anchor program id" +msgstr "ID de programa ancla de ingreso TCX" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "Se usa cuando tc_order es before/after. Debe ser un ID de programa de ingreso valido en la misma interfaz." + +msgid "TCX egress anchor program id" +msgstr "ID de programa ancla de egreso TCX" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "Se usa cuando tc_order es before/after. Debe ser un ID de programa de egreso valido en la misma interfaz." diff --git a/luci-app-bandix/po/fr/bandix.po b/luci-app-bandix/po/fr/bandix.po new file mode 100644 index 00000000..42e378f3 --- /dev/null +++ b/luci-app-bandix/po/fr/bandix.po @@ -0,0 +1,1257 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Moniteur de trafic Bandix" + +msgid "Loading data..." +msgstr "Chargement des données..." + +msgid "Unable to fetch data" +msgstr "Impossible de récupérer les données" + +msgid "Unable to fetch history data" +msgstr "Impossible de récupérer les données d'historique" + +msgid "Hostname" +msgstr "Nom d'hôte" + +msgid "IP Address" +msgstr "Adresse IP" + +msgid "MAC Address" +msgstr "Adresse MAC" + +msgid "Download Speed" +msgstr "Vitesse de téléchargement" + +msgid "Upload Speed" +msgstr "Vitesse de téléversement" + +msgid "Total Download" +msgstr "Téléchargement total" + +msgid "Total Upload" +msgstr "Téléversement total" + +msgid "Download Limit" +msgstr "Limite de téléchargement" + +msgid "Upload Limit" +msgstr "Limite de téléversement" + +msgid "Interface Language" +msgstr "Langue de l'interface" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "Sélectionner la langue d'affichage pour le moniteur de trafic Bandix" + +msgid "Device Info" +msgstr "Informations sur l'appareil" + +msgid "Device List" +msgstr "Liste des appareils" + +msgid "LAN Traffic" +msgstr "Trafic LAN" + +msgid "WAN Traffic" +msgstr "Trafic WAN" + +msgid "Network Type" +msgstr "Type de Réseau" + +msgid "Rate Limit" +msgstr "Limite de débit" + +msgid "Actions" +msgstr "Actions" + +msgid "Online Devices" +msgstr "Appareils en ligne" + +msgid "WAN Only" +msgstr "WAN uniquement" + +msgid "Settings" +msgstr "Paramètres" + +msgid "Device Settings" +msgstr "Paramètres de l'appareil" + +msgid "Rate Limits" +msgstr "Paramètres de limitation" + +msgid "Remove Rate Limit" +msgstr "Supprimer la limite" + +msgid "Save" +msgstr "Enregistrer" + +msgid "Cancel" +msgstr "Annuler" + +msgid "Set Rate Limit" +msgstr "Définir la limite" + +msgid "Device" +msgstr "Appareil" + +msgid "Set Hostname" +msgstr "Définir le nom d'hôte" + +msgid "Please enter hostname" +msgstr "Veuillez entrer le nom d'hôte" + +msgid "Hostname set successfully" +msgstr "Nom d'hôte défini avec succès" + +msgid "Failed to set hostname" +msgstr "Échec de la définition du nom d'hôte" + +msgid "Unlimited" +msgstr "Illimité" + +msgid "Settings saved successfully" +msgstr "Paramètres enregistrés avec succès" + +msgid "Failed to save settings" +msgstr "Échec de l'enregistrement des paramètres" + +msgid "Please enter a valid speed value" +msgstr "Veuillez entrer une valeur de vitesse valide" + +msgid "Speed value must be greater than 0" +msgstr "La vitesse doit être supérieure à 0" + +msgid "Saving..." +msgstr "Enregistrement..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "La limitation de vitesse s'applique uniquement au trafic WAN. Certains trafics internes LAN peuvent ne pas être surveillés en raison de l'accélération de commutation matérielle." + +msgid "Tip: Enter 0 for unlimited" +msgstr "Astuce : Entrez 0 pour illimité" + +msgid "Traffic History" +msgstr "Historique du trafic" + +msgid "Realtime Traffic Trends" +msgstr "Tendances du Trafic en Temps Réel" + +msgid "Select Device" +msgstr "Sélectionner un appareil" + +msgid "All Devices" +msgstr "Tous les appareils" + +msgid "Time Range" +msgstr "Plage horaire" + +msgid "Last 5 minutes" +msgstr "5 dernières minutes" + +msgid "Last 30 minutes" +msgstr "30 dernières minutes" + +msgid "Last 2 hours" +msgstr "2 dernières heures" + +msgid "Type" +msgstr "Type" + +msgid "Total" +msgstr "Total" + +msgid "LAN" +msgstr "Trafic LAN" + +msgid "WAN" +msgstr "Trafic WAN" + +msgid "Refresh" +msgstr "Actualiser" + +msgid "Upload Rate" +msgstr "Taux de téléversement" + +msgid "Download Rate" +msgstr "Taux de téléchargement" + +msgid "Last" +msgstr "Dernier" + +msgid "second" +msgstr "seconde" + +msgid "minute" +msgstr "minute" + +msgid "hour" +msgstr "heure" + +msgid "day" +msgstr "jour" + +msgid "week" +msgstr "semaine" + +msgid "Other Rates" +msgstr "Autres débits" + +msgid "Cumulative" +msgstr "Trafic cumulé" + +msgid "Total Uploaded" +msgstr "Total envoyé" + +msgid "Total Downloaded" +msgstr "Total téléchargé" + +msgid "LAN Uploaded" +msgstr "LAN envoyé" + +msgid "LAN Downloaded" +msgstr "LAN téléchargé" + +msgid "WAN Uploaded" +msgstr "WAN envoyé" + +msgid "WAN Downloaded" +msgstr "WAN téléchargé" + +msgid "Total Upload" +msgstr "Téléversement total" + +msgid "Total Download" +msgstr "Téléchargement total" + +msgid "LAN Upload" +msgstr "Débit envoi LAN" + +msgid "LAN Download" +msgstr "Débit téléchargement LAN" + +msgid "WAN Upload" +msgstr "Débit envoi WAN" + +msgid "WAN Download" +msgstr "Débit téléchargement WAN" + +msgid "Never Online" +msgstr "Jamais en ligne" + +msgid "Just Now" +msgstr "À l'instant" + +msgid "min ago" +msgstr "min il y a" + +msgid "h ago" +msgstr "h il y a" + +msgid "days ago" +msgstr "jours il y a" + +msgid "months ago" +msgstr "mois il y a" + +msgid "years ago" +msgstr "ans il y a" + +msgid "Last Online" +msgstr "Dernière connexion" + +msgid "Zoom" +msgstr "Zoom" + +msgid "Sort By" +msgstr "Trier par" + +msgid "Online Status" +msgstr "Statut en ligne" + +msgid "Total Traffic" +msgstr "Trafic total" + +msgid "Ascending" +msgstr "Croissant" + +msgid "Descending" +msgstr "Décroissant" + +msgid "Sort by Speed" +msgstr "Trier par débit" + +msgid "Sort by Traffic" +msgstr "Trier par trafic" + +msgid "Simple Mode" +msgstr "Mode simple" + +msgid "Detailed Mode" +msgstr "Mode détaillé" + +msgid "Bandix DNS Monitor" +msgstr "Moniteur DNS Bandix" + +msgid "DNS Monitor" +msgstr "Moniteur DNS" + +msgid "DNS Query Records" +msgstr "Enregistrements de requêtes DNS" + +msgid "DNS Statistics" +msgstr "Statistiques DNS" + +msgid "DNS Monitoring Disabled" +msgstr "Surveillance DNS désactivée" + +msgid "Please enable DNS monitoring in settings" +msgstr "Veuillez activer la surveillance DNS dans les paramètres" + +msgid "Go to Settings" +msgstr "Aller aux paramètres" + +msgid "No Data" +msgstr "Aucune donnée" + +msgid "Time" +msgstr "Heure" + +msgid "Domain" +msgstr "Domaine" + +msgid "Query Type" +msgstr "Type de requête" + +msgid "Response Code" +msgstr "Code de réponse" + +msgid "Response Time" +msgstr "Temps de réponse" + +msgid "Source IP" +msgstr "IP source" + +msgid "Destination IP" +msgstr "IP de destination" + +msgid "Response IPs" +msgstr "IP de réponse" + +msgid "Response Result" +msgstr "Résultat de réponse" + +msgid "DNS Server" +msgstr "Serveur DNS" + +msgid "Query" +msgstr "Requête" + +msgid "Response" +msgstr "Réponse" + +msgid "Filter" +msgstr "Filtrer" + +msgid "Domain Filter" +msgstr "Filtre domaine" + +msgid "Device Filter" +msgstr "Filtre appareil" + +msgid "DNS Server Filter" +msgstr "Filtre serveur DNS" + +msgid "Type Filter" +msgstr "Filtre type" + +msgid "All" +msgstr "Tous" + +msgid "Period" +msgstr "Période" + +msgid "Display Mode" +msgstr "Mode d'Affichage" + +msgid "This Year" +msgstr "Cette Année" + +msgid "Week" +msgstr "Cette Semaine" + +msgid "Month" +msgstr "Ce Mois" + +msgid "Year" +msgstr "Cette Année" + +msgid "Queries Only" +msgstr "Requêtes uniquement" + +msgid "Responses Only" +msgstr "Réponses uniquement" + +msgid "Search" +msgstr "Rechercher" + +msgid "Search Domain" +msgstr "Rechercher domaine" + +msgid "Search Device" +msgstr "Rechercher appareil" + +msgid "Search DNS Server" +msgstr "Rechercher serveur DNS" + +msgid "Clear" +msgstr "Effacer" + +msgid "Previous" +msgstr "Précédent" + +msgid "Next" +msgstr "Suivant" + +msgid "Page" +msgstr "Page" + +msgid "of" +msgstr "sur" + +msgid "Total" +msgstr "Total" + +msgid "records" +msgstr "enregistrements" + +msgid "Per Page" +msgstr "Par page" + +msgid "" +msgstr "" + +msgid "Total Queries" +msgstr "Total des requêtes" + +msgid "Total Responses" +msgstr "Total des réponses" + +msgid "Queries with Response" +msgstr "Requêtes avec réponse" + +msgid "Queries without Response" +msgstr "Requêtes sans réponse" + +msgid "Avg Response Time" +msgstr "Temps de réponse moyen" + +msgid "Min Response Time" +msgstr "Temps de réponse minimum" + +msgid "Max Response Time" +msgstr "Temps de réponse maximum" + +msgid "Success Rate" +msgstr "Taux de réussite" + +msgid "Success" +msgstr "Succès" + +msgid "Failure" +msgstr "Échec" + +msgid "Top Domains" +msgstr "Domaines les plus consultés" + +msgid "Top Query Types" +msgstr "Types de requêtes les plus utilisés" + +msgid "Top Devices" +msgstr "Appareils les plus actifs" + +msgid "Top DNS Servers" +msgstr "Serveurs DNS les plus utilisés" + +msgid "Unique Devices" +msgstr "Appareils uniques" + +msgid "ms" +msgstr "ms" + +msgid "minutes" +msgstr "minutes" + +msgid "Unknown Device" +msgstr "Appareil inconnu" + +msgid "Domain not found" +msgstr "Domaine introuvable" + +msgid "Server error" +msgstr "Erreur serveur" + +msgid "Format error" +msgstr "Erreur de format" + +msgid "Refused" +msgstr "Refusé" + +msgid "Other" +msgstr "Autre" + +msgid "Does not include DoH and DoT" +msgstr "N'inclut pas DoH et DoT" + +msgid "Latest Response Time" +msgstr "Dernier temps de réponse" + +msgid "Response Code Distribution" +msgstr "Distribution des codes de réponse" + +msgid "Response Time Percentiles" +msgstr "Centiles du temps de réponse" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Moniteur de connexion Bandix" + +msgid "Connection Monitor" +msgstr "Moniteur de connexion" + +msgid "Device Connection Statistics" +msgstr "Statistiques de connexion par appareil" + +msgid "Global Connection Statistics" +msgstr "Statistiques globales des connexions" + +msgid "Active TCP" +msgstr "TCP actif" + +msgid "Active UDP" +msgstr "UDP actif" + +msgid "Closed TCP" +msgstr "TCP fermé" + +msgid "Total Connections" +msgstr "Total des connexions" + +msgid "Last Updated" +msgstr "Dernière mise à jour" + +msgid "TCP Connections" +msgstr "Connexions TCP" + +msgid "UDP Connections" +msgstr "Connexions UDP" + +msgid "Established TCP" +msgstr "TCP établi" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "Total des appareils" + +msgid "Connection Monitor Disabled" +msgstr "Surveillance des connexions désactivée" + +msgid "Please enable connection monitoring in settings" +msgstr "Veuillez activer la surveillance des connexions dans les paramètres" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "La liste n'affiche que les connexions des appareils LAN, les données peuvent différer du total des connexions." + +msgid "TCP Status Details" +msgstr "Détails du statut TCP" + +msgid "Basic Settings" +msgstr "Paramètres de base" + +msgid "Traffic Monitor Settings" +msgstr "Paramètres du moniteur de trafic" + +msgid "Connection Monitor Settings" +msgstr "Paramètres du moniteur de connexion" + +msgid "DNS Monitor Settings" +msgstr "Paramètres du moniteur DNS" + +msgid "Bandix Basic Configuration" +msgstr "Configuration de base de Bandix" + +msgid "Configure basic parameters for Bandix service" +msgstr "Configurer les paramètres de base du service Bandix" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "Configuration du moniteur de trafic Bandix" + +msgid "Configure traffic monitoring related parameters" +msgstr "Configurer les paramètres de surveillance du trafic" + +msgid "Bandix Connection Monitor Configuration" +msgstr "Configuration du moniteur de connexion Bandix" + +msgid "Configure connection monitoring related parameters" +msgstr "Configurer les paramètres de surveillance des connexions" + +msgid "Bandix DNS Monitor Configuration" +msgstr "Configuration du moniteur DNS Bandix" + +msgid "Configure DNS monitoring related parameters" +msgstr "Configurer les paramètres de surveillance DNS" + +msgid "Enable" +msgstr "Activer" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "Activer le service de surveillance du trafic Bandix" + +msgid "Enable Traffic Monitoring" +msgstr "Activer la surveillance du trafic" + +msgid "Enable Connection Monitoring" +msgstr "Activer la surveillance des connexions" + +msgid "Enable DNS Monitoring" +msgstr "Activer la surveillance DNS" + +msgid "Simplified Chinese" +msgstr "Chinois simplifié" + +msgid "Traditional Chinese" +msgstr "Chinois traditionnel" + +msgid "Port" +msgstr "Port" + +msgid "Port for Bandix service to listen on" +msgstr "Port sur lequel le service Bandix écoute" + +msgid "TC Priority" +msgstr "Priorité TC" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "Définir la priorité du filtre TC pour mieux coexister avec d'autres programmes eBPF TC. Les nombres plus petits indiquent une priorité plus élevée. 0 signifie assigné par le système." + +msgid "Monitor Interface" +msgstr "Interface de surveillance" + +msgid "Select the LAN network interface to monitor" +msgstr "Sélectionner l'interface réseau LAN à surveiller" + +msgid "Speed Units" +msgstr "Unités de vitesse" + +msgid "Select the speed display unit format" +msgstr "Sélectionner le format d'unité d'affichage de la vitesse" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "Unités en octets (B/s, Ko/s, Mo/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "Unités en bits (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "Thème de l'interface" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "Sélectionner le thème d'affichage pour le moniteur de trafic Bandix" + +msgid "Follow System" +msgstr "Suivre le système" + +msgid "Light Mode" +msgstr "Mode clair" + +msgid "Dark Mode" +msgstr "Mode sombre" + +msgid "Feedback" +msgstr "Commentaires" + +msgid "Log Level" +msgstr "Niveau de journalisation" + +msgid "Set the log level for Bandix service" +msgstr "Définir le niveau de journalisation du service Bandix" + +msgid "Offline Timeout" +msgstr "Délai d'expiration hors ligne" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "Définir le délai de détection de déconnexion (secondes). Les appareils inactifs plus longtemps seront marqués hors ligne" + +msgid "Realtime Traffic Period" +msgstr "Période de trafic en temps réel" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "Intervalle de 10 minutes utilise environ 60 Ko par appareil" + +msgid "Data Flush Interval" +msgstr "Intervalle de vidage des données" + +msgid "Set the interval for flushing data to disk" +msgstr "Définir l'intervalle d'écriture des données sur le disque" + +msgid "1 minute" +msgstr "1 minute" + +msgid "5 minutes" +msgstr "5 minutes" + +msgid "10 minutes" +msgstr "10 minutes" + +msgid "15 minutes" +msgstr "15 minutes" + +msgid "20 minutes" +msgstr "20 minutes" + +msgid "25 minutes" +msgstr "25 minutes" + +msgid "30 minutes" +msgstr "30 minutes" + +msgid "1 hour" +msgstr "1 heure" + +msgid "2 hours" +msgstr "2 heures" + +msgid "12 hours" +msgstr "12 heures" + +msgid "24 hours" +msgstr "24 heures" + +msgid "Data Directory" +msgstr "Répertoire de données" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "Si vous changez le répertoire, veuillez l'ajouter manuellement au répertoire de sauvegarde" + +msgid "Bandix data storage directory" +msgstr "Répertoire de stockage des données Bandix" + +msgid "Enable Bandix connection monitoring" +msgstr "Activer la surveillance des connexions Bandix" + +msgid "Enable Bandix DNS monitoring" +msgstr "Activer la surveillance DNS Bandix" + +msgid "DNS Max Records" +msgstr "Nombre maximum d'enregistrements DNS" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "Définir le nombre maximum d'enregistrements DNS à conserver. Les plus anciens seront supprimés au-delà" + +msgid "Persist DNS Data" +msgstr "Persister les données DNS" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Activer la fonctionnalité de persistance des données DNS, les données ne seront enregistrées sur le disque que lorsque cette option est activée" + +msgid "DNS Data Flush Interval" +msgstr "Intervalle de vidage des données DNS" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "Définir l'intervalle pour vider les données DNS sur le disque" + +msgid "Persist History Data" +msgstr "Persister les données d'historique" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Activer la fonctionnalité de persistance des données, les données ne seront enregistrées sur le disque que lorsque cette option est activée" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "N'occupe pas d'espace de stockage, stocké uniquement en mémoire" + +msgid "Query & Response" +msgstr "Requête et Réponse" + +msgid "Queries" +msgstr "Requêtes" + +msgid "Responses" +msgstr "Réponses" + +msgid "Average Response Time" +msgstr "Temps de Réponse Moyen" + +msgid "Show More" +msgstr "Afficher plus" + +msgid "Show Less" +msgstr "Afficher moins" + +msgid "Add Schedule Rule" +msgstr "Ajouter une règle de limitation programmée" + +msgid "Add Rule" +msgstr "Ajouter une règle" + +msgid "Set rate limit rules for different time periods" +msgstr "Définir des règles de limitation pour différentes périodes" + +msgid "Time Slot" +msgstr "Créneau horaire" + +msgid "Days of Week" +msgstr "Jours de la semaine" + +msgid "Mon" +msgstr "Lun" + +msgid "Tue" +msgstr "Mar" + +msgid "Wed" +msgstr "Mer" + +msgid "Thu" +msgstr "Jeu" + +msgid "Fri" +msgstr "Ven" + +msgid "Sat" +msgstr "Sam" + +msgid "Sun" +msgstr "Dim" + +msgid "Adding..." +msgstr "Ajout en cours..." + +msgid "Failed to add schedule rule: " +msgstr "Échec de l'ajout de la règle programmée : " + +msgid "Please set time slot" +msgstr "Veuillez définir un créneau horaire" + +msgid "Please select at least one day" +msgstr "Veuillez sélectionner au moins un jour" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "Aucune règle programmée pour le moment, cliquez sur \"Ajouter une règle\" pour commencer" + +msgid "Loading..." +msgstr "Chargement..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "Chargement par morceaux, veuillez patienter... (%d/%d)" + +msgid "No schedule rules" +msgstr "Aucune règle programmée" + +msgid "Failed to load schedule rules" +msgstr "Échec du chargement des règles programmées" + +msgid "Delete Schedule Rule" +msgstr "Supprimer la règle programmée" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "Êtes-vous sûr de vouloir supprimer cette règle programmée ?" + +msgid "Failed to delete schedule rule" +msgstr "Échec de la suppression de la règle programmée" + +msgid "Delete Device" +msgstr "Supprimer l'appareil" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "Êtes-vous sûr de vouloir supprimer cet appareil ? L'historique du trafic sera supprimé." + +msgid "Failed to delete device" +msgstr "Échec de la suppression de l'appareil" + +msgid "Confirm" +msgstr "Confirmer" + +msgid "Close" +msgstr "Fermer" + +msgid "rule" +msgstr "règle" + +msgid "rules" +msgstr "règles" + +msgid "more" +msgstr "plus" + +msgid "No active rule" +msgstr "Aucune règle active" + +msgid "Schedule Rules" +msgstr "Règles de limitation programmée" + +msgid "Upload Statistics" +msgstr "Statistiques d'envoi" + +msgid "Download Statistics" +msgstr "Statistiques de téléchargement" + +msgid "Cumulative Traffic" +msgstr "Trafic cumulé" + +msgid "Daily" +msgstr "Quotidien" + +msgid "Weekly" +msgstr "Hebdomadaire" + +msgid "Monthly" +msgstr "Mensuel" + +msgid "Statistics" +msgstr "Statistiques" + +msgid "Average" +msgstr "Moyenne" + +msgid "Maximum" +msgstr "Maximum" + +msgid "Minimum" +msgstr "Minimum" + +msgid "WAN Upload" +msgstr "Envoi WAN" + +msgid "WAN Download" +msgstr "Téléchargement WAN" + +msgid "WAN Uploaded" +msgstr "Envoyé WAN" + +msgid "WAN Downloaded" +msgstr "Téléchargé WAN" + +msgid "Clear Traffic Data" +msgstr "Effacer les données de trafic" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "Êtes-vous sûr de vouloir effacer toutes les données de trafic ? Cette action est irréversible." + +msgid "Failed to clear traffic data: " +msgstr "Échec de l'effacement des données de trafic : " + +msgid "Restart Service" +msgstr "Redémarrer le service" + +msgid "Restart Bandix Service" +msgstr "Redémarrer le service Bandix" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "Êtes-vous sûr de vouloir redémarrer le service Bandix ?" + +msgid "Failed to restart service: " +msgstr "Échec du redémarrage du service : " + +msgid "Realtime" +msgstr "Temps réel" + +msgid "Last 24 Hours" +msgstr "Dernières 24 heures" + +msgid "Last 7 Days" +msgstr "7 derniers jours" + +msgid "Last 30 Days" +msgstr "30 derniers jours" + +msgid "Last 10 Minutes" +msgstr "10 dernières minutes" + +msgid "Last 15 Minutes" +msgstr "15 dernières minutes" + +msgid "Last 30 Minutes" +msgstr "30 dernières minutes" + +msgid "Last 1 Hour" +msgstr "Dernière heure" + +msgid "Starting installation..." +msgstr "Démarrage de l'installation..." + +msgid "Page will refresh in 3 seconds." +msgstr "La page sera actualisée dans 3 secondes." + +msgid "Installation failed" +msgstr "Échec de l'installation" + +msgid "Installation failed at step: " +msgstr "Échec de l'installation à l'étape : " + +msgid "Details: " +msgstr "Détails : " + +msgid "Installation failed: " +msgstr "Échec de l'installation : " + +msgid "Unknown error" +msgstr "Erreur inconnue" + +msgid "Service restarted successfully." +msgstr "Service redémarré avec succès." + +msgid "Service restart may have failed. Please check manually." +msgstr "Le redémarrage du service a peut-être échoué. Veuillez vérifier manuellement." + +msgid "Please restart the service." +msgstr "Veuillez redémarrer le service." + +msgid "LuCI App updated successfully!" +msgstr "Application LuCI mise à jour avec succès !" + +msgid "Bandix updated successfully!" +msgstr "Bandix mis à jour avec succès !" + +msgid "LuCI App has update: " +msgstr "L'application LuCI a une mise à jour : " + +msgid "Bandix has update: " +msgstr "Bandix a une mise à jour : " + +msgid "LuCI App is up to date: " +msgstr "L'application LuCI est à jour : " + +msgid "Bandix is up to date: " +msgstr "Bandix est à jour : " + +msgid "Updates Available" +msgstr "Mises à jour Disponibles" + +msgid "No Updates Available" +msgstr "Aucune Mise à jour Disponible" + +msgid "Detected Architecture" +msgstr "Architecture Détectée" + +msgid "Package Manager" +msgstr "Gestionnaire de Paquets" + +msgid "LuCI Assets" +msgstr "Ressources LuCI" + +msgid "Bandix Assets" +msgstr "Ressources Bandix" + +msgid "Failed to check for updates" +msgstr "Échec de la vérification des mises à jour" + +msgid "Failed to check for updates: " +msgstr "Échec de la vérification des mises à jour : " + +msgid "Checking..." +msgstr "Vérification..." + +msgid "Check for Updates" +msgstr "Rechercher des Mises à Jour" + +msgid "Installing..." +msgstr "Installation..." + +msgid "Download and Install" +msgstr "Télécharger et Installer" + +msgid "Manual Download" +msgstr "Téléchargement Manuel" + +msgid "Close" +msgstr "Fermer" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "Démarrage de l'installation... La page sera actualisée automatiquement dans 30 secondes." + +msgid "Please clear your browser cache manually after updating." +msgstr "Veuillez vider manuellement le cache du navigateur après la mise à jour." + +msgid "Traffic Statistics" +msgstr "Statistiques de Trafic" + +msgid "Traffic Statistics" +msgstr "Statistiques de Trafic" + +msgid "Device Usage Ranking" +msgstr "Classement d'Utilisation des Appareils" + +msgid "Start Date" +msgstr "Date de Début" + +msgid "End Date" +msgstr "Date de Fin" + +msgid "Reset" +msgstr "Réinitialiser" + +msgid "Today" +msgstr "Aujourd'hui" + +msgid "This Week" +msgstr "Cette Semaine" + +msgid "Last Week" +msgstr "Semaine Dernière" + +msgid "This Month" +msgstr "Ce Mois" + +msgid "Last Month" +msgstr "Mois Dernier" + +msgid "Last 90 Days" +msgstr "90 Derniers Jours" + +msgid "Last Year" +msgstr "Dernière Année" + +msgid "Traffic Timeline" +msgstr "Chronologie du Trafic" + +msgid "Aggregation:" +msgstr "Agrégation :" + +msgid "Hourly" +msgstr "Par Heure" + +msgid "Device:" +msgstr "Appareil :" + +msgid "Traffic Push URL" +msgstr "URL de poussée du trafic" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "Pousser les données de trafic vers un endpoint HTTP distant (POST JSON). Laisser vide pour désactiver." + +msgid "Device Event Push URL" +msgstr "URL de poussée des événements de périphérique" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "Pousser les événements de connexion/déconnexion de périphérique vers un endpoint HTTP distant (POST JSON lors du changement d'état). Laisser vide pour désactiver." + +msgid "Additional Subnets" +msgstr "Sous-réseaux supplémentaires" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "Sous-réseaux locaux supplémentaires (notation CIDR séparée par des virgules, ex. '192.168.2.0/24,10.0.0.0/8'). Laisser vide pour utiliser uniquement le sous-réseau d'interface." + +msgid "Exclude Interface Device" +msgstr "Exclure l'appareil d'interface" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "Exclure le routeur lui-même (appareil d'interface) des statistiques de trafic" + +msgid "Enable Neighbor Flush" +msgstr "Activer la vidange de la table des voisins" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "Activer le vidage périodique des données de la table des voisins. Généralement non recommandé si la liste des appareils fonctionne normalement." + +msgid "Neighbor Flush Interval" +msgstr "Intervalle de vidange de la table des voisins" + +msgid "Set the interval for flushing neighbor table data" +msgstr "Définir l'intervalle de vidange des données de la table des voisins" + +msgid "No devices" +msgstr "Aucun appareil" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "Le trafic LAN est vu depuis la perspective de tout le sous-réseau, donc l'upload et le download sont toujours égaux, formant une boucle fermée. De plus, en raison de la présence de puces de commutation matérielles dédiées, le trafic LAN entre 2 appareils (par ex., PC - NAS) au sein du réseau local peut ne pas être surveillable." + +msgid "Protocol" +msgstr "Protocole" + +msgid "State" +msgstr "État" + +msgid "Send" +msgstr "Envoyer" + +msgid "Reply" +msgstr "Réponse" + +msgid "Flags" +msgstr "Drapeaux" + +msgid "Loading…" +msgstr "Chargement…" + +msgid "No connections" +msgstr "Aucune connexion" + +msgid "pkts" +msgstr "paquets" + +msgid "Failed to load" +msgstr "Échec du chargement" + +msgid "Connection Details" +msgstr "Détails de connexion" + +msgid "Details" +msgstr "Détails" + +msgid "Orig Src" +msgstr "Src. orig." + +msgid "Orig Dst" +msgstr "Dest. orig." + +msgid "Repl Src" +msgstr "Src. répl." + +msgid "Repl Dst" +msgstr "Dest. répl." + +msgid "TC backend" +msgstr "Backend TC" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "Selectionnez le backend d attache TC. Recommandation : utilisez auto par defaut ; tcx est prefere sur noyau >= 6.6 ; netlink est plus sur sur les anciens noyaux." + +msgid "TC order" +msgstr "Ordre TC" + +msgid "Netlink priority" +msgstr "Priorite Netlink" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "Utilise uniquement lorsque le backend est netlink. Plage : 0..65535 (0 signifie par defaut)." + +msgid "TCX ingress anchor program id" +msgstr "ID du programme d ancrage ingress TCX" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "Utilise lorsque tc_order est before/after. Doit etre un ID de programme ingress valide sur la meme interface." + +msgid "TCX egress anchor program id" +msgstr "ID du programme d ancrage egress TCX" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "Utilise lorsque tc_order est before/after. Doit etre un ID de programme egress valide sur la meme interface." diff --git a/luci-app-bandix/po/ja/bandix.po b/luci-app-bandix/po/ja/bandix.po new file mode 100644 index 00000000..bc18fdf3 --- /dev/null +++ b/luci-app-bandix/po/ja/bandix.po @@ -0,0 +1,1257 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Bandix トラフィックモニター" + +msgid "Loading data..." +msgstr "データを読ã¿è¾¼ã¿ä¸­..." + +msgid "Unable to fetch data" +msgstr "データをå–å¾—ã§ãã¾ã›ã‚“" + +msgid "Unable to fetch history data" +msgstr "履歴データをå–å¾—ã§ãã¾ã›ã‚“" + +msgid "Hostname" +msgstr "ホストå" + +msgid "IP Address" +msgstr "IPアドレス" + +msgid "MAC Address" +msgstr "MACアドレス" + +msgid "Download Speed" +msgstr "ダウンロード速度" + +msgid "Upload Speed" +msgstr "アップロード速度" + +msgid "Total Download" +msgstr "ç·ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰é‡" + +msgid "Total Upload" +msgstr "ç·ã‚¢ãƒƒãƒ—ロードé‡" + +msgid "Download Limit" +msgstr "ダウンロード制é™" + +msgid "Upload Limit" +msgstr "アップロード制é™" + +msgid "Interface Language" +msgstr "インターフェース言語" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "Bandix トラフィックモニターã®è¡¨ç¤ºè¨€èªžã‚’é¸æŠž" + +msgid "Device Info" +msgstr "デãƒã‚¤ã‚¹æƒ…å ±" + +msgid "Device List" +msgstr "デãƒã‚¤ã‚¹ä¸€è¦§" + +msgid "LAN Traffic" +msgstr "LAN トラフィック" + +msgid "WAN Traffic" +msgstr "WAN トラフィック" + +msgid "Network Type" +msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¿ã‚¤ãƒ—" + +msgid "Rate Limit" +msgstr "速度制é™" + +msgid "Actions" +msgstr "æ“作" + +msgid "Online Devices" +msgstr "オンラインデãƒã‚¤ã‚¹" + +msgid "WAN Only" +msgstr "WAN トラフィックã®ã¿" + +msgid "Settings" +msgstr "設定" + +msgid "Device Settings" +msgstr "デãƒã‚¤ã‚¹è¨­å®š" + +msgid "Rate Limits" +msgstr "速度制é™" + +msgid "Remove Rate Limit" +msgstr "速度制é™ã‚’解除" + +msgid "Save" +msgstr "ä¿å­˜" + +msgid "Cancel" +msgstr "キャンセル" + +msgid "Set Rate Limit" +msgstr "速度制é™ã‚’設定" + +msgid "Device" +msgstr "デãƒã‚¤ã‚¹" + +msgid "Set Hostname" +msgstr "ホストåを設定" + +msgid "Please enter hostname" +msgstr "ホストåを入力ã—ã¦ãã ã•ã„" + +msgid "Hostname set successfully" +msgstr "ホストåã®è¨­å®šã«æˆåŠŸã—ã¾ã—ãŸ" + +msgid "Failed to set hostname" +msgstr "ホストåã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ" + +msgid "Unlimited" +msgstr "無制é™" + +msgid "Settings saved successfully" +msgstr "設定をä¿å­˜ã—ã¾ã—ãŸ" + +msgid "Failed to save settings" +msgstr "設定ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ" + +msgid "Please enter a valid speed value" +msgstr "有効ãªé€Ÿåº¦å€¤ã‚’入力ã—ã¦ãã ã•ã„" + +msgid "Speed value must be greater than 0" +msgstr "速度値ã¯0より大ãã„å¿…è¦ãŒã‚りã¾ã™" + +msgid "Saving..." +msgstr "ä¿å­˜ä¸­..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "速度制é™ã¯ WAN トラフィックã«ã®ã¿é©ç”¨ã•れã¾ã™ã€‚一部ã®LAN内部トラフィックã¯ã€ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã‚¹ã‚¤ãƒƒãƒãƒ³ã‚°ã‚¢ã‚¯ã‚»ãƒ©ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«ã‚ˆã‚Šç›£è¦–ã•れãªã„å ´åˆãŒã‚りã¾ã™ã€‚" + +msgid "Tip: Enter 0 for unlimited" +msgstr "ヒント:0を入力ã™ã‚‹ã¨ç„¡åˆ¶é™ã«ãªã‚Šã¾ã™" + +msgid "Traffic History" +msgstr "トラフィック履歴" + +msgid "Realtime Traffic Trends" +msgstr "リアルタイムトラフィックトレンド" + +msgid "Select Device" +msgstr "デãƒã‚¤ã‚¹ã‚’é¸æŠž" + +msgid "All Devices" +msgstr "ã™ã¹ã¦ã®ãƒ‡ãƒã‚¤ã‚¹" + +msgid "Time Range" +msgstr "時間範囲" + +msgid "Last 5 minutes" +msgstr "éŽåŽ»5分" + +msgid "Last 30 minutes" +msgstr "éŽåŽ»30分" + +msgid "Last 2 hours" +msgstr "éŽåŽ»2時間" + +msgid "Type" +msgstr "タイプ" + +msgid "Total" +msgstr "åˆè¨ˆ" + +msgid "LAN" +msgstr "LAN トラフィック" + +msgid "WAN" +msgstr "WAN トラフィック" + +msgid "Refresh" +msgstr "æ›´æ–°" + +msgid "Upload Rate" +msgstr "アップロード速度" + +msgid "Download Rate" +msgstr "ダウンロード速度" + +msgid "Last" +msgstr "最後" + +msgid "second" +msgstr "ç§’" + +msgid "minute" +msgstr "分" + +msgid "hour" +msgstr "時間" + +msgid "day" +msgstr "æ—¥" + +msgid "week" +msgstr "週" + +msgid "Other Rates" +msgstr "ãã®ä»–ã®é€Ÿåº¦" + +msgid "Cumulative" +msgstr "累計トラフィック" + +msgid "Total Uploaded" +msgstr "ç·ã‚¢ãƒƒãƒ—ロード" + +msgid "Total Downloaded" +msgstr "ç·ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰" + +msgid "LAN Uploaded" +msgstr "LAN アップロード済ã¿" + +msgid "LAN Downloaded" +msgstr "LAN ダウンロード済ã¿" + +msgid "WAN Uploaded" +msgstr "WAN アップロード済ã¿" + +msgid "WAN Downloaded" +msgstr "WAN ダウンロード済ã¿" + +msgid "Total Upload" +msgstr "ç·ã‚¢ãƒƒãƒ—ロード速度" + +msgid "Total Download" +msgstr "ç·ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰é€Ÿåº¦" + +msgid "LAN Upload" +msgstr "LAN アップロード速度" + +msgid "LAN Download" +msgstr "LAN ダウンロード速度" + +msgid "WAN Upload" +msgstr "WAN アップロード速度" + +msgid "WAN Download" +msgstr "WAN ダウンロード速度" + +msgid "Never Online" +msgstr "オンラインã«ãªã£ãŸã“ã¨ãŒã‚りã¾ã›ã‚“" + +msgid "Just Now" +msgstr "ãŸã£ãŸä»Š" + +msgid "min ago" +msgstr "分å‰" + +msgid "h ago" +msgstr "時間å‰" + +msgid "days ago" +msgstr "æ—¥å‰" + +msgid "months ago" +msgstr "ヶ月å‰" + +msgid "years ago" +msgstr "å¹´å‰" + +msgid "Last Online" +msgstr "最終オンライン" + +msgid "Zoom" +msgstr "ズーム" + +msgid "Sort By" +msgstr "ä¸¦ã³æ›¿ãˆ" + +msgid "Online Status" +msgstr "オンライン状態" + +msgid "Total Traffic" +msgstr "ç·ãƒˆãƒ©ãƒ•ィック" + +msgid "Ascending" +msgstr "昇順" + +msgid "Descending" +msgstr "é™é †" + +msgid "Sort by Speed" +msgstr "速度ã§ä¸¦ã³æ›¿ãˆ" + +msgid "Sort by Traffic" +msgstr "トラフィックã§ä¸¦ã³æ›¿ãˆ" + +msgid "Simple Mode" +msgstr "シンプルモード" + +msgid "Detailed Mode" +msgstr "詳細モード" + +msgid "Bandix DNS Monitor" +msgstr "Bandix DNS モニター" + +msgid "DNS Monitor" +msgstr "DNS モニター" + +msgid "DNS Query Records" +msgstr "DNS クエリ記録" + +msgid "DNS Statistics" +msgstr "DNS 統計情報" + +msgid "DNS Monitoring Disabled" +msgstr "DNS監視ãŒç„¡åйã§ã™" + +msgid "Please enable DNS monitoring in settings" +msgstr "設定ã§DNS監視を有効ã«ã—ã¦ãã ã•ã„" + +msgid "Go to Settings" +msgstr "設定ã«ç§»å‹•" + +msgid "No Data" +msgstr "データãªã—" + +msgid "Time" +msgstr "時間" + +msgid "Domain" +msgstr "ドメイン" + +msgid "Query Type" +msgstr "クエリタイプ" + +msgid "Response Code" +msgstr "応答コード" + +msgid "Response Time" +msgstr "応答時間" + +msgid "Source IP" +msgstr "é€ä¿¡å…ƒIP" + +msgid "Destination IP" +msgstr "宛先IP" + +msgid "Response IPs" +msgstr "応答IP" + +msgid "Response Result" +msgstr "å¿œç­”çµæžœ" + +msgid "DNS Server" +msgstr "DNSサーãƒãƒ¼" + +msgid "Query" +msgstr "クエリ" + +msgid "Response" +msgstr "応答" + +msgid "Filter" +msgstr "フィルター" + +msgid "Domain Filter" +msgstr "ドメインフィルター" + +msgid "Device Filter" +msgstr "デãƒã‚¤ã‚¹ãƒ•ィルター" + +msgid "DNS Server Filter" +msgstr "DNSサーãƒãƒ¼ãƒ•ィルター" + +msgid "Type Filter" +msgstr "タイプフィルター" + +msgid "All" +msgstr "ã™ã¹ã¦" + +msgid "Period" +msgstr "期間" + +msgid "Display Mode" +msgstr "表示モード" + +msgid "This Year" +msgstr "今年" + +msgid "Week" +msgstr "今週" + +msgid "Month" +msgstr "今月" + +msgid "Year" +msgstr "今年" + +msgid "Queries Only" +msgstr "クエリã®ã¿" + +msgid "Responses Only" +msgstr "応答ã®ã¿" + +msgid "Search" +msgstr "検索" + +msgid "Search Domain" +msgstr "ドメインを検索" + +msgid "Search Device" +msgstr "デãƒã‚¤ã‚¹ã‚’検索" + +msgid "Search DNS Server" +msgstr "DNSサーãƒãƒ¼ã‚’検索" + +msgid "Clear" +msgstr "クリア" + +msgid "Previous" +msgstr "å‰ã¸" + +msgid "Next" +msgstr "次ã¸" + +msgid "Page" +msgstr "ページ" + +msgid "of" +msgstr "ã®" + +msgid "Total" +msgstr "åˆè¨ˆ" + +msgid "records" +msgstr "ä»¶ã®è¨˜éŒ²" + +msgid "Per Page" +msgstr "ページã‚ãŸã‚Š" + +msgid "" +msgstr "ä»¶" + +msgid "Total Queries" +msgstr "ç·ã‚¯ã‚¨ãƒªæ•°" + +msgid "Total Responses" +msgstr "ç·å¿œç­”æ•°" + +msgid "Queries with Response" +msgstr "応答ã‚りクエリ" + +msgid "Queries without Response" +msgstr "応答ãªã—クエリ" + +msgid "Avg Response Time" +msgstr "å¹³å‡å¿œç­”時間" + +msgid "Min Response Time" +msgstr "最短応答時間" + +msgid "Max Response Time" +msgstr "最長応答時間" + +msgid "Success Rate" +msgstr "æˆåŠŸçŽ‡" + +msgid "Success" +msgstr "æˆåŠŸ" + +msgid "Failure" +msgstr "失敗" + +msgid "Top Domains" +msgstr "最もクエリã•れãŸãƒ‰ãƒ¡ã‚¤ãƒ³" + +msgid "Top Query Types" +msgstr "最も使用ã•れãŸã‚¯ã‚¨ãƒªã‚¿ã‚¤ãƒ—" + +msgid "Top Devices" +msgstr "最もアクティブãªãƒ‡ãƒã‚¤ã‚¹" + +msgid "Top DNS Servers" +msgstr "最も使用ã•れãŸDNSサーãƒãƒ¼" + +msgid "Unique Devices" +msgstr "ユニークデãƒã‚¤ã‚¹æ•°" + +msgid "ms" +msgstr "ミリ秒" + +msgid "minutes" +msgstr "分" + +msgid "Unknown Device" +msgstr "䏿˜Žãªãƒ‡ãƒã‚¤ã‚¹" + +msgid "Domain not found" +msgstr "ドメインãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +msgid "Server error" +msgstr "サーãƒãƒ¼ã‚¨ãƒ©ãƒ¼" + +msgid "Format error" +msgstr "フォーマットエラー" + +msgid "Refused" +msgstr "æ‹’å¦" + +msgid "Other" +msgstr "ãã®ä»–" + +msgid "Does not include DoH and DoT" +msgstr "DoH 㨠DoT ã¯å«ã¾ã‚Œã¾ã›ã‚“" + +msgid "Latest Response Time" +msgstr "最新ã®å¿œç­”時間" + +msgid "Response Code Distribution" +msgstr "応答コード分布" + +msgid "Response Time Percentiles" +msgstr "応答時間パーセンタイル" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Bandix 接続モニター" + +msgid "Connection Monitor" +msgstr "接続モニター" + +msgid "Device Connection Statistics" +msgstr "デãƒã‚¤ã‚¹æŽ¥ç¶šçµ±è¨ˆ" + +msgid "Global Connection Statistics" +msgstr "グローãƒãƒ«æŽ¥ç¶šçµ±è¨ˆ" + +msgid "Active TCP" +msgstr "アクティブTCP" + +msgid "Active UDP" +msgstr "アクティブUDP" + +msgid "Closed TCP" +msgstr "クローズTCP" + +msgid "Total Connections" +msgstr "ç·æŽ¥ç¶šæ•°" + +msgid "Last Updated" +msgstr "最終更新" + +msgid "TCP Connections" +msgstr "TCP接続数" + +msgid "UDP Connections" +msgstr "UDP接続数" + +msgid "Established TCP" +msgstr "確立済ã¿TCP" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "デãƒã‚¤ã‚¹ç·æ•°" + +msgid "Connection Monitor Disabled" +msgstr "接続モニターãŒç„¡åйã§ã™" + +msgid "Please enable connection monitoring in settings" +msgstr "è¨­å®šã§æŽ¥ç¶šãƒ¢ãƒ‹ã‚¿ãƒ¼ã‚’æœ‰åŠ¹ã«ã—ã¦ãã ã•ã„" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "リストã¯LANデãƒã‚¤ã‚¹æŽ¥ç¶šã®ã¿ã‚’表示ã—ã¾ã™ã€‚データã¯ç·æŽ¥ç¶šæ•°ã¨ç•°ãªã‚‹å ´åˆãŒã‚りã¾ã™ã€‚" + +msgid "TCP Status Details" +msgstr "TCP 状態詳細" + +msgid "Basic Settings" +msgstr "基本設定" + +msgid "Traffic Monitor Settings" +msgstr "トラフィックモニター設定" + +msgid "Connection Monitor Settings" +msgstr "接続モニター設定" + +msgid "DNS Monitor Settings" +msgstr "DNSモニター設定" + +msgid "Bandix Basic Configuration" +msgstr "Bandix 基本設定" + +msgid "Configure basic parameters for Bandix service" +msgstr "Bandix サービスã®åŸºæœ¬ãƒ‘ラメータを設定" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "Bandix トラフィックモニター設定" + +msgid "Configure traffic monitoring related parameters" +msgstr "トラフィック監視関連ã®ãƒ‘ラメータを設定" + +msgid "Bandix Connection Monitor Configuration" +msgstr "Bandix 接続モニター設定" + +msgid "Configure connection monitoring related parameters" +msgstr "接続監視関連ã®ãƒ‘ラメータを設定" + +msgid "Bandix DNS Monitor Configuration" +msgstr "Bandix DNSモニター設定" + +msgid "Configure DNS monitoring related parameters" +msgstr "DNS監視関連ã®ãƒ‘ラメータを設定" + +msgid "Enable" +msgstr "有効" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "Bandix トラフィックモニターサービスを有効ã«ã™ã‚‹" + +msgid "Enable Traffic Monitoring" +msgstr "トラフィック監視を有効ã«ã™ã‚‹" + +msgid "Enable Connection Monitoring" +msgstr "接続監視を有効ã«ã™ã‚‹" + +msgid "Enable DNS Monitoring" +msgstr "DNS監視を有効ã«ã™ã‚‹" + +msgid "Simplified Chinese" +msgstr "簡体字中国語" + +msgid "Traditional Chinese" +msgstr "ç¹ä½“字中国語" + +msgid "Port" +msgstr "ãƒãƒ¼ãƒˆ" + +msgid "Port for Bandix service to listen on" +msgstr "Bandix サービスãŒãƒªãƒƒã‚¹ãƒ³ã™ã‚‹ãƒãƒ¼ãƒˆ" + +msgid "TC Priority" +msgstr "TC 優先度" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "TC フィルターã®å„ªå…ˆåº¦ã‚’設定ã—ã¦ã€ä»–ã® eBPF TC プログラムã¨ã‚ˆã‚Šè‰¯ã共存ã§ãるよã†ã«ã—ã¾ã™ã€‚数値ãŒå°ã•ã„ã»ã©å„ªå…ˆåº¦ãŒé«˜ããªã‚Šã¾ã™ã€‚0 ã¯ã‚·ã‚¹ãƒ†ãƒ å‰²ã‚Šå½“ã¦ã‚’æ„味ã—ã¾ã™ã€‚" + +msgid "Monitor Interface" +msgstr "監視インターフェース" + +msgid "Select the LAN network interface to monitor" +msgstr "監視ã™ã‚‹LANãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ã‚’é¸æŠž" + +msgid "Speed Units" +msgstr "速度å˜ä½" + +msgid "Select the speed display unit format" +msgstr "速度表示ã®å˜ä½å½¢å¼ã‚’é¸æŠž" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "ãƒã‚¤ãƒˆå˜ä½ (B/s, KB/s, MB/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "ビットå˜ä½ (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "インターフェーステーマ" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "Bandix トラフィックモニターã®è¡¨ç¤ºãƒ†ãƒ¼ãƒžã‚’é¸æŠž" + +msgid "Follow System" +msgstr "システムã«å¾“ã†" + +msgid "Light Mode" +msgstr "ライトモード" + +msgid "Dark Mode" +msgstr "ダークモード" + +msgid "Feedback" +msgstr "フィードãƒãƒƒã‚¯" + +msgid "Log Level" +msgstr "ログレベル" + +msgid "Set the log level for Bandix service" +msgstr "Bandix サービスã®ãƒ­ã‚°ãƒ¬ãƒ™ãƒ«ã‚’設定" + +msgid "Offline Timeout" +msgstr "オフラインタイムアウト" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "デãƒã‚¤ã‚¹ã®ã‚ªãƒ•ライン検出ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã‚’設定(秒)。ã“ã®æ™‚間より長ãéžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªãƒ‡ãƒã‚¤ã‚¹ã¯ã‚ªãƒ•ラインã¨ã—ã¦ãƒžãƒ¼ã‚¯ã•れã¾ã™" + +msgid "Realtime Traffic Period" +msgstr "リアルタイムトラフィック周期" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "10分間隔ã§ãƒ‡ãƒã‚¤ã‚¹ã‚ãŸã‚Šç´„60KBを使用" + +msgid "Data Flush Interval" +msgstr "データフラッシュ間隔" + +msgid "Set the interval for flushing data to disk" +msgstr "データをディスクã«ãƒ•ラッシュã™ã‚‹é–“隔を設定" + +msgid "1 minute" +msgstr "1分" + +msgid "5 minutes" +msgstr "5分" + +msgid "10 minutes" +msgstr "10分" + +msgid "15 minutes" +msgstr "15分" + +msgid "20 minutes" +msgstr "20分" + +msgid "25 minutes" +msgstr "25分" + +msgid "30 minutes" +msgstr "30分" + +msgid "1 hour" +msgstr "1時間" + +msgid "2 hours" +msgstr "2時間" + +msgid "12 hours" +msgstr "12時間" + +msgid "24 hours" +msgstr "24時間" + +msgid "Data Directory" +msgstr "データディレクトリ" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "ディレクトリを変更ã—ãŸå ´åˆã¯ã€æ‰‹å‹•ã§ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ディレクトリã«è¿½åŠ ã—ã¦ãã ã•ã„" + +msgid "Bandix data storage directory" +msgstr "Bandix データストレージディレクトリ" + +msgid "Enable Bandix connection monitoring" +msgstr "Bandix 接続監視を有効ã«ã™ã‚‹" + +msgid "Enable Bandix DNS monitoring" +msgstr "Bandix DNS監視を有効ã«ã™ã‚‹" + +msgid "DNS Max Records" +msgstr "DNS最大記録数" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "ä¿æŒã™ã‚‹DNSã‚¯ã‚¨ãƒªè¨˜éŒ²ã®æœ€å¤§æ•°ã‚’設定。ã“ã®åˆ¶é™ã‚’è¶…ãˆã‚‹ã¨å¤ã„記録ãŒå‰Šé™¤ã•れã¾ã™" + +msgid "Persist DNS Data" +msgstr "DNSデータを永続化" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "DNSデータ永続化機能を有効ã«ã™ã‚‹ã€‚ã“ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰åйãªå ´åˆã®ã¿ãƒ‡ãƒ¼ã‚¿ãŒãƒ‡ã‚£ã‚¹ã‚¯ã«æ°¸ç¶šåŒ–ã•れã¾ã™" + +msgid "DNS Data Flush Interval" +msgstr "DNSデータフラッシュ間隔" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "DNSデータをディスクã«ãƒ•ラッシュã™ã‚‹é–“隔を設定" + +msgid "Persist History Data" +msgstr "履歴データを永続化" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "データ永続化機能を有効ã«ã™ã‚‹ã€‚ã“ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰åйãªå ´åˆã®ã¿ãƒ‡ãƒ¼ã‚¿ãŒãƒ‡ã‚£ã‚¹ã‚¯ã«æ°¸ç¶šåŒ–ã•れã¾ã™" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "ストレージ容é‡ã‚’å æœ‰ã›ãšã€ãƒ¡ãƒ¢ãƒªã«ã®ã¿ä¿å­˜" + +msgid "Query & Response" +msgstr "クエリã¨ãƒ¬ã‚¹ãƒãƒ³ã‚¹" + +msgid "Queries" +msgstr "クエリ" + +msgid "Responses" +msgstr "レスãƒãƒ³ã‚¹" + +msgid "Average Response Time" +msgstr "å¹³å‡å¿œç­”時間" + +msgid "Show More" +msgstr "ã‚‚ã£ã¨è¦‹ã‚‹" + +msgid "Show Less" +msgstr "é–‰ã˜ã‚‹" + +msgid "Add Schedule Rule" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ã‚’追加" + +msgid "Add Rule" +msgstr "ルールを追加" + +msgid "Set rate limit rules for different time periods" +msgstr "ç•°ãªã‚‹æ™‚間帯ã«ãƒ¬ãƒ¼ãƒˆåˆ¶é™ãƒ«ãƒ¼ãƒ«ã‚’設定" + +msgid "Time Slot" +msgstr "時間帯" + +msgid "Days of Week" +msgstr "曜日" + +msgid "Mon" +msgstr "月" + +msgid "Tue" +msgstr "ç«" + +msgid "Wed" +msgstr "æ°´" + +msgid "Thu" +msgstr "木" + +msgid "Fri" +msgstr "金" + +msgid "Sat" +msgstr "土" + +msgid "Sun" +msgstr "æ—¥" + +msgid "Adding..." +msgstr "追加中..." + +msgid "Failed to add schedule rule: " +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ã®è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸï¼š" + +msgid "Please set time slot" +msgstr "時間帯を設定ã—ã¦ãã ã•ã„" + +msgid "Please select at least one day" +msgstr "å°‘ãªãã¨ã‚‚1æ—¥ã‚’é¸æŠžã—ã¦ãã ã•ã„" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ãŒã¾ã ã‚りã¾ã›ã‚“。「ルールを追加ã€ã‚’クリックã—ã¦è¨­å®šã‚’é–‹å§‹ã—ã¦ãã ã•ã„" + +msgid "Loading..." +msgstr "読ã¿è¾¼ã¿ä¸­..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "分割読ã¿è¾¼ã¿ä¸­ã§ã™ã€‚ã—ã°ã‚‰ããŠå¾…ã¡ãã ã•ã„... (%d/%d)" + +msgid "No schedule rules" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ãªã—" + +msgid "Failed to load schedule rules" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ" + +msgid "Delete Schedule Rule" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ã‚’削除" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "ã“ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«åˆ¶é™ãƒ«ãƒ¼ãƒ«ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ" + +msgid "Failed to delete schedule rule" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ" + +msgid "Delete Device" +msgstr "デãƒã‚¤ã‚¹ã‚’削除" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "ã“ã®ãƒ‡ãƒã‚¤ã‚¹ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿãƒˆãƒ©ãƒ•ィック履歴も削除ã•れã¾ã™ã€‚" + +msgid "Failed to delete device" +msgstr "デãƒã‚¤ã‚¹ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ" + +msgid "Confirm" +msgstr "確èª" + +msgid "Close" +msgstr "é–‰ã˜ã‚‹" + +msgid "rule" +msgstr "ルール" + +msgid "rules" +msgstr "ルール" + +msgid "more" +msgstr "ãã®ä»–" + +msgid "No active rule" +msgstr "アクティブãªãƒ«ãƒ¼ãƒ«ãªã—" + +msgid "Schedule Rules" +msgstr "スケジュール制é™ãƒ«ãƒ¼ãƒ«" + +msgid "Upload Statistics" +msgstr "アップロード統計" + +msgid "Download Statistics" +msgstr "ダウンロード統計" + +msgid "Cumulative Traffic" +msgstr "ç´¯ç©ãƒˆãƒ©ãƒ•ィック" + +msgid "Daily" +msgstr "日次" + +msgid "Weekly" +msgstr "週次" + +msgid "Monthly" +msgstr "月次" + +msgid "Statistics" +msgstr "統計" + +msgid "Average" +msgstr "å¹³å‡" + +msgid "Maximum" +msgstr "最大" + +msgid "Minimum" +msgstr "最å°" + +msgid "WAN Upload" +msgstr "WAN アップロード" + +msgid "WAN Download" +msgstr "WAN ダウンロード" + +msgid "WAN Uploaded" +msgstr "WAN アップロードé‡" + +msgid "WAN Downloaded" +msgstr "WAN ダウンロードé‡" + +msgid "Clear Traffic Data" +msgstr "トラフィックデータを削除" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "ã™ã¹ã¦ã®ãƒˆãƒ©ãƒ•ィックデータを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。" + +msgid "Failed to clear traffic data: " +msgstr "トラフィックデータã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸï¼š" + +msgid "Restart Service" +msgstr "サービスå†èµ·å‹•" + +msgid "Restart Bandix Service" +msgstr "Bandix サービスをå†èµ·å‹•" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "Bandix サービスをå†èµ·å‹•ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ" + +msgid "Failed to restart service: " +msgstr "サービスã®å†èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸï¼š" + +msgid "Realtime" +msgstr "リアルタイム" + +msgid "Last 24 Hours" +msgstr "éŽåŽ»24時間" + +msgid "Last 7 Days" +msgstr "éŽåŽ»7日間" + +msgid "Last 30 Days" +msgstr "éŽåŽ»30日間" + +msgid "Last 10 Minutes" +msgstr "éŽåŽ»10分" + +msgid "Last 15 Minutes" +msgstr "éŽåŽ»15分" + +msgid "Last 30 Minutes" +msgstr "éŽåŽ»30分" + +msgid "Last 1 Hour" +msgstr "éŽåŽ»1時間" + +msgid "Starting installation..." +msgstr "インストールを開始ã—ã¦ã„ã¾ã™..." + +msgid "Page will refresh in 3 seconds." +msgstr "3秒後ã«ãƒšãƒ¼ã‚¸ãŒæ›´æ–°ã•れã¾ã™ã€‚" + +msgid "Installation failed" +msgstr "インストール失敗" + +msgid "Installation failed at step: " +msgstr "インストールãŒã‚¹ãƒ†ãƒƒãƒ—ã§å¤±æ•—ã—ã¾ã—ãŸï¼š" + +msgid "Details: " +msgstr "詳細:" + +msgid "Installation failed: " +msgstr "インストール失敗:" + +msgid "Unknown error" +msgstr "䏿˜Žãªã‚¨ãƒ©ãƒ¼" + +msgid "Service restarted successfully." +msgstr "ã‚µãƒ¼ãƒ“ã‚¹ãŒæ­£å¸¸ã«å†èµ·å‹•ã•れã¾ã—ãŸã€‚" + +msgid "Service restart may have failed. Please check manually." +msgstr "サービスã®å†èµ·å‹•ãŒå¤±æ•—ã—ãŸå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚手動ã§ç¢ºèªã—ã¦ãã ã•ã„。" + +msgid "Please restart the service." +msgstr "サービスをå†èµ·å‹•ã—ã¦ãã ã•ã„。" + +msgid "LuCI App updated successfully!" +msgstr "LuCIã‚¢ãƒ—ãƒªãŒæ­£å¸¸ã«æ›´æ–°ã•れã¾ã—ãŸï¼" + +msgid "Bandix updated successfully!" +msgstr "BandixãŒæ­£å¸¸ã«æ›´æ–°ã•れã¾ã—ãŸï¼" + +msgid "LuCI App has update: " +msgstr "LuCIã‚¢ãƒ—ãƒªã«æ›´æ–°ãŒã‚りã¾ã™ï¼š" + +msgid "Bandix has update: " +msgstr "Bandixã«æ›´æ–°ãŒã‚りã¾ã™ï¼š" + +msgid "LuCI App is up to date: " +msgstr "LuCIã‚¢ãƒ—ãƒªã¯æœ€æ–°ã§ã™ï¼š" + +msgid "Bandix is up to date: " +msgstr "Bandixã¯æœ€æ–°ã§ã™ï¼š" + +msgid "Updates Available" +msgstr "利用å¯èƒ½ãªæ›´æ–°" + +msgid "No Updates Available" +msgstr "利用å¯èƒ½ãªæ›´æ–°ãªã—" + +msgid "Detected Architecture" +msgstr "検出ã•れãŸã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£" + +msgid "Package Manager" +msgstr "パッケージマãƒãƒ¼ã‚¸ãƒ£ãƒ¼" + +msgid "LuCI Assets" +msgstr "LuCIアセット" + +msgid "Bandix Assets" +msgstr "Bandixアセット" + +msgid "Failed to check for updates" +msgstr "æ›´æ–°ã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸ" + +msgid "Failed to check for updates: " +msgstr "æ›´æ–°ã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸï¼š" + +msgid "Checking..." +msgstr "確èªä¸­..." + +msgid "Check for Updates" +msgstr "更新を確èª" + +msgid "Installing..." +msgstr "インストール中..." + +msgid "Download and Install" +msgstr "ダウンロードã—ã¦ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«" + +msgid "Manual Download" +msgstr "手動ダウンロード" + +msgid "Close" +msgstr "é–‰ã˜ã‚‹" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "インストールを開始ã—ã¦ã„ã¾ã™... ページã¯30秒後ã«è‡ªå‹•çš„ã«æ›´æ–°ã•れã¾ã™ã€‚" + +msgid "Please clear your browser cache manually after updating." +msgstr "更新後ã€ãƒ–ラウザã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’手動ã§ã‚¯ãƒªã‚¢ã—ã¦ãã ã•ã„。" + +msgid "Traffic Statistics" +msgstr "トラフィック統計" + +msgid "Traffic Statistics" +msgstr "トラフィック統計" + +msgid "Device Usage Ranking" +msgstr "デãƒã‚¤ã‚¹ä½¿ç”¨é‡ãƒ©ãƒ³ã‚­ãƒ³ã‚°" + +msgid "Start Date" +msgstr "é–‹å§‹æ—¥" + +msgid "End Date" +msgstr "終了日" + +msgid "Reset" +msgstr "リセット" + +msgid "Today" +msgstr "今日" + +msgid "This Week" +msgstr "今週" + +msgid "Last Week" +msgstr "先週" + +msgid "This Month" +msgstr "今月" + +msgid "Last Month" +msgstr "先月" + +msgid "Last 90 Days" +msgstr "éŽåŽ»90æ—¥" + +msgid "Last Year" +msgstr "éŽåŽ»1å¹´" + +msgid "Traffic Timeline" +msgstr "トラフィックタイムライン" + +msgid "Aggregation:" +msgstr "集計:" + +msgid "Hourly" +msgstr "時間å˜ä½" + +msgid "Device:" +msgstr "デãƒã‚¤ã‚¹ï¼š" + +msgid "Traffic Push URL" +msgstr "トラフィックプッシュURL" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "トラフィックデータをリモートHTTPエンドãƒã‚¤ãƒ³ãƒˆã«ãƒ—ッシュ(POST JSON)。無効ã«ã™ã‚‹å ´åˆã¯ç©ºã®ã¾ã¾ã«ã—ã¾ã™ã€‚" + +msgid "Device Event Push URL" +msgstr "デãƒã‚¤ã‚¹ã‚¤ãƒ™ãƒ³ãƒˆãƒ—ッシュURL" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "デãƒã‚¤ã‚¹ã®ã‚ªãƒ³ãƒ©ã‚¤/オフラインイベントをリモートHTTPエンドãƒã‚¤ãƒ³ãƒˆã«ãƒ—ッシュ(状態変更時ã«POST JSON)。無効ã«ã™ã‚‹å ´åˆã¯ç©ºã®ã¾ã¾ã«ã—ã¾ã™ã€‚" + +msgid "Additional Subnets" +msgstr "追加サブãƒãƒƒãƒˆ" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "追加ã®ãƒ­ãƒ¼ã‚«ãƒ«ã‚µãƒ–ãƒãƒƒãƒˆï¼ˆã‚«ãƒ³ãƒžåŒºåˆ‡ã‚Šã®CIDR表記ã€ä¾‹ï¼š'192.168.2.0/24,10.0.0.0/8')。インターフェースサブãƒãƒƒãƒˆã®ã¿ã‚’使用ã™ã‚‹å ´åˆã¯ç©ºã®ã¾ã¾ã«ã—ã¾ã™ã€‚" + +msgid "Exclude Interface Device" +msgstr "インターフェースデãƒã‚¤ã‚¹ã‚’除外" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "トラフィック統計ã‹ã‚‰ãƒ«ãƒ¼ã‚¿ãƒ¼è‡ªä½“(インターフェースデãƒã‚¤ã‚¹ï¼‰ã‚’除外ã™ã‚‹" + +msgid "Enable Neighbor Flush" +msgstr "ãƒã‚¤ãƒãƒ¼ãƒ†ãƒ¼ãƒ–ルフラッシュを有効ã«ã™ã‚‹" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "ãƒã‚¤ãƒãƒ¼ãƒ†ãƒ¼ãƒ–ルデータã®å®šæœŸãƒ•ラッシュを有効ã«ã—ã¾ã™ã€‚デãƒã‚¤ã‚¹ãƒªã‚¹ãƒˆãŒæ­£å¸¸ã«å‹•作ã—ã¦ã„ã‚‹å ´åˆã¯ã€é€šå¸¸ã¯æœ‰åйã«ã—ãªã„ã“ã¨ã‚’ãŠå‹§ã‚ã—ã¾ã™ã€‚" + +msgid "Neighbor Flush Interval" +msgstr "ãƒã‚¤ãƒãƒ¼ãƒ†ãƒ¼ãƒ–ルフラッシュ間隔" + +msgid "Set the interval for flushing neighbor table data" +msgstr "ãƒã‚¤ãƒãƒ¼ãƒ†ãƒ¼ãƒ–ルデータã®ãƒ•ラッシュ間隔を設定" + +msgid "No devices" +msgstr "デãƒã‚¤ã‚¹ãªã—" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "LANトラフィックã¯ã‚µãƒ–ãƒãƒƒãƒˆå…¨ä½“ã®è¦–点ã‹ã‚‰è¦‹ã‚‰ã‚Œã‚‹ãŸã‚ã€ã‚¢ãƒƒãƒ—ロードã¨ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã¯å¸¸ã«ç­‰ã—ãã€é–‰ãƒ«ãƒ¼ãƒ—ã‚’å½¢æˆã—ã¾ã™ã€‚ã•らã«ã€å°‚用ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã‚¹ã‚¤ãƒƒãƒãƒ³ã‚°ãƒãƒƒãƒ—ã®å­˜åœ¨ã«ã‚ˆã‚Šã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯å†…ã®2ã¤ã®ãƒ‡ãƒã‚¤ã‚¹ï¼ˆä¾‹ï¼šPC - NAS)間ã®LANトラフィックã¯ç›£è¦–ã§ããªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" + +msgid "Protocol" +msgstr "プロトコル" + +msgid "State" +msgstr "状態" + +msgid "Send" +msgstr "é€ä¿¡" + +msgid "Reply" +msgstr "応答" + +msgid "Flags" +msgstr "フラグ" + +msgid "Loading…" +msgstr "読ã¿è¾¼ã¿ä¸­â€¦" + +msgid "No connections" +msgstr "接続ãªã—" + +msgid "pkts" +msgstr "パケット" + +msgid "Failed to load" +msgstr "読ã¿è¾¼ã¿å¤±æ•—" + +msgid "Connection Details" +msgstr "接続詳細" + +msgid "Details" +msgstr "詳細" + +msgid "Orig Src" +msgstr "é€ä¿¡å…ƒ" + +msgid "Orig Dst" +msgstr "é€ä¿¡å…ˆ" + +msgid "Repl Src" +msgstr "応答元" + +msgid "Repl Dst" +msgstr "応答先" + +msgid "TC backend" +msgstr "TCãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "TCアタッãƒã®ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã‚’é¸æŠžã—ã¾ã™ã€‚推奨: 既定ã§ã¯autoを使用ã—ã€ã‚«ãƒ¼ãƒãƒ«>= 6.6ã§ã¯tcxを優先ã€å¤ã„カーãƒãƒ«ã§ã¯netlinkã®æ–¹ãŒå®‰å…¨ã§ã™ã€‚" + +msgid "TC order" +msgstr "TCé †åº" + +msgid "Netlink priority" +msgstr "Netlink優先度" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "backendãŒnetlinkã®å ´åˆã®ã¿ä½¿ç”¨ã—ã¾ã™ã€‚範囲: 0..65535(0ã¯æ—¢å®šï¼‰ã€‚" + +msgid "TCX ingress anchor program id" +msgstr "TCX ingressアンカープログラムID" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "tc_orderãŒbefore/afterã®ã¨ãã«ä½¿ç”¨ã—ã¾ã™ã€‚åŒã˜ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ä¸Šã®æœ‰åйãªingressプログラムIDã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +msgid "TCX egress anchor program id" +msgstr "TCX egressアンカープログラムID" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "tc_orderãŒbefore/afterã®ã¨ãã«ä½¿ç”¨ã—ã¾ã™ã€‚åŒã˜ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ã‚§ãƒ¼ã‚¹ä¸Šã®æœ‰åйãªegressプログラムIDã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" diff --git a/luci-app-bandix/po/pl/bandix.po b/luci-app-bandix/po/pl/bandix.po new file mode 100644 index 00000000..56e9d2db --- /dev/null +++ b/luci-app-bandix/po/pl/bandix.po @@ -0,0 +1,1257 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Monitor Ruchu Bandix" + +msgid "Loading data..." +msgstr "Åadowanie danych..." + +msgid "Unable to fetch data" +msgstr "Nie można pobrać danych" + +msgid "Unable to fetch history data" +msgstr "Nie można pobrać danych historycznych" + +msgid "Hostname" +msgstr "Nazwa hosta" + +msgid "IP Address" +msgstr "Adres IP" + +msgid "MAC Address" +msgstr "Adres MAC" + +msgid "Download Speed" +msgstr "PrÄ™dkość pobierania" + +msgid "Upload Speed" +msgstr "PrÄ™dkość wysyÅ‚ania" + +msgid "Total Download" +msgstr "CaÅ‚kowite pobranie" + +msgid "Total Upload" +msgstr "CaÅ‚kowite wysÅ‚anie" + +msgid "Download Limit" +msgstr "Limit pobierania" + +msgid "Upload Limit" +msgstr "Limit wysyÅ‚ania" + +msgid "Interface Language" +msgstr "JÄ™zyk interfejsu" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "Wybierz jÄ™zyk wyÅ›wietlania dla Monitora Ruchu Bandix" + +msgid "Device Info" +msgstr "Informacje o urzÄ…dzeniu" + +msgid "Device List" +msgstr "Lista urzÄ…dzeÅ„" + +msgid "LAN Traffic" +msgstr "Ruch LAN" + +msgid "WAN Traffic" +msgstr "Ruch WAN" + +msgid "Network Type" +msgstr "Typ Sieci" + +msgid "Rate Limit" +msgstr "Limit prÄ™dkoÅ›ci" + +msgid "Actions" +msgstr "Akcje" + +msgid "Online Devices" +msgstr "UrzÄ…dzenia online" + +msgid "WAN Only" +msgstr "Tylko WAN" + +msgid "Settings" +msgstr "Ustawienia" + +msgid "Device Settings" +msgstr "Ustawienia urzÄ…dzenia" + +msgid "Rate Limits" +msgstr "Limity prÄ™dkoÅ›ci" + +msgid "Remove Rate Limit" +msgstr "UsuÅ„ limit prÄ™dkoÅ›ci" + +msgid "Save" +msgstr "Zapisz" + +msgid "Cancel" +msgstr "Anuluj" + +msgid "Set Rate Limit" +msgstr "Ustaw limit prÄ™dkoÅ›ci" + +msgid "Device" +msgstr "UrzÄ…dzenie" + +msgid "Set Hostname" +msgstr "Ustaw nazwÄ™ hosta" + +msgid "Please enter hostname" +msgstr "ProszÄ™ wprowadzić nazwÄ™ hosta" + +msgid "Hostname set successfully" +msgstr "Nazwa hosta zostaÅ‚a ustawiona pomyÅ›lnie" + +msgid "Failed to set hostname" +msgstr "Nie udaÅ‚o siÄ™ ustawić nazwy hosta" + +msgid "Unlimited" +msgstr "Bez limitu" + +msgid "Settings saved successfully" +msgstr "Ustawienia zapisane pomyÅ›lnie" + +msgid "Failed to save settings" +msgstr "Nie udaÅ‚o siÄ™ zapisać ustawieÅ„" + +msgid "Please enter a valid speed value" +msgstr "ProszÄ™ wprowadzić prawidÅ‚owÄ… wartość prÄ™dkoÅ›ci" + +msgid "Speed value must be greater than 0" +msgstr "Wartość prÄ™dkoÅ›ci musi być wiÄ™ksza niż 0" + +msgid "Saving..." +msgstr "Zapisywanie..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "Ograniczenie prÄ™dkoÅ›ci dotyczy tylko ruchu WAN. Niektóre wewnÄ™trzne ruchu LAN mogÄ… nie być monitorowane z powodu przyspieszenia przełączania sprzÄ™towego." + +msgid "Tip: Enter 0 for unlimited" +msgstr "Wskazówka: Wprowadź 0 dla bez limitu" + +msgid "Traffic History" +msgstr "Historia ruchu" + +msgid "Realtime Traffic Trends" +msgstr "Trendy Ruchu w Czasie Rzeczywistym" + +msgid "Select Device" +msgstr "Wybierz urzÄ…dzenie" + +msgid "All Devices" +msgstr "Wszystkie urzÄ…dzenia" + +msgid "Time Range" +msgstr "Zakres czasu" + +msgid "Last 5 minutes" +msgstr "Ostatnie 5 minut" + +msgid "Last 30 minutes" +msgstr "Ostatnie 30 minut" + +msgid "Last 2 hours" +msgstr "Ostatnie 2 godziny" + +msgid "Type" +msgstr "Typ" + +msgid "Total" +msgstr "CaÅ‚kowity" + +msgid "LAN" +msgstr "Ruch LAN" + +msgid "WAN" +msgstr "Ruch WAN" + +msgid "Refresh" +msgstr "OdÅ›wież" + +msgid "Upload Rate" +msgstr "PrÄ™dkość wysyÅ‚ania" + +msgid "Download Rate" +msgstr "PrÄ™dkość pobierania" + +msgid "Last" +msgstr "Ostatni" + +msgid "second" +msgstr "sekunda" + +msgid "minute" +msgstr "minuta" + +msgid "hour" +msgstr "godzina" + +msgid "day" +msgstr "dzieÅ„" + +msgid "week" +msgstr "tydzieÅ„" + +msgid "Other Rates" +msgstr "Inne prÄ™dkoÅ›ci" + +msgid "Cumulative" +msgstr "Skumulowany" + +msgid "Total Uploaded" +msgstr "CaÅ‚kowite wysÅ‚ane" + +msgid "Total Downloaded" +msgstr "CaÅ‚kowite pobrane" + +msgid "LAN Uploaded" +msgstr "LAN wysÅ‚ane" + +msgid "LAN Downloaded" +msgstr "LAN pobrane" + +msgid "WAN Uploaded" +msgstr "WAN wysÅ‚ane" + +msgid "WAN Downloaded" +msgstr "WAN pobrane" + +msgid "Total Upload" +msgstr "CaÅ‚kowite wysyÅ‚anie" + +msgid "Total Download" +msgstr "CaÅ‚kowite pobieranie" + +msgid "LAN Upload" +msgstr "WysyÅ‚anie LAN" + +msgid "LAN Download" +msgstr "Pobieranie LAN" + +msgid "WAN Upload" +msgstr "WysyÅ‚anie WAN" + +msgid "WAN Download" +msgstr "Pobieranie WAN" + +msgid "Never Online" +msgstr "Nigdy online" + +msgid "Just Now" +msgstr "WÅ‚aÅ›nie teraz" + +msgid "min ago" +msgstr "min temu" + +msgid "h ago" +msgstr "godz. temu" + +msgid "days ago" +msgstr "dni temu" + +msgid "months ago" +msgstr "miesiÄ™cy temu" + +msgid "years ago" +msgstr "lat temu" + +msgid "Last Online" +msgstr "Ostatnio online" + +msgid "Zoom" +msgstr "PowiÄ™ksz" + +msgid "Sort By" +msgstr "Sortuj wedÅ‚ug" + +msgid "Online Status" +msgstr "Status online" + +msgid "Total Traffic" +msgstr "CaÅ‚kowity ruch" + +msgid "Ascending" +msgstr "RosnÄ…co" + +msgid "Descending" +msgstr "MalejÄ…co" + +msgid "Sort by Speed" +msgstr "Sortuj wedÅ‚ug prÄ™dkoÅ›ci" + +msgid "Sort by Traffic" +msgstr "Sortuj wedÅ‚ug ruchu" + +msgid "Simple Mode" +msgstr "Tryb prosty" + +msgid "Detailed Mode" +msgstr "Tryb szczegółowy" + +msgid "Bandix DNS Monitor" +msgstr "Monitor DNS Bandix" + +msgid "DNS Monitor" +msgstr "Monitor DNS" + +msgid "DNS Query Records" +msgstr "Rekordy zapytaÅ„ DNS" + +msgid "DNS Statistics" +msgstr "Statystyki DNS" + +msgid "DNS Monitoring Disabled" +msgstr "Monitorowanie DNS wyłączone" + +msgid "Please enable DNS monitoring in settings" +msgstr "ProszÄ™ włączyć monitorowanie DNS w ustawieniach" + +msgid "Go to Settings" +msgstr "Przejdź do ustawieÅ„" + +msgid "No Data" +msgstr "Brak danych" + +msgid "Time" +msgstr "Czas" + +msgid "Domain" +msgstr "Domena" + +msgid "Query Type" +msgstr "Typ zapytania" + +msgid "Response Code" +msgstr "Kod odpowiedzi" + +msgid "Response Time" +msgstr "Czas odpowiedzi" + +msgid "Source IP" +msgstr "IP źródÅ‚owe" + +msgid "Destination IP" +msgstr "IP docelowe" + +msgid "Response IPs" +msgstr "IP odpowiedzi" + +msgid "Response Result" +msgstr "Wynik odpowiedzi" + +msgid "DNS Server" +msgstr "Serwer DNS" + +msgid "Query" +msgstr "Zapytanie" + +msgid "Response" +msgstr "Odpowiedź" + +msgid "Filter" +msgstr "Filtr" + +msgid "Domain Filter" +msgstr "Filtr domeny" + +msgid "Device Filter" +msgstr "Filtr urzÄ…dzenia" + +msgid "DNS Server Filter" +msgstr "Filtr serwera DNS" + +msgid "Type Filter" +msgstr "Filtr typu" + +msgid "All" +msgstr "Wszystkie" + +msgid "Period" +msgstr "Okres" + +msgid "Display Mode" +msgstr "Tryb WyÅ›wietlania" + +msgid "This Year" +msgstr "Ten Rok" + +msgid "Week" +msgstr "Ten TydzieÅ„" + +msgid "Month" +msgstr "Ten MiesiÄ…c" + +msgid "Year" +msgstr "Ten Rok" + +msgid "Queries Only" +msgstr "Tylko zapytania" + +msgid "Responses Only" +msgstr "Tylko odpowiedzi" + +msgid "Search" +msgstr "Szukaj" + +msgid "Search Domain" +msgstr "Szukaj domeny" + +msgid "Search Device" +msgstr "Szukaj urzÄ…dzenia" + +msgid "Search DNS Server" +msgstr "Szukaj serwera DNS" + +msgid "Clear" +msgstr "Wyczyść" + +msgid "Previous" +msgstr "Poprzednia" + +msgid "Next" +msgstr "NastÄ™pna" + +msgid "Page" +msgstr "Strona" + +msgid "of" +msgstr "z" + +msgid "Total" +msgstr "CaÅ‚kowity" + +msgid "records" +msgstr "rekordów" + +msgid "Per Page" +msgstr "Na stronÄ™" + +msgid "" +msgstr "" + +msgid "Total Queries" +msgstr "CaÅ‚kowite zapytania" + +msgid "Total Responses" +msgstr "CaÅ‚kowite odpowiedzi" + +msgid "Queries with Response" +msgstr "Zapytania z odpowiedziÄ…" + +msgid "Queries without Response" +msgstr "Zapytania bez odpowiedzi" + +msgid "Avg Response Time" +msgstr "Åšredni czas odpowiedzi" + +msgid "Min Response Time" +msgstr "Minimalny czas odpowiedzi" + +msgid "Max Response Time" +msgstr "Maksymalny czas odpowiedzi" + +msgid "Success Rate" +msgstr "Wskaźnik sukcesu" + +msgid "Success" +msgstr "Sukces" + +msgid "Failure" +msgstr "Niepowodzenie" + +msgid "Top Domains" +msgstr "Najpopularniejsze domeny" + +msgid "Top Query Types" +msgstr "Najpopularniejsze typy zapytaÅ„" + +msgid "Top Devices" +msgstr "Najpopularniejsze urzÄ…dzenia" + +msgid "Top DNS Servers" +msgstr "Najpopularniejsze serwery DNS" + +msgid "Unique Devices" +msgstr "Unikalne urzÄ…dzenia" + +msgid "ms" +msgstr "ms" + +msgid "minutes" +msgstr "minut" + +msgid "Unknown Device" +msgstr "Nieznane urzÄ…dzenie" + +msgid "Domain not found" +msgstr "Domena nie znaleziona" + +msgid "Server error" +msgstr "Błąd serwera" + +msgid "Format error" +msgstr "Błąd formatu" + +msgid "Refused" +msgstr "Odrzucone" + +msgid "Other" +msgstr "Inne" + +msgid "Does not include DoH and DoT" +msgstr "Nie obejmuje DoH i DoT" + +msgid "Latest Response Time" +msgstr "Najnowszy czas odpowiedzi" + +msgid "Response Code Distribution" +msgstr "RozkÅ‚ad kodów odpowiedzi" + +msgid "Response Time Percentiles" +msgstr "Percentyle czasu odpowiedzi" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Monitor PołączeÅ„ Bandix" + +msgid "Connection Monitor" +msgstr "Monitor połączeÅ„" + +msgid "Device Connection Statistics" +msgstr "Statystyki połączeÅ„ urzÄ…dzeÅ„" + +msgid "Global Connection Statistics" +msgstr "Globalne statystyki połączeÅ„" + +msgid "Active TCP" +msgstr "Aktywne TCP" + +msgid "Active UDP" +msgstr "Aktywne UDP" + +msgid "Closed TCP" +msgstr "ZamkniÄ™te TCP" + +msgid "Total Connections" +msgstr "CaÅ‚kowite połączenia" + +msgid "Last Updated" +msgstr "Ostatnia aktualizacja" + +msgid "TCP Connections" +msgstr "Połączenia TCP" + +msgid "UDP Connections" +msgstr "Połączenia UDP" + +msgid "Established TCP" +msgstr "Ustanowione TCP" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "CaÅ‚kowite urzÄ…dzenia" + +msgid "Connection Monitor Disabled" +msgstr "Monitor połączeÅ„ wyłączony" + +msgid "Please enable connection monitoring in settings" +msgstr "ProszÄ™ włączyć monitorowanie połączeÅ„ w ustawieniach" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "Lista pokazuje tylko połączenia urzÄ…dzeÅ„ LAN, dane mogÄ… różnić siÄ™ od caÅ‚kowitych połączeÅ„." + +msgid "TCP Status Details" +msgstr "Szczegóły statusu TCP" + +msgid "Basic Settings" +msgstr "Ustawienia podstawowe" + +msgid "Traffic Monitor Settings" +msgstr "Ustawienia monitora ruchu" + +msgid "Connection Monitor Settings" +msgstr "Ustawienia monitora połączeÅ„" + +msgid "DNS Monitor Settings" +msgstr "Ustawienia monitora DNS" + +msgid "Bandix Basic Configuration" +msgstr "Podstawowa konfiguracja Bandix" + +msgid "Configure basic parameters for Bandix service" +msgstr "Skonfiguruj podstawowe parametry dla usÅ‚ugi Bandix" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "Konfiguracja Monitora Ruchu Bandix" + +msgid "Configure traffic monitoring related parameters" +msgstr "Skonfiguruj parametry zwiÄ…zane z monitorowaniem ruchu" + +msgid "Bandix Connection Monitor Configuration" +msgstr "Konfiguracja Monitora PołączeÅ„ Bandix" + +msgid "Configure connection monitoring related parameters" +msgstr "Skonfiguruj parametry zwiÄ…zane z monitorowaniem połączeÅ„" + +msgid "Bandix DNS Monitor Configuration" +msgstr "Konfiguracja Monitora DNS Bandix" + +msgid "Configure DNS monitoring related parameters" +msgstr "Skonfiguruj parametry zwiÄ…zane z monitorowaniem DNS" + +msgid "Enable" +msgstr "Włącz" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "Włącz usÅ‚ugÄ™ Monitora Ruchu Bandix" + +msgid "Enable Traffic Monitoring" +msgstr "Włącz monitorowanie ruchu" + +msgid "Enable Connection Monitoring" +msgstr "Włącz monitorowanie połączeÅ„" + +msgid "Enable DNS Monitoring" +msgstr "Włącz monitorowanie DNS" + +msgid "Simplified Chinese" +msgstr "ChiÅ„ski uproszczony" + +msgid "Traditional Chinese" +msgstr "ChiÅ„ski tradycyjny" + +msgid "Port" +msgstr "Port" + +msgid "Port for Bandix service to listen on" +msgstr "Port, na którym usÅ‚uga Bandix nasÅ‚uchuje" + +msgid "TC Priority" +msgstr "Priorytet TC" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "Ustaw priorytet filtra TC, aby lepiej współistnieć z innymi programami eBPF TC. Mniejsze liczby oznaczajÄ… wyższy priorytet. 0 oznacza przypisane przez system." + +msgid "Monitor Interface" +msgstr "Interfejs monitora" + +msgid "Select the LAN network interface to monitor" +msgstr "Wybierz interfejs sieci LAN do monitorowania" + +msgid "Speed Units" +msgstr "Jednostki prÄ™dkoÅ›ci" + +msgid "Select the speed display unit format" +msgstr "Wybierz format jednostki wyÅ›wietlania prÄ™dkoÅ›ci" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "Jednostki bajtów (B/s, KB/s, MB/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "Jednostki bitów (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "Motyw interfejsu" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "Wybierz motyw wyÅ›wietlania dla Monitora Ruchu Bandix" + +msgid "Follow System" +msgstr "Zgodnie z systemem" + +msgid "Light Mode" +msgstr "Tryb jasny" + +msgid "Dark Mode" +msgstr "Tryb ciemny" + +msgid "Feedback" +msgstr "Opinie" + +msgid "Log Level" +msgstr "Poziom logowania" + +msgid "Set the log level for Bandix service" +msgstr "Ustaw poziom logowania dla usÅ‚ugi Bandix" + +msgid "Offline Timeout" +msgstr "Limit czasu offline" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "Ustaw limit czasu wykrywania urzÄ…dzeÅ„ offline (sekundy). UrzÄ…dzenia nieaktywne dÅ‚użej niż ten czas zostanÄ… oznaczone jako offline" + +msgid "Realtime Traffic Period" +msgstr "Okres ruchu w czasie rzeczywistym" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "InterwaÅ‚ 10 minut używa okoÅ‚o 60 KB na urzÄ…dzenie" + +msgid "Data Flush Interval" +msgstr "InterwaÅ‚ zapisu danych" + +msgid "Set the interval for flushing data to disk" +msgstr "Ustaw interwaÅ‚ zapisu danych na dysk" + +msgid "1 minute" +msgstr "1 minuta" + +msgid "5 minutes" +msgstr "5 minut" + +msgid "10 minutes" +msgstr "10 minut" + +msgid "15 minutes" +msgstr "15 minut" + +msgid "20 minutes" +msgstr "20 minut" + +msgid "25 minutes" +msgstr "25 minut" + +msgid "30 minutes" +msgstr "30 minut" + +msgid "1 hour" +msgstr "1 godzina" + +msgid "2 hours" +msgstr "2 godziny" + +msgid "12 hours" +msgstr "12 godzin" + +msgid "24 hours" +msgstr "24 godziny" + +msgid "Data Directory" +msgstr "Katalog danych" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "JeÅ›li zmienisz katalog, proszÄ™ dodać go rÄ™cznie do katalogu kopii zapasowej" + +msgid "Bandix data storage directory" +msgstr "Katalog przechowywania danych Bandix" + +msgid "Enable Bandix connection monitoring" +msgstr "Włącz monitorowanie połączeÅ„ Bandix" + +msgid "Enable Bandix DNS monitoring" +msgstr "Włącz monitorowanie DNS Bandix" + +msgid "DNS Max Records" +msgstr "Maksymalna liczba rekordów DNS" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "Ustaw maksymalnÄ… liczbÄ™ rekordów zapytaÅ„ DNS do przechowania. Starsze rekordy zostanÄ… usuniÄ™te po przekroczeniu tego limitu" + +msgid "Persist DNS Data" +msgstr "Zachowaj dane DNS" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Włącz funkcjÄ™ trwaÅ‚oÅ›ci danych DNS, dane bÄ™dÄ… zapisywane na dysk tylko gdy ta opcja jest włączona" + +msgid "DNS Data Flush Interval" +msgstr "InterwaÅ‚ zapisu danych DNS" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "Ustaw interwaÅ‚ zapisywania danych DNS na dysk" + +msgid "Persist History Data" +msgstr "Zachowaj dane historyczne" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Włącz funkcjÄ™ trwaÅ‚oÅ›ci danych, dane bÄ™dÄ… zapisywane na dysk tylko gdy ta opcja jest włączona" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "Nie zajmuje miejsca na dysku, przechowywane tylko w pamiÄ™ci" + +msgid "Query & Response" +msgstr "Zapytanie i Odpowiedź" + +msgid "Queries" +msgstr "Zapytania" + +msgid "Responses" +msgstr "Odpowiedzi" + +msgid "Average Response Time" +msgstr "Åšredni Czas Odpowiedzi" + +msgid "Show More" +msgstr "Pokaż wiÄ™cej" + +msgid "Show Less" +msgstr "Pokaż mniej" + +msgid "Add Schedule Rule" +msgstr "Dodaj regułę limitu czasu" + +msgid "Add Rule" +msgstr "Dodaj regułę" + +msgid "Set rate limit rules for different time periods" +msgstr "Ustaw reguÅ‚y limitu dla różnych okresów czasu" + +msgid "Time Slot" +msgstr "PrzedziaÅ‚ czasowy" + +msgid "Days of Week" +msgstr "Dni tygodnia" + +msgid "Mon" +msgstr "Pon" + +msgid "Tue" +msgstr "Wt" + +msgid "Wed" +msgstr "Åšr" + +msgid "Thu" +msgstr "Czw" + +msgid "Fri" +msgstr "Pt" + +msgid "Sat" +msgstr "Sob" + +msgid "Sun" +msgstr "Nie" + +msgid "Adding..." +msgstr "Dodawanie..." + +msgid "Failed to add schedule rule: " +msgstr "Nie udaÅ‚o siÄ™ dodać reguÅ‚y limitu czasu: " + +msgid "Please set time slot" +msgstr "ProszÄ™ ustawić przedziaÅ‚ czasowy" + +msgid "Please select at least one day" +msgstr "ProszÄ™ wybrać co najmniej jeden dzieÅ„" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "Brak jeszcze reguÅ‚ limitu czasu, kliknij \"Dodaj regułę\", aby rozpocząć" + +msgid "Loading..." +msgstr "Åadowanie..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "Åadowanie fragmentami, proszÄ™ czekać... (%d/%d)" + +msgid "No schedule rules" +msgstr "Brak reguÅ‚ limitu czasu" + +msgid "Failed to load schedule rules" +msgstr "Nie udaÅ‚o siÄ™ zaÅ‚adować reguÅ‚ limitu czasu" + +msgid "Delete Schedule Rule" +msgstr "UsuÅ„ regułę limitu czasu" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "Czy na pewno chcesz usunąć tÄ™ regułę limitu czasu?" + +msgid "Failed to delete schedule rule" +msgstr "Nie udaÅ‚o siÄ™ usunąć reguÅ‚y limitu czasu" + +msgid "Delete Device" +msgstr "UsuÅ„ urzÄ…dzenie" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "Czy na pewno chcesz usunąć to urzÄ…dzenie? Historia ruchu zostanie usuniÄ™ta." + +msgid "Failed to delete device" +msgstr "Nie udaÅ‚o siÄ™ usunąć urzÄ…dzenia" + +msgid "Confirm" +msgstr "Potwierdź" + +msgid "Close" +msgstr "Zamknij" + +msgid "rule" +msgstr "reguÅ‚a" + +msgid "rules" +msgstr "reguÅ‚y" + +msgid "more" +msgstr "wiÄ™cej" + +msgid "No active rule" +msgstr "Brak aktywnej reguÅ‚y" + +msgid "Schedule Rules" +msgstr "ReguÅ‚y limitu czasu" + +msgid "Upload Statistics" +msgstr "Statystyki wysyÅ‚ania" + +msgid "Download Statistics" +msgstr "Statystyki pobierania" + +msgid "Cumulative Traffic" +msgstr "Skumulowany ruch" + +msgid "Daily" +msgstr "Dzienny" + +msgid "Weekly" +msgstr "Tygodniowy" + +msgid "Monthly" +msgstr "MiesiÄ™czny" + +msgid "Statistics" +msgstr "Statystyki" + +msgid "Average" +msgstr "Åšrednia" + +msgid "Maximum" +msgstr "Maksimum" + +msgid "Minimum" +msgstr "Minimum" + +msgid "WAN Upload" +msgstr "WysyÅ‚anie WAN" + +msgid "WAN Download" +msgstr "Pobieranie WAN" + +msgid "WAN Uploaded" +msgstr "WysÅ‚ano WAN" + +msgid "WAN Downloaded" +msgstr "Pobrano WAN" + +msgid "Clear Traffic Data" +msgstr "Wyczyść dane ruchu" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "Czy na pewno chcesz wyczyÅ›cić wszystkie dane ruchu? Tej operacji nie można cofnąć." + +msgid "Failed to clear traffic data: " +msgstr "Nie udaÅ‚o siÄ™ wyczyÅ›cić danych ruchu: " + +msgid "Restart Service" +msgstr "Uruchom ponownie usÅ‚ugÄ™" + +msgid "Restart Bandix Service" +msgstr "Uruchom ponownie usÅ‚ugÄ™ Bandix" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "Czy na pewno chcesz uruchomić ponownie usÅ‚ugÄ™ Bandix?" + +msgid "Failed to restart service: " +msgstr "Nie udaÅ‚o siÄ™ uruchomić ponownie usÅ‚ugi: " + +msgid "Realtime" +msgstr "Czas rzeczywisty" + +msgid "Last 24 Hours" +msgstr "Ostatnie 24 godziny" + +msgid "Last 7 Days" +msgstr "Ostatnie 7 dni" + +msgid "Last 30 Days" +msgstr "Ostatnie 30 dni" + +msgid "Last 10 Minutes" +msgstr "Ostatnie 10 minut" + +msgid "Last 15 Minutes" +msgstr "Ostatnie 15 minut" + +msgid "Last 30 Minutes" +msgstr "Ostatnie 30 minut" + +msgid "Last 1 Hour" +msgstr "Ostatnia 1 godzina" + +msgid "Starting installation..." +msgstr "Rozpoczynanie instalacji..." + +msgid "Page will refresh in 3 seconds." +msgstr "Strona odÅ›wieży siÄ™ za 3 sekundy." + +msgid "Installation failed" +msgstr "Instalacja nie powiodÅ‚a siÄ™" + +msgid "Installation failed at step: " +msgstr "Instalacja nie powiodÅ‚a siÄ™ w kroku: " + +msgid "Details: " +msgstr "Szczegóły: " + +msgid "Installation failed: " +msgstr "Instalacja nie powiodÅ‚a siÄ™: " + +msgid "Unknown error" +msgstr "Nieznany błąd" + +msgid "Service restarted successfully." +msgstr "UsÅ‚uga zostaÅ‚a pomyÅ›lnie uruchomiona ponownie." + +msgid "Service restart may have failed. Please check manually." +msgstr "Ponowne uruchomienie usÅ‚ugi mogÅ‚o siÄ™ nie powieść. Sprawdź rÄ™cznie." + +msgid "Please restart the service." +msgstr "ProszÄ™ ponownie uruchomić usÅ‚ugÄ™." + +msgid "LuCI App updated successfully!" +msgstr "Aplikacja LuCI zostaÅ‚a pomyÅ›lnie zaktualizowana!" + +msgid "Bandix updated successfully!" +msgstr "Bandix zostaÅ‚ pomyÅ›lnie zaktualizowany!" + +msgid "LuCI App has update: " +msgstr "Aplikacja LuCI ma aktualizacjÄ™: " + +msgid "Bandix has update: " +msgstr "Bandix ma aktualizacjÄ™: " + +msgid "LuCI App is up to date: " +msgstr "Aplikacja LuCI jest aktualna: " + +msgid "Bandix is up to date: " +msgstr "Bandix jest aktualny: " + +msgid "Updates Available" +msgstr "DostÄ™pne Aktualizacje" + +msgid "No Updates Available" +msgstr "Brak DostÄ™pnych Aktualizacji" + +msgid "Detected Architecture" +msgstr "Wykryta Architektura" + +msgid "Package Manager" +msgstr "Menedżer Pakietów" + +msgid "LuCI Assets" +msgstr "Zasoby LuCI" + +msgid "Bandix Assets" +msgstr "Zasoby Bandix" + +msgid "Failed to check for updates" +msgstr "Nie udaÅ‚o siÄ™ sprawdzić aktualizacji" + +msgid "Failed to check for updates: " +msgstr "Nie udaÅ‚o siÄ™ sprawdzić aktualizacji: " + +msgid "Checking..." +msgstr "Sprawdzanie..." + +msgid "Check for Updates" +msgstr "Sprawdź Aktualizacje" + +msgid "Installing..." +msgstr "Instalowanie..." + +msgid "Download and Install" +msgstr "Pobierz i Zainstaluj" + +msgid "Manual Download" +msgstr "Pobieranie RÄ™czne" + +msgid "Close" +msgstr "Zamknij" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "Rozpoczynanie instalacji... Strona odÅ›wieży siÄ™ automatycznie za 30 sekund." + +msgid "Please clear your browser cache manually after updating." +msgstr "Po aktualizacji należy rÄ™cznie wyczyÅ›cić pamięć podrÄ™cznÄ… przeglÄ…darki." + +msgid "Traffic Statistics" +msgstr "Statystyki ruchu" + +msgid "Traffic Statistics" +msgstr "Statystyki ruchu" + +msgid "Device Usage Ranking" +msgstr "Ranking Użycia UrzÄ…dzeÅ„" + +msgid "Start Date" +msgstr "Data PoczÄ…tkowa" + +msgid "End Date" +msgstr "Data KoÅ„cowa" + +msgid "Reset" +msgstr "Resetuj" + +msgid "Today" +msgstr "Dzisiaj" + +msgid "This Week" +msgstr "Ten TydzieÅ„" + +msgid "Last Week" +msgstr "ZeszÅ‚y TydzieÅ„" + +msgid "This Month" +msgstr "Ten MiesiÄ…c" + +msgid "Last Month" +msgstr "ZeszÅ‚y MiesiÄ…c" + +msgid "Last 90 Days" +msgstr "Ostatnie 90 Dni" + +msgid "Last Year" +msgstr "Ostatni Rok" + +msgid "Traffic Timeline" +msgstr "OÅ› Czasu Ruchu" + +msgid "Aggregation:" +msgstr "Agregacja:" + +msgid "Hourly" +msgstr "Co GodzinÄ™" + +msgid "Device:" +msgstr "UrzÄ…dzenie:" + +msgid "Traffic Push URL" +msgstr "Adres URL wysyÅ‚ania ruchu" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "WysyÅ‚aj dane ruchu do zdalnego punktu koÅ„cowego HTTP (POST JSON). Pozostaw puste, aby wyłączyć." + +msgid "Device Event Push URL" +msgstr "Adres URL wysyÅ‚ania zdarzeÅ„ urzÄ…dzenia" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "WysyÅ‚aj zdarzenia online/offline urzÄ…dzenia do zdalnego punktu koÅ„cowego HTTP (POST JSON przy zmianie stanu). Pozostaw puste, aby wyłączyć." + +msgid "Additional Subnets" +msgstr "Dodatkowe podsieci" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "Dodatkowe lokalne podsieci (notacja CIDR oddzielona przecinkami, np. '192.168.2.0/24,10.0.0.0/8'). Pozostaw puste, aby używać tylko podsieci interfejsu." + +msgid "Exclude Interface Device" +msgstr "Wyklucz urzÄ…dzenie interfejsu" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "Wyklucz sam router (urzÄ…dzenie interfejsu) ze statystyk ruchu" + +msgid "Enable Neighbor Flush" +msgstr "Włącz odÅ›wieżanie tabeli sÄ…siadów" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "Włącz okresowe odÅ›wieżanie danych tabeli sÄ…siadów. Ogólnie nie zalecane, jeÅ›li lista urzÄ…dzeÅ„ dziaÅ‚a prawidÅ‚owo." + +msgid "Neighbor Flush Interval" +msgstr "InterwaÅ‚ odÅ›wieżania tabeli sÄ…siadów" + +msgid "Set the interval for flushing neighbor table data" +msgstr "Ustaw interwaÅ‚ odÅ›wieżania danych tabeli sÄ…siadów" + +msgid "No devices" +msgstr "Brak urzÄ…dzeÅ„" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "Ruch LAN jest postrzegany z perspektywy caÅ‚ej podsieci, wiÄ™c przesyÅ‚anie i pobieranie sÄ… zawsze równe, tworzÄ…c zamkniÄ™tÄ… pÄ™tlÄ™. Ponadto, ze wzglÄ™du na obecność dedykowanych chipów przełączajÄ…cych sprzÄ™towych, ruch LAN miÄ™dzy 2 urzÄ…dzeniami (np. PC - NAS) w sieci lokalnej może nie być monitorowany." + +msgid "Protocol" +msgstr "Protokół" + +msgid "State" +msgstr "Stan" + +msgid "Send" +msgstr "WyÅ›lij" + +msgid "Reply" +msgstr "Odpowiedź" + +msgid "Flags" +msgstr "Flagi" + +msgid "Loading…" +msgstr "Åadowanie…" + +msgid "No connections" +msgstr "Brak połączeÅ„" + +msgid "pkts" +msgstr "pakiety" + +msgid "Failed to load" +msgstr "Błąd Å‚adowania" + +msgid "Connection Details" +msgstr "Szczegóły połączenia" + +msgid "Details" +msgstr "Szczegóły" + +msgid "Orig Src" +msgstr "ŹródÅ‚o orig." + +msgid "Orig Dst" +msgstr "Cel orig." + +msgid "Repl Src" +msgstr "ŹródÅ‚o odp." + +msgid "Repl Dst" +msgstr "Cel odp." + +msgid "TC backend" +msgstr "Backend TC" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "Wybierz backend podpiecia TC. Zalecenie: domyslnie uzyj auto; tcx jest preferowany na kernelu >= 6.6; netlink jest bezpieczniejszy na starszych kernelach." + +msgid "TC order" +msgstr "Kolejnosc TC" + +msgid "Netlink priority" +msgstr "Priorytet Netlink" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "Uzywane tylko, gdy backend to netlink. Zakres: 0..65535 (0 oznacza domyslny)." + +msgid "TCX ingress anchor program id" +msgstr "ID programu kotwicy TCX ingress" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "Uzywane, gdy tc_order to before/after. Musi to byc prawidlowe ID programu ingress na tym samym interfejsie." + +msgid "TCX egress anchor program id" +msgstr "ID programu kotwicy TCX egress" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "Uzywane, gdy tc_order to before/after. Musi to byc prawidlowe ID programu egress na tym samym interfejsie." diff --git a/luci-app-bandix/po/ru/bandix.po b/luci-app-bandix/po/ru/bandix.po new file mode 100644 index 00000000..32e835a9 --- /dev/null +++ b/luci-app-bandix/po/ru/bandix.po @@ -0,0 +1,1257 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Монитор трафика Bandix" + +msgid "Loading data..." +msgstr "Загрузка данных..." + +msgid "Unable to fetch data" +msgstr "Ðе удалоÑÑŒ получить данные" + +msgid "Unable to fetch history data" +msgstr "Ðе удалоÑÑŒ получить данные иÑтории" + +msgid "Hostname" +msgstr "Ð˜Ð¼Ñ Ñ…Ð¾Ñта" + +msgid "IP Address" +msgstr "IP-адреÑ" + +msgid "MAC Address" +msgstr "MAC-адреÑ" + +msgid "Download Speed" +msgstr "СкороÑть загрузки" + +msgid "Upload Speed" +msgstr "СкороÑть выгрузки" + +msgid "Total Download" +msgstr "Ð’Ñего загружено" + +msgid "Total Upload" +msgstr "Ð’Ñего выгружено" + +msgid "Download Limit" +msgstr "Ограничение загрузки" + +msgid "Upload Limit" +msgstr "Ограничение выгрузки" + +msgid "Interface Language" +msgstr "Язык интерфейÑа" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "Выберите Ñзык Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð° трафика Bandix" + +msgid "Device Info" +msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± уÑтройÑтве" + +msgid "Device List" +msgstr "СпиÑок уÑтройÑтв" + +msgid "LAN Traffic" +msgstr "Трафик LAN" + +msgid "WAN Traffic" +msgstr "Трафик WAN" + +msgid "Network Type" +msgstr "Тип Сети" + +msgid "Rate Limit" +msgstr "Ограничение ÑкороÑти" + +msgid "Actions" +msgstr "ДейÑтвиÑ" + +msgid "Online Devices" +msgstr "УÑтройÑтва в Ñети" + +msgid "WAN Only" +msgstr "Только WAN" + +msgid "Settings" +msgstr "ÐаÑтройки" + +msgid "Device Settings" +msgstr "ÐаÑтройки уÑтройÑтва" + +msgid "Rate Limits" +msgstr "ÐаÑтройки ограничениÑ" + +msgid "Remove Rate Limit" +msgstr "СнÑть ограничение" + +msgid "Save" +msgstr "Сохранить" + +msgid "Cancel" +msgstr "Отмена" + +msgid "Set Rate Limit" +msgstr "УÑтановить ограничение" + +msgid "Device" +msgstr "УÑтройÑтво" + +msgid "Set Hostname" +msgstr "УÑтановить Ð¸Ð¼Ñ Ñ…Ð¾Ñта" + +msgid "Please enter hostname" +msgstr "Введите Ð¸Ð¼Ñ Ñ…Ð¾Ñта" + +msgid "Hostname set successfully" +msgstr "Ð˜Ð¼Ñ Ñ…Ð¾Ñта уÑпешно уÑтановлено" + +msgid "Failed to set hostname" +msgstr "Ðе удалоÑÑŒ уÑтановить Ð¸Ð¼Ñ Ñ…Ð¾Ñта" + +msgid "Unlimited" +msgstr "Без ограничений" + +msgid "Settings saved successfully" +msgstr "ÐаÑтройки уÑпешно Ñохранены" + +msgid "Failed to save settings" +msgstr "Ðе удалоÑÑŒ Ñохранить наÑтройки" + +msgid "Please enter a valid speed value" +msgstr "Введите допуÑтимое значение ÑкороÑти" + +msgid "Speed value must be greater than 0" +msgstr "СкороÑть должна быть больше 0" + +msgid "Saving..." +msgstr "Сохранение..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "Ограничение ÑкороÑти применÑетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ к трафику WAN. Ðекоторые внутренние трафики LAN могут не отÑлеживатьÑÑ Ð¸Ð·-за аппаратного уÑÐºÐ¾Ñ€ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¼ÑƒÑ‚Ð°Ñ†Ð¸Ð¸." + +msgid "Tip: Enter 0 for unlimited" +msgstr "ПодÑказка: введите 0 Ð´Ð»Ñ Ð±ÐµÐ· ограничений" + +msgid "Traffic History" +msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ°" + +msgid "Realtime Traffic Trends" +msgstr "Тренды Трафика в Реальном Времени" + +msgid "Select Device" +msgstr "Выбрать уÑтройÑтво" + +msgid "All Devices" +msgstr "Ð’Ñе уÑтройÑтва" + +msgid "Time Range" +msgstr "Временной диапазон" + +msgid "Last 5 minutes" +msgstr "ПоÑледние 5 минут" + +msgid "Last 30 minutes" +msgstr "ПоÑледние 30 минут" + +msgid "Last 2 hours" +msgstr "ПоÑледние 2 чаÑа" + +msgid "Type" +msgstr "Тип" + +msgid "Total" +msgstr "Ð’Ñего" + +msgid "LAN" +msgstr "Трафик LAN" + +msgid "WAN" +msgstr "Трафик WAN" + +msgid "Refresh" +msgstr "Обновить" + +msgid "Upload Rate" +msgstr "СкороÑть выгрузки" + +msgid "Download Rate" +msgstr "СкороÑть загрузки" + +msgid "Last" +msgstr "ПоÑледний" + +msgid "second" +msgstr "Ñекунда" + +msgid "minute" +msgstr "минута" + +msgid "hour" +msgstr "чаÑ" + +msgid "day" +msgstr "день" + +msgid "week" +msgstr "неделÑ" + +msgid "Other Rates" +msgstr "Другие ÑкороÑти" + +msgid "Cumulative" +msgstr "Ðакопительный трафик" + +msgid "Total Uploaded" +msgstr "Ð’Ñего отправлено" + +msgid "Total Downloaded" +msgstr "Ð’Ñего загружено" + +msgid "LAN Uploaded" +msgstr "LAN отправлено" + +msgid "LAN Downloaded" +msgstr "LAN загружено" + +msgid "WAN Uploaded" +msgstr "WAN отправлено" + +msgid "WAN Downloaded" +msgstr "WAN загружено" + +msgid "Total Upload" +msgstr "Ð’Ñего выгружено" + +msgid "Total Download" +msgstr "Ð’Ñего загружено" + +msgid "LAN Upload" +msgstr "СкороÑть отправки LAN" + +msgid "LAN Download" +msgstr "СкороÑть загрузки LAN" + +msgid "WAN Upload" +msgstr "СкороÑть отправки WAN" + +msgid "WAN Download" +msgstr "СкороÑть загрузки WAN" + +msgid "Never Online" +msgstr "Ðикогда не был в Ñети" + +msgid "Just Now" +msgstr "Только что" + +msgid "min ago" +msgstr "мин назад" + +msgid "h ago" +msgstr "ч назад" + +msgid "days ago" +msgstr "дн назад" + +msgid "months ago" +msgstr "Ð¼ÐµÑ Ð½Ð°Ð·Ð°Ð´" + +msgid "years ago" +msgstr "лет назад" + +msgid "Last Online" +msgstr "ПоÑледний раз в Ñети" + +msgid "Zoom" +msgstr "МаÑштаб" + +msgid "Sort By" +msgstr "Сортировать по" + +msgid "Online Status" +msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð² Ñети" + +msgid "Total Traffic" +msgstr "Ð’Ñего трафика" + +msgid "Ascending" +msgstr "По возраÑтанию" + +msgid "Descending" +msgstr "По убыванию" + +msgid "Sort by Speed" +msgstr "Сортировать по ÑкороÑти" + +msgid "Sort by Traffic" +msgstr "Сортировать по трафику" + +msgid "Simple Mode" +msgstr "ПроÑтой режим" + +msgid "Detailed Mode" +msgstr "Подробный режим" + +msgid "Bandix DNS Monitor" +msgstr "Монитор DNS Bandix" + +msgid "DNS Monitor" +msgstr "Монитор DNS" + +msgid "DNS Query Records" +msgstr "ЗапиÑи запроÑов DNS" + +msgid "DNS Statistics" +msgstr "СтатиÑтика DNS" + +msgid "DNS Monitoring Disabled" +msgstr "Мониторинг DNS отключён" + +msgid "Please enable DNS monitoring in settings" +msgstr "Включите мониторинг DNS в наÑтройках" + +msgid "Go to Settings" +msgstr "Перейти в наÑтройки" + +msgid "No Data" +msgstr "Ðет данных" + +msgid "Time" +msgstr "ВремÑ" + +msgid "Domain" +msgstr "Домен" + +msgid "Query Type" +msgstr "Тип запроÑа" + +msgid "Response Code" +msgstr "Код ответа" + +msgid "Response Time" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ÐºÐ»Ð¸ÐºÐ°" + +msgid "Source IP" +msgstr "IP иÑточника" + +msgid "Destination IP" +msgstr "IP назначениÑ" + +msgid "Response IPs" +msgstr "IP ответа" + +msgid "Response Result" +msgstr "Результат ответа" + +msgid "DNS Server" +msgstr "DNS-Ñервер" + +msgid "Query" +msgstr "ЗапроÑ" + +msgid "Response" +msgstr "Ответ" + +msgid "Filter" +msgstr "Фильтр" + +msgid "Domain Filter" +msgstr "Фильтр домена" + +msgid "Device Filter" +msgstr "Фильтр уÑтройÑтва" + +msgid "DNS Server Filter" +msgstr "Фильтр DNS-Ñервера" + +msgid "Type Filter" +msgstr "Фильтр типа" + +msgid "All" +msgstr "Ð’Ñе" + +msgid "Period" +msgstr "Период" + +msgid "Display Mode" +msgstr "Режим ОтображениÑ" + +msgid "This Year" +msgstr "Этот Год" + +msgid "Week" +msgstr "Эта ÐеделÑ" + +msgid "Month" +msgstr "Этот МеÑÑц" + +msgid "Year" +msgstr "Этот Год" + +msgid "Queries Only" +msgstr "Только запроÑÑ‹" + +msgid "Responses Only" +msgstr "Только ответы" + +msgid "Search" +msgstr "ПоиÑк" + +msgid "Search Domain" +msgstr "ПоиÑк домена" + +msgid "Search Device" +msgstr "ПоиÑк уÑтройÑтва" + +msgid "Search DNS Server" +msgstr "ПоиÑк DNS-Ñервера" + +msgid "Clear" +msgstr "ОчиÑтить" + +msgid "Previous" +msgstr "ПредыдущаÑ" + +msgid "Next" +msgstr "СледующаÑ" + +msgid "Page" +msgstr "Страница" + +msgid "of" +msgstr "из" + +msgid "Total" +msgstr "Ð’Ñего" + +msgid "records" +msgstr "запиÑей" + +msgid "Per Page" +msgstr "Ðа Ñтранице" + +msgid "" +msgstr "" + +msgid "Total Queries" +msgstr "Ð’Ñего запроÑов" + +msgid "Total Responses" +msgstr "Ð’Ñего ответов" + +msgid "Queries with Response" +msgstr "ЗапроÑÑ‹ Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð¾Ð¼" + +msgid "Queries without Response" +msgstr "ЗапроÑÑ‹ без ответа" + +msgid "Avg Response Time" +msgstr "Среднее Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð°" + +msgid "Min Response Time" +msgstr "Минимальное Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð°" + +msgid "Max Response Time" +msgstr "МакÑимальное Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð°" + +msgid "Success Rate" +msgstr "Процент уÑпеха" + +msgid "Success" +msgstr "УÑпешно" + +msgid "Failure" +msgstr "Ошибка" + +msgid "Top Domains" +msgstr "Самые запрашиваемые домены" + +msgid "Top Query Types" +msgstr "Самые чаÑтые типы запроÑов" + +msgid "Top Devices" +msgstr "Самые активные уÑтройÑтва" + +msgid "Top DNS Servers" +msgstr "Самые чаÑтые DNS-Ñерверы" + +msgid "Unique Devices" +msgstr "Уникальных уÑтройÑтв" + +msgid "ms" +msgstr "мÑ" + +msgid "minutes" +msgstr "минут" + +msgid "Unknown Device" +msgstr "ÐеизвеÑтное уÑтройÑтво" + +msgid "Domain not found" +msgstr "Домен не найден" + +msgid "Server error" +msgstr "Ошибка Ñервера" + +msgid "Format error" +msgstr "Ошибка формата" + +msgid "Refused" +msgstr "Отказ" + +msgid "Other" +msgstr "Другое" + +msgid "Does not include DoH and DoT" +msgstr "Ðе включает DoH и DoT" + +msgid "Latest Response Time" +msgstr "ПоÑледнее Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð°" + +msgid "Response Code Distribution" +msgstr "РаÑпределение кодов ответа" + +msgid "Response Time Percentiles" +msgstr "Перцентили времени ответа" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Монитор Ñоединений Bandix" + +msgid "Connection Monitor" +msgstr "Монитор Ñоединений" + +msgid "Device Connection Statistics" +msgstr "СтатиÑтика Ñоединений по уÑтройÑтвам" + +msgid "Global Connection Statistics" +msgstr "ÐžÐ±Ñ‰Ð°Ñ ÑтатиÑтика Ñоединений" + +msgid "Active TCP" +msgstr "Ðктивный TCP" + +msgid "Active UDP" +msgstr "Ðктивный UDP" + +msgid "Closed TCP" +msgstr "Закрытый TCP" + +msgid "Total Connections" +msgstr "Ð’Ñего Ñоединений" + +msgid "Last Updated" +msgstr "ПоÑледнее обновление" + +msgid "TCP Connections" +msgstr "Ð¡Ð¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ TCP" + +msgid "UDP Connections" +msgstr "Ð¡Ð¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ UDP" + +msgid "Established TCP" +msgstr "УÑтановленный TCP" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "Ð’Ñего уÑтройÑтв" + +msgid "Connection Monitor Disabled" +msgstr "Мониторинг Ñоединений отключён" + +msgid "Please enable connection monitoring in settings" +msgstr "Включите мониторинг Ñоединений в наÑтройках" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "СпиÑок показывает только ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑƒÑтройÑтв LAN, данные могут отличатьÑÑ Ð¾Ñ‚ общего чиÑла Ñоединений." + +msgid "TCP Status Details" +msgstr "ПодробноÑти ÑтатуÑа TCP" + +msgid "Basic Settings" +msgstr "ОÑновные наÑтройки" + +msgid "Traffic Monitor Settings" +msgstr "ÐаÑтройки монитора трафика" + +msgid "Connection Monitor Settings" +msgstr "ÐаÑтройки монитора Ñоединений" + +msgid "DNS Monitor Settings" +msgstr "ÐаÑтройки монитора DNS" + +msgid "Bandix Basic Configuration" +msgstr "Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Bandix" + +msgid "Configure basic parameters for Bandix service" +msgstr "ÐаÑтройка базовых параметров Ñлужбы Bandix" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð° трафика Bandix" + +msgid "Configure traffic monitoring related parameters" +msgstr "ÐаÑтройка параметров мониторинга трафика" + +msgid "Bandix Connection Monitor Configuration" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð° Ñоединений Bandix" + +msgid "Configure connection monitoring related parameters" +msgstr "ÐаÑтройка параметров мониторинга Ñоединений" + +msgid "Bandix DNS Monitor Configuration" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð° DNS Bandix" + +msgid "Configure DNS monitoring related parameters" +msgstr "ÐаÑтройка параметров мониторинга DNS" + +msgid "Enable" +msgstr "Включить" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "Включить Ñлужбу мониторинга трафика Bandix" + +msgid "Enable Traffic Monitoring" +msgstr "Включить мониторинг трафика" + +msgid "Enable Connection Monitoring" +msgstr "Включить мониторинг Ñоединений" + +msgid "Enable DNS Monitoring" +msgstr "Включить мониторинг DNS" + +msgid "Simplified Chinese" +msgstr "КитайÑкий упрощённый" + +msgid "Traditional Chinese" +msgstr "КитайÑкий традиционный" + +msgid "Port" +msgstr "Порт" + +msgid "Port for Bandix service to listen on" +msgstr "Порт, на котором проÑлушивает Ñлужба Bandix" + +msgid "TC Priority" +msgstr "Приоритет TC" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "УÑтановите приоритет фильтра TC Ð´Ð»Ñ Ð»ÑƒÑ‡ÑˆÐµÐ³Ð¾ ÑоÑущеÑÑ‚Ð²Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ программами eBPF TC. Меньшие чиÑла указывают на более выÑокий приоритет. 0 означает назначенный ÑиÑтемой." + +msgid "Monitor Interface" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ð°" + +msgid "Select the LAN network interface to monitor" +msgstr "Выберите Ñетевой Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ LAN Ð´Ð»Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð¸Ð½Ð³Ð°" + +msgid "Speed Units" +msgstr "Единицы ÑкороÑти" + +msgid "Select the speed display unit format" +msgstr "Выберите формат единиц Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÑкороÑти" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "Единицы в байтах (B/s, KB/s, MB/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "Единицы в битах (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "Тема интерфейÑа" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "Выберите тему Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð½Ð¸Ñ‚Ð¾Ñ€Ð° трафика Bandix" + +msgid "Follow System" +msgstr "Следовать ÑиÑтеме" + +msgid "Light Mode" +msgstr "Светлый режим" + +msgid "Dark Mode" +msgstr "Тёмный режим" + +msgid "Feedback" +msgstr "ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑвÑзь" + +msgid "Log Level" +msgstr "Уровень журналированиÑ" + +msgid "Set the log level for Bandix service" +msgstr "УÑтановить уровень Ð»Ð¾Ð³Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñлужбы Bandix" + +msgid "Offline Timeout" +msgstr "Таймаут офлайн" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "УÑтановить таймаут Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ñ„Ð»Ð°Ð¹Ð½ (Ñекунды). УÑтройÑтва, неактивные дольше, будут помечены офлайн" + +msgid "Realtime Traffic Period" +msgstr "Период трафика в реальном времени" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "Интервал 10 минут иÑпользует около 60 КБ на уÑтройÑтво" + +msgid "Data Flush Interval" +msgstr "Интервал ÑброÑа данных" + +msgid "Set the interval for flushing data to disk" +msgstr "УÑтановить интервал запиÑи данных на диÑк" + +msgid "1 minute" +msgstr "1 минута" + +msgid "5 minutes" +msgstr "5 минут" + +msgid "10 minutes" +msgstr "10 минут" + +msgid "15 minutes" +msgstr "15 минут" + +msgid "20 minutes" +msgstr "20 минут" + +msgid "25 minutes" +msgstr "25 минут" + +msgid "30 minutes" +msgstr "30 минут" + +msgid "1 hour" +msgstr "1 чаÑ" + +msgid "2 hours" +msgstr "2 чаÑа" + +msgid "12 hours" +msgstr "12 чаÑов" + +msgid "24 hours" +msgstr "24 чаÑа" + +msgid "Data Directory" +msgstr "Каталог данных" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "ЕÑли вы измените каталог, пожалуйÑта, добавьте его вручную в каталог резервных копий" + +msgid "Bandix data storage directory" +msgstr "Каталог Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… Bandix" + +msgid "Enable Bandix connection monitoring" +msgstr "Включить мониторинг Ñоединений Bandix" + +msgid "Enable Bandix DNS monitoring" +msgstr "Включить мониторинг DNS Bandix" + +msgid "DNS Max Records" +msgstr "МакÑимум запиÑей DNS" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "УÑтановить макÑимальное количеÑтво ÑохранÑемых запиÑей DNS. При превышении Ñтарые запиÑи будут удалÑтьÑÑ" + +msgid "Persist DNS Data" +msgstr "СохранÑть данные DNS" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Включить функцию поÑтоÑнного Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… DNS, данные будут ÑохранÑтьÑÑ Ð½Ð° диÑк только при включении Ñтой опции" + +msgid "DNS Data Flush Interval" +msgstr "Интервал ÑброÑа данных DNS" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "УÑтановить интервал Ð´Ð»Ñ ÑброÑа данных DNS на диÑк" + +msgid "Persist History Data" +msgstr "СохранÑть иÑторию данных" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "Включить функцию поÑтоÑнного Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…, данные будут ÑохранÑтьÑÑ Ð½Ð° диÑк только при включении Ñтой опции" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "Ðе занимает диÑковое проÑтранÑтво, хранитÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в памÑти" + +msgid "Query & Response" +msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¸ Ответ" + +msgid "Queries" +msgstr "ЗапроÑÑ‹" + +msgid "Responses" +msgstr "Ответы" + +msgid "Average Response Time" +msgstr "Среднее Ð’Ñ€ÐµÐ¼Ñ ÐžÑ‚Ð²ÐµÑ‚Ð°" + +msgid "Show More" +msgstr "Показать больше" + +msgid "Show Less" +msgstr "Показать меньше" + +msgid "Add Schedule Rule" +msgstr "Добавить правило Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ раÑпиÑанию" + +msgid "Add Rule" +msgstr "Добавить правило" + +msgid "Set rate limit rules for different time periods" +msgstr "УÑтановить правила Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑкороÑти Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… периодов времени" + +msgid "Time Slot" +msgstr "Временной интервал" + +msgid "Days of Week" +msgstr "Дни недели" + +msgid "Mon" +msgstr "Пн" + +msgid "Tue" +msgstr "Ð’Ñ‚" + +msgid "Wed" +msgstr "Ср" + +msgid "Thu" +msgstr "Чт" + +msgid "Fri" +msgstr "Пт" + +msgid "Sat" +msgstr "Сб" + +msgid "Sun" +msgstr "Ð’Ñ" + +msgid "Adding..." +msgstr "Добавление..." + +msgid "Failed to add schedule rule: " +msgstr "Ðе удалоÑÑŒ добавить правило раÑпиÑаниÑ: " + +msgid "Please set time slot" +msgstr "ПожалуйÑта, уÑтановите временной интервал" + +msgid "Please select at least one day" +msgstr "ПожалуйÑта, выберите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один день" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "Правил раÑпиÑÐ°Ð½Ð¸Ñ Ð¿Ð¾ÐºÐ° нет, нажмите \"Добавить правило\", чтобы начать наÑтройку" + +msgid "Loading..." +msgstr "Загрузка..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "ÐŸÐ¾ÑˆÑ‚ÑƒÑ‡Ð½Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°, подождите... (%d/%d)" + +msgid "No schedule rules" +msgstr "Ðет правил раÑпиÑаниÑ" + +msgid "Failed to load schedule rules" +msgstr "Ðе удалоÑÑŒ загрузить правила раÑпиÑаниÑ" + +msgid "Delete Schedule Rule" +msgstr "Удалить правило Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ раÑпиÑанию" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñто правило раÑпиÑаниÑ?" + +msgid "Failed to delete schedule rule" +msgstr "Ðе удалоÑÑŒ удалить правило раÑпиÑаниÑ" + +msgid "Delete Device" +msgstr "Удалить уÑтройÑтво" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñто уÑтройÑтво? ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ° будет удалена." + +msgid "Failed to delete device" +msgstr "Ðе удалоÑÑŒ удалить уÑтройÑтво" + +msgid "Confirm" +msgstr "Подтвердить" + +msgid "Close" +msgstr "Закрыть" + +msgid "rule" +msgstr "правило" + +msgid "rules" +msgstr "правила" + +msgid "more" +msgstr "еще" + +msgid "No active rule" +msgstr "Ðет активных правил" + +msgid "Schedule Rules" +msgstr "Правила Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ раÑпиÑанию" + +msgid "Upload Statistics" +msgstr "СтатиÑтика отправки" + +msgid "Download Statistics" +msgstr "СтатиÑтика загрузки" + +msgid "Cumulative Traffic" +msgstr "Ðакопительный трафик" + +msgid "Daily" +msgstr "Ежедневно" + +msgid "Weekly" +msgstr "Еженедельно" + +msgid "Monthly" +msgstr "ЕжемеÑÑчно" + +msgid "Statistics" +msgstr "СтатиÑтика" + +msgid "Average" +msgstr "Среднее" + +msgid "Maximum" +msgstr "МакÑимум" + +msgid "Minimum" +msgstr "Минимум" + +msgid "WAN Upload" +msgstr "Отправка WAN" + +msgid "WAN Download" +msgstr "Загрузка WAN" + +msgid "WAN Uploaded" +msgstr "Отправлено WAN" + +msgid "WAN Downloaded" +msgstr "Загружено WAN" + +msgid "Clear Traffic Data" +msgstr "ОчиÑтить данные трафика" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "Ð’Ñ‹ уверены, что хотите очиÑтить вÑе данные трафика? Это дейÑтвие Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ." + +msgid "Failed to clear traffic data: " +msgstr "Ðе удалоÑÑŒ очиÑтить данные трафика: " + +msgid "Restart Service" +msgstr "ПерезапуÑтить Ñлужбу" + +msgid "Restart Bandix Service" +msgstr "ПерезапуÑтить Ñлужбу Bandix" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "Ð’Ñ‹ уверены, что хотите перезапуÑтить Ñлужбу Bandix?" + +msgid "Failed to restart service: " +msgstr "Ðе удалоÑÑŒ перезапуÑтить Ñлужбу: " + +msgid "Realtime" +msgstr "Ð’ реальном времени" + +msgid "Last 24 Hours" +msgstr "ПоÑледние 24 чаÑа" + +msgid "Last 7 Days" +msgstr "ПоÑледние 7 дней" + +msgid "Last 30 Days" +msgstr "ПоÑледние 30 дней" + +msgid "Last 10 Minutes" +msgstr "ПоÑледние 10 минут" + +msgid "Last 15 Minutes" +msgstr "ПоÑледние 15 минут" + +msgid "Last 30 Minutes" +msgstr "ПоÑледние 30 минут" + +msgid "Last 1 Hour" +msgstr "ПоÑледний 1 чаÑ" + +msgid "Starting installation..." +msgstr "Ðачало уÑтановки..." + +msgid "Page will refresh in 3 seconds." +msgstr "Страница обновитÑÑ Ñ‡ÐµÑ€ÐµÐ· 3 Ñекунды." + +msgid "Installation failed" +msgstr "УÑтановка не удалаÑÑŒ" + +msgid "Installation failed at step: " +msgstr "УÑтановка не удалаÑÑŒ на шаге: " + +msgid "Details: " +msgstr "ПодробноÑти: " + +msgid "Installation failed: " +msgstr "УÑтановка не удалаÑÑŒ: " + +msgid "Unknown error" +msgstr "ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" + +msgid "Service restarted successfully." +msgstr "Служба уÑпешно перезапущена." + +msgid "Service restart may have failed. Please check manually." +msgstr "ПерезапуÑк Ñлужбы мог не удатьÑÑ. ПожалуйÑта, проверьте вручную." + +msgid "Please restart the service." +msgstr "ПожалуйÑта, перезапуÑтите Ñлужбу." + +msgid "LuCI App updated successfully!" +msgstr "Приложение LuCI уÑпешно обновлено!" + +msgid "Bandix updated successfully!" +msgstr "Bandix уÑпешно обновлен!" + +msgid "LuCI App has update: " +msgstr "Приложение LuCI имеет обновление: " + +msgid "Bandix has update: " +msgstr "Bandix имеет обновление: " + +msgid "LuCI App is up to date: " +msgstr "Приложение LuCI актуально: " + +msgid "Bandix is up to date: " +msgstr "Bandix актуален: " + +msgid "Updates Available" +msgstr "ДоÑтупны ОбновлениÑ" + +msgid "No Updates Available" +msgstr "Ðет ДоÑтупных Обновлений" + +msgid "Detected Architecture" +msgstr "ÐžÐ±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð½Ð°Ñ Ðрхитектура" + +msgid "Package Manager" +msgstr "Менеджер Пакетов" + +msgid "LuCI Assets" +msgstr "РеÑурÑÑ‹ LuCI" + +msgid "Bandix Assets" +msgstr "РеÑурÑÑ‹ Bandix" + +msgid "Failed to check for updates" +msgstr "Ðе удалоÑÑŒ проверить обновлениÑ" + +msgid "Failed to check for updates: " +msgstr "Ðе удалоÑÑŒ проверить обновлениÑ: " + +msgid "Checking..." +msgstr "Проверка..." + +msgid "Check for Updates" +msgstr "Проверить ОбновлениÑ" + +msgid "Installing..." +msgstr "УÑтановка..." + +msgid "Download and Install" +msgstr "Скачать и УÑтановить" + +msgid "Manual Download" +msgstr "Ð ÑƒÑ‡Ð½Ð°Ñ Ð—Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°" + +msgid "Close" +msgstr "Закрыть" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "Ðачало уÑтановки... Страница автоматичеÑки обновитÑÑ Ñ‡ÐµÑ€ÐµÐ· 30 Ñекунд." + +msgid "Please clear your browser cache manually after updating." +msgstr "ПожалуйÑта, вручную очиÑтите кеш браузера поÑле обновлениÑ." + +msgid "Traffic Statistics" +msgstr "СтатиÑтика трафика" + +msgid "Traffic Statistics" +msgstr "СтатиÑтика трафика" + +msgid "Device Usage Ranking" +msgstr "Рейтинг иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑƒÑтройÑтв" + +msgid "Start Date" +msgstr "Дата начала" + +msgid "End Date" +msgstr "Дата окончаниÑ" + +msgid "Reset" +msgstr "СброÑить" + +msgid "Today" +msgstr "СегоднÑ" + +msgid "This Week" +msgstr "Ðа Ñтой неделе" + +msgid "Last Week" +msgstr "Ðа прошлой неделе" + +msgid "This Month" +msgstr "Ð’ Ñтом меÑÑце" + +msgid "Last Month" +msgstr "Ð’ прошлом меÑÑце" + +msgid "Last 90 Days" +msgstr "ПоÑледние 90 дней" + +msgid "Last Year" +msgstr "За поÑледний год" + +msgid "Traffic Timeline" +msgstr "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÑˆÐºÐ°Ð»Ð° трафика" + +msgid "Aggregation:" +msgstr "ÐгрегациÑ:" + +msgid "Hourly" +msgstr "По чаÑам" + +msgid "Device:" +msgstr "УÑтройÑтво:" + +msgid "Traffic Push URL" +msgstr "URL Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ трафика" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "ОтправлÑть данные трафика на удаленную HTTP конечную точку (POST JSON). ОÑтавьте пуÑтым Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ." + +msgid "Device Event Push URL" +msgstr "URL Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ Ñобытий уÑтройÑтва" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "ОтправлÑть ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ/Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ ÑƒÑтройÑтва на удаленную HTTP конечную точку (POST JSON при изменении ÑоÑтоÑниÑ). ОÑтавьте пуÑтым Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ." + +msgid "Additional Subnets" +msgstr "Дополнительные подÑети" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "Дополнительные локальные подÑети (CIDR Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· запÑтую, напр. '192.168.2.0/24,10.0.0.0/8'). ОÑтавьте пуÑтым Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ подÑети интерфейÑа." + +msgid "Exclude Interface Device" +msgstr "ИÑключить уÑтройÑтво интерфейÑа" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "ИÑключить Ñам роутер (уÑтройÑтво интерфейÑа) из ÑтатиÑтики трафика" + +msgid "Enable Neighbor Flush" +msgstr "Включить ÑÐ±Ñ€Ð¾Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ ÑоÑедей" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "Включить периодичеÑкий ÑÐ±Ñ€Ð¾Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… таблицы ÑоÑедей. Обычно не рекомендуетÑÑ, еÑли ÑпиÑок уÑтройÑтв работает нормально." + +msgid "Neighbor Flush Interval" +msgstr "Интервал ÑброÑа таблицы ÑоÑедей" + +msgid "Set the interval for flushing neighbor table data" +msgstr "УÑтановить интервал ÑброÑа данных таблицы ÑоÑедей" + +msgid "No devices" +msgstr "Ðет уÑтройÑтв" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "Трафик LAN раÑÑматриваетÑÑ Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ Ð·Ñ€ÐµÐ½Ð¸Ñ Ð²Ñей подÑети, поÑтому загрузка и выгрузка вÑегда равны, Ð¾Ð±Ñ€Ð°Ð·ÑƒÑ Ð·Ð°Ð¼ÐºÐ½ÑƒÑ‚Ñ‹Ð¹ цикл. Кроме того, из-за Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ñпециализированных аппаратных коммутационных чипов, трафик LAN между 2 уÑтройÑтвами (например, ПК - NAS) в локальной Ñети может быть не подлежащим мониторингу." + +msgid "Protocol" +msgstr "Протокол" + +msgid "State" +msgstr "СоÑтоÑние" + +msgid "Send" +msgstr "Отправка" + +msgid "Reply" +msgstr "Ответ" + +msgid "Flags" +msgstr "Флаги" + +msgid "Loading…" +msgstr "Загрузка…" + +msgid "No connections" +msgstr "Ðет подключений" + +msgid "pkts" +msgstr "пакеты" + +msgid "Failed to load" +msgstr "Ошибка загрузки" + +msgid "Connection Details" +msgstr "ПодробноÑти ÑоединениÑ" + +msgid "Details" +msgstr "Подробнее" + +msgid "Orig Src" +msgstr "ИÑÑ‚. отпр." + +msgid "Orig Dst" +msgstr "Ðазнач. отпр." + +msgid "Repl Src" +msgstr "ИÑÑ‚. ответа" + +msgid "Repl Dst" +msgstr "Ðазнач. ответа" + +msgid "TC backend" +msgstr "БÑкенд TC" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "Выберите бÑкенд Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ TC. РекомендациÑ: по умолчанию иÑпользуйте auto; tcx предпочтителен на Ñдре >= 6.6; netlink безопаÑнее на Ñтарых Ñдрах." + +msgid "TC order" +msgstr "ПорÑдок TC" + +msgid "Netlink priority" +msgstr "Приоритет Netlink" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "ИÑпользуетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ при backend=netlink. Диапазон: 0..65535 (0 означает по умолчанию)." + +msgid "TCX ingress anchor program id" +msgstr "ID Ñкорной программы TCX ingress" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "ИÑпользуетÑÑ, когда tc_order имеет значение before/after. Должен быть корректный ID ingress-программы на том же интерфейÑе." + +msgid "TCX egress anchor program id" +msgstr "ID Ñкорной программы TCX egress" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "ИÑпользуетÑÑ, когда tc_order имеет значение before/after. Должен быть корректный ID egress-программы на том же интерфейÑе." diff --git a/luci-app-bandix/po/zh_Hans/bandix.po b/luci-app-bandix/po/zh_Hans/bandix.po new file mode 100644 index 00000000..2e74db81 --- /dev/null +++ b/luci-app-bandix/po/zh_Hans/bandix.po @@ -0,0 +1,1284 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Bandix æµé‡ç›‘控" + +msgid "Loading data..." +msgstr "正在加载数æ®..." + +msgid "Unable to fetch data" +msgstr "æ— æ³•èŽ·å–æ•°æ®" + +msgid "Unable to fetch history data" +msgstr "无法获å–åŽ†å²æ•°æ®" + +msgid "Hostname" +msgstr "主机å" + +msgid "IP Address" +msgstr "IP地å€" + +msgid "MAC Address" +msgstr "MAC地å€" + +msgid "Download Speed" +msgstr "下载速度" + +msgid "Upload Speed" +msgstr "上传速度" + +msgid "Total Download" +msgstr "总下载é‡" + +msgid "Total Upload" +msgstr "总上传é‡" + +msgid "Download Limit" +msgstr "下载é™é€Ÿ" + +msgid "Upload Limit" +msgstr "上传é™é€Ÿ" + +msgid "Interface Language" +msgstr "界é¢è¯­è¨€" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "选择 Bandix æµé‡ç›‘控的显示语言" + +msgid "Device Info" +msgstr "设备信æ¯" + +msgid "Device List" +msgstr "设备列表" + +msgid "LAN Traffic" +msgstr "LAN æµé‡" + +msgid "WAN Traffic" +msgstr "WAN æµé‡" + +msgid "Network Type" +msgstr "网络类型" + +msgid "Rate Limit" +msgstr "é™é€Ÿè®¾ç½®" + +msgid "Actions" +msgstr "æ“作" + +msgid "Online Devices" +msgstr "在线设备" + +msgid "WAN Only" +msgstr "ä»…é™WAN æµé‡" + +msgid "Settings" +msgstr "设置" + +msgid "Device Settings" +msgstr "设备设置" + +msgid "Rate Limits" +msgstr "é™é€Ÿè®¾ç½®" + +msgid "Remove Rate Limit" +msgstr "å–æ¶ˆé™é€Ÿ" + +msgid "Save" +msgstr "ä¿å­˜" + +msgid "Cancel" +msgstr "å–æ¶ˆ" + +msgid "Set Rate Limit" +msgstr "设置é™é€Ÿ" + +msgid "Device" +msgstr "设备" + +msgid "Set Hostname" +msgstr "设置主机å" + +msgid "Please enter hostname" +msgstr "请输入主机å" + +msgid "Hostname set successfully" +msgstr "主机å设置æˆåŠŸ" + +msgid "Failed to set hostname" +msgstr "主机å设置失败" + +msgid "Unlimited" +msgstr "æ— é™åˆ¶" + +msgid "Settings saved successfully" +msgstr "设置æˆåŠŸ" + +msgid "Failed to save settings" +msgstr "设置失败" + +msgid "Please enter a valid speed value" +msgstr "请输入有效的速度值" + +msgid "Speed value must be greater than 0" +msgstr "速度值必须大于0" + +msgid "Saving..." +msgstr "ä¿å­˜ä¸­..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "é™é€ŸåŠŸèƒ½ä»…å¯¹ WAN æµé‡ç”Ÿæ•ˆã€‚æŸäº› LAN 内部æµé‡å¯èƒ½å› ç¡¬ä»¶äº¤æ¢åŠ é€Ÿæœªè¢«ç›‘æŽ§ã€‚" + +msgid "Tip: Enter 0 for unlimited" +msgstr "æç¤ºï¼šè¾“å…¥ 0 表示无é™åˆ¶" + +msgid "Traffic History" +msgstr "åŽ†å²æµé‡è¶‹åŠ¿" + +msgid "Realtime Traffic Trends" +msgstr "实时æµé‡è¶‹åŠ¿" + +msgid "Select Device" +msgstr "选择设备" + +msgid "All Devices" +msgstr "所有设备" + +msgid "Time Range" +msgstr "时间范围" + +msgid "Last 5 minutes" +msgstr "最近5分钟" + +msgid "Last 30 minutes" +msgstr "最近30分钟" + +msgid "Last 2 hours" +msgstr "最近2å°æ—¶" + +msgid "Type" +msgstr "类型" + +msgid "Total" +msgstr "总æµé‡" + +msgid "LAN" +msgstr "LAN æµé‡" + +msgid "WAN" +msgstr "WAN æµé‡" + +msgid "Refresh" +msgstr "刷新" + +msgid "Upload Rate" +msgstr "上传速率" + +msgid "Download Rate" +msgstr "下载速率" + +msgid "Last" +msgstr "最近" + +msgid "second" +msgstr "ç§’" + +msgid "minute" +msgstr "分钟" + +msgid "hour" +msgstr "å°æ—¶" + +msgid "day" +msgstr "天" + +msgid "week" +msgstr "周" + +msgid "Other Rates" +msgstr "其他速率" + +msgid "Cumulative" +msgstr "累计æµé‡" + +msgid "Total Uploaded" +msgstr "总上传" + +msgid "Total Downloaded" +msgstr "总下载" + +msgid "LAN Uploaded" +msgstr "LAN 已上传" + +msgid "LAN Downloaded" +msgstr "LAN 已下载" + +msgid "WAN Uploaded" +msgstr "WAN 已上传" + +msgid "WAN Downloaded" +msgstr "WAN 已下载" + +msgid "Total Upload" +msgstr "总上传速率" + +msgid "Total Download" +msgstr "总下载速率" + +msgid "LAN Upload" +msgstr "LAN 上传速率" + +msgid "LAN Download" +msgstr "LAN 下载速率" + +msgid "WAN Upload" +msgstr "WAN 上传速率" + +msgid "WAN Download" +msgstr "WAN 下载速率" + +msgid "Never Online" +msgstr "从未上线" + +msgid "Just Now" +msgstr "刚刚" + +msgid "min ago" +msgstr "分钟å‰" + +msgid "h ago" +msgstr "å°æ—¶å‰" + +msgid "days ago" +msgstr "天å‰" + +msgid "months ago" +msgstr "个月å‰" + +msgid "years ago" +msgstr "å¹´å‰" + +msgid "Last Online" +msgstr "最åŽä¸Šçº¿" + +msgid "Zoom" +msgstr "缩放" + +msgid "Sort By" +msgstr "æŽ’åºæ–¹å¼" + +msgid "Online Status" +msgstr "在线状æ€" + +msgid "Total Traffic" +msgstr "总æµé‡" + +msgid "Ascending" +msgstr "å‡åº" + +msgid "Descending" +msgstr "é™åº" + +msgid "Sort by Speed" +msgstr "按速度排åº" + +msgid "Sort by Traffic" +msgstr "æŒ‰ç”¨é‡æŽ’åº" + +msgid "Simple Mode" +msgstr "简易模å¼" + +msgid "Detailed Mode" +msgstr "详细模å¼" + +msgid "Bandix DNS Monitor" +msgstr "Bandix DNS 监控" + +msgid "DNS Monitor" +msgstr "DNS 监控" + +msgid "DNS Query Records" +msgstr "DNS 查询记录" + +msgid "DNS Statistics" +msgstr "DNS 统计信æ¯" + +msgid "DNS Monitoring Disabled" +msgstr "DNS监控未å¯ç”¨" + +msgid "Please enable DNS monitoring in settings" +msgstr "请在设置中å¯ç”¨DNS监控功能" + +msgid "Go to Settings" +msgstr "å‰å¾€è®¾ç½®" + +msgid "No Data" +msgstr "æ— æ•°æ®" + +msgid "Time" +msgstr "æ—¶é—´" + +msgid "Domain" +msgstr "域å" + +msgid "Query Type" +msgstr "查询类型" + +msgid "Response Code" +msgstr "å“应ç " + +msgid "Response Time" +msgstr "å“应时间" + +msgid "Source IP" +msgstr "æºIP" + +msgid "Destination IP" +msgstr "目标IP" + +msgid "Response IPs" +msgstr "å“应IP" + +msgid "Response Result" +msgstr "å“应结果" + +msgid "DNS Server" +msgstr "DNSæœåС噍" + +msgid "Query" +msgstr "查询" + +msgid "Response" +msgstr "å“应" + +msgid "Filter" +msgstr "过滤" + +msgid "Domain Filter" +msgstr "域å过滤" + +msgid "Device Filter" +msgstr "设备过滤" + +msgid "DNS Server Filter" +msgstr "DNSæœåŠ¡å™¨è¿‡æ»¤" + +msgid "Type Filter" +msgstr "类型过滤" + +msgid "All" +msgstr "全部" + +msgid "Period" +msgstr "周期" + +msgid "Display Mode" +msgstr "显示模å¼" + +msgid "Week" +msgstr "本周" + +msgid "Month" +msgstr "本月" + +msgid "Year" +msgstr "本年" + +msgid "Queries Only" +msgstr "仅查询" + +msgid "Responses Only" +msgstr "ä»…å“应" + +msgid "Search" +msgstr "æœç´¢" + +msgid "Search Domain" +msgstr "æœç´¢åŸŸå" + +msgid "Search Device" +msgstr "æœç´¢è®¾å¤‡" + +msgid "Search DNS Server" +msgstr "æœç´¢DNSæœåС噍" + +msgid "Clear" +msgstr "清除" + +msgid "Previous" +msgstr "上一页" + +msgid "Next" +msgstr "下一页" + +msgid "Page" +msgstr "第" + +msgid "of" +msgstr "页,共" + +msgid "Total" +msgstr "全部" + +msgid "records" +msgstr "æ¡è®°å½•" + +msgid "Per Page" +msgstr "æ¯é¡µæ˜¾ç¤º" + +msgid "" +msgstr "æ¡" + +msgid "Total Queries" +msgstr "总查询数" + +msgid "Total Responses" +msgstr "总å“应数" + +msgid "Queries with Response" +msgstr "有å“应查询" + +msgid "Queries without Response" +msgstr "æ— å“应查询" + +msgid "Avg Response Time" +msgstr "å¹³å‡å“应时间" + +msgid "Min Response Time" +msgstr "最快å“应时间" + +msgid "Max Response Time" +msgstr "最慢å“应时间" + +msgid "Success Rate" +msgstr "æˆåŠŸçŽ‡" + +msgid "Success" +msgstr "æˆåŠŸ" + +msgid "Failure" +msgstr "失败" + +msgid "Top Domains" +msgstr "最常查询域å" + +msgid "Top Query Types" +msgstr "最常用查询类型" + +msgid "Top Devices" +msgstr "最活跃设备" + +msgid "Top DNS Servers" +msgstr "最常用DNSæœåС噍" + +msgid "Unique Devices" +msgstr "唯一设备数" + +msgid "ms" +msgstr "毫秒" + +msgid "minutes" +msgstr "分钟" + +msgid "Unknown Device" +msgstr "未知设备" + +msgid "Domain not found" +msgstr "åŸŸåæœªæ‰¾åˆ°" + +msgid "Server error" +msgstr "æœåŠ¡å™¨é”™è¯¯" + +msgid "Format error" +msgstr "æ ¼å¼é”™è¯¯" + +msgid "Refused" +msgstr "æ‹’ç»" + +msgid "Other" +msgstr "å…¶ä»–" + +msgid "Does not include DoH and DoT" +msgstr "ä¸åŒ…å« DoH å’Œ DoT" + +msgid "Latest Response Time" +msgstr "最新å“应时间" + +msgid "Response Code Distribution" +msgstr "å“应ç åˆ†å¸ƒ" + +msgid "Response Time Percentiles" +msgstr "å“应时间百分ä½" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Bandix 连接监控" + +msgid "Connection Monitor" +msgstr "连接监控" + +msgid "Device Connection Statistics" +msgstr "设备连接统计" + +msgid "Global Connection Statistics" +msgstr "全局连接统计" + +msgid "Active TCP" +msgstr "活跃TCP" + +msgid "Active UDP" +msgstr "活跃UDP" + +msgid "Closed TCP" +msgstr "已关闭TCP" + +msgid "Total Connections" +msgstr "总连接数" + +msgid "Last Updated" +msgstr "æœ€åŽæ›´æ–°" + +msgid "TCP Connections" +msgstr "TCP连接数" + +msgid "UDP Connections" +msgstr "UDP连接数" + +msgid "Established TCP" +msgstr "已建立TCP" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "设备总数" + +msgid "Connection Monitor Disabled" +msgstr "连接监控未å¯ç”¨" + +msgid "Please enable connection monitoring in settings" +msgstr "请在设置中å¯ç”¨è¿žæŽ¥ç›‘控功能" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "åˆ—è¡¨åªæ˜¾ç¤ºå±€åŸŸç½‘设备连接,数æ®å¯èƒ½å’Œæ€»è¿žæŽ¥æ•°ä¸ä¸€è‡´ã€‚" + +msgid "TCP Status Details" +msgstr "TCP 状æ€è¯¦æƒ…" + +msgid "Basic Settings" +msgstr "基本设置" + +msgid "Traffic Monitor Settings" +msgstr "æµé‡ç›‘控设置" + +msgid "Connection Monitor Settings" +msgstr "连接监控设置" + +msgid "DNS Monitor Settings" +msgstr "DNS监控设置" + +msgid "Bandix Basic Configuration" +msgstr "Bandix 基本é…ç½®" + +msgid "Configure basic parameters for Bandix service" +msgstr "é…ç½® Bandix æœåŠ¡çš„åŸºæœ¬å‚æ•°" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "Bandix æµé‡ç›‘控é…ç½®" + +msgid "Configure traffic monitoring related parameters" +msgstr "é…ç½®æµé‡ç›‘æŽ§ç›¸å…³å‚æ•°" + +msgid "Bandix Connection Monitor Configuration" +msgstr "Bandix 连接监控é…ç½®" + +msgid "Configure connection monitoring related parameters" +msgstr "é…ç½®è¿žæŽ¥ç›‘æŽ§ç›¸å…³å‚æ•°" + +msgid "Bandix DNS Monitor Configuration" +msgstr "Bandix DNS监控é…ç½®" + +msgid "Configure DNS monitoring related parameters" +msgstr "é…ç½®DNSç›‘æŽ§ç›¸å…³å‚æ•°" + +msgid "Enable" +msgstr "å¯ç”¨" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "å¯ç”¨ Bandix æµé‡ç›‘控æœåŠ¡" + +msgid "Enable Traffic Monitoring" +msgstr "å¯ç”¨æµé‡ç›‘控" + +msgid "Enable Connection Monitoring" +msgstr "å¯ç”¨è¿žæŽ¥ç›‘控" + +msgid "Enable DNS Monitoring" +msgstr "å¯ç”¨DNS监控" + +msgid "Simplified Chinese" +msgstr "简体中文" + +msgid "Traditional Chinese" +msgstr "ç¹ä½“中文" + +msgid "Port" +msgstr "端å£" + +msgid "Port for Bandix service to listen on" +msgstr "Bandix æœåŠ¡ç›‘å¬çš„端å£" + +msgid "TC Priority" +msgstr "TC 优先级" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "设置 TC filter 优先级,使得与其他 eBPF TC ç¨‹åºæ›´å¥½çš„共存,数字越å°ï¼Œä¼˜å…ˆçº§è¶Šé«˜ï¼Œ0 表示由系统分é…。" + +msgid "Monitor Interface" +msgstr "监控网å¡" + +msgid "Select the LAN network interface to monitor" +msgstr "选择è¦ç›‘控的LAN网络接å£" + +msgid "Speed Units" +msgstr "网速å•ä½" + +msgid "Select the speed display unit format" +msgstr "选择网速显示的å•使 ¼å¼" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "字节å•ä½ (B/s, KB/s, MB/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "比特å•ä½ (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "界é¢ä¸»é¢˜" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "选择 Bandix æµé‡ç›‘控的显示主题" + +msgid "Follow System" +msgstr "è·Ÿéšç³»ç»Ÿ" + +msgid "Light Mode" +msgstr "明亮模å¼" + +msgid "Dark Mode" +msgstr "暗黑模å¼" + +msgid "Feedback" +msgstr "æ„è§å馈" + +msgid "Log Level" +msgstr "日志级别" + +msgid "Set the log level for Bandix service" +msgstr "设置 Bandix æœåŠ¡çš„æ—¥å¿—çº§åˆ«" + +msgid "Offline Timeout" +msgstr "离线超时时间" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "设置设备离线判断的超时时间(秒)。超过此时间未活动的设备将被标记为离线" + +msgid "Realtime Traffic Period" +msgstr "实时æµé‡å‘¨æœŸ" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "10分钟历å²å‘¨æœŸï¼Œæ¯ä¸ªè®¾å¤‡å ç”¨ 60KB" + +msgid "Data Flush Interval" +msgstr "æ•°æ® flush é—´éš”" + +msgid "Set the interval for flushing data to disk" +msgstr "设置数æ®å†™å…¥ç£ç›˜çš„æ—¶é—´é—´éš”" + +msgid "1 minute" +msgstr "1 分钟" + +msgid "5 minutes" +msgstr "5 分钟" + +msgid "10 minutes" +msgstr "10 分钟" + +msgid "15 minutes" +msgstr "15 分钟" + +msgid "20 minutes" +msgstr "20 分钟" + +msgid "25 minutes" +msgstr "25 分钟" + +msgid "30 minutes" +msgstr "30 分钟" + +msgid "1 hour" +msgstr "1 å°æ—¶" + +msgid "2 hours" +msgstr "2 å°æ—¶" + +msgid "12 hours" +msgstr "12 å°æ—¶" + +msgid "24 hours" +msgstr "24 å°æ—¶" + +msgid "Data Directory" +msgstr "æ•°æ®ç›®å½•" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "如果更改了目录,请手动添加到备份目录" + +msgid "Bandix data storage directory" +msgstr "Bandix æ•°æ®å­˜å‚¨ç›®å½•" + +msgid "Enable Bandix connection monitoring" +msgstr "å¯ç”¨ Bandix 连接监控功能" + +msgid "Enable Bandix DNS monitoring" +msgstr "å¯ç”¨ Bandix DNS监控功能" + +msgid "DNS Max Records" +msgstr "DNS最大记录数" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "设置DNS查询记录的最大ä¿å­˜æ•°é‡ï¼Œè¶…过此数é‡å°†åˆ é™¤æœ€æ—§çš„记录" + +msgid "Persist DNS Data" +msgstr "æŒä¹…化DNSæ•°æ®" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "å¯ç”¨DNSæ•°æ®æŒä¹…åŒ–åŠŸèƒ½ï¼Œåªæœ‰å¯ç”¨æ­¤é€‰é¡¹åŽæ‰ä¼šæŒä¹…化到ç£ç›˜" + +msgid "DNS Data Flush Interval" +msgstr "DNSæ•°æ® flush é—´éš”" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "设置DNSæ•°æ®å†™å…¥ç£ç›˜çš„æ—¶é—´é—´éš”" + +msgid "Persist History Data" +msgstr "æŒä¹…åŒ–åŽ†å²æ•°æ®" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "å¯ç”¨æ•°æ®æŒä¹…åŒ–åŠŸèƒ½ï¼Œåªæœ‰å¯ç”¨æ­¤é€‰é¡¹åŽæ‰ä¼šæŒä¹…化到ç£ç›˜" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "ä¸å ç”¨å­˜å‚¨ç©ºé—´ï¼Œä»…存储在内存中" + +msgid "Query & Response" +msgstr "查询与å“应" + +msgid "Queries" +msgstr "查询" + +msgid "Responses" +msgstr "å“应" + +msgid "Average Response Time" +msgstr "å¹³å‡å“应时间" + +msgid "Show More" +msgstr "显示更多" + +msgid "Show Less" +msgstr "显示更少" + +msgid "Add Schedule Rule" +msgstr "添加定时é™é€Ÿè§„则" + +msgid "Add Rule" +msgstr "添加规则" + +msgid "Set rate limit rules for different time periods" +msgstr "为ä¸åŒæ—¶é—´æ®µè®¾ç½®é™é€Ÿè§„则" + +msgid "Time Slot" +msgstr "时间段" + +msgid "Days of Week" +msgstr "星期" + +msgid "Mon" +msgstr "周一" + +msgid "Tue" +msgstr "周二" + +msgid "Wed" +msgstr "周三" + +msgid "Thu" +msgstr "周四" + +msgid "Fri" +msgstr "周五" + +msgid "Sat" +msgstr "周六" + +msgid "Sun" +msgstr "周日" + +msgid "Adding..." +msgstr "添加中..." + +msgid "Failed to add schedule rule: " +msgstr "添加定时é™é€Ÿè§„则失败:" + +msgid "Please set time slot" +msgstr "请设置时间段" + +msgid "Please select at least one day" +msgstr "请至少选择一天" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "还没有定时é™é€Ÿè§„则,点击"添加规则"开始设置" + +msgid "Loading..." +msgstr "加载中..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "分段加载中,请ç¨ç­‰... (%d/%d)" + +msgid "No schedule rules" +msgstr "没有定时é™é€Ÿè§„则" + +msgid "Failed to load schedule rules" +msgstr "加载定时é™é€Ÿè§„则失败" + +msgid "Delete Schedule Rule" +msgstr "删除定时é™é€Ÿè§„则" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "确定è¦åˆ é™¤è¿™ä¸ªå®šæ—¶é™é€Ÿè§„则å—?" + +msgid "Failed to delete schedule rule" +msgstr "删除定时é™é€Ÿè§„则失败" + +msgid "Delete Device" +msgstr "删除设备" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "确定è¦åˆ é™¤è¯¥è®¾å¤‡å—?æµé‡åކå²å°†è¢«æ¸…除。" + +msgid "Failed to delete device" +msgstr "删除设备失败" + +msgid "Confirm" +msgstr "确认" + +msgid "Close" +msgstr "关闭" + +msgid "rule" +msgstr "规则" + +msgid "rules" +msgstr "规则" + +msgid "more" +msgstr "更多" + +msgid "No active rule" +msgstr "无生效规则" + +msgid "Schedule Rules" +msgstr "定时é™é€Ÿè§„则" + +msgid "Upload Statistics" +msgstr "上传统计" + +msgid "Download Statistics" +msgstr "下载统计" + +msgid "Cumulative Traffic" +msgstr "累计æµé‡" + +msgid "Daily" +msgstr "æ¯æ—¥" + +msgid "Weekly" +msgstr "æ¯å‘¨" + +msgid "Monthly" +msgstr "æ¯æœˆ" + +msgid "Statistics" +msgstr "统计" + +msgid "Average" +msgstr "å¹³å‡å€¼" + +msgid "Maximum" +msgstr "最大值" + +msgid "Minimum" +msgstr "最å°å€¼" + +msgid "WAN Upload" +msgstr "WAN 上传" + +msgid "WAN Download" +msgstr "WAN 下载" + +msgid "WAN Uploaded" +msgstr "WAN 上传é‡" + +msgid "WAN Downloaded" +msgstr "WAN 下载é‡" + +msgid "Clear Traffic Data" +msgstr "删除æµé‡æ•°æ®" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "ç¡®å®šè¦æ¸…除所有æµé‡æ•°æ®å—?此æ“作无法撤销。" + +msgid "Failed to clear traffic data: " +msgstr "清除æµé‡æ•°æ®å¤±è´¥ï¼š" + +msgid "Restart Service" +msgstr "é‡å¯æœåŠ¡" + +msgid "Restart Bandix Service" +msgstr "é‡å¯ Bandix æœåŠ¡" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "确定è¦é‡å¯ Bandix æœåŠ¡å—?" + +msgid "Failed to restart service: " +msgstr "é‡å¯æœåŠ¡å¤±è´¥ï¼š" + +msgid "Realtime" +msgstr "实时" + +msgid "Last 24 Hours" +msgstr "最近24å°æ—¶" + +msgid "Last 7 Days" +msgstr "最近7天" + +msgid "Last 30 Days" +msgstr "最近30天" + +msgid "Last 10 Minutes" +msgstr "最近10分钟" + +msgid "Last 15 Minutes" +msgstr "最近15分钟" + +msgid "Last 30 Minutes" +msgstr "最近30分钟" + +msgid "Last 1 Hour" +msgstr "最近1å°æ—¶" + +msgid "Starting installation..." +msgstr "开始安装..." + +msgid "Page will refresh in 3 seconds." +msgstr "页é¢å°†åœ¨3ç§’åŽåˆ·æ–°ã€‚" + +msgid "Installation failed" +msgstr "安装失败" + +msgid "Installation failed at step: " +msgstr "安装在步骤失败:" + +msgid "Details: " +msgstr "详细信æ¯ï¼š" + +msgid "Installation failed: " +msgstr "安装失败:" + +msgid "Unknown error" +msgstr "未知错误" + +msgid "Service restarted successfully." +msgstr "æœåŠ¡é‡å¯æˆåŠŸã€‚" + +msgid "Service restart may have failed. Please check manually." +msgstr "æœåŠ¡é‡å¯å¯èƒ½å¤±è´¥ï¼Œè¯·æ‰‹åŠ¨æ£€æŸ¥ã€‚" + +msgid "Please restart the service." +msgstr "请é‡å¯æœåŠ¡ã€‚" + +msgid "LuCI App updated successfully!" +msgstr "LuCI 应用更新æˆåŠŸï¼" + +msgid "Bandix updated successfully!" +msgstr "Bandix æ›´æ–°æˆåŠŸï¼" + +msgid "LuCI App has update: " +msgstr "LuCI 应用有更新:" + +msgid "Bandix has update: " +msgstr "Bandix 有更新:" + +msgid "LuCI App is up to date: " +msgstr "LuCI 应用已是最新版本:" + +msgid "Bandix is up to date: " +msgstr "Bandix 已是最新版本:" + +msgid "Updates Available" +msgstr "有å¯ç”¨æ›´æ–°" + +msgid "No Updates Available" +msgstr "æ— å¯ç”¨æ›´æ–°" + +msgid "Detected Architecture" +msgstr "检测到的架构" + +msgid "Package Manager" +msgstr "包管ç†å™¨" + +msgid "LuCI Assets" +msgstr "LuCI 资æº" + +msgid "Bandix Assets" +msgstr "Bandix 资æº" + +msgid "Failed to check for updates" +msgstr "检查更新失败" + +msgid "Failed to check for updates: " +msgstr "检查更新失败:" + +msgid "Checking..." +msgstr "检查中..." + +msgid "Check for Updates" +msgstr "检查更新" + +msgid "Installing..." +msgstr "安装中..." + +msgid "Download and Install" +msgstr "下载并安装" + +msgid "Manual Download" +msgstr "手动下载" + +msgid "Close" +msgstr "关闭" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "开始安装... 页é¢å°†åœ¨30ç§’åŽè‡ªåŠ¨åˆ·æ–°ã€‚" + +msgid "Please clear your browser cache manually after updating." +msgstr "æ›´æ–°åŽè¯·æ‰‹åŠ¨æ¸…ç©ºæµè§ˆå™¨ç¼“存。" + +msgid "Update available" +msgstr "有更新" + +msgid "Update available, click to go to settings" +msgstr "有更新,点击å‰å¾€è®¾ç½®" + +msgid "Traffic Statistics" +msgstr "æµé‡ç»Ÿè®¡" + +msgid "Traffic Statistics" +msgstr "æµé‡ç»Ÿè®¡" + +msgid "Device Usage Ranking" +msgstr "è®¾å¤‡ç”¨é‡æŽ’è¡Œ" + +msgid "Start Date" +msgstr "开始日期" + +msgid "End Date" +msgstr "ç»“æŸæ—¥æœŸ" + +msgid "Reset" +msgstr "é‡ç½®" + +msgid "Today" +msgstr "今天" + +msgid "This Week" +msgstr "本周" + +msgid "Last Week" +msgstr "上周" + +msgid "This Month" +msgstr "本月" + +msgid "This Year" +msgstr "本年" + +msgid "Last Month" +msgstr "上月" + +msgid "Last 90 Days" +msgstr "最近90天" + +msgid "Last Year" +msgstr "最近一年" + +msgid "Traffic Timeline" +msgstr "æµé‡æ—¶é—´çº¿" + +msgid "Aggregation:" +msgstr "èšåˆæ–¹å¼ï¼š" + +msgid "Hourly" +msgstr "æŒ‰å°æ—¶" + +msgid "Device:" +msgstr "设备:" + +msgid "Global Rate Limit" +msgstr "全局é™é€Ÿ" + +msgid "When enabled, all devices will be rate limited. Devices in the list are exempt (whitelist)." +msgstr "å¯ç”¨åŽï¼Œæ‰€æœ‰è®¾å¤‡éƒ½ä¼šé™é€Ÿï¼›åˆ—表内设备为白åå•,ä¸å—é™é€Ÿã€‚" + +msgid "Exempt Devices (Whitelist)" +msgstr "è±å…设备(白åå•)" + +msgid "Remove this device from the list?" +msgstr "从列表中移除此设备?" + +msgid "Default Rate Limit" +msgstr "默认é™é€Ÿ" + +msgid "Wireless" +msgstr "无线" + +msgid "Wired" +msgstr "有线" + +msgid "Traffic Push URL" +msgstr "æµé‡æŽ¨é€URL" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "å°†æµé‡æ•°æ®æŽ¨é€è‡³è¿œç¨‹HTTP端点(POST JSON)。留空则ç¦ç”¨ã€‚" + +msgid "Device Event Push URL" +msgstr "设备事件推é€URL" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "将设备上下线事件推é€è‡³è¿œç¨‹HTTP端点(状æ€å˜åŒ–æ—¶POST JSON)。留空则ç¦ç”¨ã€‚" + +msgid "Additional Subnets" +msgstr "é¢å¤–å­ç½‘" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "é¢å¤–的本地å­ç½‘(用逗å·åˆ†éš”çš„CIDR表示法,例如'192.168.2.0/24,10.0.0.0/8')。留空则åªä½¿ç”¨æŽ¥å£å­ç½‘。" + +msgid "Exclude Interface Device" +msgstr "排除接å£è®¾å¤‡" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "从æµé‡ç»Ÿè®¡ä¸­æŽ’除路由器本身(接å£è®¾å¤‡ï¼‰" + +msgid "Enable Neighbor Flush" +msgstr "å¯ç”¨é‚»å±…表刷新" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "å¯ç”¨å®šæœŸåˆ·æ–°é‚»å±…表数æ®ã€‚若设备列表正常,通常ä¸å»ºè®®å¼€å¯ã€‚" + +msgid "Neighbor Flush Interval" +msgstr "邻居表刷新间隔" + +msgid "Set the interval for flushing neighbor table data" +msgstr "设置邻居表数æ®åˆ·æ–°çš„æ—¶é—´é—´éš”" + +msgid "No devices" +msgstr "无设备" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "LAN æµé‡æ˜¯ä»Žæ•´ä¸ªå­ç½‘视角æ¥çœ‹ï¼Œæ‰€ä»¥ä¸Šä¼ å’Œä¸‹è½½æ€»æ˜¯ç›¸ç­‰ï¼Œæ˜¯ä¸€ä¸ªé—­çŽ¯ã€‚å¦å¤–,由于专用硬件交æ¢èŠ¯ç‰‡çš„å­˜åœ¨ï¼Œå±€åŸŸç½‘ä¸­ 2 终端(比如 PC - NAS)之间的 LAN æµé‡å¯èƒ½æ— æ³•监控。" + +msgid "Protocol" +msgstr "åè®®" + +msgid "State" +msgstr "状æ€" + +msgid "Send" +msgstr "å‘é€" + +msgid "Reply" +msgstr "回å¤" + +msgid "Flags" +msgstr "标记" + +msgid "Loading…" +msgstr "加载中…" + +msgid "No connections" +msgstr "暂无连接" + +msgid "pkts" +msgstr "包" + +msgid "Failed to load" +msgstr "加载失败" + +msgid "Connection Details" +msgstr "连接详情" + +msgid "Details" +msgstr "详情" + +msgid "Orig Src" +msgstr "å‘èµ·æº" + +msgid "Orig Dst" +msgstr "å‘起目标" + +msgid "Repl Src" +msgstr "å›žå¤æº" + +msgid "Repl Dst" +msgstr "回å¤ç›®æ ‡" + +msgid "TC backend" +msgstr "TC åŽç«¯" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "选择 TC 挂载åŽç«¯ã€‚建议默认使用 auto;在内核 >= 6.6 时优先使用 tcx;旧内核使用 netlink 更稳妥。" + +msgid "TC order" +msgstr "TC 顺åº" + +msgid "Netlink priority" +msgstr "Netlink 优先级" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "仅在åŽç«¯ä¸º netlink 时使用。范围:0..65535(0 表示默认)。" + +msgid "TCX ingress anchor program id" +msgstr "TCX å…¥ç«™é”šç‚¹ç¨‹åº ID" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "当 tc_order 为 before/after 时使用。必须是åŒä¸€æŽ¥å£ä¸Šçš„æœ‰æ•ˆå…¥ç«™ç¨‹åº ID。" + +msgid "TCX egress anchor program id" +msgstr "TCX å‡ºç«™é”šç‚¹ç¨‹åº ID" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "当 tc_order 为 before/after 时使用。必须是åŒä¸€æŽ¥å£ä¸Šçš„æœ‰æ•ˆå‡ºç«™ç¨‹åº ID。" diff --git a/luci-app-bandix/po/zh_Hant/bandix.po b/luci-app-bandix/po/zh_Hant/bandix.po new file mode 100644 index 00000000..b77babc6 --- /dev/null +++ b/luci-app-bandix/po/zh_Hant/bandix.po @@ -0,0 +1,1257 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" + +msgid "Bandix Traffic Monitor" +msgstr "Bandix æµé‡ç›£æŽ§" + +msgid "Loading data..." +msgstr "正在載入數æ®..." + +msgid "Unable to fetch data" +msgstr "無法å–得數æ®" + +msgid "Unable to fetch history data" +msgstr "無法å–å¾—æ­·å²æ•¸æ®" + +msgid "Hostname" +msgstr "主機å" + +msgid "IP Address" +msgstr "IPä½å€" + +msgid "MAC Address" +msgstr "MACä½å€" + +msgid "Download Speed" +msgstr "下載速度" + +msgid "Upload Speed" +msgstr "上傳速度" + +msgid "Total Download" +msgstr "總下載é‡" + +msgid "Total Upload" +msgstr "總上傳é‡" + +msgid "Download Limit" +msgstr "下載é™é€Ÿ" + +msgid "Upload Limit" +msgstr "上傳é™é€Ÿ" + +msgid "Interface Language" +msgstr "介é¢èªžè¨€" + +msgid "Select the display language for Bandix Traffic Monitor" +msgstr "鏿“‡ Bandix æµé‡ç›£æŽ§çš„顯示语言" + +msgid "Device Info" +msgstr "設備資訊" + +msgid "Device List" +msgstr "設備清單" + +msgid "LAN Traffic" +msgstr "LAN æµé‡" + +msgid "WAN Traffic" +msgstr "WAN æµé‡" + +msgid "Network Type" +msgstr "網路類型" + +msgid "Rate Limit" +msgstr "é™é€Ÿè¨­å®š" + +msgid "Actions" +msgstr "æ“作" + +msgid "Online Devices" +msgstr "線上設備" + +msgid "WAN Only" +msgstr "ä»…é™WAN æµé‡" + +msgid "Settings" +msgstr "設定" + +msgid "Device Settings" +msgstr "設備設定" + +msgid "Rate Limits" +msgstr "é™é€Ÿè¨­å®š" + +msgid "Remove Rate Limit" +msgstr "å–æ¶ˆé™é€Ÿ" + +msgid "Save" +msgstr "儲存" + +msgid "Cancel" +msgstr "å–æ¶ˆ" + +msgid "Set Rate Limit" +msgstr "設定é™é€Ÿ" + +msgid "Device" +msgstr "設備" + +msgid "Set Hostname" +msgstr "設定主機å" + +msgid "Please enter hostname" +msgstr "請輸入主機å" + +msgid "Hostname set successfully" +msgstr "主機å設定æˆåŠŸ" + +msgid "Failed to set hostname" +msgstr "主機å設定失敗" + +msgid "Unlimited" +msgstr "ç„¡é™åˆ¶" + +msgid "Settings saved successfully" +msgstr "設定æˆåŠŸ" + +msgid "Failed to save settings" +msgstr "設定失敗" + +msgid "Please enter a valid speed value" +msgstr "請輸入有效的速度值" + +msgid "Speed value must be greater than 0" +msgstr "速度值必須大於0" + +msgid "Saving..." +msgstr "儲存中..." + +msgid "Rate limiting only applies to WAN traffic." +msgstr "é™é€ŸåŠŸèƒ½åƒ…å° WAN æµé‡ç”Ÿæ•ˆã€‚æŸäº› LAN 內部æµé‡å¯èƒ½å› ç¡¬ä»¶äº¤æ›åŠ é€Ÿæœªè¢«ç›£æŽ§ã€‚" + +msgid "Tip: Enter 0 for unlimited" +msgstr "æç¤ºï¼šè¾“å…¥ 0 表示無é™åˆ¶" + +msgid "Traffic History" +msgstr "æ­·å²æµé‡è¶¨å‹¢" + +msgid "Realtime Traffic Trends" +msgstr "峿™‚æµé‡è¶¨å‹¢åœ–" + +msgid "Select Device" +msgstr "鏿“‡è¨­å‚™" + +msgid "All Devices" +msgstr "所有設備" + +msgid "Time Range" +msgstr "時間範åœ" + +msgid "Last 5 minutes" +msgstr "最近5分é˜" + +msgid "Last 30 minutes" +msgstr "最近30分é˜" + +msgid "Last 2 hours" +msgstr "最近2å°æ™‚" + +msgid "Type" +msgstr "類型" + +msgid "Total" +msgstr "總æµé‡" + +msgid "LAN" +msgstr "LAN æµé‡" + +msgid "WAN" +msgstr "WAN æµé‡" + +msgid "Refresh" +msgstr "釿–°æ•´ç†" + +msgid "Upload Rate" +msgstr "上傳速率" + +msgid "Download Rate" +msgstr "下載速率" + +msgid "Last" +msgstr "最近" + +msgid "second" +msgstr "ç§’" + +msgid "minute" +msgstr "分é˜" + +msgid "hour" +msgstr "å°æ™‚" + +msgid "day" +msgstr "天" + +msgid "week" +msgstr "周" + +msgid "Other Rates" +msgstr "其他速率" + +msgid "Cumulative" +msgstr "累計æµé‡" + +msgid "Total Uploaded" +msgstr "總上傳" + +msgid "Total Downloaded" +msgstr "總下載" + +msgid "LAN Uploaded" +msgstr "LAN 已上傳" + +msgid "LAN Downloaded" +msgstr "LAN 已下載" + +msgid "WAN Uploaded" +msgstr "WAN 已上傳" + +msgid "WAN Downloaded" +msgstr "WAN 已下載" + +msgid "Total Upload" +msgstr "總上傳速率" + +msgid "Total Download" +msgstr "總下載速率" + +msgid "LAN Upload" +msgstr "LAN 上傳速率" + +msgid "LAN Download" +msgstr "LAN 下載速率" + +msgid "WAN Upload" +msgstr "WAN 上傳速率" + +msgid "WAN Download" +msgstr "WAN 下載速率" + +msgid "Never Online" +msgstr "從未上線" + +msgid "Just Now" +msgstr "剛剛" + +msgid "min ago" +msgstr "分é˜å‰" + +msgid "h ago" +msgstr "å°æ™‚å‰" + +msgid "days ago" +msgstr "天å‰" + +msgid "months ago" +msgstr "个月å‰" + +msgid "years ago" +msgstr "å¹´å‰" + +msgid "Last Online" +msgstr "最後上線" + +msgid "Zoom" +msgstr "縮放" + +msgid "Sort By" +msgstr "æŽ’åºæ–¹å¼" + +msgid "Online Status" +msgstr "線上狀態" + +msgid "Total Traffic" +msgstr "總æµé‡" + +msgid "Ascending" +msgstr "å‡åº" + +msgid "Descending" +msgstr "é™åº" + +msgid "Sort by Speed" +msgstr "ä¾é€Ÿåº¦æŽ’åº" + +msgid "Sort by Traffic" +msgstr "ä¾ç”¨é‡æŽ’åº" + +msgid "Simple Mode" +msgstr "簡易模å¼" + +msgid "Detailed Mode" +msgstr "詳細模å¼" + +msgid "Bandix DNS Monitor" +msgstr "Bandix DNS 監控" + +msgid "DNS Monitor" +msgstr "DNS 監控" + +msgid "DNS Query Records" +msgstr "DNS 查詢記錄" + +msgid "DNS Statistics" +msgstr "DNS 統計資訊" + +msgid "DNS Monitoring Disabled" +msgstr "DNS監控未啟用" + +msgid "Please enable DNS monitoring in settings" +msgstr "请在設定中啟用DNS監控功能" + +msgid "Go to Settings" +msgstr "å‰å¾€è¨­å®š" + +msgid "No Data" +msgstr "無資料" + +msgid "Time" +msgstr "時間" + +msgid "Domain" +msgstr "網域" + +msgid "Query Type" +msgstr "查詢類型" + +msgid "Response Code" +msgstr "回應碼" + +msgid "Response Time" +msgstr "回應時間" + +msgid "Source IP" +msgstr "來æºIP" + +msgid "Destination IP" +msgstr "目標IP" + +msgid "Response IPs" +msgstr "回應IP" + +msgid "Response Result" +msgstr "å›žæ‡‰çµæžœ" + +msgid "DNS Server" +msgstr "DNS伺æœå™¨" + +msgid "Query" +msgstr "查詢" + +msgid "Response" +msgstr "回應" + +msgid "Filter" +msgstr "篩é¸" + +msgid "Domain Filter" +msgstr "網域篩é¸" + +msgid "Device Filter" +msgstr "設備篩é¸" + +msgid "DNS Server Filter" +msgstr "DNS伺æœå™¨ç¯©é¸" + +msgid "Type Filter" +msgstr "類型篩é¸" + +msgid "All" +msgstr "全部" + +msgid "Period" +msgstr "週期" + +msgid "Display Mode" +msgstr "顯示模å¼" + +msgid "This Year" +msgstr "本年" + +msgid "Week" +msgstr "本週" + +msgid "Month" +msgstr "本月" + +msgid "Year" +msgstr "本年" + +msgid "Queries Only" +msgstr "仅查詢" + +msgid "Responses Only" +msgstr "仅回應" + +msgid "Search" +msgstr "æœå°‹" + +msgid "Search Domain" +msgstr "æœå°‹ç¶²åŸŸ" + +msgid "Search Device" +msgstr "æœå°‹è¨­å‚™" + +msgid "Search DNS Server" +msgstr "æœå°‹DNS伺æœå™¨" + +msgid "Clear" +msgstr "清除" + +msgid "Previous" +msgstr "上一é " + +msgid "Next" +msgstr "下一é " + +msgid "Page" +msgstr "第" + +msgid "of" +msgstr "é ï¼Œå…±" + +msgid "Total" +msgstr "全部" + +msgid "records" +msgstr "筆記錄" + +msgid "Per Page" +msgstr "æ¯é é¡¯ç¤º" + +msgid "" +msgstr "ç­†" + +msgid "Total Queries" +msgstr "總查詢數" + +msgid "Total Responses" +msgstr "總回應數" + +msgid "Queries with Response" +msgstr "有回應查詢" + +msgid "Queries without Response" +msgstr "無回應查詢" + +msgid "Avg Response Time" +msgstr "å¹³å‡å›žæ‡‰æ™‚é–“" + +msgid "Min Response Time" +msgstr "最快回應時間" + +msgid "Max Response Time" +msgstr "最慢回應時間" + +msgid "Success Rate" +msgstr "æˆåŠŸçŽ‡" + +msgid "Success" +msgstr "æˆåŠŸ" + +msgid "Failure" +msgstr "失敗" + +msgid "Top Domains" +msgstr "最常查詢網域" + +msgid "Top Query Types" +msgstr "最常用查詢類型" + +msgid "Top Devices" +msgstr "最活èºè¨­å‚™" + +msgid "Top DNS Servers" +msgstr "最常用DNS伺æœå™¨" + +msgid "Unique Devices" +msgstr "唯一設備數" + +msgid "ms" +msgstr "毫秒" + +msgid "minutes" +msgstr "分é˜" + +msgid "Unknown Device" +msgstr "未知設備" + +msgid "Domain not found" +msgstr "網域未找到" + +msgid "Server error" +msgstr "伺æœå™¨éŒ¯èª¤" + +msgid "Format error" +msgstr "æ ¼å¼éŒ¯èª¤" + +msgid "Refused" +msgstr "拒絕" + +msgid "Other" +msgstr "å…¶ä»–" + +msgid "Does not include DoH and DoT" +msgstr "ä¸åŒ…å« DoH å’Œ DoT" + +msgid "Latest Response Time" +msgstr "最新回應時間" + +msgid "Response Code Distribution" +msgstr "回應碼分布" + +msgid "Response Time Percentiles" +msgstr "回應時間百分ä½" + +msgid "P50" +msgstr "P50" + +msgid "P90" +msgstr "P90" + +msgid "P95" +msgstr "P95" + +msgid "P99" +msgstr "P99" + +msgid "Bandix Connection Monitor" +msgstr "Bandix 連線監控" + +msgid "Connection Monitor" +msgstr "連線監控" + +msgid "Device Connection Statistics" +msgstr "設備連線統計" + +msgid "Global Connection Statistics" +msgstr "全域連線統計" + +msgid "Active TCP" +msgstr "æ´»èºTCP" + +msgid "Active UDP" +msgstr "æ´»èºUDP" + +msgid "Closed TCP" +msgstr "已關閉TCP" + +msgid "Total Connections" +msgstr "總連線數" + +msgid "Last Updated" +msgstr "最後更新" + +msgid "TCP Connections" +msgstr "TCP連線數" + +msgid "UDP Connections" +msgstr "UDP連線數" + +msgid "Established TCP" +msgstr "已建立TCP" + +msgid "TIME_WAIT TCP" +msgstr "TIME_WAIT TCP" + +msgid "CLOSE_WAIT TCP" +msgstr "CLOSE_WAIT TCP" + +msgid "Total Devices" +msgstr "設備總數" + +msgid "Connection Monitor Disabled" +msgstr "連線監控未啟用" + +msgid "Please enable connection monitoring in settings" +msgstr "请在設定中啟用連線監控功能" + +msgid "List only shows LAN device connections, data may differ from total connections." +msgstr "清單åªé¡¯ç¤ºå€åŸŸç¶²è·¯è¨­å‚™é€£ç·šï¼Œæ•¸æ®å¯èƒ½å’Œç¸½é€£ç·šæ•¸ä¸ä¸€è‡´ã€‚" + +msgid "TCP Status Details" +msgstr "TCP 狀態詳情" + +msgid "Basic Settings" +msgstr "基本設定" + +msgid "Traffic Monitor Settings" +msgstr "æµé‡ç›£æŽ§è¨­å®š" + +msgid "Connection Monitor Settings" +msgstr "連線監控設定" + +msgid "DNS Monitor Settings" +msgstr "DNS監控設定" + +msgid "Bandix Basic Configuration" +msgstr "Bandix 基本é…ç½®" + +msgid "Configure basic parameters for Bandix service" +msgstr "é…ç½® Bandix æœå‹™çš„åŸºæœ¬å‚æ•¸" + +msgid "Bandix Traffic Monitor Configuration" +msgstr "Bandix æµé‡ç›£æŽ§é…ç½®" + +msgid "Configure traffic monitoring related parameters" +msgstr "é…ç½®æµé‡ç›£æŽ§ç›¸é—œå‚數" + +msgid "Bandix Connection Monitor Configuration" +msgstr "Bandix 連線監控é…ç½®" + +msgid "Configure connection monitoring related parameters" +msgstr "é…ç½®é€£ç·šç›£æŽ§ç›¸é—œå‚æ•¸" + +msgid "Bandix DNS Monitor Configuration" +msgstr "Bandix DNS監控é…ç½®" + +msgid "Configure DNS monitoring related parameters" +msgstr "é…ç½®DNSç›£æŽ§ç›¸é—œå‚æ•¸" + +msgid "Enable" +msgstr "啟用" + +msgid "Enable Bandix Traffic Monitor Service" +msgstr "啟用 Bandix æµé‡ç›£æŽ§æœå‹™" + +msgid "Enable Traffic Monitoring" +msgstr "啟用æµé‡ç›£æŽ§" + +msgid "Enable Connection Monitoring" +msgstr "啟用連線監控" + +msgid "Enable DNS Monitoring" +msgstr "啟用DNS監控" + +msgid "Simplified Chinese" +msgstr "简体中文" + +msgid "Traditional Chinese" +msgstr "ç¹ä½“中文" + +msgid "Port" +msgstr "連接埠" + +msgid "Port for Bandix service to listen on" +msgstr "Bandix æœå‹™ç›£è½çš„連接埠" + +msgid "TC Priority" +msgstr "TC 優先級" + +msgid "Set TC filter priority to better coexist with other eBPF TC programs. Lower numbers indicate higher priority. 0 means system-assigned." +msgstr "設置 TC filter 優先級,使得與其他 eBPF TC ç¨‹åºæ›´å¥½çš„共存,數字越å°ï¼Œå„ªå…ˆç´šè¶Šé«˜ï¼Œ0 表示由系統分é…。" + +msgid "Monitor Interface" +msgstr "監控網å¡" + +msgid "Select the LAN network interface to monitor" +msgstr "鏿“‡è¦ç›£æŽ§çš„LAN網路介é¢" + +msgid "Speed Units" +msgstr "网速單ä½" + +msgid "Select the speed display unit format" +msgstr "鏿“‡ç½‘é€Ÿé¡¯ç¤ºçš„å–®ä½æ ¼å¼" + +msgid "Bytes Units (B/s, KB/s, MB/s)" +msgstr "ä½å…ƒçµ„å–®ä½ (B/s, KB/s, MB/s)" + +msgid "Bits Units (bps, Kbps, Mbps)" +msgstr "ä½å…ƒå–®ä½ (bps, Kbps, Mbps)" + +msgid "Interface Theme" +msgstr "界é¢ä¸»é¡Œ" + +msgid "Select the display theme for Bandix Traffic Monitor" +msgstr "鏿“‡ Bandix æµé‡ç›£æŽ§çš„顯示主題" + +msgid "Follow System" +msgstr "跟隨系統" + +msgid "Light Mode" +msgstr "明亮模å¼" + +msgid "Dark Mode" +msgstr "暗黑模å¼" + +msgid "Feedback" +msgstr "æ„見回饋" + +msgid "Log Level" +msgstr "日誌層級" + +msgid "Set the log level for Bandix service" +msgstr "設定 Bandix æœå‹™çš„æ—¥èªŒå±¤ç´š" + +msgid "Offline Timeout" +msgstr "離線超时時間" + +msgid "Set the timeout for device offline detection (seconds). Devices inactive for longer than this time will be marked as offline" +msgstr "è¨­å®šè¨­å‚™é›¢ç·šåˆ¤æ–·çš„è¶…æ—¶æ™‚é–“ï¼ˆç§’ï¼‰ã€‚è¶…éŽæ­¤æ™‚間未活動的設備将被標記为離線" + +msgid "Realtime Traffic Period" +msgstr "峿™‚æµé‡é€±æœŸ" + +msgid "10 minutes interval uses about 60 KB per device" +msgstr "10åˆ†é˜æ­·å²é€±æœŸï¼Œæ¯ä¸ªè¨­å‚™ä½”用 60KB" + +msgid "Data Flush Interval" +msgstr "æ•¸æ® flush é–“éš”" + +msgid "Set the interval for flushing data to disk" +msgstr "設定數æ®å¯«å…¥ç£ç¢Ÿçš„æ™‚é–“é–“éš”" + +msgid "1 minute" +msgstr "1 分é˜" + +msgid "5 minutes" +msgstr "5 分é˜" + +msgid "10 minutes" +msgstr "10 分é˜" + +msgid "15 minutes" +msgstr "15 分é˜" + +msgid "20 minutes" +msgstr "20 分é˜" + +msgid "25 minutes" +msgstr "25 分é˜" + +msgid "30 minutes" +msgstr "30 分é˜" + +msgid "1 hour" +msgstr "1 å°æ™‚" + +msgid "2 hours" +msgstr "2 å°æ™‚" + +msgid "12 hours" +msgstr "12 å°æ™‚" + +msgid "24 hours" +msgstr "24 å°æ™‚" + +msgid "Data Directory" +msgstr "數æ®ç›®å½•" + +msgid "If you change the directory, please manually add it to the backup directory" +msgstr "如果更改了目錄,請手動添加到備份目錄" + +msgid "Bandix data storage directory" +msgstr "Bandix 數æ®å„²å­˜ç›®éŒ„" + +msgid "Enable Bandix connection monitoring" +msgstr "啟用 Bandix 連線監控功能" + +msgid "Enable Bandix DNS monitoring" +msgstr "啟用 Bandix DNS監控功能" + +msgid "DNS Max Records" +msgstr "DNS最大记录數" + +msgid "Set the maximum number of DNS query records to keep. Older records will be deleted when this limit is exceeded" +msgstr "設定DNS查詢記錄的最大儲存數é‡ï¼Œè¶…éŽæ­¤æ•¸é‡å°†åˆªé™¤æœ€èˆŠçš„记录" + +msgid "Persist DNS Data" +msgstr "æŒä¹…化DNS數據" + +msgid "Enable DNS data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "啟用DNS數據æŒä¹…åŒ–åŠŸèƒ½ï¼Œåªæœ‰å•Ÿç”¨æ­¤é¸é …å¾Œæ‰æœƒæŒä¹…化到ç£ç¢Ÿ" + +msgid "DNS Data Flush Interval" +msgstr "DNS數據 flush é–“éš”" + +msgid "Set the interval for flushing DNS data to disk" +msgstr "設定DNS數據寫入ç£ç¢Ÿçš„æ™‚é–“é–“éš”" + +msgid "Persist History Data" +msgstr "æŒä¹…åŒ–æ­·å²æ•¸æ®" + +msgid "Enable data persistence functionality, data will only be persisted to disk when this option is enabled" +msgstr "å•Ÿç”¨æ•¸æ®æŒä¹…åŒ–åŠŸèƒ½ï¼Œåªæœ‰å•Ÿç”¨æ­¤é€‰é¡¹åŽæ‰æœƒæŒä¹…化到ç£ç¢Ÿ" + +msgid "Does not occupy storage space, stored only in memory" +msgstr "ä¸ä½”用存儲空間,僅存儲在內存中" + +msgid "Query & Response" +msgstr "查詢與響應" + +msgid "Queries" +msgstr "查詢" + +msgid "Responses" +msgstr "響應" + +msgid "Average Response Time" +msgstr "å¹³å‡éŸ¿æ‡‰æ™‚é–“" + +msgid "Show More" +msgstr "顯示更多" + +msgid "Show Less" +msgstr "顯示更少" + +msgid "Add Schedule Rule" +msgstr "新增定時é™é€Ÿè¦å‰‡" + +msgid "Add Rule" +msgstr "新增è¦å‰‡" + +msgid "Set rate limit rules for different time periods" +msgstr "為ä¸åŒæ™‚間段設定é™é€Ÿè¦å‰‡" + +msgid "Time Slot" +msgstr "時間段" + +msgid "Days of Week" +msgstr "星期" + +msgid "Mon" +msgstr "週一" + +msgid "Tue" +msgstr "週二" + +msgid "Wed" +msgstr "週三" + +msgid "Thu" +msgstr "週四" + +msgid "Fri" +msgstr "週五" + +msgid "Sat" +msgstr "週六" + +msgid "Sun" +msgstr "週日" + +msgid "Adding..." +msgstr "新增中..." + +msgid "Failed to add schedule rule: " +msgstr "新增定時é™é€Ÿè¦å‰‡å¤±æ•—:" + +msgid "Please set time slot" +msgstr "請設定時間段" + +msgid "Please select at least one day" +msgstr "è«‹è‡³å°‘é¸æ“‡ä¸€å¤©" + +msgid "No scheduled rules yet, click \"Add Rule\" to start setting" +msgstr "還沒有定時é™é€Ÿè¦å‰‡ï¼Œé»žæ“Š"新增è¦å‰‡"開始設定" + +msgid "Loading..." +msgstr "載入中..." + +msgid "Loading in chunks, please wait... (%d/%d)" +msgstr "分段載入中,請ç¨å€™... (%d/%d)" + +msgid "No schedule rules" +msgstr "沒有定時é™é€Ÿè¦å‰‡" + +msgid "Failed to load schedule rules" +msgstr "載入定時é™é€Ÿè¦å‰‡å¤±æ•—" + +msgid "Delete Schedule Rule" +msgstr "刪除定時é™é€Ÿè¦å‰‡" + +msgid "Are you sure you want to delete this schedule rule?" +msgstr "確定è¦åˆªé™¤é€™å€‹å®šæ™‚é™é€Ÿè¦å‰‡å—Žï¼Ÿ" + +msgid "Failed to delete schedule rule" +msgstr "刪除定時é™é€Ÿè¦å‰‡å¤±æ•—" + +msgid "Delete Device" +msgstr "刪除設備" + +msgid "Are you sure you want to delete this device? Traffic history will be removed." +msgstr "確定è¦åˆªé™¤è©²è¨­å‚™å—Žï¼Ÿæµé‡æ­·å²å°‡è¢«æ¸…除。" + +msgid "Failed to delete device" +msgstr "刪除設備失敗" + +msgid "Confirm" +msgstr "確èª" + +msgid "Close" +msgstr "關閉" + +msgid "rule" +msgstr "è¦å‰‡" + +msgid "rules" +msgstr "è¦å‰‡" + +msgid "more" +msgstr "更多" + +msgid "No active rule" +msgstr "無生效è¦å‰‡" + +msgid "Schedule Rules" +msgstr "定時é™é€Ÿè¦å‰‡" + +msgid "Upload Statistics" +msgstr "上傳統計" + +msgid "Download Statistics" +msgstr "下載統計" + +msgid "Cumulative Traffic" +msgstr "累計æµé‡" + +msgid "Daily" +msgstr "æ¯æ—¥" + +msgid "Weekly" +msgstr "æ¯é€±" + +msgid "Monthly" +msgstr "æ¯æœˆ" + +msgid "Statistics" +msgstr "統計" + +msgid "Average" +msgstr "å¹³å‡å€¼" + +msgid "Maximum" +msgstr "最大值" + +msgid "Minimum" +msgstr "最å°å€¼" + +msgid "WAN Upload" +msgstr "WAN 上傳" + +msgid "WAN Download" +msgstr "WAN 下載" + +msgid "WAN Uploaded" +msgstr "WAN 上傳é‡" + +msgid "WAN Downloaded" +msgstr "WAN 下載é‡" + +msgid "Clear Traffic Data" +msgstr "刪除æµé‡æ•¸æ“š" + +msgid "Are you sure you want to clear all traffic data? This action cannot be undone." +msgstr "ç¢ºå®šè¦æ¸…除所有æµé‡æ•¸æ“šå—Žï¼Ÿæ­¤æ“作無法撤銷。" + +msgid "Failed to clear traffic data: " +msgstr "清除æµé‡æ•¸æ“šå¤±æ•—:" + +msgid "Restart Service" +msgstr "é‡å•Ÿæœå‹™" + +msgid "Restart Bandix Service" +msgstr "é‡å•Ÿ Bandix æœå‹™" + +msgid "Are you sure you want to restart the Bandix service?" +msgstr "確定è¦é‡å•Ÿ Bandix æœå‹™å—Žï¼Ÿ" + +msgid "Failed to restart service: " +msgstr "é‡å•Ÿæœå‹™å¤±æ•—:" + +msgid "Realtime" +msgstr "峿™‚" + +msgid "Last 24 Hours" +msgstr "最近24å°æ™‚" + +msgid "Last 7 Days" +msgstr "最近7天" + +msgid "Last 30 Days" +msgstr "最近30天" + +msgid "Last 10 Minutes" +msgstr "最近10分é˜" + +msgid "Last 15 Minutes" +msgstr "最近15分é˜" + +msgid "Last 30 Minutes" +msgstr "最近30分é˜" + +msgid "Last 1 Hour" +msgstr "最近1å°æ™‚" + +msgid "Starting installation..." +msgstr "開始安è£..." + +msgid "Page will refresh in 3 seconds." +msgstr "é é¢å°‡åœ¨3ç§’å¾Œé‡æ–°æ•´ç†ã€‚" + +msgid "Installation failed" +msgstr "安è£å¤±æ•—" + +msgid "Installation failed at step: " +msgstr "安è£åœ¨æ­¥é©Ÿå¤±æ•—:" + +msgid "Details: " +msgstr "詳細資訊:" + +msgid "Installation failed: " +msgstr "安è£å¤±æ•—:" + +msgid "Unknown error" +msgstr "未知錯誤" + +msgid "Service restarted successfully." +msgstr "æœå‹™é‡å•ŸæˆåŠŸã€‚" + +msgid "Service restart may have failed. Please check manually." +msgstr "æœå‹™é‡å•Ÿå¯èƒ½å¤±æ•—,請手動檢查。" + +msgid "Please restart the service." +msgstr "è«‹é‡å•Ÿæœå‹™ã€‚" + +msgid "LuCI App updated successfully!" +msgstr "LuCI 應用更新æˆåŠŸï¼" + +msgid "Bandix updated successfully!" +msgstr "Bandix æ›´æ–°æˆåŠŸï¼" + +msgid "LuCI App has update: " +msgstr "LuCI 應用有更新:" + +msgid "Bandix has update: " +msgstr "Bandix 有更新:" + +msgid "LuCI App is up to date: " +msgstr "LuCI 應用已是最新版本:" + +msgid "Bandix is up to date: " +msgstr "Bandix 已是最新版本:" + +msgid "Updates Available" +msgstr "有å¯ç”¨æ›´æ–°" + +msgid "No Updates Available" +msgstr "ç„¡å¯ç”¨æ›´æ–°" + +msgid "Detected Architecture" +msgstr "檢測到的架構" + +msgid "Package Manager" +msgstr "套件管ç†å™¨" + +msgid "LuCI Assets" +msgstr "LuCI 資æº" + +msgid "Bandix Assets" +msgstr "Bandix 資æº" + +msgid "Failed to check for updates" +msgstr "檢查更新失敗" + +msgid "Failed to check for updates: " +msgstr "檢查更新失敗:" + +msgid "Checking..." +msgstr "檢查中..." + +msgid "Check for Updates" +msgstr "檢查更新" + +msgid "Installing..." +msgstr "安è£ä¸­..." + +msgid "Download and Install" +msgstr "下載並安è£" + +msgid "Manual Download" +msgstr "手動下載" + +msgid "Close" +msgstr "關閉" + +msgid "Starting installation... The page will refresh automatically in 30 seconds." +msgstr "開始安è£... é é¢å°‡åœ¨30ç§’å¾Œè‡ªå‹•é‡æ–°æ•´ç†ã€‚" + +msgid "Please clear your browser cache manually after updating." +msgstr "更新後請手動清空ç€è¦½å™¨å¿«å–。" + +msgid "Traffic Statistics" +msgstr "æµé‡çµ±è¨ˆ" + +msgid "Traffic Statistics" +msgstr "æµé‡çµ±è¨ˆ" + +msgid "Device Usage Ranking" +msgstr "è¨­å‚™ç”¨é‡æŽ’è¡Œ" + +msgid "Start Date" +msgstr "開始日期" + +msgid "End Date" +msgstr "çµæŸæ—¥æœŸ" + +msgid "Reset" +msgstr "é‡ç½®" + +msgid "Today" +msgstr "今天" + +msgid "This Week" +msgstr "本週" + +msgid "Last Week" +msgstr "上週" + +msgid "This Month" +msgstr "本月" + +msgid "Last Month" +msgstr "上月" + +msgid "Last 90 Days" +msgstr "最近90天" + +msgid "Last Year" +msgstr "最近一年" + +msgid "Traffic Timeline" +msgstr "æµé‡æ™‚é–“ç·š" + +msgid "Aggregation:" +msgstr "èšåˆæ–¹å¼ï¼š" + +msgid "Hourly" +msgstr "æŒ‰å°æ™‚" + +msgid "Device:" +msgstr "設備:" + +msgid "Traffic Push URL" +msgstr "æµé‡æŽ¨é€URL" + +msgid "Push traffic data to a remote HTTP endpoint (POST JSON). Leave empty to disable." +msgstr "å°‡æµé‡æ•¸æ“šæŽ¨é€è‡³é ç¨‹HTTP端點(POST JSON)。留空則ç¦ç”¨ã€‚" + +msgid "Device Event Push URL" +msgstr "設備事件推é€URL" + +msgid "Push device online/offline events to a remote HTTP endpoint (POST JSON on state change). Leave empty to disable." +msgstr "將設備上下線事件推é€è‡³é ç¨‹HTTP端點(狀態變化時POST JSON)。留空則ç¦ç”¨ã€‚" + +msgid "Additional Subnets" +msgstr "é¡å¤–å­ç¶²" + +msgid "Additional local subnets (comma-separated CIDR notation, e.g. '192.168.2.0/24,10.0.0.0/8'). Leave empty to use only interface subnet." +msgstr "é¡å¤–的本地å­ç¶²ï¼ˆç”¨é€—號分隔的CIDR表示法,例如'192.168.2.0/24,10.0.0.0/8')。留空則åªä½¿ç”¨æŽ¥å£å­ç¶²ã€‚" + +msgid "Exclude Interface Device" +msgstr "排除介é¢è¨­å‚™" + +msgid "Exclude the router itself (interface device) from traffic statistics" +msgstr "從æµé‡çµ±è¨ˆä¸­æŽ’除路由器本身(介é¢è¨­å‚™ï¼‰" + +msgid "Enable Neighbor Flush" +msgstr "啟用鄰居表刷新" + +msgid "Enable periodic flush of neighbor table data. Generally not recommended if the device list works normally." +msgstr "啟用定期刷新鄰居表數據。若設備列表正常,通常ä¸å»ºè­°é–‹å•Ÿã€‚" + +msgid "Neighbor Flush Interval" +msgstr "鄰居表刷新間隔" + +msgid "Set the interval for flushing neighbor table data" +msgstr "設置鄰居表數據刷新的時間間隔" + +msgid "No devices" +msgstr "無設備" + +msgid "LAN Traffic is viewed from the entire subnet perspective, so upload and download are always equal, forming a closed loop. Additionally, due to the presence of dedicated hardware switching chips, LAN traffic between 2 devices (e.g., PC - NAS) within the local network may not be monitorable." +msgstr "LAN æµé‡æ˜¯å¾žæ•´å€‹å­ç¶²è¦–角來看,所以上傳和下載總是相等,是一個閉環。å¦å¤–ï¼Œç”±æ–¼å°ˆç”¨ç¡¬é«”äº¤æ›æ™¶ç‰‡çš„存在,å€åŸŸç¶²è·¯ä¸­ 2 終端(比如 PC - NAS)之間的 LAN æµé‡å¯èƒ½ç„¡æ³•監控。" + +msgid "Protocol" +msgstr "å”定" + +msgid "State" +msgstr "狀態" + +msgid "Send" +msgstr "發é€" + +msgid "Reply" +msgstr "回覆" + +msgid "Flags" +msgstr "標記" + +msgid "Loading…" +msgstr "載入中…" + +msgid "No connections" +msgstr "暫無連線" + +msgid "pkts" +msgstr "å°åŒ…" + +msgid "Failed to load" +msgstr "載入失敗" + +msgid "Connection Details" +msgstr "連線詳情" + +msgid "Details" +msgstr "詳情" + +msgid "Orig Src" +msgstr "發起æº" + +msgid "Orig Dst" +msgstr "發起目標" + +msgid "Repl Src" +msgstr "回覆æº" + +msgid "Repl Dst" +msgstr "回覆目標" + +msgid "TC backend" +msgstr "TC 後端" + +msgid "Select TC attach backend. Recommendation: use auto by default; tcx is preferred on kernel >= 6.6; netlink is safer on older kernels." +msgstr "鏿“‡ TC 掛載後端。建議é è¨­ä½¿ç”¨ auto;在內核 >= 6.6 時優先使用 tcx;較舊內核使用 netlink 更穩妥。" + +msgid "TC order" +msgstr "TC é †åº" + +msgid "Netlink priority" +msgstr "Netlink 優先級" + +msgid "Only used when backend is netlink. Range: 0..65535 (0 means default)." +msgstr "僅在後端為 netlink 時使用。範åœï¼š0..65535(0 表示é è¨­ï¼‰ã€‚" + +msgid "TCX ingress anchor program id" +msgstr "TCX å…¥ç«™éŒ¨é»žç¨‹å¼ ID" + +msgid "Used when tc_order is before/after. Must be a valid ingress program id on the same interface." +msgstr "ç•¶ tc_order 為 before/after 時使用。必須是åŒä¸€ä»‹é¢ä¸Šçš„æœ‰æ•ˆå…¥ç«™ç¨‹å¼ ID。" + +msgid "TCX egress anchor program id" +msgstr "TCX å‡ºç«™éŒ¨é»žç¨‹å¼ ID" + +msgid "Used when tc_order is before/after. Must be a valid egress program id on the same interface." +msgstr "ç•¶ tc_order 為 before/after 時使用。必須是åŒä¸€ä»‹é¢ä¸Šçš„æœ‰æ•ˆå‡ºç«™ç¨‹å¼ ID。" diff --git a/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix b/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix new file mode 100755 index 00000000..d4bdec52 --- /dev/null +++ b/luci-app-bandix/root/usr/libexec/rpcd/luci.bandix @@ -0,0 +1,1798 @@ +#!/bin/sh +# Copyright 2025 timsaya + +. /usr/share/libubox/jshn.sh + +# 从UCIé…置读å–端å£å·ï¼Œå¦‚果读å–失败则使用默认端å£8686 +BANDIX_PORT=$(uci get bandix.general.port 2>/dev/null || echo "8686") +readonly BANDIX_API_BASE="http://127.0.0.1:$BANDIX_PORT" +readonly BANDIX_DEVICES_API="$BANDIX_API_BASE/api/traffic/devices" +readonly BANDIX_LIMITS_API="$BANDIX_API_BASE/api/traffic/limits" +readonly BANDIX_METRICS_API="$BANDIX_API_BASE/api/traffic/metrics" +readonly BANDIX_CONNECTION_API="$BANDIX_API_BASE/api/connection/devices" +readonly BANDIX_CONNECTION_FLOWS_API="$BANDIX_API_BASE/api/connection/flows" +readonly BANDIX_DNS_QUERIES_API="$BANDIX_API_BASE/api/dns/queries" +readonly BANDIX_DNS_STATS_API="$BANDIX_API_BASE/api/dns/stats" +readonly BANDIX_SCHEDULE_LIMITS_API="$BANDIX_API_BASE/api/traffic/limits/schedule" +readonly BANDIX_TRAFFIC_USAGE_RANKING_API="$BANDIX_API_BASE/api/traffic/usage/ranking" +readonly BANDIX_TRAFFIC_USAGE_INCREMENTS_API="$BANDIX_API_BASE/api/traffic/usage/increments" +readonly BANDIX_RATE_LIMIT_WHITELIST_API="$BANDIX_API_BASE/api/traffic/rate_limit/whitelist" +readonly BANDIX_RATE_LIMIT_WHITELIST_ENABLED_API="$BANDIX_API_BASE/api/traffic/rate_limit/whitelist/enabled" +readonly BANDIX_RATE_LIMIT_DEFAULT_API="$BANDIX_API_BASE/api/traffic/rate_limit/default" + +# 通用函数:创建简å•çš„JSONå“应 +make_value() { + json_init + json_add_string "$1" "$2" + json_dump + json_cleanup +} + +# 通用函数:创建错误å“应 +make_error() { + json_init + json_add_boolean "success" 0 + json_add_string "error" "$1" + json_dump + json_cleanup +} + +# 通用函数:创建æˆåŠŸå“应 +make_success() { + json_init + json_add_boolean "success" 1 + [ -n "$1" ] && json_add_string "message" "$1" + json_dump + json_cleanup +} + +# 转义JSON字符串 +escape_json_string() { + echo "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g; s/\r/\\r/g; s/\t/\\t/g' +} + +get_rate_limit_whitelist() { + local response=$(curl -s --connect-timeout 2 --max-time 5 -X GET "$BANDIX_RATE_LIMIT_WHITELIST_API" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +set_rate_limit_whitelist_enabled() { + local enabled_raw="$1" + local enabled="false" + case "$enabled_raw" in + 1|true|TRUE|True) + enabled="true" + ;; + esac + + local request_data="{\"enabled\": $enabled}" + local response=$(curl -s --connect-timeout 3 --max-time 10 -X POST -H "Content-Type: application/json" -d "$request_data" "$BANDIX_RATE_LIMIT_WHITELIST_ENABLED_API" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +add_rate_limit_whitelist_mac() { + local mac="$1" + if [ -z "$mac" ]; then + make_error "MAC address is required" + return + fi + + local mac_escaped=$(escape_json_string "$mac") + local request_data="{\"mac\": \"$mac_escaped\"}" + local response=$(curl -s --connect-timeout 3 --max-time 10 -X POST -H "Content-Type: application/json" -d "$request_data" "$BANDIX_RATE_LIMIT_WHITELIST_API" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +delete_rate_limit_whitelist_mac() { + local mac="$1" + if [ -z "$mac" ]; then + make_error "MAC address is required" + return + fi + + local mac_escaped=$(escape_json_string "$mac") + local request_data="{\"mac\": \"$mac_escaped\"}" + local response=$(curl -s --connect-timeout 3 --max-time 10 -X DELETE -H "Content-Type: application/json" -d "$request_data" "$BANDIX_RATE_LIMIT_WHITELIST_API" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +set_default_rate_limit() { + local wan_rx_rate_limit="$1" + local wan_tx_rate_limit="$2" + + if [ -z "$wan_rx_rate_limit" ] || [ -z "$wan_tx_rate_limit" ]; then + make_error "Missing parameters" + return + fi + + local request_data="{ + \"wan_rx_rate_limit\": $wan_rx_rate_limit, + \"wan_tx_rate_limit\": $wan_tx_rate_limit + }" + + local response=$(curl -s --connect-timeout 3 --max-time 10 -X POST -H "Content-Type: application/json" -d "$request_data" "$BANDIX_RATE_LIMIT_DEFAULT_API" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +# 删除设备 +delete_device() { + local mac="$1" + if [ -z "$mac" ]; then + make_error "MAC address is required" + return + fi + + local mac_escaped=$(escape_json_string "$mac") + local request_data="{\"mac\": \"$mac_escaped\"}" + local response=$(curl -s --connect-timeout 3 --max-time 10 -X DELETE -H "Content-Type: application/json" -d "$request_data" "$BANDIX_DEVICES_API" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +# 获å–è®¾å¤‡çŠ¶æ€ +# GET /api/traffic/devices -> $.data +# { +# d: [{ +# mac, # MAC åœ°å€ +# ip4, # IPv4 åœ°å€ +# ip6, # IPv6 地å€åˆ—表 +# host, # 主机å +# conn, # 接入类型 (wifi/wired/router) +# uplink, # 接入接å£å (eth1/lan2/phy0-ap0),无则空串 +# w_ch, # WiFi 频é“å· (1/36/149)ï¼Œéž WiFi 为 0 +# last, # 最åŽåœ¨çº¿æ—¶é—´æˆ³(ms) +# t_rx_b, t_tx_b, # 总下/上行字节 +# t_rx_r, t_tx_r, # 总下/上行速率 +# w_rx_b, w_tx_b, # WAN 下/上行字节 +# w_rx_r, w_tx_r, # WAN 下/上行速率 +# w_rx_l, w_tx_l, # WAN 下/上行é™é€Ÿ +# l_rx_b, l_tx_b, # LAN 下/上行字节 +# l_rx_r, l_tx_r # LAN 下/上行速率 +# }] +# } +get_device_status() { + local url="$BANDIX_DEVICES_API" + local start_ms="$1" + local end_ms="$2" + + local query_params="" + if [ -n "$start_ms" ] && [ "$start_ms" != "null" ] && [ "$start_ms" != "undefined" ]; then + query_params="${query_params}start_ms=$start_ms&" + fi + if [ -n "$end_ms" ] && [ "$end_ms" != "null" ] && [ "$end_ms" != "undefined" ]; then + query_params="${query_params}end_ms=$end_ms&" + fi + query_params=$(echo "$query_params" | sed 's/&$//') + [ -n "$query_params" ] && url="${url}?${query_params}" + + local api_result=$(curl -s --connect-timeout 2 --max-time 5 "$url" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$api_result" ]; then + echo '{"d":[]}' + return + fi + + # æå– data 部分并返回 + local data_part=$(echo "$api_result" | jsonfilter -e '$.data' 2>/dev/null) + if [ -n "$data_part" ]; then + echo "$data_part" + else + echo '{"d":[]}' + fi +} + +# 获å–åŽ†å²æŒ‡æ ‡ï¼ˆå¯é€‰MAC) +get_metrics() { + local mac="$1" + local url="$BANDIX_METRICS_API" + if [ -n "$mac" ]; then + # 转义MAC + local mac_escaped=$(echo "$mac" | sed 's/\//\\\//g') + url="$url?mac=$mac_escaped" + fi + + # logger "luci.bandix.metrics: entering mac=$mac url=$url" + local api_result=$(curl -s --connect-timeout 1 --max-time 3 "$url" 2>/dev/null) + local curl_exit_code=$? + # logger "luci.bandix.metrics: curl finished with exit code: $curl_exit_code" + + if [ $curl_exit_code -ne 0 ] || [ -z "$api_result" ]; then + # logger "luci.bandix.metrics: curl failed or empty response, returning empty metrics" + # 返回空结果(原始格å¼ï¼‰ + echo '{"retention_seconds":600,"mac":"","metrics":[]}' + return + fi + + # 使用 jsonfilter æå– data éƒ¨åˆ†ï¼ˆæ ¹æ®æ–‡æ¡£ï¼Œè¿™æ˜¯å¤„ç†å¤§JSONçš„æŽ¨èæ–¹å¼ï¼‰ + local data_part=$(echo "$api_result" | jsonfilter -e '$.data' 2>/dev/null) + if [ -n "$data_part" ]; then + local data_size=${#data_part} + # logger "luci.bandix.metrics: extracted data part using jsonfilter, size: $data_size bytes" + echo "$data_part" + return + else + # logger "luci.bandix.metrics: jsonfilter failed to extract data part" + echo '{"retention_seconds":600,"mac":"","metrics":[]}' + fi +} + +# 设置设备主机å绑定 +set_device_hostname() { + local mac="$1" + local hostname="$2" + + # logger "luci.bandix: set_device_hostname 傿•°: mac=$mac hostname=$hostname" + + # 验è¯å‚æ•° + if [ -z "$mac" ]; then + make_error "MAC address is required" + return + fi + + # hostnameå¯ä»¥ä¸ºç©ºï¼Œè¡¨ç¤ºåˆ é™¤ç»‘定 + if [ -z "$hostname" ]; then + hostname="" + fi + + # 转义特殊字符 + local mac_escaped=$(escape_json_string "$mac") + local hostname_escaped=$(escape_json_string "$hostname") + + # æž„å»ºè¯·æ±‚æ•°æ® + local request_data="{ + \"mac\": \"$mac\", + \"hostname\": \"$hostname\" + }" + + # 记录请求数æ®ï¼ˆç”¨äºŽè°ƒè¯•) + # logger "luci.bandix: hostname request_data=$request_data" + + # å‘é€è¯·æ±‚到bandix API + local bindings_api="$BANDIX_API_BASE/api/traffic/bindings" + local response=$(curl -s --connect-timeout 3 --max-time 10 -X POST -H "Content-Type: application/json" -d "$request_data" "$bindings_api" 2>/dev/null) + + # logger "luci.bandix: hostname API response=$response" + + if [ $? -eq 0 ] && [ -n "$response" ]; then + # 检查APIå“应是å¦åŒ…å«successçŠ¶æ€ + if echo "$response" | grep -q '"status":\s*"success"'; then + make_success "Hostname binding set successfully" + else + # API返回了å“åº”ä½†ä¸æ˜¯successçŠ¶æ€ + json_init + json_add_boolean "success" 0 + json_add_string "error" "API returned error response" + json_add_string "response" "$response" + json_dump + json_cleanup + fi + else + make_error "Failed to set hostname binding" + fi +} + +# 获å–è¿žæŽ¥ç›‘æŽ§æ•°æ® +# GET /api/connection/devices -> raw response (no $.data extraction) +# { +# status, data: { +# cnt, # è®¾å¤‡æ•°é‡ +# last, # æœ€åŽæ›´æ–°æ—¶é—´æˆ³(ms) +# g: { # 全局连接统计 +# total, # 总连接数 +# tcp, udp, # TCP/UDP 连接数 +# tcp_est, tcp_tw, tcp_cw, # ESTABLISHED/TIME_WAIT/CLOSE_WAIT +# last # æœ€åŽæ›´æ–°æ—¶é—´æˆ³(ms) +# }, +# d: [{ # å„设备连接统计 +# mac, ip4, host, # 设备标识 +# total, tcp, udp, # 总/TCP/UDP 连接数 +# tcp_est, tcp_tw, tcp_cw, # ESTABLISHED/TIME_WAIT/CLOSE_WAIT +# last # æœ€åŽæ›´æ–°æ—¶é—´æˆ³(ms) +# }] +# } +# } +get_connection_devices() { + # 检查连接监控是å¦å¯ç”¨ + local connection_enabled=$(uci get bandix.connections.enabled 2>/dev/null) + if [ "$connection_enabled" != "1" ]; then + make_error "Connection monitoring is not enabled" + return + fi + + # 从 Bandix API 获å–è¿žæŽ¥æ•°æ® + local response=$(curl -s --connect-timeout 2 --max-time 5 -X GET "$BANDIX_CONNECTION_API" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + + # 直接返回API结果 + echo "$response" +} + +get_connection_flows() { + local connection_enabled=$(uci get bandix.connections.enabled 2>/dev/null) + if [ "$connection_enabled" != "1" ]; then + make_error "Connection monitoring is not enabled" + return + fi + + local ip="$1" + local protocol="$2" + local state="$3" + local page="$4" + local page_size="$5" + + local query_params="" + [ -n "$ip" ] && query_params="${query_params}ip=$(printf '%s' "$ip" | sed 's/ /%20/g')&" + [ -n "$protocol" ] && query_params="${query_params}protocol=$(printf '%s' "$protocol" | sed 's/ /%20/g')&" + [ -n "$state" ] && query_params="${query_params}state=$(printf '%s' "$state" | sed 's/ /%20/g')&" + [ -n "$page" ] && query_params="${query_params}page=$page&" + [ -n "$page_size" ] && query_params="${query_params}page_size=$page_size&" + query_params=$(echo "$query_params" | sed 's/&$//') + + local url="$BANDIX_CONNECTION_FLOWS_API" + [ -n "$query_params" ] && url="${url}?${query_params}" + + local response=$(curl -s --connect-timeout 2 --max-time 5 -X GET "$url" 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + echo "$response" +} + +# èŽ·å– DNS 查询记录 +get_dns_queries() { + # 检查 DNS 监控是å¦å¯ç”¨ + local dns_enabled=$(uci get bandix.dns.enabled 2>/dev/null) + if [ "$dns_enabled" != "1" ]; then + make_error "DNS monitoring is not enabled" + return + fi + + # æž„å»ºæŸ¥è¯¢å‚æ•° + local query_params="" + local domain="$1" + local device="$2" + local is_query="$3" + local dns_server="$4" + local query_type="$5" + local page="$6" + local page_size="$7" + + [ -n "$domain" ] && query_params="${query_params}domain=$(printf '%s' "$domain" | sed 's/ /%20/g')&" + [ -n "$device" ] && query_params="${query_params}device=$(printf '%s' "$device" | sed 's/ /%20/g')&" + [ -n "$is_query" ] && query_params="${query_params}is_query=$is_query&" + [ -n "$dns_server" ] && query_params="${query_params}dns_server=$(printf '%s' "$dns_server" | sed 's/ /%20/g')&" + [ -n "$query_type" ] && query_params="${query_params}query_type=$(printf '%s' "$query_type" | sed 's/ /%20/g')&" + [ -n "$page" ] && query_params="${query_params}page=$page&" + [ -n "$page_size" ] && query_params="${query_params}page_size=$page_size&" + + # 移除末尾的 & + query_params=$(echo "$query_params" | sed 's/&$//') + + local url="$BANDIX_DNS_QUERIES_API" + [ -n "$query_params" ] && url="${url}?${query_params}" + + # 从 Bandix API èŽ·å– DNS æŸ¥è¯¢æ•°æ® + local response=$(curl -s --connect-timeout 2 --max-time 10 -X GET "$url" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + + # 直接返回API结果 + echo "$response" +} + +# èŽ·å– DNS ç»Ÿè®¡ä¿¡æ¯ +get_dns_stats() { + # 检查 DNS 监控是å¦å¯ç”¨ + local dns_enabled=$(uci get bandix.dns.enabled 2>/dev/null) + if [ "$dns_enabled" != "1" ]; then + make_error "DNS monitoring is not enabled" + return + fi + + # 从 Bandix API èŽ·å– DNS ç»Ÿè®¡æ•°æ® + local response=$(curl -s --connect-timeout 2 --max-time 10 -X GET "$BANDIX_DNS_STATS_API" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + + # 直接返回API结果 + echo "$response" +} + +# 获å–è®¾å¤‡ç”¨é‡æŽ’è¡Œ +# GET /api/traffic/usage/ranking -> $.data +# { +# start, end, # 统计时间范围(ms) +# net, # 网络类型 (wan/lan/all) +# cnt, # è®¾å¤‡æ•°é‡ +# t_b, t_rx_b, t_tx_b, # 总/下/上行字节 +# r: [{ +# mac, ip4, host, # 设备标识 +# r, # 排å +# pct, # å æ¯”(%) +# t_b, rx_b, tx_b # 总/下/上行字节 +# }] +# } +get_traffic_usage_ranking() { + local start_ms="$1" + local end_ms="$2" + local network_type="$3" + + # æž„å»ºæŸ¥è¯¢å‚æ•°ï¼ˆåªæ·»åŠ éžç©ºä¸”æœ‰æ•ˆçš„å‚æ•°ï¼‰ + local query_params="" + # 检查 start_ms æ˜¯å¦æœ‰æ•ˆï¼ˆéžç©ºä¸”䏿˜¯ "null" 或 "undefined") + if [ -n "$start_ms" ] && [ "$start_ms" != "null" ] && [ "$start_ms" != "undefined" ]; then + query_params="${query_params}start_ms=$start_ms&" + fi + # 检查 end_ms æ˜¯å¦æœ‰æ•ˆ + if [ -n "$end_ms" ] && [ "$end_ms" != "null" ] && [ "$end_ms" != "undefined" ]; then + query_params="${query_params}end_ms=$end_ms&" + fi + # 检查 network_type æ˜¯å¦æœ‰æ•ˆ + if [ -n "$network_type" ] && [ "$network_type" != "null" ] && [ "$network_type" != "undefined" ]; then + query_params="${query_params}network_type=$network_type&" + fi + + # 移除末尾的 & + query_params=$(echo "$query_params" | sed 's/&$//') + + local url="$BANDIX_TRAFFIC_USAGE_RANKING_API" + [ -n "$query_params" ] && url="${url}?${query_params}" + + # 从 Bandix API 获å–è®¾å¤‡ç”¨é‡æŽ’è¡Œæ•°æ® + local response=$(curl -s --connect-timeout 2 --max-time 10 -X GET "$url" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + + # æå– data 部分并返回 + local data_part=$(echo "$response" | jsonfilter -e '$.data' 2>/dev/null) + if [ -n "$data_part" ]; then + echo "$data_part" + else + # 如果æå–失败,返回空结果 + echo '{"start":0,"end":0,"t_rx_b":0,"t_tx_b":0,"t_b":0,"cnt":0,"r":[]}' + fi +} + +# èŽ·å–æ—¶é—´åºåˆ—å¢žé‡æ•°æ® +# GET /api/traffic/usage/increments -> $.data +# { +# start, end, # 统计时间范围(ms) +# agg, # èšåˆç²’度 (1m/5m/1h/1d) +# net, # 网络类型 (wan/lan/all) +# mac, # 指定设备 MAC(空=全部) +# t_b, t_rx_b, t_tx_b, # 总/下/上行字节 +# inc: [{ +# start, end, # 分段时间范围(ms) +# w_rx_avg/max/min/p90/p95/p99, # WAN 下行速率统计 +# w_tx_avg/max/min/p90/p95/p99, # WAN 上行速率统计 +# l_rx_avg/max/min/p90/p95/p99, # LAN 下行速率统计 +# l_tx_avg/max/min/p90/p95/p99, # LAN 上行速率统计 +# w_rx_b, w_tx_b, # WAN 下/ä¸Šè¡Œå­—èŠ‚å¢žé‡ +# l_rx_b, l_tx_b # LAN 下/ä¸Šè¡Œå­—èŠ‚å¢žé‡ +# }] +# } +get_traffic_usage_increments() { + local start_ms="$1" + local end_ms="$2" + local aggregation="$3" + local mac="$4" + local network_type="$5" + + # æž„å»ºæŸ¥è¯¢å‚æ•°ï¼ˆåªæ·»åŠ éžç©ºä¸”æœ‰æ•ˆçš„å‚æ•°ï¼‰ + local query_params="" + # 检查 start_ms æ˜¯å¦æœ‰æ•ˆï¼ˆéžç©ºä¸”䏿˜¯ "null" 或 "undefined") + if [ -n "$start_ms" ] && [ "$start_ms" != "null" ] && [ "$start_ms" != "undefined" ]; then + query_params="${query_params}start_ms=$start_ms&" + fi + # 检查 end_ms æ˜¯å¦æœ‰æ•ˆ + if [ -n "$end_ms" ] && [ "$end_ms" != "null" ] && [ "$end_ms" != "undefined" ]; then + query_params="${query_params}end_ms=$end_ms&" + fi + # 检查 aggregation æ˜¯å¦æœ‰æ•ˆ + if [ -n "$aggregation" ] && [ "$aggregation" != "null" ] && [ "$aggregation" != "undefined" ]; then + query_params="${query_params}aggregation=$aggregation&" + fi + # 检查 mac æ˜¯å¦æœ‰æ•ˆ + if [ -n "$mac" ] && [ "$mac" != "null" ] && [ "$mac" != "undefined" ]; then + query_params="${query_params}mac=$(printf '%s' "$mac" | sed 's/ /%20/g')&" + fi + # 检查 network_type æ˜¯å¦æœ‰æ•ˆ + if [ -n "$network_type" ] && [ "$network_type" != "null" ] && [ "$network_type" != "undefined" ]; then + query_params="${query_params}network_type=$network_type&" + fi + + # 移除末尾的 & + query_params=$(echo "$query_params" | sed 's/&$//') + + local url="$BANDIX_TRAFFIC_USAGE_INCREMENTS_API" + [ -n "$query_params" ] && url="${url}?${query_params}" + + # 从 Bandix API èŽ·å–æ—¶é—´åºåˆ—å¢žé‡æ•°æ® + local response=$(curl -s --connect-timeout 2 --max-time 10 -X GET "$url" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + + # æå– data 部分并返回 + local data_part=$(echo "$response" | jsonfilter -e '$.data' 2>/dev/null) + if [ -n "$data_part" ]; then + echo "$data_part" + else + # 如果æå–失败,返回空结果 + echo '{"start":0,"end":0,"agg":"hourly","mac":"all","inc":[],"t_rx_b":0,"t_tx_b":0,"t_b":0}' + fi +} + +# 获å–定时é™é€Ÿè§„则 +get_schedule_limits() { + # 从 Bandix API 获å–定时é™é€Ÿè§„则 + local response=$(curl -s --connect-timeout 2 --max-time 5 -X GET "$BANDIX_SCHEDULE_LIMITS_API" 2>/dev/null) + + # 检查APIè°ƒç”¨æ˜¯å¦æˆåŠŸ + if [ $? -ne 0 ] || [ -z "$response" ]; then + make_error "Failed to connect to Bandix service" + return + fi + + # 直接返回API结果 + echo "$response" +} + +# 设置定时é™é€Ÿè§„则 +set_schedule_limit() { + local mac="$1" + local start_time="$2" + local end_time="$3" + local days="$4" + local wan_tx_rate_limit="$5" + local wan_rx_rate_limit="$6" + + # 验è¯å‚æ•° + if [ -z "$mac" ]; then + make_error "MAC address is required" + return + fi + + if [ -z "$start_time" ] || [ -z "$end_time" ] || [ -z "$days" ]; then + make_error "Time slot parameters are required" + return + fi + + # 转义MAC地å€ä¸­çš„特殊字符 + local mac_escaped=$(escape_json_string "$mac") + + # æž„å»ºè¯·æ±‚æ•°æ® + local request_data="{ + \"mac\": \"$mac\", + \"time_slot\": { + \"start\": \"$start_time\", + \"end\": \"$end_time\", + \"days\": $days + }, + \"wan_tx_rate_limit\": $wan_tx_rate_limit, + \"wan_rx_rate_limit\": $wan_rx_rate_limit + }" + + # å‘é€è¯·æ±‚到bandix API + local response=$(curl -s --connect-timeout 3 --max-time 10 -X POST -H "Content-Type: application/json" -d "$request_data" "$BANDIX_SCHEDULE_LIMITS_API" 2>/dev/null) + + if [ $? -eq 0 ] && [ -n "$response" ]; then + # 检查APIå“应是å¦åŒ…å«successçŠ¶æ€ + if echo "$response" | grep -q '"status":\s*"success"'; then + make_success "Schedule limit set successfully" + else + # API返回了å“åº”ä½†ä¸æ˜¯successçŠ¶æ€ + json_init + json_add_boolean "success" 0 + json_add_string "error" "API returned error response" + json_add_string "response" "$response" + json_dump + json_cleanup + fi + else + make_error "Failed to set schedule limit" + fi +} + +# 编辑定时é™é€Ÿè§„则 +update_schedule_limit() { + local id="$1" + local mac="$2" + local start_time="$3" + local end_time="$4" + local days="$5" + local wan_rx_rate_limit="$6" + local wan_tx_rate_limit="$7" + + if [ -z "$id" ]; then + make_error "ID is required" + return + fi + + if [ -z "$mac" ]; then + make_error "MAC address is required" + return + fi + + if [ -z "$start_time" ] || [ -z "$end_time" ] || [ -z "$days" ]; then + make_error "Time slot parameters are required" + return + fi + + local id_escaped=$(escape_json_string "$id") + local mac_escaped=$(escape_json_string "$mac") + + local request_data="{ + \"id\": \"$id\", + \"mac\": \"$mac\", + \"time_slot\": { + \"start\": \"$start_time\", + \"end\": \"$end_time\", + \"days\": $days + }, + \"wan_rx_rate_limit\": $wan_rx_rate_limit, + \"wan_tx_rate_limit\": $wan_tx_rate_limit + }" + + local response=$(curl -s --connect-timeout 3 --max-time 10 -X PUT -H "Content-Type: application/json" -d "$request_data" "$BANDIX_SCHEDULE_LIMITS_API" 2>/dev/null) + + if [ $? -eq 0 ] && [ -n "$response" ]; then + if echo "$response" | grep -q '"status":\s*"success"'; then + make_success "Schedule limit updated successfully" + else + json_init + json_add_boolean "success" 0 + json_add_string "error" "API returned error response" + json_add_string "response" "$response" + json_dump + json_cleanup + fi + else + make_error "Failed to update schedule limit" + fi +} + +# 删除定时é™é€Ÿè§„则 +delete_schedule_limit() { + local id="$1" + + if [ -z "$id" ]; then + make_error "ID is required" + return + fi + + local id_escaped=$(escape_json_string "$id") + local request_data="{\"id\": \"$id\"}" + + local response=$(curl -s --connect-timeout 3 --max-time 10 -X DELETE -H "Content-Type: application/json" -d "$request_data" "$BANDIX_SCHEDULE_LIMITS_API" 2>/dev/null) + + if [ $? -eq 0 ] && [ -n "$response" ]; then + if echo "$response" | grep -q '"status":\s*"success"'; then + make_success "Schedule limit deleted successfully" + else + json_init + json_add_boolean "success" 0 + json_add_string "error" "API returned error response" + json_add_string "response" "$response" + json_dump + json_cleanup + fi + else + make_error "Failed to delete schedule limit" + fi +} + +# æ¸…ç©ºæ•°æ® +clear_data() { + local data_dir=$(uci get bandix.general.data_dir 2>/dev/null || echo "/usr/share/bandix") + local metrics_dir="$data_dir/metrics" + + # 检查目录是å¦å­˜åœ¨ + if [ ! -d "$metrics_dir" ]; then + make_error "Metrics directory does not exist" + return + fi + + # 删除 metrics 目录下的所有文件 + rm -rf "$metrics_dir"/* 2>/dev/null + + if [ $? -eq 0 ]; then + make_success "Data cleared successfully" + else + make_error "Failed to clear data" + fi +} + +# é‡å¯æœåŠ¡ +restart_service() { + # 执行æœåŠ¡é‡å¯ + /etc/init.d/bandix restart >/dev/null 2>&1 + + if [ $? -eq 0 ]; then + make_success "Service restarted successfully" + else + make_error "Failed to restart service" + fi +} + +# 获å–ç‰ˆæœ¬ä¿¡æ¯ +get_version() { + json_init + + # 检测包管ç†å™¨ç±»åž‹ + local pkg_manager=$(get_package_manager) + + # èŽ·å– luci-app-bandix 版本 + local luci_version="" + + if [ "$pkg_manager" = "opkg" ]; then + # opkg æ–¹å¼ + if [ -f "/usr/lib/opkg/info/luci-app-bandix.control" ]; then + luci_version=$(grep "^Version:" /usr/lib/opkg/info/luci-app-bandix.control 2>/dev/null | cut -d' ' -f2) + fi + # 如果无法从 control 文件获å–,å°è¯•从 opkg å‘½ä»¤èŽ·å– + if [ -z "$luci_version" ]; then + luci_version=$(opkg list-installed luci-app-bandix 2>/dev/null | awk '{print $NF}') + fi + elif [ "$pkg_manager" = "apk" ]; then + # apk æ–¹å¼ + # apk çš„ control 文件路径å¯èƒ½ä¸åŒï¼Œå…ˆå°è¯•常è§è·¯å¾„ + if [ -f "/lib/apk/db/installed" ]; then + luci_version=$(grep "^luci-app-bandix-" /usr/lib/apk/db/installed 2>/dev/null | head -n 1 | sed -n 's/^luci-app-bandix-\(.*\)$/\1/p') + fi + # 如果无法从 installed 文件获å–,å°è¯•从 apk info å‘½ä»¤èŽ·å– + if [ -z "$luci_version" ]; then + luci_version=$(apk list --installed --manifest luci-app-bandix 2>/dev/null | awk '{print $NF}') + fi + fi + + # 如果还是无法获å–,使用默认值 + if [ -z "$luci_version" ]; then + luci_version="Unknown" + fi + + # èŽ·å– bandix 版本 + local bandix_version="" + + if [ "$pkg_manager" = "opkg" ]; then + # opkg æ–¹å¼ + if [ -f "/usr/lib/opkg/info/bandix.control" ]; then + bandix_version=$(grep "^Version:" /usr/lib/opkg/info/bandix.control 2>/dev/null | cut -d' ' -f2) + fi + # 如果无法从 control 文件获å–,å°è¯•从 opkg å‘½ä»¤èŽ·å– + if [ -z "$bandix_version" ]; then + bandix_version=$(opkg list-installed bandix 2>/dev/null | awk '{print $NF}') + fi + elif [ "$pkg_manager" = "apk" ]; then + # apk æ–¹å¼ + # apk çš„ control 文件路径å¯èƒ½ä¸åŒï¼Œå…ˆå°è¯•常è§è·¯å¾„ + if [ -f "/usr/lib/apk/db/installed" ]; then + bandix_version=$(grep "^bandix-" /usr/lib/apk/db/installed 2>/dev/null | head -n 1 | sed -n 's/^bandix-\(.*\)$/\1/p') + fi + # 如果无法从 installed 文件获å–,å°è¯•从 apk info å‘½ä»¤èŽ·å– + if [ -z "$bandix_version" ]; then + bandix_version=$(apk list --installed --manifest bandix 2>/dev/null | awk '{print $NF}') + fi + fi + + # 如果还是无法获å–,å°è¯•从 bandix API 获å–(如果æœåŠ¡è¿è¡Œä¸­ï¼‰ + if [ -z "$bandix_version" ]; then + local api_result=$(curl -s --connect-timeout 2 --max-time 5 "$BANDIX_API_BASE/api/version" 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$api_result" ]; then + bandix_version=$(echo "$api_result" | jsonfilter -e '$.version' 2>/dev/null) + [ -z "$bandix_version" ] && bandix_version=$(echo "$api_result" | jsonfilter -e '$.data.version' 2>/dev/null) + fi + fi + # 如果还是无法获å–,使用默认值 + if [ -z "$bandix_version" ]; then + bandix_version="Unknown" + fi + + json_add_string "luci_app_version" "$luci_version" + json_add_string "bandix_version" "$bandix_version" + json_dump + json_cleanup +} + +compare_versions() { + local ver1="$1" + local ver2="$2" + + if [ "$ver1" = "$ver2" ]; then + return 1 + fi + + local sorted=$(printf '%s\n%s\n' "$ver1" "$ver2" | sort -V | head -n1) + if [ "$sorted" = "$ver1" ]; then + return 0 + else + return 1 + fi +} + +# 检测包管ç†å™¨ç±»åž‹ +get_package_manager() { + command -v apk >/dev/null && echo "apk" || echo "opkg" +} + +# 获å–系统架构 +get_system_arch() { + # 优先从 /etc/os-release èŽ·å– OPENWRT_ARCH + if [ -f "/etc/os-release" ]; then + local arch=$(grep "^OPENWRT_ARCH=" /etc/os-release 2>/dev/null | cut -d'=' -f2 | tr -d '"') + if [ -n "$arch" ]; then + echo "$arch" + return + fi + fi + + # 最åŽå°è¯•从 uname èŽ·å– + uname -m 2>/dev/null +} + +# 检查更新 +check_update() { + json_init + + # 检测包管ç†å™¨ç±»åž‹ + local pkg_manager=$(get_package_manager) + + # 获å–当å‰ç‰ˆæœ¬ + local current_luci_version="" + if [ "$pkg_manager" = "opkg" ]; then + if [ -f "/usr/lib/opkg/info/luci-app-bandix.control" ]; then + current_luci_version=$(grep "^Version:" /usr/lib/opkg/info/luci-app-bandix.control 2>/dev/null | cut -d' ' -f2) + fi + if [ -z "$current_luci_version" ]; then + current_luci_version=$(opkg list-installed luci-app-bandix 2>/dev/null | awk '{print $NF}') + fi + elif [ "$pkg_manager" = "apk" ]; then + if [ -f "/lib/apk/db/installed" ]; then + current_luci_version=$(grep "^luci-app-bandix-" /lib/apk/db/installed 2>/dev/null | head -n 1 | sed -n 's/^luci-app-bandix-\(.*\)$/\1/p') + fi + if [ -z "$current_luci_version" ]; then + current_luci_version=$(apk info luci-app-bandix 2>/dev/null | grep "^luci-app-bandix-" | head -n 1 | sed -n 's/^luci-app-bandix-\(.*\) .*/\1/p') + fi + fi + + local current_bandix_version="" + if [ "$pkg_manager" = "opkg" ]; then + if [ -f "/usr/lib/opkg/info/bandix.control" ]; then + current_bandix_version=$(grep "^Version:" /usr/lib/opkg/info/bandix.control 2>/dev/null | cut -d' ' -f2) + fi + if [ -z "$current_bandix_version" ]; then + current_bandix_version=$(opkg list-installed bandix 2>/dev/null | awk '{print $NF}') + fi + elif [ "$pkg_manager" = "apk" ]; then + if [ -f "/lib/apk/db/installed" ]; then + current_bandix_version=$(grep "^bandix-" /lib/apk/db/installed 2>/dev/null | grep -v "^luci-app-bandix-" | head -n 1 | sed -n 's/^bandix-\(.*\)$/\1/p') + fi + if [ -z "$current_bandix_version" ]; then + current_bandix_version=$(apk info bandix 2>/dev/null | grep "^bandix-" | head -n 1 | sed -n 's/^bandix-\(.*\) .*/\1/p') + fi + fi + + # 检查 luci-app-bandix æ›´æ–° + local luci_latest_version="" + local luci_has_update="0" + local luci_update_url="" + local luci_release_body="" + local luci_download_url="" + + local luci_api_result=$(curl -s --connect-timeout 10 --max-time 30 "https://api.github.com/repos/timsaya/luci-app-bandix/releases/latest" 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$luci_api_result" ]; then + luci_latest_version=$(echo "$luci_api_result" | jsonfilter -e '$.tag_name' 2>/dev/null) + # 去掉 v å‰ç¼€ + luci_latest_version=${luci_latest_version#v} + luci_update_url=$(echo "$luci_api_result" | jsonfilter -e '$.html_url' 2>/dev/null) + luci_release_body=$(echo "$luci_api_result" | jsonfilter -e '$.body' 2>/dev/null) + + # èŽ·å–æž¶æž„ä¿¡æ¯å’ŒåŒ…管ç†å™¨ç±»åž‹ + local arch=$(get_system_arch) + local pkg_manager=$(get_package_manager) + + # æ ¹æ®åŒ…管ç†å™¨ç±»åž‹ç¡®å®šä¼˜å…ˆçš„æ–‡ä»¶æ‰©å±•å + local preferred_ext="" + if [ "$pkg_manager" = "opkg" ]; then + preferred_ext="ipk" + elif [ "$pkg_manager" = "apk" ]; then + preferred_ext="apk" + fi + + # 查找对应架构的 ipk/apk 文件 + # åªæŸ¥æ‰¾åŒ¹é…包管ç†å™¨æ ¼å¼çš„包,找ä¸åˆ°å°±æŠ¥é”™ + # 使用循环é历 assets 数组,直到找ä¸åˆ°å…ƒç´ ä¸ºæ­¢ + local i=0 + local asset_count=0 + + # 先统计 assets æ•°é‡ + while true; do + local asset_name=$(echo "$luci_api_result" | jsonfilter -e "$.assets[$i].name" 2>/dev/null) + if [ -z "$asset_name" ]; then + break + fi + asset_count=$((asset_count + 1)) + i=$((i + 1)) + done + + # 查找匹é…包管ç†å™¨æ ¼å¼çš„ _all 包 + if [ -n "$preferred_ext" ] && [ "$asset_count" -gt 0 ]; then + i=0 + while true; do + local asset_name=$(echo "$luci_api_result" | jsonfilter -e "$.assets[$i].name" 2>/dev/null) + if [ -z "$asset_name" ]; then + break + fi + # åŒ¹é… _all æ ¼å¼ï¼Œä¸”å¿…é¡»æ˜¯ä¼˜å…ˆæ ¼å¼ + if echo "$asset_name" | grep -qE "(luci-app-bandix.*_all|luci-app-bandix-.*-all)\.${preferred_ext}$"; then + luci_download_url=$(echo "$luci_api_result" | jsonfilter -e "$.assets[$i].browser_download_url" 2>/dev/null) + break + fi + i=$((i + 1)) + done + fi + + # 如果没找到 _all,å°è¯•找包å«å½“剿ž¶æž„的(åªåŒ¹é…包管ç†å™¨æ ¼å¼ï¼‰ + # 例如:luci-app-bandix_0.10.0-r1_aarch64_cortex-a53.ipk + if [ -z "$luci_download_url" ] && [ -n "$arch" ] && [ -n "$preferred_ext" ] && [ "$asset_count" -gt 0 ]; then + i=0 + while true; do + local asset_name=$(echo "$luci_api_result" | jsonfilter -e "$.assets[$i].name" 2>/dev/null) + if [ -z "$asset_name" ]; then + break + fi + # åŒ¹é…æ ¼å¼ï¼š*_æž¶æž„.优先扩展å + # 例如:文件ååŒ…å« "_aarch64_cortex-a53." 且以 .ipk 或 .apk 结尾 + # åŒæ—¶æŽ’除 i18n 包(åªåŒ¹é…主包) + if echo "$asset_name" | grep -qE "^luci-app-bandix[^-]" && \ + echo "$asset_name" | grep -qE "\.${preferred_ext}$" && \ + echo "$asset_name" | grep -q "_${arch}\."; then + luci_download_url=$(echo "$luci_api_result" | jsonfilter -e "$.assets[$i].browser_download_url" 2>/dev/null) + break + fi + i=$((i + 1)) + done + fi + + if [ -n "$current_luci_version" ] && [ -n "$luci_latest_version" ]; then + if compare_versions "$current_luci_version" "$luci_latest_version"; then + luci_has_update="1" + fi + fi + fi + + # 检查 bandix æ›´æ–° + local bandix_latest_version="" + local bandix_has_update="0" + local bandix_update_url="" + local bandix_release_body="" + local bandix_download_url="" + + local bandix_api_result=$(curl -s --connect-timeout 10 --max-time 30 "https://api.github.com/repos/timsaya/openwrt-bandix/releases/latest" 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$bandix_api_result" ]; then + bandix_latest_version=$(echo "$bandix_api_result" | jsonfilter -e '$.tag_name' 2>/dev/null) + # 去掉 v å‰ç¼€ + bandix_latest_version=${bandix_latest_version#v} + bandix_update_url=$(echo "$bandix_api_result" | jsonfilter -e '$.html_url' 2>/dev/null) + bandix_release_body=$(echo "$bandix_api_result" | jsonfilter -e '$.body' 2>/dev/null) + + # èŽ·å–æž¶æž„ä¿¡æ¯å’ŒåŒ…管ç†å™¨ç±»åž‹ + local arch=$(get_system_arch) + local pkg_manager=$(get_package_manager) + + # æ ¹æ®åŒ…管ç†å™¨ç±»åž‹ç¡®å®šä¼˜å…ˆçš„æ–‡ä»¶æ‰©å±•å + local preferred_ext="" + if [ "$pkg_manager" = "opkg" ]; then + preferred_ext="ipk" + elif [ "$pkg_manager" = "apk" ]; then + preferred_ext="apk" + fi + + # 查找对应架构的 ipk/apk 文件 + # bandix 包格å¼ï¼šbandix-版本-r修订å·_æž¶æž„.apk 或 bandix-版本-r修订å·_æž¶æž„.ipk + # 或者:bandix_版本-r修订å·_æž¶æž„.apk 或 bandix_版本-r修订å·_æž¶æž„.ipk + # 例如:bandix-0.10.2-r1_aarch64_cortex-a53.apk 或 bandix_0.10.2-r1_aarch64_cortex-a53.apk + local bandix_asset_count=0 + + # 先统计 assets æ•°é‡ + if [ -n "$arch" ]; then + local i=0 + while true; do + local asset_name=$(echo "$bandix_api_result" | jsonfilter -e "$.assets[$i].name" 2>/dev/null) + if [ -z "$asset_name" ]; then + break + fi + bandix_asset_count=$((bandix_asset_count + 1)) + i=$((i + 1)) + done + + # åªæŸ¥æ‰¾åŒ¹é…包管ç†å™¨æ ¼å¼çš„æž¶æž„特定包 + # 如果找ä¸åˆ°åŒ¹é…æ ¼å¼çš„包,就ä¸è®¾ç½® download_url,åŽç»­ä¼šæŠ¥é”™ + if [ -n "$preferred_ext" ] && [ "$bandix_asset_count" -gt 0 ]; then + i=0 + while true; do + local asset_name=$(echo "$bandix_api_result" | jsonfilter -e "$.assets[$i].name" 2>/dev/null) + if [ -z "$asset_name" ]; then + break + fi + # åŒ¹é…æ ¼å¼ï¼šbandix-*_æž¶æž„.ä¼˜å…ˆæ‰©å±•å æˆ– bandix_*_æž¶æž„.优先扩展å + # 例如:bandix-0.10.2-r1_aarch64_cortex-a53.ipk 或 bandix_0.10.2-r1_aarch64_cortex-a53.ipk + if echo "$asset_name" | grep -qE "^(bandix-|bandix_)" && \ + echo "$asset_name" | grep -qE "\.${preferred_ext}$" && \ + echo "$asset_name" | grep -q "_${arch}\."; then + bandix_download_url=$(echo "$bandix_api_result" | jsonfilter -e "$.assets[$i].browser_download_url" 2>/dev/null) + break + fi + i=$((i + 1)) + done + fi + fi + + if [ -n "$current_bandix_version" ] && [ -n "$bandix_latest_version" ]; then + if compare_versions "$current_bandix_version" "$bandix_latest_version"; then + bandix_has_update="1" + fi + fi + fi + + json_add_string "current_luci_version" "$current_luci_version" + json_add_string "current_bandix_version" "$current_bandix_version" + json_add_string "latest_luci_version" "$luci_latest_version" + json_add_string "latest_bandix_version" "$bandix_latest_version" + # 使用字符串 "1" 或 "0" 表示布尔值,在 JavaScript 中å¯ä»¥è½¬æ¢ä¸ºå¸ƒå°”值 + json_add_string "luci_has_update" "$luci_has_update" + json_add_string "bandix_has_update" "$bandix_has_update" + json_add_string "luci_update_url" "$luci_update_url" + json_add_string "bandix_update_url" "$bandix_update_url" + json_add_string "luci_release_body" "$luci_release_body" + json_add_string "bandix_release_body" "$bandix_release_body" + # æ£€æŸ¥æ˜¯å¦æ‰¾åˆ°äº†ä¸‹è½½é“¾æŽ¥ï¼Œå¦‚æžœæ²¡æ‰¾åˆ°åˆ™æ·»åŠ é”™è¯¯ä¿¡æ¯ + local luci_error="" + local bandix_error="" + + if [ -z "$luci_download_url" ] && [ "$luci_has_update" = "1" ]; then + local pkg_manager=$(get_package_manager) + local preferred_ext="" + if [ "$pkg_manager" = "opkg" ]; then + preferred_ext="ipk" + elif [ "$pkg_manager" = "apk" ]; then + preferred_ext="apk" + fi + if [ -n "$preferred_ext" ]; then + luci_error="No ${preferred_ext} package found for luci-app-bandix" + else + luci_error="Unknown package manager, cannot determine package format" + fi + fi + + if [ -z "$bandix_download_url" ] && [ "$bandix_has_update" = "1" ]; then + local pkg_manager=$(get_package_manager) + local preferred_ext="" + if [ "$pkg_manager" = "opkg" ]; then + preferred_ext="ipk" + elif [ "$pkg_manager" = "apk" ]; then + preferred_ext="apk" + fi + if [ -n "$preferred_ext" ]; then + bandix_error="No ${preferred_ext} package found for bandix" + else + bandix_error="Unknown package manager, cannot determine package format" + fi + fi + + json_add_string "luci_download_url" "$luci_download_url" + json_add_string "bandix_download_url" "$bandix_download_url" + json_add_string "luci_error" "$luci_error" + json_add_string "bandix_error" "$bandix_error" + # 添加调试信æ¯ï¼šæž¶æž„ã€åŒ…管ç†å™¨å’Œèµ„äº§æ•°é‡ + local detected_arch=$(get_system_arch) + local detected_pkg_manager=$(get_package_manager) + json_add_string "detected_arch" "$detected_arch" + json_add_string "detected_pkg_manager" "$detected_pkg_manager" + json_add_int "luci_asset_count" "$asset_count" + json_add_int "bandix_asset_count" "$bandix_asset_count" + json_dump + json_cleanup +} + +# 下载并安装更新 +install_update() { + local package_type="$1" # "luci" 或 "bandix" + local download_url="$2" + + if [ -z "$package_type" ] || [ -z "$download_url" ]; then + make_error "Missing parameters" + return + fi + + json_init + + # 步骤1: 下载文件到 /tmp + local filename=$(basename "$download_url") + local filepath="/tmp/$filename" + + json_add_string "step" "downloading" + json_add_string "filepath" "$filepath" + + # 使用 wget 下载文件 + wget -q --timeout=10 -O "$filepath" "$download_url" 2>&1 + local download_exit_code=$? + + if [ $download_exit_code -ne 0 ] || [ ! -f "$filepath" ]; then + rm -f "$filepath" + json_add_boolean "success" 0 + json_add_string "error" "Failed to download package" + json_add_string "step" "download_failed" + json_dump + json_cleanup + return + fi + + # 步骤2: 更新软件仓库 + json_add_string "step" "updating_repo" + if command -v opkg >/dev/null 2>&1; then + opkg update 2>/dev/null || true + elif command -v apk >/dev/null 2>&1; then + apk update 2>/dev/null || true + fi + + # 步骤3: 安装包 + json_add_string "step" "installing" + local install_result="" + local install_exit_code=1 + + if command -v opkg >/dev/null 2>&1; then + install_result=$(opkg install "$filepath" 2>&1) + install_exit_code=$? + elif command -v apk >/dev/null 2>&1; then + install_result=$(apk add --allow-untrusted "$filepath" 2>&1) + install_exit_code=$? + else + rm -f "$filepath" + json_add_boolean "success" 0 + json_add_string "error" "No package manager found (opkg or apk)" + json_add_string "step" "install_failed" + json_dump + json_cleanup + return + fi + + # 清ç†ä¸‹è½½çš„æ–‡ä»¶ + rm -f "$filepath" + + if [ $install_exit_code -ne 0 ]; then + json_add_boolean "success" 0 + json_add_string "error" "Failed to install package" + json_add_string "output" "$install_result" + json_add_string "step" "install_failed" + json_dump + json_cleanup + return + fi + + # 返回æˆåŠŸç»“æžœ + json_add_boolean "success" 1 + json_add_string "message" "Package installed successfully" + json_add_string "output" "$install_result" + json_add_string "step" "completed" + json_dump + json_cleanup +} + +case "$1" in + list) + json_init + json_add_object "getStatus" + json_add_int "start_ms" + json_add_int "end_ms" + json_close_object + + json_add_object "getMetrics" + json_add_string "mac" + json_close_object + + json_add_object "setHostname" + json_add_string "mac" + json_add_string "hostname" + json_close_object + + json_add_object "deleteDevice" + json_add_string "mac" + json_close_object + + json_add_object "getConnection" + json_close_object + + json_add_object "getConnectionFlows" + json_add_string "ip" + json_add_string "protocol" + json_add_string "state" + json_add_int "page" + json_add_int "page_size" + json_close_object + + json_add_object "getDnsQueries" + json_add_string "domain" + json_add_string "device" + json_add_string "is_query" + json_add_string "dns_server" + json_add_string "query_type" + json_add_int "page" + json_add_int "page_size" + json_close_object + + json_add_object "getDnsStats" + json_close_object + + json_add_object "getTrafficUsageRanking" + json_add_int "start_ms" + json_add_int "end_ms" + json_add_string "network_type" + json_close_object + + json_add_object "getTrafficUsageIncrements" + json_add_int "start_ms" + json_add_int "end_ms" + json_add_string "aggregation" + json_add_string "mac" + json_add_string "network_type" + json_close_object + + json_add_object "getScheduleLimits" + json_close_object + + json_add_object "setScheduleLimit" + json_add_string "mac" + json_add_string "start_time" + json_add_string "end_time" + json_add_string "days" + json_add_int "wan_rx_rate_limit" + json_add_int "wan_tx_rate_limit" + json_close_object + + json_add_object "updateScheduleLimit" + json_add_string "id" + json_add_string "mac" + json_add_string "start_time" + json_add_string "end_time" + json_add_string "days" + json_add_int "wan_rx_rate_limit" + json_add_int "wan_tx_rate_limit" + json_close_object + + json_add_object "deleteScheduleLimit" + json_add_string "id" + json_close_object + + json_add_object "clearData" + json_close_object + + json_add_object "restartService" + json_close_object + + json_add_object "getVersion" + json_close_object + + json_add_object "getSystemArch" + json_close_object + + json_add_object "checkUpdate" + json_close_object + + json_add_object "installUpdate" + json_add_string "package_type" + json_add_string "download_url" + json_close_object + + json_add_object "getRateLimitWhitelist" + json_close_object + + json_add_object "setRateLimitWhitelistEnabled" + json_add_string "enabled" + json_close_object + + json_add_object "addRateLimitWhitelist" + json_add_string "mac" + json_close_object + + json_add_object "deleteRateLimitWhitelist" + json_add_string "mac" + json_close_object + + json_add_object "setDefaultRateLimit" + json_add_int "wan_rx_rate_limit" + json_add_int "wan_tx_rate_limit" + json_close_object + + json_dump + json_cleanup + ;; + call) + case "$2" in + getStatus) + start_ms="" + end_ms="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + start_ms="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$start_ms" ] && start_ms="$(echo "$input" | jsonfilter -e '$.start_ms' 2>/dev/null)" + end_ms="$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null)" + [ -z "$end_ms" ] && end_ms="$(echo "$input" | jsonfilter -e '$.end_ms' 2>/dev/null)" + else + [ -n "$3" ] && start_ms="$3" + [ -n "$4" ] && end_ms="$4" + fi + get_device_status "$start_ms" "$end_ms" + ;; + getMetrics) + # logger "luci.bandix: getMetrics called" + # 读å–傿•°ï¼šä¼˜å…ˆ STDIN(带超时,é¿å…阻塞),其次ä½ç½®å‚数($3) + # 很奇怪收到的是 received input: {"mac":"70:e2:84:2b:9f:42","ubus_rpc_session":"4b0c5dcd9baf9963e4f13647fa71228a"} + mac="" + input="" + # å°è¯•读å–一行 STDIN,1 秒超时以é¿å…在无输入场景下阻塞 + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + # logger "luci.bandix: received input: $input" + # æ”¯æŒæ•°ç»„或对象两ç§é£Žæ ¼ + mac="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$mac" ] && mac="$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null)" + else + # æŸäº›çŽ¯å¢ƒä¸ä¼šé€šè¿‡ STDIN ä¼ å‚,改为读å–ä½ç½®å‚æ•° + [ -n "$3" ] && mac="$3" + # logger "luci.bandix: received argv mac: $mac" + fi + get_metrics "$mac" + ;; + setHostname) + # logger "luci.bandix: setHostname called" + + # 从 stdin è¯»å– JSON 傿•° + read input + # logger "luci.bandix: received input: $input" + + if [ -n "$input" ]; then + # å°è¯•è§£æžæ•°ç»„æ ¼å¼çš„ JSON 傿•° (LuCI RPC 通常使用数组格å¼) + # 傿•°æ ¼å¼: ["mac", "hostname"] + mac=$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null) + hostname=$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null) + + # 如果数组格å¼è§£æžå¤±è´¥ï¼Œå°è¯•å¯¹è±¡æ ¼å¼ + if [ -z "$mac" ]; then + mac=$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null) + hostname=$(echo "$input" | jsonfilter -e '$.hostname' 2>/dev/null) + fi + + # logger "luci.bandix: parsed - mac=$mac hostname=$hostname" + + # 验è¯å‚数(hostnameå¯ä»¥ä¸ºç©ºï¼‰ + if [ -n "$mac" ]; then + # 调用主机å设置函数 + set_device_hostname "$mac" "$hostname" + else + # logger "luci.bandix: setHostname MAC傿•°ç¼ºå¤±" + make_error "Missing MAC address parameter" + fi + else + # logger "luci.bandix: setHostname 没有接收到输入" + make_error "No input received" + fi + ;; + deleteDevice) + mac="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + mac="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$mac" ] && mac="$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null)" + else + [ -n "$3" ] && mac="$3" + fi + delete_device "$mac" + ;; + getConnection) + # logger "luci.bandix: getConnection called" + get_connection_devices + ;; + getConnectionFlows) + ip="" + protocol="" + state="" + page="" + page_size="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + ip="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$ip" ] && ip="$(echo "$input" | jsonfilter -e '$.ip' 2>/dev/null)" + protocol="$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null)" + [ -z "$protocol" ] && protocol="$(echo "$input" | jsonfilter -e '$.protocol' 2>/dev/null)" + state="$(echo "$input" | jsonfilter -e '$[2]' 2>/dev/null)" + [ -z "$state" ] && state="$(echo "$input" | jsonfilter -e '$.state' 2>/dev/null)" + page="$(echo "$input" | jsonfilter -e '$[3]' 2>/dev/null)" + [ -z "$page" ] && page="$(echo "$input" | jsonfilter -e '$.page' 2>/dev/null)" + page_size="$(echo "$input" | jsonfilter -e '$[4]' 2>/dev/null)" + [ -z "$page_size" ] && page_size="$(echo "$input" | jsonfilter -e '$.page_size' 2>/dev/null)" + else + [ -n "$3" ] && ip="$3" + [ -n "$4" ] && protocol="$4" + [ -n "$5" ] && state="$5" + [ -n "$6" ] && page="$6" + [ -n "$7" ] && page_size="$7" + fi + get_connection_flows "$ip" "$protocol" "$state" "$page" "$page_size" + ;; + getDnsQueries) + # logger "luci.bandix: getDnsQueries called" + # 从 stdin è¯»å– JSON 傿•° + read input + + if [ -n "$input" ]; then + # è§£æžå‚æ•° + domain=$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null) + [ -z "$domain" ] && domain=$(echo "$input" | jsonfilter -e '$.domain' 2>/dev/null) + + device=$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null) + [ -z "$device" ] && device=$(echo "$input" | jsonfilter -e '$.device' 2>/dev/null) + + is_query=$(echo "$input" | jsonfilter -e '$[2]' 2>/dev/null) + [ -z "$is_query" ] && is_query=$(echo "$input" | jsonfilter -e '$.is_query' 2>/dev/null) + + dns_server=$(echo "$input" | jsonfilter -e '$[3]' 2>/dev/null) + [ -z "$dns_server" ] && dns_server=$(echo "$input" | jsonfilter -e '$.dns_server' 2>/dev/null) + + query_type=$(echo "$input" | jsonfilter -e '$[4]' 2>/dev/null) + [ -z "$query_type" ] && query_type=$(echo "$input" | jsonfilter -e '$.query_type' 2>/dev/null) + + page=$(echo "$input" | jsonfilter -e '$[5]' 2>/dev/null) + [ -z "$page" ] && page=$(echo "$input" | jsonfilter -e '$.page' 2>/dev/null) + + page_size=$(echo "$input" | jsonfilter -e '$[6]' 2>/dev/null) + [ -z "$page_size" ] && page_size=$(echo "$input" | jsonfilter -e '$.page_size' 2>/dev/null) + + get_dns_queries "$domain" "$device" "$is_query" "$dns_server" "$query_type" "$page" "$page_size" + else + get_dns_queries "" "" "" "" "" "" "" + fi + ;; + getDnsStats) + # logger "luci.bandix: getDnsStats called" + get_dns_stats + ;; + getTrafficUsageRanking) + start_ms="" + end_ms="" + network_type="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + start_ms="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$start_ms" ] && start_ms="$(echo "$input" | jsonfilter -e '$.start_ms' 2>/dev/null)" + end_ms="$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null)" + [ -z "$end_ms" ] && end_ms="$(echo "$input" | jsonfilter -e '$.end_ms' 2>/dev/null)" + network_type="$(echo "$input" | jsonfilter -e '$[2]' 2>/dev/null)" + [ -z "$network_type" ] && network_type="$(echo "$input" | jsonfilter -e '$.network_type' 2>/dev/null)" + else + [ -n "$3" ] && start_ms="$3" + [ -n "$4" ] && end_ms="$4" + [ -n "$5" ] && network_type="$5" + fi + get_traffic_usage_ranking "$start_ms" "$end_ms" "$network_type" + ;; + getTrafficUsageIncrements) + start_ms="" + end_ms="" + aggregation="" + mac="" + network_type="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + start_ms="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$start_ms" ] && start_ms="$(echo "$input" | jsonfilter -e '$.start_ms' 2>/dev/null)" + end_ms="$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null)" + [ -z "$end_ms" ] && end_ms="$(echo "$input" | jsonfilter -e '$.end_ms' 2>/dev/null)" + aggregation="$(echo "$input" | jsonfilter -e '$[2]' 2>/dev/null)" + [ -z "$aggregation" ] && aggregation="$(echo "$input" | jsonfilter -e '$.aggregation' 2>/dev/null)" + mac="$(echo "$input" | jsonfilter -e '$[3]' 2>/dev/null)" + [ -z "$mac" ] && mac="$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null)" + network_type="$(echo "$input" | jsonfilter -e '$[4]' 2>/dev/null)" + [ -z "$network_type" ] && network_type="$(echo "$input" | jsonfilter -e '$.network_type' 2>/dev/null)" + else + [ -n "$3" ] && start_ms="$3" + [ -n "$4" ] && end_ms="$4" + [ -n "$5" ] && aggregation="$5" + [ -n "$6" ] && mac="$6" + [ -n "$7" ] && network_type="$7" + fi + get_traffic_usage_increments "$start_ms" "$end_ms" "$aggregation" "$mac" "$network_type" + ;; + getScheduleLimits) + # logger "luci.bandix: getScheduleLimits called" + get_schedule_limits + ;; + setScheduleLimit) + # logger "luci.bandix: setScheduleLimit called" + + # 从 stdin è¯»å– JSON 傿•° + read input + # logger "luci.bandix: received input: $input" + + if [ -n "$input" ]; then + # å°è¯•è§£æžæ•°ç»„æ ¼å¼çš„ JSON 傿•° (LuCI RPC 通常使用数组格å¼) + # 傿•°æ ¼å¼: ["mac", "start_time", "end_time", "days", wan_tx_rate_limit, wan_rx_rate_limit] + mac=$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null) + start_time=$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null) + end_time=$(echo "$input" | jsonfilter -e '$[2]' 2>/dev/null) + # days å¯èƒ½æ˜¯ JSON 数组字符串,需è¦ç‰¹æ®Šå¤„ç† + days=$(echo "$input" | jsonfilter -e '$[3]' 2>/dev/null) + # 如果æå–失败,å°è¯•作为字符串æå– + if [ -z "$days" ]; then + days=$(echo "$input" | jsonfilter -e '$[3]' -s 2>/dev/null) + fi + wan_tx_rate_limit=$(echo "$input" | jsonfilter -e '$[4]' 2>/dev/null) + wan_rx_rate_limit=$(echo "$input" | jsonfilter -e '$[5]' 2>/dev/null) + + # 如果数组格å¼è§£æžå¤±è´¥ï¼Œå°è¯•å¯¹è±¡æ ¼å¼ + if [ -z "$mac" ]; then + mac=$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null) + start_time=$(echo "$input" | jsonfilter -e '$.start_time' 2>/dev/null) + end_time=$(echo "$input" | jsonfilter -e '$.end_time' 2>/dev/null) + # days å¯èƒ½æ˜¯ JSON 数组字符串 + days=$(echo "$input" | jsonfilter -e '$.days' 2>/dev/null) + # 如果æå–失败,å°è¯•æå–为 JSON 数组 + if [ -z "$days" ]; then + days=$(echo "$input" | jsonfilter -e '$.days' -s 2>/dev/null) + fi + wan_tx_rate_limit=$(echo "$input" | jsonfilter -e '$.wan_tx_rate_limit' 2>/dev/null) + wan_rx_rate_limit=$(echo "$input" | jsonfilter -e '$.wan_rx_rate_limit' 2>/dev/null) + fi + + # 如果 days è¿˜ä¸æ˜¯æœ‰æ•ˆçš„ JSON 数组格å¼ï¼Œå°è¯•从原始输入中æå– + if [ -z "$days" ] || ! echo "$days" | grep -q '^\['; then + # å°è¯•直接æå– days 字段的值 + days=$(echo "$input" | sed -n 's/.*"days"[[:space:]]*:[[:space:]]*\(\[.*\]\).*/\1/p' 2>/dev/null) + fi + + # logger "luci.bandix: parsed - mac=$mac start=$start_time end=$end_time days=$days tx=$wan_tx_rate_limit rx=$wan_rx_rate_limit" + + # 验è¯å‚æ•° + if [ -n "$mac" ] && [ -n "$start_time" ] && [ -n "$end_time" ] && [ -n "$days" ] && [ -n "$wan_tx_rate_limit" ] && [ -n "$wan_rx_rate_limit" ]; then + # 调用定时é™é€Ÿè®¾ç½®å‡½æ•° + set_schedule_limit "$mac" "$start_time" "$end_time" "$days" "$wan_tx_rate_limit" "$wan_rx_rate_limit" + else + # logger "luci.bandix: setScheduleLimit 傿•°ç¼ºå¤±æˆ–无效" + make_error "Missing or invalid parameters" + fi + else + # logger "luci.bandix: setScheduleLimit 没有接收到输入" + make_error "No input received" + fi + ;; + updateScheduleLimit) + read input + + if [ -n "$input" ]; then + id=$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null) + mac=$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null) + start_time=$(echo "$input" | jsonfilter -e '$[2]' 2>/dev/null) + end_time=$(echo "$input" | jsonfilter -e '$[3]' 2>/dev/null) + days=$(echo "$input" | jsonfilter -e '$[4]' 2>/dev/null) + if [ -z "$days" ]; then + days=$(echo "$input" | jsonfilter -e '$[4]' -s 2>/dev/null) + fi + wan_rx_rate_limit=$(echo "$input" | jsonfilter -e '$[5]' 2>/dev/null) + wan_tx_rate_limit=$(echo "$input" | jsonfilter -e '$[6]' 2>/dev/null) + + if [ -z "$id" ]; then + id=$(echo "$input" | jsonfilter -e '$.id' 2>/dev/null) + mac=$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null) + start_time=$(echo "$input" | jsonfilter -e '$.start_time' 2>/dev/null) + end_time=$(echo "$input" | jsonfilter -e '$.end_time' 2>/dev/null) + days=$(echo "$input" | jsonfilter -e '$.days' 2>/dev/null) + if [ -z "$days" ]; then + days=$(echo "$input" | jsonfilter -e '$.days' -s 2>/dev/null) + fi + wan_rx_rate_limit=$(echo "$input" | jsonfilter -e '$.wan_rx_rate_limit' 2>/dev/null) + wan_tx_rate_limit=$(echo "$input" | jsonfilter -e '$.wan_tx_rate_limit' 2>/dev/null) + fi + + if [ -z "$days" ] || ! echo "$days" | grep -q '^\['; then + days=$(echo "$input" | sed -n 's/.*"days"[[:space:]]*:[[:space:]]*\(\[.*\]\).*/\1/p' 2>/dev/null) + fi + + if [ -n "$id" ] && [ -n "$mac" ] && [ -n "$start_time" ] && [ -n "$end_time" ] && [ -n "$days" ] && [ -n "$wan_rx_rate_limit" ] && [ -n "$wan_tx_rate_limit" ]; then + update_schedule_limit "$id" "$mac" "$start_time" "$end_time" "$days" "$wan_rx_rate_limit" "$wan_tx_rate_limit" + else + make_error "Missing or invalid parameters" + fi + else + make_error "No input received" + fi + ;; + deleteScheduleLimit) + read input + + if [ -n "$input" ]; then + id=$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null) + [ -z "$id" ] && id=$(echo "$input" | jsonfilter -e '$.id' 2>/dev/null) + + if [ -n "$id" ]; then + delete_schedule_limit "$id" + else + make_error "Missing id parameter" + fi + else + make_error "No input received" + fi + ;; + clearData) + # logger "luci.bandix: clearData called" + clear_data + ;; + restartService) + # logger "luci.bandix: restartService called" + restart_service + ;; + getVersion) + # logger "luci.bandix: getVersion called" + get_version + ;; + getSystemArch) + # logger "luci.bandix: getSystemArch called" + local arch=$(get_system_arch) + json_init + json_add_string "arch" "$arch" + json_dump + json_cleanup + ;; + checkUpdate) + # logger "luci.bandix: checkUpdate called" + check_update + ;; + installUpdate) + # logger "luci.bandix: installUpdate called" + # 从 stdin è¯»å– JSON 傿•° + read input + + if [ -n "$input" ]; then + # è§£æžå‚æ•° + package_type=$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null) + [ -z "$package_type" ] && package_type=$(echo "$input" | jsonfilter -e '$.package_type' 2>/dev/null) + + download_url=$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null) + [ -z "$download_url" ] && download_url=$(echo "$input" | jsonfilter -e '$.download_url' 2>/dev/null) + + if [ -n "$package_type" ] && [ -n "$download_url" ]; then + install_update "$package_type" "$download_url" + else + make_error "Missing package_type or download_url parameter" + fi + else + make_error "No input received" + fi + ;; + getRateLimitWhitelist) + get_rate_limit_whitelist + ;; + setRateLimitWhitelistEnabled) + enabled="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + enabled="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$enabled" ] && enabled="$(echo "$input" | jsonfilter -e '$.enabled' 2>/dev/null)" + else + [ -n "$3" ] && enabled="$3" + fi + set_rate_limit_whitelist_enabled "$enabled" + ;; + addRateLimitWhitelist) + mac="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + mac="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$mac" ] && mac="$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null)" + else + [ -n "$3" ] && mac="$3" + fi + add_rate_limit_whitelist_mac "$mac" + ;; + deleteRateLimitWhitelist) + mac="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + mac="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$mac" ] && mac="$(echo "$input" | jsonfilter -e '$.mac' 2>/dev/null)" + else + [ -n "$3" ] && mac="$3" + fi + delete_rate_limit_whitelist_mac "$mac" + ;; + setDefaultRateLimit) + wan_rx_rate_limit="" + wan_tx_rate_limit="" + input="" + if read -t 1 -r input; then + : + fi + if [ -n "$input" ]; then + wan_rx_rate_limit="$(echo "$input" | jsonfilter -e '$[0]' 2>/dev/null)" + [ -z "$wan_rx_rate_limit" ] && wan_rx_rate_limit="$(echo "$input" | jsonfilter -e '$.wan_rx_rate_limit' 2>/dev/null)" + wan_tx_rate_limit="$(echo "$input" | jsonfilter -e '$[1]' 2>/dev/null)" + [ -z "$wan_tx_rate_limit" ] && wan_tx_rate_limit="$(echo "$input" | jsonfilter -e '$.wan_tx_rate_limit' 2>/dev/null)" + else + [ -n "$3" ] && wan_rx_rate_limit="$3" + [ -n "$4" ] && wan_tx_rate_limit="$4" + fi + set_default_rate_limit "$wan_rx_rate_limit" "$wan_tx_rate_limit" + ;; + esac + ;; +esac diff --git a/luci-app-bandix/root/usr/share/luci/menu.d/luci-app-bandix.json b/luci-app-bandix/root/usr/share/luci/menu.d/luci-app-bandix.json new file mode 100644 index 00000000..d57191fd --- /dev/null +++ b/luci-app-bandix/root/usr/share/luci/menu.d/luci-app-bandix.json @@ -0,0 +1,46 @@ +{ + "admin/network/bandix": { + "title": "Bandix", + "order": 90, + "action": { + "type": "alias", + "path": "admin/network/bandix/index" + }, + "depends": { + "acl": [ "luci-app-bandix" ], + "uci": { "bandix": true } + } + }, + "admin/network/bandix/index": { + "title": "Status", + "order": 10, + "action": { + "type": "view", + "path": "bandix/index" + } + }, + "admin/network/bandix/connection": { + "title": "Connections", + "order": 15, + "action": { + "type": "view", + "path": "bandix/connection" + } + }, + "admin/network/bandix/dns": { + "title": "DNS", + "order": 20, + "action": { + "type": "view", + "path": "bandix/dns" + } + }, + "admin/network/bandix/settings": { + "title": "Settings", + "order": 25, + "action": { + "type": "view", + "path": "bandix/settings" + } + } +} diff --git a/luci-app-bandix/root/usr/share/luci/status/bandix.json b/luci-app-bandix/root/usr/share/luci/status/bandix.json new file mode 100644 index 00000000..13a6795c --- /dev/null +++ b/luci-app-bandix/root/usr/share/luci/status/bandix.json @@ -0,0 +1,12 @@ +{ + "bandix": { + "title": "Bandix æµé‡ç›‘控", + "description": "局域网设备æµé‡ç›‘控和统计æœåŠ¡", + "instances": { + "instance": { + "type": "process", + "init": "bandix" + } + } + } +} \ No newline at end of file diff --git a/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json b/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json new file mode 100644 index 00000000..452ec7dd --- /dev/null +++ b/luci-app-bandix/root/usr/share/rpcd/acl.d/luci-app-bandix.json @@ -0,0 +1,75 @@ +{ + "luci-app-bandix": { + "description": "Grant access to bandix traffic monitoring", + "read": { + "ubus": { + "luci.bandix": [ + "getStatus", + "getMetrics", + "getMetricsDay", + "getMetricsWeek", + "getMetricsMonth", + "getConnection", + "getConnectionFlows", + "setHostname", + "deleteDevice", + "getDnsQueries", + "getDnsStats", + "getScheduleLimits", + "setScheduleLimit", + "deleteScheduleLimit", + "clearData", + "restartService", + "getVersion", + "getSystemArch", + "checkUpdate", + "installUpdate", + "getTrafficUsageRanking", + "getTrafficUsageIncrements", + "getRateLimitWhitelist" + ] + }, + "uci": [ + "bandix" + ] + }, + "write": { + "ubus": { + "luci.bandix": [ + "getStatus", + "getMetrics", + "getMetricsDay", + "getMetricsWeek", + "getMetricsMonth", + "getConnection", + "getConnectionFlows", + "setHostname", + "deleteDevice", + "getDnsQueries", + "getDnsStats", + "getScheduleLimits", + "setScheduleLimit", + "deleteScheduleLimit", + "clearData", + "restartService", + "getVersion", + "getSystemArch", + "checkUpdate", + "installUpdate", + "getTrafficUsageRanking", + "getTrafficUsageIncrements", + "getRateLimitWhitelist", + "getRateLimitWhitelistEnabled", + "setRateLimitWhitelistEnabled", + "addRateLimitWhitelist", + "deleteRateLimitWhitelist", + "setDefaultRateLimit", + "updateScheduleLimit" + ] + }, + "uci": [ + "bandix" + ] + } + } +} \ No newline at end of file diff --git a/luci-app-banmac-ipt/Makefile b/luci-app-banmac-ipt/Makefile new file mode 100644 index 00000000..db6d7752 --- /dev/null +++ b/luci-app-banmac-ipt/Makefile @@ -0,0 +1,31 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-banmac-ipt +PKG_VERSION:=20211118 + + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-app-banmac-ipt + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI Support for Ban Client + PKGARCH:=all +endef + +define Build/Compile +endef + +define Package/luci-app-banmac-ipt/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci + cp -pR ./luasrc/* $(1)/usr/lib/lua/luci + $(INSTALL_DIR) $(1)/usr/banmac + $(INSTALL_BIN) ./files/banmac/* $(1)/usr/banmac + $(INSTALL_DIR) $(1)/etc + $(INSTALL_CONF) ./files/banmaclog $(1)/etc/banmaclog + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/banmac.conf $(1)/etc/config/banmac +endef + +$(eval $(call BuildPackage,luci-app-banmac-ipt)) diff --git a/luci-app-banmac-ipt/files/banmac.conf b/luci-app-banmac-ipt/files/banmac.conf new file mode 100644 index 00000000..2b0df1a0 --- /dev/null +++ b/luci-app-banmac-ipt/files/banmac.conf @@ -0,0 +1,5 @@ + +config banlist + +config banmac 'smartphone' + diff --git a/luci-app-banmac-ipt/files/banmac/ban.sh b/luci-app-banmac-ipt/files/banmac/ban.sh new file mode 100755 index 00000000..9a5130bc --- /dev/null +++ b/luci-app-banmac-ipt/files/banmac/ban.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +sectionname=$(echo $0 | cut -d '_' -f 2 | sed 's/^OO!%!OO//') +getcmac=$(uci get banmac.$sectionname.banlist_mac | tr 'A-Z' 'a-z') +iptables -I FORWARD -m mac --mac-source $getcmac -j DROP +hostname=$(grep -n $getcmac /tmp/dhcp.leases | cut -d ' ' -f 4) +hostip=$(grep -n $getcmac /tmp/dhcp.leases | cut -d ' ' -f 3) +echo "★ç¦ç½‘设备:$hostname($hostip) MAC地å€ï¼š$getcmac æ“作日期:$(date +%Yå¹´%m月%dæ—¥\ %H点%M分%Sç§’)" >> /etc/banmaclog + +for i in $(seq 0 1) +do + for x in $(iw wlan${i} station dump | grep -i station | cut -d ' ' -f 2) + do + if [ $x = $getcmac ]; then + iw dev wlan${i} station del $x + fi + done +done diff --git a/luci-app-banmac-ipt/files/banmac/unban.sh b/luci-app-banmac-ipt/files/banmac/unban.sh new file mode 100755 index 00000000..42d7e704 --- /dev/null +++ b/luci-app-banmac-ipt/files/banmac/unban.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +sectionname=$(echo $0 | cut -d '_' -f 2 | sed 's/^OO!%!OO//') +getcmac=$(uci get banmac.$sectionname.banlist_mac | tr 'A-Z' 'a-z') +iptables -D FORWARD -m mac --mac-source $getcmac -j DROP + +sed -i "s/$(cat /etc/banmaclog | grep $getcmac | head -n 1)//;/^\s*$/d" /etc/banmaclog diff --git a/luci-app-banmac-ipt/files/banmaclog b/luci-app-banmac-ipt/files/banmaclog new file mode 100644 index 00000000..26906d62 --- /dev/null +++ b/luci-app-banmac-ipt/files/banmaclog @@ -0,0 +1,3 @@ +#点击 One-Click Ban å¿«é€Ÿç¦æ­¢æŒ‡å®šå®¢æˆ·ç«¯ã€‚点击 One-Click UnBan 快速解ç¦ã€‚ +#这里记录了客户端列表 +---------------------------------------------------------------------- diff --git a/luci-app-banmac-ipt/luasrc/controller/banmac.lua b/luci-app-banmac-ipt/luasrc/controller/banmac.lua new file mode 100644 index 00000000..d78af5cb --- /dev/null +++ b/luci-app-banmac-ipt/luasrc/controller/banmac.lua @@ -0,0 +1,7 @@ +module("luci.controller.banmac",package.seeall) + +function index() + local page = entry({"admin", "services", "banmac"}, cbi("banmac"), _("BanMac"),5) + page.dependent = true +end + diff --git a/luci-app-banmac-ipt/luasrc/model/cbi/banmac.lua b/luci-app-banmac-ipt/luasrc/model/cbi/banmac.lua new file mode 100644 index 00000000..73e056bf --- /dev/null +++ b/luci-app-banmac-ipt/luasrc/model/cbi/banmac.lua @@ -0,0 +1,47 @@ +m = Map("banmac", translate("BanMac")) + +local banlist = m:section(TypedSection, "banlist", translate("log")) +banlist.anonymous = true + +local bmdetails = "/etc/banmaclog" +local BMNXFS = require "nixio.fs" +bmd = banlist:option(TextValue, "details") +bmd.rows = 6 +bmd.wrap = "off" +bmd.cfgvalue = function(self, section) + return BMNXFS.readfile(bmdetails) or "" +end +bmd.write = function(self, section, value) + BMNXFS.writefile(bmdetails, value:gsub("\r\n", "\n")) +end + +s = m:section(TypedSection, "banmac", "") +s.anonymous = false +s.addremove = true + +s:tab("banmactab", translate("BanMac Menu")) + +banlist_mac = s:taboption("banmactab", Value, "banlist_mac", translate("MAC address")) +banlist_mac.rmempty = true +banlist_mac.datatype = "macaddr" +luci.sys.net.mac_hints(function(mac, name) + banlist_mac:value(mac, "%s (%s)" %{ mac, name }) +end) + +ban_mac = s:taboption("banmactab", Button, "ban_mac", translate("One-Click BAN")) +ban_mac.rmempty = false +ban_mac.inputstyle = "apply" +function ban_mac.write(self, section) + luci.util.exec("cp /usr/banmac/ban.sh /tmp/ban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") + luci.util.exec("/tmp/ban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") +end + +unban_mac = s:taboption("banmactab", Button, "unban_mac", translate("One-Click UnBAN")) +unban_mac.rmempty = false +unban_mac.inputstyle = "apply" +function unban_mac.write(self, section) + luci.util.exec("cp /usr/banmac/unban.sh /tmp/unban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") + luci.util.exec("/tmp/unban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") +end + +return m diff --git a/luci-app-banmac-nft/Makefile b/luci-app-banmac-nft/Makefile new file mode 100644 index 00000000..2c028fe8 --- /dev/null +++ b/luci-app-banmac-nft/Makefile @@ -0,0 +1,31 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-banmac-nft +PKG_VERSION:=20231012 + + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-app-banmac-nft + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI Support for Ban Client + PKGARCH:=all +endef + +define Build/Compile +endef + +define Package/luci-app-banmac-nft/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci + cp -pR ./luasrc/* $(1)/usr/lib/lua/luci + $(INSTALL_DIR) $(1)/usr/banmac + $(INSTALL_BIN) ./files/banmac/* $(1)/usr/banmac + $(INSTALL_DIR) $(1)/etc + $(INSTALL_CONF) ./files/banmaclog $(1)/etc/banmaclog + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/banmac.conf $(1)/etc/config/banmac +endef + +$(eval $(call BuildPackage,luci-app-banmac-nft)) diff --git a/luci-app-banmac-nft/files/banmac.conf b/luci-app-banmac-nft/files/banmac.conf new file mode 100644 index 00000000..2b0df1a0 --- /dev/null +++ b/luci-app-banmac-nft/files/banmac.conf @@ -0,0 +1,5 @@ + +config banlist + +config banmac 'smartphone' + diff --git a/luci-app-banmac-nft/files/banmac/ban.sh b/luci-app-banmac-nft/files/banmac/ban.sh new file mode 100755 index 00000000..075d00a8 --- /dev/null +++ b/luci-app-banmac-nft/files/banmac/ban.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +sectionname=$(echo $0 | cut -d '_' -f 2 | sed 's/^OO!%!OO//') +getcmac=$(uci get banmac.$sectionname.banlist_mac | tr 'A-Z' 'a-z') +iptables -I FORWARD -m mac --mac-source $getcmac -j DROP +hostname=$(grep -n $getcmac /tmp/dhcp.leases | cut -d ' ' -f 4) +hostip=$(grep -n $getcmac /tmp/dhcp.leases | cut -d ' ' -f 3) +echo "★ç¦ç½‘设备:$hostname($hostip) MAC地å€ï¼š$getcmac æ“作日期:$(date +%Yå¹´%m月%dæ—¥\ %H点%M分%Sç§’)" >> /etc/banmaclog + +for i in $(seq 0 1);do + for j in $(seq 0 1);do + for x in $(iw dev phy${i}-ap${j} station dump | grep -i station | awk '{print$2}');do + if [ $x = $getcmac ]; then + iw dev phy${i}-ap${j} station del $x + fi + done + done +done diff --git a/luci-app-banmac-nft/files/banmac/unban.sh b/luci-app-banmac-nft/files/banmac/unban.sh new file mode 100755 index 00000000..42d7e704 --- /dev/null +++ b/luci-app-banmac-nft/files/banmac/unban.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +sectionname=$(echo $0 | cut -d '_' -f 2 | sed 's/^OO!%!OO//') +getcmac=$(uci get banmac.$sectionname.banlist_mac | tr 'A-Z' 'a-z') +iptables -D FORWARD -m mac --mac-source $getcmac -j DROP + +sed -i "s/$(cat /etc/banmaclog | grep $getcmac | head -n 1)//;/^\s*$/d" /etc/banmaclog diff --git a/luci-app-banmac-nft/files/banmaclog b/luci-app-banmac-nft/files/banmaclog new file mode 100644 index 00000000..26906d62 --- /dev/null +++ b/luci-app-banmac-nft/files/banmaclog @@ -0,0 +1,3 @@ +#点击 One-Click Ban å¿«é€Ÿç¦æ­¢æŒ‡å®šå®¢æˆ·ç«¯ã€‚点击 One-Click UnBan 快速解ç¦ã€‚ +#这里记录了客户端列表 +---------------------------------------------------------------------- diff --git a/luci-app-banmac-nft/luasrc/controller/banmac.lua b/luci-app-banmac-nft/luasrc/controller/banmac.lua new file mode 100644 index 00000000..d78af5cb --- /dev/null +++ b/luci-app-banmac-nft/luasrc/controller/banmac.lua @@ -0,0 +1,7 @@ +module("luci.controller.banmac",package.seeall) + +function index() + local page = entry({"admin", "services", "banmac"}, cbi("banmac"), _("BanMac"),5) + page.dependent = true +end + diff --git a/luci-app-banmac-nft/luasrc/model/cbi/banmac.lua b/luci-app-banmac-nft/luasrc/model/cbi/banmac.lua new file mode 100644 index 00000000..73e056bf --- /dev/null +++ b/luci-app-banmac-nft/luasrc/model/cbi/banmac.lua @@ -0,0 +1,47 @@ +m = Map("banmac", translate("BanMac")) + +local banlist = m:section(TypedSection, "banlist", translate("log")) +banlist.anonymous = true + +local bmdetails = "/etc/banmaclog" +local BMNXFS = require "nixio.fs" +bmd = banlist:option(TextValue, "details") +bmd.rows = 6 +bmd.wrap = "off" +bmd.cfgvalue = function(self, section) + return BMNXFS.readfile(bmdetails) or "" +end +bmd.write = function(self, section, value) + BMNXFS.writefile(bmdetails, value:gsub("\r\n", "\n")) +end + +s = m:section(TypedSection, "banmac", "") +s.anonymous = false +s.addremove = true + +s:tab("banmactab", translate("BanMac Menu")) + +banlist_mac = s:taboption("banmactab", Value, "banlist_mac", translate("MAC address")) +banlist_mac.rmempty = true +banlist_mac.datatype = "macaddr" +luci.sys.net.mac_hints(function(mac, name) + banlist_mac:value(mac, "%s (%s)" %{ mac, name }) +end) + +ban_mac = s:taboption("banmactab", Button, "ban_mac", translate("One-Click BAN")) +ban_mac.rmempty = false +ban_mac.inputstyle = "apply" +function ban_mac.write(self, section) + luci.util.exec("cp /usr/banmac/ban.sh /tmp/ban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") + luci.util.exec("/tmp/ban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") +end + +unban_mac = s:taboption("banmactab", Button, "unban_mac", translate("One-Click UnBAN")) +unban_mac.rmempty = false +unban_mac.inputstyle = "apply" +function unban_mac.write(self, section) + luci.util.exec("cp /usr/banmac/unban.sh /tmp/unban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") + luci.util.exec("/tmp/unban_OO!%!OO" ..section.. "_.sh >/dev/null 2>&1 &") +end + +return m diff --git a/luci-app-cpu-status-mini/LICENSE b/luci-app-cpu-status-mini/LICENSE new file mode 100644 index 00000000..4c903101 --- /dev/null +++ b/luci-app-cpu-status-mini/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 gSpotx2f + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/luci-app-cpu-status-mini/Makefile b/luci-app-cpu-status-mini/Makefile new file mode 100644 index 00000000..634b9e36 --- /dev/null +++ b/luci-app-cpu-status-mini/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2025 gSpot (https://github.com/gSpotx2f/luci-app-cpu-status-mini) +# +# This is free software, licensed under the MIT License. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-cpu-status-mini +PKG_VERSION:=0.2.0 +PKG_RELEASE:=1 +LUCI_TITLE:=CPU utilization info for the LuCI status page +LUCI_PKGARCH:=all +PKG_LICENSE:=MIT + +#include ../../luci.mk +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-cpu-status-mini/README.md b/luci-app-cpu-status-mini/README.md new file mode 100644 index 00000000..ae67ffb1 --- /dev/null +++ b/luci-app-cpu-status-mini/README.md @@ -0,0 +1,38 @@ +# luci-app-cpu-status-mini +CPU utilization info for the LuCI status page (OpenWrt webUI). + +OpenWrt >= 21.02. + +Advanced version: [luci-app-cpu-status](https://github.com/gSpotx2f/luci-app-cpu-status). + +## Installation notes + +**OpenWrt >= 25.12:** + + wget --no-check-certificate -O /tmp/luci-app-cpu-status-mini-0.2.0-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-cpu-status-mini-0.2.0-r1.apk + apk --allow-untrusted add /tmp/luci-app-cpu-status-mini-0.2.0-r1.apk + rm /tmp/luci-app-cpu-status-mini-0.2.0-r1.apk + service rpcd reload + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-cpu-status-mini-ru-0.2.0-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-cpu-status-mini-ru-0.2.0-r1.apk + apk --allow-untrusted add /tmp/luci-i18n-cpu-status-mini-ru-0.2.0-r1.apk + rm /tmp/luci-i18n-cpu-status-mini-ru-0.2.0-r1.apk + +**OpenWrt <= 24.10:** + + wget --no-check-certificate -O /tmp/luci-app-cpu-status-mini_0.2.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-cpu-status-mini_0.2.0-r1_all.ipk + opkg install /tmp/luci-app-cpu-status-mini_0.2.0-r1_all.ipk + rm /tmp/luci-app-cpu-status-mini_0.2.0-r1_all.ipk + service rpcd reload + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-cpu-status-mini-ru_0.2.0-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-cpu-status-mini-ru_0.2.0-r1_all.ipk + opkg install /tmp/luci-i18n-cpu-status-mini-ru_0.2.0-r1_all.ipk + rm /tmp/luci-i18n-cpu-status-mini-ru_0.2.0-r1_all.ipk + +## Screenshots: + +![](https://github.com/gSpotx2f/luci-app-cpu-status-mini/blob/master/screenshots/01.jpg) diff --git a/luci-app-cpu-status-mini/htdocs/luci-static/resources/view/status/include/18_cpu.js b/luci-app-cpu-status-mini/htdocs/luci-static/resources/view/status/include/18_cpu.js new file mode 100644 index 00000000..b897e7b6 --- /dev/null +++ b/luci-app-cpu-status-mini/htdocs/luci-static/resources/view/status/include/18_cpu.js @@ -0,0 +1,58 @@ +'use strict'; +'require baseclass'; +'require fs'; + +return baseclass.extend({ + title : _('CPU Load'), + + cpuStatLast: null, + + load() { + return L.resolveDefault(fs.read('/proc/stat'), null); + }, + + render(cpuData) { + if(!cpuData) return; + + let cpuStat = null; + let statItemsArray = cpuData.trim().split('\n').filter(s => s.startsWith('cpu')); + + for(let str of statItemsArray) { + let arr = str.split(/\s+/).slice(0, 8); + if(arr[0] === 'cpu') { + arr[0] = 0; + arr = arr.map(e => Number(e)); + cpuStat = [ + arr[1] + arr[2] + arr[3] + arr[5] + arr[6] + arr[7], + arr[4], + ]; + }; + }; + + let cpuTable = E('table', { 'class': 'table' }); + let loadAvg = 0; + + if(this.cpuStatLast !== null) { + let idle = cpuStat[1] - this.cpuStatLast[1]; + let sum = cpuStat[0] - this.cpuStatLast[0]; + loadAvg = Math.round(100 * sum / (sum + idle)); + }; + + cpuTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'width': '33%' }, _('Total Load')), + E('td', { 'class': 'td' }, + E('div', { + 'class': 'cbi-progressbar', + 'title': (this.cpuStatLast !== null) ? loadAvg + '%' : _('Calculating') + '...', + }, + E('div', { 'style': 'width:' + loadAvg + '%' }) + ) + ), + ]) + ); + + this.cpuStatLast = cpuStat; + return cpuTable; + }, +}); diff --git a/luci-app-cpu-status-mini/po/ru/cpu-status.po b/luci-app-cpu-status-mini/po/ru/cpu-status.po new file mode 100644 index 00000000..a9a2918a --- /dev/null +++ b/luci-app-cpu-status-mini/po/ru/cpu-status.po @@ -0,0 +1,22 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Language: ru\n" + +msgid "Calculating" +msgstr "ВычиÑление" + +msgid "CPU Load" +msgstr "Загрузка ЦПУ" + +msgid "Total Load" +msgstr "ÐžÐ±Ñ‰Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°" diff --git a/luci-app-cpu-status-mini/po/templates/cpu-status.pot b/luci-app-cpu-status-mini/po/templates/cpu-status.pot new file mode 100644 index 00000000..543e6568 --- /dev/null +++ b/luci-app-cpu-status-mini/po/templates/cpu-status.pot @@ -0,0 +1,11 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Calculating" +msgstr "" + +msgid "CPU Load" +msgstr "" + +msgid "Total Load" +msgstr "" diff --git a/luci-app-cpu-status-mini/root/usr/share/rpcd/acl.d/luci-app-cpu-status.json b/luci-app-cpu-status-mini/root/usr/share/rpcd/acl.d/luci-app-cpu-status.json new file mode 100644 index 00000000..229c8203 --- /dev/null +++ b/luci-app-cpu-status-mini/root/usr/share/rpcd/acl.d/luci-app-cpu-status.json @@ -0,0 +1,10 @@ +{ + "luci-app-cpu-status": { + "description": "Grant access to cpu-status procedures", + "read": { + "file": { + "/proc/stat": [ "read" ] + } + } + } +} diff --git a/luci-app-cpu-status-mini/screenshots/01.jpg b/luci-app-cpu-status-mini/screenshots/01.jpg new file mode 100644 index 00000000..e784d2c6 Binary files /dev/null and b/luci-app-cpu-status-mini/screenshots/01.jpg differ diff --git a/luci-app-cpu-status/LICENSE b/luci-app-cpu-status/LICENSE new file mode 100644 index 00000000..4c903101 --- /dev/null +++ b/luci-app-cpu-status/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 gSpotx2f + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/luci-app-cpu-status/Makefile b/luci-app-cpu-status/Makefile new file mode 100644 index 00000000..79b9b720 --- /dev/null +++ b/luci-app-cpu-status/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2026 gSpot (https://github.com/gSpotx2f/luci-app-cpu-status) +# +# This is free software, licensed under the MIT License. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-cpu-status +PKG_VERSION:=0.6.3 +PKG_RELEASE:=1 +LUCI_TITLE:=CPU utilization info for the LuCI status page +LUCI_PKGARCH:=all +PKG_LICENSE:=MIT + +#include ../../luci.mk +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-cpu-status/README.md b/luci-app-cpu-status/README.md new file mode 100644 index 00000000..b7d3faa7 --- /dev/null +++ b/luci-app-cpu-status/README.md @@ -0,0 +1,42 @@ +# luci-app-cpu-status +CPU utilization info for the LuCI status page (OpenWrt webUI). + +OpenWrt >= 21.02. + +Lite version: [luci-app-cpu-status-mini](https://github.com/gSpotx2f/luci-app-cpu-status-mini). + +## Installation notes + +**OpenWrt >= 25.12:** + + wget --no-check-certificate -O /tmp/luci-app-cpu-status-0.6.3-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-cpu-status-0.6.3-r1.apk + apk --allow-untrusted add /tmp/luci-app-cpu-status-0.6.3-r1.apk + rm /tmp/luci-app-cpu-status-0.6.3-r1.apk + service rpcd reload + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-cpu-status-ru-0.6.3-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-cpu-status-ru-0.6.3-r1.apk + apk --allow-untrusted add /tmp/luci-i18n-cpu-status-ru-0.6.3-r1.apk + rm /tmp/luci-i18n-cpu-status-ru-0.6.3-r1.apk + +**OpenWrt <= 24.10:** + + wget --no-check-certificate -O /tmp/luci-app-cpu-status_0.6.3-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-cpu-status_0.6.3-r1_all.ipk + opkg install /tmp/luci-app-cpu-status_0.6.3-r1_all.ipk + rm /tmp/luci-app-cpu-status_0.6.3-r1_all.ipk + service rpcd reload + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-cpu-status-ru_0.6.3-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-cpu-status-ru_0.6.3-r1_all.ipk + opkg install /tmp/luci-i18n-cpu-status-ru_0.6.3-r1_all.ipk + rm /tmp/luci-i18n-cpu-status-ru_0.6.3-r1_all.ipk + +## Screenshots: + +![](https://github.com/gSpotx2f/luci-app-cpu-status/blob/master/screenshots/01.jpg) + +## Related LuCI applications: + +CPU performance: [https://github.com/gSpotx2f/luci-app-cpu-perf](https://github.com/gSpotx2f/luci-app-cpu-perf). diff --git a/luci-app-cpu-status/htdocs/luci-static/resources/svg/cpu.svg b/luci-app-cpu-status/htdocs/luci-static/resources/svg/cpu.svg new file mode 100644 index 00000000..59eec308 --- /dev/null +++ b/luci-app-cpu-status/htdocs/luci-static/resources/svg/cpu.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/luci-app-cpu-status/htdocs/luci-static/resources/view/status/cpu.js b/luci-app-cpu-status/htdocs/luci-static/resources/view/status/cpu.js new file mode 100644 index 00000000..ed8e2297 --- /dev/null +++ b/luci-app-cpu-status/htdocs/luci-static/resources/view/status/cpu.js @@ -0,0 +1,509 @@ +'use strict'; +'require dom'; +'require fs'; +'require poll'; +'require request'; +'require view'; +'require ui'; + +document.head.append(E('style', {'type': 'text/css'}, +` +:root { + --app-cpu-status-total: gray; + --app-cpu-status-user: blue; + --app-cpu-status-sys: red; + --app-cpu-status-sirq: green; +} +.svg_background { + width: 100%; + height: 300px; + border: 1px solid #000; + background: #fff'; +} +[data-darkmode="true"] .svg_background { + background-color: var(--background-color-high) !important; +} +.graph_legend { + border-bottom: 2px solid; +} +.total { + border-color: var(--app-cpu-status-total); +} +.user{ + border-color: var(--app-cpu-status-user); +} +.sys { + border-color: var(--app-cpu-status-sys); +} +.sirq { + border-color: var(--app-cpu-status-sirq); +} +svg line.grid { + stroke: black; + stroke-width: 0.1; +} +[data-darkmode="true"] svg line.grid { + stroke: #fff !important; +} +svg text { + fill: #eee; + font-size: 9pt; + font-family: sans-serif; + text-shadow: 1px 1px 1px #000; +} +svg #total_line { + fill: var(--app-cpu-status-total); + fill-opacity: 0.4; + stroke: var(--app-cpu-status-total); + stroke-width: 1; +} +svg #user_line { + fill: var(--app-cpu-status-user); + fill-opacity: 0.5; + stroke: var(--app-cpu-status-user); + stroke-width: 1; +} +svg #sys_line { + fill: var(--app-cpu-status-sys); + fill-opacity: 0.5; + stroke: var(--app-cpu-status-sys); + stroke-width: 1; +} +svg #sirq_line { + fill: var(--app-cpu-status-sirq); + fill-opacity: 0.5; + stroke: var(--app-cpu-status-sirq); + stroke-width: 1; +} +`)); + +Math.log2 = Math.log2 || (x => Math.log(x) * Math.LOG2E); + +return view.extend({ + pollInterval : 3, + + dataBufferSize: 4, + + CPUDevices : {}, + + graphPolls : [], + + lastStatArray : null, + + parseProcData(data) { + let cpu_stat_array = []; + let stat_items_array = data.trim().split('\n').filter(s => s.startsWith('cpu')); + + for(let str of stat_items_array) { + let arr = str.split(/\s+/).slice(0, 8); + arr[0] = (arr[0] === 'cpu') ? -1 : arr[0].replace('cpu', ''); + cpu_stat_array.push(arr.map(e => Number(e))); + }; + + cpu_stat_array.sort((a, b) => a[0] - b[0]); + return cpu_stat_array; + }, + + calcCPULoad(cpu_stat_array) { + let ret_array = []; + cpu_stat_array.forEach((c, i) => { + let loadUser = 0, + loadNice = 0, + loadSys = 0, + loadIdle = 0, + loadIo = 0, + loadIrq = 0, + loadSirq = 0, + loadAvg = 0; + if(this.lastStatArray !== null && this.lastStatArray.cpuNum === c.cpuNum) { + let user = c[1] - this.lastStatArray[i][1], + nice = c[2] - this.lastStatArray[i][2], + sys = c[3] - this.lastStatArray[i][3], + idle = c[4] - this.lastStatArray[i][4], + io = c[5] - this.lastStatArray[i][5], + irq = c[6] - this.lastStatArray[i][6], + sirq = c[7] - this.lastStatArray[i][7]; + let sum = user + nice + sys + idle + io + irq + sirq; + loadUser = Number((100 * user / sum).toFixed(1)); + loadNice = Number((100 * nice / sum).toFixed(1)); + loadSys = Number((100 * sys / sum).toFixed(1)); + loadIdle = Number((100 * idle / sum).toFixed(1)); + loadIo = Number((100 * io / sum).toFixed(1)); + loadIrq = Number((100 * irq / sum).toFixed(1)); + loadSirq = Number((100 * sirq / sum).toFixed(1)); + loadAvg = Math.round(100 * (user + nice + sys + io + irq + sirq) / sum); + }; + ret_array.push( + {cpuNum: c[0], loadUser, loadNice, loadSys, loadIdle, loadIo, loadIrq, loadSirq, loadAvg}); + }); + this.lastStatArray = cpu_stat_array; + return ret_array; + }, + + getCPUData(cpu_data) { + return L.resolveDefault(fs.read('/proc/stat'), null).then(cpu_data => { + if(cpu_data) { + let cpu_stat_array = this.parseProcData(cpu_data); + + // For single-core CPU + if(cpu_stat_array.length === 2) { + cpu_stat_array = cpu_stat_array.slice(0, 1); + }; + + let cpu_load_array = this.calcCPULoad(cpu_stat_array); + + for(let i = 0; i < cpu_load_array.length; i++) { + let num = i; + let total = cpu_load_array[i].loadAvg; + let user = cpu_load_array[i].loadUser; + let sys = cpu_load_array[i].loadSys; + let sirq = cpu_load_array[i].loadSirq; + + if(!(num in this.CPUDevices)) { + this.CPUDevices[num] = { + num : i, + name: String(cpu_load_array[i].cpuNum), + load: [], + }; + }; + + let load_array = this.CPUDevices[num].load; + load_array.push([ + new Date().getTime(), + total || 0, + user || 0, + sys || 0, + sirq || 0, + ]); + if(load_array.length > this.dataBufferSize) { + load_array.shift(); + }; + }; + + }; + return this.CPUDevices; + }); + }, + + loadSVG(src) { + return request.get(src).then(response => { + if(!response.ok) { + throw new Error(response.statusText); + }; + + return E('div', { + 'class': 'svg_background', + }, E(response.text())); + }); + }, + + updateGraph(cpu_num, svg, peak, lines, cb) { + let G = svg.firstElementChild; + let view = document.querySelector('#view'); + let width = view.offsetWidth - 2; + let height = 300 - 2; + let base_step = 5; + let time_interval = 60; + let time_interval_min = time_interval / 60 + let step = base_step * this.pollInterval; + let data_wanted = Math.ceil(width / step); + let timeline_offset = width % step; + let data_values = []; + let line_elements = []; + + for(let i = 0; i < lines.length; i++) { + if(lines[i] != null) { + data_values.push([]); + }; + }; + + let info = { + line_current: [], + line_average: [], + line_peak : [], + }; + + /* prefill datasets */ + for(let i = 0; i < data_values.length; i++) { + for(let j = 0; j < data_wanted; j++) { + data_values[i][j] = NaN; + }; + }; + + /* plot horizontal time interval lines */ + for(let i = width % (base_step * time_interval); i < width; i += base_step * time_interval) { + let x = i - (timeline_offset); + let line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); + line.setAttribute('x1', x); + line.setAttribute('y1', 0); + line.setAttribute('x2', x); + line.setAttribute('y2', '100%'); + line.setAttribute('class', 'grid'); + + let text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + text.setAttribute('x', x + 5); + text.setAttribute('y', 15); + text.append(document.createTextNode(String((width - i) / base_step / time_interval) + 'm')); + + G.append(line); + G.append(text); + }; + + info.interval = this.pollInterval; + info.timeframe = Math.floor(data_wanted / time_interval * this.pollInterval); + + this.graphPolls.push({ + cpu_num, + svg, + peak, + lines, + cb, + info, + width, + height, + step, + data_wanted, + values : data_values, + timestamp : 0, + fill : 1, + }); + }, + + pollData() { + poll.add(L.bind(function() { + return this.getCPUData().then(L.bind(function(datasets) { + + for(let gi = 0; gi < this.graphPolls.length; gi++) { + let ctx = this.graphPolls[gi]; + + if(!datasets[ctx.cpu_num]) { + continue; + }; + + let data = datasets[ctx.cpu_num].load; + + if(!data) { + continue; + }; + + let values = ctx.values; + let lines = ctx.lines; + let info = ctx.info; + let peak = ctx.peak; + let data_scale = 0; + let data_wanted = ctx.data_wanted; + let last_timestamp = NaN; + + for(let i = 0, di = 0; di < lines.length; di++) { + if(lines[di] == null) { + continue; + }; + + for(let j = ctx.timestamp ? 0 : 1; j < data.length; j++) { + + /* skip overlapping and empty entries */ + if(data[j][0] <= ctx.timestamp) { + continue; + }; + + if(i == 0) { + ctx.fill++; + last_timestamp = data[j][0]; + }; + + info.line_current[i] = data[j][di + 1]; + values[i].push(info.line_current[i]); + }; + + i++; + }; + + /* cut off outdated entries */ + ctx.fill = Math.min(ctx.fill, data_wanted); + + for(let i = 0; i < values.length; i++) { + let len = values[i].length; + values[i] = values[i].slice(len - data_wanted, len); + + /* find peaks, averages */ + info.line_peak[i] = NaN; + info.line_average[i] = 0; + + let nonempty = 0; + for(let j = 0; j < values[i].length; j++) { + info.line_peak[i] = isNaN(info.line_peak[i]) ? values[i][j] : Math.max(info.line_peak[i], values[i][j]); + info.line_peak[i] = Number(info.line_peak[i].toFixed(1)); + + if(!isNaN(values[i][j])) { + nonempty++; + info.line_average[i] += values[i][j]; + }; + }; + + info.line_average[i] = info.line_average[i] / nonempty; + info.line_average[i] = Number(info.line_average[i].toFixed(1)); + }; + + /* remember current timestamp, calculate horizontal scale */ + if(!isNaN(last_timestamp)) { + ctx.timestamp = last_timestamp; + }; + + let size = Math.floor(Math.log2(info.peak)); + let div = Math.pow(2, size - (size % 10)); + data_scale = ctx.height / peak; + + /* plot data */ + for(let i = 0, di = 0; di < lines.length; di++) { + if(lines[di] == null) { + continue; + }; + + let el = ctx.svg.firstElementChild.getElementById(lines[di].line); + let pt = '0,' + ctx.height; + let y = 0; + + if(!el) { + continue; + }; + + for(let j = 0; j < values[i].length; j++) { + let x = j * ctx.step; + + y = ctx.height - Math.floor(values[i][j] * data_scale); + //y -= Math.floor(y % (1 / data_scale)); + y = isNaN(y) ? ctx.height + 1 : y; + pt += ` ${x},${y}`; + }; + + pt += ` ${ctx.width},${y} ${ctx.width},${ctx.height}`; + el.setAttribute('points', pt); + + i++; + }; + + info.label_25 = 0.25 * peak; + info.label_50 = 0.50 * peak; + info.label_75 = 0.75 * peak; + + if(typeof(ctx.cb) == 'function') { + ctx.cb(ctx.svg, info); + }; + }; + }, this)); + }, this), this.pollInterval); + }, + + load() { + return Promise.all([ + this.loadSVG(L.resource('svg/cpu.svg')), + this.getCPUData(), + ]); + }, + + render(data) { + let svg = data[0]; + let cpus = data[1]; + let map = E('div', { 'class': 'cbi-map', 'id': 'map' }); + let tabs = E('div'); + map.append(tabs); + + for(let i of Object.values(cpus)) { + let cpu_num = i.num; + let cpu_name = (Number(i.name) >= 0 ) ? `${_('CPU')} ${i.name}` : _('Total'); + let csvg = svg.cloneNode(true); + + tabs.append(E('div', { 'class': 'cbi-section', 'data-tab': cpu_num, 'data-tab-title': cpu_name }, [ + csvg, + E('div', { 'class': 'right' }, E('small', { 'data-graph': 'scale' }, '-')), + E('br'), + E('table', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [ + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td right top' }, E('strong', { 'class': 'graph_legend total' }, _('Total') + ':')), + E('td', { 'class': 'td', 'data-graph': 'total_cur' }, '-'), + E('td', { 'class': 'td right top' }, E('strong', {}, _('Average:'))), + E('td', { 'class': 'td', 'data-graph': 'total_avg' }, '-'), + + E('td', { 'class': 'td right top' }, E('strong', {}, _('Peak:'))), + E('td', { 'class': 'td', 'data-graph': 'total_peak' }, '-'), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td right top' }, E('strong', { 'class': 'graph_legend user' }, 'User' + ':')), + E('td', { 'class': 'td', 'data-graph': 'user_cur' }, '-'), + E('td', { 'class': 'td right top' }, E('strong', {}, _('Average:'))), + E('td', { 'class': 'td', 'data-graph': 'user_avg' }, '-'), + + E('td', { 'class': 'td right top' }, E('strong', {}, _('Peak:'))), + E('td', { 'class': 'td', 'data-graph': 'user_peak' }, '-'), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td right top' }, E('strong', { 'class': 'graph_legend sys' }, 'System' + ':')), + E('td', { 'class': 'td', 'data-graph': 'sys_cur' }, '-'), + E('td', { 'class': 'td right top' }, E('strong', {}, _('Average:'))), + E('td', { 'class': 'td', 'data-graph': 'sys_avg' }, '-'), + + E('td', { 'class': 'td right top' }, E('strong', {}, _('Peak:'))), + E('td', { 'class': 'td', 'data-graph': 'sys_peak' }, '-'), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td right top' }, E('strong', { 'class': 'graph_legend sirq' }, 'Sirq' + ':')), + E('td', { 'class': 'td', 'data-graph': 'sirq_cur' }, '-'), + E('td', { 'class': 'td right top' }, E('strong', {}, _('Average:'))), + E('td', { 'class': 'td', 'data-graph': 'sirq_avg' }, '-'), + + E('td', { 'class': 'td right top' }, E('strong', {}, _('Peak:'))), + E('td', { 'class': 'td', 'data-graph': 'sirq_peak' }, '-'), + ]), + + ]), + E('br'), + ])); + + this.updateGraph( + cpu_num, + csvg, + 100, + [ { 'line': 'total_line' }, { 'line': 'user_line' }, { 'line': 'sys_line' }, { 'line': 'sirq_line' } ], + (svg, info) => { + let G = svg.firstElementChild, tab = svg.parentNode; + + G.getElementById('label_25').firstChild.data = '%d %%'.format(info.label_25); + G.getElementById('label_50').firstChild.data = '%d %%'.format(info.label_50); + G.getElementById('label_75').firstChild.data = '%d %%'.format(info.label_75); + + tab.querySelector('[data-graph="scale"]').firstChild.data = _('(%d minute window, %d second interval)').format(info.timeframe, info.interval); + + dom.content(tab.querySelector('[data-graph="total_cur"]'), info.line_current[0] + ' %'); + dom.content(tab.querySelector('[data-graph="total_avg"]'), info.line_average[0] + ' %'); + dom.content(tab.querySelector('[data-graph="total_peak"]'), info.line_peak[0] + ' %'); + + dom.content(tab.querySelector('[data-graph="user_cur"]'), info.line_current[1] + ' %'); + dom.content(tab.querySelector('[data-graph="user_avg"]'), info.line_average[1] + ' %'); + dom.content(tab.querySelector('[data-graph="user_peak"]'), info.line_peak[1] + ' %'); + + dom.content(tab.querySelector('[data-graph="sys_cur"]'), info.line_current[2] + ' %'); + dom.content(tab.querySelector('[data-graph="sys_avg"]'), info.line_average[2] + ' %'); + dom.content(tab.querySelector('[data-graph="sys_peak"]'), info.line_peak[2] + ' %'); + + dom.content(tab.querySelector('[data-graph="sirq_cur"]'), info.line_current[3] + ' %'); + dom.content(tab.querySelector('[data-graph="sirq_avg"]'), info.line_average[3] + ' %'); + dom.content(tab.querySelector('[data-graph="sirq_peak"]'), info.line_peak[3] + ' %'); + } + ); + }; + + ui.tabs.initTabGroup(tabs.childNodes); + this.pollData(); + + return E([], [ + E('h2', _('CPU load')), + E('div', {'class': 'cbi-map-descr'}, + _('This page displays the average CPU load at %d second interval.').format(this.pollInterval)), + map, + ]); + }, + + handleSaveApply: null, + handleSave : null, + handleReset : null, +}); diff --git a/luci-app-cpu-status/htdocs/luci-static/resources/view/status/include/18_cpu.js b/luci-app-cpu-status/htdocs/luci-static/resources/view/status/include/18_cpu.js new file mode 100644 index 00000000..8aa0242d --- /dev/null +++ b/luci-app-cpu-status/htdocs/luci-static/resources/view/status/include/18_cpu.js @@ -0,0 +1,363 @@ +'use strict'; +'require baseclass'; +'require fs'; + +document.head.append(E('style', {'type': 'text/css'}, +` +.cpu-status-view-mode-entry { + display: inline-block; + cursor: pointer; + margin: 2px 4px 2px 0 !important; + padding: 3px 5px; + border: 1px solid; + border-color: transparent; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + opacity: 0.7; + background-color: rgba(100 100 100 / 0.2); +} +.cpu-status-view-mode-entry:hover { + opacity: 0.9; +} +.cpu-status-view-mode-entry:active { + opacity: 1.0; +} +.cpu-status-view-mode-entry-checked { + border: 1px solid; + opacity: 1.0; +} +.cpu-status-view-mode-entry-checked:hover { + opacity: 1.0; +} +`)); + +return baseclass.extend({ + title : _('CPU Load'), + + viewName : 'cpu_status', + + availableViewModes: { + 0: [ 'allCPUs', _('Load') ], + 1: [ 'allCPUsDetail', _('Detailed load') ], + 2: [ 'eachCPU', _('Load of each CPU') ], + 3: [ 'eachCPUDetail', _('Detailed load of each CPU') ], + }, + + viewMode : 0, + + lastStatArray : null, + + restoreSettingsFromLocalStorage() { + let viewModeLocal = localStorage.getItem(`luci-app-${this.viewName}-viewMode`); + if(viewModeLocal) { + this.viewMode = Number(viewModeLocal); + }; + }, + + saveSettingsToLocalStorage(viewMode) { + if(this.viewMode != viewMode) { + localStorage.setItem( + `luci-app-${this.viewName}-viewMode`, String(viewMode)); + }; + }, + + parseProcData(data) { + let cpuStatArray = []; + let statItemsArray = data.trim().split('\n').filter(s => s.startsWith('cpu')); + + for(let str of statItemsArray) { + let arr = str.split(/\s+/).slice(0, 8); + arr[0] = (arr[0] == 'cpu') ? Infinity : arr[0].replace('cpu', ''); + cpuStatArray.push(arr.map(e => Number(e))); + }; + + cpuStatArray.sort((a, b) => a[0] - b[0]); + + return cpuStatArray; + }, + + calcCPULoad(cpuStatArray) { + let retArray = []; + cpuStatArray.forEach((c, i) => { + let loadUser = 0, + loadNice = 0, + loadSys = 0, + loadIdle = 0, + loadIo = 0, + loadIrq = 0, + loadSirq = 0, + loadAvg = 0; + if(this.lastStatArray !== null && this.lastStatArray.cpuNum == c.cpuNum) { + let user = c[1] - this.lastStatArray[i][1], + nice = c[2] - this.lastStatArray[i][2], + sys = c[3] - this.lastStatArray[i][3], + idle = c[4] - this.lastStatArray[i][4], + io = c[5] - this.lastStatArray[i][5], + irq = c[6] - this.lastStatArray[i][6], + sirq = c[7] - this.lastStatArray[i][7]; + let sum = user + nice + sys + idle + io + irq + sirq; + loadUser = Number((100 * user / sum).toFixed(1)); + loadNice = Number((100 * nice / sum).toFixed(1)); + loadSys = Number((100 * sys / sum).toFixed(1)); + loadIdle = Number((100 * idle / sum).toFixed(1)); + loadIo = Number((100 * io / sum).toFixed(1)); + loadIrq = Number((100 * irq / sum).toFixed(1)); + loadSirq = Number((100 * sirq / sum).toFixed(1)); + loadAvg = Math.round(100 * (user + nice + sys + io + irq + sirq) / sum); + }; + retArray.push( + {cpuNum: c[0], loadUser, loadNice, loadSys, loadIdle, loadIo, loadIrq, loadSirq, loadAvg}); + }); + return retArray; + }, + + allCPUs: { + makeTable() { + this.table = E('table', { 'class': 'table' }); + }, + append(cpuNum, cpuLoadObj, cpuLoadFlag) { + if(cpuNum == Infinity) { + this.table.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'width': '33%' }, + _('Total load')), + E('td', { 'class': 'td' }, + E('div', { + 'class': 'cbi-progressbar', + 'title': (cpuLoadFlag) ? + cpuLoadObj.loadAvg + '%' : + _('Calculating') + '...', + }, + E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' }) + ) + ), + ]) + ); + }; + }, + }, + + allCPUsDetail: { + cpuTableTitles: [ + _('All CPUs'), + _('Load'), + 'user %', + 'nice %', + 'system %', + 'idle %', + 'iowait %', + 'irq %', + 'softirq %', + ], + makeTable() { + this.table = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left' }, this.cpuTableTitles[0]), + E('th', { 'class': 'th left' }, this.cpuTableTitles[1]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[2]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[3]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[4]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[5]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[6]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[7]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[8]), + ]) + ); + }, + append(cpuNum, cpuLoadObj, cpuLoadFlag) { + if(cpuNum == Infinity) { + this.table.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[0] }, + _('Total load')), + E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[1] }, + E('div', { + 'class': 'cbi-progressbar', + 'title': (cpuLoadFlag) ? + cpuLoadObj.loadAvg + '%' : + _('Calculating') + '...', + 'style': 'min-width:8em !important', + }, + E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' }) + ) + ), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[2] }, cpuLoadObj.loadUser), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[3] }, cpuLoadObj.loadNice), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[4] }, cpuLoadObj.loadSys), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[5] }, cpuLoadObj.loadIdle), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[6] }, cpuLoadObj.loadIo), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[7] }, cpuLoadObj.loadIrq), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[8] }, cpuLoadObj.loadSirq), + ]) + ); + }; + }, + }, + + eachCPU: { + makeTable() { + this.table = E('table', { 'class': 'table' }); + }, + append(cpuNum, cpuLoadObj, cpuLoadFlag) { + this.table.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'width': '33%' }, + (cpuNum == Infinity) ? _('Total load') : _('CPU') + ' ' + cpuNum), + E('td', { 'class': 'td' }, + E('div', { + 'class': 'cbi-progressbar', + 'title': (cpuLoadFlag) ? + cpuLoadObj.loadAvg + '%' : + _('Calculating') + '...', + }, + E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' }) + ) + ), + ]) + ); + }, + }, + + eachCPUDetail: { + cpuTableTitles: [ + _('CPU'), + _('Load'), + 'user %', + 'nice %', + 'system %', + 'idle %', + 'iowait %', + 'irq %', + 'softirq %', + ], + makeTable() { + this.table = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left' }, this.cpuTableTitles[0]), + E('th', { 'class': 'th left' }, this.cpuTableTitles[1]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[2]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[3]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[4]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[5]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[6]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[7]), + E('th', { 'class': 'th center' }, this.cpuTableTitles[8]), + ]) + ); + }, + append(cpuNum, cpuLoadObj, cpuLoadFlag) { + this.table.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[0] }, + (cpuNum == Infinity) ? _('Total load') : _('CPU') + ' ' + cpuNum), + E('td', { 'class': 'td left', 'data-title': this.cpuTableTitles[1] }, + E('div', { + 'class': 'cbi-progressbar', + 'title': (cpuLoadFlag) ? + cpuLoadObj.loadAvg + '%' : + _('Calculating') + '...', + 'style': 'min-width:8em !important', + }, + E('div', { 'style': 'width:' + cpuLoadObj.loadAvg + '%' }) + ) + ), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[2] }, cpuLoadObj.loadUser), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[3] }, cpuLoadObj.loadNice), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[4] }, cpuLoadObj.loadSys), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[5] }, cpuLoadObj.loadIdle), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[6] }, cpuLoadObj.loadIo), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[7] }, cpuLoadObj.loadIrq), + E('td', { 'class': 'td center', + 'data-title': this.cpuTableTitles[8] }, cpuLoadObj.loadSirq), + ]) + ); + }, + }, + + makeCPUTable(cpuLoadArray) { + let currentView = (this.availableViewModes[this.viewMode] !== undefined) ? + this[this.availableViewModes[this.viewMode][0]] : + this[this.availableViewModes[0][0]]; + currentView.makeTable(); + cpuLoadArray.forEach((c, i) => { + currentView.append(c.cpuNum, c, (this.lastStatArray !== null)); + }); + return currentView.table; + }, + + load() { + this.restoreSettingsFromLocalStorage(); + return L.resolveDefault(fs.read('/proc/stat'), null); + }, + + render(cpuData) { + if(!cpuData) return; + + let cpuStatArray = this.parseProcData(cpuData); + + // For single-core CPU + if(cpuStatArray.length == 2) { + cpuStatArray = cpuStatArray.slice(1, 2); + delete this.availableViewModes[2]; + delete this.availableViewModes[3]; + if(this.viewMode > 1) this.viewMode = 0; + }; + + let cpuLoadArray = this.calcCPULoad(cpuStatArray); + let cpuTable = this.makeCPUTable(cpuLoadArray); + + let viewModeSelectFunc = value => { + this.saveSettingsToLocalStorage(value); + this.viewMode = value; + viewModeEntries.forEach(i => { + i.classList.remove('cpu-status-view-mode-entry-checked'); + }); + viewModeEntries[value].classList.add('cpu-status-view-mode-entry-checked'); + let newTable = this.makeCPUTable(cpuLoadArray); + cpuTable.replaceWith(newTable); + cpuTable = newTable; + }; + + let viewModeSelectOnClick = ev => { + viewModeSelectFunc(ev.target.dataset.value); + ev.target.blur(); + }; + + let viewModeEntries = []; + + for(let [i, v] of Object.entries(this.availableViewModes)) { + viewModeEntries.push( + E('span', { + 'class' : 'cpu-status-view-mode-entry', + 'data-value': i, + 'click' : viewModeSelectOnClick, + }, v[1]) + ); + }; + + viewModeSelectFunc(this.viewMode); + + this.lastStatArray = cpuStatArray; + + return E('div', { 'class': 'cbi-section' }, [ + E('div', { 'style': 'margin-bottom:1em' }, + viewModeEntries + ), + cpuTable, + ]); + }, +}); diff --git a/luci-app-cpu-status/po/ru/cpu-status.po b/luci-app-cpu-status/po/ru/cpu-status.po new file mode 100644 index 00000000..9e9d4449 --- /dev/null +++ b/luci-app-cpu-status/po/ru/cpu-status.po @@ -0,0 +1,58 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Language: ru\n" + +msgid "(%d minute window, %d second interval)" +msgstr "(%d минутное окно, %d Ñекундный интервал)" + +msgid "All CPUs" +msgstr "Ð’Ñе ЦПУ" + +msgid "Average:" +msgstr "СреднÑÑ:" + +msgid "Calculating" +msgstr "ВычиÑление" + +msgid "CPU" +msgstr "ЦПУ" + +msgid "CPU Load" +msgstr "Загрузка ЦПУ" + +msgid "CPU load" +msgstr "Загрузка ЦПУ" + +msgid "Detailed load" +msgstr "ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°" + +msgid "Detailed load of each CPU" +msgstr "ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° каждого ЦПУ" + +msgid "Load" +msgstr "Загрузка" + +msgid "Load of each CPU" +msgstr "Загрузка каждого ЦПУ" + +msgid "Peak:" +msgstr "ПиковаÑ:" + +msgid "This page displays the average CPU load at %d second interval." +msgstr "Ðа Ñтой Ñтранице отображаетÑÑ ÑреднÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ° ЦПУ за %d Ñекундный интервал." + +msgid "Total" +msgstr "ОбщаÑ" + +msgid "Total load" +msgstr "ÐžÐ±Ñ‰Ð°Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°" diff --git a/luci-app-cpu-status/po/templates/cpu-status.pot b/luci-app-cpu-status/po/templates/cpu-status.pot new file mode 100644 index 00000000..ceece785 --- /dev/null +++ b/luci-app-cpu-status/po/templates/cpu-status.pot @@ -0,0 +1,47 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "(%d minute window, %d second interval)" +msgstr "" + +msgid "All CPUs" +msgstr "" + +msgid "Average:" +msgstr "" + +msgid "Calculating" +msgstr "" + +msgid "CPU" +msgstr "" + +msgid "CPU Load" +msgstr "" + +msgid "CPU load" +msgstr "" + +msgid "Detailed load" +msgstr "" + +msgid "Detailed load of each CPU" +msgstr "" + +msgid "Load" +msgstr "" + +msgid "Load of each CPU" +msgstr "" + +msgid "Peak:" +msgstr "" + +msgid "This page displays the average CPU load at %d second interval." +msgstr "" + +msgid "Total" +msgstr "" + +msgid "Total load" +msgstr "" diff --git a/luci-app-cpu-status/po/zh_Hans/cpu-status.po b/luci-app-cpu-status/po/zh_Hans/cpu-status.po new file mode 100644 index 00000000..d9c68456 --- /dev/null +++ b/luci-app-cpu-status/po/zh_Hans/cpu-status.po @@ -0,0 +1,58 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Language: zh_Hans\n" + +msgid "(%d minute window, %d second interval)" +msgstr "(最近 %d 分钟信æ¯ï¼Œæ¯ %d 秒刷新)" + +msgid "All CPUs" +msgstr "所有 CPU" + +msgid "Average:" +msgstr "å¹³å‡ï¼š" + +msgid "Calculating" +msgstr "计算中..." + +msgid "CPU" +msgstr "CPU" + +msgid "CPU Load" +msgstr "CPU" + +msgid "CPU load" +msgstr "CPU è´Ÿè½½" + +msgid "Detailed load" +msgstr "负载详情" + +msgid "Detailed load of each CPU" +msgstr "å„ CPU 负载详情" + +msgid "Load" +msgstr "è´Ÿè½½" + +msgid "Load of each CPU" +msgstr "å„ CPU è´Ÿè½½" + +msgid "Peak:" +msgstr "峰值:" + +msgid "This page displays the average CPU load at %d second interval." +msgstr "此页é¢å±•示 %d 秒内 CPU å¹³å‡è´Ÿè½½ã€‚" + +msgid "Total" +msgstr "总计" + +msgid "Total load" +msgstr "总负载" diff --git a/luci-app-cpu-status/po/zh_Hant/cpu-status.po b/luci-app-cpu-status/po/zh_Hant/cpu-status.po new file mode 100644 index 00000000..79bb56ce --- /dev/null +++ b/luci-app-cpu-status/po/zh_Hant/cpu-status.po @@ -0,0 +1,40 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Language: zh_Hant\n" + +msgid "All CPUs" +msgstr "所有 CPUs" + +msgid "Calculating" +msgstr "計算中" + +msgid "CPU" +msgstr "CPU" + +msgid "CPU Load" +msgstr "CPU 負載" + +msgid "Detailed load" +msgstr "詳細負載" + +msgid "Detailed load of each CPU" +msgstr "詳細負載 (æ¯å€‹ CPU)" + +msgid "Load" +msgstr "負載" + +msgid "Load of each CPU" +msgstr "負載 (æ¯å€‹ CPU)" + +msgid "Total load" +msgstr "總負載" diff --git a/luci-app-cpu-status/root/usr/share/luci/menu.d/luci-app-cpu-status.json b/luci-app-cpu-status/root/usr/share/luci/menu.d/luci-app-cpu-status.json new file mode 100644 index 00000000..64e4bc6f --- /dev/null +++ b/luci-app-cpu-status/root/usr/share/luci/menu.d/luci-app-cpu-status.json @@ -0,0 +1,13 @@ +{ + "admin/status/realtime/cpu": { + "title": "CPU", + "order": 9, + "action": { + "type": "view", + "path": "status/cpu" + }, + "depends": { + "acl": [ "luci-app-cpu-status" ] + } + } +} diff --git a/luci-app-cpu-status/root/usr/share/rpcd/acl.d/luci-app-cpu-status.json b/luci-app-cpu-status/root/usr/share/rpcd/acl.d/luci-app-cpu-status.json new file mode 100644 index 00000000..229c8203 --- /dev/null +++ b/luci-app-cpu-status/root/usr/share/rpcd/acl.d/luci-app-cpu-status.json @@ -0,0 +1,10 @@ +{ + "luci-app-cpu-status": { + "description": "Grant access to cpu-status procedures", + "read": { + "file": { + "/proc/stat": [ "read" ] + } + } + } +} diff --git a/luci-app-cpu-status/screenshots/01.jpg b/luci-app-cpu-status/screenshots/01.jpg new file mode 100644 index 00000000..5c0556da Binary files /dev/null and b/luci-app-cpu-status/screenshots/01.jpg differ diff --git a/luci-app-cpu-status/screenshots/02.jpg b/luci-app-cpu-status/screenshots/02.jpg new file mode 100644 index 00000000..9f919aef Binary files /dev/null and b/luci-app-cpu-status/screenshots/02.jpg differ diff --git a/luci-app-disks-info/LICENSE b/luci-app-disks-info/LICENSE new file mode 100644 index 00000000..48f616c1 --- /dev/null +++ b/luci-app-disks-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 gSpotx2f + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/luci-app-disks-info/Makefile b/luci-app-disks-info/Makefile new file mode 100644 index 00000000..630f0931 --- /dev/null +++ b/luci-app-disks-info/Makefile @@ -0,0 +1,20 @@ +# +# Copyright (C) 2025 gSpot (https://github.com/gSpotx2f/luci-app-disks-info) +# +# This is free software, licensed under the MIT License. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-disks-info +PKG_VERSION:=0.6.1 +PKG_RELEASE:=1 +LUCI_TITLE:=Information about connected disk devices (partitions, filesystems, SMART). +LUCI_DEPENDS:=+ucode +ucode-mod-fs +fdisk +smartmontools +smartmontools-drivedb +LUCI_PKGARCH:=all +PKG_LICENSE:=MIT + +#include ../../luci.mk +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-disks-info/README.md b/luci-app-disks-info/README.md new file mode 100644 index 00000000..4ad60277 --- /dev/null +++ b/luci-app-disks-info/README.md @@ -0,0 +1,40 @@ +# luci-app-disks-info +Status of connected disk devices (partitions, filesystems, SMART) for LuCI (OpenWrt webUI). + +OpenWrt >= 22.03. + +**Dependences:** ucode, ucode-mod-fs, fdisk, smartmontools, smartmontools-drivedb. + +## Installation notes + +**OpenWrt >= 25.12:** + + apk update + wget --no-check-certificate -O /tmp/luci-app-disks-info-0.6.1-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-disks-info-0.6.1-r1.apk + apk --allow-untrusted add /tmp/luci-app-disks-info-0.6.1-r1.apk + rm /tmp/luci-app-disks-info-0.6.1-r1.apk + service rpcd restart + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-disks-info-ru-0.6.1-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-disks-info-ru-0.6.1-r1.apk + apk --allow-untrusted add /tmp/luci-i18n-disks-info-ru-0.6.1-r1.apk + rm /tmp/luci-i18n-disks-info-ru-0.6.1-r1.apk + +**OpenWrt <= 24.10:** + + opkg update + wget --no-check-certificate -O /tmp/luci-app-disks-info_0.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-disks-info_0.6.1-r1_all.ipk + opkg install /tmp/luci-app-disks-info_0.6.1-r1_all.ipk + rm /tmp/luci-app-disks-info_0.6.1-r1_all.ipk + service rpcd restart + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-disks-info-ru_0.6.1-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-disks-info-ru_0.6.1-r1_all.ipk + opkg install /tmp/luci-i18n-disks-info-ru_0.6.1-r1_all.ipk + rm /tmp/luci-i18n-disks-info-ru_0.6.1-r1_all.ipk + +## Screenshots: + +![](https://github.com/gSpotx2f/luci-app-disks-info/blob/master/screenshots/01.jpg) diff --git a/luci-app-disks-info/htdocs/luci-static/resources/view/disks-info.js b/luci-app-disks-info/htdocs/luci-static/resources/view/disks-info.js new file mode 100644 index 00000000..e36e42bc --- /dev/null +++ b/luci-app-disks-info/htdocs/luci-static/resources/view/disks-info.js @@ -0,0 +1,1000 @@ +'use strict'; +'require fs'; +'require rpc'; +'require ui'; +'require view'; + +document.head.append(E('style', {'type': 'text/css'}, +` +:root { + --app-disks-info-dark-font-color: #2e2e2e; + --app-disks-info-light-font-color: #fff; + --app-disks-info-warn-color: #fff7e2; + --app-disks-info-err-color: #fcc3bf; + --app-disks-info-ok-color-label: #2ea256; + --app-disks-info-err-color-label: #ff4e54; +} +:root[data-darkmode="true"] { + --app-disks-info-dark-font-color: #fff; + --app-disks-info-light-font-color: #fff; + --app-disks-info-warn-color: #8d7000; + --app-disks-info-err-color: #a93734; + --app-disks-info-ok-color-label: #007627; + --app-disks-info-err-color-label: #a93734; +} +.disks-info-label-status { + display: inline; + margin: 0 4px !important; + padding: 1px 4px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + text-transform: uppercase; + font-weight: bold; + line-height: 1.6em; +} +.disks-info-ok-label { + background-color: var(--app-disks-info-ok-color-label) !important; + color: var(--app-disks-info-light-font-color) !important; +} +.disks-info-err-label { + background-color: var(--app-disks-info-err-color-label) !important; + color: var(--app-disks-info-light-font-color) !important; +} +.disks-info-warn { + background-color: var(--app-disks-info-warn-color) !important; + color: var(--app-disks-info-dark-font-color) !important; +} +.disks-info-warn .td { + color: var(--app-disks-info-dark-font-color) !important; +} +.disks-info-warn td { + color: var(--app-disks-info-dark-font-color) !important; +} +.disks-info-err { + background-color: var(--app-disks-info-err-color) !important; + color: var(--app-disks-info-dark-font-color) !important; +} +.disks-info-err .td { + color: var(--app-disks-info-dark-font-color) !important; +} +.disks-info-err td { + color: var(--app-disks-info-dark-font-color) !important; +} +svg polyline.disks-info-temp-line { + fill: rgba(0 98 130 / 0.2) !important; + fill-opacity: 1; + stroke: rgba(0 98 130 / 1.0) !important; + stroke-width: 1; +} +svg line.disks-info-line-w { + stroke: orange !important; + stroke-opacity: 1; + stroke-width: 0.8; +} +svg line.disks-info-line-c { + stroke: red !important; + stroke-opacity: 1; + stroke-width: 0.7; +} +svg line.disks-info-time-grid { + stroke: rgba(122 122 122 / 0.2) !important; + stroke-width: 1; +} +svg text.disks-info-time-text { + fill: rgba(122 122 122 / 0.5) !important; + font-family: monospace; + font-size: 12px; + font-weight: bold; + writing-mode: vertical-rl; +} +svg line.disks-info-celsius-line { + stroke: rgba(122 122 122 / 0.2) !important; + stroke-width: 1; +} +svg text.disks-info-celsius-text { + fill: #eee !important; + font-family: monospace; + font-size: 14px; + text-shadow: 1px 1px 1px #000; +} +svg text.disks-info-summary-text { + fill: #eee !important; + font-family: monospace; + font-size: 12px; + text-shadow: 1px 1px 1px #000; +} +`)); + +return view.extend({ + viewName : 'disks-info', + + fsSpaceWarning : 90, + + ssdEnduranceWarning : 95, + + diskTempWarningDefault : 60, + + diskTempCriticalDefault: 80, + + smartCriticalAttrs : [ 5, 11, 183, 184, 187, 196, 197, 198, 200, 202, 220 ], + + smartTempAttrs : [ 190, 194 ], + + deviceRegExp : new RegExp('^((h|s)d[a-z]|nvme[0-9]+n[0-9]+)$'), + + availDeviceTypes : [ + { name: 'auto', title: _('auto') }, + { name: 'sat', title: _('SAT (SCSI to ATA Translation)') }, + ], + + smartctl : '/usr/sbin/smartctl', + + deviceType : {}, + + devices : [], + + callDevices : rpc.declare({ + object: 'luci.disks-info', + method: 'getDevices', + expect: { '': {} }, + }), + + restoreSettingsFromLocalStorage() { + let deviceType = localStorage.getItem(`luci-app-${this.viewName}-deviceType`); + if(deviceType) { + let items = deviceType.split(';'); + if(items.length > 0) { + for(let i of items) { + let [k, v] = i.split('='); + if(k && v) { + this.deviceType[k] = v; + }; + }; + }; + }; + }, + + saveSettingsToLocalStorage() { + let items = []; + for(let [k, v] of Object.entries(this.deviceType)) { + items.push(`${k}=${v}`); + }; + localStorage.setItem( + `luci-app-${this.viewName}-deviceType`, items.join(';')); + }, + + getDeviceData(device) { + let deviceType = this.deviceType[device] || this.availDeviceTypes[0].name; + return Promise.all([ + device, + L.resolveDefault(fs.exec_direct( + this.smartctl, + [ '-d', deviceType, '-iAHl', 'scttemp', '-l', 'error', '-l', 'devstat', '--json=c', device ], + 'json'), null), + ]); + }, + + setSctTempLogInterval(device) { + let deviceNormalized = device.replace(/\//g, '-'); + let num = document.getElementById('logging_interval_value' + deviceNormalized).value; + let pSave = document.getElementById('logging_interval_type' + deviceNormalized).checked; + + if(/^[0-9]{1,2}$/.test(num) && Number(num) > 0) { + num = String(Number(num)); + } else { + return; + }; + + return fs.exec(this.smartctl, + [ '-l', 'scttempint,' + (pSave ? num + ',p' : num), device ] + ).then(res => { + window.location.reload(); + }).catch(e => ui.addNotification(null, E('p', {}, e.message))); + }, + + createDiskTable(fdiskData, dfData) { + let diskInfoTable = E('table', { 'class': 'table' }); + for(let i of fdiskData.diskInfo) { + diskInfoTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _(i[0]) + ':'), + E('td', { 'class': 'td left' }, i[1]), + ]) + ); + }; + + let partitionsTablePlaceholder = E('tr', { 'class': 'tr placeholder' }, + E('td', { 'class': 'td' }, + E('em', {}, _('No partitions available')) + ) + ); + let dfTablePlaceholder = E('tr', { 'class': 'tr placeholder' }, + E('td', { 'class': 'td' }, + E('em', {}, _('No mounted filesystems')) + ) + ); + let partitionsTableTitles = [ + _('Device'), + _('Boot'), + _('Start'), + _('End'), + _('Sectors'), + _('Size'), + _('Type'), + ]; + let partitionsTable = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left' }, partitionsTableTitles[0]), + E('th', { 'class': 'th left' }, partitionsTableTitles[1]), + E('th', { 'class': 'th left' }, partitionsTableTitles[2]), + E('th', { 'class': 'th left' }, partitionsTableTitles[3]), + E('th', { 'class': 'th left' }, partitionsTableTitles[4]), + E('th', { 'class': 'th left' }, partitionsTableTitles[5]), + E('th', { 'class': 'th left' }, partitionsTableTitles[6]), + ]) + ); + let dfTableTitles = [ + _('Filesystem'), + _('Type'), + _('Size'), + _('Used'), + _('Available'), + _('Use') + ' %', + _('Mounted on'), + ]; + let dfTable = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left' }, dfTableTitles[0]), + E('th', { 'class': 'th left' }, dfTableTitles[1]), + E('th', { 'class': 'th left' }, dfTableTitles[2]), + E('th', { 'class': 'th left' }, dfTableTitles[3]), + E('th', { 'class': 'th left' }, dfTableTitles[4]), + E('th', { 'class': 'th center' }, dfTableTitles[5]), + E('th', { 'class': 'th left' }, dfTableTitles[6]), + ]) + ); + + let partitions = fdiskData.partitions; + if(partitions) { + for(let i of partitions) { + partitionsTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[0], + }, i.device), + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[1], + }, (i.boot) ? _('yes') : _('no')), + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[2], + }, i.start), + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[3], + }, i.end), + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[4], + }, i.sectors), + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[6], + }, i.size), + E('td', { + 'class' : 'td left', + 'data-title': partitionsTableTitles[7], + }, i.type), + ]) + ); + }; + if(partitionsTable.children.length <= 1) { + partitionsTable.append(partitionsTablePlaceholder); + } else if(dfData) { + for(let i of dfData) { + dfTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { + 'class' : 'td left', + 'data-title': dfTableTitles[0], + }, i.filesystem), + E('td', { + 'class' : 'td left', + 'data-title': dfTableTitles[1], + }, i.type), + E('td', { + 'class' : 'td left', + 'data-title': dfTableTitles[2], + }, i.size), + E('td', { + 'class' : 'td left', + 'data-title': dfTableTitles[3], + }, i.used), + E('td', { + 'class' : 'td left', + 'data-title': dfTableTitles[4], + }, i.available), + E('td', { + 'class': (parseInt(i.use_perc) >= this.fsSpaceWarning) ? + 'td left disks-info-warn' : 'td left', + 'data-title': dfTableTitles[5], + }, E('div', { + 'class': 'cbi-progressbar', + 'title': i.use_perc, + 'style': 'min-width:8em !important', + }, + E('div', { 'style': 'width:' + i.use_perc }) + ) + ), + E('td', { + 'class' : 'td left', + 'data-title': dfTableTitles[6], + }, i.mounted), + ]), + ); + }; + if(dfTable.children.length <= 1) { + dfTable.append(dfTablePlaceholder); + }; + }; + } else { + partitionsTable.append(partitionsTablePlaceholder); + dfTable.append(dfTablePlaceholder); + }; + + return E([ + E('div', { 'class': 'cbi-value' }, diskInfoTable), + E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, _('Partitions') + ':'), + partitionsTable, + ]), + E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, _('Mounted filesystems') + ':'), + dfTable, + ]), + ]); + }, + + createSmartTable(smartObject) { + let smartStatusLabel = (smartObject.smart_status.passed) ? + E('span', { 'class': 'disks-info-label-status disks-info-ok-label' }, + _('passed')) + : + E('span', { 'class': 'disks-info-label-status disks-info-err-label' }, + _('failed')); + + let smartStatus = E('h5', { + 'style': 'width:100% !important; text-align:center !important', + }, [ + _('SMART overall-health self-assessment test result:'), + smartStatusLabel, + ]); + + let smartAttrsTable = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th right' }, _('Id')), + E('th', { 'class': 'th left' }, _('Attribute name')), + E('th', { 'class': 'th left' }, _('RAW')), + E('th', { 'class': 'th left' }, _('VALUE')), + E('th', { 'class': 'th left' }, _('WORST')), + E('th', { 'class': 'th left' }, _('THRESH')), + E('th', { 'class': 'th left' }, _('WHEN FAILED')), + ]) + ); + + for(let attr of smartObject.ata_smart_attributes.table) { + let tempValue; + let lineStyle = (attr.value <= attr.thresh) ? 'tr disks-info-err' : + (this.smartCriticalAttrs.includes(attr.id) && attr.raw.value > 0) ? 'tr disks-info-warn' : + (this.smartTempAttrs.includes(attr.id) && +(attr.raw.string.split(' ')[0]) >= this.diskTempWarning) ? + 'tr disks-info-warn' : 'tr'; + + smartAttrsTable.append( + E('tr', { + 'class': lineStyle, + }, [ + E('td', { 'class': 'td right', 'data-title': _('Id') }, + E('span', { + 'style': 'cursor:help; border-bottom:1px dotted', + 'data-tooltip': 'hex: %02X'.format(attr.id) + }, attr.id) + ), + E('td', { 'class': 'td left', 'data-title': _('Attribute name') }, + attr.name.replace(/_/g, ' ')), + E('td', { 'class': 'td left', 'data-title': _('RAW') }, + E('span', { + 'style': 'cursor:help; border-bottom:1px dotted; font-weight:bold', + 'data-tooltip': 'hex: %012X'.format(attr.raw.value) + }, attr.raw.string) + ), + E('td', { 'class': 'td left', 'data-title': _('VALUE') }, + '%03d'.format(attr.value)), + E('td', { 'class': 'td left', 'data-title': _('WORST') }, + '%03d'.format(attr.worst)), + E('td', { 'class': 'td left', 'data-title': _('THRESH') }, + '%03d'.format(attr.thresh)), + E('td', { 'class': 'td left', 'data-title': _('WHEN FAILED') }, + attr.when_failed || '-'), + ]) + ); + }; + + return E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, _('S.M.A.R.T.') + ':'), + smartStatus, + smartAttrsTable, + ]); + }, + + createErrorLog(table) { + let errorLogTable = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left', 'style':'min-width:16%' }, _('Error number')), + E('th', { 'class': 'th left', 'style':'min-width:17%' }, _('Lifetime hours')), + E('th', { 'class': 'th left' }, _('Description')), + ]) + ); + for(let errObj of table) { + errorLogTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Error number') }, + errObj.error_number), + E('td', { 'class': 'td left', 'data-title': _('Lifetime hours') }, + errObj.lifetime_hours), + E('td', { 'class': 'td left', 'data-title': _('Description') }, + errObj.error_description), + ]) + ); + }; + return E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, _('S.M.A.R.T. error log') + ':'), + E('div', { 'style': 'width:100%; max-height:20em; overflow:auto' }, + errorLogTable + ), + ]); + }, + + createTempTable(smartObject) { + return E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, _('Temperature') + ':'), + E('table', { 'class': 'table' }, [ + E('tr', { + 'class': (smartObject.temperature.current >= smartObject.temperature.op_limit_max) ? + 'tr disks-info-err' : (smartObject.temperature.current >= this.diskTempWarning) ? + 'tr disks-info-warn' : 'tr', + }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Current') + ':'), + E('td', { 'class': 'td left' }, ('current' in smartObject.temperature) ? + smartObject.temperature.current + ' °C' : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Lifetime min') + ':'), + E('td', { 'class': 'td left' }, ('lifetime_min' in smartObject.temperature) ? + smartObject.temperature.lifetime_min + ' °C' : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Lifetime max') + ':'), + E('td', { 'class': 'td left' }, ('lifetime_max' in smartObject.temperature) ? + smartObject.temperature.lifetime_max + ' °C' : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Recommended min') + ':'), + E('td', { 'class': 'td left' }, ('op_limit_min' in smartObject.temperature) ? + smartObject.temperature.op_limit_min + ' °C' : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Recommended max') + ':'), + E('td', { 'class': 'td left' }, ('op_limit_max' in smartObject.temperature) ? + smartObject.temperature.op_limit_max + ' °C' : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Limit min') + ':'), + E('td', { 'class': 'td left' }, ('limit_min' in smartObject.temperature) ? + smartObject.temperature.limit_min + ' °C' : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Limit max') + ':'), + E('td', { 'class': 'td left' }, ('limit_max' in smartObject.temperature) ? + smartObject.temperature.limit_max + ' °C' : null), + ]), + ]) + ]); + }, + + createSctTempArea(smartObject) { + let device = smartObject.device.name; + let deviceTime = smartObject.local_time.time_t; + let intervalMin = smartObject.ata_sct_temperature_history.logging_interval_minutes; + let intervalSec = intervalMin * 60; + let dataSize = smartObject.ata_sct_temperature_history.size; + let tempData = smartObject.ata_sct_temperature_history.table; + let dataUnits = []; + let tempMin = tempData.reduce( + (min, current) => (current < min && current !== null) ? current : min, + Infinity); + let tempMax = tempData.reduce( + (max, current) => (current > max && current !== null) ? current : max, + -Infinity); + let tempDiff = tempMax - tempMin; + + let i = dataSize - 1; + while(i >= 0) { + if(deviceTime % intervalSec == 0) { + dataUnits.push([i, tempData[i], new Date(deviceTime * 1000)]); + i--; + }; + deviceTime--; + }; + dataUnits.reverse(); + + // GRAPH + + let svgWidth = 900; + let svgHeight = 300; + let tempValueMul = (tempDiff >= 60) ? 3 : Math.round(svgHeight / (tempDiff + 20)); + let tempMinimalValue = (tempMin > 10) ? tempMin - 10 : 0; + let tempAxisStep = (tempDiff >= 60) ? 6 : (tempDiff >= 30) ? 4 : 2; + let timeAxisStep = svgWidth / dataSize; + let timeAxisInterval = Math.ceil(dataSize / 32); + + let svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.setAttribute('width', '100%'); + svg.setAttribute('height', '100%'); + svg.setAttribute('version', '1.1'); + svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + // temperature line + let tempLine = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); + tempLine.setAttribute('class', 'disks-info-temp-line'); + let tempPoints = [[0, svgHeight]]; + + for(let i = 0; i < dataSize; i++) { + tempPoints.push([ + i * timeAxisStep, + (dataUnits[i][1] != null) ? + (svgHeight - (dataUnits[i][1] - tempMinimalValue) * tempValueMul) : + svgHeight * 2 + ]); + }; + tempPoints.push([tempPoints[tempPoints.length - 1][0], svgHeight]); + tempLine.setAttribute('points', tempPoints.map(e => e.join(',')).join(' ')); + svg.appendChild(tempLine); + + // temperature warning + let lineW = document.createElementNS('http://www.w3.org/2000/svg', 'line'); + lineW.setAttribute('x1', 0); + lineW.setAttribute('y1', svgHeight - (this.diskTempWarning - tempMinimalValue) * tempValueMul); + lineW.setAttribute('x2', '100%'); + lineW.setAttribute('y2', svgHeight - (this.diskTempWarning - tempMinimalValue) * tempValueMul); + lineW.setAttribute('class', 'disks-info-line-w'); + svg.appendChild(lineW); + + // temperature critical + let lineC = document.createElementNS('http://www.w3.org/2000/svg', 'line'); + lineC.setAttribute('x1', 0); + lineC.setAttribute('y1', svgHeight - (this.diskTempCritical - tempMinimalValue) * tempValueMul); + lineC.setAttribute('x2', '100%'); + lineC.setAttribute('y2', svgHeight - (this.diskTempCritical - tempMinimalValue) * tempValueMul); + lineC.setAttribute('class', 'disks-info-line-c'); + svg.appendChild(lineC); + + // time labels + let j = 0; + for(let i = 0; i < svgWidth; i += timeAxisStep * timeAxisInterval) { + let line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); + line.setAttribute('x1', i); + line.setAttribute('y1', 0); + line.setAttribute('x2', i); + line.setAttribute('y2', '100%'); + line.setAttribute('class', 'disks-info-time-grid'); + svg.appendChild(line); + let text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + text.setAttribute('x', i + 6); + text.setAttribute('y', 0); + text.setAttribute('class', 'disks-info-time-text'); + if(i >= 2 * timeAxisStep * timeAxisInterval) { + text.appendChild(document.createTextNode('%02d.%02d %02d:%02d'.format( + dataUnits[j][2].getDate(), + dataUnits[j][2].getMonth() + 1, + dataUnits[j][2].getHours(), + dataUnits[j][2].getMinutes() + ))); + }; + j += timeAxisInterval; + svg.appendChild(text); + if(j >= dataSize) { + break; + }; + }; + + // temperature labels + let c = 0; + for(let i = svgHeight; i > 0; i -= tempValueMul * tempAxisStep) { + let line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); + line.setAttribute('x1', 0); + line.setAttribute('y1', i); + line.setAttribute('x2', '100%'); + line.setAttribute('y2', i); + line.setAttribute('class', 'disks-info-celsius-line'); + svg.appendChild(line); + let text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + text.setAttribute('x', 0); + text.setAttribute('y', i - 3); + text.setAttribute('class', 'disks-info-celsius-text'); + if(c % 2 == 0) { + text.appendChild(document.createTextNode(((svgHeight - i) / tempValueMul) + tempMinimalValue + ' °C')); + }; + svg.appendChild(text); + c++; + }; + + // temperature min/max, log interval + let text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + text.setAttribute('x', svgWidth / 3); + text.setAttribute('y', svgHeight - 10); + text.setAttribute('class', 'disks-info-summary-text'); + text.appendChild(document.createTextNode(`Interval:${intervalMin}m Tmin:${tempMin}°C Tmax:${tempMax}°C`)); + svg.appendChild(text); + + // TABLE + + dataUnits = dataUnits.filter((e, i, a) => { + return e[1] != ((a[i - 1] !== undefined) && a[i - 1][1]); + }); + + let sctTempTable = E('table', { 'class': 'table' }, + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left', 'style': 'width:33%' }, _('Index')), + E('th', { 'class': 'th left', 'style': 'width:33%' }, _('Estimated time')), + E('th', { 'class': 'th left' }, _('Temperature') + ' °C'), + ]) + ); + + for(let [num, temp, date] of dataUnits) { + if(temp === null) { + continue; + }; + sctTempTable.append( + E('tr', { + 'class': (temp >= this.diskTempCritical) ? 'tr disks-info-err' : + (temp >= this.diskTempWarning) ? 'tr disks-info-warn' : 'tr', + }, [ + E('td', { 'class': 'td left', 'data-title': _('Index') }, + num), + E('td', { 'class': 'td left', 'data-title': _('Estimated time') }, + '%d-%02d-%02d %02d:%02d'.format( + date.getFullYear(), + date.getMonth() + 1, + date.getDate(), + date.getHours(), + date.getMinutes() + )), + E('td', { 'class': 'td left', 'data-title': _('Temperature') + ' °C' }, + temp), + ]) + ); + }; + + let deviceNormalized = device.replace(/\//g, '-'); + let loggingIntervalValue = E('input', { + 'id' : 'logging_interval_value' + deviceNormalized, + 'type' : 'text', + 'class' : 'cbi-input-text', + 'style' : 'width:4em !important; min-width:4em !important', + 'maxlength' : 4, + 'value' : 1, + 'placeholder' : '1-1440', + }); + ui.addValidator(loggingIntervalValue, 'range(1,1440)', false); + + return E([ + E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, + `${_('SCT temperature history')} (${_('interval')}: ${intervalMin} ${_('min')}.):`), + E('div', { 'style': 'width:100%; min-height:' + (svgHeight + 20) + 'px; overflow:auto; margin-top:0.2em' }, + E('div', { + 'style': 'width:' + svgWidth + 'px; height:' + svgHeight + 'px; margin:auto', + }, svg) + ), + E('div', { 'style': 'width:100%; max-height:20em; overflow:auto; margin-top:0.2em' }, + sctTempTable + ), + ]), + + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'for': 'logging_interval_value' + deviceNormalized }, + _('Set logging interval') + ' (' + _('min') + ')'), + E('div', { 'class': 'cbi-value-field' }, loggingIntervalValue), + ]), + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'for': 'logging_interval_type' + deviceNormalized }, + _('Preserve across power cycles')), + E('div', { 'class': 'cbi-value-field' }, + E('div', { 'class': 'cbi-checkbox' }, [ + E('input', { + 'type': 'checkbox', + 'id' : 'logging_interval_type' + deviceNormalized, + }), + E('label', {}) + ]) + ), + ]), + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'for': 'apply_interval_value' + deviceNormalized }, + _('Write to disk device memory') + ), + E('div', { 'class': 'cbi-value-field' }, [ + E('div', {}, E('button', { + 'class': 'btn cbi-button-apply important', + 'click': ui.createHandlerFn(this, this.setSctTempLogInterval, device), + }, _('Apply'))), + E('input', { + 'id' : 'apply_interval_value' + deviceNormalized, + 'type': 'hidden', + }), + ]), + E('hr'), + ]), + + ]); + }, + + createDeviceStatistics(statObject) { + let statsArea = E('div', { 'class': 'cbi-value' }, + E('h3', {}, _('Device statistics') + ':') + ); + for(let page of statObject.pages) { + if(!page || !Array.isArray(page.table) || page.table.length == 0) { + continue; + }; + let pageTableTitle = E('h5', + { 'style': 'width:100% !important; text-align:left !important' }, + _(page.name) + ); + let pageTable = E('table', { 'class': 'table' }); + for(let entry of page.table) { + pageTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:50%' }, _(entry.name) + ':'), + (page.number == 7 && entry.offset == 8) ? + E('td', { + 'class': (entry.value >= this.ssdEnduranceWarning) ? + 'td left disks-info-warn' : 'td left', + }, + E('div', { + 'class': 'cbi-progressbar', + 'title': entry.value + '%', + 'data-tooltip': _('May not be supported by some devices...'), + }, + E('div', { 'style': 'width:' + entry.value + '%' }) + ) + ) + : + E('td', { 'class': 'td left' }, entry.value), + ]) + ); + }; + statsArea.append(pageTableTitle, pageTable); + }; + return statsArea; + }, + + createDeviceTable(smartObject) { + return E('div', { 'class': 'cbi-value' }, [ + E('h3', {}, _('Device') + ':'), + E('table', { 'class': 'table' }, [ + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Model Family') + ':'), + E('td', { 'class': 'td left' }, smartObject.model_family), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Device Model') + ':'), + E('td', { 'class': 'td left' }, smartObject.model_name), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Serial Number') + ':'), + E('td', { 'class': 'td left' }, smartObject.serial_number), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('LU WWN Device Id') + ':'), + E('td', { 'class': 'td left' }, ('wwn' in smartObject) ? + Object.values(smartObject.wwn).map( + e => e.toString(16)).join(' ') : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Firmware Version') + ':'), + E('td', { 'class': 'td left' }, smartObject.firmware_version), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('User Capacity') + ':'), + E('td', { 'class': 'td left' }, ('user_capacity' in smartObject) ? + `${smartObject.user_capacity.bytes} ${_('bytes')} [${(smartObject.user_capacity.bytes / 1e9).toFixed()} ${_('Gb')}] (${smartObject.user_capacity.blocks} ${_('blocks')})` + : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, `${_('Sector Size')} (${_('logical/physical')}):`), + E('td', { 'class': 'td left' }, ('logical_block_size' in smartObject) ? + `${smartObject.logical_block_size} ${_('bytes')} / ${smartObject.physical_block_size} ${_('bytes')}` + : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Rotation Rate') + ':'), + E('td', { 'class': 'td left' }, (smartObject.rotation_rate == 0) ? + _('Solid State Device') : smartObject.rotation_rate), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Form Factor') + ':'), + E('td', { 'class': 'td left' }, ('form_factor' in smartObject) ? + smartObject.form_factor.name : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Device is') + ':'), + E('td', { 'class': 'td left' }, smartObject.in_smartctl_database ? + _('In smartctl database [for details use: -P show]') : + _('Not in smartctl database [for details use: -P showall]')), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('ATA Version is') + ':'), + E('td', { 'class': 'td left' }, ('ata_version' in smartObject) ? + smartObject.ata_version.string : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('SATA Version is') + ':'), + E('td', { 'class': 'td left' }, ('sata_version' in smartObject) ? + smartObject.sata_version.string : null), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, _('Local Time is') + ':'), + E('td', { 'class': 'td left' }, ('local_time' in smartObject) ? + smartObject.local_time.asctime : null), + ]), + ]) + ]); + }, + + load() { + this.restoreSettingsFromLocalStorage(); + return L.resolveDefault(this.callDevices(), []); + }, + + render(devicesData) { + this.devices = devicesData.devices; + + let devicesNode = E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, + E('div', { 'class': 'cbi-value' }, + E('em', {}, _('No devices detected')) + ) + ) + ); + + if(this.devices && this.devices.length > 0) { + devicesNode = E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, + E('div', { 'class': 'cbi-value' }, + E('em', { 'class': 'spinning' }, _('Collecting data...')) + ) + ) + ); + + Promise.all( + this.devices.map(device => this.getDeviceData(device)) + ).then(data => { + let devicesTabs = E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, + E('div', { 'class': 'cbi-value' }, [ + E('div', { 'style': 'width:100%; text-align:right !important' }, + E('button', { + 'class': 'btn', + 'click': () => window.location.reload(), + }, _('Refresh devices')) + ) + ]) + ) + ); + + let tabsContainer = E('div', { 'class': 'cbi-section-node cbi-section-node-tabbed' }); + devicesTabs.append(tabsContainer); + + for(let i = 0; i < data.length; i++) { + let deviceName = data[i][0]; + let smart = data[i][1]; + let fdisk = devicesData.fdisk[deviceName]; + let df = devicesData.df[deviceName]; + let deviceTab = E('div', { + 'data-tab' : i, + 'data-tab-title': deviceName, + }); + tabsContainer.append(deviceTab); + + let deviceNormalized = deviceName.replace(/\//g, '-'); + let deviceTypeSelect = E('select', + { + 'id' : 'device_type' + deviceNormalized, + 'change': (ev) => { + this.deviceType[deviceName] = ev.target.value || this.availDeviceTypes[0].name; + this.saveSettingsToLocalStorage(); + window.location.reload(); + }, + } + ); + for(let i of this.availDeviceTypes) { + deviceTypeSelect.append(E('option', { 'value': i.name }, i.title)); + }; + deviceTypeSelect.value = this.deviceType[deviceName] || this.availDeviceTypes[0].name; + + deviceTab.append( + E('div', { 'class': 'cbi-value' }, [ + E('label', { 'class': 'cbi-value-title', 'for': 'device_type' + deviceNormalized }, + _('Device type')), + E('div', { 'class': 'cbi-value-field' }, + deviceTypeSelect + ), + ]), + ); + + if(fdisk && df) { + deviceTab.append(this.createDiskTable(fdisk, df)); + }; + + if(smart) { + let smartObject = smart; + + try { + smartObject = JSON.parse(smart); + } catch(err) {}; + + this.diskTempWarning = ( + smartObject.temperature && smartObject.temperature.op_limit_max || this.diskTempWarningDefault); + this.diskTempCritical = ( + smartObject.temperature && smartObject.temperature.limit_max || this.diskTempCriticalDefault); + + if('smart_status' in smartObject && 'ata_smart_attributes' in smartObject && + Array.isArray(smartObject.ata_smart_attributes.table) && + smartObject.ata_smart_attributes.table.length > 0) { + deviceTab.append(this.createSmartTable(smartObject)); + }; + if('ata_smart_error_log' in smartObject) { + if(smartObject.ata_smart_error_log.summary.table) { + deviceTab.append(this.createErrorLog(smartObject.ata_smart_error_log.summary.table)); + }; + }; + if('temperature' in smartObject) { + deviceTab.append(this.createTempTable(smartObject)); + }; + if('ata_sct_temperature_history' in smartObject && + Array.isArray(smartObject.ata_sct_temperature_history.table) && + smartObject.ata_sct_temperature_history.table.length > 0) { + deviceTab.append(this.createSctTempArea(smartObject)); + }; + if('ata_device_statistics' in smartObject && + Array.isArray(smartObject.ata_device_statistics.pages) && + smartObject.ata_device_statistics.pages.length > 0) { + deviceTab.append(this.createDeviceStatistics(smartObject.ata_device_statistics)); + }; + if('device' in smartObject) { + deviceTab.append(this.createDeviceTable(smartObject)); + }; + }; + }; + + ui.tabs.initTabGroup(tabsContainer.children); + devicesNode.replaceWith(devicesTabs); + }).catch(e => ui.addNotification(null, E('p', {}, e.message))); + }; + + return E([ + E('h2', { 'class': 'fade-in' }, _('Disk Devices')), + E('div', { 'class': 'cbi-section-descr fade-in' }, + _("Status of connected disk devices.")), + devicesNode, + ]); + }, + + handleSaveApply: null, + handleSave : null, + handleReset : null, +}); diff --git a/luci-app-disks-info/po/ru/disks-info.po b/luci-app-disks-info/po/ru/disks-info.po new file mode 100644 index 00000000..a02a0620 --- /dev/null +++ b/luci-app-disks-info/po/ru/disks-info.po @@ -0,0 +1,285 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ru\n" +"X-Generator: Poedit 2.0.6\n" + +msgid "ATA Version is" +msgstr "ВерÑÐ¸Ñ ATA" + +msgid "Apply" +msgstr "Применить" + +msgid "Attribute name" +msgstr "Ð˜Ð¼Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð°" + +msgid "Available" +msgstr "ДоÑтупно" + +msgid "Boot" +msgstr "Загрузочный" + +msgid "Collecting data..." +msgstr "Сбор данных..." + +msgid "Current" +msgstr "ТекущаÑ" + +msgid "Description" +msgstr "ОпиÑание" + +msgid "Device" +msgstr "УÑтройÑтво" + +msgid "Device Model" +msgstr "Модель уÑтройÑтва" + +msgid "Device is" +msgstr "УÑтройÑтво" + +msgid "Device statistics" +msgstr "СтатиÑтика уÑтройÑтва" + +msgid "Device type" +msgstr "Тип уÑтройÑтва" + +msgid "Disk model" +msgstr "Модель диÑка" + +msgid "Disk identifier" +msgstr "Идентификатор диÑка" + +msgid "Disklabel type" +msgstr "Тип разметки диÑка" + +msgid "Disk Devices" +msgstr "ДиÑковые уÑтройÑтва" + +msgid "End" +msgstr "Конец" + +msgid "Error number" +msgstr "Ðомер ошибки" + +msgid "Estimated time" +msgstr "РаÑчётное времÑ" + +msgid "Filesystem" +msgstr "Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема" + +msgid "Firmware Version" +msgstr "ВерÑÐ¸Ñ Ð¿Ñ€Ð¾ÑˆÐ¸Ð²ÐºÐ¸" + +msgid "Form Factor" +msgstr "Форм-фактор" + +msgid "Free-Fall Statistics" +msgstr "СтатиÑтика падений" + +msgid "Gb" +msgstr "Гб" + +msgid "General Statistics" +msgstr "ÐžÐ±Ñ‰Ð°Ñ ÑтатиÑтика" + +msgid "General Errors Statistics" +msgstr "ÐžÐ±Ñ‰Ð°Ñ ÑтатиÑтика ошибок" + +msgid "Id" +msgstr "" + +msgid "In smartctl database [for details use: -P show]" +msgstr "ÐаходитÑÑ Ð² базе smartctl [подробно: -P show]" + +msgid "Index" +msgstr "ИндекÑ" + +msgid "LU WWN Device Id" +msgstr "" + +msgid "Lifetime hours" +msgstr "ЧаÑов наработки" + +msgid "Lifetime max" +msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð·Ð° Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹" + +msgid "Lifetime min" +msgstr "ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð·Ð° Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹" + +msgid "Limit max" +msgstr "Лимит макÑ" + +msgid "Limit min" +msgstr "Лимит мин" + +msgid "Local Time is" +msgstr "Локальное времÑ" + +msgid "May not be supported by some devices..." +msgstr "Может не поддерживатьÑÑ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼Ð¸ уÑтройÑтвами..." + +msgid "Model Family" +msgstr "СемейÑтво моделей" + +msgid "Mounted filesystems" +msgstr "Смонтированные файловые ÑиÑтемы" + +msgid "Mounted on" +msgstr "Смонтировано" + +msgid "No devices detected" +msgstr "УÑтройÑтва не найдены" + +msgid "No mounted filesystems" +msgstr "Ðет Ñмонтированных файловых ÑиÑтем" + +msgid "No partitions available" +msgstr "Ðет доÑтупных разделов" + +msgid "Not in smartctl database [for details use: -P showall]" +msgstr "ОтÑутÑтвует в базе smartctl [подробно: -P showall]" + +msgid "Partitions" +msgstr "Разделы" + +msgid "Percentage Used Endurance Indicator" +msgstr "Процентный индикатор изноÑа" + +msgid "Preserve across power cycles" +msgstr "Сохранить при выключении питаниÑ" + +msgid "RAW" +msgstr "" + +msgid "Recommended max" +msgstr "Ð ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¼Ð°ÐºÑ" + +msgid "Recommended min" +msgstr "Ð ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¼Ð¸Ð½" + +msgid "Refresh devices" +msgstr "Обновить уÑтройÑтва" + +msgid "Rotating Media Statistics" +msgstr "СтатиÑтика механичеÑкой чаÑти" + +msgid "Rotation Rate" +msgstr "СкороÑть вращениÑ" + +msgid "S.M.A.R.T." +msgstr "" + +msgid "S.M.A.R.T. error log" +msgstr "Лог ошибок S.M.A.R.T." + +msgid "SATA Version is" +msgstr "ВерÑÐ¸Ñ SATA" + +msgid "SCT temperature history" +msgstr "Сводка температуры SCT" + +msgid "SMART overall-health self-assessment test result:" +msgstr "Результат теÑта оценки общего ÑоÑтоÑÐ½Ð¸Ñ SMART:" + +msgid "Set logging interval" +msgstr "Интервал логированиÑ" + +msgid "Sector Size" +msgstr "Размер Ñектора" + +msgid "Sector size (logical/physical)" +msgstr "Размер Ñектора (логичеÑкий/физичеÑкий)" + +msgid "Sectors" +msgstr "Секторы" + +msgid "Serial Number" +msgstr "Серийный номер" + +msgid "Size" +msgstr "Размер" + +msgid "Solid State Device Statistics" +msgstr "СтатиÑтика SSD" + +msgid "Start" +msgstr "Ðачало" + +msgid "Status of connected disk devices." +msgstr "СоÑтоÑние подключенных диÑковых уÑтройÑтв." + +msgid "Temperature" +msgstr "Температура" + +msgid "Temperature Statistics" +msgstr "СтатиÑтика температуры" + +msgid "THRESH" +msgstr "" + +msgid "Transport Statistics" +msgstr "СтатиÑтика транÑпорта" + +msgid "Type" +msgstr "Тип" + +msgid "Units" +msgstr "Единицы объёма" + +msgid "Use" +msgstr "ИÑпользуетÑÑ" + +msgid "Used" +msgstr "ИÑпользовано" + +msgid "User Capacity" +msgstr "ДоÑÑ‚ÑƒÐ¿Ð½Ð°Ñ Ñ‘Ð¼ÐºÐ¾Ñть" + +msgid "VALUE" +msgstr "" + +msgid "WHEN FAILED" +msgstr "" + +msgid "WORST" +msgstr "" + +msgid "Write to disk device memory" +msgstr "ЗапиÑать в памÑть диÑкового уÑтройÑтва" + +msgid "auto" +msgstr "авто" + +msgid "blocks" +msgstr "блоков" + +msgid "bytes" +msgstr "байт" + +msgid "failed" +msgstr "не пройден" + +msgid "interval" +msgstr "интервал" + +msgid "logical/physical" +msgstr "логичеÑкий/физичеÑкий" + +msgid "min" +msgstr "мин" + +msgid "no" +msgstr "нет" + +msgid "passed" +msgstr "пройден" + +msgid "да" +msgstr "" diff --git a/luci-app-disks-info/po/templates/disks-info.pot b/luci-app-disks-info/po/templates/disks-info.pot new file mode 100644 index 00000000..1ff8d8fc --- /dev/null +++ b/luci-app-disks-info/po/templates/disks-info.pot @@ -0,0 +1,275 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "ATA Version is" +msgstr "" + +msgid "Apply" +msgstr "" + +msgid "Attribute name" +msgstr "" + +msgid "Available" +msgstr "" + +msgid "Boot" +msgstr "" + +msgid "Collecting data..." +msgstr "" + +msgid "Current" +msgstr "" + +msgid "Description" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Device Model" +msgstr "" + +msgid "Device is" +msgstr "" + +msgid "Device statistics" +msgstr "" + +msgid "Device type" +msgstr "" + +msgid "Disk model" +msgstr "" + +msgid "Disk identifier" +msgstr "" + +msgid "Disklabel type" +msgstr "" + +msgid "Disk Devices" +msgstr "" + +msgid "End" +msgstr "" + +msgid "Error number" +msgstr "" + +msgid "Estimated time" +msgstr "" + +msgid "Filesystem" +msgstr "" + +msgid "Firmware Version" +msgstr "" + +msgid "Form Factor" +msgstr "" + +msgid "Free-Fall Statistics" +msgstr "" + +msgid "Gb" +msgstr "" + +msgid "General Statistics" +msgstr "" + +msgid "General Errors Statistics" +msgstr "" + +msgid "Id" +msgstr "" + +msgid "In smartctl database [for details use: -P show]" +msgstr "" + +msgid "Index" +msgstr "" + +msgid "LU WWN Device Id" +msgstr "" + +msgid "Lifetime hours" +msgstr "" + +msgid "Lifetime max" +msgstr "" + +msgid "Lifetime min" +msgstr "" + +msgid "Limit max" +msgstr "" + +msgid "Limit min" +msgstr "" + +msgid "Local Time is" +msgstr "" + +msgid "May not be supported by some devices..." +msgstr "" + +msgid "Model Family" +msgstr "" + +msgid "Mounted filesystems" +msgstr "" + +msgid "Mounted on" +msgstr "" + +msgid "No devices detected" +msgstr "" + +msgid "No mounted file systems" +msgstr "" + +msgid "No partitions available" +msgstr "" + +msgid "Not in smartctl database [for details use: -P showall]" +msgstr "" + +msgid "Partitions" +msgstr "" + +msgid "Percentage Used Endurance Indicator" +msgstr "" + +msgid "Preserve across power cycles" +msgstr "" + +msgid "RAW" +msgstr "" + +msgid "Recommended max" +msgstr "" + +msgid "Recommended min" +msgstr "" + +msgid "Refresh devices" +msgstr "" + +msgid "Rotating Media Statistics" +msgstr "" + +msgid "Rotation Rate" +msgstr "" + +msgid "S.M.A.R.T." +msgstr "" + +msgid "S.M.A.R.T. error log" +msgstr "" + +msgid "SATA Version is" +msgstr "" + +msgid "SCT temperature history" +msgstr "" + +msgid "SMART overall-health self-assessment test result:" +msgstr "" + +msgid "Set logging interval" +msgstr "" + +msgid "Sector Size" +msgstr "" + +msgid "Sector size (logical/physical)" +msgstr "" + +msgid "Sectors" +msgstr "" + +msgid "Serial Number" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Solid State Device Statistics" +msgstr "" + +msgid "Start" +msgstr "" + +msgid "Status of connected disk devices." +msgstr "" + +msgid "Temperature" +msgstr "" + +msgid "Temperature Statistics" +msgstr "" + +msgid "THRESH" +msgstr "" + +msgid "Transport Statistics" +msgstr "" + +msgid "Type" +msgstr "" + +msgid "Units" +msgstr "" + +msgid "Use" +msgstr "" + +msgid "Used" +msgstr "" + +msgid "User Capacity" +msgstr "" + +msgid "VALUE" +msgstr "" + +msgid "WHEN FAILED" +msgstr "" + +msgid "WORST" +msgstr "" + +msgid "Write to disk device memory" +msgstr "" + +msgid "auto" +msgstr "" + +msgid "blocks" +msgstr "" + +msgid "bytes" +msgstr "" + +msgid "failed" +msgstr "" + +msgid "interval" +msgstr "" + +msgid "logical/physical" +msgstr "" + +msgid "min" +msgstr "" + +msgid "no" +msgstr "" + +msgid "passed" +msgstr "" + +msgid "yes" +msgstr "" diff --git a/luci-app-disks-info/po/zh_Hans/disks-info.po b/luci-app-disks-info/po/zh_Hans/disks-info.po new file mode 100644 index 00000000..587d6d41 --- /dev/null +++ b/luci-app-disks-info/po/zh_Hans/disks-info.po @@ -0,0 +1,349 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: Frand.Ren \n" +"Language-Team: Chinese (Simplified) \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_Hans\n" +"X-Generator: Weblate 4.6-dev\n" + +msgid "ATA Version is" +msgstr "ATA 版本" + +msgid "Apply" +msgstr "应用" + +msgid "Attribute name" +msgstr "傿•°å" + +msgid "Available" +msgstr "å¯ç”¨" + +msgid "Boot" +msgstr "引导" + +msgid "Collecting data..." +msgstr "正在收集数æ®..." + +msgid "Current" +msgstr "当å‰" + +msgid "Description" +msgstr "æè¿°" + +msgid "Device" +msgstr "设备" + +msgid "Device is" +msgstr "设备" + +msgid "Device Model" +msgstr "设备型å·" + +msgid "Device statistics" +msgstr "设备统计信æ¯" + +msgid "Disk model" +msgstr "åž‹å·" + +msgid "Disk identifier" +msgstr "ç£ç›˜æ ‡è¯†ç¬¦" + +msgid "Disklabel type" +msgstr "分区表类型" + +msgid "Disk Devices" +msgstr "ç£ç›˜è®¾å¤‡" + +msgid "End" +msgstr "结æŸ" + +msgid "Error number" +msgstr "错误å·" + +msgid "Estimated time" +msgstr "预计时间" + +msgid "Filesystems" +msgstr "文件系统" + +msgid "Filesystem" +msgstr "文件系统" + +msgid "Firmware Version" +msgstr "固件版本" + +msgid "Form Factor" +msgstr "外形" + +msgid "Free-Fall Statistics" +msgstr "自由跌è½ç»Ÿè®¡" + +msgid "Gb" +msgstr "" + +msgid "General Statistics" +msgstr "常è§ä¿¡æ¯ç»Ÿè®¡" + +msgid "General Errors Statistics" +msgstr "错误信æ¯ç»Ÿè®¡" + +msgid "Id" +msgstr "ID" + +msgid "In smartctl database [for details use: -P show]" +msgstr "在 smartctl æ•°æ®åº“中 [详细使用说明:-P show]" + +msgid "Index" +msgstr "索引" + +msgid "Information about the connected disk devices." +msgstr "有关已连接ç£ç›˜è®¾å¤‡çš„ä¿¡æ¯" + +msgid "LU WWN Device Id" +msgstr "LI WWN 设备ID" + +msgid "Lifetime hours" +msgstr "ç”Ÿå‘½å°æ—¶æ•°" + +msgid "Lifetime max" +msgstr "åŽ†å²æœ€é«˜æ¸©" + +msgid "Lifetime min" +msgstr "åŽ†å²æœ€ä½Žæ¸©" + +msgid "Limit max" +msgstr "ä¸Šé™æ¸©åº¦" + +msgid "Limit min" +msgstr "䏋陿¸©åº¦" + +msgid "Local Time is" +msgstr "当剿—¶é—´" + +msgid "May not be supported by some devices..." +msgstr "æŸäº›è®¾å¤‡å¯èƒ½ä¸æ”¯æŒ..." + +msgid "Model Family" +msgstr "å®¶æ—åž‹å·" + +msgid "Mounted on" +msgstr "挂载点" + +msgid "No devices detected" +msgstr "未检测到设备" + +msgid "No mounted filesystems" +msgstr "没有挂载文件系统" + +msgid "No partitions available" +msgstr "没有å¯ç”¨åˆ†åŒº" + +msgid "Not in smartctl database [for details use: -P showall]" +msgstr "ä¸åœ¨ smartctl æ•°æ®åº“中 [详细使用说明:-P showall]" + +msgid "Partitions" +msgstr "分区" + +msgid "Percentage Used Endurance Indicator" +msgstr "已使用寿命" + +msgid "Preserve across power cycles" +msgstr "é‡å¯åŽä¸å˜" + +msgid "RAW" +msgstr "原始值" + +msgid "Recommended max" +msgstr "æŽ¨èæœ€é«˜æ¸©åº¦" + +msgid "Recommended min" +msgstr "æŽ¨èæœ€ä½Žæ¸©åº¦" + +msgid "Refresh devices" +msgstr "釿–°åŠ è½½è®¾å¤‡ä¿¡æ¯" + +msgid "Rotating Media Statistics" +msgstr "旋转媒体统计" + +msgid "Rotation Rate" +msgstr "转速" + +msgid "S.M.A.R.T." +msgstr "" + +msgid "S.M.A.R.T. error log" +msgstr "S.M.A.R.T. 错误日志" + +msgid "SATA Version is" +msgstr "SATA 版本" + +msgid "SCT temperature history" +msgstr "SCT 温度历å²" + +msgid "SMART overall-health self-assessment test result:" +msgstr "SMART 自我评估:" + +msgid "Set logging interval" +msgstr "设置记录间隔" + +msgid "Sector Size" +msgstr "扇区大å°" + +msgid "Sector size (logical/physical)" +msgstr "扇区大å°(逻辑/物ç†)" + +msgid "Sectors" +msgstr "扇区" + +msgid "Serial Number" +msgstr "åºåˆ—å·" + +msgid "Size" +msgstr "大å°" + +msgid "Solid State Device Statistics" +msgstr "固æ€ç¡¬ç›˜ç»Ÿè®¡ä¿¡æ¯" + +msgid "Start" +msgstr "开始" + +msgid "Temperature" +msgstr "温度" + +msgid "Temperature Statistics" +msgstr "温度统计" + +msgid "THRESH" +msgstr "临界值" + +msgid "Transport Statistics" +msgstr "传输统计" + +msgid "Type" +msgstr "类型" + +msgid "Units" +msgstr "å•ä½" + +msgid "Use" +msgstr "已使用" + +msgid "Used" +msgstr "已使用" + +msgid "User Capacity" +msgstr "总大å°" + +msgid "VALUE" +msgstr "当å‰å€¼" + +msgid "WHEN FAILED" +msgstr "失效时间" + +msgid "WORST" +msgstr "最差值" + +msgid "Write to device memory" +msgstr "ä¿å­˜é…ç½®" + +msgid "blocks" +msgstr "å—" + +msgid "bytes" +msgstr "字节" + +msgid "failed" +msgstr "失败" + +msgid "interval" +msgstr "é—´éš”" + +msgid "logical/physical" +msgstr "逻辑/物ç†" + +msgid "min" +msgstr "分钟" + +msgid "passed" +msgstr "通过" + +msgid "I/O size (minimum/optimal)" +msgstr "I/O å¤§å° (最å°/最优)" + +msgid "Number of Hardware Resets" +msgstr "硬件å¤ä½è®¡æ•°" + +msgid "Number of Interface CRC Errors" +msgstr "接å£CRC错误计数" + +msgid "Lifetime Power-On Resets" +msgstr "上电å¤ä½è®¡æ•°" + +msgid "Power-on Hours" +msgstr "é€šç”µå°æ—¶" + +msgid "Logical Sectors Written" +msgstr "逻辑扇区写计数" + +msgid "Number of Write Commands" +msgstr "命令写计数" + +msgid "Logical Sectors Read" +msgstr "逻辑扇区读计数" + +msgid "Number of Read Commands" +msgstr "命令读计数" + +msgid "Number of Reported Uncorrectable Errors" +msgstr "无法修å¤çš„错误计数" + +msgid "Resets Between Cmd Acceptance and Completion" +msgstr "命令接收与完æˆä¹‹é—´çš„å¤ä½è®¡æ•°" + +msgid "Current Temperature" +msgstr "当剿¸©åº¦" + +msgid "Average Short Term Temperature" +msgstr "çŸ­æœŸå¹³å‡æ¸©åº¦" + +msgid "Average Long Term Temperature" +msgstr "é•¿æœŸå¹³å‡æ¸©åº¦" + +msgid "Highest Temperature" +msgstr "最高温度" + +msgid "Lowest Temperature" +msgstr "最低温度" + +msgid "Highest Average Short Term Temperature" +msgstr "çŸ­æœŸæœ€é«˜å¹³å‡æ¸©åº¦" + +msgid "Lowest Average Short Term Temperature" +msgstr "çŸ­æœŸæœ€ä½Žå¹³å‡æ¸©åº¦" + +msgid "Highest Average Long Term Temperature" +msgstr "é•¿æœŸæœ€é«˜å¹³å‡æ¸©åº¦" + +msgid "Lowest Average Long Term Temperature" +msgstr "é•¿æœŸæœ€ä½Žå¹³å‡æ¸©åº¦" + +msgid "Time in Over-Temperature" +msgstr "超温时间" + +msgid "Specified Maximum Operating Temperature" +msgstr "æŽ¨èæœ€é«˜å·¥ä½œæ¸©åº¦" + +msgid "Time in Under-Temperature" +msgstr "低温时间" + +msgid "Specified Minimum Operating Temperature" +msgstr "æŽ¨èæœ€ä½Žå·¥ä½œæ¸©åº¦" + +msgid "Solid State Device" +msgstr "固æ€ç¡¬ç›˜" diff --git a/luci-app-disks-info/root/usr/share/luci/menu.d/luci-app-disks-info.json b/luci-app-disks-info/root/usr/share/luci/menu.d/luci-app-disks-info.json new file mode 100644 index 00000000..1aa46295 --- /dev/null +++ b/luci-app-disks-info/root/usr/share/luci/menu.d/luci-app-disks-info.json @@ -0,0 +1,18 @@ +{ + "admin/status/disks-info": { + "title": "Disk Devices", + "order": 90, + "action": { + "type": "view", + "path": "disks-info" + }, + "depends": { + "acl": [ "luci-app-disks-info" ], + "fs": { + "/bin/df": "executable", + "/usr/sbin/fdisk": "executable", + "/usr/sbin/smartctl": "executable" + } + } + } +} diff --git a/luci-app-disks-info/root/usr/share/rpcd/acl.d/luci-app-disks-info.json b/luci-app-disks-info/root/usr/share/rpcd/acl.d/luci-app-disks-info.json new file mode 100644 index 00000000..bdbd21e5 --- /dev/null +++ b/luci-app-disks-info/root/usr/share/rpcd/acl.d/luci-app-disks-info.json @@ -0,0 +1,15 @@ +{ + "luci-app-disks-info": { + "description": "Grant access to disks-info procedures", + "read": { + "ubus": { + "luci.disks-info": [ "getDevices" ] + }, + "cgi-io": [ "exec" ], + "file": { + "/usr/sbin/smartctl -d* -iAHl scttemp -l error -l devstat --json=c /dev/*": [ "exec" ], + "/usr/sbin/smartctl -l scttempint,[0-9,p]* /dev/*": [ "exec" ] + } + } + } +} diff --git a/luci-app-disks-info/root/usr/share/rpcd/ucode/luci.disks-info b/luci-app-disks-info/root/usr/share/rpcd/ucode/luci.disks-info new file mode 100644 index 00000000..4d9ca9d8 --- /dev/null +++ b/luci-app-disks-info/root/usr/share/rpcd/ucode/luci.disks-info @@ -0,0 +1,138 @@ + +'use strict'; + +import { lsdir, popen } from 'fs'; + +const fdiskPattern = '/usr/sbin/fdisk -lo Device,Start,End,Sectors,Size,Type %s 2> /dev/null'; +const dfPattern = '/bin/df -Th %s 2> /dev/null'; +const deviceRegexp = /^((h|s)d[a-z]|nvme[0-9]+n[0-9]+)$/; +const devicesDir = '/dev'; + +function getCmdOutput(cmd) { + let ret = ''; + const fp = popen(cmd, 'r'); + if(fp) { + let c = fp.read('all'); + fp.close(); + if(c) { + ret = trim(c); + } + } + return ret; +} + +function getDiskDevices() { + let devices = lsdir(devicesDir); + if(devices) { + devices = map( + filter(devices, e => match(e, deviceRegexp)), + e => devicesDir + '/' + e + ); + } + return devices ?? []; +} + +function getFdiskData(device) { + let diskDict = {}; + let diskInfo = []; + let partitions = []; + let output = getCmdOutput(sprintf(fdiskPattern, device)); + let diskData = map( + split(trim(output), '\n\n', 3), + e => trim(e) + ); + if(length(diskData) > 0) { + diskInfo = map( + map(split(diskData[0], '\n'), e => trim(e)), + e => map(split(e, ':', 2), e => trim(e)) + ); + if(diskData[1]) { + let partitionsRaw = map(split(diskData[1], '\n'), e => split(e, /\s+/)); + for(let i = 1; i < length(partitionsRaw); i++) { + let device, boot = false, start, end, sectors, size; + let lastField = 5; + if(partitionsRaw[i][1] == '*') { + lastField = 6; + device = partitionsRaw[i][0]; + boot = true; + start = partitionsRaw[i][2]; + end = partitionsRaw[i][3]; + sectors = partitionsRaw[i][4]; + size = partitionsRaw[i][5]; + } else { + device = partitionsRaw[i][0]; + start = partitionsRaw[i][1]; + end = partitionsRaw[i][2]; + sectors = partitionsRaw[i][3]; + size = partitionsRaw[i][4]; + } + let type = []; + for(let j = lastField; j < length(partitionsRaw[i]); j++) { + push(type, partitionsRaw[i][j]); + } + push(partitions, { device, boot, start, end, sectors, size, type: join(' ', type) }); + } + } + } + diskDict['diskInfo'] = diskInfo; + diskDict['partitions'] = partitions; + return diskDict; +} + +function getDfData(partition) { + let fsDict = {}; + let output = getCmdOutput(sprintf(dfPattern, partition)); + let fsData = map( + split(trim(output), '\n'), + e => trim(e) + ); + if(fsData[1]) { + let dataRaw = split(fsData[1], /\s+/); + fsDict['filesystem'] = dataRaw[0]; + fsDict['type'] = dataRaw[1]; + fsDict['size'] = dataRaw[2]; + fsDict['used'] = dataRaw[3]; + fsDict['available'] = dataRaw[4]; + fsDict['use_perc'] = dataRaw[5]; + fsDict['mounted'] = dataRaw[6]; + } + return fsDict; +} + +const methods = { + getDevices: { + call: function() { + let data = {}; + const devices = getDiskDevices(); + if(length(devices) > 0) { + let fdiskData = {}; + for(let i in devices) { + fdiskData[i] = getFdiskData(i); + } + let dfData = {}; + for(let k, v in fdiskData) { + let filesystems = []; + for(let j in v.partitions) { + let res = getDfData(j.device); + if(length(res) > 0) { + push(filesystems, res); + } + } + dfData[k] = filesystems; + } + data['devices'] = () => { + let d = []; + for(let k in fdiskData) { + push(d, k); + } + return d; + }(); + data['fdisk'] = fdiskData; + data['df'] = dfData; + } + return data; + } + } +}; + +return { 'luci.disks-info': methods }; diff --git a/luci-app-disks-info/screenshots/01.jpg b/luci-app-disks-info/screenshots/01.jpg new file mode 100644 index 00000000..e5f76500 Binary files /dev/null and b/luci-app-disks-info/screenshots/01.jpg differ diff --git a/luci-app-interfaces-statistics/LICENSE b/luci-app-interfaces-statistics/LICENSE new file mode 100644 index 00000000..4c903101 --- /dev/null +++ b/luci-app-interfaces-statistics/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 gSpotx2f + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/luci-app-interfaces-statistics/Makefile b/luci-app-interfaces-statistics/Makefile new file mode 100644 index 00000000..d9e647d8 --- /dev/null +++ b/luci-app-interfaces-statistics/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2026 gSpot (https://github.com/gSpotx2f/luci-app-interfaces-statistics) +# +# This is free software, licensed under the MIT License. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-interfaces-statistics +PKG_VERSION:=0.4.2 +PKG_RELEASE:=1 +LUCI_TITLE:=Network interfaces statistics +LUCI_PKGARCH:=all +PKG_LICENSE:=MIT + +#include ../../luci.mk +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-interfaces-statistics/README.md b/luci-app-interfaces-statistics/README.md new file mode 100644 index 00000000..568994f8 --- /dev/null +++ b/luci-app-interfaces-statistics/README.md @@ -0,0 +1,36 @@ +# luci-app-interfaces-statistics +Network interfaces statistics for LuCI (OpenWrt webUI). + +OpenWrt >= 21.02. + +## Installation notes + +**OpenWrt >= 25.12:** + + wget --no-check-certificate -O /tmp/luci-app-interfaces-statistics-0.4.2-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-interfaces-statistics-0.4.2-r1.apk + apk --allow-untrusted add /tmp/luci-app-interfaces-statistics-0.4.2-r1.apk + rm /tmp/luci-app-interfaces-statistics-0.4.2-r1.apk + service rpcd restart + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-interfaces-statistics-ru-0.4.2-r1.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-interfaces-statistics-ru-0.4.2-r1.apk + apk --allow-untrusted add /tmp/luci-i18n-interfaces-statistics-ru-0.4.2-r1.apk + rm /tmp/luci-i18n-interfaces-statistics-ru-0.4.2-r1.apk + +**OpenWrt <= 24.10:** + + wget --no-check-certificate -O /tmp/luci-app-interfaces-statistics_0.4.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-interfaces-statistics_0.4.2-r1_all.ipk + opkg install /tmp/luci-app-interfaces-statistics_0.4.2-r1_all.ipk + rm /tmp/luci-app-interfaces-statistics_0.4.2-r1_all.ipk + service rpcd restart + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-interfaces-statistics-ru_0.4.2-r1_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-interfaces-statistics-ru_0.4.2-r1_all.ipk + opkg install /tmp/luci-i18n-interfaces-statistics-ru_0.4.2-r1_all.ipk + rm /tmp/luci-i18n-interfaces-statistics-ru_0.4.2-r1_all.ipk + +## Screenshots: + +![](https://github.com/gSpotx2f/luci-app-interfaces-statistics/blob/master/screenshots/01.jpg) diff --git a/luci-app-interfaces-statistics/htdocs/luci-static/resources/view/interfaces-statistics.js b/luci-app-interfaces-statistics/htdocs/luci-static/resources/view/interfaces-statistics.js new file mode 100644 index 00000000..57601148 --- /dev/null +++ b/luci-app-interfaces-statistics/htdocs/luci-static/resources/view/interfaces-statistics.js @@ -0,0 +1,384 @@ +'use strict'; +'require poll'; +'require rpc'; +'require ui'; +'require view'; + +const labelStyleUp = 'background-color:#388438; color:#fff'; +const labelStyleDown = 'background-color:#767676; color:#fff'; + +return view.extend({ + ifacesArray : [], + + callNetDevice: rpc.declare({ + object: 'network.device', + method: 'status', + expect: { '': {} } + }), + + formatBytesString(bytes) { + let units = (bytes > 10**12) ? + `${Number((bytes / 1000 / 1000 / 1000 / 1000).toFixed(2))} ${_('Tb')}` : + (bytes > 10**9) ? + `${Number((bytes / 1000 / 1000 / 1000).toFixed(2))} ${_('Gb')}` : + (bytes > 10**6) ? + `${Number((bytes / 1000 / 1000).toFixed(2))} ${_('Mb')}` : + `${Number((bytes / 1000).toFixed(2))} ${_('Kb')}`; + return `${bytes} (${units})`; + }, + + setIfacesData(ifacesData) { + for(let iface of this.ifacesArray) { + let ifaceState = null; + let ifacesStatisticsObject = null; + + if(ifacesData[iface] !== undefined) { + ifaceState = ifacesData[iface].up; + ifacesStatisticsObject = ifacesData[iface].statistics; + }; + + let state = document.querySelector('[data-ifstat="%s_state"]'.format(iface)); + state.textContent = (ifaceState) ? _('Interface is up') : _('Interface is down'); + state.style = (ifaceState) ? labelStyleUp : labelStyleDown; + + if(!ifacesStatisticsObject) continue; + + for(let [k, v] of Object.entries(ifacesStatisticsObject)) { + let elem = document.querySelector('[data-ifstat="%s_%s"]'.format(iface, k)); + if(elem !== null) { + if(k == 'rx_bytes' || k == 'tx_bytes') { + elem.innerHTML = this.formatBytesString(v); + } else { + elem.textContent = v; + } + }; + }; + }; + }, + + update() { + return this.callNetDevice().then(ifacesData => { + this.setIfacesData(ifacesData); + }).catch(e => ui.addNotification(null, E('p', {}, e.message))); + }, + + load() { + return this.callNetDevice().catch( + e => ui.addNotification(null, E('p', {}, e.message))); + }, + + render(ifacesData) { + + let ifacesNode = E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, + E('div', { 'class': 'cbi-value' }, + E('em', {}, _('No interfaces detected')) + ) + ) + ); + + if(ifacesData) { + ifacesNode = E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, + E('div', { 'class': 'cbi-value' }, [ + E('div', { 'style': 'width:100%; text-align:right !important' }, + E('button', { + 'class': 'btn', + 'click': () => window.location.reload(), + }, _('Refresh interfaces')) + ) + ]) + ) + ); + + let tabsContainer = E('div', { 'class': 'cbi-section-node cbi-section-node-tabbed' }); + ifacesNode.append(tabsContainer); + + let tab = 0; + + for(let iface in ifacesData) { + let ifaceName = iface; + let ifacesStatisticsObject = ifacesData[iface].statistics; + let ifaceState = ifacesData[iface].up; + let ifaceMac = ifacesData[iface].macaddr; + + if(ifaceMac == "00:00:00:00:00:00") { + ifaceMac = null; + }; + + this.ifacesArray.push(iface); + this.ifacesArray.sort(); + + let ifaceTab = E('div', { + 'data-tab' : tab, + 'data-tab-title': ifaceName, + }); + tabsContainer.append(ifaceTab); + + let ifaceTable = E('table', { 'class': 'table' }); + + if(ifaceMac) { + ifaceTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, + _('MAC Address') + ':'), + E('td', { 'class': 'td left' }, ifaceMac), + ]), + ); + }; + + ifaceTable.append( + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'style': 'width:33%' }, + _('State') + ':'), + E('td', { 'class': 'td left' }, + E('span', { + 'data-ifstat': iface + '_state', + 'class': 'label', + 'style': (ifaceState) ? labelStyleUp : labelStyleDown, + }, + (ifaceState) ? + _('Interface is up') : _('Interface is down') + ) + ), + ]), + ); + + let statTable = E('table', { 'class': 'table' }, [ + E('tr', { 'class': 'tr table-titles' }, [ + E('th', { 'class': 'th left', 'style': 'width:33%' }, + _('Parameter')), + E('th', { 'class': 'th left', 'style': 'width:33%' }, + _('Receive')), + E('th', { 'class': 'th left' }, _('Transmit')), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('bytes')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_bytes', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_bytes + ), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_bytes', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_bytes + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('packets')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_packets', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_packets + ), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_packets', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_packets + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_errors + ), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_errors', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_errors + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('dropped')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_dropped', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_dropped + ), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_dropped', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_dropped + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('compressed')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_compressed', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_compressed + ), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_compressed', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_compressed + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('fifo errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_fifo_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_fifo_errors + ), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_fifo_errors', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_fifo_errors + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('multicast')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_multicast', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.multicast + ), + E('td', { 'class': 'td left', 'data-title': _('Transmit') }, + ' '), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('crc errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_crc_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_crc_errors + ), + E('td', { 'class': 'td left', 'data-title': _('Transmit') }, + ' '), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('frame errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_frame_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_frame_errors + ), + E('td', { 'class': 'td left', 'data-title': _('Transmit') }, + ' '), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('length errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_length_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_length_errors + ), + E('td', { 'class': 'td left', 'data-title': _('Transmit') }, + ' '), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('missed errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_missed_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_missed_errors + ), + E('td', { 'class': 'td left', 'data-title': _('Transmit') }, + ' '), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('over errors')), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_rx_over_errors', + 'data-title' : _('Receive') }, + ifacesStatisticsObject.rx_over_errors + ), + E('td', { 'class': 'td left', 'data-title': _('Transmit') }, + ' '), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('collisions')), + E('td', { 'class': 'td left', 'data-title': _('Receive') }, + ' '), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_collisions', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.collisions + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('carrier errors')), + E('td', { 'class': 'td left', 'data-title': _('Receive') }, + ' '), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_carrier_errors', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_carrier_errors + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('heartbeat errors')), + E('td', { 'class': 'td left', 'data-title': _('Receive') }, + ' '), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_heartbeat_errors', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_heartbeat_errors + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('aborted errors')), + E('td', { 'class': 'td left', 'data-title': _('Receive') }, + ' '), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_aborted_errors', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_aborted_errors + ), + ]), + E('tr', { 'class': 'tr' }, [ + E('td', { 'class': 'td left', 'data-title': _('Parameter') }, + _('window errors')), + E('td', { 'class': 'td left', 'data-title': _('Receive') }, + ' '), + E('td', { 'class': 'td left', + 'data-ifstat': ifaceName + '_tx_window_errors', + 'data-title' : _('Transmit') }, + ifacesStatisticsObject.tx_window_errors + ), + ]), + ]); + + ifaceTab.append(E([ + E('div', { 'class': 'cbi-value' }, ifaceTable), + E('div', { 'class': 'cbi-value' }, statTable), + ])); + + tab++; + }; + + ui.tabs.initTabGroup(tabsContainer.children); + poll.add(L.bind(this.update, this)); + }; + + return E([ + E('h2', { 'class': 'fade-in' }, _('Interfaces Statistics')), + E('div', { 'class': 'cbi-section-descr fade-in' }), + ifacesNode, + ]); + }, + + handleSaveApply: null, + handleSave : null, + handleReset : null, +}); diff --git a/luci-app-interfaces-statistics/po/ru/interfaces-statistics.po b/luci-app-interfaces-statistics/po/ru/interfaces-statistics.po new file mode 100644 index 00000000..924b5e59 --- /dev/null +++ b/luci-app-interfaces-statistics/po/ru/interfaces-statistics.po @@ -0,0 +1,106 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Language: ru\n" + +msgid "Gb" +msgstr "Гб" + +msgid "Interface is down" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½" + +msgid "Interface is up" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½" + +msgid "Interfaces Statistics" +msgstr "СтатиÑтика интерфейÑов" + +msgid "Kb" +msgstr "Кб" + +msgid "MAC Address" +msgstr "MAC адреÑ" + +msgid "Mb" +msgstr "Мб" + +msgid "No interfaces detected" +msgstr "ИнтерфейÑÑ‹ не найдены" + +msgid "Parameter" +msgstr "Параметр" + +msgid "Receive" +msgstr "Получено" + +msgid "Refresh interfaces" +msgstr "Обновить интерфейÑÑ‹" + +msgid "State" +msgstr "СоÑтоÑние" + +msgid "Tb" +msgstr "Тб" + +msgid "Transmit" +msgstr "Передано" + +msgid "aborted errors" +msgstr "" + +msgid "bytes" +msgstr "" + +msgid "carrier errors" +msgstr "" + +msgid "collisions" +msgstr "" + +msgid "compressed" +msgstr "" + +msgid "crc errors" +msgstr "" + +msgid "dropped" +msgstr "" + +msgid "errors" +msgstr "" + +msgid "fifo errors" +msgstr "" + +msgid "frame errors" +msgstr "" + +msgid "heartbeat errors" +msgstr "" + +msgid "length errors" +msgstr "" + +msgid "missed errors" +msgstr "" + +msgid "multicast" +msgstr "" + +msgid "over errors" +msgstr "" + +msgid "packets" +msgstr "" + +msgid "window errors" +msgstr "" diff --git a/luci-app-interfaces-statistics/po/templates/interfaces-statistics.pot b/luci-app-interfaces-statistics/po/templates/interfaces-statistics.pot new file mode 100644 index 00000000..2a276de0 --- /dev/null +++ b/luci-app-interfaces-statistics/po/templates/interfaces-statistics.pot @@ -0,0 +1,95 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Gb" +msgstr "" + +msgid "Interface is down" +msgstr "" + +msgid "Interface is up" +msgstr "" + +msgid "Interfaces Statistics" +msgstr "" + +msgid "Kb" +msgstr "" + +msgid "MAC Address" +msgstr "" + +msgid "Mb" +msgstr "" + +msgid "No interfaces detected" +msgstr "" + +msgid "Parameter" +msgstr "" + +msgid "Receive" +msgstr "" + +msgid "Refresh interfaces" +msgstr "" + +msgid "State" +msgstr "" + +msgid "Tb" +msgstr "" + +msgid "Transmit" +msgstr "" + +msgid "aborted errors" +msgstr "" + +msgid "bytes" +msgstr "" + +msgid "carrier errors" +msgstr "" + +msgid "collisions" +msgstr "" + +msgid "compressed" +msgstr "" + +msgid "crc errors" +msgstr "" + +msgid "dropped" +msgstr "" + +msgid "errors" +msgstr "" + +msgid "fifo errors" +msgstr "" + +msgid "frame errors" +msgstr "" + +msgid "heartbeat errors" +msgstr "" + +msgid "length errors" +msgstr "" + +msgid "missed errors" +msgstr "" + +msgid "multicast" +msgstr "" + +msgid "over errors" +msgstr "" + +msgid "packets" +msgstr "" + +msgid "window errors" +msgstr "" diff --git a/luci-app-interfaces-statistics/po/zh_Hans/interfaces-statistics.po b/luci-app-interfaces-statistics/po/zh_Hans/interfaces-statistics.po new file mode 100755 index 00000000..cac44329 --- /dev/null +++ b/luci-app-interfaces-statistics/po/zh_Hans/interfaces-statistics.po @@ -0,0 +1,85 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" +"Last-Translator: 孤爺仔 \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Language: zh_CN\n" + +msgid "Collecting data..." +msgstr "正在收集数æ®..." + +msgid "Frequency" +msgstr "频率" + +msgid "Ghz" +msgstr "Ghz" + +msgid "Interface is down" +msgstr "接å£å·²å…³é—­" + +msgid "Interface is up" +msgstr "接å£å·²æ‰“å¼€" + +msgid "Interfaces Statistics" +msgstr "接å£ç»Ÿè®¡" + +msgid "MAC Address" +msgstr "MAC地å€" + +msgid "No interfaces detected" +msgstr "未检测到接å£" + +msgid "Parameter" +msgstr "傿•°" + +msgid "Receive" +msgstr "接收" + +msgid "Refresh interfaces" +msgstr "刷新接å£" + +msgid "SSID" +msgstr "SSID" + +msgid "State" +msgstr "State" + +msgid "Transmit" +msgstr "å‘é€" + +msgid "bytes" +msgstr "bytes" + +msgid "carrier" +msgstr "载体" + +msgid "collisions" +msgstr "冲çª" + +msgid "compressed" +msgstr "已压缩" + +msgid "dropped" +msgstr "dropped" + +msgid "errors" +msgstr "错误" + +msgid "fifo" +msgstr "先进先出" + +msgid "frame" +msgstr "框架" + +msgid "multicast" +msgstr "多播" + +msgid "packets" +msgstr "å°åŒ…" diff --git a/luci-app-interfaces-statistics/root/usr/share/luci/menu.d/luci-app-interfaces-statistics.json b/luci-app-interfaces-statistics/root/usr/share/luci/menu.d/luci-app-interfaces-statistics.json new file mode 100644 index 00000000..887e5d54 --- /dev/null +++ b/luci-app-interfaces-statistics/root/usr/share/luci/menu.d/luci-app-interfaces-statistics.json @@ -0,0 +1,13 @@ +{ + "admin/network/interfaces-statistics": { + "title": "Interfaces Statistics", + "order": 70, + "action": { + "type": "view", + "path": "interfaces-statistics" + }, + "depends": { + "acl": [ "luci-app-interfaces-statistics" ] + } + } +} diff --git a/luci-app-interfaces-statistics/root/usr/share/rpcd/acl.d/luci-app-interfaces-statistics.json b/luci-app-interfaces-statistics/root/usr/share/rpcd/acl.d/luci-app-interfaces-statistics.json new file mode 100644 index 00000000..2d78dea7 --- /dev/null +++ b/luci-app-interfaces-statistics/root/usr/share/rpcd/acl.d/luci-app-interfaces-statistics.json @@ -0,0 +1,10 @@ +{ + "luci-app-interfaces-statistics": { + "description": "Grant access to interfaces-statistics procedures", + "read": { + "ubus": { + "network.device": [ "status" ] + } + } + } +} diff --git a/luci-app-interfaces-statistics/screenshots/01.jpg b/luci-app-interfaces-statistics/screenshots/01.jpg new file mode 100644 index 00000000..8a4bfa1f Binary files /dev/null and b/luci-app-interfaces-statistics/screenshots/01.jpg differ diff --git a/luci-app-internet-detector/Makefile b/luci-app-internet-detector/Makefile new file mode 100644 index 00000000..411cedc2 --- /dev/null +++ b/luci-app-internet-detector/Makefile @@ -0,0 +1,17 @@ +# +# (Ñ) 2026 gSpot (https://github.com/gSpotx2f/luci-app-internet-detector) +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-internet-detector +PKG_VERSION:=1.7.3 +PKG_RELEASE:=1 +LUCI_TITLE:=LuCI support for internet-detector +LUCI_DEPENDS:=+internet-detector +LUCI_PKGARCH:=all + +#include ../../luci.mk +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js b/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js new file mode 100644 index 00000000..7cdca962 --- /dev/null +++ b/luci-app-internet-detector/htdocs/luci-static/resources/view/internet-detector.js @@ -0,0 +1,2050 @@ +'use strict'; +'require baseclass'; +'require form'; +'require fs'; +'require poll'; +'require rpc'; +'require uci'; +'require ui'; +'require view'; +'require tools.widgets as widgets' + +document.head.append(E('style', {'type': 'text/css'}, +` +:root { + --app-id-font-color: #454545; + --app-id-font-shadow: #fff; + --app-id-connected-color: #6bdebb; + --app-id-disconnected-color: #f8aeba; + --app-id-undefined-color: #dfdfdf; +} +:root[data-darkmode="true"] { + --app-id-font-color: #f6f6f6; + --app-id-font-shadow: #4d4d4d; + --app-id-connected-color: #005F20; + --app-id-disconnected-color: #a93734; + --app-id-undefined-color: #4d4d4d; +} +.id-connected { + --on-color: var(--app-id-font-color); + background-color: var(--app-id-connected-color) !important; + border-color: var(--app-id-connected-color) !important; + color: var(--app-id-font-color) !important; + text-shadow: 0 1px 1px var(--app-id-font-shadow); +} +.id-disconnected { + --on-color: var(--app-id-font-color); + background-color: var(--app-id-disconnected-color) !important; + border-color: var(--app-id-disconnected-color) !important; + color: var(--app-id-font-color) !important; + text-shadow: 0 1px 1px var(--app-id-font-shadow); +} +.id-undefined { + --on-color: var(--app-id-font-color); + background-color: var(--app-id-undefined-color) !important; + border-color: var(--app-id-undefined-color) !important; + color: var(--app-id-font-color) !important; + text-shadow: 0 1px 1px var(--app-id-font-shadow); +} +.id-label-status { + display: inline-block; + word-wrap: break-word; + margin: 2px !important; + padding: 4px 8px; + border: 1px solid; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + font-weight: bold; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +} +`)); + +const btnStyleEnabled = 'btn cbi-button-save'; +const btnStyleDisabled = 'btn cbi-button-reset'; +const btnStyleApply = 'btn cbi-button-apply'; + +var Timefield = ui.Textfield.extend({ + secToString(value) { + let string = '0'; + if(/^\d+$/.test(value)) { + value = Number(value); + if(value >= 86400 && (value % 86400) == 0) { + string = String(value / 86400) + 'd'; + } + else if(value >= 3600 && (value % 3600) == 0) { + string = String(value / 3600) + 'h'; + } + else if(value >= 60 && (value % 60) == 0) { + string = String(value / 60) + 'm'; + } + else { + string = String(value) + 's'; + }; + }; + return string; + }, + + render() { + let frameEl = E('div', { 'id': this.options.id }), + inputEl = E('input', { + 'id' : this.options.id ? 'widget.' + this.options.id : null, + 'name' : this.options.name, + 'type' : 'text', + 'class' : 'cbi-input-text', + 'readonly' : this.options.readonly ? '' : null, + 'disabled' : this.options.disabled ? '' : null, + 'maxlength' : this.options.maxlength, + 'placeholder': this.options.placeholder, + 'value' : this.secToString(this.value), + }); + frameEl.appendChild(inputEl); + return this.bind(frameEl); + }, + + getValue() { + let rawValue = this.node.querySelector('input').value, + value = 0, + res = rawValue.match(/^(\d+)([dhms]?)$/); + if(res) { + if(res[2] == 'd') { + value = Number(res[1]) * 86400; + } + else if(res[2] == 'h') { + value = Number(res[1]) * 3600; + } + else if(res[2] == 'm') { + value = Number(res[1]) * 60; + } + else if(!res[2] || res[2] == 's') { + value = Number(res[1]); + } + else { + value = 0; + }; + } else { + value = 0; + }; + return String(value); + }, + + setValue(value) { + let inputEl = this.node.querySelector('input'); + inputEl.value = this.secToString(value); + }, +}); + +var TextfieldButton = ui.Textfield.extend({ + render() { + let frameEl = E('div', { 'id': this.options.id }), + inputEl = E('input', { + 'id' : this.options.id ? 'widget.' + this.options.id : null, + 'name' : this.options.name, + 'type' : 'text', + 'class' : 'cbi-input-text', + 'readonly' : this.options.readonly ? '' : null, + 'disabled' : this.options.disabled ? '' : null, + 'maxlength' : this.options.maxlength, + 'placeholder': this.options.placeholder, + 'value' : this.value, + }); + frameEl.appendChild(E('div', { 'class': 'control-group' }, [ + inputEl, + E('button', { + 'class' : `cbi-button cbi-button-${this.options.btnstyle || 'neutral'}`, + 'title' : this.options.btntitle, + 'aria-label': this.options.btntitle, + 'click' : this.options.onclick, + }, this.options.btntext,) + ])); + return this.bind(frameEl); + }, +}); + +return view.extend({ + appName : 'internet-detector', + configDir : '/etc/internet-detector', + pollInterval : L.env.pollinterval, + appStatus : 'stoped', + initStatus : null, + inetStatus : null, + inetStatusArea : E('div', { 'class': 'cbi-value-field', 'id': 'inetStatusArea' }), + serviceStatusLabel : E('em', { 'id': 'serviceStatusLabel' }), + initButton : null, + currentAppMode : '0', + defaultHosts : [ '8.8.8.8', '1.1.1.1' ], + defaultURLs : [ 'https://www.google.com' ], + ledsPath : '/sys/class/leds', + ledsPerInstance : 3, + leds : [], + publicIPProviders : { + dns : [ + { name: 'opendns1', title: 'opendns1 (DNS)' }, + { name: 'opendns2', title: 'opendns2 (DNS)' }, + { name: 'opendns3', title: 'opendns3 (DNS)' }, + { name: 'opendns4', title: 'opendns4 (DNS)' }, + { name: 'google', title: 'google (DNS)' }, + { name: 'akamai', title: 'akamai (DNS)' }, + ], + http: [ + { name: 'akamai_http', title: 'akamai (HTTP)' }, + { name: 'amazonaws', title: 'amazonaws (HTTP)' }, + { name: 'wgetip', title: 'wgetip.com (HTTP)' }, + { name: 'ifconfig', title: 'ifconfig.me (HTTP)' }, + { name: 'ipecho', title: 'ipecho.net (HTTP)' }, + { name: 'canhazip', title: 'canhazip.com (HTTP)' }, + { name: 'icanhazip', title: 'icanhazip.com (HTTP)' }, + ], + }, + mm : false, + mmInit : false, + email : false, + emailExec : false, + telegram : false, + curlExec : false, + modRegularScriptNextRun: {}, + + callInitStatus: rpc.declare({ + object: 'luci', + method: 'getInitList', + params: [ 'name' ], + expect: { '': {} } + }), + + callInitAction: rpc.declare({ + object: 'luci', + method: 'setInitAction', + params: [ 'name', 'action' ], + expect: { result: false } + }), + + getInitStatus() { + return this.callInitStatus(this.appName).then(res => { + if(res) { + return res[this.appName].enabled; + } else { + throw _('Command failed'); + } + }).catch(e => { + ui.addNotification(null, + E('p', _('Failed to get %s init status: %s').format(this.appName, e))); + }); + }, + + handleServiceAction(action) { + return this.callInitAction(this.appName, action).then(success => { + if(!success) { + throw _('Command failed'); + }; + return true; + }).catch(e => { + ui.addNotification(null, + E('p', _('Service action failed "%s %s": %s').format(this.appName, action, e))); + }); + }, + + callInit: rpc.declare({ + object: 'luci.internet-detector', + method: 'Init', + expect: { '': {} } + }), + + getInit() { + return this.callInit().then(data => { + return data; + }); + }, + + callUIPoll: rpc.declare({ + object: 'luci.internet-detector', + method: 'UIPoll', + expect: { '': {} } + }), + + getUIPoll() { + return this.callUIPoll().then(data => { + return data; + }); + }, + + callStatus: rpc.declare({ + object: 'luci.internet-detector', + method: 'Status', + expect: { '': {} } + }), + + getStatus() { + return this.callStatus().then(data => { + return data; + }); + }, + + callInetStatus: rpc.declare({ + object: 'luci.internet-detector', + method: 'InetStatus', + expect: { '': {} } + }), + + getInetStatus() { + return this.callInetStatus().then(data => { + return data; + }); + }, + + callTgChatId: rpc.declare({ + object: 'luci.internet-detector-mod-telegram', + method: 'GetTgChatId', + params: [ 'botToken', 'proxyType', 'proxyHost', 'proxyPort', 'proxyUser', 'proxyPasswd', 'iface' ], + expect: { '': {} } + }), + + getTgChatId(botToken, proxyType, proxyHost, proxyPort, proxyUser, proxyPasswd, iface) { + return this.callTgChatId( + botToken, proxyType, proxyHost, proxyPort, proxyUser, proxyPasswd, iface).then(data => { + return data; + }); + }, + + setInternetStatus() { + this.inetStatusArea.innerHTML = ''; + + if(!this.inetStatus || !this.inetStatus.instances || this.inetStatus.instances.length == 0) { + let label = E('span', { 'class': 'id-label-status id-undefined' }, _('Undefined')); + if((this.currentAppMode == '1' && this.appStatus != 'stoped') || this.currentAppMode == '2') { + label.classList.add('spinning'); + }; + this.inetStatusArea.append(label); + } else { + this.inetStatus.instances.sort((a, b) => a.num - b.num); + for(let i of this.inetStatus.instances) { + let status = _('Disconnected'); + let className = 'id-label-status id-disconnected'; + if(i.inet == 0) { + status = _('Connected'); + className = 'id-label-status id-connected'; + } + else if(i.inet == -1) { + status = _('Undefined'); + className = 'id-label-status id-undefined spinning'; + }; + + let publicIp = (i.mod_public_ip !== undefined) ? + ' | %s: %s'.format(_('Public IP'), (i.mod_public_ip == '') ? _('Undefined') : _(i.mod_public_ip)) + : ''; + + this.inetStatusArea.append( + E('span', { 'class': className }, '%s%s%s'.format( + i.instance + ': ', status, publicIp) + ) + ); + + if(i.mod_regular_script) { + this.modRegularScriptNextRun[i.instance] = i.mod_regular_script; + let nextRunLabel = document.getElementById('id_next_run_' + i.instance); + if(nextRunLabel) { + if(this.appStatus == 'running') { + nextRunLabel.innerHTML = this.modRegularScriptNextRun[i.instance]; + } else { + nextRunLabel.innerHTML = _('Not scheduled'); + }; + }; + }; + }; + }; + + if(this.appStatus == 'running') { + this.serviceStatusLabel.textContent = _('Running'); + } else { + this.serviceStatusLabel.textContent = _('Stopped'); + }; + }, + + servicePoll() { + return Promise.all([ + this.getStatus(), + this.getInetStatus(), + ]).then(stat => { + this.appStatus = stat[0].status; + this.inetStatus = stat[1]; + this.setInternetStatus(); + }).catch(e => { + this.appStatus = 'stoped'; + this.inetStatus = {}; + }); + }, + + uiPoll() { + return this.getUIPoll().then(status => { + this.inetStatus = status; + this.setInternetStatus(); + }); + }, + + serviceRestart() { + return this.handleServiceAction('restart'); + }, + + serviceRestartHandler() { + poll.stop(); + return this.serviceRestart().then(() => { + window.setTimeout(() => this.servicePoll(), 1000); + poll.start(); + }); + }, + + getTgChatIdHandler(ev, instance) { + ev.preventDefault(); + + let botToken; + let botTokenInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_api_token'.format(this.appName, instance)); + if(botTokenInput) { + botToken = botTokenInput.value; + }; + if(!botTokenInput || !botToken) { + alert(_('Bot API token is missing!')); + return; + }; + let proxyType = ''; + let proxyTypeInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_proxy_type'.format(this.appName, instance)); + if(proxyTypeInput) { + proxyType = proxyTypeInput.value; + }; + let proxyHost = ''; + let proxyHostInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_proxy_host'.format(this.appName, instance)); + if(proxyHostInput) { + proxyHost = proxyHostInput.value; + }; + let proxyPort = ''; + let proxyPortInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_proxy_port'.format(this.appName, instance)); + if(proxyPortInput) { + proxyPort = proxyPortInput.value; + }; + let proxyUser = ''; + let proxyUserInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_proxy_user'.format(this.appName, instance)); + if(proxyUserInput) { + proxyUser = proxyUserInput.value; + }; + let proxyPasswd = ''; + let proxyPasswdInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_proxy_passwd'.format(this.appName, instance)); + if(proxyPasswdInput) { + proxyPasswd = proxyPasswdInput.value; + }; + let iface = ''; + let ifaceInput = document.getElementById( + 'cbid.%s.%s.mod_telegram_iface'.format(this.appName, instance)); + if(ifaceInput) { + let li = ifaceInput.querySelector('li[selected]'); + if(li) { + iface = li.dataset.value || ''; + }; + }; + + return this.getTgChatId(botToken, proxyType, proxyHost, proxyPort, proxyUser, proxyPasswd, iface).then(r => { + if(r.ok) { + if(r.chatId) { + let tgChatIdInput = document.getElementById( + 'widget.cbid.%s.%s.mod_telegram_chat_id'.format(this.appName, instance)); + if(tgChatIdInput) { + if(r.chatId.length == 0) { + alert(_('No messages available. Write something to the bot and try again.')); + } else { + tgChatIdInput.value = r.chatId[r.chatId.length - 1]; + tgChatIdInput.focus(); + tgChatIdInput.blur(); + }; + }; + }; + } else { + let errCode = r.errCode; + let errorString = `${_('Error')} ${errCode}.`; + if(errCode == 401 || errCode == 404) { + errorString += ` ${_('Incorrect bot token?')}`; + } else { + errorString += ` ${r.errDesc}.`; + } + alert(errorString); + }; + }).catch(e => { + alert(e.message); + throw e; + }); + }, + + validateUrl(section, value) { + return (/^$|^https?:\/\/([\w.-]+|\[[a-fA-F0-9:.]+\])(:[0-9]{2,5})?((\/|\?).*)?$/.test(value)) ? + true : _('Expecting:') + ` ${_('valid URL')}\n`; + }, + + CBITimeInput: form.Value.extend({ + __name__ : 'CBI.TimeInput', + + renderWidget(section_id, option_index, cfgvalue) { + let value = (cfgvalue != null) ? cfgvalue : this.default, + widget = new Timefield(value, { + id : this.cbid(section_id), + optional : this.optional || this.rmempty, + maxlength : 3, + placeholder: _('Type a time string'), + validate : L.bind( + function(section, value) { + return (/^$|^\d+[dhms]?$/.test(value)) ? true : _('Expecting:') + + ` ${_('One of the following:')}\n - ${_('days')}: 1d\n - ${_('hours')}: 2h\n - ${_('minutes')}: 10m\n - ${_('seconds')}: 30s\n`; + }, + this, + section_id + ), + disabled : (this.readonly != null) ? this.readonly : this.map.readonly, + }); + return widget.render(); + }, + }), + + CBITextfieldButtonInput: form.Value.extend({ + __name__ : 'CBI.TextfieldButtonInput', + + renderWidget(section_id, option_index, cfgvalue) { + let value = (cfgvalue != null) ? cfgvalue : this.default, + widget = new TextfieldButton(value, { + id : this.cbid(section_id), + optional : this.optional || this.rmempty, + datatype : this.datatype, + placeholder: this.placeholder, + validate : L.bind(this.validate, this, section_id), + disabled : (this.readonly != null) ? this.readonly : this.map.readonly, + btntext : this.btntext, + btntitle : this.btntitle, + btnstyle : this.btnstyle, + onclick : this.onclick, + }); + return widget.render(); + }, + }), + + CBIBlockInetStatus: form.Value.extend({ + __name__ : 'CBI.BlockInetStatus', + + __init__(map, section, ctx) { + this.map = map; + this.section = section; + this.ctx = ctx; + this.optional = true; + this.rmempty = true; + }, + + renderWidget(section_id, option_index, cfgvalue) { + this.ctx.setInternetStatus(); + + return E([ + E('label', { 'class': 'cbi-value-title', 'for': 'inetStatusArea' }, + _('Internet status') + ), this.ctx.inetStatusArea + ]) + }, + }), + + CBIBlockServiceStatus: form.Value.extend({ + __name__ : 'CBI.BlockServiceStatus', + + __init__(map, section, ctx) { + this.map = map; + this.section = section; + this.ctx = ctx; + this.optional = true; + this.rmempty = true; + }, + + renderWidget(section_id, option_index, cfgvalue) { + return E([ + E('label', { 'class': 'cbi-value-title', 'for': 'serviceStatusLabel' }, + _('Service') + ), + E('div', { 'class': 'cbi-value-field' }, + this.ctx.serviceStatusLabel + ), + ]); + }, + }), + + CBIBlockInitButton: form.Value.extend({ + __name__ : 'CBI.BlockInitButton', + + __init__(map, section, ctx) { + this.map = map; + this.section = section; + this.ctx = ctx; + this.optional = true; + this.rmempty = true; + }, + + renderWidget(section_id, option_index, cfgvalue) { + this.ctx.initButton = E('button', { + 'class': (!this.ctx.initStatus) ? btnStyleDisabled : btnStyleEnabled, + 'click': ui.createHandlerFn(this, () => { + return this.ctx.handleServiceAction( + (!this.ctx.initStatus) ? 'enable' : 'disable' + ).then(success => { + if(!success) { + return; + }; + if(!this.ctx.initStatus) { + this.ctx.initButton.textContent = _('Enabled'); + this.ctx.initButton.className = btnStyleEnabled; + this.ctx.initStatus = true; + } + else { + this.ctx.initButton.textContent = _('Disabled'); + this.ctx.initButton.className = btnStyleDisabled; + this.ctx.initStatus = false; + }; + }); + }), + }, (!this.ctx.initStatus) ? _('Disabled') : _('Enabled')); + + return E( [ + E('label', { 'class': 'cbi-value-title', 'for': 'initButton' }, + _('Run service at startup') + ), + E('div', { 'class': 'cbi-value-field' }, [ + E('div', {}, this.ctx.initButton), + E('input', { + 'id' : 'initButton', + 'type': 'hidden', + }), + ]), + ]); + }, + }), + + CBIBlockFileEdit: form.Value.extend({ + __name__ : 'CBI.BlockFileEdit', + + __init__(map, section, ctx, id, file, title, description, callback) { + this.map = map; + this.section = section; + this.ctx = ctx; + this.id = id, + this.optional = true; + this.rmempty = true; + this.file = file; + this.title = title; + this.description = description; + this.callback = callback; + this.content = ''; + }, + + cfgvalue(section_id, option) { + return this.content; + }, + + formvalue(section_id) { + let value = this.content; + let textarea = document.getElementById('widget.file_edit.content.' + this.id); + if(textarea) { + value = textarea.value.trim().replace(/\r\n/g, '\n') + '\n'; + }; + return value; + }, + + write(section_id, formvalue) { + return fs.write(this.file, formvalue).then(rc => { + ui.addNotification(null, E('p', _('Contents have been saved.')), + 'info'); + if(this.callback) { + return this.callback(rc); + }; + }).catch(e => { + ui.addNotification(null, E('p', _('Unable to save the contents') + + ': %s'.format(e.message))); + }); + }, + + load() { + return L.resolveDefault(fs.read(this.file), '').then(c => { + this.content = c; + }); + }, + + renderWidget(section_id, option_index, cfgvalue) { + return E('textarea', { + 'id' : 'widget.file_edit.content.' + this.id, + 'class' : 'cbi-input-textarea', + 'style' : 'width:100% !important', + 'rows' : 10, + 'wrap' : 'off', + 'spellcheck': 'false', + }, cfgvalue); + }, + }), + + load() { + return Promise.all([ + this.getStatus(), + this.getInitStatus(), + L.resolveDefault(fs.list(this.ledsPath), []), + this.getInit(), + uci.load(this.appName), + ]).catch(e => { + ui.addNotification( + null, E('p', _('An error has occurred') + ': %s'.format(e.message))); + }); + }, + + render(data) { + if(!data) { + return; + }; + this.appStatus = (data[0].code == 0) ? data[0].stdout.trim() : null; + this.initStatus = data[1]; + this.leds = data[2]; + if(data[3]) { + if(data[3].mm_mod) { + this.mm = true; + }; + if(data[3].mm_init) { + this.mmInit = true; + }; + if(data[3].email_mod) { + this.email = true; + }; + if(data[3].email_exec) { + this.emailExec = true; + }; + if(data[3].telegram) { + this.telegram = true; + }; + if(data[3].curl_exec) { + this.curlExec = true; + }; + }; + this.currentAppMode = uci.get(this.appName, 'config', 'mode'); + + let s, o, ss; + let m = new form.Map(this.appName, + _('Internet Detector'), + _('Checking Internet availability.')); + + + /* Status widget */ + + s = m.section(form.NamedSection, 'config', 'main'); + o = s.option(this.CBIBlockInetStatus, this); + + + s = m.section(form.NamedSection, 'config', 'main'); + + + /* Service widget */ + + if(this.currentAppMode == '1') { + o = s.option(this.CBIBlockServiceStatus, this); + + // restart button + o = s.option(form.Button, + '_restart_btn', _('Restart service') + ); + o.onclick = () => this.serviceRestartHandler(); + o.inputtitle = _('Restart'); + o.inputstyle = btnStyleApply; + + // init button + o = s.option(this.CBIBlockInitButton, this); + }; + + + /* Main settings */ + + // mode + let mode = s.option(form.ListValue, 'mode', + _('Internet detector mode')); + mode.value('0', _('Disabled')); + mode.value('1', _('Service')); + mode.value('2', _('Web UI only (UI detector)')); + mode.description = '%s
%s
%s'.format( + _('Disabled: detector is completely off.'), + _('Service: detector always runs as a system service.'), + _('Web UI only: detector works only when the Web UI is open (UI detector).') + ); + mode.default = '0'; + + + /* Instances configuration */ + + if(this.currentAppMode != '2') { + + // logging_level + o = s.option(form.ListValue, 'logging_level', + _('Logging'), + _('Log event level.') + ); + o.value(-1, _('Disabled')); + o.value(3, _('Error')); + o.value(4, _('Warning')); + o.value(5, _('Notice')); + o.value(6, _('Info')); + o.value(7, _('Debug')); + o.rmempty = false; + o.default = '6'; + }; + + s = m.section(form.GridSection, 'instance'); + + s.title = _('Instances'); + s.addremove = true; + s.sortable = true; + s.nodescriptions = true; + s.addbtntitle = _('Add instance'); + + s.tab('main', _('Main settings')); + + function makeIntervalOptions(list) { + list.value(2, '2 ' + _('sec')); + list.value(5, '5 ' + _('sec')); + list.value(10, '10 ' + _('sec')); + list.value(15, '15 ' + _('sec')); + list.value(20, '20 ' + _('sec')); + list.value(25, '25 ' + _('sec')); + list.value(30, '30 ' + _('sec')); + list.value(60, '1 ' + _('min')); + list.value(120, '2 ' + _('min')); + list.value(300, '5 ' + _('min')); + list.value(600, '10 ' + _('min')); + } + + function makeTimerDelayOptions(list) { + list.value(25, '25 ' + _('msec')); + list.value(50, '50 ' + _('msec')); + list.value(100, '100 ' + _('msec')); + list.value(250, '250 ' + _('msec')); + list.value(500, '500 ' + _('msec')); + list.value(750, '750 ' + _('msec')); + list.value(1000, '1 ' + _('sec')); + list.value(1500, '1.5 ' + _('sec')); + list.value(2000, '2 ' + _('sec')); + } + + // description + o = s.taboption('main', form.Value, 'description', + _("Description")); + o.datatype = 'maxlength(30)'; + o.modalonly = null; + + // hosts + o = s.taboption('main', form.DynamicList, + 'hosts', _('Hosts'), + _('Hosts for checking Internet availability. Hosts are polled (in list order) until at least one responds.') + ); + o.datatype = 'or(host,hostport,ipaddrport(1))'; + o.default = this.defaultHosts; + o.depends({ check_type: '0' }); + o.depends({ check_type: '1' }); + o.rmempty = false; + o.modalonly = true; + + if(this.curlExec) { + + // urls + o = s.taboption('main', form.DynamicList, + 'urls', _('URLs'), + _('URLs for checking Internet availability. URLs are polled (in list order) until at least one returns HTTP status code 200.') + ); + o.validate = this.validateUrl; + o.default = this.defaultURLs; + o.rmempty = false; + o.depends({ check_type: '2' }); + o.modalonly = true; + }; + + // check_type + o = s.taboption('main', form.ListValue, + 'check_type', _('Check type'), + _('Host availability check type.') + '
' + + ((this.curlExec) ? '' : + _('To support URL checking, you need to install curl.')) + ); + o.value(1, _('ICMP-echo request (ping)')); + o.value(0, _('TCP port connection')); + if(this.curlExec) { + o.value(2, _('URL test (HTTP)')); + }; + o.default = '0'; + o.modalonly = true; + + // tcp_port + o = s.taboption('main', form.Value, + 'tcp_port', _('TCP port'), + _('Default port value for TCP connections.') + ); + o.datatype = 'port'; + o.default = '53'; + o.depends({ check_type: '0' }); + o.modalonly = true; + + // icmp_packet_size + o = s.taboption('main', form.ListValue, + 'icmp_packet_size', _('ICMP packet data size')); + o.value(1, _('Small: 1 byte')); + o.value(32, _('Windows: 32 bytes')); + o.value(56, _('Standard: 56 bytes')); + o.value(248, _('Big: 248 bytes')); + o.value(1492, _('Huge: 1492 bytes')); + o.value(9000, _('Jumbo: 9000 bytes')); + o.default = '56'; + o.depends({ check_type: '1' }); + o.modalonly = true; + + if(this.curlExec) { + + // proxy_type + o = s.taboption('main', form.ListValue, + 'proxy_type', _('Proxy') + ); + o.value('', _('Disabled')); + o.value('http'); + o.value('socks4'); + o.value('socks4a'); + o.value('socks5'); + o.value('socks5h'); + o.default = ''; + o.depends({ check_type: '2' }); + o.modalonly = true; + + // proxy_host + o = s.taboption('main', form.Value, + 'proxy_host', _('Proxy host') + ); + o.datatype = 'host'; + o.rmempty = false; + o.depends({ proxy_type: /.+/ }); + o.modalonly = true; + + // proxy_port + o = s.taboption('main', form.Value, + 'proxy_port', _('Proxy port') + ); + o.datatype = 'port'; + o.rmempty = false; + o.depends({ proxy_type: /.+/ }); + o.modalonly = true; + + // proxy_user + o = s.taboption('main', form.Value, + 'proxy_user', _('Proxy user') + ); + o.depends({ proxy_type: /(http|socks5h?)/ }); + o.modalonly = true; + + // proxy_passwd + o = s.taboption('main', form.Value, + 'proxy_passwd', _('Proxy password') + ); + o.depends({ proxy_type: /(http|socks5h?)/ }); + o.modalonly = true; + o.password = true; + }; + + // iface + o = s.taboption('main', widgets.DeviceSelect, + 'iface', _('Device'), + _('Network device for Internet access. If not specified, the default device is used.') + ); + o.noaliases = true; + o.modalonly = true; + + // interval_up + o = s.taboption('main', form.ListValue, + 'interval_up', _('Alive interval'), + _('Hosts polling interval when the Internet is up.') + ); + o.default = '30'; + o.modalonly = true; + makeIntervalOptions(o); + + // interval_down + o = s.taboption('main', form.ListValue, + 'interval_down', _('Dead interval'), + _('Hosts polling interval when the Internet is down.') + ); + o.default = '5'; + o.modalonly = true; + makeIntervalOptions(o); + + // connection_attempts + o = s.taboption('main', form.ListValue, + 'connection_attempts', _('Connection attempts'), + _('Maximum number of attempts to connect to each host.') + ); + o.modalonly = true; + o.value(1); + o.value(2); + o.value(3); + o.default = '2'; + + // connection_timeout + o = s.taboption('main', form.ListValue, + 'connection_timeout', _('Connection timeout'), + _('Maximum timeout for waiting for a response from the host.') + ); + o.modalonly = true; + o.value(1, '1 ' + _('sec')); + o.value(2, '2 ' + _('sec')); + o.value(3, '3 ' + _('sec')); + o.value(4, '4 ' + _('sec')); + o.value(5, '5 ' + _('sec')); + o.value(6, '6 ' + _('sec')); + o.value(7, '7 ' + _('sec')); + o.value(8, '8 ' + _('sec')); + o.value(9, '9 ' + _('sec')); + o.value(10, '10 ' + _('sec')); + o.default = '2'; + + // enabled + o = s.taboption('main', form.Flag, 'enabled', + _('Enabled'), + ); + o.rmempty = false; + o.default = '1'; + o.editable = true; + o.modalonly = false; + + + /* Modules */ + + if(this.currentAppMode != '2') { + s.tab('led_control', _('LED control')); + s.tab('reboot_device', _('Reboot device')); + s.tab('restart_network', _('Restart network')); + if(this.mm) { + s.tab('restart_modem', _('Restart modem')); + }; + }; + + s.tab('public_ip', _('Public IP address')); + + if(this.currentAppMode != '2') { + if(this.email) { + s.tab('email', _('Email notification')); + }; + if(this.telegram) { + s.tab('telegram', _('Telegram notification')); + }; + s.tab('user_scripts', _('User scripts')); + s.tab('regular_script', _('Regular script')); + }; + + s.addModalOptions = (s, section_id, ev) => { + + if(section_id == 'config') { + s.map.children = []; + s.map.readonly = true; + s.map.children.push(new form.NamedSection(s.map, '_dummy', '_dummy', + _('Error!'), _('Invalid instance name...'))); + return; + }; + + if(this.currentAppMode != '2') { + + // LED control + + o = s.taboption('led_control', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('LED indicates the Internet status.') + + '
'; + o.modalonly = true; + + if(this.leds.length > 0) { + this.leds.sort((a, b) => (a.name > b.name) ? 1 : (a.name < b.name) ? -1 : 0); + + // enabled + o = s.taboption('led_control', form.Flag, + 'mod_led_control_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + o = s.taboption('led_control', form.SectionValue, + s.section, form.NamedSection, s.section); + o.depends({ mod_led_control_enabled: '1' }); + ss = o.subsection; + + for(let i = 1; i <= this.ledsPerInstance; i++) { + ss.tab('led' + i + '_tab', _('LED') + ' ' + i); + + // led_name + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_name', + _('LED Name')); + o.modalonly = true; + if(i > 1) { + o.rmempty = true; + o.optional = true; + }; + this.leds.forEach(e => o.value(e.name)); + + // led_action_1 + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_action_1', + _('After connection')); + o.depends({ ['mod_led_control_led' + i + '_name']: /.+/ }); + o.modalonly = true; + o.value(1, _('Off')); + o.value(2, _('On')); + o.value(3, _('Blinking (kernel: timer)')); + o.value(4, _('Network device activity (kernel: netdev)')); + o.default = '2'; + + // blink_on_delay_1 + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_blink_on_delay_1', + _('On-state delay'), + _('On-state delay for blinking option.')); + makeTimerDelayOptions(o); + o.depends({ ['mod_led_control_led' + i + '_action_1']: '3' }); + o.modalonly = true; + o.default = '500'; + + // blink_off_delay_1 + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_blink_off_delay_1', + _('Off-state delay'), + _('Off-state delay for blinking option.')); + makeTimerDelayOptions(o); + o.depends({ ['mod_led_control_led' + i + '_action_1']: '3' }); + o.modalonly = true; + o.default = '500'; + + // netdev_device_1 + o = ss.taboption('led' + i + '_tab', widgets.DeviceSelect, + 'mod_led_control_led' + i + '_netdev_device_1', + _('Device'), + _('LED will display the link activity of this network device.') + ); + o.depends({ ['mod_led_control_led' + i + '_action_1']: '4' }); + o.modalonly = true; + o.rmempty = false; + o.noaliases = true; + + // netdev_mode_1 + o = ss.taboption('led' + i + '_tab', form.MultiValue, + 'mod_led_control_led' + i + '_netdev_mode_1', + _('LED mode') + ); + o.depends({ ['mod_led_control_led' + i + '_action_1']: '4' }); + o.modalonly = true; + o.value('link', _('Link On')); + o.value('tx', _('Transmit')); + o.value('rx', _('Receive')); + o.default = 'link'; + o.rmempty = false; + + // led_action_2 + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_action_2', + _('After disconnection')); + o.depends({ ['mod_led_control_led' + i + '_name']: /.+/ }); + o.modalonly = true; + o.value(1, _('Off')); + o.value(2, _('On')); + o.value(3, _('Blinking (kernel: timer)')); + o.value(4, _('Network device activity (kernel: netdev)')); + o.default = '1'; + + // blink_on_delay_2 + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_blink_on_delay_2', + _('On-state delay'), + _('On-state delay for blinking option.')); + makeTimerDelayOptions(o); + o.depends({ ['mod_led_control_led' + i + '_action_2']: '3' }); + o.modalonly = true; + o.default = '500'; + + // blink_off_delay_2 + o = ss.taboption('led' + i + '_tab', form.ListValue, + 'mod_led_control_led' + i + '_blink_off_delay_2', + _('Off-state delay'), + _('Off-state delay for blinking option.')); + makeTimerDelayOptions(o); + o.depends({ ['mod_led_control_led' + i + '_action_2']: '3' }); + o.modalonly = true; + o.default = '500'; + + // netdev_device_2 + o = ss.taboption('led' + i + '_tab', widgets.DeviceSelect, + 'mod_led_control_led' + i + '_netdev_device_2', + _('Device'), + _('LED will display the link activity of this network device.') + ); + o.depends({ ['mod_led_control_led' + i + '_action_2']: '4' }); + o.modalonly = true; + o.rmempty = false; + o.noaliases = true; + + // netdev_mode_2 + o = ss.taboption('led' + i + '_tab', form.MultiValue, + 'mod_led_control_led' + i + '_netdev_mode_2', + _('LED mode') + ); + o.depends({ ['mod_led_control_led' + i + '_action_2']: '4' }); + o.modalonly = true; + o.value('link', _('Link On')); + o.value('tx', _('Transmit')); + o.value('rx', _('Receive')); + o.default = 'link'; + o.rmempty = false; + + }; + } else { + o = s.taboption('led_control', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('No LEDs available...') + + '
'; + o.modalonly = true; + }; + + // Reboot device + + o = s.taboption('reboot_device', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Device will be rebooted when the Internet is disconnected.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('reboot_device', form.Flag, 'mod_reboot_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + // dead_period + o = s.taboption('reboot_device', this.CBITimeInput, + 'mod_reboot_dead_period', _('Dead period'), + _('Period of time without Internet access until the device is rebooted.') + ); + o.default = '3600'; + o.rmempty = false; + o.modalonly = true; + + // force_reboot_delay + o = s.taboption('reboot_device', form.ListValue, + 'mod_reboot_force_reboot_delay', _('Forced reboot delay'), + _('Waiting for a reboot to complete before performing a forced reboot.') + ); + o.modalonly = true; + o.value(0, _('Disable forced reboot')); + o.value(60, '1 ' + _('min')); + o.value(120, '2 ' + _('min')); + o.value(300, '5 ' + _('min')); + o.value(600, '10 ' + _('min')); + o.value(1800, '30 ' + _('min')); + o.value(3600, '1 ' + _('hour')); + o.default = '300'; + + // disconnected_at_startup + o = s.taboption('reboot_device', form.Flag, + 'mod_reboot_disconnected_at_startup', + _('On startup'), + _('Reboot device if the Internet is disconnected at service startup.') + ); + o.rmempty = false; + o.modalonly = true; + + // Restart network + + o = s.taboption('restart_network', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Network will be restarted when the Internet is disconnected.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('restart_network', form.Flag, + 'mod_network_restart_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + // dead_period + o = s.taboption('restart_network', this.CBITimeInput, + 'mod_network_restart_dead_period', _('Dead period'), + _('Period of time without Internet access before network restart.') + ); + o.default = '900'; + o.rmempty = false; + o.modalonly = true; + + // ifaces + o = s.taboption('restart_network', widgets.DeviceSelect, + 'mod_network_restart_ifaces', + _('Device'), + _('Network device or interface to restart. If not specified, then the network service is restarted.') + ); + o.modalonly = true; + o.multiple = true; + o.modalonly = true; + + // attempts + o = s.taboption('restart_network', form.ListValue, + 'mod_network_restart_attempts', _('Restart attempts'), + _('Maximum number of network restart attempts before Internet access is available.') + ); + o.modalonly = true; + o.value(1); + o.value(2); + o.value(3); + o.value(4); + o.value(5); + o.value(10); + o.value(0, _('infinitely')); + o.default = '1'; + + // attempt_interval + o = s.taboption('restart_network', this.CBITimeInput, + 'mod_network_restart_attempt_interval', _('Attempt interval'), + _('Interval between network restarts.') + ); + o.default = '60'; + o.rmempty = false; + o.modalonly = true; + + // device_timeout + o = s.taboption('restart_network', form.ListValue, + 'mod_network_restart_device_timeout', _('Device timeout'), + _('Timeout between stopping and starting a network device when restarting.') + ); + o.modalonly = true; + o.value(0, '0 ' + _('sec')); + o.value(1, '1 ' + _('sec')); + o.value(2, '2 ' + _('sec')); + o.value(3, '3 ' + _('sec')); + o.value(4, '4 ' + _('sec')); + o.value(5, '5 ' + _('sec')); + o.value(6, '6 ' + _('sec')); + o.value(7, '7 ' + _('sec')); + o.value(8, '8 ' + _('sec')); + o.value(9, '9 ' + _('sec')); + o.value(10, '10 ' + _('sec')); + o.default = '0'; + + // disconnected_at_startup + o = s.taboption('restart_network', form.Flag, + 'mod_network_restart_disconnected_at_startup', + _('On startup'), + _('Restart network if the Internet is disconnected at service startup.') + ); + o.rmempty = false; + o.modalonly = true; + + // Restart modem + + if(this.mm) { + if(this.mmInit) { + o = s.taboption('restart_modem', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Modem will be restarted when the Internet is disconnected.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('restart_modem', form.Flag, + 'mod_modem_restart_enabled', + _('Enabled'), + ); + o.rmempty = false; + o.modalonly = true; + + // dead_period + o = s.taboption('restart_modem', this.CBITimeInput, + 'mod_modem_restart_dead_period', _('Dead period'), + _('Period of time without Internet access before modem restart.') + ); + o.default = '600'; + o.rmempty = false; + o.modalonly = true; + + // any_band + o = s.taboption('restart_modem', form.Flag, + 'mod_modem_restart_any_band', _('Unlock modem bands'), + _('Set the modem to be allowed to use any band.') + ); + o.rmempty = false; + o.modalonly = true; + + // attempts + o = s.taboption('restart_modem', form.ListValue, + 'mod_modem_restart_attempts', _('Restart attempts'), + _('Maximum number of modem restart attempts before Internet access is available.') + ); + o.modalonly = true; + o.value(1); + o.value(2); + o.value(3); + o.value(4); + o.value(5); + o.value(10); + o.value(0, _('infinitely')); + o.default = '1'; + + // attempt_interval + o = s.taboption('restart_modem', this.CBITimeInput, + 'mod_modem_restart_attempt_interval', _('Attempt interval'), + _('Interval between modem restarts.') + ); + o.default = '60'; + o.rmempty = false; + o.modalonly = true; + + // iface + o = s.taboption('restart_modem', widgets.NetworkSelect, + 'mod_modem_restart_iface', + _('Interface'), + _('ModemManger interface. If specified, it will be restarted after restarting ModemManager.') + ); + o.multiple = false; + o.nocreate = true; + o.modalonly = true; + + // iface_timeout + o = s.taboption('restart_modem', form.ListValue, + 'mod_modem_restart_iface_timeout', _('Interface timeout'), + _('Timeout between stopping and starting a ModemManger interface when restarting.') + ); + o.modalonly = true; + o.value(0, '0 ' + _('sec')); + o.value(1, '1 ' + _('sec')); + o.value(2, '2 ' + _('sec')); + o.value(3, '3 ' + _('sec')); + o.value(4, '4 ' + _('sec')); + o.value(5, '5 ' + _('sec')); + o.value(6, '6 ' + _('sec')); + o.value(7, '7 ' + _('sec')); + o.value(8, '8 ' + _('sec')); + o.value(9, '9 ' + _('sec')); + o.value(10, '10 ' + _('sec')); + o.default = '0'; + + // disconnected_at_startup + o = s.taboption('restart_modem', form.Flag, + 'mod_modem_restart_disconnected_at_startup', + _('On startup'), + _('Restart modem if the Internet is disconnected at service startup.') + ); + o.rmempty = false; + o.modalonly = true; + } else { + o = s.taboption('restart_modem', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('ModemManager is not available...') + + '
'; + o.modalonly = true; + }; + }; + }; + + // Public IP address + + o = s.taboption('public_ip', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Checking the real public IP address.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('public_ip', form.Flag, 'mod_public_ip_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + // provider + o = s.taboption('public_ip', form.ListValue, + 'mod_public_ip_provider', _('Provider'), + _('Service for determining the public IP address.') + '
' + + ((this.curlExec) ? '' : + _('To support HTTP services, you need to install curl.')) + ); + o.modalonly = true; + for(let i of this.publicIPProviders.dns) { + o.value(i.name, i.title); + }; + if(this.curlExec) { + for(let i of this.publicIPProviders.http) { + o.value(i.name, i.title); + }; + }; + o.default = this.publicIPProviders.dns[0].name; + + // ipv6 + o = s.taboption('public_ip', form.ListValue, + 'mod_public_ip_qtype', _('DNS query type'), + _('The type of record requested in the DNS query (if the service supports it).') + ); + o.modalonly = true; + o.value('0', 'A (IPv4)'); + o.value('1', 'AAAA (IPv6)'); + o.default = '0'; + for(let i of this.publicIPProviders.dns) { + o.depends({ mod_public_ip_provider: i.name }); + }; + + // interval + o = s.taboption('public_ip', form.ListValue, + 'mod_public_ip_interval', _('Polling interval'), + _('Interval between IP address requests.') + ); + o.default = '600'; + o.modalonly = true; + o.value(60, '1' + ' ' + _('min')); + o.value(300, '5' + ' ' + _('min')); + o.value(600, '10' + ' ' + _('min')); + o.value(1800, '30' + ' ' + _('min')); + o.value(3600, '1' + ' ' + _('hour')); + o.value(10800, '3' + ' ' + _('hour')); + + // interval_failed + o = s.taboption('public_ip', form.ListValue, + 'mod_public_ip_interval_failed', _('Failed interval'), + _('Interval between IP address requests if the IP address is not defined.') + ); + o.default = '60'; + o.modalonly = true; + o.value(30, '30' + ' ' + _('sec')); + o.value(60, '1' + ' ' + _('min')); + o.value(180, '3' + ' ' + _('min')); + o.value(300, '5' + ' ' + _('min')); + o.value(600, '10' + ' ' + _('min')); + + // request_attempts + o = s.taboption('public_ip', form.ListValue, + 'mod_public_ip_request_attempts', _('Attempts'), + _('Number of attempts to request an IP address.') + ); + o.default = '2' + o.modalonly = true; + for(let i = 1; i <= 3; i++) { + o.value(i); + }; + + // timeout + o = s.taboption('public_ip', form.ListValue, + 'mod_public_ip_timeout', _('Server response timeout') + ); + o.default = '3' + o.modalonly = true; + for(let i = 1; i <= 5; i++) { + o.value(i, i + ' ' + _('sec')); + }; + + if(this.currentAppMode != '2') { + + // enable_ip_script + o = s.taboption('public_ip', form.Flag, + 'mod_public_ip_enable_ip_script', + _('Enable public-ip-script')); + o.rmempty = false; + o.modalonly = true; + + // public-ip-script edit dialog + o = s.taboption('public_ip', this.CBIBlockFileEdit, this, + 'public-ip-script', + this.configDir + '/public-ip-script.' + s.section, + _('Edit public-ip-script'), + _('Shell commands that run when the public IP address changes. New IP is available as value of the $PUBLIC_IP variable (empty string if undefined).') + ); + o.modalonly = true; + + // Email notification + + if(this.email) { + if(this.emailExec) { + o = s.taboption('email', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('An email will be sent when connected or disconnected from the Internet.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('email', form.Flag, 'mod_email_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + // mode + o = s.taboption('email', form.ListValue, + 'mod_email_mode', _('When email will be sent') + ); + o.modalonly = true; + o.value(0, _('after connection')); + o.value(1, _('after disconnection')); + o.value(2, _('after connection or disconnection')); + o.default = '0'; + + // alive_period + o = s.taboption('email', this.CBITimeInput, + 'mod_email_alive_period', _('Alive period'), + _('Period of time after connecting to the Internet before sending a message.') + ); + o.rmempty = false; + o.modalonly = true; + o.depends({ 'mod_email_mode': '0' }); + o.depends({ 'mod_email_mode': '2' }); + o.default = '0'; + + // dead_period + o = s.taboption('email', this.CBITimeInput, + 'mod_email_dead_period', _('Dead period'), + _('Period of time after disconnecting from Internet before sending a message.') + ); + o.rmempty = false; + o.modalonly = true; + o.depends({ 'mod_email_mode': '1' }); + o.depends({ 'mod_email_mode': '2' }); + o.default = '0'; + + // host_alias + o = s.taboption('email', form.Value, + 'mod_email_host_alias', + _('Host alias'), + _('Host identifier in messages. If not specified, hostname will be used.')); + o.modalonly = true; + + // mail_recipient + o = s.taboption('email', form.Value, + 'mod_email_mail_recipient', _('Recipient')); + o.description = _('Email address of the recipient.'); + o.modalonly = true; + + // mail_sender + o = s.taboption('email', form.Value, + 'mod_email_mail_sender', _('Sender')); + o.description = _('Email address of the sender.'); + o.modalonly = true; + + // mail_user + o = s.taboption('email', form.Value, + 'mod_email_mail_user', _('User')); + o.description = _('Username for SMTP authentication.'); + o.modalonly = true; + + // mail_password + o = s.taboption('email', form.Value, + 'mod_email_mail_password', _('Password')); + o.description = _('Password for SMTP authentication.'); + o.password = true; + o.modalonly = true; + + // mail_smtp + o = s.taboption('email', form.Value, + 'mod_email_mail_smtp', _('SMTP server')); + o.description = _('Hostname/IP address of the SMTP server.'); + o.datatype = 'host'; + o.modalonly = true; + + // mail_smtp_port + o = s.taboption('email', form.Value, + 'mod_email_mail_smtp_port', _('SMTP server port')); + o.datatype = 'port'; + o.modalonly = true; + + // mail_security + o = s.taboption('email', form.ListValue, + 'mod_email_mail_security', _('Security')); + o.description = '%s
%s'.format( + _('TLS: use STARTTLS if the server supports it.'), + _('SSL: SMTP over SSL.'), + ); + o.value('tls', 'TLS'); + o.value('ssl', 'SSL'); + o.default = 'tls'; + o.modalonly = true; + + // message_at_startup + o = s.taboption('email', form.Flag, + 'mod_email_message_at_startup', + _('On startup'), + _('Send message on service startup.') + ); + o.rmempty = false; + o.modalonly = true; + } else { + o = s.taboption('email', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Mailsend is not available...') + + '
'; + o.modalonly = true; + }; + }; + + // Telegram notification + + if(this.telegram) { + if(this.curlExec) { + o = s.taboption('telegram', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Telegram message will be sent when connected or disconnected from the Internet.') + + '
' + + _("You need to register a new %sTelegram bot%s. Then get the bot's API token and paste it into the Bot token field. After that, open a chat with the bot, write something (in the Telegram app) and you will be able to get the chat ID using the ID button.").format("", '') + + '
'; + + o.modalonly = true; + + // enabled + o = s.taboption('telegram', form.Flag, + 'mod_telegram_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + // mode + o = s.taboption('telegram', form.ListValue, + 'mod_telegram_mode', _('When message will be sent') + ); + o.modalonly = true; + o.value(0, _('after connection')); + o.value(1, _('after disconnection')); + o.value(2, _('after connection or disconnection')); + o.default = '0'; + + // alive_period + o = s.taboption('telegram', this.CBITimeInput, + 'mod_telegram_alive_period', _('Alive period'), + _('Period of time after connecting to the Internet before sending a message.') + ); + o.rmempty = false; + o.modalonly = true; + o.depends({ 'mod_telegram_mode': '0' }); + o.depends({ 'mod_telegram_mode': '2' }); + o.default = '0'; + + // dead_period + o = s.taboption('telegram', this.CBITimeInput, + 'mod_telegram_dead_period', _('Dead period'), + _('Period of time after disconnecting from Internet before sending a message.') + ); + o.rmempty = false; + o.modalonly = true; + o.depends({ 'mod_telegram_mode': '1' }); + o.depends({ 'mod_telegram_mode': '2' }); + o.default = '0'; + + // host_alias + o = s.taboption('telegram', form.Value, + 'mod_telegram_host_alias', + _('Host alias'), + _('Host identifier in messages. If not specified, hostname will be used.')); + o.modalonly = true; + + // tg_api_token + o = s.taboption('telegram', form.Value, + 'mod_telegram_api_token', _('Bot token'), + _('Telegram bot API token.')); + o.password = true; + o.modalonly = true; + + // tg_chat_id + o = s.taboption('telegram', this.CBITextfieldButtonInput, + 'mod_telegram_chat_id', _('Chat ID'), + _('ID of the Telegram chat to which messages will be sent.') + ); + o.btntext = _('ID'), + o.btntitle = _('Request chat ID from bot API'), + o.btnstyle = 'action', + o.onclick = ui.createHandlerFn(this, + (ev) => this.getTgChatIdHandler(ev, s.section)); + o.modalonly = true; + o.optional = false; + o.rmempty = false; + o.depends({ 'mod_telegram_api_token': /.+/ }); + + // proxy_type + o = s.taboption('telegram', form.ListValue, + 'mod_telegram_proxy_type', _('Proxy') + ); + o.value('', _('Disabled')); + o.value('http'); + o.value('socks4'); + o.value('socks4a'); + o.value('socks5'); + o.value('socks5h'); + o.default = ''; + o.modalonly = true; + + // proxy_host + o = s.taboption('telegram', form.Value, + 'mod_telegram_proxy_host', _('Proxy host') + ); + o.datatype = 'host'; + o.rmempty = false; + o.depends({ mod_telegram_proxy_type: /.+/ }); + o.modalonly = true; + + // proxy_port + o = s.taboption('telegram', form.Value, + 'mod_telegram_proxy_port', _('Proxy port') + ); + o.datatype = 'port'; + o.rmempty = false; + o.depends({ mod_telegram_proxy_type: /.+/ }); + o.modalonly = true; + + // proxy_user + o = s.taboption('telegram', form.Value, + 'mod_telegram_proxy_user', _('Proxy user') + ); + o.depends({ mod_telegram_proxy_type: /(http|socks5h?)/ }); + o.modalonly = true; + + // proxy_passwd + o = s.taboption('telegram', form.Value, + 'mod_telegram_proxy_passwd', _('Proxy password') + ); + o.depends({ mod_telegram_proxy_type: /(http|socks5h?)/ }); + o.modalonly = true; + o.password = true; + + // iface + o = s.taboption('telegram', widgets.DeviceSelect, + 'mod_telegram_iface', _('Device'), + _('Network device for sending messages. If not specified, the default device is used.') + ); + o.noaliases = true; + o.modalonly = true; + + // message_at_startup + o = s.taboption('telegram', form.Flag, + 'mod_telegram_message_at_startup', + _('On startup'), + _('Send message on service startup.') + ); + o.rmempty = false; + o.modalonly = true; + } else { + o = s.taboption('telegram', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Curl is not available...') + + '
'; + o.modalonly = true; + }; + }; + + // User scripts + + o = s.taboption('user_scripts', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Shell commands to run when connected or disconnected from the Internet.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('user_scripts', form.Flag, 'mod_user_scripts_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + o = s.taboption('user_scripts', form.SectionValue, + 'user_scripts_section', form.NamedSection, s.section); + ss = o.subsection; + + // up-script tab + ss.tab('user_scripts_up_script', 'up-script'); + + o = ss.taboption('user_scripts_up_script', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Shell commands that run when connected to the Internet.') + + '
'; + o.modalonly = true; + + // up_script edit + o = ss.taboption('user_scripts_up_script', this.CBIBlockFileEdit, this, + 'up_script', + this.configDir + '/up-script.' + s.section, + _('Edit up-script') + ); + o.modalonly = true; + + // alive_period + o = ss.taboption('user_scripts_up_script', this.CBITimeInput, + 'mod_user_scripts_alive_period', _('Alive period'), + _('Period of time after connecting to Internet before up-script runs.') + ); + o.default = '0'; + o.rmempty = false; + o.modalonly = true; + + // up_script_attempts + o = ss.taboption('user_scripts_up_script', form.ListValue, + 'mod_user_scripts_up_script_attempts', _('Attempts'), + _('Maximum number of up-script run attempts when connected to the Internet.') + ); + o.modalonly = true; + o.value(1); + o.value(2); + o.value(3); + o.value(4); + o.value(5); + o.value(10); + o.value(0, _('infinitely')); + o.default = '1'; + + // up_script_attempt_interval + o = ss.taboption('user_scripts_up_script', this.CBITimeInput, + 'mod_user_scripts_up_script_attempt_interval', + _('Attempt interval'), + _('Interval between up-script runs.') + ); + o.default = '60'; + o.rmempty = false; + o.modalonly = true; + + // connected_at_startup + o = ss.taboption('user_scripts_up_script', form.Flag, + 'mod_user_scripts_connected_at_startup', + _('On startup'), + _('Run up-script if the Internet is connected at service startup.') + ); + o.rmempty = false; + o.modalonly = true; + + // down-script tab + ss.tab('user_scripts_down_script', 'down-script'); + + o = ss.taboption('user_scripts_down_script', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Shell commands to run when disconnected from the Internet.') + + '
'; + o.modalonly = true; + + // down_script edit + o = ss.taboption('user_scripts_down_script', this.CBIBlockFileEdit, this, + 'down_script', + this.configDir + '/down-script.' + s.section, + _('Edit down-script') + ); + o.modalonly = true; + + // dead_period + o = ss.taboption('user_scripts_down_script', this.CBITimeInput, + 'mod_user_scripts_dead_period', _('Dead period'), + _('Period of time after disconnecting from Internet before down-script runs.') + ); + o.default = '0'; + o.rmempty = false; + o.modalonly = true; + + // down_script_attempts + o = ss.taboption('user_scripts_down_script', form.ListValue, + 'mod_user_scripts_down_script_attempts', _('Attempts'), + _('Maximum number of down-script run attempts before Internet access is available.') + ); + o.modalonly = true; + o.value(1); + o.value(2); + o.value(3); + o.value(4); + o.value(5); + o.value(10); + o.value(0, _('infinitely')); + o.default = '1'; + + // down_script_attempt_interval + o = ss.taboption('user_scripts_down_script', this.CBITimeInput, + 'mod_user_scripts_down_script_attempt_interval', + _('Attempt interval'), + _('Interval between down-script runs.') + ); + o.default = '60'; + o.rmempty = false; + o.modalonly = true; + + // disconnected_at_startup + o = ss.taboption('user_scripts_down_script', form.Flag, + 'mod_user_scripts_disconnected_at_startup', + _('On startup'), + _('Run down-script if the Internet is disconnected at service startup.') + ); + o.rmempty = false; + o.modalonly = true; + + // Regular script + + o = s.taboption('regular_script', form.DummyValue, '_dummy'); + o.rawhtml = true; + o.default = '
' + + _('Shell commands that are run regularly.') + + '
'; + o.modalonly = true; + + // enabled + o = s.taboption('regular_script', form.Flag, + 'mod_regular_script_enabled', + _('Enabled')); + o.rmempty = false; + o.modalonly = true; + + // next run + o = s.taboption('regular_script', form.DummyValue, + '_dummy', _('Next run')); + o.rawhtml = true; + o.default = '' + (this.modRegularScriptNextRun[s.section] || _('Not scheduled')) + ''; + o.modalonly = true; + + // interval + o = s.taboption('regular_script', this.CBITimeInput, + 'mod_regular_script_interval', _('Run interval') + ); + o.default = '3600'; + o.rmempty = false; + o.modalonly = true; + + // inet_state + o = s.taboption('regular_script', form.ListValue, + 'mod_regular_script_inet_state', _('Run if Internet state is') + ); + o.modalonly = true; + o.value(0, _('connected')); + o.value(1, _('disconnected')); + o.value(2, _('connected or disconnected')); + o.default = '2'; + + // regular_script edit + o = s.taboption('regular_script', this.CBIBlockFileEdit, this, + 'regular_script', + this.configDir + '/regular-script.' + s.section, + _('Edit regular-script'), + _('Shell commands that run regularly at a specified interval. Current state of the Internet is available as value of the $INET_STATE variable (0 - connected, 1 - disconnected).') + ); + o.modalonly = true; + }; + + }; + + if(this.currentAppMode != '0') { + poll.add( + L.bind((this.currentAppMode == '1') ? this.servicePoll : this.uiPoll, this), + this.pollInterval + ); + }; + + let mapPromise = m.render(); + mapPromise.then(node => node.classList.add('fade-in')); + return mapPromise; + }, +}); diff --git a/luci-app-internet-detector/htdocs/luci-static/resources/view/status/include/00_internet.js b/luci-app-internet-detector/htdocs/luci-static/resources/view/status/include/00_internet.js new file mode 100644 index 00000000..f6b4272b --- /dev/null +++ b/luci-app-internet-detector/htdocs/luci-static/resources/view/status/include/00_internet.js @@ -0,0 +1,150 @@ +'use strict'; +'require baseclass'; +'require fs'; +'require rpc'; +'require uci'; + +document.head.append(E('style', {'type': 'text/css'}, +` +:root { + --app-id-font-color: #454545; + --app-id-font-shadow: #fff; + --app-id-connected-color: #6bdebb; + --app-id-disconnected-color: #f8aeba; + --app-id-undefined-color: #dfdfdf; +} +:root[data-darkmode="true"] { + --app-id-font-color: #f6f6f6; + --app-id-font-shadow: #4d4d4d; + --app-id-connected-color: #005F20; + --app-id-disconnected-color: #a93734; + --app-id-undefined-color: #4d4d4d; +} +.id-connected { + --on-color: var(--app-id-font-color); + background-color: var(--app-id-connected-color) !important; + border-color: var(--app-id-connected-color) !important; + color: var(--app-id-font-color) !important; + text-shadow: 0 1px 1px var(--app-id-font-shadow); +} +.id-disconnected { + --on-color: var(--app-id-font-color); + background-color: var(--app-id-disconnected-color) !important; + border-color: var(--app-id-disconnected-color) !important; + color: var(--app-id-font-color) !important; + text-shadow: 0 1px 1px var(--app-id-font-shadow); +} +.id-undefined { + --on-color: var(--app-id-font-color); + background-color: var(--app-id-undefined-color) !important; + border-color: var(--app-id-undefined-color) !important; + color: var(--app-id-font-color) !important; + text-shadow: 0 1px 1px var(--app-id-font-shadow); +} +.id-label-status { + display: inline-block; + word-wrap: break-word; + margin: 2px !important; + padding: 4px 8px; + border: 1px solid; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + font-weight: bold; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +} +`)); + +return baseclass.extend({ + title : _('Internet'), + appName : 'internet-detector', + currentAppMode : null, + inetStatus : null, + + callUIPoll: rpc.declare({ + object: 'luci.internet-detector', + method: 'UIPoll', + expect: { '': {} } + }), + + getUIPoll() { + return this.callUIPoll().then(data => { + return data; + }); + }, + + callInetStatus: rpc.declare({ + object: 'luci.internet-detector', + method: 'InetStatus', + expect: { '': {} } + }), + + getInetStatus() { + return this.callInetStatus().then(data => { + return data; + }); + }, + + async load() { + if(!this.currentAppMode) { + await uci.load(this.appName).then(data => { + this.currentAppMode = uci.get(this.appName, 'config', 'mode'); + }).catch(e => {}); + }; + + if(this.currentAppMode == '2') { + return this.getUIPoll(); + } + else if(this.currentAppMode == '1') { + return L.resolveDefault(this.getInetStatus(), null); + }; + }, + + render(data) { + if(this.currentAppMode == '0') { + return; + } + + this.inetStatus = data; + + let inetStatusArea = E('div', {}); + + if(!this.inetStatus || !this.inetStatus.instances || this.inetStatus.instances.length == 0) { + let label = E('span', { 'class': 'id-label-status id-undefined' }, _('Undefined')); + if(this.currentAppMode == '2') { + label.classList.add('spinning'); + }; + inetStatusArea.append(label); + } else { + this.inetStatus.instances.sort((a, b) => a.num - b.num); + + for(let i of this.inetStatus.instances) { + let status = _('Disconnected'); + let className = 'id-label-status id-disconnected'; + if(i.inet == 0) { + status = _('Connected'); + className = 'id-label-status id-connected'; + } + else if(i.inet == -1) { + status = _('Undefined'); + className = 'id-label-status id-undefined spinning'; + }; + + let publicIp = (i.mod_public_ip !== undefined) ? + ' | %s: %s'.format(_('Public IP'), (i.mod_public_ip == '') ? _('Undefined') : _(i.mod_public_ip)) + : ''; + + inetStatusArea.append( + E('span', { 'class': className }, '%s%s%s'.format( + i.instance + ': ', status, publicIp) + ) + ); + }; + }; + + return E('div', { + 'class': 'cbi-section', + 'style': 'margin-bottom:1em', + }, inetStatusArea); + }, +}); diff --git a/luci-app-internet-detector/po/ru/internet-detector.po b/luci-app-internet-detector/po/ru/internet-detector.po new file mode 100644 index 00000000..cae6c563 --- /dev/null +++ b/luci-app-internet-detector/po/ru/internet-detector.po @@ -0,0 +1,747 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? " +"1 : 2);\n" +"Language: ru\n" + +msgid "LED Name" +msgstr "Ð˜Ð¼Ñ LED" + +msgid "LED control" +msgstr "Управление LED" + +msgid "" +"LED indicates the Internet status." +msgstr "LED отображает ÑÑ‚Ð°Ñ‚ÑƒÑ Ð˜Ð½Ñ‚ÐµÑ€Ð½ÐµÑ‚." + +msgid "LED mode" +msgstr "Режим LED" + +msgid "" +"LED will display the link activity of this network device." +msgstr "" +"LED будет отображать активноÑть линка Ñтого Ñетевого уÑтройÑтва." + +msgid "Add instance" +msgstr "Добавить ÑкземплÑÑ€" + +msgid "After connection" +msgstr "ПоÑле подключениÑ" + +msgid "After disconnection" +msgstr "ПоÑле отключениÑ" + +msgid "Alive interval" +msgstr "Интервал при подключении" + +msgid "Alive period" +msgstr "Период поÑле подключениÑ" + +msgid "An email will be sent when connected or disconnected from the Internet." +msgstr "Сообщение будет отправлено на email при подключении или отключении от Интернет." + +msgid "An error has occurred" +msgstr "Произошла ошибка" + +msgid "Attempt interval" +msgstr "Интервал попыток" + +msgid "Attempts" +msgstr "Попытки" + +msgid "Big: 248 bytes" +msgstr "Большой: 248 байт" + +msgid "Blinking (kernel: timer)" +msgstr "Мигание (kernel: timer)" + +msgid "Bot API token is missing!" +msgstr "ОтÑутÑтвует API токен бота!" + +msgid "Bot token" +msgstr "Токен бота" + +msgid "ID чата" +msgstr "" + +msgid "Check type" +msgstr "Тип проверки" + +msgid "Checking Internet availability." +msgstr "Проверка доÑтупноÑти Интернет." + +msgid "Checking the real public IP address." +msgstr "Проверка реального публичного IP адреÑа." + +msgid "Command failed" +msgstr "Команда не выполнена" + +msgid "Connected" +msgstr "Подключен" + +msgid "Connection attempts" +msgstr "Попытки подключениÑ" + +msgid "Connection timeout" +msgstr "Таймаут ÑоединениÑ" + +msgid "Contents have been saved." +msgstr "Содержимое Ñохранено." + +msgid "Curl is not available..." +msgstr "Curl недоÑтупен..." + +msgid "Dead interval" +msgstr "Интервал при отключении" + +msgid "Dead period" +msgstr "Период поÑле отключениÑ" + +msgid "Debug" +msgstr "Отладка" + +msgid "Default port value for TCP connections." +msgstr "Стандартное значение порта Ð´Ð»Ñ TCP-подключений." + +msgid "Description" +msgstr "ОпиÑание" + +msgid "Device" +msgstr "УÑтройÑтво" + +msgid "Device will be rebooted when the Internet is disconnected." +msgstr "УÑтройÑтво будет перезагружено при отключении Интернет." + +msgid "Disable forced reboot" +msgstr "Отключить принудительную перезагрузку" + +msgid "Disabled" +msgstr "Отключен" + +msgid "Disabled: detector is completely off." +msgstr "Отключен: детектор полноÑтью выключен." + +msgid "Disconnected" +msgstr "Отключен" + +msgid "Dismiss" +msgstr "Закрыть" + +msgid "DNS query type" +msgstr "Тип DNS-запроÑа" + +msgid "Edit" +msgstr "Изменить" + +msgid "Edit down-script" +msgstr "Изменить down-script" + +msgid "Edit regular-script" +msgstr "Изменить regular-script" + +msgid "Edit public-ip-script" +msgstr "Изменить public-ip-script" + +msgid "Edit up-script" +msgstr "Изменить up-script" + +msgid "Email notification" +msgstr "Уведомление по email" + +msgid "Email address of the recipient." +msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ." + +msgid "Email address of the sender." +msgstr "Email-Ð°Ð´Ñ€ÐµÑ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÐµÐ»Ñ." + +msgid "Enable" +msgstr "Включить" + +msgid "Enable public-ip-script" +msgstr "Включить public-ip-script" + +msgid "Enabled" +msgstr "Включен" + +msgid "Error" +msgstr "Ошибка" + +msgid "Error!" +msgstr "Ошибка!" + +msgid "Expecting:" +msgstr "ОжидаетÑÑ:" + +msgid "Failed interval" +msgstr "Интервал при неудаче" + +msgid "Failed to get %s init status: %s" +msgstr "Ðе удалоÑÑŒ получить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ %s: %s" + +msgid "Forced reboot delay" +msgstr "Задержка принудительной перезагрузки" + +msgid "Host alias" +msgstr "ПÑевдоним хоÑта" + +msgid "Host availability check type." +msgstr "Тип проверки доÑтупноÑти хоÑта." + +msgid "Host identifier in messages. If not specified, hostname will be used." +msgstr "Идентификатор хоÑта в ÑообщениÑÑ…. ЕÑли не указан, будет иÑпользовано Ð¸Ð¼Ñ Ñ…Ð¾Ñта." + +msgid "Hostname/IP address of the SMTP server." +msgstr "Ð˜Ð¼Ñ Ñ…Ð¾Ñта/IP-Ð°Ð´Ñ€ÐµÑ SMTP-Ñервера." + +msgid "Hosts" +msgstr "ХоÑты" + +msgid "Hosts polling interval when the Internet is down." +msgstr "Интервал опроÑа хоÑтов еÑли Интернет недоÑтупен." + +msgid "Hosts polling interval when the Internet is up." +msgstr "Интервал опроÑа хоÑтов еÑли Интернет доÑтупен." + +msgid "" +"Hosts for checking Internet availability. Hosts are polled (in list " +"order) until at least one responds." +msgstr "" +"ХоÑты Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ доÑтупноÑти Интернет. ХоÑты опрашиваютÑÑ (в порÑдке " +"ÑпиÑка) до тех пор, пока Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один из них не ответит." + +msgid "Huge: 1492 bytes" +msgstr "Огромный: 1492 байта" + +msgid "ID of the Telegram chat to which messages will be sent." +msgstr "ID чата Telegram в который будут отправлены ÑообщениÑ." + +msgid "ICMP-echo request (ping)" +msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ ICMP-echo (ping)" + +msgid "ICMP packet data size" +msgstr "Размер данных ICMP-пакета" + +msgid "Incorrect bot token?" +msgstr "Ðеправильный токен бота?" + +msgid "Info" +msgstr "ИнформациÑ" + +msgid "Instances" +msgstr "ЭкземплÑры" + +msgid "Interface" +msgstr "ИнтерфейÑ" + +msgid "Interface timeout" +msgstr "Таймаут интерфейÑа" + +msgid "Internet" +msgstr "Интернет" + +msgid "Internet Detector" +msgstr "Интернет-детектор" + +msgid "Internet detector mode" +msgstr "Режим интернет-детектора" + +msgid "Internet status" +msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð˜Ð½Ñ‚ÐµÑ€Ð½ÐµÑ‚" + +msgid "Interval between IP address requests." +msgstr "Интервал между запроÑами IP адреÑа." + +msgid "Interval between IP address requests if the IP address is not defined." +msgstr "Интервал между запроÑами IP адреÑа, еÑли IP Ð°Ð´Ñ€ÐµÑ Ð½Ðµ определён." + +msgid "Interval between modem restarts." +msgstr "Интервал между перезапуÑками модема." + +msgid "Interval between network restarts." +msgstr "Интервал между перезапуÑками Ñети." + +msgid "Interval between down-script runs." +msgstr "Интервал между запуÑками down-script." + +msgid "Interval between up-script runs." +msgstr "Интервал между запуÑками up-script." + +msgid "Invalid instance name..." +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ ÑкземплÑра..." + +msgid "Jumbo: 9000 bytes" +msgstr "ГигантÑкий: 9000 байт" + +msgid "LED control" +msgstr "Управление LED" + +msgid "Link On" +msgstr "Подключение" + +msgid "Loading" +msgstr "Загрузка" + +msgid "Log event level." +msgstr "Уровень Ñобытий лога." + +msgid "Logging" +msgstr "ЗапиÑÑŒ Ñобытий в лог" + +msgid "Mailsend is not available..." +msgstr "Mailsend недоÑтупен..." + +msgid "Main settings" +msgstr "ОÑновные наÑтройки" + +msgid "Maximum number of attempts to connect to each host." +msgstr "МакÑимальное количеÑтво попыток Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº каждому хоÑту." + +msgid "" +"Maximum number of network restart attempts before Internet access is " +"available." +msgstr "" +"МакÑимальное количеÑтво попыток перезапуÑка Ñети до поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупа в " +"Интренет." + +msgid "" +"Maximum number of up-script run attempts when connected to the Internet." +msgstr "" +"МакÑимальное количеÑтво попыток запуÑка up-script при подключении к Интренет." + +msgid "" +"Maximum number of down-script run attempts before Internet access is available." +msgstr "" +"МакÑимальное количеÑтво попыток запуÑка down-script до поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупа в " +"Интренет." + +msgid "Maximum timeout for waiting for a response from the host." +msgstr "МакÑимальный таймаут Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð° от хоÑта." + +msgid "ModemManager is not available..." +msgstr "ModemManager недоÑтупен..." + +msgid "Modem will be restarted when the Internet is disconnected." +msgstr "Модем будет перезапущен при отключении Интернет." + +msgid "" +"ModemManger interface. If specified, it will be restarted after restarting " +"ModemManager." +msgstr "" +"Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ModemManager. ЕÑли задан, то будет перезапущен поÑле перезапуÑка " +"ModemManger." + +msgid "Network device activity (kernel: netdev)" +msgstr "ÐктивноÑть Ñетевого уÑтройÑтва (kernel: netdev)" + +msgid "" +"Network device for Internet access. If not specified, the default " +"device is used." +msgstr "" +"Сетевое уÑтройÑтво Ð´Ð»Ñ Ð´Ð¾Ñтупа в Интернет. ЕÑли не указано, иÑпользуетÑÑ " +"уÑтройÑтво по умолчанию." + +msgid "" +"Network device for sending messages. If not specified, the default " +"device is used." +msgstr "" +"Сетевое уÑтройÑтво Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ Ñообщений. ЕÑли не указано, иÑпользуетÑÑ " +"уÑтройÑтво по умолчанию." + +msgid "" +"Network device or interface to restart. If not specified, then the network service is restarted." +msgstr "" +"Сетевое уÑтройÑтво или Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑка. ЕÑли не задано, то будет перезапущена ÑÐµÑ‚ÐµÐ²Ð°Ñ " +"Ñлужба." + +msgid "Network will be restarted when the Internet is disconnected." +msgstr "Сеть будет перезапущена при отключении Интернет." + +msgid "Next run" +msgstr "Следующий запуÑк" + +msgid "No LEDs available..." +msgstr "Ðет доÑтупных LED..." + +msgid "No messages available. Write something to the bot and try again." +msgstr "Ðет доÑтупных Ñообщений. Ðапишите что-нибудь боту и попробуйте ещё раз." + +msgid "Not scheduled" +msgstr "Ðе запланирован" + +msgid "Notice" +msgstr "Сообщение" + +msgid "Number of attempts to request an IP address." +msgstr "КоличеÑтво попыток запроÑа IP адреÑа" + +msgid "Off" +msgstr "Выключить" + +msgid "Off-state delay" +msgstr "Задержка выключенного ÑоÑтоÑниÑ" + +msgid "Off-state delay for blinking option." +msgstr "Задержка выключенного ÑоÑтоÑÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿Ñ†Ð¸Ð¸ миганиÑ." + +msgid "On" +msgstr "Включить" + +msgid "On startup" +msgstr "При запуÑке" + +msgid "On-state delay" +msgstr "Задержка включённого ÑоÑтоÑниÑ" + +msgid "On-state delay for blinking option." +msgstr "Задержка включённого ÑоÑтоÑÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿Ñ†Ð¸Ð¸ миганиÑ." + +msgid "One of the following:" +msgstr "Одно из Ñледующих значений:" + +msgid "Password" +msgstr "Пароль" + +msgid "Password for SMTP authentication." +msgstr "Пароль Ð´Ð»Ñ SMTP-аутентификации." + +msgid "" +"Period of time after connecting to Internet before up-script runs." +msgstr "" +"Период времени поÑле Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Интернет перед запуÑком up-script." + +msgid "" +"Period of time after connecting to the Internet before sending a message." +msgstr "Период времени поÑле Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Интернет перед отправкой ÑообщениÑ." + +msgid "" +"Period of time after disconnecting from Internet before down-script runs." +msgstr "" +"Период времени поÑле Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚ Интернет перед запуÑком down-script." + +msgid "" +"Period of time after disconnecting from Internet before sending a message." +msgstr "Период времени отÑутÑÑ‚Ð²Ð¸Ñ Ð´Ð¾Ñтупа в Интренет перед отправкой ÑообщениÑ." + +msgid "Period of time without Internet access before modem restart." +msgstr "Период времени отÑутÑÑ‚Ð²Ð¸Ñ Ð´Ð¾Ñтупа в Интренет перед перезапуÑком модема." + +msgid "Period of time without Internet access before network restart." +msgstr "Период времени отÑутÑÑ‚Ð²Ð¸Ñ Ð´Ð¾Ñтупа в Интренет перед перезапуÑком Ñети." + +msgid "" +"Period of time without Internet access until the device is rebooted." +msgstr "" +"Период времени отÑутÑÑ‚Ð²Ð¸Ñ Ð´Ð¾Ñтупа в Интренет перед перезагрузкой уÑтройÑтва." + +msgid "Polling interval" +msgstr "Интервал опроÑа" + +msgid "Provider" +msgstr "Провайдер" + +msgid "Proxy" +msgstr "ПрокÑи" + +msgid "Proxy host" +msgstr "ХоÑÑ‚ прокÑи" + +msgid "Proxy password" +msgstr "Пароль прокÑи" + +msgid "Proxy port" +msgstr "Порт прокÑи" + +msgid "Proxy user" +msgstr "Пользователь прокÑи" + +msgid "Public IP" +msgstr "Публичный IP" + +msgid "Public IP address" +msgstr "Публичный IP адреÑ" + +msgid "Reboot device" +msgstr "Перезагрузка уÑтройÑтва" + +msgid "Reboot device if the Internet is disconnected at service startup." +msgstr "Перезагрузка уÑтройÑтва еÑли Интренет отключен при запуÑке Ñлужбы." + +msgid "Receive" +msgstr "Приём" + +msgid "Recipient" +msgstr "Получатель" + +msgid "Regular script" +msgstr "РегулÑрный Ñкрипт" + +msgid "Request chat ID from bot API" +msgstr "ЗапроÑить ID чата через API бота" + +msgid "Restart" +msgstr "ПерезапуÑк" + +msgid "Restart attempts" +msgstr "Попытки перезапуÑка" + +msgid "Restart modem" +msgstr "ПерезапуÑк модема" + +msgid "Restart modem if the Internet is disconnected at service startup." +msgstr "ПерезапуÑк модема еÑли Интренет отключен при запуÑке Ñлужбы." + +msgid "Restart network" +msgstr "ПерезапуÑк Ñети" + +msgid "Restart network if the Internet is disconnected at service startup." +msgstr "ПерезапуÑк Ñети еÑли Интренет отключен при запуÑке Ñлужбы." + +msgid "Restart service" +msgstr "ПерезапуÑк Ñлужбы" + +msgid "Device timeout" +msgstr "Таймаут уÑтройÑтва" + +msgid "Run interval" +msgstr "Интервал запуÑка" + +msgid "Run if Internet state is" +msgstr "ВыполнÑть еÑли ÑÑ‚Ð°Ñ‚ÑƒÑ Ð˜Ð½Ñ‚ÐµÑ€Ð½ÐµÑ‚" + +msgid "Run service at startup" +msgstr "ЗапуÑк Ñлужбы при Ñтарте" + +msgid "Run down-script if the Internet is disconnected at service startup." +msgstr "Выполнить down-script еÑли Интренет отключен при запуÑке Ñлужбы." + +msgid "Run up-script if the Internet is connected at service startup." +msgstr "Выполнить up-script еÑли Интренет подключен при запуÑке Ñлужбы." + +msgid "Running" +msgstr "ВыполнÑетÑÑ" + +msgid "SMTP server" +msgstr "SMTP-Ñервер" + +msgid "SMTP server port" +msgstr "Порт SMTP-Ñервера" + +msgid "SSL: SMTP over SSL." +msgstr "SSL: SMTP поверх SSL." + +msgid "Save" +msgstr "Сохранить" + +msgid "Security" +msgstr "БезопаÑноÑть" + +msgid "Send message on service startup." +msgstr "ОтправлÑть Ñообщение при запуÑке Ñлужбы." + +msgid "Sender" +msgstr "Отправитель" + +msgid "Server response timeout" +msgstr "Таймаут ответа Ñервера" + +msgid "Service" +msgstr "Служба" + +msgid "Service action failed \"%s %s\": %s" +msgstr "Ðе удалоÑÑŒ выполнить дейÑтвие Ñлужбы \"%s %s\": %s" + +msgid "Service configuration" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñлужбы" + +msgid "Service for determining the public IP address." +msgstr "Ð¡ÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ IP адреÑа." + +msgid "Service: detector always runs as a system service." +msgstr "Служба: детектор работает поÑтоÑнно, как ÑиÑÑ‚ÐµÐ¼Ð½Ð°Ñ Ñлужба." + +msgid "Set the modem to be allowed to use any band." +msgstr "Разрешить модему иÑпользование любой чаÑтоты." + +msgid "Shell commands that are run regularly." +msgstr "Команды shell выполнÑемые регулÑрно." + +msgid "Shell commands that run when connected to the Internet." +msgstr "Команды shell выполнÑемые при подключении к Интернет." + +msgid "Shell commands that run regularly at a specified interval. Current state of the Internet is available as value of the $INET_STATE variable (0 - connected, 1 - disconnected)." +msgstr "Команды shell выполнÑемые регулÑрно Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñ‹Ð¼ интервалом. Текущее ÑоÑтоÑние Интернет доÑтупно как значение переменной $INET_STATE (0 - подключен, 1 - отключен)." + +msgid "Shell commands that run when the public IP address changes. New IP is available as value of the $PUBLIC_IP variable (empty string if undefined)." +msgstr "Команды shell выполнÑемые при изменении публичного IP адреÑа. Ðовый IP доÑтупен как значение переменной $PUBLIC_IP (пуÑÑ‚Ð°Ñ Ñтрока еÑли не определён)." + +msgid "Shell commands to run when connected or disconnected from the Internet." +msgstr "Команды shell выполнÑемые при подключении или отключении Интернет." + +msgid "Shell commands to run when disconnected from the Internet." +msgstr "Команды shell выполнÑемые при отключении от Интернет." + +msgid "Small: 1 byte" +msgstr "Маленький: 1 байт" + +msgid "Standard: 56 bytes" +msgstr "Стандартный: 56 байт" + +msgid "Stopped" +msgstr "ОÑтановлена" + +msgid "TCP port" +msgstr "TCP-порт" + +msgid "TCP port connection" +msgstr "Подключение к TCP-порту" + +msgid "Telegram bot API token." +msgstr "API токен Telegram бота." + +msgid "Telegram message will be sent when connected or disconnected from the Internet." +msgstr "Сообщение в Telegram будет отправлено при подключении или отключении от Интернет." + +msgid "The type of record requested in the DNS query (if the service supports it)." +msgstr "Тип запиÑи запрашиваемой в DNS-запроÑе (еÑли ÑÐµÑ€Ð²Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÑ‚)." + +msgid "TLS: use STARTTLS if the server supports it." +msgstr "TLS: иÑпользовать STARTTLS еÑли Ñервер поддерживает." + +msgid "Timeout between stopping and starting a network device when restarting." +msgstr "Таймаут между оÑтановкой и запуÑком Ñетевого уÑтройÑтва при перезапуÑке." + +msgid "Timeout between stopping and starting a ModemManger interface when restarting." +msgstr "Таймаут между оÑтановкой и запуÑком интерфейÑа ModemManger при перезапуÑке." + +msgid "To support HTTP services, you need to install curl." +msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ HTTP ÑервиÑов необходимо уÑтановить curl." + +msgid "To support URL checking, you need to install curl." +msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ проверки URL необходимо уÑтановить curl." + +msgid "Transmit" +msgstr "Передача" + +msgid "Type a time string" +msgstr "Введите Ñтроку времени" + +msgid "Unable to read the contents" +msgstr "Ðевозможно прочитать Ñодержимое" + +msgid "Unable to save the contents" +msgstr "Ðевозможно Ñохранить Ñодержимое" + +msgid "Undefined" +msgstr "Ðеопределён" + +msgid "Unlock modem bands" +msgstr "ОÑвободить чаÑтоты модема" + +msgid "URL test (HTTP)" +msgstr "ТеÑÑ‚ URL (HTTP)" + +msgid "" +"URLs for checking Internet availability. URLs are polled (in list " +"order) until at least one returns HTTP status code 200." +msgstr "" +"URL Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ доÑтупноÑти Интернет. URL опрашиваютÑÑ (в порÑдке " +"ÑпиÑка) до тех пор, пока Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один из них не вернёт код ÑтатуÑа HTTP 200." + +msgid "User" +msgstr "Пользователь" + +msgid "User scripts" +msgstr "ПользовательÑкие Ñкрипты" + +msgid "Username for SMTP authentication." +msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ SMTP-аутентификации." + +msgid "Waiting for a reboot to complete before performing a forced reboot." +msgstr "" +"Ожидание Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ перед выполнением принудительной " +"перезагрузки." + +msgid "Warning" +msgstr "Внимание" + +msgid "Web UI only (UI detector)" +msgstr "Только web-Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ (UI детектор)" + +msgid "Web UI only: detector works only when the Web UI is open (UI detector)." +msgstr "" +"Только web-интерфейÑ: детектор работает только в web-интерфейÑе (UI " +"детектор)." + +msgid "When email will be sent" +msgstr "Когда будет отправлено Ñообщение" + +msgid "When message will be sent" +msgstr "Когда будет отправлено Ñообщение" + +msgid "Windows: 32 bytes" +msgstr "Windows: 32 байта" + +msgid "" +"You need to register a new %sTelegram bot%s. Then get the bot's API token and paste it into the Bot token field. After that, open a chat with the bot, write something (in the Telegram app) and you will be able to get the chat ID using the ID button." +msgstr "" +"Ðеобходимо зарегиÑтрировать новый %sTelegram бот%s. Затем получить API токен бота и вÑтавить его в поле Токен бота. ПоÑле Ñтого, откройте чат Ñ Ð±Ð¾Ñ‚Ð¾Ð¼, напишите что-нибудь (в приложении Telegram) и можно будет получить ID чата Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ кнопки ID." + +msgid "after connection" +msgstr "поÑле подключениÑ" + +msgid "after connection or disconnection" +msgstr "поÑле Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ отключениÑ" + +msgid "after disconnection" +msgstr "поÑле отключениÑ" + +msgid "connected" +msgstr "подключен" + +msgid "connected or disconnected" +msgstr "подключен или отключен" + +msgid "days" +msgstr "дни" + +msgid "disconnected" +msgstr "отключен" + +msgid "down-script" +msgstr "down-script" + +msgid "hour" +msgstr "чаÑ" + +msgid "infinitely" +msgstr "беÑконечно" + +msgid "hours" +msgstr "чаÑÑ‹" + +msgid "min" +msgstr "мин" + +msgid "minutes" +msgstr "минуты" + +msgid "msec" +msgstr "мÑек" + +msgid "sec" +msgstr "Ñек" + +msgid "seconds" +msgstr "Ñекунды" + +msgid "up-script" +msgstr "up-script" diff --git a/luci-app-internet-detector/po/templates/internet-detector.pot b/luci-app-internet-detector/po/templates/internet-detector.pot new file mode 100644 index 00000000..bd5822bf --- /dev/null +++ b/luci-app-internet-detector/po/templates/internet-detector.pot @@ -0,0 +1,706 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "LED Name" +msgstr "" + +msgid "LED control" +msgstr "" + +msgid "" +"LED indicates the Internet status." +msgstr "" + +msgid "LED mode" +msgstr "" + +msgid "" +"LED will display the link activity of this network device." +msgstr "" + +msgid "Add instance" +msgstr "" + +msgid "After connection" +msgstr "" + +msgid "After disconnection" +msgstr "" + +msgid "Alive interval" +msgstr "" + +msgid "Alive period" +msgstr "" + +msgid "An email will be sent when connected or disconnected from the Internet." +msgstr "" + +msgid "An error has occurred" +msgstr "" + +msgid "Attempt interval" +msgstr "" + +msgid "Attempts" +msgstr "" + +msgid "Big: 248 bytes" +msgstr "" + +msgid "Blinking (kernel: timer)" +msgstr "" + +msgid "Bot API token is missing!" +msgstr "" + +msgid "Bot token" +msgstr "" + +msgid "Chat ID" +msgstr "" + +msgid "Check type" +msgstr "" + +msgid "Checking Internet availability." +msgstr "" + +msgid "Checking the real public IP address." +msgstr "" + +msgid "Command failed" +msgstr "" + +msgid "Connected" +msgstr "" + +msgid "Connection attempts" +msgstr "" + +msgid "Connection timeout" +msgstr "" + +msgid "Contents have been saved." +msgstr "" + +msgid "Curl is not available..." +msgstr "" + +msgid "Dead interval" +msgstr "" + +msgid "Dead period" +msgstr "" + +msgid "Debug" +msgstr "" + +msgid "Default port value for TCP connections." +msgstr "" + +msgid "Description" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "Device will be rebooted when the Internet is disconnected." +msgstr "" + +msgid "Disable forced reboot" +msgstr "" + +msgid "Disabled" +msgstr "" + +msgid "Disabled: detector is completely off." +msgstr "" + +msgid "Disconnected" +msgstr "" + +msgid "Dismiss" +msgstr "" + +msgid "DNS query type" +msgstr "" + +msgid "Edit" +msgstr "" + +msgid "Edit down-script" +msgstr "" + +msgid "Edit regular-script" +msgstr "" + +msgid "Edit public-ip-script" +msgstr "" + +msgid "Edit up-script" +msgstr "" + +msgid "Email notification" +msgstr "" + +msgid "Email address of the recipient." +msgstr "" + +msgid "Email address of the sender." +msgstr "" + +msgid "Enable" +msgstr "" + +msgid "Enable public-ip-script" +msgstr "" + +msgid "Enabled" +msgstr "" + +msgid "Error" +msgstr "" + +msgid "Error!" +msgstr "" + +msgid "Expecting:" +msgstr "" + +msgid "Failed interval" +msgstr "" + +msgid "Failed to get %s init status: %s" +msgstr "" + +msgid "Forced reboot delay" +msgstr "" + +msgid "Host alias" +msgstr "" + +msgid "Host availability check type." +msgstr "" + +msgid "Host identifier in messages. If not specified, hostname will be used." +msgstr "" + +msgid "Hostname/IP address of the SMTP server." +msgstr "" + +msgid "Hosts" +msgstr "" + +msgid "Hosts polling interval when the Internet is down." +msgstr "" + +msgid "Hosts polling interval when the Internet is up." +msgstr "" + +msgid "" +"Hosts for checking Internet availability. Hosts are polled (in list " +"order) until at least one responds." +msgstr "" + +msgid "Huge: 1492 bytes" +msgstr "" + +msgid "ID of the Telegram chat to which messages will be sent." +msgstr "" + +msgid "ICMP-echo request (ping)" +msgstr "" + +msgid "ICMP packet data size" +msgstr "" + +msgid "Incorrect bot token?" +msgstr "" + +msgid "Info" +msgstr "" + +msgid "Instances" +msgstr "" + +msgid "Interface" +msgstr "" + +msgid "Interface timeout" +msgstr "" + +msgid "Internet" +msgstr "" + +msgid "Internet Detector" +msgstr "" + +msgid "Internet detector mode" +msgstr "" + +msgid "Internet status" +msgstr "" + +msgid "Interval between IP address requests." +msgstr "" + +msgid "Interval between IP address requests if the IP address is not defined." +msgstr "" + +msgid "Interval between modem restarts." +msgstr "" + +msgid "Interval between network restarts." +msgstr "" + +msgid "Interval between down-script runs." +msgstr "" + +msgid "Interval between up-script runs." +msgstr "" + +msgid "Invalid instance name..." +msgstr "" + +msgid "Jumbo: 9000 bytes" +msgstr "" + +msgid "LED control" +msgstr "" + +msgid "Link On" +msgstr "" + +msgid "Loading" +msgstr "" + +msgid "Log event level." +msgstr "" + +msgid "Logging" +msgstr "" + +msgid "Mailsend is not available..." +msgstr "" + +msgid "Main settings" +msgstr "" + +msgid "Maximum number of attempts to connect to each host." +msgstr "" + +msgid "" +"Maximum number of network restart attempts before Internet access is " +"available." +msgstr "" + +msgid "" +"Maximum number of up-script run attempts when connected to the Internet." +msgstr "" + +msgid "" +"Maximum number of down-script run attempts before Internet access is available." +msgstr "" + +msgid "Maximum timeout for waiting for a response from the host." +msgstr "" + +msgid "ModemManager is not available..." +msgstr "" + +msgid "Modem will be restarted when the Internet is disconnected." +msgstr "" + +msgid "" +"ModemManger interface. If specified, it will be restarted after restarting " +"ModemManager." +msgstr "" + +msgid "Network device activity (kernel: netdev)" +msgstr "" + +msgid "" +"Network device for Internet access. If not specified, the default " +"device is used." +msgstr "" + +msgid "" +"Network device for sending messages. If not specified, the default " +"device is used." +msgstr "" + +msgid "" +"Network device or interface to restart. If not specified, then the network service is restarted." +msgstr "" + +msgid "Network will be restarted when the Internet is disconnected." +msgstr "" + +msgid "Next run" +msgstr "" + +msgid "No LEDs available..." +msgstr "" + +msgid "No messages available. Write something to the bot and try again." +msgstr "" + +msgid "Not scheduled" +msgstr "" + +msgid "Notice" +msgstr "" + +msgid "Number of attempts to request an IP address." +msgstr "" + +msgid "Off" +msgstr "" + +msgid "Off-state delay" +msgstr "" + +msgid "Off-state delay for blinking option." +msgstr "" + +msgid "On" +msgstr "" + +msgid "On startup" +msgstr "" + +msgid "On-state delay" +msgstr "" + +msgid "On-state delay for blinking option." +msgstr "" + +msgid "One of the following:" +msgstr "" + +msgid "Password" +msgstr "" + +msgid "Password for SMTP authentication." +msgstr "" + +msgid "" +"Period of time after connecting to Internet before up-script runs." +msgstr "" + +msgid "" +"Period of time after connecting to the Internet before sending a message." +msgstr "" + +msgid "" +"Period of time after disconnecting from Internet before down-script runs." +msgstr "" + +msgid "" +"Period of time after disconnecting from Internet before sending a message." +msgstr "" + +msgid "Period of time without Internet access before modem restart." +msgstr "" + +msgid "Period of time without Internet access before network restart." +msgstr "" + +msgid "" +"Period of time without Internet access until the device is rebooted." +msgstr "" + +msgid "Polling interval" +msgstr "" + +msgid "Provider" +msgstr "" + +msgid "Proxy" +msgstr "" + +msgid "Proxy host" +msgstr "" + +msgid "Proxy password" +msgstr "" + +msgid "Proxy port" +msgstr "" + +msgid "Proxy user" +msgstr "" + +msgid "Public IP" +msgstr "" + +msgid "Public IP address" +msgstr "" + +msgid "Reboot device" +msgstr "" + +msgid "Reboot device if the Internet is disconnected at service startup." +msgstr "" + +msgid "Receive" +msgstr "" + +msgid "Recipient" +msgstr "" + +msgid "Regular script" +msgstr "" + +msgid "Request chat ID from bot API" +msgstr "" + +msgid "Restart" +msgstr "" + +msgid "Restart attempts" +msgstr "" + +msgid "Restart modem" +msgstr "" + +msgid "Restart modem if the Internet is disconnected at service startup." +msgstr "" + +msgid "Restart network" +msgstr "" + +msgid "Restart network if the Internet is disconnected at service startup." +msgstr "" + +msgid "Restart service" +msgstr "" + +msgid "Device timeout" +msgstr "" + +msgid "Run interval" +msgstr "" + +msgid "Run if Internet state is" +msgstr "" + +msgid "Run service at startup" +msgstr "" + +msgid "Run down-script if the Internet is disconnected at service startup." +msgstr "" + +msgid "Run up-script if the Internet is connected at service startup." +msgstr "" + +msgid "Running" +msgstr "" + +msgid "SMTP server" +msgstr "" + +msgid "SMTP server port" +msgstr "" + +msgid "SSL: SMTP over SSL." +msgstr "" + +msgid "Save" +msgstr "" + +msgid "Security" +msgstr "" + +msgid "Send message on service startup." +msgstr "" + +msgid "Sender" +msgstr "" + +msgid "Server response timeout" +msgstr "" + +msgid "Service" +msgstr "" + +msgid "Service action failed \"%s %s\": %s" +msgstr "" + +msgid "Service configuration" +msgstr "" + +msgid "Service for determining the public IP address." +msgstr "" + +msgid "Service: detector always runs as a system service." +msgstr "" + +msgid "Set the modem to be allowed to use any band." +msgstr "" + +msgid "Shell commands that are run regularly." +msgstr "" + +msgid "Shell commands that run when connected to the Internet." +msgstr "" + +msgid "Shell commands that run regularly at a specified interval. Current state of the Internet is available as value of the $INET_STATE variable (0 - connected, 1 - disconnected)." +msgstr "" + +msgid "Shell commands that run when the public IP address changes. New IP is available as value of the $PUBLIC_IP variable (empty string if undefined)." +msgstr "" + +msgid "Shell commands to run when connected or disconnected from the Internet." +msgstr "" + +msgid "Shell commands to run when disconnected from the Internet." +msgstr "" + +msgid "Small: 1 byte" +msgstr "" + +msgid "Standard: 56 bytes" +msgstr "" + +msgid "Stopped" +msgstr "" + +msgid "TCP port" +msgstr "" + +msgid "TCP port connection" +msgstr "" + +msgid "Telegram bot API token." +msgstr "" + +msgid "Telegram message will be sent when connected or disconnected from the Internet." +msgstr "" + +msgid "The type of record requested in the DNS query (if the service supports it)." +msgstr "" + +msgid "TLS: use STARTTLS if the server supports it." +msgstr "" + +msgid "Timeout between stopping and starting a network device when restarting." +msgstr "" + +msgid "Timeout between stopping and starting a ModemManger interface when restarting." +msgstr "" + +msgid "To support HTTP services, you need to install curl." +msgstr "" + +msgid "To support URL checking, you need to install curl." +msgstr "" + +msgid "Transmit" +msgstr "" + +msgid "Type a time string" +msgstr "" + +msgid "Unable to read the contents" +msgstr "" + +msgid "Unable to save the contents" +msgstr "" + +msgid "Undefined" +msgstr "" + +msgid "Unlock modem bands" +msgstr "" + +msgid "URL test (HTTP)" +msgstr "" + +msgid "" +"URLs for checking Internet availability. URLs are polled (in list " +"order) until at least one returns HTTP status code 200." +msgstr "" + +msgid "User" +msgstr "" + +msgid "User scripts" +msgstr "" + +msgid "Username for SMTP authentication." +msgstr "" + +msgid "Waiting for a reboot to complete before performing a forced reboot." +msgstr "" + +msgid "Warning" +msgstr "" + +msgid "Web UI only (UI detector)" +msgstr "" + +msgid "Web UI only: detector works only when the Web UI is open (UI detector)." +msgstr "" + +msgid "When email will be sent" +msgstr "" + +msgid "When message will be sent" +msgstr "" + +msgid "Windows: 32 bytes" +msgstr "" + +msgid "" +"You need to register a new %sTelegram bot%s. Then get the bot's API token and paste it into the Bot token field. After that, open a chat with the bot, write something (in the Telegram app) and you will be able to get the chat ID using the ID button." +msgstr "" + +msgid "after connection" +msgstr "" + +msgid "after disconnection" +msgstr "" + +msgid "connected" +msgstr "" + +msgid "connected or disconnected" +msgstr "" + +msgid "days" +msgstr "" + +msgid "disconnected" +msgstr "" + +msgid "down-script" +msgstr "" + +msgid "hour" +msgstr "" + +msgid "hours" +msgstr "" + +msgid "infinitely" +msgstr "" + +msgid "min" +msgstr "" + +msgid "minutes" +msgstr "" + +msgid "msec" +msgstr "" + +msgid "sec" +msgstr "" + +msgid "seconds" +msgstr "" + +msgid "up-script" +msgstr "" diff --git a/luci-app-internet-detector/root/usr/libexec/rpcd/luci.internet-detector b/luci-app-internet-detector/root/usr/libexec/rpcd/luci.internet-detector new file mode 100755 index 00000000..42da7acd --- /dev/null +++ b/luci-app-internet-detector/root/usr/libexec/rpcd/luci.internet-detector @@ -0,0 +1,97 @@ +#!/usr/bin/env lua + +local appName = "internet-detector" +local appExec = "/usr/bin/internet-detector" +local mailsendExec = "/usr/bin/mailsend" +local modemManagerInit = "/etc/init.d/modemmanager" +local curlExec = "/usr/bin/curl" + +local InternetDetector = require(appName .. ".main") +local uci = require("uci") +local unistd = require("posix.unistd") + +local function prequire(package) + local retVal, pkg = pcall(require, package) + return retVal and pkg +end + +local function init() + local lines = {} + if prequire(appName .. ".modules.mod_modem_restart") then + lines[#lines + 1] = '"mm_mod":true' + if (unistd.access(modemManagerInit, "x") and + os.execute(modemManagerInit .. " enabled") == 0) then + lines[#lines + 1] = '"mm_init":true' + else + lines[#lines + 1] = '"mm_init":false' + end + else + lines[#lines + 1] = '"mm_mod":false' + end + if prequire(appName .. ".modules.mod_email") then + lines[#lines + 1] = '"email_mod":true' + if unistd.access(mailsendExec, "x") then + lines[#lines + 1] = '"email_exec":true' + else + lines[#lines + 1] = '"email_exec":false' + end + else + lines[#lines + 1] = '"email_mod":false' + end + if prequire(appName .. ".modules.mod_telegram") then + lines[#lines + 1] = '"telegram":true' + else + lines[#lines + 1] = '"telegram":false' + end + if unistd.access(curlExec, "x") then + lines[#lines + 1] = '"curl_exec":true' + else + lines[#lines + 1] = '"curl_exec":false' + end + return string.format("{%s}", table.concat(lines, ",")) +end + +local function startUiInstances() + local uciCursor = uci.cursor() + local mode = tonumber(uciCursor:get(appName, "config", "mode")) + if mode == 2 then + uciCursor:foreach( + appName, + "instance", + function(s) + if s.enabled == "1" then + os.execute(string.format("%s -a daemon -i %s", appExec, s[".name"])) + end + end + ) + end +end + +local function uiPoll() + if InternetDetector:status() == "stoped" then + startUiInstances() + else + InternetDetector:setSIGUSR() + end + return InternetDetector:inetStatus() +end + +local function list() + io.write('{"Init":{},"Status":{},"InetStatus":{},"UIPoll":{}}') +end + +if arg[1] == "list" then + list() +elseif arg[1] == "call" then + if arg[2] == "Init" then + io.write(init()) + elseif arg[2] == "Status" then + io.write(string.format('{"status":"%s"}', tostring(InternetDetector:status()))) + elseif arg[2] == "InetStatus" then + io.write(InternetDetector:inetStatus()) + elseif arg[2] == "UIPoll" then + io.write(uiPoll()) + end +end + +os.exit(0) diff --git a/luci-app-internet-detector/root/usr/share/luci/menu.d/luci-app-internet-detector.json b/luci-app-internet-detector/root/usr/share/luci/menu.d/luci-app-internet-detector.json new file mode 100644 index 00000000..2299a2c0 --- /dev/null +++ b/luci-app-internet-detector/root/usr/share/luci/menu.d/luci-app-internet-detector.json @@ -0,0 +1,17 @@ +{ + "admin/services/internet-detector": { + "title": "Internet Detector", + "order": 80, + "action": { + "type": "view", + "path": "internet-detector" + }, + "depends": { + "acl": [ "luci-app-internet-detector" ], + "fs": { + "/usr/bin/internet-detector": "executable" + }, + "uci": { "internet-detector": true } + } + } +} diff --git a/luci-app-internet-detector/root/usr/share/rpcd/acl.d/luci-app-internet-detector.json b/luci-app-internet-detector/root/usr/share/rpcd/acl.d/luci-app-internet-detector.json new file mode 100644 index 00000000..0f9e8de0 --- /dev/null +++ b/luci-app-internet-detector/root/usr/share/rpcd/acl.d/luci-app-internet-detector.json @@ -0,0 +1,28 @@ +{ + "luci-app-internet-detector": { + "description": "Grant access to internet-detector procedures", + "read": { + "file": { + "/sys/class/leds": [ "list" ], + "/etc/internet-detector/up-script*": [ "read" ], + "/etc/internet-detector/down-script*": [ "read" ], + "/etc/internet-detector/public-ip-script*": [ "read" ], + "/etc/internet-detector/regular-script*": [ "read" ] + }, + "uci": [ "internet-detector" ], + "ubus": { + "luci": [ "getInitList", "setInitAction" ], + "luci.internet-detector": [ "Init", "Status", "InetStatus", "UIPoll" ] + } + }, + "write": { + "file": { + "/etc/internet-detector/up-script*": [ "write" ], + "/etc/internet-detector/down-script*": [ "write" ], + "/etc/internet-detector/public-ip-script*": [ "write" ], + "/etc/internet-detector/regular-script*": [ "write" ] + }, + "uci": [ "internet-detector" ] + } + } +} diff --git a/luci-app-log/LICENSE b/luci-app-log/LICENSE new file mode 100644 index 00000000..4c903101 --- /dev/null +++ b/luci-app-log/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 gSpotx2f + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/luci-app-log/Makefile b/luci-app-log/Makefile new file mode 100644 index 00000000..929cef98 --- /dev/null +++ b/luci-app-log/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) 2025 gSpot (https://github.com/gSpotx2f/luci-app-log) +# +# This is free software, licensed under the MIT License. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-log-viewer +PKG_VERSION:=1.5.0 +PKG_RELEASE:=2 +LUCI_TITLE:=Advanced syslog and kernel log (tail, search, etc) +LUCI_DEPENDS:=+ucode +ucode-mod-fs +LUCI_PKGARCH:=all +#LUCI_PKGARCH:=noarch +PKG_LICENSE:=MIT + +#include ../../luci.mk +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-log/README.md b/luci-app-log/README.md new file mode 100644 index 00000000..f8644dd6 --- /dev/null +++ b/luci-app-log/README.md @@ -0,0 +1,66 @@ +# luci-app-log-viewer +Advanced syslog and kernel log (tail, search, etc) for LuCI (OpenWrt webUI). + +OpenWrt >= 22.03. + +Supported LuCI themes: luci-theme-bootstrap, luci-theme-material, luci-theme-openwrt-2020. + +**Dependences:** ucode, ucode-mod-fs. + +## Installation notes + +**OpenWrt >= 25.12:** + + wget --no-check-certificate -O /tmp/luci-app-log-viewer-1.5.0-r2.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-log-viewer-1.5.0-r2.apk + apk --allow-untrusted add /tmp/luci-app-log-viewer-1.5.0-r2.apk + rm /tmp/luci-app-log-viewer-1.5.0-r2.apk + service rpcd restart + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-log-viewer-ru-1.5.0-r2.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-log-viewer-ru-1.5.0-r2.apk + apk --allow-untrusted add /tmp/luci-i18n-log-viewer-ru-1.5.0-r2.apk + rm /tmp/luci-i18n-log-viewer-ru-1.5.0-r2.apk + +**OpenWrt <= 24.10:** + + wget --no-check-certificate -O /tmp/luci-app-log-viewer_1.5.0-r2_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-log-viewer_1.5.0-r2_all.ipk + opkg install /tmp/luci-app-log-viewer_1.5.0-r2_all.ipk + rm /tmp/luci-app-log-viewer_1.5.0-r2_all.ipk + service rpcd restart + +i18n-ru: + + wget --no-check-certificate -O /tmp/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk + opkg install /tmp/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk + rm /tmp/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk + +## Screenshots: + +Kernel log: + +![](https://github.com/gSpotx2f/luci-app-log/blob/master/screenshots/01.jpg) + +System log (logd): + +![](https://github.com/gSpotx2f/luci-app-log/blob/master/screenshots/02.jpg) + +Filter settings: + +![](https://github.com/gSpotx2f/luci-app-log/blob/master/screenshots/03.jpg) + +System log (syslog-ng): + +![](https://github.com/gSpotx2f/luci-app-log/blob/master/screenshots/04.jpg) + +## Mod lines: + + wget --no-check-certificate -O /www/luci-static/resources/view/log-viewer/log-widget.js https://github.com/gSpotx2f/luci-app-log/raw/master/dev-mods-examples/mod-lines/htdocs/luci-static/resources/view/log-viewer/log-widget.js + +![](https://github.com/gSpotx2f/luci-app-log/blob/master/dev-mods-examples/mod-lines/screenshots/01.jpg) + +## Mod textarea: + + wget --no-check-certificate -O /www/luci-static/resources/view/log-viewer/log-widget.js https://github.com/gSpotx2f/luci-app-log/raw/master/dev-mods-examples/mod-textarea/htdocs/luci-static/resources/view/log-viewer/log-widget.js + +![](https://github.com/gSpotx2f/luci-app-log/blob/master/dev-mods-examples/mod-textarea/screenshots/01.jpg) diff --git a/luci-app-log/dev-mods-examples/mod-app-example/htdocs/luci-static/resources/view/log-viewer/dropbear.js b/luci-app-log/dev-mods-examples/mod-app-example/htdocs/luci-static/resources/view/log-viewer/dropbear.js new file mode 100644 index 00000000..c16a37ee --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-app-example/htdocs/luci-static/resources/view/log-viewer/dropbear.js @@ -0,0 +1,9 @@ +'use strict'; +'require view.log-viewer.log-system as abc'; + +return abc.view.extend({ + viewName : 'dropbear', + title : _('Dropbear'), + enableAutoRefresh: false, + appPattern : 'dropbear\[[0-9]*\]:', +}); diff --git a/luci-app-log/dev-mods-examples/mod-app-example/root/usr/share/luci/menu.d/luci-app-log-viewer-dropbear.json b/luci-app-log/dev-mods-examples/mod-app-example/root/usr/share/luci/menu.d/luci-app-log-viewer-dropbear.json new file mode 100644 index 00000000..87386d8a --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-app-example/root/usr/share/luci/menu.d/luci-app-log-viewer-dropbear.json @@ -0,0 +1,10 @@ +{ + "admin/status/log-viewer/dropbear": { + "title": "Dropbear", + "order": 3, + "action": { + "type": "view", + "path": "log-viewer/dropbear" + } + } +} diff --git a/luci-app-log/dev-mods-examples/mod-lines/htdocs/luci-static/resources/view/log-viewer/log-widget.js b/luci-app-log/dev-mods-examples/mod-lines/htdocs/luci-static/resources/view/log-viewer/log-widget.js new file mode 100644 index 00000000..724ffdf4 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-lines/htdocs/luci-static/resources/view/log-viewer/log-widget.js @@ -0,0 +1,113 @@ +'use strict'; +'require baseclass'; +'require ui'; +'require view.log-viewer.log-base as base'; + +document.head.append(E('style', {'type': 'text/css'}, +` +:root { + --app-log-entry-outline-color: #ccc; +} +:root[data-darkmode="true"] { + --app-log-entry-outline-color: #555; +} +#log-area { + width: 100%; + height: 100%; + margin-bottom: 1em; +} +.log-entry-line { + display: inline-block; + text-indent: 8px; + margin: 0 0 1px 0; + padding: 0 4px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + border: 1px solid var(--app-log-entry-outline-color); + font-weight: normal; + /*font-size: 12px !important;*/ + font-family: monospace !important; + white-space: pre-wrap !important; + overflow-wrap: anywhere !important; +} +`)); + +return baseclass.extend({ + view: base.view.extend({ + + filterHighlightFunc(match) { + return `${match}`; + }, + + padNumber(number, lengthFirst, lengthLast) { + let length = Math.max(lengthFirst, lengthLast); + try { + number = String(number).padStart(length, ' '); + } catch(e) { + if(e.name != 'TypeError') { + throw e; + }; + }; + return number; + }, + + makeLogArea(logdataArray) { + let lines = `${_('No entries available...')}`; + let logArea = E('div', { 'id': 'log-area' }); + + for(let level of Object.keys(this.logLevels)) { + this.logLevelsStat[level] = 0; + }; + + let logdataArrayLen = logdataArray.length; + + if(logdataArray.length > 0) { + lines = []; + let firstNumLength = String(logdataArray[0][0]).length; + let lastNumLength = String(logdataArray[logdataArrayLen - 1][0]).length; + logdataArray.forEach((e, i) => { + if(e[4] in this.logLevels) { + this.logLevelsStat[e[4]] = this.logLevelsStat[e[4]] + 1; + }; + e[0] = this.padNumber(e[0], firstNumLength, lastNumLength); + if(e[5]) { + e[5] = ` ${e[5]}`; + }; + lines.push( + `` + + e.filter(i => (i)).join(' ') + + '' + ); + }); + lines = lines.join('
'); + }; + + try { + logArea.insertAdjacentHTML('beforeend', lines); + } catch(err) { + if(err.name == 'SyntaxError') { + ui.addNotification(null, + E('p', {}, _('HTML/XML error') + ': ' + err.message), 'error'); + }; + throw err; + }; + + let levelsStatString = ''; + if((Object.values(this.logLevelsStat).reduce((s,c) => s + c, 0)) > 0) { + Object.entries(this.logLevelsStat).forEach(e => { + if(e[0] in this.logLevels && e[1] > 0) { + levelsStatString += `${e[1]}`; + }; + }); + }; + + return E([ + E('div', { 'class': 'log-entries-count' }, + `${_('Entries')}: ${logdataArray.length} / ${this.totalLogLines}${levelsStatString}` + ), + logArea, + ]); + }, + }), +}); diff --git a/luci-app-log/dev-mods-examples/mod-lines/screenshots/01.jpg b/luci-app-log/dev-mods-examples/mod-lines/screenshots/01.jpg new file mode 100644 index 00000000..13b3cc4a Binary files /dev/null and b/luci-app-log/dev-mods-examples/mod-lines/screenshots/01.jpg differ diff --git a/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/boot.js b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/boot.js new file mode 100644 index 00000000..51ec8259 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/boot.js @@ -0,0 +1,9 @@ +'use strict'; +'require view.log-viewer.multilog.log-multilog as abc'; + +return abc.view.extend({ + viewName : 'multilog-boot', + title : _('Log') + ' - ' + _('boot.log'), + autoRefresh: false, + logFile : '/var/log/boot.log', +}); diff --git a/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/cron.js b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/cron.js new file mode 100644 index 00000000..88e807f6 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/cron.js @@ -0,0 +1,9 @@ +'use strict'; +'require view.log-viewer.multilog.log-multilog as abc'; + +return abc.view.extend({ + viewName : 'multilog-cron', + title : _('Log') + ' - ' + _('cron'), + autoRefresh: false, + logFile : '/var/log/cron', +}); diff --git a/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/log-multilog.js b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/log-multilog.js new file mode 100644 index 00000000..2dd8112f --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/log-multilog.js @@ -0,0 +1,25 @@ +'use strict'; +'require baseclass'; +'require fs'; +'require view.log-viewer.log-system as abc'; + +return baseclass.extend({ + view: abc.view.extend({ + /** + * Log file. + * + * @property {string} logFile + */ + logFile: null, + + getLogHash() { + return fs.stat(this.logFile).then((data) => { + return data.mtime || ''; + }).catch(e => {}); + }, + + getLogData(tail) { + return L.resolveDefault(fs.read_direct(this.logFile, 'text'), ''); + }, + }), +}); diff --git a/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/maillog.js b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/maillog.js new file mode 100644 index 00000000..f2bf9481 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/maillog.js @@ -0,0 +1,9 @@ +'use strict'; +'require view.log-viewer.multilog.log-multilog as abc'; + +return abc.view.extend({ + viewName : 'multilog-maillog', + title : _('Log') + ' - ' + _('maillog'), + autoRefresh: false, + logFile : '/var/log/maillog', +}); diff --git a/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/messages.js b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/messages.js new file mode 100644 index 00000000..49f24090 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/messages.js @@ -0,0 +1,9 @@ +'use strict'; +'require view.log-viewer.multilog.log-multilog as abc'; + +return abc.view.extend({ + viewName : 'multilog-messages', + title : _('Log') + ' - ' + _('messages'), + autoRefresh: true, + logFile : '/var/log/messages', +}); diff --git a/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/secure.js b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/secure.js new file mode 100644 index 00000000..7795cdb5 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/htdocs/luci-static/resources/view/log-viewer/multilog/secure.js @@ -0,0 +1,9 @@ +'use strict'; +'require view.log-viewer.multilog.log-multilog as abc'; + +return abc.view.extend({ + viewName : 'multilog-secure', + title : _('Log') + ' - ' + _('secure'), + autoRefresh: false, + logFile : '/var/log/secure', +}); diff --git a/luci-app-log/dev-mods-examples/mod-multilog/root/usr/share/luci/menu.d/luci-app-log-viewer.json b/luci-app-log/dev-mods-examples/mod-multilog/root/usr/share/luci/menu.d/luci-app-log-viewer.json new file mode 100644 index 00000000..b2c28efb --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/root/usr/share/luci/menu.d/luci-app-log-viewer.json @@ -0,0 +1,67 @@ +{ + "admin/status/log-viewer": { + "title": "Log Viewer", + "order": 5, + "action": { + "type": "alias", + "path": "admin/status/log-viewer/messages" + }, + "depends": { + "acl": [ "luci-app-log-viewer" ] + } + }, + + "admin/status/log-viewer/messages": { + "title": "messages", + "order": 1, + "action": { + "type": "view", + "path": "log-viewer/multilog/messages" + } + }, + + "admin/status/log-viewer/secure": { + "title": "secure", + "order": 2, + "action": { + "type": "view", + "path": "log-viewer/multilog/secure" + } + }, + + "admin/status/log-viewer/maillog": { + "title": "maillog", + "order": 3, + "action": { + "type": "view", + "path": "log-viewer/multilog/maillog" + } + }, + + "admin/status/log-viewer/cron": { + "title": "cron", + "order": 4, + "action": { + "type": "view", + "path": "log-viewer/multilog/cron" + } + }, + + "admin/status/log-viewer/boot": { + "title": "boot", + "order": 5, + "action": { + "type": "view", + "path": "log-viewer/multilog/boot" + } + }, + + "admin/status/log-viewer/dmesg": { + "title": "kernel", + "order": 6, + "action": { + "type": "view", + "path": "log-viewer/dmesg" + } + } +} diff --git a/luci-app-log/dev-mods-examples/mod-multilog/root/usr/share/rpcd/acl.d/luci-app-log-viewer.json b/luci-app-log/dev-mods-examples/mod-multilog/root/usr/share/rpcd/acl.d/luci-app-log-viewer.json new file mode 100644 index 00000000..619026f4 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-multilog/root/usr/share/rpcd/acl.d/luci-app-log-viewer.json @@ -0,0 +1,22 @@ +{ + "luci-app-log-viewer": { + "description": "Grant access to log-viewer procedures", + "read": { + "cgi-io": [ "exec" ], + "file": { + "/sbin/logread*": [ "exec" ], + "/usr/sbin/logread*": [ "exec" ], + "/bin/dmesg -r": [ "exec" ], + "/var/log/messages": [ "read" ], + "/var/log/secure": [ "read" ], + "/var/log/maillog": [ "read" ], + "/var/log/cron": [ "read" ], + "/var/log/boot.log": [ "read" ] + }, + "ubus": { + "system": [ "info" ], + "luci.log-viewer": [ "getSyslogSize", "getSyslogHash", "getDmesgSize", "getDmesgHash", "getLogfileSize" ] + } + } + } +} diff --git a/luci-app-log/dev-mods-examples/mod-multilog/screenshots/01.jpg b/luci-app-log/dev-mods-examples/mod-multilog/screenshots/01.jpg new file mode 100644 index 00000000..adf90162 Binary files /dev/null and b/luci-app-log/dev-mods-examples/mod-multilog/screenshots/01.jpg differ diff --git a/luci-app-log/dev-mods-examples/mod-textarea/htdocs/luci-static/resources/view/log-viewer/log-widget.js b/luci-app-log/dev-mods-examples/mod-textarea/htdocs/luci-static/resources/view/log-viewer/log-widget.js new file mode 100644 index 00000000..3b802d43 --- /dev/null +++ b/luci-app-log/dev-mods-examples/mod-textarea/htdocs/luci-static/resources/view/log-viewer/log-widget.js @@ -0,0 +1,85 @@ +'use strict'; +'require baseclass'; +'require ui'; +'require view.log-viewer.log-base as base'; + +return baseclass.extend({ + view: base.view.extend({ + rowsDefault: 20, + + htmlEntities(str) { + return str; + }, + + filterHighlightFunc(match) { + return `â–º${match}â—„`; + }, + + padNumber(number, lengthFirst, lengthLast) { + let length = Math.max(lengthFirst, lengthLast); + try { + number = String(number).padStart(length, ' '); + } catch(e) { + if(e.name != 'TypeError') { + throw e; + }; + }; + return number; + }, + + makeLogArea(logdataArray) { + let lines = _('No entries available...'); + let logTextarea = E('textarea', { + 'id' : 'syslog', + 'class' : 'cbi-input-textarea', + 'style' : 'width:100% !important; margin-bottom:1em; resize:none; font-size:12px; font-family:monospace !important', + 'readonly' : 'readonly', + 'wrap' : 'off', + 'rows' : this.rowsDefault, + 'spellcheck': 'false', + }); + + for(let level of Object.keys(this.logLevels)) { + this.logLevelsStat[level] = 0; + }; + + let logdataArrayLen = logdataArray.length; + + if(logdataArrayLen > 0) { + lines = []; + let firstNumLength = String(logdataArray[0][0]).length; + let lastNumLength = String(logdataArray[logdataArrayLen - 1][0]).length; + logdataArray.forEach((e, i) => { + if(e[4] in this.logLevels) { + this.logLevelsStat[e[4]] = this.logLevelsStat[e[4]] + 1; + }; + e[0] = this.padNumber(e[0], firstNumLength, lastNumLength); + if(e[5]) { + e[5] = `\t${e[5]}`; + }; + lines.push(e.filter(i => (i)).join(' ')); + }); + lines = lines.join('\r\n'); + }; + + logTextarea.value = lines; + logTextarea.rows = ((logdataArrayLen + 1) < this.rowsDefault) ? this.rowsDefault : logdataArrayLen + 1; + + let levelsStatString = ''; + if((Object.values(this.logLevelsStat).reduce((s,c) => s + c, 0)) > 0) { + Object.entries(this.logLevelsStat).forEach(e => { + if(e[0] in this.logLevels && e[1] > 0) { + levelsStatString += `${e[1]}`; + }; + }); + }; + + return E([ + E('div', { 'class': 'log-entries-count' }, + `${_('Entries')}: ${logdataArrayLen} / ${this.totalLogLines}${levelsStatString}` + ), + logTextarea, + ]); + }, + }), +}); diff --git a/luci-app-log/dev-mods-examples/mod-textarea/screenshots/01.jpg b/luci-app-log/dev-mods-examples/mod-textarea/screenshots/01.jpg new file mode 100644 index 00000000..c34e0eeb Binary files /dev/null and b/luci-app-log/dev-mods-examples/mod-textarea/screenshots/01.jpg differ diff --git a/luci-app-log/htdocs/luci-static/resources/view/log-viewer/dmesg.js b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/dmesg.js new file mode 100644 index 00000000..13a5035f --- /dev/null +++ b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/dmesg.js @@ -0,0 +1,168 @@ +'use strict'; +'require fs'; +'require rpc'; +'require ui'; +'require view.log-viewer.log-widget as widget'; + +return widget.view.extend({ + viewName : 'dmesg', + + title : _('Kernel Log'), + + enableAutoRefresh : true, + + enableConvertTimestamp: true, + + entryRegexp : new RegExp(/^<(\d{1,2})>\[([\d\s.]+)\]\s+(.*)$/), + + entriesHandler : null, + + facilityName : [ + 'kern', + 'user', + 'mail', + 'daemon', + 'auth', + 'syslog', + 'lpr', + 'news', + ], + + localtime : null, + + uptime : null, + + days : { + 0: 'Sun', + 1: 'Mon', + 2: 'Tue', + 3: 'Wed', + 4: 'Thu', + 5: 'Fri', + 6: 'Sat', + 7: 'Sun', + }, + + months : { + 1: 'Jan', + 2: 'Feb', + 3: 'Mar', + 4: 'Apr', + 5: 'May', + 6: 'Jun', + 7: 'Jul', + 8: 'Aug', + 9: 'Sep', + 10: 'Oct', + 11: 'Nov', + 12: 'Dec', + }, + + logCols : [ + '#', + _('Timestamp'), + null, + _('Facility'), + _('Level'), + _('Message'), + ], + + callLogHash : rpc.declare({ + object: 'luci.log-viewer', + method: 'getDmesgHash', + expect: { '': {} } + }), + + callSystemInfo : rpc.declare({ + object: 'system', + method: 'info' + }), + + getLogHash() { + return this.callLogHash().then(data => { + return data.hash || ''; + }); + }, + + convertTimestampFunc(t) { + if(!this.convertTimestampValue || !this.localtime || !this.uptime) { + return t; + }; + let date = new Date((this.localtime - this.uptime + Math.round(Number(t))) * 1000); + return '%s %s %2d %02d:%02d:%02d %d'.format( + this.days[ date.getUTCDay() ], + this.months[ date.getUTCMonth() + 1 ], + date.getUTCDate(), + date.getUTCHours(), + date.getUTCMinutes(), + date.getUTCSeconds(), + date.getUTCFullYear() + ); + }, + + async getLogData(tail) { + await this.callSystemInfo().then(s => { + this.localtime = s.localtime; + this.uptime = s.uptime; + }).catch(err => {}); + return fs.exec_direct('/bin/dmesg', [ '-r' ], 'text').catch(err => { + throw new Error(_('Unable to load log data:') + ' ' + err.message); + }); + }, + + parseLogData(logdata, tail) { + if(!logdata) { + return []; + }; + + let unsupportedLog = false; + this.logTimestampFlag = true; + this.logFacilitiesFlag = true; + this.logLevelsFlag = true; + this.logHostsFlag = false; + + let strings = logdata.trim().split(/\n/); + + if(tail && tail > 0 && strings) { + strings = strings.slice(-tail); + }; + + this.totalLogLines = strings.length; + + let entriesArray = strings.map((e, i) => { + let logLevelsTranslate = Object.keys(this.logLevels); + let strArray = e.match(this.entryRegexp); + if(strArray) { + let level = 0; + let facility = 0; + if(strArray[1].length > 1) { + let fieldArray = Number(strArray[1]).toString(8).split(''); + level = logLevelsTranslate[Number(fieldArray[1])]; + facility = Number(fieldArray[0]); + } else { + level = logLevelsTranslate[Number(strArray[1]).toString(8)]; + }; + return [ + i + 1, // # (Number) + this.convertTimestampFunc(strArray[2].trim()), // Timestamp (String) + null, // Host (String) + this.facilityName[ facility ], // Facility (String) + level, // Level (String) + this.htmlEntities(strArray[3]) || ' ', // Message (String) + ]; + } else { + unsupportedLog = true; + return; + }; + }); + + if(unsupportedLog) { + throw new Error(_('Unable to load log data:') + ' ' + _('Unsupported log format')); + } else { + if(this.logSortingValue == 'desc') { + entriesArray.reverse(); + }; + return entriesArray; + }; + }, +}); diff --git a/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-base.js b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-base.js new file mode 100644 index 00000000..365dacf9 --- /dev/null +++ b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-base.js @@ -0,0 +1,1338 @@ +'use strict'; +'require poll'; +'require baseclass'; +'require ui'; +'require view'; + +document.head.append(E('style', {'type': 'text/css'}, +` +:root { + --app-log-dark-font-color: #2e2e2e; + --app-log-light-font-color: #fff; + --app-log-debug-font-color: #737373; + --app-log-raw-font-color: #737373; + --app-log-emerg-color: #a93734; + --app-log-alert: #ff7968; + --app-log-crit: #fcc3bf; + --app-log-err: #ffe9e8; + --app-log-warn: #fff7e2; + --app-log-notice: #e3ffec; + --app-log-info: rgba(0,0,0,0); + --app-log-debug: #ebf6ff; + --app-log-raw: #eee; + --app-log-entries-count-border: #ccc; +} +:root[data-darkmode="true"] { + --app-log-dark-font-color: #fff; + --app-log-light-font-color: #fff; + --app-log-debug-font-color: #e7e7e7; + --app-log-raw-font-color: #aaa; + --app-log-emerg-color: #960909; + --app-log-alert: #eb5050; + --app-log-crit: #dc7f79; + --app-log-err: #9a5954; + --app-log-warn: #8d7000; + --app-log-notice: #007627; + --app-log-info: rgba(0,0,0,0); + --app-log-debug: #5986b1; + --app-log-raw: #353535; + --app-log-entries-count-border: #555; +} +#logWrapper { + overflow: auto !important; + width: 100%; + min-height: 20em'; +} +.log-empty { +} +.log-emerg { + background-color: var(--app-log-emerg-color) !important; + color: var(--app-log-light-font-color); +} +log-emerg .td { + color: var(--app-log-light-font-color) !important; +} +log-emerg td { + color: var(--app-log-light-font-color) !important; +} +.log-alert { + background-color: var(--app-log-alert) !important; + color: var(--app-log-light-font-color); +} +.log-alert .td { + color: var(--app-log-light-font-color) !important; +} +.log-alert td { + color: var(--app-log-light-font-color) !important; +} +.log-crit { + background-color: var(--app-log-crit) !important; + color: var(--app-log-dark-font-color) !important; +} +.log-crit .td { + color: var(--app-log-dark-font-color) !important; +} +.log-crit td { + color: var(--app-log-dark-font-color) !important; +} +.log-err { + background-color: var(--app-log-err) !important; + color: var(--app-log-dark-font-color) !important; +} +.log-err .td { + color: var(--app-log-dark-font-color) !important; +} +.log-err td { + color: var(--app-log-dark-font-color) !important; +} +.log-warn { + background-color: var(--app-log-warn) !important; + color: var(--app-log-dark-font-color) !important; +} +.log-warn .td { + color: var(--app-log-dark-font-color) !important; +} +.log-warn td { + color: var(--app-log-dark-font-color) !important; +} +.log-notice { + background-color: var(--app-log-notice) !important; + color: var(--app-log-dark-font-color) !important; +} +.log-notice .td { + color: var(--app-log-dark-font-color) !important; +} +.log-notice td { + color: var(--app-log-dark-font-color) !important; +} +.log-info { + background-color: var(--app-log-info) !important; + /*color: var(--app-log-dark-font-color) !important;*/ +} +.log-debug { + background-color: var(--app-log-debug) !important; + color: var(--app-log-debug-font-color) !important; +} +.log-debug .td { + color: var(--app-log-debug-font-color) !important; +} +.log-debug td { + color: var(--app-log-debug-font-color) !important; +} +.log-raw { + background-color: var(--app-log-raw) !important; + color: var(--app-log-raw-font-color) !important; +} +.log-raw .td { + color: var(--app-log-raw-font-color) !important; +} +.log-raw td { + color: var(--app-log-raw-font-color) !important; +} +.log-highlight-item { + background-color: #ffef00; + color: #2e2e2e; +} +.log-entries-count { + margin: 0 0 5px 5px; + font-weight: bold; + opacity: 0.7; +} +.log-entries-count-level { + display: inline-block !important; + margin: 0 0 0 5px; + padding: 0 4px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + border: 1px solid var(--app-log-entries-count-border); + font-weight: normal; +} +.log-host-dropdown-item { +} +.log-facility-dropdown-item { +} +#moreEntriesBar { + opacity: 0.7; +} +#moreEntriesBar > button { + margin: 1em 0 1em 0 !important; + min-width: 100%; +} +.log-side-block { + position: fixed; + z-index: 200 !important; + opacity: 0.7; + right: 1px; + top: 40vh; +} +.log-side-btn { + position: relative; + display: block; + left: 1px; + top: 1px; + margin: 0 !important; + min-width: 3.2em; +} +`)); + +return baseclass.extend({ + view: view.extend({ + /** + * View name (for local storage and downloads). + * + * @property {string} viewName + */ + viewName : null, + + /** + * Page title. + * + * @property {string} title + */ + title : null, + + /** + * Enable auto refresh log. + * + * @property {bool} enableAutoRefresh + */ + enableAutoRefresh : false, + + /** + * Enable timestamp conversion. + * + * @property {bool} enableConvertTimestamp + */ + enableConvertTimestamp: false, + + pollInterval : L.env.pollinterval, + + logFacilities : { + 'kern' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'kern')), + 'user' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'user')), + 'mail' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'mail')), + 'daemon' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'daemon')), + 'auth' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'auth')), + 'syslog' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'syslog')), + 'lpr' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'lpr')), + 'news' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'news')), + 'uucp' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'uucp')), + 'cron' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'cron')), + 'authpriv': E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'authpriv')), + 'ftp' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'ftp')), + 'ntp' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'ntp')), + 'log' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'log')), + 'security': E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'security')), + 'console' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'console')), + 'clock' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'clock')), + 'local0' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local0')), + 'local1' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local1')), + 'local2' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local2')), + 'local3' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local3')), + 'local4' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local4')), + 'local5' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local5')), + 'local6' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local6')), + 'local7' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local7')), + }, + + logLevels : { + 'emerg' : E('span', { 'class': 'zonebadge log-emerg' }, E('strong', 'Emergency')), + 'alert' : E('span', { 'class': 'zonebadge log-alert' }, E('strong', 'Alert')), + 'crit' : E('span', { 'class': 'zonebadge log-crit' }, E('strong', 'Critical')), + 'err' : E('span', { 'class': 'zonebadge log-err' }, E('strong', 'Error')), + 'warn' : E('span', { 'class': 'zonebadge log-warn' }, E('strong', 'Warning')), + 'notice': E('span', { 'class': 'zonebadge log-notice' }, E('strong', 'Notice')), + 'info' : E('span', { 'class': 'zonebadge log-info' }, E('strong', 'Info')), + 'debug' : E('span', { 'class': 'zonebadge log-debug' }, E('strong', 'Debug')), + }, + + tailValue : 25, + + fastTailIncrement : 50, + + fastTailValue : null, + + timeFilterValue : null, + + timeFilterReValue : false, + + hostFilterValue : null, + + hostFilterReValue : false, + + facilityFilterValue : [], + + levelFilterValue : [], + + msgFilterValue : null, + + msgFilterReValue : false, + + logSortingValue : 'asc', + + autoRefreshValue : true, + + autorefreshOn : true, + + logTimestampFlag : false, + + logHostFlag : false, + + logFacilitiesFlag : false, + + logLevelsFlag : false, + + logLevelsStat : {}, + + logFacilitiesDropdown: null, + + logLevelsDropdown : null, + + totalLogLines : 0, + + logCols : [ '#', null, null, null, null, _('Message') ], + + convertTimestampValue: false, + + convertTimestampOn : false, + + lastHash : null, + + actionButtons : [], + + htmlEntities(str) { + return String(str).replace( + /&/g, '&').replace( + //g, '>').replace( + /"/g, '"').replace( + /'/g, '''); + }, + + checkZeroValue(value) { + return (/^[0-9]+$/.test(value)) ? value : 0 + }, + + makeRegExpButton(filterEl, checked) { + const btnOnClass = 'cbi-button-positive btn important', + btnOnStyle = 'text-decoration:none', + btnOffClass = 'cbi-button-neutral btn', + btnOffStyle = 'text-decoration:line-through'; + let btn = E('button', { + 'class': checked ? btnOnClass : btnOffClass, + 'style': checked ? btnOnStyle : btnOffStyle, + 'title': _('Apply pattern as regular expression'), + 'click': ev => { + ev.target.toggle(); + filterEl.focus(); + ev.preventDefault(); + }, + }, 'RE'); + btn._state = checked; + btn._on = function() { + this._state = true; + this.className = btnOnClass; + this.style = btnOnStyle; + }; + btn._off = function() { + this._state = false; + this.className = btnOffClass; + this.style = btnOffStyle; + }; + btn.checked = function() { + return this._state; + }; + btn.toggle = function() { + this._state ? this._off() : this._on(); + }; + btn.set = function(flag) { + flag ? this._on() : this._off(); + }; + return btn; + }, + + makeLogConvertTimestampSection() { + if(!this.enableConvertTimestamp) { + return ''; + }; + return E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'convertTimestamp', + }, _('Date')), + E('div', { 'class': 'cbi-value-field' }, [ + E('div', { 'class': 'cbi-checkbox' }, [ + this.convertTimestamp, + E('label', {}), + ]), + E('div', { 'class': 'cbi-value-description' }, + _('Convert timestamps to a human readable date.') + ), + ]), + ]); + }, + + makeLogTimeFilterSection() { + return E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'timeFilter', + }, _('Timestamp filter')), + E('div', { 'class': 'cbi-value-field' }, [ + E('span', { 'class': 'control-group' }, [ + this.timeFilter, + E('button', { + 'class': 'cbi-button-neutral btn', + 'click': ev => { + ev.target.blur(); + ev.preventDefault(); + this.timeFilter.value = null; + this.timeFilter.focus(); + }, + }, '⌫'), + this.timeFilterReBtn, + ]), + E('div', { 'class': 'cbi-value-description' }, + _('!pattern - entries that do not match the pattern.') + ), + ]), + ]); + }, + + makeLogHostFilterSection() { + return E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'hostFilter', + }, _('Host filter')), + E('div', { 'class': 'cbi-value-field' }, [ + E('span', { 'class': 'control-group' }, [ + this.hostFilter, + E('button', { + 'class': 'cbi-button-neutral btn', + 'click': ev => { + ev.target.blur(); + ev.preventDefault(); + this.hostFilter.value = null; + this.hostFilter.focus(); + }, + }, '⌫'), + this.hostFilterReBtn, + ]), + E('div', { 'class': 'cbi-value-description' }, + _('!pattern - entries that do not match the pattern.') + ), + ]), + ]); + }, + + makeLogFacilitiesDropdownSection() { + this.logFacilitiesDropdown = new ui.Dropdown( + null, + this.logFacilities, + { + id : 'logFacilitiesDropdown', + sort : Object.keys(this.logFacilities), + multiple : true, + select_placeholder: _('All'), + } + ); + return E( + 'div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'logFacilitiesDropdown', + }, _('Facilities')), + E('div', { 'class': 'cbi-value-field' }, + this.logFacilitiesDropdown.render() + ), + ] + ); + }, + + makeLogLevelsDropdownSection() { + this.logLevelsDropdown = new ui.Dropdown( + null, + this.logLevels, + { + id : 'logLevelsDropdown', + sort : Object.keys(this.logLevels), + multiple : true, + select_placeholder: _('All'), + } + ); + return E( + 'div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'logLevelsDropdown', + }, _('Logging levels')), + E('div', { 'class': 'cbi-value-field' }, + this.logLevelsDropdown.render() + ), + ] + ); + }, + + setRegexpValidator(elem, flagEl) { + ui.addValidator( + elem, + 'string', + true, + v => { + if(!flagEl.checked()) { + return true; + }; + try { + new RegExp(v, 'giu'); + return true; + } catch(err) { + return _('Invalid regular expression') + ':\n' + err.message; + }; + }, + 'blur', + 'focus', + 'input' + ); + }, + + setFilterSettings() { + this.tailValue = this.checkZeroValue(this.tailInput.value); + if(this.logTimestampFlag) { + if(this.enableConvertTimestamp) { + this.convertTimestampValue = this.convertTimestamp.checked; + }; + this.timeFilterValue = this.timeFilter.value; + this.timeFilterReValue = this.timeFilterReBtn.checked() + }; + if(this.logHostFlag) { + this.hostFilterValue = this.hostFilter.value; + this.hostFilterReValue = this.hostFilterReBtn.checked() + }; + if(this.logFacilitiesFlag) { + this.facilityFilterValue = this.logFacilitiesDropdown.getValue(); + }; + if(this.logLevelsFlag) { + this.levelFilterValue = this.logLevelsDropdown.getValue(); + }; + this.msgFilterValue = this.msgFilter.value; + this.msgFilterReValue = this.msgFilterReBtn.checked() + + this.logSortingValue = this.logSorting.value; + this.autoRefreshValue = this.autoRefresh.checked; + if(this.autorefreshOn) { + if(this.autoRefreshValue) { + poll.add(this.pollFuncWrapper, this.pollInterval); + this.refreshBtn.style.visibility = 'hidden'; + } else { + poll.remove(this.pollFuncWrapper); + this.refreshBtn.style.visibility = 'visible'; + }; + }; + }, + + resetFormValues() { + this.tailInput.value = this.tailValue; + if(this.logTimestampFlag) { + if(this.enableConvertTimestamp) { + this.convertTimestamp.checked = this.convertTimestampValue; + }; + this.timeFilter.value = this.timeFilterValue; + this.timeFilterReBtn.set(this.timeFilterReValue); + }; + if(this.logHostFlag) { + this.hostFilter.value = this.hostFilterValue; + this.hostFilterReBtn.set(this.hostFilterReValue); + }; + if(this.logFacilitiesFlag) { + this.logFacilitiesDropdown.setValue(this.facilityFilterValue); + }; + if(this.logLevelsFlag) { + this.logLevelsDropdown.setValue(this.levelFilterValue); + }; + this.msgFilter.value = this.msgFilterValue; + this.msgFilterReBtn.set(this.msgFilterReValue); + + this.logSorting.value = this.logSortingValue; + this.autoRefresh.checked = this.autoRefreshValue; + }, + + /** + * Receives raw log data. + * Abstract method, must be overridden by a subclass! + * + * @instance + * @abstract + * + * @param {number} tail + * @returns {string} + * Returns the raw content of the log. + */ + getLogData(tail) { + throw new Error('getLogData must be overridden by a subclass'); + }, + + /** + * Parses log data. + * Abstract method, must be overridden by a subclass! + * + * @instance + * @abstract + * + * @param {string} logdata + * @param {number} tail + * @returns {Array} + * Returns an array of values: [ #, Timestamp, Host, Facility, Level, Message ]. + */ + parseLogData(logdata, tail) { + throw new Error('parseLogData must be overridden by a subclass'); + }, + + /** + * Highlights the search result for a pattern. + * Abstract method, must be overridden by a subclass! + * + * To disable the highlight option, views extending + * this base class should overwrite the `filterHighlightFunc` + * function with `null`. + * + * @instance + * @abstract + * + * @param {string} logdata + * @returns {string} + * Returns a string with the highlighted part. + */ + filterHighlightFunc(match) { + throw new Error('filterHighlightFunc must be overridden by a subclass'); + }, + + setStringFilter(entriesArray, fieldNum, pattern) { + let not = pattern.startsWith('!'); + pattern = pattern.replace(/^!/, ''); + let isHFunc = (typeof(this.filterHighlightFunc) == 'function'); + let fArr = []; + if(!pattern) { + return entriesArray; + }; + entriesArray.forEach((e, i) => { + if(e[fieldNum] == null) { + return; + }; + if(not) { + if(!(e[fieldNum].includes(pattern))) { + fArr.push(e); + }; + } else { + if(e[fieldNum].includes(pattern)) { + if(isHFunc) { + e[fieldNum] = e[fieldNum].replace(pattern, this.filterHighlightFunc); + }; + fArr.push(e); + }; + }; + }); + return fArr; + }, + + setRegexpFilter(entriesArray, fieldNum, pattern) { + let not = pattern.startsWith('!'); + pattern = pattern.replace(/^!/, ''); + let isHFunc = (typeof(this.filterHighlightFunc) == 'function'); + let fArr = []; + if(!pattern) { + return entriesArray; + }; + try { + let regExp = new RegExp(pattern, 'giu'); + entriesArray.forEach((e, i) => { + if(e[fieldNum] == null) { + return; + }; + if(not) { + if(!(regExp.test(e[fieldNum]))) { + fArr.push(e); + }; + } else { + if(regExp.test(e[fieldNum])) { + if(isHFunc) { + e[fieldNum] = e[fieldNum].replace(regExp, this.filterHighlightFunc); + }; + fArr.push(e); + }; + }; + regExp.lastIndex = 0; + }); + } catch(err) { + if(err.name == 'SyntaxError') { + return entriesArray; + } else { + throw err; + }; + }; + return fArr; + }, + + setTimeFilter(entriesArray) { + let fPattern = this.timeFilterValue; + if(!fPattern) { + return entriesArray; + }; + return (this.timeFilterReValue) ? + this.setRegexpFilter(entriesArray, 1, fPattern) : + this.setStringFilter(entriesArray, 1, fPattern); + }, + + setHostFilter(entriesArray) { + let fPattern = this.hostFilterValue; + if(!fPattern) { + return entriesArray; + }; + return (this.hostFilterReValue) ? + this.setRegexpFilter(entriesArray, 2, fPattern) : + this.setStringFilter(entriesArray, 2, fPattern); + }, + + setFacilityFilter(entriesArray) { + let logFacilitiesKeys = Object.keys(this.logFacilities); + if(logFacilitiesKeys.length > 0 && this.logFacilitiesDropdown) { + if(this.facilityFilterValue.length == 0) { + return entriesArray; + }; + return entriesArray.filter(e => this.facilityFilterValue.includes(e[3])); + }; + return entriesArray; + }, + + setLevelFilter(entriesArray) { + let logLevelsKeys = Object.keys(this.logLevels); + if(logLevelsKeys.length > 0 && this.logLevelsDropdown) { + if(this.levelFilterValue.length == 0) { + return entriesArray; + }; + return entriesArray.filter(e => this.levelFilterValue.includes(e[4])); + }; + return entriesArray; + }, + + setMsgFilter(entriesArray) { + let fPattern = this.msgFilterValue; + if(!fPattern) { + return entriesArray; + }; + return (this.msgFilterReValue) ? + this.setRegexpFilter(entriesArray, 5, fPattern) : + this.setStringFilter(entriesArray, 5, fPattern); + }, + + /** + * Creates the contents of the log area. + * Abstract method, must be overridden by a subclass! + * + * @instance + * @abstract + * + * @param {Array} logdataArray + * @returns {Node} + * Returns a DOM node containing the log area. + */ + makeLogArea(logdataArray) { + throw new Error('makeLogArea must be overridden by a subclass'); + }, + + disableFormElems() { + Array.from(this.logFilterForm.elements).forEach( + e => e.disabled = true + ); + this.actionButtons.forEach(e => e.disabled = true); + }, + + enableFormElems() { + Array.from(this.logFilterForm.elements).forEach( + e => e.disabled = false + ); + this.actionButtons.forEach(e => e.disabled = false); + }, + + downloadLog(ev) { + this.disableFormElems(); + return this.getLogData(0).then(logdata => { + logdata = logdata || ''; + let link = E('a', { + 'download': this.viewName + '.log', + 'href' : URL.createObjectURL( + new Blob([ logdata ], { type: 'text/plain' })), + }); + link.click(); + URL.revokeObjectURL(link.href); + }).catch(err => { + ui.addNotification(null, + E('p', {}, _('Download error') + ': ' + err.message)); + }).finally(() => { + this.enableFormElems(); + }); + }, + + restoreSettingsFromLocalStorage() { + let tailValueLocal = localStorage.getItem(`luci-app-${this.viewName}-tailValue`); + if(tailValueLocal) { + this.tailValue = Number(tailValueLocal); + }; + let logSortingLocal = localStorage.getItem(`luci-app-${this.viewName}-logSortingValue`); + if(logSortingLocal) { + this.logSortingValue = logSortingLocal; + }; + if(this.enableConvertTimestamp) { + let convertTimestampLocal = localStorage.getItem(`luci-app-${this.viewName}-convertTimestampValue`); + if(convertTimestampLocal) { + this.convertTimestampValue = Boolean(Number(convertTimestampLocal)); + }; + }; + if(this.enableAutoRefresh) { + let autoRefreshLocal = localStorage.getItem(`luci-app-${this.viewName}-autoRefreshValue`); + if(autoRefreshLocal) { + this.autoRefreshValue = Boolean(Number(autoRefreshLocal)); + }; + }; + }, + + saveSettingsToLocalStorage(tailValue, logSortingValue, autoRefreshValue, convertTimestampValue) { + tailValue = this.checkZeroValue(tailValue); + if(this.tailValue != tailValue) { + localStorage.setItem( + `luci-app-${this.viewName}-tailValue`, String(tailValue)); + }; + if(this.logSortingValue != logSortingValue) { + localStorage.setItem( + `luci-app-${this.viewName}-logSortingValue`, logSortingValue); + }; + if(this.convertTimestampOn) { + if(this.convertTimestampValue != convertTimestampValue) { + localStorage.setItem( + `luci-app-${this.viewName}-convertTimestampValue`, String(Number(convertTimestampValue))); + }; + }; + if(this.autorefreshOn) { + if(this.autoRefreshValue != autoRefreshValue) { + localStorage.setItem( + `luci-app-${this.viewName}-autoRefreshValue`, String(Number(autoRefreshValue))); + }; + }; + }, + + reloadLog(tail, modal=false, autorefresh=false) { + tail = (tail && tail > 0) ? tail : 0; + if(!autorefresh) { + this.disableFormElems(); + poll.stop(); + }; + return this.getLogData(tail).then(logdata => { + logdata = logdata || ''; + this.logWrapper.innerHTML = ''; + this.logWrapper.append( + this.makeLogArea( + this.setMsgFilter( + this.setFacilityFilter( + this.setLevelFilter( + this.setHostFilter( + this.setTimeFilter( + this.parseLogData(logdata, tail) + ) + ) + ) + ) + ) + ) + ); + if(logdata && logdata !== '') { + if(this.enableConvertTimestamp && !this.logConvertTimestampElem) { + this.logConvertTimestampElem = this.makeLogConvertTimestampSection(); + }; + if(this.logTimestampFlag && !this.logTimeFilterElem) { + this.logTimeFilterElem = this.makeLogTimeFilterSection(); + }; + if(this.logHostFlag && !this.logHostFilterElem) { + this.logHostFilterElem = this.makeLogHostFilterSection(); + }; + if(this.logFacilitiesFlag && !this.logFacilitiesDropdown) { + this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection(); + }; + if(this.logLevelsFlag && !this.logLevelsDropdown) { + this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection(); + }; + }; + + if(!autorefresh) { + poll.start(); + }; + }).finally(() => { + if(modal) { + ui.hideModal(); + }; + if(!autorefresh) { + this.enableFormElems(); + }; + }); + }, + + filterSettingsModal() { + return ui.showModal(_('Filter settings'), [ + E('div', { 'class': 'cbi-map' }, + E('div', { 'class': 'cbi-section' }, [ + E('div', { 'class': 'cbi-section-node' }, [ + E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'tailInput', + }, _('Last entries')), + E('div', { 'class': 'cbi-value-field' }, + E('span', { 'class': 'control-group' }, [ + this.tailInput, + E('button', { + 'class': 'cbi-button-neutral btn', + 'click': ev => { + ev.target.blur(); + ev.preventDefault(); + this.tailInput.value = 0; + this.tailInput.focus(); + }, + }, '⌫'), + ]) + ), + ]), + this.logConvertTimestampElem, + this.logTimeFilterElem, + this.logHostFilterElem, + this.logFacilitiesDropdownElem, + this.logLevelsDropdownElem, + E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'msgFilter', + }, _('Message filter')), + E('div', { 'class': 'cbi-value-field' }, [ + E('span', { 'class': 'control-group' }, [ + this.msgFilter, + E('button', { + 'class': 'cbi-button-neutral btn', + 'click': ev => { + ev.target.blur(); + ev.preventDefault(); + this.msgFilter.value = null; + this.msgFilter.focus(); + }, + }, '⌫'), + this.msgFilterReBtn, + ]), + E('div', { 'class': 'cbi-value-description' }, + _('!pattern - entries that do not match the pattern.') + ), + ]), + ]), + E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'logSorting', + }, _('Sorting entries')), + E('div', { 'class': 'cbi-value-field' }, this.logSorting), + ]), + ((this.autorefreshOn) ? + E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'autoRefresh', + }, _('Auto refresh')), + E('div', { 'class': 'cbi-value-field' }, + E('div', { 'class': 'cbi-checkbox' }, [ + this.autoRefresh, + E('label', {}), + ]) + ), + ]) : ''), + ]), + ]), + ), + this.logFilterForm, + E('div', { 'class': 'right button-row' }, [ + E('button', { + 'class': 'btn', + 'click': ev => { + ev.target.blur(); + this.resetFormValues(); + this.timeFilter.focus(); + this.msgFilter.focus(); + ui.hideModal(); + }, + }, _('Dismiss')), + ' ', + E('button', { + 'type' : 'submit', + 'form' : 'logFilterForm', + 'class': 'btn cbi-button-positive important', + 'click': ui.createHandlerFn(this, function(ev) { + ev.target.blur(); + ev.preventDefault(); + return this.onSubmitFilter(); + }), + }, _('Apply')), + ]), + ], 'cbi-modal'); + }, + + updateLog(autorefresh=false) { + let tail = (Number(this.tailValue) == 0 || Number(this.fastTailValue) == 0) + ? 0 : Math.max(Number(this.tailValue), this.fastTailValue) + return this.reloadLog(tail, false, autorefresh); + }, + + /** + * Creates a promise for the RPC request. + * Abstract method, must be overridden by a subclass! + * + * To completely disable the auto log refresh option, views extending + * this base class should overwrite the `getLogHash` function + * with `null`. + * + * @instance + * @abstract + * + * @returns {Promise} + * Returns a promise that returns the unique value for the current log state. + */ + getLogHash() { + throw new Error('getLogHash must be overridden by a subclass'); + }, + + /** + * Converts the timestamp format. + * Abstract method, must be overridden by a subclass! + * + * To completely disable the convert timrstamp option, views extending + * this base class should overwrite the `convertTimestampFunc` function + * with `null`. + * + * @instance + * @abstract + * + * @param {string} t + * @returns {String} + * Returns the converted timestamp string. + */ + convertTimestampFunc(t) { + throw new Error('convertTimestampFunc must be overridden by a subclass'); + }, + + async pollFunc() { + await this.getLogHash().then(async hash => { + if(this.lastHash !== hash) { + this.lastHash = hash; + return await this.updateLog(true); + }; + }); + }, + + onSubmitFilter() { + if(this.logSorting.value != this.logSortingValue) { + if(this.logSorting.value == 'desc') { + this.logWrapper.after(this.moreEntriesBar); + } else { + this.logWrapper.before(this.moreEntriesBar); + }; + }; + this.saveSettingsToLocalStorage( + this.tailInput.value, this.logSorting.value, + this.autoRefresh.checked, this.convertTimestamp.checked); + this.setFilterSettings(); + this.fastTailValue = Number(this.tailValue); + return this.reloadLog(Number(this.tailValue), true); + }, + + scrollToTop() { + this.logWrapper.scrollIntoView(true); + }, + + scrollToBottom() { + this.logWrapper.scrollIntoView(false); + }, + + load() { + this.restoreSettingsFromLocalStorage(); + if(!this.enableAutoRefresh || typeof(this.getLogHash) != 'function') { + this.autorefreshOn = false; + this.autoRefreshValue = false; + }; + if(this.enableConvertTimestamp && typeof(this.convertTimestampFunc) == 'function') { + this.convertTimestampOn = true; + }; + return this.getLogData(this.tailValue); + }, + + render(logdata) { + this.pollFuncWrapper = L.bind(this.pollFunc, this); + + this.logWrapper = E('div', { + 'id': 'logWrapper', + }, this.makeLogArea(this.parseLogData(logdata, this.tailValue))); + + this.fastTailValue = this.tailValue + + this.tailInput = E('input', { + 'id' : 'tailInput', + 'name' : 'tailInput', + 'type' : 'text', + 'form' : 'logFilterForm', + 'class' : 'cbi-input-text', + 'style' : 'width:4em !important; min-width:4em !important', + 'maxlength': 5, + }); + this.tailInput.value = this.tailValue; + ui.addValidator(this.tailInput, 'uinteger', true); + + this.convertTimestamp = E('input', { + 'id' : 'convertTimestamp', + 'name': 'convertTimestamp', + 'type': 'checkbox', + 'form': 'logFilterForm', + }); + this.convertTimestamp.checked = this.convertTimestampValue; + + this.timeFilter = E('input', { + 'id' : 'timeFilter', + 'name' : 'timeFilter', + 'type' : 'text', + 'form' : 'logFilterForm', + 'class' : 'cbi-input-text', + 'placeholder': _('Type a search pattern...'), + }); + + this.timeFilterReBtn = this.makeRegExpButton(this.timeFilter, this.timeFilterReValue); + this.setRegexpValidator(this.timeFilter, this.timeFilterReBtn); + + this.hostFilter = E('input', { + 'id' : 'hostFilter', + 'name' : 'hostFilter', + 'type' : 'text', + 'form' : 'logFilterForm', + 'class' : 'cbi-input-text', + 'placeholder': _('Type a search pattern...'), + }); + + this.hostFilterReBtn = this.makeRegExpButton(this.hostFilter, this.hostFilterReValue); + this.setRegexpValidator(this.hostFilter, this.hostFilterReBtn); + + this.logConvertTimestampElem = ''; + this.logTimeFilterElem = ''; + this.logHostFilterElem = ''; + this.logFacilitiesDropdownElem = ''; + this.logLevelsDropdownElem = ''; + + if(this.logTimestampFlag) { + this.logConvertTimestampElem = this.makeLogConvertTimestampSection(); + this.logTimeFilterElem = this.makeLogTimeFilterSection(); + }; + if(this.logLevelsFlag) { + this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection(); + }; + if(this.logFacilitiesFlag) { + this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection(); + }; + if(this.logHostFlag) { + this.logHostFilterElem = this.makeLogHostFilterSection(); + }; + + this.msgFilter = E('input', { + 'id' : 'msgFilter', + 'name' : 'msgFilter', + 'type' : 'text', + 'form' : 'logFilterForm', + 'class' : 'cbi-input-text', + 'placeholder': _('Type a search pattern...'), + }); + + this.msgFilterReBtn = this.makeRegExpButton(this.msgFilter, this.msgFilterReValue); + this.setRegexpValidator(this.msgFilter, this.msgFilterReBtn); + + this.logSorting = E('select', { + 'id' : 'logSorting', + 'name' : 'logSorting', + 'form' : 'logFilterForm', + 'class': "cbi-input-select", + }, [ + E('option', { 'value': 'asc' }, _('ascending')), + E('option', { 'value': 'desc' }, _('descending')), + ]); + this.logSorting.value = this.logSortingValue; + + this.autoRefresh = E('input', { + 'id' : 'autoRefresh', + 'name' : 'autoRefresh', + 'type' : 'checkbox', + 'form' : 'logFilterForm', + }); + this.autoRefresh.checked = this.autoRefreshValue; + + this.filterEditsBtn = E('button', { + 'class': 'cbi-button btn cbi-button-action', + 'click': L.bind(this.filterSettingsModal, this), + }, _('Edit')); + + this.logFilterForm = E('form', { + 'id' : 'logFilterForm', + 'name' : 'logFilterForm', + 'style' : 'display:none', + 'submit': ev => { + ev.preventDefault(); + return this.onSubmitFilter(); + }, + }); + + this.logDownloadBtn = E('button', { + 'id' : 'logDownloadBtn', + 'name' : 'logDownloadBtn', + 'class': 'cbi-button btn', + 'click': ui.createHandlerFn(this, this.downloadLog), + }, _('Download log')); + + this.refreshBtn = E('button', { + 'title': _('Refresh log'), + 'class': 'cbi-button btn log-side-btn', + 'style': `visibility:${(this.autoRefreshValue) ? 'hidden' : 'visible'}`, + 'click': ui.createHandlerFn(this, function(ev) { + ev.target.blur(); + return this.updateLog(); + }), + }, '⟳'); + + function getMoreEntries(ev) { + ev.target.blur(); + if(this.fastTailValue === null) { + this.fastTailValue = Number(this.tailValue); + }; + if(this.fastTailValue > 0) { + this.fastTailValue += this.fastTailIncrement; + }; + return this.reloadLog(this.fastTailValue); + } + + this.moreEntriesBtn = E('button', { + 'title': _('More entries'), + 'class': 'cbi-button btn log-side-btn', + 'style': 'margin-top:1px !important', + 'click': ui.createHandlerFn(this, getMoreEntries), + }, `+${this.fastTailIncrement}`); + + this.moreEntriesRowBtn = E('button', { + 'class': 'cbi-button btn', + 'click': ui.createHandlerFn(this, getMoreEntries), + }, _('More entries')); + + this.moreEntriesBar = E('div', { + 'id' : 'moreEntriesBar', + 'class': 'center', + }, this.moreEntriesRowBtn); + + this.allEntriesBtn = E('button', { + 'title': _('All entries'), + 'class': 'cbi-button btn log-side-btn', + 'style': 'margin-top:1px !important', + 'click': ui.createHandlerFn(this, function(ev) { + ev.target.blur(); + this.fastTailValue = 0; + return this.reloadLog(0); + }), + }, _('All')); + + this.filterModalBtn = E('button', { + 'title': _('Filter settings'), + 'class': 'cbi-button btn log-side-btn', + 'style': 'margin-top:10px !important', + 'click': ev => { + ev.target.blur(); + this.filterSettingsModal(); + }, + }, '▢'); + + this.actionButtons.push(this.filterEditsBtn, this.logDownloadBtn, + this.refreshBtn, this.moreEntriesBtn, + this.moreEntriesRowBtn, + this.allEntriesBtn, this.filterModalBtn); + + document.body.append( + E('div', { + 'align': 'right', + 'class': 'log-side-block', + }, [ + this.refreshBtn, + this.moreEntriesBtn, + this.allEntriesBtn, + this.filterModalBtn, + E('button', { + 'class': 'cbi-button btn log-side-btn', + 'style': 'margin-top:10px !important', + 'click': ev => { + this.scrollToTop(); + ev.target.blur(); + }, + }, '↑'), + E('button', { + 'class': 'cbi-button btn log-side-btn', + 'style': 'margin-top:1px !important', + 'click': ev => { + this.scrollToBottom(); + ev.target.blur(); + }, + }, '↓'), + ]) + ); + + if(this.autorefreshOn && this.autoRefreshValue) { + poll.add(this.pollFuncWrapper, this.pollInterval); + }; + + let logArea = [ this.moreEntriesBar, this.logWrapper ]; + if(this.logSortingValue == 'desc') { + logArea.reverse(); + }; + + return E([ + E('h2', { 'id': 'logTitle', 'class': 'fade-in' }, this.title), + E('div', { 'class': 'cbi-section-descr fade-in' }), + E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, [ + E('div', { 'class': 'cbi-value' }, [ + E('label', { + 'class': 'cbi-value-title', + 'for' : 'filterSettings', + }, _('Filter settings')), + E('div', { 'class': 'cbi-value-field' }, [ + E('div', {}, this.filterEditsBtn), + E('input', { + 'id' : 'filterSettings', + 'type': 'hidden', + }), + ]), + ]), + ]) + ), + E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, logArea) + ), + E('div', { 'class': 'cbi-section fade-in' }, + E('div', { 'class': 'cbi-section-node' }, + E('div', { 'class': 'cbi-value' }, + E('div', { + 'align': 'left', + 'style': 'width:100%', + }, this.logDownloadBtn) + ), + ) + ), + ]); + }, + + handleSaveApply: null, + handleSave : null, + handleReset : null, + }), +}) diff --git a/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-system.js b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-system.js new file mode 100644 index 00000000..78abf857 --- /dev/null +++ b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-system.js @@ -0,0 +1,179 @@ +'use strict'; +'require baseclass'; +'require fs'; +'require view.log-viewer.log-widget as widget'; + +return baseclass.extend({ + view: widget.view.extend({ + enableAutoRefresh: true, + + /** + * Pattern for picking application-specific entries from the log. + * + * @property {string} appPattern + */ + appPattern : '^', + + /** + * Enable "tail" option for the logread (logread -l). + * Must be disabled for application-specific log. + * + * @property {bool} loggerTail + */ + loggerTail : false, + + logdRegexp : new RegExp(/^([^\s]{3}\s+[^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2}\s+\d{4})\s+([a-z0-9]+)\.([a-z]+)\s+(.*)$/), + + syslog_ngRegexp : new RegExp(/^([^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2})\s+([^\s]+)\s+(.*)$/), + + entryRegexp : null, + + loggerChecked : false, + + entriesHandler : null, + + logger : null, + + getLogHash() { + return this.getLogData(1, true).then(data => { + return data || ''; + }); + }, + + // logd + logdHandler(strArray, lineNum) { + return [ + lineNum, // # (Number) + strArray[1], // Timestamp (String) + null, // Host (String) + strArray[2], // Facility (String) + strArray[3], // Level (String) + this.htmlEntities(strArray[4]) || ' ', // Message (String) + ]; + }, + + // syslog-ng + syslog_ngHandler(strArray, lineNum) { + return [ + lineNum, // # (Number) + strArray[1], // Timestamp (String) + strArray[2], // Host (String) + null, // Facility (String) + null, // Level (String) + this.htmlEntities(strArray[3]) || ' ', // Message (String) + ]; + }, + + // unsupported log handler + unsupportedLogHandler(line, lineNum) { + return [ + lineNum, // # (Number) + null, // Timestamp (String) + null, // Host (String) + null, // Facility (String) + null, // Level (String) + this.htmlEntities(line) || ' ', // Message (String) + ]; + }, + + checkLogread() { + return Promise.all([ + L.resolveDefault(fs.stat('/sbin/logread'), null), + L.resolveDefault(fs.stat('/usr/sbin/logread'), null), + ]).then(stat => { + let logger = (stat[0]) ? stat[0].path : (stat[1]) ? stat[1].path : null; + if(logger) { + this.logger = logger; + } else { + throw new Error(_('Logread not found')); + }; + }); + }, + + async getLogData(tail, extraTstamp=false) { + if(!this.logger) { + await this.checkLogread(); + }; + let loggerArgs = []; + if(this.loggerTail && tail) { + loggerArgs.push('-l', String(tail)); + }; + loggerArgs.push('-e', this.appPattern); + if(extraTstamp) { + loggerArgs.push('-t'); + }; + return fs.exec_direct(this.logger, loggerArgs, 'text').catch(err => { + throw new Error(_('Unable to load log data:') + ' ' + err.message); + }); + }, + + parseLogData(logdata, tail) { + if(!logdata) { + return []; + }; + + let strings = logdata.trim().split(/\n/); + + if(!this.loggerTail && tail && tail > 0 && strings) { + strings = strings.slice(-tail); + }; + + this.totalLogLines = strings.length; + + let entriesArray = strings.map((e, i) => { + if(!this.loggerChecked) { + if(this.logdRegexp.test(e)) { + this.entryRegexp = this.logdRegexp; + this.logTimestampFlag = true; + this.logFacilitiesFlag = true; + this.logLevelsFlag = true; + this.logHostFlag = false; + this.entriesHandler = this.logdHandler; + this.logCols = [ + '#', + _('Timestamp'), + null, + _('Facility'), + _('Level'), + _('Message'), + ]; + this.loggerChecked = true; + } + else if(this.syslog_ngRegexp.test(e)) { + this.entryRegexp = this.syslog_ngRegexp; + this.logTimestampFlag = true; + this.logFacilitiesFlag = false; + this.logLevelsFlag = false; + this.logHostFlag = true; + this.logFacilities = {}; + this.logLevels = {}; + this.entriesHandler = this.syslog_ngHandler; + this.logCols = [ + '#', + _('Timestamp'), + _('Host'), + null, + null, + _('Message'), + ]; + this.loggerChecked = true; + } else { + return this.unsupportedLogHandler(e, i + 1); + }; + }; + + let strArray = e.match(this.entryRegexp); + if(strArray) { + return this.entriesHandler(strArray, i + 1); + } else { + return this.unsupportedLogHandler(e, i + 1); + }; + }); + + if(this.logSortingValue == 'desc') { + entriesArray.reverse(); + }; + return entriesArray; + }, + }), +}); diff --git a/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-widget.js b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-widget.js new file mode 100644 index 00000000..742f1c28 --- /dev/null +++ b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/log-widget.js @@ -0,0 +1,117 @@ +'use strict'; +'require baseclass'; +'require ui'; +'require view.log-viewer.log-base as base'; + +document.head.append(E('style', {'type': 'text/css'}, +` +#logTable { + width: calc(100% - 4px); +} +.log-entry-time-cell { + min-width: 14em !important; + white-space: pre-wrap !important; +} +.log-entry-host-cell { + min-width: 10em !important; + overflow-wrap: anywhere !important; +} +.log-entry-message-cell { + min-width: 20em !important; + white-space: pre-wrap !important; + overflow-wrap: anywhere !important; +} +.log-entry-text-nowrap { + white-space: nowrap !important; +}; +`)); + +return baseclass.extend({ + view: base.view.extend({ + + filterHighlightFunc(match) { + return `${match}`; + }, + + makeLogArea(logdataArray) { + let lines = `${_('No entries available...')}`; + let logTable = E('table', { 'id': 'logTable', 'class': 'table' }); + + for(let level of Object.keys(this.logLevels)) { + this.logLevelsStat[level] = 0; + }; + + if(logdataArray.length > 0) { + lines = []; + logdataArray.forEach((e, i) => { + if(e[4] in this.logLevels) { + this.logLevelsStat[e[4]] = this.logLevelsStat[e[4]] + 1; + }; + + let line = [ `` ]; + this.logCols.forEach((c, i) => { + if(c) { + let cellClass = ''; + switch(i) { + case 0: + case 3: + case 4: + cellClass = 'log-entry-text-nowrap'; + break; + case 1: + cellClass = 'log-entry-time-cell'; + break; + case 2: + cellClass = 'log-entry-host-cell'; + break; + case 5: + cellClass = 'log-entry-message-cell'; + break; + }; + line.push(`${e[i] || ' '}`); + }; + }); + line.push(''); + lines.push(line.join('')); + }); + lines = lines.join(''); + + let logTableHeader = E('tr', { 'class': 'tr table-titles' }); + this.logCols.forEach(e => { + if(e) { + logTableHeader.append( + E('th', { 'class': 'th left log-entry-text-nowrap' }, e) + ); + }; + }); + logTable.append(logTableHeader); + }; + + try { + logTable.insertAdjacentHTML('beforeend', lines); + } catch(err) { + if(err.name == 'SyntaxError') { + ui.addNotification(null, + E('p', {}, _('HTML/XML error') + ': ' + err.message), 'error'); + }; + throw err; + }; + + let levelsStatString = ''; + if((Object.values(this.logLevelsStat).reduce((s,c) => s + c, 0)) > 0) { + Object.entries(this.logLevelsStat).forEach(e => { + if(e[0] in this.logLevels && e[1] > 0) { + levelsStatString += `${e[1]}`; + }; + }); + }; + + return E([ + E('div', { 'class': 'log-entries-count' }, + `${_('Entries')}: ${logdataArray.length} / ${this.totalLogLines}${levelsStatString}` + ), + logTable, + ]); + }, + }), +}); diff --git a/luci-app-log/htdocs/luci-static/resources/view/log-viewer/syslog.js b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/syslog.js new file mode 100644 index 00000000..56adfc51 --- /dev/null +++ b/luci-app-log/htdocs/luci-static/resources/view/log-viewer/syslog.js @@ -0,0 +1,10 @@ +'use strict'; +'require view.log-viewer.log-system as abc'; + +return abc.view.extend({ + viewName : 'syslog', + title : _('System Log'), + enableAutoRefresh: true, + appPattern : '^', + loggerTail : true, +}); diff --git a/luci-app-log/po/ru/log-viewer.po b/luci-app-log/po/ru/log-viewer.po new file mode 100644 index 00000000..aa82bc7a --- /dev/null +++ b/luci-app-log/po/ru/log-viewer.po @@ -0,0 +1,129 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ru\n" +"X-Generator: Poedit 2.0.6\n" + +msgid "!pattern - entries that do not match the pattern." +msgstr "!шаблон - запиÑи не Ñовпадающие Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð¾Ð¼." + +msgid "All" +msgstr "Ð’Ñе" + +msgid "All entries" +msgstr "Ð’Ñе запиÑи" + +msgid "Apply" +msgstr "Применить" + +msgid "Apply pattern as regular expression" +msgstr "ПрименÑть фильтр как регулÑрное выражение" + +msgid "Auto refresh" +msgstr "Ðвтообновление" + +msgid "Convert timestamps to a human readable date." +msgstr "Конвертировать временные метки в удобочитаемую дату." + +msgid "Date" +msgstr "Дата" + +msgid "Dismiss" +msgstr "Закрыть" + +msgid "Download log" +msgstr "Скачать журнал" + +msgid "Edit" +msgstr "Изменить" + +msgid "Entries" +msgstr "ЗапиÑи" + +msgid "Facility" +msgstr "КатегориÑ" + +msgid "Facilities" +msgstr "Категории" + +msgid "Filter settings" +msgstr "ÐаÑтройки фильтра" + +msgid "Host" +msgstr "ХоÑÑ‚" + +msgid "Hosts" +msgstr "ХоÑты" + +msgid "Invalid regular expression" +msgstr "Ðеправильное регулÑрное выражение" + +msgid "Kernel Log" +msgstr "Журнал Ñдра" + +msgid "Last entries" +msgstr "ПоÑледние запиÑи" + +msgid "Level" +msgstr "Уровень" + +msgid "Log" +msgstr "Лог" + +msgid "Log Viewer" +msgstr "ПроÑмотр лога" + +msgid "Logging levels" +msgstr "Уровни логированиÑ" + +msgid "Logread not found" +msgstr "Logread не найден" + +msgid "Message" +msgstr "Сообщение" + +msgid "Message filter" +msgstr "Фильтр Ñообщений" + +msgid "More entries" +msgstr "Больше запиÑей" + +msgid "No entries available..." +msgstr "Ðет доÑтупных запиÑей..." + +msgid "Refresh log" +msgstr "Обновить лог" + +msgid "Sorting entries" +msgstr "Сортировка запиÑей" + +msgid "System Log" +msgstr "СиÑтемный журнал" + +msgid "Timestamp" +msgstr "ВремÑ" + +msgid "Timestamp filter" +msgstr "Фильтр даты" + +msgid "Type a search pattern..." +msgstr "Введите шаблон Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка..." + +msgid "Unable to load log data:" +msgstr "Ðевозможно загрузить данные лога:" + +msgid "Unsupported log format" +msgstr "Ðеподдерживаемый формат лога" + +msgid "ascending" +msgstr "по возраÑтанию" + +msgid "descending" +msgstr "по убыванию" diff --git a/luci-app-log/po/templates/log-viewer.pot b/luci-app-log/po/templates/log-viewer.pot new file mode 100644 index 00000000..03510941 --- /dev/null +++ b/luci-app-log/po/templates/log-viewer.pot @@ -0,0 +1,119 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "!pattern - entries that do not match the pattern." +msgstr "" + +msgid "All" +msgstr "" + +msgid "All entries" +msgstr "" + +msgid "Apply" +msgstr "" + +msgid "Apply pattern as regular expression" +msgstr "" + +msgid "Auto refresh" +msgstr "" + +msgid "Convert timestamps to a human readable date." +msgstr "" + +msgid "Date" +msgstr "" + +msgid "Dismiss" +msgstr "" + +msgid "Download log" +msgstr "" + +msgid "Edit" +msgstr "" + +msgid "Entries" +msgstr "" + +msgid "Facility" +msgstr "" + +msgid "Facilities" +msgstr "" + +msgid "Filter settings" +msgstr "" + +msgid "Host" +msgstr "" + +msgid "Hosts" +msgstr "" + +msgid "Invalid regular expression" +msgstr "" + +msgid "Kernel Log" +msgstr "" + +msgid "Last entries" +msgstr "" + +msgid "Level" +msgstr "" + +msgid "Log" +msgstr "" + +msgid "Log Viewer" +msgstr "" + +msgid "Logging levels" +msgstr "" + +msgid "Logread not found" +msgstr "" + +msgid "Message" +msgstr "" + +msgid "Message filter" +msgstr "" + +msgid "More entries" +msgstr "" + +msgid "No entries available..." +msgstr "" + +msgid "Refresh log" +msgstr "" + +msgid "Sorting entries" +msgstr "" + +msgid "System Log" +msgstr "" + +msgid "Timestamp" +msgstr "" + +msgid "Timestamp filter" +msgstr "" + +msgid "Type a search pattern..." +msgstr "" + +msgid "Unable to load log data:" +msgstr "" + +msgid "Unsupported log format" +msgstr "" + +msgid "ascending" +msgstr "" + +msgid "descending" +msgstr "" diff --git a/luci-app-log/root/usr/share/luci/menu.d/luci-app-log-viewer.json b/luci-app-log/root/usr/share/luci/menu.d/luci-app-log-viewer.json new file mode 100644 index 00000000..9c13cbf6 --- /dev/null +++ b/luci-app-log/root/usr/share/luci/menu.d/luci-app-log-viewer.json @@ -0,0 +1,31 @@ +{ + "admin/status/log-viewer": { + "title": "Log Viewer", + "order": 5, + "action": { + "type": "alias", + "path": "admin/status/log-viewer/syslog" + }, + "depends": { + "acl": [ "luci-app-log-viewer" ] + } + }, + + "admin/status/log-viewer/syslog": { + "title": "System Log", + "order": 1, + "action": { + "type": "view", + "path": "log-viewer/syslog" + } + }, + + "admin/status/log-viewer/dmesg": { + "title": "Kernel Log", + "order": 2, + "action": { + "type": "view", + "path": "log-viewer/dmesg" + } + } +} diff --git a/luci-app-log/root/usr/share/rpcd/acl.d/luci-app-log-viewer.json b/luci-app-log/root/usr/share/rpcd/acl.d/luci-app-log-viewer.json new file mode 100644 index 00000000..e5b091ad --- /dev/null +++ b/luci-app-log/root/usr/share/rpcd/acl.d/luci-app-log-viewer.json @@ -0,0 +1,17 @@ +{ + "luci-app-log-viewer": { + "description": "Grant access to log-viewer procedures", + "read": { + "cgi-io": [ "exec" ], + "file": { + "/sbin/logread*": [ "exec" ], + "/usr/sbin/logread*": [ "exec" ], + "/bin/dmesg -r": [ "exec" ] + }, + "ubus": { + "system": [ "info" ], + "luci.log-viewer": [ "getSyslogSize", "getSyslogHash", "getDmesgSize", "getDmesgHash", "getLogfileSize" ] + } + } + } +} diff --git a/luci-app-log/root/usr/share/rpcd/ucode/luci.log-viewer b/luci-app-log/root/usr/share/rpcd/ucode/luci.log-viewer new file mode 100644 index 00000000..6c7f0e5c --- /dev/null +++ b/luci-app-log/root/usr/share/rpcd/ucode/luci.log-viewer @@ -0,0 +1,67 @@ + +'use strict'; + +import { popen, stat } from 'fs'; + +const dmesgCmd = '/bin/dmesg'; +const logreadCmd = ( + (stat('/sbin/logread')?.perm?.user_exec) ? '/sbin/logread' : + ((stat('/usr/sbin/logread')?.perm?.user_exec) ? '/usr/sbin/logread' : null)); + +if(!logreadCmd) { + die('Error! Logread not found!'); +} + +function getCmdOutput(cmd, number) { + let ret = ''; + const fd = popen(cmd, 'r'); + if(fd) { + let c = fd.read('all'); + fd.close(); + if(c) { + c = trim(c); + ret = number ? int(c) : c; + } + } + return ret; +} + +const methods = { + getSyslogSize: { + call: function() { + return { 'bytes': getCmdOutput(logreadCmd + ' | wc -c', true) }; + }, + }, + + getSyslogHash: { + call: function() { + return { 'hash': getCmdOutput(logreadCmd + ' -t -l 1') }; + }, + }, + + getDmesgSize: { + call: function() { + return { 'bytes': getCmdOutput(dmesgCmd + ' | wc -c', true) }; + }, + }, + + getDmesgHash: { + call: function() { + return { 'hash': getCmdOutput(dmesgCmd + ' | tail -n 1') }; + }, + }, + + getLogfileSize: { + args: { fpath: 'fpath' }, + call: function(request) { + let ret = ''; + const path = request.args?.fpath; + if(path) { + ret = stat(path)?.size; + } + return { 'bytes': ret ?? '' }; + }, + }, +}; + +return { 'luci.log-viewer': methods }; diff --git a/luci-app-log/screenshots/01.jpg b/luci-app-log/screenshots/01.jpg new file mode 100644 index 00000000..68a0fa9b Binary files /dev/null and b/luci-app-log/screenshots/01.jpg differ diff --git a/luci-app-log/screenshots/02.jpg b/luci-app-log/screenshots/02.jpg new file mode 100644 index 00000000..37359f87 Binary files /dev/null and b/luci-app-log/screenshots/02.jpg differ diff --git a/luci-app-log/screenshots/03.jpg b/luci-app-log/screenshots/03.jpg new file mode 100644 index 00000000..d3bd850d Binary files /dev/null and b/luci-app-log/screenshots/03.jpg differ diff --git a/luci-app-log/screenshots/04.jpg b/luci-app-log/screenshots/04.jpg new file mode 100644 index 00000000..22698381 Binary files /dev/null and b/luci-app-log/screenshots/04.jpg differ diff --git a/luci-app-nvr/Makefile b/luci-app-nvr/Makefile new file mode 100644 index 00000000..3175dba4 --- /dev/null +++ b/luci-app-nvr/Makefile @@ -0,0 +1,36 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-nvr +PKG_VERSION:=20230818 + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-app-nvr + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI Support for Network Video Recorder + PKGARCH:=all + DEPENDS:=+ffmpeg +endef + +define Build/Prepare + $(foreach po,$(wildcard ${CURDIR}/luasrc/i18n/*.po), \ + po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));) +endef + +define Build/Compile +endef + +define Package/luci-app-nvr/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci + cp -pR ./luasrc/* $(1)/usr/lib/lua/luci + $(INSTALL_DIR) $(1)/usr/nvr + $(INSTALL_BIN) ./files/nvr/* $(1)/usr/nvr + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/nvr.conf $(1)/etc/config/nvr + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/nvr.init $(1)/etc/init.d/nvr +endef + +$(eval $(call BuildPackage,luci-app-nvr)) diff --git a/luci-app-nvr/files/nvr.conf b/luci-app-nvr/files/nvr.conf new file mode 100644 index 00000000..737ee7f3 --- /dev/null +++ b/luci-app-nvr/files/nvr.conf @@ -0,0 +1,15 @@ + +config nvr 'config' + option loop_write '1' + option fulldisk '1' + option storage_directory '/mnt/sda1/camera' + option disk_name 'sda1' + option disk_usage '85%' + option rec_time '600' + option storage_size '1000' + option enable_audio '1' + option enabled '0' + option nvr_sourcelist 'hikvision' + option hik_list 'none' + option total_days '30' + diff --git a/luci-app-nvr/files/nvr.init b/luci-app-nvr/files/nvr.init new file mode 100755 index 00000000..c8054a81 --- /dev/null +++ b/luci-app-nvr/files/nvr.init @@ -0,0 +1,36 @@ +#!/bin/sh /etc/rc.common + +START=99 +USE_PROCD=1 + +PROG="/usr/nvr/nvrrecord" + +init_conf() { + config_load "nvr" + config_get "enabled" "config" "enabled" +} + + +start_service() { + init_conf + [ "${enabled}" == "1" ] || exit 0 + + procd_open_instance nvr + procd_set_param command $PROG + procd_set_param respawn + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "nvr" +} + +reload_service() { + stop + start +} + +stop_service() { + init_conf + service_stop $PROG +} diff --git a/luci-app-nvr/files/nvr/nvrcommon b/luci-app-nvr/files/nvr/nvrcommon new file mode 100755 index 00000000..82413d1d --- /dev/null +++ b/luci-app-nvr/files/nvr/nvrcommon @@ -0,0 +1,170 @@ +#!/bin/sh + +_source="$(uci get nvr.config.nvr_sourcelist)" +_directory="$(uci get nvr.config.storage_directory | sed 's/\/$//')" +_disk_name="$(uci get nvr.config.disk_name)" +_rec_time="$(uci get nvr.config.rec_time)" +_size="$(expr $(uci get nvr.config.storage_size) \* 1024)" +_total_days="$(uci get nvr.config.total_days)" +_loop_write="$(uci get nvr.config.loop_write)" +_fulldisk="$(uci get nvr.config.fulldisk)" +_disk_usage="$(echo $(uci get nvr.config.disk_usage) | cut -d '%' -f1)" +_enable_audio="$(uci get nvr.config.enable_audio)" +_all_clients="" +_disk="" + +function detect_disk() { + if [ "$(df -hT | grep "${_disk_name}")" = "" ];then + _disk="X" + else + _disk="" + fi +} + +function test_totaldays() { + _dir_nums="$(ls -l $_directory | grep "^d" | wc -l)" + if [ "$_total_days" -lt "$_dir_nums" ];then + _first_dir="$(ls -l $_directory | grep "^d" | head -n1 | awk '{print$9}')" + rm -rf $_directory/$_first_dir + fi +} + +function count_filesize() { + _client_dir="$(ls -l $_directory/$_day_target | grep "^d" | awk '{print$9}')" + for c in $_client_dir;do + _single_filesize="$(ls -l $_directory/$_day_target/$c | head -n1 | awk '{print$5}')" + if [ "$_single_filesize" = "" ];then + _single_filesize=0 + else + _single_filesize="$(expr $_single_filesize / 1024)" + fi + _nums_clientdir_file="$(ls -l $_directory/$_day_target/$c | grep "^-" | wc -l)" + _total_filesize="$(expr $_single_filesize \* $_nums_clientdir_file + $_total_filesize)" + done +} + +function search_daydir_head() { + _day_target="$(ls -l $_directory | grep "^d" | head -n1 | awk '{print$9}')" + count_filesize +} + +function search_daydir_tail() { + _day_target="$(ls -l $_directory | grep "^d" | tail -n1 | awk '{print$9}')" + count_filesize +} + +function search_daydir_midone() { + _day_target="$(ls -l $_directory | grep "^d" | head -n2 | tail -n1 | awk '{print$9}')" + count_filesize +} + +function test_dir_space() { + if [ "$(df -h | grep $_disk_name | awk '{print$5}' | head -n 1 | cut -d '%' -f1)" -ge "$_disk_usage" ];then + _dir_space="$(expr $_size + 9999)" + else + _daydir_num="$(ls -l $_directory | grep "^d" | wc -l)" + if [ "$_daydir_num" -ge 3 ];then + _day_target="$(ls -l $_directory | grep "^d" | head -n2 | tail -n1 | awk '{print$9}')" + _mid_daydir_num="$(expr $_daydir_num - 2)" + search_daydir_midone + _total_filesize="$(expr $_total_filesize \* $_mid_daydir_num)" + search_daydir_head + search_daydir_tail + elif [ "$_daydir_num" -eq 2 ];then + search_daydir_head + search_daydir_tail + else + search_daydir_head + fi + _dir_space=$_total_filesize + fi +} + +function test_loopwrite() { + if [ "$_loop_write" -eq 1 ];then + _total_filesize=0 + if [ "$_fulldisk" -eq 1 ];then + if [ "$(df -h | grep $_disk_name | awk '{print$5}' | head -n 1 | cut -d '%' -f1)" -ge "$_disk_usage" ];then + _dir_space="$(expr $_size + 9999)" + else + _dir_space=1 + fi + else + test_dir_space + fi + while [ "$_dir_space" -ge "$_size" ];do + _first_dir="$(ls -l $_directory | grep "^d" | head -n1 | awk '{print$9}')" + _action_dir="$(ls -l $_directory/$_first_dir | grep "^d" | awk '{print$9}')" + for i in $_action_dir;do + rm "$_directory/$_first_dir/$i/$(ls -l $_directory/$_first_dir/$i | grep "^-" | head -n1 | awk '{print$9}')" + if [ "$(ls -l $_directory/$_first_dir/$i | grep "^-")" = "" ];then + rm -rf $_directory/$_first_dir/$i + fi + if [ "$(ls -l $_directory | grep "^d" | wc -l )" -gt 1 ];then + if [ "$(du -s $_directory/$_first_dir | awk '{print$1}')" -le "$(expr $_totalnum \* 4 + 4)" ];then + rm -rf $_directory/$_first_dir + break + fi + fi + done + _total_filesize=0 + if [ "$_fulldisk" -eq 1 ];then + if [ "$(df -h | grep $_disk_name | awk '{print$5}' | head -n 1 | cut -d '%' -f1)" -ge "$_disk_usage" ];then + _dir_space="$(expr $_size + 9999)" + else + _dir_space=1 + fi + else + test_dir_space + fi + done + else + echo "do not test looping write!" + fi +} + +case $_source in + hikvision) + _hik_user="$(uci get nvr.config.hik_user)" + _hik_pass="$(uci get nvr.config.hik_pass)" + if [ "$(uci get nvr.config.hik_list)" = "one-by-one" ];then + _all_clients=$(uci get nvr.config.hikpush) + _totalnum="$(echo $_all_clients | sed 's/ /\n/g' | wc -l)" + else + _ipstart="$(uci get nvr.config.hik_batch_start)" + _ipend="$(uci get nvr.config.hik_batch_end)" + _startnum="$(echo $_ipstart | cut -d '.' -f4)" + _totalnum=$(expr $(echo $_ipend | cut -d '.' -f4) - $(echo $_ipstart | cut -d '.' -f4) + 1) + for i in $(seq 1 $_totalnum);do + _all_clients="$_all_clients $(echo $_ipstart | sed 's/[0-9]*$//')$(expr $_startnum + $i - 1)" + done + fi + ;; + tplink) + _tplink_user="$(uci get nvr.config.tplink_user)" + _tplink_pass="$(uci get nvr.config.tplink_pass)" + if [ "$(uci get nvr.config.tplink_list)" = "one-by-one" ];then + _all_clients=$(uci get nvr.config.tplinkpush) + _totalnum="$(echo $_all_clients | sed 's/ /\n/g' | wc -l)" + else + _ipstart="$(uci get nvr.config.tplink_batch_start)" + _ipend="$(uci get nvr.config.tplink_batch_end)" + _startnum="$(echo $_ipstart | cut -d '.' -f4)" + _totalnum=$(expr $(echo $_ipend | cut -d '.' -f4) - $(echo $_ipstart | cut -d '.' -f4) + 1) + for i in $(seq 1 $_totalnum);do + _all_clients="$_all_clients $(echo $_ipstart | sed 's/[0-9]*$//')$(expr $_startnum + $i - 1)" + done + fi + ;; + rtmp-url) + _all_clients=$(uci get nvr.config.rtmppush) + _totalnum="$(echo $_all_clients | sed 's/ /\n/g' | wc -l)" + ;; + multiple-types) + _all_clients=$(uci get nvr.config.multipush) + _totalnum="$(echo $_all_clients | sed 's/ /\n/g' | wc -l)" + ;; + none) + exit 0 + ;; +esac diff --git a/luci-app-nvr/files/nvr/nvrpush b/luci-app-nvr/files/nvr/nvrpush new file mode 100755 index 00000000..b2771bc5 --- /dev/null +++ b/luci-app-nvr/files/nvr/nvrpush @@ -0,0 +1,16 @@ +#!/bin/sh +. /usr/nvr/nvrcommon + +_app_prefix="$(uci get nvr.config.rtmp_server_app)" + +for a in $_all_clients;do + if [ "$_source" = "hikvision" ];then + ffmpeg -i "rtsp://${_hik_user}:${_hik_pass}@${a}:554/h264/ch1/main/av_stream" -c copy -f flv "${_app_prefix}/${a}" & + elif [ "$_source" = "tplink" ];then + ffmpeg -i "rtsp://${_tplink_user}:${_tplink_pass}@${a}:554/stream1" -c copy -f flv "${_app_prefix}/${a}" & + elif [ "$_source" = "rtmp-url" ];then + ffmpeg -i $a -c copy -f flv "${_app_prefix}/${a}" & + elif [ "$_source" = "multiple-types" ];then + ffmpeg -i $a -c copy -f flv "${_app_prefix}/${a}" & + fi +done diff --git a/luci-app-nvr/files/nvr/nvrrecord b/luci-app-nvr/files/nvr/nvrrecord new file mode 100755 index 00000000..5c57b80d --- /dev/null +++ b/luci-app-nvr/files/nvr/nvrrecord @@ -0,0 +1,42 @@ +#!/bin/sh +. /usr/nvr/nvrcommon + +function main() { + test_totaldays + test_loopwrite + for a in $_all_clients;do + theday="$(date +%Y-%m-%d)" + thedir=$(echo $a | sed 's/\///g') + if [ ! -d "$_directory/$theday/$thedir" ];then + mkdir -p "$_directory/$theday/$thedir" + fi + if [ "$_source" = "hikvision" ];then + _input="rtsp://${_hik_user}:${_hik_pass}@${a}:554/h264/ch1/main/av_stream" + elif [ "$_source" = "tplink" ];then + _input="rtsp://${_tplink_user}:${_tplink_pass}@${a}:554/stream1" + elif [ "$_source" = "rtmp-url" ];then + _input="$a" + elif [ "$_source" = "multiple-types" ];then + _input="$a" + fi + if [ ! -f "${_directory}/${theday}/${thedir}/${thename}.*" ];then + kill -9 "$(ps -w | grep ffmpeg | grep "${_input}" | grep -v grep | grep -v "\-f flv")" + fi + thename="$(date +%Y-%m-%d-%H:%M:%S)" + if [ "$_enable_audio" -eq 1 ];then + ffmpeg -i "${_input}" -c copy -t ${_rec_time} "${_directory}/${theday}/${thedir}/${thename}.mkv" & + else + ffmpeg -i "${_input}" -vcodec copy -an -t ${_rec_time} "${_directory}/${theday}/${thedir}/${thename}.mp4" & + fi + done + sleep $(expr ${_rec_time} - 6) +} + +while true;do + detect_disk + if [ "${_disk}" = "" ];then + main + else + sleep 10 + fi +done diff --git a/luci-app-nvr/files/nvr/nvrstart b/luci-app-nvr/files/nvr/nvrstart new file mode 100755 index 00000000..a0c882eb --- /dev/null +++ b/luci-app-nvr/files/nvr/nvrstart @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ "$(uci get nvr.config.enabled)" -eq 1 ];then + /etc/init.d/nvr enable 2>&1 & + /etc/init.d/nvr start 2>&1 & +else + /usr/nvr/nvrrecord 2>&1 & +fi + + diff --git a/luci-app-nvr/files/nvr/nvrstop b/luci-app-nvr/files/nvr/nvrstop new file mode 100755 index 00000000..a9ca0b63 --- /dev/null +++ b/luci-app-nvr/files/nvr/nvrstop @@ -0,0 +1,9 @@ +#!/bin/sh +. /usr/nvr/nvrcommon + +/etc/init.d/nvr stop +kill -9 $(busybox ps | grep nvrrecord | grep -v grep | awk '{print$1}') 2>&1 & + +for i in $_all_clients;do + kill -9 $(ps -w | grep $i | grep -v grep | grep -v "\-f flv" | awk '{print$1}') 2>&1 & +done diff --git a/luci-app-nvr/luasrc/controller/nvr.lua b/luci-app-nvr/luasrc/controller/nvr.lua new file mode 100644 index 00000000..9960c440 --- /dev/null +++ b/luci-app-nvr/luasrc/controller/nvr.lua @@ -0,0 +1,24 @@ +module("luci.controller.nvr",package.seeall) + +function index() + if not nixio.fs.access("/etc/config/nvr") then + return + end + + local page = entry({"admin", "services", "nvr"}, cbi("nvr"), _("NVR"),20) + page.dependent = true + entry({"admin", "services", "nvr", "status"}, call("nvr_status")).leaf = true +end + +function nvr_status() + local nvrrecord = luci.sys.exec("ps -w | grep nvrrecord | grep -v grep | awk '{print$1}' 2>/dev/null ") + local pushpid = luci.sys.exec("ps -w | grep 'f flv rtmp' | grep -v grep | awk '{print$1}' 2>/dev/null ") + + local e = { + nvrrecord = nvrrecord, + pushpid = pushpid + } + + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-nvr/luasrc/i18n/nvr.zh-cn.lmo b/luci-app-nvr/luasrc/i18n/nvr.zh-cn.lmo new file mode 100644 index 00000000..4b274fe7 Binary files /dev/null and b/luci-app-nvr/luasrc/i18n/nvr.zh-cn.lmo differ diff --git a/luci-app-nvr/luasrc/model/cbi/nvr.lua b/luci-app-nvr/luasrc/model/cbi/nvr.lua new file mode 100644 index 00000000..b978aa3e --- /dev/null +++ b/luci-app-nvr/luasrc/model/cbi/nvr.lua @@ -0,0 +1,209 @@ +m = Map("nvr", translate("The luci-app for instead of network video recorder hardware.")) + +m:section(SimpleSection).template = "nvr_status" + +s = m:section(TypedSection, "nvr", "", translate("Network Video Recorder")) +s.anonymous = true +s.addremove = false + +s:tab("nvr", translate("Basic setting")) +enabled = s:taboption("nvr", Flag, "enabled", translate("Record daemon")) +enabled.rmempty = false + +nvr_sourcelist = s:taboption("nvr", ListValue, "nvr_sourcelist", translate("camera source")) +nvr_sourcelist.placeholder = "none" +nvr_sourcelist:value("none") +nvr_sourcelist:value("hikvision",translate("hikvision")) +nvr_sourcelist:value("tplink",translate("tplink")) +nvr_sourcelist:value("rtmp-url",translate("rtmp url")) +nvr_sourcelist:value("multiple-types",translate("multiple types")) +nvr_sourcelist.default = "none" +nvr_sourcelist.rmempty = true + +hik_list = s:taboption("nvr", ListValue, "hik_list", translate("camera list")) +hik_list:depends( "nvr_sourcelist", "hikvision" ) +hik_list.placeholder = "none" +hik_list:value("none") +hik_list:value("one-by-one",translate("one by one")) +hik_list:value("batch-add",translate("batch add")) +hik_list.default = "none" +hik_list.rmempty = true + +hik_addonebyone = s:taboption("nvr", DynamicList, "hikpush") +hik_addonebyone:depends( "hik_list", "one-by-one" ) +hik_addonebyone.title = translate("camera ip address") +hik_addonebyone.datatype = "ipaddr" +hik_addonebyone.placeholder = "192.168.1.64" +hik_addonebyone.description = translate("click + to continue") + +hik_batch_start=s:taboption("nvr", Value, "hik_batch_start", translate("start of the ip address")) +hik_batch_start:depends( "hik_list", "batch-add" ) +hik_batch_start.datatype = "ipaddr" +hik_batch_start.placeholder = "192.168.1.64" +hik_batch_start.rmempty = true + +hik_batch_end=s:taboption("nvr", Value, "hik_batch_end", translate("end of the ip address")) +hik_batch_end:depends( "hik_list", "batch-add" ) +hik_batch_end.datatype = "ipaddr" +hik_batch_end.placeholder = "192.168.1.200" +hik_batch_end.rmempty = true + +hik_user=s:taboption("nvr", Value, "hik_user", translate("camera username")) +hik_user:depends( "nvr_sourcelist", "hikvision" ) +hik_user.datatype = "string" +hik_user.placeholder = "username" +hik_user.rmempty = true + +hik_pass=s:taboption("nvr", Value, "hik_pass", translate("camera password")) +hik_pass:depends( "nvr_sourcelist", "hikvision" ) +hik_pass.datatype = "string" +hik_pass.placeholder = "password" +hik_pass.rmempty = true + +tplink_list = s:taboption("nvr", ListValue, "tplink_list", translate("camera list")) +tplink_list:depends( "nvr_sourcelist", "tplink" ) +tplink_list.placeholder = "none" +tplink_list:value("none") +tplink_list:value("one-by-one",translate("one by one")) +tplink_list:value("batch-add",translate("batch add")) +tplink_list.default = "none" +tplink_list.rmempty = true + +tplink_addonebyone = s:taboption("nvr", DynamicList, "tplinkpush") +tplink_addonebyone:depends( "tplink_list", "one-by-one" ) +tplink_addonebyone.title = translate("camera ip address") +tplink_addonebyone.datatype = "ipaddr" +tplink_addonebyone.placeholder = "192.168.1.60" +tplink_addonebyone.description = translate("click + to continue") + +tplink_batch_start=s:taboption("nvr", Value, "tplink_batch_start", translate("start of the ip address")) +tplink_batch_start:depends( "tplink_list", "batch-add" ) +tplink_batch_start.datatype = "ipaddr" +tplink_batch_start.placeholder = "192.168.1.60" +tplink_batch_start.rmempty = true + +tplink_batch_end=s:taboption("nvr", Value, "tplink_batch_end", translate("end of the ip address")) +tplink_batch_end:depends( "tplink_list", "batch-add" ) +tplink_batch_end.datatype = "ipaddr" +tplink_batch_end.placeholder = "192.168.1.200" +tplink_batch_end.rmempty = true + +tplink_user=s:taboption("nvr", Value, "tplink_user", translate("camera username")) +tplink_user:depends( "nvr_sourcelist", "tplink" ) +tplink_user.datatype = "string" +tplink_user.placeholder = "username" +tplink_user.rmempty = true + +tplink_pass=s:taboption("nvr", Value, "tplink_pass", translate("camera password")) +tplink_pass:depends( "nvr_sourcelist", "tplink" ) +tplink_pass.datatype = "string" +tplink_pass.placeholder = "password" +tplink_pass.rmempty = true + +rtmpurl_add = s:taboption("nvr", DynamicList, "rtmppush") +rtmpurl_add:depends( "nvr_sourcelist", "rtmp-url" ) +rtmpurl_add.title = translate("rtmp url address") +rtmpurl_add.datatype = "string" +rtmpurl_add.placeholder = "rtmp://ip:1935/live/camera001" +rtmpurl_add.description = translate("adding one by one") + +multi_info1 = s:taboption("nvr", DummyValue, "multi_info1", translate("information")) +multi_info1:depends( "nvr_sourcelist", "multiple-types" ) +multi_info1.description = translate("hikvision: rtsp://username:password@ip:554/h264/ch1/main/av_stream") +multi_info2 = s:taboption("nvr", DummyValue, "multi_info2", translate("information")) +multi_info2:depends( "nvr_sourcelist", "multiple-types" ) +multi_info2.description = translate("tplink: rtsp://username:password@ip:554/stream1") + +multi_add = s:taboption("nvr", DynamicList, "multipush") +multi_add:depends( "nvr_sourcelist", "multiple-types" ) +multi_add.title = translate("rtsp/rtmp/http url address") +multi_add.datatype = "string" +multi_add.placeholder = "rtmp://ip:1935/live/camera001" +multi_add.description = translate("adding one by one") + +storage_directory=s:taboption("nvr", Value, "storage_directory", translate("data storage directory")) +storage_directory.rmempty = false +storage_directory.datatype = "string" +storage_directory.placeholder = "/mnt/sda1/camera" +storage_directory.default = "/mnt/sda1/camera" + +disk_name=s:taboption("nvr", Value, "disk_name", translate("storage disk name")) +disk_name.rmempty = false +disk_name.datatype = "string" +disk_name.placeholder = "sda1" + +disk_usage=s:taboption("nvr", Value, "disk_usage", translate("set maximum disk space usage")) +disk_usage.rmempty = false +disk_usage.datatype = "string" +disk_usage.placeholder = "85%" + +rec_time=s:taboption("nvr", Value, "rec_time", translate("single file duration")) +rec_time.rmempty = false +rec_time.datatype = "uinteger" +rec_time.placeholder = "300" +rec_time.default = "300" +rec_time.description = translate("in seconds") + +storage_size=s:taboption("nvr", Value, "storage_size", translate("allocate total storage space")) +storage_size.rmempty = false +storage_size.datatype = "uinteger" +storage_size.placeholder = "1000" +storage_size.default = "1000" +storage_size.description = translate("in megabytes") + +total_days=s:taboption("nvr", Value, "total_days", translate("total days of videos")) +total_days.rmempty = false +total_days.datatype = "uinteger" +total_days.placeholder = "30" +total_days.default = "30" + +loop_write=s:taboption("nvr", Flag, "loop_write", translate("looping writting to disk")) +loop_write.rmempty = false + +fulldisk=s:taboption("nvr", Flag, "fulldisk", translate("only detect disk space")) +fulldisk.rmempty = false + +enable_audio=s:taboption("nvr", Flag, "enable_audio", translate("enable audio")) +enable_audio.rmempty = false + +do_push=s:taboption("nvr", Flag, "do_push", translate("whether to push stream")) + +rtmp_server_app=s:taboption("nvr", Value, "rtmp_server_app", translate("rtmp server application url")) +rtmp_server_app:depends( "do_push", "1" ) +rtmp_server_app.rmempty = true +rtmp_server_app.datatype = "string" +rtmp_server_app.placeholder = "rtmp://ip:1935/application_name" + +s:tab("action", translate("Action")) + +recordaction=s:taboption("action", Button, "recoredaction", translate("One-click Record")) +recordaction.rmempty = true +recordaction.inputstyle = "apply" +function recordaction.write(self, section) + luci.util.exec("/usr/nvr/nvrstart 2>&1 &") +end + +recordstop=s:taboption("action", Button, "recordstop", translate("One-click STOP Record")) +recordstop.rmempty = true +recordstop.inputstyle = "apply" +function recordstop.write(self, section) + luci.util.exec("/usr/nvr/nvrstop 2>&1 & ") +end + +pushaction=s:taboption("action", Button, "pushaction", translate("One-click Push stream")) +pushaction:depends( "do_push", "1" ) +pushaction.rmempty = true +pushaction.inputstyle = "apply" +function pushaction.write(self, section) + luci.util.exec("/usr/nvr/nvrpush >/dev/null 2>&1 &") +end + +pushstop = s:taboption("action", Button, "pushstop", translate("One-click STOP Push")) +pushstop:depends( "do_push", "1" ) +pushstop.rmempty = true +pushstop.inputstyle = "apply" +function pushstop.write(self, section) + luci.util.exec("kill -9 $(ps -w | grep 'f flv rtmp' | grep -v grep | awk '{print$1}' 2>&1 &)") +end + +return m diff --git a/luci-app-nvr/luasrc/view/nvr_status.htm b/luci-app-nvr/luasrc/view/nvr_status.htm new file mode 100644 index 00000000..bb674178 --- /dev/null +++ b/luci-app-nvr/luasrc/view/nvr_status.htm @@ -0,0 +1,26 @@ + + +
+

+ <%:Collecting data...%> +

+
diff --git a/luci-app-nvr/nvr.zh-cn.po b/luci-app-nvr/nvr.zh-cn.po new file mode 100644 index 00000000..b1bbd114 --- /dev/null +++ b/luci-app-nvr/nvr.zh-cn.po @@ -0,0 +1,126 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "NVR" +msgstr "ç½‘ç»œè§†é¢‘å½•åƒæœº" + +msgid "The luci-app for instead of network video recorder hardware." +msgstr "ä»£æ›¿ç½‘ç»œå½•åƒæœºç¡¬ä»¶çš„luci应用程åº" + +msgid "Network Video Recorder" +msgstr "ç½‘ç»œè§†é¢‘å½•åƒæœº" + +msgid "Basic setting" +msgstr "基本设置" + +msgid "Record daemon" +msgstr "å¼€å¯å½•åƒå®ˆæŠ¤è¿›ç¨‹" + +msgid "camera source" +msgstr "æ‘„åƒæœºæº" + +msgid "hikvision" +msgstr "海康å¨è§†" + +msgid "rtmp url" +msgstr "rtmp视频æºurl" + +msgid "multiple types" +msgstr "多ç§ç±»åž‹è§†é¢‘æº" + +msgid "camera list" +msgstr "æ‘„åƒæœºåˆ—表" + +msgid "one by one" +msgstr "é€ä¸ªæ·»åŠ " + +msgid "batch add" +msgstr "æ‰¹é‡æ·»åŠ " + +msgid "camera ip address" +msgstr "æ‘„åƒæœºip地å€" + +msgid "click + to continue" +msgstr "å•击+ç»§ç»­" + +msgid "start of the ip address" +msgstr "èµ·å§‹çš„ip地å€" + +msgid "end of the ip address" +msgstr "结尾的ip地å€" + +msgid "camera username" +msgstr "æ‘„åƒæœºç”¨æˆ·å" + +msgid "camera password" +msgstr "æ‘„åƒæœºå¯†ç " + +msgid "rtmp url address" +msgstr "rtmp视频æºurl地å€" + +msgid "hikvision: rtsp://username:password@ip:554/h264/ch1/main/av_stream" +msgstr "海康å¨è§†ç›‘控urlè§†é¢‘æºæ ¼å¼: rtsp://username:password@ip:554/h264/ch1/main/av_stream" + +msgid "tplink: rtsp://username:password@ip:554/stream1" +msgstr "tplink监控urlè§†é¢‘æºæ ¼å¼: rtsp://username:password@ip:554/stream1" + +msgid "rtsp/rtmp/http url address" +msgstr "rtsp/rtmp/http视频æºurl地å€" + +msgid "adding one by one" +msgstr "é€ä¸ªæ·»åŠ " + +msgid "data storage directory" +msgstr "æ•°æ®å­˜å‚¨ç›®å½•" + +msgid "storage disk name" +msgstr "存储数æ®çš„ç£ç›˜å" + +msgid "set maximum disk space usage" +msgstr "设置最大ç£ç›˜ç©ºé—´å ç”¨çއ" + +msgid "single file duration" +msgstr "æ¯ä¸ªæ–‡ä»¶çš„æ—¶é•¿" + +msgid "in seconds" +msgstr "以秒为å•ä½" + +msgid "allocate total storage space" +msgstr "åˆ†é…æ€»å­˜å‚¨ç©ºé—´" + +msgid "in megabytes" +msgstr "以兆字节为å•ä½ï¼ˆM)" + +msgid "total days of videos" +msgstr "循环ä¿å­˜è§†é¢‘的总天数" + +msgid "looping writting to disk" +msgstr "å¼€å¯å¾ªçޝ写入ç£ç›˜" + +msgid "only detect disk space" +msgstr "仅检测整个ç£ç›˜ç©ºé—´" + +msgid "enable audio" +msgstr "å¼€å¯å½•音" + +msgid "whether to push stream" +msgstr "æ˜¯å¦æŽ¨æµ" + +msgid "rtmp server application url" +msgstr "rtmpæœåŠ¡å™¨åº”ç”¨ç¨‹åºurl" + +msgid "Action" +msgstr "动作" + +msgid "One-click Record" +msgstr "一键录制监控视频" + +msgid "One-click STOP Record" +msgstr "ä¸€é”®åœæ­¢å½•制" + +msgid "One-click Push stream" +msgstr "一键推æµ" + +msgid "One-click STOP Push" +msgstr "ä¸€é”®åœæ­¢æŽ¨æµ" + diff --git a/luci-app-openvpn-server-client/Makefile b/luci-app-openvpn-server-client/Makefile new file mode 100644 index 00000000..3dd6ec16 --- /dev/null +++ b/luci-app-openvpn-server-client/Makefile @@ -0,0 +1,22 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for OpenVPN Server +LUCI_DEPENDS:=+openvpn-openssl +openvpn-easy-rsa +LUCI_PKGARCH:=all +PKG_NAME:=luci-app-openvpn-server-client +PKG_VERSION:=6.0 +PKG_RELEASE:=3 +MAINTAINER:=lunatickochiya <125438787@qq.com> + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + + + diff --git a/luci-app-openvpn-server-client/luasrc/controller/openvpn-server.lua b/luci-app-openvpn-server-client/luasrc/controller/openvpn-server.lua new file mode 100755 index 00000000..ec54f48c --- /dev/null +++ b/luci-app-openvpn-server-client/luasrc/controller/openvpn-server.lua @@ -0,0 +1,35 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2025 LunaticKochiya<125438787@qq.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- +module("luci.controller.openvpn-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/openvpn") then + return + end + + entry({"admin", "services", "openvpn-server"},firstchild(), _("OpenVPN Server"), 1).dependent = true + + entry({"admin", "services", "openvpn-server", "general"}, cbi("openvpn-server/openvpn-server"), _("OpenVPN Server"), 1).leaf = true + entry({"admin", "services", "openvpn-server", "client"},cbi("openvpn-server/openvpn-server_ovpn"), _("Client"), 2).leaf = true + entry({"admin", "services", "openvpn-server", "log"},form("openvpn-server/openvpn-server_run_log"), _("Running log"), 3).leaf = true + + entry({"admin", "services", "openvpn-server","status"},call("act_status")).leaf=true +end + +function act_status() + local e={} + e.running=luci.sys.call("pgrep openvpn >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server.lua b/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server.lua new file mode 100755 index 00000000..54fcfc31 --- /dev/null +++ b/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server.lua @@ -0,0 +1,274 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2025 LunaticKochiya<125438787@qq.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- + +--require("luci.tools.webadmin") + +local uci = require "luci.model.uci".cursor() +local sys = require "luci.sys" + +local function get_openvpn_info() + local version_str = sys.exec("openvpn --version 2>/dev/null | head -n1") + local full_output = sys.exec("openvpn --version 2>/dev/null") + + local major, minor, patch = version_str:match("OpenVPN%s+(%d+)%.(%d+)%.(%d+)") + if not (major and minor and patch) then + return nil, nil, nil, false + end + + local lzo_supported = full_output:match("%[LZO%]") ~= nil + + return tonumber(major), tonumber(minor), tonumber(patch), lzo_supported +end + +local major, minor, patch, lzo = get_openvpn_info() + +mp = Map("openvpn", "OpenVPN Server",translate("An easy config OpenVPN Server Web-UI")) + +mp:section(SimpleSection).template = "openvpn/openvpn_status" + +s = mp:section(TypedSection, "openvpn") +s.anonymous = true +s.addremove = false + + +s.filter = function(self, section) + return section:match("^myvpn") ~= nil +end + +s:tab("basic", translate("Base Setting")) + +o = s:taboption("basic", Flag, "enabled", translate("Enable")) + +port = s:taboption("basic", Value, "port", translate("Port")) +port.datatype = "range(1,65535)" + +ddns = s:taboption("basic", Value, "ddns", translate("WAN DDNS or IP")) +ddns.datatype = "string" +ddns.default = "exmple.com" +ddns.rmempty = false + +localnet = s:taboption("basic", Value, "server", translate("Client Network")) +localnet.datatype = "string" +localnet.description = translate("VPN Client Network IP with subnet") + +proto = s:taboption("basic",Value,"proto", translate("proto")) +proto.datatype = "string" +proto:value("tcp4") +proto:value("udp4") +proto:value("tcp6") +proto:value("udp6") +proto.default ="tcp4" + +if (major > 2) or (major == 2 and minor >= 6) then +disable_dco = s:taboption("basic",Flag,"disable_dco", translate("disable dco")) +disable_dco.description = translate("Disabling DCO provides better compatibility but disables acceleration.") +end + +if (major > 2) or (major == 2 and minor >= 5) then +allow_compression = s:taboption("basic",Value,"allow_compression", translate("Allow Compression")) +allow_compression.datatype = "string" +allow_compression:value("asym") +allow_compression:value("yes") +allow_compression:value("no") +allow_compression.default="asym" +allow_compression.description = translate("Allow compression, DCO can only be used when set to NO. asym is compatible mode.") + +push_peer_info = s:taboption("basic",Flag,"push_peer_info", translate("push peer info")) +push_peer_info.description = translate("This will allow the server to know more info about the client like HWADDR, very useful for managing IoT devices.") + +end + +if lzo then +comp_lzo = s:taboption("basic",Value,"comp_lzo", translate("comp_lzo")) +comp_lzo.datatype = "string" +comp_lzo:value("adaptive") +comp_lzo:value("yes") +comp_lzo:value("no") +if (major > 2) or (major == 2 and minor >= 5) then +comp_lzo:depends("allow_compression", "yes") +comp_lzo:depends("allow_compression", "asym") +comp_lzo:depends("comp_lzo", "yes") +comp_lzo:depends("comp_lzo", "adaptive") +comp_lzo.default="adaptive" +else +comp_lzo:depends("comp_lzo", "yes") +comp_lzo:depends("comp_lzo", "adaptive") +comp_lzo.default="adaptive" +end +comp_lzo.description = translate("Using LZO compression, it does not support versions above 2.5.X, does not support DCO; if your version number is greater than this version, select NO to disable it.") +end + +auth_user_pass_verify = s:taboption("basic",Value,"auth_user_pass_verify", translate("user password verify")) +auth_user_pass_verify.datatype = "string" +auth_user_pass_verify.description = translate("Default: /etc/openvpn/server/checkpsw.sh via-env, leave it empty to disable") + +script_security = s:taboption("basic",Value,"script_security", translate("script_security: to use with user and password")) +script_security.datatype = "range(1,3)" +script_security:value("1") +script_security:value("2") +script_security:value("3") +script_security.description = translate("Default 3, leave it empty to disable") + +duplicate_cn = s:taboption("basic",Flag,"duplicate_cn", translate("duplicate_cn")) +duplicate_cn.description = translate("This option allows multiple clients to connect using the same certificate and key and assign different IP addresses") +client_to_client = s:taboption("basic",Flag,"client_to_client", translate("client-to-client")) +client_to_client.description = translate("Allow clients to see each other, otherwise multiple clients can only access the server and cannot connect to each other") +username_as_common_name = s:taboption("basic",Flag,"username_as_common_name", translate("username_as_common_name")) +username_as_common_name.description = translate("Use the UserName provided by the client as the Common Name") +client_cert_not_required = s:taboption("basic",Flag,"client_cert_not_required", translate("client_cert_not_required")) +client_cert_not_required.description = translate("After this option is enabled, the client does not need cert and key. If this option is not enabled, cert and key and user password double verification are required.") + +list = s:taboption("basic", DynamicList, "push") +list.title = translate("Client Settings") +list.datatype = "string" +list.description = translate("Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router") + + +local o +o = s:taboption("basic", Button,"certificate",translate("OpenVPN Client config file")) +o.inputtitle = translate("Download .ovpn file") +o.description = translate("If you use user password verification only, remember to delete the key and cert.") +o.inputstyle = "reload" +o.write = function() + luci.sys.call("sh /etc/genovpn.sh 2>&1 >/dev/null") + Download() +end + +s:tab("code", translate("Client code")) +local conf = "/etc/ovpnadd.conf" +local NXFS = require "nixio.fs" +o = s:taboption("code", TextValue, "conf") +o.description = translate("Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(conf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(conf, value:gsub("\r\n", "\n")) +end + +s:tab("passwordfile", translate("User and password")) +local pass = "/etc/openvpn/server/psw-file" +local NXFS = require "nixio.fs" +o = s:taboption("passwordfile", TextValue, "pass") +o.description = translate("Each line contains a pair of user and password, separated by a space") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(pass) or "" +end +o.write = function(self, section, value) + NXFS.writefile(pass, value:gsub("\r\n", "\n")) +end + +s:tab("checkpsw", translate("Authentication script")) +local checkpswconf = "/etc/openvpn/server/checkpsw.sh" +local NXFS = require "nixio.fs" +o = s:taboption("checkpsw", TextValue, "checkpswconf") +o.description = translate("Authentication script") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(checkpswconf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(checkpswconf, value:gsub("\r\n", "\n")) +end + +local pid = luci.util.exec("/usr/bin/pgrep openvpn") + +function openvpn_process_status() + local status = "OpenVPN is not running now " + + if pid ~= "" then + status = "OpenVPN is running with the PID " .. pid .. "" + end + + local status = { status=status } + local table = { pid=status } + return table +end + + + +function Download() + local t,e + t=nixio.open("/tmp/my.ovpn","r") + luci.http.header('Content-Disposition','attachment; filename="my.ovpn"') + luci.http.prepare_content("application/octet-stream") + while true do + e=t:read(nixio.const.buffersize) + if(not e)or(#e==0)then + break + else + luci.http.write(e) + end + end + t:close() + luci.http.close() +end + +t = mp:section(Table, openvpn_process_status()) +t.anonymous = true + +t:option(DummyValue, "status", translate("OpenVPN status")) + +if pid == "" then + start = t:option(Button, "_start", translate("Start")) + start.inputstyle = "apply" + function start.write(self, section) + luci.util.exec("uci set openvpn.myvpn.enabled=='1' && uci commit openvpn") + message = luci.util.exec("/etc/init.d/openvpn start 2>&1") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "services", "openvpn-server") .. "?message=" .. message + ) + end +else + stop = t:option(Button, "_stop", translate("Stop")) + stop.inputstyle = "reset" + function stop.write(self, section) + luci.util.exec("uci set openvpn.myvpn.enabled=='0' && uci commit openvpn") + luci.util.exec("/etc/init.d/openvpn stop") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "services", "openvpn-server") + ) + end +end + +local comp_lzo_val = uci:get("openvpn", "myvpn", "comp_lzo") + +function mp.on_after_commit(self) + os.execute("uci set firewall.openvpn.dest_port=$(uci get openvpn.myvpn.port) && uci commit firewall && /etc/init.d/firewall restart") + os.execute("/etc/init.d/openvpn restart") + if comp_lzo_val == "no" then + uci:delete("openvpn", "myvpn", "comp_lzo") + uci:commit("openvpn") + end +end + +gen = t:option(Button,"cert",translate("OpenVPN Cert")) +gen.inputstyle = "apply" +function gen.write(self, section) + luci.util.exec("/etc/openvpncert.sh") +end + +--local apply = luci.http.formvalue("cbi.apply") +--if apply then +-- os.execute("/etc/init.d/openvpn restart") +--end + +return mp diff --git a/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server_ovpn.lua b/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server_ovpn.lua new file mode 100755 index 00000000..2c77bcbf --- /dev/null +++ b/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server_ovpn.lua @@ -0,0 +1,180 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2025 LunaticKochiya<125438787@qq.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- +local NXFS = require "nixio.fs" +local sys = require "luci.sys" +local util = require "luci.util" + +local base_dir = "/etc/openvpn" + +local function get_config_path(identifier) + if identifier and identifier:match("^[a-zA-Z0-9_%-]+$") then + return base_dir .. "/" .. identifier .. ".conf" + end + return nil +end + +m2 = Map("openvpn", "OpenVPN Client", translate("Configuration for OpenVPN client instances. The instance name you provide becomes the UCI section name (e.g., 'client1' leads to `config openvpn 'client1'`).")) + +m2:section(SimpleSection).template = "openvpn/openvpn_status" + +sl = m2:section(TypedSection, "openvpn", translate("OpenVPN Client Instances")) +sl.title = translate("OpenVPN Client Instances") +sl.anonymous = false +sl.addremove = true +sl.description = translate("Enter a unique identifier (e.g., client1, client2) when adding an instance. This identifier is used for the UCI section name and the corresponding .conf file.") +sl.sortable = true + +sl.filter = function(self, section) + return section:match("^client") ~= nil +end + +sl:tab("base", translate("Base Settings")) +sl:tab("config_file", translate("Client Config File Content")) + +local o + +o = sl:taboption("base", Flag, "enabled", translate("Enable Instance")) +o.default = o.disabled +o.rmempty = false + +o = sl:taboption("base", Value, "config", translate("Config File Path")) +o.readonly = true +o.placeholder = translate("Auto-generated based on instance identifier") +o.datatype = "file" +o.rmempty = false + +o.cfgvalue = function(self, section) + return get_config_path(section) or translate("Invalid instance identifier.") +end + +o = sl:taboption("config_file", TextValue, "_config_content") +o.title = translate("OpenVPN Configuration (.ovpn/.conf)") +o.description = translate("Paste the content of the .ovpn or .conf file here. This will be saved to the path shown in 'Base Settings'.") +o.rows = 15 +o.wrap = "off" +o.rmempty = true + +o.cfgvalue = function(self, section) + local conf_file = get_config_path(section) + if conf_file then + return NXFS.readfile(conf_file) or "" + else + return "-- " .. translate("Cannot read file: Invalid instance identifier used for this section.") .. " --" + end +end + +o.write = function(self, section, value) + local conf_file = get_config_path(section) + if not conf_file then + luci.util.perror("OpenVPN: Invalid identifier '" .. tostring(section) .. "', cannot write config file.") + return + end + + if value and value ~= "" then + NXFS.writefile(conf_file, value:gsub("\r\n", "\n")) + self.map:set(section, "config", conf_file) + else + NXFS.remove(conf_file) + end +end + +o.remove = function(self, section) + local conf_file = get_config_path(section) + if conf_file then + NXFS.remove(conf_file) + end +end + +sl.on_remove = function(self, section) + local conf_file = get_config_path(section) + if conf_file then + local ok, err = NXFS.remove(conf_file) + if ok then + luci.util.perror("OpenVPN: Removed config file: " .. conf_file) + else + luci.util.perror("OpenVPN: Error removing config file " .. conf_file .. ": " .. tostring(err)) + end + end + TypedSection.on_remove(self, section) +end + +sp = m2:section(TypedSection, "openvpnpassword", translate("OpenVPN Client Authentication")) +sp.title = translate("OpenVPN Client Authentication") +sp.anonymous = false +sp.addremove = true +sp.description = translate("Configure authentication files for OpenVPN client instances.") +sp.sortable = true + +o = sp:option(Value, "pwdfile", translate("Authentication File Path")) +o.placeholder = translate("Enter the path for the authentication file (e.g., /etc/openvpn/password.txt)") +o.datatype = "string" +o.rmempty = false + +o = sp:option(TextValue, "_auth_content", translate("Authentication File Content")) +o.description = translate("Enter the content of the authentication file (e.g., username on the first line, password on the second line). This will be saved to the path shown above.") +o.rows = 5 +o.wrap = "off" +o.rmempty = true + +o.cfgvalue = function(self, section) + local pwdfile = self.map:get(section, "pwdfile") + if pwdfile then + return NXFS.readfile(pwdfile) or "" + else + return "-- " .. translate("Cannot read file: Invalid instance identifier used for this section.") .. " --" + end +end + +o.write = function(self, section, value) + local pwdfile = self.map:get(section, "pwdfile") + if not pwdfile then + luci.util.perror("OpenVPN: Invalid identifier '" .. tostring(section) .. "', cannot write authentication file.") + return + end + + if value and value ~= "" then + NXFS.writefile(pwdfile, value:gsub("\r\n", "\n")) + else + NXFS.remove(pwdfile) + end +end + +o.remove = function(self, section) + local pwdfile = self.map:get(section, "pwdfile") + if pwdfile then + NXFS.remove(pwdfile) + end +end + +sp.on_remove = function(self, section) + local pwdfile = self.map:get(section, "pwdfile") + if pwdfile then + local ok, err = NXFS.remove(pwdfile) + if ok then + luci.util.perror("OpenVPN: Removed authentication file: " .. pwdfile) + else + luci.util.perror("OpenVPN: Error removing authentication file " .. pwdfile .. ": " .. tostring(err)) + end + end + TypedSection.on_remove(self, section) +end + +m2.on_commit = function(self) + local result = sys.call("/etc/init.d/openvpn reload") + if result ~= 0 then + self.message = translate("Failed to reload OpenVPN service.") + end +end + +return m2 diff --git a/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server_run_log.lua b/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server_run_log.lua new file mode 100755 index 00000000..d6c02b6c --- /dev/null +++ b/luci-app-openvpn-server-client/luasrc/model/cbi/openvpn-server/openvpn-server_run_log.lua @@ -0,0 +1,83 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2025 LunaticKochiya<125438787@qq.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- +local fs = require "nixio.fs" +local conffile = "/var/openvpn.log" +local conffile_pass = "/etc/openvpn/openvpn-password.log" + +f = SimpleForm("logview") + +t1 = f:field(TextValue, "conf_file_log") +t1.rmempty = true +t1.rows = 20 +t1.css_style = "width: 95vw !important;" +function t1.cfgvalue() + return fs.readfile(conffile) or "" +end +t1.readonly = "readonly" +t1.description = "OpenVPN Log File" + +t2 = f:field(TextValue, "conf_logread") +t2.rmempty = true +t2.rows = 20 +t2.css_style = "width: 95vw !important;" +function t2.cfgvalue() + local log_output = "" + local handle = io.popen("logread | grep openvpn") + if handle then + log_output = handle:read("*a") + handle:close() + end + return log_output or "" +end +t2.readonly = "readonly" +t2.description = "OpenVPN Logread Output" + +t3 = f:field(TextValue, "conf_file_pass_log") +t3.rmempty = true +t3.rows = 20 +t3.css_style = "width: 95vw !important;" +function t3.cfgvalue() + return fs.readfile(conffile_pass) or "" +end +t3.readonly = "readonly" +t3.description = "OpenVPN Password Log File" + + + +local clear_btn = f:field(Button, "clear_pass_log") +clear_btn.title = "清空登陆日志" +clear_btn.inputstyle = "remove" +clear_btn.description = "点击清空上é¢å†…容" + +function clear_btn.write(self, section) + fs.writefile(conffile_pass, "") +end + +t4 = f:field(TextValue, "ifconfig_tun") +t4.rmempty = true +t4.rows = 10 +t4.css_style = "width: 95vw !important;" +function t4.cfgvalue() + local ifconfig_output = "" + local handle = io.popen("ifconfig | grep -A 6 '^tun' 2>/dev/null") + if handle then + ifconfig_output = handle:read("*a") + handle:close() + end + return ifconfig_output or "No tun interfaces found" +end +t4.readonly = "readonly" +t4.description = "All tun Interfaces Configuration" + +return f diff --git a/luci-app-openvpn-server-client/luasrc/view/openvpn/openvpn_status.htm b/luci-app-openvpn-server-client/luasrc/view/openvpn/openvpn_status.htm new file mode 100755 index 00000000..e3931742 --- /dev/null +++ b/luci-app-openvpn-server-client/luasrc/view/openvpn/openvpn_status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
\ No newline at end of file diff --git a/luci-app-openvpn-server-client/po/zh-cn/openvpn-server.po b/luci-app-openvpn-server-client/po/zh-cn/openvpn-server.po new file mode 100644 index 00000000..afa7bb69 --- /dev/null +++ b/luci-app-openvpn-server-client/po/zh-cn/openvpn-server.po @@ -0,0 +1,218 @@ +msgid "OpenVPN Server" +msgstr "OpenVPN æœåС噍" + +msgid "An easy config OpenVPN Server Web-UI" +msgstr "易于使用的 OpenVPN æœåС噍 Web-UI" + +msgid "Base Setting" +msgstr "基本设置" + +msgid "Enable" +msgstr "å¯ç”¨" + +msgid "Port" +msgstr "端å£" + +msgid "WAN DDNS or IP" +msgstr "WANå£çš„ DDNSåŸŸå æˆ–者 IP" + + +msgid "Client Network" +msgstr "客户端网段" + +msgid "VPN Client Network IP with subnet" +msgstr "客户端分é…的网段地å€ï¼ˆé»˜è®¤ä¸º 10.8.0.0 255.255.255.0)" + + +msgid "Client Settings" +msgstr "客户端推é€é…ç½®" + +msgid "OpenVPN Client config file" +msgstr "OpenVPN 客户端é…置文件" + + +msgid "Download .ovpn file" +msgstr "一键下载 .ovpn 文件" + +msgid "If you are using IOS client, please download this .ovpn file and send it via QQ or Email to your IOS device" +msgstr "如果你使用的是 iOS 设备,你å¯ä»¥ä½¿ç”¨ QQ 或者邮件å‘é€åˆ°è‡ªå·±çš„设备上用 OpenVPN 客户端打开导入" + +msgid "Special Code" +msgstr "特殊代ç " + +msgid "(!)Special Code you know that add in to client .ovpn file" +msgstr "(!)特殊代ç å°†è‡ªåЍåˆå¹¶åˆ°å®¢æˆ·ç«¯çš„ .ovpn é…置文件中" + +msgid "Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router" +msgstr "æ ¹æ®è·¯ç”±çš„实际LAN IP 修改 route 192.168.0.0 255.255.255.0 å’Œ dhcp-option DNS 192.168.0.1 这两行" + +msgid "OpenVPN status" +msgstr "OpenVPN è¿è¡Œçжæ€" + +msgid "Running log" +msgstr "è¿è¡Œæ—¥å¿—" + +msgid "Login log" +msgstr "登陆日志" + +msgid "user password verify" +msgstr "å¸å·å¯†ç éªŒè¯" + +msgid "Default: /etc/openvpn/server/checkpsw.sh via-env, leave it empty to disable" +msgstr "默认设置:/etc/openvpn/server/checkpsw.sh via-env,留空ç¦ç”¨" + +msgid "script_security: to use with user and password" +msgstr "script_securityé…åˆå¸å·å¯†ç éªŒè¯ä½¿ç”¨" + +msgid "Default 3, leave it empty to disable" +msgstr "默认设置:3,留空ç¦ç”¨" + +msgid "This option allows multiple clients to connect using the same certificate and key and assign different IP addresses" +msgstr "这个选项å…许多个客户端使用相åŒçš„è¯ä¹¦å’Œå¯†é’¥è¿›è¡Œè¿žæŽ¥ï¼Œå¹¶åˆ†é…ä¸åŒçš„ IP" + +msgid "Allow clients to see each other, otherwise multiple clients can only access the server and cannot connect to each other" +msgstr "å…许客户端之间相互å¯è§ï¼Œå¦åˆ™å¤šä¸ªå®¢æˆ·ç«¯åªèƒ½çœ‹åˆ°æœåŠ¡å™¨ï¼Œè€Œçœ‹ä¸åˆ°å½¼æ­¤" + +msgid "After this option is enabled, the client does not need cert and key. If this option is not enabled, cert and key and user password double verification are required." +msgstr "打开åŽå®¢æˆ·ç«¯åˆ™ä¸éœ€è¦certå’Œkey,䏿‰“开则需è¦certå’Œkey以åŠå¸å·å¯†ç åŒé‡éªŒè¯" + +msgid "If you use user password verification only, remember to delete the key and cert." +msgstr "如果使用å•独å¸å·å¯†ç éªŒè¯,一定è¦è®°å¾—删除keyå’Œcert内容" + +msgid "Client code" +msgstr "客户端代ç " + +msgid "Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass" +msgstr "想è¦åŠ å…¥åˆ°.ovpn文件里的代ç ,如果使用å¸å·å¯†ç éªŒè¯åˆ™éœ€è¦åŠ å…¥auth-user-pass" + +msgid "User and password" +msgstr "å¸å·å¯†ç " + +msgid "Each line contains a pair of user and password, separated by a space" +msgstr "æ¯è¡Œä¸€ç»„å¸å·å¯†ç ,å¸å·å¯†ç ä¸­é—´ç©ºæ ¼éš”å¼€" + +msgid "compess use lzo" +msgstr "使用lzo" + +msgid "Use the UserName provided by the client as the Common Name" +msgstr "使用客户端æä¾›çš„UserName作为Common Name" + +msgid "Authentication script" +msgstr "认è¯è„šæœ¬" + +msgid "user pass code" +msgstr "å¸å·å¯†ç " + +msgid "OpenVPN Client Config" +msgstr "OpenVPN 客户端é…ç½®" + +msgid "Delete config file" +msgstr "删除é…置文件" + +msgid "Delete conf" +msgstr "删除é…ç½®å¹¶åœæ­¢æœåŠ¡" + +msgid "Start Client Only Button" +msgstr "ä»…å¯åŠ¨å®¢æˆ·ç«¯" + +msgid "each one code one line username first" +msgstr "第一行写用户å,第二行写密ç ï¼Œä»…仅在客户端代ç é‡ŒåŠ å…¥auth-user-pass pass.txtæ‰æœ‰æ•ˆ" + +msgid "An easy config OpenVPN Client Web-UI" +msgstr "简å•çš„OpenVPN客户端WEB界é¢" + +msgid "Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass pass.txt" +msgstr "ç›®å‰ä»…仅支æŒopenvpnçš„.ovpnæ ¼å¼ä½œä¸ºå®¢æˆ·ç«¯ï¼Œåœ¨windowsç”¨æ–‡æœ¬æ–¹å¼æ‰“å¼€.ovpn文件,粘贴到上é¢ç©ºç™½å¤„,如果需è¦å¸å·å¯†ç éªŒè¯ä½ éœ€è¦åŠ å…¥ auth-user-pass pass.txt到.ovpn文件。" + +msgid "Clear the client configuration file, note: if you do not use the client mode, be sure to clear the configuration file! The start button in server mode will cause the server and client to start at the same time. If you only want to start the server, click this button." +msgstr "清除客户端é…置文件,注æ„:如果ä¸ä½¿ç”¨å®¢æˆ·ç«¯æ¨¡å¼çš„è¯åŠ¡å¿…æ¸…é™¤é…ç½®æ–‡ä»¶ï¼æœåŠ¡ç«¯æ¨¡å¼çš„å¯åŠ¨æŒ‰é’®ä¼šå¯¼è‡´åŒæ—¶å¯åЍæœåŠ¡ç«¯å’Œå®¢æˆ·ç«¯ï¼Œå¦‚æžœåªæƒ³å¯åЍæœåŠ¡ç«¯ï¼Œç‚¹å‡»æ­¤æŒ‰é’®ã€‚" + +msgid "Only start client mode. This button is different from the start button in server mode!" +msgstr "ä»…ä»…å¯åŠ¨å®¢æˆ·ç«¯æ¨¡å¼ã€‚此按钮与æœåŠ¡ç«¯æ¨¡å¼çš„å¯åŠ¨æŒ‰é’®ä¸åŒï¼" + +msgid "Only stop client mode. This button is different from the stop button in server mode!" +msgstr "ä»…ä»…åœç”¨å®¢æˆ·ç«¯æ¨¡å¼ã€‚此按钮与æœåŠ¡ç«¯æ¨¡å¼çš„åœç”¨æŒ‰é’®ä¸åŒï¼åŒæ—¶ç¦æ­¢openvpnæœåŠ¡ï¼Œç¦æ­¢è‡ªå¯åŠ¨ã€‚" + +msgid "click save and apply below this page to write config to file" +msgstr "点击页é¢ä¸‹æ–¹çš„ä¿å­˜åº”用åŽä¼šå†™å…¥åˆ°é…置文件里" + +msgid "Click Enable WAN port input data mode below, so that other machines can access this machine. You can also go to the firewall page to set it yourself." +msgstr "点击下方的å¯ç”¨WANå£è¾“å…¥æ•°æ®æ¨¡å¼ï¼Œè®©åˆ«çš„æœºå™¨å¯ä»¥è®¿é—®æœ¬æœºã€‚你也å¯ä»¥åŽ»é˜²ç«å¢™é¡µé¢è‡ªè¡Œè®¾ç½®ã€‚(éžå¿…è¦è®¾ç½®ï¼Œä¸è¦é‡å¤ç‚¹å‡»ä¸€ä¸ªæŒ‰é’®ï¼‰" + +msgid "Configuration for OpenVPN client instances. The instance name you provide becomes the UCI section name (e.g., 'client1' leads to `config openvpn 'client1'`)." +msgstr "OpenVPN 客户端实例的é…置。您æä¾›çš„实例åç§°å°†æˆä¸º UCI 部分å称(例如,'client1' 对应于 `config openvpn 'client1'`)。" + +msgid "OpenVPN Client" +msgstr "OpenVPN 客户端" + +msgid "OpenVPN Client Instances" +msgstr "OpenVPN 客户端实例" + +msgid "Enter a unique identifier (e.g., client1, client2) when adding an instance. This identifier is used for the UCI section name and the corresponding .conf file." +msgstr "添加实例时输入唯一标识符(例如,client1ã€client2)。该标识符用于 UCI 部分å称和相应的 .conf 文件。" + +msgid "Enable Instance" +msgstr "å¯ç”¨å®žä¾‹" + +msgid "Auto-generated based on instance identifier" +msgstr "æ ¹æ®å®žä¾‹æ ‡è¯†ç¬¦è‡ªåŠ¨ç”Ÿæˆ" + +msgid "Invalid instance identifier." +msgstr "无效的实例标识符。" + +msgid "OpenVPN Configuration (.ovpn/.conf)" +msgstr "OpenVPN é…ç½® (.ovpn/.conf)" + +msgid "Paste the content of the .ovpn or .conf file here. This will be saved to the path shown in 'Base Settings'." +msgstr "在此粘贴 .ovpn 或 .conf 文件的内容。将ä¿å­˜åˆ°â€œåŸºæœ¬è®¾ç½®â€ä¸­æ˜¾ç¤ºçš„路径。" + +msgid "Cannot read file: Invalid instance identifier used for this section." +msgstr "æ— æ³•è¯»å–æ–‡ä»¶ï¼šæ­¤éƒ¨åˆ†ä½¿ç”¨çš„实例标识符无效。" + +msgid "Authentication File Path" +msgstr "è®¤è¯æ–‡ä»¶è·¯å¾„" + +msgid "Enter the path for the authentication file (e.g., /etc/openvpn/password.txt)" +msgstr "è¾“å…¥è®¤è¯æ–‡ä»¶çš„路径(例如,/etc/openvpn/password.txt)" + +msgid "Authentication File Content" +msgstr "è®¤è¯æ–‡ä»¶å†…容" + +msgid "Enter the content of the authentication file (e.g., username on the first line, password on the second line). This will be saved to the path shown above." +msgstr "è¾“å…¥è®¤è¯æ–‡ä»¶çš„内容(例如,第一行是用户å,第二行是密ç ï¼‰ã€‚å°†ä¿å­˜åˆ°ä¸Šé¢æ˜¾ç¤ºçš„路径。" + +msgid "Failed to restart OpenVPN service." +msgstr "é‡å¯ OpenVPN æœåŠ¡å¤±è´¥ã€‚" + +msgid "Removed config file: " +msgstr "已移除é…置文件:" + +msgid "Error removing config file " +msgstr "移除é…置文件时出错 " + +msgid "Removed authentication file: " +msgstr "å·²ç§»é™¤è®¤è¯æ–‡ä»¶ï¼š" + +msgid "Error removing authentication file " +msgstr "ç§»é™¤è®¤è¯æ–‡ä»¶æ—¶å‡ºé”™ " + +msgid "Base Settings " +msgstr "基本设置 " + +msgid "OpenVPN Client Authentication " +msgstr "OpenVPN客户端认è¯è´¦å·å¯†ç  " + +msgid "Configure authentication files for OpenVPN client instances. " +msgstr "ç»™OpenVPN客户端é…置账å·å¯†ç æ–‡ä»¶ " + +msgid "Config File Path " +msgstr "é…置文件路径 " + +msgid "Using LZO compression, it does not support versions above 2.5.X, does not support DCO; if your version number is greater than this version, select NO to disable it." +msgstr "使用LZOåŽ‹ç¼©ï¼Œä¸æ”¯æŒ2.5.Xä»¥ä¸Šçš„ç‰ˆæœ¬ï¼Œä¸æ”¯æŒDCO,如果你的版本å·å¤§äºŽè¿™ä¸ªç‰ˆæœ¬é€‰æ‹©NOæ¥ç¦ç”¨å®ƒ" + +msgid "This will allow the server to know more info about the client like HWADDR, very useful for managing IoT devices." +msgstr "这将å…许æœåŠ¡å™¨èŽ·å–æ›´å¤šå…³äºŽå®¢æˆ·ç«¯çš„ä¿¡æ¯ï¼Œæ¯”如硬件地å€ï¼ˆHWADDR),这对于管ç†ç‰©è”网设备éžå¸¸æœ‰ç”¨ã€‚" + +msgid "Disabling DCO provides better compatibility but disables acceleration." +msgstr "ç¦ç”¨DCOå¯ä»¥æä¾›æ›´å¥½çš„兼容性,但会关闭加速功能。" diff --git a/luci-app-openvpn-server-client/po/zh_Hans b/luci-app-openvpn-server-client/po/zh_Hans new file mode 120000 index 00000000..41451e4a --- /dev/null +++ b/luci-app-openvpn-server-client/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/luci-app-openvpn-server-client/root/etc/config/openvpn b/luci-app-openvpn-server-client/root/etc/config/openvpn new file mode 100644 index 00000000..4c1b6648 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/config/openvpn @@ -0,0 +1,41 @@ + +config openvpn 'myvpn' + option enabled '0' + option proto 'tcp4' + option dev 'tun' + option topology 'subnet' + option server '10.8.0.0 255.255.255.0' + option comp_lzo 'adaptive' + option ca '/etc/openvpn/pki/ca.crt' + option dh '/etc/openvpn/pki/dh.pem' + option cert '/etc/openvpn/pki/server.crt' + option key '/etc/openvpn/pki/server.key' + option persist_key '1' + option persist_tun '1' + option max_clients '88' + option keepalive '10 120' + option verb '3' + option status '/var/log/openvpn_status.log' + option log '/tmp/openvpn.log' + option port '1194' + option ddns 'myserver.f3322.net' + option auth_user_pass_verify '/etc/openvpn/server/checkpsw.sh via-env' + option script_security '3' + list push 'route 192.168.9.0 255.255.255.0' + list push 'comp-lzo adaptive' + list push 'redirect-gateway def1 bypass-dhcp' + list push 'dhcp-option DNS 192.168.9.1' + +config openvpn 'client1' + option enabled '0' + option config '/etc/openvpn/client1.conf' + +config openvpn 'client2' + option enabled '0' + option config '/etc/openvpn/client2.conf' + +config openvpnpassword 'pwd1' + option pwdfile '/etc/openvpn/pass.txt' + +config openvpnpassword 'pwd2' + option pwdfile '/etc/openvpn/pass2.txt' diff --git a/luci-app-openvpn-server-client/root/etc/easy-rsa/keys/index.txt b/luci-app-openvpn-server-client/root/etc/easy-rsa/keys/index.txt new file mode 100644 index 00000000..4bb34b80 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/easy-rsa/keys/index.txt @@ -0,0 +1,2 @@ +V 270821142642Z 01 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com +V 270821142658Z 02 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=client1/name=EasyRSA/emailAddress=ZJ@ZJ.com diff --git a/luci-app-openvpn-server-client/root/etc/easy-rsa/keys/serial b/luci-app-openvpn-server-client/root/etc/easy-rsa/keys/serial new file mode 100644 index 00000000..75016ea3 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/easy-rsa/keys/serial @@ -0,0 +1 @@ +03 diff --git a/luci-app-openvpn-server-client/root/etc/easy-rsa/vars b/luci-app-openvpn-server-client/root/etc/easy-rsa/vars new file mode 100644 index 00000000..c7f26a1c --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/easy-rsa/vars @@ -0,0 +1,10 @@ +set_var EASYRSA_OPENSSL "openssl" +set_var EASYRSA_KEY_SIZE 2048 +set_var EASYRSA_REQ_COUNTRY "lunatickochiya" +set_var EASYRSA_REQ_PROVINCE "github" +set_var EASYRSA_REQ_CITY "github" +set_var EASYRSA_REQ_ORG "github" +set_var EASYRSA_REQ_EMAIL "lunatickochiya@github.com" +set_var EASYRSA_REQ_OU "github" +set_var EASYRSA_CA_EXPIRE 3650 +set_var EASYRSA_CERT_EXPIRE 3650 diff --git a/luci-app-openvpn-server-client/root/etc/genovpn.sh b/luci-app-openvpn-server-client/root/etc/genovpn.sh new file mode 100755 index 00000000..91c3cdcd --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/genovpn.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +ddns=`uci get openvpn.myvpn.ddns` +port=`uci get openvpn.myvpn.port` +proto=`uci get openvpn.myvpn.proto` + +cat > /tmp/my.ovpn <' >> /tmp/my.ovpn +cat /etc/openvpn/pki/ca.crt >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +cat /etc/openvpn/pki/client1.crt >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +cat /etc/openvpn/pki/client1.key >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +[ -f /etc/ovpnadd.conf ] && cat /etc/ovpnadd.conf >> /tmp/my.ovpn diff --git a/luci-app-openvpn-server-client/root/etc/openvpn/client/delclient.sh b/luci-app-openvpn-server-client/root/etc/openvpn/client/delclient.sh new file mode 100755 index 00000000..4246d9c0 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/openvpn/client/delclient.sh @@ -0,0 +1,5 @@ +#!/bin/sh +/etc/init.d/openvpn stop +sleep 3 +rm /etc/openvpn/client.conf +rm /etc/openvpn/pass.txt \ No newline at end of file diff --git a/luci-app-openvpn-server-client/root/etc/openvpn/client/startclient.sh b/luci-app-openvpn-server-client/root/etc/openvpn/client/startclient.sh new file mode 100755 index 00000000..453ab168 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/openvpn/client/startclient.sh @@ -0,0 +1,4 @@ +#!/bin/sh +/etc/init.d/openvpn enable +sleep 3 +/etc/init.d/openvpn restart diff --git a/luci-app-openvpn-server-client/root/etc/openvpn/client/stopclient.sh b/luci-app-openvpn-server-client/root/etc/openvpn/client/stopclient.sh new file mode 100644 index 00000000..0c4c4d70 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/openvpn/client/stopclient.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +sleep 2 +/etc/init.d/openvpn stop +sleep 2 +/etc/init.d/openvpn disable diff --git a/luci-app-openvpn-server-client/root/etc/openvpn/server/checkpsw.sh b/luci-app-openvpn-server-client/root/etc/openvpn/server/checkpsw.sh new file mode 100755 index 00000000..48f93fb6 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/openvpn/server/checkpsw.sh @@ -0,0 +1,34 @@ +#!/bin/sh +########################################################### +# checkpsw.sh (C) 2004 Mathias Sundman +# +# This script will authenticate OpenVPN users against +# a plain text file. The passfile should simply contain +# one row per user with the username first followed by +# one or more space(s) or tab(s) and then the password. + +PASSFILE="/etc/openvpn/server/psw-file" +LOG_FILE="/etc/openvpn/openvpn-password.log" +TIME_STAMP=`date "+%Y-%m-%d %T"` + +########################################################### + +if [ ! -r "${PASSFILE}" ]; then + echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE} + exit 1 +fi + +CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}` + +if [ "${CORRECT_PASSWORD}" = "" ]; then + echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE} + exit 1 +fi + +if [ "${password}" = "${CORRECT_PASSWORD}" ]; then + echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE} + exit 0 +fi + +echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE} +exit 1 \ No newline at end of file diff --git a/luci-app-openvpn-server-client/root/etc/openvpn/server/psw-file b/luci-app-openvpn-server-client/root/etc/openvpn/server/psw-file new file mode 100755 index 00000000..05c1e3c1 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/openvpn/server/psw-file @@ -0,0 +1 @@ +lunatic urey \ No newline at end of file diff --git a/luci-app-openvpn-server-client/root/etc/openvpncert.sh b/luci-app-openvpn-server-client/root/etc/openvpncert.sh new file mode 100755 index 00000000..a593719e --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/openvpncert.sh @@ -0,0 +1,62 @@ +#!/bin/sh + + +function rand_str() { + (base64 /dev/urandom | tr -dc 'A-Za-z' | head -c $1) 2>/dev/null +} + +function rand_str_upper() { + (rand_str $1 | tr 'a-z' 'A-Z') 2>/dev/null +} + +function rand_str_lower() { + (rand_str $1 | tr 'A-Z' 'a-z') 2>/dev/null +} + +function rand_easy_rsa_vars() { + local KEY_PROVINCE="$(rand_str_upper 6)" + local KEY_CITY="$(rand_str 8)" + local KEY_ORG="$(rand_str 8)" + local KEY_EMAIL="$(rand_str_lower 8)@$(rand_str_lower 4).$(rand_str_lower 3)" + local KEY_OU="$(rand_str 8)" + sed -i \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_COUNTRY[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_COUNTRY\t\"$KEY_PROVINCE\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_PROVINCE[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_PROVINCE\t\"$KEY_CITY\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_CITY[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_CITY\t\"$KEY_ORG\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_ORG[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_ORG\t\"$KEY_ORG\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_EMAIL[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_EMAIL\t\"$KEY_EMAIL\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_OU[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_OU\t\"$KEY_OU\"/" \ + /etc/easy-rsa/vars +} + +rand_easy_rsa_vars + + +rm -rf /root/pki + +export EASYRSA_PKI="/etc/easy-rsa/pki" +export EASYRSA_VARS_FILE="/etc/easy-rsa/vars" +export EASYRSA_CLI="easyrsa --batch" + +echo -en "yes\nyes\n" | $EASYRSA_CLI init-pki +# Generate DH +$EASYRSA_CLI gen-dh + +# Generate for the CA +$EASYRSA_CLI build-ca nopass + +# Generate for the server +$EASYRSA_CLI build-server-full server nopass + +# Generate for the client +$EASYRSA_CLI build-client-full client1 nopass + +# Copy files +mkdir -p /etc/openvpn/pki +cp /etc/easy-rsa/pki/ca.crt /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/dh.pem /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/issued/server.crt /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/private/server.key /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/issued/client1.crt /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/private/client1.key /etc/openvpn/pki/ +echo "OpenVPN Cert renew successfully" diff --git a/luci-app-openvpn-server-client/root/etc/ovpnadd.conf b/luci-app-openvpn-server-client/root/etc/ovpnadd.conf new file mode 100644 index 00000000..4969b7a9 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/ovpnadd.conf @@ -0,0 +1 @@ +auth-user-pass \ No newline at end of file diff --git a/luci-app-openvpn-server-client/root/etc/uci-defaults/openvpn b/luci-app-openvpn-server-client/root/etc/uci-defaults/openvpn new file mode 100755 index 00000000..3498b7d1 --- /dev/null +++ b/luci-app-openvpn-server-client/root/etc/uci-defaults/openvpn @@ -0,0 +1,46 @@ +#!/bin/sh + +openvpn_port="$(uci -q get openvpn.myvpn.port)" +[ -z "$openvpn_port" ] && openvpn_port=1194 + +uci -q batch <<-EOF >/dev/null + delete network.vpn0 + set network.vpn0=interface + set network.vpn0.ifname='tun0' + set network.vpn0.proto='none' + + commit network + delete firewall.openvpn + set firewall.openvpn=rule + set firewall.openvpn.name='openvpn' + set firewall.openvpn.target='ACCEPT' + set firewall.openvpn.src='wan' + set firewall.openvpn.proto='tcp udp' + set firewall.openvpn.dest_port="$openvpn_port" + delete firewall.vpn + set firewall.vpn=zone + set firewall.vpn.name='vpn' + set firewall.vpn.input='ACCEPT' + set firewall.vpn.forward='ACCEPT' + set firewall.vpn.output='ACCEPT' + set firewall.vpn.masq='1' + set firewall.vpn.network='vpn0' + delete firewall.vpntowan + set firewall.vpntowan=forwarding + set firewall.vpntowan.src='vpn' + set firewall.vpntowan.dest='wan' + delete firewall.vpntolan + set firewall.vpntolan=forwarding + set firewall.vpntolan.src='vpn' + set firewall.vpntolan.dest='lan' + delete firewall.lantovpn + set firewall.lantovpn=forwarding + set firewall.lantovpn.src='lan' + set firewall.lantovpn.dest='vpn' + commit firewall +EOF + +chmod 0777 /etc/openvpn/server/checkpsw.sh + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/luci-app-openvpn-server-client/root/usr/share/ucitrack/luci-app-openvpn-server-client.json b/luci-app-openvpn-server-client/root/usr/share/ucitrack/luci-app-openvpn-server-client.json new file mode 100644 index 00000000..719367c9 --- /dev/null +++ b/luci-app-openvpn-server-client/root/usr/share/ucitrack/luci-app-openvpn-server-client.json @@ -0,0 +1,4 @@ +{ + "config": "openvpn", + "init": "" +} diff --git a/luci-app-openvpn-server/Makefile b/luci-app-openvpn-server/Makefile new file mode 100644 index 00000000..bf1195f0 --- /dev/null +++ b/luci-app-openvpn-server/Makefile @@ -0,0 +1,21 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for OpenVPN Server +LUCI_DEPENDS:=+openvpn-openssl +openvpn-easy-rsa +LUCI_PKGARCH:=all +PKG_NAME:=luci-app-openvpn-server +PKG_VERSION:=2.0 +PKG_RELEASE:=21 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + + + diff --git a/luci-app-openvpn-server/luasrc/controller/openvpn-server.lua b/luci-app-openvpn-server/luasrc/controller/openvpn-server.lua new file mode 100755 index 00000000..a2cb1553 --- /dev/null +++ b/luci-app-openvpn-server/luasrc/controller/openvpn-server.lua @@ -0,0 +1,23 @@ + +module("luci.controller.openvpn-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/openvpn") then + return + end + + entry({"admin", "services", "openvpn-server"},firstchild(), _("OpenVPN Server"), 1).dependent = true + + entry({"admin", "services", "openvpn-server", "general"}, cbi("openvpn-server/openvpn-server"), _("OpenVPN Server"), 1).leaf = true + entry({"admin", "services", "openvpn-server", "log"},form("openvpn-server/openvpn-server_run_log"), _("Running log"), 2).leaf = true + entry({"admin", "services", "openvpn-server", "passlog"},form("openvpn-server/openvpn-server_pass_log"), _("Login log"), 3).leaf = true + + entry({"admin", "services", "openvpn-server","status"},call("act_status")).leaf=true +end + +function act_status() + local e={} + e.running=luci.sys.call("pgrep openvpn >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server.lua b/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server.lua new file mode 100755 index 00000000..d21f2613 --- /dev/null +++ b/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server.lua @@ -0,0 +1,228 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2025 LunaticKochiya<125438787@qq.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id$ +]]-- + +--require("luci.tools.webadmin") + +local uci = require "luci.model.uci".cursor() + +mp = Map("openvpn", "OpenVPN Server",translate("An easy config OpenVPN Server Web-UI")) + +mp:section(SimpleSection).template = "openvpn/openvpn_status" + +s = mp:section(TypedSection, "openvpn") +s.anonymous = true +s.addremove = false + +s.filter = function(self, section) + return section:match("^myvpn") ~= nil +end + +s:tab("basic", translate("Base Setting")) + +o = s:taboption("basic", Flag, "enabled", translate("Enable")) + +port = s:taboption("basic", Value, "port", translate("Port")) +port.datatype = "range(1,65535)" + +ddns = s:taboption("basic", Value, "ddns", translate("WAN DDNS or IP")) +ddns.datatype = "string" +ddns.default = "exmple.com" +ddns.rmempty = false + +localnet = s:taboption("basic", Value, "server", translate("Client Network")) +localnet.datatype = "string" +localnet.description = translate("VPN Client Network IP with subnet") + +proto = s:taboption("basic",Value,"proto", translate("proto")) +proto.datatype = "string" +proto:value("tcp4") +proto:value("udp4") +proto:value("tcp6") +proto:value("udp6") +proto.default ="tcp4" + +comp_lzo = s:taboption("basic",Value,"comp_lzo", translate("comp_lzo")) +comp_lzo.datatype = "string" +comp_lzo:value("adaptive") +comp_lzo:value("yes") +comp_lzo:value("no") +comp_lzo.default="adaptive" +comp_lzo.description = translate("Using LZO compression, it does not support versions above 2.5.X, does not support DCO; if your version number is greater than this version, select NO to disable it.") +comp_lzo:depends("comp_lzo", "yes") +comp_lzo:depends("comp_lzo", "adaptive") + + +auth_user_pass_verify = s:taboption("basic",Value,"auth_user_pass_verify", translate("user password verify")) +auth_user_pass_verify.datatype = "string" +auth_user_pass_verify.description = translate("Default: /etc/openvpn/server/checkpsw.sh via-env, leave it empty to disable") + +script_security = s:taboption("basic",Value,"script_security", translate("script_security: to use with user and password")) +script_security.datatype = "range(1,3)" +script_security:value("1") +script_security:value("2") +script_security:value("3") +script_security.description = translate("Default 3, leave it empty to disable") + +duplicate_cn = s:taboption("basic",Flag,"duplicate_cn", translate("duplicate_cn")) +duplicate_cn.description = translate("This option allows multiple clients to connect using the same certificate and key and assign different IP addresses") +client_to_client = s:taboption("basic",Flag,"client_to_client", translate("client-to-client")) +client_to_client.description = translate("Allow clients to see each other, otherwise multiple clients can only access the server and cannot connect to each other") +username_as_common_name = s:taboption("basic",Flag,"username_as_common_name", translate("username_as_common_name")) +username_as_common_name.description = translate("Use the UserName provided by the client as the Common Name") +client_cert_not_required = s:taboption("basic",Flag,"client_cert_not_required", translate("client_cert_not_required")) +client_cert_not_required.description = translate("After this option is enabled, the client does not need cert and key. If this option is not enabled, cert and key and user password double verification are required.") + +list = s:taboption("basic", DynamicList, "push") +list.title = translate("Client Settings") +list.datatype = "string" +list.description = translate("Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router") + + +local o +o = s:taboption("basic", Button,"certificate",translate("OpenVPN Client config file")) +o.inputtitle = translate("Download .ovpn file") +o.description = translate("If you use user password verification only, remember to delete the key and cert.") +o.inputstyle = "reload" +o.write = function() + luci.sys.call("sh /etc/genovpn.sh 2>&1 >/dev/null") + Download() +end + +s:tab("code", translate("Client code")) +local conf = "/etc/ovpnadd.conf" +local NXFS = require "nixio.fs" +o = s:taboption("code", TextValue, "conf") +o.description = translate("Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(conf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(conf, value:gsub("\r\n", "\n")) +end + +s:tab("passwordfile", translate("User and password")) +local pass = "/etc/openvpn/server/psw-file" +local NXFS = require "nixio.fs" +o = s:taboption("passwordfile", TextValue, "pass") +o.description = translate("Each line contains a pair of user and password, separated by a space") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(pass) or "" +end +o.write = function(self, section, value) + NXFS.writefile(pass, value:gsub("\r\n", "\n")) +end + +s:tab("checkpsw", translate("Authentication script")) +local checkpswconf = "/etc/openvpn/server/checkpsw.sh" +local NXFS = require "nixio.fs" +o = s:taboption("checkpsw", TextValue, "checkpswconf") +o.description = translate("Authentication script") +o.rows = 13 +o.wrap = "off" +o.cfgvalue = function(self, section) + return NXFS.readfile(checkpswconf) or "" +end +o.write = function(self, section, value) + NXFS.writefile(checkpswconf, value:gsub("\r\n", "\n")) +end + +local pid = luci.util.exec("/usr/bin/pgrep openvpn") + +function openvpn_process_status() + local status = "OpenVPN is not running now " + + if pid ~= "" then + status = "OpenVPN is running with the PID " .. pid .. "" + end + + local status = { status=status } + local table = { pid=status } + return table +end + + + +function Download() + local t,e + t=nixio.open("/tmp/my.ovpn","r") + luci.http.header('Content-Disposition','attachment; filename="my.ovpn"') + luci.http.prepare_content("application/octet-stream") + while true do + e=t:read(nixio.const.buffersize) + if(not e)or(#e==0)then + break + else + luci.http.write(e) + end + end + t:close() + luci.http.close() +end + +t = mp:section(Table, openvpn_process_status()) +t.anonymous = true + +t:option(DummyValue, "status", translate("OpenVPN status")) + +if pid == "" then + start = t:option(Button, "_start", translate("Start")) + start.inputstyle = "apply" + function start.write(self, section) + luci.util.exec("uci set openvpn.myvpn.enabled=='1' && uci commit openvpn") + message = luci.util.exec("/etc/init.d/openvpn start 2>&1") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "services", "openvpn-server") .. "?message=" .. message + ) + end +else + stop = t:option(Button, "_stop", translate("Stop")) + stop.inputstyle = "reset" + function stop.write(self, section) + luci.util.exec("uci set openvpn.myvpn.enabled=='0' && uci commit openvpn") + luci.util.exec("/etc/init.d/openvpn stop") + luci.util.exec("sleep 2") + luci.http.redirect( + luci.dispatcher.build_url("admin", "services", "openvpn-server") + ) + end +end + +function mp.on_after_commit(self) + os.execute("uci set firewall.openvpn.dest_port=$(uci get openvpn.myvpn.port) && uci commit firewall && /etc/init.d/firewall restart") + os.execute("/etc/init.d/openvpn restart") + local comp_lzo_val = uci:get("openvpn", "myvpn", "comp_lzo") + if comp_lzo_val == "no" then + uci:delete("openvpn", "myvpn", "comp_lzo") + uci:save("openvpn") + uci:commit("openvpn") + end +end + +gen = t:option(Button,"cert",translate("OpenVPN Cert")) +gen.inputstyle = "apply" +function gen.write(self, section) + luci.util.exec("/etc/openvpncert.sh") +end + +--local apply = luci.http.formvalue("cbi.apply") +--if apply then +-- os.execute("/etc/init.d/openvpn restart") +--end + +return mp diff --git a/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server_pass_log.lua b/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server_pass_log.lua new file mode 100755 index 00000000..17e80a1b --- /dev/null +++ b/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server_pass_log.lua @@ -0,0 +1,14 @@ +local fs = require "nixio.fs" +local conffile = "/etc/openvpn/openvpn-password.log" + +f = SimpleForm("logview") + +t = f:field(TextValue, "conf") +t.rmempty = true +t.rows = 20 +function t.cfgvalue() + return fs.readfile(conffile) or "" +end +t.readonly="readonly" + +return f \ No newline at end of file diff --git a/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server_run_log.lua b/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server_run_log.lua new file mode 100755 index 00000000..992811f0 --- /dev/null +++ b/luci-app-openvpn-server/luasrc/model/cbi/openvpn-server/openvpn-server_run_log.lua @@ -0,0 +1,14 @@ +local fs = require "nixio.fs" +local conffile = "/var/openvpn.log" + +f = SimpleForm("logview") + +t = f:field(TextValue, "conf") +t.rmempty = true +t.rows = 20 +function t.cfgvalue() + return fs.readfile(conffile) or "" +end +t.readonly="readonly" + +return f \ No newline at end of file diff --git a/luci-app-openvpn-server/luasrc/view/openvpn/openvpn_status.htm b/luci-app-openvpn-server/luasrc/view/openvpn/openvpn_status.htm new file mode 100755 index 00000000..e3931742 --- /dev/null +++ b/luci-app-openvpn-server/luasrc/view/openvpn/openvpn_status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
\ No newline at end of file diff --git a/luci-app-openvpn-server/po/zh-cn/openvpn-server.po b/luci-app-openvpn-server/po/zh-cn/openvpn-server.po new file mode 100644 index 00000000..dac58d19 --- /dev/null +++ b/luci-app-openvpn-server/po/zh-cn/openvpn-server.po @@ -0,0 +1,212 @@ +msgid "OpenVPN Server" +msgstr "OpenVPN æœåС噍" + +msgid "An easy config OpenVPN Server Web-UI" +msgstr "易于使用的 OpenVPN æœåС噍 Web-UI" + +msgid "Base Setting" +msgstr "基本设置" + +msgid "Enable" +msgstr "å¯ç”¨" + +msgid "Port" +msgstr "端å£" + +msgid "WAN DDNS or IP" +msgstr "WANå£çš„ DDNSåŸŸå æˆ–者 IP" + + +msgid "Client Network" +msgstr "客户端网段" + +msgid "VPN Client Network IP with subnet" +msgstr "客户端分é…的网段地å€ï¼ˆé»˜è®¤ä¸º 10.8.0.0 255.255.255.0)" + + +msgid "Client Settings" +msgstr "客户端推é€é…ç½®" + +msgid "OpenVPN Client config file" +msgstr "OpenVPN 客户端é…置文件" + + +msgid "Download .ovpn file" +msgstr "一键下载 .ovpn 文件" + +msgid "If you are using IOS client, please download this .ovpn file and send it via QQ or Email to your IOS device" +msgstr "如果你使用的是 iOS 设备,你å¯ä»¥ä½¿ç”¨ QQ 或者邮件å‘é€åˆ°è‡ªå·±çš„设备上用 OpenVPN 客户端打开导入" + +msgid "Special Code" +msgstr "特殊代ç " + +msgid "(!)Special Code you know that add in to client .ovpn file" +msgstr "(!)特殊代ç å°†è‡ªåЍåˆå¹¶åˆ°å®¢æˆ·ç«¯çš„ .ovpn é…置文件中" + +msgid "Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router" +msgstr "æ ¹æ®è·¯ç”±çš„实际LAN IP 修改 route 192.168.0.0 255.255.255.0 å’Œ dhcp-option DNS 192.168.0.1 这两行" + +msgid "OpenVPN status" +msgstr "OpenVPN è¿è¡Œçжæ€" + +msgid "Running log" +msgstr "è¿è¡Œæ—¥å¿—" + +msgid "Login log" +msgstr "登陆日志" + +msgid "user password verify" +msgstr "å¸å·å¯†ç éªŒè¯" + +msgid "Default: /etc/openvpn/server/checkpsw.sh via-env, leave it empty to disable" +msgstr "默认设置:/etc/openvpn/server/checkpsw.sh via-env,留空ç¦ç”¨" + +msgid "script_security: to use with user and password" +msgstr "script_securityé…åˆå¸å·å¯†ç éªŒè¯ä½¿ç”¨" + +msgid "Default 3, leave it empty to disable" +msgstr "默认设置:3,留空ç¦ç”¨" + +msgid "This option allows multiple clients to connect using the same certificate and key and assign different IP addresses" +msgstr "这个选项å…许多个客户端使用相åŒçš„è¯ä¹¦å’Œå¯†é’¥è¿›è¡Œè¿žæŽ¥ï¼Œå¹¶åˆ†é…ä¸åŒçš„ IP" + +msgid "Allow clients to see each other, otherwise multiple clients can only access the server and cannot connect to each other" +msgstr "å…许客户端之间相互å¯è§ï¼Œå¦åˆ™å¤šä¸ªå®¢æˆ·ç«¯åªèƒ½çœ‹åˆ°æœåŠ¡å™¨ï¼Œè€Œçœ‹ä¸åˆ°å½¼æ­¤" + +msgid "After this option is enabled, the client does not need cert and key. If this option is not enabled, cert and key and user password double verification are required." +msgstr "打开åŽå®¢æˆ·ç«¯åˆ™ä¸éœ€è¦certå’Œkey,䏿‰“开则需è¦certå’Œkey以åŠå¸å·å¯†ç åŒé‡éªŒè¯" + +msgid "If you use user password verification only, remember to delete the key and cert." +msgstr "如果使用å•独å¸å·å¯†ç éªŒè¯,一定è¦è®°å¾—删除keyå’Œcert内容" + +msgid "Client code" +msgstr "客户端代ç " + +msgid "Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass" +msgstr "想è¦åŠ å…¥åˆ°.ovpn文件里的代ç ,如果使用å¸å·å¯†ç éªŒè¯åˆ™éœ€è¦åŠ å…¥auth-user-pass" + +msgid "User and password" +msgstr "å¸å·å¯†ç " + +msgid "Each line contains a pair of user and password, separated by a space" +msgstr "æ¯è¡Œä¸€ç»„å¸å·å¯†ç ,å¸å·å¯†ç ä¸­é—´ç©ºæ ¼éš”å¼€" + +msgid "compess use lzo" +msgstr "使用lzo" + +msgid "Use the UserName provided by the client as the Common Name" +msgstr "使用客户端æä¾›çš„UserName作为Common Name" + +msgid "Authentication script" +msgstr "认è¯è„šæœ¬" + +msgid "user pass code" +msgstr "å¸å·å¯†ç " + +msgid "OpenVPN Client Config" +msgstr "OpenVPN 客户端é…ç½®" + +msgid "Delete config file" +msgstr "删除é…置文件" + +msgid "Delete conf" +msgstr "删除é…ç½®å¹¶åœæ­¢æœåŠ¡" + +msgid "Start Client Only Button" +msgstr "ä»…å¯åŠ¨å®¢æˆ·ç«¯" + +msgid "each one code one line username first" +msgstr "第一行写用户å,第二行写密ç ï¼Œä»…仅在客户端代ç é‡ŒåŠ å…¥auth-user-pass pass.txtæ‰æœ‰æ•ˆ" + +msgid "An easy config OpenVPN Client Web-UI" +msgstr "简å•çš„OpenVPN客户端WEB界é¢" + +msgid "Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass pass.txt" +msgstr "ç›®å‰ä»…仅支æŒopenvpnçš„.ovpnæ ¼å¼ä½œä¸ºå®¢æˆ·ç«¯ï¼Œåœ¨windowsç”¨æ–‡æœ¬æ–¹å¼æ‰“å¼€.ovpn文件,粘贴到上é¢ç©ºç™½å¤„,如果需è¦å¸å·å¯†ç éªŒè¯ä½ éœ€è¦åŠ å…¥ auth-user-pass pass.txt到.ovpn文件。" + +msgid "Clear the client configuration file, note: if you do not use the client mode, be sure to clear the configuration file! The start button in server mode will cause the server and client to start at the same time. If you only want to start the server, click this button." +msgstr "清除客户端é…置文件,注æ„:如果ä¸ä½¿ç”¨å®¢æˆ·ç«¯æ¨¡å¼çš„è¯åŠ¡å¿…æ¸…é™¤é…ç½®æ–‡ä»¶ï¼æœåŠ¡ç«¯æ¨¡å¼çš„å¯åŠ¨æŒ‰é’®ä¼šå¯¼è‡´åŒæ—¶å¯åЍæœåŠ¡ç«¯å’Œå®¢æˆ·ç«¯ï¼Œå¦‚æžœåªæƒ³å¯åЍæœåŠ¡ç«¯ï¼Œç‚¹å‡»æ­¤æŒ‰é’®ã€‚" + +msgid "Only start client mode. This button is different from the start button in server mode!" +msgstr "ä»…ä»…å¯åŠ¨å®¢æˆ·ç«¯æ¨¡å¼ã€‚此按钮与æœåŠ¡ç«¯æ¨¡å¼çš„å¯åŠ¨æŒ‰é’®ä¸åŒï¼" + +msgid "Only stop client mode. This button is different from the stop button in server mode!" +msgstr "ä»…ä»…åœç”¨å®¢æˆ·ç«¯æ¨¡å¼ã€‚此按钮与æœåŠ¡ç«¯æ¨¡å¼çš„åœç”¨æŒ‰é’®ä¸åŒï¼åŒæ—¶ç¦æ­¢openvpnæœåŠ¡ï¼Œç¦æ­¢è‡ªå¯åŠ¨ã€‚" + +msgid "click save and apply below this page to write config to file" +msgstr "点击页é¢ä¸‹æ–¹çš„ä¿å­˜åº”用åŽä¼šå†™å…¥åˆ°é…置文件里" + +msgid "Click Enable WAN port input data mode below, so that other machines can access this machine. You can also go to the firewall page to set it yourself." +msgstr "点击下方的å¯ç”¨WANå£è¾“å…¥æ•°æ®æ¨¡å¼ï¼Œè®©åˆ«çš„æœºå™¨å¯ä»¥è®¿é—®æœ¬æœºã€‚你也å¯ä»¥åŽ»é˜²ç«å¢™é¡µé¢è‡ªè¡Œè®¾ç½®ã€‚(éžå¿…è¦è®¾ç½®ï¼Œä¸è¦é‡å¤ç‚¹å‡»ä¸€ä¸ªæŒ‰é’®ï¼‰" + +msgid "Configuration for OpenVPN client instances. The instance name you provide becomes the UCI section name (e.g., 'client1' leads to `config openvpn 'client1'`)." +msgstr "OpenVPN 客户端实例的é…置。您æä¾›çš„实例åç§°å°†æˆä¸º UCI 部分å称(例如,'client1' 对应于 `config openvpn 'client1'`)。" + +msgid "OpenVPN Client" +msgstr "OpenVPN 客户端" + +msgid "OpenVPN Client Instances" +msgstr "OpenVPN 客户端实例" + +msgid "Enter a unique identifier (e.g., client1, client2) when adding an instance. This identifier is used for the UCI section name and the corresponding .conf file." +msgstr "添加实例时输入唯一标识符(例如,client1ã€client2)。该标识符用于 UCI 部分å称和相应的 .conf 文件。" + +msgid "Enable Instance" +msgstr "å¯ç”¨å®žä¾‹" + +msgid "Auto-generated based on instance identifier" +msgstr "æ ¹æ®å®žä¾‹æ ‡è¯†ç¬¦è‡ªåŠ¨ç”Ÿæˆ" + +msgid "Invalid instance identifier." +msgstr "无效的实例标识符。" + +msgid "OpenVPN Configuration (.ovpn/.conf)" +msgstr "OpenVPN é…ç½® (.ovpn/.conf)" + +msgid "Paste the content of the .ovpn or .conf file here. This will be saved to the path shown in 'Base Settings'." +msgstr "在此粘贴 .ovpn 或 .conf 文件的内容。将ä¿å­˜åˆ°â€œåŸºæœ¬è®¾ç½®â€ä¸­æ˜¾ç¤ºçš„路径。" + +msgid "Cannot read file: Invalid instance identifier used for this section." +msgstr "æ— æ³•è¯»å–æ–‡ä»¶ï¼šæ­¤éƒ¨åˆ†ä½¿ç”¨çš„实例标识符无效。" + +msgid "Authentication File Path" +msgstr "è®¤è¯æ–‡ä»¶è·¯å¾„" + +msgid "Enter the path for the authentication file (e.g., /etc/openvpn/password.txt)" +msgstr "è¾“å…¥è®¤è¯æ–‡ä»¶çš„路径(例如,/etc/openvpn/password.txt)" + +msgid "Authentication File Content" +msgstr "è®¤è¯æ–‡ä»¶å†…容" + +msgid "Enter the content of the authentication file (e.g., username on the first line, password on the second line). This will be saved to the path shown above." +msgstr "è¾“å…¥è®¤è¯æ–‡ä»¶çš„内容(例如,第一行是用户å,第二行是密ç ï¼‰ã€‚å°†ä¿å­˜åˆ°ä¸Šé¢æ˜¾ç¤ºçš„路径。" + +msgid "Failed to restart OpenVPN service." +msgstr "é‡å¯ OpenVPN æœåŠ¡å¤±è´¥ã€‚" + +msgid "Removed config file: " +msgstr "已移除é…置文件:" + +msgid "Error removing config file " +msgstr "移除é…置文件时出错 " + +msgid "Removed authentication file: " +msgstr "å·²ç§»é™¤è®¤è¯æ–‡ä»¶ï¼š" + +msgid "Error removing authentication file " +msgstr "ç§»é™¤è®¤è¯æ–‡ä»¶æ—¶å‡ºé”™ " + +msgid "Base Settings " +msgstr "基本设置 " + +msgid "OpenVPN Client Authentication " +msgstr "OpenVPN客户端认è¯è´¦å·å¯†ç  " + +msgid "Configure authentication files for OpenVPN client instances. " +msgstr "ç»™OpenVPN客户端é…置账å·å¯†ç æ–‡ä»¶ " + +msgid "Config File Path " +msgstr "é…置文件路径 " + +msgid "Using LZO compression, it does not support versions above 2.5.X, does not support DCO; if your version number is greater than this version, select NO to disable it." +msgstr "使用LZOåŽ‹ç¼©ï¼Œä¸æ”¯æŒ2.5.Xä»¥ä¸Šçš„ç‰ˆæœ¬ï¼Œä¸æ”¯æŒDCO,如果你的版本å·å¤§äºŽè¿™ä¸ªç‰ˆæœ¬é€‰æ‹©NOæ¥ç¦ç”¨å®ƒ" diff --git a/luci-app-openvpn-server/po/zh_Hans b/luci-app-openvpn-server/po/zh_Hans new file mode 120000 index 00000000..41451e4a --- /dev/null +++ b/luci-app-openvpn-server/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/luci-app-openvpn-server/root/etc/config/openvpn b/luci-app-openvpn-server/root/etc/config/openvpn new file mode 100644 index 00000000..b1317562 --- /dev/null +++ b/luci-app-openvpn-server/root/etc/config/openvpn @@ -0,0 +1,35 @@ + +config openvpn 'myvpn' + option enabled '0' + option proto 'tcp4' + option dev 'tun' + option topology 'subnet' + option server '10.8.0.0 255.255.255.0' + option comp_lzo 'adaptive' + option ca '/etc/openvpn/pki/ca.crt' + option dh '/etc/openvpn/pki/dh.pem' + option cert '/etc/openvpn/pki/server.crt' + option key '/etc/openvpn/pki/server.key' + option persist_key '1' + option persist_tun '1' + option max_clients '88' + option keepalive '10 120' + option verb '3' + option status '/var/log/openvpn_status.log' + option log '/tmp/openvpn.log' + option port '1194' + option ddns 'myserver.f3322.net' + option auth_user_pass_verify '/etc/openvpn/server/checkpsw.sh via-env' + option script_security '3' + list push 'route 192.168.9.0 255.255.255.0' + list push 'comp-lzo adaptive' + list push 'redirect-gateway def1 bypass-dhcp' + list push 'dhcp-option DNS 192.168.9.1' + +config openvpnclient + +config openvpnclientstart + +config openvpnclientconf + +config openvpnclientstop diff --git a/luci-app-openvpn-server/root/etc/easy-rsa/vars b/luci-app-openvpn-server/root/etc/easy-rsa/vars new file mode 100644 index 00000000..c7f26a1c --- /dev/null +++ b/luci-app-openvpn-server/root/etc/easy-rsa/vars @@ -0,0 +1,10 @@ +set_var EASYRSA_OPENSSL "openssl" +set_var EASYRSA_KEY_SIZE 2048 +set_var EASYRSA_REQ_COUNTRY "lunatickochiya" +set_var EASYRSA_REQ_PROVINCE "github" +set_var EASYRSA_REQ_CITY "github" +set_var EASYRSA_REQ_ORG "github" +set_var EASYRSA_REQ_EMAIL "lunatickochiya@github.com" +set_var EASYRSA_REQ_OU "github" +set_var EASYRSA_CA_EXPIRE 3650 +set_var EASYRSA_CERT_EXPIRE 3650 diff --git a/luci-app-openvpn-server/root/etc/genovpn.sh b/luci-app-openvpn-server/root/etc/genovpn.sh new file mode 100755 index 00000000..91c3cdcd --- /dev/null +++ b/luci-app-openvpn-server/root/etc/genovpn.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +ddns=`uci get openvpn.myvpn.ddns` +port=`uci get openvpn.myvpn.port` +proto=`uci get openvpn.myvpn.proto` + +cat > /tmp/my.ovpn <' >> /tmp/my.ovpn +cat /etc/openvpn/pki/ca.crt >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +cat /etc/openvpn/pki/client1.crt >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +cat /etc/openvpn/pki/client1.key >> /tmp/my.ovpn +echo '' >> /tmp/my.ovpn +[ -f /etc/ovpnadd.conf ] && cat /etc/ovpnadd.conf >> /tmp/my.ovpn diff --git a/luci-app-openvpn-server/root/etc/openvpn/server/checkpsw.sh b/luci-app-openvpn-server/root/etc/openvpn/server/checkpsw.sh new file mode 100755 index 00000000..48f93fb6 --- /dev/null +++ b/luci-app-openvpn-server/root/etc/openvpn/server/checkpsw.sh @@ -0,0 +1,34 @@ +#!/bin/sh +########################################################### +# checkpsw.sh (C) 2004 Mathias Sundman +# +# This script will authenticate OpenVPN users against +# a plain text file. The passfile should simply contain +# one row per user with the username first followed by +# one or more space(s) or tab(s) and then the password. + +PASSFILE="/etc/openvpn/server/psw-file" +LOG_FILE="/etc/openvpn/openvpn-password.log" +TIME_STAMP=`date "+%Y-%m-%d %T"` + +########################################################### + +if [ ! -r "${PASSFILE}" ]; then + echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE} + exit 1 +fi + +CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}` + +if [ "${CORRECT_PASSWORD}" = "" ]; then + echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE} + exit 1 +fi + +if [ "${password}" = "${CORRECT_PASSWORD}" ]; then + echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE} + exit 0 +fi + +echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE} +exit 1 \ No newline at end of file diff --git a/luci-app-openvpn-server/root/etc/openvpn/server/psw-file b/luci-app-openvpn-server/root/etc/openvpn/server/psw-file new file mode 100755 index 00000000..05c1e3c1 --- /dev/null +++ b/luci-app-openvpn-server/root/etc/openvpn/server/psw-file @@ -0,0 +1 @@ +lunatic urey \ No newline at end of file diff --git a/luci-app-openvpn-server/root/etc/openvpncert.sh b/luci-app-openvpn-server/root/etc/openvpncert.sh new file mode 100755 index 00000000..a593719e --- /dev/null +++ b/luci-app-openvpn-server/root/etc/openvpncert.sh @@ -0,0 +1,62 @@ +#!/bin/sh + + +function rand_str() { + (base64 /dev/urandom | tr -dc 'A-Za-z' | head -c $1) 2>/dev/null +} + +function rand_str_upper() { + (rand_str $1 | tr 'a-z' 'A-Z') 2>/dev/null +} + +function rand_str_lower() { + (rand_str $1 | tr 'A-Z' 'a-z') 2>/dev/null +} + +function rand_easy_rsa_vars() { + local KEY_PROVINCE="$(rand_str_upper 6)" + local KEY_CITY="$(rand_str 8)" + local KEY_ORG="$(rand_str 8)" + local KEY_EMAIL="$(rand_str_lower 8)@$(rand_str_lower 4).$(rand_str_lower 3)" + local KEY_OU="$(rand_str 8)" + sed -i \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_COUNTRY[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_COUNTRY\t\"$KEY_PROVINCE\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_PROVINCE[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_PROVINCE\t\"$KEY_CITY\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_CITY[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_CITY\t\"$KEY_ORG\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_ORG[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_ORG\t\"$KEY_ORG\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_EMAIL[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_EMAIL\t\"$KEY_EMAIL\"/" \ + -e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_OU[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_OU\t\"$KEY_OU\"/" \ + /etc/easy-rsa/vars +} + +rand_easy_rsa_vars + + +rm -rf /root/pki + +export EASYRSA_PKI="/etc/easy-rsa/pki" +export EASYRSA_VARS_FILE="/etc/easy-rsa/vars" +export EASYRSA_CLI="easyrsa --batch" + +echo -en "yes\nyes\n" | $EASYRSA_CLI init-pki +# Generate DH +$EASYRSA_CLI gen-dh + +# Generate for the CA +$EASYRSA_CLI build-ca nopass + +# Generate for the server +$EASYRSA_CLI build-server-full server nopass + +# Generate for the client +$EASYRSA_CLI build-client-full client1 nopass + +# Copy files +mkdir -p /etc/openvpn/pki +cp /etc/easy-rsa/pki/ca.crt /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/dh.pem /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/issued/server.crt /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/private/server.key /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/issued/client1.crt /etc/openvpn/pki/ +cp /etc/easy-rsa/pki/private/client1.key /etc/openvpn/pki/ +echo "OpenVPN Cert renew successfully" diff --git a/luci-app-openvpn-server/root/etc/ovpnadd.conf b/luci-app-openvpn-server/root/etc/ovpnadd.conf new file mode 100644 index 00000000..4969b7a9 --- /dev/null +++ b/luci-app-openvpn-server/root/etc/ovpnadd.conf @@ -0,0 +1 @@ +auth-user-pass \ No newline at end of file diff --git a/luci-app-openvpn-server/root/etc/uci-defaults/openvpn b/luci-app-openvpn-server/root/etc/uci-defaults/openvpn new file mode 100755 index 00000000..3498b7d1 --- /dev/null +++ b/luci-app-openvpn-server/root/etc/uci-defaults/openvpn @@ -0,0 +1,46 @@ +#!/bin/sh + +openvpn_port="$(uci -q get openvpn.myvpn.port)" +[ -z "$openvpn_port" ] && openvpn_port=1194 + +uci -q batch <<-EOF >/dev/null + delete network.vpn0 + set network.vpn0=interface + set network.vpn0.ifname='tun0' + set network.vpn0.proto='none' + + commit network + delete firewall.openvpn + set firewall.openvpn=rule + set firewall.openvpn.name='openvpn' + set firewall.openvpn.target='ACCEPT' + set firewall.openvpn.src='wan' + set firewall.openvpn.proto='tcp udp' + set firewall.openvpn.dest_port="$openvpn_port" + delete firewall.vpn + set firewall.vpn=zone + set firewall.vpn.name='vpn' + set firewall.vpn.input='ACCEPT' + set firewall.vpn.forward='ACCEPT' + set firewall.vpn.output='ACCEPT' + set firewall.vpn.masq='1' + set firewall.vpn.network='vpn0' + delete firewall.vpntowan + set firewall.vpntowan=forwarding + set firewall.vpntowan.src='vpn' + set firewall.vpntowan.dest='wan' + delete firewall.vpntolan + set firewall.vpntolan=forwarding + set firewall.vpntolan.src='vpn' + set firewall.vpntolan.dest='lan' + delete firewall.lantovpn + set firewall.lantovpn=forwarding + set firewall.lantovpn.src='lan' + set firewall.lantovpn.dest='vpn' + commit firewall +EOF + +chmod 0777 /etc/openvpn/server/checkpsw.sh + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/luci-app-openvpn-server/root/usr/share/ucitrack/luci-app-openvpn-server.json b/luci-app-openvpn-server/root/usr/share/ucitrack/luci-app-openvpn-server.json new file mode 100644 index 00000000..719367c9 --- /dev/null +++ b/luci-app-openvpn-server/root/usr/share/ucitrack/luci-app-openvpn-server.json @@ -0,0 +1,4 @@ +{ + "config": "openvpn", + "init": "" +} diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile new file mode 100644 index 00000000..96938fab --- /dev/null +++ b/luci-app-passwall/Makefile @@ -0,0 +1,173 @@ +# Copyright (C) 2018-2020 L-WRT Team +# Copyright (C) 2021-2025 xiaorouji +# Copyright (C) 2026 Openwrt-Passwall Organization +# +# This is free software, licensed under the GNU General Public License v3. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-passwall +PKG_VERSION:=26.5.20 +PKG_RELEASE:=1 +PKG_PO_VERSION:=$(PKG_VERSION) + +PKG_CONFIG_DEPENDS:= \ + CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Geoview \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SingBox \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray_Plugin + +LUCI_TITLE:=LuCI support for PassWall +LUCI_PKGARCH:=all +LUCI_DEPENDS:=+coreutils +coreutils-base64 +coreutils-nohup +curl \ + +chinadns-ng +dns2socks +dnsmasq-full +ip-full \ + +libuci-lua +lua +luci-compat +luci-lib-jsonc \ + +microsocks +resolveip +tcping +lyaml + +define Package/$(PKG_NAME)/config +menu "Configuration" + depends on PACKAGE_$(PKG_NAME) + +config PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy + bool "Iptables Transparent Proxy" + select PACKAGE_ipset + select PACKAGE_ipt2socks + select PACKAGE_iptables + select PACKAGE_iptables-zz-legacy + select PACKAGE_iptables-mod-conntrack-extra + select PACKAGE_iptables-mod-iprange + select PACKAGE_iptables-mod-socket + select PACKAGE_iptables-mod-tproxy + select PACKAGE_kmod-ipt-nat + default y if ! PACKAGE_firewall4 + +config PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy + bool "Nftables Transparent Proxy" + select PACKAGE_ipt2socks + select PACKAGE_nftables + select PACKAGE_kmod-nft-socket + select PACKAGE_kmod-nft-tproxy + select PACKAGE_kmod-nft-nat + default y if PACKAGE_firewall4 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Geoview + bool "Include Geoview" + select PACKAGE_geoview + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy + bool "Include Haproxy" + select PACKAGE_haproxy + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria + bool "Include Hysteria" + select PACKAGE_hysteria + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy + bool "Include NaiveProxy" + depends on !(arc||armeb||loongarch64||mips||mips64||powerpc||TARGET_gemini) + select PACKAGE_naiveproxy + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client + bool "Include Shadowsocks Rust Client" + depends on !i386 + select PACKAGE_shadowsocks-rust-sslocal + default y if aarch64||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server + bool "Include Shadowsocks Rust Server" + depends on !i386 + select PACKAGE_shadowsocks-rust-ssserver + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client + bool "Include ShadowsocksR Libev Client" + select PACKAGE_shadowsocksr-libev-ssr-local + select PACKAGE_shadowsocksr-libev-ssr-redir + default y + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server + bool "Include ShadowsocksR Libev Server" + select PACKAGE_shadowsocksr-libev-ssr-server + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS + bool "Include Shadow-TLS" + select PACKAGE_shadow-tls + depends on aarch64||arm||x86_64 + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs + bool "Include Simple-Obfs (Shadowsocks Plugin)" + select PACKAGE_simple-obfs-client + default y + +config PACKAGE_$(PKG_NAME)_INCLUDE_SingBox + bool "Include Sing-Box" + select PACKAGE_sing-box + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata + bool "Include V2ray_Geodata" + select PACKAGE_v2ray-geoip + select PACKAGE_v2ray-geosite + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin + bool "Include V2ray-Plugin (Shadowsocks Plugin)" + select PACKAGE_v2ray-plugin + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Xray + bool "Include Xray" + select PACKAGE_xray-core + select PACKAGE_unzip + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Xray_Plugin + bool "Include Xray-Plugin (Shadowsocks Plugin)" + select PACKAGE_xray-plugin + default n + +endmenu +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/passwall +/etc/config/passwall_server +/usr/share/passwall/rules/direct_host +/usr/share/passwall/rules/direct_ip +/usr/share/passwall/rules/proxy_host +/usr/share/passwall/rules/proxy_ip +/usr/share/passwall/rules/block_host +/usr/share/passwall/rules/block_ip +/usr/share/passwall/rules/lanlist_ipv4 +/usr/share/passwall/rules/lanlist_ipv6 +/usr/share/passwall/rules/domains_excluded +endef + +define Package/$(PKG_NAME)/postrm +#!/bin/sh +rm -f $${IPKG_INSTROOT}/usr/share/passwall/rules/*.nft +exit 0 +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js new file mode 100644 index 00000000..8148b9dd --- /dev/null +++ b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/Sortable.min.js @@ -0,0 +1,2 @@ +/*! Sortable 1.15.7 - MIT | git://github.com/SortableJS/Sortable.git */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function m(t){return t.host&&t!==document&&t.host.nodeType&&t.host!==t?t.host:t.parentNode}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&g(t,e)||o&&t===n)return t}while(t!==n&&(t=m(t)))}return null}var v,b=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(b," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(b," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function D(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function E(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function jt(t){$&&$.parentNode[K]._isOutsideThisEl(t.target)}function Ht(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Rt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ht.supportPointer&&"PointerEvent"in window&&(!u||d),emptyInsertThreshold:5};for(n in G.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Xt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Pt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?f(t,"pointerdown",this._onTapStart):(f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),_t.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,N())}function Lt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Kt(t){t.draggable=!1}function Wt(){Ot=!1}function zt(t){return setTimeout(t,0)}function Gt(t){return clearTimeout(t)}Ht.prototype={constructor:Ht,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(bt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,$):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Mt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Mt.push(o)}}(o),!$&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||nt===l)){if(rt=j(l),lt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return Z({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),q("filter",n,{evt:e}),void(i&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return Z({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),q("filter",n,{evt:e}),!0}))return void(i&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!$&&n.parentNode===r&&(o=X(n),tt=r,Q=($=n).parentNode,et=$.nextSibling,nt=n,ct=a.group,dt={target:Ht.dragged=$,clientX:(e||t).clientX,clientY:(e||t).clientY},gt=dt.clientX-o.left,mt=dt.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,$.style["will-change"]="all",o=function(){q("delayEnded",i,{evt:t}),Ht.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&($.draggable=!0),i._triggerDragStart(t,e),Z({sortable:i,name:"choose",originalEvent:t}),k($,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){E($,t.trim(),Kt)}),f(l,"dragover",Ft),f(l,"mousemove",Ft),f(l,"touchmove",Ft),a.supportPointer?(f(l,"pointerup",i._onDrop),this.nativeDraggable||f(l,"pointercancel",i._onDrop)):(f(l,"mouseup",i._onDrop),f(l,"touchend",i._onDrop),f(l,"touchcancel",i._onDrop)),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,$.draggable=!0),q("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ht.eventCanceled?this._onDrop():(a.supportPointer?(f(l,"pointerup",i._disableDelayedDrag),f(l,"pointercancel",i._disableDelayedDrag)):(f(l,"mouseup",i._disableDelayedDrag),f(l,"touchend",i._disableDelayedDrag),f(l,"touchcancel",i._disableDelayedDrag)),f(l,"mousemove",i._delayedDragTouchMoveHandler),f(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&f(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){$&&Kt($),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"pointerup",this._disableDelayedDrag),p(t,"pointercancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?f(document,"pointermove",this._onTouchMove):f(document,e?"touchmove":"mousemove",this._onTouchMove):(f($,"dragend",this),f(tt,"dragstart",this._onDragStart));try{document.selection?zt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;Et=!1,tt&&$?(q("dragStarted",this,{evt:e}),this.nativeDraggable&&f(document,"dragover",jt),n=this.options,t||k($,n.dragClass,!1),k($,n.ghostClass,!0),Ht.active=this,t&&this._appendGhost(),Z({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ht){this._lastX=ht.clientX,this._lastY=ht.clientY,Yt();for(var t=document.elementFromPoint(ht.clientX,ht.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ht.clientX,ht.clientY))!==e;)e=t;if($.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ht.clientX,clientY:ht.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=m(t=e));Bt()}},_onTouchMove:function(t){if(dt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=J&&D(J,!0),a=J&&r&&r.a,l=J&&r&&r.d,e=Nt&&Dt&&S(Dt),a=(i.clientX-dt.clientX+o.x)/(a||1)+(e?e[0]-xt[0]:0)/(a||1),l=(i.clientY-dt.clientY+o.y)/(l||1)+(e?e[1]-xt[1]:0)/(l||1);if(!Ht.active&&!Et){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))E.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>E.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,J),e?t.clientX<_.left-10||t.clientY65536?(i[0]=240|(1835008&n)>>>18,i[1]=128|(258048&n)>>>12,i[2]=128|(4032&n)>>>6,i[3]=128|63&n):n>2048?(i[0]=224|(61440&n)>>>12,i[1]=128|(4032&n)>>>6,i[2]=128|63&n):n>128?(i[0]=192|(1984&n)>>>6,i[1]=128|63&n):i[0]=n,this.parsedData.push(i)}this.parsedData=Array.prototype.concat.apply([],this.parsedData),this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function e(t,e){this.typeNumber=t,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}t.prototype={getLength:function(t){return this.parsedData.length},write:function(t){for(var e=0,r=this.parsedData.length;e=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,r)},setupPositionProbePattern:function(t,e){for(var r=-1;r<=7;r++)if(!(t+r<=-1||this.moduleCount<=t+r))for(var o=-1;o<=7;o++)e+o<=-1||this.moduleCount<=e+o||(this.modules[t+r][e+o]=0<=r&&r<=6&&(0==o||6==o)||0<=o&&o<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=o&&o<=4)},getBestMaskPattern:function(){for(var t=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var o=g.getLostPoint(this);(0==r||t>o)&&(t=o,e=r)}return e},createMovieClip:function(t,e,r){var o=t.createEmptyMovieClip(e,r);this.make();for(var i=0;i>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(r=0;r<18;r++){o=!t&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,o=g.getBCHTypeInfo(r),i=0;i<15;i++){var n=!t&&1==(o>>i&1);i<6?this.modules[i][8]=n:i<8?this.modules[i+1][8]=n:this.modules[this.moduleCount-15+i][8]=n}for(i=0;i<15;i++){n=!t&&1==(o>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=n:i<9?this.modules[8][15-i-1+1]=n:this.modules[8][15-i-1]=n}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,o=this.moduleCount-1,i=7,n=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var s=0;s<2;s++)if(null==this.modules[o][a-s]){var h=!1;n>>i&1)),g.getMask(e,o,a-s)&&(h=!h),this.modules[o][a-s]=h,-1==--i&&(n++,i=7)}if((o+=r)<0||this.moduleCount<=o){o-=r,r=-r;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(t,r,o){for(var i=m.getRSBlocks(t,r),n=new _,a=0;a8*h)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*h+")");for(n.getLengthInBits()+4<=8*h&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*h||(n.put(e.PAD0,8),n.getLengthInBits()>=8*h));)n.put(e.PAD1,8);return e.createBytes(n,i)},e.createBytes=function(t,e){for(var r=0,o=0,i=0,n=new Array(e.length),a=new Array(e.length),s=0;s=0?d.get(c):0}}var m=0;for(u=0;u=0;)e^=g.G15<=0;)e^=g.G18<>>=1;return e},getPatternPosition:function(t){return g.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case i:return(e+r)%2==0;case n:return e%2==0;case a:return r%3==0;case s:return(e+r)%3==0;case h:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case l:return e*r%2+e*r%3==0;case u:return(e*r%2+e*r%3)%2==0;case f:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new p([1],0),r=0;r5&&(r+=3+n-5)}for(o=0;o=256;)t-=255;return d.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},c=0;c<8;c++)d.EXP_TABLE[c]=1<>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};var v=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];function C(){var t=!1,e=navigator.userAgent;if(/android/i.test(e)){t=!0;var r=e.toString().match(/android ([0-9]\.[0-9])/i);r&&r[1]&&(t=parseFloat(r[1]))}return t}var w=function(){var t=function(t,e){this._el=t,this._htOption=e};return t.prototype.draw=function(t){var e=this._htOption,r=this._el,o=t.getModuleCount();Math.floor(e.width/o),Math.floor(e.height/o);function i(t,e){var r=document.createElementNS("http://www.w3.org/2000/svg",t);for(var o in e)e.hasOwnProperty(o)&&r.setAttribute(o,e[o]);return r}this.clear();var n=i("svg",{viewBox:"0 0 "+String(o)+" "+String(o),width:"100%",height:"100%",fill:e.colorLight});n.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),r.appendChild(n),n.appendChild(i("rect",{fill:e.colorLight,width:"100%",height:"100%"})),n.appendChild(i("rect",{fill:e.colorDark,width:"1",height:"1",id:"template"}));for(var a=0;a'],s=0;s");for(var h=0;h');a.push("")}a.push(""),r.innerHTML=a.join("");var l=r.childNodes[0],u=(e.width-l.offsetWidth)/2,f=(e.height-l.offsetHeight)/2;u>0&&f>0&&(l.style.margin=f+"px "+u+"px")},t.prototype.clear=function(){this._el.innerHTML=""},t}():function(){function t(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}if(this._android&&this._android<=2.1){var e=1/window.devicePixelRatio,r=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(t,o,i,n,a,s,h,l,u){if("nodeName"in t&&/img/i.test(t.nodeName))for(var f=arguments.length-1;f>=1;f--)arguments[f]=arguments[f]*e;else void 0===l&&(arguments[1]*=e,arguments[2]*=e,arguments[3]*=e,arguments[4]*=e);r.apply(this,arguments)}}var o=function(t,e){this._bIsPainted=!1,this._android=C(),this._htOption=e,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=e.width,this._elCanvas.height=e.height,t.appendChild(this._elCanvas),this._el=t,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.alt="Scan me!",this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return o.prototype.draw=function(t){var e=this._elImage,r=this._oContext,o=this._htOption,i=t.getModuleCount(),n=o.width/i,a=o.height/i,s=Math.round(n),h=Math.round(a);e.style.display="none",this.clear();for(var l=0;lv.length)throw new Error("Too long data");return r}(QRCode=function(t,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:o.H},"string"==typeof e&&(e={text:e}),e)for(var r in e)this._htOption[r]=e[r];"string"==typeof t&&(t=document.getElementById(t)),this._htOption.useSVG&&(D=w),this._android=C(),this._el=t,this._oQRCode=null,this._oDrawing=new D(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)}).prototype.makeCode=function(t){this._oQRCode=new e(A(t,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(t),this._oQRCode.make(),this._el.title=t,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=o}(),"undefined"!=typeof module&&(module.exports=QRCode); diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua new file mode 100644 index 00000000..909285bc --- /dev/null +++ b/luci-app-passwall/luasrc/controller/passwall.lua @@ -0,0 +1,1070 @@ +-- Copyright (C) 2018-2020 L-WRT Team +-- Copyright (C) 2021-2025 xiaorouji +-- Copyright (C) 2026 Openwrt-Passwall Organization + +module("luci.controller.passwall", package.seeall) +local api = require "luci.passwall.api" +local appname = "passwall" -- not available +local uci = api.uci -- in funtion index() +local fs = api.fs +local http = require "luci.http" +local util = require "luci.util" +local i18n = require "luci.i18n" +local jsonStringify = luci.jsonc.stringify +local jsonParse = luci.jsonc.parse + +function index() + if not nixio.fs.access("/etc/config/passwall") then + if nixio.fs.access("/usr/share/passwall/0_default_config") then + luci.sys.call('cp -f /usr/share/passwall/0_default_config /etc/config/passwall') + else return end + end + local api = require "luci.passwall.api" + local appname = "passwall" -- global definitions not available + local uci = api.uci -- in function index() + local fs = api.fs + entry({"admin", "services", appname}).dependent = true + entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true + entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true + entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true + local e + if uci:get(appname, "@global[0]", "hide_from_luci") ~= "1" then + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("Pass Wall"), -1) + else + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, -1) + end + e.dependent = true + e.acl_depends = { "luci-app-passwall" } + --[[ Client ]] + entry({"admin", "services", appname, "settings"}, cbi(appname .. "/client/global"), _("Basic Settings"), 1).dependent = true + entry({"admin", "services", appname, "node_list"}, cbi(appname .. "/client/node_list"), _("Node List"), 2).dependent = true + entry({"admin", "services", appname, "node_subscribe"}, cbi(appname .. "/client/node_subscribe"), _("Node Subscribe"), 3).dependent = true + entry({"admin", "services", appname, "other"}, cbi(appname .. "/client/other", {autoapply = true}), _("Other Settings"), 92).leaf = true + if api.is_finded("haproxy") then + entry({"admin", "services", appname, "haproxy"}, cbi(appname .. "/client/haproxy"), _("Load Balancing"), 93).leaf = true + end + entry({"admin", "services", appname, "app_update"}, cbi(appname .. "/client/app_update"), _("App Update"), 95).leaf = true + entry({"admin", "services", appname, "rule"}, cbi(appname .. "/client/rule"), _("Rule Manage"), 96).leaf = true + entry({"admin", "services", appname, "rule_list"}, cbi(appname .. "/client/rule_list", {autoapply = true}), _("Rule List"), 97).leaf = true + entry({"admin", "services", appname, "node_subscribe_config"}, cbi(appname .. "/client/node_subscribe_config")).leaf = true + entry({"admin", "services", appname, "node_config"}, cbi(appname .. "/client/node_config")).leaf = true + entry({"admin", "services", appname, "shunt_rules"}, cbi(appname .. "/client/shunt_rules")).leaf = true + entry({"admin", "services", appname, "socks_config"}, cbi(appname .. "/client/socks_config")).leaf = true + entry({"admin", "services", appname, "acl"}, cbi(appname .. "/client/acl"), _("Access control"), 98).leaf = true + entry({"admin", "services", appname, "acl_config"}, cbi(appname .. "/client/acl_config")).leaf = true + entry({"admin", "services", appname, "log"}, form(appname .. "/client/log"), _("Runtime Logs"), 999).leaf = true + + --[[ Server ]] + entry({"admin", "services", appname, "server"}, cbi(appname .. "/server/index"), _("Server-Side"), 99).leaf = true + entry({"admin", "services", appname, "server_user"}, cbi(appname .. "/server/user")).leaf = true + + --[[ API ]] + entry({"admin", "services", appname, "server_user_update"}, call("server_user_update")).leaf = true + entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true + entry({"admin", "services", appname, "server_user_log"}, call("server_user_log")).leaf = true + entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true + entry({"admin", "services", appname, "server_clear_log"}, call("server_clear_log")).leaf = true + entry({"admin", "services", appname, "link_add_node"}, call("link_add_node")).leaf = true + entry({"admin", "services", appname, "socks_autoswitch_add_node"}, call("socks_autoswitch_add_node")).leaf = true + entry({"admin", "services", appname, "socks_autoswitch_remove_node"}, call("socks_autoswitch_remove_node")).leaf = true + entry({"admin", "services", appname, "gen_client_config"}, call("gen_client_config")).leaf = true + entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true + entry({"admin", "services", appname, "get_redir_log"}, call("get_redir_log")).leaf = true + entry({"admin", "services", appname, "get_socks_log"}, call("get_socks_log")).leaf = true + entry({"admin", "services", appname, "get_chinadns_log"}, call("get_chinadns_log")).leaf = true + entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true + entry({"admin", "services", appname, "clear_log"}, call("clear_log")).leaf = true + entry({"admin", "services", appname, "index_status"}, call("index_status")).leaf = true + entry({"admin", "services", appname, "haproxy_status"}, call("haproxy_status")).leaf = true + entry({"admin", "services", appname, "socks_status"}, call("socks_status")).leaf = true + entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true + entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true + entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true + entry({"admin", "services", appname, "add_node"}, call("add_node")).leaf = true + entry({"admin", "services", appname, "update_node"}, call("update_node")).leaf = true + entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true + entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true + entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true + entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true + entry({"admin", "services", appname, "reassign_group"}, call("reassign_group")).leaf = true + entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true + entry({"admin", "services", appname, "save_node_order"}, call("save_node_order")).leaf = true + entry({"admin", "services", appname, "save_node_list_opt"}, call("save_node_list_opt")).leaf = true + entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true + entry({"admin", "services", appname, "rollback_rules"}, call("rollback_rules")).leaf = true + entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true + entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true + entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true + entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true + entry({"admin", "services", appname, "flush_set"}, call("flush_set")).leaf = true + + --[[rule_list]] + entry({"admin", "services", appname, "read_rulelist"}, call("read_rulelist")).leaf = true + + --[[Components update]] + entry({"admin", "services", appname, "check_passwall"}, call("app_check")).leaf = true + local coms = require "luci.passwall.com" + local com + for _, com in ipairs(coms.order) do + entry({"admin", "services", appname, "check_" .. com}, call("com_check", com)).leaf = true + entry({"admin", "services", appname, "update_" .. com}, call("com_update", com)).leaf = true + end + + --[[Backup]] + entry({"admin", "services", appname, "create_backup"}, call("create_backup")).leaf = true + entry({"admin", "services", appname, "restore_backup"}, call("restore_backup")).leaf = true + + --[[geoview]] + entry({"admin", "services", appname, "geo_view"}, call("geo_view")).leaf = true + + entry({"admin", "services", appname, "fetch_certsha256"}, call("fetch_certsha256")).leaf = true +end + +local function http_write_json(content) + http.prepare_content("application/json") + http.write(jsonStringify(content or {code = 1})) +end + +local function http_write_json_ok(data) + http.prepare_content("application/json") + http.write(jsonStringify({code = 1, data = data})) +end + +local function http_write_json_error(data) + http.prepare_content("application/json") + http.write(jsonStringify({code = 0, data = data})) +end + +function reset_config() + luci.sys.call('/etc/init.d/passwall stop') + luci.sys.call('[ -f "/usr/share/passwall/0_default_config" ] && cp -f /usr/share/passwall/0_default_config /etc/config/passwall') + http.redirect(api.url()) +end + +function show_menu() + api.sh_uci_del(appname, "@global[0]", "hide_from_luci", true) + luci.sys.call("rm -rf /tmp/luci-*") + luci.sys.call("/etc/init.d/rpcd restart >/dev/null") + http.redirect(api.url()) +end + +function hide_menu() + api.sh_uci_set(appname, "@global[0]", "hide_from_luci", "1", true) + luci.sys.call("rm -rf /tmp/luci-*") + luci.sys.call("/etc/init.d/rpcd restart >/dev/null") + http.redirect(luci.dispatcher.build_url("admin", "status", "overview")) +end + +function link_add_node() + -- 分片接收以çªç ´uhttpdçš„é™åˆ¶ + local tmp_file = "/tmp/links.conf" + local chunk = http.formvalue("chunk") + local chunk_index = tonumber(http.formvalue("chunk_index")) + local total_chunks = tonumber(http.formvalue("total_chunks")) + local group = http.formvalue("group") or "default" + + if chunk and chunk_index ~= nil and total_chunks ~= nil then + -- æŒ‰é¡ºåºæ‹¼æŽ¥åˆ°æ–‡ä»¶ + local mode = "a" + if chunk_index == 0 then + mode = "w" + end + local f = io.open(tmp_file, mode) + if f then + f:write(chunk) + f:close() + end + -- 如果是最åŽä¸€ç‰‡ï¼Œæ‰æ‰§è¡Œ + if chunk_index + 1 == total_chunks then + luci.sys.call("lua /usr/share/passwall/subscribe.lua add " .. group) + end + end +end + +function socks_autoswitch_add_node() + local id = http.formvalue("id") + local key = http.formvalue("key") + if id and id ~= "" and key and key ~= "" then + uci:set(appname, id, "enable_autoswitch", "1") + local new_list = uci:get(appname, id, "autoswitch_backup_node") or {} + for i = #new_list, 1, -1 do + if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then + table.remove(new_list, i) + end + end + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e["remark"]:find(key) then + table.insert(new_list, e.id) + end + end + uci:set_list(appname, id, "autoswitch_backup_node", new_list) + api.uci_save(uci, appname) + end + http.redirect(api.url("socks_config", id)) +end + +function socks_autoswitch_remove_node() + local id = http.formvalue("id") + local key = http.formvalue("key") + if id and id ~= "" and key and key ~= "" then + uci:set(appname, id, "enable_autoswitch", "1") + local new_list = uci:get(appname, id, "autoswitch_backup_node") or {} + for i = #new_list, 1, -1 do + if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then + table.remove(new_list, i) + end + end + uci:set_list(appname, id, "autoswitch_backup_node", new_list) + api.uci_save(uci, appname) + end + http.redirect(api.url("socks_config", id)) +end + + +function gen_client_config() + local id = http.formvalue("id") + local config_file = api.TMP_PATH .. "/config_" .. id + luci.sys.call(string.format("/usr/share/passwall/app.sh run_socks flag=config_%s node=%s bind=127.0.0.1 socks_port=1080 config_file=%s no_run=1", id, id, config_file)) + if nixio.fs.access(config_file) then + http.prepare_content("application/json") + http.write(luci.sys.exec("cat " .. config_file)) + luci.sys.call("rm -f " .. config_file) + else + http.redirect(api.url("node_list")) + end +end + +function get_now_use_node() + local path = "/tmp/etc/passwall/acl/default" + local e = {} + local tcp_node = api.get_cache_var("ACL_GLOBAL_TCP_node") + if tcp_node then + e["TCP"] = tcp_node + end + local udp_node = api.get_cache_var("ACL_GLOBAL_UDP_node") + if udp_node then + e["UDP"] = udp_node + end + http_write_json(e) +end + +function get_redir_log() + local name = http.formvalue("name") + local proto = http.formvalue("proto") + local path = "/tmp/etc/passwall/acl/" .. name + proto = proto:upper() + if proto == "UDP" and (uci:get(appname, "@global[0]", "udp_node") or "nil") == "tcp" and not fs.access(path .. "/" .. proto .. ".log") then + proto = "TCP" + end + if fs.access(path .. "/" .. proto .. ".log") then + local content = luci.sys.exec("tail -n 19999 ".. path .. "/" .. proto .. ".log") + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_socks_log() + local name = http.formvalue("name") + local path = "/tmp/etc/passwall/SOCKS_" .. name .. ".log" + if fs.access(path) then + local content = luci.sys.exec("cat ".. path) + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_chinadns_log() + local flag = http.formvalue("flag") + local path = "/tmp/etc/passwall/acl/" .. flag .. "/chinadns_ng.log" + if fs.access(path) then + local content = luci.sys.exec("tail -n 5000 ".. path) + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_log() + -- luci.sys.exec("[ -f /tmp/log/passwall.log ] && sed '1!G;h;$!d' /tmp/log/passwall.log > /tmp/log/passwall_show.log") + http.write(luci.sys.exec("[ -f '/tmp/log/passwall.log' ] && cat /tmp/log/passwall.log")) +end + +function clear_log() + luci.sys.call("echo '' > /tmp/log/passwall.log") +end + +function index_status() + local e = {} + local dns_shunt = uci:get(appname, "@global[0]", "dns_shunt") or "dnsmasq" + if dns_shunt == "smartdns" then + local port = api.get_cache_var("SMARTDNS_LOCAL_PORT") or 0 + e.dns_mode_status = (port ~= 0) and luci.sys.call(string.format("netstat -apn | grep ':%s ' >/dev/null", port)) == 0 or false + elseif dns_shunt == "chinadns-ng" then + e.dns_mode_status = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'chinadns_ng' >/dev/null") == 0 + else + e.dns_mode_status = luci.sys.call("netstat -apn | grep ':15353 ' >/dev/null") == 0 + end + + e.haproxy_status = "-1" + if api.is_finded("haproxy") then + e.haproxy_status = (luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0) and "0" or "1" + end + + e["tcp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'TCP' >/dev/null") == 0 + + if (uci:get(appname, "@global[0]", "udp_node") or "nil") == "tcp" then + e["udp_node_status"] = e["tcp_node_status"] + else + e["udp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'UDP' >/dev/null") == 0 + end + http_write_json(e) +end + +function haproxy_status() + local e = {} + e["status"] = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0 + http_write_json(e) +end + +function socks_status() + local e = {} + local index = http.formvalue("index") + local id = http.formvalue("id") + e.index = index + e.socks_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep -v '_acl_' | grep '%s' | grep 'SOCKS_' > /dev/null", id)) == 0 + local use_http = uci:get(appname, id, "http_port") or 0 + e.use_http = 0 + if tonumber(use_http) > 0 then + e.use_http = 1 + e.http_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep -v '_acl_' | grep '%s' | grep -E 'HTTP_|HTTP2SOCKS' > /dev/null", id)) == 0 + end + http_write_json(e) +end + +function connect_status() + local e = {} + e.use_time = "" + local url = http.formvalue("url") + local aliyun = string.find(url, "aliyun") + local chn_list = uci:get(appname, "@global[0]", "chn_list") or "direct" + local gfw_list = uci:get(appname, "@global[0]", "use_gfw_list") or "1" + local proxy_mode = uci:get(appname, "@global[0]", "tcp_proxy_mode") or "proxy" + local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1" + local socks_server = (localhost_proxy == "0") and api.get_cache_var("GLOBAL_TCP_SOCKS_server") or "" + url = "-w %{http_code}:%{time_pretransfer} " .. url + if socks_server and socks_server ~= "" then + if (chn_list == "proxy" and gfw_list == "0" and proxy_mode ~= "proxy" and aliyun ~= nil) or (chn_list == "0" and gfw_list == "0" and proxy_mode == "proxy") then + -- 中国列表+阿里 or 全局 + url = "-x socks5h://" .. socks_server .. " " .. url + elseif aliyun == nil then + -- å…¶ä»–ä»£ç†æ¨¡å¼+阿里以外网站 + url = "-x socks5h://" .. socks_server .. " " .. url + end + end + local result = luci.sys.exec('/usr/bin/curl --connect-timeout 3 --max-time 5 -o /dev/null -I -sk ' .. url) + local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") + if code ~= 0 then + local use_time_str = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") + local use_time = tonumber(use_time_str) + if use_time then + if use_time_str:find("%.") then + e.use_time = string.format("%.2f", use_time * 1000) + else + e.use_time = string.format("%.2f", use_time / 1000) + end + e.ping_type = "curl" + end + end + http_write_json(e) +end + +function ping_node() + local index = http.formvalue("index") + local address = http.formvalue("address") + local port = http.formvalue("port") + local type = http.formvalue("type") or "icmp" + local e = {} + e.index = index + if type == "tcping" and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then + if api.is_ipv6(address) then + address = api.get_ipv6_only(address) + end + e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, address)) + else + e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % address) + end + http_write_json(e) +end + +function urltest_node() + local index = http.formvalue("index") + local id = http.formvalue("id") + local e = {} + e.index = index + local result = luci.sys.exec(string.format("/usr/share/passwall/test.sh url_test_node %s %s", id, "urltest_node")) + local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") + if code ~= 0 then + local use_time_str = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") + local use_time = tonumber(use_time_str) + if use_time then + if use_time_str:find("%.") then + e.use_time = string.format("%.2f", use_time * 1000) + else + e.use_time = string.format("%.2f", use_time / 1000) + end + end + end + http_write_json(e) +end + +function add_node() + local redirect = http.formvalue("redirect") + + local uuid = api.gen_short_uuid() + uci:section(appname, "nodes", uuid) + + local group = http.formvalue("group") + if group and group ~= "default" then + uci:set(appname, uuid, "group", group) + end + + uci:set(appname, uuid, "type", "Socks") + + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_config", uuid)) + else + api.uci_save(uci, appname, true, true) + http_write_json({result = uuid}) + end +end + +function update_node() + local id = http.formvalue("id") -- Node id + local data = http.formvalue("data") -- json new Data + if id and data then + local data_t = jsonParse(data) or {} + if next(data_t) then + for k, v in pairs(data_t) do + uci:set(appname, id, k, v) + end + api.uci_save(uci, appname) + http_write_json_ok() + return + end + end + http_write_json_error() +end + +function set_node() + local protocol = http.formvalue("protocol") + local section = http.formvalue("section") + uci:set(appname, "@global[0]", protocol .. "_node", section) + if protocol == "tcp" then + local node_protocol = uci:get(appname, section, "protocol") + if node_protocol == "_shunt" then + local type = uci:get(appname, section, "type") + local dns_shunt = uci:get(appname, "@global[0]", "dns_shunt") + local dns_key = (dns_shunt == "smartdns") and "smartdns_dns_mode" or "dns_mode" + local dns_mode = uci:get(appname, "@global[0]", dns_key) + local new_dns_mode = (type == "Xray") and "xray" or "sing-box" + if dns_mode ~= new_dns_mode then + uci:set(appname, "@global[0]", dns_key, new_dns_mode) + uci:set(appname, "@global[0]", "v2ray_dns_mode", "tcp") + end + end + end + api.uci_save(uci, appname, true, true) + http.redirect(api.url("log")) +end + +function copy_node() + local section = http.formvalue("section") + local uuid = api.gen_short_uuid() + uci:section(appname, "nodes", uuid) + for k, v in pairs(uci:get_all(appname, section)) do + if not k:match("^%.") and k ~= "group" then + if k == "remarks" then v = (v or "") .. "(1)" end + uci:set(appname, uuid, k, v) + end + end + uci:set(appname, uuid, "add_mode", 1) + api.uci_save(uci, appname) + http.redirect(api.url("node_config", uuid)) +end + +function clear_all_nodes() + uci:set(appname, '@global[0]', "enabled", "0") + uci:set(appname, '@global[0]', "socks_enabled", "0") + uci:set(appname, '@haproxy_config[0]', "balancing_enable", "0") + uci:delete(appname, '@global[0]', "tcp_node") + uci:delete(appname, '@global[0]', "udp_node") + uci:foreach(appname, "socks", function(t) + uci:delete(appname, t[".name"]) + uci:set_list(appname, t[".name"], "autoswitch_backup_node", {}) + end) + uci:foreach(appname, "haproxy_config", function(t) + uci:delete(appname, t[".name"]) + end) + uci:foreach(appname, "acl_rule", function(t) + uci:delete(appname, t[".name"], "tcp_node") + uci:delete(appname, t[".name"], "udp_node") + end) + uci:foreach(appname, "nodes", function(node) + uci:delete(appname, node['.name']) + end) + uci:foreach(appname, "subscribe_list", function(t) + uci:delete(appname, t[".name"], "md5") + uci:delete(appname, t[".name"], "chain_proxy") + uci:delete(appname, t[".name"], "preproxy_node") + uci:delete(appname, t[".name"], "to_node") + end) + + api.uci_save(uci, appname, true, true) +end + +function delete_select_nodes() + local ids = http.formvalue("ids") + local redirect = http.formvalue("redirect") + string.gsub(ids, '[^' .. "," .. ']+', function(w) + local socks + uci:foreach(appname, "socks", function(t) + if t["node"] == w then + uci:delete(appname, t[".name"]) + socks = "Socks_" .. t[".name"] + end + local changed = false + local auto_switch_node_list = uci:get(appname, t[".name"], "autoswitch_backup_node") or {} + for i = #auto_switch_node_list, 1, -1 do + if w == auto_switch_node_list[i] then + table.remove(auto_switch_node_list, i) + changed = true + end + end + if changed then + uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list) + end + end) + local tcp_node = uci:get(appname, "@global[0]", "tcp_node") or "" + if tcp_node == w or tcp_node == socks then + uci:delete(appname, '@global[0]', "tcp_node") + end + local udp_node = uci:get(appname, "@global[0]", "udp_node") or "" + if udp_node == w or udp_node == socks then + uci:delete(appname, '@global[0]', "udp_node") + end + uci:foreach(appname, "haproxy_config", function(t) + if t["lbss"] == w then + uci:delete(appname, t[".name"]) + end + end) + uci:foreach(appname, "acl_rule", function(t) + if t["tcp_node"] == w or t["tcp_node"] == socks then + uci:delete(appname, t[".name"], "tcp_node") + end + if t["udp_node"] == w or t["udp_node"] == socks then + uci:delete(appname, t[".name"], "udp_node") + end + end) + uci:foreach(appname, "nodes", function(t) + if t["preproxy_node"] == w then + uci:delete(appname, t[".name"], "preproxy_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + if t["to_node"] == w then + uci:delete(appname, t[".name"], "to_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + local list_name = t["urltest_node"] and "urltest_node" or (t["balancing_node"] and "balancing_node") + if list_name then + local nodes = uci:get_list(appname, t[".name"], list_name) + if nodes then + local changed = false + local new_nodes = {} + for _, node in ipairs(nodes) do + if node ~= w and node ~= socks then + table.insert(new_nodes, node) + else + changed = true + end + end + if changed then + uci:set_list(appname, t[".name"], list_name, new_nodes) + end + end + end + if t["fallback_node"] == w or t["fallback_node"] == socks then + uci:delete(appname, t[".name"], "fallback_node") + end + end) + uci:foreach(appname, "subscribe_list", function(t) + if t["preproxy_node"] == w then + uci:delete(appname, t[".name"], "preproxy_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + if t["to_node"] == w then + uci:delete(appname, t[".name"], "to_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + end) + if (uci:get(appname, w, "add_mode") or "0") == "2" then + local group = uci:get(appname, w, "group") or "" + if group ~= "" then + uci:foreach(appname, "subscribe_list", function(t) + if t["remark"] == group then + uci:delete(appname, t[".name"], "md5") + end + end) + end + end + uci:delete(appname, w) + end) + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_list")) + else + api.uci_save(uci, appname, true, true) + end +end + +function get_node() + local id = http.formvalue("id") + local result = {} + local show_node_info = api.uci_get_type("global_other", "show_node_info", "0") + + local function add_is_ipv6_key(o) + if o and o.address and show_node_info == "1" then + local f = api.get_ipv6_full(o.address) + if f ~= "" then + o.ipv6 = true + o.full_address = f + end + end + end + + if id then + result = uci:get_all(appname, id) + add_is_ipv6_key(result) + else + local default_nodes = {} + local other_nodes = {} + uci:foreach(appname, "nodes", function(t) + add_is_ipv6_key(t) + if not t.group or t.group == "" then + default_nodes[#default_nodes + 1] = t + else + other_nodes[#other_nodes + 1] = t + end + end) + for i = 1, #default_nodes do result[#result + 1] = default_nodes[i] end + for i = 1, #other_nodes do result[#result + 1] = other_nodes[i] end + end + http_write_json(result) +end + +function save_node_order() + local ids = http.formvalue("ids") or "" + local new_order = {} + for id in ids:gmatch("([^,]+)") do + new_order[#new_order + 1] = id + end + for idx, name in ipairs(new_order) do + luci.sys.call(string.format("uci -q reorder %s.%s=%d", appname, name, idx - 1)) + end + api.sh_uci_commit(appname) + http_write_json({ status = "ok" }) +end + +function reassign_group() + local ids = http.formvalue("ids") or "" + local group = http.formvalue("group") or "default" + for id in ids:gmatch("([^,]+)") do + if group ~="" and group ~= "default" then + api.sh_uci_set(appname, id, "group", group) + else + api.sh_uci_del(appname, id, "group") + end + end + api.sh_uci_commit(appname) + http_write_json({ status = "ok" }) +end + +function save_node_list_opt() + local option = http.formvalue("option") or "" + local value = http.formvalue("value") or "" + if option ~= "" then + api.sh_uci_set(appname, "@global_other[0]", option, value, true) + end + http_write_json({ status = "ok" }) +end + +function update_rules() + local update = http.formvalue("update") or "" + if update == "" then + http_write_json_error({ message = "missing update target" }) + return + end + luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &") + http_write_json() +end + +function rollback_rules() + local arg_type = http.formvalue("type") + local rules = http.formvalue("rules") or "" + if arg_type ~= "geoip" and arg_type ~= "geosite" then + http_write_json_error() + return + end + local bak_dir = "/tmp/bak_v2ray/" + local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/") + local geo2rule = uci:get(appname, "@global_rules[0]", "geo2rule") or "0" + fs.move(bak_dir .. arg_type .. ".dat", geo_dir .. arg_type .. ".dat") + fs.rmdir(bak_dir) + if geo2rule == "1" and rules ~= "" then + luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. rules .. "' rollback > /dev/null") + end + http_write_json_ok() +end + +function server_user_update() + local id = http.formvalue("id") -- Node id + local data = http.formvalue("data") -- json new Data + if id and data then + local data_t = jsonParse(data) or {} + if next(data_t) then + for k, v in pairs(data_t) do + uci:set(appname .. "_server", id, k, v) + end + api.uci_save(uci, appname .. "_server") + http_write_json_ok() + return + end + end + http_write_json_error() +end + +function server_user_status() + local e = {} + e.index = http.formvalue("index") + e.status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/bin/' | grep -i '%s' >/dev/null", appname .. "_server", http.formvalue("id"))) == 0 + http_write_json(e) +end + +function server_user_log() + local id = http.formvalue("id") + if fs.access("/tmp/etc/passwall_server/" .. id .. ".log") then + local content = luci.sys.exec("cat /tmp/etc/passwall_server/" .. id .. ".log") + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function server_get_log() + http.write(luci.sys.exec("[ -f '/tmp/log/passwall_server.log' ] && cat /tmp/log/passwall_server.log")) +end + +function server_clear_log() + luci.sys.call("echo '' > /tmp/log/passwall_server.log") +end + +function app_check() + local json = api.to_check_self() + http_write_json(json) +end + +function com_check(comname) + local json = api.to_check("",comname) + http_write_json(json) +end + +function com_update(comname) + local json = nil + local task = http.formvalue("task") + if task == "extract" then + json = api.to_extract(comname, http.formvalue("file"), http.formvalue("subfix")) + elseif task == "move" then + json = api.to_move(comname, http.formvalue("file")) + else + json = api.to_download(comname, http.formvalue("url"), http.formvalue("size")) + end + + http_write_json(json) +end + +function read_rulelist() + local rule_type = http.formvalue("type") + local rule_path + if rule_type == "gfw" then + rule_path = "/usr/share/passwall/rules/gfwlist" + elseif rule_type == "chn" then + rule_path = "/usr/share/passwall/rules/chnlist" + elseif rule_type == "chnroute" then + rule_path = "/usr/share/passwall/rules/chnroute" + else + http.status(400, "Invalid rule type") + return + end + if fs.access(rule_path) then + http.prepare_content("text/plain") + http.write(fs.readfile(rule_path)) + end +end + +local backup_files = { + "/etc/config/passwall", + "/etc/config/passwall_server", + "/usr/share/passwall/rules/block_host", + "/usr/share/passwall/rules/block_ip", + "/usr/share/passwall/rules/direct_host", + "/usr/share/passwall/rules/direct_ip", + "/usr/share/passwall/rules/proxy_host", + "/usr/share/passwall/rules/proxy_ip" +} + +function create_backup() + local date = os.date("%y%m%d%H%M") + local tar_file = "/tmp/passwall-" .. date .. "-backup.tar.gz" + fs.remove(tar_file) + local cmd = "tar -czf " .. tar_file .. " " .. table.concat(backup_files, " ") + luci.sys.call(cmd) + http.header("Content-Disposition", "attachment; filename=passwall-" .. date .. "-backup.tar.gz") + http.header("X-Backup-Filename", "passwall-" .. date .. "-backup.tar.gz") + http.prepare_content("application/octet-stream") + http.write(fs.readfile(tar_file)) + fs.remove(tar_file) +end + +function restore_backup() + local result = { status = "error", message = "unknown error" } + local ok, err = pcall(function() + local filename = http.formvalue("filename") + local chunk = http.formvalue("chunk") + local chunk_index = tonumber(http.formvalue("chunk_index") or "-1") + local total_chunks = tonumber(http.formvalue("total_chunks") or "-1") + if not filename then + result = { status = "error", message = "Missing filename" } + return + end + if not chunk then + result = { status = "error", message = "Missing chunk data" } + return + end + local file_path = "/tmp/" .. filename + local decoded = nixio.bin.b64decode(chunk) + if not decoded then + result = { status = "error", message = "Base64 decode failed" } + return + end + local fp = io.open(file_path, "a+") + if not fp then + result = { status = "error", message = "Failed to open file: " .. file_path } + return + end + fp:write(decoded) + fp:close() + if chunk_index + 1 == total_chunks then + uci:revert(appname) + luci.sys.call("echo '' > /tmp/log/passwall.log") + api.log(" * PassWall é…置文件上传æˆåŠŸâ€¦") + local temp_dir = '/tmp/passwall_bak' + luci.sys.call("mkdir -p " .. temp_dir) + if luci.sys.call("tar -xzf " .. file_path .. " -C " .. temp_dir) == 0 then + for _, backup_file in ipairs(backup_files) do + local temp_file = temp_dir .. backup_file + if fs.access(temp_file) then + luci.sys.call("cp -f " .. temp_file .. " " .. backup_file) + end + end + api.log(" * PassWall é…置还原æˆåŠŸâ€¦") + api.log(" * é‡å¯ PassWall æœåŠ¡ä¸­â€¦\n") + luci.sys.call('/etc/init.d/passwall restart > /dev/null 2>&1 &') + luci.sys.call('/etc/init.d/passwall_server restart > /dev/null 2>&1 &') + result = { status = "success", message = "Upload completed", path = file_path } + else + api.log(" * PassWall é…置文件解压失败,请é‡è¯•ï¼") + result = { status = "error", message = "Decompression failed" } + end + luci.sys.call("rm -rf " .. temp_dir) + fs.remove(file_path) + else + result = { status = "success", message = "Chunk received" } + end + end) + if not ok then + result = { status = "error", message = tostring(err) } + end + http_write_json(result) +end + +function geo_view() + local action = http.formvalue("action") + local value = http.formvalue("value") + if not value or value == "" then + http.prepare_content("text/plain") + http.write(i18n.translate("Please enter query content!")) + return + end + local function get_rules(str, type) + local rules_id = {} + uci:foreach(appname, "shunt_rules", function(s) + local list + if type == "geoip" then list = s.ip_list else list = s.domain_list end + for line in string.gmatch((list or ""), "[^\r\n]+") do + if line ~= "" and not line:find("#") then + local prefix, main = line:match("^(.-):(.*)") + if not main then main = line end + if type == "geoip" and (api.datatypes.ipaddr(str) or api.datatypes.ip6addr(str)) then + if main:find(str, 1, true) then rules_id[#rules_id + 1] = s[".name"] end + else + if main == str then rules_id[#rules_id + 1] = s[".name"] end + end + end + end + end) + return rules_id + end + local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") + local geosite_path = geo_dir .. "/geosite.dat" + local geoip_path = geo_dir .. "/geoip.dat" + local geo_type, file_path, cmd + local geo_string = "" + local bin = api.finded_com("geoview") + if action == "lookup" then + if api.datatypes.ipaddr(value) or api.datatypes.ip6addr(value) then + geo_type, file_path = "geoip", geoip_path + else + geo_type, file_path = "geosite", geosite_path + end + cmd = string.format("%q -type %q -action lookup -input %q -value %q -lowmem=true", bin, geo_type, file_path, value) + geo_string = luci.sys.exec(cmd):lower() + if geo_string ~= "" then + local lines, rules, seen = {}, {}, {} + for line in geo_string:gmatch("([^\n]+)") do + lines[#lines + 1] = geo_type .. ":" .. line + for _, r in ipairs(get_rules(line, geo_type) or {}) do + if not seen[r] then seen[r] = true; rules[#rules + 1] = r end + end + end + for _, r in ipairs(get_rules(value, geo_type) or {}) do + if not seen[r] then seen[r] = true; rules[#rules + 1] = r end + end + geo_string = table.concat(lines, "\n") + if #rules > 0 then + geo_string = geo_string .. "\n--------------------\n" + geo_string = geo_string .. i18n.translate("Rules containing this value:") .. "\n" + geo_string = geo_string .. table.concat(rules, "\n") + end + end + elseif action == "extract" then + local prefix, list = value:match("^(geoip:)(.*)$") + if not prefix then + prefix, list = value:match("^(geosite:)(.*)$") + end + if prefix and list and list ~= "" then + geo_type = prefix:sub(1, -2) + file_path = (geo_type == "geoip") and geoip_path or geosite_path + cmd = string.format("%q -type %q -action extract -input %q -list %q -lowmem=true", bin, geo_type, file_path, list) + geo_string = luci.sys.exec(cmd) + end + end + http.prepare_content("text/plain") + if geo_string and geo_string ~="" then + http.write(geo_string) + else + http.write(i18n.translate("No results were found!")) + end +end + +function subscribe_del_node() + local remark = http.formvalue("remark") + if remark and remark ~= "" then + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate " .. luci.util.shellquote(remark) .. " > /dev/null 2>&1") + end + http.status(200, "OK") +end + +function subscribe_del_all() + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1") + http.status(200, "OK") +end + +function subscribe_manual() + local section = http.formvalue("section") or "" + local current_url = http.formvalue("url") or "" + if section == "" or current_url == "" then + http_write_json({ success = false, msg = "Missing section or URL, skip." }) + return + end + local uci_url = api.sh_uci_get(appname, section, "url") + if not uci_url or uci_url == "" then + http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") }) + return + end + if uci_url ~= current_url then + api.sh_uci_set(appname, section, "url", current_url, true) + end + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &") + http_write_json({ success = true, msg = "Subscribe triggered." }) +end + +function subscribe_manual_all() + local sections = http.formvalue("sections") or "" + local urls = http.formvalue("urls") or "" + if sections == "" or urls == "" then + http_write_json({ success = false, msg = "Missing section or URL, skip." }) + return + end + local section_list = util.split(sections, ",") + local url_list = util.split(urls, ",") + -- 检查是å¦å­˜åœ¨æœªä¿å­˜é…ç½® + for i, section in ipairs(section_list) do + local uci_url = api.sh_uci_get(appname, section, "url") + if not uci_url or uci_url == "" then + http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") }) + return + end + end + -- ä¿å­˜æœ‰å˜åŠ¨çš„url + for i, section in ipairs(section_list) do + local current_url = url_list[i] or "" + local uci_url = api.sh_uci_get(appname, section, "url") + if current_url ~= "" and uci_url ~= current_url then + api.sh_uci_set(appname, section, "url", current_url, true) + end + end + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &") + http_write_json({ success = true, msg = "Subscribe triggered." }) +end + +function flush_set() + local redirect = http.formvalue("redirect") or "0" + local reload = http.formvalue("reload") or "0" + if reload == "1" then + uci:set(appname, '@global[0]', "flush_set", "1") + api.uci_save(uci, appname, true, true) + else + api.sh_uci_set(appname, "@global[0]", "flush_set", "1", true) + end + if redirect == "1" then + http.redirect(api.url("log")) + end +end + +function fetch_certsha256() + local id = http.formvalue("id") or "" + local address = (id ~= "") and uci:get(appname, id, "address") or "" + local port = (id ~= "") and uci:get(appname, id, "port") or 0 + if id == "" or address == "" or not api.datatypes.hostname(address) or port == 0 then + http_write_json_error() + return + end + local data = api.fetch_cert_sha256(address, port, 5) + http_write_json(data ~= "" and { code = 1, data = data } or { code = 0 }) +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua new file mode 100644 index 00000000..9d5edc7e --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua @@ -0,0 +1,104 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local sys = api.sys + +m = Map(appname) +api.set_apply_on_parse(m) + +s = m:section(TypedSection, "global", translate("ACLs"), "" .. translate("ACLs is a tools which used to designate specific IP proxy mode.") .. "") +s.anonymous = true + +o = s:option(Flag, "acl_enable", translate("Main switch")) +o.rmempty = false +o.default = false + +-- [[ ACLs Settings ]]-- +s = m:section(TypedSection, "acl_rule") +s.template = "cbi/tblsection" +s.sortable = true +s.anonymous = true +s.addremove = true +s.extedit = api.url("acl_config", "%s") +function s.create(e, t) + t = TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end +function s.remove(e, t) + sys.call("rm -rf /tmp/etc/passwall_tmp/dns_" .. t .. "*") + TypedSection.remove(e, t) +end + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +---- Remarks +o = s:option(Value, "remarks", translate("Remarks")) +o.rmempty = true + +local mac_t = {} +sys.net.mac_hints(function(e, t) + mac_t[e] = { + ip = t, + mac = e + } +end) + +o = s:option(DummyValue, "sources", translate("Source")) +o.rawhtml = true +o.cfgvalue = function(t, n) + local e = '' + local v = Value.cfgvalue(t, n) or '-' + string.gsub(v, '[^' .. " " .. ']+', function(w) + local a = w + if mac_t[w] then + a = a .. ' (' .. mac_t[w].ip .. ')' + end + if #e > 0 then + e = e .. "
" + end + e = e .. a + end) + return e +end + +o = s:option(DummyValue, "interface", translate("Source Interface")) +o.cfgvalue = function(t, n) + local v = Value.cfgvalue(t, n) or '-' + return v +end + +--[[ +---- TCP No Redir Ports +o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) +o.default = "default" +o:value("disable", translate("No patterns are used")) +o:value("default", translate("Default")) +o:value("1:65535", translate("All")) + +---- UDP No Redir Ports +o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports")) +o.default = "default" +o:value("disable", translate("No patterns are used")) +o:value("default", translate("Default")) +o:value("1:65535", translate("All")) + +---- TCP Redir Ports +o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports")) +o.default = "default" +o:value("default", translate("Default")) +o:value("1:65535", translate("All")) +o:value("80,443", "80,443") +o:value("80:65535", "80 " .. translate("or more")) +o:value("1:443", "443 " .. translate("or less")) + +---- UDP Redir Ports +o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports")) +o.default = "default" +o:value("default", translate("Default")) +o:value("1:65535", translate("All")) +o:value("53", "53") +]]-- + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua new file mode 100644 index 00000000..d908e37d --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua @@ -0,0 +1,604 @@ +local api = require "luci.passwall.api" +local appname = "passwall" + +m = Map(appname) +m.redirect = api.url("acl") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local fs = api.fs +local sys = api.sys +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_gfwlist = fs.access("/usr/share/passwall/rules/gfwlist") +local has_chnlist = fs.access("/usr/share/passwall/rules/chnlist") +local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute") + +local port_validate = function(self, value, t) + return value:gsub("-", ":") +end + +local nodes_table = {} +for _, e in ipairs(api.get_valid_nodes()) do + nodes_table[#nodes_table + 1] = e +end + +local normal_list = {} +for _, v in pairs(nodes_table) do + if v.node_type == "normal" then + normal_list[#normal_list + 1] = v + end +end + +local socks_list = {} +m.uci:foreach(appname, "socks", function(s) + if s.enabled == "1" and s.node then + socks_list[#socks_list + 1] = { + id = "Socks_" .. s[".name"], + remark = translate("Socks Config") .. " " .. string.format("[%s %s]", s.port, translate("Port")), + group = "Socks" + } + end +end) + +local dynamicList_write = function(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + t = table.concat(t, " ") + return DynamicList.write(self, section, t) +end + +-- [[ ACLs Settings ]]-- +s = m:section(NamedSection, arg[1], translate("ACLs"), translate("ACLs")) +s.addremove = false +s.dynamic = false + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +---- Remarks +o = s:option(Value, "remarks", translate("Remarks")) +o.default = arg[1] +o.rmempty = false + +o = s:option(Value, "interface", translate("Source Interface")) +o:value("", translate("All")) +local iface = api.get_network_devices() +for _, d in ipairs(iface) do + o:value(d.name, d.label) +end +o.validate = function(self, value, section) + if value == "" or value:match("^[a-zA-Z0-9][a-zA-Z0-9%.%_%-]*$") then + return value + end + return nil, translate("Invalid interface name") +end + +local mac_t = {} +sys.net.mac_hints(function(e, t) + mac_t[#mac_t + 1] = { + ip = t, + mac = e + } +end) +table.sort(mac_t, function(a,b) + if #a.ip < #b.ip then + return true + elseif #a.ip == #b.ip then + if a.ip < b.ip then + return true + else + return #a.ip < #b.ip + end + end + return false +end) + +---- Source +sources = s:option(DynamicList, "sources", translate("Source")) +sources.description = "
  • " .. translate("Example:") +.. "
  • " .. translate("MAC") .. ": 00:00:00:FF:FF:FF" +.. "
  • " .. translate("IP") .. ": 192.168.1.100" +.. "
  • " .. translate("IP CIDR") .. ": 192.168.1.0/24" +.. "
  • " .. translate("IP range") .. ": 192.168.1.100-192.168.1.200" +.. "
  • " .. translate("IPSet") .. ": ipset:lanlist" +.. "
" +sources.cast = "string" +for _, key in pairs(mac_t) do + sources:value(key.mac, "%s (%s)" % {key.mac, key.ip}) +end +sources.cfgvalue = function(self, section) + local value + if self.tag_error[section] then + value = self:formvalue(section) + else + value = self.map:get(section, self.option) + if type(value) == "string" then + local value2 = {} + string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end) + value = value2 + end + end + return value +end +sources.validate = function(self, value, t) + local err = {} + for _, v in ipairs(value) do + local flag = false + if v:find("ipset:") and v:find("ipset:") == 1 then + local ipset = v:gsub("ipset:", "") + if ipset and ipset ~= "" then + flag = true + end + end + + if flag == false and datatypes.macaddr(v) then + flag = true + end + + if flag == false and datatypes.ip4addr(v) then + flag = true + end + + if flag == false and api.iprange(v) then + flag = true + end + + if flag == false then + err[#err + 1] = v + end + end + + if #err > 0 then + self:add_error(t, "invalid", translate("Not true format, please re-enter!")) + for _, v in ipairs(err) do + self:add_error(t, "invalid", v) + end + end + + return value +end +sources.write = dynamicList_write + +---- TCP No Redir Ports +local TCP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "tcp_no_redir_ports") +o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) +o:value("", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")") +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +---- UDP No Redir Ports +local UDP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_no_redir_ports") +o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"), + "" .. + translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") .. + "") +o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")") +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +o = s:option(DummyValue, "_hide_node_option", "") +o.template = "passwall/cbi/hidevalue" +o.value = "1" +o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" }) +if TCP_NO_REDIR_PORTS == "1:65535" and UDP_NO_REDIR_PORTS == "1:65535" then + o:depends({ tcp_no_redir_ports = "", udp_no_redir_ports = "" }) +end + +o = s:option(Flag, "use_global_config", translatef("Use global config")) +o.default = "0" +o.rmempty = false +o:depends({ _hide_node_option = "1", ['!reverse'] = true }) + +o = s:option(ListValue, "tcp_node", "" .. translate("TCP Node") .. "") +o.default = "" +o:depends({ _hide_node_option = false, use_global_config = false }) +o.template = appname .. "/cbi/nodes_listvalue" +o.group = {} +o.remove = function(self, section) + m:del(section, self.option) + m:del(section, "udp_node") +end + +o = s:option(DummyValue, "_tcp_node_bool", "") +o.template = "passwall/cbi/hidevalue" +o.value = "1" +o:depends({ tcp_node = "", ['!reverse'] = true }) + +o = s:option(ListValue, "udp_node", "" .. translate("UDP Node") .. "") +o.default = "" +o:value("", translate("Close")) +o:value("tcp", translate("Same as the tcp node")) +o:depends({ _tcp_node_bool = "1", _node_sel_other = "1" }) +o.template = appname .. "/cbi/nodes_listvalue" +o.group = {"",""} +o.remove = function(self, section) + local v = s.fields["shunt_udp_node"]:formvalue(section) + if not v then + return m:del(section, self.option) + end +end + +o = s:option(ListValue, "shunt_udp_node", "" .. translate("UDP Node") .. "") +o:value("close", translate("Close")) +o:value("tcp", translate("Same as the tcp node")) +o:depends({ _tcp_node_bool = "1", _node_sel_shunt = "1" }) +o.cfgvalue = function(self, section) + local v = m:get(section, "udp_node") or "" + if v == "" then v = "close" end + if v ~= "close" and v ~= "tcp" then v = "tcp" end + return v +end +o.write = function(self, section, value) + if value == "close" then value = "" end + return m:set(section, "udp_node", value) +end + +o = s:option(DummyValue, "_udp_node_bool", "") +o.template = "passwall/cbi/hidevalue" +o.value = "1" +o:depends({ udp_node = "", ['!reverse'] = true }) +o:depends({ shunt_udp_node = "tcp" }) + +---- TCP Proxy Drop Ports +local TCP_PROXY_DROP_PORTS = m:get("@global_forwarding[0]", "tcp_proxy_drop_ports") +o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports")) +o:value("", translate("Use global config") .. "(" .. TCP_PROXY_DROP_PORTS .. ")") +o:value("disable", translate("No patterns are used")) +o.validate = port_validate +o:depends({ use_global_config = true }) +o:depends({ _tcp_node_bool = "1" }) + +---- UDP Proxy Drop Ports +local UDP_PROXY_DROP_PORTS = m:get("@global_forwarding[0]", "udp_proxy_drop_ports") +o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports")) +o:value("", translate("Use global config") .. "(" .. UDP_PROXY_DROP_PORTS .. ")") +o:value("disable", translate("No patterns are used")) +o:value("443", translate("QUIC")) +o.validate = port_validate +o:depends({ use_global_config = true }) +o:depends({ _tcp_node_bool = "1" }) + +---- TCP Redir Ports +local TCP_REDIR_PORTS = m:get("@global_forwarding[0]", "tcp_redir_ports") +o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"), translatef("Only work with using the %s node.", "TCP")) +o:value("", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")") +o:value("1:65535", translate("All")) +o:value("80,443", "80,443") +o:value("80:65535", "80 " .. translate("or more")) +o:value("1:443", "443 " .. translate("or less")) +o.validate = port_validate +o:depends({ use_global_config = true }) +o:depends({ _tcp_node_bool = "1" }) + +---- UDP Redir Ports +local UDP_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_redir_ports") +o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports"), translatef("Only work with using the %s node.", "UDP")) +o:value("", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")") +o:value("1:65535", translate("All")) +o:value("53", "53") +o.validate = port_validate +o:depends({ use_global_config = true }) +o:depends({ _udp_node_bool = "1" }) + +o = s:option(DummyValue, "tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', + translate("The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000.")) +end +o:depends({ use_global_config = true }) +o:depends({ _tcp_node_bool = "1" }) + +o = s:option(Flag, "use_direct_list", translatef("Use %s", translate("Direct List"))) +o.default = "1" +o:depends({ _tcp_node_bool = "1" }) + +o = s:option(Flag, "use_proxy_list", translatef("Use %s", translate("Proxy List"))) +o.default = "1" +o:depends({ _tcp_node_bool = "1" }) + +o = s:option(Flag, "use_block_list", translatef("Use %s", translate("Block List"))) +o.default = "1" +o:depends({ _tcp_node_bool = "1" }) + +if has_gfwlist then + o = s:option(Flag, "use_gfw_list", translatef("Use %s", translate("GFW List"))) + o.default = "1" + o:depends({ _tcp_node_bool = "1" }) +end + +if has_chnlist or has_chnroute then + o = s:option(ListValue, "chn_list", translate("China List")) + o:value("0", translate("Close(Not use)")) + o:value("direct", translate("Direct Connection")) + o:value("proxy", translate("Proxy")) + o.default = "direct" + o:depends({ _tcp_node_bool = "1" }) +end + +o = s:option(ListValue, "tcp_proxy_mode", "TCP " .. translate("Proxy Mode")) +o:value("disable", translate("No Proxy")) +o:value("proxy", translate("Proxy")) +o:depends({ _tcp_node_bool = "1" }) + +o = s:option(ListValue, "udp_proxy_mode", "UDP " .. translate("Proxy Mode")) +o:value("disable", translate("No Proxy")) +o:value("proxy", translate("Proxy")) +o:depends({ _udp_node_bool = "1" }) + +o = s:option(DummyValue, "switch_mode", " ") +o.template = appname .. "/global/proxy" +o:depends({ _tcp_node_bool = "1" }) + +-- Node → DNS Depends Settings +o = s:option(DummyValue, "_node_sel_shunt", "") +o.template = appname .. "/cbi/hidevalue" +o.value = "1" +o:depends({ tcp_node = "__always__" }) + +o = s:option(DummyValue, "_node_sel_other", "") +o.template = appname .. "/cbi/hidevalue" +o.value = "1" +o:depends({ _node_sel_shunt = "1", ['!reverse'] = true }) + +---- DNS +o = s:option(ListValue, "dns_shunt", "DNS " .. translate("Shunt")) +o.default = "chinadns-ng" +o:value("dnsmasq", "Dnsmasq") +o:value("chinadns-ng", translate("ChinaDNS-NG (recommended)")) +o:depends({ _tcp_node_bool = "1" }) + +o = s:option(DummyValue, "view_chinadns_log", " ") +o.template = appname .. "/acl/view_chinadns_log" + +o = s:option(Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature.")) +o.default = "0" +o:depends({ _tcp_node_bool = "1" }) + +---- DNS Forward Mode +o = s:option(ListValue, "dns_mode", translate("Filter Mode")) +if api.is_finded("dns2socks") then + o:value("dns2socks", "dns2socks") +end +if has_singbox then + o:value("sing-box", "Sing-Box") +end +if has_xray then + o:value("xray", "Xray") +end +o:depends({ _tcp_node_bool = "1", _node_sel_other = "1" }) +o.write = function(self, section, value) + if value == "dns2socks" then + m:del(section, "v2ray_dns_mode") + end + return ListValue.write(self, section, value) +end +o.remove = function(self, section) + local f = s.fields["tcp_node"] + local id_val = f and f:formvalue(section) or "" + if id_val == "" then + return m:del(section, self.option) + end + for _, v in pairs(nodes_table) do + if v.id == id_val then + local new_val = (v.type == "Xray") and "xray" or "sing-box" + m:set(section, self.option, new_val) + + local dns_field = s.fields[v.type == "Xray" and "xray_dns_mode" or "singbox_dns_mode"] + local v2ray_dns_mode = dns_field and dns_field:formvalue(section) + if v2ray_dns_mode then + m:set(section, "v2ray_dns_mode", v2ray_dns_mode) + end + + break + end + end +end + +o = s:option(ListValue, "xray_dns_mode", translate("Request protocol")) +o.default = "tcp" +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("doh", "DoH") +o:depends("dns_mode", "xray") +o.cfgvalue = function(self, section) + return m:get(section, "v2ray_dns_mode") +end +o.write = function(self, section, value) + if s.fields["dns_mode"]:formvalue(section) == "xray" then + return m:set(section, "v2ray_dns_mode", value) + end +end + +o = s:option(ListValue, "singbox_dns_mode", translate("Request protocol")) +o.default = "tcp" +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("doh", "DoH") +o:value("http3", "HTTP3(DoH3)") +o:depends("dns_mode", "sing-box") +o.cfgvalue = function(self, section) + return m:get(section, "v2ray_dns_mode") +end +o.write = function(self, section, value) + if s.fields["dns_mode"]:formvalue(section) == "sing-box" then + return m:set(section, "v2ray_dns_mode", value) + end +end + +---- DNS Forward +o = s:option(Value, "remote_dns", translate("Remote DNS")) +o.default = "1.1.1.1" +o:value("1.1.1.1", "1.1.1.1 (CloudFlare)") +o:value("1.1.1.2", "1.1.1.2 (CloudFlare-Security)") +o:value("8.8.4.4", "8.8.4.4 (Google)") +o:value("8.8.8.8", "8.8.8.8 (Google)") +o:value("9.9.9.9", "9.9.9.9 (Quad9-Recommended)") +o:value("149.112.112.112", "149.112.112.112 (Quad9-Recommended)") +o:value("208.67.220.220", "208.67.220.220 (OpenDNS)") +o:value("208.67.222.222", "208.67.222.222 (OpenDNS)") +o:depends({dns_mode = "dns2socks"}) +o:depends({xray_dns_mode = "udp"}) +o:depends({xray_dns_mode = "tcp"}) +o:depends({singbox_dns_mode = "udp"}) +o:depends({singbox_dns_mode = "tcp"}) + +o = s:option(Value, "remote_dns_doh", translate("Remote DNS DoH")) +o.description = translate("Format: URL[,IP] (optional IP to map the domain in the URL)") +o:value("https://1.1.1.1/dns-query", "1.1.1.1 (CloudFlare)") +o:value("https://1.1.1.2/dns-query", "1.1.1.2 (CloudFlare-Security)") +o:value("https://8.8.4.4/dns-query", "8.8.4.4 (Google)") +o:value("https://8.8.8.8/dns-query", "8.8.8.8 (Google)") +o:value("https://9.9.9.9/dns-query", "9.9.9.9 (Quad9)") +o:value("https://149.112.112.112/dns-query", "149.112.112.112 (Quad9)") +o:value("https://208.67.222.222/dns-query", "208.67.222.222 (OpenDNS)") +o:value("https://dns.adguard.com/dns-query,94.140.14.14", "94.140.14.14 (AdGuard)") +o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "116.202.176.26 (LibreDNS)") +o:value("https://doh.libredns.gr/ads,116.202.176.26", "116.202.176.26 (LibreDNS-NoAds)") +o.default = o.keylist[1] +o.validate = function(self, value, t) + if value ~= "" then + value = api.trim(value) + local flag = 0 + local util = require "luci.util" + local val = util.split(value, ",") + local url = val[1] + val[1] = nil + for i = 1, #val do + local v = val[i] + if v then + if not api.datatypes.ipmask4(v) then + flag = 1 + end + end + end + if flag == 0 then + return value + end + end + return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP" +end +o:depends({xray_dns_mode = "doh"}) +o:depends({singbox_dns_mode = "doh"}) +o:depends({singbox_dns_mode = "http3"}) + +o = s:option(Value, "remote_dns_client_ip", translate("EDNS Client Subnet")) +o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "
" .. + translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).") +o.datatype = "ipaddr" +o:depends({dns_mode = "sing-box"}) +o:depends({dns_mode = "xray"}) +o:depends({_node_sel_shunt = "1"}) + +o = s:option(Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy.")) +o.default = "0" +o.rmempty = false +o:depends({dns_mode = "sing-box"}) +o:depends({dns_mode = "xray"}) +o.validate = function(self, value, t) + if value and value == "1" then + local _dns_mode = s.fields["dns_mode"]:formvalue(t) + local _tcp_node = s.fields["tcp_node"]:formvalue(t) + if _dns_mode and _tcp_node then + if (m:get(_tcp_node, "type") or ""):lower() ~= _dns_mode and not _tcp_node:find("Socks_") then + return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode) + end + end + end + return value +end + +o = s:option(ListValue, "chinadns_ng_default_tag", translate("Default DNS")) +o.default = "none" +o:value("gfw", translate("Remote DNS")) +o:value("chn", translate("Direct DNS")) +o:value("none", translate("Smart, Do not accept no-ip reply from Direct DNS")) +o:value("none_noip", translate("Smart, Accept no-ip reply from Direct DNS")) +local desc = "
    " + .. "
  • " .. translate("When not matching any domain name list:") .. "
  • " + .. "
  • " .. translate("Remote DNS: Can avoid more DNS leaks, but some domestic domain names maybe to proxy!") .. "
  • " + .. "
  • " .. translate("Direct DNS: Internet experience may be better, but DNS will be leaked!") .. "
  • " +o.description = desc + .. "
  • " .. translate("Smart: Forward to both direct and remote DNS, if the direct DNS resolution result is a mainland China IP, then use the direct result, otherwise use the remote result.") .. "
  • " + .. "
  • " .. translate("In smart mode, no-ip reply from Direct DNS:") .. "
  • " + .. "
  • " .. translate("Do not accept: Wait and use Remote DNS Reply.") .. "
  • " + .. "
  • " .. translate("Accept: Trust the Reply, using this option can improve DNS resolution speeds for some mainland IPv4-only sites.") .. "
  • " + .. "
" +o:depends({dns_shunt = "chinadns-ng", tcp_proxy_mode = "proxy", chn_list = "direct"}) + +o = s:option(Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("Force queries with qtype 65 to respond with an SOA record.")) +o.default = "0" +o.rmempty = false +o:depends({dns_shunt = "chinadns-ng"}) + +o = s:option(ListValue, "use_default_dns", translate("Default DNS")) +o.default = "direct" +o:value("remote", translate("Remote DNS")) +o:value("direct", translate("Direct DNS")) +o.description = desc .. "" +o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"}) + +local tcp = s.fields["tcp_node"] +local udp = s.fields["udp_node"] +for k, v in pairs(socks_list) do + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +for k, v in pairs(nodes_table) do + if #normal_list == 0 then + s.fields["dns_mode"]:depends({ _tcp_node_bool = "1" }) + break + end + if v.protocol == "_shunt" then + if v.type == "Xray" and has_xray then + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + + s.fields["xray_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id }) + s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id }) + end + if v.type == "sing-box" and has_singbox then + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + + s.fields["singbox_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id }) + s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id }) + end + else + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end +end + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua new file mode 100644 index 00000000..f87781f9 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua @@ -0,0 +1,32 @@ +local api = require "luci.passwall.api" +local appname = "passwall" + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ App Settings ]]-- +s = m:section(TypedSection, "global_app", translate("App Update"), + "" .. + translate("Please confirm that your firmware supports FPU.") .. + "") +s.anonymous = true +s:append(Template(appname .. "/app_update/app_version")) + +local k, v +local com = require "luci.passwall.com" +for _, k in ipairs(com.order) do + v = com[k] + if k ~= "chinadns-ng" then + o = s:option(Value, k:gsub("%-","_") .. "_file", translatef("%s App Path", v.name)) + o.default = v.default_path or ("/usr/bin/" .. k) + o.rmempty = false + end +end + +o = s:option(DummyValue, "tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', translate("if you want to run from memory, change the path, /tmp beginning then save the application and update it manually.")) +end + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua new file mode 100644 index 00000000..49a0d62a --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -0,0 +1,842 @@ +api = require "luci.passwall.api" +appname = "passwall" +datatypes = api.datatypes +local fs = api.fs +has_singbox = api.finded_com("sing-box") +has_xray = api.finded_com("xray") +local has_gfwlist = fs.access("/usr/share/passwall/rules/gfwlist") +local has_chnlist = fs.access("/usr/share/passwall/rules/chnlist") +local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute") + +m = Map(appname) +api.set_apply_on_parse(m) + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local nodes_table = {} +for _, e in ipairs(api.get_valid_nodes()) do + nodes_table[#nodes_table + 1] = e +end + +local normal_list = {} +local balancing_list = {} +local urltest_list = {} +local shunt_list = {} +local iface_list = {} +for _, v in pairs(nodes_table) do + if v.node_type == "normal" then + normal_list[#normal_list + 1] = v + end + if v.protocol and v.protocol == "_balancing" then + balancing_list[#balancing_list + 1] = v + end + if v.protocol and v.protocol == "_urltest" then + urltest_list[#urltest_list + 1] = v + end + if v.protocol and v.protocol == "_shunt" then + shunt_list[#shunt_list + 1] = v + end + if v.protocol and v.protocol == "_iface" then + iface_list[#iface_list + 1] = v + end +end + +local socks_list = {} + +local tcp_socks_server = "127.0.0.1" .. ":" .. (m:get("@global[0]", "tcp_node_socks_port") or "1070") +local socks_table = {} +socks_table[#socks_table + 1] = { + id = tcp_socks_server, + remark = tcp_socks_server .. " - " .. translate("TCP Node") +} +m.uci:foreach(appname, "socks", function(s) + if s.enabled == "1" and s.node then + local id, remark + for k, n in pairs(nodes_table) do + if (s.node == n.id) then + remark = n["remark"]; break + end + end + id = "127.0.0.1" .. ":" .. s.port + socks_table[#socks_table + 1] = { + id = id, + remark = id .. " - " .. (remark or translate("Misconfigured")) + } + socks_list[#socks_list + 1] = { + id = "Socks_" .. s[".name"], + remark = translate("Socks Config") .. " " .. string.format("[%s %s]", s.port, translate("Port")), + group = "Socks" + } + end +end) + +local doh_validate = function(self, value, t) + value = value:gsub("%s+", "") + if value ~= "" then + local flag = 0 + local util = require "luci.util" + local val = util.split(value, ",") + local url = val[1] + val[1] = nil + for i = 1, #val do + local v = val[i] + if v then + if not datatypes.ipmask4(v) and not datatypes.ipmask6(v) then + flag = 1 + end + end + end + if flag == 0 then + return value + end + end + return nil, translatef("%s request address","DoH") .. " " .. translate("Format must be:") .. " URL,IP" +end + +m:append(Template(appname .. "/global/status")) + +global_cfgid = m:get("@global[0]")[".name"] + +s = m:section(TypedSection, "global") +s.anonymous = true +s.addremove = false + +s:tab("Main", translate("Main")) + +-- [[ Global Settings ]]-- +o = s:taboption("Main", Flag, "enabled", translate("Main switch")) +o.rmempty = false + +---- TCP Node +o = s:taboption("Main", ListValue, "tcp_node", "" .. translate("TCP Node") .. "") +o.template = appname .. "/cbi/nodes_listvalue" +o:value("", translate("Close")) +o.group = {""} + +---- UDP Node +o = s:taboption("Main", ListValue, "udp_node", "" .. translate("UDP Node") .. "") +o.template = appname .. "/cbi/nodes_listvalue" +o:value("", translate("Close")) +o:value("tcp", translate("Same as the tcp node")) +o.group = {"",""} +o:depends("_node_sel_other", "1") +o.remove = function(self, section) + local v = s.fields["shunt_udp_node"]:formvalue(section) + if not v then + return m:del(section, self.option) + end +end + +o = s:taboption("Main", ListValue, "shunt_udp_node", "" .. translate("UDP Node") .. "") +o:value("close", translate("Close")) +o:value("tcp", translate("Same as the tcp node")) +o:depends("_node_sel_shunt", "1") +o.cfgvalue = function(self, section) + local v = m:get(section, "udp_node") or "" + if v == "" then v = "close" end + if v ~= "close" and v ~= "tcp" then v = "tcp" end + return v +end +o.write = function(self, section, value) + if value == "close" then value = "" end + return m:set(section, "udp_node", value) +end + +-- Shunt Start +if (has_singbox or has_xray) and #nodes_table > 0 then + if #normal_list > 0 or #iface_list > 0 then + current_node_id = m.uci:get(appname, global_cfgid, "tcp_node") + current_node = current_node_id and m.uci:get_all(appname, current_node_id) or {} + if current_node.protocol == "_shunt" then + local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua") + setfenv(shunt_lua, getfenv(1))(m, s, { + node_id = current_node_id, + node = current_node, + socks_list = socks_list, + urltest_list = urltest_list, + balancing_list = balancing_list, + iface_list = iface_list, + normal_list = normal_list, + verify_option = s.fields["tcp_node"], + tab = "Shunt", + tab_desc = translate("Shunt Rule") + }) + end + else + local tips = s:taboption("Main", DummyValue, "tips", " ") + tips.rawhtml = true + tips.cfgvalue = function(t, n) + return string.format('%s', translate("There are no available nodes, please add or subscribe nodes first.")) + end + tips:depends({ tcp_node = "", ["!reverse"] = true }) + for k, v in pairs(shunt_list) do + tips:depends("tcp_node", v.id) + end + for k, v in pairs(balancing_list) do + tips:depends("tcp_node", v.id) + end + end +end + +o = s:taboption("Main", Value, "tcp_node_socks_port", translate("TCP Node") .. " Socks " .. translate("Listen Port")) +o.default = 1070 +o.datatype = "port" +o:depends({ tcp_node = "", ["!reverse"] = true }) +--[[ +if has_singbox or has_xray then + o = s:taboption("Main", Value, "tcp_node_http_port", translate("TCP Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) + o.default = 0 + o.datatype = "port" +end +]]-- +o = s:taboption("Main", Flag, "tcp_node_socks_bind_local", translate("TCP Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "1" +o:depends({ tcp_node = "", ["!reverse"] = true }) + +-- Node → DNS Depends Settings +o = s:taboption("Main", DummyValue, "_node_sel_shunt", "") +o.template = appname .. "/cbi/hidevalue" +o.value = "1" +o:depends({ tcp_node = "__always__" }) + +o = s:taboption("Main", DummyValue, "_node_sel_other", "") +o.template = appname .. "/cbi/hidevalue" +o.value = "1" +o:depends({ _node_sel_shunt = "1", ['!reverse'] = true }) + +-- [[ DNS Settings ]]-- +s:tab("DNS", translate("DNS")) + +o = s:taboption("DNS", ListValue, "dns_shunt", "DNS " .. translate("Shunt")) +o:value("dnsmasq", "Dnsmasq") +o:value("chinadns-ng", translate("ChinaDNS-NG (recommended)")) +if api.is_finded("smartdns") then + o:value("smartdns", "SmartDNS") + o.write = function(self, section, value) + if value ~= "smartdns" then + m:del(section, "group_domestic") + end + return ListValue.write(self, section, value) + end + + o = s:taboption("DNS", Value, "group_domestic", translate("Domestic group name")) + o.placeholder = "local" + o.rmempty = false + o:depends("dns_shunt", "smartdns") + o.description = translate("You only need to configure domestic DNS packets in SmartDNS, and fill in the domestic DNS group name here.") + o.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translatef("%s cannot be empty.", "SmartDNS " .. translate("Domestic group name")) + end + return value + end +end + +o = s:taboption("DNS", ListValue, "direct_dns_mode", translate("Direct DNS") .. " " .. translate("Request protocol")) +o:value("", translate("Auto")) +o:value("udp", translatef("Requery DNS By %s", "UDP")) +o:value("tcp", translatef("Requery DNS By %s", "TCP")) +o:depends({dns_shunt = "dnsmasq"}) +o:depends({dns_shunt = "chinadns-ng"}) + +o = s:taboption("DNS", Value, "direct_dns", translate("Direct DNS")) +o.datatype = "or(ipaddr,ipaddrport)" +o.default = "223.5.5.5" +o:value("223.5.5.5") +o:value("223.6.6.6") +o:value("180.184.1.1") +o:value("180.184.2.2") +o:value("114.114.114.114") +o:value("114.114.115.115") +o:value("119.28.28.28") +o:depends("direct_dns_mode", "udp") +o:depends("direct_dns_mode", "tcp") + +o = s:taboption("DNS", Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6")) +o.default = "0" + +-- TCPåˆ†æµæ—¶dns过滤模å¼ä¿å­˜é€»è¾‘ +function dns_mode_save(section) + local f = s.fields["tcp_node"] + local id_val = f and f:formvalue(section) or "" + if id_val == "" then + return + end + for _, v in pairs(shunt_list) do + if v.id == id_val then + local type_val = v.type + if type_val and (type_val == "Xray" or type_val == "sing-box") then + local dns_shunt_val = s.fields["dns_shunt"]:formvalue(section) + local dns_mode_val = (dns_shunt_val ~= "smartdns") and "dns_mode" or "smartdns_dns_mode" + local current_val = m:get(section, dns_mode_val) or "" + local new_val = (type_val == "Xray") and "xray" or "sing-box" + + if current_val ~= new_val then + m:set(section, dns_mode_val, new_val) + m:del(section, (dns_mode_val == "dns_mode") and "smartdns_dns_mode" or "dns_mode") + end + + local dns_field = s.fields[type_val == "Xray" and "xray_dns_mode" or "singbox_dns_mode"] + local v2ray_dns_mode = dns_field and dns_field:formvalue(section) + if v2ray_dns_mode and m:get(section, "v2ray_dns_mode") ~= v2ray_dns_mode then + m:set(section, "v2ray_dns_mode", v2ray_dns_mode) + end + + break + end + end + end +end + +---- DNS Forward Mode +o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode")) +o.default = "tcp" +o:value("udp", translatef("Requery DNS By %s", "UDP")) +o:value("tcp", translatef("Requery DNS By %s", "TCP")) +if api.is_finded("dns2socks") then + o:value("dns2socks", "dns2socks") +end +if has_singbox then + o:value("sing-box", "Sing-Box") +end +if has_xray then + o:value("xray", "Xray") +end +o:depends({ dns_shunt = "chinadns-ng", _node_sel_other = "1" }) +o:depends({ dns_shunt = "dnsmasq", _node_sel_other = "1" }) +o.write = function(self, section, value) + if value ~= "sing-box" and value ~= "xray" then + m:del(section, "v2ray_dns_mode") + end + return ListValue.write(self, section, value) +end +o.remove = function(self, section) + local f = s.fields["smartdns_dns_mode"] + if f and f:formvalue(section) then + return m:del(section, self.option) + end + dns_mode_save(section) +end + +---- SmartDNS Forward Mode +if api.is_finded("smartdns") then + o = s:taboption("DNS", ListValue, "smartdns_dns_mode", translate("Filter Mode")) + o:value("socks", "Socks") + if has_singbox then + o:value("sing-box", "Sing-Box") + end + if has_xray then + o:value("xray", "Xray") + end + o:depends({ dns_shunt = "smartdns", _node_sel_other = "1" }) + o.write = function(self, section, value) + if value == "socks" then + m:del(section, "v2ray_dns_mode") + end + return ListValue.write(self, section, value) + end + o.remove = function(self, section) + local f = s.fields["dns_mode"] + if f and f:formvalue(section) then + return m:del(section, self.option) + end + dns_mode_save(section) + end + + o = s:taboption("DNS", DynamicList, "smartdns_remote_dns", translate("Remote DNS")) + o:value("tcp://1.1.1.1") + o:value("tcp://8.8.4.4") + o:value("tcp://8.8.8.8") + o:value("tcp://9.9.9.9") + o:value("tcp://208.67.222.222") + o:value("tls://1.1.1.1") + o:value("tls://8.8.4.4") + o:value("tls://8.8.8.8") + o:value("tls://9.9.9.9") + o:value("tls://208.67.222.222") + o:value("https://1.1.1.1/dns-query") + o:value("https://8.8.4.4/dns-query") + o:value("https://8.8.8.8/dns-query") + o:value("https://9.9.9.9/dns-query") + o:value("https://208.67.222.222/dns-query") + o:value("https://dns.adguard.com/dns-query,94.140.14.14") + o:value("https://doh.libredns.gr/dns-query,116.202.176.26") + o:value("https://doh.libredns.gr/ads,116.202.176.26") + o:depends({ dns_shunt = "smartdns", smartdns_dns_mode = "socks" }) + o.cfgvalue = function(self, section) + return m:get(section, self.option) or {"tcp://1.1.1.1"} + end + function o.write(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + return DynamicList.write(self, section, t) + end +end + +o = s:taboption("DNS", ListValue, "xray_dns_mode", translate("Remote DNS") .. " " .. translate("Request protocol")) +o.default = "tcp" +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("doh", "DoH") +o:depends("dns_mode", "xray") +o:depends("smartdns_dns_mode", "xray") +o.cfgvalue = function(self, section) + return m:get(section, "v2ray_dns_mode") +end +o.write = function(self, section, value) + local f = s.fields["smartdns_dns_mode"] + if s.fields["dns_mode"]:formvalue(section) == "xray" or (f and f:formvalue(section) == "xray") then + return m:set(section, "v2ray_dns_mode", value) + end +end + +o = s:taboption("DNS", ListValue, "singbox_dns_mode", translate("Remote DNS") .. " " .. translate("Request protocol")) +o.default = "tcp" +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("doh", "DoH") +o:value("http3", "HTTP3(DoH3)") +o:depends("dns_mode", "sing-box") +o:depends("smartdns_dns_mode", "sing-box") +o.cfgvalue = function(self, section) + return m:get(section, "v2ray_dns_mode") +end +o.write = function(self, section, value) + local f = s.fields["smartdns_dns_mode"] + if s.fields["dns_mode"]:formvalue(section) == "sing-box" or (f and f:formvalue(section) == "sing-box") then + return m:set(section, "v2ray_dns_mode", value) + end +end + +o = s:taboption("DNS", Value, "socks_server", translate("Socks Server"), translate("Make sure socks service is available on this address.")) +for k, v in pairs(socks_table) do o:value(v.id, v.remark) end +o.default = socks_table[1].id +o.validate = function(self, value, t) + if not datatypes.ipaddrport(value) then + return nil, translate("Socks Server") .. " " .. translate("Not valid IP format, please re-enter!") + end + return value +end +o:depends({dns_mode = "dns2socks"}) + +---- DNS Forward +o = s:taboption("DNS", Value, "remote_dns", translate("Remote DNS")) +o.datatype = "or(ipaddr,ipaddrport)" +o.default = "1.1.1.1" +o:value("1.1.1.1", "1.1.1.1 (CloudFlare)") +o:value("1.1.1.2", "1.1.1.2 (CloudFlare-Security)") +o:value("8.8.4.4", "8.8.4.4 (Google)") +o:value("8.8.8.8", "8.8.8.8 (Google)") +o:value("9.9.9.9", "9.9.9.9 (Quad9)") +o:value("149.112.112.112", "149.112.112.112 (Quad9)") +o:value("208.67.220.220", "208.67.220.220 (OpenDNS)") +o:value("208.67.222.222", "208.67.222.222 (OpenDNS)") +o:depends({dns_mode = "dns2socks"}) +o:depends({dns_mode = "tcp"}) +o:depends({dns_mode = "udp"}) +o:depends({xray_dns_mode = "udp"}) +o:depends({xray_dns_mode = "tcp"}) +o:depends({singbox_dns_mode = "udp"}) +o:depends({singbox_dns_mode = "tcp"}) + +---- DoH +o = s:taboption("DNS", Value, "remote_dns_doh", translate("Remote DNS DoH")) +o.description = translate("Format: URL[,IP] (optional IP to map the domain in the URL)") +o.default = o.keylist[1] +o:value("https://1.1.1.1/dns-query", "1.1.1.1 (CloudFlare)") +o:value("https://1.1.1.2/dns-query", "1.1.1.2 (CloudFlare-Security)") +o:value("https://8.8.4.4/dns-query", "8.8.4.4 (Google)") +o:value("https://8.8.8.8/dns-query", "8.8.8.8 (Google)") +o:value("https://9.9.9.9/dns-query", "9.9.9.9 (Quad9)") +o:value("https://149.112.112.112/dns-query", "149.112.112.112 (Quad9)") +o:value("https://208.67.222.222/dns-query", "208.67.222.222 (OpenDNS)") +o:value("https://dns.adguard.com/dns-query,94.140.14.14", "94.140.14.14 (AdGuard)") +o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "116.202.176.26 (LibreDNS)") +o:value("https://doh.libredns.gr/ads,116.202.176.26", "116.202.176.26 (LibreDNS-NoAds)") +o.validate = doh_validate +o:depends({xray_dns_mode = "doh"}) +o:depends({singbox_dns_mode = "doh"}) +o:depends({singbox_dns_mode = "http3"}) + +o = s:taboption("DNS", Value, "remote_dns_client_ip", translate("EDNS Client Subnet")) +o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "
" .. + translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).") +o.datatype = "ipaddr" +o:depends({dns_mode = "sing-box"}) +o:depends({dns_mode = "xray"}) +o:depends("dns_shunt", "smartdns") +o:depends("_node_sel_shunt", "1") + +o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy.")) +o.default = "0" +o:depends({dns_mode = "sing-box", dns_shunt = "dnsmasq"}) +o:depends({dns_mode = "sing-box", dns_shunt = "chinadns-ng"}) +o:depends({smartdns_dns_mode = "sing-box", dns_shunt = "smartdns"}) +o:depends({dns_mode = "xray", dns_shunt = "dnsmasq"}) +o:depends({dns_mode = "xray", dns_shunt = "chinadns-ng"}) +o:depends({smartdns_dns_mode = "xray", dns_shunt = "smartdns"}) +--o:depends("_node_sel_shunt", "1") +o.validate = function(self, value, t) + if value and value == "1" then + local _dns_mode = s.fields["dns_mode"]:formvalue(t) + if not _dns_mode and s.fields["smartdns_dns_mode"] then + _dns_mode = s.fields["smartdns_dns_mode"]:formvalue(t) + end + local _tcp_node = s.fields["tcp_node"]:formvalue(t) + if _dns_mode and _tcp_node then + if (m:get(_tcp_node, "type") or ""):lower() ~= _dns_mode and not _tcp_node:find("Socks_") then + return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode) + end + end + end + return value +end + +o = s:taboption("DNS", ListValue, "chinadns_ng_default_tag", translate("Default DNS")) +o.default = "none" +o:value("gfw", translate("Remote DNS")) +o:value("chn", translate("Direct DNS")) +o:value("none", translate("Smart, Do not accept no-ip reply from Direct DNS")) +o:value("none_noip", translate("Smart, Accept no-ip reply from Direct DNS")) +local desc = "
    " + .. "
  • " .. translate("When not matching any domain name list:") .. "
  • " + .. "
  • " .. translate("Remote DNS: Can avoid more DNS leaks, but some domestic domain names maybe to proxy!") .. "
  • " + .. "
  • " .. translate("Direct DNS: Internet experience may be better, but DNS will be leaked!") .. "
  • " +o.description = desc + .. "
  • " .. translate("Smart: Forward to both direct and remote DNS, if the direct DNS resolution result is a mainland China IP, then use the direct result, otherwise use the remote result.") .. "
  • " + .. "
  • " .. translate("In smart mode, no-ip reply from Direct DNS:") .. "
  • " + .. "
  • " .. translate("Do not accept: Wait and use Remote DNS Reply.") .. "
  • " + .. "
  • " .. translate("Accept: Trust the Reply, using this option can improve DNS resolution speeds for some mainland IPv4-only sites.") .. "
  • " + .. "
" +o:depends({dns_shunt = "chinadns-ng", tcp_proxy_mode = "proxy", chn_list = "direct"}) + +o = s:taboption("DNS", ListValue, "use_default_dns", translate("Default DNS")) +o.default = "direct" +o:value("remote", translate("Remote DNS")) +o:value("direct", translate("Direct DNS")) +o.description = desc .. "" +o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"}) +if api.is_finded("smartdns") then + o:depends({dns_shunt = "smartdns", tcp_proxy_mode = "proxy", chn_list = "direct"}) +end + +o = s:taboption("DNS", Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("Force queries with qtype 65 to respond with an SOA record.")) +o.default = "0" +o:depends({dns_shunt = "chinadns-ng"}) +if api.is_finded("smartdns") then + o:depends({dns_shunt = "smartdns"}) +end + +o = s:taboption("DNS", Flag, "dns_redirect", translate("DNS Redirect"), translate("Force special DNS server to need proxy devices.")) +o.default = "1" +o.rmempty = false + +local prefer_nft = m:get("@global_forwarding[0]", "prefer_nft") == "1" +local set_title = api.i18n.translate(prefer_nft and "Clear NFTSET on Reboot" or "Clear IPSET on Reboot") +o = s:taboption("DNS", Flag, "flush_set_on_reboot", set_title, translate("Clear IPSET/NFTSET on service reboot. This may increase reboot time.")) +o.default = "0" + +set_title = api.i18n.translate(prefer_nft and "Clear NFTSET" or "Clear IPSET") +o = s:taboption("DNS", DummyValue, "clear_ipset", set_title, translate("Try this feature if the rule modification does not take effect.")) +o.rawhtml = true +function o.cfgvalue(self, section) + return string.format( + [[]], + api.url("flush_set") .. "?redirect=1&reload=1", set_title) +end + +s:tab("Proxy", translate("Mode")) + +o = s:taboption("Proxy", Flag, "use_direct_list", translatef("Use %s", translate("Direct List"))) +o.default = "1" + +o = s:taboption("Proxy", Flag, "use_proxy_list", translatef("Use %s", translate("Proxy List"))) +o.default = "1" + +o = s:taboption("Proxy", Flag, "use_block_list", translatef("Use %s", translate("Block List"))) +o.default = "1" + +if has_gfwlist then + o = s:taboption("Proxy", Flag, "use_gfw_list", translatef("Use %s", translate("GFW List"))) + o.default = "1" +end + +if has_chnlist or has_chnroute then + o = s:taboption("Proxy", ListValue, "chn_list", translate("China List")) + o:value("0", translate("Close(Not use)")) + o:value("direct", translate("Direct Connection")) + o:value("proxy", translate("Proxy")) + o.default = "direct" +end + +---- TCP Default Proxy Mode +o = s:taboption("Proxy", ListValue, "tcp_proxy_mode", "TCP " .. translate("Default Proxy Mode")) +o:value("disable", translate("No Proxy")) +o:value("proxy", translate("Proxy")) +o.default = "proxy" + +---- UDP Default Proxy Mode +o = s:taboption("Proxy", ListValue, "udp_proxy_mode", "UDP " .. translate("Default Proxy Mode")) +o:value("disable", translate("No Proxy")) +o:value("proxy", translate("Proxy")) +o.default = "proxy" + +o = s:taboption("Proxy", DummyValue, "switch_mode", " ") +o.template = appname .. "/global/proxy" + +---- Check the transparent proxy component +local handle = io.popen("lsmod") +local mods = "" +if handle then + mods = handle:read("*a") or "" + handle:close() +end + +if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then + o = s:taboption("Proxy", Flag, "localhost_proxy", translate("Localhost Proxy"), translate("When selected, localhost can transparent proxy.")) + o.default = "1" + o.rmempty = false + + o = s:taboption("Proxy", Flag, "client_proxy", translate("Client Proxy"), translate("When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy.")) + o.default = "1" + o.rmempty = false +else + local html = string.format([[
%s
]], translate("Missing components, transparent proxy is unavailable.")) + o = s:taboption("Proxy", DummyValue, "localhost_proxy", translate("Localhost Proxy")) + o.rawhtml = true + function o.cfgvalue(self, section) + return html + end + + o = s:taboption("Proxy", DummyValue, "client_proxy", translate("Client Proxy")) + o.rawhtml = true + function o.cfgvalue(self, section) + return html + end +end + +o = s:taboption("Proxy", DummyValue, "_proxy_tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', api.url("acl"), translate("Want different devices to use different proxy modes/ports/nodes? Please use access control.")) +end + +s:tab("log", translate("Log")) +o = s:taboption("log", Flag, "log_tcp", translate("Enable") .. " " .. translatef("%s Node Log", "TCP")) +o.default = "0" +o.rmempty = false + +o = s:taboption("log", Flag, "log_udp", translate("Enable") .. " " .. translatef("%s Node Log", "UDP")) +o.default = "0" +o.rmempty = false + +o = s:taboption("log", ListValue, "loglevel", "Sing-Box/Xray " .. translate("Log Level")) +o.default = "warning" +o:value("debug") +o:value("info") +o:value("warning") +o:value("error") + +o = s:taboption("log", Flag, "advanced_log_feature", translate("Advanced log feature"), translate("For professionals only.")) +o.default = "0" +o = s:taboption("log", Flag, "sys_log", translate("Logging to system log"), translate("Logging to the system log for more advanced functions. For example, send logs to a dedicated log server.")) +o:depends("advanced_log_feature", "1") +o.default = "0" +o = s:taboption("log", Value, "persist_log_path", translate("Persist log file directory"), translate("The path to the directory used to store persist log files, the \"/\" at the end can be omitted. Leave it blank to disable this feature.")) +o:depends({ ["advanced_log_feature"] = 1, ["sys_log"] = 0 }) +o = s:taboption("log", Value, "log_event_filter", translate("Log Event Filter"), translate("Support regular expression.")) +o:depends("advanced_log_feature", "1") +o = s:taboption("log", Value, "log_event_cmd", translate("Shell Command"), translate("Shell command to execute, replace log content with %s.")) +o:depends("advanced_log_feature", "1") + +o = s:taboption("log", Flag, "log_chinadns_ng", translate("Enable") .. " ChinaDNS-NG " .. translate("Log")) +o.default = "0" +o.rmempty = false + +o = s:taboption("log", DummyValue, "_log_tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', translate("It is recommended to disable logging during regular use to reduce system overhead.")) +end + +s:tab("faq", "FAQ") +o = s:taboption("faq", DummyValue, "") +o.template = appname .. "/global/faq" + +s:tab("maintain", translate("Maintain")) +o = s:taboption("maintain", DummyValue, "") +o.template = appname .. "/global/backup" + +-- [[ Socks Server ]]-- +o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switch")) +o.rmempty = false + +s2 = m:section(TypedSection, "socks", translate("Socks Config")) +s2.template = "cbi/tblsection" +s2.anonymous = true +s2.addremove = true +s2.extedit = api.url("socks_config", "%s") +function s2.create(e, t) + local uuid = api.gen_short_uuid() + t = uuid + TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end +function s2.remove(e, t) + local socks = "Socks_" .. t + local new_node = "" + local node0 = m:get("@nodes[0]") or nil + if node0 then + new_node = node0[".name"] + end + if (m:get("@global[0]", "tcp_node") or "") == socks then + m:set('@global[0]', "tcp_node", new_node) + end + if (m:get("@global[0]", "udp_node") or "") == socks then + m:set('@global[0]', "udp_node", new_node) + end + m.uci:foreach(appname, "acl_rule", function(s) + if s["tcp_node"] and s["tcp_node"] == socks then + m:set(s[".name"], "tcp_node", "default") + end + if s["udp_node"] and s["udp_node"] == socks then + m:set(s[".name"], "udp_node", "default") + end + end) + m.uci:foreach(appname, "nodes", function(s) + local list_name = s["urltest_node"] and "urltest_node" or (s["balancing_node"] and "balancing_node") + if list_name then + local nodes = m.uci:get_list(appname, s[".name"], list_name) + if nodes then + local changed = false + local new_nodes = {} + for _, node in ipairs(nodes) do + if node ~= socks then + table.insert(new_nodes, node) + else + changed = true + end + end + if changed then + m.uci:set_list(appname, s[".name"], list_name, new_nodes) + end + end + end + if s["fallback_node"] == socks then + m:del(s[".name"], "fallback_node") + end + end) + TypedSection.remove(e, t) +end + +o = s2:option(DummyValue, "status", translate("Status")) +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('
', n) +end + +---- Enable +o = s2:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +o = s2:option(ListValue, "node", translate("Socks Node")) +o.template = appname .. "/cbi/nodes_listvalue" +o.group = {} + +o = s2:option(DummyValue, "now_node", translate("Current Node")) +o.rawhtml = true +o.cfgvalue = function(_, n) + local current_node = api.get_cache_var("socks_" .. n) + if current_node then + local node = m:get(current_node) + if node then + return (api.get_node_remarks(node) or ""):gsub("(:)%[", "%1
[") + end + end +end + +local n = 1 +m.uci:foreach(appname, "socks", function(s) + if s[".name"] == section then + return false + end + n = n + 1 +end) + +o = s2:option(Value, "port", "Socks " .. translate("Listen Port")) +o.default = n + 1080 +o.datatype = "port" +o.rmempty = false + +if has_singbox or has_xray then + o = s2:option(Value, "http_port", "HTTP " .. translate("Listen Port")) + o.default = 0 + o.datatype = "port" +end + +local tcp = s.fields["tcp_node"] +local udp = s.fields["udp_node"] +local socks = s2.fields["node"] +for k, v in pairs(socks_list) do + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +for k, v in pairs(nodes_table) do + if #normal_list == 0 and #iface_list == 0 then + break + end + if v.protocol == "_shunt" then + if has_singbox or has_xray then + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + + s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id }) + if m:get(v.id, "type") == "Xray" then + s.fields["xray_dns_mode"]:depends({ tcp_node = v.id }) + else + s.fields["singbox_dns_mode"]:depends({ tcp_node = v.id }) + end + end + else + tcp:value(v.id, v["remark"]) + tcp.group[#tcp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + udp:value(v.id, v["remark"]) + udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + if v.type == "Socks" then + if has_singbox or has_xray then + socks:value(v.id, v["remark"]) + socks.group[#socks.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + else + socks:value(v.id, v["remark"]) + socks.group[#socks.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end +end + +local footer = Template(appname .. "/global/footer") +footer.api = api +footer.global_cfgid = global_cfgid +footer.shunt_list = api.jsonc.stringify(shunt_list) +m:append(footer) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua new file mode 100644 index 00000000..397944eb --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua @@ -0,0 +1,181 @@ +local api = require "luci.passwall.api" +local appname = api.appname +local datatypes = api.datatypes +local net = require "luci.model.network".init() + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + obj = e, + remarks = e["remark"], + group = e["group"] + } + end +end + +m = Map(appname, "HAPROXY " .. translate("Load Balancing")) +api.set_apply_on_parse(m) + +m:append(Template(appname .. "/cbi/nodes_value_com")) + +-- [[ Haproxy Settings ]]-- +s = m:section(TypedSection, "global_haproxy", translate("Basic Settings")) +s.anonymous = true + +s:append(Template(appname .. "/haproxy/status")) + +---- Balancing Enable +o = s:option(Flag, "balancing_enable", translate("Enable Load Balancing")) +o.rmempty = false +o.default = false + +---- Console Login Auth +o = s:option(Flag, "console_auth", translate("Console Login Auth")) +o.default = false +o:depends("balancing_enable", true) + +---- Console Username +o = s:option(Value, "console_user", translate("Console Username")) +o.default = "" +o:depends("console_auth", true) + +---- Console Password +o = s:option(Value, "console_password", translate("Console Password")) +o.password = true +o.default = "" +o:depends("console_auth", true) + +---- Console Port +o = s:option(Value, "console_port", translate("Console Port"), translate("In the browser input routing IP plus port access, such as:192.168.1.1:1188")) +o.datatype = "port" +o.default = 1188 +o:depends("balancing_enable", true) + +o = s:option(Flag, "bind_local", translate("Haproxy Port") .. " " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" +o:depends("balancing_enable", true) + +o = s:option(ListValue, "balancingStrategy", translate("Balancing Strategy")) +o:value("roundrobin", "roundRobin") +o:value("random", "random") +o:value("leastconn", "leastConn") +o:value("source", "source") +o.default = "roundrobin" +o:depends("balancing_enable", true) + +---- Health Check Type +o = s:option(ListValue, "health_check_type", translate("Health Check Type")) +o.default = "passwall_logic" +o:value("tcp", "TCP") +o:value("passwall_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement"))) +o:depends("balancing_enable", true) + +---- Passwall Inner implement Probe URL +o = s:option(Value, "health_probe_url", translate("Probe URL")) +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.default = o.keylist[3] +o.description = translate("The URL used to detect the connection status.") +o:depends("health_check_type", "passwall_logic") + +---- Health Check Inter +o = s:option(Value, "health_check_inter", translate("Health Check Inter")) +o.datatype = "min(20)" +o.default = 60 +o:depends("balancing_enable", true) +o.description = translate("Units:seconds") .. " ( ≥ 20s )
" .. + translate("Note: Frequent health checks increase CPU usage; an interval ≥ 60 seconds is recommended.") + +o = s:option(DummyValue, "health_check_tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', translate("When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid.")) +end +o:depends("health_check_type", "passwall_logic") + +-- [[ Balancing Settings ]]-- +s = m:section(TypedSection, "haproxy_config", translate("Node List")) +s.description = "" .. + translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "
" .. + translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. "
" +s.template = "cbi/tblsection" +s.sortable = true +s.anonymous = true +s.addremove = true + +s.create = function(e, t) + TypedSection.create(e, api.gen_short_uuid()) +end + +s.remove = function(self, section) + for k, v in pairs(self.children) do + v.rmempty = true + v.validate = nil + end + TypedSection.remove(self, section) +end + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +---- Node Address +o = s:option(Value, "lbss", translate("Node Address")) +o.template = appname .. "/cbi/nodes_value" +o.group = {} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +o.rmempty = false +o.validate = function(self, value) + if not value then return nil, translate("Node address cannot be empty.") end + local t = m:get(value) or nil + if t and t[".type"] == "nodes" then + return value + end + if datatypes.hostport(value) or datatypes.ip4addrport(value) then + return value + end + if api.is_ipv6addrport(value) then + return value + end + return nil, translate("Not valid IP format, please re-enter!") .. " (IP:Port)" +end + +---- Haproxy Port +o = s:option(Value, "haproxy_port", translate("Haproxy Port")) +o.datatype = "port" +o.default = 1181 +o.rmempty = false + +---- Node Weight +o = s:option(Value, "lbweight", translate("Node Weight")) +o.datatype = "min(1)" +o.default = 5 +o.rmempty = false + +---- Export +o = s:option(ListValue, "export", translate("Export Of Multi WAN")) +o:value(0, translate("Auto")) +local wa = require "luci.tools.webadmin" +wa.cbi_add_networks(o) +o.default = 0 +o.rmempty = false + +---- Mode +o = s:option(ListValue, "backup", translate("Mode")) +o:value(0, translate("Primary")) +o:value(1, translate("Standby")) +o.rmempty = false + +m:append(Template(appname .. "/haproxy/js")) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua new file mode 100644 index 00000000..7711808d --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/include/shunt_options.lua @@ -0,0 +1,190 @@ +local m, s, data = ... + +if not data.node_id or not data.node then + return +end + +local current_node_id = data.node_id +local node_list = data.node_list or api.get_node_list() + +local function get_cfgvalue() + return function(self, section) + return m:get(current_node_id, self.option) + end +end +local function get_write() + return function(self, section, value) + if data.verify_option then + if data.verify_option:formvalue(section) == current_node_id then + m:set(current_node_id, self.option, value) + end + else + m:set(current_node_id, self.option, value) + end + end +end +local function get_remove() + return function(self, section) + if data.verify_option then + if data.verify_option:formvalue(section) == current_node_id then + m:del(current_node_id, self.option) + end + else + m:del(current_node_id, self.option) + end + end +end + +if data.tab then + s:tab(data.tab, data.tab_desc) +end + +local function add_option(class, option_name, option_title, option_desc) + local a + if data.tab then + a = s:taboption(data.tab, class, option_name, option_title) + else + a = s:option(class, option_name, option_title) + end + if a then + if option_desc then + a.description = option_desc + end + a.cfgvalue = get_cfgvalue() + a.write = get_write() + a.remove = get_remove() + end + if data.verify_option then + a:depends(data.verify_option.option, current_node_id) + end + return a +end + +local function add_depends(o, deps) + if #o.deps > 0 then + for index, value in ipairs(o.deps) do + for k, v in pairs(deps) do + o.deps[index][k] = v + end + end + else + o:depends(deps) + end +end + +if data.node.type == "Xray" then + o = add_option(ListValue, "domainStrategy", translate("Domain Strategy")) + o:value("AsIs") + o:value("IPIfNonMatch") + o:value("IPOnDemand") + o.default = "IPOnDemand" + o.description = "
  • " .. translate("'AsIs': Only use domain for routing. Default value.") + .. "
  • " .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.") + .. "
  • " .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.") + .. "
" + + o = add_option(ListValue, "domainMatcher", translate("Domain matcher")) + o:value("hybrid") + o:value("linear") +end + +o = add_option(Flag, "fakedns", 'FakeDNS' .. " " .. translate("Main switch"), translate("Use FakeDNS work in the domain that proxy.") .. "
" .. + translate("Suitable scenarios for let the node servers get the target domain names.") .. "
" .. + translate("Such as: DNS unlocking of streaming media, reducing DNS query latency, etc.")) + +local shunt_rules = {} +m.uci:foreach(appname, "shunt_rules", function(e) + e.id = e[".name"] + e.remarks = e.remarks or e[".name"] + e["_node_option"] = e[".name"] + e["_node_default"] = "" + e["_fakedns_option"] = e[".name"] .. "_fakedns" + e["_proxy_tag_option"] = e[".name"] .. "_proxy_tag" + table.insert(shunt_rules, e) +end) +table.insert(shunt_rules, { + id = ".default", + remarks = translate("Default"), + _node_option = "default_node", + _node_default = "_direct", + _fakedns_option = "default_fakedns", + _proxy_tag_option = "default_proxy_tag", +}) + +s2 = m:section(Table, shunt_rules, " ") +s2.config = appname +s2.sectiontype = "shunt_option_list" + +o = s2:option(DummyValue, "remarks", translate("Rule")) +o.rawhtml = true +o.cfgvalue = function(self, section) + if shunt_rules[section].id == ".default" then + return string.format('%s', shunt_rules[section].remarks) + else + return string.format('%s', api.url("shunt_rules", shunt_rules[section].id), shunt_rules[section].remarks) + end +end + +_node = s2:option(Value, "_node", translate("Node")) +_node.template = appname .. "/cbi/nodes_listvalue" +_node.group = {"","","",""} +_node:value("", translate("Close (Not use)")) +_node:value("_default", translate("Use default node")) +_node:value("_direct", translate("Direct Connection")) +_node:value("_blackhole", translate("Blackhole (Block)")) +_node.cfgvalue = function(self, section) + return m:get(current_node_id, shunt_rules[section]["_node_option"]) or shunt_rules[section]["_node_default"] +end +_node.write = function(self, section, value) + return m:set(current_node_id, shunt_rules[section]["_node_option"], value) +end +_node.remove = function(self, section) + return m:del(current_node_id, shunt_rules[section]["_node_option"]) +end + +o = s2:option(Flag, "_fakedns", string.format('FakeDNS', translate("Use FakeDNS work in the domain that proxy.") .. "\n" .. + translate("Suitable scenarios for let the node servers get the target domain names.") .. "\n" .. + translate("Such as: DNS unlocking of streaming media, reducing DNS query latency, etc."))) +o.cfgvalue = function(self, section) + return m:get(current_node_id, shunt_rules[section]["_fakedns_option"]) +end +o.write = function(self, section, value) + return m:set(current_node_id, shunt_rules[section]["_fakedns_option"], value) +end +o.remove = function(self, section) + return m:del(current_node_id, shunt_rules[section]["_fakedns_option"]) +end + +proxy_tag_node = s2:option(ListValue, "_proxy_tag", string.format('%s', + translate("Set the node to be used as a pre-proxy.") .. "\n" .. translate("Each rule has a separate switch that controls whether this rule uses the pre-proxy or not."), + translate("Preproxy"))) +proxy_tag_node.template = appname .. "/cbi/nodes_listvalue" +proxy_tag_node.group = {""} +proxy_tag_node:value("", translate("Close (Not use)")) +proxy_tag_node.cfgvalue = function(self, section) + return m:get(current_node_id, shunt_rules[section]["_proxy_tag_option"]) +end +proxy_tag_node.write = function(self, section, value) + return m:set(current_node_id, shunt_rules[section]["_proxy_tag_option"], value) +end +proxy_tag_node.remove = function(self, section) + return m:del(current_node_id, shunt_rules[section]["_proxy_tag_option"]) +end + +for k1, v1 in pairs(node_list) do + if k1 ~= "shunt_list" then + for i, v in ipairs(v1) do + _node:value(v.id, v.remark) + _node.group[#_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + + proxy_tag_node:value(v.id, v.remark) + proxy_tag_node.group[#proxy_tag_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end +end + +local footer = Template(appname .. "/include/shunt_options") +footer.api = api +footer.id = current_node_id +footer.normal_list = api.jsonc.stringify(node_list.normal_list) +m:append(footer) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/log.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/log.lua new file mode 100644 index 00000000..ef8c9be0 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/log.lua @@ -0,0 +1,8 @@ +local api = require "luci.passwall.api" +local appname = "passwall" + +f = SimpleForm(appname) +f.reset = false +f.submit = false +f:append(Template(appname .. "/log/log")) +return f diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua new file mode 100644 index 00000000..9cbb3a9e --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -0,0 +1,126 @@ +api = require "luci.passwall.api" +appname = "passwall" + +m = Map(appname, translate("Node Config")) +m.redirect = api.url("node_list") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +fs = require "nixio.fs" +formvalue_key = "cbid." .. appname .. "." .. arg[1] .. "." + +local header = Template(appname .. "/node_config/header") +header.api = api +header.config = m.config +header.section = arg[1] +m:append(header) + +m:append(Template(appname .. "/cbi/nodes_multivalue_com")) +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +groups = {} +m.uci:foreach(appname, "nodes", function(s) + if s[".name"] ~= arg[1] then + if s.group and s.group ~= "" then + groups[s.group] = true + end + end +end) + +s = m:section(NamedSection, arg[1], "nodes", "") +s.addremove = false +s.dynamic = false + +o = s:option(DummyValue, "passwall", " ") +o.rawhtml = true +o.template = "passwall/node_config/link_share_man" +o.value = arg[1] + +o = s:option(Value, "remarks", translate("Node Remarks")) +o.default = translate("Remarks") +o.rmempty = false + +o = s:option(Value, "group", translate("Group Name")) +o.default = "" +o:value("", translate("default")) +for k, v in pairs(groups) do + o:value(k) +end +o.write = function(self, section, value) + value = api.trim(value) + local lower = value:lower() + + if lower == "" or lower == "default" then + return m:del(section, self.option) + end + + for _, v in ipairs(self.keylist or {}) do + if v:lower() == lower then + return m:set(section, self.option, v) + end + end + m:set(section, self.option, value) +end + +local types_dir = "/usr/lib/lua/luci/model/cbi/passwall/client/type/" +s.val = {} +s.val["type"] = m.uci:get(appname, arg[1], "type") +s.val["protocol"] = m.uci:get(appname, arg[1], "protocol") + +if luci.http.formvalue("cbi.submit") == "1" then + local formvalue_type = luci.http.formvalue(formvalue_key .. "type") + if formvalue_type then + s.val["type"] = formvalue_type + end +end + +o = s:option(ListValue, "type", translate("Type")) + +if api.is_finded("ipt2socks") then + s.fields["type"]:value("Socks", translate("Socks")) + + if s.val["type"] == "Socks" then + local function _n(name) + return "socks_" .. name + end + o = s:option(ListValue, _n("del_protocol"), " ") --始终éšè—,用于删除 protocol + o:depends({ [_n("__hide")] = "1" }) + o.rewrite_option = "protocol" + + o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + + o = s:option(Value, _n("port"), translate("Port")) + o.datatype = "port" + + o = s:option(Value, _n("username"), translate("Username")) + + o = s:option(Value, _n("password"), translate("Password")) + o.password = true + + api.luci_types(arg[1], m, s, "Socks", "socks_") + end + +end + +local type_table = {} +for filename in fs.dir(types_dir) do + table.insert(type_table, filename) +end +table.sort(type_table) + +for index, value in ipairs(type_table) do + local p_func = loadfile(types_dir .. value) + setfenv(p_func, getfenv(1))(m, s) +end + +local footer = Template(appname .. "/node_config/footer") +footer.api = api +footer.config = m.config +footer.section = arg[1] + +m:append(footer) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua new file mode 100644 index 00000000..0465b87a --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -0,0 +1,35 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local sys = api.sys +local datatypes = api.datatypes + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ Other Settings ]]-- +s = m:section(TypedSection, "global_other") +s.anonymous = true + +o = s:option(ListValue, "auto_detection_time", translate("Automatic detection delay")) +o:value("0", translate("Close")) +o:value("icmp", "Ping") +o:value("tcping", "TCP Ping") + +o = s:option(Flag, "show_node_info", translate("Show server address and port")) +o.default = "0" + +o = s:option(Value, "url_test_url", translate("URL Test Address")) +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.default = o.keylist[3] + +-- [[ Add the node via the link ]]-- +s:append(Template(appname .. "/node_list/link_add_node")) + +m:append(Template(appname .. "/node_list/node_list")) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua new file mode 100644 index 00000000..481477aa --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -0,0 +1,228 @@ +local api = require "luci.passwall.api" +local uci = api.uci +local appname = "passwall" +local has_ss_rust = api.is_finded("sslocal") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") +local ss_type = {} +local trojan_type = {} +local vmess_type = {} +local vless_type = {} +local hysteria2_type = {} +local xray_version = api.get_app_version("xray") +if has_ss_rust then + local s = "shadowsocks-rust" + table.insert(ss_type, s) +end +if has_singbox then + local s = "sing-box" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + table.insert(hysteria2_type, s) +end +if has_xray then + local s = "xray" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + if api.compare_versions(xray_version, ">=", "26.1.13") then + table.insert(hysteria2_type, s) + end +end +if has_hysteria2 then + local s = "hysteria2" + table.insert(hysteria2_type, s) +end + +m = Map(appname) +api.set_apply_on_parse(m) + +function m.on_before_save(self) + if self.no_commit then + return + end + self.uci:foreach(appname, "subscribe_list", function(e) + self:del(e[".name"], "md5") + end) +end + +-- [[ Subscribe Settings ]]-- +s = m:section(TypedSection, "global_subscribe", "") +s.anonymous = true + +o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode")) +o:value("0", translate("Close")) +o:value("1", translate("Discard List")) +o:value("2", translate("Keep List")) +o:value("3", translate("Discard List,But Keep List First")) +o:value("4", translate("Keep List,But Discard List First")) + +o = s:option(DynamicList, "filter_discard_list", translate("Discard List")) + +o = s:option(DynamicList, "filter_keep_list", translate("Keep List")) + +if #ss_type > 0 then + o = s:option(ListValue, "ss_type", translatef("%s Node Use Type", "Shadowsocks")) + o:value("", translate("Auto")) + for key, value in pairs(ss_type) do + o:value(value) + end +end + +if #trojan_type > 0 then + o = s:option(ListValue, "trojan_type", translatef("%s Node Use Type", "Trojan")) + o:value("", translate("Auto")) + for key, value in pairs(trojan_type) do + o:value(value) + end +end + +if #vmess_type > 0 then + o = s:option(ListValue, "vmess_type", translatef("%s Node Use Type", "VMess")) + o:value("", translate("Auto")) + for key, value in pairs(vmess_type) do + o:value(value) + end +end + +if #vless_type > 0 then + o = s:option(ListValue, "vless_type", translatef("%s Node Use Type", "VLESS")) + o:value("", translate("Auto")) + for key, value in pairs(vless_type) do + o:value(value) + end +end + +if #hysteria2_type > 0 then + o = s:option(ListValue, "hysteria2_type", translatef("%s Node Use Type", "Hysteria2")) + o:value("", translate("Auto")) + for key, value in pairs(hysteria2_type) do + o:value(value) + end +end + +if #ss_type > 0 or #trojan_type > 0 or #vmess_type > 0 or #vless_type > 0 or #hysteria2_type > 0 then + o.description = string.format("%s", + translate("The configured type also applies to the core specified when manually importing nodes.")) +end + +---- Subscribe Delete All +o = s:option(DummyValue, "_stop", translate("Delete All Subscribe Node")) +o.rawhtml = true +function o.cfgvalue(self, section) + return string.format( + [[]], + translate("Delete All Subscribe Node")) +end + +o = s:option(DummyValue, "_update", translate("Manual subscription All")) +o.rawhtml = true +o.cfgvalue = function(self, section) + return string.format([[ + ]], + translate("Manual subscription All")) +end + +s = m:section(TypedSection, "subscribe_list", "", "" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "") +s.addremove = true +s.anonymous = true +s.sortable = true +s.template = "cbi/tblsection" +s.extedit = api.url("node_subscribe_config", "%s") +function s.create(e, t) + m.no_commit = true + local id = TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(id)) +end + +o = s:option(Value, "remark", translate("Remarks")) +o.width = "auto" +o.rmempty = false +o.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translate("Remark cannot be empty.") + end + local duplicate = false + m.uci:foreach(appname, "subscribe_list", function(e) + if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then + duplicate = true + return false + end + end) + if duplicate or value:lower() == "default" then + return nil, translate("This remark already exists, please change a new remark.") + end + return value +end +o.write = function(self, section, value) + local old = m:get(section, self.option) or "" + if old ~= value then + m.uci:foreach(appname, "nodes", function(e) + if e["group"] and e["group"]:lower() == old:lower() then + m.uci:set(appname, e[".name"], "group", value) + end + if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then + local gs = "" + for g in e["node_group"]:gmatch("%S+") do + if api.UrlEncode(old) == g then + gs = gs .. " " .. api.UrlEncode(value) + else + gs = gs .. " " .. g + end + end + gs = api.trim(gs) + m.uci:set(appname, e[".name"], "node_group", gs) + end + end) + end + return Value.write(self, section, value) +end + +o = s:option(DummyValue, "_node_count", translate("Subscribe Info")) +o.rawhtml = true +o.cfgvalue = function(t, n) + local remark = m:get(n, "remark") or "" + local str = m:get(n, "rem_traffic") or "" + local expired_date = m:get(n, "expired_date") or "" + if expired_date ~= "" then + str = str .. (str ~= "" and "/" or "") .. expired_date + end + str = str ~= "" and "
" .. str or "" + local num = 0 + m.uci:foreach(appname, "nodes", function(s) + if s["group"] and s["group"]:lower() == remark:lower() then + num = num + 1 + end + end) + return string.format("%s%s", translate("Node num") .. ": " .. num, str) +end + +o = s:option(Value, "url", translate("Subscribe URL")) +o.width = "auto" +o.rmempty = false + +o = s:option(DummyValue, "_remove", translate("Delete the subscribed node")) +o.rawhtml = true +function o.cfgvalue(self, section) + local remark = m:get(section, "remark") or "" + return string.format( + [[]], + remark, translate("Delete the subscribed node")) +end + +o = s:option(DummyValue, "_update", translate("Manual subscription")) +o.rawhtml = true +o.cfgvalue = function(self, section) + return string.format([[ + ]], + section, translate("Manual subscription")) +end + +m:append(Template(appname .. "/node_subscribe/js")) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua new file mode 100644 index 00000000..55a94368 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua @@ -0,0 +1,334 @@ +local api = require "luci.passwall.api" +local uci = api.uci +local appname = "passwall" + +m = Map(appname) +m.redirect = api.url("node_subscribe") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +function m.on_before_save(self) + self:del(arg[1], "md5") +end + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local has_ss_rust = api.is_finded("sslocal") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") +local ss_type = {} +local trojan_type = {} +local vmess_type = {} +local vless_type = {} +local hysteria2_type = {} +local xray_version = api.get_app_version("xray") +if has_ss_rust then + local s = "shadowsocks-rust" + table.insert(ss_type, s) +end +if has_singbox then + local s = "sing-box" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + table.insert(hysteria2_type, s) +end +if has_xray then + local s = "xray" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + if api.compare_versions(xray_version, ">=", "26.1.13") then + table.insert(hysteria2_type, s) + end +end +if has_hysteria2 then + local s = "hysteria2" + table.insert(hysteria2_type, s) +end +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + remark = e["remark"], + type = e["type"], + add_mode = e["add_mode"], + chain_proxy = e["chain_proxy"], + group = e["group"] + } + end +end + +s = m:section(NamedSection, arg[1]) +s.addremove = false +s.dynamic = false + +o = s:option(Value, "remark", translate("Subscribe Remark")) +o.rmempty = false +o.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translate("Remark cannot be empty.") + end + local duplicate = false + m.uci:foreach(appname, "subscribe_list", function(e) + if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then + duplicate = true + return false + end + end) + if duplicate or value:lower() == "default" then + return nil, translate("This remark already exists, please change a new remark.") + end + return value +end +o.write = function(self, section, value) + local old = m:get(section, self.option) or "" + if old ~= value then + m.uci:foreach(appname, "nodes", function(e) + if e["group"] and e["group"]:lower() == old:lower() then + m.uci:set(appname, e[".name"], "group", value) + end + if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then + local gs = "" + for g in e["node_group"]:gmatch("%S+") do + if api.UrlEncode(old) == g then + gs = gs .. " " .. api.UrlEncode(value) + else + gs = gs .. " " .. g + end + end + gs = api.trim(gs) + m.uci:set(appname, e[".name"], "node_group", gs) + end + end) + end + return Value.write(self, section, value) +end + +o = s:option(TextValue, "url", translate("Subscribe URL")) +o.rows = 5 +o.rmempty = false +o.validate = function(self, value) + if not value or value == "" then + return nil, translate("URL cannot be empty.") + end + return value:gsub("%s+", ""):gsub("%z", "") +end + +o = s:option(ListValue, "domain_resolver", translate("Domain DNS Resolve")) +o.description = translate("If the node address is a domain name, this DNS will be used for resolution.") .. "
" .. + translate("Supports only Xray or Sing-box node types.") .. "
" .. string.format('%s', + translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) +o:value("", translate("Auto")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("https", "DoH") + +o = s:option(Value, "domain_resolver_dns", "DNS") +o.datatype = "or(ipaddr,ipaddrport)" +o:value("114.114.114.114") +o:value("223.5.5.5:53") +o.default = o.keylist[1] +o:depends({ domain_resolver = "tcp" }) +o:depends({ domain_resolver = "udp" }) + +o = s:option(Value, "domain_resolver_dns_https", "DNS") +o:value("https://120.53.53.53/dns-query", "DNSPod") +o:value("https://223.5.5.5/dns-query", "AliDNS") +o.default = o.keylist[1] +o:depends({ domain_resolver = "https" }) + +o = s:option(ListValue, "domain_strategy", translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) +o.default = "" +o:value("", translate("Auto")) +o:value("UseIPv4v6", translate("Prefer IPv4")) +o:value("UseIPv6v4", translate("Prefer IPv6")) +o:value("UseIPv4", translate("IPv4 Only")) +o:value("UseIPv6", translate("IPv6 Only")) + +o = s:option(Flag, "allowInsecure", translate("allowInsecure")) +o.default = "0" +o.rmempty = false +o.description = translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.") .. "
" .. + translate("Used when the node link does not include this parameter.") + +o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode")) +o.default = "5" +o:value("0", translate("Close")) +o:value("1", translate("Discard List")) +o:value("2", translate("Keep List")) +o:value("3", translate("Discard List,But Keep List First")) +o:value("4", translate("Keep List,But Discard List First")) +o:value("5", translate("Use global config")) + +o = s:option(DynamicList, "filter_discard_list", translate("Discard List")) +o:depends("filter_keyword_mode", "1") +o:depends("filter_keyword_mode", "3") +o:depends("filter_keyword_mode", "4") + +o = s:option(DynamicList, "filter_keep_list", translate("Keep List")) +o:depends("filter_keyword_mode", "2") +o:depends("filter_keyword_mode", "3") +o:depends("filter_keyword_mode", "4") + +if #ss_type > 0 then + o = s:option(ListValue, "ss_type", translatef("%s Node Use Type", "Shadowsocks")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(ss_type) do + o:value(value) + end +end + +if #trojan_type > 0 then + o = s:option(ListValue, "trojan_type", translatef("%s Node Use Type", "Trojan")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(trojan_type) do + o:value(value) + end +end + +if #vmess_type > 0 then + o = s:option(ListValue, "vmess_type", translatef("%s Node Use Type", "VMess")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(vmess_type) do + o:value(value) + end +end + +if #vless_type > 0 then + o = s:option(ListValue, "vless_type", translatef("%s Node Use Type", "VLESS")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(vless_type) do + o:value(value) + end +end + +if #hysteria2_type > 0 then + o = s:option(ListValue, "hysteria2_type", translatef("%s Node Use Type", "Hysteria2")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(hysteria2_type) do + o:value(value) + end + + o = s:option(Value, "hysteria_up_mbps", "Hy/Hy2 " .. translate("Max upload Mbps")) + o.datatype = "uinteger" + o.default = "100" + + o = s:option(Value, "hysteria_down_mbps", "Hy/Hy2 " .. translate("Max download Mbps")) + o.datatype = "uinteger" + o.default = "100" +end + +o = s:option(Flag, "boot_update", translate("Update Once on Boot"), translate("Updates the subscription the first time PassWall runs automatically after each system boot.")) +o.default = 0 + +---- Enable auto update subscribe +o = s:option(Flag, "auto_update", translate("Enable auto update subscribe")) +o.default = 0 +o.rmempty = false + +---- Week Update +o = s:option(ListValue, "week_update", translate("Update Mode")) +o:value(8, translate("Loop Mode")) +o:value(7, translate("Every day")) +o:value(1, translate("Every Monday")) +o:value(2, translate("Every Tuesday")) +o:value(3, translate("Every Wednesday")) +o:value(4, translate("Every Thursday")) +o:value(5, translate("Every Friday")) +o:value(6, translate("Every Saturday")) +o:value(0, translate("Every Sunday")) +o.default = 7 +o:depends("auto_update", true) +o.rmempty = true + +---- Time Update +o = s:option(ListValue, "time_update", translate("Update Time(every day)")) +for t = 0, 23 do o:value(t, t .. ":00") end +o.default = 0 +o:depends("week_update", "0") +o:depends("week_update", "1") +o:depends("week_update", "2") +o:depends("week_update", "3") +o:depends("week_update", "4") +o:depends("week_update", "5") +o:depends("week_update", "6") +o:depends("week_update", "7") +o.rmempty = true + +---- Interval Update +o = s:option(ListValue, "interval_update", translate("Update Interval(hour)")) +for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end +o.default = 2 +o:depends("week_update", "8") +o.rmempty = true + +o = s:option(ListValue, "access_mode", translate("Subscribe URL Access Method")) +o.default = "" +o:value("", translate("Auto")) +o:value("direct", translate("Direct Connection")) +o:value("proxy", translate("Proxy")) + +o = s:option(Value, "user_agent", translate("User-Agent")) +o.default = "passwall" +o:value("passwall", "PassWall") +o:value("v2rayN/9.99", "v2rayN") +o:value("clash.meta", "Clash.Meta") +o:value("Clash", "Clash") +o:value("curl", "Curl") +o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Linux") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Windows") + +o = s:option(ListValue, "chain_proxy", translate("Chain Proxy")) +o:value("", translate("Close(Not use)")) +o:value("1", translate("Preproxy Node")) +o:value("2", translate("Landing Node")) +o:value("3", translate("Outbound Interface")) + +local descrStr = "Chained proxy works only with Xray or Sing-box nodes.
" +descrStr = descrStr .. "You can only use manual or imported nodes as chained nodes." +descrStr = translate(descrStr) .. "
" .. translate("Only support a layer of proxy.") + +o1 = s:option(ListValue, "preproxy_node", translate("Preproxy Node")) +o1:depends({ ["chain_proxy"] = "1" }) +o1.description = descrStr +o1.template = appname .. "/cbi/nodes_listvalue" +o1.group = {} + +o2 = s:option(ListValue, "to_node", translate("Landing Node")) +o2:depends({ ["chain_proxy"] = "2" }) +o2.description = descrStr +o2.template = appname .. "/cbi/nodes_listvalue" +o2.group = {} + +o3 = s:option(Value, "outbound_iface", translate("Outbound Interface")) +o3:depends({ ["chain_proxy"] = "3" }) +o3:value("", translate("All")) +local iface = api.get_network_devices() +for _, d in ipairs(iface) do + o3:value(d.name, d.label) +end + +for k, v in pairs(nodes_table) do + if (v.type == "Xray" or v.type == "sing-box") and (not v.chain_proxy or v.chain_proxy == "") and v.add_mode ~= "2" then + o1:value(v.id, v.remark) + o1.group[#o1.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + o2:value(v.id, v.remark) + o2.group[#o2.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end +end + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua new file mode 100644 index 00000000..431a60dc --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua @@ -0,0 +1,267 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local fs = api.fs +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") + +local port_validate = function(self, value, t) + return value:gsub("-", ":") +end + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ Delay Settings ]]-- +s = m:section(TypedSection, "global_delay", translate("Delay Settings")) +s.anonymous = true +s.addremove = false + +---- Open and close Daemon +o = s:option(Flag, "start_daemon", translate("Open and close Daemon")) +o.default = 1 +o.rmempty = false + +---- Delay Start +o = s:option(Value, "start_delay", translate("Delay Start"), translate("Units:seconds")) +o.default = "1" +o.rmempty = true + +for index, value in ipairs({"stop", "start", "restart"}) do + o = s:option(ListValue, value .. "_week_mode", translate(value .. " automatically mode")) + o:value("", translate("Disable")) + o:value(8, translate("Loop Mode")) + o:value(7, translate("Every day")) + o:value(1, translate("Every Monday")) + o:value(2, translate("Every Tuesday")) + o:value(3, translate("Every Wednesday")) + o:value(4, translate("Every Thursday")) + o:value(5, translate("Every Friday")) + o:value(6, translate("Every Saturday")) + o:value(0, translate("Every Sunday")) + o = s:option(ListValue, value .. "_time_mode", translate(value .. " Time(Every day)")) + for t = 0, 23 do o:value(t, t .. ":00") end + o.default = 0 + o:depends(value .. "_week_mode", "0") + o:depends(value .. "_week_mode", "1") + o:depends(value .. "_week_mode", "2") + o:depends(value .. "_week_mode", "3") + o:depends(value .. "_week_mode", "4") + o:depends(value .. "_week_mode", "5") + o:depends(value .. "_week_mode", "6") + o:depends(value .. "_week_mode", "7") + o = s:option(ListValue, value .. "_interval_mode", translate(value .. " Interval(Hour)")) + for t = 1, 24 do o:value(t, t .. " " .. translate("Hour")) end + o.default = 2 + o:depends(value .. "_week_mode", "8") +end + +-- [[ Forwarding Settings ]]-- +s = m:section(TypedSection, "global_forwarding", translate("Forwarding Settings")) +s.anonymous = true +s.addremove = false + +---- TCP No Redir Ports +o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) +o.default = "disable" +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +---- UDP No Redir Ports +o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"), + "" .. translate( + "Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") .. + "") +o.default = "disable" +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +---- TCP Proxy Drop Ports +o = s:option(Value, "tcp_proxy_drop_ports", translate("TCP Proxy Drop Ports")) +o.default = "disable" +o:value("disable", translate("No patterns are used")) +o.validate = port_validate + +---- UDP Proxy Drop Ports +o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports")) +o.default = "443" +o:value("disable", translate("No patterns are used")) +o:value("443", translate("QUIC")) +o.validate = port_validate + +---- TCP Redir Ports +o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports")) +o:value("1:65535", translate("All")) +o:value("22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418", translate("Common Use")) +o:value("80,443", translate("Only Web")) +o.default = o.keylist[2] +o.validate = port_validate + +---- UDP Redir Ports +o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports")) +o.default = "1:65535" +o:value("1:65535", translate("All")) +o:value("53", "DNS") +o.validate = port_validate + +o = s:option(DummyValue, "tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', + translate("The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000.")) +end + +---- Use nftables +o = s:option(ListValue, "prefer_nft", translate("Prefer firewall tools")) +o.default = "1" +o:value("0", "Iptables") +o:value("1", "Nftables") + +---- Check the transparent proxy component +local handle = io.popen("lsmod") +local mods = "" +if handle then + mods = handle:read("*a") or "" + handle:close() +end + +if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then + o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way")) + o.default = "redirect" + o:value("redirect", "REDIRECT") + o:value("tproxy", "TPROXY") + o:depends("ipv6_tproxy", false) + o.remove = function(self, section) + -- ç¦æ­¢åœ¨éšè—时删除 + end + + o = s:option(ListValue, "_tcp_proxy_way", translate("TCP Proxy Way")) + o.default = "tproxy" + o:value("tproxy", "TPROXY") + o:depends("ipv6_tproxy", true) + o.write = function(self, section, value) + self.map:set(section, "tcp_proxy_way", value) + end + + if mods:find("ip6table_mangle") or mods:find("nft_tproxy") then + ---- IPv6 TProxy + o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"), + "" .. translate( + "Experimental feature. Make sure that your node supports IPv6.") .. + "") + o.default = 0 + o.rmempty = false + end +end + +o = s:option(Flag, "accept_icmp", translate("Hijacking ICMP (PING)")) +o.default = 0 + +o = s:option(Flag, "accept_icmpv6", translate("Hijacking ICMPv6 (IPv6 PING)")) +o:depends("ipv6_tproxy", true) +o.default = 0 + +if has_xray then + s_xray = m:section(TypedSection, "global_xray", "Xray " .. translate("Settings")) + s_xray.anonymous = true + s_xray.addremove = false + + o = s_xray:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists.")) + o.default = 0 + + o = s_xray:option(ListValue, "fragment_packets", translate("Fragment Packets"), translate("\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation.")) + o.default = "tlshello" + o:value("tlshello", "tlshello") + o:value("1-1", "1-1") + o:value("1-2", "1-2") + o:value("1-3", "1-3") + o:value("1-5", "1-5") + o:depends("fragment", true) + + o = s_xray:option(Value, "fragment_length", translate("Fragment Length"), translate("Fragmented packet length (byte)")) + o.datatype = "or(uinteger,portrange)" + o.default = "100-200" + o:depends("fragment", true) + + o = s_xray:option(Value, "fragment_delay", translate("Fragment Delay"), translate("Fragmentation interval (ms)")) + o.datatype = "or(uinteger,portrange)" + o.default = "10-20" + o:depends("fragment", true) + + o = s_xray:option(Value, "fragment_maxSplit", translate("Max Split"), translate("Limit the maximum number of splits.")) + o.datatype = "or(uinteger,portrange)" + o.default = "100-200" + o:depends("fragment", true) + + o = s_xray:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions.")) + o.default = 0 + + o = s_xray:option(Flag, "sniffing_override_dest", translate("Override the connection destination address")) + o.default = 0 + o.description = translate("Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly.") + + local domains_excluded = string.format("/usr/share/%s/rules/domains_excluded", appname) + o = s_xray:option(TextValue, "excluded_domains", translate("Excluded Domains"), translate("If the traffic sniffing result is in this list, the destination address will not be overridden.")) + o.rows = 15 + o.wrap = "off" + o.cfgvalue = function(self, section) return fs.readfile(domains_excluded) or "" end + o.write = function(self, section, value) fs.writefile(domains_excluded, value:gsub("\r\n", "\n")) end + o:depends({sniffing_override_dest = true}) + + o = s_xray:option(Value, "buffer_size", translate("Buffer Size"), translate("Buffer size for every connection (kB)")) + o.datatype = "uinteger" + + s_xray_noise = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets"),"" .. translate("To send noise packets, select \"Noise\" in Xray Settings.") .. "") + s_xray_noise.template = "cbi/tblsection" + s_xray_noise.sortable = true + s_xray_noise.anonymous = true + s_xray_noise.addremove = true + + s_xray_noise.create = function(e, t) + TypedSection.create(e, api.gen_short_uuid()) + end + + s_xray_noise.remove = function(self, section) + for k, v in pairs(self.children) do + v.rmempty = true + v.validate = nil + end + TypedSection.remove(self, section) + end + + o = s_xray_noise:option(Flag, "enabled", translate("Enable")) + o.default = 1 + o.rmempty = false + + o = s_xray_noise:option(ListValue, "type", translate("Type")) + o:value("rand", "rand") + o:value("array", "array") + o:value("str", "str") + o:value("hex", "hex") + o:value("base64", "base64") + + o = s_xray_noise:option(Value, "packet", translate("Packet | Rand Length")) + o.datatype = "minlength(1)" + o.rmempty = false + + o = s_xray_noise:option(Value, "delay", translate("Delay (ms)")) + o.datatype = "or(uinteger,portrange)" + o.rmempty = false +end + +if has_singbox then + s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings")) + s.anonymous = true + s.addremove = false + + o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"), + translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first.")) + o.default = 0 + + o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"), + translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed.")) + o.default = 0 +end + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua new file mode 100644 index 00000000..fa5d6d87 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua @@ -0,0 +1,176 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local has_xray = api.finded_com("xray") +local has_singbox = api.finded_com("sing-box") + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ Rule Settings ]]-- +s = m:section(TypedSection, "global_rules", translate("Rule status")) +s.anonymous = true + +--[[ +o = s:option(Flag, "adblock", translate("Enable adblock")) +o.rmempty = false +]]-- + +---- gfwlist URL +o = s:option(DynamicList, "gfwlist_url", translate("GFW domains(gfwlist) Update URL")) +o:depends("geo2rule", false) +o:value("https://cdn.jsdelivr.net/gh/YW5vbnltb3Vz/domain-list-community@release/gfwlist.txt", translate("v2fly/domain-list-community")) +o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt", translate("Loyalsoldier/v2ray-rules-dat")) +o:value("https://cdn.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt", translate("Loukky/gfwlist-by-loukky")) +o:value("https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt", translate("gfwlist/gfwlist")) +o.default = o.keylist[2] + +----chnroute URL +o = s:option(DynamicList, "chnroute_url", translate("China IPs(chnroute) Update URL")) +o:depends("geo2rule", false) +o:value("https://cdn.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china.txt", translate("gaoyifan/china-operator-ip/china")) +o:value("https://ispip.clang.cn/all_cn.txt", translate("Clang.CN")) +o:value("https://cdn.jsdelivr.net/gh/soffchen/GeoIP2-CN@release/CN-ip-cidr.txt", translate("soffchen/GeoIP2-CN")) +o:value("https://cdn.jsdelivr.net/gh/Hackl0us/GeoIP2-CN@release/CN-ip-cidr.txt", translate("Hackl0us/GeoIP2-CN")) +o:value("https://cdn.jsdelivr.net/gh/blackmatrix7/ios_rule_script@master/rule/Clash/ChinaMax/ChinaMax_IP_No_IPv6.txt", translate("ios_rule_script/ChinaMax_IP_No_IPv6")) + +----chnroute6 URL +o = s:option(DynamicList, "chnroute6_url", translate("China IPv6s(chnroute6) Update URL")) +o:depends("geo2rule", false) +o:value("https://cdn.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china6.txt", translate("gaoyifan/china-operator-ip/china6")) +o:value("https://ispip.clang.cn/all_cn_ipv6.txt", translate("Clang.CN.IPv6")) +o:value("https://cdn.jsdelivr.net/gh/blackmatrix7/ios_rule_script@master/rule/Clash/ChinaMax/ChinaMax_IP.txt", translate("ios_rule_script/ChinaMax_IP")) + +----chnlist URL +o = s:option(DynamicList, "chnlist_url", translate("China List(Chnlist) Update URL")) +o:depends("geo2rule", false) +o:value("https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf", translate("felixonmars/domains.china")) +o:value("https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf", translate("felixonmars/apple.china")) +o:value("https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf", translate("felixonmars/google.china")) +o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/china-list.txt", translate("Loyalsoldier/china-list")) +o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/apple-cn.txt", translate("Loyalsoldier/apple-cn")) +o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/google-cn.txt", translate("Loyalsoldier/google-cn")) +o:value("https://cdn.jsdelivr.net/gh/blackmatrix7/ios_rule_script@master/rule/Clash/ChinaMax/ChinaMax_Domain.txt", translate("ios_rule_script/ChinaMax_Domain")) + +if has_xray or has_singbox then + o = s:option(Value, "geoip_url", translate("GeoIP Update URL")) + o:value("https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat", translate("Loyalsoldier/geoip")) + o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geoip.dat", translate("MetaCubeX/geoip")) + o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip.dat", translate("Loyalsoldier/geoip (CDN)")) + o:value("https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat", translate("MetaCubeX/geoip (CDN)")) + o.default = o.keylist[1] + + o = s:option(Value, "geosite_url", translate("Geosite Update URL")) + o:value("https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat", translate("Loyalsoldier/geosite")) + o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geosite.dat", translate("MetaCubeX/geosite")) + o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat", translate("Loyalsoldier/geosite (CDN)")) + o:value("https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat", translate("MetaCubeX/geosite (CDN)")) + o.default = o.keylist[1] + + o = s:option(Value, "v2ray_location_asset", translate("Location of Geo rule files"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are.")) + o.default = "/usr/share/v2ray/" + o.placeholder = "/usr/share/v2ray/" + o.rmempty = false + + if api.is_finded("geoview") then + o = s:option(Flag, "geo2rule", translate("Generate Rule List from Geo")) + o.default = 0 + o.rmempty = false + o.description = translate("Generate rule lists such as GFW, China domains, and China IP ranges based on Geo files.") .. "
" .. + translate("When manually updating with this option enabled, rules will be regenerated from existing Geo files even if no new version is available.") .. "" + + o = s:option(Flag, "enable_geoview", translate("Enable Geo Data Parsing")) + o.default = 0 + o.rmempty = false + o.description = "
    " + .. "
  • " .. translate("Experimental feature.") .. "
  • " + .. "
  • " .. "1." .. translate("Analyzes and preloads GeoIP/Geosite data to enhance the shunt performance of Sing-box/Xray.") .. "
  • " + .. "
  • " .. "2." .. translate("Once enabled, the rule list can support GeoIP/Geosite rules.") .. "
  • " + .. "
  • " .. translate("Note: Increases resource usage; Geosite analysis is only supported in ChinaDNS-NG and SmartDNS modes.") .. "
  • " + .. "
" + function o.write(self, section, value) + local old = m:get(section, self.option) or "0" + if old ~= value then + m:set("@global[0]", "flush_set", "1") + end + return Flag.write(self, section, value) + end + end +end + +---- Auto Update +o = s:option(Flag, "auto_update", translate("Enable auto update rules")) +o.default = 0 +o.rmempty = false + +---- Week Update +o = s:option(ListValue, "week_update", translate("Update Mode")) +o:value(8, translate("Loop Mode")) +o:value(7, translate("Every day")) +o:value(1, translate("Every Monday")) +o:value(2, translate("Every Tuesday")) +o:value(3, translate("Every Wednesday")) +o:value(4, translate("Every Thursday")) +o:value(5, translate("Every Friday")) +o:value(6, translate("Every Saturday")) +o:value(0, translate("Every Sunday")) +o.default = 7 +o:depends("auto_update", true) +o.rmempty = true + +---- Time Update +o = s:option(ListValue, "time_update", translate("Update Time(every day)")) +for t = 0, 23 do o:value(t, t .. ":00") end +o.default = 0 +o:depends("week_update", "0") +o:depends("week_update", "1") +o:depends("week_update", "2") +o:depends("week_update", "3") +o:depends("week_update", "4") +o:depends("week_update", "5") +o:depends("week_update", "6") +o:depends("week_update", "7") +o.rmempty = true + +---- Interval Update +o = s:option(ListValue, "interval_update", translate("Update Interval(hour)")) +for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end +o.default = 2 +o:depends("week_update", "8") +o.rmempty = true + +---- 更新选项,始终被jséšè— +local flags = { + "gfwlist_update", "chnroute_update", "chnroute6_update", + "chnlist_update", "geoip_update", "geosite_update" +} +for _, f in ipairs(flags) do + o = s:option(Flag, f) + o.rmempty = false +end + +s:append(Template(appname .. "/rule/rule_version")) + +if has_xray or has_singbox then + s = m:section(TypedSection, "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") + s.template = "cbi/tblsection" + s.anonymous = false + s.addremove = true + s.sortable = true + s.extedit = api.url("shunt_rules", "%s") + function s.create(e, t) + TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) + end + function s.remove(e, t) + m.uci:foreach(appname, "nodes", function(s) + if s["protocol"] and s["protocol"] == "_shunt" then + m:del(s[".name"], t) + end + end) + TypedSection.remove(e, t) + end + + o = s:option(DummyValue, "remarks", translate("Remarks")) +end + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua new file mode 100644 index 00000000..6ad3f058 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua @@ -0,0 +1,338 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local fs = api.fs +local sys = api.sys +local uci = api.uci +local datatypes = api.datatypes +local path = string.format("/usr/share/%s/rules/", appname) +local gfwlist_path = "/usr/share/passwall/rules/gfwlist" +local chnlist_path = "/usr/share/passwall/rules/chnlist" +local chnroute_path = "/usr/share/passwall/rules/chnroute" + +m = Map(appname) +api.set_apply_on_parse(m) + +function clean_text(text) + local nbsp = string.char(0xC2, 0xA0) -- ä¸é—´æ–­ç©ºæ ¼ï¼ˆU+00A0) + local fullwidth_space = string.char(0xE3, 0x80, 0x80) -- 全角空格(U+3000) + return text + :gsub("\t", " ") + :gsub(nbsp, " ") + :gsub(fullwidth_space, " ") + :gsub("^%s+", "") + :gsub("%s+$", "\n") + :gsub("\r\n", "\n") + :gsub("[ \t]*\n[ \t]*", "\n") +end + +-- [[ Rule List Settings ]]-- +s = m:section(TypedSection, "global_rules") +s.anonymous = true + +s:tab("direct_list", translate("Direct List")) +s:tab("proxy_list", translate("Proxy List")) +s:tab("block_list", translate("Block List")) +s:tab("lan_ip_list", translate("Lan IP List")) +s:tab("route_hosts", translate("Route Hosts")) + +---- Direct Hosts +local direct_host = path .. "direct_host" +o = s:taboption("direct_list", TextValue, "direct_host", "", "" .. translate("Join the direct hosts list of domain names will not proxy.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(direct_host) or "" +end +o.write = function(self, section, value) + fs.writefile(direct_host, value:gsub("\r\n", "\n")) + sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*") +end +o.remove = function(self, section, value) + fs.writefile(direct_host, "") + sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*") +end +o.validate = function(self, value) + local hosts= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, api.trim(w)) end) + for index, host in ipairs(hosts) do + if host ~= "" and not host:find("^#") and not host:find("^geosite:") then + if not datatypes.hostname(host) then + return nil, host .. " " .. translate("Not valid domain name, please re-enter!") + end + end + end + return value +end + +---- Direct IP +local direct_ip = path .. "direct_ip" +o = s:taboption("direct_list", TextValue, "direct_ip", "", "" .. translate("These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(direct_ip) or "" +end +o.write = function(self, section, value) + fs.writefile(direct_ip, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + fs.writefile(direct_ip, "") +end +o.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, api.trim(w)) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask ~= "" and not ipmask:find("^#") and not ipmask:find("^geoip:") then + if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then + return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!") + end + end + end + return value +end + +---- Proxy Hosts +local proxy_host = path .. "proxy_host" +o = s:taboption("proxy_list", TextValue, "proxy_host", "", "" .. translate("These had been joined websites will use proxy. Please input the domain names of websites, every line can input only one website domain. For example: google.com.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(proxy_host) or "" +end +o.write = function(self, section, value) + fs.writefile(proxy_host, value:gsub("\r\n", "\n")) + sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*") +end +o.remove = function(self, section, value) + fs.writefile(proxy_host, "") + sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*") +end +o.validate = function(self, value) + local hosts= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, api.trim(w)) end) + for index, host in ipairs(hosts) do + if host ~= "" and not host:find("^#") and not host:find("^geosite:") then + if not datatypes.hostname(host) then + return nil, host .. " " .. translate("Not valid domain name, please re-enter!") + end + end + end + return value +end + +---- Proxy IP +local proxy_ip = path .. "proxy_ip" +o = s:taboption("proxy_list", TextValue, "proxy_ip", "", "" .. translate("These had been joined ip addresses will use proxy. Please input the ip address or ip address segment, every line can input only one ip address. For example: 35.24.0.0/24 or 8.8.4.4.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(proxy_ip) or "" +end +o.write = function(self, section, value) + fs.writefile(proxy_ip, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + fs.writefile(proxy_ip, "") +end +o.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, api.trim(w)) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask ~= "" and not ipmask:find("^#") and not ipmask:find("^geoip:") then + if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then + return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!") + end + end + end + return value +end + +---- Block Hosts +local block_host = path .. "block_host" +o = s:taboption("block_list", TextValue, "block_host", "", "" .. translate("These had been joined websites will be block. Please input the domain names of websites, every line can input only one website domain. For example: twitter.com.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(block_host) or "" +end +o.write = function(self, section, value) + fs.writefile(block_host, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + fs.writefile(block_host, "") +end +o.validate = function(self, value) + local hosts= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, api.trim(w)) end) + for index, host in ipairs(hosts) do + if host ~= "" and not host:find("^#") and not host:find("^geosite:") then + if not datatypes.hostname(host) then + return nil, host .. " " .. translate("Not valid domain name, please re-enter!") + end + end + end + return value +end + +---- Block IP +local block_ip = path .. "block_ip" +o = s:taboption("block_list", TextValue, "block_ip", "", "" .. translate("These had been joined ip addresses will be block. Please input the ip address or ip address segment, every line can input only one ip address.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(block_ip) or "" +end +o.write = function(self, section, value) + fs.writefile(block_ip, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + fs.writefile(block_ip, "") +end +o.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, api.trim(w)) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask ~= "" and not ipmask:find("^#") and not ipmask:find("^geoip:") then + if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then + return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!") + end + end + end + return value +end + +---- Lan IPv4 +local lanlist_ipv4 = path .. "lanlist_ipv4" +o = s:taboption("lan_ip_list", TextValue, "lanlist_ipv4", "", "" .. translate("The list is the IPv4 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(lanlist_ipv4) or "" +end +o.write = function(self, section, value) + fs.writefile(lanlist_ipv4, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + fs.writefile(lanlist_ipv4, "") +end +o.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, api.trim(w)) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask ~= "" and not ipmask:find("^#") then + if not datatypes.ipmask4(ipmask) then + return nil, ipmask .. " " .. translate("Not valid IPv4 format, please re-enter!") + end + end + end + return value +end + +---- Lan IPv6 +local lanlist_ipv6 = path .. "lanlist_ipv6" +o = s:taboption("lan_ip_list", TextValue, "lanlist_ipv6", "", "" .. translate("The list is the IPv6 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(lanlist_ipv6) or "" +end +o.write = function(self, section, value) + fs.writefile(lanlist_ipv6, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + fs.writefile(lanlist_ipv6, "") +end +o.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, api.trim(w)) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask ~= "" and not ipmask:find("^#") then + if not datatypes.ipmask6(ipmask) then + return nil, ipmask .. " " .. translate("Not valid IPv6 format, please re-enter!") + end + end + end + return value +end + +---- Route Hosts +local hosts = "/etc/hosts" +o = s:taboption("route_hosts", TextValue, "hosts", "", "" .. translate("Configure routing etc/hosts file, if you don't know what you are doing, please don't change the content.") .. "") +o.rows = 15 +o.wrap = "off" +o.cfgvalue = function(self, section) + return fs.readfile(hosts) or "" +end +o.write = function(self, section, value) + fs.writefile(hosts, clean_text(value)) +end +o.remove = function(self, section, value) + fs.writefile(hosts, "") +end + +if fs.access(gfwlist_path) then + s:tab("gfw_list", translate("GFW List")) + o = s:taboption("gfw_list", DummyValue, "_gfw_fieldset") + o.rawhtml = true + o.default = string.format([[ +
+ + +
+ + ]], translate("Read List")) +end + +if fs.access(chnlist_path) then + s:tab("chn_list", translate("China List") .. "(" .. translate("Domain") .. ")") + o = s:taboption("chn_list", DummyValue, "_chn_fieldset") + o.rawhtml = true + o.default = string.format([[ +
+ + +
+ + ]], translate("Read List")) +end + +if fs.access(chnroute_path) then + s:tab("chnroute_list", translate("China List") .. "(IP)") + o = s:taboption("chnroute_list", DummyValue, "_chnroute_fieldset") + o.rawhtml = true + o.default = string.format([[ +
+ + +
+ + ]], translate("Read List")) +end + +m:append(Template(appname .. "/rule_list/js")) + +local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") +local geosite_path = geo_dir .. "/geosite.dat" +local geoip_path = geo_dir .. "/geoip.dat" +if api.finded_com("geoview") and fs.access(geosite_path) and fs.access(geoip_path) then + if api.compare_versions(api.get_app_version("geoview"), ">=", "0.1.0") then + s:tab("geoview", translate("Geo View")) + o = s:taboption("geoview", DummyValue, "_geoview_fieldset") + o.rawhtml = true + o.template = appname .. "/rule_list/geoview" + end +end + +m.on_before_save = function(self) + m:set("@global[0]", "flush_set", "1") +end + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua new file mode 100644 index 00000000..85596c9b --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua @@ -0,0 +1,248 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local datatypes = api.datatypes + +m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule")) +m.redirect = api.url("rule") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +m.on_before_save = function(self) + m:set("@global[0]", "flush_set", "1") +end + +-- Add inline CSS to map description +m.description = (m.description or "") .. "\n" .. [[ + +]] + +function clean_text(text) + local nbsp = string.char(0xC2, 0xA0) -- ä¸é—´æ–­ç©ºæ ¼ï¼ˆU+00A0) + local fullwidth_space = string.char(0xE3, 0x80, 0x80) -- 全角空格(U+3000) + return text + :gsub("\t", " ") + :gsub(nbsp, " ") + :gsub(fullwidth_space, " ") + :gsub("^%s+", "") + :gsub("%s+$", "\n") + :gsub("\r\n", "\n") + :gsub("[ \t]*\n[ \t]*", "\n") +end + +s = m:section(NamedSection, arg[1], "shunt_rules", "") +s.addremove = false +s.dynamic = false + +remarks = s:option(Value, "remarks", translate("Remarks")) +remarks.default = arg[1] +remarks.rmempty = false +remarks.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translate("Remark cannot be empty.") + end + return value +end + +protocol = s:option(MultiValue, "protocol", translate("Protocol")) +protocol:value("http") +protocol:value("tls") +protocol:value("quic") +protocol:value("bittorrent") +protocol.widget = "checkbox" +protocol.default = nil + +o = s:option(MultiValue, "inbound", translate("Inbound Tag")) +o:value("tproxy", translate("Transparent proxy")) +o:value("socks", "Socks") +o.widget = "checkbox" +o.default = nil + +network = s:option(ListValue, "network", translate("Network")) +network:value("tcp,udp", "TCP UDP") +network:value("tcp", "TCP") +network:value("udp", "UDP") + +source = s:option(DynamicList, "source", translate("Source")) +source.description = "
  • " .. translate("Example:") +.. "
  • " .. translate("IP") .. ": 192.168.1.100" +.. "
  • " .. translate("IP CIDR") .. ": 192.168.1.0/24" +.. "
  • " .. translate("GeoIP") .. ": geoip:private" +.. "
" +source.cast = "string" +source.cfgvalue = function(self, section) + local value + if self.tag_error[section] then + value = self:formvalue(section) + else + value = self.map:get(section, self.option) + if type(value) == "string" then + local value2 = {} + string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end) + value = value2 + end + end + return value +end +source.validate = function(self, value, t) + local err = {} + for _, v in ipairs(value) do + local flag = false + if datatypes.ip4addr(v) then + flag = true + end + + if flag == false and v:find("geoip:") and v:find("geoip:") == 1 then + flag = true + end + + if flag == false then + err[#err + 1] = v + end + end + + if #err > 0 then + self:add_error(t, "invalid", translate("Not true format, please re-enter!")) + for _, v in ipairs(err) do + self:add_error(t, "invalid", v) + end + end + + return value +end + +local dynamicList_write = function(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + t = table.concat(t, " ") + return DynamicList.write(self, section, t) +end + +source.write = dynamicList_write + +--[[ +-- Too low usage rate, hidden +sourcePort = s:option(Value, "sourcePort", translate("Source port")) +]]-- + +port = s:option(Value, "port", translate("port")) + +domain_list = s:option(TextValue, "domain_list", translate("Domain")) +domain_list.rows = 10 +domain_list.wrap = "off" +domain_list.validate = function(self, value) + local hosts= {} + value = clean_text(value) + string.gsub(value, "[^\r\n]+", function(w) table.insert(hosts, w) end) + for index, host in ipairs(hosts) do + local flag = 1 + local tmp_host = host + if not host:find("#") and host:find("%s") then + elseif host:find("regexp:") and host:find("regexp:") == 1 then + flag = 0 + elseif host:find("domain:.") and host:find("domain:.") == 1 then + tmp_host = host:gsub("domain:", "") + elseif host:find("full:.") and host:find("full:.") == 1 then + tmp_host = host:gsub("full:", "") + elseif host:find("geosite:") and host:find("geosite:") == 1 then + flag = 0 + elseif host:find("ext:") and host:find("ext:") == 1 then + flag = 0 + elseif host:find("rule-set:", 1, true) == 1 or host:find("rs:") == 1 then + local w = host:sub(host:find(":") + 1, #host) + if w:find("local:") == 1 or w:find("remote:") == 1 then + flag = 0 + end + elseif host:find("#") and host:find("#") == 1 then + flag = 0 + end + if flag == 1 then + if not datatypes.hostname(tmp_host) then + return nil, tmp_host .. " " .. translate("Not valid domain name, please re-enter!") + end + end + end + return value +end +domain_list.description = "
    " +.. "
  • " .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.") .. "
  • " +.. "
  • " .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.") .. "
  • " +.. "
  • " .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.") .. "
  • " +.. "
  • " .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.") .. "
  • " +.. "
  • " .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.") .. "
  • " +.. "
  • " + .. translate("Sing-Box is compatible with Geo rules and rule-set. rule-set begin with 'rule-set:remote:' or 'rule-set:local:'.") + .. "
      " + .. "
    • " .. translate("Such as:") .. "'rule-set:remote:https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs'" .. "
    • " + .. "
    • " .. translate("Such as:") .. "'rule-set:local:/usr/share/sing-box/geosite-cn.srs'" .. "
    • " + .. "
    " +.. "
  • " +.. "
  • " .. translate("Annotation: Begining with #") .. "
  • " +.. "
" +ip_list = s:option(TextValue, "ip_list", "IP") +ip_list.rows = 10 +ip_list.wrap = "off" +ip_list.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, "[^\r\n]+", function(w) table.insert(ipmasks, w) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 and not ipmask:find("%s") then + elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 and not ipmask:find("%s") then + elseif ipmask:find("rule-set:", 1, true) == 1 or ipmask:find("rs:") == 1 then + local w = ipmask:sub(ipmask:find(":") + 1, #ipmask) + if w:find("local:") == 1 or w:find("remote:") == 1 then + flag = 0 + end + elseif ipmask:find("#") and ipmask:find("#") == 1 then + else + if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then + return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!") + end + end + end + return value +end +ip_list.description = "
    " +.. "
  • " .. translate("IP: such as '127.0.0.1'.") .. "
  • " +.. "
  • " .. translate("CIDR: such as '127.0.0.0/8'.") .. "
  • " +.. "
  • " .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.") .. "
  • " +.. "
  • " + .. translate("Sing-Box is compatible with Geo rules and rule-set. rule-set begin with 'rule-set:remote:' or 'rule-set:local:'.") + .. "
      " + .. "
    • " .. translate("Such as:") .. "'rule-set:remote:https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs'" .. "
    • " + .. "
    • " .. translate("Such as:") .. "'rule-set:local:/usr/share/sing-box/geoip-cn.srs'" .. "
    • " + .. "
    " +.. "
  • " +.. "
  • " .. translate("Annotation: Begining with #") .. "
  • " +.. "
" + +o = s:option(Flag, "invert", "Invert", translate("Invert match result.") .. " " .. translate("Only support Sing-Box.")) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua new file mode 100644 index 00000000..114aaa05 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua @@ -0,0 +1,139 @@ +local api = require "luci.passwall.api" +local appname = "passwall" + +m = Map(appname) +m.redirect = api.url() +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +m:append(Template(appname .. "/cbi/nodes_dynamiclist_com")) +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + nodes_table[#nodes_table + 1] = e +end + +s = m:section(NamedSection, arg[1], translate("Socks Config"), translate("Socks Config")) +s.addremove = false +s.dynamic = false + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +local auto_switch_tip +local current_node = api.get_cache_var("socks_" .. arg[1]) +if current_node then + local n = m:get(current_node) + if n then + if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then + if n then + local remarks = api.get_node_remarks(n) + local url = api.url("node_config", n[".name"]) + auto_switch_tip = translatef("Current node: %s", string.format('%s', url, remarks)) .. "
" + end + end + end +end + +socks_node = s:option(ListValue, "node", translate("Node")) +if auto_switch_tip then + socks_node.description = auto_switch_tip +end +socks_node.template = appname .. "/cbi/nodes_listvalue" +socks_node.group = {} + +o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" + +local n = 1 +m.uci:foreach(appname, "socks", function(s) + if s[".name"] == section then + return false + end + n = n + 1 +end) + +o = s:option(Value, "port", "Socks " .. translate("Listen Port")) +o.default = n + 1080 +o.datatype = "port" +o.rmempty = false + +if has_singbox or has_xray then + o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) + o.default = 0 + o.datatype = "port" +end + +o = s:option(Flag, "log", translate("Enable") .. " " .. translate("Log")) +o.default = 1 +o.rmempty = false + +o = s:option(Flag, "enable_autoswitch", translate("Auto Switch")) +o.default = 0 +o.rmempty = false + +o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds")) +o.datatype = "min(10)" +o.default = 30 +o:depends("enable_autoswitch", true) + +o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds")) +o.datatype = "min(1)" +o.default = 3 +o:depends("enable_autoswitch", true) + +o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num")) +o.datatype = "min(1)" +o.default = 1 +o:depends("enable_autoswitch", true) + +o = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes")) +o:depends("enable_autoswitch", true) +o.template = appname .. "/cbi/nodes_dynamiclist" +o.group = {} +o.write = function(self, section, value) + local n = s.fields["node"]:formvalue(section) + local v = type(value) == "table" and value or { value } + local t = {} + for _, x in ipairs(v) do + if x and x ~= n then t[#t+1] = x end + end + return DynamicList.write(self, section, t) +end +for i, v in pairs(nodes_table) do + if v.protocol ~= "_shunt" then + o:value(v.id, v.remark) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + s.fields["enable_autoswitch"]:depends({ node = v.id }) + end + socks_node:value(v.id, v["remark"]) + socks_node.group[#socks_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end + +o = s:option(Flag, "autoswitch_restore_switch", translate("Restore Switch"), translate("When detects main node is available, switch back to the main node.")) +o:depends("enable_autoswitch", true) + +o = s:option(Value, "autoswitch_probe_url", translate("Probe URL"), translate("The URL used to detect the connection status.")) +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.default = o.keylist[3] +o:depends("enable_autoswitch", true) + +o = s:option(DummyValue, "btn") +o.template = appname .. "/socks_auto_switch/btn" +o:depends("enable_autoswitch", true) + +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/hysteria2.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/hysteria2.lua new file mode 100644 index 00000000..fc0886df --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/hysteria2.lua @@ -0,0 +1,109 @@ +local m, s = ... + +if not api.finded_com("hysteria") then + return +end + +type_name = "Hysteria2" + +-- [[ Hysteria2 ]] + +s.fields["type"]:value(type_name, "Hysteria2") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "hysteria2_" + +local function _n(name) + return option_prefix .. name +end + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("udp", "UDP") + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) +o:depends({ [_n("realms")] = false }) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" +o:depends({ [_n("realms")] = false }) + +o = s:option(Value, _n("hop"), translate("Port hopping range")) +o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") +o.rewrite_option = o.option +o:depends({ [_n("realms")] = false }) + +o = s:option(Value, _n("hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) +o.datatype = "or(uinteger,portrange)" +o.placeholder = "30" +o.default = "30" +o.rewrite_option = o.option +o:depends({ [_n("realms")] = false }) + +o = s:option(Flag, _n("realms"), translate("Realms")) +o.default = "0" +o.rewrite_option = o.option + +o = s:option(Value, _n("realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(DynamicList, _n("realm_stun"), translate("Realm STUN")) +o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(Value, _n("auth_password"), translate("Auth Password")) +o.password = true +o.rewrite_option = o.option + +o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o:value("gecko") +o.rewrite_option = o.option + +o = s:option(Value, _n("obfs_password"), translate("Obfs Password")) +o.rewrite_option = o.option +o:depends({ [_n("obfs_type")] = "salamander" }) +o:depends({ [_n("obfs_type")] = "gecko" }) + +o = s:option(Flag, _n("fast_open"), translate("Fast Open")) +o.default = "0" + +o = s:option(Value, _n("tls_serverName"), translate("Domain")) + +o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) +o.default = "0" + +o = s:option(Value, _n("tls_pinSHA256"), translate("PinSHA256"),translate("Certificate fingerprint")) + +o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps")) +o.rewrite_option = o.option + +o = s:option(Value, _n("down_mbps"), translate("Max download Mbps")) +o.rewrite_option = o.option + +o = s:option(Value, _n("recv_window"), translate("QUIC stream receive window")) +o.rewrite_option = o.option + +o = s:option(Value, _n("recv_window_conn"), translate("QUIC connection receive window")) +o.rewrite_option = o.option + +o = s:option(Value, _n("idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)") +o.rewrite_option = o.option + +o = s:option(Value, _n("keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)") +o.rewrite_option = o.option + +o = s:option(Flag, _n("disable_mtu_discovery"), translate("Disable MTU detection")) +o.default = "0" +o.rewrite_option = o.option + +o = s:option(Flag, _n("lazy_start"), translate("Lazy Start")) +o.default = "0" +o.rewrite_option = o.option + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/naive.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/naive.lua new file mode 100644 index 00000000..621596fd --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/naive.lua @@ -0,0 +1,37 @@ +local m, s = ... + +if not api.is_finded("naive") then + return +end + +type_name = "Naiveproxy" + +-- [[ Naive ]] + +s.fields["type"]:value(type_name, "NaiveProxy") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "naive_" + +local function _n(name) + return option_prefix .. name +end + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("https", translate("HTTPS")) +o:value("quic", translate("QUIC")) + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("username"), translate("Username")) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua new file mode 100644 index 00000000..4730c274 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua @@ -0,0 +1,860 @@ +local m, s = ... + +if not api.finded_com("xray") then + return +end + +local jsonc = api.jsonc + +type_name = "Xray" + +-- [[ Xray ]] + +s.fields["type"]:value(type_name, "Xray") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "xray_" + +local function _n(name) + return option_prefix .. name +end + +local formvalue_proto = luci.http.formvalue(formvalue_key .. _n("protocol")) + +if formvalue_proto then s.val["protocol"] = formvalue_proto end + +local arg_select_proto = luci.http.formvalue("select_proto") or "" + +local ss_method_list = { + "none", "plain", "aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero" } + +local header_type_list = { + "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns" +} + +local xray_version = api.get_app_version("xray") + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("vmess", translate("Vmess")) +o:value("vless", translate("VLESS")) +o:value("http", translate("HTTP")) +o:value("socks", translate("Socks")) +o:value("shadowsocks", translate("Shadowsocks")) +o:value("trojan", translate("Trojan")) +o:value("wireguard", translate("WireGuard")) +if api.compare_versions(xray_version, ">=", "26.1.13") then + o:value("hysteria2", translate("Hysteria2")) +end +if api.compare_versions(xray_version, ">=", "1.8.12") then + o:value("_balancing", translate("Balancing")) +end +o:value("_shunt", translate("Shunt")) +o:value("_iface", translate("Custom Interface")) +function o.custom_cfgvalue(self, section) + if arg_select_proto ~= "" then + return arg_select_proto + else + return m:get(section, self.option:sub(1 + #option_prefix)) + end +end + +local load_balancing_options = s.val["protocol"] == "_balancing" or arg_select_proto == "_balancing" +local load_shunt_options = s.val["protocol"] == "_shunt" or arg_select_proto == "_shunt" +local load_iface_options = s.val["protocol"] == "_iface" or arg_select_proto == "_iface" +local load_normal_options = true +if load_balancing_options or load_shunt_options or load_iface_options then + load_normal_options = nil +end +if not arg_select_proto:find("_") then + load_normal_options = true +end + +local netdev_list = api.get_network_devices() +local node_list = api.get_node_list() +local fallback_list = {} +local is_balancer = nil +for k, e in ipairs(node_list.balancing_list or {}) do + if e.id ~= arg[1] then + fallback_list[#fallback_list + 1] = { + id = e["id"], + remark = e["remark"], + group = e["group"], + fallback = e.o["fallback_node"], + } + else + is_balancer = true + end +end + +if load_balancing_options then -- [[ Load balancing Start ]] + o = s:option(ListValue, _n("node_add_mode"), translate("Node Addition Method")) + o:depends({ [_n("protocol")] = "_balancing" }) + o.default = "manual" + o:value("manual", translate("Manual")) + o:value("batch", translate("Batch")) + + o = s:option(MultiValue, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, document")) + o:depends({ [_n("node_add_mode")] = "manual" }) + o.widget = "checkbox" + o.template = appname .. "/cbi/nodes_multivalue" + o.group = {} + for k1, v1 in pairs(node_list) do + if k1 == "socks_list" or k1 == "normal_list" then + for i, v in ipairs(v1) do + o:value(v.id, v.remark) + o.group[#o.group+1] = v.group or "" + end + end + end + -- è¯»å–æ—§ DynamicList + function o.cfgvalue(self, section) + return m.uci:get_list(appname, section, "balancing_node") or {} + end + -- å†™å…¥ä¿æŒ DynamicList + function o.custom_write(self, section, value) + local old = m.uci:get_list(appname, section, "balancing_node") or {} + local new, set = {}, {} + for v in value:gmatch("%S+") do + new[#new + 1] = v + set[v] = 1 + end + for _, v in ipairs(old) do + if not set[v] then + m.uci:set_list(appname, section, "balancing_node", new) + return + end + set[v] = nil + end + for _ in pairs(set) do + m.uci:set_list(appname, section, "balancing_node", new) + return + end + end + + o = s:option(MultiValue, _n("node_group"), translate("Select Group")) + o:depends({ [_n("node_add_mode")] = "batch" }) + o.widget = "checkbox" + o:value("default", translate("default")) + for k, v in pairs(groups) do + o:value(api.UrlEncode(k), k) + end + + o = s:option(Value, _n("node_match_rule"), translate("Node Matching Rules")) + o:depends({ [_n("node_add_mode")] = "batch" }) + local descrStr = "Example: ^A && B && !C && D$
" + descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" + descrStr = descrStr .. "Conditions are joined by &&, and their order does not affect the result." + o.description = translate(descrStr) .. string.format("
%s", + translate("Keep the match scope small. Too many nodes can impact router performance.")) + + o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy")) + o:depends({ [_n("protocol")] = "_balancing" }) + o:value("random") + o:value("roundRobin") + o:value("leastPing") + o:value("leastLoad") + o.default = "random" + + -- Fallback Node + o = s:option(ListValue, _n("fallback_node"), translate("Fallback Node")) + o.group = {"",""} + o:value("", translate("Close(Not use)")) + o:value("_direct", translate("Direct Connection")) + o:depends({ [_n("protocol")] = "_balancing" }) + o.template = appname .. "/cbi/nodes_listvalue" + -- 最大 fallback 套娃层数 + local MAX_FALLBACK_DEPTH = 3 + -- 检查是å¦ä¼šå½¢æˆå›žçޝ + local function will_loop(start_id, target_id, depth) + depth = depth or 0 + -- 超过最大深度åŽåœæ­¢é€’å½’ + if depth >= MAX_FALLBACK_DEPTH then + return false + end + for _, v in ipairs(fallback_list) do + if v.id == target_id then + local fb = v.fallback + -- 没有 fallback + if not fb or fb == "" or fb == "_direct" then + return false + end + -- 检测到回环 + if fb == start_id then + return true + end + -- 继续递归检查 + return will_loop(start_id, fb, depth + 1) + end + end + return false + end + -- èŽ·å– fallback 链深度 + local function get_fallback_depth(id, depth) + depth = depth or 0 + if depth >= MAX_FALLBACK_DEPTH then + return depth + end + for _, v in ipairs(fallback_list) do + if v.id == id then + local fb = v.fallback + if not fb or fb == "" or fb == "_direct" then + return depth + end + return get_fallback_depth(fb, depth + 1) + end + end + return depth + end + for _, v in ipairs(fallback_list) do + local depth = get_fallback_depth(v.id) + -- 超过最大套娃层数åŽï¼Œä¸å…许继续选择 balancer + if depth < MAX_FALLBACK_DEPTH + and not will_loop(arg[1], v.id) + then + o:value(v.id, v.remark) + o.group[#o.group + 1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + for k1, v1 in pairs(node_list) do + if k1 == "socks_list" or k1 == "normal_list" or k1 == "urltest_list" then + for i, v in ipairs(v1) do + o:value(v.id, v.remark) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + end + + -- æŽ¢æµ‹åœ°å€ + o = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custom Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL.")) + o:depends({ [_n("protocol")] = "_balancing" }) + + o = s:option(Value, _n("probeUrl"), translate("Probe URL")) + o:depends({ [_n("useCustomProbeUrl")] = true }) + o:value("https://cp.cloudflare.com/", "Cloudflare") + o:value("https://www.gstatic.com/generate_204", "Gstatic") + o:value("https://www.google.com/generate_204", "Google") + o:value("https://www.youtube.com/generate_204", "YouTube") + o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") + o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") + o.default = o.keylist[3] + o.description = translate("The URL used to detect the connection status.") + + -- 探测间隔 + o = s:option(Value, _n("probeInterval"), translate("Probe Interval")) + o:depends({ [_n("protocol")] = "_balancing" }) + o.default = "1m" + o.placeholder = "1m" + o.description = translate("The interval between initiating probes.") .. "
" .. + translate("The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively.") .. "
" .. + translate("When the unit is not filled in, it defaults to seconds.") + + o = s:option(Value, _n("expected"), translate("Preferred Node Count")) + o:depends({ [_n("balancingStrategy")] = "leastLoad" }) + o.datatype = "uinteger" + o.default = "2" + o.placeholder = "2" + o.description = translate("The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them.") + + o = s:option(Value, _n("tolerance"), translate("Failure Tolerance (%)")) + o:depends({ [_n("balancingStrategy")] = "leastLoad" }) + o.datatype = "uinteger" + o.default = "10" + o.placeholder = "10" + o.description = translate("The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate.") +end -- [[ è´Ÿè½½å‡è¡¡ End ]] + +if load_iface_options then -- [[ è‡ªå®šä¹‰æŽ¥å£ Start ]] + o = s:option(Value, _n("iface"), translate("Interface")) + o:depends({ [_n("protocol")] = "_iface" }) + for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) + end +end -- [[ è‡ªå®šä¹‰æŽ¥å£ End ]] + + +if load_normal_options then + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("uuid"), translate("ID")) +o.password = true +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(ListValue, _n("security"), translate("Encrypt Method")) +for a, t in ipairs(security_list) do o:value(t) end +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(Value, _n("encryption"), translate("Encrypt Method") .. " (encryption)") +o.default = "none" +o.placeholder = "none" +o:depends({ [_n("protocol")] = "vless" }) +o.validate = function(self, value) + value = api.trim(value) + return (value == "" and "none" or value) +end + +o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(ss_method_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("iv_check"), translate("IV Check")) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-128-gcm" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-256-gcm" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "chacha20-poly1305" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "xchacha20-poly1305" }) + +o = s:option(Flag, _n("uot"), translate("UDP over TCP")) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:value("xtls-rprx-vision-udp443") +o:depends({ [_n("protocol")] = "vless" }) + +---- [[hysteria2]] +o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range")) +o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) +o.datatype = "or(uinteger,portrange)" +o.placeholder = "30" +o.default = "30" +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) +o.password = true +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) +o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + +o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)") +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Value, _n("hysteria2_keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)") +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Flag, _n("hysteria2_disable_mtu_discovery"), translate("Disable MTU detection")) +o.default = "0" +o:depends({ [_n("protocol")] = "hysteria2"}) +---- [[hysteria2 end]] + +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("reality"), translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision.")) +o.default = 0 +o:depends({ [_n("tls")] = true, [_n("transport")] = "raw" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "ws" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "grpc" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "xhttp" }) + +o = s:option(ListValue, _n("alpn"), translate("alpn")) +o.default = "default" +o:value("default", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +-- o = s:option(Value, _n("minversion"), translate("minversion")) +-- o.default = "1.3" +-- o:value("1.3") +-- o:depends({ [_n("tls")] = true }) + +o = s:option(Value, _n("tls_serverName"), "SNI " .. translate("Domain")) +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +if api.compare_versions(os.date("%Y.%m.%d"), "<", "2026.6.1") then + o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) + o.default = "0" + o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + o:depends({ [_n("protocol")] = "hysteria2" }) +end + +if api.compare_versions(xray_version, ">=", "26.1.31") then + o = s:option(Value, _n("tls_pinSHA256"), translate("TLS Chain Fingerprint (SHA256)")) + o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + o:depends({ [_n("protocol")] = "hysteria2" }) + o.description = translate("Once set, connects only when the server’s chain fingerprint matches.") .. + string.format("%s", "→ " .. translate("Fetch Manually")) + + o = s:option(Value, _n("tls_CertByName"), translate("TLS Certificate Name (CertName)"), translate("TLS is used to verify the leaf certificate name.")) + o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + o:depends({ [_n("protocol")] = "hysteria2" }) +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(TextValue, _n("ech_config"), translate("ECH Config")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +-- [[ REALITY部分 ]] -- +o = s:option(Value, _n("reality_publicKey"), translate("Public Key")) +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Value, _n("reality_shortId"), translate("Short Id")) +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Value, _n("reality_spiderX"), translate("Spider X")) +o.placeholder = "/" +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Flag, _n("utls"), translate("uTLS")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + +o = s:option(ListValue, _n("fingerprint"), translate("Finger Print")) +o:value("chrome") +o:value("firefox") +o:value("edge") +o:value("safari") +o:value("360") +o:value("qq") +o:value("ios") +o:value("android") +o:value("random") +o:value("randomized") +o.default = "chrome" +o:depends({ [_n("tls")] = true, [_n("utls")] = true }) +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Flag, _n("use_mldsa65Verify"), translate("ML-DSA-65")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(TextValue, _n("reality_mldsa65Verify"), "ML-DSA-65 " .. translate("Public key")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("use_mldsa65Verify")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("raw", "RAW (TCP)") +o:value("mkcp", "mKCP") +o:value("ws", "WebSocket") +o:value("grpc", "gRPC") +o:value("httpupgrade", "HttpUpgrade") +o:value("xhttp", "XHTTP") +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(Value, _n("wireguard_public_key"), translate("Public Key")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(Value, _n("wireguard_mtu"), translate("MTU")) +o.default = "1420" +o:depends({ [_n("protocol")] = "wireguard" }) + +if api.compare_versions(xray_version, ">=", "1.8.0") then + o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) + o:depends({ [_n("protocol")] = "wireguard" }) +end + +o = s:option(Value, _n("wireguard_keepAlive"), translate("Keep Alive")) +o.default = "0" +o:depends({ [_n("protocol")] = "wireguard" }) + +-- [[ RAW部分 ]]-- + +-- TCP伪装 +o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o:depends({ [_n("transport")] = "raw" }) + +-- HTTP域å +o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host")) +o:depends({ [_n("tcp_guise")] = "http" }) + +-- HTTP路径 +o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path")) +o.placeholder = "/" +o:depends({ [_n("tcp_guise")] = "http" }) + +-- [[ mKCP部分 ]]-- + +o = s:option(ListValue, _n("mkcp_guise"), translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests.')) +for a, t in ipairs(header_type_list) do o:value(t) end +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_domain"), translate("Camouflage Domain"), translate("Use it together with the DNS disguised type. You can fill in any domain.")) +o:depends({ [_n("mkcp_guise")] = "dns" }) + +o = s:option(Value, _n("mkcp_mtu"), translate("KCP MTU")) +o.datatype = "uinteger" +o.default = 1350 +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed")) +o:depends({ [_n("transport")] = "mkcp" }) + +-- [[ WebSocket部分 ]]-- +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_heartbeatPeriod"), translate("HeartbeatPeriod(second)")) +o.datatype = "integer" +o:depends({ [_n("transport")] = "ws" }) + +-- [[ gRPC部分 ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(ListValue, _n("grpc_mode"), "gRPC " .. translate("Transfer mode")) +o:value("gun") +o:value("multi") +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Flag, _n("grpc_health_check"), translate("Health check")) +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Value, _n("grpc_idle_timeout"), translate("Idle timeout")) +o.default = "10" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Value, _n("grpc_health_check_timeout"), translate("Health check timeout")) +o.default = "20" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Flag, _n("grpc_permit_without_stream"), translate("Permit without stream")) +o.default = "0" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Value, _n("grpc_initial_windows_size"), translate("Initial Windows Size")) +o.default = "0" +o:depends({ [_n("transport")] = "grpc" }) + +-- [[ HttpUpgrade部分 ]]-- +o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HttpUpgrade Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ XHTTP部分 ]]-- +o = s:option(ListValue, _n("xhttp_mode"), "XHTTP " .. translate("Mode")) +o:depends({ [_n("transport")] = "xhttp" }) +o.default = "auto" +o:value("auto") +o:value("packet-up") +o:value("stream-up") +o:value("stream-one") + +o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host")) +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_path"), translate("XHTTP Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Flag, _n("use_xhttp_extra"), translate("XHTTP Extra")) +o.default = "0" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(TextValue, _n("xhttp_extra"), " ", translate("An XHttpObject in JSON format, used for sharing.")) +o:depends({ [_n("use_xhttp_extra")] = true }) +o.rows = 10 +o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "xhttp_extra") + if raw then + return api.base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "xhttp_extra", api.base64Encode(value) or "") + local success, data = pcall(jsonc.parse, value) + if success and data then + local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address) + or (data.downloadSettings and data.downloadSettings.address) + if address and address ~= "" then + address = address:gsub("^%[", ""):gsub("%]$", "") + m:set(section, "download_address", address) + else + m:del(section, "download_address") + end + else + m:del(section, "download_address") + end +end +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if api.jsonc.parse(value) then + return value + else + return nil, "XHTTP Extra " .. translate("Must be JSON text!") + end +end +o.custom_remove = function(self, section, value) + m:del(section, "xhttp_extra") + m:del(section, "download_address") +end + +-- [[ User-Agent ]]-- +o = s:option(Value, _n("user_agent"), translate("User-Agent")) +o.default = "" +o:value("", translate("default")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", "chrome") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0", "firefox") +o:value("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15", "safari") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70", "edge") +o:value("Go-http-client/1.1", "golang") +o:value("curl/7.68.0", "curl") +o:depends({ [_n("tcp_guise")] = "http" }) +o:depends({ [_n("transport")] = "ws" }) +o:depends({ [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("transport")] = "xhttp" }) +o:depends({ [_n("transport")] = "grpc" }) + +-- [[ Mux.Cool ]]-- +o = s:option(Flag, _n("mux"), "Mux", translate("Enable Mux.Cool")) +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "raw" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "ws" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "grpc" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(Value, _n("mux_concurrency"), translate("Mux concurrency")) +o.default = -1 +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("xudp_concurrency"), translate("XUDP Mux concurrency")) +o.default = 8 +o:depends({ [_n("mux")] = true }) + +--[[FinalMask]] +o = s:option(Flag, _n("use_finalmask"), "FinalMask") +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "wireguard" }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(TextValue, _n("finalmask"), " ") +o:depends({ [_n("use_finalmask")] = true }) +o.rows = 10 +o.wrap = "off" +o.description = translate("An FinalMaskObject in JSON format, used for sharing.") .. "
" .. + translate("Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings.") +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "finalmask") + if raw then + return api.base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "finalmask", api.base64Encode(value) or "") +end +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if api.jsonc.parse(value) then + return value + else + return nil, "FinalMask " .. translate("Must be JSON text!") + end +end + +--[[Fast Open]] +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) +o.default = 0 + +--[[tcpMptcp]] +o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) +o.default = 0 + +o = s:option(Value, _n("preconns"), translate("Pre-connections"), translate("Number of early established connections to reduce latency.")) +o.datatype = "uinteger" +o.placeholder = 0 +o:depends({ [_n("protocol")] = "vless" }) + +o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve")) +o.description = translate("If the node address is a domain name, this DNS will be used for resolution.") .. "
" .. string.format('%s', + translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) +o:value("", translate("Auto")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("https", "DoH") + +o = s:option(Value, _n("domain_resolver_dns"), "DNS") +o.datatype = "or(ipaddr,ipaddrport)" +o:value("114.114.114.114") +o:value("223.5.5.5:53") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "tcp" }) +o:depends({ [_n("domain_resolver")] = "udp" }) + +o = s:option(Value, _n("domain_resolver_dns_https"), "DNS") +o:value("https://120.53.53.53/dns-query", "DNSPod") +o:value("https://223.5.5.5/dns-query", "AliDNS") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "https" }) + +o = s:option(ListValue, _n("domain_strategy"), translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) +o.default = "" +o:value("", translate("Auto")) +o:value("UseIPv4v6", translate("Prefer IPv4")) +o:value("UseIPv6v4", translate("Prefer IPv6")) +o:value("UseIPv4", translate("IPv4 Only")) +o:value("UseIPv6", translate("IPv6 Only")) + +local protocols = s.fields[_n("protocol")].keylist +if #protocols > 0 then + for i, v in ipairs(protocols) do + if not v:find("^_") then + s.fields[_n("address")]:depends({ [_n("protocol")] = v }) + s.fields[_n("port")]:depends({ [_n("protocol")] = v }) + s.fields[_n("domain_resolver")]:depends({ [_n("protocol")] = v }) + s.fields[_n("domain_strategy")]:depends({ [_n("protocol")] = v }) + + if v ~= "hysteria2" then + s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v }) + s.fields[_n("tcpMptcp")]:depends({ [_n("protocol")] = v }) + end + end + end +end +end +-- [[ Normal single node End ]] + +if not load_shunt_options then + o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy")) + o:value("", translate("Close(Not use)")) + if not (load_iface_options or load_balancing_options) then + -- Special node cannot be use pre-proxy. + o:value("1", translate("Preproxy Node")) + o:value("3", translate("Outbound Interface")) + end + o:value("2", translate("Landing Node")) + + o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) + o1:depends({ [_n("chain_proxy")] = "1" }) + o1.template = appname .. "/cbi/nodes_listvalue" + o1.group = {} + + o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface")) + o3:depends({ [_n("chain_proxy")] = "3" }) + o3:value("", translate("All")) + for _, d in ipairs(netdev_list) do + o3:value(d.name, d.label) + end + + o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) + o2:depends({ [_n("chain_proxy")] = "2" }) + o2.template = appname .. "/cbi/nodes_listvalue" + o2.group = {} + + for k1, v1 in pairs(node_list) do + if k1 ~= "shunt_list" and k1 ~= "iface_list" then + for i, v in ipairs(v1) do + if v.id ~= arg[1] then + o1:value(v.id, v.remark) + o1.group[#o1.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + if k1 == "normal_list" then + -- Landing Node not support use special node. + o2:value(v.id, v.remark) + o2.group[#o2.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + end + end + end +end + +api.luci_types(arg[1], m, s, type_name, option_prefix) + +if load_shunt_options then + local current_node = m.uci:get_all(appname, arg[1]) or {} + local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua") + setfenv(shunt_lua, getfenv(1))(m, s, { + node_id = arg[1], + node = current_node, + node_list = node_list, + }) +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua new file mode 100644 index 00000000..19c6ad05 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua @@ -0,0 +1,880 @@ +local m, s = ... + +local singbox_bin = api.finded_com("sing-box") + +if not singbox_bin then + return +end + +type_name = "sing-box" + +-- [[ sing-box ]] + +s.fields["type"]:value(type_name, "Sing-Box") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "singbox_" + +local function _n(name) + return option_prefix .. name +end + +local formvalue_proto = luci.http.formvalue(formvalue_key .. _n("protocol")) + +if formvalue_proto then s.val["protocol"] = formvalue_proto end + +local arg_select_proto = luci.http.formvalue("select_proto") or "" + +local ss_method_new_list = { + "none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +local ss_method_old_list = { + "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20", +} + +local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero" } + +local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'") + +local singbox_version = api.get_app_version("sing-box"):match("[^v]+") + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("socks", "Socks") +o:value("http", "HTTP") +o:value("shadowsocks", "Shadowsocks") +o:value("vmess", "Vmess") +o:value("trojan", "Trojan") +if singbox_tags:find("with_wireguard") then + o:value("wireguard", "WireGuard") +end +if singbox_tags:find("with_quic") then + o:value("hysteria", "Hysteria") +end +o:value("vless", "VLESS") +if singbox_tags:find("with_quic") then + o:value("tuic", "TUIC") +end +if singbox_tags:find("with_quic") then + o:value("hysteria2", "Hysteria2") +end +o:value("anytls", "AnyTLS") +o:value("ssh", "SSH") +if singbox_tags:find("with_naive_outbound") then + o:value("naive", "NaïveProxy") +end +o:value("_urltest", translate("URLTest")) +o:value("_shunt", translate("Shunt")) +o:value("_iface", translate("Custom Interface")) +function o.custom_cfgvalue(self, section) + if arg_select_proto ~= "" then + return arg_select_proto + else + return m:get(section, self.option:sub(1 + #option_prefix)) + end +end + +local load_urltest_options = s.val["protocol"] == "_urltest" or arg_select_proto == "_urltest" +local load_shunt_options = s.val["protocol"] == "_shunt" or arg_select_proto == "_shunt" +local load_iface_options = s.val["protocol"] == "_iface" or arg_select_proto == "_iface" +local load_normal_options = true +if load_urltest_options or load_shunt_options or load_iface_options then + load_normal_options = nil +end +if not arg_select_proto:find("_") then + load_normal_options = true +end + +local netdev_list = api.get_network_devices() +local node_list = api.get_node_list() + +if load_urltest_options then -- [[ URLTest Start ]] + o = s:option(ListValue, _n("node_add_mode"), translate("Node Addition Method")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.default = "manual" + o:value("manual", translate("Manual")) + o:value("batch", translate("Batch")) + + o = s:option(MultiValue, _n("urltest_node"), translate("URLTest node list"), translate("List of nodes to test, document")) + o:depends({ [_n("node_add_mode")] = "manual" }) + o.widget = "checkbox" + o.template = appname .. "/cbi/nodes_multivalue" + o.group = {} + for k1, v1 in pairs(node_list) do + if k1 == "socks_list" or k1 == "normal_list" then + for i, v in ipairs(v1) do + o:value(v.id, v.remark) + o.group[#o.group+1] = v.group or "" + end + end + end + -- è¯»å–æ—§ DynamicList + function o.cfgvalue(self, section) + return m.uci:get_list(appname, section, "urltest_node") or {} + end + -- å†™å…¥ä¿æŒ DynamicList + function o.custom_write(self, section, value) + local old = m.uci:get_list(appname, section, "urltest_node") or {} + local new, set = {}, {} + for v in value:gmatch("%S+") do + new[#new + 1] = v + set[v] = 1 + end + for _, v in ipairs(old) do + if not set[v] then + m.uci:set_list(appname, section, "urltest_node", new) + return + end + set[v] = nil + end + for _ in pairs(set) do + m.uci:set_list(appname, section, "urltest_node", new) + return + end + end + + o = s:option(MultiValue, _n("node_group"), translate("Select Group")) + o:depends({ [_n("node_add_mode")] = "batch" }) + o.widget = "checkbox" + o:value("default", translate("default")) + for k, v in pairs(groups) do + o:value(api.UrlEncode(k), k) + end + + o = s:option(Value, _n("node_match_rule"), translate("Node Matching Rules")) + o:depends({ [_n("node_add_mode")] = "batch" }) + local descrStr = "Example: ^A && B && !C && D$
" + descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" + descrStr = descrStr .. "Conditions are joined by &&, and their order does not affect the result." + o.description = translate(descrStr) .. string.format("
%s", + translate("Keep the match scope small. Too many nodes can impact router performance.")) + + o = s:option(Value, _n("urltest_url"), translate("Probe URL")) + o:depends({ [_n("protocol")] = "_urltest" }) + o:value("https://cp.cloudflare.com/", "Cloudflare") + o:value("https://www.gstatic.com/generate_204", "Gstatic") + o:value("https://www.google.com/generate_204", "Google") + o:value("https://www.youtube.com/generate_204", "YouTube") + o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") + o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") + o.default = o.keylist[3] + o.description = translate("The URL used to detect the connection status.") + + o = s:option(Value, _n("urltest_interval"), translate("Test interval")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.default = "3m" + o.placeholder = "3m" + o.description = translate("The interval between initiating probes.") .. "
" .. + translate("The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively.") .. "
" .. + translate("When the unit is not filled in, it defaults to seconds.") .. "
" .. + translate("Test interval must be less or equal than idle timeout.") + + o = s:option(Value, _n("urltest_tolerance"), translate("Test tolerance"), translate("The test tolerance in milliseconds.")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.datatype = "uinteger" + o.placeholder = "50" + o.default = "50" + + o = s:option(Value, _n("urltest_idle_timeout"), translate("Idle timeout")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.placeholder = "30m" + o.default = "30m" + o.description = translate("The idle timeout.") .. "
" .. + translate("The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively.") .. "
" .. + translate("When the unit is not filled in, it defaults to seconds.") + + o = s:option(Flag, _n("urltest_interrupt_exist_connections"), translate("Interrupt existing connections")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.default = "0" + o.description = translate("Interrupt existing connections when the selected outbound has changed.") +end -- [[ URLTest End ]] + +if load_iface_options then -- [[ è‡ªå®šä¹‰æŽ¥å£ Start ]] + o = s:option(Value, _n("iface"), translate("Interface")) + o:depends({ [_n("protocol")] = "_iface" }) + for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) + end +end + + +if load_normal_options then + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("uuid"), translate("ID")) +o.password = true +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "tuic" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "ssh" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "anytls" }) +o:depends({ [_n("protocol")] = "ssh" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(ListValue, _n("security"), translate("Encrypt Method")) +for a, t in ipairs(security_list) do o:value(t) end +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(ss_method_new_list) do o:value(t) end +for a, t in ipairs(ss_method_old_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("uot"), translate("UDP over TCP")) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Value, _n("alter_id"), "Alter ID") +o.datatype = "uinteger" +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(Flag, _n("global_padding"), "global_padding", translate("Protocol parameter. Will waste traffic randomly if enabled.")) +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(Flag, _n("authenticated_length"), "authenticated_length", translate("Protocol parameter. Enable length block encryption.")) +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) + +if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria_hop"), translate("Port hopping range")) + o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval(second)"), translate("Example:") .. "30 (≥5)") + o.datatype = "uinteger" + o.placeholder = "30" + o.default = "30" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(ListValue, _n("hysteria_auth_type"), translate("Auth Type")) + o:value("disable", translate("Disable")) + o:value("string", translate("STRING")) + o:value("base64", translate("BASE64")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "string"}) + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "base64"}) + + o = s:option(Value, _n("hysteria_up_mbps"), translate("Max upload Mbps")) + o.default = "10" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_down_mbps"), translate("Max download Mbps")) + o.default = "50" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_recv_window"), translate("QUIC connection receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection")) + o:depends({ [_n("protocol")] = "hysteria" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(ListValue, _n("tuic_congestion_control"), translate("Congestion control algorithm")) + o.default = "cubic" + o:value("bbr", translate("BBR")) + o:value("cubic", translate("CUBIC")) + o:value("new_reno", translate("New Reno")) + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(ListValue, _n("tuic_udp_relay_mode"), translate("UDP relay mode")) + o.default = "native" + o:value("native", translate("native")) + o:value("quic", translate("QUIC")) + o:depends({ [_n("protocol")] = "tuic" }) + + --[[ + o = s:option(Flag, _n("tuic_udp_over_stream"), translate("UDP over stream")) + o:depends({ [_n("protocol")] = "tuic" }) + ]]-- + + o = s:option(Flag, _n("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) + o.default = 0 + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(Value, _n("tuic_heartbeat"), translate("Heartbeat interval(second)")) + o.datatype = "uinteger" + o.default = "3" + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(ListValue, _n("tuic_alpn"), translate("QUIC TLS ALPN")) + o.default = "default" + o:value("default", translate("Default")) + o:value("h3") + o:value("h2") + o:value("h3,h2") + o:value("http/1.1") + o:value("h2,http/1.1") + o:value("h3,h2,http/1.1") + o:value("spdy/3.1") + o:value("h3,spdy/3.1") + o:depends({ [_n("protocol")] = "tuic" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range")) + o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + + o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) + o.datatype = "or(uinteger,portrange)" + o.placeholder = "30" + o.default = "30" + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + + o = s:option(Flag, _n("hysteria2_realms"), translate("Realms")) + o.default = "0" + if api.compare_versions(singbox_version, ">=", "1.14.0") then + o:depends({ [_n("protocol")] = "hysteria2"}) + else + o:depends({ [_n("protocol")] = "__hide"}) + end + + o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN")) + o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) + o:value("", translate("Disable")) + o:value("salamander") + o:value("gecko") + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) + o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + o:depends({ [_n("hysteria2_obfs_type")] = "gecko" }) + + o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)") + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(Value, _n("hysteria2_keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)") + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(Flag, _n("hysteria2_disable_mtu_discovery"), translate("Disable MTU detection")) + o.default = "0" + o:depends({ [_n("protocol")] = "hysteria2"}) +end + +-- [[ SSH config start ]] -- +o = s:option(TextValue, _n("ssh_priv_key"), translate("Private Key")) +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("protocol")] = "ssh" }) +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n") + return value +end + +o = s:option(Value, _n("ssh_priv_key_pp"), translate("Private Key Passphrase")) +o.password = true +o:depends({ [_n("protocol")] = "ssh" }) + +o = s:option(DynamicList, _n("ssh_host_key"), translate("Host Key"), translate("Accept any if empty.")) +o:depends({ [_n("protocol")] = "ssh" }) + +o = s:option(DynamicList, _n("ssh_host_key_algo"), translate("Host Key Algorithms")) +o:depends({ [_n("protocol")] = "ssh" }) + +o = s:option(Value, _n("ssh_client_version"), translate("Client Version"), translate("Random version will be used if empty.")) +o:depends({ [_n("protocol")] = "ssh" }) +-- [[ SSH config end ]] -- + +-- [[ naive start ]] -- +o = s:option(Value, _n("naive_insecure_concurrency"), translate("Concurrent Tunnels")) +o.datatype = "uinteger" +o.placeholder = "0" +o.default = "0" +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Flag, _n("naive_quic"), translate("QUIC")) +o.default = 0 +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(ListValue, _n("naive_congestion_control"), translate("Congestion control algorithm")) +o.default = "bbr" +o:value("bbr", translate("BBR")) +o:value("bbr2", translate("BBRv2")) +o:value("cubic", translate("CUBIC")) +o:value("reno", translate("New Reno")) +o:depends({ [_n("naive_quic")] = "1" }) +-- [[ naive end ]] -- + +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "anytls" }) + +o = s:option(ListValue, _n("alpn"), translate("ALPN")) +o.default = "default" +o:value("default", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria" }) + +o = s:option(Flag, _n("tls_disable_sni"), translate("Disable SNI"), translate("Do not send server name in ClientHello.")) +o.default = "0" +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("tls_serverName"), "SNI " .. translate("Domain")) +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) +o.default = "0" +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(TextValue, _n("ech_config"), translate("ECH Config")) +o.default = "" +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n") + return value +end + +o = s:option(Value, _n("ech_query_server_name"), translate("ECH Query Domain"), translate("Overrides the domain name used for ECH HTTPS record queries.")) +o:depends({ [_n("ech")] = true }) + +if singbox_tags:find("with_utls") then + o = s:option(Flag, _n("utls"), translate("uTLS")) + o.default = "0" + o:depends({ [_n("tls")] = true }) + + o = s:option(ListValue, _n("fingerprint"), translate("Finger Print")) + o:value("chrome") + o:value("firefox") + o:value("edge") + o:value("safari") + o:value("360") + o:value("qq") + o:value("ios") + o:value("android") + o:value("random") + o:value("randomized") + o.default = "chrome" + o:depends({ [_n("utls")] = true }) + + -- [[ REALITY部分 ]] -- + o = s:option(Flag, _n("reality"), translate("REALITY")) + o.default = 0 + o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "socks", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "anytls", [_n("tls")] = true }) + + o = s:option(Value, _n("reality_publicKey"), translate("Public Key")) + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_shortId"), translate("Short Id")) + o:depends({ [_n("reality")] = true }) +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("tcp", "TCP") +o:value("http", "HTTP") +o:value("ws", "WebSocket") +o:value("httpupgrade", "HTTPUpgrade") +if singbox_tags:find("with_quic") then + o:value("quic", "QUIC") +end +if singbox_tags:find("with_grpc") then + o:value("grpc", "gRPC") +else o:value("grpc", "gRPC-lite") +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +if singbox_tags:find("with_wireguard") then + o = s:option(Value, _n("wireguard_public_key"), translate("Public Key")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_mtu"), translate("MTU")) + o.default = "1420" + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) + o:depends({ [_n("protocol")] = "wireguard" }) +end + +-- [[ TCP部分(模拟) ]]-- +o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o:depends({ [_n("transport")] = "tcp" }) + +o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host")) +o:depends({ [_n("tcp_guise")] = "http" }) + +o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path")) +o.placeholder = "/" +o:depends({ [_n("tcp_guise")] = "http" }) + +-- [[ HTTP部分 ]]-- +o = s:option(DynamicList, _n("http_host"), translate("HTTP Host")) +o:depends({ [_n("transport")] = "http" }) + +o = s:option(Value, _n("http_path"), translate("HTTP Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "http" }) + +o = s:option(Flag, _n("http_h2_health_check"), translate("Health check")) +o:depends({ [_n("tls")] = true, [_n("transport")] = "http" }) + +o = s:option(Value, _n("http_h2_read_idle_timeout"), translate("Idle timeout")) +o.default = "10" +o:depends({ [_n("tls")] = true, [_n("transport")] = "http", [_n("http_h2_health_check")] = true }) + +o = s:option(Value, _n("http_h2_health_check_timeout"), translate("Health check timeout")) +o.default = "15" +o:depends({ [_n("tls")] = true, [_n("transport")] = "http", [_n("http_h2_health_check")] = true }) + +-- [[ WebSocket部分 ]]-- +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Flag, _n("ws_enableEarlyData"), translate("Enable early data")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_maxEarlyData"), translate("Early data length")) +o.default = "1024" +o:depends({ [_n("ws_enableEarlyData")] = true }) + +o = s:option(Value, _n("ws_earlyDataHeaderName"), translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol")) +o:depends({ [_n("ws_enableEarlyData")] = true }) + +-- [[ HTTPUpgrade部分 ]]-- +o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ gRPC部分 ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Flag, _n("grpc_health_check"), translate("Health check")) +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Value, _n("grpc_idle_timeout"), translate("Idle timeout")) +o.default = "10" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Value, _n("grpc_health_check_timeout"), translate("Health check timeout")) +o.default = "20" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Flag, _n("grpc_permit_without_stream"), translate("Permit without stream")) +o.default = "0" +o:depends({ [_n("grpc_health_check")] = true }) + +-- [[ User-Agent ]]-- +o = s:option(Value, _n("user_agent"), translate("User-Agent")) +o.default = "" +o:value("", translate("default")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", "chrome") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0", "firefox") +o:value("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15", "safari") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70", "edge") +o:value("Go-http-client/1.1", "golang") +o:value("curl/7.68.0", "curl") +o:depends({ [_n("tcp_guise")] = "http" }) +o:depends({ [_n("transport")] = "http" }) +o:depends({ [_n("transport")] = "ws" }) +o:depends({ [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("protocol")] = "naive" }) + +-- [[ Mux ]]-- +o = s:option(Flag, _n("mux"), translate("Mux")) +o.rmempty = false +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("uot")] = "" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(ListValue, _n("mux_type"), translate("Mux")) +o:value("smux") +o:value("yamux") +o:value("h2mux") +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("mux_concurrency"), translate("Mux concurrency")) +o.default = 4 +o:depends({ [_n("mux")] = true, [_n("tcpbrutal")] = false }) + +o = s:option(Flag, _n("mux_padding"), translate("Padding")) +o.default = 0 +o:depends({ [_n("mux")] = true }) + +-- [[ TCP Brutal ]]-- +o = s:option(Flag, _n("tcpbrutal"), translate("TCP Brutal")) +o.default = 0 +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("tcpbrutal_up_mbps"), translate("Max upload Mbps")) +o.default = "10" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Value, _n("tcpbrutal_down_mbps"), translate("Max download Mbps")) +o.default = "50" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Flag, _n("shadowtls"), "ShadowTLS") +o.default = 0 +o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = false }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = false }) + +o = s:option(ListValue, _n("shadowtls_version"), "ShadowTLS " .. translate("Version")) +o.default = "1" +o:value("1", "ShadowTLS v1") +o:value("2", "ShadowTLS v2") +o:value("3", "ShadowTLS v3") +o:depends({ [_n("shadowtls")] = true }) + +o = s:option(Value, _n("shadowtls_password"), "ShadowTLS " .. translate("Password")) +o.password = true +o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "2" }) +o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "3" }) + +o = s:option(Value, _n("shadowtls_serverName"), "ShadowTLS " .. translate("Domain")) +o:depends({ [_n("shadowtls")] = true }) + +if singbox_tags:find("with_utls") then + o = s:option(Flag, _n("shadowtls_utls"), "ShadowTLS " .. translate("uTLS")) + o.default = "0" + o:depends({ [_n("shadowtls")] = true }) + + o = s:option(ListValue, _n("shadowtls_fingerprint"), "ShadowTLS " .. translate("Finger Print")) + o:value("chrome") + o:value("firefox") + o:value("edge") + o:value("safari") + -- o:value("360") + o:value("qq") + o:value("ios") + -- o:value("android") + o:value("random") + -- o:value("randomized") + o.default = "chrome" + o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_utls")] = true }) +end + +-- [[ SIP003 plugin ]]-- +o = s:option(Flag, _n("plugin_enabled"), translate("plugin")) +o.default = 0 +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("plugin"), "SIP003 " .. translate("plugin")) +o.default = "obfs-local" +o:depends({ [_n("plugin_enabled")] = true }) +o:value("obfs-local") +o:value("v2ray-plugin") + +o = s:option(Value, _n("plugin_opts"), translate("opts")) +o:depends({ [_n("plugin_enabled")] = true }) + +o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve")) +o.description = translate("If the node address is a domain name, this DNS will be used for resolution.") .. "
" .. string.format('%s', + translate("Note: For node-specific DNS only. Keep Auto to avoid extra overhead.")) +o:value("", translate("Auto")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("https", "DoH") + +o = s:option(Value, _n("domain_resolver_dns"), "DNS") +o.datatype = "or(ipaddr,ipaddrport)" +o:value("114.114.114.114") +o:value("223.5.5.5:53") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "tcp" }) +o:depends({ [_n("domain_resolver")] = "udp" }) + +o = s:option(Value, _n("domain_resolver_dns_https"), "DNS") +o:value("https://120.53.53.53/dns-query", "DNSPod") +o:value("https://223.5.5.5/dns-query", "AliDNS") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "https" }) + +o = s:option(ListValue, _n("domain_strategy"), translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) +o.default = "" +o:value("", translate("Auto")) +o:value("prefer_ipv4", translate("Prefer IPv4")) +o:value("prefer_ipv6", translate("Prefer IPv6")) +o:value("ipv4_only", translate("IPv4 Only")) +o:value("ipv6_only", translate("IPv6 Only")) + + +local protocols = s.fields[_n("protocol")].keylist +if #protocols > 0 then + for i, v in ipairs(protocols) do + if not v:find("^_") then + local depends_condition = { [_n("protocol")] = v } + if v == "hysteria2" then + depends_condition[_n("hysteria2_realms")] = false + end + s.fields[_n("address")]:depends(depends_condition) + s.fields[_n("port")]:depends(depends_condition) + s.fields[_n("domain_resolver")]:depends(depends_condition) + s.fields[_n("domain_strategy")]:depends(depends_condition) + end + end +end +end +-- [[ Normal single node End ]] + +if not load_shunt_options then + o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy")) + o:value("", translate("Close(Not use)")) + if not (load_iface_options or load_urltest_options) then + -- Special node cannot be use pre-proxy. + o:value("1", translate("Preproxy Node")) + o:value("3", translate("Outbound Interface")) + end + o:value("2", translate("Landing Node")) + + o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) + o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false }) + o1.template = appname .. "/cbi/nodes_listvalue" + o1.group = {} + + o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface")) + o3:depends({ [_n("chain_proxy")] = "3" }) + o3:value("", translate("All")) + for _, d in ipairs(netdev_list) do + o3:value(d.name, d.label) + end + + o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) + o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false }) + o2.template = appname .. "/cbi/nodes_listvalue" + o2.group = {} + + for k1, v1 in pairs(node_list) do + if k1 ~= "shunt_list" and k1 ~= "iface_list" then + for i, v in ipairs(v1) do + if v.id ~= arg[1] then + o1:value(v.id, v.remark) + o1.group[#o1.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + if k1 == "normal_list" then + -- Landing Node not support use special node. + o2:value(v.id, v.remark) + o2.group[#o2.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + end + end + end +end + +api.luci_types(arg[1], m, s, type_name, option_prefix) + +if load_shunt_options then + local current_node = m.uci:get_all(appname, arg[1]) or {} + local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall/client/include/shunt_options.lua") + setfenv(shunt_lua, getfenv(1))(m, s, { + node_id = arg[1], + node = current_node, + node_list = node_list, + }) +end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss-rust.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss-rust.lua new file mode 100644 index 00000000..36cd9bca --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ss-rust.lua @@ -0,0 +1,76 @@ +local m, s = ... + +if not api.is_finded("sslocal") then + return +end + +type_name = "SS-Rust" + +-- [[ Shadowsocks Rust ]] + +s.fields["type"]:value(type_name, "Shadowsocks Rust") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssrust_" + +local function _n(name) + return option_prefix .. name +end + +local ssrust_encrypt_method_list = { + "none", "plain", + "aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +o = s:option(ListValue, _n("del_protocol")) --始终éšè—,用于删除 protocol +o:depends({ [_n("__hide")] = "1" }) +o.rewrite_option = "protocol" + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true + +o = s:option(Value, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) +o.default = 0 + +o = s:option(Flag, _n("plugin_enabled"), translate("plugin")) +o.default = 0 + +o = s:option(Value, _n("plugin"), "SIP003 " .. translate("plugin"), translate("Supports custom SIP003 plugins, Make sure the plugin is installed.")) +o.default = "none" +o:value("none", translate("none")) +if api.is_finded("xray-plugin") then o:value("xray-plugin") end +if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end +if api.is_finded("obfs-local") then o:value("obfs-local") end +if api.is_finded("shadow-tls") then o:value("shadow-tls") end +o:depends({ [_n("plugin_enabled")] = true }) +o.validate = function(self, value, t) + if value and value ~= "" and value ~= "none" then + if not api.is_finded(value) then + return nil, value .. ": " .. translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(Value, _n("plugin_opts"), translate("opts")) +o:depends({ [_n("plugin_enabled")] = true }) + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua new file mode 100644 index 00000000..3001f626 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ssr.lua @@ -0,0 +1,70 @@ +local m, s = ... + +if not api.is_finded("ssr-local") and not api.is_finded("ssr-redir")then + return +end + +type_name = "SSR" + +-- [[ ShadowsocksR Libev ]] + +s.fields["type"]:value(type_name, "ShadowsocksR Libev") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssr_" + +local function _n(name) + return option_prefix .. name +end + +local ssr_encrypt_method_list = { + "none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb", + "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", + "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", + "cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20", + "chacha20-ietf" +} + +local ssr_protocol_list = { + "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple", + "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5", + "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c", + "auth_chain_d", "auth_chain_e", "auth_chain_f" +} +local ssr_obfs_list = { + "plain", "http_simple", "http_post", "random_head", "tls_simple", + "tls1.0_session_auth", "tls1.2_ticket_auth" +} + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true + +o = s:option(ListValue, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +for a, t in ipairs(ssr_protocol_list) do o:value(t) end + +o = s:option(Value, _n("protocol_param"), translate("Protocol_param")) + +o = s:option(ListValue, _n("obfs"), translate("Obfs")) +for a, t in ipairs(ssr_obfs_list) do o:value(t) end + +o = s:option(Value, _n("obfs_param"), translate("Obfs_param")) + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) +o.default = 0 + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua new file mode 100644 index 00000000..d6ee9323 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/index.lua @@ -0,0 +1,91 @@ +local api = require "luci.passwall.api" + +m = Map("passwall_server", translate("Server-Side")) +api.set_apply_on_parse(m) + +t = m:section(NamedSection, "global", "global") +t.anonymous = true +t.addremove = false + +e = t:option(Flag, "enable", translate("Enable")) +e.rmempty = false + +t = m:section(TypedSection, "user", translate("Users Manager")) +t.anonymous = true +t.addremove = true +t.sortable = true +t.template = "cbi/tblsection" +t.extedit = api.url("server_user", "%s") +function t.create(e, t) + local uuid = api.gen_uuid() + t = uuid + TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end +function t.remove(e, t) + e.map.proceed = true + e.map:del(t) + luci.http.redirect(api.url("server")) +end + +e = t:option(Flag, "enable", translate("Enable")) +e.width = "5%" +e.rmempty = false + +e = t:option(DummyValue, "status", translate("Status")) +e.rawhtml = true +e.cfgvalue = function(t, n) + return string.format('%s', translate("Collecting data...")) +end + +e = t:option(DummyValue, "remarks", translate("Remarks")) +e.width = "15%" + +e = t:option(DummyValue, "type", translate("Type")) +e.width = "20%" +e.rawhtml = true +e.cfgvalue = function(t, n) + local str = "" + local type = m:get(n, "type") or "" + if type == "sing-box" or type == "Xray" then + local protocol = m:get(n, "protocol") or "" + if protocol == "vmess" then + protocol = "VMess" + elseif protocol == "vless" then + protocol = "VLESS" + elseif protocol == "shadowsocks" then + protocol = "SS" + elseif protocol == "shadowsocksr" then + protocol = "SSR" + elseif protocol == "wireguard" then + protocol = "WG" + elseif protocol == "hysteria" then + protocol = "HY" + elseif protocol == "hysteria2" then + protocol = "HY2" + elseif protocol == "anytls" then + protocol = "AnyTLS" + else + protocol = protocol:gsub("^%l",string.upper) + local custom = m:get(n, "custom") or "0" + if custom == "1" then + protocol = translate("Custom Config") + end + end + if type == "sing-box" then type = "Sing-Box" end + type = type .. " " .. protocol + end + str = str .. translate(type) + return str +end + +e = t:option(DummyValue, "port", translate("Port")) + +e = t:option(Flag, "log", translate("Log")) +e.default = "1" +e.rmempty = false + +m:append(Template("passwall/server/log")) + +m:append(Template("passwall/server/users_list_status")) +return m diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/hysteria2.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/hysteria2.lua new file mode 100644 index 00000000..a59c78b1 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/hysteria2.lua @@ -0,0 +1,135 @@ +local m, s = ... + +if not api.finded_com("hysteria") then + return +end + +local fs = api.fs + +local type_name = "Hysteria2" + +-- [[ Hysteria2 ]] + +s.fields["type"]:value(type_name, "Hysteria2") + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "hysteria2_" + +local function _n(name) + return option_prefix .. name +end + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("realms"), translate("Realms")) +o.default = "0" +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(DynamicList, _n("realm_stun"), translate("Realm STUN")) +o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(Value, _n("auth_password"), translate("Auth Password")) +o.password = true +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o:value("gecko") +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("obfs_password"), translate("Obfs Password")) +o.rewrite_option = o.option +o:depends({ [_n("obfs_type")] = "salamander" }) +o:depends({ [_n("obfs_type")] = "gecko" }) + +o = s:option(Flag, _n("udp"), translate("UDP")) +o.default = "1" +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps")) +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("down_mbps"), translate("Max download Mbps")) +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("ignoreClientBandwidth"), translate("ignoreClientBandwidth")) +o.default = "0" +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end +o:depends({ [_n("custom")] = false }) + +o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end +o:depends({ [_n("custom")] = false }) + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua new file mode 100644 index 00000000..437f11c7 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua @@ -0,0 +1,528 @@ +local m, s = ... + +if not api.finded_com("xray") then + return +end + +local type_name = "Xray" + +-- [[ Xray ]] + +s.fields["type"]:value(type_name, "Xray") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "xray_" + +local function _n(name) + return option_prefix .. name +end + +local x_ss_method_list = { + "none", "plain", "aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +local header_type_list = { + "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("vmess", "Vmess") +o:value("vless", "VLESS") +o:value("http", "HTTP") +o:value("socks", "Socks") +o:value("shadowsocks", "Shadowsocks") +o:value("trojan", "Trojan") +o:value("hysteria2", translate("Hysteria2")) +o:value("dokodemo-door", "dokodemo-door") +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("auth"), translate("Auth")) +o.validate = function(self, value, t) + if value and value == "1" then + local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or "" + local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or "" + if user_v == "" or pass_v == "" then + return nil, translate("Username and Password must be used together!") + end + end + return value +end +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "http" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("auth")] = true }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("auth")] = true }) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o:depends({ [_n("protocol")] = "dokodemo-door" }) + +o = s:option(Value, _n("d_address"), translate("Destination address")) +o:depends({ [_n("protocol")] = "dokodemo-door" }) + +o = s:option(Value, _n("d_port"), translate("Destination port")) +o.datatype = "port" +o:depends({ [_n("protocol")] = "dokodemo-door" }) + +o = s:option(Value, _n("decryption"), translate("Encrypt Method") .. " (decryption)") +o.default = "none" +o.placeholder = "none" +o:depends({ [_n("protocol")] = "vless" }) +o.validate = function(self, value) + value = api.trim(value) + return (value == "" and "none" or value) +end + +o = s:option(ListValue, _n("x_ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(x_ss_method_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("iv_check"), translate("IV Check")) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("ss_network"), translate("Transport")) +o.default = "tcp,udp" +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("udp_forward"), translate("UDP Forward")) +o.default = "1" +o.rmempty = false +o:depends({ [_n("protocol")] = "socks" }) + +o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password")) +for i = 1, 3 do + o:value(api.gen_uuid(1)) +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:depends({ [_n("protocol")] = "vless" }) + +---- [[ hysteria2 ]] +o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) +o.password = true +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) +o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + +o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control")) +o.default = 0 +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) + +o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) + +---- [[ TLS ]] +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o.validate = function(self, value, t) + if value then + local reality = s.fields[_n("reality")] and s.fields[_n("reality")]:formvalue(t) or nil + if reality and reality == "1" then return value end + if value == "1" then + local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or "" + local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or "" + if ca == "" or key == "" then + return nil, translate("Public key and Private key path can not be empty!") + end + end + return value + end +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ REALITY部分 ]] -- +o = s:option(Flag, _n("reality"), translate("REALITY")) +o.default = 0 +o:depends({ [_n("tls")] = true }) + +o = s:option(Value, _n("reality_private_key"), translate("Private Key")) +o:depends({ [_n("reality")] = true }) + +o = s:option(DynamicList, _n("reality_shortId"), translate("Short Id")) +o:depends({ [_n("reality")] = true }) + +o = s:option(Value, _n("reality_dest"), translate("Dest")) +o.default = "google.com:443" +o:depends({ [_n("reality")] = true }) + +o = s:option(DynamicList, _n("reality_serverNames"), translate("serverNames")) +o:depends({ [_n("reality")] = true }) +function o.write(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + return DynamicList.write(self, section, t) +end + +o = s:option(ListValue, _n("alpn"), translate("alpn")) +o.default = "h2,http/1.1" +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65")) +o.default = "0" +o:depends({ [_n("reality")] = true }) + +o = s:option(TextValue, _n("reality_mldsa65Seed"), "ML-DSA-65 " .. translate("Private Key")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("use_mldsa65Seed")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +-- o = s:option(Value, _n("minversion"), translate("minversion")) +-- o.default = "1.3" +-- o:value("1.3") +--o:depends({ [_n("tls")] = true }) + +-- [[ TLS部分 ]] -- + +o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2"}) +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2"}) +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + +o = s:option(TextValue, _n("ech_key"), translate("ECH Key")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("raw", "RAW") +o:value("mkcp", "mKCP") +o:value("ws", "WebSocket") +o:value("grpc", "gRPC") +o:value("httpupgrade", "HttpUpgrade") +o:value("xhttp", "XHTTP") +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ WebSocket部分 ]]-- + +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o:depends({ [_n("transport")] = "ws" }) + +-- [[ HttpUpgrade部分 ]]-- +o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HttpUpgrade Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ XHTTP部分 ]]-- +o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host")) +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_path"), translate("XHTTP Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_maxuploadsize"), translate("maxUploadSize")) +o.default = "1000000" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_maxconcurrentuploads"), translate("maxConcurrentUploads")) +o.default = "10" +o:depends({ [_n("transport")] = "xhttp" }) + +-- [[ TCP部分 ]]-- + +-- TCP伪装 +o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o:depends({ [_n("transport")] = "raw" }) + +-- HTTP域å +o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host")) +o:depends({ [_n("tcp_guise")] = "http" }) + +-- HTTP路径 +o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path")) +o:depends({ [_n("tcp_guise")] = "http" }) + +-- [[ mKCP部分 ]]-- + +o = s:option(ListValue, _n("mkcp_guise"), translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests.')) +for a, t in ipairs(header_type_list) do o:value(t) end +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_domain"), translate("Camouflage Domain"), translate("Use it together with the DNS disguised type. You can fill in any domain.")) +o:depends({ [_n("mkcp_guise")] = "dns" }) + +o = s:option(Value, _n("mkcp_mtu"), translate("KCP MTU")) +o.datatype = "uinteger" +o.default = 1350 +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed")) +o:depends({ [_n("transport")] = "mkcp" }) + +-- [[ gRPC部分 ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +--[[FinalMask]] +o = s:option(Flag, _n("use_finalmask"), "FinalMask") +o.default = "0" +o:depends({ [_n("custom")] = false, [_n("protocol")] = "vmess" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "vless" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "trojan" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "wireguard" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "hysteria2" }) + +o = s:option(TextValue, _n("finalmask"), "FinalMask JSON") +o:depends({ [_n("use_finalmask")] = true }) +o.rows = 10 +o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "finalmask") + if raw then + return api.base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "finalmask", api.base64Encode(value) or "") +end +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if api.jsonc.parse(value) then + return value + else + return nil, "FinalMask " .. translate("Must be JSON text!") + end +end + +--[[acceptProxyProtocol]] +o = s:option(Flag, _n("acceptProxyProtocol"), translate("acceptProxyProtocol"), translate("Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used.")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +--[[Fast Open]] +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) +o.default = "0" +o:depends({ [_n("protocol")] = "vmess", [_n("custom")] = false }) +o:depends({ [_n("protocol")] = "vless", [_n("custom")] = false }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("custom")] = false }) +o:depends({ [_n("protocol")] = "trojan", [_n("custom")] = false }) + +-- [[ Fallback部分 ]]-- +o = s:option(Flag, _n("fallback"), translate("Fallback")) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "raw" }) +o:depends({ [_n("protocol")] = "trojan", [_n("transport")] = "raw" }) + +--[[ +o = s:option(Value, _n("fallback_alpn"), "Fallback alpn") +o:depends({ [_n("fallback")] = true }) + +o = s:option(Value, _n("fallback_path"), "Fallback path") +o:depends({ [_n("fallback")] = true }) + +o = s:option(Value, _n("fallback_dest"), "Fallback dest") +o:depends({ [_n("fallback")] = true }) + +o = s:option(Value, _n("fallback_xver"), "Fallback xver") +o.default = 0 +o:depends({ [_n("fallback")] = true }) +]]-- + +o = s:option(DynamicList, _n("fallback_list"), "Fallback", translate("format: dest,path,xver")) +o:depends({ [_n("fallback")] = true }) + +o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e.type == type_name then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + remarks = e["remark"], + group = e["group"] + } + end +end + +o = s:option(ListValue, _n("outbound_node"), translate("outbound node")) +o:value("", translate("Close")) +o:value("_socks", translate("Custom Socks")) +o:value("_http", translate("Custom HTTP")) +o:value("_iface", translate("Custom Interface")) +o.template = api.appname .. "/cbi/nodes_listvalue" +o.group = {"","","",""} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)")) +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_port"), translate("Port")) +o.datatype = "port" +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_username"), translate("Username")) +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_password"), translate("Password")) +o.password = true +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_iface"), translate("Interface")) +o:depends({ [_n("outbound_node")] = "_iface"}) +local netdev_list = api.get_network_devices() +for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) +end + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +o = s:option(ListValue, _n("loglevel"), translate("Log Level")) +o.default = "warning" +o:value("debug") +o:value("info") +o:value("warning") +o:value("error") +o:depends({ [_n("log")] = true }) + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua new file mode 100644 index 00000000..562e9035 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/sing-box.lua @@ -0,0 +1,507 @@ +local m, s = ... + +local singbox_bin = api.finded_com("sing-box") + +if not singbox_bin then + return +end + +local type_name = "sing-box" + +-- [[ Sing-Box ]] + +s.fields["type"]:value(type_name, "Sing-Box") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "singbox_" + +local function _n(name) + return option_prefix .. name +end + +local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'") + +local ss_method_list = { + "none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("mixed", "Mixed") +o:value("socks", "Socks") +o:value("http", "HTTP") +o:value("shadowsocks", "Shadowsocks") +o:value("vmess", "Vmess") +o:value("vless", "VLESS") +o:value("trojan", "Trojan") +o:value("naive", "Naive") +if singbox_tags:find("with_quic") then + o:value("hysteria", "Hysteria") +end +if singbox_tags:find("with_quic") then + o:value("tuic", "TUIC") +end +if singbox_tags:find("with_quic") then + o:value("hysteria2", "Hysteria2") +end +o:value("anytls", "AnyTLS") +o:value("direct", "Direct") +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("auth"), translate("Auth")) +o.validate = function(self, value, t) + if value and value == "1" then + local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or "" + local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or "" + if user_v == "" or pass_v == "" then + return nil, translate("Username and Password must be used together!") + end + end + return value +end +o:depends({ [_n("protocol")] = "mixed" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "http" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("auth")] = true }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "anytls" }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("auth")] = true }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "anytls" }) + +if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria_up_mbps"), translate("Max upload Mbps")) + o.default = "100" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_down_mbps"), translate("Max download Mbps")) + o.default = "100" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(ListValue, _n("hysteria_auth_type"), translate("Auth Type")) + o:value("disable", translate("Disable")) + o:value("string", translate("STRING")) + o:value("base64", translate("BASE64")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "string"}) + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "base64"}) + + o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_recv_window_client"), translate("QUIC connection receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_max_conn_client"), translate("QUIC concurrent bidirectional streams")) + o.default = "1024" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection")) + o:depends({ [_n("protocol")] = "hysteria" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(ListValue, _n("tuic_congestion_control"), translate("Congestion control algorithm")) + o.default = "cubic" + o:value("bbr", translate("BBR")) + o:value("cubic", translate("CUBIC")) + o:value("new_reno", translate("New Reno")) + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(Flag, _n("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) + o.default = 0 + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(Value, _n("tuic_heartbeat"), translate("Heartbeat interval(second)")) + o.datatype = "uinteger" + o.default = "3" + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(ListValue, _n("tuic_alpn"), translate("QUIC TLS ALPN")) + o.default = "default" + o:value("default", translate("Default")) + o:value("h3") + o:value("h2") + o:value("h3,h2") + o:value("http/1.1") + o:value("h2,http/1.1") + o:value("h3,h2,http/1.1") + o:value("spdy/3.1") + o:value("h3,spdy/3.1") + o:depends({ [_n("protocol")] = "tuic" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(Flag, _n("hysteria2_realms"), translate("Realms")) + o.default = "0" + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN")) + o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) + o:value("", translate("Disable")) + o:value("salamander") + o:value("gecko") + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) + o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + o:depends({ [_n("hysteria2_obfs_type")] = "gecko" }) + + o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"), translate("Commands the client to use the BBR flow control algorithm")) + o.default = 0 + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) + + o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) +end + +o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o:depends({ [_n("protocol")] = "direct" }) + +o = s:option(Value, _n("d_address"), translate("Destination address")) +o:depends({ [_n("protocol")] = "direct" }) + +o = s:option(Value, _n("d_port"), translate("Destination port")) +o.datatype = "port" +o:depends({ [_n("protocol")] = "direct" }) + +o = s:option(Value, _n("decryption"), translate("Encrypt Method")) +o.default = "none" +o:depends({ [_n("protocol")] = "vless" }) + +o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(ss_method_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password")) +for i = 1, 3 do + o:value(api.gen_uuid(1)) +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "tuic" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:depends({ [_n("protocol")] = "vless" , [_n("tls")] = true }) + +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o.validate = function(self, value, t) + if value then + local reality = s.fields[_n("reality")] and s.fields[_n("reality")]:formvalue(t) or nil + if reality and reality == "1" then return value end + if value == "1" then + local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or "" + local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or "" + if ca == "" or key == "" then + return nil, translate("Public key and Private key path can not be empty!") + end + end + return value + end +end +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "anytls" }) + +-- https://github.com/SagerNet/sing-box/commit/d2a04c4e41e6cef0937331cb6d10211f431caaab +if singbox_tags:find("with_utls") then + -- [[ REALITY部分 ]] -- + o = s:option(Flag, _n("reality"), translate("REALITY")) + o.default = 0 + o:depends({ [_n("protocol")] = "http", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "anytls", [_n("tls")] = true }) + + o = s:option(Value, _n("reality_private_key"), translate("Private Key")) + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_shortId"), translate("Short Id")) + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_handshake_server"), translate("Handshake Server")) + o.default = "google.com" + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_handshake_server_port"), translate("Handshake Server Port")) + o.datatype = "port" + o.default = "443" + o:depends({ [_n("reality")] = true }) +end + +o = s:option(ListValue, _n("alpn"), translate("ALPN")) +o.default = "default" +o:value("default", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria" }) + +-- [[ TLS部分 ]] -- + +o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + +o = s:option(TextValue, _n("ech_key"), translate("ECH Key")) +o.default = "" +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n") + value = value:gsub("^%s*\n", "") + if value:sub(-1) == "\n" then + value = value:sub(1, -2) + end + return value +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("tcp", "TCP") +o:value("http", "HTTP") +o:value("ws", "WebSocket") +o:value("httpupgrade", "HTTPUpgrade") +o:value("quic", "QUIC") +o:value("grpc", "gRPC") +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ HTTP部分 ]]-- + +o = s:option(DynamicList, _n("http_host"), translate("HTTP Host")) +o:depends({ [_n("transport")] = "http" }) + +o = s:option(Value, _n("http_path"), translate("HTTP Path")) +o:depends({ [_n("transport")] = "http" }) + +-- [[ WebSocket部分 ]]-- + +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o:depends({ [_n("transport")] = "ws" }) + +-- [[ HTTPUpgrade部分 ]]-- + +o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ gRPC部分 ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +-- [[ Mux ]]-- +o = s:option(Flag, _n("mux"), translate("Mux")) +o.rmempty = false +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ TCP Brutal ]]-- +o = s:option(Flag, _n("tcpbrutal"), translate("TCP Brutal")) +o.default = 0 +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("tcpbrutal_up_mbps"), translate("Max upload Mbps")) +o.default = "10" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Value, _n("tcpbrutal_down_mbps"), translate("Max download Mbps")) +o.default = "50" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e.type == type_name then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + remarks = e["remark"], + group = e["group"] + } + end +end + +o = s:option(ListValue, _n("outbound_node"), translate("outbound node")) +o:value("", translate("Close")) +o:value("_socks", translate("Custom Socks")) +o:value("_http", translate("Custom HTTP")) +o:value("_iface", translate("Custom Interface")) +o.template = api.appname .. "/cbi/nodes_listvalue" +o.group = {"","","",""} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)")) +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_port"), translate("Port")) +o.datatype = "port" +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_username"), translate("Username")) +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_password"), translate("Password")) +o.password = true +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_iface"), translate("Interface")) +o:depends({ [_n("outbound_node")] = "_iface" }) +local netdev_list = api.get_network_devices() +for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) +end + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +o = s:option(ListValue, _n("loglevel"), translate("Log Level")) +o.default = "info" +o:value("debug") +o:value("info") +o:value("warn") +o:value("error") +o:depends({ [_n("log")] = true }) + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua new file mode 100644 index 00000000..bfb00061 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/socks.lua @@ -0,0 +1,51 @@ +local m, s = ... + +if not api.is_finded("microsocks") then + return +end + +local type_name = "Socks" + +local option_prefix = "socks_" + +local function _n(name) + return option_prefix .. name +end + +-- [[ microsocks ]] + +s.fields["type"]:value(type_name, "Socks") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" + +o = s:option(Flag, _n("auth"), translate("Auth")) +o.validate = function(self, value, t) + if value and value == "1" then + local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or "" + local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or "" + if user_v == "" or pass_v == "" then + return nil, translate("Username and Password must be used together!") + end + end + return value +end + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("auth")] = true }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("auth")] = true }) + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua new file mode 100644 index 00000000..ed2a2863 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ss-rust.lua @@ -0,0 +1,77 @@ +local m, s = ... + +if not api.is_finded("ssserver") then + return +end + +local type_name = "SS-Rust" + +-- [[ Shadowsocks Rust ]] + +s.fields["type"]:value(type_name, translate("Shadowsocks Rust")) + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssrust_" + +local function _n(name) + return option_prefix .. name +end + +local ssrust_encrypt_method_list = { + "plain", "none", + "aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua new file mode 100644 index 00000000..02a94f61 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ssr.lua @@ -0,0 +1,108 @@ +local m, s = ... + +if not api.is_finded("ssr-server") then + return +end + +local type_name = "SSR" + +-- [[ ShadowsocksR ]] + +s.fields["type"]:value(type_name, translate("ShadowsocksR")) + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssr_" + +local function _n(name) + return option_prefix .. name +end + +local ssr_encrypt_method_list = { + "none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb", + "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", + "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", + "cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20", + "chacha20-ietf" +} + +local ssr_protocol_list = { + "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple", + "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5", + "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c", + "auth_chain_d", "auth_chain_e", "auth_chain_f" +} +local ssr_obfs_list = { + "plain", "http_simple", "http_post", "random_head", "tls_simple", + "tls1.0_session_auth", "tls1.2_ticket_auth" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +for a, t in ipairs(ssr_protocol_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("protocol_param"), translate("Protocol_param")) +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("obfs"), translate("Obfs")) +for a, t in ipairs(ssr_obfs_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("obfs_param"), translate("Obfs_param")) +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("udp_forward"), translate("UDP Forward")) +o.default = "1" +o.rmempty = false + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua b/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua new file mode 100644 index 00000000..35312f53 --- /dev/null +++ b/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua @@ -0,0 +1,59 @@ +api = require "luci.passwall.api" +appname = api.appname +fs = api.fs + +m = Map("passwall_server", translate("Server Config")) +m.redirect = api.url("server") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +local header = Template(appname .. "/server/config_header") +header.api = api +header.config = m.config +header.section = arg[1] +m:append(header) + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +s = m:section(NamedSection, arg[1], "user", "") +s.addremove = false +s.dynamic = false + +local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/" +s.val = m:get(arg[1]) or {} + +o = s:option(Flag, "enable", translate("Enable")) +o.default = "1" +o.rmempty = false + +o = s:option(Value, "remarks", translate("Remarks")) +o.default = translate("Remarks") +o.rmempty = false + +o = s:option(ListValue, "type", translate("Type")) + +local type_table = {} +for filename in fs.dir(types_dir) do + table.insert(type_table, filename) +end +table.sort(type_table, function(a, b) + if a == "socks.lua" then return true end + if b == "socks.lua" then return false end + return a < b +end) + +for index, value in ipairs(type_table) do + local p_func = loadfile(types_dir .. value) + setfenv(p_func, getfenv(1))(m, s) +end + +local footer = Template(appname .. "/server/config_footer") +footer.api = api +footer.config = m.config +footer.section = arg[1] +m:append(footer) + +return m diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua new file mode 100644 index 00000000..10886cf0 --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/api.lua @@ -0,0 +1,1719 @@ +module("luci.passwall.api", package.seeall) +local com = require "luci.passwall.com" +nixio = require "nixio" +fs = require "nixio.fs" +sys = require "luci.sys" +uci = require "luci.model.uci".cursor() +util = require "luci.util" +datatypes = require "luci.cbi.datatypes" +jsonc = require "luci.jsonc" +i18n = require "luci.i18n" + +appname = "passwall" +curl_args = { "-skfL", "--connect-timeout 3", "--retry 3" } +command_timeout = 300 +OPENWRT_ARCH = nil +DISTRIB_ARCH = nil +OPENWRT_BOARD = nil + +CACHE_PATH = "/tmp/etc/" .. appname .. "_tmp" +LOG_FILE = "/tmp/log/" .. appname .. ".log" +TMP_PATH = "/tmp/etc/" .. appname +TMP_IFACE_PATH = TMP_PATH .. "/iface" + +function log(...) + local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + local f, err = io.open(LOG_FILE, "a") + if f and err == nil then + f:write(result .. "\n") + f:close() + end +end + +function is_js_luci() + return sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 +end + +function is_old_uci() + return sys.call("grep -E 'require[ \t]*\"uci\"' /usr/lib/lua/luci/model/uci.lua >/dev/null 2>&1") == 0 +end + +function uci_save(cursor, config, commit, apply) + if is_old_uci() then + cursor:save(config) + if commit then + cursor:commit(config) + if apply then + sys.call("/etc/init.d/" .. config .. " reload > /dev/null 2>&1 &") + end + end + else + commit = true + if commit then + if apply then + cursor:commit(config) + else + sh_uci_commit(config) + end + end + end +end + +function sh_uci_get(config, section, option) + local _, val = exec_call(string.format("uci -q get %s.%s.%s", config, section, option)) + return val +end + +function sh_uci_set(config, section, option, val, commit) + exec_call(string.format("uci -q set %s.%s.%s=\"%s\"", config, section, option, val)) + if commit then sh_uci_commit(config) end +end + +function sh_uci_del(config, section, option, commit) + exec_call(string.format("uci -q delete %s.%s.%s", config, section, option)) + if commit then sh_uci_commit(config) end +end + +function sh_uci_add_list(config, section, option, val, commit) + exec_call(string.format("uci -q del_list %s.%s.%s=\"%s\"", config, section, option, val)) + exec_call(string.format("uci -q add_list %s.%s.%s=\"%s\"", config, section, option, val)) + if commit then sh_uci_commit(config) end +end + +function sh_uci_commit(config) + exec_call(string.format("uci -q commit %s", config)) +end + +function set_cache_var(key, val) + sys.call(string.format('. /usr/share/passwall/utils.sh ; set_cache_var %s "%s"', key, val)) +end + +function get_cache_var(key) + local val = sys.exec(string.format('. /usr/share/passwall/utils.sh ; echo -n $(get_cache_var %s)', key)) + if val == "" then val = nil end + return val +end + +function get_new_port() + local cmd_format = ". /usr/share/passwall/utils.sh ; echo -n $(get_new_port %s tcp,udp)" + return tonumber(sys.exec(string.format(cmd_format, "auto"))) +end + +function exec_call(cmd) + math.randomseed(os.time()) + local tag = "\x01__RC__" .. tostring(math.random(100000, 999999)) .. "\x01" + local f = io.popen('(' .. cmd .. '); printf "\\n' .. tag .. '%d" "$?"') + local out = f:read("*a") or "" + f:close() + local rc = out:match(tag .. "(%d+)%s*$") + if not rc then + return 255, trim(out) + end + out = out:gsub("\n?" .. tag .. "%d+%s*$", "") + return tonumber(rc), trim(out) +end + +function base64Decode(text) + if not text then return '' end + local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+") + local mod4 = #encoded % 4 + encoded = encoded .. string.sub('====', mod4 + 1) + local result = nixio.bin.b64decode(encoded) + if result then + return result:gsub("%z", "") + else + return text + end +end + +function base64Encode(text) + if not text then return nil end + return nixio.bin.b64encode(text) +end + +function UrlEncode(szText) + if type(szText) ~= "string" then return "" end + return szText:gsub("([^%w%-_%.%~])", function(c) + return string.format("%%%02X", string.byte(c)) + end) +end + +function UrlDecode(szText) + if type(szText) ~= "string" then return "" end + return szText and szText:gsub("%+", " "):gsub("%%(%x%x)", function(h) + return string.char(tonumber(h, 16)) + end) or nil +end + +--æå–URL中的域å和端å£(no ip) +function get_domain_port_from_url(url) + local scheme, domain, port = string.match(url, "^(https?)://([%w%.%-]+):?(%d*)") + if not domain then + scheme, domain, port = string.match(url, "^(https?)://(%b[])([^:/]*)/?") + end + if not domain then return nil, nil end + if domain:sub(1, 1) == "[" then domain = domain:sub(2, -2) end + port = port ~= "" and tonumber(port) or (scheme == "https" and 443 or 80) + if datatypes.ipaddr(domain) or datatypes.ip6addr(domain) then return nil, nil end + return domain, port +end + +--è§£æžåŸŸå +function domainToIPv4(domain, dns) + local Dns = dns or "223.5.5.5" + local IPs = luci.sys.exec('nslookup %s %s | awk \'/^Name:/{getline; if ($1 == "Address:") print $2}\'' % { domain, Dns }) + for IP in string.gmatch(IPs, "%S+") do + if datatypes.ipaddr(IP) and not datatypes.ip6addr(IP) then return IP end + end + return nil +end + +function curl_base(url, file, args) + if not args then args = {} end + if file then + args[#args + 1] = "-o " .. file + end + local cmd = string.format('curl %s "%s"', table_join(args), url) + return exec_call(cmd) +end + +function curl_proxy(url, file, args) + --ä½¿ç”¨ä»£ç† + local socks_server = get_cache_var("GLOBAL_TCP_SOCKS_server") + if socks_server and socks_server ~= "" then + if not args then args = {} end + local tmp_args = clone(args) + tmp_args[#tmp_args + 1] = "-x socks5h://" .. socks_server + return curl_base(url, file, tmp_args) + end + return nil, nil +end + +function curl_logic(url, file, args) + local return_code, result = curl_proxy(url, file, args) + if not return_code or return_code ~= 0 then + return_code, result = curl_base(url, file, args) + end + return return_code, result +end + +function curl_direct(url, file, args) + --直连访问 + local chn_list = uci:get(appname, "@global[0]", "chn_list") or "direct" + local Dns = (chn_list == "proxy") and "1.1.1.1" or "223.5.5.5" + if not args then args = {} end + local tmp_args = clone(args) + local domain, port = get_domain_port_from_url(url) + if domain then + local ip = domainToIPv4(domain, Dns) + if ip then + tmp_args[#tmp_args + 1] = "--resolve " .. domain .. ":" .. port .. ":" .. ip + end + end + return curl_base(url, file, tmp_args) +end + +function curl_auto(url, file, args) + local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1" + if localhost_proxy == "1" then + return curl_base(url, file, args) -- 当路由器本机开å¯ä»£ç†æ—¶ï¼Œé‡‡ç”¨passwall规则进行访问 + else + local return_code, result = curl_proxy(url, file, args) + if not return_code or return_code ~= 0 then + return_code, result = curl_direct(url, file, args) + end + return return_code, result + end +end + +function url(...) + local url = string.format("admin/services/%s", appname) + local args = { ... } + for i, v in pairs(args) do + if v ~= "" then + url = url .. "/" .. v + end + end + return require "luci.dispatcher".build_url(url) +end + +function trim(s) + if type(s) ~= "string" then return "" end + local i, j = 1, #s + while i <= j and s:byte(i) <= 32 do i = i + 1 end + while j >= i and s:byte(j) <= 32 do j = j - 1 end + if i > j then return "" end + return s:sub(i, j) +end + +-- 分割字符串 +function split(full, sep) + if full then + full = full:gsub("%z", "") -- è¿™é‡Œä¸æ˜¯å¾ˆæ¸…楚 有时候结尾带个\0 + local off, result = 1, {} + while true do + local nStart, nEnd = full:find(sep, off) + if not nEnd then + local res = string.sub(full, off, string.len(full)) + if #res > 0 then -- 过滤掉 \0 + table.insert(result, res) + end + break + else + table.insert(result, string.sub(full, off, nStart - 1)) + off = nEnd + 1 + end + end + return result + end + return {} +end + +function is_exist(table, value) + for index, k in ipairs(table) do + if k == value then + return true + end + end + return false +end + +function repeat_exist(table, value) + local count = 0 + for index, k in ipairs(table) do + if k:find("-") and k == value then + count = count + 1 + end + end + if count > 1 then + return true + end + return false +end + +function remove(...) + for index, value in ipairs({...}) do + if value and #value > 0 and value ~= "/" then + sys.call(string.format("rm -rf %s", value)) + end + end +end + +function is_install(package) + if package and #package > 0 then + local file_path = "/usr/lib/opkg/info" + local file_ext = ".control" + local has = sys.call("[ -d " .. file_path .. " ]") + if has ~= 0 then + file_path = "/lib/apk/packages" + file_ext = ".list" + end + return sys.call(string.format('[ -s "%s/%s%s" ]', file_path, package, file_ext)) == 0 + end + return false +end + +function get_args(arg) + local var = {} + for i, arg_k in pairs(arg) do + if i > 0 then + local v = arg[i + 1] + if v then + if repeat_exist(arg, v) == false then + var[arg_k] = v + end + end + end + end + return var +end + +function get_function_args(arg) + local var = nil + if arg and #arg > 1 then + local param = {} + for i = 2, #arg do + param[#param + 1] = arg[i] + end + var = get_args(param) + end + return var +end + +function strToTable(str) + if str == nil or type(str) ~= "string" then + return {} + end + + return loadstring("return " .. str)() +end + +function is_normal_node(e) + if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then + return false + end + return true +end + +function is_special_node(e) + return is_normal_node(e) == false +end + +function is_ip(val) + val = trim(val):lower() + local str = val:match("%[(.-)%]") or val + return datatypes.ipaddr(str) or false +end + +function is_ipv6(val) + val = trim(val):lower() + local str = val:match("%[(.-)%]") or val + return datatypes.ip6addr(str) or false +end + +function is_local_ip(ip) + ip = trim(ip):lower() + ip = ip:gsub("^[%w%d]+://", "") -- 去掉å议头 + :gsub("/.*$", "") -- 去掉路径 + :gsub("^%[", ""):gsub("%]$", "") -- 去掉IPv6æ–¹æ‹¬å· + :gsub(":%d+$", "") -- åŽ»æŽ‰ç«¯å£ + return ip:match("^127%.") or ip:match("^10%.") or + ip:match("^172%.1[6-9]%.") or ip:match("^172%.2[0-9]%.") or + ip:match("^172%.3[0-1]%.") or ip:match("^192%.168%.") or + ip == "::1" or ip:match("^f[cd]") or ip:match("^fe[89ab]") +end + +function is_ipv6addrport(val) + local address, port = val:match("%[(.-)%]:([0-9]+)$") + if address and datatypes.ip6addr(address) and datatypes.port(port) then + return true + end + return false +end + +function get_ipv6_only(val) + local result = "" + local inner = val:match("%[(.-)%]") or val + if datatypes.ip6addr(inner) then + result = inner + end + return result +end + +function get_ipv6_full(val) + local result = "" + if is_ipv6(val) then + result = val + if not val:match("%[.-%]") then + result = "[" .. result .. "]" + end + end + return result +end + +function get_ip_type(val) + if is_ipv6(val) then + return "6" + elseif datatypes.ip4addr(val) then + return "4" + end + return "" +end + +function is_mac(val) + return datatypes.macaddr(val) +end + +function ip_or_mac(val) + if val then + if get_ip_type(val) == "4" then + return "ip" + end + if is_mac(val) then + return "mac" + end + end + return "" +end + +function iprange(val) + if val then + local ipStart, ipEnd = val:match("^([^/]+)-([^/]+)$") + if (ipStart and datatypes.ip4addr(ipStart)) and (ipEnd and datatypes.ip4addr(ipEnd)) then + return true + end + end + return false +end + +function get_domain_from_url(url) + local domain = string.match(url, "//([^/]+)") + if domain then + return domain + end + return url +end + +function get_valid_nodes() + local show_node_info = uci_get_type("global_other", "show_node_info", "0") + local nodes = {} + local default_nodes = {} + local other_nodes = {} + uci:foreach(appname, "nodes", function(e) + e.id = e[".name"] + if e.type and e.remarks then + local type_name = e.type + if e.type == "sing-box" then type_name = "Sing-Box" end + if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then + e["remark"] = trim("%s:[%s]" % {type_name .. " " .. i18n.translatef(e.protocol), e.remarks}) + e["node_type"] = "special" + if not e.group or e.group == "" then + default_nodes[#default_nodes + 1] = e + else + other_nodes[#other_nodes + 1] = e + end + end + local port = e.port or e.hysteria_hop or e.hysteria2_hop + local is_realm = (e.type == "Hysteria2" or e.protocol == 'hysteria2') and e.hysteria2_realms or nil + if (port and e.address) or is_realm then + local address = e.address + if is_ip(address) or datatypes.hostname(address) or is_realm then + if (e.type == "sing-box" or e.type == "Xray") and e.protocol then + local protocol = e.protocol + if protocol == "vmess" then + protocol = "VMess" + elseif protocol == "vless" then + protocol = "VLESS" + elseif protocol == "shadowsocks" then + protocol = "SS" + elseif protocol == "shadowsocksr" then + protocol = "SSR" + elseif protocol == "wireguard" then + protocol = "WG" + elseif protocol == "hysteria" then + protocol = "HY" + elseif protocol == "hysteria2" then + protocol = "HY2" + elseif protocol == "anytls" then + protocol = "AnyTLS" + elseif protocol == "ssh" then + protocol = "SSH" + else + protocol = protocol:gsub("^%l",string.upper) + end + type_name = type_name .. " " .. protocol + end + if is_ipv6(address) then address = get_ipv6_full(address) end + type_name = is_realm and type_name .. " Realm" or type_name + e["remark"] = trim("%s:[%s]" % {type_name, e.remarks}) + if show_node_info == "1" then + port = (port or ""):gsub(":", "-") + if not is_realm then + e["remark"] = trim("%s:[%s] %s:%s" % {type_name, e.remarks, address, port}) + end + end + e.node_type = "normal" + if not e.group or e.group == "" then + default_nodes[#default_nodes + 1] = e + else + other_nodes[#other_nodes + 1] = e + end + end + end + end + end) + for i = 1, #default_nodes do nodes[#nodes + 1] = default_nodes[i] end + for i = 1, #other_nodes do nodes[#nodes + 1] = other_nodes[i] end + return nodes +end + +function get_node_list() + local node_list = { + socks_list = {}, + normal_list = {}, + } + uci:foreach(appname, "socks", function(s) + if s.enabled == "1" and s.node then + node_list.socks_list[#node_list.socks_list + 1] = { + id = "Socks_" .. s[".name"], + remark = i18n.translate("Socks Config") .. " [" .. s.port .. i18n.translate("Port") .. "]", + group = "Socks" + } + end + end) + for k, e in ipairs(get_valid_nodes()) do + if e.node_type == "normal" then + node_list.normal_list[#node_list.normal_list + 1] = { + id = e[".name"], + remark = e["remark"], + type = e["type"], + chain_proxy = e["chain_proxy"], + group = e["group"] + } + end + if e.protocol and e.protocol:find("^_") then + local proto = e.protocol:sub(2) + if not node_list[proto .. "_list"] then + node_list[proto .. "_list"] = {} + end + node_list[proto .. "_list"][#node_list[proto .. "_list"] + 1] = { + id = e[".name"], + remark = e["remark"], + group = e["group"], + o = e, + } + end + end + return node_list +end + +function get_node_remarks(n) + local remarks = "" + if n then + local type_name = n.type + if n.type == "sing-box" then type_name = "Sing-Box" end + if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface" or n.protocol == "_urltest") then + remarks = trim("%s:[%s]" % {type_name .. " " .. i18n.translatef(n.protocol), n.remarks}) + else + if (n.type == "sing-box" or n.type == "Xray") and n.protocol then + local protocol = n.protocol + if protocol == "vmess" then + protocol = "VMess" + elseif protocol == "vless" then + protocol = "VLESS" + elseif protocol == "shadowsocks" then + protocol = "SS" + elseif protocol == "shadowsocksr" then + protocol = "SSR" + elseif protocol == "wireguard" then + protocol = "WG" + elseif protocol == "hysteria" then + protocol = "HY" + elseif protocol == "hysteria2" then + protocol = "HY2" + elseif protocol == "anytls" then + protocol = "AnyTLS" + elseif protocol == "ssh" then + protocol = "SSH" + else + protocol = protocol:gsub("^%l",string.upper) + end + type_name = type_name .. " " .. protocol + end + if (n.type == "Hysteria2" or n.protocol == 'hysteria2') and n.hysteria2_realms then + type_name = type_name .. " Realm" + end + remarks = trim("%s:[%s]" % {type_name, n.remarks}) + end + end + return remarks +end + +function get_full_node_remarks(n) + local remarks = get_node_remarks(n) + if #remarks > 0 then + local port = n.port or n.hysteria_hop or n.hysteria2_hop + if n.address and port then + port = port:gsub(":", "-") + remarks = remarks .. " " .. n.address .. ":" .. port + end + end + return remarks +end + +function gen_uuid(format) + local uuid = sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)") + if format == nil then + uuid = string.gsub(uuid, "-", "") + end + return uuid +end + +function gen_short_uuid() + return sys.exec("echo -n $(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8)") +end + +function uci_get_type(type, config, default) + local value = uci:get_first(appname, type, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. ".@" .. type .."[0]." .. config .. ")") + if (value == nil or value == "") and (default and default ~= "") then + value = default + end + return value +end + +function uci_get_type_id(id, config, default) + local value = uci:get(appname, id, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. "." .. id .. "." .. config .. ")") + if (value == nil or value == "") and (default and default ~= "") then + value = default + end + return value +end + +local function chmod_755(file) + if file and file ~= "" then + if not fs.access(file, "rwx", "rx", "rx") then + fs.chmod(file, 755) + end + end +end + +function get_customed_path(e) + return uci_get_type("global_app", e .. "_file") +end + +function finded_com(e) + local bin = get_app_path(e) + if not bin then return end + local s = luci.sys.exec('echo -n $(type -t -p "%s" | head -n1)' % { bin }) + if s == "" then + s = nil + end + return s +end + +function finded(e) + return luci.sys.exec('echo -n $(type -t -p "/bin/%s" -p "/usr/bin/%s" "%s" | head -n1)' % {e, e, e}) +end + +function is_finded(e) + return finded(e) ~= "" and true or false +end + +function clone(org) + local function copy(org, res) + for k,v in pairs(org) do + if type(v) ~= "table" then + res[k] = v; + else + res[k] = {}; + copy(v, res[k]) + end + end + end + + local res = {} + copy(org, res) + return res +end + +function get_bin_version_cache(file, cmd) + sys.call("mkdir -p /tmp/etc/passwall_tmp") + if fs.access(file) then + chmod_755(file) + local md5 = sys.exec("echo -n $(md5sum " .. file .. " | awk '{print $1}')") + if fs.access("/tmp/etc/passwall_tmp/" .. md5) then + return sys.exec("echo -n $(cat /tmp/etc/passwall_tmp/%s)" % md5) + else + local version = sys.exec(string.format("echo -n $(%s %s)", file, cmd)) + if version and version ~= "" then + sys.call("echo '" .. version .. "' > " .. "/tmp/etc/passwall_tmp/" .. md5) + return version + end + end + end + return "" +end + +function get_app_path(app_name) + if com[app_name] then + local def_path = com[app_name].default_path + local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file") + path = path and (#path>0 and path or def_path) or def_path + return path + end +end + +function get_app_version(app_name, file) + if file == nil then file = get_app_path(app_name) end + return get_bin_version_cache(file, com[app_name].cmd_version) +end + +local function is_file(path) + if path and #path > 1 then + if sys.exec('[ -f "%s" ] && echo -n 1' % path) == "1" then + return true + end + end + return nil +end + +local function is_dir(path) + if path and #path > 1 then + if sys.exec('[ -d "%s" ] && echo -n 1' % path) == "1" then + return true + end + end + return nil +end + +local function get_final_dir(path) + if is_dir(path) then + return path + else + return get_final_dir(fs.dirname(path)) + end +end + +local function get_free_space(dir) + if dir == nil then dir = "/" end + if sys.call("df -k " .. dir .. " >/dev/null 2>&1") == 0 then + return tonumber(sys.exec("echo -n $(df -k " .. dir .. " | awk 'NR>1' | awk '{print $4}')")) + end + return 0 +end + +local function get_file_space(file) + if file == nil then return 0 end + if fs.access(file) then + return tonumber(sys.exec("echo -n $(du -k " .. file .. " | awk '{print $1}')")) + end + return 0 +end + +function _unpack(t, i) + i = i or 1 + if t[i] ~= nil then return t[i], _unpack(t, i + 1) end +end + +function table_join(t, s) + if not s then + s = " " + end + local str = "" + for index, value in ipairs(t) do + str = str .. t[index] .. (index == #t and "" or s) + end + return str +end + +local function exec(cmd, args, writer, timeout) + local os = require "os" + local nixio = require "nixio" + + local fdi, fdo = nixio.pipe() + local pid = nixio.fork() + + if pid > 0 then + fdo:close() + + if writer or timeout then + local starttime = os.time() + while true do + if timeout and os.difftime(os.time(), starttime) >= timeout then + nixio.kill(pid, nixio.const.SIGTERM) + return 1 + end + + if writer then + local buffer = fdi:read(2048) + if buffer and #buffer > 0 then + writer(buffer) + end + end + + local wpid, stat, code = nixio.waitpid(pid, "nohang") + + if wpid and stat == "exited" then return code end + + if not writer and timeout then nixio.nanosleep(1) end + end + else + local wpid, stat, code = nixio.waitpid(pid) + return wpid and stat == "exited" and code + end + elseif pid == 0 then + nixio.dup(fdo, nixio.stdout) + fdi:close() + fdo:close() + nixio.exece(cmd, args, nil) + nixio.stdout:close() + os.exit(1) + end +end + +function compare_versions(ver1, comp, ver2) + local table = table + + if not ver1 then ver1 = "" end + if not ver2 then ver2 = "" end + + local av1 = util.split(ver1, "[%.%-]", nil, true) + local av2 = util.split(ver2, "[%.%-]", nil, true) + + local max = table.getn(av1) + local n2 = table.getn(av2) + if (max < n2) then max = n2 end + + for i = 1, max, 1 do + local s1 = tonumber(av1[i] or 0) or 0 + local s2 = tonumber(av2[i] or 0) or 0 + + if comp == "~=" and (s1 ~= s2) then return true end + if (comp == "<" or comp == "<=") and (s1 < s2) then return true end + if (comp == ">" or comp == ">=") and (s1 > s2) then return true end + if (s1 ~= s2) then return false end + end + + return not (comp == "<" or comp == ">") +end + +local function auto_get_arch() + local arch = nixio.uname().machine or "" + if not OPENWRT_ARCH and fs.access("/usr/lib/os-release") then + OPENWRT_ARCH = sys.exec("echo -n $(grep 'OPENWRT_ARCH' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')") + OPENWRT_BOARD = sys.exec("echo -n $(grep 'OPENWRT_BOARD' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')") + if OPENWRT_ARCH == "" then OPENWRT_ARCH = nil end + if OPENWRT_BOARD == "" then OPENWRT_BOARD = nil end + end + if not DISTRIB_ARCH and fs.access("/etc/openwrt_release") then + DISTRIB_ARCH = sys.exec("echo -n $(grep 'DISTRIB_ARCH' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}')") + if DISTRIB_ARCH == "" then DISTRIB_ARCH = nil end + end + + if arch:match("^i[%d]86$") then + arch = "x86" + elseif arch:match("armv5") then -- armv5l + arch = "armv5" + elseif arch:match("armv6") then + arch = "armv6" + elseif arch:match("armv7") then -- armv7l + arch = "armv7" + end + + if OPENWRT_ARCH or DISTRIB_ARCH then + if arch == "mips" then + if OPENWRT_ARCH and OPENWRT_ARCH:match("mipsel") == "mipsel" + or DISTRIB_ARCH and DISTRIB_ARCH:match("mipsel") == "mipsel" then + arch = "mipsel" + end + elseif arch == "armv7" then + if OPENWRT_ARCH and not OPENWRT_ARCH:match("vfp") and not OPENWRT_ARCH:match("neon") + or DISTRIB_ARCH and not DISTRIB_ARCH:match("vfp") and not DISTRIB_ARCH:match("neon") then + arch = "armv5" + end + end + end + + if arch == "aarch64" and OPENWRT_BOARD and OPENWRT_BOARD:match("rockchip") ~= nil then + arch = "rockchip" + end + + return trim(arch) +end + +function parseURL(url_str) + local res = {} + + -- 1. Get Scheme (http://) + local rest = url_str + local scheme, s_rest = url_str:match("^([%w%.%-%+]+)://(.+)$") + if scheme then + res.protocol = scheme + rest = s_rest + end + + -- 2. Get Authority (user:pass@host:port) and Path + local authority, path = rest:match("^([^/]+)(.*)$") + if path and path ~= "" then + res.pathname = path:match("^([^?#]*)") + end + + -- 3. Process Auth info (user:pass@) + -- Use [^@]+ to match the content before the leftmost @. + local user_info, host_port = authority:match("^([^@]+)@(.+)$") + if user_info then + local u, p = user_info:match("^([^:]+):?(.*)$") + res.username = u or "" + res.password = p or "" + else + host_port = authority + end + + -- 4. Handles Host and Port (IPv6 compatible) + -- First look for square brackets [], if not found, then look for regular colons. + local ipv6_host, ipv6_port = host_port:match("^%[(.+)%]:(%d+)$") + if ipv6_host then + res.hostname = ipv6_host + res.port = tonumber(ipv6_port) + else + -- Check if it's an IPv6 address with parentheses but no port number: [2001:db8::1] + local pure_ipv6 = host_port:match("^%[(.+)%]$") + if pure_ipv6 then + res.hostname = pure_ipv6 + else + -- IPv4 or hostname match + local h, p = host_port:match("^([^:]+):(%d+)$") + if h and p then + res.hostname = h + res.port = tonumber(p) + else + res.hostname = host_port + end + end + end + + res.host = host_port + return res +end + +function parseDoH(doh_str) + doh_str = trim(doh_str) + if doh_str == "" then return nil end + + local url_part, ip_part + if doh_str:find(",", 1, true) then + url_part, ip_part = doh_str:match("^([^,]+),(.+)$") + else + url_part = doh_str + end + + local res = parseURL(url_part) + if not res then return nil end + + res.url = url_part + if ip_part and ip_part ~= "" and is_ip(ip_part) then + res.hostip = ip_part + end + + return res +end + +local default_file_tree = { + x86_64 = "amd64", + x86 = "386", + aarch64 = "arm64", + rockchip = "arm64", + mips = "mips", + mips64 = "mips64", + mipsel = "mipsel", + mips64el = "mips64el", + armv5 = "arm.*5", + armv6 = "arm.*6[^4]*", + armv7 = "arm.*7", + armv8 = "arm64", + riscv64 = "riscv64" +} + +local function get_api_json(url) + local jsonc = require "luci.jsonc" + local return_code, content = curl_auto(url, nil, curl_args) + if return_code ~= 0 or content == "" then return {} end + return jsonc.parse(content) or {} +end + +local function check_path(app_name) + local path = get_app_path(app_name) or "" + if path == "" then + return { + code = 1, + error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", app_name) + } + end + return { + code = 0, + app_path = path + } +end + +function to_check(arch, app_name) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + if not arch or arch == "" then arch = auto_get_arch() end + + local file_tree = com[app_name].file_tree[arch] or default_file_tree[arch] or "" + + if file_tree == "" then + return { + code = 1, + error = i18n.translate("Can't determine ARCH, or ARCH not supported.") + } + end + + local local_version = get_app_version(app_name) + local match_file_name = string.format(com[app_name].match_fmt_str, file_tree) + local json = get_api_json(com[app_name]:get_url()) + + if #json > 0 then + json = json[1] + end + + if json.tag_name == nil then + return { + code = 1, + error = i18n.translate("Get remote version info failed.") + } + end + + local remote_version = json.tag_name + if com[app_name].remote_version_str_replace then + remote_version = remote_version:gsub(com[app_name].remote_version_str_replace, "") + end + local has_update = compare_versions(local_version:match("[^v]+"), "<", remote_version:match("[^v]+")) +--[[ + if not has_update then + return { + code = 0, + local_version = local_version, + remote_version = remote_version + } + end +]]-- + local asset = {} + for _, v in ipairs(json.assets) do + if v.name and v.name:match(match_file_name) then + asset = v + break + end + end + if not asset.browser_download_url then + return { + code = 1, + local_version = local_version, + remote_version = remote_version, + html_url = json.html_url, + data = asset, + error = i18n.translate("New version found, but failed to get new version download url.") + } + end + + return { + code = 0, + has_update = has_update, + local_version = local_version, + remote_version = remote_version, + html_url = json.html_url, + data = asset + } +end + +function to_download(app_name, url, size) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + if not url or url == "" then + return {code = 1, error = i18n.translate("Download url is required.")} + end + + sys.call("/bin/rm -f /tmp/".. app_name .."_download.*") + + local tmp_file = trim(util.exec("mktemp -u -t ".. app_name .."_download.XXXXXX")) + + if size then + local kb1 = get_free_space("/tmp") + if tonumber(size) > tonumber(kb1) then + return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")} + end + end + + local _curl_args = clone(curl_args) + table.insert(_curl_args, "--speed-limit 51200 --speed-time 15 --max-time 300") + + local return_code, result = curl_auto(url, tmp_file, _curl_args) + result = return_code == 0 + + if not result then + exec("/bin/rm", {"-f", tmp_file}) + return { + code = 1, + error = i18n.translatef("File download failed or timed out: %s", url) + } + end + + return {code = 0, file = tmp_file, zip = com[app_name].zipped } +end + +function to_extract(app_name, file, subfix) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + if not file or file == "" or not fs.access(file) then + return {code = 1, error = i18n.translate("File path required.")} + end + + local tools_name + if com[app_name].zipped then + if not com[app_name].zipped_suffix or com[app_name].zipped_suffix == "zip" then + tools_name = "unzip" + end + if com[app_name].zipped_suffix and com[app_name].zipped_suffix == "tar.gz" then + tools_name = "tar" + end + if tools_name then + if sys.exec("echo -n $(command -v %s)" % { tools_name }) == "" then + exec("/bin/rm", {"-f", file}) + return { + code = 1, + error = i18n.translate("Not installed %s, Can't unzip!" % { tools_name }) + } + end + end + end + + sys.call("/bin/rm -rf /tmp/".. app_name .."_extract.*") + + local new_file_size = get_file_space(file) + local tmp_free_size = get_free_space("/tmp") + if tmp_free_size <= 0 or tmp_free_size <= new_file_size then + return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")} + end + + local tmp_dir = trim(util.exec("mktemp -d -t ".. app_name .."_extract.XXXXXX")) + + local output = {} + + if tools_name then + if tools_name == "unzip" then + local bin = sys.exec("echo -n $(command -v unzip)") + exec(bin, {"-o", file, app_name, "-d", tmp_dir}, function(chunk) output[#output + 1] = chunk end) + elseif tools_name == "tar" then + local bin = sys.exec("echo -n $(command -v tar)") + if com[app_name].zipped_suffix == "tar.gz" then + exec(bin, {"-zxf", file, "-C", tmp_dir}, function(chunk) output[#output + 1] = chunk end) + sys.call("/bin/mv -f " .. tmp_dir .. "/*/" .. com[app_name].name:lower() .. " " .. tmp_dir) + end + end + end + + local files = util.split(table.concat(output)) + + exec("/bin/rm", {"-f", file}) + + return {code = 0, file = tmp_dir} +end + +function to_move(app_name,file) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + local app_path = result.app_path + local bin_path = file + local cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_download.*" + if fs.stat(file, "type") == "dir" then + bin_path = file .. "/" .. com[app_name].name:lower() + cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_extract.*" + end + + if not file or file == "" then + sys.call(cmd_rm_tmp) + return {code = 1, error = i18n.translate("Client file is required.")} + end + + local new_version = get_app_version(app_name, bin_path) + if new_version == "" then + sys.call(cmd_rm_tmp) + return { + code = 1, + error = i18n.translate("The client file is not suitable for current device.") .. app_name .. "__" .. bin_path + } + end + + local flag = sys.call('busybox pgrep -af "passwall/.*'.. app_name ..'" >/dev/null') + if flag == 0 then + sys.call("/etc/init.d/passwall stop") + end + + local old_app_size = 0 + if fs.access(app_path) then + old_app_size = get_file_space(app_path) + end + local new_app_size = get_file_space(bin_path) + local final_dir = get_final_dir(app_path) + local final_dir_free_size = get_free_space(final_dir) + if final_dir_free_size > 0 then + final_dir_free_size = final_dir_free_size + old_app_size + if new_app_size > final_dir_free_size then + sys.call(cmd_rm_tmp) + return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)} + end + end + + result = exec("/bin/mv", { "-f", bin_path, app_path }, nil, command_timeout) == 0 + + sys.call(cmd_rm_tmp) + if flag == 0 then + sys.call("/etc/init.d/passwall restart >/dev/null 2>&1 &") + end + + if not result or not fs.access(app_path) then + return { + code = 1, + error = i18n.translatef("Can't move new file to path: %s", app_path) + } + end + + return {code = 0} +end + +function get_version() + local version = sys.exec("opkg list-installed luci-app-passwall 2>/dev/null | awk '{print $3}'") + if not version or #version == 0 then + version = sys.exec("apk list luci-app-passwall 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-") + end + return (version or ""):gsub("\n", ""):match("^([^-]+)") +end + +function to_check_self() + local url = "https://raw.githubusercontent.com/Openwrt-Passwall/openwrt-passwall/main/luci-app-passwall/Makefile" + local tmp_file = "/tmp/passwall_makefile" + local return_code, result = curl_auto(url, tmp_file, curl_args) + result = return_code == 0 + if not result then + exec("/bin/rm", {"-f", tmp_file}) + return { + code = 1, + error = i18n.translatef("Failed") + } + end + local local_version = get_version() + local remote_version = sys.exec("echo -n $(grep '^PKG_VERSION' /tmp/passwall_makefile | head -n 1 | awk -F '=' '{print $2}')") + exec("/bin/rm", {"-f", tmp_file}) + + local has_update = compare_versions(local_version, "<", remote_version) + if not has_update then + return { + code = 0, + local_version = local_version, + remote_version = remote_version + } + end + return { + code = 1, + has_update = true, + local_version = local_version, + remote_version = remote_version, + error = i18n.translatef("The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install.", remote_version) + } +end + +function luci_types(id, m, s, type_name, option_prefix) + local fv_type + local field_type = s.fields["type"] + if field_type then + fv_type = field_type:formvalue(id) + end + local rewrite_option_table = {} + for key, value in pairs(s.fields) do + if key:find(option_prefix) == 1 then + if not s.fields[key].not_rewrite then + if s.fields[key].rewrite_option then + if not rewrite_option_table[s.fields[key].rewrite_option] then + rewrite_option_table[s.fields[key].rewrite_option] = 1 + else + rewrite_option_table[s.fields[key].rewrite_option] = rewrite_option_table[s.fields[key].rewrite_option] + 1 + end + end + + s.fields[key].cfgvalue = function(self, section) + -- 添加自定义 custom_cfgvalue 属性,如果有自定义的 custom_cfgvalue 函数,则使用自定义的 cfgvalue 逻辑 + if self.custom_cfgvalue then + return self:custom_cfgvalue(section) + else + if self.rewrite_option then + return m:get(section, self.rewrite_option) + else + if self.option:find(option_prefix) == 1 then + return m:get(section, self.option:sub(1 + #option_prefix)) + end + end + end + end + s.fields[key].write = function(self, section, value) + if s.fields["type"]:formvalue(id) == type_name then + -- 添加自定义 custom_write 属性,如果有自定义的 custom_write 函数,则使用自定义的 write 逻辑 + if self.custom_write then + self:custom_write(section, value) + else + if self.rewrite_option then + m:set(section, self.rewrite_option, value) + else + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end + end + end + end + s.fields[key].remove = function(self, section) + if s.fields["type"]:formvalue(id) == type_name then + -- 添加自定义 custom_remove 属性,如果有自定义的 custom_remove 函数,则使用自定义的 remove 逻辑 + if self.custom_remove then + self:custom_remove(section) + else + if self.rewrite_option and rewrite_option_table[self.rewrite_option] == 1 then + m:del(section, self.rewrite_option) + else + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end + end + end + end + end + end + + local deps = s.fields[key].deps + if #deps > 0 then + for index, value in ipairs(deps) do + deps[index]["type"] = type_name + end + else + s.fields[key]:depends({ type = type_name }) + end + + if fv_type and fv_type ~= type_name then + s.fields[key].rmempty = true + end + end + end +end + +function get_std_domain(domain) + domain = trim(domain) + if domain == "" then return "" end + -- å« # → "" + for i = 1, #domain do + if domain:byte(i) == 35 then return "" end -- '#' + end + local len = #domain + local si, ei = 1, len + -- 去å‰ç¼€ '.' + while si <= len and domain:byte(si) == 46 do si = si + 1 end + -- 去åŽç¼€ '.' + while ei >= si and domain:byte(ei) == 46 do ei = ei - 1 end + if si > ei then return "" end + domain = domain:sub(si, ei) + len = #domain + -- æ˜¯å¦æœ‰ '*' + local star = false + for i = 1, len do + if domain:byte(i) == 42 then star = true break end + end + if not star then return domain end + -- 切割 label + local parts, pstart = {}, 1 + for i = 1, len + 1 do + local b = (i <= len) and domain:byte(i) or 46 -- '.' ä½œä¸ºç»“æŸ + if b == 46 then + parts[#parts + 1] = domain:sub(pstart, i - 1) + pstart = i + 1 + end + end + -- 从å³å‘å·¦æ‰¾å« '*' ,å¹¶åˆ é™¤åŒ…å« '*' 的部分åŠå…¶å·¦è¾¹éƒ¨åˆ† + for i = #parts, 1, -1 do + local s = parts[i] + local has = false + for j = 1, #s do + if s:byte(j) == 42 then has = true break end + end + if has then + if i == #parts then return "" end + local out = parts[i + 1] + for k = i + 2, #parts do + out = out .. "." .. parts[k] + end + return out + end + end + return domain +end + +function format_go_time(input) + input = input and trim(input) + local N = 0 + if input and input:match("^%d+$") then + N = tonumber(input) + elseif input and input ~= "" then + for value, unit in input:gmatch("(%d+)%s*([hms])") do + value = tonumber(value) + if unit == "h" then + N = N + value * 3600 + elseif unit == "m" then + N = N + value * 60 + elseif unit == "s" then + N = N + value + end + end + end + if N <= 0 then + return "0s" + end + local result = "" + local h = math.floor(N / 3600) + local m = math.floor(N % 3600 / 60) + local s = N % 60 + if h > 0 then result = result .. h .. "h" end + if m > 0 then result = result .. m .. "m" end + if s > 0 or result == "" then result = result .. s .. "s" end + return result +end + +function set_apply_on_parse(map) + if not map then return end + if is_js_luci() then + apply_redirect(map) + local old = map.on_after_save + map.on_after_save = function(self) + if old then old(self) end + map:set("@global[0]", "timestamp", os.time()) + end + -- ä¼˜åŒ–é¡µé¢ + local cbi = require "luci.cbi" + map:append(cbi.Template(appname .. "/cbi/optimize_cbi_ui")) + end +end + +function apply_redirect(m) + local tmp_uci_file = "/etc/config/" .. appname .. "_redirect" + if m.redirect and m.redirect ~= "" then + if fs.access(tmp_uci_file) then + local redirect + for line in io.lines(tmp_uci_file) do + redirect = line:match("option%s+url%s+['\"]([^'\"]+)['\"]") + if redirect and redirect ~= "" then break end + end + if redirect and redirect ~= "" then + sys.call("/bin/rm -f " .. tmp_uci_file) + luci.http.redirect(redirect) + end + else + fs.writefile(tmp_uci_file, "config redirect\n") + end + m.on_after_save = function(self) + local redirect = self.redirect + if redirect and redirect ~= "" then + uci:set(appname .. "_redirect", "@redirect[0]", "url", redirect) + end + end + else + sys.call("/bin/rm -f " .. tmp_uci_file) + end +end + +function match_node_rule(name, rule) + if not name then return false end + if not rule or rule == "" then return true end + -- split rule by && + local function split_and(expr) + local t = {} + for part in expr:gmatch("[^&]+") do + part = part:gsub("^%s+", ""):gsub("%s+$", "") + if part ~= "" then + table.insert(t, part) + end + end + return t + end + -- match single condition + local function match_cond(str, cond) + if cond == "" then + return true + end + -- exclude: !xxx + if cond:sub(1, 1) == "!" then + local k = cond:sub(2) + if k == "" then return true end + return not str:find(k, 1, true) + end + -- prefix: ^xxx + if cond:sub(1, 1) == "^" then + local k = cond:sub(2) + return str:sub(1, #k) == k + end + -- suffix: xxx$ + if cond:sub(-1) == "$" then + local k = cond:sub(1, -2) + return str:sub(-#k) == k + end + -- contains + return str:find(cond, 1, true) ~= nil + end + -- AND logic + for _, cond in ipairs(split_and(rule)) do + if not match_cond(name, cond) then + return false + end + end + return true +end + +function get_core(field, candidates) + local v = uci:get(appname, "@global_subscribe[0]", field) + if v and v ~= "" then + for _, c in ipairs(candidates) do + if c[2] == v and c[1] then + return v + end + end + end + for _, c in ipairs(candidates) do + if c[1] then return c[2] end + end + return nil +end + +function cleanEmptyTables(t) + if type(t) ~= "table" then return nil end + for k, v in pairs(t) do + if type(v) == "table" then + t[k] = cleanEmptyTables(v) + end + end + return next(t) and t or nil +end + +function fetch_cert_sha256(host, port, timeout) + if not host or not datatypes.hostname(host) then return "" end + port = tonumber(port) or 443 + timeout = tonumber(timeout) or 5 + local xray = finded_com("xray") + local cmd + if xray then + cmd = string.format( + "timeout %d %q tls ping %s:%d 2>/dev/null " .. + "| awk 'tolower($0) ~ /without sni/ {f=1} tolower($0) ~ /with sni/ {f=0} " .. + "f && tolower($0) ~ /cert.*leaf.*sha256/ {sub(/.*:/,\"\"); gsub(/[[:space:]]/,\"\"); print; exit}'", + timeout, xray, host, port + ) + else + cmd = string.format( + "timeout %d openssl s_client -connect %s:%d -servername %s -showcerts /dev/null " .. + "| awk 'BEGIN{c=0}/BEGIN CERT/{c++} c==1{print} /END CERT/{if(c==1)exit}' " .. + "| openssl x509 -outform der 2>/dev/null " .. + "| sha256sum 2>/dev/null", + timeout, host, port, host + ) + end + local out = trim(sys.exec(cmd)) + local fp = out:match("^([0-9a-fA-F]+)") + if not fp then return "" end + return fp:upper() +end + +function vps_domain_exclude(domain) + if trim(domain) == "" then return true end + local map = { + ["engage.cloudflareclient.com"] = 1, + ["google.com"] = 1, ["www.google.com"] = 1, + ["youtube.com"] = 1, ["www.youtube.com"] = 1, + ["github.com"] = 1, ["telegram.org"] = 1, + ["cloudflare.com"] = 1, ["www.cloudflare.com"] = 1, + ["bing.com"] = 1, ["www.bing.com"] = 1, ["x.com"] = 1 + } + if map[domain] then return true end + return false +end + +function parse_realm_uri(uri) + if type(uri) ~= "string" then return nil end + -- realm://token@server/realm_id?query + local token, server_url, realm_id, query = trim(uri):match("^realm://([^@]+)@([^/]+)/([^?]*)%??(.*)$") + if not token or not server_url or not realm_id then return nil end + realm_id = realm_id:gsub("/+$", "") + local realm = { + token = token, + server_url = server_url, + realm_id = realm_id + } + -- è§£æž query 中的 stun= + if query and query ~= "" then + local stun_servers = {} + for key, value in query:gmatch("([^&=?]+)=([^&]+)") do + if key == "stun" and value ~= "" then + stun_servers[#stun_servers + 1] = value + end + end + if #stun_servers > 0 then + realm.stun_servers = stun_servers + end + end + return realm +end + +function get_network_devices() + local _sysnet = "/sys/class/net/" + -- Map UCI interface names to their device names and vice versa + local _iface_to_dev = {} + local _dev_to_ifaces = {} + local _iface_proto = {} + uci:foreach("network", "interface", function(sec) + local name = sec[".name"] + if name ~= "loopback" then + _iface_proto[name] = sec.proto + if sec.device then + _iface_to_dev[name] = sec.device + _dev_to_ifaces[sec.device] = _dev_to_ifaces[sec.device] or {} + table.insert(_dev_to_ifaces[sec.device], name) + end + end + end) + -- Classify device type using sysfs attributes + local function classify_sysfs(dev) + if fs.stat(_sysnet .. dev .. "/bridge", "type") == "dir" then + return i18n.translate("Bridge") + elseif fs.stat(_sysnet .. dev .. "/wireless", "type") == "dir" then + return i18n.translate("Wireless Adapter") + elseif dev:match("^tun") or dev:match("^tap") or dev:match("^wg") or dev:match("^ppp") then + return i18n.translate("Tunnel Interface") + else + return i18n.translate("Ethernet Adapter") + end + end + -- Classify offline UCI interfaces by config hints + local function classify_uci(dev_name, proto) + if dev_name and dev_name:match("^br%-") then + return i18n.translate("Bridge") + elseif proto == "wireguard" or proto == "pppoe" or proto == "pptp" or proto == "l2tp" then + return i18n.translate("Tunnel Interface") + else + return i18n.translate("Interface") + end + end + + local _seen = {} + local _devices = {} + -- Active kernel devices from /sys/class/net/ + -- Skip bridge member ports (/master) and DSA master devices (/dsa) + local _iter = fs.dir(_sysnet) + if _iter then + for dev in _iter do + if dev ~= "lo" + and not dev:match("^veth") + and not dev:match("^ifb") + and not dev:match("^gre") + and not dev:match("^sit") + and not dev:match("^ip6tnl") + and not dev:match("^erspan") + and not fs.stat(_sysnet .. dev .. "/master", "type") + and not fs.stat(_sysnet .. dev .. "/dsa", "type") + then + local dtype = classify_sysfs(dev) + local label = dtype .. ': "' .. dev .. '"' + if _dev_to_ifaces[dev] then + label = label .. " (" .. table.concat(_dev_to_ifaces[dev], ", ") .. ")" + end + _devices[#_devices + 1] = { name = dev, label = label, sort = dtype .. ":" .. dev } + _seen[dev] = true + end + end + end + -- UCI interfaces whose device does not currently exist + for iface, dev in pairs(_iface_to_dev) do + if not _seen[dev] then + local dtype = classify_uci(dev, _iface_proto[iface]) + local label = dtype .. ': "' .. iface .. '"' + _devices[#_devices + 1] = { name = iface, label = label, sort = "zzz:" .. iface } + _seen[dev] = true + end + end + table.sort(_devices, function(a, b) return a.sort < b.sort end) + return _devices +end diff --git a/luci-app-passwall/luasrc/passwall/com.lua b/luci-app-passwall/luasrc/passwall/com.lua new file mode 100644 index 00000000..9d378007 --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/com.lua @@ -0,0 +1,118 @@ +local _M = {} + +local function gh_release_url(self) + --return "https://api.github.com/repos/" .. self.repo .. "/releases/latest" + return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-release-api.json" +end + +local function gh_pre_release_url(self) + --return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1" + return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json" +end + +-- 排åºé¡ºåºå®šä¹‰ +_M.order = { + "geoview", + "chinadns-ng", + "xray", + "sing-box", + "hysteria" +} + +_M.hysteria = { + name = "Hysteria", + repo = "HyNetwork/hysteria", + get_url = gh_release_url, + cmd_version = "version | awk '/^Version:/ {print $2}'", + remote_version_str_replace = "app/", + zipped = false, + default_path = "/usr/bin/hysteria", + match_fmt_str = "linux%%-%s$", + file_tree = { + armv6 = "arm", + armv7 = "arm", + mipsel = "mipsle" + } +} + +_M["sing-box"] = { + name = "Sing-Box", + repo = "SagerNet/sing-box", + get_url = gh_release_url, + cmd_version = "version | awk '{print $3}' | sed -n 1P", + zipped = true, + zipped_suffix = "tar.gz", + default_path = "/usr/bin/sing-box", + match_fmt_str = "linux%%-%s", + file_tree = { + x86_64 = "amd64%-musl", + x86 = "386%-musl", + aarch64 = "arm64%-musl", + rockchip = "arm64%-musl", + mips = "mips%-softfloat", + mips64 = "mips64%-softfloat", + mipsel = "mipsle%-softfloat%-musl", + mips64el = "mips64le%-softfloat", + armv7 = "armv7%-musl", + armv8 = "arm64%-musl", + riscv64 = "riscv64%-musl" + } +} + +_M.xray = { + name = "Xray", + repo = "XTLS/Xray-core", + get_url = gh_pre_release_url, + cmd_version = "version | awk '{print $2}' | sed -n 1P", + zipped = true, + default_path = "/usr/bin/xray", + match_fmt_str = "linux%%-%s", + file_tree = { + x86_64 = "64", + x86 = "32", + mips = "mips32", + mipsel = "mips32le", + mips64el = "mips64le" + } +} + +_M["chinadns-ng"] = { + name = "ChinaDNS-NG", + repo = "zfl9/chinadns-ng", + get_url = gh_release_url, + cmd_version = "-V | awk '{print $2}'", + zipped = false, + default_path = "/usr/bin/chinadns-ng", + match_fmt_str = "%s", + file_tree = { + x86_64 = "wolfssl@x86_64.*x86_64@", + x86 = "wolfssl@i386.*i686", + mips = "wolfssl@mips%-.*mips32%+soft_float@", + mips64 = "wolfssl@mips64%-.*mips64%+soft_float@", + mipsel = "wolfssl@mipsel.*mips32%+soft_float@", + mips64el = "wolfssl@mips64el%-.*mips64%+soft_float@", + aarch64 = "wolfssl_noasm@aarch64.*v8a", + rockchip = "wolfssl@aarch64.*v8a", + armv5 = "wolfssl@arm.*v5te", + armv6 = "wolfssl@arm.*v6t2", + armv7 = "wolfssl@arm.*eabihf.*v7a", + armv8 = "wolfssl_noasm@aarch64.*v8a", + riscv64 = "wolfssl@riscv64.*" + } +} + +_M.geoview = { + name = "Geoview", + repo = "snowie2000/geoview", + get_url = gh_release_url, + cmd_version = '-version 2>/dev/null | awk \'NR==1 && $1=="Geoview" {print $2}\'', + zipped = false, + default_path = "/usr/bin/geoview", + match_fmt_str = "linux%%-%s", + file_tree = { + mipsel = "mipsle", + mips64el = "mips64le" + } +} + +return _M diff --git a/luci-app-passwall/luasrc/passwall/server_app.lua b/luci-app-passwall/luasrc/passwall/server_app.lua new file mode 100644 index 00000000..bec17f8e --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/server_app.lua @@ -0,0 +1,256 @@ +#!/usr/bin/lua + +local action = arg[1] +local api = require "luci.passwall.api" +local sys = api.sys +local uci = api.uci +local jsonc = api.jsonc + +local CONFIG = "passwall_server" +local CONFIG_PATH = "/tmp/etc/" .. CONFIG +local NFT_INCLUDE_FILE = CONFIG_PATH .. "/" .. CONFIG .. ".nft" +local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log" +local TMP_BIN_PATH = CONFIG_PATH .. "/bin" +local require_dir = "luci.passwall." + +local ipt_bin = sys.exec("echo -n $(/usr/share/passwall/iptables.sh get_ipt_bin)") +local ip6t_bin = sys.exec("echo -n $(/usr/share/passwall/iptables.sh get_ip6t_bin)") + +local nft_flag = api.is_finded("fw4") and "1" or "0" + +local function log(...) + local f, err = io.open(LOG_APP_FILE, "a") + if f and err == nil then + local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + f:write(str .. "\n") + f:close() + end +end + +local function cmd(cmd) + sys.call(cmd) +end + +local function ipt(arg) + if ipt_bin and #ipt_bin > 0 then + cmd(ipt_bin .. " -w " .. arg) + end +end + +local function ip6t(arg) + if ip6t_bin and #ip6t_bin > 0 then + cmd(ip6t_bin .. " -w " .. arg) + end +end + +local function ln_run(s, d, command, output) + if not output then + output = "/dev/null" + end + d = TMP_BIN_PATH .. "/" .. d + cmd(string.format('[ ! -f "%s" ] && ln -s %s %s 2>/dev/null', d, s, d)) + return string.format("%s >%s 2>&1 &", d .. " " .. command, output) +end + +local function gen_include() + cmd(string.format("echo '#!/bin/sh' > /tmp/etc/%s.include", CONFIG)) + local function extract_rules(n, a) + local _ipt = ipt_bin + if n == "6" then + _ipt = ip6t_bin + end + local result = "*" .. a + result = result .. "\n" .. sys.exec(_ipt .. '-save -t ' .. a .. ' | grep "PSW-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"') + result = result .. "COMMIT" + return result + end + local f, err = io.open("/tmp/etc/" .. CONFIG .. ".include", "a") + if f and err == nil then + if nft_flag == "0" then + f:write(ipt_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ipt_bin .. '-restore -c' .. "\n") + f:write(ipt_bin .. '-restore -n <<-EOT' .. "\n") + f:write(extract_rules("4", "filter") .. "\n") + f:write("EOT" .. "\n") + f:write(ip6t_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ip6t_bin .. '-restore -c' .. "\n") + f:write(ip6t_bin .. '-restore -n <<-EOT' .. "\n") + f:write(extract_rules("6", "filter") .. "\n") + f:write("EOT" .. "\n") + f:close() + else + f:write("nft -f " .. NFT_INCLUDE_FILE .. "\n") + f:close() + end + end +end + +local function start() + local enabled = tonumber(uci:get(CONFIG, "@global[0]", "enable") or 0) + if enabled == nil or enabled == 0 then + return + end + cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH)) + cmd(string.format("touch %s", LOG_APP_FILE)) + if nft_flag == "0" then + ipt("-N PSW-SERVER") + ipt("-I INPUT -j PSW-SERVER") + ip6t("-N PSW-SERVER") + ip6t("-I INPUT -j PSW-SERVER") + else + nft_file, err = io.open(NFT_INCLUDE_FILE, "w") + nft_file:write('#!/usr/sbin/nft -f\n') + nft_file:write('add chain inet fw4 PSW-SERVER\n') + nft_file:write('flush chain inet fw4 PSW-SERVER\n') + nft_file:write('insert rule inet fw4 input position 0 jump PSW-SERVER comment "PSW-SERVER"\n') + end + uci:foreach(CONFIG, "user", function(user) + local id = user[".name"] + local enable = user.enable + if enable and tonumber(enable) == 1 then + local enable_log = user.log + local log_path = nil + if enable_log and enable_log == "1" then + log_path = CONFIG_PATH .. "/" .. id .. ".log" + else + log_path = nil + end + local remarks = user.remarks + local port = tonumber(user.port) + local bin + local config = {} + local config_file = CONFIG_PATH .. "/" .. id .. ".json" + local udp_forward = 1 + local type = user.type or "" + if type == "Socks" then + local auth = "" + if user.auth and user.auth == "1" then + local username = user.username or "" + local password = user.password or "" + if username ~= "" and password ~= "" then + username = "-u " .. username + password = "-P " .. password + auth = username .. " " .. password + end + end + bin = ln_run("/usr/bin/microsocks", "microsocks_" .. id, string.format("-i :: -p %s %s", port, auth), log_path) + elseif type == "SSR" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + else + config = require(require_dir .. "util_shadowsocks").gen_config_server(user) + end + local udp_param = "" + udp_forward = tonumber(user.udp_forward) or 1 + if udp_forward == 1 then + udp_param = "-u" + end + type = type:lower() + bin = ln_run("/usr/bin/" .. type .. "-server", type .. "-server", "-c " .. config_file .. " " .. udp_param, log_path) + elseif type == "SS-Rust" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + else + config = require(require_dir .. "util_shadowsocks").gen_config_server(user) + end + bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path) + elseif type == "Xray" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + if log_path then + if not config.log then + config.log = {} + end + config.log.loglevel = user.loglevel + end + else + config = require(require_dir .. "util_xray").gen_config_server(user) + end + bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path) + elseif type == "sing-box" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + if log_path then + if not config.log then + config.log = {} + end + config.log.timestamp = true + config.log.disabled = false + config.log.level = user.loglevel + config.log.output = log_path + end + else + config = require(require_dir .. "util_sing-box").gen_config_server(user) + end + bin = ln_run(api.get_app_path("sing-box"), "sing-box", "run -c " .. config_file, log_path) + elseif type == "Hysteria2" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + else + config = require(require_dir .. "util_hysteria2").gen_config_server(user) + end + bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path) + end + + if next(config) then + local f, err = io.open(config_file, "w") + if f and err == nil then + f:write(jsonc.stringify(config, 1)) + f:close() + end + log(string.format("%s 生æˆé…置文件并è¿è¡Œ - %s", remarks, config_file)) + end + + if bin then + cmd(bin) + end + + local bind_local = user.bind_local or 0 + if bind_local and tonumber(bind_local) ~= 1 and port then + if nft_flag == "0" then + ipt(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + ip6t(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + if udp_forward == 1 then + ipt(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + ip6t(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + end + else + nft_file:write(string.format('add rule inet fw4 PSW-SERVER meta l4proto tcp tcp dport {%s} counter accept comment "%s"\n', port, remarks)) + if udp_forward == 1 then + nft_file:write(string.format('add rule inet fw4 PSW-SERVER meta l4proto udp udp dport {%s} counter accept comment "%s"\n', port, remarks)) + end + end + end + end + end) + if nft_flag == "1" then + nft_file:write("add rule inet fw4 PSW-SERVER return\n") + nft_file:close() + cmd("nft -f " .. NFT_INCLUDE_FILE) + end + gen_include() +end + +local function stop() + cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH)) + if nft_flag == "0" then + ipt("-D INPUT -j PSW-SERVER 2>/dev/null") + ipt("-F PSW-SERVER 2>/dev/null") + ipt("-X PSW-SERVER 2>/dev/null") + ip6t("-D INPUT -j PSW-SERVER 2>/dev/null") + ip6t("-F PSW-SERVER 2>/dev/null") + ip6t("-X PSW-SERVER 2>/dev/null") + else + local nft_cmd = "handles=$(nft -a list chain inet fw4 input | grep -E \"PSW-SERVER\" | awk -F '# handle ' '{print$2}')\n for handle in $handles; do\n nft delete rule inet fw4 input handle ${handle} 2>/dev/null\n done" + cmd(nft_cmd) + cmd("nft flush chain inet fw4 PSW-SERVER 2>/dev/null") + cmd("nft delete chain inet fw4 PSW-SERVER 2>/dev/null") + end + cmd(string.format("rm -rf %s %s /tmp/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG)) +end + +if action then + if action == "start" then + start() + elseif action == "stop" then + stop() + end +end diff --git a/luci-app-passwall/luasrc/passwall/util_hysteria2.lua b/luci-app-passwall/luasrc/passwall/util_hysteria2.lua new file mode 100644 index 00000000..89049692 --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/util_hysteria2.lua @@ -0,0 +1,173 @@ +module("luci.passwall.util_hysteria2", package.seeall) +local api = require "luci.passwall.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config_server(node) + local config = { + listen = (function() + if node.hysteria2_realms and node.hysteria2_realm_url then + local url = node.hysteria2_realm_url:gsub("/+$", "") + if node.port then + url = url .. (url:find("?") and "&lport=" or "?lport=") .. node.port + end + return url + end + return ":" .. (node.port or "0") + end)(), + tls = { + cert = node.tls_certificateFile, + key = node.tls_keyFile, + }, + obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and { + type = node.hysteria2_obfs_type, + [node.hysteria2_obfs_type] = { + password = node.hysteria2_obfs_password + } + } or nil, + auth = { + type = "password", + password = node.hysteria2_auth_password + }, + bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and { + up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil, + down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil + } or nil, + ignoreClientBandwidth = (node.hysteria2_ignoreClientBandwidth == "1") and true or false, + disableUDP = (node.hysteria2_udp == "0") and true or false, + realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and { + stunServers = node.hysteria2_realm_stun + } or nil + } + return config +end + +function gen_config(var) + local node_id = var["node"] + if not node_id then + print("node ä¸èƒ½ä¸ºç©º") + return + end + local node = uci:get_all("passwall", node_id) + local local_tcp_redir_port = var["local_tcp_redir_port"] + local local_udp_redir_port = var["local_udp_redir_port"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local tcp_proxy_way = var["tcp_proxy_way"] + local server_host = var["server_host"] or (node.address or ""):lower() + local server_port = var["server_port"] or node.port + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_full(server_host) + end + + local server = server_host .. ":" .. ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-") + + local config = { + server = (function() + if node.hysteria2_realms and node.hysteria2_realm_url then + return node.hysteria2_realm_url:gsub("/+$", "") + end + return server + end)(), + realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and { + stunServers = node.hysteria2_realm_stun + } or nil, + transport = { + type = "udp", + udp = node.hysteria2_hop and (function() + local udp = {} + local t = node.hysteria2_hop_interval + if not t then return nil end + if t:find("-", 1, true) then + local min, max = t:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + udp.minHopInterval = min .. "s" + udp.maxHopInterval = max .. "s" + return udp + end + end + t = tonumber((t or "30"):match("^%d+")) + t = (t and t >= 5) and t or 30 + udp.hopInterval = t .. "s" + return udp + end)() or nil + }, + obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and { + type = node.hysteria2_obfs_type, + [node.hysteria2_obfs_type] = { + password = node.hysteria2_obfs_password + } + } or nil, + auth = node.hysteria2_auth_password, + tls = { + sni = node.tls_serverName, + insecure = (node.tls_allowInsecure == "1") and true or false, + pinSHA256 = (node.tls_pinSHA256) and node.tls_pinSHA256 or nil, + }, + quic = { + initStreamReceiveWindow = (node.hysteria2_recv_window) and tonumber(node.hysteria2_recv_window) or nil, + initConnReceiveWindow = (node.hysteria2_recv_window_conn) and tonumber(node.hysteria2_recv_window_conn) or nil, + maxIdleTimeout = (function(t) + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t .. "s" or "30s" + end)(node.hysteria2_idle_timeout), + keepAlivePeriod = (function(t) + t = tonumber(tostring(t or "0"):match("^%d+")) + return (t and t >= 2 and t <= 60) and t .. "s" or nil + end)(node.hysteria2_keep_alive_period), + disablePathMTUDiscovery = (node.hysteria2_disable_mtu_discovery) and true or false, + }, + bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and { + up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil, + down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil + } or nil, + fast_open = (node.fast_open == "1") and true or false, + lazy = (node.hysteria2_lazy_start == "1") and true or false, + socks5 = (local_socks_address and local_socks_port) and { + listen = local_socks_address .. ":" .. local_socks_port, + username = (local_socks_username and local_socks_password) and local_socks_username or nil, + password = (local_socks_username and local_socks_password) and local_socks_password or nil, + disableUDP = false, + } or nil, + http = (local_http_address and local_http_port) and { + listen = local_http_address .. ":" .. local_http_port, + username = (local_http_username and local_http_password) and local_http_username or nil, + password = (local_http_username and local_http_password) and local_http_password or nil, + } or nil, + tcpRedirect = ("redirect" == tcp_proxy_way and local_tcp_redir_port) and { + listen = "0.0.0.0:" .. local_tcp_redir_port + } or nil, + tcpTProxy = ("tproxy" == tcp_proxy_way and local_tcp_redir_port) and { + listen = "0.0.0.0:" .. local_tcp_redir_port + } or nil, + udpTProxy = (local_udp_redir_port) and { + listen = "0.0.0.0:" .. local_udp_redir_port + } or nil + } + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + end +end diff --git a/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua b/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua new file mode 100644 index 00000000..02c4d27d --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua @@ -0,0 +1,43 @@ +module("luci.passwall.util_naiveproxy", package.seeall) +local api = require "luci.passwall.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config(var) + local node_id = var["node"] + if not node_id then + print("node ä¸èƒ½ä¸ºç©º") + return + end + local node = uci:get_all("passwall", node_id) + local run_type = var["run_type"] + local local_addr = var["local_addr"] + local local_port = var["local_port"] + local server_host = var["server_host"] or (node.address or ""):lower() + local server_port = var["server_port"] or node.port + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_full(server_host) + end + local server = server_host .. ":" .. server_port + + local config = { + listen = run_type .. "://" .. local_addr .. ":" .. local_port, + proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server + } + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + end +end diff --git a/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua b/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua new file mode 100644 index 00000000..819b8278 --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua @@ -0,0 +1,161 @@ +module("luci.passwall.util_shadowsocks", package.seeall) +local api = require "luci.passwall.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config_server(node) + local config = {} + config.server_port = tonumber(node.port) + config.password = node.password + config.timeout = tonumber(node.timeout) + config.fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false + config.method = node.method + + if node.type == "SS-Rust" then + config.server = "::" + config.mode = "tcp_and_udp" + else + config.server = {"[::0]", "0.0.0.0"} + end + + if node.type == "SSR" then + config.protocol = node.protocol + config.protocol_param = node.protocol_param + config.obfs = node.obfs + config.obfs_param = node.obfs_param + end + + return config +end + +local plugin_sh, plugin_bin + +function gen_config(var) + local node_id = var["node"] + if not node_id then + print("node ä¸èƒ½ä¸ºç©º") + return + end + local node = uci:get_all("passwall", node_id) + local server_host = var["server_host"] or (node.address or ""):lower() + local server_port = var["server_port"] or node.port + local local_addr = var["local_addr"] + local local_port = var["local_port"] + local mode = var["mode"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local local_tcp_redir_port = var["local_tcp_redir_port"] + local local_tcp_redir_address = var["local_tcp_redir_address"] or "0.0.0.0" + local local_udp_redir_port = var["local_udp_redir_port"] + local local_udp_redir_address = var["local_udp_redir_address"] or "0.0.0.0" + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_only(server_host) + end + local server = server_host + + local plugin_file + if node.plugin and node.plugin ~= "" and node.plugin ~= "none" then + plugin_sh = var["plugin_sh"] or "" + plugin_file = (plugin_sh ~="") and plugin_sh or node.plugin + plugin_bin = node.plugin + end + + local config = { + server = server, + server_port = tonumber(server_port), + local_address = local_addr, + local_port = tonumber(local_port), + password = node.password, + method = node.method, + timeout = tonumber(node.timeout), + fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false, + reuse_port = true, + tcp_tproxy = var["tcp_tproxy"] and true or nil + } + + if node.type == "SSR" then + config.protocol = node.protocol + config.protocol_param = node.protocol_param + config.obfs = node.obfs + config.obfs_param = node.obfs_param + elseif node.type == "SS-Rust" then + config = { + servers = { + { + address = server, + port = tonumber(server_port), + method = node.method, + password = node.password, + timeout = tonumber(node.timeout), + plugin = plugin_file or nil, + plugin_opts = (plugin_file) and node.plugin_opts or nil + } + }, + locals = {}, + fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false + } + if local_socks_address and local_socks_port then + table.insert(config.locals, { + local_address = local_socks_address, + local_port = tonumber(local_socks_port), + mode = "tcp_and_udp" + }) + end + if local_http_address and local_http_port then + table.insert(config.locals, { + protocol = "http", + local_address = local_http_address, + local_port = tonumber(local_http_port) + }) + end + if local_tcp_redir_address and local_tcp_redir_port then + table.insert(config.locals, { + protocol = "redir", + mode = "tcp_only", + tcp_redir = var["tcp_tproxy"] and "tproxy" or nil, + local_address = local_tcp_redir_address, + local_port = tonumber(local_tcp_redir_port) + }) + end + if local_udp_redir_address and local_udp_redir_port then + table.insert(config.locals, { + protocol = "redir", + mode = "udp_only", + local_address = local_udp_redir_address, + local_port = tonumber(local_udp_redir_port) + }) + end + end + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + if plugin_sh and plugin_sh ~="" and plugin_bin then + local f = io.open(plugin_sh, "w") + f:write("#!/bin/sh\n") + f:write("export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:$PATH\n") + f:write(plugin_bin .. " $@ &\n") + f:write("echo $! > " .. plugin_sh:gsub("%.sh$", ".pid") .. "\n") + f:write("wait\n") + f:close() + luci.sys.call("chmod +x " .. plugin_sh) + end + end +end diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua new file mode 100644 index 00000000..3d428e05 --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -0,0 +1,2267 @@ +module("luci.passwall.util_sing-box", package.seeall) +local api = require "luci.passwall.api" +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local appname = "passwall" +local fs = api.fs +local split = api.split +local ech_domain = {} + +local local_version = api.get_app_version("sing-box"):match("[^v]+") +local version_ge_1_14_0 = api.compare_versions(local_version, ">=", "1.14.0") + +local GLOBAL = { + DNS_SERVER = {}, + DNS_HOSTNAME = {}, + VPS_EXCLUDE = {} +} + +local GEO_VAR = { + OK = nil, + DIR = nil, + SITE_PATH = nil, + IP_PATH = nil, + SITE_TAGS = {}, + IP_TAGS = {}, + TO_SRS_PATH = "/tmp/etc/" .. appname .."_tmp/singbox_srss/" +} + +function check_geoview() + if not GEO_VAR.OK then + -- Only get once + GEO_VAR.OK = (api.finded_com("geoview") and api.compare_versions(api.get_app_version("geoview"), ">=", "0.1.10")) and 1 or 0 + end + if GEO_VAR.OK == 0 then + api.log("ï¼ï¼ï¼æ³¨æ„:缺少 Geoview 组件或版本过低,Sing-Box åˆ†æµæ— æ³•å¯ç”¨ï¼") + else + GEO_VAR.DIR = GEO_VAR.DIR or (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") + GEO_VAR.SITE_PATH = GEO_VAR.SITE_PATH or (GEO_VAR.DIR .. "/geosite.dat") + GEO_VAR.IP_PATH = GEO_VAR.IP_PATH or (GEO_VAR.DIR .. "/geoip.dat") + if not fs.access(GEO_VAR.TO_SRS_PATH) then + fs.mkdir(GEO_VAR.TO_SRS_PATH) + end + end + return GEO_VAR.OK +end + +function geo_convert_srs(var) + if check_geoview() ~= 1 then + return + end + local geo_path = var["geo_path"] + local prefix = var["prefix"] + local rule_name = var["rule_name"] + local output_srs_file = GEO_VAR.TO_SRS_PATH .. prefix .. "-" .. rule_name .. ".srs" + local bin = api.finded_com("geoview") + if not fs.access(output_srs_file) and bin then + local cmd = string.format("%q -type %q -action convert -input %q -list %q -output %q -lowmem=true", + bin, prefix, geo_path, rule_name, output_srs_file) + sys.call(cmd) + local status = fs.access(output_srs_file) and "success." or "failed!" + if status == "failed!" then + api.log(string.format(" - %s:%s 转æ¢ä¸ºsrsæ ¼å¼ï¼š%s", prefix, rule_name, status)) + end + end +end + +local function convert_geofile() + if check_geoview() ~= 1 then + return + end + local function convert(file_path, prefix, tags) + if next(tags) and fs.access(file_path) then + local md5_file = GEO_VAR.TO_SRS_PATH .. prefix .. ".dat.md5" + local new_md5 = sys.exec("md5sum " .. file_path .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "") + local old_md5 = sys.exec("[ -f " .. md5_file .. " ] && head -n 1 " .. md5_file .. " | tr -d ' \t\n' || echo ''") + if new_md5 ~= "" and new_md5 ~= old_md5 then + sys.call("printf '%s' " .. new_md5 .. " > " .. md5_file) + sys.call("rm -rf " .. GEO_VAR.TO_SRS_PATH .. prefix .. "-*.srs" ) + end + for k in pairs(tags) do + geo_convert_srs({["geo_path"] = file_path, ["prefix"] = prefix, ["rule_name"] = k}) + end + end + end + --api.log("Sing-Box 规则集转æ¢ï¼š") + convert(GEO_VAR.SITE_PATH, "geosite", GEO_VAR.SITE_TAGS) + convert(GEO_VAR.IP_PATH, "geoip", GEO_VAR.IP_TAGS) +end + +function gen_outbound(flag, node, tag, proxy_table) + local result = nil + if node then + local node_id = node[".name"] + if tag == nil then + tag = node_id + end + local remarks = node.remarks + + local proxy_tag = nil + local fragment = nil + local record_fragment = nil + local run_socks_instance = true + if proxy_table ~= nil and type(proxy_table) == "table" then + proxy_tag = proxy_table.tag or nil + fragment = (proxy_table.fragment and node.protocol ~= "naive" and not node.hysteria2_realms) and true or nil + record_fragment = (proxy_table.record_fragment and node.protocol ~= "naive" and not node.hysteria2_realms) and true or nil + run_socks_instance = proxy_table.run_socks_instance + end + + if node.type ~= "sing-box" then + local relay_port = node.port + local new_port = api.get_new_port() + local config_file = string.format("%s_%s_%s.json", flag, tag, new_port) + if tag and node_id and not tag:find(node_id) then + config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port) + end + if run_socks_instance then + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s", + new_port, --flag + node_id, --node + "127.0.0.1", --bind + new_port, --socks port + config_file, --config file + (proxy_tag and relay_port) and tostring(relay_port) or "" --relay port + ) + ) + ) + end + node = { + protocol = "socks", + address = "127.0.0.1", + port = new_port + } + proxy_tag = "socks <- " .. node_id + else + if proxy_tag then + node.detour = proxy_tag + end + end + + if remarks then + tag = tag .. ":" .. remarks + end + + node.address = (node.address or ""):lower() + + result = { + _id = node_id, + _flag = flag, + _flag_proxy_tag = proxy_tag, + tag = tag, + type = node.protocol, + server = node.address, + server_port = tonumber(node.port), + domain_resolver = { + server = "direct", + strategy = node.domain_strategy + }, + detour = node.detour, + } + + if api.datatypes.hostname(node.address) and node.domain_resolver and (node.domain_resolver_dns or node.domain_resolver_dns_https) then + local dns_proto = node.domain_resolver + local server_address + local server_port + local server_path + if dns_proto == "https" then + local _a = api.parseDoH(node.domain_resolver_dns_https) + if _a then + server_address = _a.hostname + server_port = _a.port or 443 + server_path = _a.pathname or "" + if _a.hostname and api.datatypes.hostname(_a.hostname) then + GLOBAL.DNS_HOSTNAME[_a.hostname] = true + end + end + else + server_address = node.domain_resolver_dns + server_port = 53 + local split = api.split(server_address, ":") + if #split > 1 then + server_address = split[1] + server_port = tonumber(split[#split]) + end + end + local dns_key = dns_proto .. "|" .. tostring(server_address) .. "|" .. tostring(server_port) .. "|" .. tostring(server_path or "") + if not GLOBAL.DNS_SERVER[dns_key] then + GLOBAL.DNS_SERVER[dns_key] = { + server = { + tag = "dns-node-" .. api.gen_short_uuid(), + type = dns_proto, + server = server_address, + server_port = server_port, + path = server_path, + domain_resolver = "direct", + detour = "direct" + }, + domain = {} + } + end + local exists + for _, d in ipairs(GLOBAL.DNS_SERVER[dns_key].domain) do + if d == node.address then exists = true; break end + end + if not exists then table.insert(GLOBAL.DNS_SERVER[dns_key].domain, node.address) end + result.domain_resolver.server = GLOBAL.DNS_SERVER[dns_key].server.tag + GLOBAL.VPS_EXCLUDE[node.address] = true + end + + local tls = nil + if node.protocol == "hysteria" or node.protocol == "hysteria2" or node.protocol == "tuic" or node.protocol == "naive" then + node.tls = "1" + end + if node.tls == "1" then + local alpn = nil + if node.alpn and node.alpn ~= "default" then + alpn = {} + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + tls = { + enabled = true, + disable_sni = (node.tls_disable_sni == "1") and true or false, --ä¸è¦åœ¨ ClientHello 中å‘逿œåС噍åç§°. + server_name = node.tls_serverName, --用于验è¯è¿”回è¯ä¹¦ä¸Šçš„主机å,除éžè®¾ç½®ä¸å®‰å…¨ã€‚它还包å«åœ¨ ClientHello 中以支æŒè™šæ‹Ÿä¸»æœºï¼Œé™¤éžå®ƒæ˜¯ IP 地å€ã€‚ + insecure = node.tls_allowInsecure == "1" or (node.tls_pinSHA256 and node.tls_pinSHA256 ~= ""), --接å—任何æœåС噍è¯ä¹¦ã€‚(兼顾 xray çš„ pinnedPeerCertSha256 ) + alpn = alpn, --支æŒçš„应用层åè®®åå•†åˆ—è¡¨ï¼ŒæŒ‰ä¼˜å…ˆé¡ºåºæŽ’åˆ—ã€‚å¦‚æžœä¸¤ä¸ªå¯¹ç­‰ç‚¹éƒ½æ”¯æŒ ALPN,则选择的å议将是此列表中的一个,如果没有相互支æŒçš„å议则连接将失败。 + --min_version = "1.2", + --max_version = "1.3", + fragment = fragment, + record_fragment = record_fragment, + ech = (node.ech == "1") and (function() + local function get_ech_domain(s) --兼容xray "域å+DNS" æ ¼å¼ech + local domain, dns = s:match("^([^+]+)%+(.+)$") + if not domain or not dns then return nil end + if not (dns:match("^https?://") or dns:match("^tcp://") or dns:match("^udp://") or dns:match("^h2c://")) then + return nil + end + if not domain:match("^[%w%-%.]+%.[%a]+$") then return nil end + return domain + end + local ech = { enabled = true } + local config = node.ech_config + local qname = node.ech_query_server_name + if config and not qname then + qname = get_ech_domain(config) + if not qname and not (config:match("%-+%s*BEGIN") and config:match("%-+%s*END")) then + config = "-----BEGIN ECH CONFIGS-----\n" .. config:gsub("%s+", "") .. "\n-----END ECH CONFIGS-----" + end + end + if qname then + ech.query_server_name = qname + ech_domain[qname] = true + elseif config then + ech.config = { config } + elseif node.tls_serverName and node.tls_serverName ~= "" then + ech_domain[node.tls_serverName] = true + end + return ech + end)() or nil, + utls = (node.utls == "1" or node.reality == "1") and { + enabled = true, + fingerprint = node.fingerprint or "chrome" + } or nil, + reality = (node.reality == "1") and { + enabled = true, + public_key = node.reality_publicKey, + short_id = node.reality_shortId + } or nil + } + end + + local mux = nil + if node.mux == "1" then + mux = { + enabled = true, + protocol = node.mux_type or "h2mux", + max_connections = ( (node.tcpbrutal == "1") and 1 ) or tonumber(node.mux_concurrency) or 4, + padding = (node.mux_padding == "1") and true or false, + --min_streams = 4, + --max_streams = 0, + brutal = { + enabled = (node.tcpbrutal == "1") and true or false, + up_mbps = tonumber(node.tcpbrutal_up_mbps) or 10, + down_mbps = tonumber(node.tcpbrutal_down_mbps) or 50, + }, + } + end + + local v2ray_transport = nil + + if node.transport == "tcp" and node.tcp_guise == "http" and (node.tcp_guise_http_host or "") ~= "" then --模拟xray raw(tcp)传输 + v2ray_transport = { + type = "http", + host = node.tcp_guise_http_host, + path = node.tcp_guise_http_path and (function() + local first = node.tcp_guise_http_path[1] + return (first == "" or not first) and "/" or first + end)() or "/", + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil, + ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil, + } + --ä¸å¼ºåˆ¶æ‰§è¡Œ TLS。如果未é…ç½® TLS,将使用纯 HTTP 1.1。 + end + + if node.transport == "http" then + v2ray_transport = { + type = "http", + host = node.http_host or {}, + path = node.http_path or "/", + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil, + ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil, + } + --ä¸å¼ºåˆ¶æ‰§è¡Œ TLS。如果未é…ç½® TLS,将使用纯 HTTP 1.1。 + end + + if node.transport == "ws" then + v2ray_transport = { + type = "ws", + path = node.ws_path or "/", + headers = (node.ws_host or node.user_agent) and { + Host = node.ws_host, + ["User-Agent"] = node.user_agent + } or nil, + max_early_data = tonumber(node.ws_maxEarlyData) or nil, + early_data_header_name = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil --è¦ä¸Ž Xray-core 兼容,请将其设置为 Sec-WebSocket-Protocol。它需è¦ä¸ŽæœåŠ¡å™¨ä¿æŒä¸€è‡´ã€‚ + } + end + + if node.transport == "httpupgrade" then + v2ray_transport = { + type = "httpupgrade", + host = node.httpupgrade_host, + path = node.httpupgrade_path or "/", + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil + } + end + + if node.transport == "quic" then + v2ray_transport = { + type = "quic" + } + --没有é¢å¤–的加密支æŒï¼š 它基本上是é‡å¤åŠ å¯†ã€‚ 并且 Xray-core 在这里与 v2ray-core ä¸å…¼å®¹ã€‚ + end + + if node.transport == "grpc" then + v2ray_transport = { + type = "grpc", + service_name = node.grpc_serviceName, + idle_timeout = tonumber(node.grpc_idle_timeout) or nil, + ping_timeout = tonumber(node.grpc_health_check_timeout) or nil, + permit_without_stream = (node.grpc_permit_without_stream == "1") and true or nil, + } + end + + local protocol_table = nil + + if node.protocol == "socks" then + protocol_table = { + version = "5", + username = (node.username and node.password) and node.username or nil, + password = (node.username and node.password) and node.password or nil, + udp_over_tcp = node.uot == "1" and { + enabled = true, + version = 2 + } or nil, + } + end + + if node.protocol == "http" then + protocol_table = { + username = (node.username and node.password) and node.username or nil, + password = (node.username and node.password) and node.password or nil, + path = nil, + headers = nil, + tls = tls + } + end + + if node.protocol == "shadowsocks" then + protocol_table = { + method = node.method or nil, + password = node.password or "", + plugin = (node.plugin_enabled and node.plugin) or nil, + plugin_opts = (node.plugin_enabled and node.plugin_opts) or nil, + udp_over_tcp = node.uot == "1" and { + enabled = true, + version = 2 + } or nil, + multiplex = mux, + } + end + + if node.protocol == "trojan" then + protocol_table = { + password = node.password, + tls = tls, + multiplex = mux, + transport = v2ray_transport + } + end + + if node.protocol == "vmess" then + protocol_table = { + uuid = node.uuid, + security = node.security, + alter_id = (node.alter_id) and tonumber(node.alter_id) or 0, + global_padding = (node.global_padding == "1") and true or false, + authenticated_length = (node.authenticated_length == "1") and true or false, + tls = tls, + packet_encoding = "", --UDP 包编ç ã€‚(空):ç¦ç”¨ packetaddr:由 v2ray 5+ æ”¯æŒ xudp:由 xray æ”¯æŒ + multiplex = mux, + transport = v2ray_transport, + } + end + + if node.protocol == "vless" then + protocol_table = { + uuid = node.uuid, + flow = (node.tls == '1' and node.flow) and node.flow or nil, + tls = tls, + packet_encoding = "xudp", --UDP 包编ç ã€‚(空):ç¦ç”¨ packetaddr:由 v2ray 5+ æ”¯æŒ xudp:由 xray æ”¯æŒ + multiplex = mux, + transport = v2ray_transport, + } + end + + if node.protocol == "wireguard" then + if node.wireguard_reserved then + local bytes = {} + if not node.wireguard_reserved:match("[^%d,]+") then + node.wireguard_reserved:gsub("%d+", function(b) + bytes[#bytes + 1] = tonumber(b) + end) + else + local result = api.base64Decode(node.wireguard_reserved) + for i = 1, #result do + bytes[i] = result:byte(i) + end + end + node.wireguard_reserved = #bytes > 0 and bytes or nil + end + protocol_table = { + system_interface = nil, + interface_name = nil, + local_address = node.wireguard_local_address, + private_key = node.wireguard_secret_key, + peer_public_key = node.wireguard_public_key, + pre_shared_key = node.wireguard_preSharedKey, + reserved = node.wireguard_reserved, + mtu = tonumber(node.wireguard_mtu), + } + end + + if node.protocol == "hysteria" then + local server_ports = {} + if node.hysteria_hop then + node.hysteria_hop = string.gsub(node.hysteria_hop, "-", ":") + for range in node.hysteria_hop:gmatch("([^,]+)") do + if range:match("^%d+:%d+$") then + table.insert(server_ports, range) + end + end + result.server_port = nil + end + protocol_table = { + server_ports = next(server_ports) and server_ports or nil, + hop_interval = (function() + if not next(server_ports) then return nil end + local v = tonumber((node.hysteria_hop_interval or "30"):match("^%d+")) + return (v and v >= 5) and (v .. "s") or "30s" + end)(), + up_mbps = tonumber(node.hysteria_up_mbps), + down_mbps = tonumber(node.hysteria_down_mbps), + obfs = node.hysteria_obfs, + auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil, + auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil, + recv_window_conn = tonumber(node.hysteria_recv_window_conn), --1.14 å°†å˜æ›´ä¸º stream_receive_window + recv_window = tonumber(node.hysteria_recv_window), --1.14 å°†å˜æ›´ä¸º connection_receive_window + disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false, --1.14 å°†å˜æ›´ä¸º disable_path_mtu_discovery + tls = tls + } + end + + if node.protocol == "shadowtls" then + protocol_table = { + version = tonumber(node.shadowtls_version), + password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.password or nil, + tls = tls, + } + end + + if node.protocol == "tuic" then + protocol_table = { + uuid = node.uuid, + password = node.password, + congestion_control = node.tuic_congestion_control or "cubic", + udp_relay_mode = node.tuic_udp_relay_mode or "native", + udp_over_stream = false, + zero_rtt_handshake = (node.tuic_zero_rtt_handshake == "1") and true or false, + heartbeat = (tonumber(node.tuic_heartbeat) or 3) .. "s", + tls = tls + } + node.tuic_alpn = (node.tuic_alpn and node.tuic_alpn ~= "default") and node.tuic_alpn or "h3" + local alpn = {} + string.gsub(node.tuic_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then protocol_table.tls.alpn = alpn end + end + + if node.protocol == "hysteria2" then + local server_ports = {} + if node.hysteria2_hop then + node.hysteria2_hop = string.gsub(node.hysteria2_hop, "-", ":") + for range in node.hysteria2_hop:gmatch("([^,]+)") do + if range:match("^%d+:%d+$") then + table.insert(server_ports, range) + end + end + result.server_port = nil + end + if node.hysteria2_realms then + server_ports = {} + end + local interval, interval_max + if next(server_ports) then + interval = "30s" + local t = node.hysteria2_hop_interval or "30s" + if t:find("-", 1, true) then + local min, max = t:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + interval = min .. "s" + interval_max = max .. "s" + end + else + t = tonumber(t:match("^%d+")) + t = (t and t >= 5) and t or 30 + interval = t .. "s" + end + end + protocol_table = { + server_ports = next(server_ports) and server_ports or nil, + hop_interval = interval, + hop_interval_max = interval_max, + up_mbps = (node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil, + down_mbps = (node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil, + obfs = node.hysteria2_obfs_type and { + type = node.hysteria2_obfs_type, + password = node.hysteria2_obfs_password + } or nil, + password = node.hysteria2_auth_password or nil, + idle_timeout = (function(t) + if not version_ge_1_14_0 then return nil end + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t or 30 + end)(node.hysteria2_idle_timeout), + keep_alive_period = (function(t) + if not version_ge_1_14_0 then return nil end + t = tonumber(tostring(t or "0"):match("^%d+")) + return (t and t >= 2 and t <= 60) and t or nil + end)(node.hysteria2_keep_alive_period), + disable_path_mtu_discovery = version_ge_1_14_0 and (tonumber(node.hysteria2_disable_mtu_discovery) == 1) or nil, + tls = tls, + realm = node.hysteria2_realms and (function() + result.server = nil + result.server_port = nil + local realm = api.parse_realm_uri(node.hysteria2_realm_url) + if realm then + realm.server_url = realm.server_url and "https://" .. realm.server_url or nil + realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun + return realm + end + return nil + end)() or nil + } + end + + if node.protocol == "anytls" then + protocol_table = { + password = (node.password and node.password ~= "") and node.password or "", + idle_session_check_interval = "30s", + idle_session_timeout = "30s", + min_idle_session = 5, + tls = tls + } + end + + if node.protocol == "ssh" then + protocol_table = { + user = (node.username and node.username ~= "") and node.username or "root", + password = (node.password and node.password ~= "") and node.password or "", + private_key = node.ssh_priv_key, + private_key_passphrase = node.ssh_priv_key_pp, + host_key = node.ssh_host_key, + host_key_algorithms = node.ssh_host_key_algo, + client_version = node.ssh_client_version + } + end + + if node.protocol == "naive" then + protocol_table = { + username = (node.username and node.username ~= "") and node.username or "", + password = (node.password and node.password ~= "") and node.password or "", + insecure_concurrency = tonumber(node.naive_insecure_concurrency or 0) > 0 and tonumber(node.naive_insecure_concurrency) or 0, + udp_over_tcp = node.uot == "1" and { + enabled = true, + version = 2 + } or false, + extra_headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + quic = node.naive_quic == "1" and true or false, + quic_congestion_control = (node.naive_quic == "1" and node.naive_congestion_control) and node.naive_congestion_control or nil, + tls = tls + } + end + + if protocol_table then + for key, value in pairs(protocol_table) do + result[key] = value + end + end + end + return result +end + +function gen_config_server(node) + local outbounds = { + { type = "direct", tag = "direct" } + } + + local tls = { + enabled = true, + certificate_path = node.tls_certificateFile, + key_path = node.tls_keyFile, + alpn = (node.alpn and node.alpn ~= "default") and (function() + local alpn = {} + string.gsub(node.alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then return alpn end + return nil + end)() or nil + } + + if node.tls == "1" and node.reality == "1" then + tls.certificate_path = nil + tls.key_path = nil + tls.server_name = node.reality_handshake_server + tls.reality = { + enabled = true, + private_key = node.reality_private_key, + short_id = { + node.reality_shortId + }, + handshake = { + server = node.reality_handshake_server, + server_port = tonumber(node.reality_handshake_server_port) + } + } + end + + if node.tls == "1" and node.ech == "1" then + tls.ech = { + enabled = true, + key = node.ech_key and { node.ech_key } or nil + } + end + + local mux = nil + if node.mux == "1" then + mux = { + enabled = true, + padding = (node.mux_padding == "1") and true or false, + brutal = { + enabled = (node.tcpbrutal == "1") and true or false, + up_mbps = tonumber(node.tcpbrutal_up_mbps) or 10, + down_mbps = tonumber(node.tcpbrutal_down_mbps) or 50, + }, + } + end + + local v2ray_transport = nil + + if node.transport == "http" then + v2ray_transport = { + type = "http", + host = node.http_host or {}, + path = node.http_path or "/", + } + end + + if node.transport == "ws" then + v2ray_transport = { + type = "ws", + path = node.ws_path or "/", + headers = (node.ws_host ~= nil) and { Host = node.ws_host } or nil, + early_data_header_name = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil --è¦ä¸Ž Xray-core 兼容,请将其设置为 Sec-WebSocket-Protocol。它需è¦ä¸ŽæœåŠ¡å™¨ä¿æŒä¸€è‡´ã€‚ + } + end + + if node.transport == "httpupgrade" then + v2ray_transport = { + type = "httpupgrade", + host = node.httpupgrade_host, + path = node.httpupgrade_path or "/", + } + end + + if node.transport == "quic" then + v2ray_transport = { + type = "quic" + } + --没有é¢å¤–的加密支æŒï¼š 它基本上是é‡å¤åŠ å¯†ã€‚ 并且 Xray-core 在这里与 v2ray-core ä¸å…¼å®¹ã€‚ + end + + if node.transport == "grpc" then + v2ray_transport = { + type = "grpc", + service_name = node.grpc_serviceName, + } + end + + local inbound = { + type = node.protocol, + tag = "inbound", + listen = (node.bind_local == "1") and "127.0.0.1" or "::", + listen_port = tonumber(node.port), + } + + local protocol_table = nil + + if node.protocol == "mixed" then + protocol_table = { + users = (node.auth == "1") and { + { + username = node.username, + password = node.password + } + } or nil, + set_system_proxy = false + } + end + + if node.protocol == "socks" then + protocol_table = { + users = (node.auth == "1") and { + { + username = node.username, + password = node.password + } + } or nil + } + end + + if node.protocol == "http" then + protocol_table = { + users = (node.auth == "1") and { + { + username = node.username, + password = node.password + } + } or nil, + tls = (node.tls == "1") and tls or nil, + } + end + + if node.protocol == "shadowsocks" then + protocol_table = { + method = node.method, + password = node.password, + multiplex = mux, + } + end + + if node.protocol == "vmess" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + uuid = node.uuid[i], + alterId = 0, + } + end + protocol_table = { + users = users, + tls = (node.tls == "1") and tls or nil, + multiplex = mux, + transport = v2ray_transport, + } + end + end + + if node.protocol == "vless" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + uuid = node.uuid[i], + flow = node.flow, + } + end + protocol_table = { + users = users, + tls = (node.tls == "1") and tls or nil, + multiplex = mux, + transport = v2ray_transport, + } + end + end + + if node.protocol == "trojan" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + password = node.uuid[i], + } + end + protocol_table = { + users = users, + tls = (node.tls == "1") and tls or nil, + fallback = nil, + fallback_for_alpn = nil, + multiplex = mux, + transport = v2ray_transport, + } + end + end + + if node.protocol == "naive" then + protocol_table = { + users = { + { + username = node.username, + password = node.password + } + }, + tls = tls, + } + end + + if node.protocol == "hysteria" then + protocol_table = { + up = node.hysteria_up_mbps .. " Mbps", + down = node.hysteria_down_mbps .. " Mbps", + up_mbps = tonumber(node.hysteria_up_mbps), + down_mbps = tonumber(node.hysteria_down_mbps), + obfs = node.hysteria_obfs, + users = { + { + name = "user1", + auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil, + auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil, + } + }, + recv_window_conn = node.hysteria_recv_window_conn and tonumber(node.hysteria_recv_window_conn) or nil, --1.14 to stream_receive_window + recv_window_client = node.hysteria_recv_window_client and tonumber(node.hysteria_recv_window_client) or nil, --1.14 to connection_receive_window + max_conn_client = node.hysteria_max_conn_client and tonumber(node.hysteria_max_conn_client) or nil, --1.14 to max_concurrent_streams + disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false, --1.14 to disable_path_mtu_discover + tls = tls + } + end + + if node.protocol == "tuic" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + uuid = node.uuid[i], + password = node.password + } + end + tls.alpn = (node.tuic_alpn and node.tuic_alpn ~= "default") and (function() + local alpn = {} + string.gsub(node.tuic_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then return alpn end + return nil + end)() or nil + protocol_table = { + users = users, + congestion_control = node.tuic_congestion_control or "cubic", + zero_rtt_handshake = (node.tuic_zero_rtt_handshake == "1") and true or false, + heartbeat = (tonumber(node.tuic_heartbeat) or 3) .. "s", + tls = tls + } + end + end + + if node.protocol == "hysteria2" then + protocol_table = { + up_mbps = (node.hysteria2_ignore_client_bandwidth ~= "1" and node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil, + down_mbps = (node.hysteria2_ignore_client_bandwidth ~= "1" and node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil, + obfs = node.hysteria2_obfs_type and { + type = node.hysteria2_obfs_type, + password = node.hysteria2_obfs_password + } or nil, + users = { + { + name = "user1", + password = node.hysteria2_auth_password or nil, + } + }, + ignore_client_bandwidth = (node.hysteria2_ignore_client_bandwidth == "1") and true or false, + tls = tls, + realm = node.hysteria2_realms and (function() + local realm = api.parse_realm_uri(node.hysteria2_realm_url) + if realm then + realm.server_url = realm.server_url and "https://" .. realm.server_url or nil + realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun + realm.stun_domain_resolver = "direct" + return realm + end + return nil + end)() or nil + } + end + + if node.protocol == "anytls" then + protocol_table = { + users = { + { + name = (node.username and node.username ~= "") and node.username or "sekai", + password = node.password + } + }, + tls = tls, + } + end + + if node.protocol == "direct" then + protocol_table = { + network = (node.d_protocol ~= "TCP,UDP") and node.d_protocol or nil, + override_address = node.d_address, + override_port = tonumber(node.d_port) + } + end + + if protocol_table then + for key, value in pairs(protocol_table) do + inbound[key] = value + end + end + + local route = { + rules = { + { + ip_is_private = true, + action = node.accept_lan == "1" and "route" or "reject", + outbound = node.accept_lan == "1" and "direct" or nil + + } + } + } + + if node.outbound_node then + local outbound = nil + if node.outbound_node == "_iface" and node.outbound_node_iface then + outbound = { + type = "direct", + tag = "outbound", + bind_interface = node.outbound_node_iface, + routing_mark = 255, + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface)) + else + local outbound_node_t = uci:get_all("passwall", node.outbound_node) + if node.outbound_node == "_socks" or node.outbound_node == "_http" then + outbound_node_t = { + type = node.type, + protocol = node.outbound_node:gsub("_", ""), + address = node.outbound_node_address, + port = tonumber(node.outbound_node_port), + username = (node.outbound_node_username and node.outbound_node_username ~= "") and node.outbound_node_username or nil, + password = (node.outbound_node_password and node.outbound_node_password ~= "") and node.outbound_node_password or nil, + } + end + outbound = require("luci.passwall.util_sing-box").gen_outbound(nil, outbound_node_t, "outbound") + end + if outbound then + route.final = outbound.tag + table.insert(outbounds, 1, outbound) + end + end + + local config = { + log = { + disabled = (not node or node.log == "0") and true or false, + level = node.loglevel or "info", + timestamp = true, + --output = logfile, + }, + dns = { + servers = {{ + type = "local", + tag = "direct" + }} + }, + inbounds = { inbound }, + outbounds = outbounds, + route = route + } + + for index, value in ipairs(config.outbounds) do + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + end + + return config +end + +function gen_config(var) + local flag = var["flag"] + local log = var["log"] or "0" + local loglevel = var["loglevel"] or "warn" + local logfile = var["logfile"] or "/dev/null" + local node_id = var["node"] + local server_host = var["server_host"] + local server_port = var["server_port"] + local tcp_proxy_way = var["tcp_proxy_way"] + local tcp_redir_port = var["tcp_redir_port"] + local udp_redir_port = var["udp_redir_port"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local dns_listen_port = var["dns_listen_port"] + local direct_dns_port = var["direct_dns_port"] + local direct_dns_udp_server = var["direct_dns_udp_server"] + local direct_dns_tcp_server = var["direct_dns_tcp_server"] + local direct_dns_query_strategy = var["direct_dns_query_strategy"] + local remote_dns_udp_server = var["remote_dns_udp_server"] + local remote_dns_udp_port = var["remote_dns_udp_port"] + local remote_dns_tcp_server = var["remote_dns_tcp_server"] + local remote_dns_tcp_port = var["remote_dns_tcp_port"] + local remote_dns_doh = var["remote_dns_doh"] + local remote_dns_http3 = var["remote_dns_http3"] + local remote_dns_client_ip = var["remote_dns_client_ip"] + local remote_dns_query_strategy = var["remote_dns_query_strategy"] + local remote_dns_fake = var["remote_dns_fake"] + local dns_cache = var["dns_cache"] + local dns_socks_address = var["dns_socks_address"] + local dns_socks_port = var["dns_socks_port"] + local no_run = var["no_run"] + + local dns_domain_rules = {} + local dns = nil + local inbounds = {} + local outbounds = {} + local rule_set_table = {} + local COMMON = {} + + local singbox_settings = uci:get_all(appname, "@global_singbox[0]") or {} + + local route = { + rules = {} + } + + local experimental = nil + + function add_rule_set(tab) + if tab and next(tab) and tab.tag and not rule_set_table[tab.tag]then + rule_set_table[tab.tag] = tab + end + end + + function parse_rule_set(w, rs) + -- Format: remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-netflix.srs' + -- Format: local:/usr/share/sing-box/geosite-netflix.srs' + local result = nil + if w and #w > 0 then + if w:find("local:") == 1 or w:find("remote:") == 1 then + local _type = w:sub(1, w:find(":") - 1) -- "local" or "remote" + w = w:sub(w:find(":") + 1, #w) + local format = nil + local filename = w:sub(-w:reverse():find("/") + 1) -- geosite-netflix.srs + local suffix = "" + local find_doc = filename:reverse():find("%.") + if find_doc then + suffix = filename:sub(-find_doc + 1) -- "srs" or "json" + end + if suffix == "srs" then + format = "binary" + elseif suffix == "json" then + format = "source" + end + if format then + local rule_set_tag = filename:sub(1, filename:find("%.") - 1) --geosite-netflix + if rule_set_tag and #rule_set_tag > 0 then + if rs then + rule_set_tag = "rs_" .. rule_set_tag + end + result = { + type = _type, + tag = rule_set_tag, + format = format, + path = _type == "local" and w or nil, + url = _type == "remote" and w or nil, + --download_detour = _type == "remote" and "", + --update_interval = _type == "remote" and "", + } + end + end + end + end + return result + end + + function geo_rule_set(prefix, rule_name) + local output_srs_file = "local:" .. GEO_VAR.TO_SRS_PATH .. prefix .. "-" .. rule_name .. ".srs" + return parse_rule_set(output_srs_file) + end + + if node_id then + local node = uci:get_all(appname, node_id) + if node then + if server_host and server_port then + node.address = server_host + node.port = server_port + end + end + + if local_socks_port then + local inbound = { + type = "socks", + tag = "socks-in", + listen = local_socks_address, + listen_port = tonumber(local_socks_port), + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.users = { + { + username = local_socks_username, + password = local_socks_password + } + } + end + table.insert(inbounds, inbound) + table.insert(route.rules, { + action = "sniff", + inbound = inbound.tag + }) + end + + if local_http_port then + local inbound = { + type = "http", + tag = "http-in", + listen = local_http_address, + listen_port = tonumber(local_http_port) + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.users = { + { + username = local_http_username, + password = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if tcp_redir_port then + local inbound + if tcp_proxy_way ~= "tproxy" then + inbound = { + type = "redirect", + tag = "redirect_tcp", + listen = "::", + listen_port = tonumber(tcp_redir_port) + } + else + inbound = { + type = "tproxy", + tag = "tproxy_tcp", + network = "tcp", + listen = "::", + listen_port = tonumber(tcp_redir_port) + } + end + table.insert(inbounds, inbound) + table.insert(route.rules, { + action = "sniff", + inbound = inbound.tag + }) + end + + if udp_redir_port then + local inbound = { + type = "tproxy", + tag = "tproxy_udp", + network = "udp", + listen = "::", + listen_port = tonumber(udp_redir_port) + } + table.insert(inbounds, inbound) + table.insert(route.rules, { + action = "sniff", + inbound = inbound.tag + }) + end + + function gen_socks_config_node(node_id, socks_id, remarks) + if node_id then + socks_id = node_id:sub(1 + #"Socks_") + end + local result + local socks_node = uci:get_all(appname, socks_id) or nil + if socks_node then + if not remarks then + remarks = socks_node.port + end + result = { + [".name"] = "Socksid_" .. socks_id, + remarks = remarks, + type = "sing-box", + protocol = "socks", + address = "127.0.0.1", + port = socks_node.port, + uot = "1" + } + end + return result + end + + local nodes_list = {} + function get_urltest_batch_nodes(_node) + if #nodes_list == 0 then + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then + nodes_list[#nodes_list + 1] = { + id = e[".name"], + remarks = e["remarks"], + group = e["group"] + } + end + end + end + if not _node.node_group or _node.node_group == "" then return {} end + local nodes = {} + for g in _node.node_group:gmatch("%S+") do + g = api.UrlDecode(g) + for k, v in pairs(nodes_list) do + local gn = (v.group and v.group ~= "") and v.group or "default" + if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then + nodes[#nodes + 1] = v.id + end + end + end + return nodes + end + + function get_node_by_id(node_id) + if not node_id or node_id == "" or node_id == "nil" then return nil end + if node_id:find("Socks_") then + return gen_socks_config_node(node_id) + else + return uci:get_all(appname, node_id) + end + end + + function gen_urltest_outbound(_node) + local urltest_id = _node[".name"] + local urltest_tag = "urltest-" .. urltest_id + -- existing urltest + for _, v in ipairs(outbounds) do + if v.tag == urltest_tag then + return v, true + end + end + -- new urltest + local ut_nodes + if _node.node_add_mode and _node.node_add_mode == "batch" then + ut_nodes = get_urltest_batch_nodes(_node) + else + ut_nodes = _node.urltest_node + end + + api.log(" - 加载 Sing-Box URLTest 节点ã€" .. (_node.remarks or "") .. "】,å­èŠ‚ç‚¹æ•°é‡ï¼š" .. #(ut_nodes or {})) + + local valid_nodes = {} + for i = 1, #(ut_nodes or {}) do + local ut_node_id = ut_nodes[i] + local ut_node_tag = "ut-" .. ut_node_id + local is_new_ut_node = true + for _, outbound in ipairs(outbounds) do + if string.sub(outbound.tag, 1, #ut_node_tag) == ut_node_tag then + is_new_ut_node = false + valid_nodes[#valid_nodes + 1] = outbound.tag + break + end + end + if is_new_ut_node then + local outboundTag = gen_outbound_get_tag(flag, ut_node_id, ut_node_tag, { fragment = singbox_settings.fragment == "1" or nil, record_fragment = singbox_settings.record_fragment == "1" or nil, run_socks_instance = not no_run }) + if outboundTag then + valid_nodes[#valid_nodes + 1] = outboundTag + end + end + end + if #valid_nodes == 0 then return nil end + local outbound = { + type = "urltest", + tag = urltest_tag, + outbounds = valid_nodes, + url = _node.urltest_url or "https://www.gstatic.com/generate_204", + interval = (api.format_go_time(_node.urltest_interval) ~= "0s") and api.format_go_time(_node.urltest_interval) or "3m", + tolerance = (_node.urltest_tolerance and tonumber(_node.urltest_tolerance) > 0) and tonumber(_node.urltest_tolerance) or 50, + idle_timeout = (api.format_go_time(_node.urltest_idle_timeout) ~= "0s") and api.format_go_time(_node.urltest_idle_timeout) or "30m", + interrupt_exist_connections = (_node.urltest_interrupt_exist_connections == "true" or _node.urltest_interrupt_exist_connections == "1") and true or false + } + return outbound + end + + function set_outbound_detour(node, outbound, outbounds_table) + if not node or not outbound or not outbounds_table then return nil end + local default_outTag = outbound.tag + local last_insert_outbound + + if node.shadowtls == "1" then + local _node = { + type = "sing-box", + protocol = "shadowtls", + shadowtls_version = node.shadowtls_version, + password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil, + address = node.address, + port = node.port, + tls = "1", + tls_serverName = node.shadowtls_serverName, + utls = node.shadowtls_utls, + fingerprint = node.shadowtls_fingerprint + } + local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls") + if shadowtls_outbound then + last_insert_outbound = shadowtls_outbound + outbound.detour = outbound.tag .. "_shadowtls" + outbound.server = nil + outbound.server_port = nil + end + end + + if node.chain_proxy == "1" and node.preproxy_node then + if outbound["_flag_proxy_tag"] then + --Ignore + else + local preproxy_node = get_node_by_id(node.preproxy_node) + if preproxy_node then + local preproxy_outbound, exist + if preproxy_node.protocol == "_urltest" then + preproxy_outbound, exist = gen_urltest_outbound(preproxy_node) + else + preproxy_outbound = gen_outbound(node[".name"], preproxy_node) + end + if preproxy_outbound then + outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag + outbound.detour = preproxy_outbound.tag + if not exist then + last_insert_outbound = preproxy_outbound + end + default_outTag = outbound.tag + end + end + end + end + if node.chain_proxy == "2" and node.to_node then + local to_node = get_node_by_id(node.to_node) + if to_node then + -- Landing Node not support use special node. + if to_node.protocol:find("^_") then + to_node = nil + end + end + if to_node then + local to_outbound + if to_node.type ~= "sing-box" then + local tag = to_node[".name"] + local new_port = api.get_new_port() + table.insert(inbounds, { + type = "direct", + tag = tag, + listen = "127.0.0.1", + listen_port = new_port, + override_address = to_node.address, + override_port = tonumber(to_node.port), + }) + table.insert(rules, 1, { + action = "route", + inbound = {tag}, + outbound = outbound.tag, + }) + if to_node.tls_serverName == nil then + to_node.tls_serverName = to_node.address + end + to_node.address = "127.0.0.1" + to_node.port = new_port + to_outbound = gen_outbound(node[".name"], to_node, tag, { + tag = tag, + run_socks_instance = not no_run + }) + else + to_outbound = gen_outbound(node[".name"], to_node) + end + if to_outbound then + to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag + if to_node.type == "sing-box" then + to_outbound.detour = outbound.tag + end + table.insert(outbounds_table, to_outbound) + default_outTag = to_outbound.tag + end + end + end + if node.chain_proxy == "3" and node.outbound_iface then + outbound.detour = nil + outbound.bind_interface = node.outbound_iface + end + return default_outTag, last_insert_outbound + end + + function gen_outbound_get_tag(flag, node_id, tag, proxy_table) + if not node_id or node_id == "nil" then return nil end + local node + if type(node_id) == "string" then + node = get_node_by_id(node_id) + elseif type(node_id) == "table" then + node = node_id + end + if not tag then tag = node[".name"] end + if node then + if proxy_table.chain_proxy == "1" or proxy_table.chain_proxy == "2" then + node.chain_proxy = proxy_table.chain_proxy + node.preproxy_node = proxy_table.chain_proxy == "1" and proxy_table.preproxy_node + node.to_node = proxy_table.chain_proxy == "2" and proxy_table.to_node + proxy_table.chain_proxy = nil + proxy_table.preproxy_node = nil + proxy_table.to_node = nil + end + local outbound, exist + if node.protocol == "_urltest" then + outbound, exist = gen_urltest_outbound(node) + if exist then + return outbound.tag + end + elseif node.protocol == "_iface" then + if node.iface then + outbound = { + tag = tag, + type = "direct", + bind_interface = node.iface, + routing_mark = 255, + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) + end + else + for _, _outbound in ipairs(outbounds) do + -- Avoid generating duplicate nested processes + if _outbound["_flag_proxy_tag"] and _outbound["_flag_proxy_tag"]:find("socks <- " .. node[".name"], 1, true) then + outbound = api.clone(_outbound) + outbound.tag = tag + break + end + end + if not outbound then + outbound = gen_outbound(flag, node, tag, proxy_table) + end + end + if outbound then + local default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) + table.insert(outbounds, outbound) + if last_insert_outbound then + table.insert(outbounds, last_insert_outbound) + end + return default_outbound_tag + end + end + end + + rules = {} + + if node and node.protocol == "_shunt" then + inner_fakedns = node.fakedns or "0" + + local function gen_shunt_node(rule_name, _node_id) + if not rule_name then return nil, nil end + if not _node_id then _node_id = node[rule_name] end + if _node_id == "_direct" then + return "direct" + elseif _node_id == "_blackhole" then + return "block" + elseif _node_id == "_default" and rule_name ~= "default" then + return "default" + elseif _node_id then + local proxy_table = { + fragment = singbox_settings.fragment == "1", + record_fragment = singbox_settings.record_fragment == "1", + run_socks_instance = not no_run, + } + local preproxy_node_id = node[rule_name .. "_proxy_tag"] + if preproxy_node_id == _node_id then preproxy_node_id = nil end + if preproxy_node_id then + proxy_table.chain_proxy = "2" + proxy_table.to_node = _node_id + return gen_outbound_get_tag(flag, preproxy_node_id, rule_name, proxy_table) + else + return gen_outbound_get_tag(flag, _node_id, rule_name, proxy_table) + end + end + return nil + end + + --default_node + local default_node_id = node.default_node or "_direct" + COMMON.default_outbound_tag = gen_shunt_node("default", default_node_id) + + if inner_fakedns == "1" and node["default_fakedns"] == "1" then + remote_dns_fake = true + end + + --shunt rule + uci:foreach(appname, "shunt_rules", function(e) + local outboundTag = gen_shunt_node(e[".name"]) + if outboundTag and e.remarks then + if outboundTag == "default" then + outboundTag = COMMON.default_outbound_tag + end + local protocols = nil + if e["protocol"] and e["protocol"] ~= "" then + protocols = {} + string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) + table.insert(protocols, w) + end) + end + + local inboundTag = nil + if e["inbound"] and e["inbound"] ~= "" then + inboundTag = {} + if e["inbound"]:find("tproxy") then + if tcp_redir_port then + if tcp_proxy_way == "tproxy" then + table.insert(inboundTag, "tproxy_tcp") + else + table.insert(inboundTag, "redirect_tcp") + end + end + if udp_redir_port then + table.insert(inboundTag, "tproxy_udp") + end + end + if e["inbound"]:find("socks") then + if local_socks_port then + table.insert(inboundTag, "socks-in") + end + end + end + + local rule = { + action = "route", + inbound = inboundTag, + outbound = outboundTag, + protocol = protocols + } + + if outboundTag == "block" then + rule.action = "reject" + rule.outbound = nil + end + + if e.network then + local network = {} + string.gsub(e.network, '[^' .. "," .. ']+', function(w) + table.insert(network, w) + end) + rule.network = network + end + + if e.source then + local source_ip_cidr = {} + local is_private = false + string.gsub(e.source, '[^' .. " " .. ']+', function(w) + if w:find("geoip") == 1 then + local _geoip = w:sub(1 + #"geoip:") --适é…srs + if _geoip == "private" then + is_private = true + end + else + table.insert(source_ip_cidr, w) + end + end) + rule.source_ip_is_private = is_private and true or nil + rule.source_ip_cidr = #source_ip_cidr > 0 and source_ip_cidr or nil + if is_private or #source_ip_cidr > 0 then rule.rule_set_ip_cidr_match_source = true end + end + + --[[ + -- Too low usage rate, hidden + if e.sourcePort then + local source_port = {} + local source_port_range = {} + string.gsub(e.sourcePort, '[^' .. "," .. ']+', function(w) + if tonumber(w) and tonumber(w) >= 1 and tonumber(w) <= 65535 then + table.insert(source_port, tonumber(w)) + else + table.insert(source_port_range, w) + end + end) + rule.source_port = #source_port > 0 and source_port or nil + rule.source_port_range = #source_port_range > 0 and source_port_range or nil + end + ]]-- + + if e.port then + local port = {} + local port_range = {} + string.gsub(e.port, '[^' .. "," .. ']+', function(w) + if tonumber(w) and tonumber(w) >= 1 and tonumber(w) <= 65535 then + table.insert(port, tonumber(w)) + else + table.insert(port_range, w) + end + end) + rule.port = #port > 0 and port or nil + rule.port_range = #port_range > 0 and port_range or nil + end + + local rule_set = {} + + if e.domain_list then + local domain_table = { + shunt_tag = e[".name"], + outboundTag = outboundTag, + domain = {}, + domain_suffix = {}, + domain_keyword = {}, + domain_regex = {}, + rule_set = {}, + fakedns = nil, + invert = e.invert == "1" and true or nil + } + string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("geosite:") == 1 then + local _geosite = w:sub(1 + #"geosite:") --适é…srs + local t = geo_rule_set("geosite", _geosite) + if t then + GEO_VAR.SITE_TAGS[_geosite] = true + add_rule_set(t) + table.insert(rule_set, t.tag) + table.insert(domain_table.rule_set, t.tag) + end + elseif w:find("regexp:") == 1 then + table.insert(domain_table.domain_regex, w:sub(1 + #"regexp:")) + elseif w:find("full:") == 1 then + table.insert(domain_table.domain, w:sub(1 + #"full:")) + elseif w:find("domain:") == 1 then + table.insert(domain_table.domain_suffix, w:sub(1 + #"domain:")) + elseif w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then + w = w:sub(w:find(":") + 1, #w) + local t = parse_rule_set(w, true) + if t then + add_rule_set(t) + table.insert(rule_set, t.tag) + table.insert(domain_table.rule_set, t.tag) + end + else + table.insert(domain_table.domain_keyword, w) + end + end) + rule.domain = #domain_table.domain > 0 and domain_table.domain or nil + rule.domain_suffix = #domain_table.domain_suffix > 0 and domain_table.domain_suffix or nil + rule.domain_keyword = #domain_table.domain_keyword > 0 and domain_table.domain_keyword or nil + rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil + rule.rule_set = #domain_table.rule_set > 0 and domain_table.rule_set or nil + if inner_fakedns == "1" and node[e[".name"] .. "_fakedns"] == "1" then + domain_table.fakedns = true + end + + if outboundTag then + table.insert(dns_domain_rules, api.clone(domain_table)) + end + end + + if e.ip_list then + local ip_cidr = {} + local is_private = false + string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("geoip:") == 1 then + local _geoip = w:sub(1 + #"geoip:") --适é…srs + if _geoip == "private" then + is_private = true + else + local t = geo_rule_set("geoip", _geoip) + if t then + GEO_VAR.IP_TAGS[_geoip] = true + add_rule_set(t) + table.insert(rule_set, t.tag) + end + end + elseif w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then + w = w:sub(w:find(":") + 1, #w) + local t = parse_rule_set(w, true) + if t then + add_rule_set(t) + table.insert(rule_set, t.tag) + end + else + table.insert(ip_cidr, w) + end + end) + + rule.ip_is_private = is_private and true or nil + rule.ip_cidr = #ip_cidr > 0 and ip_cidr or nil + end + + rule.rule_set = #rule_set > 0 and rule_set or nil --适é…srs + rule.invert = e.invert == "1" and true or nil + + table.insert(rules, rule) + end + end) + else + COMMON.default_outbound_tag = gen_outbound_get_tag(flag, node or node_id, nil, { + fragment = singbox_settings.fragment == "1" or nil, + record_fragment = singbox_settings.record_fragment == "1" or nil, + run_socks_instance = not no_run + }) + end + + for index, value in ipairs(rules) do + table.insert(route.rules, rules[index]) + end + end + + if COMMON.default_outbound_tag then + route.final = COMMON.default_outbound_tag + end + + if dns_listen_port then + dns = { + servers = {}, + rules = {}, + disable_cache = (dns_cache and dns_cache == "0") and true or false, + disable_expire = false, --ç¦ç”¨ DNS 缓存过期。 + independent_cache = false, --使æ¯ä¸ª DNS æœåŠ¡å™¨çš„ç¼“å­˜ç‹¬ç«‹ï¼Œä»¥æ»¡è¶³ç‰¹æ®Šç›®çš„ã€‚å¦‚æžœå¯ç”¨ï¼Œå°†è½»å¾®é™ä½Žæ€§èƒ½ã€‚ + reverse_mapping = true, --在å“应 DNS 查询åŽå­˜å‚¨ IP 地å€çš„å呿˜ å°„以为路由目的æä¾›åŸŸå。 + } + + local default_outTag = COMMON.default_outbound_tag + + if dns_socks_address and dns_socks_port then + default_outTag = "dns_socks_out" + table.insert(outbounds, 1, { + type = "socks", + tag = default_outTag, + server = dns_socks_address, + server_port = tonumber(dns_socks_port) + }) + end + + remote_strategy = "prefer_ipv6" + if remote_dns_query_strategy == "UseIPv4" then + remote_strategy = "ipv4_only" + elseif remote_dns_query_strategy == "UseIPv6" then + remote_strategy = "ipv6_only" + end + + local remote_server = { + tag = "remote", + domain_resolver = "direct", + detour = default_outTag, + } + + if remote_dns_udp_server then + local server_port = tonumber(remote_dns_udp_port) or 53 + remote_server.type = "udp" + remote_server.server = remote_dns_udp_server + remote_server.server_port = server_port + + elseif remote_dns_tcp_server then + local server_port = tonumber(remote_dns_tcp_port) or 53 + remote_server.type = "tcp" + remote_server.server = remote_dns_tcp_server + remote_server.server_port = server_port + + elseif remote_dns_doh then + local _a = api.parseDoH(remote_dns_doh) + if _a then + remote_server.type = "https" + if remote_dns_http3 then + remote_server.type = "h3" + end + remote_server.server = _a.hostname + remote_server.server_port = _a.port or 443 + remote_server.path = _a.pathname or "" + + if api.datatypes.hostname(_a.hostname) then + if _a.hostip then + if not hosts_predefined then hosts_predefined = {} end + hosts_predefined[_a.hostname] = _a.hostip + remote_server_domain_resolver = "hosts" + else + GLOBAL.DNS_HOSTNAME[_a.hostname] = true + remote_server_domain_resolver = "direct" + end + end + end + end + + if api.is_local_ip(remote_server.server) then --dns为本地ip,ä¸èµ°ä»£ç† + remote_server.detour = "direct" + end + + if remote_server_domain_resolver then + remote_server.domain_resolver = remote_server_domain_resolver + end + + table.insert(dns.servers, remote_server) + + fakedns_tag = "remote_fakeip" + if remote_dns_fake or inner_fakedns == "1" then + table.insert(dns.servers, { + tag = fakedns_tag, + type = "fakeip", + inet4_range = "198.18.0.0/15", + inet6_range = "fc00::/18", + }) + + if not experimental then + experimental = {} + end + experimental.cache_file = { + enabled = true, + store_fakeip = true, + path = api.CACHE_PATH .. "/singbox_" .. flag .. ".db" + } + end + + if direct_dns_udp_server or direct_dns_tcp_server then + local domain = {} + local nodes_domain_text = sys.exec([[uci show passwall | sed -n "s/.*\.address='\([^']*\)'/\1/p" | sort -u]]) + string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) + w = (w or ""):lower() + if not api.vps_domain_exclude(w) and api.datatypes.hostname(w) and not GLOBAL.VPS_EXCLUDE[w] then + table.insert(domain, w) + end + end) + if #domain > 0 then + table.insert(dns_domain_rules, 1, { + outboundTag = "direct", + domain = domain + }) + end + + direct_strategy = "prefer_ipv6" + if direct_dns_query_strategy == "UseIPv4" then + direct_strategy = "ipv4_only" + elseif direct_dns_query_strategy == "UseIPv6" then + direct_strategy = "ipv6_only" + end + + local direct_dns_server, port, type + if direct_dns_udp_server then + port = tonumber(direct_dns_port) or 53 + direct_dns_server = direct_dns_udp_server + type = "udp" + elseif direct_dns_tcp_server then + port = tonumber(direct_dns_port) or 53 + direct_dns_server = direct_dns_tcp_server + type = "tcp" + end + + table.insert(dns.servers, { + tag = "direct", + type = type, + server = direct_dns_server, + server_port = port, + detour = "direct", + }) + end + + local default_dns_flag = "remote" + if dns_socks_address and dns_socks_port then + else + if node_id and (tcp_redir_port or udp_redir_port) then + local node = get_node_by_id(node_id) + if node.protocol == "_shunt" then + if node.default_node == "_direct" then + default_dns_flag = "direct" + end + end + else default_dns_flag = "direct" + end + end + if default_dns_flag == "remote" then + if remote_dns_fake then + table.insert(dns.rules, { + query_type = { "A", "AAAA" }, + server = fakedns_tag, + disable_cache = true, + rewrite_ttl = 30, + strategy = remote_strategy + }) + end + end + dns.final = default_dns_flag + + --按分æµé¡ºåºDNS + if dns_domain_rules and #dns_domain_rules > 0 then + for index, value in ipairs(dns_domain_rules) do + if value.outboundTag and (value.domain or value.domain_suffix or value.domain_keyword or value.domain_regex or value.rule_set) then + local dns_rule = { + action = "route", + server = value.outboundTag, + domain = (value.domain and #value.domain > 0) and value.domain or nil, + domain_suffix = (value.domain_suffix and #value.domain_suffix > 0) and value.domain_suffix or nil, + domain_keyword = (value.domain_keyword and #value.domain_keyword > 0) and value.domain_keyword or nil, + domain_regex = (value.domain_regex and #value.domain_regex > 0) and value.domain_regex or nil, + rule_set = (value.rule_set and #value.rule_set > 0) and value.rule_set or nil, --适é…srs + disable_cache = false, + invert = value.invert, + } + if value.outboundTag == "block" then + dns_rule.action = "predefined" + dns_rule.rcode = "NOERROR" + dns_rule.server = nil + dns_rule.disable_cache = nil + end + if value.outboundTag == "direct" then + dns_rule.strategy = direct_strategy + end + if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then + dns_rule.server = "remote" + dns_rule.rewrite_ttl = 30 + dns_rule.strategy = remote_strategy + dns_rule.client_subnet = remote_dns_client_ip + if value.outboundTag ~= COMMON.default_outbound_tag and (remote_server.address or remote_server.server) then + local remote_dns_server = api.clone(remote_server) + remote_dns_server.tag = value.shunt_tag + local is_local = (remote_server.address and api.is_local_ip(remote_server.address)) or + (remote_server.server and api.is_local_ip(remote_server.server)) --dns为本地ip,ä¸èµ°ä»£ç† + remote_dns_server.detour = is_local and "direct" or value.outboundTag + table.insert(dns.servers, remote_dns_server) + dns_rule.server = remote_dns_server.tag + end + if value.fakedns then + local fakedns_dns_rule = api.clone(dns_rule) + fakedns_dns_rule.query_type = { + "A", "AAAA" + } + fakedns_dns_rule.server = fakedns_tag + fakedns_dns_rule.disable_cache = true + table.insert(dns.rules, fakedns_dns_rule) + end + end + table.insert(dns.rules, dns_rule) + end + end + end + local dns_in_inbound = { + type = "direct", + tag = "dns-in", + listen = "127.0.0.1", + listen_port = tonumber(dns_listen_port), + } + table.insert(inbounds, dns_in_inbound) + table.insert(route.rules, { + action = "sniff", + inbound = dns_in_inbound.tag + }) + table.insert(route.rules, 1, { + action = "hijack-dns", + inbound = dns_in_inbound.tag + }) + end + + if not dns then + dns = { + servers = {{ + type = "local", + tag = "direct" + }} + } + end + + route.default_domain_resolver = { + server = "direct" + } + + if not dns.rules then dns.rules = {} end + + for i, v in pairs(GLOBAL.DNS_SERVER) do + table.insert(dns.servers, v.server) + table.insert(dns.rules, 1, { + action = "route", + server = v.server.tag, + disable_cache = false, + domain = v.domain, + }) + end + if next(GLOBAL.DNS_HOSTNAME) then + local hostname = {} + for line, _ in pairs(GLOBAL.DNS_HOSTNAME) do + table.insert(hostname, line) + end + table.insert(dns.rules, 1, { + query_type = { "A", "AAAA" }, + domain = hostname, + server = "direct" + }) + end + + if next(ech_domain) ~= nil then + table.insert(dns.servers, { + tag = "ech-dns", + type = "https", + server = "223.5.5.5" + }) + local domain = {} + for line, _ in pairs(ech_domain) do domain[#domain+1] = line end + table.insert(dns.rules, 1, { + domain = domain, + server = "ech-dns" + }) + end + + table.insert(dns.servers, { + tag = "hosts", + type = "hosts", + predefined = (hosts_predefined and next(hosts_predefined) ~= nil) and hosts_predefined or nil + }) + if not version_ge_1_14_0 then + table.insert(dns.rules, 1, { + ip_accept_any = true, + server = "hosts" + }) + else + table.insert(dns.rules, 1, { + action = "evaluate", + server = "hosts" + }) + table.insert(dns.rules, 2, { + match_response = true, + ip_accept_any = true, + action = "respond" + }) + end + + if COMMON.default_outbound_tag == "block" then + route.final = nil + table.insert(route.rules, { + action = "reject" + }) + end + + if next(rule_set_table) then + route.rule_set = {} + for k, v in pairs(rule_set_table) do + table.insert(route.rule_set, v) + end + end + + if inbounds or outbounds then + local config = { + log = { + disabled = log == "0" and true or false, + level = loglevel, + timestamp = true, + output = logfile, + }, + -- DNS + dns = dns, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + -- 路由 + route = route, + --实验性 + experimental = experimental, + } + table.insert(outbounds, { + type = "direct", + tag = "direct", + routing_mark = 255, + }) + for index, value in ipairs(config.outbounds) do + if not value["_flag_proxy_tag"] and not value.detour and value["_id"] and value.server and (value.server_port or value.server_ports) and not no_run then + sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list")) + end + if not value.detour and not value.bind_interface and value.server then + value.detour = "direct" + end + if (value.server and not api.datatypes.hostname(value.server)) and not value.realm then + value.domain_resolver = nil + end + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + end + if true then + local endpoints = {} + for i = #config.outbounds, 1, -1 do + local value = config.outbounds[i] + if value.type == "wireguard" then + -- https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint + local endpoint = { + type = "wireguard", + tag = value.tag, + system = value.system_interface, + name = value.interface_name, + mtu = value.mtu, + address = value.local_address, + private_key = value.private_key, + peers = { + { + address = value.server, + port = value.server_port, + public_key = value.peer_public_key, + pre_shared_key = value.pre_shared_key, + allowed_ips = {"0.0.0.0/0"}, + reserved = value.reserved + } + }, + domain_resolver = { + server = "direct", + strategy = value.domain_strategy + }, + detour = value.detour + } + endpoints[#endpoints + 1] = endpoint + table.remove(config.outbounds, i) + end + end + if #endpoints > 0 then + config.endpoints = endpoints + end + end + return jsonc.stringify(config, 1) + end +end + +function gen_proto_config(var) + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local server_proto = var["server_proto"] + local server_address = var["server_address"] + local server_port = var["server_port"] + local server_username = var["server_username"] + local server_password = var["server_password"] + + local inbounds = {} + local outbounds = {} + + if local_socks_address and local_socks_port then + local inbound = { + type = "socks", + tag = "socks-in", + listen = local_socks_address, + listen_port = tonumber(local_socks_port), + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.users = { + username = local_socks_username, + password = local_socks_password + } + end + table.insert(inbounds, inbound) + end + + if local_http_address and local_http_port then + local inbound = { + type = "http", + tag = "http-in", + tls = nil, + listen = local_http_address, + listen_port = tonumber(local_http_port), + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.users = { + { + username = local_http_username, + password = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then + local outbound = { + type = server_proto, + tag = "out", + server = server_address, + server_port = tonumber(server_port), + username = (server_username and server_password) and server_username or nil, + password = (server_username and server_password) and server_password or nil, + } + if outbound then table.insert(outbounds, outbound) end + end + + local config = { + log = { + disabled = true, + level = "warn", + timestamp = true, + }, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + } + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config +_G.gen_proto_config = gen_proto_config +_G.geo_convert_srs = geo_convert_srs + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + if (next(GEO_VAR.SITE_TAGS) or next(GEO_VAR.IP_TAGS)) and not no_run then + convert_geofile() + end + end +end diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua new file mode 100644 index 00000000..edbe252c --- /dev/null +++ b/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -0,0 +1,2074 @@ +module("luci.passwall.util_xray", package.seeall) +local api = require "luci.passwall.api" +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local appname = "passwall" +local fs = api.fs + +local GLOBAL = { + DNS_SERVER = {}, + DNS_HOSTNAME = {}, + VPS_EXCLUDE = {} +} + +local xray_version = api.get_app_version("xray") + +local function get_domain_excluded() + local path = string.format("/usr/share/%s/rules/domains_excluded", appname) + local content = fs.readfile(path) + if not content then return nil end + local hosts = {} + string.gsub(content, '[^' .. "\n" .. ']+', function(w) + local s = api.trim(w) + if s == "" then return end + if s:find("#") and s:find("#") == 1 then return end + if not s:find("#") or s:find("#") ~= 1 then table.insert(hosts, s) end + end) + if #hosts == 0 then hosts = nil end + return hosts +end + +function gen_outbound(flag, node, tag, proxy_table) + local result = nil + if node then + local node_id = node[".name"] + if tag == nil then + tag = node_id + end + local remarks = node.remarks + + local proxy_tag = nil + local fragment = nil + local noise = nil + local run_socks_instance = true + if proxy_table ~= nil and type(proxy_table) == "table" then + proxy_tag = proxy_table.tag or nil + fragment = proxy_table.fragment or nil + noise = proxy_table.noise or nil + run_socks_instance = proxy_table.run_socks_instance + end + + if node.type ~= "Xray" then + if node.type == "Socks" then + node.protocol = "socks" + node.transport = "tcp" + else + local relay_port = node.port + local new_port = api.get_new_port() + local config_file = string.format("%s_%s_%s.json", flag, tag, new_port) + if tag and node_id and not tag:find(node_id) then + config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port) + end + if run_socks_instance then + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s", + new_port, --flag + node_id, --node + "127.0.0.1", --bind + new_port, --socks port + config_file, --config file + (proxy_tag and relay_port) and tostring(relay_port) or "" --relay port + ) + )) + end + node = {} + node.protocol = "socks" + node.transport = "tcp" + node.address = "127.0.0.1" + node.port = new_port + end + node.stream_security = "none" + proxy_tag = "socks <- " .. node_id + else + if proxy_tag then + node.proxySettings = { + tag = proxy_tag, + transportLayer = true + } + end + end + + if node.type == "Xray" then + if node.tls and node.tls == "1" then + node.stream_security = "tls" + if node.type == "Xray" and node.reality and node.reality == "1" then + node.stream_security = "reality" + end + end + end + + if node.protocol == "wireguard" and node.wireguard_reserved then + local bytes = {} + if not node.wireguard_reserved:match("[^%d,]+") then + node.wireguard_reserved:gsub("%d+", function(b) + bytes[#bytes + 1] = tonumber(b) + end) + else + local result = api.base64Decode(node.wireguard_reserved) + for i = 1, #result do + bytes[i] = result:byte(i) + end + end + node.wireguard_reserved = #bytes > 0 and bytes or nil + end + + if node.protocol == "hysteria2" then + node.protocol = "hysteria" + node.transport = "hysteria" + node.stream_security = "tls" + end + + if remarks then + tag = tag .. ":" .. remarks + end + + node.address = (node.address or ""):lower() + + result = { + _id = node_id, + _flag = flag, + _flag_proxy_tag = proxy_tag, + tag = tag, + proxySettings = node.proxySettings or nil, + protocol = node.protocol, + mux = { + enabled = (node.mux == "1") and true or false, + concurrency = (node.mux == "1" and ((node.mux_concurrency) and tonumber(node.mux_concurrency) or -1)) or nil, + xudpConcurrency = (node.mux == "1" and ((node.xudp_concurrency) and tonumber(node.xudp_concurrency) or 8)) or nil + } or nil, + -- 底层传输é…ç½® + streamSettings = (node.streamSettings or node.protocol == "vmess" or node.protocol == "vless" or node.protocol == "socks" or node.protocol == "shadowsocks" or node.protocol == "trojan" or node.protocol == "hysteria") and { + sockopt = { + mark = 255, + domainStrategy = node.domain_strategy or "UseIP", + tcpFastOpen = (node.tcp_fast_open == "1") and true or nil, + tcpMptcp = (node.tcpMptcp == "1") and true or nil + }, + network = node.transport, + security = node.stream_security, + tlsSettings = (node.stream_security == "tls") and { + serverName = node.tls_serverName, + allowInsecure = (function() + if node.tls_pinSHA256 and node.tls_pinSHA256 ~= "" then return nil end + if api.compare_versions(os.date("%Y.%m.%d"), "<", "2026.6.1") and node.tls_allowInsecure == "1" then return true end + end)(), + fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil, + pinnedPeerCertSha256 = (function() + if api.compare_versions(xray_version, "<", "26.1.31") then return nil end + if not node.tls_pinSHA256 then return "" end + return node.tls_pinSHA256 + end)(), + verifyPeerCertByName = (function() + if api.compare_versions(xray_version, "<", "26.1.31") then return nil end + if not node.tls_CertByName then return "" end + return node.tls_CertByName + end)(), + echConfigList = (node.ech == "1") and node.ech_config or nil + } or nil, + realitySettings = (node.stream_security == "reality") and { + serverName = node.tls_serverName, + publicKey = node.reality_publicKey, + shortId = node.reality_shortId or "", + spiderX = node.reality_spiderX or "/", + fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome", + mldsa65Verify = (node.use_mldsa65Verify == "1") and node.reality_mldsa65Verify or nil + } or nil, + rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and { + header = { + type = node.tcp_guise, + request = (node.tcp_guise == "http") and { + path = node.tcp_guise_http_path and (function() + local t, r = node.tcp_guise_http_path, {} + for _, v in ipairs(t) do + r[#r + 1] = (v == "" and "/" or v) + end + return r + end)() or {"/"}, + headers = (node.tcp_guise_http_host or node.user_agent) and { + Host = node.tcp_guise_http_host, + ["User-Agent"] = node.user_agent and {node.user_agent} or nil + } or nil + } or nil + } + } or nil, + kcpSettings = (node.transport == "mkcp") and { + mtu = (node.mkcp_mtu and node.mkcp_mtu ~= "") and tonumber(node.mkcp_mtu) or 1350, + tti = 50, + uplinkCapacity = 12, + downlinkCapacity = 100, + CwndMultiplier = 1, + MaxSendingWindow = 2 * 1024 * 1024 + } or nil, + wsSettings = (node.transport == "ws") and { + path = node.ws_path or "/", + host = node.ws_host, + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + maxEarlyData = tonumber(node.ws_maxEarlyData) or nil, + earlyDataHeaderName = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil, + heartbeatPeriod = tonumber(node.ws_heartbeatPeriod) or nil + } or nil, + grpcSettings = (node.transport == "grpc") and { + serviceName = node.grpc_serviceName, + multiMode = (node.grpc_mode == "multi") and true or false, + idle_timeout = node.grpc_idle_timeout and (tonumber(node.grpc_idle_timeout) < 10 and 10 or tonumber(node.grpc_idle_timeout)) or nil, + health_check_timeout = tonumber(node.grpc_health_check_timeout) or nil, + permit_without_stream = (node.grpc_permit_without_stream == "1") and true or false, + initial_windows_size = node.grpc_initial_windows_size and tonumber(node.grpc_initial_windows_size) or 0, + user_agent = node.user_agent + } or nil, + httpupgradeSettings = (node.transport == "httpupgrade") and { + path = node.httpupgrade_path or "/", + host = node.httpupgrade_host, + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil + } or nil, + xhttpSettings = (node.transport == "xhttp") and { + mode = node.xhttp_mode or "auto", + path = node.xhttp_path or "/", + host = node.xhttp_host, + extra = (function() + local extra = {} + if node.xhttp_extra then + local ok, parsed = pcall(jsonc.parse, api.base64Decode(node.xhttp_extra)) + if ok and type(parsed) == "table" then + extra = parsed.extra or parsed + end + end + -- å¤„ç† User-Agent + if node.user_agent and node.user_agent ~= "" then + extra.headers = extra.headers or {} + if not extra.headers["User-Agent"] and not extra.headers["user-agent"] then + extra.headers["User-Agent"] = node.user_agent + end + end + return api.cleanEmptyTables(extra) + end)() + } or nil, + hysteriaSettings = (node.transport == "hysteria") and { + version = 2, + auth = node.hysteria2_auth_password + } or nil, + finalmask = (function() + local finalmask = {} + local TP = node.transport + if TP == "mkcp" then + local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", + dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local udp = {} + if node.mkcp_guise and node.mkcp_guise ~= "none" then + local g = { type = map[node.mkcp_guise] } + if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then + g.settings = { domain = node.mkcp_domain } + end + udp[#udp+1] = g + end + local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + if node.mkcp_seed and node.mkcp_seed ~= "" then + c.settings = { password = node.mkcp_seed } + end + udp[#udp+1] = c + finalmask.udp = udp + elseif TP == "hysteria" then + if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then + finalmask.udp = {{ + type = node.hysteria2_obfs_type, + settings = node.hysteria2_obfs_password and { + password = node.hysteria2_obfs_password + } or nil + }} + end + local up = tonumber(node.hysteria2_up_mbps) or 0 + local down = tonumber(node.hysteria2_down_mbps) or 0 + finalmask.quicParams = { + congestion = (up <= 0 and down <= 0) and "bbr" or "brutal", + brutalUp = up > 0 and (up .. "mbps") or nil, + brutalDown = down > 0 and (down .. "mbps") or nil, + udpHop = (node.hysteria2_hop) and { + ports = string.gsub(node.hysteria2_hop, ":", "-"), + interval = (function(v) + if not v then return 30 end + if v:find("-", 1, true) then + local min, max = v:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + return min .. "-" .. max + end + return 30 + end + v = tonumber((v or "30"):match("^%d+")) + return (v and v >= 5) and v or 30 + end)(node.hysteria2_hop_interval) + } or nil, + maxIdleTimeout = (function(t) + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t or 30 + end)(node.hysteria2_idle_timeout), + keepAlivePeriod = (function(t) + t = tonumber(tostring(t or "0"):match("^%d+")) + return (t and t >= 2 and t <= 60) and t or nil + end)(node.hysteria2_keep_alive_period), + disablePathMTUDiscovery = tonumber(node.hysteria2_disable_mtu_discovery) == 1 + } + end + if fragment and fragment_table and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then + finalmask.tcp = finalmask.tcp or {} + finalmask.tcp[#finalmask.tcp+1] = api.clone(fragment_table) + end + if noise and noise_table and (TP == "mkcp" or (TP == "xhttp" and node.alpn == "h3")) then + finalmask.udp = finalmask.udp or {} + finalmask.udp[#finalmask.udp+1] = api.clone(noise_table) + end + if node.finalmask and node.finalmask ~= "" then + local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) + if ok and type(fm) == "table" then + finalmask = fm + end + end + return api.cleanEmptyTables(finalmask) + end)() + } or nil, + settings = { + vnext = (node.protocol == "vmess" or node.protocol == "vless") and { + { + address = node.address, + port = tonumber(node.port), + users = { + { + id = node.uuid, + level = 0, + security = (node.protocol == "vmess") and node.security or nil, + testpre = (node.protocol == "vless") and tonumber(node.preconns) or nil, + encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil, + flow = (node.protocol == "vless" + and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none")) + and node.flow and node.flow ~= "") and node.flow or nil + } + } + } + } or nil, + servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { + { + address = node.address, + port = tonumber(node.port), + method = (node.method == "chacha20-ietf-poly1305" and "chacha20-poly1305") or + (node.method == "xchacha20-ietf-poly1305" and "xchacha20-poly1305") or + (node.method ~= "" and node.method) or nil, + ivCheck = (node.protocol == "shadowsocks") and node.iv_check == "1" or nil, + uot = (node.protocol == "shadowsocks") and node.uot == "1" or nil, + password = node.password or "", + users = (node.username and node.password) and { + { + user = node.username, + pass = node.password + } + } or nil + } + } or nil, + address = (node.protocol == "wireguard" and node.wireguard_local_address) or (node.protocol == "hysteria" and node.address) or nil, + secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil, + peers = (node.protocol == "wireguard") and { + { + publicKey = node.wireguard_public_key, + endpoint = node.address .. ":" .. node.port, + preSharedKey = node.wireguard_preSharedKey, + keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil + } + } or nil, + mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil, + reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil, + port = (node.protocol == "hysteria" and node.port) and tonumber(node.port) or nil, + version = node.protocol == "hysteria" and 2 or nil + } + } + + if node.protocol == "wireguard" then + result.settings.kernelMode = false + end + + local alpn = {} + if node.alpn and node.alpn ~= "default" then + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + if alpn and #alpn > 0 then + if result.streamSettings.tlsSettings then + result.streamSettings.tlsSettings.alpn = alpn + end + end + + if api.datatypes.hostname(node.address) and node.domain_resolver and (node.domain_resolver_dns or node.domain_resolver_dns_https) then + local dns_proto = node.domain_resolver + local config_address + local config_port + if dns_proto == "https" then + local _a = api.parseDoH(node.domain_resolver_dns_https) + if _a then + config_address = _a.url + config_port = _a.port or 443 + if _a.hostname and api.datatypes.hostname(_a.hostname) then + GLOBAL.DNS_HOSTNAME[_a.hostname] = true + end + end + else + local server_address = node.domain_resolver_dns + config_port = 53 + local split = api.split(server_address, ":") + if #split > 1 then + server_address = split[1] + config_port = tonumber(split[#split]) + end + config_address = server_address + if dns_proto == "tcp" then + config_address = dns_proto .. "://" .. server_address .. ":" .. config_port + end + end + local dns_key = dns_proto .. "|" .. config_address .. "|" .. tostring(config_port) + if not GLOBAL.DNS_SERVER[dns_key] then + GLOBAL.DNS_SERVER[dns_key] = { + tag = "dns-node-" .. api.gen_short_uuid(), + -- queryStrategy = node.domain_strategy or "UseIP", + address = config_address, + port = config_port, + finalQuery = true, + disableCache = false, + serveStale = true, + domains = {} + } + end + local exists + local domain = "full:" .. node.address + for _, d in ipairs(GLOBAL.DNS_SERVER[dns_key].domains) do + if d == domain then exists = true; break end + end + if not exists then table.insert(GLOBAL.DNS_SERVER[dns_key].domains, domain) end + GLOBAL.VPS_EXCLUDE[node.address] = true + end + end + return result +end + +function gen_config_server(node) + local settings = nil + local routing = nil + local outbounds = { + { protocol = "freedom", tag = "direct", settings = { finalRules = {{ action = "allow" }}}}, { protocol = "blackhole", tag = "blocked" } + } + + if node.protocol == "vmess" or node.protocol == "vless" then + if node.uuid then + local clients = {} + for i = 1, #node.uuid do + clients[i] = { + id = node.uuid[i], + flow = (node.protocol == "vless" + and (node.tls == "1" or (node.decryption and node.decryption ~= "" and node.decryption ~= "none")) + and node.flow and node.flow ~= "") and node.flow or nil + } + end + settings = { + clients = clients, + decryption = (node.protocol == "vless") and ((node.decryption and node.decryption ~= "") and node.decryption or "none") or nil + } + end + elseif node.protocol == "socks" then + settings = { + udp = ("1" == node.udp_forward) and true or false, + auth = ("1" == node.auth) and "password" or "noauth", + accounts = ("1" == node.auth) and { + { + user = node.username, + pass = node.password + } + } or nil + } + elseif node.protocol == "http" then + settings = { + allowTransparent = false, + accounts = ("1" == node.auth) and { + { + user = node.username, + pass = node.password + } + } or nil + } + node.transport = "tcp" + node.tcp_guise = "none" + elseif node.protocol == "shadowsocks" then + settings = { + method = node.method, + password = node.password, + ivCheck = ("1" == node.iv_check) and true or false, + network = node.ss_network or "TCP,UDP" + } + elseif node.protocol == "trojan" then + if node.uuid then + local clients = {} + for i = 1, #node.uuid do + clients[i] = { + password = node.uuid[i], + } + end + settings = { + clients = clients + } + end + elseif node.protocol == "hysteria2" then + settings = { + version = 2, + clients = node.hysteria2_auth_password and { + { auth = node.hysteria2_auth_password } + } + } + elseif node.protocol == "dokodemo-door" then + settings = { + network = node.d_protocol, + address = node.d_address, + port = tonumber(node.d_port) + } + end + + if node.fallback and node.fallback == "1" then + local fallbacks = {} + for i = 1, #node.fallback_list do + local fallbackStr = node.fallback_list[i] + if fallbackStr then + local tmp = {} + string.gsub(fallbackStr, '[^,]+', function(w) + table.insert(tmp, w) + end) + local dest = tmp[1] or "" + local path = tmp[2] + local xver = tonumber(tmp[3]) + if not dest:find("%.") then + dest = tonumber(dest) + end + fallbacks[i] = { + path = path, + dest = dest, + xver = xver + } + end + end + settings.fallbacks = fallbacks + end + + routing = { + domainStrategy = "IPOnDemand", + rules = { + { + ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, + outboundTag = (node.accept_lan == nil or node.accept_lan == "0") and "blocked" or "direct" + } + } + } + + if node.outbound_node then + local outbound = nil + if node.outbound_node == "_iface" and node.outbound_node_iface then + outbound = { + protocol = "freedom", + tag = "outbound", + streamSettings = { + sockopt = { + mark = 255, + interface = node.outbound_node_iface + } + }, + settings = { + finalRules = {{ action = "allow" }} + } + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface)) + else + local outbound_node_t = uci:get_all("passwall", node.outbound_node) + if node.outbound_node == "_socks" or node.outbound_node == "_http" then + outbound_node_t = { + type = node.type, + protocol = node.outbound_node:gsub("_", ""), + transport = "tcp", + address = node.outbound_node_address, + port = node.outbound_node_port, + username = (node.outbound_node_username and node.outbound_node_username ~= "") and node.outbound_node_username or nil, + password = (node.outbound_node_password and node.outbound_node_password ~= "") and node.outbound_node_password or nil, + } + end + outbound = require("luci.passwall.util_xray").gen_outbound(nil, outbound_node_t, "outbound") + end + if outbound then + table.insert(outbounds, 1, outbound) + end + end + + if node.protocol == "hysteria2" then + node.protocol = "hysteria" + node.transport = "hysteria" + node.tls = "1" + end + + local config = { + log = { + -- error = "/tmp/etc/passwall_server/log/" .. user[".name"] .. ".log", + loglevel = ("1" == node.log) and node.loglevel or "none" + }, + -- 传入连接 + inbounds = { + { + listen = (node.bind_local == "1") and "127.0.0.1" or nil, + port = tonumber(node.port), + protocol = node.protocol, + settings = settings, + streamSettings = { + network = node.transport, + security = "none", + tlsSettings = ("1" == node.tls) and { + disableSystemRoot = false, + certificates = { + { + certificateFile = node.tls_certificateFile, + keyFile = node.tls_keyFile + } + }, + echServerKeys = (node.ech == "1") and node.ech_key or nil + } or nil, + rawSettings = (node.transport == "raw" or node.transport == "tcp") and { + header = { + type = node.tcp_guise, + request = (node.tcp_guise == "http") and { + path = node.tcp_guise_http_path and (function() + local t, r = node.tcp_guise_http_path, {} + for _, v in ipairs(t) do + r[#r + 1] = (v == "" and "/" or v) + end + return r + end)() or {"/"}, + headers = { + Host = node.tcp_guise_http_host or {} + } + } or nil + } + } or nil, + kcpSettings = (node.transport == "mkcp") and { + mtu = (node.mkcp_mtu and node.mkcp_mtu ~= "") and tonumber(node.mkcp_mtu) or 1350, + tti = 50, + uplinkCapacity = 12, + downlinkCapacity = 100, + CwndMultiplier = 1, + MaxSendingWindow = 2 * 1024 * 1024 + } or nil, + wsSettings = (node.transport == "ws") and { + host = node.ws_host or nil, + path = node.ws_path + } or nil, + grpcSettings = (node.transport == "grpc" and node.grpc_serviceName) and { + serviceName = node.grpc_serviceName + } or nil, + httpupgradeSettings = (node.transport == "httpupgrade") and { + path = node.httpupgrade_path or "/", + host = node.httpupgrade_host + } or nil, + xhttpSettings = (node.transport == "xhttp") and { + path = node.xhttp_path or "/", + host = node.xhttp_host, + maxUploadSize = node.xhttp_maxuploadsize, + maxConcurrentUploads = node.xhttp_maxconcurrentuploads + } or nil, + hysteriaSettings = (node.transport == "hysteria") and { + version = 2 + } or nil, + finalmask = (function() + local finalmask = {} + if node.transport == "mkcp" then + local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", + dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local udp = {} + if node.mkcp_guise and node.mkcp_guise ~= "none" then + local g = { type = map[node.mkcp_guise] } + if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then + g.settings = { domain = node.mkcp_domain } + end + udp[#udp+1] = g + end + local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + if node.mkcp_seed and node.mkcp_seed ~= "" then + c.settings = { password = node.mkcp_seed } + end + udp[#udp+1] = c + finalmask.udp = udp + elseif node.transport == "hysteria" then + if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then + finalmask.udp = {{ + type = node.hysteria2_obfs_type, + settings = node.hysteria2_obfs_password and { + password = node.hysteria2_obfs_password + } or nil + }} + end + local ignore = tonumber(node.hysteria2_ignore_client_bandwidth) == 1 + local up = (not ignore) and tonumber(node.hysteria2_up_mbps) or 0 + local down = (not ignore) and tonumber(node.hysteria2_down_mbps) or 0 + finalmask.quicParams = { + congestion = (up <= 0 and down <= 0) and "bbr" or "brutal", + brutalUp = up > 0 and (up .. "mbps") or nil, + brutalDown = down > 0 and (down .. "mbps") or nil + } + end + if node.finalmask and node.finalmask ~= "" then + local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) + if ok and type(fm) == "table" then + finalmask = fm + end + end + return api.cleanEmptyTables(finalmask) + end)(), + sockopt = { + tcpFastOpen = (node.tcp_fast_open == "1") and true or nil, + acceptProxyProtocol = (node.acceptProxyProtocol and node.acceptProxyProtocol == "1") and true or false + } + } + } + }, + -- 传出连接 + outbounds = outbounds, + routing = routing + } + + local alpn = {} + if node.alpn then + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + if alpn and #alpn > 0 then + if config.inbounds[1].streamSettings.tlsSettings then + config.inbounds[1].streamSettings.tlsSettings.alpn = alpn + end + end + + if "1" == node.tls then + config.inbounds[1].streamSettings.security = "tls" + if "1" == node.reality then + config.inbounds[1].streamSettings.tlsSettings = nil + config.inbounds[1].streamSettings.security = "reality" + config.inbounds[1].streamSettings.realitySettings = { + show = false, + dest = node.reality_dest, + serverNames = node.reality_serverNames or {}, + privateKey = node.reality_private_key, + shortIds = node.reality_shortId or "", + mldsa65Seed = (node.use_mldsa65Seed == "1") and node.reality_mldsa65Seed or nil + } or nil + end + end + + for index, value in ipairs(config.outbounds) do + for k, v in pairs(config.outbounds[index]) do + if k and k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + if value.protocol == "freedom" and api.compare_versions(xray_version, "<", "26.5.3") then -- Todo is to remove it + value.settings = nil + end + end + + return config +end + +function gen_config(var) + local flag = var["flag"] + local node_id = var["node"] + local server_host = var["server_host"] + local server_port = var["server_port"] + local tcp_proxy_way = var["tcp_proxy_way"] or "redirect" + local tcp_redir_port = var["tcp_redir_port"] + local udp_redir_port = var["udp_redir_port"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local dns_listen_port = var["dns_listen_port"] + local dns_cache = var["dns_cache"] + local direct_dns_port = var["direct_dns_port"] + local direct_dns_udp_server = var["direct_dns_udp_server"] + local direct_dns_tcp_server = var["direct_dns_tcp_server"] + local direct_dns_query_strategy = var["direct_dns_query_strategy"] + local remote_dns_udp_server = var["remote_dns_udp_server"] + local remote_dns_udp_port = var["remote_dns_udp_port"] + local remote_dns_tcp_server = var["remote_dns_tcp_server"] + local remote_dns_tcp_port = var["remote_dns_tcp_port"] + local remote_dns_doh = var["remote_dns_doh"] + local remote_dns_client_ip = var["remote_dns_client_ip"] + local remote_dns_fake = var["remote_dns_fake"] + local remote_dns_query_strategy = var["remote_dns_query_strategy"] + local dns_socks_address = var["dns_socks_address"] + local dns_socks_port = var["dns_socks_port"] + local loglevel = var["loglevel"] or "warning" + local no_run = var["no_run"] + + local dns_domain_rules = {} + local dns = nil + local fakedns = nil + local routing = nil + local observatory = nil + local burstObservatory = nil + local strategy = nil + local inbounds = {} + local outbounds = {} + local COMMON = {} + + local xray_settings = uci:get_all(appname, "@global_xray[0]") or {} + + if xray_settings.fragment == "1" then + local delay = xray_settings.fragment_delay + fragment_table = { + type = "fragment", + settings = { + packets = xray_settings.fragment_packets, + length = xray_settings.fragment_length, + delay = delay and (delay:find("-", 1, true) and delay or tonumber(delay)) or nil, + maxSplit = xray_settings.fragment_maxSplit + } + } + end + + if xray_settings.noise == "1" then + local noises = {} + uci:foreach(appname, "xray_noise_packets", function(n) + if n.enabled == "1" then + local noise = { + rand = (n.type == "rand" and n.packet) and (n.packet:find("-", 1, true) and n.packet or tonumber(n.packet)) or nil, + type = (n.type ~= "rand") and n.type or nil, + packet = (n.type ~= "rand") and n.packet or nil, + delay = n.delay and (n.delay:find("-", 1, true) and n.delay or tonumber(n.delay)) or nil + } + table.insert(noises, noise) + end + end) + noise_table = #noises > 0 and { + type = "noise", + settings = { reset = 0, noise = noises } + } or nil + end + + if node_id then + local node = uci:get_all(appname, node_id) + local balancers = {} + local rules = {} + if node then + if server_host and server_port then + node.address = server_host + node.port = server_port + end + end + if local_socks_port then + local inbound = { + tag = "socks-in", + listen = local_socks_address, + port = tonumber(local_socks_port), + protocol = "socks", + settings = {auth = "noauth", udp = true}, + sniffing = { + enabled = (xray_settings.sniffing_override_dest == "1") or (node and node.protocol == "_shunt") or false + } + } + if inbound.sniffing.enabled == true then + inbound.sniffing.destOverride = {"http", "tls", "quic"} + inbound.sniffing.routeOnly = xray_settings.sniffing_override_dest ~= "1" or nil + inbound.sniffing.domainsExcluded = xray_settings.sniffing_override_dest == "1" and get_domain_excluded() or nil + end + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.settings.auth = "password" + inbound.settings.accounts = { + { + user = local_socks_username, + pass = local_socks_password + } + } + end + table.insert(inbounds, inbound) + end + if local_http_port then + local inbound = { + listen = local_http_address, + port = tonumber(local_http_port), + protocol = "http", + settings = {allowTransparent = false} + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.settings.accounts = { + { + user = local_http_username, + pass = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + + function gen_socks_config_node(node_id, socks_id, remarks) + if node_id then + socks_id = node_id:sub(1 + #"Socks_") + end + local result + local socks_node = uci:get_all(appname, socks_id) or nil + if socks_node then + if not remarks then + remarks = socks_node.port + end + result = { + [".name"] = "Socksid_" .. socks_id, + remarks = remarks, + type = "Xray", + protocol = "socks", + address = "127.0.0.1", + port = socks_node.port, + transport = "tcp", + stream_security = "none" + } + end + return result + end + + function get_node_by_id(node_id) + if not node_id or node_id == "" or node_id == "nil" then return nil end + if node_id:find("Socks_") then + return gen_socks_config_node(node_id) + else + return uci:get_all(appname, node_id) + end + end + + local nodes_list = {} + function get_balancer_batch_nodes(_node) + if #nodes_list == 0 then + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then + nodes_list[#nodes_list + 1] = { + id = e[".name"], + remarks = e["remarks"], + group = e["group"] + } + end + end + end + if not _node.node_group or _node.node_group == "" then return {} end + local nodes = {} + for g in _node.node_group:gmatch("%S+") do + g = api.UrlDecode(g) + for k, v in pairs(nodes_list) do + local gn = (v.group and v.group ~= "") and v.group or "default" + if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then + nodes[#nodes + 1] = v.id + end + end + end + return nodes + end + + function gen_loopback(outbound_tag, loopback_dst) + if not outbound_tag or outbound_tag == "" then return nil end + local inbound_tag = loopback_dst and "lo-to-" .. loopback_dst or outbound_tag .. "-lo" + local loopback_outbound = { + protocol = "loopback", + tag = outbound_tag, + settings = { inboundTag = inbound_tag } + } + local insert_index = #outbounds + 1 + if outbound_tag == "default" then + insert_index = 1 + end + table.insert(outbounds, insert_index, loopback_outbound) + return loopback_outbound + end + + function gen_balancer(_node, loopback_tag) + local balancer_id = _node[".name"] + local balancer_tag = "balancer-" .. balancer_id + local loopback_dst = balancer_id -- route destination for the loopback outbound + if not loopback_tag or loopback_tag == "" then loopback_tag = balancer_id end + -- existing balancer + for _, v in ipairs(balancers) do + if v.tag == balancer_tag then + local loopback_outbound = gen_loopback(loopback_tag, loopback_dst) + return balancer_tag, loopback_outbound + end + end + -- new balancer + local blc_nodes + if _node.node_add_mode and _node.node_add_mode == "batch" then + blc_nodes = get_balancer_batch_nodes(_node) + else + blc_nodes = _node.balancing_node + end + + api.log(" - 加载 Xray è´Ÿè½½å‡è¡¡ 节点ã€" .. (_node.remarks or "") .. "】,å­èŠ‚ç‚¹æ•°é‡ï¼š" .. #(blc_nodes or {})) + + local valid_nodes = {} + for i = 1, #(blc_nodes or {}) do + local blc_node_id = blc_nodes[i] + local blc_node_tag = "blc-" .. blc_node_id + local is_new_blc_node = true + for _, outbound in ipairs(outbounds) do + if string.sub(outbound.tag, 1, #blc_node_tag) == blc_node_tag then + is_new_blc_node = false + valid_nodes[#valid_nodes + 1] = outbound.tag + break + end + end + if is_new_blc_node then + local outboundTag = gen_outbound_get_tag(flag, blc_node_id, blc_node_tag, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run }) + if outboundTag then + valid_nodes[#valid_nodes + 1] = outboundTag + end + end + end + if #valid_nodes == 0 then return nil end + + -- fallback node + local fallback_node_id = _node.fallback_node + fallback_node_id = (fallback_node_id and fallback_node_id ~= "") and fallback_node_id or nil + local fallback_node_tag = (fallback_node_id == "_direct") and "direct" or "blackhole" + if fallback_node_id and fallback_node_id ~= "_direct" then + local is_new_node = true + for _, outbound in ipairs(outbounds) do + if string.sub(outbound.tag, 1, #fallback_node_id) == fallback_node_id then + is_new_node = false + fallback_node_tag = outbound.tag + break + end + end + if is_new_node then + local fallback_node = get_node_by_id(fallback_node_id) + if fallback_node then + if fallback_node.protocol ~= "_balancing" then + local outboundTag = gen_outbound_get_tag(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run }) + if outboundTag then + fallback_node_tag = outboundTag + end + else + if gen_balancer(fallback_node) then + fallback_node_tag = fallback_node_id + end + end + end + end + end + if _node.balancingStrategy == "leastLoad" then + strategy = { + type = _node.balancingStrategy, + settings = { + expected = _node.expected and tonumber(_node.expected) and tonumber(_node.expected) or 2, + maxRTT = "1s", + tolerance = (function(t) + t = tonumber(t) or 0 + if t < 1 then return nil end + if t > 100 then t = 100 end + return t / 100 + end)(_node.tolerance) + } + } + else + strategy = { type = _node.balancingStrategy or "random" } + end + table.insert(balancers, { + tag = balancer_tag, + selector = api.clone(valid_nodes), + fallbackTag = fallback_node_tag, + strategy = strategy + }) + if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" or fallback_node_tag then + local t = api.format_go_time(_node.probeInterval) + if t == "0s" then + t = "60s" + elseif not t:find("[hm]") and tonumber(t:match("%d+")) < 10 then + t = "10s" + end + if _node.balancingStrategy == "leastLoad" then + burstObservatory = burstObservatory or { + subjectSelector = { "blc-" }, + pingConfig = { + destination = _node.useCustomProbeUrl and _node.probeUrl or nil, + interval = t, + sampling = 3, + timeout = "5s" + } + } + else + observatory = observatory or { + subjectSelector = { "blc-" }, + probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil, + probeInterval = t, + enableConcurrency = true + } + end + end + local loopback_outbound = gen_loopback(loopback_tag, loopback_dst) + local inbound_tag = loopback_outbound.settings.inboundTag + table.insert(rules, { inboundTag = { inbound_tag }, balancerTag = balancer_tag }) + return balancer_tag, loopback_outbound + end + + function set_outbound_detour(node, outbound, outbounds_table) + if not node or not outbound or not outbounds_table then return nil end + local default_outTag = outbound.tag + local last_insert_outbound + + if node.chain_proxy == "1" and node.preproxy_node then + if outbound["_flag_proxy_tag"] then + --Ignore + else + local preproxy_node = get_node_by_id(node.preproxy_node) + if preproxy_node then + local preproxy_outbound, exist + if preproxy_node.protocol == "_balancing" then + local balancer_tag, loopback_outbound = gen_balancer(preproxy_node) + if loopback_outbound then + preproxy_outbound = loopback_outbound + exist = true + end + else + preproxy_outbound = gen_outbound(node[".name"], preproxy_node) + end + if preproxy_outbound then + outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag + outbound.proxySettings = { + tag = preproxy_outbound.tag, + transportLayer = true + } + if not exist then + last_insert_outbound = preproxy_outbound + end + default_outTag = outbound.tag + end + end + end + end + if node.chain_proxy == "2" and node.to_node then + local to_node = get_node_by_id(node.to_node) + if to_node then + -- Landing Node not support use special node. + if to_node.protocol and to_node.protocol:find("^_") then + to_node = nil + end + end + if to_node then + local to_outbound + if to_node.type ~= "Xray" then + local in_tag = "inbound_" .. to_node[".name"] .. "_" .. tostring(outbound.tag) + local new_port = api.get_new_port() + table.insert(inbounds, { + tag = in_tag, + listen = "127.0.0.1", + port = new_port, + protocol = "dokodemo-door", + settings = {network = "tcp,udp", address = to_node.address, port = tonumber(to_node.port)} + }) + if to_node.tls_serverName == nil then + to_node.tls_serverName = to_node.address + end + to_node.address = "127.0.0.1" + to_node.port = new_port + table.insert(rules, 1, { + inboundTag = {in_tag}, + outboundTag = outbound.tag + }) + to_outbound = gen_outbound(node[".name"], to_node, to_node[".name"], { + tag = to_node[".name"], + run_socks_instance = not no_run + }) + else + to_outbound = gen_outbound(node[".name"], to_node) + end + if to_outbound then + to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag + if to_node.type == "Xray" then + to_outbound.proxySettings = { + tag = outbound.tag, + transportLayer = true + } + end + table.insert(outbounds_table, to_outbound) + default_outTag = to_outbound.tag + end + end + end + if node.chain_proxy == "3" and node.outbound_iface then + if outbound.streamSettings and outbound.streamSettings.sockopt then + outbound.streamSettings.sockopt.interface = node.outbound_iface + end + end + return default_outTag, last_insert_outbound + end + + function gen_outbound_get_tag(flag, node_id, tag, proxy_table) + if not node_id or node_id == "" or node_id == "nil" then return nil end + local node + if type(node_id) == "string" then + node = get_node_by_id(node_id) + elseif type(node_id) == "table" then + node = node_id + end + if not tag then tag = node[".name"] end + if node then + if proxy_table.chain_proxy == "1" or proxy_table.chain_proxy == "2" then + node.chain_proxy = proxy_table.chain_proxy + node.preproxy_node = proxy_table.chain_proxy == "1" and proxy_table.preproxy_node + node.to_node = proxy_table.chain_proxy == "2" and proxy_table.to_node + proxy_table.chain_proxy = nil + proxy_table.preproxy_node = nil + proxy_table.to_node = nil + end + local outbound, has_add_outbound + for _, _outbound in ipairs(outbounds) do + -- Avoid generating duplicate nested processes + if _outbound["_flag_proxy_tag"] and _outbound["_flag_proxy_tag"]:find("socks <- " .. node[".name"], 1, true) then + outbound = api.clone(_outbound) + outbound.tag = tag + break + end + end + if node.protocol == "_balancing" then + local balancer_tag, loopback_outbound = gen_balancer(node, tag) + if loopback_outbound then + outbound = loopback_outbound + node[".name"] = outbound.tag + has_add_outbound = true + end + elseif node.protocol == "_iface" then + if node.iface then + outbound = { + tag = tag, + protocol = "freedom", + streamSettings = { + sockopt = { + mark = 255, + interface = node.iface + } + }, + settings = (api.compare_versions(xray_version, ">", "26.4.25")) and { -- Todo: Remove version check + finalRules = {{ action = "allow" }} + } or nil + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) + end + end + if not outbound then + outbound = gen_outbound(flag, node, tag, proxy_table) + end + if outbound then + local default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) + if not has_add_outbound then + local insert_index = #outbounds + 1 + if tag == "default" then + insert_index = 1 + end + table.insert(outbounds, insert_index, outbound) + end + if last_insert_outbound then + table.insert(outbounds, last_insert_outbound) + end + return default_outbound_tag + end + end + end + + if node and node.protocol == "_shunt" then + inner_fakedns = node.fakedns or "0" + + local function gen_shunt_node(rule_name, _node_id) + if not rule_name then return nil end + if not _node_id then _node_id = node[rule_name] end + if _node_id == "_direct" then + return "direct" + elseif _node_id == "_blackhole" then + return "blackhole" + elseif _node_id == "_default" and rule_name ~= "default" then + return "default" + elseif _node_id then + local proxy_table = { + fragment = xray_settings.fragment == "1", + noise = xray_settings.noise == "1", + run_socks_instance = not no_run, + } + local preproxy_node_id = node[rule_name .. "_proxy_tag"] + if preproxy_node_id == _node_id then preproxy_node_id = nil end + if preproxy_node_id then + proxy_table.chain_proxy = "2" + proxy_table.to_node = _node_id + return gen_outbound_get_tag(flag, preproxy_node_id, rule_name, proxy_table) + else + return gen_outbound_get_tag(flag, _node_id, rule_name, proxy_table) + end + end + return nil + end + + --default_node + local default_node_id = node.default_node or "_direct" + local default_outboundTag = gen_shunt_node("default", default_node_id) + COMMON.default_outbound_tag = default_outboundTag + + if inner_fakedns == "1" and node["default_fakedns"] == "1" then + remote_dns_fake = true + end + + --shunt rule + uci:foreach(appname, "shunt_rules", function(e) + local outbound_tag = gen_shunt_node(e[".name"]) + if outbound_tag and e.remarks then + if outbound_tag == "default" then + outbound_tag = default_outboundTag + end + local protocols = nil + if e["protocol"] and e["protocol"] ~= "" then + protocols = {} + string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) + table.insert(protocols, w) + end) + end + local inbound_tag = nil + if e["inbound"] and e["inbound"] ~= "" then + inbound_tag = {} + if e["inbound"]:find("tproxy") then + if tcp_redir_port then + table.insert(inbound_tag, "tcp_redir") + end + if udp_redir_port then + table.insert(inbound_tag, "udp_redir") + end + end + if e["inbound"]:find("socks") then + if local_socks_port then + table.insert(inbound_tag, "socks-in") + end + end + end + local domains = nil + if e.domain_list then + local domain_table = { + shunt_rule_name = e[".name"], + outboundTag = outbound_tag, + domain = {}, + fakedns = nil, + } + domains = {} + string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end + table.insert(domains, w) + table.insert(domain_table.domain, w) + end) + if inner_fakedns == "1" and node[e[".name"] .. "_fakedns"] == "1" and #domains > 0 then + domain_table.fakedns = true + end + if outbound_tag then + table.insert(dns_domain_rules, api.clone(domain_table)) + end + if #domains == 0 then domains = nil end + end + local ip = nil + if e.ip_list then + ip = {} + string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end + table.insert(ip, w) + end) + if #ip == 0 then ip = nil end + end + local source = nil + if e.source then + source = {} + string.gsub(e.source, '[^' .. " " .. ']+', function(w) + table.insert(source, w) + end) + end + local rule = { + ruleTag = e.remarks, + inboundTag = inbound_tag, + outboundTag = outbound_tag, + network = e["network"] or "tcp,udp", + source = source, + --sourcePort = e["sourcePort"] ~= "" and e["sourcePort"] or nil, + port = e["port"] ~= "" and e["port"] or nil, + protocol = protocols + } + if domains then + local _rule = api.clone(rule) + _rule.ruleTag = _rule.ruleTag .. " Domains" + _rule.domains = domains + table.insert(rules, _rule) + end + if ip then + local _rule = api.clone(rule) + _rule.ruleTag = _rule.ruleTag .. " IP" + _rule.ip = ip + table.insert(rules, _rule) + end + if not domains and not ip and protocols then + table.insert(rules, rule) + end + end + end) + + if default_outboundTag then + local rule = { + _flag = "default", + type = "field", + outboundTag = default_outboundTag + } + if node.domainStrategy == "IPIfNonMatch" then + rule.ip = { "0.0.0.0/0", "::/0" } + else + rule.network = "tcp,udp" + end + table.insert(rules, rule) + end + + routing = { + domainStrategy = node.domainStrategy or "AsIs", + domainMatcher = node.domainMatcher or "hybrid", + balancers = #balancers > 0 and balancers or nil, + rules = rules + } + else + COMMON.default_outbound_tag = gen_outbound_get_tag(flag, node or node_id, nil, { + fragment = xray_settings.fragment == "1" or nil, + noise = xray_settings.noise == "1" or nil, + run_socks_instance = not no_run + }) + if COMMON.default_outbound_tag then + routing = { + domainStrategy = "AsIs", + domainMatcher = "hybrid", + balancers = #balancers > 0 and balancers or nil, + rules = rules + } + table.insert(routing.rules, { + ruleTag = "default", + network = "tcp,udp", + outboundTag = COMMON.default_outbound_tag + }) + end + end + + if tcp_redir_port or udp_redir_port then + local inbound = { + protocol = "dokodemo-door", + settings = {network = "tcp,udp", followRedirect = true}, + streamSettings = {sockopt = {tproxy = "tproxy"}}, + sniffing = { + enabled = (xray_settings.sniffing_override_dest == "1") or (node and node.protocol == "_shunt") or false + } + } + if inbound.sniffing.enabled == true then + inbound.sniffing.destOverride = {"http", "tls", "quic"} + inbound.sniffing.metadataOnly = false + inbound.sniffing.routeOnly = xray_settings.sniffing_override_dest ~= "1" or nil + inbound.sniffing.domainsExcluded = xray_settings.sniffing_override_dest == "1" and get_domain_excluded() or nil + end + if remote_dns_fake or inner_fakedns == "1" then + inbound.sniffing.enabled = true + if not inbound.sniffing.destOverride then + inbound.sniffing.destOverride = {"fakedns"} + inbound.sniffing.metadataOnly = true + else + table.insert(inbound.sniffing.destOverride, "fakedns") + inbound.sniffing.metadataOnly = false + end + end + + if tcp_redir_port then + local tcp_inbound = api.clone(inbound) + tcp_inbound.tag = "tcp_redir" + tcp_inbound.settings.network = "tcp" + tcp_inbound.port = tonumber(tcp_redir_port) + tcp_inbound.streamSettings.sockopt.tproxy = tcp_proxy_way + table.insert(inbounds, tcp_inbound) + end + + if udp_redir_port then + local udp_inbound = api.clone(inbound) + udp_inbound.tag = "udp_redir" + udp_inbound.settings.network = "udp" + udp_inbound.port = tonumber(udp_redir_port) + table.insert(inbounds, udp_inbound) + end + end + end + + local node_dns = {} + for i, v in pairs(GLOBAL.DNS_SERVER) do + table.insert(node_dns, { + server = v, + outboundTag = "direct" + }) + end + + if (remote_dns_udp_server and remote_dns_udp_port) or (remote_dns_tcp_server and remote_dns_tcp_port) or remote_dns_doh or #node_dns > 0 then + if not routing then + routing = { + domainStrategy = "IPOnDemand", + rules = {} + } + end + + dns = { + tag = "dns-global", + hosts = {}, + disableCache = (dns_cache and dns_cache == "0") and true or false, + disableFallback = true, + disableFallbackIfMatch = true, + servers = {}, + clientIp = (remote_dns_client_ip and remote_dns_client_ip ~= "") and remote_dns_client_ip or nil, + queryStrategy = "UseIP", + useSystemHosts = true + } + + local _direct_dns = {} + + direct_dns_udp_server = (direct_dns_udp_server and direct_dns_udp_server ~= "") and direct_dns_udp_server or nil + + if direct_dns_udp_server or direct_dns_tcp_server then + _direct_dns.tag = "dns-global-direct" + _direct_dns.queryStrategy = (direct_dns_query_strategy and direct_dns_query_strategy ~= "") and direct_dns_query_strategy or "UseIP" + + if direct_dns_udp_server then + local port = tonumber(direct_dns_port) or 53 + _direct_dns.port = port + _direct_dns.address = direct_dns_udp_server + elseif direct_dns_tcp_server then + local port = tonumber(direct_dns_port) or 53 + _direct_dns.address = "tcp://" .. direct_dns_tcp_server .. ":" .. port + end + + if COMMON.default_outbound_tag == "direct" then + table.insert(dns.servers, _direct_dns) + end + end + if dns_listen_port and next(_direct_dns) then + local domain = {} + local nodes_domain_text = sys.exec([[uci show passwall | sed -n "s/.*\.\(address\|download_address\)='\([^']*\)'/\2/p" | sort -u]]) + string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) + w = (w or ""):lower() + if not api.vps_domain_exclude(w) and api.datatypes.hostname(w) and not GLOBAL.VPS_EXCLUDE[w] then + table.insert(domain, "full:" .. w) + end + end) + if #domain > 0 then + table.insert(dns_domain_rules, 1, { + shunt_rule_name = "logic-vpslist", + outboundTag = "direct", + domain = domain + }) + end + end + + local _remote_dns = {} + + if remote_dns_udp_server then + _remote_dns.address = remote_dns_udp_server + _remote_dns.port = tonumber(remote_dns_udp_port) or 53 + + elseif remote_dns_tcp_server then + _remote_dns.address = "tcp://" .. remote_dns_tcp_server .. ":" .. tonumber(remote_dns_tcp_port) or 53 + + elseif remote_dns_doh then + local _a = api.parseDoH(remote_dns_doh) + if _a then + _remote_dns.address = _a.url + _remote_dns.port = _a.port or 443 + + if api.datatypes.hostname(_a.hostname) then + if _a.hostip then + dns.hosts[_a.hostname] = _a.hostip + else + GLOBAL.DNS_HOSTNAME[_a.hostname] = true + end + end + end + end + + if next(_remote_dns) then + -- _remote_dns.tag = "dns-global-remote" + _remote_dns.queryStrategy = (remote_dns_query_strategy and remote_dns_query_strategy ~= "") and remote_dns_query_strategy or "UseIPv4" + table.insert(dns.servers, _remote_dns) + end + + local _remote_fakedns = { + --tag = "dns-global-remote-fakedns", + address = "fakedns", + } + + if remote_dns_fake or inner_fakedns == "1" then + fakedns = {} + local fakedns4 = { + ipPool = "198.18.0.0/15", + poolSize = 65535 + } + local fakedns6 = { + ipPool = "fc00::/18", + poolSize = 65535 + } + if remote_dns_query_strategy == "UseIP" then + table.insert(fakedns, fakedns4) + table.insert(fakedns, fakedns6) + elseif remote_dns_query_strategy == "UseIPv4" then + table.insert(fakedns, fakedns4) + elseif remote_dns_query_strategy == "UseIPv6" then + table.insert(fakedns, fakedns6) + end + if remote_dns_fake and inner_fakedns ~= "1" then + table.insert(dns.servers, 1, _remote_fakedns) + end + end + + local dns_outbound_tag = "direct" + if dns_socks_address and dns_socks_port then + dns_outbound_tag = "out" + table.insert(outbounds, 1, { + tag = dns_outbound_tag, + protocol = "socks", + streamSettings = { + network = "tcp", + security = "none", + sockopt = { + mark = 255 + } + }, + settings = { + servers = { + { + address = dns_socks_address, + port = tonumber(dns_socks_port) + } + } + } + }) + else + if COMMON.default_outbound_tag then + dns_outbound_tag = COMMON.default_outbound_tag + end + end + + local dns_rule_position = 1 + local remote_dns_outbound + if dns_listen_port then + table.insert(inbounds, { + listen = "127.0.0.1", + port = tonumber(dns_listen_port), + protocol = "dokodemo-door", + tag = "dns-in", + settings = { + address = "0.0.0.0", + network = "tcp,udp" + } + }) + + -- remote dns outbound + local chn_list = uci:get(appname, "@global[0]", "chn_list") or "direct" + remote_dns_outbound = { + tag = "dns-out", + protocol = "dns", + proxySettings = dns_outbound_tag and { + tag = (dns_outbound_tag ~= "blackhole") and dns_outbound_tag or "direct" + } or nil, + settings = { + address = (chn_list ~= "proxy") and "8.8.8.8" or "223.5.5.5", + port = 53, + network = "tcp", + nonIPQuery = (api.compare_versions(xray_version, "<", "26.4.25")) and "reject" or nil, -- Todo is to remove it + rules = (api.compare_versions(xray_version, ">", "26.4.17")) and {} or nil + } + } + + table.insert(routing.rules, 1, { + inboundTag = { + "dns-in" + }, + outboundTag = "dns-out" + }) + dns_rule_position = dns_rule_position + 1 + end + + if not COMMON.default_outbound_tag or COMMON.default_outbound_tag == "direct" then + if direct_dns_udp_server or direct_dns_tcp_server then + table.insert(routing.rules, dns_rule_position, { + inboundTag = { + "dns-global-direct" + }, + outboundTag = "direct" + }) + dns_rule_position = dns_rule_position + 1 + end + end + + --按分æµé¡ºåºDNS + local remote_dns_out_rules = {} + if dns_domain_rules and #dns_domain_rules > 0 then + for index, value in ipairs(dns_domain_rules) do + if value.domain and value.outboundTag then + local dns_server = nil + if value.outboundTag == "direct" and _direct_dns.address then + dns_server = api.clone(_direct_dns) + else + if value.fakedns then + dns_server = api.clone(_remote_fakedns) + else + dns_server = api.clone(_remote_dns) + end + end + local outboundTag + if dns_server then + if not api.is_local_ip(dns_server.address) or value.outboundTag == "blackhole" then + outboundTag = value.outboundTag + else + outboundTag = "direct" --dns为本地ip,走直连 + end + end + --[[ + local dns_block_mode = "host" + if dns_block_mode == "host" and outboundTag == "blackhole" then + for d_i, d_k in ipairs(value.domain) do + dns.hosts[d_k] = "0.0.0.0" + end + dns_server = nil + end + ]]-- + + -- remote dns outbound rules + if value.outboundTag == "blackhole" then + table.insert(remote_dns_out_rules, { + action = "reject", + domain = api.clone(value.domain) + }) + else + table.insert(remote_dns_out_rules, { + action = "hijack", + qtype = "1,28", + domain = api.clone(value.domain) + }) + end + + if dns_server then + --dns_server.finalQuery = true + dns_server.domains = value.domain + if value.shunt_rule_name then + dns_server.tag = "dns-in-" .. value.shunt_rule_name + if value.shunt_rule_name == "logic-vpslist" then + dns_server.finalQuery = true + dns_server.disableCache = false + dns_server.serveStale = true + dns_server.serveExpiredTTL = 30 + end + end + table.insert(dns.servers, dns_server) + table.insert(routing.rules, dns_rule_position, { + inboundTag = { dns_server.tag }, + outboundTag = outboundTag + }) + dns_rule_position = dns_rule_position + 1 + end + end + end + end + + local _outboundTag + if _remote_dns.address and not api.is_local_ip(_remote_dns.address) or dns_outbound_tag == "blackhole" then --dns为本地ip,ä¸èµ°ä»£ç† + _outboundTag = dns_outbound_tag + else + _outboundTag = "direct" + end + table.insert(routing.rules, dns_rule_position, { + inboundTag = { "dns-global" }, + outboundTag = _outboundTag + }) + dns_rule_position = dns_rule_position + 1 + + local default_rule_index = nil + for index, value in ipairs(routing.rules) do + if value.ruleTag == "default" then + default_rule_index = index + break + end + end + if default_rule_index then + local default_rule = api.clone(routing.rules[default_rule_index]) + table.remove(routing.rules, default_rule_index) + table.insert(routing.rules, default_rule) + end + + local dns_hosts_len = 0 + for key, value in pairs(dns.hosts) do + dns_hosts_len = dns_hosts_len + 1 + end + + if dns_hosts_len == 0 then + dns.hosts = nil + end + + -- remote dns outbound + if remote_dns_outbound then + if remote_dns_outbound.settings.rules then + table.insert(remote_dns_out_rules, { + action = "hijack", + qtype = "1,28" + }) + table.insert(remote_dns_out_rules, { + action = "direct" + }) + remote_dns_outbound.settings.rules = remote_dns_out_rules + end + table.insert(outbounds, remote_dns_outbound) + end + + -- 自定义节点 DNS + if #node_dns > 0 and #dns.servers < 1 then + dns.servers = { "localhost" } + end + local idx = dns_listen_port and 2 or 1 + for i = #node_dns, 1, -1 do + local value = node_dns[i] + table.insert(routing.rules, idx, { + inboundTag = { + value.server.tag + }, + outboundTag = value.outboundTag, + }) + table.insert(dns.servers, 2, value.server) + end + if next(GLOBAL.DNS_HOSTNAME) then + local hostname = {} + for line, _ in pairs(GLOBAL.DNS_HOSTNAME) do + table.insert(hostname, line) + end + local new_dns_server = next(_direct_dns) and api.clone(_direct_dns) or { address = "localhost" } + new_dns_server.tag = "dns-in-bootstrap" + new_dns_server.domains = hostname + table.insert(dns.servers, 2, new_dns_server) + table.insert(routing.rules, idx, { + inboundTag = { "dns-in-bootstrap" }, + outboundTag = "direct" + }) + end + end + + if inbounds or outbounds then + local config = { + log = { + -- error = string.format("/tmp/etc/%s/%s.log", appname, node[".name"]), + loglevel = loglevel + }, + -- DNS + dns = dns, + fakedns = fakedns, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + -- 连接观测 + observatory = (not burstObservatory) and observatory or nil, + burstObservatory = burstObservatory, + -- 路由 + routing = routing, + -- 本地策略 + policy = { + levels = { + [0] = { + -- handshake = 4, + -- connIdle = 300, + -- uplinkOnly = 2, + -- downlinkOnly = 5, + bufferSize = xray_settings.buffer_size and tonumber(xray_settings.buffer_size) or nil, + statsUserUplink = false, + statsUserDownlink = false + } + }, + -- system = { + -- statsInboundUplink = false, + -- statsInboundDownlink = false + -- } + } + } + + local direct_outbound = { + protocol = "freedom", + tag = "direct", + settings = { + domainStrategy = (direct_dns_query_strategy and direct_dns_query_strategy ~= "") and direct_dns_query_strategy or "UseIP", + finalRules = (api.compare_versions(xray_version, ">", "26.4.25")) and {{ action = "allow" }} or nil -- Todo: Remove version check + }, + streamSettings = { + sockopt = { + mark = 255 + } + } + } + if COMMON.default_outbound_tag == "direct" then + table.insert(outbounds, 1, direct_outbound) + else + table.insert(outbounds, direct_outbound) + end + + local blackhole_outbound = { + protocol = "blackhole", + tag = "blackhole" + } + if COMMON.default_outbound_tag == "blackhole" then + table.insert(outbounds, 1, blackhole_outbound) + else + table.insert(outbounds, blackhole_outbound) + end + for index, value in ipairs(config.outbounds) do + local pt = value.protocol + local exclude = { blackhole=1, dns=1, freedom=1, loopback=1 } + if not value["_flag_proxy_tag"] and value["_id"] and pt and not exclude[pt] and not no_run then + sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list")) + end + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + end + return jsonc.stringify(config, 1) + end +end + +function gen_proto_config(var) + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local server_proto = var["server_proto"] + local server_address = var["server_address"] + local server_port = var["server_port"] + local server_username = var["server_username"] + local server_password = var["server_password"] + + local inbounds = {} + local outbounds = {} + local routing = nil + + if local_socks_address and local_socks_port then + local inbound = { + listen = local_socks_address, + port = tonumber(local_socks_port), + protocol = "socks", + settings = { + udp = true, + auth = "noauth" + } + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.settings.auth = "password" + inbound.settings.accounts = { + { + user = local_socks_username, + pass = local_socks_password + } + } + end + table.insert(inbounds, inbound) + end + + if local_http_address and local_http_port then + local inbound = { + listen = local_http_address, + port = tonumber(local_http_port), + protocol = "http", + settings = { + allowTransparent = false + } + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.settings.accounts = { + { + user = local_http_username, + pass = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then + local outbound = { + protocol = server_proto, + streamSettings = { + network = "tcp", + security = "none" + }, + settings = { + servers = { + { + address = server_address, + port = tonumber(server_port), + users = (server_username and server_password) and { + { + user = server_username, + pass = server_password + } + } or nil + } + } + } + } + if outbound then table.insert(outbounds, outbound) end + end + + -- é¢å¤–传出连接 + table.insert(outbounds, { + protocol = "freedom", + tag = "direct", + settings = (api.compare_versions(xray_version, ">", "26.4.25")) and { -- Todo: Remove version check + finalRules = {{ action = "allow" }} + } or nil, + sockopt = {mark = 255} + }) + + local config = { + log = { + loglevel = "warning" + }, + -- 传入连接 + inbounds = inbounds, + -- 传出连接 + outbounds = outbounds, + -- 路由 + routing = routing + } + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config +_G.gen_proto_config = gen_proto_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + end +end diff --git a/luci-app-passwall/luasrc/view/passwall/acl/view_chinadns_log.htm b/luci-app-passwall/luasrc/view/passwall/acl/view_chinadns_log.htm new file mode 100644 index 00000000..316b1d6a --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/acl/view_chinadns_log.htm @@ -0,0 +1,55 @@ +<% +local api = require "luci.passwall.api" +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm b/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm new file mode 100644 index 00000000..cda606e7 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm @@ -0,0 +1,213 @@ +<% +local api = require "luci.passwall.api" +local com = require "luci.passwall.com" +local version = {} +-%> + + + +
+ +
+ + 〠<%=api.get_version()%> 】 + + + +
+
+ +<%for _, k in ipairs(com.order) do + local v = com[k] + version[k] = api.get_app_version(k)%> +
+ +
+ + 〠<%=version[k] ~="" and version[k] or translate("Null") %> 】 + + + + +
+
+<%end%> diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/hidevalue.htm b/luci-app-passwall/luasrc/view/passwall/cbi/hidevalue.htm new file mode 100644 index 00000000..c007e399 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/hidevalue.htm @@ -0,0 +1,3 @@ +
" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>" style="display: none !important"> + " /> +
diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_dynamiclist.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_dynamiclist.htm new file mode 100644 index 00000000..f516aceb --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_dynamiclist.htm @@ -0,0 +1,149 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template + +local json = require "luci.jsonc" + +-- 读å–值(keylist/vallist/group) +local values = {} +for i, key in pairs(self.keylist) do + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } +end + +-- 获å–当å‰é…置值 +local current_key = {} +local cval = self:cfgvalue(section) +if type(cval) == "table" then + for _, v in ipairs(cval) do + for item in string.gmatch(v, "[^,]+") do + current_key[#current_key+1] = item + end + end +elseif type(cval) == "string" then + for item in string.gmatch(cval, "[^,]+") do + current_key[#current_key+1] = item + end +end + +-- 分离无组节点(ungrouped)与有组节点(groupedï¼‰ï¼Œå¹¶ä¿æŒåŽŸæœ‰é¡ºåº +local ungrouped = {} +local groups = {} +local group_order = {} +for _, item in ipairs(values) do + if not item.group or item.group == "" then + table.insert(ungrouped, item) + else + local g = item.group + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) + end +end + +-- 打包数æ®ç»™ JS +local dropdown_data = { + current_key = current_key, + ungrouped = ungrouped, + groups = groups, + group_order = group_order, + cbid = cbid, +} +%> + + +
+ + + +
+ + +
+ + <%=translate("-- Please choose --")%> + + +
+ + +
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_dynamiclist_com.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_dynamiclist_com.htm new file mode 100644 index 00000000..74f6e31e --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_dynamiclist_com.htm @@ -0,0 +1,654 @@ +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +-- It is the common part of the template and cannot be used independently +%> + + + + diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm new file mode 100644 index 00000000..fe15cf6e --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm @@ -0,0 +1,148 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template + +local json = require "luci.jsonc" + +-- 读å–值(keylist/vallist/group) +local values = {} +for i, key in pairs(self.keylist) do + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } +end + +-- 获å–当å‰é…置值(å•值) +local current_key = nil +local cval = self:cfgvalue(section) +if type(cval) == "table" then + -- è‹¥æ„外为table,å–第一个 + for k,_ in pairs(cval) do + current_key = k + break + end +elseif type(cval) == "string" then + current_key = (cval:match("%S+")) -- å–第一个 token +end + +-- 分离无组节点(ungrouped)与有组节点(groupedï¼‰ï¼Œå¹¶ä¿æŒåŽŸæœ‰é¡ºåº +local ungrouped = {} +local groups = {} +local group_order = {} +for _, item in ipairs(values) do + if not item.group or item.group == "" then + table.insert(ungrouped, item) + else + local g = item.group + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) + end +end + +-- 如果没有é…置值,默认å–第一个(优先无组第一项,å¦åˆ™ç¬¬ä¸€ç»„第一项) +if not current_key then + if #ungrouped > 0 then + current_key = ungrouped[1].key + else + -- 找到 group_order 第一个有节点的项 + for _, g in ipairs(group_order) do + if groups[g] and #groups[g] > 0 then + current_key = groups[g][1].key + break + end + end + end +end + +-- 获å–å½“å‰ label(用于主控件显示) +local function find_label_by_key(k) + if not k then return "" end + for _, v in ipairs(values) do + if v.key == k then return v.label end + end + return "" +end +local current_label = find_label_by_key(current_key) or "" + +-- 打包数æ®ç»™ JS +local dropdown_data = { + current_key = current_key, + current_label = current_label, + ungrouped = ungrouped, + groups = groups, + group_order = group_order, + cbid = cbid, +} +%> + + +
+ + + +
+ + <%=pcdata("("..translate("Not set")..")")%> + + +
+ + +
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm new file mode 100644 index 00000000..9de708e5 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm @@ -0,0 +1,758 @@ +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +-- It is the common part of the template and cannot be used independently +%> + + + diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm new file mode 100644 index 00000000..e1c46c5f --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm @@ -0,0 +1,132 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +local json = require "luci.jsonc" +local cbid = "cbid." .. self.config .. "." .. section .. "." .. self.option + +-- è¯»å– MultiValue +local values = {} +for i, key in pairs(self.keylist) do + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } +end + +-- 获å–选中值 +local selected = {} +local cval = self:cfgvalue(section) +if type(cval) == "table" then + for _, v in pairs(cval) do + selected[v] = true + end +elseif type(cval) == "string" then + for v in cval:gmatch("%S+") do + selected[v] = true + end +end + +-- 按原顺åºåˆ†ç»„ +local groups = {} +local group_order = {} +for _, item in ipairs(values) do + local g = item.group + if not g or g == "" then + g = translate("default") + end + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) +end + +local total_count = #values +local selected_count = 0 +for _, item in ipairs(values) do + if selected[item.key] then + selected_count = selected_count + 1 + end +end + +local function idSafe(id) + return (id + :gsub("^%s+", "") + :gsub("%s+$", "") + :gsub("%s+", "-") + :gsub("[%z\1-\31\127]", "") + ) +end +%> + +
+ + + + +
+
    + <% for _, gname in ipairs(group_order) do local items = groups[gname] %> +
  • + +
    + + <%=pcdata(gname)%> + <% + local g_selected = 0 + for _, it in ipairs(items) do + if selected[it.key] then + g_selected = g_selected + 1 + end + end + %> + + (<%=g_selected%>/<%=#items%>) + +
    + + +
  • + <% end %> +
+
+ +
+ + + <%:Selected:%> <%=selected_count%>/<%=total_count%> +
+
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue_com.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue_com.htm new file mode 100644 index 00000000..646f691b --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue_com.htm @@ -0,0 +1,460 @@ +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +%> + + + + diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm new file mode 100644 index 00000000..beb3ce2a --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm @@ -0,0 +1,162 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template + +local json = require "luci.jsonc" + +-- 读å–值(keylist/vallist/group) +local values = {{key = "", label = translate("-- Please choose --")}} +for i, key in pairs(self.keylist) do + if key and key ~= "" then + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } + end +end + +-- 获å–当å‰é…置值(å•值) +local current_key = nil +local cval = self:cfgvalue(section) +if type(cval) == "table" then + -- è‹¥æ„外为table,å–第一个 + for k,_ in pairs(cval) do + current_key = k + break + end +elseif type(cval) == "string" then + current_key = (cval:match("%S+")) -- å–第一个 token +end + +-- 分离无组节点(ungrouped)与有组节点(groupedï¼‰ï¼Œå¹¶ä¿æŒåŽŸæœ‰é¡ºåº +local ungrouped = {} +local groups = {} +local group_order = {} +local current_key_added = false +for _, item in ipairs(values) do + if not current_key_added and current_key and current_key ~= "" and item.key == current_key then + current_key_added = true + end + if not item.group or item.group == "" then + table.insert(ungrouped, item) + else + local g = item.group + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) + end +end +if not current_key_added and current_key and current_key ~= "" then + table.insert(ungrouped, {key = current_key, label = current_key}) +end + +-- 如果没有é…置值,默认å–第一个(优先无组第一项,å¦åˆ™ç¬¬ä¸€ç»„第一项) +if not current_key then + if #ungrouped > 0 then + current_key = ungrouped[1].key + else + -- 找到 group_order 第一个有节点的项 + for _, g in ipairs(group_order) do + if groups[g] and #groups[g] > 0 then + current_key = groups[g][1].key + break + end + end + end +end + +-- 获å–å½“å‰ label(用于主控件显示) +local function find_label_by_key(k) + if not k then return "" end + for _, v in ipairs(values) do + if v.key == k then return v.label end + end + return "" +end +local current_label = find_label_by_key(current_key) or "" + +-- 打包数æ®ç»™ JS +local dropdown_data = { + current_key = current_key, + current_label = current_label, + ungrouped = ungrouped, + groups = groups, + group_order = group_order, + cbid = cbid, +} +%> + + +
+ + + + +
+ + <%=pcdata(translate("-- Please choose --"))%> + + +
+ + +
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm new file mode 100644 index 00000000..1f784d04 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm @@ -0,0 +1,792 @@ +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +-- It is the common part of the template and cannot be used independently +%> + + + diff --git a/luci-app-passwall/luasrc/view/passwall/cbi/optimize_cbi_ui.htm b/luci-app-passwall/luasrc/view/passwall/cbi/optimize_cbi_ui.htm new file mode 100644 index 00000000..579d0383 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/cbi/optimize_cbi_ui.htm @@ -0,0 +1,24 @@ + diff --git a/luci-app-passwall/luasrc/view/passwall/global/backup.htm b/luci-app-passwall/luasrc/view/passwall/global/backup.htm new file mode 100644 index 00000000..f92d529c --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/global/backup.htm @@ -0,0 +1,241 @@ +<% +local api = require "luci.passwall.api" +-%> + +
+

<%:Backup and Restore%>

+
+ <%:Backup or Restore Client and Server Configurations.%> +
+ <%:Note: Restoring configurations across different versions may cause compatibility issues.%> +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + + + + + diff --git a/luci-app-passwall/luasrc/view/passwall/global/faq.htm b/luci-app-passwall/luasrc/view/passwall/global/faq.htm new file mode 100644 index 00000000..bb68c39f --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/global/faq.htm @@ -0,0 +1,66 @@ +<% +local api = require "luci.passwall.api" +-%> + +
+
+
    + <%:DNS related issues:%> +
  • 1. <%:Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off.%>
  • +
  • 2. <%:If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):%> +
    • â—¦ <%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%>
    • +
    • â—¦ <%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%>
    • +
    • â—¦ <%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%>
    • +
    +
  • +
  • 3. <%:Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed.%>
  • +
+
+
+
+ + diff --git a/luci-app-passwall/luasrc/view/passwall/global/footer.htm b/luci-app-passwall/luasrc/view/passwall/global/footer.htm new file mode 100644 index 00000000..7c7b1b4d --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/global/footer.htm @@ -0,0 +1,293 @@ +<% +local api = self.api +local appname = api.appname +-%> + + diff --git a/luci-app-passwall/luasrc/view/passwall/global/proxy.htm b/luci-app-passwall/luasrc/view/passwall/global/proxy.htm new file mode 100644 index 00000000..33ce38f0 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/global/proxy.htm @@ -0,0 +1,110 @@ +
" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>"> + +
+
+ + + + +
+
+
+ + diff --git a/luci-app-passwall/luasrc/view/passwall/global/status.htm b/luci-app-passwall/luasrc/view/passwall/global/status.htm new file mode 100644 index 00000000..d27b3b81 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/global/status.htm @@ -0,0 +1,281 @@ +<% +local api = require "luci.passwall.api" +-%> + + + +
+ + <%:Running Status%> + +
+
+
+
+
+ +
+
+
+

TCP
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

UDP
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

DNS
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

HAPROXY
N/A

+
+
+
+
+
+
+
+ +
+
+
+

<%:AliCloud Conn.%>
<%:Touch Check%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:Google Conn.%>
<%:Touch Check%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:GitHub Conn.%>
<%:Touch Check%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:YouTube Conn.%>
<%:Touch Check%>

+
+
+
+
+ +
diff --git a/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm b/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm new file mode 100644 index 00000000..22256df1 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/haproxy/js.htm @@ -0,0 +1,238 @@ +<% +local api = require "luci.passwall.api" +local appname = api.appname +-%> + + + + diff --git a/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm b/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm new file mode 100644 index 00000000..7d5e0907 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/haproxy/status.htm @@ -0,0 +1,30 @@ +<% +local api = require "luci.passwall.api" +local haproxy_enable = api.uci_get_type("global_haproxy", "balancing_enable", "0") +local console_port = api.uci_get_type("global_haproxy", "console_port", "") +-%> +

+ + diff --git a/luci-app-passwall/luasrc/view/passwall/include/shunt_options.htm b/luci-app-passwall/luasrc/view/passwall/include/shunt_options.htm new file mode 100644 index 00000000..7f5e4439 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/include/shunt_options.htm @@ -0,0 +1,76 @@ + + \ No newline at end of file diff --git a/luci-app-passwall/luasrc/view/passwall/log/log.htm b/luci-app-passwall/luasrc/view/passwall/log/log.htm new file mode 100644 index 00000000..33208086 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/log/log.htm @@ -0,0 +1,45 @@ +<% +local api = require "luci.passwall.api" +-%> + +
+ + +
diff --git a/luci-app-passwall/luasrc/view/passwall/node_config/footer.htm b/luci-app-passwall/luasrc/view/passwall/node_config/footer.htm new file mode 100644 index 00000000..7a16884f --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/node_config/footer.htm @@ -0,0 +1,48 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/node_config/header.htm b/luci-app-passwall/luasrc/view/passwall/node_config/header.htm new file mode 100644 index 00000000..7d7fda07 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/node_config/header.htm @@ -0,0 +1,80 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/node_config/link_share_man.htm b/luci-app-passwall/luasrc/view/passwall/node_config/link_share_man.htm new file mode 100644 index 00000000..13a28126 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/node_config/link_share_man.htm @@ -0,0 +1,1862 @@ +<%+cbi/valueheader%> +<% +local api = require "luci.passwall.api" +local appname = api.appname +local map = self.map + +local has_ss_rust = api.is_finded("sslocal") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") + +local ss_type = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}}) +local trojan_type = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}}) +local vmess_type = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local vless_type = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local hysteria2_type = api.get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{has_singbox,"sing-box"}, {has_xray,"xray"}}) + +local current_node = map:get(section) +-%> + + + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm b/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm new file mode 100644 index 00000000..e59a21c0 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/node_list/link_add_node.htm @@ -0,0 +1,556 @@ +<% +local api = require "luci.passwall.api" +-%> + + + + + + + +
+
+

<%:Reassign Node Group%>

+
+
+ +
+
+ <%:default%> + +
+ + +
+
+
+
+ + +
+
+
+ + + +
+
+ + + + + + + + + +
+
+ + diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm new file mode 100644 index 00000000..86c49b14 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm @@ -0,0 +1,1119 @@ +<% +local api = require "luci.passwall.api" +local appname = api.appname +-%> + + + + +<% if api.is_js_luci() then -%> + +<%- else %> + +<%- end %> + + + + + + + +
+
+ + + +
+
+
+ <%:You choose node is:%> +
+
+ + + +
+
+
diff --git a/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm b/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm new file mode 100644 index 00000000..b27f401c --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/node_subscribe/js.htm @@ -0,0 +1,276 @@ +<% +local api = require "luci.passwall.api" +-%> + + + + + diff --git a/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm b/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm new file mode 100644 index 00000000..c0834a1c --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm @@ -0,0 +1,338 @@ +<% +local api = require "luci.passwall.api" +local fs = api.fs +local has_old_geoip = fs.access("/tmp/bak_v2ray/geoip.dat") +local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat") +-%> + + + + +
+ +
+
+ + + + + + +

+ + <% if has_old_geoip then %> + + <% end %> + <% if has_old_geosite then %> + + <% end %> +
+
+
+ + diff --git a/luci-app-passwall/luasrc/view/passwall/rule_list/geoview.htm b/luci-app-passwall/luasrc/view/passwall/rule_list/geoview.htm new file mode 100644 index 00000000..098fae35 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/rule_list/geoview.htm @@ -0,0 +1,111 @@ +<% +local api = require "luci.passwall.api" +-%> + + + +
+
    + <%:Tips:%> +
  • 1. <%:By entering a domain or IP, you can query the Geo rule list they belong to.%>
  • +
  • 2. <%:By entering a GeoIP or Geosite, you can extract the domains/IPs they contain.%>
  • +
  • 3. <%:Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct.%>
  • +
+
+
+ +
+ +
+ <%:Enter a domain or IP to query the Geo rule list they belong to.%> +
+
+
+
+ +
+ +
+ <%:Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw%> +
+
+
+
+ +
+ + diff --git a/luci-app-passwall/luasrc/view/passwall/rule_list/js.htm b/luci-app-passwall/luasrc/view/passwall/rule_list/js.htm new file mode 100644 index 00000000..c950646d --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/rule_list/js.htm @@ -0,0 +1,47 @@ +<% +local api = require "luci.passwall.api" +local translate = luci.i18n.translate +local total_lines_text = translate("Total Lines") +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/server/config_footer.htm b/luci-app-passwall/luasrc/view/passwall/server/config_footer.htm new file mode 100644 index 00000000..7b835ec2 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/server/config_footer.htm @@ -0,0 +1,27 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/server/config_header.htm b/luci-app-passwall/luasrc/view/passwall/server/config_header.htm new file mode 100644 index 00000000..1957dec4 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/server/config_header.htm @@ -0,0 +1,56 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/server/log.htm b/luci-app-passwall/luasrc/view/passwall/server/log.htm new file mode 100644 index 00000000..f3374088 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/server/log.htm @@ -0,0 +1,48 @@ +<% +local api = require "luci.passwall.api" +-%> + +
+ + <%:Logs%> + + + +
diff --git a/luci-app-passwall/luasrc/view/passwall/server/users_list_status.htm b/luci-app-passwall/luasrc/view/passwall/server/users_list_status.htm new file mode 100644 index 00000000..8ba385aa --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/server/users_list_status.htm @@ -0,0 +1,38 @@ +<% +local api = require "luci.passwall.api" +-%> + diff --git a/luci-app-passwall/luasrc/view/passwall/socks_auto_switch/btn.htm b/luci-app-passwall/luasrc/view/passwall/socks_auto_switch/btn.htm new file mode 100644 index 00000000..485889d5 --- /dev/null +++ b/luci-app-passwall/luasrc/view/passwall/socks_auto_switch/btn.htm @@ -0,0 +1,45 @@ +<% +local api = require "luci.passwall.api" +-%> + + + +
" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>"> + +
+ + +
+
diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po new file mode 100644 index 00000000..237fdeae --- /dev/null +++ b/luci-app-passwall/po/zh-cn/passwall.po @@ -0,0 +1,2133 @@ +msgid "Pass Wall" +msgstr "PassWall" + +msgid "Auto" +msgstr "自动" + +msgid "RUNNING" +msgstr "è¿è¡Œä¸­" + +msgid "NOT RUNNING" +msgstr "未è¿è¡Œ" + +msgid "UNINSTALLED" +msgstr "未安装" + +msgid "Working..." +msgstr "连接正常" + +msgid "Problem detected!" +msgstr "连接失败" + +msgid "Touch Check" +msgstr "点我检测" + +msgid "TLS handshake test, latency for reference only" +msgstr "TLSæ¡æ‰‹æµ‹è¯•,延时仅供å‚考" + +msgid "Kernel Unsupported" +msgstr "å†…æ ¸ä¸æ”¯æŒ" + +msgid "Settings" +msgstr "设置" + +msgid "Main Settings" +msgstr "节点选择" + +msgid "Basic Settings" +msgstr "基本设置" + +msgid "Node List" +msgstr "节点列表" + +msgid "Other Settings" +msgstr "高级设置" + +msgid "Load Balancing" +msgstr "è´Ÿè½½å‡è¡¡" + +msgid "Enter interface" +msgstr "进入界é¢" + +msgid "Rule Manage" +msgstr "规则管ç†" + +msgid "Rule List" +msgstr "规则列表" + +msgid "Access control" +msgstr "访问控制" + +msgid "Runtime Logs" +msgstr "è¿è¡Œæ—¥å¿—" + +msgid "Node Config" +msgstr "节点é…ç½®" + +msgid "Shunt Policy Config" +msgstr "åˆ†æµæ–¹æ¡ˆé…ç½®" + +msgid "Running Status" +msgstr "è¿è¡Œçжæ€" + +msgid "AliCloud Conn." +msgstr "阿里连接" + +msgid "Google Conn." +msgstr "谷歌连接" + +msgid "GitHub Conn." +msgstr "GitHub 连接" + +msgid "YouTube Conn." +msgstr "YouTube 连接" + +msgid "Node Check" +msgstr "节点检测" + +msgid "Check..." +msgstr "检测中..." + +msgid "Clear" +msgstr "清除" + +msgid "Main switch" +msgstr "主开关" + +msgid "TCP Node" +msgstr "TCP 节点" + +msgid "UDP Node" +msgstr "UDP 节点" + +msgid "Edit Current Node" +msgstr "编辑当å‰èŠ‚ç‚¹" + +msgid "Socks Config" +msgstr "Socks é…ç½®" + +msgid "Socks Node" +msgstr "Socks 节点" + +msgid "Current Node" +msgstr "当å‰èŠ‚ç‚¹" + +msgid "Listen Port" +msgstr "监å¬ç«¯å£" + +msgid "0 is not use" +msgstr "0 为ä¸ä½¿ç”¨" + +msgid "Same as the tcp node" +msgstr "与 TCP 节点相åŒ" + +msgid "Current node: %s" +msgstr "当å‰èŠ‚ç‚¹ï¼š%s" + +msgid "DNS Shunt" +msgstr "DNS分æµ" + +msgid "Domestic group name" +msgstr "国内分组å" + +msgid "You only need to configure domestic DNS packets in SmartDNS, and fill in the domestic DNS group name here." +msgstr "您åªéœ€è¦åœ¨SmartDNSé…置好国内DNS分组,并在此处填入国内DNS分组å。" + +msgid "%s cannot be empty." +msgstr "%s ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Filter Mode" +msgstr "过滤模å¼" + +msgid "TCP node must be '%s' type to use FakeDNS." +msgstr "TCP 节点必须是 '%s' 类型æ‰èƒ½ä½¿ç”¨ FakeDNS。" + +msgid "Direct DNS" +msgstr "直连 DNS" + +msgid "Remote DNS" +msgstr "远程 DNS" + +msgid "Resolver For The List Proxied" +msgstr "è§£æžè¢«ä»£ç†çš„域å列表" + +msgid "Requery DNS By %s" +msgstr "通过 %s 请求 DNS" + +msgid "Socks Server" +msgstr "Socks æœåС噍" + +msgid "Misconfigured" +msgstr "é…ç½®ä¸å½“" + +msgid "Make sure socks service is available on this address." +msgstr "è¯·ç¡®ä¿æ­¤ Socks æœåŠ¡å¯ç”¨ã€‚" + +msgid "%s request address" +msgstr "%s 请求地å€" + +msgid "Format must be:" +msgstr "æ ¼å¼å¿…须为:" + +msgid "Request protocol" +msgstr "请求åè®®" + +msgid "Remote DNS DoH" +msgstr "远程 DNS DoH" + +msgid "Format: URL[,IP] (optional IP to map the domain in the URL)" +msgstr "æ ¼å¼ï¼šURL[,IP](IP å¯é€‰ï¼Œç”¨äºŽç»‘定 URL 中的域å)" + +msgid "Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address)." +msgstr "用于 DNS 查询时通知 DNS æœåŠ¡å™¨ï¼Œå®¢æˆ·ç«¯æ‰€åœ¨çš„åœ°ç†ä½ç½®ï¼ˆä¸èƒ½æ˜¯ç§æœ‰ IP 地å€ï¼‰ã€‚" + +msgid "This feature requires the DNS server to support the Edns Client Subnet (RFC7871)." +msgstr "æ­¤åŠŸèƒ½éœ€è¦ DNS æœåŠ¡å™¨æ”¯æŒ EDNS Client Subnet(RFC7871)。" + +msgid "The effect is better, recommend." +msgstr "效果更好,推è使用。" + +msgid "ChinaDNS-NG (recommended)" +msgstr "ChinaDNS-NG (推è)" + +msgid "Default DNS" +msgstr "默认 DNS" + +msgid "When not matching any domain name list:" +msgstr "当ä¸åŒ¹é…任何域å列表时:" + +msgid "Remote DNS: Can avoid more DNS leaks, but some domestic domain names maybe to proxy!" +msgstr "远程 DNS:å¯ä»¥é¿å…更多的 DNS 泄露,但会导致规则列表外的æŸäº›å›½å†…域åå¯èƒ½ä¼šèµ°ä»£ç†ï¼" + +msgid "Direct DNS: Internet experience may be better, but DNS will be leaked!" +msgstr "直连 DNS:上网体验å¯èƒ½ä¼šæ›´ä½³ï¼Œä½†æ˜¯ä¼šæ³„露 DNSï¼" + +msgid "Smart, Do not accept no-ip reply from Direct DNS" +msgstr "æ™ºèƒ½ï¼Œä¸æŽ¥å—直连 DNS 空å“应" + +msgid "Smart, Accept no-ip reply from Direct DNS" +msgstr "智能,接å—直连 DNS 空å“应" + +msgid "Smart: Forward to both direct and remote DNS, if the direct DNS resolution result is a mainland China IP, then use the direct result, otherwise use the remote result." +msgstr "æ™ºèƒ½ï¼šåŒæ—¶è½¬å‘给直连和远程 DNS,如果直连 DNS è§£æžç»“果是大陆 IP,则使用直连结果,å¦åˆ™ä½¿ç”¨è¿œç¨‹ç»“果。" + +msgid "In smart mode, no-ip reply from Direct DNS:" +msgstr "使用智能模å¼ï¼Œç›´è¿ž DNS 返回空å“应时:" + +msgid "Do not accept: Wait and use Remote DNS Reply." +msgstr "䏿ޥå—:等待并使用远程 DNS çš„å“应。" + +msgid "Accept: Trust the Reply, using this option can improve DNS resolution speeds for some mainland IPv4-only sites." +msgstr "接å—:信任空å“应,使用此选项å¯ä»¥æå‡éƒ¨åˆ†å¤§é™†ä»… IPv4 站点的 DNS è§£æžé€Ÿåº¦ã€‚" + +msgid "Filter Proxy Host IPv6" +msgstr "过滤代ç†åŸŸå IPv6" + +msgid "Experimental feature." +msgstr "实验性功能。" + +msgid "Use FakeDNS work in the domain that proxy." +msgstr "需è¦ä»£ç†çš„域å使用 FakeDNS。" + +msgid "Suitable scenarios for let the node servers get the target domain names." +msgstr "适åˆè®©èŠ‚ç‚¹æœåŠ¡å™¨èŽ·å–目标域å的场景。" + +msgid "Such as: DNS unlocking of streaming media, reducing DNS query latency, etc." +msgstr "例如:æµåª’体的 DNS è§£é”ã€å‡å°‘ DNS 查询延迟等。" + +msgid "Redirect" +msgstr "é‡å®šå‘" + +msgid "DNS Redirect" +msgstr "DNS é‡å®šå‘" + +msgid "Force special DNS server to need proxy devices." +msgstr "强制需è¦ä»£ç†çš„设备使用专用 DNS æœåŠ¡å™¨ã€‚" + +msgid "Clear IPSET on Reboot" +msgstr "é‡å¯æ¸…空 IPSET" + +msgid "Clear NFTSET on Reboot" +msgstr "é‡å¯æ¸…空 NFTSET" + +msgid "Clear IPSET/NFTSET on service reboot. This may increase reboot time." +msgstr "é‡å¯æœåŠ¡æ—¶æ¸…ç©º IPSET/NFTSET,å¯èƒ½ä¼šå»¶é•¿é‡å¯æ—¶é—´ã€‚" + +msgid "Clear IPSET" +msgstr "清空 IPSET" + +msgid "Clear NFTSET" +msgstr "清空 NFTSET" + +msgid "Try this feature if the rule modification does not take effect." +msgstr "å¦‚æžœä¿®æ”¹è§„åˆ™åŽæ²¡æœ‰ç”Ÿæ•ˆï¼Œè¯·å°è¯•此功能。" + +msgid "Force HTTPS SOA" +msgstr "åœç”¨ HTTPS 记录解æž" + +msgid "Force queries with qtype 65 to respond with an SOA record." +msgstr "强制使 qtype 65 查询返回 SOA。" + +msgid "Are you sure to hide?" +msgstr "你确定è¦éšè—å—?" + +msgid "DNS related issues:" +msgstr "DNS 相关问题:" + +msgid "Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off." +msgstr "æŸäº›æµè§ˆå™¨å¦‚ Chrome 等内置此功能,这会影å“设置的 DNS è§£æžã€‚您å¯ä»¥è¿›å…¥ '设置->ç§éšå’Œå®‰å…¨->使用安全 DNS' èœå•,将其关闭。" + +msgid "If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):" +msgstr "如果在é‡å¯åŽæ— æ³•上网,请å°è¯•清除终端设备的缓存(先关闭所有正在使用的æµè§ˆå™¨åº”用程åºï¼Œè¿™ä¸€æ­¥å°¤å…¶é‡è¦ï¼‰ï¼š" + +msgid "For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'." +msgstr "对于Windows系统,请在命令æç¤ºç¬¦ä¸­è¿è¡Œå‘½ä»¤ 'ipconfig /flushdns'." + +msgid "For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'." +msgstr "对于Mac系统,在终端中è¿è¡Œå‘½ä»¤ 'sudo killall -HUP mDNSResponder'." + +msgid "For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi." +msgstr "对于移动设备,å¯é€šè¿‡é‡æ–°æŽ¥å…¥ç½‘ç»œçš„æ–¹å¼æ¸…除。比如开关一次飞行模å¼ï¼Œé‡æ–°è¿žæŽ¥ WiFi。" + +msgid "Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed." +msgstr "请确认您设备的网络设置,客户端 DNS æœåŠ¡å™¨å’Œé»˜è®¤ç½‘å…³åº”å‡æŒ‡å‘æœ¬è·¯ç”±å™¨ï¼Œä»¥ç¡®ä¿ DNS 查询正确路由。" + +msgid "Browser access:" +msgstr "æµè§ˆå™¨è®¿é—®ï¼š" + +msgid "Hide in main menu:" +msgstr "在主èœå•中éšè—:" + +msgid "Show in main menu:" +msgstr "在主èœå•中显示:" + +msgid "DNS Export Of Multi WAN" +msgstr "国内 DNS 指定解æžå‡ºå£" + +msgid "Node Export Of Multi WAN" +msgstr "节点指定出å£" + +msgid "Only support Multi Wan." +msgstr "åªæœ‰å¤šçº¿æŽ¥å…¥æ‰æœ‰æ•ˆã€‚" + +msgid "Not Specify" +msgstr "䏿Œ‡å®š" + +msgid "custom" +msgstr "自定义" + +msgid "Process" +msgstr "进程" + +msgid "1 Process" +msgstr "å•进程" + +msgid "Use %s" +msgstr "使用 %s" + +msgid "Close(Not use)" +msgstr "关闭(ä¸ä½¿ç”¨ï¼‰" + +msgid "Proxy Mode" +msgstr "ä»£ç†æ¨¡å¼" + +msgid "Default Proxy Mode" +msgstr "é»˜è®¤ä»£ç†æ¨¡å¼" + +msgid "No Proxy" +msgstr "ä¸ä»£ç†" + +msgid "Proxy" +msgstr "代ç†" + +msgid "Global Proxy" +msgstr "全局代ç†" + +msgid "GFW List" +msgstr "GFW 列表" + +msgid "Not China List" +msgstr "中国列表以外" + +msgid "China List" +msgstr "中国列表" + +msgid "Localhost" +msgstr "本机" + +msgid "Switch Mode" +msgstr "åˆ‡æ¢æ¨¡å¼" + +msgid "Localhost Proxy" +msgstr "路由器本机代ç†" + +msgid "When selected, localhost can transparent proxy." +msgstr "当勾选时,路由器本机å¯ä»¥é€æ˜Žä»£ç†ã€‚" + +msgid "Client Proxy" +msgstr "客户端代ç†" + +msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy." +msgstr "当勾选时,局域网内的设备å¯ä»¥é€æ˜Žä»£ç†ã€‚å¦åˆ™ï¼Œå°†ä¸ä»£ç†ã€‚但您ä»ç„¶å¯ä»¥ä½¿ç”¨è®¿é—®æŽ§åˆ¶å…许指定的设备代ç†ã€‚" + +msgid "Missing components, transparent proxy is unavailable." +msgstr "ç¼ºå°‘ç»„ä»¶ï¼Œé€æ˜Žä»£ç†ä¸å¯ç”¨ã€‚" + +msgid "Want different devices to use different proxy modes/ports/nodes? Please use access control." +msgstr "希望ä¸åŒè®¾å¤‡ä½¿ç”¨ä¸åŒçš„ä»£ç†æ¨¡å¼/端å£/节点?请使用访问控制。" + +msgid "Operation" +msgstr "æ“作" + +msgid "Add Node" +msgstr "添加节点" + +msgid "Add the node via the link" +msgstr "通过链接添加节点" + +msgid "Enter share links, one per line. Subscription links are not supported!" +msgstr "输入分享链接,支æŒå¤šä¸ªèŠ‚ç‚¹ï¼Œæ¯è¡Œä¸€ä¸ªã€‚请勿输入订阅链接ï¼" + +msgid "Please enter the correct link." +msgstr "请输入正确的链接。" + +msgid "Clear all nodes" +msgstr "清空所有节点" + +msgid "Are you sure to clear all nodes?" +msgstr "ä½ ç¡®å®šè¦æ¸…空所有节点å—?" + +msgid "Success" +msgstr "æˆåŠŸ" + +msgid "Error" +msgstr "错误" + +msgid "Delete select nodes" +msgstr "删除选择的节点" + +msgid "To Top" +msgstr "置顶" + +msgid "Select" +msgstr "选择" + +msgid "Selected:" +msgstr "已选:" + +msgid "DeSelect" +msgstr "å选" + +msgid "Select all" +msgstr "全选" + +msgid "DeSelect all" +msgstr "å…¨ä¸é€‰" + +msgid "Are you sure to delete select nodes?" +msgstr "你确定è¦åˆ é™¤é€‰æ‹©çš„节点å—?" + +msgid "You no select nodes !" +msgstr "你没有选择任何节点ï¼" + +msgid "Are you sure set to" +msgstr "你确定è¦è®¾ä¸º" + +msgid "the server?" +msgstr "æœåС噍å—?" + +msgid "You choose node is:" +msgstr "你选择的节点是:" + +msgid "Timeout" +msgstr "è¶…æ—¶" + +msgid "Node Remarks" +msgstr "节点备注" + +msgid "Add Mode" +msgstr "添加方å¼" + +msgid "Save Order" +msgstr "ä¿å­˜å½“å‰é¡ºåº" + +msgid "Saved current page order successfully." +msgstr "ä¿å­˜å½“å‰é¡µé¢é¡ºåºæˆåŠŸã€‚" + +msgid "Drag to reorder" +msgstr "æ‹–åŠ¨ä»¥é‡æŽ’" + +msgid "Type" +msgstr "类型" + +msgid "_balancing" +msgstr "è´Ÿè½½å‡è¡¡" + +msgid "_shunt" +msgstr "分æµ" + +msgid "_iface" +msgstr "接å£" + +msgid "Balancing" +msgstr "è´Ÿè½½å‡è¡¡" + +msgid "Node Addition Method" +msgstr "节点添加方å¼" + +msgid "Manual" +msgstr "手动" + +msgid "Batch" +msgstr "批é‡" + +msgid "Select Group" +msgstr "选择分组" + +msgid "Node Matching Rules" +msgstr "节点匹é…规则" + +msgid "" +"Example: ^A && B && !C && D$
" +"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" +"Conditions are joined by &&, and their order does not affect the result." +msgstr "" +"示例:^A && B && !C && D$
" +"è¡¨ç¤ºèŠ‚ç‚¹å¤‡æ³¨éœ€åŒæ—¶æ»¡è¶³ï¼šä»¥ A 开头(^)ã€åŒ…å« Bã€ä¸åŒ…å« C(!)ã€å¹¶ä»¥ D 结尾($)。
" +"多个æ¡ä»¶ä½¿ç”¨ && 连接,æ¡ä»¶é¡ºåºä¸å½±å“结果。" + +msgid "Keep the match scope small. Too many nodes can impact router performance." +msgstr "建议尽é‡ç¼©å°åŒ¹é…范围,节点过多会增加路由器负载。" + +msgid "Balancing Strategy" +msgstr "è´Ÿè½½å‡è¡¡ç­–ç•¥" + +msgid "Fallback Node" +msgstr "åŽå¤‡èŠ‚ç‚¹" + +msgid "Use Custom Probe URL" +msgstr "使用自定义探测网å€" + +msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL." +msgstr "默认使用内置的探测网å€ï¼Œå¯ç”¨æ­¤é€‰é¡¹ä»¥ä½¿ç”¨è‡ªå®šä¹‰æŽ¢æµ‹ç½‘å€ã€‚" + +msgid "Probe URL" +msgstr "探测网å€" + +msgid "The URL used to detect the connection status." +msgstr "用于检测连接状æ€çš„网å€ã€‚" + +msgid "Probe Interval" +msgstr "探测间隔" + +msgid "The interval between initiating probes." +msgstr "å‘起探测的间隔。" + +msgid "The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively." +msgstr "æ—¶é—´æ ¼å¼ä¸ºæ•°å­—+å•ä½ï¼Œæ¯”如"10s", "2h45m",支æŒçš„æ—¶é—´å•使œ‰ s,m,h,分别对应秒ã€åˆ†ã€æ—¶ã€‚" + +msgid "When the unit is not filled in, it defaults to seconds." +msgstr "未填写å•使—¶ï¼Œé»˜è®¤ä¸ºç§’。" + +msgid "Preferred Node Count" +msgstr "优选节点数é‡" + +msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them." +msgstr "è´Ÿè½½å‡è¡¡å™¨é€‰å‡ºæœ€ä¼˜èŠ‚ç‚¹çš„ä¸ªæ•°ï¼Œæµé‡å°†åœ¨è¿™å‡ ä¸ªèŠ‚ç‚¹ä¸­éšæœºåˆ†é…。" + +msgid "Failure Tolerance (%)" +msgstr "测速失败率容å¿åº¦ï¼ˆ%)" + +msgid "The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate." +msgstr "æœ€å¤šå¯æŽ¥å—的测速失败率,例如 1 表示å…许 1% 的测速失败率。" + +msgid "Shunt" +msgstr "分æµ" + +msgid "Preproxy" +msgstr "å‰ç½®ä»£ç†" + +msgid "Preproxy Node" +msgstr "å‰ç½®ä»£ç†èŠ‚ç‚¹" + +msgid "Set the node to be used as a pre-proxy." +msgstr "设置用作å‰ç½®ä»£ç†çš„节点。" + +msgid "Each rule has a separate switch that controls whether this rule uses the pre-proxy or not." +msgstr "æ¯æ¡è§„则都有独立开关控制本规则是å¦ä½¿ç”¨å‰ç½®ä»£ç†ã€‚" + +msgid "Close (Not use)" +msgstr "关闭(ä¸ä½¿ç”¨ï¼‰" + +msgid "Use default node" +msgstr "使用默认节点" + +msgid "Direct Connection" +msgstr "直连" + +msgid "Blackhole (Block)" +msgstr "黑洞(å±è”½ï¼‰" + +msgid "There are no available nodes, please add or subscribe nodes first." +msgstr "没有å¯ç”¨èŠ‚ç‚¹ï¼Œè¯·å…ˆæ·»åŠ æˆ–è®¢é˜…èŠ‚ç‚¹ã€‚" + +msgid "No shunt rules? Click me to go to add." +msgstr "没有分æµè§„则?点我å‰å¾€åŽ»æ·»åŠ ã€‚" + +msgid "When using, localhost will connect this node first and then use this node to connect the default node." +msgstr "当使用时,本机将首先连接到此节点,然åŽå†ä½¿ç”¨æ­¤èŠ‚ç‚¹è¿žæŽ¥åˆ°é»˜è®¤èŠ‚ç‚¹è½åœ°ã€‚" + +msgid "Domain Strategy" +msgstr "域åè§£æžç­–ç•¥" + +msgid "Domain matcher" +msgstr "域å匹é…算法" + +msgid "'AsIs': Only use domain for routing. Default value." +msgstr "AsIs:åªä½¿ç”¨åŸŸå进行路由选择。默认值。" + +msgid "'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again." +msgstr "IPIfNonMatchï¼šå½“åŸŸåæ²¡æœ‰åŒ¹é…任何规则时,将域åè§£æžæˆ IP(A 记录或 AAAA è®°å½•ï¼‰å†æ¬¡è¿›è¡ŒåŒ¹é…。" + +msgid "'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately." +msgstr "IPOnDemandï¼šå½“åŒ¹é…æ—¶ç¢°åˆ°ä»»ä½•基于 IP 的规则,将域åç«‹å³è§£æžä¸º IP 进行匹é…。" + +msgid "Prefer IPv4" +msgstr "IPv4 优先" + +msgid "Prefer IPv6" +msgstr "IPv6 优先" + +msgid "IPv4 Only" +msgstr "ä»… IPv4" + +msgid "IPv6 Only" +msgstr "ä»… IPv6" + +msgid "Load balancing node list" +msgstr "è´Ÿè½½å‡è¡¡èŠ‚ç‚¹åˆ—è¡¨" + +msgid "Load balancing node list, document" +msgstr "è´Ÿè½½å‡è¡¡èŠ‚ç‚¹åˆ—è¡¨ï¼Œæ–‡æ¡£åŽŸç†" + +msgid "From Share URL" +msgstr "导入分享URL" + +msgid "Build Share URL" +msgstr "导出分享URL" + +msgid "Generate QRCode" +msgstr "生æˆäºŒç»´ç " + +msgid "Export Config File" +msgstr "导出é…置文件" + +msgid "Import Finished" +msgstr "导入完æˆï¼š" + +msgid "Not a supported scheme:" +msgstr "䏿”¯æŒè¿™ç§æ ·å¼çš„:" + +msgid "Invalid Share URL Format" +msgstr "无效的分享URLä¿¡æ¯" + +msgid "Paste Share URL Here" +msgstr "在此处粘贴分享信æ¯" + +msgid "Share URL to clipboard unable." +msgstr "无法分享URL到剪贴æ¿ã€‚" + +msgid "Share URL to clipboard successfully." +msgstr "æˆåŠŸå¤åˆ¶åˆ†äº«URL到剪贴æ¿ã€‚" + +msgid "Faltal on get option, please help in debug:" +msgstr "代ç é”™è¯¯ï¼Œè¯·å助æ‰è™«ï¼š" + +msgid "Faltal on set option, please help in debug:" +msgstr "代ç é”™è¯¯ï¼Œè¯·å助æ‰è™«ï¼š" + +msgid "Address" +msgstr "地å€" + +msgid "Address (Support Domain Name)" +msgstr "地å€ï¼ˆæ”¯æŒåŸŸå)" + +msgid "Trojan Verify Cert" +msgstr "验è¯è¯ä¹¦" + +msgid "Trojan Cert Path" +msgstr "è¯ä¹¦è·¯å¾„" + +msgid "Finger Print" +msgstr "指纹伪造" + +msgid "Avoid using randomized, unless you have to." +msgstr "é¿å…使用 randomized , 除éžä½ å¿…é¡»è¦ã€‚" + +msgid "Original" +msgstr "原版" + +msgid "Transport Plugin" +msgstr "传输层æ’ä»¶" + +msgid "Shadowsocks secondary encryption" +msgstr "Shadowsocks 二次加密" + +msgid "Obfs Type" +msgstr "混淆类型" + +msgid "Obfs Password" +msgstr "混淆密ç " + +msgid "Auth Type" +msgstr "认è¯ç±»åž‹" + +msgid "Auth Password" +msgstr "认è¯å¯†ç " + +msgid "Client BBR Control" +msgstr "客户端 BBR æµæŽ§" + +msgid "Commands the client to use the BBR flow control algorithm" +msgstr "命令客户端使用 BBR æµé‡æŽ§åˆ¶ç®—法" + +msgid "PinSHA256" +msgstr "PinSHA256" + +msgid "Certificate fingerprint" +msgstr "è¯ä¹¦æŒ‡çº¹" + +msgid "Max upload Mbps" +msgstr "最大上行(Mbps)" + +msgid "Max download Mbps" +msgstr "最大下行(Mbps)" + +msgid "QUIC stream receive window" +msgstr "QUIC æµæŽ¥æ”¶çª—å£" + +msgid "QUIC connection receive window" +msgstr "QUIC 连接接收窗å£" + +msgid "QUIC concurrent bidirectional streams" +msgstr "QUIC å¹¶å‘åŒå‘æµçš„æœ€å¤§æ•°é‡" + +msgid "QUIC KeepAlive interval" +msgstr "QUIC KeepAlive é—´éš”" + +msgid "Disable MTU detection" +msgstr "ç¦ç”¨ MTU 检测" + +msgid "ignoreClientBandwidth" +msgstr "忽略客户端带宽设置" + +msgid "Lazy Start" +msgstr "延迟å¯åЍ" + +msgid "Encrypt Method" +msgstr "加密方å¼" + +msgid "Encrypt Key" +msgstr "加密密钥" + +msgid "Latency" +msgstr "延迟" + +msgid "Automatic detection delay" +msgstr "自动检测延迟" + +msgid "Show server address and port" +msgstr "显示æœåŠ¡å™¨åœ°å€å’Œç«¯å£" + +msgid "URL Test Address" +msgstr "URL 测试地å€" + +msgid "URL Test" +msgstr "URL 测试" + +msgid "Test" +msgstr "测试" + +msgid "Node num" +msgstr "节点数é‡" + +msgid "Self add" +msgstr "自添" + +msgid "Apply" +msgstr "应用" + +msgid "Use" +msgstr "使用" + +msgid "Copy" +msgstr "å¤åˆ¶" + +msgid "Delay Settings" +msgstr "定时é…ç½®" + +msgid "Open and close Daemon" +msgstr "å¯åŠ¨å®ˆæŠ¤è¿›ç¨‹" + +msgid "Delay Start" +msgstr "开机时延时å¯åЍ" + +msgid "Units:seconds" +msgstr "å•ä½ï¼šç§’" + +msgid "Units:minutes" +msgstr "å•ä½ï¼šåˆ†é’Ÿ" + +msgid "stop automatically mode" +msgstr "定时关闭模å¼" + +msgid "stop Time(Every day)" +msgstr "关闭时间(æ¯å¤©)" + +msgid "stop Interval(Hour)" +msgstr "关闭间隔(å°æ—¶)" + +msgid "start automatically mode" +msgstr "å®šæ—¶å¼€å¯æ¨¡å¼" + +msgid "start Time(Every day)" +msgstr "开坿—¶é—´(æ¯å¤©)" + +msgid "start Interval(Hour)" +msgstr "å¼€å¯é—´éš”(å°æ—¶)" + +msgid "restart automatically mode" +msgstr "定时é‡å¯æ¨¡å¼" + +msgid "restart Time(Every day)" +msgstr "é‡å¯æ—¶é—´(æ¯å¤©)" + +msgid "restart Interval(Hour)" +msgstr "é‡å¯é—´éš”(å°æ—¶)" + +msgid "Forwarding Settings" +msgstr "转å‘é…ç½®" + +msgid "TCP No Redir Ports" +msgstr "TCP ä¸è½¬å‘端å£" + +msgid "UDP No Redir Ports" +msgstr "UDP ä¸è½¬å‘端å£" + +msgid "Fill in the ports you don't want to be forwarded by the agent, with the highest priority." +msgstr "填写你ä¸å¸Œæœ›è¢«ä»£ç†è½¬å‘的端å£ï¼Œä¼˜å…ˆçº§æœ€é«˜ã€‚" + +msgid "The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000." +msgstr "以上端å£è®¾ç½®æ”¯æŒå•端å£å’Œç«¯å£èŒƒå›´ã€‚
多个端å£ç”¨è‹±æ–‡é€—å·(,)隔开。
例:21,80,443,1000:2000。" + +msgid "TCP Proxy Drop Ports" +msgstr "TCP 转å‘å±è”½ç«¯å£" + +msgid "UDP Proxy Drop Ports" +msgstr "UDP 转å‘å±è”½ç«¯å£" + +msgid "TCP Redir Ports" +msgstr "TCP 转å‘端å£" + +msgid "UDP Redir Ports" +msgstr "UDP 转å‘端å£" + +msgid "No patterns are used" +msgstr "ä¸ä½¿ç”¨" + +msgid "All" +msgstr "所有" + +msgid "Common Use" +msgstr "常用的" + +msgid "Only Web" +msgstr "仅网页" + +msgid "default" +msgstr "默认" + +msgid "Default" +msgstr "默认" + +msgid "Close" +msgstr "关闭" + +msgid "Hijacking ICMP (PING)" +msgstr "劫æŒICMP (PING)" + +msgid "Hijacking ICMPv6 (IPv6 PING)" +msgstr "劫æŒICMPv6 (IPv6 PING)" + +msgid "Sniffing" +msgstr "æµé‡å—…探" + +msgid "TCP Proxy Way" +msgstr "TCP ä»£ç†æ–¹å¼" + +msgid "Proxy Settings" +msgstr "代ç†é…ç½®" + +msgid "Auto Switch" +msgstr "自动切æ¢" + +msgid "How often to test" +msgstr "多久检测一次" + +msgid "Timeout seconds" +msgstr "è¶…æ—¶ç§’æ•°" + +msgid "Timeout retry num" +msgstr "è¶…æ—¶é‡è¯•次数" + +msgid "Main node" +msgstr "主节点" + +msgid "List of backup nodes" +msgstr "备用节点的列表" + +msgid "Restore Switch" +msgstr "æ¢å¤åˆ‡æ¢" + +msgid "When detects main node is available, switch back to the main node." +msgstr "当检测到主节点å¯ç”¨æ—¶ï¼Œåˆ‡æ¢å›žä¸»èŠ‚ç‚¹ã€‚" + +msgid "Add nodes to the standby node list by keywords" +msgstr "通过关键字添加节点到备用节点列表" + +msgid "Delete nodes in the standby node list by keywords" +msgstr "通过关键字删除备用节点列表的节点" + +msgid "Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase." +msgstr "请输入节点关键字,注æ„区分空格ã€å¤§å†™å’Œå°å†™ã€‚" + +msgid "Configure this node with 127.0.0.1: this port" +msgstr "使用 127.0.0.1 和此端å£é…置节点" + +msgid "Enable Load Balancing" +msgstr "å¼€å¯è´Ÿè½½å‡è¡¡" + +msgid "Console Login Auth" +msgstr "控制å°ç™»å½•认è¯" + +msgid "Console Username" +msgstr "控制å°è´¦å·" + +msgid "Console Password" +msgstr "控制å°å¯†ç " + +msgid "Console Port" +msgstr "控制å°ç«¯å£" + +msgid "In the browser input routing IP plus port access, such as:192.168.1.1:1188" +msgstr "在æµè§ˆå™¨è¾“入路由IP加端å£è®¿é—®ï¼Œå¦‚:192.168.1.1:1188" + +msgid "Haproxy Port" +msgstr "è´Ÿè½½å‡è¡¡ç«¯å£" + +msgid "Health Check Type" +msgstr "å¥åº·æ£€æŸ¥ç±»åž‹" + +msgid "Inner implement" +msgstr "内置实现" + +msgid "Health Check Inter" +msgstr "å¥åº·æ£€æŸ¥èŠ‚ç‚¹é—´éš”æ—¶é—´" + +msgid "Note: Frequent health checks increase CPU usage; an interval ≥ 60 seconds is recommended." +msgstr "注æ„:检测过于频ç¹ä¼šå¢žåŠ  CPU 负载,建议间隔 ≥60 秒。" + +msgid "When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid." +msgstr "当使用 URL 测试时,负载å‡è¡¡èŠ‚ç‚¹å°†è½¬æ¢æˆ Socks 节点。下é¢çš„节点列表自定义时必须为 Socks 节点,å¦åˆ™å¥åº·æ£€æŸ¥å°†æ— æ•ˆã€‚" + +msgid "Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group." +msgstr "添加节点,指定出å£åŠŸèƒ½æ˜¯ä¸ºå¤š WAN 用户准备的。负载比é‡èŒƒå›´ 1-256。多个主æœåС噍å¯ä»¥è´Ÿè½½å‡è¡¡ï¼Œå¤‡ç”¨åªæœ‰åœ¨ä¸»æœåŠ¡å™¨ç¦»çº¿æ—¶æ‰ä¼šå¯ç”¨ï¼å¯ä»¥è®¾ç½®å¤šä¸ªç»„,负载å‡è¡¡ç«¯å£ç›¸åŒåˆ™ä¸ºä¸€ç»„。" + +msgid "Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!" +msgstr "注æ„,当使用 TCP å¥åº·æ£€æŸ¥æ—¶è´Ÿè½½å‡è¡¡çš„节点é…ç½®å‚æ•°å¿…须一致,å¦åˆ™æ— æ³•正常使用ï¼" + +msgid "Node" +msgstr "节点" + +msgid "Node Address" +msgstr "节点地å€" + +msgid "Node address cannot be empty." +msgstr "节点地å€ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Node Port" +msgstr "节点端å£" + +msgid "Node Weight" +msgstr "负载比é‡" + +msgid "Export Of Multi WAN" +msgstr "多 WAN 指定出å£" + +msgid "Main" +msgstr "主è¦" + +msgid "Mode" +msgstr "模å¼" + +msgid "Primary" +msgstr "主è¦" + +msgid "Standby" +msgstr "备用" + +msgid "Check update" +msgstr "检查更新" + +msgid "Force update" +msgstr "强制更新" + +msgid "Manually update" +msgstr "手动更新" + +msgid "Rollback" +msgstr "回滚" + +msgid "Rollbacking..." +msgstr "回滚中..." + +msgid "Update Options" +msgstr "更新选项" + +msgid "The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install." +msgstr "最新版本:%sï¼Œç›®å‰æš‚䏿”¯æŒè‡ªåŠ¨æ›´æ–°ï¼Œå¦‚éœ€æ›´æ–°ï¼Œè¯·è‡ªè¡Œç¼–è¯‘æˆ–ä¸‹è½½ ipk ç„¶åŽæ‰‹åŠ¨å®‰è£…ã€‚" + +msgid "Enable custom URL" +msgstr "å¯ç”¨è‡ªå®šä¹‰è§„则地å€" + +msgid "GFW domains(gfwlist) Update URL" +msgstr "防ç«å¢™åŸŸå列表(gfwlist)æ›´æ–°URL" + +msgid "China IPs(chnroute) Update URL" +msgstr "中国IP段(chnroute)æ›´æ–°URL" + +msgid "China IPv6s(chnroute6) Update URL" +msgstr "中国IPv6段(chnroute6)æ›´æ–°URL" + +msgid "China List(Chnlist) Update URL" +msgstr "中国域å列表(Chnlist)æ›´æ–°URL" + +msgid "Rule status" +msgstr "规则版本" + +msgid "Enable auto update rules" +msgstr "å¼€å¯è‡ªåŠ¨æ›´æ–°è§„åˆ™" + +msgid "Update Time(every day)" +msgstr "æ›´æ–°æ—¶é—´(æ¯å¤©)" + +msgid "Update Interval(hour)" +msgstr "æ›´æ–°é—´éš”(å°æ—¶)" + +msgid "Update Mode" +msgstr "更新模å¼" + +msgid "Loop Mode" +msgstr "循环" + +msgid "Every day" +msgstr "æ¯å¤©" + +msgid "Every Monday" +msgstr "æ¯å‘¨ä¸€" + +msgid "Every Tuesday" +msgstr "æ¯å‘¨äºŒ" + +msgid "Every Wednesday" +msgstr "æ¯å‘¨ä¸‰" + +msgid "Every Thursday" +msgstr "æ¯å‘¨å››" + +msgid "Every Friday" +msgstr "æ¯å‘¨äº”" + +msgid "Every Saturday" +msgstr "æ¯å‘¨å…­" + +msgid "Every Sunday" +msgstr "æ¯å‘¨æ—¥" + +msgid "hour" +msgstr "å°æ—¶" + +msgid "Hour" +msgstr "å°æ—¶" + +msgid "GeoIP Update URL" +msgstr "GeoIP æ›´æ–°URL" + +msgid "Geosite Update URL" +msgstr "Geosite æ›´æ–°URL" + +msgid "Location of Geo rule files" +msgstr "Geo 规则文件目录" + +msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." +msgstr "æ­¤å˜é‡æŒ‡å®š geoip.dat å’Œ geosite.dat 文件所在的目录。" + +msgid "Generate Rule List from Geo" +msgstr "从 Geo 文件生æˆè§„则" + +msgid "Generate rule lists such as GFW, China domains, and China IP ranges based on Geo files." +msgstr "æ ¹æ® Geo 文件生æˆè§„则列表,包括 GFWã€ä¸­å›½åŸŸå和中国 IP 段等。" + +msgid "When manually updating with this option enabled, rules will be regenerated from existing Geo files even if no new version is available." +msgstr "å¯ç”¨æ­¤é€‰é¡¹åŽæ‰‹åŠ¨æ›´æ–°æ—¶,å³ä½¿æ²¡æœ‰æ–°ç‰ˆæœ¬ä¹Ÿä¼šä»ŽçŽ°æœ‰ Geo æ–‡ä»¶é‡æ–°ç”Ÿæˆè§„则。" + +msgid "Enable Geo Data Parsing" +msgstr "å¼€å¯ Geo æ•°æ®è§£æž" + +msgid "Analyzes and preloads GeoIP/Geosite data to enhance the shunt performance of Sing-box/Xray." +msgstr "分æžå’Œé¢„加载 GeoIP/Geosite æ•°æ®ï¼Œä»¥å¢žå¼º Sing-box/Xray çš„åˆ†æµæ•ˆæžœã€‚" + +msgid "Once enabled, the rule list can support GeoIP/Geosite rules." +msgstr "å¯ç”¨åŽï¼Œè§„则列表å¯ä»¥æ”¯æŒ GeoIP/Geosite 规则。" + +msgid "Note: Increases resource usage; Geosite analysis is only supported in ChinaDNS-NG and SmartDNS modes." +msgstr "注:会增加一些系统资æºçš„开销,仅在 ChinaDNS-NG å’Œ SmartDNS 模å¼ä¸‹æ”¯æŒåˆ†æž Geosite 。" + +msgid "Shunt Rule" +msgstr "分æµè§„则" + +msgid "Please note attention to the priority, the higher the order, the higher the priority." +msgstr "请注æ„优先级问题,排åºè¶Šä¸Šé¢ä¼˜å…ˆçº§è¶Šé«˜ã€‚" + +msgid "Update..." +msgstr "更新中" + +msgid "It is the latest version" +msgstr "已是最新版本" + +msgid "Update successful" +msgstr "æ›´æ–°æˆåŠŸ" + +msgid "Click to update" +msgstr "点击更新" + +msgid "Updating..." +msgstr "更新中" + +msgid "Retry" +msgstr "é‡è¯•" + +msgid "Unexpected error" +msgstr "æ„外错误" + +msgid "Updating, are you sure to close?" +msgstr "正在更新,你确认è¦å…³é—­å—?" + +msgid "Downloading..." +msgstr "下载中" + +msgid "Unpacking..." +msgstr "解压中" + +msgid "Moving..." +msgstr "移动中" + +msgid "App Update" +msgstr "组件更新" + +msgid "Please confirm that your firmware supports FPU." +msgstr "è¯·ç¡®è®¤ä½ çš„å›ºä»¶æ”¯æŒ FPU。" + +msgid "if you want to run from memory, change the path, /tmp beginning then save the application and update it manually." +msgstr "如果你希望从内存中è¿è¡Œï¼Œè¯·æ›´æ”¹è·¯å¾„,/tmp 开头,然åŽä¿å­˜åº”用åŽï¼Œå†æ‰‹åŠ¨æ›´æ–°ã€‚" + +msgid "Make sure there is enough space to install %s" +msgstr "ç¡®ä¿æœ‰è¶³å¤Ÿçš„空间安装 %s" + +msgid "App Path" +msgstr "程åºè·¯å¾„" + +msgid "%s App Path" +msgstr "%s 程åºè·¯å¾„" + +msgid "%s Client App Path" +msgstr "%s 客户端程åºè·¯å¾„" + +msgid "alternate API URL for version checking" +msgstr "用于版本检查的 API URL" + +msgid "Node Subscribe" +msgstr "节点订阅" + +msgid "Subscribe Remark" +msgstr "订阅备注(机场)" + +msgid "Subscribe Info" +msgstr "订阅信æ¯" + +msgid "Subscribe URL" +msgstr "订阅网å€" + +msgid "Subscribe URL Access Method" +msgstr "订阅网å€è®¿é—®æ–¹å¼" + +msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically." +msgstr "新增订阅请先ä¿å­˜å¹¶åº”用åŽå†æ‰‹åŠ¨è®¢é˜…ï¼›å¦‚ä»…ä¿®æ”¹è®¢é˜…åœ°å€ï¼Œå¯ç›´æŽ¥æ‰‹åŠ¨è®¢é˜…ï¼Œç³»ç»Ÿå°†è‡ªåŠ¨ä¿å­˜ã€‚" + +msgid "Please save and apply before manually subscribing." +msgstr "请先ä¿å­˜å¹¶åº”用åŽå†æ‰‹åŠ¨è®¢é˜…ã€‚" + +msgid "Subscribe URL cannot be empty." +msgstr "订阅网å€ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Subscribe via proxy" +msgstr "通过代ç†è®¢é˜…" + +msgid "Update Once on Boot" +msgstr "开机更新一次" + +msgid "Updates the subscription the first time PassWall runs automatically after each system boot." +msgstr "è·¯ç”±æ¯æ¬¡å¯åЍåŽï¼Œé¦–次自动è¿è¡Œ PassWall 时更新订阅。" + +msgid "Enable auto update subscribe" +msgstr "å¼€å¯è‡ªåŠ¨æ›´æ–°è®¢é˜…" + +msgid "Manual subscription" +msgstr "手动订阅" + +msgid "Delete All Subscribe Node" +msgstr "删除所有订阅节点" + +msgid "Delete the subscribed node" +msgstr "删除已订阅的节点" + +msgid "Are you sure you want to delete all subscribed nodes?" +msgstr "您确定è¦åˆ é™¤æ‰€æœ‰å·²è®¢é˜…的节点å—?" + +msgid "Manual subscription All" +msgstr "手动订阅全部链接" + +msgid "This remark already exists, please change a new remark." +msgstr "此备注已存在,请改一个新的备注。" + +msgid "Remark cannot be empty." +msgstr "备注ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "URL cannot be empty." +msgstr "网å€ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Filter keyword Mode" +msgstr "过滤关键字模å¼" + +msgid "Discard List" +msgstr "丢弃列表" + +msgid "Keep List" +msgstr "ä¿ç•™åˆ—表" + +msgid "Discard List,But Keep List First" +msgstr "丢弃列表,但ä¿ç•™åˆ—表优先" + +msgid "Keep List,But Discard List First" +msgstr "ä¿ç•™åˆ—表,但丢弃列表优先" + +msgid "Use global config" +msgstr "使用全局é…ç½®" + +msgid "User-Agent" +msgstr "用户代ç†(User-Agent)" + +msgid "Used when the node link does not include this parameter." +msgstr "当节点链接未包å«è¯¥å‚数时,将使用此设置。" + +msgid "Add" +msgstr "添加" + +msgid "ACLs" +msgstr "访问控制" + +msgid "ACLs is a tools which used to designate specific IP proxy mode." +msgstr "访问控制列表是用于指定特殊 IP ä»£ç†æ¨¡å¼çš„工具。" + +msgid "Example:" +msgstr "例:" + +msgid "IP range" +msgstr "IP 范围" + +msgid "Source Interface" +msgstr "æºæŽ¥å£" + +msgid "Bridge" +msgstr "网桥" + +msgid "Wireless Adapter" +msgstr "无线适é…器" + +msgid "Ethernet Adapter" +msgstr "以太网适é…器" + +msgid "Tunnel Interface" +msgstr "éš§é“æŽ¥å£" + +msgid "Invalid interface name" +msgstr "无效的接å£åç§°" + +msgid "Use Interface With ACLs" +msgstr "ä½¿ç”¨æŽ¥å£æŽ§åˆ¶" + +msgid "Remarks" +msgstr "备注" + +msgid "Direct List" +msgstr "直连列表" + +msgid "Proxy List" +msgstr "代ç†åˆ—表" + +msgid "Block List" +msgstr "å±è”½åˆ—表" + +msgid "Lan IP List" +msgstr "局域网 IP 列表" + +msgid "Route Hosts" +msgstr "路由 Hosts 文件" + +msgid "Join the direct hosts list of domain names will not proxy." +msgstr "加入的域åä¸èµ°ä»£ç†ï¼Œå¯¹æ‰€æœ‰æ¨¡å¼æœ‰æ•ˆã€‚且优先级最高。" + +msgid "These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5." +msgstr "加入的 IP 段ä¸èµ°ä»£ç†ï¼Œå¯¹æ‰€æœ‰æ¨¡å¼æœ‰æ•ˆã€‚且优先级最高。å¯è¾“å…¥ IP åœ°å€æˆ–åœ°å€æ®µï¼Œå¦‚:192.168.0.0/24 或 223.5.5.5,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined websites will use proxy. Please input the domain names of websites, every line can input only one website domain. For example: google.com." +msgstr "加入的域å将走代ç†ã€‚输入网站域å,如:google.com,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined ip addresses will use proxy. Please input the ip address or ip address segment, every line can input only one ip address. For example: 35.24.0.0/24 or 8.8.4.4." +msgstr "加入的 IP 段将走代ç†ã€‚å¯è¾“å…¥ IP åœ°å€æˆ–åœ°å€æ®µï¼Œå¦‚:35.24.0.0/24 或 8.8.4.4,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined websites will be block. Please input the domain names of websites, every line can input only one website domain. For example: twitter.com." +msgstr "加入的域åå°†å±è”½ã€‚输入网站域å,如:twitter.com,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "The list is the IPv4 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "列表中为 IPv4 的局域网 IP 列表,代表局域网直连 IP。如果需è¦ä»£ç†åˆ—表中的局域网 IP,请将其在该列表中清除,并将其添加到代ç†åˆ—表中。默认情况下ä¸è¦ä¿®æ”¹è¿™ä¸ªåˆ—表。" + +msgid "The list is the IPv6 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "列表中为 IPv6 的局域网 IP 列表,代表局域网直连 IP。如果需è¦ä»£ç†åˆ—表中的局域网 IP,请将其在该列表中清除,并将其添加到代ç†åˆ—表中。默认情况下ä¸è¦ä¿®æ”¹è¿™ä¸ªåˆ—表。" + +msgid "Configure routing etc/hosts file, if you don't know what you are doing, please don't change the content." +msgstr "é…置路由 etc/hosts 文件,如果你ä¸çŸ¥é“自己在åšä»€ä¹ˆï¼Œè¯·ä¸è¦æ”¹åŠ¨å†…å®¹ã€‚" + +msgid "These had been joined ip addresses will be block. Please input the ip address or ip address segment, every line can input only one ip address." +msgstr "加入的 IP 段将å±è”½ã€‚å¯è¾“å…¥ IP åœ°å€æˆ–åœ°å€æ®µï¼Œæ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "Inbound Tag" +msgstr "入站标签" + +msgid "Transparent proxy" +msgstr "逿˜Žä»£ç†" + +msgid "Not valid domain name, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆåŸŸåï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not valid IP format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆ IP æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not valid IPv4 format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆ IPv4 æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not valid IPv6 format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆ IPv6 æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not true format, please re-enter!" +msgstr "䏿˜¯æ­£ç¡®çš„æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'." +msgstr "纯字符串: 当此字符串匹é…目标域å中任æ„部分,该规则生效。比如'sina.com'å¯ä»¥åŒ¹é…'sina.com'ã€'sina.com.cn'å’Œ'www.sina.com',但ä¸åŒ¹é…'sina.cn'。" + +msgid "Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'." +msgstr "正则表达å¼: ç”±'regexp:'开始,余下部分是一个正则表达å¼ã€‚当此正则表达å¼åŒ¹é…ç›®æ ‡åŸŸåæ—¶ï¼Œè¯¥è§„则生效。例如'regexp:\\.goo.*\\.com$'匹é…'www.google.com'ã€'fonts.googleapis.com',但ä¸åŒ¹é…'google.com'。" + +msgid "Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'." +msgstr "å­åŸŸå (推è): ç”±'domain:'开始,余下部分是一个域åã€‚å½“æ­¤åŸŸåæ˜¯ç›®æ ‡åŸŸå或其å­åŸŸå时,该规则生效。例如'domain:v2ray.com'匹é…'www.v2ray.com'ã€'v2ray.com',但ä¸åŒ¹é…'xv2ray.com'。" + +msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'." +msgstr "完整匹é…: ç”±'full:'开始,余下部分是一个域å。当此域å完整匹é…ç›®æ ‡åŸŸåæ—¶ï¼Œè¯¥è§„则生效。例如'full:v2ray.com'匹é…'v2ray.com'但ä¸åŒ¹é…'www.v2ray.com'。" + +msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn." +msgstr "预定义域å列表:由'geosite:'开头,余下部分是一个å称,如geosite:google或者geosite:cn。" + +msgid "Sing-Box is compatible with Geo rules and rule-set. rule-set begin with 'rule-set:remote:' or 'rule-set:local:'." +msgstr "Sing-Box å¯å…¼å®¹ Geo 规则和规则集,规则集由 'rule-set:remote:' 或 'rule-set:local:' 开始。" + +msgid "Such as:" +msgstr "例如:" + +msgid "Annotation: Begining with #" +msgstr "注释: ç”± # 开头" + +msgid "Invert match result." +msgstr "å选匹é…结果。" + +msgid "Only support Sing-Box." +msgstr "åªæ”¯æŒ Sing-Box。" + +msgid "IP: such as '127.0.0.1'." +msgstr "IP: 形如'127.0.0.1'。" + +msgid "CIDR: such as '127.0.0.0/8'." +msgstr "CIDR: 形如'10.0.0.0/8'." + +msgid "GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code." +msgstr "GeoIP: 形如'geoip:cn',必须以geoip:(å°å†™ï¼‰å¼€å¤´ï¼ŒåŽé¢è·ŸåŒå­—符国家代ç ï¼Œæ”¯æŒå‡ ä¹Žæ‰€æœ‰å¯ä»¥ä¸Šç½‘的国家。" + +msgid "Clear logs" +msgstr "清空日志" + +msgid "Only recommend to use with VLESS-TCP-XTLS-Vision." +msgstr "åªæŽ¨è与 VLESS-TCP-XTLS-Vision æ­é…使用。" + +msgid "Password" +msgstr "密ç " + +msgid "IV Check" +msgstr "IV 检查" + +msgid "UDP over TCP" +msgstr "TCP å°è£… UDP" + +msgid "Connection Timeout" +msgstr "连接超时时间" + +msgid "Local Port" +msgstr "本地端å£" + +msgid "Fast Open" +msgstr "快速打开" + +msgid "Pre-connections" +msgstr "预连接" + +msgid "Number of early established connections to reduce latency." +msgstr "预连接的数é‡ï¼Œç”¨äºŽé™ä½Žå»¶è¿Ÿã€‚" + +msgid "Need node support required" +msgstr "需è¦èŠ‚ç‚¹æ”¯æŒ" + +msgid "plugin" +msgstr "æ’ä»¶" + +msgid "Supports custom SIP003 plugins, Make sure the plugin is installed." +msgstr "支æŒè‡ªå®šä¹‰ SIP003 æ’ä»¶ï¼Œè¯·ç¡®ä¿æ’件已安装。" + +msgid "opts" +msgstr "æ’件选项" + +msgid "Protocol" +msgstr "åè®®åç§°" + +msgid "Protocol_param" +msgstr "åè®®å‚æ•°" + +msgid "Obfs" +msgstr "æ··æ·†" + +msgid "Obfs_param" +msgstr "æ··æ·†å‚æ•°" + +msgid "Plugin Name" +msgstr "æ’ä»¶åç§°" + +msgid "Plugin Arguments" +msgstr "æ’件傿•°" + +msgid "User Level" +msgstr "用户等级(level)" + +msgid "Transport" +msgstr "传输方å¼" + +msgid "Public Key" +msgstr "公钥" + +msgid "Private Key" +msgstr "ç§é’¥" + +msgid "Pre shared key" +msgstr "é¢å¤–的对称加密密钥" + +msgid "Local Address" +msgstr "本地地å€" + +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "用“,â€éš”开的å进制数字或 Base64 ç¼–ç å­—符串。" + +msgid "Camouflage Domain" +msgstr "伪装域å" + +msgid "Camouflage Type" +msgstr "伪装类型" + +msgid "Transport Layer Encryption" +msgstr "传输层加密" + +msgid "Whether or not transport layer encryption is enabled, \"none\" for unencrypted, \"tls\" for using TLS, \"xtls\" for using XTLS." +msgstr "是å¦å¯å…¥ä¼ è¾“层加密,支æŒçš„选项有 \"none\" 表示ä¸åŠ å¯†ï¼Œ\"tls\" 表示使用 TLS,\"xtls\" 表示使用 XTLS。" + +msgid "Transfer mode" +msgstr "传输模å¼" + +msgid "Do not send server name in ClientHello." +msgstr "ä¸è¦åœ¨ ClientHello 中å‘逿œåС噍å称。" + +msgid "Domain" +msgstr "域å" + +msgid "allowInsecure" +msgstr "å…许ä¸å®‰å…¨è¿žæŽ¥" + +msgid "Whether unsafe connections are allowed. When checked, Certificate validation will be skipped." +msgstr "是å¦å…许ä¸å®‰å…¨è¿žæŽ¥ã€‚当勾选时,将跳过è¯ä¹¦éªŒè¯ã€‚" + +msgid "%s Node Use Type" +msgstr "%s 节点使用类型" + +msgid "UDP relay mode" +msgstr "UDP 中继模å¼" + +msgid "Congestion control algorithm" +msgstr "拥塞控制算法" + +msgid "Heartbeat interval(second)" +msgstr "ä¿æ´»å¿ƒè·³åŒ…å‘é€é—´éš”(å•ä½ï¼šç§’)" + +msgid "Disable SNI" +msgstr "关闭 SNI æœåС噍å称指示" + +msgid "Enable 0-RTT QUIC handshake" +msgstr "客户端å¯ç”¨ 0-RTT QUIC è¿žæŽ¥æ¡æ‰‹" + +msgid "
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests." +msgstr "
none:默认值,ä¸è¿›è¡Œä¼ªè£…,å‘é€çš„æ•°æ®æ˜¯æ²¡æœ‰ç‰¹å¾çš„æ•°æ®åŒ…。
srtpï¼šä¼ªè£…æˆ SRTP æ•°æ®åŒ…ï¼Œä¼šè¢«è¯†åˆ«ä¸ºè§†é¢‘é€šè¯æ•°æ®ï¼ˆå¦‚ FaceTime)。
utpï¼šä¼ªè£…æˆ uTP æ•°æ®åŒ…,会被识别为 BT 下载数æ®ã€‚
wechat-video:伪装æˆå¾®ä¿¡è§†é¢‘通è¯çš„æ•°æ®åŒ…。
dtlsï¼šä¼ªè£…æˆ DTLS 1.2 æ•°æ®åŒ…。
wireguardï¼šä¼ªè£…æˆ WireGuard æ•°æ®åŒ…。(并䏿˜¯çœŸæ­£çš„ WireGuard åè®®)
dns:把æµé‡ä¼ªè£…æˆ DNS 请求。" + +msgid "Use it together with the DNS disguised type. You can fill in any domain." +msgstr "é…åˆä¼ªè£…类型 DNS 使用,å¯éšä¾¿å¡«ä¸€ä¸ªåŸŸå。" + +msgid "Auth" +msgstr "身份认è¯" + +msgid "Socks for authentication" +msgstr "Socks è®¤è¯æ–¹å¼" + +msgid "Socks protocol authentication, support anonymous and password." +msgstr "Socks åè®®çš„è®¤è¯æ–¹å¼ï¼Œæ”¯æŒåŒ¿åæ–¹å¼å’Œè´¦å·å¯†ç æ–¹å¼ã€‚" + +msgid "anonymous" +msgstr "匿å" + +msgid "User Password" +msgstr "è´¦å·å¯†ç " + +msgid "Username and Password must be used together!" +msgstr "è´¦å·å’Œå¯†ç å¿…é¡»åŒæ—¶ä½¿ç”¨ï¼" + +msgid "Node Number" +msgstr "节点数é‡" + +msgid "You can only set up a maximum of %s nodes for the time being, Used for access control." +msgstr "ç›®å‰æœ€å¤šåªèƒ½è®¾ç½® %s 个节点,用于给访问控制使用。" + +msgid "Prefer firewall tools" +msgstr "首选防ç«å¢™å·¥å…·" + +msgid "IPv6 TProxy" +msgstr "IPv6 逿˜Žä»£ç†(TProxy)" + +msgid "Experimental feature. Make sure that your node supports IPv6." +msgstr "实验特性,请确ä¿ä½ çš„节点支æŒIPv6" + +msgid "Status info" +msgstr "状æ€ä¿¡æ¯" + +msgid "Big icon" +msgstr "大图标" + +msgid "Show node check" +msgstr "显示节点检测" + +msgid "Show Show IP111" +msgstr "显示 IP111" + +msgid "Destination protocol" +msgstr "目标åè®®" + +msgid "Destination address" +msgstr "目标地å€" + +msgid "Destination port" +msgstr "目标端å£" + +msgid "Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used." +msgstr "æ˜¯å¦æŽ¥æ”¶ PROXY protocol,当该节点è¦è¢«å›žè½æˆ–被代ç†è½¬å‘时,必须å¯ç”¨ï¼Œå¦åˆ™ä¸èƒ½ä½¿ç”¨ã€‚" + +msgid "outbound node" +msgstr "出站节点" + +msgid "Custom Socks" +msgstr "自定义 Socks" + +msgid "Custom HTTP" +msgstr "自定义 HTTP" + +msgid "Custom Interface" +msgstr "自定义接å£" + +msgid "Interface" +msgstr "接å£" + +msgid "Bind Local" +msgstr "本机监å¬" + +msgid "When selected, it can only be accessed localhost." +msgstr "当勾选时,åªèƒ½æœ¬æœºè®¿é—®ã€‚" + +msgid "Accept LAN Access" +msgstr "接å—局域网访问" + +msgid "When selected, it can accessed lan , this will not be safe!" +msgstr "当勾选时,å¯ä»¥ç›´æŽ¥è®¿é—®å±€åŸŸç½‘,这将ä¸å®‰å…¨ï¼ï¼ˆéžç‰¹æ®Šæƒ…况ä¸å»ºè®®å¼€å¯ï¼‰" + +msgid "Enable Remote" +msgstr "å¯ç”¨è½¬å‘" + +msgid "You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more." +msgstr "您å¯ä»¥è½¬å‘到 Nginx/Caddy/V2ray/Xray WebSocket 等。" + +msgid "Remote Address" +msgstr "远程地å€" + +msgid "Remote Port" +msgstr "远程端å£" + +msgid "as:" +msgstr "如:" + +msgid "Public key absolute path" +msgstr "公钥文件ç»å¯¹è·¯å¾„" + +msgid "Private key absolute path" +msgstr "ç§é’¥æ–‡ä»¶ç»å¯¹è·¯å¾„" + +msgid "Can't find this file!" +msgstr "找ä¸åˆ°è¿™ä¸ªæ–‡ä»¶ï¼" + +msgid "Public key and Private key path can not be empty!" +msgstr "公钥和ç§é’¥æ–‡ä»¶è·¯å¾„ä¸èƒ½ä¸ºç©ºï¼" + +msgid "Server-Side" +msgstr "æœåŠ¡å™¨ç«¯" + +msgid "Server Config" +msgstr "æœåС噍é…ç½®" + +msgid "Users Manager" +msgstr "用户管ç†" + +msgid "Logs" +msgstr "日志" + +msgid "Log" +msgstr "日志" + +msgid "%s Node Log" +msgstr "%s 节点日志" + +msgid "Log Level" +msgstr "日志等级" + +msgid "Advanced log feature" +msgstr "高级日志功能" + +msgid "For professionals only." +msgstr "ä»…é™ä¸“业人士使用。" + +msgid "Persist log file directory" +msgstr "æŒä¹…性日志文件目录" + +msgid "The path to the directory used to store persist log files, the \"/\" at the end can be omitted. Leave it blank to disable this feature." +msgstr "用æ¥å­˜å‚¨æŒä¹…性日志文件的目录路径,末尾的 “/†å¯ä»¥çœç•¥ã€‚留空以ç¦ç”¨æ­¤åŠŸèƒ½ã€‚" + +msgid "Logging to system log" +msgstr "记录到系统日志" + +msgid "Logging to the system log for more advanced functions. For example, send logs to a dedicated log server." +msgstr "将日志记录到系统日志,以实现更加高级的功能。例如,把日志å‘é€åˆ°ä¸“门的日志æœåŠ¡å™¨ã€‚" + +msgid "Log Event Filter" +msgstr "日志事件过滤器" + +msgid "Support regular expression." +msgstr "æ”¯æŒæ­£åˆ™è¡¨è¾¾å¼ã€‚" + +msgid "Shell Command" +msgstr "Shell 命令" + +msgid "Shell command to execute, replace log content with %s." +msgstr "è¦æ‰§è¡Œçš„ Shell 命令,用 %s 代替日志内容。" + +msgid "Not enabled log" +msgstr "未å¯ç”¨æ—¥å¿—" + +msgid "It is recommended to disable logging during regular use to reduce system overhead." +msgstr "正常使用时建议关闭日志,以å‡å°‘系统开销。" + +msgid "UDP Forward" +msgstr "UDP 转å‘" + +msgid "DNS Settings" +msgstr "DNS 设置" + +msgid "Null" +msgstr "æ— " + +msgid "You did not fill in the %s path. Please save and apply then update manually." +msgstr "您没有填写 %s 路径。请ä¿å­˜åº”用åŽå†æ‰‹åŠ¨æ›´æ–°ã€‚" + +msgid "Not installed %s, Can't unzip!" +msgstr "未安装 %s,无法解压ï¼" + +msgid "Can't determine ARCH, or ARCH not supported." +msgstr "无法确认ARCHæž¶æž„ï¼Œæˆ–æ˜¯ä¸æ”¯æŒã€‚" + +msgid "Get remote version info failed." +msgstr "获å–远程版本信æ¯å¤±è´¥ã€‚" + +msgid "New version found, but failed to get new version download url." +msgstr "å‘现新版本,但未能获得新版本的下载地å€ã€‚" + +msgid "Download url is required." +msgstr "请指定下载地å€ã€‚" + +msgid "File download failed or timed out: %s" +msgstr "文件下载失败或超时:%s" + +msgid "File path required." +msgstr "请指定文件路径。" + +msgid "%s not enough space." +msgstr "%s 空间ä¸è¶³ã€‚" + +msgid "Can't find client in file: %s" +msgstr "无法在文件中找到客户端:%s" + +msgid "Client file is required." +msgstr "请指定客户端文件。" + +msgid "The client file is not suitable for current device." +msgstr "客户端文件ä¸é€‚åˆå½“å‰è®¾å¤‡ã€‚" + +msgid "Can't move new file to path: %s" +msgstr "无法移动新文件到:%s" + +msgid "An XHttpObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ XHttpObject,用æ¥å®žçŽ°åˆ†äº«ã€‚" + +msgid "Enable Mux.Cool" +msgstr "å¯ç”¨ Mux.Cool" + +msgid "Mux concurrency" +msgstr "最大并å‘连接数" + +msgid "XUDP Mux concurrency" +msgstr "XUDP 最大并å‘连接数" + +msgid "Padding" +msgstr "å¡«å……" + +msgid "Enable early data" +msgstr "å¯ç”¨å‰ç½®æ•°æ®" + +msgid "Early data length" +msgstr "å‰ç½®æ•°æ®æœ€å¤§é•¿åº¦" + +msgid "Early data header name" +msgstr "å‰ç½®æ•°æ® HTTP 头å" + +msgid "Recommended value: Sec-WebSocket-Protocol" +msgstr "推è值:Sec-WebSocket-Protocol" + +msgid "Health check" +msgstr "å¥åº·æ£€æŸ¥" + +msgid "Health check timeout" +msgstr "检查超时时间" + +msgid "Permit without stream" +msgstr "æ— å­è¿žæŽ¥æ—¶çš„å¥åº·æ£€æŸ¥" + +msgid "Initial Windows Size" +msgstr "åˆå§‹çª—å£å¤§å°" + +msgid "Excluded Domains" +msgstr "排除域å" + +msgid "If the traffic sniffing result is in this list, the destination address will not be overridden." +msgstr "如果æµé‡å—…探结果在此列表中,则ä¸ä¼šè¦†ç›–目标地å€ã€‚" + +msgid "Buffer Size" +msgstr "缓冲区大å°" + +msgid "Buffer size for every connection (kB)" +msgstr "æ¯ä¸€ä¸ªè¿žæŽ¥çš„缓冲区大å°ï¼ˆkB)" + +msgid "Idle Timeout" +msgstr "空闲超时" + +msgid "Hop Interval(second)" +msgstr "端å£è·³è·ƒé—´éš”(秒)" + +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "支æŒå›ºå®šå€¼æˆ–éšæœºèŒƒå›´ï¼ˆå¦‚ 30 或 5-30ï¼‰ï¼Œæœ€å° 5 秒。" + +msgid "HeartbeatPeriod(second)" +msgstr "心跳周期(å•ä½ï¼šç§’)" + +msgid "Override the connection destination address" +msgstr "覆盖连接目标地å€" + +msgid "Handshake Server" +msgstr "æ¡æ‰‹æœåС噍" + +msgid "Handshake Server Port" +msgstr "æ¡æ‰‹æœåŠ¡å™¨ç«¯å£" + +msgid "Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "用探测出的域å覆盖连接目标地å€ã€‚
å¦åˆ™ä»…将探测得到的域å用于路由。
如使用分æµèŠ‚ç‚¹ï¼Œè¯·æ­£ç¡®è®¾ç½®åŸŸå分æµè§„则。" + +msgid "Override the connection destination address with the sniffed domain.
When enabled, traffic will match only by domain, ignoring IP rules.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "用探测出的域å覆盖连接目标地å€ã€‚
å¯ç”¨åŽä»…使用域å进行æµé‡åŒ¹é…,将忽略IP规则。
如使用分æµèŠ‚ç‚¹ï¼Œè¯·æ­£ç¡®è®¾ç½®åŸŸå分æµè§„则。" + +msgid "Protocol parameter. Will waste traffic randomly if enabled." +msgstr "åè®®å‚æ•°ã€‚如果å¯ç”¨ä¼šéšæœºæµªè´¹æµé‡ã€‚" + +msgid "Protocol parameter. Enable length block encryption." +msgstr "åè®®å‚æ•°ã€‚å¯ç”¨é•¿åº¦å—加密。" + +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "TLS è¯ä¹¦é“¾æŒ‡çº¹ï¼ˆSHA256)" + +msgid "Once set, connects only when the server’s chain fingerprint matches." +msgstr "设置åŽï¼Œä»…在æœåС噍è¯ä¹¦é“¾æŒ‡çº¹åŒ¹é…时连接。" + +msgid "TLS Certificate Name (CertName)" +msgstr "TLS è¯ä¹¦å称(CertName)" + +msgid "TLS is used to verify the leaf certificate name." +msgstr "TLS ç”¨äºŽéªŒè¯ leaf è¯ä¹¦çš„ name。" + +msgid "Fetch Manually" +msgstr "手动获å–" + +msgid "Fetch Failed" +msgstr "获å–失败" + +msgid "ECH Config" +msgstr "ECH é…ç½®" + +msgid "ECH Key" +msgstr "ECH 密钥" + +msgid "ECH Query Domain" +msgstr "ECH 查询域å" + +msgid "Overrides the domain name used for ECH HTTPS record queries." +msgstr "覆盖用于 ECH HTTPS 记录查询的域å。" + +msgid "Enable Multipath TCP, need to be enabled in both server and client configuration." +msgstr "å¯ç”¨ Multipath TCP,需在æœåŠ¡ç«¯å’Œå®¢æˆ·ç«¯é…ç½®ä¸­åŒæ—¶å¯ç”¨ã€‚" + +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ FinalMaskObject,用æ¥å®žçŽ°åˆ†äº«ã€‚" + +msgid "Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings." +msgstr "自定义 finalmask 将覆盖 mkcpã€hysteria2ã€fragmentã€noise 等相关é…置。" + +msgid "Fragment" +msgstr "分片" + +msgid "TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists." +msgstr "TCP 分片,在æŸäº›æƒ…况下å¯ä»¥æ¬ºéª—审查系统,比如绕过 SNI 黑åå•。" + +msgid "Fragment Packets" +msgstr "分片方å¼" + +msgid "\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation." +msgstr "\"1-3\" 是 TCP çš„æµåˆ‡ç‰‡ï¼Œåº”用于客户端第 1 至第 3 次写数æ®ã€‚\"tlshello\" 是 TLS æ¡æ‰‹åŒ…切片。" + +msgid "Fragment Length" +msgstr "分片包长" + +msgid "Fragmented packet length (byte)" +msgstr "分片包长 (byte)" + +msgid "Fragment Delay" +msgstr "分片延迟" + +msgid "Fragmentation interval (ms)" +msgstr "分片间隔(ms)" + +msgid "Max Split" +msgstr "最大分片数" + +msgid "Limit the maximum number of splits." +msgstr "é™åˆ¶åˆ†ç‰‡çš„æœ€å¤§æ•°é‡ã€‚" + +msgid "Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first." +msgstr "å°†æ¡æ‰‹æ•°æ®æ‹†åˆ†ä¸ºå¤šä¸ª TLS 记录,æå‡æŠ—å°é”能力,几乎ä¸å¢žåŠ å»¶è¿Ÿï¼Œå»ºè®®ä¼˜å…ˆå¯ç”¨ã€‚" + +msgid "Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed." +msgstr "å°† TLS æ¡æ‰‹æ•°æ®åˆ†ä¸ºå¤šä¸ª TCP 包å‘é€ï¼Œæé«˜ä¼ªè£…性,å¯èƒ½å¢žåŠ å»¶è¿Ÿï¼Œä»…åœ¨å°é”䏥釿—¶ä½¿ç”¨ã€‚" + +msgid "Noise" +msgstr "噪声" + +msgid "UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions." +msgstr "UDP 噪声,在æŸäº›æƒ…况下å¯ä»¥ç»•过一些针对 UDP å议的é™åˆ¶ã€‚" + +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "在 Xray 设置中勾选 “噪声†以å‘é€å™ªå£°åŒ…。" + +msgid "Xray Noise Packets" +msgstr "Xray 噪声数æ®åŒ…" + +msgid "Packet | Rand Length" +msgstr "æ•°æ®åŒ… | Rand 长度" + +msgid "Delay (ms)" +msgstr "延迟(ms)" + +msgid "If is domain name, The requested domain name will be resolved to IP before connect." +msgstr "如果是域å,域å将在请求å‘出之å‰è§£æžä¸º IP。" + +msgid "Domain DNS Resolve" +msgstr "域å DNS è§£æž" + +msgid "If the node address is a domain name, this DNS will be used for resolution." +msgstr "å¦‚æžœèŠ‚ç‚¹åœ°å€æ˜¯åŸŸå,则将使用此 DNS 进行解æžã€‚" + +msgid "Note: For node-specific DNS only. Keep Auto to avoid extra overhead." +msgstr "注æ„:仅用于节点专用 DNSï¼Œé€šå¸¸è¯·ä¿æŒè‡ªåŠ¨ï¼Œä»¥å…增加开销。" + +msgid "Supports only Xray or Sing-box node types." +msgstr "ä»…æ”¯æŒ Xray 或 Sing-box 类型节点。" + +msgid "Chain Proxy" +msgstr "链å¼ä»£ç†" + +msgid "Outbound Interface" +msgstr "出站接å£" + +msgid "Landing Node" +msgstr "è½åœ°èŠ‚ç‚¹" + +msgid "Only support a layer of proxy." +msgstr "仅支æŒä¸€å±‚代ç†ã€‚" + +msgid "" +"Chained proxy works only with Xray or Sing-box nodes.
" +"You can only use manual or imported nodes as chained nodes." +msgstr "" +"链å¼ä»£ç†ä»…æ”¯æŒ Xray 或 Sing-box 节点。
" +"ä»…æ”¯æŒæ‰‹åŠ¨æ·»åŠ æˆ–å¯¼å…¥çš„èŠ‚ç‚¹ç”¨ä½œé“¾å¼èŠ‚ç‚¹ã€‚" + +msgid "Only work with using the %s node." +msgstr "与使用 %s 节点时生效。" + +msgid "Total Lines" +msgstr "总行数:" + +msgid "Read List" +msgstr "读å–列表" + +msgid "Maintain" +msgstr "维护" + +msgid "Backup and Restore" +msgstr "备份还原" + +msgid "Backup or Restore Client and Server Configurations." +msgstr "å¤‡ä»½æˆ–è¿˜åŽŸå®¢æˆ·ç«¯åŠæœåŠ¡ç«¯é…置。" + +msgid "Note: Restoring configurations across different versions may cause compatibility issues." +msgstr "注æ„:ä¸åŒç‰ˆæœ¬é—´çš„é…ç½®æ¢å¤å¯èƒ½ä¼šå¯¼è‡´å…¼å®¹æ€§é—®é¢˜ã€‚" + +msgid "Create Backup File" +msgstr "创建备份文件" + +msgid "Restore Backup File" +msgstr "æ¢å¤å¤‡ä»½æ–‡ä»¶" + +msgid "DL Backup" +msgstr "下载备份" + +msgid "RST Backup" +msgstr "æ¢å¤å¤‡ä»½" + +msgid "UL Restore" +msgstr "上传æ¢å¤" + +msgid "CLOSE WIN" +msgstr "关闭窗å£" + +msgid "Restore to default configuration" +msgstr "æ¢å¤é»˜è®¤é…ç½®" + +msgid "Do Reset" +msgstr "执行é‡ç½®" + +msgid "Please select a file first." +msgstr "请先选择一个文件。" + +msgid "Invalid file type. Please upload a .tar.gz file." +msgstr "文件类型无效,请上传一个 .tar.gz 文件。" + +msgid "File size exceeds 10MB limit." +msgstr "文件大å°è¶…过 10MB é™åˆ¶ã€‚" + +msgid "Do you want to restore the client to default settings?" +msgstr "是å¦è¦æ¢å¤å®¢æˆ·ç«¯é»˜è®¤é…置?" + +msgid "Are you sure you want to restore the client to default settings?" +msgstr "是å¦çœŸçš„è¦æ¢å¤å®¢æˆ·ç«¯é»˜è®¤é…置?" + +msgid "_urltest" +msgstr "URLTest" + +msgid "URLTest node list" +msgstr "URLTest 节点列表" + +msgid "List of nodes to test, document" +msgstr "è¦æµ‹è¯•的节点列表,文档原ç†" + +msgid "Test interval" +msgstr "测试间隔" + +msgid "Test interval must be less or equal than idle timeout." +msgstr "测试间隔时间必须å°äºŽæˆ–等于空闲超时时间。" + +msgid "Test tolerance" +msgstr "测试容差" + +msgid "The test tolerance in milliseconds." +msgstr "测试容差时间(å•ä½ï¼šæ¯«ç§’)。" + +msgid "Idle timeout" +msgstr "空闲超时" + +msgid "The idle timeout." +msgstr "空闲超时时间。" + +msgid "Interrupt existing connections" +msgstr "中断现有连接" + +msgid "Interrupt existing connections when the selected outbound has changed." +msgstr "当选择的出站å‘生å˜åŒ–时中断现有连接。" + +msgid "Port hopping range" +msgstr "端å£è·³è·ƒèŒƒå›´" + +msgid "Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,)." +msgstr "æ ¼å¼ä¸ºï¼š1000:2000 或 1000-2000 多组时用逗å·(,)隔开。" + +msgid "Use Custom Config" +msgstr "使用自定义é…ç½®" + +msgid "Custom Config" +msgstr "自定义é…ç½®" + +msgid "Must be JSON text!" +msgstr "必须是 JSON 文本内容ï¼" + +msgid "Geo View" +msgstr "Geo 查询" + +msgid "Query" +msgstr "查询" + +msgid "Querying" +msgstr "查询中" + +msgid "Please enter query content!" +msgstr "请输入查询内容ï¼" + +msgid "No results were found!" +msgstr "未找到任何结果ï¼" + +msgid "Rules containing this value:" +msgstr "所在规则列表:" + +msgid "Domain/IP Query" +msgstr "域å/IP 查询" + +msgid "GeoIP/Geosite Query" +msgstr "GeoIP/Geosite 查询" + +msgid "Enter a domain or IP to query the Geo rule list they belong to." +msgstr "输入域å/IP,查询它们所在的 Geo 规则列表。" + +msgid "Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw" +msgstr "输入 GeoIP/Geosite,æå–它们所包å«çš„域å/IP。格å¼ï¼šgeoip:cn 或 geosite:gfw" + +msgid "Tips:" +msgstr "å°è´´å£«ï¼š" + +msgid "By entering a domain or IP, you can query the Geo rule list they belong to." +msgstr "å¯ä»¥é€šè¿‡è¾“入域å/IP,查询它们所在的 Geo 规则列表。" + +msgid "By entering a GeoIP or Geosite, you can extract the domains/IPs they contain." +msgstr "å¯ä»¥é€šè¿‡è¾“å…¥ GeoIP/Geosite,æå–它们所包å«çš„域å/IP。" + +msgid "Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct." +msgstr "利用 GeoIP/Geosite 查询功能,å¯ä»¥éªŒè¯è¾“入的 Geo è§„åˆ™æ˜¯å¦æ­£ç¡®ã€‚" + +msgid "Private Key Passphrase" +msgstr "ç§é’¥æŒ‡çº¹" + +msgid "Host Key" +msgstr "主机密钥" + +msgid "Accept any if empty." +msgstr "ç•™ç©ºåˆ™ä¸æ ¡éªŒã€‚" + +msgid "Host Key Algorithms" +msgstr "主机密钥算法" + +msgid "Client Version" +msgstr "客户端版本" + +msgid "Random version will be used if empty." +msgstr "å¦‚ç•™ç©ºï¼Œåˆ™ä½¿ç”¨éšæœºç‰ˆæœ¬ã€‚" + +msgid "The configured type also applies to the core specified when manually importing nodes." +msgstr "é…ç½®çš„ç±»åž‹åŒæ ·é€‚用于手动导入节点时所指定的核心程åºã€‚" + +msgid "Group Name" +msgstr "分组å" + +msgid "Reassign Group" +msgstr "调整分组" + +msgid "Reassign Node Group" +msgstr "调整节点分组" + +msgid "Currently using %s node" +msgstr "当å‰ä½¿ç”¨çš„ %s 节点" + +msgid "Search nodes..." +msgstr "æœç´¢èŠ‚ç‚¹â€¦" + +msgid "Concurrent Tunnels" +msgstr "å¹¶å‘éš§é“连接数" + +msgid "Processing, please wait…" +msgstr "正在处ç†ï¼Œè¯·ç¨å€™â€¦" diff --git a/luci-app-passwall/po/zh_Hans b/luci-app-passwall/po/zh_Hans new file mode 120000 index 00000000..41451e4a --- /dev/null +++ b/luci-app-passwall/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/luci-app-passwall/root/etc/config/passwall_server b/luci-app-passwall/root/etc/config/passwall_server new file mode 100644 index 00000000..c9526cb2 --- /dev/null +++ b/luci-app-passwall/root/etc/config/passwall_server @@ -0,0 +1,4 @@ + +config global 'global' + option enable '0' + diff --git a/luci-app-passwall/root/etc/hotplug.d/iface/98-passwall b/luci-app-passwall/root/etc/hotplug.d/iface/98-passwall new file mode 100644 index 00000000..e0c8277b --- /dev/null +++ b/luci-app-passwall/root/etc/hotplug.d/iface/98-passwall @@ -0,0 +1,35 @@ +#!/bin/sh + +. /usr/share/passwall/utils.sh + +[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || exit 0 + +([ "$(get_cache_var "ENABLED_DEFAULT_ACL")" = "1" ] || [ "$(get_cache_var "ENABLED_ACLS")" = "1" ]) && [ -f ${LOCK_PATH}/${CONFIG}_ready.lock ] && { + + default_device=$(ip route show default 2>/dev/null | awk -F 'dev ' '{print $2}' | awk '{print $1}' | head -n1) + default6_device=$(ip -6 route show default 2>/dev/null | awk -F 'dev ' '{print $2}' | awk '{print $1}' | head -n1) + ( [ "$default_device" = "$DEVICE" ] || [ "$default6_device" = "$DEVICE" ] ) && { + + if [ "$ACTION" = "ifupdate" ]; then + USE_TABLES=$(get_cache_var "USE_TABLES") + [ -n "$USE_TABLES" ] && { ${APP_PATH}/${USE_TABLES}.sh update_wan_sets >/dev/null 2>&1 & } + exit 0 + fi + + [ ! -d ${LOCK_PATH} ] && mkdir -p ${LOCK_PATH} + LOCK_FILE="${LOCK_PATH}/${CONFIG}_ifup.lock" + if [ -s ${LOCK_FILE} ]; then + SPID=$(cat ${LOCK_FILE}) + if [ -e /proc/${SPID}/status ]; then + exit 1 + fi + cat /dev/null > ${LOCK_FILE} + fi + echo $$ > ${LOCK_FILE} + + /etc/init.d/${CONFIG} restart >/dev/null 2>&1 & + logger -p notice -t network -s "${CONFIG}: restart when $INTERFACE ifup" + + rm -rf ${LOCK_FILE} + } +} diff --git a/luci-app-passwall/root/etc/init.d/passwall b/luci-app-passwall/root/etc/init.d/passwall new file mode 100755 index 00000000..189836f8 --- /dev/null +++ b/luci-app-passwall/root/etc/init.d/passwall @@ -0,0 +1,86 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=15 + +ROOT="${IPKG_INSTROOT:-}" +. "$ROOT/usr/share/passwall/utils.sh" +APP_FILE=${APP_PATH}/app.sh +LOCK_FILE_DIR=/var/lock +LOCK_FILE=${LOCK_FILE_DIR}/${CONFIG}.lock + +set_lock() { + [ ! -d "$LOCK_FILE_DIR" ] && mkdir -p $LOCK_FILE_DIR + exec 999>"$LOCK_FILE" + flock -xn 999 +} + +unset_lock() { + flock -u 999 + rm -rf "$LOCK_FILE" +} + +unlock() { + failcount=1 + while [ "$failcount" -le 10 ]; do + if [ -f "$LOCK_FILE" ]; then + let "failcount++" + sleep 1s + [ "$failcount" -ge 10 ] && unset_lock + else + break + fi + done +} + +boot_func() { + local delay=$(uci -q get ${CONFIG}.@global_delay[0].start_delay || echo 1) + if [ "$delay" -gt 0 ]; then + echolog "执行å¯åŠ¨å»¶æ—¶ $delay ç§’åŽå†å¯åЍ!" + sleep $delay + fi + restart boot + touch ${LOCK_FILE_DIR}/${CONFIG}_ready.lock +} + +boot() { + boot_func >/dev/null 2>&1 & +} + +start() { + set_lock + [ $? == 1 ] && echolog "脚本已ç»åœ¨è¿è¡Œï¼Œä¸é‡å¤è¿è¡Œï¼Œé€€å‡º." && exit 0 + $APP_FILE start + unset_lock +} + +stop() { + unlock + set_lock + [ $? == 1 ] && echolog "åœæ­¢è„šæœ¬ç­‰å¾…è¶…æ—¶ï¼Œä¸é‡å¤è¿è¡Œï¼Œé€€å‡º." && exit 0 + $APP_FILE stop + unset_lock +} + +restart() { + set_lock + [ $? == 1 ] && echolog "脚本已ç»åœ¨è¿è¡Œï¼Œä¸é‡å¤è¿è¡Œï¼Œé€€å‡º." && exit 0 + rule_lock=${LOCK_FILE_DIR}/${CONFIG}_rule_update.lock + sub_lock=${LOCK_FILE_DIR}/${CONFIG}_subscribe.lock + for i in $(seq 1 300); do + if [ ! -f "$rule_lock" ] && [ ! -f "$sub_lock" ]; then + break + fi + sleep 2 + done + rm -f "$rule_lock" "$sub_lock" + $APP_FILE stop + $APP_FILE start $1 + unset_lock +} + +reload() { + echo "Warning: This service does not support configuration reloading" + echo "Performing full restart instead..." + restart +} diff --git a/luci-app-passwall/root/etc/init.d/passwall_server b/luci-app-passwall/root/etc/init.d/passwall_server new file mode 100755 index 00000000..f60b8c23 --- /dev/null +++ b/luci-app-passwall/root/etc/init.d/passwall_server @@ -0,0 +1,22 @@ +#!/bin/sh /etc/rc.common + +START=99 + +start() { + lua /usr/lib/lua/luci/passwall/server_app.lua start +} + +stop() { + lua /usr/lib/lua/luci/passwall/server_app.lua stop +} + +restart() { + stop + start +} + +reload() { + echo "Warning: This service does not support configuration reloading" + echo "Performing full restart instead..." + restart +} diff --git a/luci-app-passwall/root/etc/uci-defaults/luci-passwall b/luci-app-passwall/root/etc/uci-defaults/luci-passwall new file mode 100755 index 00000000..0a1d8fa4 --- /dev/null +++ b/luci-app-passwall/root/etc/uci-defaults/luci-passwall @@ -0,0 +1,58 @@ +#!/bin/sh + +if [ -e "/etc/config/ucitrack" ]; then + uci -q batch <<-EOF + delete ucitrack.@passwall[-1] + add ucitrack passwall + set ucitrack.@passwall[-1].init=passwall + delete ucitrack.@passwall_server[-1] + add ucitrack passwall_server + set ucitrack.@passwall_server[-1].init=passwall_server + commit ucitrack +EOF +fi + +uci -q batch <<-EOF + delete firewall.passwall + set firewall.passwall=include + set firewall.passwall.type='script' + set firewall.passwall.path='/var/etc/passwall.include' + + delete firewall.passwall_server + set firewall.passwall_server=include + set firewall.passwall_server.type='script' + set firewall.passwall_server.path='/var/etc/passwall_server.include' + + set dhcp.@dnsmasq[0].localuse=1 + commit dhcp + set uhttpd.main.max_requests=50 + commit uhttpd +EOF + +if [ -x "/sbin/fw3" ]; then + uci -q set firewall.passwall.reload='1' + uci -q set firewall.passwall_server.reload='1' +else + uci -q delete firewall.passwall.reload + uci -q delete firewall.passwall.fw4_compatible + uci -q delete firewall.passwall_server.reload + uci -q delete firewall.passwall_server.fw4_compatible +fi +uci commit firewall + +[ ! -s "/etc/config/passwall" ] && cp -f /usr/share/passwall/0_default_config /etc/config/passwall + +chmod +x /usr/share/passwall/*.sh + +[ "$(uci -q get passwall.@global_xray[0].sniffing)" == "1" ] && [ "$(uci -q get passwall.@global_xray[0].route_only)" != "1" ] && uci -q set passwall.@global_xray[0].sniffing_override_dest=1 +uci -q delete passwall.@global_xray[0].sniffing +uci -q delete passwall.@global_xray[0].route_only +uci -q commit passwall + +sed -i "s#add_from#group#g" /etc/config/passwall 2>/dev/null + +rm -f /tmp/luci-indexcache /tmp/luci-indexcache.* +rm -rf /tmp/luci-modulecache/ +killall -HUP rpcd 2>/dev/null + +exit 0 diff --git a/luci-app-passwall/root/usr/share/passwall/0_default_config b/luci-app-passwall/root/usr/share/passwall/0_default_config new file mode 100644 index 00000000..4c532d72 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/0_default_config @@ -0,0 +1,255 @@ + +config global + option enabled '0' + option socks_enabled '0' + option tcp_node_socks_port '1070' + option filter_proxy_ipv6 '1' + option dns_shunt 'chinadns-ng' + option dns_mode 'tcp' + option remote_dns '1.1.1.1' + list smartdns_remote_dns 'https://1.1.1.1/dns-query' + option use_default_dns 'direct' + option chinadns_ng_default_tag 'none' + option dns_redirect '1' + option use_direct_list '1' + option use_proxy_list '1' + option use_block_list '1' + option use_gfw_list '1' + option chn_list 'direct' + option tcp_proxy_mode 'proxy' + option udp_proxy_mode 'proxy' + option localhost_proxy '1' + option client_proxy '1' + option acl_enable '0' + option log_tcp '0' + option log_udp '0' + option loglevel 'error' + option log_chinadns_ng '0' + +config global_haproxy + option balancing_enable '0' + +config global_delay + option start_daemon '1' + option start_delay '60' + +config global_forwarding + option tcp_no_redir_ports 'disable' + option udp_no_redir_ports 'disable' + option tcp_proxy_drop_ports 'disable' + option udp_proxy_drop_ports '443' + option tcp_redir_ports '22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418' + option udp_redir_ports '1:65535' + option accept_icmp '0' + option prefer_nft '1' + option tcp_proxy_way 'redirect' + option ipv6_tproxy '0' + +config global_xray + option sniffing_override_dest '0' + +config global_singbox + +config global_other + option auto_detection_time 'tcping' + option show_node_info '0' + +config global_rules + option auto_update '0' + option chnlist_update '1' + option chnroute_update '1' + option chnroute6_update '1' + option gfwlist_update '1' + option geosite_update '0' + option geoip_update '0' + list gfwlist_url 'https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt' + list chnroute_url 'https://ispip.clang.cn/all_cn.txt' + list chnroute_url 'https://cdn.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china.txt' + list chnroute6_url 'https://ispip.clang.cn/all_cn_ipv6.txt' + list chnroute6_url 'https://cdn.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china6.txt' + list chnlist_url 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf' + list chnlist_url 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf' + option v2ray_location_asset '/usr/share/v2ray/' + option geoip_url 'https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat' + option geosite_url 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat' + +config global_app + option geoview_file '/usr/bin/geoview' + option sing_box_file '/usr/bin/sing-box' + option xray_file '/usr/bin/xray' + option hysteria_file '/usr/bin/hysteria' + +config global_subscribe + option filter_keyword_mode '1' + list filter_discard_list 'è·ç¦»ä¸‹æ¬¡é‡ç½®å‰©ä½™' + list filter_discard_list '套é¤åˆ°æœŸ' + list filter_discard_list '过期时间' + list filter_discard_list '剩余æµé‡' + list filter_discard_list 'QQ群' + list filter_discard_list '官网' + +config nodes 'myshunt' + option remarks 'åˆ†æµæ€»èŠ‚ç‚¹' + option type 'Xray' + option protocol '_shunt' + option DirectGame '_direct' + option ProxyGame '_default' + option AIGC '_default' + option Streaming '_default' + option Proxy '_default' + option Direct '_direct' + option default_node '_direct' + option domainStrategy 'IPOnDemand' + +config shunt_rules 'DirectGame' + option remarks 'DirectGame' + option network 'tcp,udp' + option domain_list '# steam直连域å获å–国内CDN走国内线路下载 +cm.steampowered.com +steamserver.net + +# steam国内CDNåŽä¸ºäº‘ +steampipe.steamcontent.tnkjmec.com +# steam国内CDN白山云 +st.dl.eccdnx.com +st.dl.bscstorage.net +st.dl.pinyuncloud.com +# steam国内CDNæ–°æµäº‘(原金山云)(支æŒipv6) +dl.steam.clngaa.com +# steam国内CDN网宿 +cdn.mileweb.cs.steampowered.com.8686c.com +cdn-ws.content.steamchina.com +# steam国内CDN腾讯云 (蒸汽中国独å ) +cdn-qc.content.steamchina.com +# steam国内CDN阿里云(支æŒipv6) +cdn-ali.content.steamchina.com +xz.pphimalayanrt.com +lv.queniujq.cn +alibaba.cdn.steampipe.steamcontent.com + +# 国内游æˆgeosite域å +geosite:category-games@cn' + option ip_list '# steam直连IP +45.121.184.0/24 +103.10.124.0/23 +103.28.54.0/24 +146.66.152.0/24 +146.66.155.0/24 +153.254.86.0/24 +155.133.224.0/22 +155.133.230.0/24 +155.133.232.0/23 +155.133.234.0/24 +155.133.236.0/22 +155.133.240.0/23 +155.133.244.0/23 +155.133.246.0/24 +155.133.248.0/21 +162.254.192.0/21 +185.25.182.0/23 +190.217.32.0/22 +192.69.96.0/22 +205.196.6.0/24 +208.64.200.0/22 +208.78.164.0/22 +205.185.194.0/24' + +config shunt_rules 'ProxyGame' + option remarks 'ProxyGame' + option network 'tcp,udp' + option domain_list '# steam 商店/客æœ/èŠå¤©/网页布局/API/二维ç /Googleäº‘åŒæ­¥ 代ç†URL +steamcommunity.com +www.steamcommunity.com +store.steampowered.com +checkout.steampowered.com +api.steampowered.com +help.steampowered.com +login.steampowered.com +store.akamai.steamstatic.com +steambroadcast.akamaized.net +steamvideo-a.akamaihd.net +steamusercontent-a.akamaihd.net +steamstore-a.akamaihd.net +steamcommunity-a.akamaihd.net +steamcdn-a.akamaihd.net +steamuserimages-a.akamaihd.net +community.akamai.steamstatic.com +avatars.akamai.steamstatic.com +community.steamstatic.com +cdn.akamai.steamstatic.com +avatars.steamstatic.com +shared.akamai.steamstatic.com +clan.akamai.steamstatic.com +cdn.cloudflare.steamstatic.com +community.cloudflare.steamstatic.com +store.cloudflare.steamstatic.com +avatars.cloudflare.steamstatic.com +clan.cloudflare.steamstatic.com +shared.cloudflare.steamstatic.com +steam-chat.com +steamcloud-ugc.storage.googleapis.com +steamcloud-eu-ams.storage.googleapis.com +steamcloud-eu-fra.storage.googleapis.com +steamcloud-finland.storage.googleapis.com +steamcloud-saopaulo.storage.googleapis.com +steamcloud-singapore.storage.googleapis.com +steamcloud-sydney.storage.googleapis.com +steamcloud-taiwan.storage.googleapis.com +steamcloud-eu.storage.googleapis.com +domain:blizzard.com +geosite:category-games' + +config shunt_rules 'AIGC' + option remarks 'AIGC' + option network 'tcp,udp' + option domain_list 'geosite:category-ai-!cn +geosite:apple-intelligence' + +config shunt_rules 'Streaming' + option remarks 'Streaming' + option network 'tcp,udp' + option domain_list 'geosite:netflix +geosite:disney' + +config shunt_rules 'Proxy' + option remarks 'Proxy' + option network 'tcp,udp' + option domain_list 'geosite:geolocation-!cn' + option ip_list '149.154.160.0/20 +91.108.4.0/22 +91.108.56.0/24 +109.239.140.0/24 +67.198.55.0/24 +8.8.4.4 +8.8.8.8 +208.67.222.222 +208.67.220.220 +1.1.1.1 +1.1.1.2 +1.0.0.1 +9.9.9.9 +149.112.112.112 +2001:67c:4e8::/48 +2001:b28:f23c::/48 +2001:b28:f23d::/48 +2001:b28:f23f::/48 +2001:b28:f242::/48 +2001:4860:4860::8888 +2001:4860:4860::8844 +2606:4700:4700::1111 +2606:4700:4700::1001' + +config shunt_rules 'Direct' + option remarks 'Direct' + option network 'tcp,udp' + option domain_list 'geosite:cn' + option ip_list '223.5.5.5/32 +223.6.6.6/32 +119.29.29.29/32 +180.76.76.76/32 +114.114.114.114/32 +114.114.115.115/32 +1.12.12.12/32 +120.53.53.53/32 +geoip:cn +geoip:private' diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh new file mode 100755 index 00000000..d1668ad4 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -0,0 +1,2074 @@ +#!/bin/sh +# Copyright (C) 2018-2020 L-WRT Team +# Copyright (C) 2021-2025 xiaorouji +# Copyright (C) 2026 Openwrt-Passwall Organization + +. /lib/functions.sh +. /lib/functions/service.sh +. /usr/share/libubox/jshn.sh + +. /usr/share/passwall/utils.sh +GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default +LUA_UTIL_PATH=/usr/lib/lua/luci/passwall +UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua +UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua +UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua +UTIL_NAIVE=$LUA_UTIL_PATH/util_naiveproxy.lua +UTIL_HYSTERIA2=$LUA_UTIL_PATH/util_hysteria2.lua +SINGBOX_BIN=$(first_type $(config_t_get global_app sing_box_file) sing-box) +XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray) + +check_run_environment() { + local prefer_nft=$(config_t_get global_forwarding prefer_nft 1) + local dnsmasq_info=$(dnsmasq -v 2>/dev/null) + local dnsmasq_ver=$(echo "$dnsmasq_info" | sed -n '1s/.*version \([0-9.]*\).*/\1/p') + # local dnsmasq_opts=$(echo "$dnsmasq_info" | grep -i "Compile time options") + local dnsmasq_ipset=0; echo "$dnsmasq_info" | grep -qw "ipset" && dnsmasq_ipset=1 + local dnsmasq_nftset=0; echo "$dnsmasq_info" | grep -qw "nftset" && dnsmasq_nftset=1 + local has_ipt=0; { command -v iptables-legacy || command -v iptables; } >/dev/null && has_ipt=1 + local has_ipset=$(command -v ipset >/dev/null && echo 1 || echo 0) + local has_fw4=$(command -v fw4 >/dev/null && echo 1 || echo 0) + if [ "$prefer_nft" = "1" ]; then + if [ "$dnsmasq_nftset" -eq 1 ] && [ "$has_fw4" -eq 1 ]; then + USE_TABLES="nftables" + elif [ "$has_ipset" -eq 1 ] && [ "$has_ipt" -eq 1 ] && [ "$dnsmasq_ipset" -eq 1 ]; then + echolog "警告:nftables (fw4) 应用环境ä¸å®Œæ•´ï¼Œåˆ‡æ¢è‡³ iptables。(has_fw4:$has_fw4/dnsmasq_nftset:$dnsmasq_nftset)" + USE_TABLES="iptables" + fi + else + if [ "$has_ipset" -eq 1 ] && [ "$has_ipt" -eq 1 ] && [ "$dnsmasq_ipset" -eq 1 ]; then + USE_TABLES="iptables" + elif [ "$dnsmasq_nftset" -eq 1 ] && [ "$has_fw4" -eq 1 ]; then + echolog "警告:iptables (fw3) 应用环境ä¸å®Œæ•´ï¼Œåˆ‡æ¢è‡³ nftables。(has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_ipset:$dnsmasq_ipset)" + USE_TABLES="nftables" + fi + fi + + if [ -n "$USE_TABLES" ]; then + local dep_list + local file_path="/usr/lib/opkg/info" + local file_ext=".control" + [ -d "/lib/apk/packages" ] && { file_path="/lib/apk/packages"; file_ext=".list"; } + + if [ "$USE_TABLES" = "iptables" ]; then + dep_list="iptables-mod-tproxy iptables-mod-socket iptables-mod-iprange iptables-mod-conntrack-extra kmod-ipt-nat" + else + dep_list="kmod-nft-socket kmod-nft-tproxy kmod-nft-nat" + nftflag=1 + local v_num=$(echo "$dnsmasq_ver" | tr -cd '0-9') + if [ "${v_num:-0}" -lt 290 ]; then + echolog "æç¤ºï¼šDnsmasq ($dnsmasq_ver) 低于 2.90,建议å‡çº§ä»¥å¢žå¼ºç¨³å®šæ€§ã€‚" + fi + fi + local pkg + for pkg in $dep_list; do + if [ ! -s "${file_path}/${pkg}${file_ext}" ]; then + echolog "警告:${USE_TABLES} 逿˜Žä»£ç†ç¼ºå¤±åŸºç¡€ä¾èµ– ${pkg}ï¼" + fi + done + else + echolog "è­¦å‘Šï¼šä¸æ»¡è¶³ä»»ä½•逿˜Žä»£ç†ç³»ç»ŸçŽ¯å¢ƒã€‚(has_fw4:$has_fw4/has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_nftset:$dnsmasq_nftset/dnsmasq_ipset:$dnsmasq_ipset)" + fi +} + +run_ipt2socks() { + local flag proto tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file + local _extra_param="" + eval_set_val $@ + [ -n "$log_file" ] || log_file="/dev/null" + socks_address=$(get_host_ip "ipv4" ${socks_address}) + [ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -a $socks_username -k $socks_password" + [ -n "$tcp_tproxy" ] || _extra_param="${_extra_param} -R" + case "$proto" in + UDP) + flag="${flag}_UDP" + _extra_param="${_extra_param} -U" + ;; + TCP) + flag="${flag}_TCP" + _extra_param="${_extra_param} -T" + ;; + *) + flag="${flag}_TCP_UDP" + ;; + esac + _extra_param="${_extra_param} -o 60 -n 65535 -v" + ln_run "$(first_type ipt2socks)" "ipt2socks_${flag}" $log_file -l $local_port -b 0.0.0.0 -s $socks_address -p $socks_port ${_extra_param} +} + +run_singbox() { + local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password + local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port + local loglevel log_file config_file server_host server_port no_run + eval_set_val $@ + [ -z "$type" ] && { + type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + [ "$type" != "sing-box" ] && [ -n "$SINGBOX_BIN" ] && type="sing-box" + } + [ -z "$type" ] && return 1 + [ -n "$log_file" ] || local log_file="/dev/null" + json_init + if [ "$log_file" = "/dev/null" ]; then + json_add_string "log" "0" + else + json_add_string "log" "1" + json_add_string "logfile" "${log_file}" + fi + [ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn") + [ "$loglevel" = "warning" ] && loglevel="warn" + json_add_string "loglevel" "$loglevel" + + [ -n "$flag" ] && json_add_string "flag" "$flag" + [ -n "$node" ] && json_add_string "node" "$node" + [ -n "$server_host" ] && json_add_string "server_host" "$server_host" + [ -n "$server_port" ] && json_add_string "server_port" "$server_port" + [ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port" + [ -n "$tcp_proxy_way" ] && json_add_string "tcp_proxy_way" "$tcp_proxy_way" + [ -n "$udp_redir_port" ] && json_add_string "udp_redir_port" "$udp_redir_port" + [ -n "$socks_address" ] && json_add_string "local_socks_address" "$socks_address" + [ -n "$socks_port" ] && json_add_string "local_socks_port" "$socks_port" + [ -n "$socks_username" ] && [ -n "$socks_password" ] && { + json_add_string "local_socks_username" "$socks_username" + json_add_string "local_socks_password" "$socks_password" + } + [ -n "$http_address" ] && json_add_string "local_http_address" "$http_address" + [ -n "$http_port" ] && json_add_string "local_http_port" "$http_port" + [ -n "$http_username" ] && [ -n "$http_password" ] && { + json_add_string "local_http_username" "$http_username" + json_add_string "local_http_password" "$http_password" + } + [ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && { + json_add_string "dns_socks_address" "${dns_socks_address}" + json_add_string "dns_socks_port" "${dns_socks_port}" + } + [ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}" + [ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}" + + if [ -n "$direct_dns_udp_server" ]; then + direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}') + json_add_string "direct_dns_udp_server" "$(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')" + elif [ -n "$direct_dns_tcp_server" ]; then + direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}') + json_add_string "direct_dns_tcp_server" "$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')" + else + local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",") + json_add_string "direct_dns_udp_server" "$(echo ${local_dns} | awk -F '#' '{print $1}')" + direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}') + fi + json_add_string "direct_dns_port" "${direct_dns_port:-53}" + direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP} + json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}" + + [ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}" + case "$remote_dns_protocol" in + udp|tcp) + local _proto="$remote_dns_protocol" + local _dns=$(get_first_dns remote_dns_${_proto}_server 53 | sed 's/#/:/g') + local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}') + local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}') + json_add_string "remote_dns_${_proto}_server" "${_dns_address}" + json_add_string "remote_dns_${_proto}_port" "${_dns_port}" + ;; + doh|http3) + json_add_string "remote_dns_doh" "${remote_dns_doh}" + [ "$remote_dns_protocol" = "http3" ] && json_add_string "remote_dns_http3" "1" + ;; + esac + + [ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}" + [ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1" + [ -n "$no_run" ] && json_add_string "no_run" "1" + local _json_arg="$(json_dump)" + lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file + [ -n "$no_run" ] && return + + local test_log_file=$log_file + [ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/${config_file##*/}_test.log" + $SINGBOX_BIN check -c "$config_file" > $test_log_file 2>&1; local status=$? + if [ "${status}" = 0 ]; then + ln_run "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file" + else + echolog "Sing-box é…置文件 $config_file 校验有误,进程å¯åŠ¨å¤±è´¥ï¼Œé”™è¯¯ä¿¡æ¯ï¼š" + cat ${test_log_file} >> ${LOG_FILE} + fi + [ "$test_log_file" != "$log_file" ] && rm -f "${test_log_file}" +} + +run_xray() { + local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password + local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port + local loglevel log_file config_file server_host server_port no_run + eval_set_val $@ + [ -z "$type" ] && { + type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + [ "$type" != "xray" ] && [ -n "$XRAY_BIN" ] && type="xray" + } + [ -z "$type" ] && return 1 + json_init + [ -n "$log_file" ] || local log_file="/dev/null" + [ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning") + [ -n "$flag" ] && json_add_string "flag" "$flag" + [ -n "$node" ] && json_add_string "node" "$node" + [ -n "$server_host" ] && json_add_string "server_host" "$server_host" + [ -n "$server_port" ] && json_add_string "server_port" "$server_port" + [ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port" + [ -n "$tcp_proxy_way" ] && json_add_string "tcp_proxy_way" "$tcp_proxy_way" + [ -n "$udp_redir_port" ] && json_add_string "udp_redir_port" "$udp_redir_port" + [ -n "$socks_address" ] && json_add_string "local_socks_address" "$socks_address" + [ -n "$socks_port" ] && json_add_string "local_socks_port" "$socks_port" + [ -n "$socks_username" ] && [ -n "$socks_password" ] && { + json_add_string "local_socks_username" "$socks_username" + json_add_string "local_socks_password" "$socks_password" + } + [ -n "$http_address" ] && json_add_string "local_http_address" "$http_address" + [ -n "$http_port" ] && json_add_string "local_http_port" "$http_port" + [ -n "$http_username" ] && [ -n "$http_password" ] && { + json_add_string "local_http_username" "$http_username" + json_add_string "local_http_password" "$http_password" + } + [ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && { + json_add_string "dns_socks_address" "${dns_socks_address}" + json_add_string "dns_socks_port" "${dns_socks_port}" + } + [ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}" + + if [ -n "$direct_dns_udp_server" ]; then + direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}') + json_add_string "direct_dns_udp_server" "$(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')" + elif [ -n "$direct_dns_tcp_server" ]; then + direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}') + json_add_string "direct_dns_tcp_server" "$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')" + else + local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",") + json_add_string "direct_dns_udp_server" "$(echo ${local_dns} | awk -F '#' '{print $1}')" + direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}') + fi + json_add_string "direct_dns_port" "${direct_dns_port:-53}" + + direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP} + json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}" + [ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}" + [ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}" + [ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1" + [ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}" + + case "$remote_dns_protocol" in + udp|tcp) + local _proto="$remote_dns_protocol" + local _dns=$(get_first_dns remote_dns_${_proto}_server 53 | sed 's/#/:/g') + local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}') + local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}') + json_add_string "remote_dns_${_proto}_server" "${_dns_address}" + json_add_string "remote_dns_${_proto}_port" "${_dns_port}" + ;; + doh) + json_add_string "remote_dns_doh" "${remote_dns_doh}" + ;; + esac + + json_add_string "loglevel" "$loglevel" + [ -n "$no_run" ] && json_add_string "no_run" "1" + local _json_arg="$(json_dump)" + lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file + [ -n "$no_run" ] && return + + local test_log_file=$log_file + [ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/${config_file##*/}_test.log" + $XRAY_BIN run -test -c "$config_file" > $test_log_file; local status=$? + if [ "${status}" = 0 ]; then + ln_run "$XRAY_BIN" "xray" "${log_file}" run -c "$config_file" + else + echolog "Xray é…置文件 $config_file 校验有误,进程å¯åŠ¨å¤±è´¥ï¼Œé”™è¯¯ä¿¡æ¯ï¼š" + cat ${test_log_file} >> ${LOG_FILE} + fi + [ "$test_log_file" != "$log_file" ] && rm -f "${test_log_file}" +} + +run_dns2socks() { + local flag socks socks_address socks_port socks_username socks_password listen_address listen_port dns cache log_file + local _extra_param="" + eval_set_val $@ + [ -n "$flag" ] && flag="_${flag}" + [ -n "$log_file" ] || log_file="/dev/null" + dns=$(get_first_dns dns 53 | sed 's/#/:/g') + [ -n "$socks" ] && { + socks="${socks//#/:}" + socks_address=$(echo $socks | awk -F ':' '{print $1}') + socks_port=$(echo $socks | awk -F ':' '{print $2}') + } + [ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} /u $socks_username /p $socks_password" + [ -z "$cache" ] && cache=1 + [ "$cache" = "0" ] && _extra_param="${_extra_param} /d" + ln_run "$(first_type dns2socks)" "dns2socks${flag}" $log_file ${_extra_param} "${socks_address}:${socks_port}" "${dns}" "${listen_address}:${listen_port}" +} + +run_chinadns_ng() { + local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag _no_logic_log _tcp_node _remote_fakedns _filter_https + local _extra_param="" + eval_set_val $@ + + local _CONF_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.conf + local _LOG_FILE="/dev/null" + [ "$(config_t_get global log_chinadns_ng "0")" == "1" ] && _LOG_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.log + + _extra_param="-FLAG ${_flag} -TCP_NODE ${_tcp_node} -LISTEN_PORT ${_listen_port} -DNS_LOCAL ${_dns_local} -DNS_TRUST ${_dns_trust}" + _extra_param="${_extra_param} -USE_DIRECT_LIST ${_use_direct_list} -USE_PROXY_LIST ${_use_proxy_list} -USE_BLOCK_LIST ${_use_block_list}" + _extra_param="${_extra_param} -GFWLIST ${_gfwlist} -CHNLIST ${_chnlist} -NO_IPV6_TRUST ${_no_ipv6_trust} -DEFAULT_MODE ${_default_mode}" + _extra_param="${_extra_param} -DEFAULT_TAG ${_default_tag} -NFTFLAG ${nftflag} -NO_LOGIC_LOG ${_no_logic_log} -REMOTE_FAKEDNS ${_remote_fakedns}" + _extra_param="${_extra_param} -FILTER_HTTPS ${_filter_https} -LOG_FILE ${_LOG_FILE}" + + lua $APP_PATH/helper_chinadns_add.lua ${_extra_param} > ${_CONF_FILE} + ln_run "$(first_type chinadns-ng)" chinadns-ng "${_LOG_FILE}" -C ${_CONF_FILE} +} + +run_socks() { + local flag node bind socks_port config_file http_port http_config_file relay_port log_file no_run + eval_set_val $@ + [ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file + [ -n "$http_port" ] || http_port=0 + [ -n "$http_config_file" ] && [ -z "$(echo ${http_config_file} | grep $TMP_PATH)" ] && http_config_file=$TMP_PATH/$http_config_file + if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then + log_file=$TMP_PATH/$log_file + else + log_file="/dev/null" + fi + + local node2socks_port=0 + local type remarks server_host server_port + if is_socks_wrap "$node"; then + node2socks_port=$(config_n_get ${node#Socks_} port 0) + fi + if [ "$node2socks_port" = "0" ]; then + type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + remarks=$(config_n_get $node remarks) + server_host=$(config_n_get $node address) + server_port=$(config_n_get $node port) + else + type="socks" + server_host="127.0.0.1" + server_port=$node2socks_port + remarks="Socks é…ç½®($server_port 端å£)" + fi + + [ -n "$relay_port" ] && { + server_host="127.0.0.1" + server_port=$relay_port + } + local error_msg tmp + + if [ -n "$server_host" ] && [ -n "$server_port" ]; then + check_host $server_host + [ $? != 0 ] && { + echolog " - Socks节点:[$remarks]${server_host} æ˜¯éžæ³•çš„æœåŠ¡å™¨åœ°å€ï¼Œæ— æ³•å¯åЍï¼" + return 1 + } + tmp="${server_host}:${server_port}" + else + error_msg="æŸç§åŽŸå› ï¼Œæ­¤ Socks æœåŠ¡çš„ç›¸å…³é…置已失è”,å¯åŠ¨ä¸­æ­¢ï¼" + fi + + if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then + local protocol=$(config_n_get $node protocol) + if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ] || [ "$protocol" == "_urltest" ]; then + unset error_msg + fi + fi + + if [ -n "${error_msg}" ] && ([ -n "$(config_n_get $node hysteria_hop)" ] || [ -n "$(config_n_get $node hysteria2_hop)" ] || [ "$(config_n_get $node hysteria2_realms)" = "1" ]); then + unset error_msg + fi + + [ -n "${error_msg}" ] && { + [ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},å¯åŠ¨ä¸­æ­¢ ${bind}:${socks_port} ${error_msg}" + return 1 + } + [ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},å¯åЍ ${bind}:${socks_port}" + + json_init + json_add_string "node" "${node}" + json_add_string "server_host" "${server_host}" + json_add_string "server_port" "${server_port}" + case "$type" in + socks) + local _socks_address _socks_port _socks_username _socks_password + if [ "$node2socks_port" = "0" ]; then + _socks_address=$(config_n_get $node address) + _socks_port=$(config_n_get $node port) + _socks_username=$(config_n_get $node username) + _socks_password=$(config_n_get $node password) + else + _socks_address="127.0.0.1" + _socks_port=$node2socks_port + fi + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "$bind" + json_add_string "local_http_port" "$http_port" + } + json_add_null "server_host" + json_add_null "server_port" + json_add_string "local_socks_address" "$bind" + json_add_string "local_socks_port" "$socks_port" + json_add_string "server_proto" "socks" + json_add_string "server_address" "${_socks_address}" + json_add_string "server_port" "${_socks_port}" + json_add_string "server_username" "${_socks_username}" + json_add_string "server_password" "${_socks_password}" + if [ -n "${SINGBOX_BIN}" ]; then + type="sing-box" + local bin="${SINGBOX_BIN}" + local util="${UTIL_SINGBOX}" + elif [ -n "${XRAY_BIN}" ]; then + type="xray" + local bin="${XRAY_BIN}" + local util="${UTIL_XRAY}" + fi + [ -n "${bin}" ] && [ -n "${util}" ] && { + lua ${util} gen_proto_config "$(json_dump)" > $config_file + [ -n "$no_run" ] || ln_run "$bin" $type $log_file run -c "$config_file" + } + unset bin util + ;; + sing-box) + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + local _args="http_address=$bind http_port=$http_port" + } + [ -n "$relay_port" ] && _args="${_args} server_host=$server_host server_port=$server_port" + [ -n "$no_run" ] && _args="${_args} no_run=1" + run_singbox flag=$flag node=$node socks_address=$bind socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args} + ;; + xray) + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + local _args="http_address=$bind http_port=$http_port" + } + [ -n "$relay_port" ] && _args="${_args} server_host=$server_host server_port=$server_port" + [ -n "$no_run" ] && _args="${_args} no_run=1" + run_xray flag=$flag node=$node socks_address=$bind socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args} + ;; + naiveproxy) + json_add_string "run_type" "socks" + json_add_string "local_addr" "$bind" + json_add_string "local_port" "$socks_port" + lua $UTIL_NAIVE gen_config "$(json_dump)" > $config_file + [ -n "$no_run" ] || ln_run "$(first_type naive)" naive $log_file "$config_file" + ;; + ssr) + json_add_string "local_addr" "$bind" + json_add_string "local_port" "$socks_port" + lua $UTIL_SS gen_config "$(json_dump)" > $config_file + [ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u + ;; + ss-rust) + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "$bind" + json_add_string "local_http_port" "$http_port" + } + [ -n "$no_run" ] || { + local plugin_sh="${config_file%.json}_plugin.sh" + json_add_string "plugin_sh" "$plugin_sh" + } + json_add_string "local_socks_address" "$bind" + json_add_string "local_socks_port" "$socks_port" + lua $UTIL_SS gen_config "$(json_dump)" > $config_file + [ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v + ;; + hysteria2) + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "$bind" + json_add_string "local_http_port" "$http_port" + } + json_add_string "local_socks_address" "$bind" + json_add_string "local_socks_port" "$socks_port" + lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file + [ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client + ;; + esac + + set_cache_var "node_${node}_socks_port" "${socks_port}" + + # http to socks + [ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && { + json_init + json_add_string "local_http_address" "$bind" + json_add_string "local_http_port" "$http_port" + json_add_string "server_proto" "socks" + json_add_string "server_address" "127.0.0.1" + json_add_string "server_port" "$socks_port" + json_add_string "server_username" "$_username" + json_add_string "server_password" "$_password" + if [ -n "${SINGBOX_BIN}" ]; then + type="sing-box" + local bin="${SINGBOX_BIN}" + local util="${UTIL_SINGBOX}" + elif [ -n "${XRAY_BIN}" ]; then + type="xray" + local bin="${XRAY_BIN}" + local util="${UTIL_XRAY}" + fi + [ -n "${bin}" ] && [ -n "${util}" ] && { + lua ${util} gen_proto_config "$(json_dump)" > $http_config_file + [ -n "$no_run" ] || ln_run "$bin" $type /dev/null run -c "$http_config_file" + } + unset bin util + } + unset http_flag + + [ -z "$no_run" ] && [ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list +} + +run_redir() { + local node proto bind local_port config_file log_file + eval_set_val $@ + local tcp_node_socks_flag tcp_node_http_flag + [ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=${GLOBAL_ACL_PATH}/${config_file} + if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then + log_file=${GLOBAL_ACL_PATH}/${log_file} + else + log_file="/dev/null" + fi + local proto=$(echo $proto | tr 'A-Z' 'a-z') + local PROTO=$(echo $proto | tr 'a-z' 'A-Z') + + local node2socks_port=0 + local type remarks server_host port + if is_socks_wrap "$node"; then + node2socks_port=$(config_n_get ${node#Socks_} port 0) + fi + if [ "$node2socks_port" = "0" ]; then + type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + remarks=$(config_n_get $node remarks) + server_host=$(config_n_get $node address) + port=$(config_n_get $node port) + else + if [ "${DNS_MODE}" = "xray" ]; then + type="xray" + elif [ "${DNS_MODE}" = "sing-box" ]; then + type="sing-box" + else + type="socks" + fi + server_host="127.0.0.1" + port=$node2socks_port + remarks="Socks é…ç½®($port 端å£)" + fi + + local enable_log=$(config_t_get global log_${proto} 1) + [ "$enable_log" != "1" ] && log_file="/dev/null" + [ -n "$server_host" ] && [ -n "$port" ] && { + check_host $server_host + [ $? != 0 ] && { + echolog "${PROTO}节点:[$remarks]${server_host} æ˜¯éžæ³•çš„æœåŠ¡å™¨åœ°å€ï¼Œæ— æ³•å¯åЍï¼" + return 1 + } + } + [ "$bind" != "127.0.0.1" ] && echolog "${PROTO}节点:[$remarks],监å¬ç«¯å£ï¼š$local_port" + + json_init + json_add_string "node" "${node}" + case "$PROTO" in + UDP) + case "$type" in + socks) + local _socks_address _socks_port _socks_username _socks_password + if [ "$node2socks_port" = "0" ]; then + _socks_address=$(config_n_get $node address) + _socks_port=$(config_n_get $node port) + _socks_username=$(config_n_get $node username) + _socks_password=$(config_n_get $node password) + else + _socks_address="127.0.0.1" + _socks_port=$node2socks_port + fi + run_ipt2socks flag=default proto=UDP local_port=${local_port} socks_address=${_socks_address} socks_port=${_socks_port} socks_username=${_socks_username} socks_password=${_socks_password} log_file=${log_file} + ;; + sing-box) + local protocol=$(config_n_get $node protocol) + [ "$protocol" = "_shunt" ] && { + local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat" + local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat" + if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then + echolog "* 缺少Geo规则文件,UDP Sing-Box分æµèŠ‚ç‚¹æ— æ³•æ­£å¸¸ä½¿ç”¨ï¼" + fi + } + run_singbox flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file + ;; + xray) + local protocol=$(config_n_get $node protocol) + [ "$protocol" = "_shunt" ] && { + local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat" + local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat" + if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then + echolog "* 缺少Geo规则文件,UDP Xray分æµèŠ‚ç‚¹æ— æ³•æ­£å¸¸ä½¿ç”¨ï¼" + fi + } + run_xray flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file + ;; + naiveproxy) + echolog "Naiveproxy䏿”¯æŒUDP转å‘ï¼" + ;; + ssr) + json_add_string "local_addr" "0.0.0.0" + json_add_string "local_port" "$local_port" + lua $UTIL_SS gen_config "$(json_dump)" > $config_file + ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v -U + ;; + ss-rust) + local plugin_sh="${config_file%.json}_plugin.sh" + json_add_string "plugin_sh" "$plugin_sh" + json_add_string "local_udp_redir_port" "$local_port" + lua $UTIL_SS gen_config "$(json_dump)" > $config_file + ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v + ;; + hysteria2) + json_add_string "local_udp_redir_port" "$local_port" + lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file + ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client + ;; + esac + ;; + TCP) + [ "$TCP_UDP" = "1" ] && echolog "UDP节点:与TCP节点相åŒ" + tcp_node_socks=1 + tcp_node_socks_bind_local=$(config_t_get global tcp_node_socks_bind_local 1) + tcp_node_socks_bind="127.0.0.1" + [ "${tcp_node_socks_bind_local}" != "1" ] && tcp_node_socks_bind="0.0.0.0" + tcp_node_socks_port=$(get_new_port $(config_t_get global tcp_node_socks_port 1070)) + tcp_node_http_port=$(config_t_get global tcp_node_http_port 0) + [ "$tcp_node_http_port" != "0" ] && tcp_node_http=1 + if [ $PROXY_IPV6 == "1" ]; then + echolog "å¼€å¯å®žéªŒæ€§IPv6逿˜Žä»£ç†(TProxy),请确认您的节点åŠç±»åž‹æ”¯æŒIPv6ï¼" + fi + + if [ "${TCP_PROXY_WAY}" = "redirect" ]; then + can_ipt=$(echo "$REDIRECT_LIST" | grep "$type") + elif [ "${TCP_PROXY_WAY}" = "tproxy" ]; then + can_ipt=$(echo "$TPROXY_LIST" | grep "$type") + fi + [ -z "$can_ipt" ] && type="socks" + + case "$type" in + socks) + _socks_flag=1 + if [ "$node2socks_port" = "0" ]; then + _socks_address=$(config_n_get $node address) + _socks_port=$(config_n_get $node port) + _socks_username=$(config_n_get $node username) + _socks_password=$(config_n_get $node password) + else + _socks_address="127.0.0.1" + _socks_port=$node2socks_port + fi + [ -z "$can_ipt" ] && { + local _config_file=$config_file + _config_file="TCP_SOCKS_${node}.json" + local _port=$(get_new_port 3001) + run_socks flag="TCP" node=$node bind=127.0.0.1 socks_port=${_port} config_file=${_config_file} + _socks_address=127.0.0.1 + _socks_port=${_port} + unset _socks_username + unset _socks_password + } + ;; + sing-box) + local _flag="TCP" + local _args="" + [ "$tcp_node_socks" = "1" ] && { + tcp_node_socks_flag=1 + _args="${_args} socks_address=${tcp_node_socks_bind} socks_port=${tcp_node_socks_port}" + config_file="${config_file//TCP/TCP_SOCKS}" + } + [ "$tcp_node_http" = "1" ] && { + tcp_node_http_flag=1 + _args="${_args} http_port=${tcp_node_http_port}" + config_file="${config_file//TCP/TCP_HTTP}" + } + [ "$TCP_UDP" = "1" ] && { + UDP_REDIR_PORT=$local_port + unset UDP_NODE + _flag="TCP_UDP" + _args="${_args} udp_redir_port=${UDP_REDIR_PORT}" + config_file="${config_file//TCP/TCP_UDP}" + } + + local protocol=$(config_n_get $node protocol) + local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) + [ "${DNS_MODE}" != "sing-box" ] && [ "$protocol" = "_shunt" ] && { + DNS_MODE="sing-box" + [ "$v2ray_dns_mode" = "tcp+doh" ] && v2ray_dns_mode="tcp" + } + + [ "$protocol" = "_shunt" ] && { + local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat" + local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat" + if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then + echolog "* 缺少Geo规则文件,TCP Sing-Box分æµèŠ‚ç‚¹æ— æ³•æ­£å¸¸ä½¿ç”¨ï¼" + fi + [ "$(config_n_get $node fakedns)" = "1" ] && { + USE_FAKEDNS=1 + GLOBAL_SHUNT_NODE_FAKEDNS=1 + } + } + + [ "${DNS_MODE}" = "sing-box" ] && { + NO_PLUGIN_DNS=1 + config_file="${config_file//.json/_DNS.json}" + _args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}" + DNSMASQ_FILTER_PROXY_IPV6=0 + local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip) + [ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}" + [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" + resolve_dns_port=${NEXT_DNS_LISTEN_PORT} + _args="${_args} dns_listen_port=${resolve_dns_port}" + + case "$(config_t_get global direct_dns_mode "auto")" in + udp) + _args="${_args} direct_dns_udp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + ;; + tcp) + _args="${_args} direct_dns_tcp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + ;; + esac + + _args="${_args} remote_dns_protocol=${v2ray_dns_mode}" + case "$v2ray_dns_mode" in + udp|tcp) + local _proto="$v2ray_dns_mode" + _args="${_args} remote_dns_${_proto}_server=${REMOTE_DNS}" + resolve_dns_log="Sing-Box DNS(127.0.0.1#${resolve_dns_port}) -> ${_proto}://${REMOTE_DNS}" + ;; + doh|http3) + local remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") + _args="${_args} remote_dns_doh=${remote_dns_doh}" + resolve_dns_log="Sing-Box DNS(127.0.0.1#${resolve_dns_port}) -> ${remote_dns_doh}" + ;; + esac + local remote_fakedns=$(config_t_get global remote_fakedns 0) + [ "${remote_fakedns}" = "1" ] && { + REMOTE_FAKEDNS=1 + _args="${_args} remote_fakedns=1" + resolve_dns_log="${resolve_dns_log} + FakeDNS" + USE_FAKEDNS=1 + } + NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1) + } + run_singbox flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args} + ;; + xray) + local _flag="TCP" + local _args="" + [ "$tcp_node_socks" = "1" ] && { + tcp_node_socks_flag=1 + _args="${_args} socks_address=${tcp_node_socks_bind} socks_port=${tcp_node_socks_port}" + config_file="${config_file//TCP/TCP_SOCKS}" + } + [ "$tcp_node_http" = "1" ] && { + tcp_node_http_flag=1 + _args="${_args} http_port=${tcp_node_http_port}" + config_file="${config_file//TCP/TCP_HTTP}" + } + [ "$TCP_UDP" = "1" ] && { + UDP_REDIR_PORT=$local_port + unset UDP_NODE + _flag="TCP_UDP" + _args="${_args} udp_redir_port=${UDP_REDIR_PORT}" + config_file="${config_file//TCP/TCP_UDP}" + } + + local protocol=$(config_n_get $node protocol) + local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) + [ "${DNS_MODE}" != "xray" ] && [ "$protocol" = "_shunt" ] && { + DNS_MODE="xray" + [ "$v2ray_dns_mode" = "http3" ] && v2ray_dns_mode="tcp" + } + #兼容旧模å¼ï¼Œæ‹©æœºç§»é™¤ + [ "$v2ray_dns_mode" = "tcp+doh" ] && v2ray_dns_mode="tcp" + + [ "$protocol" = "_shunt" ] && { + local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat" + local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat" + if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then + echolog "* 缺少Geo规则文件,TCP Xray分æµèŠ‚ç‚¹æ— æ³•æ­£å¸¸ä½¿ç”¨ï¼" + fi + [ "$(config_n_get $node fakedns)" = "1" ] && { + USE_FAKEDNS=1 + GLOBAL_SHUNT_NODE_FAKEDNS=1 + } + } + + [ "${DNS_MODE}" = "xray" ] && { + NO_PLUGIN_DNS=1 + config_file="${config_file//.json/_DNS.json}" + _args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}" + DNSMASQ_FILTER_PROXY_IPV6=0 + local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip) + [ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}" + [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" + resolve_dns_port=${NEXT_DNS_LISTEN_PORT} + _args="${_args} dns_listen_port=${resolve_dns_port}" + + case "$(config_t_get global direct_dns_mode "auto")" in + udp) + _args="${_args} direct_dns_udp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + ;; + tcp) + _args="${_args} direct_dns_tcp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + ;; + esac + + _args="${_args} remote_dns_protocol=${v2ray_dns_mode}" + case "$v2ray_dns_mode" in + udp|tcp) + local _proto="$v2ray_dns_mode" + _args="${_args} remote_dns_${_proto}_server=${REMOTE_DNS}" + resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> ${_proto}://${REMOTE_DNS}" + ;; + doh) + local remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") + _args="${_args} remote_dns_doh=${remote_dns_doh}" + resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> ${remote_dns_doh}" + ;; + esac + local remote_fakedns=$(config_t_get global remote_fakedns 0) + [ "${remote_fakedns}" = "1" ] && { + REMOTE_FAKEDNS=1 + _args="${_args} remote_fakedns=1" + resolve_dns_log="${resolve_dns_log} + FakeDNS" + USE_FAKEDNS=1 + } + NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1) + } + run_xray flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args} + ;; + naiveproxy) + json_add_string "run_type" "redir" + json_add_string "local_addr" "0.0.0.0" + json_add_string "local_port" "$local_port" + lua $UTIL_NAIVE gen_config "$(json_dump)" > $config_file + ln_run "$(first_type naive)" naive $log_file "$config_file" + ;; + ssr) + [ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true" + local _extra_param + [ "$TCP_UDP" = "1" ] && { + config_file="${config_file//TCP/TCP_UDP}" + UDP_REDIR_PORT=$TCP_REDIR_PORT + unset UDP_NODE + _extra_param="-u" + } + json_add_string "local_addr" "0.0.0.0" + json_add_string "local_port" "$local_port" + lua $UTIL_SS gen_config "$(json_dump)" > $config_file + ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v ${_extra_param} + ;; + ss-rust) + json_add_string "local_tcp_redir_port" "$local_port" + [ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true" + [ "$tcp_node_socks" = "1" ] && { + tcp_node_socks_flag=1 + config_file="${config_file//TCP/TCP_SOCKS}" + json_add_string "local_socks_address" "${tcp_node_socks_bind}" + json_add_string "local_socks_port" "${tcp_node_socks_port}" + } + [ "$tcp_node_http" = "1" ] && { + tcp_node_http_flag=1 + config_file="${config_file//TCP/TCP_HTTP}" + json_add_string "local_http_port" "${tcp_node_http_port}" + } + [ "$TCP_UDP" = "1" ] && { + config_file="${config_file//TCP/TCP_UDP}" + UDP_REDIR_PORT=$TCP_REDIR_PORT + unset UDP_NODE + json_add_string "local_udp_redir_port" "$local_port" + } + local plugin_sh="${config_file%.json}_plugin.sh" + json_add_string "plugin_sh" "$plugin_sh" + lua $UTIL_SS gen_config "$(json_dump)" > $config_file + ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v + ;; + hysteria2) + json_add_string "local_tcp_redir_port" "$local_port" + [ "$tcp_node_socks" = "1" ] && { + tcp_node_socks_flag=1 + config_file="${config_file//TCP/TCP_SOCKS}" + json_add_string "local_socks_address" "${tcp_node_socks_bind}" + json_add_string "local_socks_port" "${tcp_node_socks_port}" + } + [ "$tcp_node_http" = "1" ] && { + tcp_node_http_flag=1 + config_file="${config_file//TCP/TCP_HTTP}" + json_add_string "local_http_port" "${tcp_node_http_port}" + } + [ "$TCP_UDP" = "1" ] && { + config_file="${config_file//TCP/TCP_UDP}" + UDP_REDIR_PORT=$TCP_REDIR_PORT + unset UDP_NODE + json_add_string "local_udp_redir_port" "$local_port" + } + json_add_string "tcp_proxy_way" "${TCP_PROXY_WAY}" + lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file + ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client + ;; + esac + if [ -n "${_socks_flag}" ]; then + local _flag="TCP" + [ "$TCP_UDP" = "1" ] && { + _flag="TCP_UDP" + UDP_REDIR_PORT=$TCP_REDIR_PORT + unset UDP_NODE + } + local _socks_tproxy="" + [ "${TCP_PROXY_WAY}" = "tproxy" ] && _socks_tproxy="1" + run_ipt2socks flag=default proto=${_flag} tcp_tproxy=${_socks_tproxy} local_port=${local_port} socks_address=${_socks_address} socks_port=${_socks_port} socks_username=${_socks_username} socks_password=${_socks_password} log_file=${log_file} + fi + + [ -z "$tcp_node_socks_flag" ] && { + [ "$tcp_node_socks" = "1" ] && { + local config_file="SOCKS_TCP.json" + local log_file="SOCKS_TCP.log" + local http_port=0 + local http_config_file="HTTP2SOCKS_TCP.json" + [ "$tcp_node_http" = "1" ] && [ -z "$tcp_node_http_flag" ] && { + http_port=$tcp_node_http_port + } + run_socks flag=TCP node=$node bind=$tcp_node_socks_bind socks_port=$tcp_node_socks_port config_file=$config_file http_port=$http_port http_config_file=$http_config_file + } + } + + [ "$tcp_node_socks" = "1" ] && { + TCP_SOCKS_server="127.0.0.1:$tcp_node_socks_port" + set_cache_var "GLOBAL_TCP_SOCKS_server" "${TCP_SOCKS_server}" + } + ;; + esac + unset tcp_node_socks_flag tcp_node_http_flag + [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list + [ -n "${redir_port}" ] && set_cache_var "node_${node}_${PROTO}_redir_port" "${local_port}" +} + +start_redir() { + local proto=${1} + eval node=\$${proto}_NODE + if [ -n "$node" ]; then + TYPE=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + local config_file="${proto}.json" + local log_file="${proto}.log" + eval current_port=\$${proto}_REDIR_PORT + local port=$(echo $(get_new_port $current_port $proto)) + eval ${proto}_REDIR_PORT=$port + run_redir node=$node proto=${proto} bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file + set_cache_var "ACL_GLOBAL_${proto}_node" "${node}" + set_cache_var "ACL_GLOBAL_${proto}_redir_port" "${port}" + [ "$TCP_UDP" = "1" ] && { + set_cache_var "ACL_GLOBAL_UDP_node" "${node}" + set_cache_var "ACL_GLOBAL_UDP_redir_port" "${port}" + } + else + [ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return + echolog "${proto}节点没有选择或为空,ä¸ä»£ç†${proto}。" + fi +} + +start_socks() { + [ "$SOCKS_ENABLED" = "1" ] && { + local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') + [ -n "$ids" ] && { + echolog "åˆ†æž Socks æœåŠ¡çš„èŠ‚ç‚¹é…ç½®..." + for id in $ids; do + local enabled=$(config_n_get $id enabled 0) + [ "$enabled" == "0" ] && continue + local node=$(config_n_get $id node) + [ -z "$node" ] && continue + local bind_local=$(config_n_get $id bind_local 0) + local bind="0.0.0.0" + [ "$bind_local" = "1" ] && bind="127.0.0.1" + local port=$(config_n_get $id port) + local config_file="SOCKS_${id}.json" + local log_file="SOCKS_${id}.log" + local log=$(config_n_get $id log 1) + [ "$log" == "0" ] && log_file="" + local http_port=$(config_n_get $id http_port 0) + local http_config_file="HTTP2SOCKS_${id}.json" + local enable_autoswitch=$(config_n_get $id enable_autoswitch 0) + [ "$enable_autoswitch" = "1" ] && [ -z "$(config_n_get $id autoswitch_backup_node)" ] && enable_autoswitch=0 + local no_rec=0 + [ "$enable_autoswitch" = "1" ] && no_rec=1 + NO_REC_PROCESS=$no_rec $APP_PATH/app.sh run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file + set_cache_var "socks_${id}" "$node" + #自动切æ¢é€»è¾‘ + [ "$enable_autoswitch" = "1" ] && { $APP_PATH/socks_auto_switch.sh ${id} > /dev/null 2>&1 & } + done + } + } +} + +socks_node_switch() { + local flag new_node + eval_set_val $@ + [ -n "$flag" ] && [ -n "$new_node" ] && { + local prefix pf filename + # ç»“æŸ SS æ’件进程 + for prefix in "" "HTTP_"; do + pf="$TMP_PATH/${prefix}SOCKS_${flag}_plugin.pid" + [ -s "$pf" ] && kill -9 "$(head -n1 "$pf")" >/dev/null 2>&1 + done + + busybox pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1 + for prefix in "" "HTTP_" "HTTP2"; do + rm -rf "$TMP_PATH/${prefix}SOCKS_${flag}"* + done + + for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do + grep -q "${flag}" "${TMP_SCRIPT_FUNC_PATH}/${filename}" && \ + rm -f "${TMP_SCRIPT_FUNC_PATH}/${filename}" "${TMP_PATH}/script_rstats/${filename}.count" + done + local bind_local=$(config_n_get $flag bind_local 0) + local bind="0.0.0.0" + [ "$bind_local" = "1" ] && bind="127.0.0.1" + local port=$(config_n_get $flag port) + local config_file="SOCKS_${flag}.json" + local log_file="SOCKS_${flag}.log" + local log=$(config_n_get $flag log 1) + [ "$log" == "0" ] && log_file="" + local http_port=$(config_n_get $flag http_port 0) + local http_config_file="HTTP2SOCKS_${flag}.json" + LOG_FILE="/dev/null" + run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file + set_cache_var "socks_${flag}" "$new_node" + local ENABLED_DEFAULT_ACL=$(get_cache_var "ENABLED_DEFAULT_ACL") + local ENABLED_ACLS=$(get_cache_var "ENABLED_ACLS") + [ "$ENABLED_DEFAULT_ACL" != "1" -a "$ENABLED_ACLS" != "1" ] && return + local USE_TABLES=$(get_cache_var "USE_TABLES") + [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list + } +} + +clean_crontab() { + [ -f "${LOCK_PATH}/${CONFIG}_cron.lock" ] && return + touch /etc/crontabs/root + #sed -i "/${CONFIG}/d" /etc/crontabs/root >/dev/null 2>&1 + sed -i "/$(echo "/etc/init.d/${CONFIG}" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1 + sed -i "/$(echo "lua ${APP_PATH}/rule_update.lua log" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1 + sed -i "/$(echo "lua ${APP_PATH}/subscribe.lua start" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1 + + busybox pgrep -af "${CONFIG}/" | awk '/tasks\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -f ${LOCK_PATH}/${CONFIG}_tasks.lock +} + +start_crontab() { + local update_loop + + if [ "$ENABLED_DEFAULT_ACL" = "1" ] || [ "$ENABLED_ACLS" = "1" ]; then + local start_daemon=$(config_t_get global_delay start_daemon 0) + [ "$start_daemon" = "1" ] && { $APP_PATH/monitor.sh > /dev/null 2>&1 & } + fi + + if [ -f "${LOCK_PATH}/${CONFIG}_cron.lock" ]; then + rm -f "${LOCK_PATH}/${CONFIG}_cron.lock" + echolog "当å‰ä¸ºè®¡åˆ’任务自动è¿è¡Œï¼Œä¸é‡æ–°é…置定时任务。" + return + fi + + clean_crontab + + if [ "$ENABLED" != "1" ]; then + /etc/init.d/cron restart + return + fi + + build_time() { + local w="$1" + local h="$2" + local expr="0 $h * * $w" + [ "$w" = "7" ] && expr="0 $h * * *" + echo "$expr" + } + + add_service_cron() { + local week="$1" + local hour="$2" + local action="$3" + local logmsg="$4" + [ -z "$week" ] && return + local svr_t=$(build_time "$week" "$hour") + if [ "$week" = "8" ]; then + update_loop=1 + else + echo "$svr_t /etc/init.d/$CONFIG $action > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + echolog "$logmsg" + } + + # ===== stop/start/restart ===== + add_service_cron "$(config_t_get global_delay stop_week_mode)" "$(config_t_get global_delay stop_time_mode)" "stop" "é…置定时任务:自动关闭æœåŠ¡ã€‚" + + add_service_cron "$(config_t_get global_delay start_week_mode)" "$(config_t_get global_delay start_time_mode)" "start" "é…ç½®å®šæ—¶ä»»åŠ¡ï¼šè‡ªåŠ¨å¼€å¯æœåŠ¡ã€‚" + + add_service_cron "$(config_t_get global_delay restart_week_mode)" "$(config_t_get global_delay restart_time_mode)" "restart" "é…置定时任务:自动é‡å¯æœåŠ¡ã€‚" + + # ===== rule update ===== + local autoupdate=$(config_t_get global_rules auto_update) + local weekupdate=$(config_t_get global_rules week_update) + local dayupdate=$(config_t_get global_rules time_update) + if [ "$autoupdate" = "1" ]; then + local rule_t=$(build_time "$weekupdate" "$dayupdate") + if [ "$weekupdate" = "8" ]; then + update_loop=1 + else + echo "$rule_t lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + echolog "é…置定时任务:自动更新规则。" + fi + + # ===== subscribe ===== + local TMP_SUB_PATH=$TMP_PATH/sub_crontabs + mkdir -p "$TMP_SUB_PATH" + local item cfgid remark week_update time_update + for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get "$item" auto_update 0)" = "1" ]; then + cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1) + remark=$(config_n_get "$item" remark) + week_update=$(config_n_get "$item" week_update) + time_update=$(config_n_get "$item" time_update) + echo "$cfgid" >> "$TMP_SUB_PATH/${week_update}_${time_update}" + echolog "é…置定时任务:自动更新ã€$remark】订阅。" + fi + done + if [ -d "$TMP_SUB_PATH" ]; then + local name cfgids + for name in $(ls "$TMP_SUB_PATH"); do + week_update=${name%_*} + time_update=${name#*_} + cfgids=$(tr '\n' ',' < "$TMP_SUB_PATH/$name" | sed 's/,$//') + local sub_t=$(build_time "$week_update" "$time_update") + if [ "$week_update" = "8" ]; then + update_loop=1 + else + echo "$sub_t lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + done + rm -rf "$TMP_SUB_PATH" + fi + + # ===== loop ===== + if [ "$ENABLED_DEFAULT_ACL" = "1" ] || [ "$ENABLED_ACLS" = "1" ]; then + if [ "$update_loop" = "1" ]; then + $APP_PATH/tasks.sh > /dev/null 2>&1 & + echolog "自动更新:å¯åŠ¨å¾ªçŽ¯æ›´æ–°è¿›ç¨‹ã€‚" + fi + else + echolog "è¿è¡ŒäºŽéžä»£ç†æ¨¡å¼ï¼Œä»…å…许æœåŠ¡å¯åœçš„定时任务。" + fi + + /etc/init.d/cron restart +} + +stop_crontab() { + [ -f "${LOCK_PATH}/${CONFIG}_cron.lock" ] && return + clean_crontab + /etc/init.d/cron restart + #echolog "清除定时执行命令。" +} + +start_dns() { + echolog "DNS域åè§£æžï¼š" + + local china_ng_local_dns=$(IFS=','; set -- $LOCAL_DNS; [ "${1%%[#:]*}" = "127.0.0.1" ] && echo "$1" || ([ -n "$2" ] && echo "$*" || echo "$1")) + local sing_box_local_dns= + local direct_dns_mode=$(config_t_get global direct_dns_mode "auto") + + #获å–访问控制节点所使用的DNSåˆ†æµæ¨¡å¼ + local ACL_RULE_DNSMASQ=0 + for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get $acl_section enabled)" = "1" ] && \ + [ "$(config_n_get $acl_section dns_shunt)" = "dnsmasq" ]; then + ACL_RULE_DNSMASQ=1 + break + fi + done + + case "$direct_dns_mode" in + udp) + LOCAL_DNS=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/') + china_ng_local_dns=${LOCAL_DNS} + sing_box_local_dns="direct_dns_udp_server=${LOCAL_DNS}" + ;; + tcp) + local DIRECT_DNS=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/') + china_ng_local_dns="tcp://${DIRECT_DNS}" + sing_box_local_dns="direct_dns_tcp_server=${DIRECT_DNS}" + + #当全局(包括访问控制节点)开å¯chinadns-ng时,ä¸å¯åŠ¨æ–°è¿›ç¨‹ã€‚ + [ "$DNS_SHUNT" != "chinadns-ng" ] || [ "$ACL_RULE_DNSMASQ" = "1" ] && { + LOCAL_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}" + local china_ng_c_dns="tcp://$(get_first_dns DIRECT_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b :: -l ${NEXT_DNS_LISTEN_PORT} -c ${china_ng_c_dns} -d chn + echolog " - ChinaDNS-NG(${LOCAL_DNS}) -> ${china_ng_c_dns}" + echolog " * 请确ä¿ä¸Šæ¸¸ç›´è¿ž DNS æ”¯æŒ TCP 查询。" + NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1) + } + ;; + auto) + #Automatic logic is already done by default + : + ;; + esac + + # 追加直连DNS到iptables/nftables + [ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && IPT_APPEND_DNS= + add_default_port() { + [ -z "$1" ] && echo "" || echo "$1" | awk -F',' '{for(i=1;i<=NF;i++){if($i !~ /#/) $i=$i"#53";} print $0;}' OFS=',' + } + LOCAL_DNS=$(add_default_port "$LOCAL_DNS") + IPT_APPEND_DNS=$(add_default_port "${IPT_APPEND_DNS:-$LOCAL_DNS}") + echo "$IPT_APPEND_DNS" | grep -q -E "(^|,)$LOCAL_DNS(,|$)" || IPT_APPEND_DNS="${IPT_APPEND_DNS:+$IPT_APPEND_DNS,}$LOCAL_DNS" + [ -n "$DIRECT_DNS" ] && { + DIRECT_DNS=$(add_default_port "$DIRECT_DNS") + echo "$IPT_APPEND_DNS" | grep -q -E "(^|,)$DIRECT_DNS(,|$)" || IPT_APPEND_DNS="${IPT_APPEND_DNS:+$IPT_APPEND_DNS,}$DIRECT_DNS" + } + # 排除127.0.0.1çš„æ¡ç›® + IPT_APPEND_DNS=$(echo "$IPT_APPEND_DNS" | awk -F',' '{for(i=1;i<=NF;i++) if($i !~ /^127\.0\.0\.1/) printf (i>1?",":"") $i; print ""}' | sed 's/^,\|,$//g') + + TUN_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}" + [ -n "${NO_PLUGIN_DNS}" ] && TUN_DNS="127.0.0.1#${resolve_dns_port}" + + case "$DNS_MODE" in + dns2socks) + local dns2socks_socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:1080) | sed "s/#/:/g") + local dns2socks_forward=$(get_first_dns REMOTE_DNS 53 | sed 's/#/:/g') + run_dns2socks socks=$dns2socks_socks_server listen_address=127.0.0.1 listen_port=${NEXT_DNS_LISTEN_PORT} dns=$dns2socks_forward cache=$DNS_CACHE + echolog " - dns2socks(${TUN_DNS}),${dns2socks_socks_server} -> tcp://${dns2socks_forward}" + ;; + sing-box) + [ -z "${NO_PLUGIN_DNS}" ] && { + local config_file=$TMP_PATH/DNS.json + local log_file=$TMP_PATH/DNS.log + local log_file=/dev/null + local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file" + [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" + _args="${_args} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY}" + _args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}" + DNSMASQ_FILTER_PROXY_IPV6=0 + local remote_fakedns=$(config_t_get global remote_fakedns 0) + [ "${remote_fakedns}" = "1" ] && { + REMOTE_FAKEDNS=1 + _args="${_args} remote_fakedns=1" + USE_FAKEDNS=1 + } + local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip) + [ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}" + TCP_PROXY_DNS=1 + local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) + _args="${_args} dns_listen_port=${NEXT_DNS_LISTEN_PORT}" + _args="${_args} remote_dns_protocol=${v2ray_dns_mode}" + case "$v2ray_dns_mode" in + udp|tcp) + local _proto="$v2ray_dns_mode" + _args="${_args} remote_dns_${_proto}_server=${REMOTE_DNS}" + echolog " - Sing-Box DNS(${TUN_DNS}) -> ${_proto}://${REMOTE_DNS}" + ;; + doh|http3) + local remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") + _args="${_args} remote_dns_doh=${remote_dns_doh}" + echolog " - Sing-Box DNS(${TUN_DNS}) -> ${remote_dns_doh}" + ;; + esac + _args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}" + [ -n "${sing_box_local_dns}" ] && _args="${_args} ${sing_box_local_dns}" + run_singbox ${_args} + } + ;; + xray) + [ -z "${NO_PLUGIN_DNS}" ] && { + local config_file=$TMP_PATH/DNS.json + local log_file=$TMP_PATH/DNS.log + local log_file=/dev/null + local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file" + [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" + _args="${_args} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY}" + _args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}" + DNSMASQ_FILTER_PROXY_IPV6=0 + local remote_fakedns=$(config_t_get global remote_fakedns 0) + [ "${remote_fakedns}" = "1" ] && { + REMOTE_FAKEDNS=1 + _args="${_args} remote_fakedns=1" + USE_FAKEDNS=1 + } + local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip) + [ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}" + TCP_PROXY_DNS=1 + local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) + #兼容旧模å¼ï¼Œæ‹©æœºç§»é™¤ + [ "$v2ray_dns_mode" = "tcp+doh" ] && v2ray_dns_mode="tcp" + _args="${_args} dns_listen_port=${NEXT_DNS_LISTEN_PORT}" + _args="${_args} remote_dns_protocol=${v2ray_dns_mode}" + case "$v2ray_dns_mode" in + udp|tcp) + local _proto="$v2ray_dns_mode" + _args="${_args} remote_dns_${_proto}_server=${REMOTE_DNS}" + echolog " - Xray DNS(${TUN_DNS}) -> ${_proto}://${REMOTE_DNS}" + ;; + doh) + local remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") + _args="${_args} remote_dns_doh=${remote_dns_doh}" + echolog " - Xray DNS(${TUN_DNS}) -> ${remote_dns_doh}" + ;; + esac + _args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}" + run_xray ${_args} + } + ;; + udp) + UDP_PROXY_DNS=1 + local china_ng_listen_port=${NEXT_DNS_LISTEN_PORT} + local china_ng_trust_dns="udp://$(get_first_dns REMOTE_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + if [ "$DNS_SHUNT" != "chinadns-ng" ] && [ "$FILTER_PROXY_IPV6" = "1" ]; then + DNSMASQ_FILTER_PROXY_IPV6=0 + local no_ipv6_trust="-N" + ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b :: -l ${china_ng_listen_port} -t ${china_ng_trust_dns} -d gfw ${no_ipv6_trust} + echolog " - ChinaDNS-NG(${TUN_DNS}) -> ${china_ng_trust_dns}" + else + TUN_DNS="$(echo ${REMOTE_DNS} | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')" + echolog " - udp://${TUN_DNS}" + fi + ;; + tcp) + TCP_PROXY_DNS=1 + local china_ng_listen_port=${NEXT_DNS_LISTEN_PORT} + local china_ng_trust_dns="tcp://$(get_first_dns REMOTE_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + [ "$DNS_SHUNT" != "chinadns-ng" ] && { + [ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0 && local no_ipv6_trust="-N" + ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b :: -l ${china_ng_listen_port} -t ${china_ng_trust_dns} -d gfw ${no_ipv6_trust} + echolog " - ChinaDNS-NG(${TUN_DNS}) -> ${china_ng_trust_dns}" + } + ;; + esac + + [ -n "${resolve_dns_log}" ] && echolog " - ${resolve_dns_log}" + + [ -n "${TCP_PROXY_DNS}" ] && echolog " * 请确认上游 DNS æ”¯æŒ TCP/DoH 查询,如éžç›´è¿žåœ°å€ï¼Œç¡®ä¿ TCP ä»£ç†æ‰“å¼€ï¼Œå¹¶ä¸”å·²ç»æ­£ç¡®è½¬å‘ï¼" + [ -n "${UDP_PROXY_DNS}" ] && echolog " * 请确认上游 DNS æ”¯æŒ UDP 查询并已使用 UDP 节点,如上游 DNS éžç›´è¿žåœ°å€ï¼Œç¡®ä¿ UDP ä»£ç†æ‰“å¼€ï¼Œå¹¶ä¸”å·²ç»æ­£ç¡®è½¬å‘ï¼" + + local china_ng_listen=0 + [ "${DNS_SHUNT}" = "smartdns" ] && { + if command -v smartdns > /dev/null 2>&1; then + rm -rf $TMP_PATH2/dnsmasq_default* + local group_domestic=$(config_t_get global group_domestic) + local smartdns_remote_dns=$(config_t_get global smartdns_remote_dns) + if [ -n "${smartdns_remote_dns}" -a "${smartdns_remote_dns}" != "nil" ]; then + smartdns_remote_dns=$(echo ${smartdns_remote_dns} | tr -s ' ' '|') + else + smartdns_remote_dns="tcp://1.1.1.1" + fi + + echolog " - 域åè§£æžï¼šä½¿ç”¨SmartDNS,请确ä¿é…置正常。" + china_ng_listen="127.0.0.1#${SMARTDNS_LISTEN_PORT}" + echolog " - SmartDNS(127.0.0.1#${SMARTDNS_LOCAL_PORT}) -> 国内分组(${group_domestic:-null}),SmartDNS(${china_ng_listen}) -> Dnsmasq" + china_ng_listen="${china_ng_listen},::1#${SMARTDNS_LISTEN_PORT}" + + local subnet_ip=$(config_t_get global remote_dns_client_ip) + lua $APP_PATH/helper_smartdns_add.lua -FLAG "default" -SMARTDNS_CONF "/tmp/etc/smartdns/$CONFIG.conf" \ + -LISTEN_PORT ${SMARTDNS_LISTEN_PORT} -LOCAL_PORT ${SMARTDNS_LOCAL_PORT} \ + -LOCAL_GROUP ${group_domestic:-null} -REMOTE_GROUP "passwall_proxy" -REMOTE_PROXY_SERVER ${TCP_SOCKS_server} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" \ + -REMOTE_DNS ${smartdns_remote_dns} -DNS_MODE ${DNS_MODE:-socks} -TUN_DNS ${TUN_DNS} -REMOTE_FAKEDNS ${REMOTE_FAKEDNS:-0} \ + -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ + -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE "${TCP_PROXY_MODE}" -NO_PROXY_IPV6 ${FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ + -SUBNET ${subnet_ip:-0} -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} + source $APP_PATH/helper_smartdns.sh restart + + USE_DEFAULT_DNS="chinadns_ng" + else + DNS_SHUNT="dnsmasq" + echolog " * 未安装SmartDNS,默认使用Dnsmasq进行域åè§£æžï¼" + fi + } + + [ "${DNS_SHUNT}" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && { + chinadns_ng_min=2024.04.13 + chinadns_ng_now=$($(first_type chinadns-ng) -V | grep -i "ChinaDNS-NG " | awk '{print $2}') + if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then + echolog " * 注æ„ï¼šå½“å‰ ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,å¦åˆ™ DNS 有å¯èƒ½æ— æ³•正常工作ï¼" + fi + + [ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0 + [ -z "${china_ng_listen_port}" ] && local china_ng_listen_port=$(expr $NEXT_DNS_LISTEN_PORT + 1) + china_ng_listen="127.0.0.1#${china_ng_listen_port}" + [ -z "${china_ng_trust_dns}" ] && local china_ng_trust_dns=${TUN_DNS} + + echolog " - ChinaDNS-NG(${china_ng_listen}):直连DNS:${china_ng_local_dns},å¯ä¿¡DNS:${china_ng_trust_dns}" + + china_ng_listen="${china_ng_listen},::1#${china_ng_listen_port}" + + run_chinadns_ng \ + _flag="default" \ + _listen_port=${china_ng_listen_port} \ + _dns_local=${china_ng_local_dns} \ + _dns_trust=${china_ng_trust_dns} \ + _no_ipv6_trust=${FILTER_PROXY_IPV6} \ + _use_direct_list=${USE_DIRECT_LIST} \ + _use_proxy_list=${USE_PROXY_LIST} \ + _use_block_list=${USE_BLOCK_LIST} \ + _gfwlist=${USE_GFW_LIST} \ + _chnlist=${CHN_LIST} \ + _default_mode=${TCP_PROXY_MODE} \ + _default_tag=$(config_t_get global chinadns_ng_default_tag smart) \ + _no_logic_log=0 \ + _tcp_node=${TCP_NODE} \ + _remote_fakedns=${REMOTE_FAKEDNS:-0} \ + _filter_https=$(config_t_get global force_https_soa 0) + + USE_DEFAULT_DNS="chinadns_ng" + } + + [ "$USE_DEFAULT_DNS" = "remote" ] && { + dnsmasq_version=$(dnsmasq -v | grep -i "Dnsmasq version " | awk '{print $3}') + [ "$(expr $dnsmasq_version \>= 2.87)" == 0 ] && echolog "Dnsmasq版本低于2.87,有å¯èƒ½æ— æ³•正常使用ï¼ï¼ï¼" + } + + local DNSMASQ_TUN_DNS=$(get_first_dns TUN_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/') + local RUN_NEW_DNSMASQ=1 + RUN_NEW_DNSMASQ=${DNS_REDIRECT} + if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then + #The old logic will be removed in the future. + #Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices. + [ "1" = "0" ] && { + DIRECT_DNSMASQ_PORT=$(get_new_port 11400) + DIRECT_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/direct_dnsmasq.conf + DIRECT_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/direct_dnsmasq.d + mkdir -p ${DIRECT_DNSMASQ_CONF_PATH} + lua $APP_PATH/helper_dnsmasq.lua copy_instance -LISTEN_PORT ${DIRECT_DNSMASQ_PORT} -DNSMASQ_CONF ${DIRECT_DNSMASQ_CONF} -TMP_DNSMASQ_PATH ${DIRECT_DNSMASQ_CONF_PATH} + ln_run "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid + echo "${DIRECT_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/direct_dnsmasq_port + } + + #Rewrite the default DNS service configuration + #Modify the default dnsmasq service + lua $APP_PATH/helper_dnsmasq.lua stretch + lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \ + -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${DNSMASQ_TUN_DNS} \ + -REMOTE_FAKEDNS ${REMOTE_FAKEDNS:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \ + -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ + -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ + -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} + uci -q add_list dhcp.@dnsmasq[0].addnmount=${GLOBAL_DNSMASQ_CONF_PATH} + uci -q commit dhcp + lua $APP_PATH/helper_dnsmasq.lua logic_restart -LOG 1 + else + #Run a copy dnsmasq instance, DNS hijack for that need proxy devices. + GLOBAL_DNSMASQ_PORT=$(get_new_port 11400) + GLOBAL_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/dnsmasq.conf + GLOBAL_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/dnsmasq.d + lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \ + -LISTEN_PORT ${GLOBAL_DNSMASQ_PORT} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${DNSMASQ_TUN_DNS} \ + -REMOTE_FAKEDNS ${REMOTE_FAKEDNS:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \ + -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ + -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ + -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} + ln_run "$(first_type dnsmasq)" "dnsmasq_default" "/dev/null" -C ${GLOBAL_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/dnsmasq.pid + set_cache_var "ACL_default_dns_port" "${GLOBAL_DNSMASQ_PORT}" + DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT} + #dhcp.leases to hosts + $APP_PATH/lease2hosts.sh > /dev/null 2>&1 & + fi +} + +start_haproxy() { + [ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return + local haproxy_ver=$($(first_type haproxy) -v 2>/dev/null | awk 'NR==1 {print $3}' | cut -d'-' -f1) + if [ "$(check_ver "$haproxy_ver" "3.0.0")" = "1" ]; then + echolog "* 注æ„:haproxy($haproxy_ver) 程åºç‰ˆæœ¬ä½Žï¼ŒHAPROXY è´Ÿè½½å‡è¡¡å¯åŠ¨å¤±è´¥ï¼Œè¯·æ›´æ–°åˆ° 3.0 以上版本。" + return + fi + local haproxy_path=$TMP_PATH/haproxy + local haproxy_conf="config.cfg" + lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} -dns ${LOCAL_DNS} + ln_run "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}" +} + +acl_app() { + local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1) + [ -n "$items" ] && { + local item + local socks_port redir_port dns_port dnsmasq_port chinadns_port + local msg msg2 + socks_port=11100 + redir_port=11200 + dns_port=11300 + dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400} + chinadns_port=11500 + for item in $items; do + local sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}') + [ "$(config_n_get $sid enabled)" = "1" ] || continue + eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-) + + if [ -n "${sources}" ]; then + for s in $sources; do + local s2 + is_iprange=$(lua_api "iprange(\"${s}\")") + if [ "${is_iprange}" = "true" ]; then + s2="iprange:${s}" + elif [ -n "$(echo ${s} | grep '^ipset:')" ]; then + s2="ipset:${s}" + else + _ip_or_mac=$(lua_api "ip_or_mac(\"${s}\")") + if [ "${_ip_or_mac}" = "ip" ]; then + s2="ip:${s}" + elif [ "${_ip_or_mac}" = "mac" ]; then + s2="mac:${s}" + fi + fi + [ -n "${s2}" ] && source_list="${source_list}\n${s2}" + unset s2 + done + else + source_list="any" + fi + + local acl_path=${TMP_ACL_PATH}/$sid + mkdir -p ${acl_path} + [ -n "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list + + use_global_config=${use_global_config:-0} + [ "${use_global_config}" = "1" ] && { + tcp_node="default" + udp_node="default" + } + tcp_no_redir_ports=${tcp_no_redir_ports:-${TCP_NO_REDIR_PORTS}} + udp_no_redir_ports=${udp_no_redir_ports:-${UDP_NO_REDIR_PORTS}} + if has_1_65535 "$tcp_no_redir_ports" && has_1_65535 "$udp_no_redir_ports"; then + unset use_global_config + unset tcp_node + unset udp_node + else + use_direct_list=${use_direct_list:-1} + use_proxy_list=${use_proxy_list:-1} + use_block_list=${use_block_list:-1} + use_gfw_list=${use_gfw_list:-1} + chn_list=${chn_list:-direct} + tcp_proxy_mode=${tcp_proxy_mode:-proxy} + udp_proxy_mode=${udp_proxy_mode:-proxy} + filter_proxy_ipv6=${filter_proxy_ipv6:-0} + dnsmasq_filter_proxy_ipv6=${filter_proxy_ipv6} + dns_shunt=${dns_shunt:-dnsmasq} + dns_mode=${dns_mode:-dns2socks} + remote_dns=${remote_dns:-1.1.1.1} + use_default_dns=${use_default_dns:-direct} + fi + + [ -n "$tcp_node" ] && { + local GLOBAL_TCP_NODE=$(get_cache_var "ACL_GLOBAL_TCP_node") + [ -n "${GLOBAL_TCP_NODE}" ] && GLOBAL_TCP_redir_port=$(get_cache_var "ACL_GLOBAL_TCP_redir_port") + if [ "$tcp_node" = "default" ]; then + if [ -n "${GLOBAL_TCP_NODE}" ]; then + set_cache_var "ACL_${sid}_tcp_node" "${GLOBAL_TCP_NODE}" + set_cache_var "ACL_${sid}_tcp_redir_port" "${GLOBAL_TCP_redir_port}" + set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}" + set_cache_var "ACL_${sid}_tcp_default" "1" + [ "$GLOBAL_SHUNT_NODE_FAKEDNS" = "1" ] && use_fakedns=1 + else + echolog " - 全局节点未å¯ç”¨ï¼Œè·³è¿‡ã€${remarks}】" + fi + else + [ "$(config_get_type $tcp_node)" = "nodes" ] || [ "$(config_get_type ${tcp_node#Socks_})" = "socks" ] && { + if [ -n "${GLOBAL_TCP_NODE}" ] && [ "$tcp_node" = "${GLOBAL_TCP_NODE}" ]; then + set_cache_var "ACL_${sid}_tcp_node" "${GLOBAL_TCP_NODE}" + set_cache_var "ACL_${sid}_tcp_redir_port" "${GLOBAL_TCP_redir_port}" + set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}" + set_cache_var "ACL_${sid}_tcp_default" "1" + [ "$GLOBAL_SHUNT_NODE_FAKEDNS" = "1" ] && use_fakedns=1 + else + local type protocol + if [ "$(config_get_type ${tcp_node#Socks_})" = "socks" ]; then + if [ "${dns_mode}" = "xray" ]; then + type="xray" + elif [ "${dns_mode}" = "sing-box" ]; then + type="sing-box" + fi + else + type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z') + protocol=$(config_n_get $tcp_node protocol) + fi + #兼容旧模å¼ï¼Œæ‹©æœºç§»é™¤ + [ "$v2ray_dns_mode" = "tcp+doh" ] && v2ray_dns_mode="tcp" + ([ "$type" = "sing-box" ] || [ "$type" = "xray" ]) && [ "$protocol" = "_shunt" ] && [ "$type" != "$dns_mode" ] && { + dns_mode=$type + [ "$type" = "xray" ] && [ "$v2ray_dns_mode" = "http3" ] && v2ray_dns_mode="tcp" + } + dns_cache_key="${dns_mode}_${remote_dns}_${v2ray_dns_mode:-none}_${remote_dns_client_ip:-0}_${remote_fakedns:-0}" + ([ "$v2ray_dns_mode" = "doh" ] || [ "$v2ray_dns_mode" = "http3" ]) && { + dns_cache_key="${dns_mode}_${remote_dns_doh:-https://1.1.1.1/dns-query}_${v2ray_dns_mode:-doh}_${remote_dns_client_ip:-0}_${remote_fakedns:-0}" + } + + if [ "$remote_fakedns" = "1" ] || ([ "$protocol" = "_shunt" ] && [ "$(config_n_get $tcp_node fakedns)" = "1" ]); then + use_fakedns=1 + fi + + run_dns() { + local _dns_port + [ -n $1 ] && _dns_port=$1 + [ -z ${_dns_port} ] && { + dns_port=$(get_new_port $(expr $dns_port + 1)) + _dns_port=$dns_port + if [ "$dns_mode" = "dns2socks" ]; then + run_dns2socks flag=acl_${sid} socks_address=127.0.0.1 socks_port=$socks_port listen_address=0.0.0.0 listen_port=${_dns_port} dns=$remote_dns cache=1 + elif [ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ]; then + config_file=$TMP_ACL_PATH/${tcp_node}_SOCKS_${socks_port}_DNS.json + remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query} + local type=${dns_mode} + [ "${dns_mode}" = "sing-box" ] && type="singbox" + dnsmasq_filter_proxy_ipv6=0 + remote_dns_query_strategy="UseIP" + [ "$filter_proxy_ipv6" = "1" ] && remote_dns_query_strategy="UseIPv4" + run_${type} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_udp_server=${remote_dns} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns_doh}" remote_dns_query_strategy=${remote_dns_query_strategy} remote_dns_client_ip=${remote_dns_client_ip} config_file=$config_file + fi + set_cache_var "node_${tcp_node}_$(echo -n "${dns_cache_key}" | md5sum | cut -d " " -f1)" "${_dns_port}" + } + + [ "$dns_shunt" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && { + chinadns_ng_min=2024.04.13 + chinadns_ng_now=$($(first_type chinadns-ng) -V | grep -i "ChinaDNS-NG " | awk '{print $2}') + if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then + echolog " * 注æ„ï¼šå½“å‰ ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,å¦åˆ™ DNS 有å¯èƒ½æ— æ³•正常工作ï¼" + fi + + [ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0 + chinadns_port=$(expr $chinadns_port + 1) + _china_ng_listen="127.0.0.1#${chinadns_port},::1#${chinadns_port}" + + _chinadns_local_dns=$(IFS=','; set -- $LOCAL_DNS; [ "${1%%[#:]*}" = "127.0.0.1" ] && echo "$1" || ([ -n "$2" ] && echo "$1,$2" || echo "$1")) + _direct_dns_mode=$(config_t_get global direct_dns_mode "auto") + case "${_direct_dns_mode}" in + udp) + _chinadns_local_dns=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/') + ;; + tcp) + _chinadns_local_dns="tcp://$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')" + ;; + esac + + run_chinadns_ng \ + _flag="$sid" \ + _listen_port=${chinadns_port} \ + _dns_local=${_chinadns_local_dns} \ + _dns_trust=127.0.0.1#${_dns_port} \ + _no_ipv6_trust=${filter_proxy_ipv6} \ + _use_direct_list=${use_direct_list} \ + _use_proxy_list=${use_proxy_list} \ + _use_block_list=${use_block_list} \ + _gfwlist=${use_gfw_list} \ + _chnlist=${chn_list} \ + _default_mode=${tcp_proxy_mode} \ + _default_tag=${chinadns_ng_default_tag:-smart} \ + _no_logic_log=1 \ + _tcp_node=${tcp_node} \ + _remote_fakedns=${remote_fakedns:-0} \ + _filter_https=${force_https_soa:-0} + + use_default_dns="chinadns_ng" + } + + dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1)) + local dnsmasq_conf=${acl_path}/dnsmasq.conf + local dnsmasq_conf_path=${acl_path}/dnsmasq.d + lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} -DNSMASQ_CONF_FILE ${dnsmasq_conf} \ + -LISTEN_PORT ${dnsmasq_port} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS $LOCAL_DNS \ + -USE_DIRECT_LIST "${use_direct_list}" -USE_PROXY_LIST "${use_proxy_list}" -USE_BLOCK_LIST "${use_block_list}" -USE_GFW_LIST "${use_gfw_list}" -CHN_LIST "${chn_list}" \ + -TUN_DNS "127.0.0.1#${_dns_port}" -REMOTE_FAKEDNS ${remote_fakedns:-0} -USE_DEFAULT_DNS "${use_default_dns:-direct}" -CHINADNS_DNS ${_china_ng_listen:-0} \ + -TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${dnsmasq_filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \ + -NO_LOGIC_LOG 1 + ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid + set_cache_var "ACL_${sid}_dns_port" "${dnsmasq_port}" + set_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}_${dns_cache_key}" | md5sum | cut -d " " -f1)" "${dnsmasq_port}" + #dhcp.leases to hosts + $APP_PATH/lease2hosts.sh > /dev/null 2>&1 & + } + _redir_port=$(get_cache_var "node_${tcp_node}_redir_port") + _socks_port=$(get_cache_var "node_${tcp_node}_socks_port") + if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then + socks_port=${_socks_port} + tcp_port=${_redir_port} + _dnsmasq_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}_${dns_cache_key}" | md5sum | cut -d " " -f1)") + if [ -z "${_dnsmasq_port}" ]; then + _dns_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${dns_cache_key}" | md5sum | cut -d " " -f1)") + run_dns ${_dns_port} + else + [ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}" + fi + else + socks_port=$(get_new_port $(expr $socks_port + 1)) + set_cache_var "node_${tcp_node}_socks_port" "${socks_port}" + redir_port=$(get_new_port $(expr $redir_port + 1)) + set_cache_var "node_${tcp_node}_redir_port" "${redir_port}" + tcp_port=$redir_port + + if [ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]; then + config_file="acl/${tcp_node}_TCP_${redir_port}.json" + _extra_param="socks_address=127.0.0.1 socks_port=$socks_port" + [ "${type}" = "${dns_mode}" ] && { + dns_port=$(get_new_port $(expr $dns_port + 1)) + _dns_port=$dns_port + config_file="${config_file//TCP_/DNS_${_dns_port}_TCP_}" + dnsmasq_filter_proxy_ipv6=0 + remote_dns_query_strategy="UseIP" + [ "$filter_proxy_ipv6" = "1" ] && remote_dns_query_strategy="UseIPv4" + remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query} + _extra_param="${_extra_param} dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_udp_server=${remote_dns} remote_dns_tcp_server=${remote_dns}" + _extra_param="${_extra_param} remote_dns_doh=${remote_dns_doh} remote_dns_query_strategy=${remote_dns_query_strategy} remote_fakedns=${remote_fakedns:-0} remote_dns_client_ip=${remote_dns_client_ip}" + } + _extra_param="${_extra_param} tcp_proxy_way=$TCP_PROXY_WAY" + [ -n "$udp_node" ] && ([ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]) && { + config_file="${config_file//TCP_/TCP_UDP_}" + _extra_param="${_extra_param} udp_redir_port=$redir_port" + } + config_file="$TMP_PATH/$config_file" + [ "${type}" = "sing-box" ] && type="singbox" + run_${type} flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file + else + config_file="acl/${tcp_node}_SOCKS_${socks_port}.json" + run_socks flag=$tcp_node node=$tcp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file + local log_file=$TMP_ACL_PATH/ipt2socks_${tcp_node}_${redir_port}.log + log_file="/dev/null" + run_ipt2socks flag=acl_${tcp_node} tcp_tproxy=${is_tproxy} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file + fi + run_dns ${_dns_port} + fi + set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}" + set_cache_var "ACL_${sid}_tcp_redir_port" "${tcp_port}" + fi + } + fi + [ "${use_fakedns}" = "1" ] && set_cache_var "ACL_${sid}_fakedns" "1" + } + [ -n "$udp_node" ] && { + [ -n "$tcp_node" ] && { + local protocol=$(config_n_get $tcp_node protocol) + [ "$protocol" = "_shunt" ] && [ "$udp_node" != "default" ] && { + udp_node="tcp" + } + } + if [ "$udp_node" = "default" ]; then + local GLOBAL_UDP_NODE=$(get_cache_var "ACL_GLOBAL_UDP_node") + [ -n "${GLOBAL_UDP_NODE}" ] && GLOBAL_UDP_redir_port=$(get_cache_var "ACL_GLOBAL_UDP_redir_port") + if [ -n "${GLOBAL_UDP_NODE}" ]; then + set_cache_var "ACL_${sid}_udp_node" "${GLOBAL_UDP_NODE}" + set_cache_var "ACL_${sid}_udp_redir_port" "${GLOBAL_UDP_redir_port}" + set_cache_var "ACL_${sid}_udp_default" "1" + else + echolog " - 全局节点未å¯ç”¨ï¼Œè·³è¿‡ã€${remarks}】" + fi + elif [ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]; then + udp_node=$(get_cache_var "ACL_${sid}_tcp_node") + udp_port=$(get_cache_var "ACL_${sid}_tcp_redir_port") + set_cache_var "ACL_${sid}_udp_node" "${udp_node}" + set_cache_var "ACL_${sid}_udp_redir_port" "${udp_port}" + else + [ "$(config_get_type $udp_node)" = "nodes" ] || [ "$(config_get_type ${udp_node#Socks_})" = "socks" ] && { + if [ -n "${GLOBAL_UDP_NODE}" ] && [ "$udp_node" = "${GLOBAL_UDP_NODE}" ]; then + set_cache_var "ACL_${sid}_udp_node" "${GLOBAL_UDP_NODE}" + set_cache_var "ACL_${sid}_udp_redir_port" "${GLOBAL_UDP_redir_port}" + set_cache_var "ACL_${sid}_udp_default" "1" + else + _redir_port=$(get_cache_var "node_${udp_node}_redir_port") + _socks_port=$(get_cache_var "node_${udp_node}_socks_port") + if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then + socks_port=${_socks_port} + udp_port=${_redir_port} + else + socks_port=$(get_new_port $(expr $socks_port + 1)) + set_cache_var "node_${udp_node}_socks_port" "${socks_port}" + redir_port=$(get_new_port $(expr $redir_port + 1)) + set_cache_var "node_${udp_node}_redir_port" "${redir_port}" + udp_port=$redir_port + + local type + if [ "$(config_get_type ${udp_node#Socks_})" = "socks" ]; then + if [ "${dns_mode}" = "xray" ]; then + type="xray" + elif [ "${dns_mode}" = "sing-box" ]; then + type="sing-box" + fi + else + type=$(echo $(config_n_get $udp_node type) | tr 'A-Z' 'a-z') + fi + if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then + config_file="acl/${udp_node}_UDP_${redir_port}.json" + config_file="$TMP_PATH/$config_file" + [ "${type}" = "sing-box" ] && type="singbox" + run_${type} flag=$udp_node node=$udp_node udp_redir_port=$redir_port config_file=$config_file + else + config_file="acl/${udp_node}_SOCKS_${socks_port}.json" + run_socks flag=$udp_node node=$udp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file + local log_file=$TMP_ACL_PATH/ipt2socks_${udp_node}_${redir_port}.log + log_file="/dev/null" + run_ipt2socks flag=acl_${udp_node} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file + fi + fi + set_cache_var "ACL_${sid}_udp_node" "${udp_node}" + set_cache_var "ACL_${sid}_udp_redir_port" "${udp_port}" + fi + } + fi + } + unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh remote_dns_client_ip + unset _ip _mac _iprange _ipset _ip_or_mac source_list tcp_port udp_port config_file _extra_param dns_cache_key + unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6 remote_fakedns force_https_soa use_fakedns + done + unset socks_port redir_port dns_port dnsmasq_port chinadns_port + } +} + +start() { + mkdir -p /tmp/etc /tmp/log $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_PATH2 + get_config + export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/") + export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET + export ENABLE_DEPRECATED_GEOSITE=true + export ENABLE_DEPRECATED_GEOIP=true + export SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN=1 + ulimit -n 65535 + start_haproxy + start_socks + nftflag=0 + USE_TABLES="" + check_run_environment + if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then + [ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && { + uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1' + uci -q commit ${CONFIG} + uci -q set dhcp.@dnsmasq[0].dns_redirect='0' + uci -q commit dhcp + lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0 + } + fi + [ "$ENABLED_DEFAULT_ACL" == 1 ] && { + mkdir -p ${GLOBAL_ACL_PATH} + start_redir TCP + start_redir UDP + start_dns + } + [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start + set_cache_var "USE_TABLES" "$USE_TABLES" + if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then + bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables) + set_cache_var "bak_bridge_nf_ipt" "$bridge_nf_ipt" + sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1 + [ "$PROXY_IPV6" == "1" ] && { + bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables) + set_cache_var "bak_bridge_nf_ip6t" "$bridge_nf_ip6t" + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1 + } + fi + + start_crontab + echolog "è¿è¡Œå®Œæˆï¼\n" + + [ "$ENABLED" = 1 ] && [ "$1" = "boot" ] && { + local cfgids item + for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get "$item" boot_update 0)" = "1" ]; then + local cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1) + cfgids="${cfgids:+$cfgids,}$cfgid" + fi + done + [ -n "$cfgids" ] && { + sleep 5 + lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 & + } + } +} + +stop() { + clean_log + eval_cache_var + [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh stop + delete_ip2route + # ç»“æŸ SS æ’件进程 + # kill_all xray-plugin v2ray-plugin obfs-local shadow-tls + local pid_file pid + find "$TMP_PATH" -type f -name '*_plugin.pid' 2>/dev/null | while read -r pid_file; do + read -r pid < "$pid_file" + if [ -n "$pid" ]; then + kill -9 "$pid" >/dev/null 2>&1 + fi + done + busybox pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1 + busybox pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh|server_app\.lua|ujail/{print $1}' | xargs kill -9 >/dev/null 2>&1 + unset V2RAY_LOCATION_ASSET + unset XRAY_LOCATION_ASSET + unset SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN + stop_crontab + source $APP_PATH/helper_smartdns.sh del + rm -rf $GLOBAL_DNSMASQ_CONF + rm -rf $GLOBAL_DNSMASQ_CONF_PATH + [ "1" = "1" ] && { + #restore logic + bak_dnsmasq_dns_redirect=$(config_t_get global dnsmasq_dns_redirect) + [ -n "${bak_dnsmasq_dns_redirect}" ] && { + uci -q set dhcp.@dnsmasq[0].dns_redirect="${bak_dnsmasq_dns_redirect}" + uci -q commit dhcp + uci -q delete ${CONFIG}.@global[0].dnsmasq_dns_redirect + uci -q commit ${CONFIG} + } + if [ -z "${ACL_default_dns_port}" ] || [ -n "${bak_dnsmasq_dns_redirect}" ]; then + uci -q del_list dhcp.@dnsmasq[0].addnmount="${GLOBAL_DNSMASQ_CONF_PATH}" + uci -q commit dhcp + lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0 + fi + [ -n "${bak_bridge_nf_ipt}" ] && sysctl -w net.bridge.bridge-nf-call-iptables=${bak_bridge_nf_ipt} >/dev/null 2>&1 + [ -n "${bak_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${bak_bridge_nf_ip6t} >/dev/null 2>&1 + } + rm -rf $TMP_PATH + rm -f ${LOCK_PATH}/${CONFIG}_socks_auto_switch* + rm -f ${LOCK_PATH}/${CONFIG}_lease2hosts* + rm -f ${LOCK_PATH}/${CONFIG}_monitor* + echolog "清空并关闭相关程åºå’Œç¼“存完æˆã€‚" + exit 0 +} + +get_config() { + ENABLED_DEFAULT_ACL=0 + TCP_REDIR_PORT=1041 + UDP_REDIR_PORT=1051 + ENABLED=$(config_t_get global enabled 0) + SOCKS_ENABLED=$(config_t_get global socks_enabled 0) + TCP_NODE=$(config_t_get global tcp_node) + UDP_NODE=$(config_t_get global udp_node) + TCP_UDP=0 + if [ "$UDP_NODE" = "tcp" ]; then + UDP_NODE=$TCP_NODE + TCP_UDP=1 + elif [ "$UDP_NODE" = "$TCP_NODE" ]; then + TCP_UDP=1 + fi + [ -n "$TCP_NODE" ] && { + local protocol=$(config_n_get $TCP_NODE protocol) + [ "$protocol" = "_shunt" ] && [ -n "$UDP_NODE" ] && { + UDP_NODE=$TCP_NODE + TCP_UDP=1 + } + } + [ "$ENABLED" = 1 ] && { + local _node + for _node in "$TCP_NODE" "$UDP_NODE"; do + [ -n "$_node" ] && case "$_node" in + Socks_*) [ "$(config_get_type "${_node#Socks_}")" = "socks" ] && ENABLED_DEFAULT_ACL=1 ;; + *) [ "$(config_get_type "$_node")" = "nodes" ] && ENABLED_DEFAULT_ACL=1 ;; + esac + done + } + ENABLED_ACLS=$(config_t_get global acl_enable 0) + [ "$ENABLED_ACLS" = 1 ] && { + [ "$(uci show ${CONFIG} | grep "@acl_rule" | grep "enabled='1'" | wc -l)" == 0 ] && ENABLED_ACLS=0 + } + set_cache_var ENABLED_DEFAULT_ACL $ENABLED_DEFAULT_ACL + set_cache_var ENABLED_ACLS $ENABLED_ACLS + + TCP_PROXY_WAY=$(config_t_get global_forwarding tcp_proxy_way redirect) + PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0) + TCP_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '80,443') + UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535') + TCP_NO_REDIR_PORTS=$(config_t_get global_forwarding tcp_no_redir_ports 'disable') + UDP_NO_REDIR_PORTS=$(config_t_get global_forwarding udp_no_redir_ports 'disable') + TCP_PROXY_DROP_PORTS=$(config_t_get global_forwarding tcp_proxy_drop_ports 'disable') + UDP_PROXY_DROP_PORTS=$(config_t_get global_forwarding udp_proxy_drop_ports '80,443') + USE_DIRECT_LIST=$(config_t_get global use_direct_list 1) + USE_PROXY_LIST=$(config_t_get global use_proxy_list 1) + USE_BLOCK_LIST=$(config_t_get global use_block_list 1) + USE_GFW_LIST=$(config_t_get global use_gfw_list 1) + CHN_LIST=$(config_t_get global chn_list direct) + TCP_PROXY_MODE=$(config_t_get global tcp_proxy_mode proxy) + UDP_PROXY_MODE=$(config_t_get global udp_proxy_mode proxy) + [ "${TCP_PROXY_MODE}" != "disable" ] && TCP_PROXY_MODE="proxy" + [ "${UDP_PROXY_MODE}" != "disable" ] && UDP_PROXY_MODE="proxy" + LOCALHOST_PROXY=$(config_t_get global localhost_proxy 1) + [ "${LOCALHOST_PROXY}" == 1 ] && { + LOCALHOST_TCP_PROXY_MODE=$TCP_PROXY_MODE + LOCALHOST_UDP_PROXY_MODE=$UDP_PROXY_MODE + } + CLIENT_PROXY=$(config_t_get global client_proxy 1) + DNS_SHUNT=$(config_t_get global dns_shunt dnsmasq) + [ -z "$(first_type $DNS_SHUNT)" ] && DNS_SHUNT="dnsmasq" + DNS_MODE=$(config_t_get global dns_mode tcp) + [ "$DNS_SHUNT" = "smartdns" ] && DNS_MODE=$(config_t_get global smartdns_dns_mode socks) + REMOTE_DNS=$(config_t_get global remote_dns 1.1.1.1:53 | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g') + USE_DEFAULT_DNS=$(config_t_get global use_default_dns direct) + FILTER_PROXY_IPV6=$(config_t_get global filter_proxy_ipv6 0) + DNS_REDIRECT=$(config_t_get global dns_redirect 1) + + REDIRECT_LIST="socks ss-rust ssr sing-box xray naiveproxy hysteria2" + TPROXY_LIST="socks ss-rust ssr sing-box xray hysteria2" + + NEXT_DNS_LISTEN_PORT=15353 + TUN_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}" + DNS_CACHE=0 + DIRECT_DNS_QUERY_STRATEGY="UseIP" + REMOTE_DNS_QUERY_STRATEGY="UseIP" + [ "$FILTER_PROXY_IPV6" = "1" ] && REMOTE_DNS_QUERY_STRATEGY="UseIPv4" + DNSMASQ_FILTER_PROXY_IPV6=${FILTER_PROXY_IPV6} + + IPT_APPEND_DNS=${LOCAL_DNS} + + DNSMASQ_CONF_DIR=/tmp/dnsmasq.d + DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')" + if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then + DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")" + if [ -n "$DNSMASQ_CONF_DIR" ]; then + DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/} + else + DNSMASQ_CONF_DIR="/tmp/dnsmasq.d" + fi + fi + set_cache_var GLOBAL_DNSMASQ_CONF ${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf + set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d + + SMARTDNS_LOCAL_PORT=0 + SMARTDNS_LISTEN_PORT=0 + [ "${DNS_SHUNT}" = "smartdns" ] && { + NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1) + SMARTDNS_LOCAL_PORT=${NEXT_DNS_LISTEN_PORT} + NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1) + SMARTDNS_LISTEN_PORT=${NEXT_DNS_LISTEN_PORT} + NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1) + LOCAL_DNS="127.0.0.1#${SMARTDNS_LOCAL_PORT}" + set_cache_var "SMARTDNS_LOCAL_PORT" "${SMARTDNS_LOCAL_PORT}" + } +} + +get_local_dns() { + RESOLVFILE=/tmp/resolv.conf.d/resolv.conf.auto + [ -f "${RESOLVFILE}" ] && [ -s "${RESOLVFILE}" ] || RESOLVFILE=/tmp/resolv.conf.auto + + ISP_DNS=$(cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -v -E '^(0\.0\.0\.0|127\.0\.0\.1)$' | awk '!seen[$0]++') + ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}' | grep -v -Fx ::1 | grep -v -Fx :: | awk '!seen[$0]++') + + DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' '\n' | grep -v "\/" | sed ':label;N;s/\n/,/;b label') + [ -z "${DEFAULT_DNS}" ] && [ "$(echo $ISP_DNS | tr ' ' '\n' | wc -l)" -ge 1 ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | tr '\n' ',' | sed 's/,$//') + LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}" +} + +get_local_dns + +arg1=$1 +shift +case $arg1 in +run_socks) + run_socks $@ + ;; +socks_node_switch) + socks_node_switch $@ + ;; +start) + start $@ + ;; +stop) + stop + ;; +esac diff --git a/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua b/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua new file mode 100644 index 00000000..5ad9444b --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua @@ -0,0 +1,560 @@ +#!/usr/bin/lua + +-- Copyright(c): lwb1978 2025–2027 + +local api = require("luci.passwall.api") +local urlencode = api.UrlEncode +local base64 = api.base64Encode +local json = api.jsonc + +local function host_format(host) + if not host then return "" end + local str = host:match("%[(.-)%]") or host + if api.datatypes.ip6addr(str) then + return "[" .. str .. "]" + end + return host +end + +local function build_alpn(alpn) -- 排åº+åŽ»é‡ + if not alpn then return nil end + + local seen = {} + local order = { "h3", "h2", "http/1.1" } + + if type(alpn) == "table" then + for _, v in ipairs(alpn) do + if v then seen[v] = true end + end + else + seen[tostring(alpn)] = true + end + + local t = {} + for _, v in ipairs(order) do + if seen[v] then table.insert(t, v) end + end + + if #t == 0 then return nil end + return table.concat(t, ",") +end + +local function build_common(node) + local o = {} + + o.server = host_format(node.server) + o.port = node.port + o.name = node.name + + -- ===== TLS ===== + o.tls = {} + + if node["reality-opts"] then + o.tls.security = "reality" + o.tls.pbk = node["reality-opts"]["public-key"] + o.tls.sid = node["reality-opts"]["short-id"] + elseif node.tls then + o.tls.security = "tls" + end + + o.tls.sni = node.servername or node.sni + o.tls.fp = node["client-fingerprint"] + o.tls.pcs = node.fingerprint + o.tls.insecure = node["skip-cert-verify"] == true + + o.tls.alpn = build_alpn(node.alpn) + + local ech_opts = node["ech-opts"] + if ech_opts and ech_opts.enable == true then + if ech_opts["query-server-name"] then + o.tls.ech = ech_opts["query-server-name"] .. "+https://223.5.5.5/dns-query" + elseif ech_opts.config then + o.tls.ech = ech_opts.config + end + end + + -- ===== transport ===== + o.transport = {} + local net = node.network or "tcp" + o.transport.type = net + + local function get_first(v) + if type(v) == "table" then return v[1] end + return v + end + + if net == "ws" then + local opts = node["ws-opts"] + if opts then + o.transport.path = opts.path + o.transport.host = opts.headers and opts.headers.Host + end + + elseif net == "grpc" then + local opts = node["grpc-opts"] + if opts then + o.transport.serviceName = opts["grpc-service-name"] + end + + elseif net == "http" then + local opts = node["http-opts"] + if opts then + o.transport.host = get_first(opts.host) + o.transport.path = get_first(opts.path) + end + + elseif net == "h2" then + local opts = node["h2-opts"] + if opts then + o.transport.host = get_first(opts.host) + o.transport.path = opts.path + end + + elseif net == "xhttp" then + local opts = node["xhttp-opts"] + if opts then + o.transport.host = opts.host + o.transport.path = opts.path + o.transport.mode = opts.mode + + local extra = {} + + -- headers + if opts.headers then + extra.headers = opts.headers + end + + if opts["x-padding-bytes"] then + extra.xPaddingBytes = opts["x-padding-bytes"] + end + + if opts["no-grpc-header"] ~= nil then + extra.noGRPCHeader = opts["no-grpc-header"] + end + + if opts["sc-max-each-post-bytes"] then + extra.scMaxEachPostBytes = opts["sc-max-each-post-bytes"] + end + + if opts["sc-min-posts-interval-ms"] then + extra.scMinPostsIntervalMs = opts["sc-min-posts-interval-ms"] + end + + -- xmux + if opts["reuse-settings"] then + local r = opts["reuse-settings"] + local xmux = {} + + if r["max-concurrency"] then xmux.maxConcurrency = r["max-concurrency"] end + if r["max-connections"] then xmux.maxConnections = tonumber(r["max-connections"]) end + if r["c-max-reuse-times"] then xmux.cMaxReuseTimes = tonumber(r["c-max-reuse-times"]) end + if r["h-max-request-times"] then xmux.hMaxRequestTimes = r["h-max-request-times"] end + if r["h-max-reusable-secs"] then xmux.hMaxReusableSecs = r["h-max-reusable-secs"] end + if r["h-keep-alive-period"] then xmux.hKeepAlivePeriod = tonumber(r["h-keep-alive-period"]) end + + if next(xmux) then extra.xmux = xmux end + end + + -- download-settings + if opts["download-settings"] then + local d = opts["download-settings"] + local ds = {} + + if d.server then ds.address = d.server end + if d.port then ds.port = d.port end + + ds.network = "xhttp" + + -- TLS + if d.tls then + ds.security = "tls" + ds.tlsSettings = {} + + if d.servername then + ds.tlsSettings.serverName = d.servername + end + if d["skip-cert-verify"] == true then + ds.tlsSettings.allowInsecure = true + end + if d["client-fingerprint"] then + ds.tlsSettings.fingerprint = d["client-fingerprint"] + end + if d.fingerprint then + ds.tlsSettings.pinnedPeerCertSha256 = d.fingerprint + end + if d.alpn then + ds.tlsSettings.alpn = d.alpn + end + end + + -- xhttpSettings + local xs = {} + + if d.path then xs.path = d.path end + if d.host then xs.host = d.host end + + if next(xs) then + ds.xhttpSettings = xs + end + + extra.downloadSettings = ds + end + + if next(extra) then + o.transport.extra = json.stringify(extra) + end + end + end + + return o +end + +-- VLESS +local function encode_vless(node) + local o = build_common(node) + + local link = "vless://" .. node.uuid .. "@" .. o.server .. ":" .. o.port + local p = {} + + if node.flow then table.insert(p, "flow=" .. urlencode(node.flow)) end + if node.encryption then table.insert(p, "encryption=" .. urlencode(node.encryption)) end + + -- TLS + if o.tls.security then table.insert(p, "security=" .. o.tls.security) end + if o.tls.pbk then table.insert(p, "pbk=" .. urlencode(o.tls.pbk)) end + if o.tls.sid then table.insert(p, "sid=" .. urlencode(o.tls.sid)) end + if o.tls.sni then table.insert(p, "sni=" .. urlencode(o.tls.sni)) end + if o.tls.fp then table.insert(p, "fp=" .. urlencode(o.tls.fp)) end + if o.tls.alpn then table.insert(p, "alpn=" .. urlencode(o.tls.alpn)) end + if o.tls.ech then table.insert(p, "ech=" .. urlencode(o.tls.ech)) end + if o.tls.pcs then table.insert(p, "pcs=" .. urlencode(o.tls.pcs)) end + table.insert(p, "allowInsecure=" .. (o.tls.insecure and "1" or "0")) + + -- transport + table.insert(p, "type=" .. o.transport.type) + if o.transport.host then table.insert(p, "host=" .. urlencode(o.transport.host)) end + if o.transport.path then table.insert(p, "path=" .. urlencode(o.transport.path)) end + if o.transport.serviceName then table.insert(p, "serviceName=" .. urlencode(o.transport.serviceName)) end + if o.transport.mode then table.insert(p, "mode=" .. urlencode(o.transport.mode)) end + if o.transport.extra then table.insert(p, "extra=" .. urlencode(o.transport.extra)) end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(o.name or "") +end + +-- Trojan +local function encode_trojan(node) + local o = build_common(node) + + local link = "trojan://" .. node.password .. "@" .. o.server .. ":" .. o.port + local p = {} + + if o.tls.security then table.insert(p, "security=" .. o.tls.security) end + if o.tls.pbk then table.insert(p, "pbk=" .. urlencode(o.tls.pbk)) end + if o.tls.sid then table.insert(p, "sid=" .. urlencode(o.tls.sid)) end + if o.tls.sni then table.insert(p, "sni=" .. urlencode(o.tls.sni)) end + if o.tls.fp then table.insert(p, "fp=" .. urlencode(o.tls.fp)) end + if o.tls.alpn then table.insert(p, "alpn=" .. urlencode(o.tls.alpn)) end + if o.tls.ech then table.insert(p, "ech=" .. urlencode(o.tls.ech)) end + if o.tls.pcs then table.insert(p, "pcs=" .. urlencode(o.tls.pcs)) end + table.insert(p, "allowInsecure=" .. (o.tls.insecure and "1" or "0")) + + table.insert(p, "type=" .. o.transport.type) + if o.transport.host then table.insert(p, "host=" .. urlencode(o.transport.host)) end + if o.transport.path then table.insert(p, "path=" .. urlencode(o.transport.path)) end + if o.transport.serviceName then table.insert(p, "serviceName=" .. urlencode(o.transport.serviceName)) end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(o.name or "") +end + +-- VMess +local function encode_vmess(node) + local o = build_common(node) + + local obj = { + v = "2", + ps = o.name, + add = node.server, + port = tostring(node.port), + id = node.uuid, + aid = tostring(node.alterId or 0), + net = o.transport.type, + security = node.cipher, + scy = node.cipher, + type = "none", + host = o.transport.host or "", + path = o.transport.path or "", + tls = o.tls.security == "tls" and "tls" or "", + sni = o.tls.sni, + alpn = o.tls.alpn, + fp = o.tls.fp, + ech = o.tls.ech, + pcs = o.tls.pcs, + insecure = o.tls.insecure and "1" or "0", + tfo = node.tfo and "1" or "0" + } + + if o.transport.type == "grpc" then + obj.path = o.transport.serviceName or "" + end + + return "vmess://" .. base64(json.stringify(obj)) +end + +-- SS +local function encode_ss(node) + local userinfo = node.cipher .. ":" .. node.password + local base = userinfo .. "@" .. host_format(node.server) .. ":" .. node.port + local link = "ss://" .. base64(base) + + local p = {} + + if node.udp then table.insert(p, "udp=1") end + if node["udp-over-tcp"] then table.insert(p, "uot=1") end + + if node.plugin then + local plugin = (node.plugin == "obfs") and "obfs-local" or node.plugin + if plugin == "shadow-tls" then + local shadow_tls = base64(json.stringify(node["plugin-opts"] or {})) + table.insert(p, "shadow-tls=" .. urlencode(shadow_tls)) + else + local opts = {} + for k, v in pairs(node["plugin-opts"] or {}) do + if plugin == "obfs-local" then + if k == "mode" then k = "obfs" end + if k == "host" then k = "obfs-host" end + elseif plugin == "v2ray-plugin" then + if k == "mode" and v == "websocket" then + v = nil + elseif type(v) == "boolean" then + if v == true then + table.insert(opts, k) + end + v = nil + end + elseif plugin == "gost-plugin" then + if k == "mode" and v == "websocket" then v = "ws" end + if k == "host" then k = "serverName" end + if k == "headers" then v = nil end + end + if v ~= nil then + if type(v) == "boolean" then + v = v and "1" or "0" + end + table.insert(opts, k .. "=" .. v) + end + end + if #opts > 0 then plugin = plugin .. ";" .. table.concat(opts, ";") end + table.insert(p, "plugin=" .. urlencode(plugin)) + end + end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(node.name or "") +end + +-- Hysteria +local function encode_hysteria2(node) + local link = "hysteria://" .. host_format(node.server) .. ":" .. (node.port or "") + local p = {} + + if node["auth-str"] then table.insert(p, "auth=" .. node["auth-str"]) end + if node["ports"] then table.insert(p, "mport=" .. node["ports"]) end + if node.obfs then table.insert(p, "obfsParam=" .. node.obfs) end + if node.sni then table.insert(p, "sni=" .. node.sni) end + if node.up then table.insert(p, "upmbps=" .. node.up) end + if node.down then table.insert(p, "downmbps=" .. node.down) end + if node["skip-cert-verify"] then table.insert(p, "insecure=1") end + if node["fingerprint"] then table.insert(p, "pinSHA256=" .. urlencode(node["fingerprint"])) end + + if node.alpn then + table.insert(p, "alpn=" .. urlencode(build_alpn(node.alpn))) + end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(node.name or "") +end + +-- Hysteria2 +local function encode_hysteria2(node) + local link = "hysteria2://" .. (node.password or "") .. "@" .. host_format(node.server) .. ":" .. (node.port or "") + local p = {} + + if node["ports"] then table.insert(p, "mport=" .. urlencode(node["ports"])) end + if node.obfs then table.insert(p, "obfs=" .. node.obfs) end + if node["obfs-password"] then table.insert(p, "obfs-password=" .. node["obfs-password"]) end + if node.up then table.insert(p, "upmbps=" .. node.up) end + if node.down then table.insert(p, "downmbps=" .. node.down) end + + if node.sni then table.insert(p, "sni=" .. urlencode(node.sni)) end + if node["skip-cert-verify"] then table.insert(p, "insecure=1") end + if node["fingerprint"] then table.insert(p, "pinSHA256=" .. urlencode(node["fingerprint"])) end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(node.name or "") +end + +-- TUIC +local function encode_tuic(node) + local link = "tuic://" .. node.uuid .. ":" .. node.password .. "@" .. host_format(node.server) .. ":" .. node.port + local p = {} + + if node["congestion-controller"] then + table.insert(p, "congestion_control=" .. node["congestion-controller"]) + end + + if node.alpn then + table.insert(p, "alpn=" .. urlencode(build_alpn(node.alpn))) + end + + if node.sni then table.insert(p, "sni=" .. urlencode(node.sni)) end + if node["disable-sni"] then table.insert(p, "disable_sni=1") end + if node["skip-cert-verify"] then table.insert(p, "allowInsecure=1") end + if node["udp-relay-mode"] then table.insert(p, "udp_relay_mode=" .. node["udp-relay-mode"]) end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(node.name or "") +end + +-- AnyTLS +local function encode_anytls(node) + local o = build_common(node) + + local link = "anytls://" .. (node.password or "") .. "@" .. host_format(node.server) .. ":" .. node.port + local p = {} + + if o.tls.sni then table.insert(p, "sni=" .. urlencode(o.tls.sni)) end + if o.tls.alpn then table.insert(p, "alpn=" .. urlencode(o.tls.alpn)) end + if o.tls.fp then table.insert(p, "fp=" .. urlencode(o.tls.fp)) end + if o.tls.ech then table.insert(p, "ech=" .. urlencode(o.tls.ech)) end + if o.tls.pcs then + table.insert(p, "allowInsecure=1") + else + table.insert(p, "allowInsecure=" .. (o.tls.insecure and "1" or "0")) + end + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return link .. "#" .. urlencode(node.name or "") +end + +-- SSR +local function encode_ssr(node) + local link = host_format(node.server) .. ":" .. node.port .. ":" .. (node.protocol or "") .. ":" .. + (node.cipher or "") .. ":" .. (node.obfs or "") .. ":" .. base64(node.password) + local p = {} + + if node["obfs-param"] then table.insert(p, "obfsparam=" .. base64(node["obfs-param"])) end + if node["protocol-param"] then table.insert(p, "protoparam=" .. base64(node["protocol-param"])) end + table.insert(p, "remarks=" .. base64(node.name)) + + if #p > 0 then + link = link .. "?" .. table.concat(p, "&") + end + + return "ssr://" .. base64(link) +end + +local function encode_node(node) + if (not node.type) or (not node.name) then return nil end + + local t = node.type + + if t == "vless" then return encode_vless(node) + elseif t == "trojan" then return encode_trojan(node) + elseif t == "vmess" then return encode_vmess(node) + elseif t == "ss" then return encode_ss(node) + elseif t == "hysteria" then return encode_hysteria(node) + elseif t == "hysteria2" then return encode_hysteria2(node) + elseif t == "tuic" then return encode_tuic(node) + elseif t == "anytls" then return encode_anytls(node) + elseif t == "ssr" then return encode_ssr(node) + else api.log("è®¢é˜…è½¬æ¢ â†’ ä¸¢å¼ƒä¸æ”¯æŒçš„节点:" .. node.name .. ",节点类型:" .. t) + end +end + +function parseClashNode(raw, remark) + if not raw then return "" end + local ok, lyaml = pcall(require, "lyaml") + if not ok then return raw end + + local data = lyaml.load(raw) + if not data or type(data) ~= "table" then return raw end + if not data.proxies then return "" end + + api.log('检测到 Clash è®¢é˜…ï¼Œæ­£åœ¨è¿›è¡Œè½¬æ¢ ...') + + local links = {} + for _, node in ipairs(data.proxies) do + local link = encode_node(node) + if link then + table.insert(links, link) + end + end + + return #links > 0 and table.concat(links, "\n") or "" +end + +function parse_clash_sub_info(headers) + local userinfo = headers:match("[Ss]ubscription%-userinfo:%s*([^\r\n]+)") + if not userinfo then return nil end + + local upload = tonumber(userinfo:match("upload=(%d+)")) or 0 + local download = tonumber(userinfo:match("download=(%d+)")) or 0 + local total = tonumber(userinfo:match("total=(%d+)")) or 0 + local expire = tonumber(userinfo:match("expire=(%d+)")) + local remain = total - (upload + download) + if remain < 0 then remain = 0 end + + local function format_size(bytes) + local units = { "B", "KB", "MB", "GB", "TB", "PB" } + local i = 1 + while bytes >= 1024 and i < #units do + bytes = bytes / 1024 + i = i + 1 + end + if bytes >= 100 then + return string.format("%.0f%s", bytes, units[i]) + elseif bytes >= 10 then + return string.format("%.1f%s", bytes, units[i]) + else + return string.format("%.2f%s", bytes, units[i]) + end + end + + local rem_traffic = format_size(remain) + + local expired_date + if expire and expire > 0 then + local t = os.date("*t", expire) + expired_date = string.format("%d-%d-%d", t.year, t.month, t.day) + else + expired_date = "长期有效" + end + + return { + rem_traffic = rem_traffic, + expired_date = expired_date + } +end diff --git a/luci-app-passwall/root/usr/share/passwall/haproxy.lua b/luci-app-passwall/root/usr/share/passwall/haproxy.lua new file mode 100644 index 00000000..ba5e171f --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/haproxy.lua @@ -0,0 +1,238 @@ +#!/usr/bin/lua + +local api = require ("luci.passwall.api") +local appname = api.appname +local fs = api.fs +local jsonc = api.jsonc +local uci = api.uci +local sys = api.sys + +local log = function(...) + api.log(...) +end + +function get_ip_port_from(str) + local result_port = sys.exec("echo -n " .. str .. " | sed -n 's/^.*[:#]\\([0-9]*\\)$/\\1/p'") + local result_ip = sys.exec(string.format("__host=%s;__varport=%s;", str, result_port) .. "echo -n ${__host%%${__varport:+[:#]${__varport}*}}") + return result_ip, result_port +end + +local var = api.get_args(arg) +local haproxy_path = var["-path"] +local haproxy_conf = var["-conf"] +local haproxy_dns = var["-dns"] or "119.29.29.29:53,223.5.5.5:53" + +local cpu_thread = sys.exec('echo -n $(cat /proc/cpuinfo | grep "processor" | wc -l)') or "1" +local health_check_type = uci:get(appname, "@global_haproxy[0]", "health_check_type") or "tcp" +local health_check_inter = uci:get(appname, "@global_haproxy[0]", "health_check_inter") or "20" +local balancingStrategy = uci:get(appname, "@global_haproxy[0]", "balancingStrategy") or "roundrobin" +local console_port = uci:get(appname, "@global_haproxy[0]", "console_port") +local bind_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0" +local bind_address = "0.0.0.0" +if bind_local == "1" then bind_address = "127.0.0.1" end + +log("HAPROXY è´Ÿè½½å‡è¡¡ï¼š") +log(string.format(" * 控制å°ç«¯å£ï¼š%s", console_port)) +fs.mkdir(haproxy_path) +local haproxy_file = haproxy_path .. "/" .. haproxy_conf + +local f_out = io.open(haproxy_file, "a") + +local haproxy_config = [[ +global + daemon + log 127.0.0.1 local2 + maxconn 60000 + stats socket {{path}}/haproxy.sock + nbthread {{nbthread}} + external-check + insecure-fork-wanted + spread-checks 50 + tune.max-checks-per-thread 5 + +defaults + mode tcp + log global + option tcplog + option dontlognull + option http-server-close + #option forwardfor except 127.0.0.0/8 + option redispatch + retries 2 + timeout http-request 10s + timeout queue 1m + timeout connect 10s + timeout client 1m + timeout server 1m + timeout http-keep-alive 10s + timeout check 10s + maxconn 3000 + +resolvers mydns + resolve_retries 1 + timeout resolve 5s + hold valid 600s +{{dns}} +]] + +haproxy_config = haproxy_config:gsub("{{path}}", haproxy_path) +haproxy_config = haproxy_config:gsub("{{nbthread}}", cpu_thread) + +local mydns = "" +local index = 0 +string.gsub(haproxy_dns, '[^' .. "," .. ']+', function(w) + index = index + 1 + local s = w:gsub("#", ":") + if not s:find(":") then + s = s .. ":53" + end + mydns = mydns .. (index > 1 and "\n" or "") .. " " .. string.format("nameserver dns%s %s", index, s) +end) +haproxy_config = haproxy_config:gsub("{{dns}}", mydns) + +f_out:write(haproxy_config) + +local listens = {} + +uci:foreach(appname, "haproxy_config", function(t) + if t.enabled == "1" then + local server_remark + local server_address + local server_port + local lbss = t.lbss + local listen_port = tonumber(t.haproxy_port) or 0 + local server_node = uci:get_all(appname, lbss) + local hop = (health_check_type == "passwall_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil + hop = hop and hop:gsub(":", "-") or nil + if server_node and server_node.address and (server_node.port or hop) then + server_remark = server_node.address .. ":" .. (server_node.port or hop) + server_address = server_node.address + server_port = server_node.port or hop + t.origin_address = server_address + t.origin_port = server_port + if health_check_type == "passwall_logic" then + if server_node.type ~= "Socks" then + local relay_port = server_node.port + local new_port = api.get_new_port() + local config_file = string.format("haproxy_%s_%s.json", t[".name"], new_port) + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s", + new_port, --flag + server_node[".name"], --node + "127.0.0.1", --bind + new_port, --socks port + config_file --config file + ) + ) + ) + server_address = "127.0.0.1" + server_port = new_port + end + end + else + server_address, server_port = get_ip_port_from(lbss) + server_remark = server_address .. ":" .. server_port + t.origin_address = server_address + t.origin_port = server_port + end + if server_address and server_port and listen_port > 0 then + if not listens[listen_port] then + listens[listen_port] = {} + end + t.server_remark = server_remark + t.server_address = server_address + t.server_port = server_port + table.insert(listens[listen_port], t) + else + log(" - 丢弃1个明显无效的节点") + end + end +end) + +local inter = tonumber((health_check_inter or "20"):match("^%d+")) +inter = (inter and inter >= 20) and inter or 20 +local inter_arg = "inter " .. inter .. "s fastinter " .. inter / 2 .. "s downinter " .. inter * 1.5 .. "s" + +local sortTable = {} +for i in pairs(listens) do + if i ~= nil then + table.insert(sortTable, i) + end +end +table.sort(sortTable, function(a,b) return (a < b) end) + +for i, port in pairs(sortTable) do + log(" + å…¥å£ %s:%s" % {bind_address, port}) + + f_out:write("\n" .. string.format([[ +listen %s + bind %s:%s + mode tcp + balance %s +]], port, bind_address, port, balancingStrategy)) + + if health_check_type == "passwall_logic" then + f_out:write(string.format([[ + option external-check + external-check command "/usr/share/%s/haproxy_check.sh" +]], appname)) + end + + local count_M, count_B = 1, 1 + for i, o in ipairs(listens[port]) do + local remark = o.server_remark or "" + -- 防止é‡å导致无法è¿è¡Œ + if tostring(o.backup) ~= "1" then + remark = "M" .. count_M .. "-" .. remark + count_M = count_M + 1 + else + remark = "B" .. count_B .. "-" .. remark + count_B = count_B + 1 + end + local server = o.server_address .. ":" .. o.server_port + local server_conf = "server {{remark}} {{server}} weight {{weight}} {{resolvers}} check {{inter_arg}} rise 2 fall 2 {{backup}}" + server_conf = server_conf:gsub("{{remark}}", remark) + server_conf = server_conf:gsub("{{server}}", server) + server_conf = server_conf:gsub("{{weight}}", o.lbweight) + local resolvers = "resolvers mydns" + if api.is_ip(o.server_address) then + resolvers = "" + end + server_conf = server_conf:gsub("{{resolvers}}", resolvers) + server_conf = server_conf:gsub("{{inter_arg}}", inter_arg) + server_conf = server_conf:gsub("{{backup}}", tostring(o.backup) == "1" and "backup" or "") + + f_out:write(" " .. api.trim(server_conf) .. "\n") + + if o.export ~= "0" then + sys.call(string.format(". /usr/share/%s/utils.sh ; add_ip2route %s %s", appname, o.origin_address, o.export)) + end + + log(string.format(" | - 出å£èŠ‚ç‚¹ï¼š%s:%s,æƒé‡ï¼š%s", o.origin_address, o.origin_port, o.lbweight)) + end +end + +--控制å°é…ç½® +local console_user = uci:get(appname, "@global_haproxy[0]", "console_user") +local console_password = uci:get(appname, "@global_haproxy[0]", "console_password") +local str = [[ +listen console + bind 0.0.0.0:%s + mode http + stats refresh 30s + stats uri / + stats admin if TRUE + %s +]] +f_out:write("\n" .. string.format(str, console_port, (console_user and console_user ~= "" and console_password and console_password ~= "") and "stats auth " .. console_user .. ":" .. console_password or "")) + +f_out:close() + +--passwall内置å¥åº·æ£€æŸ¥URL +if health_check_type == "passwall_logic" then + local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204" + local f_url = io.open(haproxy_path .. "/Probe_URL", "w") + f_url:write(probeUrl) + f_url:close() +end diff --git a/luci-app-passwall/root/usr/share/passwall/haproxy_check.sh b/luci-app-passwall/root/usr/share/passwall/haproxy_check.sh new file mode 100755 index 00000000..3b5700f3 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/haproxy_check.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin +CONFIG=passwall + +listen_address=$1 +listen_port=$2 +server_address=$3 +server_port=$4 + +busybox pgrep -af "${CONFIG}/" | grep -E 'app\.sh.*(start|stop)|nftables\.sh|iptables\.sh|subscribe\.lua' >/dev/null && { + # ç‰¹å®šä»»åŠ¡æ‰§è¡Œä¸­ä¸æ£€æµ‹ + exit 0 +} + +probe_file="/tmp/etc/passwall/haproxy/Probe_URL" +probeUrl="https://www.google.com/generate_204" +if [ -f "$probe_file" ]; then + firstLine=$(head -n 1 "$probe_file" | tr -d ' \t\n') + [ -n "$firstLine" ] && probeUrl="$firstLine" +fi + +extra_params="-x socks5h://${server_address}:${server_port}" +if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then + extra_params="${extra_params} --retry-all-errors" +fi + +status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout 3 --retry 1 --max-time 6 -w "%{http_code}" "${probeUrl}") + +case "$status" in + 200|204) + exit 0 + ;; + *) + exit 1 + ;; +esac diff --git a/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua new file mode 100644 index 00000000..209fe258 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua @@ -0,0 +1,538 @@ +local api = require "luci.passwall.api" +local appname = api.appname + +local var = api.get_args(arg) +local FLAG = var["-FLAG"] +local LISTEN_PORT = var["-LISTEN_PORT"] +local DNS_LOCAL = var["-DNS_LOCAL"] +local DNS_TRUST = var["-DNS_TRUST"] +local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"] +local USE_PROXY_LIST = var["-USE_PROXY_LIST"] +local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"] +local GFWLIST = var["-GFWLIST"] +local CHNLIST = var["-CHNLIST"] +local NO_IPV6_TRUST = var["-NO_IPV6_TRUST"] +local DEFAULT_MODE = var["-DEFAULT_MODE"] +local DEFAULT_TAG = var["-DEFAULT_TAG"] +local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"] +local TCP_NODE = var["-TCP_NODE"] +local NFTFLAG = var["-NFTFLAG"] +local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"] +local FILTER_HTTPS = var["-FILTER_HTTPS"] +local LOG_FILE = var["-LOG_FILE"] + +local uci = api.uci +local sys = api.sys +local fs = api.fs +local datatypes = api.datatypes + +local TMP_PATH = "/tmp/etc/" .. appname +local TMP_ACL_PATH = TMP_PATH .. "/acl" +local RULES_PATH = "/usr/share/" .. appname .. "/rules" +local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG +local config_lines = {} +local tmp_lines = {} +local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview") +local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt" + +if IS_SHUNT_NODE then + REMOTE_FAKEDNS = uci:get(appname, TCP_NODE, "fakedns") or "0" +end + +local function log(...) + if NO_LOGIC_LOG == "1" then + return + end + api.log(...) +end + +local function is_file_nonzero(path) + if path and #path > 1 then + if sys.exec('[ -s "%s" ] && echo -n 1' % path) == "1" then + return true + end + end + return nil +end + +local function insert_unique(dest_table, value, lookup_table) + if not lookup_table[value] then + table.insert(dest_table, value) + lookup_table[value] = true + end +end + +local function merge_array(array1, array2) + for i, line in ipairs(array2) do + table.insert(array1, #array1 + 1, line) + end +end + +local function insert_array_before(array1, array2, target) --å°†array2æ’入到array1çš„targetå‰é¢ï¼Œtargetä¸å­˜åœ¨åˆ™è¿½åŠ  + for i, line in ipairs(array1) do + if line == target then + for j = #array2, 1, -1 do + table.insert(array1, i, array2[j]) + end + return + end + end + merge_array(array1, array2) +end + +local function insert_array_after(array1, array2, target) --å°†array2æ’入到array1çš„targetåŽé¢ï¼Œtargetä¸å­˜åœ¨åˆ™è¿½åŠ  + for i, line in ipairs(array1) do + if line == target then + for j = 1, #array2 do + table.insert(array1, i + j, array2[j]) + end + return + end + end + merge_array(array1, array2) +end + +local function get_geosite(list_arg, out_path) + local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/" + geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat" + if not is_file_nonzero(geosite_path) then return 1 end + local bin = api.finded_com("geoview") + if bin and list_arg and out_path then + local cmd = string.format("%q -type geosite -append=true -input %q -list %q -output %q -lowmem=true", + bin, geosite_path, list_arg, out_path) + sys.call(cmd) + return 0 + end + return 1 +end + +if not fs.access(FLAG_PATH) then + fs.mkdir(FLAG_PATH) +end + +local setflag = (NFTFLAG == "1") and "inet@passwall@" or "" + +local only_global = (DEFAULT_MODE == "proxy" and CHNLIST == "0" and GFWLIST == "0") and 1 + +config_lines = { + LOG_FILE ~= "/dev/null" and "verbose" or "", + "bind-addr ::", + "bind-port " .. LISTEN_PORT, + "china-dns " .. DNS_LOCAL, + "trust-dns " .. DNS_TRUST, + tonumber(FILTER_HTTPS) == 1 and "filter-qtype 65" or "" +} + +for i = 1, 6 do + table.insert(config_lines, "#--" .. i) +end + +--自定义规则组,åŽå£°æ˜Žçš„组具有更高优先级 +--å±è”½åˆ—表 +local file_block_host = TMP_ACL_PATH .. "/block_host" +if USE_BLOCK_LIST == "1" and not fs.access(file_block_host) then + local block_domain, lookup_block_domain = {}, {} + local geosite_arg = "" + for line in io.lines(RULES_PATH .. "/block_host") do + if not line:find("#") and line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + geosite_arg = geosite_arg .. (geosite_arg ~= "" and "," or "") .. line + else + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(block_domain, line, lookup_block_domain) + end + end + end + if #block_domain > 0 then + local f_out = io.open(file_block_host, "w") + for i = 1, #block_domain do + f_out:write(block_domain[i] .. "\n") + end + f_out:close() + end + if USE_GEOVIEW == "1" and geosite_arg ~= "" and api.is_finded("geoview") then + if get_geosite(geosite_arg, file_block_host) == 0 then + log(" * è§£æž[å±è”½åˆ—表] Geosite 到å±è”½åŸŸå表(blocklist)完æˆ") + else + log(" * è§£æž[å±è”½åˆ—表] Geosite 到å±è”½åŸŸå表(blocklist)失败ï¼") + end + end +end +if USE_BLOCK_LIST == "1" and is_file_nonzero(file_block_host) then + tmp_lines = { + "group null", + "group-dnl " .. file_block_host + } + insert_array_after(config_lines, tmp_lines, "#--5") +end + +--始终用国内DNSè§£æžèŠ‚ç‚¹åŸŸå +local file_vpslist = TMP_ACL_PATH .. "/vpslist" +if not is_file_nonzero(file_vpslist) then + local f_out = io.open(file_vpslist, "w") + local written_domains = {} + local function process_address(address) + address = (address or ""):lower() + if api.vps_domain_exclude(address) then return end + if datatypes.hostname(address) and not written_domains[address] then + f_out:write(address .. "\n") + written_domains[address] = true + end + end + uci:foreach(appname, "nodes", function(t) + process_address(t.address) + process_address(t.download_address) + end) + uci:foreach(appname, "subscribe_list", function(t) --订阅链接 + local url, _ = api.get_domain_port_from_url(t.url or "") + if url and url ~= "" then + process_address(url) + end + end) + f_out:close() +end +if is_file_nonzero(file_vpslist) then + local sets = { + setflag .. "psw_vps", + setflag .. "psw_vps6" + } + tmp_lines = { + "group vpslist", + "group-dnl " .. file_vpslist, + "group-upstream " .. DNS_LOCAL, + "group-ipset " .. table.concat(sets, ",") + } + insert_array_after(config_lines, tmp_lines, "#--6") + log(string.format(" - 节点列表中的域å(vpslist):%s", DNS_LOCAL or "默认")) +end + +--直连(白åå•)列表 +local file_direct_host = TMP_ACL_PATH .. "/direct_host" +if USE_DIRECT_LIST == "1" and not fs.access(file_direct_host) then + local direct_domain, lookup_direct_domain = {}, {} + local geosite_arg = "" + for line in io.lines(RULES_PATH .. "/direct_host") do + if not line:find("#") and line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + geosite_arg = geosite_arg .. (geosite_arg ~= "" and "," or "") .. line + else + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(direct_domain, line, lookup_direct_domain) + end + end + end + if #direct_domain > 0 then + local f_out = io.open(file_direct_host, "w") + for i = 1, #direct_domain do + f_out:write(direct_domain[i] .. "\n") + end + f_out:close() + end + if USE_GEOVIEW == "1" and geosite_arg ~= "" and api.is_finded("geoview") then + if get_geosite(geosite_arg, file_direct_host) == 0 then + log(" * è§£æž[直连列表] Geosite 到域å白åå•(whitelist)完æˆ") + else + log(" * è§£æž[直连列表] Geosite 到域å白åå•(whitelist)失败ï¼") + end + end +end +if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then + local sets = { + setflag .. "psw_white", + setflag .. "psw_white6" + } + tmp_lines = { + "group directlist", + "group-dnl " .. file_direct_host, + "group-upstream " .. DNS_LOCAL, + "group-ipset " .. table.concat(sets, ",") + } + insert_array_after(config_lines, tmp_lines, "#--4") + log(string.format(" - 域å白åå•(whitelist):%s", DNS_LOCAL or "默认")) +end + +--代ç†ï¼ˆé»‘åå•)列表 +local file_proxy_host = TMP_ACL_PATH .. "/proxy_host" +if USE_PROXY_LIST == "1" and not fs.access(file_proxy_host) then + local proxy_domain, lookup_proxy_domain = {}, {} + local geosite_arg = "" + for line in io.lines(RULES_PATH .. "/proxy_host") do + if not line:find("#") and line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + geosite_arg = geosite_arg .. (geosite_arg ~= "" and "," or "") .. line + else + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(proxy_domain, line, lookup_proxy_domain) + end + end + end + if #proxy_domain > 0 then + local f_out = io.open(file_proxy_host, "w") + for i = 1, #proxy_domain do + f_out:write(proxy_domain[i] .. "\n") + end + f_out:close() + end + if USE_GEOVIEW == "1" and geosite_arg ~= "" and api.is_finded("geoview") then + if get_geosite(geosite_arg, file_proxy_host) == 0 then + log(" * è§£æž[代ç†åˆ—表] Geosite 到代ç†åŸŸå表(blacklist)完æˆ") + else + log(" * è§£æž[代ç†åˆ—表] Geosite 到代ç†åŸŸå表(blacklist)失败ï¼") + end + end +end +if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then + local sets = { + setflag .. "psw_black", + setflag .. "psw_black6" + } + if FLAG ~= "default" then + sets = { + setflag .. "psw_" .. FLAG .. "_black", + setflag .. "psw_" .. FLAG .. "_black6" + } + end + tmp_lines = { + "group proxylist", + "group-dnl " .. file_proxy_host, + "group-upstream " .. DNS_TRUST, + REMOTE_FAKEDNS ~= "1" and "group-ipset " .. table.concat(sets, ",") or "" + } + if NO_IPV6_TRUST == "1" then table.insert(tmp_lines, "no-ipv6 tag:proxylist") end + insert_array_after(config_lines, tmp_lines, "#--3") + log(string.format(" - 代ç†åŸŸå表(blacklist):%s", DNS_TRUST or "默认")) +end + +--内置组(chn/gfw)ä¼˜å…ˆçº§åœ¨è‡ªå®šä¹‰ç»„åŽ +--GFW列表 +if GFWLIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then + local sets = { + setflag .. "psw_gfw", + setflag .. "psw_gfw6" + } + if FLAG ~= "default" then + sets = { + setflag .. "psw_" .. FLAG .. "_gfw", + setflag .. "psw_" .. FLAG .. "_gfw6" + } + end + tmp_lines = { + "gfwlist-file " .. RULES_PATH .. "/gfwlist", + REMOTE_FAKEDNS ~= "1" and "add-taggfw-ip " .. table.concat(sets, ",") or "" + } + if NO_IPV6_TRUST == "1" then table.insert(tmp_lines, "no-ipv6 tag:gfw") end + merge_array(config_lines, tmp_lines) + log(string.format(" - 防ç«å¢™åŸŸå表(gfwlist):%s", DNS_TRUST or "默认")) +end + +--中国列表 +if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then + if CHNLIST == "direct" then + tmp_lines = { + "chnlist-file " .. RULES_PATH .. "/chnlist", + "ipset-name4 " .. setflag .. "psw_chn", + "ipset-name6 " .. setflag .. "psw_chn6", + "add-tagchn-ip", + "chnlist-first" + } + merge_array(config_lines, tmp_lines) + log(string.format(" - 中国域å表(chnroute):%s", DNS_LOCAL or "默认")) + end + + --å›žä¸­å›½æ¨¡å¼ + if CHNLIST == "proxy" then + local sets = { + setflag .. "psw_chn", + setflag .. "psw_chn6" + } + tmp_lines = { + "group chn_proxy", + "group-dnl " .. RULES_PATH .. "/chnlist", + "group-upstream " .. DNS_TRUST, + REMOTE_FAKEDNS ~= "1" and "group-ipset " .. table.concat(sets, ",") or "" + } + if NO_IPV6_TRUST == "1" then table.insert(tmp_lines, "no-ipv6 tag:chn_proxy") end + insert_array_after(config_lines, tmp_lines, "#--1") + log(string.format(" - 中国域å表(chnroute):%s", DNS_TRUST or "默认")) + end +end + +--分æµè§„则 +if IS_SHUNT_NODE then + local white_domain, lookup_white_domain = {}, {} + local shunt_domain, lookup_shunt_domain = {}, {} + local file_white_host = FLAG_PATH .. "/shunt_direct_host" + local file_shunt_host = FLAG_PATH .. "/shunt_proxy_host" + local geosite_white_arg, geosite_shunt_arg = "", "" + + local t = uci:get_all(appname, TCP_NODE) + local default_node_id = t["default_node"] or "_direct" + uci:foreach(appname, "shunt_rules", function(s) + local _node_id = t[s[".name"]] + if _node_id and _node_id ~= "_blackhole" then + if _node_id == "_default" then + _node_id = default_node_id + end + + local domain_list = s.domain_list or "" + for line in string.gmatch(domain_list, "[^\r\n]+") do + if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("ext:") then + if line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + if _node_id == "_direct" then + geosite_white_arg = geosite_white_arg .. (geosite_white_arg ~= "" and "," or "") .. line + else + geosite_shunt_arg = geosite_shunt_arg .. (geosite_shunt_arg ~= "" and "," or "") .. line + end + else + if line:find("domain:") or line:find("full:") then + line = string.match(line, ":([^:]+)$") + end + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + if _node_id == "_direct" then + insert_unique(white_domain, line, lookup_white_domain) + else + insert_unique(shunt_domain, line, lookup_shunt_domain) + end + end + end + end + end + + if _node_id ~= "_direct" then + log(string.format(" - Sing-Box/Xray分æµè§„则(%s):%s", s.remarks, DNS_TRUST or "默认")) + end + end + end) + + if is_file_nonzero(file_white_host) == nil then + if #white_domain > 0 then + local f_out = io.open(file_white_host, "w") + for i = 1, #white_domain do + f_out:write(white_domain[i] .. "\n") + end + f_out:close() + end + end + + if is_file_nonzero(file_shunt_host) == nil then + if #shunt_domain > 0 then + local f_out = io.open(file_shunt_host, "w") + for i = 1, #shunt_domain do + f_out:write(shunt_domain[i] .. "\n") + end + f_out:close() + end + end + + if GFWLIST == "1" and CHNLIST == "0" and USE_GEOVIEW == "1" and api.is_finded("geoview") then --ä»…GFW模å¼è§£æžgeosite + local return_white, return_shunt + if geosite_white_arg ~= "" then + return_white = get_geosite(geosite_white_arg, file_white_host) + end + if geosite_shunt_arg ~= "" then + return_shunt = get_geosite(geosite_shunt_arg, file_shunt_host) + end + if (return_white == nil or return_white == 0) and (return_shunt == nil or return_shunt == 0) then + log(" * è§£æž[分æµèŠ‚ç‚¹] Geosite 完æˆ") + else + log(" * è§£æž[分æµèŠ‚ç‚¹] Geosite 失败ï¼") + end + end + + local sets = { + setflag .. "psw_shunt", + setflag .. "psw_shunt6" + } + if FLAG ~= "default" then + sets = { + setflag .. "psw_" .. FLAG .. "_shunt", + setflag .. "psw_" .. FLAG .. "_shunt6" + } + end + + if is_file_nonzero(file_white_host) then + if USE_DIRECT_LIST == "1" then + --当白åå•å¯ç”¨æ—¶ï¼Œæ·»åŠ åˆ°ç™½åå•组一åŒå¤„ç† + for i, v in ipairs(config_lines) do + if v == "group-dnl " .. file_direct_host then + config_lines[i] = "group-dnl " .. file_direct_host .. "," .. file_white_host + break + end + end + else + --当白åå•ä¸å¯ç”¨æ—¶ï¼Œåˆ›å»ºæ–°ç»„,ipset到shuntlist + tmp_lines = { + "group whitelist", + "group-dnl " .. file_white_host, + "group-upstream " .. DNS_LOCAL, + "group-ipset " .. table.concat(sets, ",") + } + insert_array_after(config_lines, tmp_lines, "#--4") + end + + end + + if is_file_nonzero(file_shunt_host) then + tmp_lines = { + "group shuntlist", + "group-dnl " .. file_shunt_host, + "group-upstream " .. DNS_TRUST, + (not only_global and REMOTE_FAKEDNS == "1") and "" or ("group-ipset " .. table.concat(sets, ",")) + } + if NO_IPV6_TRUST == "1" then table.insert(tmp_lines, "no-ipv6 tag:shuntlist") end + insert_array_after(config_lines, tmp_lines, "#--2") + end + +end + +--åªä½¿ç”¨gfwlist模å¼ï¼ŒGFW列表以外的域ååŠé»˜è®¤ä½¿ç”¨æœ¬åœ°DNS +if GFWLIST == "1" and CHNLIST == "0" then DEFAULT_TAG = "chn" end + +--回中国模å¼ï¼Œä¸­å›½åˆ—表以外的域ååŠé»˜è®¤ä½¿ç”¨æœ¬åœ°DNS +if CHNLIST == "proxy" then DEFAULT_TAG = "chn" end + +--全局模å¼ï¼Œé»˜è®¤ä½¿ç”¨è¿œç¨‹DNS +if only_global then + DEFAULT_TAG = "gfw" + if NO_IPV6_TRUST == "1" and not IS_SHUNT_NODE then + table.insert(config_lines, "no-ipv6") + end +end + +--æ˜¯å¦æŽ¥å—直连 DNS 空å“应 +if DEFAULT_TAG == "none_noip" then table.insert(config_lines, "noip-as-chnip") end + +if DEFAULT_TAG == nil or DEFAULT_TAG == "smart" or DEFAULT_TAG == "none_noip" then DEFAULT_TAG = "none" end + +table.insert(config_lines, "default-tag " .. DEFAULT_TAG) + +if DEFAULT_TAG == "none" then + table.insert(config_lines, "verdict-cache 5000") +end + +table.insert(config_lines, "hosts") + +if DEFAULT_TAG == "chn" then + log(string.format(" - 默认 DNS :%s", DNS_LOCAL)) +elseif DEFAULT_TAG == "gfw" then + log(string.format(" - 默认 DNS :%s", DNS_TRUST)) +else + log(string.format(" - 默认 DNS :%s", "智能匹é…")) +end + +--输出é…置文件 +if #config_lines > 0 then + for i = 1, #config_lines do + line = config_lines[i] + if line ~= "" and not line:find("^#--") then + print(line) + end + end +end + +log(" - ChinaDNS-NG已作为Dnsmasq上游,如果你自行é…置了错误的DNSæµç¨‹ï¼Œå°†ä¼šå¯¼è‡´åŸŸå(直连/代ç†åŸŸå)分æµå¤±æ•ˆï¼ï¼ï¼") diff --git a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua new file mode 100644 index 00000000..2b318cfc --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua @@ -0,0 +1,737 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local uci = api.uci +local sys = api.sys +local fs = api.fs +local datatypes = api.datatypes +local TMP = {} + +local function tinsert(table_name, val) + if table_name and type(table_name) == "table" then + if not TMP[table_name] then + TMP[table_name] = {} + end + if TMP[table_name][val] then + return false + end + table.insert(table_name, val) + TMP[table_name][val] = true + return true + end + return false +end + +local function backup_servers() + local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server") + if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then + uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS) + api.uci_save(uci, appname, true) + end +end + +local function restore_servers() + local dns_table = {} + local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server") + if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then + for k, v in ipairs(DNSMASQ_DNS) do + tinsert(dns_table, v) + end + end + local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers") + if OLD_SERVER and #OLD_SERVER > 0 then + for k, v in ipairs(OLD_SERVER) do + tinsert(dns_table, v) + end + uci:delete(appname, "@global[0]", "dnsmasq_servers") + api.uci_save(uci, appname, true) + end + if dns_table and #dns_table > 0 then + uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table) + api.uci_save(uci, "dhcp", true) + end +end + +function stretch() + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + local dnsmasq_noresolv = uci:get("dhcp", "@dnsmasq[0]", "noresolv") + local _flag + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if not v:find("/") then + _flag = true + end + end + end + if not _flag and dnsmasq_noresolv == "1" then + uci:delete("dhcp", "@dnsmasq[0]", "noresolv") + local RESOLVFILE = "/tmp/resolv.conf.d/resolv.conf.auto" + local file = io.open(RESOLVFILE, "r") + if not file then + RESOLVFILE = "/tmp/resolv.conf.auto" + else + local size = file:seek("end") + file:close() + if size == 0 then + RESOLVFILE = "/tmp/resolv.conf.auto" + end + end + uci:set("dhcp", "@dnsmasq[0]", "resolvfile", RESOLVFILE) + api.uci_save(uci, "dhcp", true) + end +end + +function restart(var) + local LOG = var["-LOG"] + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + if LOG == "1" then + api.log("é‡å¯ dnsmasq æœåŠ¡") + end +end + +function logic_restart(var) + local LOG = var["-LOG"] + local DEFAULT_DNS = api.get_cache_var("DEFAULT_DNS") + if DEFAULT_DNS then + backup_servers() + --sys.call("sed -i '/list server/d' /etc/config/dhcp >/dev/null 2>&1") + local dns_table = {} + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if v:find("/") then + tinsert(dns_table, v) + end + end + uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table) + api.uci_save(uci, "dhcp", true) + end + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + restore_servers() + else + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + end + if LOG == "1" then + api.log("é‡å¯ dnsmasq æœåŠ¡") + end +end + +function copy_instance(var) + local LISTEN_PORT = var["-LISTEN_PORT"] + local TMP_DNSMASQ_PATH = var["-TMP_DNSMASQ_PATH"] + local conf_lines = {} + local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')") + for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do + local filter + if line:find("passwall") then filter = true end + if line:find("ubus") then filter = true end + if line:find("dhcp") then filter = true end + if line:find("server=") == 1 then filter = true end + if line:find("port=") == 1 then filter = true end + if line:find("conf%-dir=") == 1 then + filter = true + if TMP_DNSMASQ_PATH then + local tmp_path = line:sub(1 + #"conf-dir=") + sys.call(string.format("cp -r %s/* %s/ 2>/dev/null", tmp_path, TMP_DNSMASQ_PATH)) + end + end + if line:find("address=") == 1 or (line:find("server=") == 1 and line:find("/")) then filter = nil end + if not filter then + tinsert(conf_lines, line) + end + end + tinsert(conf_lines, "port=" .. LISTEN_PORT) + if TMP_DNSMASQ_PATH then + sys.call("rm -rf " .. TMP_DNSMASQ_PATH .. "/*passwall*") + end + if var["-return"] == "1" then + return conf_lines + end + if #conf_lines > 0 then + local DNSMASQ_CONF = var["-DNSMASQ_CONF"] + local conf_out = io.open(DNSMASQ_CONF, "a") + conf_out:write(table.concat(conf_lines, "\n")) + conf_out:write("\n") + conf_out:close() + end +end + +function add_rule(var) + local FLAG = var["-FLAG"] + local TMP_DNSMASQ_PATH = var["-TMP_DNSMASQ_PATH"] + local DNSMASQ_CONF_FILE = var["-DNSMASQ_CONF_FILE"] + local LISTEN_PORT = var["-LISTEN_PORT"] + local DEFAULT_DNS = var["-DEFAULT_DNS"] + local LOCAL_DNS = var["-LOCAL_DNS"] + local TUN_DNS = var["-TUN_DNS"] + local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"] + local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"] + local CHINADNS_DNS = var["-CHINADNS_DNS"] + local TCP_NODE = var["-TCP_NODE"] + local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"] + local USE_PROXY_LIST = var["-USE_PROXY_LIST"] + local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"] + local USE_GFW_LIST = var["-USE_GFW_LIST"] + local CHN_LIST = var["-CHN_LIST"] + local DEFAULT_PROXY_MODE = var["-DEFAULT_PROXY_MODE"] + local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"] + local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"] + local NFTFLAG = var["-NFTFLAG"] + local CACHE_PATH = api.CACHE_PATH + local CACHE_FLAG = "dnsmasq_" .. FLAG + local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG + local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt" + local USE_CHINADNS_NG = "0" + local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt" + + if IS_SHUNT_NODE then + REMOTE_FAKEDNS = uci:get(appname, TCP_NODE, "fakedns") or "0" + end + + local list1 = {} + local excluded_domain = {} + + local function log(...) + if NO_LOGIC_LOG == "1" then + return + end + api.log(...) + end + + local function check_dns(domain, dns) + if domain == "" or domain:find("#") then + return false + end + if not dns then + return + end + for k,v in ipairs(list1[domain].dns) do + if dns == v then + return true + end + end + return false + end + + local function check_ipset(domain, ipset) + if domain == "" or domain:find("#") then + return false + end + if not ipset then + return + end + for k,v in ipairs(list1[domain].ipsets) do + if ipset == v then + return true + end + end + return false + end + + local function set_domain_address(domain, address) + if domain == "" or domain:find("#") then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + if not list1[domain].address then + list1[domain].address = address + end + end + + local function set_domain_dns(domain, dns) + if domain == "" or domain:find("#") then + return + end + if not dns then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + for line in string.gmatch(dns, '[^' .. "," .. ']+') do + if not check_dns(domain, line) then + table.insert(list1[domain].dns, line) + end + end + end + + local function set_domain_ipset(domain, ipset) + if domain == "" or domain:find("#") then + return + end + if not ipset then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + for line in string.gmatch(ipset, '[^' .. "," .. ']+') do + if not check_ipset(domain, line) then + table.insert(list1[domain].ipsets, line) + end + end + end + + local function add_excluded_domain(domain) + if domain == "" or domain:find("#") then + return + end + excluded_domain[domain] = true + end + + local function check_excluded_domain(domain) + if domain == "" or domain:find("#") then + return false + end + if excluded_domain[domain] then + return true + end + local pos = domain:find(".", 1, true) + while pos do + if excluded_domain[domain:sub(pos + 1)] then + return true + end + pos = domain:find(".", pos + 1, true) + end + return false + end + + local cache_text = "" + local nodes_address_md5 = sys.exec("echo -n $(uci show passwall | grep '\\.address') | md5sum") + local new_rules = sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)") + local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. USE_DEFAULT_DNS .. CHINADNS_DNS .. USE_DIRECT_LIST .. USE_PROXY_LIST .. USE_BLOCK_LIST .. USE_GFW_LIST .. CHN_LIST .. DEFAULT_PROXY_MODE .. NO_PROXY_IPV6 .. nodes_address_md5 .. new_rules .. NFTFLAG + if fs.access(CACHE_TEXT_FILE) then + for line in io.lines(CACHE_TEXT_FILE) do + cache_text = line + end + end + + if cache_text ~= new_text then + api.remove(CACHE_DNS_PATH .. "*") + end + + local dnsmasq_default_dns + if USE_DEFAULT_DNS ~= "nil" then + if USE_DEFAULT_DNS == "direct" then + dnsmasq_default_dns = LOCAL_DNS + end + if USE_DEFAULT_DNS == "remote" then + dnsmasq_default_dns = TUN_DNS + end + if USE_DEFAULT_DNS == "remote" and CHN_LIST == "direct" then + dnsmasq_default_dns = TUN_DNS + end + end + + local only_global + if DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0" then + --没有å¯ç”¨ä¸­å›½åˆ—表和GFW列表时 + dnsmasq_default_dns = TUN_DNS + only_global = 1 + end + if USE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then + dnsmasq_default_dns = CHINADNS_DNS + USE_CHINADNS_NG = "1" + end + + local setflag_4= (NFTFLAG == "1") and "4#inet#passwall#" or "" + local setflag_6= (NFTFLAG == "1") and "6#inet#passwall#" or "" + + if not fs.access(CACHE_DNS_PATH) then + fs.mkdir(CACHE_DNS_PATH) + + --å±è”½åˆ—表 + if USE_CHINADNS_NG == "0" then + if USE_BLOCK_LIST == "1" then + for line in io.lines("/usr/share/passwall/rules/block_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") and not line:find(":") then + set_domain_address(line, "") + end + end + end + end + + local fwd_dns + local no_ipv6 + + --始终用国内DNSè§£æžèŠ‚ç‚¹åŸŸå + if true then + fwd_dns = LOCAL_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + else + local sets = { + setflag_4 .. "psw_vps", + setflag_6 .. "psw_vps6" + } + local function process_address(address) + address = (address or ""):lower() + if api.vps_domain_exclude(address) then return end + if datatypes.hostname(address) then + set_domain_dns(address, fwd_dns) + set_domain_ipset(address, table.concat(sets, ",")) + end + end + uci:foreach(appname, "nodes", function(t) + process_address(t.address) + process_address(t.download_address) + end) + uci:foreach(appname, "subscribe_list", function(t) --订阅链接 + local url, _ = api.get_domain_port_from_url(t.url or "") + if url and url ~= "" then + process_address(url) + end + end) + log(string.format(" - 节点列表中的域å(vpslist):%s", fwd_dns or "默认")) + end + end + + --直连(白åå•)列表 + if USE_DIRECT_LIST == "1" then + if fs.access("/usr/share/passwall/rules/direct_host") then + fwd_dns = LOCAL_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + local sets = { + setflag_4 .. "psw_white", + setflag_6 .. "psw_white6" + } + --始终用国内DNSè§£æžç›´è¿žï¼ˆç™½åå•)列表 + for line in io.lines("/usr/share/passwall/rules/direct_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") and not line:find(":") then + add_excluded_domain(line) + set_domain_dns(line, fwd_dns) + set_domain_ipset(line, table.concat(sets, ",")) + end + end + log(string.format(" - 域å白åå•(whitelist):%s", fwd_dns or "默认")) + end + end + end + + --代ç†ï¼ˆé»‘åå•)列表 + if USE_PROXY_LIST == "1" then + if fs.access("/usr/share/passwall/rules/proxy_host") then + fwd_dns = TUN_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + local set_name = "psw_black" + local set6_name = "psw_black6" + if FLAG ~= "default" then + set_name = "psw_" .. FLAG .. "_black" + set6_name = "psw_" .. FLAG .. "_black6" + end + local sets = { + setflag_4 .. set_name + } + if NO_PROXY_IPV6 ~= "1" then + table.insert(sets, setflag_6 .. set6_name) + end + if REMOTE_FAKEDNS == "1" then + sets = {} + end + --始终使用远程DNSè§£æžä»£ç†ï¼ˆé»‘åå•)列表 + for line in io.lines("/usr/share/passwall/rules/proxy_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") and not line:find(":") then + add_excluded_domain(line) + if NO_PROXY_IPV6 == "1" then + set_domain_address(line, "::") + end + set_domain_dns(line, fwd_dns) + set_domain_ipset(line, table.concat(sets, ",")) + end + end + log(string.format(" - 代ç†åŸŸå表(blacklist):%s", fwd_dns or "默认")) + end + end + end + + --GFW列表 + if USE_GFW_LIST == "1" then + if fs.access("/usr/share/passwall/rules/gfwlist") then + fwd_dns = TUN_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + local set_name = "psw_gfw" + local set6_name = "psw_gfw6" + if FLAG ~= "default" then + set_name = "psw_" .. FLAG .. "_gfw" + set6_name = "psw_" .. FLAG .. "_gfw6" + end + local sets = { + setflag_4 .. set_name + } + if NO_PROXY_IPV6 ~= "1" then + table.insert(sets, setflag_6 .. set6_name) + end + if REMOTE_FAKEDNS == "1" then + sets = {} + end + for line in io.lines("/usr/share/passwall/rules/gfwlist") do + if line ~= "" and not line:find("#") and not check_excluded_domain(line) then + if NO_PROXY_IPV6 == "1" then + set_domain_address(line, "::") + end + if dnsmasq_default_dns == fwd_dns then + fwd_dns = nil + else + set_domain_dns(line, fwd_dns) + end + set_domain_ipset(line, table.concat(sets, ",")) + end + end + log(string.format(" - 防ç«å¢™åŸŸå表(gfwlist):%s", fwd_dns or "默认")) + end + end + end + + --中国列表 + if CHN_LIST ~= "0" then + if fs.access("/usr/share/passwall/rules/chnlist") then + fwd_dns = nil + if CHN_LIST == "direct" then + fwd_dns = LOCAL_DNS + end + if CHN_LIST == "proxy" then + fwd_dns = TUN_DNS + end + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + local sets = { + setflag_4 .. "psw_chn", + setflag_6 .. "psw_chn6" + } + if CHN_LIST == "proxy" then + if NO_PROXY_IPV6 == "1" then + sets = { + setflag_4 .. "psw_chn" + } + end + if REMOTE_FAKEDNS == "1" then + sets = {} + end + end + for line in io.lines("/usr/share/passwall/rules/chnlist") do + if line ~= "" and not line:find("#") and not check_excluded_domain(line) then + if CHN_LIST == "proxy" and NO_PROXY_IPV6 == "1" then + set_domain_address(line, "::") + end + if dnsmasq_default_dns == fwd_dns then + fwd_dns = nil + else + set_domain_dns(line, fwd_dns) + end + set_domain_ipset(line, table.concat(sets, ",")) + end + end + log(string.format(" - 中国域å表(chnroute):%s", fwd_dns or "默认")) + end + end + end + + --分æµè§„则 + if IS_SHUNT_NODE and USE_CHINADNS_NG == "0" then + local t = uci:get_all(appname, TCP_NODE) + local default_node_id = t["default_node"] or "_direct" + uci:foreach(appname, "shunt_rules", function(s) + local _node_id = t[s[".name"]] + if _node_id and _node_id ~= "_blackhole" then + if _node_id == "_default" then + _node_id = default_node_id + end + + fwd_dns = nil + no_ipv6 = nil + + local sets = {} + + if _node_id == "_direct" then + fwd_dns = LOCAL_DNS + if USE_DIRECT_LIST == "1" then + table.insert(sets, setflag_4 .. "psw_white") + table.insert(sets, setflag_6 .. "psw_white6") + else + local set_name = "psw_shunt" + local set6_name = "psw_shunt6" + if FLAG ~= "default" then + set_name = "psw_" .. FLAG .. "_shunt" + set6_name = "psw_" .. FLAG .. "_shunt6" + end + table.insert(sets, setflag_4 .. set_name) + table.insert(sets, setflag_6 .. set6_name) + end + else + local set_name = "psw_shunt" + local set6_name = "psw_shunt6" + if FLAG ~= "default" then + set_name = "psw_" .. FLAG .. "_shunt" + set6_name = "psw_" .. FLAG .. "_shunt6" + end + fwd_dns = TUN_DNS + table.insert(sets, setflag_4 .. set_name) + if NO_PROXY_IPV6 ~= "1" then + table.insert(sets, setflag_6 .. set6_name) + else + no_ipv6 = true + end + if not only_global then + if REMOTE_FAKEDNS == "1" then + sets = {} + end + end + end + + local domain_list = s.domain_list or "" + for line in string.gmatch(domain_list, "[^\r\n]+") do + if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then + if line:find("domain:") or line:find("full:") then + line = string.match(line, ":([^:]+)$") + end + line = api.get_std_domain(line) + add_excluded_domain(line) + + if no_ipv6 then + set_domain_address(line, "::") + end + set_domain_dns(line, fwd_dns) + set_domain_ipset(line, table.concat(sets, ",")) + end + end + if _node_id ~= "_direct" then + log(string.format(" - Sing-Box/Xray分æµè§„则(%s):%s", s.remarks, fwd_dns or "默认")) + end + end + end) + elseif only_global == 1 and NO_PROXY_IPV6 == "1" then + --节点:固定节点 + --ä»£ç†æ¨¡å¼ï¼šå…¨å±€æ¨¡å¼ + --过滤代ç†åŸŸå IPv6:å¯ç”¨ + --ç¦æ­¢è§£æžæ‰€æœ‰IPv6记录 + list1["#"] = { + dns = {}, + ipsets = {}, + address = "::" + } + end + + if list1 and next(list1) then + local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a") + local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a") + local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a") + local set_name = "ipset" + if NFTFLAG == "1" then + set_name = "nftset" + end + for key, value in pairs(list1) do + if value.address then + local domain = "." .. key + if key == "#" then + domain = key + end + address_out:write(string.format("address=/%s/%s", domain, value.address) .. "\n") + end + if value.dns and #value.dns > 0 then + for i, dns in ipairs(value.dns) do + server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n") + end + end + if value.ipsets and #value.ipsets > 0 then + local ipsets_str = "" + for i, ipset in ipairs(value.ipsets) do + ipsets_str = ipsets_str .. ipset .. "," + end + ipsets_str = ipsets_str:sub(1, #ipsets_str - 1) + ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n") + end + end + address_out:close() + server_out:close() + ipset_out:close() + end + + local f_out = io.open(CACHE_TEXT_FILE, "a") + f_out:write(new_text) + f_out:close() + end + + if USE_CHINADNS_NG == "0" then + api.remove(TMP_DNSMASQ_PATH) + fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH) + end + + if DNSMASQ_CONF_FILE ~= "nil" then + local conf_lines = {} + if LISTEN_PORT then + --Copy dnsmasq instance + conf_lines = copy_instance({["-LISTEN_PORT"] = LISTEN_PORT, ["-TMP_DNSMASQ_PATH"] = TMP_DNSMASQ_PATH, ["-return"] = "1"}) + --dhcp.leases to hosts + local hosts = "/tmp/etc/" .. appname .. "_tmp/dhcp-hosts" + sys.call("touch " .. hosts) + tinsert(conf_lines, "addn-hosts=" .. hosts) + else + --Modify the default dnsmasq service + end + if USE_CHINADNS_NG == "0" then + tinsert(conf_lines, string.format("conf-dir=%s", TMP_DNSMASQ_PATH)) + end + if dnsmasq_default_dns then + for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do + tinsert(conf_lines, string.format("server=%s", s)) + end + tinsert(conf_lines, "all-servers") + tinsert(conf_lines, "no-poll") + tinsert(conf_lines, "no-resolv") + if USE_CHINADNS_NG == "0" then + log(string.format(" - 默认:%s", dnsmasq_default_dns)) + end + + if FLAG == "default" then + api.set_cache_var("DEFAULT_DNS", DEFAULT_DNS) + end + end + if #conf_lines > 0 then + local conf_out = io.open(DNSMASQ_CONF_FILE, "a") + conf_out:write(table.concat(conf_lines, "\n")) + conf_out:write("\n") + conf_out:close() + end + end + + if USE_CHINADNS_NG == "0" then + log(" - PassWallå¿…é¡»ä¾èµ–于Dnsmasq,如果你自行é…置了错误的DNSæµç¨‹ï¼Œå°†ä¼šå¯¼è‡´åŸŸå(直连/代ç†åŸŸå)分æµå¤±æ•ˆï¼ï¼ï¼") + end +end + +_G.stretch = stretch +_G.restart = restart +_G.logic_restart = logic_restart +_G.copy_instance = copy_instance +_G.add_rule = add_rule + +if arg[1] then + local func =_G[arg[1]] + if func then + func(api.get_function_args(arg)) + end +end diff --git a/luci-app-passwall/root/usr/share/passwall/helper_smartdns.sh b/luci-app-passwall/root/usr/share/passwall/helper_smartdns.sh new file mode 100755 index 00000000..14254f14 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/helper_smartdns.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +restart() { + local no_log + eval_set_val $@ + _LOG_FILE=$LOG_FILE + [ -n "$no_log" ] && LOG_FILE="/dev/null" + rm -rf /tmp/smartdns.cache + /etc/init.d/smartdns reload >/dev/null 2>&1 + LOG_FILE=${_LOG_FILE} +} + +del() { + rm -rf /tmp/etc/smartdns/passwall.conf + sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1 + rm -rf /tmp/smartdns.cache + /etc/init.d/smartdns reload >/dev/null 2>&1 +} + +arg1=$1 +shift +case $arg1 in +del) + del $@ + ;; +restart) + restart $@ + ;; +*) ;; +esac diff --git a/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua new file mode 100644 index 00000000..818d8fdc --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua @@ -0,0 +1,696 @@ +local api = require "luci.passwall.api" +local appname = api.appname + +local var = api.get_args(arg) +local FLAG = var["-FLAG"] +local SMARTDNS_CONF = var["-SMARTDNS_CONF"] +local LOCAL_GROUP = var["-LOCAL_GROUP"] +local REMOTE_GROUP = var["-REMOTE_GROUP"] +local REMOTE_PROXY_SERVER = var["-REMOTE_PROXY_SERVER"] +local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"] +local REMOTE_DNS = var["-REMOTE_DNS"] +local TUN_DNS = var["-TUN_DNS"] +local DNS_MODE = var["-DNS_MODE"] +local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"] +local TCP_NODE = var["-TCP_NODE"] +local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"] +local USE_PROXY_LIST = var["-USE_PROXY_LIST"] +local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"] +local USE_GFW_LIST = var["-USE_GFW_LIST"] +local CHN_LIST = var["-CHN_LIST"] +local DEFAULT_PROXY_MODE = var["-DEFAULT_PROXY_MODE"] +local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"] +local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"] +local NFTFLAG = var["-NFTFLAG"] +local SUBNET = var["-SUBNET"] +local LISTEN_PORT = var["-LISTEN_PORT"] +local LOCAL_PORT = var["-LOCAL_PORT"] + +local uci = api.uci +local sys = api.sys +local fs = api.fs +local datatypes = api.datatypes + +local TMP_PATH = "/tmp/etc/" .. appname +local TMP_ACL_PATH = TMP_PATH .. "/acl" +local RULES_PATH = "/usr/share/" .. appname .. "/rules" +local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG +local TMP_CONF_FILE = FLAG_PATH .. "/smartdns.conf" +local config_lines = {} +local tmp_lines = {} +local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview") +local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt" + +if IS_SHUNT_NODE then + REMOTE_FAKEDNS = uci:get(appname, TCP_NODE, "fakedns") or "0" +end + +local function log(...) + if NO_LOGIC_LOG == "1" then + return + end + api.log(...) +end + +local function is_file_nonzero(path) + if path and #path > 1 then + if sys.exec('[ -s "%s" ] && echo -n 1' % path) == "1" then + return true + end + end + return nil +end + +local function insert_unique(dest_table, value, lookup_table) + if not lookup_table[value] then + table.insert(dest_table, value) + lookup_table[value] = true + end +end + +local function merge_array(array1, array2) + for i, line in ipairs(array2) do + table.insert(array1, #array1 + 1, line) + end +end + +local function insert_array_before(array1, array2, target) --å°†array2æ’入到array1çš„targetå‰é¢ï¼Œtargetä¸å­˜åœ¨åˆ™è¿½åŠ  + for i, line in ipairs(array1) do + if line == target then + for j = #array2, 1, -1 do + table.insert(array1, i, array2[j]) + end + return + end + end + merge_array(array1, array2) +end + +local function insert_array_after(array1, array2, target) --å°†array2æ’入到array1çš„targetåŽé¢ï¼Œtargetä¸å­˜åœ¨åˆ™è¿½åŠ  + for i, line in ipairs(array1) do + if line == target then + for j = 1, #array2 do + table.insert(array1, i + j, array2[j]) + end + return + end + end + merge_array(array1, array2) +end + +local function get_geosite(list_arg, out_path) + local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/" + geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat" + if not is_file_nonzero(geosite_path) then return 1 end + local bin = api.finded_com("geoview") + if bin and list_arg and out_path then + local cmd = string.format("%q -type geosite -append=true -input %q -list %q -output %q -lowmem=true", + bin, geosite_path, list_arg, out_path) + sys.call(cmd) + return 0 + end + return 1 +end + +if not fs.access(FLAG_PATH) then + fs.mkdir(FLAG_PATH) +end + +local LOCAL_EXTEND_ARG = "" +if LOCAL_GROUP == "null" or LOCAL_GROUP == "" then + log(" * 注æ„:SmartDNS å›½å†…åˆ†ç»„åæœªè®¾ç½®ï¼ŒDNS 将无法正常工作ï¼ï¼ï¼") + os.exit(1) +else + --从smartdnsé…置中读å–傿•° + local custom_conf_path = "/etc/smartdns/custom.conf" + local options = { + {key = "dualstack_ip_selection", config_key = "dualstack-ip-selection", yes_no = true, arg_yes = "-d yes", arg_no = "-d no", default = "yes"}, + {key = "speed_check_mode", config_key = "speed-check-mode", prefix = "-c ", default = "ping,tcp:80,tcp:443"}, + {key = "serve_expired", config_key = "serve-expired", yes_no = true, arg_yes = "", arg_no = "-no-serve-expired", default = "yes"}, + {key = "response_mode", config_key = "response-mode", prefix = "-r ", default = "first-ping"}, + {key = "rr_ttl", config_key = "rr-ttl", prefix = "-rr-ttl "}, + {key = "rr_ttl_min", config_key = "rr-ttl-min", prefix = "-rr-ttl-min "}, + {key = "rr_ttl_max", config_key = "rr-ttl-max", prefix = "-rr-ttl-max "}, + {key = "rr_ttl_reply_max", config_key = "rr-ttl-reply-max", prefix = "-rr-ttl-reply-max "}, + { + key = "force_aaaa_soa", + config_key = "force-qtype-SOA", + prefix = "-address ", + get_value = function(custom_config) + local soa = custom_config["force-qtype-SOA"] + return ((soa and soa:match("(^|%s)28(%s|$)")) + or custom_config["force-AAAA-SOA"] == "yes" + or uci:get("smartdns", "@smartdns[0]", "force_aaaa_soa") == "1") + and "#6" or "-6" + end + } + } + -- 从 custom.conf 中读å–值,以最åŽå‡ºçŽ°çš„å€¼ä¸ºå‡† + local custom_config = {} + local f_in = io.open(custom_conf_path, "r") + if f_in then + for line in f_in:lines() do + line = api.trim(line) + if line ~= "" and not line:match("^#") then + local param, value = line:match("^(%S+)%s+(.+)$") + if param and value then custom_config[param] = value end + end + end + f_in:close() + end + -- 从 smartdns é…置中读å–值,优先级以 custom.conf 为准 + for _, opt in ipairs(options) do + local val + if opt.get_value then + val = opt.get_value(custom_config) + else + val = custom_config[opt.config_key] or uci:get("smartdns", "@smartdns[0]", opt.key) or opt.default + end + if val == "yes" then val = "1" elseif val == "no" then val = "0" end + if opt.yes_no then + local arg = (val == "1" and opt.arg_yes or opt.arg_no) + if arg and arg ~= "" then + LOCAL_EXTEND_ARG = LOCAL_EXTEND_ARG .. (LOCAL_EXTEND_ARG ~= "" and " " or "") .. arg + end + else + if val and (not opt.value or (opt.invert and val ~= opt.value) or (not opt.invert and val == opt.value)) then + LOCAL_EXTEND_ARG = LOCAL_EXTEND_ARG .. (LOCAL_EXTEND_ARG ~= "" and " " or "") .. (opt.prefix or "") .. (opt.arg or val) + end + end + end +end + +if not REMOTE_GROUP or REMOTE_GROUP == "nil" then + REMOTE_GROUP = "passwall_proxy" + if REMOTE_DNS then + REMOTE_DNS = REMOTE_DNS:gsub("#", ":") + end + sys.call('sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1') +end + +local force_https_soa = uci:get(appname, "@global[0]", "force_https_soa") or 0 +local proxy_server_name = "passwall-proxy-server" +config_lines = { + tonumber(LISTEN_PORT) ~= 0 and "bind [::]:" .. LISTEN_PORT .. "@lo" or "", + (tonumber(LOCAL_PORT) ~= 0 and LOCAL_GROUP) and "bind [::]:" .. LOCAL_PORT .. "@lo -group " .. LOCAL_GROUP or "", + tonumber(force_https_soa) == 1 and "force-qtype-SOA 65" or "force-qtype-SOA -,65", + "server 223.5.5.5 -bootstrap-dns", + is_file_nonzero("/etc/hosts") and "hosts-file /etc/hosts" or "", + DNS_MODE == "socks" and string.format("proxy-server socks5://%s -name %s", REMOTE_PROXY_SERVER, proxy_server_name) or "" +} +if DNS_MODE == "socks" then + for w in string.gmatch(REMOTE_DNS, '[^|]+') do + local server_dns = api.trim(w) + local server_param + + local dnsType = string.match(server_dns, "^(.-)://") + dnsType = dnsType and string.lower(dnsType) or nil + local dnsServer = string.match(server_dns, "://(.+)") or server_dns + + if dnsType and dnsType ~= "" and dnsType ~= "udp" then + if dnsType == "tcp" then + server_param = "server-tcp " .. dnsServer + elseif dnsType == "tls" then + server_param = "server-tls " .. dnsServer + elseif dnsType == "quic" then + server_param = "server-quic " .. dnsServer + elseif dnsType == "https" or dnsType == "h3" then + local http_host = nil + local url = w + local port = 443 + local s = api.split(w, ",") + if s and #s > 1 then + url = s[1] + local dns_ip = s[2] + local host_port = api.get_domain_from_url(s[1]) + if host_port and #host_port > 0 then + http_host = host_port + local s2 = api.split(host_port, ":") + if s2 and #s2 > 1 then + http_host = s2[1] + port = s2[2] + end + url = url:gsub(http_host, dns_ip) + end + end + server_dns = url + if http_host then + server_dns = server_dns .. " -http-host " .. http_host + end + server_param = (dnsType == "https" and "server-https " or "server-h3 ") .. server_dns + end + else + server_param = "server " .. dnsServer + + end + + if not api.is_local_ip(w) then + server_param = server_param .. " -proxy " .. proxy_server_name + end + + server_param = server_param .. " -group " .. REMOTE_GROUP .. " -exclude-default-group" + if SUBNET and SUBNET ~= "" and SUBNET ~= "0" then + server_param = server_param .. " -subnet " .. SUBNET + end + table.insert(config_lines, server_param) + end + if not IS_SHUNT_NODE then REMOTE_FAKEDNS = "0" end +else + local server_param = string.format("server %s -group %s -exclude-default-group", TUN_DNS:gsub("#", ":"), REMOTE_GROUP) + table.insert(config_lines, server_param) + log(" - " .. DNS_MODE:gsub("^%l",string.upper) .. " " .. TUN_DNS .. " -> " .. REMOTE_GROUP) +end + +--设置默认 DNS 分组(托底组) +local DEFAULT_DNS_GROUP = (USE_DEFAULT_DNS == "direct" and LOCAL_GROUP) or + (USE_DEFAULT_DNS == "remote" and REMOTE_GROUP) +local only_global = (DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0") and 1 --没有å¯ç”¨ä¸­å›½åˆ—表和GFW列表时(全局) +if only_global == 1 then + DEFAULT_DNS_GROUP = REMOTE_GROUP +end +if DEFAULT_DNS_GROUP then + local domain_rules_str = "domain-rules /./ -nameserver " .. DEFAULT_DNS_GROUP + if DEFAULT_DNS_GROUP == REMOTE_GROUP then + domain_rules_str = domain_rules_str .. " -speed-check-mode none -d no -no-serve-expired" + domain_rules_str = domain_rules_str .. " -address " .. (NO_PROXY_IPV6 == "1" and "#6" or "-6") + elseif DEFAULT_DNS_GROUP == LOCAL_GROUP then + domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "") + end + table.insert(config_lines, domain_rules_str) +end + +local setflag = (NFTFLAG == "1") and "inet#passwall#" or "" +local set_type = (NFTFLAG == "1") and "-nftset" or "-ipset" + +--é¢„è®¾æŽ’åºæ ‡ç­¾(è¶Šå¾€åŽä¼˜å…ˆçº§è¶Šé«˜) +for i = 1, 8 do + table.insert(config_lines, "#--" .. i) +end + +--å±è”½åˆ—表 +local file_block_host = TMP_ACL_PATH .. "/block_host" +if USE_BLOCK_LIST == "1" and not fs.access(file_block_host) then + local block_domain, lookup_block_domain = {}, {} + local geosite_arg = "" + for line in io.lines(RULES_PATH .. "/block_host") do + if not line:find("#") and line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + geosite_arg = geosite_arg .. (geosite_arg ~= "" and "," or "") .. line + else + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(block_domain, line, lookup_block_domain) + end + end + end + if #block_domain > 0 then + local f_out = io.open(file_block_host, "w") + for i = 1, #block_domain do + f_out:write(block_domain[i] .. "\n") + end + f_out:close() + end + if USE_GEOVIEW == "1" and geosite_arg ~= "" and api.is_finded("geoview") then + if get_geosite(geosite_arg, file_block_host) == 0 then + log(" * è§£æž[å±è”½åˆ—表] Geosite 到å±è”½åŸŸå表(blocklist)完æˆ") + else + log(" * è§£æž[å±è”½åˆ—表] Geosite 到å±è”½åŸŸå表(blocklist)失败ï¼") + end + end +end +if USE_BLOCK_LIST == "1" and is_file_nonzero(file_block_host) then + local domain_set_name = "passwall-block" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_block_host), + string.format("domain-rules /domain-set:%s/ -a #", domain_set_name) + } + insert_array_after(config_lines, tmp_lines, "#--7") +end + +--始终用国内DNSè§£æžèŠ‚ç‚¹åŸŸå +local file_vpslist = TMP_ACL_PATH .. "/vpslist" +if not is_file_nonzero(file_vpslist) then + local f_out = io.open(file_vpslist, "w") + local written_domains = {} + local function process_address(address) + address = (address or ""):lower() + if api.vps_domain_exclude(address) then return end + if datatypes.hostname(address) and not written_domains[address] then + f_out:write(address .. "\n") + written_domains[address] = true + end + end + uci:foreach(appname, "nodes", function(t) + process_address(t.address) + process_address(t.download_address) + end) + uci:foreach(appname, "subscribe_list", function(t) --订阅链接 + local url, _ = api.get_domain_port_from_url(t.url or "") + if url and url ~= "" then + process_address(url) + end + end) + f_out:close() +end +if is_file_nonzero(file_vpslist) then + local domain_set_name = "passwall-vpslist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_vpslist) + } + local sets = { + "#4:" .. setflag .. "psw_vps", + "#6:" .. setflag .. "psw_vps6" + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",") + domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "") + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--8") + log(string.format(" - 节点列表中的域å(vpslist)使用分组:%s", LOCAL_GROUP or "默认")) +end + +--直连(白åå•)列表 +local file_direct_host = TMP_ACL_PATH .. "/direct_host" +if USE_DIRECT_LIST == "1" and not fs.access(file_direct_host) then + local direct_domain, lookup_direct_domain = {}, {} + local geosite_arg = "" + for line in io.lines(RULES_PATH .. "/direct_host") do + if not line:find("#") and line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + geosite_arg = geosite_arg .. (geosite_arg ~= "" and "," or "") .. line + else + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(direct_domain, line, lookup_direct_domain) + end + end + end + if #direct_domain > 0 then + local f_out = io.open(file_direct_host, "w") + for i = 1, #direct_domain do + f_out:write(direct_domain[i] .. "\n") + end + f_out:close() + end + if USE_GEOVIEW == "1" and geosite_arg ~= "" and api.is_finded("geoview") then + if get_geosite(geosite_arg, file_direct_host) == 0 then + log(" * è§£æž[直连列表] Geosite 到域å白åå•(whitelist)完æˆ") + else + log(" * è§£æž[直连列表] Geosite 到域å白åå•(whitelist)失败ï¼") + end + end +end +if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then + local domain_set_name = "passwall-directlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_direct_host) + } + local sets = { + "#4:" .. setflag .. "psw_white", + "#6:" .. setflag .. "psw_white6" + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",") + domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "") + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--6") + log(string.format(" - 域å白åå•(whitelist)使用分组:%s", LOCAL_GROUP or "默认")) +end + +--代ç†ï¼ˆé»‘åå•)列表 +local file_proxy_host = TMP_ACL_PATH .. "/proxy_host" +if USE_PROXY_LIST == "1" and not fs.access(file_proxy_host) then + local proxy_domain, lookup_proxy_domain = {}, {} + local geosite_arg = "" + for line in io.lines(RULES_PATH .. "/proxy_host") do + if not line:find("#") and line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + geosite_arg = geosite_arg .. (geosite_arg ~= "" and "," or "") .. line + else + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(proxy_domain, line, lookup_proxy_domain) + end + end + end + if #proxy_domain > 0 then + local f_out = io.open(file_proxy_host, "w") + for i = 1, #proxy_domain do + f_out:write(proxy_domain[i] .. "\n") + end + f_out:close() + end + if USE_GEOVIEW == "1" and geosite_arg ~= "" and api.is_finded("geoview") then + if get_geosite(geosite_arg, file_proxy_host) == 0 then + log(" * è§£æž[代ç†åˆ—表] Geosite 到代ç†åŸŸå表(blacklist)完æˆ") + else + log(" * è§£æž[代ç†åˆ—表] Geosite 到代ç†åŸŸå表(blacklist)失败ï¼") + end + end +end +if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then + local domain_set_name = "passwall-proxylist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_proxy_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + local sets = { + "#4:" .. setflag .. "psw_black" + } + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = REMOTE_FAKEDNS ~= "1" and (domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")) or domain_rules_str + else + domain_rules_str = domain_rules_str .. " -address -6" + table.insert(sets, "#6:" .. setflag .. "psw_black6") + domain_rules_str = REMOTE_FAKEDNS ~= "1" and (domain_rules_str .. " -d no " .. set_type .. " " .. table.concat(sets, ",")) or domain_rules_str + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--5") + log(string.format(" - 代ç†åŸŸå表(blacklist)使用分组:%s", REMOTE_GROUP or "默认")) +end + +--GFW列表 +if USE_GFW_LIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then + local domain_set_name = "passwall-gfwlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, RULES_PATH .. "/gfwlist") + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + local sets = { + "#4:" .. setflag .. "psw_gfw" + } + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = REMOTE_FAKEDNS ~= "1" and (domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")) or domain_rules_str + else + domain_rules_str = domain_rules_str .. " -address -6" + table.insert(sets, "#6:" .. setflag .. "psw_gfw6") + domain_rules_str = REMOTE_FAKEDNS ~= "1" and (domain_rules_str .. " -d no " .. set_type .. " " .. table.concat(sets, ",")) or domain_rules_str + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--1") + log(string.format(" - 防ç«å¢™åŸŸå表(gfwlist)使用分组:%s", REMOTE_GROUP or "默认")) +end + +--中国列表 +if CHN_LIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then + local domain_set_name = "passwall-chnlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, RULES_PATH .. "/chnlist") + } + + if CHN_LIST == "direct" then + local sets = { + "#4:" .. setflag .. "psw_chn", + "#6:" .. setflag .. "psw_chn6" + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",") + domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "") + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--2") + log(string.format(" - 中国域å表(chnroute)使用分组:%s", LOCAL_GROUP or "默认")) + end + + --å›žä¸­å›½æ¨¡å¼ + if CHN_LIST == "proxy" then + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + local sets = { + "#4:" .. setflag .. "psw_chn" + } + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = REMOTE_FAKEDNS ~= "1" and (domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")) or domain_rules_str + else + domain_rules_str = domain_rules_str .. " -address -6" + table.insert(sets, "#6:" .. setflag .. "psw_chn6") + domain_rules_str = REMOTE_FAKEDNS ~= "1" and (domain_rules_str .. " -d no " .. set_type .. " " .. table.concat(sets, ",")) or domain_rules_str + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--2") + log(string.format(" - 中国域å表(chnroute)使用分组:%s", REMOTE_GROUP or "默认")) + end +end + +--分æµè§„则 +if IS_SHUNT_NODE then + local white_domain, lookup_white_domain = {}, {} + local shunt_domain, lookup_shunt_domain = {}, {} + local file_white_host = FLAG_PATH .. "/shunt_direct_host" + local file_shunt_host = FLAG_PATH .. "/shunt_proxy_host" + local geosite_white_arg, geosite_shunt_arg = "", "" + + local t = uci:get_all(appname, TCP_NODE) + local default_node_id = t["default_node"] or "_direct" + uci:foreach(appname, "shunt_rules", function(s) + local _node_id = t[s[".name"]] + if _node_id and _node_id ~= "_blackhole" then + if _node_id == "_default" then + _node_id = default_node_id + end + + local domain_list = s.domain_list or "" + for line in string.gmatch(domain_list, "[^\r\n]+") do + if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("ext:") then + if line:find("geosite:") then + line = string.match(line, ":([^:]+)$") + if _node_id == "_direct" then + geosite_white_arg = geosite_white_arg .. (geosite_white_arg ~= "" and "," or "") .. line + else + geosite_shunt_arg = geosite_shunt_arg .. (geosite_shunt_arg ~= "" and "," or "") .. line + end + else + if line:find("domain:") or line:find("full:") then + line = string.match(line, ":([^:]+)$") + end + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + if _node_id == "_direct" then + insert_unique(white_domain, line, lookup_white_domain) + else + insert_unique(shunt_domain, line, lookup_shunt_domain) + end + end + end + end + end + + if _node_id ~= "_direct" then + log(string.format(" - Sing-Box/Xray分æµè§„则(%s)使用分组:%s", s.remarks, REMOTE_GROUP or "默认")) + end + end + end) + + if is_file_nonzero(file_white_host) == nil then + if #white_domain > 0 then + local f_out = io.open(file_white_host, "w") + for i = 1, #white_domain do + f_out:write(white_domain[i] .. "\n") + end + f_out:close() + end + end + + if is_file_nonzero(file_shunt_host) == nil then + if #shunt_domain > 0 then + local f_out = io.open(file_shunt_host, "w") + for i = 1, #shunt_domain do + f_out:write(shunt_domain[i] .. "\n") + end + f_out:close() + end + end + + if USE_GFW_LIST == "1" and CHN_LIST == "0" and USE_GEOVIEW == "1" and api.is_finded("geoview") then --ä»…GFW模å¼è§£æžgeosite + local return_white, return_shunt + if geosite_white_arg ~= "" then + return_white = get_geosite(geosite_white_arg, file_white_host) + end + if geosite_shunt_arg ~= "" then + return_shunt = get_geosite(geosite_shunt_arg, file_shunt_host) + end + if (return_white == nil or return_white == 0) and (return_shunt == nil or return_shunt == 0) then + log(" * è§£æž[分æµèŠ‚ç‚¹] Geosite 完æˆ") + else + log(" * è§£æž[分æµèŠ‚ç‚¹] Geosite 失败ï¼") + end + end + + if is_file_nonzero(file_white_host) then + local domain_set_name = "passwall-whitehost" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_white_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + if USE_DIRECT_LIST == "1" then + local sets = { + "#4:" .. setflag .. "psw_white", + "#6:" .. setflag .. "psw_white6" + } + domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",") + else + local sets = { + "#4:" .. setflag .. "psw_shunt", + "#6:" .. setflag .. "psw_shunt6" + } + domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",") + end + domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "") + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--4") + end + + if is_file_nonzero(file_shunt_host) then + local domain_set_name = "passwall-shuntlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_shunt_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + local sets = { + "#4:" .. setflag .. "psw_shunt" + } + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = (not only_global and REMOTE_FAKEDNS == "1") + and domain_rules_str + or (domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")) + else + domain_rules_str = domain_rules_str .. " -address -6" + table.insert(sets, "#6:" .. setflag .. "psw_shunt6") + domain_rules_str = (not only_global and REMOTE_FAKEDNS == "1") + and domain_rules_str + or (domain_rules_str .. " -d no " .. set_type .. " " .. table.concat(sets, ",")) + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--3") + end + +end + +if #config_lines > 0 then + local f_out = io.open(TMP_CONF_FILE, "w") + for i = 1, #config_lines do + line = config_lines[i] + if line ~= "" and not line:find("^#--") then + f_out:write(line .. "\n") + end + end + f_out:close() +end + +if DEFAULT_DNS_GROUP then + log(string.format(" - 默认 DNS 分组:%s", DEFAULT_DNS_GROUP)) +end + +fs.symlink(TMP_CONF_FILE, SMARTDNS_CONF) +sys.call(string.format('echo "conf-file %s" >> /etc/smartdns/custom.conf', string.gsub(SMARTDNS_CONF, appname, appname .. "*"))) +log(" - SmartDNS已作为Dnsmasq上游,如果你自行é…置了错误的DNSæµç¨‹ï¼Œå°†ä¼šå¯¼è‡´åŸŸå(直连/代ç†åŸŸå)分æµå¤±æ•ˆï¼ï¼ï¼") diff --git a/luci-app-passwall/root/usr/share/passwall/iptables.sh b/luci-app-passwall/root/usr/share/passwall/iptables.sh new file mode 100755 index 00000000..fe449ed1 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -0,0 +1,1539 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +MY_PATH=$DIR/iptables.sh +UTILS_PATH=$DIR/utils.sh +IPSET_LOCAL="psw_local" +IPSET_WAN="psw_wan" +IPSET_LAN="psw_lan" +IPSET_VPS="psw_vps" +IPSET_SHUNT="psw_shunt" +IPSET_GFW="psw_gfw" +IPSET_CHN="psw_chn" +IPSET_BLACK="psw_black" +IPSET_WHITE="psw_white" +IPSET_BLOCK="psw_block" + +IPSET_LOCAL6="psw_local6" +IPSET_WAN6="psw_wan6" +IPSET_LAN6="psw_lan6" +IPSET_VPS6="psw_vps6" +IPSET_SHUNT6="psw_shunt6" +IPSET_GFW6="psw_gfw6" +IPSET_CHN6="psw_chn6" +IPSET_BLACK6="psw_black6" +IPSET_WHITE6="psw_white6" +IPSET_BLOCK6="psw_block6" + +USE_SHUNT_TCP=0 +USE_SHUNT_UDP=0 + +# ASCII code for PSW1.Use whatever,just not the same. +FWMARK="0x50535731" + +ipt=$(command -v iptables-legacy || command -v iptables) +ip6t=$(command -v ip6tables-legacy || command -v ip6tables) + +ipt_n="$ipt -t nat -w" +ipt_m="$ipt -t mangle -w" +ip6t_n="$ip6t -t nat -w" +ip6t_m="$ip6t -t mangle -w" +[ -z "$ip6t" -o -z "$(lsmod | grep 'ip6table_nat')" ] && ip6t_n="eval #$ip6t_n" +[ -z "$ip6t" -o -z "$(lsmod | grep 'ip6table_mangle')" ] && ip6t_m="eval #$ip6t_m" +FWI=$(uci -q get firewall.passwall.path 2>/dev/null) +FAKE_IP="198.18.0.0/15" +FAKE_IP_6="fc00::/18" + +factor() { + if [ -z "$1" ] || [ -z "$2" ]; then + echo "" + elif [ "$1" == "1:65535" ]; then + echo "" + else + echo "$2 $1" + fi +} + +dst() { + echo "-m set $2 --match-set $1 dst" +} + +comment() { + local name=$(echo $1 | sed 's/ /_/g') + echo "-m comment --comment "${name}"" +} + +#解决端å£è¶…过15个ipt无效,支æŒå•端å£ã€ç«¯å£èŒƒå›´ +add_port_rules() { + local ipt_cmd="$1" + local port_list="$2" + local target="$3" + echo "$port_list" | grep -vq '[0-9]' && return + port_list=$(echo "$port_list" | tr -d ' ' | sed 's/-/:/g' | tr ',' '\n' | awk '!a[$0]++' | grep -v '^$') + [ -z "$port_list" ] && return + if echo "$port_list" | grep -q '^1:65535$'; then + eval "$ipt_cmd $target" + return + fi + local multiport_ports="" + local range_ports="" + local count=0 + local port + for port in $port_list; do + if echo "$port" | grep -q ':'; then + range_ports="$range_ports $port" + else + multiport_ports="$multiport_ports,$port" + count=$((count + 1)) + if [ "$count" -eq 15 ]; then + eval "$ipt_cmd -m multiport --dport ${multiport_ports#,} $target" + multiport_ports="" + count=0 + fi + fi + done + if [ -n "$multiport_ports" ]; then + eval "$ipt_cmd -m multiport --dport ${multiport_ports#,} $target" + fi + for port in $range_ports; do + eval "$ipt_cmd --dport $port $target" + done +} + +destroy_ipset() { + for i in "$@"; do + ipset -q -F $i + ipset -q -X $i + done +} + +insert_rule_before() { + [ $# -ge 3 ] || { + return 1 + } + local ipt_tmp="${1}"; shift + local chain="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$($ipt_tmp -n -L $chain --line-numbers 2>/dev/null | grep "$keyword" | head -n 1 | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + $ipt_tmp -A $chain $rule + else + if [ -z "${_index}" ]; then + _index=${default_index} + fi + $ipt_tmp -I $chain $_index $rule + fi +} + +insert_rule_after() { + [ $# -ge 3 ] || { + return 1 + } + local ipt_tmp="${1}"; shift + local chain="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$($ipt_tmp -n -L $chain --line-numbers 2>/dev/null | grep "$keyword" | awk 'END {print}' | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + $ipt_tmp -A $chain $rule + else + if [ -n "${_index}" ]; then + _index=$((_index + 1)) + else + _index=${default_index} + fi + $ipt_tmp -I $chain $_index $rule + fi +} + +RULE_LAST_INDEX() { + [ $# -ge 3 ] || { + echolog "索引列举方å¼ä¸æ­£ç¡®ï¼ˆiptables),终止执行ï¼" + return 1 + } + local ipt_tmp="${1}"; shift + local chain="${1}"; shift + local list="${1}"; shift + local default="${1:-0}"; shift + local _index=$($ipt_tmp -n -L $chain --line-numbers 2>/dev/null | grep "$list" | head -n 1 | awk '{print $1}') + echo "${_index:-${default}}" +} + +REDIRECT() { + local s="-j REDIRECT" + [ -n "$1" ] && { + local s="$s --to-ports $1" + [ "$2" == "TPROXY" ] && { + local mark="-m mark --mark ${FWMARK}" + s="${mark} -j TPROXY --on-port $1" + } + } + echo "$s" +} + +get_jump_ipt() { + case "$1" in + direct) + local s="" + local mark="-m mark ! --mark ${FWMARK}" + s="${mark} -j RETURN" + echo $s + ;; + proxy) + if [ -n "$2" ] && [ -n "$(echo $2 | grep "^-")" ]; then + echo "$2" + else + echo "$(REDIRECT $2 $3)" + fi + ;; + esac +} + +load_acl() { + ([ "$ENABLED_ACLS" == 1 ] || ([ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ])) && echolog " - 访问控制:" + [ "$ENABLED_ACLS" == 1 ] && { + acl_app + for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do + eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-) + + tcp_no_redir_ports=${tcp_no_redir_ports:-default} + udp_no_redir_ports=${udp_no_redir_ports:-default} + use_global_config=${use_global_config:-0} + tcp_proxy_drop_ports=${tcp_proxy_drop_ports:-default} + udp_proxy_drop_ports=${udp_proxy_drop_ports:-default} + tcp_redir_ports=${tcp_redir_ports:-default} + udp_redir_ports=${udp_redir_ports:-default} + use_direct_list=${use_direct_list:-1} + use_proxy_list=${use_proxy_list:-1} + use_block_list=${use_block_list:-1} + use_gfw_list=${use_gfw_list:-1} + chn_list=${chn_list:-direct} + tcp_proxy_mode=${tcp_proxy_mode:-proxy} + udp_proxy_mode=${udp_proxy_mode:-proxy} + [ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS + [ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS + [ "$tcp_proxy_drop_ports" = "default" ] && tcp_proxy_drop_ports=$TCP_PROXY_DROP_PORTS + [ "$udp_proxy_drop_ports" = "default" ] && udp_proxy_drop_ports=$UDP_PROXY_DROP_PORTS + [ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS + [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS + + [ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node") + [ -n "$(get_cache_var "ACL_${sid}_tcp_redir_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_redir_port") + [ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node") + [ -n "$(get_cache_var "ACL_${sid}_udp_redir_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_redir_port") + [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") + [ -n "$(get_cache_var "ACL_${sid}_fakedns")" ] && use_fakedns=$(get_cache_var "ACL_${sid}_fakedns") + [ -n "$tcp_node" ] && { + if is_socks_wrap "$tcp_node"; then + tcp_node_remark="Socks é…ç½®($(config_n_get ${tcp_node#Socks_} port) 端å£)" + else + tcp_node_remark=$(config_n_get $tcp_node remarks) + fi + } + [ -n "$udp_node" ] && { + if is_socks_wrap "$udp_node"; then + udp_node_remark="Socks é…ç½®($(config_n_get ${udp_node#Socks_} port) 端å£)" + else + udp_node_remark=$(config_n_get $udp_node remarks) + fi + } + + use_shunt_tcp=0 + use_shunt_udp=0 + [ -n "$tcp_node" ] && [ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1 + [ -n "$udp_node" ] && [ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1 + + [ "${use_global_config}" = "1" ] && { + if is_socks_wrap "$TCP_NODE"; then + tcp_node_remark="Socks é…ç½®($(config_n_get ${TCP_NODE#Socks_} port) 端å£)" + else + tcp_node_remark=$(config_n_get $TCP_NODE remarks) + fi + if is_socks_wrap "$UDP_NODE"; then + udp_node_remark="Socks é…ç½®($(config_n_get ${UDP_NODE#Socks_} port) 端å£)" + else + udp_node_remark=$(config_n_get $UDP_NODE remarks) + fi + use_direct_list=${USE_DIRECT_LIST} + use_proxy_list=${USE_PROXY_LIST} + use_block_list=${USE_BLOCK_LIST} + use_gfw_list=${USE_GFW_LIST} + chn_list=${CHN_LIST} + tcp_proxy_mode=${TCP_PROXY_MODE} + udp_proxy_mode=${UDP_PROXY_MODE} + use_shunt_tcp=${USE_SHUNT_TCP} + use_shunt_udp=${USE_SHUNT_UDP} + dns_redirect_port=${DNS_REDIRECT_PORT} + black_set_name=${IPSET_BLACK} + black6_set_name=${IPSET_BLACK6} + gfw_set_name=${IPSET_GFW} + gfw6_set_name=${IPSET_GFW6} + shunt_set_name=${IPSET_SHUNT} + shunt6_set_name=${IPSET_SHUNT6} + use_fakedns=${USE_FAKEDNS} + } + + _acl_list=${TMP_ACL_PATH}/${sid}/source_list + + for i in $(cat $_acl_list); do + local _ipt_source _ipv4 + local msg + if [ -n "${interface}" ]; then + local gateway device + network_get_gateway gateway "${interface}" + network_get_device device "${interface}" + # network_get_device returns empty for non-UP interfaces (e.g. auto='0'). + # Try ubus directly, then check if the name is a kernel device. + [ -z "${device}" ] && device=$(ubus call "network.interface.${interface}" status 2>/dev/null | jsonfilter -e '@.device' 2>/dev/null) + [ -z "${device}" ] && [ -d "/sys/class/net/${interface}" ] && device="${interface}" + [ -z "${device}" ] && device="${interface}" + _ipt_source="-i ${device} " + msg="æºæŽ¥å£ã€${device}】," + else + msg="æºæŽ¥å£ã€æ‰€æœ‰ã€‘," + fi + if [ -n "$(echo ${i} | grep '^iprange:')" ]; then + _iprange=$(echo ${i} | sed 's#iprange:##g') + _ipt_source=$(factor ${_iprange} "${_ipt_source}-m iprange --src-range") + msg="${msg}IP rangeã€${_iprange}】," + _ipv4="1" + unset _iprange + elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then + _ipset=$(echo ${i} | sed 's#ipset:##g') + msg="${msg}IPsetã€${_ipset}】," + ipset -q list ${_ipset} >/dev/null + if [ $? -eq 0 ]; then + _ipt_source="${_ipt_source}-m set --match-set ${_ipset} src" + unset _ipset + else + echolog " - ã€$remarks】,${msg}ä¸å­˜åœ¨ï¼Œå¿½ç•¥ã€‚" + unset _ipset + continue + fi + elif [ -n "$(echo ${i} | grep '^ip:')" ]; then + _ip=$(echo ${i} | sed 's#ip:##g') + _ipt_source=$(factor ${_ip} "${_ipt_source}-s") + msg="${msg}IPã€${_ip}】," + _ipv4="1" + unset _ip + elif [ -n "$(echo ${i} | grep '^mac:')" ]; then + _mac=$(echo ${i} | sed 's#mac:##g') + _ipt_source=$(factor ${_mac} "${_ipt_source}-m mac --mac-source") + msg="${msg}MACã€${_mac}】," + unset _mac + elif [ -n "$(echo ${i} | grep '^any')" ]; then + msg="${msg}所有设备," + else + continue + fi + msg="ã€$remarks】,${msg}" + + ipt_tmp=$ipt_n + [ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m + + [ "$tcp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$tcp_no_redir_ports"; then + [ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN" 2>/dev/null + add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN" + echolog " - ${msg}ä¸ä»£ç† TCP 端å£[${tcp_no_redir_ports}]" + else + #ç»“æŸæ—¶ä¼šreturn,无需加多余的规则。 + unset tcp_port + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ TCP 端å£" + fi + } + + [ "$udp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$udp_no_redir_ports"; then + [ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" 2>/dev/null + add_port_rules "$ipt_m -A PSW $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" + echolog " - ${msg}ä¸ä»£ç† UDP 端å£[${udp_no_redir_ports}]" + else + #ç»“æŸæ—¶ä¼šreturn,无需加多余的规则。 + unset udp_port + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ UDP 端å£" + fi + } + + local dns_redirect + [ $(config_t_get global dns_redirect "1") = "1" ] && dns_redirect=53 + if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then + [ "${use_proxy_list}" = "1" ] && { + [ "${use_global_config}" = "0" ] && { + black_set_name="psw_${sid}_black" + black6_set_name="psw_${sid}_black6" + ipset -! create $black_set_name nethash maxelem 1048576 timeout 172800 + ipset -! create $black6_set_name nethash family inet6 maxelem 1048576 timeout 172800 + } + } + [ "${use_gfw_list}" = "1" ] && { + [ "${use_global_config}" = "0" ] && { + gfw_set_name="psw_${sid}_gfw" + gfw6_set_name="psw_${sid}_gfw6" + ipset -! create $gfw_set_name nethash maxelem 1048576 timeout 172800 + ipset -! create $gfw6_set_name nethash family inet6 maxelem 1048576 timeout 172800 + } + } + [ "${use_shunt_tcp}" = "1" -o "${use_shunt_udp}" = "1" ] && { + [ "${use_global_config}" = "0" ] && { + shunt_set_name="psw_${sid}_shunt" + shunt6_set_name="psw_${sid}_shunt6" + ipset -! create $shunt_set_name nethash maxelem 1048576 timeout 172800 + ipset -! create $shunt6_set_name nethash family inet6 maxelem 1048576 timeout 172800 + } + } + [ -n "${dns_redirect_port}" ] && dns_redirect=${dns_redirect_port} + else + [ -n "${DIRECT_DNSMASQ_PORT}" ] && dns_redirect=${DIRECT_DNSMASQ_PORT} + fi + if [ -n "${dns_redirect}" ]; then + $ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN + [ "$_ipv4" != "1" ] && $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + $ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN + [ "$_ipv4" != "1" ] && $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + $ipt_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect} + [ "$_ipv4" != "1" ] && $ip6t_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect} 2>/dev/null + $ipt_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect} + [ "$_ipv4" != "1" ] && $ip6t_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect} 2>/dev/null + [ -z "$(get_cache_var "ACL_${sid}_tcp_default")" ] && echolog " - ${msg}使用与全局é…ç½®ä¸ç›¸åŒèŠ‚ç‚¹ï¼Œå·²å°†DNS强制é‡å®šå‘到专用 DNS æœåŠ¡å™¨ã€‚" + fi + + [ -n "$tcp_port" -o -n "$udp_port" ] && { + [ "${use_block_list}" = "1" ] && $ipt_m -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_BLOCK) -j DROP + [ "${use_direct_list}" = "1" ] && $ipt_tmp -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_WHITE) -j RETURN + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_block_list}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_BLOCK6) -j DROP 2>/dev/null + [ "${use_direct_list}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_WHITE6) -j RETURN 2>/dev/null + } + + [ "$tcp_proxy_drop_ports" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "-d $FAKE_IP_6 -j DROP" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $black6_set_name) -j DROP" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $gfw6_set_name) -j DROP" 2>/dev/null + [ "${chn_list}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $IPSET_CHN6) $(get_jump_ipt ${chn_list} "-j DROP")" 2>/dev/null + [ "${use_shunt_tcp}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $shunt6_set_name) -j DROP" 2>/dev/null + [ "${tcp_proxy_mode}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "-j DROP" 2>/dev/null + } + [ "${use_fakedns}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "-d $FAKE_IP -j DROP" + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $black_set_name) -j DROP" + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $gfw_set_name) -j DROP" + [ "${chn_list}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $IPSET_CHN) $(get_jump_ipt ${chn_list} "-j DROP")" + [ "${use_shunt_tcp}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $shunt_set_name) -j DROP" + [ "${tcp_proxy_mode}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "-j DROP" + echolog " - ${msg}å±è”½ä»£ç† TCP 端å£[${tcp_proxy_drop_ports}]" + } + + [ "$udp_proxy_drop_ports" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "-d $FAKE_IP_6 -j DROP" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $black6_set_name) -j DROP" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $gfw6_set_name) -j DROP" 2>/dev/null + [ "${chn_list}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $IPSET_CHN6) $(get_jump_ipt ${chn_list} "-j DROP")" 2>/dev/null + [ "${use_shunt_udp}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $shunt6_set_name) -j DROP" 2>/dev/null + [ "${udp_proxy_mode}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "-j DROP" 2>/dev/null + } + [ "${use_fakedns}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "-d $FAKE_IP -j DROP" + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $black_set_name) -j DROP" + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $gfw_set_name) -j DROP" + [ "${chn_list}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $IPSET_CHN) $(get_jump_ipt ${chn_list} "-j DROP")" + [ "${use_shunt_udp}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $shunt_set_name) -j DROP" + [ "${udp_proxy_mode}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "-j DROP" + echolog " - ${msg}å±è”½ä»£ç† UDP 端å£[${udp_proxy_drop_ports}]" + } + } + + [ -n "$tcp_port" ] && { + if [ -n "${tcp_proxy_mode}" ]; then + msg2="${msg}使用 TCP 节点[$tcp_node_remark]" + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${tcp_port})" + ipt_tmp=$ipt_m + ipt_j="-j PSW_RULE" + else + msg2="${msg2}(REDIRECT:${tcp_port})" + ipt_j="$(REDIRECT $tcp_port)" + fi + + [ "$accept_icmp" = "1" ] && { + [ "${use_fakedns}" = "1" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} -d $FAKE_IP $(REDIRECT) + [ "${use_proxy_list}" = "1" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} $(dst $black_set_name) $(REDIRECT) + [ "${use_gfw_list}" = "1" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} $(dst $gfw_set_name) $(REDIRECT) + [ "${chn_list}" != "0" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} $(dst $IPSET_CHN) $(get_jump_ipt ${chn_list}) + [ "${use_shunt_tcp}" = "1" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} $(dst $shunt_set_name) $(REDIRECT) + [ "${tcp_proxy_mode}" != "disable" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} $(REDIRECT) + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} -d $FAKE_IP_6 $(REDIRECT) 2>/dev/null + [ "${use_proxy_list}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $black6_set_name) $(REDIRECT) 2>/dev/null + [ "${use_gfw_list}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $gfw6_set_name) $(REDIRECT) 2>/dev/null + [ "${chn_list}" != "0" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $IPSET_CHN6) $(get_jump_ipt ${chn_list}) 2>/dev/null + [ "${use_shunt_tcp}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $shunt6_set_name) $(REDIRECT) 2>/dev/null + [ "${tcp_proxy_mode}" != "disable" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(REDIRECT) 2>/dev/null + } + + [ "${use_fakedns}" = "1" ] && $ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP ${ipt_j} + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $black_set_name) ${ipt_j}" + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $gfw_set_name) ${ipt_j}" + [ "${chn_list}" != "0" ] && add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $IPSET_CHN) $(get_jump_ipt ${chn_list} "${ipt_j}")" + [ "${use_shunt_tcp}" = "1" ] && add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $shunt_set_name) ${ipt_j}" + [ "${tcp_proxy_mode}" != "disable" ] && add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "${ipt_j}" + [ -n "${is_tproxy}" ] && $ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $tcp_port TPROXY) + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP_6 -j PSW_RULE 2>/dev/null + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $black6_set_name) -j PSW_RULE" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $gfw6_set_name) -j PSW_RULE" 2>/dev/null + [ "${chn_list}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $IPSET_CHN6) $(get_jump_ipt ${chn_list} "-j PSW_RULE")" 2>/dev/null + [ "${use_shunt_tcp}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $shunt6_set_name) -j PSW_RULE" 2>/dev/null + [ "${tcp_proxy_mode}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "-j PSW_RULE" 2>/dev/null + $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $tcp_port TPROXY) 2>/dev/null + } + else + msg2="${msg}ä¸ä»£ç† TCP" + fi + echolog " - ${msg2}" + } + + [ "$_ipv4" != "1" ] && $ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN 2>/dev/null + $ipt_tmp -A PSW $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN + + [ -n "$udp_port" ] && { + if [ -n "${udp_proxy_mode}" ]; then + msg2="${msg}使用 UDP 节点[$udp_node_remark]" + msg2="${msg2}(TPROXY:${udp_port})" + + [ "${use_fakedns}" = "1" ] && $ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} -d $FAKE_IP -j PSW_RULE + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $black_set_name) -j PSW_RULE" + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $gfw_set_name) -j PSW_RULE" + [ "${chn_list}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $IPSET_CHN) $(get_jump_ipt ${chn_list} "-j PSW_RULE")" + [ "${use_shunt_udp}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $shunt_set_name) -j PSW_RULE" + [ "${udp_proxy_mode}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "-j PSW_RULE" + $ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} $(REDIRECT $udp_port TPROXY) + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} -d $FAKE_IP_6 -j PSW_RULE 2>/dev/null + [ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $black6_set_name) -j PSW_RULE" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $gfw6_set_name) -j PSW_RULE" 2>/dev/null + [ "${chn_list}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $IPSET_CHN6) $(get_jump_ipt ${chn_list} "-j PSW_RULE")" 2>/dev/null + [ "${use_shunt_udp}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $shunt6_set_name) -j PSW_RULE" 2>/dev/null + [ "${udp_proxy_mode}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "-j PSW_RULE" 2>/dev/null + $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} $(REDIRECT $udp_port TPROXY) 2>/dev/null + } + else + msg2="${msg}ä¸ä»£ç† UDP" + fi + echolog " - ${msg2}" + } + [ "$_ipv4" != "1" ] && $ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} -p udp -j RETURN 2>/dev/null + $ipt_m -A PSW $(comment "$remarks") ${_ipt_source} -p udp -j RETURN + unset ipt_tmp ipt_j _ipt_source msg msg2 _ipv4 + done + unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface + unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp dns_redirect use_fakedns + done + } + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && { + msg="ã€é»˜è®¤ã€‘," + local ipt_tmp=$ipt_n + [ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m + + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† TCP 端å£[${TCP_NO_REDIR_PORTS}]" + else + unset TCP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ TCP 端å£" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† UDP 端å£[${UDP_NO_REDIR_PORTS}]" + else + unset UDP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ UDP 端å£" + fi + } + + local DNS_REDIRECT + [ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53 + if ([ -n "$TCP_NODE" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${UDP_PROXY_MODE}" ]); then + [ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT} + else + [ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT} + fi + + if [ -n "${DNS_REDIRECT}" ]; then + $ipt_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN + $ip6t_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN 2>/dev/null + $ipt_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN + $ip6t_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN 2>/dev/null + $ipt_n -A PSW_DNS $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} + $ip6t_n -A PSW_DNS $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} 2>/dev/null + $ipt_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} + $ip6t_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} 2>/dev/null + fi + + [ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && { + [ "${USE_BLOCK_LIST}" = "1" ] && $ipt_m -A PSW $(comment "默认") $(dst $IPSET_BLOCK) -j DROP + [ "${USE_DIRECT_LIST}" = "1" ] && $ipt_tmp -A PSW $(comment "默认") $(dst $IPSET_WHITE) -j RETURN + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_BLOCK_LIST}" = "1" ] && $ip6t_m -A PSW $(comment "默认") $(dst $IPSET_BLOCK6) -j DROP 2>/dev/null + [ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_m -A PSW $(comment "默认") $(dst $IPSET_WHITE6) -j RETURN 2>/dev/null + } + + [ "$TCP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP_6 -j DROP" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK6) -j DROP" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW6) -j DROP" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j DROP")" + [ "${USE_SHUNT_TCP}" = "1" ] && $ip6t_m -A PSW $(comment "默认") -p tcp $TCP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j DROP" + [ "${TCP_PROXY_MODE}" != "disable" ] && $ip6t_m -A PSW $(comment "默认") -p tcp $TCP_PROXY_DROP_PORTS "-j DROP" + } + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j DROP" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j DROP" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j DROP")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS $(dst $IPSET_SHUNT) "-j DROP" + [ "${TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-j DROP" + echolog " - ${msg}å±è”½ä»£ç† TCP 端å£[${TCP_PROXY_DROP_PORTS}]" + } + + [ "$UDP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP_6 -j DROP" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK6) -j DROP" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_GFW6) -j DROP" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j DROP")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j DROP" + [ "${UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-j DROP" + } + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j DROP" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j DROP" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j DROP")" + [ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT) -j DROP" + [ "${UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-j DROP" + echolog " - ${msg}å±è”½ä»£ç† UDP 端å£[${UDP_PROXY_DROP_PORTS}]" + } + } + + # 加载TCPé»˜è®¤ä»£ç†æ¨¡å¼ + if [ -n "${TCP_PROXY_MODE}" ]; then + [ -n "$TCP_NODE" ] && { + if is_socks_wrap "$TCP_NODE"; then + msg2="${msg}使用 TCP 节点[Socks é…ç½®($(config_n_get ${TCP_NODE#Socks_} port) 端å£)]" + else + msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]" + fi + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})" + ipt_j="-j PSW_RULE" + else + msg2="${msg2}(REDIRECT:${TCP_REDIR_PORT})" + ipt_j="$(REDIRECT $TCP_REDIR_PORT)" + fi + + [ "$accept_icmp" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ipt_n -A PSW $(comment "默认") -p icmp -d $FAKE_IP $(REDIRECT) + [ "${USE_PROXY_LIST}" = "1" ] && $ipt_n -A PSW $(comment "默认") -p icmp $(dst $IPSET_BLACK) $(REDIRECT) + [ "${USE_GFW_LIST}" = "1" ] && $ipt_n -A PSW $(comment "默认") -p icmp $(dst $IPSET_GFW) $(REDIRECT) + [ "${CHN_LIST}" != "0" ] && $ipt_n -A PSW $(comment "默认") -p icmp $(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST}) + [ "${USE_SHUNT_TCP}" = "1" ] && $ipt_n -A PSW $(comment "默认") -p icmp $(dst $IPSET_SHUNT) $(REDIRECT) + [ "${TCP_PROXY_MODE}" != "disable" ] && $ipt_n -A PSW $(comment "默认") -p icmp $(REDIRECT) + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT) + [ "${USE_PROXY_LIST}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(dst $IPSET_BLACK6) $(REDIRECT) + [ "${USE_GFW_LIST}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(dst $IPSET_GFW6) $(REDIRECT) + [ "${CHN_LIST}" != "0" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST}) + [ "${USE_SHUNT_TCP}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(dst $IPSET_SHUNT6) $(REDIRECT) + [ "${TCP_PROXY_MODE}" != "disable" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(REDIRECT) + } + + [ "${USE_FAKEDNS}" = "1" ] && $ipt_tmp -A PSW $(comment "默认") -p tcp -d $FAKE_IP ${ipt_j} + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_BLACK) ${ipt_j}" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_GFW) ${ipt_j}" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "${ipt_j}")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_SHUNT) ${ipt_j}" + [ "${TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "${ipt_j}" + [ -n "${is_tproxy}" ]&& $ipt_tmp -A PSW $(comment "默认") -p tcp $(REDIRECT $TCP_REDIR_PORT TPROXY) + + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW $(comment "默认") -p tcp -d $FAKE_IP_6 -j PSW_RULE + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_GFW6) -j PSW_RULE" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j PSW_RULE")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_SHUNT6) -j PSW_RULE" + [ "${TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "-j PSW_RULE" + $ip6t_m -A PSW $(comment "默认") -p tcp $(REDIRECT $TCP_REDIR_PORT TPROXY) + } + + echolog " - ${msg2}" + } + fi + $ipt_n -A PSW $(comment "默认") -p tcp -j RETURN + $ipt_m -A PSW $(comment "默认") -p tcp -j RETURN + $ip6t_m -A PSW $(comment "默认") -p tcp -j RETURN + + # 加载UDPé»˜è®¤ä»£ç†æ¨¡å¼ + if [ -n "${UDP_PROXY_MODE}" ]; then + [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ] && { + if is_socks_wrap "$UDP_NODE"; then + msg2="${msg}使用 UDP 节点[Socks é…ç½®($(config_n_get ${UDP_NODE#Socks_} port) 端å£)](TPROXY:${UDP_REDIR_PORT})" + else + msg2="${msg}使用 UDP 节点[$(config_n_get $UDP_NODE remarks)](TPROXY:${UDP_REDIR_PORT})" + fi + + [ "${USE_FAKEDNS}" = "1" ] && $ipt_m -A PSW $(comment "默认") -p udp -d $FAKE_IP -j PSW_RULE + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_BLACK) -j PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_GFW) -j PSW_RULE" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j PSW_RULE")" + [ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_SHUNT) -j PSW_RULE" + [ "${UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "-j PSW_RULE" + $ipt_m -A PSW $(comment "默认") -p udp $(REDIRECT $UDP_REDIR_PORT TPROXY) + + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW $(comment "默认") -p udp -d $FAKE_IP_6 -j PSW_RULE + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_GFW6) -j PSW_RULE" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j PSW_RULE")" + [ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_SHUNT6) -j PSW_RULE" + [ "${UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "-j PSW_RULE" + $ip6t_m -A PSW $(comment "默认") -p udp $(REDIRECT $UDP_REDIR_PORT TPROXY) + } + + echolog " - ${msg2}" + } + fi + $ipt_m -A PSW $(comment "默认") -p udp -j RETURN + $ip6t_m -A PSW $(comment "默认") -p udp -j RETURN + } +} + +filter_haproxy() { + for item in ${haproxy_items}; do + local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1) + ipset -q add $IPSET_VPS $ip + done + echolog " - [$?]加入负载å‡è¡¡çš„节点到ipset[$IPSET_VPS]直连完æˆ" +} + +filter_vpsip() { + local EXCLUDE_VPSIP="^(127\.0\.0\.1|1\.1\.1\.1|1\.1\.1\.2|8\.8\.8\.8|8\.8\.4\.4|9\.9\.9\.9)$" + uci show $CONFIG | grep -E "(\.address=|\.download_address=)" | cut -d "'" -f 2 | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}$" | grep -Ev "$EXCLUDE_VPSIP" | sed "s/^/add $IPSET_VPS /" | awk '1; END{print "COMMIT"}' | ipset -! -R + echolog " - [$?]加入所有IPv4节点到ipset[$IPSET_VPS]直连完æˆ" + uci show $CONFIG | grep -E "(\.address=|\.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed "s/^/add $IPSET_VPS6 /" | awk '1; END{print "COMMIT"}' | ipset -! -R + echolog " - [$?]加入所有IPv6节点到ipset[$IPSET_VPS6]直连完æˆ" + #订阅方å¼ä¸ºç›´è¿žæ—¶ + get_subscribe_host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -Ev "$EXCLUDE_VPSIP" | sed "s/^/add $IPSET_VPS /" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + get_subscribe_host | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed "s/^/add $IPSET_VPS6 /" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R +} + +filter_server_port() { + local address="$1" + local port=$(echo "$2" | tr '-' ':' | tr -d ' ') + local stream=$(echo "$3" | tr 'A-Z' 'a-z') + local ipt_tmp="$ipt_n" _is_tproxy _ipt_cmd _ver multi_ports p ports + [ "$(config_t_get global_forwarding tcp_proxy_way redirect)" = "tproxy" ] && _is_tproxy="TPROXY" + [ "$stream" = "udp" ] && _is_tproxy="TPROXY" + [ -n "$_is_tproxy" ] && ipt_tmp="$ipt_m" + for _ver in 4 6; do + [ "$_ver" = "4" ] && _ipt_cmd="$ipt_tmp" + [ "$_ver" = "6" ] && _ipt_cmd="$ip6t_m" + multi_ports="" + for p in $(echo "$port" | tr ',' ' '); do + case "$p" in + *:* ) + $_ipt_cmd -n -L PSW_OUTPUT 2>/dev/null | grep -q "${address}:${p}:${stream}" || \ + $_ipt_cmd -I PSW_OUTPUT $(comment "${address}:${p}:${stream}") -p "$stream" -d "$address" --dport "$p" -j RETURN 2>/dev/null + ;; + * ) + multi_ports="${multi_ports},$p" + ;; + esac + done + if [ -n "$multi_ports" ]; then + ports=$(printf "%s\n" "${multi_ports#,}" | tr ',' '\n' | sort -n | tr '\n' ',' | sed 's/,$//') + $_ipt_cmd -n -L PSW_OUTPUT 2>/dev/null | grep -q "${address}:${ports}:${stream}" || \ + $_ipt_cmd -I PSW_OUTPUT $(comment "${address}:${ports}:${stream}") -p "$stream" -d "$address" -m multiport --dports "$ports" -j RETURN 2>/dev/null + fi + done +} + +filter_node() { + local node="$1" stream="$2" + [ -z "$node" ] && return 1 + local address=$(config_n_get "$node" address) + local port=$(config_n_get "$node" port) + local hop=$(config_n_get "$node" hysteria2_hop) + [ -n "$hop" ] && port="${port:+$port,}$hop" + [ -z "$address" -o -z "$port" ] && return 1 + filter_server_port "$address" "$port" "$stream" +} + +filter_direct_node_list() { + [ ! -s "$TMP_PATH/direct_node_list" ] && return + awk '!seen[$0]++' "$TMP_PATH/direct_node_list" | while read -r _node_id; do + filter_node "$_node_id" TCP + filter_node "$_node_id" UDP + unset _node_id + done +} + +update_wan_sets() { + local log=$1 + + [ -z "$(command -v get_wan_ips)" ] && . "$UTILS_PATH" + + local WAN_IP=$(get_wan_ips ip4) + [ -n "$WAN_IP" ] && { + ipset -F "$IPSET_WAN" + for wan_ip in $WAN_IP; do + ipset -! add "$IPSET_WAN" "$wan_ip" + done + [ "$log" = "log" ] && { + local wan_ip + for wan_ip in $WAN_IP; do + echolog " - [$?]加入WAN IPv4到ipset[$IPSET_WAN]:${wan_ip}" + done + } + } + + local WAN6_IP=$(get_wan_ips ip6) + [ -n "$WAN6_IP" ] && { + ipset -F "$IPSET_WAN6" + for wan6_ip in $WAN6_IP; do + ipset -! add "$IPSET_WAN6" "$wan6_ip" + done + [ "$log" = "log" ] && { + local wan6_ip + for wan6_ip in $WAN6_IP; do + echolog " - [$?]加入WAN IPv6到ipset[$IPSET_WAN6]:${wan6_ip}" + done + } + } +} + +add_firewall_rule() { + echolog "开始加载 iptables 防ç«å¢™è§„则..." + ipset -! create $IPSET_LOCAL nethash maxelem 1048576 + ipset -! create $IPSET_WAN nethash maxelem 1048576 + ipset -! create $IPSET_LAN nethash maxelem 1048576 + ipset -! create $IPSET_VPS nethash maxelem 1048576 + ipset -! create $IPSET_SHUNT nethash maxelem 1048576 timeout 172800 + ipset -! create $IPSET_GFW nethash maxelem 1048576 timeout 172800 + ipset -! create $IPSET_CHN nethash maxelem 1048576 timeout 172800 + ipset -! create $IPSET_BLACK nethash maxelem 1048576 timeout 172800 + ipset -! create $IPSET_WHITE nethash maxelem 1048576 timeout 172800 + ipset -! create $IPSET_BLOCK nethash maxelem 1048576 timeout 172800 + + ipset -! create $IPSET_LOCAL6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_WAN6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_LAN6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_VPS6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_SHUNT6 nethash family inet6 maxelem 1048576 timeout 172800 + ipset -! create $IPSET_GFW6 nethash family inet6 maxelem 1048576 timeout 172800 + ipset -! create $IPSET_CHN6 nethash family inet6 maxelem 1048576 timeout 172800 + ipset -! create $IPSET_BLACK6 nethash family inet6 maxelem 1048576 timeout 172800 + ipset -! create $IPSET_WHITE6 nethash family inet6 maxelem 1048576 timeout 172800 + ipset -! create $IPSET_BLOCK6 nethash family inet6 maxelem 1048576 timeout 172800 + + cat $RULES_PATH/chnroute | tr -s '\n' | grep -v "^#" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_CHN &/g" -e "s/$/ timeout 0/g" | ipset -! -R + cat $RULES_PATH/chnroute6 | tr -s '\n' | grep -v "^#" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_CHN6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + + #导入规则列表ã€åˆ†æµè§„则中的IP列表 + local USE_SHUNT_NODE=0 + local USE_PROXY_LIST_ALL=${USE_PROXY_LIST} + local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST} + local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST} + local _TCP_NODE=$(config_t_get global tcp_node) + local _UDP_NODE=$(config_t_get global udp_node) + local USE_GEOVIEW=$(config_t_get global_rules enable_geoview) + [ -z "$(first_type $(config_t_get global_app geoview_file) geoview)" ] && USE_GEOVIEW=0 + + [ -n "$_TCP_NODE" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=1 && USE_SHUNT_NODE=1 + [ -n "$_UDP_NODE" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1 + [ "$_UDP_NODE" = "tcp" ] && USE_SHUNT_UDP=$USE_SHUNT_TCP + + for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + [ "$(config_n_get $acl_section enabled)" != "1" ] && continue + [ "$(config_n_get $acl_section use_global_config 0)" != "1" ] && { + [ "$(config_n_get $acl_section use_direct_list 1)" = "1" ] && USE_PROXY_LIST_ALL=1 + [ "$(config_n_get $acl_section use_proxy_list 1)" = "1" ] && USE_DIRECT_LIST_ALL=1 + [ "$(config_n_get $acl_section use_block_list 1)" = "1" ] && USE_BLOCK_LIST_ALL=1 + } + for _node in $(config_n_get $acl_section tcp_node) $(config_n_get $acl_section udp_node); do + local node_protocol=$(config_n_get $_node protocol) + [ "$node_protocol" = "_shunt" ] && { USE_SHUNT_NODE=1; break; } + done + done + + #直连列表 + [ "$USE_DIRECT_LIST_ALL" = "1" ] && { + cat $RULES_PATH/direct_ip | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_WHITE &/g" -e "s/$/ timeout 0/g" | ipset -! -R + cat $RULES_PATH/direct_ip | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_WHITE6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + [ "$USE_GEOVIEW" = "1" ] && { + local GEOIP_CODE=$(cat $RULES_PATH/direct_ip | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_WHITE &/g" -e "s/$/ timeout 0/g" | ipset -! -R + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_WHITE6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + echolog " - [$?]è§£æžå¹¶åŠ å…¥[直连列表] GeoIP 到 IPSET 完æˆ" + fi + } + } + + #代ç†åˆ—表 + [ "$USE_PROXY_LIST_ALL" = "1" ] && { + cat $RULES_PATH/proxy_ip | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_BLACK &/g" -e "s/$/ timeout 0/g" | ipset -! -R + cat $RULES_PATH/proxy_ip | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_BLACK6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + [ "$USE_GEOVIEW" = "1" ] && { + local GEOIP_CODE=$(cat $RULES_PATH/proxy_ip | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_BLACK &/g" -e "s/$/ timeout 0/g" | ipset -! -R + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_BLACK6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + echolog " - [$?]è§£æžå¹¶åŠ å…¥[代ç†åˆ—表] GeoIP 到 IPSET 完æˆ" + fi + } + } + + #å±è”½åˆ—表 + [ "$USE_BLOCK_LIST_ALL" = "1" ] && { + cat $RULES_PATH/block_ip | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_BLOCK &/g" -e "s/$/ timeout 0/g" | ipset -! -R + cat $RULES_PATH/block_ip | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_BLOCK6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + [ "$USE_GEOVIEW" = "1" ] && { + local GEOIP_CODE=$(cat $RULES_PATH/block_ip | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_BLOCK &/g" -e "s/$/ timeout 0/g" | ipset -! -R + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_BLOCK6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + echolog " - [$?]è§£æžå¹¶åŠ å…¥[å±è”½åˆ—表] GeoIP 到 IPSET 完æˆ" + fi + } + } + + #分æµåˆ—表 + [ "$USE_SHUNT_NODE" = "1" ] && { + local GEOIP_CODE="" + local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') + for shunt_id in $shunt_ids; do + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_SHUNT &/g" -e "s/$/ timeout 0/g" | ipset -! -R + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | grep -v "^#" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_SHUNT6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + [ "$USE_GEOVIEW" = "1" ] && { + local geoip_code=$(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$geoip_code" ] && GEOIP_CODE="${GEOIP_CODE:+$GEOIP_CODE,}$geoip_code" + } + done + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $IPSET_SHUNT &/g" -e "s/$/ timeout 0/g" | ipset -! -R + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_SHUNT6 &/g" -e "s/$/ timeout 0/g" | ipset -! -R + echolog " - [$?]è§£æžå¹¶åŠ å…¥[分æµèŠ‚ç‚¹] GeoIP 到 IPSET 完æˆ" + fi + } + + get_local_ips ip4 | sed "s/^/add $IPSET_LOCAL /" | ipset -! -R + get_local_ips ip6 | sed "s/^/add $IPSET_LOCAL6 /" | ipset -! -R + + #局域网IP列表 + ipset -! -R <<-EOF + $(gen_lanlist | sed -e "s/^/add $IPSET_LAN /") + EOF + + ipset -! -R <<-EOF + $(gen_lanlist_6 | sed -e "s/^/add $IPSET_LAN6 /") + EOF + + # 忽略特殊IP段 + local lan_ifname lan_ip + lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname) + [ -n "$lan_ifname" ] && { + lan_ip=$(ip address show $lan_ifname | grep -w "inet" | awk '{print $2}') + lan_ip6=$(ip address show $lan_ifname | grep -w "inet6" | awk '{print $2}') + #echolog "本机IPv4网段互访直连:${lan_ip}" + #echolog "本机IPv6网段互访直连:${lan_ip6}" + + [ -n "$lan_ip" ] && ipset -! -R <<-EOF + $(echo $lan_ip | sed -e "s/ /\n/g" | sed -e "s/^/add $IPSET_LAN /") + EOF + + [ -n "$lan_ip6" ] && ipset -! -R <<-EOF + $(echo $lan_ip6 | sed -e "s/ /\n/g" | sed -e "s/^/add $IPSET_LAN6 /") + EOF + } + + update_wan_sets "log" + + [ -n "$ISP_DNS" ] && { + #echolog "å¤„ç† ISP DNS 例外..." + for ispip in $ISP_DNS; do + ipset -! add $IPSET_WHITE $ispip timeout 0 + echolog " - [$?]追加ISP IPv4 DNS到白åå•:${ispip}" + done + } + + [ -n "$ISP_DNS6" ] && { + #echolog "å¤„ç† ISP IPv6 DNS 例外..." + for ispip6 in $ISP_DNS6; do + ipset -! add $IPSET_WHITE6 $ispip6 timeout 0 + echolog " - [$?]追加ISP IPv6 DNS到白åå•:${ispip6}" + done + } + + # 过滤所有节点IP + filter_vpsip > /dev/null 2>&1 & + # filter_haproxy > /dev/null 2>&1 & + + accept_icmp=$(config_t_get global_forwarding accept_icmp 0) + accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0) + + if [ "${TCP_PROXY_WAY}" = "redirect" ]; then + unset is_tproxy + elif [ "${TCP_PROXY_WAY}" = "tproxy" ]; then + is_tproxy="TPROXY" + fi + + $ipt_n -N PSW + $ipt_n -A PSW $(dst $IPSET_LAN) -j RETURN + $ipt_n -A PSW $(dst $IPSET_VPS) -j RETURN + + $ipt_n -A PSW $(comment "WAN_IP_RETURN") $(dst $IPSET_WAN) -j RETURN + + [ "$accept_icmp" = "1" ] && insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p icmp -j PSW" + [ -z "${is_tproxy}" ] && insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW" + + $ipt_n -N PSW_OUTPUT + $ipt_n -A PSW_OUTPUT $(dst $IPSET_LAN) -j RETURN + $ipt_n -A PSW_OUTPUT $(dst $IPSET_VPS) -j RETURN + [ "${USE_DIRECT_LIST}" = "1" ] && $ipt_n -A PSW_OUTPUT $(dst $IPSET_WHITE) -j RETURN + $ipt_n -A PSW_OUTPUT -m mark --mark 255 -j RETURN + + $ipt_n -N PSW_DNS + if [ $(config_t_get global dns_redirect "1") = "0" ]; then + #Only hijack when dest address is local IP + $ipt_n -I PREROUTING -m set --match-set $IPSET_LAN src $(dst $IPSET_LOCAL) -j PSW_DNS + else + $ipt_n -I PREROUTING -m set --match-set $IPSET_LAN src -j PSW_DNS + fi + + $ipt_m -N PSW_DIVERT + $ipt_m -A PSW_DIVERT -j MARK --set-mark ${FWMARK} + $ipt_m -A PSW_DIVERT -j ACCEPT + + $ipt_m -N PSW_RULE + $ipt_m -A PSW_RULE -j CONNMARK --restore-mark + $ipt_m -A PSW_RULE -m mark --mark ${FWMARK} -j RETURN + $ipt_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark ${FWMARK} + $ipt_m -A PSW_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark ${FWMARK} + $ipt_m -A PSW_RULE -j CONNMARK --save-mark + + $ipt_m -N PSW + $ipt_m -A PSW $(dst $IPSET_LAN) -j RETURN + $ipt_m -A PSW $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW -m conntrack --ctdir REPLY -j RETURN + + $ipt_m -A PSW $(comment "WAN_IP_RETURN") $(dst $IPSET_WAN) -j RETURN + + insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW" + # Only TCP, UDP Invalid. + insert_rule_before "$ipt_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT" + + $ipt_m -N PSW_OUTPUT + $ipt_m -A PSW_OUTPUT $(dst $IPSET_LAN) -j RETURN + $ipt_m -A PSW_OUTPUT $(dst $IPSET_VPS) -j RETURN + [ -n "$IPT_APPEND_DNS" ] && { + local local_dns dns_address dns_port + for local_dns in $(echo $IPT_APPEND_DNS | tr ',' ' '); do + dns_address=$(echo "$local_dns" | sed -E 's/(@|\[)?([0-9a-fA-F:.]+)(@|#|$).*/\2/') + dns_port=$(echo "$local_dns" | sed -nE 's/.*#([0-9]+)$/\1/p') + if echo "$dns_address" | grep -q -v ':'; then + $ipt_m -A PSW_OUTPUT -p udp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + $ipt_m -A PSW_OUTPUT -p tcp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + echolog " - [$?]追加直连DNS到iptables:${dns_address}:${dns_port:-53}" + else + $ip6t_m -A PSW_OUTPUT -p udp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + $ip6t_m -A PSW_OUTPUT -p tcp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + echolog " - [$?]追加直连DNS到iptables:[${dns_address}]:${dns_port:-53}" + fi + done + } + + [ "${USE_BLOCK_LIST}" = "1" ] && $ipt_m -A PSW_OUTPUT $(dst $IPSET_BLOCK) -j DROP + [ "${USE_DIRECT_LIST}" = "1" ] && $ipt_m -A PSW_OUTPUT $(dst $IPSET_WHITE) -j RETURN + $ipt_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN + $ipt_m -A PSW_OUTPUT -m mark --mark 255 -j RETURN + + ip rule add fwmark ${FWMARK} table 999 priority 999 + ip route add local 0.0.0.0/0 dev lo table 999 + + [ "$accept_icmpv6" = "1" ] && { + $ip6t_n -N PSW + $ip6t_n -A PSW $(dst $IPSET_LAN6) -j RETURN + $ip6t_n -A PSW $(dst $IPSET_VPS6) -j RETURN + $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW + + $ip6t_n -N PSW_OUTPUT + $ip6t_n -A PSW_OUTPUT $(dst $IPSET_LAN6) -j RETURN + $ip6t_n -A PSW_OUTPUT $(dst $IPSET_VPS6) -j RETURN + [ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_n -A PSW_OUTPUT $(dst $IPSET_WHITE6) -j RETURN + $ip6t_n -A PSW_OUTPUT -m mark --mark 255 -j RETURN + } + + $ip6t_n -N PSW_DNS + if [ $(config_t_get global dns_redirect "1") = "0" ]; then + #Only hijack when dest address is local IP + $ip6t_n -I PREROUTING -m set --match-set $IPSET_LAN6 src $(dst $IPSET_LOCAL6) -j PSW_DNS + else + $ip6t_n -I PREROUTING -m set --match-set $IPSET_LAN6 src -j PSW_DNS + fi + + $ip6t_m -N PSW_DIVERT + $ip6t_m -A PSW_DIVERT -j MARK --set-mark ${FWMARK} + $ip6t_m -A PSW_DIVERT -j ACCEPT + + $ip6t_m -N PSW_RULE + $ip6t_m -A PSW_RULE -j CONNMARK --restore-mark + $ip6t_m -A PSW_RULE -m mark --mark ${FWMARK} -j RETURN + $ip6t_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark ${FWMARK} + $ip6t_m -A PSW_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark ${FWMARK} + $ip6t_m -A PSW_RULE -j CONNMARK --save-mark + + $ip6t_m -N PSW + $ip6t_m -A PSW $(dst $IPSET_LAN6) -j RETURN + $ip6t_m -A PSW $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW -m conntrack --ctdir REPLY -j RETURN + + $ip6t_m -A PSW $(comment "WAN6_IP_RETURN") $(dst $IPSET_WAN6) -j RETURN + + insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW" + # Only TCP, UDP Invalid. + insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT" + + $ip6t_m -N PSW_OUTPUT + $ip6t_m -A PSW_OUTPUT -m mark --mark 255 -j RETURN + $ip6t_m -A PSW_OUTPUT $(dst $IPSET_LAN6) -j RETURN + $ip6t_m -A PSW_OUTPUT $(dst $IPSET_VPS6) -j RETURN + [ "${USE_BLOCK_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_BLOCK6) -j DROP + [ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_WHITE6) -j RETURN + $ip6t_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN + + ip -6 rule add fwmark ${FWMARK} table 999 priority 999 + ip -6 route add local ::/0 dev lo table 999 + + [ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && { + local ipt_tmp=$ipt_n + if [ -n "${is_tproxy}" ]; then + ipt_tmp=$ipt_m + ipt_j="-j PSW_RULE" + else + ipt_j="$(REDIRECT $TCP_REDIR_PORT)" + fi + + msg="ã€è·¯ç”±å™¨æœ¬æœºã€‘," + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ipt_tmp -A PSW_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† TCP 端å£[${TCP_NO_REDIR_PORTS}]" + else + unset LOCALHOST_TCP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ TCP 端å£" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† UDP 端å£[${UDP_NO_REDIR_PORTS}]" + else + unset LOCALHOST_UDP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ UDP 端å£" + fi + } + + if ([ -n "$TCP_NODE" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then + [ -n "$DNS_REDIRECT_PORT" ] && { + $ipt_n -A OUTPUT $(comment "PSW_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A OUTPUT $(comment "PSW_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + $ipt_n -A OUTPUT $(comment "PSW_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A OUTPUT $(comment "PSW_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + } + fi + + [ -n "${LOCALHOST_TCP_PROXY_MODE}" -o -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { + [ "$TCP_PROXY_DROP_PORTS" != "disable" ] && { + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j DROP" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j DROP" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j DROP")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT) -j DROP" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "-j DROP" + echolog " - ${msg}å±è”½ä»£ç† TCP 端å£[${TCP_PROXY_DROP_PORTS}]" + } + + [ "$UDP_PROXY_DROP_PORTS" != "disable" ] && { + [ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP" + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j DROP" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_GFW) -j DROP" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j DROP")" + [ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT) -j DROP" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_PROXY_DROP_PORTS "-j DROP" + echolog " - ${msg}å±è”½ä»£ç† UDP 端å£[${UDP_PROXY_DROP_PORTS}]" + } + } + + # åŠ è½½è·¯ç”±å™¨è‡ªèº«ä»£ç† TCP + if [ -n "$TCP_NODE" ]; then + _proxy_tcp_access() { + [ -n "${2}" ] || return 0 + if echo "${2}" | grep -q -v ':'; then + ipset -q test $IPSET_LAN ${2} + [ $? -eq 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ TCP 代ç†è½¬å‘对该æœåС噍 TCP/${3} 端å£çš„访问" + return 0 + } + if [ -z "${is_tproxy}" ]; then + $ipt_n -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT) + else + $ipt_m -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} -j PSW_RULE + $ipt_m -I PSW $(comment "本机") -p tcp -i lo -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT TPROXY) + fi + echolog " - [$?]将上游 DNS æœåС噍 ${2}:${3} 加入到路由器自身代ç†çš„ TCP 转å‘链" + else + ipset -q test $IPSET_LAN6 ${2} + [ $? -eq 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ TCP 代ç†è½¬å‘对该æœåС噍 TCP/${3} 端å£çš„访问" + return 0 + } + $ip6t_m -I PSW_OUTPUT -p tcp -d ${2} --dport ${3} -j PSW_RULE + $ip6t_m -I PSW $(comment "本机") -p tcp -i lo -d ${2} --dport ${3} $(REDIRECT $TCP_REDIR_PORT TPROXY) + echolog " - [$?]将上游 DNS æœåС噍 [${2}]:${3} 加入到路由器自身代ç†çš„ TCP 转å‘é“¾ï¼Œè¯·ç¡®ä¿æ‚¨çš„节点支æŒIPv6,并开å¯IPv6逿˜Žä»£ç†ï¼" + fi + } + [ -n "${TCP_PROXY_DNS}" ] && hosts_foreach REMOTE_DNS _proxy_tcp_access 53 + + [ "$accept_icmp" = "1" ] && { + $ipt_n -A OUTPUT -p icmp -j PSW_OUTPUT + [ "${USE_FAKEDNS}" = "1" ] && $ipt_n -A PSW_OUTPUT -p icmp -d $FAKE_IP $(REDIRECT) + [ "${USE_PROXY_LIST}" = "1" ] && $ipt_n -A PSW_OUTPUT -p icmp $(dst $IPSET_BLACK) $(REDIRECT) + [ "${USE_GFW_LIST}" = "1" ] && $ipt_n -A PSW_OUTPUT -p icmp $(dst $IPSET_GFW) $(REDIRECT) + [ "${CHN_LIST}" != "0" ] && $ipt_n -A PSW_OUTPUT -p icmp $(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST}) + [ "${USE_SHUNT_TCP}" = "1" ] && $ipt_n -A PSW_OUTPUT -p icmp $(dst $IPSET_SHUNT) $(REDIRECT) + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && $ipt_n -A PSW_OUTPUT -p icmp $(REDIRECT) + } + + [ "$accept_icmpv6" = "1" ] && { + $ip6t_n -A OUTPUT -p ipv6-icmp -j PSW_OUTPUT + [ "${USE_FAKEDNS}" = "1" ] && $ip6t_n -A PSW_OUTPUT -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT) + [ "${USE_PROXY_LIST}" = "1" ] && $ip6t_n -A PSW_OUTPUT -p ipv6-icmp $(dst $IPSET_BLACK6) $(REDIRECT) + [ "${USE_GFW_LIST}" = "1" ] && $ip6t_n -A PSW_OUTPUT -p ipv6-icmp $(dst $IPSET_GFW6) $(REDIRECT) + [ "${CHN_LIST}" != "0" ] && $ip6t_n -A PSW_OUTPUT -p ipv6-icmp $(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST}) + [ "${USE_SHUNT_TCP}" = "1" ] && $ip6t_n -A PSW_OUTPUT -p ipv6-icmp $(dst $IPSET_SHUNT6) $(REDIRECT) + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && $ip6t_n -A PSW_OUTPUT -p ipv6-icmp $(REDIRECT) + } + + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ipt_tmp -A PSW_OUTPUT -p tcp -d $FAKE_IP ${ipt_j} + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_tmp -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_BLACK) ${ipt_j}" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_tmp -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_GFW) ${ipt_j}" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_tmp -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "${ipt_j}")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ipt_tmp -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_SHUNT) ${ipt_j}" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_tmp -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "${ipt_j}" + [ -n "${is_tproxy}" ] && $ipt_m -A PSW $(comment "本机") -p tcp -i lo $(REDIRECT $TCP_REDIR_PORT TPROXY) + } + [ -z "${is_tproxy}" ] && $ipt_n -A OUTPUT -p tcp -j PSW_OUTPUT + [ -n "${is_tproxy}" ] && { + $ipt_m -A PSW $(comment "本机") -p tcp -i lo -j RETURN + insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -p tcp -j PSW_OUTPUT" + } + + [ "$PROXY_IPV6" == "1" ] && { + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW_OUTPUT -p tcp -d $FAKE_IP_6 -j PSW_RULE + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_GFW6) -j PSW_RULE" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j PSW_RULE")" + [ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_SHUNT6) -j PSW_RULE" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "-j PSW_RULE" + $ip6t_m -A PSW $(comment "本机") -p tcp -i lo $(REDIRECT $TCP_REDIR_PORT TPROXY) + } + $ip6t_m -A PSW $(comment "本机") -p tcp -i lo -j RETURN + insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -p tcp -j PSW_OUTPUT" + } + fi + + # åŠ è½½è·¯ç”±å™¨è‡ªèº«ä»£ç† UDP + if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then + _proxy_udp_access() { + [ -n "${2}" ] || return 0 + if echo "${2}" | grep -q -v ':'; then + ipset -q test $IPSET_LAN ${2} + [ $? == 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ UDP 代ç†è½¬å‘对该æœåС噍 UDP/${3} 端å£çš„访问" + return 0 + } + $ipt_m -I PSW_OUTPUT -p udp -d ${2} --dport ${3} -j PSW_RULE + $ipt_m -I PSW $(comment "本机") -p udp -i lo -d ${2} --dport ${3} $(REDIRECT $UDP_REDIR_PORT TPROXY) + echolog " - [$?]将上游 DNS æœåС噍 ${2}:${3} 加入到路由器自身代ç†çš„ UDP 转å‘链" + else + ipset -q test $IPSET_LAN6 ${2} + [ $? == 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ UDP 代ç†è½¬å‘对该æœåС噍 UDP/${3} 端å£çš„访问" + return 0 + } + $ip6t_m -I PSW_OUTPUT -p udp -d ${2} --dport ${3} -j PSW_RULE + $ip6t_m -I PSW $(comment "本机") -p udp -i lo -d ${2} --dport ${3} $(REDIRECT $UDP_REDIR_PORT TPROXY) + echolog " - [$?]将上游 DNS æœåС噍 [${2}]:${3} 加入到路由器自身代ç†çš„ UDP 转å‘é“¾ï¼Œè¯·ç¡®ä¿æ‚¨çš„节点支æŒIPv6,并开å¯IPv6逿˜Žä»£ç†ï¼" + fi + } + [ -n "${UDP_PROXY_DNS}" ] && hosts_foreach REMOTE_DNS _proxy_udp_access 53 + [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ipt_m -A PSW_OUTPUT -p udp -d $FAKE_IP -j PSW_RULE + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_BLACK) -j PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_GFW) -j PSW_RULE" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_CHN) $(get_jump_ipt ${CHN_LIST} "-j PSW_RULE")" + [ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_SHUNT) -j PSW_RULE" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "-j PSW_RULE" + $ipt_m -A PSW $(comment "本机") -p udp -i lo $(REDIRECT $UDP_REDIR_PORT TPROXY) + } + $ipt_m -A PSW $(comment "本机") -p udp -i lo -j RETURN + insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -p udp -j PSW_OUTPUT" + + [ "$PROXY_IPV6" == "1" ] && { + [ -n "$LOCALHOST_UDP_PROXY_MODE" ] && { + [ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW_OUTPUT -p udp -d $FAKE_IP_6 -j PSW_RULE + [ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_GFW6) -j PSW_RULE" + [ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j PSW_RULE")" + [ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_SHUNT6) -j PSW_RULE" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "-j PSW_RULE" + $ip6t_m -A PSW $(comment "本机") -p udp -i lo $(REDIRECT $UDP_REDIR_PORT TPROXY) + } + $ip6t_m -A PSW $(comment "本机") -p udp -i lo -j RETURN + insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -p udp -j PSW_OUTPUT" + } + fi + + $ipt_m -I OUTPUT $(comment "mangle-OUTPUT-PSW") -o lo -j RETURN + insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -m mark --mark ${FWMARK} -j RETURN" + + $ip6t_m -I OUTPUT $(comment "mangle-OUTPUT-PSW") -o lo -j RETURN + insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -m mark --mark ${FWMARK} -j RETURN" + } + + # 加载ACLS + load_acl + + [ -d "${TMP_IFACE_PATH}" ] && { + for iface in $(ls ${TMP_IFACE_PATH}); do + $ipt_n -A PSW_OUTPUT -o $iface -j RETURN + $ipt_m -A PSW_OUTPUT -o $iface -j RETURN + done + } + + $ipt_n -I PREROUTING $(comment "PSW") -m mark --mark ${FWMARK} -j RETURN + $ip6t_n -I PREROUTING $(comment "PSW") -m mark --mark ${FWMARK} -j RETURN + + filter_direct_node_list > /dev/null 2>&1 & + + echolog "防ç«å¢™è§„则加载完æˆï¼" +} + +del_firewall_rule() { + for ipt in "$ipt_n" "$ipt_m" "$ip6t_n" "$ip6t_m"; do + for chain in "PREROUTING" "OUTPUT"; do + for i in $(seq 1 $($ipt -nL $chain | grep -c PSW)); do + local index=$($ipt --line-number -nL $chain | grep PSW | head -1 | awk '{print $1}') + $ipt -D $chain $index 2>/dev/null + done + done + for chain in "PSW" "PSW_OUTPUT" "PSW_DIVERT" "PSW_DNS" "PSW_RULE"; do + $ipt -F $chain 2>/dev/null + $ipt -X $chain 2>/dev/null + done + done + + ip rule del fwmark ${FWMARK} 2>/dev/null + ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null + + ip -6 rule del fwmark ${FWMARK} 2>/dev/null + ip -6 route del local ::/0 dev lo table 999 2>/dev/null + + destroy_ipset $IPSET_LOCAL + destroy_ipset $IPSET_WAN + destroy_ipset $IPSET_LAN + destroy_ipset $IPSET_VPS + #destroy_ipset $IPSET_SHUNT + #destroy_ipset $IPSET_GFW + #destroy_ipset $IPSET_CHN + #destroy_ipset $IPSET_BLACK + destroy_ipset $IPSET_BLOCK + destroy_ipset $IPSET_WHITE + + destroy_ipset $IPSET_LOCAL6 + destroy_ipset $IPSET_WAN6 + destroy_ipset $IPSET_LAN6 + destroy_ipset $IPSET_VPS6 + #destroy_ipset $IPSET_SHUNT6 + #destroy_ipset $IPSET_GFW6 + #destroy_ipset $IPSET_CHN6 + #destroy_ipset $IPSET_BLACK6 + destroy_ipset $IPSET_BLOCK6 + destroy_ipset $IPSET_WHITE6 + + echolog "删除 iptables 规则完æˆã€‚" +} + +flush_ipset() { + echolog "清空 IPSet。" + for _name in $(ipset list | grep "Name: " | grep "psw_" | awk '{print $2}'); do + destroy_ipset ${_name} + done +} + +flush_include() { + echo '#!/bin/sh' >$FWI +} + +gen_include() { + flush_include + extract_rules() { + local _ipt="${ipt}" + [ "$1" == "6" ] && _ipt="${ip6t}" + [ -z "${_ipt}" ] && return + + echo "*$2" + ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | grep -v "mangle\-OUTPUT\-PSW" | grep -v "socket \-j PSW_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + echo 'COMMIT' + } + local __ipt="" + [ -n "${ipt}" ] && { + __ipt=$(cat <<- EOF + + ${MY_PATH} update_wan_sets + + mangle_output_psw=\$(${ipt}-save -t mangle | grep "PSW" | grep "mangle\-OUTPUT\-PSW" | sed "s#-A OUTPUT ##g") + $ipt-save -c | grep -v "PSW" | $ipt-restore -c + $ipt-restore -n <<-EOT + $(extract_rules 4 nat) + $(extract_rules 4 mangle) + EOT + + echo "\${mangle_output_psw}" | while read line; do + \$(${MY_PATH} insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "\${line}") + done + + [ "$accept_icmp" = "1" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p icmp -j PSW") + [ -z "${is_tproxy}" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW") + + \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW") + \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT") + EOF + ) + } + local __ip6t="" + [ -n "${ip6t}" ] && { + __ip6t=$(cat <<- EOF + mangle_output_psw=\$(${ip6t}-save -t mangle | grep "PSW" | grep "mangle\-OUTPUT\-PSW" | sed "s#-A OUTPUT ##g") + $ip6t-save -c | grep -v "PSW" | $ip6t-restore -c + $ip6t-restore -n <<-EOT + $(extract_rules 6 nat) + $(extract_rules 6 mangle) + EOT + + echo "\${mangle_output_psw}" | while read line; do + \$(${MY_PATH} insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "\${line}") + done + + [ "$accept_icmpv6" = "1" ] && $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW + + \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW") + \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT") + EOF + ) + } + cat <<-EOF >> $FWI + ${__ipt} + + ${__ip6t} + + return 0 + EOF + return 0 +} + +get_ipt_bin() { + echo $ipt +} + +get_ip6t_bin() { + echo $ip6t +} + +start() { + [ "$ENABLED_DEFAULT_ACL" == 0 -a "$ENABLED_ACLS" == 0 ] && return + add_firewall_rule + gen_include +} + +stop() { + [ -z "$(command -v echolog)" ] && . "$UTILS_PATH" + del_firewall_rule + [ $(config_t_get global flush_set_on_reboot "0") = "1" -o $(config_t_get global flush_set "0") = "1" ] && { + uci -q delete ${CONFIG}.@global[0].flush_set + uci -q commit ${CONFIG} + flush_ipset + rm -rf $TMP_PATH2/singbox* + rm -rf $TMP_PATH2/dnsmasq* + rm -rf $TMP_PATH2/geo_output + } + flush_include +} + +arg1=$1 +shift +case $arg1 in +RULE_LAST_INDEX) + RULE_LAST_INDEX "$@" + ;; +insert_rule_before) + insert_rule_before "$@" + ;; +insert_rule_after) + insert_rule_after "$@" + ;; +get_ipt_bin) + get_ipt_bin + ;; +get_ip6t_bin) + get_ip6t_bin + ;; +filter_direct_node_list) + filter_direct_node_list + ;; +update_wan_sets) + update_wan_sets "$@" + ;; +stop) + stop + ;; +start) + start + ;; +*) ;; +esac diff --git a/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh b/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh new file mode 100755 index 00000000..d81de507 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +# dhcp.leases to hosts + +. /usr/share/passwall/utils.sh +LOCK_FILE=${LOCK_PATH}/${CONFIG}_lease2hosts.lock +LEASE_FILE="/tmp/dhcp.leases" +HOSTS_FILE="$TMP_PATH2/dhcp-hosts" +TMP_FILE="/tmp/dhcp-hosts.tmp" + +exec 99>"$LOCK_FILE" +flock -n 99 +if [ "$?" != 0 ]; then + exit 0 +fi + +reload_dnsmasq_pids() { + local pidfile pid + find $TMP_PATH/acl -type f -name 'dnsmasq.pid' 2>/dev/null | while read pidfile; do + if [ -s "$pidfile" ]; then + read pid < "$pidfile" + if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then + kill -HUP "$pid" + fi + fi + done +} + +while true; do + + if [ -f "$LEASE_FILE" ]; then + awk 'NF >= 4 && $4 != "*" {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE" + if [ -s "$TMP_FILE" ]; then + if [ ! -f "$HOSTS_FILE" ] || ! cmp -s "$TMP_FILE" "$HOSTS_FILE"; then + mv "$TMP_FILE" "$HOSTS_FILE" + reload_dnsmasq_pids + else + rm -f "$TMP_FILE" + fi + else + if [ -s "$HOSTS_FILE" ]; then + : > "$HOSTS_FILE" + reload_dnsmasq_pids + fi + rm -f "$TMP_FILE" + fi + fi + + sleep 60 + +done 2>/dev/null diff --git a/luci-app-passwall/root/usr/share/passwall/monitor.sh b/luci-app-passwall/root/usr/share/passwall/monitor.sh new file mode 100755 index 00000000..5314b7d4 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/monitor.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +. $DIR/utils.sh +LOCK_FILE=${LOCK_PATH}/${CONFIG}_monitor.lock + +MAX_RESTART_COUNT=10 +RESTART_STATS_DIR="${TMP_PATH}/script_rstats" +mkdir -p "$RESTART_STATS_DIR" + +sleep 58s +last_cleanup_date=$(date +%Y%m%d) +while [ 1 -eq 1 ]; do + [ -f "$LOCK_FILE" ] && { + sleep 6s + continue + } + touch $LOCK_FILE + + for file in "$TMP_SCRIPT_FUNC_PATH"/*; do + [ -f "$file" ] || continue + IFS= read -r cmd < "$file" + [ -z "$cmd" ] && continue + cmd_check=$(printf '%s' "$cmd" | sed 's/>.*$//;s/[[:space:]]*$//') + + case "$cmd_check" in + *dns2socks*) cmd_check=${cmd_check//:/ } ;; + esac + + filename=$(basename "$file") + stats_file="${RESTART_STATS_DIR}/${filename}.count" + if [ -s "$stats_file" ]; then + read restart_count < "$stats_file" + [ -z "$restart_count" ] && restart_count=0 + else + restart_count=0 + fi + # 检查是å¦è¶…过最大é‡å¯æ¬¡æ•° + [ "$restart_count" -ge "$MAX_RESTART_COUNT" ] && continue + + if ! busybox pgrep -f "$cmd_check" >/dev/null; then + restart_count=$((restart_count + 1)) + echo "$restart_count" > "$stats_file" + #echo "${cmd} 进程挂掉,é‡å¯" >> /tmp/log/passwall.log + sh -c "nohup $cmd 2>&1 &" + sleep 1 + fi + done + + # æ¯å¤©æ¸…ç†ä¸€æ¬¡ç»Ÿè®¡æ–‡ä»¶ï¼ˆè·¨å¤©åŽæ‰§è¡Œä¸€æ¬¡ï¼‰ + current_date=$(date +%Y%m%d) + if [ "$current_date" != "$last_cleanup_date" ]; then + rm -f "${RESTART_STATS_DIR:?}"/* 2>/dev/null + last_cleanup_date="$current_date" + fi + + rm -f $LOCK_FILE + sleep 58s +done diff --git a/luci-app-passwall/root/usr/share/passwall/nftables.sh b/luci-app-passwall/root/usr/share/passwall/nftables.sh new file mode 100755 index 00000000..114e0240 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -0,0 +1,1549 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +MY_PATH=$DIR/nftables.sh +UTILS_PATH=$DIR/utils.sh +NFTABLE_NAME="inet passwall" +NFTSET_LOCAL="psw_local" +NFTSET_WAN="psw_wan" +NFTSET_LAN="psw_lan" +NFTSET_VPS="psw_vps" +NFTSET_SHUNT="psw_shunt" +NFTSET_GFW="psw_gfw" +NFTSET_CHN="psw_chn" +NFTSET_BLACK="psw_black" +NFTSET_WHITE="psw_white" +NFTSET_BLOCK="psw_block" + +NFTSET_LOCAL6="psw_local6" +NFTSET_WAN6="psw_wan6" +NFTSET_LAN6="psw_lan6" +NFTSET_VPS6="psw_vps6" +NFTSET_SHUNT6="psw_shunt6" +NFTSET_GFW6="psw_gfw6" +NFTSET_CHN6="psw_chn6" +NFTSET_BLACK6="psw_black6" +NFTSET_WHITE6="psw_white6" +NFTSET_BLOCK6="psw_block6" + +USE_SHUNT_TCP=0 +USE_SHUNT_UDP=0 + +# ASCII code for PSW1.Use whatever,just not the same. +FWMARK="0x50535731" + +FWI=$(uci -q get firewall.passwall.path 2>/dev/null) +FAKE_IP="198.18.0.0/15" +FAKE_IP_6="fc00::/18" + +factor() { + local ports="$1" + if [ -z "$1" ] || [ -z "$2" ] || [ "$ports" = "1:65535" ]; then + echo "" + # acl mac address + elif echo "$1" | grep -qE '([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}'; then + echo "$2 {$1}" + else + ports=$(echo "$ports" | tr -d ' ' | sed 's/:/-/g' | tr ',' '\n' | awk '!a[$0]++' | grep -v '^$') + [ -z "$ports" ] && { echo ""; return; } + if echo "$ports" | grep -q '^1-65535$'; then + echo "" + return + fi + local port + local port_list="" + for port in $ports; do + port_list="${port_list},$port" + done + port_list="${port_list#,}" + echo "$2 {$port_list}" + fi +} + +insert_rule_before() { + [ $# -ge 4 ] || { + return 1 + } + local table_name="${1}"; shift + local chain_name="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$(nft -a list chain $table_name $chain_name 2>/dev/null | grep "$keyword" | awk -F '# handle ' '{print$2}' | head -n 1 | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + nft "add rule $table_name $chain_name $rule" + else + if [ -z "${_index}" ]; then + _index=${default_index} + fi + nft "insert rule $table_name $chain_name position $_index $rule" + fi +} + +insert_rule_after() { + [ $# -ge 4 ] || { + return 1 + } + local table_name="${1}"; shift + local chain_name="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$(nft -a list chain $table_name $chain_name 2>/dev/null | grep "$keyword" | awk -F '# handle ' '{print$2}' | head -n 1 | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + nft "add rule $table_name $chain_name $rule" + else + if [ -n "${_index}" ]; then + _index=$((_index + 1)) + else + _index=${default_index} + fi + nft "insert rule $table_name $chain_name position $_index $rule" + fi +} + +RULE_LAST_INDEX() { + [ $# -ge 3 ] || { + echolog "索引列举方å¼ä¸æ­£ç¡®ï¼ˆnftables),终止执行ï¼" + return 1 + } + local table_name="${1}"; shift + local chain_name="${1}"; shift + local keyword="${1}"; shift + local default="${1:-0}"; shift + local _index=$(nft -a list chain $table_name $chain_name 2>/dev/null | grep "$keyword" | awk -F '# handle ' '{print$2}' | head -n 1 | awk '{print $1}') + echo "${_index:-${default}}" +} + +REDIRECT() { + local s="counter redirect" + [ -n "$1" ] && { + local s="$s to :$1" + [ "$2" == "TPROXY" ] && { + s="counter meta mark ${FWMARK} tproxy to :$1" + } + [ "$2" == "TPROXY4" ] && { + s="counter meta mark ${FWMARK} tproxy ip to :$1" + } + [ "$2" == "TPROXY6" ] && { + s="counter meta mark ${FWMARK} tproxy ip6 to :$1" + } + } + echo $s +} + +destroy_nftset() { + for i in "$@"; do + nft flush set $NFTABLE_NAME $i 2>/dev/null + nft delete set $NFTABLE_NAME $i 2>/dev/null + done +} + +gen_nft_tables() { + if ! nft list table "$NFTABLE_NAME" >/dev/null 2>&1; then + nft -f - <<-EOF + table $NFTABLE_NAME { + chain dstnat { + type nat hook prerouting priority dstnat - 1; policy accept; + } + chain mangle_prerouting { + type filter hook prerouting priority mangle - 1; policy accept; + } + chain mangle_output { + type route hook output priority mangle - 1; policy accept; + } + chain nat_output { + type nat hook output priority -1; policy accept; + } + } + EOF + fi +} + +insert_nftset() { + local nftset_name="${1}"; shift + local timeout_argument="${1}"; shift + local default_timeout="365d" + local suffix="" + + if [ -n "$nftset_name" ] && { [ $# -gt 0 ] || [ ! -t 0 ]; }; then + case "$timeout_argument" in + "-1") suffix="" ;; + "0") suffix=" timeout $default_timeout" ;; + *) suffix=" timeout $timeout_argument" ;; + esac + { + if [ $# -gt 0 ]; then + printf "%s\n" "$@" + else + cat + fi | tr -s ' \t' '\n' | awk -v s="$suffix" -v n="$nftset_name" -v t="$NFTABLE_NAME" ' + { + gsub(/^[ \t\r]+|[ \t\r]+$/, ""); + } + $0 != "" { + if (first == 0) { + printf "add element %s %s { \n", t, n; + first = 1; + } else { + printf ",\n"; + } + printf "%s%s", $0, s; + } + END { + if (first == 1) printf "\n }\n"; + } + ' + } | nft -f - + fi +} + +gen_nftset() { + local nftset_name="${1}"; shift + local ip_type="${1}"; shift + # 0 - don't set defalut timeout + local timeout_argument_set="${1}"; shift + # 0 - don't let element timeout(365 days) when set's timeout parameters be seted + # -1 - follow the set's timeout parameters + local timeout_argument_element="${1}"; shift + local gc_interval_time="1h" + + if ! nft list set $NFTABLE_NAME $nftset_name >/dev/null 2>&1; then + if [ "$timeout_argument_set" == "0" ]; then + nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; auto-merge; }" + else + nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; timeout $timeout_argument_set; gc-interval $gc_interval_time; auto-merge; }" + fi + fi + [ $# -gt 0 ] || [ ! -t 0 ] && insert_nftset "$nftset_name" "$timeout_argument_element" "$@" +} + +get_jump_nft() { + case "$1" in + direct) + echo "mark != ${FWMARK} counter return" + ;; + proxy) + if [ -n "$2" ] && [ -n "$(echo $2 | grep "^counter")" ]; then + echo "$2" + else + echo "$(REDIRECT $2 $3)" + fi + ;; + esac +} + +load_acl() { + ([ "$ENABLED_ACLS" == 1 ] || ([ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ])) && echolog " - 访问控制:" + [ "$ENABLED_ACLS" == 1 ] && { + acl_app + for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do + eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-) + + tcp_no_redir_ports=${tcp_no_redir_ports:-default} + udp_no_redir_ports=${udp_no_redir_ports:-default} + use_global_config=${use_global_config:-0} + tcp_proxy_drop_ports=${tcp_proxy_drop_ports:-default} + udp_proxy_drop_ports=${udp_proxy_drop_ports:-default} + tcp_redir_ports=${tcp_redir_ports:-default} + udp_redir_ports=${udp_redir_ports:-default} + use_direct_list=${use_direct_list:-1} + use_proxy_list=${use_proxy_list:-1} + use_block_list=${use_block_list:-1} + use_gfw_list=${use_gfw_list:-1} + chn_list=${chn_list:-direct} + tcp_proxy_mode=${tcp_proxy_mode:-proxy} + udp_proxy_mode=${udp_proxy_mode:-proxy} + [ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS + [ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS + [ "$tcp_proxy_drop_ports" = "default" ] && tcp_proxy_drop_ports=$TCP_PROXY_DROP_PORTS + [ "$udp_proxy_drop_ports" = "default" ] && udp_proxy_drop_ports=$UDP_PROXY_DROP_PORTS + [ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS + [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS + + [ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node") + [ -n "$(get_cache_var "ACL_${sid}_tcp_redir_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_redir_port") + [ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node") + [ -n "$(get_cache_var "ACL_${sid}_udp_redir_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_redir_port") + [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") + [ -n "$(get_cache_var "ACL_${sid}_fakedns")" ] && use_fakedns=$(get_cache_var "ACL_${sid}_fakedns") + [ -n "$tcp_node" ] && { + if is_socks_wrap "$tcp_node"; then + tcp_node_remark="Socks é…ç½®($(config_n_get ${tcp_node#Socks_} port) 端å£)" + else + tcp_node_remark=$(config_n_get $tcp_node remarks) + fi + } + [ -n "$udp_node" ] && { + if is_socks_wrap "$udp_node"; then + udp_node_remark="Socks é…ç½®($(config_n_get ${udp_node#Socks_} port) 端å£)" + else + udp_node_remark=$(config_n_get $udp_node remarks) + fi + } + use_shunt_tcp=0 + use_shunt_udp=0 + [ -n "$tcp_node" ] && [ "$(config_n_get $tcp_node protocol)" = "_shunt" ] && use_shunt_tcp=1 + [ -n "$udp_node" ] && [ "$(config_n_get $udp_node protocol)" = "_shunt" ] && use_shunt_udp=1 + + [ "${use_global_config}" = "1" ] && { + if is_socks_wrap "$TCP_NODE"; then + tcp_node_remark="Socks é…ç½®($(config_n_get ${TCP_NODE#Socks_} port) 端å£)" + else + tcp_node_remark=$(config_n_get $TCP_NODE remarks) + fi + if is_socks_wrap "$UDP_NODE"; then + udp_node_remark="Socks é…ç½®($(config_n_get ${UDP_NODE#Socks_} port) 端å£)" + else + udp_node_remark=$(config_n_get $UDP_NODE remarks) + fi + use_direct_list=${USE_DIRECT_LIST} + use_proxy_list=${USE_PROXY_LIST} + use_block_list=${USE_BLOCK_LIST} + use_gfw_list=${USE_GFW_LIST} + chn_list=${CHN_LIST} + tcp_proxy_mode=${TCP_PROXY_MODE} + udp_proxy_mode=${UDP_PROXY_MODE} + use_shunt_tcp=${USE_SHUNT_TCP} + use_shunt_udp=${USE_SHUNT_UDP} + dns_redirect_port=${DNS_REDIRECT_PORT} + black_set_name=${NFTSET_BLACK} + black6_set_name=${NFTSET_BLACK6} + gfw_set_name=${NFTSET_GFW} + gfw6_set_name=${NFTSET_GFW6} + shunt_set_name=${NFTSET_SHUNT} + shunt6_set_name=${NFTSET_SHUNT6} + use_fakedns=${USE_FAKEDNS} + } + + _acl_list=${TMP_ACL_PATH}/${sid}/source_list + + for i in $(cat $_acl_list); do + local _ipt_source _ipv4 + local msg + if [ -n "${interface}" ]; then + local gateway device + network_get_gateway gateway "${interface}" + network_get_device device "${interface}" + # network_get_device returns empty for non-UP interfaces (e.g. auto='0'). + # Try ubus directly, then check if the name is a kernel device. + [ -z "${device}" ] && device=$(ubus call "network.interface.${interface}" status 2>/dev/null | jsonfilter -e '@.device' 2>/dev/null) + [ -z "${device}" ] && [ -d "/sys/class/net/${interface}" ] && device="${interface}" + [ -z "${device}" ] && device="${interface}" + _ipt_source="iifname ${device} " + msg="æºæŽ¥å£ã€${device}】," + else + msg="æºæŽ¥å£ã€æ‰€æœ‰ã€‘," + fi + if [ -n "$(echo ${i} | grep '^iprange:')" ]; then + _iprange=$(echo ${i} | sed 's#iprange:##g') + _ipt_source=$(factor ${_iprange} "${_ipt_source}ip saddr") + msg="${msg}IP rangeã€${_iprange}】," + _ipv4="1" + unset _iprange + elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then + _ipset=$(echo ${i} | sed 's#ipset:##g') + _ipt_source="${_ipt_source}ip saddr @${_ipset}" + msg="${msg}NFTsetã€${_ipset}】," + unset _ipset + elif [ -n "$(echo ${i} | grep '^ip:')" ]; then + _ip=$(echo ${i} | sed 's#ip:##g') + _ipt_source=$(factor ${_ip} "${_ipt_source}ip saddr") + msg="${msg}IPã€${_ip}】," + _ipv4="1" + unset _ip + elif [ -n "$(echo ${i} | grep '^mac:')" ]; then + _mac=$(echo ${i} | sed 's#mac:##g') + _ipt_source=$(factor ${_mac} "${_ipt_source}ether saddr") + msg="${msg}MACã€${_mac}】," + unset _mac + elif [ -n "$(echo ${i} | grep '^any')" ]; then + msg="${msg}所有设备," + else + continue + fi + msg="ã€$remarks】,${msg}" + + [ "$tcp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$tcp_no_redir_ports"; then + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ${_ipt_source} ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ${_ipt_source} meta l4proto tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\"" + echolog " - ${msg}ä¸ä»£ç† TCP 端å£[${tcp_no_redir_ports}]" + else + #ç»“æŸæ—¶ä¼šreturn,无需加多余的规则。 + unset tcp_port + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ TCP 端å£" + fi + } + + [ "$udp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$udp_no_redir_ports"; then + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" 2>/dev/null + echolog " - ${msg}ä¸ä»£ç† UDP 端å£[${udp_no_redir_ports}]" + else + #ç»“æŸæ—¶ä¼šreturn,无需加多余的规则。 + unset udp_port + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ UDP 端å£" + fi + } + + local dns_redirect + [ $(config_t_get global dns_redirect "1") = "1" ] && dns_redirect=53 + if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then + [ "${use_proxy_list}" = "1" ] && { + [ "${use_global_config}" = "0" ] && { + black_set_name="psw_${sid}_black" + black6_set_name="psw_${sid}_black6" + gen_nftset $black_set_name ipv4_addr "2d" 0 + gen_nftset $black6_set_name ipv6_addr "2d" 0 + } + } + [ "${use_gfw_list}" = "1" ] && { + [ "${use_global_config}" = "0" ] && { + gfw_set_name="psw_${sid}_gfw" + gfw6_set_name="psw_${sid}_gfw6" + gen_nftset $gfw_set_name ipv4_addr "2d" 0 + gen_nftset $gfw6_set_name ipv6_addr "2d" 0 + } + } + [ "${use_shunt_tcp}" = "1" -o "${use_shunt_udp}" = "1" ] && { + [ "${use_global_config}" = "0" ] && { + shunt_set_name="psw_${sid}_shunt" + shunt6_set_name="psw_${sid}_shunt6" + gen_nftset $shunt_set_name ipv4_addr "2d" 0 + gen_nftset $shunt6_set_name ipv6_addr "2d" 0 + } + } + [ -n "${dns_redirect_port}" ] && dns_redirect=${dns_redirect_port} + else + [ -n "${DIRECT_DNSMASQ_PORT}" ] && dns_redirect=${DIRECT_DNSMASQ_PORT} + fi + if [ -n "${dns_redirect}" ]; then + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + #nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\"" + #nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\"" + [ -z "$(get_cache_var "ACL_${sid}_tcp_default")" ] && echolog " - ${msg}使用与全局é…ç½®ä¸ç›¸åŒèŠ‚ç‚¹ï¼Œå·²å°†DNS强制é‡å®šå‘到专用 DNS æœåŠ¡å™¨ã€‚" + fi + + [ -n "$tcp_port" -o -n "$udp_port" ] && { + [ "${use_block_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ${_ipt_source} ip daddr @$NFTSET_BLOCK counter drop comment \"$remarks\"" + [ "${use_block_list}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ${_ipt_source} ip daddr @$NFTSET_BLOCK counter drop comment \"$remarks\"" + [ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ${_ipt_source} ip daddr @$NFTSET_WHITE counter return comment \"$remarks\"" + [ "${use_direct_list}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ${_ipt_source} ip daddr @$NFTSET_WHITE counter return comment \"$remarks\"" + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_block_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ${_ipt_source} ip6 daddr @$NFTSET_BLOCK6 counter drop comment \"$remarks\"" + [ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ${_ipt_source} ip6 daddr @$NFTSET_WHITE6 counter return comment \"$remarks\"" + } + + [ "$tcp_proxy_drop_ports" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$black6_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$gfw6_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${chn_list} "counter drop") comment \"$remarks\"" 2>/dev/null + [ "${use_shunt_tcp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$shunt6_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") counter drop comment \"$remarks\"" 2>/dev/null + } + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr $FAKE_IP counter drop comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr @$black_set_name counter drop comment \"$remarks\"" + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr @$gfw_set_name counter drop comment \"$remarks\"" + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${chn_list} "counter drop") comment \"$remarks\"" + [ "${use_shunt_tcp}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip daddr @$shunt_set_name counter drop comment \"$remarks\"" + [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") counter drop comment \"$remarks\"" + echolog " - ${msg}å±è”½ä»£ç† TCP 端å£[${tcp_proxy_drop_ports}]" + } + + [ "$udp_proxy_drop_ports" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$black6_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$gfw6_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${chn_list} "counter drop") comment \"$remarks\"" 2>/dev/null + [ "${use_shunt_udp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$shunt6_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${udp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") counter drop comment \"$remarks\"" 2>/dev/null + } + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr $FAKE_IP counter drop comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr @$black_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr @$gfw_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${chn_list} "counter drop") comment \"$remarks\"" 2>/dev/null + [ "${use_shunt_udp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip daddr @$shunt_set_name counter drop comment \"$remarks\"" 2>/dev/null + [ "${udp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") counter drop comment \"$remarks\"" 2>/dev/null + echolog " - ${msg}å±è”½ä»£ç† UDP 端å£[${udp_proxy_drop_ports}]" + } + } + + [ -n "$tcp_port" ] && { + if [ -n "${tcp_proxy_mode}" ]; then + msg2="${msg}使用 TCP 节点[$tcp_node_remark]" + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${tcp_port})" + nft_chain="PSW_MANGLE" + nft_j="counter jump PSW_RULE" + else + msg2="${msg2}(REDIRECT:${tcp_port})" + nft_chain="PSW_NAT" + nft_j="$(REDIRECT $tcp_port)" + fi + + [ "$accept_icmp" = "1" ] && { + [ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$NFTSET_WHITE counter return comment \"$remarks\"" + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT) comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$black_set_name $(REDIRECT) comment \"$remarks\"" + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$gfw_set_name $(REDIRECT) comment \"$remarks\"" + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$NFTSET_CHN $(get_jump_nft ${chn_list}) comment \"$remarks\"" + [ "${use_shunt_tcp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$shunt_set_name $(REDIRECT) comment \"$remarks\"" + [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} $(REDIRECT) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} return comment \"$remarks\"" + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$NFTSET_WHITE6 counter return comment \"$remarks\"" 2>/dev/null + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$black6_set_name $(REDIRECT) comment \"$remarks\"" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$gfw6_set_name $(REDIRECT) comment \"$remarks\"" 2>/dev/null + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${chn_list}) comment \"$remarks\"" 2>/dev/null + [ "${use_shunt_tcp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$shunt6_set_name $(REDIRECT) comment \"$remarks\"" 2>/dev/null + [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} $(REDIRECT) comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} return comment \"$remarks\"" 2>/dev/null + } + + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP ${nft_j} comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr @$black_set_name ${nft_j} comment \"$remarks\" " + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr @$gfw_set_name ${nft_j} comment \"$remarks\" " + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${chn_list} "${nft_j}") comment \"$remarks\" " + [ "${use_shunt_tcp}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr @$shunt_set_name ${nft_j} comment \"$remarks\"" + [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ${nft_j} comment \"$remarks\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(REDIRECT $tcp_port TPROXY4) comment \"$remarks\"" + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$black6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$gfw6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${chn_list} "counter jump PSW_RULE") comment \"$remarks\" " + [ "${use_shunt_tcp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$shunt6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(REDIRECT $tcp_port TPROXY) comment \"$remarks\"" 2>/dev/null + } + else + msg2="${msg}ä¸ä»£ç† TCP" + fi + echolog " - ${msg2}" + } + + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null + + [ -n "$udp_port" ] && { + if [ -n "${udp_proxy_mode}" ]; then + msg2="${msg}使用 UDP 节点[$udp_node_remark]" + msg2="${msg2}(TPROXY:${udp_port})" + + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW_RULE comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr @$black_set_name counter jump PSW_RULE comment \"$remarks\"" + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr @$gfw_set_name counter jump PSW_RULE comment \"$remarks\"" + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${chn_list} "counter jump PSW_RULE") comment \"$remarks\"" + [ "${use_shunt_udp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr @$shunt_set_name counter jump PSW_RULE comment \"$remarks\"" + [ "${udp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(REDIRECT $udp_port TPROXY4) comment \"$remarks\"" + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + [ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"$remarks\"" + [ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$black6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$gfw6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${chn_list}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${chn_list} "counter jump PSW_RULE") comment \"$remarks\"" 2>/dev/null + [ "${use_shunt_udp}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$shunt6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + [ "${udp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(REDIRECT $udp_port TPROXY) comment \"$remarks\"" 2>/dev/null + } + else + msg2="${msg}ä¸ä»£ç† UDP" + fi + echolog " - ${msg2}" + } + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null + unset nft_chain nft_j _ipt_source msg msg2 _ipv4 + done + unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface + unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp dns_redirect use_fakedns + done + } + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && { + msg="ã€é»˜è®¤ã€‘," + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\"" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† TCP 端å£[${TCP_NO_REDIR_PORTS}]" + else + unset TCP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ TCP 端å£" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\"" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† UDP 端å£[${UDP_NO_REDIR_PORTS}]" + else + unset UDP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ UDP 端å£" + fi + } + + local DNS_REDIRECT + [ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53 + if ([ -n "$TCP_NODE" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${UDP_PROXY_MODE}" ]); then + [ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT} + else + [ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT} + fi + + if [ -n "${DNS_REDIRECT}" ]; then + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp udp dport 53 counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp udp dport 53 counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp tcp dport 53 counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp tcp dport 53 counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp udp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp tcp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp udp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp tcp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\"" + fi + + [ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && { + [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_BLOCK counter drop comment \"默认\"" + [ "${USE_BLOCK_LIST}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_BLOCK counter drop comment \"默认\"" + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_WHITE counter return comment \"默认\"" + [ "${USE_DIRECT_LIST}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_WHITE counter return comment \"默认\"" + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_BLOCK6 counter drop comment \"默认\"" + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_WHITE6 counter return comment \"默认\"" + } + + [ "$TCP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr @$NFTSET_BLACK6 counter drop comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr @$NFTSET_GFW6 counter drop comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${CHN_LIST} "counter drop") comment \"默认\"" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr @$NFTSET_SHUNT6 counter drop comment \"默认\"" + [ "${TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop comment \"默认\"" + } + + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip daddr $FAKE_IP counter drop comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip daddr @$NFTSET_BLACK counter drop comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip daddr @$NFTSET_GFW counter drop comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${CHN_LIST} "counter drop") comment \"默认\"" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip daddr @$NFTSET_SHUNT counter drop comment \"默认\"" + [ "${TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop comment \"默认\"" + echolog " - ${msg}å±è”½ä»£ç† TCP 端å£[${TCP_PROXY_DROP_PORTS}]" + } + + [ "$UDP_PROXY_DROP_PORTS" != "disable" ] && { + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr @$NFTSET_BLACK6 counter drop comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr @$NFTSET_GFW6 counter drop comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${CHN_LIST} "counter drop") comment \"默认\"" + [ "${USE_SHUNT_UDP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr @$NFTSET_SHUNT6 counter drop comment \"默认\"" + [ "${UDP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop comment \"默认\"" + } + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip daddr $FAKE_IP counter drop comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip daddr @$NFTSET_BLACK counter drop comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip daddr @$NFTSET_GFW counter drop comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${CHN_LIST} "counter drop") comment \"默认\"" + [ "${USE_SHUNT_UDP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip daddr @$NFTSET_SHUNT counter drop comment \"默认\"" + [ "${UDP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop comment \"默认\"" + echolog " - ${msg}å±è”½ä»£ç† UDP 端å£[${UDP_PROXY_DROP_PORTS}]" + } + } + + # 加载TCPé»˜è®¤ä»£ç†æ¨¡å¼ + if [ -n "${TCP_PROXY_MODE}" ]; then + [ -n "$TCP_NODE" ] && { + if is_socks_wrap "$TCP_NODE"; then + msg2="${msg}使用 TCP 节点[Socks é…ç½®($(config_n_get ${TCP_NODE#Socks_} port) 端å£)]" + else + msg2="${msg}使用 TCP 节点[$(config_n_get $TCP_NODE remarks)]" + fi + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${TCP_REDIR_PORT})" + nft_chain="PSW_MANGLE" + nft_j="counter jump PSW_RULE" + else + msg2="${msg2}(REDIRECT:${TCP_REDIR_PORT})" + nft_chain="PSW_NAT" + nft_j="$(REDIRECT $TCP_REDIR_PORT)" + fi + + [ "$accept_icmp" = "1" ] && { + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip daddr @$NFTSET_WHITE counter return comment \"默认\"" + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ip daddr $FAKE_IP $(REDIRECT) comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ip daddr @$NFTSET_BLACK $(REDIRECT) comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ip daddr @$NFTSET_GFW $(REDIRECT) comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ip daddr @$NFTSET_CHN $(get_jump_nft ${CHN_LIST}) comment \"默认\"" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ip daddr @$NFTSET_SHUNT $(REDIRECT) comment \"默认\"" + [ "${TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp $(REDIRECT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp return comment \"默认\"" + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip6 daddr @$NFTSET_WHITE6 counter return comment \"默认\"" + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr @$NFTSET_BLACK6 $(REDIRECT) comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr @$NFTSET_GFW6 $(REDIRECT) comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${CHN_LIST}) comment \"默认\"" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr @$NFTSET_SHUNT6 $(REDIRECT) comment \"默认\"" + [ "${TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 $(REDIRECT) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 return comment \"默认\"" + } + + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j} comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr @$NFTSET_BLACK ${nft_j} comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr @$NFTSET_GFW ${nft_j} comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${CHN_LIST} "${nft_j}") comment \"默认\"" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr @$NFTSET_SHUNT ${nft_j} comment \"默认\"" + [ "${TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j} comment \"默认\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(REDIRECT $TCP_REDIR_PORT TPROXY4) comment \"默认\"" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp counter return comment \"默认\"" + + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr @$NFTSET_BLACK6 counter jump PSW_RULE comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr @$NFTSET_GFW6 counter jump PSW_RULE comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${CHN_LIST} "counter jump PSW_RULE") comment \"默认\"" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr @$NFTSET_SHUNT6 counter jump PSW_RULE comment \"默认\"" + [ "${TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(REDIRECT $TCP_REDIR_PORT TPROXY) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp counter return comment \"默认\"" + } + + echolog " - ${msg2}" + } + fi + + # 加载UDPé»˜è®¤ä»£ç†æ¨¡å¼ + if [ -n "${UDP_PROXY_MODE}" ]; then + [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ] && { + if is_socks_wrap "$UDP_NODE"; then + msg2="${msg}使用 UDP 节点[Socks é…ç½®($(config_n_get ${UDP_NODE#Socks_} port) 端å£)](TPROXY:${UDP_REDIR_PORT})" + else + msg2="${msg}使用 UDP 节点[$(config_n_get $UDP_NODE remarks)](TPROXY:${UDP_REDIR_PORT})" + fi + + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW_RULE comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr @$NFTSET_BLACK counter jump PSW_RULE comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr @$NFTSET_GFW counter jump PSW_RULE comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr @$NFTSET_CHN $(get_jump_nft ${CHN_LIST} "counter jump PSW_RULE") comment \"默认\"" + [ "${USE_SHUNT_UDP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr @$NFTSET_SHUNT counter jump PSW_RULE comment \"默认\"" + [ "${UDP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(REDIRECT $UDP_REDIR_PORT TPROXY4) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp counter return comment \"默认\"" + + [ "$PROXY_IPV6" == "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"默认\"" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr @$NFTSET_BLACK6 counter jump PSW_RULE comment \"默认\"" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr @$NFTSET_GFW6 counter jump PSW_RULE comment \"默认\"" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${CHN_LIST} "counter jump PSW_RULE") comment \"默认\"" + [ "${USE_SHUNT_UDP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr @$NFTSET_SHUNT6 counter jump PSW_RULE comment \"默认\"" + [ "${UDP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(REDIRECT $UDP_REDIR_PORT TPROXY) comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp counter return comment \"默认\"" + } + + echolog " - ${msg2}" + } + fi + } +} + +filter_haproxy() { + for item in ${haproxy_items}; do + get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1 + done | insert_nftset $NFTSET_VPS "-1" + echolog " - [$?]加入负载å‡è¡¡çš„节点到nftset[$NFTSET_VPS]直连完æˆ" +} + +filter_vps_addr() { + for server_host in "$@"; do + get_host_ip "ipv4" ${server_host} + done | insert_nftset $NFTSET_VPS "-1" + + for server_host in "$@"; do + get_host_ip "ipv6" ${server_host} + done | insert_nftset $NFTSET_VPS6 "-1" +} + +filter_vpsip() { + local EXCLUDE_VPSIP="^(127\.0\.0\.1|1\.1\.1\.1|1\.1\.1\.2|8\.8\.8\.8|8\.8\.4\.4|9\.9\.9\.9)$" + uci show $CONFIG | grep -E "(\.address=|\.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -Ev "$EXCLUDE_VPSIP" | insert_nftset $NFTSET_VPS "-1" + echolog " - [$?]加入所有IPv4节点到nftset[$NFTSET_VPS]直连完æˆ" + uci show $CONFIG | grep -E "(\.address=|\.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_VPS6 "-1" + echolog " - [$?]加入所有IPv6节点到nftset[$NFTSET_VPS6]直连完æˆ" + #订阅方å¼ä¸ºç›´è¿žæ—¶ + get_subscribe_host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -Ev "$EXCLUDE_VPSIP" | insert_nftset $NFTSET_VPS "-1" + get_subscribe_host | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_VPS6 "-1" +} + +filter_server_port() { + local address="$1" + local port=$(echo "$2" | tr ':' '-' | tr -d ' ') + local stream=$(echo "$3" | tr 'A-Z' 'a-z') + local _ip_type _port_expr _ver _is_tproxy + local _nft_output_chain="PSW_OUTPUT_NAT" + [ "$(config_t_get global_forwarding tcp_proxy_way redirect)" = "tproxy" ] && _is_tproxy="TPROXY" + [ "$stream" = "udp" ] && _is_tproxy="TPROXY" + [ -n "$_is_tproxy" ] && _nft_output_chain="PSW_OUTPUT_MANGLE" + case "$port" in + *,*) _port_expr="{ $port }" ;; + *) _port_expr="$port" ;; + esac + for _ver in 4 6; do + [ "$_ver" = "4" ] && _ip_type="ip" + [ "$_ver" = "6" ] && _ip_type="ip6" && _nft_output_chain="PSW_OUTPUT_MANGLE_V6" + nft list chain "$NFTABLE_NAME" "$_nft_output_chain" 2>/dev/null | grep -q "comment \"${address}:${port}:${stream}\"" || \ + nft insert rule "$NFTABLE_NAME" "$_nft_output_chain" meta l4proto "$stream" $_ip_type daddr "$address" "$stream" dport $_port_expr return comment "\"${address}:${port}:${stream}\"" 2>/dev/null + done +} + +filter_node() { + local node="$1" stream="$2" + [ -z "$node" ] && return 1 + local address=$(config_n_get "$node" address) + local port=$(config_n_get "$node" port) + local hop=$(config_n_get "$node" hysteria2_hop) + [ -n "$hop" ] && port="${port:+$port,}$hop" + [ -z "$address" -o -z "$port" ] && return 1 + filter_server_port "$address" "$port" "$stream" +} + +filter_direct_node_list() { + [ ! -s "$TMP_PATH/direct_node_list" ] && return + awk '!seen[$0]++' "$TMP_PATH/direct_node_list" | while read -r _node_id; do + filter_node "$_node_id" TCP + filter_node "$_node_id" UDP + unset _node_id + done +} + + +del_script_mwan3() { + [ -s "/etc/init.d/mwan3" ] && sed -i "/${CONFIG}/d" /etc/init.d/mwan3 >/dev/null 2>&1 +} + +add_script_mwan3() { + del_script_mwan3 + [ -s "/etc/init.d/mwan3" ] && { + sed -i '/start_service()/,/}/ s/^}/ \/usr\/share\/passwall\/nftables.sh mwan3_start\n}/' /etc/init.d/mwan3 + sed -i '/stop_service().*{/a \ \/usr\/share\/passwall\/nftables.sh mwan3_stop' /etc/init.d/mwan3 + } +} + +mwan3_stop() { + local handles=$(nft -a list chain ip mangle mwan3_hook 2>/dev/null | grep "${FWMARK}" | awk -F '# handle ' '{print$2}') + for handle in $handles; do + nft delete rule ip mangle mwan3_hook handle ${handle} 2>/dev/null + done +} + +mwan3_start() { + mwan3_stop + nft list chain ip mangle mwan3_hook >/dev/null 2>&1 && nft insert rule ip mangle mwan3_hook ct mark ${FWMARK} counter return >/dev/null 2>&1 +} + +update_wan_sets() { + local log=$1 + + [ -z "$(command -v get_wan_ips)" ] && . "$UTILS_PATH" + + local WAN_IP=$(get_wan_ips ip4) + [ -n "$WAN_IP" ] && { + nft flush set $NFTABLE_NAME $NFTSET_WAN + echo "$WAN_IP" | insert_nftset $NFTSET_WAN "-1" + [ "$log" = "log" ] && { + local wan_ip + for wan_ip in $WAN_IP; do + echolog " - [$?]加入WAN IPv4到nftset[$NFTSET_WAN]:${wan_ip}" + done + } + } + + local WAN6_IP=$(get_wan_ips ip6) + [ -n "${WAN6_IP}" ] && { + nft flush set $NFTABLE_NAME $NFTSET_WAN6 + echo "$WAN6_IP" | insert_nftset $NFTSET_WAN6 "-1" + [ "$log" = "log" ] && { + local wan6_ip + for wan6_ip in $WAN6_IP; do + echolog " - [$?]加入WAN IPv6到nftset[$NFTSET_WAN6]:${wan6_ip}" + done + } + } +} + +add_firewall_rule() { + echolog "开始加载 nftables 防ç«å¢™è§„则..." + gen_nft_tables + add_script_mwan3 + mwan3_start + gen_nftset $NFTSET_WAN ipv4_addr 0 "-1" + gen_nftset $NFTSET_VPS ipv4_addr 0 "-1" + gen_nftset $NFTSET_GFW ipv4_addr "2d" 0 + gen_nftset $NFTSET_LOCAL ipv4_addr 0 "-1" + gen_nftset $NFTSET_LAN ipv4_addr 0 "-1" $(gen_lanlist) + if [ -f $RULES_PATH/chnroute.nft ] && [ -s $RULES_PATH/chnroute.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute.nft) -ge 8 ]; then + #echolog "使用缓存加载chnroute..." + nft -f $RULES_PATH/chnroute.nft + else + cat $RULES_PATH/chnroute | tr -s '\n' | grep -v "^#" | gen_nftset $NFTSET_CHN ipv4_addr "2d" 0 + fi + gen_nftset $NFTSET_BLACK ipv4_addr "2d" 0 + gen_nftset $NFTSET_WHITE ipv4_addr "2d" 0 + gen_nftset $NFTSET_BLOCK ipv4_addr "2d" 0 + gen_nftset $NFTSET_SHUNT ipv4_addr "2d" 0 + + gen_nftset $NFTSET_WAN6 ipv6_addr 0 "-1" + gen_nftset $NFTSET_VPS6 ipv6_addr 0 "-1" + gen_nftset $NFTSET_GFW6 ipv6_addr "2d" 0 + gen_nftset $NFTSET_LOCAL6 ipv6_addr 0 "-1" + gen_nftset $NFTSET_LAN6 ipv6_addr 0 "-1" $(gen_lanlist_6) + if [ -f $RULES_PATH/chnroute6.nft ] && [ -s $RULES_PATH/chnroute6.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute6.nft) -ge 8 ]; then + #echolog "使用缓存加载chnroute6..." + nft -f $RULES_PATH/chnroute6.nft + else + cat $RULES_PATH/chnroute6 | tr -s '\n' | grep -v "^#" | gen_nftset $NFTSET_CHN6 ipv6_addr "2d" 0 + fi + gen_nftset $NFTSET_BLACK6 ipv6_addr "2d" 0 + gen_nftset $NFTSET_WHITE6 ipv6_addr "2d" 0 + gen_nftset $NFTSET_BLOCK6 ipv6_addr "2d" 0 + gen_nftset $NFTSET_SHUNT6 ipv6_addr "2d" 0 + + #导入规则列表ã€åˆ†æµè§„则中的IP列表 + local USE_SHUNT_NODE=0 + local USE_PROXY_LIST_ALL=${USE_PROXY_LIST} + local USE_DIRECT_LIST_ALL=${USE_DIRECT_LIST} + local USE_BLOCK_LIST_ALL=${USE_BLOCK_LIST} + local _TCP_NODE=$(config_t_get global tcp_node) + local _UDP_NODE=$(config_t_get global udp_node) + local USE_GEOVIEW=$(config_t_get global_rules enable_geoview) + [ -z "$(first_type $(config_t_get global_app geoview_file) geoview)" ] && USE_GEOVIEW=0 + + [ -n "$_TCP_NODE" ] && [ "$(config_n_get $_TCP_NODE protocol)" = "_shunt" ] && USE_SHUNT_TCP=1 && USE_SHUNT_NODE=1 + [ -n "$_UDP_NODE" ] && [ "$(config_n_get $_UDP_NODE protocol)" = "_shunt" ] && USE_SHUNT_UDP=1 && USE_SHUNT_NODE=1 + [ "$_UDP_NODE" = "tcp" ] && USE_SHUNT_UDP=$USE_SHUNT_TCP + + for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + [ "$(config_n_get $acl_section enabled)" != "1" ] && continue + [ "$(config_n_get $acl_section use_global_config 0)" != "1" ] && { + [ "$(config_n_get $acl_section use_direct_list 1)" = "1" ] && USE_PROXY_LIST_ALL=1 + [ "$(config_n_get $acl_section use_proxy_list 1)" = "1" ] && USE_DIRECT_LIST_ALL=1 + [ "$(config_n_get $acl_section use_block_list 1)" = "1" ] && USE_BLOCK_LIST_ALL=1 + } + for _node in $(config_n_get $acl_section tcp_node) $(config_n_get $acl_section udp_node); do + local node_protocol=$(config_n_get $_node protocol) + [ "$node_protocol" = "_shunt" ] && { USE_SHUNT_NODE=1; break; } + done + done + + #直连列表 + [ "$USE_DIRECT_LIST_ALL" = "1" ] && { + cat $RULES_PATH/direct_ip | grep -v "^#" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_WHITE "0" + cat $RULES_PATH/direct_ip | grep -v "^#" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_WHITE6 "0" + [ "$USE_GEOVIEW" = "1" ] && { + local GEOIP_CODE=$(cat $RULES_PATH/direct_ip | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_WHITE "0" + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_WHITE6 "0" + echolog " - [$?]è§£æžå¹¶åŠ å…¥[直连列表] GeoIP 到 NFTSET 完æˆ" + fi + } + } + + #代ç†åˆ—表 + [ "$USE_PROXY_LIST_ALL" = "1" ] && { + cat $RULES_PATH/proxy_ip | grep -v "^#" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_BLACK "0" + cat $RULES_PATH/proxy_ip | grep -v "^#" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_BLACK6 "0" + [ "$USE_GEOVIEW" = "1" ] && { + local GEOIP_CODE=$(cat $RULES_PATH/proxy_ip | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_BLACK "0" + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_BLACK6 "0" + echolog " - [$?]è§£æžå¹¶åŠ å…¥[代ç†åˆ—表] GeoIP 到 NFTSET 完æˆ" + fi + } + } + + #å±è”½åˆ—表 + [ "$USE_BLOCK_LIST_ALL" = "1" ] && { + cat $RULES_PATH/block_ip | grep -v "^#" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_BLOCK "0" + cat $RULES_PATH/block_ip | grep -v "^#" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_BLOCK6 "0" + [ "$USE_GEOVIEW" = "1" ] && { + local GEOIP_CODE=$(cat $RULES_PATH/block_ip | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_BLOCK "0" + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_BLOCK6 "0" + echolog " - [$?]è§£æžå¹¶åŠ å…¥[å±è”½åˆ—表] GeoIP 到 NFTSET 完æˆ" + fi + } + } + + #分æµåˆ—表 + [ "$USE_SHUNT_NODE" = "1" ] && { + local GEOIP_CODE="" + local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') + for shunt_id in $shunt_ids; do + config_n_get $shunt_id ip_list | grep -v "^#" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_SHUNT "0" + config_n_get $shunt_id ip_list | grep -v "^#" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_SHUNT6 "0" + [ "$USE_GEOVIEW" = "1" ] && { + local geoip_code=$(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$geoip_code" ] && GEOIP_CODE="${GEOIP_CODE:+$GEOIP_CODE,}$geoip_code" + } + done + if [ -n "$GEOIP_CODE" ]; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $NFTSET_SHUNT "0" + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_SHUNT6 "0" + echolog " - [$?]è§£æžå¹¶åŠ å…¥[分æµèŠ‚ç‚¹] GeoIP 到 NFTSET 完æˆ" + fi + } + + get_local_ips ip4 | insert_nftset $NFTSET_LOCAL "-1" + get_local_ips ip6 | insert_nftset $NFTSET_LOCAL6 "-1" + + # 忽略特殊IP段 + local lan_ifname lan_ip + lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname) + [ -n "$lan_ifname" ] && { + lan_ip=$(ip address show $lan_ifname | grep -w "inet" | awk '{print $2}') + lan_ip6=$(ip address show $lan_ifname | grep -w "inet6" | awk '{print $2}') + #echolog "本机IPv4网段互访直连:${lan_ip}" + #echolog "本机IPv6网段互访直连:${lan_ip6}" + + [ -n "$lan_ip" ] && echo $lan_ip | insert_nftset $NFTSET_LAN "-1" + [ -n "$lan_ip6" ] && echo $lan_ip6 | insert_nftset $NFTSET_LAN6 "-1" + } + + update_wan_sets "log" + + [ -n "$ISP_DNS" ] && { + #echolog "å¤„ç† ISP DNS 例外..." + echo "$ISP_DNS" | insert_nftset $NFTSET_WHITE 0 + for ispip in $ISP_DNS; do + echolog " - [$?]追加ISP IPv4 DNS到白åå•:${ispip}" + done + } + + [ -n "$ISP_DNS6" ] && { + #echolog "å¤„ç† ISP IPv6 DNS 例外..." + echo $ISP_DNS6 | insert_nftset $NFTSET_WHITE6 0 + for ispip6 in $ISP_DNS6; do + echolog " - [$?]追加ISP IPv6 DNS到白åå•:${ispip6}" + done + } + + # 过滤所有节点IP + filter_vpsip > /dev/null 2>&1 & + # filter_haproxy > /dev/null 2>&1 & + # Prevent some conditions + filter_vps_addr $(config_n_get $TCP_NODE address) $(config_n_get $UDP_NODE address) > /dev/null 2>&1 & + filter_vps_addr $(config_n_get $TCP_NODE download_address) $(config_n_get $UDP_NODE download_address) > /dev/null 2>&1 & + + accept_icmp=$(config_t_get global_forwarding accept_icmp 0) + accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0) + + if [ "${TCP_PROXY_WAY}" = "redirect" ]; then + unset is_tproxy + nft_prerouting_chain="PSW_NAT" + nft_output_chain="PSW_OUTPUT_NAT" + elif [ "${TCP_PROXY_WAY}" = "tproxy" ]; then + is_tproxy="TPROXY" + nft_prerouting_chain="PSW_MANGLE" + nft_output_chain="PSW_OUTPUT_MANGLE" + fi + + nft "add chain $NFTABLE_NAME PSW_DIVERT" + nft "flush chain $NFTABLE_NAME PSW_DIVERT" + # Only TCP, UDP Invalid. + nft "add rule $NFTABLE_NAME PSW_DIVERT meta l4proto tcp socket transparent 1 mark set ${FWMARK} counter accept" + + nft "add chain $NFTABLE_NAME PSW_DNS" + nft "flush chain $NFTABLE_NAME PSW_DNS" + if [ $(config_t_get global dns_redirect "1") = "0" ]; then + #Only hijack when dest address is local IP + nft "insert rule $NFTABLE_NAME dstnat ip saddr @${NFTSET_LAN} ip daddr @${NFTSET_LOCAL} jump PSW_DNS" + nft "insert rule $NFTABLE_NAME dstnat ip6 saddr @${NFTSET_LAN6} ip6 daddr @${NFTSET_LOCAL6} jump PSW_DNS" + else + nft "insert rule $NFTABLE_NAME dstnat ip saddr @${NFTSET_LAN} jump PSW_DNS" + nft "insert rule $NFTABLE_NAME dstnat ip6 saddr @${NFTSET_LAN6} jump PSW_DNS" + fi + + # for ipv4 ipv6 tproxy mark + nft "add chain $NFTABLE_NAME PSW_RULE" + nft "flush chain $NFTABLE_NAME PSW_RULE" + nft "add rule $NFTABLE_NAME PSW_RULE counter meta mark set ct mark" + nft "add rule $NFTABLE_NAME PSW_RULE meta mark ${FWMARK} counter return" + nft "add rule $NFTABLE_NAME PSW_RULE tcp flags & (fin|syn|rst|ack) == syn counter meta mark set ${FWMARK}" + nft "add rule $NFTABLE_NAME PSW_RULE meta l4proto udp ct state { new, related } counter meta mark set ${FWMARK}" + nft "add rule $NFTABLE_NAME PSW_RULE counter ct mark set mark" + + #ipv4 tproxy mode and udp + nft "add chain $NFTABLE_NAME PSW_MANGLE" + nft "flush chain $NFTABLE_NAME PSW_MANGLE" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW_MANGLE ct direction reply counter return" + + nft "add chain $NFTABLE_NAME PSW_OUTPUT_MANGLE" + nft "flush chain $NFTABLE_NAME PSW_OUTPUT_MANGLE" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_VPS counter return" + [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_BLOCK counter drop" + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_WHITE counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ct direction reply counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE meta mark 255 counter return" + + # jump chains + nft "add rule $NFTABLE_NAME mangle_prerouting counter jump PSW_DIVERT" + nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW_MANGLE" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW_MANGLE" + + #ipv4 tcp redirect mode + [ -z "${is_tproxy}" ] && { + nft "add chain $NFTABLE_NAME PSW_NAT" + nft "flush chain $NFTABLE_NAME PSW_NAT" + nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME dstnat ip protocol tcp counter jump PSW_NAT" + + nft "add chain $NFTABLE_NAME PSW_OUTPUT_NAT" + nft "flush chain $NFTABLE_NAME PSW_OUTPUT_NAT" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_NAT ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_NAT ip daddr @$NFTSET_VPS counter return" + [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_NAT ip daddr @$NFTSET_BLOCK counter drop" + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_NAT ip daddr @$NFTSET_WHITE counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_NAT meta mark 255 counter return" + } + + #icmp ipv6-icmp redirect + if [ "$accept_icmp" = "1" ]; then + nft "add chain $NFTABLE_NAME PSW_ICMP_REDIRECT" + nft "flush chain $NFTABLE_NAME PSW_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip daddr @$NFTSET_VPS counter return" + + [ "$accept_icmpv6" = "1" ] && { + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip6 daddr @$NFTSET_LAN6 counter return" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip6 daddr @$NFTSET_VPS6 counter return" + } + + nft "add rule $NFTABLE_NAME dstnat meta l4proto {icmp,icmpv6} counter jump PSW_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME nat_output meta l4proto {icmp,icmpv6} counter jump PSW_ICMP_REDIRECT" + fi + + #ipv4 wan_ip + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_WAN counter return comment \"WAN_IP_RETURN\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_WAN counter return comment \"WAN_IP_RETURN\"" + + ip rule add fwmark ${FWMARK} table 999 priority 999 + ip route add local 0.0.0.0/0 dev lo table 999 + + #ipv6 tproxy mode and udp + nft "add chain $NFTABLE_NAME PSW_MANGLE_V6" + nft "flush chain $NFTABLE_NAME PSW_MANGLE_V6" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ct direction reply counter return" + + nft "add chain $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6" + nft "flush chain $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_BLOCK6 counter drop" + [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_WHITE6 counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ct direction reply counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta mark 255 counter return" + + [ -n "$IPT_APPEND_DNS" ] && { + local local_dns dns_address dns_port + for local_dns in $(echo $IPT_APPEND_DNS | tr ',' ' '); do + dns_address=$(echo "$local_dns" | sed -E 's/(@|\[)?([0-9a-fA-F:.]+)(@|#|$).*/\2/') + dns_port=$(echo "$local_dns" | sed -nE 's/.*#([0-9]+)$/\1/p') + if echo "$dns_address" | grep -q -v ':'; then + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol tcp ip daddr ${dns_address} $(factor ${dns_port:-53} "tcp dport") counter return" + echolog " - [$?]追加直连DNS到nftables:${dns_address}:${dns_port:-53}" + else + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr ${dns_address} $(factor ${dns_port:-53} "tcp dport") counter return" + echolog " - [$?]追加直连DNS到nftables:[${dns_address}]:${dns_port:-53}" + fi + done + } + + # jump chains + [ "$PROXY_IPV6" == "1" ] && { + nft "add rule $NFTABLE_NAME mangle_prerouting meta nfproto {ipv6} counter jump PSW_MANGLE_V6" + nft "add rule $NFTABLE_NAME mangle_output meta nfproto {ipv6} counter jump PSW_OUTPUT_MANGLE_V6 comment \"PSW_OUTPUT_MANGLE\"" + + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_WAN6 counter return comment \"WAN6_IP_RETURN\"" + + ip -6 rule add fwmark ${FWMARK} table 999 priority 999 + ip -6 route add local ::/0 dev lo table 999 + } + + [ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && { + msg="ã€è·¯ç”±å™¨æœ¬æœºã€‘," + + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† TCP 端å£[${TCP_NO_REDIR_PORTS}]" + else + unset LOCALHOST_TCP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ TCP 端å£" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + echolog " - ${msg}ä¸ä»£ç† UDP 端å£[${UDP_NO_REDIR_PORTS}]" + else + unset LOCALHOST_UDP_PROXY_MODE + echolog " - ${msg}ä¸ä»£ç†æ‰€æœ‰ UDP 端å£" + fi + } + + if ([ -n "$TCP_NODE" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ -n "$UDP_NODE" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then + [ -n "$DNS_REDIRECT_PORT" ] && { + nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW_DNS\"" + nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW_DNS\"" + nft "add rule $NFTABLE_NAME nat_output meta l4proto udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW_DNS\"" + nft "add rule $NFTABLE_NAME nat_output meta l4proto tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW_DNS\"" + } + fi + + [ -n "${LOCALHOST_TCP_PROXY_MODE}" -o -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { + [ "$TCP_PROXY_DROP_PORTS" != "disable" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr $FAKE_IP $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop + [ "${USE_PROXY_LIST}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr @$NFTSET_BLACK $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop + [ "${USE_GFW_LIST}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr @$NFTSET_GFW $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop + [ "${CHN_LIST}" != "0" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr @$NFTSET_CHN $(factor $TCP_PROXY_DROP_PORTS "tcp dport") $(get_jump_nft ${CHN_LIST} "counter drop") + [ "${USE_SHUNT_TCP}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr @$NFTSET_SHUNT $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop + echolog " - ${msg}å±è”½ä»£ç† TCP 端å£[${TCP_PROXY_DROP_PORTS}]" + } + + [ "$UDP_PROXY_DROP_PORTS" != "disable" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop + [ "${USE_PROXY_LIST}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_BLACK $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop + [ "${USE_GFW_LIST}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_GFW $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop + [ "${CHN_LIST}" != "0" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_CHN $(factor $UDP_PROXY_DROP_PORTS "udp dport") $(get_jump_nft ${CHN_LIST} "counter drop") + [ "${USE_SHUNT_UDP}" = "1" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_SHUNT $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && nft add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") counter drop + echolog " - ${msg}å±è”½ä»£ç† UDP 端å£[${UDP_PROXY_DROP_PORTS}]" + } + } + + # åŠ è½½è·¯ç”±å™¨è‡ªèº«ä»£ç† TCP + if [ -n "$TCP_NODE" ]; then + _proxy_tcp_access() { + [ -n "${2}" ] || return 0 + if echo "${2}" | grep -q -v ':'; then + nft "get element $NFTABLE_NAME $NFTSET_LAN {${2}}" &>/dev/null + [ $? -eq 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ TCP 代ç†è½¬å‘对该æœåС噍 TCP/${3} 端å£çš„访问" + return 0 + } + if [ -z "${is_tproxy}" ]; then + nft insert rule $NFTABLE_NAME PSW_OUTPUT_NAT ip protocol tcp ip daddr ${2} tcp dport ${3} $(REDIRECT $TCP_REDIR_PORT) + else + nft insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol tcp ip daddr ${2} tcp dport ${3} counter jump PSW_RULE + nft insert rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp iif lo tcp dport ${3} ip daddr ${2} $(REDIRECT $TCP_REDIR_PORT TPROXY4) comment \"本机\" + fi + echolog " - [$?]将上游 DNS æœåС噍 ${2}:${3} 加入到路由器自身代ç†çš„ TCP 转å‘链" + else + nft "get element $NFTABLE_NAME $NFTSET_LAN6 {${2}}" &>/dev/null + [ $? -eq 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ TCP 代ç†è½¬å‘对该æœåС噍 TCP/${3} 端å£çš„访问" + return 0 + } + nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr ${2} tcp dport ${3} counter jump PSW_RULE" + nft "insert rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp iif lo tcp dport ${3} ip6 daddr ${2} $(REDIRECT $TCP_REDIR_PORT TPROXY6) comment \"本机\"" + echolog " - [$?]将上游 DNS æœåС噍 [${2}]:${3} 加入到路由器自身代ç†çš„ TCP 转å‘é“¾ï¼Œè¯·ç¡®ä¿æ‚¨çš„节点支æŒIPv6,并开å¯IPv6逿˜Žä»£ç†ï¼" + fi + } + [ "$TCP_PROXY_DNS" == 1 ] && hosts_foreach REMOTE_DNS _proxy_tcp_access 53 + + [ "$accept_icmp" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP counter redirect" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp ip daddr @$NFTSET_BLACK counter redirect" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp ip daddr @$NFTSET_GFW counter redirect" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp ip daddr @$NFTSET_CHN $(get_jump_nft ${CHN_LIST})" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp ip daddr @$NFTSET_SHUNT counter redirect" + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp counter redirect" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp counter return" + } + + [ "$accept_icmpv6" = "1" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 counter redirect" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr @$NFTSET_BLACK6 counter redirect" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr @$NFTSET_GFW6 counter redirect" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr @$NFTSET_CHN6 $(get_jump_nft ${CHN_LIST})" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr @$NFTSET_SHUNT6 counter redirect" + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter redirect" + nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter return" + } + + if [ -n "${is_tproxy}" ]; then + nft_chain="PSW_OUTPUT_MANGLE" + nft_j="counter jump PSW_RULE" + else + nft_chain="PSW_OUTPUT_NAT" + nft_j="$(REDIRECT $TCP_REDIR_PORT)" + fi + + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j}" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr @$NFTSET_BLACK $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr @$NFTSET_GFW $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr @$NFTSET_CHN $(factor $TCP_REDIR_PORTS "tcp dport") $(get_jump_nft ${CHN_LIST} "${nft_j}")" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr @$NFTSET_SHUNT $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp iif lo $(REDIRECT $TCP_REDIR_PORT TPROXY4) comment \"本机\"" + } + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp iif lo counter return comment \"本机\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_output ip protocol tcp counter jump PSW_OUTPUT_MANGLE comment \"PSW_OUTPUT_MANGLE\"" + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME nat_output ip protocol tcp counter jump PSW_OUTPUT_NAT" + + [ "$PROXY_IPV6" == "1" ] && { + [ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_BLACK6 $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_GFW6 $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW_RULE" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_CHN6 $(factor $TCP_REDIR_PORTS "tcp dport") $(get_jump_nft ${CHN_LIST} "counter jump PSW_RULE")" + [ "${USE_SHUNT_TCP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_SHUNT6 $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW_RULE" + [ "${LOCALHOST_TCP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW_RULE" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $TCP_REDIR_PORT TPROXY) comment \"本机\"" + } + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"本机\"" + } + fi + + # åŠ è½½è·¯ç”±å™¨è‡ªèº«ä»£ç† UDP + if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then + _proxy_udp_access() { + [ -n "${2}" ] || return 0 + if echo "${2}" | grep -q -v ':'; then + nft "get element $NFTABLE_NAME $NFTSET_LAN {${2}}" &>/dev/null + [ $? == 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ UDP 代ç†è½¬å‘对该æœåС噍 UDP/${3} 端å£çš„访问" + return 0 + } + nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr ${2} udp dport ${3} counter jump PSW_RULE" + nft "insert rule $NFTABLE_NAME PSW_MANGLE ip protocol udp iif lo ip daddr ${2} $(REDIRECT $UDP_REDIR_PORT TPROXY4) comment \"本机\"" + echolog " - [$?]将上游 DNS æœåС噍 ${2}:${3} 加入到路由器自身代ç†çš„ UDP 转å‘链" + else + nft "get element $NFTABLE_NAME $NFTSET_LAN6 {${2}}" &>/dev/null + [ $? == 0 ] && { + echolog " - 上游 DNS æœåС噍 ${2} 已在直接访问的列表中,ä¸å¼ºåˆ¶å‘ UDP 代ç†è½¬å‘对该æœåС噍 UDP/${3} 端å£çš„访问" + return 0 + } + nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr ${2} udp dport ${3} counter jump PSW_RULE" + nft "insert rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp iif lo ip6 daddr ${2} $(REDIRECT $UDP_REDIR_PORT TPROXY6) comment \"本机\"" + echolog " - [$?]将上游 DNS æœåС噍 [${2}]:${3} 加入到路由器自身代ç†çš„ UDP 转å‘é“¾ï¼Œè¯·ç¡®ä¿æ‚¨çš„节点支æŒIPv6,并开å¯IPv6逿˜Žä»£ç†ï¼" + fi + } + [ -n "${UDP_PROXY_DNS}" ] && hosts_foreach REMOTE_DNS _proxy_udp_access 53 + [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW_RULE" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_BLACK $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_GFW $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_CHN $(factor $UDP_REDIR_PORTS "udp dport") $(get_jump_nft ${CHN_LIST} "counter jump PSW_RULE")" + [ "${USE_SHUNT_UDP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_SHUNT $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp iif lo $(REDIRECT $UDP_REDIR_PORT TPROXY4) comment \"本机\"" + } + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp iif lo counter return comment \"本机\"" + nft "add rule $NFTABLE_NAME mangle_output ip protocol udp counter jump PSW_OUTPUT_MANGLE comment \"PSW_OUTPUT_MANGLE\"" + + [ "$PROXY_IPV6" == "1" ] && { + [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && { + [ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE" + [ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_BLACK6 $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + [ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_GFW6 $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + [ "${CHN_LIST}" != "0" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_CHN6 $(factor $UDP_REDIR_PORTS "udp dport") $(get_jump_nft ${CHN_LIST} "counter jump PSW_RULE")" + [ "${USE_SHUNT_UDP}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_SHUNT6 $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + [ "${LOCALHOST_UDP_PROXY_MODE}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $UDP_REDIR_PORT TPROXY) comment \"本机\"" + } + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp iif lo counter return comment \"本机\"" + } + fi + + nft "add rule $NFTABLE_NAME mangle_output oif lo counter return comment \"PSW_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME mangle_output meta mark ${FWMARK} counter return comment \"PSW_OUTPUT_MANGLE\"" + } + + # 加载ACLS + load_acl + + [ -d "${TMP_IFACE_PATH}" ] && { + for iface in $(ls ${TMP_IFACE_PATH}); do + nft "add rule $NFTABLE_NAME $nft_output_chain oif $iface counter return" + nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 oif $iface counter return" + done + } + + filter_direct_node_list > /dev/null 2>&1 & + + echolog "防ç«å¢™è§„则加载完æˆï¼" +} + +del_firewall_rule() { + for nft in "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do + local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW_" | awk -F '# handle ' '{print$2}') + for handle in $handles; do + nft delete rule $NFTABLE_NAME ${nft} handle ${handle} 2>/dev/null + done + done + + for handle in $(nft -a list chains | grep -E "chain PSW_" | grep -v "PSW_RULE" | awk -F '# handle ' '{print$2}'); do + nft delete chain $NFTABLE_NAME handle ${handle} 2>/dev/null + done + + # Need to be removed at the end, otherwise it will show "Resource busy" + nft delete chain $NFTABLE_NAME handle $(nft -a list chains | grep -E "PSW_RULE" | awk -F '# handle ' '{print$2}') 2>/dev/null + + ip rule del fwmark ${FWMARK} 2>/dev/null + ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null + + ip -6 rule del fwmark ${FWMARK} 2>/dev/null + ip -6 route del local ::/0 dev lo table 999 2>/dev/null + + destroy_nftset $NFTSET_LOCAL + destroy_nftset $NFTSET_WAN + destroy_nftset $NFTSET_LAN + destroy_nftset $NFTSET_VPS + #destroy_nftset $NFTSET_SHUNT + #destroy_nftset $NFTSET_GFW + #destroy_nftset $NFTSET_CHN + #destroy_nftset $NFTSET_BLACK + destroy_nftset $NFTSET_BLOCK + destroy_nftset $NFTSET_WHITE + + destroy_nftset $NFTSET_LOCAL6 + destroy_nftset $NFTSET_WAN6 + destroy_nftset $NFTSET_LAN6 + destroy_nftset $NFTSET_VPS6 + #destroy_nftset $NFTSET_SHUNT6 + #destroy_nftset $NFTSET_GFW6 + #destroy_nftset $NFTSET_CHN6 + #destroy_nftset $NFTSET_BLACK6 + destroy_nftset $NFTSET_BLOCK6 + destroy_nftset $NFTSET_WHITE6 + + del_script_mwan3 + + echolog "删除 nftables 规则完æˆã€‚" +} + +flush_nftset() { + echolog "清空 NFTSet。" + for _name in $(nft -a list sets | grep -E "psw_" | awk -F 'set ' '{print $2}' | awk '{print $1}'); do + destroy_nftset ${_name} + done +} + +flush_table() { + nft flush table $NFTABLE_NAME + nft delete table $NFTABLE_NAME +} + +flush_include() { + echo '#!/bin/sh' >$FWI +} + +gen_include() { + flush_include + local nft_chain_file=$TMP_PATH/PSW_RULE.nft + echo '#!/bin/sh' > $nft_chain_file + nft list table $NFTABLE_NAME >> $nft_chain_file + + local __nft=" " + __nft=$(cat <<- EOF + + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW_DIVERT)" ] && nft -f ${nft_chain_file} + + ${MY_PATH} update_wan_sets + EOF + ) + + cat <<-EOF >> $FWI + ${__nft} + + return 0 + EOF + return 0 +} + +start() { + [ "$ENABLED_DEFAULT_ACL" == 0 -a "$ENABLED_ACLS" == 0 ] && return + add_firewall_rule + gen_include +} + +stop() { + [ -z "$(command -v echolog)" ] && . "$UTILS_PATH" + del_firewall_rule + [ $(config_t_get global flush_set_on_reboot "0") = "1" -o $(config_t_get global flush_set "0") = "1" ] && { + uci -q delete ${CONFIG}.@global[0].flush_set + uci -q commit ${CONFIG} + #flush_table + flush_nftset + rm -rf $TMP_PATH2/singbox* + rm -rf $TMP_PATH2/dnsmasq* + rm -rf $TMP_PATH2/geo_output + } + flush_include +} + +arg1=$1 +shift +case $arg1 in +insert_nftset) + insert_nftset "$@" + ;; +filter_direct_node_list) + filter_direct_node_list + ;; +mwan3_start) + mwan3_start + ;; +mwan3_stop) + mwan3_stop + ;; +update_wan_sets) + update_wan_sets "$@" + ;; +stop) + stop + ;; +start) + start + ;; +*) ;; +esac diff --git a/luci-app-passwall/root/usr/share/passwall/rule_update.lua b/luci-app-passwall/root/usr/share/passwall/rule_update.lua new file mode 100755 index 00000000..d022b9ec --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rule_update.lua @@ -0,0 +1,801 @@ +#!/usr/bin/lua + +local api = require ("luci.passwall.api") +local name = api.appname +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local fs = api.fs + +local arg1 = arg[1] +local arg2 = arg[2] +local arg3 = arg[3] + +local nftable_name = "inet passwall" +local rule_path = "/usr/share/" .. name .. "/rules" +local reboot = 0 +local gfwlist_update = "0" +local chnroute_update = "0" +local chnroute6_update = "0" +local chnlist_update = "0" +local geoip_update = "0" +local geosite_update = "0" + +local excluded_domain = {"apple.com","sina.cn","sina.com.cn","baidu.com","byr.cn","jlike.com","weibo.com","zhongsou.com","youdao.com","sogou.com","so.com","soso.com","aliyun.com","taobao.com","jd.com","qq.com","bing.com"} + +local gfwlist_url = uci:get(name, "@global_rules[0]", "gfwlist_url") or {"https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt"} +local chnroute_url = uci:get(name, "@global_rules[0]", "chnroute_url") or {"https://ispip.clang.cn/all_cn.txt"} +local chnroute6_url = uci:get(name, "@global_rules[0]", "chnroute6_url") or {"https://ispip.clang.cn/all_cn_ipv6.txt"} +local chnlist_url = uci:get(name, "@global_rules[0]", "chnlist_url") or {"https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf"} +local geoip_url = uci:get(name, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat" +local geosite_url = uci:get(name, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" +local asset_location = uci:get(name, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/" +local geo2rule = uci:get(name, "@global_rules[0]", "geo2rule") or "0" +local geoip_update_ok, geosite_update_ok = false, false +asset_location = asset_location:match("/$") and asset_location or (asset_location .. "/") +local backup_path = "/tmp/bak_v2ray/" +local rollback = false + +if arg3 == "cron" then + arg2 = nil +elseif arg3 == "rollback" then + rollback, geoip_update_ok, geosite_update_ok = true, true, true +end + +local log = function(...) + if arg1 then + if arg1 == "log" then + api.log(...) + elseif arg1 == "print" then + local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + print(result) + end + end +end + +--gen cache for nftset from file +local function gen_cache(set_name, ip_type, input_file, output_file) + local tmp_set_name = set_name .. "_tmp_" .. os.time() + local f_in = io.open(input_file, "r") + if not f_in then return false end + local nft_pipe = io.popen("nft -f -", "w") + if not nft_pipe then + f_in:close() + return false + end + nft_pipe:write('#!/usr/sbin/nft -f\n') + nft_pipe:write(string.format('add table %s\n', nftable_name)) + nft_pipe:write(string.format('add set %s %s { type %s; flags interval, timeout; timeout 2d; gc-interval 1h; auto-merge; }\n', nftable_name, tmp_set_name, ip_type)) + nft_pipe:write(string.format('add element %s %s { ', nftable_name, tmp_set_name)) + local count = 0 + local batch_size = 500 + for line in f_in:lines() do + local ip = line:match("^%s*(.-)%s*$") + if ip and ip ~= "" then + nft_pipe:write(ip, "timeout 365d, ") + count = count + 1 + if count % batch_size == 0 then + nft_pipe:write("}\n") + nft_pipe:write(string.format('add element %s %s { ', nftable_name, tmp_set_name)) + end + end + end + nft_pipe:write("}\n") + f_in:close() + + local success = nft_pipe:close() + if not (success == true or success == 0) then + os.execute(string.format('nft delete set %s %s 2>/dev/null', nftable_name, tmp_set_name)) + return false + end + os.execute(string.format('nft list set %s %s | sed "s/%s/%s/g" > %s', nftable_name, tmp_set_name, tmp_set_name, set_name, output_file)) + os.execute(string.format('nft delete set %s %s 2>/dev/null', nftable_name, tmp_set_name)) +end + +-- curl +local function curl(url, file) + local http_code = 0 + local header_str = "" + local args = { + "-fskL", + "--retry 3", + "--connect-timeout 3", + "--max-time 300", + "--speed-limit 51200 --speed-time 15", + '-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"', + "--dump-header -", + "-w '\\n%{http_code}'" + } + if file then + args[#args + 1] = "-o " .. file + end + local return_code, result = api.curl_auto(url, nil, args) + if result and result ~= "" then + local body, code = result:match("^(.-)%s*([0-9]+)$") + if code then + http_code = tonumber(code) or 0 + header_str = body + else + http_code = tonumber(result:match("(%d+)%s*$")) or 0 + end + end + if header_str ~= "" then + header_str = header_str:gsub("\r", "") + end + return return_code, http_code, header_str +end + +--check excluded domain +local excluded_map = {} +for _, d in ipairs(excluded_domain) do + excluded_map[d] = true +end +local function check_excluded_domain(value) + if not value or value == "" then return false end + value = value:lower() + local eq_pos = value:find("=", 1, true) + if eq_pos then + value = value:sub(eq_pos + 1) + end + if value:sub(1,1) == "/" then + value = value:sub(2) + end + local slash_pos = value:find("/", 1, true) + local colon_pos = value:find(":", 1, true) + local cut_pos + if slash_pos and colon_pos then + cut_pos = (slash_pos < colon_pos) and slash_pos or colon_pos + else + cut_pos = slash_pos or colon_pos + end + if cut_pos then + value = value:sub(1, cut_pos - 1) + end + value = value:gsub("^%.*", ""):gsub("%.*$", "") + while value do + if excluded_map[value] then + return true + end + local dot_pos = value:find(".", 1, true) + if not dot_pos then + break + end + value = value:sub(dot_pos + 1) + end + return false +end + +-- 替代 string.find 查找 "^[#!\\[@]+" +local function is_comment_line(s) + if not s or s == "" then return false end + local b = s:byte(1) + -- '#' = 35, '!' = 33, '\' = 92, '[' = 91, '@' = 64 + if b == 35 or b == 33 or b == 92 or b == 91 or b == 64 then + return true + end + return false +end + +-- IPv4 检测,替代 string.find "^%d+%.%d+%.%d+%.%d+" +-- IPv4 cidr检测,替代 string.find "^%d+%.%d+%.%d+%.%d+[%/][%d]+$" +local function is_ipv4(s, check_cidr) + local dot = 0 + local seg_start = 1 + local len = #s + local mask_start = nil + local i = 1 + while i <= len do + local b = s:byte(i) + if b >= 48 and b <= 57 then + -- 数字,继续 + elseif b == 46 then -- "." + dot = dot + 1 + if dot > 3 or i == seg_start then return false end + local seg = tonumber(s:sub(seg_start, i - 1)) + if not seg or seg > 255 then return false end + seg_start = i + 1 + elseif b == 47 then -- "/" + if not check_cidr then return false end + if dot ~= 3 or i == seg_start then return false end + local seg = tonumber(s:sub(seg_start, i - 1)) + if not seg or seg > 255 then return false end + mask_start = i + 1 + break + else + return false + end + i = i + 1 + end + -- 如果没有 CIDR,则检查最åŽä¸€æ®µå³å¯ + if not check_cidr or not mask_start then + if dot ~= 3 or seg_start > len then return false end + local seg = tonumber(s:sub(seg_start)) + return seg and seg <= 255 or false + end + -- CIDR æŽ©ç æ£€æŸ¥ + if mask_start > len then return false end + local mask = tonumber(s:sub(mask_start)) + return mask and mask >= 0 and mask <= 32 or false +end + +local function is_ipv4_cidr(s) + return is_ipv4(s, true) +end + +local function is_ipv6(s, check_cidr) + local first = s:byte(1) + local last = s:byte(#s) + if first == 91 and last == 93 then -- "[" and "]" + s = s:sub(2, -2) + end + local len = #s + local i = 1 + local seg_len = 0 + local segs = 0 + local saw_dc = false -- 是å¦å‡ºçް "::" + local b + while i <= len do + b = s:byte(i) + -- CIDR 部分 + if b == 47 then -- '/' + if not check_cidr then + return false + end + -- å¤„ç† "/" 之å‰çš„æ®µ + if seg_len > 0 then segs = segs + 1 end + if (not saw_dc and segs ~= 8) or (saw_dc and segs > 8) then return false end + -- è§£æžæŽ©ç  + i = i + 1 + if i > len then return false end + local mask = 0 + while i <= len do + b = s:byte(i) + if b < 48 or b > 57 then return false end + mask = mask * 10 + (b - 48) + if mask > 128 then return false end + i = i + 1 + end + -- CIDR è§£æžæˆåŠŸ + return true + end + -- 冒å·å¤„ç†ï¼ˆ: 或 ::) + if b == 58 then + local nextb = (i+1 <= len) and s:byte(i+1) or 0 + -- "::" + if nextb == 58 then + if saw_dc then return false end + saw_dc = true + if seg_len > 0 then segs = segs + 1 end + seg_len = 0 + i = i + 2 + else + -- 普通 ":" + if seg_len == 0 then return false end + segs = segs + 1 + seg_len = 0 + i = i + 1 + end + else + -- hex æ•°å­— + local is_hex = + (b >= 48 and b <= 57) or -- 0-9 + (b >= 65 and b <= 70) or -- A-F + (b >= 97 and b <= 102) -- a-f + if not is_hex then return false end + seg_len = seg_len + 1 + if seg_len > 4 then return false end + i = i + 1 + end + end + if seg_len > 0 then segs = segs + 1 end + if not saw_dc then return segs == 8 end + return segs <= 8 +end + +-- IPv6 cidr检测,替代 string.find ":-[%x]+%:+[%x]-[%/][%d]+$" +local function is_ipv6_cidr(s) + return is_ipv6(s, true) +end + +-- 检测是å¦å«æœ‰å†’å·ï¼Œæ›¿ä»£ string.find(line, ":") +local function has_colon(s) + for i = 1, #s do + if s:byte(i) == 58 then -- ':' + return true + end + end + return false +end + +-- 域åæå–,替代 string.match "([%w%-]+%.[%w%.%-]+)[%/%*]*" +local function extract_domain(s) + if not s or s == "" then return nil end + local len = #s + local start = nil + local last_dot = nil + for i = 1, len do + local b = s:byte(i) + -- å…许的域å字符:a-zA-Z0-9.- + if (b >= 48 and b <= 57) or (b >= 65 and b <= 90) or (b >= 97 and b <= 122) or b == 45 or b == 46 then + if not start then start = i end + if b == 46 then last_dot = i end + else + if start then + if last_dot and last_dot > start then + local domain = s:sub(start, i - 1) + while domain:byte(1) == 46 do + domain = domain:sub(2) + end + return domain + else + start = nil + last_dot = nil + end + end + end + end + if start and last_dot and last_dot > start then + local domain = s:sub(start) + while domain:byte(1) == 46 do + domain = domain:sub(2) + end + return domain + end + return nil +end + +local function non_file_check(file_path, header_content) + local remote_file_size = nil + local local_file_size = tonumber(fs.stat(file_path, "size") or 0) + if local_file_size == 0 then + log("下载文件为空或读å–出错。") + return true + end + if header_content and header_content ~= "" then + for size in header_content:gmatch("[Cc]ontent%-[Ll]ength:%s*(%d+)") do + local s = tonumber(size) + if s and s > 0 then + remote_file_size = s + end + end + end + if remote_file_size and remote_file_size ~= local_file_size then + log(string.format("校验出错:远程 %dB, 下载 %dB", remote_file_size, local_file_size)) + return true + end + return false +end + +local function GeoToRule(rule_name, rule_type, out_path) + local bin = api.finded_com("geoview") + if not (bin and api.compare_versions(api.get_app_version("geoview"), ">=", "0.1.10")) then + log("[警告] Geoview ç»„ä»¶ç¼ºå¤±æˆ–ç‰ˆæœ¬è¿‡ä½Žï¼Œè§„åˆ™ç”Ÿæˆæµç¨‹å·²è¢«è·³è¿‡ã€‚") + return false + end + local geosite_path = asset_location .. "geosite.dat" + local geoip_path = asset_location .. "geoip.dat" + local file_path = (rule_type == "domain") and geosite_path or geoip_path + local geo_arg + if rule_type == "domain" then + if rule_name == "gfwlist" then + geo_arg = "-type geosite -list gfw" + else + geo_arg = "-type geosite -list cn" + end + elseif rule_type == "ip4" then + geo_arg = "-type geoip -list cn -ipv6=false" + elseif rule_type == "ip6" then + geo_arg = "-type geoip -list cn -ipv4=false" + end + local cmd = string.format(bin .. " -input '%s' %s -lowmem=true -output '%s'", file_path, geo_arg, out_path) + sys.exec(cmd) + local local_file_size = tonumber(fs.stat(out_path, "size") or 0) + if local_file_size == 0 then + os.remove(out_path) + log(rule_name .. " 生æˆå¤±è´¥ï¼Œè¯·ç¡®ä¿ Geo 文件正确且包å«ç›®æ ‡è§„则。") + return false + end + return true +end + +--fetch rule +local function fetch_rule(rule_name, rule_type, url, exclude_domain, max_retries) + local sret = 0 + local max_attempts = max_retries or 2 + local rule_dataset = {} + local file_tmp = "/tmp/" .. rule_name .. "_tmp" + local rule_final_path = rule_path .. "/" .. rule_name + if geo2rule == "1" then + url = {"geo2rule"} + log(rule_name.. " 开始生æˆ...") + else + log(rule_name.. " 开始更新...") + end + + for k, v in ipairs(url) do + local current_file = "/tmp/" .. rule_name .. "_dl" .. k + local success = false + + if v ~= "geo2rule" then + for i = 1, max_attempts do + local return_code, http_code, header = curl(v, current_file) + if return_code == 0 and not non_file_check(current_file, header) then + success = true + break + end + os.remove(current_file) + log(string.format("%s 第%dæ¡è§„则下载失败 (HTTP:%s),正在进行第%d次å°è¯•...", rule_name, k, tostring(http_code), i)) + end + else + if not GeoToRule(rule_name, rule_type, current_file) then return 1 end + success = true + end + + if success then + local f = io.open(current_file, "r") + if f then + if rule_name == "gfwlist" and geo2rule == "0" then + local decode = api.base64Decode(f:read("*all")) + for line in string.gmatch(decode, "[^\r\n]+") do + line = line:gsub("full:", "") + if not (is_comment_line(line) or is_ipv4(line) or has_colon(line) or (exclude_domain and check_excluded_domain(line))) then + local match = extract_domain(line) + if match and not is_ipv4(match) then + rule_dataset[match] = true + end + end + end + else + for line in f:lines() do + if rule_type == "domain" then + line = line:gsub("full:", "") + if not (is_comment_line(line) or is_ipv4(line) or has_colon(line) or (exclude_domain and check_excluded_domain(line))) then + local match = extract_domain(line) + if match and not is_ipv4(match) then + rule_dataset[match] = true + end + end + elseif rule_type == "ip4" then + local function is_0dot(s) -- "^0%..*" + return s and s:byte(1)==48 and s:byte(2)==46 + end + if is_ipv4_cidr(line) and not is_0dot(line) then + rule_dataset[line] = true + end + elseif rule_type == "ip6" then + local function is_double_colon_cidr(s) -- "^::(/%d+)?$" + if not s or s:byte(1)~=58 or s:byte(2)~=58 then return false end + local l = #s + if l==2 then return true end + if l==3 or s:byte(3)~=47 then return false end + for i=4,l do + local b=s:byte(i) + if b<48 or b>57 then return false end + end + return true + end + if is_ipv6_cidr(line) and not is_double_colon_cidr(line) then + rule_dataset[line] = true + end + end + end + end + f:close() + end + else + sret = 1 + log(string.format("%s 第%dæ¡è§„则: %s 下载失败ï¼", rule_name, k, v)) + end + os.remove(current_file) + end + + if sret == 0 then + local result_list = {} + for line, _ in pairs(rule_dataset) do table.insert(result_list, line) end + table.sort(result_list) + + local out = io.open(file_tmp, "w") + if out then + for _, line in ipairs(result_list) do out:write(line .. "\n") end + out:close() + end + + local old_md5 = sys.exec(string.format("md5sum %s 2>/dev/null | awk '{print $1}'", rule_final_path)):gsub("\n", "") + local new_md5 = sys.exec(string.format("md5sum %s 2>/dev/null | awk '{print $1}'", file_tmp)):gsub("\n", "") + + if old_md5 ~= new_md5 then + if api.is_finded("fw4") and (rule_type == "ip4" or rule_type == "ip6") then + local nft_file = file_tmp .. ".nft" + local set_name = "psw_" .. rule_name + if rule_name == "chnroute" then set_name = "psw_chn" + elseif rule_name == "chnroute6" then set_name = "psw_chn6" end + + local addr_type = (rule_type == "ip4") and "ipv4_addr" or "ipv6_addr" + gen_cache(set_name, addr_type, file_tmp, nft_file) + os.execute(string.format("mv -f %s %s.nft", nft_file, rule_final_path)) + end + os.execute(string.format("mv -f %s %s", file_tmp, rule_final_path)) + if not rollback then reboot = 1 end + log(string.format("%s æ›´æ–°æˆåŠŸï¼Œæ€»è§„åˆ™æ•° %d æ¡ã€‚", rule_name, #result_list)) + else + log(rule_name .. " 版本一致,无需更新。") + os.remove(file_tmp) + end + else + log(rule_name .. " æ›´æ–°å¤±è´¥ï¼ˆéƒ¨åˆ†æˆ–å…¨éƒ¨èµ„æºæ— æ³•下载)。") + os.remove(file_tmp) + end + return 0 +end + +local function fetch_geofile(geo_name, geo_type, url) + local tmp_path = "/tmp/" .. geo_name + local asset_path = asset_location .. geo_name + local down_filename = url:match("^.*/([^/?#]+)") + local sha_url = url:gsub(down_filename, down_filename .. ".sha256sum") + local sha_path = tmp_path .. ".sha256sum" + + local function verify_sha256(sha_file) + return sys.call("sha256sum -c " .. sha_file .. " > /dev/null 2>&1") == 0 + end + + local sha_verify = select(1, curl(sha_url, sha_path)) == 0 + if sha_verify then + local f = io.open(sha_path, "r") + if f then + local content = f:read("*l") + f:close() + if content then + content = content:gsub("(%x+)%s+.+", "%1 " .. tmp_path) + f = io.open(sha_path, "w") + if f then + f:write(content) + f:close() + end + end + end + if fs.access(asset_path) then + sys.call(string.format("cp -f %s %s", asset_path, tmp_path)) + if verify_sha256(sha_path) then + log(geo_type .. " 版本一致,无需更新。") + return 0 + end + end + end + + local sret_tmp, _, header = curl(url, tmp_path) + if sret_tmp == 0 and non_file_check(tmp_path, header) then + log(geo_type .. " 下载文件过程出错,å°è¯•釿–°ä¸‹è½½ã€‚") + os.remove(tmp_path) + sret_tmp, _, header= curl(url, tmp_path) + if sret_tmp == 0 and non_file_check(tmp_path, header) then + sret_tmp = 1 + log(geo_type .. " 下载文件过程出错,请检查网络或下载链接åŽé‡è¯•ï¼") + end + end + if sret_tmp == 0 then + if sha_verify then + if verify_sha256(sha_path) then + sys.call(string.format("mkdir -p %s && mv -f %s %s", backup_path, asset_path, backup_path)) + sys.call(string.format("mkdir -p %s && mv -f %s %s", asset_location, tmp_path, asset_path)) + reboot = 1 + log(geo_type .. " æ›´æ–°æˆåŠŸã€‚") + if geo_type == "geoip" then + geoip_update_ok = true + else + geosite_update_ok = true + end + else + log(geo_type .. " 更新失败,请ç¨åŽé‡è¯•æˆ–æ›´æ¢æ›´æ–°URL。") + return 1 + end + else + if fs.access(asset_path) and sys.call(string.format("cmp -s %s %s", tmp_path, asset_path)) == 0 then + log(geo_type .. " 版本一致,无需更新。") + return 0 + end + sys.call(string.format("mkdir -p %s && mv -f %s %s", backup_path, asset_path, backup_path)) + sys.call(string.format("mkdir -p %s && mv -f %s %s", asset_location, tmp_path, asset_path)) + reboot = 1 + log(geo_type .. " æ›´æ–°æˆåŠŸã€‚") + if geo_type == "geoip" then + geoip_update_ok = true + else + geosite_update_ok = true + end + end + else + log(geo_type .. " 更新失败,请ç¨åŽé‡è¯•æˆ–æ›´æ¢æ›´æ–°URL。") + return 1 + end + return 0 +end + +local function fetch_gfwlist() + fetch_rule("gfwlist","domain",gfwlist_url,true) +end + +local function fetch_chnroute() + fetch_rule("chnroute","ip4",chnroute_url,false) +end + +local function fetch_chnroute6() + fetch_rule("chnroute6","ip6",chnroute6_url,false) +end + +local function fetch_chnlist() + fetch_rule("chnlist","domain",chnlist_url,false) +end + +local function fetch_geoip() + fetch_geofile("geoip.dat","geoip",geoip_url) +end + +local function fetch_geosite() + fetch_geofile("geosite.dat","geosite",geosite_url) +end + +if arg2 then + string.gsub(arg2, '[^' .. "," .. ']+', function(w) + if w == "gfwlist" then + gfwlist_update = "1" + end + if w == "chnroute" then + chnroute_update = "1" + end + if w == "chnroute6" then + chnroute6_update = "1" + end + if w == "chnlist" then + chnlist_update = "1" + end + if w == "geoip" then + geoip_update = "1" + end + if w == "geosite" then + geosite_update = "1" + end + end) + if rollback then arg2 = nil end +else + gfwlist_update = uci:get(name, "@global_rules[0]", "gfwlist_update") or "1" + chnroute_update = uci:get(name, "@global_rules[0]", "chnroute_update") or "1" + chnroute6_update = uci:get(name, "@global_rules[0]", "chnroute6_update") or "1" + chnlist_update = uci:get(name, "@global_rules[0]", "chnlist_update") or "1" + geoip_update = uci:get(name, "@global_rules[0]", "geoip_update") or "1" + geosite_update = uci:get(name, "@global_rules[0]", "geosite_update") or "1" +end +if geo2rule ~= "1" and gfwlist_update == "0" and chnroute_update == "0" and chnroute6_update == "0" and chnlist_update == "0" and geoip_update == "0" and geosite_update == "0" then + os.exit(0) +end + +local function check_instance(action) + local rule_lock = "/var/lock/" .. name .. "_rule_update.lock" + local sub_lock = "/var/lock/" .. name .. "_subscribe.lock" + + if action == "start" then + math.randomseed(os.time() + math.floor(os.clock() * 1000)) + api.nixio.nanosleep(0, math.random(100, 1000) * 1000000) + if fs.access(rule_lock) then + log("有[规则更新]实例正在è¿è¡Œï¼Œè¯·ç¨åŽå†è¯•...\n") + os.exit(0) + else + luci.sys.call("touch " .. rule_lock) + end + elseif action == "end" then + luci.sys.call("rm -f " .. rule_lock) + return + end + + if fs.access(sub_lock) then + log("[订阅]实例正在è¿è¡Œï¼Œ[规则更新]进入队列等待...\n") + end + while fs.access(sub_lock) do + api.nixio.nanosleep(2, 0) + end +end + +check_instance("start") + +log("开始更新规则...") +local function safe_call(func, err_msg) + xpcall(func, function(e) + log(e) + log(debug.traceback()) + log(err_msg) + end) +end + +local function remove_tmp_geofile(name) + os.remove("/tmp/" .. name .. ".dat") + os.remove("/tmp/" .. name .. ".dat.sha256sum") +end + +if geo2rule == "1" then + if geoip_update == "1" and not rollback then + log("geoip 开始更新...") + safe_call(fetch_geoip, "æ›´æ–°geoipå‘生错误...") + remove_tmp_geofile("geoip") + end + + if geosite_update == "1" and not rollback then + log("geosite 开始更新...") + safe_call(fetch_geosite, "æ›´æ–°geositeå‘生错误...") + remove_tmp_geofile("geosite") + end + + -- 如果是手动更新(arg2存在)始终生æˆè§„则 + if arg2 then geoip_update_ok, geosite_update_ok = true, true end + chnroute_update, chnroute6_update, gfwlist_update, chnlist_update = "1", "1", "1", "1" + + if geoip_update_ok then + if fs.access(asset_location .. "geoip.dat") then + safe_call(fetch_chnroute, "生æˆchnrouteå‘生错误...") + safe_call(fetch_chnroute6, "生æˆchnroute6å‘生错误...") + else + log("geoip.dat 文件ä¸å­˜åœ¨,跳过规则生æˆã€‚") + end + end + + if geosite_update_ok then + if fs.access(asset_location .. "geosite.dat") then + safe_call(fetch_gfwlist, "生æˆgfwlistå‘生错误...") + safe_call(fetch_chnlist, "生æˆchnlistå‘生错误...") + else + log("geosite.dat 文件ä¸å­˜åœ¨,跳过规则生æˆã€‚") + end + end +else + if gfwlist_update == "1" then + safe_call(fetch_gfwlist, "æ›´æ–°gfwlistå‘生错误...") + end + + if chnroute_update == "1" then + safe_call(fetch_chnroute, "æ›´æ–°chnrouteå‘生错误...") + end + + if chnroute6_update == "1" then + safe_call(fetch_chnroute6, "æ›´æ–°chnroute6å‘生错误...") + end + + if chnlist_update == "1" then + safe_call(fetch_chnlist, "æ›´æ–°chnlistå‘生错误...") + end + + if geoip_update == "1" then + log("geoip 开始更新...") + safe_call(fetch_geoip, "æ›´æ–°geoipå‘生错误...") + remove_tmp_geofile("geoip") + end + + if geosite_update == "1" then + log("geosite 开始更新...") + safe_call(fetch_geosite, "æ›´æ–°geositeå‘生错误...") + remove_tmp_geofile("geosite") + end +end + +if not rollback then + uci:set(name, "@global_rules[0]", "gfwlist_update", gfwlist_update) + uci:set(name, "@global_rules[0]", "chnroute_update", chnroute_update) + uci:set(name, "@global_rules[0]", "chnroute6_update", chnroute6_update) + uci:set(name, "@global_rules[0]", "chnlist_update", chnlist_update) + uci:set(name, "@global_rules[0]", "geoip_update", geoip_update) + uci:set(name, "@global_rules[0]", "geosite_update", geosite_update) + api.uci_save(uci, name, true) +end + +if reboot == 1 then + if arg3 == "cron" then + if not fs.access("/var/lock/" .. name .. ".lock") then + sys.call("touch /tmp/lock/" .. name .. "_cron.lock") + end + end + + log("é‡å¯æœåŠ¡ï¼Œåº”ç”¨æ–°çš„è§„åˆ™ã€‚") + uci:set(name, "@global[0]", "flush_set", "1") + api.uci_save(uci, name, true, true) +end +log("规则更新完毕...\n") + +check_instance("end") diff --git a/luci-app-passwall/root/usr/share/passwall/rules/block_host b/luci-app-passwall/root/usr/share/passwall/rules/block_host new file mode 100644 index 00000000..e69de29b diff --git a/luci-app-passwall/root/usr/share/passwall/rules/block_ip b/luci-app-passwall/root/usr/share/passwall/rules/block_ip new file mode 100644 index 00000000..e69de29b diff --git a/luci-app-passwall/root/usr/share/passwall/rules/chnlist b/luci-app-passwall/root/usr/share/passwall/rules/chnlist new file mode 100644 index 00000000..17c93612 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/chnlist @@ -0,0 +1,119210 @@ +0.zone +00.net +000.link +000000.net +0000001.xin +000001.xin +00000qpqp00000.com +0000550xtz2.shop +0000552bb0.shop +0000552bb1.shop +0000552bb2.shop +0000552bb3.shop +0000552bb4.shop +0000f0deb5f4e6c3.com +0000wb.com +0001.xin +000114.com +00012023.com +0001700.xin +0002.xin +0003399xtz1.shop +0003399xtz2.shop +00042.com +00058.com +0006111xtz2.shop +0006266.com +00063.xin +000678.xin +0006fc9541020.beer +000700.com +000714.xyz +000793.com +0007999ab0.shop +0007999ab1.shop +0007999ab2.shop +0007999ab3.shop +0007999ab4.shop +0007999ab5.shop +0007999ab6.shop +0007999ab7.shop +0007999ab8.shop +0007999ab9.shop +0008.xin +00086.net +000868adh1.shop +000868agl1.shop +000868atz2.shop +0008bet.com +0009.xin +00091.xin +000b0fb9410281.beer +000e.com +000pc.net +001.com +001019.xin +001060.com +00117163.xyz +001d628661009.beer +001daima.com +001fzc.com +001jm.com +001job.com +001jp.com +001kd.com +001km.com +001pp.com +001pt.com +001sj.net +001tudou.com +001u.com +001u2.xin +001wifi.com +001win5.cc +002.xin +002049.com +00257.com +002574.com +0028.xin +0033.com +00333118.com +0037wan.com +00394.net +003caixukun.xin +004.xin +0044696.com +004678.com +004837963.xyz +005.tv +0056.com +00563.com +0058.com +005854.xin +00615.net +00653.xin +0066.com +00665ba1f014ee0e.com +00666.xin +006shipin.org +007.pub +0073.com +00772229.com +00791.com +007card.vip +007gameapp10.com +007manhua.com +007shoes.com +007swz.com +007szx.com +007yx.com +008.bet +00817.com +00847.xin +0086l.com +0086org.com +008n0l12145.xin +008sport.com +009.xin +0098118.com +009job.com +009y.com +00bx.com +00cdn.com +00cf.com +00cha.com +00cha.net +00ef6bce51ccd47d.com +00fkh408382.xin +00hh.com +00hzx.xin +00i1xg5s3s.xin +00ic.com +00it.net +00lfoo16454.xin +00mi.com +00o5nm18258.xin +00plri7b.xin +00r9fexyub.xin +00shu.com +00shu.la +00tera.com +00tu.com +00ukkgtc5.xin +00ve1bg9.xin +00wv.com +00xu.com +00y9334535.com +01-2--3.xin +01-cf.com +010.cc +010123456.com +010155.net +0101cdn.com +0101e.com +0101game.online +0101semi.com +0101ssd.com +010203.com +010237.com +01058511989.com +01095113.com +010b.com +010bianhu.com +010bjzs.com +010cb.com +010cns.com +010dell.com +010dh.com +010dsmzyy.com +010fang.net +010gaokao.com +010huaer.com +010huashi.com +010jianzhan.com +010lf.com +010p.cc +010shangpu.com +010time.com +010xiongdi.com +010zaixian.com +011.com +011.xin +011a4460e391a7f4.com +0121.xin +012233.com +0123.xin +0123401234.com +0123456789.com +0123f.xin +0127.xin +01291.xin +01317.org +01350.work +0135135.com +01368.com +0138.com +014.cc +014.xin +01401.com +0142f5348f8cd094.com +0143.xin +014929.com +014cbd7e810301.beer +014esw24222.xin +015.xin +0158f80.com +016.xin +016sf.com +018.xin +018yun.xin +019.xin +01975cf969f20191.com +019jb0sc.xin +01a7d69861013.beer +01be6bfabbd3024a.com +01bzw.us +01bzw.xyz +01caijing.com +01d55251a10241.beer +01dou.com +01f438bf710301.beer +01ffa63e710261.beer +01home.com +01hour.com +01hr.com +01hub.com +01isp.com +01isp.net +01jinhua.com +01jzw.com +01ki.com +01p.com +01p6xc08451.xin +01pxzw0737.xin +01rv.com +01skjj.com +01studio.cc +01teacher.com +01wb.com +01ww.xin +01x13k30.xin +01yo.com +01yuanma.com +01yun.com +01zenith.net +01zhuanche.com +01zk.com +01zph.com +02-89910011.com +020.com +020.net +0200.xin +02000.xin +02017.com +0208.com +020883.com +020910.com +020banjia.net +020bdqn.net +020gzjx.com +020h.com +020job.com +020trvl.com +020xue.com +020ym.com +020zp.net +020ztc.com +021-116114.com +021.com +021.net +0214.com +02156506666.net +02163.com +0217.xin +021a5f9841009.beer +021bolang.com +021byb.com +021dianyuan.com +021dzjx.com +021east.com +021gjhb.com +021huamei.com +021huaying.com +021images.com +021images.vip +021ja.com +021jgyy.com +021jingwei.com +021kd.com +021lawfirm.com +021phone.com +021ren.com +021sports.com +021tk.com +021van.com +021wfz.com +021ye.com +021yongzhuo.com +021zhuang.com +021zsb.com +022003.com +0222.xin +0229.xin +022china.com +022meishu.com +022s.com +022shui.com +022sunny.com +022v.com +023086.com +023bc5v99h.xin +023cj.com +023cq.cc +023dir.com +023dns.com +023fyy.com +023gmdk.com +023up.com +023xfyy.com +023xiaoyuan.com +023yts.com +023yy95.net +023yynk.net +023zhang.xin +023zp.com +02405.com +024365.com +0245.cc +0245.net +02456789.com +0246b05e23a644b5.com +024888.net +024bj.com +024eps.com +024f9wrcm.xin +024frde.com +024fuchan.com +024fuwu.com +024heyi.com +024hh.com +024huada.com +024jsq.com +024zxw.com +025.com +025002.com +02516.com +025ct.com +025kaiyi.com +025nj.com +025njtf.com +025sc.com +025tffs.com +025tongfeng.com +025tuanjian.com +025tuopan.com +025xl.com +025zp.com +0264032a252fcf53.com +026hao.com +026idc.com +0270.cc +027119.xin +02712122.com +02727.com +02766667777.com +0279.net +027965888.net +027accp.com +027aige.com +027ar51848.xin +027art.com +027chuxun.com +027chwl.com +027chx.com +027cloud.com +027eat.com +027g3nkf40.com +027hhl.com +027hpedu.com +027hpit.com +027htxt.com +027hxzy.com +027hy.com +027idc.com +027jsxh.com +027one.com +027qjxh.com +027qyy.com +027tianlong.com +027tytpf.com +027wcbyy.com +027yx.com +027zb.com +027zikao.com +027zpw.com +028-xhxgt.com +0283home.com +0289kh1448.xin +028csc.com +028desite.com +028f.com +028hema.com +028kuaidai.com +028ltzx.com +028office.com +028px.com +028pxw.com +028sh.com +028sjkj.com +028yyyy.com +029200.com +02924.com +029558.com +029900.com +029gl.com +029jiuda.com +029judao.com +029k.com +029lvwo.com +029shw.com +029taihe.com +029wsw.com +029xxw.com +029yjy.com +029zp.com +02a5ji7vso.com +02b5c31e511032.beer +02bjmbzoat.xin +02d.com +02fb56599d46ae7d.com +02hm.com +02lb.com +02lu.com +02pew65z89.com +02shu.com +02tf6d18201.xin +02u21a0lka.xin +02wan.com +02wq.com +02yc.com +02z97426404.xin +03.com +030.xin +030303.com +030hag5r91.xin +030mall.com +030yo.xin +0310it.com +0311.cc +031130.xyz +03118888.com +0311hd.com +0311led.com +0311wifi.com +0315.center +0316.cc +0316366.com +03167.com +0316yun.com +0320.work +0321.xin +03241119.xyz +03256.xin +0328.com +032ab0b0a10292.beer +033033.com +0333.xin +03369709d10301.beer +0349.xin +035110000.com +0351data.com +0351fdc.com +0352fang.com +0354rcw.com +0355fk.com +0356.com +0356f.com +0357dc382faf80f5.com +0357hz.com +0359tv.com +0368.com +036yx.com +0370-2221999.net +0371jixie.com +0371lianghao.com +0371sou.com +0371wang.com +037398.com +03770e40910272.beer +0377auto.com +0377ny.xin +0378zz.com +0379home.com +0379wan.com +037lcq08115.xin +038d0addd10241.beer +0391fc.com +03964.com +039r93jevs.xin +03b2ef6fe1960045.com +03bcyh2069.xin +03cl.xin +03cz8604316.xin +03d882c8810271.beer +03dq.com +03f99b91610271.beer +03fcw.com +03fdcw.com +03fugu.xin +03k.org +03m7pa17g.xin +03ssif8zb.xin +03supin.com +03tc.com +03u.com +03wy.com +03xs.com +040.xin +04052.xin +04075k2xgr.com +04085o08379.xin +0411.com +041101.com +0411ct.com +0411cxd.com +0411e.com +0411gh.com +0411hd.com +0411king.com +0411xslvshi.com +0411zssy.com +0415123.com +0415t.com +0416job.com +041799.com +0421wcbzk.com +0427.com +0429f95301011.beer +0430.com +0431cn.com +0434.cc +0437.com +043j8118366.xin +0444.xin +0452e.com +0453.com +0453bc39456389ff.com +0454.cc +0455tv.com +0455zd.com +0456yun.com +046.xin +0460.com +0470a.com +0472.com +04763.work +0476vip.com +048.xin +0484.xin +048o9ml5x3.xin +049.com +049.xin +04a1to24453.xin +04adca98c1022.beer +04apr5bl.xin +04be22jjkv.xin +04c01e0ad4c891d7.com +04db11e1ea504cf2.com +04ip.com +04l68n18142.xin +04n1ns24180.xin +04qfw7m68o.com +04r0e3w2ac.com +04vfkt24311.xin +05.gd +050.xin +0502.xin +050400.com +050504.xin +0507c.xin +0509.xin +051058.com +0510gcw.com +0510gtgc.com +0510syedu.com +0510zyw.com +0513.net +0513.org +0513011.com +0513zs.com +0514.com +0514.net +05148.cc +0514gcw.com +051591.com +0515kf.com +0515smw.com +0515yc.com +0515yy.com +0516ds.com +0516k.com +0517.net +0517cw.com +0517man.com +0517w.com +0518home.com +0518yy.com +0523114.com +05236.com +052360.com +0523bbs.net +0523tx.net +0523zp.com +0523zz.com +0527.xin +05273.com +0527zp.com +0527zz.com +05280.xin +0529.xin +052yx.com +0531.com +053135.com +0531soso.com +0531wt.com +0532.com +053217.com +0532eu.com +0533.net +0534.com +0534888.com +0535-0411.com +0535cp.com +0535you.com +05366196.com +0536job.net +0536qz.com +0536weixin.com +0537love.com +0537ys.com +0537yz.com +0539fc.com +053c.com +0540.xin +0543.xin +0543bbs.com +0543hr.com +0544.xin +054400.com +0545.xin +0546.xin +0546fdc.com +0549.xin +0550.com +055110.com +055178.com +0551wl.com +0552jie.com +0553zsw.com +0554news.com +0554qd.xin +0554shdz.com +0554zp.com +0555fc.com +0557100.com +0558job.com +0559hs.com +0559jqdq.com +055dq.xin +055e8qn69j.com +0564abc.com +0564shw.com +0566job.com +057.com +057.xin +0570fc.com +0570zs.com +057191.com +0571crm.com +0571gszc.com +0571nh.com +0571pu.com +0571zp.com +0572h.com +0572home.com +0572zpw.com +0573fang.com +0573ol.com +0573ren.com +0574bbs.com +0574nbjg.com +0575.host +057555.com +0575bbs.com +0575jb.com +0575life.com +0575qs.com +0575zhuji.com +0576qq.com +0577-it.com +0577365.net +0577cnw.com +0577gyy.com +0577home.net +0577hr.com +0577job.com +0577qiche.com +0578rencai.com +05790.com +0579818.com +0579com.com +0579fw.com +057x.com +05880a57e1022.beer +058a2a0741016.beer +058e001fc10251.beer +058ed0543d61b235.com +058idc.com +05927.com +0592dsw.com +0592jj.com +0592ui.com +0592xl.com +0594.com +0594.work +0594fake.com +0594hyw.com +0594sneaker.com +0595.com +0595a74c711012.beer +0595job.com +0595qz.com +0595rc.com +0596fc.com +0597kk.com +0597music.com +0597ok.com +0597seo.com +0598777.com +0598yu.com +0599yx.com +05bf51fa911012.beer +05bq.com +05by3k248.xin +05cc8c4cc1023.beer +05e44607310271.beer +05idc.com +05info.com +05ja1g16464.xin +05n2azbp.xin +05p9uj1253.xin +05rjxqsp5i.xin +05sun.com +05vauwva3.xin +05vm.com +05wan.com +05wang.com +05youxi.com +060.xin +0603.xin +0605.com +0609.com +061.xin +0616.xin +0616a9dbe68fac9c.com +0618.com +0618.xin +06192.com +0623.xin +062wfly8z.xin +0631.xin +063108.com +0631rc.com +0632.xin +0632idc.com +0633.xin +0634.com +0634.xin +0635.com +0635.xin +064.xin +065201.com +065423cd010311.beer +06555.com +0660hf.com +0663.net +06639.xin +0663job.com +0666.xin +0668.com +06681.com +0668gz.com +067555.com +06888.work +068rolbmiz.xin +069.xin +0693f784d1023.beer +06abc.com +06b8ziwxjf.xin +06climate.com +06dc36591a49441c.com +06ee1860c1015.beer +06game.com +06ik7744n.xin +06ps.com +06tn.com +06z8mzlma.xin +07.cc +07.la +070725.xyz +07073.com +07073h5.com +07073vr.com +0708.com +0712f.com +0712fang.com +0714.com +0714110.xin +0715fc.com +0715rc.com +0715zp.com +0716fw.com +0716mr.com +07177.com +0718.cc +0718qp.com +0718xf.com +072.xin +0722fc.com +0722zs.com +0724c.com +0725.com +0728f.com +0730188.com +0730news.com +073122.com +0731777.com +0731a.com +0731cfw.com +0731fdc.com +0731hds.com +0731i.com +0731job.com +0731mcw.com +0731pgy.com +0731tg.com +0731wan.com +0733news.com +0734zpw.com +0735.com +07358.com +0735jz.com +0735zx.com +0735zz.com +0736fdc.com +0736zp.com +0736zz.com +0738.cc +0738rc.com +073980.com +0739qq.com +0739tt.com +073e5367a10292.beer +073img.com +073pic.com +07430743.com +0743fd8231024.beer +0744114.com +0744tv.com +0746job.com +0746news.com +0750.xin +0750rc.com +0751.cc +075238.com +0752qc.com +0753zz.com +0755.net +07551.com +07551.net +0755400.com +075577777.com +0755888.com +0755910.com +0755bdqn.com +0755bzf.com +0755caibao.com +0755cts.com +0755fm.com +0755gty.com +0755hao.com +0755haoyu.com +0755hj.com +0755hz.com +0755jz.net +0755sszx.net +0755yf.net +0755zb.com +0756fang.com +0756idc.com +0756tong.com +0756zx.com +0757fc.com +0757info.com +0757p.com +0757rc.com +0758net.com +0759.pw +0759home.com +0759job.com +0759k.com +0759yc.com +076.xin +0760.com +0760bw.com +0760rc.com +07629.org +076299.com +076299.net +0762uu.com +0763f.com +076650.com +07666.com +0768000.com +0769auto.com +0769che.com +0769king.xin +0769net.com +0769pf.com +0769sun.com +0769sx.com +0769web.net +0769yp.com +076t0uhtl9.xin +077.xin +0771.com +0771.tv +07712008.com +07715555555.com +0771cts.com +0771cyts.com +0771fukang.com +0771rc.com +0772fang.com +0772gcw.com +0772job.com +0772lou.com +07743988888.com +07752267777.com +07754255555.com +0775fcw.com +0775jzw.com +0775qc.com +0775yzf.com +0776.cool +07761.com +0776hr.com +0779-2678999.com +078.xin +078079.com +07890.com +078bdd796e8b4b12.com +07908.com +0791abc.com +0791br.com +0791fuwu.com +0791look.com +0791qzw.com +0792jj.net +0792ju.com +0792lsly.com +0792u.com +0793.tv +07938.com +0794zp.com +0797122.com +0797auto.com +0797ayzp.com +0797rs.com +0797tuan.com +0797zz.com +0798.cc +0799z.com +079mxd.com +07ba0de711020.beer +07bmss01426.xin +07cn.com +07cn.net +07e12xs2io.xin +07f0798569af4d70.com +07fe8668211012.beer +07fea775dffd96d4.com +07jfrv01301.xin +07k6np0378.xin +07kacm20339.xin +07net01.com +07ozikk8w3.xin +07ren.com +07sh.com +07swz.com +07u82t16391.xin +07w97p18164.xin +07zk7z26405.xin +080.xin +0800c988e1010.beer +0801.xin +0804.org +080e068141ea500e.com +081.com +081.xin +0813fs.com +0817.net +0817ch.com +0817tv.com +0818tuan.com +0818tuangou.com +082.xin +0820.xin +0827ug.com +0830bbs.com +0831.app +0831home.com +0832mh.com +0835.com +0835meiya.com +0838.com +0838che.com +0839zp.com +08424b74011032.beer +0843d5944883e752.com +085.com +0852diaoyu.com +0853rc.com +0856st.com +0857job.com +0859job.com +0859qp.com +0859sy.com +0860.xin +086019.com +08644.com +0871aaa.com +0873js.com +0877zp.com +0890.com +08952.com +08958e44r8.com +0898.net +089858.com +0898888.com +0898hq.com +0898mmf.com +0898uf.com +089u.com +08an.com +08ar.com +08b68dbbbf876114.com +08c6.com +08c8b537f1021.beer +08c9f63d31021.beer +08cms.com +08fc8f0ee3f2768a.com +08ky.com +08px.com +08qx.com +08wojia.com +08x1am20483.xin +08zf.com +0904.cool +090901.xin +090expo.com +0912158.com +0912app.com +0912fdj.com +0913ss.com +0915531111.xin +0916001.com +0917.com +0917888.com +0917e.com +0918f5dadde012c3.com +0919123.com +092394.com +093.com +0935e.com +0937.cc +0937.com +0937.net +0937js.com +09388.xin +0938edu.com +0938net.com +0939.net +0939.xin +093nd9.com +094.xin +09451.com +0945a5ee91011.beer +094j35.com +095.xin +095196555.com +0951job.com +09527.xin +0952xh.com +0959930d71015.beer +096.xin +0962xb24260.xin +0963d9712a525457.com +096663.com +0972xxg.com +0979.xin +0990fc0011011.beer +0991dj.com +0991net.com +0992.cc +09928.xin +09946.center +09948.xin +099913.com +099b127ae166d8f1.com +09aag016266.xin +09b3045664731d42.com +09c5062ea1020.beer +09e12x16370.xin +09ea354bd9542ba7.com +09game.com +09iatm1z.xin +09lc5d12399.xin +09mhncdop.xin +09p9z7d1h8.com +09pay.xin +09pj75gs09.xin +09pzq024240.xin +09rrqh7s62.xin +09shijue.com +09vvme1l.xin +09xx5a24352.xin +09z7wy3k.xin +0a0fx7vz1l.xin +0a2d.com +0a2g5a04175.xin +0a32mt201.xin +0a64qa16273.xin +0a6ri001390.xin +0a8a112e8bb5045e.com +0acrdtuhed.xin +0ag8kg01470.xin +0ape4t08268.xin +0aq4hxqs.xin +0ax2rjo3od.xin +0axoa626262.xin +0b145c21210e933c.com +0b4xq91061.xin +0b6e0659811021.beer +0b8ky116130.xin +0barrfplp.xin +0bb261a6a46d766a.com +0bb875c361022.beer +0bbd0e535194e7f7.com +0bddiq9a0q.xin +0bdfe52341114.beer +0bef0493410272.beer +0bjasw18181.xin +0bke7a16362.xin +0bmfo404187.xin +0bqa9826122.xin +0bw82f20390.xin +0bxed90150.xin +0c3bjz070.xin +0c449995810292.beer +0c9a2959d10311.beer +0c9b8639d1024.beer +0car0.com +0cname.com +0cokid18352.xin +0cq9hzrz.xin +0cqpj504251.xin +0d.work +0d00.xin +0d06e627dbe6654a.com +0d263788316151cb.com +0d3lnlkylu.xin +0d49f571e1017.beer +0daily.com +0day.xin +0ddvic16247.xin +0de41y26132.xin +0dian8.org +0dm.com +0dmhu412466.xin +0dou490764.xin +0dt83e18342.xin +0du.net +0du4br04412.xin +0duw.com +0duxs.com +0dxkge0412.xin +0e0c2e9e94622290.com +0e38e883511032.beer +0e706b6c62da3920.com +0e76427381016.beer +0e7o6216306.xin +0e91wut86c.com +0easy.com +0ecff3e99dce5b33.com +0ee18d4c192243b3.com +0efef58c41014.beer +0egh661666.xin +0eghje0112.xin +0ek4sg08401.xin +0emvvs04229.xin +0en6hz2u.xin +0ew4p6fb1.xin +0f0lj908444.xin +0f602h26461.xin +0f63e6089d80dffe.com +0fbcjwr4x2.xin +0fbs03i1i.xin +0fc45y3sbr.xin +0fe5d43561011.beer +0fe7e0a941011.beer +0fep69v3.xin +0fj5qx12422.xin +0fl1j80347.xin +0flnis04328.xin +0fnkjai21b.xin +0g13wzk4pj.xin +0g1s.com +0g5q5hrcbo.xin +0g9l08zbsc.xin +0ggt51agn0.xin +0ggw7u16311.xin +0gklqj5hal.xin +0gmu6zwf87.xin +0gouche.com +0gps2ppnu9.xin +0gtsz9jw.xin +0gyyc924408.xin +0h3lfj12415.xin +0hbgmcs5gb.xin +0he0.com +0hgame.com +0hl5ntdm0i.xin +0hq7006r07.xin +0hzxwa2471.xin +0i-i0.com +0i6js716143.xin +0i71r4qg.xin +0im9f31630.xin +0iq8q8163.xin +0iwgt324206.xin +0j1oul247.xin +0j3h9616299.xin +0j4wdc8bs8.xin +0j783008494.xin +0jb520030.xin +0jl3h724403.xin +0k2u4didtd.xin +0k6dm96.xin +0ka.com +0kdmutnc.xin +0kee.com +0kfq5e16254.xin +0kkkkkt.com +0km5ip01196.xin +0kmny96j9gtb.xin +0koxpnwfx.xin +0krmre24376.xin +0kt0nm0380.xin +0l23f6i4e8.com +0l2nf218236.xin +0l7mqk1284.xin +0leb5s268.xin +0lircg1235.xin +0lw1ib2sa.xin +0lzamwtu.xin +0m7eaq04292.xin +0m93wwr0.xin +0mbvyf1437.xin +0me14c18373.xin +0mfbac1gsj.xin +0mfqi124198.xin +0mk9ht2449.xin +0moju716460.xin +0mrzee12192.xin +0ms.one +0ms65u0s8t.xin +0mu4f8xw0k.xin +0n469e12312.xin +0n5hylf79s.xin +0n663xtw.xin +0nc13z04356.xin +0nejoqlu3.xin +0nelddmoha.xin +0nk5dhsp.xin +0nnk3nxyu3.xin +0np1ydukvn.com +0npkjexon.xin +0nqxhrpw30.xin +0nw2sq2622.xin +0nzk4t3lrn.xin +0o0o.xin +0o1djo20199.xin +0o6wqk24113.xin +0o8lgn20118.xin +0obhhr12439.xin +0okm1a12139.xin +0olgbi04133.xin +0olut8.com +0one.xin +0oo70c26213.xin +0or1h40327.xin +0p21iz0729.xin +0p2wrugphn.xin +0p4ips24224.xin +0p5i7dxr6y.xin +0p901yay.xin +0plpxp1898.xin +0poho720169.xin +0ptf4g04404.xin +0pxrom71q8.xin +0q5stv04123.xin +0q9y3z18365.xin +0qd9dnzon9.xin +0qm88r0891.xin +0qqczcn8l8.xin +0r8ag0y7di.xin +0range5.xin +0rg.xin +0rgojh0146.xin +0rgu7ha3p.xin +0rl.cc +0rljmz01274.xin +0rz.ltd +0s73o26p67.com +0s8s.com +0sm.com +0snd.cc +0u.com +0voice.com +0x3.com +0x3.me +0x6.me +0x7.me +0x9.me +0xaa55.com +0xff000000.com +0xffffff.org +0xiao.com +0xjqlun2.work +0xsky.com +0xue.com +0z.gs +0zn5mg.asia +1-123.com +1-b.tc +1-cs.net +1-du.net +1-fss24-s0.streamhoster.com +1-luxury.com +1-yuan.net +1.biz +1.cc +100-tong.com +100.com +100.me +100.travel +10000.com +100000w.com +10000gd.tech +10000idc.net +10000job.com +10000link.com +10000post.com +10000shequ.com +10000tc.com +10000yao.com +10001wan.com +100024.xyz +1000360.com +10006.info +1000coco.com +1000fun.com +1000my.com +1000phone.com +1000phone.net +1000plan.org +1000qm.vip +1000qs.com +1000thinktank.com +1000tuan.com +1000uc.com +1000xuexi.com +1000xun.com +1000zhu.com +10010.com +10010.net +10010.team +10010400.net +10010hb.net +10010js.com +10010ll.com +10010mx.com +10010nm.com +1001g.com +1001hw.com +1001p.com +100248.com +10029.com +10034.com +100520.com +100580.com +1008011.com +1008120.com +10086.com +10086.games +10086.world +1008656.com +10086kuaixiu.com +100allin.com +100alpha.com +100ask.net +100ask.org +100audio.com +100bt.com +100chou.com +100chui.com +100cjc.com +100credit.com +100cup.com +100d3.com +100data.com +100du.com +100e.com +100eby.com +100eshu.com +100exam.com +100fang.com +100font.com +100guoji.com +100hsl.com +100incense.com +100inn.cc +100intlschool.com +100ip.net +100jg.com +100jiapu.com +100kk.com +100ksw.com +100lake.com +100lbj.com +100legend.com +100loujia.com +100market.net +100md.com +100mian.com +100mmedia.net +100nets.com +100njz.com +100nong.com +100offer.com +100old.com +100pd.com +100pei.com +100ppi.com +100puzzles.com +100qu.net +100run.com +100shop.com +100shuai.com +100skin.com +100stone.com +100sucai.com +100szy.com +100t.com +100tal.com +100tiao1.net +100tmt.com +100top1.com +100try.com +100tv.com +100txy.com +100vr.com +100wa.com +100web.store +100weidu.com +100wen.com +100wsanguo.com +100xgj.com +100xhs.com +100xiao.com +100xin.com +100xuexi.com +100yangsheng.com +100ycdn.com +100ye.com +100ye.net +100yigui.com +100yingcai.com +100yiyao.net +100zd.com +100zhuang.com +100zp.com +101.com +1010-0000.com +10100.com +10100000.com +10101111.com +10101111cdn.com +1010gamer.com +1010jiajiao.com +1010jz.com +1010pic.com +1010sh.com +1010t.com +101505.com +10155.com +1015600.com +10185.com +101hair.com +101hr.com +101jiajiao.com +101weiqi.com +1024.ink +1024fuli.com +1024g.com +1024ie.com +1024nic.com +1024ss.com +1024tools.com +1024wl.com +1024zx.com +1026jz.com +10284.com +102no.com +102pay.com +103153.com +10333.com +10349.com +10479.org +1050qm.com +105mr.com +10625fffd42119ce.com +10636.pro +10639888.com +1065m.com +10666114.net +1073.com +1088hg41.com +108addf0811012.beer +108ai.com +108mir.com +108pk.com +108qi.com +108sq.com +108tian.com +109.com +109360.com +10966.net +109876543210.com +109ya.com +10bests.com +10c5a16c51015.beer +10de7e1f17f512b2.com +10ec4a74b10281.beer +10fang.com +10gjkj.com +10gt.com +10guoying.com +10huan.com +10idc.com +10isp.com +10moons.com +10p07v10o5.com +10pkpk.com +10qq.com +10r1.com +10s1.com +10sea.com +10soo.com +10tianqi.com +10urzr3jk.icu +10vps.com +10yan.com +110.com +11000011.com +1108cd985e95ad39.com +110ask.com +110clwz.com +110disk.net +110route.com +110tm.com +111.com +111111111.com +1111lm.com +111237.com +1113.cc +1114.com +11159.com +11160066.com +1116fad134.info +1116fad135.info +1116fad158.info +1116fad167.info +1116fad176.info +11172222.com +111867.com +111com.net +111wo.com +111yao.com +111zyw.com +112112.com +112192.com +1122.com +11222.com +112682.com +1128job.com +112998.xyz +112seo.com +112wan.com +11315.com +11343.com +113989.com +113dh.com +113ya.com +114-91.com +1145858.com +11467.com +11478.com +114837322.xyz +114auto.com +114best.com +114blog.com +114cbd.com +114chn.com +114db.com +114dev.com +114dg.com +114dns.com +114dns.net +114dnss.com +114gh.com +114guoshu.com +114hyw.com +114hzw.com +114ic.com +114ic.net +114jcw.com +114menhu.com +114mo.com +114my.com +114my.net +114naliyou.com +114oc.com +114photo.com +114piaowu.com +114pinpai.com +114qy.com +114s.com +114sf.com +114shouji.com +114study.com +114ttg.com +114ups.com +114yygh.com +114zhibo.com +114zpw.com +114zw.org +115.com +115155.xyz +1156.com +1156dns.com +115800.com +115cdn.com +115cdn.de +115cdn.net +115cloud.com +115cloud.net +115img.com +115meta.com +115seo.com +115vod.com +115wg.com +115zb.com +1163.com +1166.com +1168.tv +11684.com +116968.com +116cd.com +116cd.net +116daohang.com +116kj.com +116yx.com +11714ae0b1014.beer +117915.com +117a6af992d4208e.com +117trip.com +117y.com +1181.com +118114.net +118360.com +1188fc.com +118cy.com +118inns.com +118jm.com +118pan.com +118ttc.com +118wa.com +1190119.com +119120.org +11951.com +11992169.xyz +119958.com +119bid.com +119lora.com +119tx.com +119you.com +11bao.com +11bz.com +11cda806e11012.beer +11cdn.cc +11dmh.com +11dns.com +11fdj.com +11fldxn.com +11flow.com +11g.com +11gai.com +11haoka.com +11job.com +11job.net +11ka.com +11lx.com +11meigui.com +11pdf.com +11player.com +11rain.com +11slotvip.cc +11space.com +11sun.com +11wow.com +11xotn7p.com +11yinyuan.com +11zhang.com +120.net +1204cm.com +120918.com +120ask.com +120askimages.com +120bid.com +120btc.com +120cihui.com +120fd.com +120it.com +120jg.com +120jhccz.com +120jinyi.com +120jxxh.com +120kid.com +120kq.com +120naotan.com +120scp.com +120sg.com +120shgc.com +120spd.com +120sun.com +120top.com +120x.net +120ym.com +121121.net +12114rc.com +1212.com +12120.net +12123.com +121314.com +121588.com +121ask.com +121down.com +121ghs.com +121mai.com +121mu.com +121wty.com +122521.com +12260808.xyz +12272.vip +1228xbdz7m.cfd +122bid.com +122c3e52810272.beer +122cha.com +122cn.net +122law.com +122w.net +123-789.com +123.cc +12301.cc +1230539.com +12306.com +12306bypass.com +12308.com +12308com.com +1230t.com +123123.net +12315.com +12316cn.com +12317.com +12317wan.com +1231818.com +123242.com +123245.com +123254.com +123294.com +123295.com +123326.com +12333.com +12333.org +12333si.com +12333tc.com +123366.xyz +1233dns.com +1234.me +12341288.com +1234567.com +123456edu.com +123456wz.com +12345b.com +12345good.com +12345good.net +12348.net +12349.net +1234biao.com +1234i.com +1234n.com +1234sy.com +1234wu.com +1234wu.net +1234ye.com +1234yes.com +12354.com +12355.net +123624.com +123635.com +123641.com +123652.com +12365auto.com +12366.com +12366.net +12366cn.com +123684.com +12369zb.com +123773.com +123842.com +123860.com +123865.com +123888222.com +123912.com +123952.com +123957.com +123aa.com +123aoe.com +123baofeng.com +123bo.com +123boligang.com +123du.cc +123ems.com +123fc.com +123fh.com +123haitao.com +123haiwai.com +123hao.com +123hdp.com +123huaiyun.com +123juzi.com +123kanfang.com +123langlang.com +123meiyan.com +123menpiao.com +123nice.net +123ox.com +123pan.com +123panpay.com +123pans.com +123qibu.com +123qy.com +123shopee.com +123si.org +123slg.com +123ths.com +123u.com +123v.net +123webgame.com +123wk.com +123xfw.com +123xueshu.com +123yiche.com +123ypw.com +123yx.com +124866.xyz +125.la +125180.com +12530.com +12533.com +1256789.xyz +12580.com +12580.tv +12580life.com +12590d0ff10272.beer +125cn.net +125edu.com +125job.com +125p.com +125school.com +125visa.com +125y.com +125yan.com +126.am +126.com +126.fm +126.link +126.net +126blog.com +126disk.com +126doc.com +126job.net +126qiye.com +127.com +127.net +1278721.com +127cdn.com +127xx.com +127z.com +128456.com +1288.tv +12880.com +128d3a16610271.beer +128qd.com +128sy.com +128uu.com +12988.net +129t.com +12dzx.com +12e6824e11013.beer +12ef916d92d482fa.com +12gang.com +12h5.com +12ha.com +12kanshu.com +12ketang.com +12ky.com +12miao.com +12pk.com +12py879p9p.com +12sporting.com +12yao.com +12ym.com +13.gs +130.org +130014.xyz +130158.com +131.com +13100455400.com +13112.com +1312.vip +13124.com +13131313131.com +1314.io +1314520sz.com +1314gl.com +1314h.com +1314study.com +1314tkd.com +1314wallet.com +1314zf.com +1314zhilv.com +131cc.com +1322.com +13233.org +132lawyer.com +1330.net +1332vp.com +133300.com +13377608388.com +13384.com +133998.com +13482896776.com +1350135.com +135031.com +135139.net +135309.com +135650.com +13567.com +1356789.com +1357vip.com +135958.com +135995.com +135bianjiqi.com +135e.com +135editor.com +135edu.com +135plat.com +135yuedu.com +136.com +1360.com +136136.com +1362-rfwi.cc +13636.com +1366.com +13667703999.com +136bet.app +136fc.com +136hr.com +136pic.com +13707.net +137139.com +13720.com +13726936178.com +137365.com +1374.com +13793085458.com +13793277711.com +137home.com +137y.com +138.net +13800.net +13800100.co +13800100.com +1380898.com +138379.com +138gzs.com +138job.com +138pet.com +138top.com +138vps.com +139.com +139000.com +13901559172.com +1391.com +13910.com +139130.com +139135.com +1392189.com +13937180868.com +13980.com +1399vip.com +139cm.com +139ee.com +139erp.com +139game.com +139game.net +139play.com +139shop.com +139talk.com +139wanke.com +139y.com +139zhuti.com +13a.com +13c283b0710281.beer +13cr.com +13e7.com +13ejob.com +13freight.com +13gm.com +13jue.com +13lm.com +13q19b8wgb.com +13qh.com +13s.co +13th.tech +13ww.net +13xiaoshuo.com +13yx.com +14033.live.streamtheworld.com +140414.com +1404c4ce1d63a0d7.com +1415926.com +1415926.mobi +141799c86c1ba267.com +142857.red +14294.com +143614.xyz +14498.com +1451cn.com +14565cabd1011.beer +146368.com +14776ac8e1022.beer +147seo.com +148-law.com +1488.com +148com.com +148la.com +14944.net +14f99ce2609c0071.com +14hj.com +14play.net +14xd.com +14ygame.com +150100.com +150170.com +150ce9517a529b73.com +150cn.com +151.hk +1510game.com +15111223344.com +15140.com +1515.website +15153.com +15166.com +151733.com +1518.com +151m.net +151rs.com +151top.com +151web.com +15201.com +15211223344.com +152500.com +1527ego.com +153.com +15311223344.com +153332.xyz +153g.net +15426.org +15440.org +1545ts.com +155.com +155155155.xyz +1556.net +1559.com +155idc.com +156186.com +156669.com +156pay.com +156zy.suyunbo.tv +157110.com +157300.net +157seo.com +158566.com +1588.tv +158c.com +158wf.com +159.com +15982.com +159shouji.com +15beipk.com +15bl.com +15gg.com +15gift.com +15hr.com +15hr.net +15job.com +15kuaixiu.com +15lu.com +15ms.com +15scsc.com +15sn.com +15tqw.com +15wkd6i45lq3.com +15xdd.com +15yl.com +15yunmall.com +160.com +1601sy4ge0.com +1606c348011042.beer +160c7443c1019.beer +160dyf.com +160job.com +160yx.com +16109.com +161580.com +1616.net +16163.com +1616n.com +16177.net +1617k.com +1618.com +1626.com +163.cm +163.com +163.fm +163.gg +163.link +163.lu +163.net +163110.com +1633.com +1633.store +1633d.com +163501.xyz +163663.com +1637.com +163888.net +1639f577b1022.beer +163adl.com +163cdn.com +163cms.com +163cn.link +163cn.tv +163cp.com +163cs.com +163fen.com +163guangdong.com +163guoqi.com +163gz.com +163henan.com +163hot.net +163hubei.com +163hunan.com +163img.com +163industry.com +163jiasu.com +163k.cc +163k.com +163kada.com +163lady.com +163liao.com +163mail.cc +163mail.com +163mail.net +163nasa.com +163nos.com +163ns.com +163pinglun.com +163py.com +163qb.com +163qikanlunwen.com +163qiyukf.com +163wh.com +163yu.com +163yun.com +164580.com +16466.com +165123.com +16537.ru +16587.com +165image.com +165image.vip +165zhuji.com +166.com +166.net +16612.cc +166161.com +166511.com +1665213d91017.beer +1666.com +1668.net +1668hk.com +166cai.com +166cdn.com +166dns.com +16757.com +16768.com +168-hx.com +16816.com +168267xz.com +168338.com +16835.com +16838.com +1686888.com +1688.com +16885.com +16886000.com +168866.com +16888.com +1688988.com +1688b2b.com +1688du.com +1688e.com +1688eric.com +1688la.com +1688lucky.com +1688ru.com +1688s.com +1688tsw.com +1688zhuce.com +16899168.com +168auto.com +168chaogu.com +168dc.com +168dmj.com +168dns.com +168hs.com +168job.com +168kaifu.com +168kk.com +168kn.com +168lyq.com +168mlj.com +168moliao.com +168rcw.com +168tea.com +168tex.com +168trucker.com +168xiezi.com +168zcw.com +169.com +169163.com +16925500.xyz +169369.com +16949pcb.com +1696.com +169666.xyz +169700.com +16988.com +16999.com +169it.com +169jk.com +169ol.com +16app.tv +16boke.com +16bus.net +16buzhi.com +16c1.com +16ceshi.com +16ds.com +16fan.com +16fc0df828e1570e.com +16first.com +16game.net +16hyt.com +16kang.com +16ker.com +16lao.com +16map.com +16p.com +16pic.com +16rd.com +16sucai.com +16type.com +16tz.com +16wl.cc +16xx8.com +17.com +170.com +170066.com +17025.org +170601.xyz +17083731a1019.beer +170hi.com +170mv.com +170tao.com +171026.com +17167.com +17173-inc.com +17173.com +17173.net +17173cdn.com +17173gc.com +17173ie.com +17173v.com +17173vr.com +17173vr.net +17173yx.com +17178.com +1717pk.com +1718china.com +1718world.com +171tax.com +171win.net +17207.com +17293879b10261.beer +172haoka.vip +172l.com +172mix.com +172tt.com +172xiaoyuan.com +173.com +173.hk +173.tv +1732.com +1732.net +17345.com +17350.com +17351.com +17365h5.com +17365pc.com +1739705934745550.com +173cs.com +173eg.com +173fahao.com +173fc.com +173fh.com +173funny.com +173ie.com +173ie.net +173kan.com +173kw.com +173kz.com +173on.com +173shouyou.com +173shouyou.net +173sy.com +173tuku.com +173uu.com +173yeyou.com +173yeyou.net +173zb.com +173zy.com +1744.cc +17495.com +175045d8e62848be.com +1755.com +17566.com +1758.com +175aa.com +175cinemas.com +175club.com +175game.com +175ha.com +175hd.com +175kh.com +175pt.com +175pt.net +175sf.com +175wan.com +175yo.com +17666.mobi +1766bbs.com +17673.com +1768.com +176quan.com +176web.net +1773.com +1778.com +177xfb.com +178.com +178.net +178198.com +178448.com +1787.ink +178768.com +178800.cc +178871.xyz +17888.com +178du.com +178hui.com +178linux.com +178rw.com +178yy.com +178zhaopin.com +179.com +179179.com +1797.cc +17986.net +17989.com +179cy.com +179e.com +17admob.com +17ai.me +17aifun.com +17b.net +17bang.ren +17bdc.com +17beijiang.com +17bianji.com +17biao.com +17bigu.com +17biying.net +17bt.com +17byh.com +17c13ae4a36b8862.com +17c8d205dbcbc534.com +17cdn.com +17ce.com +17chacha.com +17chdd.com +17cma.com +17coding.info +17d.co +17dao.com +17dap.com +17dawan.com +17dc.com +17ditu.com +17dm.com +17donor.com +17dp.com +17duu.com +17emarketing.com +17et.com +17ex.com +17f.co +17fandai.com +17fee.com +17feia.com +17fengguo.com +17fengyou.com +17fifa.com +17font.com +17foreign.com +17forex.com +17fpv.com +17g.com +17game.com +17gaoda.com +17getfun.com +17golang.com +17guagua.com +17gwx.com +17haibao.com +17hc.com +17house.com +17hpl.com +17huahua.com +17huang.com +17huayuan.com +17huo.com +17huodong.com +17ic.com +17itou.com +17ivr.com +17jc.net +17jiaoyu.com +17jiedu.org +17jita.com +17jzt.com +17k.com +17kan.cc +17kgk.com +17kjs.com +17koko.com +17kouyu.com +17kqh.com +17kss.com +17kuxun.com +17kxgame.com +17kzy.com +17l18w9s1z.com +17lai.org +17lai.site +17lele.net +17lewan.net +17lht.com +17liuxue.com +17ll.com +17look.com +17m3.com +17meb.com +17meiwen.com +17mqw.com +17ms.com +17neo.com +17oh.com +17ok.com +17only.net +17p.co +17p2mz326p.world +17pa.com +17palyba.com +17popo.com +17pr.com +17pw.com +17python.com +17qcc.com +17qiche.com +17qiqu.com +17qread.com +17qzx.com +17rd.com +17rd.net +17read.com +17relax.com +17roco.com +17sfc.com +17shanyuan.com +17shenqi.com +17smart.net +17sort.com +17startup.com +17sucai.com +17suzao.com +17swan.com +17syi.com +17sysj.com +17t.co +17tanwan.com +17taoca.com +17taotaoa.com +17taotaob.com +17taotaoba.com +17taotaoc.com +17tcw.com +17tigan.com +17tiku.com +17toushi.com +17track.net +17ttt.com +17tx.com +17u.com +17u.net +17u1u.com +17u7.com +17ugo.com +17uhui.com +17uhui.net +17uoo.com +17usoft.com +17usoft.net +17utt.com +17uxi.com +17v5.com +17van.com +17vin.com +17vsell.com +17wan7.com +17wanba.com +17wangdan.com +17wansf.com +17wanxiao.com +17wclass.com +17weike.com +17wendao.com +17whz.com +17win.com +17ww.cc +17xianwan.com +17xing.com +17xsj.com +17xueaoshu.com +17xueba.com +17xueshe.com +17xuexi.com +17xxl.com +17xxw.com +17y.com +17ya.com +17yaoqu.com +17ym.org +17you.com +17yund.com +17yunlian.net +17yunzhijiao.com +17yunzhijiao.net +17yy.com +17zhiliao.com +17zhuangxiu.com +17ziti.com +17zjh.com +17zub.com +17zuoye.com +17zuoye.net +17zuqiu.com +17zwd.com +17zyxy.com +17zyxy.net +18.cm +18000000001.com +1800zz.com +18023.com +18095.com +18095.work +180disk.com +180qt.com +180yy.com +1811d2af81022.beer +181709bd610271.beer +18176631811.com +18183.com +18183g.com +18183sf.com +181855.com +1818hm.com +181b5f7e71011.beer +181ps.com +181ue.com +18251.org +18263.vip +182682.xyz +182yg.org +18318.com +18375.com +183me.com +183post.com +183read.cc +183read.com +1845p3hr95.com +18488.com +185185.com +1857qc.net +185c72b7d750569a.com +1860sf.com +1866.tv +18665348887.com +186688.com +18713d3521023.beer +1872001.com +1873game.com +1874.cool +18778450600.com +187997.com +188.com +188.net +188.vip +188158.com +188187.xyz +188188.org +18837331771.com +18856.com +188628.com +1888.com.mo +18888.com +188bifen.com +188bio.com +188cdn.com +188hi.com +188lanxi.com +188mb.com +188pi.com +188soft.com +188wan.com +188yd.com +189002.com +1892139.com +18937777777.com +18999666.xyz +189cha.com +189che.com +189cube.com +189ebuy.com +189jxt.com +189qas.com +189read.com +189sec.com +189smarthome.com +189store.com +189works.com +189young.com +18aa28dfd1020.beer +18art.art +18av.com +18d9535531011.beer +18dao.info +18daxue.com +18db5cd8710292.beer +18dx.com +18ebank.com +18fd54f1b1114.beer +18fzl.com +18guanjia.com +18imall.com +18inet.com +18ishop.com +18istore.com +18join.com +18juyou.com +18l.net +18ladys.com +18link.com +18ph.com +18q.co +18qh.com +18qiang.com +18qingqu.com +18snf.com +18t0f515a3.com +18touch.com +18wk.com +18yl.com +18zhongyao.com +18zhuanqian.com +18zn.com +18zp.com +18zw.com +19.com +190.vip +1900.live +19000yy.com +1900m.com +1903beer.com +1903it.com +1904bus.com +1905.com +190757.com +190cai.com +19183.live.streamtheworld.com +19196.com +19197a01ee502e4c.com +1919game.net +191game.com +192ly.com +192sm.com +1931.com +1934xjzy.com +1937china.com +1937cn.com +1937nanjing.org +193839.com +193sihu.com +194610.xyz +1947.cc +1949idc.com +194nb.com +195155.com +195268032591463.icu +195idc.com +196b7adb23969e39.com +196g.com +196r.gg +197.cc +197.com +197232.vip +1977088.com +197784.com +197854.com +19789.com +197924.com +19799.com +198358.com +19840423.com +198434.com +198503.xyz +198526.com +1985cd.com +1985qg.com +1987619.com +1987cn.com +1987yp.com +1988.tv +19888.tv +198game.net +1990i.com +199238.vip +1993sc.com +199508.com +199604.com +1997sty.com +1998mall.com +1998n.com +1998r.com +1999year.com +199it.com +199u2.com +199yt.com +19adulttoys.shop +19c8.com +19call.com +19call.net +19cntv.com +19d1341dfd0a74d4.com +19ed5ce761013.beer +19lou.com +19mini.com +19mro.com +19pay.net +19ued.com +19where.com +19x19.com +19yxw.com +19zhan.com +1a22.com +1a4a282fe1010.beer +1aa071e45acb08d2.com +1aab715d01015.beer +1ac6404321019.beer +1afaecefe1014.beer +1amen.com +1ang.com +1aq.com +1auto.net +1b0dbdb5310311.beer +1b0y8tocaz24.com +1b17.com +1b1tech.com +1b22e3a337fe5542.com +1b3e11b2e88c6129.com +1baf107ed1014.beer +1blx503444.com +1boshu1.com +1browser.net +1bus.net +1c0d1n1f0l1y.cc +1c38.com +1c767ba9310272.beer +1c96b435fa52e4bf.com +1cae.com +1caifu.com +1caitong.com +1card1.com +1cdakj.com +1cent.xyz +1checker.com +1chong.com +1cloudsp.com +1cnmedia.com +1cno.com +1d0b8b3d1800debe.com +1d1d100.com +1d21653941c21219.com +1d9z.com +1dao99.com +1date1cake.com +1dcdp4.com +1de6de84b1017.beer +1der-ad.com +1diaocha.com +1diary.me +1drv.ws +1dw9r53h79.com +1e44f70c510272.beer +1e9d98e731024.beer +1ed3277798d157ac.com +1f11.com +1f1bc1d5310272.beer +1f371be461017.beer +1f6cd3ca611032.beer +1f71060e75b35349.com +1fangchan.com +1fenlei.com +1flash.net +1foo.com +1fooai.com +1g31.com +1gaifang.com +1gbru.com +1gcat.com +1gdoutian.com +1gesem.com +1ggame.com +1gow.net +1haigtm.com +1haitao.com +1hangye.com +1haogu.com +1hdru-hls-otcnet.cdnvideo.ru +1hkt.com +1hourlife.com +1hshop.com +1huamu.com +1huizhan.com +1hwz.com +1ij6ut.com +1iptv.com +1j1x.com +1jbest.com +1jh3a5806i.com +1jiesong.com +1jkbie336689.com +1ju.com +1juhao.com +1juzi.com +1k100.com +1k2k.com +1ka123.com +1kapp.com +1ke.net +1kic.com +1kkk.com +1kmxc.com +1kuang.com +1kx.me +1kxun.com +1kyx.com +1law.vip +1liantu.com +1ljx.com +1lou.com +1lzs.com +1m.net +1m3d.com +1m85.com +1mall.com +1maoshua.com +1mdoutian.com +1menjin.com +1mfg.com +1miba.com +1mishu.com +1mit.com +1mjz.com +1mmbie336689.com +1mmed.com +1more.com +1ms.run +1mushroom.com +1mutian.com +1mxian.com +1n1v97c96h.com +1nami.com +1nfinite.ai +1nmob.com +1nongjing.com +1note.life +1nyz.com +1o1o.xyz +1paibao.net +1plas.com +1pm2.com +1ppt.com +1pxs.com +1q2q.com +1qfa.com +1qia.com +1qianbao.com +1qianbao.net +1qirun.com +1qishu.com +1qit.com +1qsf.com +1r0zwootq4.com +1r1g.com +1renshi.com +1safety.cc +1sapp.com +1shangbiao.com +1shoucang.com +1sj.tv +1skp.com +1smart.org +1sohu.com +1speaking.com +1st56.com +1stacks.net +1stchip.com +1styan.com +1sw12mvkbp.com +1szq.com +1t.gs +1t1t.com +1tai.com +1tdw.com +1textile.com +1ting.com +1tjob.com +1tong.com +1toon.com +1tu-design.com +1tu.com +1tuikem.com +1uuc.com +1w1w314c71.com +1wang.com +1xbet88.com +1xinzulin.com +1xlala.cc +1xmb.com +1y.com +1y0g.com +1y2y.com +1yabc.com +1yangai.com +1yaoda.com +1yb.co +1ycdn.com +1yd.me +1ydt.com +1yinian.com +1ysh.com +1yunhui.com +1yyg.com +1zhangdan.com +1zhanshou.com +1zhao.org +1zhe.com +1zhengji.com +1zhixue.com +1zj.com +1zjob.com +1zu.com +2-33.com +2-class.com +2-mm.net +2.biz +20001104.com +2000200.com +200022.xyz +2000888.com +2000dns.com +2000new.com +2000y.net +20021002.xyz +2003996ab2b800ac.com +2003n.cc +2003n.com +2006q.com +20087.com +2008php.com +2008red.com +2008zwe.com +200call.com +200rtu04.bar +200wan.com +200y.com +200zi.com +201061.com +201201.com +2012jh.com +20130123.com +201314520.net +2014.mobi +20150.net +201551.com +2016os.com +2016ruanwen.com +2016win10.com +20170228.com +20171117.com +2017338.com +20174555.com +20188.com +2018zjjly.com +20191209.xyz +2019cdac.com +201g.com +202014.xyz +202030.com +2022.work +202271.xyz +2022cdnpl.com +2023.com +2023game.com +2024qq.com +2025.net +202wan.com +203328.com +2048ai.net +2048sj.com +2049baby.com +204cloud.com +2050life.com +2052ce12d523062f.com +206zz.com +207xz.com +2080ly.com +2093hd.com +2099xs.com +20e2554096acf2c6.com +20fl.com +20images10.com +20images21.com +20images25.com +20images7.com +20ju.com +20kf.com +20on.com +20planet.com +20qu.com +20xs.org +20xue.com +20xy.cc +20yy.com +20z.com +21-sun.com +210997.com +210d6afa17b4823f.com +210z.com +2113.com +2114.com +2115.com +211600.com +21168.org +21191.vip +2119915.com +211cad.com +211d2977a10301.beer +211hr.com +211ic.com +211zph.com +212200.com +212300.com +212313.com +2125.com +212512124156.icu +21263.net +2128673cd1013.beer +2130453ff61f34c1.com +21322.org +2133.com +2133bbs.com +21373.com +2144.com +2144gy.com +215489736524785.icu +2155.com +215soft.com +2165588.com +216tt.com +217.net +21713.org +2177s.com +217wo.com +21826aafe2a48426.com +218318.com +21869.org +218996.com +2189cok.com +21ask.com +21bcr.com +21beats.com +21bowu.com +21bx.com +21cake.com +21cbr.com +21cccc.com +21ccnn.com +21ccvn.com +21cd.com +21cloudbox.com +21cn.com +21cn.net +21cnentmail.com +21cnev.com +21cnhr.com +21cnimg.com +21cnjy.com +21cnjy.net +21cnsales.com +21cnsungate.com +21cntx.com +21cos.com +21cp.cc +21cp.com +21ctest.com +21cto.com +21dagong.com +21datasheet.com +21deal.com +21dianyuan.com +21dida.com +21dtv.com +21ejob.com +21eline.com +21epub.com +21etm.com +21fid.com +21food.com +21fv52efm1.com +21gold.org +21good.com +21hifi.com +21hospital.com +21hyzs.com +21ic.com +21icsearch.com +21ido.com +21jiao.net +21jingji.com +21js.com +21kan.com +21ks.net +21kunpeng.com +21ld.com +21maoyi.com +21mcu.com +21mmo.com +21mould.net +21na.com +21our.com +21qa.net +21qphr.com +21qupu.com +21rv.com +21shhr.com +21shipin.com +21shte.net +21sjmg.com +21sla.com +21so.com +21softs.com +21spv.com +21tb.com +21teacher.com +21tjsports.com +21tx.com +21tyn.com +21uv.com +21van.com +21viacloud.com +21vianet.com +21voa.com +21wecan.com +21wenda.com +21wenju.com +21xc.com +21xcx.com +21xfbd.com +21xianhua.com +21xl.info +21xuema.com +21yangjie.com +21yibiao.com +21yq.com +21ytv.com +21zbs.com +22.com +220840.com +220c.com +221234.xyz +221400job.com +22145.com +2217.com +221700.com +222.com +22221111.com +222579.com +22283.live.streamtheworld.com +222abc999abc.com +222bz.com +222i.net +222pcb.com +2233488aa7.shop +22336699.xyz +2238202.com +2239.com +22393.live.streamtheworld.com +2243.com +22442400.com +2247.com +224700.com +224837439.xyz +224m.com +225.cc +2255039.com +2258.com +2259.com +225f360dca52f6cf.com +225image.com +225image.vip +2265.com +226500.com +226531.com +226969.xyz +226yzy.com +2280.com +2281wa.ren +2288.org +2288116ab4.shop +228job.com +229.com +2295.com +2298.com +22ba.com +22baobei.com +22bw.com +22cc0971910251.beer +22dm.com +22edu.com +22hd.com +22lianmeng.com +22lrc.com +22mt.in +22n.com +22net.com +22plc.com +22pq.com +22shop.com +22tianbo.com +22tj.com +22vape.com +22vd.com +2305.org +230890.com +231083.com +231122.com +2317.com +231e3dffa1010.beer +2321111.com +232232.xyz +2323u.com +2323wan.com +232485.com +2329.com +233.com +2330.com +233000.com +2333333333333.com +2333u.com +23356.com +233863.com +2339.com +233id.com +233leyuan.com +233lyly.com +233netcloud.com +233netpre.com +233netpro.com +233py.com +233xyx.com +2344.com +2345.gd +2345.net +23456789.xyz +23456v.com +2345cdn.com +2345cdn.net +2345download.com +2345ff.com +2345ii.com +2345mbrowser.com +2345soso.com +234du.com +234f.com +234f0188110291.beer +234fang.com +2354b5daa10311.beer +236306.com +236400.com +236501.xyz +2366.com +23673.com +236z.com +2375.org +2375sj.com +238000.net +238090.com +238e22bf310251.beer +2392fe36a1019.beer +239300.net +23bei.com +23book.com +23class.com +23cube.com +23dns.com +23do.com +23du.com +23e489f9600657c1.com +23e4cb2581013.beer +23img.com +23job.net +23ks.com +23luke.com +23mofang.com +23qb.com +23qb.net +23qcw.com +23sk.com +23txt.com +23us.so +23us23us.com +23uswx.com +23uswx.info +23uswx.net +23wow.com +23wx.cc +23wx.io +23xsw.cc +23ye.com +23yy.com +23zw.com +240yx.com +24198ef3f855c8ff.com +24331.org +24335.org +246546.com +246b35da610272.beer +246ys.com +2478.com +248.com +2486.org +248xyx.com +249m.com +24av.com +24bb0cd0c3b8480d.com +24biao.com +24dab50b3223e582.com +24dq.com +24geban.com +24haowan.com +24hmb.com +24jiankong.com +24k99.com +24kplus.com +24maker.com +24money.com +24om.com +24shi.cc +24th.com +24timemap.com +24u7tos.com +24zbw.com +250.cc +2500.tv +25000li.com +2500city.com +2500sz.com +250340.com +250a3526251.xin +2512124740355.icu +251400.com +2523.com +25285577.com +253.com +25395.vip +253952.com +253u.com +2541.com +254254.com +254game.com +2551aa29811031.beer +255616.com +2559e5f081017.beer +255star.com +256app.com +256cha.com +25752.com +258.com +258288.com +25847.com +25892.com +258ch.com +258en.com +258fuwu.com +258sd.com +258weishi.com +25992.com +25az.com +25dddaa6f10261.beer +25dir.com +25dx.com +25fe391eb68e3f9c.com +25game.com +25nc.com +25pp.com +25pyg.com +25q7ekcc67.com +25rk.com +25tmw.com +25un.com +25wy.com +25xg.com +25xianbao.com +25xm.com +25xz.com +25yi.com +25yz.com +260.net +260068.com +26210.org +2628liao.com +2629.com +263-mail.net +263.com +263.net +26330a8c11017.beer +263cv.net +263em.com +263fc.com +263idc.com +263idc.net +263live.net +263vps.com +263xmail.com +263y.com +264006.com +264321.com +264400.com +265.com +26582.vip +26595.com +265g.com +265h.com +265xh.com +266.com +266.la +266fbded61019.beer +266wan.com +2671111.net +26779.org +2677dl.com +2678.com +26785.org +267pd1841t.com +2686.com +2688.com +268v.com +269.net +26923.com +26a9118418e77c84.com +26c23b9f311042.beer +26ce3e05310251.beer +26d124fdb11032.beer +26duc.com +26e02ca8210272.beer +26f4a1f8f10271.beer +26host.com +26joy.com +26ks.cc +26s.com +26youxi.com +270326012f82.icu +270che.com +270top.com +27195.vip +272500.com +27270.com +27399.com +273u.com +2743b3ed63ebb546.com +27492.com +275.com +27512.org +2755005.com +277sy.com +277t.com +27813000.com +2789a91661019.beer +278wan.com +279love.com +279tt.com +27al.com +27cat.com +27d7c9e9b3a34696.com +27daili.com +27l.com +27tj.com +27ws.com +27xuexiao.com +28.bet +28.com +281010.com +28126.cc +281669.vip +281826.vip +282626.xyz +2827.com +28283.com +282g.com +283d.com +2848168.com +28493.com +2850.com +28517.org +2858999.com +28715.vip +288idc.com +289.com +2896.ro +2898.com +28beiduo.com +28ce6d14004bae01.com +28d4cc3671024.beer +28d7baa3e1013.beer +28e4cd79f1023.beer +28eb96ed4da91317.com +28gl.com +28gua.com +28ka.com +28khy.com +28qp.com +28rv.com +28sog.com +28tui.com +28yt.com +28z9.com +28zhe.com +29029.com +2903866.net +291315.com +2918.com +29227e5771014.beer +2925.com +292775.com +29293.com +293.net +29592.net +296u.com +29736.org +29797.com +2980.com +29888.org +299906.com +29c17146910271.beer +29c385dc5e75af06.com +29ca702351014.beer +29dnue.com +29nh.com +29xf.com +2a965464310251.beer +2agi.net +2ai2.com +2ai2.net +2amok.com +2apzhfa.xyz +2av7.com +2b079fbcd1009.beer +2b71f0159d3b2d42.com +2b7a44c2110251.beer +2bbd099f5dc4d3aa.com +2bkw.com +2broear.com +2bulu.com +2bzq.com +2c5bf25c11b8dc3e.com +2c71b194031fc683.com +2c883aeffbeef6c7.com +2caipiao.com +2ccc.com +2chcn.com +2cloo.com +2cname.com +2cq.com +2cshop.com +2cto.com +2cubeglobal.com +2cycd.com +2cycomic.com +2cyxw.com +2cyzx.com +2d1a542c1e340653.com +2d261b4e6e641e43.com +2d3d5d.net +2d6cd83bf10261.beer +2d8f1726e1d61d69.com +2danji.com +2db3d5c761abe51b.com +2dcode.biz +2df.me +2dffbc61dea7ca0a.com +2dfire.com +2dfire.info +2dmaker.com +2dph.com +2du.net +2dyou.com +2e30175771022.beer +2e30a72a21023.beer +2e56m039tk.com +2ea31935add3d6b0.com +2eb4189e6451af49.com +2ed1fefd710272.beer +2ed5d.com +2ed7d8ec410271.beer +2ee8565103abf121.com +2eka.cloud +2emai.com +2f.com +2f24ad2dc10261.beer +2facb31bb10272.beer +2fda37d4c10292.beer +2fz1.com +2gdt.com +2gei.com +2haha.com +2haitao.com +2handsmt.com +2haohr.com +2heng.xin +2hu.net +2hua.com +2i1i.com +2ibook.com +2ic.cc +2ita.com +2itcn.com +2j88.com +2jianli.com +2k27cny7hx.cfd +2k2k.com +2kb.com +2kfb.com +2kk.cc +2kka.com +2kno.com +2ktq.com +2kxs.info +2kxs.org +2kxy.com +2kzw.info +2l4938221x.com +2lian.com +2liang.net +2ll.co +2loveyou.com +2m2j.com +2m3m.com +2ma2.com +2mcnxs.cc +2mdn-cn.net +2mjob.com +2mould.com +2mpq9iu440.com +2muslim.com +2o.cx +2or3m.com +2p.biz +2p.com +2pcdn.com +2q10.com +2qsc.com +2qupu.com +2r3r.com +2rich.net +2sdx.com +2sey.com +2sjc.com +2sonar.com +2sx.net +2t58.com +2taobao2jd.com +2tianxin.com +2tt.net +2tubaobao.xyz +2tx.com +2umj.com +2urch0.info +2urg1y.info +2urk3j.shop +2uroz.info +2v8d.com +2v9t3xf9z2.com +2vfun.com +2w.com +2w.ma +2weima.com +2xiazai.com +2y9y.com +2ychem.com +2yq.org +2yuanyy.com +2yup.com +2yx8.com +2z96vx20bx.com +2zhan.com +2zhk.com +2zimu.com +2zzt.com +3-3.me +3-hospital-cqmu.com +3.biz +30.net +3000.com +300033.info +30006124.xyz +3000api.com +3000idc.com +3000soft.net +3000test.com +3000ways.com +3000xs.cc +3001.net +300113.com +300280.com +300624.com +3008268.com +300hu.com +300ppt.com +300zi.com +3011.net +3016.com +301688.com +301mba.com +3023.com +302302.xyz +302423a641021.beer +303c.com +3044.com +30583a8b910261.beer +3062d65271020.beer +306t.com +3072ccba588e48d0.com +308.app +308.tv +30888.com +3099.net +30aitool.com +30c.org +30cgy.com +30daydo.com +30fun.com +30gaokao.com +30ka.com +30play.com +30post.com +30sche.com +30th-feb.com +30vps.com +30w.co +31062gs7f9.com +310game.com +310s-2520.com +310tv.com +310v.com +310v.net +310win.com +311.biz +311100.com +311wan.com +312000.net +31260939.com +31264.org +312green.com +313033.com +313515.com +314pay.com +315008.com +3150315.com +3152018.com +3158.com +3158bbs.com +315958.com +315banzhao.com +315che.com +315code.com +315dian.com +315fangwei.com +315hyw.com +315i.com +315img.com +315mro.com +315online.com +315rx.com +315tech.com +315tsz.com +31609.com +31668.com +316watches.com +3171688.com +317608.com +31793.com +317hu.com +318595.xyz +3188.la +318ek.com +318jskyycq.com +318yishu.com +3198.com +31998a86110251.beer +319d3741ad1da914.com +31amjs.com +31b081b851019.beer +31b675a9cce68585.com +31bzjx.com +31cg.com +31d.net +31doc.com +31expo.com +31fabu.com +31food.com +31games.com +31gamestudio.com +31huiyi.com +31i9ti.com +31idc.com +31jf.com +31jgj.com +31knit.com +31m49.com +31maque.com +31meijia.com +31ml.com +31mold.com +31ns.info +31pump.com +31rent.com +31sf.com +31travel.com +31wj.com +31xj.com +31yarn.com +31yr.com +320921.com +320g.com +321.net +321002.com +321009.com +32109.com +321274.com +321321321.vip +321a6d50a1009.beer +321ba.com +321cad.com +321cy.com +321fenx.com +321go.com +321key.com +321mh.com +321sq.com +321tips.com +321zou.com +3223.com +322799.com +322h.com +322wl.com +3230.com +32331.vip +3234.com +3235587.com +3237.com +32495fe5f11042.beer +325802.net +3259.com +325999.com +3259b95be11032.beer +3269.org +32768k.net +327aa34f510311.beer +3280.com +32800.com +3283773e9dc5cde5.com +3286.cc +328f.com +328vip.com +3290.com +32974z0361.com +32a5d6351989b210.com +32cd.com +32ka.com +32kan.com +32r.com +32rsoft.com +32us.com +32wan.com +32xp.com +33.com +3304399.com +3304399.net +330d5ba0e1024.beer +33105.com +331234.xyz +3320.net +3321.com +3322.cc +3322.net +3322.org +3322032.com +33226163.xyz +3323.com +33230.org +3323399.com +332831.com +333-555.com +333.com +33315.com +333232.xyz +333333.com +333333.org +3335665.com +33360.com +333666999.club +3336683.com +3337726.com +3337756.com +3337782.com +33380xl.com +333915.com +3339999.net +3339auto.com +333a51.app +333a58.app +333bbb777kkk.com +333cn.com +333com85.app +333com89.app +333f.com +333iy.com +333job.com +333ku.com +333rh.com +333y3.com +334433.xyz +3344u.com +334837632.xyz +33519.com +3356666.com +3359.com +33591.com +3361.com +33655.net +3366.com +3366.net +336685.com +336688.net +3366886633.com +3366img.com +3366ok.com +336cfe9101009.beer +336woool.com +337000.com +3377577c.app +3377751e.app +3377999c.app +337y.com +3387.com +338888.net +3389dh.com +33988.net +33aml.com +33app.net +33bus.com +33dy.cc +33erwo.com +33fang.com +33ip.com +33iq.com +33jianzhi.com +33lc.com +33ly.com +33map.com +33map.net +33oncall.com +33out.com +33oz.com +33subs.com +33tool.com +33trip.com +33yq.com +34.com +340888.com +3419e2cbf10261.beer +341d88b04156e9d3.com +342200.com +342jinbo.com +34347.com +343480.com +345123.xyz +3454.com +3456-1.vip +3456.cc +3456.com +3456.tv +34563686.work +34580.com +345fk.com +345huishou.com +345idc.com +3464.com +346888.com +346g4247o9.world +348b60ac51011.beer +34a14155f1016.beer +34c5fe453528e605.com +34f04e8d410291.beer +34lou.com +34wl.com +34xian.com +35.com +35.net +350.com +350.net +3500.com +350200.com +350211.net +3503.com +3504cde7b76a2cc9.com +35091.cc +350abc.net +350c.com +3516w.com +35195.vip +352.com +3520.net +352200.com +3525.com +3527.net +353233.com +3533.com +35335.com +3536.com +35463.org +354d7967c11032.beer +3551.com +3558b3020217b9a3.com +355xx.com +356123.com +35617.vip +35667.com +3566t.com +356884.com +357.com +357global.com +358.com +359203.com +35941.com +3595.com +359798114.xyz +35app.com +35ba.com +35d1.com +35db4d2761021.beer +35dxs.com +35e0510ae11032.beer +35go.net +35inter.com +35jk.com +35lz.com +35nic.com +35pic.com +35sf.com +35xss.com +35zww.com +36-7.com +36.cc +36.la +360-g.net +360-game.net +360-jr.com +360.com +360.net +3600.net +3600d.com +360114.com +360118.com +360424.com +360500.com +3608.com +360abc.com +360adlab.com +360adlab.net +360adlab.org +360aiyi.com +360anyu.com +360boclub.com +360bsafe.com +360buy.com +360buyimg.com +360buyinternational.com +360byd.com +360bzl.com +360caifu.com +360cdn.com +360changshi.com +360che.com +360chezhan.com +360chou.com +360cloudwaf.com +360daikuan.com +360ddj.com +360dlcdn.com +360doc.com +360doc.net +360doc1.net +360doc11.net +360doc18.net +360doc2.net +360doc21.net +360doc22.net +360doc25.net +360doc30.net +360doc33.net +360doc35.net +360doc36.net +360doc37.net +360doc4.net +360doc7.net +360docs.net +360doo.com +360down.com +360drm.com +360eol.com +360gann.com +360gem.com +360gogreen.com +360gongju.com +360gongkao.com +360gtm.com +360guanai.com +360hapi.com +360hifi.com +360hitao.com +360hqb.com +360humi.com +360huzhubao.com +360hx.com +360hy.com +360hyzj.com +360ic.com +360imgcdn.com +360insurancemall.com +360jianzhu.com +360jie.com +360jinrong.net +360jk.com +360jq.com +360jrjietiao.com +360jrkt.com +360kan.com +360kcsj.com +360kj.net +360ksbd.com +360kuai.com +360kuaixiao.com +360kuaixue.com +360kxr.com +360lion.com +360lj.com +360lnk.com +360loushi.com +360midi.com +360mkt.com +360os.com +360panyun.com +360panyun.net +360powder.com +360qc.com +360qd.com +360qhcdn.com +360qikan.com +360qikan.net +360qnw.com +360qws.com +360qyaq.com +360safe.com +360safedns.com +360sdn.com +360shouji.com +360shouzhuan.com +360shuke.com +360shuoshuo.com +360sides.com +360sides.net +360simg.com +360sjrom.com +360sky.com +360so.com +360so.net +360sok.com +360sou.com +360sou.net +360soucha.com +360sousou.com +360sportwatches.com +360src.com +360sres.com +360stamp.com +360taojin.com +360tianma.com +360timg.com +360tong.net +360top.com +360totalsecurity.com +360tpcdn.com +360tres.com +360tuan.com +360u9.com +360underwear.com +360uu.com +360vcloud.com +360vcloud.net +360vrzy.com +360webcache.com +360wenmi.com +360worldcare.com +360wscdn.com +360wulian.net +360wyw.com +360wzb.com +360wzws.com +360xh.com +360xiaos.com +360xiehui.com +360xinyongka.com +360xkw.com +360xlab.com +360xlab.net +360xlab.org +360xyws.com +360yao.com +360ybj.com +360yijia.com +360youtu.com +360yuanshuo.com +360yuxue.com +360zebra.com +360zhileng.com +360zhushou.com +360zhyx.com +360zmr.com +360zqaq.com +360zqf.com +360zuowen.com +360zuqiu.com +36130.com +361757.com +3618med.com +361cv.com +361dai.com +361mogame.com +361sport.com +361zhao.com +362.cc +36267.vip +363.com +363.hk +363.net +363120.com +363322014.com +3636.tech +363635.com +363u.com +364000.com +36410.org +36476.work +365.com +365.hk +36500.net +365128.com +365135.com +3652.com +36524hua.com +36543.com +365500.com +3656.com +36578.com +365960.com +365autogo.com +365azw.com +365bh.cc +365bj.com +365bmc.com +365bmw.com +365book.net +365cego.com +365cgw.com +365chanlun.com +365chiji.com +365css.com +365cyd.com +365cyd.net +365daan.com +365daygo.com +365dhw.com +365diandao.com +365digitalonline.com +365ditu.com +365editor.com +365eme.com +365essay.com +365f.com +365fanyi.com +365gangqin.com +365gcd.net +365gongchang.com +365good.cc +365heart.com +365hele.com +365hf.com +365htk.com +365huaer.com +365huangjin.com +365ibuy.com +365icl.com +365ime.com +365j.com +365jia.com +365jiankang.com +365jilin.com +365jq.com +365jw.com +365jz.com +365kan.tv +365kandian.com +365key.com +365kl.net +365liye.com +365master.com +365matrix.com +365mmjg.com +365mx.com +365nongye.com +365pcbuy.com +365pingxuan.com +365pk.com +365pp.com +365pr.net +365pub.com +365qipai365.com +365rili.com +365sec.com +365sf89.com +365shequ.com +365sky.com +365sydc.com +365ta.com +365time.com +365ting.com +365tkt.com +365ttcz.com +365tvip.com +365vip.com +365world.com +365xiazai.com +365xs.la +365xuet.com +365yarn.com +365yg.com +365you.com +365yyf.com +365zhaopin.com +365zhuanrang.com +365zmw.com +365zsw.net +365zzx.com +3660bf60ab32baab.com +36612345.com +3663.com +366300.com +366666.net +36683.com +3669yx.com +366club.com +366ec.com +366ec.net +366kmpf.com +366translation.com +36706.com +3673.com +367edu.com +36838.org +36840.com +36885.vip +3688km.com +368mall.com +368tea.com +369110.xyz +36932.com +36939.net +369785.com +3699.cc +3699.co +3699wan.com +369cha.com +369hui.com +36ab8227e10311.beer +36aw.com +36dianping.com +36dj.com +36dong.com +36hjob.com +36jr.com +36kr.com +36kr.net +36krcdn.com +36krcnd.com +36pnes36t0qs.com +36qp.com +36rv3j3.shop +36tw.com +36ve.net +36yc.com +36zpp.com +37.com +37021.com +37051.cc +370fd.com +371.com +371.net +3710167.com +37163.com +371bus.com +371love.com +37201.com +3721.vip +3721520.com +3722.com +37274.com +372951b2210301.beer +3733.com +3733game.com +3737.com +3737k.com +373a5e2a6f8a3f9a.com +373c0f3771021.beer +373f.com +373net.com +373yx.com +37439.com +3761.com +3768.org +377466.com +3774cd2332503d45.com +379.com +37937.com +3794b0fa67e5f83b.com +379art.com +379bst.com +37a15fd3b16897ba.com +37biao.com +37bjw.com +37cbca02a1019.beer +37cos.com +37cu.com +37dh.com +37game2.com +37gjw.com +37gogo.com +37hr.com +37k.com +37laboratory.com +37med.com +37pps.com +37su.com +37swan.com +37tang.com +37tgy.com +37wan.net +37wan.one +37wanimg.com +37wanwan.com +37wanwancdn.com +37women.com +37www.com +37wxwl.com +37x4kf0q4n.com +37yzy.com +37zone.com +37zp.com +3800920.com +3800j.com +380852.com +380871.com +38109222.com +3816.net +3817.com +38198.org +381pk.com +3822edf4d1022.beer +38387.app +3839.com +38393.org +3839apk.com +3839app.com +3839app.net +3839img.com +3839pay.com +3839pic.com +3839vc.com +3839video.com +383k.com +383yun.com +3851120.com +3856.cc +38566.org +385k.cc +38711.cc +38735.vip +388g.com +3892222.com +38999h.vip +38a9018e44a7da0f.com +38b06119b10271.beer +38blog.com +38ejed.com +38film.com +38hack.com +38hot.net +38hp.com +38hzt.com +38mhw.com +38xs.com +38zp.com +39.com +39.net +390seo.com +391065.com +3911.com +3913.com +391k.com +392766.net +393.com +3937.com +3939339.com +394394.com +3949006e510272.beer +394afb34a1020.beer +39507037133f.icu +39655.com +3975ad.com +3975ad.xyz +3975app.com +3975cdn.com +3977s.com +398423277d755d82.com +3987.com +3993.com +399s.com +39amjs.com +39ask.net +39b86269e11031.beer +39b8fe8f4c6f9dee.com +39bfe802d10292.beer +39center.com +39clean.com +39cs.com +39d83s.com +39dg.com +39ej7e.com +39f6e28d71009.beer +39fei.com +39fengliao.com +39h83s.com +39hd.com +39health.com +39jks.com +39kan.com +39kf.com +39meitu.com +39nj8382uq.com +39shubao.com +39shuwu.com +39sk.com +39txt.com +39yst.com +3a2dc2bd21023.beer +3a2studio.com +3a4.net +3a4b5c.com +3afbda6f11015.beer +3ait.com +3alv.com +3aok.com +3apz.com +3aqj.com +3avox.com +3b13795054e3ac5a.com +3b1aj.info +3b1bm3f.shop +3b1bvrwc.info +3b1fcl.info +3b1xgp.shop +3b2479faf10301.beer +3b2o.com +3bag.ru +3bf.cc +3bfc4d6861010.beer +3bu.com +3c1bddb4110301.beer +3c2p.com +3c324f3ae10241.beer +3c3t.com +3c4c142e21021.beer +3c5a7b25910281.beer +3c6a1a5d01015.beer +3c9035c3bd9e7599.com +3cb106206b814b15.com +3cf6c871511032.beer +3chongmen.com +3cjob.com +3conline.com +3cpp.org +3ct.cc +3d-apollo.com +3d-chips.com +3d-gold.com +3d-medicines.com +3d-stereovision.com +3d2000.com +3d2848f7811042.beer +3d503a99384e0d4c.com +3d66.com +3d7ce8a16c0f8781.com +3d9r.com +3daima.com +3dbody.com +3dbt.com +3dbuyu.com +3dbuyu.net +3dcat.live +3ddaz.com +3ddl.net +3ddl.org +3deazer.com +3debut.com +3ded4c0f310311.beer +3dfcs.com +3dgali.com +3dgenomics.org +3dhao.com +3dhoo.com +3dinlife.com +3djulebu.com +3dkunshan.com +3dllc.cc +3dllc.com +3dly.com +3dmaxvip.com +3dmgame.com +3dmgame.hk +3dmgame.net +3dmjiasu.com +3dmomoda.com +3dmxku.com +3dnew.com +3doe.com +3drrr.com +3dsdce.com +3dsjw.com +3dsnail.com +3dtakers.com +3dtank.com +3dtoo.com +3dwebyx.com +3dwhere.com +3dxt.com +3dxy.net +3dzyw.com +3e.net +3e089a2bd1011.beer +3e1f90ccd1016.beer +3e306b2a010272.beer +3e38c7206c1beb1a.com +3e5da509e10271.beer +3e6dfbe90c676f1d.com +3ec933de211031.beer +3echemical.com +3edns.com +3edu.net +3efda91b710311.beer +3elife.net +3etimes.com +3eyes.org +3f20c121e6032c50.com +3f4155b1310311.beer +3f496850f89e7809.com +3f5348d2ff43ee00.com +3f73dbae64fefabb.com +3f9b37df0629ada1.com +3fahudong.com +3fang.com +3fantizi.com +3fb762d23d09f297.com +3fc5960c0be056ce.com +3fcl8.net +3fda.com +3feb063cbf96bd40.com +3fzipper.com +3g-edu.org +3g368.com +3g48.com +3g567.com +3gbizhi.com +3gcj.com +3gdisk.com +3gifs.com +3glasses.com +3gmfw.com +3gogogo.com +3gosc.com +3gpk.net +3gqqw.com +3gsou.com +3gwoool.com +3gxk.net +3h.com +3h1i.com +3h3.com +3h77.com +3haovip.com +3healthcare.com +3heyun.com +3hhinvestment.com +3hmedicalgroup.com +3hmlg.com +3incloud.com +3ins.net +3j3f.com +3jdh.com +3jhuyu.com +3jidi.com +3jlm.com +3jrx.com +3jzh.com +3k.com +3k3cn.com +3ke.cc +3kew.com +3kid.com +3kismet.com +3kjs.com +3kk.com +3kmq.com +3ko.com +3kr.com +3kyi.com +3kzhushou.com +3labtest.com +3laohu.com +3lbrand.com +3lengjing.com +3lmeter.com +3lsoft.com +3m099cey43.com +3mbang.com +3mh0yvx.com +3miao.net +3miko.xyz +3mtw.com +3mu.me +3muzn.com +3n1b.com +3nbb.com +3nfood.com +3ny8.com +3piaochong.com +3png.com +3polar.com +3poo.com +3pw.net +3q2008.com +3qdu.com +3qdu.net +3qdu.org +3qdus.com +3qhouse.com +3qit.com +3qj.com +3qled.com +3qqq.net +3quan.com +3qwe.com +3qxsw.com +3qzone.cc +3r.work +3r5y.com +3rcd.com +3renhe.net +3renwx.com +3richman.com +3rotber.com +3rroll.com +3s-guojian.com +3s.work +3s001.com +3s78.com +3scard.com +3sjt.com +3slift.com +3snews.net +3songshu.com +3sribu.com +3srobotics.com +3stl.com +3sunway.com +3swg.com +3t3.org +3thiku.com +3tilabs.com +3tinkers.com +3tmall.com +3treesgroup.com +3tstore.com +3u.com +3ukkht3yn3.work +3unshine.com +3uol.com +3us.com +3uww.cc +3uww.com +3v.do +3vjia.com +3vjuyuan.com +3vsheji.com +3wcoffee.com +3wen.com +3wfocus.com +3wft.com +3wka.com +3wmm.com +3wyk.com +3x6gr4f829.com +3x7.com +3xgd.com +3xiaoniao.com +3xiazai.com +3xinhome.com +3xyg.com +3y1.com +3y7h.com +3yakj.com +3yoqu.com +3yt.com +3yt.la +3yun.net +3ywepvs8n1.com +3yx.com +3zbsy.com +3zhijk.com +3zhm.com +3zmuseum.com +3zonegame.com +4-xiang.com +4.biz +4.plus +400-lighting.com +400.com +40000-30000.com +4000011520.com +4000022282.com +4000034168.com +4000066666.com +4000156651.com +4000278400.com +4000286188.com +4000500521.com +4000730138.com +4000773040.com +400078.com +4000892990.com +4000979797.com +4000kbpe.bar +4001006666.com +4001113900.com +4001180057.com +400123.com +4001581581.com +4001817899.com +4001890001.com +4001961200.com +400301.com +400332.com +40035.com +400388.com +4006055885.com +4006216888.com +4006300457.com +4006339177.com +4006510600.com +4006631958.com +4006695539.com +4006758160.com +4006787252.com +4006800660.com +4006806555.com +4006906600.com +4007051668.com +4007108885.net +4007112366.com +4007123123.com +4007777958.com +4008-197-197.com +4008000000.com +4008005216.com +4008075595.com +4008100800.com +4008103103.com +4008107107.com +4008109886.com +4008117117.com +4008123123.com +4008258399.com +4008338788.com +4008600011.com +4008618618.com +4008787706.com +4008800016.com +4008824365.com +4008863456.com +4008880999.com +4008880999.net +4008885818.com +4008cn.com +4009.com +4009515151.com +4009870870.com +4009991000.com +400cx.com +400dianhua.com +400gb.com +400ja.com +400kaoyan.vip +400lyw.com +400num.com +400qikan.com +400taocan.com +400vv.com +400web.com +4020.la +40407.com +404886.com +404mzk.com +404wan.com +404youxi.com +405400.com +407wan.com +4080517.com +408399.com +408399.net +4087b09ee4632bb5.com +408cf42720d8be86.com +408ec542b10281.beer +409a1957110311.beer +409c27e4c1015.beer +409d0a7b710241.beer +40bw71.ren +40c53fc1d11021.beer +40cb.com +40images15.com +40images16.com +40le.com +40sishi.com +40xk.com +411-hospital.com +41113.com +41163.org +41188.com +41188844.com +411au.com +4132c3c4011021.beer +413cd5ac210291.beer +413xkyd.com +414500.net +416548ebbf96c1b9.com +4166.net +41739b0aa10301.beer +417628.org +4177.com +41818.net +419600.com +419g.com +41game.com +41gw.com +41huiyi.com +41ms.com +41wan.com +41xt.com +420d586841024.beer +42144.com +421db96b91011.beer +42224b3c51016.beer +422425.xyz +422877.com +4234.org +4234cdn.com +4234q.com +42353.com +423down.com +4243.net +425300.co +425yx.com +426.ltd +42736c12558acabf.com +4275.com +429006.com +42ed983e61019.beer +42how.com +42trip.com +42verse.shop +42xz.com +430d6eba715dabb4.com +4311.com +432.com +432520.com +432b4376611021.beer +43439g.com +435000.com +435200.com +4355.com +43578.com +436400.com +4366.com +4366aa.com +4366ga.com +4366game.com +4366pk.com +4377.com +437zhifu.com +43803a8c410261.beer +4393ce88a10272.beer +4395e6c8b10291.beer +4399-xyx.com +4399.com +4399.net +43999yx.com +4399api.com +4399api.net +4399biule.com +4399data.com +4399dmw.com +4399doc.com +4399er.com +4399hdhh.com +4399hhh.com +4399i.net +4399inc.com +4399j.com +4399mail.com +4399pk.com +4399sj.com +4399swf.com +4399sy.com +4399wanju.com +4399xyx.com +4399youpai.com +4399youxi.com +4399yyy.com +4399zmxy.com +439f2bbb180aecab.com +43cv.com +43ns.com +43xs.com +43yl.com +43zhubao.com +4417.com +44290f2c9bce56ed.com +4444.cc +44440fd0d212bb76.com +4444448.com +4445156.com +44460.com +44481.org +444888qq.com +4450044.com +4450055.com +4451199.com +4451818.com +44552003.com +446dca1e17538cf6.com +44719.org +44749.net +4480.cc +4484.win +44878s.com +4488e4460a95a041.com +448cee8738b7860d.com +449393.vet +44971.com +44983.com +4499.com +44ff56d11fa53a9a.com +44h.co +44hr.com +44iuno85gr.com +44jj.com +44pq.cc +44vs.com +4502512122531.icu +4506ecebe10292.beer +45077.one +450926731.xyz +451057365.xyz +451f46bd110281.beer +453400.com +453600.net +45451.com +4546.org +455522.com +45560ll.com +45575.com +45592.com +455a525cfff81301.com +456.net +45656666.com +456jy.com +456ss.com +456tt.com +457.com +457557.com +4587.com +4587c00611011.beer +458kq.com +459.org +45app.com +45fan.com +45inst.com +45io.com +45it.com +45ns.com +45r.com +45te.com +45win.com +45xie.com +45yx.com +461000.net +462.com +46245fb7d43c13a3.com +46412.com +4644440.vip +46576.org +46644.com +46721.org +46771313.com +46809.org +4687794fd9.com +46940.vip +4694393.com +46ab3da510d4ccaf.com +46cdn.vip +46d7940171014.beer +46eadc71881fb97a.com +46mlsv.com +46ny920931.com +46ps.com +46xs.com +4714da8871019.beer +471f94eab9784273.com +47295.com +472ac621b11032.beer +4735.com +47365.com +473787.com +4738.com +47462.org +47473.com +474b.com +4765.com +47787.com +4779.com +47819.com +478bc6c1c10301.beer +47964154c11021.beer +479d8573510301.beer +47daili.com +47e17a13ee18fa43.com +47gs.com +47oupy0408.com +47rq.com +47zu.com +480.cc +480.hk +4805555.com +480e7c558d3d8aaa.com +48251413f10281.beer +48267.com +48455m.com +4846.com +4848360.com +48575.com +48670.vip +4869.cc +487.com +4871.org +4888.com +4888033.com +4888777a14.shop +4888g.vip +48905.com +48cdn.vip +48hao.net +48log.com +49.com +491.com +4916a68576d64a34.com +492288.com +492f2622e64c138e.com +4930.com +49333g.com +49333j.com +49358.com +493601.com +49363.com +49377.work +4937711.com +495.cc +495495.com +49568009.com +4957b5fd7265b790.com +496db29b7745a79c.com +497-img.com +497.com +498.net +499-img.com +499n.com +499youxi.com +49app.com +49e7fb6261023.beer +49eb891471010.beer +49ko.com +49ms.net +49pic.com +49r5eoqrd2.com +49vps.com +49xia.com +49you.com +49yu.com +49zz1110002a4.shop +4a38863a11017.beer +4a4779c371024.beer +4abb.com +4ading.com +4anet.com +4apx.com +4aqq.com +4b036c92244f5b1b.com +4b145a7b110292.beer +4b4d913d9b6506e9.com +4b784b66f10311.beer +4b9953f631024.beer +4ba69ed8e10292.beer +4bf85b0f61014.beer +4c28539c4f10ad16.com +4c37ebc131010.beer +4c43edd99cd8bb40.com +4c4866d8179d6f70.com +4c55033b91010.beer +4c5p021888.com +4c645708fabd0e13.com +4ccd82a0d11031.beer +4ci.cc +4cm.cc +4cnzz.com +4cun.com +4d2bc4d7311031.beer +4d458710811011.beer +4d64c7aff11031.beer +4dai.com +4db.com +4de7ab130011974d.com +4dec3cfc0794efb4.com +4do71q84l1.com +4dwan.com +4e0e47ea71022.beer +4e6fe7920a044f98.com +4e7e414fd1015.beer +4ebf1036c1010.beer +4ee.ee +4ef06207210281.beer +4ef870db01022.beer +4eglwkq.com +4everdns.com +4ewriting.com +4f0b987b410311.beer +4f411973f14e0f10.com +4f61.com +4f68340f5b6c21a9.com +4f89.com +4f9bf1e673931484.com +4fang.net +4fd4969ff1022.beer +4fe55e9f6c893405.com +4ggogo.com +4gh6.com +4glte.org +4gqp.com +4gtoefl.com +4h6s.com +4hgame.com +4hii.net +4hmodel.com +4hpy.com +4inlook.com +4jplus.com +4k123.com +4kbizhi.com +4kdesk.com +4kgood.com +4kgou.com +4kya.com +4l.hk +4lzr.com +4ndwc.com +4o.org +4pf6hb.com +4pis.com +4pnt.com +4portun.com +4px.com +4pyun.com +4q5q.com +4qx.net +4s4c0dw764.com +4sai.com +4sender.com +4sender.net +4sjob.com +4sscrm.com +4startime.com +4tdf.com +4thetooth.com +4thworkshop.com +4to66.com +4u1mx79nlw.com +4u4v.net +4w8.net +4xiaoshuo.info +4xiaoshuo.org +4xseo.com +4xx.me +4y4.net +4ye.cc +4yt.net +4yx.com +4zt.com +5-link.com +5.biz +50-jia.com +500.com +5000.com +50004.com +5000yan.com +50011114.com +50014455.com +50016666.com +50018.com +50027.com +500cache.com +500d.me +500doc.com +500du.com +500fd.com +500gm.com +500hj.com +500px.me +500talk.com +500tb.com +500wan.com +500wancache.com +500zhongcai.com +5011.net +501h.com +501wan.com +502258.com +50257e08d1015.beer +5026p06ot6.com +503118.com +50331.net +5033333.com +503b2f379abaf979.com +503error.com +505035.com +5054399.com +5054399.net +505uu.com +5066.com +506u5nf5j5.com +50747.com +507c7d240b2eae97.com +5087.com +508hdsys.com +508mallsys.com +508sys.com +50915.org +50970.com +50bangzh.com +50cnnet.com +50dacaaf86cda9cb85ee95577c9a522bf.com +50pk.com +50sht.com +50vm.com +50xiao.com +50yc.com +50yu.com +50zi.com +50zw.co +50zw.net +51-cf.com +51-jia.com +51-visa.com +51.am +51.com +51.net +5100.net +51015kid.shop +51056.org +510560.com +510erp.com +510hb.com +510xds.com +510you.com +51110.com +51119.com +5117.com +511718.com +5117sell.com +5118.com +5118img.com +5119.net +511m.com +511mv.com +511wan.com +511wh.com +511wx.com +511yj.com +512.vip +5120.com +5120bb.com +51230.com +51234g7.com +51269017.com +51298888.com +512test.com +512wx.com +512youxi.com +5132.com +513337.com +5137.cc +51386.com +5138zhuan.com +513zp.com +513zz.com +514193.com +514200.com +5144wan.com +51508.com +51511.com +5151888.xyz +5151app.com +5151sc.com +5153.com +51555.net +51569.com +5156lunwen.com +5156xz.com +51589.com +5158wan.com +515app.com +515car.com +515fa.com +515ppt.com +51643.com +51656582.com +51658042.com +5166.info +51661182.com +5166ys.com +516edu.com +516ly.com +516lyw.com +5170d.com +5173.com +5173cdn.com +51766.com +5177cq.com +517best.com +517cdn.com +517dv.com +517ee.com +517gf.com +517hotel.com +517huwai.com +517idc.com +517japan.com +517job.com +517la.com +517la.net +517lppz.com +517mh.net +517ming.com +517mr.com +517na.com +517office.com +517sc.com +517tez.com +517xc.com +51802.com +5184.com +5184pass.com +5185.cc +51864.com +51870.com +5187g.com +5188.com +518doc.com +518h48fwg6.com +518yp.com +51926.org +51969.com +51985.net +5199.cc +5199.com +51990d860a03b055.com +5199yx.com +51a.co +51aiclk.com +51aimei.com +51aiwan.com +51app.com +51art.com +51ask.org +51asm.com +51asp.net +51aspx.com +51auto.com +51autocar.net +51autogo.com +51awifi.com +51b2b.com +51babybuy.com +51baigong.com +51banban.com +51banka.net +51baocan.com +51baoshui.com +51bbcy.com +51bbmm.com +51bbo.com +51besttea.com +51bi.com +51biaoqing.com +51bidlive.com +51bike.com +51biz.com +51bjrc.com +51bmb.com +51bokao.com +51bonli.com +51book.com +51boshi.net +51bras.com +51bsi.com +51bushou.com +51buy.com +51bxg.com +51bzi.com +51caiyou.com +51callcenter.com +51callu.net +51camel.com +51caocao.net +51ccd.com +51ccdn.com +51cck.com +51ccn.com +51cdn.com +51cdngo.com +51cfm.com +51cg.com +51chang.com +51changdu.com +51changdu.xyz +51changxie.com +51chaoshang.com +51chost.com +51chouqian.com +51chuanpiao.com +51chuli.com +51cir.com +51cjyy.com +51ckjr.com +51clc.com +51cmm.com +51cnhr.com +51cocoa.com +51code.com +51coma.com +51comp.com +51company.com +51cosmo.com +51cpm.com +51create.center +51credit.com +51csr.com +51cto.com +51cube.com +51cunzheng.com +51cxsoft.com +51czapp.com +51dai.com +51daifu.com +51daima.com +51daka.com +51dangpu.com +51daxueedu.com +51dc.com +51dcgg.com +51dcw.com +51device.com +51dfc.com +51diangu.com +51diantang.com +51diaocha.com +51din.com +51dingxiao.com +51ditu.com +51diyring.com +51dmq.com +51dns.com +51docs.com +51dojoy.com +51dpub.com +51drv.com +51dszn.com +51dugou.com +51dz.com +51dzrc.com +51dzt.com +51dzw.com +51ean.com +51ean.xin +51easymaster.com +51eb0685c11021.beer +51ebo.com +51ebooks.com +51eduline.com +51eim.com +51eins.com +51ejz.com +51ekt.com +51ele.net +51emin.com +51emo.com +51en.com +51epei.com +51eshop.com +51etong.com +51etr.com +51f.com +51facai.com +51fangan.com +51fangfu.com +51fanli.com +51fanli.net +51fbpay.com +51feibao.com +51feitu.com +51feiyu.com +51fiber.net +51finace.com +51findwork.com +51fire.xyz +51fl.com +51fpg.com +51fsw.com +51fubei.com +51fucai.com +51fund.com +51fxkj.com +51fxzq.com +51fytx.com +51g3.com +51g3.net +51g4.com +51gaifang.com +51gamecard.com +51ganjie.com +51gaoji.com +51gaoxiao.com +51garlic.com +51gdrc.com +51gh.net +51give.org +51gjie.com +51gjj.com +51golife.com +51gonggui.com +51goods.vip +51gouke.com +51gowan.com +51gox.com +51gran.com +51grb.com +51grfy.com +51growup.com +51gszr.com +51guanhuai.com +51guoji.com +51gzgk.com +51h.co +51h5.com +51hailang.com +51hanghai.com +51hangkong.com +51haojob.com +51hbjob.com +51hchc.com +51hcw.com +51hei.com +51hejia.com +51hgtg.com +51hhjy.com +51hicard.com +51hika.com +51hjk.com +51hlife.com +51hlife.net +51homemoney.com +51hosting.com +51hostonline.com +51houniao.com +51hr.com +51huaji.com +51huanhuan.com +51hunningtu.com +51huoyou.com +51hwzy.com +51ibm.com +51idc.com +51ideal.com +51ifind.com +51ifonts.com +51ima.com +51img1.com +51img2.com +51img3.com +51img5.com +51img6.com +51img7.com +51img9.com +51imo.com +51ipc.com +51ischool.com +51itapp.com +51itstudy.com +51iwifi.com +51ixuejiao.com +51jb.com +51jiabo.com +51jiameng.com +51jiang.com +51jianxie.com +51jiaoxi.com +51jiecai.com +51jiemeng.com +51jingying.com +51jinkang.com +51jishu.com +51jiuhuo.com +51job.com +51jobapp.com +51jobcdn.com +51jobdns.com +51js.com +51jt.com +51jucaimi.com +51juhe.com +51jujibao.com +51julebu.com +51junde.com +51junshi.com +51kanmanhua.com +51kanong.com +51kaola.net +51kaxun.com +51kehui.com +51kf100.com +51kids.com +51kik.com +51kim.com +51kshen.com +51kt.com +51kuaizhuan.com +51kupin.com +51kywang.com +51la.ink +51labour.com +51laibei.com +51laiqiang.com +51langtu.com +51laohe.com +51ldb.com +51ldzx.com +51lepai.com +51lesheng.com +51lg.com +51lingji.com +51liucheng.com +51losangeles.com +51lstt.com +51lucy.com +51lxrc.com +51lzr.com +51mag.com +51maiquan.com +51marryyou.com +51mch.com +51mdd.com +51mdq.com +51meeting.com +51meigu.com +51meiliao.com +51meishu.com +51miaoxin.com +51microshop.com +51miduoduo.com +51miit.com +51minsheng.com +51miz.com +51mmt.com +51mnq.com +51mo.com +51mochu.com +51mockup.com +51mokao.com +51mole.com +51moot.net +51mpa.net +51mrp.com +51msc.com +51mta.com +51nearby.com +51newsapp.com +51niux.com +51nod.com +51nwt.com +51offer.com +51open.net +51opone.com +51ops.com +51p.co +51panhuo.com +51papers.com +51passion.com +51peptide.com +51pgzs.com +51photo.vip +51php.com +51piao.com +51piaohua.com +51pibu.com +51pigai.com +51ping.com +51pinwei.com +51pla.com +51pocket.com +51pocket.net +51poll.com +51pos.com +51pot.com +51poweron.com +51pptmoban.com +51psj.com +51puer.com +51qc.com +51qc.net +51qianduan.com +51qianguo.com +51qianvisa.com +51qicheng.com +51qingjiao.com +51qixing.net +51qqt.com +51qtg.com +51qub.com +51qudao888.com +51qumi.com +51quzhe.com +51race.com +51rc.com +51read.site +51recovery.com +51relaw.com +51rencai.com +51render.com +51renpin.com +51rich.net +51rong.com +51room.com +51rp.com +51rry.com +51rumo.com +51rxzc.com +51rz.org +51sai.com +51sanhu.com +51sao.net +51school.com +51scw.net +51sdj.com +51sdx.com +51search.net +51seer.com +51select.com +51self.com +51selling.com +51sgg.cc +51share.net +51shashiji.com +51shebao.com +51shengxue.com +51shenzhouyun.com +51sheyuan.com +51shizhi.com +51shop.ink +51shoubei.com +51shoufei.net +51shoushi.com +51shubiao.com +51shuobo.com +51shyc.com +51signing.com +51sjht.com +51sjm.com +51sjsj.com +51sjyx.com +51sole.com +51soulou.com +51speeds.com +51spjx.com +51ssl.com +51ste.com +51sucaiyuan.com +51suitui.com +51sutong.com +51sytx.com +51szhk.com +51talk.com +51talkenglish.com +51tanbao.com +51tao.com +51taonan.com +51taoshi.com +51taoshi.org +51taowei.com +51taoyang.com +51tas.com +51tb.me +51tbox.com +51test.net +51testing.com +51testing.net +51testing.org +51tgb.com +51tiancai.com +51tiangou.com +51tie.com +51tietu.net +51tijian.com +51tingyi.com +51tiqianle.com +51tjhr.com +51togic.com +51tonglu.com +51tools.info +51touch.com +51toufang.com +51tour.com +51touxiang.com +51toys.store +51tra.com +51tracking.com +51trust.com +51tuiyi.com +51tunhuo.com +51tv.com +51tv.net +51tvbao.com +51tvrom.com +51txapp.com +51tys.com +51tyty.com +51tz.com +51u.co +51uc.com +51ukf.com +51uyi.com +51vhost.net +51vimeo.com +51vip.biz +51vv.com +51vv.net +51vv2.com +51w.co +51wangdai.com +51wangming.com +51wangpi.com +51wanquan.com +51wanxue.com +51wcad.com +51wcity.com +51web.com +51weblove.com +51websec.com +51weihu.com +51weishi.com +51weitao.net +51wendang.com +51wenzy.com +51wf.com +51wincai.com +51windows.net +51wj.com +51wnl-cq.com +51wnl.com +51world.win +51wp.com +51wtp.com +51wxjz.com +51wydj.com +51wyfl.com +51wzg.com +51wzxz.com +51xbx.com +51xcr.com +51xcrc.com +51xiancheng.com +51xianwan.com +51xiaolu.com +51xingjy.com +51xinhu.com +51xinyuan.com +51xnj.com +51xuanmu.com +51xuanxiao.com +51xuanzhu.com +51xue8.com +51xuediannao.com +51xuetang.com +51xuetongxin.com +51xuexiaoyi.com +51xxsp.com +51y5.com +51yabei.com +51yajk.com +51yanwang.com +51yey.com +51yhdai.com +51yhgj.com +51yidun.com +51yilu.com +51ying.net +51yip.com +51ykb.com +51ym.me +51ymxc.com +51ynedu.com +51yonggao.com +51you.com +51youdian.com +51yougo.com +51youpin.com +51youth.com +51ys.com +51ytg.com +51yuansu.com +51yuepin.com +51yueqian.com +51yugou.com +51yund.com +51yundong.me +51ywx.com +51yxcyy.com +51yxky.com +51yxwz.com +51zan.com +51zd.net +51zghbh.com +51zhangdan.com +51zhantai.com +51zheduoduo.com +51zhi.com +51zhishang.com +51zhituwang.com +51zhizhao.com +51zhucai.com +51zixiu.com +51zjedu.com +51zjxm.com +51zmt.net +51znt.com +51znyx.com +51zr.com +51zsb.net +51zsjc.com +51ztzj.com +51zwd.com +51zx.com +51zxw.net +51zywl.com +51zyzy.com +51zzl.com +51zzyjs.com +52-ic.com +52.vip +520.com +520.net +5200tv.com +520101.com +520520520520520.com +520730.com +520740.com +520810.xyz +52091w.com +520cc.com +520cfc.com +520chs.com +520code.net +520diandu.com +520gexing.com +520hello.com +520hhht.com +520homo.com +520hspfb.com +520im.com +520it.com +520lbl.com +520link.com +520love520.com +520lpy.com +520mingmei.com +520mojing.com +520ok.net +520qr.net +520switch.com +520touxiang.com +520txtba.com +520way.com +520xiazai.com +520xp.com +520xy8.com +520yidui.com +520zc.com +520zg.net +5210601.com +52112.com +5211game.com +521251212122.icu +52161.org +52177.com +521799.xyz +521dayu.com +521g.com +521led.com +521logo.com +521qw.com +521szlx.com +521u.com +521up.com +521watch.com +521xunlei.com +52237377.com +522de.com +522gg.com +523333.com +52372.com +5238333.com +52393.com +523c8cb891010.beer +523touzi.com +52419.net +524399game.com +525.life +525069.com +5251yx.com +52524118.com +5252b.com +5253.com +525566.com +5258.net +5258da.com +525zb.com +526183.com +526266.com +526537.xyz +52676.com +526net.com +527100.com +52733999.com +5277.com +527fgame.com +527ice.com +527meeting.com +527ss.com +528045.com +5281.net +52841819.com +528500.com +528529.com +52892.com +528day.com +52969.com +52ai.com +52ali88.com +52alipay.com +52aoteman.com +52appok.com +52asus.com +52audio.com +52bar.com +52bishe.com +52bjd.com +52bji.com +52bjy.com +52blog.net +52bluetooth.com +52bus.com +52bwg.com +52by.com +52caiyuan.com +52car.net +52ce.com +52ch.net +52cha.com +52che.com +52cik.com +52ckd.com +52click.net +52cmajor.com +52cnp.com +52cnw.net +52code.store +52codes.net +52cv.com +52da.com +52dangong.com +52debug.net +52design.com +52desk.com +52dian.com +52dianbo.com +52digua.com +52dmtp.com +52doc.com +52dsy.com +52dtv.com +52dus.com +52duzhe.com +52dy.tv +52dyy.com +52dzxy.com +52edns.com +52edy.com +52enku.com +52eshu.com +52etf.site +52fangzi.com +52fanxing.com +52feijuba.com +52fzwg.com +52gaoge.com +52gaoxiao.com +52gg.com +52ggd.com +52gongju.net +52grz.com +52guzhuang.com +52gvim.com +52hardware.com +52hb.com +52hbl.com +52hejia.com +52help.net +52hotel.net +52hrtt.com +52hrttpic.com +52huaqiao.com +52hwl.com +52hxw.com +52hyjs.com +52ig.net +52im.net +52investing.com +52inwet.com +52ios.xyz +52itstyle.vip +52jdyy.com +52jianpan.com +52jiaoshi.com +52jiaozhou.com +52jiawei.com +52jingsai.com +52jinhu.com +52jisu.com +52jj.net +52jrjy.com +52js8.com +52jscn.com +52jubensha.com +52juqingba.com +52jxrc.com +52jxt.com +52kan.vip +52kanxiaoshuo.com +52kd.com +52kejian.com +52kfly.com +52leho.com +52liaoshen.com +52liezheng.com +52life.cc +52linglong.com +52lion.com +52luohu.com +52lvyou.com +52m.co +52mac.com +52magic.net +52maicong.com +52mba.com +52meirong.com +52mengdong.com +52met.com +52mhw.com +52miji.com +52mip.com +52ml.net +52mqbiao.com +52mtc.com +52muban.com +52muyou.com +52mvp.com +52nantong.net +52niuka.com +52njl.com +52nyg.com +52pcfree.com +52photo.com +52pht.com +52pi.com +52pi.net +52pictu.com +52pk.com +52pk.net +52pkvr.com +52playgame.com +52pojie.com +52post.com +52ppt.com +52qixiang.com +52qmct.com +52qqba.com +52queji.com +52qumao.com +52qupu.com +52ra3.com +52ranwen.net +52rd.com +52rental.com +52rsjy.com +52ruodian.com +52samsung.com +52shanghe.com +52shangou.com +52shehua.com +52shici.com +52shihu.com +52shipping.com +52shuw.cc +52shuxue.com +52solution.com +52songshu.com +52souluo.com +52suda.com +52survey.com +52svip.cc +52swine.com +52t1.com +52tc.co +52tc.info +52tesla.com +52tgfc.com +52thing.com +52tian.net +52tiny.com +52tong.com +52toolbox.com +52toys.com +52tps.com +52tt.com +52tup.com +52tzs.com +52udl.com +52uhs.com +52vps.com +52w.co +52wana.com +52wanh5.cc +52wenku.com +52wlw.com +52wmb.com +52wower.com +52wubi.com +52xcyx.com +52xianbao.com +52xiaoshuowang.com +52xie.com +52xitong.com +52xiuxian.com +52xsj.com +52xuexi.net +52xydl.com +52xz.com +52yawa.com +52ybcj.com +52yh.com +52yitian.com +52ykjob.com +52youbian.com +52youju.com +52youpiao.com +52youtu.com +52yq.com +52yushi.com +52yuwan.com +52ywan.com +52yxyx.com +52yyxk.com +52z.com +52zhaopin.com +52zhifu.com +52zixue.com +52zjkj.com +52zx.cc +52zx.net +52zxw.com +52zy.com +5306.com +5308999.com +53155.vip +531pool.com +532106.com +53233.org +532588.com +533.com +53326.com +5334.com +5338.org +533y.com +53431.com +5345.com +53471.com +534d73a9411032.beer +535fs.com +535v.com +5366.com +5367.com +5368111.com +537300.com +53797.vip +537images20.com +537images22.com +537images41.com +537images42.com +537images45.com +537images47.com +5385s.com +538618.com +538a9b8b890bff34.com +53920.net +5395.com +53957.tw +53981.org +539831.vip +53af08566e5d84ef.com +53ai.com +53c0083250a165d1.com +53chewu.com +53dns.com +53dns.net +53dns.org +53ee.com +53info.com +53iq.com +53miji.com +53museum.org +53nic.com +53q517g14c.world +53shop.com +53shubiao.com +53site.com +53wan.com +53win555.com +53wy.com +53xjd.com +53yu.com +53zaixian.com +53zw.net +54.com +54.net +5401da8c911031.beer +5406622.com +5406633.com +540734621.xyz +54114.com +5414050.com +5414900.com +54268.com +5433.com +54391.com +54406c82bf7d5705.com +5442.com +544521.xyz +544e5adac11012.beer +54540333.com +54543.org +545c.com +546709.cc +5467b.vip +54780.org +54948888.vip +5499.com +5499ok.com +54ak.com +54b03611f10271.beer +54banana.com +54benniao.com +54doctor.net +54doctors.net +54dr.com +54hcz.com +54heb.com +54im.com +54jkw.com +54job.com +54ks.com +54lol.com +54maimai.com +54md.com +54mdown.com +54op.com +54pictu.com +54traveler.com +54tup.com +54watch.com +54xiaoshuo.com +54young.com +54youshi.com +54yt.net +54yuqing.com +55.cc +55.com +5500w.com +550400.com +550416.com +5508.net +5509.cc +550d93f291021.beer +5510928.com +55114008.com +551144.com +55188.com +55188.net +551d811bb4ddf283.com +5525game.com +553356.com +55344.com +554030cc.com +554488.com +5548.net +554baad62c869a7b.com +55555.ink +55555.io +55555432.com +55555558.com +5555622ab0.shop +5559000ab0.shop +5559000ab7.shop +555abc222abc.com +555abc777abc.com +555edu.net +555tg6s98w9d8sw.com +555yst.com +5566.net +5566292.com +5566362.com +5566592.com +5566596.com +5566752.com +5566975.com +5567.me +556z.com +557.net +55706.com +55749.net +557666a.com +5577.com +5577169.com +5577199.com +5577292.com +5577375.com +5577408.com +5577411.com +5577552.com +5577690.com +5577758.com +5577860.com +5577865.com +5577937.com +5577943.com +5577956.com +558.com +5588.tv +5588124.com +5588294.com +5588492.com +5588bet.com +558idc.com +559.cc +55935.vip +5595.cc +5599.com +5599.net +5599276.com +5599785.com +55b5f319e26f3e37.com +55bbs.com +55d0548671023.beer +55d32c2b010271.beer +55dai.com +55dian.com +55doc.com +55duanzi.com +55dushu.com +55e5.com +55g.cc +55haitao.com +55hike.com +55hl.com +55hl.net +55ht5hn.shop +55i8.com +55idc.com +55it.com +55jisu.com +55kantu.com +55la.com +55r5.com +55shantao.com +55tour.com +55tuan.com +55y.cc +55y5.com +55zhoucheng.com +55zs.com +56.com +560.im +56015.com +5606968d01021.beer +56099443.com +560e.com +560wf.com +5611.com +56114.com +56135.com +56156.com +5618.co +5629.com +56360.com +564.cc +564253a9b11042.beer +56456c9fa1013.beer +5648.cc +56506666.com +5654.com +565656.com +56597.vip +566job.com +566zhibo.com +567.org +567030.com +56711.com +567909.xyz +567fafafaf.com +567idc.com +568.com +5684.com +5684t.net +56851.net +56885.net +569.com +5694.com +56a.com +56ad2ddadaebfb59.com +56ads.com +56beijing.org +56bid.com +56c.co +56care.com +56che.com +56cheng.com +56cheng.vip +56china.com +56clte.org +56dagong.com +56dichan.com +56dq.com +56dr.com +56dr.net +56dt.com +56dz.com +56ggb.com +56gk.com +56hb.com +56home.org +56idc.com +56img.com +56img.net +56imgs.com +56jg.com +56join.com +56kad.com +56laile.com +56linked.com +56md.com +56ml.com +56mp.com +56nb6oo06g.com +56products.com +56qq.com +56shangpu.com +56show.com +56shuku.org +56sing.com +56steel.com +56tchr.com +56tim.com +56tj.com +56tv.org +56uu.com +56xiniao.com +56ye.net +56yun.com +56zhibo.com +57.net +57017.work +57023.com +5707777.com +571400.net +571xz.com +57273vy9x0.com +57357.vip +574e313cc10272.beer +5755.com +576.com +57608.com +5760x.com +57648.com +57665.com +57676.com +576tv.com +57781.vip +57781057.com +577job.com +57821.com +57875.vip +579666.com +579idc.com +57auto.com +57bm.com +57class.net +57df3696bffd3eb4.com +57dp.com +57go.com +57mail.com +57px.com +57qy.com +57sh.com +57tbs.com +57tc.net +57tibet.com +57tuan.com +57us.com +57uu.com +57www.com +57yy.site +57zhe.com +58.com +5800.com +580114.com +580168.com +580590.com +5805c102b11021.beer +58091.xyz +580ban.com +580dns.com +580eda.net +580jz.net +580k.com +580tequan.com +5811x.com +58142404237055.icu +58153.xyz +58188.com +58199.com +582116.com +58232.vip +582hr.com +583316.com +583go.com +58416.org +5858.com +5858xs.com +58611.net +58620888.com +5866.com +5867yh.com +586jz.com +587.cc +58738.org +587image.com +5884.com +5888.tv +588fb105cf2606b5.com +588ku.com +588tao.com +588z.com +5898yun.com +58abb.com +58antenna.com +58auv.com +58bd0ad4222284cf.com +58bh.com +58buy.com +58chaiyou.com +58che.com +58cloud.com +58coin.com +58corp.com +58dadi.com +58daojia.com +58demo.com +58display.com +58dns.me +58dns.org +58eventer.com +58fkb.com +58food.com +58game.com +58ganji-corp.com +58ganji.com +58ghost.com +58hua.com +58ib.com +58iclick.com +58insure.com +58iwan.com +58izl.com +58jb.com +58jixie.com +58jmw.com +58kad.com +58kuaipai.com +58kuku.com +58lingshi.com +58lovepet.com +58meeting.com +58mhg.com +58moto.com +58peilian.com +58pic.com +58pxe.com +58q.org +58q8.com +58qz.com +58shangban.com +58supin.com +58trz.com +58ubk.com +58uxd.com +58wan.com +58wangwei.com +58wanwan.com +58wuji.com +58wzd.com +58xinghuo.com +58xinrui.com +58xs.com +58xs.la +58xueche.com +58xuexi.com +58yaoji.com +58yiji.com +58youtui.com +58youxi.com +58yuesao.com +58z.net +59.com +5909.net +590m.com +59120.com +591237.com +59139.com +59168.net +59178.com +5918656.com +5918dyw.com +591918.com +591con.com +591hx.com +591master.com +591moto.com +591moto.net +591mrzx.com +591syd.com +591wsh.com +591wy.com +591yhw.com +592163.com +59220ab771010.beer +59232.org +5923d.com +592bet5.com +592zn.com +59370.com +5945i.com +595.bet +595.cc +59519.com +5956777.com +595818.com +5959.vip +5959068.com +5959366.com +5959510.com +5959536.com +5959540.com +5959690.com +59598.com +595dlxzbanone.com +595image.vip +595led.com +596fc.com +597.com +597guilin.com +597mm.com +597rcw.com +59852.vip +59888888.xyz +599.com +59958b.com +5999.tv +59b1a9d9d1010.beer +59b2b.com +59baike.com +59bf02cb03a7fbbb.com +59dead1ce10301.beer +59dun.com +59ec5453559f0.streamlock.net +59f086f4910311.beer +59f35373bf3f8e7d.com +59ff599661017.beer +59hi.com +59iedu.com +59iwh.com +59jt.com +59med.com +59ni.com +59pk.net +59rj.com +59store.com +59w.net +59wanmei.com +59wj.com +59yx.com +5a1eacf0110241.beer +5a6fed2321010.beer +5a8.org +5a828d12510272.beer +5a8878b99c8f9160.com +5a8a3d1d111021.beer +5a9bf3726d2b09fa.com +5aa212657a354b3e.com +5aaa.com +5acbd.com +5adanci.com +5adanhao.com +5afc70ef010251.beer +5ag.net +5aivideo.com +5aixia.com +5aiyoo.com +5ajob.com +5any.com +5aq.net +5auto.net +5axxw.com +5b1c73dc010311.beer +5b2b697bd748d07b.com +5b39c2f791014.beer +5b3znjecy.cfd +5b529d4e711021.beer +5ba6319c311011.beer +5baike.com +5ber.com +5bite.com +5biying.com +5bjm.com +5c3639aa99149.streamlock.net +5c407acb510301.beer +5c554118a1021.beer +5c84i.net +5cb69e8045837fa9.com +5ccic.com +5cda.com +5ce.com +5ce08adc68995a7a.com +5ceimg.com +5cgo.com +5cpod.com +5d.ink +5d116d676087d0e8.com +5d170bdbce0cbe9b.com +5d2ede2.com +5d6d.com +5d6d.net +5d770c50c1016.beer +5d7bcbb1a1022.beer +5dao.cc +5dashi.com +5dc0af35081be08e.com +5ddd.com +5dfp.com +5dfsd2.com +5dgbgv941b.com +5dgz.com +5ding.com +5dmail.net +5dplay.net +5ds.com +5e17f526411011.beer +5e17fc2cca2967e2.com +5e2fd110b10301.beer +5e40004d710251.beer +5eaf8fd6c1024.beer +5earena.com +5earenacdn.com +5eplay.com +5eplaycdn.com +5er0.com +5etz.com +5ewin.com +5f28dfaae1016.beer +5f36b4f39ba574b7.com +5f52903c110251.beer +5f69826526db4f44.com +5f9e6b1603f69b9b.com +5fa26ed6d1024.beer +5fen.com +5fo.org +5fun.com +5fwan.com +5g-smart.com +5gcdnx.com +5gh.com +5gimos.com +5gjoy.com +5guanjianci.com +5gwan.com +5gxsd.com +5gxt.com +5gy.com +5gzm.net +5h.com +5had0w.com +5hoom.com +5i.com +5i366.com +5i591.com +5i5aj.com +5i5j.com +5i5t.com +5i65.com +5i9u.com +5iag.com +5iag.net +5iape.com +5ibear.com +5ibug.net +5icbs.com +5ich.net +5ichecker.com +5ichong.com +5icool.com +5idc.com +5idev.com +5idhl.com +5idream.net +5iec.com +5iecity.com +5iexpress.com +5ifapiao.com +5ifit.com +5iflying.com +5ifund.com +5igcc.com +5igcw.com +5iggci.com +5igupiao.com +5igzw.com +5ihuish.com +5iidea.com +5ijk.net +5ikang.com +5iliao.com +5ilog.com +5ilr.com +5ilrc.com +5iluying.com +5imeishi.com +5imomo.com +5imusic.com +5imx.com +5imxbbs.com +5iops.com +5ipatent.com +5ipkwan.com +5isanguo.com +5isohu.com +5iucn.com +5iweix.com +5iximai.com +5ixuexiwang.com +5iyoule.com +5iyq.com +5iyuyan.com +5izzy.com +5jingcai.com +5jinzhishu.com +5jjdw.com +5jli.com +5jue.com +5jwl.com +5k.work +5k58.com +5k5m.com +5ka30l5885.com +5kaixin.net +5kbox.com +5kcrm.com +5kcrm.net +5kda.com +5khouse.com +5kmw.com +5kwuke.com +5lanren.com +5lu.com +5lux.com +5m5m5m.com +5mapk.com +5mu.com +5nd.com +5nexus.com +5nnj.com +5o.com +5ooq.com +5opzl.com +5opzl.net +5pao.com +5pb.net +5pk.com +5plus1.net +5q.com +5qwan.com +5qzone.net +5r1.net +5radar.com +5rc.com +5read.com +5rfh44h5.cc +5ring.com +5ritt.com +5rs.me +5s4f.com +5s5j.com +5s886.com +5seals.com +5see.com +5sem.com +5sha.com +5shubook.com +5snow.com +5sw.com +5t6t.com +5tangs.com +5teacher.com +5th.zone +5thhospital.com +5thspace.net +5tjps9c62j.com +5tmobi.com +5tmovice.com +5tqjogo.com +5u18.com +5u3d.com +5u5u5u5u.com +5uchina.com +5uec9e3sj2.com +5ul.com +5umao.com +5upm.com +5usport.com +5uu8.com +5uyk.com +5v13.com +5w123.com +5w5.com +5w52.com +5w5w.com +5waihui.com +5wanpk.com +5web.site +5wx.org +5wxw.com +5wyxi.com +5x54.com +5xcg.com +5xiaobo.com +5xini.com +5xmjm.com +5xyouse.com +5y6s.com +5yang.cc +5ydj.com +5yhua.org +5ykj.com +5you.cc +5you.com +5youchou.com +5zai.com +5zd.com +5zg.com +5zhr.com +5zls.com +5zw.com +6-china.com +6-u.com +6.biz +6.mms.vlog.xuite.net +60.net +600064.com +600083.com +600086.com +6000f6l4n8.com +6000feet.com +600146.net +600200.com +600208.net +600216.com +6002255.com +600280.com +600282.net +600496.com +600576.com +6006.xin +600689.com +600711.com +600822sh.com +600895.com +600df970611031.beer +600yj.com +601book.com +602.com +602ab6ff810251.beer +602img.com +60301c31eca86940.com +603027.com +603603b.com +603603d.com +603966.com +603ee.com +60414.agency +6044faac164dbe06.com +6046.net +605-zy.com +605276655648.icu +60582ce6688bd14e.com +60593.com +605dns.com +605f40b0b174f4ea.com +605zy.co +60606161.com +60623.org +6066888.com +606b558d310281.beer +6073168.com +607images15.com +607images16.com +607images36.com +607images40.com +608.vip +6080d.com +60951.my +60dj.com +60kan.com +60mil.com +60nm.com +60oa.com +60qc.com +60wr.com +60yp.com +61.com +610115.com +610213.net +61029.com +6103g.com +6104.tv +6112.com +611qk.com +611res.com +6122cec31dfe86dd.com +612345.com +612459.com +614e697c5fb7c42a.com +6153.cc +61611.net +616167.com +6164.com +61658.com +6168511.com +6169966.com +616a191f21009.beer +616pic.com +616wan.com +6186.com +6187wo.com +6188.net +6188cnc.com +618bg.com +618cj.com +618day.com +618hr.com +618ky.com +618tech.com +618waihui.com +61916.com +61916.net +61977.center +61baobao.com +61bb.com +61bbw.com +61cloud.net +61diy.com +61draw.com +61ertong.com +61gequ.com +61hd.net +61hr.com +61ic.com +61info.com +61k.com +61kezhan.com +61mc.com +61ok.com +61psy.com +61sheji.com +61sou.com +61tg.com +61thi77ewg.com +62.vip +6202.com +62115.com +62126tt.com +62212366.com +6222251.com +62456e3303420792.com +624down.com +62609e25011021.beer +6266.cc +62669.com +626x.com +628.com +6285s.com +62923.vip +629973.com +62ca01745cf46371.com +62d6797ca064d36c.com +62ddccc8810301.beer +62dns.com +62game.com +62l.net +62wy.com +6300.net +630book.cc +630book.co +630book.com +630read.com +630zw.org +631r.xyz +632121d3c4f46e67.com +63243.com +632news.com +63329.pet +6333.tv +6334x.com +633586c05c8f4543.com +634.ag +634d.com +634image.com +634image.vip +6360.com +6373.com +63744c3e410292.beer +637600.com +6380.org +6383.com +638300.com +6385844.com +63860.vip +639311.com +63936b71f3e4ab6a.com +6397869a4eb51a13.com +63a795836312c99d.com +63b4ff1aeff2818d.com +63cj.com +63fl.com +63pe.com +63u.net +63yx.com +63yy.com +6406.org +640640.com +641.com +642online.com +64365.com +64504.com +645250.net +6453.net +64538.net +646000.com +6463.com +64644444.com +64783333.com +648sy.com +64dns.com +64foot.com +64gua.com +64ma.com +64mv.com +64oak78y99.com +64pay.com +64ptd74095.com +6501111.com +65119.com +651700.com +652ebb57a11021.beer +653697e101020.beer +654320.com +6543210.com +654321wan.com +655u.com +655yx.com +65601111.com +656126.com +65650000.com +65656564.com +656gate.com +658.com +65875.com +659595.com +65993zubo26633.com +65b01705c10261.beer +65bb2d6d81010.beer +65box.com +65dataranking.com +65ec0ea7f04562ad.com +65liuxue.com +65mhxy.com +6600.org +66016.com +660378.com +6605oo.com +66083797.com +660pp.com +66123123.com +66152.com +66168.net +6617.com +66173yx.com +662city.com +662p.com +66301cc.com +6633102.com +6633488.com +6633696.com +663661.com +6636yy.com +66378.com +66388.net +663jx.com +66445.org +66446200.com +66460.com +664e4037310291.beer +6655.com +6655.la +6655304.com +66580.com +665888j.com +665888s.com +6660333.com +666127.xyz +666291.xyz +6665.com +666532.xyz +666546.xyz +666548.xyz +66661s.com +6666343ac4.shop +6666519.net +66665s.com +66666.host +666666.host +6666m.vip +6666ppt.com +6666sa.com +6666xsw.com +6668dns.com +6669832.com +666bos.com +666gps.com +666idc.com +666kuaishou.com +666kuaishou.net +666pic.com +666post.com +666scly.com +666shuwu.com +666wan.com +666wan.net +666wx.cc +666xinxin.com +66701288.com +66747.org +6677243.com +667744.com +6677954.com +6677cq.com +667f46342ace5437.com +66825.com +6686.com +6686a9.com +6686x5.com +6686x8.com +6688.com +668app.com +668cdn.cc +668cdn.xyz +668lw.com +668map.com +668wan.com +669167d4fc316421.com +66930909.com +669322.com +6695.com +66988.tv +6699.fun +66990000.xyz +6699129.com +6699301.com +6699343.com +6699407.com +6699408.com +6699484.com +6699496.com +6699497.com +6699758.com +6699784.com +6699804.com +6699811.com +6699848.com +6699873.com +669cd3a3ea61d96f.com +669pic.com +669play.com +669ye.com +669zw.com +66brl.com +66c970e7e1011.beer +66call.com +66ddf809c0cc0fb1.com +66ds.net +66good.com +66han.com +66huigo.com +66ika.com +66in.net +66jiedai.com +66l.cc +66laws.com +66mi.com +66mobi.com +66money.com +66mz8.com +66n.co +66nao.com +66nh.com +66park.net +66perfect.com +66play.com +66rjz.com +66rom.com +66rou.com +66rpg.com +66ruian.com +66shouyou.com +66sj.com +66sy.com +66team.com +66to.net +66ui.com +66v.net +66wc.com +66web.com +66weiyou.com +66wmw.com +66wz.com +66xue.com +66y.com +66you.com +66yyba.com +66zhang.com +66zhizu.com +66zhuang.com +67.com +67017.com +670e13a8f11042.beer +6711img.com +671845093759368.icu +671992tc08.com +672m1z9ogj.world +67318n.com +674da9a521017.beer +6758169ad1020.beer +67623.com +676z.com +677.com +677.vip +6771112.com +678119.com +678301.com +6786666.com +6787.com +67876.com +678820.com +6788888.net +6789che.com +6789g.com +6789sm.com +678cn.com +678edu.net +678ie.com +678py.com +678vr.com +67921547311681.icu +67a38421b10281.beer +67a4488e31017.beer +67az.com +67cha.com +67f4951a0c77434d.com +67it.com +67joy.com +67mo.com +67tool.com +67wanwan.com +67wx.com +67y.com +68.com +68.gy +68.vip +680.com +68120120.com +681314.com +6816.com +682.com +68211.com +6822.com +682ff8a9c89d5d88.com +6832123.com +6840011.com +6844.com +685462.com +68596e90010311.beer +68606060.com +68659061.com +6868shop.com +6868yx.com +68716871.com +68792999.com +688539.com +6887cc57c10251.beer +6888.ee +6888.tv +688dns.com +688wz.net +68955.com +68978.net +6899wan.com +68apk.com +68bbq.com +68china.net +68design.net +68e5fc2c1344afb8.com +68ecshop.com +68gainian.com +68h5.com +68hanchen.com +68hlw.com +68hr.com +68jcw.com +68ke.com +68mall.com +68play.com +68sign.com +68team.com +68u.co +68web.net +68websoft.com +68zhan.net +69090.com +6912s.com +6917.com +69216.blog +69260.com +692657.com +693.com +6934.net +693975.com +69478.com +695157.com +695175.com +69525.com +695275.com +695828.com +695ljg.com +696.cool +696157.com +69698689.com +696b333851010.beer +697e43da249f79cd.com +698wan.com +69916666.com +699333.xyz +69981.com +699h5.com +699pic.com +69fd4a3dbd02f66c.com +69g.com +69hr.com +69mok.com +69shu.org +69shuba.cc +69tianqi.com +69xiu.com +69yc.com +69ys.com +69zw.com +6a221afdbbe2d2e5.com +6a2e6e54178e45a3.com +6a3ad24293be062d.com +6a4126ebcf94c39d.com +6a8a.com +6aas.com +6ab81d83f7d83dbe.com +6adj.com +6an8.com +6api.net +6apt.com +6b1813f5210261.beer +6b3b.com +6b3cfa277bae3b4b.com +6b786q3e.work +6bac9d15d10271.beer +6bbk.com +6bdns.com +6c0f63385ed13b89.com +6c6c.com +6c7ccba3e11031.beer +6cit.com +6cmap.com +6cnzz.com +6d4d5.com +6d4g.com +6d576388add270c5.com +6d7d.com +6d888.com +6dan.com +6dbx.com +6dcg.com +6de7eb04410311.beer +6dfefa7039812445.com +6diy.com +6ds.me +6du.in +6duoyu.com +6e212121910292.beer +6e8a225320471153.com +6e8fe57151019.beer +6eat.com +6edigital.com +6ef102d0210261.beer +6f25df38a10291.beer +6f7b51b741014.beer +6f8b82f9fbb439db.com +6fast.com +6fcsj.com +6fe7c9d291017.beer +6ff6313e475a7a32.com +6g5fd1a.com +6gh4.com +6ght.com +6glz.com +6gz6h1ze8r.com +6h979.com +6hd0hoc.com +6hgame.com +6hudong.com +6huo.com +6hwan.com +6ict.com +6ie6.com +6ifang.com +6juzi.com +6jz.com +6k11.com +6k6g.com +6k9k.com +6ke.com +6kw.com +6kxz.com +6laohu.com +6li.com +6lk.net +6ll.com +6lrt.com +6ls.cc +6m5m.com +6miu.com +6miu.net +6my575.com +6niu.com +6nm6.com +6our.com +6p667.com +6p7q8c3oa4.com +6pen.art +6pifa.net +6puppy.xyz +6pzftj.com +6r6992xeq1jho.cyou +6ren.com +6rencn.com +6renyou.com +6rooms.com +6s4qki.com +6s54.com +6sfg.com +6sq.net +6t.com +6t12.com +6tcc.com +6tennis.com +6thhosp.com +6tiantian.com +6tie.com +6tktrd.com +6tt.com +6tu.com +6twrte12ft.com +6u9muvn94m.com +6uudy.com +6v.com +6v6.work +6vdyg.com +6wan.com +6wtx.com +6wwww.com +6wz.co +6x.studio +6x69f31vso.com +6xcdn.com +6xd.com +6xiu.com +6xw.com +6yoo.com +6young.site +6yso.com +6yxk.com +6yxs.com +6yygh.site +6yyy7.com +6z.net +6z6z.com +6za0l6fjl0.com +6ze.net +6ziz.com +6zu.com +6zy37f4df2.com +7-11bj.com +7-che.com +7-meeting.com +7-mi.net +7-vk.com +7-wx.com +70.cc +70.net +700618.com +70098.com +700chat.com +700kan.com +700live.com +700megs.com +700mh.com +701.com +703804.com +70392.com +70392.org +70524.com +706net.com +707598.xyz +707e518c610291.beer +7080edu.com +70822.com +7089899.com +7089dd.com +7089gg.com +70cq.com +70dir.com +70gm27345d.com +70jj.com +70ka.com +70pf2fj3sd.com +70ppt.com +70soft.com +70ym.com +70yx.com +71.am.com +71.net +7114.com +7116.com +7116dns.com +711hospital.com +711pr.com +7120.com +71360.com +7139.com +71390.com +714.com +714a0ffa611031.beer +714b5653f10292.beer +715083.com +715288.com +715300.com +71556v.com +71683.com +71714.com +7172737.com +71757ae5f10241.beer +7176.com +717c.com +717down.com +718991.com +71908.com +7192.com +719400.com +719f06caf1017.beer +71acg.com +71acg.net +71b394ce11114.beer +71baomu.com +71baomu.net +71big.net +71caigou.com +71d7f1e121019.beer +71dm.com +71e.com +71edge.com +71edge.net +71edge.work +71elink.com +71f68cc351015.beer +71go.com +71k.com +71lady.com +71p.net +71tao.com +71tech.com +71txt.com +71wl.com +71wx.net +71xe.com +71xk.com +72.com +72017.net +720582.com +720health.com +720static.com +720think.com +720ui.com +720yes.com +720yun.com +720yuntu.com +7210.com +7211.com +7214fa7e11011.beer +72177.com +7217kf2961.com +721888.xyz +72242s.com +72257c.com +72257e.com +72257j.com +72258q.com +72287c.com +72287h.com +72287o.xyz +7230.com +7239ll.net +723e7a5a510261.beer +7245f7d6211012.beer +724pride.com +724pridecryogenics.com +724pridetech.com +72535276268b14e0.com +7265a5ef31011.beer +726p.com +7273.com +727380.com +727d5e6cb1011.beer +7280.com +7291v.com +7298.com +72byte.com +72ce.com +72crm.com +72crm.net +72crm.org +72d3bb672f4a6997.com +72dj.com +72dns.com +72dns.net +72e.net +72en.com +72g.com +72gu.com +72h6hn4r3e.com +72home.com +72kjmb.com +72la.com +72max.com +72qq.com +72r.net +72swk.com +72whys.com +72xit.com +72xuan.com +72y.co +72yce.com +72yun.com +72zhan.com +730d60bec10281.beer +731.tv +73110010.com +7315297af11011.beer +73232yx.com +73261825f768447d.com +732732.com +7337pay.com +734969.com +73573dd6a1023.beer +7366cba131014.beer +73676699.com +737.com +737698.xyz +73789.com +73850.org +73864.org +738888.xyz +73925.work +73980.org +7399.com +73bc.com +73bt.com +73card.com +73d1708e01022.beer +73ea00c7710272.beer +73so.com +73zw8.com +74.com +7415.com +741b0fca410271.beer +7428.net +743forever.com +7441a334d13a0000.com +74478fd3b9cca85f.com +744zy.com +745998.xyz +74615ee887a99dd7.com +7474.com +7477.com +747wan.com +749333.xyz +74955.net +74966.net +74977.net +74ad7537d1014.beer +74cms.com +74da6ad581020.beer +74dns.com +74f11ac633122c20.com +74hao.com +75.team +75111.com +75111.net +75122d9a05f7a5a7.com +751257.vip +75184.com +75271.com +752d7cf9a8cd3341.com +7534w8m16e.com +75367.com +7543c79b410291.beer +75510010.com +756u.com +7574.com +75757.com +757dy.com +7580.ltd +7597af9ac1010.beer +75982.com +75a8f8759fc99775.com +75b58faf61014.beer +75d31e3ac62e6e53.com +75g.co +75ll.com +75n474.com +75pk.com +75team.com +75ww.com +75xn.com +76120.org +7618.com +761a.com +7633sqw.com +76474cf781f10d61.com +7651.com +766.com +7663.com +76676.com +766899d4f1011.beer +766app.com +766er.com +766test.com +766vd.com +766z.com +767qkdj34u.com +767stock.com +76831.org +76868.com +7688.net +7689.site +76963.com +769car.com +76ab.com +76baobao.com +76bb.com +76c9c1aa27766f1d.com +76dongdong.com +76ju.com +76mz.com +76pay.com +76pf.com +76y.com +76zu.com +77005163.xyz +770539.com +7711.com +77112007.com +77119159.com +771633.com +77169.com +77169.net +7717wan.com +7722wx.com +7723.com +7723img.com +7724.com +7724yx.com +7725.com +77304.com +77304y.com +77313.com +7733320.com +7733352.com +7733577.com +7733706.com +7733728.com +7735.net +77381v.com +7744wan.com +77521.com +77545.com +7755028.com +7755056.com +7755078.com +7755267.com +7755302.com +7755306.com +7755330.com +7755360.com +7756.org +775jia.net +776577.com +7766.info +7766.org +7766060.com +7766073.com +7766081.com +7766090.com +7766300.com +7766362.com +7766380.com +7766396.com +7766398.com +77670.org +77745.com +7777733.com +777biubiu.com +777dd.life +777e.store +777eee888eee.com +777haoka.com +777lala.com +777moban.com +777sy.com +777yh.am +7788.com +7788310.com +7788610.com +7788js.com +7789.com +778buy.com +77991.com +7799358.com +7799378.com +77994008.com +7799520.com +779wan.com +77bh.com +77bike.com +77bx.com +77cr0ip236.com +77dd23.com +77de.com +77dushu.com +77dyy.net +77ebooks.com +77ed699516ed5193.com +77ee6f16b1011.beer +77eye.com +77fanwen.com +77gog.com +77hd.com +77hudong.com +77itv.com +77l.com +77lux.com +77music.com +77nn.net +77nt.com +77nt.info +77piano.com +77pin.net +77shu.com +77shuku.la +77shuku.org +77shw.com +77socks.com +77tianqi.com +77vcd.com +77xmd.com +77yx.com +77zhangh.com +77zhanghao.com +77zn.com +78.link +78104.org +78110.org +781203.com +78126dh.com +7829t.com +782e2u6m99.com +78302.com +785836.com +785956.com +78654321.com +78665.vip +786e7138b09934b3.com +78785z.com +7881.com +7888.com +788899.com +788v.com +7890.net +78901.net +7899.cc +789hi.com +789hsw.com +789win07.com +78bar.com +78dian.com +78diy.com +78dm.net +78ee.com +78fz.com +78gk.com +78h34.com +78hr.com +78md.com +78oa.com +78os.com +78plat.com +78tp.com +78v.com +78yx.net +79.biz +790.com +79008500.xyz +790a8f76c10301.beer +7928a82f311032.beer +79332.agency +793360.com +793688.com +79432.com +7951ee2a510281.beer +79521.cc +7979u.com +797sun.com +7988.com +798com.com +798edu.com +798ydh.com +798zb.tv +799.net +79979.loan +7997v.com +7999.tv +79999.net +799job.com +79abc.com +79bb57f37108d1b9.com +79ecb629691d165f.com +79f9bf9e410292.beer +79jr.com +79tao.com +79yougame.com +79yx.com +7a.cm +7a1dd6b621020.beer +7a1f7ba4211042.beer +7a31jmf.com +7a8k.com +7a9b89eb3d333f2c.com +7ade93e381021.beer +7ahr.com +7analytics.com +7b2.com +7b6466e191019.beer +7b761738c10261.beer +7bess.com +7bip9h1k5s.com +7c.com +7c5ba8e2b10281.beer +7c637ea6d10271.beer +7c644b8a21013.beer +7caiyun.com +7capp.com +7ccj.com +7cdfad1816def43d.com +7cgw.org +7chacha.com +7ci.com +7cname.com +7cnv.com +7cv.com +7cxk.com +7cyn.com +7d4b19ab710241.beer +7d5y.com +7d604703e1023.beer +7d8fc91771017.beer +7d9c2005e1015.beer +7dc0d8dad10281.beer +7dc20a92cc1da04d.com +7didc.com +7do.net +7down.com +7down.net +7dsw.com +7e.hk +7e051eec511021.beer +7e9dba1891021.beer +7east.com +7ed.net +7edown.com +7ee.com +7eo8cc932r.com +7f0107332e0db161.com +7f36600721781324.com +7f416cfd411012.beer +7f86a2a17fcd5a5d.com +7fa19203510241.beer +7fa973f8c7bdcddb.com +7fei.com +7fff5701c5415d77.com +7fgame.com +7flowers.com +7forz.com +7fresh.com +7glb.com +7gongzhu.net +7grandcross.com +7gugu.com +7h1fg6b6kd.com +7hcn.com +7head.icu +7help.net +7ho.com +7hon.com +7hua.com +7icp.com +7il.co +7ipr.com +7its.com +7jia.com +7jia2.com +7jiaqi.com +7jjjj.com +7jk.com +7juju.com +7k35.com +7k7k.com +7k8k.com +7ka.co +7kk.com +7kla.com +7kla.net +7ko.com +7kww.net +7littlemen.com +7lk.com +7luohu.com +7lw.com +7mah2.com +7moor-fs2.com +7moor-zx.com +7moor.com +7msj.com +7mx.com +7mz3a.com +7nepal.com +7net.cc +7oh.net +7pa.com +7paiqun.com +7piq.com +7po.com +7q5.com +7qile.com +7quw.com +7r7z.com +7rdao.com +7road.com +7road.net +7ronggame.com +7runto.com +7rz37dp998.com +7sef.com +7sfashion.com +7sodu.net +7souti.com +7sown.com +7soyo.com +7su.com +7syc.com +7t9.com +7tapp.com +7tenet.net +7tgame.com +7tnt.com +7tou.com +7tqy.com +7tui.net +7ugl.com +7usa.net +7uv.com +7v6.net +7vd7.com +7vk.com +7vyou.com +7wan.com +7wate.com +7wee.com +7wenta.com +7wenyi.com +7wnews.com +7wsh.com +7wsh.net +7wx3675l72.com +7x24cc.com +7x688.com +7xdown.com +7xiuxing.com +7xm.net +7xz.com +7y5.net +7y7.com +7yc.com +7yigame.com +7youxi.com +7yuki.com +7yun.com +7yun.org +7yundns.com +7yylucky.com +7yz.com +7yzone.com +7z4bz6e2cp.world +7zgame.com +7zhan.com +7zhou.com +7zkj.com +7zm.com +7zz6.com +7zzy.com +8-008.com +8.biz +8.xyz +80.hk +80000.cc +800423.com +800507.com +8006506.com +8006511.com +8006tu.com +800713.com +800820.net +8008202191.com +8008205555.com +80088886.com +8009900800.com +800app.com +800bamboo.com +800best.com +800best.net +800bestapi.com +800bestapp.com +800bestex.com +800book.net +800buy.com +800cdn.com +800du.com +800hr.com +800jcw.com +800li.net +800lie.com +800lj.com +800mei.net +800pharm.com +800pifa.com +800tu.com +800tuan.com +800tzw.com +800vod.com +800wen.com +800xiaoshuo.com +800xs.net +800you.com +800youhuo.com +80166.com +802203.com +8025edaf81019.beer +80351.com +804c3f72a13dad45.com +805481.com +80585.com +805a8702410281.beer +8065f8f0f10261.beer +807.com +807d286522a4a453.com +807df2a0610272.beer +80800.vip +8080bl.com +8080i.com +8081.net +80811daa56184e5f.com +8082audio.com +8087sss.com +8087vvv.com +80899999.com +808c6f532d08909b.com +808xs.com +8090.com +8090.pk +809090.xyz +8090app.com +8090cdn.com +8090mt.com +8090st.com +8090vision.com +8090yx.com +8090yxs.com +80982.org +80a2a140710301.beer +80baicai.biz +80bi.com +80c189b091016.beer +80cz.net +80data.net +80day.com +80dd7626911042.beer +80den.com +80dongli.com +80host.com +80kongjian.com +80kuku.com +80lou.com +80paper.com +80s.im +80shihua.com +80sjy.net +80srz.com +80test.com +80txt.cc +80txt.com +80txt.la +80vps.com +80wifi.cc +80x.co +80xg.com +80xs.la +80zw.info +81007.work +8100ab16d11021.beer +810840.com +81138183c1024.beer +81182479.com +811sisp.com +81241g43cj.world +81257.com +81265.com +81265.net +812813.com +8130088.com +81312.com +81366j.com +815.pub +815008.com +8158.com +81593.com +815ybw.com +81629.com +8162t.com +81663344.com +81677.com +816798.net +8169.com +81730450affbad30.com +817398.com +81761.com +818.com +81813.com +8181xw.com +8181zx.com +81835.com +8185t.com +8188.cc +818cq.com +818it.com +818long.com +818ps.com +818tu.com +818u.com +818watch.com +81988888.com +81999.org +81999999.com +81art.com +81book.com +81comdns.com +81ek.com +81gfchina.com +81guofang.com +81hongshi.com +81it.com +81kx.com +81lcd.com +81man.com +81pan.com +81rzqh.cfd +81tech.com +81tt.net +81xy.com +81zhongwenx.com +81zw.com +81zw.la +8203app.com +8207hh.net +8207uu.net +82137777.com +82158.com +82250856.com +822644.com +8228.tv +822ef055f1017.beer +823238fa910271.beer +82335966.com +8243d76487f3a834.com +8246.net +8254ce48211021.beer +8264.com +82676666.com +82686677.com +82686699.com +826pc.com +826wan.com +828385vip.com +82859.com +8289880.com +828g.com +828i.com +82920.com +8295099d311031.beer +8295dc6e7e797638.com +82987977.com +829e30d07853f4fd.com +82d5d0e4f10291.beer +82e0dd98d1edbbb1.com +82flex.com +82ip.com +82ky.com +82l.net +82pk.com +8303.org +83047.work +83124.com +83133.com +83133.vip +83152222.com +8325.com +8329607.com +833006.net +8333dhz.com +8336.com +833k5u23mb.com +83480900.com +834834002.com +834834009.com +834834vip4.com +835444.cc +835images48.com +835images55.com +835images61.com +835images73.com +835images76.com +835images83.com +83661111.net +83666.com +83753751.com +8379888.com +8383.vip +838413.com +838dz.com +83934.com +83990567.com +83edu.net +83h87d.com +83iiq501o2.com +83kxs.com +83mo7n9giq.com +83x.cc +84.com +84.vc +84008.com +84185858.com +8421.com +84308.com +84399.com +84460yhh7t.com +844wan.com +84560262.xyz +845de4aca1019.beer +845e4a87610292.beer +846645d29f0aa91f.com +84684.net +8475.org +8477.com +848.com +848.tv +84d8388721016.beer +84fk.com +84ju.com +84ke.com +84ktv.com +84ny.com +84zcb.com +850088.com +850718.xyz +8521.org +85229666.com +85253000.com +85384.com +853lab.com +854255.com +8543c0ee3b9082b5.com +8558.org +85657777.com +85679999.com +85791df5e89bcda6.com +8579s.com +857yx.com +857zb1.tv +85814.com +85880234.com +858game.com +85c531cb9c14f457.com +85f46a104256c205.com +85jk.com +85kf.com +85sc.com +85wp.com +85xt.com +86-import.com +860029.com +860527.com +860598.com +86079898.com +8613.org +861718.com +86175.com +861817.com +86215.com +86262.com +863.cc +863soft.com +86516edu.com +865211.com +86586222.com +86590.com +866.com +86656.net +866ds.com +8671099.com +8673h.com +86754.org +867867jh.com +8682.cc +8684.com +8686c.com +8688g.com +86933.com +869d.com +869v.com +86a92644807597fa.com +86amsdy.com +86bdada6e1019.beer +86bus.com +86crk.com +86ditu.com +86dk.com +86eh.com +86eye.com +86fis.com +86fsp.com +86game.com +86gc.net +86hcdnsuv.com +86hh.com +86hk.vip +86hr.com +86huoche.com +86jg.com +86joy.com +86kang.com +86kl.com +86kongqi.com +86lawyer.com +86mai.com +86mama.com +86mdo.com +86nb.com +86office.com +86pla.com +86pm25.com +86ps.net +86rexian.com +86sb.com +86tec.com +86tree.com +86ty.com +86uuu.com +86wind.com +86wol.com +86xq.com +86y.org +86yqy.com +87.vip +870.com +870818.com +870q.com +87111111.com +87130000.com +87131.vip +87161.vip +871659.org +87188718.com +872.cc +872872.com +8732365.com +8733777251212.icu +87388v.com +875296.org +8756s.com +875902.vip +8765043b5db2cbcb.com +87654321.xyz +8767.com +8769d53.com +876dns.com +876web.com +8770000.com +87739b0fc18fe40a.com +8775.com +87753.net +877771.xyz +8779.com +8782.org +87870.com +87872277.com +878998.net +87929796a10271.beer +87949.cc +8799.com +87a37933611021.beer +87b041a2019314d7.com +87bc16a2fc6c4036.com +87e1ed649c57575b.com +87g.com +87money.com +87pk.com +87vr.com +87yy.com +88-z.com +88.com +880.net +8800.org +880022.com +8801.net +880303.xyz +880331.net +88077777.com +88090.com +880sy.com +880you.com +88106.com +88116008.com +8811777.com +881794d571016.beer +881812c.com +88183322.com +88183355.com +881ac9cfd560166d.com +8821.com +8822304.com +88239001.com +8825.com +8828y.com +88303887.com +8831.app +8831398.com +88321268.com +88360.com +8838sl.com +883dai.com +884358.com +8844.com +88453392.com +8848.com +8848phone.com +8848y.com +885.com +8850006.com +885210.net +88582.com +8860.net +8864.com +8866.org +886623.com +8866316aav.work +8866316apt.work +8866886688.com +8867556d88.net +8868.com +88682089.app +8868a16.app +8868vip130.app +886966.com +886abc.com +886cdead210292.beer +886vps.com +887367.com +88737v.com +88765.com +887777.com +887w.com +888-8.com +8880666.com +888132.com +8882258ab4.shop +888484.xyz +888608.xyz +8886664ad2.shop +88880809.com +88887777.com +8888800000.com +8889997777.com +888ban.com +888chem.com +888eee777eee.com +888jiagong.com +888pic.com +888ppt.com +888rj.com +888twt.com +888win12.com +8890.com +8890tu.com +8896.com +88966.net +8899.net +88995799.com +8899yyy.vip +889d9745511021.beer +88adb49761022.beer +88bank.com +88bx.com +88c3eaa9f1015.beer +88caijing.com +88cdn.com +88dushu.com +88fang.com +88fe6607b11011.beer +88gogo.com +88h3.com +88hom.com +88ht.com +88icon.com +88ipa.com +88k.site +88koo.com +88la.cc +88la.la +88lan.com +88laser.com +88lmtupian.com +88lot.com +88meishi.com +88mf.com +88ming.net +88order.com +88pets.com +88sup.com +88sus.com +88tang.com +88tph.com +88ttv.com +88wbet.me +88xiaoshuo.com +88xr.org +88y5.com +88ysg.com +88zha.com +88zjzy.com +89006006.com +890bf715220716f3.com +8910.io +89178.com +8926174358102.icu +8928.org +892qipai.com +89303.com +89438.com +894994.com +89538777.com +89567.cc +89609335.com +8961zx.com +896de44003a72c48.com +896qipai.com +89713742a93610e3.com +897cdb929ebd7ee2.com +898.travel +89801133.com +89808222.com +8980cc.com +8989118.com +8989jt.com +8999.cc +89b12b5e3ff8085c.com +89dj.com +89doc.com +89ds.com +89f0e4a1603d3372.com +89f9ee46410292.beer +89qw.com +89uu.com +8a.hk +8a10847841cdf19b.com +8a53ccb021015.beer +8ab113871fb000b2.com +8ah.cc +8aza.com +8b0dead347366514.com +8b2.net +8b3efd3d91017.beer +8b753196c6c34891.com +8b92b52bd10301.beer +8badedce210292.beer +8bb.com +8bcd9.com +8bce394a2cdc5541.com +8bd02a5c35c9ab25.com +8bo.com +8btc-ops.com +8btc.com +8btm.com +8c657a4ba5616b4f.com +8ce7bc1173775468.com +8cname.com +8cnet.com +8d36745b85e5711c.com +8d6a9a22611032.beer +8d7c51ca60de7bc5.com +8d8215f2d2278f42.com +8d99e9f8b690b895.com +8ddbf947e1020.beer +8dei.com +8dexpress.com +8dn.com +8dol.com +8dou.com +8dt.com +8dudata.com +8dus.com +8dwww.com +8e5da0c5911031.beer +8e8z.com +8eda52911f4518b6.com +8ee1834c110272.beer +8eeea09bc1009.beer +8europe.com +8f72500e910271.beer +8faa7.com +8fe.com +8fenxiang.com +8ft6h20ivn.com +8ggq.com +8gl.com +8gn2i0i5fc.com +8gov.com +8gui.com +8gyu.com +8h15725mm7.com +8hgame.com +8hsleep.com +8hy7q32i4q.com +8i8b.com +8jdns.net +8jie8.com +8jxn.com +8jzw.cc +8k5lu58221.com +8k7k.com +8kana.com +8kjl34x2gj08.com +8kkcny.click +8kmm.com +8kwebs.com +8kzw.com +8l8e.com +8lag.com +8lhx.com +8liuxing.com +8lj.cc +8llp.com +8lun.com +8m8t.com +8mcn.com +8mhh.com +8mi.tech +8minzk.com +8miu.com +8miu.net +8mkt.com +8moom.com +8mpaoche.com +8ms.xyz +8n2.com +8n6n.com +8njy.com +8o9o.com +8pig.com +8pingce.com +8pu.com +8qwe5.com +8qzy.com +8rlq38736p.com +8rn4u.com +8rs8i.com +8s123.com +8shop.cc +8so.net +8tennis.com +8tgh.com +8tool.club +8tupian.com +8tupian.net +8u18.com +8u58.com +8u7q5l9gox.com +8uid.com +8uyx.com +8wan.com +8win.com +8win.net +8wiu.com +8wq.com +8wss.com +8wym.com +8x6x.com +8xs.org +8xz8.com +8yao2hds35sv.com +8ydsp.com +8ym8.com +8ytech.com +8yx.com +8z.net +8zhuayu.cc +8ziben.com +8zntx.com +8zy.com +9-xin.com +9-zhuce.com +9.biz +9.xyz +90.cc +900.la +900.vc +9000wy.com +900112.com +900501.xyz +900cha.com +900d8ac6110261.beer +900php.com +900ppt.com +900yi.com +90123.com +9018.net +90231611e4973cbb.com +904e0d2ba10241.beer +9056b8f915baba58.com +90576.com +90686.com +906you.com +90747.pro +9090cdndns.com +90a7597f835b14bd.com +90ao.com +90b5d42ca1016.beer +90c6.com +90dao.com +90ers.com +90game.bet +90ko.net +90kuai.net +90lhd.com +90qh.com +90sheji.com +90sjimg.com +90tank.com +90vm.com +90wmoyu.com +90yang.com +90yk.com +90zm.net +91-box.com +91.com +91.plus +9100.ink +9105.cc +9105.com +91084.com +910app.com +910play.com +911.vip +91103d3a31014.beer +9111.tv +91118.com +91160.com +911zy.com +912355.com +912366.com +9125flying.com +912688.com +912hf.com +912k.com +912yx.com +91300.com +9133.com +9136.com +91360.com +91378.com +913aefac85f5bf8f.com +913pc.com +913vr.com +913you.com +9149df3441020.beer +915.tv +9154wan.com +91558.com +915658.com +91583.com +91588kf.org +915d.tv +916360.net +9166yx.com +916m.com +917.com +9170.com +917st.com +91827364592013.icu +91827364592018.icu +9186.com +9188.com +9188.work +918canyin.com +918dxs.com +918fg.com +918ka.cc +918rc.com +919.com +9191mr.com +9191net.com +9191steel.com +9191zx.com +9193.com +91985.com +9199.com +919watch.com +91ac.com +91act.com +91ajs.com +91all.net +91anjian.com +91art.net +91baby.com +91boshi.net +91boshuo.com +91bushou.com +91carnet.com +91cdkey.com +91cha.com +91changxie.com +91chengguo.com +91convert.com +91ctc.com +91cy.app +91cy.cc +91czxs.com +91daizhang.com +91danji.com +91datong.com +91dba.com +91dbb.com +91dbq.com +91ddcc.com +91ddedu.com +91dict.com +91dnso.com +91doujin.com +91dub.com +91duba.com +91duobaoyu.com +91em.com +91es.com +91exam.org +91exiu.com +91facts.com +91fangan.com +91fifa.com +91fyt.com +91game.com +91goodschool.com +91haigui.com +91haiju.com +91haoka.com +91haoke.com +91health.net +91hecheng.com +91hmi.com +91https.com +91huayi.com +91huayi.net +91huifu.com +91huoke.com +91huola.com +91hy.com +91idc.gg +91ifx.com +91ios.com +91ios.fun +91jbz.com +91jf.com +91jiabohui.com +91jiafang.com +91jianguo.com +91jin.com +91jinjindai.com +91jinrong.com +91jinshu.com +91jiujige.com +91jkj.com +91jkys.com +91jlb.com +91jm.com +91jmw.com +91job.com +91join.com +91jtg.com +91k7.com +91kami.com +91kq.com +91kw.net +91laihama.com +91laiz.com +91ld.com +91lda.com +91leju.net +91lewei.com +91listen.com +91lsf.com +91lx.com +91m.co +91maibiao.com +91maths.com +91meitu.com +91miaoshou.com +91muou.icu +91muzhi.com +91ninthpalace.com +91nzh.com +91pandian.com +91pdf.com +91petct.com +91php.com +91post.com +91pusi.com +91q.com +91quce.com +91qycl.com +91rjz.com +91ronghui.com +91ruyu.com +91saishi.com +91sd.com +91sem.cc +91sfdj.com +91shenfan.com +91short.com +91shouce.com +91smart.net +91soer.com +91soker.com +91sotu.com +91soumu.com +91sph.com +91sst.com +91strategy.com +91student.com +91suan.com +91suke.com +91switch.com +91syun.com +91taoke.com +91ting.net +91tm45tzyb.com +91toolbox.com +91tty.com +91tvb.cc +91tw.net +91up.com +91vpn.com +91vps.com +91vrchat.com +91vst.com +91waijiao.com +91waitang.com +91wangcai.com +91wangyx.com +91way.com +91weimai.com +91wenmi.com +91wenwen.net +91wllm.com +91wujia.com +91wutong.com +91wzg.com +91x.org +91xch.com +91xcm.com +91xfw.com +91xiake.com +91xiazai.com +91xinshang.com +91xjcs.com +91xsj.com +91xunyou.com +91xxt.com +91xy.com +91y.com +91yao.com +91yinpin.com +91yixun.com +91yk.com +91yong.com +91you.com +91youban.com +91youchai.com +91youxi.com +91yoyo.net +91yu.com +91yuedu.com +91yunxiao.com +91yunying.com +91yxbox.com +91yxl.com +91zhongkao.com +91zhuti.com +91znyx.com +91zxw.com +92.net +920uc.com +921.com +9211.com +9217fdb98dcc13a8.com +9217web.com +92220556.com +92220558.com +92220577.com +92220668.com +92220701.com +92220760.com +92224i.net +92224s.com +922997xtz2.shop +923f92a4e1df1753.com +924747.com +925g.com +925ps.com +926kf.com +92751437c39b61ee.com +927927.com +927953.com +927game.com +928.sale +928vbi.com +928xpj.com +92913.com +929825.com +92987.com +9299.net +929g.com +929vip.shop +92anycall.com +92ay.com +92bbs.net +92bce178d60f5a3e.com +92cf4088b1014.beer +92cloud.com +92demo.com +92dp.com +92dpw.com +92dydh.com +92e483231a9103f8.com +92fa.com +92fox.com +92gyw.com +92hidc.net +92jzh.com +92kaifa.com +92kk.com +92le.com +92lm.com +92lucky.com +92mp.com +92nas.com +92ni.com +92oz46nne1.com +92scj.com +92shuoshuo.com +92sucai.com +92to.com +92txt.cc +92u93e.com +92wan.com +92wudao.com +92wx.com +92wx.la +92wy.com +92xygame.com +92y.co +92yanqing.com +92yo.com +92zc.com +92zhiqu.com +92zuqu.com +930a48879eaa652b.com +930hh.com +9312.net +93126.org +93135.com +931931jh.com +933.moe +933332.xyz +93376v.com +934dsw.com +934hd.com +93636.com +936u.com +9377a.com +9377d.com +9377df.com +9377g.com +9377j.com +9377ja.com +9377z.com +9378.com +93913.com +939397.vet +93966.com +93977v.com +93984.org +93e8209f610272.beer +93eu.com +93fbf3a7f10281.beer +93gaokao.com +93hdw9.com +93jiang.com +93jx.net +93kk.com +93land.com +93lh.com +93njf0.com +93pk.com +93sdk.com +93sem.com +93soso.com +93trf.com +93tyy.com +93wgames.com +93yo.com +93you.com +93zp.com +94001.com +94001.vip +940177.com +940304.xyz +94113162.xyz +94117.net +941adu.com +941gb.com +942mc.com +94362.com +9437803d210271.beer +944.com +94445.com +9453job.com +945d3447ed068dbd.com +945n48.com +946000.com +9466.com +947fd9a0011042.beer +94831.com +9486483.com +948hj.com +949047l1jr.com +9495.com +94994.com +949949.com +94ad.com +94afx.com +94beb5b921021.beer +94cb.com +94cto.com +94fcb6f5810241.beer +94gan.net +94goo.com +94he38.com +94i5.com +94kuai.com +94mxd.com +94php.com +94q.com +94qy.com +94rmb.com +94rp.com +94te.com +94xy.com +94you.net +94ys.com +95-1.vip +95.com +95001111.com +95007.com +95013.com +95021.com +950901.com +95095.com +950c6df3c6ee90b1.com +95105105.com +95105369.com +95105555.com +95105888.com +95105899.com +9512.net +951280.com +951368.com +95158.com +95169.com +95191.com +95195.com +951dns.com +95262.com +9527cha.com +9527cloud.com +9527dns.com +9527g.com +95303.com +95311.com +9533.org +953yx.com +95408.com +9540f8f83e1e7a8c.com +95447.com +95504.net +95504test.com +95508.com +95516.com +95516.net +95526.mobi +95528.com +9553.com +9557.com +95572.com +95579.com +95580.net +95588.com +95598pay.com +95599.hk +955yes.com +9560.cc +95600.vip +9564.com +95659.org +9567.com +95684f80222b921a.com +957431860395659.icu +9574528ue9.com +95779.com +958358.com +9588.com +95890.com +959.com +9595111.vip +95a.co +95b.co +95bd.com +95dns.cc +95dushu.com +95dushu.net +95e.co +95en.com +95epay.com +95fenapp.com +95ib.com +95ip.com +95jizhang.com +95k.com +95links.com +95ns.net +95px.com +95shubao.info +95to59.com +95xiu.com +95ye.com +95yijing.com +95zh.com +96005656.com +960123.com +960638.com +96090090.com +96096kp.com +960rc.com +9610.com +96110.org +9611111.com +96160.cc +96189.com +96189.tv +9618968.com +96192.com +962.net +962007.com +962168.com +962222.net +96225.com +962360.com +962518.com +962600.com +96262.com +96335.com +96355.com +96369.net +963695.com +963999.com +96459.com +964yx.com +965.one +96519.org +96528.com +96533.com +965373.com +96558.com +9655bcfbe1022.beer +96567.com +96590.net +9663.com +9665.com +966599.com +9665yx.com +9666666.com +9666sr.com +966zlnfjuza4oloh2bk.app +96804.com +96811.com +96811.net +96822.com +968309.com +968550.com +96856.org +9686000.com +96877.net +968816.com +9688896.com +968pk.com +969009.com +9692bc70da600f84.com +969368.com +96966.com +969g.com +96ac893dd11011.beer +96b25c0edb71ca11.com +96caifu.com +96cc09c581022.beer +96ce3cebe11042.beer +96daa24471013.beer +96dp.com +96eaa004b05872ae.com +96f2d.com +96flw.com +96hq.com +96kaifa.com +96lh.net +96lou.com +96ni.net +96pk.com +96sdk.com +96sir.com +96weixin.com +96yx.com +96zxue.com +97.biz +97.cc +970mhz.com +97111.work +9718.com +9718game.com +972.com +9724.com +9736s.com +97576.com +97616.net +97654.com +97665.com +97775.com +9778.com +977k.com +977zy.com +97866.com +9787.com +978clouds.com +978s.com +97936.com +97971166.com +97971188.com +97972209.com +97973.com +97973309.com +97973399.com +97975508.com +97976608.com +9797cp2.com +9797ly.com +9797x4.com +9797x7.com +9799.com +9799251212480.icu +97a12bb360b26d1c.com +97add.com +97bacdab676db530.com +97ce6cbd010292.beer +97d9f793c1022.beer +97doc.com +97f6185064157973.com +97gg.net +97go.com +97jiayou.com +97jindianzi.com +97jz.com +97kid.com +97kks.com +97lp.com +97lpw.com +97lrf0l3xa.com +97ol.com +97rp.com +97rx.com +97ting.com +97ui.com +97uimg.com +97wd.com +97wyw.com +97xdj.net +97zm.com +98.com +98.ma +98030.center +980512.com +980cje.com +981.ee +98182.com +98187411.com +9823f7b9o6.com +98388fafafa.com +984g.com +985.so +985900.com +985dh.com +985hezi.com +985ks.com +985ks.net +985sy.com +98612.com +9862ad1f310292.beer +98654.com +987.com +9873.com +9876game.com +9877.com +987app.com +987dns.com +987you.com +98809.com +988848a9d1013.beer +98892.com +988sl.com +9891.com +9891760ee2389285.com +989198.com +98945.org +9898049.com +98982201.com +98982202.com +98982288.com +98982601.com +98983355.com +98984422.com +98986688.com +9898758.com +98987729.com +9898jh2.com +98b8cd6b21011.beer +98cloud.com +98d4c586f11012.beer +98du.com +98e774f505d78b1a.com +98ep.com +98eye.com +98k4.com +98lm.com +98mc.cc +98mp.com +98nice.com +98one.com +98t.la +98t.net +98tang.com +98tsg.com +98w.co +98weixin.com +98xiaoshuo.com +98xz.com +98yl.com +98zhibo.com +98znz.com +98zw.com +99.com +99113guoji.com +99114.com +99118.com +9911yx.com +99166.com +9917.com +9918.tv +99193.com +991fd1ce91009.beer +991kang.com +991quka.com +9928.tv +99357b59811012.beer +9935china-air.com +9939.com +993937.com +99394.com +993h.com +9942.org +99442.com +9944wb.com +99469.com +994t7px765.com +994wan.com +9950air.com +9951.cc +995120.net +99520.love +996.com +996007.icu +9963.org +996404.xyz +9965dns.com +9966.com +9966.org +9966333.com +9966886699.com +996996.com +996a.com +996box.com +996dns.com +996pic.com +996sdk.com +9973.com +997788.com +998.com +9981ypk.com +9982.com +998231.com +998274.com +99844666.com +99887w.com +998917.com +99895.org +998jk.com +998jx.com +998law.com +998tool.com +9991.com +999120.net +999125.com +999136.xyz +999178.com +999765.xyz +999777.com +9998.tv +99988866.xyz +9999224xtz1.shop +99999dns.com +999abc333abc.com +999ask.com +999brain.com +999d743c51022.beer +999inandon.com +999mywine.com +999shengqian.com +999tea.com +999welder.com +999wx.com +99aiji.net +99aly.com +99bdf.com +99biaozhun.com +99bill.com +99bo.cc +99box.com +99brand.com +99bs.club +99caiba.com +99cc.com +99cfw.com +99cha.com +99cloud.net +99corley.com +99count.com +99danji.com +99dingding.com +99down.com +99dushu.com +99dushuzu.com +99dw.com +99eo.com +99eyao.com +99fang.com +99fei.net +99fenlei.com +99fund.com +99fund.org +99haoche.com +99haoling.com +99hdf.com +99hkjf.com +99huodong.xyz +99ielts.com +99inf.com +99inn.cc +99jee.com +99jianzhu.com +99jiasu.com +99jiasu.net +99jrk.com +99kf.com +99kt.com +99ku.cc +99ku.vip +99kypay.com +99leidun.com +99max.me +99mc.com +99meihua.com +99meiju.tv +99mk.info +99mk.la +99mk.net +99mssj.com +99mst.com +99music.net +99n.me +99nets.me +99pdf.com +99ppt.com +99qh.com +99qibang.com +99qimingzi.com +99qumingzi.com +99read.com +99shi.com +99shou.com +99sj.com +99sky.com +99sun.com +99sushe.com +99sy.co +99thz.com +99tianji.com +99tongxuelu.com +99uri.com +99weiqi.com +99wj.com +99wuxian.com +99xr.com +99xueshu.com +99youmeng.com +99ys.com +99yunshi.com +99yx.com +99zihua.com +99zzw.com +9a04d8da811031.beer +9a9m.com +9aca7ec4f5ae25e5.com +9ailai.com +9aimai.com +9air.com +9amts.com +9aoduo.com +9aola.com +9b09eea7810251.beer +9b11b109-ab3d-4193-ac60-79cc19b3e76d.link +9b37f3cc81011.beer +9bb4cf93e10261.beer +9bianli.com +9c0c0433602d188a.com +9c67282f22796ac6.com +9c941a3b41021.beer +9ca4b8eca1019.beer +9cao9.com +9cb.com +9ccapital.com +9ce69ea6b10272.beer +9cfa10ad910291.beer +9che.com +9chew.com +9clive.com +9conn.net +9d19.com +9d47e2c251009.beer +9d86072bbc545262.com +9d87bc4302122ef4.com +9damao.com +9damao.net +9day.cc +9db.cc +9ddm.com +9de3c7ffb10291.beer +9deli.com +9dfb917ee1019.beer +9dfx.com +9dian.info +9dida.net +9dinn.com +9douyu.com +9droom.com +9duw.com +9dwork.com +9e707bdb763386bf.com +9eacc080d10291.beer +9ead.com +9eae58cbc333acf8.com +9earth.com +9efca2b9a1009.beer +9eip.com +9ele.com +9etravel.com +9f113d434f8c49f0.com +9f7ef6acd10291.beer +9fapi.com +9fav.com +9fb8d5b6bff66a4d.com +9fbank.com +9fe3e7d4c10311.beer +9fh5.com +9first.com +9flb.com +9fmk.com +9fo.com +9fonecard.com +9fpuhui.com +9fs.com +9fzt.com +9fzt.net +9g8g.com +9gg.cc +9ghao.com +9gt.net +9he.com +9hier.com +9host.org +9hou.com +9ht.com +9huadian.net +9i0i.com +9icad.com +9icode.net +9icy.com +9idudu.com +9igcw.com +9ihb.com +9ihome.com +9ijf.com +9ilrc.com +9ilu.com +9imobi.com +9inx.com +9ioldgame.com +9iphp.com +9ishe.com +9ist.com +9iwanwan.com +9iwz.net +9ixf.com +9ixiuxiu.com +9j9y.com +9ji.com +9juewu.com +9jx.com +9k01.com +9k9k.com +9ka.vip +9kcs.com +9kd.com +9khc0iv5n7.com +9kkk.xyz +9kld.com +9kus.com +9laidu.net +9linux.com +9liuda.com +9ljr84.xyz +9longe.net +9m7v44974i.com +9man.com +9mayi.com +9miao.com +9mic.com +9nali.com +9newlive.com +9ngames.com +9niu.com +9nj563358x.com +9now.net +9ok.com +9om.com +9omj.com +9one.cc +9open.com +9orange.com +9p.net +9pinke.com +9pk.net +9qd0wul789.com +9qu.com +9ria.com +9sb.net +9sgx.com +9shadow.com +9skb.com +9skm.com +9sky.com +9slab.com +9sleep.org +9sug.com +9syw.com +9t-tech.com +9taobao.com +9taohao.com +9tax.com +9to.com +9tong.com +9tonglian.com +9tov.com +9u8u.com +9upk.com +9vf.com +9w1an.com +9w9.com +9wee.net +9wuli.com +9wwx.com +9xdb.com +9xgame.com +9xic.com +9xinli.com +9xiu.com +9xiuzb.com +9xo9.com +9xs.org +9xun.com +9ya.net +9yao.com +9yaocn.com +9yc.com +9ye.com +9yiban.com +9you.com +9you.net +9yread.com +9yue.com +9yuntu.com +9yuonline.com +9yz.com +9zas5.com +9zhen.com +9znet.com +9zx.com +a-b.cc +a-du.net +a-isv.org +a-jazz.com +a-liai.com +a-map.co +a-map.link +a-map.vip +a-startech.com +a-sy.com +a-xun.com +a.xttv.top +a0318.com +a049636971024.beer +a04d48409e40ca3f.com +a0598.com +a0770.com +a0bi.com +a0d73230f9d52dfb.com +a0fca7a55be096ef.com +a135.net +a142b5e7511011.beer +a1789.com +a18.ltd +a1891cc2258a919b.com +a1a22678d1019.beer +a1coin.xyz +a1t2w1lzfr.com +a21fs.com +a29e2657018e645b.com +a2dongman.com +a2e1c81dce0fd3ce.com +a2gu2.com +a30437f3510292.beer +a32bd427dd.skin +a335cb802c120705.com +a33a8c8c81011.beer +a40dc409e2ea86b1.com +a42c6d113874e1f3.com +a44aeaeac1016.beer +a45e4f5fd10272.beer +a465a95641016.beer +a490cce2411032.beer +a4da96ae511032.beer +a4s6.com +a4size.net +a5.net +a5089302099a537e.com +a5380a8e41016.beer +a5399.com +a549543886.asia +a5600.com +a58cd776cc.baby +a5b.cc +a5idc.com +a5idc.net +a5j.cc +a5lt.com +a5xiazai.com +a5y.net +a61cee76f4df41b1.com +a632079.me +a6562752811032.beer +a6h8.com +a6ksw.net +a7.com +a700in.ren +a7479032d1014.beer +a74be6c3e1021.beer +a756716251017.beer +a75d755806b1095d.com +a7647e3f151b4a5d.com +a766.com +a789.org +a7a13fde51022.beer +a7c6e291d10292.beer +a7d4bd3ce10281.beer +a7dcb6d9011032.beer +a8.com +a83c8524b88a06ae.com +a87807b4811031.beer +a87f34a60cf36893.com +a88b9f894719c3d8.com +a88dc138be.run +a8f947.com +a8tg.com +a8u.net +a8z8.com +a909ed7022b1ecc1.com +a9188.com +a963.com +a96b32e2b1015.beer +a9998f7ed11042.beer +a9c7f491710251.beer +a9market.com +a9vg.com +a9x9.com +aa-lsk.com +aa08072678.xyz +aa152.com +aa360.net +aa433d1b51013.beer +aa43z7.com +aa4491.com +aa50b44761011.beer +aa56238652.com +aa5c82aeb10271.beer +aa5d.com +aa65535.com +aa6666.com +aa6f0397a3cf50d7.com +aa76858896.com +aa77kk.com +aa84c23fc4aa335a.com +aaalawfirm.com +aaalogisticsgroup.com +aaareplicawatch.com +aaawz.cc +aaayu.com +aaayun.com +aabooo.com +aabqn.com +aac3442de07869c0.com +aacoptics.com +aactp.net +aad5.com +aadcloud.com +aadongman.com +aads-cng.net +aafxw.com +aai07251mu.com +aai07260mu.com +aakss.com +aaltosemi.com +aamets.com +aamev.com +aamgame.com +aamgame.mobi +aamgame.net +aamsmart.com +aamyoe.com +aanroute.net +aap5.com +aapinche.org +aaplimg.com +aardio.com +aarkpbkc.com +aaronlam.xyz +aaspt.net +aastartups.com +aatccn.com +aatcmdvi.com +aateda.com +aauc.net +aaucwbe.com +aavisa.com +aawvw.com +aaxinwen.net +aaygw.com +aaym.net +aayu.today +aayun.icu +aazao.com +ab-sm.com +ab126.com +ab173.com +ab1989.com +ab365.com +ab839c2562b8ae05.com +abaa.cc +abacaipu.com +abackup.com +abaizx.com +abang.com +abaoge.com +abatour.com +abbbio.com +abbisko.com +abbooa.com +abbreviat.com +abbyschoice.net +abc-ca.com +abc-love.com +abc119.tv +abc12366.com +abc151.com +abc188.com +abc369.net +abc4game.com +abc56692388.com +abc59783718.com +abc7722.com +abcache.com +abcbank.shop +abcdd10006.icu +abcdd10032.icu +abcdd10034.icu +abcdd10046.icu +abcdocker.com +abcdv.net +abcerikk8.com +abcfintech.com +abcgonglue.com +abchina.com +abchinalife.com +abcjiaoyu.com +abckantu.com +abcleasing.com +abclive2-lh.akamaihd.net +abclogs.com +abcpost.com.au +abcrcw.com +abcs8.com +abcsbank.com +abctime.com +abcve.com +abcxb.com +abcxx.net +abcxyzkk.xyz +abcydia.com +abd007.com +abddn.com +abdf002.com +abe-sz.com +abe-tech.com +abedu.net +abef6142010291.beer +abercrombie.com +abesmoke.com +abhouses.com +abiechina.com +abifsey.com +abitcg.com +abite.com +abiz.com +abkou.com +able-elec.com +ablejeans.com +ablesci.com +ablesky.com +abletive.com +ablman.com +abloz.com +ably.fan +abmjc.com +abnen.com +abnotebook.com +aboatedu.com +aboboo.com +aboilgame.com +abond.net +aboutcg.com +aboutcg.net +aboutcg.org +aboutgk.com +aboutmy.name +aboutnew.net +aboutyun.com +aboveyunbo.com +abox.plus +abpuvw.com +abreader.com +abslw.com +absoloop.com +absst.com +abtd.net +abtnetworks.com +abtpaper.com +abtt266.com +abublue.com +abundancen.com +abuquant.com +abusi.net +abusky.com +abuyun.com +aby.pub +abykt.com +abyssdawn.com +ac.fun +ac268.com +ac3ba49731016.beer +ac57.com +ac6891953e265977.com +ac78416978de6213.com +acabridge.net +acachina.com +academygkusa.com +academypublication.com +acadn.com +acb365.com +acbiot.com +acc3.net +acc5.com +accdisplay.com +accelerateg.com +acceleratet.com +accelink.com +acceptablt.com +accessads.net +accessgood.com +accessibility-union.com +accessibility-union.net +accessibility-union.org +accessibilityunion.com +accessibilityunion.net +accessibilityunion.org +accessicp.com +accessoft.com +accesspath.com +accgame.com +accio.com +acclb.com +acclb.net +acconsys.com +accopower.com +account.htcvive.com +accr.cc +accsh.org +acctdns.com +acctdns.net +accu.cc +accuramed.com +accurate-china.com +accurate520.com +accxiaoheihe.com +acdianyuan.com +acdnrvh.com +ace-info.com +ace-pow.com +ace-rubber.com +ace06a98610272.beer +ace113.com +acejoy.com +acelamicro.com +aceoo.com +acepanel.net +acesheep.com +acetace.com +acetaffy.club +acetar.com +acewill.net +acexpress.org +acfechina.org +acflow.com +acftu.org +acfun.com +acfun.net +acfun.tv +acfunchina.com +acfunchina.net +acg.gd +acg.tv +acg.xin +acg169.com +acg17.com +acg183.com +acg18s.com +acg4.com +acg6.com +acgdb.com +acggit.com +acgist.com +acglivefan.com +acgmc.com +acgorg.com +acgpic.net +acgpp.net +acgrenwu.com +acgres.com +acgsan.com +acgsky.win +acgtofe.com +acgtubao.com +acguxhda.com +acgvideo.com +acgvr.com +acgwolf.com +acgzc.com +acgzyj.com +achiming.com +achizi.com +acing.com +acingame.com +acirclea.com +acirno.com +acjw.net +ackjled.com +acloudbaas.com +acloudrender.com +acm.org +acmcoder.com +acmec-e.com +acmemob.com +acmetranslation.com +acmoba.com +acmsearch.com +acmturc.com +acnow.net +aco-musical.com +acoloo.com +acoolread.com +acpf-cn.org +acplay.net +acq42.com +acqiche.com +acqyjg.com +acrel-eem.com +acrel-microgrid.com +acrel-znyf.com +acrossmetals.com +acroview.com +acs.org +acshoes.com +acsrq.com +act-telecom.com +actacams.com +actamath.com +actbbs.com +actcn.net +acthao.com +acthd123.com +actime.net +actions-semi.com +actionsky.com +activate.activation-v2.kaspersky.com +activation-gp.com +activation-v2.kaspersky.com +activeclub.net +activepower.net +activity-dy.com +activity-wbsj.com +activity-zhendingtech.com +activity01.com +activity02.com +activity03.com +activity04.com +activity05.com +activitybyte.com +actoys.com +actoys.net +actranslation.com +actself.me +actuive.com +acuangle.net +acumoxj.com +acwapowercn.com +acwifi.net +acwing.com +acwlkj.com +acxk.net +acxxg.com +ad-cn.net +ad-diamond.com +ad-gone.com +ad-goods.com +ad-squirrel.com +ad-young.com +ad110.com +ad22b2e021014.beer +ad2b0298510251.beer +ad321.cc +ad5.com +ad518.com +ad77.com +ad778.com +ada-post.com +adamahf.com +adamcdn.com +adamcoder.com +adamerck.net +adanachina.com +adapay.tech +adas.com +adbgz.com +adbiding.com +adbvllc.cfd +adc-expo.com +adcdn.com +adcomeon.com +adcotechina.com +addaad.com +addchina.com +addgog.com +addimmar168.com +addinghome.com +addnewer.com +addog.vip +addoom.com +addpcn.com +addpv.com +addww.com +addx.live +ade8.com +adeasyx.com +adebang.com +adebibi.com +adeccogroupcn.com +adellock.com +adesk.com +adeskpro.com +adexplain.com +adfaith.com +adfortest.com +adfuns.com +adfyt.com +adg-dental.com +adguardprivate.com +adhei.com +adhimalayandi.com +adhubbj.xyz +adhudong.com +adi-whatsepp.com +adianshi.com +adiexpress.com +adigifactory.com +adiic.com +adinju.com +adipman.net +adjdds.com +adjucai.com +adjuz.com +adjyc.com +adkjpx.com +adl163.com +adl888.com +adlainortye.com +adlefei.com +adlo.net +adluckin.com +adm88888.com +adm999.com +admai.com +admaimai.com +admama.com +admamax.com +admbucket.com +admile.xyz +admin04.com +admin10000.com +admin345.com +admin5.net +admin88.com +admincdn.com +admintony.com +adminxe.com +adminxy.com +admob-cn.com +admobclick.com +admobile.mobi +admonitor.org +admqr.com +admsger.com +admsidea.com +admtvs.com +admunan.com +admxh.com +adnineplus.com +adnrhy.com +adobe-tool.com +adobeae.com +adobeedu.com +adobesc.com +adoebike.com +adonest.com +adongyu.com +adoregeek.com +adoutu.com +adparticle.com +adpchina.com +adpfm513.com +adplusx.com +adpsh.com +adqtt.net +ads66.com +adsalecdn.com +adsalecprj.com +adsame.com +adscover.com +adsctl.com +adseye.com +adseyeservice.com +adsfancy.com +adshonor.net +adshuju.com +adsjdy.com +adslr.com +adsmogo.com +adsmogo.mobi +adsmogo.net +adssaas.com +adssap.com +adsspr.com +adstarcharm.com +adsue.com +adsuni.com +adtaipo.com +adtchrome.com +adtianmai.com +adtime.com +adtmm.com +aduan.cc +adubest.com +aduer.com +adult-stem-cells.com +adunicorn.com +adunimax.com +adunioncode.com +aduspot.com +adutou.com +advanced-microsemi.com +advanced-pneumatics.com +adventsoft.org +advertcn.com +advich.com +advisionhorizon.com +advlion.com +advuser.com +adwanji.com +adwebcloud.com +adwep.com +adwery.com +adwintech.com +adwke.com +adwork.net +adx.pw +adxflow.com +adxiuqia.com +adxliangmei.com +adxmax.com +adxmq.com +adxqd.com +adxwork.com +adxyun.com +adyoc.com +adyounger.com +adyuedong.com +adzhongdian.com +adzhp.cc +adzhp.net +adzhp.site +adznb.com +adzshd.com +ae-inbr.xin +ae0f9d6cf11021.beer +ae1234.com +ae224e62eb93c42a.com +ae256.com +ae3a6d6e09359c15.com +ae58c58c051aacd9.com +ae5de9f6f1021.beer +ae60.com +ae7b5112dd1be127.com +aebell.com +aebiz.net +aec188.com +aecbattery.com +aecc-mall.com +aecichina.com +aecname.com +aecsian.com +aeec9b62d1016.beer +aeenergy.com +aeenets.com +aeespace.com +aegcar.com +aegis-env.com +aegisafe.com +aegisx.net +aegonthtf.com +aehyok.com +aeicei.com +aeink.com +aeinsen.com +aekyungnb.com +aemedia.org +aemoban.com +aeneag.xyz +aeo-cctv.com +aeolustyre.com +aeonbuy.com +aeonmall-china.com +aeonmed.com +aeoto.net +aepku.com +aerchs.com +aerdai.com +aerfaying.com +aerivon.net +aero-shenyang.com +aerochina.net +aerocityholding.com +aerofugia.com +aes-beijing.org +aesimka.com +aesoftland.com +aestheticbutler.xyz +aesucai.com +aevit.xyz +aexpec.com +af122.com +af165fa2910261.beer +af26a21252823cc6.com +af36.com +af360.com +af4bfc60f11011.beer +af8d4587126e00c0.com +afaisouth.com +afang.com +afanti100.com +afarway.com +afbd4a3905a4a9a5.com +afca-asia.org +afca6b82c11032.beer +afcec.com +afcfsf.xyz +afcs.dell.com +afdian.com +afdian.net +afdiancdn.com +afdsc.com +afdvr.cc +afdvr.com +afe-whatsepp.com +afea4f9221023.beer +afeica.com +afengblog.com +afengsoft.com +afenxi.com +affann.com +affluenze.com +afgame.com +afhao.com +afirstsoft.com +afjk.com +afjob88.com +aflink.com +aflytec.com +afp.adchina.com +afpchinesesports.com +african-styles.com +afriendx.com +afrindex.com +afshanghai.org +afszc.com +aft1v1.com +aft56.com +aftersale-amazon.com +aftersales.cc +aftvc.com +afudan.com +afunapp.com +afuvip.com +afzhan.com +ag03.com +ag8.com +agcen.com +agcloudcs.com +agconnect.link +age.tv +age06.com +age6000.com +aged100.com +agedm.app +agefans.com +agel-tech.com +agelocer.com +agenge.com +agenow.com +agentyun.com +aghcdn.com +agi360.xyz +agile-china.com +agileex.com +aginomoto.com +agiquery.com +agiso.com +agitationi.com +agitekservice.com +aglory.com +agmos012.com +agnaw.com +agoow.com +agora.io +agoralab.co +agpolis.com +agriotcloud.com +agrittex.com +agrochemshow.com +agrodt.com +agrofairs.com +agrosg.com +agrowingchina.com +agstt.com +agtech.ltd +agucn.com +agui.cc +agumd.com +agv-amr.com +agvag.com +agxs.net +ah-inter.com +ah-suuwaa.com +ah-zl.com +ah12333.com +ah163.com +ah163.net +ah3c.com +ah788.com +ah7907.com +ah8.cc +ah9yu.com +ahacpp.com +ahaec.com +ahaiba.com +ahaiba.net +ahalei.com +ahanxun.com +ahaohao.com +ahaoyw.com +ahatjt.com +ahauto.com +ahbagy.org +ahbanker.com +ahbb.cc +ahbbsun.com +ahbbtv.com +ahbrt.com +ahbsxh.com +ahbxgwy.com +ahbys.com +ahbzgs.com +ahbztv.com +ahbzxnykj.com +ahbzyy.com +ahc.ink +ahcaijing.com +ahcaw.com +ahceisc.com +ahcfrc.com +ahchanye.com +ahcnb.com +ahcoating.com +ahcsdz.com +ahcyfc.com +ahczqy.com +ahczwater.com +ahd.so +ahdaer.com +ahdahda.com +ahdbsst.com +ahdci.com +ahdf56.com +ahdfjt.com +ahdhf.com +ahdjbh.com +ahdngj.com +ahdohpiechei.com +ahdsez.com +ahdxj.com +ahdzfp.com +aheading.com +ahetyy.com +ahfda.com +ahfeixi.com +ahfensitong.com +ahfg.net +ahfgb.com +ahfszx.com +ahfytx.com +ahgae.com +ahgkw.org +ahglj.com +ahgssh.com +ahguangbo.com +ahgyrn.com +ahgzedu.com +ahhaige.com +ahhanmi.com +ahhaoze.com +ahhbxh.com +ahhcbiotech.com +ahhdb.com +ahhhjx.com +ahhkedu.com +ahhngsjt.com +ahhnsz.net +ahhome.com +ahhouse.com +ahhsxyy.com +ahhtzx.com +ahhwdp.com +ahhyzn.com +ahhzi.com +ahianzhang.com +ahiib.com +ahinv.com +ahipi.com +ahitv.com +ahjdq.com +ahjgxy.com +ahjiankong.com +ahjinyu.com +ahjixi.com +ahjk.com +ahjk34.com +ahjkjt.com +ahjlcd.com +ahjoe.com +ahjpgroup.com +ahjsedu.net +ahjsexam.com +ahjszls.com +ahjtxx.com +ahjyec.com +ahjzjy.com +ahjzw.com +ahjzzs.com +ahkds.com +ahkemi.com +ahkende.com +ahkjksw.com +ahkjwx.com +ahkxsoft.com +ahlca.org +ahlib.com +ahlife.com +ahljnews.com +ahlqgs.com +ahlsm1.com +ahltgroup.com +ahluqiao.com +ahlxb.com +ahlyjt.com +ahlzgd.com +ahmif.com +ahmky.com +ahmwgroup.com +ahnanfang.com +ahnec.com +ahnluh.com +ahnmc.com +ahno-tool.com +ahnxs.com +ahohai.com +ahome365.com +ahomezc.com +ahougn.com +ahpdkj.com +ahphi.com +ahplm.com +ahqian.com +ahqmdq.com +ahqxsw.com +ahrccp.com +ahrcu.com +ahrcw.com +ahread.com +ahrenji.com +ahrenkun.com +ahrsksw.net +ahrunzi.com +ahs.pub +ahsalt.com +ahscl.com +ahscxyy.com +ahsea.com +ahsfdxrmyy.com +ahshbszyyy.com +ahsj-group.com +ahsjxjy.com +ahsjyxh.com +ahspxh.com +ahsqjt.com +ahssgs.com +ahssnews.com +ahsthzx.com +ahswyz.com +ahsxkyb.com +ahsxscsw.com +ahsyj.com +ahsylsy.com +ahsz.tv +ahszbx.com +ahteacher.com +ahtelit.com +ahtlbyby.com +ahtongyuan.com +ahtrq.com +ahtxyyjt.com +ahtypg.com +ahuano.com +ahubbs.com +ahudows.com +ahuyi.com +ahwater.net +ahwbkf.com +ahwjnews.com +ahwjxx.com +ahwmw.com +ahwmyy.com +ahwnqzs.com +ahwnwl.com +ahwwnews.com +ahwwx.com +ahwxcs.com +ahwxhr.com +ahxcyy.com +ahxmgk.com +ahxunbu.com +ahxwkj.com +ahxyol.com +ahydnet.com +ahyessoft.com +ahyijiali.com +ahyiqing.com +ahyouchengedu.com +ahyouth.com +ahyqx.com +ahysxh.com +ahyuning.com +ahyx.cc +ahyx.net +ahyyxh.com +ahyzzx.com +ahzcw.cc +ahzp.com +ahzs10000.com +ahzssw.com +ahztsh.com +ahzxy.com +ahzyw.com +ai-abc.com +ai-anchor.com +ai-augmented.com +ai-cai.com +ai-cctv.com +ai-classes.com +ai-cool.com +ai-daxue.com +ai-factory.com +ai-indestry.com +ai-qingchang.com +ai-rtc.com +ai-start.com +ai-test.com +ai-thinker.com +ai-vip.net +ai-ways.com +ai-yuanjing.com +ai.cc +ai.run +ai012.com +ai0513.com +ai257.com +ai572.com +ai7.com +ai7.org +aiaa.org +aiacfo.org +aiacgn.com +aiagain.com +aiagain.net +aiage.com +aiaigame.com +aiaigu168.com +aiaitie.com +aialbb.com +aianno.com +aiaor.com +aiappx.com +aiba.com +aibaimm.com +aibang.com +aibang.run +aibangbaoxian.net +aibanges.com +aibank.com +aibank.link +aibao.com +aibaocloud.com +aibaogao.com +aibaohu.com +aibaov.com +aibaoxian.com +aibase.com +aibeike.com +aibiaomei.com +aibiaow.com +aibing.cc +aibll.com +aibo123.com +aiboce.com +aiboco.com +aibookba.com +aibreeno.com +aibrm.com +aibwz.asia +aic707.com +aicai.com +aicaicdn.com +aicailang.com +aicairen.com +aicait.com +aicccloud.com +aicdn.com +aicdn.work +aicdn2.com +aicdn3.com +aicdn4.com +aicdn5.com +aichagu.com +aichaicp.com +aichan.info +aichangbaishan.com +aichaoxing.com +aichat.net +aichat1234.com +aichehome.com +aichi-zhe.com +aichinaw.com +aichunjing.com +aiclicash.com +aicloud.com +aicoauto.com +aicode.cc +aicoinstorge.com +aiconn.com +aicsemi.com +aicsuk.net +aicthink.com +aicu8.com +aicunfu.com +aicunxibao.com +aida64.cc +aida64cn.com +aidabest.com +aidai.com +aidaijia.com +aidaily.com +aidaiz.com +aidalan.com +aidangbao.com +aidanji.com +aidapeid.com +aidaxing.com +aidaxue.com +aidcgroup.net +aidcstore.net +aideep.com +aidenleong.com +aidianji.net +aidiao.com +aidien.fun +aidigong.com +aidimedia.com +aidjyun.com +aidlearning.net +aidlux.com +aidoctor.world +aidoczh.com +aidog.com +aidong-ai.com +aidong.me +aidonghai.com +aidoor.net +aidouzuji.com +aidpaper.com +aidream.website +aidrive.com +aidubuluo.com +aidugame.com +aiduoka.com +aidusk.com +aidusk.org +aiduwenxue.com +aidynamic.com +aidytt.com +aiec-alliance.com +aieco.org +aiecoms.com +aiegde.com +aiegle.com +aiema.com +aiemy.com +aieok.com +aier020.com +aier021.com +aier0431.com +aier0755.com +aier0771.com +aier0775.com +aierchina.com +aierfano.com +aierhb.com +aierhs.com +aierlz.com +aieryk.com +aierzy.com +aievsge.com +aieye8.com +aiezu.com +aifabu.com +aifacelab.com +aifamu.com +aifanfan.com +aifang.com +aifanyi.net +aifcdn.com +aifei.com +aifei.info +aifengjie.com +aifengkeji.com +aifenlei.com +aifont.com +aifooler.com +aifoxtech.com +aifu10.com +aifu360.com +aifuturex.com +aifuwus.com +aifuxi.com +aigame.com +aigame100.com +aiganggu.com +aigc-cloud.com +aigc369.com +aigcarena.com +aigccdn.com +aigclsp.com +aigcxm.com +aige010.com +aigei.com +aigewc.com +aigexing.com +aigexing.net +aigo.com +aigobook.com +aigodiy.com +aigodlike.com +aigou.com +aigrammar.net +aigtek.com +aiguhuishou.com +aiguilai.com +aiguo.tech +aigupiao.com +aihaisi.com +aihala.com +aihanfu.com +aihanfu.net +aihangtian.com +aihao.org +aihecong.com +aihehuo.com +aihelp.net +aihelpcn.net +aihero100.com +aihke.com +aihoge.com +aihotel.com +aihst8.com +aihua1998.com +aihuajia.com +aihuaju.com +aihuau.com +aihuazhou.com +aihubs.net +aihuhua.com +aihuishou.com +aii-alliance.org +aiibii.com +aiig.cc +aiihu.com +aiijournal.com +aiimg.com +aiimooc.com +aiioii.com +aiit.me +aiitec.com +aiiup.com +aiji66.com +aijiajiankang.com +aijianji.com +aijiatui.com +aijiayou.com +aijingu.com +aijishu.com +aijiuku.com +aijizhang.net +aijuhome.com +aik.com +aikaixin.com +aikaiyuan.com +aikan669.com +aikan8.com +aikanba.cc +aikang.com +aikanggroup.com +aikeapp.com +aikep.com +aiketour.com +aikf.com +aikgmgre.com +aikonchem.com +aikucun.com +ail-online.moe +ailaba.com +ailabs.xin +ailai6.com +ailbaba.me +ailemon.net +ailete.com +ailewan.com +aileyun.net +ailiao360.com +ailibang.com +ailibi.com +ailinglei.com +ailingmao.com +ailinux.net +ailinzhou.com +ailipu.com +ailite.com +ailiyun.com +ailom.com +ailongmiao.com +ailuckyboy.com +ailugroup.com +ailuluz.com +ailuntan.com +ailvxing.com +aim-ec.com +aimaker.space +aimap.com +aimatech.com +aimatrix.ai +aimcx.com +aimeas.com +aimeideni.com +aimeifen.vip +aimeike.tv +aimeilid.com +aimengang.com +aimergroup.com +aimeter.com +aimgroupcn.com +aimicron.com +aimilebc.com +aimin1979.com +aimingmed.com +aimingtai.com +aimipay.net +aimiplay.com +aimo.work +aimo2o.com +aimoeart.com +aimoge.com +aimoneshoes.com +aimsen.com +aimu-app.com +ainas.cc +ainiapp.com +ainirobot.com +ainiseo.com +ainiu.net +ainixing.com +ainm.cc +ainol.com +ainuoedu.com +ainyi.com +aioclinic.com +aioexpress.com +aiops.com +aioptics.com +aiotoolbox.com +aip-gz.com +aip.net +aip.org +aipage.com +aipai.com +aipaike.com +aipaixt.asia +aipaiyinghua.com +aipark.com +aiparkvip.com +aipay.cloud +aipcc-gz.com +aipedu.net +aipenglai.com +aipgy.com +aiphz.com +aipiaxi.com +aipingxiang.com +aipintuan.com +aipiwu.com +aippt.com +aiprose.com +aipu-waton.com +aipuo.com +aipz.com +aiqfd.com +aiqgy.com +aiqi-pharma.com +aiqiangua.com +aiqianxq.com +aiqibaba.com +aiqicha.com +aiqiche.com +aiqin.com +aiqingyu1314.com +aiqisoft.com +aiqiye.cc +aiqiyi.com +aiqiyicloud-mgmt.com +aiqiyicloud.com +aiqiyicloud.net +aiqiyivip.com +aiqle.com +aiqu.com +aiqu.design +aiquxs.com +aiqygogo.com +air-level.com +air-matters.com +air-matters.io +air-world.com +air.cc +airacm.com +airbft.com +airboo.com +airchangan.com +airchina.com +airchinacargo.com +airchinagroup.com +airchinaim.com +airchinamedia.com +aircourses.com +aircx.bid +airdali.com +airdoc.com +airdropin.com +airenche.com +airepay.net +airfex.net +airguilin.com +airj.website +airjd.com +airkunming.com +airland1966.com +airleaderchina.com +airmart.vip +airmate-china.com +airmb.com +airmobyte.com +airnut.com +airoha.com.tw +airpipetech.com +airpointshop.com +airportcip.com +airportcn.com +airsavvi.com +airshipads.ru +airspa.net +airstar-finance.com +airstar.com +airstarfinance.com +airstarfinance.net +airtac.com +airtofly.com +airtu.me +airwh.com +airworksoft.com +aisaohuo.com +aisbeijing.com +aise.chat +aisecurius.com +aisee.tv +aiseeking.com +aiseminar.com +aisenseinc.com +aishangba.info +aishangba.org +aishangyangyu.com +aisharenet.com +aishengji.com +aishenhua.com +aishenqi.net +aishuge.cc +aishuge.la +aishukong.com +aishuola.com +aishushu3.com +aishuttler.com +aisidi.com +aisila.com +aisilipu.com +aisin-sh.com +aisino.com +aisinogd.com +aisinogz.com +aisitool.com +aisixiang.com +aiskr.com +aisky.cc +aiskycn.com +aislharrow.com +aisnogames.com +aisojie.com +aisou.club +aisoutv.com +aispeech.com +aisportsapp.com +aispreadtech.com +aistar.site +aistar666.com +aistudio-app.com +aisx.cc +aisy.com +aitangyou.com +aitaotu.com +aitcfw.com +aite.xyz +aitecar.com +aitecc.com +aitechforsafety.com +aitemall.com +aiterent.com +aitesu.com +aitetech.com +aitiancheng.com +aitielu.com +aiting.com +aitists.com +aititia.com +aitiyu.com +aitkcn.com +aitntnews.com +aito.auto +aitoolwang.com +aitrans.net +aitransfy.com +aitsnet.com +aituan.com +aituanche.com +aitutor100.com +aitutu.cc +aitype.net +aiufida.com +aiutdns.com +aiuxdesign.com +aiuxian.com +aiuxstudio.com +aiv5.cc +aiveola.com +aivivo.com +aiviy.com +aiviysoft.com +aivote.com +aiwaly.com +aiwan4399.com +aiwan91.com +aiwanba.net +aiwatchs.com +aiwebsec.com +aiwei365.net +aiweibang.com +aiweibk.com +aiweline.com +aiwenyi.com +aiwisland.com +aiworkspace.com +aiwuzhou.com +aiwvegax.com +aiww.com +aixag.com +aixcoder.com +aixiangtan.com +aixiaoduo.com +aixiaoka.net +aixiaola.com +aixiaomedia.com +aixiashu.com +aixiashu.info +aixiashu.net +aixiatxt.com +aixiawx.com +aixiaxs.com +aixiaxsw.com +aixiezuobao.com +aixifan.com +aixigua.com +aixin-ins.com +aixin-life.com +aixin-life.net +aixinhaitun.com +aixinmusic.com +aixinwechat.com +aixinwu.org +aixiu.net +aixiuyingyu.com +aixq.com +aixs.info +aixs.org +aixue.net +aixuebanban.com +aixueche.com +aixuedai.com +aixuejun.com +aixuekku.com +aixuesheng.net +aixuetang.com +aixuexi.com +aixyy.com +aixzu.com +aiya.live +aiya8.com +aiyaapp.com +aiyamax.com +aiyangedu.com +aiyanqing.com +aiyaopai.com +aiyecdn.com +aiyewj.com +aiyewjc.com +aiyichuan.com +aiyidu.com +aiyinghun.com +aiyingli.com +aiyingshi.com +aiyinteli.com +aiyishu.com +aiyisoft.com +aiyituo.com +aiyjs.com +aiykj.com +aiyo99.com +aiyong.work +aiyongaiwan.com +aiyou.com +aiyoumi.com +aiyouxi.com +aiyouzj.com +aiyoweia.com +aiysm.com +aiyue520.com +aiyuke.com +aiyunxiao.com +aiyy.org +aizaoqi.com +aizgtc.com +aizhan.com +aizhanzhe.com +aizhengli.com +aizhet.com +aizhibo.net +aizhishang.com +aizhugong.com +aizools.com +aizuna.com +aizuopin.com +aizusheng.com +ajbcloud.com +ajbtv.com +ajcass.com +ajcctv.com +ajclass.com +ajedu.com +ajfcxx.com +ajgts.com +ajhchem.com +ajhimalayanqf.com +ajiang.net +ajihuo.com +ajinga.com +ajiu.xin +ajiuqian.com +ajkcdn.com +ajkdns2.com +ajkfc.com +ajkimg.com +ajkinclude.com +ajlty.com +ajmide.com +ajpysz.com +ajrcb.com +ajs-app.com +ajs17.com +ajtmy.com +ajuhao.com +ajutwatch.com +ajwang.com +ajxhgy.com +ajyg.com +ajzq.com +ak-medical.net +ak.cc +ak0.tw +ak03220hou.com +ak03230hou.com +ak1ak1.com +ak47ids.com +aka-amd-njpwworld-hls-enlive.akamaized.net +aka700.com +aka700.net +akadns88.net +akadns99.net +akaifa.com +akailibrary.com +akamai.com +akashadata.com +akashic.cc +akaxin.com +akbchina.com +akbe.com +akbing.com +akbkgame.com +akcomemetals.com +akdns.net +akeeps.com +akesobio.com +akey.im +akey.me +akey.work +akeyun.com +akgjgs.com +akhlwyy.com +akhtm.com +akhy.com +aki-game.com +aki-game.net +aki-game2.com +aki-game2.net +akile.net +akjianding.com +akkogear.com +aklyw.com +akng.net +akniu.com +akoeva.com +akomr.com +akoo0509uis.com +akpig.com +akplayer.com +akppt.net +akptfe.com +akr-developers.com +akru.plus +akscan.com +akspeedy.com +akswjt.com +aksxw.com +aku.pub +akuziti.com +akylq.com +akymmzs.com +al-jin.com +al8l.com +alabmed.com +alaboshuiyan.com +alacun.com +aladdin-assets.com +aladdin-e.com +aladdin-reagent.com +aladdinedu.com +aladdinnet.com +alafy.com +alai.net +alameal.com +alanyhq.com +alavr.com +alayanew.com +alayu.com +alayunchina.com +alazv.com +albeche.com +albertaz.com +alc-iot.com +alcasset.com +alcatel-home.com +alcatelmobile.com +alcha.com +alcty.com +alcy.cc +aldeee.com +aldf.online +aldgo.com +aldnew.com +aldsd.com +aldtop.com +aldwx.com +aledeco-hk.com +aleenote.com +alenable.com +alertover.com +alevelwx.com +alexhaohao.com +alexinea.com +alexpad.fun +alexyan.cc +alfa-x.sbs +alfachemar.com +alfafull.com +alfingfuda.com +algkfd.com +algogear.com +algorithmart.com +alh6.com +alhug.com +alhywj.com +ali-api-test.net +ali-cdn.com +ali-expo.com +ali-gtm-01.net +ali-gtm-pressure.com +ali-health.com +ali-restore.net +ali-star.com +ali213.com +ali213.net +ali37.net +aliadvance.com +aliajj.com +alialipay.com +alianhome.com +aliapp-inc.com +aliapp.com +aliappcdn.com +alibaba-inc.com +alibaba.cdn.steampipe.steamcontent.com +alibaba.com +alibaba.net +alibabacapital.com +alibabachengdun.com +alibabachengdun.net +alibabacloud.co.in +alibabacloud.com +alibabacloud.com.au +alibabacloud.com.hk +alibabacloud.com.my +alibabacloud.com.sg +alibabacloud.com.tw +alibabacorp.com +alibabadesign-enable.com +alibabadesign.com +alibabadns.com +alibabadoctor.com +alibabafonts.com +alibabafoundation.com +alibabafuturehotel.com +alibabagroup.com +alibabainno.com +alibabaonline.com +alibabapictures.com +alibabaplanet.com +alibabastars.com +alibabatech.org +alibabatechqa.com +alibabaued.com +alibabausercontent.com +alibabawood.com +alibench.com +alibjyun.com +alibjyun.net +alibole.com +alibtc.com +alibtrip.com +alibuybuy.com +alic.com +alicache.com +alicall.com +alicaptcha.com +alicdm.com +alicdn.com +alicdn.net +alicloud.com +alicloudapi-inner.com +alicloudapi.com +alicloudcc.com +alicloudccp.com +alicloudddos.com +alicloudlayer.com +alicloudsec.com +alicloudwaf.com +alicontainer.com +alictf.com +alidata.org +alidayu.com +aliddmall.com +alidns.com +alidns.net +alidz.net +aliedge.com +alienfans.net +aliensidea.com +alientek.com +aliexpress-media.com +aliexpress.com +aliexpress.ru +aliexpress.us +alifabu.com +alifanyi.com +alifejk.com +alifenxiao.com +aligames.com +aligaofang.com +aligenie.com +aligfcc.com +aligfddos.com +aligfwaf.com +alighting.com +alihd.net +alihealth.hk +alihealth.net +alihh.com +alihuahua.com +aliimg.com +aliiotapp.com +alijijinhui.org +alijk.com +alikmd.com +alikunlun.com +alikunlun.net +alili.tech +aliliying.com +aliloan.com +aliluya.com +alimamaframe.com +alimaomall.com +alime.ai +alimebot.com +alimei.com +alimmdn.com +alinx.com +alinx.vip +aliog.com +alionexpo.com +alipan.com +alipansou.com +alipay-corp.com +alipay-eco.com +alipay-inc.com +alipay-traffic.com +alipay.com +alipay.hk +alipay.net +alipayauto.com +alipaycs.com +alipaydesign.com +alipaydev.com +alipaydns.com +alipayeshop.com +alipayhk.com +alipaymo.com +alipayobjects.com +alipayplus.com +alipcsec.com +aliplay.com +aliplus.com +alippm.com +aliqiche.com +aliqq.cc +aliresearch-internal.com +aliresearch.com +alirtc.com +alirui.com +alisealing-pre.com +alisealing-sit.com +alisealing-uat.com +alisealing.com +alishine.net +aliso.cc +alisoft.com +alisolarlight.com +alisports.com +alitchina.com +alitelecom.com +alithefox.net +alithon.com +alitianji.com +alitrip.com +alitrip.hk +alittle-tea.com +alittlesoldier.com +aliued.com +aliunicorn.com +aliuv.com +alivcr.com +alivecdn.com +alivv.com +aliway.com +aliwd.com +aliwears.com +aliwork.com +aliwx.net +alixiaomi.com +alixiaoyouhui.com +alixixi.com +alixox.com +alixueyuan.net +aliyiyao.com +aliyizhan.com +aliypc.com +aliyue.net +aliyun-esa.net +aliyun-inc.com +aliyun-iot-share.com +aliyun-znfhq.net +aliyun.com +aliyun.org +aliyun.xin +aliyunbaas.com +aliyunbaike.com +aliyuncc.com +aliyuncdn.com +aliyuncdn.net +aliyunceng.com +aliyuncname.xyz +aliyuncs.com +aliyuncsslb.com +aliyuncsslbintl.com +aliyunddos0002.com +aliyunddos0003.com +aliyunddos0005.com +aliyunddos0006.com +aliyunddos0007.com +aliyunddos0010.com +aliyunddos0011.com +aliyunddos0012.com +aliyunddos0014.com +aliyunddos0015.com +aliyunddos0017.com +aliyunddos0018.com +aliyunddos0019.com +aliyunddos0020.com +aliyunddos0023.com +aliyunddos0024.com +aliyunddos0025.com +aliyunddos0026.com +aliyunddos0027.com +aliyunddos0029.com +aliyunddos0030.com +aliyunddos1001.com +aliyunddos1002.com +aliyunddos1003.com +aliyunddos1004.com +aliyunddos1005.com +aliyunddos1006.com +aliyunddos1007.com +aliyunddos1008.com +aliyunddos1009.com +aliyunddos1010.com +aliyunddos1011.com +aliyunddos1012.com +aliyunddos1013.com +aliyunddos1014.com +aliyunddos1015.com +aliyunddos1016.com +aliyunddos1017.com +aliyunddos1018.com +aliyunddos1019.com +aliyunddos1020.com +aliyunddos1021.com +aliyunddos1022.com +aliyunddos1023.com +aliyunddos1024.com +aliyunddos1025.com +aliyunddos1026.com +aliyunddos1027.com +aliyunddos1028.com +aliyunddos1029.com +aliyunddos1030.com +aliyundrive.cloud +aliyundrive.com +aliyundrive.net +aliyunduncc.com +aliyundunddos.com +aliyundunwaf.com +aliyunedu.net +aliyunfile.com +aliyunfuwuqi.com +aliyunga.com +aliyunga0004.com +aliyunga0005.com +aliyunga0006.com +aliyunga0007.com +aliyunga0008.com +aliyunga0009.com +aliyunga0010.com +aliyunga0011.com +aliyunga0012.com +aliyunga0013.com +aliyunga0014.com +aliyunga0015.com +aliyunga0016.com +aliyunga0017.com +aliyunga0018.com +aliyunga0019.com +aliyunga0020.com +aliyunga0021.com +aliyunga0022.com +aliyunga0023.com +aliyunga0024.com +aliyunga0025.com +aliyunga0026.com +aliyunga0027.com +aliyunga0028.com +aliyunga0029.com +aliyunga0030.com +aliyunga0031.com +aliyunga0032.com +aliyunga0033.com +aliyunga0034.com +aliyunga0035.com +aliyunga0036.com +aliyunga0037.com +aliyunga0038.com +aliyunga0039.com +aliyunga0040.com +aliyunga0041.com +aliyunga0042.com +aliyunga0043.com +aliyunga0044.com +aliyunga0045.com +aliyunga0046.com +aliyunga0047.com +aliyunga0048.com +aliyunga0049.com +aliyunga0050.com +aliyunga860004.com +aliyunga8601.com +aliyunga8602.com +aliyunga8603.com +aliyungf.com +aliyungrtn.com +aliyunhelp.com +aliyunhn.com +aliyunidaas.com +aliyuniot.com +aliyunj.com +aliyunjiasu.cloud +aliyunlive.com +aliyunlivetest.com +aliyunos.com +aliyunparking.com +aliyunpds.com +aliyunqifu.com +aliyunrtc.com +aliyunssl3.com +aliyunvpc.com +aliyunwaf.com +aliyunwaf1.com +aliyunwaf2.com +aliyunwaf3.com +aliyunwaf4.com +aliyunwaf5.com +aliyunx.com +alizhaopin.com +alizhizhu.com +alizila.com +aljazeera-eng-hd-live.hls.adaptive.level3.net +alkpharm.com +alkuyi.com +all-in-data.com +all3c.com +all4seiya.net +allapp.link +allawnfs.com +allawno.com +allawntech.com +allbrightlaw.com +allchips.com +allcitygo.com +allcitysz.net +alldobetter.com +alldragon.com +alleadprint.com +allenmarket.com +allfang.com +allfootballapp.com +allfunnies.com +allgamesky.com +allhistory.com +alliancebrh.com +allianz360.com +allicdata.com +allied-corp.com +alliedrongda.com +allinbots.com +allinfinance.com +allinpay.com +allinpaygx.com +allinpayhb.com +allinpaysz.com +allinso.com +alllandnet.com +alllget.com +alllook.tv +allmaga.net +allmed-china.com +allmei.com +allnow.com +alloyteam.com +allpay.xin +allpayx.com +allpku.com +allposs.com +allrace.com +allred.vip +allsafeip.com +allsaintsmusic.com +allschool.com +allschoolcdn.com +allsenseww.com +allshiping.com +allshopwatch.com +allspark-cn.com +allstack.net +allstatics.com +allstor.org +alltechmed.com +alltion-cn.com +alltoall.net +alltobid.com +alltosun.com +alltuu.cc +alltuu.com +allvalue.com +allwellsports.com +allweyes.com +allwin368.com +allwinnertech.com +allwinso.com +allyes.net +allyfurn.com +allystar.com +allyvn.com +alminecn.com +almondoy.com +alnan.com +alo7.com +aloha-ukulele.com +alonemonkey.com +along96.com +alongsky.com +alookweb.com +alpha-browser.com +alpha-star.org +alphabiopharma.com +alphabole.com +alphassl.com +alphay.com +alrailpha.com +alskbc.com +alsolife.com +alsovalue.com +alszxyy.com +altamob.com +altratek.com +altstory.com +altwavehub.cfd +altxw.com +alu-ledprofile.com +aluaa.com +aluminiumchina.com +aluntan.com +alwaysnb.com +alwayzev.com +alwindoor.com +alxw.com +alyasset.com +alyisheng.com +alypw.com +alyzq.com +alzls.com +alzscl.com +am-sino.com +am1116.com +am774.com +am810.net +am89.com +amaiche.com +amallb2b.com +amalrob.com +amantang.com +amanyi.com +amap.com +amapauto.com +amarsoft.com +amassfreight.com +amasswww.com +amaxchina.com +amayad.com +amazfit.com +amazingsys.com +amazom-update.com +ambassadorchina.com +amberbj.com +amberedu.com +amberhotelsgroup.com +amberknit.com +ambier.net +ambition-soft.com +ambow.com +amcarebsh.com +amcaresz.com +amcarewl.com +amcfortune.com +amchamchina.org +amcvoyages.com +amd.com +amdlive-ch01.ctnd.com.edgesuite.net +amdlive-ch03-ctnd-com.akamaized.net +amdlive-ch03.ctnd.com.edgesuite.net +amdlive.ctnd.com.edgesuite.net +amdotibet.com +amec-inc.com +amegroups.org +ameisx.com +amemv.com +amemv.net +ameow.xyz +americachineselife.com +amethystum.com +amexpressnetwork.com +ameya360.com +amflowbikes.com +amflower.com +amgbs.com +amgepic.com +amh.sh +amhimalayanet.com +amhl.net +amiao.co +amicc.com +amijiaoyu.com +amindbox.com +aminglinux.com +amishii.com +amishow.com +amivian.com +amiyabot.com +amo-solar.com +amo9.com +amobbs.com +amoe.cc +amonxu.com +amoydxmed.com +amp-intl.com +ampcn.com +amperobots.com +amphenol-auto.com +amphenol-industrial.com +amphenol-jet.com +amphibiachina.org +amplesky.com +amplly.com +ampmake.com +ampxl.com +amqyl.com +ams-aigc.com +ams.org +amsky.cc +amsoveasea.com +amssro.net +amswater.com +amtbbs.org +amtf18.com +amtjt.com +amtron-ic.com +amuletj.com +amuletor.com +amuluze.com +amunion.com +amusic.shop +amyart360.com +amymx.org +amyroutes.com +amysql.com +amyxun.com +amz123.com +amz520.com +amz800.com +amzcaptain.com +amzcfo.com +amzdh.com +amzkeys.com +amzmm.com +amzndns-cn.biz +amzndns-cn.com +amzndns-cn.net +amzqazc.com +an1health.com +an2.net +an68.com +analog.com +analogfoundries.com +analysysdata.com +analytics.strava.com +anan123.vip +anan666.com +anandoor.com +anandzhang.com +ananlighting.com +ananpet.com +anao.vip +anatuprak.com +anav.com +anbang-life.com +anbanggroup.com +anbaool.com +anbokeji.net +ancbk.com +ancda.com +ancdwqob.asia +ancesours.com +anchnet.com +ancii.com +ancun.com +anda-cn.com +anda-tech.com +andaike.com +andakc.com +andan.me +andazr.com +andcaifu.com +andemed.com +andertechs.com +andes.tech +andesbrain.com +andeshengtec.com +andfx.net +andgele.com +andhj.com +andpay.me +andreader.com +android-doc.com +android-studio.org +androidesk.com +androidga.com +androidgo.duapp.com +androidinvest.com +androidmi.com +androidmov.com +androidonline.net +androidperformance.com +androidtea.com +andtosi.com +andwi.com +andygcj.com +andyx.net +ane56.com +aneasystone.com +anestcang.com +anetuo.com +anf-z.com +anfan.com +anfangnews.com +anfangzb.com +anfensi.com +anfine-healthcare.com +anfipet.com +angeeks.com +angel-game.net +angel-hospital.com +angel-medical.net +angel-usa.com +angelacon.com +angelakillian.com +angelarabbit.com +angelcrunch.com +angelhome.org +angeljjangnara.com +angell-studio.com +angelmom.org +angeltranslation.com +angelyeast.com +angelyeast.ru +angelyeast.xyz +angine.tech +angleebeauty.com +anglo-chinese.com +angogotech.net +angrymailer.com +angrymiao.com +angui.org +anguilasia.com +anguomob.com +angustar.com +angwei.net +anhei2.com +anhei3.net +anheng.com +anhengcloud.com +anheyu.com +anhkgg.com +anhouse.com +anhuaedu.com +anhuanjia.com +anhui-expressway.net +anhui365.net +anhuiaia.com +anhuicta.com +anhuigaokao.com +anhuihr.com +anhuihuayun.com +anhuijszp.com +anhuilife.com +anhuimeijia.com +anhuimobile.com +anhuinews.com +anhuiry.com +anhuisjx.com +anhuisuya.com +anhuiwine.com +anhuiyun.com +anhuizk.com +ani-sh.com +aniccw.net +aniceapp.com +anicoga.com +anictdns.store +anijue.com +anileyehospital.org +animalchina.com +animate.art +animationcritics.com +animebytes.tv +animetamashi.com +animetaste.net +animetorrents.me +anischools.com +anitama.net +aniu.com +aniu.so +aniu.tv +aniworld.tv +anjgas.com +anji-ceva.com +anji-logistics.com +anji-tonghui.com +anji66.net +anjia.com +anjiala.com +anjialaw.com +anjian.com +anjianghu.net +anjiangshi.com +anjiechem.com +anjiecorp.com +anjifood.com +anjilog.com +anjimicro.com +anjismart.com +anjixg.com +anjoyfood.com +anjubao.com +anjujituan.com +anjuke.com +anjukestatic.com +ankai.com +ankang.net +ankang06.org +ankangfulu.com +ankangtong.com +ankangwang.com +ankaotong.com +ankebio.com +ankelife.com +ankeni.net +anker-in.com +ankerjiedian.com +ankevip.com +ankeyunda.com +ankianki.com +ankichina.net +ankki.com +ankobot.com +ankogroup.com +ankuai.net +anl-cn.com +anlai.com +anlaiye.com +anlewo.com +anlian.co +anliantest.com +anlibaby.com +anlilaw.com +anlink.com +anlitai.com +anlogic.com +anlu.net +anlu114.com +anlusy.com +anmco8.com +anmeisheng.com +anmo.com +anmobc.com +anmpserver.com +anmumchina.com +ann9.com +annabelz.com +annainj.com +annearkham.com +anneijun.com +annelhair.com +annhe.net +anniekids.net +annil.com +annoron.com +annto.com +annualreviews.org +annuoxun.com +anoah.com +anonym-hi.com +anosmcloud.com +anoyi.com +anpig.com +anpsk.org +anpu119.com +anpush.com +anpuzx.com +anqingonline.com +anqingwt.com +anqingzhiyun.com +anqn.com +anqu.com +anquan.info +anquanbao.com +anquanjs.com +anquanke.com +anquanone.com +anquanssl.com +anquantong.com +anquanzhao.com +anran233.com +anrangas.com +anranhs.com +anrayer.com +anren.org +anrenmind.com +anrenxmed.com +anrlm.com +anruan.com +anruichina.com +ansendun.com +anshahouse.com +anshibuff.com +anshiduo.com +anshig.com +anshinko.com +anshism.com +anshunfiber.com +anshunholdinggroup.com +anshuntech.ltd +ansiding.com +ansimeter.com +ansky.com +ansteelgroup.com +ansucai.com +ansuner.com +ansxtech.com +ant-biz.com +ant-cloud.net +ant-financial.com +ant-open.com +anta.com +antaifans.com +antaiib.com +antairui.net +antangbusiness.com +antao.hk +antaq.com +antbank.hk +antbuyhot.com +antchina.com +antcloud-miniprogram.com +antcut.com +antdigital.com +antebao.com +antebo.com +antekoptics.net +antespace.com +antewer.com +antfans.com +antfin-inc.com +antfin.com +antfinancial-corp.com +antforecast.com +antfortune.com +antgroup.com +antgv.com +antibanads.com +antibodychina.com +anticheatexpert.com +antiquelearn.com +antiviruspcsuite.com +antiy.com +antiy.net +antiycloud.com +antmoe.com +antom.com +antpcdn.com +antpedia.com +antping.com +antplay888.com +antriver.com +antrol.com +antsdaq.com +antso.com +antsoo.com +antspainter.org +antto.cc +antuan.com +antuan365.com +antuni.com +antuofh.com +antutu.com +antutu.net +antvlive.ab5c6921.cdnviet.com +antvr.com +antwork.link +antyikangih.com +anw.red +anweilan.com +anweishi.com +anweizhi.com +anwen.cc +anwfm.com +anwha-auto.com +anxia.com +anxiangkeji.net +anxiaoer.com +anxin.com +anxin.link +anxin168.com +anxin360.com +anxin360.net +anxinapk.com +anxinbianmei.com +anxindavisa.com +anxinfloor.com +anxinfloors.com +anxinlirong.com +anxinmai.com +anxinssl.com +anxintrust.com +anxinwangdun.com +anxinyisheng.com +anxinzhonghui.com +anxiu.com +anxiw.com +anxjm.com +anxunshihui.com +any123.com +any8.com +anyan.com +anyang100.com +anyangedu.com +anyant.com +anybeen.com +anybox.com +anychem.com +anycoh.com +anycross.com +anycubic.com +anye.xyz +anyelse.com +anyew.com +anyforprint.com +anyforweb.com +anygame.info +anyihua.com +anyimai.com +anyizn.com +anyka.com +anyknew.com +anyline.org +anymcu.com +anymetre.com +anyni.com +anynote.org +anyolife.com +anyong.net +anyoy.com +anyrtc.io +anyrui.win +anysafer.com +anyscdn.com +anyskygame.com +anysql.net +anystandards.com +anytesting.com +anytocopy.com +anyun100.com +anyunjianzhan.com +anyv.net +anyview.net +anyway.fm +anyway.red +anywlan.com +anywood.com +anyxz.com +anzerclub.com +anzext.com +anzhen.org +anzhengshipin.com +anzhi.com +anzhiguolv.com +anzhitan.com +anzhixun.com +anzhuauto.com +anzhuo.com +anzhuo.me +anzhuoapk.com +anzhuoe.com +anzhuoshouzhuan.com +anzmy.com +anzogame.com +anzow.com +ao-di.com +ao-hua.com +ao3yiqag7zc8za.com +aoao365.com +aoaob.com +aoasign.com +aobacore.com +aobaishi.com +aobanghb.com +aoboor.com +aobosoft.com +aocde.com +aocdn.com +aoch.com +aochengcdn.com +aocslb.com +aocter.net +aodabo.tech +aodaliyaqianzheng.com +aodbw.com +aoddoll.com +aode8.com +aodeline.com +aodeng.cc +aodianyun.com +aodingsy.com +aoecq.com +aoedi.com +aoerdz.com +aoetech.com +aofanxx.com +aofeida.com +aofenghuanjing.com +aofenglu.com +aofs.vip +aogocorp.com +aograph.com +aoguan.com +aoguansteel.com +aoguanwns.com +aohaosiyq.com +aohuasports.com +aohuatextiles.com +aojauto.com +aojia-oil.com +aojiahuashare.com +aojiamarly.com +aojian.net +aojian2.net +aojiaostudio.com +aojiyingyu.com +aojiyouxue.com +aoju.net +aokang.com +aokangsports.com +aolai.com +aolaigo.com +aoligei.site +aolijsj.com +aolinjy.com +aolinpharma.com +aoliongame.com +aolvyou.com +aolylcd.com +aomao.com +aomeikeji.com +aomolit.com +aomygodstatic.com +aonaotu.com +aoni.cc +aoofu.com +aoogee.com +aoohu.com +aoongmob.com +aooooz.com +aopayun.com +aoqiangtc.com +aorankj.com +aoratec.com +aoscdn.com +aoscom.net +aosenm.com +aosens.com +aoseo.com +aoserp.com +aoshine.com +aoshitang.com +aoshite.net +aoshowsh.com +aoshu.com +aosikazyimage.com +aosong.com +aosoo.com +aoswtc.com +aotaidianqi.com +aotchina.com +aotian.com +aoto.com +aotoso.com +aotrip.net +aotuzuche.com +aotxland.com +aoun.ltd +aovud.com +aowei-sh.com +aowei.com +aowenmarketing.com +aoxiang100.com +aoxingrelang.com +aoxintong.com +aoxsb.com +aoy-power.com +aoya-hk.com +aoyanchang.com +aoyangzg.com +aoyanwl.com +aoye.com +aoyige.com +aoyii.com +aoyiluoad.com +aoyor.com +aoyotech.com +aoyou.cc +aoyou.com +aoyou365.com +aoyoulife.com +aoyoux.com +aoyu100.com +aoyuanlives.com +aoyunque.com +aozare-acemak.com +aozare-avernai.com +aozhanls.com +aozhougoufang.com +ap-china.com +ap1983.com +ap4r.com +ap88.com +ap8888.com +apaas-zone-test.com +apabi.com +apad.pro +apartments-bj.com +apass.com +apayun.com +apbiao.com +apcc2.com +apcdns.com +apcdns.net +apclc.com +apcso.com +apcta.com +apcups.org +apcupse.com +apdcdn.com +apdcdn.net +ape8.com +apearth.com +apecloud.ltd +apecn.com +apecome.com +apehorse.com +apeloa.com +apesk.com +apet.vip +apetdog.com +apetops.com +apevolo.com +apexhuntingau.com +apexmic.com +apexquartzstone.com +apextechnik.com +apeyun.com +apfeien.com +apgoview.com +aphidic.com +api-expo.com +api-forwards.com +api-m.com +api-vod-qcloud.com +api.anythinktech.com +api.crisp.chat +api.so +apiairasia.com +apiandroid.com +apicase.io +apicgate.com +apichina.com +apickup.com +apicloud.com +apifabric.net +apifox.com +apifoxmock.com +apigateway.info +apigwtencent.com +apilyzy.com +apim.work +apimkt.net +apipost.net +apiqecz.com +apira.org +apirc.org +apiseven.com +apispace.com +apistd.com +apitask.com +apitd.net +apitutu.com +apiunion.com +apiview.com +apizl.com +apizza.cc +apizza.net +apjingsi.com +apk3.com +apk4399.com +apk8.com +apkbus.com +apkdv.com +apkevery.com +apkhot.com +apkj.com +apkpackagesys.com +apkplug.com +apkrj.com +apkxz.com +apkyx.com +apkzu.com +aplaybox.com +aplnk.com +aplum-inc.com +aplum.com +aplus100.com +apluscap.com +aplusda.org +aplusunion.com +apmarry.com +apmbooth.com +apme-magnetics.com +apmengfan.com +apmgmedical.com +apmsecbg.com +apmvista.com +apnring.com +apodaenvi.com +apollo-platform.com +apollo-share.com +apollo.auto +apolloon-group.com +apollopump.com +apollotop.com +apous.com +apowo.com +apowogame.com +apoyl.com +app-analytics-services.com +app-measurement-cn.com +app-measurement.com +app-router.com +app.so +app001.com +app0772.com +app111.com +app111.org +app1116.app +app16688.com +app168.cc +app17.com +app178.com +app2006.com +app2pixel.com +app86.com +app887.com +appbi.com +appbk.com +appbocai.com +appbsl.com +appbw.com +appbz.info +appbza.com +appchina.com +appchizi.com +appcms.org +appcoo.com +appcool.com +appcpx.com +appcup.com +appdao.com +appdi.com +appdown.info +appdp.com +appeasou.com +appeeres.com +appfeng.com +appfenxiang.com +appfimo.com +appganhuo.com +appgenuine.com +appgrub.com +appia.vip +appicad.net +appicplay.com +appidfx.com +appifan.com +appinn.com +appkaifa.com +appkefu.com +applausefz.com +applinzi.com +applm.com +applogcdn.com +applogo.net +applon.net +applysquare.com +applysquare.net +appmifile.com +appmiu.com +appnode.com +appol.com +appollochina.com +appotronics.com +appqv.com +approvebook.com +apps-solayer.org +apps121.com +apps5.oingo.com +appscan.io +appsecurity.top +appsflower.com +appsflyer-cn.com +appshike.com +appshop.cc +appsimg.com +appsina.com +appso.com +appsolution.cc +apptao.com +apptaxi.net +apptrackerlink.com +appubang.com +appublisher.com +appurl.cc +appurl.me +appvipshop.com +appweb1.com +appweiyuan.com +appwill.com +appwuhan.com +appwuhan.net +appxzz.com +appyao.com +appying.com +appykt.com +appyouni.com +appzhigong.com +appzhonghua.com +aprche.net +apriltq.com +aprunchuang.com +aps.org +apsdai.com +apsfon.com +apsgo.com +apsoto.com +apspharm.com +aptchina.com +aptchip.com +aptdn.net +aptenon.com +apubond.com +apusic.com +apwuyou.com +aq2y.com +aqara.com +aqawzxeg.com +aqb.so +aqbxcdn9.com +aqbz.org +aqc100.com +aqcmgvxk.com +aqd-tv.com +aqdcdn.com +aqdesk.com +aqdlt.net +aqdstatic.com +aqee.net +aqfen.com +aqgygc.com +aqhospital.com +aqidb.org +aqigxaxv.com +aqioo.com +aqisite.com +aqjx.com +aqjz.net +aqlife.com +aqniu.com +aqpta.com +aqqcx.com +aqrose.com +aqrsblg.com +aqsc.org +aqsiqauto.com +aqtd.com +aqtowngas.com +aqtwpc.com +aqtwwx.net +aqtwwxemail.com +aqtxt.net +aqua-worth.com +aquabk.com +aquacity-tj.com +aquair-china.com +aquanliang.com +aquanutriera.com +aquanyou.com +aquapipetech.com +aquaterramail.com +aquathlondenice.com +aquaticowatch.com +aquayee.com +aquazhuhai.com +aqueck.com +aqumon.com +aqviwv.com +aqvx8mcr392mv7.com +aqxx.org +aqyqqy.com +aqyun.com +aqyzm.com +aqzpw.com +aqzt.com +aqzyzx.com +ar-max.com +ar0101.com +arabsquash.com +aragexpo.com +araldite2014.com +aranya.cc +arapp.online +aray1981.com +arayzou.com +arbays.com +arc-uds.com +arcas-da.com +arcdmi.com +archaeuscapital.com +archcollege.com +archcookie.com +archcy.com +archermind.com +archeros.com +archgo.com +archgrid.xyz +archi-motive.com +archiant.com +archina.com +archiname.com +archio.pro +archiposition.com +architbang.com +archrd.net +archsummit.com +arco.design +arcsoftai.com +arcstack.club +arcteryx-log.com +arctic007.com +arcticray.com +arctiler.com +arctime.org +ard-china.com +ardmon.com +ardsec.com +areader.com +arebz.com +arefly.com +arenabreakoutcn.com +arerberte.com +areweloongyet.com +arextecn.com +arglasses.work +argylehotels.com +arhoo.com +ariacraft.net +arielcosmetic.com +arin-elec.com +arinchina.com +arisastar.com +ark301.com +arkfeng.xyz +arkfwq.com +arkid.cc +arkid.org +arkntools.app +arkoo.com +arkrdigital.com +arkread.com +arksz.com +arliki.com +arlmy.me +arm9.net +arm9home.net +armaf.org +armbbs.net +armchina.com +armdesigner.com +armfly.com +armin.cc +armourtires.com +armracolostrumes.site +armsrock.com +armsword.com +armvm.com +armystar.com +arnstbearing.com +arocmag.com +aroseks.com +arowanahome.com +arp.cc +arpbox.com +arpun.com +arqinge.com +arrbid.com +arromaxinc.com +arrow-sh.com +arrow-tower.com +arrowceramic.com +arrowos.net +arrowwardrobe.com +ars-china.com +arswp.com +arswz.com +art-ba-ba.com +art-child.com +art-coding.com +art138.com +art238.com +artacode.com +artaime.com +artbookinchina.com +artcg.design +artcool.com +artcto.com +artdata.net +artebuy.com +artech-graphite.com +artemedhospital.com +arterytek.com +artexamcq.com +artfinace.com +artfoxlive.com +artgogo.com +arthals.ink +arthing.org +arthome163.com +arthubdam.com +arthurchiao.art +arthurpharma.com +articclothes.com +article.cool +artimg.net +artinchip.com +artisan-cloud.com +artisan-tek.com +artistry-club.com +artistrylab.net +artlianhe.com +artlinkart.com +artlnk.com +artmuseumonline.org +artnchina.com +artop-sh.com +artopgroup.com +artopia-group.com +artp.cc +artpangu.com +artpro.com +artpro.vip +artproglobal.com +artrade.com +artrobot.com +artron.net +artronartdata.com +artronimages.com +artrus.net +arts-nj.com +artsbuy.com +artshanghaifair.com +artsoa.com +artverse.work +artvisioncg.com +artwaker.com +artwe.com +artwun.com +artww.com +artxun.com +arvato-ocs.com +arvinhk.com +aryasec.com +as-doll.com +as-hitech.com +as-hls-ww-live.akamaized.net +as.mr +as16.com +as3f.com +as5.com +as66588.com +asa-asia.com +asasd.online +asatiles.com +asattitude.com +asbazainville.org +asc-events.org +asc-wines.com +ascelibrary.org +ascend-bio.com +ascendgene.com +ascendgz.com +ascenpower.com +ascentawits.com +aschina.org +aschip.com +aschtj.com +asciima.com +asczwa.com +asczxcefsv.com +asd.red +asd868.com +asdbfjoiug.com +asdeshan.com +asdf-bj.net +asdf010.com +asdlkjf.com +asdx.io +asean-china-center.org +aseann.com +aseanparts.com +asemi360.com +asemi99.net +asen-pharm.com +aseoc.com +aseoe.com +asf4asgfrxc.com +asfuwu.com +asfzl.net +asgezhi.com +ashan.org +ashgdf.com +ashidc.com +ashining.com +ashoucang.com +ashqgpxy.com +ashsilent.com +ashvsash.net +asi-midea.com +asia-cdn.com +asia-dns.com +asia-sh.com +asiabt.com +asiaci.com +asiacold.com +asiacool.com +asiacorp.net +asiadvb.net +asiae.com +asiaeap.com +asiaecs.com +asiafactor.com +asiafm.hk +asiafm.net +asiagreenfund.com +asiaidc.net +asiainfo-sec.com +asiainfo.com +asiainfo.org +asiainfodata.com +asiametallurgical.com +asianev.com +asianewsphoto.com +asianmetal.com +asiarobot.net +asiaseiki.com +asiasymbol.com +asiatelco.com +asiayun.com +asiet.net +asifadeaway.com +asilu.com +asim-emc.com +asimi8.com +asit.cc +asjnu.com +askbrisk.com +askci.com +askdd.org +askdiandian.com +askemq.com +asketchup.com +askk.cc +asklib.com +asklink.com +askpanda.cc +askququ.com +askraste.com +asktao.com +asktempo.com +asktug.com +askxt.org +asleyu.com +aslk2018.com +asls.space +asm.org +asm64.com +asmasm.com +asme.org +asmlc.com +asmr.gay +asmr.red +asnlab.com +asnlab.org +asnowsz.com +aso.ink +aso100.com +aso114.com +aso120.com +asoasm.com +asosde.com +asosoaiid.com +asp168.com +asp300.com +asp300.net +asp8php.com +aspbc.com +aspcms.com +aspiration-cn.com +aspirationtesting.com +aspire-info.com +aspirecn.com +aspiresun.com +aspnet.tech +aspqypmw.com +aspsky.net +aspx.cc +aspxhome.com +asq-qm.org +asqhr.com +asqql.com +asr-cn.com +asrmicro.com +assassinscreedcodenamejade.com +assemblydragon.com +asset-us-store.msi.com +asset-vendor-event.msi.com +asset.msi.com +assets-global.viveport.com +assrt.net +assyrb.com +astbbs.com +asterfusion.com +asteriavs.com +astestech.com +astfc.com +asthis.net +astipaint.com +astm.org +astra-biotech.com +astraintel.com +astral-vector.com +astro1.rastream.com +astroai-in.com +astroaio.com +astron.ac +astronergy.com +astropulsion.com +astrostanleystudio.com +asty664.com +asujp.com +asurada.zone +asus-sh.com +asussmart.com +asusw.net +asvm.net +aswetalk.net +asxrpcb.com +asxw.net +asxzcn.com +asyzonline.com +aszhuyuan.com +at-e.com +at0086.net +at188.com +at317.com +at58.com +at7790s887.com +at78.com +ata-edu.com +ata-test.net +atacchina.com +atanyu.com +atatech.org +atats.shop +atb.so +atbug.com +atc-sh.com +atcc360.com +atchip.com +atcloudbox.com +atcontainer.com +atcpu.com +aterminal.net +atfeng.com +atgbiotechnology.com +atguigu.com +atguigu.org +athaitao.com +athensgamulch.com +athmapp.com +athub.com +atianqi.com +atidesoft.com +atido.com +atimeli.com +ating.info +atjoqgi.com +atk-film.com +atk.pro +atk.store +atkgear.com +atlab.ai +atlaslovestravel.com +atlhb.com +atlmall.com +atlxm.com +atmbox.com +atmcu.com +atmlimited.com +atmob.com +atob100.com +atobo.com +atollbath.com +atom-hitech.com +atomgameteam.com +atomgit.com +atomgit.net +atomhike-en.com +atomic-art.com +atomlife.net +atomlock.com +atrenew.com +atri.ink +atriptech.com +atrustdns.com +ats6355866.com +atshph.com +atstudy.com +atsws.com +attacker.fit +attainsgroup.com +attendees.link +atticus.vip +attomotion.com +attop.com +attri.mobi +attribuly.com +atukjhesk.com +atum-tech.net +atuoyi.com +atwbz.com +atwtech.net +atyomi.com +atyun.com +atyun.net +atzjg.net +atzlinux.com +atzuche.com +au-daiwa.shop +aube-archi.com +aubemobile.com +aubor-ind.com +aubye.com +aucanlink.com +auchexpo.com +aucnln.com +audan2011.com +audatex.ch +audatex.com +audatex.net +audio-gd.com +audio-technica-hz.com +audio-y.com +audio160.com +audiobuy.cc +audiocn.com +audiocn.net +audiocn.org +audiofamily.net +audiotop.net +audiowell.com +audiowell.net +audiowellzq.com +audioxj.com +auditcn.com +audlabs.com +audtools.com +aufewb.com +augix.me +augsky.com +augurit.com +augustcn.com +auiou.com +aulacn.com +auldey.com +aumantruck.com +aunapi.com +auniontech.com +aunload.com +auoda.net +auok.run +auozzjs.lol +aupu.net +auqscfmk.com +auqsipfm.com +aura-el.com +auroapi.com +aurogon.com +auromcs.com +aurora-jy.com +aurora-oa.com +aurorauo.com +aurumdriver.vip +aus.cc +ausaview.com +ausbio.com +ausca-oils.com +ausdn.com +ausdream.org +aushinelyn.com +aushy.com +ausner.net +ausnutria.com +ausny.com +ausperbio.com +auspous.com +aussino.net +austargroup.com +austarstudy.com +australiaxy.com +ausunpharm.com +authbus.com +authing-inc.co +authing.co +authing.com +auto-ccpit.org +auto-changchun.com +auto-ekontrol.com +auto-expos.com +auto-learning.com +auto-made.com +auto-mooc.com +auto-purify.com +auto-testing.net +auto-union.net +auto-wo.com +auto1768.com +auto18.com +auto318.com +auto328.com +auto510.com +auto6s.com +autoahk.com +autoai.com +autobaidu.com +autobaojun.com +autobit.xyz +autobizreview.com +autocamel.com +autochinashow.org +autochinazh.com +autochips.com +autochongqing.com +autodl.com +autodmp.com +autodnsv1.com +autodnsv1.net +autodwg.com +autoecosystems.com +autoengine.com +autoesd.com +autofull.net +autogslb.com +autohao.com +autohenan.com +autoho.com +autohome.com +autohome.tel +autohr.org +autohunan.com +autoij.com +autoitx.com +autojiaoyi.com +autojingji.com +autojs.org +automall365.com +automsen.com +autonavi.com +autoparts-yoto.com +autopartsdk.com +autopeitao.com +autophagy.net +autoqingdao.com +autosey.com +autoshafa.com +autoshanghai.org +autosmt.net +autostreets.com +autosup.com +autothinker.net +autounicom.com +autovideo.club +autovolke.com +autowelds.com +autowise.ai +autoz.net +autozi.com +autumndesires.com +auwincmc.com +aux-home.com +auxgroup.com +auy07161km.com +auy07230km.com +auyou.com +av-ic.com +av199.com +av2.me +av269.com +av380.net +av77.org +avadairy.com +avalon233.com +avanpa.com +avanzacorp.com +avaryholding.com +avatamveda.com +avatarmind.com +avatarmobi.com +avatr.com +avaya.hk +avc-mr.com +avc-ott.com +avdgw.com +avec6ua79dc6.com +avemaria.fun +aves.art +avfline.com +avgh5.com +avgnati.com +avgnatii.com +avgroft.com +aviationsnip.com +avic-acs.com +avic-apc.com +avic.com +avichina.com +avicnews.com +avicsec.com +avicsgt.com +avicui.com +avilive.com +avinex.com +avischina.com +avivaqueen.com +avl-hitec.com +avlinsight.com +avlsec.com +avlyun.com +avlyun.net +avlyun.org +avnpc.com +avoscloud.com +avp76.com +avp76.net +avpic.xyz +avptec.com +avq360.com +avrvi.com +avstar4.com +avt-cn.com +avtechcn.com +avtt830.com +avuejs.com +aw-ol.com +aw.cc +awaker.net +awaliwa.com +awardsequence.com +awc618.com +awcloud.com +awcn.cc +awehunt.com +awemeughun.com +awemeuglang.com +awemeugsoul.com +awemeugwave.com +aweray.com +awesome-hd.me +awfggc.com +awhouse.art +awi-intl.com +awinic.com +awmote.com +aword.net +awotuan.com +awoyun.com +awsamazonlab.com +awsdns-cn-00.com +awsdns-cn-00.net +awsdns-cn-01.biz +awsdns-cn-01.net +awsdns-cn-02.biz +awsdns-cn-02.net +awsdns-cn-03.biz +awsdns-cn-04.net +awsdns-cn-05.biz +awsdns-cn-05.net +awsdns-cn-06.com +awsdns-cn-06.net +awsdns-cn-07.biz +awsdns-cn-07.com +awsdns-cn-07.net +awsdns-cn-09.biz +awsdns-cn-09.com +awsdns-cn-09.net +awsdns-cn-10.com +awsdns-cn-11.biz +awsdns-cn-11.com +awsdns-cn-12.biz +awsdns-cn-12.net +awsdns-cn-14.biz +awsdns-cn-14.com +awsdns-cn-15.net +awsdns-cn-16.biz +awsdns-cn-16.net +awsdns-cn-17.biz +awsdns-cn-17.com +awsdns-cn-17.net +awsdns-cn-18.biz +awsdns-cn-18.net +awsdns-cn-19.biz +awsdns-cn-19.net +awsdns-cn-20.biz +awsdns-cn-20.com +awsdns-cn-20.net +awsdns-cn-21.biz +awsdns-cn-21.net +awsdns-cn-22.com +awsdns-cn-22.net +awsdns-cn-23.com +awsdns-cn-23.net +awsdns-cn-24.biz +awsdns-cn-24.com +awsdns-cn-24.net +awsdns-cn-25.com +awsdns-cn-25.net +awsdns-cn-26.com +awsdns-cn-27.biz +awsdns-cn-27.com +awsdns-cn-28.biz +awsdns-cn-28.net +awsdns-cn-29.biz +awsdns-cn-31.net +awsdns-cn-33.biz +awsdns-cn-33.net +awsdns-cn-34.com +awsdns-cn-34.net +awsdns-cn-35.biz +awsdns-cn-35.net +awsdns-cn-36.biz +awsdns-cn-36.com +awsdns-cn-36.net +awsdns-cn-37.biz +awsdns-cn-37.com +awsdns-cn-37.net +awsdns-cn-38.net +awsdns-cn-39.biz +awsdns-cn-39.com +awsdns-cn-39.net +awsdns-cn-40.biz +awsdns-cn-40.com +awsdns-cn-40.net +awsdns-cn-41.biz +awsdns-cn-41.com +awsdns-cn-41.net +awsdns-cn-42.biz +awsdns-cn-42.com +awsdns-cn-43.biz +awsdns-cn-44.biz +awsdns-cn-44.com +awsdns-cn-44.net +awsdns-cn-45.biz +awsdns-cn-45.com +awsdns-cn-45.net +awsdns-cn-46.biz +awsdns-cn-46.com +awsdns-cn-46.net +awsdns-cn-47.biz +awsdns-cn-47.com +awsdns-cn-47.net +awsdns-cn-48.biz +awsdns-cn-48.com +awsdns-cn-48.net +awsdns-cn-49.biz +awsdns-cn-50.biz +awsdns-cn-50.net +awsdns-cn-51.biz +awsdns-cn-51.com +awsdns-cn-52.biz +awsdns-cn-52.com +awsdns-cn-52.net +awsdns-cn-53.com +awsdns-cn-54.biz +awsdns-cn-54.net +awsdns-cn-55.biz +awsdns-cn-55.com +awsdns-cn-55.net +awsdns-cn-56.biz +awsdns-cn-56.net +awsdns-cn-57.com +awsdns-cn-58.biz +awsdns-cn-58.com +awsdns-cn-58.net +awsdns-cn-59.biz +awsdns-cn-59.net +awsdns-cn-60.biz +awsdns-cn-60.com +awsdns-cn-60.net +awsdns-cn-61.biz +awsdns-cn-62.biz +awsdns-cn-62.com +awsdns-cn-62.net +awsdns-cn-63.biz +awsdns-cn-63.com +awsdns-cn-63.net +awsdns-vip.com +awsok.com +awsonamazon.com +awspaas.com +awspony.com +awstar.net +awtmt.com +awuming.com +awx1.com +awyerwu.com +awyx.xyz +ax196.com +ax2nc4.ren +ax8dm212f0.com +axa123.com +axatp.com +axbsec.com +axbur.com +axcf.com +axentbath.com +axera-tech.com +axfys.com +axhimalayancc.com +axhjfobr.shop +axhub.im +axiang.com +axiaoxin.com +axic6906.com +axilone-shunhua.com +axinsur.com +axisfluid.com +axjm-ex.com +axjsw.com +axjx.com +axmro.com +axmw.com +axnsc.com +axoij.com +axq66.com +axqqq.com +axqswm.net +axs8.com +axshuyuan.com +axuer.com +axuexiw.com +axunyou.com +axure.us +axureshop.com +axureux.com +axxsw.org +axybio.com +axyxt.com +axzchou.com +ay-china.com +ay-health.com +ay001.com +ay001.net +ay2fy.com +ay57.com +ay5y.com +ay99.net +ayalm.com +ayatuan.com +aybwg.org +aycav.com +aycgu.com +aychfy.com +ayctgy.com +aydaojia.com +aye.ink +ayeucefm.com +ayfdc.com +ayfy.com +ayfyfy.com +ayguge.com +ayhmjy.com +ayhuowan.com +ayhyxg.com +ayi800.com +ayibang.com +ayidada.com +ayijx.com +ayilaile.com +ayilian.com +ayjewelry.com +ayjs.net +aykj.net +ayklgas.com +aymym.com +aynchem.com +ayoushu.com +ayqy.net +ayrbs.com +ayrc.cc +ayrc.net +ayrmt.com +ayrq.com +aysbxxh.com +ayshq.com +aysjhod.xyz +aysjyjjh.com +ayudasalud.com +ayump.com +ayunlian.com +ayuren.com +ayuyun.com +ayw.ink +ayxz.com +ayzzxx.com +az009.com +azad.asia +azbingxin.com +azbq.org +azchcdna.com +azchcdnb.com +azchcdnc.com +azchcdnd.com +azchcdne.com +azchcdnf.com +azchcdng.com +azchcdnh.com +azchcdni.com +azchcdnj.com +azchcdnk.com +azchcdnl.com +azchcdnm.com +azchcdnn.com +azchcdno.com +azchcdnp.com +azchcdnq.com +azchcdnr.com +azchcdns.com +azetac.com +azf010.com +azhimalayanvh.com +azhituo.com +azhubaby.com +azjy88.com +azmcode.com +azmtszpk.com +azonete.com +azooo.com +azoyacdn.com +azoyagroup.com +azp315.com +azpdl.com +azpdl.net +azt365.com +azuiblc.com +azure-wave.com +azure.cc +azureflying.com +azuremigrate.download.prss.microsoft.com +azuremigratetest.download.prss.microsoft.com +azurestackhub.download.prss.microsoft.com +azurestackhubuat.download.prss.microsoft.com +azuretouch.net +azurew.com +azureyun.com +azxdiy.com +azy288.com +azycjd.com +azyfy.com +azz.net +azzdm.com +b-chem.com +b-cro.com +b-eurochina.com +b-fairy.com +b-k-automation.com +b-raymedia.com +b.biz +b01.net +b02f0d7f3745ba7c.com +b041e427810281.beer +b07cceaf011012.beer +b08.com +b082392de1024.beer +b13075593271.com +b13bc577fd.run +b18e55f8a1010.beer +b19a352d2336941a.com +b1bj.com +b1cjcgy8s2.com +b1n.net +b1qg.com +b214bd8861009.beer +b2216419b1013.beer +b22fb6d6d1015.beer +b23.tv +b230756fa1114.beer +b230ed9d61010.beer +b262a49751023.beer +b27ceaa1053.skin +b287f400810291.beer +b29f45a5b10271.beer +b29gj.com +b2b-builder.com +b2b.biz +b2b123.com +b2b168.com +b2b168.net +b2b168.org +b2b3.com +b2b6.com +b2b818.com +b2bdq.com +b2bgo.com +b2bic.com +b2bkk.com +b2bname.com +b2bvip.com +b2bvip.net +b2byao.com +b2c-28loops.com +b2c.biz +b2cedu.com +b2clouds.com +b2jiaxiao.com +b2q.com +b2star.com +b3198a37310281.beer +b3727743007e8b15.com +b384f2fff3e6d159.com +b3b97f52c55246d7.com +b3inside.com +b3log.org +b3logfile.com +b40e80b301022.beer +b44fd0fd51014.beer +b4ca25f717d58cac.com +b5.com +b510qh.shop +b5232b4da6e285b2.com +b53358ed31009.beer +b555b.com +b55weik1d4.com +b5669d7a0a.vip +b5a3f14042830b91.com +b5b6.com +b5b6308ab4859018.com +b5csgo.plus +b5esports.me +b5m.com +b5nngc6zmt.com +b6098130711042.beer +b612.me +b612.net +b612kaji.com +b643bce461009.beer +b6522.com +b670bffdf1021.beer +b68f0a844eec7fff.com +b6a531b371011.beer +b6cc0921b1024.beer +b6r.com +b71ea195f05f569c.com +b71ef13941015.beer +b75c5da009ac3871.com +b76ad11181024.beer +b7av.com +b7e314d4810241.beer +b7eeeb26810241.beer +b812824ed173a8c0.com +b83d11444463a621.com +b883481331023.beer +b8e4d120a10271.beer +b8kk.com +b8yx.com +b9127b1b510292.beer +b93a0ccdfcd1d26c.com +b93df4bea4666064.com +b963aae3c10272.beer +b9a3e87f01023.beer +b9ad.com +b9bdc7d62dfb0e5e.com +b9noqayb1s.work +ba-li.com +ba08e2f96f675d22.com +ba1400.com +ba20db47708bc51f.com +ba7jcm.live +baacloud32.com +baae91ac810311.beer +baalchina.net +baaniarts.com +baba-blog.com +baba12.com +bababian.com +bababus.com +babady.com +babai.cc +babaicai.com +babaike.com +babaimi.com +baballs.com +babao.com +babapi.com +babawar.com +babaxiong.com +babedy.com +babeijiu.com +babeword.com +babifood.com +babiguoguo.com +babolchina.com +baboshan.com +babsoft.net +babuxiang2005.com +baby-bus.com +baby-joy.com +baby577.com +baby611.com +baby7blog.com +baby868.com +babybus.com +babybus.org +babycdn.com +babymoro.com +babymozart.cc +babyqiming.com +babytree.com +babytreeimg.com +bacaizi.com +bacaola.com +bacaoo.com +bacaosh.com +bacic5i5j.com +backaudio.com +backdata.net +backendman.com +backmany.com +backoffice-cms.com +backupdesktopcloud.com +bacninhlocalguide.com +bacocis.com +bacts.com +bacyfzjt.com +badambiz.com +badazhou.com +bademeiji.com +badmintoncn.com +badmintone.com +badong.net +badou.com +badouxueyuan.com +badu.com +badudns.cc +baduziyuan.com +badwe.com +baeapps.com +baertt.com +baetyl.tech +baf566dfd40e3413.com +bafangjuhe.com +bafangwy.com +bag198.com +bagb2b.com +bagevent.com +bags163.com +bagsnet.com +bagstory.net +bagtree.com +baguichong.com +baguilingyun.com +bagxs.com +bahealpharma.com +bahecloud.com +bahens.com +bahepark.com +bai.com +baian-group.com +baiao.com +baibaipei.com +baibaoyun.com +baibm.com +baibo8.com +baibomedia.com +baibu.com +baic-group.com +baicai.asia +baicai.com +baicaijie09.com +baicaio.com +baicaiyouxuan.com +baicaolu.net +baicaosoft.com +baiccapital.com +baiccl.com +baicdnx.com +baicells.com +baicfc.com +baicheng.com +baichengtax.com +baichengyuehua.com +baichuan-ai.com +baichuan.tech +baichuanhd.com +baichuanhudong.com +baichuannet.vip +baichuanweb.com +baicizhan.com +baicizhan.org +baiclouds.com +baicmotor.com +baicmotorsales.com +baicrx.com +baicuoa.com +baidajob.com +baidao.com +baideled.com +baidenafu.com +baidesz.com +baidevalve.com +baideye.com +baidiapp.com +baidinet.com +baidu-bank.com +baidu-cdn.com +baidu-cdn.net +baidu-int.com +baidu-itm.com +baidu-mgame.com +baidu-nj.com +baidu-tech.com +baidu-wenxue.com +baidu.cc +baidu.com +baidu.com.hk +baidu.hk +baidu.mobi +baidu120.cc +baidu123.com +baiduads.com +baiduapp.com +baidubaidubaidu.net +baidubce.com +baidubcr.com +baidubos.com +baiducloudapi.com +baiducontent.com +baidudaquan.com +baidudw.com +baidufe.com +baidufree.com +baiduhtml5.com +baiduhui.com +baidujinshu.com +baidulook.com +baiduor.com +baidupan.com +baidupcs.com +baidupcs.net +baidupeixun.com +baidusmartapps.com +baidusx.cc +baidusx.com +baidutab.com +baidutieba.com +baidutt.com +baiduux.com +baiduwaf.com +baiduwebgame.com +baiduwpan.com +baiduxiaodai.com +baiduxiaoshuo.com +baiduyangguang.org +baiduyun.com +baiduyun.wiki +baiduyuncdn.com +baiduyuncdn.net +baiduyundns.com +baiduyundns.net +baiduyunsousou.com +baiduyunwaf.com +baiduzjn.com +baieryk.com +baifae.com +baifang.in +baifangdianqi.com +baifangzh.com +baifeiyue.com +baifubao.com +baigebao.com +baigebg.com +baigehuidi.com +baigeseo.com +baigo.net +baigolf.com +baigongbao.com +baigougou.com +baigouwanggong.com +baiguitang.com +baihangbao.com +baihangdai.com +baihaocha.com +baihe.com +baiheee.com +baihelove.com +baihemedical.com +baihemob.com +baihezi.com +baihong.com +baihongsoft.com +baihuayan.com +baihui.com +baihui.live +baihui168.com +baihuibio.com +baihuillq.com +baihuiyaoye.com +baiila.com +baiinfo.com +baijia.com +baijiacloud.com +baijiahulian.com +baijiantest.com +baijiasheping.com +baijiaxingwang.com +baijiayun.com +baijiayuncdn.com +baijiegroup.com +baijiexiu.com +baijii.com +baijincdn.com +baijingapp.com +baijiudl.com +baijob.com +baijunjz.com +baijunyao.com +baijus.net +baijuyi.com +baikaigroup.com +baikalasia.com +baikalminer.com +baikalyq.com +baikangyun.com +baike.com +baikecs.com +baiked.com +baikehuanjing.com +baikemy.com +baikemy.net +baikeshiji.com +baikeshijie.com +baikevod.com +baikewenda.com +baikexueshe.com +baikezh.com +bailb.com +bailepin.com +bailiaijia.com +bailiangroup.com +bailiann.com +bailiban.com +bailiguangmang.com +bailing.online +bailing88.com +bailingdanci.com +bailingjk.net +bailinsi.net +bailitech.com +bailitools.com +bailitop.com +bailizw.com +bailucloud.com +bailvanquan.xyz +baima.com +baimao-expo.com +baimao.com +baimaohui.net +baimatech.com +baimda.com +baimei.com +baimeidashu.com +baimiao.tech +baimiaoapp.com +baimin.com +baina.com +bainaben.com +bainaruibusiness.com +baineng.cc +bainmedical.net +bainus.com +baiousen.com +baiozhuntuixing.com +baipin.pw +baipu365.com +baiqian.com +baiqiangart.com +baiqiangyl.com +baiqianxin.com +baiqiaogame.com +baiqishi.com +baiqiso.com +baiqiyaoye.com +baiquefahuasi.com +bairenzbg.org +bairoe.com +baironginc.com +bairuitech.com +baisainuo.com +baise.cc +baise123.vip +baise1314.com +baisecn.com +baiselife.com +baiselyw.com +baiseshiyu.com +baiseylj.com +baiseyun.com +baisha.com +baishan-cloud.com +baishan-cloud.net +baishan-gateway.com +baishan.com +baishancdnx.com +baishancdnx.net +baishancdnx.top +baishancloud.com +baishancloud.org +baishandnsx.com +baishandnsx.net +baishandnsx.top +baishangeek.com +baishanyun.com +baishicha.com +baishimeipai.com +baishinetwork.com +baishishuju.com +baishixi.xyz +baishuku.la +baishulou.net +baishunet.com +baishuyun.com +baishuzhai.cc +baishuzhai.com +baisihan.com +baisiterzh.com +baisiweiting.com +baisu.cc +baisuizhixiang.com +baitahe.net +baitaihuge.com +baitanheichang.com +baitdu.com +baite666.com +baithu.com +baitianinfo.com +baitiao.com +baitomould.com +baitongplastics.com +baitongwang.com +baitu.com +baituibao.com +baiu.com +baiven.com +baiwandz.com +baiwang.com +baiwangjs.com +baiwen100.com +baiwenbao.com +baiwujt.com +baiwulin.com +baiwushi168.com +baiwutong.com +baixiangfood.com +baixiangnews.com +baixiaosheng.net +baixiaoxs.com +baixihuang.com +baixing.com +baixing.net +baixingjob.com +baixingyllh.com +baixiong.info +baixiu.org +baiyang.com +baiyangseo.com +baiyaohy.com +baiycap.net +baiye5.com +baiyewang.com +baiyi.shop +baiyi181.com +baiyiba.com +baiyikc.com +baiying.com +baiyinggd.com +baiyintouzi.com +baiyishequ.com +baiyizg.com +baiyjk.com +baiyou100.com +baiyu.tech +baiyujingfeng.com +baiyumedia.com +baiyun-hotel.com +baiyunairport.com +baiyunholding.com +baiyunhuojia.com +baiyunmh.com +baiyunpump.com +baiyunxitong.com +baiyuyu.com +baiyyy.com +baizengtech.com +baizhan.net +baizhanke.com +baizhanlive.com +baizhouniao.com +baizlink.com +bajasaechina.com +bajie1.com +bajiebofang.com +bajiexinxi.net +bajintech.com +baka.im +baka.plus +bakaxl.com +bakbitionb.com +bakclass.com +bakerdavid.shop +bakingerp.com +baklib.com +bakpower.com +bakshifen.com +bakstotre.com +bala.cc +balance-net.com +balancer-sh.com +baldc.com +baldor-tech.com +baletu.com +balift.com +balihe.com +balijieji.com +balimtoy.com +balingtxt.com +ballgametime.com +ballpure.com +balltv.cc +baltamatica.com +baltamatica.net +bama-supercon.com +bamaiwo.com +bamalifelong.com +bamaol.cc +bamaol.com +bamashenspring.com +bamatea.com +bamaying.com +bamboofactorychina.com +bambooolab.com +bambu-lab.com +bambulab.com +bamengame.com +bamensq.com +bamenzhushou.com +bamuwu.com +bamuyu.com +bananafather.com +bananain.com +bananalighter.com +bananau.com +bananaumbrella.com +bananaunder.com +banban.work +banbang.com +banbanjia8.com +banbao22.com +banbijiang.com +bancai.com +bancheng08.fun +banchengyun.com +banchuan.net +banciyuan.me +bandainamcoshanghai.com +bandao.com +bandaoapp.com +bandari.net +bandayun.com +bandcevent.com +bandcoder.com +bandeyu.com +bandianli.com +bandoristation.com +bandvr.com +banfubbs.com +bangandi.com +bangbang.com +bangbang93.com +bangbanghuoyun.com +bangbendi.com +bangboss.com +bangbuy.com +bangcaiwu.com +bangcheng0769.com +bangchengchem.com +bangcle.com +bangcn.com +bangdao-tech.com +banggeen.com +banggo.com +banghaiwai.com +bangivf.com +bangjiantong.com +bangjigroup.com +bangju.net +bangkaixin.com +bangkao.com +bangkaow.com +bangkebao.com +bangkehui.com +banglianai.com +bangmai.com +bangninji.com +bangnixia.com +bangnizexiao.com +bangongtuku.com +bangongyi.com +bangongziyuan.com +bangqi66.com +bangqike.com +bangqu.com +bangrong.com +bangsee.com +bangshouwang.com +bangtaixcl.com +bangthink.com +bangtukj.com +banguanjiabc.com +bangwo8.com +bangwo8.net +bangwoting.com +bangxuetang.com +bangyike.com +bangzechem.com +bangzhuta.com +banji.org +banji001.com +banjia1680.com +banjiajia.com +banjiang.cc +banjiekuaiji.com +banjing.com +banjixiaoguanjia.com +banjuanshu.com +banjunxingkeji.com +bank-139.com +bank-of-china.com +bank-of-tianjin.com +bankalliance.net +bankcomm.com +bankcomm.com.au +bankcomm.com.mo +bankcomm.com.tw +bankcz.com +bankgz.com +bankhr.com +bankksw.com +banklilv.com +bankofbbg.com +bankofchangsha.com +bankofchina.com +bankofdl.com +bankofshanghai.com +bankofshanghai.net +bankofsv.com +bankoftianjin.com +bankoftieling.com +bankofvolc.com +bankofyk.com +banksteel.com +bankyellowriver.com +banlikanban.com +banma.com +banmaaike.com +banmacdn.com +banmadayuwen.com +banmaedu.com +banmaerp.com +banmagushi.com +banmajsq.com +banmajz.net +banmasiwei.com +banmasrf.com +banmasusuan.com +banmayingyu.com +banmi.mobi +bannei.com +banner668.com.hk +banqumusic.com +bansha.com +banshangong.com +banshier.com +bantangapp.com +bantangbuy.com +bantouyan.com +banwagong.men +banwagongcn.com +banwagongzw.com +banwo365.com +banwoo.net +banwoyo.net +banwugongsi.com +banxiaomazaojiao.com +banxiayue.com +banye.tech +banyiyi.com +banyuetan.org +banyuetanapp.com +banyuetanedu.com +banyuetanxcx.com +banyunjuhe.com +banzhe.xyz +banzhuti.com +banzou.name +banzouzhizuo.com +bao-fang.com +bao-hulu.com +bao12333.com +bao265.com +bao315.com +bao369.com +baoanchina.com +baob123.com +baobanli.com +baobao001.com +baobao88.com +baobaobang.com +baobaoqiming.site +baobaoshu.com +baobei360.com +baobeicang.com +baobeigezi.com +baobeihr.com +baobeihuijia.com +baobeio.com +baobeita.com +baobeituan.com +baobeiy.com +baobianli.net +baocdn.com +baochaojianghu.com +baochunyiran.com +baocps.com +baocuicoin.com +baodan100.com +baodan360.com +baodaohealth.com +baodaren.net +baodery.com +baodian.com +baodigs.com +baodu.com +baoduys.com +baofeng.com +baofeng.la +baofeng.mobi +baofeng.net +baofeng365.com +baofengtv.com +baofon.com +baofoo.com +baofoo.net +baofu.art +baofu.com +baofu.info +baofull.com +baofumuye.com +baogang.info +baogao.com +baogao.store +baogaobox.com +baogaoku.com +baogaoting.com +baoge.net +baogebei.com +baoguangtai.com +baoguogroup.com +baohanghr.com +baohebao.com +baohongbao.net +baohua-pec.com +baohuagroup.com +baohuatravel.com +baohuaxia.com +baohuiming.net +baoimg.net +baoinsurance.com +baoji-marathon.com +baoji3g.com +baojia.com +baojiagaiye.com +baojian.com +baojiazhijia.com +baojiegy.com +baojijob.com +baojinews.com +baojinling.com +baojule.com +baojun.net +baojunev.com +baokan.tv +baokang.com +baokanhuicui.com +baokao.net +baokaodaxue.com +baoke-cn.com +baoku.com +baokuaishou.com +baokuandi.com +baokutreasury.com +baolansz.com +baoliannet.com +baolijuyuan.org +baolizx.com +baolong.biz +baolong.com +baoltx.com +baolu.store +baomaxs.com +baomei.tv +baomi.com +baomi365.com +baomidou.com +baomihua.com +baoming.com +baoming.work +baomingge.com +baomitu.com +baoneng.com +baoqin.com +baoqingvip.com +baor.work +baoruan.com +baoruisi.com +baoshe.net +baoshe01.com +baoshengcable.com +baoshengele.com +baoshenggroup.com +baoshuanglong.com +baoshuiguoji.com +baoshuiguoji.net +baoshuo.ren +baoshuo.xyz +baosight.com +baosiwushidhex.work +baosteel.com +baosteel.info +baosteelpackaging.com +baostock.com +baotadns.com +baotaiclad.com +baotaikonggu.com +baotang5.com +baotime.com +baotoo.com +baotoulawyer.com +baotounews.com +baotoushizx.com +baotuba.com +baotuo.cc +baowu.com +baowuenergy.com +baowugroup.com +baoxian.com +baoxian72.com +baoxianhai.com +baoxianjie.net +baoxianqi.com +baoxianshichang.com +baoxiaobar.com +baoxiaohe.com +baoxiaoke.com +baoxinchewang.com +baoxingmuye.com +baoxinleasing.com +baoxins.com +baoxiu.com +baoxiu.net +baoxuexi.com +baoxuexiedu.com +baoyagroup.com +baoyang1.com +baoyang888.com +baoyegroup.com +baoyehb.com +baoyejs.com +baoying.com +baoyizn.com +baoyt.com +baoyuanchem.com +baoyueai.com +baoyuekj.com +baoyuncm.com +baoyung.com +baoyuntong.com +baoz.net +baozang.com +baozengzhang.com +baozhenart.com +baozheng.cc +baozhenlu.com +baozhilin.com +baozhuang.biz +baozhuangren.com +baozi.fun +baozi178.com +baozijishu.com +baozipu.com +baozou.com +baozoudi.com +baozoumanhua.com +baozugongkeji.com +baozun.com +baozy.com +bapengpc.com +baping.com +baqi28.com +baqiu.com +barhuta.com +barjiang.com +barlosi.com +barman.vip +baron-bj.com +baronyhotels.com +baronzhang.com +barretlee.com +bartistar.online +bartymedical.com +basechem.org +basecity.com +based-edu.com +baseopendev.com +basequan.com +basestonedata.com +bashan.com +bashigao.com +bashuhuapai.com +bashuku.com +basiccat.org +basicfinder.com +basischina.com +bastcn.com +basunlighting.com +bat-sz.com +batchat.com +batengtiyu1.com +batian.net +batman.plus +batmanit.com +batmsg.com +batplay.com +battery-cert.com +battery-expo.com +battery8.com +batterydir.com +batterykey.com +battle-fsd.com +battlecare.net +battleofballs.com +batupian.net +baufortune.com +bauschlombchina.com +bawagon.com +bawanglongbengye.com +bawjxt.net +bawu.net +baxiami.com +baxichina.com +baxisuye.com +baydn.com +baye.tech +bayee.cc +bayinh.com +baykee.net +baynoe.com +bayucar.com +bayuche.com +bayuegua.com +bayueju.com +bayunhome.com +bayuxuexiao.net +bayzedhealthcare.com +bazaarjewelrychina.com +bazai.com +bazhan.com +bazhepu.com +bazhong.com +bazhongol.com +bazhua.me +bazhuay.com +bazhuayu.cc +bazhuayu.com +bazhuayukeji.com +bazi.cloud +bazi.run +bazi.xin +bazi5.com +baziguwen.com +bazizeri.com +bb-game.com +bb-hy.com +bb-pco.com +bb06.com +bb361a58c1015.beer +bb39977653.com +bb3a14ca57af4d81.com +bb52e27c75560d3f.com +bb730b04b6cc8c57.com +bbanp.com +bbaod.com +bbaqw.com +bbb1415.com +bbbaaa.com +bbbao.com +bbbb.com +bbbcdns.com +bbbmq.com +bbbms.com +bbbtgo.com +bbc54c1281125042.com +bbcagroup.com +bbcayy.com +bbchin.com +bbctop.cc +bbctop.com +bbdj.com +bbdservice.com +bbdup.com +bbecpsc.com +bbef-tech.com +bbef.com +bbeshop.com +bbez.com +bbfkjkh.com +bbfoxgame.com +bbfstore.com +bbfytsn.com +bbgdex.com +bbgsite.com +bbguangcai.com +bbhou.com +bbicn.com +bbioo.com +bbjgr.com +bbk.com +bbk000.com +bbkantu.com +bbkys.com +bblcdn.com +bblmw.com +bblops.com +bbmuwwxyk.com +bbmy.net +bbobo.com +bbonfire.com +bbosu.com +bbpph.com +bbpu.com +bbqcdn.com +bbqe.com +bbqk.com +bbqk.net +bbqming.com +bbqseo.com +bbqwhg.com +bbrmedia.com +bbrtv.com +bbs-alsontech.com +bbs0415.com +bbs0551.com +bbs1x.net +bbscloud.com +bbsds.com +bbsls.net +bbsmc.net +bbsnet.com +bbstv.clouducs.com +bbsufida.com +bbsut.com +bbsxp.com +bbszjj.com +bbtang.info +bbtcaster.com +bbteapress.com +bbtengfeizaixian.com +bbthy.net +bbtkid.com +bbtpress.com +bbtwatch.com +bbugifts.com +bbunion.com +bbw-portnet.com +bbwcec.com +bbwcq.com +bbwfish.com +bbwgw.com +bbwhy.com +bbwict.com +bbwoils.com +bbwotc.com +bbwport.com +bbwport.net +bbwrc.com +bbwse.com +bbwunisco.com +bbxarq.com +bbxinwen.com +bbxinwen.net +bbxstjx.com +bbydsol.com +bbzhh.com +bbzhi.com +bbzhsw.com +bbzxky.fun +bc150.com +bc4785bd211012.beer +bc5539.com +bc754c518ef6127a.com +bc966.com +bcaacademy.org +bcactc.com +bcb5.com +bcbjjy.com +bcbksbx.com +bcbpm.com +bcbvi.com +bccastle.com +bccn.net +bccnsoft.com +bccoder.com +bccv.com +bcdaren.com +bcdnx.com +bcdy.net +bce-cdn.com +bce-cdn.net +bce0619341023.beer +bceapp.com +bcebos.com +bcedns.com +bcedns.net +bcedocument.com +bcegc.com +bcehost.com +bcehosts.com +bceidaas.com +bceimg.com +bcelive.com +bcevod.com +bcewaf.com +bcf1ef2511022.beer +bcfmglobal.com +bcfy188.com +bcgf.cc +bcghotel.com +bchdemo.site +bchlkj.com +bchrt.com +bcisz.org +bcitb.com +bcjkcloud.com +bcjp.net +bclcraft.com +bcmcdn.com +bcmonomial.xyz +bcn.cc +bcpcn.com +bcpgame.com +bcpharma.com +bcplab.com +bcpmdata.com +bcreat.com +bcrjl.com +bcrmtzx.com +bcryo.com +bcsfoong.com +bcshipgo.com +bcsloong.com +bcsytv.com +bctdtx.com +bctest.com +bctts.com +bcty365.com +bcvbw.com +bcvdmovie.com +bcwangluo.net +bcxgame.com +bcxgps.com +bcxww.com +bcy.net +bcyimg.com +bczcdn.com +bczyyy.com +bd-caict.com +bd-gti.com +bd-union.com +bd001.net +bd0afb0887.xin +bd3be95d910301.beer +bd682bc7d22322eb.com +bd689.com +bd7kzs.site +bdactivity.com +bdaenviro.com +bdajob.com +bdall.com +bdapark.com +bdatu.com +bdbae.com +bdc-rays.com +bdcb.cc +bdcgz.com +bdchangtujs.com +bdchina.com +bdcloudapi.com +bdclouddns.com +bdcn-media.com +bddhospital.com +bddlm.com +bde5fc098b5291bf.com +bdebid.com +bdeceimg.com +bdegnine.com +bdf2.com +bdfczx.com +bdfmj.com +bdfmkj.com +bdfyy999.com +bdfzcd.net +bdfzkyy.com +bdg-brain.com +bdgamelive.com +bdgp.cc +bdgqx.com +bdgslb.com +bdgw.cc +bdhdtv.com +bdhengding.com +bdhhg.com +bdhhome.com +bdhulanwang.com +bdimg.com +bdinfo.net +bdispatch.com +bdispatch.net +bdjz.vip +bdkyr.com +bdlcqjw.com +bdmozon.com +bdmyandex.com +bdns-api-test.net +bdns-boe.com +bdns-boe.net +bdns-gtm-01.net +bdns-gtm-pressure.com +bdns-restore.net +bdns-test.com +bdns-test.net +bdo-dahua.com +bdpan.com +bdpnt.com +bdppe.net +bdqn027.com +bdqn666.com +bdqnwh.com +bds-cn.com +bds666.com +bdsagslb.com +bdsagslbtest.com +bdsana.com +bdsd.design +bdsgx.com +bdshengce.com +bdshuang.com +bdsimg.com +bdsj.net +bdspacetime.com +bdstar.com +bdstatic.cc +bdstatic.com +bdsytime.com +bdszh.vip +bdtianchang.com +bdtic.com +bdtjrcv.com +bdtm.net +bdtsc.com +bduapp.com +bdurl.net +bdvending.com +bdwater.com +bdwhyscjh.com +bdwkxz.com +bdwm.net +bdwork.com +bdxc.com +bdxdgs.com +bdxiguaimg.com +bdxigualive.com +bdxiguastatic.com +bdxiguavod.com +bdxpa.com +bdxx.net +bdxyykj.com +bdxyz.com +bdycdn.com +bdycdn.net +bdydns.com +bdydns.net +bdyhhb.com +bdylzbyy.com +bdymkt.com +bdysc.com +bdysite.com +bdysites.com +bdyz.xyz +bdzhipin.com +bdzjdsagslb.com +be-xx.com +be1775.com +be1dbb20578c1b79.com +be20e436e111e1f7.com +be30d71aea370488.com +be7076f2b2ff2953.com +be79d8d36f962bd6.com +be84433f5ce02a66.com +be896b364b76c6df.com +be90.com +beacons.gcp.gvt2.com +beacons.gvt2.com +beacons2.gvt2.com +beacons3.gvt2.com +beadwallet.com +beamweldingmachine.com +beancomm.com +beantechyun.com +bear20.com +bearead.com +beargoo.com +bearingclub.com +bearrental.com +bearsing.com +bearyboard.com +bearychat.com +beastush.com +beasure.com +beatbeatone.com +beats-digital.com +beatsbydre.com +beaucare.org +beautifulbank.com +beautifulcarrot.com +beautifullinux.com +beautifulzzzz.com +beaverbio.com +beb688d9cad7d208.com +bebhmongb.com +bechangedt.com +becker-china.com +beckwai.com +beckyroom.com +becod.com +becomingcelia.com +becominggroup.com +becukwai.com +beduu.com +bee-core.com +bee-net.com +bee-station.com +bee3d.com +beebeepop.com +beebeeto.com +beecook.com +beedancing.com +beeeeego.com +beeflower-cn.com +beegoedu.com +beejoygames.com +beelink.com +beep365.com +beeplay123.com +beeshow.tv +beespal.com +beestor.com +beeui.com +beeweart.com +befar.com +begcl.com +begeel.com +begindcc.com +bego.cc +begoto.com +begowin.com +behake.com +behao.net +behaviac.com +behrenswatches.com +behrenswatches.shop +bei1688.com +beiamp.net +beianw.com +beibaobang.com +beibaozq.com +beibei.com +beibenkc.com +beicaiyuan.com +beicdn.com +beichende.com +beicity.com +beidasoft.com +beidd.com +beidian.com +beidisi.com +beidoou.com +beidou.org +beidou66.com +beidouchong.com +beidouedu.net +beidouone.com +beidousafety.org +beidouxingxueche.com +beiduolab.com +beierbio.com +beierchina.net +beierjin.net +beieryouxi.com +beifa.com +beifang.net +beifangfoshifen.com +beifangjiaoyu.com +beifeng.com +beifuni.com +beigangyouxuan.com +beigonggroup.com +beiguorc.com +beihai365.com +beihai97.com +beihaidc.com +beihaigame.com +beihailihe.com +beihaimayi.com +beihaiqiuzhi.com +beihaireexpo.com +beihaiwuyeguanli.com +beihaiwz.com +beihan.net +beihansoft.com +beihuasoft.com +beihuo.net +beiing.net +beijin100.com +beijing-air.com +beijing-chopard.com +beijing-girardperregaux.com +beijing-halfmarathon.com +beijing-hmo.com +beijing-hualian.com +beijing-kids.com +beijing-lipin.com +beijing-marathon.com +beijing-office.com +beijing-time.org +beijing-tokyo.com +beijing101.com +beijing120.com +beijing518.com +beijingaierfei.com +beijingapt.com +beijingbang.com +beijingbaomu.com +beijingbio.tech +beijingcenterforthearts.com +beijingcustoms.com +beijingfenxiangkeji.com +beijingfire.com +beijingfojiao.com +beijinggobroadhospital.com +beijingguoyitang.com +beijinghopemedcare.com +beijinghuafu.com +beijinghuiyizhongxin.com +beijinglandbridge.com +beijingnongjiayuan.com +beijingnorthstar.com +beijingrc.com +beijingrc.net +beijingrenyi.com +beijingsanchi.com +beijingtaixie.com +beijingtoon.com +beijingtrucks.com +beijingwatch.com +beijingxiantour.com +beijingxinzhuoyue.com +beijingyouxi.com +beijingyuanxin.com +beijingzc.com +beijingzoo.com +beijinxuetang.com +beijiu.ink +beijzc.com +beikeba.com +beikeiot.com +beikeread.com +beikongyun.com +beilayl.com +beileike.com +beileimaoedu.com +beiletoys.com +beilewh.com +beilianjd.com +beilile.com +beilin.ltd +beilinbox.com +beiliufuyang.com +beimai.com +beimeihongfeng.com +beimeizhijia.com +beimeizhiying.com +beinglab.com +beingmate.com +beipenggroup.com +beipy.com +beiqujy.com +beirangroup.com +beiren-tech.com +beiren.cc +beiren.com +beironsign.com +beirunjie.com +beise.com +beisen.com +beisenapp.com +beisencloud.com +beisencorp.com +beisenpaas.com +beisenyl.com +beismei.com +beitaguoguo.com +beitaichufang.com +beitao8.com +beitown.com +beitre.com +beiwaibest.com +beiwaiclass.com +beiwaiguoji.com +beiwaionline.com +beiwaiqingshao.com +beiwo.com +beiww.com +beixibaobao.com +beixingmh.com +beiyijt.com +beiyinqi.com +beiyiskjc.com +beiyongzhan.com +beiyuwangxiao.com +beizhua.com +beiziman.com +bej9.com +bejirog.com +bejson.com +bekko.com +belarusvisacenter.com +belfone.com +belgiumvisacenterd.com +beliefbiomed.com +beliefy.com +belimked.com +belle8.com +belletrip.com +bellinlaser.com +belllan.com +belloai.com +beloj.com +belray-coffee.com +beltandroadforum.org +beltxman.com +belverra.com +bemanicn.com +bemfa.com +bemhome.com +benbenlong.com +benber-tech.com +benber.com +benbun.com +bencaopu.com +bendan.website +bendi5.com +bendibao.com +bendijin.net +bendis.cc +bendiso.com +bendiw.cc +bendizhidao.com +benduo.net +benewake.com +benfuip.com +bengbufan.com +bengden.com +bengfa.biz +benghuai.com +bengku.com +bengou.com +bengrong.com +bengtie.com +bengyechina.com +bengzhanc.com +benhs.com +beniao.com +benjamin.fun +benkejieye.com +benkua.com +benlai.com +benlailife.com +benlaisy.com +benling-sh.com +benliuxinwen.com +benlizu.com +benlkjc.com +benlong.vip +benma.com +benmi.com +benmu-health.com +bennybu.fun +benpsbp.com +benqhospital.com +benqmedicalcenter.com +benqmedicalcentersz.com +bensewang.com +benshouji.com +bensiea.com +benweitang.com +benweng.com +benxiang.com +benyh.com +benyouhui.com +benyuannet.com +benzhb.com +benzhibbs.com +benzhiwangluo.com +benztto.com +beodesj.com +beony.com +beook.com +bepal.pro +bepurestandards.com +bequ6.com +bequ6.org +bequgew.com +bequgexs.com +bequgezw.com +bequw.com +bequwx.org +berchina.com +berens-china.com +berfen.com +bergerda.com +berlin8.org +berlinchan.com +berlinix.com +bernouly.com +berrydigi.com +berrygenomics.com +bersella-ai.cc +bersilion.com +bertadata.com +berui.com +berylbot.com +bes.ren +besbranding.com +bescar.com +beschannels.com +bescity.com +bescloud.com +besclouds.com +bescn.com +besg-bee.com +besget.com +beshtech.com +besile.com +besino.com +besonchina.com +bessystem.com +best-display.com +best-inc.com +best-intl-school.com +best-lookstone.com +best1.com +best198.com +best66.me +best73.com +bestadprof.com +bestapp.wiki +bestarzx.com +bestatic.com +bestb2b.com +bestbeibao.com +bestblower.com +bestcdn.vip +bestcem.com +bestchoiceco.com +bestcloudcdn.com +bestclouddns.com +bestcood.com +bestcovered.com +bestcrossborder.com +bestdataclub.com +bestdo.com +bestdon.net +bestdosas.com +bestechnic.com +bestedm.net +besteduchina.com +bester-cn.com +bestexpresser.com +bestfood517.com +bestfuturevip.com +bestgo.com +besthairextensions.com +besthub.tech +besticity.com +bestincapi.com +bestincapp.com +bestjy.net +bestkids.net +bestlec.com +bestlee.net +bestlosslessmusic.com +bestmate.net +bestmoban.com +bestomro.com +bestone.com +bestone.vip +bestopview.com +bestpay.net +bestpeng.com +bestqliang.com +bestraylaser.com +bestreplicheitalia.com +bestrhy.com +bestsdwan.com +bestshinhwa.com +bestsign.info +bestsign.tech +bestsignuniversal.com +bestsrc.com +beststeel-sh.com +bestsungas.com +bestsuppliers.com +bestswifter.com +besttrav.com +bestugali.com +bestv6.com +bestvcdn.com +bestvcdn.net +bestviewstock.com +bestwa.com +bestwatch.cc +bestwatchaaa.com +bestwaysh.com +bestwehotel.com +bestweshop.com +bestwesternfelicityshenzhen.com +bestzone.org +bestzumo.com +bet007.com +bet2268.com +bet2396.com +bet33040.com +bet365uo.com +bet3739.com +bet505.app +bet5993.com +bet6598.com +bet6737.com +bet6755.com +bet8.cm +beta-dns.com +betaband.net +betadance.net +betaenv.com +betaflare.com +betahub.tech +betaidc.com +betamao.me +betaquantity.com +betasmart.tech +betavolt.tech +betawm.com +betazixun.com +betcctv.com +betely.com +bethh777.com +betokapp.com +betop-cn.com +betop365.com +betophall.com +bettapharma.com +bettbio.com +better-cn.com +better365.com +betterclyde.com +betteredu.net +betteryeah.com +betwayasia.org +beuyinm.com +beva.com +bevol.com +bewellbio.com +bewg.net +bewgnn.com +beyebe.com +beyond-perfection.com +beyondbit.com +beyondcomparepro.com +beyondfund.com +beyondh.com +beyonditsm.com +beyondq.com +beyonds.com +beyondsungroup.com +beyoner.net +beyotime.com +bezbzsyf.com +bf-jxqc.com +bf-z.com +bf-zhengzhou.com +bf07e33c810281.beer +bf35.com +bf99.com +bfcdnbf.com +bfcdnrd.com +bfcdnsc.com +bfchayuan.com +bfcmovie.com +bfdcloud.com +bfe-networks.com +bfe-networks.net +bffengshi.com +bffyun.com +bffzb.com +bfgho.com +bfhdp1120.com +bfhmj.com +bfhmq.com +bfhzmj.com +bfikuncdn.com +bfimg.com +bfjr.com +bfjxmajiang.com +bfjxmj.com +bfklyhuan.com +bflschayuan.com +bfnbgame.com +bfningbo.com +bfqh.com +bfqifu.com +bfqqsg.com +bfqtchayuan.com +bfqzmyq.com +bfscoc.com +bfsea.xyz +bfsmy.com +bfssj.com +bfsu-artery.net +bfsutw.com +bfsxmj.com +bft-robot.com +bftq.com +bftv.com +bfvvs.com +bfw.wiki +bfxiuxianqipai.com +bfxpj888.com +bfypq.com +bfyx.com +bfyx.net +bfzhan.com +bfzzmj.com +bg.v4.a.dl.ws.microsoft.com +bg4.v4.a.dl.ws.microsoft.com +bg45.com +bg7ywl.com +bgbfds.com +bgbk.org +bgbluesky.com +bgccn.com +bgctv.com +bgdeco.com +bgdzsw.com +bgfl.net +bggd.com +bghc.net +bghgw.com +bghmj.com +bgi-graphene.com +bgi.com +bgic.com +bgici.com +bgigc.com +bgjbq.com +bgk100.com +bgkj.pro +bgl88.com +bglmzm.com +bgmfans.com +bgmrecord.com +bgnyl.com +bgosp.com +bgrdh.com +bgri.com +bgrimm.com +bgrwgglz.com +bgs123.com +bgsdk.net +bgsdyz.com +bgsyb.com +bgteach.com +bgtwater.com +bgucu.com +bgv888.com +bgvalve.com +bgwcsz.com +bgwl.net +bgwxc.com +bgxcl.com +bgxu.com +bgyfhh.com +bgyfhyx.com +bgyhotel.com +bgyhotels.com +bgypc.com +bgypsc.com +bgyshop.com +bgyvfs.net +bgzchina.com +bgzx365.com +bh-lay.com +bh-mangrove.com +bh-med.com +bh-xhhd.com +bh1t.com +bh3.com +bh5.com +bh568.com +bh8cg18i96.com +bh8sel.com +bhabb.com +bhbd-alliance.org +bhccn.com +bhcd.net +bhcgky.com +bhcpu.com +bhcyhotel.com +bhcyts.cc +bhcyy.com +bhczxx.com +bhdata.com +bhdl520.com +bhdns.com +bhdxfsyy.com +bhdyjs.com +bhecard.com +bheyy.com +bhfc.net +bhfeiyang.com +bhfz114.com +bhghy.com +bhgjjy.com +bhgmarketplace.com +bhgroups.com +bhgsb.com +bhhfsc.com +bhhospital.com +bhhsx.com +bhhthl.com +bhhzjt.com +bhidi.com +bhiv.pro +bhjcsc.com +bhjinghao.com +bhjjj360.com +bhjuxian.com +bhkyxy.com +bhlib.com +bhlietu.com +bhlqjt.com +bhluoer.com +bhlyw.net +bhnet.net +bhnge.com +bhnsh.com +bhpcc.com +bhpiano.com +bhpiston.com +bhqd6688.com +bhqzyy.com +bhrencai.com +bhrssp.com +bhsanfan.com +bhsbdcdjzx.com +bhsence.com +bhsgnk.com +bhshtksp.com +bhshunhui.com +bhshyy.com +bhsr.com +bhszyyy.com +bhtv.cc +bhuitong.com +bhuvgy.com +bhwzdnweys.com +bhxww.com +bhxx.net +bhxxpt.com +bhxz.net +bhybskq.com +bhyby.com +bhyintan.com +bhyueda.com +bhzck.club +bhzck.xyz +bhzd88.com +bhzdzx.net +bhzhu203.com +bhzp.net +bhzpw.com +bhzw.com +bhzyxy.net +bi-ci.com +bi-sage.site +bi4sight.com +bi5u.com +bi8brp.com +bian-fengwei.com +bianbao.net +bianbu.xyz +biancheng.net +biancui.com +biandangroup.com +biandiantong.com +biandouyun.com +biandown.com +bianews.com +bianfeng.com +bianfengkuailai.com +bianhaiyun.com +bianjianzen.com +bianjiebao.com +bianjiqi.net +bianjiyi.com +bianju.me +bianlifeng.com +bianlun.net +bianmachaxun.com +bianminwang.com +bianpingyou.com +bianquchina.com +bianquzyk.com +biantaishuo.com +biantongzixun.com +bianwa.com +bianwanjia.com +bianxiazai.com +bianyifang.com +bianyuandaigou.com +bianzhia.com +bianzhile.com +bianzhirensheng.com +biao12.com +biaobaini.com +biaoceo.com +biaoda.me +biaodan.info +biaodan100.com +biaodiancloud.com +biaodiandichan.com +biaodianfu.com +biaofaw.com +biaoge.com +biaoge.me +biaohs.com +biaoju01.com +biaomi.com +biaopan8.com +biaopeibao.com +biaopu.cloud +biaoqing.com +biaoqing888.com +biaoqingjia.com +biaoqingwen.com +biaoshixinyi.com +biaoshula.com +biaosucdn.com +biaotianxia.com +biaotuan.com +biaotukeji.com +biaoyi.com +biaozhaozhao.com +biaozhiku.com +biaozhun.org +biaozhun8.com +biaozhuns.com +bib0.com +bibaodao.com +bibenet.com +bibibi.net +bibigpt.co +bibiku.com +bible.vip +bicido.com +bicobrand.com +bicoin.info +bicomoptics.com +bicpaedu.com +bicredit.xin +bicv.com +bicyc.com +bid-view.com +bidchance.com +bidemi.com +bidepharm.com +bidepharmatech.com +bidgojp.com +bidianbao.com +bidianer.com +bidingxing.com +bidizhaobiao.com +bidns.net +biduo.cc +biduobao.com +biduoxs.com +biduwenxue.com +bidwhy.com +bie-plc.com +biec.com +biechila.com +biede.com +biedoul.com +biekanle.com +biema.com +biept.com +bieshu.com +bietongfeng.com +bieyangapp.com +bieyelighting.com +bifabu.com +bifengxia.com +bifiv.com +biftsce.com +big-bit.com +big-shanghai.com +big5network.com +bigaaa.net +bigaka.com +bigan.net +bigbaicai.com +bigballbiz.club +bigbangux.com +bigbenmeng.com +bigbigai.com +bigbigsun.com +bigbigwon.com +bigbigwork.com +bigbrosci.com +bigbrx.com +bigcakegame.com +bigcat.com +bigcloud.click +bigda.com +bigdata-expo.org +bigdata.ren +bigdatacq.com +bigdatasafe.org +bigdatastudy.net +bigdatawuhan.com +bigddg.com +bige0.com +bigecko.com +bigehudong.com +bigemao.com +bigemap.com +bigerdata.com +bigerwall.com +bigeshuju.com +bigesj.com +bigeyes.com +biggaming.online +biggerlens.com +biggeryun.com +bigherdsman.com +bigjpg.com +bigniu.com +bignox.com +bigo.sg +bigo.tv +bigogm.com +bigoledog.com +bigolive.tv +bigops.com +bigplayers.com +bigpt8.com +bigqiao.com +bigquant.com +bigrnet.com +bigtide.com +biguiyuan.net +biguo100.com +biguolunwen.com +biguotk.com +bigwayseo.com +bigwh.com +bigwinepot.com +bigwww.com +bigxiao.com +bigyulin.com +bigzhong.com +bihe0832.com +bihongbo.com +bihoo.com +bihu.com +bihu.work +bihuatuku.net +bihubao.com +bihuoji.com +biikan.com +biioii.com +biji.com +bijiago.com +bijiagou.com +bijianzw.com +bijiao.org +bijiasso.com +bijiatu.com +bijienetworks.com +bijingdi.com +bijirim.com +bijixia.net +bijsc.com +bikeceo.com +bikecool.com +bikehome.cc +bikehome.net +biketo.com +biketour-giant.com +biking-m.com +bilalipay.com +bilandtech.com +bilezu.com +bilfinance.com +biliapi.com +biliapi.net +bilibil.com +bilibili.cc +bilibili.co +bilibili.com +bilibili.li +bilibili.net +bilibili.tv +bilibili996.com +bilibiligame.co +bilibiligame.net +bilibilihelper.com +bilibilipay.com +bilibiliq.com +bilicdn1.com +bilicdn2.com +bilicdn3.com +bilicdn4.com +bilicdn5.com +bilicomic.com +bilicomics.com +biligame.co +biligame.com +biligame.net +biligo.com +biligx.com +bilihot.com +biliimg.com +biliintl.co +biliintl.com +bilimanga.net +bilinl.com +bilinovel.com +biliplus.com +biliui.com +bilive.com +bilivideo.com +bilivideo.net +biliyu.com +bill-jc.com +billchn.com +billionaireboard.com +billionbottle.com +billionconnect.com +billionseo.com +billowlink.com +billu.cc +billwang.net +bilnn.com +bim-times.com +bimant.com +bimawen.com +bimface.com +bimfmchina.com +bimhuite.com +bimige.net +bimiwu.com +bimjoy.com +bimsa.net +binancezh.kim +binancezh.link +binary-semi.com +binaryai.net +binaryai.tech +binbinbiji.com +binbinyl.com +bincailiuxue.com +binfang.com +binfenniao.com +binfenquzu.com +binfenshikong.com +binfenyeke.com +binfenyingyu.com +binfenzhilv.com +bing400.com +bingchenvacuum.com +bingd.com +bingdian01.com +bingdoc.com +bingdou.site +bingfan.com +bingganqy.com +binggo.com +bingguner.com +binghelengmei.com +bingjo.com +bingjun.cc +binglai.net +binglanggu.com +binglianhuajianzhan.com +bingliekeji.com +binglixue.com +bingninglaowu.com +bingo321.com +bingocinemas.com +bingoenglish.com +bingolink.biz +bingosci.com +bingqipu.net +bingquan.com +bingshandashu.com +bingsin.com +bingtuannet.com +binguo.me +bingxs.com +bingyan.net +bingyandianqi.com +bingyongjin.vip +bingyuanhb.com +bingzunkeji.com +binhaiinv.com +binhaiwater.com +binhangtech.com +binjie.fun +binjie.site +binligzj.com +binliwatch.com +binmt.cc +binmtplus.com +binnong.com +binpang.me +binqsoft.com +binstream.live +binuoniu.com +binxin.com +binzc.com +binzhi.com +binzhikeji.com +binzhouw.com +binzz.com +bio-dxzf.com +bio-equip.com +bio-fount.com +bio-fuyang.com +bio-info-trainee.com +bio-island.com +bio-protocol.org +bio-review.com +bio1000.com +bio360.net +bio4p.com +biobiopha.com +biobw.org +biocause.com +biocellcharger.com +bioceltech.com +biochemsafebuy.com +biocloud.net +biocome.com +biocompounds.com +biodiscover.com +biodiscover.net +biodx.com +bioeast.com +biogeeker.com +biogo.net +biogot.com +bioguoke.com +biohf.com +biohong.com +biohuaxing.com +biohyalux.com +biohymn.com +bioinfo-scrounger.com +biokangtai.com +biokerun.com +bioktech.com +biolab.xyz +bioligo.com +biolihe.com +biome-expo.com +biomedicchina.com +biominhai.com +bionav.cc +bionovapharma.com +bioon.com +bioon.net +biopotentia.com +biorule.com +bioscenepharma.com +biosci-cq.com +bioscienceres.com +bioshineking.com +biosmelt.com +biosrepair.com +biosschina.com +biostar-pharm.com +biostatistic.net +biosune.com +biotanon.com +biotecan.com +biotech-meds.com +biotechina.com +biotechwell.com +biothink.tech +bioustar.com +biovector.net +biovip.com +bioway-pku.com +bioxtime.com +bipaihang.com +bipvcn.com +biqg8.com +biqige.cc +biqiuge.com +biqu.ge +biqu6.com +biquan8.com +biqubao.com +biqubao10.com +biqubu.com +biqudu.com +biqudu.tv +biqufu.com +biqugao.cc +biquge.info +biquge.la +biquge123.com +biquge8.com +biquge9.cc +biquge99.cc +biqugeg.com +biqugena.com +biquges.com +biqugesk.org +biqugex.com +biqugexs.com +biqugexs.la +biqugexsapp.com +biqugexsw.com +biqugezw.us +biqugg.org +biqugo.net +biqugu.cc +biqukai.com +biqukan.com +biquke.com +biquke.la +biquke.me +biquku.la +biqukun.com +biqukun.la +biquluo.com +biqupai.com +biqusa.com +biqushu.com +biqusk.com +biqusoso.com +biquw.com +biquw.info +biquw.la +biquwo.com +biquwo.net +biquwx.la +biquxs.com +biquyue.com +biquzw.info +biqwo.com +biransign.com +bird.art +bird4d.com +birdback.org +birdol.com +birdotech.com +birdwork.com +birentech.com +bisairi.com +bisco777.bet +bisenaccess.com +bisenet.com +bisenpark.com +bisgz.com +bishen.ink +bishengoffice.com +bishengyuan.com +bisheziliao.com +bishijie.com +bishuiwan.com +bisjigang.com +bison-technologies.com +bisonglighting.com +bisonscm.com +bisp.com +bistream.net +bit-coin-cash.asia +bitahub.com +bitauto.com +bitautoimg.com +bitautotech.com +bitbe.at +bitbrowser.net +bitcar.com +bitcron.com +bitdave.fun +bitdefender-cn.com +biteabc.com +bitech-automotive-wuhu.com +bitecoin.com +biteedu.com +bitekou.com +bitell.com +bitenn.com +bitett.com +bitgo.cc +bitgo.net +bitguai.com +bithosts.net +bitiful.com +bitiful.net +bitintelligence.net +bitjd.com +bitjia.com +bitky.cc +bitlib.cc +bitmain.vip +bitmingw.com +bitmoe.com +bitol.net +bitongtech.com +bitonloop.com +bitosscdn.com +bitqiu.com +bitscn.com +bitsde.com +bitse.com +bitvh.com +bitzsoft.com +biubiu.tv +biubiu001.com +biuged.com +biulie.com +biusoft.com +biwangxiao.com +biwuke.com +bixiaxs.net +bixishang.com +bixu.cc +bixu.me +bixuecrm.com +bixueke.com +biya.ltd +biyabi.com +biyan8.com +biyangwang.com +biyao.com +biye.net +biyehome.net +biyele.com +biyelunwenjiance.com +biyequna.com +biyequnar.com +biyezheng8.com +biyi.net +biyidc.com +biyingniao.com +biyinjishi.com +biyong007.com +biyork.com +biyou.tech +biyouxue.com +biyuandi.com +biyuansh.com +biyuanshuiwu.com +biyuwu.cc +biyuzg.com +biz-abroad.com +biz-east.com +biz-email.net +biz178.com +biz72.com +bizatmobile.com +bizcent.com +bizchallenge.net +bizcharts.net +bizcn-test.com +bizcn.com +bizcn.net +bizcn666.com +bizconfstreaming.com +bizhi360.com +bizhi88.com +bizhigq.com +bizhimiao.com +bizhiquan.com +bizhiwang.com +bizhixia.com +bizhizj.com +bizhizu.com +bizhongchou.com +bizmoto.com +biznewscn.com +bizopsmall.com +bizpai.com +bizsmooth.com +bizsmooth.org +bizsn.com +bizsofts.com +bizvane.com +bj-big.com +bj-brother.com +bj-brsf.com +bj-bts.com +bj-byjz.com +bj-cronda.com +bj-dahon.com +bj-dsmzyy.com +bj-fm.com +bj-fxh.com +bj-git.com +bj-hengdeli.com +bj-ipcf.org +bj-jzgg.com +bj-klws.com +bj-kpn.com +bj-nego.com +bj-pr.com +bj-px.com +bj-sea.com +bj-syc.com +bj-sydc.com +bj-tencentclb.cloud +bj-tencentclb.com +bj-tencentclb.net +bj-tencentclb.work +bj-tvart.com +bj-tygy.com +bj-win.com +bj-wjh.com +bj-yt.com +bj-zkhb.com +bj003.com +bj0yx.com +bj1.api.bing.com +bj1000e.com +bj148.org +bj159zx.com +bj1777.com +bj17z.com +bj2scmm.com +bj315.org +bj35.com +bj360.com +bj42195.com +bj51.org +bj520.com +bj597.com +bj5i5j.com +bj7z.com +bj80.com +bj918.com +bj96007.com +bjadks.com +bjadmix.com +bjadn.net +bjagro.com +bjaja.com +bjango.com +bjanjili.com +bjartmuseum.com +bjatv.com +bjbaidianfeng.com +bjbalb.com +bjbaodao.net +bjbb.com +bjbeichen.com +bjbeifangjx.com +bjbfdt.com +bjbkwy.com +bjblackhole.com +bjbna.com +bjbpi.com +bjbrew.com +bjbtfu.com +bjbus.com +bjbywx.com +bjbzc.com +bjbzszxy.com +bjc-ent.com +bjcae.com +bjcag.com +bjcancer.org +bjcankao.com +bjcapital.com +bjcatzgroup.com +bjcdc.org +bjcdomain.com +bjceis.com +bjcgtrain.com +bjchengjiu.com +bjchishengkeji.com +bjchunxin.com +bjcjl.net +bjcjyt.com +bjckkj.com +bjclover.com +bjcls.net +bjcma.com +bjcoco.com +bjcomic.net +bjcomm.com +bjcomparison.com +bjconrad.com +bjcontinent.com +bjcorona.com +bjcpjzhyxh.com +bjcrg.com +bjcsfx.com +bjcshy.com +bjcsyg.com +bjcta.net +bjcxdf.com +bjcxqd.com +bjcycg.com +bjcyjt.com +bjcymt.com +bjcymyy.com +bjcyzg.com +bjd-mc.com +bjdcfy.com +bjdclib.com +bjddtm.com +bjdf110.com +bjdfrw.com +bjdfxj.com +bjdhwy.com +bjdiaoyu.com +bjdjc.com +bjdllti.com +bjdongxin.com +bjdp2p.com +bjdragon.com +bjdsppa.com +bjdth.com +bjdw.org +bjdwl.net +bjdxfsxx.com +bjdxzxy.com +bjdyhsy.com +bjdyyc.com +bjeasycom.com +bjebc.com +bjeesa.org +bjef.com +bjei.com +bjent.org +bjepea.com +bjesg.com +bjesound.com +bjewaytek.com +bjexmail.com +bjexx.com +bjfc.cc +bjflc.com +bjfmart.com +bjfpw.com +bjfqy.com +bjfriendshiphotel.com +bjfsali.com +bjftfy.com +bjfzst.com +bjgas.com +bjgasgh.com +bjgastx.com +bjgcl.com +bjgdkn.com +bjgdzx.com +bjgfa.com +bjggk.com +bjggxh.com +bjgjjcapital.com +bjgjjmxy.com +bjgjtjk.com +bjgk.com +bjglxf.com +bjglxt.com +bjgongteng.com +bjgongyu.com +bjgoodwill.com +bjgree.net +bjgujibaohu.com +bjgumu.com +bjguodu.com +bjgxs.com +bjgymq.com +bjgyzjw.com +bjgyzs.com +bjgzc.com +bjhaiguang.com +bjhaijixing.com +bjhanlin.com +bjhdcp.com +bjhdhm.com +bjhdnet.com +bjhdrx.com +bjhee.com +bjhengchi.com +bjhengjia.net +bjhenson.com +bjherbest.com +bjhgbjgs.com +bjhlgw.com +bjhmcm.com +bjhmyq.com +bjhouse.com +bjhrha.com +bjhsyk.com +bjhsyuntai.com +bjhszp.com +bjhtlckj.com +bjhtzsgs.com +bjhuaxin.com +bjhuiqi.net +bjhuizhu.com +bjhwbr.com +bjhwtx.com +bjhwxy.com +bjhx110.com +bjhxqh.com +bjhxzlyy.com +bjhytjxjg.com +bjhzkq.com +bjhzzs.com +bjiab.com +bjiae.net +bjiaep.com +bjicpark.com +bjicrm.com +bjidc.net +bjidit.com +bjinfobank.com +bjipwqzx.com +bjitic.com +bjiwex.com +bjjbbayy.com +bjjbls.com +bjjchf.com +bjjdwx.com +bjjfsd.com +bjjgyy.com +bjjhhft.com +bjjhhn.com +bjjhsw.com +bjjihui.com +bjjingdong.com +bjjinl.com +bjjinming.com +bjjinsong.com +bjjiuhe.com +bjjizhun.com +bjjjst.com +bjjk66.com +bjjkglxh.org +bjjkw.net +bjjmzh.com +bjjnrl.com +bjjnzf.com +bjjqe.com +bjjqzyy.com +bjjr-tencentclb.cloud +bjjr-tencentclb.com +bjjr-tencentclb.net +bjjr-tencentclb.work +bjjsj.com +bjjsschool.net +bjjstyyzzyy.com +bjjsyy.com +bjjszyyy.com +bjjtat.com +bjjubao.org +bjjuli.com +bjjzjt.com +bjjzjxhyxh.com +bjjzsc.com +bjjzzpt.com +bjk30.com +bjkaihua.com +bjkaihua.net +bjkcsj.com +bjkdhy.com +bjkdvm.com +bjkeyscin.com +bjkgedu.com +bjknrt.com +bjkqj.com +bjkqyx.com +bjkrtwl.com +bjkswy.com +bjktaz.com +bjktwe.com +bjkxgroup.com +bjl777.com +bjlacc.com +bjlangbo.com +bjlanqiao.com +bjlaw995.com +bjlcs-tech.com +bjlevsoft.com +bjlg.com +bjljzw888.com +bjlkhd.net +bjllsy.com +bjlmg.com +bjlongview.com +bjlot.com +bjltsj.com +bjltwp.com +bjltxk.com +bjlyjszx.com +bjlysy001.com +bjlyw.com +bjmailqq.com +bjmama.com +bjmama.net +bjmamiai.com +bjmania.com +bjmda.com +bjmeikao.com +bjmerson.com +bjmjm.com +bjmslp.com +bjmti.com +bjmts.net +bjmxkn.com +bjmxxh.com +bjmxy.net +bjmylike.com +bjmzdx.org +bjmzw.com +bjn2ms.net +bjnai.net +bjnaxl.com +bjnhsw.com +bjnja.com +bjnkzx.com +bjnsr.com +bjnxgbyy.com +bjota.com +bjp321.com +bjpag.com +bjpcyd.com +bjpfh.com +bjpifu.com +bjpinweixuan.com +bjpmhyxh.com +bjpowernode.com +bjppa.com +bjpryk.com +bjqcjdcj.com +bjqh.org +bjqhgjj.com +bjqichezl.com +bjqingyang.com +bjqlg.com +bjqtbase.com +bjqtfifthbase.com +bjqtforthbase.com +bjqtsecbase.com +bjqtthirdbase.com +bjqtti.com +bjqyjjlb.com +bjqykc.com +bjqzhd.com +bjraee.com +bjrc.com +bjrcb.com +bjrdhx.com +bjretech.com +bjreview.com +bjrjgj.com +bjrjtdkj.com +bjrjyy.com +bjrlzyw.com +bjrock.com +bjrqjt.com +bjrtcdn.com +bjrtjt.com +bjrun.com +bjrussia-art.com +bjrwdx.com +bjry.com +bjsasc.com +bjsava.com +bjsbnet.com +bjscfl.com +bjscszh.com +bjscyxh.com +bjsdcm.net +bjsdeyy.com +bjsdfz.com +bjsdgroup.com +bjsdr.org +bjsfdr.com +bjsfrj.com +bjsftzxyjhyy.com +bjsgzgs.com +bjshaet.com +bjshdjy.com +bjsheng.com +bjshgzzxh.com +bjshowinfilm.com +bjsiasun.com +bjsinglewindow.com +bjsj5.com +bjsjds.com +bjsjgyy.com +bjsjsch12333.com +bjsjstxyy.com +bjsjsyly.com +bjsjwl.com +bjskjzs.com +bjsoho.com +bjsound.com +bjsoyo.com +bjsptf.com +bjspw.com +bjsrc.com +bjsrmyy.com +bjsryc.com +bjssjsyy.com +bjsskdn.com +bjstcc.com +bjstjy.com +bjsubway.cc +bjsubway.com +bjsuewin.com +bjsxdgzc.com +bjsxjt.com +bjsxt.com +bjsydq.com +bjsyhy.org +bjsyqw.com +bjsytv.com +bjsyzy.com +bjszhd.net +bjszlsjt.com +bjtaihua.com +bjtcf.com +bjtcy.com +bjtdhkj.com +bjtelecom.net +bjtieke.com +bjtitle.com +bjtjhn.com +bjtjw.net +bjtjzx.com +bjtkyy.com +bjtmjr.com +bjtndao.org +bjtobacco.com +bjtonghui.com +bjtongjian.com +bjtopli.com +bjtqcy.com +bjtradestar.com +bjtth.org +bjttsf.com +bjtvnews.com +bjtxc.com +bjtysj.com +bjtyzh.org +bjtzeduyun.com +bjtzfy.com +bjtzzg.com +bju-flo.com +bjucd.com +bjun.tech +bjunionstar.net +bjuri.com +bjvps.net +bjvtc.com +bjweizhifu.com +bjwenchen.com +bjwenyu.com +bjwftd.com +bjwfz.com +bjwhds.com +bjwhmedia.com +bjwig.com +bjwkhotel.com +bjwkzl.com +bjwpjs.com +bjwqxh.com +bjwt.com +bjwwhc.com +bjwyseo.com +bjxa.com +bjxchjxx.com +bjxcloud.com +bjxcsy.net +bjxdfk.com +bjxf315.com +bjxhly.com +bjximei.com +bjxingma.com +bjxingzheng.com +bjxinku.com +bjxinyou.com +bjxjyy666.com +bjxjzyy.com +bjxku.com +bjxtjmsb.com +bjxtkj.com +bjxueche.net +bjxwcq.com +bjxwx.com +bjxx.vip +bjxx8.com +bjxxw.com +bjxyjf.com +bjxyjy.com +bjxzlou.com +bjxzxw.com +bjyah.com +bjyald.com +bjyc.online +bjycwa.com +bjycxh.com +bjyczb.com +bjydzy.com +bjyestar.com +bjyhjt.net +bjyhwy.com +bjyingge.com +bjyingyun.com +bjyirui.com +bjyizhimei.com +bjylhyxh.com +bjyme.com +bjyn.com +bjyouth.net +bjypw.com +bjyqsj.com +bjysxh.com +bjysyunsheng.com +bjyszb.com +bjythd.com +bjyuantong.com +bjyubing.com +bjyueshenzj.com +bjyujinxiang.com +bjywt.com +bjyxl.com +bjyyb.net +bjyyun.com +bjyzfjj.com +bjzalaw.com +bjzaxy.com +bjzbb.com +bjzbkj.com +bjzcha.com +bjzcth.com +bjzg.com +bjzgh.org +bjzgh12351.org +bjzghd.com +bjzhaxikj.net +bjzhiborui.com +bjzhishi.com +bjzhongyi.com +bjzhsx.com +bjzkgc.com +bjzkgr.com +bjzkhs.com +bjzklk.com +bjzklp.com +bjzmdlsxs.com +bjzmkm.com +bjzmqj.com +bjznkq.net +bjznnt.com +bjzph.com +bjzqw.com +bjzrzc.com +bjzs.cc +bjzs114.com +bjzsxccm.com +bjzunlaotang.com +bjzwbc.com +bjzwhz.com +bjzwx.com +bjzwzx.com +bjzxcp.com +bjzxsf.net +bjzxyy.com +bjzy360.com +bjzybaoan.com +bjzybc.com +bjzyjt.com +bjzyrxgs.com +bjzysx.com +bjzzcb.com +bjzzdb.com +bjzzrx.com +bjzzschool.com +bk-cdn.com +bk-cdn01.com +bk3r.com +bk41.net +bk5u.com +bkaivl2daed.com +bkapigw.com +bkapps.com +bkbgame.com +bkbyxa.com +bkcipbewruo.com +bkcloud.cc +bkclouds.cc +bkcode.net +bkdou.com +bkeconomy.com +bkiije.com +bkill.com +bkill.net +bkjia.com +bkjk-inc.com +bkjk.com +bkjk123.com +bkjpress.com +bkjsemi.com +bkkchina.com +bkn.cc +bkneng.com +bknzdh.com +bkpcn.com +bkqq.com +bkrgame.com +bkscc.com +bktencent.com +bktsj.com +bkuax.com +bkweek.com +bkzzy.com +bl.com +bl0757.com +bl91.com +black-unique.com +blackberry.com +blackbirdsport.com +blackdir.com +blackdragon.com +blackeep.com +blackh4t.org +blackint3.com +blackluxury.com +blackshark.com +blackswancake.com +blackxl.org +blazefire.com +blazefire.net +blazingnight.cfd +blazor.zone +blbilibili.com +blbl.online +blbx.com +blctsy.com +bld365.com +bldaea.store +bldimg.com +bldlive.com +bldpharm.com +bldybbb.com +bldz.com +bldzlsb.com +bleege.com +blemall.com +blendercn.org +blessedbin.com +blestech.com +blgl8.com +blgxhn.com +blhdazhe.com +bliao.com +blibao.com +blibee.com +blibee.net +blicube.com +blimage.com +bliner.me +bling.link +blingabc.com +blinghour.com +blingoffice.com +blissmall.net +blizzardcn.com +blju.com +blksails.net +bllsbz.com +blm.net +blmpb.com +blockchain.hk +blockchain123.com +blockchainlabs.org +blockmeta.com +blockob.com +blocrepresents.com +blog.htc.com +blog.htcvive.com +blog.vive.com +blog120.com +blogcdn-dns.net +blogchina.com +blogchina.org +blogchinese.com +blogcn.co +blogfeng.com +bloggern.com +bloghub.fun +blogjava.net +blogofmusic.com +blogou.com +blogqun.com +blogturn.com +blogways.net +blogwe.com +blogxuan.com +bloom-powder.com +bloomage.com +bloomagebiotech.com +bloomchiic.com +bloomgamer.com +bloomtoursvip.com +bloqp.com +blossomwed.com +bloves.com +blovestorm.com +blowawards.com +blowing-mould.com +blowmoldmachines.com +blpack.com +blqugex.cc +blqx.com +blqy.com +blr206.com +blschain.com +blshthb.com +blskye.com +blsw.cc +blsweda.com +blsx.com +blszf.hk +blszhifa.com +blszyy.com +bltyyls.com +bltzw.com +blue-city.com +blue-skylandscape.com +blue-zero.com +blue0123.com +bluearchive-cn.com +bluebeebox.com +bluebellalingerie.com +bluebellls.com +bluebirdme.com +blueboxasia.com +bluebridge-amc.com +bluebullcn.com +bluebungalow-au.com +bluecardpay.com +bluecardsoft.com +bluecardsoft.net +bluecatyun.com +bluecefa.com +bluecity.com +blued.com +bluedarti.com +bluedgames.com +bluedhealth.com +bluedimg.com +bluedon.com +bluedoorindex.com +bluedotcc.com +bluefite.com +bluefocus.com +bluefocusgroup.com +blueglass.vip +bluegogo.com +bluegoon.com +bluehn.com +blueidea.com +bluek.org +bluelettercn.org +bluelightfuse.com +bluelive.me +bluenotechina.com +blueocean-china.net +blueplus.cc +bluepoch.com +bluesdream.com +blueseaict.com +bluesharkinfo.com +blueshow.net +blueskykong.com +blueskyschool.net +blueskystudy.com +blueskyxn.com +blueslc.tech +bluesoleil.com +bluestep.cc +bluetime.com +bluetowngroup.com +bluetrum.com +bluewhaleremote.com +bluezz.net +blurdev.com +blw.moe +blwire.com +blxfc.com +blxs.info +blxs.la +blycctv.com +blyun.com +blzddist1-a.akamaihd.net +blzls.xyz +blzpw.net +blzsjx.com +bm-inv.com +bm-mc.com +bm001.com +bm0392.com +bm12166.org +bm369.net +bm50ue2uwnj7.com +bm8.tv +bmbios.com +bmbn100.com +bmbqwater.com +bmc-medical.com +bmcedu.net +bmcx.com +bmdbr.com +bmdxcx.com +bme-assemble.com +bme-clock.com +bme-grow.com +bme-introduce.com +bme-invite.com +bme-mp.com +bme-wx.com +bmeicn.com +bmema.org +bmeol.com +bmfsm.com +bmh1958.com +bmimage.com +bmj.com +bmjet.com +bmjzkj.com +bml365.com +bmlink.com +bmlxkj.com +bmm-assemble.com +bmm-clock.com +bmm-grow.com +bmm-introduce.com +bmm-invite.com +bmm-mp.com +bmm-wx.com +bmmmd.com +bmmsteel.com +bmob.site +bmobapp.com +bmobcloud.com +bmobpay.com +bmolive.help +bmoook.com +bmosecuritylogin.com +bmp.ovh +bmpj.net +bmrtech.com +bmrtjt.com +bms16.com +bmser.com +bmshow.com +bmtrip.com +bmw8033.com +bmwallpaper.com +bmwchina.cloud +bmwnc.com +bmxinfang.com +bmyl2.com +bmzxw.com +bn21.com +bnacg.com +bnbba.com +bnbcamp.com +bnblogs.cc +bnbtrip.com +bnc66.com +bnchina.com +bncp.xyz +bncwork.com +bncyh.com +bndsfc.com +bnhelm.com +bnhshiguan.com +bnjyks.com +bnk-jaoptions.com +bnncn.com +bnnd.net +bnnnk.com +bnocode.com +bntyh.com +bnup.com +bnupg.com +bnwin.com +bnxf.online +bnysq.com +bnyy.com +bnzone.com +bo-blog.com +bo0s.com +bo56.com +boadge.com +boai.com +boai120.com +boaigx.com +boaihospital.com +boairl.com +boaiswgs.com +boanits.com +boao.press +boaoforum.org +bob-cardif.com +bob-leasing.com +bob.com +bobaow.com +bobbns.com +bobcare.com +bobcfc.com +bobcoder.cc +bobdirectbank.com +bobdog.com +boblog.com +bobmao.com +bobo2008.com +bobo91.com +bobobird.com +bobohome.store +bobopic.com +boboyq.com +bobswatchstore.com +bobtranslate.com +boc-leasing.com +bocai.life +bocaicms.com +bocaiwawa.com +bocamchina.com +bocaviation.com +boccfc.cc +boce.com +boce003.com +bocep2c.com +bocetest.com +bocfullertonbank.com +bocgi.com +bocgins.com +bochaai.com +bochengmed.com +bochk.com +bochkonline.com +bochyun.com +bocichina.com +bocifco.com +bocifunds.com +bocigroup.com +bociim.com +bocim.com +bocins.com +bocohz.com +bocomcc.com +bocommleasing.com +bocommlife.com +bocommtrust.com +bocondalian.com +bocsolution.com +bodaedu.net +bodahu.com +bodatek.net +bode-e.com +bodestone.com +bodiantrading.com +boditechgx.com +bodoai.com +bodocn.com +bodu.com +boduhappiness.com +bodyguard007.com +boe.com +boendejc.com +boerchina.com +boerzg.com +bof98.com +bofangw.com +bofyou.com +bog.ac +bogaochem.com +bogokj.com +boguanpaimai.com +bogute.com +boguub.com +bohaiadx.com +bohaigs.com +bohaileasing.com +bohailife.net +bohaishibei.com +bohaisports.com +bohaiyun.com +bohaoclub.com +bohe.com +bohejiasuqi.com +bohewangluo.com +bohu.co +bohua.com +bohuanchina.com +bohuasanhe.com +bohui-tech.com +bohuigk.com +bohuihe.com +bohuitalent.com +boilerinfo.net +boill.com +boilmc.com +boincdn.live +boiots.com +bojianger.com +bojiaojituan.com +bojicdmo.com +bojie.bid +bojolight.com +bojoy.net +bojun-import.com +boka.vc +bokaishi.com +bokao2o.com +boke.com +boke.one +boke.pw +boke112.com +boke8.net +bokecc.com +bokecs.net +bokee.com +bokee.net +bokesoft.com +bokesoftware.com +bokexia.com +bokeyz.com +boktour.com +bokunwatch.com +bolaa.com +bolan.net +bolaninfo.com +bolanjr.com +boldfrontierdesign.com +boldseas.com +bole-china.com +bole.com +bole.name +bole766.com +bolead.com +boledir.com +bolegs.com +bolehu.net +bolei99.com +boleihg.com +bolejiang.com +bolejiaoxue.com +bolelink.com +bolexiaozhao.com +bolin1688.com +bolink.club +bolken.com +bolo.me +bolo.video +bolongxm.com +bolq.com +boltp.com +boluogouwu.com +boluomee.com +boluomeet.com +boluomi01.com +boluoyun.com +boluoyunyu.com +boluozaixian.com +bom.ai +bom2buy.com +bomanair.com +bomeeting.net +bomin-china.com +bominelec.com +boming-sc.com +bomman.com +bomyg.com +bon-top.com +bon-wine.com +bonan.vip +bonbonbongame.com +bond120.com +bond520.com +bondent.com +bondlady.com +boneboat.com +bonepuppy.com +bonestgattiwatch.com +bongm.com +bongmi.com +bongv.com +bongwell.com +boningad.xyz +bonjour.bio +bonkee.net +bonkgb.com +bonree.com +boobooke.com +boodo.com +booea.com +booen.co +booeoo.com +boohee.com +book118.com +book1993.com +bookabc.net +bookapka.com +bookask.com +bookdao.com +bookdown.net +bookedu.com +bookersea.com +bookfedex.com +bookfeel.com +booking001.com +bookingtee.com +bookinlife.net +booknest.net +bookof.com +bookqi.com +books51.com +bookschina.com +booksgoo.com +bookshadow.com +bookshi.com +bookshoptw.com +bookshuku.com +booksky.cc +bookskys.com +booksn.com +booksos.net +booktxt.com +booktxt.net +bookuu.com +bookxnote.com +boolan.com +boolaw.com +boole-tech.com +boolv.com +boomallha.com +boonew.com +boonoo.net +boooba.com +boooming.com +boooog.net +booop.net +boopwater.com +boosj.com +boost77.com +boostsolar.com +boosyi.com +bootmb.com +bootstrapmb.com +boox.com +booyu-import.com +booz88.com +bopai.com +bopaisemi.com +bopinquwei.online +bopuyun.com +boqianpvm.com +boqii.com +boqiicdn.com +boqugew.com +boracaybestdeals.com +borain.com +borcci.com +borderlessbd.com +borenhospital.com +borlonclan.com +born-tw.com +born123.com +borninsummer.com +boroyf.com +borpor.com +borscon.com +borui-group.com +borui1001.com +boruipinggu.com +boruiqin.com +boruisx.com +boruixun.com +boruiyanjiu.com +borun-sun.com +boruntong.com +boryou.com +bos.xin +boscuser.com +bosdsoft.com +boseclub.com +boseip.com +bosen-fuji.com +bosenrui.com +bosera.com +bosera.com.hk +boshgame.com +boshi.tv +boshihoujob.com +boshijob.com +boshika.com +boshixitong.com +boshungame.com +bosi12315.com +bosibest.com +bosidata.com +bosideng.com +bosideng.me +bosideng.net +bosigame.com +bosikj.com +boslon.com +bosmaa.com +bosmarter.com +bosmia.com +bosomchina.com +bosondata.net +bosong.online +bosonnlp.com +bosonshop.com +boss-young.com +bosscdn.com +bossco.cc +bosscome.com +bossgoo.com +bossgy.com +bosshr.com +bossincom.com +bosszhipin.com +bostonis.org +bosunman.com +botaogroup.com +botaoo.com +botaopac.com +bote777.org +botemotor.com +botnet.cc +botny.com +botocard.com +boton-tech.com +botongr.com +botorange.com +botsfy.com +botslab.com +bottlekj.com +bouffalolab.com +bountech.com +bountyteam.com +boway.com +boweifeng.com +bowerp.com +bowok.com +bowu66.com +bowuzhi.fm +box-anchor.com +box-z.com +box3.fun +boxdouyin.com +boxgu.com +boxiaole.com +boxilink.com +boxim.online +boxisign.com +boxmoe.com +boxuegu.com +boxueio.com +boxui.com +boxunyt.com +boxz.com +boy-toy.net +boya300.com +boyaa.com +boyaapoker.com +boyaastar.com +boyaceo.com +boyais.com +boyamedia.com +boyamicro.com +boyaobang.com +boyasoftware.com +boyaxun.com +boydwang.com +boyi.co +boyikang.com +boyingsj.com +boyinhotel.com +boyishu.me +boylondonchina.com +boyoucy.com +boyouquan.com +boysky.com +boyuan-pharma.com +boyuan.com +boyuan.net +boyuanchemical.com +boyuanjiaxin.com +boyue.com +boyuecasting.com +boyueedu.com +boyuemobile.com +boyuesh.com +boyunso.com +boyuntu.com +boyuonline.com +bozhong.com +bozifs.com +bp1w.com +bpaykwai.com +bpec.com +bpgjuice.net +bpimg.com +bpmlt.com +bpmuseum.com +bppan.com +bpqwxsh.com +bpsemi.com +bpteach.com +bpxxfw.com +bpxxvo.com +bq04.com +bqb.xyz +bqbh.org +bqfy.com +bqg8.cc +bqg8.la +bqgjt.work +bqgwap.com +bqgxsw.com +bqjeep212.com +bqlcev.com +bqpoint.com +bqq8.com +bqqpx.com +bqrdh.com +bqsnn.com +bqtalk.com +bqteng.com +bqu123.com +bqyhb.com +br-cn.com +br737.com +bra-cdche.com +brabus-china.com +bragood.com +brain1981.com +brainmed.com +brainqaf.com +brand-isv.com +brand24k.com +brand4x4.com +brandcn.com +brandpano.com +brandsitejp.com +brandvista.com +brasaude.com +brasilcn.com +braveybelief.com +bravognss.com +brazzaleqingdao.com +brcpower.com +bre-line56.com +bre-linex.com +breadtrip.com +breathfilm.com +breenomeet.cc +breeze-chem.com +brentron.com +brewbeerwiki.org +brewersmix.com +brgame.app +brgame.vip +brick4.com +brickmachinery.net +bricksball.com +bricktou.com +bricsgo.com +bridge-image.com +bridgee.net +bridgelawfirm.com +brighost.com +bright-gene.com +bright-trend.com +bright21cn.com +brightdairy.com +brightdecolighting.com +brightfood.com +brightliao.com +brightmeat.com +brilliance-auto.com +brilliant-optoelectronics.com +bringbuys.com +bringspring.com +brire.com +britesemi.com +brlinked.com +brlmed.com +brmnq.com +brmyx.com +broad-ocean.com +broad.com +broad.org +broadair.net +broadbio.com +broadcasthe.net +broadcom-wuxi.com +broadcredit.org +broadex-tech.com +broadon.net +broadskytech.com +broadview-auto.com +brochef.com +bronzesoft.com +broqiang.com +brosmed.com +brother-bsh.com +brother-cn.net +brother-movie.com +brotherchem.com +browserleaks.com +browurl.com +brpcb.com +brsiee.com +brsnzp.com +brtbeacon.com +brtbeacon.net +brtn.org +brtpawn.com +brttc.com +brtvcloud.com +brunoxu.com +brxjzp.com +brxtal.com +bryzq.com +bs-56.com +bs-dolfin.net +bs-lab.com +bs-marathon.com +bs-yc.com +bs008.com +bs2005.com +bsagit.com +bsbgjj.com +bsbkjt.com +bsbydd.com +bscabank.com +bsccdn.com +bsccdn.net +bscdns.com +bscdnweb.com +bscea.org +bscedge.com +bscgslb.com +bsclink.com +bscomc.com +bscsjsn.com +bscstorage.com +bscstorage.net +bsctg.com +bscxypx.com +bsd-lifescience.com +bsd4fz.com +bsdcdsy.com +bsdexp.com +bsdfyyls.com +bsdongxin.com +bsdt1688.com +bsehk.com +bseqp.com +bserc.com +bsgcnc.com +bsgoal.com +bsgsgl.com +bsgslb.com +bsgz.com +bsh-safety.com +bsh-tech.com +bsh.com +bshare.com +bshark.com +bshdmotor.com +bshgem.com +bshmzx.com +bshsrl.com +bshu.com +bsida.com +bsidu.com +bsitcn.com +bsjhlx.com +bsjyjt.com +bskrt.com +bskuav.com +bslongyin.com +bsmatrix.com +bsmjdjzx.com +bsmy.cc +bsnljt.com +bsnniubi.com +bspapp.com +bsping.com +bsquant.com +bsrczpw.com +bsrmyy.com +bsrse.com +bssfy.com +bssgnkyy.com +bst-lab.com +bstatic.com +bstatics.com +bstbattery.com +bstchemical.com +bsteel.net +bstgjg777.com +bstinfo.com +bstj.com +bstjiaoyu.com +bstjt.com +bstzcs.com +bsurl.cc +bswtan.com +bswxw.com +bsxhly.com +bsxiaoshuo.com +bsxldl.com +bsxyzsdec.com +bsybx.com +bsydns.com +bsydns.net +bsyjrb.com +bsyjt.com +bsyxx.com +bsyyjt.com +bsz666.com +bszhly.com +bszip.me +bszxtl.com +bszyqc.com +bt-club.com +bt6.club +bt66.tv +btaxwy.com +btb8.com +btbat.com +btbctex.com +btc-precisionmedical.com +btc114.com +btc38.com +btc789.com +btcbbs.com +btcbca.com +btcbtc.tech +btcc886.com +btccjt.com +btcfans.com +btcha.com +btclass.net +btcqingbao.com +btcside.com +btcwatch.com +btcxue.com +btd56.com +btdad.live +btdad17.xyz +btdair.com +btdog.com +btdos.com +btdy.com +btechina.com +btei6pis99.com +btgame.com +btgcjs.com +btgdt.com +btgljt.com +btgtravel.com +bth.vip +bthhotels.com +bthlt.com +bthome.com +bthuifu.com +bthxjd.com +bthyhb.com +btiii.com +btime.com +btjhcc.com +btjtfz.com +btjy.net +btjzgc.com +btl-cn.com +btltl.com +btmayi.cc +btmeiju.com +btnotes.com +btophr.com +btorange.com +btosolar.com +btp-pharm.com +btpig.com +btplay.net +btpxbf.com +btropdi.xyz +btsemi.com +btshidai.com +btspreads.com +btsteel.com +btten.com +bttiantang.cc +bttiantang.com +btttg.com +bttzy.com +btv.org +btvcd.net +btvcloud.com +btwater.com +btwmw.net +btwoa.com +btwob.net +btxintong.com +btydjxc.com +btyhkj.com +btyijiaxueyuan.com +btytgj.com +btzbjt.com +btzgamepkg.com +btzhcc.com +btzthb.com +btzyc.com +buaaer.com +bubaigei.com +bubalusplus.com +bubbb.com +bubugao.com +bubuko.com +bubuol.com +bubuying.net +bubuyouqian.com +bubuzheng.com +bubuzou.com +bucg.com +bucg6.com +buchang.com +buchaq.com +buchina.net +bucid.com +buckydrop.com +bucuo100.com +bucuoba.com +budao.com +budao24.com +budhano.com +budiankj.com +budikeji.com +buding.tv +budingmore.com +budingscan.com +budiot.com +budou.com +budui.com +bueryx.com +bufan.com +buff8.com +buffaloex.com +buffst.com +bufpay.com +bughz.com +bugjump.net +bugku.com +bugnull.com +bugscan.net +bugscaner.com +bugu120.com +bugua.com +buguangdeng.com +bugukj.com +bugutime.com +bugxia.com +buhuyo.com +buickcare.net +buidea.com +build-decor.com +build.microsoft.com +build8.com +build9s.io +builddecor.org +buildface.com +buildhr.com +building9s.io +buildjob.net +buildnewapp.com +buildwaterexpo.com +buixz.cfd +buka365.com +buke999.com +bukesiyi8.com +bukeyi.net +bulaisi.com +bulaoge.net +bulapingc.com +bulbsquare.com +bulejie.com +bullcome.com +bullmachinery.com +bullvet.net +buluanmai.com +bululusexdoll.com +bumenkeji.com +bumiu.com +bundor.com +bundpic.com +bundsummit.org +bungba.com +bunze.com +buread.com +burgud.com +burnelltek.com +burningvocabulary.com +burongyi.com +bus365.com +bus6e.com +bus84.com +busbaoche.com +bushangban.com +bushi123.com +busilinq.com +businessconnectchina.com +businesssaga.com +businessweekchina.com +busionline.com +busituzi.com +busnc.com +bustoprint.com +bustruckexpo.com +but7.com +butair.com +butao.com +butel.com +butian.net +butiao.com +butjx.com +butongshe.com +butterapis.com +button-nt.com +buxia.net +buxian8.com +buxiuga.com +buy-bar.com +buy-copi888.com +buy-copys888.com +buy0596.com +buyanshufa.com +buyaocha.com +buycoor.com +buydeem.com +buydouke.com +buyfine.net +buyhot.vip +buyi9.com +buyiju.com +buyjingxi.com +buyjk.com +buylabel.com +buyoudao.com +buysun.net +buysweet.com +buyu1314.com +buyueyuyun.com +buyun.co +buzao.net +buzhi.com +buzhibushi.com +bva68.com +bvfcdn.com +bvfcdn2.com +bvgv.com +bvmc.cc +bvseo.com +bw1006.com +bw30yun.com +bw40.net +bw8848.com +bwae.org +bwangel.me +bwave.cc +bwbeer.com +bwbot.org +bwchinese.com +bwcj.com +bwcjxt.com +bwda.net +bwell-tec.com +bweyi.com +bwfapiao.com +bwfhmall.com +bwgqwea.com +bwgrt.com +bwhero.com +bwhgsb.com +bwie.net +bwjf.com +bwlc.net +bwmelon.com +bwoer.com +bwokai.com +bwpx.com +bwsm.org +bwsoft.net +bwtlab.com +bwton.com +bwxsj.com +bwxxw.com +bwzhcs.com +bx0byte.com +bx169.com +bx1k.com +bx24k.com +bxbest.net +bxcc.vip +bxd365.com +bxdaka.com +bxdbf.com +bxdlkj.com +bxfish360.net +bxgcb.com +bxgdl.com +bxgdunhua.com +bxgkzy.com +bxgmmw.com +bxgshengwang.com +bxgt.com +bxgycfsb.com +bxhaibao.com +bxjob.net +bxjyxx.net +bxkejian.com +bxktv.com +bxldz.com +bxltw.com +bxmd51.com +bxnfsy.com +bxnjmj.com +bxpedia.com +bxr.im +bxrfund.com +bxshopya.com +bxshscc.xyz +bxwatch.com +bxwljt.com +bxwst.com +bxwx.cc +bxwx.io +bxwx.tv +bxxhtsw.com +bxxy.com +bxyuer.com +bxzc123.com +bxzczx.com +bxzhiku.com +bxzxw.com +by-health.com +by-leasing.com +by56.com +by6.app +by6sx.com +by899.com +byai.com +bybieyang.com +bybily.com +byboai.com +bybon.com +bybutter.com +byc168.com +byclean.net +byd.auto +byd.com +bydauto.com +bydglobal.com +bydhaiyang.com +bydit.com +bydmax.com +bydoceanauto.com +bydpcic.com +bydq.com +bydsfy.com +bydyhos.com +byefy.com +byf.com +byfen.com +byfen.net +byfunds.com +bygamesdk.com +bygpu.com +bygqlsj.xyz +byguitar.com +bygw.net +byhao.net +byhiv.com +byhlds.com +byhlds.net +byhua.com +byi.pw +byjd.com +bykszb.com +bylw.com +bylwcc.com +bylwjc.com +bymygf.com +bymz.net +bynesyy.com +bynezyy.com +bynmc.com +bynonco.com +bynrnews.com +bynsyh.com +byodonline.com +bypanghu.xyz +bypbn.com +bypos.net +byqsc.net +byr-navi.com +byr.cc +byr.wiki +byread.com +byrhkj.com +bys120.com +bysb.net +byshf.com +byshjg.com +byshr.com +bysocket.com +byspharm.com +bystack.com +bystatic.com +bysxfz.com +byszc.com +bytapp.com +bytcm.com +byte-dns.com +byte-dns.net +byte-edge.com +byte-edgeworker.com +byte-gslb.com +byte-test.com +byte-test.net +byte-ticket.com +byte.online +byte00.com +byte00.net +byte000.com +byte008.com +byteac.com +byteacct.com +byteacctimg.com +byteactivity.com +byteactivity11.com +byteactivity12.com +byteadverts.com +byteapi.com +byteapk.com +bytecdn.com +bytecdn.net +bytecdntp.com +bytecho.net +bytecimg.com +bytecloud.com +byted-dast.com +byted-edu.com +byted-static.com +byted-ug.com +byted.org +bytedance-boe.net +bytedance.com +bytedance.net +bytedance.org +bytedanceapi.com +bytedancehermestest.com +bytedanceoss.net +bytedancevod.com +bytedcdn.com +bytedeliver.com +bytedgames.com +bytedns.com +bytedns.net +bytedns1.com +bytedns2.com +bytedns3.com +bytedns4.com +bytedns5.com +bytedns6.com +bytedns7.com +bytednsdoc.com +bytedsocial.com +byteedu.com +byteeffecttos.com +bytefae.com +bytefast.net +bytefcdn.com +bytefcdnrd.com +bytegecko.com +bytegeckoext.com +bytegle.site +bytegle.tech +bytegoofy.com +bytegrowth.com +bytegslb.com +bytehwm.com +byteics.com +byteics.net +byteimg.com +byteimgc.com +byteinspire.com +byteintl.net +byteisland.com +bytelb.net +bytelb000.net +bytell.net +bytemaimg.com +bytemastatic.com +bytemedi.com +bytemelody.com +bytenew.com +bytenewst.com +byteoc.com +byteorg.com +byteorge.com +byteox.com +bytepoker.fun +byteq8u.net +bytescm.com +bytesfield.com +bytesim.com +bytesmanager.com +bytespeech.com +bytesslb.net +bytesus.com +bytesyscdn.com +bytetcc.com +bytetech.info +bytetos.com +bytetraffic.net +bytetstatic.com +bytetstatic.net +byteug.com +bytevalk.com +bytevcloudvod.com +bytevdn-boe.com +bytevdn.com +bytewars.cc +bytewebservice.com +byteww.com +bytexns.com +bytexns.net +bytexservice.com +bytezhi.com +bythealthy.com +bythewayer.com +bytianshankd.com +byts.com +bytter.com +bytzjt.com +byvast.com +byw.lol +byxrmyy.net +byxsnzg.com +byxtzn.com +byxue.com +byxx.com +byxy.com +byyapp.com +byyc.net +byydkj.net +byyfy.net +byytfy.com +byzhihuo.com +byzjbyq.com +byzkj.com +byzoro.com +byzp.com +byzsyy.com +byzt.net +byzxy.com +bz-e.com +bz01.com +bz55.com +bz889.com +bzbgr.com +bzbs.net +bzbyzk.com +bzchaxun.com +bzcjw.com +bzcm.net +bzcm88.com +bzcw8.com +bzd6688.com +bzddrive.com +bzfar.com +bzfpms.com +bzfwq.com +bzfwy.com +bzfwzs.com +bzfxb.com +bzfxw.com +bzgd.com +bzglyfjq.com +bzgwl.com +bzhou.cc +bzhslyj.com +bzjsjt.com +bzjulihg.com +bzjw.com +bzkad.com +bzko.com +bzlxzl.com +bzmfxz.com +bzmhm.com +bzname.com +bzonl.com +bzqmz.com +bzrb.net +bzrqfd.com +bzsanguo.com +bzsanyuan.com +bzsb.info +bzsoso.com +bzszxyy.com +bzszyjx.com +bzszyy.com +bzszyy123.com +bzt120.com +bztdxxl.com +bzvtc.com +bzwater.com +bzwz.com +bzwzw.com +bzxinwen.com +bzxz.net +bzxzk.net +bzy.net +bzy2015.com +bzzpw.com +bzzxq.com +c-119.com +c-3.moe +c-abc.site +c-ame.com +c-banner.com +c-c.com +c-canyin.com +c-china.com +c-cpp.com +c-ctrip.com +c-discover.com +c-estbon.com +c-fehong.com +c-fol.net +c-jet.com +c-lodop.com +c-markaudio.com +c-nin.com +c-ps.net +c-rst.com +c-snd.com +c-sz.com +c-t.work +c-thme.com +c-vcc.com +c-wms.com +c-yl.com +c.admob.com +c.pki.goog +c03b92b501009.beer +c052kzyp55.com +c098d113b11031.beer +c0c0b511e1009.beer +c0f1lk250w.com +c114.net +c122e63a111031.beer +c133.com +c1a0.com +c1a2.com +c1a3.com +c1a8330703dc6f12.com +c1ass.com +c1channel.com +c1el.com +c1km1.com +c1km4.com +c1s.com +c2427457b16e03ea.com +c27619fb01019.beer +c2ax1yu599.com +c2h4.org +c360dn.com +c369a0f0611031.beer +c3806.com +c3810.com +c39cb900df.run +c3acg.com +c3b9cd3fb10311.beer +c3crm.com +c3pool.org +c3x.me +c4006.com +c4008.com +c400c.cc +c402f6df11021.beer +c4190cb63e65819b.com +c41b1d28472ea27c.com +c437dfd45f96b488.com +c43c3cb111011.beer +c469f14b911012.beer +c4752e8a51.vip +c47cb27580c5de6b.com +c49.com +c495f3eb10d6cf13.com +c4c6c49a6453534d.com +c4d.com +c4d.live +c4datc.com +c4dcn.com +c4dco.com +c4dpro.com +c4dsky.com +c4hcdn.com +c4sy726by8.com +c4ys.com +c4yx.com +c50forum.com +c516b5c2510272.beer +c53c4e56510281.beer +c54sauo3y85m2g.com +c558624c4b6f5f42.com +c578801be1009.beer +c57e6607c10292.beer +c57fbfc585.skin +c5a13eec21010.beer +c5a7e584ed460dcd.com +c5b27c7c01019.beer +c5b3c3db298ea985.com +c5b6bpoq7q.world +c5bf2b35337761f4.com +c5game.com +c5iot.com +c6133f7f98120d7f.com +c631dlc0br.com +c658e6a643fe3a95.com +c659e27c366ae634.com +c6a0cbdfa0be06e6.com +c6bad2ad01020.beer +c6c.com +c6n708.ren +c7.net +c7032.com +c705e5bdb71ae01d.com +c7197.com +c7200.com +c7233.com +c72a775z36.com +c73567b858ce4908.com +c7526.com +c77200.com +c77c.com +c7878.com +c7bc68c2811032.beer +c7c1jx3ikk.bar +c7c8.com +c7fffvip16.com +c7fffvip29.com +c7g.com +c7games.org +c7vvv.com +c7y.com +c835249c31017.beer +c837c4e951009.beer +c8571e9ad7689b0a.com +c88a8ae86f58a489.com +c8a8b0af81014.beer +c8f8537d91013.beer +c8uixr96iv79.com +c9018.com +c919.sbs +c944748d38bcc258.com +c953b5d8b1013.beer +c969.com +c9b5b03e0ef62dc0.com +c9c855b3da9b3b66.com +c9d1d314b98f8fe3.com +c9e8e19a411012.beer +c9ec9c2f0c2de043.com +c9o8nlanfm.work +ca-aicc.com +ca-sme.org +ca-smefs.com +ca-tencentclb.cloud +ca-tencentclb.com +ca-tencentclb.net +ca-tencentclb.work +ca001.com +ca002.com +ca003.com +ca0d7b2da10271.beer +ca163.net +ca168.com +ca2e9ea18bedfdf2.com +ca315.com +ca39.com +ca5d4ce601013.beer +ca800.com +ca91a5eb7ed4495e.com +ca9ce6rv872ce1.com +caa830d2710251.beer +caa86.org +caaa-spacechina.com +caaad.com +caacbook.com +caacchina.org +caacsri.com +caagei.com +caagov.com +caakee.com +caaladi.com +caanb.com +caapa.org +caasai.com +caasbuy.com +caasse.com +caayee.com +cab346ef31016.beer +cabbagebox.com +cabbeen.com +cabc-online.com +cabee.org +cabhr.com +cabinetbuy.com +cableabc.com +cabletiegun.com +cabling-system.com +cabplink.com +cabr-fire.com +cac-citc.com +cac2667b8c265fb8.com +cacakp.com +cacc-sf.org +cacfo.com +cacfo.net +cache4ever.com +cache666.com +cachekit.com +cachemoment.com +cachiyeung.com +cackui.com +cacpp.com +cacre.org +cacs-summit.com +cacsec.com +cacter.com +cactiapi.com +cactifans.com +cactmc.com +cad1688.com +cad2688.com +cad5.com +cad8.net +cad888.com +cada.cc +caddcc.com +cadenzayueqi.com +cadforex.com +cadict.net +cadmon.net +cadreg.com +cadrolift.com +cadzhuan.com +cadzj.com +cadzxw.com +caecc.com +caeda-cxrh.com +caeef787f1694f47.com +caeerr.com +caeete.net +caefa.org +caein.com +caeri-te.com +caes.store +caexpo.com +caexpo.org +cafachine.com +cafagame.com +cafamuseum.org +caffci.org +cagentle.com +cagetest.com +cageystone.com +cagoe.com +cahkms.org +cai-ba.com +cai110.com +cai58t.com +cai88.com +caiacn.com +caiair.com +caian.net +caibangzi.com +caibaojian.com +caibaopay.com +caibaotao.com +caibeike.com +caibihui.com +caibowen.net +caicao.net +caidan2.com +caidao1.com +caidao8.com +caidaocloud.com +caidian.com +caidian365.com +caidianqu.com +caiens.com +caifei.net +caifengprinting.com +caifu.com +caifu500.net +caifupai.com +caifuxingketang.com +caifuxingmingxue.com +caifuzhongwen.com +caigaowang.com +caigeqiu.vip +caigou2003.com +caigou365.com +caigoubao.cc +caigoutong.net +caiguayun.com +caiguu.com +caih.com +caihanlin.com +caihcloud.com +caihcom.com +caihdata.com +caiheht.com +caihong.com +caihong5g.com +caihong8888.com +caihongbashi.net +caihongche.com +caihongduoduo.com +caihongjia.com +caihongjianzhan.com +caihongmeng.com +caihongqi.com +caihongsheying.com +caihongto.com +caihongx.com +caihoo.com +caihuapak.com +caihuicloud.com +caihuoxia.com +caiips.com +caij100.com +caijing365.com +caijingche.com +caijingmobile.com +caijingnews.net +caijingwu.com +caijinyuan.com +caijiruanjian.com +caijj.com +caike.com +caiku.cc +caiku.com +caikuai91.com +caikuaitoutiao.com +caikuo.com +cailele.com +cailianpress.com +cailiao.com +cailiaoniu.com +cailiaoren.com +cailutong.com +caimaiba.com +caimei365.com +caimitech.com +caimogu.cc +caimogu.net +caimomo.com +cainachina.com +caing.com +cainiao-inc.com +cainiao-inc.net +cainiao.com +cainiaobaoka.com +cainiaocc.com +cainiaojc.com +cainiaojiaocheng.com +cainiaoxueyuan.com +cainiaoya.com +cainiaoyizhan.com +cainongnet.com +cainuan365.com +caipiaogu.com +caipintu.com +caipopo.com +caipucaipu.com +caiqizhe.com +cairenhui.com +cairongquan.com +cairot.com +cairuijun.com +caisan.io +caishen.ai +caishenpo.com +caishenyy.com +caishuiedu.com +caisixiang.com +caistc.com +caistv.com +cait.com +cait1981.com +caitaimg2.com +caitaw.com +caitun.com +caituyou.com +caiu8.com +caiwan.com +caiweiming.com +caiwennews.com +caiwu51.com +caiwuchina.com +caixadirectaanalisar.com +caixin.com +caixinfoundation.org +caixinmedia.com +caixinonline.com +caiyicloud.com +caiyiduo.com +caiyu.com +caiyuemedical.com +caiyun.com +caiyunai.com +caiyunapp.com +caiyuncdn.com +caiyunhub.com +caiyunyi.com +caizhaowang.com +caizhihr.com +caj11.com +cake400.com +cake6.com +calatopia.com +calawei.com +calb-tech.com +calccn.com +caldigit.net +caledoniancable.com +calendar520.com +calgoncarbon-china.com +cali-light.com +cali999.net +callbei.com +callcenter88.com +callergen.com +callmekeji.com +callmysoft.com +callrui.com +caloinfo.com +calorietech.com +calt.com +calterah.com +calvinneo.com +camartsphotography.com +cambm.com +cambodiafang.com +cambricon.com +cambridge.org +camc.cc +camcap.us +camcard.com +camce-rc.com +camdihg.com +came-online.org +camera360.com +cameraunion.net +camhen.com +camilliar.com +camir.org +camnpr.com +camoryapps.com +campanilechina.com +campari1987.com +campbicycle.com +campgreenbox.com +campingcn.com +campiu.com +campus-app.net +campuschina.org +campushoy.com +campusphere.net +campusplus.com +camreizuxphd.com +camscanner.com +camsnetec.com +camyu.net +can-dao.com +can-gas.com +can-lead.com +can.tv +cana.space +canaan-creative.com +canaanmt.com +canadaae.net +canalmuseum.net +canasy.com +canature.com +canbaojin.com +cancda.net +cancer361.com +candiabiotech.com +candou.com +candybook.com +candyhaw.com +candylab.net +candypay.com +candystars.net +canet.com +canevent.com +canfire.net +cang-jia.net +cang.com +cangdu.org +cangfengzhe.com +canghaiip.com +canghaimachine.com +cangjie-lang.net +canglanghospital.com +cangmang.xyz +cangoonline.com +cangowin.com +cangpie.com +cangqiang.com +cangqiongkanshu.com +cangshui.net +cangshutun.com +cangxiaoer.com +cangxitianli.com +cangya.com +cangzhouhd.com +canhighcenter.com +canhot.net +caniculab.com +canidc.com +canjio.com +cankao100.com +cankaoshouce.com +cankaoxiaoxi.com +cankaoxx.com +canlanjy.com +cannelton.org +canonpumps.com +canpdu.com +canpoint.net +canpopo.com +canrill.com +cansee.net +cansemitech.com +cansine.com +cantoge.com +cantonbio.com +cantonde.com +cantonfairad.com +cantontower.com +canvcan.com +canway.net +canwayit.com +canwaysoft.com +canxingmedia.com +canyin.cc +canyin.com +canyin168.com +canyin2017.com +canyin375.com +canyin88.com +canyincha.com +canyinzixun.com +canyouchina.com +canyousoftware.com +canyuanzs.com +caoanhospital.com +caobao.com +caocaobusiness.cc +caocaocustomer.cc +caocaoglobal.com +caocaojourney.cc +caocaokeji.net +caocaomarketing.cc +caocaomedia.cc +caocaoproduct.cc +caocaopromotion.cc +caocaoservice.cc +caocaosx.com +caocaotravel.cc +caocaotrip.cc +caocaotrip.com +caochai.com +caochai.net +caochen.net +caogen.com +caogenb2b.com +caogong.org +caohai.com +caohaifeng.com +caohejing.com +caohua.com +caoke.net +caoliao.net +caomall.net +caomei.wiki +caomeipai.com +caomeishuma.com +caoniang.com +caonmp.com +caos-china.org +caoshiyabo.com +caotama.com +caotianmiao.com +caotu66.com +caovan.com +caoxianfc.com +caoxie.com +caoxudong.info +caoyudong.com +capablist.com +capatue.com +capellahotelsanya.com +capitalcloud.net +capitaleco-pro.com +capitalip.org +capitalonline.net +capitaltoday.com +capjfx.club +capjoy.com +cappdr.org +caps-china.org +capsuleshanghai.com +captain-cro.com +capturetheflag.fun +capvision.com +capwhale.com +caqzlsgs.com +car-metaverse.com +car0575.com +car2sharechina.com +car369.com +car388.com +carapk.com +carben.me +carbinpower.com +carbonbiking.com +carbononegroup.com +carbonscn.com +carbonxprogram.com +carcav.com +carcdn.com +cardaudio.com +cardbaobao.com +cardcmb.com +cardcn.com +cardinfolink.com +cardlan.com +cardlogroup.com +cardniu.com +cardniudai.com +cardplus.work +cardqu.com +cardyang.com +care-challenge.com +care110.com +caredear.com +careduka.com +careerchina.com +careerexe.com +careerintlinc.com +careerqihang.com +careersky.org +carefiber.work +careked.com +carelifefood.com +carellicpa.com +carertec.com +careuc.com +carezb.com +cargai.com +cargeer.com +cargo001.com +cargodiscovery.com +cargofee.com +cargosmart.com +caribgalaxy.com +carimg.com +carisen.com +carivisa.com +carking001.com +carlinkin.com +carmov.com +carmucn.com +carnegiebj.com +carnoc.com +carodpiano.com +carp56.com +carpoly.com +carrotchou.blog +carrotchou.com +carry6.com +carry6.net +carrydj.com +cars001.com +carschina.com +carsmp3.com +cart-med.com +cartaocontinente-ptssta.cfd +cartech8.com +cartersda.com +carthane.com +cartimen.com +cartoonwin.com +carutoo.com +carxinwen.com +carxoo.com +caryoud.com +carzd.com +carzenplus.com +carzone365.com +carzyuncle.com +cas.org +cas01.com +casarocinante.com +casarte.com +casbin.com +casbin.org +casboc.com +cascadepharm.com +casctcp.com +casdoor.com +casdoor.org +case-platformhealth.com +case91.com +casear.net +casece.org +caseinnoo.com +casemic.com +cashbackok.com +cashbus.com +cashcatads.com +cashtoutiao.com +cashwaytech.com +casia.com +casibase.com +casic-addsino.com +casic-t.com +casic.com +casic304.com +casic3s.com +casicloud.com +casicyber.com +casis.work +casjob.com +caslease.com +casmeit.com +casmita.com +casmn.com +casnb.com +casp.hk +caspte.com +casqy.com +casszzy.com +cast.news98.com.tw +cast.uforadio.com.tw +castbd.com +castelu.com +castiron-bathtub.com +castlepeakhospital.moe +castyum.com +casvino.com +casvisor.com +casvm.com +casystar.com +casyueda.com +cat-cn.com +cat898.com +catalike.com +catalyst-loading.com +catcat321.com +catchingdoll.com +catchyrime.com +catering-shizuoka.com +catfish-cms.com +catguo.com +cathassist.org +cathayagroup.com +catia-china.com +catic-dde.com +caticgz.com +caticol.com +catjc.com +catl.com +cato-chem.com +cato-travel.com +catofes.com +cattsoft.com +cattsp.com +catugbio.com +catus.xyz +catuscdn.xyz +catv.net +catv114.com +catweiqi.com +catyun.cc +caua1988.com +caua99.com +caup.net +caupd.com +caupdbj.com +cauvet.com +cav-ad.com +cavca.org +cawae.net +caxa.com +caxx.net +cayzlh.com +cazpw.com +cazx.net +cb-h.com +cb07fef6ccb66c8e.com +cb6037f1b10261.beer +cb8888.shop +cb8a5dff61011.beer +cb8e405b81014.beer +cbaleague.com +cbbn.net +cbc32120f1014.beer +cbca.net +cbcechina.com +cbcgroup.net +cbcie.com +cbcloud123.com +cbcsnote.com +cbcuri.com +cbd-china.com +cbd0512.com +cbd263.com +cbdcn.com +cbdd9912fb913294.com +cbdio.com +cbdstest.download.prss.microsoft.com +cbdz13.com +cbe21.com +cbea.com +cbec365.com +cbecok.com +cbecx.com +cbeeexpo.com +cbes21.com +cbex.com +cbf92cea38c259ee.com +cbfau.com +cbgcloud.com +cbhb.biz +cbi360.net +cbiachina.com +cbiao.com +cbice.com +cbiec.com +cbiec.net +cbigame.com +cbinews.com +cbismb.com +cbitft.com +cbivisa.com +cbj1998.com +cbjq.com +cbjuice.com +cbjy520.com +cbjzw.org +cbmexpo.com +cbmf.org +cbminfo.com +cbmsci.com +cbmwz.net +cbn.me +cbndata.com +cbndata.org +cbnri.org +cbnweek.com +cboad.com +cbquan.com +cbsbearing.com +cbsnewshd-lh.akamaihd.net +cbsrc.com +cbtgc.com +cbtimer.com +cburi.com +cbvac.com +cbvvt.com +cbvx8.com +cbxs.net +cby.me +cbzr.com +cc-airshow.com +cc-honor.com +cc-image.com +cc-pharming.com +cc-q.com +cc-uavia.com +cc.cd +cc.co +cc06040d408f65b1.com +cc0808.com +cc11bh.com +cc1588.com +cc55k.com +cc707.com +cc7m.com +cc8.cc +cc86.com +cc89aba4a2ccad27.com +cca135.com +ccabchina.com +ccai.cc +ccall.cc +ccamc.co +ccaon.com +ccapbook.com +ccapedu.com +ccartd.com +ccarting.com +ccasn.com +ccasy.com +ccatcloud.com +ccatnet.com +ccawz.com +ccb.com +ccbb6be551024.beer +ccbcos.com +ccbec-shenzhen.com +ccbecexpo.com +ccbflift.com +ccbft.com +ccbfund.com +ccbfutures.com +ccbhome.net +ccbiam.com +ccbintl.com.hk +ccbleasing.com +ccbnd.com +ccbookfair.com +ccbpcn.com +ccbpension.com +ccbride.com +ccbseoul.com +ccbxt.com +ccc-ch.com +ccc-chn.com +cccamtop.com +cccbs.net +cccc-capital.com +cccc-sdc.com +cccc-sjer.com +cccc58.com +cccc8cccccc.cc +ccccccccccc.cc +cccclc-gd.com +cccclc.com +ccccoe.cc +ccccoe.com +ccccsg.com +cccdun.com +cccdzxw.com +cccf-cloud.com +cccitu.com +cccity.cc +cccking.com +ccckq.com +cccm-em120.com +cccmat.com +cccmii.com +cccmtf.com +cccnec.com +cccovvv.com +cccpan.com +cccppp.com +cccsql.com +ccctspm.org +cccwaf.com +cccyun.cc +ccd86.com +ccddb877c1024.beer +ccdma.org +ccdol.com +cce-china.com +cce0bd02011032.beer +ccea.pro +cceato.com +ccebbs.com +ccedia.com +ccedisp.com +ccedpw.com +ccedtu.com +ccee.com +cceea.net +cceep.com +ccement.com +ccen.net +ccepc.com +cces2006.org +ccesda.com +ccets.com +ccfddl.com +ccfeb.com +ccflow.org +ccfourth.com +ccfta.com +ccgaa.com +ccgdc.com +ccgff.com +ccgfie.com +ccggd.com +ccgim.com +ccgjbus.com +ccgogogo.com +ccgoyi.com +ccgs120.net +ccgslb.com +ccgslb.net +ccgxk.com +cchaosheng.com +cchc-hyd.com +cchccc.com +cchcch.com +cchengr.com +cchezhan.com +cchfound.org +cchlgame.com +cchorse.com +cchorse.net +cchoubo.com +cchpu.com +cci-intervention.com +ccia-cleaning.org +ccia.xin +cciaiot.org +cciatv.com +ccic-8.com +ccic-auto.com +ccic-lab.com +ccic-set.com +ccic.com +ccic2.com +cciccloud.com +ccice.com +ccicgd.com +ccicgx.com +ccicsd.com +ccidcom.com +ccidconsulting.com +cciddata.com +cciddesign.com +ccidedu.com +ccidexpo.com +ccidgroup.com +ccidnet.com +ccidreport.com +ccidsmart.com +ccidthinktank.com +ccidwise.com +cciea.com +ccieh3c.com +ccifc.org +ccig.com +ccigchina.com +ccinchina.com +ccip.ren +ccipp.org +ccirm.org +ccit360.com +ccita.net +ccitimes.com +ccitu.com +cciup.com +ccj88.com +ccjec.com +ccjhdljs.com +ccjkncdc.com +ccjkwjjedu.com +ccjoo.com +ccjoy.com +ccjoyland.com +ccjs120.com +ccjt.com +ccjxcn.com +ccjytv.com +ccjzzj.com +cckbyi.com +cckefu1.com +cckefu3.com +cckggroup.com +ccknbc.cc +cckyedu.com +cclawer.com +cclawnet.com +cclbook.com +cclcn.com +ccle5.com +ccler.com +cclexpo.com +cclgpx.com +cclimg.com +cclinux.org +cclndx.com +cclolcc.com +cclqme.xyz +ccluster.net +cclyun.com +ccm-1.com +ccm-hardware.com +ccm99.com +ccmama.com +ccmcgc.com +ccmdl.adobe.com +ccmdls.adobe.com +ccme.cc +ccmfcm.com +ccmicroera.com +ccmn.net +ccmodel.com +ccmw.net +ccn.ren +ccn360.com +ccnbdh.com +ccnee.com +ccnew.com +ccngx.com +ccnovel.com +ccnovo.com +ccnpic.com +ccnt.com +ccoalnews.com +ccoaonline.com +ccoco.vip +ccode.cc +ccoi.ren +cconn.cc +ccoop.net +ccoopg.com +ccops.net +ccopyright.com +ccostm.com +ccotcm.com +ccoymc.com +ccp3060.com +ccpaie.com +ccpc.io +ccpc360.com +ccpgssd.com +ccpit-academy.org +ccpit-sichuan.org +ccpit-sx.org +ccpit-tga.org +ccpit.org +ccpitbj.org +ccpitbm.org +ccpitbuild.org +ccpitcft.com +ccpitcq.org +ccpitecc.com +ccpitfujian.org +ccpitgs.com +ccpitgx.org +ccpithebei.com +ccpithn.org +ccpitjinan.org +ccpitjs.org +ccpitlight.org +ccpitln.org +ccpitnb.org +ccpitsd.com +ccpittex.com +ccpittj.org +ccpitxiamen.org +ccpitxian.org +ccplay.cc +ccplay.com +ccpnt.org +ccpod.com +ccprec.com +ccproxy.com +ccps56.com +ccqctg.com +ccqf.com +ccqg.com +ccqtgb.com +ccqtm.com +ccqyj.com +ccrate.cc +ccrc.com +ccrfmed.com +ccrgt.com +ccrici.com +ccrjk.com +ccrjkf.com +ccrjw.com +ccsacacasfdghh.com +ccschangsha.com +ccscrbyy.com +ccsedqrmyy.com +ccsfuchan.com +ccskqyy.com +ccsngqyy.com +ccsnpower.com +ccsp365.com +ccssmm.com +ccst.cc +ccsuu.com +ccswuhan.com +ccsx.net +ccsxlyy.com +cct-g.com +cct-lab.com +cct365.net +cctalent.com +cctalk.com +cctalk.net +cctash.com +cctaw.com +cctbn.com +cctc.cc +cctcce.com +cctcct.com +cctcdn.com +cctek.com +cctheze.com +cctime.com +cction.com +cctlife.com +cctmt.com +cctocloud.com +cctpgm.com +cctpress.com +cctry.com +cctsz.com +cctu.org +cctv-19.com +cctv-caijing.com +cctv-peiyin.com +cctv-star.com +cctv.com +cctv0002.com +cctv13cctv13.com +cctv18.com +cctv4g.com +cctv5bo.com +cctvcdn.net +cctvcj.com +cctvctpc.com +cctvdyt.com +cctvfendou.com +cctvfinance.com +cctvjingji.com +cctvmall.com +cctvpic.com +cctvplus.com +cctvsdyxl.com +cctvse.net +cctvweishi.com +cctvxftx365.com +cctw.cc +cctypx.com +cctzz.net +ccughc.net +ccutchi.com +ccv160.com +ccv168.com +ccview.net +ccvui.com +ccwcw.com +ccwcyw.com +ccwifi.cc +ccwl.net +ccwonline.com +ccwonline.net +ccwork.com +ccwow.cc +ccwqtv.com +ccwto.net +ccxcn.com +ccxcredit.com +ccxhfk.com +ccybeta.cc +ccydkj.com +ccygmy.com +ccyia.com +ccynice.com +ccyts.com +ccyunmai.com +ccyyxx.com +cczel.com +cczjyy.com +cczk.com +cczkdmkj.com +cczq.com +cczq.net +cczxyjhyy.com +cd-cxh.com +cd-estt.com +cd-hk.net +cd-hss.com +cd-kc.com +cd-motorshow.com +cd-ox.com +cd-pa.com +cd-psychologist.com +cd-rail.com +cd-sd.com +cd-tencentclb.cloud +cd-tencentclb.com +cd-tencentclb.net +cd-tencentclb.work +cd-web.org +cd-wx.com +cd-wx.net +cd-zc.com +cd00c44f211031.beer +cd120.com +cd12371.com +cd1958.com +cd20.net +cd2120.com +cd23f.com +cd3120.com +cd365689f11012.beer +cd37wan.com +cd3hospital.com +cd42195.com +cd58.com +cd6.com +cd658ad6a610b9a5.com +cd7a871ab11011.beer +cd7yy.com +cdabon.com +cdacz.com +cdadata.com +cdadsj.com +cdairport.com +cdajcx.com +cdajzp.com +cdamdi.com +cdanet.org +cdangel.com +cdapex.com +cdaten.com +cdb-leasing.com +cdbaidu.com +cdbdsec.com +cdbfb.net +cdbokon.com +cdborz.com +cdbsdyk.com +cdbsfund.com +cdc80b3514292771.com +cdcbj.com +cdcbn.com +cdcc.ink +cdccic.com +cdccpit.org +cdcea.org +cdcgames.net +cdchjyy.com +cdchuandong.com +cdcitypark.com +cdcoslm.com +cdcxhl.com +cdcyts.com +cddayun.com +cddc56.com +cddengji.com +cddgg.com +cddgg.net +cddjip.com +cddlhx.com +cddlkj.net +cddq120.com +cddscj.com +cddsgk.com +cde-os.com +cdea4d2cb10261.beer +cdeaa.com +cded23c0b11011.beer +cdedu.com +cdeledu.com +cdenvironment.com +cdfanmu.com +cdfcjg.com +cdfcn.com +cdfeimi.com +cdfer.com +cdfgsanya.com +cdfgt.com +cdfhnmall.com +cdfhnms.com +cdfinger.com +cdfmembers.com +cdfortis.com +cdfsunrise.com +cdfuwuqi.com +cdgas.com +cdgdad.com +cdgdp.com +cdggq.com +cdggzy.com +cdgjbus.com +cdgmgd.com +cdgoufang.com +cdgowell.com +cdgql.com +cdgrf.com +cdgtw.net +cdgxfz.com +cdgxsyzx.com +cdgxxy.net +cdh3c.com +cdhaiguang.com +cdhfund.com +cdhglsc.com +cdhgr.com +cdhjsw.com +cdhke.com +cdhkxy.com +cdhld.com +cdhr.net +cdhrsip.org +cdhsgb.com +cdhtgroup.com +cdhtgs.com +cdhtrq.com +cdhuaying.com +cdhxdq.com +cdii-leasing.com +cdirs.com +cditv.tv +cdjcow.com +cdjfwy.com +cdjhqczl.com +cdjiaoan.com +cdjingfeng.com +cdjituan.com +cdjnrc.com +cdjsjlxh.com +cdjsjx.com +cdjtzhtc.com +cdjxjy.com +cdjzso.com +cdjzw.com +cdjzzg.com +cdkeynogap.com +cdkf.com +cdkjbg.com +cdkjw.org +cdks.run +cdkyfc.com +cdlaobing.com +cdlbmy.com +cdlbyl.com +cdlchd.com +cdlgp.com +cdliangwang.com +cdlingsou.com +cdlinux.net +cdlsym.com +cdlvbao.com +cdlxqn.com +cdmcaac.com +cdmddyf.com +cdmfund.org +cdmgiml.com +cdmhwh.com +cdmjwater.com +cdms-china.com +cdn-build.com +cdn-build.net +cdn-cba.com +cdn-cdn.net +cdn-dodo.com +cdn-gw-dv.net +cdn-hotels.com +cdn-speed.com +cdn-static.farfetch-contents.com +cdn-uc.cc +cdn-v.com +cdn-videos.akamaized.net +cdn.ampproject.org +cdn.angruo.com +cdn.fun +cdn.globalsigncdn.com.cdn.cloudflare.net +cdn.hkdtmb.com +cdn.ist +cdn.jetbrains.com +cdn.lilyemby.com +cdn.marketplaceimages.windowsphone.com +cdn.samsung.com +cdn.shanghai.nyu.edu +cdn.show +cdn.vin +cdn.zampdsp.com +cdn000.com +cdn08.com +cdn1.vip +cdn1008.com +cdn1218.com +cdn16.com +cdn20.com +cdn20.info +cdn20.org +cdn2000.com +cdn2020.com +cdn30.com +cdn30.info +cdn30.org +cdn3344.com +cdn35.com +cdn365gnlc.vip +cdn365lc.vip +cdn40.com +cdn50.com +cdn56.com +cdn60.com +cdn86.com +cdn86.net +cdn90.com +cdn90.net +cdn90.org +cdn99.com +cdnb.net +cdnbbb.net +cdnbuild.com +cdnbuild.net +cdnbye.com +cdnc.org +cdncache.com +cdncache.net +cdncdncdn.com +cdncenter.com +cdncg.com +cdnchatgpt.com +cdnchushou.com +cdncl.net +cdnclouds.net +cdncode.com +cdnczydwl.com +cdnddd.com +cdnddd.net +cdndm.com +cdndm5.com +cdndm5.net +cdndns.vip +cdndns1.com +cdndns2.com +cdndns2.net +cdndo.com +cdndoctor.com +cdndu.com +cdnet110.com +cdnetdns.net +cdnetgdns.com +cdnetworks.net +cdnexus.com +cdnf.cc +cdngia.com +cdngot.com +cdngslb.com +cdngslb8.com +cdngtm.com +cdnhhh.net +cdnhub.net +cdnhwc1.com +cdnhwc10.com +cdnhwc2.com +cdnhwc3.com +cdnhwc4.com +cdnhwc5.com +cdnhwc6.com +cdnhwc7.com +cdnhwc8.com +cdnhwc9.com +cdnhwcajk17.com +cdnhwcatq08.com +cdnhwcbni108.com +cdnhwcbqs106.com +cdnhwcbzj102.com +cdnhwcchh18.com +cdnhwccmz121.com +cdnhwcead111.com +cdnhwcedi10.com +cdnhwcedt124.com +cdnhwcggk22.com +cdnhwcgnc118.com +cdnhwcgqa21.com +cdnhwchcg02.com +cdnhwcibv122.com +cdnhwcick110.com +cdnhwcjlg112.com +cdnhwcjog12.com +cdnhwcjsb120.com +cdnhwckfz116.com +cdnhwckon103.com +cdnhwcljk104.com +cdnhwcllh11.com +cdnhwclxu105.com +cdnhwclxw05.com +cdnhwcoem01.com +cdnhwcohm19.com +cdnhwcoph123.com +cdnhwcprh113.com +cdnhwcpsd13.com +cdnhwcqgw115.com +cdnhwcqir15.com +cdnhwcqve117.com +cdnhwcqwg14.com +cdnhwctnm107.com +cdnhwctxz24.com +cdnhwcuim119.com +cdnhwcupf06.com +cdnhwcurq03.com +cdnhwcvix16.com +cdnhwcxcy07.com +cdnhwczba04.com +cdnhwczjt20.com +cdnhwczks109.com +cdnhwczmn114.com +cdnhwczth23.com +cdnhwcztu09.com +cdnhwczxh101.com +cdnidc.net +cdnjs8888.com +cdnjson.com +cdnjtzy.com +cdnkxy.com +cdnle.com +cdnle.net +cdnlinkcloud.com +cdnlinking.com +cdnmama.com +cdnmg.com +cdnnx.com +cdnok.com +cdnoutcheck.com +cdnpe.com +cdnqttdispatcher01.com +cdnsvc.com +cdntip.com +cdntipbak.com +cdntips.com +cdntips.net +cdntxt.com +cdnudns.com +cdnunion.com +cdnvp.com +cdnvpn.net +cdnvue.com +cdnwaf.net +cdnxcrpl.vip +cdnyoyun.com +cdnyt69.com +cdnyyds999.com +cdoers.com +cdpgroupltd.com +cdqcnt.com +cdqcp.com +cdqcw.net +cdqcxy.com +cdqczx.com +cdqmw.net +cdqph.com +cdqsng.com +cdqss.com +cdqszz.com +cdqzcz.com +cdrbs.net +cdrcb.com +cdren.net +cdrich.com +cdrjob.com +cdronghai.com +cdrqxh.com +cdrsigc.com +cdrtvu.com +cdruzhu.com +cds-seal.com +cdsb.com +cdsb.mobi +cdscdscdn.com +cdsenfa.com +cdsgsz.com +cdshangceng.com +cdshishi.net +cdshx.com +cdsixun.com +cdsjjy.com +cdsjtech.com +cdskdxyy.com +cdsledu.net +cdslsxh.com +cdslsxh.org +cdsme.com +cdsns.com +cdsnzx.com +cdspace.net +cdsslz.net +cdsuns.com +cdswjs.com +cdswx.net +cdsxdd.com +cdsxlc.com +cdt-ec.com +cdt-md.com +cdt-re.com +cdtcxh.org +cdtianda.com +cdtkdw.com +cdtlev.com +cdtlxx.net +cdtnrq.com +cdtszn.net +cdtyxx999.com +cdtz.net +cduncname.com +cdvcloud.com +cdvisor.com +cdwulian.com +cdxdyy.com +cdxrdz.com +cdxsxbx.com +cdxw.net +cdxwcx.com +cdxwxy.com +cdxydb.com +cdydlx.com +cdyee.com +cdyestar.com +cdyfy.com +cdygdq.com +cdyj56.com +cdylzx.net +cdynt.com +cdyouhui.com +cdyrjygs.com +cdysxx.com +cdysxy.com +cdyushun.com +cdyywz.com +cdyzhotel.com +cdzdgw.com +cdzgh.com +cdzgzs.com +cdzhuoyu.com +cdzimo.com +cdzixun.net +cdzjryb.com +cdzk.com +cdzk.net +cdzk.org +cdzls.net +cdzongtian.com +cdzp8.com +cdzrjdgc.com +cdzs.org +cdzuche.com +cdzvan.com +cdzxy.com +cdzzhn.com +ce-air.com +ce04.com +ce2293.com +ce247ce247.shop +cea45b9f61023.beer +ceacq.com +ceair.com +ceairdutyfree.com +ceairgroup.com +ceaj.org +ceamg.com +ceawgez.com +ceba.tech +cebbank.com +cebcn.com +cebike.com +ceblease.com +cebpubservice.com +cebu.vip +cecafdb.org +cecb2b.com +cecbh.com +cecc-cx.com +ceccen.com +cecdc.com +cece-mall.com +cece.com +cece.la +cecesat.com +cecewu.com +cecgw.com +cecgx.com +cechoice.com +cecisp.com +cecloud.com +cecloudcs.com +cecmath.com +cecom.cc +ceconline.com +ceconlinebbs.com +cecport.cc +cecport.com +cecxtal.com +ceda-fluid.com +cedachina.org +cedarhd.com +cedfxub.org +cediy.com +cedock.com +ceeger.com +ceegpower.com +ceeia.com +ceeji.net +ceepower.com +ceepsp.com +ceeunion.com +cef114.com +ceggd.com +cehiy.com +cehome.com +cehuan.com +cehuashen.com +cehui8.com +cei1958.com +ceiaec.org +ceibs.edu +ceibsonline.com +ceic.com +ceice.org +ceicloud.com +ceicsz.net +ceiea.com +ceigd.com +ceinettgt.com +ceitcl.com +cekeis.com +cekid.com +celebpalace.com +celebritywallpapershq.com +celgenpharm.com +celhr.com +celiang.net +celinlawyers.com +celiss.com +cell-gene.com +cell-origin.com +cellcook.com +cellixsoft.com +cellocation.com +cellprobio.com +cellprotek.com +cells-net.com +cells-net.net +cellwise-semi.com +celucasn.com +celwk.com +cemat-asia.com +cematsh.com +cement365.com +cementren.com +cemho.com +cemni.com +cemodule.com +cemsurveys.com +cemsurveys.net +cemyun.com +cen-li.com +cenano-china.com +cenbel.com +cenbest.com +cenboomh.com +cencimeter.com +cencs.com +cendes-arch.com +cengceng.chat +cengcloud.net +ceniiat.com +cenjiasu.com +cenkersz.com +cenn.com +cennjt.com +cenray-ic.com +censh.com +centainfo.com +centaland.com +centanet.com +centauriglobal.com +centbrowser.net +centec.com +cententcymbals.com +centerm.com +centit.com +centong.com +centos.bz +centralchina.com +centralsolomon.com +centrechina.com +centricsoftwarechina.com +centrincloud.com +centrixlink.com +centrmus.com +centroidtec.com +centrostuditaliani.com +century-carrier.com +century-cn.com +century21cn.com +centurycreation.com +centuryenglish.com +centurystar.net +centurytrip.com +cenuan.com +cenvan.net +cenvandns.com +cenwan.com +cenwaymaterials.com +cenwor.com +cenwoy.com +cenxilm.com +cenxinews.com +cenya.com +ceobiao.com +ceoeo.com +ceoim.com +ceolaws.net +ceolearn.com +ceook.com +ceotx.com +ceowww.com +ceoxq.com +ceozero.com +cepark.com +cepea.com +cepeta.com +cepin.com +ceping.com +ceping365.com +cepmh.com +ceppea.net +ceppedu.com +ceprei.com +ceprei.org +cer.net +ceracdn.net +ceradir.com +cerambath.org +ceramicschina.com +ceramsoc.com +cercg.com +cere.cc +cerestools.com +cernet.com +cernet.net +cernet2.net +cersign.com +cersp.com +certicn.com +certificatey.com +ces-transaction.com +cese2.com +cesfn.com +cesfutures.com +ceshanmi.com +ceshi.com +ceshi112.com +ceshigo.com +ceshigu.com +ceshiren.com +cesinet.com +cesipc.com +cesko-dl.com +cespc.com +cestco.com +cesu.net +cetanfa.wiki +cetc33.com +cetc52.com +cetc55.com +cetccloud.com +cetceg.com +cetcio.com +cetcmotor.com +cetcssi.com +cetgps.com +cethik.com +cetkmh.com +cetsteam.com +cetzig.com +ceultimate.com +ceve-market.org +cevsn.com +cewud.com +ceydz.com +ceyice.net +ceyige.com +cezhu.net +cf-china.info +cf-ns.com +cf-ns.net +cf-ns.site +cf-ns.tech +cf01e170e475757b.com +cf115.com +cf69.com +cf6ea43741014.beer +cf8587a521017.beer +cfachina.org +cfanlost.com +cfb30e2181013.beer +cfbond.com +cfc365.com +cfca-c.org +cfccd.com +cfcf1958.com +cfchem.com +cfchi.com +cfchint.com +cfcpn.com +cfd-china.com +cfd163.com +cfdp.org +cfdwater.com +cfecq.com +cfedu.net +cfei.net +cfej.net +cfeks.com +cffote.com +cfgbj.com +cfgfr.com +cfgjwl.com +cfgpu.com +cfgyp.com +cfhfz.com +cfhi.com +cfhpc.org +cfhuodong.cc +cfhuodong.com +cfido.com +cfiec.net +cfimg.com +cfishsoft.com +cfjbqc.com +cfjqr.com +cfjzyxh.com +cfkjgx.com +cflab.net +cfldcn.com +cflm.com +cflpla.com +cfluid.com +cfm119.com +cfmcc.com +cfmeutencent.com +cfmmc.com +cfmna-tencent.com +cfmoto.com +cfmseatencent.com +cfnotes.com +cfoft.online +cfogc.com +cfogc.net +cfpa.team +cfrlr.com +cfsbcn.com +cfscar.com +cfsggjt.com +cfsino.com +cfss.cc +cfsuper.com +cftcredit.com +cftea.com +cftecgroup.com +cftest7.com +cftest8.com +cftsupport.com +cftzqinzhou.com +cfucn.com +cfunctions.com +cfund108.com +cfuture.shop +cfvvv.com +cfxydefsyy.com +cfxyfsyy.com +cfxyjy.com +cfyedu.com +cfyy.cc +cfyygf.com +cfyzs.com +cfzpw.com +cfzq.com +cfztq.com +cg-ku.com +cg-orz.com +cg-schools.com +cg009.com +cg100iii.com +cg1993.com +cg3da.com +cg98.com +cg99.com +cgacar.com +cgadmob.com +cgahz.com +cgames.com +cgangs.com +cgboo.com +cgbtek.com +cgc.press +cgcable.com +cgcss.com +cgdbia.com +cgdeuvip.com +cgdg.com +cgdown.com +cgebio.com +cgebook.com +cgeinc.com +cgejournal.com +cger.com +cgguy.com +cggygs.com +cghhospital.org +cghospital.com +cgicop.com +cgiia.com +cgiumuo.xyz +cgjoy.com +cgjoy.net +cgke.com +cgkjvip.com +cgksw.com +cgktudr.xyz +cgl.cc +cglw.com +cglzw.net +cgmama.com +cgmantou.com +cgmao.com +cgmcc.net +cgmjh.com +cgmodel.com +cgmol.com +cgmxw.com +cgnei.com +cgnjy.com +cgnmc.com +cgnne.com +cgntv-glive.ofsdelivery.net +cgoec-tencentclb.cloud +cgoec-tencentclb.com +cgoec-tencentclb.net +cgoec-tencentclb.work +cgonet.com +cgowater.com +cgown.com +cgpbatech.com +cgplayer.com +cgplusplus.com +cgreentown.com +cgris.net +cgrpark.com +cgrzzl.com +cgsec.com +cgsfusion.com +cgsoft.net +cgtblog.com +cgtn.com +cgtsg.com +cgtsj.com +cgtsj.org +cgtyhk.com +cgtz.com +cguardian.com +cgufo.com +cguiw.com +cgutech.com +cgvoo.com +cgwang.com +cgwenjian.com +cgwic.com +cgws.com +cgxcig.net +cgxdm.com +cgxia.com +cgxlzdm.com +cgxm.net +cgylke.com +cgylw.com +cgyou.com +cgyouxi.com +cgyu.com +cgzair.com +cgzj.com +cgzy.net +cgzyw.com +ch-auto.com +ch-chip.com +ch-gk.com +ch-guerrant.com +ch-tools.com +ch-water.com +ch.com +ch028.net +ch12333.com +ch6k5zd77f.com +ch9888.com +ch999.com +ch999img.com +cha-china.org +cha-tm.com +cha127.com +cha138.com +chaba123.com +chabansheng.com +chabeichong.com +chacd.com +chacewang.com +chacha.com +chachaba.com +chachawenshu.com +chache-cn.com +chache808.com +chacheku.com +chachengji.com +chacihai.com +chacuo.net +chadianhua.net +chadoc.com +chaej.com +chafanhou.com +chafei.net +chagee.com +chaguan.center +chahua.org +chahui.com +chahuo.com +chaic.com +chaichefang.com +chaiderl.com +chaiding.com +chaidongpower.com +chaihezi.com +chaijing.com +chaimage.com +chain.cc +chain56.com +chaincar.com +chaincatcher.com +chaindd.com +chainedbox.com +chainhd.com +chainknow.com +chainlinkpcp.com +chainlinkwork.com +chainnode.com +chainpharm.com +chainsql.net +chaint.net +chainwinlaw.com +chaiqian88.com +chaishiguan.com +chaitin.com +chaizz.com +chajiage.com +chajian5.com +chajiandaquan.com +chajianxw.com +chajiayuan.com +chajie.com +chajn.org +chakahao.com +chakahui.com +chakonghao.com +chakuaizhao.com +chalaili.com +chalangautozone.com +chalaoshi.de +chalcochem.com +chalieco.com +challenge-21c.com +challenge-design.com +chalwin.com +chamcfae.com +chamei.com +chameiwang.com +chamfond.com +chamiji.com +champconsult.com +champion-ic.com +championasia.hk +championmkt.com +championunion.com +champsely.com +chan.ink +chancel.ltd +chandao.net +chandashi.com +chandi.biz +chandixiu.com +chanfine.com +chang-xiang.com +changan.biz +changancap.com +changanfunds.com +changanren.com +changantaihe.com +changba-ktv.com +changba.com +changbaapi.com +changbaapp.com +changbaimg.com +changbalive.com +changbiyuan.com +changchun-ccpit.com +changchunmarathon.com +changchunwater.com +changda.life +changdaore.com +changdunovel.com +changergroup.com +changfa.com +changfaproperties.com +changfaqifu.com +changfengpacking.com +changfengsteeltube.com +changfon.com +changhaigfrp.com +changhe-suzuki.com +changhe.com +changhe.tech +changheauto.com +changhedayun.com +changheng88.com +changhong-network.com +changhong.com +changhongit.com +changhongnetwork.net +changhu12333.com +changhualaw.com +changhuist.com +changingie.com +changingtek.com +changjiangdata.com +changjiangjin.com +changjiangtimes.com +changjianxy.com +changjingtong.com +changjiulogistics.com +changjiuqiche.com +changker.com +changkezhe.com +changlipeixun.com +changliuabc.com +changloong.com +changloong.net +changmengyun.com +changning.net +changpingquzhongxiyijieheyiyuan.com +changpu3d.com +changqingshu.net +changqu.cc +changshabdc.com +changshang.com +changshaship.com +changshatong.com +changshazrkj.com +changshengmobi.com +changshengshangye.com +changshengyiliao.com +changshiban.com +changshizu.com +changshouchemgroup.com +changshu-marathon.com +changshunhuojia.com +changtong2800.com +changtounet.com +changtubus.com +changuanjia.com +changwang.com +changwankeji.com +changwei.asia +changx.com +changxianchem.com +changxiao.co +changxiaow.com +changxie.com +changxingyun.com +changxuew.com +changyan.com +changyegroup.com +changyifan.com +changyin-lab.com +changying.com +changyizu.com +changyonggame.com +changyou.com +changyoyo.com +changyuangroup.com +changyudz.com +changyushengwu.com +changzhinews.com +chanjet.com +chanjue.net +chanluntan.com +chanmama.com +channelbeyond.com +channellive.leshantv.net +channingsun.bid +chanpay.com +chanpin100.com +chanpindashi.com +chansemt.com +chanshi.vip +chanway.net +chanwind.com +chanxuan.com +chanxuehezuo.com +chanzhi.org +chao-cn.com +chao-fan.com +chaoan.chaoantv.com +chaoart.com +chaobohui.com +chaodamould.com +chaodavalves.com +chaodu123.com +chaofan.com +chaofanlin.com +chaofanshuma.com +chaofantian.com +chaoge.press +chaogejiaoyu.com +chaogu1688.com +chaohuatech.com +chaohuishou.com +chaoji.com +chaojibiaodan.com +chaojibiaoge.com +chaojibuy.com +chaojicdn.com +chaojifan.com +chaojihetong.com +chaojijianli.com +chaojiping.homes +chaojituzi.net +chaojiying.com +chaojiyun.com +chaokaixin.net +chaolean.com +chaoliangkj.com +chaoliuguan.com +chaolongbus.com +chaoluoluo.com +chaonanclub.com +chaonanrc.com +chaonei.com +chaopaiyizu.com +chaopx.com +chaoren.com +chaoschina.com +chaosec.com +chaoshanren.com +chaoshen.cc +chaoshengboliuliangji.com +chaoshengxin.com +chaoshi168.com +chaosqh.com +chaosw.com +chaov.com +chaowanjoy.com +chaoweb.com +chaowei-machine.com +chaoxibiao.net +chaoxin.com +chaoxing.cc +chaoxing.com +chaoxingv.com +chaoyang.com +chaoyi996.com +chaoyinjiu.com +chaoyuesd.com +chaozhenht.com +chaozhoudaily.com +chaozhouyin.com +chaozuo.com +chapangzhan.com +chapaofan.com +chaping.tv +chappell1811.com +char123.com +charcaius.com +charge-mobile.com +chargedot.com +chargerlab.com +chargerlink.com +chariotpharm.com +charlinserver.online +charllena.com +charlottedaviesrmt.com +charlsdata.com +charmdeer.com +charmingglobe.com +charmkeytextile.com +charmsunfund.com +chartboost-china.com +chase-secure55.wiki +chasedorisu.com +chaseyanyu.net +chashebao.com +chashudi.com +chat12m.cfd +chat14da.cfd +chat2db-ai.com +chat778.com +chatairc.com +chatanywhere.tech +chatartpro.com +chateaustarriver.com +chatglm.site +chatgptboke.com +chatm.com +chatmindai.net +chatnos.com +chatqp.net +chatvgx.com +chatyygpt.com +chawo.com +chaxiaow.com +chaxinyu.net +chaxun.biz +chaxunchina.com +chaxunfapiao.com +chaxunjiao.com +chayanfamily.com +chayangge.com +chaye.com +chayeo.com +chayu.com +chayueshebao.com +chayuqing.com +chaz.fun +chazhengla.com +chazidian.com +chaziyu.com +chazuo.com +chazuo.net +chazuowang.com +chbcnet.com +chbdunt.com +chblt.com +chbml.com +chbpp.com +chce-expo.com +chcedo.com +chceg.com +chceshi001.com +chcmu.com +chcnav.com +chcoin.com +chcompass.com +chcontrol.com +chcpay.com +chda.net +chdajob.com +chdelphin.com +chdies.com +chdmc.com +chdqyy.com +chdtp.com +che-shijie.com +che-youhui.com +che.com +che0.com +che101.com +che168.com +che168.net +che2.com +che300.com +che314.com +che777.com +cheaa.com +cheaa.org +cheaca.org +cheapdoma.com +cheaphost.me +cheapreplicawatch.com +cheapviagraws.com +cheapyou.com +cheari.com +cheasa.org +cheatmaker.org +chebaba.com +chebada.com +chebaipishu.com +chebianjie.com +chebianjie.net +chebiao.cc +chebiao.net +chebrake.com +checar.mobi +chechakj.com +chechaoxue.com +checheng.com +chechong.com +chechuan.com +checi.org +check.cc +checkaigc.com +checkip.pw +checkmath.net +checkoo.com +checkpass.net +checkzeit.com +checkzoo.com +checom.net +chediandian.com +chedongxi.com +cheduo.com +cheegu.com +cheerfun.dev +cheerjoy.com +cheersee.com +cheersofa.com +cheerspublishing.com +cheersson.com +cheertech.ltd +cheerycouture.com +cheetahfun.com +cheetahgames.com +cheetahgo.net +cheetahmobile.com +chefafa.com +chefugao.com +cheguo.com +chegva.com +chehang168.com +chehejia.com +chehui.com +cheil.site +chejianding.com +chejingjie.com +chekuaipai.com +chelajanitorial.com +chelangauto.com +chelifang.com +chelink.com +chellex.com +chelun.com +chem-stone.com +chem17.com +chem234.com +chem31.com +chem36.com +chem365.net +chem366.com +chem960.com +chem99.com +chemalink.net +chemao.com +chembeango.com +chembible.com +chembk.com +chemcd.com +chemchina.com +chemcp.com +chemcyber.com +chemdodgen.com +chemdrug.com +chememall.com +chemfish.com +chemgogo.com +chemi-tech.com +chemicalbook.com +chemicalreagent.com +chemingpian.com +chemishequ.com +chemm.com +chemmade.com +chemmerce.com +chemmuseum.com +chemnet.com +chemourscg.com +chempacific-china.com +chemptc.com +chemrc.com +chemsrc.com +chemtour.com +chemwells.com +chemwith.com +chemyouth.com +chemyq.com +chen-design.com +chen.fun +chenag.com +chenall.net +chenapp.com +chenbo.info +chenduaomei.com +chener.net +chenfan.info +cheng-sen.com +cheng.xin +chengaizixun.com +chengan-web.com +chengan.tech +chengbanggroup.com +chengcai.net +chengchuanren.com +chengde-jz.com +chengdebank.com +chengdegj.com +chengdegroup.com +chengdewater.com +chengdu-expat.com +chengduair.com +chengdubao.com +chengdufanyi.com +chengdun.com +chengdurail.com +chengduzhishang.com +chengegeya.com +chenger0711.com +chengezhao.com +chengfankj.com +chengfeilong.com +chengfengboli.com +chengfengerlai.com +chenggnet.com +chenggongguiji.com +chenghai.cc +chenghct.com +chenghen.com +chenghua888.com +chenghuijituan.com +chenghuiqian.xyz +chengji-inc.com +chengjianjituan.com +chengjing.com +chengjinholdinggroup.com +chengkao365.com +chenglang.net +chenglangyun.com +chenglil.com +chenglin.name +chenglinpak.com +chenglispv.com +chengliwang.com +chengloongcishan.org +chenglou.net +chengmei.games +chengmeiyouxuan.com +chengpeiquan.com +chengrang.com +chengrengaokaobaoming.com +chengrenjiaoyu1.com +chengruide.com +chengshan.com +chengshidingxiang.com +chengshiguanjia.com +chengshijun.com +chengshu.com +chengsmart.com +chengtaijiaju.com +chengtay.com +chengtianxiajy.com +chengtiexinxi.com +chengtongjz.com +chengtu.com +chengwei.com +chengweitx.com +chengxiangqian.com +chengxiangzhineng.com +chengxiaoliu.com +chengxingjicj.com +chengxinyouxuan.com +chengxua.com +chengxuan.com +chengyangyang.com +chengye-capital.com +chengyi.press +chengyitex.com +chengyouyun.com +chengyuanwenquan.com +chengyucidian.net +chengyun.com +chengyuwan.com +chengzhaoxi.xyz +chengzhinj.com +chengzijianzhan.com +chengzivr.com +chenhe.cc +chenhe.me +chenhr.com +chenhuangxun.com +chenhui.org +chenjia.me +chenjiehua.me +chenjinghealth.com +chenjt.com +chenkeiot.com +chenksoft.com +chenlb.com +chenlianfu.com +chenliangroup.com +chenlinux.com +chenlinzuwu.com +chenlong.com +chenmingpaper.com +chenmomo.com +chennianyoupin.com +chenpe.com +chenplus.com +chenpon.com +chenpot.com +chenroot.com +chenruixuan.com +chenruo.net +chens.life +chenshipin.com +chensuyang.com +chenva.com +chenwenwl.com +chenxiao.cc +chenxin99.com +chenxinghb.com +chenxingweb.com +chenxisoft.com +chenxm.cc +chenxuehu.com +chenxuhou.com +chenxunyun.com +cheny.org +chenyang.com +chenyanghg.com +chenyea.com +chenyifaer67373.com +chenyistyle.com +chenyongqi.com +chenyou123.com +chenyu.me +chenyudong.com +chenyuemz.com +chenyuwulian.com +chenyuxia.com +chenyyds.com +chenzao.com +chenzhicheng.com +chenzhongkj.com +chenzhongtech.com +cheonhyeong.com +cheoo.com +cheoz.com +cherentec.com +cheriexsky.love +cherry-ai.com +chervonauto.com +chervongroup.com +cheryholding.com +cheryjaguarlandrover.com +cherylalopes.com +cherymanuals.com +cheshenghuo.com +cheshi-img.com +cheshi.com +cheshi111.com +cheshi18.com +cheshijie.com +cheshipin.com +cheshirex.com +cheshizh.com +chesicc.com +chesicc.net +chesir.com +chesir.net +chesono.com +chessease.net +chestercharles.com +chesthospital.com +chesudi.com +chetiansi.com +chetodeng.com +chetuanwang.net +chetuobang.com +chetx.com +chetxia.com +chetxt.com +chevip.com +chevlen.com +cheweiguanjia.com +chewen.com +chewulin.com +chexian9.com +chexiancha.com +chexiang.com +chexiaoliang.net +chexinmeng.com +chexiu.com +chextx.com +chexun.com +chexun.net +cheyaoshi.com +cheyian.com +cheyipai.com +cheyishang.com +cheyisou.com +cheyou123.com +cheyuan.com +cheyun.com +cheyuu.com +chezhanri.com +chezhibao.com +chezhubidu.com +chezhutech.com +chezhuzhinan.com +chezizhu.com +chezvi.com +chfsmartad.com +chgcw.com +chghouse.org +chgi.net +chgie.com +chglmp.com +chgreenway.com +chgry.com +chgzfls.com +chhqtest.com +chhua.com +chhuc.org +chhw.com +chhzm.com +chi2ko.com +chi588.com +chi86.com +chianbaohan.com +chibanting.com +chichuang.com +chickfrp.com +chiconysquare.com +chicopharm.com +chida.org +chidafeiji.com +chidaolian.com +chidaoni.com +chidaoni.net +chidaotv.com +chidd.net +chidowl.com +chidudata.com +chidutech.com +chiefmore.com +chiefpharma.com +chieftin.org +chietom.com +chihao.com +chihe.so +chihealbio.com +chiheba.com +chiheshan.com +chihkao.com +chihm.com +chiji-h5.com +chiji.app +childjia.com +childlib.org +childrentheatre.org +chileaf.com +chili3d.com +chillyroom.com +chilwee.com +chimboon.com +chimbusco.com +chimelong.com +chimezi.com +chimoph.com +chin-fine.com +china-10.com +china-3.com +china-315.com +china-aa.org +china-ah.com +china-anhe.com +china-asahi.com +china-aseanbis.com +china-audit.com +china-autotech.com +china-b.com +china-baiyun.com +china-bdh.com +china-bee.com +china-bicycle.com +china-biding.com +china-bluestar.com +china-bme.com +china-borun.com +china-boy.org +china-boya.com +china-caihua.com +china-cale.com +china-capsule.com +china-cas.org +china-cba.net +china-cbn.com +china-cbs.com +china-ccc.org +china-ccie.com +china-ccii.com +china-ccw.com +china-cdig.com +china-cdt.com +china-ceco.com +china-ced.com +china-ceec-cooperation.com +china-cet.com +china-cfa.org +china-chair.com +china-channel.com +china-chca.org +china-chigo.com +china-cicc.org +china-citytour.com +china-clearing.com +china-cloud.com +china-cmca.org +china-cmd.org +china-cnic.com +china-co.com +china-coc.org +china-consulate.org +china-core.com +china-cotton.org +china-cpu.co +china-cpu.com +china-cri.com +china-csm.org +china-cssc.org +china-denox.com +china-designer.com +china-dingjie.com +china-drama.com +china-drm.net +china-dt.com +china-dtv.com +china-eaea.com +china-ecee.com +china-eia.com +china-embassy.org +china-engine.net +china-entercom.com +china-enterprise.com +china-epa.com +china-erzhong.com +china-fangyuan.com +china-fei.com +china-feininger.com +china-fire.com +china-fishery.com +china-flash.com +china-flower.com +china-futian.com +china-g.com +china-galaxy-inv.com +china-gehang.com +china-genius.com +china-gg.com +china-giant.com +china-gnd.com +china-goffen.com +china-gold.com +china-goldcard.com +china-greenfund.com +china-greenlighting.com +china-gwy.com +china-hechang.com +china-hengyuan.com +china-hhsj.com +china-highway.com +china-holiday.com +china-hongfei.com +china-house.com +china-hp.com +china-hrg.com +china-htdl.com +china-huamin.com +china-huazhou.com +china-hulong.com +china-hushan.com +china-hxzb.com +china-hzd.com +china-iace.com +china-ida.com +china-inse.com +china-invests.net +china-ipif.com +china-isotope.com +china-j.com +china-jianan.com +china-jinlong.com +china-jit.com +china-jlt.com +china-jm.org +china-jxcf.com +china-kaidiwt.com +china-kaihua.com +china-kaoshi.com +china-key.com +china-khgroup.com +china-kids-expo.com +china-kids-fair.com +china-kingmold.com +china-knobs.com +china-lantu.com +china-latv.com +china-lawoffice.com +china-led.net +china-light-guides.com +china-lithium.com +china-liye.com +china-logistics.com +china-longgong.com +china-lottery.net +china-lsh.com +china-m2m.com +china-mcc.com +china-mile.com +china-moutai.com +china-mt.org +china-mx.net +china-nengyuan.com +china-nlp.com +china-nns.com +china-norbin.com +china-npa.org +china-nsftz.com +china-obgyn.net +china-office-solutions.com +china-orientgroup.com +china-oulu.com +china-pa.org +china-packcon.com +china-payments.com +china-pcba.com +china-pengye.com +china-pharmacy.com +china-pinyuan.com +china-planet.com +china-pub.com +china-qiao.com +china-qjbz.org +china-radiology.com +china-re.net +china-refrigerants.com +china-ric.com +china-riscv.com +china-russia.org +china-sand.com +china-sce.com +china-sea.net +china-season.com +china-security.com +china-see.com +china-seeq.com +china-sfc.com +china-shancun.com +china-shimo.com +china-shjyx.com +china-shufan.com +china-shugaung.net +china-sites.com +china-slate.com +china-smartech.com +china-sorsa.org +china-soyea.com +china-spirulina.net +china-springs.com +china-sss.com +china-stainless.com +china-sunshine.com +china-sz.com +china-thk.com +china-tin.com +china-tisense.com +china-tje.com +china-tongyu.com +china-topplus.com +china-tops.com +china-tower.com +china-toy-expo.com +china-train.net +china-tsac.com +china-uju.com +china-up.com +china-valve.com +china-vcom.com +china-vision.org +china-vn.com +china-vo.org +china-wanlin.com +china-warping.com +china-waste.com +china-weldnet.com +china-whwaterexpo.com +china-ws.org +china-wss.com +china-xb.com +china-xcsy.com +china-xian.com +china-xiba.com +china-xiuzheng.com +china-xzgec.com +china-xzkg.com +china-yaguang.com +china-yansheng.com +china-yd.com +china-yiang.com +china-yida.com +china-yinda.com +china-yintai.com +china-yongfeng.com +china-yt-expo.com +china-yuanfang.com +china-yuli.com +china-yxt.com +china-zbycg.com +china-zeiss.com +china-zhongda.net +china-zikao.com +china-zjj.net +china-zrg.com +china-zysj.com +china.com +china.mintel.com +china000799.com +china001.com +china12345.net +china12365.com +china124.com +china17.net +china1baogao.com +china1f.com +china2000.org +china3-15.com +china30s.com +china35.com +china356.com +china3gpp.com +china4a.org +china5e.com +china60.com +china6688.com +china724.com +china777.org +china918.org +china95.com +china95.net +china95.xyz +china9y.com +chinaab.com +chinaacc.com +chinaacme.net +chinaacryl.com +chinaadec.com +chinaadren.com +chinaadvance.com +chinaaeri.com +chinaaet.com +chinaagrisci.com +chinaags.net +chinaagv.com +chinaahth.com +chinaairer.com +chinaamc.com +chinaant.com +chinaant.net +chinaarabcf.org +chinaaris.com +chinaartificialstone.com +chinaasaservice.com +chinaasc.org +chinaaseanenv.org +chinaaseanfertilizer.com +chinaasic.com +chinaath.com +chinaautoms.com +chinaautoregs.com +chinaautosupplier.com +chinaave.org +chinaaviationdaily.com +chinab4c.com +chinababy365.com +chinabac.com +chinabaike.com +chinabaiker.com +chinabancai.com +chinabaoan.com +chinabaogao.com +chinabashan.com +chinabattery.org +chinabbtravel.com +chinabdh.com +chinabeego.com +chinabeer.net +chinabencaogangmu.com +chinabenson.com +chinabesteasy.com +chinabeston.com +chinabeverage.org +chinabgao.com +chinabge.com +chinabid315.com +chinabidding.cc +chinabidding.com +chinabiddingzb.com +chinabigdata.com +chinabigwin.com +chinabike.net +chinabim.com +chinabird.org +chinablackcat.com +chinablowers.com +chinabmi.com +chinabn.org +chinabooktrading.com +chinaboyun.com +chinabreed.com +chinabrightstone.com +chinabsb.com +chinabuildingcentre.com +chinabulk.com +chinabus.info +chinabuses.com +chinabuy1002.com +chinabxwx.com +chinabym.com +chinabyte.com +chinabzp.com +chinac.com +chinac3.com +chinacable.com +chinacace.org +chinacache.com +chinacache.net +chinacacm.org +chinacaj.net +chinacamel.com +chinacapac.com +chinacapg.com +chinacarbide.com +chinacars.com +chinacasa.org +chinacatel.com +chinacba.org +chinaccia.com +chinaccm.com +chinaccsi.com +chinacct.org +chinacdc.com +chinacdnb2b.com +chinacelacforum.org +chinacenn.com +chinacentrifuge.com +chinaceot.com +chinaceotv.com +chinacfa.com +chinacfi.net +chinacfo.net +chinacft.org +chinacge.com +chinachangbo.com +chinachangfang.com +chinachant.com +chinachaoyang.com +chinacharityfederation.org +chinachemnet.com +chinachild.org +chinachina.net +chinachugui.com +chinachuntian.com +chinacib.com +chinacid.org +chinacie.org +chinacil.com +chinacir.com +chinacity.net +chinacitywater.org +chinacld.com +chinaclean.org +chinacleanexpo.com +chinacljt.com +chinacma.org +chinacmo.com +chinacoal.com +chinacoatingnet.com +chinacoffee.vip +chinacomix.com +chinaconch.com +chinacondiment.com +chinaconsulatesf.org +chinaconsun.com +chinaconveyor.com +chinacordblood.org +chinacosco.com +chinacourt.org +chinacpda.com +chinacpda.org +chinacqme.com +chinacqpgx.com +chinacqsb.com +chinacraa.org +chinacrane.net +chinacrankshaft.com +chinacreator.com +chinacrops.org +chinacrosspoint.com +chinacrt.com +chinacses.org +chinacsf.com +chinactv.com +chinaculture.org +chinacustomsdata.com +chinacxjs.org +chinacyx.com +chinadachi.com +chinadafen.com +chinadafeng.com +chinadaily.net +chinadailyglobal.com +chinadais.net +chinadaja.com +chinadance.com +chinadart.com +chinadas.net +chinadatapay.com +chinadatatrading.com +chinadbs.com +chinaddn.com +chinaddos.com +chinadds.net +chinadentalshow.com +chinadep.com +chinadewei.com +chinadforce.com +chinadianji.com +chinadianming.com +chinadidao.com +chinadipl.com +chinadjba.com +chinadkec.com +chinadmoz.org +chinadns.com +chinadns.org +chinadongchu.com +chinadougong.com +chinadra.com +chinadrtv.com +chinadrum.net +chinadsl.net +chinaduo.com +chinadyt.com +chinadz.com +chinadzfp.com +chinadzyl.com +chinae.net +chinaeastlaw.com +chinaebizal.com +chinaebr.com +chinaecnet.com +chinaeda.org +chinaedu.com +chinaedu.net +chinaedunet.com +chinaedunewsw.com +chinaefu.net +chinaega.com +chinaehs.net +chinaeia.org +chinaeinet.com +chinaeinv.com +chinaejiao.com +chinaembassy.at +chinaepoxy.com +chinaepu.com +chinaequity.net +chinaerdos.com +chinaerospace.com +chinaesf.net +chinaeshare.com +chinaesm.com +chinaet.net +chinaev100.com +chinaeve.com +chinaexam.org +chinaexpo365.com +chinaexpressair.com +chinafa.org +chinafangxing.com +chinafarad.com +chinafarming.com +chinafashionbao.com +chinafasten.com +chinafastpcb.com +chinafbdq.com +chinafcx.com +chinafeiting.com +chinafert-gov.com +chinaffmpeg.com +chinafga.org +chinafiber.com +chinafic.org +chinafilm.com +chinafilmhy.com +chinafilms.net +chinafinancenet.com +chinafinanceonline.com +chinafininfo.com +chinafishtv.com +chinafix.com +chinaflashmarket.com +chinaflier.com +chinafolklore.org +chinafoma.com +chinafoodj.com +chinafoodsltd.com +chinaforklift.com +chinafpd.net +chinafph.com +chinafpma.org +chinafranchiseexpo.com +chinafruitime.com +chinafsl.com +chinaftat.org +chinafuda.com +chinafudaoban.com +chinafumao.com +chinafxd.com +chinafxkj.com +chinag.pro +chinagames.net +chinagayles.com +chinagb.net +chinagb.org +chinagba.com +chinagcl.com +chinagdda.com +chinagdn.com +chinaghwl.com +chinagiftsfair.com +chinaglassnet.com +chinagoldcoin.net +chinagoldgroup.com +chinagongcheng.com +chinagoods.com +chinagosun.com +chinagp.net +chinagpay.com +chinagps.cc +chinagrandauto.com +chinagrandinc.com +chinagrazia.com +chinagreenbio.com +chinagreentown.com +chinagrid.net +chinagrowthcapital.com +chinagslb.com +chinagslb.net +chinagsrc.com +chinagungho.org +chinaguohuan.com +chinaguyao.com +chinagwy.com +chinagwy.net +chinagwy.org +chinagwyw.org +chinagzn.com +chinahacker.com +chinahaixun.com +chinaham.com +chinahanang.com +chinahao.com +chinahaochuan.com +chinaharp.com +chinahazelnut.com +chinahbj.com +chinahbjob.com +chinahengying.com +chinahho.com +chinahhxh.com +chinahighnew.com +chinahightech.com +chinahighto.com +chinahighway.com +chinahiron.com +chinahiron.ltd +chinahiyou.com +chinahj.club +chinahkidc.net +chinahky.com +chinahnjs.com +chinahongdu.net +chinahonghui.net +chinahongying.com +chinahorologe.com +chinahorse.org +chinahosesupply.com +chinahotelgz.com +chinahpa.org +chinahqjjw.com +chinahr.com +chinahrd.net +chinahrt.com +chinahsdp.com +chinahte.com +chinahtz.com +chinahualai.com +chinahuashan.com +chinahuaxicun.com +chinahuaxue.com +chinahuben.com +chinahudong.com +chinahugong.com +chinahuizhanjie.com +chinahumo.com +chinahvacr.com +chinahw.net +chinahylq.com +chinahyyj.com +chinahzkj.com +chinaiat.com +chinaiatb.org +chinaidcnet.com +chinaidcnet.net +chinaido.com +chinaidr.com +chinaief.net +chinaielts.org +chinaiern.com +chinaiia.org +chinaiiss.org +chinainfoseek.com +chinainout.com +chinainput.net +chinainsbrokers.com +chinaiol.com +chinaiprlaw.com +chinairn.com +chinairport.net +chinait.vip +chinaitcapital.com +chinaitlab.com +chinaiut.com +chinajan.com +chinajcz.com +chinajeweler.com +chinajfj.com +chinajienuo.com +chinajierda.com +chinajinguo.com +chinajinlong.com +chinajinsheng.com +chinajinzhan.com +chinajinzhou.com +chinajiuquan.com +chinajj.org +chinajjz.com +chinajnhb.com +chinajoiner.net +chinajorson.net +chinajoy.net +chinajs120.com +chinajsc.com +chinajsjmxh.com +chinajsxx.com +chinajungong.com +chinajuva.com +chinajyhj.com +chinajyjxh.com +chinajyxdh.com +chinajyy.net +chinajzqc.com +chinakab.com +chinakangping.com +chinakangyue.com +chinakaoyan.com +chinakeon.com +chinakewei.com +chinakidville.com +chinakiln.net +chinakingho.com +chinakingland.com +chinakingo.com +chinakinzo.com +chinaklb.com +chinakong.com +chinakongzi.org +chinakqn.com +chinakshx.com +chinaksi.com +chinakuangshi.com +chinakyzl.com +chinalabexpo.com +chinalabs.com +chinalahigh.com +chinalancoo.com +chinalandpress.com +chinalanhua.com +chinalao.com +chinalaobao.com +chinalawbook.com +chinalawedu.com +chinalawinfo.com +chinalawyer.co +chinalawyeryn.com +chinaleather.com +chinaleather.org +chinaledger.com +chinalep.org +chinalibs.net +chinalicensing.org +chinalicensingexpo.com +chinalifang.com +chinalims.net +chinalingshan.com +chinalink.tv +chinalions.com +chinaliriver.com +chinalive.com +chinaliyou.com +chinalm.org +chinalonghu.com +chinalowcarb.com +chinalpharm.com +chinalsjt.com +chinalubricant.com +chinalulutong.com +chinalure.com +chinalushan.com +chinaluxury.net +chinalww.com +chinalxnet.com +chinamadas.com +chinamae.com +chinamags.org +chinamani.com +chinamaohong.com +chinamap.com +chinamaven.com +chinambn.com +chinamca.com +chinamcache.com +chinamcloud.com +chinamea.org +chinameat.net +chinamedicinej.com +chinamendu.com +chinamenwang.com +chinamerger.com +chinametro.net +chinameyer.com +chinamie.org +chinamingyan.net +chinamining.com +chinamission.be +chinamissun.com +chinamobile.com +chinamobiledevice.com +chinamobileltd.com +chinamost.net +chinamotian.com +chinamsa.org +chinamssp.com +chinamuscle.org +chinamusical.net +chinamwh.com +chinamworld.com +chinamypp.com +chinananda.com +chinananyang.com +chinanbb.com +chinanet-sh.com +chinanet.cc +chinanet88.com +chinanetcenter.com +chinanetidc.com +chinanetsun-dns.com +chinanetsun.com +chinanev.net +chinaneweast.com +chinanewera.com +chinanewkey.com +chinanews.com +chinanim.com +chinaningbo.com +chinanmi.com +chinanrb.com +chinanums.com +chinanwa.com +chinaobp.com +chinaoceanwide.com +chinaoct.com +chinaoly.com +chinaomp.com +chinaonebuild.com +chinaonstreetparking.com +chinaonward.net +chinaopc.org +chinaopen.com +chinaopticsvalley.com +chinaore.com +chinaorff.com +chinaorff.org +chinaorganicchem.com +chinaorientgroup.com +chinaott.com +chinaott.net +chinapag.com +chinapandi.com +chinapanocean.com +chinapantheum.com +chinapantom.com +chinapaper.net +chinaparking.org +chinapastel.com +chinapay.com +chinapayhongkong.com +chinapbw.com +chinapcd.com +chinape168.com +chinapearlk.com +chinapeier.com +chinapelletizer.com +chinapeople.com +chinapet.com +chinapet.net +chinapharm.net +chinaphp.com +chinaphper.com +chinapilotage.org +chinapipe.net +chinapiston.com +chinaplasonline.com +chinaplat.com +chinapm.org +chinapnr.com +chinaportrait.org +chinaports.com +chinapost-life.com +chinapoto.com +chinapower.org +chinapowerbi.com +chinapp.com +chinapp.net +chinapsy.com +chinapubmed.net +chinapuleather.com +chinapusirui.com +chinapv.org +chinaqcb.com +chinaqfc.com +chinaqi.net +chinaqigong.com +chinaqikan.com +chinaqingtian.com +chinaqipeihui.com +chinaqjydxh.com +chinaql.org +chinaqoe.net +chinaquickpcb.com +chinaqunsheng.com +chinaqw.com +chinaray-oled.com +chinarayying.com +chinarca.com +chinardr.com +chinardr.net +chinaredstar.com +chinaredsun.com +chinareform.net +chinarem.org +chinaren.com +chinarenzhi.com +chinaresin.com +chinarespiratory.org +chinarjw.com +chinarta.com +chinartlaw.com +chinaruiji.com +chinarun.com +chinarunau.com +chinarzfh.com +chinasaat.com +chinasalestore.com +chinasanbai.com +chinasanc.com +chinasantian.com +chinasareview.com +chinasatcom.com +chinasbm-eet.com +chinasbm.com +chinasciencejournal.com +chinascope.com +chinascopefinancial.com +chinascpjy.com +chinascrap.com +chinascsoft.com +chinasecuritization.org +chinaseed114.com +chinasexq.com +chinasg.com +chinashadt.com +chinashenglu.com +chinashengmao.com +chinashj.com +chinashop.cc +chinashpp.com +chinashunyi.com +chinasia.org +chinasie.com +chinasigma.com +chinasiia.com +chinasilk.com +chinasilkmuseum.com +chinasilver.hk +chinasinew.com +chinasinging.com +chinasiwei.com +chinaslc.com +chinasmartpay.com +chinasmcc.com +chinasmp.com +chinasnow.net +chinasnto.com +chinasnw.com +chinaso.com +chinasoftbank.com +chinasofti.com +chinasoftinc.com +chinasoftosg.com +chinasooa.com +chinasoushang.com +chinaspringtown.com +chinasrg.com +chinasrif.com +chinassbc.com +chinassl.com +chinassl.net +chinasspp.com +chinastarlogistics.com +chinastationeryfair.com +chinasti.com +chinastoneforest.com +chinasufa.com +chinasunglow.com +chinasuntree.com +chinasupercloud.com +chinasuperwool.com +chinaswa.org +chinaswim.com +chinaswimmer.com +chinasws.com +chinasydw.org +chinaszma.com +chinataa.org +chinatai.com +chinatairun.com +chinataitan.com +chinataiwan.org +chinatalent.org +chinatalentgroup.com +chinatat.com +chinatechie.com +chinatechie.net +chinatechinsights.com +chinatelecom-h.com +chinatelecom.com.hk +chinatelecom.com.mo +chinatelecomglobal.com +chinatelecomhk.com +chinatelecomiot.com +chinatelling.com +chinatet.com +chinatex.com +chinatex.net +chinatex.org +chinatg.com +chinathinksbig.com +chinatianyin.com +chinatibetnews.com +chinaticket.com +chinatikfans.com +chinatimber.org +chinatimes.cc +chinatiner.com +chinatiredealer.com +chinatla.com +chinatle.com +chinatlzm.com +chinatmco.com +chinatongjia.com +chinatopbrands.net +chinatoplon.com +chinatourguide.com +chinatpm.com +chinatpm.net +chinatrace.org +chinatranslation.net +chinatravel.net +chinatravelacademy.com +chinatraveldepot.com +chinatruck.org +chinatrucks.com +chinatsi.com +chinatsp.com +chinatt.com +chinattas.com +chinattl.com +chinatungsten.com +chinatupai.com +chinatv-net.com +chinatyco.com +chinatypical.com +chinau.cc +chinaufo.com +chinaui.com +chinauidesign.com +chinauma.com +chinaums.com +chinaun.net +chinaunicom-a.com +chinaunicom.com +chinaunicom.com.hk +chinaunicomglobal.com +chinaunionpay.com +chinaunionpay.net +chinauniversalasset.com +chinaunix.com +chinaunix.net +chinaunix.org +chinauo.com +chinauos.com +chinauos.net +chinaups.com +chinaus.com +chinauwei.com +chinava.net +chinavalin.com +chinavas.com +chinavcpe.com +chinavfx.net +chinavid.com +chinavideo.org +chinavideos.net +chinaviewstone.com +chinaviolin.net +chinavipsoft.com +chinavisual.com +chinavivers.com +chinaviwon.com +chinavr.net +chinawanbang.com +chinawanda.com +chinawanlitrans.com +chinawatchnet.com +chinawaterexpo.com +chinawatertech.com +chinawch.com +chinawebber.com +chinawebmap.com +chinaweiyu.com +chinaweizheng.com +chinawepon.com +chinawerewolf.com +chinawie.com +chinawindnews.com +chinawinjoy.com +chinawiserv.com +chinawitmedia.com +chinawr.net +chinaws.net +chinawssdxh.com +chinawudang.com +chinawulong.com +chinawutong.com +chinawutong.net +chinawuyuan.com +chinawxfoundry.com +chinaxiaokang.com +chinaxidian.com +chinaxinge.com +chinaxingye.com +chinaxinhuaair.com +chinaxinport.com +chinaxintu.com +chinaxinzhi.com +chinaxiuqi.com +chinaxiv.com +chinaxiv.net +chinaxiv.org +chinaxpp.com +chinaxq.com +chinaxqf.com +chinaxuchuan.com +chinaxuehang.com +chinaxueqian.com +chinaxwcb.com +chinaxy.com +chinaxzrc.com +chinayacht.org +chinayadea.com +chinayanghe.com +chinayanming.com +chinayaojiang.com +chinayarn.com +chinaybx.com +chinaygj.com +chinayigui.com +chinayikangyaoye.com +chinayinyi.com +chinayis.com +chinayishuhua.com +chinaymc.com +chinayms.com +chinayongfa.com +chinayoubang.com +chinayounao.com +chinayouthpower.org +chinays.com +chinayuanwang.com +chinayucai.com +chinayulin.com +chinayunlang.com +chinayuns.com +chinayuqiu.com +chinayyhg.com +chinayyjx.com +chinaz.com +chinaz.net +chinazbd.com +chinazbj.com +chinazh.net +chinazhifu.com +chinazhijiang.com +chinazhz.com +chinazikao.com +chinazipper.org +chinazjgc.com +chinazjph.com +chinazjy.com +chinazkjc.com +chinazmhb.com +chinaznj.com +chinazns.com +chinaznyj.com +chinazov.com +chinazsgroup.com +chinaztg.com +chinazwds.com +chinazxjc.com +chinazxt.com +chinazy.org +chinca.org +chindices.com +chine-info.com +chinee.com +chinemiss.com +chinese-no1.com +chinese315.org +chineseacc.com +chineseafs.org +chineseall.com +chinesechip.com +chinesecio.com +chineseconsulate.org +chineseembassy.org +chinesehongker.com +chinesejk.com +chineselaw.com +chineselighting.org +chinesemale.com +chinesemedical.net +chinesemeter.com +chinesemooc.org +chinesemoocs.org +chinesepaper-cut.com +chineserose.com +chinesetown.net +chingan.com +chingkun.com +chingli.com +chingmi.com +chinjpd.com +chinlingo.com +chinrt.com +chinsc.com +chint.com +chint.net +chintanneng.com +chintautomation.com +chintautoparts.com +chintcable.com +chintim.com +chinulture.com +chip37.com +chipcoo.com +chipcreation.com +chipdance.com +chipdebug.com +chipeasy.com +chiphell.com +chiphometek.com +chiplayout.net +chipmanufacturing.org +chiponeic.com +chipown.com +chippacking.com +chipsbank.com +chipsec.com +chipsgo.com +chipsir.com +chipup.com +chipwing.com +chipyun.com +chiralquest.com +chisage.com +chisai.tech +chisc.net +chishine3d.com +chishoes.com +chitic.com +chitu.com +chitudexiaozhi.com +chitus.com +chivast.com +chivox.com +chivoxapp.com +chiway-repton.com +chiwayedu.com +chiwayind.com +chiwigogo.com +chixia.com +chixm.com +chixuyun.com +chiyanjiasu.com +chiyekeji.com +chiyifen.com +chiyufeng.com +chizao.com +chizhou.cc +chizhoubus.com +chizhouchacha.com +chizhouhospital.com +chizhoujob.com +chizhouren.com +chiznews.com +chj-care.com +chjchina.com +chjgg.com +chjiye.com +chjso.com +chjyw.org +chkee.com +chkschool.com +chlingkong.com +chlmfm.com +chlmiao.com +chloe99.com +chlxj.com +chmc.cc +chmecc.org +chmed.net +chmgames.com +chmia.org +chmod0777kk.com +chmti.com +chn-cstc.com +chn-das.com +chn-new-9sport.com +chn0769.com +chn112.com +chn168.com +chnart.com +chnau99999.com +chnbook.org +chnboxing.com +chnbsg.com +chnchi.com +chncia.org +chncomic.com +chncon.com +chncopper.com +chncpa.org +chncwds.com +chndaqi.com +chndeli.com +chndesign.com +chndoi.com +chndoi.net +chndoi.org +chnews.net +chnfi.com +chnfund.com +chngalaxy.com +chngc.net +chngsl.com +chnjet.com +chnlanker.com +chnmed.com +chnmodel.com +chnmus.net +chnmusic.org +chnpac.com +chnpec.com +chnppmuseum.com +chnpush.com +chnqiang.com +chnqifeng.com +chnqsedu.com +chnrailway.com +chnroad.com +chnso.com +chnsuv.com +chntel.com +chnxw.com +chocei.com +chofei.com +chofn.com +chofn.net +chofn.org +chofnipr.com +choiceform.com +chomixbiotech.com +chong4.net +chongbuluo.com +chongchi.com +chongdawang.com +chongdeedu.com +chongdiantou.com +chongdk.net +chongdugou.net +chonger.org +chongfabianli.com +chongguanglawfirm.com +chongjisyj.com +chongjiyashiji.com +chongkongwang999.com +chongmingzhuce.com +chongnengjihua.com +chongqingbbs.com +chongqingdongjin.com +chongqingrenpin.com +chongqingyoupin.com +chongqu.com +chongso.com +chongsoft.com +chongwenwen.com +chongwu.cc +chongwudian.com +chongwujiaoyi.com +chongwunet.com +chongya.vip +chongyejia.com +chongyike.com +chongyitang.org +chongyunpowu.com +chongzhi.com +chongzuo.club +chonka.com +chontdoled.com +chonton.com +choosepickhere.com +choositon.com +chooway.com +chopetto.com +chosign.com +choubag.com +chouchoujiang.com +chouchoumao.com +choujue.net +choukang.com +choupangxia.com +chouqu.com +chouti.com +choututech.com +chowtaiseng.com +chplayer.com +chq360.com +chrent.com +chrice.net +chrieschina.com +christophero.xyz +chrmn.com +chroad.com +chrome64.com +chrome666.com +chromecj.com +chromedownloads.net +chromefor.com +chromegw.com +chromeliulanqi.com +chromezj.com +chronusartcenter.org +chrstatic.com +chs.pub +chs5e.com +chsbs.com +chsdl.com +chsdpharma.com +chsgw.com +chshcms.com +chshsaas.com +chsmarttv.com +chsndt.org +chspra.com +chspv.com +chste.com +chszzy.com +chtcmotor.com +chtf.com +chtfund.com +chtgc.com +chtjf.com +chtmxp.com +chtpe.com +chtwm.com +chu-ying.com +chu0.com +chu110.com +chu21.com +chu58.com +chua.pro +chuairan.com +chuaizhe.com +chualamdimsum.com +chuan-s.com +chuanbojiang.com +chuanboyi.com +chuandaizc.com +chuandasolar.com +chuandong.com +chuang-fan.com +chuang-pin.com +chuangansou.com +chuangcache.com +chuangcdn.com +chuangchangnet.com +chuangchenwangluo.com +chuangcifang.com +chuangdaxx.com +chuangduyouyue.com +chuangen.com +chuangfeixin.com +chuanggallery.com +chuanghe.net +chuanghui-cn.com +chuangjiangx.com +chuangjie.com +chuangjing.com +chuangkem.com +chuangkeup.com +chuangkit.com +chuanglan.com +chuangli.net +chuanglian.net +chuanglinggame.com +chuangliukeji.com +chuangluo.com +chuangmaoshanghai.com +chuangmei8.com +chuangongsi.com +chuangseo.com +chuangshiwl.com +chuangshiyuli.com +chuangtie.com +chuangtoo.com +chuangx.org +chuangxin.com +chuangxinapi.com +chuangxinbateng.com +chuangxinoa.com +chuangxuan.xyz +chuangyebaba.com +chuangyehai.com +chuangyejia.com +chuangyetv.com +chuangyijisu.com +chuangyimao.com +chuangyiqifu.com +chuangyisai.com +chuangyiwh.com +chuangyouqi.com +chuangyuan.ltd +chuangyuejoy.com +chuangzaoshi.com +chuangzuoniu.com +chuanhai.net +chuanhuan.com +chuanjiaoban.com +chuanke.com +chuanloo.com +chuanmeixing.com +chuannan.net +chuanpuyun.com +chuanqi.com +chuanqiart.com +chuanqibbs.com +chuanshanjia.work +chuanshanqundao.com +chuansong.me +chuansongme.com +chuantangjitrade.com +chuantec.com +chuantiegroup.com +chuantu88.com +chuanxincao.net +chuanye.com +chuanyejinxuan.xyz +chuanyifu.com +chuanyinet.com +chuanying365.com +chuanying520.com +chuanyuanbang.com +chuanyuapp.com +chuanzhen.com +chuapp.com +chuasu.com +chuban.cc +chubanyun.me +chubaohui.com +chucheng.wiki +chuchujie.com +chuchur.com +chufaba.me +chufw.com +chuge8.com +chugou360.com +chuguo.tech +chuguo78.com +chuguohao.com +chuguoqu.com +chuhai.group +chuhaige.com +chuhailiqi.com +chuimg.com +chuinet.com +chuisax.com +chuishen.xyz +chuixue.com +chuiyue.com +chujian.xyz +chujing-electric.com +chujingapp.com +chujuan.net +chujunkeji.com +chukong-inc.com +chukonggame.com +chukou1.com +chukouplus.com +chuleg.com +chumenwenwen.com +chun-wang.com +chun-xiang.com +chunbo.com +chunboimg.com +chundi.com +chundi.org +chunengauto.com +chunfengapp.com +chunfengxing.com +chungkwong.cc +chunhaijx.com +chunhingplasticbags.com +chunhuinongye.com +chunjiangvalve.com +chunjingban.net +chunlan.com +chunliangpai.com +chunliao.net +chunloo.com +chunmen.com +chunmi.com +chunqiuhong.com +chunsheng.com +chunshuitang.com +chunshuizhijia.com +chunsuns.com +chuntaoyisheng.com +chuntsuan.com +chunxing-group.com +chunxuanmao.com +chunxudianqi.com +chunyiscdk.com +chunyu.me +chunyu.mobi +chunyuyisheng.com +chunzuo.com +chuoemg.work +chuolitech.com +chuquan.me +churenjixie.com +churuisy.com +chusan.com +chusenscm.com +chuseo.com +chushan.com +chushang027.com +chushi.cool +chushihome.com +chushiji.com +chushixiu.com +chushou.tv +chushu.org +chushu123.com +chutianlaser.com +chutianzhinu.com +chuxindata.com +chuxingpay.com +chuxingyouhui.com +chuxinhd.com +chuxinhudong.com +chuxinvip.com +chuxueyun.com +chuyaer.com +chuyigao.com +chuyu.me +chuzhaobiao.com +chvacuum.com +chvoice.com +chw818.com +chwang.com +chwedu.com +chwlsq.com +chxchips.com +chxent.com +chxin-oil.com +chxq.org +chxyl.com +chxyq.com +chyitech.com +chysoft.net +chyw.pub +chyxx.com +chyyyygl.com +chz.cc +chzhkeji.com +chzhsw.com +chzhw.com +chzpw.com +chzsks.com +chzwater.com +chzybj.com +ci-cn.com +ci-du.com +ci-ele.com +ci-xing.com +ci123.com +ci800.com +ciaie.com +cialisrxmsn.com +ciallo.cc +ciaoca.com +ciapst.org +ciaxkzxy.com +cibaike.com +cibawl.com +cibfintech.com +cibia.org +cibn-intl.com +cibn.cc +cibn.com +cibnlive.com +cibnott.net +cibntv.net +cibnvst.com +ciboedu.org +cibonet.com +cibresearch.com +cibuser.com +cic-js.com +cicadayun.com +cicaf.com +cicba.net +cicc.com +ciccfund.com +cicconline.com +ciccphoto.com +ciccwargame.com +ciccwm.com +ciceme.com +cicfexpo.com +cicg.tech +ciciec.com +cicihappy.com +cicmag.com +cicnn.com +cicoe.net +cicphoto.com +cict.com +cidf.net +cidi.ai +cidianbao.com +cidiancn.com +cidianso.com +ciding.cc +cidschina.com +ciduw.com +cie-lgr.com +cieaast.com +ciec-expo.com +ciec.com +ciect.com +ciecte.com +ciecworld.com +ciedata.com +cieet.com +ciepe.com +cietac-hb.org +cietac-sc.org +cietac.org +ciezn.com +cifa-china.com +cifalshanghai.org +cifco.net +ciff-gz.com +cifm.com +cifnews.com +cifoo.com +ciftis.org +cig-cq.com +cigadesign.com +cigarambassador.com +cigh.com +cignacmb-ipmi.com +cignacmb.com +cignacmbamc.com +cignacmbuser.com +cigtech.com +ciguang.com +cih-index.com +cihai123.com +cihexpo.com +cihua.net +ciiccq.com +ciicgat.com +ciichr.com +ciicjs.com +ciicsh.com +ciidoo.com +ciie.org +ciif-expo.com +ciiip.com +ciiplat.com +cijiasu.com +cijiyun.com +cikelink.com +cilgroup.org +ciliba.life +cilin.org +cilishenqi.cc +cilogo.com +cim2025.net +cimamotor.com +cimc-tianda.com +cimc.com +cimccity.com +cimcdlem.com +cimcjm.com +cimclogistics.com +cimcreefertrailer.com +cimcvehiclesgroup.com +cimen.club +cimic.com +cimicgroup.com +cimictiles.com +ciming-bj.com +ciming-sh.com +ciming.com +cimingaoya.com +cimingbj.com +cimingsy.com +cimsic.com +cimtshow.com +cinacom.net +cinasoft.com +cindaflc.com +cindasc.com +cindasoft.com +cinehello.com +cineplexsn.com +cingta.com +ciniao.me +cinic.com +cinsee.com +cinsos.com +cio114.com +cio360.net +cioage.com +cioln.help +ciomp-cggc.com +ciopharma.com +ciotimes.com +ciotour.com +ciou.com +cioxom-top.com +cip.cc +cipgtrans.com +cipherupcloud.com +ciplawyer.com +cippe.net +ciprun.com +cipscom.com +cipukj.com +cipunited.com +circday.com +circleharmonyhealth.com +circlelog.com +circuitboardchips.com +cirmall.com +cirrowings.com +cirs-ck.com +cirs-group.com +cirs-reach.com +cirscn.com +cisbeijing.com +ciscon.org +cisdish.com +cisgz.com +cisia.org +cismef.com +cisskwt.com +cistds.org +cistsports.com +cisuntech.com +cit168.com +citahub.com +citaq.com +citeaexample.com +citegalleries.com +citexpo.org +citgc.com +citiais.com +citic-wealth.com +citic.com +citicbank.com +citicbankuser.com +citiccapital.com +citiccard.com +citicdameng.com +citicenvirotech.com +citicfunds.com +citicguoanbn.com +citichmc.com +citiciam.com +citicifh.com +citicleasing.com +citicnetworks.com +citics.com +citics.com.hk +citicsf.com +citicsinfo.com +citicsteel.com +citie-gd.com +citiraise.com +citisa.org +citiz.net +citizenmech.com +citreport.com +cits-jl.com +cits-sz.net +citsbj.com +citscq.com +citscsc.com +citsgbt.com +citsgs.com +citsguilin.com +citshq.com +citsp.net +citsqd.net +citssh.com +citswx.com +citsxa.com +citsyn.com +citszz.com +citvc.com +city12580.com +city199.com +city8.com +city8090.com +citybrain.com +citygf.com +cityhui.com +cityhuitech.com +citylinker.com +cityoncenter.com +cityos.com +citypaly.com +citys114.com +citysbs.com +citysz.net +citytogo.com +cityup.org +citywy.com +ciunofor.com +civicswarm.com +civigas.com +civilizec.com +civilness.com +civiw.com +ciweek.com +ciweekforum.com +ciweekly.com +ciwei.net +ciweimao.com +ciweishixi.com +ciweiyuedui.com +ciwong.com +ciwong.net +ciwork.net +cixcomputing.com +cixibank.com +cixiedu.net +cixtech.com +cixuanfuw.com +ciyagroup.com +ciyew.com +ciyitech.com +ciyocon.com +ciyoga.org +ciyuan.men +ciyuanji.com +ciyuans.com +ciyun.link +ciyynodegroup.cyou +cizip.com +cj0515.com +cj120.com +cj5bs.com +cj5bs.net +cj8.ren +cjaljs.com +cjasen.com +cjavapy.com +cjbeng.com +cjbjedu.com +cjbxt.com +cjccb.com +cjchina.net +cjcn.com +cjdcw.com +cjdg.com +cjdropshipping.com +cjdsp.com +cjeduw.com +cjftb.com +cjhospital.com +cjhxfund.com +cjhydrogen.com +cjia.com +cjiahome.com +cjienc.com +cjiit.com +cjitri.com +cjj365.cc +cjjd01.com +cjjd02.com +cjjd03.com +cjjd04.com +cjjd05.com +cjjd06.com +cjjd07.com +cjjd08.com +cjjd09.com +cjjd10.com +cjjd11.com +cjjd12.com +cjjd13.com +cjjd14.com +cjjd15.com +cjjd16.com +cjjd17.com +cjjd18.com +cjjd19.com +cjjd20.com +cjjhb.com +cjjhk.com +cjjjs.com +cjjnff.com +cjk3d.net +cjkhd.com +cjkihgroup.com +cjkjks.com +cjkt.com +cjkz.com +cjlap.com +cjlulu.com +cjm.so +cjmit.com +cjmr.org +cjmx.com +cjmxhedu.com +cjn.com +cjnas.com +cjnis.com +cjol.com +cjrcsc.com +cjs-lwh.love +cjsc.com +cjsgegs.com +cjshipin.net +cjsic.com +cjslcg.com +cjspd.com +cjsy.net +cjsyedu.com +cjtl.com +cjtmsp.com +cjtouzi.com +cjveg.com +cjwcjyy.com +cjwlb.com +cjww.com +cjx2.com +cjxqjt.com +cjxz.com +cjycode.com +cjys.net +cjyun.org +cjyy6789.com +cjyyw.com +cjzcb.com +cjzcgl.com +cjzsy.com +cjzww.com +cjzx.net +cjzzc.com +ck-coinmcap.lol +ck0771.com +ck100.com +ck180.net +ck586.com +ck830.com +ck921.com +ckair.com +ckan.tv +ckbv165.org +ckd-mbd.com +ckd.im +ckd.so +ckd8.com +ckdzb.com +ckefu.com +ckernel.org +ckeyan17.com +ckeyan17.net +ckeyedu.com +ckfxx.com +ckhdvt.com +ckia.org +ckimg.com +ckj100.com +ckj1000.com +ckjr001.com +ckjryy.com +ckpharm.com +ckplayer.com +ckqjyjq.xyz +cksct.com +cksic.com +cksschool.com +cksx.org +cktqeiau.com +cktshare.com +ckuai.com +ckvmrtfg.com +ckw205.com +ckweax9zn5.com +ckxx.net +ckzcc.com +ckzhaoyaojing.com +ckzhijiaedu.com +cl-acg.com +cl-kongtiao.com +cl-power.com +cl0438.com +cl0579.com +cl2009.com +cl868.com +clady.cc +clam-itc.com +clamc.com +clamptek.com +clangcn.com +clangtx.com +clanzx.net +clapreptile.com +claritywallpaper.com +clarivate.com +clashroyaleapp.com +classa-z.com +classcms.com +classic023.com +classinpaas.com +classix-unlimited.co.uk +classmateer.com +classpassincn.com +classpod.com +classpodcdn.com +claviercn.com +clawchat.com +clawhub-mirror.com +clay-wangzhi.com +clayidols.com +clb6.net +clboss.com +clbu.club +clbug.com +clbz666.com +clcgq.com +clcindex.com +clclibrary.com +clcoolyun.com +clcs.cc +clcwwyj.com +clcz.com +cldfsv.com +cldisk.com +clean-cn.com +cleandfd.com +cleanupsys.com +clear-sz.com +clear888.com +clearaki.com +clearcrane.com +cleargrass.com +clearmediatech.com +clearofchina.com +clearsky360.com +cleartone.club +clevercn.net +cleveroom.com +clewm.net +clfcgc.com +clfdked.icu +clfile.com +clfzsn.com +clgcxs.com +clgslc.com +clhimalayanxx.com +clhqcyx.com +cli.im +clianjie.com +clickfuntech.com +clicksdiy.com +clickserve.cc-dt.com +clicksun.net +clickwifi.net +clidone.com +client.amplifi.com +client51.com +clientperipherals.dell.com +clifford-hospital.org +cliffordtrading.com +cliim.com +cliim.net +clijc.com +climedic.com +clinbrain.com +clivia.fun +clj178.com +cljport.com +cljtscd.com +cljtwr.com +cljtzycw.com +clk1.top +clled.com +cllk.net +clloz.com +clmpg.com +clngaa.com +cloopen.com +cloopen.net +cloopm.com +closeli.work +closertb.site +clothes178.com +clothinggg.store +clothjob.com +clothr.com +clotliu.com +clouclip.com +cloud-b2b.com +cloud-beijing.com +cloud-control.top +cloud-dahua.com +cloud-dns.net +cloud-frame.com +cloud-hebi.com +cloud-hub.co +cloud-industry-delivery.site +cloud-link.com +cloud-links.net +cloud-neofussvr.sslcs.cdngc.net +cloud-ningbo.com +cloud-ordos.com +cloud-rtc.com +cloud-rtc.net +cloud-scdn-ns.net +cloud-scdn-ns.tech +cloud-scdn.com +cloud-shenzhen.com +cloud-shiyan.com +cloud-sun.com +cloud-wuhan.com +cloud-xian.com +cloud-xm.com +cloud-zhaoqing.com +cloud-zhongwei.com +cloud21cn.com +cloud301.net +cloud56.net +cloud887325.com +clouda.com +cloudacc1.com +cloudacc1.net +cloudajs.org +cloudangelfunds.com +cloudanqing.com +cloudappl.com +cloudbaoshan.com +cloudbase.net +cloudbeibei.com +cloudbility.com +cloudbinzhou.com +cloudbool.com +cloudcachetci.com +cloudcc.com +cloudcdn.net +cloudcdns.com +cloudcdns.net +cloudcdnvip.com +cloudcflare.com +cloudchangde.com +cloudchangsha.com +cloudchangzhou.com +cloudchaozhou.com +cloudchengde.com +cloudchengdu.com +cloudchinese.com +cloudchuzhou.com +cloudcross.com +cloudcsp.com +cloudczs.com +clouddalian.com +clouddatong.com +clouddcs.com +clouddiffuse.xyz +clouddig.com +clouddn.com +clouddongying.com +clouddream.net +cloudencent.com +cloudflare-cn.com +cloudflare.fun +cloudflareanycast.net +cloudflarecn.net +cloudflareglobal.net +cloudflareinsights-cn.com +cloudflareip.com +cloudflareperf.com +cloudflareprod.com +cloudflarestaging.com +cloudflarestoragegw.com +cloudfoshan.com +cloudfront-cn.net +cloudfuqing.com +cloudganzhou.com +cloudgap.net +cloudgfw.com +cloudgfw.net +cloudgoing.com +cloudguangzhou.com +cloudguarding.com +cloudgx.net +cloudhaidong.com +cloudhefei.com +cloudhengshui.com +cloudhin.com +cloudhlo.com +cloudhost.link +cloudhua.com +cloudhuaihua.com +cloudhuizhou.com +cloudhvacr.com +cloudidaas.com +cloudinnov.com +cloudinward.com +cloudiplc.com +cloudjinan.com +cloudjinchang.com +cloudjingzhou.com +cloudjining.com +cloudjiujiang.com +cloudkirin.com +cloudkunming.com +cloudleshan.com +cloudlijiang.com +cloudlishui.com +cloudluohe.com +cloudluoyang.com +cloudlvs.com +cloudmarket-apigw.com +cloudmaster.hk +cloudmeishan.com +cloudmes.io +cloudminds.com +cloudmob.vip +cloudmob.xyz +cloudmountainproducts.com +cloudnanan.com +cloudnanjing.com +cloudnanning.com +cloudnantong.com +cloudnapps.com +cloudnet.world +cloudnetb2b.com +cloudouc.com +cloudp.cc +cloudpense.com +cloudpnr.com +cloudquanzhou.com +cloudrmt.com +cloudroom.com +clouds1000.com +cloudsanya.com +cloudsation.com +cloudsconverge.com +cloudsec1.com +cloudsec1.net +cloudsee.com +cloudsee.net +cloudseeplus.com +cloudseetech.com +cloudserver01.com +cloudses.com +cloudsgis.com +cloudshanghai.com +cloudshaoyang.com +cloudshenfuxingqu.com +cloudsigma.com +cloudsiping.com +cloudsite.vip +cloudskysec.com +cloudstencent.com +cloudstudio-app.net +cloudstudio.club +cloudstudio.net +cloudstudio.run +cloudstudio.work +cloudsuqian.com +cloudswift.cloud +cloudtalkers.com +cloudtangshan.com +cloudtencents.com +cloudtianjin.com +cloudtomicro.com +cloudtongchuan.com +cloudtongliang.com +cloudtopo.com +cloudtrans.com +cloudtui.com +cloudv.cdnetworks.com +cloudvast.com +cloudvdn.com +cloudvogue.com +cloudvse.com +cloudwalk.com +cloudweinan.com +cloudwise.ai +cloudwise.com +cloudxiangtan.com +cloudxianyou.com +cloudxining.com +cloudxns.com +cloudxns.net +cloudyanan.com +cloudyancheng.com +cloudyantai.com +cloudyee.com +cloudyinchuan.com +cloudyo.net +cloudyouku.com +cloudytrace.com +cloudytrace.org +cloudyueyang.com +cloudyuncheng.com +cloudyuxi.com +cloudzhongshan.com +cloudzhuhai.com +clpcdn.com +clpga.org +clqccy.com +clqcgsgw.com +clqctxc.com +clqrmyy.com +clroi.com +cls-a.com +cls-c.com +cls.cc +clsa.com +clsbhs.com +clsgd.com +clshanghai.com +clsj.com +clsshare.com +clssn.com +clssnews.com +clsz-group.com +clto.cc +cltt.org +club-pc.com +clubcarev.com +clubhy.com +clubske.com +cluerich.com +clx360.com +clxlb.com +clxsbj.com +clxsczx.com +clyiyuan.com +clz.me +clzd.com +clzd.fun +clzqm.com +clzqxp.com +clzt.com +clzyqche.com +cm-health.com +cm-inv.com +cm-iov.com +cm-worklink.com +cm.fancyapi.com +cm.ipinyou.com +cm233.com +cm3721.com +cm442.com +cmacredit.org +cmaif.com +cmaifz.com +cmakaoj.com +cmandroid.com +cmanuf.com +cmastd.com +cmb-leasing.com +cmbajia.com +cmbchina.biz +cmbchina.com +cmbchina.net +cmbchinawm.com +cmbi.com.hk +cmbimg.com +cmbuat.com +cmbwinglungbank.com +cmbwlb.com +cmbyc.com +cmca-view.com +cmcc.in +cmccb2b.com +cmcconenet.com +cmccsim.com +cmcgd.com +cmcha.org +cmcink.com +cmcloud.org +cmclound.com +cmcm.com +cmcmadmin.com +cmcmapp.com +cmcmcdn.com +cmcmcmai.com +cmcmiot.com +cmcmpc.com +cmcmsecurity.com +cmcmserv.com +cmcmtrans.com +cmco-cn.com +cmcrcw.com +cmct.tv +cmct22.com +cmctea.net +cmd.tw +cmd5.com +cmd5.la +cmd5.org +cmd8.com +cmda-ccs.com +cmda.net +cmdcxls.com +cmdpe.com +cmdschool.org +cmdsir.com +cmdw.vip +cme-am.com +cme-cq.com +cme021.com +cmea-crtc.com +cmec.com +cmechina.net +cmedia360.com +cmedns.com +cmeii.com +cmejob.com +cmenergyshipping.com +cmer-ningbo.com +cmer.com +cmerdi.com +cmersz.com +cmes.org +cmf.biz +cmf.ltd +cmfchina.com +cmfish.com +cmfspay.com +cmft.com +cmfu.com +cmfwiper.com +cmgadx.com +cmgame.com +cmgchengdu.com +cmgdb.com +cmge.com +cmgemooc.com +cmgn.cc +cmgos.com +cmgrasp.com +cmhello.com +cmhijs.com +cmhk.com +cmic.site +cmicapm.com +cmidc.net +cming.com +cmiotcd.com +cmiyu.com +cmjz.net +cmlog.com +cmltzz.com +cmmaap.com +cmmchn.com +cmmim.com +cmnetech.com +cmnxt.com +cmo2o.com +cmoc.com +cmodel.com +cmodes.com +cmol.com +cmpay.com +cmpe360.com +cmpedu.com +cmpo1914.com +cmr-co.com +cmread.com +cmreltd.com +cmri.cc +cmrid.com +cms1924.org +cms258.com +cmschina.com +cmscmc.org +cmseasy.cc +cmsfg.com +cmsjournal.net +cmsk1979.com +cmskchp.com +cmskcrm.com +cmsta.org +cmstop.com +cmstp.com +cmswin.com +cmt1993.com +cmt7.com +cmtauto.com +cmtdi.com +cmtopdr.com +cmtrq.com +cmtv1.com +cmu1h.com +cmudental.com +cmugx.com +cmuliang.com +cmviking.com +cmvtc.com +cmwb.com +cmwin.com +cmxrcw.com +cmykjx.net +cmypsc.com +cmys.cc +cmyunerp.com +cmyynet.com +cmzd.com +cmzi.com +cmzj.net +cmzyk.com +cn-5.com +cn-833.org +cn-ab.com +cn-aci.com +cn-bldc.com +cn-bowei.com +cn-boxing.com +cn-c114.net +cn-caa.com +cn-cav.com +cn-cddc.com +cn-cdn1.skymansion.net +cn-ceramic.com +cn-cg.com +cn-chenguang.com +cn-comfort.com +cn-cr.com +cn-elite.com +cn-em.com +cn-ferment.com +cn-food.net +cn-ghtube.com +cn-goldeneagle.com +cn-hbs.com +cn-healthcare.com +cn-healthclass.com +cn-heipa.com +cn-huaguang.com +cn-huar.com +cn-hw.net +cn-immunotech.com +cn-kanghong.com +cn-lance.net +cn-lcd.com +cn-lingte.com +cn-lq.net +cn-mingda.com +cn-msedge.net +cn-mw.com +cn-natural.com +cn-only.com +cn-psy.com +cn-railway.net +cn-rcqc.com +cn-roofexpert.com +cn-school.com +cn-sdf.com +cn-shine.com +cn-soft.com +cn-tf.com +cn-tom.com +cn-truck.com +cn-unitech.com +cn-vending.com +cn-visa.com +cn-weida.com +cn-wisely.com +cn-witmed.com +cn-xsl.com +cn-zhentai.com +cn-zhongrui.com +cn.bing.com +cn.bing.net +cn.download.nvidia.com +cn.eset.com +cn.mm.bing.net +cn.net +cn.online.standardchartered.com +cn.pool.ntp.org +cn.sc.com +cn.vc +cn.widevine.com +cn.windowssearch.com +cn0-6.com +cn006.com +cn010w.com +cn0434.com +cn0577.net +cn0713.com +cn0851.com +cn0917.com +cn11185.com +cn12365.org +cn156.com +cn168.com +cn18k.com +cn2030.com +cn22.net +cn2che.com +cn2rv.com +cn314.com +cn357.com +cn360cn.com +cn365a.com +cn365c.com +cn365d.com +cn365e.com +cn3wm.com +cn486.com +cn49.com +cn4e.com +cn51.com +cn5135.com +cn6szx.com +cn88.net +cn880.com +cn939.com +cn99.com +cnaaa.com +cnaaa.net +cnaaa6.com +cnaaa7.com +cnaaa8.com +cnaaa9.com +cnaai.com +cnaca.org +cnacg.cc +cnacgc.com +cnaction.com +cnad.com +cnaf.com +cnafc.org +cnagcoin.com +cnaidc.com +cnaifm.com +cnain.online +cnaio.net +cnaiplus.com +cnair.com +cnaja.com +cnal.com +cnalu.com +cnambition.com +cname-cdn.com +cname-syd.com +cname123.net +cname88.com +cnamegslb.com +cnameip.xyz +cnamexingzuoy.com +cnamico.com +cnanzhi.com +cnaomeng.com +cnatom.com +cnats.com +cnautofinance.com +cnautonews.com +cnautotool.com +cnb.cool +cnb.run +cnb.space +cnbabylon.com +cnball.net +cnbang.net +cnbaosi.com +cnbaowen.net +cnbct.org +cnbeinuo.com +cnbeta.com +cnbetacdn.com +cnbfjt.com +cnbidding.com +cnbio.net +cnbiocell.com +cnbis.com +cnbis.org +cnbizmedia.com +cnbjx.com +cnbksy.com +cnbkw.com +cnblogs.com +cnblogs.vip +cnblower.com +cnbm-njks.com +cnbmltd.com +cnbmtech.com +cnbmys.com +cnbnl.com +cnboat.com +cnbonly.com +cnbooking.net +cnbooks.org +cnbp.net +cnbrass.com +cnbsm.com +cnbugs.com +cnbuses.com +cnbysc.com +cnbzol.com +cnbzs.com +cnc-bga-oca.com +cnc-gd.net +cnc-school.com +cnca.net +cncad.net +cncaifu.com +cncame.com +cncanghai.com +cncapital.net +cncapital.org +cncbinternational.com +cncbpc.com +cncc.bingj.com +cnccac.com +cnccchina.com +cnccdn.com +cnccea.com +cncdh2.com +cncdn.com +cncdnx.com +cncdomain.com +cncecci.com +cncecsci.com +cncecyc.com +cncfans.com +cncflux.com +cncgdns.com +cncgdns.net +cncgw.org +cnchainnet.com +cnchangyi.com +cnchaowei.com +cnchemmy.com +cncheng.com +cnchezhan.com +cnchospital.com +cnchu.com +cncico.com +cncjichuang.com +cncjishu.com +cncjj.com +cncjmjg.com +cnclead.com +cncljt.com +cncloud.com +cncma.org +cncmrn.com +cncms.com +cncmun.com +cncn.com +cncn.net +cncnbd.com +cncncn.com +cncnet.net +cncnki.com +cncolour.com +cncompute.com +cncoolm.com +cncopter.com +cncosmic.com +cncotton.com +cncourt.org +cncovs.com +cncqcloud.com +cncqcy.com +cncqsw.com +cncqti.com +cncr-it.com +cncrk.com +cncrony.com +cncruise.com +cncrypt.com +cncsen.com +cncsj.net +cncsparetools.com +cnctg.net +cnction.com +cnctrip.com +cncwkj.com +cncxjyu.com +cndailu.com +cndao.com +cndata.com +cndatacom.com +cndbl.com +cndc-pl.com +cndcpta.com +cndds.com +cndelong.com +cndesign.com +cndesk.com +cndezhong.com +cndf.net +cndfdt.com +cndfele.com +cndfilm.com +cndhl.com +cndhotels.com +cndi-bj.com +cndi.com +cndids.com +cndingli.com +cndingxi.com +cndits.com +cndl.vip +cndledu.com +cndmaterial.com +cndns.com +cndns5.com +cndnscn.com +cndoct.com +cndog.net +cndongrun.com +cndongxiao.com +cndoornet.com +cndoors.com +cndqjc.com +cndrealty.com +cndsnet.com +cndtour.com +cndw.com +cndy.org +cndzh.com +cndzq.com +cndzys.com +cne-motor.com +cne-om.com +cne.com +cnean.com +cnecc.com +cnechc.com +cnecport.com +cnedulaw.net +cneeex.com +cnegood.com +cnegov.com +cnegov.org +cnelc.com +cnelecom.net +cnelite.org +cneln.net +cnemb.com +cnena.com +cneol-dns.net +cneonl.com +cnep001.com +cnepaper.com +cnepaper.net +cnepub.com +cnerlang.com +cnetea.net +cnetec.com +cnetsec.com +cnexp.net +cnexpo.com +cnexps.com +cneyoo.com +cnezsoft.com +cnfanews.com +cnfantasia.com +cnfarasia.com +cnfashion.net +cnfca.com +cnfce.net +cnfcyy.com +cnfczn.com +cnfczy.com +cnfeat.com +cnfeol.com +cnfeol.net +cnfg.cc +cnfia.com +cnfiberhome.com +cnfin.com +cnfina.com +cnfirst.net +cnfish.com +cnfisher.com +cnfjwz.com +cnfla.com +cnflyinghorse.com +cnfol.com +cnfolimg.com +cnfood.com +cnforever.com +cnforex.com +cnfosale.com +cnfpc.com +cnfpia.org +cnfpzz.com +cnfq.com +cnfrag.com +cnfrey.com +cnfrp.com +cnfrp.net +cnfruit.com +cnfth.com +cnfuhuaqi.com +cnfuyin.org +cnfxc.com +cnfxj.org +cnfyyj.com +cnfzflw.com +cngal.org +cnganen.com +cngaosu.com +cngaoxiu.com +cngb.org +cngba.com +cngbdl.com +cngbol.net +cngdhl.com +cngin.com +cngjtx.com +cngma.com +cngold.org +cngoldres.com +cngolf.tv +cngongfu.com +cngrain.com +cngreatop.com +cngreenfield.com +cngsda.net +cngsf.com +cngslb.com +cngslb.net +cnguangxing.com +cnguibao.com +cnguibie.com +cngulu.com +cngwv.com +cngwzj.com +cngxbj.com +cngxjy.com +cngxsmj.com +cngyff.com +cngyi.com +cnh5.net +cnhacker.com +cnhaifan.com +cnhalo.net +cnhanjia.com +cnhantide.com +cnhanxing.com +cnhaomen.com +cnhaoshengyi.com +cnhbql.com +cnhbstock.com +cnhbtc.com +cnhcb.com +cnhd.com +cnheader.com +cnhemiao.com +cnhenda.com +cnhengkai.com +cnhhgjx.com +cnhhl.com +cnhiger.com +cnhiker.com +cnhis.cc +cnhis.com +cnhli.com +cnhls.com +cnhlsxe.com +cnhnb.com +cnhongke.org +cnhonker.com +cnhow.net +cnhqt.com +cnhsjz.com +cnhsw.net +cnhszx.com +cnhuafag.com +cnhuafas.com +cnhuanya.com +cnhubei.com +cnhuoche.com +cnhvacrnet.com +cnhwjt.com +cnhyc.com +cnhyjt.com +cnhyky.com +cnhzsc.com +cnhzz.com +cniao5.com +cnibx.com +cniceberg.com +cnicif.com +cnielts.com +cniiib.com +cnimg.elex.com +cnimporter.com +cninfo.net +cninj.com +cninnovatel.com +cninsure.net +cninternetdownloadmanager.com +cnios.net +cnipa-gd.com +cnipa-hb.com +cnipa-pesc.com +cnipa-sc.com +cnipa-tj.com +cnipai.com +cnipr.com +cnirtrade.com +cnispgroup.com +cnitblog.com +cniteyes.com +cniti.com +cnitom.com +cnitpm.com +cnitv.net +cnix.cc +cnjccrusher.com +cnjdz.net +cnjecc.com +cnjf.com +cnjffb.com +cnjfsilk.com +cnjgtec.com +cnjhyg.com +cnjiajun.com +cnjiali.com +cnjiaolian.com +cnjingchu.com +cnjingtong.com +cnjingyigroup.com +cnjiuze.com +cnjiwang.com +cnjj.com +cnjjwb.com +cnjkzxw.com +cnjlc.com +cnjnsb.com +cnjob.com +cnjournals.com +cnjournals.net +cnjournals.org +cnjp-exp.com +cnjpetr.org +cnjrna.com +cnjsdz.com +cnjsun.com +cnjunhe.com +cnjunnet.com +cnjunzilan.com +cnjurry.com +cnjurui.com +cnjxl.com +cnjxol.com +cnjyky.com +cnjyw.net +cnjzb.com +cnjzgroup.com +cnk8.com +cnkaile.com +cnkang.com +cnkanshu.com +cnkefa.com +cnkeg.com +cnkesai.com +cnkeyboard.com +cnkgraph.com +cnkh.com +cnki.net +cnki.vip +cnkicheck.info +cnkidoi.com +cnkidoi.net +cnkidoi.org +cnkinect.com +cnkingjoy.com +cnkis.net +cnkivip.net +cnkix.com +cnkizw.com +cnklog.com +cnkly.com +cnknowledge.com +cnkosun.com +cnkpgs.com +cnkuai.com +cnky.net +cnkyz.com +cnlampholder.com +cnlandport.com +cnlang.org +cnlanhui.com +cnlanling.com +cnlaunch.com +cnlaw.net +cnlawweb.net +cnlcg.com +cnldedu.com +cnldzc.com +cnledw.com +cnlianjie.com +cnliequan.com +cnlight.com +cnlightnet.com +cnlinka.com +cnlishuai.com +cnlist.com +cnlist.org +cnlive.com +cnliveimg.com +cnljxh.com +cnlng.com +cnlongkou.net +cnlot.net +cnlso.com +cnluan.com +cnlubadd.com +cnluolun.com +cnlushan.com +cnlwg.com +cnmagtec.com +cnmanhua.com +cnmansi.com +cnmarathon.net +cnmarinefan.com +cnmattson.com +cnmcl.net +cnmdy.com +cnmec.biz +cnmeiwei.com +cnmf.net +cnmhg.com +cnmhh.work +cnmia.org +cnmie.com +cnmill.com +cnmineqs.net +cnminiorange.com +cnmjcn.com +cnmjcn.cyou +cnmjcn.net +cnmjin.net +cnmla.com +cnmmsc.org +cnmo.com +cnmobile.net +cnmods.net +cnmods.org +cnmoershu.com +cnmooc.org +cnmp3.com +cnmsl.net +cnmsn.com +cnmsn.net +cnmstl.net +cnmtpt.com +cnmuseum.com +cnmysoft.com +cnn-wali.com +cnn100.com +cnnaihuo.com +cnnb.com +cnnbfdc.com +cnnbsa.com +cnncbhy.com +cnncguilin.com +cnndns.com +cnnetsec.com +cnneweragx.com +cnnfootballclub.com +cnnic.net +cnnice.com +cnnmol.com +cnnorge.com +cnnorip.org +cnnosolar.com +cnnot.com +cnnpz.com +cnns.net +cnntzr.com +cnnuo.com +cnnx.net +cnnyye.org +cnobin.org +cnod.net +cnoddt.com +cnoic.com +cnoil.com +cnolnic.com +cnolnic.net +cnolnic.org +cnonjx.com +cnonline.org +cnoocengineering.com +cnoocltd.com +cnool.net +cnopendata.com +cnops.xyz +cnoptec.com +cnork.com +cnosr.com +cnoswiki.com +cnoutdoor.com +cnovirt.com +cnovtec-chamber.com +cnpaf.net +cnpaiwei.com +cnpaiwo.com +cnpanda.net +cnparking.org +cnpatent.com +cnpatrickstar.com +cnpcbidding.com +cnpcgas.com +cnpcmall.com +cnpdccutter.com +cnpenjing.com +cnpereading.com +cnpfjt.com +cnpghouse.com +cnpgjt.com +cnphar.net +cnpharm.com +cnphotec.com +cnphotos.net +cnpickleball.com +cnpickups.com +cnpicl.com +cnpiecgb.com +cnpiecsb.com +cnpkm.com +cnpl-ltl.com +cnplanetary.com +cnplugins.com +cnpmjs.org +cnpoli.com +cnponer.com +cnpot.com +cnpou.com +cnpoultry.com +cnpowdernet.com +cnpowdertech.com +cnpp100.com +cnppa.org +cnpressphoto.com +cnprofit.com +cnprs.com +cnpsec.com +cnpubc.com +cnpubg.com +cnpv.com +cnpxyy.com +cnpython.com +cnqc.com +cnqcc.com +cnqd.net +cnqiang.com +cnqichun.com +cnqifeng88.com +cnqjw.com +cnqr.org +cnquanjing.com +cnqwt.com +cnradio.com +cnraksmart.com +cnrancher.com +cnrceo.com +cnrcloudfm.com +cnrdm.com +cnrdn.com +cnreagent.com +cnree.com +cnrencai.com +cnrepair.com +cnrepark.com +cnrft.com +cnrhwq.com +cnricc.com +cnrih.com +cnrj45.com +cnrmall.com +cnrmc.com +cnrmobile.com +cnrotech.com +cnrouter.com +cnrsj.com +cnrubbermachinery.com +cnrunda.com +cnrunlin.com +cnrust.com +cnrv.io +cns.hk +cnsaes.org +cnsal.com +cnsanf.com +cnsantech.com +cnsav.com +cnsb.org +cnsbjy.com +cnsc8.com +cnsce.net +cnscee.com +cnsciedu.com +cnscn.com +cnscnet.com +cnscore.com +cnsdb.com +cnsdjxw.com +cnseay.com +cnseeq.com +cnsesan.com +cnsetsail.com +cnsfk.com +cnshende.com +cnshexinji.com +cnshiri.com +cnshjy.com +cnshuizu.com +cnshzm.com +cnside.com +cnsihai.com +cnsikao.com +cnsilkworm.com +cnsimeng.com +cnsimin.com +cnsiwu.com +cnskg.com +cnskyit.com +cnsleep.org +cnslpa.com +cnsnpj.com +cnsnvc.com +cnso.org +cnsoc.org +cnsoftbei.com +cnsoftnews.com +cnsolarwind.com +cnsolomo.com +cnsorl.com +cnspeed.com +cnsphoto.com +cnsrack.com +cnssr.org +cnssssl.com +cnste.org +cnstock.com +cnsudong.com +cnsug.com +cnsun.net +cnsunbird.com +cnsundin.com +cnsuning.com +cnsuv.com +cnsuzi.com +cnswds.com +cnswy.net +cnsynews.com +cnsz.org +cnszjlt.com +cnszxw.com +cnszyzz.com +cnta.com +cntagore.com +cntaiping.com +cntally.com +cntan.net +cntangka.com +cntapp.com +cntaz.com +cntc.com +cntech.com +cnten.com +cnteno.com +cntex-ian.org +cntexjob.com +cntexnet.com +cntgol.com +cntheory.com +cnthinkers.com +cntjq.net +cntle.com +cntlfs.com +cntofu.com +cntopgear.com +cntoplead.com +cntour365.com +cntplus.com +cntrades.com +cntranslators.com +cntries.com +cntronics.com +cntslawfirm.com +cntuw.com +cntv.com +cntvan.com +cntwg.com +cntyjt.com +cntywhcm.com +cnu.cc +cnuninet.net +cnuozu.com +cnur.com +cnuschool.org +cnutcon.com +cnuuu.com +cnvcs.com +cnvf.com +cnvfq.com +cnvn.net +cnvps.com +cnvtech.com +cnwa.com +cnwaci.com +cnwaishi.com +cnwaking.com +cnwansun.com +cnwaternews.com +cnwb.net +cnwbwb.com +cnwear.com +cnweblog.com +cnwebshow.com +cnweiju.com +cnweiming.com +cnweisou.com +cnwest.com +cnwhc.com +cnwindows.com +cnwinenews.com +cnwood-ipp.org +cnwsgj.com +cnwtn.com +cnwutong.com +cnww1985.com +cnww9.com +cnwxw.com +cnwzd.com +cnwzhd.com +cnxcjt.com +cnxclm.com +cnxct.com +cnxds.com +cnxdw.com +cnxfans.com +cnxhacker.com +cnxhyp.com +cnxiangyan.com +cnxiantao.com +cnxianzai.com +cnxiaobai.com +cnxiaoyuan.com +cnxibu.com +cnxieku.com +cnxile.com +cnxincai.com +cnxingoplastics.com +cnxishui.net +cnxk.com +cnxklm.com +cnxmxf.com +cnxnmy.com +cnxos.com +cnxox.com +cnxulong.com +cnxunren.com +cnxuntu.com +cnxyk.com +cnxzm.com +cnyada.net +cnyanglao.com +cnyce.com +cnydgroup.com +cnyeig.com +cnyings.com +cnyipu.com +cnyixun.com +cnyouhao.com +cnypa.org +cnypbx.com +cnys.com +cnytgy.com +cnyw.net +cnywinfo.com +cnyydj.com +cnzcn.net +cnzdfm.com +cnzdhg.com +cnzgc.com +cnzgcec.com +cnzhanting.com +cnzhanzhang.com +cnzhengmu.com +cnzhepai.com +cnzhhy.com +cnzhiyuanhui.com +cnzhjk.com +cnzhongcha.com +cnzhongzhuan.com +cnzici.com +cnzjdd.com +cnzjj.com +cnzjol.com +cnzkzg.com +cnznfy.com +cnzps.com +cnzrc.com +cnzscx.com +cnzskj.com +cnzsqh.com +cnzsrf.com +cnzsyz.com +cnzweal.com +cnzxsoft.com +cnzxwh.com +cnzy56.com +cnzyao.com +cnzzla.com +cnzznz.com +co-effort.com +co-farming.com +co-inclusion.org +co-mall.net +co-mens.com +co-plant.com +co-sail.com +co-trust.com +co188.com +co188cdn.com +co1in.me +co2coin.org +coach-edu.com +coach-japanese.com +coahr.net +coalcloud.net +coalstudy.com +coantec.com +coaoo.com +coastalcitycinema.com +coatingol.com +cobenet.com +cobetterfiltration.com +cobioer.com +coboak.com +cobuy.net +cobvgroup.com +cocas.cc +cocav.com +cocfan.com +cochemist.com +cochicon.com +cocia.org +coco413.com +cocoachina.com +cocodiy.com +cocogoat.work +cocohealthcare.com +cocololo.com +coconuet.com +cocoon-data.com +cocophp.com +cocoren.com +cocos.com +cocos.org +cocos2d-x.org +cocos2d.org +cocos2dx.net +cocosgame.net +cocostudio.org +cocozq.com +cocss.com +codante.org +code-abc.com +code-by.org +code369.com +code666.com +code84.com +codeachange.com +codeages.work +codeaha.com +codebaoku.com +codebe.org +codebuddy.info +codebuddy.net +codebuddy.pro +codebuddy.work +codebus.net +codebye.com +codechina.net +codecomeon.com +codedefault.com +codeeeee.com +codeflying.net +codeforge.com +codehy.com +codeidc.com +codeios.com +codekissyoung.com +codekk.com +codelife.cc +codemart.com +codenews.cc +codeofchina.com +codepku.com +codeplayer.vip +codeplaygames.com +codeprj.com +codepub.com +coder.work +coder100.com +coder4.com +coder55.com +coderbee.net +coderclock.com +codercto.com +coderhuo.tech +coderli.com +codernav.com +coderplanets.com +coderprepares.com +codersec.net +codersrc.com +coderyuan.com +coderzh.com +codes51.com +codesdq.com +codesoft.hk +codess.cc +codetop.cc +codewd.com +codeweblog.com +codeweixin.com +codewoody.com +codex-watch.com +codezh.com +codezyw.com +codigoscript.com +coding-io.com +coding-newsletter.com +coding-pages.com +coding.love +coding.me +coding.net +coding3min.com +codingapp.com +codingchangeworld.com +codingcorp.net +codingdao.com +codingke.com +codingsky.com +codingwhy.com +codingyang.com +codj.net +codm.com +codming.com +codmwest.com +codoon.com +codooncdn.com +coelmont.com +coeusssyp.com +cofco-capital.com +cofco-trust.com +cofco.com +cofcoet.com +cofcofuturesintl.com +cofcoko.com +cofcosp.com +cofcotrading.com +cofeed.com +coffee-hdl.com +coffee-iot.com +coffee-script.org +coffee08.com +coffeecdn.com +coffeejp.com +coffeeofchina.com +coffeeteaimagazine.com +cofferxm.com +cofile.net +cofly.com +cofool.com +cofortest.com +cogcpa.org +cogdelschool.com +cogitosoft.com +cognizepower.com +cogobuy.com +cogolinks.com +cogonline.com +cogskl.com +cohim.com +cohl.com +cohuatech.com +coicjs.org +coin007.com +coin163.com +coinabc.com +coinall.live +coinall.ltd +coincsd.com +coindog.com +coinglo.store +coinhaven.store +coinnice.com +coinrobotics.com +coins-carnival.com +coinsky.com +coinvs.com +coinyue.com +cokll.com +cokutau.com +colahotpot.com +colasmart.com +coldextrusion.com +coldfunction.com +coldlake1.com +coldlar.com +coli688.com +colineapp.com +colinker.com +colipu.com +collaborate.download.prss.microsoft.com +collaborateppe.download.prss.microsoft.com +collect-med.com +collect-v6-51.la +college-ing.com +collt.org +colly-pink.com +collycn.com +colobu.com +colocess.com +color-measure.com +color365.com +colorbird.com +colorfulclouds.net +colorfulltech.net +colorimeter.com +coloros.com +coloros.net +colortechchina.com +colorv.com +coloryr.com +colosseo7143.xyz +colourlife.com +columbia-china.com +columbia-kaiyuan.com +columbia-wuxi.com +com-hs-hkdy.com +com.fi +com.mp +com.tv +com4loves.com +comac.cc +comake.online +combestlogistics.com +combiosz.com +combocn.com +combofin.com +combomen.com +combosm.com +combpm.com +combss.com +comdeep.com +come-bio.com +comebond.com +comebt.com +comefilm.com +comeken.com +comeorg.com +comestuff.com +comet.cc +comeyes.com +comflowy.com +comfylink.com +comiai.com +comic520.com +comicdd.com +comicer.com +comicfans.net +comicv.com +comicyu.com +comiis.com +cominbio.com +comingchina.com +comlan.com +comlbs.com +commchina.net +comme.work +communicatte.com +comnergy.com +comocloud.net +compal.com +companydns.com +compassedu.hk +compevt.com +compgoo.com +complant.com +complemeny.com +complexstudio.net +componentcn.com +composolder.com +compoundsemiconductorchina.net +comprame.com +computeinit.com +computer26.com +comra.org +comsazms.com +comsenz.com +comseoer.com +comsharp.com +comway-mro.com +comweixin.com +comwin-sh.com +con-star.com +con.sh +con3c.com +conan06.com +conantoptical.com +conbagroup.com +conceptan.com +conchdate.com +conchdesktop.com +conco-esd.com +concordiashanghai.org +concordmedical.com +concox.net +concretehr.com +conda-group.com +condorchina.com +cone-x.com +conele.com +conergas.net +conew.com +conextweb.com +confluxrpc.com +conghua.com +congmiqq.com +congratulatiy.com +congresobolivariano.org +congrongfund.com +congtoo.com +congtoukaishi.com +congwuku.com +congyicn.com +congzao.com +congzhi.com +conhagroup.com +conlerpharm.com +conodmedical.com +conoha.vip +conpak.com +conpak.com.hk +conquerom.com +conquerore.com +conshow.com +conslive.com +consmation.com +console-integration.cdnetworks.com +console.cdnetworks.com +constao.com +constar-gd.com +constgroup.com +content4ads.com +contentchina.com +contentstore.htcvive.com +controlinai.com +conuo.com +convertlab.com +convoypayments.com +cony-tech.com +conyedit.com +conyli.cc +coo1read.com +coobar.com +coobos.com +cooboys.com +cooc-china.com +coocaa.com +coocare.com +coocent.net +coodesker.com +coodir.com +coodove.com +coofandy.com +coofans.com +cooffee.net +cooh5.com +coohua.com +cooioo.com +cookcai.com +cookicut.com +cookie4you.com +cookiezhong.com +cool-admin.com +cool-de.com +cool-play.com +coolact.net +coolaf.com +coolapk.com +coolapkmarket.com +coolapkmarket.net +coolaw.com +coolban.com +coolbcloud.com +coolbuy.com +coolcar.cc +coolccloud.com +coolcode.org +coolcode.tech +coolcou.com +cooldock.com +cooldu.com +cooleasy.net +coolecho.net +coolecloud.com +coolexe.com +coolfd.com +coolgaga.com +coolgamebox.com +coolgua.net +coolight.cool +coolkaba.com +coolkit.cc +coolkk.net +coolku.cc +coollf.com +coolmitech.com +coolnull.com +coolook.org +coolool.com +coolpad.com +coolping.com +coolqi.com +coolsdream.com +coolshark.com +coolsite.vip +coolsite360.com +coolsphoto.com +cooltechsh.com +cooltuku.com +cooluc.com +coolwarmsy.com +coolweb.work +coolwei.com +coolxcloud.com +coolxigua.com +coolyun.com +coolzcloud.com +coomix.net +coomo99.com +coomodel.com +coonote.com +cooole.com +coooolfan.com +coooz.com +coopcc.com +cooperningbo.com +coor.work +coordsx.com +cootek.com +cootekos.com +cootekservice.com +coovee.com +coovee.net +coowor.com +cooyun.com +cop.cdnetworks.com +copl.com.hk +copperalliance.asia +copperhome.net +copyedu.com +copyfuture.com +copythelink.com +copywatchstyle.com +cor-games.com +coralset.com +corari.com +core-biopharma.com +corebai.com +coreesports.net +corehalo.com +coremakingsolutions.com +corerain.com +corex-design.com +corgichina.com +corlercar888.com +coros.com +corp-email.com +corp.cc +corpallies.com +corpautohome.com +corpease.net +corpize.com +corpring.com +correoc.asia +coryes.com +cos-beauty.com +cos-show.com +cos126.com +cosbuluo.com +coschat.com +cosco-logisticsqd.com +cosco.com +coscon.com +coscoshipping.com +coscoshippingenergy.com +cosdnsresolve-wxzf.com +cosdnsresolve.com +cosedm.com +cosen.net +coshelper.com +coshin.com +coship.com +cosideabl.com +cosinedu.com +cosineg.com +cosize.com +cosjiang.com +coslinic.com +cosmileonly.com +cosmo-lady.com +cosmoplat.com +cosmoschem.com +cosmosource.com +cosmx.com +cosoar.com +cosofteck.com +cosplay8.com +cosplayla.com +costku.com +costuan.com +cosunter.com +cosxu.com +cosyjoy.com +cosz.com +cotek-robotics.com +cotong.com +cotticoffee.com +cottonchina.org +cotv.tv +couns.com +couplefish.com +couponover.info +couqiao.net +courage-magnet.com +coursegraph.com +courtesya.com +cousz-gd.com +covcec.com +coverequire.com +coverweb.cc +covinda.com +covoart.com +covtv.com +cowarobot.com +cowcs.com +cowealth.com +cowellhealth.com +cowlevel.net +cowrycare.com +cowtransfer.com +coyigroup.com +coyis.com +coyotebio-lab.com +coyuk.com +coyuns.net +coz9uiesr5zv6.com +cozdyez2ap.com +coze.site +cozonenet.com +cp-keji.com +cp0556.com +cp121.com +cp2804.com +cp365.org +cpa51.com +cpaddress.com +cpaed.org +cpajia.com +cpakg.com +cpass.com +cpbao.com +cpcaauto.com +cpcadata.com +cpcccac.com +cpcell.com +cpcep.com +cpciei.org +cpcni.net +cpcphone.com +cpcw.com +cpdad.com +cpdaily.com +cpdasoft.com +cpdhd.com +cpdyj.com +cpe-fund.com +cpecc.net +cpeccgx.net +cpema.org +cpeol.net +cpepgc.com +cpfia.org +cpfwzs.com +cpg-motor.com +cphfgg.com +cphiic.com +cphoto.net +cphoto.org +cphu.org +cpiano.com +cpiaoju.com +cpiccdn.com +cpicfiber.com +cpicfunds.com +cpidi.com +cpihualai.com +cpitsh.org +cpixe.com +cpjltx.com +cplamc.com +cplotus.com +cpm1000.com +cpmiao.net +cpmrc.org +cpnalb.org +cpo.xyz +cpo2o.com +cpolar.com +cpolive.com +cpooo.com +cposchool.com +cpp-prog.com +cpp114.com +cpp32.com +cppb-wg.com +cppblog.com +cppc123.com +cppdebug.com +cppfoto.com +cpph.com +cppinfo.com +cpplay.com +cppoly.com +cpppf.org +cppszw.com +cpqrmyy.com +cpro.baidustatic.com +cproton.com +cps1688.com +cps800.com +cpsbeijing.org +cpse.com +cpsenglish.com +cpt-world.com +cpt123.com +cpt564.com +cptae.com +cptc56.com +cptmcp.com +cptn.tv +cptv2018.com +cpu114.com +cpu668.com +cpu7.com +cpubbs.com +cpuchaopin.com +cpudj.com +cpuh2.com +cpury.com +cpuxn.com +cpvatgkx.com +cpwlx.com +cpwnews.com +cpwzb.com +cpzls.com +cpzst.com +cpzyrj.com +cq-cable.com +cq-city.com +cq-ct.com +cq-ct.tech +cq-eatge.com +cq-gyw.com +cq-md.com +cq-ns.com +cq-pf.com +cq-qqcg.com +cq-rongjia.com +cq-sound.com +cq-tencentclb.cloud +cq-tencentclb.com +cq-tencentclb.net +cq-tencentclb.work +cq-wnl.com +cq-yj.com +cq-yt.com +cq168.com +cq315house.com +cq3a.com +cq5135.com +cq556.com +cq6.com +cq69.com +cq6969.com +cq8.com +cq96868.com +cq9yuan.com +cqaaa.com +cqace.com +cqaflopack.com +cqai.vip +cqaihua.com +cqaky.com +cqallcure.com +cqange.com +cqangel.com +cqanmei.com +cqapg.com +cqaso.com +cqatec.com +cqbafumen.com +cqbayy.com +cqbbzyy.com +cqbdfeng.com +cqbfc.com +cqbm2007.com +cqbnedu.com +cqbnjsjt.com +cqbnrc.com +cqbntv.com +cqbode.com +cqbondrite.com +cqbosai.com +cqbshyy.com +cqbwjc.net +cqbys.com +cqc-ts.com +cqc.so +cqcartest.com +cqcasin.com +cqcatr.com +cqcb.com +cqcbank.com +cqcbd-jbc.com +cqcbl.com +cqccci.com +cqccn.com +cqccsic.com +cqcdbs.com +cqcdc.org +cqcdxl.com +cqcfe.com +cqchinabase.com +cqchuangjing.com +cqcico.com +cqcig.com +cqciig.com +cqcitymedia.com +cqcjnj.com +cqcjxx.com +cqcklib.com +cqcmi.com +cqcmxy.com +cqcoal.com +cqcp.net +cqcpt.com +cqcrane.com +cqcrossmobil.com +cqcsic.com +cqcssk120.com +cqcsskyy.com +cqcy.com +cqcyhuagong.com +cqcyxyxh.com +cqczx.com +cqdahan.com +cqdai.com +cqdailynews.com +cqdaming.com +cqdashun.com +cqdayou.com +cqdc.com +cqdcg.com +cqdcgj.com +cqddpaint.com +cqddyl.com +cqddzx.com +cqdent.com +cqdggs.com +cqdianxin.com +cqdic.com +cqdingqi.com +cqdingyan.com +cqdj.cc +cqdjzyy.com +cqdkj.com +cqdky.com +cqdongnanhospital.com +cqdongyang.com +cqdpt.com +cqdting.com +cqduoliu.com +cqe.cc +cqeca.org +cqedo.com +cqedu.online +cqeec.com +cqelyy.com +cqem.net +cqemme.com +cqenergy.com +cqest.com +cqetcvip.com +cqeyeyy.com +cqfdcxy.com +cqfesco.com +cqfic.com +cqfind.com +cqfire.com +cqfjly.com +cqflct.com +cqfmbank.com +cqfus.com +cqfuyou.com +cqfygzfw.com +cqgaoke.com +cqgc.com +cqgdcy.com +cqgdkf.com +cqgearbox.com +cqgewerv.com +cqggwx.com +cqggx.com +cqggzy.com +cqgh.org +cqgj.net +cqglcj.com +cqglion.com +cqgmfw.com +cqgnhg.com +cqgrain.com +cqgreat.com +cqgsdb.com +cqgtjt.com +cqguangren.com +cqguangrong.com +cqguli.com +cqguohua.com +cqguorui.com +cqgwd.com +cqgwy.org +cqgwzx.com +cqgxjscy.com +cqgxqsmartedu.com +cqgyjsxy.com +cqgyjt.com +cqgymsxx.com +cqgyzone.com +cqgz.com +cqgzdlgc.com +cqgzf.net +cqh2o.com +cqhac.com +cqhansa.com +cqhaofeng.com +cqhasin.com +cqhbcy.net +cqhbzh.com +cqhejuda.com +cqhengbogroup.com +cqhengding.com +cqhengr.com +cqhewin.com +cqhhm.com +cqhimalayanky.com +cqhjj.com +cqhjjt.com +cqhjyzl.com +cqhkcdns.com +cqhkyy.com +cqhma.com +cqhnbsb.com +cqhncd.com +cqhongshuangda.com +cqhouse.net +cqhrjd.com +cqhsjs.com +cqhtu.com +cqhushan.com +cqhwr.com +cqhwzs.com +cqhxdbj666.com +cqhxeye.com +cqhxf.com +cqhxfk.com +cqhxgf.com +cqhxyy.com +cqhxzz.net +cqhyd.com +cqhydraulic.com +cqhyjtss.com +cqhyky.com +cqhylab.com +cqhyyy120.com +cqhz510.com +cqhzjy.com +cqiic.com +cqiivc.com +cqindex.com +cqink.com +cqinstinct.com +cqioe.com +cqios.com +cqiot.cc +cqipa.com +cqipc.net +cqirobot.com +cqiss.com +cqit.com +cqiter.com +cqiti.com +cqitic.com +cqivc.com +cqj.net +cqjat.com +cqjbrc.com +cqjchg.com +cqjdc.com +cqjdgc.com +cqjdgyx.com +cqjdjczx.com +cqjet.com +cqjgx.com +cqjhfk.com +cqjhgczx.com +cqjhsy.com +cqjhtxy.com +cqjiangxue.com +cqjiaxian.com +cqjieli.com +cqjiexun.com +cqjingyu.com +cqjizhi.com +cqjj.net +cqjjnet.com +cqjkhb.com +cqjlyy.net +cqjnjs.com +cqjnkgjt.com +cqjnw.org +cqjob.com +cqjpyg.com +cqjsaq.com +cqjsd.com +cqjtedu.com +cqjtsn.com +cqjunan.com +cqjx.net +cqjy.com +cqjyfcyy.com +cqjyhuida.com +cqjyn.com +cqjyxh.com +cqjzxy.com +cqjzy.com +cqkangshan.com +cqkaogu.com +cqkbjd.com +cqkcyy.com +cqkdtui1.com +cqkeguan.com +cqkejufu.com +cqkepu.com +cqkerui.com +cqkexun.com +cqkeye.com +cqkfb.com +cqkhjt.cc +cqkjb.com +cqkjwx.com +cqkjzyxy.com +cqknls.com +cqkqinfo.com +cqkqjt.com +cqkundian.com +cqkx.com +cqkxhospital.com +cqkytech.com +cqkytq.com +cqlaifu.com +cqlandtower.com +cqlba.com +cqlbjg.com +cqld.com +cqlfn.com +cqlhyy.com +cqlibo.com +cqlilan.com +cqlincom.com +cqlinrui.com +cqliving.com +cqljhr.com +cqljjrjd.com +cqljjt.com +cqljmjs.com +cqljzp.com +cqlkuav.com +cqllfood.com +cqlonghoo.com +cqloway.com +cqlp.com +cqlpa.com +cqls.work +cqlummy.com +cqlxzjzx.com +cqlyckj.com +cqlydc.com +cqlys.com +cqlyy.com +cqlzz.com +cqmaika.com +cqmama.net +cqmanzhong.com +cqmarathon.com +cqmas.com +cqmbkq.com +cqmbyy.com +cqmcu.com +cqmeidoing.com +cqmeiyuan.com +cqmiaoa.com +cqmiaochi.com +cqminghua.com +cqmlmh.com +cqmmgo.com +cqmmjt.com +cqmpf.com +cqmsdq.com +cqmstech.com +cqmtek.com +cqmtswkj.com +cqmva.com +cqmw.com +cqmylike.com +cqmzj.com +cqnc.cc +cqncnews.com +cqndl.com +cqnetcn.com +cqnews.net +cqnhn.com +cqnht.com +cqnkhz4j8nmhqp.com +cqnongzi.com +cqntdq.com +cqnurse.com +cqnx.com +cqnydb.com +cqooc.com +cqpac.com +cqpartek.com +cqpbx.com +cqpearlriver.com +cqpeidu.com +cqpeixin.com +cqpet120.com +cqpfh.com +cqpfjt.com +cqpfmz.com +cqph.com +cqphar.com +cqpix.com +cqpost.com +cqpump.com +cqpwt.com +cqpwy.com +cqpwz.com +cqpx.cc +cqpzjc.com +cqqcjzsj.com +cqqgsafe.com +cqqgx.com +cqqianggu.com +cqqiujing.com +cqqiyi.com +cqqjyy.com +cqqnb.net +cqqnjt.com +cqqp.com +cqqsys.com +cqqsyy.com +cqqttk.com +cqqxxny.com +cqrafk.com +cqrailway.com +cqranxie.com +cqrc.net +cqrcb.com +cqrcdsc.com +cqrcfl.com +cqrfym.com +cqrig.com +cqrksw.com +cqrm.com +cqrmb.com +cqrmrq.com +cqrqdx.com +cqrwys.com +cqryxfp.com +cqs-hm.com +cqsaea.com +cqsamr.com +cqscmy.net +cqsdei.com +cqsdzy.com +cqsfqcpj.com +cqsfybjy.com +cqsgczjxx.org +cqshenou.com +cqshic.com +cqship.com +cqshoucheng.com +cqshrq.com +cqshulan.com +cqshyzx.com +cqsifang.com +cqsj365.com +cqsjb.com +cqsjbc.com +cqsjd.xyz +cqsjky.com +cqsjnzx.com +cqsjsyy.com +cqslhjx.com +cqslim.com +cqslim.net +cqsms.net +cqsoft.org +cqsongshan.com +cqspx.com +cqsq.com +cqssgf.com +cqstgxy.com +cqstjt.com +cqstjzx.com +cqstudents.com +cqsuoqi.com +cqswah.com +cqswjjx.com +cqswxcy.com +cqsx.net +cqsxdb.com +cqsxedu.com +cqsxhb.com +cqsxjsj.com +cqsxrj.com +cqsxsl.com +cqsyjq.com +cqsyjz.com +cqsymj.com +cqsyz.com +cqszfy.com +cqsznyy.com +cqsztech.com +cqszyy.com +cqszyyhyxh.com +cqszzs.com +cqt-top.com +cqtalent.com +cqtally.co +cqtally.com +cqtanlaoda.com +cqtaotan.com +cqtbyy.com +cqtctech.com +cqtea.com +cqtfjs.com +cqtiantai.com +cqtieba.com +cqtkjj.com +cqtkyy.com +cqtl.org +cqtlskj.com +cqtn.com +cqtnfs.com +cqtqzx.com +cqtrans.com +cqtransit.com +cqtrend.com +cqtresearch.com +cqtrvl.com +cqttech.com +cqtuoda.com +cqtxyy.com +cqtyanglao.com +cqtynpx.com +cquae.com +cquc.net +cqud.net +cqudp.com +cqukf.com +cqulit.com +cquni.com +cqvantai.com +cqvavo.com +cqvcet.com +cqvip.com +cqvip.vip +cqvist.net +cqw.cc +cqwanli.com +cqwanshang.com +cqwater.net +cqwbdq.com +cqwbgg.com +cqweh.com +cqwenbo.com +cqwest.com +cqwin.com +cqwlg.com +cqwlzz.com +cqwsnews.net +cqwsrmyy.com +cqwszjs.com +cqwtqc.com +cqwtqx.com +cqwulong.net +cqwuxi.com +cqwxnews.net +cqwzax.com +cqwzwh.com +cqwzwl.com +cqxayl.com +cqxcx.net +cqxdfpr.com +cqxdjgxx.com +cqxdnzyy.com +cqxdyy.com +cqxfxh.com +cqxh120.com +cqxhdc.com +cqxhyz.com +cqxianfeng.com +cqxiheng.com +cqxinge.com +cqxingyun.com +cqxinhua.com +cqxinshuo.com +cqxitou.com +cqxj-hospital.com +cqxjr.net +cqxm-group.com +cqxnyy.com +cqxpxt.com +cqxqz.com +cqxshs.com +cqxsxt.com +cqxszx.net +cqxtcx.com +cqxwdb.com +cqxwtx.com +cqxxly.net +cqxxt.com +cqxyfl.com +cqxygf.com +cqxyjc.com +cqxzxy.com +cqybhr.com +cqybxl.com +cqyc.com +cqyc.net +cqycqzyy.com +cqydgz.com +cqydxy.com +cqyestar.com +cqyfjs.com +cqyfkgjt.com +cqyfsk.com +cqygfm.com +cqyhpx.com +cqyhss.com +cqyhyq.com +cqyingang.com +cqyisen.com +cqyixiao.com +cqyljgxx.com +cqym120.com +cqynzz.com +cqyongfeng.com +cqyouloft.com +cqyqjz.com +cqysgyy.com +cqysp.com +cqysxx.com +cqysxy.com +cqyti.com +cqytjt.com +cqytsw.com +cqytu.com +cqytyk.com +cqyu.com +cqyuanjing.com +cqyuhong.com +cqyunshi.com +cqyuxing.com +cqyuzhoujx.com +cqyx999.com +cqyxlx.com +cqyxzz.com +cqyygz.com +cqyyjc.com +cqyysx.com +cqyyzy.com +cqyznews.com +cqzbcg.com +cqzcjw.com +cqzct.com +cqzdrl.com +cqzgl.com +cqzgzdh.com +cqzhihaolaw.com +cqzhongxingyuan.com +cqzhqyjt.com +cqzikao.com +cqzike.com +cqzk.net +cqzkjs.com +cqzls.com +cqzoan.com +cqzq6.com +cqzql.com +cqzrsh.com +cqzskj.com +cqzuxia.com +cqzww.com +cqzxmoto.com +cqzxrmyy.com +cqzxwx.com +cqzxzlyy.com +cqzyktqxxh.com +cqzymj.com +cqzyx.net +cqzyyd.com +cqzyzs.com +cqzz.net +cqzzcd.com +cr-artisan.com +cr-cts.com +cr-expo.com +cr-leasing.com +cr-newenergy.com +cr-power.com +cr11gcsgd.com +cr15g.com +cr173.com +cr175.com +cr18g.com +cr19gj.com +cr20g.com +cr6868.com +cr8gc.com +crabchina.com +cracmedu.org +craer.com +craftcontact.com +craftria.com +craftsb2b.com +craigmaher.net +craim.net +crandom.com +crane-china.cc +crane-net.com +cranewh.com +crash.work +cravatar.com +crazepony.com +crazybig.fun +crazyenglish.com +crazyflasher.com +crazyjs.org +crazyming.com +crazymoneys.com +crazyones.world +crazyphper.com +crazypm.com +crazyrtc.com +crazywong.com +crbbg.com +crbc.com +crbeverage.com +crbiopharm.com +crc-bj.com +crc.com.hk +crc.hk +crc81.com +crcapm.com +crcccl.com +crccfl.com +crccig.com +crcctc.com +crcebg.com +crcegsd.com +crcement.com +crcgas.com +crchi.com +crclogistics.com +crcrfsp.com +crcsz.com +crct.com +crctrust.com +crdyf.com +cre.net +cread.com +creality.com +crealitycloud.com +creatby.com +createcdigital.com +createpoint.qti.qualcomm.com +createw.com +createwf.com +creati5.com +creation-bj.com +creationventure.com +creative-micro.com +creativityeco.com +creator-sh.com +creatreme.com +creatunion.com +creavidia.com +crec4.com +crec4mc.com +crecexpo.com +crecg-jt.com +crecg.com +crecgi.com +crechan.com +crecohe.com +crecshif.com +crectgroup.com +crecu.com +cred.com +credibleglass.com +credit100.com +creditcn.com +credithc.com +creditrepairjournal.com +creditsailing.com +creditzuji.com +creegc.com +creflux.net +creia.net +creo-support.com +crep-led.com +crepcrep.com +creplus.net +crestv.com +cret-bio.com +crewcn.com +crfchina.com +crfsdi.com +crgdpharm.com +crgecent.com +crggcn.com +crgkxl.com +crgy.com +crhealthcare.com.hk +cri-grandera.com +cri-on.com +criankara.com +criarabic.com +criberlin.com +cribsas.com +cric.com +cric2009.com +cricbigdata.com +cricchina.com +crieasyfm.com +crienglish.com +criezfm.com +crifan.org +crifst.com +crilondon.com +crimoon.net +crimoscow.com +crinductance.com +crinihaochina.com +cririo.com +criseoul.com +crisydney.com +critokyo.com +criwashington.com +crjfw.com +crl.globalsign.net +crl.kaspersky.com +crl.pki.goog +crlf0710.com +crlg.com +crlintex.com +crls.pki.goog +crm.cc +crm1001.com +crmch.com +crmclick.com +crmeb.com +crmeb.net +crmicro.com +crmip.com +crmyy.com +crnews.net +crodigy.com +crodigynat.com +croot.com +croplifechina.org +cross-border-public.com +cross-zone.com +crossborderlion.com +crossingstar.com +crossingstarstudio.com +crossmo.com +crosswaycn.com +crov.com +crown-chain.com +crowndth.com +crowya.com +crpaas.com +crpcg.com +crpharm.com +crracelve.com +crrcgc.cc +crrjz.com +crs811.com +crsc.cc +crscm.com +crsky.com +crsn168.com +crtc-hr.com +crtdri.com +crtg.com +crtrcloud.com +crtrust.com +crtyhr.com +crucg.com +cruelcoding.com +crukings.com +crvc.com +crvic.org +crwnt.com +crx4.com +crxdl.com +crxsoso.com +cry33.com +crysound.com +crystaledu.com +crystalskeleton.com +cryuantafund.com +cs-air.com +cs-airport.com +cs-cjl.com +cs-cydq.com +cs-eval.com +cs-jinwei.com +cs-pos.com +cs-video.com +cs-xf.com +cs0799.com +cs090.com +cs12333.com +cs2-aipn.com +cs27.com +cs2c.com +cs2ccloud.com +cs2pw.com +cs30.net +cs451.com +cs48.com +cs528.com +cs53.com +cs6zhong.com +csair.com +csairdutyfree.com +csairholiday.com +csairshop.com +csapa.org +csarw.org +csaspx.com +csau.com +csbes.com +csbme.org +csbtv.com +csbyjy.com +csc100.com +csc108.com +csc86.com +cscac.net +cscan.co +cscatv.com +cscdf.org +cscec.com +cscec1b-bj.com +cscec1b.net +cscec7b.com +cscec81.com +cscec8bud.com +cscecbjadi.com +cscecparking.com +csci.hk +cscjedu.com +csclc.com +cscmgg.com +csct-china.com +cscxsemi.com +csd568.com +csdc.info +csdczx.com +csdeshang.com +csdewater.com +csdh.com +csdhe.com +csdhxx.com +csdiy.wiki +csdk.com +csdn.com +csdn.net +csdn.work +csdyjs.net +csdyx.com +cse-bidding.com +csea1991.org +csebank.com +csec-tencentclb.cloud +csec-tencentclb.com +csec-tencentclb.net +csec-tencentclb.work +csemc.com +cseptc.net +cserveriip.com +cserwen.com +cseve.com +csflgg.com +csflwl.com +csfounder.com +csfreezer.com +csftyy.com +csfudu.com +csfybjy.com +csgasgroup.com +csgcjxxh.com +csgcyy.com +csgdjtxy.com +csgfjc.com +csghy.com +csgjhzzx.com +csgjjgxx.com +csgjjt.com +csgkjt.com +csgocn.net +csgongshui.com +csgpc.org +csgwexpo.com +csgxyl.com +cshaodu.com +csharpkit.com +cshbl.com +cshbxy.com +cshcp.com +cshijian.com +cshixi.com +cshltx.com +cshnac.com +cshnkj.com +cshrzc.com +cshslf.com +cshst.com +cshuanyu.com +cshufanyi.com +cshxdc.com +cshxschool.com +cshypg.com +cshzywkj.com +csiamd.com +csic-711.com +csic612.com +csic6801.com +csic76.com +csicmakers.com +csicpl.com +csictec.net +csiea.net +csig158.com +csiic.com +csilp.com +csimcc.com +csisolar.com +csj-stcloud.com +csjcs.com +csjdeveloper.com +csjgwy.com +csjiexin.com +csjitian.com +csjkjs.com +csjkjt.com +csjmould.com +csjmzy.com +csjqfz.com +csjsdz.com +csjtys.net +csjtz.com +csjunwei.com +csjvision.com +csjwang.com +cskaoyan.com +cskefu.com +cskjgc.com +cskliz.com +cskrl.com +csksoft.net +cskx.com +cskxjk.com +cslbbs.net +cslfans.com +cslgfd.com +cslkjt.com +cslou.com +cslxzx.com +cslyrc.com +csmadik.com +csmall.com +csmama.net +csmar.com +csmbcx.com +csmc-cloud.com +csmedlab.com +csmh-semi.com +csmjzs.com +csmscon.com +csmxh.com +csmzxy.com +csnbgsh.com +csnhjyxx.com +csnhszjy.com +csnhw.com +csnzxl.com +csoly.com +csomdmyxy.com +csomick.com +cspasz.org +cspbj.com +cspcbaike.com +cspda.net +cspengyuan.com +cspiii.com +cspmk.com +cspplaza.com +cspro.org +cspruc.com +csptia.org +csqsg.com +csrcare.com +csrcbank.com +csrcsc.com +csrda.com +csres.com +csrgm.com +csrlzyw.com +csrunhe.com +css-js.com +css3er.com +css6.com +css88.com +cssaaa.com +cssbe.com +cssbkj.com +cssbyy.com +cssccq.com +csscia.com +csscmall.com +cssdsyy.com +csseplastic.com +cssf.cc +cssf.com +cssf.net +cssforest.org +cssfybjy.com +cssg-ahi.com +csshenda.com +csshenyu.com +csshjdxh.com +csshuobo.com +cssjzy.com +csslcloud.net +cssmagic.net +cssmoban.com +cssqt.com +cssthxx.com +csstoday.net +cssuez.com +cssywgy.com +csszone.net +cst119.com +cst6.com +cstccloud.org +cstcloud.net +cstcq.com +csteamian.work +cstech.ltd +csteelnews.com +cstexun.com +csthxx.com +cstianye.com +cstimer.net +csto.com +cstonepharma.com +cstong.net +cstparking.com +cstriker1407.info +cstuotian.net +cstxgz.com +csuboy.com +csuct.com +csudgroup.com +csuedu.com +csundec.com +csunews.com +csur.fun +csvii.com +csvw.com +csw333.com +cswamp.com +cswef.org +csweigou.com +csweiwei.com +cswqvzh.com +cswszy.com +csxbank.com +csxdf.com +csxiangfeng.com +csxingfutemple.org +csxingya.com +csxinhua.com +csxinshun.com +csxinxu.com +csxjedu.com +csxjzx.com +csxsjc.com +csxsrcw.com +csxww.com +csy17.com +csyamei.com +csyestar.com +csygz5c6qk.best +csykgs.com +csylxy.com +csylzx.net +csyrtcs.com +csysgz.com +csytv.com +csyunkj.com +csyuwei.com +cszec.com +cszhgjzx.com +cszhjt.com +cszhonghui.com +cszhxf119.com +cszit.com +cszjgj.com +cszjzx.com +cszkzn.com +cszlgs.com +cszn120.com +cszpra.com +cszsjy.com +csztv.com +cszuxing.com +cszx.com +cszyedu.com +cszyjsxx.com +cszykt.com +ct-cdm.com +ct-emall.com +ct-laser.com +ct-parking.com +ct108.com +ct52.com +cta613.org +ctaca.com +ctags.net +ctalive.com +ctans.com +ctaweb.org +ctb50.com +ctbcdn.com +ctbcleasing.com +ctbjia888.com +ctbpsp.com +ctbyq.net +ctc-ctc.com +ctc-zj.com +ctc.lol +ctc100.com +ctcai.com +ctcdn.com +ctcdn.net +ctcdn.org +ctcdnov.net +ctce8.com +ctcefive.com +ctcisz.com +ctcloudmeeting.com +ctcmo.com +ctcnj.net +ctcnn.com +ctcnpa.com +ctcontents.com +ctcsci.com +ctcsz.com +ctcwri.org +ctcxzgs.com +ctdatacare.com +ctdcdn.com +ctdcn.com +ctdisk.com +ctdns.net +ctdns.org +ctdsb.com +ctdsb.net +ctdzsk.com +ctea-ctea.org +cteaw.com +cteb.com +ctecdcs.com +ctech-alpha.com +cteic.com +ctex.org +ctexcel.ca +ctexcel.com +ctexcel.com.hk +ctexcel.fr +ctexcel.us +ctexw.com +ctfhub.com +ctfile.com +ctfile.net +ctfmall.com +ctfo.com +ctftools.com +ctfund.com +ctgapp.com +ctgcdn.com +ctghealthy.com +ctghr.com +ctghro.com +ctgia.com +ctgne.com +cthcdn.com +cthcdn.net +cthgjx.com +cthh9mnv.com +cthhmu.com +cthj-co.com +cthuwork.com +cthuwork.net +cthy.com +cti-cert.com +ctibet.com +ctic-lab.com +ctic-labs.com +ctiea.com +ctiforum.com +ctiku.com +ctils.com +ctimall.com +ctime.com +ctiot.info +ctipckcx.com +ctis-cn.com +ctjin.com +ctjituan.com +ctjl.net +ctjsoft.com +ctkon.com +ctkq.com +ctlcdn.com +ctlcdn.net +ctlife.tv +ctma.net +ctmcdn.com +ctmcdn.net +ctmcq.com +ctmgid.com +ctmon.com +ctmwow.com +ctn1986.com +ctnma.com +ctntech.com +ctnyypt.com +ctnz.net +ctocio.com +ctoclub.com +ctongonline.com +ctoutiao.com +ctovcdn.com +ctpdd.com +ctrcw.net +ctrender.com +ctrip-ttd.hk +ctrip.co.id +ctrip.co.kr +ctrip.co.th +ctrip.com +ctrip.com.hk +ctrip.my +ctrip.sg +ctripbiz.com +ctripbuy.hk +ctripc.com +ctripgslb.com +ctripins.com +ctripqa.com +ctripteam.com +cts010.com +ctsbw.com +ctsec.com +ctsfreight.com +ctsgx.com +ctshk.com +ctsho.com +ctsitravel.com +ctsmed.com +ctsscs.com +ctssd.com +ctsto.com +ctszh.com +ctszs.com +cttbj.com +cttgd.com +cttip.org +cttms.com +cttpptrs-pt.cfd +cttptru-pt.icu +cttq.com +cttsd.com +cttv.co +ctuaa.com +ctv56.org +ctvpost.com +ctvrd.org +ctvwx.com +ctwx.net +ctwxc.com +ctxcdn.com +ctxcdn.net +ctxcpa.com +ctxirang.com +cty9.com +ctycdn.com +ctycdn.net +ctycdn.org +ctyny.com +ctyo.com +ctyun.net +ctyun.online +ctyuncdn.com +ctyuncdn.net +ctyuninner.com +ctyunwaf.com +ctyunwaf1.com +ctzb.com +ctzcdn.com +ctzcdn.net +ctzg.com +cu-air.com +cu5gaia.com +cuaa.net +cuahmap.com +cuav.net +cubavcenter.com +cubead.com +cubegoal.com +cubejoy.com +cubespace.city +cubestation.com +cubicise.com +cubie.cc +cubing.com +cubox.pro +cucdc.com +cuchost.com +cucldk.com +cuctv.com +cueber.com +cuebzzy.com +cuelog.com +cufeyk.com +cugala.com +cuggw.com +cugroup.com +cugstore.com +cuhnj.com +cui1000.com +cuihuan.net +cuijiahua.com +cuilai.com +cuiniaoedu.com +cuiniuhui.com +cuiqingcai.com +cuiru123.com +cuiruo.com +cuirushi.com +cuiuc.com +cuiv.com +cuixingreen.com +cuixueshe.com +cuiyongjian.com +cuiyouxuan.com +cujs.com +cuketest.com +cul-studies.com +culaiwan.com +culdata.com +culia.org +culiangwang.org +culturemagasin.com +cumboly.com +cumen.fun +cummins-cq.com +cumtenn.com +cumulon.com +cunan.com +cuncunle.com +cuncwg.com +cunfang.com +cunhao.net +cunliangtech.com +cunnar.com +cunshao.com +cunylyu.work +cunyoulu.com +cunzhen.vip +cunzj.com +cuobiezi.net +cuonc.com +cuopen.net +cuour-edu.com +cuour.com +cuour.org +cuoxin.com +cupdapp.com +cupdata.com +cupddns.com +cupddns.net +cupdns.com +cupfox.com +cupinn.com +cuplayer.com +cuplayer.net +cupmcn.com +cuppot.com +curlc.com +current.vc +cursor.zone +curtisasia.com +cusdvs.com +cusdvs.net +custeel.com +customization-cdn.dell.com +customizedfasteners.com +customsapp.com +customskh.org +custouch.com +custpref.com +cutemidi.com +cuteng.com +cutepet-hk.com +cutieshop153.com +cutowallpaper.com +cutv.com +cuuhn.com +cuumo.com +cux.cc +cuz.cx +cuzz.site +cvc898cvc.com +cvchome.com +cvcri.com +cvftc.net +cvicse.com +cvicseks.com +cvillazc.com +cvmart.net +cvmassageocs.com +cvn-china.com +cvoazsxs.cfd +cvoesnzau.cfd +cvoit.com +cvonet.com +cvoon.com +cvpyqih.com +cvrobot.net +cvszavosz.icu +cvtapi.com +cvte.com +cvtestatic.com +cvtvcn.com +cwag.com +cwbaike.com +cwbgp.space +cwbpsi.com +cwcec.com +cwdma.org +cwdtf.com +cwems.com +cwestc.com +cweun.org +cwewater.com +cwfls.com +cwgarnet.com +cwgsdl.com +cwhnh.com +cwiaj.com +cwitxoakk98d.com +cwjedu.com +cwjt.com +cwlchina.com +cwliupaotea.com +cwmcs.com +cwmtn.com +cwmzyyy.com +cwouzcmp.com +cwq.com +cwst.net +cwtc.com +cwun.org +cwxzx.com +cwyan.com +cwz12123.com +cwzdgroup.com +cwzww.com +cx-smarthome.com +cx.cc +cx001.com +cx312.com +cx368.com +cx580.com +cx930.net +cxacg.com +cxas.com +cxbbattery.com +cxbiji.com +cxbio.com +cxbsx.com +cxbz958.com +cxc233.com +cxcc.me +cxcentury.com +cxcijiedu.com +cxcyds.com +cxdm-tech.com +cxdqkj.com +cxdz2000.com +cxf1999.com +cxfccs.com +cxfuwu.com +cxgame.net +cxgaugrv.com +cxgeo.com +cxgj56.com +cxglmc.com +cxglys.com +cxgw.com +cxh99.com +cxhan.com +cxhl365.net +cxhr.com +cxhuoyun.com +cxhyy.com +cxic.com +cximg.com +cxisc.com +cxjrh.com +cxjt.net +cxju.com +cxkfwn.com +cxkjjy.com +cxkyz.com +cxlyzj.com +cxmld.com +cxmoe.com +cxmt.com +cxmtc.net +cxnyjt.com +cxnykjy.com +cxory.com +cxpharm.com +cxqex.com +cxql.net +cxrczpw.com +cxsdszx.com +cxsk.work +cxsm.com +cxstar.com +cxsteel.com +cxstgc.com +cxsw3d.com +cxta.com +cxthhhhh.com +cxtld.com +cxtrip.cc +cxtuku.com +cxumol.com +cxvlog.com +cxw.com +cxwl.com +cxwyf.net +cxxjs.com +cxy521.com +cxy61.com +cxy7.com +cxybattery.com +cxycsx.vip +cxydh.xyz +cxydw.net +cxyfjd.com +cxylfc.com +cxylx.com +cxyob.com +cxytiandi.com +cxyule.com +cxyxiaowu.com +cxyxwl.com +cxyyls.com +cxyym.com +cxz.com +cxzg.com +cxzntc.com +cxzw.com +cxzyjt.com +cy-cdn.com +cy-coo.com +cy-credit.com +cy-email.com +cy-isp.com +cy-isp.net +cy-jg.com +cy-jm.com +cy-mmm.com +cy-pharm.com +cy-scm.com +cy-ymtw.com +cy.com +cy2009.com +cy365.com +cy580.com +cy88.com +cyagen.com +cyalarm.com +cyanhillcapital.com +cyanpeach.com +cyb-bot.com +cyb800.com +cybaojian.com +cyberspace.com +cybertogether.net +cyberway-china.net +cybstar.com +cybtc.com +cyc2018.xyz +cychaiqian.com +cyclemixcn.com +cyclewell.com +cyclingchina.net +cyclone-robotics.com +cyclonemoto.com +cycnet.com +cycoo.com +cyctapp.com +cyd5918.com +cydiaa.com +cydiakk.com +cydow.com +cyegushi.com +cyfeng.com +cyfengchao.com +cyflscb.com +cyfyydyfy.com +cygbdst.com +cygia.com +cygs.com +cygse.com +cyhazyy.com +cyhlwhb.com +cyhlwmt.com +cyhm.com +cyhone.com +cyhx98.com +cyicts.com +cyida.com +cyie.com +cyikao.com +cyimking.com +cyjcloud.com +cyjhfm.com +cyjiasu.com +cyjjw.net +cyjlighting.com +cyjoycity.com +cyjsh.com +cyjysb.com +cyjyxxw.com +cyjzzd.com +cyk-cable.com +cyktqdrp.com +cylaowu.com +cylh.com +cylink.bond +cylong.com +cymcgs.com +cynee.net +cynovan.com +cyo.cc +cyol.com +cyol.net +cyou-inc.com +cyoupic.com +cyouzai.com +cypatent.com +cypharma.com +cyphouse.com +cypmedia.com +cypresstel.com +cyprestar.com +cyqyfyxh.com +cyr168.com +cyruc.com +cyrx.com +cys.world +cysq.com +cystool.com +cyswkj.com +cyswxa.com +cysy-cn.com +cysygroup.com +cyszxyy.com +cyt369.com +cytcard.com +cytoniche.com +cytosinlab.com +cyts.com +cytsdl.com +cytslinkage.com +cytsls.com +cytsonline.com +cytstibet.com +cytuig.com +cyuandao.com +cyudun.net +cyuew.com +cyuntech.com +cyuyin.com +cyvalve.com +cywetc.com +cywl.org +cywlxy.com +cywyjj.com +cyxh.org +cyxigua.com +cyxny.net +cyxshop.com +cyy18.com +cyyangqiguan.com +cyycdn.com +cyyo.vip +cyypscl.com +cyyself.name +cyyvip.com +cyzl.com +cyzm.net +cyzs97.com +cyzwb.com +cyzywl.com +cyzzzz.com +cz-toshiba.com +cz-yk.com +cz121.com +cz128.com +cz88.net +cz89.com +czb365.com +czbanbantong.com +czbank.com +czbcpaint.com +czbq.net +czbtv.com +czbx18.com +czcarbon.com +czcdt.com +czcgewater.com +czchuanlin.com +czchyz.com +czcia.com +czcid.com +czclzc.com +czcqly.com +czctech.com +czdaiwei.com +czddbearing.com +czdingming.com +czdlj.com +czdqyy.com +czdsfy.com +czduxinban.com +czdyrmyy.com +czech-visacenter.com +czedu.com +czepb.com +czey.com +czfangshuo.com +czfcdp.com +czfcw.com +czfdc.com +czfesco-mg.com +czfhdmls.com +czfph.com +czgcsb.com +czgd.tv +czgdly.com +czgjj.com +czgjj.net +czgmjsj.com +czgongzuo.com +czgtjt.com +czguangfu.org +czhaobiao.com +czhbgx.com +czhjs.com +czhmjx.com +czhtff.com +czhuayuansuye.com +czie.net +czifi.org +czinfo.net +czitc.com +czjake.com +czjdgz.com +czjdjt.com +czjdu.com +czjfa.com +czjiangteng.com +czjilijia.com +czjju.com +czjlsb.com +czjoel.com +czjpw.com +czjsy.com +czjyzx.net +czkbdq.net +czkctl.com +czkingdee.com +czlgj.com +czlingke.com +czlkgy.com +czlsgz.com +czlskj.com +czlxgc.net +czmarathon.net +czmc.com +czmh.com +czmstt.com +czmw.com +czmypx.com +cznengshuo.com +cznewcom.com +czolgame.com +czongyi.com +czopen.com +czpbxc.com +czpoly.com +czpv.net +czqingzhifeng.com +czqqkj.com +czrcw.com +czrjh.com +czrmyy.com +czrsymt.com +czsafjx.com +czsbtjx.com +czsfy.com +czsldy.com +czsmk.com +czsrc.com +czsrmyy.com +czsshb.com +czstx.net +czswdx.com +cztaojiu.com +cztour.com +cztrjs.com +cztv.cc +cztv.com +cztv.tv +cztvcdn.com +cztvcloud.com +cztzkg.com +czur.com +czvv.net +czwie.com +czws.com +czwsg5.com +czwxbyq.com +czwxtz.com +czxiu.com +czxixi.com +czxixigu.com +czxr.net +czxthmls.com +czxuexi.com +czxxp.com +czxxw.com +czxy.com +czyabo.com +czybjz.com +czyefy.com +czyfxd.com +czyl.cc +czyongfeng.com +czypcb.com +czyuxing.com +czyxba.com +czzqp.com +czzsw.com +czzy-edu.com +czzyc.com +czzyvideo.com +czzzbwg.com +d-controls.com +d-ctrip.com +d-d.design +d-heaven.com +d-innovation.com +d-long.com +d-robotics.cc +d-stars.net +d-techs.com +d-wolves.com +d.cg +d.design +d00.net +d03jd.com +d05512bf210292.beer +d0be5a65855b67f1.com +d0bf4234011011.beer +d0ff97cf35c6a919.com +d10a.com +d11180a781015.beer +d11a.com +d1226c9c010311.beer +d13fa03a1909beae.com +d163.net +d17.cc +d1be4a4fdf902c14.com +d1c73dbb1de91850.com +d1cm.com +d1com.com +d1cy.com +d1dengju.com +d1dytt.com +d1ev.com +d1f20dc1910272.beer +d1f25004011021.beer +d1f41d7b74d2717d.com +d1ld.com +d1lx.com +d1miao.com +d1mm.com +d1net.com +d1rcw.com +d1sm.net +d1xf.net +d1xn.com +d1xny.com +d1y.cc +d20d0896ac7f79d3.com +d22a.com +d22fa4e66e2dbda2.com +d23c41a0511031.beer +d27c2e00d10251.beer +d2940a1d3924e37f.com +d2core.com +d2film.com +d2kdi2ss.com +d2scdn.com +d2shost.com +d2ty.com +d2ziran.com +d30c8d2641021.beer +d3490d69fd4b2039.com +d3581247411021.beer +d37hw752kt.com +d3bc311b910311.beer +d3ch.com +d3cn.net +d3e5f7g9.work +d3eurostreet.com +d3f.com +d3games.com +d3iz9md.com +d3tt.com +d3zone.com +d4000.com +d406dc73a1016.beer +d475a937d0e92b96.com +d48c3443110281.beer +d4cd5439c1009.beer +d4ctech.com +d4z1onkegyrs5.cloudfront.net +d54a00143de85b64.com +d56c84cfb4a786f7.com +d58.net +d5a18ed7b2f74e45.com +d5h.net +d5power.com +d5render.com +d5xs.net +d65d6.com +d65fee3222cbaf80.com +d6861213910261.beer +d6ffdb55d1009.beer +d7585a05210281.beer +d777.com +d7e29629277.luxe +d7ftpecw.work +d7vg.com +d7w.net +d837c367d34d7bb5.com +d8e8664c05df452c.com +d8fb1ffab10251.beer +d8th.com +d90eeacb0ed722f9.com +d920c164caf0ebba.com +d959fb95dd5cc433.com +d9741b1859dfcfee.com +d99net.net +d9af5a60.edmonst.net +d9b5cc7f82ccfc18.com +d9j8.com +d9js.com +d9k99.com +d9ym.com +da-mai.com +da-quan.net +da.anythinktech.com +da.biz +da01.com +da3h.com +da563c3c21010.beer +da88.net +daai.fun +daanbar.com +daanche.com +daangene.com +daanjiexi.com +daanwang.com +daanwo.com +daanxi.com +daas-auto.com +daba.com +dabai4.com +dabaicai.org +dabaidaojia.com +dabaise.com +dabangong.com +dabangsoft.com +dabanke.com +dabao123.com +dabao22.com +dabaoge.host +dabapiao.com +dabaqian.com +dabeiduo.com +dabiaoji.info +dabiaojituan.com +dabieshu.com +dabin69.com +dabingseo.com +dabjy.com +daboluo.net +dabusi.com +dacai.com +dacang.ltd +dacankao.com +dacankao.net +dacaomei.com +dacbiotech.com +daccc.com +daccf.com +dachanet.com +dachao.com +dachaokn.com +dachaoshan.org +dachengbiochemical.com +dachengge.com +dachenglaw.com +dachengsh.com +dachengshuiwu.com +dachengzi.net +dachkj.com +dachuanchina.com +dachuizichan.com +dachun.tv +dachushicai.com +dad86b446ac9f8b7.com +dada114.net +dada360.com +dadaabc.com +dadagame.com +dadagem.xyz +dadajiasu.com +dadaogroup.com +dadaojiayuan.com +dadaqipai.com +dadasasa.com +dadasou.com +dadateach.com +dadayou.com +dadclab.com +daddybaby.com +daddymami.net +daddysweety.com +dadeedu.com +dadetong.com +dadicinema.com +dadighost.com +dadikid.net +dadisalt.com +dadiwang.com +dadiyimao.com +dadongwu.com +dadou.com +daduoduo.com +daduofa.com +dadushixiecheng.com +daeac4faf10292.beer +daerzhu.com +daeshin-china.com +daf-rs.com +daf30622c1010.beer +dafaji.com +dafang24.com +dafangtour.net +dafangya.com +dafanshu.com +dafaun.com +dafenghk.com +dafenghk.net +dafmgroup.com +dafork.com +dafosi.org +dagangcheng.com +dagongcredit.com +dagongnet.com +dagongtech.com +daguan.com +daguangnews.com +dagufood.com +daguiot.com +daguipc.com +dagun.net +daguzhe.com +dagyujt.com +dahachuxing.com +dahai96.com +dahainan.com +dahaiwater.com +dahaiyang.com +dahan-sports.com +dahanghaiol.com +dahangroup.com +dahangsky.com +dahangzhou.com +dahantc.com +dahanyinbang.com +dahanyu.com +dahao-dahao.com +dahaoexpo.com +daheapp.com +dahecube.com +dahei.com +daheng-image.com +daheng-imaging.com +daheng-imavision.com +dahengit.com +dahepiao.com +dahetest.com +dahongba.net +dahongtec.com +dahongtool.com +dahouduan.com +dahua-cpa.com +dahua-ferrules.com +dahuaab.com +dahuabloc.com +dahuaddns.com +dahuagong.com +dahualan.com +dahuap2p.com +dahuap2pcloud.com +dahuasurvey.com +dahuatech.com +dahuawang.com +dahuhg.com +dahuifuwu.com +dahuodong.com +dai-shi.com +dai361.com +daiaotech.com +daiban0571.com +daibanke.com +daibi.com +daicelchina.com +daicuo.cc +daicuo.net +daidaicp.com +daidaipu.com +daidongxi.com +daigege.com +daigou.com +daigraphia.com +daihaobiao.com +daihing.com +daijuchuang.net +daijun.com +daikandq.com +daikuan.com +daili321.com +dailianmama.com +dailianqun.com +dailiantong.com +dailianzj.com +dailiba.com +dailijizhang.cc +dailiweishang.com +dailugou.com +dailybing.com +dailygn.com +dailyqd.com +daimafans.com +daimagongfang.com +daimami.com +daimao.work +daimawang.com +daimay.com +daimg.com +dainiter.com +dairao.net +daishangqian.com +daishanmarathon.com +daishu.com +daishucha.com +daishujiankang.com +daishutijian.com +daisyfin.com +daita.red +daittotrade.com +daivc.com +daiwofly.com +daiwoqu.com +daixiaji.net +daixiaobao.com +daixiaomi.com +daixiaorui.com +daixiehyl.com +daiyanbao.com +daiyanmama.com +daiyinzi.com +daizitouxiang.com +dajan.com +dajiabao.com +dajiachou.com +dajiadou6.com +dajiadu8.com +dajiaka.com +dajialaikan.com +dajialawyer.com +dajianet.com +dajiang365.com +dajiangsai.org +dajiangtai.com +dajianhui.com +dajianyouju.com +dajiashequ.com +dajiashuo.com +dajiazhao.com +dajiazhongyi.com +dajiazulin.com +dajibacdn.com +dajibapass.com +dajie.com +dajieimg.com +dajilin.com +dajinan.com +dajingdiao.com +dajingmed.com +dajixie.com +dajke.com +dajudeng.com +dajuntech.com +dajuyuan.net +daka.net +dakage.com +dakahr.com +dakamao8.com +dakangchem.com +dakangmedical.com +dakao100.com +dakao8.com +dakao8.net +dakapath.com +dakaruanwen.com +dakasi.com +dakedakedu.com +dakejie.com +dakekj.com +dakele.com +dakw.xyz +dalaba.com +dalanyouxi.com +dalao.net +dalaosz.com +daleigroup.com +dalelingtea.com +dali-group.com +dalian-chuanpiao.com +dalianair-china.com +dalianbus.com +daliancs.com +dalianiso.com +dalianjiaojing.com +dalianshengmi.com +daliansky.net +daliantyre.com +dalianwater.com +dalianxianting.com +daliaolaser.com +daliapp.net +dalidaily.com +dalidm.com +dalifa.com +daliha.com +dalipan.com +dalisanta.com +dalongkeji.com +dalongyun.com +daltonbio.com +dalu.net +daluma.com +daluo.com +daluom.com +daluwang.net +daluxinxi.com +dalvhe.com +dalvlaw.com +dalwiaavieru.com +dalwiaebulon.com +dalwiakieyne.com +dalwiaresham.com +dalwl.work +dalyfeds.com +damai.com +damaicheng.com +damaimed.com +damao.city +damatu1.com +damddos.com +dameisheng.com +dameiweb.com +dameng.com +damiercapital.com +damijing.com +damingweb.com +damiw.com +damixs.biz +damndigital.com +damo-academy.com +damodel.com +damonroller.com +damostar.com +damotu.com +damoyang.com +damuchong.com +damuite.com +dan-my.com +dan-sing.com +dan8gui.com +danale.com +danaleplatform.com +danaonao.org +danaqsy.com +danatlas.com +danbagui.com +danbaodan.com +dance365.com +danceinchina.org +dancf.com +danchuangglobal.com +dancihu.com +dancingcg.com +dancizhan.com +dandaiqh.com +dandan818.com +dandang.org +dandanhou.net +dandanjiang.tv +dandanman.com +dandanplay.com +dandanplayer.com +dandantang.com +dandanvoice.com +dandanz.com +dandanzan.com +dandanzkw.com +danding.com +danding.fun +dandinghuayi.com +dandongbank.com +dandou.com +danews.cc +dang-jian.com +dang3.com +dangaocn.com +dangaoss.com +dangbei.com +dangbei.net +dangbeiprojector.com +dangbiao.com +dangcdn.com +dangdaiyiyao.com +dangdang.com +dangdj.com +dangguai.com +danghongyun.com +danghuan.com +dangjian.com +dangjianwang.com +dangjinguiping.com +dangpu.com +dangtianle.com +dangwan.com +dangzhi.com +dangzhi.net +dangzhu.net +dangzhuntianqi.com +danhao51.com +danhaowang.org +danhuaer.com +danhuangyun.com +daniao.org +danilelxp.com +daningcenter.com +daningdaning.com +daningtv.com +daniopack.com +daniuguwang.com +daniuit.com +daniujiaoyu.com +daniushiwan.com +daniuwangxiao.com +danji100.com +danji6.com +danji8.com +danji9.com +danjiang.com +danjuanapp.com +danjuanfunds.com +danjuantaxi.com +danjuantec.com +danke.com +dankegongyu.com +dankexiaoyuan.com +danlan.org +danlancare.com +danlanlove.com +danlingfuyou.com +danlirencomedy.com +danlu.net +danmaku.live +danmaku.tv +danmakupie.com +danmi.com +danming-ic.com +danmo.com +danmofun.com +danmoshui.com +danmu.com +danniao.com +danotest.com +danpin.com +danqi.com +danten.org +danteng.me +dantengge.org +dantin.com +dantins.com +dantuvc.com +danwukeji.com +danxia.com +danxin.net +danyang.com +danzhaoedu.com +danzhou8.com +dao-fu.com +dao123.com +dao3.fun +dao42.com +dao50.com +daoapp.io +daoapp.me +daoboime.com +daochen.com +daocloud.io +daocloud.vip +daocloudapp.com +daodao.com +daodaojizhang.com +daodaozz.com +daodejing.org +daodian100.com +daodianfu.com +daodoc.com +daododo.com +daoduoduo.com +daofengdj.com +daoguo.com +daohang198.com +daohang4.com +daohang88.com +daohangtx.com +daohu123.com +daohui.net +daohuo.shop +daoiqi.com +daoisms.org +daojia-inc.com +daojia.com +daojiale.com +daojialianmeng.com +daojishiqi.com +daojishiwang.com +daokers.com +daokeyuedu.com +daokoudai.com +daomengad.com +daomengren.com +daomicfo.com +daomuol.com +daonong.com +daopei.net +daopub.com +daoqin.net +daoran.tv +daoru.in +daoruimi.com +daoscript.org +daoshui.com +daotin.com +daotour.com +daotudashi.com +daovay.com +daovoice.io +daoxiangcun.com +daoxila.com +daoxila.net +daoyu.fun +daoyu.me +daoyu8.com +daoyumiao.com +daozhao.com +dapai8.com +dapan.com +dapei.cc +dapenggangguanchang.com +dapenti.com +dapingshidai.com +dapiniu.com +dappdiscover.com +dapustor.com +daqi.com +daqiao.host +daqiguanli.com +daqihui.com +daqing8080.com +daqiso.com +daqizhong.com +daqo.com +daqqd.com +daqsoft.com +daquan.com +daquan.la +daquangroup.com +daquncnc.com +daraz.lk +daraz.pk +darczpw.com +dare-auto.com +darehui.com +daren.today +darenfund.com +darenjiazu.com +darensky.com +dareu.com +darewayhealth.com +darkcloudpiece.com +darkmi.com +darknight.games +darmao.com +darongcheng.com +darryring.com +dartchina.com +dartou.com +dartsearch-cn.net +dartzon.com +daruan.com +darwinlearns.com +dasctf.com +dasfbio.com +dasfjd.com +dashanghaizhuce.com +dashangu.com +dashen520.com +dashen8.com +dashengji.com +dashengpan.com +dashengshan.com +dashengzuji.com +dashenquan.com +dashentv.com +dashenw.com +dashgame.com +dashi518.com +dashichang.work +dashigame.com +dashikou.com +dashisx.com +dashitech.com +dashiyou.com +dashu.com +dashubaba.com +dashuju123.com +dasiyingyu.com +dasong108.com +dasoujia.com +dassm.com +dasuan110.com +dasuanwang.com +dasung.com +dasungtech.com +dat881.com +data-speaker.com +data380.com +data4h.com +data5u.com +data86.com +data86.net +data985.com +dataarobotics.com +datacanvas.com +datacname.com +datacomo.com +datacvg.com +datadragon.net +dataduoduo.com +dataesb.com +dataeye.com +datafun.vip +datag.vip +datagear.tech +datagrand.com +datahome2026.com +datahubtrack.com +datahuif.com +dataie.com +dataing.com +datang.com +datang.net +datangnxp.com +datangweishi.com +datangyouxi-inc.com +datangyouxia.com +datangyouxib.com +datangyouxic.com +datangyouxie.com +datangzww.com +dataodu.com +dataojo.com +dataoke.com +datarelab.com +datarj.com +datasheet.hk +datasheet5.com +datastoragesummit.com +datatang.com +datatech-info.com +datatist.com +datatocn.com +datatool.vip +datauseful.com +dataxcrm.com +datayes.com +datazt.com +datealive.com +datebao.com +datepj.com +datesdata.com +datia-inspect.com +datianmen.com +datk.anythinktech.com +datong.info +datongjianshe.com +datongtaxi.com +datuc.com +daugres.com +dauteen.com +dav01.com +davdian.com +davidlovezoe.club +davincimotor.com +davinfo.com +davost.com +davycloud.com +dawangling.com +dawawa.com +daweiai.com +daweijita.com +daweisoft.com +daweiyishu.com +dawenbo.com +dawenling.com +dawenming.com +dawensk.com +dawenxue.net +dawenxue.org +dawhcm.com +dawnarc.com +dawndiy.com +dawnjs.com +dawnlab.me +dawnled.net +dawntech.net +dawuhanapp.com +dawurencai.com +dawuyu.com +dawx.com +dawx.net +daxfix.com +daxia.com +daxiang91.com +daxianghuyu.com +daxiangkeji.com +daxianglingke.com +daxianglink.com +daxiangqun.net +daxiangshouche.com +daxianzuji.com +daxicn.com +daxiit.com +daxiongxueyixue.com +daxishi.com +daxitouzi.com +daxue52.com +daxuecidian.com +daxuecn.com +daxueit.com +daxuejiayou.com +daxuelu.com +daxuepc.com +daxuesoutijiang.com +daxuetian.com +daxuewang.com +dayaguqin.com +dayainfo.com +dayang.group +dayangjt.com +dayangliangyou.com +dayangmotorcycle.com +dayangmuye.com +dayangshop.com +dayangsz.com +dayanmei.com +dayanyanglao.com +dayanzai.me +dayapress.com +dayayu.com +dayclover.com +daydao.com +dayday.plus +daydaymap.com +daydays.com +daydaytest.com +daydayup123.com +daydx.com +daye.hk +dayee.com +dayehome.com +dayesmart.com +dayezheng.com +dayhao.com +dayhellohotel.com +dayhr.com +dayi100.com +dayichang.com +dayifund.org +dayihangqing.com +dayila.net +dayilive.com +dayima.com +dayin.com +dayin.la +dayin8.com +dayinhu.com +dayinjiqudong.com +dayinmao.com +dayinpai.com +dayinpiano.com +dayirc.com +dayishengwu.com +dayitea.com +dayiwater.com +dayong.name +dayoo.com +dayrui.com +dayscamera.com +daysou.com +dayspringpharma.com +dayss.com +daysview.com +dayu-group.com +dayu-valve.com +dayu.com +dayu.work +dayuanqy.com +dayuansouti.com +dayuanzong.com +dayucdn.com +dayucdntip.com +dayue.com +dayue8.com +dayugame.net +dayugf.com +dayugslb.com +dayukaoshi.com +dayukeji.com +dayulego.com +dayulegobak.com +dayungroup.com +dayuntongzhou.com +dayup.org +dayustudy.com +dayutukun.com +dayuzy.com +daza168.com +dazanggui.org +dazhangfang.com +dazhangqiu.com +dazhe5.com +dazheda.com +dazhengtop.com +dazhenzimiao.com +dazhewa.com +dazhicorp.com +dazhistudy.com +dazhitech.com +dazhixue.com +dazhong-valve.com +dazhong.com +dazhongbanben.com +dazhonghr.com +dazhongkanche.com +dazhoumzj.com +dazhoushan.com +dazhouwater.com +dazhu1988.com +dazhuangwang.com +dazhuangyan.com +dazibo.com +dazidazi.com +dazijia.com +daziya.com +dazizhuanqian.net +dazoread.com +dazpin.com +daztoutiao.com +dazuhang.com +dazui.com +dazuichazi.com +dazzle-fashion.com +db-cache.com +db.ci +db162.com +db23bc6de1024.beer +db2b0d032aefa755.com +db5f9bf125415ac9.com +db6bfe859b7825fc.com +db6f227cfb009078.com +db9w.com +db9x.com +dba95a0a82447ac3.com +dbank.com +dbankcdn.com +dbankcdn.ru +dbankcloud.asia +dbankcloud.com +dbankcloud.eu +dbankcloud.ru +dbankedge.asia +dbankedge.net +dbanote.com +dbaobao.com +dbatmb.com +dbbqb.com +dbc2000.net +dbcdh.com +dbcsq.com +dbdna.com +dbe5c181b58111e2.com +dbf71743f55a8ff4.com +dbh123.net +dbjsjt.com +dbkan.com +dbkuaizi.com +dblgf.com +dbljj.com +dbmailserver.com +dbmall.com +dbmeta.net +dbnuo.com +dbpan.com +dbparking.com +dbqf.xyz +dbqgg.com +dbs724.com +dbscar.com +dbshop.net +dbss360.com +dbtclub.com +dbyun.net +dbzy5.com +dc-cn.com +dc0792.com +dc168cc6a2fe73d3.com +dc568.com +dc5febe781010.beer +dc625.com +dc8c1b13e8a9a886.com +dcarapi.com +dcarimg.com +dcarlive.com +dcarstatic.com +dcarvod.com +dcatgame.com +dcb-group.com +dcb123.com +dcccji.com +dcdapp.com +dcdkjx.com +dcdnx.com +dceb32e758290eed.com +dcef3671664fa11b.com +dcement.com +dcexport.work +dcf365.com +dcg.microsoft.com +dcg123.com +dcgqt.com +dcgsi.com +dcgstd.com +dchotel.net +dcic-china.com +dcits.com +dckgjt.com +dckj19.com +dckygroup.com +dcloud.io +dcloud.xin +dcloudlive.com +dcloudlive.net +dclouds.cloud +dcloudsp.com +dcloudsp.net +dcloudstc.com +dcloudstc.net +dcloudvod.com +dcloudvod.net +dclygroup.com +dcmagcn.com +dcmk17.com +dcn01.ps4.update.playstation.net +dcn01.ps5.update.playstation.net +dcpc.com +dcpfb.com +dcqsq.com +dcsapi.com +dcshow.com +dcsjw.com +dcsme.org +dcsq.com +dcstack.org +dct-cloud.com +dcutp.com +dcwucu.com +dcxnews.com +dcxx.vip +dcxzmxa.com +dcybkj.com +dcyiyao.com +dcyjc.com +dcyz.com +dcyzq.com +dczcsc.com +dczkj.com +dczy168.com +dd-advisor.com +dd-gz.com +dd-img.com +dd.ci +dd.ma +dd001.net +dd01.com +dd0415.net +dd0513702337fb4b.com +dd0d7e15310311.beer +dd128.com +dd2007.com +dd208.com +dd369.com +dd373.com +dd4.com +dd536adb110272.beer +dd666mir.com +dd903b8fbe36755d.com +ddadaal.me +ddahr.net +ddbiquge.cc +ddbiquge.com +ddbiu.com +ddblquge.cc +ddbqgtxt.cc +ddcdn.com +ddcheshi.com +ddchong.com +ddcits.com +ddcorp.net +ddcsjw.com +ddcwl.com +ddd-china.com +dddazhe.com +ddddns.net +ddddocr.com +ddddyres.com +dddfe.com +dddgong.com +dddja.com +dddki.com +dddkq.com +dddwan.com +dde-desktop.org +ddedush.com +ddfans.com +ddfchina.com +ddfresh.net +ddfzb.com +ddguanhuai.com +ddhly.com +ddhy.com +ddiaas.com +ddianle.com +ddimg.mobi +ddimg.net +dding.net +ddiqbh.com +ddj123.com +ddjjzz.com +ddjk.com +ddjs-cn.com +ddjsyx.com +ddkanqiu.cc +ddkanqiu.net +ddkanqu.com +ddkids.com +ddkt365.com +ddky.com +ddle.cc +ddlequ.com +ddmaicai.net +ddmap.com +ddmc.mobi +ddmer.com +ddmogo.com +ddnddn.com +ddnscn.com +ddnspod.com +ddnsto.com +ddnx.com +ddong.com +ddonplan.com +ddooo.com +ddoor.net +ddos.com +ddos567.net +ddosc.com +ddosendns.com +ddosfh.com +ddoshy.com +ddosjq.xyz +ddove.com +ddpai.com +ddpoc.com +ddqcw.com +dds.dell.com +ddsaas.com +ddsiojf.xyz +ddsk.la +ddsm.com +ddstarapp.com +ddsy.com +ddtk.vip +ddtsg.com +ddtugame.com +ddtxgame.com +ddun.com +ddunyun.com +ddurl.to +dduser.mobi +dduwork.com +ddvaj.com +ddweilai.com +ddwgame.com +ddwhm.com +ddwjs.com +ddxhx.com +ddxhyl.com +ddxq.mobi +ddxs.vip +ddxsku.com +ddxstxt8.com +ddyjapp.com +ddyqh.com +ddyun.com +ddyun123.com +ddyylczz.com +ddyylczzs.com +ddz.com +ddzf.cc +ddzhj.com +ddzl.net +ddzls.net +ddzn.tech +ddznzj.com +ddztv.com +ddzui.com +ddzuqin.com +ddzuwu.com +de-ele.com +de-moe.org +de-tencentclb.cloud +de-tencentclb.com +de-tencentclb.net +de-tencentclb.work +de0.cc +de1000.com +de123.net +de1919.com +de2edec3011032.beer +de56.com +de83cc01111.xin +de9745f491023.beer +deaconhousewuxi.com +deadnine.com +deafchina.com +deahu.com +dealsbank.com +dealsmake.com +deansys.com +dear520dear.com +dearclick.com +dearda.com +dearedu.com +dearisland.com +deartree.com +dearxuan.com +deasun.com +deathearth.com +deau-cable.com +deb1c7bad11031.beer +debao.com +debao123.com +debaochina.com +debbe32e10b635a7.com +deben.me +debug.moe +debugdump.com +debugo.com +debuycn.com +decansmd.com +decard.com +decd5279411012.beer +decent-china.com +decentcapital.com +decerp.cc +dechang-chem.com +dechingroup.com +dechlogi.com +dechong.site +dechua.com +deckmanager.net +declous.com +decohome.cc +decoration.ltd +decorcn.com +decwhy.com +deczh.com +dede-zj.com +dede168.com +dedeadmin.com +dedebiz.com +dedecms.com +dedecms8.com +dedecmsmuban.com +dedecmsplus.com +dedeeims.com +dedegg.com +dedejs.com +dedemao.com +dedesos.com +dedezhuji.com +deebio.com +deeceal.com +deehon.com +deemos.com +deep-os.com +deep56.com +deepblog.net +deepcloudsdp.com +deepcoin.red +deepcool.com +deepdone.work +deepepg.com +deepermobile.com +deepfast.com +deepin-ai.com +deepin.com +deepin.io +deepin.org +deepinghost.com +deepinmind.com +deepinos.org +deepinout.com +deepinstall.com +deepleaper.com +deeplearn.me +deeplearn.work +deepmd.net +deepoon.com +deeprouter.org +deepseapioneer.com +deepseek.com +deepseeksvc.com +deepsheet.net +deeptechchina.com +deeptrain.net +deeptrip.com +deepvinci.tech +deepvps.com +deer-express.com +deerex.com +deerfieldbch.com +deerhappy.com +deerjet.com +deerma.com +deernice.com +deexchina.com +def5feeaeb220776.com +defair.online +defcoding.com +defeng999.com +defineabc.com +defoen.com +defofy.com +defoile.com +defuv.com +defvul.com +degitec-jiangyin.com +deguoguanjia.com +dehe99.com +deheheng.com +deheng.com +dehengclinic.com +dehenglaw.com +dehsm.com +dehua.net +dehuaca.com +dehuigroup.com +dehuisk.com +dehuiyuan.com +dehumidifierchina.com +deifgs.com +deikuo.com +dejia-shijiebei1.com +dejiart.com +dejiplaza.com +dekeego.com +dekekc.com +dekls.com +dekonglife.com +dektw.com +dekuncn.com +dekunyy.com +dekyy.com +del.pub +delaiyun.cloud +delanauto.com +dele.com +deli-tools.com +delib2b.com +delibao.com +delicacyup.com +delicloud.com +delilegal.com +delin-sh.com +delingkeji.com +delinklab.com +delipu.cc +delishi.com +deliworld.com +delixi-electric.com +delixi.com +delixidrive.com +deliyun.com +dell-alw.com +dell-brand.com +dell027.com +dellecs.com +dellemc-solution.com +dellenglish.com +dellfuwuqi.com +dellhpibm.com +dellrsm.com +dellzj.com +delong-group.com +delonggou.com +delonix.group +delovabio.com +delphi-connect.com +delphijiaocheng.com +deltaverse.net +delun-group.com +delunyk.com +deluxewatchbox.com +deluxworld.com +deluya.com +demanmedical.com +demark-jgkj.com +demaxmedical.com +demingzi.com +demix.cc +demixc.com +demizhongbao.com +demlution.com +demo-15.work +demo1024.com +demo8.com +demodashi.com +demogic.com +demon.tw +demonlee.tech +demososo.com +denachina.com +denaircompressor.com +deng88.com +denganliang.com +dengbaogonggao.com +dengbi8.com +dengbiao.com +dengdingsheng.com +dengfengwater.com +dengguobi.com +denghao.org +denghaoxuan.com +denghuo.com +dengkanwen.com +dengmoe.com +dengni.org +dengta120.com +dengtabao.com +dengtacj.com +dengtadaka.com +dengxiaolong.com +dengxiaopingnet.com +deniulor.com +denon-proaudio.com +denopark.com +denson168.com +dentistshow.com +denverokie.com +denza.cloud +denzacloud.com +deosen.com +deosin.com +dep-star.com +depailed.com +depamu.com +dependdns.com +dephir.com +deppon.com +depthlink.com +depuchem.com +deqingbank.com +dercase.com +derekchou.com +derenbs.com +derlook.com +derucci.com +derun-env.com +derunbao.com +derunss.com +deruxi.com +derzh.com +des8.com +desano.com +desay.com +desaysv.com +deserts.io +deshaus.com +desheng-edu.com +desheng-school.com +desheng.net +deshengdachem.com +deshenghonglan.com +deshengtea.com +deshengzj.com +deshicheng.com +design-engine.org +design006.com +designjiaoshi.com +designkit.com +designmoma.com +designshidai.com +designsketchskill.com +designuuu.com +designwithlove.org +designyunasai.com +desk-site.com +deskcar.com +deskcity.com +deskcity.org +deskguanjia.com +deskpool.com +desktop-calculator.com +desktopcal.com +deskwc.com +desnerboats.com +desoonproduct.com +destoon.com +desunpv.com +desuntech.com +deswfggabc.work +detaisy.com +deteufelde.shop +detion.com +detonfan.com +detonger.com +detu.com +dev-dh.com +dev59.com +devashen.com +devask.net +devbean.net +devblogs.microsoft.com +devclub.cc +devdir.biz +devedu.net +developer.htcvive.com +developer.microsoft.com +developer.vive.com +developers.pub +developwechat.com +developweixin.com +develpress.com +devemi.com +devework.com +devexel-tech.com +devexel.com +devexpresscn.com +devicewell.com +devil0629.com +devio.org +devops-dev.com +devotiongroup.com +devourad.com +devpss.com +devsapp.net +devsiki.com +devskyr.com +devtang.com +devui.design +devweixin.com +devzeng.com +deweier.com +deweisi.net +dewmobile.net +dewu.com +dewu.net +dewucdn.com +dewumall.com +dewx.net +dexejhyxh.com +dexi009.com +dexian.mobi +dexingroup.com +dexingrv.com +dexinhr.com +dexinmobi.com +dexinquan.com +dexinrq.com +dexinsg.com +dexiya.com +dextercai.com +dexuee.com +dexueedu.com +dexunyun.com +dexxg.com +deyangbk.com +deyatech.com +deyayk.com +deyecloud.com +deyeehome.com +deyerchem.com +deyi.com +deyi.net +deyicc.com +deyijijin.org +deyiso.com +deyle-electric.com +deyouec.com +deyoulife.com +deyuan.fun +deyuantextile.com +deyun.fun +dezhanyigou.com +dezhongmobi.com +dezhoudaily.com +dezhoulawyer.com +dezhuyun.com +dezstia.com +df-1912.com +df-college.com +df-gd.com +df-nissanfc.com +df-nissanfl.com +df0535.com +df321b81208721f1.com +df33.com +df81.com +df9377.com +df962388.com +dfb232ce910241.beer +dfcfs.com +dfcfw.com +dfcms.net +dfcx-bj.com +dfdaily.com +dfdd-toubiaole.com +dfdinsin.com +dfdtt.com +dfebda0512.vip +dfedu.com +dfeeb7ee91022.beer +dfev.net +dffcw.net +dfgiso.com +dfgsb.com +dfgsz.com +dfham.com +dfhog.com +dfhon.com +dfhr.com +dfhrc.com +dfhy888.com +dfig0.com +dfine.tech +dfjyun.com +dfkhgj.com +dfkj.cc +dflmtc.com +dflzm.com +dflzmxs.com +dfmc.com +dfmcastrol.com +dfmingya.com +dfnzhp.com +dfpost.com +dfpz.net +dfqcmy.com +dfqy.com +dfratings.com +dfrcb.com +dfs168.com +dfshurufa.com +dfshw.com +dfshysw.com +dfsjsoft.com +dfsmw.com +dfsouth.com +dfss-club.com +dfstw.com +dfsyjm.com +dftcdq.com +dftryy.com +dftyyls.com +dftzj.com +dfwl.net +dfwlg.com +dfxq.com +dfxqc.com +dfxwdc.com +dfxy.net +dfxyw.com +dfy027.com +dfyanyi.com +dfyapp.com +dfyl-luxgen.com +dfyne.cz +dfynet.com +dfyoo.com +dfysgs.com +dfysscy.com +dfysw.net +dfyuan.com +dfyyc.com +dfyzx.com +dfzbsh.com +dfzk.com +dfzmzyc.com +dfzxvip.com +dfzyxy.net +dg-360lhx.com +dg-dns.com +dg-dx.com +dg-hanxin.com +dg-mall.com +dg-niuniu.com +dg-paas.com +dg-tcm.com +dg11185.com +dg121.com +dg456.com +dg688.com +dgaefi.org +dgaiia.com +dgbaineng.com +dgbgw.com +dgbia.com +dgbyxny.com +dgbzy.com +dgcct.com +dgchenghe.com +dgcia.com +dgcpkl.com +dgddh.xyz +dgdq1688.com +dgdqw.com +dgdydd.com +dgegbj.com +dgeia.com +dgg.net +dggcyy.com +dggdk.com +dgggs.com +dgghy.com +dggjqw.com +dggjyy.com +dggosungroup.com +dggq.com +dggxxh.com +dggywx.com +dghgzm.com +dghjt.com +dghobo17.com +dghonggao.net +dghqmotor.com +dghuafuli.com +dginfo.com +dgjijiagong668.com +dgjiuqi.com +dgjoy.co +dgjwsy.com +dgjx.net +dgjxmk.com +dgjy.net +dgk2n.com +dgkj888.com +dglpool.com +dglyjx.com +dglyyun.com +dglzd.com +dgmama.net +dgn.cc +dgndf.com +dgnekon.com +dgnet.net +dgnkj.com +dgobch.com +dgod.net +dgouyijiance.com +dgovp.com +dgpenghao.com +dgphospital.com +dgpp.com +dgprj.com +dgpump86.com +dgqczz.com +dgqianguan.com +dgqjj.com +dgqzxx.net +dgrbcj.com +dgrcw.com +dgrsa.org +dgruizhi.com +dgrunhe.com +dgs-td2.com +dgsbtjx.com +dgsfweb.com +dgshifeng.com +dgshunjin.com +dgsltx.com +dgsme.org +dgspk.com +dgswhg.com +dgsztyy.com +dgt-factory.com +dgtianbao.xin +dgtle.com +dgtn1718.org +dgtpcj.com +dgtungwah.com +dgtuoyue.com +dgtzjt.com +dgw888.com +dgweierwj.com +dgweitian.com +dgwia.com +dgwlhj.com +dgwtrl.com +dgxbjg.com +dgxinde.net +dgxue.com +dgxxz.com +dgxzxjj.com +dgyanda.com +dgyejia.com +dgyhsb.com +dgyian.com +dgyibiao.com +dgykz.com +dgylec.com +dgyq-water.com +dgysdx.com +dgytdz.com +dgyuanyi.com +dgyw.cc +dgzaixing.com +dgzcsy.net +dgzhihongjx.com +dgzhisen.com +dgzj.com +dgzp.com +dgzx.net +dgzz1.com +dh.cx +dh01.com +dh0580.com +dh08126.net +dh33660.com +dh3t.com +dh5a.com +dh5idnf.com +dh7373.com +dh7999.com +dh818.com +dh9191.com +dh978.com +dhaitun.com +dhasgf.com +dhb.hk +dhb168.com +dhboy.com +dhbs86.com +dhchain.com +dhcooker.com +dhdly.com +dhg858a07.shop +dhgfhgsfg.com +dhgsqjcnd.com +dhgsqjcnj.com +dhgsqjcnm.com +dhguanye.com +dhgz.com +dhh-gz.com +dhhqfw.com +dhidcw.com +dhimavision.com +dhj3413.com +dhjt.com +dhkm.vip +dhkq120.com +dhkqyy.com +dhl-online.com +dhl-y.info +dhl8o3x5.bond +dhlfki.shop +dhlijg.bond +dhlvux.asia +dhlzhif.asia +dhmeri.com +dhmsnyy.com +dhppa.com +dhqfz.com +dhqtech.com +dhrcbank.com +dhrest.com +dhrest2.com +dhs-sports.com +dhsrmyy.com +dhszyy.net +dht5867.com +dhtest.com +dhtopology.com +dhtv.tv +dhuili.com +dhvisiontech.com +dhw-wiremesh.com +dhw22.com +dhwooden.com +dhxx.com +dhyct.com +dhyjaqa.com +dhyz.net +dhzfgm.com +dhznib.com +di1k.com +di28nl.com +di3ke.com +di7cn.net +di88.net +diablohu.com +diact.com +diaidi.com +diaigame.com +dialoguechinefrance.com +diamondfavour.net +diamondfsd.com +diamondinnovations.cfd +dian-ai.com +dian-stable.com +dian.so +dian123.com +dian234.com +dian5.com +dian68.net +dianapp.com +dianbaobao.com +dianbb.com +dianbio.com +dianbo.org +dianbobao.com +dianbucuo.com +diancang.xyz +dianchacha.com +dianchizhijia.com +dianchouapp.com +diandanbao.com +diandao.org +diandaxia.com +diandeng.tech +diandian.com +diandian.net +diandianchong.com +diandianmeijia.com +diandiannuo.com +diandianqi.com +diandianshu.com +diandianwaimai.com +diandianys.com +diandianzhe.com +diandong.com +diandongche.biz +dianfanyingyu.com +dianfengcms.com +dianfuji.com +diangan.org +diangeapp.com +diangong8.com +diangongbao.com +diangongjiang.com +diangongwu.com +dianhen.com +dianhong.com +dianhou.com +dianji007.com +dianjianggame.com +dianjiangrcw.com +dianjiangxin.cc +dianjihr.com +dianjin123.com +dianjinghu.com +dianjingzhe.com +dianjipinpai.com +dianjiqi.com +diankeji.com +dianlanbao.com +dianlanyibiao.com +dianli.com +dianli08.com +dianli100.com +dianlinet.com +dianlut.com +dianlut.net +dianmi365.com +diannaoban.com +diannaodiy.net +diannaoxianka.com +dianopen.com +dianou.com +dianpifa.com +dianping.com +dianpingba.com +dianpushuo.com +dianqikaiguan.com +dianqizazhi.com +dianqugame.com +dianranart.com +dianremo1688.com +dianrong.com +dianru.net +dians.net +diansan.com +dianshanchina.com +dianshang.com +dianshangmulu.com +dianshangyi.com +dianshi.com +dianshihome.com +dianshijia.com +dianshu119.com +diansu-cdn.net +diantads.com +diantangzuyi.com +diantonghudong.com +diantoushi.com +diantui.net +dianwanhezi.com +dianwannan.com +dianwanshidai.com +dianwantu.com +dianwo98.com +dianwoba.com +dianwoda.com +dianwolf.com +dianwoyou.com +dianxian.net +dianxian8.com +dianxiandianlanchang.com +dianxiaobao.net +dianxiaomi.com +dianxin.net +dianxinnews.com +dianxinos.com +dianyacloud.com +dianyingshow.com +dianyingwenxue.com +dianyong123.com +dianyongqi.com +dianyuan.com +dianzhanggui.net +dianzhangzhipin.com +dianzheli.com +dianzhenkeji.com +dianzhentan.com +dianzhi.com +dianzhong.com +dianzi6.com +dianziaihaozhe.com +dianzihetong.net +dianzixuexi.com +dianzizhao.com +diaoben.com +diaochapai.com +diaochapai.net +diaochatong.com +diaocnc.com +diaoding.biz +diaojiang.com +diaokeji.net +diaosaas.com +diaosi.net +diaosiweb.net +diaosu9.com +diaosu98.com +diaosunet.com +diaosuoju.net +diaox2.com +diaoy.com +diaoyan001.com +diaoyou.com +diaoyoupai.com +diaoyu.com +diaoyu123.com +diaoyu365.com +diaoyuren.com +diaoyuwang.com +diaoyuweng.com +diary365.net +diaxue.com +diazha.com +dibaifang.com +dibang18.com +dibaotong.com +dibchina.com +dibcn.com +diboot.com +dibunet.com +dic123.com +dicastal.com +dichan.com +dichan.net +dichanlao.com +dichanren.com +dichanw.com +dichedai.com +dicila-china.com +dicksflashsale-vip.com +dicom365.com +dictall.com +dida110.com +dida365.com +didabds.com +didacar.com +didachuxing.com +didamall.com +didao.com +didaoshidai.com +didapaper.com +didapinche.com +didatravel.com +didatxt.com +didctf.com +dideu.com +didi-food.com +didi-trip.com +didi.xin +didialift.com +didiapp.com +didiaustralia.blog +didibuluo.com +didichuxing.com +dididadidi.com +dididapiao.com +dididi88.com +didiglobal.com +didimobility.co.jp +didimobility.com +didiopenapi.com +didipai.com +didiqiche.com +didishijie.com +didispace.com +didistatic.com +diditaxi.com +didiwuxian.com +didixk.com +didiyun.com +didiyun.org +didiyunapi.com +diducoder.com +diebian.net +dieclock.com +diemoe.net +dieniao.com +dieqiu.com +diershoubing.com +dietfd.com +diexuan.net +diexun.com +dieyanli.com +difanapp.com +difersports.com +diffir.com +diffusefuture.com +diffusenetwork.com +dig-gy.com +digcredit.com +digeeker.com +digi-wo.com +digigd.com +digihail.com +digihuman.com +digiic.com +digiinfr.com +digimons.net +digirepub.com +digisky.com +digit3ds.com +digital-hangzhou.com +digital-ren.com +digitalchina.com +digitalchinahealth.org +digitalcloudshield.com +digitalcnzz.com +digitalcq.com +digitaldrew.net +digitalfiles.org +digitaling.com +digitaljx.com +digitalmanu.com +digitalvolvo.com +digitalwuhan.com +digitalwuhan.net +digitalyili.com +digitclouds.com +digitguangdong.com +digitimetech.com +digitlink.net +digitser.net +digitwater.com +digiwin.com +digiwoods.com +digiwork.com +digod.com +digoexpress.com +digsur.com +digu.com +digu.plus +digu365.com +digua.com +diguage.com +diguazu.com +dihaobedding.com +dihaopipe.com +dihaowa.com +dihuaikeji.com +diiqu.com +dijianggroup.com +dijingchao.com +dijiuban.com +dikalon.com +dikeqc.com +dili360.com +dili365.com +dilidili.com +diliy.com +dima-industry.com +dimei88.com +dimeng.vip +dimensi-9.com +dimensionalzone.com +dimenspace.com +dimocap.com +dimolabel.com +dimsmary.tech +dimsolo.com +dimtown.com +dinais.com +dinarspeculator.com +dindin.com +ding-chuang.com +ding-liang.com +dingbang99.com +dingcaicai.com +dingcooltech.com +dingdachuxing.com +dingdandao.com +dingdangchem.com +dingdanggj.com +dingdangjia.net +dingdangnao.com +dingdanxia.com +dingdatech.com +dingdd.com +dingdean.com +dingdi.com +dingdian001.com +dingdiange.org +dingdiann.com +dingdiann.net +dingdiansk.com +dingdianxs.la +dingdianzw.com +dingding.com +dingding.xin +dingdingdan.com +dingdingdoctor.com +dingdingkaike.com +dingdingtingche.com +dingdingzn.com +dingdone.com +dingdongcloud.com +dingdongebusiness.com +dingdongmao.com +dingdongxiaoqu.com +dingdx.com +dingefactory.com +dingertai.com +dingfubang.com +dinggebaojian.com +dinggou.org +dinggu.net +dinghaiec.com +dinghantech.com +dinghengjc.com +dinghu.com +dinghuakuai.com +dinghuaren.com +dinghui.org +dinghuo123.com +dinghuo365.com +dinghuoche.com +dinghuovip.com +dingjiwangluo.com +dingkeji.com +dinglia.com +dingliangame.com +dinglianhuanbao.com +dinglicom.com +dinglipin.net +dinglongchem.com +dinglongjx.com +dinglutang.com +dingoa.com +dingqiao.cc +dingqiaoks.com +dingqibao.com +dingqidong.com +dingqingyun.com +dingrongxd.com +dingrtc.com +dingruxin.com +dingsheng.com +dingso.com +dingtalent.com +dingtalk.com +dingtalk.net +dingtalkapps.com +dingtalkcloud.com +dingtangzqx.com +dingteam.com +dingtoo.com +dingwei.link +dingweilishi.com +dingwenacademy.com +dingxiang-inc.com +dingxikeji.com +dingxinwen.com +dingxiushipin.com +dingxutonghui.com +dingyang.com +dingyanqf.com +dingyantec.com +dingyao17.com +dingyue-ele.com +dingyueads.com +dingzhijl.com +dingzhoudaily.com +dingzhourencai.com +diningcity.asia +dinju.com +dinpay.com +dinsense.com +dinte.work +dinyocasa.com +dinzd.com +diodecy.com +dioenglish.com +diomasce.com +dionly.com +diopic.net +dious-f.com +dipephoto.com +dipont.com +dippstar.com +diqiuw.com +diqua.com +dir001.com +dir28.com +directui.com +dis9.net +disccrds.com +discount-polska.store +discourse-studies.com +discoversources.com +discoveryriflescope.com +discrepancye.com +discuz.chat +discuz.com +discuz.net +discuz.org +discuz.vip +discuzfans.net +discuzlab.com +disenjn.com +dishanhuanbao.com +dishen.com +dishuge.com +dishuizhijia.com +disimy.com +dislux.com +dislytegame.com +dismall.com +distantmeaning.com +distinctclinic.com +ditai.fun +ditan.com +ditan360.com +ditian-tech.com +ditianshanhe.com +ditiefuli.com +ditiezu.com +ditiezu.net +ditrit.com +ditu.live.com +dituhui.com +dituw.net +dituwuyou.com +dituyi.com +diugai.com +diuta.com +diuut.com +divcss5.com +divepai.com +diving-fish.com +divizg.com +divoiotcloud.com +diwork.com +diwuyuan.com +dixinkj.com +dixintong.com +diy10.com +diyahz.com +diybcq.com +diydiymall.com +diygogogo.com +diygw.com +diyhi.com +diyibox.com +diyicai.com +diyidan.com +diyidan.net +diyidanhao.com +diyiedu.com +diyifanwen.com +diyifanwen.net +diyigaokao.com +diyihuifu.com +diyiliuxue.com +diyinews.com +diyishijian.com +diyixiazai.com +diyixin.com +diyiyou.com +diyiyt.com +diyiyunshi.com +diyiziti.com +diyleyuan.com +diymianmo.com +diymysite.com +diynova.com +diyosl.com +diypda.com +diyring.cc +diyyh.com +diyzhen.com +dizalpharma.com +dizgslb.com +dizh.net +dizhimei.com +dizhu.org +dizhuche.com +diziguiwang.com +dizishu.com +dizzylab.net +dj-dj.net +dj.net +dj.tc +dj10.com +dj134.com +dj16.com +dj175.com +dj193.com +dj63.com +dj89.com +dj92.cc +dj92cc.com +dj96.com +dj97.com +dj99.com +djbh.net +djbhjg.net +djbx.com +djc8888.com +djcc.com +djcp099.com +djcscs.com +djcx.cc +djdjapp.com +djdkk.com +djdsh.com +djduoduo.com +djdyqn.com +djec.net +djeconomic.com +djf.com +djf313.com +djfensi.com +djfrj.com +djgy.com +djhxn.com +dji.com +dji.ink +dji.net +djiang.net +djiavip.com +djicdn.com +djigate.com +djiits.com +djiops.com +djiservice.org +djjgj.com +djjlseo.com +djjw.com +djjyzly.com +djkgongshui.com +djkhgy2.com +djkk.com +djkpai.com +djksh.com +djksq.com +djkxl.com +djlcom.net +djlmvip.com +djlsoft.net +djm-bj.com +djmillison.com +djrhf0.com +djserver.center +djsh5.com +djstechpc.com +djstg.com +djtpf.com +djtpt.com +djtt.com +djttw.com +djtz.net +dju8.com +djunf.com +djuu.com +djwjsj.com +djxcable.com +djxww.com +djy517.com +djye.com +djyg.shop +djyinyue.com +djyjob.com +djymjsw.com +djyule.com +djzhj.com +djzr88.com +djzyg.com +dk-lexus.com +dk8s.com +dkashop.com +dkcloudlive.com +dkdangle.com +dkdgroup.com +dkdsfrwety.xyz +dkewl.com +dkfinancing.com +dkgyw.com +dkhg23.com +dkhs.com +dkjiaoyang.com +dkjmy.com +dkjmyq.com +dklogs.net +dkmol.net +dknsankf.com +dkntgc.com +dksgames.com +dkskcloud.com +dktad.com +dktzjt.com +dku51.com +dky.cc +dkybpc.com +dkykyt5516.vip +dkzt.com +dkzx.net +dl-hf.com +dl-hr.com +dl-kg.com +dl-meitu.com +dl-rc.com +dl.delivery.mp.microsoft.com +dl.dell.com +dl0728.com +dl23zx.com +dl2link.com +dl56.net +dl8z.com +dlairport.com +dlbaohuang.com +dlbbdk.com +dlbbs.com +dlbh.net +dlbiotech.com +dlcaic.com +dlcsos.com +dld56.com +dldlsw.com +dldm.com +dledu.com +dler.cloud +dlfederal.com +dlfeyljt.com +dlfy-metalparts.com +dlg-expo.com +dlgouji.com +dlgslb.net +dlgwbn.com +dlgxbl.com +dlhaibaobio.com +dlhope.com +dlhospital.com +dlhuayang.com +dlhwjq.com +dljczb.com +dljdy.com +dljianbing.com +dljierui.com +dljlxx.com +dljrw.com +dljs.net +dljsjt.com +dlkldz.com +dlkykycc55.com +dllawyers.org +dllzj.com +dlmeasure.com +dlmianshuiche.com +dlmonita.com +dlmyzf.com +dlmzk.com +dlnel.com +dlnel.org +dlnyzb.com +dlonng.com +dlosri.com +dlphoschem.com +dlpuwan.com +dlqcgz.com +dlrkb.com +dls88.com +dlsccn.com +dlsgs.com +dlshian.com +dlsjyy.com +dlsqb.com +dlssa.com +dlsstax.com +dlsunworld.com +dlszywz.com +dlteacher.com +dltm.net +dltobacco.com +dltubu.com +dlvalve.com +dlw-lighting.com +dlw360.com +dlw666.com +dlwang.vip +dlwjdh.com +dlwmkj.com +dlwx369.com +dlxgjy.com +dlxk.com +dlxmicro.com +dlxww.com +dly56.com +dlyy365.com +dlzb.com +dlzbxx.com +dlzj.net +dlzs-audio.com +dlztb.com +dlzxyy.com +dlzyc.com +dm-hr.net +dm004.net +dm0775.com +dm21.com +dm300.com +dm456.co +dm5.com +dm591.com +dm5u.com +dm67.com +dm9.com +dma13.org +dmacg.net +dmaking.com +dmall.com +dmallcdn.com +dmallovo.com +dmaow.com +dmb168.com +dmcdn.com +dmd968.com +dmdaili.com +dmeg88.com +dmeiti.com +dmeiti.net +dmeng.net +dmentt.help +dmgapp.com +dmgeek.com +dmggb.com +dmgpark.com +dmguo.com +dmgyta.com +dmgytb.com +dmhlj.com +dmhmusic.com +dmhy.com +dmicrobe.com +dmiug.com +dmjk120.com +dmjnb.com +dmjvip.com +dmm.ink +dmmaterial.com +dmooo.com +dmpdmp.com +dmpdsp.com +dmplugin.net +dmqhyadmin.com +dmqst.com +dmqwl.com +dmread.com +dmrta.com +dms365.com +dmssc.net +dmtemp.com +dmtg.com +dmtgy.com +dmu-1.com +dmvideo.mobi +dmvideo.net +dmvideo.org +dmvvv.com +dmxs.net +dmyouxi.com +dmyy.cc +dmzfa.com +dmzgame.com +dmzj.com +dmzlcn.com +dmzx.com +dmzzbjb.net +dmzzkz.com +dn.com +dn23.com +dn580.com +dn8188.com +dnake-park.com +dnatupu.com +dnbbn.com +dnbbs.com +dnbiz.com +dncable.com +dndc.cloud +dnettvbox.com +dnfziliao.com +dngswin7.com +dngz.net +dnhcc.com +dningbo.com +dnion.com +dnjd.com +dnjsb.com +dnlunwen.com +dnmall.com +dnmcn.com +dnnunion.com +dnole.com +dnparking.com +dnpz.net +dnqc.com +dnrenfang.com +dns-diy.com +dns-dns.net +dns-sky.com +dns-url.com +dns-waf.com +dns.com +dns.la +dns.pub +dns002.com +dns0755.net +dns100.net +dns110.com +dns123.net +dns12345.com +dns200.net +dns2008.com +dns567.com +dns6132.com +dns666.com +dns6868.com +dns800.com +dnsabc.com +dnsany.com +dnsapi12.com +dnsbbzj.com +dnsbubu.com +dnsce.com +dnscnc.com +dnsdaquan.com +dnsddos.com +dnsdizhi.com +dnse0.com +dnse0.net +dnse1.com +dnse1.net +dnse2.com +dnse2.net +dnse3.com +dnse3.net +dnse4.com +dnse4.net +dnse5.com +dnse5.net +dnse6.com +dnse6.net +dnse7.com +dnse7.net +dnse8.com +dnse8.net +dnse9.com +dnse9.net +dnsfamily.com +dnsfast.online +dnsff.com +dnsfox.net +dnsgtm.com +dnsguest.com +dnsgulf.net +dnsh6666.com +dnshe.com +dnsidentity.com +dnsinside.net +dnsip.com +dnsip.net +dnsis.net +dnsjia.com +dnsjiasu001.com +dnslin.com +dnsmeasurement.com +dnsmsn.com +dnsng.net +dnsns5.com +dnsns6.com +dnsnut.com +dnsnw.com +dnso.fun +dnsoe1.com +dnsoe2.com +dnsoe3.com +dnsoe4.com +dnsoe5.com +dnsoe6.com +dnsoray.net +dnsour.com +dnspai.com +dnspig.com +dnspod.com +dnspod.mobi +dnspod.net +dnspod.org +dnspood.net +dnsppdd.com +dnspro.icu +dnsrw.com +dnss.vip +dnssina.com +dnstest.vip +dnstx88.cc +dnsurl.net +dnsv1.com +dnsv1.net +dnsv2.com +dnsv2.net +dnsv20.com +dnsv3.com +dnsv3.net +dnsv4.com +dnsv4.net +dnsv5.com +dnsv5.net +dnsv8.net +dnsvcache.com +dnsvhost.com +dnsvip1.net +dnsw7777.com +dnswa.com +dnswhk.com +dnswind.net +dnsx9.cc +dnsxdp.com +dnsxv1.com +dnsxv1.net +dnsxv2.com +dnsxv2.net +dnsxv3.com +dnsxv3.net +dnsxv4.com +dnsxv4.net +dnsxv5.com +dnsxv5.net +dnsy8888.com +dnsyy.net +dnszftp.com +dnszh.com +dnszw.com +dnurse.com +dnv-group.com +dnwxwww.com +dnxtc.net +dnxttech.com +dny123.com +dny8.com +dnyywl.com +dnzh.org +dnzhuti.com +dnzjds.com +dnzp.com +do-won.com +do123.net +do1618.com +do1999.com +do35.com +doabit.com +doata.net +dobe-game.com +dobechina.com +dobest.com +dobosc.com +dobunkan.com +doc-baidu.org +doc163.com +doc361.net +doc88.com +doccamera.com +docer.com +docexcel.net +docin.com +docin.net +dockerinfo.net +dockerone.com +dockerpull.pw +dockone.io +dockx.app +doclass.com +docn.net +docodgroup.com +docoi.cc +docpe.com +docs.cdnetworks.com +docs.microsoft.com +docschina.org +docshare.org +docsj.com +docsmall.com +docsou.com +doctor-network.com +doctorbridge.com +doctorcom.com +doctorkickstart.com +doctorscrap.com +doctoryou.ai +docuarea.org +documents.cdnetworks.com +docx88.com +docxz.com +doczj.com +dodjoy.com +dodo8.com +dodobook.net +dodoca.com +dodoeasy.com +dodoedu.com +dodoh5.com +dodonecq.com +dodonew.com +dodovip.com +doducity.com +doercn.com +doergob.com +doerhr.com +doerjob.com +doffry.com +dofolong.com +dog-e-clothing.com +dog089a-a66.com +dogain.com +doganinsaatemlak.com +dogecast.com +dogecdn.com +dogecloud.com +dogecoin.studio +dogedns.com +dogedoge.com +dogevideo.com +dogfight360.com +dogfuzhu.com +doggygosubs.com +doghun.com +doglg.com +dogmr.com +dogwhere.com +dogyun.com +doh.plus +doh.pub +dohai.com +dohia.com +dohuo.com +doibns.com +doii.cc +doingv.com +doit.am +doitim.com +doitwiki.com +doiua.com +doki8.com +dolcn.com +dolfincdnx.com +dolfincdnx.net +dolfincdnx.top +dolfindns.net +dolfindnsx.com +dolfindnsx.net +dolfindnsx.top +dolgma.com +dolike.com +doll-leaves.com +doll-zone.com +dollun.com +dolovely.net +dolphin-browser.com +dolphin-global.com +dolphin.com +dolphincube.com +dolphinpaper.com +dolphinphp.com +dom-3d.net +domabio.com +domaingz.com +domesticmedia.cc +domesticmedia.co +domesticmedia.com +domesticmedia.net +domesticmedia.tv +domesticmediagame.co +domesticmediagame.net +domesticmediapay.com +domigewear.com +domilight.com +domob-inc.com +domob.org +domobcdn.com +domobnetwork.com +domor.net +domp4.cc +domp4.net +dondonwenda.com +done-home.com +donews.com +dong-shou.com +dong-xu.com +dong10.com +dongaigc.com +dongannews.com +dongao.com +dongaoacc.com +dongaocloud.com +dongba.com +dongbao-cn.com +dongbao120.com +dongbaoshengwu.com +dongbd.com +dongbeishifandaxue.com +dongbing.wiki +dongboauto.com +dongbochem.com +dongbosy.com +dongbucaijing.com +dongcai.net +dongcaibao.com +dongcaibaoxian.com +dongcaijijin.com +dongchali.net +dongchedi.com +dongchediapp.com +dongchehui.net +dongcheng120.com +dongchenghotels.com +dongcheyun.com +dongchuangipr.com +dongchuanmin.com +dongdao.net +dongdianqiu.com +dongdongaijia.com +dongdongliu.com +dongdongmai.com +dongdongwenda.com +dongdongzu.com +dongeejiao.com +dongfahouse.com +dongfang-heater.com +dongfang-sisal.com +dongfang-wh.com +dongfang.com +dongfang77.com +dongfangfuli.com +dongfanglicaishi.com +dongfangnews.com +dongfangnuojin.com +dongfangqb.com +dongfangtech.net +dongfangzi.cafe +dongfeng-honda-ur-v.com +dongfeng-honda.com +dongfeng-nissan.com +dongfeng-robot.com +dongfeng.net +dongfengem.com +dongfengtc.com +dongfengtrucks.com +dongfou.com +dongfund.com +donggaoshiye.com +dongge.com +dongguanguoyao.com +dongguantoday.com +donghaidl.com +donghaifunds.com +donghaileasing.com +donghailighter.com +donghaotest.com +donghetea.com +donghongzx.com +donghuangshanquan.com +donghugroup.com +donghui.tech +donghuihospital.com +donghulvdao.com +donghushequ.com +dongjian.cc +dongjiao.cc +dongjiaoapp.com +dongjiaotn.com +dongjiax.com +dongjin-cn.com +dongjinyu.com +dongjueonline.com +dongjujituan.com +dongjun.cc +dongjungroup.com +dongjunhui.com +dongkafei.com +dongkelun.com +dongkouren.com +donglaishun.com +donglangroup.com +dongli720.com +donglidianji.com +donglin.org +donglinchem.com +donglingying.cc +donglinkeji.com +donglishuzhai.net +donglivillage.com +dongliw.com +donglizhixin.com +donglongfm.com +dongman.la +dongmanwang.com +dongmanxingkong.com +dongmanzx.com +dongmiban.com +dongmk.com +dongnanmaifeng.com +dongnanshan.com +dongnanwangjia.com +dongni100.com +dongniao.net +dongnienglish.com +dongniyingyu.com +dongpeng.net +dongpengjieju.com +dongpingren.com +dongputech.com +dongqiang.com +dongqiniqin.com +dongqiudi.com +dongqiudi.net +dongri.com +dongricn.com +dongrv.com +dongsentire.com +dongsenzs.com +dongshengdasha.com +dongshiju.com +dongshou.com +dongshunxinxi.com +dongsport.com +dongtai588.com +dongtaijt.com +dongteng.cc +dongting.com +dongtu.com +dongua.com +dongwm.com +dongxi.net +dongxingkonggu.com +dongxingnet.com +dongxong.com +dongxu.com +dongyanggas.com +dongyangmotor.com +dongyao.ren +dongyaods.com +dongyaowuliu.com +dongyewenhua.com +dongyimg.com +dongyin.com +dongyin.net +dongyixiang.com +dongyoutu.com +dongyuansl.com +dongyuetruck.com +dongyun.biz +dongyun01.com +dongzee.com +dongzhougroup.com +dongzhuandi.com +dongzhuoyao.com +dongzsec.com +donhonet.net +doniv.net +donlim.com +donnor.com +donoo.net +donper.com +dontfar.com +donvv.com +doodoobird.com +doofull.com +doohe.com +dooioo.com +dookay.com +dooland.com +doonsec.com +dooo.cc +doooor.com +doooor.net +door-expo.com +dooready.com +doorhr.com +doorqr.com +doorzo.app +doorzo.net +doosunggroup.com +doov5g.com +dooya.com +dopic.net +dopo-online.net +dopoil.com +dopool.com +dora-control.cdnetworks.com +dora-family.com +dorapp.com +dorcen.com +dorgean.com +dorole.com +dorpule.com +dorrr.com +doseeing.com +doserv.com +doservice.com +doshome.com +dosilicon.com +dosk.win +dosnap.com +dospy.com +dossav.com +dossen.com +dostor.com +dosxs.com +dot.pub +dotaindex.com +dotamax.com +dotcpp.com +dotdotnews.com +doteck.com +dotgate.com +dothantech.com +doticloud.com +dotty-china.com +dotwe.org +dou.bz +dou.li +dou.top +dou6.cc +doubaijiu.com +douban.com +douban.fm +doubanio.com +doubao.com +doubaocdn.com +doubaozhidao.com +doubean.com +doubilm.com +doubimeizhi.com +doublearrow.net +doubleclick-cn.net +doubleclick.net +doublecoinholdings.com +doubleeagle-group.com +doublestarmingren.com +doublewin123.com +doublleclinic.com +doubo03.com +douboshi.net +douc.cc +doucang.com +doucanlk.xyz +doucehua.com +douchacha.com +douco.com +doudang.com +doudehui.com +doudeke.com +doudier.com +doudou.com +doudou.fun +doudou.in +doudou1217.com +doudou520.online +doudouad.com +doudoubird.com +doudouditu.com +doudouso.com +doufan.tv +doufm.net +dougong.net +dougongyun.com +douguo.com +douguo.net +douhao.com +douhaomei.com +douhua.net +douhuameiquan.com +douhuameiquan.net +douhuawenxue.com +douhuaxiongmao.com +douhuibuy.com +douhuomall.com +doujis.com +doukantv.com +doukeji.com +doukou.com +doulaicha.com +doulaidu.cc +doulaidu8.cc +doule-ref.com +douleyun.net +doulongyun.com +doumenqu.com +doumi.com +doumiip.com +doumistatic.com +douniwan.org +doupai.cc +doupay.com +doupocangqiong1.com +douqi.com +douqq.com +doushen.com +doushisan.com +dousonvalve.com +doutian.me +doutianshequ.com +doutub.com +doutuimao.net +doutukeji.com +doutushe.com +douwanweb.com +douxiangtao.com +douxie.com +douya2.com +douyabo.com +douyacun.com +douyadaili.com +douyar.com +douyin.com +douyin766.com +douyinact.com +douyinact.net +douyincdn.com +douyinclips.com +douyincloud.net +douyincloud.run +douyinec.com +douyinfe.com +douyingequ.com +douyinhanyu.com +douyinliving.com +douyinmusicclips.com +douyinmusicpromotion.com +douyinmusicvideo.com +douyinpay.com +douyinpic.com +douyinshortvideo.com +douyinstatic.com +douyinvideo.net +douyinvod.click +douyinvod.com +douyinxs.com +douyongtuan.com +douyou100.com +douyu.com +douyu.tv +douyuex.com +douyuscdn.com +douyushepin.com +douyutv.com +douzaimai.com +douzi.com +douzihuyu.com +douzijiasu.com +dovechina.com +dovepay.com +dovesky.com +dovov.com +dowater.com +dowebok.com +doweidu.com +dowell-health.com +dowhere.com +down10s.com +down123.cc +down123.me +down199.com +down568.com +down6.com +downabc.com +downbei.com +downcc.com +downcodes.com +downfi.com +downg.com +downhand.com +downjoy.com +downke.com +downkr.com +downkuai.com +download-cn.msi.com +download.jetbrains.com +download.microsoft.com +download.qatp1.net +download.visualstudio.microsoft.com +downloadcenter.samsung.com +downloads.ltd +downok.com +downos.com +downpp.com +downqa.com +downsave.com +downwn.com +downxia.com +downxing.com +downxy.com +downyi.com +downza.com +dowv.com +dowway.com +dowyuan.com +doxo.fun +doxue.com +doxygen.io +doyeah.com +doyee.com +doyoimg.com +doyonoc.com +doyoo.net +doyoudo.com +doyouhike.net +dozview.com +dp.tech +dp168.com +dp2u.com +dpanel.cc +dpangzi.com +dpcafc.com +dpcq1.net +dpcyjt.com +dpd-hul.cfd +dpdfsd.com +dpdp.net +dpdpt-prtra.cfd +dper.com +dpfile.com +dpgz.com +dpifloor.com +dpin100.com +dpkyz.com +dplor.com +dplord.com +dplslab.com +dpma.cc +dpn.net +dpqct.com +dprjh.com +dpsoidf.com +dptech.com +dptechnology.net +dptel.com +dpurat.com +dpw.pub +dpwl.net +dpxkjw.com +dpxq.com +dpy8.com +dq123.com +dq247.com +dq3c.com +dq800.com +dq99.net +dqccc.cc +dqccc.com +dqcccc.com +dqdaily.com +dqdbrc.com +dqdg.cc +dqdgame.com +dqdm.com +dqf14u8573.com +dqguo.com +dqhsrq.com +dqhui.com +dqhyxh.com +dqiis.com +dqjob88.com +dqlaketour.com +dqlnyy.com +dqntv.com +dqntwl.com +dqoooo.com +dqpi.net +dqpkb.com +dqpu.com +dqrailing.com +dqshdj.com +dqshjt.com +dqsjt.com +dqsldz.com +dqsq.net +dqsy.net +dqtzdt.com +dqyadong.net +dqyfapiao.com +dqyouqi.com +dqyq.com +dqzboy.com +dqzrrq.com +dqzsteel.com +dr-bj.com +dr-jm.com +dr-ku.com +dr009.com +draftstatic.com +drageasy.com +dragon-chem.com +dragon-download.msi.com +dragon-guide.net +dragon-hotel.com +dragonballcn.com +dragonest.com +dragonfgame.com +dragonfly.fun +dragonlab.org +dragonlcm.com +dragonnewsru.com +dragonsea-china.com +dragonseagroup.com +dragonspringwater.com +dragontrail.com +dragontsc.com +dragonwell-jdk.io +dragonyq.com +drakeet.com +dramasclub.com +dramx.com +drartisan.com +drasy.net +drawyoo.com +drbdp.com +drcact.com +drcbank.com +drcg8.com +drclvs.com +drcnetdns.com +drcuiyutao.com +dream-loft.com +dream-marathon.com +dream.ren +dream211.com +dreamad.mobi +dreamai.fun +dreamavatar.com +dreambig.work +dreamboys.org +dreamcast.hk +dreamchasercapital.com +dreame.tech +dreamershop.com +dreamkite.net +dreammeta.net +dreamo100.com +dreampiggy.com +dreams-travel.com +dreamshell.cc +dreamspark.download.prss.microsoft.com +dreamsparkuat.download.prss.microsoft.com +drearry.com +dreawer.com +drebella.com +dressmeup-hk.com +drgou.com +drice.cc +driect-jajpviewd00.com +driect-jeopbnkoa00.com +driect-sntpjpviewa08.com +driectjp-jeobnksad01.com +driectjp-tuowja02.com +drinkmagazine.asia +drinkpoem.com +drip.im +dripcar.com +driver114.com +driverchina.com +driverdevelop.com +drivergenius.com +driverzeng.com +driverzj.com +drivethelife.com +drjou.cc +drlai.com +drli.group +drlmeng.com +drm-lic-dom.net +drm-x.com +drmaml.com +drmsoft.net +drockart.com +droi.com +droiapps.com +droiseewd.com +droitstock.com +droiyou.com +drokozz.club +dropsec.xyz +drouma.com +drp321.com +drpika.com +drry.site +drscrewdriver.com +drscrm.com +drsmilehealth.com +drsrp.com +drstour.com +drtyf.com +drugadmin.com +drugfuture.com +druggcp.net +drughk.com +druid.vip +drupalla.com +drupalproject.org +drvceo.com +drvi.net +drvsky.com +drxexpo.com +ds-360.com +ds-lg.com +ds028.com +ds123456.com +ds5f.com +dsary.com +dsb.ink +dsbaike.com +dsblog.net +dscbs.com +dscq.com +dsdbxg.com +dsdod.com +dsdyf.com +dseman.com +dser.com +dsfdy.com +dsfjh.vip +dsfpz.com +dsfuse.com +dsfzcz.com +dsfzh.com +dsgaokao.com +dshigao.com +dshltech.com +dshrc.com +dsilicone.com +dsjt.com +dskb.co +dskj-ops.com +dsktjt.com +dskystudio.com +dslbuy.com +dslr120.com +dslrpark.com +dslt.tech +dslvts.com +dslwk.com +dslyy.com +dsm888.com +dsmxp.com +dsmyiyuan.com +dsmzyy.com +dsmzyy120.com +dsnpz.com +dsnzyy120.com +dsook.com +dspga.com +dspgo.com +dspmt.com +dspwhy.com +dsq.com +dsqzls.com +dsqzxyy.com +dsrepark.com +dss.hk +dsspinfo.com +dsssp.com +dsstudio.tech +dssz.com +dst.gov.mo +dstcar.com +dstfsbc.com +dstguanwang.com +dsti.net +dsw6.com +dswjcms.com +dswljt.com +dswmt.com +dswql.com +dswx.cc +dswzxh.com +dsx.ac +dsx2020.com +dsxliuxue.com +dsxys.pro +dsyqt.com +dsyun.com +dsz.cc +dt-paint.com +dt-stor.com +dt123.net +dt830.com +dtao.com +dtcj.com +dtcms.net +dtcoalmine.com +dtcxw.com +dtdcjt.net +dtdream.com +dtdxcw.com +dtechcn.com +dtfjw.com +dthgdq.com +dthr.com +dtidc.com +dtime.com +dtjh-bj.com +dtjhgs.com +dtlpt.com +dtlqg.com +dtlty.com +dtmbw.com +dtmiller.com +dtminds.com +dtmiot.com +dtmuban.com +dtnews.net +dtq.com +dtrcb.com +dtrcw.net +dts007.com +dtssyy.com +dtstack.com +dtstatic.com +dtston.com +dttc-icp.com +dttt.net +dtuosh.com +dtuyun.com +dtwave.com +dtxww.com +dtxxjq.com +dtysky.moe +dtyunxi.com +dtyzg.com +dtzj.com +du-hope.com +du-xiaomai.com +du.biz +du7.com +du8.com +dualaid.com +dualspace.com +dualspacetech.com +duan.red +duangks.com +duanju.com +duanju.fun +duanjuzi.com +duanlonggang.com +duanmale.com +duanmeiwen.com +duanqu.com +duanrong.com +duanshipin.vip +duanshu.com +duantian.com +duanwdm.com +duanwenxue.com +duanwenxue8.com +duanxb.com +duanxiansen.com +duanxianxia.com +duanxin.com +duanxin520.com +duanxindao.com +duanzaixian.vip +duanzao001.com +duanzikuaizui.com +duanziya.com +duapp-preview.com +duapp.net +duasrdwb.com +duba.cc +duba.com +duba.net +dubairen.com +dubao123.com +dubbing.tech +dubbingx.com +dubbo.io +duble.live +dubola.com +dubprince.com +dubyc.com +ducafecat.com +ducafecat.tech +ducar.cc +duchina.com +duckycn.com +duckyset.com +dudong.com +dudongsheji.com +duduaa.com +dudubashi.com +dududm.com +dudujb.com +duduji.com +dudujuzi.com +dudulu.org +dudutalk.com +duduwo.com +duelcn.com +dugrqnn.xyz +duguying.net +duhao.net +duhaobao.net +dui.ai +duia.com +duiai.com +duibiao.com +duibiao.org +duibimao.com +duiduihuishou.com +duiduilian.com +duiduipengds.com +duijie666.com +duikuang.com +duimg.com +duimin.com +duiopen.com +duipu.com +duishu.com +duitang.com +duitangwang.com +duitianhe.com +duiyou360.com +duiz.net +duizhuang.com +dujiabieshu.com +dujin.org +dujixiao.com +dujiza.com +dujun.io +dukang.com +dukechiang.com +duketop1.com +dukharo.com +dukku.com +dukuai.com +dule.cc +dulesocks.com +duliangaotu.com +dulife.com +dulifei.com +dulightapp.com +dullr.com +dulwich.org +dumall.com +dumanhua.com +dumasoftware.com +dumi0898.com +dumpapp.com +dun.la +dun555.com +dun599.com +dunan.net +dunanac.com +dunankeji.com +dunbaigo.com +dundianwang.com +dungeon-server.com +dungkarime.com +dunhuang-yueqi.com +dunhuang.com +dunhuangtour.com +dunjiaodu.com +dunkhome.com +dunstanhardcastle.com +dunsuan.com +dunwang.com +dunzhiwang.com +duoao.com +duobiyi.com +duocaish.com +duocaitou.com +duocengban.org +duochang.cc +duodaa.com +duodanke.com +duodele.com +duodian.com +duodiwan.com +duodunj.com +duoduo.link +duoduo123.com +duoduo365.com +duoduobang365.com +duoduocdn.com +duoduocm.com +duoduodashi.com +duoduoipo.com +duoduopan.com +duoduoshipin.vip +duoduoyin.com +duoduoyoucai.com +duoduoyouli888.com +duoduoyuncai.com +duoduozb.com +duodutek.com +duoduwang.com +duoerpharmacy.com +duofriend.com +duofugroup.com +duogouhui.com +duohuanbao.com +duohui.co +duoic.com +duokaima.com +duokaiwang.com +duokaiya.com +duokaiyun.com +duokan.com +duokanbox.com +duoke.com +duoke.net +duokebao.net +duokebo.com +duoku.com +duolabao.com +duolabaocdn.com +duoladayin.com +duolahua.com +duolaika.com +duolaima.com +duolapiao.com +duolatom.com +duolawk.asia +duolayunwang.com +duole.com +duolebaohuang.com +duolebh.com +duolebo.com +duolegame.com +duolegd.com +duolegj.com +duolegouji.com +duolemahjong.com +duolemajiang.com +duolemao.com +duolepdk.com +duolephz.com +duolesj.com +duolesk.com +duolexing.com +duolexq.com +duoliheng.com +duoliucui.com +duoluodeyu.com +duomeng.fun +duomeng.net +duomeng.org +duomi.com +duomian-static.com +duomian.com +duomiao.pro +duomicheng.com +duominuo.com +duomiyou.com +duomni.com +duomo3205.xyz +duomob.com +duomoyu.com +duomu.hk +duomu.tv +duonvlangceo.com +duopaiad.com +duopao.com +duopei.cc +duopei.xyz +duopingka.com +duoqu.com +duorenwei.com +duorou.com +duorou.me +duorou42.com +duosai.com +duose.com +duosenfashion.com +duoshan.com +duoshitong.com +duoshoubang.com +duoshuo.com +duososo.com +duost.com +duotai.net +duotaoli.com +duotegame.com +duoteyx.com +duotin.com +duotoupiao.com +duotuscdn.com +duowan.com +duowanns.com +duoweijt.com +duoweisoft.com +duowenlvshi.com +duoxinqi.com +duoxue.com +duoyewu.com +duoyi.com +duoying.com +duoyinsu.com +duoyoumi.com +duozhi.com +duozhuayu.com +duozhuayu.net +duoziwang.com +dup2.org +dupingzu.com +duplo-shandong.com +dur9.com +duread8.com +durkcell.com +durkeesox.net +durkflex.net +durongjie.com +dusaiphoto.com +dusao.vip +dusays.com +dusdn.com +dusdn.net +dushaofei.com +dushewang.com +dushi118.com +dushicn.com +dushifen.com +dushiliren.net +dushiquan.net +dushu.com +dushu.io +dushu263.com +dushu365.com +dushu369.com +dushu66.com +dushudaren.com +duskonlinestore.com +dustess.com +dustglobal.com +dusulang.com +dute.me +dutenews.com +dutyfreeyun.com +dutype.com +duuchin.com +duunion.com +duwenxue.com +duwenz.com +duwenzhang.com +duwfi.org +duxiaomai.net +duxiaoman-int.com +duxiaoman.com +duxiaomanfintech.com +duxiaomanfund.com +duxiaomantech.com +duxiu.com +duxuetang.com +duyandb.com +duyao001.com +duyaonet.com +duyixing.com +duyunfk.com +duyunshi.com +duzelong.com +duzhe.com +duzhoumo.com +dv37.com +dv58.com +dvagent.com +dvbbs.net +dvbcn.com +dvbei.com +dvd2017.com.tw +dvdc100.com +dvidc.com +dvkors.com +dvmama.com +dvmission.com +dvr163.com +dvrdydns.com +dvsadive.com +dvvvs.com +dw-microbiology.com +dw4.co +dwbxg.com +dwdds.com +dwforging.com +dwgbj.com +dwgszc.com +dwgwatch.com +dwhub.net +dwidc.com +dwinput.com +dwion.com +dwjkgl.com +dwjpwf.com +dwjxz.com +dwmoniqi.com +dwntme.com +dwoke.com +dwq.com +dwrh.net +dwsedu.com +dwsgases.com +dwstatic.com +dwstock.com +dwt.life +dww11.com +dwwin.com +dwxyamaha.com +dwywood.com +dwywooden.com +dwz.lc +dwzhs.com +dwzjd.com +dx-job.com +dx-marine.com +dx-tech.com +dx00.net +dx10000.com +dx2008.com +dx86.com +dxbei.com +dxcc.org +dxclinics.com +dxda.com +dxdl1688.com +dxdlw.com +dxe520.com +dxecs.com +dxf6.com +dxfbk.com +dxfblog.com +dxgg.co +dxguanxian.org +dxhuafu.net +dxinzf.com +dxjs.com +dxjt2013.com +dxjzz666.com +dxlfile.com +dxm-cdn.com +dxm-int.com +dxm-yibai.com +dxmjinr.com +dxmjuhe.com +dxmlcf.com +dxmlcfintech.com +dxmpay.com +dxmstatic.com +dxmwx.com +dxmyqh.com +dxncyy.com +dxnky.com +dxnt.com +dxnwyjw.com +dxper.net +dxqck.com +dxqjg.com +dxqyy.com +dxr.com +dxrc.com +dxs8.com +dxsaxw.com +dxsbb.com +dxsclass.com +dxsdb.com +dxsdermyy.com +dxshtb.com +dxsk.com +dxsng.com +dxsport.com +dxsrmyy.com +dxsvr.com +dxszx.com +dxton.com +dxtradedata.com +dxtyy.com +dxuexi.com +dxwei.com +dxwfgg.com +dxxxfl.com +dxxzjgdgs.com +dxy.com +dxy.me +dxy.net +dxyan.org +dxyb.com +dxycdn.com +dxyer.com +dxyff.com +dxys.pro +dxyykj.com +dxzanzhu.com +dxzhz.com +dxzk88.com +dxzq.net +dxztc.com +dxzw.com +dxzx.com +dy-bus.com +dy-hospital.com +dy120.net +dy163.cc +dy172.com +dy1905.net +dy2018.com +dy2066.com +dy3j.com +dy558.com +dyaobo2029.com +dybeta.com +dycar.net +dyccb.net +dycdn.com +dycic.net +dycjy.com +dycloud.run +dycloudbk.com +dycmyl.com +dycnchem.com +dycom365.com +dycyw.com +dydata.io +dydt.net +dye-ol.com +dyechina.com +dyedu.net +dyemp.com +dyets-cn.com +dyfc.net +dyfm200.com +dyfsp88.wiki +dyg-hec.com +dygf.com +dygmotor.com +dygod.org +dygyjs.com +dygzs.com +dyhculture.com +dyhengli.com +dyhgames.com +dyhjw.com +dyhongshun.com +dyhuidong.com +dyhxgame.com +dyjqd.com +dyjqlrj.com +dyjs.com +dyjw.info +dyjxjt.com +dyjxsj.com +dyjymy.com +dykszx.com +dykz66.com +dylc.com +dyls.app +dyly.com +dylyghm.com +dymatic.com +dymexhealthcare.com +dyml.net +dymusictape.com +dymusicvideo.com +dynabook-dbh.com +dynavolt.net +dynguyeniq.com +dyonr.com +dypf8.com +dyqc.com +dyqh.info +dyqm888.com +dyrbw.com +dyrcb.net +dyrmt.com +dyrs.cc +dyrtg.com +dysday.com +dysgydlc.com +dyshf.com +dyshortvideo.com +dysj.com +dysji.com +dyspcdntip.com +dythmy.com +dytmgm.com +dytss.com +dytt2028.cc +dytt789.com +dytt7899.com +dytt8.net +dytt89.com +dyvideotape.com +dywcc.com +dywuyuan.com +dywxs.com +dywzx.com +dyxldjy.com +dyxsdwm.com +dyxtw.com +dyxuexin.com +dyxw.com +dyxz.la +dyxzyy.com +dyys.com +dyysdhv.xyz +dyysoft.net +dyyy120.com +dyzdx.com +dyzpw.com +dyzs163.com +dyzsart.com +dyzxw.org +dz-ailive.com +dz-ic.net +dz-x.net +dz-z.com +dz.tt +dz000.com +dz0566.com +dz11.com +dz137.com +dz169.com +dz19.net +dz1982.com +dz211.com +dz31hao.com +dz88.com +dz98.com +dzabosn.com +dzbarcode.com +dzbchina.com +dzbdq.com +dzblo.com +dzboligang.com +dzbxk.com +dzcch.com +dzcj.tv +dzcjw.com +dzcmedu.com +dzcnc.com +dzcolor.com +dzcrcgas.com +dzdesign.cc +dzdiy.com +dzdu.com +dzdvip.com +dzdxs.net +dzdzzd.com +dzemotor.com +dzfang.com +dzfc.com +dzfjsm.com +dzfwjd.com +dzglsb.net +dzgxq.com +dzh.link +dzhlive.com +dzhope.com +dzhqexpo.com +dziuu.com +dzjc.com +dzjkw.net +dzjob.net +dzkbw.com +dzkx.org +dzlaa.com +dzlems.net +dzljy.com +dzllzg.com +dzlndygh.com +dzmachines.com +dzmhospital.com +dzng.com +dzoptics.com +dzp.tv +dzpc.net +dzpezp.com +dzpk.com +dzpklite.com +dzpknews.com +dzqrmyy.com +dzqu.com +dzqxj.com +dzr120.com +dzrbs.com +dzrcd.com +dzronghui.com +dzrsteel.com +dzs2004.com +dzsaas.com +dzsaascdn.com +dzsc.com +dzsdg.com +dzsg.com +dzsjgroup.com +dzsjtjt.com +dzsm.com +dzspzx.com +dzsrcw.com +dzst999.com +dzszlsyxgs.com +dztester.com +dztugongbu.net +dztv.tv +dztz168.com +dzvv.com +dzw3.com +dzwad.com +dzwebs.net +dzwindows.com +dzwork.net +dzwww.com +dzwww.net +dzwy.com +dzxsw.net +dzxw.net +dzxxzy.com +dzxzh.com +dzy.link +dzybk.com +dzyqc.com +dzyule.com +dzyysb.com +dzyzj.com +dzz.cc +dzzcgs.com +dzzgsw.com +dzzoffice.com +dzzui.com +dzzy88.com +dzzyisp.com +e-10031.com +e-adcon.com +e-ande.com +e-bidding.org +e-buychina.com +e-byte.com +e-cbest.com +e-celap.com +e-chinalife.com +e-cig-market.com +e-ciie.com +e-cloudstore.com +e-cookies.net +e-cspc.com +e-cuc.com +e-czt.com +e-elitech.com +e-eway.com +e-fangtong.com +e-flyinc.com +e-fong.com +e-ging.com +e-ging.net +e-giordano.com +e-gooo.com +e-guofu.com +e-hongw.com +e-hqins.com +e-huaxue.com +e-icco.com +e-jianxiu.com +e-jitp-dom.com +e-jitp-dom.net +e-jitp-glo.com +e-jitp-glo.net +e-jjj.com +e-jlt.com +e-kawai.com +e-kays.com +e-length.com +e-lining.com +e-mallchina.com +e-mmt.com +e-nci.com +e-nebula.com +e-net.hk +e-onekey.com +e-peilian.com +e-picclife.com +e-pointchina.com +e-power.vip +e-pxn.com +e-qdpm.com +e-readbook.com +e-ruikd.com +e-seenet.com +e-sleb.com +e-sscard.com +e-tecsun.com +e-tiller.com +e-ufnb.com +e-uniongroup.com +e-vaulting.com +e-xina.com +e-xp05.vip +e0453.com +e0514.com +e0575.com +e0734.com +e0838.com +e1.vdowowza.vip.hk1.tvb.com +e12345.com +e1288.com +e1299.com +e12e.com +e13000d6f1019.beer +e151475d71020.beer +e1617.com +e1988.com +e1evh0lp4n.com +e213155.com +e21cn.com +e22a.com +e23dns.net +e24c.com +e253.com +e27e02c891010.beer +e2capp.com +e2edesign.com +e2esoft.com +e2say.com +e307586127f21050.com +e32047a8e21fbc0a.com +e32a01b94145bb23.com +e3492587711012.beer +e360e.com +e363172a110241.beer +e365mall.com +e36b9a1c210301.beer +e3861.com +e38647b2411b17c3.com +e3j.co +e3ol.com +e4008.com +e43bb71e710272.beer +e44e4e8c11020.beer +e452a362210291.beer +e495f363ae7187cf.com +e4d0c1f1d1021.beer +e4e4c4415fd53198.com +e4l4.com +e4xk2cvh.work +e508250086b14d75.com +e53w.com +e5413.com +e5865f69dee0.xyz +e58860e249bf56ad.com +e58b70798965b223.com +e58f8d5eb11032.beer +e5a743f9511d287d.com +e5d929dd82a164f1.com +e5d9384f510292.beer +e5e333e55e5e3d.xyz +e5hc.com +e5n.com +e5sj.com +e5tech.com +e600.com +e656gps.com +e65u.com +e66609.com +e68cname.com +e6ad1d0761021.beer +e6gps.com +e763.com +e77b0ff1f10241.beer +e7890.com +e7ba7566e10291.beer +e7cc97fab56d13b6.com +e7cn.net +e7e6.net +e7e7e7.com +e7f60ece99e82d92.com +e7flash.com +e7lang.com +e7wan.com +e7wei.com +e7z.net +e8034d5ac1022.beer +e80bf18e978d9e37.com +e80fb4ced1015.beer +e81fd4b49ca5e6a4.com +e836g.com +e84p8174c7.com +e88u.com +e890.com +e8bfeae1bf34023d.com +e8cfdb0ee10272.beer +e9527ad346cb0157.com +e9797.com +e9898.com +e99999.com +e9x51y8t91.com +ea-china.com +ea-retina.com +ea-xing.com +ea2cn-dev-outlet.dell.com +ea2cn-prod-outlet.dell.com +ea2cn-staging-outlet.dell.com +ea360.com +ea3w.com +ea65d2a2f16d6b8c.com +ea6d86dbe8e3e423.com +ea7c8805e10241.beer +ea89f50fde822303.com +eabax.com +eachnet.com +eachsee.com +eachtravel.com +eachwave.com +eadianqi.com +eaeacn.com +eaecis.com +eaf341cc30c286cf.com +eafifaonline2.com +eagle-sight.com +eaglebgm.com +eaglebrandgroup.com +eagleceramics.com +eaglecoin.com +eaglejt.com +eaglemale.com +eaglenos.com +eagleyun.com +eagllwin.com +eagonxc.com +eagsen.com +eaibot.com +eaka365.com +eal-ceair.com +eallcn.com +eallerp.com +eamn.net +eanfang.com +eanmed.com +eap2.net +eapchina.net +ear0.com +eardatek.com +earlytrip.fun +earningapp.info +earth-science.net +earth-traveller.com +earth2037.com +earthdq.com +earthedu.com +earthstar-cloud.com +earture.org +easck.com +eascs.com +easea.net +easebar.net +easecation.net +easeconvert.com +easefun.info +easeheal.com +easemob.com +easerun.com +easesale.com +easesdk.com +easeslb.com +easetuner.com +easeus.com +easeyedelivery.com +eashu.com +easi-tech.com +easilysend.com +easipass.com +easipay.net +easitcn.com +easiu.com +easonad.com +east-regis.com +east.net +east263.com +eastall.com +eastar-group.com +eastbest.com +eastbuy.com +eastchinafair.com +eastcmc.com +eastcom-group.com +eastcom-sw.com +eastcom.com +eastcom.site +eastcompeace.com +eastcoms.com +eastday.com +eastdesign.net +eastdrama.com +eastdushi.com +easteat.com +eastecloud.com +eastecp.com +eastelsoft.com +eastent.com +eastern-tek.com +easternalong.com +easternpose.com +eastforever.com +eastfu.com +easthc.com +easthome.com +eastib.com +easticloud.com +eastjl.com +eastjq.com +eastled.com +eastlen.com +eastlending.com +eastmab.com +eastmannplastics.com +eastmarathon.com +eastmoney.com +eastmoneyfutures.com +eastmoneyloans.com +eastmoneysec.com +eastobacco.com +eastpharm.com +eastpump.com +eastshanghaifair.com +eastsilver.com +eastsoo.com +eastspacelight.com +eaststarbio.com +easttone.com +eastunion.net +eastups.com +eastwin-zc.com +eastwinn.com +eastwudpharma.com +eastyule.com +easu.net +easugar.com +easy-all.net +easy-china.com +easy-dotnet.com +easy-eai.com +easy-ent.com +easy-h5.com +easy-linkholiday.com +easy-mock.com +easy-signing.com +easy163.net +easy2world.com +easy361.com +easy888.com +easyar.com +easyarvr.com +easybug.org +easyclean.fun +easydarwin.org +easyder.com +easydo.work +easydoc.net +easyeda.com +easyfang.com +easyfapiao.com +easyfunfun.com +easygame2021.com +easygametime.com +easygovm.com +easyhaitao.com +easyhin.com +easyidc.com +easylabplus.com +easyliao.net +easylinkin.com +easylinkin.net +easymule.com +easynet.vip +easypakk.com +easypayx.com +easyrecovery.cc +easyrecovery.net +easyrecoverycn.com +easyscholar.cc +easysensor.net +easysofthome.com +easyswoole.com +easytifen.com +easytimetv.com +easytite.com +easytocn.com +easytogophuket.com +easytouch-manager.com +easytouch.com +easytrip.com +easyv.cloud +easywza.com +easyya.com +easyzw.com +eaton-samc.com +eatonbusbar.com +eatuo.com +eavic.com +eawh.com +eaydu.com +eayh.com +eaymusic.com +eayou.com +eayuan.com +eayyou.com +eazypharm.com +eazytec-cloud.com +eb-ind.com +eb0de9d6bc52f2d0.com +eb10c842d10291.beer +eb623580160e8cbc.com +eb80.com +eb94ccc9625d8539.com +ebadfbe1278533ae.com +ebadu.net +ebaidutv.com +ebaifo.com +ebaina.com +ebaixing.com +ebama.net +ebancom.com +ebangchina.com +ebank96518.com +ebanma.com +ebanshu.net +ebaodai.com +ebaoquan.org +ebaotech.com +ebasset.com +ebb6ea72919edea2.com +ebbcb476210291.beer +ebbf2f9101016.beer +ebchina.com +ebchinaintl.com +ebchinatech.com +ebcvm.org +ebdan.net +ebdoor.com +ebfb8c1c2f714608.com +ebfcn.com +ebfkc.com +ebfortune.com +ebgic.com +ebibi.com +ebico.com +ebidbid.com +ebidding.com +ebigear.com +ebiobuy.com +ebiomall.com +ebiotrade.com +ebioweb.com +ebjfinance.com +ebjservice.com +eblockschina.com +ebls-group.com +ebnew.com +ebocert.com +ebookmen.com +ebopark.com +eboxmaker.com +ebpftravel.com +ebptp.com +ebrun.com +ebscn-am.com +ebscn.com +ebscohost.com +ebseek.com +ebsfw.com +ebt.group +ebtang.com +ebtrust.com +ebuckler.com +ebullienceconsultancy.com +ebumbrella.com +ebuy16.com +ebuy1718.com +ebways.com +ebyet.com +ebyte.com +ec-ae.com +ec-cloudtech.com +ec-dns.com +ec-founder.com +ec-sz.com +ec-world.com +ec.com +ec07yxgd11.com +ec233.com +ec3s.com +ec45f2d84111f960.com +ec4ca59341009.beer +ec4e54545d0e31fa.com +ec51.com +ec6056a95386f752.com +ec8j.com +ecac1cd921021.beer +ecadi.com +ecaidian.com +ecaihr.com +ecamzone.cc +ecanmed.com +ecapp.org +ecaptechnology.com +ecaray.com +ecare365.com +ecarechina.com +ecarxgroup.com +ecb43b6f5064acc6.com +ecbcamp.com +ecboo.com +ecbos.com +ecbuy.net +eccang.com +eccc-china.com +eccdnx.com +eccn.com +eccnmall.com +ecco-market.com +eccpos.com +ecdag.net +ecdnx.com +ecduo.com +ece-global.com +eceibs.com +eceibs.net +eceibs20.com +ecej.com +ecer.com +ecerdns.com +ecerimg.com +ecf-gov.com +ecgci.com +ecgoods.com +ecgtool.com +echanceyun.com +echangye.com +echao8.com +echargenet.com +echarpile.com +echatsoft.com +echead.com +echemsrc.com +echepiao.com +echiele.com +echinacareers.com +echinacities.com +echinagov.com +echinalife.org +echinatobacco.com +echo-isoftstone.com +echo188.com +echoing.tech +echoteen.com +echovelle.com +echu-cable.com +echuaren.com +echunlan.com +echuzhou.com +eci-everconn.com +eciawards.org +ecice06.com +ecigdaily.com +ecinnovations.com +ecitic.com +ecitic.net +eciticcfc.com +ecjobhome.com +ecjson.com +eckgxbfa.com +eckwai.com +ecloud-gdu.com +ecloud.hk +ecmc-nj.com +ecmould.com +ecnpl.net +ecnu.net +ecnuas.com +ecnudec.com +eco-seavol.com +eco-system.xyz +ecoalchina.com +ecocn.org +ecodreamers.com +ecoland-plan.com +ecoliving168.com +ecolovo.com +ecom-lightapp.com +ecomanbiotech.com +ecombdapi.com +ecombdimg.com +ecombdpage.com +ecombdstatic.com +ecombdvod.com +ecomoter.com +econtactsplus.com +ecool.site +ecoplastech.com +ecoprint.tech +ecorr.org +ecotourgroup.com +ecouser.net +ecovacs.com +ecovacsgroup.com +ecowrd.com +ecp-cloud.com +ecp-cloud.net +ecphk.com +ecplf.com +ecppn.com +ecpsrplus.com +ecqd.com +ecqun.com +ecr-global.com +ecrrc.com +ecs6.com +ecsage.net +ecscoupon.com +ecscpu.com +ecshop.com +ecshop123.com +ecsits.com +ecspartner.com +ecsponline.com +ecsxs.com +ectdno.com +ectencent.com +ectnno.com +ectnno.org +ectrip.com +ecukwai.com +ecustmde.com +ecv360.com +ecvv.com +ecwan77.net +ecydm.com +ecyti.com +ecyzm.com +eczuafam.com +ed-textile.com +ed21.cc +ed2k.vip +ed2kers.com +ed2kk.com +ed403ab821011.beer +ed77fc33a10241.beer +ed834dbe3264d3a0.com +eda-china.com +eda1024.com +eda2.com +eda365.com +eda365.net +eda4bf686e3ac7d4.com +eda7fb17710272.beer +edaboss.com +edadoc.com +edagit.com +edai.com +edaibo.com +edaili.com +edaixi.com +edaizhijia.com +edajob.com +edaka.org +edaocha.com +edata100.com +edatahome.com +edatop.com +edawiki.com +edaxiang.com +edazhang.com +edb-tech.com +edcba.com +edcdfg.com +edcfda.com +eddic.net +eddingpharm.com +eddycjy.com +ede35.com +ededian.com +edefang.net +edengjiang.com +edesson.com +edge-byted.com +edge-cluster-hk-pre.com +edge.music-choice-play-chaina1.top.comcast.net +edgefn.net +edgegslb.com +edgekey88.net +edgemec.com +edgeone-ai-dev.com +edgeone-ai.com +edgeone-browser-rendering-dev.com +edgeone-browser-rendering.com +edgeone.ai +edgeone.app +edgeone.cool +edgeone.run +edgeone.site +edgeonedl1.com +edgeonedl1.net +edgeonedy1.com +edgeonedy1.net +edgeonestic1.com +edgeonestic1.net +edgeonetcp1.com +edgeonetcp1.net +edgeonev1.com +edgeonev1.net +edgeonev2.com +edgeonev2.net +edgeonev3.com +edgeonev3.net +edgeonev4.com +edgeonev4.net +edgeonev5.com +edgeonev5.net +edgeonevod1.com +edgeonevod1.net +edgep.net +edgesrv.com +edgetls.xyz +edhic.com +edi198.com +edianda.com +edianshang.com +ediantec.com +edianyun.com +edianzu.com +ediaoyu.com +ediconf.org +edifier.com +edimob.com +edingzhuan.com +edisec.net +editorjianying.com +editsprings.com +edlcaster.com +edmcn.net +edmseller.com +edns.com +edojia.com +edong.com +edongeejiao.com +edongli.net +edongyun.com +edoou.com +edowning.net +edozx.com +edqgk.com +edragongame.com +edrawsoft.com +edream-tech.com +edsionte.com +edspay.com +edt2017.com +edt2018.com +edtsoft.com +edty.com +edu-cj.com +edu-edu.com +edu-nw.com +edu03.com +edu0851.com +edu1488.com +edu24o1.com +edu24ol.com +edu4399.com +edu510.com +edu5a.com +edu63.com +edu777.com +edu84.com +edu84.net +edu88.com +eduaaf.com +eduaiplat.com +eduapaashwc.com +eduardoam.com +eduartisan.com +educg.net +educhn.net +educoder.net +edudc.net +edudigital123.com +eduease.com +eduego.com +eduei.com +eduglobal.com +eduglobalchina.com +eduhuoshi.com +edui.fun +eduic-sh.com +eduiso.com +edujia.com +edujianshe.com +edujiaoyu.com +edukuang.com +edulawonline.com +edulivevideo.com +edumail.pub +edumine.net +edumq.com +eduour.com +edupm.com +edurck.com +edushi.com +edusoho.com +edusoho.net +edusy.net +edutao.com +edutime.net +edutrackconsult.com +edutxw.com +eduu.com +eduuu.com +eduwenzheng.com +eduwest.com +eduwo.com +eduwx.com +edux.design +eduxcxportal.com +eduxiji.net +eduydt.com +eduyf.com +eduyo.com +eduzb.com +eduzhai.net +eduzhixin.com +eduzs.net +edwiv.com +edxmy.cc +ee-nav.com +ee067e33bd637916.com +ee123.net +ee1234.com +ee409d6370bfc826.com +ee45560.com +ee68.com +ee6da7410adfd3aa.com +ee702ec398aaecfd.com +ee99.net +eeban.com +eebbk.com +eebbk.net +eeboard.com +eechina.com +eecnt.com +eecourse.com +eecso.com +eedevice.com +eedns.com +eedzvv.com +eee-eee.com +eee4.com +eeeam.com +eeedri.com +eeedu.net +eeeen.com +eeeetop.com +eeeff.com +eeekkk.com +eeeknow.com +eeeqi.net +eees.cc +eeetb.com +eeezahomemena.com +eefans.com +eefcdn.com +eeff.net +eefocus.com +eefung.com +eegem.com +eehk.net +eehu.com +eei168.com +eeio99.com +eeioe.com +eeju.com +eelly.com +eema.info +eenzo.com +eeook.com +eeparking.com +eepw.com +eeqiu.com +eeskill.com +eeso.net +eestar.com +eetoday.com +eetop.com +eetrend.com +eetrust.com +eeuetqbv.shop +eevision.com +eeworld.com +eeworm.com +eexiaoshuo.com +eeyd.com +eeyxs.com +eeyys.com +eezml.com +ef-cdn.com +ef17145aecd7dd06.com +ef360.com +ef360.net +ef369594911012.beer +efang.tv +efangwang.com +efapiao.com +efasco.com +efashionchina.com +efashioncloud.com +efb6ff0d81022.beer +efbf407b011021.beer +efchina.org +efe.cc +efengqing.com +efesco.com +eff-soft.com +eff85fd9610292.beer +effapp.com +efficient.hk +effood.net +efglobal-gy.com +efivestar.com +efl-tech.com +eflagcomm.com +eflybird.com +eflycloud.com +eflydns.net +efmac.net +efnchina.com +eforclub.com +efotile.com +efount.com +efoxconn.com +efpp.com +eftime.com +efucms.com +efueloil.com +efuin.com +efunchina.com +efuncn.com +efunent.com +efunq.com +efusc.com +efwh.com +efy-tech.com +efzhou.com +efzzs.com +egainnews.com +egbt.net +egcmedia.com +egeel.com +egfb2221.com +eggbnk.com +eggrj.com +eghimalayanak.com +egjqgs.com +ego-robotics.com +egoint.com +egongzheng.com +egood995.com +egoonet.com +egotops.com +egou68.com +egouz.com +egovsum.com +egpctiz.com +egpharm.com +egqch.link +egqkxzd.com +egrdrill.net +egreatworld.com +egret-labs.org +egret.com +egridconsulting.com +egrowads.com +egsea.com +egshuyuan.com +egsssy.com +egt365.com +egu365.com +eguangjie.com +eguantao.com +eguqwhvg.com +egwealth.hk +egxlx.com +ehafo.com +ehaier.com +ehaini.com +ehaiwang.com +ehang.com +ehanglian.com +ehangtian.com +ehaohai.com +ehaoyao.com +ehaoyao.us +ehclglobal.com +ehealthcareforum.com +ehecd.com +ehedco.com +ehejun.com +ehengjian.com +eheren.com +ehetech.com +eheyin.com +ehijoy.com +ehinvest.hk +ehnasia.com +ehnchina.com +ehome-env.com +ehome5.com +ehome8.com +ehomeclouds.com +ehomeday.com +ehousechina.com +ehowbuy.com +ehowbuy.net +ehrel.com +ehschina.com +ehsy.com +ehtcn.com +ehualu.com +ehuarun.com +ehuatai.com +ehuataifund.com +ehub.net +ehui.net +ehuijing.com +ehujia.com +ehuoke.com +ehuoyan.com +ehuoyun.com +ehutu.com +ehuyao.com +ehuzhu.com +ei6nd.com +eia-data.com +eia543.com +eiacloud.com +eiafans.com +eiccmall.com +eickaopei.com +eicodesign.com +eicourse.com +eicp.net +eicp.vip +eicuhq.xyz +eiczz.com +eid-sft.com +eidcenter.com +eidlink.com +eidtokencloud.com +eifini.com +eightbridge.com +eightedu.com +eigpay.com +eihtfire.com +eiicn.com +eiisys.com +eiixx.com +eijiucq.com +eilieili.cc +eimoney.com +einfo-tech.com +eingdong.com +einkcn.com +einsteintiles.com +eintone.com +eiot.com +eisoo.com +ejamad.com +ejc56.com +ejcms.com +ejcop.com +ejdrone.com +ejdyin.com +ejectu.com +ejecx.com +ejee.com +ejeegroup.com +ejhimalayanje.com +ejia7.net +ejiacn.com +ejianlong.com +ejianmedia.com +ejiawang.cc +ejiayou.com +ejiayu.com +ejie.me +ejiecheng.com +ejinshan.net +ejion.net +ejmrh.com +ejomoo.com +ejoo.cc +ejoy.com +ejoy365.com +ejoy365hk.com +ejrfood.com +ejsoon.win +ejtieyi.com +ejtsyc.com +eju.com +ejudata.com +ejuhome.com +ejustcn.com +ejy365.com +ek-edu.com +ek1ng.com +ekaidian.com +ekan001.com +ekang99.com +ekangji.com +ekaobang.com +ekaoyan.com +ekaoyan365.com +ekclubinternational.com +ekdoc.com +ekecdn.com +ekewy.com +ekimmigration.com +eking-tech.com +ekingair.com +ekingtopwood.com +ekmic873o6vkza.com +ekoooo.com +eks0451.com +eksoi7mwa4fa27.com +ekuaibao.com +ekumao.com +ekumb.com +ekuzy.com +ekweixin.com +ekwing.com +ekxx.net +elabinfo.com +elabpic.com +elaina.vin +elaiter.com +elameyal.com +elane.com +elangchina.com +elanking.com +elanp.com +elanso.com +elanw.com +elascloud.com +elawoffice.net +elbmodel.com +eldamu.com +eldawa.com +ele.me +ele.to +ele001.com +ele1.com +ele12.com +elec100.com +elecfans.com +elecfans.net +elecinfo.com +elecloud8.com +elecrystal.com +elecshop.com +elecspn.com +eleduck.com +elefang.com +elefirst.com +elegant-prosper.com +elegsant.com +elelx.com +eleme.hk +eleme.io +elemecdn.com +element3ds.com +elementaw.com +elementfresh.com +elenet.me +elephant-base.com +elephantrobotics.com +eleui.net +elevator-expo.com +elex-tech.net +elexcon.com +elextec.com +elfartworld.com +elfinbook.com +elfjs.com +elht.com +elian5.com +elianhong.com +elianmeng.vip +eliansy.com +elianwiz.com +eliaoxuke.com +elicht.com +elikeme.com +elikeme.net +elimautism.org +eling.me +elingka.com +elingyun.com +elinzy.com +elita.work +elite-shooters.com +elitecrm.com +elitenexusgroup.com +elitesland.com +elitetie.com +elitimes.com +eliwang.com +elkpi.com +ellassay.com +ellechina.com +ellemen.com +elleschool.com +elliotxing.com +elmerlxy.com +elmerzhang.com +eloancn.com +elong-edm.com +elong.com +elong.net +elongai.com +elonghotel.com +elongshine.com +elongstatic.com +elongtrip.com +elontest.com +eloonggame.com +eloongsun.com +elpcon.com +elpland.com +elpont.net +elpsky.com +els001.com +elsker.com +elsz5.xyz +eltmall.com +eltt.org +eltws.com +eluxiu.com +eluying.com +elvgufen.com +elvshi.com +elvxing.net +elxk.com +elysia.beauty +em86.net +emai.com +email.fund +emaileds.com +emailflame.com +emailuo.com +emailxqq.com +emak.hk +emakerzone.com +emall001.com +emao.com +emao.net +emaozi.com +emapgis.com +emarketingw.com +emas-poc.com +ematong.com +emaup.com +emavil.com +emax.cc +embcom.net +embed-cloudstudio.net +embed.cc +embedfire.com +embedhq.org +embedmcu.com +embedsky.com +embedtrain.org +embedu.org +embedunion.com +embedway.com +embest-tech.com +embryform.com +embryochina.com +embsky.com +emby.men +emby.yun +embyvip.org +emcbj.com +emcdir.com +emcsosin.com +emdoor.com +emea.cdnetworks.com +emed.cc +emeiju.com +emeixian.com +emeixs.com +emengju.com +emeok.com +emepu.com +emerald.com +emeratech.com +emergencyexit.xyz +emfuture.com +emilechouriet.com +emiltorres.com +emin123.com +eminsheng.com +emiretasnbd.com +emjianshen.com +emjob.com +emlinix.com +emlog.net +emmmn.com +emodor.com +emoi-cncdn.bing.com +emoji6.com +emojimobile.com +emoriko.com +emotibot.com +emotofine.com +emots.cc +emoyu.com +empornium.me +emqx.cloud +emqx.com +emqx.net +emr-volces.com +ems-audio.com +ems517.com +emsec.hk +emsepc.com +emshost.com +emshua.com +emsym.com +emtana.com +emtcm.com +emtronix.com +emtx.com +emu999.net +emuban.com +emuch.net +emuchong.com +emugif.com +emui.com +emui.tech +emuia.com +emulatedlab.com +emumax.com +emupic.com +emushroom.net +emwan.com +emzexzfp.com +en-micro.com +en.tm +en51.com +en5static.com +en8848.com +en998.com +enacdn.biz +enacdn.info +enacdn.net +enaiter.com +ename.com +ename.net +enantiotech.com +enbamaoyi.com +enbrands.com +encthinking.com +enderbbs.fun +enderuixm.com +endianpp.com +endovastec.com +endowa-auto.com +endress.store +endurance-shinmaywa.com +enec.net +enelcn.com +energy-greenland.com +energy-root.com +energy-zj.com +energychina.press +energyhz.com +enerpat.net +enet16.com +enet16.net +enet360.com +enet369.com +enetedu.com +enfi.vip +enflame-tech.com +enfodesk.com +enforever.com +eng24.com +engeniustec.com +engeyuan.com +engineeringvillage.com +engley.com +englibrary.com +english163.com +englishdict.cc +englishmasterclub.com +englishtimes.cc +engloncar.com +engpx.com +engr-z.com +enguo.com +engz.net +engzai.com +enianteam.com +enicn.com +eniu.com +enjerr.com +enjlink.com +enjoy.link +enjoy1992.com +enjoy3c.com +enjoycare.com +enjoydiy.com +enjoyfe.com +enjoyglobal.net +enjoying3d.com +enjoykorea.net +enjoymeet.com +enjoynowapp.com +enjoyor.net +enjoyyue.com +enjoyz.com +enketu.com +enkichen.com +enkj.com +enkris.com +enlaide.com +enlightent.com +enlistsecurely.com +enmonster.com +enmotech.com +enmuo.com +enn-ng.com +ennenergy.com +ennew.com +ennewpower.com +ennews.com +ennmt.com +ennobay.com +ennocad.com +ennovabio.com +ennpet.com +ennpower.com +ennresearch.com +enovatemotors.com +enoya.com +enpapers.com +enpht.com +enpower-sd.com +enpowermicro.com +enproscm.com +enqoo.com +enread.com +enricgroup-sh.com +enrlb.com +enroo.com +enroobbs.com +enruida.com +enruigroup.com +enrz.com +ens4.com +enshide.com +enshijob.com +ensignworld.com +enstylement.com +ent001.com +ent120.com +entengll.com +enterdesk.com +enterdesk.net +entive.com +entstudy.com +entts.com +enunix.com +enuomachinery.net +envi-ch.com +envisionagents.com +envisioncn.com +enwing-tech.com +enxicled.com +enyamusical.com +enyugame.net +enzj.com +eo-edgefunctions.com +eo-edgefunctions1.com +eo-edgefunctions2.com +eo-edgefunctions3.com +eo-edgefunctions4.com +eo-edgefunctions5.com +eo-edgefunctions6.com +eo-edgefunctions7.com +eo-edgefunctions8.com +eo-edgefunctions9.com +eo-preview.com +eo-shieldspace.com +eo-vod.com +eo-vod1.com +eo-vod2.com +eo-vod3.com +eo-vod4.com +eo-vod5.com +eo-vpcgw.com +eoacc2.com +eoacme-dev.com +eoacme0.com +eoacme1.com +eoacme2.com +eoacme3.com +eoaluminium.com +eobuwieplonline.com +eoeandroid.com +eoemarket.com +eoemarket.net +eoffcn.com +eofreqctrl.com +eofreqctrlbk.com +eogamewechat.com +eoivisa.com +eojofdrzei4.com +eolce.com +eolink.com +eolinker.com +eomgames.net +eomoo.com +eomoy.com +eonad.org +eonlytech.com +eonun.com +eoof.net +eoofoo.com +eooioo.com +eoopoo.com +eooqoo.com +eoouoo.com +eoovoo.com +eoriver.com +eorygadw.com +eorzea.moe +eosantpool.com +eoss-hj.com +eovod.com +ep-china.net +ep-zl.com +ep12.com +ep365.com +epaas.net +epaiclub.com +epailive.com +epalfish.com +epandian.com +epanshi.com +epark.cc +epassway.com +epay.com +epaynfc.com +epbiao.com +epchina.com +epcnn.com +epcservicio.com +epcsw.com +epd3.com +epday.com +epeaksport.com +epeimall.com +epeo.net +epermarket.com +epesr.com +epet.com +epetbar.com +epetpet.com +epexpo-asia.com +epfrontier.com +epg-power.com +ephen.me +ephua.com +epian1.com +epiaogo.com +epibiotek.com +epicgamesspot.com +epichust.com +epinautomation.com +epinduo.com +epinga.com +epinhoo.com +epinv.com +epinzu.com +epjike.com +epjob88.com +epkey.com +eplove.com +epluspvy.com +epnnel.com +epoos.com +eportyun.com +eprcw.com +eprezi.com +eps-tigermed.com +epsea.com +epshw.com +epstsoft.com +eptchina.com +eptsz.com +epub360.com +epubit.com +epweike.com +epwitkey.com +epwk.com +epzcw.com +epzwxs.com +eq321.com +eqding.com +eqh5.com +eqicha.com +eqidi.com +eqie.com +eqifa.com +eqigou.com +eqingdan.com +eqixiu.com +eqiyingxiao.com +eqlky.com +eqmis.com +eqmobi.com +eqnvip.com +eqoavtbu.com +eqq.net +equalocean.com +equdong.net +equipmentimes.com +eqxiu.com +eqxiul.com +eqxiuzhan.com +eqyn.com +er07.com +er8gmvwi54p5x1.com +eraclean.com +eraedu.com +eral.com +eran123.com +eranet-dns.com +eranet.com +eranqi.com +erapp.run +erbadu.com +erbingimg.com +ercc.cc +ercfh.com +ercoabv.com +erda.cloud +erdaicms.com +erdangame.xyz +erdangjiade.com +erddv.com +erdiamond.com +erdianzhang.com +erdong.site +erdosedu.com +erdosrcb.com +erdossysw.com +erelcn.com +erentalcarpro.com +ereter.com +ereuiib.com +erfang-ic.com +erg3r.com +ergcb.com +ergecdn.com +ergedd.com +ergediandian.com +ergeduoduo.com +ergengtech.com +ergengtv.com +ergouzi.fun +ergvx.com +erhlyc.club +erhss.org +erhua.cc +eric-bot.com +ericdeng.net +erichfund.com +eriqua.com +erji.com +erji.hk +erji.net +erjianglin.com +erjiren.com +erk8.com +erke.com +erkuai.com +erldoc.com +erlo.vip +erlou.com +ermain.com +ermao.com +ermao.live +ermeiti.com +ermiao.com +ernaonet.com +ernest.me +ernxzc.com +eroacg.com +eromesalo.com +erongdu.com +erp321.com +erp321.net +erpang.cc +erpingge.com +erpwd.com +erro.life +ersantian.com +ershicimi.com +ersjk.com +ersoso.com +ersuo.com +ert.icu +ert7.com +erthb.online +ertmineq.com +ertongkongjian.com +ertongtuku.com +ertoutiao.com +erun.cloud +erun360.com +ervtqeq1206.vip +erw.cc +erxin360.com +erxitong.com +erya100.com +eryajf.net +eryanet.com +eryi.org +eryyutu.com +erzzz.com +es-soccer.com +es100.com +es2q.com +es86.com +es9e.com +esa2000.com +esafenet.com +esandcloud.com +esavip.com +esbedu.com +esbook.cc +esc.show +escdn.com +escjy.com +esclt.net +escortevenly.com +esdaxiagu.com +esde.cc +esdhm.net +esemseo.com +esenagro.com +esensoft.com +esfimg.com +esgforum.com +esgz.com +eshangle.com +esheep.com +eshenlin.com +eshimin.com +eshine-logistics.com +eshiyun.info +eshop-switch.com +eshopb2c.com +eshoppromohub.com +eshow365.com +eshufa.com +eshuizong.com +eshukan.com +eshzp.com +esilk.net +esinidc.com +esipark.com +esjlf.com +esjson.com +esk365.com +eskedu.com +eskimall.com +eskysky.com +eslosity.com +eslygroup.com +esm8u7oe9ci5.com +esmartwave.com +esnai.com +esnai.net +esni.tech +esnpc.com +esoboy.com +esoho.org +eson.org +esoo.org +esoogle.com +esou.biz +esoua.com +esound.vip +esouou.com +espeedpost.com +esplus.club +espnlol.com +esports-console.com +esportsreg.com +esr.com +essaystar.com +essca.com +essclick.com +essemi.com +essencefund.com +esseniot.com +essent-tech.com +ession.com +essjj.com +esstglobal.com +essurl.com +esswye.com +essxp.com +essyy.com +estandonhotel.com +esteellink.com +estelchina.com +estonegroup.com +estory365.com +estrongs.com +esttools.com +estudychinese.com +estun.com +esudai.com +esugimoto.com +esun21.com +esun88.com +esune.com +esunny.com +esunresin.com +esurging.com +eswin.com +eswincomputing.com +eswlnk.com +eswxj.com +eswzx.com +esxlt.com +eszmall.com +esztsg.org +esztyg.com +eszwdx.com +eszyb.com +et-api.com +et-cdn.com +et-fine.com +et001.com +et0731.com +et59.com +etagri.com +etang.com +etao.com +etaog.com +etaswisswatch.com +etbet.com +etccenter.com +etccenters.com +etcchebao.com +etcgsx.com +etchcb.com +etcifk.vip +etcifw.vip +etciwe.vip +etcsd.com +etcsx.com +etcupor.cc +etczs.net +etczx.com +etelux.com +eternalsys.com +eterngroup.com +etescape.com +etest8.com +eteste.com +etf.group +etf88.com +etfcjz.com +etfiber.net +etg56.com +ethainan.com +ethan.pub +ethercap.com +ethereum.work +etian365.com +etiantian.com +etiantian.net +etimeusa.com +etitgo.com +etiv.me +etjournals.com +etjy.com +etlong.com +etmoc.com +etmtoy.com +etmwanju.com +etocrm.com +etokzt.site +etolies.com +etomlink.com +eton-tech.com +etonetech.com +etonfood.com +etong.com +etongchem.com +etongguan.com +etonjx.com +etonkidd.com +etonkids.com +etool.cc +etoote.com +etoote.net +etoplive.com +etoprun.com +etoptour.com +etoubao.com +etoujie.com +etovl.org +etowncapital.com +etownestate.com +etpass.com +etpcar.com +etplat.com +etpowers.com +etrack01.com +etrack02.com +etrack03.com +etrack04.com +etrack05.com +etrack07.com +etrack08.com +etradegx.com +etransfar.com +etranshare.com +etrasemi.com +etrd.org +etrol.com +etrump.net +ets100.com +etsc-tech.com +etsingshan.com +etsoon.com +etsstar.com +ett-cn.com +ett.cc +ettabiotech.com +ettbl.org +ettdns.com +ettdns.net +ettdnsv.com +ettdnsv.net +ettinn.com +ettshop.com +etu6.com +etuan.com +etuan123.com +etudu.com +etuogroup.com +etuoyi.com +etuschool.org +etwgzkce.com +etxcs.com +etycx.com +etyy.com +etyyy.com +etz927.com +etzj.net +etzqw.com +etzzy.com +eu4cn.com +eub-inc.com +euci-software.com +eucure.com +eudic.net +euejia.com +euetsp.website +eueui.com +eufc.org +euforums.com +euhhob.com +eui.cc +euibe.com +euino.com +euklass.com +eulike.com +eulixos.com +eumt.com +eur-go.com +eurasia.edu +eurasiacasinolasvegas.com +euratao.com +eureka.name +eurkon.com +euroasia-p.com +eurochinesedaily.com +eurofinscn.com +europapa.com +europe.com.hk +europewatch.com +europewatch.com.hk +eursell.com +eusercenter.com +eushophq.com +eusoftbank.com +euwan.com +euzw.net +ev123.com +ev123.net +ev3ds.com +ev88.com +ev98.com +eva-group.com +eva001.com +evacellbio.com +evan.xin +evancg.com +evanway.net +evask360.com +evcar.com +evcard.com +evcard.vip +evcrrc.com +evdays.com +evdo.vip +eve.moe +evebattery.com +evefashion.com +evening.me +eventown.com +events.pub +eveqbow.xyz +ever9527.com +everbox.net +everbright.com +everbright21.com +everbrightlaw.com +everbrightphotonics.com +evercarecn.com +everdns.com +everdrawing.com +evereasycom.com +everedit.net +everet.org +evergrande.com +evergrandeauto.com +evergrandeservice.com +evergrandespring.com +evergreen-plastics.com +evergreen2012.org +everichgroup.com +everisker.com +everknight.net +everlight-space.com +evernakedcake.com +everpay.org +everrobot.com +eversino.com +everspry.com +everstar.xyz +everstray.com +eversun-chn.com +everybodysuo.com +everychina.com +everydo.com +everyinch.net +everyonejun.com +everyouthtech.com +evestemptation.com +evewan.com +evfchina.com +evget.com +evgezphv.com +evhui.com +evideostb.com +evileyesaint.com +evilleaker.com +evinchina.com +evisa99.com +evisionics.com +evisugo.com +evketang.com +evkworld.net +evlightpro.com +evlook.com +evmam-tbrat.com +evobserver.com +evoc.com +evocqd.com +evotrue.com +evpartner.com +evpowergroup.com +evtcn.com +evtrust.com +evzhidao.com +evznl.org +evzs.com +ew-wirestripping.com +ew80.com +ew80.net +ew80yun.com +ew9z.com +ewaga.com +ewang.com +ewaninfo.com +ewarecomputer.com +ewaterchina.com +ewatt.com +ewceo.com +ewdcloud.com +ewebeditor.net +ewebsoft.com +ewecha.com +ewei.com +eweiqi.com +eweirong.com +eweis.com +ewemt.com +ewen.co +ewenyan.com +ewhnzmqncm7.com +ewidecloud.com +ewidewater.com +ewidewater.net +ewie.net +ewin007.com +ewinshine.com +ewinshocks.com +ewoka.com +ewomail.com +eworksglobal.com +eworldship.com +ewpeinfo.com +ewqcxz.com +ewsaas.com +ewsdxc.com +ewstudy.com +ewt360.com +ewteacher.com +ewtp.com +ewtp.org +ewu.cc +ewuzhen.com +ewzqsyuc.link +ex-energybattery.com +ex-silver.com +ex-starch.com +ex360.com +exact-ic.com +exam100.net +exam58.com +exam76.com +exam8.com +examcoo.com +examda.com +examebook.com +examk.com +exampx.com +examw.com +exands.com +exaphotons.com +exasic.com +exbaotuan.com +exbapp.com +exbot.net +exc-resin.com +exc118.com +excake.com +excalibur.link +excarepharm.com +excbio.com +excean.com +exceedconn.com +excegroup.com +excegroupur.com +excel8.com +excel880.com +excelbbx.net +excelcn.com +excelhome.net +excellbio.com +excellencegroupfoundation.com +excelpharma.com +excelpx.com +excm.net +exd.design +exdoll.com +exedus.com.co +exeedcars.com +exemplifyt.com +exexm.com +exezhanqun.com +exfree.com +exgpykzm.com +exhera.com +exhobby.com +exia.xyz +exiaoba.com +exiliumgf.com +exinee.com +exingbao.com +exiqu.com +exllog.com +exmailgz.com +exmailqq.com +exmay.com +exmetis.com +exmoo.com +exmrw.com +exnpk.com +exntech.com +exo-mk.com +exound.com +exp99.com +expba.com +expdns.net +expec-tech.com +expensiveg.com +expin.site +expingworld.com +expiredns.net +expirenotification.com +expirepausedns.com +expku.com +explinks.com +explorehainan.com +explorexd.com +expo-china.com +expo-nb.com +expocemat.com +expodmc.com +expoeye.net +expohsp.com +expolifestyle.com +exponingbo.com +expoon.com +expoooo.com +expoquan.com +expotu.com +expowindow.com +expozh.com +expressboo.com +expresscompanynetwork.com +expreview.com +exprun.com +expsky.com +exquisite-automotive.com +exscapesmoke.com +exsvc.net +ext2fsd.com +extech-sh.com +exteriorm.com +externalcoop.com +extfans.com +extqq.com +extron-tech.com +extscreen.com +extstars.com +exuanfang.cc +exuanpin.com +exuanshi.com +exuekt.com +exueshi.com +exuezhe.com +exyws.org +ey100.com +ey3g.com +ey99.com +eyacn.com +eyangfan.com +eyangguang.com +eyangzhen.com +eyao168.com +eyaobei.com +eyaodev.xyz +eyar.com +eyasglobal.com +eyasgloble.com +eybond.com +eybook.com +eycfhb.com +eycms.net +eydata.net +eydns.com +eye023.com +eye024.com +eye025.com +eye027.com +eye0510.com +eye0515.com +eye0561.com +eye0712.com +eye0731.com +eye0746.com +eye0770.com +eye0771.com +eye0773.com +eye0774.com +eye0775.com +eye0776.com +eye0777.com +eye0779.com +eyeabc.com +eyee.com +eyeofcloud.com +eyeofcloud.net +eyepetizer.net +eyeplay.org +eyesar.com +eyeshenzhen.com +eyeso.net +eyhsj.com +eyili.com +eyingchuang.com +eyingyubao.com +eyiwu.com +eyoodns.com +eyoogo.com +eyou.com +eyou.net +eyoubaidu.com +eyoucms.com +eyouct.com +eyoumb.com +eyoungindustry.com +eyourbusiness.com +eyouwx.com +eyprint.com +eyspwkg.com +eyuangong.com +eyuconnect.com +eyugame.com +eyunidc.com +eyunzhu.com +eyuyan.com +eyuyan.la +eyuyao.com +eyuzhu.com +eywedu.com +eywedu.net +eywedu.org +eyy168.com +eyy8.vip +eyyyye.com +eyz.ink +eyzeafp.com +ez-leaf.com +ez01.com +ezagoo.com +ezaiai.com +ezca.org +ezchip.tech +ezcname.com +ezcpt.com +ezcun.com +ezdnscenter.com +ezeeship.com +ezeroshop.com +ezfuns.com +ezhangdan.com +ezhangu.com +ezhayan.com +ezhicai.com +ezhijiantuoluo.com +ezhijiao.com +ezhiwan.com +ezhou.com +ezhousetech.com +ezhu.com +ezhun.com +ezhupei.com +ezindie.com +eziot.com +ezjhw.com +ezlippi.com +ezliushao.com +ezloo.com +eznowdns.com +eznowdns.net +ezone-h5.com +ezonsport.com +ezpro.pro +ezreal.cool +ezrent.hk +ezrpro.com +ezshou.com +ezsuperfans.com +eztcn.com +eztest.org +eztvnet.com +ezucoo.com +ezviz.com +ezwan.com +ezwanjia.com +ezwise.com +ezyotkp.com +ezzls.com +ezzxw.com +f-0.cc +f-biology.com +f-dou.com +f-insight.com +f-stack.org +f.biz +f.cx +f008.com +f015dfc4510292.beer +f049443d111032.beer +f0580.com +f0758.com +f08ecb0455f06f18.com +f09qgja1.com +f0f21399311031.beer +f1-shanghai.com +f11w.com +f130.com +f139.com +f14ed7c801022.beer +f1943w.com +f1d28bdd11019.beer +f1zd.com +f24hls-i.akamaihd.net +f26.cc +f2c8017f110281.beer +f2cca7592f8a0441.com +f2time.com +f315.cc +f32365.com +f3322.net +f3322.org +f33eb245b1022.beer +f385e7fcd1013.beer +f397350c0958109e.com +f3bed1ef51013.beer +f3ff28a3e1015.beer +f40ca6aa911042.beer +f419a55f61023.beer +f41g.com +f42cccb808.forum +f442165e29dbca6e.com +f44b9bd1fe4e913f.com +f49f8e0421015.beer +f4a107d7a11012.beer +f4b2ed8f711011.beer +f4e2a302f1016.beer +f52o04oylrbmfw.com +f537.com +f542d8de71022.beer +f5432.com +f54321.com +f54c463ad528b39a.com +f567c912a077aacc.com +f5cs.com +f5ec7553b5ec6ea3.com +f5fa5ff8ef7379ba.com +f5gh.com +f5sd.com +f5yx.com +f61a.com +f61b.com +f66a747451016.beer +f69a662cb11031.beer +f6b06c2d5821c34e.com +f6c62f7ab11031.beer +f6d4a4f461010.beer +f6yc.com +f704204fa11021.beer +f71f38e6a1015.beer +f746c2da252336a6.com +f7777.net +f79ca805111881f6.com +f79f9e5b71019.beer +f7aa9093710281.beer +f7chinavip.com +f7e84829210281.beer +f7yuncdn.com +f800909401015.beer +f8167007e7bf667d.com +f831fb9ce11031.beer +f8e772f41348c086.com +f8fm.com +f92ec0629f52f064.com +f94fa469f5680337.com +f9ee74bf602c79cf.com +f9f4a38021013.beer +fa-part.com +fa-today.com +fa-tojoin.com +fa2da1f5b1024.beer +fa80a608ec3e1ead.com +faadcf6d01009.beer +faakee.com +faanw.com +faayoo.com +fabang.com +fabao365.com +fabaofoundation.com +fabaogou.com +fabiao.com +fabiaoqing.com +fabigbig.com +fablusa.com +fabpo.com +fabu.io +fabu114.com +faburuanwen.com +fabuzhushou.com +facaishu.com +facang.com +facash.com +face-plus-plus.com +face100.net +face2ai.com +faceboer.com +facebookol.com +facebooksx.com +facecloud.net +facedic.com +faceface2.com +facehufu.com +faceid.com +facejoking.com +facephoto.com +faceplusplus.com +facernt.com +faceu.com +faceu.mobi +faceu.net +faceui.com +faceunity.com +fachcloud.com +facri.com +factchina.com +factj.com +factube.com +fad9e7ce5a0de13c.com +fada12888888.work +fadada.com +fadesky.com +fadfunds.com +fadior.cc +fadoudou.com +fadoushi.com +fadsc.com +fadsfasd.asia +fadui.com +faer.work +fafa9.com +fafaku.com +fafawang.com +fafeng.com +fafuli.com +fagaoshi.com +fageka.com +fagua.net +faguowenhua.com +fahai.com +fahuolianmeng.com +faidev.cc +faidns.com +faieduusr.com +faihdusr.com +faimallusr.com +faioo.com +faipod.com +fair-guard.com +fair1688.com +fairguard.net +fairguard.tech +fairhr.com +fairkwa.com +fairplaycloud.com +fairso.com +fairygui.com +fairysen.com +fairysoft.net +fairysoftware.com +fairytest.com +faiscm.com +faisco.com +faisys.com +faiusr.com +faiusrd.com +faiww.com +fajiayun.com +fajihao.com +fakamiao.com +fakamiao.shop +fakeloc.cc +fakeluxurywatches.com +falconnet.app +falconsending.com +falcontalent.com +faloo.com +famascro.com +fameile.net +fameirui.com +famen163.com +famenbaike.com +famens.com +famens.vip +famensi.com +family-marathon.com +familyincloud.com +familykoloro.com +familylifemag.com +familyzuji.com +faminuo.com +famiyou.com +famobiotech.com +famousoffice.com +famoustone.com +famulei.com +fan-lun.com +fan-md.com +fan-tastic.fun +fan-xun.com +fan88.com +fanai.com +fanbook.mobi +fancl-vip.com +fancyecommerce.com +fancygo.xyz +fandcode.com +fandengds.com +fandian.com +fandiankeji.com +fandongxi.com +fane8.com +fanerkongjian.com +fanfannet.com +fanfou.com +fang-te.com +fang-zhou.com +fang.com +fang.xin +fang24k.com +fang33.com +fang668.com +fang91.com +fang99.cc +fang99.com +fangbei.org +fangcang.com +fangcece.com +fangchan.com +fangche.net +fangchengbao.com +fangchengbaoapp.com +fangchengganglvxingshe.com +fangchip.com +fangcloud.com +fangcunshan.xyz +fangda-specialsteels.com +fangda.com +fangdacarbon.com +fangdaijisuanqi.com +fangdaquan.com +fangdd.com +fangdichanceo.com +fangdonggroup.com +fangdr.com +fangdudu.com +fangfa.net +fanggeek.com +fangguan6.com +fanghenet.com +fangheng.com +fanghua120.com +fanghuafu.com +fanghuihui.com +fangjia.com +fangjiadp.com +fangjinsuo.com +fangkeduo.net +fangkewang.com +fangko.com +fangkuai.com +fangkuai.link +fangkuaiwang.com +fangkuaiyi.com +fanglb.com +fangle.com +fangliju.com +fanglimei.com +fanglinad.com +fanglitong.com +fangma.com +fangming.com +fango8.com +fangpaiwang.com +fangqk.com +fangrun.com +fangshanzi.com +fangsheji.com +fangshengaxle.com +fangsi.net +fangstar.com +fangtan007.com +fangtangtv.com +fangte.com +fangtian.net +fangtong.com +fangtx.com +fangwei315.com +fangweima.com +fangwuzaixian.com +fangxfang.com +fangxian.org +fangxiaobao.net +fangxiaoer.com +fangxin.com +fangxinbao.com +fangxinbiao.com +fangxinmai.com +fangxinzhuomian.com +fangxu.work +fangyanzazhi.com +fangyb.com +fangyi.com +fangyiai.com +fangyou.com +fangyouquan.com +fangyouw.com +fangyuan-group.com +fangyuan365.com +fangyuanhp.com +fangyuannew1zycdn.cc +fangyunlin.com +fangzd.com +fangzew.com +fangzhengip.com +fangzhengshufa.com +fangzhenxiu.com +fangzhipeng.com +fangzhouad.com +fangzhoukonggu.com +fangzhoulawyer.com +fangzhouqihang.com +fangzhoushidai.com +fangzhouyanglao.com +fangzongguan.com +fanhai-hk.com +fanhaib.com +fanhaic.com +fanhangame.ltd +fanhaoyue.com +fanhar.com +fanhonghua.net +fanhougame.com +fanhuaholdings.com +fanhuan.com +fanhuan.org +fanhuishou.com +fanin.cc +faniuwenda.com +fanjianhome.com +fanjinyan.com +fanjunyang.zone +fankebang.com +fankhome.com +fankuweb.com +fanli.com +fanli001.net +fanlibei.com +fanlihe.com +fanlihi.com +fanlihotels.com +fanlitou.com +fanlv.fun +fanmeilantian.com +fanmimi.com +fanmingming.com +fanmugua.net +fannaojiputi.com +fanooo.com +fanpaijidian.com +fanpanjidain.com +fanpusoft.com +fanqiang.com +fanqianxs.com +fanqianzhushou.com +fanqie.im +fanqiecopyright.com +fanqiejiang.net +fanqienovel.com +fanqieopen.com +fanqieopenpic.com +fanqieopenstatic.com +fanqieopenvod.com +fanqier.com +fanqiesdk.com +fanqiesdkpic.com +fanqiesdkstatic.com +fanqiesdkvod.com +fanqietianqi.com +fanqievv.com +fanqiewin10.com +fanqiexitong.com +fanquanwang.com +fanruan.com +fanruanclub.com +fanryes.com +fans35.com +fans8.com +fanshicekong.com +fanshigang.com +fanshui.net +fansiji.com +fansimg.com +fansjoy.net +fansobattery.com +fansoon.com +fansx.com +fansyes.com +fantablade.com +fantaiai.com +fantaicdn.net +fantaitech.com +fantanggame.com +fantasticbin.com +fantatech.com +fantawild.com +fante.com +fantibody.com +fantnet.com +fantong.com +fantsida.com +fanttec.com +fantuan.hk +fanuc666.com +fanuchdf.com +fanw8.com +fanwantianyu.com +fanwe.com +fanwen118.com +fanwenbaike.com +fanwenq.com +fanwenzhan.com +fanwubi.org +fanxian.com +fanxiang.com +fanxianw.com +fanxiaojian.com +fanxing.com +fanxingliveshow.com +fanxingshidaitech.com +fanxuefei.com +fany-eda.com +fany-online.com +fanyantao.com +fanyeda.com +fanyedu.com +fanyi.com +fanyi1234.com +fanyiba.net +fanyibase.com +fanyigou.com +fanyigou.net +fanyijia.com +fanyiqi.net +fanyishang.com +fanyitec.com +fanyouvip.com +fanyu.com +fanyu.work +fanyuip.com +fanzehua.com +fanzhidu.com +fanzhiyang.com +fapharm.com +fapiao.com +fapiao365.com +fapiaobang.com +fapselc.com +faq-whtasapp.com +faq-whtasapp.net +faqianjia.com +faqiren.com +far-china.com +far123.com +far800.com +faraconix.com +faradayfuturecn.com +faradynamics.com +fareastcontainers.com +farenhui.com +farennews.com +farerdak.com +farfir.com +farisl.com +farmasino.com +farmkd.com +farmsec.com +farsee2.com +farsightdev.com +farsiightppc.com +fas-bee.com +fasensor.com +fash1043.cloudycdn.services +fashaoyou.net +fashengba.com +fashilawfirm.com +fashionan.com +fashionszshow.com +fashiontrenddigest.com +fashuounion.com +fasionchan.com +fast-eyes.com +fast-heat-cartridge-heaters.com +fast.im +fast666ioceywit93h8a.com +fastadmin.net +fastbuild.run +fastcdn.com +fastchina.net +fastdo.cc +fastener-cn.net +fastener.cc +fastgz.com +fastidea.cc +fastidea.me +fastindexs.com +fastliii.com +fastmirror.net +fastmirror.org +fastmis.com +fastmock.site +fastmovie88.com +fastmyna.com +faston56.com +fastonetech.com +fastoper.com +fastposter.net +fastreportcn.com +fastsdwan.com +fastsilver.press +fastsoc.com +fastsoso.cc +faststatics.com +fastx-ai.com +fat-tail.com +fat999.com +fatangmedia.com +fatbobman.com +fateadm.com +fatedier.com +fateqi.com +fatfreader.com +fatherai.com +fatiao.pro +fatier.com +fatoan.com +fatvg.com +faussefrance.com +faussemontrerolex.com +favang.com +favdeb.com +favopen.com +favoreducation.com +favorites.ren +faw-benteng.com +faw-vw.com +faw.com +fawan.com +faway.com +fawmc.com +fawsoft.com +fawulu.com +fawuzaixian.com +faxdns.com +faxdns.net +faxianjingpin.com +faxianla.com +faxianlaw.com +faxianpindao.com +faxingbao.com +faxingchina.com +faxingcn.com +faxingsj.com +faxingzhan.com +faxiufang.com +faxuan.net +faxy-tech.com +fayfans.com +fayifa.com +fayimen.com +fayiyi.com +fayufaguo.com +fazhijx.com +fazz.fun +fb32dc52302e6b9b.com +fb46cd5483f029aa.com +fb4bc82f71019.beer +fb56.com +fbaichuan.com +fbank.com +fbatop.com +fbf6c93bf10272.beer +fbflex.com +fbjsgf.com +fbkjapp.com +fbku.com +fblife.com +fblsj.com +fbnxb.com +fbook.net +fbpaas.com +fbsjedu.com +fbuy365.com +fbxslw.com +fbyvalve.com +fc-smartglobal.xyz +fc0531.com +fc0633.com +fc224220480630b3.com +fc3e2b88fc5254c9.com +fc571.com +fc62.com +fc811.com +fc858.com +fc92322b910311.beer +fcachinagsdp.com +fcai.com +fcapp.run +fcb16888.com +fcbox.com +fcboxmall.com +fcbs999.com +fcbsgroup.com +fcbu.com +fcc8aa32d10251.beer +fcchbj.com +fccs.com +fccscar.com +fcczp.com +fcd2448c6211c5a6.com +fcdecb0b610261.beer +fcg01.com +fcg0770.com +fcgasj.com +fcgby.com +fcgfcjy.com +fcgfzjy.com +fcggsj.com +fcghbxx.com +fcglib.com +fcgsaps.com +fcgsnews.com +fcgstzjt.com +fcguoan.com +fcgxt.com +fcgzjchy.com +fcgzph.com +fcgzrkq.com +fcgzrzyqxyj.com +fchospital.com +fcjjdbsc.com +fcjjt.com +fcjob.net +fcjob88.com +fcjtaobao.com +fcjuxian.com +fckpw.com +fclassroom.com +fcldaf.com +fcljt.com +fclouddns.net +fcloudpaas.com +fcnes.com +fcnode.net +fcpawn.com +fcpiao.com +fcpowerup.com +fcqjc.com +fcrc114.com +fcs.dell.com +fcs1.com +fcsc.com +fcsccz.com +fcsdzly.xyz +fcseiko.com +fcstor.com +fcsubcn.cc +fcsubcn.pro +fctaiwan.com +fcto.rest +fcvvip.com +fcw0633.com +fcw6.com +fcwei.com +fcwr8.com +fcwyglyxgs.com +fcxxh.org +fcxzb.com +fcz.ink +fcz360.com +fczhongwang.com +fczlpt.com +fczlsc.com +fczst.com +fczx.com +fd-capital.com +fd-trust.com +fd-yy.com +fd-zj.com +fd08a9f9a1016.beer +fdbatt.com +fdc0746.com +fdcjj.org +fdcyun.com +fdczbstatic.com +fdd0cd79c10281.beer +fdeent.org +fdeer.com +fdevops.com +fdf46bd061024.beer +fdfhtl.com +fdfinvoice.com +fdgearbox.com +fdh6up750n.com +fdjskf.com +fdjzu.com +fdkfloor.com +fdkm88.com +fdlbeckwai.com +fdleckwai.com +fdlt.net +fdmhmm.com +fdooo.com +fdqc.com +fdren.com +fdrobot.com +fdtsgs.com +fdttgroup.com +fdx-fund.com +fdxww.com +fdxxjs.com +fdzcxy.com +fdzq.com +fdzyy.com +fdzzjs.com +fe-cable.com +fe15a959f1020.beer +fe232d4b510271.beer +fe2x.cc +fe520.com +fe7f9abcbf8e1dd2.com +feadi.com +feanton.com +feapp.net +featchina.com +febbab1472011af4.com +fecc.cc +fecify.com +fecmall.com +fecn.net +fecshop.com +fedlearner.net +fedte.cc +feeair.com +feeclouds.com +feedcoop.net +feedcoopapi.com +feedsp.com +feeeco.com +feehi.com +feejii.com +feekr.com +feel-bar.com +feelcars.com +feelchat.net +feelec.net +feelnowtrip.com +feelsoar.com +feemoo.com +feemoo.vip +feepan.com +feeprint.com +feesing.com +feeyan.com +feeye.com +feeyo.com +feeyun.com +fefd203.xin +fegine.com +feheadline.com +fehelper.com +fehorizon.com +fei580.com +feiair.com +feiauto.com +feibajiasu.com +feibaokeji.com +feiben-starter.com +feibians.com +feibing.tech +feibisi.com +feibisi.org +feibit.com +feibo.com +feichangrice.com +feichicloud.com +feichong.net +feicool.com +feicui168.com +feicui99.com +feicuishuo.com +feicuiwuyu.com +feida-china.net +feidacrusher.com +feidaep.com +feidagroup.com +feidaoboke.com +feidavalve.com +feidazuanji.com +feidee.com +feidee.net +feidi.com +feidiao.com +feidou.com +feie.work +feierlaiedu.com +feiersmart.com +feifandesign.com +feifanindustry.com +feifantxt.com +feifantxt.net +feifdx.com +feifei.com +feifeiboke.com +feifeishijie.com +feifeixitong.com +feifeiziyuan.com +feifustudio.com +feigang.net +feige.ee +feigeblog.com +feigo.fun +feihe.com +feihe168.com +feiheair.com +feihengip.com +feihongtec.com +feihu.me +feihua.com +feihuadns.com +feihuo.com +feihutaoke.com +feijie.org +feijing88.com +feijipan.com +feijiu.net +feijiuzs.com +feijix.com +feijs.com +feikework.com +feikongbao.com +feiku.com +feikua.net +feiliao.com +feilihua.com +feiliks.com +feiliu.com +feilixi888.com +feilu.cc +feilvway.com +feimalv.com +feimao666.com +feimaoweb.com +feimaoyun.com +feimawaiqin.com +feimayun.com +feimogames.com +feimooo.com +feimosheji.com +feimoustex.net +feinews.com +feiniao.name +feiniaomy.com +feiniaowangluo.com +feiniu.com +feinno.com +feiphp.com +feipin.com +feipin.net +feipinzhan.com +feipr.com +feiq18.com +feirar.com +feiruikeji.com +feisaidi.com +feisan.net +feishu-3rd-party-services.com +feishu-boe.net +feishu-pre.net +feishu.net +feishuapp-cdn.net +feishuapp.com +feishucdn.com +feishudoc.com +feishuhuiyi.com +feishuimg-boe.com +feishuimg-pre.com +feishuimg.com +feishukacdn.com +feishumeetings.com +feishuoffice.com +feishuopenplatformrecord.com +feishupkg.com +feishuvc.com +feishuwx.net +feishuzw.net +feisiplus.com +feistech.com +feisu.com +feisuwx.org +feisuxs.com +feisuzhibo.com +feitaomall.com +feitengsoft.com +feitent.com +feitianwu7.com +feitsui.com +feituo126.com +feiwan.net +feiwentianxia.com +feixian.cc +feixiansoft.com +feixiaoqiu.com +feixiong.tv +feixue666.com +feixuege.com +feixueteam.net +feiyang.com +feiyang.hk +feiyang233.club +feiyang971.com +feiyangholiday.com +feiyangjm.com +feiyangstar.com +feiyiblog.com +feiyin2016.com +feiying-china.com +feiyit.com +feiyouyun.com +feiyu.com +feiyuapi.com +feiyue.online +feiyueconglin.com +feiyuhu.com +feiyun.cc +feiyunjs.com +feiyuteam.com +feizan.com +feizhaojun.com +feizhiyi.com +feizhu.com +feizhuke.com +feizhupan.com +feizhuqwq.com +feizutrip.com +feizw.net +felicitysolar.com +feling.net +felink.com +felix021.com +felizpg.com +felmvip.com +felo-ev.com +femrice.com +fen360.com +fenbaner.net +fenbei.com +fenbeijinfu.com +fenbeitong.com +fenbi.com +fenbike.com +fenbilantian.com +fenbu.net +fenby.com +fencescn.com +fenchuan8.com +fenda.com +fendytech.com +fenfen.com +fenfenriji.com +fenfentang.com +fenfenwz.com +fenfenyu.com +fenfenzh.cc +feng-du.com +feng.com +feng.pub +feng1.com +fengakj.com +fengaomedical.com +fengba888.com +fengbangleasing.com +fengbao.com +fengbaowo.com +fengbohan.com +fengbolive.com +fengcaijiaju.com +fengchaoyuan.com +fengche.us +fengchengroup.com +fengchizixun.com +fengchuanba.com +fengchui.cc +fengchusheng.com +fengcms.com +fengcx.com +fengdu.com +fengdu365.com +fengdufrp.com +fengduqi.com +fengduxiaoshuo.com +fengedu.com +fengeek.com +fengei.com +fengeini.com +fengex.com +fengfeng.cc +fenggangzulin.com +fenggongliangrenju.com +fenggouhui.com +fenggui-baking.com +fenghaibin.com +fenghenever.com +fenghong.tech +fenghua001.com +fenghuangcanyin.com +fenghuangxs.com +fenghui-motor.com +fenghuidongman.com +fenghuo.cc +fenghuoyunji.com +fengimg.com +fengj.com +fengji.net +fengjiawang.net +fengjierc.com +fengjing.com +fengjinggroup.com +fengjinketang.com +fengjr.com +fengjx.com +fengkeji.com +fengkongbao.com +fengkuangzaoren.com +fengkui.net +fenglao.org +fengli.com +fengli.su +fengliankeji.com +fenglichem.com +fenglingroup.com +fenglinjiu.com +fenglinlab.com +fenglu-alu.com +fengmaniu.com +fengmap.com +fengmeng.net +fengmios.com +fengnayun.com +fengniao.com +fengniaohd.com +fengniaojianzhan.com +fengone.com +fengpintech.com +fengread.com +fengse.com +fengshangroup.com +fengshangweekly.com +fengshankeji.com +fengshi8888.com +fengshigroup.com +fengsung.com +fengsutb.com +fengtai.tv +fengtalk.com +fengtao365.com +fengtaochanglai.com +fengtianz.com +fengtingsmart.com +fengtupic.com +fengwanyx.com +fengwatch.com +fengwenyi.com +fengwo.com +fengwohao.com +fengxb.com +fengxian110.com +fengxianrc.com +fengxianwater.com +fengxiaotx.com +fengxing007.com +fengxinglihua.com +fengxuan.co +fengyan.cc +fengyang.fun +fengyeholding.com +fengyitong.name +fengyuangufen.com +fengyuncad.com +fengyuncx.com +fengyunlu.com +fengyunmusic.net +fengyunpdf.com +fengyushan.com +fengzegroup.com +fengzhan.vip +fengzhangame.net +fengzhao.net +fengzigame.com +fengzusw.com +fenha.net +fenhong123.com +fenhuo360.com +fenixmall.com +fenjiji.net +fenjj.com +fenke.com +fenking.club +fenlei168.com +fenlei265.com +fenleidao.com +fenleihu.com +fenlekeji.com +fenliu.net +fenmitech.com +fennessy.hk +fenqile.com +fenqix.com +fenqubiao.com +fens.me +fensaas.com +fensebook.com +fenshua123.com +fensishenghuo.com +fenssy.com +fentorsolar.com +fenxi.cc +fenxi.com +fenxi.org +fenxiangdashi.com +fenxianglife.com +fenxiti.com +fenxm.com +fenxmi.com +fenxuekeji.com +fenyu.net +fenyucn.com +fenzhi.com +fenzhi.net +fenzijr.com +feotech.com +fequan.com +ferlie.net +ferlytc.com +fermatmind.com +ferqwo.sbs +ferro-alloys.com +fescoadecco.com +fescoadeccochongqing.com +fescoadeccozhejiang.com +fescogroup.com +fescoguangdong.com +fescojinan.com +feso.tech +festaint.com +fetion-portal.com +fetiononline.com +fetionpic.com +fettesgz.com +feucnp.com +feverales.com +feverassets.net +fevermi.com +fevia.work +fevte.com +feydj.com +feyer-tc.com +ff14.cloud +ff54.ink +ff63.com +ff722fbac1011.beer +ffalcon.com +ffan.com +ffasp.com +ffb199e9266142c6.com +ffbc6bb121021.beer +ffbc82f8d1013.beer +ffbook.cc +ffbuddy.com +ffc540c0611031.beer +ffca028de10292.beer +ffcell.com +ffcloudcdn.com +ffdbj.com +ffe06ebc91024.beer +ffe0be9f91019.beer +ffeeii.com +ffepower.com +fffont.com +ffhome.com +ffis.me +ffj.cc +ffls-edu.com +ffmomola.com +ffnmu.com +ffpedia.com +ffpw1688.com +ffquan.com +ffreeslott.com +ffsgame.com +ffsky.com +fftcc.com +fftub.com +ffxivhuntcn.com +ffy.com +ffzww.com +fg.cc +fg114.com +fgba.net +fgcndigital.com +fgeekcloud.com +fgfed.com +fggyw.com +fghi34.com +fgidna.com +fgkj.cc +fglt.net +fgnwct.com +fgo.wiki +fgowiki.com +fgq.net +fgtxnews.com +fgvisa.net +fh01.com +fh1551.com +fh21.com +fh21static.com +fh77.net +fh86.com +fh888.com +fhaircut.com +fhb971.com +fhclm.com +fhcomp.com +fhd001.com +fheb-four.com +fheb-six.com +fhfxys.com +fhgame.com +fhgjds.com +fhguotai.com +fhl05161ps.com +fhldns.com +fhldns.net +fhlmotor.com +fhlun.com +fhmion.com +fhmooc.com +fhmv.com +fhonest.com +fhoverseas.com +fhrlw.com +fhsfilm.com +fht360.com +fhtao.com +fhtj.com +fhtlw.com +fhtre.com +fhvalley.com +fhwlgs.com +fhwzx.com +fhycedu.com +fhycs.com +fhyl56.net +fhyx.com +fhyx.hk +fhzggame.com +fhzl.co +fi-play.com +fi0.cc +fi11.com +fi7.cc +fi94.com +fia-china.com +fibercrops.com +fiberglasschina.com +fiberhome.com +fiberhomegroup.com +fibocom.com +fibodata.com +fibrlink.net +ficochina.net +ficowshen.com +fiehff.com +fieldcommunicator.net +fifa666.com +fifaschool.com +fifedu.com +fifsky.com +figure-it.com +fiifh.com +fiil.com +fiinote.com +fiio.com +fiio.net +filcochina.com +file.hhtv.cc +file.mb.leshantv.net +filediag.com +filez.com +filfox.info +fillersmart.com +fillseo.com +film-yuelongchina.com +filteringlist.com +fily.fun +fim34s.com +fimky.com +fimmu.com +fin-shine.com +finaleden.com +finaltheory.me +finance365.com +financetcloud.com +financeun.com +financialdatamining.com +financialstreetforum.com +finchina.com +finclip.com +finddanandlaura.com +finderweb.net +findhro.com +findic.com +findic.kr +findic.tw +findic.us +findlawimg.com +findlinked.com +findmyfun.xyz +findmyrepair.com +findoout.com +findshu.net +findxk.com +findxz.com +findyou.xin +findzd.com +finebey.com +finebi.com +fineex.com +fineforming.com +fineheads.com +fineidc.com +fineimmu.com +finelybook.com +finer2.com +finereport.com +finereporthelp.com +fineset.com +finesilver.store +finetooling.com +fineui.com +finewatchcare.com +fineway.com +finewyx.com +fineyoga.com +finezb.com +fingard.com +finger-cnc.com +fingerflyapp.com +fingerjoys.com +fingerstylechina.com +fingertc.com +fingu.com +fingu.net +finjetchemical.com +finndy.com +finogeeks.com +finovo.com +finshell-cib.com +fintechinchina.com +fintechquan.com +finupfriends.com +finupgroup.com +finzfin.com +finzjr.com +fiocco-group.com +fir.im +fir.vip +firadio.net +fire233.com +fire2333.com +fire24h.com +firebase-settings.crashlytics.com +firebirdprint.com +firebit.com +firedata119.com +fireemblem.net +fireemulator.com +fireflyacg.com +firegz.com +firerock.tech +firetry.com +firevale.com +firhq.com +firm-lithium.com +first-panel.com +first-swg.com +firstarpc.com +firstdrs.com +firstfood-cn.com +firstlinkapp.com +firstmetcs.net +firstonesource.com +firstp2p.com +firstproduction.net +firstpvm.com +firsunbioscience.com +firwinds.site +fiscan007.com +fisdhu.com +fish2bird.com +fish3000.com +fishcn.com +fisherac.com +fisherv.com +fishfay.com +fishfd.com +fishflying.net +fishin2boat.com +fishing-sh.com +fishing-sinkers.com +fishingjoy.com +fishingmarkets.com +fishings.biz +fishlee.net +fishmobi.com +fishqc.org +fishros.com +fishs.com +fishtui.com +fishwantg.com +fishyoung.com +fit-start.co +fit120.net +fit2cloud.com +fitgroup.com +fitit100.com +fitoneapp.com +fittentech.com +fittingcn.com +fiu07021kl.com +fiu07040kl.com +fiui.org +fivecakes.com +fivedo.net +fiveplus.com +fivestarsolar.com +fivision-tech.com +fix666.com +fixdown.com +fixhdd.org +fixmath.com +fiyta.com +fj-atfz.com +fj-ba.com +fj-cc.com +fj-eprint.com +fj-jima.com +fj-kn.com +fj10010.com +fj133165.com +fj173.net +fj2000.com +fj3c.net +fj888.com +fj96336.com +fj987.com +fjbcjt.com +fjbdex.com +fjber.com +fjbgwl.com +fjbiopharma.com +fjbk.org +fjbyjs.com +fjc001.com +fjce.com +fjcee.com +fjcgxc.com +fjcid.com +fjcoop.com +fjcqjy.com +fjcredit.com +fjctw.net +fjctyz.net +fjcyl.com +fjcyl.org +fjdaily.com +fjdaze.com +fjdc.xyz +fjdf.vip +fjdfxy.com +fjdh.com +fjdkjt.com +fjdygljt.com +fjdzmy.com +fjeca.com +fjejjt.com +fjepn.com +fjetc.com +fjeverone.com +fjfgroup.com +fjfhsteel.com +fjfoxiang.com +fjfs.net +fjfxjt.com +fjfzsx.com +fjgczjxh.com +fjgdwl.com +fjgkedu.com +fjgsgl.com +fjgtfood.com +fjguanyue.com +fjgwy.org +fjhaizu.com +fjhcw.com +fjhospital.com +fjhps.com +fjhrjt.com +fjhsjg.com +fjhssy.com +fjhuayagroup.com +fjhxbank.com +fjhxcaee.com +fjhxvc.com +fjii.com +fjjcjy.com +fjjcled.com +fjjgn396.com +fjjianxin.com +fjjmylbx.com +fjjnsn.com +fjjoyz.com +fjjsp01.com +fjjszg.com +fjjyt.net +fjjyxy.com +fjjzjt.com +fjkdxh.com +fjkqyy.com +fjlawyers.net +fjlb.com +fjlcjs.com +fjlcjt.com +fjleixin.com +fjlg.com +fjlh.com +fjlib.net +fjllsn.com +fjlstz.net +fjlszbc.com +fjly.com +fjlygroup.com +fjlyrmyy.com +fjlyzls.com +fjlzy.com +fjm.info +fjmap.net +fjmego.com +fjmh.com +fjmlh.com +fjmotor.net +fjmstc.com +fjmzw.com +fjndqx.com +fjndwb.com +fjnet.com +fjnhjt.com +fjotic.com +fjpca.com +fjpcz.com +fjpicc.com +fjpit.com +fjpta.com +fjptdy.com +fjptyz.com +fjptzs.com +fjptzx.com +fjptzyt.com +fjqfkg.com +fjqjsw.com +fjrclh.com +fjrcw.com +fjrmyy.com +fjrtv.net +fjsafxh.com +fjsalt.com +fjsanheng.com +fjsdn.com +fjsdsrmyy.com +fjsdxy.com +fjsdzj.com +fjsen.com +fjsenda.com +fjsfa.org +fjsfjyl.com +fjsfy.com +fjshgx.com +fjshjy.net +fjsj.com +fjsjkyy.com +fjsmjj.com +fjssjt.com +fjstfc.com +fjstjt.com +fjstmgcjzhyxh.com +fjsxqy.com +fjsxyqygl.com +fjsyyhyxh.com +fjszx.com +fjtd-logistics.com +fjtelecom.com +fjtianya.com +fjtp.net +fjtv.net +fjtzlt.com +fjvs.org +fjwanan.com +fjwjgs.com +fjwr.xyz +fjwxj.com +fjwzjt.com +fjxfgroup.com +fjxhfx.com +fjxhyw.com +fjxhyy.com +fjxiehe.com +fjxn.com +fjxsxx.com +fjxwx.com +fjxxal.com +fjybyjjysos.com +fjyc8.com +fjycw.com +fjydnews.com +fjyfjsjt.com +fjyklc.com +fjyunba.com +fjyxdm.com +fjyxgl.com +fjyy.org +fjyyjt.com +fjzbgf.com +fjzikao.net +fjzixun.com +fjzol.com +fjzx.org +fjzyxx.com +fjzzct.com +fk100.com +fkask.net +fkblog.org +fkbuff.com +fkcaijing.com +fkdex.com +fkdmg.com +fkdxg.com +fkeduwxxcx.com +fkgou.com +fkguolu.com +fkhdactive.com +fkhdview.com +fkhongdan.com +fklhb.com +fklngy.com +fktool.com +fkw.com +fkw100.com +fkwapi.com +fkwatchtw.com +fkwvya4035.vip +fkyuer.com +fkyun.com +fkyxt.com +fl-game.net +fl0632.com +fl160.com +fl168.com +fl365.com +fl5.co +fl580.com +flacc.com +flagchem.com +flairmicro.com +flamecdn.com +flamesky.org +flamingcold.com +flan1688.com +flaredup.com +flash8.net +flash8f.com +flashcat.cloud +flashgame163.com +flashgene.com +flashkrypton.com +flashmemoryworld.com +flashsalesfb.store +flashv8.com +flashwar.com +flashwolfcn.com +flashxsport.com +flaskflock.com +flatsh.com +flawcache.com +flclb.com +flduo.com +fle078.com +flebm.com +fleeper.com +fleetlogd.com +fleety.com +flexifont.com +fleyun.com +flfc5999.com +flgame.net +flhimalayandn.com +fliggy.com +fliggy.hk +flightroutes24.com +flikfill.com +flintech.org +flintos.com +flip.fun +fliplus.com +flleasing.com +flmgr.net +flml.cc +floatcamellia.com +floatingislandapps.com +floatmaze.com +flockypet.com +flomoapp.com +floorb2b.com +flora009.work +florentiavillage.com +flourish-fs.com +flowchemchina.com +flower188.com +flower33.com +flowerknows.co +flowever.net +flowinnglobal.com +flowlbkj.com +flowportal.com +flowtechgd.com +flowtechsh.com +flpsz.com +flpwb.com +flqrmyy.com +flrcw.com +fltau.com +fltcsb.com +fltrp.com +fluke-ig.com +flumatic.com +flutterchina.club +flvcd.com +flvlog.com +flvpw.com +flvsp.com +flvurl.net +flwatertech.com +flxc.net +flxdns.com +flxzz.com +fly-exp.com +fly139.com +fly160.com +fly1999.com +fly2lan.cc +fly3949.com +fly63.com +fly84.com +fly998.com +flyadx.com +flyai.com +flyancctv.com +flycc.net +flyco.com +flycua.com +flydigi.com +flyenglish.com +flyert.com +flyertea.com +flyertrip.com +flyfishx.com +flyfunny.com +flygo.net +flygon.net +flyhand.com +flyingeffect.com +flyingpigeon1936.com +flyme.com +flyme.net +flymeauto.com +flymeos.com +flymeyun.com +flyml.net +flymobi.biz +flymodem.net +flymopaper.com +flyneutron.com +flysand.com +flysheeep.com +flytcloud.com +flytexpress.com +flzc.com +flzhan.com +fm-uivs.com +fm058.com +fm0754.com +fm0758.com +fm086.com +fm120.com +fm365.com +fm3838.com +fm4399.com +fm520.com +fm875.com +fm901.cityfm.tw +fm918.net +fm929.cityfm.tw +fm960.net +fm971.cityfm.tw +fm983.cityfm.tw +fmbimg.com +fmc123.com +fmcoprc.gov.mo +fmd360.com +fmetro.net +fmi33.com +fminers.com +fmjmm.com +fmkefu.com +fmkpharm.com +fmmob.com +fmscm.com +fmsdlb.com +fmsh.com +fmssrc.com +fmswift.net +fmtmed.com +fmtt6.xyz +fmwei.com +fmwhahaha.com +fmy90.com +fmyunlv.com +fn-mart.com +fn-tech.com +fn010.com +fnconn.com +fnedge.net +fnetlink.com +fnf-foods.com +fnfcutlery.com +fnhealth.com +fnji.com +fnji.net +fnjiasu.com +fnjs.cc +fnjsq.com +fnkq.com +fnkslift.com +fnkvision.com +fnlvshi.com +fnmobi.com +fnnas.com +fnnas.net +fnnsh.com +fnnspa.com +fnos.net +fnrcw.com +fnrczp.com +fnsbqvz.com +fnscore.com +fnwlzz.com +fnxzyy.com +fnyes.com +fnysb.com +fob123.com +fob580.com +fobaoyou.com +fobbusinessforum.com +fobcentury.com +fobmy.com +fobshanghai.com +focaj.com +focalbrand.com +focalhot.com +focc.cc +fochot.com +focigc.com +focobio.com +focofish.com +foctek.com +focus-efc.com +focus-eloan.com +focus-fusion.com +focuschina.com +focusight.net +focussend.com +focustock.com +fodaba.com +fodexin.com +fodian.net +fodizi.com +fodizi.net +fodlab.com +fodonline.com +fofa.info +fofa.so +fofcn.tech +fofen.com +fofstudio.net +fofuai.com +fogcloud.io +foguanghui.org +fohohr.com +foidn.com +foisongroup.com +fojiaonet.com +fojiaoyongpin.com +fokstone.com +foldur.com +folidaymall.com +folij9nry5cxy8.com +followintg.com +followsteel.com +folou.com +fondcosplay.com +foneplatform.com +fonian.com +fonsview.com +font.im +font6.com +fontgoods.com +fontke.com +fontong.com +fontoohotels.com +fontowns.com +fontsfile.com +fontshow.com +fontvip.com +fontyi.com +fonye.com +foodaily.com +foodbk.com +foodciexpo.com +foodex360.com +foodjx.com +foodkz.com +foodmate.net +foodqs.com +foods1.com +foodsc.net +foodspace.net +foodspjm.com +foodszs.com +foodu14.com +foofish.net +fooher.com +foojoo.com +fookunion.com +fookwood.com +fookyik.com +fooleap.org +foomx.com +foooooot.com +foosheng.com +football8888.store +footballdown.com +footbig.com +footgamer.com +footseen.com +foovoo.com +fooww.com +foqian.com +for-she.com +for512.com +for68.com +forbeschina.com +forbetty.com +forbuyers.com +forceclouds.com +forcecreat.com +forcemz.net +forcger.com +forcloudcdn.com +ford.com +fordgo.com +forecam.com +foreignapi.com +foreignserver.com +foremostgroup.com +forenose.com +forerunnercollege.com +foreseahealth.com +foresealife.com +foreseamall.com +foresightfund.com +foresl.com +forestfood.com +forestmusicnanjing.com +forestpolice.net +forestpolice.org +forevernine.com +foreveross.com +foreweld.com +forface3d.com +forgame.com +forindata.com +forkeji.com +forkliftnet.com +forlinx.com +form-create.com +formeasy.cc +formeneed.com +formessengers.com +formingcn.com +formssi.com +formtalk.net +fornass.com +fornature.com +forrealbio.com +forrelaxing.com +forshine.net +forsol.net +forsou.com +forthxu.com +fortiortech.com +fortrustpower.com +fortunatelyt.com +fortune-co.com +fortunebs.net +fortunehair.com +fortunepdc.com +fortunevc.com +forwardgroup.com +forwe.store +forwell-parking.com +foryone.com +foryou56.com +foryouge.com +foryougroup.com +forys-at.com +fos.cc +foscam.com +foshanaosibo.com +foshanmuseum.com +foshannews.com +foshannews.net +foshanplus.com +foshanpower.com +foshion.com +fosss.org +fosstea.com +fosun-uhi.com +fosun.com +fosunhealth.com +fosunholiday.com +fosunmetal.com +fosunpharma.com +fosunwanbang.com +fotile.com +fotileglobal.com +fotilestyle.com +fotomore.com +fotoplace.cc +fotosay.com +fototuan.com +foturn.com +fou.net +foumobile.com +founder.com +founder.net +founderaipu.com +founderbn.com +founderchip.com +foundereagle.com +founderff.com +founderfu.com +founderic.com +founderinternational.com +founderit.com +founderpcb.com +founderpod.com +foundersc.com +foundertech.com +foundertype.com +founpad.com +four-faith.com +fourco-inc.com +fourfaithwater.com +fovmy.com +fow.ink +fowep.com +fox-studio.net +fox008.com +foxconn.com +foxconnmall.com +foxera.com +foxirj.com +foxmail.com +foxphp.com +foxqq.com +foxtable.com +foxuc.com +foxugame.com +foxwaf.com +foxwho.com +foxwq.com +foxzld.com +foyuan.net +fozhidaoxs.cc +fozl.sg +fpaixfl.com +fpc-nb.com +fpccn.com +fpcn.net +fpdclub.net +fpdisplay.com +fpdvision.com +fpe-china.com +fpg.com.tw +fpga-china.com +fpgabbs.com +fpgakey.com +fpgaw.com +fphis.com +fphs.cc +fphs5.com +fpi-inc.com +fpliu.com +fpoll.net +fpsace.com +fpsjk.com +fpstt.com +fpwap.com +fpxz.net +fpyy120.com +fq688.com +fqapps.com +fqbnbg1311.vip +fqfilm.com +fqghj.net +fqgyljt.com +fqhospital.com +fqis.xin +fqjob.net +fqlook.com +fqnovel-op.com +fqnovel.com +fqnovelim.com +fqnovelop.com +fqnovelpic.com +fqnovelstatic.com +fqnovelvod.com +fqpai.com +fqrsw.com +fquwcs3089.vip +fqvpc.online +fqworld.org +fqxdw.com +fqxs.org +fqxsw.cc +fr-trading.com +fr0528.art +fr2007.com +fractal-technology.com +fraeco.com +fraee.com +fragpunk.com +fragrance.ink +frainfo.com +framemaker.com +franceqz.com +francissoung.com +franckfw.com +francochinois.com +frankenman.group +frankyrobot.com +franzsandner.com +fraproperty.com +frcisforce.com +frdic.com +fread.com +fredamd.com +fredestiny.com +free-863.com +free-api.com +free-coin.org +free-doctor.com +free-e.net +free-img.com +free9.net +freebuf.com +freebz.net +freecomm.net +freedgo.com +freedirlist.com +freedomscm.com +freedoonline.com +freegeeker.com +freehpcg.com +freeidea.win +freejishu.com +freekaobo.com +freekaoyan.com +freelycode.com +freelynb.com +freelynet.cloud +freelynet.com +freemancn.com +freemindworld.com +freemoban.com +freemudgame.com +freemypay.com +freeoa.net +freeovp.com +freeqingnovel.com +freeshoppingchina.com +freessl.org +freestman.com +freestyle666.com +freetech.com.hk +freetiku.com +freeuid.com +freevm.com +freewhale.net +freeydch.com +freeyun.com +freezhw.com +freezl.net +frefloya.com +frensworkz.com +freqchina.com +fresh-ideas.cc +freshfresh.com +freshhema.com +freshippo.com +freshippomarket.com +freshiz.xyz +freshnewsnet.com +freshtrgetgendyalert.xyz +frgsupps.store +frhelper.com +friendeye.com +friends-exchange.com +friends8.com +friendship-match.com +frigate-cn.video +fright-tattoo.com +frigidpine.com +fringe-zero.com +frisobaby.com +fristweb.org +frlawyer.com +frler.com +frodzo.club +froglesson.com +frombyte.com +fromgeek.com +fromshandong.com +fromwiz.com +frontierbiotech.com +frontjs.com +frontopbd.com +frontpharm.com +frontstreetcoffee.com +frontwize.com +frost-s.com +frostchina.com +frostwell.cc +frostwell.net +frostwing98.com +frp-act.com +frp-air.com +frp-all.com +frp-any.com +frp-arm.com +frp-bag.com +frp-bar.com +frp-bid.com +frp-box.com +frp-boy.com +frp-bus.com +frp-china.net +frp-dad.com +frp-dog.com +frp-egg.com +frp-end.com +frp-era.com +frp-fan.com +frp-fee.com +frp-fog.com +frp-fox.com +frp-fun.com +frp-gap.com +frp-gas.com +frp-gym.com +frp-hat.com +frp-hen.com +frp-hip.com +frp-hub.com +frp-ice.com +frp-jar.com +frp-key.com +frp-kit.com +frp-lab.com +frp-leg.com +frp-mad.com +frp-mix.com +frp-mom.com +frp-net.com +frp-now.com +frp-nut.com +frp-off.com +frp-oil.com +frp-one.com +frp-own.com +frp-pen.com +frp-put.com +frp-rib.com +frp-rug.com +frp-run.com +frp-say.com +frp-sea.com +frp-shy.com +frp-six.com +frp-ski.com +frp-sun.com +frp-tag.com +frpapp.com +frt.ltd +frtgraphite.com +fruitday.com +frysb.com +frytea.com +frzmh.com +fs-ade.com +fs-bus.com +fs-czx.com +fs-eliza.com +fs-qiyun.com +fs-yld.net +fs.microsoft.com +fs0757.com +fs121.com +fs1982.com +fs31.com +fs58.com +fs7000.com +fsabwy.com +fsaii.com +fsbankonline.com +fsbldjd.com +fsbqgd.com +fsccjy.com +fsccyy.com +fschems.com +fschico.com +fscinda.com +fscjfm.com +fscjkj.net +fscm.tech +fscmjt.com +fscsps.com +fsdxzhpt.com +fsecity.com +fseig.com +fseport.com +fsesa.com +fsfsfz.com +fsfund.com +fsfy.com +fsgas.com +fsgbly.com +fsgcw.com +fsgechao.com +fsggb.com +fsgplus.com +fsgzhg.com +fshczf.com +fshd.com +fshh1688.com +fshj118.com +fshones.com +fshpharm.com +fshsfl.com +fshsl.com +fshuiren.com +fshyschool.net +fshzg.com +fsigc.com +fsight.ai +fsightai.com +fsilon.com +fsjgchina.com +fsjgw.com +fsjinlan.com +fsjinma.com +fsjoy.com +fsjrl.com +fsjsdtc.com +fsjx.org +fsjy.net +fsky.pro +fskzpw.com +fslgz.com +fslinker.com +fsllq.com +fslsg.com +fsltsmhjq.com +fslyx.com +fsmama.com +fsmcled.com +fsmeeting.com +fsmi818.com +fsoet.com +fsohu.com +fsoptronics.com +fsou.com +fspage.com +fspcdn.com +fspinqiu.com +fspits.com +fspride.com +fspt.net +fspublic.com +fsruibin.com +fssdbjyy.com +fssdlhyxh.com +fsspc.com +fssptjj.com +fsstone.com +fsswsxh.com +fst-pipe.net +fstaoci.com +fstcb.com +fstgs.com +fsthr.com +fstrhb.com +fstvgo.com +fsukj.com +fswater.com +fswateraso.net +fswchina.com +fswk.com +fsxchina.com +fsxinquan.com +fsxsj.net +fsxzygz.com +fsy6.com +fsyanhe.com +fsygroup.com +fsyhlz.com +fsylr.com +fsyq.net +fsysyy.com +fsytss.com +fsyule.net +fsyuncai.com +fsyxg.com +fsyy.net +fsyyy.com +fszhihuiyan.com +fszhiko.com +fszyjx.com +ft.tech +ft12.com +ft22.com +ft98.com +fta.dell.com +ftaapj.dell.com +ftaemea.dell.com +ftaro.com +ftasitapj.dell.com +ftbj.net +ftcoaster.com +ftcwifi.com +ftd.nz +ftdevice.com +ftesop.com +ftfast.com +ftfund.com +ftfx.ink +fthformal.com +fthgz.com +fthimalayandb.com +ftium4.com +ftlcloud.com +ftls.xyz +ftlzghz.com +ftmespro.com +ftnwater.com +ftoc.com +ftourcn.com +ftp.pet +ftsafe.com +ftsfund.com +ftswcc.com +fttrs.com +ftuan.com +ftwafer.com +ftxad.com +ftxft.com +ftxgame.com +ftxia.com +ftxsoccer.com +ftylw.com +ftzbq.com +ftzn.net +ftzx.com +fu-guan.com +fu-rui.com +fu2zu.com +fu57.com +fu62.vip +fuanna.com +fubabafumama.com +fubangauctions.com +fubaochem.com +fubaofei.com +fubonchina.com +fubonplastic.com +fuca-china.com +fucantec.com +fuchaipower.com +fuchaoqun.com +fuchen33.com +fuchengshicai.com +fuchuangyu.com +fucol.club +fuczx.com +fuda.com +fuda120.com +fudaguangzhou.com +fudahospital.com +fudaiapp.com +fudajishu.com +fudajn.com +fudakang.com +fudancell.com +fudanglp.com +fudanmed.com +fudanpress.com +fudasafe.com +fudayiyao.com +fudian-bank.com +fudongdong.com +fudu167.com +fudubao.com +fuduwang.com +fuduxiao.com +fuduxuexiao.com +fuedf.org +fuel-lab.com +fuelcellchina.com +fuermu.com +fufeng-group.com +fufuidc.com +fufuok.com +fugary.com +fuguangchina.com +fuguangwater.com +fuguantang.com +fuhai360.com +fuhancapital.com +fuhanziben.com +fuhaoku.com +fuhefu.com +fuheng.org +fuhouyin.com +fuhuibao.club +fui.im +fuiou.com +fuioupay.com +fujfu.com +fujiabin.com +fujianbenz.com +fujiangames.com +fujianguofu.com +fujianmei.com +fujianrc.com +fujiansme.com +fujianyinruan.com +fujinguo.com +fujinjiazheng.com +fujinotrade.com +fujutec.com +fuka.cc +fukangjixie.com +fukangqipai.com +fukangyuanyanglao.com +fuke39.com +fukexie.com +fulanka.com +fulantv.com +fulengen.com +fuliansheng.com +fuliao.com +fuliaotech.com +fuliba.com +fulicat.com +fulimin.org +fulin.org +fuling.com +fulinpm.com +fulinsujiao.com +fulinxiuxian.com +fuliquan.com +fulishemusic.com +fulitec.com +fuliti.com +fuliw.net +full-way.com +fullcopecb.icu +fullde.com +fullhan.com +fullics.com +fulllinks.com +fullluckcalendar.com +fullsemitech.com +fullstack.love +fulltech.work +fulltruckalliance.com +fulou.life +fultree.com +fulu.com +fulykong.com +fuma-carbide.com +fumake.com +fumaofawu.com +fumi.com +fumiaoyinpin.com +fumin.com +fumu.com +fumubang.com +fumuhui.com +fun.tv +fun2ex.com +fun4go.com +funcdn.com +funcrea.com +functionads.com +functionaltextilesshanghai.com +functorz.com +fund001.com +fundebug.com +fundebug.net +fundegroup.com +fundog.cc +fundrive.com +fundxy.com +funenc.com +funengscm.com +funeralchain.com +funfungolf.com +fungichina.com +fungj.com +funhillmedia.com +funhillrm.com +funi.com +funi365.com +funik.com +funiutang.net +funjsq.com +funkoonlinegb.club +funletu.com +funliving.com +funmz.com +funnet.net +funnycore.com +funnycorelive.com +funnyplaying.com +funnysphere.com +funpaer.com +funplay66.com +funqipai.com +funsens.com +funshareamusement.com +funshion.com +funshion.net +funshion.tv +funshipin.com +funtaoyuan.com +funtouchos.com +funtoygame.com +funvba.com +funwear.com +funxun.com +funyard-hotels.com +funzm.com +fupanwang.com +fupin832.com +furagon.com +furama-beihai.com +furderdriving.com +furenchina.com +furenkeji.com +furielec.com +furongedu.com +furrychina.com +furuijiaju.vip +furuise.com +fusaide.com +fusheng-group.com +fushengal.com +fushibao.com +fushite.com +fusiling.com +fusion-inte.com +fusion.design +fusionappl.com +fusure.com +fusureum.com +futa.eu +futaike.net +futang.org +fute.com +futianlvshi.com +futongquartz.com +futu5.com +futuau.com +futuesop.com +futufin.com +futuhn.com +futuniuniu.com +futunn.com +future-sh.com +futureengineer.org +futurejuzhen.vip +futurenetlab.com +futureprize.org +futurescontest.com +futustatic.com +fututrade.com +fututrustee.com +fuwa.org +fuwahgroup.com +fuwai.com +fuwaliuxue.com +fuwei.com +fuweifilms.com +fuweivision.com +fuweiwang.com +fuweizn.com +fuwit.com +fuwj.com +fuwo.com +fuwu7.com +fuwuce.com +fuwucms.com +fuwuqinet.com +fuwuqu.com +fuxila.com +fuxinbank.com +fuxinews.com +fuxinghf.com +fuxingtech.com +fuxingwang.com +fuxuanji-jp.com +fuxunpay.com +fuyang.com +fuyang.net +fuyangbio.com +fuyangjituan.com +fuyangren.org +fuyangtv.com +fuyaogroup.com +fuyaozb.com +fuyaozhubao.com +fuyingdai.com +fuyingkeji.com +fuyingyanke.com +fuyiou.com +fuyiwang.net +fuyou.online +fuyou888.com +fuyoubank.com +fuyougame.com +fuyoukache.com +fuyuan5.com +fuyuan6.com +fuyuehotels.com +fuyunbj.com +fuyuncc.com +fuyunjiasu.com +fuyuzhe.com +fuzadu.com +fuzamei.com +fuzeetech.com +fuzegame.com +fuzfu.net +fuzhenghos.com +fuzhhc.com +fuzhimao.com +fuzhoufashi.com +fuzhuangwang.com +fuzhugo.com +fuziche.com +fvfvxs.com +fview.com +fvo2o.com +fvti.com +fw-12365.com +fw365.online +fw4.co +fw4.me +fwbsjnakjabdname.com +fwcfwg.com +fwcranes.com +fwcx315.com +fwdq.com +fwdqw.com +fwfly.com +fwhzxxgbyy.com +fwljmwf.com +fwlxtc.com +fwqje67h.work +fwqlt.com +fwqtg.net +fws-china.com +fwtoys.com +fwvv.net +fwwevez.xyz +fwxgx.com +fx-plc.com +fx120.net +fx168api.com +fx168news.com +fx168vip.com +fx3q.com +fx678.com +fx678.net +fx678img.com +fx678red.com +fx696.com +fx898.com +fxbaogao.com +fxccp1296.com +fxcdev.com +fxclass.net +fxcsxb.com +fxcw.com +fxdp.com +fxe0898.com +fxeyee.com +fxeyetips.com +fxfbx.com +fxfcyy.com +fxgjwy.com +fxgz8.com +fxhaoke.com +fxian.org +fxiaoke.com +fxingw.com +fxjia.shop +fxkedu.com +fxkjnj.com +fxlbb.com +fxlbl.com +fxltsbl.com +fxm.so +fxo2opt.com +fxpai.com +fxpan.com +fxpharm.com +fxrcw.net +fxsh.com +fxsou.com +fxsw.net +fxt365.com +fxtrip.com +fxtrips.com +fxw.la +fxwe.com +fxxww.net +fxxz.com +fxyf99.com +fxzb.vip +fxzhj.com +fxzhjapp.com +fxzygc.com +fy-connect.com +fy-game.com +fy-mold.com +fy027.com +fy169.net +fy1938.com +fy2d.com +fy35.com +fy65.com +fyaaz.org +fyab.net +fyage.com +fyak.net +fyal.net +fyan.net +fyapi.net +fyat.net +fyau.net +fyaw.net +fybiji.com +fybj.net +fybjsd.com +fyblogs.com +fybxw.com +fycpu.com +fycrcgas.com +fyddj.com +fyddjys.com +fydeos.com +fydvtu.com +fyec.net +fyeds.com +fyeds0.com +fyeds1.com +fyeds2.com +fyeds3.com +fyeds4.com +fyeds5.com +fyeds6.com +fyeds7.com +fyeds8.com +fyeds9.com +fyedu.net +fyeedu.net +fyfch.com +fygame.com +fygdrs.com +fygi.com +fygift.com +fygjyljt.com +fygmbc.com +fygroup.com +fygsoft.com +fyigou.com +fyjl.org +fyjsz.net +fyjzyxh.com +fylcg.com +fyleasing.com +fyluo.com +fymaduoji.com +fymall0.com +fymall1.com +fymall2.com +fymall3.com +fymall4.com +fymall5.com +fymall6.com +fymall7.com +fymall8.com +fymall9.com +fymallqa0.com +fymallqa1.com +fymallqa2.com +fymallqa3.com +fymallqa4.com +fymallqa5.com +fymallqa6.com +fymallqa7.com +fymallqa8.com +fymallqa9.com +fynas.com +fynb.net +fynews.net +fypage.com +fypt.net +fyqyjt.com +fyrc.net +fyrcbk.com +fyrexian.com +fyrmyy.com +fyrqgs.com +fyrwzz.com +fyscs.com +fysfzk.com +fysip.com +fysoft3.com +fysyy.com +fytcw.com +fythbkj.com +fytire.com +fytschool.com +fytxonline.com +fytz.net +fyuanpack.com +fyun.cc +fyun.org +fyvart.com +fywip.com +fywx.cc +fyxhlink.com +fyxtzc.com +fyxxcl.com +fyxxwb.com +fyxz.com +fyydnz.cc +fyynlx.com +fyyy.com +fyzku.com +fyzls.com +fyzp.net +fz-aefi.com +fz-energy.com +fz-gf.com +fz0752.com +fz222.com +fz2sc.com +fz597.com +fzahw.com +fzaqjy.com +fzbbk.com +fzbdcj.com +fzbidding.com +fzbingo.com +fzbm.com +fzccpit.org +fzcollege.org +fzcpos.com +fzcrg.com +fzcyjh.com +fzddg.com +fzdmag.com +fzdzyun.com +fzec-tencentclb.cloud +fzec-tencentclb.com +fzec-tencentclb.net +fzec-tencentclb.work +fzele.com +fzengine.com +fzentertainment.com +fzetyy.com +fzfhg.com +fzfinancing.com +fzfrp.com +fzfu.com +fzfzjx.com +fzg360.com +fzghy.com +fzgolden.com +fzhlkx.com +fzhqzx.net +fzhzxh.com +fzithome.com +fzjdct.com +fzjingzhou.com +fzjs.work +fzjxr.com +fzjxw.com +fzkjg.com +fzl7.com +fzlawyers.net +fzlbar.com +fzlean.com +fzlft.com +fzlizhi.net +fzlol.com +fzmama.net +fzmetro.net +fzmtr.com +fzn.cc +fzport.com +fzqywater.com +fzrsrc.com +fzs.com +fzsdtkq.com +fzsdyyy.com +fzshouji.com +fzslyy.com +fzswgc.com +fzswjt.com +fzswyc.com +fzsybj.com +fzthinking.com +fzvcolco.com +fzwater.com +fzwcn.com +fzwhzn.com +fzwqq.com +fzwtqx.com +fzwxxcx.com +fzxiaomange.com +fzxm.com +fzyfan.com +fzyfs.net +fzyinghe.com +fzyun.net +fzyvis.com +fzyz.net +fzzhaobiao.com +fzzhtc.com +fzzhuoyi.com +fzzixun.com +fzzpw.net +fzzqcdn.com +g-biomed.com +g-bits.com +g-cores.com +g-digital4ud.com +g-film.com +g-hi.com +g-medon.com +g-proxy.com +g-spin.com +g-tar.com +g-var.com +g.biz +g00gle.vip +g052m43e2ghn.com +g1080.com +g12e.com +g12e.org +g188.net +g1d.net +g1yx.com +g2.link +g20chn.org +g2h3.com +g2us.com +g2work.com +g32365.com +g3d.org +g3img.com +g3user.com +g3voip.com +g3wei.com +g4weixin.com +g55m94b1za.com +g59p.com +g5h.com +g5h4.com +g5kj.com +g63.fun +g66667777.com +g768r.com +g77775555.com +g7bd307de.skin +g80mx.com +g82btd54.work +g88885555.com +g88886666.com +g8hh.com +g983.com +g9china.com +ga-me.com +ga-zn.com +ga002.com +gaaamee.com +gaapqcloud.com +gaaptest.com +gac-capital.com +gac-nio.com +gacfca.com +gacfcasales.com +gacfiatauto.com +gachn.com +gaclib.net +gacmotor.com +gacrnd.com +gacsofinco.com +gadlee.com +gae-pro.com +gaeadata.com +gaeamobile-inc.net +gaeamobile.net +gaetausohyei.com +gafata.com +gafei.com +gafencuchina.com +gagacafe.com +gagaga.icu +gagaga.tech +gagahi.com +gai.net +gaiabiohx.com +gaiamount.com +gaiaworkforce.com +gaibang365.com +gaibar.com +gaibieshu.net +gaicas.com +gaigeshen.work +gainchip.com +gainda.net +gaineng.net +gainet.com +gainscha.com +gaintop.com +gairuo.com +gaisen.ltd +gaishichina.com +gaishitongshu.com +gaitu.com +gaituba.com +gaitubao.com +gaituya.com +gaixingchang.com +gaixue.com +gaiyadajidali.com +gaiyazhanlan.com +gaizhui.com +gajerseys.com +gajsk.com +gal3d.info +gala-v.com +galaxix.com +galaxus.club +galaxus.work +galaxy-geely.com +galaxy-immi.com +galaxyasset.com +galaxycarepair.com +galaxyfont.com +galaxyinfo.com +galaxymagnets.com +galaxyoversea.com +galileo.work +galsun.com +galudisu.info +galvincdn.com +gamder.cc +gamdream.com +game-as.com +game-client.com +game-props.com +game-reign.com +game10000.com +game112233.com +game123.space +game12315.com +game13.com +game2.com +game234.com +game332.com +game3vs7novel.com +game499.com +game5.com +game5399.com +game773.com +game798.com +game80s.com +game89.com +game900.com +game9012.com +game95.cc +gameabc.com +gameabc2.com +gameabc2.net +gameapida.com +gameapp.club +gamebar.com +gamebean.com +gamebean.net +gamebee.net +gamebonfire.com +gamebto.com +gamecat.fun +gamecatstudio.com +gamecomb.com +gamed9.com +gamedachen.com +gamedo.org +gameducky.com +gameegg.com +gameexp.com +gamefang.com +gamefeile.com +gamefm.com +gamegamept.com +gamege.com +gameggg.com +gamegocenter.com +gamegocenter.net +gamehaopu.com +gamehome.tv +gameinns.com +gameitop.com +gamejym.com +gamekee.com +gamekezhan.com +gamekuaishou.com +gamelet.games +gameley.com +gameloop.com +gameloop.fun +gamemale.com +gamemcu.com +gamemei.com +gamemili.com +gamenow.club +gameol.com +gamepingce.com +gamepp.com +gamer520.net +gamerboom.com +gameres.com +gamerhome.com +gamerhome.net +gamermake.com +gamersky.com +gamersky.net +gamerstorm.com +gamesh.com +gameshr.com +gamesifu.com +gametanzi.com +gametaptap.com +gametdd.com +gametea.com +gametea.net +gamethk.com +gamett.net +gameviewer.com +gamewifi.net +gamewower.com +gamexdd.com +gamexhb.com +gamexun.com +gameyiming.com +gameyisi.com +gameyj.com +gamfe.com +gammabicycle.com +gammatimes.com +gamutsoft.com +gamux.org +gamxex.com +gan-ren.com +gandi.net +ganduee.com +gangbao365.com +gangbogroup.com +gangduotech.com +ganggangguoji.com +ganggg.com +gangguan8.com +gangguana.com +ganghaowang.com +gangjiajieli.com +gangpaibao.com +gangqinpu.com +gangqinxiansheng.com +gangshenglian.com +gangtise.com +gangwan.com +gangyu.org +gangyuan.com +ganhao.vip +ganji.com +ganjiangrc.com +ganjiangvpn.com +ganjiazheng.com +ganjin.com +ganjistatic1.com +ganjistatic2.com +gank-studio.com +gank.io +gankang.com +gankao.com +gankaomao.com +gankaosheng.com +gankgames.com +gankh5.com +ganlj.com +ganlongjt.com +ganlv.net +ganlvji.com +ganniu.com +ganode.org +ganqi.com +ganqi.net +ganqing10.com +ganrobot.com +ganso.net +gansuairport.com +gansumuseum.com +gansuyouxi.com +gantanhao.com +gantanhao.vip +gantong.net +ganwan.com +ganxb2.com +ganxi.com +ganxianw.com +ganxianzhi.win +ganxinet.com +ganyeah.com +ganyu.com +ganyu.org +ganyu8.net +ganyurc.com +ganzhe.com +ganzhishi.com +ganzhong.net +ganzitv.com +gao-shou.com +gao.bo +gao.com +gao7.com +gao7gao8.com +gaoan.net +gaobei.com +gaobiao.xyz +gaobohealthcare-sh.com +gaocangyun.com +gaoce.cc +gaocegege.com +gaochun.info +gaoda8.com +gaodage.com +gaodangbiao.com +gaode.com +gaodilicai.com +gaodimed.com +gaoding.com +gaoduanqianzheng.com +gaoduguoji.com +gaodun.com +gaodunwangxiao.com +gaofacable.com +gaofangcache.com +gaofangm.com +gaofangz.com +gaofans.com +gaofeie.com +gaofen.com +gaofenplatform.com +gaofenzi.org +gaofushuai.com +gaogpress.com +gaogulou.com +gaohaipeng.com +gaohangip.com +gaoheconsult.com +gaohr.com +gaohuasec.com +gaoimg.com +gaojer.com +gaoji.ren +gaojie.com +gaojihealth.com +gaojima.com +gaojipro.com +gaojitui.com +gaojiua.com +gaokao.com +gaokao365.com +gaokao789.com +gaokaobaoming.com +gaokaohelp.com +gaokaomeishu.com +gaokaopai.com +gaokaoq.com +gaokaozhiku.com +gaokaozhitongche.com +gaokeny.com +gaokin.com +gaokowl.com +gaokw.com +gaokzx.com +gaolian.com +gaoligroup.com +gaolihanjie.com +gaolouimg.com +gaomeif.com +gaomeluo.com +gaominews.com +gaomon.net +gaopaiwood.com +gaopeng.com +gaopin.tech +gaopinimages.com +gaopost.com +gaoqidian.com +gaoqingdianshi.com +gaoqinghua.com +gaoqingpai.com +gaoqiwenda.com +gaoqixhb.com +gaoqixie.com +gaore.com +gaosafe.com +gaosan.com +gaoseng.com +gaoshou.me +gaoshouvr.com +gaoshouyou.com +gaosiedu.com +gaosivip.com +gaosouyi.com +gaosu.com +gaosudu.com +gaotang.cc +gaotangwang.com +gaotieshike.com +gaotu006.club +gaotu007.club +gaotu100.com +gaotu11.com +gaotuxueyuan.com +gaowoip.com +gaoxiaobang.com +gaoxiaodashi.com +gaoxiaoit.com +gaoxiaojob.com +gaoxiaoo.com +gaoxiaozp.com +gaoxin123.com +gaoxincarbon.com +gaoxinedu.com +gaoxinedu.net +gaoxinjy.com +gaoxitech.com +gaoyawang.com +gaoyizaixian.com +gaoyoujob.com +gaozhaiedu.com +gaozhentang.com +gaozhidazhuan.com +gaozhongwuli.com +gaozhouba.com +gaozi365.com +gap.hk +gapitech.com +gaqcloud.com +gaqcloud.net +gaqcloud1.com +gaqcloud2.com +gaqcloudbackup.com +gaqcloudbackup.net +gara.cc +garage-bastide.com +garden-aquarium.com +gardencn.com +gardenhotel.com +gardenhotelshanghai.com +garfopg.org +garleden.com +garmin.com +garmuri.com +garnoc.com +garnor.com +garphy.com +garply.com +garyee.com +gas-analyzers.com +gas-scrubber.com +gas-turbine-parts.com +gas775.com +gas800.com +gasfw.com +gasgoo.com +gasgood.com +gashr.com +gashw.com +gaspeedup.com +gaspim.com +gasshow.com +gastank-china.com +gastronomy.gov.mo +gate-dhgames.com +gateface.com +gateweb3.cc +gateweb3.io +gather-dns.com +gatymciu.com +gaudie.org +gaugan.com +gaush.com +gautomator.com +gavill.com +gavindesign.com +gavinzh.com +gaxgame.com +gaxrmyy.com +gayotv.net +gayzyhh.com +gaze.run +gazellegames.net +gazemd.com +gazx.org +gb324.com +gb55009.com +gb56.net +gb5842.com +gbacd.com +gbase8a.com +gbasebi.com +gbasig.com +gbdex.com +gbdz.net +gbeca.org +gbffchina.com +gbgba.com +gbgcn.com +gbhome.com +gbiac.net +gbicdn.com +gbicom.com +gbictc.com +gbimg.com +gbma.org +gbofd.com +gbox.pub +gboxchina.com +gbphar.com +gbrgz.com +gbskptu1044.vip +gbsrobot.com +gbstape.com +gbt88.com +gbtranswins.com +gbvh.com +gbw114.com +gbxgateway-dev.dell.com +gbxgateway.dell.com +gc-zb.com +gc0771.com +gc1616.com +gc39.com +gc48tdh6gm.com +gc73.com +gc91.com +gcable.tv +gccdn.net +gccgz.com +gcchina.com +gccmgw.com +gccrcw.com +gcdcrs.com +gcexlab3.com +gcgd.net +gcgzjt.com +gchao.com +gchbs.com +gchhotels.com +gci-china.com +gcihotel.net +gciig.com +gcimg.net +gcjc.com +gcjgxx.com +gcjlkj.com +gcjr.com +gcjy.info +gckychina.com +gcl-et.com +gcl-perovskite.com +gcl-power.com +gcld.net +gclhgc.com +gcloudcs.com +gcloudcstest.com +gcloudcstestonly.com +gclouddolphin.com +gcloudf.com +gcloudgbs.com +gcloudsdk.com +gcloudsvcs.com +gcmc.cc +gcok.com +gcomtechnology.com +gcopt.com +gcoreinc.com +gcores.com +gcpok.com +gcpunion.org +gcs66.com +gcscmp.com +gcstorage.com +gctianshanxh.com +gctong.com +gctwds.com +gctzsh.com +gcwdp.com +gcwduoduo.com +gcwith.com +gcykj.com +gcyts.com +gcyy08.com +gczyg.com +gd-chenxing.com +gd-chuangfu.com +gd-dl.com +gd-esa.com +gd-haijing.com +gd-hcsj.com +gd-hongyuegroup.com +gd-hskj.com +gd-hstech.com +gd-huadi.com +gd-id.com +gd-jinzhanggui.com +gd-jxjy.com +gd-kexin.com +gd-linux.com +gd-linux.org +gd-ls.com +gd-lt.com +gd-realfaith.com +gd-shenhua.com +gd-tianchen.com +gd-tianyue.com +gd-wanxi.com +gd-weisi.com +gd-xrsd.com +gd1580.com +gd165.com +gd2000.org +gd2h.com +gd32.com +gd32mcu.com +gd3n.com +gd56114.com +gd563.com +gd9d.com +gda086.com +gdaa.ltd +gdadjs.com +gdadri.com +gdaep.com +gdahua.com +gdaia.net +gdairport.com +gdanano.com +gdandun.com +gdapi.net +gdarcu.net +gdase.com +gdass.org +gdatacube.net +gdatc.net +gdbailin.com +gdbainengbao.com +gdbaishun.net +gdbbk.com +gdbhnk.com +gdbicyclexh.com +gdbidding.com +gdbita.com +gdbljd.com +gdbmh.com +gdbsjd.com +gdbzkz.com +gdbzkz.org +gdcaa.com +gdcaia.com +gdcaward.com +gdcayyebh.com +gdccaa.com +gdcci.com +gdccus.org +gdcdsh.com +gdceg.com +gdcgkg.com +gdchanbo.com +gdchess.com +gdchjt.com +gdcia.org +gdcic.net +gdcjrhcjh.com +gdcjtd.com +gdcjxx.com +gdcocodemer.com +gdcoop.com +gdcopper.com +gdcordblood.org +gdcost.com +gdcow.com +gdcreate.com +gdcsgj.com +gdctaa.com +gdctcd.com +gdctdb.com +gdctpark.com +gdcts.com +gdctsvisa.com +gdctsy.com +gdcvi.net +gdcxc2c.com +gdcxxy.net +gdcygp.com +gdcyl.org +gdczedu.net +gdczkj.com +gdczyy.com +gddata.net +gddci.com +gddcjt.com +gddcm.com +gddelux.com +gddeqing.com +gddfpaper.com +gddfund.com +gddg.cc +gddhn.com +gddianchuang.com +gddidg.com +gddikasi.com +gddingxin.com +gddjauto.com +gddlaaa.com +gddlkj.com +gddmsmc.com +gddqfs.com +gddqfs.net +gddrcgzjt.com +gddsjt.com +gddtop.com +gddyhb168.com +gddysl.com +gddz0769.com +gde.cc +gdeams.com +gdebidding.com +gdecn.com +gdedia.com +gdedu123.com +gdeeia.com +gdefair.com +gdeia.com +gdems.com +gdepi.com +gdevops.com +gdfanhua.com +gdfcjz.com +gdfeiyang.com +gdfenxiao.com +gdfggvfsd.asia +gdfgq.club +gdfjsh.org +gdfplaza.com +gdfs.com +gdfsg-yxva.vip +gdfshx.com +gdfuji.com +gdfushefanghuxiehui.com +gdfzsy.com +gdgajt.com +gdganhua.com +gdgassoc.com +gdgcjhf.com +gdgczb.com +gdggkf.com +gdghg.com +gdgkfn.com +gdgkty.com +gdgowe.com +gdgpc.net +gdgrsw.com +gdguangdong.com +gdguozhi.com +gdgwyw.com +gdgxxbw.com +gdgzhengzhou.com +gdgzrb.com +gdhairun.com +gdhaoma.com +gdhbsh.com +gdhchina.com +gdhcsh.com +gdhdbxg.com +gdhdgc.com +gdhengdian.com +gdhfjt.com +gdhfkg.com +gdhhgroup.com +gdhhjs.net +gdhhotels.com +gdhjtz.com +gdhjzs.com +gdhla.com +gdhmgc.com +gdhongsha.com +gdhpwx.com +gdhqzy.com +gdhsbid.com +gdhtcm.com +gdhuana.com +gdhuaxun.net +gdhuaya.com +gdhwater.com +gdhwgf.com +gdhwjl.com +gdhxgf.com +gdhylhh.com +gdhzsb.com +gdi5ap2ikn.com +gdida.org +gdie.com +gdinfo.net +gdinin.com +gdinm.com +gdinsa.org +gdinsight.com +gdipa.org +gdippa.com +gdiso.com +gdj-tech.com +gdjdxh.com +gdjdxy.com +gdjhh.com +gdjiabao.com +gdjinge.com +gdjinguan.net +gdjingyin.com +gdjinzong.com +gdjiutu.com +gdjky.com +gdjlfood.com +gdjlxh.org +gdjly.com +gdjs120.com +gdjshd.com +gdjugong.com +gdjuhan.com +gdjuntai.com +gdjxjy.com +gdjxzs.com +gdjydg.com +gdjysteel.com +gdjyw.com +gdjyyy.com +gdkailin.com +gdkcsj.com +gdkepler.com +gdkingma.com +gdkjb.com +gdkjk56.com +gdkjw.com +gdkjzy.net +gdks168.com +gdkszx.com +gdktzx.com +gdkxpcb.com +gdkyhj.com +gdkz88.com +gdlaoan.com +gdlgsw.com +gdlgxy.com +gdlighting.com +gdlii.com +gdlinefly.com +gdlingjie.net +gdlins.com +gdliontech.com +gdlkjt.com +gdlmetc.com +gdlnpumps.com +gdlsgz.com +gdlswl.com +gdly-motor.com +gdlz.com +gdmagam.com +gdmain.com +gdmca.org +gdmhjjt.com +gdmia.com +gdminda.com +gdmm.com +gdmoa.org +gdmschina.com +gdmtjt.com +gdmuah.com +gdmusah.com +gdmuseum.com +gdmzh.com +gdmztv.com +gdnanbo.com +gdnbdaqi.com +gdnd2016.com +gdnengyuan.com +gdneptunus.com +gdnewmedia.cc +gdnfu.com +gdnfzb.com +gdnhci.com +gdnin.com +gdniubang.com +gdnjuae.com +gdnybank.com +gdnyjt.com +gdofun.com +gdoip.com +gdojbk.com +gdokpackaging.com +gdolai.com +gdomall.com +gdou.com +gdpace.com +gdpdd.com +gdpengquan.com +gdpia.com +gdprm.com +gdprm.net +gdpsc.org +gdpysc.com +gdqcxcl.com +gdqianliang.com +gdqianyou.com +gdqlxh.com +gdquannong.com +gdqxjt.com +gdqynews.com +gdrc.com +gdrc360.com +gdrc365.com +gdrcu.com +gdrdcy.com +gdrfyy.com +gdronggang.com +gdroro.com +gdrqj.org +gdrsrc.com +gdruien.com +gdruisheng.com +gdrxyy.com +gdrxzx.com +gdryc.com +gds-huanbaogroup.com +gds-services.com +gdsa.com +gdsaipu.com +gdsalt.com +gdsanlian.com +gdsanling.com +gdsbaxh.com +gdscse.net +gdsday.com +gdsdays.com +gdsdkg.com +gdsdwan.com +gdsdyy.com +gdsflbs.com +gdsfpharma.com +gdsfsgl.com +gdsgd.com +gdsgj.com +gdsgjgxh.com +gdshcm.com +gdshe.org +gdshunna.net +gdshuojin.com +gdsia.net +gdsjqr.com +gdsjx.com +gdsjxjy.com +gdskfz.com +gdskills.com +gdskin.com +gdslrobot.com +gdslwl.com +gdsme.org +gdsoftpark.com +gdsports.net +gdsqyg.com +gdsrcw.com +gdssie.com +gdsspt.net +gdst.cc +gdstc.group +gdstie.com +gdstlab.com +gdsugar.com +gdsunfly.com +gdsunhot.com +gdsunli.com +gdsuxie.com +gdswgc.com +gdswine.com +gdsxgd.com +gdsxgf.com +gdsytech.com +gdsyy.org +gdsyzxsz.com +gdszjgdj.org +gdszkw.com +gdszsl.com +gdszxh.com +gdtadx.com +gdtaihao.com +gdtap.com +gdtc.cc +gdtcoin.com +gdtcyy.com +gdtengen.com +gdtengnan.com +gdtex.com +gdtextbook.com +gdtianrun.com +gdtianshanoa.com +gdtichy.com +gdton.com +gdtongda.com +gdtongjiang.com +gdtongyi.com +gdtravel.com +gdtri.com +gdtstream.com +gdttaph.com +gdttc.com +gdtu.org +gdtx56.com +gdtykj.net +gdtz888.com +gdtzb.com +gdu-tech.com +gduaee.com +gdunis.com +gdupi.com +gdus.cc +gdutbbs.com +gdveren.com +gdvolunteer.net +gdwanlv.com +gdwanshun.com +gdwbyq.com +gdwca.com +gdwczb.com +gdweilaisw.com +gdwha.org +gdwia.com +gdwlcloud.com +gdwld.com +gdwlife.com +gdwsa.com +gdwse.com +gdwsrc.net +gdww.com +gdwxyf.com +gdwz.com +gdxdf.com +gdxdpg.com +gdxdy.com +gdxfl.com +gdxindun.com +gdxinqiang168.com +gdxinxiang.com +gdxise.com +gdxjzx.org +gdxmsx.com +gdxscode.com +gdxsn.com +gdxueyin.com +gdxy.vip +gdxych.com +gdybkjjt.com +gdyd.com +gdydgj.com +gdydzb.com +gdyeb.com +gdygsk.com +gdyhgn.com +gdyhsp.com +gdyiyou.com +gdykhb.net +gdylhp.com +gdyngl.com +gdyouyes.com +gdypt.com +gdyqxc.com +gdyslyh.org +gdysnk.com +gdysxh.com +gdytc.com +gdytxh.com +gdyuanshun.com +gdyuasa.com +gdyuegou.com +gdyuhi.com +gdyunxiao.com +gdyunyin.net +gdyxc.com +gdyyjgxh.com +gdyyyy.net +gdz.co +gdzbha.com +gdzcjt.net +gdzd-motor.com +gdzdbidding.com +gdzgjl.com +gdzgy.com +gdzhcx.com +gdzhenxing.com +gdzhiding.com +gdzhig.com +gdzhonghua.com +gdzhongpeng.com +gdzhongshan.com +gdzjdl.com +gdzjqy.com +gdzp.org +gdzrlj.com +gdzs2018.cc +gdzs2018.vip +gdzskj.tech +gdzsxx.com +gdzszt.com +gdztbz.com +gdzuoxie.com +gdzxgj.com +gdzxmm.com +gdzy5413.com +gdzygroup.com +gdzygy.com +gdzyinvest.com +gdzyjnw.com +gdzz114.com +gdzzjc.com +gdzzw.net +gdzzz.com +ge-garden.net +ge100.com +ge3rge43r6.com +geality.com +geapu.com +gear5.me +gearbbs.net +gearfront.net +gearkr.com +gearpharma.com +gearsnet.com +geautos.com +gebaiwan.com +gebchina.com +gebertech.com +gebilaoshi.com +gebinlong.com +gebiqu.com +gec123.com +geci123.com +gecimi.com +gecpc.com +gedi2099.com +gedou8.com +gedoumi.com +gedu.org +geeboo.com +geebook.com +geedai.com +geedu.com +geeetech.com +geeeu.com +geehy.com +geejing.com +geek-docs.com +geek-papa.com +geek-share.com +geek32.com +geekbang.com +geekbang.org +geekbangtech.com +geekcar.com +geekcar.net +geekclo.com +geekdata.com +geekdaxue.co +geekdive.com +geekefu.com +geekercloud.com +geekerconsulting.com +geekerhua.com +geekfans.com +geekiron.com +geeklab.work +geeklei.com +geekluo.com +geekmaker.com +geekman.vip +geeknev.com +geekpark.net +geekpwn.com +geekpwn.org +geeksblog.cc +geeksman.com +geektcp.com +geektutu.com +geeku.net +geekwom.com +geekxia.com +geekxue.com +geekzhao.me +geekzl.com +geelevel.com +geely-auto-gtm.com +geely-motors.com +geely-test.com +geely.com +geely.com.qa +geely.pe +geelyauto.com.hk +geelycv.com +geelydesign.com +geelyholding.com +geelylaos.com +geelyminiprogram.com +geelyph.com +geelysc.com +geelyswedenholdings.com +geement.com +geeqee.com +geermunews.com +geermurmt.com +geeseteam.com +geesic.com +geespace.com +geetest.com +geevisit.com +geewaza.com +geexek.com +geezn.com +gegame.site +gegeailu.org +gegedao.com +gegejia.com +gegemm.work +gegeselect.hk +gegeyingshi.com +gehaowu.com +gehope.com +gehua.com +gehua.net +gei-journal.com +gei.pw +gei6.com +geicloud.com +geihuasuan.com +geihui.com +geilicdn.com +geilijiasu.com +geilijiasu.net +geiliwx.com +geimian.com +geiniwan.com +geisnic.com +geizan.cc +gelaha.com +gelicang.net +geline.net +gelinya.com +geliqi.net +gellec.com +gelonghui.com +gelu.me +gelufu.com +gem-soft.com +gemac-cn.com +gembotech.com +gemchina.com +gemdale.com +gemei.com +gemelai.com +gemiaomiao.org +gemii.cc +gemini-galaxy.com +gemini530.net +gemjz.com +gemled-tech.com +gempharmatech.com +gempoll.com +gemuedu.com +genchim.com +gendan5.com +gendantong.com +gendone.com +genegeo.com +geneliunx.com +genelotus.com +genepharma.com +general-power.com +generalfushi.com +generalichina.com +generaltouch.com +generalwatertech.com +genergy-technology.com +genericfixer.com +generosbio.com +genesis-rock.com +geneskies.com +genetalks.com +genevoyager.com +geneway-bio.com +geneworldcn.com +genfleet.com +gengchuangz.com +gengfuwang.com +genghai.com +gengius.com +gengleyuan.com +gengls.org +gengnie.com +gengsan.com +gengshangpin.com +gengstar.com +gengzhongbang.com +genhousebio.com +geni4s.com +genial.vip +geniatech.com +genie-robot.com +geniusafc.com +geniusara.com +geniuscn.com +geniusite.com +genmiao.com +genobank.org +genomeditech.com +genrace.com +genscript.com +gensee.com +genshinimpact.com +genshinimpact.moe +genshuixue.com +genstars.com +gentco.com +gentechchina.com +gentize.com +genudite.com +genuine-bio.com +genuway.com +genvict.com +genway.net +geo-compass.com +geo.kaspersky.com +geo2k.com +geoactivity.net +geoai.com +geoforcechip.com +geogsci.com +geoharbour.com +geohey.com +geoidc.com +geolong.com +geometryauto.com +geons.host +georginaarmadas.com +geosheen.com +geospatialsmart.com +geovisearth.com +gepcc.com +gephb.com +gepresearch.com +gepubbs.com +geren-jianli.com +gerenjianli.com +gerenshuoming.com +gerhard-china.com +germmc.com +geruihuate.com +geruishuiwu.com +geruisi-bio.com +gerzz.com +gesanghua.org +gescosteel.com +gescs.com +gesedna.com +gesedna.net +gesep.com +geshitong.net +geshui.com +geshui100.com +geshui99.com +geshuiba.com +gestagpu.com +gesuo.com +geswl.com +get-shell.com +get.vip +get233.com +getbs.com +getcai.com +getconnectplus.com +getddhospi.com +getehu.com +getelighting.com +getgetai.com +gethover.com +getiis.com +getiot.tech +getkwai.com +getmarkman.com +getpm.com +getquicker.net +getrebuild.com +getsays.com +getsetgadget.com +getsurfboard.com +gettopacoustic.com +getu.fun +getui.vip +getvidi.co +gewala.com +gewara.com +gewei-wh.com +gewei.com +geweng.com +gewu.vc +gewuer.com +gewuzhixiang.com +gexiao.me +gexiaocloud.com +gexinda.com +gexing.com +gexing.me +gexings.com +gexingshuo.com +gexingzipai.com +gexiong.com +gexiuyixibai.org +geyawatch.com +geyevalve.com +geyifudi.com +geyo.com +geyoukj.com +gezida.com +gezila.com +gezipu8.net +gezivisa.com +gf-cloud.com +gf-funds.com +gf-metals.com +gf-nj.com +gf.app +gf.cc +gf139.com +gf1579.com +gf7979cn.com +gfan.com +gfanstore.com +gfbk.net +gfbzb.com +gfbzb.net +gfcdn.xyz +gfcity.com +gfcname.com +gfcvisa.com +gfd178.com +gfdj99665.com +gfdns.net +gfdsa.net +gfdwsx.com +gfedu.com +gfedu.net +gffirm.com +gffwq.com +gfglb.com +gfh82.com +gfhealthcare.com +gfjeah-rhjeb6.com +gfjl.org +gflad.com +gflz.com +gfmpv.com +gfnormal00ab.com +gfnormal00ac.com +gfnormal00ad.com +gfnormal00ae.com +gfnormal00af.com +gfnormal00ag.com +gfnormal00ai.com +gfnormal00al.com +gfnormal00am.com +gfnormal00ao.com +gfnormal00ap.com +gfnormal00aq.com +gfnormal00ar.com +gfnormal00as.com +gfnormal00at.com +gfnormal01aa.com +gfnormal01ab.com +gfnormal01ac.com +gfnormal01ad.com +gfnormal01af.com +gfnormal01ag.com +gfnormal01ah.com +gfnormal01ak.com +gfnormal01al.com +gfnormal01am.com +gfnormal01an.com +gfnormal01ao.com +gfnormal01ap.com +gfnormal01aq.com +gfnormal01ar.com +gfnormal01as.com +gfnormal01at.com +gfnormal02aa.com +gfnormal02ab.com +gfnormal02ac.com +gfnormal02ad.com +gfnormal02ae.com +gfnormal02af.com +gfnormal02ag.com +gfnormal02ah.com +gfnormal02ai.com +gfnormal02aj.com +gfnormal02ak.com +gfnormal02al.com +gfnormal02am.com +gfnormal02an.com +gfnormal02ao.com +gfnormal02ap.com +gfnormal02aq.com +gfnormal02ar.com +gfnormal02as.com +gfnormal02at.com +gfnormal03aa.com +gfnormal03ab.com +gfnormal03ac.com +gfnormal03ad.com +gfnormal03ae.com +gfnormal03af.com +gfnormal03ag.com +gfnormal03ah.com +gfnormal03ai.com +gfnormal03aj.com +gfnormal03ak.com +gfnormal03al.com +gfnormal03am.com +gfnormal03an.com +gfnormal03ao.com +gfnormal03ap.com +gfnormal03aq.com +gfnormal03ar.com +gfnormal03as.com +gfnormal03at.com +gfnormal04aa.com +gfnormal04ab.com +gfnormal04ac.com +gfnormal04ad.com +gfnormal04ae.com +gfnormal04af.com +gfnormal04ag.com +gfnormal04ah.com +gfnormal04ai.com +gfnormal04aj.com +gfnormal04ak.com +gfnormal04al.com +gfnormal04am.com +gfnormal04an.com +gfnormal04ao.com +gfnormal04ap.com +gfnormal04aq.com +gfnormal04ar.com +gfnormal04as.com +gfnormal04at.com +gfnormal05aa.com +gfnormal05ab.com +gfnormal05ac.com +gfnormal05ad.com +gfnormal05ae.com +gfnormal05af.com +gfnormal05ag.com +gfnormal05ah.com +gfnormal05ai.com +gfnormal05aj.com +gfnormal05ak.com +gfnormal05al.com +gfnormal05am.com +gfnormal05an.com +gfnormal05ao.com +gfnormal05ap.com +gfnormal05aq.com +gfnormal05ar.com +gfnormal05as.com +gfnormal05at.com +gfnormal06aa.com +gfnormal06ab.com +gfnormal06ac.com +gfnormal06ad.com +gfnormal06ae.com +gfnormal06af.com +gfnormal06ag.com +gfnormal06ah.com +gfnormal06ai.com +gfnormal06aj.com +gfnormal06ak.com +gfnormal06al.com +gfnormal06am.com +gfnormal06an.com +gfnormal06ao.com +gfnormal06ap.com +gfnormal06aq.com +gfnormal06ar.com +gfnormal06as.com +gfnormal06at.com +gfnormal07aa.com +gfnormal07ab.com +gfnormal07ac.com +gfnormal07ad.com +gfnormal07af.com +gfnormal07ag.com +gfnormal07ah.com +gfnormal07ai.com +gfnormal07aj.com +gfnormal07ak.com +gfnormal07al.com +gfnormal07am.com +gfnormal07an.com +gfnormal07ao.com +gfnormal07ap.com +gfnormal07aq.com +gfnormal07ar.com +gfnormal07as.com +gfnormal07at.com +gfnormal08aa.com +gfnormal08ab.com +gfnormal08ac.com +gfnormal08ad.com +gfnormal08ae.com +gfnormal08af.com +gfnormal08ag.com +gfnormal08ah.com +gfnormal08ai.com +gfnormal08aj.com +gfnormal08ak.com +gfnormal08al.com +gfnormal08am.com +gfnormal08an.com +gfnormal08ao.com +gfnormal08ap.com +gfnormal08aq.com +gfnormal08ar.com +gfnormal08as.com +gfnormal08at.com +gfnormal09aa.com +gfnormal09ab.com +gfnormal09ac.com +gfnormal09ad.com +gfnormal09ae.com +gfnormal09af.com +gfnormal09ag.com +gfnormal09ah.com +gfnormal09ai.com +gfnormal09aj.com +gfnormal09ak.com +gfnormal09al.com +gfnormal09am.com +gfnormal09an.com +gfnormal09ao.com +gfnormal09ap.com +gfnormal09aq.com +gfnormal09ar.com +gfnormal09as.com +gfnormal09at.com +gfnyzb.com +gforward.org +gfoxsoft.net +gfren.org +gfrtrttweet.com +gfslgy.com +gfsz.net +gftiec.com +gfttek.com +gftuan.com +gfun.me +gfund.com +gfvip00aa.com +gfvip00ab.com +gfvip00ac.com +gfvip00ad.com +gfvip00ae.com +gfvip00af.com +gfvip00ag.com +gfvip00ah.com +gfvip00ai.com +gfvip00aj.com +gfvip00ak.com +gfvip00al.com +gfvip00am.com +gfvip00an.com +gfvip00ao.com +gfvip00ap.com +gfvip00aq.com +gfvip00ar.com +gfvip00as.com +gfvip00at.com +gfvip01aa.com +gfvip01ab.com +gfvip01ac.com +gfvip01ad.com +gfvip01ae.com +gfvip01af.com +gfvip01ag.com +gfvip01ah.com +gfvip01ak.com +gfvip01al.com +gfvip01am.com +gfvip01an.com +gfvip01ao.com +gfvip01ap.com +gfvip01aq.com +gfvip01ar.com +gfvip01as.com +gfvip01at.com +gfvip02aa.com +gfvip02ab.com +gfvip02ac.com +gfvip02ad.com +gfvip02ae.com +gfvip02af.com +gfvip02ag.com +gfvip02ah.com +gfvip02ai.com +gfvip02aj.com +gfvip02ak.com +gfvip02al.com +gfvip02am.com +gfvip02an.com +gfvip02ao.com +gfvip02ap.com +gfvip02aq.com +gfvip02ar.com +gfvip02as.com +gfvip02at.com +gfvip03aa.com +gfvip03ab.com +gfvip03ac.com +gfvip03ad.com +gfvip03ae.com +gfvip03af.com +gfvip03ag.com +gfvip03ah.com +gfvip03ai.com +gfvip03aj.com +gfvip03ak.com +gfvip03al.com +gfvip03am.com +gfvip03an.com +gfvip03ao.com +gfvip03ap.com +gfvip03aq.com +gfvip03ar.com +gfvip03as.com +gfvip03at.com +gfvip04aa.com +gfvip04ab.com +gfvip04ac.com +gfvip04ad.com +gfvip04ae.com +gfvip04af.com +gfvip04ag.com +gfvip04ah.com +gfvip04ai.com +gfvip04aj.com +gfvip04ak.com +gfvip04al.com +gfvip04am.com +gfvip04an.com +gfvip04ao.com +gfvip04ap.com +gfvip04aq.com +gfvip04ar.com +gfvip04as.com +gfvip04at.com +gfvip05aa.com +gfvip05ab.com +gfvip05ac.com +gfvip05ad.com +gfvip05ae.com +gfvip05af.com +gfvip05ag.com +gfvip05ah.com +gfvip05ai.com +gfvip05aj.com +gfvip05ak.com +gfvip05al.com +gfvip05am.com +gfvip05an.com +gfvip05ao.com +gfvip05ap.com +gfvip05aq.com +gfvip05ar.com +gfvip05as.com +gfvip05at.com +gfvip06aa.com +gfvip06ac.com +gfvip06ad.com +gfvip06ae.com +gfvip06ag.com +gfvip06ah.com +gfvip06ai.com +gfvip06aj.com +gfvip06ak.com +gfvip06am.com +gfvip06an.com +gfvip06ao.com +gfvip06ap.com +gfvip06aq.com +gfvip06ar.com +gfvip06as.com +gfvip06at.com +gfvip07aa.com +gfvip07ab.com +gfvip07ac.com +gfvip07ad.com +gfvip07ae.com +gfvip07af.com +gfvip07ag.com +gfvip07ah.com +gfvip07ai.com +gfvip07aj.com +gfvip07ak.com +gfvip07al.com +gfvip07am.com +gfvip07an.com +gfvip07ao.com +gfvip07ap.com +gfvip07aq.com +gfvip07ar.com +gfvip07as.com +gfvip07at.com +gfvip08aa.com +gfvip08ab.com +gfvip08ac.com +gfvip08ad.com +gfvip08ae.com +gfvip08ag.com +gfvip08ah.com +gfvip08ai.com +gfvip08aj.com +gfvip08ak.com +gfvip08al.com +gfvip08am.com +gfvip08an.com +gfvip08ao.com +gfvip08ap.com +gfvip08aq.com +gfvip08ar.com +gfvip08at.com +gfxaa.com +gfxcamp.com +gfxtr1.com +gfxy.com +gfzihua.com +gfzj.us +gg-lb.com +gg-led.com +gg.com +gg122.net +gg1994.com +ggac.net +ggaiyan.com +ggas.com +ggbamy.com +ggbanfu.com +ggbondtech.com +ggbygx.com +ggcimbar.com +ggcj.com +ggcx.com +ggcykf.com +ggdata.com +ggecc.com +ggecgc.com +ggemo.com +ggeye.com +ggfsfy.com +ggfswy.com +ggg42.com +ggg868.com +gggcn.com +gggfyl.com +gggg5.com +ggghny.com +gggjs.com +gggqa.com +gggrp.com +gggua.com +gggwg.com +gggzhi.com +gggzpw.com +gghb.cloud +gghcgg.com +gghosp.net +gghs.info +gghualong.com +gghx120.com +gghy.org +gginto.com +ggjcpm.com +ggjpay.com +ggjrw.com +ggjstz.com +ggjszp.com +ggjt.com +ggjtfw.com +ggksw.com +ggkuai.com +ggl.com +gglenglish.com +gglkw.net +gglmg.com +ggmlechi.com +ggmm55.com +ggmsw.com +ggnqmy.com +ggo.net +ggoplay.com +ggowan.com +ggqule.com +ggqunshanmuye.com +ggqx.com +ggrcw.com +ggren.net +ggrsmy.com +ggrsrc.com +ggsfcw.com +ggshfmy.com +ggshmy.com +ggslxs.com +ggsq.cc +ggtime.com +ggtjx.com +ggtrj.com +ggttvc.com +ggunk1tn.com +ggwan.com +ggwan.net +ggweijie.com +ggwlxx.com +ggwxmuye.com +ggwzpf120.com +ggxarq.com +ggxdsmzx.com +ggxhx.com +ggxiaolinmy.com +ggxinzhitaimy.com +ggxjhk.com +ggxsjz.com +ggxue.com +ggxx.net +ggy.net +ggy775.com +ggyouyu.com +ggysc.com +ggysfw.com +ggytc.com +ggyx666.com +ggyy100.com +ggzbbj.com +ggzc.net +ggzgc.com +ggzha.com +ggzhaf.com +ggzs.me +ggzuhao.com +ggzx.net +gh-fm.com +gh-reagent.com +gh-shipping.com +gh8s.com +ghatg.com +ghboke.com +ghbxrj.com +ghc168.com +ghcec.com +ghcis.com +ghcxzb.com +ghddi.org +ghdoor.com +ghed119.com +ghedu.com +ghfdc.org +ghgglobal.com +ghglzx.com +ghgy.com +ghhyjc.com +ghibliwiki.org +ghitcsh.com +ghitest.com +ghjbh123.com +ghlawyer.net +ghlearning.com +ghlshb.com +ghlykj.com +ghmba.com +ghmcchina.com +ghmd448.com +ghmisnet.com +gho5.com +ghoffice.com +ghost-him.com +ghost008.com +ghost11.com +ghost32.net +ghost64.com +ghostchu.com +ghostoact.com +ghostsf.com +ghostwin7win8.com +ghostxp2.com +ghostxpsp3.net +ghostxx.com +ghoxz.com +ghparking.com +ghpepower.com +ghproxy.cc +ghpy3333.com +ghpym.com +ghrepower.com +ghrlib.com +ghs.net +ghschool.com +ghsd16888.com +ghsense.com +ghsmc.com +ghsmpwalmart.com +ght-china.com +ght120.com +ghtech.com +ghtianshancn.com +ghtt.net +ghturbine.com +ghtzgs.com +ghwgame.com +ghxi.com +ghxsw.com +ghyg.com +ghyhjsw.com +ghyl888.com +ghzhushou.com +ghzs.com +ghzs666.com +giabbs.com +giaimg.com +gialen.com +giant-china.com +giant-cycling-lifestyle.com +giantaircompressor.com +giantcdn.com +giantet.com +giantgd.com +giantkone.com +giao.me +gibcp.com +gicasa.com +giccoo.com +gicfg.com +gicp.net +gidepay.com +giecds.com +giexya.com +gif5.net +giffox.com +gifhome.com +gifshow.com +giftres.com +giftsbeijing.com +gifu-pr.com +giga-da.com +giga-science.com +gigaget.com +gigbl.com +gigpayroll.com +gihg.com +gihiji.com +giho.com +giihg.com +giikin.com +giiktop.com +giiso.com +gijsq.com +gildata.com +gilieye.com +giltbridge.com +giltworld.com +gimcyun.com +gimhoy.com +gimmgimm.com +gimoo.net +gimsh.com +gin-vue-admin.com +ginde.com +ginfon.com +gingerbreadstudio.cc +gingyan.com +ginlong.com +ginshio.org +ginwa.com +gio07231rp.com +gioccc.com +giomeru.com +gionee.com +gionee.net +gioneemobile.net +gioner.com +giordano.com +giorgiomorandihotels.com +giraff3.com +girdear.net +girl13.com +girls-frontline.com +girlsfighters.com +girlw.net +giscafer.com +giserdqy.com +gispark.org +gissaas.com +gissinggroup.com +gissky.net +gistc.com +git-repo.info +git-star.com +gitcafe.ink +gitclone.com +gitcode.com +gitcode.host +gitcode.net +gitee.com +gitee.io +githang.com +github-zh.com +githubim.com +githubshare.com +gitinn.com +gitiu.com +gitlib.com +gitmirror.com +gitnoteapp.com +gitom.com +gitpp.com +gitsea.com +gitshell.com +gitv.tv +gityuan.com +gityx.com +giveda.com +giyu8.com +gizaworks.com +gizwits.com +gj62.com +gjbaek.ren +gjcars.com +gjceshi9.com +gjcha.com +gjcoil.com +gjcweb.com +gjcxgs.com +gjdk100.com +gjds.vip +gjdwzp.com +gjfmxd.com +gjgzpw.com +gjhgroup.com +gjhl.com +gjj.cc +gjjcxw.com +gjjiaxiao.com +gjjnhb.com +gjjsbz.com +gjkdwl.com +gjl15.com +gjlease.com +gjmbwxpt.com +gjmbwxzx.com +gjmrk.com +gjnlyd.com +gjpdh.com +gjrwls.com +gjsj.com +gjsun.com +gjsy.org +gjtmu.com +gjtool.com +gjtt.net +gjw.com +gjw123.com +gjwca.org +gjwl123.com +gjwlyy.com +gjxh.org +gjxx.com +gjxzq.com +gjydz.com +gjyfish.com +gjyuxiang.com +gjyys.com +gjzfw.com +gjzy.com +gk-cn.com +gk-net.com +gk-z.com +gk.ink +gk.link +gk100.com +gk114.com +gk99.com +gkcyc.com +gkczgs.com +gkczp.com +gkfb.com +gkgzj.com +gkhxtc.com +gki88.com +gkjzy.com +gkket.com +gkkxd.com +gklx.net +gkmao.com +gkmems.com +gkmhq.com +gkmotor.com +gkong.com +gkoo.net +gkoudai.com +gkqcw.com +gkqxfsl.xyz +gkrpgtee.com +gkshanghai.com +gkshuju.com +gktianshanjd.com +gkwo.net +gkxd.com +gkxs.com +gkxx.com +gkyly.com +gkzhan.com +gkzj.com +gkzj.net +gkzpfw.com +gkzppt.com +gkzq.mobi +gkzqxc.com +gkzxw.com +gkzy.com +gkzy100.com +gkzyb.com +gkzzd.com +gkzzy.com +gl-data.com +gl-mes.com +gl-qf.com +gl-uav.com +gl-zj.com +gl102.com +gl114.net +gl170.com +gl17u.com +gl18.com +gl258.com +gl2mt.com +glab.online +glacierluo.com +gladcc.com +gladdigit.com +glafamily.com +glamever.com +glamourred.com +glamourtrains.com +glanimaltrade.com +glanu.com +glaproject.com +glasercom.com +glass-ciac.com +glassbottleproducer.com +glasseasy.com +glassmicro.com +glavo.site +glaway.com +glawyer.net +glb3.com +glb4.com +glb6.com +glbaishen.com +glbdns.com +glblkq.com +glby118.com +glbyhotel.com +glbyjdjt.com +glcablesy.com +glcanyin.net +glcape.com +glcct.com +glcht.com +glchunchao.com +glchuyun.com +glcits.com +glclcsy.com +glcszy.com +gldaewoo.com +gldjc.com +gleasy.com +glecan.com +glelec.com +gleyy.com +glface.com +glfangzhen.com +glfdfcyy.com +glflyy.com +glfpii.com +glfund.com +glfyjg.com +glgangyu.com +glgcsj.com +glgda.com +glgdst.com +glgeneng.com +glggh.com +glgh.org +glghy.com +glgnmt.com +glgsoft.com +glgst.com +glgtzc.com +glgyzn.com +glgzlq.com +glhcjs.com +glhckj.com +glhclv-kool.com +glhdq.com +glhfmy.com +glhfsy.com +glhmmr.com +glhnkj.com +glhospital.com +glhrzx.com +glhsylqx.com +glhtpcb.com +glhuade.com +glhuashi.com +glhuayue.com +glhycy.com +glhygjlxs.com +glhzhotel.com +glhzzx.com +glicon.design +glifegame.com +glinfo.com +glinkmedia.com +glinksure.com +gljcss.com +gljdjt.com +gljiatianxia.com +gljiayu.com +gljieli.com +gljinbao.com +gljinfeng.com +gljinhui.com +gljinshan.com +gljkfhq.com +gljlw.com +gljshy.com +gljshz.com +gljsjl.com +gljtkg.com +gljtxjy.com +gljygd.com +gljykj.com +gljyrj.com +gljzgs.com +glk7.com +glkgjt.com +glkths.com +gllcit.com +gllfyy.com +glljsh.com +glljy.com +gllshan.com +gllstz.com +glludiyan.com +gllue.com +gllue.me +gllue.net +gllxsb.com +gllycs.com +glmama.com +glmapper.com +glmayo.com +glmbc.com +glmingke.com +glmmodels.com +glncn.com +glnewstar.com +glo-slotsimulator.com +gloamingtechnology.com +global-dba.com +global-download.acer.com +global-harbor.com +global-idc.net +global-jf.com +global-ks-cdn.com +global-leader.com +global-otc.com +global-scsl.com +global-tio2.com +global56.com +globalaccentchinese.com +globalauthorid.com +globalbaike.com +globalbuy.cc +globalchangan.com +globalcho.com +globalesim.shop +globaletrust.com +globalgeopark.org +globalhardwares.com +globalimporter.net +globalizex.com +globalmil.com +globalnevs.com +globalpingbao.com +globalscanner.com +globalsigncdn.com +globalslb.net +globalso.com +globalso.site +globalsources.com +globalsourcingbiz.com +globalstech.com +globalston.com +globaltenpay.com +globaltradecoo.com +globalvisa888.com +globalx-nest.com +globebill.com +globecancer.com +globeedu.com +globrand.com +globusevents.com +glodon.com +glofang.com +glofiy.work +gloraledu.com +gloriahotels.com +gloriamedia.com +glorygarment.com +glorysoft.com +gloryview.com +glorze.com +glosellers.com +glosku.com +glosspp.com +glowapp.fun +glowapp.vip +glowoman.org +glpenhui.com +glplyf.com +glqh.com +glqshb.com +glquanji.com +glrcjob.com +glrcw.com +glreading.com +glredu.com +glriverside.com +glrmyy.com +glruixin.com +glsanhua.com +glsdhnt.com +glseed.com +glsgmr.com +glshimg.com +glsjf.com +glsmy024.com +glssgolf.com +glsstm.com +glsxdlkj.com +glsxr.com +glsyjd.com +glsyjgs.com +glsytzjt.com +glt365.com +gltop.com +gltsg.com +gltvs.com +gltx.tech +gltzjt.com +gluebon.com +glumes.com +glvroc.com +glvs.com +glwangcheng.com +glwuhong.com +glwxw.net +glwyhd.com +glxcc.net +glxcjt.com +glxd.com +glxhzs.com +glxiaoyaohu.com +glxinhu.com +glxkbz.com +glxsyx.vip +glxwdb.com +glxxjx.com +glxyjx.com +glxyrn.com +glyhjc.com +glyhy.com +glyjk.com +glylgg.com +glyltl.com +glyndwrsway.com +glyphara.com +glyslydjq.com +glyummy.com +glyxc.com +glyxjtgc.com +glz8.com +glzcqy.com +glzdgx.com +glzeasun.com +glzfst.com +glzh-szzx.site +glzhcyy.com +glzhealth.com +glzip.com +glzizhu.com +glzj88.com +glzmn.com +glzrflx.com +glzsjc.com +glzthz.com +glztj.com +glzx.net +glzyjt.com +glzzjy.com +gm-scm.com +gm016.com +gm193.com +gm3.win +gm35.com +gm3studio.com +gm825.com +gm825.net +gm86.com +gm88.com +gm99game.net +gmacsaic.com +gmacsaic.net +gmanhua.com +gmatg.com +gmaxbiopharm.com +gmbbs.net +gmbuluo.com +gmcc.net +gmcinnov.com +gmcmonline.com +gmdeng.com +gmdt9b.com +gmdun.com +gmecn.com +gmed.cc +gmedata.com +gmeditech.com +gmedtech.com +gmem.cc +gmeri.com +gmerit.com +gmertc.com +gmfc.cc +gmfintl.com +gmg.so +gmgc.info +gmgitc.com +gmhub.com +gmhuijin.com +gmhysj.com +gmi1001.com +gmilesquan.com +gmiot.net +gmjk.com +gmm01.com +gmmicro.com +gmmsj.com +gmmtcc.com +gmoe.cc +gmoj.net +gmonline-all.com +gmpbj.com +gmqd.com +gmquickapp.com +gmrmyy.com +gmsec.net +gmsolid.com +gmssl.org +gmsyun.com +gmt-china.org +gmt-cn.com +gmtacoa.com +gmtv.cc +gmtzy.com +gmugmu.com +gmw.com +gmwiki.com +gmxmym.ren +gmya.net +gmyihua.com +gmylj.com +gmz88.com +gmzhushou.com +gmzi.com +gmzm.org +gmzp.net +gmzx.com +gn168.com +gn301.xyz +gnber.com +gncebest88.com +gndaily.com +gndown.com +gneec.com +gneec3.com +gneec4.com +gneec5.com +gneec7.com +gneeccloud.com +gneedu.com +gnehr.com +gnete.com +gnetis.com +gnetpg.com +gng92.com +gngnk.com +gnhome.com +gnhpc.com +gnice-it.com +gnict.com +gninstruments.com +gnitif.com +gnlearn.com +gnnzfw.com +gnrcbank.com +gnrnye.com +gnrtv.com +gnsschips.center +gnssinfo.com +gnssopenlab.org +gnt8.com +gnvip.net +gnway.cc +gnway.com +gnway.org +gnzad.com +gnzrk.com +go-admin.com +go-behind.one +go-gddq.com +go-goal.com +go.cc +go007.com +go108.com +go1314.com +go2aaron.com +go2eu.com +go2map.com +go2yd.com +go300.com +go5kvsiay5wx.com +goalchina.net +goalhi.com +goalmapapp.com +goalonez.site +goapk.com +gobanma.com +gobasearcher.com +gobelike.net +gobivc.com +gobroadhealthcare-sh.com +gobroadhealthcare.com +gobyd.com +gocarjourney.com +gocashback.com +gocchina.com +gocdn.cc +gocea.net +goceshi.com +goclee.com +gocn.vip +godaily.org +godasai.com +godbiao.com +godblessrail.com +godblessyuan.com +goddelivery.com +goddessxzns.com +godele.com +godgy.xyz +godic.net +godida.com +godo.pub +godoor.com +godotcn.com +godsendcn.com +godsheepteam.com +godsignal.com +godweiyang.com +godwolf.com +goeasy.io +goelia1995.com +goepe.com +goertek.com +goetheslz.com +gofarqzyy.com +goforandroid.com +goframe.org +gofreeplay.com +gofrp.org +gog-cdn-fastly.gog.com +gog-cdn.akamaized.net +gogalaxy.gog-statics.com +gogbuy.com +goglew5sn.com +gogo.so +gogo123.com +gogo123.net +gogoauc.com +gogocn.com +gogofly.com +gogokid.com +gogolinux.com +gogooffer.com +gogoqq.com +gogoup.com +goherbalfood.com +gohighfund.com +goho.co +gohoedu.com +gohomesafe.org +gohomesh.com +gohong.com +going-link.com +gojiaju.com +gojira.net +gokaigai.com +goke.com +gokemicro.com +gokols.com +gokuai.com +golahsg.com +golang8.com +golangapi.com +golanger.com +golangroadmap.com +golangw.com +golaravel.com +gold-dragon-castings.com +gold-seagull.com +gold-v.com +gold58.com +gold678.com +goldav.net +golday666.com +golday999.com +golday9999.com +goldbj.com +goldbox.vip +golden-bamboo.com +golden-book.com +golden-infor.com +golden-soft.com +golden-spri.com +golden3t.net +goldenad.net +goldenbeechina.com +goldenear.club +goldenexpogroup.com +goldengoosee.com +goldengreengolf.com +goldenhighway-chem.com +goldenholiday.com +goldenhome.cc +goldening.com +goldenken.com +goldenladies.com +goldenname.com +goldennumis.store +goldenseaair.com +goldentec.com +goldenthroat.com +goldentom.com +goldfoil.com +goldgov.com +goldgrid.com +goldhoe.com +goldksoft.com +goldlion-china.com +goldlion-info.com +goldmadon.com +goldmantis.com +goldmarkrealestate.com +goldmt.net +goldstone-group.com +goldstone-investment.com +goldstonepack.com +goldsunchn.com +goldsunmachinery.com +goldsupplier.com +goldvole.com +goldwaterhk.com +goldwind.com +golenpower.com +golfvv.com +golink.com +golinkapi.com +golinkcn.com +golinkgroup.com +golinksworld.com +golive-tv.com +golivetv.tv +goluckcity.com +goluckyvip.com +golue.com +gomaeps.com +gomanlift.com +gomeart.com +gomecloud.com +gomegj.com +gomeholdings.com +gomehome.com +gomeplus.com +gomo.com +gomocdn.com +gomvyxvm.com +gona-semi.com +gonever.com +gong-xin.com +gong123.com +gongao.net +gongbaike.com +gongbi.net +gongbiaoku.com +gongboshi.com +gongcdn.com +gongchang.com +gongcheng168.com +gongchengbing.com +gongchengjn.com +gongchou.com +gongchu.com +gongfubb.com +gongfudou.com +gongji58.com +gongjiao.com +gongjiao160.com +gongjiaomi.com +gongjiyun.com +gongju.com +gongju5.com +gongjux.com +gongkaohub.com +gongkaoleida.com +gongkaowo.com +gongkong.com +gongkong001.com +gongkongbpo.com +gongkongedu.com +gongkongjia.com +gongkongke.com +gongkongmall.com +gongkongsaas.com +gonglchuangl.net +gonglf.com +gonglve.net +gongmo1688.com +gongmutang.com +gongnou.com +gongpin.net +gongpingjia.com +gongqiu.biz +gongshang120.com +gongshiku.com +gongsibao.com +gongsijiaoyi.com +gongsizhang.com +gongsizhijia.com +gongwuxing.com +gongxiangcj.com +gongxiao8.com +gongxiaodaji.com +gongxuanwang.com +gongxueyun.com +gongye360.com +gongyefengshan.com +gongyeku.com +gongyelian.com +gongyeyun.com +gongyeyunwang.com +gongyi.la +gongyi.net +gongyi.xin +gongyichuangyi.net +gongyicn.org +gongyidaily.com +gongying405.com +gongyingshang.biz +gongyingshi.com +gongyipuhui.com +gongyishibao.com +gongyou.com +gongyouhui.com +gongyoumishu.com +gongzhao.net +gongzhao.work +gongzhou.com +gongzhou.net +gongzhun.com +gongzicp.com +gongzufudinzu.com +gongzuobaogao.xyz +gongzuoshouji.net +gongzuoyun.org +gonsun.com +gonvvama.net +gonxt.com +gonyn.com +goo17.com +gooagoo.com +gooann.com +goobai.com +goobye.net +good-display.com +good-expo.com +good-import.com +good.cc +good1230.com +good321.net +good519.com +goodacc.net +goodally.hk +goodao.net +goodapk.com +goodbaby.com +goodbabygroup.com +goodbaike.com +goodcang.com +goodcloud.xyz +gooddr.com +gooddu.com +goode-china.com +goodealwigs.com +goodeeis.com +goodesocket.com +goodfamily.cc +goodfamily.com +goodgongshi.com +goodgupiao.com +goodid.com +goodix.com +goodjd.com +goodjili.com +goodjob100.com +goodk88.com +goodkejian.com +goodlcm.com +goodlift.net +goodluckcalendar.com +goodmorening.com +goodnic.net +goododo.com +goodonecn.com +goodprogrammer.org +goodqq.net +goodrain.com +goodread.com +goodschool.world +goodsid.com +goodsku.com +goodstudydayup.com +goodtea.cc +goodtech.live +goodtp.com +goodwe.com +goodwillcis.com +goodwillresource.com +goodwyee.com +goodyoungtea.com +goofish.com +googe.ink +googoc.com +googol-power.com +googolpark.com +googvv.com +goolemall.com +goolink.org +goome.net +goomj.com +goonemei.com +gooo8.com +goooc.net +gooogua.com +gooooal.com +gooood.hk +goootech.com +goootu.com +goopush2025.com +gooray.com +goosai.com +goosail.com +gooseeker.com +gootho.com +gootoai.com +goowine.com +gooxi.com +gooyo.com +goozp.com +gopedu.com +gopeed.com +goplaycn.com +gopos.hk +goproxy.cc +goproxy.io +gorebuy.com +goregxa.com +gorichox.com +gorouter.info +gorse.com +gortune.com +gosailgis.com +goselling.com +goshijia.com +goshopjp.com +gosinoic.com +goskygroup.com +gosonly.com +gospelwin.com +gost-pct.com +gosun.com +gosun.ltd +gosuncdn.com +gosuncdn.net +gosuncn.com +gosunm.com +got001.com +got002.com +gotechcn.com +gotechina.com +goten.com +gothe3.com +goto-game.com +goto-game.mobi +goto-game.net +goto-game.org +gotobath.com +gotocdn.com +gotocoding.com +gotodn.com +gotofreight.com +gotohui.com +gotohz.com +gotohzrb.com +gotoip.net +gotoip1.com +gotoip11.com +gotoip2.com +gotoip3.com +gotoip4.com +gotoip88.com +gotokeep.com +gotolink.net +gotonav.com +gotonets.com +gotopsoft.com +gotostudyroom.com +gotoubi.com +gotozhuan.com +gotran.com +gotvg.com +gou.com +goubrand.com +gouchezj.com +goufang.com +goufw.com +gougoujp.com +gouguoyin.com +gouhai.com +gouhao.com +gouhaowang.com +gouhuasuan.shop +goujianwu.com +goukk.com +goukuai.com +goulegu.com +goulew.com +goulong.com +goumee.com +goumin.com +goupautomation.com +goupsec.com +goupuzi.com +gourmet114.com +goushh.com +gouso.com +gousu.com +goutanzi.com +gouwanmei.com +gouwo.com +gouwudang.com +gouwuke.com +gouwule.com +gouwuyu.com +gouyoukeji.com +gov-static.tech +govagroup.com +govfz.com +govisionox.net +govjc.com +govmade.com +govqcloud.com +govuln.com +govwq.com +gowan8.com +goweb1.cc +goweb2.net +goweb3.net +goweike.net +gowinamc.com +gowincms.com +gowinlease.com +gowlc.net +gowmo.com +gowonganinn.com +goww.net +goxytrbz.com +goyihu.com +goyoo.com +gozap.com +gozongroup.com +gozyq.com +gp-tm.com +gp1903.com +gp1907.com +gp241.com +gp259.com +gp451.com +gp51.com +gp88888.com +gp891.com +gpai.net +gpall.net +gpautobid.com +gpb-hls.streamguys1.com +gpbbs.net +gpbeta.com +gpboke.com +gpcang.com +gpcqjy.com +gpd.hk +gpdi.com +gper.club +gpetrip.com +gpfang.net +gpgwx.com +gpl-express.com +gplayspace.com +gplqdb.com +gplus-lab.com +gpmii.net +gpmro.com +gpmycez.com +gpnewtech.com +gpost-ge.cfd +gpowersoft.com +gppapp.com +gpqnrc.com +gps009.net +gps010.net +gps123.org +gps16888.com +gpsbao.com +gpsgx.net +gpslook.net +gpsonextra.net +gpsoo.net +gpsov.com +gpspw.net +gpsrcw.com +gpsspg.com +gpstool.com +gpsuu.com +gpszlsc.com +gpticket.org +gptkong.com +gpubgm.com +gpuez.com +gpuztrvt.com +gpxiv5kew4mvk.com +gpxxz.com +gpxygpfx.com +gpxz.com +gpxzw.com +gpyck.com +gpydxl.com +gq-rose.com +gq60.com +gqbmt.com +gqget.com +gqgkj.com +gqhmt.com +gqjd.net +gqjtgs.com +gqjx.net +gqk.tv +gqprgkr.com +gqpyh.com +gqqsm.com +gqsj.cc +gqsoso.com +gqsyk.com +gqsym.com +gqt168.com +gqxtq.com +gqzewmsk8yma18.com +gr-hospital.com +gr3xuaov74khb.com +gra-moissanitesorg.com +grab4k.com +grablan.com +grabsun.com +grace2015.site +gracece.com +graceelectron.com +gracelaser.com +gracg.com +gradaimmi.com +gradgroup.com +gradgroup.net +graduallylift.com +grafytek.com +grainedu.com +grainstorage.net +grand-tec.com +grandcitytours.com +granddongshan.com +grandee-elevator.com +grandelazio.com +grandhopebio.com +grandinsight.com +grandioes.com +grandkol.com +grandlisboa.com +grandlisboapalace.com +grandloong.com +grandomics.com +grandordesign.com +grandpharm.com +grandqueen.com +grandskylightgardenshenzhen.com +grandskylightshenzhenguanlan.com +grandwaylaw.com +grapchina.org +graphene.tv +graphmovie.com +graphmovies.com +grass98.com +grassmoon.net +graueneko.xyz +gravity-engine.com +graz.quest +grcbank.com +grchina.com +grcwzx.com +great-future.com +greatagroup.com +greatbit.com +greatesting.com +greathink.com +greatld.com +greatoo.com +greatopensource.com +greatops.net +greatopt.com +greatpowercn.com +greatran.com +greatroma.com +greatsk.com +greatsoftman.com +greatsolid.com +greatssp.com +greatstargroup.com +greatstartools.com +greatwallmusic.com +greatwuyi.com +gredmedic.com +gree-jd.com +gree.com +greebox.com +greedc.com +greedongaohotel.com +greefinance.com +greejt.com +green-cpc.com +green-holdings.com +green-sh.com +green12306.com +greencharm.com +greenchengjian.com +greencompute.org +greendh.com +greenism.net +greenits.net +greenlandcn.com +greenlandsc.com +greenpine.cc +greenswolf.com +greentomail.com +greentownchina.com +greenvalleypharma.com +greenwater.cc +greenwaychina.org +greenwicher.com +greenwood-park.com +greenxf.com +greenxiazai.com +greepi.com +greeyun.com +grender.com +greplay.com +grescw.com +gretf.com +greyli.com +greywolfcdn.net +greywolffast.com +greywolfns.com +grfexpo.com +grfyw.com +grg2013.com +grgaoren.com +grgbanking.com +grgreecv.com +grgroup.cc +grgsecurity.com +grgtest.com +grgvision.com +grgyintong.com +grid2048.com +gridsum.com +gridy.com +grikin.com +grinm.com +grirem.com +gritgen.com +gritpharma.com +grjzjt.com +grksc.com +grmxdy.com +grnuo.com +groad.net +gronhi.com +groovymedicine.com +grouk.com +groundsun.com +group-purchasing.com +group-spl.com +group-wenyuan.com +groupfangyuan.com +grouphx.com +groupjh.com +groupjx.com +grouplus.com +groupshenxi.com +growatt.com +growful.com +growth.ai.srv +growthbox.net +grpindex.com +grria.net +grs-syphu.com +grspet.com +grstz.com +grt-china.com +grtrelay.com +grtsports.com +grumplesgroup.com +gruntjs.net +gruposeimex.com +grxxw.com +gryltop.com +gryphline.com +gryu.net +gryw666.com +grzmz.com +grzq.com +gs-cdn.com +gs090.com +gs12122.com +gs14.com +gs1cn.org +gs2.ww.prod.dl.playstation.net +gs6699.com +gsadds.com +gsafc.com +gsafety.com +gsaxns.com +gsbankchina.com +gsbankmall.com +gscaishui.com +gscblog.com +gscdn.pub +gschaos.club +gscidc.net +gsdk.tv +gsdpw.com +gsdswz.com +gsdtfx.com +gsdyjsgs.com +gseen.com +gsensebot.com +gsfilter.net +gsflcp.com +gsfrj.com +gsfybjy.com +gsfycloud.com +gsfzb.com +gsgltz.com +gsgs10086.com +gsgundam.com +gshangju.com +gshis.net +gshmhotels.com +gshmzs.com +gshopper.com +gshqqcx.shop +gshrgroup.com +gsi24.com +gsicpa.net +gsidy.com +gsjb.com +gsjkjt.com +gsjqtv.com +gsjt-cn.com +gsjt56.com +gsjtky.com +gskaiwei.com +gskfzxyy.com +gskjpt.com +gsktraining.com +gskwai.com +gsl.cc +gslbauto.com +gslbdns.com +gslbdns.net +gslmw.net +gsmpers.com +gsmuban.com +gsnhcg.com +gsnytz.com +gspaceteam.com +gspst.com +gspt.com +gspxonline.com +gsqstudio.com +gsrc.com +gsrcb.net +gsrcu.com +gsrcw.com +gsrecv.com +gsrl.net +gsrwfyy.com +gss56.com +gssag.com +gssbh.com +gssey.com +gsshylsh.com +gssjyxrmyy.com +gsskyst.com +gssltxrmyy.com +gsslxh.com +gsstargroup.com +gsstic.com +gsstock.com +gsstsdgs.com +gsswtz.com +gst-china.net +gst.prod.dl.playstation.net +gstarcad.com +gstatic-cn.com +gsthq.com +gstonegames.com +gstsz.com +gstzyyy.com +gswjxjzx.com +gswljt.com +gswz.com +gsx009.com +gsxb.net +gsxcdn.com +gsxetc.com +gsxgw.com +gsxservice.com +gsxtj.com +gsydxzyy.com +gsysportwear.com +gsyth.com +gsyxjyw.com +gsyygh.com +gszhaopin.com +gszlyy.com +gszph.com +gszq.com +gszsc.com +gszybw.com +gszyi.com +gszytcm.com +gszyy.com +gt-generator.com +gt-oil.com +gt-semi.com +gt47xc.com +gt520.com +gtac.cc +gtadata.com +gtajl.com +gtan.com +gtaos.com +gtarcade.com +gtarsc.com +gtastart.com +gtaxqh.com +gtbuy.work +gtc-power.com +gtcedu.com +gtcfla.net +gtcfzp.com +gtcim.com +gtd-china.com +gtder.club +gtdgc.com +gtdlife.com +gtdreamlife.com +gtdsc.com +gter.net +gtetern.com +gtfund.com +gtg56.com +gtgqw.com +gtgres.com +gtht.com +gthzc.com +gti56.com +gtibee.com +gtig-esen.com +gtig.com +gtiggm.com +gtimg.com +gtinno.com +gtja-allianz.com +gtja.com +gtjadev.com +gtjaqh.com +gtjazg.com +gtjgzt.com +gtjiaoyu.com +gtjt.com +gtk-china.com +gtkj.tech +gtkl.net +gtlggy.com +gtlrxt.com +gtm-a1b2.com +gtm-a1b3.com +gtm-a1b4.com +gtm-a1b5.com +gtm-a1b6.com +gtm-a1b7.com +gtm-a1b8.com +gtm-a1b9.com +gtm-a2b2.com +gtm-a2b3.com +gtm-a2b4.com +gtm-a2b5.com +gtm-a2b6.com +gtm-a2b7.com +gtm-a2b8.com +gtm-a2b9.com +gtm-a3b1.com +gtm-a3b3.com +gtm-a3b4.com +gtm-a3b5.com +gtm-a3b6.com +gtm-a3b7.com +gtm-a3b8.com +gtm-a3b9.com +gtm-a4b1.com +gtm-a4b2.com +gtm-a4b3.com +gtm-a4b4.com +gtm-a4b5.com +gtm-a4b6.com +gtm-a4b7.com +gtm-a4b8.com +gtm-a4b9.com +gtm-a5b1.com +gtm-a5b2.com +gtm-a5b3.com +gtm-a5b4.com +gtm-a5b5.com +gtm-a6b1.com +gtm-a6b2.com +gtm-a6b3.com +gtm-a6b4.com +gtm-citycloud.com +gtm-host.com +gtm-i1d1.com +gtm-i1d2.com +gtm-i1d6.com +gtm-i1d7.com +gtm-i1d8.com +gtm-i1d9.com +gtm-i2d3.com +gtm-i2d4.com +gtm-i2d6.com +gtm-i2d8.com +gtm-i2d9.com +gtm-we.com +gtm.oasisfeng.com +gtm.pub +gtmlufax.com +gtmsh.com +gtn9.com +gtobal.com +gtphotonics.com +gtpso.com +gtqzg.com +gtradedata.com +gtrukxeo.com +gts.work +gtshebei.com +gtsnzp.com +gttctech.com +gttxidc.com +gtuanb.com +gtuu.com +gtwrmdxo.com +gtx-sh.com +gtxf.com +gtxh.com +gtxp2.com +gtycn.net +gtyztpt.com +gtzlw.com +gtzszy.com +gtzxhk.com +gtzxsg.com +gtzy123.com +gu166.com +gu360.com +gua123.com +guabu.com +guaguay.com +guahao-inc.com +guahao.com +guahao114.com +guahaoe.com +guahaowang.com +guaiguai.com +guaihou.com +guaiku.com +guaileicp.com +guaili.org +guailuo.com +guailuzi.com +guaitao.cc +guaixun.com +guajibao.club +guajibao.me +guajibaola.com +guakaoba.com +guan-shi.com +guan.com +guan5.com +guanaitong.com +guance.com +guanchangnongmu.com +guanchao.site +guanchiad.com +guancibaoku.com +guandan.com +guandan.mobi +guandan888.com +guandang.net +guandata.com +guandianle.com +guang-yuan.com +guang.com +guangbali.com +guangbao-uni.com +guangbo.net +guangbogroup.com +guangcimh.com +guangdamr.com +guangdauser.com +guangdianyun.tv +guangdiu.com +guangdong-hotel.com +guangdong1039.com +guangdonggames.com +guangdonglianxing.com +guangdonglong.com +guangdongrc.com +guangdongtianxi.com +guangdongwater.com +guangdongyunchen.com +guangdv.com +guangfan.com +guangfeng.com +guangfulingyuan.com +guanggao.com +guanghan-marathon.com +guanghe.tv +guanghuayigou.com +guanghui.com +guangjie5u.com +guangjieba.com +guangjiela.com +guangjinghb.com +guangjipharm.com +guangjiubusiness.com +guangjiucompany.com +guangju123.com +guangjuke.com +guangka.com +guangkatf.com +guangli88.com +guanglikou.com +guanglilvyuan.com +guanglingroup.com +guanglongsoft.com +guangming.com +guangmintou.com +guangnengquan.com +guangraoluntan.com +guangruijixie.com +guangsai.cc +guangshaxy.com +guangshenghang.com +guangsuan.com +guangsuss.com +guangte-ne.com +guangtuikeji.com +guanguigroup.com +guanguser.com +guangwaifu.com +guangwei.com +guangxi910.com +guangxibiaoxie.com +guangxicarbon.com +guangxichunhui.com +guangxigames.com +guangxiguozhi.com +guangxihaihui.com +guangxihongji.com +guangxijiazhi.com +guangxijinhang.com +guangxilindakejimeiliyaoshang.com +guangxilonghua.com +guangxima.com +guangximinhang.com +guangxinengyuan.com +guangxipubeihuaheng.com +guangxircw.com +guangxishangfu.com +guangxishuizhiyangzhigongsi.com +guangxisichujiadao.com +guangxixinchan.com +guangxixinyan.com +guangxixinyuwanzixun.com +guangxiyijie.com +guangxizbq.com +guangxizhonghui.com +guangxizhutingqi.com +guangxunsd.com +guangya-group.com +guangyapan.com +guangyi.net +guangyinghj.com +guangyuancare.com +guangyuangroup.com +guangyuanjt.com +guangyuanmarathon.com +guangyuhb.com +guangyv.com +guangzhitui.com +guangzhou-logistics.com +guangzhou-marathon.com +guangzhouamc.com +guangzhoudazhong.com +guangzhougy.com +guangzhouxiehe.com +guangzhouyibo.com +guangzhouzaiyu.com +guanhaiwei.com +guanhaobio.com +guanhejx.com +guanhou.com +guanhuaju.com +guanjiajf.com +guanjunjg.com +guankou.net +guanlannet.com +guanli360.com +guanlixi.com +guanliyun.com +guanmeikj.com +guannews.com +guanngxu.com +guanpark.com +guanpindiaosu.com +guanquanapp.com +guanrenjiaoyu.com +guanshanbaodian.com +guanshang1998.com +guanshangyu.cc +guanshenggz.com +guansong.com +guansre.com +guantao.com +guanting.com +guanvip8.com +guanwang.cc +guanwang.com +guanwangbao.com +guanwangdaquan.com +guanwangshijie.com +guanwangyun.com +guanwuxiaoer.com +guanxf.com +guanxian.org +guanxiaokai.com +guanxingyun.com +guanxintec.com +guanxxg.com +guanyezipper.com +guanyierp.com +guanyinshan.com +guanyiyun.com +guanzhongrc.com +guanzhu.mobi +guanzhulian.com +guanzhunet.com +guanziheng.com +guapaijia.com +guardease.com +guardrailchina.com +guatedu.com +guatuwang.com +guazhuan.com +guazi-apps.com +guazi.com +guazi.net +guazi75637736.cc +guazipai.com +guazistatic.com +guazixs.com +guba.com +guba163.com +gubaike.com +gubo.org +gucciblog.net +guccistar.com +gucheng.com +guchengnews.com +guchengxiangye.com +gucihand.com +gucn.com +gucun.info +gucunpark.net +guczkbdq.com +gudeapp.com +gudemanage.com +gudianwenxue.com +gudongtech.com +gufengmh9.com +gufenxueshu.net +gug66.com +gugeapps.net +gugexs.com +gugezg.com +gugong.net +gugu.fun +gugu5.com +gugu6.com +gugud.com +gugudang.com +guguread.com +gugushuzi.com +guguyu.com +guguyun.com +guguyuyin.com +guguzhu.com +guhantai.com +guhei.net +guheshuyuan.com +guhuozaiol.com +gui333.com +gui66.com +guibi.com +guicaiyun.com +guichanghj.com +guichuideng.com +guichuxing.com +guidecari.com +guidechem.com +guideir.com +guideofsh.com +guiderank-app.com +guifan.cc +guifancha.com +guifanku.com +guifeng.net +guifun.com +guigang688.com +guigu.org +guigushi2.com +guihaikj.com +guihejr.com +guihua.com +guihuangfood.com +guihuayun.com +guiji.com +guijingchina.com +guijinshu.com +guijitech.com +guijob.com +guikai888.com +guikangmaterials.com +guikuan.com +guilinaohu.com +guilincyjt.com +guilinhd.com +guilinhengda.com +guilinihg.com +guilinjiaqi.com +guilinjizhuangxiang.com +guilinlife.com +guilinlv.com +guilinoutdoor.com +guilinpharma.com +guilinruntai.com +guilinsongyu.com +guilintianhu.com +guilintravel.com +guilinzhiyuan.com +guiluohuang.com +guimamuye.com +guimengjob.com +guimengning.com +guimengshangeng.com +guinsoft.com +guipeibao.com +guipin.com +guiqingkeji.com +guiqv.com +guirong.com +guiscn.com +guishangtong.com +guishanhotel.com +guishequ.com +guisteel.com +guitan.com +guitang.com +guitang.fun +guitarq.com +guitongmy.com +guitu18.com +guiwang.org +guiweilian.com +guixiaozi.com +guixue.com +guiyangmarathon.com +guiyingclub.net +guiyuhuanbao.com +guiyuntai.com +guizeco.com +guizheng.net +guizhenghe.com +guizhenwei.com +guizhougames.com +guizhougas.com +guizhoushengyang.com +guizhutanglao.com +guj6.com +gujianba.com +gujing.com +gujinshici.com +gujiushu.com +gujiyx.com +gukaculture.com +gukaifu.com +gukaihu.com +gukun.com +gulandscape.com +guliem.com +gulinglong.com +gulinrongmei.com +gullmap.com +gulltour.com +gulongbbs.com +gulove.com +gulu.tv +gulu001.com +gulugj.com +gululu.com +guluyou.com +gumade.com +gumang.com +gumaor.com +gumeng.net +gumiji.com +gumingnc.com +gumo.pro +gumodels.com +gumpmall.com +gundambattle.com +gunshitech.com +gunsuo.com +guo-kai.com +guo7.com +guo98.com +guoanaz.com +guoanclub.com +guoanele.com +guoanqi.com +guoanwine.com +guoaoqiyuan.com +guobaihui.com +guobaoyou.com +guobiao99.com +guobiaotest.com +guobin120.com +guoboshi.com +guocaipps.com +guocaiqinghai.com +guocar.com +guochaos.com +guocool.com +guocuijingju.com +guodashi.com +guodatzjt.com +guodegang.org +guodi.net +guodiana.com +guodingnet.com +guodongbaohe.com +guodongtech.com +guodongtechnology.com +guodouw.com +guodu.com +guodu.hk +guodushidai.com +guofanglab.com +guofen.com +guofenchaxun.com +guofenchaxun.net +guofeng.com +guofenkong.com +guogongxin.com +guoguangmold.com +guoguo-app.com +guoguojie.com +guohanlawfirm.com +guohaokeji.com +guohongxin.com +guohu360.com +guohua88.com +guohuapharm.com +guohuarf.com +guohuayule.com +guoing.com +guoji.biz +guoji.pro +guojiang.tv +guojianglive.com +guojiayikao.com +guojiayixuekaoshi.com +guojiazhiyezige.com +guojidaigou.com +guojiexpress.com +guojijinjia.com +guojimami.com +guojing-tech.com +guojiseka.com +guojiwuye.com +guojixiao.com +guojixuexiao.net +guojixuexiao.org +guojiyujiaxueyuanzongbu.com +guojizhanlanhui.com +guojj.com +guojusoft.com +guokang.com +guokelonghui.com +guoketest.com +guokeyun.com +guokongqixie.com +guokr.com +guokr.io +guokr.net +guoku.com +guolaiwanba.com +guolan.com +guolannewmaterial.com +guole.fun +guoli.com +guolianchem.com +guolianglab.org +guolin.tech +guolisec.com +guolong365.com +guolongplastic.com +guoluonews.com +guolv.com +guolv.net +guomai.cc +guomaoreducer.com +guomeijiayuanxiaoxue.com +guomeikuaidi.com +guomiaokeji.com +guomin999.com +guominpension.com +guomu.com +guoocang.com +guopeiwang.com +guopika.com +guoping123.com +guopop.tech +guoqi.org +guoqi365.com +guoqinwang.com +guorongfei.com +guoruijx.com +guoshengtech.com +guoshi.com +guosujt.com +guotaijsh.com +guotailiangyou.com +guotangauto.com +guotongglobal.com +guoturen.com +guotv.com +guowai.org +guoweijt.com +guoweistem.com +guoweitong.com +guowuwushu.com +guoxiehao.com +guoxikonggu.com +guoxinbj.com +guoxinlanqiao.com +guoxinmac.com +guoxinqh.com +guoxintek.com +guoxue.com +guoxue123.com +guoxuedashi.com +guoxuemeng.com +guoxuemi.com +guoxuwang.com +guoyang.cc +guoyang.work +guoyangtech.com +guoyc.online +guoyice.com +guoyihuake.com +guoyitang.org +guoyu.com +guoyue.games +guoyuegroup.com +guoyuejituan.com +guoyunjc.com +guoyusec.com +guoyutec.com +guozaoke.com +guozh.net +guozhangroup.com +guozhanjiaoyu.com +guozhen.net +guozhenyi.com +guozhivip.com +guozhuan.com +guozhuangxincai.com +guozi.org +guoziyx.com +guozucq.org +gupang.com +gupaoedu.com +gupei.com +gupen.com +gupiao135.com +gupiao168.com +gupiao8.com +gupiaoq.com +gupiaowajue.com +gupowang.com +gupt.net +gupuu.com +gupzs.com +guqiankun.com +guqiu.com +guqu.net +guronge.com +gurukeji.com +gushengwang.com +gushequ.com +gushi.ci +gushi.com +gushi160.com +gushi365.com +gushiai.com +gushici.com +gushicimingju.com +gushidaquan.cc +gushidi.com +gushiji.cc +gushiju.net +gushiwen.org +gusspro.com +gusucaishui.com +gusuwang.com +guteke.com +gutlighting.com +gutou.com +gutousoft.com +gutx.org +guwan.com +guwantj.com +guweimin.com +guwendao.net +guwenxs.com +guwenxuexi.com +guwu121.com +guxiang.com +guxunw.com +guyizisha.com +guyuehe.com +guyuehome.com +guyuenglish.com +guyungame.com +guzhang.com +guzhangting.com +guzhenm.com +guzhongtrade.com +guzuci.com +guzwiayz.com +gvcr9zaemdzh.com +gvg-redsun.com +gvgoo.com +gvi-tech.com +gvlocalization.com +gvmocpc.com +gvoiceplat.com +gvt2-cn.com +gvwyuik.com +gw-ec.com +gw.craft.moe +gw4.cc +gw66.vip +gwacoe.com +gwamcc.com +gwauto.com +gwbfc.com +gwblighting.com +gwc.net +gwcdncloud.com +gwdang.com +gwdqsb.com +gwdzkj.com +gweike.com +gwell.cc +gwenorcasv1.com +gwepy.org +gwetech.com +gwfls.com +gwfx.net +gwgl168.com +gwgsc.com +gwi.cc +gwidc.com +gwin-cn.com +gwinbody.com +gwjakzzx.com +gwjinan.com +gwkvepgc.com +gwm-global.com +gwmapp-h.com +gwmapp-w.com +gwmfc.com +gwmmarathon.com +gwmsoft.com +gwnsxx.com +gwnz.com +gworg.com +gwozai.com +gwpdi.com +gwpp.net +gwpstools.com +gwrcw.com +gwsdns.com +gwtt.com +gwvpsceping.com +gwwg.com +gwxeda.com +gwy.com +gwyclass.com +gwyoo.com +gwyou.com +gwypxw.com +gwysydw.com +gwyzk.com +gwyzwb.com +gwzft.com +gwzhinan.com +gwzwfw.com +gwzyxh.com +gx-antai.com +gx-aozhan.com +gx-biosensor.com +gx-ds.net +gx-etrans.com +gx-hengyuan.com +gx-hm.com +gx-lc.com +gx-newmedia.com +gx-royalpartners.com +gx-stbd.com +gx-wl.com +gx-xc.com +gx-xjyx.com +gx-yidaiyilu.com +gx-zy.com +gx10010.com +gx121.com +gx12333.net +gx12580.net +gx163.com +gx1g.com +gx3j.net +gx4485.com +gx5127.com +gx516.com +gx51766.com +gx5f.com +gx79.com +gx81jxzl.com +gx966888.com +gxaas.net +gxabd.net +gxacjs.com +gxacto.com +gxadt.com +gxadwh.com +gxaedu.com +gxahjy.com +gxaids.com +gxairlines.com +gxaist.com +gxaixier.com +gxalt.com +gxanchen.com +gxankao.com +gxantu.com +gxany.com +gxaoma.com +gxar.com +gxarl.com +gxasjc.com +gxasjn.com +gxawjmy.com +gxaxjy.com +gxaxpc.com +gxayn.com +gxb.io +gxbaichen.com +gxbaidu.net +gxbaidutg.com +gxbaifugch.com +gxbaikuang.com +gxbaixun.com +gxbakj.com +gxbaozhiyue.com +gxbasic.com +gxbbwsw.com +gxbbwyl.com +gxbcf.com +gxbcgjg.com +gxbcjc.com +gxbckj.com +gxbdcx.com +gxbdtx.com +gxbeiente.com +gxbest.xyz +gxbeyy.com +gxbf.net +gxbgdl.com +gxbgtf.com +gxbhgas.com +gxbhjg.com +gxbhlg.com +gxbhly.net +gxbian.com +gxbiandao.com +gxbidding.com +gxbihongkeji.com +gxbinhai.com +gxbiyang.com +gxblfs.com +gxbltz.com +gxbml.com +gxbmmy.com +gxbngs.com +gxbochi.com +gxboning.com +gxbotlan.com +gxbqba.com +gxbqkj.com +gxbr668.com +gxbre.com +gxbrm.com +gxbs.net +gxbscbh.com +gxbsfj.com +gxbsky.com +gxbsnx.com +gxbssyy.com +gxbstlxx.com +gxbsyjsw.com +gxbtjt.com +gxbtka.com +gxbtnz.com +gxbtsc.com +gxbtsy.com +gxbtxc.com +gxbygs.com +gxbyjxc.com +gxbykj.com +gxbyrcb.com +gxbys.com +gxbyw.com +gxbyx.com +gxbzjx.com +gxcae.com +gxcaining.com +gxcaiyiduo.com +gxcampus.com +gxcards.com +gxcareer.com +gxcast.com +gxcatv.com +gxcbjs.com +gxcbljt.com +gxccblg.com +gxccedu.com +gxccjt.com +gxcd.pw +gxcdc.com +gxceg.com +gxcei.com +gxcerc.com +gxcexxzx.com +gxcfjx.com +gxcgmf.com +gxcgzh.com +gxch168.com +gxchanghe.com +gxchangjiangpn-jinnuo.com +gxchbf.com +gxchem.com +gxchengjian.com +gxchengmei.com +gxchengyun.com +gxchlrf.com +gxchr.com +gxchuanghua.com +gxchuanlan.com +gxchuen.com +gxchunmao.com +gxchuxin.com +gxcic.net +gxcimc.com +gxcj.cc +gxcj.net +gxcjcl.com +gxcjgt.cc +gxcjn.com +gxcjtc.com +gxclkj.com +gxclzz.com +gxcmgr.com +gxcmicc.com +gxcncec.com +gxcnjx.com +gxcodemaker.com +gxcors.com +gxcounty.com +gxcpa.com +gxcq188.com +gxcqm.com +gxcr.cc +gxcrcw.com +gxcrh.net +gxcrhj.com +gxcrjm.com +gxcro.com +gxcrzxgs.com +gxcschem.com +gxcscm.com +gxcsfc.com +gxcskj.com +gxcsmed.com +gxcsmx.com +gxcsqj.com +gxcsycj.com +gxcsypm.com +gxcszm.com +gxctc.net +gxctd.com +gxcthb.com +gxcti.com +gxctzb.com +gxcuiping.com +gxcvuedu.com +gxcw.com +gxcxhb.com +gxcxxny.com +gxcxyx.com +gxcyaq.com +gxcyhjt168.com +gxcyzs.com +gxcz88.com +gxczm.com +gxcznews.com +gxcznews.net +gxczrc.com +gxdadu.com +gxdairy.com +gxdajin.com +gxdajixiong.com +gxdake.com +gxdanbao.com +gxdangan.com +gxdansi.com +gxdanzo.com +gxdaos.com +gxdaosheng.com +gxdbdl.com +gxdbxrmyy.com +gxdco.net +gxdcwh.com +gxddcs.com +gxddtz.com +gxddzl.com +gxdegas.com +gxdetdq.com +gxdfjt.com +gxdfzx.com +gxdhgy.com +gxdhhb.com +gxdhyy.com +gxdiba.com +gxdicai.com +gxdig.com +gxdingyi.com +gxdingyu.com +gxdkjmy.com +gxdkyr.net +gxdljz.com +gxdltech.com +gxdlxy.com +gxdlzl.com +gxdmds.com +gxdmsq.com +gxdmtrade.com +gxdmw.com +gxdna.com +gxdnu.com +gxdong.com +gxdongce.com +gxdongfangshi.com +gxdonghong.com +gxdongkai.com +gxdoulaibo.com +gxdqtg.com +gxdrh.com +gxds1.com +gxdse.com +gxdslyy.com +gxdslyyls.com +gxdsoms.com +gxdsxf.com +gxdsyl.com +gxdtchem.com +gxdtiot.com +gxdtjl.com +gxdtsc.com +gxdunshen.com +gxduomeishi.com +gxduyi.com +gxdx5.com +gxdxbj.com +gxdxcredit.com +gxdxdt.com +gxdxjs.com +gxdxlk.com +gxdxlxs.com +gxdycpa.com +gxdygs.com +gxdygx.com +gxdyxjd.com +gxdyyj.com +gxea.com +gxeaq.com +gxecard.com +gxecm.com +gxeduyun.net +gxegoo.com +gxehy.com +gxeits.com +gxej.net +gxelang.com +gxenews.com +gxeph.com +gxept.com +gxeqjx.com +gxeqx.com +gxer.net +gxeszx.com +gxevc.com +gxewa.com +gxfag.com +gxfaj.com +gxfanghu.com +gxfanlian.com +gxfanlu.com +gxfanxing.com +gxfanyayoga.com +gxfcq.com +gxfcw.com +gxfengjie.com +gxfenglei.com +gxfengxingjq.com +gxffjt.com +gxfhjs.com +gxfhny.com +gxfhxx.com +gxfi.net +gxfigroup.com +gxfin.com +gxfinfr.com +gxfjly.com +gxflm.com +gxflpg.com +gxfls.com +gxflzx.com +gxfm.net +gxfmmy.com +gxfnt.com +gxforestry.com +gxfrhb.com +gxfsms.com +gxfssy.com +gxfsty.com +gxfswl.com +gxfsxrmyy.com +gxfsyljt.com +gxftu.org +gxfushun.com +gxfusui.com +gxfuxue.com +gxfuyuan.com +gxfxhjwy.com +gxfxly.com +gxfxm.com +gxfxwh.com +gxfxzb.com +gxfybj.com +gxfygp.com +gxfysteel.com +gxfyzx.com +gxfzf.com +gxfzkkj.com +gxfzpg.com +gxfzyjs.com +gxg1978.com +gxgaia.com +gxgangji.com +gxgangxin.com +gxgangyuan.com +gxganhua.com +gxgaoling.com +gxgaotong.com +gxgaoyao.com +gxgaoyou.com +gxgaty.com +gxgba.com +gxgbdb.com +gxgbkj.com +gxgbx.com +gxgcedu.com +gxgcfscl.com +gxgcjs.com +gxgczxjt.com +gxgd192.com +gxgdbg.com +gxgdhg.com +gxgdlsp.com +gxgdpg.com +gxgdyy.com +gxgdyz.com +gxgeek.com +gxgentle.com +gxgf.net +gxgfsh.com +gxggcmc.com +gxggdq.com +gxggfhsmy.com +gxgghx.com +gxggm.com +gxghfs.com +gxghjt.com +gxghpg.com +gxghyysc.com +gxghzh.com +gxgj.com +gxgjgc.com +gxgjgg.com +gxgjh.com +gxgjjl.com +gxgjjt.com +gxgjny.com +gxgjzy.com +gxgkzzr.com +gxgl588.com +gxglft.com +gxglgcjs.com +gxglhd.com +gxglhx.com +gxgljhgc.com +gxgljy.com +gxglkg.com +gxglnykj.com +gxglory.com +gxglyl.com +gxglys.com +gxglzj.com +gxglzs.com +gxgm.net +gxgmgc.com +gxgmjhc.com +gxgmtx.com +gxgndxdl.com +gxgoldpool.com +gxgongyinglian.com +gxgoodfirst.com +gxgp123.com +gxgpo.com +gxgpzhtc.com +gxgqdz.com +gxgqsn.com +gxgrasp.com +gxgree.com +gxgrtech.com +gxgryy.com +gxgsgl.com +gxgsgs.com +gxgshb.com +gxgswlhy.com +gxgsxy.com +gxgsyy.com +gxgszb.com +gxgtdg.com +gxgtdl.com +gxgtghy.com +gxgttt.com +gxgtxny.com +gxgtzb.com +gxgtzx.com +gxguanghui.com +gxguangxin.com +gxguangyi.com +gxguantai.com +gxguanyu.com +gxguerte.com +gxguicheng.com +gxguijiu.com +gxguimei.com +gxguiping.com +gxguiren.com +gxguirun.com +gxguite.com +gxguixing.com +gxguiyang.com +gxguizhiyuan.com +gxguoda.com +gxguoen.com +gxguojian.com +gxguojingjiuye.com +gxguoyang.com +gxguyu.com +gxgwmb.com +gxgwuxe.com +gxgwyw.org +gxgxjc.com +gxgxncplm.com +gxgxun.com +gxgyfy.com +gxgyh.com +gxgymsxx.com +gxgyrq.com +gxgyyclc.com +gxgyyy.com +gxgzlm.com +gxgztyy.com +gxgzy.com +gxgzzn.com +gxhaibao.com +gxhalw.com +gxhanhe.com +gxhanlin.com +gxhaojian.com +gxhaorun.com +gxhaozhi.com +gxharui.com +gxhb8.com +gxhbcyxh.com +gxhbedu.com +gxhbs.com +gxhc120.com +gxhc18.com +gxhc365.com +gxhcht.com +gxhclw.com +gxhcmr.com +gxhcnf.com +gxhcwy.com +gxhcyk.com +gxhczx.com +gxhdaf.com +gxhddj.com +gxhddq.com +gxhdsy.com +gxhealth.xin +gxheda.com +gxhefei.com +gxheguan.com +gxhengda.com +gxheyumaoyi.com +gxhezhixin.com +gxhfba.com +gxhfdqsb.com +gxhfyy.com +gxhg.net +gxhghg.com +gxhgjm.com +gxhgkj.com +gxhgx.net +gxhgzb.com +gxhgzc.com +gxhh.com +gxhhgc.com +gxhhgs.com +gxhhhb.com +gxhhig.com +gxhhjk.com +gxhhjt.net +gxhhmed.com +gxhhzsjt.com +gxhigreen.com +gxhis.net +gxhjbw.com +gxhjjt.net +gxhjky.com +gxhjly.com +gxhjsh.com +gxhjsz.com +gxhjwy.com +gxhjzbcyy.com +gxhjzx.com +gxhkd.com +gxhkdq.com +gxhkdyf.com +gxhkgy.com +gxhkjc.com +gxhkjt.com +gxhl.com +gxhlc.com +gxhljx.com +gxhlun.com +gxhlx.net +gxhly168.com +gxhmba.com +gxhmcm.com +gxhmdjt.com +gxhnyt.com +gxhongchuan.com +gxhonggang.com +gxhongning.com +gxhongshimuye.com +gxhongyunsi.com +gxhongzh.com +gxhope.org +gxhospital.com +gxhouse.com +gxhovi.com +gxhpxrmyy.com +gxhqh.com +gxhqjy.com +gxhqtest.com +gxhqwh.com +gxhqxmgl.com +gxhrcjz.com +gxhrkj.com +gxhs.site +gxhsba.com +gxhsjgs.com +gxhsltd.com +gxhsry.com +gxhsshj.com +gxhsshjzl.com +gxhstars.com +gxhsxcl.com +gxhsxxkj.com +gxhsykj.com +gxhszb.com +gxhtjx.com +gxhtl.com +gxhtte.com +gxhuabao.com +gxhuachi.com +gxhuachuang.com +gxhuadu.com +gxhuaen.com +gxhuahui.com +gxhuanbaojt.com +gxhuapei.com +gxhuaqu.com +gxhuar.com +gxhuaxing.com +gxhuaxintech.com +gxhui.com +gxhuicuibencao.com +gxhuifa.com +gxhuihuang.com +gxhuiji.com +gxhuijvtong.com +gxhuiming.com +gxhuitong.com +gxhuiwanger.com +gxhuolong.com +gxhxbook.com +gxhxgg.com +gxhxgroup.com +gxhxh.com +gxhxysgs.com +gxhxyyjt.com +gxhxzyh.com +gxhyart.com +gxhydq.com +gxhyey.com +gxhygg.com +gxhyhs.com +gxhykglass.com +gxhyq.com +gxhyscl.com +gxhysm.com +gxhyww.com +gxhyxf.com +gxhyxt.com +gxhyz168.com +gxhyzixun.com +gxhyzx.net +gxhzgjyy.com +gxhzjsgc.com +gxhzkj.com +gxhzsbwg.com +gxhzsqyg.com +gxhztqt.com +gxhzxk.com +gxhzxw.com +gxhzyd.com +gxi.ink +gxiang.org +gxibvc.net +gxic.club +gxic.net +gxicc.net +gxicpa.com +gxidc.com +gxidi.com +gxind.com +gxinf.com +gxinfo.org +gxinfotec.com +gxipo.net +gxjajc.com +gxjaw.com +gxjbhb.com +gxjbk.com +gxjbyy.com +gxjcbf.com +gxjccj.com +gxjch.com +gxjckc.com +gxjcqt.com +gxjcxcl.com +gxjcxy.com +gxjcy.com +gxjcys.com +gxjdcb.com +gxjdgc.com +gxjdgczx.com +gxjdgyxx.com +gxjdxs.com +gxjeyy.com +gxjf99.com +gxjfdz.com +gxjfx.com +gxjg199.com +gxjgdj.com +gxjgea.com +gxjghy.com +gxjgjjc.com +gxjgjstzjt.com +gxjgjt.com +gxjgyj.com +gxjgyjgs.com +gxjgzcb.com +gxjgzppc.com +gxjhcj.com +gxjhgczx.com +gxjhgd.com +gxjhgs.com +gxjhjcw.com +gxjhjdsb.com +gxjhjs.com +gxjhky.com +gxjhsj.com +gxjhygs.com +gxjhzj.com +gxjiahua.com +gxjiangyong.com +gxjianhong.com +gxjianlan.com +gxjianrong.com +gxjianyi.com +gxjiaohang.com +gxjiasheng.com +gxjiatai.com +gxjichang.com +gxjiebai.com +gxjiefeng.com +gxjien.com +gxjigeng.com +gxjigeyuan.com +gxjihu.com +gxjinan.com +gxjingsheng.com +gxjinhai.com +gxjinhuiauto.com +gxjinjiang.com +gxjinsu.com +gxjinsui.com +gxjintu.com +gxjirui.com +gxjiufa.com +gxjiuxincpa.com +gxjiuyi.com +gxjiuyi99.com +gxjixu.com +gxjiyu.com +gxjjb.com +gxjjfds.com +gxjjfjt.com +gxjjgy.com +gxjjh.com +gxjjyb.com +gxjkamc.com +gxjkhj.com +gxjkjg.com +gxjkjyjc.com +gxjkwy.com +gxjl99.com +gxjla.com +gxjlbw.com +gxjljz.com +gxjlkj.com +gxjlnm.com +gxjlrc.com +gxjlsc.com +gxjm.vip +gxjmggs.com +gxjmxx.com +gxjmxy.com +gxjmzg.com +gxjnbgzx.com +gxjowy.com +gxjpfs.com +gxjpjs.com +gxjpjy.com +gxjptw.com +gxjqgs.com +gxjqt.com +gxjqyy.com +gxjrxy.com +gxjrzl.com +gxjs.net +gxjsd56.com +gxjsfs.com +gxjshu.com +gxjsstjt.com +gxjstkj.com +gxjsws.com +gxjsxny.com +gxjsxszn.com +gxjt.net +gxjt001.com +gxjtaq.com +gxjtjx.com +gxjtkyy.com +gxjtpg.com +gxjtsa.com +gxjtscm.com +gxjtsjy.com +gxjttz.com +gxjttzjt.com +gxjtyab.com +gxjtysxx.com +gxjtzb.com +gxjuancheng.com +gxjub.com +gxjugu.com +gxjuhw.com +gxjunan.com +gxjunhe.com +gxjunliang.com +gxjxcloud.com +gxjxsy.com +gxjxwh.com +gxjycjsb.com +gxjyfdc.com +gxjyfkj.com +gxjygljt.com +gxjyh.store +gxjyhb.com +gxjyjs168.com +gxjyjt.com +gxjyjz.com +gxjyxxw.com +gxjyy.com +gxjyzl.com +gxjyzyw.com +gxjz123.com +gxjzcy.com +gxjzdt.com +gxjzht.com +gxjzhxd.com +gxjzj-hotel.com +gxjzj.com +gxjzjc.com +gxjzjl.com +gxjznet.com +gxjzw12315.com +gxjzy.com +gxjzzbdl.com +gxkaifan.com +gxkangtian.com +gxkaoba.com +gxkcjc.com +gxkcmy119.com +gxkdefy.com +gxkdjc.com +gxkdjd.com +gxkdjsq.com +gxkefei.com +gxkehong.com +gxkelite.com +gxkesui.com +gxkfl.com +gxkfy.com +gxkhjt.com +gxkhkj.com +gxkhn.com +gxkhxxcl.com +gxkiwi.com +gxkjd.com +gxkjdns.com +gxkjdsj.com +gxkjec.com +gxkjhb.com +gxkjjt.com +gxkjl.com +gxkjs.com +gxkjzy.com +gxkl.com +gxkld.com +gxklyy.com +gxkmkny.com +gxkongshan.com +gxkorbel.com +gxkqjt.com +gxkqty.com +gxkrqz.com +gxkrui.com +gxkrx.com +gxkrzc.com +gxksdl.com +gxksdt.com +gxksjx.net +gxksxf.com +gxktdl.com +gxktzk.com +gxktzx.com +gxkunzhen.com +gxkyjc.com +gxkzxx.com +gxlanbowang.com +gxlanco.com +gxlancogroup.com +gxlanlian.com +gxlansheng.com +gxlbang.com +gxlbbwg.com +gxlbgf.com +gxlbi.com +gxlbzszy.com +gxlcclean.com +gxlcgy.com +gxlcjsjt.com +gxlclsyf.com +gxlcpp.com +gxlcwater.com +gxlcxs.com +gxld168.com +gxlddq.com +gxldgjgpj.com +gxldjs.com +gxldpc.com +gxldzn.com +gxlecheng.com +gxlek.com +gxlelin.com +gxlfzl.com +gxlgwl.com +gxlgxx.com +gxlh168.com +gxlhcx.com +gxlhgjg.com +gxlhhb.com +gxlhjc.com +gxlhxn.com +gxlianci.com +gxliangjian.com +gxliangla.com +gxlianguan.com +gxliangyun.com +gxlianye.com +gxlianying.com +gxlib.com +gxlihua.com +gxlimu.com +gxliri.com +gxlituo.com +gxliuhang.com +gxliuqiaojidian.com +gxlixin.com +gxliyugs.com +gxljgc.com +gxljh.com +gxljjt.com +gxljjz.com +gxljxs.com +gxlk.net +gxlke.com +gxlkjy.com +gxlkl.net +gxllcb.com +gxllsw888.com +gxllxl.com +gxlmjt.com +gxlmzs.com +gxlongfa.com +gxlonsen.com +gxlove.vip +gxlqgcy.com +gxlqjs.com +gxlqkg.com +gxlqsd.com +gxlryl.com +gxlscf.com +gxlsfy.com +gxlsfz.com +gxlsnm.com +gxlstc.com +gxlswhg.com +gxltbaoan.com +gxlteng.com +gxltgjg.com +gxltjj.com +gxltm.com +gxltmyjt.com +gxltzy.com +gxluhai.com +gxlulian.com +gxluogui.com +gxluyun.com +gxlvjian.com +gxlvtong.com +gxlvwang.com +gxlwdsslgy.com +gxlwlc.com +gxlwt.com +gxlxgg.com +gxlxs2008.com +gxlxs2008.net +gxlxsn.com +gxlxxl.com +gxlxyun.com +gxly66.com +gxlyb.com +gxlycq.com +gxlycs.com +gxlycwb.com +gxlycyxh.com +gxlyghy.com +gxlygyl.com +gxlyhbkj.com +gxlyjt.com +gxlzbbw.com +gxlzck.com +gxlzdyc.com +gxlzgcc.com +gxlzgdjt.com +gxlzhm.com +gxlzlk.com +gxlzpc.com +gxlzsh.com +gxlzsmk.com +gxlztz.com +gxlzwl.com +gxlzxrmyy.com +gxlzxt.com +gxlzzc.com +gxlzzh.net +gxma123.com +gxmacc.com +gxmailu.com +gxmanyy.com +gxmaocai.com +gxmbh.com +gxmbs.com +gxmdgroup.com +gxmdjt.com +gxmeiao.com +gxmeiduo.com +gxmeike.com +gxmetalking.com +gxmggg.com +gxmiao.com +gxmiaoshu.com +gxminglian.com +gxmingshi.com +gxmj.org +gxmjyy.com +gxmjzs.com +gxmk.net +gxmlba.com +gxmlyjy.com +gxmmhgs.com +gxmmkt.com +gxmoking.com +gxmqhb.com +gxmscbs.com +gxmsg.com +gxmsgy.com +gxmtzn1658.com +gxmuch.com +gxmuwmfy.com +gxmuyfy.com +gxmuzi.com +gxmxc.com +gxmxin.com +gxmyjc.com +gxmykj.com +gxmylink.com +gxmytzsn.com +gxmzb.net +gxmzcl.com +gxmzjwy.com +gxmzkj.com +gxmzly.com +gxmznzs.com +gxnantong.com +gxnapd.com +gxnbjc.com +gxnccq.com +gxncgd.com +gxnctzjt.com +gxndcxswyxgs.com +gxnddq.com +gxndgg.com +gxnewen.com +gxnfxny.com +gxnfyk.com +gxnhjk.com +gxnjqj.com +gxnjsy.com +gxnjy.com +gxnjzj.com +gxnk.com +gxnkjgnc.com +gxnkxjry.com +gxnkyy.com +gxnkyy.net +gxnmkj.com +gxnmzj.com +gxnncj.com +gxnnclt.com +gxnndghb.com +gxnnedu.com +gxnnfx.com +gxnnhexiexinli.com +gxnnip.com +gxnnjn.com +gxnnjqgg.com +gxnnjw.com +gxnnkfzx.com +gxnnks.com +gxnnlsz.com +gxnnlyd.com +gxnnmudz.com +gxnnncp.com +gxnnsdyy.com +gxnnsmfbl.com +gxnnsy.com +gxnntfx.com +gxnnthch.com +gxnntn.com +gxnnws.com +gxnnxny.com +gxnnybskq.com +gxnnyihui.com +gxnnyxjx.com +gxnnzj.com +gxnongmu.com +gxnpzbx.com +gxnsjt.com +gxntjz.com +gxnumba.com +gxnun.net +gxnwjt.com +gxnxdb.com +gxnxgd.com +gxnydq.com +gxnymt.com +gxnzjz.com +gxnzzy.com +gxoc168.com +gxoem.com +gxok.com +gxosjc.com +gxota.com +gxota.net +gxoulian.com +gxouwen.com +gxp.cc +gxp2.com +gxpanda.com +gxpangbo.com +gxpbs.com +gxpeh.com +gxpfyy.com +gxpgfood.com +gxpgft.com +gxpggj.com +gxpghj.com +gxphc.com +gxphd.com +gxphj.com +gxpingen.com +gxpinn.com +gxpjzs.com +gxpljt.com +gxpnzp.com +gxpost.com +gxppw.com +gxptids.com +gxptkc.com +gxptyy.com +gxpu.com +gxpuyi.com +gxpxdj.com +gxpykj.com +gxqcjs.com +gxqcw.com +gxqddfxf.com +gxqdkj.com +gxqfjzzs.com +gxqgjx.com +gxqgps.com +gxqhcm.com +gxqhjc.com +gxqhtec.com +gxqianhan.com +gxqianrong.com +gxqianshuo.com +gxqianyuan.com +gxqiba.com +gxqihu.com +gxqihuan.com +gxqingchang.com +gxqintang.com +gxqiyang.com +gxqiyuan.com +gxqkcm.com +gxqljt.com +gxqllc.com +gxqmk.com +gxqnjc.com +gxqqxcl.com +gxqrhb.com +gxqrjy.com +gxqs.org +gxqszl.com +gxqtgroup.com +gxqtszxc.com +gxqyjy.com +gxqykj.com +gxqymc.com +gxqymy.com +gxqzdx.com +gxqzez.com +gxqzfz.com +gxqzk.com +gxqzrc.com +gxqzrm.com +gxqztv.com +gxqztz.net +gxqzxjh.com +gxqzxw.com +gxqzxyd.com +gxqzyz.com +gxqzzy.com +gxrasafety.com +gxrayhome.com +gxrc.com +gxrcda.com +gxrcgs.com +gxrcosta.com +gxrcpx.com +gxrcw.com +gxrcyj.com +gxrczc.com +gxrdgroup.com +gxrdjy.com +gxrenheng.com +gxrfys.com +gxrgjd.com +gxrgwl.com +gxrhdl.com +gxrijia.com +gxrjf.com +gxrjyy.com +gxrkyy.com +gxrmzs.com +gxrnzb.com +gxroad.com +gxrongpin.com +gxrongwang.com +gxrqsjhz.com +gxrsjc.com +gxrskyy.com +gxrsmllab.com +gxrtbtc.com +gxruiheng.com +gxruipai.com +gxruizhen.com +gxrunteng.com +gxrxdt.com +gxrxsy.com +gxrxsyjz.com +gxrygc.com +gxrzd.com +gxrzgczx.com +gxsad.net +gxsag.com +gxsailian.com +gxsanchuan.com +gxsanleng.com +gxsanli.com +gxsanyo.com +gxsbcj.com +gxsbfdc.com +gxsbzz.com +gxsc88.com +gxscbxg.com +gxsccl.com +gxscjn.com +gxscjx.com +gxsckj.net +gxscq.com +gxscse.com +gxscsw.com +gxsd.net +gxsdem.com +gxsdpx.com +gxsdy.com +gxseal.com +gxsejy.com +gxsell.com +gxsenge.net +gxsenhao.com +gxsenzhou.com +gxsfcm.com +gxsfht.com +gxsfjd.com +gxsgcgpt.com +gxsgip.com +gxsgys.com +gxshangbeng.com +gxshangjia.com +gxshanglong.com +gxshangyou.com +gxshanyixing.com +gxshbs.com +gxshck.com +gxshdl.com +gxshebei.com +gxshenglu.com +gxshengwei.com +gxshenyi.com +gxshgk.com +gxshile.com +gxshiteng.com +gxshixinde.com +gxshizhi.com +gxshjy.com +gxshjz.com +gxshny.com +gxshoufeng.com +gxshouji.com +gxshtf.com +gxshua.com +gxshuairun.com +gxshudao.com +gxshuibao.com +gxshuixie.com +gxshunxiu.com +gxshxc.com +gxshxf.com +gxshxlpx.com +gxshyy.com +gxshz01.com +gxshzyzs.com +gxsika.com +gxsilk.com +gxsjc.com +gxsjgs.com +gxsjmilk.com +gxsjmy.com +gxsjsd.com +gxsjtz.com +gxsjwh.com +gxskf.com +gxsksw.com +gxsksy.com +gxsl.com +gxslbj.com +gxslcc.com +gxslyj.com +gxslyy.com +gxsme.net +gxsmkt.com +gxsngc.com +gxsntp.com +gxsnzw.com +gxspas.com +gxspri.com +gxsrkj.com +gxsrtz.com +gxsrwl.com +gxsrxlzxyxzrgs.com +gxssmg.com +gxssrs.com +gxstarship.com +gxstd.com +gxsthb.com +gxsthnt.com +gxstkw.com +gxstzx.com +gxsubat.com +gxsuda.com +gxsunwin.com +gxsut.com +gxsuyun.com +gxswgd.com +gxswsw.com +gxswzps.com +gxsxbj.com +gxsxhw.com +gxsy.org +gxsycpa.com +gxsydg.com +gxsygg.com +gxsyh.com +gxsyzs.com +gxszf.net +gxszgp.com +gxszjf.com +gxszjk.com +gxszyy.com +gxtagrm.com +gxtaiping.com +gxtaishi.com +gxtaiyinuo.com +gxtalc.com +gxtangmi.com +gxtcdpp.com +gxtckj.com +gxtcq.com +gxtcsys.com +gxtdg.com +gxtenger.com +gxtengsong.com +gxtesjy.com +gxtf108.com +gxtfgg.com +gxtfmy.com +gxtfxx.com +gxthcpa.com +gxthxxkj.com +gxthyy.com +gxtianmiao.com +gxtianpin.com +gxticket.com +gxtizi.com +gxtjddc.com +gxtjksj.com +gxtjsnzg.com +gxtk.com +gxtkzx.com +gxtlgd.com +gxtljnhb.com +gxtltzjt.com +gxtmh.com +gxtmhzx.com +gxtmrs.com +gxtmsy.com +gxtodo.com +gxtonghui.com +gxtongji.com +gxtongtai.com +gxtongzhu.com +gxtopart.com +gxtp2021.com +gxtrwhy.com +gxtskq.com +gxtslr.com +gxttcc.com +gxttjs.com +gxttjt.com +gxtuipin.com +gxtuliao.com +gxtuoen.com +gxtuoyi.com +gxtuscity.com +gxtxjk.com +gxtxpec.com +gxty.com +gxty.ltd +gxtydt.com +gxtydzqy.com +gxtyjc.com +gxtykj.com +gxtyw.com +gxtywj.com +gxtyymxcgs.com +gxtzh.net +gxtznn.com +gxtzpx.com +gxtztech.com +gxucreate.com +gxue.net +gxufl.com +gxufz.com +gxuit.com +gxumi.com +gxupdi.com +gxups.com +gxuzf.com +gxvideo.net +gxvolardda.com +gxwanchao.com +gxwanchun.com +gxwbl.com +gxwcll.com +gxwcwl.com +gxwdgg.com +gxwdjt.com +gxweibo.net +gxweipeng.com +gxweite.com +gxwellsun.com +gxwenlian.com +gxwenyutech.com +gxwgdq.com +gxwgjf.com +gxwhsy.com +gxwhwy.com +gxwjkj.com +gxwjs.com +gxwjwswkj118.com +gxwjxl.com +gxwjxsbcj.com +gxwjyllh.com +gxwkhb.com +gxwkxcl.com +gxwmj168.com +gxwmpco.com +gxwofi.com +gxwogan.com +gxwohua.com +gxwoqi.com +gxwqwh.com +gxwskq.com +gxwsxt.com +gxwtai.com +gxwtba.com +gxwtrlzy.com +gxwtt.com +gxwtzy.com +gxwudun.com +gxwuyan.com +gxwuzi.com +gxwx.com +gxwxbjsy.com +gxwxjy.com +gxwxjz.com +gxwxtyn.com +gxwzgroup.com +gxwzhh.co +gxwzj.com +gxwzjt.com +gxwzjx.com +gxwzlhh.com +gxwzsz.com +gxwztv.com +gxwzxhyq.com +gxwzyl.com +gxxbx.com +gxxbysy.com +gxxbzm.com +gxxdbp.com +gxxdit.com +gxxdpc.com +gxxdzx.com +gxxfbfg.com +gxxfgg.com +gxxfky.com +gxxfsl.com +gxxfz.com +gxxgg.com +gxxgle.com +gxxgpower.com +gxxgrj.com +gxxgty.com +gxxh58.com +gxxhb.com +gxxhgj.com +gxxhgroup.com +gxxhgs.com +gxxhn.com +gxxhsd.com +gxxhtax.com +gxxhtsj.com +gxxhtx.com +gxxhtzp.com +gxxhz.com +gxxhzp.com +gxxiangxing.com +gxxiangyi88.com +gxxiaofu.com +gxxiaolong.net +gxxielang.com +gxxijiang.com +gxxilin.com +gxxin.com +gxxinchai.com +gxxingfu.com +gxxingxing.com +gxxingyao.com +gxxinhui.com +gxxinrui.net +gxxinxiang.com +gxxinye.com +gxxinyi.com +gxxinzhihai.com +gxxiyuanep.com +gxxjcz.com +gxxjry.com +gxxjsy.com +gxxkai.com +gxxkgs.com +gxxkhj.com +gxxkslgy.com +gxxldl.com +gxxlhkj.com +gxxlk.com +gxxlkj.com +gxxls.com +gxxlyc.com +gxxlzxs.com +gxxlzyc.com +gxxmglzx.com +gxxmjjs.com +gxxmyjs.com +gxxndz.com +gxxpgd.com +gxxqsm.com +gxxrf.com +gxxrwl.com +gxxrxmgl.com +gxxrzb.com +gxxstz.com +gxxsy.com +gxxszx.com +gxxszy.net +gxxtlq.com +gxxundongtech.com +gxxuyang.com +gxxw.com +gxxwjs.net +gxxy.online +gxxydhb.com +gxxyh.net +gxxyhwhcb.com +gxxyrbc.com +gxxyybc.com +gxxyydl.com +gxxyzx.com +gxxzbjy.com +gxxzbzh.com +gxxzlx.com +gxxztcm.com +gxxzwd.com +gxyaan.tech +gxyali.com +gxyanggong.com +gxyasuoji.com +gxybsw.com +gxybyy.com +gxyc.net +gxycjy.com +gxycwh.com +gxycwy.com +gxycykj.com +gxycysw.com +gxyd.com +gxydbg.com +gxydbgjj.com +gxyddyf.com +gxydeye.com +gxydfs.com +gxydh.com +gxydn.com +gxydsc.com +gxydspm.com +gxydtaxi.com +gxydxf.com +gxyefang.com +gxyesf.com +gxyete.com +gxyfck.com +gxyfdz.com +gxyfkj.com +gxyfm.com +gxyfxc.com +gxygfund.com +gxyglw.com +gxygys.com +gxyhdq.com +gxyhgcjcxxw.com +gxyhjgjt.com +gxyhjt.com +gxyhmy.net +gxyhtz.com +gxyhxx.com +gxyicheng.com +gxyidao.com +gxyide.com +gxyih.com +gxyingchuang.com +gxyingdi.com +gxyinglun.com +gxyingyue.com +gxyinniyuan.com +gxyintian.com +gxyinyulanyingguigang.com +gxyixin.com +gxyiz.com +gxyj.com +gxyjcy.com +gxyjdc.com +gxyjhb.com +gxyjmc.com +gxyjzx.com +gxykjd.com +gxylct.com +gxyldfyy.com +gxylgyx.com +gxylink.com +gxyljf.com +gxyllc.com +gxylms.com +gxylnews.com +gxyls.com +gxylsjsp.com +gxylswkj.com +gxympay.com +gxynjx.com +gxynlts.com +gxyoj.com +gxyongjiehb.com +gxyongsheng.com +gxyongzhitai.com +gxyos.com +gxypdc.com +gxypjy.com +gxypnh.com +gxyqjc.com +gxysbt.com +gxysbz.com +gxysccsh.com +gxyskz.com +gxyslkj.com +gxysqj.com +gxyss.com +gxytdyf.com +gxytgc.com +gxytk.com +gxytsy.com +gxytzx.com +gxyuanan.com +gxyuanfeng.com +gxyuansheng.com +gxyuanyun.com +gxyuchuan.com +gxyunhua.com +gxyunsen.com +gxyunsheng.com +gxyunxiang.com +gxyuqiaoshiye.com +gxyushengwenhua.com +gxyuyun.com +gxyx168.com +gxyx1688.com +gxyxdl.com +gxyxjt.com +gxyxlx.com +gxyxsh.com +gxyxtkj.com +gxyxyy.com +gxyy.net +gxyykj.com +gxyyun.com +gxyyyc.com +gxyyzwy.com +gxyz120.com +gxyzems.com +gxyzh.com +gxyzhhb.com +gxyzjc.com +gxyzrmyy.com +gxyzt.com +gxyzxf119.com +gxyzyy.com +gxzanwen.com +gxzbfm.com +gxzbkj.com +gxzbzh.com +gxzc888.com +gxzcab.com +gxzcfd.com +gxzchz.com +gxzcjh.com +gxzckj.com +gxzclq.com +gxzcpsw.com +gxzcs.com +gxzdsj.com +gxzdyg.com +gxzecai.com +gxzepu.com +gxzero.com +gxzfjg.com +gxzfnz.com +gxzfzx.com +gxzfzy.com +gxzgdl.com +gxzghsp.com +gxzgsy.com +gxzgt.com +gxzgtz.com +gxzh.ltd +gxzh666.com +gxzhdq.com +gxzhenghua.com +gxzhenhang.com +gxzhentao.com +gxzhgz.com +gxzhicui.com +gxzhihui.com +gxzhisai.com +gxzhixing.com +gxzhiyuanxing.com +gxzhizhi.com +gxzhjj.com +gxzhkj.com +gxzhlw.com +gxzhnm.com +gxzhongshui.com +gxzhongta.com +gxzhongzhai.com +gxzhp.com +gxzhpm.com +gxzhshxx.com +gxzhunchengbg.com +gxzhzb.com +gxzhzy.com +gxziheng.com +gxzj-metal.com +gxzjjs.com +gxzjjtgs.com +gxzjy.com +gxzkl.com +gxzky.com +gxzkzs.com +gxzlcs.com +gxzldt.com +gxzljt.com +gxzljx.net +gxzlnm.com +gxzls.com +gxzlsb.net +gxzm.vip +gxzmjg.com +gxzmlm.com +gxzmrl.com +gxzmtech.com +gxzmzz.com +gxznym.com +gxzongjun.com +gxzoxn.com +gxzpjx.com +gxzpw.org +gxzrdk.com +gxzrjc.com +gxzrxf.com +gxzscloud.com +gxzsgl.com +gxzsjzsj.com +gxzslfz.com +gxzsnm.com +gxzspg.com +gxzssmart.com +gxzstsg.com +gxzstzjtgs.com +gxzsyy.com +gxzszw.com +gxzt.com +gxzt148.com +gxzt99.com +gxztbf.com +gxztzs.com +gxzunx.com +gxzuojiang.com +gxzwhw.com +gxzwjt.com +gxzwxx.com +gxzxgl.com +gxzxht.com +gxzxmy.net +gxzxrh.com +gxzy.com +gxzydl.com +gxzyfs.com +gxzygygs.com +gxzyhb.com +gxzyjl.com +gxzyjsgc.com +gxzyky.com +gxzymodel.com +gxzypg.com +gxzytx.com +gxzyxysy.com +gxzyyt.com +gxzyzb.com +gxzzcpa.com +gxzzd.com +gxzztkj.com +gxzzxin.com +gy-ggy.com +gy120.net +gy1688led.com +gy2025.com +gy328.com +gy3y.com +gy794c.com +gy7n.com +gy818.com +gyaqyy.com +gyb086.com +gybcq.com +gybsn.com +gybyscy.com +gycharm.com +gycode.com +gyddos.com +gydfsy.com +gydongli.com +gyedu.net +gyersf.com +gyfensuiji.com +gyfwyy.com +gyfyy.com +gygmhs.com +gygmk.club +gyhapp.com +gyhb68.com +gyhdsj.com +gyhht.com +gyhimalayanul.com +gyhj.org +gyhm.cc +gyidc.net +gyii.com +gyip.net +gyjc88.com +gyjdgs.com +gyjiangyuan.com +gyjs.net +gykgcqtm.com +gykggz.com +gykghb.com +gykgsx.com +gykqyy.com +gylcxo.xyz +gyljc.com +gylwgjsyxx.com +gylwyy.com +gylxq.com +gym0boy.com +gymama.com +gymbo-online.com +gymxbl.com +gymy.cc +gyncb.net +gynsh.net +gynyzp.com +gyouapp.com +gypmsl.com +gypserver.com +gypump.com +gypzkat.com +gyqcw.com +gyqqd.com +gyqrmyy.com +gyr.cc +gyrcw.com +gyrmyy.com +gyrqfd.com +gyrsy.com +gyscw.com +gysdzy.com +gyseals.com +gyshwl.online +gysk.com +gysou.com +gysq.org +gysrmyy.com +gystarch.com +gystars.com +gystatic.com +gystc.com +gyswzys.com +gytcwb.com +gytxnc.com +gytzkg.com +gyuancdn.com +gyurt.com +gywlhypt.com +gywxedu.com +gywygl.com +gyxdkjdl.com +gyxtyy.com +gyxuan.com +gyxww.net +gyxx.com +gyxx365.com +gyyb.com +gyycc.com +gyypw.com +gyyuli.com +gyyywcpx.com +gyzdh.com +gyzdkq.com +gyzfbz.net +gyzhtc.com +gz-begreen.com +gz-best.com +gz-chantou.com +gz-chengkao.com +gz-cjjl.com +gz-cmc.com +gz-cube.com +gz-ejoy.com +gz-goam.com +gz-gree.com +gz-haohushan.com +gz-hipower.com +gz-huayuan.com +gz-hz.com +gz-julong.com +gz-junan.com +gz-lodihair.com +gz-ltjx.com +gz-mrt.com +gz-notary.com +gz-shanguang.com +gz-spi.com +gz-tencentclb.cloud +gz-tencentclb.com +gz-tencentclb.net +gz-tencentclb.work +gz-wx.com +gz-xinghe.com +gz-xinyu.com +gz-xt.com +gz-zhongshang.com +gz.com +gz007.net +gz0668.com +gz111.com +gz121.com +gz12301.com +gz162.com +gz1hua.com +gz300.com +gz304.com +gz360.com +gz4399.com +gz4u.net +gz528.com +gz583.com +gz91.com +gzac.org +gzanquan.com +gzap.net +gzaptech.net +gzasp.net +gzate.com +gzautojet.com +gzbaozhilin.com +gzbawei.com +gzbeaton.com +gzbic.com +gzbiogene.com +gzbl.com +gzblssly.com +gzboji.com +gzbookcenter.com +gzbt020.com +gzbus.com +gzbxyy120.com +gzbycq.com +gzbyyy.com +gzbzsport.com +gzbzx.net +gzcablec.com +gzcancer.com +gzcars.net +gzccb.com +gzccigroup.com +gzccvs.com +gzceia.com +gzch120.com +gzch12333.com +gzchangke.com +gzchangzhe.com +gzchenggeng.com +gzchj.net +gzchts.com +gzchuanghe.com +gzchupai.com +gzci.net +gzcihui.com +gzcjjs.com +gzcmer.com +gzcmjl.com +gzcn.net +gzcots.com +gzcppa.com +gzcqs.com +gzcrdzbk.com +gzcsgs.com +gzcsjg.com +gzcxhd.com +gzcxlm.org +gzcycling.com +gzczjd.com +gzdahyxh.com +gzdai.com +gzdaily.com +gzdangaopeixun.com +gzdaochen.com +gzdaqi.com +gzdata.net +gzdayue.com +gzdbx.com +gzdcsmt.com +gzdensity.com +gzdi.com +gzdia.com +gzdingan.com +gzdingjie.com +gzdingyu.com +gzdingyue.com +gzdingyun.com +gzdisheng.com +gzdjy.org +gzdli.com +gzdqyy.com +gzdryy.com +gzdsw.com +gzdtg.com +gzduguo.com +gzdysx.com +gzebpubservice.com +gzedu.com +gzeic.com +gzenxx.com +gzeryun.com +gzexpo.com +gzfc.net +gzfengmao.com +gzfezx.com +gzfgxh.com +gzfi.com +gzfin.com +gzfirst.com +gzfisher.com +gzfk01.com +gzfodak.com +gzforge.com +gzfpa.net +gzfqyy.com +gzfrldz.com +gzfsnet.com +gzfuk.net +gzgajy.com +gzgas.com +gzgayy.com +gzgccs.com +gzgccxkj.com +gzgcg.com +gzgdkq.com +gzgdwl.com +gzgelandi.com +gzghic.com +gzghyy.com +gzgj.net +gzgjcm.com +gzgjxny.com +gzglgcjt.com +gzgljx.com +gzgmjcx.com +gzgongsizhuce.com +gzguangjia.com +gzguidian.com +gzgx020.com +gzgxysjx.com +gzgyetc.com +gzh6.com +gzhaigu.com +gzhakj.com +gzhand.com +gzhangcha.com +gzhatao.com +gzhbchy.com +gzhc365.com +gzhclw.com +gzhcpcb.com +gzhd.net +gzhd56.com +gzhdcs.com +gzhe.net +gzhengdian.com +gzhengdou.com +gzheyoukeji.com +gzhfschool.com +gzhifi.com +gzhkl.com +gzhkzyyy.com +gzhm.com +gzhntec.com +gzhornet.com +gzhotelgroup.com +gzhpaier.com +gzhpgroup.com +gzhphb.com +gzhpyy.com +gzhpzz.net +gzhrsa.org +gzhsh.com +gzhstars.net +gzhtdz.com +gzhtinfo.com +gzhuake.cc +gzhuamei.net +gzhuayan.com +gzhuiwan.com +gzhuiyk.com +gzhuiyun.com +gzhwgg.com +gzhwsp.com +gzhx04.com +gzhx09.com +gzhx10.com +gzhxaq.com +gzhxyyhos.com +gzhygk.com +gzhysy.com +gzhzcj.com +gzidc.com +gziec.net +gzitvs.com +gzitwm.net +gzj568.com +gzjbjx.com +gzjbwm.com +gzjc2016.com +gzjeeseng.com +gzjgpy.com +gzjhotel.com +gzjiada.com +gzjiaw.com +gzjiehun.com +gzjiema.com +gzjingsha.com +gzjinsong.com +gzjiunuo.com +gzjizhong.com +gzjk120.com +gzjkfk.com +gzjkfund.com +gzjkjl.com +gzjkqh.com +gzjkyljt.com +gzjlp.com +gzjlwl.com +gzjlwy.com +gzjlxh.com +gzjmyy.com +gzjob.net +gzjpad.com +gzjqd.com +gzjrkg.com +gzjs020.com +gzjsxh.com +gzjt.cc +gzjtch.com +gzjtjx.com +gzjtjy.com +gzjtxh.com +gzjtxx.net +gzjtzy.net +gzjunbo.net +gzjunyu.com +gzjuqi.com +gzjvcom.com +gzjxchem.com +gzjyh.com +gzjykj.com +gzjyme.com +gzjyypt.com +gzjz-auto.com +gzjzc.com +gzkaiheng.com +gzkaiyue.com +gzkangyuan.com +gzkcsj.com +gzkcsjw.com +gzking.com +gzkint.com +gzkmbg.com +gzkofa.com +gzktm.com +gzkuaiyingyong.com +gzkunmao.com +gzkydzyyy.com +gzlarc.com +gzlawyer.org +gzlex.com +gzlgsyxx.com +gzli.com +gzliancun.com +gzlib.org +gzlig.com +gzlight.com +gzliyuanhb.com +gzljsl.com +gzlnholdings.com +gzlsgy.com +gzlt.net +gzlujiao.com +gzlushun56.com +gzlutong.com +gzluxlife.com +gzlwrc.com +gzlwycft-tencentclb.cloud +gzlwycft-tencentclb.com +gzlwycft-tencentclb.net +gzlwycft-tencentclb.work +gzlyhlawyer.com +gzlz307.com +gzlzfm.com +gzm1.com +gzmama.com +gzmath.com +gzmc668.com +gzmcg.com +gzmcgjcpt.com +gzmediaclick.com +gzmedri.com +gzmeichang.com +gzmiden.com +gzminjia.com +gzmiyuan.com +gzmlfcyy.com +gzmofa.com +gzmould.com +gzmpc.com +gzmri.com +gzmstech.com +gzmtr.com +gzmtrticket.com +gzmylike.com +gzmzedu.com +gznaturn.com +gznbsyy.com +gzncstudios.com +gznemo.com +gznf.net +gznftz.com +gzngn.com +gznict.com +gznotes.com +gznw.com +gznxbank.com +gznyjj.com +gznypfk.com +gzocl.com +gzomick.com +gzopen-tencentclb.cloud +gzopen-tencentclb.com +gzopen-tencentclb.net +gzopen-tencentclb.work +gzoyrr.com +gzpaco.com +gzpeite.com +gzpeiyou.com +gzpfs.com +gzpg.net +gzpgroup.com +gzpgs.com +gzph.net +gzpma.com +gzpoint.com +gzpotent.com +gzppa.org +gzprg.com +gzprobig.com +gzpy120.net +gzpydlc.com +gzpyxz.net +gzqbd.com +gzqiche.com +gzqixun-tech.com +gzqljxd.com +gzqsts.com +gzqunsheng.com +gzqygl.com +gzqz.com +gzrand.com +gzrandr.com +gzrch.com +gzrcqf.com +gzrecruit.com +gzredpine.com +gzrh.com +gzrishun.com +gzrkt.com +gzrobot.com +gzrobots.com +gzrqhyxh.com +gzrrj.com +gzrskh.com +gzrsksxxw.com +gzrtnet.com +gzrycl.com +gzsaf.com +gzsbdq.com +gzscbio.com +gzschknyy.com +gzscjrh.com +gzsdwrmyy.com +gzselon.com +gzsenergy.com +gzsenzheng.com +gzsewage.com +gzsg.org +gzsgczb.com +gzshaudio.com +gzsheraton.com +gzshiran.com +gzshuangbao.com +gzshuimh.com +gzshujuhui.com +gzshyk.com +gzsiyuan.com +gzsj.live +gzsjgxcl.com +gzsjjs.com +gzsjyzx.com +gzsjzzsxh.com +gzskysoil.com +gzslyy.com +gzsonic.com +gzsouth.com +gzspm.com +gzspring.com +gzspt.com +gzsq.com +gzsqkfyy.com +gzsqmxx.com +gzsrmyy.com +gzsrunda.com +gzssltzinc.com +gzssnzx.com +gzssyyy.com +gzstarship.com +gzsttc.com +gzstv.com +gzstw.com +gzstyq.com +gzsu.net +gzsuike.com +gzsums.net +gzsunny.com +gzsw168.com +gzswgf.com +gzswjs.com +gzsxds.com +gzsyyxh.com +gzszfgjj.com +gzszgas.com +gzszgyjt.com +gzszjl.com +gzszsj.com +gzszyy.com +gztaiyou.com +gztalx.com +gztamude.com +gztcdj.com +gztcm3.com +gztea.vip +gzteacher.com +gztextiles.com +gztfgame.com +gzthfy.com +gzthrc.com +gztig.com +gztime.cc +gztit.com +gztlgc.com +gztopkt.com +gztoptour.com +gztotem.com +gztowngas.com +gztrseo.com +gztszl.com +gzttjt.com +gztv.com +gztvu.com +gztwkadokawa.com +gztxcw.com +gztxedu.com +gztxfood.com +gztyjx.com +gztyre.com +gztyyedu.com +gztz.org +gztz120.com +gzu521.net +gzuc.net +gzuci.com +gzucm-yhyy.com +gzuni.com +gzupdc.com +gzv6.com +gzvalex.com +gzvstc.net +gzw.net +gzwanbao.com +gzwanju.com +gzwanzhou.com +gzwarriortech.com +gzwaterinvest.com +gzwatersupply.com +gzwcfjd.com +gzwcit.com +gzwcjs.com +gzweicai.com +gzweix.com +gzwhir.com +gzwjnt.com +gzwlcyjt.com +gzwoman.org +gzwonbo.com +gzwrit.com +gzwrjt.com +gzwshd.com +gzwswjc.com +gzwtqx.com +gzwxzf-tencentclb.cloud +gzwxzf-tencentclb.com +gzwxzf-tencentclb.net +gzwxzf-tencentclb.work +gzwynet.com +gzwzhw.com +gzxdd.com +gzxdf.com +gzxdzlyy.com +gzxf35.com +gzxhcbfx.com +gzxhce.com +gzxhhs.net +gzxianc.com +gzxiaoban.com +gzxict.com +gzxijiu.com +gzxinfo.com +gzxjgc.com +gzxrsqj.com +gzxswh.com +gzxsyy.com +gzxszf.com +gzxue.com +gzxulang.com +gzxwtjy.com +gzxxm.com +gzxxtiyu.com +gzxy.net +gzxyh.com +gzxyprint.com +gzxzjy.com +gzyajs.com +gzyangai.com +gzybao.com +gzycdy.com +gzych.vip +gzycsjgs.com +gzyct.com +gzydnewmaterial.com +gzydong.com +gzydwh.com +gzyfjsjt.com +gzyflw.com +gzyhg.vip +gzyiagu.com +gzyilongprinting.com +gzyitsy.com +gzylhyzx.com +gzyouai.com +gzyowin.com +gzyqtlxs.com +gzyqwl.net +gzysnkyy.com +gzytgf.com +gzyucai.com +gzyucai.net +gzyxedu.net +gzyxls.com +gzyxtech.com +gzyycg.com +gzyyjt.net +gzyyma.com +gzyytj.com +gzyywz.net +gzyz699.com +gzzarts.com +gzzbdl.com +gzzc-logistics.com +gzzcs.com +gzzdgg.com +gzzdkg.com +gzzdqy.net +gzzfrl.com +gzzgresin.com +gzzhanmei.com +gzzhitu.com +gzzhixin.com +gzzhrong.com +gzzjgf.com +gzzjtx.com +gzzkjc.net +gzzkzj.com +gzzkzsw.com +gzzldq.com +gzzlfw.com +gzzliot.com +gzzmedu.com +gzzoc.com +gzzongsi.com +gzzoo.com +gzzqy.net +gzzrdc007.com +gzzulin.com +gzzwis.com +gzzx.cc +h-ceo.com +h-cled.com +h-college.com +h-diode.com +h-heguo.com +h-partners.com +h-shgroup.com +h-ui.net +h-world.com +h-zl.net +h0591.com +h0758.net +h12.net +h12345.com +h128.com +h13.mobi +h14z.com +h2-bank.com +h2fc.net +h2gl.com +h2o-china.com +h2os.com +h2vm.com +h2weilai.com +h3806.com +h3807.com +h389.com +h3c.com +h3c.com.hk +h3cfuwuqi.com +h3dns.net +h3ue2s.com +h3wog.com +h3yun.com +h4088.com +h4k5.com +h4sud3rr4pmu.com +h5-share.com +h5-x.com +h5-yes.com +h5.net +h51h.com +h554.com +h55u.com +h576.com +h5abc.com +h5anli.com +h5app.com +h5avu.com +h5cn.com +h5data.com +h5designer.com +h5ds.com +h5eco.com +h5faner.com +h5gamecdn.club +h5gd.com +h5gdsvip.com +h5gdvip.com +h5in.net +h5jun.com +h5king.com +h5kuai.com +h5ky.com +h5le.com +h5login.work +h5ma.com +h5mc.com +h5mgd.com +h5mo.com +h5mota.com +h5mugeda.com +h5no1.com +h5pack.com +h5po.com +h5shuo.com +h5taotao.com +h5tpl.com +h5uc.com +h5util.com +h5video.shop +h5wap.com +h5war.com +h5youxi.com +h5yunban.com +h5zhifu.com +h61889.com +h6969.com +h6app.com +h6room.com +h6ru.net +h7ec.com +h7fpuyk8.com +h803w.com +h863.com +h99998888.com +h99999999.com +ha-airport.com +ha47.net +ha95158.com +ha97.com +haawking.com +habadog.com +habbygames.com +habctv.com +habwjc.com +hach-hanna.com +hachicnc.com +hacjkq.com +hack0nair.me +hack520.com +hack58.com +hack6.com +hackav.com +hacker5t2ohub.com +hackerav.com +hackernews.cc +hackhome.com +hackhp.com +hackhw.com +hacking-linux.com +hackinn.com +hackjie.com +hackliu.com +hacknical.com +hackp.com +hackpascal.net +hackrf.net +hackroad.com +hackyh.com +hacori.com +hacpai.com +haczjob.com +hadax.com +hadewu.com +hadobi.com +hadsky.com +haeicr.world +haers.com +haersgroup.com +haeye.net +hafei.com +hafuyoufk.com +hagaozhong.com +hagibis.com +haguan.com +haguworld.com +haha168.com +haha33.com +haha360.com +haha365.com +haha9911.com +hahack.com +hahaertong.com +hahait.com +hahajing.com +hahasou.com +hahasz.com +hahaurl.com +hahawen.com +hahayouxi.com +hahazhao.com +hahon.com +hahour.com +hai-jiang.com +hai.pet +hai360.com +haianbank.com +haianbm.com +haianedu.net +haianw.com +haianyaoye.com +haianzhuangshi.com +haibao.com +haibaobaoxian.com +haibaofoods.com +haibaoptech.com +haibaoyl.com +haibaoyouxi.com +haibeinews.com +haibian.com +haibianshibei.com +haibowh.com +haiboyi.com +haica.cc +haicent.com +haichangchina.com +haichangoceanpark.com +haichen-logistics.com +haichuang3d.com +haichufang.com +haici.com +haicj.com +haicnh.com +haicoder.net +haidaibao.com +haidaike.com +haidaoteam.com +haidaotrip.com +haidaozhu.com +haidegroup.com +haidian-marathon.com +haidii.com +haidilao.com +haidilao.net +haidilao.us +haidubooks.com +haidutouzi.net +haier-ioc.com +haier.com +haier.hk +haier.net +haiercash.com +haierfinancial.com +haiermoney.com +haiershequ.com +haiershui.com +haiersmarthomes.com +haierubic.com +haieruplus.com +haifangbest.com +haifanwu.com +haifuhospital.com +haige.com +haigeek.com +haigeer.com +haigehome.com +haigoose.com +haigouyan.com +haigugroup.com +haigui001.com +haihepharma.com +haihetour.com +haihuainternational.com +haihub.co +haihuishou.com +haiintelligent.com +haijia.org +haijianchuxing.com +haijianstock.com +haijiaonet.com +haijiaoshi.com +haijiasu.com +haijizq.com +haijob.com +haijt.com +haijudoc.com +haijunda.com +haikegroup.com +haikejin.com +haikele.com +haikeoutdoor.com +haiketrip.com +haikouvw.com +haikouwater.com +hailanchem.com +hailanggroup.com +hailea.com +hailiang.com +hailiangbio.com +hailiangedu.com +hailiangip.com +hailiangstock.com +hailiangxinxi.com +hailichemical.com +hailidoctor.com +haililiang.com +hailin.com +hailongfoods.com +hailouw.com +hailunpiano.com +hailuoai.com +hailuowu.com +haima.com +haima.me +haima001.com +haimacloud.com +haimacloudpc.com +haimaiyun.com +haiman.io +haimaoji.com +haimawan.com +haimeec.com +haimi.com +haimian.com +haimin.net +haimini.com +haimosic.com +haina.com +haina.net +hainaguangdian.com +hainajc.com +hainan.com +hainan.net +hainan0898.net +hainanairlines.com +hainancom.com +hainancp.com +hainandc.com +hainanfp.com +hainanfz.com +hainanjiuzi.com +hainanjk.com +hainanlawyer.org +hainanlecheng.com +hainanruiyuan.com +hainanwangdai.com +hainanyouxi.com +hainanyumu.com +hainanzuojia.com +hainawater.com +hainayun.net +hainiaowo.com +hainic.com +haining.com +haining.tv +hainingnews.net +hainiubl.com +hainiugo.com +hainiuxy.com +hainuotech.com +haiotsys.com +haipal.com +haipengtoy.com +haipinggroup.com +haipuzhiwu.com +haiqianghm.com +haiqigame.com +haiqingyanyu.com +haiqisoft.com +haiqq.com +haiqu.vip +hair43.com +hair8.net +hairbobo.com +hairboxonline.com +hairenren.com +hairology.net +hairongsw.com +hairuichem.com +hairuituo.com +hairunce.com +hairunmedia.com +hairunpictures.com +hairxmf.com +hairycrabs.com +haisco.com +haisenyouxi8.com +haishengfrp.com +haishensl.com +haishiyiliao.com +haishui.cc +haishun.com +haishuokj.com +haishuu.com +haisongta.com +haita.io +haitaibrowser.com +haitaichina.com +haitakuajing.com +haitangmm.com +haitangw.cc +haitangw.net +haitao.co +haitaohub.com +haitaoj.com +haitaolab.com +haitaoqq.com +haitaotong.com +haitaozu.org +haitian-food.com +haitian-group.com +haitian.com +haitiangroup.com +haitianhome.com +haitianpm.com +haitianshuiwu.com +haitl.com +haitong.com +haitongjiaoyu.com +haitou.cc +haitou360.com +haitoujia.com +haituie.com +haitunshenghuo.com +haitunvoice.com +haitunwallet.com +haitunzhibo.com +haitunzhidao.com +haitunzixi.com +haituoqi.com +haitutech.com +haiwaicat.com +haiwaichongzhi.com +haiwaihuafei.com +haiwaimoney.com +haiwaioo.com +haiwaiyou.com +haiwaiyoujia.com +haiwangbuyu.com +haiwanxinxi.com +haiwd.com +haiwei-tech.com +haiweili.com +haiwell.com +haiwen-law.com +haiwenky.com +haiwu.com +haixiachina.com +haixiangkuajing.com +haixin.com +haixin5.com +haixindichan.com +haixinews.com +haixing6.com +haixingbangfu.com +haixingcloud.com +haixinhui.com +haixinpatent.com +haixiulive.com +haixiumv.com +haixiutv.com +haixiuvv.com +haixuan.com +haixue.com +haixuemeili.com +haixuyun.com +haiyang-group.com +haiyang.net +haiyi701.com +haiyiai.tech +haiyingmt.com +haiyingshuju.com +haiyisoft-gz.com +haiyisoft.com +haiymobi.com +haiyong.site +haiyuangabion.com +haiyuangabiou.com +haiyuetechltd.com +haiyun.me +haizhanweb.com +haizhenzhu.com +haizhikj.com +haizhlink.com +haizhoumo.com +haizhu.vip +haizhuyx.com +haizitong.com +haiziwang.com +haizol.com +hajt-cn.com +haju.com +hajw.com +hajzhyxh.com +hakaimg.com +hakchina.com +hakczz.com +hakfqyy.com +hakonespring.com +hakuya.work +halade.com +halcyonz.com +halead.com +halfrost.com +haligame.com +halixun.com +haljl.com +halloar.com +hallofix.com +halobear.com +halomobi.com +halopepper.com +halsplastics.com +haluan2u.com +haluoha.com +haluolinks.com +halvie.com +ham.xin +hamdl.com +hamedal.com +haminol.com +hammypuff.com +hamu.site +hanabi-live.com +hanas.com +hanascitygas.com +hanbi.live +hanbige.com +hanboshi.com +hanbridge.org +hanchacha.com +hanchao9999.com +hancibao.com +hancloud.com +hanclouds.com +hand-china.com +handanhuizhong.com +handanjob.com +handanyz.com +handcn.com +handday.com +handelic.com +handelsen.com +handern.com +handisele.com +handone.com +handongkj.com +handongruanjian.com +handpk.com +handsfree.work +handu.com +handuyishe.com +handyfriendship.com +hanergy.com +hanex.cc +hanfakg.com +hanfan.cc +hanfei.net +hanfeiyl.com +hanfugong.com +hanganxian.com +hangbohaorun.com +hangcha-forklift.com +hangchow.org +hangdagroup.com +hangdaowangluo.com +hangdaxinli.com +hangdianzhizao.com +hangduhc.com +hangf.com +hanggao.net +hangge.com +hanghaimeng.com +hanghang.com +hanghangcha.com +hanghangohye.com +hangjia-tech.com +hangjianet.com +hangjiayun.com +hangjizulin.com +hangkong.com +hangkongxx.com +hanglorygroup.com +hangmaquan.com +hangnakeji.com +hangongjk.com +hangpai.org +hangpu-topsys.com +hangruntech.com +hangshitech.com +hangsi-bio.com +hangtianride.com +hangtu-china.com +hangtunggroup.com +hanguangbaihuo.com +hangugc.monster +hanguu.com +hangw.com +hangwei-media.com +hangxinyiqi.xin +hangyan.co +hangyang.com +hangyecloud.com +hangzhiqiao.com +hangzhouboiler.com +hangzhoueda.com +hangzhouexpo.com +hangzhoufujikura.com +hangzhoujizhang.com +hangzhoujx.com +hangzhouleili.com +hangzhouluohu.com +hangzhoumengfa.com +hangzhouqisheng.com +hangzhousports.com +hangzhoutianqi114.com +hangzhouweifeng.com +hangzhouyiyao.com +hangzhouyq.com +hangzhouzehe.com +hanhai.net +hanhaiqikan.com +hanhe-cable.com +hanhongchina.com +hanhoo.com +hanhua.com +hanhuatin.com +hanihanrf.com +hanjea.com +hanjianbing.org +hanjiaying.com +hanjie.biz +hanjjl.com +hanju-tv.org +hanjuejituan.com +hanjutv.com +hankaiacademy.com +hankaikeji.com +hankchina.com +hanke1688.com +hankeer.org +hankemaoyi.com +hanking.com +hankinggroup.com +hankmo.com +hankunlaw.com +hanlei.org +hanlin-tech.net +hanlin.com +hanlin.press +hanlindong.com +hanlinedu.com +hanlinzhijia.com +hanlka.com +hanlongpiju.com +hanlunjx.com +hanmaa.com +hanmads.com +hanmaidj.com +hanmaker.com +hanmeilin.com +hanmembrane.com +hanmozhai.com +hanniulaser.com +hannor.com +hannto.com +hanon.cc +hanpian.tv +hanpokou.com +hanpupharm.com +hanqigroup.com +hanqinghb.com +hanqunfeng.com +hanrunbt.com +hans-ad.com +hansaoxinxi.xyz +hanschen.site +hansenexpo.com +hansetile.com +hanshinkiki-xuzhou.com +hansholdings.com +hanshow.com +hansight.com +hanslaser.com +hanslaser.net +hansme.com +hansong-china.com +hanspower.com +hanspub.org +hansrobot.com +hanstong.com +hansuku.com +hansunic.com +hanswine.net +hant.cc +hantang59.com +hantangxintong.com +hantangzy.com +hantecables.com +hantele.com +hanterry.com +hantev.com +hantinghotels.com +hantongrc.com +hantongsteel.com +hanvitools.com +hanvon.com +hanvonmfrs.com +hanvontouch.com +hanwa-ch.com +hanweb.com +hanwei1234.com +hanweimetal.com +hanwenzhongyi.com +hanximeng.com +hanxinsheng.com +hanxuew.com +hanyanggroup.com +hanyangmoto.com +hanyanseed.com +hanyaohuanbao.com +hanyi.com +hanyi.studio +hanyipo.com +hanyou.com +hanyougame.com +hanyouwang.com +hanyu.me +hanyuansh.com +hanyudi.com +hanyuguoxue.com +hanyulaoshi.com +hanyutai.com +hanyuwatch.com +hanyya.com +hanzhesh.com +hanzhong123.com +hanzhonggas.com +hanzhoulaser.com +hanzify.org +hanziguan.com +hao-shangliang.com +hao.ac +hao.gg +hao.ink +hao0517.com +hao0724.com +hao0770.com +hao120.cc +hao123-hao123.com +hao123.com +hao123.com.sg +hao123.net +hao123.ph +hao12306.com +hao123img.com +hao123n.com +hao1358.com +hao136.com +hao163.com +hao184.com +hao1cm.com +hao22.com +hao222.net +hao2345.com +hao24.com +hao245.com +hao251.com +hao268.com +hao315.cc +hao315.com +hao353.com +hao360.com +hao394.com +hao3gp.com +hao5.net +hao528.com +hao568.com +hao6.com +hao695.com +hao7188.com +hao753.com +hao76.com +hao774.com +hao86.com +hao9669.com +haoad.org +haoamc.com +haoayi.xyz +haobangni.com +haobangscm.com +haobtc.com +haocaa.com +haocai.com +haocaiqi.net +haocang.com +haochang.tv +haochangyou.com +haoche1.com +haoche51.com +haochedai.com +haocheedai.com +haochehui.com +haochengda.net +haochenmo.cc +haochi123.com +haochijixie.com +haochimei.com +haochu.com +haochuguo.com +haocw.com +haodai.com +haodanku.com +haodaquan.com +haodekuai.com +haodevps.com +haodewap.com +haodewap.net +haodf.com +haodf.org +haodiany.com +haodiaoyu.com +haodingdan.com +haodisoft.com +haodiy.net +haodns123.cc +haodns789.cc +haodns999.cc +haodongdong.com +haodou.com +haodro.com +haoduck.com +haoduhe.com +haoduo.vip +haoduobao6.com +haoduofangs.com +haoduojiaju.com +haoduorou.net +haoduoziti.com +haoe123.com +haoejia.com +haoeyou.com +haofabiao.com +haofakeji.com +haofan005.com +haofang.net +haofang007.com +haofang5.com +haofangkankan.com +haofangyu999.com +haofeng-group.com +haofenshu.com +haofenxiao.net +haofly.net +haofs.com +haofz.com +haoge500.com +haogedu.com +haogj8.com +haogongzhang.com +haohaizi.com +haohan-data.com +haohanfw.com +haohanguo.com +haohanju.com +haohanjx.com +haohanpower.tech +haohanstar.com +haohao8888.com +haohaodoc.com +haohaowan.com +haohaowan.net +haohaoxiuche.com +haohaoxz.com +haohaoyx.com +haohaozhu.com +haohead.com +haoht123.com +haohuan.com +haohuanjiao.com +haohuoa.com +haohuoyuan.com +haohxs.com +haointl.com +haoinvest.com +haoji.me +haojiao.cc +haojiao.net +haojiaolian.com +haojie.work +haojing.org +haojit.com +haojixie.cc +haojixiong.com +haoju5.com +haojue.com +haojue163.com +haojushe.com +haoka88.com +haokale.com +haokan.com +haokan5.com +haokanbu.com +haokanqq.com +haokavip.com +haoke100.com +haokebang.net +haokebio.com +haokecheng.com +haokejie.com +haokeyun.vip +haokongbu123.com +haokoo.com +haoku.net +haokuaiya.com +haolaba.com +haolangtech.com +haolaoshi.tv +haolawyer.com +haole.com +haoled9999.com +haolexiang.com +haolidayiliao.com +haolietou.com +haolifa.com +haolike.com +haoliners.net +haoling.cc +haolints.com +haoliv.com +haolizi.net +haolongsci.com +haolvbt.com +haolyy.com +haoma.com +haoma123.com +haomagujia.com +haomai.net +haomaikeji.com +haomaishe.com +haomaishou.com +haomaitong.com +haomaizhizao.com +haomaku.com +haomei-alu.com +haomenke.com +haomifi.com +haomingguan.com +haommn.com +haomo-tech.com +haomove.com +haomzl.com +haonames.com +haonic.com +haoniu1.com +haonongzi.com +haooyuan.com +haopeixun.com +haoqdl.com +haoqiao.com +haoqihb.com +haoqikan.com +haoqiutiyu.com +haoqixingstem.com +haoqu.net +haoqu99.com +haoqun.vip +haoranbio.com +haorantech.com +haorc.com +haoread.com +haoreagent.com +haorencai.net +haorooms.com +haoruanmao.com +haoruo.com +haosd.com +haoseals.com +haosedaohang.com +haosenchina.com +haoservice.com +haosf.com +haosf.net +haoshangqi.com +haoshanxi.com +haosheng168.com +haoshengmall.com +haoshengyin.org +haoshenqi.com +haoshici.com +haoshifamen.com +haoshipin123.com +haoshiqi.net +haoshsh.com +haoshuaji.com +haoshudi.com +haoshun666.com +haoshunjia.com +haoshunjx.com +haoshuntm.com +haoshuo.com +haoshuyou.net +haoshuyun.com +haositone.com +haosix.com +haoso.com +haosou.com +haosou.net +haosou123.com +haosou360.com +haoss.vip +haost.com +haostay.com +haosulu.com +haote.com +haotengly.com +haotgame.com +haotianhuyu.com +haotihui.com +haotijin.com +haoting.com +haotm.com +haotonggg.com +haotoufa.com +haotougao.com +haotougu.com +haotoys.com +haott.com +haotu3.com +haotui.com +haotyn.com +haouc.com +haowa.com +haowaicaijing.com +haowallpaper.com +haowandeni.com +haowang.shop +haowangjiaohospital.com +haowangpu.com +haowanma.info +haowanok.com +haowanyou.com +haowen100.com +haowenbo.com +haowenshi.com +haowu.com +haowu.link +haowuguo.com +haowusong.com +haowuyunji.com +haoxg.net +haoxiana.com +haoxiangmachine.com +haoxiangyundong.com +haoxiaoguo.net +haoxingchen.com +haoxingcn.com +haoxingroup.com +haoxinpinggu.com +haoxintaikj.com +haoxipu.com +haoxitong.com +haoxiu.net +haoxiyou.com +haoxue.com +haoxue360.com +haoxueche.com +haoxuee.com +haoxyx.com +haoyangmao18.com +haoyao.com +haoyao163.com +haoyaofs.com +haoyaogo.com +haoychuang.com +haoyetaoci.com +haoyintong123.com +haoyisheng.com +haoyishu.com +haoyong.cc +haoyou666.com +haoyouidc.com +haoyouqian.com +haoyouxi.cc +haoyouyinxiang.com +haoyuanxiao.com +haoyue.com +haoyue28.com +haoyuepu.com +haoyun.life +haoyun13.com +haoyun56.com +haoyunbb.com +haoyunlaisz.com +haoyunlawyer.com +haoyunma.com +haoyuntech.com +haoyunwuyou.com +haoyusw.com +haozai120.com +haozaishop.com +haozhai.com +haozhanhui.com +haozhebao.com +haozhexie.com +haozhihs.com +haozhougroup.com +haozhuan.vip +haozhuji.net +haozi.net +haozi.xyz +haozip.com +haozjj.com +haozke.com +haozongjie.com +haozu.com +haozuojia.com +hapco-cn.com +hapg-hitachi.com +hapi123.net +hapids.com +hapingapp.com +hapjs.org +haplat.net +happi123.com +happigo.com +happiness9999.com +happy-ti.com +happy88.com +happycodeboy.com +happycoding.online +happydino.com +happyelements.com +happyeo.com +happyet.org +happyev.com +happyhlddz.com +happyjuzi.com +happykb.com +happykey6.com +happylivelife.com +happymmall.com +happynic.com +happypingpang.com +happyplaygame.net +happysky.org +happystudy.cc +happytimenet.com +happyvalley.link +happywalk.net +happyya.com +haqu.com +haquan.cc +harbin-electric.com +harbin123.com +harborhousehome.com +harbourmooc.com +hardcc.com +hardcoresir.net +hardhard.work +hardkr.com +hardspell.com +hardware114.com +hareonsolar.com +hariogame.com +harj120.com +harleyydavidsale.shop +harmay.com +harmight.com +harmony-et.com +harmony3.com +harmony4s.com +harmonyos.com +harmonywatch.com +harmyy.com +harog.net +harpost.com +harpping.com +harryhorsemedia.com +harrynull.tech +harrypottermagicawakened.com +harseen.com +harsom.com +hart-worldwide.com +harvestcm.com +harvesthanger.com +harworld.com +harworld.work +harzone.com +hasaf.com +hasbyk.com +hasco-group.com +hasea.com +hasee.com +hasee.net +hasen-cn.com +hashyrmyy.com +hasivo.com +haskqyy.com +hasoltd.com +haspig.com +hassbian.com +hassfull.com +hasstatic.com +hastenpharma.com +hasuhasu.com +hatanggame.com +hatangqp.com +hatangyx.com +hatelifu.club +hatfav.com +hatjedu.com +hatlonely.com +hatoem.com +hatro.cc +hatter.ink +haval-global.com +have.ink +havefun.im +havevisa.com +havewo.com +hawagame.com +hawanyx.com +hawbel.com +haweigroup.com +hawjob.com +hawjwl.com +hawkaoe.net +hawkeye.fun +hawkfilter.com +hawkhai.com +hawtaimotor.com +haxdjx.com +haxm.com +haxwx.cc +hayao.com +hayaoym.com +hayge.com +haygo.com +hayi.cc +hayseen.com +hazp.net +hazpw.org +hazq.com +hb-163.com +hb-ecloud.com +hb-gjj.com +hb-green.com +hb-hengda.com +hb-jn.com +hb-ly.com +hb-sx.net +hb-water.com +hb-ws.com +hb-xydq.com +hb-young.com +hb0561.com +hb0771.com +hb10000.com +hb10000sale.com +hb1000kv.com +hb110.cc +hb12333.com +hb191.com +hb2h.com +hb2stream1.baoxinwen.com +hb30.com +hb3rm.com +hb500.com +hb56.cc +hb96369.com +hb96568.com +hbaas.com +hbaec.com +hbafa.com +hbafxh.org +hbahyy.com +hbairport.com +hbanbao.com +hbapia.vip +hbasstu.net +hbbaidu.com +hbbfyfy.com +hbbidcloud.com +hbbidding.com +hbblxb.com +hbbmjd.com +hbbnqy.com +hbbrgd.com +hbbst99.com +hbbsw.vip +hbbutler.com +hbbwg.net +hbbxpx.com +hbbyb.com +hbbzyys.org +hbca110.com +hbcbly.com +hbccp.org +hbccpit.org +hbcdc.com +hbcdyz.com +hbcg.cc +hbchen.com +hbchufeng.com +hbcjh.net +hbcjkcfwjt.com +hbcjlq.com +hbcjw.com +hbcjxx.com +hbclgg.com +hbcljyc.com +hbclqcw.com +hbcoal.com +hbcof.com +hbcofco.com +hbcourt.org +hbct-wiremesh.com +hbctgs.com +hbcthotels.com +hbctic.com +hbctjk.com +hbctjt.com +hbcwt.com +hbcxpm.com +hbcyclub.com +hbcydlqc.com +hbcyyy.com +hbdangyang.com +hbdckj.com +hbddjt.com +hbddrn.com +hbdefon.com +hbdfmlw.com +hbdjcc.com +hbdjk.com +hbdmia.com +hbdschem.com +hbdssb.com +hbdtjqj.com +hbdx-kdyy.com +hbdzcg.com +hbdzky.com +hbdzxx.com +hbeda.org +hbedky.com +hbeducloud.com +hbeeia.com +hbekt.com +hbema.net +hbepec.com +hbfesco.com +hbfie.org +hbfintech.com +hbfootball.com +hbfoundry.org +hbfqyjt.com +hbfsh.com +hbfy.com +hbfybj.com +hbfyhb.com +hbfzb.com +hbg66.club +hbgajg.com +hbgbdst.com +hbgcxj.com +hbgdsfy.com +hbgdwl.com +hbgis.org +hbgj-3.com +hbgj.com +hbgk.net +hbglky.com +hbglobal.com +hbgr.net +hbgrb.net +hbgroups.com +hbgsetc.com +hbgswl.com +hbgwy.org +hbgydxw.com +hbgzh.com +hbha027.com +hbhaolinju.com +hbhcdn.com +hbhcgt.com +hbhdhd.com +hbhjrzzl.com +hbhm.net +hbhml.com +hbhmxx.com +hbhongrunxwy.com +hbhqzyc.com +hbhtcm.com +hbhtgroup.com +hbhtxx.com +hbhuamei.com +hbhuipu.com +hbhxbb.com +hbhxgroup.com +hbhyychem.com +hbhz.net +hbiclqc.com +hbicpa.org +hbidc.net +hbifeng.com +hbinitiate.com +hbipdc.com +hbisco.com +hbisv.com +hbitg.com +hbjbjt.net +hbjcgjg.com +hbjcgy.com +hbjcxy.com +hbjdxt.com +hbjgwl.com +hbjhc.com +hbjhkfcyy.com +hbjhpx.com +hbjia.net +hbjinnong.com +hbjinshenglan.com +hbjir.com +hbjjrb.com +hbjk114.com +hbjkjt.com +hbjmcjjt.com +hbjmyljs.com +hbjob88.com +hbjomay.com +hbjpim.com +hbjsinfo.com +hbjsxg.com +hbjtfwxh.com +hbjtjsjt.com +hbjttz.com +hbjtwljtyxgs.com +hbjtwlpt.com +hbjtzb.com +hbjubao.com +hbjxad.com +hbjxjy.org +hbjxjyw.com +hbjxym.com +hbjy.net +hbjyjmzg.com +hbjzgw.com +hbjzxh.com +hbjzzx.com +hbkggroup.com +hbkgy.com +hbkj-sic.com +hbklsl.com +hbkqw.com +hbksw.com +hbky.com +hbkyby.com +hbkzw.com +hblbjg.com +hblccy.com +hblds.com +hbldwx.com +hblhfrp.com +hblhnykj.com +hbliti.com +hblq.com +hblszzyy.com +hbltyh.com +hbltzb.com +hbltzx.com +hblxxx.com +hblynk.com +hbm360.com +hbmajiang.com +hbmchina.com +hbmes.com +hbmingjie.com +hbmmtt.com +hbn68.com +hbnews.net +hbnewsoft.com +hbneww.com +hbnfxm.com +hbnholdings.com +hbnxb.net +hbnyfzjt.com +hbnz.net +hbomick.com +hbooker.com +hboxs.com +hbpangu.net +hbpch.com +hbpengxi.com +hbpic5.com +hbpictures.com +hbppa.org +hbpryy.com +hbptzsbw.com +hbpukang.com +hbpvc.com +hbpx.net +hbqcxy.com +hbqingteng.com +hbqmys.com +hbqndc.com +hbqtgg.com +hbqydz.com +hbqyxy.com +hbr-caijing.com +hbrbmedia.com +hbrc.com +hbrchina.org +hbrchinese.org +hbrcxcl.com +hbrd.net +hbrdt.com +hbrebond.com +hbrfxh.com +hbriso.com +hbrmhospital.com +hbrsks.co +hbrsks.net +hbrsksw.com +hbruiao.com +hbruicai.com +hbrunfeng.com +hbrunlin.com +hbryzx.net +hbrzkj.com +hbs-nd.com +hbscd.com +hbsczx.com +hbsczzxy.com +hbsdenterprise.com +hbseasky.com +hbsfdx.com +hbsfedu.com +hbsfjtgs.com +hbsgsq.com +hbshanhe.com +hbshengbangwl.com +hbshgzx.com +hbshichang.com +hbshls.com +hbshunda.com +hbsia.org +hbsjym.com +hbsjzyxh.com +hbskw.com +hbslft.com +hbslndx.com +hbslxzx.com +hbsmservice.com +hbsmtxh.com +hbsmwljt.com +hbsql.com +hbsrjt.com +hbsrjyy.com +hbssfw.com +hbssttz.com +hbsszx.com +hbstars.com +hbsti.com +hbstoo.com +hbsunlink.com +hbswjt.com +hbswkj.com +hbswmyyxgs.com +hbsxkyy.com +hbsxly.com +hbsxwljt.com +hbsxzjw.com +hbsygw.com +hbsz120.com +hbszbykj.com +hbszfw.com +hbszjsjt.com +hbszlcc.com +hbszsv.com +hbsztv.com +hbszxyjhyy.com +hbszzk.com +hbszzx.com +hbtcmu.com +hbtcw.com +hbtea.com +hbtengniu.com +hbtjryp.com +hbtlh.com +hbtljg.com +hbtmjt.com +hbtobacco.com +hbtqzx.com +hbtvc.com +hbtycp.com +hbtycyjt.com +hbtyxh.com +hbun.net +hbvtc.net +hbwanhao.com +hbwanrun.com +hbweid.com +hbwenchang.com +hbwh.net +hbwhcyw.com +hbwhcyxh.com +hbwhexpo.com +hbwhjj.com +hbwjs.com +hbwljm.com +hbwlykt.com +hbwsrc.net +hbwuxue.com +hbwuye.com +hbww.org +hbxcw.com +hbxdf.com +hbxgzls.com +hbxhfc.com +hbxhxkj.com +hbxinfadi.com +hbxingchi.com +hbxmcy.com +hbxot.com +hbxtzx.com +hbxtzy.com +hbxxy.com +hbxyjob.com +hbxytc.com +hbyangyuan.com +hbyczk.com +hbydsg.com +hbydsy.com +hbyh0561.com +hbyhfcyy.com +hbyidu.com +hbyisen.com +hbyjfs.com +hbylgov.com +hbyljf.com +hbylzx.com +hbymfswz.com +hbynet.net +hbyouyunyouke.com +hbyoyo.com +hbyqtl.com +hbysfhm.com +hbyt56.com +hbyuanhao.com +hbyunxi.net +hbyunyang.net +hbyybwff.com +hbyysw.com +hbzaxh.com +hbzbw.com +hbzcpg.com +hbzgjx.com +hbzh.net +hbzhan.com +hbzhjxzz.com +hbzhonghai.com +hbzjjk.com +hbzjrx.com +hbzjzb.com +hbzknet.com +hbzkw.com +hbzkzxw.com +hbzm.cc +hbzmw.com +hbzncz.com +hbzqzx.com +hbzsb.com +hbzst.com +hbzszy.net +hbztn.com +hbzuojia.com +hbzyjsjt.com +hbzzzzw.com +hc-byq.com +hc-cdn.com +hc-overseas.com +hc-ph.com +hc-software.com +hc-sre.com +hc-testing.com +hc01.com +hc121.com +hc12306.com +hc23.com +hc360.com +hc376.com +hc39.com +hc3yy.com +hc6756.com +hc79.com +hc943.com +hca258.com +hcaj.com +hcazb.com +hcbbs.com +hcbnjy.com +hcbuy.com +hcbyq.com +hcc11.com +hcccia.com +hccenter.net +hcciot.com +hcclhealthcare.com +hccoeutg.com +hccpcba.com +hcdamai.com +hcdyhr.com +hceia.com +hcepay.com +hcfac888.com +hcfc168.com +hcftyy.com +hcgaokong.com +hcglzj.com +hcgroup.com +hcgtravels.com +hch518.com +hchbblg.com +hchbsb.com +hchezhu.com +hchina.com +hchlidc.com +hchliot.com +hchongren.com +hcicloud.com +hcinfo.tech +hcj1952.com +hcjike.com +hcjt.cc +hckg.com +hckj.org +hclonely.com +hclouder.com +hcmiraefund.com +hcmofen.com +hcnaimo.com +hcpharm.com +hcqixinhb.com +hcqxbj.com +hcrlm.com +hcschengtou.com +hcsd123.com +hcsdhgjzx.com +hcsemitek.com +hcshangwu.com +hcsilk.com +hcsjddc.com +hcsound.com +hcswgx.com +hcsyjt.com +hct-test.com +hctxf.org +hcty.com +hctzbj.com +hcvac.com +hcwebsite.com +hcwh.ltd +hcwhjd.com +hcwiki.com +hcx123.com +hcx99.com +hcxcw.com +hcxfjq.com +hcxwdb.com +hcxxy.com +hcxy6.com +hcyacg.com +hcydit.com +hcyea.com +hcykt.com +hcypzy.com +hczc.com +hczfgjj.com +hczl.com +hczm1.com +hczq.com +hczr.com +hczs.com +hczsbj.com +hczshb.com +hczxmr.com +hczyw.com +hd-english.com +hd-english.net +hd-mw.com +hd-tvb.com +hd-u.com +hd.gg +hd027.com +hd123.com +hd123.net +hd12333.com +hd199.com +hd199.net +hd2h.com +hd3p.com +hd88.cc +hd8y.com +hdabc.com +hdanc.com +hdanheng.com +hdarea.club +hdavchina.com +hdb.com +hdbaichuan.com +hdbgjt.com +hdbits.org +hdbp.com +hdbus.net +hdbz.net +hdchina.org +hdcmct.org +hdcms.net +hdcy123.com +hdd-group.com +hddata.net +hddgood.com +hddid.com +hddlion.com +hddolby.com +hddznet.com +hdeexpo.com +hdeso.com +hdfax.com +hdfimg.com +hdfybjy.com +hdgetters.com +hdh.im +hdhjtz.com +hdhome.org +hdhosp.com +hdhospital.com +hdhui.com +hditec.com +hdj.me +hdjad.com +hdjingwei.com +hdjt.net +hdjwj.com +hdjx.org +hdjxpx.com +hdkcsjxh.com +hdks.net +hdksjp.com +hdkwa.com +hdkylin.work +hdl-watch.com +hdlcdns.com +hdlchina.com +hdletv.com +hdlogo.com +hdlstage.com +hdlsxh.com +hdltest.com +hdlzmdb.com +hdmiaoc.com +hdmnw.com +hdmooncake.com +hdmryy.com +hdmtv168.com +hdmv.org +hdnd01.com +hdnychina.com +hdp88.com +hdph.com +hdpyqa.com +hdpyqc.com +hdpyqd.com +hdpyqf.com +hdqyf.club +hdrcw.com +hdsay.net +hdschina.com +hdschools.org +hdsdyyy.com +hdslb.com +hdslb.net +hdslb.org +hdsmgw.com +hdtgtm.com +hdtonghe.com +hdtyre.com +hduofen.com +hdurl.me +hdw99.com +hdwbcloud.com +hdwbsaas.com +hdwebpyqa.com +hdwebpyqc.com +hdwebpyqe.com +hdwjc.com +hdwtpay.com +hdwzz.com +hdxing.net +hdxweb.com +hdxxg.com +hdxxw.com +hdxynet.com +hdyanke.com +hdyouxi.com +hdyu.com +hdyujiu.com +hdyxgame.com +hdyxi.com +hdyy95.com +hdyzsw.com +hdzbgs.com +hdzc.com +hdzc.net +hdzcwlian.com +hdzp.com +hdzp.net +hdzuoye.com +hdzxyy.com +he-edu.com +he-ku.com +he-one.com +he17.com +he1j.com +he29.com +heacn.net +head-way.com +headconsultant.com +header.cc +heading123.com +headingfilter.com +headphoneclub.com +headscm.com +heag.com +healforce.com +healrna.com +health-china.com +health-foru.asia +healthan.net +healthbbs.net +healthcareol.net +healthcareyun.com +healthcn.com +healthgv.com +healthjd.com +healthr.com +healthybaike.com +healthych.com +healthydigitallife.com +healzentx.com +heanyo.com +hearfly.com +hearstchina.com +heart-game.com +heartide.com +heartinsti.com +heartxin.com +heating-sh.com +heatingtrace.com +heavenlywind.cc +heavenonearthhealingalternatives.com +hebangdianzi.com +hebbank.com +hebbc.org +hebbr.com +hebca.com +hebcar.com +hebecc.com +hebeeb.com +hebei.cm +hebeieb.com +hebeifanlin.com +hebeifc.com +hebeifeimeng.com +hebeigwy.org +hebeihazhi.com +hebeihualang.com +hebeijd.com +hebeijia.com +hebeijiaxin.com +hebeilyxh.com +hebeiminglan.com +hebeimutian.com +hebeinongzi.com +hebeisaixin.com +hebeishifei.com +hebeishuangning.com +hebeisia.com +hebeitongtai.com +hebeiwl.net +hebeiwulian.com +hebeiyouxi.com +hebeizuqiu.net +heben-eng.com +hebetextile.com +hebgcdy.com +hebgsetc.com +hebgtjt.com +hebi99.com +hebiia.org +hebimalasong.com +hebinhospital.com +hebisf.com +hebitv.com +hebiw.com +hebjxw.com +hebjy.com +hebkjs.com +hebl.name +hebmj.com +hebmusic.com +hebngc.com +hebnx.com +hebolaw.com +hebooming.com +hebotc.com +hebpi.com +hebpolicycube.com +hebradio.com +hebsg.net +hebshanggu.com +hebtig.com +hebtv.com +hebwlfdc.com +hebxakj.com +hebxyjt.com +hebyjxh.com +hebzd.com +hebzhy.com +hebzljx.com +hec-al.com +hec-changjiang.com +hecaijing.com +hecdn.com +hecdn.net +hechanghuyu.com +hechangshipin.com +hechangtech.com +hechengeco.com +hechiguotou.com +hechijinxin.com +hechuang.info +hechuangxinxi.xyz +hechuann.com +heclife.com +heclouds.com +hecoe.com +hecpharm.com +hedaoapp.com +hedaozi.com +hedasudi.com +hedaweb.com +hedgehogbio.com +hedgehogrock.com +hedlaonga.com +hedongli.com +hedpump.com +hedu.net +heduibu.com +heduismart.com +hedysx.com +heec.com +heeeeeh.com +heeeepin.com +heemoney.com +heenee.com +heepay.com +heerit.com +hefagear.com +hefei.cc +hefeifc.com +hefeilaws.com +hefeimarathon.com +heflc.com +hefls.net +hefunoodles.com +hegii.com +hegouvip.com +hegsryjq.com +hehagame.com +hehang.net +hehecam.com +hehecamera.com +hehejin.com +hehesheng.com +heheshouyou.com +hehesy.com +hehewan.com +heheyx.com +hehooo.com +hehouse.com +hehuapei.com +hei.red +heibai.net +heibaicao.com +heibaige.com +heibailianmeng.com +heibaimeng.com +heibaixiaoyuan.com +heibandongcha.com +heibanwa.mobi +heibaow.com +heibaowuliu.com +heibian.com +heicha.com +heicheng51.com +heidaren.com +heidiankeji.com +heigaga.com +heightindustry.com +heiguang.com +heiguang.net +heiha.net +heihei.com +heiheiyuyin.com +heihekeji.com +heijiao.net +heijiaovip.com +heike07.com +heilanhome.com +heilei.com +heilifun.com +heilongjianggames.com +heiluo.com +heima010.com +heimabao.com +heimac.net +heimadao.com +heimadata.com +heimai666.com +heimajijin.com +heimalanshi.com +heimaoseo.org +heimaoseojishu.com +heimaoshe.com +heimaying.com +heimeiai.com +heimeng.net +heimizhou.com +heiniubao.com +heiniufeiye.com +heinote.com +heinw.com +heirenlei.com +heisha.net +heishao.net +heishenhua.com +heishou.org +heistbeer.com +heitao.com +heitao2014.com +heitaosan.com +heitiane123.com +heitu.com +heitukeji.com +heiwahospital.com +heiwangke.net +heixi.com +heiyan.com +heiyan.org +heiyange.com +heiyanimg.com +heiying.cc +heiyu.cc +heiyu.space +heiyunxitong.com +heizhushoes.com +hejia-china.com +hejiang.com +hejiangroup.com +hejiantech.com +hejichip.com +hejicut.com +hejin588.com +hejujk.com +hejun.com +hejxf.com +heketai.com +hekouxin.com +heku.org +hel168.com +helensbar.com +heliang.cc +helianhealth.com +helianwap.com +helichina.com +heliforklift.com +helight.info +helijia.com +helingqi.com +helipay.com +helishun.com +helitzc.com +heliuyan.com +hello-fpga.com +hello-inc.com +hello1010.com +hello123.com +hellobanma.com +hellobike.com +hellobiye.com +hellocq.com +hellocq.net +hellodive.com +hellof1.com +helloflask.com +hellogame.net +hellogithub.com +hellogitlab.com +helloglobal.com +hellogroup.vip +hellogslb.com +hellohnb.com +hellohuohu.com +helloimg.com +helloinstruments.com +hellojava.com +hellokid.com +hellokidvip.com +hellomeowlab.com +hellomida.com +hellonitrack.com +hellopcb.com +hellorf.com +hellostreetcat.com +hellotalk8.com +hellotw.com +hellotyping.com +helloweba.com +helloweba.net +hellowebfont.com +hellowgame.com +helloworld.net +helloxjn.com +helloxkb.com +helloyao.com +helmicro.com +helmtower.com +helnon.com +helo11.com +helohub.com +help-w.com +helpmeng.com +helpmepick.net +helps.live +helpson.com +helpton.com +helptousa.com +helpweixin.com +helunyun.com +heluowenhua.net +helywin.com +hema.ren +hema.wiki +hemahuashi.com +hemaish.com +hemajs.com +hemamax.com +hemanc.com +hemanzi.com +hemaos.com +hemaread.com +hemaxiaofen.com +hemayouxi.com +hemayouxi.net +hemayun.com +hemayx.com +hemetal.com +hempelgroup.com +hen360.com +henai.com +henaiwan.com +henan100.com +henanart.com +henanbojin.com +henance.com +henancme.net +henanfucai.com +henangames.com +henaninfo.com +henanjianling.com +henanjiqiren.com +henanjubao.com +henanrc.com +henansha.com +henanshengtang.com +henansyj.com +henanxinjiang.com +henanyikayi.com +henanyixue.com +henanzhida.com +henanzsb.com +henau.net +henbt.com +hencin.com +hencoder.com +hendera.com +henduofang.com +heng-f.com +heng98.com +hengan-instruments.com +hengansl.com +hengaodebj.com +hengbao.com +hengbaochuju.com +hengbinzl.com +hengbogroup.com +hengchangda.com +hengdafilm.com +hengdafuji.com +hengdawenbo.com +hengdaxincai.com +hengdayun.com +hengdeegroup.com +hengdian.com +hengdianfilm.com +hengdianworld.com +hengdrive.com +hengdulaw.com +hengfang.com +hengfasd.com +hengfengtires.com +hengfujz.com +henggufood.com +henghe-group.com +henghe666.com +henghengmao.com +henghongjixie.com +hengjiafish.net +hengjianyy.com +hengjiatouzi.com +hengjiecdn.com +hengjiu-pt.com +hengjixiaofang.com +hengkun.com +hengli.com +hengliguoji.com +henglihotels.com +hengqian.com +hengqifeng.com +hengqijy.com +hengqikuaiji.com +hengqinmarathon.com +hengrui.com +hengruisensor.com +hengshan01.com +hengshanpharm.com +hengshengpark.com +hengshuilaobaigan.net +hengshuiyake.com +hengtai-law.com +hengtaiboyuan.com +hengtiansoft.com +hengtianyun.com +hengtonggf.com +hengtonggroup.com +hengtonglog.com +hengtongzhineng.com +hengxiangtaji.com +hengxinjinshu.com +hengxinyongli.com +hengxucapital.com +hengxueedu.com +hengyagongshui.com +hengyan.com +hengyankeji.com +hengyemould.com +hengyi.com +hengyimining.com +hengyishihua.com +hengyoux.com +hengyu.work +hengyuansilk.com +hengyuanzn.com +hengyudata.com +hengyuefund.com +hengyulighting.com +henha.com +henhaoji.com +henku.com +henkuai.com +henkung.com +henlius.com +henluoli.com +henmimang.com +henningchem.com +henovcom.com +henrayglass.com +henri.ren +hensctai.com +hensgroup.com +henzan.com +henzanapp.com +heodoraiu.com +hepalink.com +hepan.com +hepan.org +hepartshome.com +hepatox.org +hepingdao.net +hepmall.com +hepost.com +hepu123.com +hepurc.com +hepuwang.com +hepuweilai.com +hepuxw.com +heqingloong.com +hercity.com +hercules-logistics.com +hercules-micro.com +herdacdn.com +herdar.com +herdcloud.com +herdpcdn.com +herdsric.com +here120.com +here325.com +herecdn.com +heredlift.com +herenit.com +herllamo-med.com +herllamo.com +hermod1.com +hero-geek.com +hero.com +herocoming.com +heroesports.com +herogame.com +herohr.net +heroic-ltd.com +heroje.com +heroone.com +herosanctuary.com +heroskate.com +herostart.com +heroworld.net +herrel.com +herrywatch.com +herstime.com +herta.space +herton.net +hertzhu.com +heryipharma.com +heshanghuitong.com +heshdity.com +heshecasa.com +heshimilk.com +heshui.com +heshuyun.com +heson10.com +hesongwang.com +hesppe.com +hessianhealth.com +hestudio.net +heta.tech +hetaigroup.net +hetaixin.com +hetao101.com +hetaoa.com +hetaoapis.com +hetaobiancheng.com +hetaocdn.com +hetaodaxue.com +hetaointernal.com +hetaolin.com +hetaousercontent.com +hetaoxingqiu.com +hetianlab.com +hetianyu.cc +hetongamp.com +hetunzu.com +hetusoft.com +heu8.com +heungkong.com +heupxtct.work +heuvan.com +hewaner.com +hewascreen.com +heweather.com +heweather.net +hewebgl.com +heweifurniture.com +hewukeji.com +hexaamc.com +hexagonsemi.com +hexchip.com +hexdo.com +hexgears.com +hexi-electric.com +hexian.ltd +hexianbbs.com +hexiangroup.com +hexianrc.com +hexiaoxiang.com +hexicomtech.com +hexie.cc +hexieshaanxi.com +hexilai.com +hexin-puleather.com +hexinchemical.com +hexindai.com +hexinli.org +hexinwanjia.com +hexiny.com +hexinyu.com +hexmeet.com +hexsen.com +hextower.com +hexun.com +hexun.com.tw +hexuncaizhi.com +hexuu.com +heyang.cc +heyang365.com +heycan.com +heycloudy.co +heycode.com +heycomrades.com +heycross.com +heycsm.com +heydayinfo.com +heygears.com +heyi.com +heyiguangye.com +heyiguoyuan.com +heyimiao.com +heyingcn.com +heyingedu.com +heyinshiliu.com +heyix.com +heymeo.net +heymeowfm.com +heymore.com +heyou51.com +heyplus.com +heyria.com +heytap.com +heytapcloud.com +heytapcs.com +heytapdownload.com +heytapimage.com +heytapmobi.com +heytapugc.com +heytea-co.com +heytea.com +heythings-iot.com +heytime.com +heyuanstone.com +heyuanxw.com +heyuhongfang.com +heyun100.com +heyunnet.com +heywhale.com +heywoodsminiprogram.com +heyyo.com +hez70.com +heze.cc +hezebus.com +hezegd.com +hezejob.com +hezejtjt.com +hezelawyers.org +hezepharm.com +hezeribao.com +hezeswjt.com +hezhidongli.com +hezhong-china.com +hezhongyihua.com +hezhouhuatong.com +hezhoujcy.com +hezi.com +hezibook.com +hezijia.com +hezimi.com +hezongyy.com +hezuvip.com +hf-alu.com +hf-aw.com +hf-iflysse.com +hf0779.com +hf10000.com +hf12345.vip +hf168.net +hf365.com +hf3owy4.sbs +hf777.com +hf960.com +hfabiao.com +hfairport.com +hfanss.com +hfbaogao.com +hfbaozi.com +hfbcjt.com +hfbeta.com +hfbtv.com +hfbz.com +hfcentury.com +hfchosp.com +hfchzyy120.com +hfcsbc.com +hfdaoyuan.com +hfdsgs.com +hfeec-tencentclb.cloud +hfeec-tencentclb.com +hfeec-tencentclb.net +hfeec-tencentclb.work +hffhq.com +hffoil.com +hffund.com +hffy.com +hfgcxx.com +hfgdjt.com +hfgip.com +hfgjj.com +hfgxbus.com +hfhm.com +hfhouse.com +hfhuamei.com +hfhwbgyp.com +hfi-health.com +hfish.net +hfjnxh.com +hfjscn.com +hfjsj.com +hfjtjt.com +hfjxwz.com +hfjzzsxh.com +hfkeheng.com +hfkenfan.com +hfkjsd.com +hfkktt.com +hfksmdl.com +hflbysm.com +hfleda.net +hflengku.com +hflp88.com +hflube.com +hfly.net +hflz.com +hfmama.com +hfmdzx.com +hfmt.net +hfmxs.com +hfnuola.com +hfoj.net +hfplg.com +hfpx.cc +hfqgmagnet.com +hfqinhang.com +hfray.com +hfrc.net +hfrcbc.com +hfrsggff.com +hfsava.com +hfshec.com +hfsia.com +hfsid.com +hfspxh.com +hfssw.com +hfsszgcxh.com +hfswcz.com +hft-sz.com +hftfund.com +hfthink.com +hftogo.com +hftsoft.com +hftx-jt.com +hfw.cc +hfx.net +hfxczj.com +hfyestar.com +hfykd.com +hfykt.com +hfyouqi.com +hfyt365.com +hfyuqin.com +hfyyhyxh.com +hfyylcy.com +hfzfzlw.com +hfzhengxu.com +hfzjxh.com +hfzkgw.com +hfzls.com +hfzssw.com +hg-automation.com +hg-capacitor.com +hg-daigou.com +hg-valves.com +hg1218.com +hg12333.com +hg5177.com +hg568.com +hg8880.org +hg9895.com +hga994.com +hgaas.com +hgcapsule.com +hgcha.com +hgchess.com +hgcitech.com +hgepc.com +hgfdrf.com +hghngroup.com +hghsd.com +hgicreate.com +hgimage.com +hgitv.com +hgj.com +hgj668.com +hgjart.com +hgjl.net +hgjob.com +hgk-group.com +hglaser.com +hgmai.com +hgmri.com +hgnc.net +hgo06070uyi.com +hgo06071uyi.com +hgo06080uyi.com +hgo06081uyi.com +hgo06090uyi.com +hgo06091uyi.com +hgo06101uyi.com +hgo06111uyi.com +hgobox.com +hgoqi.com +hgptech.com +hgqizhong.com +hgqrx.com +hgs001.com +hgscn.com +hgsfy.com +hgsj.com +hgskjc.com +hgskyray.com +hgsyiyuan.com +hgszyyy.com +hgto.cc +hgty5533.com +hgty663.com +hgty7598.com +hguduo.com +hgvalve.com +hgveejt270.vip +hgxxgz.com +hgxxgz.net +hgyrnk.com +hgyys.com +hgzk.com +hgzkb.com +hgzrt.com +hgzxgz.com +hgzxgz.net +hgzxzc.com +hgzyxy.com +hh-gltd.com +hh-honghu.com +hh-jt.com +hh-medic.com +hh-pcbs.com +hh-pmp.com +hh-post.com +hh.global +hh010.com +hh88hh.com +hhaqpx.com +hhax.org +hhbraider.com +hhbwff.com +hhchampion.com +hhchsw.com +hhcjjy.com +hhclby.com +hhcn.com +hhcx-led.com +hhcyt.com +hhczy.com +hhdglm.com +hhdjc.com +hhdna.net +hhfdjz.com +hhfxw.com +hhglys.com +hhh.tm +hhh233.net +hhh800.com +hhh885.com +hhhg258.com +hhhji.com +hhhkpb.com +hhhoo.com +hhhstz.com +hhhtfdj.com +hhhtfin.com +hhhtscf.com +hhhtyg.com +hhitgroup.com +hhjctest.com +hhjgqh.com +hhjsyxh.com +hhjtcn.com +hhju.com +hhk365.com +hhkaobo.com +hhkin.com +hhking.com +hhkmls.com +hhl1916.com +hhlwchem.com +hhmage.com +hhmajiang.com +hhmanhua.net +hhnykg.com +hhnynews.com +hho-hawater.com +hhojs.com +hholy.com +hhozw.com +hhpcbs.com +hhpj.net +hhpmzp.com +hhqs.xyz +hhrcard.com +hhrcw.com +hhrdc.com +hhrsks.com +hhsilk.com +hhsw6688hxcdn.com +hhtmm.com +hhtravel.com +hhtravel.com.tw +hhtvc.com +hhup.com +hhuubb.com +hhuubb.net +hhvv.com +hhwenjian.com +hhwindowmesh.com +hhwl88.com +hhxfqc.com +hhxnycl.com +hhxnyqc.com +hhy0.com +hhycdk.com +hhygame.com +hhygames.com +hhytm.com +hhyungu.com +hhyy.com +hhyy100.com +hhzls.com +hhzm88.com +hhzyjng.com +hi-54.com +hi-books.com +hi-cloud.net +hi-davids.com +hi-gtd.com +hi-lead.com +hi-linux.com +hi-mantech.com +hi-roy.com +hi-sm.com +hi-spider.com +hi-techspring.com +hi-trend.com +hi0755.net +hi138.com +hi169.net +hi1718.com +hi2000.com +hi2000.net +hi772.com +hiaiabc.com +hiao.com +hiapk.com +hiascend.com +hiascend.net +hiavr.com +hibace.com +hibace.net +hibbw.net +hibea.com +hibelarus.com +hibgm.com +hibixin.com +hibogroup.com +hibor.net +hibor.org +hibt.net +hibtc.org +hibusiness.com +hibuzz.net +hiby.cd +hiby.com +hibymusic.com +hic.cloud +hicamelia.com +hicane.com +hiccupx.xyz +hicdma.com +hiceon.com +hichain.com +hicheng.net +hichina.com +hichina.net +hichipharm.com +hichips.com +hicitech.com +hiclc.com +hicling.com +hicloud.com +hicnhm.com +hicomp.com +hiconey.com +hiconics-zn.com +hiconics.com +hicoo.net +hicosmo.com +hicp.net +hicsharp.com +hicss.net +hiczp.com +hid98ys.com +hidery.com +hidesigncloud.com +hiditie.com +hidna.net +hidreamai.com +hidva.com +hiechangzhou.com +hiecheimaetu.com +hiencode.com +hienshi.com +hiersun-ido.com +hiesquire.com +hifangjia.com +hifar.net +hifengli.com +hifi168.com +hificat.com +hifidig.com +hifidiy.net +hifime.net +hifiok.com +hifishuo.com +hifiveai.com +hifkw.com +hifkw.xin +hifleet.com +hifly.mobi +hifly.tv +hifortune.net +hifpga.com +hifreud.com +hifuntv.com +hifuture.com +higer.com +higeshi.com +higgmm.net +high-genius.com +high20-playback.com +high21-playback.com +high22-playback.com +high24-playback.com +high25-playback.com +highdigitizing.com +highfaststudio.com +highfel.com +highfundcorp.com +highgo.com +highhope.com +highleveltrans.com +highlightoptics.com +highlionceramic.com +highlm.com +highly.cc +highsharp.com +highstar.com +hightac.com +hightopo.com +highwayguitar.com +higoldgroup.net +higon.com +higoshipping.com +higrand.com +higuchi.xyz +higy.org +hiheartgo.com +hihell.com +hihocoder.com +hihonor.com +hihonorcdn.com +hihonorcloud.com +hihope.org +hii-go.com +hiido.net +hiigame.net +hiiibrand.com +hiiyun.com +hijackorg.net +hijiangxi.com +hijiaoshi.com +hijin.vip +hijoys.com +hik-cloud.com +hik-express.com +hik-park.com +hikailink.com +hikari-ch.com +hikauto.com +hikcreate.com +hikemobile.com +hikerfans.com +hikihj.com +hikinginternational.com +hikiot.com +hiklife.com +hikmall.com +hikoon.com +hikops.com +hikparking.com +hikrobotics.com +hiksemitech.com +hikstor.com +hikstorage.com +hikunpeng.com +hikunpeng.net +hikvision-jl.com +hikvision.com +hikvisionauto.com +hikyun.com +hilantu.com +hilau.com +hilbcd.com +hile-bio.com +hileap.com +hilemic.com +hilfv.com +hiliad.com +hiliwi.com +hillelmilwaukee.org +hilllei.com +hillstonenet.com +hillyton.com +hilo8.com +hiloletswin.com +hilonggroup.com +hiloong.com +hilqq.com +hiluluke.com +hima.auto +himado.com +himaker.com +himalaya.com +himalaya.cool +himanufacture.com +himarking.com +himawari-japan.com +himehear.com +himeidian.com +himengyou.com +himetoo.com +himile.com +himin.com +himmpat.com +himoral.com +himorale.com +himorfei.com +hin.cool +hinabian.com +hinabiotech.com +hinavi.net +hindiabp-lh.akamaihd.net +hinocn.com +hinotravel.com +hinpy.com +hinsyeow.org +hintsnet.com +hiofd.com +hiooq0417.com +hiosu.com +hioug.com +hiparking.com +hipcam.net +hipcapi.com +hiphi.com +hiphop8.com +hiphotonics.com +hipiao.com +hipole.com +hippoanimation.com +hippter.com +hipu.com +hiputian.com +hiqiyu.com +hirain.com +hiram1009-dw.org +hirata-cn.com +hirata-hts.com +hirede.com +hiregex.com +hireye.com +hirige.com +hirisemed.com +hirisun.com +hiroop.com +hirosspac.com +hirossz.com +hirtk.com +hirunsport.com +his.sh +hisaka-china.com +hisavana.com +hiscene.com +hisdnoc.com +hisense-home.com +hisense-plaza.com +hisense-syxs.com +hisense.com +hisensehitachi.com +hisensekf.com +hisern.com +hishouhui.com +hisilicon.com +hisiphp.com +hislota.com +hismarttv.com +hisoar.com +hisoft.com +hisofts.com +hisonracking.com +historychina.net +hisugar.com +hisunplas.com +hisupplier.com +hit180.com +hitachi-helc.com +hitalk.com +hitalkers.com +hitao.com +hitbot.cc +hitctf.com +hite.me +hitechfrp.com +hiteksoft.com +hitergas.com +hitevision-solution.com +hitevision-solutions.com +hitevision.com +hitgk.com +hitnology.com +hitoor.com +hitouch.com +hitoupiao.com +hitour2005.com +hitozumi.com +hitpound.com +hitqs.com +hitrip.info +hitsame.com +hitui.com +hitv.com +hiusers.com +hiveshared.com +hivi.com +hivictor.net +hiwafer.com +hiwaysemi.com +hiwayslaw.com +hiwbb.com +hiwechats.com +hiweixiu.com +hiwelcom.com +hiwiyi.com +hiwms.com +hiworld.com +hiwuhuan.com +hixgo.com +hixianchang.com +hixiaoe.com +hixuexiao.net +hiyd.com +hiyongche.com +hiyouib.com +hiyouqu.com +hiyun.site +hiyun.tv +hizaoan.com +hizh.net +hizhecheng.com +hizj.net +hizom.com +hizyw.com +hizyy.com +hj-bits.com +hj-dog.com +hj-ienergy.com +hj-mail.com +hj-pack.com +hj01.com +hj110.com +hj1951.com +hj44103a1.shop +hjapi.com +hjasiancenter.com +hjbbs.com +hjbxw.com +hjcadc.com +hjchee.com +hjcjifen.com +hjckjt.com +hjclass.com +hjcm.net +hjcpl.com +hjd111.shop +hjd123.com +hjdhdduekcdie.com +hjdict.com +hjdns.com +hjdns.net +hjdshop.cc +hjdzn.com +hjenglish.com +hjg365.com +hjgcd.com +hjgrp.com +hjgtjt.com +hjhrcloud.com +hjido.com +hjiesuan.com +hjinternationalhotel.com +hjiuye.com +hjjg.com +hjjh.com +hjjt.net +hjjunhua.com +hjkhjkl.com +hjkklj.com +hjksjx.com +hjlrw.com +hjlw.com +hjmarathon.com +hjmtzb.com +hjpcc.com +hjpp.net +hjr-exchange.com +hjren.com +hjsj.com +hjtag.com +hjunkel.com +hjw169.com +hjw68.com +hjwsky.com +hjwsxzz.com +hjwxcps.com +hjxcl.com +hjxhg.com +hjxry.com +hjxsjx.com +hjxtv.com +hjy1314.com +hjyanxue.com +hjyc.com +hjygame.com +hjyl.org +hjyyjt.com +hjz4.com +hjz518.com +hjzlg.com +hjzzcl.com +hk-island.hk +hk-jztzjt.com +hk-pwc.com +hk-sz.com +hk-tencentclb.cloud +hk-tencentclb.com +hk-tencentclb.net +hk-tencentclb.work +hk-titan.com +hk-vstart.com +hk-xin.com +hk.uy +hk0523.com +hk603.hk +hk8668.com +hk9.com +hkaco.com +hkaima.com +hkance.com +hkance.xyz +hkanews.com +hkaohua.com +hkbchina.com +hkca.club +hkcd.com +hkcgart.com +hkchat.app +hkcna.hk +hkcoalition.com +hkcpr.com +hkctgbus.com +hkcts.com +hkctshotels.com +hkctsmembers.com +hkcwdc.com +hkd82.com +hkdfc.com +hkdfgroup.com +hkdqgroup.com +hkdzxs.com +hkexpressworld.com +hkfc.hk +hkfcchina.com +hkfdi.com +hkfe.hk +hkfljt.com +hkg3g299r4.com +hkgcloudcs.com +hkgcr.com +hkgj07.com +hkgjcz.com +hkglink.xyz +hkgol.com +hkgsw.com +hkgtedu.com +hkgwater.com +hkhdsyxx.com +hkinsu.com +hkinur.com +hkjinxin.com +hkjnn.com +hkjsrent.com +hkklock.com +hkkuaiyixiu.com +hklego.com +hklmoto.com +hklmxcx.com +hklsqc.com +hkm168.com +hkmedtime.com +hkmeinian.com +hkmipo.com +hkmjd.com +hknbc.com +hknet-inc.com +hkoke.com +hkpep.com +hkproperty.com +hkqbh.com +hkroyal.com +hkrsoft.com +hksc888.com +hkscxh.com +hkserversolution.com +hkslg520.com +hkstv.tv +hkt4.com +hktheone.com +hktidg.com +hku-szh.org +hkvisen.com +hkwb.net +hkwzig.com +hkxbjt.com +hkxen.com +hkxtech.org +hky360.com +hkyukai.vip +hkyxfgs.com +hkyykq.com +hkzlcm.com +hl-bandao.com +hl-brushes.com +hl-epay.com +hl-hengsheng.com +hl95.com +hl95001.com +hlapi.com +hlashop.com +hlb2020.com +hlbcks.com +hlbe365.com +hlbeixiu.com +hlbeixiu.net +hlbf.net +hlblz.com +hlbn.cc +hlbryy.com +hlcdn.cc +hlchsw.com +hlcm.net +hlcode.net +hld558.com +hldbtv.com +hldedu.com +hldfcom.com +hldgajjzd.com +hldgp.com +hldhouse.com +hldhuanbao.com +hldjob.com +hldjz8.com +hldmzg.com +hldnews.com +hldszxyy.com +hlduanjian.com +hledu.net +hlej.com +hlekk.org +hletong.com +hlgad.com +hlgcj.com +hlgdata.com +hlgnet.com +hlgnet.net +hlhfjt.com +hlhjapp.com +hlhmf.com +hlhqdj.com +hlhs.cc +hlhyc.com +hljcqjy.com +hljdata.net +hljgvc.com +hljgwy.net +hljgzkj.com +hljhgckj.com +hljiasen.com +hljjjb.com +hljjkfp.com +hljjytkj.com +hljpm.com +hljpost.com +hljradio.com +hljrcc.com +hljsdm.com +hljszjxhw.com +hljtchina.com +hljtcm.com +hljtv.com +hljtx.com +hljucm.net +hljxgs.com +hljyestar.com +hljyqnj.com +hljyushi.com +hljzc.net +hljzl.icu +hlkd.pro +hlkkwl.com +hlkncse.com +hlktech.com +hlkznsb.com +hllinks.com +hllives.com +hlmmold.com +hlnhw.com +hlnmg.com +hlnpic.com +hlnpm.com +hlo-trade.com +hloong.com +hlqiaojia.com +hlqxj.com +hlread.com +hls-1.wamu.org +hls-video01.cdnvideo.ru +hls.cdn.ua +hls.kqed.org +hls.qguiyang.com +hls.qxtv0763.com +hls.wlrn.mobi +hlsdq.com +hlsimu.com +hltmsp.com +hltx.net +hlupr.com +hlvitamin.com +hlw1588.com +hlwarp.com +hlwidc.com +hlwjnm.com +hlwwhy.com +hlxky.com +hlxstipark.com +hlxsykd.com +hlxsz.com +hlxy.com +hlybar.com +hlyds.com +hlyiq.com +hlytec.com +hlyy8.com +hlyykp.com +hlzaojia.com +hlzq.com +hlzqgs.com +hlzzkj.com +hm-3223.net +hm-optics.com +hm025.com +hm120.com +hm152n.com +hm163.net +hm16888.net +hm169.com +hm588.com +hm5988.com +hmadgz.com +hmarathon.com +hmbzfjt.com +hmchina.com +hmcl.net +hmdx.net +hmedu.com +hmeili.com +hmf-china.com +hmfxw.com +hmgbtv.com +hmgj.com +hmgreat.com +hminvestment.com +hmj666.com +hmjblog.com +hmjc.org +hmkp.org +hmlan.com +hmlcar.com +hmltec.com +hmly666.cc +hmmachine.com +hmmryk.com +hmnst.com +hmoe.link +hmplay.com +hmqg.com +hmqjsb.com +hmrczp.com +hmrsrc.com +hmsemi.com +hmszkj.com +hmtgo.com +hmting.com +hmtnew.com +hmtrhf.com +hmus.net +hmwdj.com +hmwzjs.com +hmx-led.com +hmx3556y0o.com +hmxixie.com +hmxw.com +hmxx.net +hmyzs.com +hmz.com +hmz8.com +hmzhtc.cc +hmzhtc.com +hmzixin.com +hmzjzx.com +hmzs.net +hmzx163.com +hn-binglang.com +hn-cbec.com +hn-hwqjxh.com +hn-medical.com +hn-xqlhw.com +hn0746.com +hn165.com +hn96520.com +hn9mu.com +hnacargo.com +hnacgs.com +hnaec.com +hnaec.org +hnaee.com +hnafxh.com +hnagroup.com +hnagroup.net +hnainfrastructure.com +hnair.com +hnair.net +hnaiya.com +hnamdi.com +hnangel.com +hnanqi.com +hnapay.com +hnasatc.com +hnaues.com +hnbaili.net +hnbemc.com +hnbidding.com +hnbits.com +hnblc.com +hnbljy.com +hnblly.com +hnbntv.com +hnbrush.com +hnbsq.com +hnbtcy.com +hnccpit.org +hnceg.com +hncfa.com +hncgkgjt.com +hnchaosu.com +hnchemtech.com +hnchuangj.net +hnchuangxiangkj.com +hncj.com +hncloud.com +hncmsx.com +hncnedu.com +hncost.com +hncourt.org +hncpu.com +hncreate.com +hncsart.com +hncsmtr.com +hncsvod.com +hnct56.com +hnctw.com +hncu.net +hncwc.com +hncxwater.com +hncytxly.com +hncyzx.com +hndbsp.com +hndca.com +hndcyg.com +hndec.com +hndfbg.com +hndfsrmyy.com +hndgxh.com +hndhsyjt.com +hndlhx.com +hndlks.com +hndmtjc.com +hndnews.com +hndpf.org +hndpx.com +hnds88.com +hndscg.com +hndsyy.com +hndt.com +hndxzte.com +hndybus.com +hndysx.com +hndz413.com +hndzxh.com +hnechz.com +hnedition.com +hnedutv.com +hnerkang.com +hnetn.com +hnetyy.net +hnfa.org +hnfapiao.com +hnfcis.com +hnfcjr.com +hnfck.com +hnfjz.com +hnfles.com +hnfudu.com +hnfyqmj.com +hnfysg.com +hngajs.com +hngangjiegou.com +hngbjy.com +hngdkg.com +hngh.org +hnghzl.com +hngjj.net +hngjx.com +hngks.com +hngoldcorp.com +hngpmall.com +hngqjc.com +hngs.net +hngscloud.com +hngsetc.com +hngtrust.com +hngwg.com +hngwkj.net +hngwmt.com +hngwy.org +hngwzk.com +hngx.net +hngyms.com +hnh.cc +hnhaofang.com +hnhbyxdq.com +hnhcrn.com +hnhdxd.com +hnhflqgc.com +hnhho.com +hnhj.net +hnhjjx.com +hnhlpp.com +hnhnled.com +hnhp.com +hnhsjt.com +hnht56.com +hnhtdg.com +hnhw.com +hnhwly.com +hnhxin.com +hnhxs.com +hnhxxk.com +hnhyfm.com +hnhylx.com +hnhyrc.com +hnhyt.com +hniec.org +hniic.com +hnijunhai.com +hninsure.com +hnisca.org +hniso.net +hnisvc.com +hnitedu.org +hnjbwh.com +hnjcly.com +hnjg.com +hnjiabao.com +hnjing.com +hnjing.net +hnjinmaizi.com +hnjkjn.com +hnjkw.net +hnjme.com +hnjmsk.com +hnjshzy.com +hnjsrcw.com +hnjtcl.com +hnjttz.com +hnjudarhr.com +hnjuhuo.com +hnjyyz.com +hnjzy.org +hnkcjt.com +hnks.com +hnksgf.com +hnktgame.com +hnktzz.com +hnkxy.com +hnkygas.com +hnkzy.com +hnlantian.com +hnlat.com +hnlawyer.org +hnlbdl.com +hnleisu.com +hnlens.com +hnliangku.com +hnlipu.com +hnlshm.com +hnlxq.com +hnlzhd.com +hnlzw.net +hnmangshan.com +hnmcymy.com +hnmdtv.com +hnmgjr.com +hnming.com +hnmjyy.com +hnmks.com +hnmlqianpan.com +hnmqtt.com +hnmrffm888.com +hnmsg.com +hnmsw.com +hnmudi.com +hnmuseum.com +hnmyjt.com +hnmzmy.com +hnnanshang.com +hnnbwdiaosu.com +hnnews.cc +hnnhyy.com +hnninglian.com +hnnkyy.com +hnnx.com +hnnxs.com +hnnyrzzl.com +hnnzwhyy.com +hnoak.com +hnoceanrace.com +hnoexpo.com +hnoscar.com +hnpdig.com +hnpfw.com +hnpic.com +hnpm.cc +hnpolice.com +hnpta.com +hnptschool.net +hnpwholesale.com.au +hnqczy.com +hnqfseed.com +hnqinshi.com +hnqlhj.com +hnqljj.com +hnqljt.com +hnqnw.com +hnquxing.com +hnquyou.com +hnqz.net +hnradio.com +hnrcjl.com +hnrcjob.com +hnrcsc.com +hnrcsc.net +hnrczpw.com +hnredcross.com +hnrich.net +hnrmb.com +hnrmtjg.com +hnrmzy.com +hnrpc.com +hnrrco.com +hnrsks.com +hnrszhjc.com +hnryly.com +hns4j.com +hns5j.com +hnsbxl.com +hnsd2fz.com +hnsdfz.org +hnsdzjy.com +hnsdzsrmyy.com +hnsfdc.com +hnsfjy.net +hnsggzy.com +hnsghsljt.com +hnsgkb.com +hnshengben.com +hnshqfz.com +hnshuntian.com +hnshyzx.com +hnsiia.com +hnsilane.com +hnsite.cc +hnsiwei.com +hnsjgroup.com +hnsjlh.com +hnsjrd.com +hnsktc.com +hnskxy.com +hnsky.net +hnslsdxy.com +hnslshyxh.com +hnslxh.com +hnslytz.com +hnsnnews.com +hnsoftedu.com +hnsong.net +hnsqtg.com +hnsrmyy.com +hnsrmyy.net +hnssjn.com +hnssyhbkj.com +hnssyxx.com +hnst.org +hnstandards.com +hnster.com +hnstguolu.net +hnstjsjt.com +hnswljt.com +hnswsjy.com +hnswxy.com +hnsyda.com +hnsygroup.com +hnsyhj.com +hnsyhm.com +hnsyu.net +hnsyyq.com +hnsyzls.com +hnsyzxyy.com +hnszn.com +hnszyxy.com +hntba.com +hntbpm.com +hntchq.com +hntcm.com +hntcmc.net +hntele.com +hnthrq.com +hntiannuo.net +hntianyue.com +hntic.com +hnticai.com +hntican.com +hntkg1.com +hntky.com +hntlxh.com +hntncdn.com +hntobacco.com +hntqb.com +hntv.tv +hntxcd.com +hntxxy.com +hntzyy.com +hnubbs.com +hnucc.com +hnukai.com +hnwanglong.com +hnwbxx.com +hnwca.com +hnwcl.com +hnwczx.com +hnwd.com +hnwdhk.com +hnwhg.org +hnwhjy.com +hnwisecom.com +hnwlcm.com +hnwlxh.com +hnwlxh.net +hnwlycg.com +hnwsbz.com +hnwtqx.com +hnwwsjzx.com +hnwyxx.com +hnwz8.com +hnwzinfo.com +hnxdf.com +hnxfpfb.com +hnxggas.com +hnxhdn.com +hnxhnews.com +hnxhyl.com +hnxingda.com +hnxljkj.com +hnxmht.com +hnxtkg.com +hnxttv.com +hnxunch.com +hnxuntang.com +hnxxc.com +hnxxyz.com +hnxzctec.com +hnyanglao.com +hnyaoshan.com +hnyaosi.com +hnydf.net +hnydgl.com +hnyesf.com +hnyfkj.com +hnyichang.com +hnyingfang.com +hnyinhan.com +hnyixiao.com +hnysfww.com +hnytgt.com +hnyuanhong.com +hnyuanyou.com +hnyuedu.com +hnyunji.com +hnyunsutong.com +hnyunzhiyi.com +hnyuyuhui.com +hnyydg.com +hnyygroup.com +hnyyws.com +hnyyxj.com +hnyyyfsyy.com +hnyyyz.com +hnyzfwlkj.com +hnyzzy.com +hnzdjsj.com +hnzfcgxh.com +hnzfgjj.com +hnzhangkun.com +hnzhaobiao.com +hnzhijiang.com +hnzhongzhuan.com +hnzhouyi.com +hnzhy.com +hnzjgdkj.com +hnzjip.com +hnzjj.com +hnzjyl.com +hnzkclouds.com +hnzkhbsb.com +hnzlyy.com +hnzm.vip +hnzoc.com +hnzose.com +hnzqw.com +hnzrjy.com +hnzrsc.com +hnzsbw.com +hnzsxh.com +hnztb.org +hnztdq.com +hnztfs.com +hnztqzjx.com +hnzxyy.com +hnzycfc.com +hnzyfy.com +hnzywh.xyz +hnzyxckj.com +hnzyydx.com +hnzyzx.com +hnzzjob.com +hnzzlh.com +hnzzms.com +hnzzrc.com +hoau.net +hobalab.com +hobby-eagle.net +hobbyboss.com +hobosgroup.com +hocheymed.com +hochitech.com +hocode.com +hocodo.com +hodgen-china.com +hodiasflavor.com +hodo170.com +hodoop.com +hoehub.com +hofcc.com +hogacn.com +hogasky.com +hogesoft.com +hoghu.com +hogon17.com +hoho123.com +hoho666.com +hohode.com +hoilon.com +hoing.net +hoisen.com +hojonn.com +hok5v5.com +hokai.com +hokori.online +hokparts.com +hold168.com +holder-pharm.com +holdhr.com +holdsteel.com +holdtwo.com +holichip.com +holike.com +holiland.com +holine.com +holkx.com +holleykingkong.com +hollischuang.com +hollisterco.com +hollwingroup.com +hollycrm.com +hollysource.com +hollysys.com +hollyuc.com +hollywant.com +holmesbio.com +holmesian.org +holoalpha.com +holoremax.com +holsauto.com +holteksupport.com +holyfunny.com +holymalls.com +holyxiongan.com +home0311.com +home0538.com +home0668.com +home133.com +home178.com +home898.com +homearch.com +homearch.shop +homearch.store +homearch.vip +homeartschina.com +homebaseradiators.com +homebehind.com +homecdn.com +homed.me +homedgroup.com +homedo.com +homeindus.com +homeinframes.com +homeinmists.com +homeinns.com +homeintour.com +homekeji.com +homeking365.com +homekingcdn.com +homekoo.com +homekoocdn.com +homelandhotel.com +homelandol.com +homesir110.com +homestyler.com +hometex114.com +hometexjoin.com +hometexnet.com +hometol.com +homey-household.com +homeyao.com +homhow.com +hommk.com +homolo.com +homolo.net +homsoboard.com +homsuncap.com +homylogistics.com +homyu.com +honaenergy.com +honbro.com +honchmedia.com +honco88.com +honda-sundiro.com +honder.com +hondugroup.com +honestmc.com +honestread.com +honesty-environ.com +honf.net +hong-lawfirm.com +hong-shun.com +hongbao.com +hongbao.sh +hongbao.show +hongbaoli.com +hongbeibang.com +hongbeicn.com +hongbizi.org +hongbo-group.com +hongbo-sh.com +hongbo100.com +hongboluo.com +hongcesys.com +hongchangpawn.com +hongchisw.com +hongchuangholding.com +hongda-steeltube.com +hongdaishu.com +hongdamach.com +hongdatec.com +hongdefund.com +hongdian.com +hongdianfund.com +hongdongpumps.com +hongdou.com +hongdoufm.com +hongdoulive.com +hongen.com +hongfasi.net +hongfengye.com +hongfuloi.com +hongganshebei.net +hongguogame.com +hongguoyouxi.com +honghaibengye.com +honghaish.com +honghe-tech.com +hongheiku.com +honghu-muffler.com +honghuajz.com +honghuotai.com +honghusaas.com +honghusoft.com +hongjia138.com +hongjiang.info +hongjibp.com +hongjiejia.com +hongjigroupsz.com +hongjin2.com +hongjing-wh.com +hongjing.com +hongjing3.com +hongjingedu.com +hongjinleather.com +hongkang-life.com +hongkegd.com +hongkeyun.com +hongkongairlines.com +hongkonganran.com +hongkongmeixie.com +hongku.com +hongkun-tech.com +hongkunjinfu.com +honglan123.com +honglans.com +honglimfg.com +honglimingbiao.com +honglipai.net +honglumedia.com +hongm.com +hongmaoshiye.com +hongmeiti.com +hongmeiti.net +hongmen.cc +hongmen.com +hongmingbus.com +hongmo.xyz +hongmoka.com +hongmu.com +hongniang.com +hongniuzyimage.com +hongpai.com +hongpig.com +hongqi.tv +hongqiangmjg.com +hongqiaochina.com +hongqipharma.com +hongqipress.com +hongrenyiyuan.com +hongrida.com +hongrinongye.com +hongrizi.com +hongru.com +hongruihuanjing.com +hongruike.com +hongsanban.com +hongsat.com +hongsegs.com +hongsejiqing.com +hongsenlin.com +hongshan.com +hongshang-led.com +hongsheng-group.com +hongsheng.shop +hongshi88.com +hongshigroup.com +hongshipaint.com +hongshizi.org +hongshn.xyz +hongshu.com +hongshunet.com +hongshunth.com +hongshuxiao.com +hongsong.club +hongsong.info +hongsungifts.com +hongta.com +hongtaijixie.com +hongtair.com +hongtaiscp.com +hongtaiwy.com +hongtastock.com +hongtelecom.com +hongtong588.com +hongtongtube.com +hongttel.com +hongtu.net +hongtu56.com +hongtucad.com +hongtunetwork.com +hongvv.com +hongwenfeh.com +hongwu.com +hongwuhuan.com +hongxiangzaixian.com +hongxiaolong.com +hongxingdl.com +hongxingdl.love +hongxinglin.com +hongxingshangye.com +hongxingzhonggong.com +hongxingzn.com +hongxiu.cc +hongxiu.com +hongxiu158.com +hongyan-e.com +hongyan.info +hongyangsoft.com +hongyangxiezi.com +hongyanhr.com +hongyanjin.com +hongyanliren.com +hongyans.com +hongyantruck.com +hongyaomall.com +hongyawang.com +hongyejixie.com +hongyewuyang.com +hongyi5.com +hongyikun.com +hongyimarine.com +hongyirong.com +hongyu-qi.com +hongyuanpharm.com +hongyuanqh.com +hongyue.com +hongyugroup.com +hongyugz.com +hongyumedical.com +hongyunduo.com +hongyuntx.com +hongyunvren.com +hongyuzps.com +hongze.net +hongze365.com +hongzerc.com +hongzetai.com +hongzhengchem.com +hongzhentextile.com +hongzhigongzuowang.com +hongzhoukan.com +hongzhuangyuan.com +hongzhuojituan.com +honhan.ltd +honkaiimpact3.com +honkaistarrail.com +honkonlaser.com +honlyu.com +honor.com +honorfair.com +honorfile.com +honorofkings.com +honpc.com +honpery.com +honsea.com +honson-china.com +honsonch.com +honstarmemory.com +honsuntec.com +honyanwl.com +honycapital.com +honyfunds.com +honyone.com +honyuan.net +hooan.net +hoodinn.com +hoodong.com +hooenergy.com +hooh5.com +hookan.com +hoolai.com +hoolaigames.com +hoolee8.com +hoolinks.com +hoolo.tv +hoonup.com +hoop-archi.com +hoopchina.com +hoopugames.net +hoosho.com +hooshun.com +hoosuntec.com +hooya.hk +hooyagroup.com +hooyoo.com +hope-bridge.com +hope-m.com +hopebank.com +hopebeauty.com +hopebiol.com +hopebook.net +hopechart.com +hopecool.com +hopeda.com +hopegoocdn.com +hopehook.com +hopemedinc.com +hopenoah.com +hoperun.com +hopes-tech.com +hopetrip.com.hk +hopexr.com +hophingfood.com +hopoot.com +hopsontong.com +horace-liu.com +horain.net +horan.cc +horchips.com +hori-gz.com +hori3d.com +horibaprecision.com +horigames.com +horion.com +horionsw.com +horizon-china.com +horizon.ai +horizon.auto +horizon.cc +horizonfuelcell.com +horizonlawyers.com +horizonrcg.com +horizonsanya.com +horju.com +horn-yacht.com +hornetcorn.com +horosama.com +horou.com +horphoto.com +horsebrowser.com +horsechinaone.com +horti-expo2019.com +hortor-comic.com +hortor.net +hortor002.com +hortor005.com +hortor020.com +hortorgames.com +horwathhtl-cn.com +hosane.com +hoscogroup.com +hosgs.com +hoshinesilicon.com +hoshiroko.com +hosjoy.com +hoslen-sh.com +hosn168.com +hosno7.com +hosonglass.com +hosory.com +hosowin.com +hospit.net +hospital-cqjs.com +hospital-cqmu.com +hospital2.com +hospitalkg.com +hospitalshy.com +hospitalstar.com +hospite.com +host263.com +host888.net +hostacc.net +hostacc1.com +hostacc2.com +hostadm.net +hostbbs.net +hostbuf.com +hostdie.com +hostgw.net +hostidc.net +hostkvm.com +hostloc.me +hostmonit.com +hostoexp.com +hostxen.com +hot-test.org +hot0755.com +hotalk.com +hotata.com +hotborn.com +hotchenghong.com +hotdb.com +hoteamsoft.com +hoteastday.com +hotel-noir-film.com +hotel-ochsen-hardheim.com +hotelbaijin.com +hotelcis.com +hotelgg.com +hoteljianguo.com +hotelpanpacific.com +hotelsjianguo.com +hotelvi.com +hotelyunos.com +hotent.com +hotent.xyz +hotgamehl.com +hotgopark.com +hotiis.com +hotkey123.com +hotkidclub.com +hotking.com +hotlcd.com +hotlinegames-jp.net +hotnewx.com +hotone.com +hotoneaudio.com +hotoos.com +hotpotstq.com +hotpub.com +hotread.com +hotsales.net +hotsnow.club +hotsnow.org +hotsoonapp.com +hotsoonapp.net +hotsoonvideo.com +hotsoonvideo.net +hotsoonzb.com +hotsoonzb.net +hotssp.com +hotstoday.com +hottechsemi.com +hottui.com +hotwatchsreplica.com +hotwind.net +hotwindbox.com +hotwon.com +hotxf.com +hotyihao.com +hou5.com +houcaller.com +houdao.com +houdao.net +houdask.com +houdewl.com +houdy.com +houfaka.com +houfangyiyao.com +houge.com +houhoucn.com +houjiji.com +houjt.com +houkai.com +houkuanshop.com +houlangsports.com +houmoai.com +houngfuh.com +houniaohao.com +houniaotrip.com +houniaoyc.com +houpukeji.com +houqigo.com +houqinbao.com +houqun.net +houquner.com +hourt-cert.com +hourui-arch.net +house086.com +house178.com +house365.com +house5.net +house510.com +house86.com +houseimg.com +houseoftantra.org +houshaoan.com +housoo.com +houwenfei.com +houwuedu.com +houxue.com +houyicaiji.com +houyuantuan.com +houzhibo.com +houzhiwang.com +houzi8.com +hovfree.com +howbuy.com +howeipharm.com +howelllighting.com +howellsto.com +howjoin.com +howlapm.com +howmay.com +howsci.com +howtoing.com +howxm.com +howyouinternational.com +howzhi.com +hoxing.com +hoxue.com +hoyakeji.com +hoyatod.com +hoyi-tech.com +hoyibox.xyz +hoyip.com +hoyo.link +hozest.com +hozin.com +hozonauto.com +hp-marathon.com +hp.com +hp123.com +hp888.com +hpbgb.com +hpblog.net +hpc.cloud +hpcang.com +hpccake.com +hpccube.com +hpculturegroup.com +hpearx.com +hpeft.com +hpepea.com +hpgamestream.com +hpglw.com +hpgzf.com +hph123.com +hphwa.com +hpichina.org +hpicorp.net +hpigc.com +hpjd.com +hplyy.com +hpmicro.com +hpnfjx.com +hpoi.net +hprt.com +hprx.com +hps-sh.com +hpstore-china.com +hpstore.cc +hptea.com +hpv112.com +hpwin.com +hpwjs.com +hpwu.com +hpwxc.com +hpyiqi.com +hpyk.com +hpzhatu.com +hq-mart.com +hq-minerals.com +hq0564.com +hq114.net +hq88.com +hqbd.com +hqbnb.com +hqbuy.com +hqbuycdn.com +hqc-china.com +hqcanyin.com +hqcg1984.com +hqchip.com +hqcr.com +hqdlsn.com +hqdoc.com +hqdoor.com +hqengroup.com +hqepay.com +hqew.com +hqew.net +hqewimg.com +hqfastner.com +hqgjzz.com +hqgq.com +hqhb.com +hqhl.net +hqhop.com +hqhospital.com +hqhot.com +hqhtfl.com +hqidi.com +hqis.org +hqiye.com +hqjcjj.com +hqjy.com +hqls.com +hqnqz.com +hqpcb.com +hqps.com +hqqt.com +hqresearch.org +hqrvs.com +hqsec.com +hqsgw.com +hqshuaimi.com +hqsmartcloud.com +hqsoft.cc +hqswuye.com +hqthw.com +hqtong.com +hqts.com +hqubbs.com +hquu.net +hqvchina.com +hqwhw.com +hqwx.com +hqxlad.com +hqyc.com +hqygyg.com +hqyj.com +hqyjng.com +hqyjsuccess.com +hqyl.com +hqys.net +hqyt.net +hqytgyh.com +hqyun.com +hqyxjy.com +hqyzx.com +hqzhou.com +hqzxecd.asia +hr-channel.com +hr-mp.com +hr-self.com +hr-welink.com +hr002.com +hr025.com +hr0571.com +hr0660.com +hr0715.com +hr0752.com +hr0753.com +hr0766.com +hr0915.com +hr1000.com +hr10000.com +hr135.com +hr2002.com +hr2003.com +hr2trainer.com +hr33.com +hr369.com +hr3ds.com +hr448.com +hr510.com +hr5156.com +hr558.net +hr668.com +hr730.com +hr763.com +hr78.net +hr9000.com +hr987.com +hrayw.com +hrb-dg.com +hrbanlv.com +hrbaodian.com +hrbar.com +hrbbcf.com +hrbbleasing.com +hrbeduy.com +hrbesd.com +hrbj.net +hrbjianchewang.com +hrbjishunbanjia.com +hrbjunxin.com +hrbmama.com +hrbmilan.com +hrbpattern.com +hrbpolarland.com +hrbpt.com +hrbshuiwu.com +hrbswx.com +hrbtv.net +hrbuyu.com +hrbyafeng.com +hrbzdty.com +hrbzhsd.com +hrbzyy.com +hrcf168.com +hrcfc.com +hrcwelink.com +hrday.com +hrddqc.com +href.lu +hrenh.com +hrexam.com +hrfc.net +hrflc.com +hrfoods.com +hrgsmz.com +hrgxyy.com +hrhuiyi.com +hrhy365.com +hrintl.com.hk +hrjextruders.com +hrjkjt.com +hrloo.com +hrm100.com +hrmarket.net +hrmtgroup.com +hro-cosmetics.com +hroot.co +hroot.com +hrpackage.com +hrrsj.com +hrs100.com +hrsalon.org +hrsay.com +hrsee.com +hrsel.com +hrsoft-china.com +hrsteelpipe.com +hrtechchina.com +hrtfin.com +hrtn.net +hrtsea.com +hrtx.com +hruikang.com +hrvouge.com +hrwuu.com +hrxiongan.com +hrxz.com +hrzy.cc +hs-bianma.com +hs-biopharm.com +hs-defense.com +hs-fe.com +hs-outlets.com +hs-sz.com +hs.net +hs13z.net +hs2z.net +hs326.com +hs499.com +hs5g.com +hs65.com +hs85.com +hsakyy.com +hsay.com +hsayi.com +hsbank.cc +hsbbs.com +hsbdc.com +hsbianma.com +hscarbonfibre.com +hscbw.com +hscc.com +hscfjt.com +hschina.net +hscn.com +hscode.net +hscode123.com +hsdbg.com +hsdcw.com +hsddyy.com +hsdfzp.com +hsdjxh.org +hsdjz.com +hseda.com +hsehome.com +hsehome.org +hsez.net +hsfh56.com +hsfund.com +hsfyyy.com +hsfzexsg.com +hsfzxjy.site +hsg2oi3c.com +hsgf.net +hsgjj.com +hsgjysj.com +hshan.com +hshdyw.com +hshhlj.com +hshj.cc +hshl360.com +hshsjy.com +hshsxkj.com +hshton.com +hshuiyi.com +hsijqa.com +hsjk.com +hsjkaoyan.com +hsjpgzx.com +hsjrhy.com +hsjt1983.com +hsjy.com +hsjy.net +hskehong.com +hskgchina.com +hskun.com +hsleu.com +hslid.net +hslight.net +hslvshan.com +hslxhl.com +hsly.org +hsm-intl.com +hsmap.com +hsmdb.com +hsmob.com +hsmrt.com +hsnewsnet.com +hsoow.com +hspeletizadora.com +hspharm.com +hspm.net +hspress.net +hsqh.net +hsqhfunds.com +hsqhospital.com +hsqjfw.com +hsqt888.com +hsqyy.com +hsrc.tv +hsrcw.com +hsrexpo.com +hsrjtk.com +hsrtd.club +hssdk.com +hssdtest.com +hssenglish.com +hssjyj.com +hsskyy.com +hsslab.com +hssrc.com +hssyy.com +hsszfx.com +hst.com +hst1966.net +hstars.net +hstbroker.com +hstczkj.com +hstd.com +hstong.com +hstpizza.com +hstspace.com +hstypay.com +hstyre.com +hsufuchifoods.com +hsuyeung.com +hswatersupply.com +hsweb.me +hswell.com +hswkzy.com +hswlkj.com +hswmb.com +hswyvz.com +hswzyh.com +hswzyj.com +hsx99.com +hsxedu.com +hsxt.com +hsxt.net +hsy188.com +hsyaguanjg.com +hsyanyi.com +hsybyh.com +hsyk023.com +hsysupply.com +hsyuntai.com +hsyunyi.com +hsyyf.me +hsyymusic.com +hsyzg.net +hszk.org +hszq6.com +hszq8.com +hszsb.org +hszsfz.com +hszsz.com +hsztbzx.com +hszw.org +hszxlzx.com +hszy8.com +hszyy8.com +hszzsyzx.net +hszzzx.net +ht-cao.com +ht-chem.com +ht-med.com +ht-motor.com +ht-rc.com +ht-saae.com +ht-tech.com +ht-valve.com +ht0775.com +ht1832.com +ht88.com +ht9.com +htai51.com +htaizhou.com +htanwang.com +htaocloud.com +htback.com +htbmsc.com +htc-media.com +htcases.com +htcis.net +htcrrc.com +htcxfund.com +htcxms.com +htd2000.com +htdata.com +htdtire.com +htdxcl.com +hteacher.net +htech360.com +hteos.com +htexam.com +htexam.net +htfcn.com +htffund.com +htfilter.com +htfoxit.com +htfpartner.com +htfutures.com +htg520.com +htgjjl.com +htgkdz.com +htguosheng.com +htgwf.com +hth.com +hti-instrument.com +htidc.com +htinfor.com +htinns.com +htinnsjm.com +htinv.com +htjinju.com +htjob.net +htjs.net +htjsq.com +htjsq.mobi +htkaoyan.com +htkgsx.com +htknow.com +htky365.com +html5-app.com +html5china.com +html5code.net +html5dw.com +html5mark.com +html5plus.org +html5train.com +html5tricks.com +htmlai.com +htmleaf.com +htmlsucai.com +htmycn.com +htnice.com +htong.com +htoo.vip +htood.com +htool.com +htqjy.com +htqyy.com +htrip.biz +hts-auto.com +htsamc.com +htsc.com +htsec.com +htsec.net +htsham.com +htsjj.com +htslauto.com +htsprings.com +httdsj.com +htths.com +httingshu.com +httpcanary.com +httpcn.com +httpsok.com +httpssl.com +htucloud.com +htudata.com +htudns.com +hturl.cc +htv123.com +htvaas.com +htvcentral.com +htwcq.com +htwed.com +htwx.net +htx.cc +htxgcw.com +htxgssb.com +htxrc.com +htxxpx.com +htxy.net +htycs.com +htyduck.com +htyhm.com +htyou.com +htys.cc +htys123.com +htyssdf.com +htyswzzgw.com +htyunwang.com +htzdj.com +htzdznjs.com +htzhgd.com +htzipr.com +hu.com +hua-chips.com +hua-lan.com +hua-yong.com +hua.com +hua1000.com +hua168.com +hua5.com +huaaiangel.com +huaan-cpa.com +huaao-trust.com +huaaojiaoyu.com +huaaoranqi.com +huaaosoft.com +huaaotech.com +huaat.com +huabaike.com +huaban.com +huaban.net +huabanimg.com +huabanpro.com +huabbao.com +huabeicw.com +huabian.com +huabianyl.com +huabo.net +huabocam.com +huabokeji.com +huabot.com +huabuqi.com +huacai-tech.com +huacai.com +huacaijia.com +huacaobk.com +huacaole.com +huacemedia.com +huachang-alu.com +huachengenjoy.com +huachengjx.com +huachenholdings.com +huachenit.com +huachenyuanyang.com +huachuangroup.net +huaco908.com +huacolor.com +huacooling.com +huada120.com +huadabz.com +huadachem.com +huadan.com +huadehyd.com +huaderack.com +huadian360.com +huadiansc.com +huadie.com +huadihealth.com +huadiplan.com +huadonghospital.com +huadongmedia.com +huadongtrack.com +huadream.com +huaduanbio.com +huadun315.com +huaduocai.net +huaease.net +huaeda.com +huaer.cc +huafaceg.com +huafagroup.com +huafaih.com +huafajituan.com +huafang.com +huafangdichan.com +huafasports.com +huafatech.com +huafeimould.com +huafeng-al.com +huafeng.com +huafengaw.com +huafens.com +huafer.cc +huafu.com +huagolf.com +huagongkaoyan.com +huagujs.com +huaguoshan.com +huaguoyuan.com +huagupai.com +huahai-gz.com +huahaibiochem.com +huahaige.com +huahaijiaju.com +huahaipharm.com +huahanart.com +huahanbook.com +huahao.com +huahengbio.com +huahengrobot.com +huahengsk.com +huahong-group.com +huahonggk.com +huahongjt.com +huahtc.com +huahua777.com +huahuacaocao.com +huahuamaoyi.com +huahuan.com +huahuihealth.com +huahuizhineng.com +huahuo.com +huai.gg +huaian.com +huaiangj.com +huaiansgyy.com +huaibaobei.com +huaibei.com +huaibeihosp.com +huaicai.cc +huaien.com +huaigang.com +huaihai.tv +huaihaixiang.com +huaijiufu.com +huaimg.com +huaimi.com +huain.com +huainanhy.com +huainannet.com +huainanren.net +huainanzi.com +huainet.com +huairen588.com +huairougreatwallmarathon.com +huairtv.com +huairui59.com +huaitao.vip +huaixin88.com +huaiyangnews.com +huaji.com +huaji.store +huajia.cc +huajiakeji.com +huajialishe.com +huajian-al.com +huajiangai.com +huajiankang.com +huajianmed.com +huajiantong.com +huajiao.com +huajiaow.com +huajiaowu.com +huajicnc.com +huajieai.com +huajifen.com +huajin100.com +huajinct.com +huajing-inf.com +huajingsec.com +huajingyun.com +huajuanma.com +huajuanyun.com +huajuhotel.com +huajx.com +huakaifilter.com +huake-weixin.com +huakewang.com +huakeyun.com +huakpower.com +hualady.com +hualaikeji.com +hualaiyun.com +hualala.com +hualan-tech.com +hualanbio.com +hualay.net +hualet.org +hualewl.net +hualiandie.com +hualiandressing.com +hualianmining.com +hualiantv.com +hualianxin.com +hualing-pm.com +hualingjiangong.com +hualiuniversity.com +hualong-sz.com +hualongholding.com +hualongxiang.com +hualu5.com +hualumedia.com +hualuwood.com +hualv.com +hualvtu.com +huaman.pub +huamanlou.cc +huamanlou.com +huamao.com +huamaobook.com +huamaorice.com +huamaoshuo.com +huamedicine.com +huameili.net +huameiyuezi.com +huamengxiaoshuo.com +huami.com +huamou.com +huamu.com +huamuwo.com +huan-tai.com +huan.tv +huananauctionctf.com +huananyiyao.com +huananzhi.com +huanbao.com +huanbaoscx.com +huanbearing.com +huanbeieloan.com +huanbeiloan.com +huanbeipic.com +huandie.com +huandonglg.com +huane.net +huanenet.com +huanergy.com +huanfeng580.com +huang-jerryc.com +huang-jiang.com +huangbaoche.com +huangbaoquan.com +huangbowei.com +huangchujunyulong.com +huangchun.net +huangdao.in +huangdao.net +huangdc.com +huangea.com +huangfusl.net +huanggangmarathon.com +huanggao.net +huanggaole.com +huangguanluo.com +huangh.com +huanghaicollege.com +huanghanlian.com +huanghegongshui.com +huanghehr.com +huanghepiao.com +huanghuacheng.com +huangjiemin.com +huangjihuang.com +huangka.com +huangkong.net +huanglei.me +huangli.com +huangli8.com +huangliangbo.com +huanglong.com +huangma.com +huangqi1688.com +huangshaotian.com +huangshimarathon.com +huangwei.me +huangwei.pro +huangxin.dev +huangxinwei.com +huangyao.work +huangye.net +huangye51.com +huangye88.com +huangye88.net +huangyifan.com +huangyixiaoshuo.com +huangyuehe.com +huangyuhui.net +huangyunkun.com +huangzz.xyz +huanhaoba.com +huanhuanhuishou.com +huanhuanxin.com +huanhuba.com +huanidc.com +huanju.net +huanjutang.com +huanjuyun.com +huanle.com +huanle800.com +huanlecdn.com +huanledd.com +huanlefish.com +huanleguang.com +huanletang.com +huanlewan.net +huanlezhuan.com +huanlingpharm.com +huanlingxiuxian.com +huanlj.com +huanmusic.com +huanong1688.com +huanongdao.com +huanpeng.com +huanpingge.com +huanq.com +huanqiu-ltd.com +huanqiu.com +huanqiu.org +huanqiu56.com +huanqiuauto.com +huanqiuchuguo.com +huanqiujiemi.com +huanqiukexue.com +huanqiumil.com +huanqiutape.com +huanqiuw.com +huanqiuyimin.com +huanqu-tec.com +huanqunquan.com +huansengifts.com +huanshoulv.com +huante.com +huantest.com +huanting.cc +huantour.com +huanuomenye.com +huanwen.com +huanwenwen.com +huanxi.com +huanxia.com +huanxiangji.com +huanximedia.com +huanxinchem.com +huanxinfluoro.com +huanxing1904.com +huanxingedu.com +huanxio.com +huanxiongdd.com +huanxiyl.com +huanyatour.com +huanyingzq.com +huanyouji.com +huanyuantech.com +huanyudns.com +huanyule.com +huanyumid.com +huanyutv.com +huanzhu101.com +huanzhucv.com +huaoe.com +huaon.com +huaougas.com +huapai.com +huapiaoer.com +huapiaoliang.com +huapinwang.com +huapontshengchem.com +huaqiaobang.com +huaqidigital.com +huaqin.com +huaqinchi.com +huaqingkeji.net +huaqingtax.com +huaqiu.com +huaraytech.com +huaren-scm.com +huarenyingyu.com +huarenyizhan.com +huari-furniture.com +huari.com +huaroem.com +huarongdao.com +huarongled.com +huarui.work +huarui1952.com +huaruiaero.com +huaruicom.com +huaruidns.com +huaruisales.com +huas.co +huasadata.com +huash.com +huashangcbbtv.com +huashangedu.com +huashanglawyer.com +huashangtop.com +huashanxin.com +huashen-edu.com +huashen-group.com +huashen6.com +huasheng-automation.com +huasheng100.com +huashengchn.com +huashengdaili.com +huashenghaoche.com +huashengjia100.com +huashengls.com +huashengshiyan.com +huashengtoutiao.com +huashi-sh.com +huashi.cc +huashi6.com +huashichang.com +huashidongman.com +huashijie.art +huashilm.com +huashipharmacymtalionlineybpay.com +huashitong.net +huashphoto.com +huashui.com +huashuitax.com +huashunxinan.net +huasimtour.com +huasiwood.com +huasongwang.com +huasu.net +huasuankeji.com +huasuhui.com +huasuokeji.com +huasyun.com +huatai-elec.com +huatai-pb.com +huatai.com +huatai1993.com +huataiyc.com +huatan365.com +huatans.com +huatec.com +huatech.net +huategas.com +huatengsci.com +huati.cc +huatian-hotel.com +huatian.net +huatianxiangsu.com +huatong-logistics.com +huatongcloud.com +huatu.com +huatugz.com +huatuo007.com +huatuowenda.com +huatuoyf.com +huaue.com +huavisa.com +huawan.com +huawangzhixun.com +huawanyun.com +huawe.com +huawei-3com.com +huawei-eu.store +huawei.asia +huawei.com +huawei.eu +huawei.ru +huaweiacad.com +huaweiapaas.com +huaweiapi.com +huaweicloud-dns.com +huaweicloud-dns.net +huaweicloud-dns.org +huaweicloud-idme.com +huaweicloud-koophone.com +huaweicloud-smn.com +huaweicloud-smn.net +huaweicloud.com +huaweicloudapis.com +huaweicloudlive.com +huaweicloudsite.com +huaweicloudwaf.com +huaweidevice.com +huaweidevice.tel +huaweidun.com +huaweielab.com +huaweifile.com +huaweiief.com +huaweiita.com +huaweils.com +huaweimall.com +huaweimarine.com +huaweimarketplace.com +huaweimossel.com +huaweioneaccess.com +huaweirtc.com +huaweisafedns.com +huaweishop.net +huaweisoft.com +huaweisre.com +huaweistatic.com +huaweiuniversity.com +huaweiyun.com +huaweizdl.com +huawenwin.com +huawo-wear.com +huawote.com +huaxi.net +huaxi100.com +huaxia.com +huaxia77.com +huaxiabeidou.com +huaxiaeye.com +huaxiaf.com +huaxiagg.com +huaxiajianyan.com +huaxiald.com +huaxialiangzi.com +huaxiangdiao.com +huaxianpai.com +huaxianzhaopin.com +huaxiao5.com +huaxiaobaokeji.com +huaxiapawn.com +huaxiashiwen.com +huaxiasz.com +huaxiataike.com +huaxiazi.com +huaxin303.com +huaxinbaojie.com +huaxincem.com +huaxing.com +huaxingas.com +huaxingchem.com +huaxinhz.com +huaxinorthop.com +huaxinpark.com +huaxiong.com +huaxirc.com +huaxj.net +huaxuezoo.com +huaxumag.com +huaxunbaili.com +huaxunholdings.com +huayang.net +huayanghui.net +huayangsolar.com +huayanwater.com +huayaocc.com +huayaody.com +huaye.com +huayi-faucet.com +huayicn.com +huayidiaosu.com +huayielec.com +huayijiahe.com +huayilawfirm.com +huayilighting.com +huayimedia.com +huayiming.com +huayin114.com +huayingglass.com +huayingrc.com +huayingsc.com +huayinhealth.com +huayinjapan.com +huayinlab.com +huayinyiliao.com +huayitaitech.com +huayitongkeji.com +huayitongtai.com +huayiweibo.com +huayiwork.com +huayiyuan.com +huayiyunxinxi.com +huayou.com +huayoumengze.com +huayoutianyu.com +huayuan-print.com +huayuanlcd.com +huayuchaxiang.com +huayue119.com +huayueivf.com +huayufilter.com +huayug.com +huayuhua.com +huayulandmarkhotel.com +huayun.com +huayunfl.com +huayuzj.com +huazhangautomation.com +huazhanggroup.com +huazhanwire.com +huazhen-gs.com +huazhen2008.com +huazhen2008.net +huazhengcaiwu.com +huazhengwuye.com +huazhenjiaoyu.com +huazhiedu.com +huazhiweilai.com +huazhixingchina.com +huazhongcar.com +huazhongcnc.com +huazhongtimes.com +huazhu.com +huazhuanapp.com +huazhucorp.com +huazirc.com +hubamdi.com +hubashihuo.com +hubcyts.com +hubei88.com +hubeiamc.com +hubeibbs.net +hubeibidding.com +hubeichengji.com +hubeici.com +hubeidaily.net +hubeifc.com +hubeifurui.com +hubeigongfu.com +hubeihome.net +hubeiip.com +hubeijingjunf.com +hubeikj.com +hubeinet.com +hubeipbx.com +hubeiport.com +hubeiqiche.org +hubeiwsd.com +hubeixuekao.com +hubeiyanjiusheng.com +hubeiyongtai.com +hubeizhengao.com +hubiao168.com +hubing.online +hubsound.com +hubstudio.vip +hubulab.com +hubwd.com +hubwiz.com +huc08.com +hucais.com +hucdn.com +huceg.com +huceo.com +huchaowei.com +hucheng100.com +huchihuchi.com +hudai.com +hudong.com +hudong100.com +hudong100.net +hudong100.org +hudongad.com +hudongba.com +hudongcdn.com +hudongkejian.com +hudongku.net +hudun.com +hudunsoft.com +huduntech.com +huelead.com +huenhuenfood.com +hufangkeji.com +hufangyun.com +hufe.cc +hugane.com +hugcar.com +hugd.com +hugecdn168.com +hugecore.net +hugeland.com +hugetall.com +hugong-js.com +hugong.com +huhaha.net +huhanba.com +huhaoyang.com +huhexian.com +huhoo.com +huhoo.net +huhua.net +huhuang.net +huhudi.com +huhuguanjia.com +huhui-sh.com +huhustory.com +huhutian.com +huhutong315.com +hui-ben.com +hui-chao.com +hui.net +hui10.com +hui10.net +hui100.com +hui43.com +hui800.com +hui800.net +huians.com +huibag.com +huibiao-group.com +huibiaoinfo.com +huibo.com +huibojob.com +huiboparking.com +huiborobot.com +huicaishui.net +huiche.com +huiche100.com +huicheimg.com +huichenghuijia.com +huichengip.com +huichengy.com +huichewang.com +huichongduo.com +huichuangjialife.com +huichuangzhanlan.com +huicx7.com +huida18.com +huidabbs.com +huidafrp.com +huidagroup.com +huidan.net +huidang.com +huidaocaishui.com +huidaqg.com +huidawanan.com +huidazhe.vip +huiddo.com +huide-medical.com +huiderui.com +huideyecai.com +huidian.net +huidiantech.com +huidu.com +huidu.net +huidu001.com +huiduogang.com +huiemall.com +huierming.com +huierp.com +huifachina.com +huifacms.com +huifayun.com +huifeng-zj.com +huifengtools.com +huifengxinxi.com +huifengzhuzao.com +huifenqi.com +huifu.com +huifudashi.com +huifusihai.com +huifutz.com +huifuzhinan.com +huigaiji.com +huigao-magnetics.com +huigezi.org +huiguanwang.com +huih110.com +huihaha.com +huihaicenter.com +huihaicn.com +huihaiyiyao.com +huihe56.com +huihefz.com +huihengmedical.com +huihestone.com +huihezx.com +huihua365.com +huihua8.com +huihuaren.com +huii.cc +huiidea.com +huiji.wiki +huijiame.com +huijian-land.com +huijiangroup.com +huijiaoyun.com +huijiazhileng.com +huijidata.com +huijie.shop +huijiegroup.com +huijiewei.com +huijimall.com +huijing.org +huijinggroup.com +huijingwl.com +huijinshang.com +huijinwater.com +huijistatic.com +huijitrans.com +huijiwiki.com +huiju.cool +huijucn.com +huikao8.com +huikex.com +huikundz.com +huila88.com +huilaimi.com +huilan-online.com +huilan.com +huilanfoundation.org +huilanyujia.com +huiliangapp.com +huilianyi.com +huililong.com +huilintyre.com +huilinwang.com +huilitc.com +huiliu.net +huiliubao.com +huilm.com +huilog.com +huilongsen.com +huilongtech.com +huilunbio.com +huilv8.com +huilvbiao.com +huilvwang.com +huilvyankuang.com +huilw.com +huilyn.com +huimaiche.com +huimaihs.com +huiman.net +huimei.net +huimeijiaozi.com +huimeisports.com +huimeiyp.com +huimeizr.com +huimengchem.com +huimengya.com +huimiaokeji.com +huimin111.com +huimincz.com +huimingcn.com +huimingjia.com +huimwang.com +huinaimei.com +huing.net +huinkj.net +huion.com +huiqia.net +huiqianfan.com +huiqibaike.com +huiqiyidiantong.com +huiqiyu.com +huiqk.com +huiqudsp.com +huiqunchina.com +huiquzu.com +huirde.com +huirenshenbao.com +huirenyy.com +huiris.com +huiruanzhuang.com +huirui-tech.com +huirui1688.com +huisem.com +huisencapital.com +huisenky.com +huishandairy.com +huishangbao.com +huishangol.com +huishantech.com +huisheng.fm +huishengaudio.com +huishenghuo.ink +huishengqianzhushou.com +huishida.com +huishou1680.com +huishoubao.com +huishoubaojiadan.com +huishouigbt.com +huishoujie.com +huishoujiuwu.com +huishoushang.com +huishouyx.com +huishuaka.com +huishuirencai.com +huishuitech.com +huisituo.com +huisj.com +huisky.com +huisou.com +huisports.com +huisuanzhang.com +huisucn.com +huisuoping.com +huitao.net +huitaoche.com +huitaoyouhui.com +huitengpipe.com +huitongqingsuan.com +huitoubj.com +huitouche.com +huitoukefood.com +huitouyan.com +huitouyu.com +huitouzi.com +huitu.com +huitu.tech +huitu8.com +huitun.com +huiurl.com +huivo.com +huiwang.net +huiweikeji.com +huiwenda.com +huiwww.com +huixianginvest.com +huixiangtiandi.com +huixiaoer.com +huixiaoer.net +huixineducation.com +huixinggroup.com +huixingsoft.com +huixinli.com +huixinyiyuan.com +huixinyt.com +huixinyun.com +huixsw.com +huixuanjiasu.com +huixueba.net +huiyan315.com +huiyangranqi.com +huiyankan.com +huiyaohuyu.com +huiybb.com +huiyda.com +huiyelaw.com +huiyi-123.com +huiyi365.net +huiyi8.com +huiyi9e.com +huiyiabc.com +huiyiai.net +huiyicq.net +huiyihealth.com +huiyinxun.com +huiyizhuo.com +huiyou.com +huiyou027.com +huiyouhotels.com +huiyuandao.com +huiyuanjia.net +huiyuansoft.com +huiyuantang.com +huiyuanyy.com +huiyucn.com +huiyuehz.com +huiyumedia.com +huiyundong.net +huiyutools.com +huize.com +huizecdn.com +huizhaofang.com +huizhek.com +huizhengmachinery.com +huizhiguanghua.com +huizhihuyu.com +huizhijiaxun.com +huizhilin.com +huizhilin.net +huizhimob.com +huizhioptech.com +huizhou-marathon.com +huizhouf.com +huiziyuan.net +huizone.com +huizuche.com +huizucloud.com +huizuoyuezi.com +huizustore.com +hujia.org +hujiang.com +hujianggroup.com +hujibbs.com +hujingnb.com +huke88.com +hukeck.com +hukecs.com +hukecwx.com +hukefjb.com +hukehyh.com +hukelc.com +hukenb.com +hukesxm.com +hukewq.com +hukexyy.com +hukou021.com +hukou365.com +hukuangroup.com +hulai.com +hulianfang.com +hulianmaibo.com +hulianwangchuangye.com +hulinhong.com +hulixin.com +huliyx.com +hulubaba.com +huluboshi.com +huludz.com +huluer.com +huluip.com +huluip.tech +huluo.com +hulusaas.com +hulusi.com +hulutrip.com +huluwa.cc +huluwa365.com +huluwa8.com +huluxia.com +huluxia.net +huluzc.com +humaiyouxi.com +humanplustech.com +humanrights-china.org +humanwellcaps.com +humanwellhb.com +humaotec.com +humblit.com +humengyun.com +humensec.com +huming.com +hummcars.com +humpline.com +hunaen.com +hunan-changda.com +hunan-huasheng.com +hunan100km.com +hunanbestall.com +hunancatv.com +hunaneu.com +hunangaozhi.com +hunangy.com +hunanhaihong.com +hunaniptv.com +hunanjz.com +hunanpea.com +hunantv.com +hunanxingxin.com +hunanyuneng.com +hunanzp.com +hunanzy.com +hunau.net +hunbei.com +hunbei1.com +hunbei2.com +hunbei3.com +hunbei4.com +hunbei5.com +hunbohui.info +hunbys.com +hunche.net +hunchun123.com +hundredcent.com +hundsun.com +hundun.net +hundx.com +hunger-valley.com +hungsh.store +hunli100.com +hunlian100.com +hunlihu.com +hunlihu1.com +hunlihu2.com +hunlihunli.com +hunliji.com +hunlimama.com +hunlimao.com +hunmiao.com +hunsh.net +huntchance.com +huntermailfocus.com +hunteron.com +huntic.com +huntkey.com +huntkeydiy.com +huntsbot.com +hunuo.com +hunyinyiyuan.com +huoas.com +huoban.com +huobanbot.com +huobanhuyu.com +huobanimg.com +huobanjs.com +huobanniu.com +huobaowang.com +huobaoweishang.com +huobaoyx.com +huobi.io +huocai.com +huochai.cc +huochai.mobi +huoche.com +huoche.net +huoche.wiki +huocheba.com +huocheci.com +huochehuan.com +huochepiao.com +huochepiao.net +huocheso.com +huocms.com +huodao.hk +huodong.org +huodong.store +huodong5.com +huodonghui.net +huodongjia.com +huodongju.com +huodongpro.com +huodongshu.com +huodongwang.com +huodongxing.com +huodongzhongguo.com +huofar.com +huofutp.com +huogongdian.com +huohao8.com +huohoo.com +huohuacdn.com +huohuahudong.com +huohudun.com +huohuo.com +huoideas.com +huoji.com +huojiaba.com +huojitui.com +huoju365.com +huokebao.net +huokeying.com +huokeyuan.com +huolala.co +huolala.work +huole.com +huolea.com +huoli.com +huolieniao.com +huolieyun.com +huolinhe.com +huolishaonianwang.com +huolug.com +huomakeji.com +huomao.com +huomaotv.com +huomaqun.com +huoming.com +huomujin.com +huonan.net +huonao.com +huoniuniu.com +huopinyuan.com +huopu.com +huoqibao.com +huoqiuw.com +huosdk.com +huoshan.cc +huoshan.club +huoshan.com +huoshancdn.com +huoshangroup.com +huoshanimg.com +huoshanlive.com +huoshanparty.com +huoshanstatic.com +huoshante8.com +huoshanvideo.net +huoshanvod.com +huoshanxiaoshipin.net +huoshanzhibo.com +huoshanzhibo.net +huoshanzhufang.com +huoshen.com +huoshen99.com +huoshi.shop +huosu.com +huowan.com +huowanes.com +huoxiaoyi.com +huoxing.com +huoxing24.com +huoxingyu.com +huoxingzi.com +huoxun.com +huoyan.com +huoyan.io +huoyanio.com +huoyantu.com +huoyanyunying.com +huoyfish.com +huoying.com +huoyuan.mobi +huoyugame.com +huoyuyan.com +huoziyin.com +hupan.com +hupanedu.com +hupanoled.com +hupo.com +hupo.tv +hupozhidao.com +hupu.com +hupu.gg +hupu.io +hupucdn.com +hupujrs.com +hupun.com +hur05100kns.com +hur05111kns.com +hur05120kns.com +hurom.vip +hurricane618.me +hurricanechip.com +hurun.net +hurx04.xyz +hurys.com +husadw.com +husenji.com +hushangcaifu.com +husini.net +husiyang.com +hust-laser.com +hust-snde.com +hust-wuxi.com +hust.cc +hust.online +hustcad.com +hustlife.com +hustlzp.com +hustmei.com +hustnews.com +hustoj.com +hustonline.net +hustp.com +hustsofc.tech +hustunique.com +hustwenhua.net +hustxb.com +hustyy.com +husubao.com +hutaojie.com +hutaolinight.com +hutegy.com +hutew.com +hutong-school.com +hutong360.com +hutongcdn.com +hutoufeng.net +hutui9.com +hutuii.com +hutusi.com +huuhoo.com +huuing.com +huwaibbs.com +huwaizb.com +huwatech.club +huway.com +huweihuang.com +huweishen.com +huwi8.com +hux6.com +huxianwang.com +huxiaofan.com +huxiaoshi.com +huxiji999.com +huxijizhongguo.com +huxingroup.com +huxishiye.com +huxiu.com +huxiu.link +huxiucdn.com +huya.com +huyajs.com +huyall.com +huyanapp.com +huyanbao.com +huyanjie.com +huyaos.com +huyaruanwen.com +huyatvns.com +huyayue.com +huyn.com +huyouxiong.com +huyueidc.com +huyuekj.com +huyuncdn.com +huyuning.com +huyuxx.com +huzhan.com +huzhang.com +huzhao1.com +huzheng.org +huzhongxin.com +huzhoumj.com +huzhoumuseum.com +huzicaotang.com +huzwater.com +hvacstar.com +hvchan.com +hvcnitl.com +hvcxo.com +hvdiy.com +hvread.com +hvsgqlo.xyz +hvtong.com +hw-ai.com +hw-go.net +hw-supply.com +hw-tm.com +hw100k.com +hw3static.com +hw555.com +hw99.com +hwactive.com +hwad.net +hwagain.com +hwait.com +hwangda.com +hwanw.com +hwaq.cc +hwashi.com +hwasmart.com +hwastro.com +hwasunpharma.com +hwatson.com +hwavi.org +hwbanaa.com +hwbaoan.com +hwbfxp5030.vip +hwbim.com +hwbs.org +hwbz.net +hwccpc.com +hwcdnsre.com +hwcloudlive.com +hwclouds-dns.com +hwclouds-dns.net +hwclouds.com +hwclouds.mobi +hwclouds.net +hwclouds.org +hwcloudsite.com +hwcloudvis.com +hwclzq.com +hwcpb.com +hwcrazy.com +hwehs.com +hweimall.com +hweventgrid.com +hwfcw.com +hwgis.com +hwhidc.com +hwht.com +hwj.com +hwjianmo.com +hwjm-mold.com +hwjyw.com +hwlchain.com +hwlifting.com +hwlpz.com +hwlxuz.work +hwocloud.com +hwoled.com +hworld.com +hwpan.com +hwrecruit.com +hwshu.com +hwsupplychain.com +hwtelcloud.com +hwtrip.com +hwtzdl.com +hwwt2.com +hwwt8.com +hwxc.com +hwxda.com +hwxfc.com +hwxjp.com +hwxnet.com +hwxuanliuqi.com +hwyton.com +hwyxxx.com +hwzn.com +hwzuku.com +hwzyjt.com +hx-parking.com +hx-qt.com +hx-r.com +hx008.com +hx008.net +hx110.com +hx1h.com +hx2car.com +hx2cars.com +hx36.net +hx416.com +hx5658.com +hx818.com +hx8886.com +hx95.com +hx99.net +hxacc.com +hxage.com +hxbdf120.com +hxbdxled.com +hxbl.com +hxbsth.com +hxbus.net +hxc-power.com +hxccc.org +hxcd.net +hxcdn.net +hxchem.net +hxchx.org +hxclouds.com +hxcsbj.com +hxct.com +hxct.ltd +hxd56.com +hxdec.com +hxdi.com +hxdkfp.com +hxdkj88.com +hxdrisk.com +hxdsbgg.com +hxdspa.com +hxdtekf.com +hxen.com +hxepawn.com +hxf111.com +hxfilm.com +hxfjw.com +hxfy888.com +hxfzzx.com +hxgame.net +hxgqw.com +hxgro.com +hxgroup.com +hxgs.com +hxgs.net +hxgwott.com +hxhaoyu.com +hxhost.com +hxhssw.com +hxiangjia.com +hxing.com +hxinq.com +hxjbh.com +hxjhcloud.com +hxjinqiao.com +hxjiot.com +hxjiqi.com +hxjnyy.com +hxjsjkj.com +hxjstech.com +hxjwang.com +hxjxs.com +hxjxsw.com +hxkba.com +hxkfh.com +hxkgjt.com +hxkj.cc +hxkj.vip +hxkq.net +hxkq.org +hxkqyxzz.net +hxland.com +hxlbc.com +hxlbd.com +hxledu.com +hxlhjt.com +hxljjt.com +hxlot.com +hxlsw.com +hxltcj.com +hxlxx.com +hxm5.com +hxmeishi.com +hxmlyy.com +hxmryy.com +hxnews.com +hxnk.com +hxny.com +hxnygx.com +hxpdd.com +hxposuiji.com +hxq123456.com +hxqc.com +hxqc.mobi +hxqcgf.com +hxqcjt.com +hxqgczx.com +hxqnj.org +hxqtedu.com +hxr100.com +hxrc.com +hxsd.com +hxsd.tv +hxseal.com +hxsec.com +hxsjjt.com +hxsmart.com +hxsme.org +hxspjt.com +hxssyy.com +hxstrive.com +hxsts.com +hxsyjt.net +hxt5.com +hxtk.com +hxtrip.com +hxtxxw.com +hxtzgroup.com +hxwglm.com +hxx.net +hxxkw.org +hxxl6.com +hxyd.cc +hxydup.com +hxyjw.com +hxys.com +hxytea.com +hxytw.com +hxyxt.com +hxyyw.com +hxz.ink +hxzlsgs.com +hy-china.com +hy-express.com +hy-f.com +hy-la.com +hy-lamp.com +hy-titan.com +hy-tp.com +hy-zr.com +hy017.com +hy01888.com +hy031.com +hy05190134.com +hy053.com +hy074.com +hy118.com +hy120.com +hy12048.com +hy123.com +hy1234567.com +hy163.com +hy169.com +hy1862.com +hy2046.com +hy219.com +hy237.com +hy254.com +hy261.com +hy2809.com +hy296.com +hy341.com +hy345.com +hy346.com +hy36061.com +hy36098.com +hy375.com +hy3804.com +hy385.com +hy4.cc +hy410.com +hy439.com +hy4445.com +hy450.com +hy453.com +hy464.com +hy5353.com +hy552.com +hy5553.com +hy563.com +hy576.com +hy628.com +hy636.com +hy679.com +hy702.com +hy7050.com +hy732.com +hy762.com +hy7703.com +hy7738.com +hy7756.com +hy8881.com +hy9698.com +hy9905.com +hyagrochem.com +hyagv.com +hyahm.com +hyaimed.com +hyakkaryouran.date +hyb2b.com +hybase.com +hybbs.net +hybbtree.com +hybiome.com +hybssy.com +hyc.com +hyccw.com +hycdn.com +hycet.com +hycfw.com +hycgy.com +hyckjic.com +hycn.com +hydarts.com +hydbest.com +hyddd.com +hyderabadgrowth.com +hydesolar.com +hydravizoficial.info +hydst.com +hydun.com +hydz999.com +hydzfp.com +hydzswyxgs.com +hyec.com +hyedu.com +hyexpo.com +hyext.com +hyey.com +hyeycg.com +hyflc.com +hyfutures.com +hyfxbj.com +hyggfx.com +hygkit.com +hygmgroup.com +hygoldcup.com +hygxbgd.com +hygy361.com +hyham.com +hyhcdn.com +hyhdtg.com +hyhhgroup.com +hyhjzc.com +hyhl66.com +hyhospital.com +hyhqjt.com +hyhro.com +hyhscm.com +hyht.fun +hyhuo.com +hyhxt.net +hyhy.cc +hyhyn.com +hyilp.com +hyimmi.com +hyipchina.com +hyj999.com +hyjgxx.com +hyjhgy.com +hyjnpx.com +hyjxmx.com +hykang.com +hykcsoft.com +hykiln.com +hykj.cc +hyl1.tv +hylanda.com +hylandslaw.com +hylicreate.com +hylik.net +hylname.com +hymake.com +hymall.net +hymater.com +hymcu.com +hymicrofiber.com +hymicrosystem.com +hymjy.net +hymson.com +hynet.co +hynetek.com +hynews.net +hyngj.com +hynixic.com +hynpay.com +hynyw.com +hyocr.com +hyouda.com +hyp-arch.com +hypefolio.com +hypefolio.net +hyper.sh +hyper3d.ai +hypercachenet.com +hypercachenode.com +hypergryph.com +hypergryph.net +hyperguestai.com +hypersilicon.com +hyperstrong.com +hyphencargo.com +hyplc.com +hypnotherapyforeverybody.com +hyppmm.com +hyptec.com +hypyimei.com +hyqcw.com +hyqdxcl.com +hyrainbow.com +hysbz.com +hysec.com +hyseim.com +hyshengnian.org +hyshi.net +hysound.com +hysteeltube.com +hyswcn.com +hyswjt.net +hysyyl.com +hysz.net +hyt01.com +hyt368.com +hytbj.com +hytch.com +hytcshare.com +hytd.com +hytera.com +hytxhd.com +hytzqb.com +hyun.cc +hyundai-chhm.com +hyundai-hmtc.com +hyuuhit.com +hyuyy.com +hywater.net +hywaternet.com +hywh1999.com +hywjjz.com +hywx.com +hyx1927.com +hyxiang888.xyz +hyxrmt.com +hyxsoft.com +hyxt.com +hyy99.com +hyybj.com +hyyf.net +hyyl.net +hyyoa.com +hyypjs.com +hyyun.com +hyyykj.net +hyyyy.net +hyyzy.com +hyzc.com +hyzc.net +hyzcservice.com +hyzenhospital.com +hyzhcdn.com +hyzhihe.com +hyznjs.com +hyzqxsb.com +hyzui.com +hz-alw.com +hz-bdqn.com +hz-ch.com +hz-delixi.com +hz-emc.com +hz-etest.com +hz-expo.com +hz-gaoke.com +hz-gn.com +hz-hospital.com +hz-jsyg.com +hz-kedi.com +hz-moon.com +hz-pharm.com +hz-polar.com +hz-spring.net +hz-tire.com +hz-tt.com +hz-winone.com +hz-xiaofei.com +hz-xin.com +hz-zhuce.com +hz-zq.com +hz2jx.com +hz2y.com +hz3201.com +hz3ds.com +hz3y.com +hz66.com +hz6z.com +hz7hospital.com +hz8z.net +hz9hospital.com +hzabjt.com +hzaee.com +hzahy.com +hzaiguojiang.com +hzairport.com +hzajjt.com +hzallina.com +hzamcare.com +hzaoz.com +hzapu.com +hzapuqi.com +hzaygb.com +hzazh.com +hzbcdp.com +hzbcxg.com +hzbh.com +hzbhjy.com +hzbhsh.com +hzbianqing.com +hzbianqu.com +hzbike.com +hzbjwy.com +hzbk.net +hzbojin.com +hzbomed.com +hzbook.com +hzboxing.com +hzboxuan.com +hzbpm.com +hzbx.com +hzc.com +hzcables.com +hzcbparking.com +hzcbs.com +hzccb.net +hzcctech.com +hzcd120.com +hzcda.com +hzcdhcyy.com +hzcdycyy.com +hzcdyyhc.com +hzcdyyyc.com +hzcekong.com +hzch.org +hzchaoxiang.com +hzchengdun.com +hzchengdun.net +hzchgj.com +hzcjtz.com +hzcmc.com +hzcmdq.com +hzcnc.com +hzcollege.com +hzcopyright.com +hzcourse.com +hzctjs.com +hzctkj.com +hzctxh.com +hzcy.com +hzczjt.com +hzdajiangdong.com +hzdare.com +hzddwk.com +hzdelian.com +hzdely.com +hzdgjc.com +hzdjr.com +hzdjy.com +hzdledu.com +hzdlrj.com +hzdmpower.com +hzdongyu.com +hzdq.com +hzdsrmyy.com +hzdtv.tv +hzdx.com +hzebang.com +hzec-tencentclb.cloud +hzec-tencentclb.com +hzec-tencentclb.net +hzec-tencentclb.work +hzecsemir.com +hzeeec.com +hzeg.com +hzelec.com +hzepd.com +hzeyun.com +hzfc.cc +hzfc365.com +hzfeat.com +hzfeiyao.com +hzfesco.com +hzfj.com +hzfllbj.com +hzfolo.com +hzfpay.com +hzfstz.com +hzfucai.net +hzfuturehos.com +hzfwq.com +hzfzxh.com +hzgcec.com +hzgcgl.com +hzggfw.com +hzgh.org +hzgjj.com +hzglsb.com +hzgmwl.com +hzgolong.com +hzgoyuan.com +hzgrow.com +hzgrys.net +hzgthb.com +hzguode.com +hzguojiao.com +hzgwzn.com +hzgxr.com +hzgymd.com +hzgzsoft.com +hzh0775.com +hzh1.com +hzhadx.com +hzhanbo.com +hzhchj.com +hzhcia.com +hzhcloud.com +hzhebei.com +hzhehua.com +hzhehui.com +hzhengding.com +hzhengtong.com +hzhf.com +hzhfdc.com +hzhfzx.com +hzhike.com +hzhisoft.com +hzhkai.com +hzhl666.com +hzhlcc.com +hzhlgzx.net +hzhlpt.com +hzhltec.com +hzhm888.com +hzhnano.com +hzhnzdh.com +hzhqdj.com +hzhqqz.com +hzhr.com +hzhssy.com +hzhstb.com +hzhtlh.com +hzhuning.com +hzhuti.com +hzhx.com +hzhxfy88888.com +hzhxsy.com +hzhy163.com +hzhyqp.com +hziam.com +hzimc.com +hzinfo.com +hzins.com +hzins.net +hzj7.com +hzjbzg.com +hzjcbg.com +hzjcp.com +hzjcqczl.com +hzjcxh.com +hzjdi.net +hzjiaro.com +hzjiaxiao.com +hzjie7.com +hzjingxian.com +hzjinlu.com +hzjiuyimo.com +hzjizhun.com +hzjlcs.com +hzjljt.com +hzjmjl.com +hzjndz.com +hzjqhy.com +hzjsjl.com +hzjtfw.com +hzjtgcjt.com +hzjtjl.com +hzjtjypt.com +hzjunglepay.com +hzjuzhi.com +hzjxapp.com +hzjxhy.com +hzjxj.com +hzjxmd.com +hzjyks.net +hzjynet.com +hzjywl.net +hzjzjc.com +hzjzmed.com +hzjzxh.com +hzkaiming.com +hzkangji.com +hzkayo.com +hzkcck.com +hzkemengda.com +hzkesheng.com +hzkjcyy.com +hzkjgf.com +hzkjn.com +hzkln.com +hzklyy.com +hzkqyyjt.com +hzkszx.com +hzlange.com +hzlawyer.net +hzlczx.com +hzleaper.com +hzleshun.com +hzlgzs.net +hzliangdong.com +hzlingxing.com +hzljlyy.com +hzlp.com +hzlqgroup.com +hzlrbiotech.com +hzlrhb.com +hzlug.org +hzlyhs.com +hzmama.net +hzman.net +hzmansheng.com +hzmantu.com +hzmba.com +hzmcd.com +hzmctech.com +hzmdch.com +hzmdcnc.com +hzmeizhuo.com +hzmest.com +hzmetro.com +hzmgdj.com +hzmixc.com +hzmkdq.com +hzmobius.com +hzmogo.com +hzmrcar.com +hzmsholding.com +hzmt001.com +hzmtg.com +hzmtjx.com +hzmxkj.net +hzmygg.com +hzmylike.com +hzncc.com +hznet.tv +hznetwk.com +hznewface.com +hznews.com +hznkg.com +hznrkj.com +hznsh.com +hzntjt.com +hznunxc.com +hznzcn.com +hzok.net +hzorganicchem.com +hzou.net +hzpcs.com +hzpgc.com +hzpswy.com +hzpzs.net +hzqfy.com +hzqiuxue.com +hzqj.com +hzqjdz.net +hzqlpt.com +hzqsn.com +hzqszl.com +hzqvod.com +hzqx.com +hzqxbg.com +hzqyhydrogen.com +hzr1.com +hzragine.com +hzranqu.com +hzrc.com +hzrczx.net +hzrdjt.com +hzredream.com +hzrib.com +hzriyue.com +hzrjjg.com +hzrjkf.com +hzrjmy.com +hzrlciec.com +hzrlhy.com +hzrobam.com +hzrqgf.com +hzrsl.com +hzrxsoft.com +hzs2sc.com +hzsaifang.com +hzsanjiaomao.com +hzsaso.com +hzsbysj.com +hzsbz.com +hzsco.com +hzscxsj.com +hzsdjzgs.com +hzsdlrmyy.com +hzsdyfzfxxx.com +hzseedcorp.com +hzsgjj.com +hzsh666.com +hzshanjie.com +hzshantai.com +hzshengjia.com +hzshudian.com +hzshuren.com +hzshw.com +hzsjnxh.org +hzslgf.com +hzslgzx.com +hzsmbio.com +hzsnowcom.com +hzsource.com +hzsp.com +hzspeed.com +hzsports.net +hzsqhb.com +hzsqsmart.com +hzsswjt.com +hzstad.com +hzstad88.com +hzstar.com +hzstarshuaier.com +hzsteel.com +hzstlzxyy.com +hzsun.com +hzsunup.com +hzswmotor.com +hzswysyy.com +hzszls.com +hzszyyy.com +hzt2006.com +hztbc.com +hztchj.com +hztcm.net +hztdjt.com +hzteaexpo.com +hztek.com +hzthinker.net +hztianchuang.com +hztianlang.com +hztiger.com +hztssy.com +hztuoliang.com +hztvmg.com +hztx.com +hztzkj.net +hzvillas.com +hzvtc.net +hzwan.com +hzwatch.com +hzwaye.com +hzweiheng.com +hzwentou.com +hzwer.com +hzwf.link +hzwgc.com +hzwindpower.com +hzwlt.com +hzwluo.com +hzwmhp.com +hzwmw.com +hzwomenmarathon.com +hzwotu.com +hzwqscl.com +hzwsa.com +hzwsjyjt.com +hzwtech.com +hzwyx.net +hzx.center +hzx8188.com +hzxbcs.com +hzxddt.com +hzxded.com +hzxdfpr.com +hzxdship.com +hzxiangbin.com +hzxiangshang.com +hzxiaoya.com +hzxinglong-ip.com +hzxiyuege.com +hzxqf.com +hzxsjgxx.com +hzxsjtzt.com +hzxuanming.com +hzxuhong.com +hzxy888.com +hzxyns.com +hzxywlkj.com +hzy189.com +hzyanglao.com +hzyaohao.com +hzyapu.com +hzyb.com +hzyestar.com +hzyhjg.com +hzyhzp.com +hzyidc.com +hzyjd.com +hzyllh.com +hzylpco.com +hzyn888.com +hzyoka.com +hzyoushu.com +hzyqys.com +hzyread.com +hzyuejie.com +hzyuewan.com +hzywinf.com +hzyxart.com +hzyye.com +hzyys.com +hzyz.net +hzyzhp.com +hzyzxx.net +hzzbco.com +hzzckg.com +hzzfxx.com +hzzh.com +hzzhaobiao.com +hzzhhd.com +hzzhileng.com +hzzhiwei.com +hzzhjs.com +hzzhonggang.net +hzzhonghao.com +hzzhuode.com +hzzhyl.com +hzzhzm.com +hzzjjsgc.com +hzzjzk.com +hzzkj.net +hzzp.com +hzzpko3186.vip +hzzqzc.com +hzzrmc.com +hzzsfs.com +hzzsxh.com +hzztkj.com +hzzuyin.com +hzzx365.com +hzzxyjhyy.com +hzzxyy.com +hzzzpt.com +i-27.name +i-520.net +i-bei.com +i-bigdatas.net +i-click.com +i-conference.org +i-excellence.com +i-f.work +i-fanr.com +i-firefly.com +i-haitao.com +i-hifi.com +i-ktv.com +i-lewan.com +i-lu.cc +i-m.dev +i-manji.com +i-markit.com +i-md.com +i-miguo.com +i-mock.com +i-modec.com +i-mofang.com +i-morefun.com +i-mylab.com +i-neeq.com +i-now.com +i-oranges.com +i-same.com +i-sensjs.com +i-shu.com +i-shunxi.com +i-size.com +i-swimmer.com +i-tetris.com +i-tongfang.com +i-touchpanel.com +i-vista.org +i-weichuan.com +i-xiaohaibao.com +i-xinnuo.com +i-xoron.com +i-z-e.com +i.dell.com +i.ipinyou.com +i.pki.goog +i007.vip +i027.com +i0349.com +i0469.com +i0734.com +i0746.com +i075.com +i0766.com +i0898.org +i11r.com +i121.net +i1608.com +i16949.com +i171.com +i1758.com +i1766.com +i178.info +i1r.cc +i2863.com +i2abc.com +i2eas.com +i2finance.net +i2ya.com +i360mall.com +i369.com +i3839.com +i3abox.com +i3ciebwk6ixfb.com +i3done.com +i3dpworld.com +i3geek.com +i3gt.com +i3smot.com +i3vsoft.com +i3yuan.com +i3z.cc +i4px.com +i4t.com +i51game.com +i52tt.com +i5399.com +i56r.com +i588ku.com +i5a6.com +i5i6.net +i5p.com +i5sto.com +i5tea.com +i66wan.com +i6879.com +i72.com +i77p94y6yi.com +i7car.com +i7fh.com +i7gg.com +i7ol.com +i7play.com +i7txt.cc +i8956.com +i8i8i8.com +i8toys.com +i8tq.com +i91pv.com +i965300.com +i987.com +i9978.net +i9dhjx.ru +i9mr.com +i9rht.com +i9star.com +ia-shenzhen.com +iaapc.org +iacstar.com +iaddata.com +iadmob.com +iadmore.com +iadtracker.com +iaeac.org +iagefans.com +iai-robot.com +iaion.com +iaitao.com +iaixue.com +iajl.org +ialicdn.com +ialloc.com +iamabio.com +iambocai.com +iameduwork.com +iamfisher.net +iamips.com +iamle.com +iamlintao.com +iamlm.com +iamshuaidi.com +iamsujie.com +iamtxt.com +iamvloger.com +iamvlogger.com +iamxcb.com +iamxiaoming.net +iamxk.com +ianbaby.com +iandun.com +ianvisa.com +ianxing.com +iaocwbk.com +iaoligame.com +iaoyou.com +iaozi.com +iaozu.com +iape-js.com +iapijy.com +iapkk.com +iapolo.com +iappad.com +iappdaily.com +iapprank.com +iapps.im +iappsafe.com +iappsign.com +iappstoday.com +iapptry.com +iarlejz.com +iars-wuhan.com +iask-media.com +iask.com +iask.in +iaskbus.com +iaskhot.com +iasmr.cc +iat-auto.com +iautodaily.com +iautodraw.com +iautopress.com +iavira.com +iaviva.com +iavlife.com +iaxure.com +iazhi.com +ib-china.com +ib3-gogin.com +ibabyjoy.com +ibadboy.net +ibailve.com +ibaiqiu.com +ibaitiao.com +ibaizhu.com +ibanana.club +ibanbu.com +ibanggo.com +ibangkf.com +ibangquan.com +ibangtiao.com +ibanma.net +ibanquan.com +ibantang.com +ibanyu.com +ibaobay.com +ibaoji.cc +ibaoji.com +ibaossl.com +ibaotu.com +ibaoxiu.net +ibaralioho.com +ibashu.net +ibayapp.com +ibb2b.com +ibbwhat.com +ibcet.org +ibczy.com +ibdxigualive.com +ibdxiguavod.com +ibee360.com +ibeidiao.com +ibeifeng.com +ibeiig.com +ibenxi.com +ibestapp.com +ibestfanli.com +ibeta.me +ibianma.com +ibicn.com +ibidian.com +ibiji.com +ibingniao.com +ibiquge.info +ibiquge.la +ibiquge.net +ibiquges.com +ibiquges.info +ibiquges.org +ibiquke.com +ibiquku.la +ibiquxs.info +ibiquxs.net +ibiquzw.info +ibireme.com +ibituo.com +ibixiaxs.com +ibkcn.com +ibkstore.com +ibl520.com +iblimg.com +iblog.ren +ibloger.net +iblue.com +iblue.me +ibluefrog.com +ibluesocial.com +iblwl.com +ibm-dns.com +ibmcampus.com +ibmfwqdl.com +ibmhz.com +ibmwclub.com +ibobscs.com +ibodao.com +ibodyhome.com +iboohee.com +ibook8.com +ibooker.cc +ibooloo.com +ibornclinic.com +ibossay.com +ibox.art +iboxpay.com +ibreader.com +ibreeno.com +ibribery.com +ibrilife.com +ibroadlink.com +ibruce.info +ibscdn.com +ibtsat.com +ibucm.com +ibuick.com +ibuscloud.com +ibuscloud.net +ibuychem.com +ibw.cc +ibytedapm.com +ic-bro.com +ic-captain.com +ic-itssc.org +ic-king.com +ic-ldo.com +ic-leasing.com +ic-mag.com +ic-spic.com +ic-valley.com +ic001.org +ic2china.com +ic37.com +ic71.com +ic72.com +ic98.com +ic9cube.com +ica-alliance.org +icabcm.org +icaew-china.com +icafe8.com +icafe8.net +icai.vip +icaidao.com +icaifu.com +icaile.com +icall.me +ican-x.com +ican365.net +icandata.com +icaneasy.com +icangshu111.com +icanvideo.com +icarbonx.com +icardfinancial.com +icaredbd.com +icasiso.com +icastlewar.com +icax.org +icbc-at.com +icbc-axa.com +icbc-cz.com +icbc-ltd.com +icbc-uk.com +icbc-us.com +icbc.ae +icbc.be +icbc.co.id +icbc.co.jp +icbc.co.kr +icbc.co.nl +icbc.com.au +icbc.com.es +icbc.com.kh +icbc.com.kw +icbc.com.la +icbc.com.mm +icbc.com.mo +icbc.com.mx +icbc.com.pe +icbc.com.pk +icbc.com.qa +icbc.com.sg +icbc.com.vn +icbc.de +icbc.eu +icbc.jp +icbc.lu +icbcalmaty.kz +icbcamg.com +icbcasia.com +icbcbr.com.br +icbci.com.hk +icbcina.com +icbcindia.com +icbcit.com +icbcleasing.com +icbclondon.com +icbcme.ae +icbcmoscow.ru +icbcmy.com +icbcnz.com +icbcpanama.com +icbcparis.fr +icbcpl.com +icbcstandard.com +icbcstandardbank.com +icbcstandardresources.com +icbcstandardsecurities.com +icbcswiss.com +icbcthai.com +icbcwallet.com +icbeexpo.com +icbkfs.com +icbkus.com +icbuy.com +icc.link +iccchina.com +iccessh.org +iccgame.com +iccgame.net +icchaoren.com +iccidchaxun.com +iccircle.com +iccsz.com +icctbs.org +iccvlog.com +icdeal.com +icdemi.com +icdmall.com +icdn2.com +icdream.com +icdt-conf.com +ice.work +ice1000.org +ice138.com +iceasy.com +icebear.me +icebound.cc +icecast-ruvr.cdnvideo.ru +icecloud-car.com +icedropper.com +iceflowsoft.com +icefoxgame.com +icehotisland.com +iceinto.com +icekylin.online +icemle.org +icentown.com +icepie.net +iceread.com +iceriverbj.com +icesimba.com +icesofts.com +icetorrent.org +icevirtuallibrary.com +icevpn.org +icewingcc.com +icewoo.com +icfans.com +icfcc.com +icfgblog.com +icfqs.com +icfusions.com +icg.cc +icgbl.org +icgebm.org +icgoo.net +icgu.com +ich8.com +ichacha.com +ichanfeng.com +ichang8.com +ichangtou.com +ichangyan.com +ichanyu.com +ichaoshangyue.com +ichaotao.com +ichaotu.com +ichat800.com +ichatcn.com +ichdata.com +icheese.net +ichehome.com +ichemsafe.com +ichenfu.com +ichengli.com +ichengsi.com +ichengyun.net +ichennan.com +icheruby.net +icheshi.com +ichezhan.com +ichhlj.com +ichika.cc +ichinaceo.com +ichinaenergy.com +ichong123.com +ichongdao.com +ichtcm.com +ichuanglan.com +ichuangye.com +ichuanyi.com +ichuguang.com +ichunqiu.com +ichunt.com +ichzh.com +iciba.com +iciba.net +icicicic.com +icignacmb.com +icinfo.net +icirculation.com +icitizens.net +icitymobile.com +icixun.com +iciyuan.com +icjs.ink +ickeep.com +icketang.com +ickey.cc +ickimg.com +iclabcn.com +iclicash.com +iclickstatic.com +icliexpo.com +icljt.com +icloud-power.com +icloudcity.com +icloudgslb.com +icloudnative.io +icloudnews.net +iclouds.work +icloudv6.com +icloudwaf.com +icmaxgroup.com +icme14.org +icminer.com +icmomo.com +icmp.link +icmsdev.com +icnal.com +icnano-tech.com +icncpc.com +icnjob.com +icnkr.com +icntv.tv +icntvcdn.com +ico-deli.com +icoat.cc +icoc.bz +icoc.in +icoc.me +icoc.vc +icodelogic.com +icoderobot.com +icofchina.com +icomuimi.com +iconntech.com +icoolby.com +icoonal.xyz +icoou.com +icoremail.net +icos8.com +icosky.com +icostapp.com +icosz.com +icot.com +icourse163.com +icourse163.org +icourses163.com +icourses163.org +icourt.cc +icp.red +icp100.net +icp21.com +icpapi.com +icpbcm.org +icpcdn.com +icpcw.com +icpdaili.com +icpdf.com +icpeexpo.com +icpenguin.com +icpenguin.net +icphu.com +icpisp.net +icpkuaiban.net +icplishi.com +icqmwrhm.com +ics-sec.com +ics.design +icshanghai.com +icsisia.com +icslx.com +icsoc.net +icson.com +icspec.com +icsprout.com +icstreet.com +icsuns.com +icswb.com +ict18.com +ict361.com +ict88.com +ictbda.com +ictcsr.org +ictdns.cloud +ictdns.icu +ictdns.store +ictdns.tech +ictehi.com +ictest8.com +ictlce.com +ictown.com +ictp-ap.org +ictpaas.com +ictun.com +ictuniv.com +iculture.cc +icustomslawyer.com +icv-ip.com +icvcs.com +icver.com +icvip.com +icxbk.com +icxinli.com +icy-capital.com +icytown.com +icyuyan.net +icz.com +iczhiku.com +iczoom.com +id-bear.com +id-photo-verify.com +id4r.com +id4r.net +id57.com +ida-a.org +idaasksyun.com +idachu.com +idacn.org +idadt.com +idailycar.com +idaima.com +idangyang.com +idanpianji.com +idaocao.com +idaotuo.com +idatacube.com +idataforces.com +idatage.com +idatagx.com +idataway.com +idatawz.com +idayer.com +idbhost.com +idc-icp.com +idc-status.com +idc002.com +idc021.com +idc027.net +idc029.com +idc123.com +idc129.com +idc1680.com +idc180.com +idc218.com +idc31.com +idc35.com +idc4.com +idc400.com +idc45.com +idc789.com +idc917.com +idcay.com +idcbdy.com +idcbest.com +idcbest.hk +idccenter.net +idcchacha.com +idccom.net +idccun.com +idcd.com +idcdoc.com +idceb.com +idcfengye.com +idcgcloudcs.com +idchz.com +idchz.net +idcicp.com +idcicpdns.com +idcjf.com +idckx.com +idcloudbase.com +idcmz.com +idcoffer.com +idcpu.com +idcquan.com +idcsec.com +idcser.com +idcsh.com +idcsmart.com +idcsp.com +idcspy.com +idcspy.net +idcss.com +idctalk.com +idctq.com +idcug.com +idcum.net +idcun.com +idcvendor.com +idcvip.net +idcwn.com +idcwp.com +idcys.com +idcyunwei.org +idczone.net +idd1.com +ideabody.com +ideacarbon.org +ideacms.net +ideacreated.com +ideaflow.pro +ideagou.com +ideaintellij.com +idealbags.com +idealcontrol.com +idealdeposition.com +idealeer.com +idealideapromos.com +idealjj.com +idealshanghai.com +ideanote.cc +ideapool.tv +ideappt.com +idearhanyu.com +ideasr.com +ideassoft.com +ideation.love +ideazhao.com +ideepin.com +ideerled.com +idejian.com +idejian.net +iden123.com +idepu.org +idesktopcal.com +idevbase.com +idgeeks.net +idgou.com +idgvc.com +idianchou.com +idianfa.com +idiankj.com +idianshijia.com +idiaoyan.com +idigi.net +idingju.com +idlegog.com +idloves.com +idlpc.win +idmzj.com +idnscloud.com +ido-love.com +ido512.com +idoacg.com +idocbank.com +idocv.com +idodb.com +idol001.com +idolmoba.com +idom.me +idong.ren +idongde.com +idongdong.com +idongniu.com +idongzhi.com +idooshu.com +idosend.com +idotools.com +idoupiao.com +idouqu.com +idourl.com +idouyinliving.com +idouyinpic.com +idouyinstatic.com +idouyinvod.com +idouzi.com +idoyun.com +idqqimg.com +idreamsky.com +idreamsoft.com +idrools.com +idrwl.com +idscn.net +idshi.com +idsoo.com +idspub.net +idss.shop +idsuipai.com +idtcdn.com +idtechwh.com +idu9.com +iduba.com +iduiying.com +idukaqi.com +iduochong.com +iduodou.com +iduokan.net +iduomi.cc +idux-vw.com +idwzs.com +idwzx.com +idx365.com +ie13.com +ie515.com +ie525.com +ie57.com +ie815.com +ie915.com +ie935.com +ieasn.com +ieasou.com +ieasy123.com +ieasyclick.net +ieasytech.com +ieasytest.net +ieayoio.com +iecdn.com +iecidc.com +iecity.com +iecool.com +iecworld.com +ieduchina.com +ieduglobe.com +ieechina.com +ieee-jas.net +ieee.org +ieeepower.com +ieeewifi.com +ieepa.org +ieevchina.com +iefang.com +iefans.net +ieffect.cc +ieforever.com +iefrd.com +iefxz.com +iegcom.com +iegourl.com +ieh-hz.com +iehou.com +ieisystem.com +iejiu.com +ieliulanqi.net +ieltsabc.com +ieltsonlinetests.com +iemailforce.com +iemblog.com +iemnet.xyz +iemouepk.com +ienglish.store +ienjoys.com +ienjoys.mobi +ientire.biz +iepcn.com +iepose.com +ieppcn.com +ieqkypcq.com +ierze.com +iesdouyin.com +iesdouyin.net +ieshs.com +ieshs.net +ieshuodong.net +ieshuoshan.com +ieshuoshan.net +iessay100.com +ietdata.com +ietheme.com +ietrcd.com +ievision.com +iewb.net +iewie.org +iewoai.com +iewzx.com +iex-group.com +iexx.com +ieyecloud.com +iezuo.com +if1f.com +ifabao.com +ifabiao.com +ifaclub.com +ifanbei.com +ifangarden.com +ifangka.com +ifanpu.com +ifanr.com +ifanr.in +ifanrcloud.com +ifanrprod.com +ifanrprod.net +ifanrusercontent.com +ifanrx.com +ifareast.com +ifatrabbit.com +ifaxin.com +ifaxin.org +ifconfig.cc +ifcresidence.com +ifdian.net +ifeart.ltd +ifedge.com +ifeehei.xyz +ifeilian.com +ifeimo.com +ifeng.com +ifengcdn.com +ifengcu.com +ifenghui.com +ifengidc.com +ifengimg.com +ifengli.com +ifenglian.com +ifenglife.com +ifengmap.com +ifengo.com +ifengpai.com +ifengqun.com +ifenguo.com +ifengweekly.com +ifengwoo.com +ifengyin.com +ifensi.com +ifenxi.com +ifenxiang.cc +ifere.com +ifeve.com +iffline.com +ifindever.com +ifintechnews.com +ifireeye.com +ifireflygame.com +ifish7.com +ifitbox.com +ifjing.com +ifjqq.com +ifkeji.com +ifkz256x3p.com +iflix.com +iflow.work +iflowercity.com +iflyadx.com +iflyaiedu.com +iflyauto-solution.com +iflydatahub.com +iflydocs.com +iflygse.com +iflyhealth.com +iflying.com +iflyink.com +iflyiot.com +iflynote.com +iflyread.com +iflyrec.com +iflyresearch.com +iflysec.com +iflytek.com +iflytekin.com +iflytektstd.com +iflytoy.com +ifmtech.com +ifnews.com +ifonelab.net +ifonts.com +iforce-ad.com +iforce-media.com +ifoxfactory.com +ifoxhui.com +ifread.com +ifreecdn.com +ifreecomm.com +ifreedom.icu +ifreedom001.com +ifreetalk.com +ifreeurl.com +ifresh.mobi +ifromvr.com +ifscity.com +ifseclabs.com +ifshot.com +ifundstore.com +ifunmac.com +ifutest.com +ifutureworks.com +ifxtx.com +ifzxs.cc +ifzzw.com +igaichong.com +igame007.com +igame58.com +igamecj.com +igandan.com +iganggu.com +igao7.com +igaoda.com +igaokaopai.com +igaosheng.com +igarwin.com +igbill.com +igdzc.com +igea-un.org +igeak.com +igeciku.com +igeekbar.com +igeekys.com +igeidao.com +igelou.com +igenetech.com +igengmei.com +igeshui.com +igetget.com +igetmall.net +igevin.info +igimu.com +igkbroker.com +iglda.com +iglqh.com +igo180.com +igo52.com +igocctv.com +igome.com +igomkt.com +igoodgame.com +igooma.com +igou.com +igoyx.com +igps123.com +igpsport.com +igptex.com +igreatdream.com +igrs.org +igta.vip +igtm-a101.com +igtm-b101.com +igtm-c101.com +igtm-d101.com +igtm-e101.com +igtm-meeting-tencent.com +igtm-yuanbao.com +igtm.pub +iguaka.com +iguangdiu.com +iguanyu.com +iguazutraffic.xyz +iguder.com +iguitar.me +iguizao.com +iguming.net +igumo.cc +iguoguo.net +iguopin.com +iguoplay.com +iguowan.com +iguoyin.com +iguxuan.com +igwfmc.com +igwzx.com +igxbaidu.net +ihacksoft.com +ihaier.com +ihaima.com +ihaique.net +ihaiu.com +ihaiyan.com +ihanbridge.com +ihanghai.com +ihanhua.com +ihani.tv +ihansen.org +ihanshi.com +ihaohaoxuexi.com +ihaoma.icu +ihaoqu.com +ihaoxi.com +ihaozhuo.com +ihappy.vip +ihappystudio.com +ihappystudio.net +ihasl.com +ihdt.tv +ihdty.com +ihealthcoming.com +ihei5.com +iheima.com +ihello.cc +ihelpy.net +ihemuu.com +ihenda.com +ihengheng.com +ihepa.com +ihggccampaign.com +ihicon.com +ihigee.com +ihint.me +ihisce.com +ihitui.com +ihitun.com +ihkk.net +ihlimtv.com +ihmch.com +ihnhr.com +ihomefnt.com +ihomesoft.net +ihongde.com +ihongma.com +ihongmeng.tech +ihongpan.com +ihonker.com +ihotchip.com +ihou.com +ihourglass.club +ihowguide.com +ihqfo.org +ihr360.com +ihrscloud.com +ihst8.com +ihstatic.com +ihtcboy.com +ihtmlcss.com +ihtwmi.yachts +ihuaben.com +ihuan.me +ihuang.org +ihuanling.com +ihuanque.com +ihuayou.com +ihuazhan.net +ihuge.net +ihui.com +ihuidian.com +ihuigo.com +ihuipao.com +ihuisida.net +ihuman.com +ihumand.com +ihuntto.com +ihuoli.com +ihuoqiu.com +ihuoshanimg.com +ihuoshanlive.com +ihuoshanstatic.com +ihuoshanvod.com +ihuoyan.com +ihupo.com +ihuyi.com +ihwrm.com +ihxlife.com +ihyhs.com +ihying.cc +ihykb.com +ihypnus.com +ihypo.net +ihytv.com +ihzzy.com +ii.td +ii010.com +ii090.com +ii35.com +ii77.com +iianews.com +iiaq.net +iiast.com +iiauuw.com +iibechina.com +iibq.com +iicall.com +iicats.com +iicha.com +iicheese.com +iicp.net +iicz.cc +iidns.com +iidx.fun +iieii.com +iiesz.com +iieye.cc +iii80.com +iiiaaa.com +iiiddd.com +iiiib.com +iiiimg.com +iiijk.com +iiiview.net +iikuzhan.com +iikx.com +iinhotel.com +iinorii.com +iiolink.com +iiong.com +iipcloud.com +iipiano.com +iirii.com +iirpwigs.com +iis7.com +iis7.net +iis8.com +iischool.com +iisfree2.com +iisp.com +iispbdy.com +iissnan.com +iitang.com +iitcp.com +iithz.com +iitol.com +iituku.com +iivd.net +iivey.com +iiwoo.com +iiyi.com +iiyiyi.com +ijatv.com +ijh.cc +ijheng.com +ijia120.com +ijia360.com +ijiandao.com +ijiangyin.com +ijianji.com +ijiaoxue.net +ijiatv.com +ijicai.com +ijie.com +ijiebao.com +ijiedian.com +ijiela.com +ijindun.com +ijingdi.com +ijingyi.com +ijinshan.com +ijinzhuan.com +ijishu.cc +ijiwei.com +ijiwen.com +ijizhi.com +ijjnews.com +ijkuhygabc.work +ijkxt.com +ijml.net +ijnqc.com +ijovo.com +ijq.tv +ijsi.org +ijson.com +ijsp.net +ijuanshi.com +ijuer.com +ijuhepay.com +ijunhai.com +ijunxun.com +ijuzhong.com +ijxuitr.com +ijycnd.com +ijzhang.com +ik123.com +ik3cloud.com +ikafan.com +ikahe.com +ikaixun.com +ikaka.com +ikanchai.com +ikang.com +ikanoo.com +ikantu365.com +ikaolaa.com +ikaowu.com +ikb.vc +ikcd.net +ikcest.org +ikck.com +ikcrm.com +ikcw.com +ikdmjx.com +ike-global.com +ikebukuro777.org +ikeled.com +ikemeng.com +ikepu.com +ikgambwqeqnv.com +ikhimalayaniq.com +ikj123.com +ikj168.com +ikjds.com +ikjtao.com +ikjxc.com +ikmoo.com +ikmt.net +ikncn.com +ikonfx.com +ikongjian.com +ikongjun.com +ikonke.com +ikoori.com +ikozn.com +ikqtcbva.com +iksea.com +ikuai8-wifi.com +ikuai8.com +ikuaicai.com +ikuaimi.com +ikuaiyue.com +ikuajing.com +ikuayou.com +ikuju.com +ikunac.com +ikuncdnfb.com +ikunpay.com +ikupan.me +ikvoaxzw.com +ikx.me +ikxnes04.com +ikyy.cc +ikzybf.com +ilab-x.com +ilabilab.com +ilaisa.com +ilaitui.com +ilangqu.com +ilanni.com +ilanyao.com +ilanzou.com +ilaoyou.com +ilaozhu.com +ilaw13.com +ilaw66.com +ilawpress.com +ilazycat.com +ilcweloc.com +ilea-roswell.org +ileadsun.com +ileapcloud.com +ileci.com +ileedarson.com +ileehoo.com +ileju.com +ileopard.com +ileshua.com +iletou.com +ilewan.com +iliangcang.com +ilianwo.com +ilianyue.com +ilibrand.com +ilifesmart.com +ilikemanga.com +ilingdai.com +ilinki.net +ilinkmall.com +ilinkone.com +ilinksure.com +ilinuxkernel.com +ilinyi.net +ilishi.net +ilivehouse.com +ilixiangguo.com +iliyu.com +illl.xyz +ilmgq.com +ilohas.com +iloli.bid +iloli.xin +ilongre.com +ilongterm.com +ilonhoo.com +iloveanan.com +ilovechao.com +ilovefishc.com +iloveopened.com +ilovey.live +ilovezuan.com +ilovezz.com +ilsungf.com +ilucky.net +iluckysf.net +iluezhi.com +ilufan.com +iluhang.com +ilustrepro.com +iluvatar.ai +iluvatar.com +ilux.ai +ilvxing.com +ilxdh.com +ilxtx.com +ilydjk.com +ilz.me +im-cc.com +im-ch.com +im.ci +im286.com +im286.net +im2maker.com +im323.com +im577.com +im5i.com +im9.com +imaccn.com +imachina.com +imaegoo.com +image-tech.vip +imageaccelerate.com +imageedu.com +imagefuture101.com +imagehub.cc +imagelol.com +imageoss.com +imageplusplus.com +imageplusplus.net +imagepy.org +imagerjt.com +images-amazon.com +images-cache.com +images-cn-8.ssl-images-amazon.com +images-cn.ssl-images-amazon.com +images.samsung.com +imagestoryai.com +imagetotxt.com +imagiclouds.com +imaginde.com +imagineadtech.com +imaibo.net +imaicai.mobi +imaijia.com +imaitu.com +imalljoy.com +imallvip.com +imalun.com +imandarin.net +imanke.com +imao2.com +imaojiang.com +imarketchina.com +imarkr.com +imaschina.com +imatlas.com +imayitxt.com +imbackr.com +imbeiyu.com +imblog.in +imbtk.com +imcapptest.com +imcart.com +imcclinics.com +imcec.org +imchinese.net +imcn.me +imcome.net +imcoming.com +imconlinereg.com +imcq.net +imd-marketing.com +imdadui.com +imdmedical.com +imdo.co +imdodo.com +imdst.com +imedao.com +imedcloudimage.com +imedera.com +imedicalai.com +imedlab.net +imedp.com +imeete.com +imeete.net +imeete1.com +imeete2.com +imeete3.com +imeete4.com +imeeton.com +imefuture.com +imeidb.com +imeihei.com +imeimama.com +imeiren.com +imeirongyi.com +imeishike.com +imeitools.com +imeitou.com +imelai.com +imeme.tv +imetacloud.com +imeyahair.com +imf.org +imfirewall.com +imfooww.com +img-space.com +img-static.tech +img-sys.com +img.beauty +img.ink +img.net +img.run +img.samsungapps.com +img.vin +img001.com +img005.com +img168.net +img16888.com +img4399.com +img4me.com +img898.com +imgbed.link +imgcdc.com +imgchr.com +imgcook.com +imgdd.cc +imgdianying.com +imgdianyingoss.com +imge.cc +imgeek.net +imgeek.org +imgets.com +imgii.com +imgkr.com +imglefeng.com +imglink.win +imgmarket.net +imgmg.com +imgo.tv +imgs.ovh +imgscdn.com +imgse.com +imgsha.com +imgsina.com +imgsohu.com +imgtex.com +imgtg.com +imgurl.org +imgyzzy.com +imgzy360.com +imhan.com +imhdr.com +imhuchao.com +imiaomeng.com +imibaby.net +imibao.com +imicome.com +imifun.com +imigu.com +imiker.com +imile-inc.com +imile.com +imitui.com +imixpark.com +imjiayin.com +imkero.net +imkevinyang.com +imlaidian.com +imlazy.ink +imlb2c.com +imlianai.com +imlianpu.com +imliuyi.com +imlizhi.com +immeee.com +immfast.com +immi520.com +immiexpo.com +immiknow.com +immivip.com +immomo.com +immomogame.com +immotors.com +immune-path.com +immusician.com +immviragroup.com +imnerd.org +imnight.com +imnks.com +imobile-ent.com +imoe.me +imoe.tech +imoeer.com +imofan.com +imoffice.com +imok.net +imok.run +imoke.org +imol.cc +imolive.tv +imoo.com +imooc.com +imoocc.com +imop.com +imosi.com +imotao.com +imotion.group +imoto.love +imou.com +imovideo.ru +imp3.net +impcochina.com +imperfectionstudio.com +imperial-vision.com +imperialsprings.com +imperialspringsforum.org +impk.cc +impnails.com +importingtochina.com +improve-ai.com +improve-medical.com +impta.com +imqianduan.com +imqq.com +imqq.net +imquzan.com +imrfresh.com +imrobotic.com +imroc.cc +imscv.com +imsharecenter.com +imshu.cc +imshusheng.com +imsilkroad.com +imsinoexpo.com +imsle.com +imsun.net +imsyy.com +imtaweb.net +imtics.com +imtrwqjier3.com +imtuan.com +imtyimages.vip +imudgame.com +imugeda.com +imuke.com +imummybiz.com +imusicking.com +imvictor.tech +imvtc.com +imwaco.com +imwallet.com +imweb.io +imweia.com +imwexpo.com +imwork.net +imwukong.com +imwzh.com +imx365.net +imxh.com +imxiaomai.com +imxingzhe.com +imxpan.com +imycdn.com +imycloud.com +imydns.net +imyfone.club +imyike.com +imyouxin.com +imys.net +imyshare.com +imyuedu.com +imyushu.com +imzego.com +imzhanghao.com +imzhongxin.com +imzhuomo.com +imzudian.com +imzy.ink +in-driving.com +in-en.com +in-freight.com +in-int.com +in-tencentclb.cloud +in-tencentclb.com +in-tencentclb.net +in-tencentclb.work +in.th +in001.com +in66.com +in800.com +in853.com +in955.com +inabr.com +inadvanceof.com +inaink.com +inav.site +inbeing.net +inbilin.com +inbooker.com +inboyu.com +inc365.com +incake.net +incensechina.com +inch.red +inchitech.com +incker.com +incloudexpo.com +incomperlite.com +incomrecycle.com +incopat.com +increasedct.com +incsg.com +inctrip.com +ind-map.com +ind4.net +ind9ed.com +indetek-lab.com +indexea.com +indexedu.com +indexedu.net +indexfor.fun +indexmob.com +indics.com +indielight.net +indienova.com +indier.com +indigobeijing.com +indmi.com +indochinatraveladvisor.com +indonesia-daily.com +indubd.com +industrybamboo.com +industryillusion.com +induta.com +inekoxia.com +inengyuan.com +inesa-it.com +inesa.com +inetech.fun +inetmaster.net +inewhope.com +inewoffice.com +inewskeji.com +inexbot.com +infarts.net +inferoey.com +infertilitybridge.com +infimotion.com +infineon-autoeco.com +infini-ai.com +infinisign.com +infiniteborders3kingdoms.com +infinitescript.com +infinity8ball.com +infinitynewtab.com +infinitytab.com +inflyway.com +info-insur.com +info-monitor.com +info-onesky.com +info.cc +info10.com +info110.com +info35.com +infobidding.com +infobigdata.com +infocloud.cc +infoeach.com +infohand.net +infohpc.com +infoier.com +infoldgames.com +infomorning.com +infong.net +infoobs.com +infoodfamily.com +infoq.com +infoqstatic.com +inforbus.com +inforeenviro.com +inforguard.net +informrack.com +inforsec.org +infosoft.cc +infovc.com +infoview.com +infowuxi.com +infoxgame.com +infoxiao.com +inframe.mobi +inftab.com +infyniclick.com +infzm.com +ing10bbs.com +ingageapp.com +ingags.com +ingaoyt.biz +ingcore.com +ingdan.com +ingeek.com +ingenic.com +ingkee.com +ingping.com +ingping.net +ingzhong.com +inhalpharma.com +inhdd.com +inhe.com +inhe365.com +inheweb.com +inhuawei.com +ini5.com +inibiru.com +inicoapp.com +inidc.net +ininin.com +initaa.com +initac.com +initaf.com +initah.com +initaj.com +initbb.com +initcc.com +initdd.com +initff.com +initialview.com +initjj.com +initkk.com +initll.com +initmm.com +initnn.com +initpp.com +initqq.com +initroot.com +initrr.com +inittt.com +inituu.com +initvv.com +initww.com +initxa.com +initxb.com +initxx.com +initzz.com +inja.com +injectionmachine.com +injoinic.com +ink4you.com +inkankan.com +inkcc.net +inkcn.com +inke.com +inke.tv +inkeygo.com +inkonlife.com +inkonote.com +inktok.com +inkuai.com +inkwai.com +inlandschool.com +inlaylink.com +inlighting.org +inlishui.com +inliuzhou.com +inluckcalendar.com +inmeng.net +inmuu.com +inmyshow.com +innatek.com +innnnnn.com +inno3d.cc +innobm.com +innocn.com +innocomn.com +innodealing.com +innofidei.com +innogenpharm.com +innohere.com +innojoy.com +innolcon.com +innomd.org +innomddesign.com +innopack97.com +innoplayfun.com +innopro.cc +innos.com +innotechx.com +innotek-co.com +innotimegood.com +innotron.com +innov-xsystem.com +innovagt.com +innovane.com +innovatedigital.com +innovationmetal.com +innoventbio.com +innover.com +innoveronline.com +innovidcn.com +innovisgroup.com +innovmedicine.com +innvitor.com +ino3w.com +inoherb.com +inoneh5.com +inong.net +inoteexpress.com +inovance-automotive.com +inovogen.com +inovppg.com +inovpu.com +inpla.net +inplayable.com +inputmore.com +inqan.com +inrice.com +inrice.zone +inrugao.com +ins110.com +insagee.com +insarticle.com +inshion.com +inshotapp.com +insigma-elec.com +insistence.tech +insmoin.com +insnail.com +insneu.com +insnex.com +insome.com +inspeed.biz +inspirecloud.com +inspmobi.com +inspur.com +inspurcloudoss.com +inspuronline.com +inspurpower.com +inspurpower.org +insta360.com +instafogging.com +installgreat.com +installwage.com +instantinfographicspresence.com +instome.com +insulators-china.com +insun-china.com +inswindow.com +insxz.com +insytone.com +int-agri.com +int2018.com +int800.com +intaek.com +intdmp.com +intecheye.com +intecol-10iwc.com +intedc.com +integrity-funds.com +intekey.com +intel-space.com +intelcupid.com +intellect.black +intelligen.ltd +intelligence-electricity.net +intelligentmanufactory.com +intelvisioncn.com +intencent.com +inter-credit.net +inter-rock.com +inter1908.net +interactivebrokers.hk +interchinawater.com +interface003.com +interiorous.com +international-gfe.nvidia.com +internationalbrand.net +internbird.com +internetke.com +internettrademark.com +intertid.com +interval.im +intimerent.com +intlgame.com +intlqydd.info +intlscdn.com +intltencentcos.com +intmedic.com +intmes.com +intohard.com +intomod.com +intopet.com +intostarry.com +intovfx.com +intowz.com +intozgc.com +intple.com +intramirror.com +intsavi.com +intseamultiply.com +intsig.com +intsig.net +intvolunteer.com +intwho.com +intwing.com +inuobi.com +inuorui.com +inuu6.com +inuyasha.love +invaluablu.com +inverter.so +invescogreatwall.com +invest-data.com +investassistant.com +investbjdx.com +investgohn.com +investoday.net +investorscn.com +investstkitts.org +invocean.com +invoee.com +invzible.com +inwaishe.com +inwatch.cc +inwuoo.com +inxedu.com +inxni.com +inxunoffice.com +inyota.com +inzone-auto.com +inzotek.com +ioa365.com +ioage.com +ioasaas.com +iocdn.cc +iocrest.com +ioe-times.com +iofange.com +ioffershow.com +ioffice100.com +iofomo.com +ioigamer.net +ioikypzw.com +ioiosafe.com +ioiox.com +ioiox.net +ioioz.com +iok.la +iol8.com +ioms.cc +ionchi.com +ioncol.com +ioneball.com +ionewu.com +iongentherapeutics.com +iooeoo.com +iooqoo.com +ioozu.com +iop.org +iopenhec.com +iophthalmology.net +iopiopl.com +ioppo.net +ioptics.org +iorca.net +iornnl.xyz +ios114.com +ios222.com +ios98.com +iosask.com +ioser.fun +iosfengwo.com +ioshacker.net +iosi.vip +iosre.com +iosrxwy.com +ioswg.com +iosyyds.com +ioszc.com +ioszn.com +iot-cas.com +iot-dc.com +iot-tencent.com +iot.moe +iot0.net +iot1001.com +iot101.com +iot688.com +iot889.com +iotachem.com +iotbay.com +iotfair.net +iotku.com +iotmag.com +iotmore.com +iotmrvr.com +iotpai.com +iotrix.net +iotronic.tech +iotrouter.com +iots.vip +iotsafe.net +iotshifang.com +iotweixin.com +iotwrt.com +iotxing.com +iotxx.com +iotyeas.com +iotyes.com +iouluo.com +ioxqm.com +ioxray.com +ioxunyun.com +ip-cdn.com +ip-guard.net +ip-hercules.com +ip-soc.com +ip.istatmenus.app +ip.la +ip008.com +ip138.com +ip159.com +ip181.com +ip192.com +ip33.com +ip3366.net +ip518.com +ip66.com +ip66.net +ip669.com +ip77.net +ip777xxx.com +ip87.com +ip938.com +ipackbynewstep.com +ipadown.com +ipadump.com +ipadview.com +ipaiban.com +ipail.com +ipalfish.com +ipalmap.com +ipampas.com +ipanda.com +ipanda.net +ipandao.com +ipandata.com +ipangcai.com +ipanocloud.com +ipanta.com +ipaobuji.com +ipaochaxun.com +ipaomi.com +ipaotuan.com +ipapark.com +ipason.com +ipay.so +ipaylinks.com +ipbaohe.com +ipcelou.com +ipchaxun.com +ipchaxun.net +ipcmen.com +ipcodm.com +ipcorecatalog.com +ipctest.com +ipcwifi.com +ipdaili.com +ipdatacloud.com +ipddz.com +ipdfmaster.com +ipdftool.com +ipdodo.com +ipdsms.com +ipduoduo.cc +ipduoduo.com +ipdz.me +ipease.net +ipehr.com +ipeijiu.com +ipengchen.com +ipengtai.com +ipetct.com +ipexp.com +ipfeibiao.com +ipfen.com +ipfsbit.com +ipgoal.com +ipguishu.com +iphonediule.com +ipin.com +ipinba.com +ipingke.com +ipingyao.com +ipip.net +ipjingling.com +ipjisuanqi.com +ipktv.com +ipku.com +iplascloud.com +iplay11g.com +iplay365.com +iplaypy.com +iplaysoft.com +iplcn.com +iplusmed.com +iplwin999.com +ipmay.com +ipmi.cc +ipmoniqi.com +ipmost.com +ipmotionmc.com +ipmph.com +ipo.hk +ipo.la +ipo1688.com +ipo3.com +ipoceo.com +iposeidonbussiness.com +iposeidoncdn.com +iposeidongame.com +ipostalcode.com +ipple.net +ipplus360.com +ippsport.com +ippzone.com +ipqcrhf.com +ipr007.com +ipr114.net +ipr123.com +iprabc.com +iprchn.com +iprdaily.com +iprdp.net +ipresst.com +iproyal.co +iprtop.com +iprub.com +iprun.com +ips.com +ips8.com +ipsebe.com +ipshu.com +ipshudi.com +ipsmap.com +ipssh.net +iptalent.com +iptrm.com +ipts.com +iptvlm.com +iptvzj.com +ipuer.com +ipuu.net +ipv4.host +ipv4dns.com +ipv6-only.com +ipv6dns.com +ipv6radar.com +ipv6testingcenter.com +ipwuji.com +ipyy.com +iq.com +iq123.com +iq33.com +iqalliance.org +iqbuud.lol +iqbxq.com +iqcrj.com +iqdedu.com +iqdii.com +iqdnet.com +iqhmh.com +iqianggou.com +iqianjin.com +iqianyue.com +iqianzhan.com +iqiaowai.com +iqidian.com +iqihang.com +iqilu.com +iqilun.com +iqimengkj.com +iqinbao.com +iqingguo.com +iqingren.com +iqingua.com +iqingyi.com +iqinshuo.com +iqinzhou.com +iqishu.la +iqiyi.com +iqiyi.demo.uwp +iqiyiedge.com +iqiyiedge.net +iqiyih5.com +iqiyipic.com +iqmie.com +iqnew.com +iqoo.com +iqr.cc +iqtianshanmw.com +iquanba.com +iquanben.net +iquanfen.com +iquanpai.com +iquanwai.com +iquaveizeeru.com +ique.com +iquegui.com +iquhuo.com +iquickfish.com +iqujing.com +iqunix.com +iqunix.store +iqupdate.com +iqxbf.com +iqxedu.com +irain.in +irainone.com +iranmahanair.com +iranshao.com +iraoping.com +irbsh.com +irc-risk.com +ircmnr.com +ireader.com +ireader.live +ireader.mobi +ireadercity.com +ireaderm.com +ireaderm.net +ireadweek.com +ireadyit.com +irealbest.com +irealcare.com +irealtech.com +irecyclingtimes.com +iredwhale.com +ireeda-tech.com +irelandvisacenter.com +iremaker.com +iremax.hk +iremax.net +iresarch.com +iresearchad.com +iresearchchina.com +irest.tv +irestapp.com +irexy.com +iridescent.ink +irisdt.com +irisdt.net +irisgw.com +irisgw.net +irising.me +irlianmeng.com +irmleader.com +irober.com +irobotbox.com +irockbunny.com +iroing.com +ironfishchina.com +irongbei.com +ironghui.com +irootech.com +irort.com +irouteros.com +irqpa.work +irrichina.com +irskj.com +irsnp.com +irtouch.com +iruanmi.com +iruanshi.com +iruidian.com +iruixing.com +irunner.mobi +iryoucai.com +is-programmer.com +is36.com +is404.com +isa-hsse.com +isa1751.com +isagzfls.com +isagzlw.com +isagzlwis.com +isagzlws.com +isagzsc.com +isagzth.com +isahome.net +isaieg.com +isamanhua.com +isameforum.org +isapt.com +isawhis.com +isawhs.com +isawuhan.com +isay365.com +isay365.hk +isay365.net +isay365.org +isayabc.com +isbdai.org +iscanchina.com +isd.com +isdox.com +isdpp.com +iseacat.com +iseafood.shop +isealsuite.com +isecsp.com +iseedog.com +iseekids.com +isellerpal.com +isenruan.com +iseoku.com +isf.ink +isfashion.com +isfdz.com +isfirst.net +isgo.com +ish168.com +ishaanxi.com +ishaibiao.com +ishala.com +ishang.net +ishanghome.com +ishangman.com +ishangtong.com +ishangu.com +ishanjian.com +ishansong.com +ishaohuang.com +isharepc.com +isheely.com +isheji.com +isheji5.com +ishell.cc +ishenbao.com +ishengxue.com +ishenping.com +ishenyou.com +ishijing.com +ishipoffshore.com +ishouhong.com +ishoujizhuan.com +ishouka.com +ishouping.com +ishowchina.com +ishowx.com +ishubao.org +ishugui.com +ishuirong.com +ishuiyun.com +ishumei.com +ishuocha.com +ishuqi.com +ishuqi.net +ishuquge.com +ishuquge.la +ishuquge.org +ishuw.com +isi-gf.com +isiabio.com +isign.ren +isigqno.com +isigu.com +isilent.me +isilicontech.com +isiluke.net +isiluke.org +isilvermaterials.com +isimcere.com +isinosig.com +isixiang.com +isixue.com +isjike.com +iskryou.com +isky000.com +iskyjoy.com +iskyone.com +iskysoft.com +islandren.com +isli.cc +islide.cc +isluo.com +ismartgo.com +ismarthealth.com +ismartware.com +ismdeep.com +isme.pub +ismisv.com +ismsms.org +ismx8.com +isnnapp.com +isnsz.com +iso-est.com +iso-iso9000.com +iso2004.com +iso37001rz.com +iso9001rz.com +isobar.tech +isocgw.net +isoftstone.com +isogx.com +isolves.com +isong520.com +isongcontrol.com +isoqh.com +isorange.com +isorenzheng.org +isosh.com +isotoo.com +isoucai.com +isoudy.com +isoyes.com +isoying.com +isoyu.com +isozhijia.com +isp.cx +ispcache.net +ispecial.xyz +ispqcloud.com +isrcb.com +isres.com +iss-ms.com +isscloud.com +issconline.com +issedu365.com +issjj.com +issks.com +ist-zl.com +istcw.com +istoreos.com +istpei.com +istrongcloud.com +istrongcloud.net +istylepdf.com +isuanyun.com +isudaji.com +isuike.com +isummi.com +isun.org +isunon.com +isunton.com +isurecloud.net +isuzhou.me +isv-tech.com +isvee.com +isvjcloud.com +isvjd.com +isvup.com +iswbm.com +isweek.com +iswifting.com +iswweb.com +isxtv.com +isyour.love +it-bound.com +it007.com +it0772.net +it120.cc +it165.net +it168.com +it2021.com +it2168.com +it224.com +it322.com +it376.com +it399.com +it478.com +it525.com +it528.com +it578.com +it610.com +it666.com +it689.com +it707.com +it7t.com +it8.com +it8g.com +it918.com +it985.com +it9g.com +ita-alliance.com +itab.link +itacademy.download.prss.microsoft.com +itacademyuat.download.prss.microsoft.com +itaconicacid.com +itaic.org +itailai.com +itaiping.com +itakeeasy.com +itakutf.com +italentclc.com +italyvisacenterd.com +itamt.com +itangbole.com +itangyuan.com +itanlian.com +itany.com +itany.org +itanzi.com +itao.com +itaoke.org +itaokecms.com +itaored.com +itaotuo.com +itasci.com +itav-gz.com +itayao.com +itbaizhan.com +itbegin.com +itblw.com +itboth.com +itbour.com +itboy.net +itbug.shop +itbulo.com +itbulu.com +itbuy.com +itbyte.net +itc.vip +itcdlf.com +itceo.com +itchaguan.com +itcm.com +itcn.cc +itcodemonkey.com +itcpn.net +itcqf.org +itczh.com +itdabao.com +itdai.com +itdayang.com +itddo2page.com +itdevnow.com +itdks.com +itdog-dns.com +itdog.com +itdog.plus +itdoisp.com +itdoor.net +itdos.com +itdos.net +itdp-china.org +iteam-dress.com +iteblog.com +itechate.com +itedou.com +iteer.net +itek-training.com +itelecloud.com +itensoft.com +iter168.com +itest.info +itetc.org +itexamprep.com +iteye.com +itfanr.cc +itfaster.com +itfeed.com +itfenghui.com +itfly.net +itfox.net +itfsw.com +itfw5.com +itgd.net +itgeeker.net +itgege.com +itgemini.net +itgochina.com +itgoodboy.com +itgsa.com +ithard.com +itheat.com +itheima.com +itheima.net +ithenticatecn.com +ithey.com +ithlj.com +ithome.com +ithome.net +ithor.com +ithor.net +ithothub.com +ithov.com +ithuangw.com +itiankong.com +itiankong.net +itianliao.com +itiexue.net +itigergrowth.com +itigergrowtha.com +itigerup.com +itilxf.com +itilzj.com +itimotor.com +itingwa.com +itjoy.net +itjspx.com +itjuzi.com +itkuku.com +itlic.com +itlog.vip +itlu.org +itlz.net +itma.org +itmakes.com +itmanager.club +itmanbu.com +itmind.net +itmoocs.com +itmop.com +itmuch.com +itmuke.com +itmyhome.com +itnavs.com +itnb.cc +itnec.org +itnihao.com +itnxs.com +itoec.org +itoegd.com +itogame.com +itoka.com +itokit.com +itokoo.com +itongcheng.cc +itonghui.com +itonglian.com +itongzhi.com +itopcoupon.com +itopers.com +itophis.com +itopplay.com +itopsdk.com +itotii.com +itouchchina.com +itougu.com +itoumi.com +itoutiao.co +itoutiaoimg.com +itoutiaoliving.com +itoutiaostatic.com +itoutiaovod.com +itower-soft.com +itoyfx.com +itpon.com +itpow.com +itptg.com +itpub.net +itpux.com +itpwd.com +itqaq.com +itrace.cc +itrackstar.com +itredu.com +itrid.com +itrip.com +itripsh.com +itrolexshop.com +itruelife.com +itruke.com +itrus.com +itruscloud.com +itrusign.com +itry.com +its114.com +itsapu.com +itsdz.com +itshai.com +itshubao.com +itsiwei.com +itsk.com +itslaw.com +itsmephoto.net +itsoku.com +itsto.com +itsun.com +itsvse.com +ittellyou.com +ittft.com +ittime.com +itto100.com +ittribalwo.com +ituad.com +ituchong.com +ituite.com +ituopeng.com +iturco.com +itutu.tv +ituu.net +ituun.com +ituut.com +itv.video +itvcn.com +itvssp.com +itwanger.com +itwlw.com +itwork.club +itwsms.com +itxe.net +itxia.club +itxp365.com +itxst.com +itxtbook.com +itxueyuan.com +ityears.com +ityg.com +itying.com +ityizu.com +itylq.com +ityouknow.com +ityxb.com +itzhai.com +itzhengshu.com +itzhimei.com +itzhp.com +itzjj.com +itzm.com +itzmx.com +itzmx.net +iu18.com +iu95522.com +iuban.com +iucars.com +iucdn.com +iuctrip.com +iufida.com +iuhtg8.com +iuinns.com +iuiu.site +iujkegbpo.xyz +iujkm.com +iuktb.com +iumemo.com +iuni.com +iunv.com +iuoooo.com +iusersurvey.com +iusertracker.com +iusmob.com +iuynfg.com +iv06.com +iv2i.com +iva-schmetz.com +ivali.com +ivanli.cc +ivaoqph.com +ivban.com +ivcheng.com +ivdchina.org +ivdys.com +ivemusic.net +iventoy.com +iverycloud.com +ivfchina.net +ivfdhc.com +ivfuture.com +ivideostar.com +iviewui.com +ivinkon.com +ivipi.com +ivips.site +ivistang.com +ivixivi.com +ivknow.com +ivolces.com +ivon.work +ivqamtkr.com +ivrwan.com +ivsky.com +ivu4e.com +ivvajob.com +ivweb.io +ivwen.com +ivxiaoyuan.com +ivy-school.org +ivybaby.me +ivydad.com +ivykit.com +ivypha.com +ivypub.org +ivyschools.com +ivysci.com +ivysun.net +ivywing.me +iwala.net +iwan4399.com +iwan78.com +iwanbei.com +iwanboy.com +iwangding.com +iwangnan.com +iwanoutdoor.com +iwanshow.com +iwanws.com +iwapan.com +iwatani-gz.com +iwatch365.com +iwatertech.com +iway-tech.com +iwcoo.com +iwebad.com +iwebchoice.com +iwecan.net +iwecxafv.com +iweek.ly +iweekapi.com +iweidu.net +iweixiu120.com +iweju.com +iwellen.com +iwen1.com +iwencai.com +iwenchuan.com +iwenson.com +iwewin.net +iwgame.com +iwhalecloud.com +iwhopro.com +iwhqmk.com +iwhr.com +iwhr.org +iwiki.com +iwin10.net +iwingchina.com +iwiscloud.com +iwishwed.com +iwith-smart.com +iwithu.net +iwjw.com +iwmmob.com +iwncomm.com +iwooji.com +iwopop.com +iwordnet.com +iwordshow.com +iwosai.com +iwpai.com +iwshang.com +iwte-expo.com +iwteexpo.com +iwuchen.com +iwurexs.info +iwurexs.net +iwurexs.org +iwuyou189.com +iwwwwwi.com +iwxapi.com +iwyvi.com +iwzbz.com +iwztc.com +iwzwh.com +iwzwy.com +ix-edu.com +ixbk.fun +ixbk.net +ixbren.net +ixdc.org +ixdzs.com +ixfc.net +ixgvideo.com +ixianlai.com +ixiaochengxu.cc +ixiaoma.com +ixiatxt.com +ixiede.com +ixigua.com +ixiguavideo.com +ixilou.com +iximo.com +ixingfei.com +ixinglu.com +ixingmei.com +ixingpan.com +ixingyan.com +ixinqing.com +ixintu.com +ixinwei.com +ixinwenjie.com +ixinwu.com +ixinyou.com +ixiqi.com +ixiumei.com +ixiupet.com +ixiway.com +ixizang.com +ixmtx.com +ixmu.net +ixpsge.com +ixs.la +ixsz.com +ixuanquge.com +ixuanshu.net +ixuenong.com +ixueshu.com +ixueyi.com +ixueyi.net +ixunke.com +ixxzx.com +ixy68.com +ixywy.com +ixzgkzps.com +ixzzcgl.com +iy-cd.com +iyamusic.com +iyangxi.com +iyaou.com +iyatt.com +iyawoqu.com +iyaxi.com +iyaxin.com +iyaya.com +iyaya.info +iyb.tm +iybtv.com +iycsky.com +iydsj.com +iydu.net +iyeeda.com +iyemao.cc +iyenei.com +iyeren.com +iyiji.com +iyincaishijiao.com +iyingdi.com +iyingji.com +iyint.com +iyiou.com +iyiqi.com +iyishengyuan.com +iyitu.com +iyiyu.com +iymark.com +iyocloud.com +iyoimar.com +iyong.com +iyongpdf.com +iyooread.com +iyoou.com +iyoucai.com +iyoudui.com +iyouhun.com +iyoujia.com +iyoujiao.net +iyouke.com +iyoule.com +iyouman.com +iyouqian.com +iyouxia.com +iyouxin.com +iyouxun.com +iyruan.com +iysj.com +iytc.net +iytcdn.com +iyuan.ltd +iyuanpei.cc +iyue.pub +iyuedan.com +iyuedian.com +iyuezhang.net +iyun.com +iyunbao.com +iyunbiao.com +iyunche.com +iyunmai.com +iyunmu.com +iyunnan.travel +iyunshu.com +iyunv.com +iyunxh.com +iyunxiao.com +iyunyue.com +iyunzk.com +iyuren.com +iyuxiyang.com +iyxing.com +iyxku.com +iyyin.com +iyz168.com +izacholsm.com +izaodao.com +izattime.qcomgeo2.com +izazamall.com +izb.pub +izdatatech.com +izenith.co +izestchina.com +izetvetv.com +izgfu.com +izhailong.com +izhanchi.com +izhangan.com +izhangchu.com +izhangheng.com +izhaohe.com +izhaoo.com +izhaowo.com +izhenxin.com +izhihuicheng.net +izhihuo.com +izhikang.com +izhiliao.com +izhiqun.com +izhishi.com +izhixiu.com +izhuanfa.com +izhuce.com +izhuose.com +izhuyue.com +izihun.com +iziyo.com +izjj.com +izmzg.com +izobrt.com +izpan.com +izpec.com +izqdn.com +izstz.com +izsvip.com +izt8.com +iztigcpk.com +izto.com +iztwp.com +iztzq.com +izuche.com +izuchebao.com +izuchecdn.com +izuciw.com +izuichun.com +izuiyou.com +izumicn.com +izywang.com +izyz.org +izz.cc +j-dun.com +j-gsexpress.com +j-h-k.com +j-smu.com +j-techcnc.com +j-test.com +j-ui.com +j03og.app +j0g0.com +j1000plan.org +j1998.com +j1j5q683cj.world +j2822.com +j2ee.cc +j2up.com +j3cx.com +j43439.com +j4lpr.com +j5.cc +j5k6.com +j66.net +j6n29.com +j8.net +j881p924q2.com +j8j9.com +j95a.com +j99h8.com +j9pic.com +ja-cloud.com +jaadee.com +jaadee.net +jabansk-auymon.com +jabizb.com +jabpark.com +jabrehoo.com +jacheng.com +jackeylea.com +jackon.me +jackxiang.com +jacky-blog.com +jackyang.me +jackytong.com +jackyyf.com +jackzhu.com +jacoll.com +jacxw.com +jadeclass.com +jademond.net +jadetowerccrc.com +jadewd.com +jadyf.com +jaeapp.com +jaebanke-jocelyou.com +jaebanke-nochujapazsn20.com +jaebanke-nochujapazsn5.com +jaecdn.com +jaedu.com +jaeger-hello.com +jaeosc.com +jaf-china.com +jafeney.com +jafie.org +jafron.com +jafronclub.com +jafroninternational.com +jagjj.com +jaguar-guangdong.com +jaifang.com +jaja123.com +jaka.com +jakabiotech.com +jakeai.com +jakehu.me +jalaa57.cc +jalorsoft.com +jamalube.net +jamanetwork.com +jamcz.com +jamidol.com +jamms.org +jammyfm.com +jampotgames.com +janbao.net +jandan.com +jandan.net +jane7.com +janezhang.com +janezt.com +jangho.com +jangyuanzhao.com +janpn.com +janrain.biz +janrainservices.com +jansonco.com +japanhr.com +japansoufun.com +jarczpw.com +jarencai.com +jarhu.com +jarods.org +jarvisw.com +jasangroup.com +jasbasnkilonau6.com +jasminer.com +jasolar.com +jason-z.com +jason5.xyz +jasongj.com +jasongzy.com +jasonsemicon.com +jasonwatches.com +jasonzk.com +jasperxu.com +jasuoenergy.net +jatcochina.com +java-er.com +java.com +java1234.com +java2000.net +javabikes.com +javaboy.org +javacui.com +javaer.xyz +javaeye.com +javamilk.org +javanav.com +javascriptcn.com +javatang.com +javawind.net +javaxxz.com +javazhiyin.com +javazx.com +javbuy.xyz +javier.io +jawouue.com +jaxcx.com +jay.tg +jaya.cc +jayce.icu +jayfc.com +jayfu.tk +jayjw.com +jayxhj.com +jaz581.com +jazlxs.com +jazzyear.com +jb100.com +jb1000.com +jb51.com +jb51.net +jbaier023.com +jbaobao.com +jbb.one +jbbzcorp.com +jbcz.tv +jbddoors.com +jbdhome.com +jbdown.com +jbdown.net +jbedu.net +jbelf.com +jbepharm.com +jbers.com +jbiev.com +jbjc.org +jbjdgroup.com +jbjw.net +jbknx.com +jblogistics.com +jbote.com +jbpmhk.com +jbpzs.com +jbryun.com +jbs-kj.com +jbsmartcity.com +jbsx88.com +jbt.ink +jbtlj.com +jbtxy.net +jbwave.com +jbwtm.com +jbxy.com +jbyy120.com +jbzj.com +jbzpw.com +jbzwread.com +jbzyk.com +jbzyw.com +jc-ai.com +jc-dl.net +jc-hr.com +jc-pcba.com +jc-saas.com +jc0531.com +jc170.com +jc315.com +jc35.com +jc56.com +jc615cezcq.world +jc808.com +jc85.com +jc88.net +jc899.com +jca-china.org +jcancer.org +jcashore.com +jcbjbcak.com +jcbmt.com +jcbq.net +jccchina.com +jcceram.com +jccinema.com +jccjtwl.com +jccmn.com +jccpay.com +jccsoc.com +jccug.com +jcdd.com +jcebid.com +jcecom.com +jcedu.org +jcetglobal.com +jcex.com +jcf94.com +jcgcn.com +jcgcw.com +jchat.io +jchl.com +jchla.com +jchouse.org +jchunuo.com +jchxmc.com +jcjjwx.com +jckjsc.com +jcku.com +jclab.net +jclegend.com +jcloud-cache.com +jcloud-cache.net +jcloud-cdn.com +jcloud-live.com +jcloud-oss.com +jcloud.com +jcloudcache.com +jcloudcache.net +jcloudcs.com +jclouddn.com +jclouddns.com +jclouddns.net +jcloudec.com +jcloudedge.com +jcloudedge.net +jcloudgslb.com +jcloudgslb.net +jcloudimg.com +jcloudimg.net +jcloudlb.com +jcloudlb.net +jcloudlive.com +jcloudlv.com +jcloudoss.com +jcloudresolve.com +jcloudresolve.net +jcloudss.com +jcloudstatic.com +jcloudstatic.net +jcloudvideo.com +jcloudvideo.net +jcloudwaf.com +jcloudwaftest.com +jcloudwaftest.net +jclps.com +jcmeh.com +jcmob.net +jcnano.com +jcnk120.com +jcno.net +jcnqqnf.com +jcodecraeer.com +jcorv.org +jcpeixun.com +jcpesz.com +jcqzw.com +jcrb.com +jcrcw.com +jcrgyy.com +jcscp.org +jcsfs.com +jcsjt.com +jcsrsj.com +jcssolar.com +jcsy66.com +jcszhtc.com +jctmj.net +jctrans-shantou.com +jctrans.com +jcumbrella.com +jcvba.com +jcwgk.com +jcwgo.com +jcwiki.net +jcwjdg.com +jcwljt.com +jcwxiao.com +jcxzlsgs.com +jcyad.com +jcyai.com +jcyes.com +jcys120.com +jcys12366.com +jcyspt.com +jcyx2019.com +jcyxds.com +jczb.vip +jczc.vip +jczh100.com +jczhijia.com +jczhiyao.com +jcznzb.com +jd-88.com +jd-app.com +jd-bbs.com +jd-credit.com +jd-df.com +jd-ex.com +jd-ex.net +jd-fm.com +jd-hospital.com +jd-link.com +jd-sprot-eur.shop +jd-zd.com +jd.co +jd.co.th +jd.com +jd.hk +jd.id +jd.ru +jd.shop +jd100.com +jd120.com +jd360.hk +jd37.com +jd5.com +jdair.net +jdallianz.com +jdapi.com +jdb-ware.com +jdb100.com +jdbbs.com +jdbbx.com +jdbchina.com +jdbhw.com +jdbjba.com +jdbox.xyz +jdbpcb.com +jdburl.com +jdbusiness.com +jdcache.com +jdcaipu.com +jdcapital.com +jdcdn.com +jdcloud-api.com +jdcloud-api.net +jdcloud-edu.com +jdcloud-elite.com +jdcloud-elive.com +jdcloud-livebuy.com +jdcloud-mail.com +jdcloud-openapi.com +jdcloud-oss.com +jdcloud-scdn.net +jdcloud-scdn.tech +jdcloud-scdndns.com +jdcloud-yd.com +jdcloud.com +jdcloudai.solutions +jdcloudcache.com +jdcloudcache.net +jdcloudcdn.com +jdcloudcdn.net +jdcloudcs.com +jdclouddns.com +jdclouddns.net +jdcloudedge.com +jdcloudedge.net +jdcloudlb.com +jdcloudlb.net +jdcloudlive.com +jdcloudlive.net +jdcloudnaming.net +jdcloudresolve.com +jdcloudresolve.net +jdcloudshop.com +jdcloudsite.com +jdcloudstatic.com +jdcloudstatic.net +jdcloudstatus.com +jdcloudstatus.net +jdcloudvideo.com +jdcloudvideo.net +jdcloudwaf.com +jdcmmc.com +jdcmoly.com +jdcontent.com +jdcq.net +jdcsww.com +jdctky.com +jdd-global.com +jdd-hub.com +jddaojia.shop +jddapeigou.com +jdddata.com +jddglobal.com +jddj.com +jddmoto.com +jddtv.com +jddyl.com +jdedu.net +jdemall.com +jdface.com +jdfair.com +jdfcloud.com +jdfeijing.com +jdfinance.com +jdfjx.com +jdfmgt.com +jdfryl.com +jdfschool.com +jdfw1.com +jdfybjy.com +jdfzm.com +jdgogo.com +jdgslb.com +jdgslb.net +jdgzf.net +jdh.com +jdh.healthcare +jdhmediajd.com +jdhospital.com +jdhuafeng.com +jdhyplay.com +jdianfei.com +jdindustry.com +jdis.org +jdiy.club +jdjgq.com +jdjingmai.com +jdjinrong.com +jdjob88.com +jdjrdns.com +jdjt.com +jdjygold.com +jdkcb.com +jdkjxy.com +jdl.com +jdl8.com +jdlgw.com +jdlhb.com +jdlhpt.com +jdlingyu.com +jdlingyu.net +jdmwk.com +jdmy.com +jdnews.net +jdon.com +jdpay.com +jdpaydns.com +jdplay.com +jdpta.com +jdpz44.com +jdreader.net +jdrns.com +jdrpr.com +jdrq.net +jds-china.com +jdsafe.com +jdsha.com +jdsjy.com +jdsmartkf.com +jdsry.com +jdss.cc +jdsyjc.com +jdt-precision.com +jdtiot.com +jdtjy.com +jdtxgc.com +jdunion.com +jduoduo.com +jdvisa.com +jdw001.com +jdw2.com +jdwdc.com +jdweixiao.com +jdwgame.com +jdwl.com +jdwmfj.com +jdworldwide.com +jdwxwz.com +jdwxzp.com +jdx.com +jdxc.net +jdxfw.com +jdxlt.com +jdxs.com +jdxsr.com +jdxyydf.com +jdxzz.com +jdy.com +jdycdn.com +jdydevelop.com +jdyfy.com +jdylb.com +jdyou.com +jdypf.com +jdyyeb.com +jdzdeyy.com +jdzeduyun.com +jdzj.com +jdzjw.com +jdzkw.com +jdzmc.com +jdzol.com +jdzol.net +jdzrcw.com +jdzs.com +jdzwang.com +jeacar.com +jean.cd +jeanphy.online +jeansc.com +jeanssalon.com +jeanswest.com +jeawin.com +jeawincdn.com +jechobio.com +jectronic.com +jedi-games.com +jedoo.com +jee-cn.com +jeeanlean.com +jeecg.com +jeecg.org +jeecms.com +jeee.ltd +jeejen.com +jeepay.com +jeepay.vip +jeeplus.org +jeequan.com +jeerun.com +jeesci.com +jeeseen.com +jeesite.com +jeewong.com +jeeyaa.com +jeeyee.com +jeeyor.com +jefen.com +jeffdingzone.com +jeffjade.com +jeffreyitstudio.com +jeflon.com +jegotrip.com +jehudf.com +jekeen.com +jelleybrown.com +jellow.club +jellow.site +jellymoo.com +jellythink.com +jemincare.com +jemoic.com +jengcloud.com +jenno-cn.com +jenomc.com +jeom.org +jeongen.com +jeoshi.com +jepekale.com +jereh-gas.com +jereh-network.com +jereh.com +jerei.com +jeremycn.com +jerpx.com +jerryzou.com +jersey01.com +jescard.com +jesdatools.com +jesie.org +jesiro.com +jesoncom.com +jesselauristonlivermore.com +jesselivermore.com +jestq.com +jet-ego.com +jet-logistics.com +jet-ok.com +jetechtool.com +jetgroup-cn.com +jetgroup-nb.com +jethoo.com +jethro.fun +jetionservice.com +jetlogistic.com +jetmobo.com +jetneed.com +jetsum.com +jetsum.net +jeulover.com +jeuronghotels.com +jevolpu.com +jewellery.gold +jewellworld.com +jewelryseeds.com +jewelryshanghai.com +jexus.org +jeyi.com +jeywatch.com +jf-biaotw.com +jf-motor.com +jf-r.com +jf1898.com +jf1969.com +jf258.com +jf900.com +jf9p.com +jfagroup.com +jfbcb.com +jfbuilding.com +jfchinese.com +jfcjt.com +jfcoo.com +jfdaily.com +jfedu.net +jfgjwl.com +jfgou.com +jfh.com +jfhzfsn.com +jfinal.com +jfinfo.com +jfj3419.com +jfjt.cc +jflparking.com +jflswl.com +jfpal.com +jfq.com +jfrogchina.com +jfrschool.com +jfsc.com +jfshare.com +jfstatic.com +jftech.com +jftianshancn.com +jfwb.com +jfwypay.com +jfxiaopaoqi.com +jfydgame.com +jfyf.cc +jfyiyao.com +jfyskw.com +jfz.com +jfzhcx.com +jfzhiyao.com +jg058.com +jg1060.com +jg1994.com +jg91.com +jgcarbide.com +jgchat.net +jgcjjt.com +jgdq.org +jgdun.com +jgdx.com +jgew3d.com +jgfarm.com +jgg.hk +jgg09.com +jggame.net +jghstar.com +jgjapp.com +jglh.com +jglm.cc +jgs-ds.com +jgscct.com +jgsdaily.com +jgsemicon.com +jgstour.com +jgsxfw.com +jgtc315.com +jguanjia.com +jgums.com +jguo.com +jgxb120.com +jgxzy.com +jgy.com +jgyljt.com +jgyun.net +jgzx.org +jgzyw.com +jh-dzcl.com +jh-sh.com +jh-trace.com +jh-uav.com +jh0516.com +jh3737.com +jh3j.com +jh597.com +jh5l.com +jh8k.com +jh96095.com +jhak.com +jhaoyou.com +jhcb.net +jhcfz.com +jhcheku.com +jhcms.com +jhconba.com +jhctbank.com +jhddsz.com +jhdmro.com +jhdpower.com +jhdxjk.com +jhenten.com +jhfl.com +jhforever.com +jhfsata.com +jhgolfcarts.com +jhgroup525.com +jhgtgb.com +jhgykt.com +jhhospital.com +jhhygl.com +jhi.cc +jhjt.xyz +jhjunda.com +jhjy.net +jhkao.com +jhkuajing.com +jhltsl.com +jhm2012.com +jhmnew.com +jhmwo.com +jhnsh.com +jhnsyh.com +jhonge.net +jhonse.com +jhotel-shanghai.com +jhpm.cc +jhqrmyy.com +jhqshfly.com +jhrcbank.com +jhrcsc.com +jhrcw.com +jhsairport.com +jhsc201ddd211svds.com +jhscl.net +jhscm.com +jhscrm.com +jhsddjd.com +jhsjttz.com +jhspa6.com +jhszyy.com +jhtmsf.com +jhu.edu +jhuishou.com +jhvsr.com +jhwaimai.com +jhwdp.com +jhwvjjw.com +jhxcms.com +jhxjd.com +jhxl.org +jhxms.com +jhxrmyy.com +jhxzlsgs.com +jhydns01.com +jhydns05.com +jhygame.com +jhyongyou.com +jhypcy.com +jhytech.com +jhyusqo.com +jhyz.net +jhzdhjt.com +jhzhizao.com +jhzhkj.com +jhzhuji.com +jhzoo.com +ji-pai.com +ji-zhun.com +ji.ci +ji7.com +jia.com +jia12.com +jia300.com +jia360.com +jia400.com +jia86.cc +jiaads.com +jiaaohuanbao.com +jiaapps.com +jiabaiwang.net +jiabangcnc.com +jiabaoyuanlin.com +jiabasha.com +jiaben.com +jiaboojc.com +jiacai001.com +jiacaitc.com +jiachangshichutieqi.com +jiacheng88.com +jiachong.com +jiadafoods.com +jiadapaper.com +jiadeqy.com +jiadingjiaxiao.com +jiadingqiang.com +jiadounet.com +jiadule.com +jiaduobao.ru +jiae.com +jiaenderen.com +jiaenhospital.com +jiafang168.com +jiafenqi.com +jiafu68.com +jiafuda.com +jiagedan.com +jiagela.com +jiagle.com +jiagoo.com +jiagoo.net +jiagouyun.com +jiaguanlaw.com +jiaguboshi.com +jiaguhome.com +jiagulun.com +jiagumen.com +jiagumima.com +jiaguowenhua.com +jiaguwenxf.com +jiahecare.com +jiaheu.com +jiahewushe.com +jiahua-sz.com +jiahuacinema.com +jiahuaming.com +jiahui.com +jiahuism.com +jiain.net +jiaji.com +jiaji28.net +jiajia-china.com +jiajia.tv +jiajiagroup.com +jiajiakt.com +jiajiangcake.com +jiajiao114.com +jiajiao400.com +jiajiaoban.com +jiajimao.com +jiajingink.com +jiajiyp.com +jiaju.cc +jiaju.com +jiajuimg.com +jiajuketang.com +jiajumi.com +jiajurenwu.com +jiajuservice.com +jiajuwo.com +jiajuxialiang.org +jiajuzhuliu.com +jiakao.com +jiakaobaodian.com +jiakaodashi.com +jiakaokemuyi.com +jiakelai.com +jiakexs.com +jialanling.com +jialaxin.cc +jialebao.cc +jialecc.com +jialei168.com +jialez.com +jialiangad.com +jialianzg.com +jialinep.com +jialiwood.com +jialiyoukuang8.com +jialongsports.com +jialvzc.com +jiamei123.com +jiameidental.com +jiameigj.com +jiameng.com +jiamengbang.net +jiamengfei.com +jiamens.com +jiami110.com +jiamiantech.com +jiaminghi.com +jiamingwenhua.com +jiamisoft.com +jian-jie.com +jian.net +jian27.com +jianada-qianzheng.com +jianae.com +jianai.love +jianai360.com +jianavi.com +jianayangzhiguo01.com +jianbaizhan.com +jianbangchem.com +jianbaolife.com +jianbihua.com +jianbihua.org +jianbihua360.com +jianbing.com +jiancai.com +jiancaijia.com +jiancaik.com +jiancenj.com +jiancent.com +jiancepai.com +jiancepaper.com +jianchacha.com +jianchiapp.com +jianchihu.net +jiandaima.com +jiandan.net +jiandantianqi.com +jiandanxinli.com +jiandaopay.com +jiandaoyun.com +jiandati.com +jiandiao.com +jianeryi.com +jianfc.com +jianfei.com +jianfei.net +jianfeiba.com +jianfeibaike.com +jianfeidaren.com +jianfengstudio.com +jiang11.com +jiang7.com +jiangbeijituan.com +jiangbeimach.com +jiangbeishuicheng.com +jiangbeiyiyuan.com +jiangbeiyiyuan.net +jiangchaochina.com +jiangcp.com +jiangduoduo.com +jiangguimei.asia +jiangguo.net +jianghaiqu.net +jianghaosm.com +jianghehuagong.com +jianghuamem.com +jianghui.xyz +jiangidea.com +jiangjiuren.com +jiangjizhong.com +jiangkk.com +jianglinminingindustry.com +jiangmama.net +jiangmike.com +jiangmin.com +jiangnan-group.com +jiangnanmarket.org +jiangningwater.com +jiangongdata.com +jiangongw.com +jiangpaipinpai.com +jiangpinjiangxin.com +jiangqiaomuye.com +jiangque.com +jiangruyi.com +jiangshankeji.com +jiangshanlihong.com +jiangshi.org +jiangshi99.com +jiangsudanzhao.com +jiangsuedu.net +jiangsufilm.com +jiangsufootball.org +jiangsugqt.org +jiangsugwy.org +jiangsukj.com +jiangsulvhe.com +jiangsumobile.com +jiangsurc.com +jiangsurhi.com +jiangsusx.com +jiangsuzhongpin.com +jiangtai.com +jiangtuoedu.com +jianguo.tv +jianguopuzi.com +jianguoyun.com +jiangweishan.com +jiangxiatech.com +jiangxinkeji.club +jiangxiol.com +jiangxirc.com +jiangxiwater.com +jiangxiwuliu.com +jiangxueqiao.com +jiangyan.tv +jiangyoushang.com +jiangyu.org +jiangzheba.com +jiangzidushu.com +jiangzikanshu.com +jiangziyuedu.com +jiangzuoku.net +jianhangcaifu.com +jianhaobao.com +jianhuagroup.com +jianhuasheng.com +jianhuavalve.com +jianhucheng.com +jianhui.org +jianhuw.com +jianianle.com +jianidc.com +jianjian.tv +jianjiaobuluo.com +jianjutec.com +jiankang123.net +jiankang13.com +jiankanghebei.com +jiankangsn.com +jiankangyouyi.com +jianke-fangzhou.com +jianke.cc +jianke.com +jianke.net +jiankong.com +jiankunchina.com +jianlc.com +jianlc.net +jianli-sky.com +jianli.com +jianli88.com +jianliao.com +jianliben.com +jianliduo.com +jianlimoban-ziyuan.com +jianlisheji.com +jianliw.com +jianlixiu.com +jianliyuan.com +jianloubao.com +jianlow.com +jianlu365.com +jianmaidi.com +jianmao.net +jianmeicao.com +jianmeng.net +jianmite.com +jianmuhub.com +jianniang.com +jianpaimeiye.com +jianpeicn.com +jianpian.info +jianpu.net +jianpu6.com +jianpu8.com +jianpu99.net +jianq.com +jianqiaochina.com +jianqimao.com +jianqiyl.com +jianran360.com +jianshe99.com +jiansheku.com +jianshen8.com +jianshenmi.com +jianshiduo.com +jianshihui.net +jianshionline.com +jianshu.com +jianshu.io +jianshu.tech +jianshuapi.com +jianshukeji.com +jiansuji001.com +jiansujihm.com +jiantaokj.com +jiantuku.com +jianwang360.com +jianweidata.com +jianweitv.com +jianwenapp.com +jianwulian.com +jianxi-materials.com +jianxinchemical.com +jianxinyun.com +jianxiyasi.com +jianyanjia.com +jianyechina.com +jianyefans.com +jianyewx.com +jianying.com +jianyixinli.com +jianyu360.com +jianyujiasu.com +jianyuweb.com +jianyv.com +jianzeppt.com +jianzhan110.com +jianzhan580.com +jianzhanbao.net +jianzhangongsi.com +jianzhe.com +jianzhi8.com +jianzhian.com +jianzhiba.net +jianzhibao.com +jianzhidaxue.com +jianzhidou.com +jianzhikeji.com +jianzhikeji.net +jianzhimao.com +jianzhiwangzhan.com +jianzhiweike.net +jianzhiyixin.com +jianzhong-edu.com +jianzhusheying.com +jiao15.com +jiaoben.net +jiaobu365.com +jiaobuser.com +jiaochengzhijia.com +jiaoda306.com +jiaodian.pub +jiaodj.com +jiaodong.net +jiaodonghr.com +jiaofei123.com +jiaohuilian.com +jiaohuiyun.com +jiaohusheji.net +jiaojiang.com +jiaokaitech.com +jiaoko.com +jiaoliuqu.com +jiaomai.com +jiaonan.net +jiaonan.tv +jiaonizuocai.com +jiaoping.com +jiaoshirencai.com +jiaoshizhaopin.net +jiaoshizhuye.com +jiaoshoubang.com +jiaoshouhuayuan.com +jiaotu.men +jiaoya.com +jiaoyanyun.com +jiaoyf.com +jiaoyibao.com +jiaoyimao.com +jiaoyin.com +jiaoyixia.com +jiaoyizhu.com +jiaoyu361.com +jiaoyu400.com +jiaoyuangroup.com +jiaoyudao.com +jiaoyumao.com +jiaoyundiandongmen.com +jiaoyunw.com +jiaoyuwo.com +jiaoyuzhan.net +jiaozhou.net +jiapin.com +jiapu.tv +jiapuvip.com +jiaqiangban.com +jiaqianglian.com +jiaqing900.com +jiaren.org +jiarenrecycle.com +jiarenvip.com +jiarenzs.com +jiaruitec.com +jiasale.com +jiashejianyan.com +jiashengguangdian.com +jiashida5618.com +jiashiguoji168.com +jiashuangkuaizi.com +jiashuba.com +jiashule.com +jiasou.cc +jiass.cc +jiasu.work +jiasubook.com +jiasucai.com +jiasuhui.com +jiasule.com +jiasule.net +jiasule.org +jiasulian.com +jiataizic.cc +jiataizir.cc +jiatejijin.com +jiatengflycdn.com +jiatongyitu.com +jiatop.com +jiatuhui.com +jiatui.com +jiatushuke.com +jiatx.com +jiawei.com +jiawei.xin +jiawentrans.com +jiawin.com +jiawonongye.com +jiawutech.com +jiawuzhanzheng.org +jiawuzi.com +jiaxianggame.com +jiaxianghudong.com +jiaxiangxm.com +jiaxiao.pub +jiaxiao100.com +jiaxiaozhijia.com +jiaxiaozhilian.com +jiaxichina.net +jiaxincloud.com +jiaxingren.com +jiaxinkg.com +jiaxinxuetang.com +jiaxiweb.com +jiaxuanwl.com +jiaxuejiyin.com +jiaxun.com +jiay.press +jiayans.net +jiayaw.com +jiayi56.com +jiayin618.com +jiayougo.com +jiayoujsq.com +jiayouxueba.com +jiayu.net +jiayu.yoga +jiayuan-ev.com +jiayuan-law.com +jiayuan.com +jiayuanzhang.com +jiayudata.com +jiayue.tech +jiayuehua.com +jiayuhongwedding.com +jiayusx.com +jiazaishanghai.com +jiazhao.com +jiazhao7.com +jiazhaoba.com +jiazhi.online +jiazhichem.com +jiazhoulvke.com +jiazhuang.com +jiazhuang6.com +jiazile.com +jiazuo.cc +jibai.com +jibao.online +jibencaozuo.com +jibi.net +jibing57.com +jibite.fun +jicaibao.com +jicaifund.com +jicaixinke.com +jice.io +jichangbus.com +jichangdaba.com +jiche.com +jicheng.net +jichengzao.net +jichuangke.com +jiclip.com +jicnj.com +jicon.net +jicyun.com +jidacheng.com +jidanpu.com +jidantuoshebei.com +jide.com +jidekan.com +jideos.com +jidi.com +jidian.im +jidiancdn.com +jidianwang.com +jidivr.com +jidiw.com +jidouauto.com +jidubook.com +jidujiao.com +jidujiasu.com +jieanjiaotong.com +jiebai.com +jiebanchuyou.com +jiebaodz.com +jiebaogroup.com +jiebide.xin +jiecang.com +jiecangtubemotors.com +jiechengcehui.com +jiechengcloud.com +jiechikeji.com +jiechuang.com +jiedaibao.gs +jiediankeji.com +jiefadg.com +jiefanglinli.net +jiefu.com +jiefu.net +jiefuku.com +jiegames.com +jiege.pro +jiegeng.com +jiegon.com +jiehua-chem.com +jiehua.com +jiehualv.com +jiehuapharma.com +jiehuigroup.com +jiehun021.com +jiehun027.com +jiejichengshi.com +jiejing.fun +jiekenmould.com +jiekon.com +jiekou.ltd +jielaigroup.com +jieliapp.com +jielibj.com +jieligo.net +jielijs.com +jieling.net +jielong-printing.com +jielong.co +jielong.com +jielongcorp.com +jielongdaquan.com +jielongguanjia.com +jiemaiyang.com +jiemeng.cc +jiemeng.tw +jiemeng8.com +jiement.com +jiemian.com +jiemin.com +jiemo.net +jiemodui.com +jiemoselect.com +jienyl.com +jiepai.net +jiepaids.com +jiepei.com +jieqi.com +jieqian.co +jieqibg.com +jieqinwang.com +jierengz.com +jieri2.com +jierili.com +jieruchaosheng.com +jiese.org +jiesen365.com +jieshangwei.com +jieshengit.com +jieshimt8.com +jieshitong.com +jieshu.me +jieshui8.com +jieshuitech.com +jieshuwang.com +jietu365.com +jietuhb.com +jietuosh.com +jietusoft.com +jieweijt.com +jiewen.run +jiexi.net +jiexitz.com +jiexiuyiyuan.com +jiexunyun.net +jieyang.la +jieyanri.com +jieyigroup.net +jieyitong.net +jieyou.com +jieyou.pro +jieyougame.com +jieyoulai888.com +jieyoutsg.com +jieyue.net +jieyuechina.com +jieyuechina.net +jifang360.com +jifang365.com +jifang369.com +jifenapp.com +jifencity.com +jifenfu.net +jifengkj.com +jifengyun.com +jifenh.com +jifenyi.com +jifenyouhuidui.com +jifenzhi.com +jifugk.com +jifulei.com +jigao616.com +jigaojituan.com +jigecili.com +jiguangdaili.com +jiguangdanci.com +jiguanglan.com +jiguo.com +jiguzuo.com +jihai8.com +jihaoba.com +jihegui.com +jihex.com +jihexian.com +jiheyun.com +jihot.com +jihuachina.com +jihuadyes.com +jihuanshe.com +jihubear.com +jihui88.com +jihujiasuqi.com +jihulab.com +jihuoma.com +jihuoniao.com +jihuoyx.com +jiiaa.com +jiimore.com +jijia.com +jijiaerp.com +jijiagames.com +jijiang5.com +jijiangep.com +jijianzhineng.com +jijiaoyu.com +jijidi.com +jijie168.com +jijigugu.club +jijijijin.com +jijing.site +jijinhao.com +jijitec.com +jijiyouxuan.com +jijuduo.com +jikabao.com +jikaicai.com +jike.city +jike.com +jike.info +jike800.com +jikecdn.com +jikedata.com +jikedingyue.com +jikedog.com +jikefan.com +jikegou.net +jikeiot.cloud +jikejiang.com +jikejiazhuang.com +jikejishu.com +jikeq.com +jiketuchuang.com +jikewan.com +jikexiaojiang.com +jikexiu.com +jikexueyuan.com +jikipedia.com +jikstatic.com +jikuai.work +jilailawyer.com +jilaoshi.com +jiletaotao.com +jili20.com +jiliguala.com +jilingames.com +jilingwy.org +jilinmarathon.com +jilinshuiwu.com +jilinxiangyun.com +jiliuwang.net +jiliyun.com +jilongsw.com +jilu.info +jiluchengshi.com +jiluer.com +jilulijob.com +jiluyu.org +jilvfaka.com +jimagroup.com +jimakj.com +jimay.com +jimei-cn.com +jimeisilk.com +jimeng.com +jimeng.mobi +jimetec.com +jimi168.com +jimicn.com +jimifashion.com +jimihu.com +jimilier.com +jimingbao.com +jimistore.com +jimmoo.com +jimoedu.net +jimu.com +jimubox.com +jimuc.com +jimucake.com +jimujiazx.com +jimuyk.com +jin-huang.net +jin-wang.net +jin-xiang.com +jin-xin.com +jin10.com +jin10x.com +jinan-marathon.com +jinan7.com +jinanfu.net +jinanguanggao.com +jinanhaofang.com +jinanhualian.com +jinankingyue.com +jinanxww.com +jinbangedu.com +jinbaobeiqiming.com +jinbaoidc.com +jinbaonet.com +jinbi-an.com +jinbiaochi.com +jinbiaohui.com +jinbiaojv.com +jinbifun.com +jinbilianmeng.com +jinbitou.net +jinbondt.com +jincaicaiwu.com +jincao.com +jincaocw.com +jincdn.com +jincece.com +jinchanggps.com +jinchanqunale.com +jincheng56dl.com +jinchengdingjs.com +jinchengmf.com +jinchengpharm.com +jinchuang.org +jinchuanrmt.com +jinchutou.com +jincin.com +jindaixx.com +jindaoshangwu.com +jindati.com +jinde-logistics.com +jindianweb.com +jindianyishi.com +jindidata.com +jindidq.com +jinding.cc +jindingfm.com +jindongsoft.com +jindoushiqi.com +jinducw.com +jindun007.net +jindun9.com +jindunfan.com +jindunkeji.com +jinduoduo.net +jinengtisheng.com +jinenrunze.com +jinergy.com +jinerkang.com +jinfan-keji.com +jinfanda.com +jinfangka.com +jinfengcx.com +jinfengpaint.com +jinfengwine.com +jinfh.net +jinfuzi.com +jing-tong.com +jing-xian.com +jingangfuhui.com +jingangjing.com +jingangjing.net +jingankerrycentre.com +jingansicbd.com +jingbantong.com +jingbo.net +jingbotech.com +jingc.com +jingcai360.net +jingcaipaint.com +jingcaituijian.com +jingch.net +jingchang.tv +jingchengban.com +jingchengwl.com +jingchi.net +jingchuhao.com +jingchurc.com +jingdajiance.com +jingdaka.com +jingdapcb.com +jingdata.com +jingdeyx.com +jingdianju.com +jingdianlaoge.com +jingdianxitong.com +jingdiao.com +jingdigital.com +jingdong.com +jingdongdaili.com +jingdongjinrong.com +jingdongyouxuan.com +jingdudai.com +jingdukaoyan.com +jingdw.com +jingge.com +jinggeng.net +jinggon.com +jinggong-auto.com +jinggongvalve.com +jingguan.ai +jinggui.com +jinghaishop.com +jinghandianzi.com +jinghangapps.com +jingheiot.com +jinghesh.net +jinghonggroup.com +jinghongmedical.com +jinghongsh.com +jinghua.com +jinghuans.com +jinghuaqimo.com +jinghudianqi.com +jinghuitang.com +jingjia.net +jingjia.org +jingjia6.com +jingjiamicro.com +jingjiang.com +jingjiasc.com +jingjiawang.com +jingjiayl.com +jingjidaokan.com +jingjie360.com +jingjiezhileng.com +jingjitech.com +jingjiu.com +jingju.com +jingjuok.com +jingjusc.com +jingkaiyuan.com +jingkan.net +jingkaowang.com +jingkebio.com +jingkeleici.com +jingkeyiqi.com +jingkids.com +jingkunagro.com +jinglawyer.com +jinglian88.com +jingliangad.com +jingling.group +jinglingbaoai.com +jinglingbiaozhu.com +jinglingshuju.com +jinglou8.com +jingluemall.com +jingluole.com +jingme.net +jingmedicine.com +jingmeiti.com +jingmen.com +jingmiguangliangg.com +jingmiliangju.com +jingnei.net +jingnengpower.com +jingoal.com +jingos.com +jingpai.com +jingpaidang.com +jingpaihao.com +jingpainet.com +jingpinhui.com +jingpinke.com +jingpt.com +jingqizhitongche.com +jingqueyun.com +jingrongshuan.com +jingruigroup.com +jingsailian.com +jingsh.com +jingshanbus.com +jingshibang.com +jingshibianhuren.com +jingshicd.com +jingshifang.net +jingshistudy.com +jingshizyy.com +jingshun-wl.com +jingshzh.com +jingsocial.com +jingtai-group.com +jingtang.xyz +jingtanggame.com +jingtao58.com +jingtuitui.com +jingtum.com +jingua168.com +jinguanauto.com +jingugroup.net +jinguilvyou.com +jingutrust.com +jingvo.com +jingwacenter.com +jingwah.com +jingwei.link +jingweizhichuang.com +jingwuhui.com +jingwxcx.com +jingxi.com +jingxi.net +jingxiang.work +jingxianglawfirm.com +jingxinad.com +jingxinclass.com +jingyakt.com +jingyanben.com +jingyanbus.com +jingyangzhijia.com +jingyanlib.com +jingyanshu.com +jingyeco.com +jingyeqian.com +jingyi186.com +jingyimetal.com +jingyinb.com +jingyingshenghua.com +jingyingyicheng.com +jingyitech.com +jingyiyiyao.com +jingyougz.com +jingytech.com +jingyuan.com +jingyuelaw.com +jingyuetang.com +jingyunos.com +jingyunyilian.com +jingyuweike.com +jingyuxiaoban.com +jingyuyun.com +jingzhengu.com +jingzhi5.com +jingzhouxw.com +jingzhu-bio.com +jingzhusz.com +jingzong.org +jinhaigroup.com +jinhaihujingqu.com +jinhaisujiao.com +jinhe-energy.com +jinheamc.com +jinher.com +jinheshiye.com +jinhevip.com +jinhongchina.com +jinhonggroup.com +jinhongnl.com +jinhu.me +jinhuapp.com +jinhuatv.com +jinhuawatch.com +jinhuazhe.com +jinhuo.net +jinhusns.com +jinhutour.com +jinianbi.com +jiniance8.com +jinianri.com +jining.com +jiningcoal.com +jiningjj.com +jiniu.work +jiniutech.com +jinjia.com +jinjiang-group.com +jinjiang.com +jinjiang.tv +jinjianghotels.com +jinjianginns.com +jinjiangwater.com +jinjiaomh.com +jinjie.tech +jinjiedu.com +jinjieshengwu.com +jinkaijia.com +jinkan.org +jinkanghospital.com +jinkaoedu.com +jinke.com +jinkedatex.com +jinkeholdings.com +jinkejoy.com +jinkex.com +jinkezhexin.com +jinkongauto.com +jinkopower.com +jinkosolar.com +jinkoubaodian.com +jinkoucaigou.com +jinku.com +jinkunlaw.com +jinlaiba.com +jinlaijinwang.com +jinlangbo.com +jinlanqihua.com +jinlanzuan.com +jinletx.com +jinlianchu.com +jinling.com +jinlingholdings.com +jinlinghotel.com +jinlinghotels.com +jinlingjiajiao.com +jinlishenghuo.com +jinliufu.net +jinliyang.net +jinliyu.cc +jinlonggeishui.com +jinluowater.net +jinluzl.com +jinlvkeji.com +jinlyb.com +jinma-int.com +jinmabrand.com +jinmajia.com +jinmalvyou.com +jinmao-ti.com +jinmao88.com +jinmaodigital.com +jinmaofoundry.com +jinmaopartners.com +jinmaowy.com +jinmaozs.com +jinmeiji.com +jinmenrc.com +jinmi.com +jinming.net +jinmixuetang.com +jinmogame.com +jinmuinfo.com +jinnong.cc +jinpacs.com +jinpai365.com +jinpanlab.com +jinpengecologyhotel.com +jinpin.xyz +jinpu.com +jinpupvc.com +jinqi2023.com +jinqiang.online +jinqiangjc.com +jinqianguan.com +jinqianma.com +jinqiaojob.com +jinqiaopu.com +jinqiexia.com +jinqigroup.com +jinqijian.com +jinqingdz.com +jinqiunc.com +jinqiuzhu.com +jinquanpharm.com +jinqunla.com +jinr.com +jinri.red +jinridiaoyu.com +jinriguanzhu.cc +jinrilife.com +jinriningxiang.com +jinrirm.com +jinrishici.com +jinritemai-inc.com +jinritemai.com +jinritoutiao.com +jinriwushi.com +jinrixing.cc +jinrongbaguanv.com +jinrongchaoshi.com +jinrongdianli.com +jinronghu.com +jinrongren.net +jinrui-tech.com +jinruimedical.com +jinruism.com +jinrunsoft.com +jins-cn.com +jinse.com +jinsebook.com +jinsehuaqin.com +jinsenforestry.com +jinsha120.com +jinshacapital.com +jinshakemei.com +jinshanapi.com +jinshandaolu.com +jinshangdai.com +jinshangji.com +jinshanglawfirm.com +jinshangroup.net +jinshangtechnology.com +jinshanju.com +jinshanmz.com +jinshasitemuseum.com +jinshengceramics.com +jinshengtang.net +jinsheyi.com +jinshi-nj.com +jinshier66.com +jinshileasing.com +jinshisoft.com +jinshitan.com +jinshixun.com +jinshmgw.com +jinshu.org +jinshuai.com +jinshuangding.com +jinshuiyuncai.com +jinshuju.co +jinshuju.com +jinshuju.cool +jinshuju.net +jinshuju.org +jinshujuapp.com +jinshujucdn.com +jinshujufiles.com +jinshuluoshui.com +jinshun.com +jinshuschool.com +jinshutuan.com +jinsiwei.com +jintaiwh.com +jintajx.com +jintanwang.com +jintdev.com +jintelisi.com +jinti.com +jintianjihao.com +jintiankansha.me +jintone.com +jintouep.com +jintouwangdai.com +jintuituiapp88.com +jinwaimai.com +jinweitec.com +jinwucdn.com +jinxiang114.com +jinxianglian.net +jinxidao.com +jinxinqh.com +jinxiu266.com +jinxuliang.com +jinxun.cc +jinyaco.com +jinyafu.com +jinyawei.com +jinyici.com +jinyidun.com +jinyindao.com +jinying.com +jinyinghotels.com +jinyingimage.com +jinyongwang.com +jinyoukai.com +jinyuan.pro +jinyuanbiochem.com +jinyuancopper.com +jinyuangejiaju.com +jinyuanlight.com +jinyunal.com +jinyunjob.com +jinyunweb.com +jinyuzd.cc +jinzhao.me +jinzheled.com +jinzhengjt.com +jinzhidagl.com +jinzhijiance.com +jinzhongbus.com +jinzhou315.com +jinzhou360.com +jinzhougroup.com +jinzhouoffice.com +jinzhucaifu.com +jinzhuoqy.com +jinzjy.com +jinzunjy.com +jioluo.com +jiongcun.com +jiongji.com +jiongtoutiao.com +jiongyaya.com +jiont.com +jionz.com +jiou.me +jiouyun.com +jipd.com +jiping.site +jipinsoft.com +jipinwww.com +jiqid.com +jiqie.com +jiqimao.com +jiqirenku.com +jiqish.com +jiqizhixin.com +jiqrxx.com +jiqw.com +jirehhz.com +jirengu.com +jirenqi.com +jiri10.com +jiri28.com +jirong.com +jirongyunke.net +jirou.com +jisapower.com +jisec.com +jisheyun.com +jishi3.com +jishicloud.com +jishicn.com +jishigou.net +jishigu.com +jishirili.com +jishitailai.com +jishiyuboke.com +jishubai.com +jishuchi.com +jishukong.com +jishulink.com +jishuoshuo.com +jishusongshu.com +jishux.com +jishuzf.com +jisi17.com +jisikaer.com +jissbon.com +jisu-cnd.com +jisu1688.com +jisuanke.com +jisuanla.com +jisuanzt.com +jisuapi.com +jisuchou.com +jisuim.com +jisuimage.com +jisuimg.com +jisujie.com +jisukandian.com +jisunton.com +jisuoffice.com +jisupdf.com +jisupdfeditor.com +jisupdftoword.com +jisupe.com +jisuqiang.com +jisuqiang.net +jisutodo.com +jisutp.com +jisuts.com +jisutui.vip +jisuwebapp.com +jisuwz.com +jisuxia.com +jisuye.com +jisuyilaixingpiyan.com +jisuziyuanbf.com +jita.fun +jita.im +jita5.com +jitaba.net +jitabang.com +jitadaren.com +jitadog.com +jitailian.com +jitaivalve.com +jitangcn.com +jitao.tech +jitapai.com +jitapu.com +jitapuji.com +jitashe.org +jitavip.com +jitetech.com +jitgame.com +jitianhz.com +jitriroad.com +jittbang.com +jitucdn.com +jitukaisuo.com +jituofuture.com +jituotech.com +jituwang.com +jiu-b.com +jiuaidu.com +jiuaizhihe.com +jiuanchem.com +jiuanyy.com +jiub.net +jiubaju.com +jiubawan.com +jiucaicaijing.com +jiucaigongshe.com +jiucaishuo.com +jiuce.com +jiuchenglaw.com +jiuchet.shop +jiuchutong.com +jiucool.org +jiudafu.com +jiudaifu.com +jiudianjiu.com +jiudianrong.com +jiudianyongpin.com +jiuding-group.com +jiudingcapital.com +jiudinggroup.com +jiudingref.com +jiufengsuye.com +jiugang.com +jiugangbid.com +jiuguijiu000799.com +jiuhantang365.com +jiuhengmake.com +jiuhewj.com +jiuhongwang.com +jiuhua0566.com +jiuhuaiwenxue.com +jiuhuang.com +jiuhuashan.cc +jiuhuishou.com +jiuhuoba.com +jiuishizanjin.com +jiujiange.com +jiujiangjx.com +jiujipos.com +jiujiuhuyu.com +jiujiuyunhui.com +jiujiuzu.com +jiujun.net +jiujunqifu.com +jiukaicable.com +jiuku.com +jiuligroup.com +jiulku.com +jiull.com +jiulong120.com +jiulve.com +jiumaojiu.com +jiumaster.com +jiumei.com +jiumei168.com +jiumei8.com +jiumeisheng.com +jiumentongbu.com +jiunile.com +jiuniok.com +jiupaicom.com +jiupainews.com +jiupaipay.com +jiuq.com +jiuqianwan.group +jiuqianwanjituan.com +jiuqijz.com +jiuqings193004.asia +jiuqings21833.asia +jiuquan.cc +jiuqucloud.com +jiuquhe.com +jiurichem.com +jiurong.com +jiuruigroup.com +jius.net +jiusanedu.com +jiuse.cloud +jiuse2.cloud +jiuse3.cloud +jiushengas.com +jiushiadx.com +jiushigong.com +jiushixing.com +jiushui.tv +jiusi.com +jiusi.net +jiusibz.com +jiusihengyuan.com +jiusili.com +jiusitm.com +jiusko.com +jiutaigroup.com +jiutong100.com +jiutongqu.com +jiutu.net +jiutw.com +jiuwa.net +jiuwan.com +jiuwang.shop +jiuwanshan.net +jiuwei.net +jiuweick.com +jiuweige.com +jiuxian.com +jiuxianfeng.com +jiuxiaobao.vip +jiuxihuan.net +jiuxinban.com +jiuxing.com +jiuxing818.com +jiuxingtang.online +jiuxinsolar.com +jiuxu.com +jiuxusb.com +jiuyan.info +jiuyanchuanmei.com +jiuyang.com +jiuyangongshe.com +jiuyaowangluo.com +jiuyejia.com +jiuyew.com +jiuyezhinan.com +jiuyf.com +jiuyi120.com +jiuyiwenhe.com +jiuyue919.com +jiuyuehuyu.com +jiuyuu.com +jiuzg.com +jiuzhai.com +jiuzhaigou-china.com +jiuzhang.com +jiuzheng.com +jiuzhenge.com +jiuzhilan.com +jiuzhinews.com +jiuzhoupharma.com +jiuzhouzb.com +jiuzhuanzhuan.com +jiuzungame.com +jiway.net +jiweichengzhu.com +jiweixin168.com +jiwu.com +jiwucdn.com +jixiang-ht.com +jixiang-tech.com +jixiang800.com +jixiangjili.com +jixiangyou.com +jixianku.com +jixiao100.com +jixiaoedu.com +jixie100.net +jixie5.com +jixie5188.com +jixiecun.com +jixiehonghong.com +jixiejiaoyu.com +jixieshi.com +jixieshigong.com +jixiew360.com +jixiewz.com +jixinbbd.com +jixinet.com +jixixx.com +jixuanw.com +jixueedu.com +jixuninfo.com +jixunjsq.com +jixunlyq.com +jiyaogroup.com +jiyi.art +jiyi.biz +jiyi.top +jiyida-logistics.com +jiyifa.com +jiyikj.com +jiyili.net +jiyin-tech.com +jiyin2020.com +jiyixcx.com +jiyou-tech.com +jiyoujia.com +jiyouwang.com +jiyouzhan.com +jiyuantour.com +jiyue-auto.com +jiyuncn.com +jiyunhudong.com +jiyunhudong.net +jiyuntang.com +jiyusi.com +jiyx.com +jizbmedia.com +jizhan.com +jizhangla.com +jizhaotang.com +jizhazha.com +jizhiba.com +jizhida.com +jizhihd.com +jizhihezi.com +jizhimobi.com +jizhiyouke.com +jizhouyoupin.com +jizhuba.com +jizhuomi.com +jizhutaoke.com +jizustore.com +jj-1918.com +jj-inn.com +jj00.com +jj0833.com +jj20.com +jj59.com +jj831.com +jj99.icu +jjbang.com +jjbank.net +jjbbs.com +jjbctv.com +jjbdns.com +jjbearings.com +jjbhn.com +jjbisai.com +jjblogs.com +jjbnews.xyz +jjbzhx.com +jjcbw.com +jjccb.com +jjcclt.com +jjcdn.com +jjcoffetel.cc +jjcoffetels.com +jjcpe.com +jjcs66.com +jjcto.com +jjdd.com +jjdede.com +jjdqshy.com +jjecn.com +jjedu.com +jjedu.net +jjeglobal.com +jjfinder.com +jjfuzu.com +jjg630.com +jjgsxc.com +jjh11.com +jjhb.com +jjhgame.com +jjhgamedns.com +jjhh.com +jjhlkqn.com +jjhuifu.com +jjhuolang.com +jjhuoyan.com +jjhza.win +jjidc.com +jjiehao.com +jjinfo.com +jjisp.com +jjj555.com +jjjaaa.com +jjjcjt.com +jjjjjertqqo2222.com +jjjkj.com +jjjlll.org +jjkeq.com +jjkjnet.com +jjkk.org +jjkucunxie.com +jjldbk.com +jjldxz.com +jjledu.net +jjlgbj.com +jjlhbs.com +jjlvu.com +jjlysh.com +jjmatch.com +jjmfc.com +jjmh.com +jjmkids.com +jjmmw.com +jjnshop.com +jjnz.com +jjonline.org +jjqj.net +jjr.vip +jjrau1656.com +jjrc.net +jjrw.com +jjsedu.org +jjshome.com +jjsip.com +jjtang.com +jjtianshangi.com +jjtonline.com +jjtravel.com +jjttjx.com +jjwdz.com +jjwli.com +jjwsx.com +jjwxc.com +jjwxc.net +jjwxc.org +jjxxk.com +jjxyls.com +jjy118.com +jjycw.net +jjygym.com +jjypyz.com +jjys188.com +jjyz.net +jjyz360.com +jjzc168.com +jjzdm.com +jjzfgjj.com +jjzls.com +jjzyy.com +jjzyy.org +jk-bms.com +jk-px.com +jk.com +jk126.com +jk13.net +jk169.net +jk2h.com +jk33zu6.org +jk37du.com +jk3a.com +jk51.com +jk725.com +jk90.com +jkangbao.com +jkapi.com +jkb7.com +jkbexp.com +jkbl.com +jkc8.com +jkchemical.com +jkcn365.com +jkcorkpads.com +jkcsjd.com +jkd.com +jkd360.com +jkdsz.com +jkelec.com +jkh-ym.com +jkhapp.com +jkhcfz.com +jkhds872.com +jkhealth.vip +jkimg.net +jkjiekuan.com +jkjzt.com +jkkefv.com +jkl6.com +jkllbd.com +jklsjm.com +jklughj.work +jknanotech.com +jkouu.com +jkpan.cc +jkpj.com +jkqdl.com +jkqingman.com +jkrcw.net +jksdhgu.com +jkt-tencentclb.cloud +jkt-tencentclb.com +jkt-tencentclb.net +jkt-tencentclb.work +jktcom.com +jktong.com +jktower.com +jkuntp.com +jkwatch99.com +jkwshk.tv +jkx.cc +jkxds.net +jkxedu.com +jkximg.com +jkxw168.com +jkyc.com +jkydt.com +jkypeg.com +jkyule.com +jkzhilu.com +jkzl.com +jkzn365.com +jl-er.com +jl-jssk.com +jl0435.com +jl0775.com +jl1mall.com +jl465.com +jl519.com +jl54.org +jl7y.com +jladi.com +jlafw.com +jlairports.com +jlakes.org +jlandmeditech.com +jlaod.com +jlaoj.com +jlaqjdjt.com +jlbhtc.com +jlbjcs.com +jlbkjt.com +jlbry.com +jlc-3dp.com +jlc-bbs.com +jlc-cad.com +jlc-cam.com +jlc-cnc.com +jlc-code.com +jlc-dfm.com +jlc-drm.com +jlc-ecad.com +jlc-erp.com +jlc-fpc.com +jlc-gw.com +jlc-jh.com +jlc-layout.com +jlc-pcb.com +jlc-smt.com +jlc-zh.com +jlc.com +jlccad.com +jlccam.com +jlccnc.com +jlccpit.com +jlcdfm.com +jlcecad.com +jlceda.com +jlcerp.com +jlcfa.com +jlcmc.com +jlcops.com +jlcsj.com +jlcsmt.com +jldjam.com +jldpvc.com +jlfba.com +jlg66.com +jlgf.com +jlginyo.com +jlgjjt.com +jlguorui.com +jlguowen.com +jlgxmob.com +jlgyjj.com +jlhc.com +jlhdq.com +jlhnw.com +jlhs.net +jlhtcm.com +jlhxjt.com +jlhzyanxue.com +jlinh.com +jljcxy.com +jljcz.com +jljgdj.org +jljnkj.com +jljob88.com +jljzzs.com +jlkfapp.com +jlkgj.com +jlkj.cc +jlkjgroup.com +jllihua.com +jllyzxyy.com +jlmhk.com +jlmhw.com +jlmuban.com +jlnku.com +jlnls.com +jlonline.com +jlpay.com +jlq.com +jlqsugar.com +jlriza.com +jlrtvu.com +jlsdesyxx.com +jlsdwj.com +jlsdzgckcy.com +jlsebhyy.com +jlsegx.com +jlsemi.com +jlsfcyy.com +jlsgjt.com +jlsjsjlhgczxxh.com +jlsjsxxw.com +jlsports.com +jlspr.com +jlsqwyy.com +jlsrc.com +jlsrmyy.net +jlstt.com +jlsw.cc +jlswansen.com +jlsyqzyy.com +jlszlyy.com +jlt01.com +jltchina.com +jlthcc4596.vip +jltq.com +jltrq.com +jltu.net +jlty56.com +jltzgfgs.com +jlwater.com +jlwlw.com +jlxfw.com +jlxhyy.com +jlxtxny.com +jlylwater.com +jlyr2.com +jlysgjzx.com +jlystatic.com +jlytzk.com +jlzhongdong.com +jlzkb.com +jlzsoft.com +jlzyz.com +jm-gallium.com +jm-machines.com +jm-talents.com +jm1ph.com +jm2046.com +jm233333.com +jm3f.com +jm3q.com +jmads.net +jmbao.com +jmbbs.com +jmbon.com +jmbus.net +jmch12333.com +jmchn.com +jmd-china.com +jmd-leatherbag.com +jmdedu.com +jmdna.com +jmdns.com +jmed.com +jmeii.com +jmeizs.com +jmev.com +jmgle.com +jmglg.com +jmgo.com +jmgsgs.com +jmhaofa.com +jmhapp.com +jmhd8.com +jmhjh.org +jmhs.net +jmi365.com +jmj-pharma.com +jmj.cc +jmj1995.com +jmjc.tech +jmjxc.com +jmjzy.com +jmkj.com +jmkx.com +jmkxjt.com +jmlanguan.com +jmlfood.com +jmmsn.com +jmmuseum.com +jmnk300.com +jmonline.org +jmp-cn.com +jmp.gd +jmqy.com +jmqyjt.com +jmrb.com +jmrcw.com +jmsqw.com +jmstatic.com +jmstation.com +jmsxsw.com +jmt-bio.com +jmtnt.com +jmtsg.com +jmwater.com +jmxckj.com +jmxiangyi.com +jmxlmc.com +jmxw.net +jmycapacitor.com +jmycbus.com +jmyleather.com +jmyna.net +jmyqsl.com +jmzcgs.com +jmzgo.com +jmzhangfu.com +jmzns.com +jn-bank.com +jn-cits.com +jn001.com +jn1535.com +jn172.com +jn720.com +jn80.com +jnadi.net +jnairport.com +jnbaibo.com +jnbank.cc +jnbbbyy.com +jnbctv.com +jnbosai.com +jnbuscard.com +jncarw.com +jncec.com +jncfcj.com +jncfjt.com +jncgzl.com +jnchsd.com +jncjjt.com +jncjsgroup.com +jncncq.com +jncyx.com +jndfzt.com +jndssd.com +jndvisa.com +jndwyy.com +jndzx.com +jnec-tencentclb.cloud +jnec-tencentclb.com +jnec-tencentclb.net +jnec-tencentclb.work +jnesc.com +jnexpert.com +jnfx.com +jnfxny.com +jngaobo.com +jngcxy.com +jnghm.com +jngjj.net +jngl.net +jnhb.com +jnhi.com +jnhongyun9.com +jnhouse.com +jnhwjt.com +jnhxzc.com +jnhyyy.com +jnhzxx.com +jnjfwzhs.com +jnjingxin.com +jnjj.com +jnjpkj.com +jnjszl.com +jnkason.com +jnkj.org +jnky.com +jnlab.com +jnlc.com +jnlgzs.com +jnltwy.com +jnmama.com +jnmc.com +jnnc.com +jnnews.tv +jnoec.com +jnpfsoft.com +jnpjyy.com +jnqzyy.com +jnrain.com +jnreli.com +jnrmyy.com +jnruilun.com +jnryc.com +jns168.com +jnshijia.com +jnshu.com +jnsjzyxh.com +jnskqyy.com +jnslyy.com +jnsmjt.com +jnsms.com +jnstdc.com +jnszhqyy.com +jntcg.com +jntig.com +jntinchina.com +jntyhl.com +jnubio.com +jnw.cc +jnwb.net +jnwenlian.com +jnwinner.com +jnxdgs.com +jnxtzdh.com +jnxydefsxx.com +jnyczx.com +jnydgm.com +jnyng.com +jnyyjt.com +jnzcsyj.com +jnzhuoxin.com +jnzjzx.net +jnzl.com +jnzongchi.com +jnzwgzs.com +jnzx.cc +jnzycw.com +jo-loagm06.com +job-sky.com +job006.com +job0575.net +job0663.com +job0722.com +job0728.com +job0768.com +job088.com +job0917.com +job10000.com +job1001.com +job120.com +job168.com +job1998.com +job225.com +job2299.com +job250.com +job263.com +job36.com +job510.com +job5156.com +job5588.com +job5678.com +job592.com +job788.com +job88.com +job910.com +job9151.com +job916.com +jobbaidu.com +jobbole.com +jobcdp.com +jobch263.com +jobcn.com +jobczrc.com +jobeast.com +jobef.com +jobgojob.com +jobhb.com +jobhuaibei.com +jobi5.com +jobidc.com +jobinhe.net +jobjm.com +jobjy.com +jobloser.com +jobosoft.vip +jobpin.com +jobsalon.net +jobsdigg.com +jobsitechina.com +jobsun.com +jobtiku.com +jobtong.com +jobui.com +jobuy.com +jobvvv.com +jobxinpg.com +jobyp.com +jocat.com +jocgreatwall.com +jocite.com +joclabor.net +jocltd.com +joctech.com +jocund-gift.com +jodoll.com +joe92.com +joessem.com +johhan.com +johnlz.com +johnmedia.com +johogames.com +johouse.com +joiest.com +joinchitchat.com +joindata.net +joineonlux.com +joinf.com +joiningss.com +joinkchem.com +joinpay.com +joinquant.com +joinsen.com +joinsuns.com +joint-harvest.com +jointas.com +jointech-cn.com +jointekbusiness.com +jointforce.com +jointown.com +joinusad.com +joinval.com +joinway.com +joinwaylawfirm.com +joinwee.com +jojo000.vip +jojoread.com +jojoreading.com +joke66.com +jokecommunity.com +jokecommunity.net +joker.li +jokerbai.com +jolimark.com +jollerge.com +jollylifelhq.com +joloplay.com +jomocdn.net +jomodns.com +jomodns.net +jomoxc.com +jomoxd.com +jonesroadbeautyrebate.com +jongtay.com +jonhuu.com +jonllen.com +jonln.com +jonny.vip +jonrmal.com +jonsbo.com +jonvie.com +jooancloud.com +joobot.com +jooioo.com +joojcc.com +joojtech.com +joojzz.com +joomla.work +joomobx.com +joooz.com +joowhee.com +joox.com +jooxemail.com +jooyacn.com +jooyoo.net +jooyuu.com +joozone.com +joqoo.com +joscent-sa.com +josen.net +josephcz.xyz +joshreso.com +joshua317.com +jotop.com +jotrin.com +jouav.com +jouder.com +joudou.com +joulwatt.com +journalmc.com +journalsay.com +journeyui.com +jourserv.com +jouypub.com +jovcloud.com +jovetech.com +jovision.com +jovisionai.com +jovmall.com +jowto.com +joy-air.com +joy-nb.com +joy110.com +joy147.com +joy5151.com +joya-electric.com +joyact.com +joyami.com +joyanglab.com +joyapi.com +joyargroup.com +joybuy.com +joybuy.es +joycity.mobi +joydin.com +joyes.com +joyfire.net +joyforce.com +joygames.com +joyglory.com +joyglue.com +joyhc.com +joyi.com +joyinchem.com +joying.com +joyingbox.com +joyingtrip.com +joyinpharma.com +joyintour.com +joyinvleah.com +joyj.com +joylawyer.com +joymeng.com +joyncleon.com +joynext.com +joyochem.com +joyocosmetics.com +joyoget.com +joyoucnc.com +joyoung.com +joyours2019.com +joyowo.com +joyplus.tv +joyshebao.com +joyslink.com +joyson.com +joyssl.com +joystay.net +joysung.com +joysunsh.com +joytest.org +joytourvip.com +joytrav.com +joytraveller.com +joytunescn.com +joytype.com +joyu.com +joyuai.com +joyugas.com +joyulf.com +joyware.com +joywellsemi.com +joywii.net +joywok.com +joyworkshop.com +joywplace.website +joyy.com +joyyan.com +joyyang.com +joyyinc.com +joyyued.com +jozhaopinopin.com +jozne.com +jp-daigou.com +jp-moco.com +jp-tencentclb.cloud +jp-tencentclb.com +jp-tencentclb.net +jp-tencentclb.work +jp.com +jp.run +jp0663.com +jp95.com +jpbeta.net +jpcec.com +jpchinapress.com +jpcoalboss.com +jpddc.com +jpedo.com +jpeen.com +jperation.com +jpfmor.com +jpg.cm +jpghd.com +jpgjzzs.com +jpgreat7.com +jphot.net +jpisp.com +jpjc315.com +jpkankan.com +jpkix.com +jpmetro.com +jpmorganchina.com +jpmsg.com +jpnettech.com +jpnlink.xyz +jpopsuki.eu +jprtyun.com +jpsdk.com +jpseek.com +jpshuntong.com +jpsmile.com +jpspecsz.com +jpsto.com +jptab.com +jpthome.com +jptoe.com +jpts.sinovision.net +jpvat.com +jpwb.cc +jpwb.net +jpwind.com +jpwindow.com +jpwky.com +jpwxapp.com +jpxm.com +jpxue.com +jpxww.com +jpyoo.com +jpyssc.com +jpzx.net +jpzy01.com +jq-school.com +jq22.com +jq33.com +jqbar.com +jqcool.net +jqdzw.com +jqgc.com +jqhtml.com +jqkgjt.com +jqlv.com +jqnbp.com +jqncp.com +jqpress.com +jqr.com +jqr5.com +jqrc.net +jqrc88.com +jqrkc.com +jqs4463333a7.shop +jqs4463333a9.shop +jqsite.com +jqsmm.com +jqtxxedk.com +jquan.ink +jquee.com +jquery123.com +jqueryfuns.com +jquerywidget.com +jqwater.com +jqwwq.com +jqyljt.com +jqyou.com +jqzhuangshi.com +jqzjop.com +jqzplat.com +jqzw.com +jr-mjg.com +jr-soft.com +jr123.com +jr18.com +jr2019.com +jravity.com +jrbiopharma.com +jrbobbin.com +jrc-tech.com +jrdaimao.com +jrexam.com +jrfcg.com +jrgang.com +jrgaofu.com +jrhot.com +jrj.com +jrjiekuan.com +jrjingshan.com +jrjr.com +jrlady.com +jrlm81.com +jrlxym.com +jrmf360.com +jrmianban.com +jrnba.cc +jrntv.com +jrpengze.com +jrqiwen.com +jrqzw.net +jrs-live-football.com +jrs-live-score.com +jrs-live-z.com +jrs-watch-live.com +jrs-yc-hupu.com +jrsncn.com +jrss.com +jrszw.com +jrteck.com +jrtgroup.net +jrtx.site +jrwenku.com +jrxtp.com +jrxzj.com +jryccm.com +jryghq.com +jryssj.com +jryzt.com +jrzj.com +jrzp.com +js-aeg.com +js-aerfa.com +js-cct.com +js-cxjt.com +js-dw.com +js-emap.com +js-gear.com +js-gojo.com +js-haiyao.com +js-jiatai.com +js-jinhua.com +js-jwt.com +js-leader.com +js-lottery.com +js-paper.com +js-powerstone.com +js-rongzheng.com +js-seeker.com +js-shenghang.com +js-talents.com +js-weilong.com +js-xny.com +js-ym.com +js-zk.com +js.design +js04999.com +js0573.com +js118114.com +js165.com +js178.com +js3.org +js3n.com +js7xc.com +js811.com +js9499.com +js96008.com +js96777.com +jsadkg.com +jsaeit.com +jsaes.com +jsafc.net +jsahj.com +jsanbo.com +jsaopa.com +jsape.com +jsarchi.com +jsartcentre.org +jsase.com +jsatcm.com +jsb-syleasing.com +jsbaidu.com +jsballs.com +jsbank.org +jsbc.com +jsbcfl.com +jsbeiyang.com +jsbestop.com +jsbexam.com +jsbfgg.com +jsbgj.com +jsblj.com +jsboxbbs.com +jsbsxh.com +jsbzwh.com +jscba.org +jsccn.com +jscdn.ink +jscdwlw.com +jsceb.com +jscelltech.com +jsceou.com +jschahua.com +jschanglong.com +jschangshou.com +jsche.net +jschunxing.com +jschy.com +jscj-elec.com +jscj.com +jsckw.org +jsclearing.com +jscmjt.com +jscnc.net +jscncg.com +jscndata.com +jscnnet.com +jsconi.com +jsconnect.com +jscrg.com +jscsbz.com +jscsdr.com +jscsfc.com +jscssimg.com +jscts.com +jscz55.com +jsd-jasper.com +jsd.cc +jsd2021.com +jsdagua.com +jsdas.com +jsdcly.com +jsddbs.com +jsddhjt.com +jsddz.net +jsdebang.com +jsdehui.com +jsdesign1.com +jsdesoft.com +jsdgb.com +jsdghfw.com +jsdhjssyjt.com +jsdjwood.com +jsdkdzw.com +jsdljn.com +jsdmirror.com +jsdonglai.com +jsdrc.com +jsdsad.com +jsduopin.net +jsdyyt.com +jsdz16.com +jsdzb.com +jsdzgc.com +jsdzlm.com +jseconomy.com +jsedu114.com +jseduinfo.com +jseea.com +jseepub.com +jsehealth.com +jsendian.com +jsenews.com +jseoptics.com +jsep.com +jsepa.com +jser.io +jsessh.com +jsexpressway.com +jsfish.net +jsfj.net +jsfls.com +jsfmly.com +jsfof.com +jsform.com +jsform3.com +jsfqhwsb.com +jsfreiburg.net +jsft.com +jsfw8.com +jsfwpt.com +jsfxw.com +jsfycdn3.com +jsfyjt.com +jsfywater.com +jsfyxh.net +jsgbds.com +jsgc.com +jsgc168.com +jsgcbank.com +jsgcjyw.com +jsgclaw.com +jsgdsb.com +jsgerrard.com +jsggwhy.com +jsgh.org +jsghfw.com +jsgho.com +jsgho.net +jsghx.com +jsgian.com +jsgjksl.com +jsgjl.net +jsgkw.org +jsgogogo.com +jsgoldenbridge.com +jsgongwei.com +jsgpa.com +jsgrb.com +jsgssb.com +jsgsyy.com +jsguohua.com +jsguolv.com +jsgwyw.org +jsgx.net +jsgxgf.com +jsgyrcb.com +jsgzgz.com +jsh.com +jshaipeng.com +jshaite.com +jshaman.com +jshanchao.com +jshaorungroup.com +jsharer.com +jshasy.com +jshazz.com +jshbank.com +jshcsoft.com +jshcxn.com +jshdata.com +jshddx.com +jshdwh.com +jshealth.com +jshemc.com +jshfgroup.com +jshgfm.com +jshggroup.com +jshgyb.com +jshhjkjt.com +jshhqc.com +jshhzssj.com +jshiway.com +jshj.org +jshkht.com +jshlfd.com +jshmrcb.com +jshnh.com +jshqjt.com +jshr.net +jshrconsult.com +jshrtfl.com +jshsoft.com +jsht88.net +jshtcm.com +jshtjt88.com +jshtocean.com +jshtsteel.com +jshuachen.com +jshuafu.com +jshuana.com +jshuanya.com +jshuaxiagroup.com +jshuaxicun.com +jshwyy.com +jshy.com +jshy1688.com +jshykg.com +jshysj.com +jshytec.com +jshywl.net +jshyzh.com +jshyzh.net +jshzfzjt.com +jshzzx.com +jsi.cc +jsifa.org +jsinnopharm.com +jsiport.com +jsirfe.com +jsjajt.com +jsjcjx.com +jsjclykz.com +jsjd.cc +jsjdgy.com +jsjdjt.com +jsjdrcb.com +jsjdzf.com +jsjeda.com +jsjffj.com +jsjfz.com +jsjgbxg.com +jsjgtz.com +jsjhtz.com +jsjiami.com +jsjianli.com +jsjianye.net +jsjinfu.com +jsjinghui.com +jsjinqi.com +jsjiuda.com +jsjj120.com +jsjjedu.com +jsjjy.com +jsjkx.com +jsjky.com +jsjkzx.com +jsjljg.com +jsjljy.com +jsjnsw.com +jsjnw.org +jsjrtzjt.com +jsjs.cc +jsjs1982.com +jsjsgroup.com +jsjskgjt.com +jsjszgz.com +jsjtxx.com +jsjunma.com +jsjwkg.com +jsjxh03.com +jsjyrcb.com +jsjyyz.com +jsjzd.com +jsk365.com +jskale.com +jskchem.com +jskh.com +jskhfm.com +jskjcms.com +jskjgc.com +jskjgroup.com +jsklcy.com +jskly.com +jskoso.com +jskpcg.org +jskuajing.com +jskunquan.com +jskwt.com +jskxjl.com +jslcjt.com +jsldweb.com +jsldxcl.com +jslegal.com +jslhgroup.com +jslhjg.com +jslida.net +jslife.net +jslijiang.com +jslink.com +jslmarathon.com +jslottery.com +jslpk.com +jslszz.com +jsltgcjt.com +jslvzhigu.com +jsly001.com +jslyjc.com +jslysp.com +jsmda.org +jsmfk.com +jsmian.com +jsminstar.com +jsmjys.com +jsmkyy.com +jsmo.xin +jsmodeling.com +jsmolfa.com +jsmrmf.com +jsmsg.com +jsmxgs.com +jsmxw.com +jsna.work +jsnaier.com +jsnewexpo.com +jsningyi.com +jsnjck.com +jsnjjg.com +jsnkmy.com +jsnol.com +jsnovel.com +jsntg.com +jsntgas.com +jsnx.net +jsnxs.com +jsnydefy.com +jsnydsfy.com +jsnzhb.com +jsocr.com +jsomick.com +jsonin.com +jsososo.com +jspaint.com +jspang.com +jspatch.com +jspcgjg.com +jspcinc.com +jspdg.com +jspeople.com +jspesz.com +jsph.net +jsphjr.com +jsphp.net +jsplayground.net +jspoh.com +jspp.com +jspwc.com +jspxcms.com +jsq886.com +jsqcyjsq.com +jsqdsx.com +jsqiuying.com +jsqlawer.com +jsqstg.com +jsqt.com +jsr.cc +jsrail.com +jsrc.com +jsrcsc.com +jsrcu.com +jsrdgg.com +jsrdsw.com +jsrea.com +jsrenshi.com +jsrgjy.net +jsrhzh.com +jsright.com +jsrongjin.com +jsrpebh.com +jsrrcb.com +jsrsks.com +jsrsrc.com +jsruifeng.net +jsruiyin.com +jsrun.net +jsrun.pro +jsrxjt.com +jss52018.com +jssaikang.com +jssalt.com +jssbaoxian.com +jssbjt.com +jssc.cc +jssczxh.com +jssdezyy.com +jssdh.com +jssem.com +jssfgl.com +jssfx.com +jssfzg.com +jssgjjt.com +jssgjs.com +jsshasczzyy.com +jsshfcw.com +jsshhzx.com +jsshichuang.com +jsshow.net +jsshrzx.com +jsshuangxin.com +jsshuntai.com +jssia.org +jssihuan.com +jssjchyxh.com +jssjiu.com +jssjrfw.com +jssjxgyw.com +jssks.com +jssling.com +jssltz.com +jssnrcb.com +jssoar.com +jssqwx.com +jsssha.com +jsssrj.com +jsssy.com +jsstgs.com +jsstt.com +jsstyt.com +jssunhui.com +jssunlord.com +jssutong.com +jssuty.com +jssuwei.com +jsswordshop.com +jssyj.com +jssytc.com +jssyyy.net +jstcm.com +jstedu.com +jstex.com +jstextile.com +jstfdz.com +jsthinktank.com +jsthjsgc.com +jsti.com +jstianniao.com +jstide.com +jstigd.com +jstjjs.com +jstlcyy.com +jstlgn.com +jstljs.com +jstor.org +jstore.site +jstoys.net +jstsks.com +jstti.com +jstucdn.com +jstv.com +jstve.org +jstxb.com +jstxdm.com +jstxrcb.net +jstxry.com +jsty.com +jstyaz.com +jstygroup.com +jstyjzsg.com +jstywl.com +jstzhospital.com +jstzjy.net +jstzloveyuebao.com +jstzrcb.com +jstzzg.net +jsuc.com +jsuedc.net +jsuhuzhi.com +jsure.com +jsurehealth.com +jsw118.com +jsw988.com +jswater.net +jswb.com +jswcc.com +jswch.net +jswebcall.com +jsweiqi.com +jsweixiu.com +jswel.com +jswenguang.com +jswenjin.com +jswfgroup.com +jswjkj.net +jswmw.com +jswonderful.com +jswrhjkj.com +jswspocapi.com +jswsxx.com +jswtc.net +jswukong.com +jswuyang.com +jswwl.com +jswx-ej.com +jswxhy.com +jswxjx.com +jswxmax.com +jswyglw.com +jswyjt.com +jswyw.com +jswzjt.com +jsxbxcl.com +jsxcra.com +jsxcx.com +jsxdf.com +jsxdyh.com +jsxfedu.com +jsxggx.com +jsxgjt.com +jsxhljt.com +jsxhrcb.com +jsxht.com +jsxhw.org +jsxhy.net +jsxiangtanzi.com +jsxiaoguo.com +jsxiaoshi.com +jsxiechang.com +jsxihu.com +jsxinfeng.com +jsxinfly.com +jsxionghuojxzz.com +jsxlhb.com +jsxmw.com +jsxpbc.com +jsxq.com +jsxtsw.com +jsxxzh.com +jsxy.biz +jsxyfy.com +jsxyjt.com +jsxzgjzx.com +jsxzkingdee.com +jsxzty.com +jsy666.xyz +jsybjt.com +jsybjz.com +jsyc-marathon.com +jsycmc.com +jsycport.com +jsycsy.com +jsyczls.com +jsyd139.com +jsydns15.com +jsyes123.com +jsyf88.com +jsyfxcl.com +jsyghw.com +jsyhkf.com +jsyhxl.com +jsyinba.com +jsyixin.com +jsyjjt.com +jsyks.com +jsyks.net +jsyksw.com +jsyljz.com +jsymjt.com +jsyongbao.com +jsypj.com +jsypyg.com +jsysafe.com +jsysedu.com +jsysxx.net +jsyt.group +jsytsw.com +jsyun.cc +jsyunhao.com +jsywjt.com +jsyxep.com +jsyxh.org +jsyxrcb.com +jsyypump.com +jsyzht.com +jsz.asia +jsz120.com +jszbtb.com +jszca.com +jszcqy.com +jszdlssws.com +jszf.org +jszfy.com +jszg.org +jszhaobiao.com +jszhiping.com +jszhjsjtgs.com +jszhongci.com +jszhongte.com +jszjcg.com +jszjgg.net +jszjgroup.com +jszjrqrd.com +jszjscl.com +jszjsx.com +jszjw.com +jszjxh.com +jszjzf.com +jszkrz.com +jszks.com +jszlgjg.com +jszlyy.com +jszmgj.com +jszmly.com +jszn.ink +jsznstny.com +jszpw.net +jszs-group.com +jszs.com +jszsgroup.cc +jszwpx.com +jszxsw.com +jszygp.com +jszygs.com +jszyjsjt.com +jszyyguoji.com +jszzks.com +jszzxjhk.com +jt-ele.com +jt-it.com +jt000.com +jt111.com +jt120.com +jt26wzz.com +jt56w.com +jt62.com +jt91.com +jta-travel.org +jtamac.com +jtamc.com +jtbole.com +jtbtech.com +jtcjd.com +jtcopper.com +jtexpress.com +jtfcg.com +jtfengtou.com +jtfulfillment.com +jtg2g.com +jtggame.com +jtgloble.com +jtgzfw.com +jtj-kr.com +jtjiaoyu.com +jtjms-ae.com +jtjms-br.com +jtjms-eg.com +jtjms-mx.com +jtjms-sa.com +jtjob.net +jtjr99.com +jtjt.info +jtjyfw.net +jtkjbike.com +jtktkj.com +jtlculture.com +jtlfans.com +jtlw.com +jtlzj.net +jtlzx.com +jtm-food.com +jtm.pub +jtmedical.com +jtn.com +jtnlk.com +jtnsh.com +jto8.com +jtpipeline.com +jtrauto.com +jtrobots.com +jtso.net +jtsp98.com +jttv.net +jttzsy.com +jtv123.com +jtwmall.com +jtxa.net +jtxmtxy.com +jtxys8.com +jtyjy.com +jtystz.com +jtyxh.com +jtzjedu.com +jtzyjt.com +ju1212.com +ju51.com +ju53.com +ju8811.com +ju8856.com +juaiyou.com +juanbao.com +juangua.com +juanyunkeji.com +juaq.com +jubaihuijia.com +jubaiye.com +jubaozang.com +juben108.com +juben98.com +juc365.com +jucaiw.com +jucanw.com +jucdn.net +jucelin.com +jucheng01.net +juchengvi.com +juchuangbio.com +juchuangfushi.com +jucool.com +jucuiwangluo.com +judajia.com +judehahh.tech +judns.com +judong-1.com +judouapp.com +juduoping.com +jue.so +juebankongjian.com +juecan.com +juedui100.com +jueduilingyu.com +juefeng.com +juehuo.com +juejinchain.com +juejinqifu.com +juemei.com +juemuren4449.com +jueqijy.com +juequling.com +juerguea.com +juewei.com +juexiang.com +juexiaotime.com +juexinw.com +jueywo.com +jufa-composite.com +jufa.vip +jufaanli.com +jufair.com +jufeng313.com +jufengcap.com +jufengcompany.com +jufenginfo.com +jufengshang.com +jufengwuxi.com +jufoinfo.com +jugezi.com +jugongdan.com +juguang.com +juguifu.com +juhaihui.com +juhangye.com +juhaokan.org +juhaokanya.com +juhaom.cc +juhaom.com +juhe.com +juhe5.com +juhebang.com +juheweb.com +juhomai.com +juhome.net +juhuasuan.com +juhui581.com +juhuicloud.com +juhuiwan.com +juhuiwan.net +jui.org +juicefs.com +juicycouture-diaperbags.org +juij.fun +juiju.com +juj66.com +juji123.com +jujianggcz.com +jujiangkk.com +jujiangktz.com +jujiaobaby.com +jujiaonet.com +jujias.com +jujie.com +jujienet.com +jujin8.com +jujinpcb.com +jujoy.com +jujumao.com +jukan.net +juke200.com +jukebao.com +jukejia.com +juketai.net +jukeyouxuan.com +jukuu.com +julaibao.com +julang88.com +julanggroup.com +julanhp.com +julanling.com +julebu.co +julecn.com +julefun.com +juli-china.com +juliandianqi.com +juliang8.com +juliangcili.com +julianghttp.com +juliangip.com +juliangyinqing.com +juliangyinqing.net +julifenti.com +juligroup.com +julihuang.com +julink.net +julisjj.com +julive.com +juliym.com +juliyuemeng.com +julong.cc +julongchina.com +julonggr.com +juluape.com +julycn.com +julydate.com +julyedu.com +julysong.com +jumanhua.com +jumanlou.com +jumbo-wpc.com +jumbot.net +jumbotutor.com +jumdfd.com +jumei.com +jumeinet.com +jumengco.com +jumengren.com +jumengtbs.net +jumi-cdn.com +jumi.com +jumi18.com +jumin.cc +juming-xz.com +juming.com +jumingwang.com +jumo2.icu +jumold.com +jumore.com +jump-center.com +jump-game.com +jump301.com +jumpjumpcat.com +jumple.com +jumppo.com +jumpserver.org +jumpstar-tech.com +jumpvg.com +jumpw.com +jumpwgame.com +jumpwo.com +jumsz.com +jumwayholdings.com +jun-hai.com +jun.la +jun4.com +junahotels.com +junankeji.com +junanres.com +junanshengwu.com +junao147.com +junaotiyu.com +junce.com +juncyun.com +jundacheng.com +jundaobaoan.com +jundui.net +jundushan.com +junengdingli.com +juneyao.com +juneyaoair.com +juneyaoairlines.com +junezx.com +junfalipin.com +jungewang.com +junhaocn.com +junhe.com +junhegroup.com +junhunxiaoshuo.com +juniontech.com +junjing.net +junjingsuodao.com +junjue888.com +junka.com +junkai.net +junlanhotels-hp.com +junlebaoruye.com +junlee.net +junli.net +junlian.me +junlinsz.com +junlongtech.com +junmoseo.com +junnanhao.com +junong360.com +junpengtouzhi.xyz +junph.com +junpin.com +junpin360.com +junpinclub.com +junpinghui.com +junpinhui.com +junpinmall.com +junpinzhi.com +junqing360.com +junrunrenli.com +junsaozg.com +junshanggame.com +junshencm.com +junshi.com +junshi881.com +junshidao.com +junshifuxin.com +junshijia.com +junshijidi.com +junshipharma.com +junshis.com +junshishu.com +junshitt.com +juntec.com +juntu.com +junwu262.com +junxinmed.com +junxunkji.com +junyao.tech +junyi-auto.com +junyimeng.com +junying.com +junyisj.com +junyouxuan.com +junyudns.com +junyuewl.com +junyushop.com +junzehb.com +junzhenggroup.com +junzhi.com +junzhuan.com +junziboxue.com +junzimen.com +junziqian.com +junziyize.com +juooo.com +jupiterlauncher.com +jupup.com +juqi.com +juqianwh.com +juqibike.com +juqingla.com +juqk.net +juquanquanapp.com +jurcc.net +juren.com +jurenqi.com +jurongfangchan.com +jurongrencai.com +jurp.net +jusdasr.com +juseey.com +jusen2008.com +jushe.org +jushen.co +jushequ.net +jushequan.com +jushewang.com +jushi.com +jushigj.com +jushihui.com +jushiwangedu.com +jushri.com +jushtong.com +jushuitan-inc.com +jushuitan.com +jushuitan.net +jushuo.com +jusiot.com +jusoucn.com +jussevent.com +jusssports.com +jusssportsvenue.com +jusstickets.com +jussyun.com +just-plain.fun +just4coding.com +just4fun.site +just998.com +justalkcloud.com +justar-cn.com +justbbs0.com +justbilt.com +justbon.com +justep.com +justering.com +justinbot.com +justjavac.com +justlove.work +justmyblog.net +justnowmn.com +justpodmedia.com +justsy.com +justtop.com +justwe.site +jutao.com +jutean.com +jutengjiqi.com +jutingshop.com +jutone.com +jutongbao.online +jutubao.com +jutuike.com +jutuilian.com +juvefans.com +juwa.net +juwan.com +juwang.com +juwangmedia.com +juwanhezi.com +juwanshe.com +juweixin.com +juwuxian.com +juxia.com +juxian.com +juxiang3d.com +juxieyun.com +juxiiangyou.com +juxin.tv +juxingj.com +juxinguanjian.com +juxinhuizhi.com +juxuan.net +juxuecms.com +juxuewen.com +juyang-chem.com +juyanwenjuan.com +juyebwg.com +juyingele.com +juyingonline.com +juyisuliao.com +juyoubao.com +juyoukuaisong.net +juyouqu.com +juyoutang.com +juyoutv.cc +juyouxi.com +juyouxuan.vip +juyuan.com +juyuewang.net +juyun.tv +juyutube.com +juyuweb.net +juzhen.com +juzhen.io +juzhentech.com +juzhenyun.org +juzhi720.com +juzhiliang.com +juzhiyuan.com +juzhongjoy.com +juzicon.com +juzicy.com +juzifenqi.com +juzijiudian.com +juzikong.com +juzilicai.com +juzimi.cc +juzioo.com +juziseo.com +juziss.com +juzistore.com +juzisy.com +juziwulian.com +juzix.io +juzizhoutou.net +juzone.cc +juzui.com +juzzi-ec.com +jv07.com +jvbhotel.com +jvcxp.com +jvdebao.com +jvgnwn.sbs +jvmai.com +jvniubi.com +jvpin.vip +jvrong.com +jvshangwang.com +jvshi.net +jvtianshanuu.com +jvyou.net +jw100.net +jw1588.com +jwappgc.com +jwautoparts.com +jwbf.online +jwbl.com +jwchicago.com +jwdili.com +jwedit.net +jwetech.com +jwfun.com +jwgb.net +jwgf.com +jwick-switch.com +jwipc.com +jwkj.site +jwl100.com +jwsaas.com +jwsem.com +jwshy.com +jwsm123.com +jwtherapeutics.com +jwview.com +jwwey.com +jwygou.com +jwyun.net +jwzhn.com +jwzykg.com +jx-189.com +jx-amc.com +jx-bank.com +jx09.com +jx116114.com +jx139.com +jx163-cname.com +jx163.com +jx188.com +jx3box.com +jx3mogu.com +jx3pve.com +jx3yymj.com +jx4.com +jx530.com +jx8.net +jx878.com +jxage.com +jxairport.com +jxausoft.com +jxawe.org +jxbhwl.com +jxbinhong.com +jxbond.com +jxbscbd.com +jxc4.com +jxcar.com +jxcat.com +jxcb.net +jxcc.com +jxccb.com +jxcdkjfz.com +jxcfs.com +jxch12333.com +jxchaguan.com +jxckd.shop +jxcsedu.com +jxct.work +jxcua.com +jxdcnc.com +jxdcost.com +jxdcw.com +jxdhhbhg.com +jxdiguo.com +jxdinfo.com +jxdlzy.com +jxdouliang.com +jxdx.com +jxdxxt.com +jxdyf.com +jxdyyy.com +jxdzx.com +jxeca.com +jxedgroup.com +jxedt.com +jxedu.net +jxeduyun.com +jxenglish.com +jxep.net +jxetv.com +jxexpressway.com +jxey.com +jxfeng.com +jxfhomes.org +jxfls.com +jxfrjs.com +jxfxky.com +jxg1.com +jxg866.com +jxga.com +jxgazx.com +jxgcxy.net +jxgdhb.com +jxgdw.com +jxgis.com +jxgs.cc +jxgtzxc.com +jxgwy.org +jxgztv.com +jxh2000.net +jxheming.com +jxhesyy.com +jxhjxy.com +jxhmjx.com +jxhmxxjs.com +jxhswhcb.com +jxhuahang.com +jxhxmed.com +jxhyxx.com +jxiaolan.com +jxic.com +jximage.com +jxjatv.com +jxjdgy.com +jxjee.com +jxjia.net +jxjianwei.com +jxjktzjt.com +jxjmzc.com +jxjob.net +jxjrw.com +jxjt666.com +jxjuwentech.com +jxjx6.com +jxjywater.com +jxkeda.com +jxkjzb.com +jxkp.com +jxksw.net +jxlgjd.com +jxln.com +jxlog.istreamsche.com +jxlong.com +jxlpjt.com +jxlsxy.com +jxlvs.com +jxlwgame.com +jxlygo.com +jxmhp.com +jxmj.com +jxmlkd.com +jxmrfire.com +jxmy18.com +jxncyy.com +jxndxuebao.com +jxnjy.com +jxnongjiayuan.com +jxnxs.com +jxnyc.net +jxpdf.com +jxphone.com +jxpp.com +jxpta.com +jxqcw.com +jxqy.city +jxqyfw.com +jxrays.com +jxrcgame.com +jxrcw.cc +jxrcw.com +jxrczp.com +jxrjxh.com +jxrmtzx.com +jxropan.com +jxrqgs.com +jxrqhy.com +jxrsrc.com +jxrtv.com +jxrtvu.com +jxsdfz.com +jxsedu.com +jxsenyang.com +jxsfjzsh.com +jxsg.com +jxshangyou.com +jxshyzhx.com +jxsilkpark.com +jxsj-vtech.com +jxsj2sy.com +jxsjgjt.com +jxsjxh.com +jxsjypt.com +jxslsyy.com +jxsltz.com +jxslyw.com +jxsrfdc.com +jxsrjt.com +jxsrra.com +jxssjx.com +jxssjy.com +jxstm.com +jxsuji.com +jxswjt.com +jxswskj.com +jxswzjx.com +jxsxdz.com +jxszxyjhyy.com +jxszyy.com +jxt1314.com +jxt189.com +jxtcxh.com +jxteacher.com +jxtech.net +jxthz.net +jxtransfer.com +jxtutechan.com +jxtvbbs.com +jxtvshop.com +jxtwkj.com +jxtxzzw.com +jxtyzx.org +jxtzw.com +jxunicom.com +jxveg.org +jxw12328.com +jxwan.com +jxwmanage.com +jxwmsj.com +jxwxai.com +jxwz.net +jxx7.com +jxxdf.com +jxxdxy.com +jxxhdn.com +jxxhsd.com +jxxinzhe.com +jxxnyqc.com +jxxs.net +jxycqy.com +jxyczs.com +jxydt.com +jxygroup.com +jxyhys.com +jxyige.com +jxyjxy.com +jxyqw.com +jxysedu.com +jxytech.com +jxyuging.com +jxyushan.com +jxyy.net +jxzbx.com +jxzeto.com +jxzikao.net +jxzl.cc +jxzxtec.com +jxzyx.com +jy-leasing.com +jy-mach.com +jy-sz.net +jy.cc +jy0604.com +jy0832.com +jy163.net +jy1991.com +jy391.com +jy510.com +jy6d.com +jyacg.com +jyacht.com +jyaochi.com +jyarton.com +jybase.net +jyblife.com +jyboo.com +jycbank.com +jycinema.com +jycloudgslb.com +jycloudgslb.net +jydc.com +jydj.net +jydoc.com +jydonghu.com +jydtu.com +jyebank.com +jyebfz.com +jyecc.com +jyeoo.com +jyeoo.net +jyfcyy.com +jyfprinting.com +jyfund.com +jyfwyun.com +jyg-lighting.com +jygch.com +jygjsq.com +jyglass.net +jygo.cc +jygpu.com +jygsdyrmyy.com +jyguagua.com +jygyl.com +jygz.com +jygz.org +jyh.com +jyhcd.com +jyhmz.com +jyhome.com +jyhwcl.com +jyhyfintax.com +jyhzsc.com +jyimg.com +jyinns.com +jyip.net +jyjhkj.com +jyjjc.com +jyjk.com +jyjxtech.com +jykm88.com +jykss.com +jykuaidi.com +jyl88.com +jylight.cc +jylink.com +jyltx.com +jylw.com +jylxbc.com +jymhb.com +jymredu.com +jynews.net +jynongye.com +jynyrc.com +jyoptical.com +jypc.org +jypecdn3.com +jypipes.com +jypmm.com +jyqcw.com +jyqingfeng.com +jyqxz2015.com +jyrcjl.com +jyrcw.com +jyrczp.com +jyrlzy.com +jyrmtzx.com +jyrmyy.com +jyrq.net +jyry.com +jys0755.com +jys6z.com +jysbcj.com +jysd.com +jysedu.com +jyseeds.com +jyshare.com +jyshoubao.com +jysld.com +jysmtech.com +jysper.net +jysq.net +jysrc369.com +jyss.com +jyss.net +jysteels.com +jysu.com +jysyyey.com +jysyzk.com +jysyzx.net +jytaier.com +jytcdq.com +jytek.com +jytjsgyp.com +jytmachinery.com +jytrump.com +jytwp.com +jyubbs.com +jywanrun.com +jywfgg.com +jywlcm.com +jywmgs.com +jywxq.com +jyxdyzx.com +jyykyy.com +jyyun.com +jyzb01.com +jyzc.com +jyzhongg.com +jyzmd.com +jyzz666.com +jyzzdq.com +jyzzx.com +jz-hy.com +jz-ins.com +jz-job.com +jz-marathon.com +jz0045.com +jz08.com +jz100.com +jz177.com +jz182.com +jz26666.com +jz36666.com +jz5u.com +jz6.com +jz60.com +jz6868.com +jz68888.com +jzac.org +jzagile.com +jzb.com +jzbar.net +jzbull.com +jzcbank.com +jzchou.com +jzcmfw.com +jzctmy.com +jzcxptm.com +jzda001.com +jzdd.com +jzdlgroup.com +jzdwh.com +jzedu24.com +jzerp.com +jzfz.net +jzg12315.com +jzgc-school.com +jzgchy.com +jzgcjsysjzz.com +jzgczz.com +jzgede.com +jzggzy.com +jzgjbus.com +jzgjj.com +jzhfz.com +jzhkr.com +jzhlgg.com +jzhospital.com +jzhuishou.com +jzhx.net +jzhy5.com +jzj2009.com +jzj9999.com +jzjgift.com +jzjt.com +jzking.com +jzkjjt.com +jzlt100.com +jzmbti.com +jzmjtjn.xyz +jzmlzy.com +jzmob.com +jzmsmj.com +jzmt.net +jznygf.com +jznyjt.com +jzongguan.com +jzpat.com +jzptt.com +jzpu.com +jzpx.net +jzq9pzcz8b.world +jzqe.com +jzqlyptall.com +jzrb.com +jzrc.net +jzrsks.com +jzsbs.com +jzsbxxh.com +jzsc.net +jzsc8.com +jzsec.com +jzsf.com +jzsgzmhjyxgs.com +jzsjyksy.com +jzsos.com +jzsousuo.com +jzsszyjzx.com +jzsxinyudianqi.com +jzsyy.com +jzszdq.com +jzszzx.com +jztey.com +jztsjx.com +jztvnews.com +jztvxmt.com +jztweb.com +jzty.com +jztylxx.com +jztzw.net +jzwcom.com +jzwl66.com +jzwxfrp.com +jzx.com +jzxian.com +jzxjcf.com +jzxs.com +jzygczx.com +jzyqyb.com +jzyqzypg.com +jzyx.com +jzzfyw.com +jzzhw.com +jzzls.com +jzzx.com +jzzypt.com +k-boxing.com +k-dyn.com +k-kbox.com +k-res.net +k.biz +k0898.com +k0rz3n.com +k12.vip +k12china.com +k12kc.com +k12zx.com +k165.com +k166.org +k1u.com +k1wave.com +k22.xyz +k2os.com +k3072.com +k365.asia +k366.com +k369.com +k382.com +k3cdn.com +k3yes.com +k43439.com +k518.com +k5hp4qte.work +k5n.com +k61.org +k6uk.com +k73.com +k780.com +k8.com +k8008.com +k8azeicxy4idx.com +k8k8k8.com +k8ser.com +k8smeetup.com +k8stech.net +k913.com +ka20.com +kaaass.net +kaadas.com +kaaer.org +kaayou.com +kaayou.net +kaayun.com +kaba365.com +kabapay.com +kabasiji.com +kaboy.net +kabu1.com +kaceie.com +kachecn.com +kachengnet.com +kacheren.com +kacper.fun +kada.com +kada163.com +kadang.com +kaduoduohk.com +kaeryun.com +kafangtech.com +kafeng.com +kagirl.net +kah8.com +kahaozhushou.com +kahha.com +kahuodong.com +kai-lun.net +kai-ying.com +kaiba315.com +kaibanglaw.com +kaiboer.com +kaichejiqiao.com +kaichengschool.com +kaicn.com +kaidanbao.com +kaidany.com +kaidapack.com +kaidechem.com +kaidianbang.com +kaidicloud.com +kaidydrilling.com +kaierda.com +kaifabang.com +kaifae.com +kaifage.com +kaifakuai.com +kaifama.com +kaifamei.com +kaifangkecheng.com +kaifapiao.com +kaifaxhl.com +kaifaxueyuan.com +kaifayun.com +kaifu.com +kaifu1.com +kaifubiao.com +kaifubiao123.com +kaigao.com +kaige68.com +kaigongyi.com +kaiguo.com +kaihei.co +kaihong.com +kaihu51.com +kaihuaeva.com +kaihuia.com +kaijia-smt.com +kaijia.com +kaijiage.com +kaijiejinrong.com +kaijieunion.com +kaijiudian.net +kaikeba.com +kailang17.com +kaili-group.com +kailinchem.com +kailing.pub +kailinjt.com +kailitech.com +kaimanhua.com +kaimen360.com +kaimenhong.org +kaimg.com +kaimitech.com +kaipai.com +kaipanhong.com +kaipanla.com +kaipuyun.com +kaipuyun.net +kaiqiancq.com +kaiqiu.cc +kaiqsz.com +kaiquan.com +kairui.tech +kairunjinshu.com +kaisacst.com +kaisagroup.com +kaisahotel.com +kaisalong.com +kaisamicf.org +kaishan-pv.com +kaishancomp.com +kaishangroup.com +kaishigo.com +kaishikan.com +kaishuhezi.com +kaishujia.com +kaishustory.com +kaitai668.com +kaitaibh.com +kaitaishotblasting.com +kaitaku.xyz +kaiteer17.com +kaitianad.com +kaitiancloud.com +kaiting.cc +kaiwenda.com +kaiweneducation.com +kaiwind.com +kaixia.com +kaixin.com +kaixin00.com +kaixin001.com +kaixin100.com +kaixinbao.com +kaixindou.net +kaixinguopiao.com +kaixinguopiaowu.net +kaixinhui.com +kaixinhui.net +kaixinit.com +kaixinlu.com +kaixinvv9.com +kaixinzuqin.com +kaixue.io +kaiyanapp.com +kaiygame.com +kaiyi.cool +kaiyihome.com +kaiyinedu.com +kaiyuan.me +kaiyuanbusiness.com +kaiyuancn.com +kaiyuangroup.cc +kaiyuanhospital.com +kaiyuanhotels.com +kaiyuanweilaikeji.com +kaiyuedoors.com +kaiyueyun.com +kaiyun.com +kaiyun.net +kaiyun360.com +kaiyuncare.com +kaiyunwu.net +kaizhan.com +kajicam.com +kajishou.com +kaka.com +kaka996.com +kakacl.net +kakadown.com +kakalili.com +kakamobi.com +kakappt.com +kakashuzi.net +kakatx.com +kakayigui.com +kakayuy.net +kaken-china.com +kaku-scdn.com +kaku.tv +kakucloud.com +kalading.com +kalamitsibeach.com +kalazan.com +kalcaddle.com +kaleesh.com +kalefans.com +kalegou.com +kalifang.com +kaliorg.com +kalugaqueen.com +kaluli.com +kamaqc.com +kameng98.com +kamenwang.com +kamfat.net +kami.vip +kami5.com +kamidox.com +kamisamak.com +kamitemall.com +kammtown.com +kamoasia.com +kamopos.com +kamtao.com +kamwu.com +kan.cc +kan0512.com +kan3721.com +kanbaobei.com +kanbing.net +kanbox.com +kancaibao.com +kanchao.com +kanchuan.com +kandao.com +kandaoni.com +kandedongguan.com +kandegang.net +kandehotelhuizhou.com +kandian.com +kandian.net +kandian.tv +kandian5.com +kandianbao.com +kandianshi.com +kandianzixun.com +kandzww.com +kanfangjilu.com +kanfeidie.com +kang-li.com +kang-zhuo.com +kang7.com +kangai8.com +kangame.tv +kangantu.com +kangbaifoundation.com +kangbatv.com +kangbeijia.com +kangbidz.com +kangbixing.com +kangchun.com +kangdacolorful.com +kangdaep.com +kangdajiuzhou.com +kangdalawyers.com +kangdamed.net +kangdexin.com +kangdns.com +kangehao.com +kangepian.com +kangerfugroup.com +kangfenhui.com +kangfenmao.com +kanggui.com +kanghe.com +kanghu.net +kanghuash.com +kanghuayun.com +kanghui.com +kanghuicy.com +kanghuwang.com +kangjiachildcare.com +kangjian.com +kangjian888.com +kangjiezx.net +kangkang.com +kanglaohui.com +kangle.net +kanglepharm.com +kanglisha.com +kangliyaoye.com +kangnai.com +kangpeining.com +kangpugroup.com +kangq.com +kangqiao-sh.com +kangre.com +kangrunpharm.com +kangshuai.biz +kangsibeauty.com +kangtaiwang.com +kangting.com +kangtor.com +kangufen.com +kanguo.com +kanguowai.com +kangxi55wlsf.com +kangxiang.com +kangxidi.com +kangxin.com +kangyang51.com +kangyiqiye.com +kangyuntang.com +kangze.com +kangzhi.com +kangzhimei.net +kangzhiqiao.com +kanimg.com +kaniuquan.com +kanixiaoxia.com +kanjia.com +kanjian.com +kanjianxinli.com +kankan.com +kankan.run +kankan365.cc +kankancity.com +kankanews.com +kankanlive.com +kankanmi.com +kankannews.com +kankanpiao.com +kankantu.com +kankanyn.com +kankanyulewang.com +kankanzhijian.com +kanketv.com +kankezw.com +kankun-smartplug.com +kanman.com +kanniao.com +kanong.com +kanongyun.com +kanqibao.com +kanqiye.com +kanqq.com +kanqu.com +kanrang.com +kanrang.net +kansdk.com +kansea.com +kanshangjie.com +kanshijie.cc +kanshu.com +kanshu5.net +kanshu58.cc +kanshuge.com +kanshuhai.com +kanshushi.com +kansp.com +kantao.net +kantianqi.net +kantop.net +kantsuu.com +kantu.com +kanwuye.com +kanwz.net +kanxue.com +kanyaji.com +kanyijie.com +kanyixue.com +kanyouxi.com +kanyouxi.tv +kanyun.com +kanzhekou.com +kanzhun.com +kanzuixian.com +kao100.com +kao750.com +kao8.cc +kao910.com +kaoaa.com +kaobeitu.com +kaochong.com +kaochongqing.com +kaodaojy.com +kaodongli.com +kaoersi.com +kaogua.com +kaoguobao.com +kaojiaoshi.com +kaojionline.com +kaojuan.com +kaola.com +kaola.com.hk +kaola100.com +kaolacam.net +kaolacdn.com +kaolafm.com +kaolafm.net +kaolawenku.com +kaom.net +kaomeiyuan.com +kaonaw.com +kaonenyi.com +kaonun.com +kaopenhs.com +kaopu001.com +kaopubao.com +kaopujinfu.com +kaopuyun.com +kaopuyun.net +kaoqin.com +kaoqintong.net +kaoqinyi.com +kaoruo.com +kaoshenzazhi.com +kaoshi110.com +kaoshi365.com +kaoshi86.com +kaoshibao.com +kaoshibb.com +kaoshidian.com +kaoshixing.com +kaoshizixun.com +kaosite.com +kaostedu.com +kaotipai.com +kaowana.com +kaowang.com +kaowx.com +kaoyan.com +kaoyan.org +kaoyan1v1.com +kaoyanbox.net +kaoyancas.com +kaoyancas.net +kaoyango.com +kaoyanjun.com +kaoyanking.com +kaoyanmiji.com +kaoyansiji.com +kaoyanwin.com +kaoyaya.com +kaozc.com +kaozh.com +kaozhiye.com +kap666.com +kapokshenzhen.com +kaquanbao.com +karatetrend.com +karger.com +kargocard.com +karl-led.com +karlzhou.com +karrytech.com +kartlover.com +kascend.com +kashangwl.com +kashen.com +kashen8.com +kashengauto.com +kasitesoft.com +kaslyju.com +kaspersky-labs.com +kasscloud.com +kataliya.net +kate-kanebo.net +katongji.com +katvr.com +katyusha.net +kava-auto.com +kavaparts.com +kaven.xyz +kavience.com +kawahdinosaur.com +kawasakijp.com +kawata-group.com +kawoka.com +kayajiuhui.com +kayhanfamily.com +kayipgroup.com +kayougame.com +kaytrip.com +kaytune.com +kazakcnr.com +kazhifu.com +kazithai.com +kazl.com +kb.com +kb54.com +kb9.com +kbans.com +kbao123.com +kbcdn.com +kbcmw.com +kbcool.com +kbdfans.com +kbdxd.org +kbgogo.com +kbgok.com +kbiquge8.com +kbjcn.com +kbkyy.com +kblcdn.com +kblin.com +kbmlifesci.com +kbn-zhejiang.com +kbnhp.com +kbnqy.com +kbobo.com +kboth.com +kbrightlaw.com +kbscd.net +kbscloud.com +kbsml.com +kbspheres.com +kbtingdu.com +kbyun.com +kc-keycool.com +kc0011.net +kc87.com +kcbebank.com +kccidc.com +kccn.net +kcdn0.com +kcdnvip.com +kcfei.com +kchance.com +kchezhan.com +kchile.com +kchuhai.com +kci-gz.com +kciptv.com +kcjpharma.com +kcjyyjzzs.com +kcloudidc.com +kcm120.com +kcmice.com +kcouxp.com +kcqcjt.com +kcrcb.com +kcrea.cc +kcrw.streamguys1.com +kctgov.com +kctzgroup.com +kcwiki.org +kcyuri.com +kczhaosheng.com +kd010.com +kd100.com +kd120.com +kd128.com +kd315.com +kd58.com +kd9000.com +kdadj.com +kdaec.com +kdatacenter.com +kdatu.com +kdcloud.com +kdclub.net +kdcnu.com +kdefu.com +kdf.ink +kdgcsoft.com +kdhj-edu.net +kdige.com +kdkefu.com +kdkh.com +kdlgs.com +kdnet.net +kdniao.com +kdpt.net +kdr163.com +kdrmd.com +kdroid.club +kds100.com +kdslife.com +kdt.im +kdued.com +kdweibo.com +kdzs.com +kdzwy.com +kdzxedu.com +ke-chuang.com +ke.com +ke51.com +ke6.com +ke6payux9q4pih.com +ke82.com +ke86.com +ke8u.com +keai.icu +keaidian.com +keaiq.com +kean1688.com +keanrui.com +keaopt.com +keba.host +kebango.com +keberosteri.com +kebi.biz +kebide.com +kebingzao.com +keboyunxiao.com +kebvalves.com +keceyun.com +kechengbiao.net +kechengkeli.com +kechuang.org +kechuangai.com +kechuangfu.com +keda-digital.com +keda-group.com +keda-u.com +keda.com +keda.fun +kedabai.com +kedacom.com +kedaifu.com +kedang.net +kedanm.com +kedaotech.com +kede-auto.com +kede.com +kedefamen.com +kedi.cc +kedian-tech.com +kedianduo.com +kedidairy.com +kedingyun.com +kedou.com +keduxinxi.com +kedwyz.com +keede.com +keejuu.com +keen-dental.com +keenbow.com +keenonrobot.com +keensky.com +keep.com +keep999.com +keepc.com +keepcdn.com +keepchen.com +keeper.work +keepfightinghxz.xyz +keepfrds.com +keepke.com +keepmobi.com +keepnight.com +keepsoft.net +keepyoga.com +keerdapower.com +keerqinmuseum.com +keerworld.com +keetalks.com +keewin.com +keey.sh +kefeijn.com +kefenxi.com +kefoo.com +kefu01.com +kefutoutiao.com +kefuzu.com +kege.com +kehaohao.com +kehou.com +kehu51.com +kehuaapp.com +kehuan-upward.com +kehuda.com +kehuzhichi.com +kehuzhichi.net +keil345.com +keinsci.com +keithbo.com +keji100.net +kejian.design +kejianx.com +kejibear.net +kejicut.com +kejids.com +kejihai.com +kejik.com +kejilie.com +kejimeixue.com +kejingyuan.com +kejinlianmeng.com +kejinshou.com +kejiqi.com +kejishou.net +kejitai.com +kejitechangsheng.com +kejitian.com +kejiwang.cc +kejiweixun.com +kejudati.com +kekaku.com +kekaoxing.com +kekaoyun.com +keke.moe +keke289.com +kekebaby.com +kekedj.com +kekegold.com +kekenet.com +kekeniu.com +kekeshici.com +kekeyuyin.com +kekkyy.com +kekoku.com +keky.org +keladuoww.com +keladuoyy.com +kelaisz.com +kelanjt.com +kelankqs.com +keldamedical.com +kele8.com +kelehuyu.com +keleqiu.com +kelete.com +keliangtek.com +kelibiao.com +kelikt.com +kelimotor.com +kelinpower.com +kelinsoft.com +kelon.com +kelong-chemical.com +kelong-powder.com +kelongding.com +keloop.com +kelorlink.com +kelphome.com +kelu.org +kelun.com +keluokelie.com +keluyjs.com +kema66.com +kemaicrm.com +keman.com +kemavip.com +keme.work +kemiaotai.com +kemicro.com +kemike888.com +kemov.com +ken-tools.com +ken.io +kename.com +kenaqz.com +kenbotong.com +kendingde.com +kendryte.com +keneng.org +kenflo.com +kenfor.com +kenfor.net +kengatoki.com +kengdie.com +kengic.com +kengwan.com +kenistab.com +keniu.com +keniub.com +keniuxy.com +kenjieer.com +kenkapacking.com +kenpai.com +kenpains.com +kenshu.cc +kenshuhu.com +kensuntec.com +kentier.com +kentxxq.com +kenuonet.com +kenweini.com +kenxon.com +kenzochina.com +keoaeic.org +keouaxbw.com +keovo.net +kepusky.com +keputech.com +keqiaojob.com +kequcps.com +ker58.com +kercan.net +kercoras.com +kerisom.com +kerlala.com +kernel-sh.com +kernel.cc +kernelfood.com +kernelmed.com +kernelnote.com +kerneltravel.net +kerntech-asp.com +kerric-china.com +kerryparkside.com +keruibell.com +keruigroup.com +keruiiai.com +keruilai.com +keruilait.com +keruisifan.com +keruknowledge.com +kerun2010.com +kerundegroup.net +kerust.com +keruyun.com +keruyun.net +kery-pharm.com +kerysoft.com +kesci.com +kesheng.com +keshenwei.com +keshizhongguo.com +kesion.com +kesiyunlai.com +kesonco.com +kesong.co +kesong520.com +kesonic.com +ketangpai.com +ketechdigital.com +ketingkeji.com +ketingzhuangxiu.com +ketofbx.net +kevinems.com +kevinjiang.info +kevinlq.com +kevke.com +kewu.cc +kewucool.com +kexgfv.com +kexianggroup.com +kexin001.com +kexinbiotech.com +kexincpa.com +kexing100.com +kexingchem.com +kexinggy.com +kexinhaoma.org +kexinshe.com +kexinyun.org +kexu.com +kexue.com +kexue.fm +kexuezixunzzs.com +kexuna.com +key-iot.com +keyboardancer.com +keyboardingonline.net +keycom-ip.com +keydak.com +keydatas.com +keyde.com +keyfc.net +keygotech.com +keyibao.com +keyigroup.com +keyingchem.com +keyipump.com +keylol.com +keymantek.com +keymedbio.com +keymoe.com +keyoo.com +keyoou.com +keyray-hk.com +keytherapharma.com +keyto168.com +keytoix.vip +keyu66.com +keyuanpharma.com +keyubio.com +keyuejiazheng.com +keyueng.com +keyunchaxun.com +keyunidc.com +keyunlaser.com +keyunsoft.com +keyyaam.com +kezehb.com +kezhaozhao.com +kezhi.tech +kf.ai +kf155yy.com +kf5.com +kf911.com +kf9977.com +kfadx.tech +kfang.xin +kfb126.com +kfb163.com +kfcbest.com +kfcdn.com +kfchiheng.com +kfcjrl.com +kfdcc.com +kffone.com +kfganquan.com +kfhome.com +kfhty.com +kfj.cc +kfjd.com +kfjyd.com +kfjyjt.com +kflhgs.com +kfmanager.com +kfqizhongji.com +kfsddj.com +kfskxy.com +kfvcca.com +kfw001.com +kfzdh.com +kfzhinan.com +kfzimg.com +kfzls.com +kg-power.com +kg.com +kghbcn.com +kgimg.com +kgipr.com +kgithub.com +kgnmkj.com +kgogame.com +kgrestrg.com +kgzyy.com +kh-zx.com +kh84.com +khdatasolutions.com +khdyly.com +khfwedu.com +khhospital.com +khidi.com +khlgamen.com +khly.com +khlysc.com +khmhvlw.com +khnhw.com +khotyn.com +khqihuo.com +khruiming.com +khs1994.com +khworidtour.com +khysct.com +ki-pa.com +kiaic.com +kiana.love +kiapmyf.xyz +kibinggroup.com +kicontech.com +kid17.com +kiddopal.com +kidikidi.net +kidsccshow.com +kidscoding8.com +kidsdown.com +kidseq.net +kidsflab.org +kidsfoto.net +kidspsy.com +kidsthomas.com +kidsyun.com +kidulte.com +kidulty.com +kiiik.com +kiijoy.com +kiinii.com +kiiyi.com +kijifept.com +kikiwon.com +kikoplay.fun +kikusuitape.com +kikuu.com +kilamanbo.com +kililife.com +killdb.com +killerheelsphotography.org +kilo1kw.com +kiloai.com +kimberley-technology.com +kimderlite.com +kimi.ai +kimi.com +kimi.link +kimi.pub +kimiss.com +kimiss.net +kimiter.com +kimleo.net +kimqi.net +kimsom.com +kimxz.com +kina.cc +kinbull.com +kindechem.com +kindlelib.com +kindobest.com +kindredous.com +kindsoft.net +king-capital.com +king-rain.com +king-strong.com +kingandkey.com +kingandwood.com +kingarad.com +kingbank.com +kingboritape.com +kingborn.org +kingbos.com +kingbrother.com +kingcheergame.com +kingcloud.com +kingcloudad.com +kingclouddns.com +kingcms.com +kingdaychina.com +kingdee-soft.com +kingdee.com +kingdee.com.tw +kingdee.org +kingdeemall.com +kingdeestar.com +kingdeeyun.com +kingdelgc.com +kingdom-ceramic.com +kingdomfishing.com +kingdomsolar.net +kingdraw.com +kingdun.net +kingexplorer.com +kingfu-china.com +kingfulai.com +kinggoo.com +kinggrid.com +kinghomechina.com +kingidc.net +kinginfo.com +kingjee-tech.com +kingjee.com +kingjin-sh.com +kingkaid.com +kingland119.com +kingleen.net +kingliton.com +kinglory.com +kinglymotor.com +kinglyuan.com +kingmagic.co +kingmagnet.com +kingmb.com +kingmylab.com +kingnare.com +kingnet.com +kingnetdc.com +kingnettech.com +kingoit.com +kingosoft.com +kingpower-cn.com +kingrack.com +kingray-tech.com +kingreader.com +kingrein.com +kingroot.net +kings3d.com +kingsemi.com +kingsh.store +kingshan2002.com +kingsley-cq.com +kingslicer.com +kingsmen-gc.com +kingsoft-office-service.com +kingsoft.com +kingsoft.net +kingsoftstore.com +kingsrich.com +kingst.org +kingstarmedical.com +kingstartech.com +kingston.group +kingstronbio.com +kingsunedu.com +kingsungmedical.com +kingsunpower.com +kingsunsoft.com +kingtaifook.com +kingtroldata.com +kingtysin.com +kingview.com +kingwisoft.com +kingyield.com +kingyon.com +kingyork.com +kingzom.com +kinhom.com +kinhoo.com +kinlong.com +kinpan.com +kinpn.com +kinpoway.com +kinqee.com +kinsec.com +kinte-ind.com +kintiger.com +kintn.com +kintowe.com +kinval.com +kinwong.com +kinzhan.com +kinzoncap.com +kiomodesign.com +kira.cool +kirakuapp.com +kirgen.com +kiriko-china.com +kirin-tech.com +kirincloud.net +kirinmach.com +kirinvm.com +kirkcloud.com +kiscoca.com +kisdee.com +kisence.com +kisilicon.com +kisops.com +kiss998.com +kisskisso.com +kissyj.com +kissyui.com +kiswo.com +kit-lee.me +kitic.net +kitiu.com +kitking.com +kitontech.com +kitstown.com +kitty.su +kituin.fun +kiun24ok.com +kivend.net +kivo.wiki +kiwa-tech.com +kiwenlau.com +kiwifarms.net +kiwifarms.st +kiwimoore.com +kiwisec.com +kiyuu.club +kj-ic.com +kj-pcb.com +kj021.com +kj1d.com +kj2100.com +kj3.com +kj400.com +kj521.com +kjb2c.com +kjcdn.com +kjchina.com +kjchuang.com +kjcity.com +kjcmxx.com +kjcxpp.com +kjcyfz.com +kjdb.org +kjdvsg.com +kjeport.com +kjewryhf.xin +kjfns.com +kjgcl.com +kjghyjy.com +kjhaoyun.com +kjimg.com +kjingbao.com +kjiuye.com +kjjcrm.com +kjjl100.com +kjjxjy.com +kjjxl.com +kjjzm.com +kjkd.com +kjkp.com +kjks.net +kjkxun.com +kjlww.com +kjmofang.com +kjmte.com +kjmti.com +kjpmconsulting.com +kjr365.com +kjrs365.com +kjsdh6.com +kjson.com +kjsv.com +kjt.com +kjtbao.com +kjtianshanxu.com +kjtong.com +kjtpay.com +kjutf-uejfncpo72u.com +kjw.cc +kjwlxt.com +kjwugx.com +kjycx.com +kjyicdn.com +kjykcdn.com +kjyun123.com +kjzhan.com +kjzj.com +kjzx.net +kjzxtk.com +kjzz.streamguys1.com +kk-china.com +kk1.vip +kk169.com +kk18.com +kk1bie336689.com +kk30.com +kk30.net +kk3g.net +kkabc.com +kkapp.com +kkcache.net +kkcapture.com +kkcdn.net +kkcha.com +kkcharge.com +kkcoo.com +kkcursor.com +kkdaxue.com +kkddosdns.com +kkdgroup.com +kkdict.com +kkdnsv1.com +kkdownload.com +kkdzpt.com +kkeji.com +kkexcel.com +kkfesw.com +kkffdns.com +kkfw.net +kkgithub.com +kkguan.com +kkgwy.com +kkh-global.com +kkhaitao.com +kkid.vip +kkidc.com +kkj2.com +kkjiaofei.com +kkjs.tech +kkk5.com +kkkwww.com +kkkxj.com +kklishi.com +kklxj.com +kkmall.org +kkmar.com +kkmh.com +kkmicro.com +kkmop.com +kkong.vip +kkrb.net +kksmg.com +kksofts.com +kkt.com +kktian.com +kktijian.com +kktv1.com +kktv5.com +kktv8.com +kkuryat.com +kkuu.com +kkwafdns.com +kkwan.cc +kkx.net +kkxnb.com +kkxxiazai.com +kkyoo.com +kkyp.shop +kkyuan.com +kkyuedu.com +kkzhan.com +kkzj.com +kkzs.io +kkzycdn.com +kl1l5.com +kl321.com +kl688.com +klandk.com +klbn100.com +klbyjt.com +klchemicals.net +klclear.com +klcsb.com +kldhq.com +klgkm.com +klhpw.com +klhuyan.com +klianfa.com +klicen.com +klingai.com +klinlee.com +klisedu.com +kliwu.com +kljiyou.com +kljtc.com +kllife.com +klmnf.com +klmy118114.com +klmybbs.com +klmymarathon.com +klmyssn.com +klner.com +klniu.com +klpbbs.com +klqcb.com +klqy.com +kltgt.com +kltjn.com +kltong.com +klub11.com +klv5qu.com +klvtu.com +klwxq.com +klx-tech.com +klxksci.com +klxsw.com +klxuexi.com +klyang.com +klzhlogistics.com +km.com +km10z.net +km169.net +km18.net +km1818.com +km28.com +km5858.com +km8z.net +kmail.com +kmaoxx.com +kmapp.net +kmbbs.com +kmbdqn.com +kmcha.com +kmcits.com +kmcits0716.com +kmcsg.com +kmcxedu.com +kmcxg.com +kmcz365.com +kmd8888.com +kmdctz.com +kmdcwt.com +kmdn.net +kmdns.net +kmeecc.com +kmeila.com +kmeitu.com +kmf.com +kmfengli.com +kmg-jd.com +kmgdgs.com +kmguolv.com +kmgybsr.com +kmhpc.net +kmhwtz.com +kmjt.net +kmlcl.com +kmlhh.com +kmljexb.xyz +kmmama.com +kmmdkj.com +kmoe0.com +kmplayercn.com +kmpwgxzy.com +kmqcwx.com +kmqsaq.com +kmread.com +kmrfidtag.com +kmrijie.com +kmron.com +kms.pub +kmssgd.com +kmsz.net +kmszy.com +kmteruite.com +kmthy.com +kmtlbj.com +kmtlfckyy.com +kmtrh.org +kmtxzs.com +kmvtc.net +kmvxwedy.com +kmw.cc +kmw.com +kmwatersupply.com +kmway.com +kmwx.net +kmxkh.com +kmxyj.com +kmy100.com +kmyanyou.com +kmyestar.com +kmykt.com +kmyzzx.com +kmzhihuitong.com +kmzp.com +kmzscc.com +kmzx.com +kmzx.org +kn-light.com +kn-nanjing.com +kn0sky.com +kn120.com +knbmotor.com +knewbi.com +knewone.com +knewsmart.com +knfeco.com +knight-un.com +knightedge.com +knightli.com +kninebox.com +knj-nanjing.com +knn-nj.com +knnnd.com +knockdream.com +knotesapp.com +know-act.com +know88.com +knowapartments.com +knowfashionstyle.com +knowhowedu.com +knowingclouds.com +knowingcloudvip.com +knowingyun.com +knowledgedp.com +knowledgu.com +knowlink-assets.com +knownpcb.com +knownsec.com +knowsafe.com +knowsurface.com +knowyourself.cc +knoya.com +knscq.com +knsheng.com +knsyxw.com +knt-nj.com +kntc.win +kntn.tech +knvps.com +knxchina.org +knzlcq.com +ko0.com +koagzrxt.com +koal.com +koalacam.net +koalareading.com +koalasolo.com +koba8.com +kobeandkdshoes.com +kobelco-zh.com +kobox.tv +kocla.com +kodcloud.com +koderover.com +kodmp.com +koenli.com +kof-kol.club +kofficemart.com +kofuf.com +kofunion.net +kogfc.net +kohergroup.com +koiclub.net +koikreative.com +koinocn.com +koioawq.com +kojihjnklka.asia +kojtech.com +kok.plus +kokophp.com +kolarmy888.com +kolcc.com +kole8.com +kolemay.com +kolleracademy.com +kolrank.com +kolstore.com +kolyun.com +komect.com +kometo.com +kompasszdcom.site +konami.cc +koncoo.com +konekomoe.com +konfan.net +kongai.org +kongao.com +kongapi.com +kongbugushi.com +kongdao.com +kongduan.com +kongfz.com +kongge.com +kongjianjia.com +kongjibusiness.com +kongjie.com +kongjieshijie.com +kongjitang.com +kongjun.com +kongkangroup.com +konglei.com +konglonggu.com +kongming-inc.com +kongqinengrebeng.com +kongquecheng.com +kongqueyuzd.cc +kongrong.com +kongtiao163.com +kongtiao365.com +kongwu2022.com +kongzhi.net +kongzhiji.com +kongzhong.com +konka.com +konkamobile.com +konkasnow.com +konkek2.com +konlan.com +konotaku.com +kooaoo.com +koobeemobile.com +koobone.com +koocdn.com +kooci.net +koodi98.com +koofang.com +koofun.com +koogua.com +kook.vip +kookong.com +koolcenter.com +kooldns.com +koolearn.com +koolproxy.com +koolyun.com +koomao.com +koopass.com +koorun.com +kooshui.com +kooteam.com +koovin.com +kooxoo.com +kopebe.com +kopisee.com +kopitokein.com +kopiurerolex.com +koplayer.com +kopperchem.com +koreabt.com +koreaxin.com +koreaxing.com +korirl.com +kormee.com +kornsweets.com +koronsoft.com +korosensei.com +korqqr1l13.com +korrun.com +kortatb.com +kortrong.com +kotaqkew.com +kotei-info.com +kotoo.com +kotoyoshi.com +koubei.com +koubeikc.com +koucai.com +kouchouwang.net +koudai.com +koudai8.com +koudaigou.net +koudaili.com +koudaionline.com +koudaionline.net +koudaitiku.com +koudaitong.com +koudashijie.com +kouer.com +kouer.net +kougukougu.work +kouhao8.com +koukao.net +koukao.org +kouke5.com +koukoutu.com +koukuko.com +koumakan.cc +kouqiangba.com +koushare.com +kouss.com +kouxin.com +kouxin.net +kouyijia.com +kouyu100.com +kouzi.com +kovemoto.com +kowa-dental.com +kowa103.com +kowloonhospital.com +koyuki.cc +koz.moe +kpblw.com +kpbs-wowza.streamguys1.com +kpbyd.com +kpdhk.com +kpfans.com +kpfcw.com +kphm88.com +kphwchem.com +kpjushi.com +kpkpw.com +kplanet.vip +kpmqg.com +kpoll.net +kppcsem.com +kprepublic.com +kpt5.com +kptour.com +kpwcmb.com +kpxmsbtw.com +kpyy239.com +kpyy258.com +kpzip.com +kpzip.net +kpzpw.com +kpzs.com +kpzuan.com +kq-cnmia.com +kq36.com +kq39.com +kq520.net +kq7.com +kq81.com +kq88.com +kqalevel.com +kqapi.com +kqgeo.com +kqgyl.com +kqj123.com +kqjtj.com +kqjtj.net +kqlink.com +kqmmm.com +kqopg.app +kqpgstxx.com +kqqy.com +kqw.com +kqwh231122.com +kqwlxxjs.com +kqzlzx.com +kqzp.net +kr-cell.com +kr-tencentclb.cloud +kr-tencentclb.com +kr-tencentclb.net +kr-tencentclb.work +kr.com +kr126.com +kra-5at.com +krahag.com +krak12.com +kraken30.com +krbk.com +krd168.com +krdrama.com +krenzheng.com +kridol.com +krioqxi.com +kriszhang.com +krones-group.com +krones.com +krpano.tech +krqcitie.com +krszf.com +krtdl.com +krxz.com +krzb.net +krzwymfr.com +krzzjn.com +ks-cdn.com +ks-cdn1.com +ks-cdnv6.com +ks-fag.com +ks-live.com +ks-spring.com +ks-terminals.com +ks-wg.com +ks1688.com +ks321.com +ks365.org +ks5.uno +ks51.com +ks5u.com +ksair.com.tw +ksapisrv.com +ksbao.cc +ksbao.com +ksbbs.com +ksbm.com +ksc-test.com +kscac.com +kscbigdata.cloud +kscbpkf.com +kscdns.com +kschuangku.com +kscloudapi.com +ksco.cc +kscord.com +ksdedu.com +ksdhgy.com +ksdown.com +ksecit.com +ksedt.com +kseibitools.com +ksense.com +ksfang.com +ksgnr.com +kshahn.com +kshaoteng.com +kshfgf.com +kshjn.com +kshot.com +kshot.net +kshtxf.com +kshuwx.com +kshwtj.com +ksjgs.com +ksjhaoka.com +ksjxgs.com +kslccb.com +kslyt.com +ksmend.com +ksmiai.com +ksmingl.com +ksmjmj.com +ksmmed.com +ksmobile.com +ksmobile.net +ksmq5a9kxzmr.com +ksn-cinfo.geoksn.kaspersky.com +ksn-crypto-wifiplus.geoksn.kaspersky.com +ksn-dc1-cert.geoksn.kaspersky.com +ksn-dc1-file.geoksn.kaspersky.com +ksn-dc1.geoksn.kaspersky.com +ksn-file.geoksn.kaspersky.com +ksn-info.geoksn.kaspersky.com +ksn-kas.geoksn.kaspersky.com +ksn-mdr.geoksn.kaspersky.com +ksn-tcert.geoksn.kaspersky.com +ksn-url.geoksn.kaspersky.com +ksn-verdict.geoksn.kaspersky.com +ksndsa.com +ksnows.com +ksoapp.com +ksokay.com +ksops.com +ksord.com +ksosoft.com +kspays.com +kspeeder.com +kspkg.com +ksrc001.com +ksren.com +ksrenfan.com +ksria.com +ksrmtzx.com +ksrmyy.org +ksruanjian.com +kss4.com +kssip.msi.com +kssjkj.com +ksslxh.com +kst-cn.com +kst100.com +kst365.com +kstao.com +kstengcai.com +kstnjscl.com +kstore.space +kstore.vip +kstv.com +ksupdate.com +ksust.com +kswcd.com +kswxjnjs.com +ksx88.com +ksxfgc.com +ksxianda.com +ksydns.com +ksydx.com +ksyiqiwan.com +ksyll.com +ksyna.com +ksyun.com +ksyun.net +ksyunad.com +ksyuncdn-k1.com +ksyuncdn-k2.com +ksyuncdn.com +ksyuncdnv6.com +ksyuncs.com +ksyungslb.com +ksyungslb2.com +ksyunv5.com +ksyunv6.com +ksyunv7.com +ksyunwaf.com +ksyxmc.com +kszhuanjia.com +kszlzz.com +kszpw.com +kszxzsxh.com +kt007.com +kt10000.com +kt286.com +kt40.com +kt5u.com +ktallong.com +ktang1.com +ktazg.com +ktbiao.com +ktc-med.com +ktcomposite.com +ktctjt.com +ktcupdate.com +kting.info +ktkt.com +ktlshu.vip +ktlstbg.com +ktmap.com +ktmv.com +ktmwan.net +ktovztie.com +ktplay.com +ktq8e0zm.work +ktrcn.com +ktrlight.com +ktstny.com +ktswjt.com +ktt-automation.com +ktu56.com +ktuner.store +ktv.com +ktvc8.com +ktvdaren.com +ktvme.com +ktvsky.com +ktwap.net +ktxuexi.com +ktyunlianjie.com +ku25.com +ku33a.net +ku6.net +ku6cdn.com +ku6img.com +ku6vms.com +ku82.com +ku90.com +ku968.com +ku987.com +kua365.com +kuaaa.com +kuabaobao.com +kuadu.com +kuafuai.net +kuai-fei.com +kuai-ying.com +kuai.ma +kuai65.com +kuai666aa8e43gomqhzeg.com +kuai666bj7tu65rkdz82.com +kuai666bjeve6ks43qyw4vc8.com +kuai666bjs3gsymi6v4h5pz.com +kuai666e9rqs5wumk7at3.com +kuai666gki3osg54rx7a.com +kuai666gkq3semv1r34.com +kuai666i4rmp7c5i16hb.com +kuai666kysktrxmwici27.com +kuai666m6vgmorxw77vb5.com +kuai666ogv754urmpb4.com +kuai666trqtauks5ht6x.com +kuai666vs5aq9o3ytdgp.com +kuai7.com +kuai8.com +kuaiads.com +kuaiapps.com +kuaibaobei.com +kuaibiao2000.com +kuaicad.com +kuaicha365.com +kuaicha888.com +kuaichala.com +kuaichale.com +kuaidadi.com +kuaidaili.com +kuaidi.com +kuaidi100.com +kuaidi321.com +kuaidihe.com +kuaidihelp.com +kuaidihome.com +kuaidilab.com +kuaidim.com +kuaidizs.com +kuaiduizuoye.com +kuaiduwen.com +kuaiex.com +kuaifaka.com +kuaifaka.net +kuaifan.shop +kuaifawu.com +kuaifeng.com +kuaifuinfo.com +kuaigames.com +kuaigeng.com +kuaigou.co +kuaiguohui.com +kuaih5.com +kuaihaodai.com +kuaihecaishui.com +kuaihou.com +kuaihuoyun.com +kuaihz.com +kuaiji.com +kuaiji.so +kuaiji521.com +kuaiji66.com +kuaijianji.com +kuaijiepaotui.com +kuaijilunwen.com +kuaijinniu.com +kuaijipeixunlg.com +kuaijishizi.com +kuaijisishu.com +kuaijitong.com +kuaijizheng365.com +kuaikan.ink +kuaikanad.com +kuaikanmanhua.com +kuaikao.com +kuaikaoti.com +kuaikuaicloud.com +kuaila.com +kuailails.com +kuailaiwz.com +kuaile-u.com +kuaile8.com +kuaile800.com +kuailedo.com +kuailekaishi.com +kuailelunwen.com +kuailepipixia.com +kuailetongyao.com +kuailexs.com +kuailexue.com +kuailezu.com +kuailiyu.com +kuailiyu.net +kuailon.com +kuailvzaixian.com +kuaimai.com +kuaimi.com +kuaimi.net +kuaiming.com +kuaipandata.com +kuaipao.run +kuaipao8.com +kuaipianer.com +kuaipin.work +kuaipiyun.com +kuaipng.com +kuaiqi.net +kuaiqikan.com +kuaiqin.com +kuaiqushuiyin.com +kuairen88.com +kuaishangkf.com +kuaishebao.com +kuaishiedu.com +kuaishou-gz.com +kuaishou.com +kuaishouapp.com +kuaishouapp.net +kuaishouapps.com +kuaishouba.com +kuaishougroup.com +kuaishoupay.com +kuaishuru.net +kuaisu.com +kuaisushu-cnd.com +kuaisuyun.com +kuaitijian.com +kuaitouad.com +kuaitu.cc +kuaitu666.com +kuaitui365.com +kuaiwan.com +kuaiwenyun.com +kuaixiazai.com +kuaixue.com +kuaiyan.com +kuaiyankanshu.org +kuaiyiad.com +kuaiyilicai.com +kuaiyingxiao88.com +kuaiyingyong.vip +kuaiyizu.net +kuaiyong.com +kuaiyoujia.com +kuaiyouxi.com +kuaiyuepu.com +kuaiyugo.com +kuaiyunds.com +kuaizhan.com +kuaizhang.com +kuaizhaogong.com +kuaizhe.com +kuaizhihui.com +kuaizhou123.com +kuaizi.co +kuaizitech.net +kuaizupu.com +kuaizy.com +kuajing.com +kuajing.hk +kuajing84.com +kuajingketang.cc +kuajingmaihuo.com +kuajingnet.com +kuajingvs.com +kuajingx.com +kuajingyan.com +kuajingyang.com +kuajingzhushou.com +kuajinzhifu.com +kuakao.com +kuakao.net +kuake8.com +kuaming.com +kuandaige.com +kuanfans.com +kuanff.com +kuanfutong.com +kuang-chi.com +kuang-chi.org +kuangchan.biz +kuangdacn.com +kuangdi.com +kuangjijia.com +kuangjiwan.com +kuangmaidz.com +kuangming.com +kuangshitech.com +kuangshun.com +kuangxiangit.com +kuangyeyuan.com +kuangyi.com +kuangyuantrade.com +kuanhuacheng.com +kuanye.net +kuark.com +kuashou.com +kuayuegroup.com +kubercloud.com +kubesre.xyz +kubey.cc +kubikeji.com +kuboluo.com +kuche.com +kuchechina.com +kuchuan.com +kucoin-in.work +kucunguanli.online +kudapp.com +kudianvip.com +kudiaoyu.com +kudingyu.com +kudou.org +kuems.com +kufangwuyou.com +kufaxian.com +kufei.com +kuge.cc +kugoo.com +kugou.com +kugou.la +kugou.net +kugouaudio.com +kugouipv6.com +kugoukid.com +kugouliveshow.com +kugouringtone.com +kugousenior.com +kugoustore.com +kugouvoice.com +kugouyouth.com +kuguanyi.com +kugz.com +kuhao360.com +kuhii.com +kuhimalayandp.com +kuicc.com +kuigkj.com +kuihe.com +kuihuakeji.com +kuihuayaoye.com +kuihuo.com +kuike.ltd +kuiniuca.com +kuishiba.com +kujiale.com +kujiang.com +kujiang.net +kuka-xj.com +kuka001.com +kukagroup.com +kukahome.com +kukankeji.com +kukasofa.com +kuke.com +kuke99.com +kukecloud.com +kukseo.com +kuku123.com +kukuda.net +kukulv.com +kukupig.com +kukushouhou.com +kukushow.com +kukushu.com +kukuspeak.com +kukuw.com +kukuxiu.com +kuledushu.com +kuleiman.com +kulekeji.com +kulemi.com +kulengvps.com +kuletco.com +kuli.ren +kuliwang.net +kuman.com +kumanju.com +kumao.vip +kumaoyun.com +kumeiwp.com +kumhosunny.com +kumi.com +kumiao.com +kumiao.tv +kumiao.vip +kumifeng.com +kun-pharm.com +kun66.xyz +kunchuang.com +kunduo.com +kungfucloud.com +kungfuenglish.com +kunguankeji.com +kunguanyx.net +kunjuke.com +kunkkawu.com +kunkundev.com +kunkunyu.com +kunlexf.com +kunlunaq.com +kunlunar.com +kunlunca.com +kunluncan.com +kunlunce.com +kunlundns.com +kunlunea.com +kunlungem.com +kunlunger.com +kunlungr.com +kunlunhuf.com +kunlunjk.com +kunlunjue.com +kunlunjyk.com +kunlunle.com +kunlunli.com +kunlunno.com +kunlunpi.com +kunlunra.com +kunlunsa.com +kunlunsc.com +kunlunsl.com +kunlunso.com +kunlunta.com +kunlunvi.com +kunlunwe.com +kunlunxin.com +kunlunyb.com +kunmingbc.com +kunmingguolv.net +kunmingkanghui.com +kunpengkg.com +kunpengtn.com +kunpo.cc +kunruijs.com +kunshandx.com +kunst-x.com +kuntaihotel.com +kuntin.com +kunyamedical.com +kuo-yi.com +kuobuy.com +kuocaicdn.com +kuocaidns.com +kuocaiyun.com +kuoo8.com +kuosheng.com +kuosheng.net +kuotu.com +kuozang.com +kuozhan.net +kupaisky.com +kupan.cc +kupao.com +kuqin.com +kuraboshanghai.com +kureader.com +kurobbs.com +kurogame-service.com +kurogame-service.xyz +kurogame.com +kurogame.net +kurogame.xyz +kurogames-ads.com +kurogames-global.com +kurogames.com +kurokingdom.com +kuroko.info +kurtizanki-spb.com +kurz-sh.com +kusdk.com +kusen888.com +kushe.net +kushouwang.net +kushuzw.com +kusnc17.com +kuso.xyz +kusouji.com +kut-hls.streamguys1.com +kut3974vc.com +kutianxia.com +kutianxia.net +kutinai.com +kutj.com +kutongji.com +kutuan.com +kuuke.com +kuvun.com +kuwan8.com +kuwanapp.com +kuwanbang.com +kuwanjitar.com +kuwen.net +kuwuu.com +kuwwz.com +kuxi100.com +kuxiaoji.com +kuxiaomiao.com +kuxiaomiao.net +kuxiaoshuo.com +kuxiaozhu.com +kuxiuktv.com +kuxueedu.com +kuy8.com +kuyh.com +kuyibu.com +kuyin123.com +kuyinxiu.com +kuyinxiuxiu.com +kuyinyun.com +kuyiso.com +kuyiyun.com +kuyoo.com +kuyouyun.com +kuyumall.com +kuyunbo.club +kuzhange.com +kuzhazha.com +kuzhengame.com +kuzu.com +kv-kva.com +kv6om4zs5i47.com +kvamerfx.com +kvenjoy.com +kviso.com +kvogues.com +kvov.com +kvps85.com +kvrmicit.com +kw007.com +kwai-group.com +kwai-pro.com +kwai.com +kwai.net +kwai.xyz +kwai666.com +kwaiadapp.com +kwaiads.com +kwaibusiness.com +kwaicdn.com +kwaicdnx.com +kwaie65eu4gvs1943.com +kwaiekow98icxsp7fz.com +kwaiesovc9xgzfcmt.com +kwaigobuy.com +kwaigroup.com +kwailai.com +kwailala.com +kwailbs.com +kwailine.com +kwailocallife.com +kwailocation.com +kwaim.com +kwairga8upiycbiv.com +kwairia4qs5e76v52z.com +kwairpoewaum3s9z41.com +kwairr9aw56vso581r.com +kwairtc.com +kwaisczway7r4tz7m8.com +kwaiselfcdn.com +kwaishop.com +kwaishouapp.com +kwaishouapp.net +kwaitalk.com +kwaitv.com +kwaiww7t3qi8x217.com +kwaixiaodian.com +kwaiying.com +kwaiymx64war5a7f.com +kwaizt.com +kwangfeng.com +kwggroupholdings.com +kwicdn.com +kwimgs.com +kwinbon.com +kwise-log.com +kwkf.com +kwmu-flash.streamguys1.com +kwniu.com +kwong-tech.com +kws123.com +kwt56.com +kwtgs.com +kwtzn.com +kwudor.com +kwwblcj.com +kwx.gd +kwxcj.com +kwxjh.net +kwxpobrw.com +kx-turbo.com +kx001.com +kx139.com +kx1978.com +kx1d.com +kx778.com +kx7p.com +kxapps.com +kxb100.com +kxbox.com +kxccjjt.com +kxceping.com +kxcq.com +kxdaili.com +kxdao.com +kxdao.org +kxdpm.com +kxdw.com +kxiaoshuo77.com +kxinyk.com +kxji.com +kxjlzx.com +kxjsys.com +kxkzrcke.com +kxl100.com +kxlc.com +kxll.com +kxload.com +kxmas.com +kxmrg.com +kxoalq.com +kxow.com +kxparking.com +kxphy.com +kxq520.com +kxqo2ev.com +kxscience.com +kxstykrgx8z3.com +kxt.com +kxtjt.com +kxtoo.com +kxtui.com +kxtwz.com +kxue.com +kxwell.com +kxx2.com +kxxsc.com +kxxxl.com +kxyyf.com +ky-express.com +ky.cc +ky.live +ky393834.com +ky5yx.com +ky6yx.com +ky7yx.com +ky958.com +kybapp.com +kybapp.net +kybcrm.com +kybimg.com +kyboye.com +kybyun.com +kych5.com +kydbp.com +kydev.net +kydl308015.vip +kydl308029.vip +kydzfl.com +kye-erp.com +kye.vip +kyec.cc +kyedu.cc +kyemall.com +kyfey.com +kygroup.ltd +kygso.com +kyhtech.com +kyhyxy.com +kyj168.com +kyjlhz.com +kyjxy.com +kyk.cc +kykjgroup.com +kylc.com +kyleduo.com +kyligence.io +kylin-os.com +kylinlot.com +kylinmobi.com +kylinos.com +kylinpet.com +kylpharm.com +kymjs.com +kyo.hk +kyoceraconnect.com +kyppt.com +kyrcw.com +kysjhx.com +kyslb.com +kysnxt.com +kysygs.com +kytijian.com +kyubwsx1g5.com +kyuedu.com +kyv5.com +kyvipw.org +kyw4y0s.com +kywiremesh.com +kyxdloan.com +kyxh.com +kyxsw.org +kyy6.com +kyzhpt.com +kyzs.com +kyzyj.com +kz.cc +kz321.com +kzcpm.com +kzgui.com +kzk1.com +kzmyhome.com +kzo.moe +kzrcw.com +kzread.com +kzrqicae.com +kzryu.xyz +kztsjj.com +kzwr.com +kzwx.net +kzyzz.com +l-zb.com +l.biz +l069.com +l178.info +l1yu.com +l2cn.com +l2h.site +l2t7.cc +l2z4l.net +l3gt9.com +l68.net +l6qmpykq.work +l799vk4qe2.com +l7audiolab.com +l85r.com +l99.com +la-bbs.net +la-chinata.hk +la-mo.com +la-technology.com +la31.com +laawoo.com +lab-bst.com +lab-easttitan.com +lab-rm.com +lab-z.com +labaoxian.com +labbang.com +labbase.net +labbuy.net +label-printing-factory.com +labgogo.com +labi.com +labisart.com +labixiao.xin +labno3.com +labuladong.online +labview.help +labxing.com +labzj.com +lacaoshi.com +lacesar.com +lackeeden.com +lacngs.com +lacocrea.com +ladiyoga.com +ladjzs.com +lady361.com +lady75.com +lady8844.com +ladybirdedu.com +ladydaily.com +ladyhua.com +ladyol.com +ladyw.com +ladyw.net +laecloud.com +laey.net +laf.run +lafaso.com +lafayettewines.com +lafy.org +lafybjy.com +lagou.com +lagouevents.com +lagoujobs.com +laguaba.com +laguke.com +lahuashanbx.com +lahuolaozao.com +lai-ai.com +laianbbs.com +laiba.shop +laibafu.com +laibeiparking.com +laibokeji.com +laibot.com +laichon.com +laichou.com +laichuanfeng.com +laidacai.com +laidazi.com +laidingba.com +laidudu.com +laifen.net +laifeng.com +laifeng.net +laifenqi.com +laifu.net +laigame7.net +laigaokao.com +laigong.com +laihua.com +laijiawen.com +laijishaofang.com +laijuba.com +laikan.com +laikanxia.com +laikanxing.com +laikanxs.com +laike.net +laikeerp.com +laiketui.com +lailaieshop.com +lailaihui.com +lailibai.com +lailin.xyz +lailinzhihui.com +lailook.net +laima-tech.com +laimaidi.com +lainse.store +lainzy.net +laipei.net +laiqi.net +laiqm.com +laiqukankan.com +laiqy.com +laird-tek.com +laisai.com +laishui.info +laisizuji.com +laisj.com +laitelaide.com +laituia.com +laituijian.net +laiwang.com +laiwo.com +laiwu.net +laiwuyizhong.com +laixi.com +laixiangzuji.com +laixindianzi.com +laixiukeji.com +laixs.com +laixueedu.com +laixuexi.cc +laiyagushi.com +laiye.com +laiyifen.com +laiyincat.com +laiyouhui.net +laiyouxi.com +laiytech.com +laiyu.com +laizee.com +laizhouba.com +laizhouba.net +laizhoujob.com +laizi.net +lajoson.com +lakala.com +lakecn.com +lakeregionfitness.com +lakwdian.com +lalaba.com +lalaedu.com +lalavision.com +lalawaimai.com +lalkk.com +lamahui.com +lamaison-arting.com +lamall.com +lambda.hk +lamborlogistics.com +lameixs.com +lamiu.com +lamost.org +lamoton.com +lampbi.com +lampouomo.com +lamuba.com +lamyu.com +lan-bridge.com +lan-lin.com +lan-ning.com +lan1001.com +lanall.com +lanapartments.com +lanbenjia.com +lanbing510.info +lanbinimall.com +lanbts.com +lanbula.com +lancdn.com +lancecity.net +lancern.xyz +lanchenglv.com +lanchuanhuanbao.com +lancn.net +lancome-beauty.com +lancong.net +lanconvey.com +lancunwater.com +lancygroup.com +land136.com +landa-solenoid.com +landai.com +landaiwood.com +landbond.com +landbridge.com +landchina.com +landed.cc +landhonor.com +landi.com +landian.vip +landian.xyz +landiannews.com +landing-med.com +landingbj.com +landintheair.com +landitrip.com +landizs.com +landjs.com +landmedium.com +landong.com +landraco.com +landray.com +landroads.com +landscape.vip +landscapek.com +landspace.com +landtu.com +landui.com +landuicdn.com +landuncn.com +landunxiaofang.com +landwind.com +landzestate.com +landzg.com +landzy.com +lanecn.com +lanfanapp.com +lanfc.com +lanfcw.com +lanfeicastle.com +lanfeitech.com +lanfeiwine.com +lanfeng.net +lanfucai.com +lanfucaijing.com +lanfw.com +lang8.net +langan-group.com +langao.com +langchao.com +langchaosh.com +langchi.com +langduqi.com +langemedtech.com +langfang.com +langfang12345.com +langfangfc.com +langfly.com +langgine.com +langhao-medical-platform.com +langhuansoft.net +langjian.work +langkaiwenhua.com +langkawipower.com +langke.com +langke.tv +langkoo.com +langkun.com +langlangjiajiao.com +langlangy.com +langlib.com +langlive.com +langmanzg.com +langqing.club +langren001.com +langren8.com +langrencard.com +langrenclub.com +langrensha.net +langruiyun.com +langsajiasi.com +langsong.site +langtao.cc +langtaojin.com +langtongpos.com +languageclass.cc +languang.com +languershiton.com +langukeji.com +langwei.net +langxi.org +langxi.xyz +langxingys.com +langxiyuyou.com +langyintech.com +langzezs.com +lanh.love +lanhanba.net +lanhao.name +lanhu.com +lanhuajituan.com +lanhuapp.com +lanhuasoft.com +lanhuhu.com +lanhui.com +lanin.tech +lanindex.com +lanjie100.com +lanjie520.com +lanjing.vip +lanjingads.com +lanjinger.com +lanjingerp.com +lanjingfm.com +lanjingmembrane.com +lanjings.com +lanjingtmt.com +lanjingzf.com +lankecloud.com +lankeji.com +lanlanlife.com +lanlanwork.com +lanlinghospital.com +lanlingtuliao.com +lanlnk.com +lanlv.com +lanmaiedu.com +lanmao.com +lanmaokeji.com +lanmaos.com +lanmicloud.com +lanmit.com +lanmiyun.com +lanniuh.com +lanniuyun.com +lanohotel.com +lanosso.com +lanou3g.com +lanovamedicines.com +lanpiankeji.com +lanpuele.com +lanpv.com +lanpw.com +lanpye.com +lanqb.com +lanqi.com +lanqibing.com +lanqingkeji.com +lanqiudi.com +lanrar.com +lanree.com +lanreelh.com +lanrenbijia.com +lanrenclub.com +lanrenexcel.com +lanrenmb.com +lanrents.com +lanrentuku.com +lanrenzhaofang.com +lanrenzhijia.com +lanrenzhoumo.com +lanruitech.com +lansancn.com +lanscn.com +lansedir.com +lansedongli.com +lanshan.com +lanshanae.com +lanshanweb.com +lanshauk.com +lanshenniao.com +lanshizi.com +lanshou.net +lansors.com +lansscl.com +lansun-pumps.com +lansurcn.com +lantiangufen.com +lantianyu.net +lantinglou.com +lantumap.com +lantushiji.com +lanuss.com +lanvote.com +lanwa.net +lanwei.org +lanwoncloudfilm.com +lanwuzhe.com +lanxinbase.com +lanxincn.com +lanxincomputing.com +lanxing123.com +lanxiniu.com +lanxiongsports.com +lanxixiaowu.com +lanxum.com +lanyaa.com +lanying.site +lanyingwang.com +lanyu.net +lanyue.com +lanyun.net +lanyunbrand.com +lanyunbusiness.com +lanyuncloud.com +lanyuncms.com +lanyunone.com +lanyusf.com +lanzchina.com +lanzhouvw.com +lanzhuwh.com +lanzn.com +lanzog.com +lanzong6.com +lanzou.com +lanzoub.com +lanzouc.com +lanzoue.com +lanzouf.com +lanzoug.com +lanzouh.com +lanzoui.com +lanzouj.com +lanzouk.com +lanzoul.com +lanzoum.com +lanzouo.com +lanzoup.com +lanzouq.com +lanzous.com +lanzout.com +lanzouu.com +lanzouv.com +lanzouw.com +lanzoux.com +lanzouy.com +lanzov.com +lanzun.net +lanzv.com +lao.si +laobaicai.net +laobaigan-hs.com +laoban100.com +laobandq.com +laobanfa.com +laobangban.com +laobanmail.com +laobi.icu +laobinggun.com +laobingmi.com +laobuxie.com +laocen.com +laodao.cc +laodaoyun.com +laodong.me +laodong66.com +laodongfa.com +laoduo.net +laoduzhe.com +laoevisa.gov.la +laofengwei.com +laofu.online +laofuzhou.net +laoge.xyz +laogongshuo.com +laogu.cc +laogu.com +laohaoren.com +laohu.com +laohu8.com +laohuabao.com +laohuangli.net +laohucaijing.com +laohuyun.com +laojiuxitong.com +laojuhui.com +laoke.com +laolai.com +laolaishou.com +laolaomiyou.com +laoliang.net +laoliboke.com +laolieren.com +laolieren.shop +laoliuceping.com +laoma.cc +laomaoniu.com +laomaotao.org +laomaotaopan.com +laomatou.com +laomo.me +laomoe.com +laomu.net +laonanren.cc +laonian100.com +laoniushuju.com +laopao.org +laoqiange.club +laoqianzhuang.com +laoren.com +laosiji.com +laosunit.com +laotiaomao.com +laowalens.com +laowuxx.com +laoxiangji.com +laoxianhui.com +laoxiezi.com +laoxuean.com +laoxuehost.com +laoxuehost.net +laoxuezhuji.com +laoy.net +laoyancheng.com +laoyaoba.com +laoyi0773.com +laoyoujiaju.com +laoyouyun.com +laoyouzhibo.com +laoyuanji.com +laoyuegou.com +laoyuge.com +laozhaopian5.com +laozicloud.com +laozu.com +laozuo.org +lapc.cc +lapin365.com +laplace-semi.com +lapostea.cfd +lapulace.com +laravel-admin.org +laravelacademy.org +larenla.com +large.net +lark-passport-qa-sg.net +larkapp.com +larkcloud.com +larkcloud.net +larkfn.com +larkoffice.com +larkofficeapp-boe.com +larkofficeapp-pre.com +larkofficeapp.com +larkofficeboe.com +larkofficecdn.com +larkofficeimg.com +larkofficepkg.com +larkofficepre.com +larkroad.com +larksuite.com +larksuitecdn.com +larksuiteimg-boe.com +larksuiteimg-pre.com +larkworld.com +larmace.com +larryms.com +larscheng.com +larsonlimited.com +laruence.com +lasashengdi.com +laschina.org +lascn.net +laserfair.com +laserjg.com +lashou.com +lasji.net +lasmasas.com +last2win.com +lastdream.net +lastline.tech +lategege.com +latepost.com +latexeasy.com +latexlive.com +latexstudio.net +latin100.com +latinhui.com +latitudeda.com +lattebank.com +lattecake.com +lattefinance.com +lattice.vip +laungee.com +laurelfilms.com +lauyoo.com +lavago.com +lavandehotels.com +lavapm.com +lavaradio.com +lavdrzv.xyz +law-lib.com +law-star.com +law-wei.com +law01.net +law6888.com +lawasst.com +lawaxi.net +lawbang.com +lawbridge.org +lawbus.net +lawen.org +lawen2.org +lawh.fun +lawinfochina.com +lawipcompass.com +lawke.com +lawlawing.com +lawlh1688.com +lawlingyun.com +lawnewscn.com +lawparks.com +lawrencetsui.com +lawsdata.com +lawtimeimg.com +lawugu.com +lawxin.com +lawxp.com +lawyee.com +lawyee.net +lawyee.org +lawyer186.com +lawyerbridge.com +lawyerchina.org +lawyermr.com +lawyerpass.com +lawyershanghai.net +lax-pro.com +laxarq.com +laxmok.com +layaair.com +layabox.com +layinfo.com +layleen.com +laymauchina.com +layoutad.com +laysky.com +layui.com +layuicdn.com +layz.net +lazada.co.id +lazada.co.th +lazada.com +lazada.com.my +lazada.com.ph +lazada.sg +lazada.vn +lazcdn.com +laze.cc +lazyaudio.com +lazybios.com +lazycat.cloud +lazycatmicroserver.com +lazycomposer.com +lazydim.com +lazyer.net +lazymap.com +lazyren.com +lazystones.com +lb-yz.com +lb.streaming.sk +lb0398.com +lb5.com +lb54hon504ke.com +lbbb.cc +lbbee.com +lbbniu.com +lbctjt.com +lbctrl.com +lbd-group.com +lbd99.com +lbddd.com +lbdj.com +lbedu.com +lbesec.com +lbexps.com +lbf123.com +lbgold.com +lbgoo.com +lbgttc.com +lbhdbl.com +lbhgle.com +lbinin.com +lbjljc.com +lbjn.cc +lbjsfz.com +lbjtjt.com +lbkaiguan.com +lbkrs.com +lbmobi.com +lbrencai.com +lbsdermyy.com +lbsdmy.com +lbsrmyy.com +lbswjt.com +lbszx.com +lbtek.com +lbtp.com +lbu.cc +lbv1.com +lbwbw.com +lbx777.com +lbx777.net +lbxcn.com +lbxcrmyy.com +lbxdrugs.com +lbxdyfgx.com +lbxjkyf.com +lbycwx.com +lbyeyaji.com +lbyq.com +lbysgz.com +lbzuo.com +lc-cn-e1-shared.com +lc-cn-n1-ayaqc.com +lc-cn-n1-npxfk.com +lc-cn-n1-shared.com +lc-cn-n1-thovg.com +lc-led.net +lc-news.com +lc-rc.com +lc044.love +lc1001.com +lc123.net +lc1618.com +lc365.net +lc787.com +lcang.com +lcatgame.com +lcayun.com +lcbdf.net +lcboai.com +lcbtv.com +lccareer.com +lccdn.net +lcchem.com +lcchgg.com +lccmw.com +lccyy.com +lccz.com +lcddjm.com +lcdhome.net +lcdtz.com +lcdushi.com +lcdwiki.com +lcdzsww.com +lcenn.com +lcfby.com +lcfcw.com +lcfgjs.com +lcfile.com +lcftech.com +lcfw.co +lcgdbzz.org +lcgjcj.com +lcgod.com +lchdf.work +lchfunv.xyz +lchot.com +lchzzs.com +lcisb.com +lciuyou.com +lcjh.com +lcjrfg.com +lcjxj.com +lcjyg.com +lckeshun.com +lckfb.com +lckiss.com +lcloudcdn.com +lcmack.com +lcmhbl.com +lcmpn.com +lcnichia.com +lcofjp.com +lcofo.com +lcoss.com +lcouncil.com +lcpdu.com +lcpumps.com +lcqixing.com +lcqjsjxxx.com +lcqwdz.com +lcrc.ltd +lcrcbank.com +lcsepu.com +lcsgxjt.com +lcsrmyy.com +lcsrw.com +lcsssg.com +lcsyzp.com +lctech-inc.com +lctsggzz.com +lcux.net +lcwl.net +lcxtgs.com +lcxwfc.com +lcxzyy.com +lcycgg.com +lcyff.com +lcyhdl.com +lcyidc.com +lcyinsu.com +lcykgg.com +lcyp.net +lcyrny.com +lcysc.com +lcywhx.com +lcyyfj.com +lcyzh.com +lczbgc.com +lczm.com +lczq.com +lczyjsxx.com +lczyun.com +lczyy.com +ld-pd.com +ld-powder.com +ld0766.com +ld12366.com +ld173.com +ld246.com +ldaq2005.com +ldb.cc +ldbj.com +ldbmcs.com +ldd.me +lddengine.com +lddgo.net +ldfdcw.com +ldgjj.com +ldgslb.com +ldhrd.com +ldhy.click +ldj-edujy.com +ldjt-china.com +ldkftz.com +ldkj-zs.com +ldkqyy.com +ldmap.net +ldmnq.com +ldngj.shop +ldoooo.com +ldqxn.com +ldrcw.com +ldseals.com +ldshijie.com +ldshj.com +ldsink.com +ldstark.com +ldtdn.com +ldtec.com +ldtech168.com +ldteq.com +ldwxiao.com +ldxiang.com +ldycdn.com +ldydh.com +ldygo.com +ldyz365.com +ldzcgs.com +ldzxyy.com +le-feng.com +le-wan.com +le.com +le365.cc +le4.com +le4ker.me +le5le.com +le8.com +le855.com +le890.com +leacol.com +leadada.com +leadal.com +leadal.net +leadamc.com +leadclimb.org +leadcoretech.com +leadding.com +leaddo.com +leader-e.com +leader609.com +leader755.com +leaderhero.com +leaderlawyer.com +leadernano.com +leaderobot.com +leadervc.com +leadge.com +leading-chem.com +leadingpharm.com +leadintelligent.com +leadlan.com +leadleo.com +leadmanbio.com +leadmap.net +leadmedpharm.com +leadmicro.com +leadmoad.com +leado-pharma.com +leadong.com +leadrd.com +leadrive.com +leadshiptech.com +leadstong.com +leadvc.com +leadvsion.com +leadway-china.com +leadwaytk.com +leadyo.com +leadzees.com +leaferjs.com +leaforbook.com +leaftools.net +leafword.com +leagcard.com +leagpoint.com +leagsoft.com +leaguesun.com +leakeyun.com +lean.ren +leangoo.com +leanote.com +leansoftx.com +leanwind.com +leanyon.com +leap-pc.com +leapahead.vip +leapfive.com +leaping.games +leapmie.com +leapmmw.com +leapmotor.com +learn-quantum.com +learn.microsoft.com +learndiary.com +learnfuture.com +learningsj.com +learnku.com +learsun.com +leatherhr.com +leautolink.com +leavescn.com +leawin.com +leayin.com +leb-china.com +lebanban.com +lebang.com +lebang.net +lebi2.com +lebilp.com +lebinwl.com +lebocode.com +lebome.com +lebopark.com +lebosky.com +leboweb.com +lecai.com +lecai08.com +lecake.com +lechain.com +lechange.com +lechangxia.cc +leche.com +lechebang.com +lecheng18.com +lechengdz.com +lechengyunfu.com +lechinepay.com +lechuangzhe.com +lecloud.com +lecloudapi.com +lecloudapis.com +lecoinfrancais.org +lecomposites.com +lecong56.com +leconiot.com +lecoo.com +lecreperoyaloak.com +lecu8.com +lecuntao.com +led-zulin.com +led661.com +ledanji.com +ledcax.com +ledchina-sh.com +ledctl.com +lede.com +ledger-phrase.com +ledguhon.com +ledhyzm.com +ledianyun.com +lediaocha.com +ledmary.com +ledo.com +ledouwan.com +ledouya.com +ledsdk.com +ledth.com +ledtoplight.net +ledu.com +ledu365.com +leduimg.com +lee-tieguo.com +leeaon.com +leeco.com +leefanmr.com +leehon.com +leelen.com +leeleo.vip +leenzee.com +leenzhu.com +leeon.me +leesdog.space +leeshen.net +leesoar.com +leesou.com +leetcode-cn.com +leetcodechina.com +leetro.com +leeuu.com +leevol.com +leevy.net +leewiart.com +lefang365.com +lefanglj.com +lefeng.com +leffercode.com +leftfm.com +leftlady.com +leftshadow.com +leftso.com +lefu8.com +lefuzuwu.com +legalsiri.com +legend-si.com +legendsec.com +legendsemi.com +legion.com.hk +legou456.com +legowechat.com +legu.cc +legu168.com +leguyu.com +leha.com +lehaitv.com +lehe.com +lehecai.com +lehibay.com +lehihi.com +leho.com +lehuadisplay.com +lehuipay.com +lehuiso.com +lei001.com +leiaomold.com +leibei.cc +leiboyiqi.com +leidacj.com +leidianip.com +leigod.com +leigodjsq.com +leihetg.com +leihuo.net +leijue.net +leijun.com +leike.cc +leikeji.com +leilei3dprinter.com +leileiluoluo.com +leilong158.com +leimengjixie.com +leimi.com +leimingtech.com +leimingtelab.com +leimudata.com +leiniao.com +leiniao365.com +leining-shield.com +leiouxiong.com +leiphone.com +leishen-lidar.com +leishencloud.com +leishenhuyu.com +leishenlaser.com +leishouwin.cc +leisoon.com +leisu-ty.net +leisu.com +leisu123.com +leisuapi.com +leisureer.com +leisurelypanda.com +leitaibio.com +leitaigongsi.com +leiting.com +leitingcn.com +leitingjunshi.com +leitool.com +leiue.com +leixiaofeng.net +leixinbuild.com +leixue.com +leiyediaoche.com +leiyunge.com +leiyunge.net +leji.com +lejiachao.com +lejian.com +lejiao.tv +lejiaolexue.com +lejiaotech.com +lejiashu.com +lejj.com +leju.com +lejucaijing.com +lejunwl.com +lekan.com +lekannews.com +lekazc.com +lekevr.com +lekoukou.com +lektec.com +lekuya.com +lelaer.com +lelai.com +lele-lezhong.com +lelecdn.com +leleda.com +leledp.com +lelehuyu.com +leleju.com +leleketang.com +lelelala.net +lelepyq.com +leletv.com +leletv.net +lelinly.com +lelongpp.com +lemai.com +lemaker.com +lemall.com +lemedu.com +lemeitu.com +lemeng.center +lemengcloud.com +lemengfun.com +lemicp.com +lemiwan.com +lemiyigou.com +lemo360.com +lemobar.com +lemoes.com +lemon4.club +lemonban.com +lemonnovel.com +lemonpiggy.com +lemonplus.asia +lemonsay.com +lemonttt.com +lemonvp.com +lemonyd.com +lemote.com +lempstack.com +lemurbrowser.com +len.ink +lenauth.com +lenbenelectric.com +lenciel.com +lendy520.com +lenfocus.com +lengcat.com +lengdou.net +lenget.com +lenglengyu.com +lengliwh.com +lenglv.com +lengshuiji.org +lengxiaohua.com +lengxiaohua.net +lengyankj.com +lengzzz.com +leniugame.com +leniy.org +lenmy.com +lenogo.com +lenosoft.com +lenosoft.net +lenovator.com +lenovo.com +lenovo.com.cdn.cloudflare.net +lenovo.net +lenovocloudos.com +lenovoconnect.com +lenovoeservice.com +lenovofile.com +lenovogame.com +lenovohci.com +lenovohuishang.com +lenovoimage.com +lenovomm.com +lenovomobile.com +lenovonetapp.com +lenovonowgo.com +lenovopoc.com +lenovoprinter.com +lenovoprinter.net +lenovots.com +lenovouat.com +lenovows.com +lenovozdl.com +lenschine.com +lenslifephoto.com +lensuo.com +lenwoo.com +lenzhao.com +leoao-inc.com +leoao.com +leocode.net +leogd.com +leolin86.com +leonblog.net +leoogo.com +leopardtale.com +leopump.com +leozwang.com +lepaicm.com +lepiaoyun.com +lepidard.com +leptv.com +lepumedical.com +leqi.us +leqian.com +leqiaobh.com +leqiaobhyy.com +leqiku.com +leqiuba.com +leqiuzbc.org +lequ.com +lequanip.com +lequgo.com +lequji.com +lequz.com +lequzh.com +lercar.com +lergao.com +lergle.com +lerist.dev +lers168.com +lers168.net +lersang.com +lertao.com +lerye.com +lesejie.com +leshangzs.com +leshangzx.com +leshanvc.com +leshare.work +leshi123.com +leshiguang.com +leshow.com +leshuatech.com +leshuazf.com +leshuwu.com +lesimao.net +lesjob.com +lesjulo.com +leslie-cheung.com +lesofn.com +lesonccl.com +lesoon.com +lesou.net +lespark.us +lesports.com +less-bug.com +less-more.net +lesscode.work +lesso.com +lestcg.com +letabc.com +letang666.com +letaoedu.com +letaoren.com +letbonchina.com +leter.io +letianbiji.com +letianshanec.com +letim-auto.com +letinet.com +leting.io +letoour.com +letotur.com +letou8.com +letoursport.com +letright.com +letrychina.com +lets-study.com +letschuhai.com +letsebuy.com +letsfilm.org +letsgaga.com +letsinno.com +letssepub.com +letsvisa.com +lettercloud.net +letuinet.com +letuixiaokefu.com +leturich.org +letushu.com +letv.com +letv8.com +letvapp.net +letvcdn.com +letvcloud.com +letvimg.com +letvlb.com +letvlive.com +letvstore.com +letwind.com +letwx.com +letyo.com +leuok.com +levc.com +levcauto.com +levect.com +level8cases.com +levelinfinite.com +levenx.com +lewaimai.com +lewang.ltd +lewangame.net +lewawa.com +lewbin.com +lewen.la +lewenba.cc +lewenlou.la +lewenn.com +lewenqu.com +lewenss.com +lewenxsw.com +lewifi.com +lex.download.prss.microsoft.com +lexar.com +lexed.org +lexiaigame.com +lexiang-app.com +lexiang-asset.com +lexiang-asset.net +lexiang-ops.com +lexiangla.com +lexiangla.net +lexiangzuji.com +lexin.com +lexin001.com +lexinchina.com +lexoncloud.net +lexuat.download.prss.microsoft.com +lexue-cloud.com +lexue.com +lexueying.com +lexun.com +lexun.net +lexuncaishui.com +lexuntimes.com +leya920.com +leyaep.com +leyan.com +leyantech.com +leyaoyao.com +leyaoyao.org +leyard.com +leybc.com +leyi007.com +leyifan.com +leying.com +leying365.com +leyingtt.com +leyishandong.com +leyixue.com +leyonb.com +leyoo.com +leyoujia.com +leyu.com +leyuanhr.com +leyue100.com +leyuglobal.com +leyun001.com +leyun365.com +leyuncn.com +leyungame.com +leyunge.com +leyuxyz.com +leyuz.com +lezai.com +lezai.org +lezhao.com +lezhi.com +lezhi99.com +lezhibo.com +lezhiot.com +lezhiyun.com +lezhuan168.com +lezhuan365.com +lezhuanwang.net +lezhudai.com +lezhufenqi.com +lezhun.com +lezi.com +lezuan.net +lezuan11.com +lezuan9.com +lezuocai.com +lf126.net +lf127.net +lfan.net +lfang.com +lfbxw.com +lfcharge.com +lfcmw.com +lfdjex.com +lfekaj.help +lfex.com +lffloor.com +lfggzz.com +lfhacks.com +lfhospital.net +lfhygl.com +lficanton.com +lfjsly.com +lfjx88.com +lfkjgh.com +lfksqzj.com +lfmxc.com +lfppt.com +lfqysm.com +lfrczp.com +lfszk.com +lftdzd.com +lfungame.com +lfwin.com +lfx20.com +lfxww.com +lfywood.com +lfyx.ink +lfyzjck.com +lfzhaopin.com +lg-lg.com +lg-pump.com +lg1024.com +lg198.com +lg5.co +lg5.com +lgbzj.com +lgcdz.com +lgctshanghai.com +lgcx.com +lgdisplayproduct.com +lgdxtech.com +lgexam.com +lgfdcw.com +lgfzgroup.com +lghd111.com +lghlncl.com +lgimg.com +lgimic.com +lglmf.com +lglmf.net +lgmi.com +lgo100.com +lgpic.com +lgpj.net +lgpm.com +lgrcbank.com +lgshouyou.com +lgtzkg.com +lguohe.com +lgvf.com +lgwy.net +lgxly.com +lgyanglao.com +lgyszl.com +lgyudiao.com +lgyzyy.com +lgzowo.com +lgzzu.com +lh-ep.com +lh-lx.com +lh.link +lh168.net +lh17.net +lh36524.com +lh75.com +lhasa.icu +lhbbj.com +lhbgchina.com +lhconst.com +lhcreditevaluation.com +lhcy168.com +lhdbgs.com +lhdeer.com +lhdown.com +lhdxz.com +lhenet.net +lhey.com +lhgcxx.com +lhguomy.xyz +lhgz.net +lhh.la +lhhy.net +lhihg.com +lhjdfs.com +lhjol.com +lhjws.com +lhjy.net +lhjyw.vip +lhjzlw.com +lhkaye.com +lhkgs.com +lhl.zone +lhl7.com +lhmj.com +lhmp.cc +lhovoxcx.work +lhp-cdn-game.online +lhp-cdn-update.online +lhpharma.com +lhratings.com +lhrbszb.com +lhs-arts.org +lhs11.com +lhs99.com +lhsdjxy.com +lhsoso.com +lhszyxx.com +lhulan.com +lhwill.com +lhwytj.com +lhxhwl.com +lhyc3888.com +lhyiliao.com +lhytgroup.com +lhzq.com +li-ca.com +li-ning.com +li-on.com +li-world.com +li-yuan.com +li.auto +li63.com +li91.com +liageren.com +lian-ou.com +lianaibiji.com +lianaixingwei.com +lianaiyx.com +lianbei66.com +lianchuang.com +lianchuanghj.com +liancsoft.com +lianda.fun +liandaomobi.com +liandaquan.com +liande.cc +lianfawy.com +lianfengqy.com +lianfengwh.com +liang520.com +liangc.com +liangchan.net +liangchanba.com +liangduapp.com +liangduiban.com +lianggao.com +lianghuadashi.com +liangjan.com +liangjiangbashu.com +liangjianghu.com +liangjiangroup.com +liangjiangwuye.com +liangjihui.com +liangjiu.shop +liangka.vip +liangkun.net +liangle.com +lianglimi.com +lianglunshijie.com +liangnuo.com +liangpinbiji.com +liangqikeji.com +liangrisheng.com +liangrunbio.com +liangshunet.com +liangtian-tech.com +lianguowang.com +liangwanjianshe.com +liangwei.cc +liangxinyao.com +liangyi.com +liangyi360.com +liangyiyy.com +liangyuan.com +liangzhishu.com +liangziheikeji.com +lianhaikeji.com +lianhanghao.com +lianhaokeji.com +lianhejiaju.com +lianhengkj.com +lianhengtec.com +lianhepaimai.com +lianhuangroup.com +lianjia.com +lianjianode.xyz +lianjianxsw.com +lianjiasm.com +lianjie.in +lianjiezhe.com +lianjingdq.com +lianjixia.com +liankaa.com +liankebio.com +liankenet.com +lianku.xin +liankuaiche.com +lianli168.com +lianlian.com +lianlianlvyou.com +lianlianpay-inc.com +lianlianpay.com +lianliantao.net +lianliantaoshop.com +lianlianz.com +lianlife.com +lianliwork.com +lianluo.com +lianmeng.la +lianmeng.link +lianmeng.work +lianmenhu.com +lianmishu.com +lianni.com +lianok.com +lianouyiyuan.com +lianpingroup.com +lianpunet.com +lianqi.net +lianqigong.com +liansaipiao.com +lianshang.com +lianshijie.com +lianshun.cc +liansn.com +liansuo.com +liantianhong.com +liantongcar.com +liantu.com +liantuobank.com +liantuofu.com +lianty.com +lianwen.com +lianwifi.com +lianwo8.com +lianwwl.com +lianxianjia.com +lianxinapp.com +lianxinkj.com +lianyi.com +lianyins.com +lianyiwater.com +lianyuannongye.com +lianyungangforum.org +lianzhixiu.com +lianzhong.com +lianzhongyun.com +lianzhoupc.com +lianzhuli.com +lianzifang.com +liao1.com +liao98.com +liaobagua.com +liaocheng.cc +liaochuo.com +liaode.com.tw +liaogu.com +liaogx.com +liaoing.com +liaoji.com +liaojiu.net +liaokong.com +liaoliao.com +liaoningmoduo.com +liaoningpharm.com +liaosam.com +liaotiantu.com +liaoworking.com +liaoxiwenhua.com +liaoxuefeng.com +liaoyuanchats.com +liaoyuanedu.org +liaozhai.tv +liauto.com +lib520.com +liba.com +liba88.com +libaclub.com +libai.com +libaidns.com +libaishuo.com +libao007.com +libaopay.com +libawall.com +liberlive-music.com +libertynlp.com +libforest.com +libguides.com +libinx.com +libiotech.com +libisky.com +liblib.art +liblib.cloud +libmk.com +libomarathon.com +libreofficechina.org +libsou.com +libssh.com +libsys.net +libtop.com +libvideo.com +lic-bcbc.com +lic-slf-dom.com +lic-slf-dom.net +licai.com +licai18.com +licaie.com +licaigc.com +licaike.com +licaiker.com +licaimofang.com +licaishouyi.com +licaixu.com +licaiyaoye.com +licancan.com +licaoz.com +licat.com +licc.tech +lichangtai.com +lichangtao.com +lichangwen.net +lichee.pro +lichenglove.com +lichengwu.net +lichenjy.com +lichimedicine.com +lichiwei.com +lichong.work +lichuang.ren +licic.net +lickeji.com +lickscreen.com +licomsh.com +licqi.com +lida100.com +lidakang.com +lidamicron.com +lidar360.com +lideapower.com +lidebiotech.com +lidepower.com +lidg-fueltank.com +lidianchizu.com +lidianren.com +lidihuo.com +liding.me +lidlsalevipeu.shop +lidodo.com +lidu6.com +lidw.com +lie.icu +liebao.live +liebaoh5.com +liebaoidc.com +liebaopay.com +liebiao.com +liebigwatch.com +liebo.com +liechan.com +liedaoshou.com +lieguo.com +lieguozhi.com +liehunwang.com +liehuo.net +liehuosoft.com +liejin99.com +lieju.com +lieketao.com +lielema.com +liemingwang.com +lienew.com +liepin.com +liepin8.com +liepincc.com +lierda.com +lierdapark.com +lierfang.com +liermusic.com +liesauer.net +lieshi.net +lieshuku.com +lietou-edm.com +lietou-static.com +lietou.com +lietou007.com +lietuwang.com +liewen.cc +liewen.la +liexing-ai.com +liexing.com +liexiulive.com +lieyingjt.com +lieyou.com +lieyouqi.com +lieyuncapital.com +lieyunpro.com +lieyunwang.com +liezhe.com +liezhen166.com +liezhun.com +lif8.com +lifan.com +life-2028sport.com +lifebook.red +lifediary.shop +lifeeu.com +lifefunkingdom.org +lifegc.com +lifegreenmedical.com +lifeng.in +lifengshoe.com +lifeofguangzhou.com +lifesense.com +lifetimecables.com +lifetm.com +lifetmt.com +lifetmt.net +lifetmt.org +lifeup.vip +lifevc.com +lifevccdn.com +lifeweeker.com +lifeyk.com +lifeyn.net +lifezb.com +liffmp.com +lifo-fj.com +lifotronic.com +lifox.net +lifrog.com +lifushop.com +lifves.com +lify.vip +ligendpower.com +ligetz.com +lighos.com +light-cos.com +light-player.com +light3moon.com +lightalk.com +lightalk.me +lightblue.net +lightbox.games +lighte-tech.com +lightgx.com +lighthg.com +lighting-china.net +lightingchina.com +lightinit.com +lightky.com +lightlygame.com +lightmake.site +lightonus.com +lightpassport.com +lightsaber.com +lightspeed-dc.com +lightspeed-lic.com +lightspeed-og.com +lightstrade.com +lightxi.com +lightyy.com +ligonggong.com +liguanchina.com +liguangtaogroup.com +liguosong.com +lih-invest.com +lihang-expo.com +lihaoshuyuan.com +liheiat.xyz +liheng1688.com +lihengjh.com +lihetong.com +lihong.net +lihongcctv.com +lihtao.com +lihua.com +lihuadonghua.com +lihuamuye.com +lihuashouji.com +lihuasoft.net +lihui.net +lihuia.com +lihun66.com +liigou.com +lijiabaijc.com +lijiabrasstube.com +lijiajia.com +lijiajia.net +lijiangbooks.com +lijiangcun.com +lijiangriver.com +lijiankai.com +lijiejiaju.com +lijigang.com +lijinghua.club +lijingquan.net +lijinxincai.com +lijinzhang.com +lijishi.com +lijizhong.com +lijjj.com +likamao.com +likangwei.com +like.video +like996.icu +likeaboat2023.com +likeacg.com +likebuy.com +likecha.com +likechuxing.com +likecs.com +likee.video +likeface.com +likefar.com +likefont.com +likeji.net +likejianzhan.com +likelic.com +likepoems.com +likeshare-tech.com +likeshuo.com +liketm.com +liketry.com +liking.site +likingfit.com +likuli.com +likuso.com +lilacbbs.com +lilaigroup.com +lilanz.com +lili.cc +liliangji.com +lilinwei.com +lilishare.com +lilisi.com +lilith.com +lilithgame.com +lilithgames.com +lilvb.com +lilygo.cc +lilysamericandiner.com +limabaoxian.com +limaoqiu.com +limebenifit.com +limei.org +limeiltd.com +limian.com +liminglight.com +limingtech.com +liminjie714.com +liminwang.com +limit-animation.com +limless.com +limobai.com +lin-jiang.com +linakesi.com +linancity.com +linaoyiqi.com +linban.com +linchangyu.com +linchuangsy.com +lincoc.com +lindapatent.com +linde-china.com +lindmik.com +lindybag.com +line-gate.com +linearbuyic.com +linearmotor.net +lineartracklight.com +linecg.com +lineget.site +linekong.com +linelayout.com +linestartech.com +linewell.com +linewow.com +linfan.com +linfeicloud.com +linfen365.com +linfeng.tech +linfenwater.net +ling-shi.com +lingangholding.com +lingangic.com +lingaoren.com +lingbao-e.com +lingboxauto.com +lingceu.com +lingd.com +lingdi.net +lingdianksw.com +lingdong.net +lingdongweilai.com +lingdongwuliu.com +lingdu.love +lingduan-sh.com +lingduohome.com +lingduzuji.com +lingdz.com +lingfengyun.com +lingganjia.com +linggao.vip +linggu.com +linghanggroup.com +linghit.com +linghitai.com +linghonggroup.com +linghua-logistics.com +linghuidzsw.com +linghuoai.com +lingji666.com +lingjiaocheng.com +lingjing.com +lingjiptai.com +lingjoin.com +lingjuad.com +lingjumobile.com +lingkaba.com +lingkebang.com +lingkou.com +lingkou.xyz +lingkuyun.com +lingla.com +linglingkaimen.com +linglingmo.site +linglong.dev +linglongart.com +linglonglife.com +linglongtech.com +lingmao.tech +lingmeijie.com +lingmeng888.com +lingmovie.com +lingnanpass.com +lingo-ace.com +lingodeer.net +lingosail.com +lingostarcdn.com +lingowhale.com +lingphone.net +lingquanb.com +lingqumall.com +lingrengame.com +lingrn.com +lingruipc.com +lingruofeng.com +lingshangkaihua.com +lingshangmeien.com +lingshenxing.com +lingshenxl.com +lingshi.com +lingshimiyu.com +lingshou.com +lingshoujia.com +lingshulian.com +lingshunlab.com +lingsky.com +lingsoul.com +lingti.com +lingtiao.com +lingtingmusic.com +lingtings.com +lingtong.info +lingtool.com +lingtu.com +lingtuan.com +lingumob.com +linguoguang.com +lingw.net +lingwe.com +lingwh.com +lingwu66.com +lingxi360.com +lingxianfund.com +lingxicloud.com +lingxigames.com +lingxing.com +lingxingcai.com +lingxingkj.com +lingxiuwenlv.com +lingxmall.com +lingy.cc +lingyanghuyu.com +lingyi.org +lingyihanhua.com +lingyiitech.com +lingyiliebian.com +lingyinsi.com +lingyinsi.org +lingyiwanwu.com +lingyuan.design +lingyue-digital.com +lingyuecloud.com +lingyuedianzi.com +lingyuint.com +lingyun.com +lingyun.net +lingyun5.com +lingyuncw.com +lingyunip.com +lingyunquan.com +lingyuok.com +lingzhanwenhua.com +lingzhilab.com +lingzhitech.com +lingzhtech.com +linhaigroup.com +linhaiwangdai.com +linhao.net +linhuatz.com +linhuiba.com +lining.com +lining0806.com +linjia.me +linjieapp.com +linjin.net +linjunlong.com +link-ai.tech +link-nemo.com +link-trans.com +link27.com +link2lib.com +link2shops.com +link3.cc +linkadsapi.com +linkbook.tech +linkbroad.com +linkbux.com +linkchant.com +linkchina.hk +linkcubecloud.net +linkdesign.tech +linkdialy.com +linkeabc.com +linkease.com +linked-f.com +linked-reality.com +linkedbyx.com +linkedhope.com +linkedin-event.com +linkedkeeper.com +linkedme.cc +linkedsee.com +linker.cc +linkernetworks.com +linkeye.net +linkfinancier.com +linkflowtech.com +linkfruits.com +linkfunny.com +linkgou.com +linkh5.com +linkh5.xyz +linkheer.com +linkiebuy.com +linkingcloud.com +linkist.net +linknewideas.com +linkoing.com +linkolder.com +linkon.me +linkontek.com +linkpai.com +linkpro.tech +linkr.com +linkrall-trk.com +linkresearcher.com +links-china.com +linksdao.com +linksfield.net +linksgood.com +linkshop.com +linksoon.net +linkstars.com +linkstec.com +linksunet.com +linktech.hk +linktom.com +linktom.net +linktree.vip +linktt.com +linkunbin.com +linkunjc.com +linkvfx.com +linkwebll.com +linli580.com +linlikuaipao.com +linliyz.com +linlongnewmaterials.com +linlongyun.com +linlongyx.com +linmi.cc +linmujianghome.com +linni.com +linnsea.com +linnxin.com +linnyou.com +linovel.net +linovelib.com +linoya.com +linpx.com +linqujob.com +linqumarathon.com +linruanwangluo.com +lins-bros.com +linshang.com +linshaoqian.work +linshi.cc +linshigong.com +linshimuye.com +linshiyongling.com +linsn.com +linstitute.net +lint2.com +lintai.tech +lintaicnc.com +lintcode.com +lintec-china.com +lintey.com +lintongrc.com +lintonpharm.com +lintui.com +linuo-paradigma.com +linuo.com +linuopv.com +linuoshi.com +linuottc.com +linux-code.com +linux-ren.org +linux.zone +linux178.com +linux265.com +linux5.net +linuxba.com +linuxbaike.com +linuxbaodian.com +linuxboy.net +linuxcool.com +linuxde.net +linuxdiyf.com +linuxdot.net +linuxea.com +linuxeden.com +linuxeye.com +linuxgogo.com +linuxidc.com +linuxidc.net +linuxjoy.com +linuxmi.com +linuxpanda.tech +linuxpk.com +linuxprobe.com +linuxsir.com +linuxso.com +linuxtone.org +linuxyunwei.com +linuxyw.com +linwushuang.fun +linx-info.com +linyafeng.com +linyang.com +linyekexue.net +linyi.net +linyibus.net +linyiren.com +linyizhizhiyuan.com +linyouquan.net +linyufan.com +linzhou.store +linzhuotech.com +linzhuxin.com +linzihy.com +lion1ou.tech +lionaka.com +lionit.net +lionkingsoft.com +lionmac.com +lionmobo.com +lionmobo.net +lionsgx.com +lipian.com +lipiji.com +lipilianghang.com +lipin.com +lipin51.com +lipind.com +lipinduihuan.com +lipro.com +lipro.net +lipu.net +lipuhome.com +lipush.com +lipuxixi.com +liqinet.com +liqinyi.com +liquan.com +liqucn.com +liquidgoldtatttoo.com +liquidnetwork.com +liqun.org +liqun.vip +liquncommercialgroup.com +liqungroup.com +liqunshop.com +liqwei.com +lirenliye.com +liriansu.com +liriji.com +lirui.name +lis99.com +lisdn.com +lisenergy.com +lisheng.gold +lishengstone.com +lishi-test.com +lishi6.com +lishi7.com +lishibk.com +lishichunqiu.com +lishicloud.com +lishiip.com +lishiming.net +lishimingren.com +lishixiaozhi.com +lishixinzhi.com +lishizhishi.com +lishuhang.me +lishuhao.ltd +lishui.com +lishuichayuan.com +lisigroup.com +lisihouseware.com +lisizhang.com +lisp123.com +lissgx.com +listary.net +listarypro.com +listeneer.com +listeningo.com +listenpa.com +listentide.com +listentoworld.com +listenvod.com +listno1.com +listong.com +lisure.com +lisz.me +litangkj.com +litaow.com +litaparking.com +litchon.com +lite-miniprogram-1.com +lite-miniprogram-5.com +litecdncname.com +litecoin.ink +litecoin.ren +litefeel.com +litemob.net +liteng-industry.com +litessl.com +lithomaterial.com +lithub.cc +litian268.com +litianchina.com +liticool.club +litilala.site +litilala.xyz +lititop.group +litiww.mobi +litofu.com +litongsupply.com +litongtech.com +litosim.com +litree.com +litten.me +little-star.love +little-sun.com +littleboy.net +littlegeek.work +littlehero.xyz +littleqiu.net +littleroost.net +littlesheep.com +littlesix.mobi +littlesproutsdk.com +littleswan.com +lituo666.com +liu-he.com +liu-kevin.com +liu16.com +liuar.xin +liubaocha.com +liucao.vip +liuchengguanli.com +liuchengtu.com +liuchengtu.net +liuchenkeji.com +liuchuo.net +liudanking.com +liudaoxiang.com +liudatxt.com +liudatxt.org +liudayadan.com +liudian6.com +liudon.com +liudon.org +liudu.com +liufanggroup.com +liugejava.com +liugezhou.online +liugj.com +liugm.com +liugong.com +liugongac.com +liugongam.com +liugonggroup.com +liuguofeng.com +liuhaolin.com +liuhubang.com +liujiagd.com +liujiajia.me +liujian666.com +liujiangblog.com +liujiaoyidai.com +liujijun.com +liujinkai.com +liujto.com +liujunworld.com +liujy.com +liukai.net +liukebao.com +liulan.net +liulanqi.net +liulantao.com +liulian.com +liulianga.com +liuliangcanmou.com +liuliangdada.com +liulianggo.com +liuliangguo.com +liuliangka.pro +liulianglf.com +liuliangmima.club +liuliangmima.vip +liuliangzu.com +liulianqi123.com +liulin.cc +liulishuo.com +liulishuo.work +liulisyb.org +liuliushe.net +liulixuexiao.com +liulj.com +liulv.net +liumapp.com +liumeinet.com +liuming.work +liumuzulin.com +liumx.com +liunian.info +liunianbanxia.com +liunn.com +liuqh.icu +liurq.com +liushen.fun +liushidong.com +liushuishiyin.com +liusibo.com +liusteel.com +liusu-kyimm.com +liusu.me +liusuping.com +liuts.com +liuwamiaoji.com +liuweihotel.com +liuwo.com +liuxianan.com +liuxianjt.com +liuxiaoer.com +liuxiaofan.com +liuxing.com +liuxingw.com +liuxinli.com +liuxuchao.com +liuxue.com +liuxue114.com +liuxue360.com +liuxue86.com +liuxuegang.site +liuxuehr.com +liuxuekw.com +liuxuesmd.com +liuxuetown.com +liuxuewind.com +liuxueyun.com +liuxx.com +liuyang.com +liuyangfcw.com +liuyangjob.com +liuyanzhao.com +liuyifei.cc +liuyiguo.com +liuyimin4.com +liuyixiang.com +liuyua.xyz +liuyunflow.com +liuyunliumeng.com +liuyuntian.com +liuzaoqi.com +liuzhihang.com +liuzhixiang.com +liuzhiyugzs.com +liuzhosoft.com +liuzhoufushan.com +liuzhoukaichuang.com +liuzhourm.com +liuzhousteel.com +liuzhuni.com +liuziyoudu.com +liuzongyang.com +liuzy88.com +livanauto.com +live-350k.streamingfast.net +live-echotv.cdnvideo.ru +live-flashscore.com +live-helps.com +live-qiudidai.com +live-ssport.com +live-voip.com +live.hhtv.cc +live.hnzzzzzdst.com +live.lxzc.net +live.ntdimg.com +live.sccxtv.com +live.sichuanmianning.com +live.streamingfast.net +live.tvbaoji.com +live.ugratv.cdnvideo.ru +live.zhihuizq.com +live02.rfi.fr +live1.jcbctv.com +live123.cc +live2.asbctv.com +live2.ntdimg.com +live800.com +liveanevia.mncnow.id +liveapp.ink +livebong68.com +livecdn.fptplay.net +livecdnh2.tvanywhere.ae +livecdnstatic.com +livechina.com +livecourse.com +livehwc4.com +liveinau.com +livejh.com +liveme.com +livemediav.com +livemook.com +livenmall.com +liver-surgery.net +livesone.net +livesupport24x7.com +liveuc.net +liveupdate-cn.msi.com +livevideostack.com +living.ai +livnj.com +livotre.com +liwai.com +liwanggui.com +liwanght.com +liweiauto.com +liweicar.com +liweijia.com +liweijituan.com +liweiliang.com +liwenzhou.com +liwi.cc +liwinon.com +liwojx.com +liwoxiao.com +liwucheng.com +liwumaoapp.com +liwushuo.com +liwuzhi.art +lixcx.com +lixfaf.com +lixiaedu.com +lixiang.com +lixianghuanbao.com +lixiangoa.com +lixiangshu.net +lixianhezi.com +lixianhua.com +lixiaocrm.com +lixiaolu.org +lixiaoskb.com +lixiaoyun.com +lixiaozhe.com +lixinapp.com +lixinger.com +lixingyong.com +lixinpharm.com +lixuan360.com +lixueba.com +lixueduan.com +lixuejiang.com +liyan365.com +liyang1.com +liyangbit.com +liyanggroup.com +liyangic.com +liyangrc.com +liyangtuopan.com +liyanmobi.com +liyaochao.com +liyegroup.com +liyi99.com +liyinewmaterial.com +liyingfei.com +liyinka.com +liyu8.com +liyuan1999.com +liyuan99.com +liyuan99.vip +liyuanchun.net +liyuanheng.com +liyuanhospital.com +liyuanresort.com +liyuansz.com +liyugang.com +liyujn.com +liyunde.com +liyunkm.com +liyunshuwu.com +liyuplay.com +liyx.fun +liyx.net +lizaberese.com +lizaike.com +lizhehaozhongyi.com +lizhenauto.com +lizhenglai.com +lizhenwang.com +lizhi.com +lizhi.fm +lizhi.io +lizhi.shop +lizhi110.com +lizhifilm.com +lizhifm.com +lizhiinc.com +lizhijitang.com +lizhilive.com +lizhiqi.com +lizhiqiang.name +lizhiqp.com +lizhiweike.com +lizhongyi.com +lizhujue98.com +lizi.com +lizihang.com +lizikeji.vip +lizilaw.com +liziqiche.com +lizitongxue.com +liziwu.net +liziyuan.com +lizq.host +lj-audio.com +lj-bank.com +lj168.com +ljbao.net +ljbbj.com +ljcdn.com +ljclz.work +ljflavor.com +ljh.cool +ljhjgc.com +ljhjny.com +ljhks.com +ljhks.net +ljia.com +ljia.net +ljimg.com +ljjcyy.com +ljjlb.net +ljjq.com +ljjyjt.com +ljk.cc +ljkangyang.com +ljlcd.com +ljlj.cc +ljlmdns.com +ljlqw.com +ljmeng.site +ljmyy120.com +ljqhju.com +ljqxjjhbc.com +ljrbw.com +ljs.fun +ljsdk.com +ljsy2017.com +ljsz.xyz +ljtx.com +ljw113.com +ljwebs.com +ljwit.com +ljwlz.com +ljxqzy.com +ljxww.com +ljz-talentapt.com +ljzfin.com +lk-jd.com +lk0355.com +lk361.com +lk366.com +lkalpos.com +lkcash.com +lkcgyl.com +lkchemical.com +lkcoffee.com +lkdt.work +lke.hk +lkfan.com +lkg888.com +lkgame.com +lkgk.net +lkgshq.com +lkhaowu.com +lki2.org +lkjujm.com +lkkbrand.com +lkkcdn.com +lkkdesign.com +lkker.com +lkkued.com +lkme.cc +lknvcti.com +lkong.com +lkong.net +lkpc.com +lkqihang.com +lksmarttech.com +lkssite.vip +lkszj.info +lktz.net +lkuaiy.com +lkxfeda.com +lkyljt.com +lkyou.com +ll-hao123.com +ll1024.com +ll5856.com +llang.net +llaoyou.com +llbzy.com +llcat.tech +lldlf.com +llever.com +llewan.com +llgjx.com +llgkm.com +llguangli.com +llguangli30.com +llhlkftzjt.com +llidc.com +llinkslaw.com +lljgame.com +lljsq.net +lljyx.com +llku.com +lllcn.com +llllx7.com +lllpv.com +llmtrend.com +llmworld.net +llongwill.com +llqsq.com +llrj.net +llrsz.com +lls.moe +llsapp.com +llscdn.com +llskjt.com +llsops.com +llsserver.com +llssite.com +llsttapp.com +llsun.com +lltoken.com +lltskb.com +llumar-cn.com +llwx.net +llx168.com +llxj119.com +llxx.cc +llxzl.com +llxzu.com +llyj.net +llyweb.com +llyy.org +llyyx.com +llzg.com +llzxedu.net +lm263.com +lm335.com +lm9999.com +lmacc.com +lmanmo.com +lmanucell.com +lmbct.com +lmbest.com +lmdouble.com +lmengcity.com +lmjtgs.com +lmjx.net +lmjzd.com +lmkggf.com +lmkzx.com +lmlc.com +lmlq.com +lmnano.com +lmnsaas.com +lmonkey.com +lmparcel.com +lmqt.com +lms.pub +lmschina.net +lmscp.com +lmtutou.com +lmtw.com +lmu5.com +lmujp.work +lmwlhh.com +lmwljz.com +lmwmm.com +lmylgs.com +lmzitie.com +lmzt.com +ln-map.com +ln-rc.com +ln525.com +lnairport.com +lnamphp.com +lnast.net +lnbaiyun.com +lnbdsc.com +lnbybc.com +lnbyy.net +lncbp.com +lncct.com +lncjxy.com +lncldapi.com +lncmcc.com +lncmxy.com +lncnw.com +lnddhxq.com +lndhdx.com +lndnw.com +lndwkj.com +lndxpt3.com +lndxptssl.com +lneab.com +lnemci.com +lnenergy.net +lnes.net +lnest.com +lnfdcxh.org +lnfssy.com +lnfzb.com +lngche.com +lngwy.org +lnhddq.com +lnhotels.com +lnhygy.com +lnicc-dl.com +lnicp.com +lninfo.com +lnjfyc.com +lnjmlnykjfzyxzrgs.com +lnjpedu.com +lnjzxy.com +lnkdjt.com +lnlawyers.net +lnlc2.net +lnldsw.com +lnlib.net +lnlon-zdh.com +lnlotto.com +lnmtc.com +lnmu3h.com +lnnoo.com +lnok.net +lnpatcm.com +lnpenger.com +lnphar.com +lnpjw.com +lnqwe.com +lnrbxmt.com +lnrcu.com +lnrsks.com +lnsenhai.com +lnsent.com +lnsgczb.com +lnsqxj.xyz +lnsrmyy.com +lnsslhyxh.com +lnsyzx.com +lnszyjt.com +lntenghui.com +lntvu.com +lntycp.com +lnvipsoft.com +lnwish.com +lnwoo.com +lnxmt.com +lnxysf.com +lnyahui.com +lnydjt.com +lnyxcj.com +lnyyzyxy.com +lnzcj.com +lnzhongka.com +lnzhqy.com +lnzikao.com +lnzsks.com +lnzy-edu.com +lnzzpf.com +lo97.com +loac.cc +loadingbay.com +loansliml.com +local-ip.online +local.hk +localizecdn.com +localxcafe.com +locatran.com +locez.com +locimg.com +lockchat.app +lockfans.com +lockin.com +lockinchina.com +locklauncher.com +lockscreenimg.com +locnavi.com +locojoy.com +locoy.com +locoyposter.com +locren.com +loctek.com +locvps.com +locvps.net +lodashjs.com +loexu.com +loftcn.com +lofter.com +loftshine.com +lofu.net +log-research.com +log1992.com +logacg.com +logclub.com +logdmentincomepay.sbs +logi.im +logi100.com +logicdsp.com +login.cdnetworks.com +logiseasy.com +logisteed-sc.com +logistics-ea.com +logisticstech.com +logo-emblem.com +logo123.net +logo2008.net +logo888.com +logo9.net +logoaa.com +logobiaozhi.com +logodao.com +logodashi.com +logohhh.com +logoly.pro +logoqq.com +logory.com +logoshe.com +logosheji.com +logosj.com +logovps.com +logowk.com +logozhizuowang.com +logwing.com +logwirecloud.com +lohaa.com +lohalink.com +lohand.com +lohasor.com +lohjs.com +lohkahhotels.com +loho88.com +lohu.info +loj.ac +loji.com +loke123.com +lokenchem.com +lokyi.name +lol99.com +lolaroseglobal.com +lolbuku.com +loldan.com +loldk.com +loli.by +loli.cloud +loli.ee +loli.net +loliapi.com +lolicon.team +loliloli.moe +loliloli.net +lolimoe.cc +lolitawardrobe.com +loljy.com +lolkeng.com +lollipopo.com +lolmax.com +lolmf.com +lolmz.com +lolphp.com +loltmall.com +lolxy.com +lolyculture.net +lomge.com +lomoment.com +lomon.com +lomowo.com +loncent.com +loncin.com +loncinindustries.com +londerful.com +londonermacaoresort.com +lonelystar.org +lonery.com +lonfoor.com +long-horn.com +long-photo.com +long-term.net +long.ge +long5.com +long7.com +longanlaw.com +longau.com +longbenren.com +longbridgeapp.com +longbridgehk.com +longcai.com +longcai027.com +longchangjixiekeji.com +longcheer.com +longchunbajiao.com +longclouds.com +longcore.com +longdameishi.com +longdaoyun.com +longde.com +longdear.com +longdear.net +longdian.com +longdiandianli.com +longduwang.com +longease.net +longfanshipping.com +longfengmarathon.com +longfor.com +longfu360.com +longguanjia.so +longhan.cc +longhoo.net +longhorn-auto.com +longhu.net +longhua.net +longhuafilm.com +longhufengyun.com +longhuiren.com +longhuquan.com +longhuvip.com +longi.com +longigroup.com +longjcun.com +longjiazuo.com +longjisteel.com +longjisz.com +longjitour.com +longjoy.net +longjunjiayuan.com +longk.com +longkui.site +longkunjituan.com +longkuntech.com +longlijituan.com +longlingas.com +longliqicom.com +longluo.me +longlycn.com +longmaosoft.com +longmarchspace.com +longmaywuliu.com +longmeicn.com +longmen-pharma.com +longmen.net +longmenedutech.com +longmeng.com +longmenshuju.com +longming.com +longmingdns.com +longnanke.com +longo.ltd +longoo.com +longood.com +longpokeji.com +longquan-baojian.com +longquecdn.com +longre.com +longrich.com +longsailing.net +longsan.com +longshanchemical.com +longshangrc.com +longsheng.com +longsheng988.com +longshine.com +longsok.com +longsto.com +longstonechina.com +longsunhd.com +longsys.com +longtaifoods.com +longtec.com +longtugame.com +longtuojixie.com +longu.com +longwangshipin.com +longwaycabinet.com +longwenedu.com +longwiki.org +longwin.org +longwintoys.com +longwisedata.com +longwisepr.com +longwx.com +longxi-tech.net +longxia.com +longxianwen.net +longxinfa.com +longxinglong.com +longxinli.com +longxintec.com +longxuan.ren +longyanbus.com +longyar.com +longygo.com +longyi-uav.com +longyin.net +longyinok.com +longyistudio.com +longyiyy.com +longyu.cc +longyucq.com +longyuedu.com +longyuegs.com +longyusheng.org +longyutec.com +longzhou.cc +longzhu.com +longzhu.tv +longzhudagroup.com +longzhulive.com +lonhcloud.net +lonleaf.com +lonlife.org +lonmedcn.com +lonsoon.com +lontengsteel.com +lontiumsemi.com +lontrue.com +lonyon.com +loocall.com +loocode.com +loodd.com +looeen.com +looeo.com +looeoo.com +loogoo.com +loohuo.com +looioo.com +lookae.com +lookao.com +lookbaby.com +lookbravo.com +lookchem.com +lookgame.com +looking-car.com +lookr.cc +looktm.com +looktmt.com +lookvin.com +loome.net +loonapp.com +loong3d.com +loongdriving.com +loongnix.com +loongnix.org +loongon.com +loongshine.com +loongsin.com +loongson.org +loongsonclub.com +loongtravel.com +loongxy.com +loonlog.com +looooker.com +loooooong.com +looquan.com +loorin.com +loovee.com +looyuoms.com +looyush.com +lopetech.net +loping151.site +lopmall.com +lopss.com +lopwon.com +lordabbettchina.com +lorefree.com +lorhf.com +lorienk.com +loring.xyz +lorzeal-zj.com +losergogogo.com +lossyou.com +lostdeer.xyz +lostphp.com +lostsakura.com +lot-ml.com +lotevision.com +lotianshangx.com +lotlab.org +lotour.com +lotour.net +lotpc.com +lotpen.com +lotsmv.com +lottery-sports.com +lotusair.net +lotusdata.com +lotusfr.com +lotut.com +loubobooo.com +louding.com +loudseas.com +louge.ltd +louislivi.com +louisvuittonbags.club +loukky.com +loulanwang.com +loupan.com +louruo.com +loushi.com +lousj.com +lousw.com +louyue.com +lovcuty.com +love-freedom.com +love-math-edu.com +love.tv +love21cn.com +love3721.com +love5201314.net +love5209420.com +love85g.com +loveabc.net +lovean.com +loveapp.com +lovebizhi.com +lovedword.com +loveforvenus.com +lovefree.cc +lovehaimi.com +lovehhy.net +lovehifi.com +loveifgames.com +loveinhere.com +loveinhtw.com +lovejavascript.com +lovejia.win +lovelacelee.com +lovelian.com +loveliao.com +lovellacountry.com +lovelyping.com +lovelytooth.com +lovemojito.com +lovengame.com +loveniwed.com +loveota.com +loveota.net +lovepd.com +loverdoor.com +lovesec.com +loveshang.com +lovesoo.org +lovestu.com +lovetan.net +loveteemo.com +loveu.life +loveuav.com +lovev.com +lovevibe1.com +lovewith.me +lovgiin.com +lovingedmond.com +lovol.com +lovology.com +loxpo.com +loyalvalleycapital.com +loyar.com +loyi.net +loyo.cc +loystnetwork.com +lp.fyi +lp023.com +lp025.com +lp91.com +lpaec.com +lpcheng.com +lpcues.com +lpd8888.com +lpetl.com +lpfile.com +lpgjkd.com +lph119.com +lpllol.com +lpmas.com +lpou.online +lppz.com +lppzimg.com +lpq1688.com +lprcx.com +lprogram.site +lpsckf.com +lpsign88.com +lpspt.com +lpswz.com +lpszstv.com +lptiyu.com +lpxinjuhui.com +lpxinke.com +lpxt.com +lpxuqi2057.vip +lpzine.com +lq5u.com +lqaafgq.com +lqabr.com +lqbby.com +lqbj.com +lqbj66.com +lqfeather.com +lqgy.com +lqhualang.com +lqjob88.com +lqjt.com +lqjyw.net +lqlst.com +lqpos.vip +lqqm.com +lqrcb.com +lqsbcl.net +lqschool.net +lqsilicon.com +lqtzjy.com +lqwang.com +lqxcl.com +lqxshop.com +lqxyljt.com +lqyaopin.com +lqyfsx.com +lqyqjt.com +lqzh.me +lqzp.com +lqzwdj.com +lr-amm.com +lr-link.com +lr8888.com +lrc99.com +lrcb.net +lrceu.com +lrcku.com +lrdcq.com +lrhold.net +lricn.com +lrist.com +lrkdzx.com +lrkj.net +lrlz.com +lrmation.com +lrnya.com +lrs001.com +lrscloud2.com +lrscloud3.com +lrt-tech.com +lrts.me +lrvin.com +ls-doll.com +ls-gb.com +ls-hospital.com +ls.link +ls0358.com +ls0513.com +ls102.com +ls1935.com +ls520.net +ls605.com +ls666.com +lsbankchina.com +lsbchina.com +lsbin.com +lsbj365.com +lsbtly.com +lsccb.com +lscstz.com +lscsw168.com +lsdfood.com +lsdjwl.com +lsdzk.com +lserp.com +lsfcj.com +lsfvideo.com +lsfwpt.com +lsfyw.net +lsgenius.com +lsgqys.com +lsgrandtheatre.com +lsgw.com +lsgwebmall.com +lsgzn.com +lsh-cat.com +lshdw.cc +lshfreda.com +lshitv.com +lshou.com +lshzj.com +lsij3km.com +lsit.net +lsjgcx.com +lsjiancai.com +lsjkj.com +lsjlp8.com +lsjnwxly.com +lsjo.com +lsjrcdn.com +lsjtjs.com +lsjxck.com +lsjxww.com +lskejisoft.com +lskem.com +lskj1993.com +lskjkf.com +lskong.com +lsldjyw.com +lslfs.com +lslgzn.com +lslihai.com +lsmaps.com +lsmtjy.com +lsmzt.cc +lsnm.com +lsoos.com +lspjy.com +lsplayer.com +lsqcjjt.com +lsqedu.com +lsqmx.com +lsqpay.com +lsqqy.com +lsqv.com +lsqx.com +lsqy398.com +lsrbs.net +lsrfzy.com +lsrmyy.com +lssdexternal.com +lssggzy.com +lssjt.com +lsswjt.com +lsszgh.com +lst1000.com +lstazl.com +lstest.com +lstt-app.com +lsttapp.com +lsttappmoney.com +lsttapppro.com +lsttappspace.com +lsttappweb.com +lsttappworks.com +lsttmoney.com +lsttnews.com +lsttonline.com +lsttpro.com +lsttrich.com +lsttweb.com +lsttworks.com +lstx.vip +lsun.net +lsuoled.com +lsup.net +lswfw.com +lswgy.com +lswld.com +lswqw.com +lsxrmtzx.com +lsxuantong.com +lsxxkj.net +lsyart.com +lsyhh.com +lsys2002.com +lszi.net +lszj.com +lszjy.com +lszjyj.com +lsznk.com +lsznkyy.com +lszp.cc +lszyy.net +lszzg.com +lt-edu.net +lt-info.net +lt-shanghai.com +lt-tree.com +lt-uv.com +lt3c.com +lt7293333.com +ltaaa.com +ltaaa.net +ltao.com +ltd.com +ltdcdn.com +ltdspot.com +ltesting.net +ltfwzs.com +ltggc.com +ltggzy.com +ltgtm.com +lth.xyz +lthqdl.com +ltidc.com +ltie.org +ltimg.net +ltjczx.com +ltjianhe.com +ltkgjt.com +ltkqjt.com +ltl5210.com +ltld.net +ltly.so +ltnic.com +ltoit.com +ltp-cloud.com +ltp.ai +ltplighting.com +ltpower.net +ltsbbs.com +ltsc.vip +ltsf.com +ltsj2005.com +ltski.com +ltswxy.com +lttconn.com +lttmgc.com +lttvip.com +ltwkw.com +ltwy.com +ltxbbs.com +ltxjob.com +ltxsw.co +ltxxgcxx.com +ltxys.com +lty.fun +ltyears.com +ltzsjt.com +ltzxw.com +ltzz666.com +lu.com +lu0.com +lu17996.com +lu35.com +lua.ren +lua99.com +luan.ma +luan163.com +luaninfo.com +luanren.com +luanup.com +luanwater.com +luanxian114.com +luanzhougucheng.com +luastudio.net +luatos.com +luba360.com +luban-furniture.com +lubandata.com +lubanjianye.com +lubanlebiao.com +lubanner.com +lubanpm.com +lubanshop.com +lubanso.com +lubansoft.com +lubanu.com +lubaocar.com +lubeichem.com +lubiao.com +lubotv.com +luboyun.com +luchengas.com +luchentech.com +luchenwater.com +luchuang.com +luciaz.me +lucifer.ren +lucifr.com +luck-number.com +luck808.com +luckao.com +luckeeinc.com +luckforcalendar.com +luckincalendar.com +luckincdn.com +luckincoffee.co +luckincoffee.com +luckincoffeecdn.com +lucklnk.com +luckmail.net +luckup.cc +lucky.gd +lucky286.com +lucky8k.com +luckyair.net +luckychipsmaster.com +luckycoffee.com +luckyop.com +luckysf.net +luckyxp.net +lucode.net +luctonchongqing.com +luctoncq.com +luctonshanghai.com +ludaocn.com +ludaopei-bjyz.com +ludashi.com +ludashicdn.com +ludashisafe.com +ludayq.com +ludedc.com +ludengtyn.com +ludeqi.com +ludiban.com +ludongyy.com +ludosuperstar.com +ludou.org +ludown.com +ludoworld.net +ludu319.com +lueasygi.com +luebin.com +luedian.com +luenmei.com +lueqiu.com +luexpo.com +lueyue.com +luezhi.com +lufahouse.com +lufangjia.com +lufaxcdn.com +lufengwuliu.net +lufengzhe.com +lufff.com +luffy.cc +luffycity.com +lufunds.com +lugangsoft.com +lugick.com +lugong.net +lugouqiaojiu.com +luguisc.com +luhai.net +luhaioil.com +luhao198.com +luhaoche.com +luhe.net +luhehospital.com +luhu.co +luhua.cc +luhuadong.com +luhuiwl.com +lujiaming.com +lujiandairy.com +lujianxin.com +lujiazuiforum.org +lujingtao.com +lujiya.com +lujun9972.win +lukachen.com +lukafei.com +lukechina.com +lukiwod.org +lukiya.com +lukou.com +lukuanart.com +lul8.com +lula.fun +lulala.com +lulaoshi.info +lulinux.com +lulisteel.com +lulubei.com +lulufind.com +lulugda.icu +luluhong.com +luluju.com +lum114.com +lumai.net +lumen-chip.com +lumiai.com +lumin.tech +lumingtec.com +lumiunited.com +lumosfun.com +lunalotus.online +lunannews.com +lunar2013.com +lunatdteteask.cfd +lundao.pub +luneng.com +lungai.com +lunkuokeji.com +lunlunapp.com +lunwengo.net +lunwenlib.com +lunwenstudy.com +lunwentong.com +lunwenxiazai.com +lunzima.net +luobo020.com +luobo360.com +luobotou.org +luobowin8.com +luoboxia.com +luochen.com +luochenyl.com +luochenzhimu.com +luodian.com +luodw.cc +luoergai.com +luofk.xyz +luoganpump.com +luogu.org +luohanacademy.com +luohanyu.cc +luohuedu.net +luojiaci.net +luojiadeyi.com +luojiji.com +luojilab.com +luojiweiye.com +luokuang.com +luolai.com +luolai.tech +luolaoguai.com +luolatu.com +luoli.net +luoluoluoluo.xyz +luomanxincai.com +luomanyueqi.com +luomapan.com +luomor.com +luoniushan.com +luoo.net +luoohu.com +luooqi.com +luopan.com +luoqiu.us +luoqiuzw.com +luori.net +luoshendao.com +luoshu.com +luoshuanchangjia.com +luosi.com +luosifen888.com +luosika.com +luosimao.com +luosoft.com +luotiannews.com +luotianyi.vc +luotuo101.com +luotuobang.net +luotuoshop.net +luowandianzi.com +luowave.com +luoxiang.com +luoxiangcheliang.com +luoxiaozi.com +luoxinyaoye.com +luoxudong.com +luoxue.com +luoyangdx.com +luoyangkeji.com +luoyangmalasong.com +luoyechenfei.com +luoying66.com +luoyingsh.com +luoyuanhang.com +luozhiyun.com +luozhongxu.com +luozongle.com +lup2p.com +lupaworld.com +luping.com +luqidong.com +lure123.com +lurefans.com +lurelogs.com +lurenshuwx.com +luruba.com +lurun68.com +lusen.com +luseng.cc +lush-mount.com +lushangroups.com +lushaojun.com +lushifu.net +lushu.com +lusongsong.com +luspet.com +lussac.net +luster3ds.com +lustervision.com +lustre-pharma.com +lusun.com +lusure-pharma.com +luszy.com +lutao.com +luteng888.com +lutongda.com +lutonggroup.com +lutongnet.com +luv66.com +luvoras.store +luwei.me +luweiwater.com +luxe.cc +luxe.co +luxemon.com +luxenixa.com +luxiangba.com +luxiangdong.com +luxiangwu.net +luxiaoche.com +luxichemical.com +luxiwang.com +luxshare-ict.com +luxtarget.com +luxuanart.com +luxuqing.com +luxury-ceramics.com +luxury2008.com +luxurybrandmall.com +luxurychina.org +luxurymany.com +luxuryshopwatch.com +luxvisions-inno.com +luyanghui.com +luyanhui.com +luyaodz.com +luye-pharm.com +luye.com +luyecanyin.com +luyijiaoyu.com +luyinla.com +luyinzhushou.com +luyitong.com +luyor.net +luyouqi.com +luyouqi.net +luyouwang.com +luyouwang.net +luyouxia.com +luyouxia.net +luyusheji.com +luyusoft.com +luzewangluo.com +luzexi.com +luzhonggonglu.com +luzhou.net +luzhoubs.com +luzhoufood.com +luzhouok.com +lv74.com +lv96.com +lvanol.com +lvbad.com +lvban365.com +lvbang.tech +lvbeijingtour.com +lvbenma.com +lvbitte.com +lvbogas.com +lvcai.biz +lvcampaign.com +lvcchong.com +lvchanghuanbao.com +lvchayun.com +lvchehui.com +lvcheng.com +lvchengba.com +lvchicar.com +lvd.cc +lvdawei.com +lvdhb.com +lvdingjia.com +lvdishandong.com +lvdongip.com +lvdxs.com +lve-china.com +lvfang.cc +lvfapiao.com +lvgangss.com +lvgou.com +lvgset.com +lvguo.net +lvhuawei.work +lvirahoe.com +lvjhx.com +lvjiaoya121.com +lvjieplus.com +lvjinsuo.com +lvjiwang.com +lvjuelaw.com +lvjuf.com +lvjunzx.com +lvkcn.com +lvke.wiki +lvkhouse.com +lvkun.site +lvlian5.com +lvluowang.com +lvlvlvyou.com +lvmae.com +lvmall.com.tw +lvmama.com +lvmenglvye.com +lvmifo.com +lvmushan.com +lvneng.com +lvnengliang.com +lvpai114.com +lvpin100.com +lvpu-chem.com +lvqingqichangjia.com +lvrdn.com +lvren.com +lvruanhome.com +lvsan.com +lvsanxia.com +lvse.com +lvsenbao.com +lvsetxt.com +lvsexitong.com +lvshidaxia.com +lvshiguan.com +lvshiminglu.com +lvshou.com +lvshou.net +lvshunmuseum.org +lvsiport.com +lvsongguo.com +lvtds.com +lvtingzs.com +lvtu100.com +lvtudiandian.com +lvtuwa.com +lvwan.com +lvwang.com +lvwenhan.com +lvwmb.com +lvxiaoer.net +lvxing.net +lvxunlaw.com +lvyahoo.com.tw +lvye.com +lvye.org +lvyestudy.com +lvyetong.com +lvyidoor.com +lvyinba.com +lvyinbar.com +lvyou168.net +lvyou521.com +lvyoubei.com +lvyouf.com +lvyoukan.com +lvyounong.com +lvyouw.net +lvysz.com +lvyuanjj.com +lvyuanpam.com +lvyuetravel.com +lvzeep.com +lvzheng.com +lw0591.com +lw0634.net +lw5188.com +lw54.com +lwalb.online +lwccc.net +lwcj.com +lwd3699.com +lwdjc.com +lwebapp.com +lwfengji.net +lwfmzh.com +lwgsw.com +lwguitar.com +lwhouse.com +lwinst.com +lwjhql.com +lwjl.com +lwjt.net +lwjy.net +lwlm.com +lwlocks.com +lwlt.net +lwlzy.com +lwnews.net +lwons.com +lwork.com +lwrcb.com +lwshanghai.org +lwshuku.info +lwsy.org +lwtylqx.com +lwurl.to +lwwandong.com +lwxgds.com +lwxs.com +lwxs11.com +lwxstxt.com +lwzls.com +lx.cok.elexapp.com +lx.pub +lx.run +lx138.com +lx2.cok.elex.com +lx2.cok.elexapp.com +lx3.cok.elexapp.com +lx598.com +lx688.com +lxapk.com +lxbio.net +lxblog.com +lxbtrip.com +lxccl.com +lxcdns.com +lxcvc.com +lxdas.com +lxdfs.com +lxdms.com +lxdns.com +lxdns.info +lxdns.net +lxdns.org +lxdp.net +lxdus.com +lxdvs.com +lxdvs.info +lxdvs.org +lxdvsss.com +lxdws.com +lxf.me +lxg2016.com +lxgcf.com +lxhg.com +lxhkair.com +lxhro.com +lxhuwai.com +lxhuwai.net +lxhz-avionics.com +lxi.me +lxjapp.com +lxjcjg.com +lxjiasu.com +lxkj.site +lxlinux.net +lxns.net +lxny.vip +lxq7t234u.shop +lxrcsc.com +lxsales.com +lxsec.com +lxsk.com +lxt55094.com +lxtianhu.com +lxtuig77.com +lxtuyoo.com +lxtuyoogame.com +lxtuyou.com +lxway.com +lxway.net +lxwlcn.com +lxxarq.com +lxxdyzx.com +lxxm.com +lxyai.com +lxybaike.com +lxydoor.com +lxyedu.com +lxyes.com +lxyjxsb.com +lxykjsz.com +lxyl020.com +lxyl028.com +lxyl053.com +lxyl070.com +lxyl071.com +lxyl219.com +lxyl247.com +lxyl328.com +lxyl335.com +lxyl353.com +lxyl355.com +lxyl375.com +lxyl539.com +lxyl803.com +lxyl954.com +lxyl980.com +lxyllawfirm.com +lxyswl.com +lxzjjt.com +lxzrmyy.com +lxzwedu.com +ly-eps.com +ly-jz.com +ly-qiche.com +ly-sky.com +ly.com +ly1by1.com +ly200-cdn.com +ly200.com +ly2y.com +ly321.com +ly333.com +ly39zx.com +ly522.com +ly6s.com +ly93.cc +lyagyd.com +lyangchuanbo.com +lyauto.com +lybdfqh.com +lybol.com +lybtmy.com +lybus.com +lybybz.com +lycheer.net +lyckw.com +lycs-arc.com +lyd-china.com +lyd6688.com +lydaas.com +lydezx.net +lydfyy.com +lydhb888.com +lydpjx.com +lydsy.com +lyduanzao.com +lydyyy.com +lyecs.com +lyenet.org +lyf.com +lyfangc.com +lyfc.com +lyfc001.com +lyfff.com +lyfsgy.com +lyfz.net +lyg.live +lyg001.com +lyg01.net +lyg1.com +lyg12371.com +lyg321.com +lyg800.com +lygcec.com +lygchkq.com +lygcjjt.com +lygcsyy.com +lygdfrcb.com +lygend.com +lygent.com +lygfdc.com +lygfish.com +lygfybj.com +lyggm.com +lyggmyk.com +lyghi.com +lyghs.net +lyghtyy.com +lygjdf.com +lygjkw.com +lygjkwljt.com +lygjtjt.com +lygjtkgjt.com +lygktj.com +lygl.net +lygmedia.com +lygnews.com +lygou.cc +lygrc.net +lygsgt.com +lygshjd.com +lygshlxh.com +lygxwmarathon.com +lygxwxqrmyy.com +lygyyjt.com +lygyyw.com +lyh666.asia +lyh8888.com +lyhb88.com +lyhendry.com +lyhero.com +lyhkh.com +lyhomestayinn.com +lyhuadu.com +lyhx.net +lyia.org +lyihub.com +lyilife.com +lyjiuzhou.com +lyjksw.com +lyjob.net +lyjunshi.com +lyjwatch.com +lyjy.net +lyjyfw.net +lyjyjt.com +lyjys.com +lylangchao.com +lyldhg.com +lylend.com +lylhkq.com +lylme.com +lylxjxc.com +lymarathon.com +lymmasu.xyz +lymy1684.com +lyngrhec.sbs +lynkco-test.com +lynkco.com +lynlzqy.com +lynne.ink +lyobs.com +lyou123.com +lyouoa.com +lypb.com +lypd.com +lypdl.com +lypower.com +lypyxx.com +lyqckyzz.com +lyqgm.com +lyqlm.com +lyquanshunmall.com +lyrc.cc +lyrcw.com +lyric-robot.com +lyrics.run +lysafety.com +lyscjc.com +lyshangdu.com +lyshark.com +lyshenglu.com +lyshgs.com +lysk.net +lysksw.com +lyslsw.com +lysq.com +lysqzs.com +lysswjt.com +lysteel.com +lyswjt.com +lysxtv.com +lysy360.com +lysyzx.com +lyszls.com +lyszxyy.com +lythw.com +lytoufang.com +lytpw.com +lytq.com +lytuanxue.com +lyuncloud.com +lyunle.com +lyunweb.com +lyunx.com +lyvnee.com +lywenlv.com +lywf.me +lywhxy.com +lywtpx.com +lywww.com +lywxww.com +lyxinhua.com +lyxltv.com +lyxsjmm.com +lyxyxx.com +lyy99.com +lyyapp.com +lyyg.com +lyyzedu.com +lyz810.com +lyzaix.com +lyzb.com +lyzb33.app +lyzfgjj.com +lyzggs.com +lyzhanlang.com +lyzlzz.com +lyzp100.com +lyzyxy.com +lz-qs.com +lz-redeem.com +lz-risun.com +lz-veoliawater.com +lz12328.com +lz310.com +lz520.net +lzabcd.com +lzahzn.com +lzailin.com +lzane.com +lzaotw.com +lzarays.com +lzb.im +lzbank.com +lzbaosteel.com +lzbcjt.com +lzbhmy.com +lzc369.com +lzcasting.com +lzcbnews.com +lzccb.com +lzcf.net +lzcgty.com +lzchcnc.com +lzchenhui.com +lzchjs.com +lzcits.com +lzcrjs.com +lzctbyq.com +lzcyjt.com +lzdchotel.com +lzdcic.com +lzdd.com +lzdfxj.com +lzdjjd.com +lzdql.com +lzdsqcysgs.com +lzdsyy.com +lzdxb888.com +lzdxdyyy.com +lzdymy.com +lzdyyy.com +lzetyy.com +lzeweb.com +lzfcjys.com +lzfdjt.com +lzfjq.com +lzfqty.com +lzfssp2007.com +lzftah.com +lzfyhgm.com +lzfzct.com +lzgas.com +lzgbdst.com +lzgd.net +lzghmy.com +lzgjcxkj.com +lzgjschool.com +lzgkyq.com +lzgm.com +lzgps.com +lzgryy.com +lzhanghai.com +lzhaoteng.com +lzhdtk.com +lzhean.com +lzhf.com +lzhhuinong.com +lzhjuszs.com +lzhl.online +lzhmmr.com +lzhongdian.com +lzhpo.com +lzhrobot.com +lzhszhyy.com +lzhtwl.com +lzhuali.com +lzhuinong.com +lzhygame.com +lzhyjd.com +lzihospital.com +lziig.com +lzimall.com +lzimc.com +lzjchina.com +lzjcm.com +lzjd.com +lzjiajuw.com +lzjianlong.com +lzjingda.com +lzjldj.com +lzjoy.com +lzjuhu.com +lzjyy.com +lzkajc.com +lzkczy.com +lzkjedu.com +lzklkqyy.com +lzknpco.com +lzkojj.com +lzky.com +lzl98.com +lzlatc.com +lzlcba.com +lzlgyy.com +lzlhpq.com +lzlj.com +lzljc.com +lzljmall.com +lzlmyyl.com +lzlqc.com +lzlrxx.com +lzlsl.com +lzlsy.com +lzltong.com +lzltool.com +lzlxylsf.com +lzlygs.com +lzmachine.net +lzmaoliu.com +lzmbhj.com +lzmckq.com +lzmei.com +lzmljdzx.com +lzmoyin.com +lzmun.com +lzmy123.com +lznbjz.com +lznetease.com +lznrlmxh.com +lzoam.com +lzolm.com +lzorient.com +lzpfei.com +lzpmia.com +lzppt.com +lzprocess.com +lzqjjx.com +lzqjsm.com +lzqqpcts.com +lzqxjx.com +lzranqi.com +lzrfc.com +lzrfhg.com +lzrimd.com +lzrkjx.com +lzrmzx.com +lzro.net +lzrq.com +lzry.com +lzsajzl.com +lzsansong.com +lzsb.org +lzsey.com +lzseygs.com +lzseyy.com +lzsfdq.com +lzsfy.com +lzsgmf.com +lzsjhjx.com +lzskqyy.com +lzskx.com +lzslgcj.com +lzslong.com +lzsmedia.com +lzsmxzy.com +lzsq.net +lzsrsj.com +lzsunspot.com +lzswmsj.com +lztb.com +lztdzy.com +lzteli.com +lztlcyxx.com +lztvnet.com +lztx123.com +lztxw.com +lztzgroup.com +lzweidaoyou.com +lzwg.com +lzwi.fun +lzwls.com +lzwopu.com +lzwsgs.com +lzwx.com +lzxbook.com +lzxfmc.com +lzxinjiu.com +lzxinwenwang.com +lzxishaj.com +lzxjet.com +lzxlgg.com +lzxnqt.com +lzxqlgwl.com +lzxqm.com +lzxqsmwl.com +lzxqswjt.com +lzxrmtzx.com +lzxrmyy.com +lzxy.com +lzyd.com +lzydby.com +lzyec.com +lzyfoods.net +lzygpm.com +lzyhcy.com +lzyhdyf.com +lzyisheng.com +lzyizhu.com +lzylkf.com +lzylqc.com +lzyoushang.com +lzyrwz.com +lzytbl.com +lzyts.com +lzyuantong.com +lzyun.vip +lzyxfs.com +lzyxsoft.net +lzyyy.com +lzyz.fun +lzyz.org +lzyzbz.com +lzyzx.net +lzyzxzyy.com +lzzcloud.net +lzzf.com +lzzg365.com +lzzgljj.com +lzzhdq.com +lzzhhq.com +lzzhongke.com +lzzkzs.com +lzzl.net +lzzlsoft.com +lzznbyq.com +lzzrgas.com +lzzy.net +lzzyy.com +m-edu.com +m-finder.com +m-hero.com +m-rainbow.com +m-team.cc +m.567it.com +m.travelzoo.com +m1.run +m123.com +m1315.com +m176.net +m186.net +m188.com +m1905.com +m1938.com +m1ok.com +m1page.com +m1world.com +m1xia.com +m2ez.com +m2mlib.com +m2mzy.com +m2time.net +m3-cloud.com +m3guo.com +m3kaiye.com +m3mk7nyo17.com +m3u8.file.leshantv.net +m3u8channel-bx.wuxianyaan.com +m3u8channel-ms.wuxianyaan.com +m3u8channel-sm.wuxianyaan.com +m3u8channel-yc.wuxianyaan.com +m3u8channel-yj.wuxianyaan.com +m3u8channel.wuxianyaan.com +m448.com +m4vmsozi62ifz.com +m5bn.com +m5m6x0vh.com +m5stack.com +m6.run +m6tza3ip7x8zr1.com +m7686d7aw5.com +m7hwocyo67.com +m8.com +m818.com +m9.run +m937.com +m999.com +m9c7ayme59tp.com +m9dz.com +ma-china.com +ma.run +ma3office.com +ma3you.com +ma5000.com +maa.plus +maaend.com +maanhui.com +maasdk.com +mabangerp.com +mabaozhuyun.com +mabiji.com +mabotech.com +mac169.com +mac189.com +mac69.com +mac89.com +macabc.com +macaobusinessnews.com +macaotourism.gov.mo +macapp8.com +macappbox.com +macat.vip +macaucentral.com +macauchenguangji.com +macaumonthly.net +macauo2o.com +macaupass.com +maccms.site +maccmsbox.com +maccura.com +macdaxue.com +macgene.com +macgood.com +machaojin.com +machenike.com +machine-information.com +machine-jh.com +machine-visions.com +machine35.com +machinery4stone.com +machloop.cc +machloop.com +machloop.net +machmall.com +machtalk.net +macjb.com +mackentan.com +mackext.com +macmao.com +macmicst.com +macocn.com +macoshome.com +macpeers.com +macrolake.com +macroprocess.com +macrosan.com +macrosilicon.com +macrounion.com +macrowing.com +macrozheng.com +macrr.com +macs.vip +macsc.com +macsem.com +macshuo.com +macsky.net +macsz.com +macv.com +macw.com +macxf.com +macxin.com +macxz.com +macz.com +maczd.com +maczhi.com +maczj.com +maczl.com +madaicaifu.com +madailicai.com +madajiefood.com +madaomall.com +madboxi.com +madefuns.com +madeinchinastone.com +madewei.com +madiancan.com +madio.net +madisonboom.com +madissonline.com +madmalls.com +madouvip.com +madouym.com +madsam.work +madsrevolution.net +maemo.cc +maershan.org +mafa.tech +mafadns.com +mafengs.com +mafengwo.com +mafengwo.net +mafengwoo.com +maff.com +mag10000.com +magadanryba.com +magaoedu.com +magcloud.net +magecorn.com +magedu.com +magentochina.org +magewell.com +magfx-jbkk.com +magi.com +magic-school.com +magich5page.com +magicleaders.com +magicneko.com +magicnetmall.com +magics-ad.com +magics.plus +magictavern.com +magicw3.com +magicwatchface.com +magicwinmail.com +magireco.moe +magma.ink +magnotel.com +magook.com +magpiepharma.com +magtechjournal.com +maguang.net +magvision.com +mahailushu.com +mahjongai.com +mahjongai.net +mahjongcup.com +mahjongcup.net +mahoupao.com +mahua.com +mahuatalk.com +mai.com +mai.tn +maianhao.com +maibaapp.com +maibaihuo.com +maibangbang.net +maibaokeji.com +maibuymai.com +maichawang.com +maiche.com +maiche168.com +maicheme.com +maichuang.net +maicro.com +maicuole.com +maidang.cool +maidangao.com +maidelong.com +maidengju.net +maideyi.com +maidiancy.com +maidige.com +maiditu.com +maidong100.com +maidongxi.com +maidou.com +maidouke.com +maidrom.net +maiduo.com +maie.name +maifjb.com +maigoo.com +maihaoche.com +maihaojiu.com +maihaome.com +maihaowan.com +maihaowuyou.com +maihaoyou.com +maihengqi.com +maihuacha.com +maihuominiapps.com +maihuwai.com +maijia.com +maijiakan.com +maijiaw.com +maijiazhichi.com +maijichuang.net +maijiemedia.com +maikami.vip +maikongjian.com +maikr.com +mail-bitgate.net +mail163.com +mail4399.com +maila88.com +maileds.com +mailehudong.com +mailejifen.com +mailetian.com +mailianou.com +mailiku.com +mailixing.com +mailizc.com +mailpanda.com +mailshanguo.com +mailyun.net +maimaibao.com +maimaiche.com +maimaidx.cc +maimaigongkong.com +maimaimaiw.com +maimemo.com +maimemostatus.com +maimiaotech.com +mainaer.com +mainaffyn-dev.com +maindown4399.com +maine1688.com +mainlandip.com +mainlandmed.com +mainshe.com +maintao.com +mainwww.com +mainyou.com +maipu.com +maipyi.com +maiqun.vip +maiqunwang.com +mairoot.com +mairuancn.com +maisanqi.com +maiscrm.com +maiseed.com +maishebei.com +maishitv.com +maishou88.com +maishoumm.com +maisry.net +maissn.com +maisu.vip +maisucai.com +maisui1.com +maitao.com +maitaowang.com +maitegao.com +maitewang.com +maitix.com +maitix.net +maitu.cc +maituan.com +maitube.com +maiuspharma.com +maiwe.com +maiweikj.com +maixhub.com +maixiaba.com +maixiang.net +maixiaodao.com +maixinxin.com +maiya91.com +maiyadi.com +maiyanju.com +maiyaole.com +maiyayk.com +maiyuesoft.com +maiyuren.com +maizer.pw +maizhi.com +maizhixiu.com +maizhuanbao.com +maiziedu.com +maizipo.com +maizuo.com +majia99.com +majiamen.com +majiang520.com +majilive.com +major-epoch.com +majorbio.com +majorprecious.com +majorsec.com +majsoul.com +maka.im +maka.mobi +makaevent.com +makaidong.com +makaiqian.com +make-w0rld-static.club +makeapp.co +makeblock.com +makecn.net +makedie.me +makeeu.com +makefang.com +makefont.com +makelie.com +makelove.la +makenv.com +makeoptim.com +makepic.net +makepolo.com +makepolo.net +makerbio.com +makeronly.com +makeronsite.com +maketion.com +makeweiyuan.com +making.link +mala123.com +malabeibei.com +malagis.com +malait.com +malajikuai.com +malata.com +malaysia-mdac.com +maldiveszh.com +maldun.com +males120.com +malifenlawyer.com +malifuke.org +malimalihome.net +malingguzhai.com +maliquankai.com +maliuliu.com +mall-builder.com +mall.com +mallchina.net +mallchina.org +mallcoo.net +mallhaha.com +mallocfree.com +mallshow.net +mallstaroa.com +mallzhe.com +mallzto.com +malmam.com +malong.com +maloyonline.com +malsmiles.com +maltm.com +mama100.com +mamabearoasis.site +mamacn.com +mamahao.com +mamahuo.com +mamayz.com +mambasms.com +mambike.com +mamcharge.com +mamecn.com +mamicode.com +mamioo.com +mamoe.net +mamsh.org +mamumall.com +man6.org +managershare.com +manamana.net +manben.com +manbetxoo.com +manbetxrr.com +manboker.com +manbu.cc +manchengpiaoxiang.com +manco-logistics.com +manction.com +mandao-tech.com +mandarinedu.org +mandarinhouse.com +mandarinmorning.net +mandashu.com +mande-car.com +mandian.com +mandiankan.com +mandnsv1.com +mandnsv1.net +mandudu.com +manduhu.com +manew.com +manewvr.com +manfen.net +manfen5.com +manfenyufa.com +manfred-auto.com +manfrottoclub.com +mangafuna.site +mangafuna.xyz +manganesenanhai.com +mangg.com +mangguo.com +mangguo168.com +mangguonews.com +mangjianghuole.com +mangocity.com +mangoebike.com +mangoent.com +mangoerp.com +mangogame.com +mangolm.com +mangomob.net +mangoru.site +mangpielb.com +mangren.com +mangrovetek.com +mangrovetreeresort.com +mangroviarestaurant.com +mangtian.com +mangtuhuyu.com +manguo42.com +mangxia.com +mangxuewang.com +mangzhongbrand.com +mangzitian.com +mangzx.com +manhinggroup.com +manhua1.com +manhua365.com +manhua8.net +manhuacheng.com +manhuadaohang.com +manhualang.com +manhuang.org +manhuapi.com +manhuatai.com +manjiwang.com +mankebao.com +mankewenxue.cc +manlaxy.com +manlaxycloud.com +manli.ltd +manlinggame.com +manlinwood.com +manluoni.com +manluotuo.com +manmanapp.com +manmanbuy.com +manmango.com +manmankan.com +manmanzou.com +manmeilp.com +manmeng168.com +manmu.net +mannian.com +manogk.com +manongdao.com +manonggu.com +manongjc.com +manosp.com +manpianyi.com +manpowergrc.com +manrong.win +manshaoco.com +manshijian.com +mantachina.com +mantangc.com +mantewei.com +mantianfei.net +mantusy.com +manulife-sinochem.com +manuscripk.com +manwahholdings.com +manxing.net +manxiu-law.com +manyacan.com +manylaw.com +manyoo.net +manyoujing.net +manyoukeji2024.com +manyoumao.com +manyupay.com +manzhai.net +manzhan.com +manzu365.com +manzuo.com +manzuocaipu.com +manzx.com +mao-shen.com +mao.fan +mao35.com +maobob123.com +maobotv.com +maobugames.com +maodou.com +maodouapp.com +maodouketang.com +maoercdn.com +maoflag.net +maogang.com +maogepingbeauty.com +maogepingedu.com +maogp.com +maogua.com +maogumaogu.com +maogx.win +maoha.com +maohongdz.com +maojiaoque.com +maojiuxs.com +maokangbio.com +maoken.com +maoln.com +maolog.com +maomao365.com +maomaoche.com +maomaoxue.com +maomaoyuanma.com +maomijiaoyi.com +maomilingyang.com +maomob.com +maomp.com +maomp.icu +maono.com +maopaoya.com +maopuyouxi.com +maoqitian.com +maoqiumail.com +maoshanger.com +maotao.net +maotiangroup.com +maotuan.net +maotuying.com +maowotao.com +maoxia007.com +maoxiangai.com +maoxinhang.com +maoxinquan.net +maoxiongtv.com +maoyachen.com +maoyan.com +maoyanqing.com +maoye-smd.com +maoyi.biz +maoyidi.com +maoyigu.com +maoyingaipu.com +maoyouxi.com +maoyun.com +maoyun.tv +maoyuncloud.com +maozhishi.com +maozhuar.com +maozhuashow.com +map-tencent.com +map17.com +map456.com +map456.net +mapabc.com +mapbar.com +mapeng.net +mapfarm.com +mapgis.com +mapgx.com +maphuan.com +mapks.com +maple-game.com +maple.ren +maplecheck.tech +maplef.net +mapmapping.com +mappn.com +maproelec.com +maptalks.com +mapvq.com +maqingbo.com +maqinnews.com +mararun.com +marathonbm.com +marathonchangsha.com +marazziguide.com +marchinfo.com +marco-bj.com +marcopolochina.com +marginalk.com +mariedalgar.com +marimekko-hots.com +marine-dancer.com +marinedancer.com +marioall.com +marioin.com +mariowap.com +marisfrolg.com +maritime-dg.com +markdown.xyz +markdream.com +markedboat.com +marketingconv.com +marketingforce.com +markfairwhale.com +markiapp.com +markji.com +markjour.com +markmall.com +markmiao.com +marknum.com +markorchem.com +markorhome.com +marksmile.com +marljoy.com +marmot-cloud.com +maro6.com +marry5.com +mars-block.com +marshal-ceramics.com +marshallscarlett.shop +marshotspot.com +marssenger.com +marstor.com +marstv.com +marsvis.com +martech365.com +martin8023.com +martincl2.me +martinlofts.com +marto.cc +marvelunlimitedresources.com +maryek.net +marylandtenthcavalry.org +mas10010.com +mas300275.com +masastack.com +mascaw.com +masdjy.com +maseek.com +masej.com +maseven.com +masff.com +masgjjt.com +masgw.com +mashang98.com +mashangfangxin.com +mashangfl.com +mashangmai.com +mashangshijie.com +mashangxue123.com +mashiro.me +mashqkq.com +mashrabiya-screen.com +masiao.com +masikkk.com +masjfc.com +masjinquan.com +maslink.com +maslong.com +mason-led.com +mason-optics.com +maspiece.com +masqhboat.com +mass-evo.com +massage-hospital.com +massclouds.com +masscrunch.com +massestech.com +massx.com +masszxyy.com +masteam.com +master-home.com +mastercardnucc.com +masterchefworks.com +masterfy.com +mastergo.com +masterkongchef.com +masterlab.vip +masterofmalteu.shop +masterofsoccer.com +mastersay.com +mastersim123.com +mastodonhub.com +masttoards.com +mastv.cc +mastvnet.com +masyi.com +masyunrui.com +mat-rev.com +mat-test.com +matao.com +match-much.com +matchboxnetwork.com +matchsaas.com +matchupexpo.com +matchvs.com +mate.vip +mateair.com +mater-rep.com +material.istreamsche.com +matfron.com +math168.com +mathartsys.com +mathchina.com +mathcn.com +mathfan.com +mathleague.hk +mathoe.com +mathpretty.com +mati.hk +matistyle.com +matlabsky.com +matoaudio.com +matocloud.com +matongxue.com +matpool.com +matpool.net +matrix-chem.com +matrix-net.tech +matrixchuang.com +matrixerse.com +matrixscrm.com +matrixsens.com +matsubayashi-op.com +matsuri.icu +matsuri.site +matt33.com +mattressmachinery.net +mauu.me +mawei.live +mawentao.com +mawhome.com +max-c.com +maxamchina.com +maxd.cloud +maxdo.net +maxfinesthair.com +maxfor-tool.com +maxgamehub.com +maxgj.net +maxhub.com +maxhub.vip +maxiang.info +maxiang.io +maxiaobang.com +maximajt.com +maximfiber.com +maxing128.com +maxinovel.com +maxio-tech.com +maxitas.com +maxjia.com +maxkamsofarms.com +maxket.com +maxlu.net +maxmindpharma.com +maxng.cc +maxok.com +maxonc.com +maxonesemi.com +maxonesoft.com +maxowen.com +maxpda.com +maxqiu.com +maxreader.la +maxreader.net +maxscend.com +maxsewing.com +maxspeedgf.com +maxtop.online +maxuscloud.com +maxviewrealty.com +maxway-logistics.com +maxwealthfund.com +maxwi.com +maxxipoint.com +may.ltd +maya09.com +maya777.com +mayabot.com +mayahuashi.com +mayanchina.com +maybe2016.com +maycpay.com +maycur.com +maydeal.com +maydo.group +mayerse.com +mayi.com +mayiangel.com +mayicms.com +mayihr.com +mayiic.com +mayikankan.com +mayikt.vip +mayima.net +mayishebao.com +mayishoubei.com +mayitek.com +mayitxt.com +mayiui.com +mayiw.com +mayiwenku.com +mayiwsk.com +mayiyx.com +mayizhuanlan.com +maylandresort.com +maylove2333.com +mayora-sh.com +mayshijia.com +maysun.net +mayswind.net +mayunbj.com +maywant.com +maywonenergy.com +mazakii.com +mazc.org +mazey.net +mazhan.com +mazhen.tech +mazhizuo.com +mazida.com +mb-go.com +mb2p.com +mb5u.com +mba518.com +mbabao.com +mbachina.com +mbadashi.com +mbadbaedu.com +mbajs.com +mbalib.com +mbanggo.com +mbatrip.com +mbazl.com +mbazsw.com +mbb0760.com +mbb180.com +mbbrowser.com +mbbs.cc +mbcloud.com +mbd.pub +mbdkjsw.com +mbestway.com +mbg06290pg.com +mbg06301pg.com +mbgo.com +mbian.com +mbiaohui.com +mbigfish.com +mbimc.com +mbinary.xyz +mbiosh.com +mbitrres.net +mbkfj1656.com +mbksh.com +mblaudio.com +mbldbb.com +mblog.club +mblu.com +mblyun.com +mbo-china.com +mbokee.com +mbs.download.prss.microsoft.com +mbsifu.com +mbsuat.download.prss.microsoft.com +mbti16cc.com +mbtools.work +mbwxzx.hk +mbysrobot.com +mbzhu.net +mc-biolab.com +mc-ccpit.com +mc-dj.com +mc-f.com +mc-test.com +mc-user.com +mc-xborder.com +mc.cc +mc520.com +mc91.com +mc9y.net +mcake.com +mcbaas.work +mcbang.com +mcbao.com +mcbbs.co +mcbbs.jp +mcbbs.net +mcbeam.pro +mcc0.com +mcc460.pub.3gppnetwork.org +mccbim.com +mccchina.com +mccshhospital.com +mcd.cc +mcdchina.net +mcdemo.show +mcdsusan.com +mcdvisa.com +mcearnmore.com +mcecy.com +mceebbs.com +mcepchina.org +mcfound.net +mcfui.work +mcfun.tv +mcfxw.com +mcgsjt.com +mchanmai.com +mchat.com +mchifi.com +mchim.net +mchost.guru +mchpk.com +mchuiji.com +mchweb.net +mchxx.net +mcidc.net +mcit.tech +mcjd.net +mckuai.com +mcloudvr.com +mcmap.cc +mcmarkets.com +mcmaster-asia.com +mcmqyc.com +mcmsmp.com +mcmssc.com +mcmtek.com +mcmusic.hk +mcnav.net +mcneko.com +mcnjigou.com +mcobj.com +mcohmygod.com +mcoo.cc +mcooks.com +mcool.com +mcpemaster.com +mcpfks.com +mcpmaid.com +mcq93.app +mcqy.net +mcsafebox.com +mcsgis.com +mcshuo.com +mctcn.com +mcu-home.com +mcue.cc +mcufan.com +mcuisp.com +mcusky.com +mcuzj.com +mcuzone.com +mcuzx.net +mcw99.com +mcwell66.com +mcwizrd.com +mcwshop.com +mcx666.com +mcxyzt.cc +mcxzs.com +mcyhfl.com +mcypls.com +mcyz.com +mczhihui.com +mczmb.org +mczwlt.net +mczyz.com +mczz.net +md-hmjt.com +md-pms.com +md5ma.com +mdapp.tv +mdbchina.com +mdbimg.com +mdclub.org +mdddg.com +mddj.com +mddlsa.com +mdeasydiagnosis.com +mdeer.com +mdex.co +mdex.com +mdfkyiyuan.com +mdfors.com +mdhky.com +mditie.com +mdjgjjt.com +mdkj1.com +mdl.ink +mdlf.xyz +mdm.plus +mdmccq.com +mdmmm.com +mdmt.com +mdnice.com +mdouvip.com +mdouwz.com +mdpda.com +mdpetrotech.com +mdrmyy.com +mdsin.com +mdsmos.com +mdsyzx.com +mdtu.com +mdupc.com +mdvdns.com +mdwyservice.com +mdxs.com +mdxw.work +mdy-edu.com +mdybk.com +mdydt.net +mdymedical.com +mdyseducation.org +mdyuepai.com +mdzgjx.com +mdzx.net +me-city.com +me-game.com +me-tencent.com +me.com +me1.ltd +me360.com +me361.com +me4399.com +meadin.com +meaningfulcloud.com +meanwell.cc +meb.com +mebhaoya.com +mebo.com +mebtf.com +mebyk.com +mecaraiotp.org +mechatim.com +mechina.org +mechr.com +mechrevo.com +mecoxlane.com +mecru.com +mecsz.com +mecue.cc +med-123.com +med-linket.com +med-water.com +med123.com +med126.com +med139.com +med66.com +meda.cc +medbotsurgical.com +medcaren.com +medcmz.com +meddatas.com +medebound.com +medejob.com +medeming.com +media.fantv.hk +media.joycorp.co.kr +media.paperclipclub.net +media.trrtv.com +mediaprima.rastream.com +mediastory.cc +mediatek.com +mediaxinan.com +medical-union.com +medicalqc.com +medicexam.net +mediecogroup.com +medifinit.com +medilinkthera.com +medinoah.com +mediparksh.com +meditrustbroker.com +meditrusthealth.com +mediumvis.com +medixcloud.com +medkaoyan.net +medlander.com +medlinkchina.com +medlinker.com +medlinker.net +medme.net +medmeeting.org +mednovogroup.com +medrc.net +medreading.com +medris-china.com +medscrm.com +medstarcorp.com +medsuture.com +medtechshare.com +medtimes-hk.com +medtion.com +medwant.com +meecec.com +meegobeta.com +meegoe.com +meekdai.com +meeket.com +meeshow.com +meet-in-shanghai.net +meet99.com +meetbf.com +meetfave.com +meethall.com +meethome.com +meeting.so +meeting666.com +meetingmeet.com +meetingrj.com +meetlawyer.com +meetsite.com +meetsocial.com +meetsoho.com +meetsprring.com +meetuvip.com +meetwhale.com +meetxian.com +meetyoumuseum.com +meetzoom.net +mefcl.com +mefenglife.com +mefenlife.com +mega555net10.org +megaemoji.com +megaer.com +megagamelog.com +megagenchina.com +megahugo.net +megalithwatch.com +megarobo.com +megasig.com +megawords.cc +megcup.com +megmeet-welding.com +megobike.com +megou8.com +meguo.com +meguri.app +meguri.moe +megvii-inc.com +megvii.com +meheco.com +mehecointl.com +mei-shu.com +mei-shu.net +mei.com +mei1.com +mei1.info +meia.me +meianclean.com +meianjuwang.com +meiaoju.com +meiba.com +meibaiwu.com +meibanla.com +meibei.com +meibg.com +meibgroup.com +meican.com +meicanstatic.com +meichen.cc +meichengchongdian.com +meichenindustry.com +meichibao.com +meichuanchuan.com +meichuanmei.com +meichunmed.com +meici.com +meida.com +meidaifu.com +meidanylon.com +meidaogg.com +meidaojia.com +meide-casting.com +meidebi.com +meidecloud.com +meideng.net +meidepump.net +meidongauto.com +meidunyipin.com +meidusacloud.com +meierbei.com +meifang.com +meifang8.com +meifangquan.com +meifazhan.com +meifengli.com +meigeinc.com +meigongyun.com +meiguanjia.net +meiguiauto.com +meiguiwxw.com +meiguo-qianzheng.com +meiguogouwu.com +meiguoxiaoxue.com +meiguoxq.com +meigushe.com +meih5.net +meiheups.com +meihouyun.com +meihu99.com +meihua.info +meihuainfo.com +meihuapacking.com +meihuboyue.com +meihudong.com +meihutong.com +meiji-icecream.com +meijia51.com +meijiadaren.com +meijiaedu.com +meijiandaojia.com +meijianpin.com +meijiashang.com +meijiavip.com +meijiebijia.com +meijieclub.com +meijiedaka.com +meijiehang.com +meijiehezi.com +meijieku.com +meijiequan.com +meijieu.com +meijiexia.com +meijieyizhan.com +meijiezaixian.com +meijiezaixian.net +meijipharma.net +meijipower.com +meijiu.com +meijubo.com +meijufans.com +meijuniao.net +meijuq.com +meijust.com +meika360.com +meikai1979.com +meikanguo.com +meikankeji.com +meikao.com +meikeda.net +meikevideo.com +meikongte.com +meikr.com +meiktv.com +meiku123.com +meilandianzi.com +meilanrilan.com +meilaoshi.com +meili-inc.com +meili-oh.com +meili43.com +meilichengren.com +meilidongnanya.com +meiligaosu.com +meilijia.com +meilijian.com +meiling.com +meilishuo.com +meilishuo.net +meilisite.com +meiliwang.org +meiliworks.com +meiljiaqi.com +meilunmeijia.com +meilvtong.com +meimedical.com +meimeidu.com +meimeifa.com +meimeiriji.com +meimeiyouxin.com +meimianjiafang.com +meiming8.com +meimingbao.net +meimingteng.com +meimingxuan.com +meinali.com +meinenggas.com +meinenggou.com +meinv.com +meiobrand.com +meionetech.com +meip0.me +meip1.me +meip4.me +meipai.com +meipaixiu.com +meipeng518.com +meipian.me +meipian2.com +meipingmeiwu.com +meipuapp.com +meipvip.net +meiqiacloud.com +meiqiausercontent.com +meiqinedu.com +meiquankongjian.com +meirenchong.com +meirijinrong.com +meiritv.net +meirixz.com +meiriyiwen.com +meirong.net +meirongchuang.com +meirongshanghai.com +meishai.com +meishanjob.com +meishanren.com +meishe-app.com +meisheapp.com +meishesdk.com +meishi.cc +meishi13.com +meishichina.com +meishiffx.online +meishij.net +meishijr.com +meishilife.com +meishiqin.com +meishischool.com +meishiwangluo.com +meishizuofa.com +meishow.com +meishu.com +meishubao.com +meishutuku.com +meisilin.com +meisubq.com +meisupic.com +meitangdehulu.com +meitanjianghu.com +meitanwang.com +meite.com +meitegou.com +meitianhui.com +meitianzuche.com +meitie.com +meitifagao.com +meitong-tech.com +meitq.com +meitu-int.com +meitu-mobile.com +meitu.com +meitu.net +meituaccount.com +meituan.com +meituan.net +meitubase.com +meitubeauty.com +meitubf.com +meitubox.com +meitucam.com +meitucamera.com +meitucoffee.com +meitudashi.com +meitudata.com +meituduoduo.com +meitufamily.com +meitufans.com +meitugif.com +meituhezi.com +meituhuahua.com +meituinside.com +meitukankan.com +meitukiss.com +meitumail.com +meitumob.com +meitumobile.com +meitumv.com +meitun.com +meituncdn.com +meituo.shop +meitupaipai.com +meitupic.com +meitupingzi.com +meituriji.com +meiturom.com +meitushijie.com +meitushop.com +meitushouji.com +meitusiyu.com +meitusnap.com +meitustatic.com +meitustore.com +meitutaotao.com +meitutg.com +meitutietie.com +meituxiangji.com +meituxiaopu.com +meituxiu.com +meituxiuxiu.com +meituyidong.com +meituyuan.com +meituyun.com +meiwafuying.com +meiweibf.com +meiweigroup.com +meiweis.com +meiweishudan.com +meiwpkpu.com +meiwulist.com +meixin.com +meixincdn.com +meixinl.com +meixinqi.com +meixiong5.com +meiya.com +meiyaapp.com +meiyacup.com +meiyan.chat +meiyan.com +meiyan.tech +meiyanstatic.com +meiyatour.com +meiye.art +meiyedana.com +meiyi.ai +meiyixinrui.com +meiyou.com +meiyue.com +meiyujt.net +meiyuko.com +meiyuwang.com +meizhan.com +meizhandian.com +meizhanggui.cc +meizhi-cn.com +meizhou.com +meizhou.net +meizitu.net +meizu.com +meizu.com.hk +meizu.net +meizuapi.com +mejorrelojes.com +mejxw.com +meke8.com +mekedoo.com +meldingcloud.com +melecode.com +melizhi.com +mellowactivy.com +mellowgroups.com +melon-eptc.com +melon.cdnetworks.com +melon.icu +meloong.com +melotgroup.com +memblaze.com +memewan.com +memeyin.com +memeyule.com +memfiredb.com +memofun.net +memorieslab.com +memoverflow.com +mems.me +memsconsulting.com +memsensing.com +memsflex.com +memsic.com +memuplay.com +memuu.com +memyy.com +men.ci +menchuang.biz +menchuang58.com +menci.xyz +mendale.com +mendd.com +menducn.com +meng-model.com +meng2u.com +meng3.com +meng800.com +mengaite.com +mengarchitects.com +mengat.com +mengbige.com +mengchongzu.com +mengdian.com +mengdie.com +mengdoc.com +mengdoctor.com +mengdodo.com +mengensha.com +mengfm.com +menggang.com +menggaole.com +menghuimengtu.com +menghunli.com +mengjiagames.com +mengjianjiemeng.com +mengkang.net +mengkm.com +menglan.com +menglechong.com +menglegame.com +menglu.com +mengmayw.com +mengmei.org +mengniang.tv +mengniuarla.com +mengniuir.com +mengou.net +mengqingpo.com +mengqiuju.com +mengsang.com +mengso.com +mengte.online +mengtian.com +mengtuiapp.com +mengvlog.com +mengxi.com +mengxiang.com +mengxiangeka.com +mengxintianxia.com +mengxyz.com +mengya.com +mengyanggroup.com +mengyin.cc +mengyou.org +mengzhou.com +mengzhuangxiu.com +mengziyuan.com +mengzuji.com +menhu.io +menksoft.com +menpad.com +menpiao.com +menpiaotuangou.com +menshiny.com +mentamob.com +mentorsc.com +mentrends.com +menu-static.gog-statics.com +menubarx.app +menwee.com +menww.com +menwww.com +menxue.com +menyuannews.com +meoof-pet.com +meovse.com +meow.plus +meowcat.org +mepai.me +mepcec.com +mepoem.com +meppon.com +meqlm.org +merach.com +mercedes-benzarena.com +merchaincargo.com +mercitime.com +mereith.com +mergeek.com +merivox.net +merklechina.com +merkpd.com +merlinmedicine.com +mero-db.com +merries-china.com +merroint.com +merryhome.com +merucario.com +mescroll.com +meshiot.com +mesince.com +mesnac.com +mesonart.com +mesou.net +mesowe.com +mesresearch.com +messawith.com +messecloud.com +meta-stone.com +meta-verse.co +meta-xuantan.com +meta.law +metacd.com +metal-min.com +metal-tube.com +metal.com +metalchina.com +metalrevolution.com +metalsinfo.com +metalyoung.com +metaoptronics.com +metaplanet3023.com +metasecurities.com +metastonecorp.com +metastudioxr.com +metastudy.vip +metasyun.com +metatrader4.com +metatrader5.com +metatube.pro +metavatar.cc +metawalle.com +metax-tech.com +metayuanjing.com +metcn.com +meten.com +meteni.com +metenk12.com +meteric.com +metersbonwe.com +metin520.com +metispharma.com +metnews.net +metong.com +metools.info +metro-3d.com +metroer.com +metrofastpass.com +metropolohotels.com +metroshield.com +metrowatch.net +metstr.com +metword.co +meu95otw4967t.com +meuicat.com +meutu.com +mevionchina.com +mew.fun +mewchan.com +mewx.art +mexingroup.com +mexontec.net +mexxum.com +meyet.net +meyoufreight.com +meyum1688.com +mezamca.com +mezhiyu.com +mezw.com +mf-y.com +mf08s.com +mf1288.com +mf999.com +mfaeb.ltd +mfbrjc.com +mfbuluo.com +mfcad.com +mfcad.net +mfcpx.com +mfcteda.com +mfcyun.com +mfdl666.com +mfdns.com +mfdzqj.com +mfexcel.com +mfg-magnets.com +mfgchn.com +mfhcd.com +mfinetech.com +mfisp.com +mfjl.wiki +mfjxcn.com +mfk.com +mflady.com +mfniu.com +mfpad.com +mfpay.net +mfqqx.com +mfqyw.com +mfsj1908.com +mftianshanam.com +mftvideo.com +mfunz.com +mfwxpay.com +mfxlawyer.com +mfzl.net +mfzxcs.com +mg-cdn.com +mg-pen.com +mg21.com +mg3721.com +mgaqehzm.com +mgcan.com +mgcmehzt.com +mgd5.com +mgdq.net +mgdzz.com +mgenbio.com +mgenware.com +mgff.com +mgfty.com +mgfy88.com +mggtech.vip +mgh2-lab.com +mgjianshe.com +mgkj.vip +mgkjht.com +mgl9.com +mglhx.com +mglip.com +mgm255.com +mgmgrandsanya.com +mgmovie.net +mgmusic.vip +mgnav.com +mgobe-webattle.com +mgongkong.com +mgplay.com.tw +mgryekby.com +mgsdk.com +mgse.info +mgskfjfod25.com +mgskfjfod31.com +mgskfjfod40.com +mgslb.com +mgslb.net +mgslb.org +mgsp.fun +mgtv.com +mgtv2025.com +mgugaklive.nowcdn.co.kr +mgw999.com +mgwxw.com +mgxf.com +mgxzsy.com +mgys.cc +mgyxw.net +mgyyw.com +mgzf.com +mgzxzs.com +mh-rjgb.com +mh160.cc +mh456.com +mh51.com +mh9.cc +mhacn.com +mhacn.net +mhaoma.com +mhbras.com +mhcharging.com +mhealth100.com +mhfotos.com +mhhf.com +mhhf.net +mhi-ac.com +mhinele.com +mhito.net +mhkami.com +mhkcomment.com +mhnzww.com +mhome.com +mhotels.design +mhpdf.com +mhpin.com +mhrooz.xyz +mhskso.sbs +mht.la +mht.tw +mhtclub.com +mhtes.com +mhtyd.com +mhtzjt.com +mhv2.net +mhw315.com +mhwck.com +mhwh168.com +mhwmm.com +mhwy2.com +mhxk.com +mhxzhkl.com +mhystatic.com +mhyun.net +mhzd.cc +mhzd.net +mi-ae.com +mi-ae.net +mi-cache.com +mi-cdn.com +mi-customer.com +mi-dong.com +mi-dun.com +mi-fds.com +mi-fds.net +mi-idc.com +mi-img.com +mi-img1.com +mi-img2.com +mi-img3.com +mi-img4.com +mi-img5.com +mi-static.com +mi.com +mi0.cc +mia.com +miaibox.com +miak.work +mian520.com +mianbao.com +miancp.com +miandanbx.com +mianfa.org +mianfeiic.com +mianfeiquming.com +mianfeiwendang.com +mianfeiwucan.org +mianfeiziti.com +mianhuatang.cc +mianhuatang.la +mianjue.com +miankousucai.com +mianmoi.com +mianshiya.com +mianshui365.com +mianwai.com +mianyangauto.com +mianyanghuida.com +mianyaojsj.com +mianyazulin.com +mianzhouhotel.com +miao-lang.com +miao15777790078.com +miaobe.com +miaobige.com +miaobolive.com +miaoche.com +miaocode.com +miaodiyun.com +miaodongbar.com +miaodongshenghuo.com +miaogongzi.cc +miaogongzi.net +miaohuiyanyi.com +miaojibrand.com +miaokaikeji.com +miaokaiyun.com +miaokan.com +miaokan100.com +miaolaoshi.com +miaolianyunapp.com +miaolingbio.com +miaomaicar.com +miaomiaolock.com +miaomiaowork.com +miaomiaoxue.com +miaomiaoz.com +miaomiaozhe.com +miaomiaozhua.com +miaomu.com +miaomuzhan.com +miaoo.me +miaopai.com +miaoqutimes.com +miaosha.com +miaoshou.cc +miaoshou.com +miaoshou.net +miaoshoucdn.com +miaoshufang.com +miaoshuwu.com +miaoshuzhai.net +miaoso.com +miaostreet.com +miaov.com +miaovps.com +miaoweijianfei.com +miaowenhk.com +miaowlabs.com +miaowutech.com +miaoxiazai.com +miaoyanai.com +miaoyin.pw +miaoyun.link +miaozanba.com +miaozao.com +miaozhan.com +miaozhun.com +miaozhunjing.net +miaozuo.com +miawycxs.com +miaxis.com +miaxis.net +mibao.com +mibaoxian.com +mibei.com +mic-s.com +micai.com +micai315.com +micaihu.net +micaiying.com +micamika.com +micang.com +micblo.com +mice-gz.org +micecn.com +michaelapp.com +michoi.com +michong.com +michplay.com +miclle.com +mico.io +micode.net +micoe.com +micro-bee.com +micro-bridge.com +micro-game-client.com +micro-x.net +microaiav.com +microbeee.com +microbell.com +microbt.com +microcai.org +microcardio.com +microchampion.com +microdiag.com +microdreams.com +microesim.com +microfotos.com +microfountain.com +micronetpay.com +microrui.net +microsate.com +microsoftsa.com +microstarsoft.com +microstern.com +microsword.net +microtrading.com +microvcard.com +microvirt.com +microvoip.com +microwear.com +microwoo.com +microwu.com +microxiang.com +microyan.com +microzuji.com +mictormedical.com +micu.hk +micw.com +micyjz.com +mid-link.net +midaapi.com +midadata.com +midainc.com +midanyi.com +midasbuy.com +middleschoolcounselor.com +midea-buy.com +midea-group.com +midea-hotwater.com +midea.com +midea.com.tr +mideabiomedical.com +mideadc.com +mideaepay.com +mideaepayuat.com +mideav.com +mideazy.com +midecopharm.com +midi-cn.com +midian.com +midiclouds.com +midicn.com +midifan.com +midingdong.com +midiplus.com +midita.com +miditools.net +midiyinyue.com +midlele.com +midonglab.com +midongtech.com +midongtech.xyz +midu.com +miduiedu.com +midukanshu.com +midureader.com +midust.com +midway.run +mieco.net +miecod.com +mieevents.com +miemie.la +miercn.com +mieseng.com +mifacelive.com +mifan365.com +mifangba.com +mifanli.com +mifanlicdn.com +mifei.com +mifeng.plus +mifengchengshi.com +mifengv.com +mifengvv.com +mifengxiuchang.com +mifengzd.com +mifengzhibo.com +mifenlife.com +mifispark.com +mifjhgq.xyz +mifon.com +mifpay.com +mifwl.com +migames.com +migelab.com +mightsquare.com +miglioriorologi.com +migood.net +migu.store +migucloud.com +migufm.com +migufun.com +migugk.com +migugu.com +miguku.com +migumaotrip.com +migutv.com +miguvideo.com +miguyu.com +mihanw.com +mihayo.com +mihayou.com +mihopacking.com +mihoyo.com +mihoyocg.com +mihoyocloud.com +mihoyogift.com +mihoyomall.com +mihuachat.com +mihuangame.com +mihuashi.com +mihuatown.com +mihui365.com +mihulu.com +mihuwa.com +miicp.com +miidc.com +miidii.tech +miidim.com +miiee.com +miiiw.com +miiiw.net +miinaa.com +miinsurtech.com +miit-icdc.org +miit-kjcg.com +mij.cc +mijewelries.com +miji8.com +mijia.tech +mijian360.com +mijiannet.com +mijiayou.com +mijiayoupin.com +mijisou.com +mijwed.com +mika123.com +mike-x.com +mikeauth.com +mikechen.cc +mikecrm.com +mikemessiha.com +mikeoperfect.com +mikesent-awareness-02.com +mikesent-awareness-04.com +mikesent.net +mikeyouxi.com +mikge.com +mikika.com +miko007.com +mikoshu.me +miku.ink +miku01.cc +mikuac.com +mikublog.com +mikucdn.com +mikuclub.fun +mikudm.com +mikumikumi.xyz +milan.com +milan520.com +milanshishang.com +milanvip.com +milchips.com +mileage.vip +milejia.com +milemovie.com +mileshub.net +mileweb.com +milianshe.com +miliantech.com +miliao.com +milido.vip +milihua.com +milike.com +milimao.com +milimili.tv +miliol.com +miliol.org +milipictures.com +militadowatch.com +miliyo.com +milkjpg.com +milliant.com +milliway-ic.com +millnovel.com +milnews.com +milo-star.com +miloktv.com +miloli.info +milsay.com +milu.com +milubtyx.com +milusybt.com +milvtong.com +milvzn.com +milyf.com +mimangfei.com +mimayun.com +mimi123.vip +mimi518.com +mimidi.com +mimimeu.com +mimiteng.com +mimixiaoke.com +mimiyc.net +mimo51.com +mimomim.com +mimoprint.com +mimouse.net +mimvp.com +minapp.com +minapp.xin +mincdn.com +mind-home.net +mind-medi.work +mindai.com +mindcherish.com +mindcontroles.com +mindechem.com +mindlabpros.site +mindmanagerchina.com +mindmm.com +mindpin.com +mindray.com +mindshow.fun +mindstore.io +mindsun.com +mindway-sz.com +minebbs.com +minecraftxz.com +minecraftzw.com +minegoods.com +minei.com +mineplugin.org +mineraltown.net +minerfun.com +minerhome.com +minewtech.com +minfengmuye.com +minfengtianfu.com +minfufa.com +ming-med.com +ming-men.com +minganmed.com +mingbianji.com +mingbiao001.com +mingbiaohao.com +mingcalc.com +mingchao.com +mingchaoonline.com +mingchaoyouxi.com +mingchu.co +mingci.org +mingcihospital.com +mingcloud.net +mingczh.com +mingdanwang.com +mingdao.com +mingdao.net +mingdao8.com +mingdaocloud.com +mingdazhongxue.com +mingdejx.com +mingdongman.com +mingdutech.com +mingechina.com +mingfengtang.com +mingfucdn.com +mingfucloud.com +mingfudns.com +mingfuyun.com +minghaoshangwu.com +minghecloud.com +mingheng-group.com +mingheyaoye.com +mingheyiyao.com +minghezhi.com +minghuatang.com +minghuaxinda.com +minghuishijia.com +mingin.com +mingjiachina.com +mingjian.com +mingjian365.com +mingjian365.net +mingjignfang.com +mingjinglu.com +mingjiudu.com +mingjuyoupin.com +mingkj.com +minglian.com +minglunlaw.com +mingmen-tech.com +mingpian.biz +mingpian.net +mingqi.co +mingqian666.com +mingqu.xyz +mingr.com +mingren888.com +mingricctv.com +mingrsoft.com +mingshi100.com +mingshi100.net +mingshi51.com +mingshi58.com +mingshiedu.com +mingshisanling.com +mingsoft.net +mingstar.net +mingtaimed.com +mingtaokeji.com +mingtejia.com +mingtian.com +mingtou.com +mingxigu.com +mingxingku.com +mingxinglai.com +mingxuan.store +mingya.mobi +mingyang100.com +mingyangtek.com +mingyangyinhe.com +mingyannet.com +mingyantong.com +mingyaohui.com +mingyaoruci.com +mingyaweb.com +mingyi.com +mingyihui.net +mingyou360.com +mingyu-porcelain.com +mingyuanfund.com +mingyuanmuye.com +mingyuanyun.com +mingzhi-tech.com +mingzhucable.com +mingzhujs.com +mingzhuoedu.com +mingzhuxiaoshuo.com +mingzihui.com +minhang.cc +minhangshi.com +minhow.com +mini-audio.com +mini-banana.com +mini-ease.com +mini-program-acc.com +miniadx.com +miniaixue.com +miniapida.com +miniapp.fun +miniapp360.com +miniappss.com +minibai.com +minibg.com +miniblink.net +minidaxue.com +minidso.com +minieye.cc +minieye.tech +minigame.com +minigameam.com +minigui.com +minigui.org +minihaowan.com +miniluck.com +minimaituan.com +minimax.chat +minimaxi.com +mining120.com +mininglamp.com +minip-service.com +minipacs.com +miniprogramadmin.com +minirizhi.com +minisforum.com +minishops.co +miniso-au.com +miniso.com +minisoyo.com +ministudy.com +minitiao.com +miniui.com +minixiazai.com +miniyounger.com +minjichem.com +minkave.com +minking.cc +minleai.com +minli.com +minmetals.com +minor-tech.com +minovapharma.com +minpayment.com +minqiao.com +minra.com +minretail.com +minshangjie.com +minshengec.com +minshengjob.com +minshenglife.com +minshop.com +minstrans.com +mintaibank.com +mintake.com +mintaylor.com +mintimate.cc +mintix.store +mintmuse.com +mintrust.com +mints-id.com +minunix.com +minxing365.com +minxiwang.com +minxue.net +minyukji.com +minyunit.cool +minz.press +minzu56.net +mionerxrospeo.com +mionexmailerc2.com +mionexmailero1.com +miooku.com +miospay.com +miot-spec.org +miotech.com +mipa.fun +mipahui.com +mipangwang.com +mipay.com +mipay.net +mipcdn.com +mipengine.com +mipengine.org +mipkj.com +miplus.cloud +mippaper.com +mipplan.com +mipplan.org +mipuo.com +mipush.com +miqixuan.net +miquapp.com +mir4399.com +mir6.com +miracdn.com +miraclelaser.com +miracleplus.com +miraclevision.com +miraclevision.net +miracomotor.com +mirahomes.shop +miratama.com +miravia.es +miredian.com +mirgaga.net +miri.site +mirmzhy.com +mirreal.net +mirrorcast.tv +mirrorchyan.com +misaka.center +misakamoe.com +misall.com +miscd.com +mishang.com +mishangkeji.com +mishuhome.com +misiai.com +misintlschool.com +miso-lab.com +mispos.cc +misrm.com +misrm.net +missevan.com +missfresh.net +misshachina.com +misshcl.com +missionhillschina.com +missjia.net +misslele.com +misstar.com +missyuan.net +misuland.com +misunly.com +mitalk.com +mitang.com +mitangtuan.com +mitao.bar +mitaoping.com +mitaowu.com +mitay.net +miteno.com +mitertec.com +mitesi.com +mitotoo.com +mitpgxvm.com +mitsubishielectric-mesh.com +mitsuha.space +mitsuiplastics-shanghai.com +mittrchina.com +mituancm.com +mituyuedu.com +mitvos.com +mitvos.net +miued.com +miui.com +miuiver.com +miulab.com +miusi.co +miuss.icu +miutour.com +miutrip.com +miwaimao.com +miwap.com +miwifi.com +miwuad.com +miwuzhentan.com +mix-planet.com +mix.moe +mixbao.com +mixcapp.com +mixcm.com +mixdesk.net +mixdo.net +mixian88.com +mixiaojin.com +mixin.cc +mixinshe.com +mixiong.tv +mixkr.com +mixly.org +mixmind.com +mixmoe.com +mixpwr.com +mixrnb.com +mixueedu.com +mixvvideo.com +miyabaobei.com +miyaboke.com +miyachat.com +miyanlife.com +miyapay.com +miyateam.com +miyatech.com +miyilink.com +miyoushe.com +miyouu.com +miyuangz.com +miyun-ecomarathon.com +miyun.com +miyun360.com +miyuncms.com +mizhai.com +mizhe.com +mizhiji.com +mizhimedia.com +mizhionline.com +mizhizbf.vip +mizhuan.me +mizone.cc +mizuda.com +mizuki2.com +mj110.net +mj365.club +mj365.site +mj365.vip +mj567.com +mj85.com +mjasoft.com +mjatm.com +mjcec.com +mjceo.com +mjecu.com +mjgxsc.com +mjgysm.com +mjh5.com +mjia.cc +mjjcn.com +mjjq.com +mjlong.com +mjlsh.com +mjmjm.com +mjoys.com +mjqishi.com +mjt288.com +mjtcsb.com +mjtom.com +mjttt.com +mjxhgdl.com +mjxpay.com +mjyg.com +mjylbj.com +mjyun.com +mjyx.com +mjyxkf.com +mjzcnd.com +mjzhcl.com +mjzj.com +mjzq.net +mk-yiliao.com +mk169.com +mk2048.com +mk5.xyz +mkaq.org +mkb0898.com +mkdata.top +mkf.com +mki7rxcwmfe7c.com +mkjump.com +mkkcn.com +mklimg.com +mklist.com +mkmchina.com +mkn666.com +mkpum.com +mkpush.com +mkqh.com +mkqst.com +mkrobot.org +mkrviu.sbs +mkshell.com +mkstone.club +mksucai.com +mktcreator.com +mktdatatech.com +mktoys.com +mktzb.com +mktzr.com +mkvcn.com +mkwhat.com +mkzcdn.com +mkzhan.com +mkzhan.net +mkzhou.com +mkzoo.com +mlabc.com +mlairport.com +mlayt14.com +mlbaikew.com +mlc.cc +mlexpo.com +mlfjnp.com +mlfkc.net +mlgj.com +mlgxw.org +mlhimalayanxt.com +mlhld.com +mlibaba.com +mlibrarys.com +mliev.com +mlink.tv +mlinkapp.com +mlinks.cc +mlinks.co +mlito.com +mlj122.com +mlj125.com +mlj130.com +mlj162.com +mlj194.com +mlj36.com +mlj93.com +mljtevy.com +mljydoors.com +mlkmba.com +mllj.net +mlmcms.com +mlmtz.com +mlnk.me +mlnsoft.net +mlocso.com +mlogcn.com +mlpzes05.com +mlqdpdgf.sbs +mlrcn.com +mlrlzy.com +mlrzsj.com +mlsbmw.com +mlsh.net +mlsub.net +mlszp.com +mlt.pub +mltrans.net +mlunwen.com +mlwanwan.com +mlwdpx.com +mlwed.com +mlwplus.com +mlwu.net +mlxks.com +mlxx.com +mlycdn.com +mlychee.com +mlyfc.net +mlyfcyy.com +mlyns.com +mlyx.com +mlzs2008.com +mm-sh.com +mm.com +mm111.net +mm131.kim +mm1357.com +mm138.com +mm2hservices.com +mm3yy.com +mm8mm8.com +mmall.com +mmaqa.com +mmarket.com +mmarket6.com +mmatch.tech +mmbang.com +mmbang.info +mmbang.net +mmbao.com +mmbest.com +mmbjq.com +mmbread.com +mmc-data.com +mmcl.net +mmcloud.com +mmcos.com +mmdtt.com +mmegg.com +mmfad.com +mmgl.net +mmgo.com +mmgogo.com +mmgoodcar.com +mmhygame.com +mmi-shanghai.com +mmia.com +mmim8.com +mmj.vip +mmjbh.com +mmjynet.com +mmjzxh.com +mmlessin.com +mmllllasjd.com +mmmglobalgroup.com +mmmmmmm.com +mmmnote.com +mmmrz.com +mmmtech.com +mmods.site +mmogg.net +mmoist.com +mmonly.cc +mmoser.work +mmosite.com +mmqidian.com +mmrcw.com +mms591.com +mmsase.com +mmsccn.com +mmscoo.com +mmsfw.com +mmsk.com +mmt3000.com +mmtch.com +mmtx.net +mmuaa.com +mmww.com +mmxchina.com +mmxiaowu.com +mmxmmx.com +mmyj.com +mmyxshop.com +mmyz.net +mmzcn.com +mmzh.com +mmzj.com +mn-soft.com +mnancheng.com +mnbvbqw.com +mnbvdfg.com +mnbvtgv.com +mndqlib.net +mnengine.com +mnfqw.org +mnihyc.com +mnjj.group +mnpc.net +mnwww.com +mo-co.com +mo298.com +mo2g.com +mo7.cc +mo9.com +moa06181ju.com +moa06211ju.com +moa06240ju.com +moa06250ju.com +moage.com +mob55.com +mobai.sbs +mobaibox.com +moban.com +mobanhao.com +mobanjing.com +mobanku.com +mobanlane.com +mobanma.com +mobantiankong.com +mobantu.com +mobanwang.com +mobanyun.com +mobao.online +mobaoo.net +mobartsgame.com +mobawan.com +mobayx.com +mobcells.com +mobcent.com +mobcloud.mobi +mobdna.com +mobeehome.com +mobgroupbuy.com +mobhui.com +mobiapp.cloud +mobibao.com +mobibrw.com +mobike.com +mobile.ccdntech.com +mobileanjian.com +mobilebone.org +mobilegamebase.com +mobilegamecdn.com +mobilelegends.com +mobilemgr-global.com +mobilemgr-global.net +mobileppp.com +mobiletrain.org +mobileztgame.com +mobispeaker.com +mobjz.com +mobkeeper.com +mobking.biz +moblazer.com +mobmore.com +mobo168.com +moboage.com +moboplayer.com +mobotap.com +mobring.co +mobrtb.com +mobsdks.com +mobsurl.com +mobtou.com +mobvoi.com +mobwan.com +mocache.com +mocafilm.com +mocartoon.com +mochafengbao.com +mochai.store +mochateam.com +mochi.website +mochiwang.com +mochouu.com +moci6.com +mockingbot.com +mockuai.com +mocn.cc +moco-mall.com +mocreak.com +mocusez.site +mocuz.com +modao.cc +modao.com +modao.io +modaogz.com +modashi.net +modb.cc +modb.pro +modelarts-infer.com +modelarts-maas.com +modelevel.com +modelltd.com +modelones.com +modelscope.net +modelwhale.com +modeng178.com +modengtianshi.com +moderatep.com +modernavenue.com +moderner.com +moderno2.com +modernsky.com +modernweekly.com +modevol.com +modian.com +modianverse.com +modificatiy.com +modooplay.com +modouwangluo.com +modstart.com +modudaojia.com +modujx11.com +modujx13.com +modujx14.com +modujx15.com +modujx16.com +moduyun.com +modxz.com +moe-box.com +moe.im +moe.so +moe.tips +moe.xin +moe123.com +moe123.org +moe321.com +moeclub.org +moedot.net +moeelf.com +moefactory.com +moefantasy.com +moefou.org +moegirl.tw +moehot.com +moehu.org +moehui.com +moeid.com +moeigfx.com +moejp.com +moeking.me +moeli123.com +moemiao.net +moerlong.com +moetu.club +moetu.org +moetuji.com +moeub.com +moeworld.tech +moex.ink +moeyuuko.com +moeyy.xyz +moezx.cc +mofacdnode.com +mofadns.online +mofahou.com +mofang.com +mofang.jp +mofangchuxing.com +mofangge.com +mofanghr.com +mofangshe.com +mofangwang.com +mofangyu.com +mofanodes.com +mofashi.ltd +mofavideo.com +mofazhu.com +moffettai.com +mofile.com +mofishgames.com +mofoun.com +mofunenglish.com +mogao.com +mogecloud.com +mogecloud.net +mogengyun.com +mogengyun.net +mogezhouyi.com +mogher.com +mogoedit.com +mogohd.com +mogojob.com +mogoo.com +mogoroom.com +mogu.com +mogu.io +mogua.co +mogucdn.com +moguding.net +moguf.com +mogujia.com +mogujie.com +mogujie.org +mogujielive.com +mogumiao.com +mogutong.com +moguv.com +moguvet.com +moguyun.com +moh.cc +moh7.com +mohangkeji.net +mohjdvh.com +mohou.com +mohu.org +mohuishou.com +moihu.com +moimg.net +moissture.com +moith.com +moji.com +moji001.com +moji002.com +mojicb.com +mojicdn.com +mojichina.com +mojichina.net +mojidict.com +mojidoc.com +mojie.app +mojie.co +mojie.kim +mojieai.com +mojitest.com +mojitok-c.com +mojocube.com +mojusteel.com +mojy.xyz +mok8uptsmk19.com +mokahr.com +mokamrp.com +mokatyper.com +mokayuedu.com +moke.com +mokeyjay.com +moko.cc +mokra.house +mokxing.com +molbase.com +molbase.net +molcoo.com +moldinginductor.com +moldnano.com +moleecel.com +molefitting.com +molerose.com +molesdn.com +molibaike.com +molihe.cc +molihua.net +molihuadami.com +molilian.com +molilier.com +molimoli.tech +moliplayer.com +molipy.com +moliqiji.com +molishe.com +molixiangce.com +mollervilla.com +molt.win +molwater.com +molygoo.com +mom001.com +moma-hz.com +mombuybuy.com +moment.fun +momentad.com +momentcake.com +momhui.com +momishi.com +mommygf.com +momo35.com +momoapk.com +momobako.com +momocdn.com +momoda8.com +momokuba.com +momooyo.com +momotn.com +momoyu.cc +momoyu.com +momoyuyouxi.com +momzs.com +monadyneed.com +monaite.com +monarch-sw.com +mondaymorningmtg.com +moneak.com +monengu.com +monengugame.com +moneydata.hk +monfetch.com +mongac.com +monhun.fun +monidai.com +monidata.com +moniex-verifyb.com +monika.love +monitoring.qpdp1.net +monkeylsp.com +monknow.com +mono.work +monolink.net +monph.com +monsterlin.com +montage-tech.com +monternet.com +montnets.com +montres8.com +monurhineas.com +monv.com +monxin.com +moocollege.com +mooctest.net +moodmoon.com +moodoon.com +mooiee.com +moojing.com +moojnn.com +moolsun.com +moomoo.com +moomooequity.com +moomootrustee.com +moomv.com +moon-insight.com +moonbasa.com +moonbio.com +moonbitlang.com +moonbt.com +mooncell.wiki +moonfly.net +moongood.com +mooninbox.com +moonjer.com +moonlian.com +moonsec.com +moonsees.com +moonshot.ai +moonstatistics.com +moonton.com +moontonapp.com +moontontech.net +moonvy.com +moonvy.cool +mooooc.com +mooool.com +mooore.net +moooyu.com +moore.ren +moore8.com +moorecat.com +mooreelite.com +mooreiot.com +moorext.com +moowo.com +mooyuu.com +mooyy.com +mop.com +mopaas.com +mopair-erm.net +mopcn.com +mopei8.com +moper.me +moper.net +mopicer.com +mopin.cc +mopo.com +mopoint.com +mopsky.com +mopxz.com +moqie.com +moqiehome.com +moqifei.com +moqikaka.com +moqilin.net +moqing.com +moqingtk.com +moqipobing.com +moqiwanba.com +moqu8.com +moquseo.com +moraex.com +morange.shop +mordernstone.com +morechinese.cc +moreck.com +moredian.com +morefood.com +morefreegame.com +morefun-philippines.com +morefunstudio.com +morefuntengyun.com +moregy.com +moreless.io +morelink.net +moremeat.com +morequick.net +moresing.com +morestep.com +morethan.tv +moretickets.com +morevfx.com +morewis.com +morewiscloud.com +morganstanleyhuaxin.com +morgendesign.com +morihei.net +morketing.com +morketinglearn.com +morketingsummit.com +morlab.com +morning.work +morningcore.com +morninghan.com +morninginn.com +morningwhistle.com +morong-elec.com +morrisco.cc +morstar.net +moschat.com +moseacg.com +moseeker.com +mosesenglish.com +mosgcj.com +moshanghotel.com +moshanghua.net +mosheng520.com +moshengliang.com +moshike.com +moshou.com +moshua.net +moshuai.cc +mosoga.net +mossimo.net +mossle.com +mostch.com +mostmob.com +mostsd.com +mosuzi.com +motanku.com +motel168.com +motherchildren.com +motic-electric.com +motie.com +motieimg.com +motiezw.com +motilive.com +motimaster.com +motimo.com +motisky.com +moto-one.com.hk +moto17.com +moto8.com +moto8.net +motomatu.com +motooy.com +motor-comm.com +motormade.com +motowoo.com +motuo2.com +mou.ge +mou.ren +mouldbbs.com +mouldnews.com +moulem.com +moumi.com +mounriver.com +mountor.net +mounui.com +mouraeodor.com +mouralanco.com +mouratoriousi.com +mousesquadca.org +moushei.com +mousycoder.com +mout.me +moutaichina.com +mova-tech.com +movcam.com +movebroad.com +movelaser.com +movesky.net +movie.mcas.jp +movie365.tv +moviemore.com +moviereviewtoday.com +movit-tech.com +mowan123.com +moweather.com +mowgz.com +mowowo.com +moxfive.xyz +moxiai.com +moxian.com +moxiaoying.com +moxidongman.com +moxin.me +moxing.net +moxingbk.com +moxingfans.com +moxingyun.com +moxiu.com +moxiu.net +moxuangenet.com +moxz.net +moyangmoyang.com +moyann.com +moyol.com +moyoyo.com +moypk.com +moyubuluo.com +moyugroup.com +moyunteng.com +moz8.com +mozartsemi.com +mozhan.com +mozheanquan.com +mozhedun.com +mozhenhau.com +mozichina.com +mozigu.net +mozillaonline.com +mozillazg.com +moziqing.com +mozouyan.com +mp.cc +mp17.com +mp333player.com +mp4ba.com +mp4cn.com +mpaascloud.com +mpacc.cc +mpacc.com +mpacc.net +mpackchina.com +mpaidata.com +mpass.club +mpbza.com +mpcloudapp.com +mpdn.fun +mpdsj.com +mpg.de +mph11.com +mphdx.com +mpiano.com +mplus.tech +mpmc-china.com +mpnbenefits.download.prss.microsoft.com +mpnbenefitsrtl.download.prss.microsoft.com +mpnbenefitsrtluat.download.prss.microsoft.com +mpoa.vip +mpopkart.com +mpqddg.club +mps.live +mpserverless.com +mpsoft.net +mpxiaomi.net +mpxx.net +mqant.com +mqc168.com +mqcoffee.com +mqhospital.com +mqikan.com +mqmgroup.com +mqqurl.com +mqqy.com +mqrouter.com +mqsyr.com +mqttdkx.vip +mqttx.app +mquanquan.com +mqxpyy.com +mqxww.com +mqyu.com +mqzoneapp.com +mr-ping.com +mr77.com +mr91.com +mrbanana.com +mrbird.cc +mrbook114.com +mrcrm.com +mrcywang.com +mrdede.com +mrdoc.pro +mrdooku.com +mrduan.com +mrenbaike.com +mrentea.com +mrhallacg.com +mrhe.net +mrhs.cc +mrjeke.com +mrjiang.com +mrjjxw.com +mrlian.club +mrlika.com +mrmfsc.ltd +mro365.com +mro9.com +mroall.com +mrobao.com +mrpyq.com +mrqf.com +mrqoxfvs.com +mrqxs.com +mrrvendor.com +mrsdgg.com +mrsingsing.com +mrsjzt.com +mrsta.com +mrtoss03.com +mrts.com +mru-taste.com +mrutaste.com +mrvcdn.com +mrwish.net +mrxiao.net +mrxwlb.com +mryunwei.com +mryys.com +mrzhenggang.com +ms08067.com +ms211.com +ms315.com +ms6666111.com +ms7caryw5i48t.com +msanjia.com +msbank.com +mscbsc.com +mscdntrip.com +mscland.org +mscodecloud.com +msd-facing.com +msddp.com +msdkpass.com +msdn.download.prss.microsoft.com +msdn.hk +msdnwogaosuni.com +msdnxitong.com +msdpmarathon.com +msdprc.com +msdprod-ad.download.prss.microsoft.com +msfpay.com +msftonlinelab.com +msg.work +msgamego.com +msgcarry.com +msgtjj.com +msh2020.com +mshandong.com +mshao.com +mshare.cc +mshareservices.com +mshchina.com +mshg2019.com +mshishang.com +mshot.com +mshouyou.com +mshw.net +mshxw.com +msits.com +msjingmi.com +msjpay.com +msjy123.com +mskoo.com +mslmc.net +msltbio.com +mslzk.com +msm.moe +msmartlife.com +msmbjp.com +msndvr.com +msny.cc +msolok.com +mspace.cc +mspacecd.com +mspharm.com +msproduct.download.prss.microsoft.com +msproductuat.download.prss.microsoft.com +msstatic.com +mst-jc.com +mstatik.com +mstchina.com +mstxx.com +msunland.com +msweekly.com +msxf.com +msxf.net +msxt.com +msxxg.com +msy5.com +msyc.cc +msyidai.com +msyos.com +msysk.com +mszdld.com +mszdld.net +mszlyoozo.com +mszmapp.com +mszq.com +mszsx.com +mszxyh.com +mt-bbs.com +mt-viki.com +mt-wire.com +mt180.com +mt22q4s3w5.com +mt3.com +mt77.com +mt888vip.com +mtab.cc +mtadvert.com +mtadx.com +mtaokj.com +mtavip.com +mtblj.com +mtchome.com +mtcn.net +mtcnsoft.com +mtcsys.com +mtcx99.com +mtcxsw.com +mtcxx.com +mtcyz.com +mtdpai.com +mtdpgame.com +mtdz.com +mte-shenzhen.com +mtedu.com +mtex.work +mtfpos.com +mtgchina.com +mtgmcim.com +mthlyp.com +mthreads.com +mti100.com +mtiancity.com +mtianshitong.com +mtide.net +mtime.com +mtimg.net +mting.info +mtitest.com +mtizt.com +mtjiangsu.com +mtk.com.tw +mtk114.com +mtkdy.com +mtketang.com +mtkgvip.com +mtkpacker.com +mtksj.com +mtlyp.work +mtm.mo +mtmos.com +mtmss.com +mtmssdn.com +mtmssdn0.com +mtmt.tech +mtmyg.com +mtmyw.com +mtnets.com +mtnets.net +mtoou.info +mtrmart.com +mtschina.com +mtsjgf.com +mtspark.com +mttlab.com +mttsq.com +mtty.com +mtv123.com +mtvip.cc +mtw.so +mtwine.com +mtwl.net +mtxshop.com +mtxyx.com +mtxzs.com +mtyun.com +mtzcjy.com +mtzqb.com +mtzscp.com +mtzuichen.com +mu69.com +muaedge.com +mubanjianli.com +mubanwan.com +mubixueyuan.com +mubon.net +mubu.com +mubucm.com +mucanzhe.com +mucf.cc +mucfc.com +much001.com +muchangqing.com +muchcloud.com +muchong.com +mudanauto.com +mudgj.com +mudiaotx.com +mudongguang.com +mudotarot.com +mudu.com +mudu.tv +muduhs.com +mufengyue.com +muftc.com +muge.info +mugeda.com +muguang.me +muguayuan.com +muhai.net +muhan.co +muhan.ltd +muhou.net +muhoujiemi.com +muhuo.chat +muidar.com +muimg.com +muin.cc +muinsoft.com +mujiangquan.com +mujihotel-beijing.com +mujin.net +mujj.us +mujoy.sg +mukenano.com +mukewang.com +mukongyun.com +mukool.com +mulangbrand.com +mulanlake.com +mulazim.com +mulightapp.com +mulinsen.com +mulinyun.com +multi-parking.com +multiconceptslink.com +multilingual-volc.com +multimodalmatch.com +multiplym.com +mulunspring.com +mumayi.com +mumbuy365.com +mumingfang.com +mumunv.com +mumuplayer.com +mumuxili.com +munantonio.com +muncard.com +mundane.ink +muniao.com +munling.com +munue.com +muomou.com +mupao.com +mupceet.com +muqianyun.com +muquan.com +muquan.net +murata-china.com +murdermysterypa.com +murl.tv +murongtech.com +murphysec.com +murphyyi.com +muryi.net +muse.ltd +muselab-tech.com +musenxi.com +muser168.com +museradio.net +musestudio.net +musetransfer.com +mushafa.net +musialmarketing.com +music-search.org +music4x.com +musicchina-expo.com +musiccia.com +musicd.cc +musicdu.com +musicedu8.com +musiceol.com +musicgw.com +musicheng.com +musiciansfriendsaleusa.shop +musikid.com +musiness.vip +muslimwww.com +muspost.icu +mussgirl.store +mustangbattery.com +mustbull.com +mustelanivalis.com +mustshipdealyy.shop +mustups.net +musyder.com +mutean.com +mutian.net +mutianyugreatwall.com +mutieffect.com +mutouxb.com +mutouyu.com +mutualhunter.com +muwai.com +muwaifanzhiliao.com +muwenxi.com +mux5.com +muxin.fun +muxiulin.com +muyangkuaibao.com +muyao.asia +muyee.com +muyer.com +muyeseed.com +muyewx.com +muyidc.com +muyingjie.com +muyingzhijia.com +muyuanfoods.com +muyuanpharm.com +muyuanwuliu.com +muyuekj0.com +muyuge.net +muyun.work +muyunsoft.com +muzhi.us +muzhibot.com +muzhicao.com +muzhifm.com +muzhigame.com +muzhiwan.com +muzhun.com +muziang.com +muzigame.com +muzijie.com +muzisoft.com +muziyueqiu.com +muzuhui.com +mvashanghai.org +mvhere.com +mvmaster.com +mvoicer.com +mvopri5ac153.com +mvorgexv.com +mvote.net +mvpdj.com +mvpmeta.com +mvpmob.com +mvprpg.com +mvpsky.com +mvs-intel.com +mvtianshanlr.com +mvwchina.com +mvyxws.com +mw.com +mw1950.com +mwadx.com +mwave.tech +mwcdns.com +mwclg.com +mwcloudcdn.com +mwcloudcdn.info +mwcname.com +mwdfawg.com +mweda.com +mwemp.com +mwjournalchina.com +mwkj.net +mwm.moe +mwquicio.com +mwrf.net +mwrfabc.com +mwstore.com +mwtee.com +mwtg.vip +mww.so +mwyzhcdn.com +mwzhtc.com +mx-china.net +mx-fm.com +mx-industry.com +mx-xz.com +mx007.com +mx175.com +mx3g.com +mx520.com +mxarts.com +mxbc.com +mxbc.net +mxbiao.com +mxchip.com +mxddp.com +mxde.com +mxdia.com +mxdjzj.com +mxdmf.com +mxdpark-gs.com +mxdraw.com +mxdraw3d.com +mxdx.net +mxeosbvt.com +mxew.com +mxflutter.com +mxfy.com +mxgogo.com +mxguan.com +mxhaitao.com +mxhichina.com +mxifund.com +mxitres.com +mxjd.com +mxjtedu.com +mxjyxx.com +mxk.cc +mxkjai.com +mxklchina.com +mxmem.com +mxnavi.com +mxnxs.com +mxnzp.com +mxomo.com +mxpharm.com +mxqe.com +mxria.com +mxsa2178.club +mxsyzen.com +mxtcn.com +mxtronics.com +mxun.com +mxw3.com +mxweiqi.com +mxwz.com +mxxjh.com +mxyinghang.com +mxyn.com +mxzgame.com +mxzx123.net +mxzzzs.com +my-cpaas.com +my-hlb.work +my-imcloud.com +my-le.com +my-ndns.com +my-qcloud.com +my-summit.com +my-tcloud.com +my.st.com +my0511.com +my0511.net +my0513.com +my0534.com +my0538.com +my0551.com +my0832.com +my089.com +my120.org +my147.com +my1616.net +my22.art +my22.fun +my22.info +my2852.com +my2space.com +my2w.com +my399.com +my3w.com +my4399.com +my510.com +my51y.com +my5v.com +my68.com +my7v.com +my88316666.com +my9166.com +my91app.com +my91game.net +my9527.com +my97.net +mya92f.icu +myagric.com +myaijarvis.com +myaiwecom.com +myalicdn.com +myalirtc.com +myallvalue.com +myanjian.com +myanmarembassy.com +myanmarembassybeijing.com +myanonamouse.net +myapp.com +myapp.ltd +myappdl1.com +myappdl1.net +myappdl2.com +myappdl2.net +myaqsh.com +myarena7.com +myarowanas.com +myauth.us +mybabya.com +mybarrefitness.com +mybdqn.com +mybj.com +mybjx.net +mybluefox.com +mybosc.com +myboyan.com +mybu.net +mybwallet.com +mybxg.com +mycaidan.com +mycaigou.com +mycaijing.com +mycar168.com +mycar58.com +mycaraok.com +mycarbar.com +mycardgame.net +mychery.com +mychery.net +mychinaunicom.com +mychuguan.com +mychunyan.net +myckjr.com +mycloudstudy.com +myclub2.com +mycnc.org +mycodes.net +mycollect.net +mycolorcity.com +mycolorway.com +mycoov.com +mycos.cc +mycos.com +mycos.net +mycos.org +mycospxk.com +mycosresearch.net +mycoss.com +mycoss.net +mycoss.org +mycplife.com +mycreate.net +mycyjg.com +mydadui.com +mydao.net +mydatetime.info +mydcis.net +mydcyj.com +mydeal.asia +mydf.net +mydical.com +mydidadi.com +mydigi.net +mydigit.net +mydigitex.com +mydisk.work +mydnns.com +mydns114.net +mydns8.com +mydnser.com +mydnspod.net +mydnsw.com +mydoc.io +mydoc123.com +mydor.com +mydown.com +mydrivers.com +mydyt.com +myecer.com +myechannel.com +myechinese.com +myeclipsecn.com +myekp.net +myelasticsearch.com +myeriri.com +myex.cc +myezdns.com +myfans.cc +myfdmg.com +myfhospital.com +myfrfr.com +myfun7.com +myfund.com +myfushun.com +mygaks.com +mygame66.com +mygame82.com +mygame88.com +mygisdel.com +mygjp.com +mygobatv.com +mygolbs.com +myguancha.com +mygymchina.com +mygzb.com +myhayo.com +myhc.net +myherocn.com +myhexin.com +myhithink.com +myhjw.vip +myhkw.com +myhl-china315.com +myhm.org +myhomeok.com +myhongzuan.com +myhopu.com +myhostadmin.net +myhscodes.com +myhuaweicloud-custom.com +myhuaweicloud-date.com +myhuaweicloud-koodrive.com +myhuaweicloud-obs.com +myhuaweicloud.com +myhuilv.com +myhuizhan.com +myhwcdn.com +myhwcloudlive.com +myhwclouds.com +myhwclouds.net +myhxy.com +myidc.club +myider.com +myie.me +myie9.com +myilibrary.com +myimis.com +myip.la +myiplay.com +myir-tech.com +myirtech.com +myitit.com +myityun.com +myjh.net +myjianzhu.com +myjiedian.com +myjob.com +myjob500.com +myjujing.com +myk3.com +mykans.com +mykarry.com +mykd.cc +mykeeta.com +mykeeta.net +mykqyy.com +mykscdn.com +mykuaidi.com +mykuaiji.com +mylbabao.com +mylguoji.com +mylhh.com +mylibs.org +mylightsite.com +mylike.cc +mylike.com +mylike120.com +mylikesz.com +mylikeyk.com +mylinkapp.hk +mylitboy.com +myliwu.net +mylotushealth.com +mylovehome.com +mylsfw.com +myluohan.com +mym001.com +mym195.com +mymaitian.com +mymanhua.com +mymaudio.com +mymember.ltd +mymetal.net +mymhotel.com +myminapp.com +mymlsoft.com +mymofun.com +mymoive.com +mymova.com +mymuwu.net +mynatapp.cc +mynb8.com +mynee.com +myo.ink +myoas.com +myoas.net +myodatech.com +myoed.com +myoldtime.com +myopenwrt.org +myoppo.com +myorbita.net +myottad.com +myouhua.com +myouth.net +myp17.com +myp2pch.net +mypaas.com +myparallelstory.com +mypcrun.com +mypethome.com +mypharma.com +mypian.com +mypiao.com +mypiaojia.com +mypitaya.com +mypity.com +mypiwik.com +mypm.net +myprad.com +mypscloud.com +mypsy365.com +mypx.org +myqbosuppportt.com +myqcloud.com +myqcloud.net +myqee.com +myqqdd.com +myqqjd.com +myr9.com +myra2.com +myrb.net +myreadcloud.com +myreadme.com +myrice.com +myrightone.com +myrqjt.com +myrtx.com +myrunners.com +mysbaojie.com +mysecretrainbow.com +mysecrettop.com +mysemlife.com +myseot.com +myshipjob.com +myshopex.com +myshoptago.com +myshow360.net +myshow800.com +myshown.com +mysinamail.com +mysipo.com +mysiteres.com +mysm888.com +mysmth.net +mysongktv.com +mysore-yoga.com +myspain.org +mysql360.com +mysqlab.net +mysqlpub.com +myssl.com +mystao.com +mystarch.com +mysteel.com +mysteel.net +mysteelcdn.com +mysteelcms.com +mysticalcard.com +mysubmail.com +mysupa.com +mysuperdns.com +mysvw.com +mysybt.com +myt126.com +mytaizhou.net +mytaofun.com +mytencentes.com +mythbird.com +mythcall.com +mythcare.com +mythidea.com +mythroad.net +mythsman.com +mythware.com +mythware.net +mytianchang.com +mytijian.com +mytju.com +mytokenapi.com +mytokenpocket.vip +mytoptown.com +mytqwpe.com +mytrix.me +mytt.com +mytv365.com +mytvgame.com +mytxly.com +myuall.com +myubbs.com +myuclass.com +myun.tv +myunke.com +myunlu.com +myusmile.online +myvipsalon.com +myvs.download.prss.microsoft.com +myvsoncloud.com +myvsuat.download.prss.microsoft.com +mywakao.com +mywaymeta.com +myweb888.com +myweimai.com +mywhh.com +mywinch.com +mywirebox.com +mywll.com +myworld6.com +myxxts.club +myxxts.com +myxycjh.com +myxypt.com +myyerrol.xyz +myyishu.com +myyjs.com +myyoudao.com +myypark.com +myyx618.com +myyx915.com +myyzd.com +myzaker.com +myzfw.com +myzhenai.com +myzhidao.com +myzhiniu.com +myzte.com +myztxyy.com +myzxsx.com +myzxyy.com +myzyy.com +myzyzy.com +mz186.com +mz52.com +mz6.net +mz99.com +mzbei.com +mzbkw.com +mzboss.com +mzdscm.com +mzeyes.com +mzfanyi.vip +mzfile.com +mzfpay.com +mzfsm.com +mzfxw.com +mzgroup.vip +mzgtuan.com +mzh.ren +mzhb.com +mzhen.com +mzhfm.com +mzhu8.com +mzhujia.com +mzjiacheng.com +mzjinyan.com +mzklg.com +mzksgmex.com +mzli.club +mzlittc.com +mzlwxw.com +mzlx88.com +mzlxcl.com +mzmjyy.com +mznznj.com +mzone.site +mzqbt.com +mzrcw.com +mzread.com +mzres.com +mzrmyy.com +mzsdsyy.com +mzsemi.com +mzsky.cc +mzsmn.com +mzsrmyy.com +mzssysmyxgs.com +mzstatic.com +mzsvn.com +mztgame.com +mztspa.com +mzty.com +mztzzx.com +mzuimg.net +mzwu.com +mzxstar.com +mzy0.com +mzyege.com +mzyfz.com +mzyispmc.com +mzyjfcn.com +mzyoudao.com +mzyun.ren +mzyunyin.com +mzyz.com +mzzhgcc.com +mzzjw.com +mzzyk.com +mzzzn.work +n-bros.net +n.biz +n0808.com +n0vadesktop.com +n12345.com +n13.club +n18.rcs.revma.com +n1b.com +n2017.com +n21.cc +n21ce.com +n283nser4cjz.com +n3sd.com +n459.com +n5w.com +n62f.vip +n63.com +n78785.com +n7maufn.sbs +n802.com +n8soft.com +n9z.net +na.ci +naaln.com +nabluemedia.com +naboyi.com +nac88.com +nachuan.com +nacuiwei.com +nadianshi.com +nadioutdoor.com +nadu8.com +naec-cn.com +naeeo.com +naeraxitang.com +nagagame.net +nagain.com +nagar-setu.com +nagcloudcs.com +nagekuai.com +nagezan.net +nahuayuan.com +nahuiyi.com +nahuo.com +nahuo8.com +nahuo9.com +naibabiji.com +naibago.com +naicha99.com +naichabiao.com +naideceas.com +naids.com +naifei.pro +naifeistation.com +naifenzhiku.com +naijian.net +nail-auto.com +nails7.com +naimal.com +naimei.com +naipan.com +naiping.net +naisuanbeng.com +naitang.com +naitta.com +naiveadmin.com +naiveblue.com +naiwch.com +naixi.com +naixi.org +naixuecha.com +naiyouxuexi.com +najingtech.com +najyj.net +najyw.net +nakedsail.com +nakeli-biotech.com +nakevip.com +naknor.com +nakong.com +nalanchuanmei.com +nalanxi.com +nalati.com +nalichi.com +name2012.com +name321.net +nameidi.com +namejin.com +namepre.com +nameserver.fit +namesilodns.com +nami.com +namibox.com +namichong.com +namihair.com +namipan.com +namiso.com +namisoft.com +namitiyu.com +namkwonglog.com +namoc.org +nan-cable.com +nan1688.com +nana.center +nanbeige.com +nanbeijt.com +nanbeiyou.com +nanbeiyu.shop +nanbushenghuo.com +nancalelectric.com +nancc.com +nancharencai.com +nanchigroup.com +nanchu.com +nanchunhz.com +nandaauto.com +nandasoft-its.com +nandasoft.com +nandiu.com +nandu.com +nandufoundation.org +nanerjia.com +nanfang-pump.com +nanfangfood.com +nanfen.com +nanfu.com +nanguache.com +nanguakexue.biz +nanguakexue.com +nangualin.com +nanguaxia.vip +nanguowl.com +nangxia.com +nanhaibank.com +nanhaicorp.com +nanhaisw.com +nanhaitoday.com +nanhexinxi.com +nanhua.net +nanhuabx.com +nanhuafunds.com +nanhuangic.com +nanhuazaobao.net +nanhufund.com +nanhujianshe.com +nanhunnvjia.com +nanhuwang.com +nanjbjjt.com +nanjet.com +nanjianggroup.com +nanjiaogroup.com +nanjing-pharma.com +nanjing-reagent.com +nanjing.com +nanjingboiler.com +nanjingbtkt.com +nanjingbyby.com +nanjingchenxi.com +nanjingelectric.com +nanjinggaopeng.com +nanjinghuihe.com +nanjinghuojia.net +nanjinglf.org +nanjingludeng.com +nanjingtianqi114.com +nanjingttym.com +nanjingxinxu.com +nanjingyinuo.com +nanjixiong.com +nankaimba.org +nanlangshengwu.com +nanlew.com +nanlingwater.com +nanlingzr.com +nanlong.com +nanmodesign.com +nanning-marathon.com +nanninginfo.com +nanningmhw.com +nanningmuseum.com +nanningnongjiao.com +nanningrcw.com +nanningtech.com +nanningxiaoou.com +nanningyouhua.com +nanningyuexing.com +nannjlnk.com +nano-zero.com +nanobody-biolab.com +nanochrom.com +nanoeast.net +nanoer.net +nanoinglobal.com +nanomicro.com +nanomotions.com +nanomxenes.com +nanosic.com +nanpowan.com +nanpu.vip +nanpua.com +nanputuo.com +nanqi.org +nanqiangbusiness.com +nanrentu.cc +nanrenwa.com +nanrenwo.net +nanrenzhi.com +nanshanfuzi.net +nanshanlvyou.com +nanshanski.com +nanshe-tech.com +nanshiw.com +nanss.com +nantaihu.com +nantong-hst.com +nantongfeixu.com +nantonghua.net +nantoujituan.com +nanvi.com +nanxi.me +nanxiang.info +nanxingmac.com +nanxinwang.com +nanxueqx.com +nanxunfb.com +nanyangcable.com +nanyangdianlan.com +nanyangpt.com +nanyangzb.com +nanyinwealth.com +nanyuecloud.com +nanyuenews.com +nanyuetong.com +nanzhougroup.com +naobaocun.com +naobiao.com +naoda.net +naoffer.com +naokor.com +naokr.com +naominet.live +naono.cc +naosiling.com +naozhong.net +naozoejnnwzjaz.work +napengzn.com +napiantian.com +naqing-tech.com +naquan.com +naquan.org +naradafoundation.org +naradahotels.com +naradapower.com +narcissoshotel.com +naris-china.com +narkii.com +narochina.com +naruto.red +narwal.com +narwaltech.com +nas-ya.com +nascrew.com +nase.tech +nasenwangluo.net +nasfreight.com +nasge.com +nasgetinfo.com +nashwork.com +nasinet.com +naslab.club +nastcorp.com +nasyeo.com +nasyun.com +nat123.com +natachem.com +natapp.cc +natapp1.cc +natapp4.cc +natappfree.cc +natashayana.shop +natbbs.com +natchecker.com +natergy.com +natfrp.com +natgmj.com +nationalchip.com +nationalee.com +nationsky.com +nationstech.com +nativosink.com +natnps.com +nattest-china.com +naturali.io +naturaltfc.com +naturalvision.org +nature-museum.net +nature.com +natureholisticwellness.com +naturesvariety-china.com +natywish.com +nauac.com +naupd.com +nav-cn.com +navchina.com +navgnss.com +navigastar.com +navimentum.com +navinfo.com +naxcx.com +naxiaozhu.com +naxide.com +nayatec.com +nayei.com +nayuansu.com +nazarstudios.com +nazhidj.com +nazhilong.com +nazo.fun +nb-bailing.com +nb-jf.com +nb-jiale.com +nb-medicalsystem.com +nb160.com +nb591.com +nba-zhibowebsite.com +nba.com +nba98k.com +nbabm.com +nbahero.com +nbahi.com +nbaidai.com +nbakan8.com +nball.cc +nbamyl.com +nbaoke.com +nbappliance.com +nbaqmq.com +nbaqsj.com +nbaqx.com +nbaxiaoshuo.com +nbbiao.com +nbbjack.com +nbbuxiutie.com +nbcbd.com +nbcentre.com +nbchao.com +nbchen.com +nbcqjy.org +nbcsgo.com +nbctg.com +nbcyts.com +nbdavid.com +nbdeli.com +nbdeli.net +nbdeyy.com +nbdisco.com +nbdkj.com +nbdpress.com +nbdyf.com +nbdyyy.com +nbegame.com +nbegame.net +nbelec.com +nbenl.com +nbfeyy.com +nbfkgs.com +nbfox.com +nbgdjt.com +nbginnovations.com +nbgj.net +nbgjwl.com +nbgodo.com +nbgong.com +nbgree.com +nbgy.com +nbhao.org +nbhechang.com +nbhhgroup.com +nbhky.com +nbhuke.com +nbhxmr.com +nbhysj.com +nbidifund.com +nbimer.com +nbit6d.com +nbjcae.com +nbjcds.com +nbjingyong.com +nbjisi.com +nbjit.com +nbjlw.com +nbjnw.com +nbjoyo.com +nbjttz.com +nbjzjn.com +nbjzzsw.com +nbkaisheng.com +nbkc-rp.com +nbkdl.com +nbkjcx.com +nbkqyy.com +nblhlyy.com +nblhwy.com +nblilong.com +nblongzhan.com +nblwhb.com +nblyhy.com +nbmai.com +nbmedicalsystem.com +nbmiao.com +nbmidun.com +nbmpzs.com +nbmylike.com +nbmyy.com +nbmzyl.com +nbnnn.xyz +nbocc.com +nbocqdm.xyz +nbosco.com +nbpathcent.org +nbpmia.com +nbpolytheatre.com +nbqixing.com +nbqwrc.com +nbrawwater.com +nbrcg.com +nbrcw.com +nbren.net +nbrj.com +nbrlzy.com +nbruili.com +nbscxh.com +nbsdjyy.com +nbsfgy.com +nbshunjian.com +nbshuoxue.com +nbshzwyy.com +nbsijian.com +nbslkg.com +nbslxh.com +nbsmjt.com +nbsp99.com +nbsqbank.com +nbsti.net +nbstjt.com +nbstrans.com +nbsz.com +nbszgd.com +nbt.ren +nbtlwl.com +nbtobacco.com +nbttbn.com +nbtzjd.com +nbtzsh.com +nbuci.com +nbudp.com +nbunicom.com +nbuser.com +nbvps.net +nbwaf.net +nbwan.net +nbwbw.com +nbweldingtorch.com +nbwelldon.com +nbwetc.com +nbwhg.com +nbwskj666.com +nbxdjt.com +nbxiaoshi.net +nbxry.com +nbxsjg.com +nbxsrc.com +nbyang.com +nbyeda.com +nbyjrf.com +nbyouth.com +nbyyz.com +nbyzyy.com +nbzhongxin.com +nbzhuzhai.com +nbzjpc.com +nbzsq.com +nbzxgj.com +nbzyenergy.com +nc-bio.com +nc189.net +nc530.com +ncarzone.com +ncawzs.com +ncboo.com +ncc-cma.net +nccqj.com +nccurbanmayfair.com +ncderuida.com +ncdxbbs.com +ncepujournal.com +ncfcsa.org +ncfgroup.com +ncfimg.com +ncfjj.com +ncfwx.com +ncfz.com +ncgprq.com +nch-bg.com +nchq.cc +nchtech.com +nchycw.com +ncidbj.com +nciyuan.com +ncjrailway.com +nclqq.com +ncmbio.com +ncmem.com +ncmtkj.com +ncmtr.com +ncnynl.com +ncogvki.xyz +ncore.cc +ncpa-classic.com +ncpc.biz +ncpqh.com +ncpssd.org +ncq8.com +ncqiche.com +ncsdyyy.com +ncshxd.com +ncsjhf.com +ncsxy.com +ncsyco.com +nctry.com +nctvcloud.com +nctzsj.com +ncu.me +ncvt.net +ncvtmi.com +ncwsxh.org +ncwsxx.com +ncxhrc.com +ncxinshou.com +ncxuw.com +ncyrqs.com +ncyscb.com +ncyunqi.com +nczfgjj.com +nczfj.com +nczxst.com +nczxwl.com +nczy.com +nd15.com +nd56.com +nd597.com +ndapp.com +ndbzteck.com +ndcimgs.com +ndcjl.com +ndcpp.com +ndcppx.com +ndcyx.com +nddaily.com +nddnrm.com +nddst.com +ndfdc.com +ndgchina.com +ndgf.net +ndgzy.com +ndhx.net +ndhys.com +ndiip.com +ndj520.com +ndjtwl.com +ndkhn.com +ndkybio.com +ndmh.com +ndoo.net +ndpharm.com +ndsad.com +ndsbbs.com +ndscsoft.com +ndser.net +ndsyy.com +ndszgb.com +nduoa.com +nduoshousi.com +nduotuan.com +ndvfxyvj.sbs +ndxlj.com +ndyt.com +ndzfl.com +ndzls.net +ne01.com +ne21.com +ne365.com +ne56.com +neapme.com +nearcharge.com +neardi.com +nearsnet.com +nease.net +neashow.com +neat-reader.com +neatifyapp.com +neboer.site +nebulogy.com +neccsh.com +necgokr2-724.acs.wecandeo.com +necool.com +nedfon.co +nedigitals.com +neeca.net +neefood.com +neegle.net +neeinn.com +neep.shop +neeq.cc +neets.cc +neeu.com +neffkb.com +nei-mao.com +nei.tm +neigou.com +neihan.net +neihancommunity.com +neihancommunity.net +neihandiantai.com +neihanfly.com +neihang.net +neihanshequ.com +neimaowang.com +neimenggugames.com +neisha.cc +neitui.com +neituixiaowangzi.com +neixiong8.net +neko.pub +nekoarch.cc +nelkshuhe.com +nellit.info +nellit.net +nellit.xyz +nelson-textiles.com +nelsonjulia.shop +nelumbosp.com +nengapp.com +nengdarack.com +nenggeimall.com +nenghaoidc.com +nengqiang.com +nengrui.com +nengshida.com +nengshouwangluo.com +nengyuanxx.com +nenufm.com +nenup.com +nenzei.com +neo-yiming.com +neo.org +neo1989.net +neoap.com +neobiochina.com +neoease.com +neoease.org +neofaith.net +neofussvr.sslcs.cdngc.net +neohytung.com +neojos.com +neolee.com +neolix.net +neomodulus.com +neoremind.com +neoscholar.com +neoschool.com +neosey.com +neoyon.com +nep-logistics.com +neptcn.com +neptunus.com +neqtahotelshanghai.com +nercdtv.org +nercel.com +nerin.com +nero-cn.com +nerocats.com +nerochat.com +nerve-corp.com +nervepotato.com +nes-auto.com +nesbbs.com +nesmt.org +nesoso.com +nesox.com +nespressochina.com +nestgene.com +nestlechinese.com +nesyouxi.net +net-add.com +net-measure.net +net-rope.com +net-sharp.com +net-swift.com +net-times.net +net0516.com +net111.info +net130.com +net199.com +net2345.net +net263.com +net767.com +netac.com +netandtv.com +netat.net +netbian.com +netbooo.com +netchina100.com +netcoc.com +netcolc.cc +netconst.com +netcoretec.com +netcute.com +netded.com +netease-inc.com +netease.com +netease.im +neteasegame.com +neteasegame.net +neteasegames.com +neteasegames.net +netentsec.com +netesee.com +netgamecar.com +netge.com +netherlandvcenter.com +nethonghe.com +netianshannu.com +netiler.com +netinfi.com +netinfi.net +netingcn.com +netitest.com +netkao.com +netman123.com +netnoease.com +netor.net +netpi.me +netpoint25.com +netposa.com +netqd.com +netsmell.com +netspreading.com +netstatic.net +netsun.com +netswise.com +netsyq.com +nett.to +nettvpro.live +netvp.net +network-hk.com +networkesl.com +networklinkpro.com +networklo.com +netzonesoft.com +netzz.net +neu-reality.com +neucrack.com +neuedu.com +neunn.com +neupaas.com +neuqsoft.com +neuroxiv.com +neuroxiv.net +neusemi.com +neusncp.com +neusoft.com +neusoftmedical.com +neutrontek.com +neux.studio +nevadaheladosjujuy.com +nevem.com +new-elegance.com +new-mobi.com +new-thread.com +new0633.com +new1cloud.com +new253.com +new669.com +new7.com +newacademic.net +newaigou.com +newaircloud.com +newamigo.net +newamstar.com +newansha.com +newaq.com +newasp.com +newasp.net +newayz.com +newbakers.com +newbandeng.com +newbanker.com +newbd.com +newbeaconhotels.com +newbeebook.com +newbeebox.com +newbenglish.com +newbook8.com +newcapec.net +newcentral.com +newcentury-edu.com +newcger.com +newchainbase.com +newchieve.com +newchinabeach.org +newchinalife.com +newcitygz.com +newclasses.org +newclouddenfender.com +newcoder.com +newcosemi.com +newdao.net +newday.me +newdreamgroup.com +newdroid.net +newdruginfo.com +newdu.com +newdun.com +newe.tv +newelementchina.com +newer2001.com +newevcar.com +neweyezs.com +newft.com +newglp.com +newgscloud.com +newharbour.net +newhb.com +newhbdoor.com +newhopbattery.com +newhopeagri.com +newhopegroup.com +newhqnotary.com +newhtml.net +newhua.com +newikou.com +newistock.com +newjg.com +newkunhua.com +newland-edu.com +newlandaidc.com +newlandcomputer.com +newlandnpt.com +newlesson.com +newlifex.com +newlink.com +newlixon.com +newlongbj.com +newlongma.com +newluobo.com +newmaker.com +newman.mobi +newmargin.com +newmorehot.com +newnanbao.com +newnewle.com +newniu.com +newoasis.cc +newoo.com +neworiental.org +nework360.com +neworldedu.org +newposture.vip +newqjsteel.com +newrathon.com +newrizon.com +news18a.com +newsapp01.com +newsccn.com +newscctv.net +newseasoft.com +newsgd.com +newsgu.com +newsgx.com +newshengwei.com +newshs.com +newsighting.com +newsing.com +newskj.com +newskj.org +newskyunion.com +newsletter-cn.com +newsletter-nespresso.com +newslqy.com +newsmth.com +newsmth.net +newsmy-car.com +newsmy.com +newsmyshop.com +newsn.net +newspluse.com +newssc.net +newssc.org +newstarpress.com +newstartsoft.com +newstjk.com +newsungroup.com +newsungroup.net +newsv5.com +newsxc.com +newsxcar.com +newsxy.com +newsyc.com +newszjk.com +newtab123.com +newtalentaward.com +newtao.work +newtimeai.com +newtimevalve.com +newtonghua.com +newtop100.com +newtouch-elec.com +newtouch.com +newtranx.com +newtrip.com +newume.com +newupbank.com +newvfx.com +newvisionvc.com +newvr.com +newwatchesale.com +newxing.com +newxitong.com +newxue.com +newyanshamall.com +newyifagroup.com +newyishi.com +newyorkerdownunder.com +newyorkluxurywatch.com +newyoton.com +newyx.net +newzealandvscenter.com +newzgc.com +newzhizao.com +newzhongyuan.com +nexaparty.com +nexmoe.com +nexon.to +next-bei.com +next-playground.com +nextclass.club +nextclass.com +nextday.im +nextech-x.com +nextjoy.com +nexto2o.com +nextpcb.com +nextplayground.com +nextriskcontrol.com +nextrt.com +nextstudios.com +nexttao.com +nextvid.net +nextworkshop.net +nextyu.com +nexus-holding.com +nexus.dell.com +nexusapex.cfd +nexushd.org +neyetwatcher.com +neytap.com +nezhu.com +neznanskyphoto.com +nf-ref.com +nf.video +nf108.com +nf56.com +nfbdc154.org +nfc315.com +nfcic.com +nfcmag.com +nfcreader.net +nfcs-med.com +nfcs-medical.com +nfdx.net +nffq.net +nffund.com +nfgjhr.com +nflchina.com +nflsxl.com +nfmedia.com +nfmrtfv.com +nfnews.com +nfoservers.com +nfpeople.com +nfqbyp.com +nfs-china.com +nfschina.com +nfsyx.com +nftrr.com +nfvalve.com +nfwl168.com +nfxsy.com +nfyeya.com +nfyny.com +nfyun.vip +nfyy.com +nfyyzcfy.com +nfzhouyi.com +nfzmy.com +nfzzh.com +ng-alain.com +ng021.com +nga.wiki +ngaa.info +ngaa.shop +ngaa.top +ngaacdn.com +ngaacdn.net +ngaagslb.com +ngaagslb.net +ngabbs.com +ngacn.cc +ngarihealth.com +ngbbs.com +ngc-marine.com +ngcgears.com +ngctransmission.com +ngcz.tv +ngedu.net +ngfcyy.com +ngfjkzps.com +ngh6.com +nghmesc.com +ngicer.com +nginstar.net +ngjjtg.com +ngkjjt.com +ngksz.com +ngmap.com +ngmyt.com +ngnice.com +ngnlink.net +ngo.com +ngotcmszh.com +ngread.com +ngrok.cc +ngs1685.com +ngswgs.com +ngtravelercn.com +ngty556.com +ngwxw.com +ngxn.com +ngzyxx.com +nh.com +nh2h.com +nh56.com +nhaidu.com +nhaidu.net +nhcec.com +nhcilab.com +nhcsw.com +nhd-mart.com +nhdacrw.xyz +nhdia.com +nhdmd.com +nhfyyy.com +nhganggeban.com +nhhongyi.com +nhjjlt.com +nhkaiyang.com +nhkeysu.com +nhkw-zh-hlscomp.akamaized.net +nhkwlive-xjp.akamaized.net +nhlq.com +nhmuni.com +nhnexpo.com +nhnst.com +nhooo.com +nhspd.com +nhwa-group.com +nhxz.com +nhygkj.com +nhzb.com +nhzhaopin.com +nhzj.com +nhzs.com +ni8.com +ni93.com +nianchu.net +nianhuawan.com +niankawang.com +nianlingjisuanqi.com +nianlun010.com +niannz.com +nianqin.cc +nianqin123.com +nianshao.me +niansir.com +niao95.com +niaobulashi.com +niaocms.com +niaogebiji.com +niaola.com +niaoquan.fun +niaosuangao.online +niaowoclub.com +niaoyun.com +niba.com +nibaguai.com +nibaku.com +nibj.com +nibomu.com +nic.ren +nic.xin +nicaicheng.com +nicaifu.com +nicaifu.net +nice-app.com +nice-china.com +nice1688.com +nicebing.com +nicebooker.com +nicecdn.com +nicefilm.com +niceguo.com +niceinno.com +niceios.com +niceisp.com +nicekid.com +niceloo.com +nicenergy.com +nicesnow.com +nicetheme.xyz +nicetuan.net +nicewatch.cc +nicexf.com +niceyea.com +nicezhuanye.com +nichuanbo.com +nickbussok.com +nicksxs.com +nicky1605.com +nicolaszhao.com +niconiconi.cc +nicosu.com +nicot-motor.com +nicotine.vip +nics365.com +nicsbuy.com +nicwind.com +nidecms.com +nidiandaojia.com +nie.io +nieapps.com +niegobrand.com +niegoweb.com +nielsenccdata.tv +nies.org +niexiaotao.com +nieyou.com +nifdc.com +nifengz.com +nightanddaythegame.com +nightcity.pub +nightmare.press +nihao.net +nihaoafrica.org +nihaodd.com +nihaotv.net +nihaotw.com +nihaowang.com +nihil.cc +nihonngo.site +niiam.com +niiceda.com +niiddm.com +niimbot.com +niiwoo.com +nikanpian.com +nike-inc.com.tw +nike.host +nike666.com +nikefans.com +nikkisoft.com +nikkiup2u2.com +nikkon-china.com +nilai.com +nileloan.com +nim-lang-cn.org +nimitzvac.com +nimolife.com +nimzx.com +nindeli.com +nine-rivers.com +ninebot-link.com +ninebot.com +nineplaying.com +nineroad.com +ninesix.cc +ninestargroup.com +ninestarmall.com +ninetylab.com +nineya.com +ning0370.com +ningban.com +ningbo-airport.com +ningbocat.com +ningboenlighten.com +ningboexport.com +ningbofy.com +ningborunner.com +ningbotianxia.com +ningbotm.net +ningbowater.com +ningdo.com +ningdong.com +ninghao.net +ninghuoban.com +ningidc.com +ningkangyuan.com +ningkekeji.com +ninglutech.com +ningma.com +ningmengdou.com +ningmengyun.com +ningshing.com +ningtingche.com +ningto.com +nington.com +ningxi.com +ningxiacaijing.com +ningxiagames.com +ningxiahuangheyun.com +ningxingxing.com +ningzhe.net +ningzhi.net +ningzhishidai.com +ningzhitec.com +ninjacn.com +ninjadq.com +ninomiya.store +nint.com +nintaus.com +ninthpalace360.com +ninthpalace520.com +nio.com +nioapis.com +niozhr.com +niparts.com +nipei.com +nipic.com +nipponcore.com +nis.stream.publicradio.org +nischina.org +nishuoa.com +nissmi.com +nitaitag.com +nittoseiki-cn.com +niu-tu.com +niu.com +niua.com +niuacc.com +niuap.com +niubalun.com +niubb.net +niubibsn.com +niubihonghong.net +niubilai.com +niubilety.com +niubixia.com +niubo.cc +niuboli.com +niucache.com +niucdn.com +niuche.com +niuclass.net +niucodata.com +niudai120.com +niudashu.com +niudie.cc +niufang.net +niufun.com +niug8.com +niugame.net +niugp.com +niuguwang.com +niuhuagong.com +niujinniu.com +niukk.com +niuming147.com +niunai.com +niuniu-dns.com +niuniufund.com +niuniutui.com +niupiano.com +niupianwang.com +niupinhui.com +niupu.com +niuqia.com +niurenqushi.com +niurosoft.com +niuschools.com +niushe.com +niushield.online +niushoushan.net +niutech.com +niutk.com +niutoushe.com +niutrans.com +niuwk.com +niuxiaoer.net +niuxyun.com +niuyou5.com +niuyuan.com +niuza.com +niuzhigongzuo.com +niuzhu.com +niuzhuan-test.com +nivtc.com +niwangwang.com +niwodai.com +niwodai.net +niwoxuexi.com +nixi.win +nixingtao.com +nixwang.com +niyingseo.com +nizhan888.com +nizi88.com +nizkeyboard.com +nj-anruitai.com +nj-bl.com +nj-bw.com +nj-chishun.com +nj-control.com +nj-deli.com +nj-dhl.com +nj-gw.com +nj-halfmarathon.com +nj-hr.com +nj-huaqiang.com +nj-hust.com +nj-jp.com +nj-jy.com +nj-kejin.com +nj-kk.com +nj-maici.com +nj-nanhuai.com +nj-newhope.com +nj-qiyiguo.net +nj-reagent.com +nj-ss.com +nj-tencentclb.cloud +nj-tencentclb.com +nj-tencentclb.net +nj-tencentclb.work +nj-test.com +nj-tongrentang.com +nj-tops.com +nj-tq.com +nj-xyzs.com +nj-zhengze.com +nj-zhongbo.com +nj-zj.com +nj0827.net +nj12320.org +nj127.com +nj13z.net +nj1937.org +nj29jt.net +nj303yy.com +nj63.com +nj87.com +njabsw.net +njaces.com +njacme.com +njajjt.com +njajt.com +njaline.com +njanmu.com +njaolian.com +njaoti.com +njatl.com +njavc.com +njbaisou.com +njbaoxun.com +njbdhb.com +njbestway.com +njbhec.com +njbhhb.net +njbiaochen.com +njbj888.com +njbnw.com +njbpvi.org +njbsby.com +njbtkt.com +njbx.com +njbx.work +njbytyq.com +njc100.com +njcangong.com +njcaringmedical.com +njcatv.net +njcbcmjt.com +njccwei.com +njcdata.com +njcedu.com +njcgs.com +njchanke.com +njchengyi.com +njchina.com +njcitygas.com +njcjby.com +njcjszyy.com +njcjzz.com +njcky.com +njcl-gear.com +njclwlkj.com +njcmotor.com +njcmsj.com +njcnmc.com +njcomptech.com +njctcm.com +njcttq.com +njcw.com +njcwlk.com +njcxj.com +njcyt99.com +njd1.com +njdapaidang.com +njdatang.com +njdewo.com +njdftl.com +njdfwb.com +njdfzg.com +njdianyong.com +njdiip.com +njdndz.com +njdnjt.com +njdq-ld.com +njdqgytg.com +njdtyx.com +njdzjcyq.com +njdzn.com +njeport.com +njfdyy.com +njfjkj.com +njfk.net +njfkdq.com +njfklngl.com +njflt.com +njfmz.com +njforge.com +njfuruisi.com +njfybjy.com +njfzad.com +njfzdc.com +njfzjc.com +njfzm.net +njgaokai.com +njgb.com +njgcct.com +njgcyy.com +njgdbus.com +njgdhb.com +njgdjg.com +njgdmm.com +njgean.com +njggk.com +njgh.org +njghes.com +njghgf.com +njgjj.com +njgjngq.com +njgjsj.com +njgjyy.com +njgljy.com +njglobalielts.com +njglsx.com +njglyy.com +njgn.com +njgreen.net +njgsmach.com +njguangkui.com +njgulan.com +njguochu.com +njguotong.com +njguoxuan.com +njgy.net +njgyjx.com +njgzm.com +njhanrui.com +njhbyl.com +njhctest.com +njhcyq.com +njhd025.com +njhddl.com +njhdzy.com +njhengda.com +njhengyou.com +njheyang.com +njhgame.com +njhightech.com +njhipower.com +njhjgs.com +njhjyy.com +njhkyq.com +njhmmr.com +njhnzx.com +njhonest.com +njhongfa.com +njhonghu.com +njhongya.com +njhoutai.com +njhrjt.com +njhsjt.com +njhszoo.com +njhtg.com +njhtjt.com +njhuachuang.com +njhuatian.com +njhuatong.com +njhuazhu.com +njhunyan.com +njhxnpx.com +njhxzx.com +njhy-elec.com +njhy-tech.com +njhzypiano.com +njiabe.com +njiairport.com +njianzhan.com +njibhu.com +njibmfwq.com +njicg.com +njicia.com +njiec.com +njiig.com +njimi.com +njjbsc.com +njjcbio.com +njjdzl.com +njjgfckyy.com +njjgjs.com +njjgzlgl.com +njjhjt.com +njjht.com +njjiancai.com +njjianguo.com +njjiantian.com +njjienuo.com +njjifei.com +njjknkyy.com +njjn.com +njjnrc.com +njjnwzyy.com +njjnzc.com +njjrc.com +njjrkj.com +njjspzx.com +njjst.com +njjsxy.com +njjsyy.com +njjtjl.com +njjttt.com +njjtxx.org +njjundong.com +njjunpu.com +njjuntong.com +njjwkj.com +njjxtz.com +njjz.net +njjzsensor.com +njjzyxh.com +njkaifeng.com +njkaiguan.com +njkcsj.com +njkeeryq.com +njkefayuan.com +njkerun.com +njkeystone.com +njkhhb.com +njkhly.com +njkilter.com +njklclear.com +njkongte.com +njkoopan.com +njkpdz.com +njkq.net +njkskn.com +njkzgjj.com +njl114.com +njlanwu.com +njletop.com +njlg56.com +njlhzn.com +njlianyang.com +njlietou.com +njlike.com +njlingyun.com +njliterature.org +njlizhuo.com +njljhy.com +njljjy.com +njljscl.com +njlkjc.com +njlndl.com +njlofty.com +njlonsen.com +njloyalty.net +njlrxx.com +njlsw.com +njltxx.com +njluye.com +njlyc.com +njlyjt.com +njlzsx.net +njmama.com +njmapp.com +njmatx.com +njmbwxzx.com +njmdzx.net +njmeisai.com +njmes.org +njmjs.com +njmjzn.com +njmkt.com +njml120.com +njmlxy.com +njmoon.com +njmsdk.com +njmuseum.com +njmuseumadmin.com +njmwwl.com +njnanlin.com +njnanmu.com +njnaws.com +njndgl.com +njnemin.com +njnewgreen.com +njnfwl.com +njnhsx.net +njnhyx.net +njnii.com +njningyi.com +njnkxt.com +njnkzz.com +njnpfl.com +njntdj.com +njnwyy.com +njnysoft.com +njnzrs.com +njodu.com +njouman.com +njpeptide.com +njpkwater.com +njpkzyy.com +njpmp.com +njpuao.com +njpud.com +njpujiang.com +njqchyxh.com +njqhjy.net +njqihong.com +njqinghai.com +njqxrc.com +njrbjd.com +njrealway.com +njrgrj.com +njrjt.com +njrmzx.com +njrnk.com +njrs119.com +njrsks.net +njrsxh.com +njruipu.com +njruisen.com +njrunk.com +njrzkj.com +njsadz.com +njsanhui.com +njsdjt.com +njsdyy.com +njsech.com +njsech.net +njsenwo.com +njservo.com +njsfyb.com +njshengde.com +njshenglue.com +njshsh.com +njshsw.com +njsimba.com +njsjz.com +njskxlyy.com +njskxlyy.net +njslaq.com +njslawyers.org +njsljy.com +njsme.com +njsmz.com +njspkj.com +njspkrmyy.com +njsqxqyy.com +njsrsyxx.com +njsspeek.com +njstht.com +njstia.com +njstudy.com +njstx.net +njstzbxxx.com +njsujing.com +njsunchem.com +njsunlord.com +njsunshine.com +njswgs.com +njswkj.com +njsxfxh.com +njsyue.com +njsyxy.com +njszxyy.com +njszy.com +njtaihong.com +njtapery.com +njtechsafety.com +njteyun.com +njtgdq.com +njthgy.com +njthsp.com +njtjyq.com +njtn.com +njtobacco.com +njtoyo.com +njtqw.com +njtrabon.com +njtransplant.com +njtrh.com +njtrq.com +njtst.com +njuchem.com +njued.com +njuoe.com +njupco.com +njust.pub +njuup.com +njuwh.com +njvcare.com +njvkd.com +njw88.com +njwbjj.com +njwcjx.com +njwds.com +njweixiao.com +njweiyi6.com +njwmbj.com +njwpdi.com +njwqqx.com +njwrr.com +njwsp.com +njwtm.com +njwtqx.com +njwuhe.com +njwww.net +njwx.com +njwz.net +njwzjsw.com +njxax.com +njxcj.com +njxfcft-tencentclb.cloud +njxfcft-tencentclb.com +njxfcft-tencentclb.net +njxfcft-tencentclb.work +njxiaochi.com +njxizebio.com +njxjjsjt.com +njxkyy.net +njxlhd.com +njxlxx.com +njxnjt.com +njxsmz.com +njxty.com +njxueyun.com +njxushang.com +njxwyl.com +njxxrc.com +njxyyy.com +njxzwh.com +njyafeng.com +njyaoze.com +njycwy.com +njydky.com +njyec.com +njyhhj.com +njyhznkj.com +njyjglxh.com +njyjxh.com +njyjzz.com +njyouwin.com +njypk.com +njyqhj.com +njyqkj0ksyz.com +njyqmj.com +njyspharma.com +njysw.com +njytian.com +njytyy.com +njyuanlang.com +njyule.club +njyulong.com +njyuyuan.com +njyxdq.com +njyy.com +njyy.name +njyydl.com +njyyhyxh.com +njyysf.net +njyz.net +njyzdl.com +njyzgz.com +njyzmj.com +njzb.net +njzb.org +njzdhotel.com +njzdyq.com +njzdyy.com +njzec.com +njzefeng.com +njzfy.com +njzhengluan.com +njzhengyuan.com +njzhituo.com +njzhongtuo.com +njzhsw.com +njzhuce.com +njzhzx.net +njzikao.com +njzj.net +njzjamc.com +njzkwiot.com +njzkyy.com +njzqzs.com +njzrdq.com +njzsgroup.com +njzxgy.com +njzxxyy.com +njzychemical.com +njzywangluo.com +njzztyl.com +nk-sh.com +nk8686.com +nkf-pharma.com +nkiec.com +nkjy.com +nkks378.org +nkshw.com +nkuytzv.com +nkygty.com +nkzy.com +nlark.com +nlbgt.com +nlecloud.com +nlhszc.com +nliniz.com +nlinkline.com +nlktj.com +nlogn.art +nlpjob.com +nlplab.com +nls1853.com +nlsc.group +nlscan.com +nlteck.com +nlttms.com +nlww168.com +nlxn.com +nlypx.com +nlyzzzxrmyy.com +nlzpw.com +nlzpy.com +nm178.net +nm8yx.com +nmb-bj.com +nmbcp.com +nmbfxy.com +nmboat.com +nmbxd1.com +nmbyh.com +nmcoo.com +nmcpo.com +nmet168.com +nmgbaiju.com +nmgchina.cc +nmgczx.com +nmgd.com +nmgfood.net +nmgfrank.com +nmgfy.com +nmggwy.org +nmggyy.com +nmghhjt.com +nmghtszkj.com +nmgjdxy.com +nmgjkmc.com +nmgjtjt.com +nmgjxjy.com +nmgjyzh.com +nmgjzyxh.com +nmglabs.com +nmglawyer.com +nmgmarathon.com +nmgmzys.com +nmgonline.com +nmgrsksw.com +nmgswkj.com +nmgswtz.com +nmgup.com +nmgwhly.com +nmgwxgs.com +nmgyjszx.com +nmimi.com +nmjtzy.com +nmjyl.com +nmkjxy.com +nmliao.cc +nmlpa.com +nmod.net +nmpfkj.com +nmrdata.com +nmrxw.com +nmsl.gs +nmslwsnd.com +nmt2.com +nmtyxy.com +nmufh.com +nmvps.com +nmwbk.com +nmweidian.com +nmxc.ltd +nmxxprt.com +nmzh.net +nn-jinlun.com +nn-tct.com +nn.com +nn12333.com +nn1yy.com +nn1zx.com +nn2fy.com +nn2yy.com +nn3yy.com +nn4yy.com +nn4z.com +nn5itt.com +nn5yy.com +nn6yy.com +nn6zx.com +nn7yy.com +nn8yy.com +nn9yy.com +nnairport.com +nnanyang.com +nnayd.com +nnbanrui.com +nnbbrn.com +nnbdfyy.com +nnbnutritionchina.com +nnboao.com +nnbooster.com +nnboyi.com +nnbsjyk.com +nnbtl.com +nnbupin.com +nnbyg.com +nncbre.com +nncc626.com +nncg1688.com +nnch.net +nnchuangliang.com +nnchyy.com +nncj.com +nncjnkyy.com +nncjyy.com +nncjzc.com +nnclgs.com +nncnjh.com +nnctjt.com +nnctzcfz.com +nncwsoft.com +nncxjh.cc +nncydyf.com +nncytz.com +nndache.com +nndascom.com +nndayuan.com +nnddssaaddeeyy.com +nnddxd.com +nndegas.com +nndims.com +nndj168.com +nndjg.com +nndjxcl.com +nndsj.co +nndssk.com +nnduyi.com +nndya.com +nndylm.com +nndz3xu7.com +nnedqp.com +nnedu.com +nnewn.com +nnfae.com +nnfcetyy.com +nnfcxx.com +nnfdys.com +nnflkyz.com +nnflzyyy.com +nnfrp.com +nnfsw.com +nnfwwb.com +nnfwzl.com +nngdjt.com +nngeo.com +nnggzxc.com +nngj.com +nngjj.com +nngjjx.com +nnglbj.com +nngljc888.com +nngreenscm.com +nngrhj.com +nngtbw.com +nnguphoto.com +nngxqscy.com +nngyds.com +nnhaidong.com +nnhaoyuan.com +nnhbsl.com +nnhccc.com +nnhccl.com +nnhcszc.com +nnhengfu.com +nnhh8.com +nnhhhbgs.com +nnhkdz.com +nnhlgx.com +nnhltz.com +nnhmcj.com +nnhongbei.com +nnhpbbs.com +nnhqcy.com +nnhqjd.com +nnhrsip.com +nnhtsy.com +nnhuaxin.com +nnhuaxiong.com +nnhuishi.com +nnhwxh.com +nnhxgg.com +nnhxwygs.com +nnhytyy.com +nnhzkj888.com +nnhzt.com +nnippsp.com +nnit30.com +nnjajt.com +nnjajt.xyz +nnjdgl.com +nnjgsd.com +nnjht.com +nnjhwy.com +nnjiangmei.com +nnjieshuo.com +nnjingchu.com +nnjingda.com +nnjingyuan.com +nnjioko.com +nnjiuji.com +nnjiuzhidu.com +nnjj120.com +nnjjk.com +nnjjtgs.com +nnjkjzs.com +nnjkwy.com +nnjl.com +nnjmskj.com +nnjnwg.com +nnjr.co +nnjsdsoft.com +nnjsgy.com +nnjsypx.com +nnjsza.com +nnjszlsb.com +nnjt.com +nnjtjt.com +nnjtkt.com +nnjtyq.com +nnjuheli.com +nnjunliang.com +nnjxbs.com +nnjy100.com +nnjzd.com +nnjzybl.com +nnkailong.com +nnkcy.com +nnkeerlab.com +nnkeruan.com +nnkeyuan.com +nnkhjq.com +nnkin.com +nnkj77.com +nnkqfs.com +nnkxnz.com +nnlanfang.com +nnlfcm.com +nnlgjt.com +nnlib.com +nnljhb.com +nnljoa.com +nnljsw.com +nnlsbl.com +nnlvdu.com +nnlwoo.com +nnlxart.com +nnlxs.com +nnlyjp.com +nnlzhs.com +nnmama.com +nnmhzc.com +nnminghe.com +nnmingyuanyun.com +nnmjm.com +nnmsjdgs.com +nnmutong.com +nnmyst.com +nnmzfy.com +nnmzof.com +nnn.vip +nnn666.com +nnnen.com +nnnews.net +nnngs.com +nnnntv.com +nnnuo.com +nnpckj.com +nnpma.com +nnpml.com +nnpnzx.com +nnpp.vip +nnqh.net +nnqianfan.com +nnqmjy.com +nnqsk.com +nnrbsoa.com +nnrc.net +nnrfjc.com +nnrig.com +nnrkz.com +nnrongjie.com +nnruixin.com +nnrxzm.com +nnryf.com +nnrzfw.com +nnsanke.com +nnsatai.com +nnsbc.com +nnsc6.com +nnscsy.com +nnsdygs.com +nnsenhong.com +nnsftz.com +nnsg520.com +nnsgx.com +nnshengan.com +nnshenghua.com +nnshzhg.com +nnsirui.com +nnsjcgs.com +nnslx.com +nnslzy.com +nnsmk.com +nnsmy.com +nnsqr.com +nnsrjsnzp.com +nnssyjs.com +nnstbss.com +nnsugar.com +nnsuoyu.com +nnsupeng.com +nnswdx.com +nnsxd.com +nnsygs.com +nnsylq.com +nnsymy.com +nnsynldc.com +nnsynqzyyy.com +nnsz.com +nnszwl.com +nnt0.net +nntaichu.com +nnthink.com +nntlj.com +nntlyy.com +nntobo.com +nnttsoft.com +nntuobang.com +nntxw.com +nntzgz.com +nnups.com +nnwb.com +nnwhg.com +nnwilking.com +nnwitkey.com +nnwk.net +nnwow.com +nnwrxd.com +nnwsgl.com +nnwtgs.com +nnwxtzgs.com +nnwysc.com +nnwytl.com +nnxchda.com +nnxcx.com +nnxczxjt.com +nnxdj.com +nnxfz.com +nnxiehehospital.com +nnxinxiang.com +nnxiyun.com +nnxjtf.com +nnxknkyy.com +nnxl.net +nnxmbh.com +nnxqy.com +nnxsypco.com +nnxt.net +nnxxzl.com +nnybf.com +nnybskq.com +nnych.com +nnydcs.com +nnyfjc.com +nnyhjc.com +nnyhtx.com +nnyhxl.com +nnyingxuan.com +nnyiya.com +nnyjpco.com +nnykx.com +nnylhz.com +nnynrc.com +nnyongzhou.com +nnysart.com +nnyunying.com +nnyy17.com +nnyypc.com +nnyyq.com +nnyyyy.com +nnzc.net +nnzdbz.com +nnzgh.org +nnzgkj.com +nnzhaoguan.com +nnzhenyukj.com +nnzhnm.com +nnzhuoli.com +nnzjjckj.com +nnzjqc.com +nnzksy.com +nnzkzs.com +nnzljx.com +nnzmyx.com +nnzn1.com +nnzp.com +nnzp.net +nnzp8.com +nnzw168.com +nnzxtx.net +nnzyjob.com +no-mad-world.club +no1news.com +no8ms.com +noahedu.com +noaheducation.com +noahgroup.com +noahhealthcare.com +noahpharm.com +noahsnail.com +noahsoft-vn.com +noahteck.com +noahwm.com +noarter.com +nobb.cc +nobel120.com +noblefashion.hk +nobleliftgroup.com +noblove.com +nocang.com +nocare.com +noclyt.com +nocobase.com +nocode-tech.com +nocode.com +nocode.host +nod32jihuoma.com +nodcloud.com +node-is.green +node1link.xyz +nodeing.com +nodejs999.com +nodekey.com +nodelayusdtcasino.com +nodeme.site +nodepacific.com +nodpcba.com +noeic.com +nohost.pro +nohup.cc +noipto.host +noirphoenix.studio +noizztv.com +nokeeu.com +nokia-sbell.com +nokia.press +nokia88.com +nokurack.com +nolanchou.com +nolibox.com +nologo.tech +nolovr.com +nomax.vip +nome.com +nomuaexander.com +nomuaheridan.com +nomuamarcia.com +nomura-nset.com +nomuraoi-sec.com +nonfemet.com +nongbaike.net +nongbaotong.com +nongcun5.com +nongcundating.com +nongfadai.com +nongfuspring.com +nonggan.com +nonghushi.vip +nongji1688.com +nongji1958.com +nongji360.com +nongjiao.com +nongjiaoyun.com +nongjitong.com +nongjx.com +nongkaigufen.com +nongkeyu.com +nongli.com +nongli.net +nonglirili.net +nongmintv.com +nongnet.com +nongpin88.com +nongplay.com +nongshang.com +nongxinyin.com +nongyao001.com +nongye.tv +nongyedns.com +nongyelu.com +nongyemen.com +nongyie.com +nongyu.net +nonobank.com +noobboss.com +noobkrf.com +noobmb.com +noobn6.com +noobofficial.com +noobsb.com +noobshanhe.com +noobtime618.com +noobvip.com +noobwatches.com +noobyard.com +noobyy.com +noobzz.net +noodba.com +noogel.xyz +noomuuhapmav.com +noonaspizza.com +noonnoora.com +noontec.com +noops.me +nooshen.com +nootoo.com +nooxion.com +noposion.com +nor-land.com +noratechpharma.com +norchem-pharma.com +nordicic.com +nordicways.com +nordikr.com +nordkete.com +nordonfire.com +nordritools.com +norinco-vehicle.com +norinco.com +norincogroup-ebuy.com +norionpro.com +norislam.com +noritzd.com +normanes.com +normar8888.com +normcore.com +normstar.net +norroybioscience.com +norsencn.com +north30degrees.com +northbundforum.com +northdy.com +northernlights.ink +northgun.com +northland-bio.com +northsoar.com +northtexascribs.com +northtimes.com +nosec.org +nosoul99.com +nossmoke.com +nosub.net +nosuchfield.com +nosugar.tech +nosugartech.com +not3.com +notbucai.com +note52.com +notedeep.com +notetao.com +notetech.org +notion.pet +notonlymoon.com +notrisk.com +nouriz.com +nova-test.com +novaicare.com +novapps.com +novastagepharma.com +novastargame.net +novaxinli.com +novel-supertv.com +novelbio.com +novelfm.com +novelfmpic.com +novelfmstatic.com +novelfmvod.com +novell.me +novelquickapp.com +novelquickapppic.com +novemideas.com +novipnoad.com +novo-auto.com +novo-biotech.com +novocool.com +novocranes.com +novodriv.com +novogene.com +novosns.com +novotelcitygate.com +novotrail.com +novotrails.com +novots.com +novtecgroup.com +novtium.com +now-cn.net +nowapi.com +nowbeta.com +nowchip.com +nowcndns.com +nowcoder.com +nowcoder.net +nowcoder.org +nowec.com +nowhttps.com +nowmsg.com +nowo.com +nowodds.com +nowre.com +nowscore.com +nowtop.net +nowxz.com +noxagile.duapp.com +noxgroup.com +noxnny.com +noxpadelsale.com +noxxxx.com +noyes88.com +npbbs.net +npbeta.com +npc233.com +npcka.com +npedi.com +npfls.com +nphoto.net +npi-sh.com +npilasers.com +npjzjx.com +nplusgroup.com +nplusgroup.net +npmmirror.com +npmss.com +npmtrend.com +npoall.com +npodevelopment.org +npp-battery.com +npp.cc +npqx.com +nprc.net +nprnat-i.akamaihd.net +npsdyyy.com +npsel.com +nptpark.com +nptparking.com +nptwedding.com +npub.net +npuxs.com +npxsw.com +npz.com +nq6.com +nq8.net +nqctek.com +nqez.com +nqiief.com +nqjt.com +nqlai.com +nqmoui.com +nqqpp.com +nqyz.org +nr-esc.com +nrb.cc +nrbbearing.com +nrdzqwd.com +nrec.com +nri-beijing.com +nrisc.com +nrmchina.com +nrmtc.com +nrsfh.com +nrsg.net +nruan.com +nrwspt.com +nrzb0.com +ns-china.net +ns1.hk +ns1011.com +ns168.net +ns222s.com +ns365.net +ns5n.com +ns6s6.com +ns8d.com +nsbdjssy.com +nsbeta.info +nsccsc.com +nschctw.com +nscloudwaf.com +nscscc.com +nscscc.org +nsd-at.com +nsdfx.net +nsdic.com +nsdszsyxx.com +nsdt.cloud +nseac.com +nsecsoft.com +nseia.com +nsemii.com +nsfocus-sase.com +nsfocus.com +nsfocus.net +nsforce.net +nsfz.net +nsfzqhkg.net +nsgz.net +nshen.net +nshzpks.com +nsig.com +nsini.com +nsiqoaks.com +nsisfans.com +nsiuqsjaza.com +nskfagcn.com +nsknsk.com +nskwj.com +nsm-electrical.com +nsmodel.com +nsoad.com +nsqtlcdn.cc +nsqtlcdn.info +nsrcup.com +nsrfww.com +nsrjlb.com +nsrmarine.com +nsseii.com +nssf.work +nsshare.com +nsstream.com +nsswa.org +nstfhg.com +nstggroup.com +nsuci.com +nsuuu.com +nsw58.com +nsw88.com +nsw99.com +nswhj.com +nswscp.com +nswyun.com +nswzs.com +nsxdns.com +nsxww.com +nsydt.com +nsyhwakrkq2.com +nsynu.com +nszmz.com +nszone.com +nszxsyxx.com +nszynd66ggbcx.com +nt.app +nt.cc +nt56.net +nt6y.com +nt7fck19y3.com +ntaow.com +ntc-lft.com +ntc.sh +ntcaac.com +ntcchina.com +ntce.com +ntcfy.com +ntdingke.com +ntdjk.com +ntdsyy.com +ntdvf.com +ntes53.com +ntes53.net +ntescdn.com +ntesmail.com +ntesunn.com +ntfabu.com +ntfan.com +ntfegd.xyz +ntfhgj.com +ntflk.com +ntfssh.com +nthcl.com +nthfw.com +nthongda.com +nthysp.com +nti56.com +ntiee.com +ntjgjt.com +ntjgpx.com +ntjhbw.com +ntjhzy.com +ntjob88.com +ntjoy.com +ntjsxy.com +ntjymall.com +ntjzyxh.com +ntkfqjy.com +ntlcjd.com +ntmlxm.com +ntmyexp.com +ntneuro.org +ntp.felixc.at +ntp123.com +ntpcb.com +ntpcn.com +ntpharma.com +ntptimeserver.com +ntqcct.com +ntqfdq.com +ntrailway.com +ntrc.com +ntrcb.com +ntrun.com +ntsanxin.com +ntservicepack.microsoft.com +ntsgx.com +ntsuye.com +nttui.com +ntwikis.com +ntwzy.com +ntxx.net +ntxz.net +ntyodspt.com +ntyodspt.net +ntyswlkj.com +ntyy888.com +ntzhcs.com +nu1l.com +nu36.vip +nuan.chat +nuan.io +nuan.org +nuancaixs.com +nuancepharma.com +nuandao.com +nuanjiayuan.com +nuannuanapp.com +nuannuanzu.com +nuanpaper.com +nuanque.com +nuanshi100.com +nuantingapp.com +nuantong8.com +nuanyuehanxing.com +nubb.com +nubia.cc +nubia.com +nubia.mobi +nucc.com +nucleisys.com +nuctech.com +nuedc-ti.com +nuedcchina.com +nufans.net +nufrr.com +nuhcpf.com +nuhighbio.com +nuist.pro +nulipin.com +nullice.com +nullno.com +nullprivate.com +num1dns.com +num2020.com +numans.cc +numemory.com +nunaios.com +nuo5.com +nuoan.com +nuobaike.com +nuobeiliao.com +nuobeirack.com +nuobz.com +nuocdn.com +nuodaguandao.com +nuodefund.com +nuodepharm.com +nuoder.com +nuoerchina.com +nuofanpay.com +nuoguangsh.com +nuohotel.com +nuoji.com +nuoke147.com +nuomi.com +nuomicikoi.com +nuomili.com +nuomiphp.com +nuomisi.com +nuona.com +nuonuo.com +nuoshell.com +nuoshou2023.com +nuosike.com +nuoxun.com +nuoyahao.com +nuoyasite.com +nuoye.xyz +nuozhan.com +nuozhensh.com +nuptec.com +nuqixi.com +nurotron.com +nursesky.com +nusudia.org +nuszar.xyz +nutdh.com +nutra-max.com +nutriease.com +nutriera.com +nutrilite-farm.com +nutsbp.com +nutspace.com +nutstart.com +nutstore.net +nutstorehq.com +nutzam.com +nuvoltatech.com +nuvoton-m0.com +nuvoton-mcu.com +nuxtv.com +nuxue.com +nuyoahbk.com +nv2118.com +nvans.com +nvcam.net +nvcong.com +nvgate16.nvidia.com +nvhaiz.com +nvidia-china.com +nvkan.com +nvpuse.com +nvpuwo.com +nvsay.com +nvsheng.com +nvshengjie.com +nvsip.com +nvwu.com +nvyouguoji.com +nvzhanshen.com +nvziwu.com +nw-host.com +nw0898.com +nwbiotec.com +nwct.me +nwdlink.com +nweon.com +nwncd.com +nwshotel.com +nwzg.net +nx-sc.com +nx.cm +nx12346.com +nx5.com +nxadmin.com +nxcells.com +nxcrb.com +nxdns.net +nxeduyun.com +nxengine.com +nxez.com +nxgangyi.com +nxgjbyy.com +nxgtjt.com +nxgyzb.com +nxhongshanhe.com +nxin.com +nxist.com +nxit.us +nxjwl.com +nxlayer2.com +nxls.com +nxly766.com +nxmy.com +nxnba.com +nxnews.net +nxnmedia.com +nxnresearch.com +nxny.com +nxpta.com +nxrmyy.com +nxrrvmy.com +nxrte.com +nxruixin.com +nxsjgd.com +nxstjt.com +nxsyy.com +nxtf.net +nxtianshangb.com +nxxdns.com +nxxh.net +nxxhr.com +nxxinhaoyuan.com +nxxllt.com +nxxmqy.com +nxxzyimg.com +nxyqs.com +nxyqs.net +nxyxh.net +nxyy.asia +nxzcah.com +nxzhnyyjy.com +nxzwnews.net +ny-yy.com +ny1988.com +ny2000.com +nya.ink +nyaacat.com +nyat.app +nyato.com +nybai.com +nybaidu.net +nybw.net +nybyggx.com +nyckidsclub.com +nyd7y.com +nydsrrsh.com +nyefy.com +nyfzx.com +nyjvbs.xyz +nyjy-china.com +nylingshang.com +nync.com +nypd520.com +nyrmyy.com +nysenba.com +nysgjgs.com +nyshipyard.com +nyshszh.com +nyshui.com +nysswq.com +nywz.net +nyxg.vip +nyxgs.com +nyxiecheng.com +nyxlzy.com +nyxr-home.com +nyxx365.com +nyxz166.com +nyyfy.com +nyzdjj.com +nyzy.com +nz86.com +nz998.com +nzb555.com +nzbdw.com +nzcxh.com +nzggroup.com +nzghotel.com +nzhnb.com +nziku.com +nzkd.com +nzlw.com +nzmice.com +nzqyowk.com +nzrlzy.com +nzsensing.com +nzsiteres.com +nzw6.com +nzwgs.com +nzxww.com +nzygyt.com +o--o.win +o-home.com +o-hr.com +o-netcom.com +o-star.cc +o.pki.goog +o0-2.com +o014148q7p.com +o03011aokk.com +o03080aokk.com +o0310o.com +o03121aokk.com +o0o0w.com +o136.com +o2123.com +o2ee.com +o2moment.com +o2o4.com +o2oa.net +o2obill.com +o2ocms.com +o2ocn.com +o2oexpo.com +o2onet.com +o2packs.com +o2pcn.com +o2ting.com +o37o.net +o3ndix.com +o571.com +o5zyk9vu2d.com +o6s.net +o790l1uw6q.com +o92mv1ik.baby +oa025.com +oa0351.com +oa7day.com +oa8000.com +oa8858.com +oabc.cc +oabg.net +oachee.com +oacrm.com +oact.net +oafocus.net +oahelp.com +oahelp.net +oaimai.com +oait360.com +oak-amc.com +oaloft.com +oaloft.net +oalur.com +oameibang.com +oaooa.com +oaqi.com +oasesalliance.com +oasistry.com +oatenglish.com +oatos.com +oauto.com +oayqwkhg.com +oaz.cc +obagame.com +obai.cc +obaku.com +obatsipilisjos.com +obeesmedia.com +obeishi.com +obesu.com +obetal.com +obins.net +obj.cc +obj6.com +objccn.io +objcer.com +objcoding.com +obkoro1.com +obolee.com +oborad.com +obowin.com +obrao.com +obsapp.net +obsbot.com +obsidian-display.com +obsworks.com +obtelecom.com +obyee.com +ocahs.com +ocale.net +ocamar.com +ocar.tv +occasionishoes.club +occpay.com +ocd120.com +oceanaircorp.com +oceanbase.com +oceanbites123.com +oceancloudapi.com +oceancus.com +oceandatas.com +oceando.cloud +oceanengine.com +oceanhood.com +oceanol.com +oceanorama.com +oceanpine.net +oceanplayable.com +oceantime.org +ocent.net +ocetest.com +ocfess.com +ocft.com +ochirly.com +ochsystems.com +ocic-static.com +ocici.com +ocideal.com +ocimg.com +oclean.com +oclkj.com +ocn187.com +ocpuritech.com +ocsjs.com +ocsp.pki.goog +ocsp.us.cdnetworks.com +ocssaas.com +oct-asia.com +oct-cts.com +octbay.com +octcommercial.com +octeshow.com +octgulou.com +octholding.com +octhotels.com +octinn.com +octmami.com +octo.fm +octocathub.com +octoparse.com +octopus31.com +octopusgame.com +octre.com +octsszj.com +octsunshine.com +octwuhan.com +oculist.net +ocwms.com +ocwuaibq.com +ocypo.org +odaily.news +odalong.com +odao.com +odeasports.com +odict.net +odinichina.com +odinjc.com +odinjilin.com +odinliu.com +odlkj.com +odohx.org +ody8.com +odypw.com +odyzj.com +oealy.com +oeasy.org +oec365.com +oecd-ilibrary.org +oecr.com +oectib.com +oedtech.com +oedun.com +oeebee.com +oeeee.com +oejournal.org +oelove.com +oemao.com +oemhouse.com +oemnew.com +oempromo.com +oemresource.com +oemsoc.download.prss.microsoft.com +oemsocuat.download.prss.microsoft.com +oemssl.cn.cdn.cloudflare.net +oeob.net +oepamvxq.com +oepkgs.net +oepkgs.org +oesell.com +oetsi.com +of3d.com +ofcard.com +ofcms.com +ofdreader.net +ofenka.com +offcn.com +offer-wow.com +offerpluscn.com +offersloc.com +office-cn.net +office-kagu1.com +office-peixun.com +office68.com +office8hour.com +officeaid.com +officeaid02.com +officebai.com +officebay.net +officecdn.microsoft.com +officectrl.com +officemkt.download.prss.microsoft.com +officemktuat.download.prss.microsoft.com +officese.com +officeweb365.com +officezhushou.com +officezy.com +offodd.com +offshoremedia.net +ofgame.net +ofidc.com +ofo.com +ofopp.com +ofpay.com +ofpay365.com +ofuns.com +ofweek.com +ofweek.net +ofyoo.com +ogame3.com +ogaoxiao.com +ogaqcbfi.com +ogccdn.com +ogivzztz.com +ogl-dragon.com +ogsoyxg.com +ogxeidiv.com +oh100.com +oh4k.com +ohausyt.com +ohedu.net +ohgnylbp.shop +ohipic.com +ohltjt.com +ohltk.com +ohneen.com +ohohklp.xyz +ohqly.com +ohtly.com +ohtpc.com +ohyee.cc +oi-wiki.com +oi-wiki.org +oi3g.com +oia05041klq.com +oia05050klq.com +oia05051klq.com +oiaqye7985.com +oicat.com +oicp.io +oicp.net +oicp.vip +oicq88.com +oicto.com +oidchina.org +oigcn.com +oigps.com +oiine.com +oiinhand.info +oilchem.net +oilcn.com +oildigital.com +oilepay.com +oilmooc.com +oinbag.com +oincp.com +oinva5yl.com +oioidesign.com +oioiok.com +oioj.net +oishi-tm.com +oiwas.com +oiz611.com +ojcdn.com +ojhdt.com +ojidacp.com +ojkjt.com +ojpal.com +ok-meeting.com +ok-skins.com +ok0415.com +ok06.com +ok096.com +ok100i.work +ok123.com +ok126.net +ok1616.com +ok165.com +ok168.com +ok183.com +ok206.com +ok3w.net +ok619.com +ok888883.com +ok9624.com +oka-vip.com +okaapps.com +okad.com +okada-china.com +okadwin.com +okair.net +okaoyan.com +okayapi.com +okaybio.com +okbao.com +okbase.net +okbmf.com +okbuy.com +okcard.com +okcdnns.com +okchang.com +okchexian.com +okcxo.com +okdai.com +okdcc.com +okdd.net +okemu.com +okex.vip +okeycar.com +okfang.com +okgoes.com +okhimalayanzi.com +okhqb.com +okidc.com +okideaad.com +okii.com +okjc.one +okjike.com +okjk.co +okk123.com +okki.com +okktee.com +oklaapp.com +oklinklink.com +oklpoi.com +okmao.com +okmart.com +okmyapp.com +okng.com +okooo.com +okoooimg.com +okplife.com +okpush.com +okr.com +okrecovery.com +oks.ltd +oksec.net +oksun.com +oksvn.com +oktamall.com +oktjy.com +oktools.xyz +oktranslation.com +oktukids.com +okuer.com +okuma-byjc.com +okvnet.com +okweb.info +okwfqz.org +okwuyou.com +okxr.com +okyueche.com +ol-cdn.com +ol-img.com +olabo.net +olacio.com +olakeji.com +olami.ai +olatop.com +olatop.net +oldboyedu.com +oldcat.me +oldding.net +oldj.net +oldmanemu.net +oldmantvg.net +oldpan.me +ole-vod.com +olecn.com +oleoad.com +oli-wolong.com +oliannews.com +olidun.com +olinone.com +olipharma.com +oliver.ren +oliveryang.net +ollomall.com +olmhedbg.cc +olo4.com +olokitchen.com +oltfm.com +olwsz.com +olxd.com +olympicmuseum-nj.org +olymtech.com +olymvax.com +olys88.com +olzz.com +omacloud.com +omarea.com +omarte.com +omaten.com +ombuy.com +omccsh.com +omchain.com +omcube.com +omedsc.com +omeet.cc +omegatravel.net +omegaxyz.com +omen.com +omgaixm.com +omgxy.com +omiaozu.com +omicsclass.com +omicshare.com +omicshare.net +omifanyi.com +omigr.com +omlzx.com +omlzz.com +ommoo.com +omni-pharma.com +omnijoi.com +omnivision-group.com +omnshoes.com +omobi.cc +omooo.com +omooo.net +omos88.com +omowork.com +ompchina.net +ompower.cc +omronmed.com +oms-elevator.com +omsheji.com +omsmy.com +omso2o.com +omycar.cc +omyerp.com +on-sun.com +onaliyun.com +oncanyin.com +onccc.com +oncdp.com +onceai.com +onceoa.com +onche.net +oncity.cc +one-all.com +one-cdn.com +one-netbook.com +one-punch.win +one.edu.kg +one918.com +onealert.com +oneasp.com +onebash.com +onebiji.com +onebox.site +onebrowser.net +onebuygz.com +onecoder.site +onecommunity-asia.com +oneconnectft.com +onedi.net +onediankeji.com +onedict.com +onedns.net +oneflys.com +onefoot365.com +onegobrand.com +onegreen.net +onehome.me +onehousesh.com +oneic.com +onein.com +oneinf.com +oneitfarm.com +oneiwff.com +onekey.cc +onekeyghost.com +onekeyrom.com +oneleafchina.com +onelic.work +onelife-love.com +onelinkplus.com +onemtservers.com +onenice.tech +oneniceapp.com +onenoter.com +oneonewrite.com +oneplus.com +oneplus.net +oneplus6666.com +oneplusbbs.com +oneplusmobile.com +onescorpion.com +oneself.icu +oneshao.com +onesight.com +onespacechina.com +onesun-china.com +onething.net +onethingc.com +onethingcloud.com +onethingd.com +onethingn.com +onethingpcs.com +onethingtech.net +onetop.net +onetts.com +oneuedu.com +onev.cat +onevcat.com +oneway.mobi +onewedesign.com +onewo.com +onewos.com +onewsimg.com +onewtech.com +onexinli.com +onexmail.com +onexunge.com +oneyac.com +onezapp.com +onezh.com +onfun.net +ongoalconveying.com +ongoaltech.com +onijiang.com +onishi-cn.com +onixhiend.com +onjobedu.com +onkocares.com +onlady.net +online-cmcc.net +online-edu.org +online-phaidon.shop +onlinecn.com +onlineding.com +onlinedown.net +onlinekr.com +onlinenic.net +onlinesjtu.com +onlinesurvey.work +onlinexijiang.com +onlly.com +onloon.net +only-memory.com +only-moment.com +only4.work +onlyedu.com +onlyedu.net +onlyeduit.com +onlygamefans.com +onlyidc.com +onlylady.com +onlyling.com +onlyliuxue.com +onlymr.com +onlypat.com +onlyred.net +onlyrobotedu.com +onlyrubberparts.com +onlystem.com +onlywem.com +onnets1.xyz +ono-bbb.com +onochem.com +onrunningshop.com +onsiteclub.com +ontall.com +ontheroadstore.com +onthetrip.com +onthink.com +onwaf.com +onwear.net +onwork.com +onwsw.com +onyealink.com +onyi.net +onyuan.com +onyxcina.com +onyxwater.net +onyy255q8c.com +oo14.com +oo365.com +ooamjs.work +oobao.net +oocct.com +oocheoo.com +ooclab.com +oodii.com +oofont.com +oofos-sandals.net +oogcw.com +oogps.com +oogsy.com +oohdear.com +ooiii.com +oojsq.com +oolap.com +oomake.com +oonne.com +oooccc.com +ooofoo.com +ooogo.com +oooiove.com +ooojogo.com +ooomm.com +ooooai.com +oooooooooo213.com +ooopic.com +oopswow.com +oopz.vip +oortgslb.com +oortos.tech +ootu.cc +oouee.com +oouyan.com +oov.cc +ooxoo.net +ooxxc.com +ooyyee.com +op86.net +opadlink.com +opahnet.com +opaidb.com +opal-qt.com +opalhk.com +opark.com +opatseg.com +opcool.com +opdown.com +opectek.com +open-ct.com +open-douyin.com +open-falcon.com +open-falcon.org +open-open.com +open-search.org +open-verify.cc +open-whatsapp-hk.vip +open.cd +open1024.com +open147.com +open189.net +openaboc.com +openadx.com +openai.wf +openailab.com +openanolis.org +openapp.run +openasic.org +openatom.club +openbayes.com +openbcs.com +opencas.org +opencitybrain.org +opencloudgpt.online +opencloudos.org +opencloudos.tech +opencourt.vip +opendatalab.com +opendns123.com +openedv.com +openerp.hk +openeuler.org +openeuler.sh +openew.com +openfans.org +openfde.com +openfrp.net +opengame0.com +opengcc.org +opengslb.com +openharmonyproject.com +openhippy.com +openinstall.com +openintelliedge.tech +openke.net +openkylin.top +openlanguage.com +openlaw.work +openlayers.vip +openlearning.com +openlink.cc +openloong.org +openloongson.org +openluat.com +openmidas.com +openmmlab.com +openmv.cc +openos.org +openqa.com +openrasp.com +openrasp.info +openrasp.net +openrasp.org +openredcloud.com +openrice.com +openrtbadx.com +opensoce.com +opensplendid.com +openssw.com +openswap.space +opentrust.net +openuc.com +openvela.com +openwbs.com +openwrt.ai +openwrt.pro +openxiaoniu.com +openxsea.com +operachina.com +opfed.com +opfibre.com +opgw-oppc.com +opjmw1.ren +opkjh.com +oplay.net +oplinking.com +oplus.com +oplustrust.com +opmaterial.com +opp2.com +oppein.com +opplestore.com +oppo.com +oppo.mobi +oppodigital.com +oppoer.me +oppofind.com +oppojia.com +oppomobile.com +oppopay.com +opportunuity.com +opposales.com +opposhop.in +opposhore.com +oppowork.com +opqnext.com +oprtb.com +opsapp.com +opshields.com +opsjuas.shop +opskb.com +opskumu.com +opstatics.com +opstatistics.com +opstool.com +opt-os.com +optbbs.com +opticres.com +opticsjournal.net +optimized-ai.com +optinetchina.com +optiondoma.com +optmv.com +optol.net +optomedic.com +optuk2.com +optzmx.com +opuzswk5tbt25.com +opwill.com +opython.com +oqss.com +oqwizd.com +oqwnfambg.com +or-sun.com +oracle-tencent.com +oracle-tencent.net +oracle-tencent.org +oracle.com +oraev.com +orafl.com +oralpractice.com +orange-ci.net +orange2h.com +orangeapk.com +orangeclk.com +orangelovely.com +orangemum.com +orangenews.hk +orangepi.org +orangesgame.com +orangetage.com +orangevip.com +oraper.com +orasos.com +oray.com +oray.net +oraybox.com +oraycn.com +orayer.com +orayimg.com +orbiepharm.com +orbitmes.com +orcadt.com +orchid-lanhua.com +orchome.com +orcode.com +orcony.com +ordchaos.com +ordedr.com +orderorigin.com +ordinaryroad.tech +ordosbank.com +ordosqyjt.com +ordostonghui.com +orebotech.com +orepainc.com +orfactory.com +org-hddnf.vip +org-tollsi.cc +organo-sz.com +orgcc.com +orggd.com +orgleaf.com +oriemac.com +orient-fund.com +orient-opto.com +orient-safety.com +orientaldata.com +orientalgas.com +orientalpearltower.com +orientalplaza.com +orientalwisdom.com +orientcable.com +orientcasa.com +orientengg.com +orientfoods.net +orientgene.com +orientgolf.com +orientgroup.com +orientpc.com +orientpowertech.com +orientscape.com +orienttextile.com +orienttumor.com +orientzj.com +orientzr.com +orifound.com +origin-a.akamaihd.ne +origin-a.akamaihd.net +originalimg.com +originalkindergarten.com +originalstatic.com +originalvod.com +origincn.com +originlee.com +originoo.com +originpic.com +originsilicon.com +originwater.com +origloria.com +orihard.com +oriphant.com +oritive.com +oriza.com +orjlight.com +orleto.com +orm-compressor.com +orolay.com +orsoon.com +orspr.com +orstatic.com +orsun.cc +ortc.cc +ortmk.com +orvaegao.com +orvibo.com +orz-dns.com +orz.asia +orz520.com +orz6.com +orzoupri.com +orztip.com +os-easy.com +os-lb.com +os-os.com +os-v.com +os7blue.com +osaaa.com +osakacopyshop.com +osapublishing.org +osase.net +osbdf.com +osbean.com +osbkj.com +osbzr.com +osc.cool +oscaches.com +oscarzhoud.com +oschina.com +oschina.io +oschina.net +oscs1024.com +osechina.com +osee-dig.com +oseminfo.com +oserror.com +osf2f.net +osf5xep778.com +osfipin.com +osgchina.org +osgervirtual.com +osgraph.com +osgz.com +oshadan.com +oshield.com +oshome.com +oshoplive.com +oshwhub.com +osicgroup.com +osizx.com +osjiaju.com +osk-clean.com +oskwai.com +oskwai.net +oslaw.net +osm-pearls.com +osmanbio.com +osmundacn.com +osnvuqwlsjakf.com +oso6.com +osogoo.com +osoos.com +ososn.com +osp.io +ospchina.com +ospod.com +osportsmedia.com +ospp.com +ospuq.org +osredm.com +osrelease.download.prss.microsoft.com +oss-cn-beijing-aliyuncs.com +oss.link +ossdshxh.com +osslan.com +osuxrq.com +osvlabs.com +osw3c.com +oswdj.com +oswhy.com +osx.cx +osxxy.com +osyunwei.com +otakirispring.org +otbmall.com +otc-china.com +otcaumiu.com +otcgd.com +otcms.com +otkglass.com +otm.ink +otms.com +otoeasy.com +otomedream.com +otosaas.com +otp-express.com +otpub.com +otqyzk7mx2t8.com +ott-live.olympicchannel.com +ott4china.com +ottai.com +ottcn.com +ottcn.help +ottffss.net +ottshopping.net +ottssp.com +ottv.tv +otuxu.com +otype.com +ou163.com +ou99.com +ouapi.com +oubauneereid.com +oubiix.lol +oubk.com +ouchang.net +ouchengzl.com +ouchgzee.com +oucuibo.com +oudapay.com +oudas.tech +oudianyun.com +ouei-sc-mulohomasi.com +oufa-travel.com +oufengblog.com +oufusoft.com +ougei.com +ouhua.info +ouhui.org +ouies88.com +ouj.com +oujiangroup.net +oujistore.com +oukan.online +oukyx.com +oulagongshi.com +oulehdtv.com +oulgp.com +ouliwang.com +oulongauto.com +ouluwind.com +ouluyun.com +oulvnet.com +oumaan.com +oumakspt.com +oume.cc +oumengke.com +ouming.com +oumoo.com +ounh.org +ounoe.com +ounuoyq.com +ouo7.com +ouou.com +ouou.icu +ououbet.com +ouougo.com +oup.com +oupaigroup.com +oupeng.com +oupeng9.com +oupengcloud.net +oupula.com +oupuzw.com +our100.net +our360vr.com +ourai.ws +ourail.com +ourats.com +ouravr.com +ourbits.club +ourbloom.com +ourbluecity.com +ourcargo.com +ourcdns.com +ourchem.com +ourcloudsec.com +ourcm.net +ourdian.com +ourdlbs.com +ourdomains.com +ourdvs.com +ourdvs.info +ourdvs.net +ourdvsss.com +ourdvsssvip.com +ourdvsvip.com +ourdxz.com +ourdxz.info +ourdxz.org +oureman.com +ourep.com +ourfdn.com +ourgame.com +ourger.com +ourglb.com +ourglb.net +ourglb0.com +ourglb0.info +ourglb0.net +ourglb0.org +ourglb0vip.com +ourhf.com +ourhlb.com +ourhlb.info +ourhlb.org +ourhy.net +ourjay.com +ourjewel.com +ourjg.com +ourjiangsu.com +ourjs.com +ourjz.com +ourl.co +ourleadchina.com +ourlife365.com +ourltc.com +ourmate.net +ourmis.com +ourpalm.com +ourplat.net +ourplay.net +ourqm.com +ourren.com +oursakura.com +ourschool.cc +oursec1.com +oursec2.com +ourseo.net +oursmc.com +ourstech.com +ourtour.com +ourunited.com +ourwebat.com +ourwebcdn.com +ourwebcdn.info +ourwebcdn.net +ourwebcdn.org +ourwebcdnvip.com +ourwebhttps.com +ourwebpic.com +ourwebpic.info +ourwebpic.net +ourwebpic.org +ourwebpicvip.com +ouryao.com +ousaikj.com +oushangstyle.com +oushidiban.net +oushinet.com +oushisheng.com +oushivoyages.com +ousweixin.com +outbrandlink.com +outes.com +outfit7.com +outfit7.net +outlets365.com +outletscn.com +outman.press +outsoo.com +ouvps.com +ouwost.com +ouxiangxiezhen.com +ouyada.com +ouyade.com +ouyanghuasi.net +ouyaoxiazai.com +ouyeel.com +ouyingyimin.com +ouyizs.com +ouyu158.com +ouzhaorj.com +ouzhou.cc +ouzhougoufang.com +ov5.org +ovalechina.com +ovaqrzcw.com +ovcgegxa.com +ovcreative.com +ovdlb.com +ovdream.com +ove3bi5rpn.com +ovear.info +ovellpump.com +oversea-ks-cdn.com +overseasops.com +overseaspharm.com +overtrue.me +ovglass.com +ovhlb.com +ovhlb.net +ovicnet.com +ovid.com +ovital.com +ovital.net +ovjpvk.org +ovmgc.com +ovopark.com +ovopic.com +ovqq.com +ovrvo.com +ovscdns.com +ovscdns.net +ovtfwn.com +ovuems.com +ovupre.com +ovuwork.com +ovxe.com +owalle.com +oway.mobi +owecn.com +oweidata.com +oweis-tech.com +owent.net +owenzhang.com +owgels.com +owinchina.com +owl-go.com +owlxjz.lol +owo.cab +owocloud.net +owoit.com +owseals.com +owsgo.com +owspace.com +owulia.com +ox5tis8cm7zg82.com +oxbridgedu.org +oxerr.net +oxfordartonline.com +oxfordbibliographies.com +oxfordmusiconline.com +oxiang.com +oxiaohua.com +oxiranchem.com +oxrm.com +oxygenos.com +oxyry.com +oya365.com +oyalee.com +oyewifi.com +oygteapq.com +oym56lm.com +oyohyee.com +oyonyou.com +oyoozo.com +oyospider.com +oyoumo.com +oysd.com +oywtv.com +oyxdwx.com +oyya.com +oyzns.com +ozmvpbhc.com +ozocenter.com +ozonabc.com +ozonbigsell.com +ozoninfo.com +ozouckzr.com +ozsmartbuy.com +ozzair.org +ozzyad.com +p-an.com +p-bstarstatic.akamaized.net +p-dragon.com +p-e-china.com +p-er.com +p-i.vip +p-pass.com +p-sig-dom.com +p-sig-dom.net +p.biz +p.bstarstatic.com +p.cdn.persaas.dell.com +p023.com +p0371.com +p0431.com +p04e.com +p0kc9ym05p.com +p0y.com +p1.com +p12345.com +p24p75149p.com +p2cdn.com +p2hp.com +p2p001.com +p2p178.com +p2pbbs.net +p2pchina.com +p2pcq.com +p2peye.com +p2peye.net +p2psearchers.com +p2ptouhang.com +p3-china.com +p33t5y8b97.com +p4pfile.com +p4pp.com +p4ws8zptrrdc6.com +p4wtpoqzihi8v.com +p5w.net +p6air.com +p6sai.com +p7game.com +p80.net +p8811.com +p8games.com +p96q3p1m93.world +p99998888.com +pa.ci +pa18.com +pa1pa.com +paahu.com +paalermat.com +paascloud.net +paat.com +pabulika.com +pacdn.com +pacebms.com +pacfc.com +pacgatelaw.com +pacicanschool.com +pacificchinaaero.com +pacificimmi.com +pacificphar.com +pacilution.com +packagesddn.win +packertec.com +packetmania.net +packsky.com +packtom.com +packty.com +pacmantwo.com +pacs-plus.com +pactera.com +padao.org +padasuo.net +padddy.vip +paddlepaddle.org +paddlewaver.com +padh.net +padns.com +padtf.com +paer.work +pafj.net +pafwl.com +pag.art +pagd.net +pageadmin.net +pagedoo.com +pagescube.com +pageseagle.com +pagetu.com +pahhhf.com +pahx.com +pahys.com +pai.video +paiago.com +paiangmedical.com +paiangstudy.com +paibanxia.com +paibaohy.com +paichen.net +paichi.com +paicoding.com +paidai.com +paidui.com +paiduidai.com +paigepian.com +paihang114.com +paihang360.com +paihang8.com +paihb.com +paihotels.cc +paihuisy.com +paikew.com +paiky.com +paiky.net +pailitao.com +pailixiang.com +paimaprint.com +paiming.net +paintinghere.org +paints.market +paipai.com +paipai123.com +paipaibang.com +paipaiimg.com +paipay.net +paipianbang.com +pairmb.com +paishi.com +paitol.com +paivideo.com +paiwan.com +paixiangxian.com +paixin.com +paixueche.net +paiyidan.net +paiyuyy.com +paizhaofanyi.net +paizhe.com +paizi.com +paizi.net +paizia.com +paizin.com +paizishop.com +pajkb.com +pajkdc.com +pajktj.com +pajt.com +pal-fin.com +palace-international.com +palanceli.com +paldq.com +pallasa.com +pally-travel.com +palm-ad.com +palm-h.com +palm.tech +palma-battery.com +palmda.com +palmebook.com +palmeread.com +palmestore.com +palmexpo.com +palmfungames.com +palmjoys.com +palmpay-inc.com +palmpay.com +palmpk.com +palmtrends.com +palmyou.com +paloinino.com +palomachina.com +pamahotel.com +pamica.com +pamss.net +pan-good.com +pan-ics.com +pan-key.com +pan131.com +pan58.com +pan8.net +panabit.com +panaihua.com +panasiashipping.com +panasonic-door.com +panasonicmall.com +panawincn.com +panbaidu.net +panbrake.com +panchinasports.com +panchip.com +panchuang.net +panda-home.com +panda-js-power.com +panda.ren +panda98.com +panda995.xyz +pandabus.cc +pandadairy.com +pandadastudio.com +pandafoundation.org +pandagreen.com +pandahome.org +pandainc.cc +pandaminer.com +pandapaint.net +pandara.xyz +pandaremit.com +pandateacher.com +pandatv.com +pandax.wiki +pandolia.net +panduoduo.net +pangbo51.com +pangbu.com +pangcheng.com +pangdago.com +pangdasc.com +pangdly.com +pangeng.vip +panggugu.com +panghuasheng.com +pangjun.com +pangku.com +pangku01.com +pangmao56.com +pangmaovc.com +pangod.com +pangodsxbj.com +pangoing.com +pangolin-sdk-toutiao-b.com +pangolin-sdk-toutiao.com +pangolin-sdk-toutiao1.com +pangolin-sdk-toutiao2.com +pangolin-sdk-toutiao3.com +pangolin-sdk-toutiao4.com +pangomicro.com +pangqiu.com +pangshare.com +pangshu.com +pangsuan.com +pangu.io +pangubox.com +panguhotel.com +panguidc.com +pangukj.com +pangusheng.com +panguso.com +pangxieke.com +pangyuan.com +panjiayuan.com +panjin.net +panjindamibest.com +panjk.com +panku.cc +pankuaisou.com +panlai.com +panlan.com +panli.com +panlv.net +panmeme.com +pannacloud.com +panocom.com +panoeade.com +panomix.com +panoramastock.com +panothers.com +panpanfood.com +panpanzsw.com +panpass.net +panpay.com +panqiincs.me +panqishu.com +panruikj.com +panshenlian.com +panshi101.com +panshianquan.com +panshihudong.com +panshiminerals.com +panshixk.com +panshiyun.com +panshy.com +pansino-solutions.com +panso.pro +pansoso.com +pansou.com +pansousuo.com +pantherhealthcare.com +pantonechina.com +pantower.com +pantrysbest.com +pantuitui.com +pantum.com +panwangkeji.com +panweizeng.com +panxsoft.com +panyiyun.com +panyouwl.com +panyun.com +panyunkj.com +panyuwater.com +paoao.net +paodoo.com +paojiao.com +paoka.com +paokucloud.com +paolanhuanbao.com +paomo.com +paomochengxingji.com +paopao.com +paopaoche.net +paopaohd.com +paopaosz.com +paoshuba.cc +paoshuba.org +paoxue.com +paozhengtong.com +paozw.org +papa21.com +papa91.com +papago.hk +papajohnschina.com +papajohnshanghai.com +papapa.tv +papatya.store +papazw.com +papegames.com +paper-translation.com +paper.tv +paper120.net +paperang.com +paperask.com +paperbert.com +paperbus.com +paperbye.com +paperccb.com +paperclipglobal.com +papercool.com +paperdb.com +papereasy.com +paperge.com +paperinsight.net +paperisok.com +papernew.net +paperok.com +paperonce.org +paperopen.com +paperpass.com +paperpass.org +paperpp.com +paperrater.net +paperright.com +papers.cool +papersay.com +papersee.com +papertime.cc +papertime.shop +papertime.vip +paperweekly.site +paperword.com +paperyy.com +papocket.com +papuanewguineans.com +paquapp.com +parallelsras.com +paratera.com +parawikis.com +parduscycle.com +parentshk.com +paris-girafe.com +parisblackpride.org +parkbees.com +parketech.com +parkicloud.com +parking520.com +parkinginfoweb.com +parkingjet.com +parkingos.club +parkingpda.com +parkingquickly.com +parkingsaas.com +parkingwang.com +parkmecn.com +parkonroad.com +parkshen.com +parkviewgreen.com +parkwaychina.com +parkworld.net +parkyardhotel.com +parsein.com +partinchina.com +partner-group.com +partner.cdnetworks.com +partnerboost.com +party68.com +paschermontre.to +pasecng.com +pasertech.com +pashu5.org +pass7.cc +passer-by.com +passfab.com +passfab.tw +passion120.com +passiongroupltd.com +passip.xyz +passnat.com +passthepopcorn.me +passwordkeyboard.com +pat-edu.com +pat-edu.org +patachina.org +patchallin.com +patchew.org +patek.website +patekphilippe.website +patent9.com +patentguru.com +patexplorer.com +patfun.com +patheagames.com +patholancet.com +pathologycn.com +patiencepoker.com +patsev.com +patsnapglobal.com +patv123.com +paul-corp.com +paul.pub +paulzzh.com +pauwaypower.com +pavay.com +pavayjt.com +pavilionshenzhenhotel.com +paxdn.com +paxgl.com +paxhz.com +paxini-robot.net +pay-in.com +pay-lakala.com +pay-ly.com +paybaike.com +paydxm.com +payeco.com +payititi.com +paykwai.com +paylf.com +paympay.com +paynews.net +paypaytech.com +paytollbyv.world +paytolltfd.world +paytollvfd.world +pb89.com +pbaohza.com +pbc-dcep.com +pbcan.com +pbcedu.net +pbcft.com +pbchizhou.com +pbdpw.com +pbiso.com +pbkrs.com +pblie.com +pbqdhty.com +pbrcw.net +pbsvpn.com +pbtcw.com +pbtlpm.com +pbtsl.com +pbtt.net +pbtxt.com +pbyz.net +pc-120.com +pc-daily.com +pc.wiki +pc02.com +pc028.com +pc120.com +pc15.net +pc168.com +pc18.net +pc186.com +pc34.com +pc360.net +pc51.com +pc520.net +pc521.net +pc5210.com +pc528.net +pc55.com +pc6.com +pc699.com +pc6a.com +pc89.com +pc8h.com +pc9.com +pcapqz.com +pcasl.com +pcauto.com +pcb-hl.com +pcb-membraneswitch.com +pcb3.com +pcb818.com +pcbask.com +pcbba.com +pcbbar.com +pcbbbs.com +pcbeta.com +pcbhunt.com +pcbjob.com +pcbserve.com +pcbsheji.com +pcbtech.net +pcbtime.com +pccm88.com +pccpa.hk +pccppc.com +pcdan.net +pcdn100.com +pcdnhome.com +pcdog.com +pcdrv.com +pcdtg.com +pceggs.com +pceva.net +pcfphs.com +pcfreetime.com +pcgeshi.com +pcgogo.com +pcgta.cc +pch.pub +pchome.com +pchome.net +pchpic.net +pcidv.com +pciiss.com +pcitc.com +pcitech.com +pcjsq.com +pcljl.com +pcmgr-global.com +pcmgr-global.net +pcmoe.net +pcoic.com +pcoof.com +pcoyx.com +pcpc521.com +pcpop.com +pcpresent.com +pcqudong.com +pcr9170.com +pcscedu.com +pcsee.org +pcsfc.com +pcshou.com +pcsjsm.com +pct86.com +pctutu.net +pctvx.com +pcw365.com +pcwcn.com +pcweb3.com +pcwenti.com +pcwgu.com +pcwl.com +pcxitongcheng.com +pcyangguangban.com +pcysy.com +pcz.net +pczhi.com +pd-italent.com +pd-sts.com +pd120.com +pd17.com +pdafans.com +pdai.tech +pdb2.com +pdbeta.com +pdd-fapiao.com +pdd.net +pddcdn.com +pddeu.com +pddglobalhr.com +pddim.com +pddpic.com +pddugc.com +pddxfd.com +pdeepmatrix.com +pdf.la +pdf00.com +pdf1122.com +pdfangchan.com +pdfbianji.com +pdfdo.com +pdffsy.com +pdfjia.com +pdflibr.com +pdfxd.com +pdfzj.com +pdgohome.com +pdgzf.com +pdhr.com +pdidc.com +pdie-expo.com +pdinvestmentgroup.com +pdlib.com +pdlnn.com +pdloscar.com +pdm.tech +pdnob.com +pdosgk.com +pdrcfw.com +pdreading.com +pdreamer.com +pdryx.com +pdscb.com +pdsey.com +pdsgjj.com +pdshouse.com +pdskgb.com +pdswater.com +pdsxww.com +pdszhtl.com +pdty123.com +pduoduo.vip +pdvc.com +pdvisa.com +pdwxo.vip +pdxx.net +pdxxg.com +pdzls.com +pe-exhibition.com +pe.vc +pe898.com +peace-read.com +peacebird.com +peaceboat.net +peacepetro.com +peacha.net +peacockedu.com +peak-labs.com +peaksport.com +peakyun.cc +peal.cc +pear.hk +pearlinpalm.com +pearvideo.com +peasrch.com +peatour.com +pebellows.com +peccn.com +pechoin.com +pecmgd.com +pecoo.com +pediatrixtherapeutics.com +pediy.com +pedli.com +peekpipai.com +peento.com +peepic.com +peerkennel.com +pegbiocq.com +peidibrand.com +peidu.com +peihao.space +peihu-lyjkgl.com +peihuyi.com +peijiamedical.com +peijian.com +peijian8.net +peikua.com +peilian.com +peiluming.com +peiluyou.com +peipusci.com +peise.net +peisebiao.com +peiwan.tv +peiwanlu.com +peiwantv.com +peixianedu.com +peixiang.com +peixinbao.com +peixinkj.com +peixinyi.com +peixun.net +peixun360.com +peixun5.com +peixune.com +peixunla.com +peixunmatou.com +peixunxue.com +peiyake.com +peiyicha.com +peiyin.net +peiyinge.com +peiyingefiles.com +peiyingo.com +peiyinshenqi.club +peiyinxiu.com +peiyou.com +peiyouwang.com +peiyue.com +peizi.com +pejdw.com +pejxjy.com +pekhongyuan.com +peksung.com +pelejs.com +pelorseating.com +pemap.com +pemch.com +penavicoxm.com +pending-renewal-domain.com +pengbaoxuan.com +pengboguandao.com +pengchengenergy.com +pengchenglx.com +pengfei.com +penghh.fun +penging.com +pengke.com +penglei.name +pengliao.com +pengpailaw.com +pengqi.club +pengqian.win +pengrl.com +pengrui-ssj.com +pengshancy.com +pengtuzm.com +penguin-logistics.space +pengxinziyuan.com +pengyaou.com +pengyihotel.com +pengyou.com +pengyou.net +pengyoukan.com +pengyuanled.com +pengyucpa.com +pengyuwei.net +pengzhihui.xyz +penhuijiqi.com +peninsula-med.com +penlingaizao.com +penno-pallet.com +pensunny.com +pentalaser.com +pentaq.com +pentatomic.com +pentiw.com +penyouw.com +penzai.com +penzealcn.com +people-squared.com +people78.com +people78.net +peopleapp.com +peopleart.tv +peopledailyhealth.com +peopledailypress.com +peoplehealthdata.com +peoplekg.com +peoplelamp.com +peoplemooc.com +peoplerail.com +peoplewang.com +peopleyuqing.com +pepresource.com +pepsimeipai.com +pepsitmall.com +peptide-china.com +perfect-input.com +perfect99.com +perfectdiary.com +perfecttradinghk.com +perfectwatchen.com +perfertw.com +perfma.net +peropero.net +peroperogames.com +persagy.com +perseverany.com +personabook.net +personpsy.org +perspectivar.com +pescms.com +pesiv.com +pesrmyy.com +pesyun.com +pet-mri.com +pet86.com +petaindonesia.org +petalmail.com +petalmaps.com +petalsdata.com +petctchina.com +petctw.com +peter-zhou.com +peterjxl.com +petersonjace.shop +petersonlian.com +petgugu.com +pethr.com +petkit.com +petkoo.com +petktasia.com +petly.net +petmrchina.com +petmrs.com +petope.com +petpcb.com +petpetin.com +petrexchina.com +petroren.com +petrostaroil.com +petrvet.com +petssky.com +pewax88.com +pewld.com +pewsc.com +pexue.com +pf.net +pf110.com +pf168.com +pfcexpress.com +pfhoo.com +pfinno.com +pfjekm.org +pfmmedicalchina.com +pft12301.cc +pftianshanno.com +pfwx.com +pfzhiliao.com +pg-leak.com +pg114.net +pgbee.com +pgc.tv +pgcaststone.com +pgcog.com +pgdz.com +pgdz4422.com +pggho.com +pghqa.org +pgidp.com +pgidw.com +pgive.com +pgjcqm.com +pgjxo.com +pgl-world.com +pglstatp-toutiao-b.com +pglstatp-toutiao.com +pgmcatalyst.com +pgos.cc +pgosglobal.com +pgpop.com +pgq.win +pgqcw.com +pgqjz7733.com +pgrm.site +pgsql.tech +pgxqw.net +pgxxw.com +pgy6.com +pgyapi.com +pgyer.cc +pgyer.com +pgyer.im +pgyidc.com +pgyy.com +pgyy.vip +pgzs.com +pgzx.net +ph-fc.com +ph365.bond +ph66.com +phaenothera.com +phaetonsemi.com +phalapi.net +phantasy.life +pharaohvisionstudios.com +pharbers.com +pharm81.mobi +pharmacn.com +pharmacodia.com +pharmacyyf.com +pharmalego.com +pharmcube.com +pharmengin.com +pharmglass.com +pharmproc.com +pharmzs.com +pharnexcloud.com +pharscin.com +phaser-china.com +phb01.com +phb123.com +phbang.net +phedu.net +phemu.net +phenom-sem.com +phet.fan +phezzan.com +phgll.com +phhongyu.com +phicomm.com +philanthropy.xin +philipswechat.com +philisense.com +philjang.work +phirda.com +phirs.com +phjqs.com +phjt.com +phlexing.com +phmacn.com +phnamedns.com +phnixhome.com +phnixpool.com +pho.so +phodal.com +phoemix.net +phoenix-ea.com +phoenixfilters.net +phoenixos.com +phoenixtea.org +phoenixtv.com +phoent.com +phoer.net +phome.net +phone580.com +phonecoolgame.com +phonegap.me +phonegap100.com +phonelinksoft.com +phonertech.com +phonthing.com +phopic.com +phosun.com +photc.com +photo0086.com +photo3050.com +photo889.com +photocnc.com +photocome.com +photohn.com +photoncounts.com +photonpay.com +photops.com +photosks.vip +php-note.com +php-oa.com +php100.com +php168.com +php168.net +php318.com +phpbbchina.com +phpbloger.com +phpcashshare.com +phpchina.com +phpcom.net +phpcomposer.com +phpconchina.com +phpcoo.com +phpddt.com +phpdr.net +phpe.net +phpernote.com +phperservice.com +phperz.com +phpfs.com +phpha.com +phphub.org +phpjiami.com +phpjiayuan.com +phpkaiyuancms.com +phplife.net +phpor.net +phpsong.com +phpspider.org +phpstat.net +phpub.mobi +phpv.net +phpwc.com +phpwc.info +phpweb.net +phpweblog.net +phpwind.com +phpwind.net +phpxs.com +phpyun.com +phsb.com +physicalchina.com +physicalchina.vip +physicalclub.com +physike.com +physoe.com +phyuan.com +phyy.com +phzg.com +pi7.com +piaget-hello.com +pianbar.net +pianbingji.com +piankuai.com +pianohl.com +pianor.com +pianoun.com +pianpian.net +piantou.net +pianyilo.com +pianyit.com +pianyiwan.com +piao.com +piao.tips +piao88.com +piao95.com +piaobing.com +piaobuy.com +piaochong.com +piaocom.com +piaodaren.com +piaode.ren +piaodian.net +piaododo.com +piaodown.com +piaogroup.com +piaohomeinn.com +piaohua.com +piaojubao.com +piaolia.com +piaoliang.com +piaoliusan.com +piaoniu.com +piaoqianqian.com +piaoquantv.com +piaoshen.com +piaotian.org +piaotongyun.com +piaowutong.cc +piaowutong.com +piaoxian.net +piaoxingqiu.com +piaoyi.org +piaoyun.net +piaozone.com +piasy.com +piaviation.com +pic-cname.cc +pic-png.com +pic16.com +pic21.com +pic315.com +pic3733.com +pic720.com +picacgp.com +picatown.com +picbling.com +picc.com +piccamc.com +picchealth.com +piccjs.com +picdlb.com +picdns.com +picing.com +pickme.cc +pickpikka.com +picooc.com +picosmos.net +picovr.com +picoxr.com +picp.io +picp.net +picsandquotes.com +picsays.com +pictureknow.com +picup.shop +picxiaobai.com +picyourmix.com +picyq.com +pidcn.com +pidoutv.com +pidru.com +piececool.com +pieceofbake.net +pieeco.com +piekee.com +piekee.net +pieshua.com +pifa.bz +pifa333.com +piflogistics.com +pifukezaixian.com +pig4cloud.com +pig66.com +pigai.org +pigcms.com +pighaihe.com +pigji.com +pigmentlc.com +pigmoral.tech +pigonline.org +pigsq.com +pigsty.cc +pigv5.com +pigx.vip +pigyun.com +pihitech.com +pihmh.com +piimg.com +piios.com +pikoplay.com +pikpak.me +pikpakdrive.com +pil0txia.com +pilaipiwang.com +pilidns.com +pilifu.com +pilimeng.com +pimaoji.com +pimax.com +pimei.com +pimgeek.com +pin-color.net +pin18pin.com +pin2eat.com +pin5i.com +pinan1688.com +pinbaitai.com +pinbaiyan.com +pinbang.com +pinbayun.com +pinble.com +pinble.net +pinchain.com +pinchedashi.com +pinchetang.com +pincn.com +pinda.com +pinduoduo.com +pinduoduo.net +pinelephant.com +pinestoneasset.com +pinfangw.com +pinfeng.group +pinfun.com +ping-an.net +ping-jia.net +ping-qu.com +ping99.com +pingan.com +pingan.com.hk +pingancdn.com +pinganfang.com +pinganfu.net +pingansilu.org +pinganventures.com +pinganwj.com +pinganyun.com +pinganzhengxin.com +pinganzhengyang.com +pingcap.com +pingce.net +pingchuangyl.com +pingcode.com +pingcode.tech +pingcoo.com +pingdingshan.me +pingdurc.com +pingevip.com +pingfangx.com +pingfanli.com +pingfenbang.com +pinggao.com +pinggaogroup.com +pinggu.com +pinggu.org +pingguobaoxiu.com +pingguodj.com +pingguoid.com +pingguolv.com +pinghe.com +pinghu.tech +pinghui-cn.com +pingjiata.com +pingmudiy.com +pingnanlearning.com +pingnantong.com +pingnuosoft.com +pingpangwang.com +pingpingw.com +pingpingze.com +pingplusplus.com +pingpongx.com +pingpongx.org +pingshu365.com +pingshu8.com +pingshuku.com +pingshuocoal.com +pingshuxiazai.com +pingstart.com +pinguan.com +pinguo.us +pingwest.com +pingxiangzhifa.com +pingxiaow.com +pingxuan123.com +pingxx.com +pingyin.cc +pingzishuo.com +pinhaohuo.com +pinhui001.com +pinidea.co +pinjiago.com +pinjiao.com +pinjiaolian.com +pinjie.cc +pinjieqicai.com +pinjiesj.com +pinkecity.com +pinkehao.com +pinkertech.com +pinkoichina.com +pinkou.com +pinla.com +pinlyu.com +pinmanduo.com +pinmuch.com +pinocchiowb.com +pinpai-bang.com +pinpai1.com +pinpai37.com +pinpaihuoyuan.com +pinpailiu.com +pinpaime.com +pinpointloc.com +pinpopt.site +pinqugongxiangktv.com +pinqukeji.com +pinshu.com +pinsuodesign.com +pintangshi.com +pintechpharma.com +pintreel.com +pintu360.com +pintuan.com +pintuanya.com +pintuer.com +pintuju.com +pintuxiu.net +pinuc.com +pinwaiyi.com +pinweiqifu.com +pinxianghui.com +pinxianghui.net +pinyafang.com +pinyinxiang.com +pinyuan.cc +pinyuew.com +pinzhenglh.com +pinzhi.org +pinzhi365.com +pinzhikeji.net +pinzs.com +pioneer-pharma.com +pioneer-pku.com +pioneerchina.com +pioneerep.com +pioneernews.cc +pioneersci.com +pipa.com +pipacoding.com +pipahealth.com +pipaw.com +pipaw.net +pipedetect.com +pipegg.com +pipgame.com +pipikou.com +pipikun.com +pipilu.com +pipimp3.com +pipipi.net +pipipifa.com +pipishu.com +pipiti.com +pipix.com +pipixue.com +pipsemi.com +pipuda.com +piqs.com +piscesys.com +pisx.com +pitayaio.com +piuqiupia.com +pivotacp.com +pivotautomotive.com +piwxal.work +pixbe.com +pixcakeai.com +pixcakes.com +pixcheese.com +pixe44lrifted.com +pixelauth.com +pixeldance.com +pixelgame.net +pixepf.sbs +pixiaojiang.com +pixivic.com +pixpark.net +piyanzi.com +piyipiba.com +pj-666.com +pj-road.com +pj.com +pj0099.com +pj09.com +pj334.org +pj39800.com +pj57.com +pj62049.com +pj73.com +pjbest.com +pjf.name +pjgear.com +pjgjg.com +pjhome.net +pjhubs.com +pjjjw.com +pjjyzx.com +pjlyds.com +pjob.net +pjtime.com +pjtka.com +pk106.com +pk137.com +pk2234.com +pk38.com +pk532.com +pk7o.com +pk995.com +pkbeta.com +pkbff.com +pkbigdata.com +pkcity.com +pkfish.com +pkfj.xyz +pkfun.com +pkgame.com +pkghund.com +pkgklk.com +pki.plus +pkm360.com +pkma.cc +pko123.com +pkoplink.com +pkpmjc.com +pkpmsoft.com +pkpuke.com +pkq.xyz +pksf8.com +pksfc.com +pksky.com +pkslow.com +pkt-cable.com +pku-cele.com +pku-hc.com +pku-hit.com +pku-lvxin.com +pku666.com +pkucare.com +pkucarenjk.com +pkucnooch.com +pkufh.com +pkufi.com +pkugac.com +pkulaw.com +pkulaws.com +pkulb.com +pkuncii.com +pkunn.com +pkuph.com +pkuphqd.com +pkupuzzle.art +pkurc.com +pkusky.com +pkusp.com +pkuszh.com +pkutourism.com +pkuxue.com +pkvs.com +pkwenku.com +pl999.com +plaidc.com +plalzhang.com +planary-yz.com +planckled.com +planetariuminsight.site +planetarylighting.com +planetmeican.com +planpelham.com +plantb2b.com +plantname.xyz +plantnutrifert.org +plantower.com +plas-cn.com +plasdata.com +plastics-machinery-equipment.com +plasway.com +plateno.cc +plateno.com +platenogroup.com +platform-cn.com +platform.dell.com +platinum-traveller.com +platinumchina.com +play-analytics.com +play-cdn10.com +play-cdn11.com +play-cdn13.com +play-cdn14.com +play-cdn16.com +play-cdn19.com +play-cdn2.com +play-cdn20.com +play-cdn7.com +play.craft.moe +play.jinnantv.top +play.scrstv.com +play.sngdxsn.com +play68.com +play700.com +play910.com +play920.com +playbattleaces.com +playcase.com +playchd.com +playcomet.jp +playcool.com +playcrab.com +playdanji.com +playdisorder.com +player.200877926.top +playerinfinite.com +playezu.com +playfifa.com +playgm.cc +playhousemag.com +playlu.com +playorcas.com +playpangu.com +playtai.com +playtai.net +playwonderful.com +playwxgame.com +playyx.com +playzy.com +plb1.com +plbig.com +plc100.com +plc11.com +plcent.com +plchinese.com +plcjs.com +plcloud.com +plctlab.com +plentypolymer.com +pleo-securelogin.com +plesk-cn.com +plex2.com +plexpt.com +plfrog.com +plll-fluid.com +plob.org +plopco.com +plottersyservicioshdz.com +plpwz.com +plsbd.com +plsdeyy.com +plsfybjy.com +pltgd.com +pluosi.com +pluralitycn.com +plures.net +plus-chem.com +plus-space.com +plus3gallery.com +plusco-tech.com +plusgantt.com +plusplus7.com +plusplustu.com +plusrtc.com +plutoer.com +plutuspay.com +pluveto.com +plvideo.net +plxao.com +plxfgroup.com +plxww.com +plycd.com +plyh.com +plyhjt.net +plyygs.com +plyz.net +plzly.com +plzx.net +plzyll.com +pm-china.com +pm-leader.com +pm-summit.org +pm222.com +pm25.com +pm265.com +pm28.com +pm360.com +pmallstore.com +pmcaff.com +pmceo.com +pmcj-group.com +pmcrobot.com +pmd5.com +pmdak.com +pmdaniu.com +pmdled.com +pmdoudou.com +pmdown.com +pmhfd.org +pmichina.org +pmish-tech.com +pmkiki.com +pmovie.com +pmparkchina.com +pmph.com +pmphai.com +pmphmooc.com +pmptuan.com +pmquanzi.com +pmr66.com +pmsmzyy.com +pmtalk.club +pmtemple.com +pmtown.com +pmway.com +pmx-nanho.com +pmxprecision.com +pmxsd.com +pmyes.com +pmyuanxing.com +pn1waq.com +pnas.org +pnetp.org +pnfang.com +pnfq.com +png.pub +pngbag.com +pngsucai.com +pniao.com +pnol.net +pnst8.com +pntagkyy.com +pntkyy.com +pntryy.com +pnty1688.com +pnwww.com +pnxct.com +pnxyrykj.com +pnzpw.com +po.co +po7ryumvkx34.com +poacefex.shop +pobaby.net +pobasoft.com +pochanguanliyanjiu.com +pochezu.com +pocketcloud.vip +pocketdigi.com +pocketuni.net +pockpower.com +pocomagnetic.com +pocosite.com +pocsuite.org +podcast.xyz +podfest.tech +podinns.com +podjiasu.org +podunjiasu.com +poem88.com +poemlife.com +poemschina.com +pohaier.com +pohover.com +poikm.com +point-memory.com +poiuytw.com +poizon.com +poj.org +pojianyunfu.com +poke203.com +pokemmc.com +pokemon-unitepgame.com +pokemon.vip +pokerbros.net +pokercup.net +pokermate.net +poketb.com +polamus.com +polariton.life +polarloco.com +polars.cc +polarxiong.com +polaxiong.com +polayoutu.com +polebrief.com +polingba.com +polo-king.com +poloxue.com +poluosenko.com +poly-gx.com +poly-pm.com +polycd.com +polycent.com +polycinemas.com +polycn.com +polycom-jl.com +polyflowenergy.com +polyhotel.com +polyhotels.com +polyinno.com +polyreymed.com +polytheatre.com +polyv.net +polywuye.com +polyxfb.com +pomears.com +pomeloyun.com +pomoho.com +pondernext.com +ponging.store +ponkong.com +ponley.com +pontite.com +pony.ai +ponyai-cn.com +ponycool.com +ponyemu.com +ponyfk.com +ponytest.com +ponytestqd.com +ponytestsh.com +ponytestsz.com +poo1.club +pooban.com +pooeoo.com +poofoo.com +pooioo.com +pook.com +pookcdn.com +pooketools.com +poorren.com +pop-bags.com +pop-fashion.com +pop-shoe.com +pop136.com +pop365.com +popcj.com +popcustoms.com +popdg.com +popgo.org +popincdn.com +popkart.tv +popkx.com +poploli.com +popmart.com +popmartfans.cc +popmtstyle.com +popoffices.com +popoho.com +popoim.com +popovivi.com +popoxiu.com +popqiu.com +popsoft.com +popss.biz +popumed.com +popupgrade.com +poputar.com +popziti.com +poration-vac-tech.com +porlockz.com +port-m.com +portalcdn.cdnetworks.com +portcontainer.com +porthebei.com +portjs.com +portjs.net +portjswl.com +portlyg.com +portmansevenstars.com +ports-intl.com +portsgmt.com +porttong.com +portugal-visacenter.com +poru-mro.com +poryf.com +pos58.com +pos580.com +posbar.com +poscerwatch.com +poseidong.com +poseidonqianshui.com +posfree.com +posge.com +posmcc.com +posn.net +pospalit.com +pospos.com +post-delivered.today +post163.com +post183.net +postarlight.com +postdelivered.today +posterlabs.com +postgres.fun +postgresqlchina.com +postjson.com +postnord.xin +postpony.com +postxin.com +posyn.com +poszjia.com +potalapalace.com +potassiumnitrate-zx.com +potato.gold +potensic.com +potevio.com +pothros.asia +potianji.net +potnsik-faastink898.com +potomaccottage.com +potops.com +potplayer.org +potplayercn.com +pouchcontainer.io +pouquiagievu.com +pouser.net +pova-elc.com +power-rail.com +power-sprayer.com +power86.com +power8t.com +powerapp.io +powerbeijing-ec.com +powerbeijing.com +powerbibbs.com +powercdn.com +powerchina-intl.com +powerchinaleasing.com +powerchinanewenergy.com +powerchinashow.com +powerchinayun.com +powerde.com +powereasy.net +powerex1.com +powerflow-tech.com +powerfulchina.com +powerhubei.com +poweric-china.com +powerlandtech.com +powerlaw.ai +powerleaderidc.com +powerliber.com +powerlong.com +powerlongmuseum.com +powerma.net +powermaxcorp.com +poweron.cc +powerpigs.net +powerpms.com +powerrsoft.com +powerskystudio.com +powerstationofart.com +powerstonetech.com +powertensors.ai +powertradepro.com +powervision.me +powerworldgd.com +powerxene.com +powpegxw.com +powzamedia.com +poxiaowy.com +poxiaoxinxi.com +poyour.com +pozou.com +pp.cc +pp100.com +pp1o.com +pp25.com +pp250.com +pp30.com +pp365.com +pp373.com +pp51.com +pp540.com +pp63.com +pp918.com +pp9l.com +ppad.com +ppaiss.com +ppbizon.com +ppbnchina.com +ppcho.com +ppcn.net +ppcode.com +ppcost.com +ppcwzebv.com +ppdai.com +ppdaicdn.com +ppdaicorp.com +ppdd.com +ppdesk.com +ppdqk.com +ppduck.com +ppdys.vip +ppfeng.com +ppforging.com +ppgallery.com +ppgame.com +ppgg.in +ppgmm.com +ppgslb.com +pphimalayanrt.com +ppia-china.com +ppinfra.com +ppio.cloud +ppio.work +ppj.io +ppjtc.net +ppkankan01.com +ppkjinc.com +ppkoo.com +pplib.net +pplive.com +pplive.net +pplm1996.com +pplp.info +ppm-htv.com +ppm2.com +ppmake.com +ppmm.org +ppmoney.com +ppnews.vip +ppos.com +ppp.gold +ppparking.net +pppcar.com +pppet.net +pppie.com +pppiii.com +pppnnm.com +pppoevps.com +ppppic.com +ppppoints.com +ppq.me +pprxcdn.com +pps.tv +ppsao.com +ppsimg.com +ppsoftw.com +ppspain.com +ppsport.com +ppstream.com +ppstream.net +ppstv.com +ppstv.net +ppsurl.com +ppsz.net +ppt118.com +ppt20.com +ppt360.com +ppt920.com +pptair.com +pptbest.com +pptboss.com +pptbz.com +pptelf.com +ppter8.com +ppthi-hoo.com +pptianliao.com +pptiyu.com +pptkj.net +pptmall.net +pptniu.com +pptsq.com +pptstore.net +pptsupermarket.com +pptui.com +pptutor.com +pptv.com +pptv5.com +pptvdata.com +pptvimg.com +pptvnet.com +pptvyun.com +pptxy.com +ppurl.com +ppvi.net +ppwan.com +ppwang.com +ppwenda.com +ppwfa.com +ppwow.cc +ppwwyyxx.com +ppx520.com +ppxclub.com +ppxiaoshuowang.com +ppximg.com +ppxm.com +ppxmw.com +ppxs.net +ppxstatic.com +ppxsw.co +ppxvod.com +ppxwo.com +ppzhan.com +ppzhilian.com +ppzuche.com +ppzw.com +pqdtcn.com +pqneq.com +pqpo.me +pqt-bearing.com +pqtygsfkv.com +pqyhigh.com +pqylow.com +pqymiddle.com +pqyvzr56aceitx.com +pqzhichan.com +pr020.com +pr027.com +pr0771.com +pr1bg.com +pradabao.com +pratic-cnc.com +prayaya.com +prayaya.net +prayaya.org +prcedu.com +prcee.org +prcfe.com +prcvalve.com +precision-biotech.com +precision-biz.com +preludeid.com +premedglobal.com +presenceall.com +pressmine.com +prestodb-china.com +prestolite-bj.com +prettech.com +preyp.net +prfc-cn.com +prfog.com +prhljt.com +pricl.com +primadiagnostic.com +primarychina.com +prime-care.com +prime-semi.com +prime3c.com +primegene.net +primerachina.com +primeton.com +princechem.com +print86.com +printerwhy.net +printhome.com +printhr.com +printidea.art +printlake.com +privateapi.xyz +privatehd.to +privatess.win +privspace.net +prizesapp.com +prjdrj.com +prkfyy.com +prnewspress.com +pro001.com +pro400.com +proangela.com +proav-china.com +procar.cc +processedmetals.com +processon.com +procetpoeinjector.com +prochembio.com +prociss.com +procivi.net +prod-controlbe.floonet.goog +prod-databe.floonet.goog +prod.databe.floonet.goog +prodcam.cc +prodcutmodel.com +productcard.gog-statics.com +productivity.wiki +proginn.com +programfan.com +programmer.ink +programmercarl.com +programschool.com +progress-cn.com +progressingeography.com +project-oa.com +project-snow.com +project.ai +projectaker.com +projector-jl.com +projector-window.com +projectserval.com +proleantech.com +prolog-int.com +prolto.com +promise-sz.com +promisingedu.com +pronax.tech +pronetway.com +prophecyi.com +proposalt.com +proquest.com +proresearch.org +pros-view.com +prositsole.com +prostar-cn.com +protect-file.com +protong.com +protontechcn.com +proup.club +providence-chemicals.com +prowine-shanghai.com +proximabeta.com +proxypass.net +proya-group.com +proya.com +proyy.com +prpracg.com +prs-9hospital.com +prs-motion.com +prsgl.com +prteco.com +prts.wiki +prtscttposty.cfd +prttech.com +prvchina.com +prwlyy.com +prxxff.com +pryk0755.com +przhushou.com +przwt.com +ps-boat.com +ps123.net +ps12345.com +ps173.com +ps288.com +ps314.com +ps616.com +ps9d.com +psaiwave.com +psald.com +psb888.com +psbc-ubank.com +psbc.com +psc4d.com +pscddos.com +psd1403.com +psd8.com +psdee.com +psdiv.com +pse-meti.com +psfjz.com +psjdhhnkjahbn.cfd +psjia.com +psjxty.com +psjyedu.com +pslkzs.com +psmartcloud.com +psnine.com +psoneart.com +psp99.com +psr-china.com +psrar.com +psrss.com +pstatp.com +pstips.net +pstxg.com +psvalve.com +psy-1.com +psychcn.com +psychspace.com +psylife.com +psysoper.com +psyzg.com +psznh.com +pszwatch.com +pszx.com +pszxw.net +pt-link.com +pt597.com +pt80.net +pt963.com +pt97.com +ptacn.com +ptah-tech.com +ptausercontent.com +ptbchina.com +ptbus.com +ptc-asia.com +ptdsh.com +pterclub.com +ptfdc.com +ptfe-rod.com +ptfish.com +ptfish.org +ptgcn.com +pthceshi.com +pthksw.com +pthxuexi.com +pthxx.com +pthxxw.com +ptimg.org +ptkckj.com +ptkill.com +ptmezkgg.com +ptnrjt.com +ptools.fun +ptorch.com +ptotour.com +ptpcp.com +ptrcw.com +pts-ai-texture.com +pts-testing.com +pts.games +ptshare.org +ptszgh.org +ptteng.com +ptwbs.net +ptweixin.com +ptx123.com +ptxie.com +ptxyrcw.com +ptxz.com +ptyg.com +ptyly.com +ptyoubike.com +ptyqm.com +ptyx.com +pu-bg.com +pu-ling.com +pu1kj.com +pu600.com +pu82.vip +puaas.com +puai999.com +puaihospital.net +puamap.com +pubbcsapp.com +pubchn.com +pubg.plus +pubg8x.com +pubghelper.com +pubgkam.com +pubgtool.com +pubgwesk.art +pubgzh-cn.vip +publiccms.com +publicdns.cc +pubmed007.com +pubmedplus.com +pubone.cc +pubtian.com +pubukeji.com +pubwinol.com +pubyun.com +pubyun.net +pubyun.org +pucijiankang.com +pudding.cc +pudetouzi.com +pudie.net +pudijt.com +pudn.com +pudongwater.com +pudutech.com +puduzhai.com +puem.org +puer10000.com +puercn.com +puersai.com +puertea.com +pufalianzheng.com +pufewev.store +puffergames.com +pugba.com +puh3.com +puhebiopharma.com +puhedesign.com +puhja.work +puhler.com +puhuacapital.com +puhuahui.com +puhuaxincai.com +puidc.com +puiedu.com +puikiuxinyi.com +pujia8.com +pujiaba.com +pujiaziwang.com +pujie.com +pujingjt888.com +pujiugame.com +pukinte.com +pule.com +pulinmed.com +pulisi.com +pulixingfu.com +pullwave.com +pullword.com +pullywood.com +pulogroup.com +pumcderm.net +pumpisok.com +pumpzc.com +punaide.com +punanhospital.com +punchbox.info +pungboo.com +puoke.com +puoraiatorcubt.icu +puppetchina.com +puppy888.com +pupu168.com +pupuapi.com +pupufz.com +pupugo.com +pupumall.com +pupumall.net +pupurazzi.com +pupuwang.com +purang.com +purcotton.com +pureage.info +purebuy.club +pureh2b.com +purekindfund.com +puremild.com +purenyy.com +puresnake.com +puresys.net +purewhite.io +purified-group.com +puritysilvers.store +purolatorko.com +puronglong.com +purplehi.com +purplelec.com +purui020.com +puruimachinery.com +pusa123.com +pusa365.com +push-herbchem.com +push2u.com +pushgrid.net +pushi-ngp.com +pushigao.com +pushihao.com +pushiyb.com +pushjoy.com +pushplus.plus +pushthink.com +pushtime.net +pushyzheng.com +pusicapital.com +pusupvc.com +putaoa.com +putaocdn.com +putaogame.com +putaojiu.com +putaotec.com +putclub.com +putdb.com +putdl.com +putian-nst.com +putian508.com +putitt.com +putonsoft.com +putop.net +puusa.net +puwenlong.com +puworld.com +puwww.com +puxiang.com +puxindesign.com +puxun.co +puyewx.com +puyideshiye.com +puyimed.com +puyuan-electric.com +puzeyf.com +puzzle8.com +puzzles100.com +pv001.com +pv001.net +pv138.com +pv265.com +pvacegurmbz3e.com +pvc-diban.net +pvc123.com +pvpin.com +pvzbaike.com +pw-partners.com +pw1999.com +pw88.com +pwand.com +pwdding.icu +pwithe.com +pwjptdg.xyz +pwjt.com +pwkss.com +pwkyyb.com +pwmat.com +pwmqr.com +pwns.fun +pwnyun.com +pword.net +pwrd.com +pwrdoverseagame.com +pwrdoverseas.com +pwsannong.com +pwsz.com +pwypx.com +pwypyq.com +px0571.com +px0769.com +px1039.com +px33.com +px5a.com +pxb7.com +pxbgp.com +pxc33.com +pxcn168.com +pxcoex.com +pxdier.net +pxemba.com +pxrczpw.com +pxsfybjy.com +pxsrmyy.com +pxtbhb.com +pxtcm.com +pxtu.com +pxtx.com +pxtzirma.com +pxuiamz.com +pxvps.com +pxwsemi.com +pxx.io +pxykyy.com +pxyuan.com +pxyyjt.com +pxzhbsq.com +pxzj.com +py-axa.com +py1080p.com +py1314.com +py168.com +py2y.com +py3.io +py3study.com +py94.com +pyadx.com +pyasfunds.com +pybrother.com +pychina.com +pychina.org +pydp888.com +pydvu.com +pyedu.cc +pyeec.com +pyer.net +pyer.site +pyfb001.com +pyhead.com +pyhosp.com +pyjdgj.com +pyjkd.com +pyjt.net +pyker.com +pylonghai.com +pymeng.com +pymh.com +pyneo.com +pyou.com +pyral07m8m.com +pysdsysc.com +pyshszh.com +pystar.com +pyt2021.com +pytesgroup.com +python-abc.xyz +python100.com +python51.com +pythonclub.org +pythoner.com +pythonheidong.com +pythonke.com +pythonlion.com +pythonthree.com +pythontip.com +pytk.net +pytool.com +pytorchtutorial.com +pywangqi.com +pyxhh.work +pyxjiang.com +pyxk.com +pyxrc.com +pyxwapp.com +pyxww.com +pyycz.com +pyynsm.com +pyzhbc.com +pyzls.com +pyzwy.com +pz028.com +pz6.com +pzboy.com +pzcgw.com +pzdf.com +pzds.com +pzfc.com +pzfcw.com +pzhccb.com +pzhdahe.com +pzhedu.com +pzhl.net +pzhol.com +pzhqx.com +pzhqz.com +pzhr.com +pzhwater.com +pzhwyw.com +pzjdimg.com +pzjiadian.com +pzlink.com +pzmls.com +pznews.com +pznrfsy.com +pznsh.com +pzoom.com +pzpu.com +pzrex.com +pzzc.net +pzzx.com +q-alumni.com +q-bakery.com +q-dazzle.com +q-parking.com +q-supreme.com +q.biz +q047.com +q1.com +q1cm.com +q2ak.com +q2cdn.com +q2d.com +q2zy.com +q36f.icu +q38519je8o.world +q49d4486xg.com +q4yvu50kh2.com +q5.com +q66x11b6c2wfg57.sbs +q6c.com +q6haqi.com +q6u.com +q77777777.com +q78s5.com +q7kyzxq4nj.com +q88b.net +q88c.net +q89850n302.com +q96bq8m39p.world +qa114.com +qacctv.com +qacn.net +qae3orq9we9t7.com +qaeczbxr.com +qafone.cc +qagpublic.qatp1.net +qakkan.vip +qalex.com +qamemc.com +qapi.cc +qaqa555.com +qaros.com +qast.com +qaxanyu.com +qaxanyuv6.com +qaxcloudwaf.com +qaxwzws.com +qaynak.com +qazasd.com +qazdsa.com +qazso.com +qaztool.com +qazwobdu.com +qazxsdc.com +qbangmang.com +qbao.cc +qbaobei.com +qbb6.com +qbboss.com +qbd888.com +qbewux.xyz +qbfnp.com +qbgxl.com +qbide.com +qbihui.com +qbiqu.com +qbitai.com +qbj.cc +qbjrxs.com +qbjwater.com +qbox.me +qbox.net +qbtxt.net +qbtzjt.com +qbview.com +qbxz.com +qc-hr.com +qc-shanghaipathology.com +qc101.com +qc188.com +qc6.com +qc99.com +qca.org +qcaipiao.com +qcbaas.com +qcbone.com +qcc.com +qcc.qualcomm.com +qccip.com +qcckyc.com +qccost.com +qccr.com +qccrm.com +qcdne.com +qcdnlog.com +qcdntest.com +qcdntest.net +qcds.com +qcdy.com +qcdyj.com +qcenglish.com +qcers.com +qcers.net +qcgm.net +qcgq168.com +qchcm.com +qches.com +qchouses.com +qchsym.com +qchxt.com +qckuaizhi.com +qclc.com +qclivecdn.com +qcloud-edumall.com +qcloud.com +qcloud.la +qcloudapps.com +qcloudcdn.com +qcloudcdnsrc.com +qcloudcjgj.com +qcloudclass.com +qcloudcos.com +qcloudcos.net +qcloudecdn.com +qclouder.com +qcloudestate.com +qcloudgme.com +qcloudgslb.com +qcloudimg.com +qcloudipv6.com +qcloudmail.com +qcloudmarket.com +qcloudns.com +qcloudocdn.com +qcloudoceanus.com +qcloudsmartiot.com +qcloudtcic.com +qcloudteo.com +qcloudtiw.com +qcloudtrip.com +qcloudtt.com +qcloudwaf.com +qcloudwzgj.com +qcloudzygj.com +qcly.love +qcly.xyz +qcmgkids.com +qcmod.xyz +qcmoe.com +qcmrjx.com +qcmuzhi.com +qcoco.com +qconbeijing.com +qconshanghai.com +qcplay.com +qcq3.com +qcql.com +qcr.cc +qcrencai.com +qcrlvip.com +qcrqll.com +qcsh8.net +qcsj.com +qcstudy.com +qct100.com +qctm.com +qctsw.com +qctx88.com +qcvbs1296.com +qcwan.com +qcwh2021.com +qcwhxx.com +qcwlseo.com +qcwp.com +qcwxjs.com +qcxrby.com +qcxs.com +qcxzls.com +qcy.com +qcymall.com +qcyoung.com +qcyuns.com +qczb.app +qd-dy.com +qd-metro.com +qd-mls.com +qd-weimob.com +qd.ink +qd0513.com +qd256.com +qd5itt.com +qd8.com +qd8kbq0.shop +qdac.cc +qdaeon.com +qdaiia.com +qdaily.com +qdairlines.com +qdairport.com +qdauction.com +qdbdsk.com +qdbhuh.com +qdbocweb.com +qdby.com +qdcaijing.com +qdcars.com +qdccb.com +qdccdl.com +qdcloudsolution.com +qdcu.com +qdcykg.com +qdcz.com +qdd.gd +qdd.gg +qdd.la +qdd2223338a2.shop +qdd2223338a9.shop +qddfxfpx.com +qddlchb.com +qddown.com +qddsjx.com +qddsta.com +qdeastsea.net +qdedu.net +qderzhong.net +qdexam.com +qdezc.work +qdfik.com +qdfnscy.com +qdfuer.com +qdfuns.com +qdgaoshanyun.com +qdgjj.com +qdgw.com +qdgxjt.com +qdgxqrc.com +qdhantang.com +qdhengyong.com +qdhetian.net +qdhkhospital.com +qdhmsoft.com +qdhongyunxing.com +qdhonmon.com +qdhr.net +qdhsty.com +qdhualing.com +qdhuaren.com +qdhw.com +qdhwjs.com +qdingnet.com +qdipc.com +qdjimo.com +qdjingchengyiqi.com +qdjjwsjf.com +qdjttzjt.com +qdjunyi.com +qdjxhz.com +qdjyjtdzsw.com +qdkefu.com +qdkelinde.com +qdkingst.com +qdkmjc.com +qdkpdy.com +qdlanrun.com +qdlcl.com +qdlib.net +qdliding.com +qdlinghaiba.com +qdlives.com +qdliye.com +qdlongre.com +qdlpay.com +qdlups.com +qdlyxx.com +qdmama.net +qdmcxh.com +qdmm.com +qdmswx.com +qdnsyh.com +qdnxsyy.com +qdnzrmyy.com +qdpdjx.com +qdport.com +qdpr.com +qdqiche.com +qdqihang.com +qdqs.com +qdrcsc.com +qdreads.com +qdsay.com +qdsbx.com +qdsdeyljt.com +qdsdyjt.com +qdshebao.com +qdshoufei.com +qdshuiche.com +qdslcs.com +qdsmjxh.com +qdspr.com +qdsrmyy.com +qdsxtkj.com +qdsysj.com +qdsyxh.com +qdtaide.com +qdtech.ai +qdtgood.com +qdthgs.com +qdtianxintai.com +qdtrrh.com +qdtxdzgc.com +qduhwq.com +qdurl.cc +qdwebim.com +qdwenxue.com +qdwpa.com +qdwxnet.com +qdxfgy.com +qdxgn.com +qdxgysy.com +qdxhd.com +qdxhs.vip +qdxtcw.com +qdycdx.com +qdyijiamei.com +qdyiyi.com +qdyuzhengtang.com +qdyxbyy.com +qdyztang.com +qdzhengkang.com +qdzhv.com +qdzkmj.com +qdzls.com +qdznjt.com +qdzx.net +qdzxyy.com +qdzz.com +qe32.com +qebk.com +qechu.com +qeebike.com +qeecc.com +qeejoo.com +qeeka.com +qeeniao.com +qeerd.com +qefee.com +qegcdn.com +qeoacc.com +qeoacc.net +qeoagphm.com +qeodns.com +qeodns.net +qeopzvgm.com +qeqnet.com +qera.online +qerwsoft.com +qeteshcn.com +qeto.com +qetoken.com +qeyopxb.com +qeyrhhy.com +qf-meter.com +qfang.com +qfangimg.com +qfbcs.com +qfbio.com +qfbwcd.xyz +qfcgroup.com +qfclo.com +qfdeng.com +qfdengn.com +qfedu.com +qfeiche.com +qfiee.com +qfihdr.com +qfns1.com +qfpay.com +qfpq.com +qfrost.com +qfrxyl.com +qfsh.com +qfsyj.com +qftimg.com +qftouch.com +qfull.com +qfun.com +qfvip.net +qfwl.com +qfxcha.com +qg.net +qg108.com +qg3oed7882.com +qgadmin.qcpp1.net +qgb2b.com +qgbnzb.com +qgbzyzl.com +qgcyjq.org +qgenius.com +qgfund.com +qgggxxw.com +qggj.com +qggzszk.org +qgjzsc.com +qgkjacc.com +qgnvbc.com +qgodb.com +qgpx.com +qgqc.shop +qgqy.com +qgren.com +qgswvza.com +qgsydw.com +qgtql.com +qgtsvvm1278.vip +qgvps.com +qgwzjs.com +qgxl.org +qgyksr.com +qgyqshz.com +qgysj.org +qgyyzs.net +qgzb.net +qgzxx.com +qgzzz.com +qh-cdn.com +qh-dl.com +qh-hospital.org +qh-lb.com +qh.com +qh24.com +qh4321.com +qh6bc.com +qh9y.com +qhangyun.com +qhass.org +qhball.com +qhbtv.com +qhcby.com +qhcdn-lb.com +qhcdn.com +qhch520.com +qhchcb.com +qhclass.com +qhcro.com +qhcswhh.com +qhcuvj3143.vip +qhd-marathon.com +qhd.net +qhdast.com +qhdatongnews.com +qhdcm.com +qhderwei.com +qhdgjj.com +qhdglc.com +qhdjgyy.com +qhdlcdn.com +qhdnews.com +qhdnxgyy.com +qhdren.com +qhduhu.com +qhdvtc.com +qhdxgps.com +qhdxw.com +qhdzyy.com +qhea.com +qhee-ma.com +qhee.com +qhfx.net +qhfzcp.com +qhgas.com +qhgufen.com +qhgwh.com +qhholding.com +qhhxnw.com +qhimg.com +qhimgs.com +qhimgs0.com +qhimgs1.com +qhimgs2.com +qhimgs3.com +qhimgs4.com +qhimgs5.com +qhimgs6.com +qhimi.com +qhjyks.com +qhkyfund.com +qhlhfund.com +qhlingwang.com +qhlyou.com +qhm123.com +qhmed.com +qhmgf.com +qhmsg.com +qhnews.com +qhong.net +qhpcc.com +qhpta.com +qhrch.com +qhrcsc.com +qhres.com +qhres2.com +qhrqxh.com +qhsat.com +qhsdzs.com +qhsetup.com +qhsklw.com +qhsrmyy.com +qhssyy.com +qhstatic.com +qhsxf.net +qhtdow.help +qhtf-china.com +qhtibetan.com +qhtui.com +qhtycp.com +qhtysz.com +qhtyzx.com +qhuah.com +qhwmw.com +qhwptyn.com +qhwww.com +qhxcjt.com +qhxzlsgs.com +qhyccd.com +qhyh.com +qhyhq.com +qhyimin.com +qhylns.com +qhysjt.com +qhytyyvx.com +qhyzzzs.com +qhzpw.com +qi-auto.com +qi-che.com +qi-ju.com +qi-wen.com +qi10.com +qi18.com +qi58.com +qiaijt.com +qiaiju.com +qiaiou.com +qiak.com +qialol.com +qian-gua.com +qian-lai.com +qian.lu +qianaolawyer.com +qianbao.com +qianbaocard.com +qianbaogroup.com +qianbaohr.com +qianbeibei.shop +qianbi360.com +qianbianapi.com +qianbianma.com +qianbianxiazai.com +qiancangwms.com +qiancha.cc +qianchenglvdong.com +qianchengrh.com +qianchengriben.com +qianchiyun.com +qiancipai.com +qiandai.com +qiandao.com +qiandaoapp.com +qiandaoapp.net +qiandaocdn.com +qiandaohu.cc +qiandaqian.com +qiandaren.com +qiandd.com +qiandeups.com +qianduan.com +qianduanheidong.com +qiandunvpn.com +qianfan.app +qianfan.tv +qianfan123.com +qianfan365.com +qianfanwanmu.com +qianfanyun.com +qianfeng.com +qiang100.com +qiangbus.com +qiangchezu.com +qiangchuan.com +qiangfu.xyz +qianggen.com +qianggen.net +qianggou5.com +qiangjin.org +qiangka.com +qianglihuifu.com +qiangmi.com +qiangqiang5.com +qiangren.com +qiangsenhg.com +qiangshengyanhua.com +qiangumeitan.com +qiangungun.com +qianguyihao.com +qiangyingjituan.com +qiangyinli.com +qianhai12315.com +qianhaiaiaitie.com +qianhaibs.com +qianhaipower.com +qianhong.com +qianhuajie.com +qianhuanhulian.com +qianhuaweb.com +qianinfo.com +qianjia.com +qianjianggas.com +qianjiangwang.com +qianjiapp.com +qianjiawen.net +qianjiayue.com +qianjing.com +qianjingdesign.com +qianjingkeji.com +qianju.org +qianka.com +qiankoo.com +qiankun6.com +qiankungroup.com +qiankunshopping.com +qiankunxin.com +qianlai778.com +qianlaiye.com +qianlht.com +qianliao.net +qianliao.tv +qianliaowang.com +qianliht.com +qianliii.com +qianlima.com +qianlimafile.com +qianlimazb.com +qianling.pw +qianlinkj.com +qianlong.com +qianluxiaoshuo.com +qianmaiapp.com +qianmaidao.com +qianmi.com +qianmingyun.com +qianmiyun.com +qianmoqi.com +qianmoufirm.com +qianmu.org +qiannahotel.com +qianniu.com +qianp.com +qianpailive.com +qianpen.com +qianpin.com +qianping.work +qianqi.net +qianqian.com +qianqiankeji.xyz +qianqiantao.com +qianrengang.com +qianrenge.com +qianrihong.net +qianrong.me +qianselight.com +qianshanren.com +qianshengqian.com +qianshuixing.com +qiansiw.com +qiant.net +qiantangke.com +qiantianchayuan.com +qiantucdn.com +qianuni.com +qianvisa.com +qianwa.com +qianwanku.com +qianwen.com +qianxiangbank.com +qianxibj.net +qianximiye.com +qianxin.com +qianxincdn.com +qianxinet.com +qianxingniwo.com +qianxingwl.com +qianxs.com +qianxuecloud.com +qianxuew.com +qianxueyunke.com +qianxun.com +qianxunclub.com +qianxungroup.com +qianxuntrip.com +qianyan.biz +qianyan001.com +qianye88.com +qianyierp.com +qianyikeji.com +qianyinedu.com +qianyingzhi.com +qianyuangx.com +qianyuewenhua.xyz +qianyuncare.com +qianyuwang.com +qianzhan.com +qianzhan123.com +qianzhanhl.com +qianzhengbanliliucheng.com +qianzhengdaiban.com +qianzhou.shop +qianzhu8.com +qianzhuvisa.com +qiao-cn.com +qiao88.com +qiaobo.net +qiaobocnc.com +qiaobuqiao.com +qiaobutang.com +qiaoclouds.com +qiaodan.com +qiaofangyun.com +qiaofanxin.com +qiaoh.com +qiaohewei.cc +qiaohu.com +qiaohuapp.com +qiaohumall.com +qiaoji8.com +qiaojiamuxian.com +qiaojiang.tv +qiaolianyimin.com +qiaolishuiwu.com +qiaomaren.com +qiaomi.com +qiaomu.ai +qiaomukeji.com +qiaoqiaoyun.com +qiaoshang.org +qiaoshisui.com +qiaoshoujituan.com +qiaosidea.com +qiaotu.com +qiaoxuanhong.com +qiaoxuesi.com +qiaoyi.org +qiaoyinkg.com +qiaoyue66.com +qiaozhuangjia.com +qiaozuji.com +qiaqa.com +qiaqiafood.com +qiawei.com +qibali.com +qibaodwight.org +qibazaixian.com +qibingdaojia.com +qibingwang.com +qibo168.com +qiboleqipai.com +qibosoft.com +qibox.com +qibuge.com +qibuluo.com +qicaispace.com +qicaizulinwang.com +qichacha.co +qichacha.com +qichacha.net +qichamao.com +qichang56.com +qichangqing.com +qichangv.com +qichecailiao.com +qichechaoren.com +qichedaquan.com +qicheedu.com +qichegeyin.com +qichehot.com +qichejingwei.com +qichelian.com +qicheliliang.com +qichemen.com +qichemoxing.net +qichengplus.com +qichepeijian.com +qichepinpai.com +qicheq.com +qichequan.net +qichetansuo.com +qichetong.com +qichexl.com +qichezhan.net +qichuang.com +qichunfdc.com +qichunzp.com +qicolor.com +qicp.net +qicp.vip +qictools.com +qida100.com +qidaile.com +qideshuiwu.com +qideyun.com +qidi-edu.com +qidian-cos-backup.com +qidian-cos.com +qidian.com +qidian688.com +qidianbox.com +qidianjob.com +qidianla.com +qidianmm.com +qidianpw.com +qidiantu.com +qidic.com +qidisheng.com +qidiwang.com +qidong.name +qidongcha.com +qidongnews.com +qidongyx.com +qidulp.com +qiduo.net +qie.tv +qiecdn.com +qieerxi.com +qiejingsu.com +qiekao.com +qiekj.com +qieman.com +qiepai.com +qieracing.com +qierge.com +qieta.com +qieyike.com +qieying.com +qieyou.com +qiezibenpao.com +qiezic.com +qiezip.com +qifan1.com +qifandianlansh.com +qifangw.com +qifeiy.com +qifeiye.com +qifeizn.com +qifeng-safety.com +qifeng.com +qifenxiao.com +qifu.me +qifub.com +qifuip.com +qigonggate.com +qigongworld.net +qigousoft.com +qiguagua.com +qigumi.com +qiguo.com +qiguoread.com +qihanbio.com +qihangcrrc.com +qihangw.com +qihaoip.com +qihaxiaoshuo.com +qihejy.com +qihepaimai.com +qihihi.com +qihoo.com +qihoo.net +qihu-lb.com +qihu.com +qihu.org +qihuaa.xyz +qihuangpuji.com +qihuangshuyuan.com +qihuangzhishu.com +qihuapi.com +qihucdn.com +qihuiai.com +qihuiwang.com +qihuorumen.com +qii404.me +qiieer.net +qiigame.com +qiivoo.com +qijedu.com +qijee.com +qijiadianzi.com +qijian99.com +qijianzs.com +qijiapay.com +qijiayoudao.net +qijilvxing.com +qijishow.com +qijishu.com +qijiyun.vip +qijizuopin.com +qijuan.com +qijucn.com +qikan.com +qikanchina.com +qikanmulu.com +qikanvip.com +qikanw.com +qike-cloud.com +qikegu.com +qikekeji.com +qikoo.com +qikouu.com +qikqiak.com +qiku.com +qikuaibao.com +qikucdn.com +qikula.com +qilaijian.com +qilang.net +qilanxiaozhu.co +qilanxiaozhu.net +qilanxiaozhu.vip +qilaoshicaishui.com +qilecms.com +qiliangjia.com +qiliaokj.com +qilindao.com +qiling.org +qilinnet.com +qilinshuixiang.com +qilinxuan.net +qilinyiqi88.com +qilitech.ltd +qiliuxs.com +qilong.com +qilongtan.com +qilongyoule.com +qilu-pharma.com +qiluce.com +qiludb.com +qiluhospital.com +qiluhr.com +qilupaint.com +qiluyidian.mobi +qiluyidian.net +qima-inc.com +qimaiz.com +qimao.com +qimi.com +qimiaosenlin.com +qiming.tech +qimingcx.com +qimingjiang.com +qimingpian.com +qimingvc.com +qimingventures.com +qimingxing.com +qimingzi.net +qiminzi.com +qimodesign.com +qimser.com +qimu86.com +qin.io +qinbei.com +qinbing.com +qincai.com +qincaigame.com +qinchacha.com +qinchuan.com +qincj.me +qinco.net +qindaohotel.com +qinde.net +qineasy.com +qinengdongfang.com +qiner520.com +qinfenpharm.com +qing-feng.com +qing-shan.com +qing-tian.com +qing.me +qing.su +qing5.com +qingbh.com +qingcache.com +qingcaige.com +qingcdn.com +qingcheng.com +qingchengfaren.com +qingchenyu.com +qingchunbank.com +qingchunlu.com +qingcigame.com +qingclass.com +qingclasscdn.com +qingcloud.com +qingcongxiaoyuan.com +qingcty.com +qingdan.com +qingdao-port.com +qingdao-port.net +qingdaochina.org +qingdaogxt.com +qingdaokohap.com +qingdaolawyer.org +qingdaomaidige.com +qingdaomedia.com +qingdaomeixie.com +qingdaomuseum.com +qingdaonengyuan.com +qingdaonews.com +qingdaoport.net +qingdaoren.com +qingdaoshenghao.com +qingdelan.com +qingdou.net +qingdou.vip +qingdouw.com +qingf001.com +qingfanqie.com +qingfeichina.com +qingfengchuxing.com +qingfengjiaoyu.com +qingflow.com +qingfo.com +qingful.com +qingfuwu.com +qingfuwucdn.com +qingfuwucdn.net +qingge666.com +qinggl.com +qinggonggroup.com +qingguo.com +qinghaigames.com +qinghaihuaer.com +qinghe-sh.com +qinghe.tv +qinghedaxue.com +qinghua2017.com +qinghuan.com +qinghuaonline.com +qinghuaxuezi.com +qinghuo.net +qingicon.com +qingjiaocloud.com +qingju.com +qingkai.net +qingkan.tw +qingkaoyan.com +qingkeji.com +qingkongfy.xyz +qingkuaipdf.com +qingkuajing.com +qingkuw.com +qinglan.info +qinglanbaseanycast.com +qinglanbaseunicast.com +qinglanji.com +qinglianfood.com +qingliange.com +qingliangkeji.com +qingliaoapp.com +qinglidashi.com +qingliezhiquan.com +qinglin.net +qingline.net +qinglingvip.com +qinglinong.com +qinglm.com +qinglue.com +qinglue.net +qinglvpin.com +qingly.ink +qingmail.com +qingmang.me +qingmang.mobi +qingmayun.com +qingmei.me +qingmh.com +qingmo.com +qingmob.com +qingmucdn.com +qingmuit.com +qingmutec.com +qingmuxinli.com +qingnianlvxing.com +qingniantuzhai.com +qingnianwang.com +qingpanduola.com +qingpin.vip +qingping.co +qingqikeji.com +qingqin.com +qingqingmedia.com +qingqj.com +qingque.co +qingqujie.com +qingquyp.com +qingr.com +qingrenw.com +qingruanit.net +qingruyun.com +qingshanpaper.com +qingshigame.com +qingshou.online +qingshow.net +qingshuo.com +qingshuxuetang.com +qingsongcdn.com +qingsongchou.com +qingsongjituan.com +qingsonngxx.com +qingstor.com +qingstorage.com +qingsucai.com +qingtajiao.com +qingtaoke.com +qingteng-inc.com +qingteng168.com +qingtengzhilian.com +qingtian16265.com +qingtiancms.net +qingting.fm +qingting123.com +qingtingfm.com +qingtingip.com +qingtingjh.com +qingtingtrip.com +qinguanjia.com +qingui123.com +qinguoag.com +qingwabs.com +qingwk.com +qingxianrenminyiyuan.com +qingxiaoyun.com +qingxinjs.com +qingxuetang.com +qingxun.com +qingyantek.com +qingyeyun.com +qingyi.com +qingying.net +qingyuangroup.com +qingyuanshihua.com +qingyun-it.com +qingyun.com +qingyuntrip.com +qingyunzu.com +qingzhanshi.com +qingzhicheng.com +qingzhifeng.com +qingzhiwenku.com +qingzhou.biz +qingzhou.ltd +qingzhou.pro +qingzhou5.com +qingzhouip.com +qinheng.com +qinhuaiziyun.com +qiniu-enterprise.com +qiniu-solutions.com +qiniu.co +qiniu.com +qiniu.in +qiniu.io +qiniu.org +qiniu.us +qiniu.work +qiniuapi.com +qiniuapp.com +qiniublob.com +qiniucc.com +qiniucdn.com +qiniucloud.net +qiniucs.com +qiniudn.com +qiniudns.com +qiniudns.net +qiniudns2.com +qiniug.com +qiniuimg.com +qiniuinc.com +qiniuio.com +qiniukodo.com +qiniup.com +qiniupkg.com +qiniuqcdn.com +qiniurs.com +qiniutek.com +qinla.com +qinlake.com +qinlaobo.com +qinlaoke.net +qinlinad.com +qinlinkeji.com +qinms.com +qinnongbank.com +qinpu.com +qinpuwang.com +qinqiang.org +qinqin.com +qinqin.net +qinqingshipin.com +qinqinxiaobao.com +qinqishuhua.org +qinronmedia.com +qinronread.com +qinrun.com +qins.com +qinshantang.com +qinshihu.com +qinsilk.com +qinsmoon.com +qinsuanbazi.com +qinxiand.com +qinxing.xyz +qinxue.com +qinxue100.com +qinxue365.com +qinxuye.me +qinyangtv.com +qinyuanyang.com +qinyukehuan.com +qinzhe.com +qinzhou.net +qinzhou360.com +qinzhou8.com +qinzhouit.com +qinzibuy.com +qinzidna.com +qionghaif.com +qionghi.com +qiongming.com +qiow.net +qipai.com +qipai007.com +qipaifan.com +qipamaijia.com +qipayuan.com +qipeipu.com +qipeiren.com +qipeiwuyou365.com +qipeng.com +qipinshangji.com +qiqao.com +qiqi2000.com +qiqiboke.com +qiqids.com +qiqilab.com +qiqipu.com +qiqiuyu.com +qiqiuyun.net +qiqjc.com +qiqu.cc +qiquanwl.com +qiquha.com +qiqumaker.com +qiquw.info +qiquwen.com +qiquyou.com +qire123.com +qirebook.com +qiredy.com +qiremanhua.com +qirui.com +qiruikeji2019.com +qisankeji.com +qisaoba.com +qisbook.com +qishenghuo.com +qishengliang.com +qishiruye.com +qishixitong.com +qishu.vip +qishui.com +qishunbao.com +qishuta.info +qishuta.la +qishuta.net +qishuta.org +qisi.co +qisool.com +qita.love +qitaifu.com +qitaijiuye.com +qiti88.com +qitian-tech.com +qitianchina.com +qitianpower.com +qitongxq.com +qituowang.com +qiu-ai.com +qiu630.com +qiuball.com +qiubiaoqing.com +qiufaqf.com +qiufengblog.com +qiuhua.com +qiujieda.com +qiujuer.net +qiujunya.com +qiukuixinxi.com +qiumei100.com +qiumeiapp.com +qiumibao.com +qiumijia.com +qiumiwu.com +qiupuwang.com +qiuqiusd.com +qiuquan.cc +qiushi.com +qiushibaike.com +qiushile.com +qiushu.cc +qiushu.info +qiushubang.com +qiushuzw.com +qiutan.com +qiutianaimeili.com +qiutiangear.com +qiuvps.com +qiuweili.com +qiuwen.wiki +qiuwu.net +qiuxian.com +qiuxiao.com +qiuxietang.com +qiuxue360.com +qiuxueshe.com +qiuyewang.com +qiuyexitong.com +qiuyueli.com +qiuzhang.com +qiuzhijiangtang.com +qiuziti.com +qiwang2025.com +qiwangming.com +qiwei.com +qiwenhui.com +qiwenqi.com +qiwenya.com +qiwiotch.com +qixayrvo.com +qixia.ltd +qixiangwang.com +qixigame.com +qixin.com +qixin007.com +qixin18.com +qixin19.com +qixincha.com +qixing123.com +qixingcr.com +qixingquan.com +qixingtang.com +qixinpro.com +qixintian.com +qixinworks.com +qixiu88.com +qixiushouce.com +qixoo.com +qixuan888.com +qixuny.com +qiye.la +qiye163.com +qiye8848.com +qiyeboao.com +qiyedata.net +qiyegongqiu.com +qiyegongqiu.net +qiyeku.com +qiyelipin.com +qiyenet.net +qiyes.com +qiyeshangpu.com +qiyeshangpu.net +qiyesou.com +qiyetong.com +qiyetoupiao.com +qiyeweixin.com +qiyewenhua.net +qiyeyougou.com +qiyeyouxiang.net +qiyi.com +qiyi.video +qiyikeji.com +qiyimusic.com +qiyipic.com +qiyiw.com +qiyoubangbang.com +qiyouji.com +qiyoujiage.com +qiyoutuo.com +qiyouwang.com +qiyouworld.com +qiytech.com +qiyu-lighting.com +qiyu99.com +qiyuanai.com +qiyuange.com +qiyuanxuetang.net +qiyucloud.com +qiyue.com +qiyuebio.com +qiyuesuo.com +qiyujiasu.com +qiyujoy.com +qiyukf.com +qiyukf.net +qiyuns3.com +qiyuntong.com +qiyunxinfu.com +qiyutech.tech +qiyutianxia.com +qizbov8115.vip +qizheplay.com +qizhidao.com +qizhihaotian.com +qizhong166.com +qizhu.org +qizhu18.com +qizhuyun.com +qizi.cc +qizuang.com +qizubang.com +qj-group.com +qj-robot.com +qj023.com +qj175.com +qj26.com +qj99.net +qjbchina.com +qjbxw.com +qjcode.com +qjcrcgas.com +qjcz.com +qjdchina.com +qjfy.com +qjhlw.com +qjhm.com +qjia.com +qjiajk.com +qjidea.com +qjimage.com +qjis.com +qjjfin.com +qjjmw.com +qjmotor.com +qjnice.com +qjrc.com +qjren.com +qjsalia.com +qjsalib.com +qjsb88.com +qjslngy.com +qjsmartech.com +qjtourism.com +qjwenming.com +qjwh.xyz +qjwhzs.com +qjwjw.com +qjxgold.com +qjystang.com +qjzl.com +qjzyy.com +qk365.com +qkagame.com +qkan.com +qkang.com +qkblh.com +qkcdn.com +qkeke.com +qkhg.com +qking.ink +qkisp.com +qkkj88.com +qkkjd.com +qkl234.com +qknode.com +qknown.com +qktoutiao.com +qkttapp.com +qkua.com +qkvop.com +qkyamkl.com +qkyxzx.com +qkzj.com +ql-cellbank.com +ql-msx.com +ql-spe.com +ql009.com +ql18.mobi +ql1d.com +ql361.com +ql361.shop +qlan99.com +qlbchina.com +qlbk.com +qlchat.com +qldgd.com +qldz.store +qldzj.com +qledu.net +qlelectrons.com +qlhimalayantm.com +qlidc.com +qlife-lab.com +qlinyun.com +qlippie.com +qlivecdn.com +qlivecloud.com +qlivertc.com +qlivertc2.com +qlivewebrtc.com +qlivewebrtc2.com +qll-times.com +qlmec.com +qlmf.com +qlmoney.com +qlnonwoven.com +qlotc.net +qlrc.com +qlrc114.com +qls.fun +qls70.com +qlteacher.com +qluu.com +qlwyjy.com +qlxiaozhan.com +qlxyedu.com +qlxzj.com +qlydw.com +qlyjt.com +qlyygl.com +qlyyqd.com +qlzygs.com +qm.net +qm119.com +qm120.com +qm2009.com +qm41.com +qm69.com +qm989.com +qmacro.com +qmail.com +qmango.com +qmceo.com +qmconfig.com +qmcro.com +qmei.me +qmei.vip +qmeikq.com +qmhd87.com +qmhimalayanpz.com +qmhkids.com +qmht.com +qmht.mobi +qmjianli.com +qmniu.com +qmoji.mobi +qmoji.net +qmqm.net +qmrms.com +qmrobot.com +qmsea.com +qmsjmfb.com +qmtj.net +qmtjgame.com +qmtmedia.com +qmtv.com +qmvchina.com +qmwtp.com +qmwyy.com +qmxny.com +qmxphoto.com +qmxrmt.com +qmxyc.com +qmyc.ltd +qmyq.com +qmyyl.com +qmz5.com +qmz99.com +qmzhibo.com +qmzs.com +qn200.com +qnali.com +qnapcn.com +qnbar.com +qncd.com +qncha.com +qnchrome.com +qndb.net +qnfcdn.com +qnfyg.com +qngas.com +qngcjx.com +qnget.com +qngslb.com +qngygf.com +qnhdkj.com +qnhuifu.com +qnjslm.com +qnjyjt.com +qnl1.com +qnlinking.com +qnlj.com +qnmlgb.tech +qnqcdn.com +qnqcdn.net +qnsdk.com +qnssl.com +qnvipmall.com +qnvipxd.com +qnw.cc +qnydns.com +qnydns.net +qnzrmyy.com +qnzyy.com +qoder.ai +qoder.com +qolai.com +qooboo.com +qoocc.com +qooioo.com +qookar.com +qookkagames.com +qoros.com +qorosauto.com +qosnet.xyz +qosq.com +qouteall.fun +qp108.com +qp110.com +qp46.com +qp49.com +qp666.com +qpaimg.com +qpb187.com +qpdca.com +qpdiy.com +qpgame.com +qpgczx.com +qphospital.com +qpjjku.com +qpjylm.com +qpkaifa.com +qplus.com +qplusstatic.com +qpmwg68cre9pci.com +qpoc.com +qpstar.com +qpwater.com +qpxiaoshuo.com +qpz.com +qpzq.net +qq-xmail.com +qq.cc +qq.cn.com +qq.com +qq.design +qq.do +qq.md +qq.net +qq.travel +qq.zone +qq11999.com +qq123.xin +qq1398.com +qq163.cc +qq163.com +qq163.net +qq190.com +qq190.net +qq260.com +qq3366.net +qq3xkm64kavh.com +qq499.com +qq5.com +qq52o.me +qq5818.com +qq620.com +qq745.com +qq7c.com +qq933.com +qq999q.com +qq9v.com +qqai.net +qqaiqin.com +qqan.com +qqb.pub +qqbiaoqing.com +qqbibile.com +qqbrowser.mobi +qqbytrans.com +qqcdn.com +qqcfw.net +qqcg.com +qqcjw.com +qqclass.com +qqclock.com +qqcnop366.vip +qqcrvpv.com +qqddc.com +qqdiannao.com +qqdiannaoguanjiadl.com +qqdna.com +qqdr.com +qqdzzb.win +qqe2.com +qqeml.com +qqeo.com +qqexmail.net +qqexpert.com +qqfamily.com +qqgameapp.com +qqgamedesign.com +qqgamemall.com +qqgames.com +qqgb.com +qqgd.com +qqgexing.com +qqgexingqianming.com +qqgfw.com +qqgpw.com +qqgx.com +qqgygd.com +qqgyhk.com +qqhangjia.com +qqhaoma.com +qqhaoma.net +qqhbx.com +qqhjy.com +qqhn.net +qqhot.com +qqhrch12333.com +qqhrnews.com +qqhubei.com +qqhwb.com +qqiac.com +qqimage.net +qqimg.net +qqjapan.com +qqje.com +qqjia.com +qqjiyu.com +qqjjsj.com +qqjm.com +qqju.com +qqkj66.com +qqkjj.com +qqkkb.com +qqkrmotors.com +qqku.com +qqkw.com +qqkwsitu.com +qqlivepull.seedata.top +qqmail.com +qqmail.email +qqmapyx.com +qqmc.com +qqmcc.org +qqmda.com +qqmra.com +qqmtc.com +qqmusic.com +qqmusic.store +qqnaozhong.com +qqnn.net +qqopenapp.com +qqor.com +qqpao.com +qqpharm.com +qqpifu.com +qqplusapp.com +qqpuke.org +qqq.tv +qqqiyemail.com +qqqiyeyouxiang.com +qqqmmm.com +qqqv.press +qqrain.com +qqread.com +qqrer.com +qqrizhi.com +qqro.com +qqscb.com +qqservice.mobi +qqsgame.com +qqsgjy.com +qqsgmob.com +qqsgplay.com +qqshidao.com +qqshuoshuo.com +qqsk.com +qqski.com +qqsm.com +qqsort.com +qqspark.com +qqssly.com +qqstudent.com +qqsurvey.net +qqswzx.com +qqt.com +qqteacher.com +qqtest.com +qqtf.com +qqthj.com +qqtjmgg.com +qqtlr.com +qqtool8.com +qqtouxiangzq.com +qqtu8.cc +qqtu8.com +qqtz.com +qquanquan.com +qqumall.com +qqun.com +qqurl.com +qqwangming6.com +qqwebapp.com +qqwewew.com +qqwiki.com +qqwin.xyz +qqwinner.com +qqwjx.com +qqwmba.net +qqwmly.com +qqwwr.com +qqwxmail.com +qqwys.net +qqxmail.com +qqxs.la +qqxsnew.net +qqxsnew5.com +qqxsw.co +qqxx.net +qqxzb-img.com +qqxzb.com +qqy189.com +qqya.com +qqyewu.com +qqymail.com +qqyn.com +qqyouju.com +qqywf.com +qqyy.com +qqzby.net +qqzfw.com +qqzhi.com +qqzi.net +qqzimu.com +qqzimu.net +qqzl.cc +qqzmly.com +qqzshc.com +qqzyw.com +qqzywang.com +qqzzz.net +qr-batch.com +qr25.com +qrcpu.com +qrgiant.com +qrmanhua.com +qrobot.com +qrprt.com +qrtest.com +qrtz.co +qrx.cc +qrzxx.com +qs-jt.net +qs12315.com +qs5.org +qs921.com +qsap-group.com +qsb.browser.miui.srv +qsbank.cc +qsbbs.net +qsbdc.com +qsboy.com +qscharge.com +qschou.com +qsebao.com +qsedu.com +qsedus.com +qseeking.com +qsfcw.com +qsfm.net +qsgx-pt.com +qshang.com +qshealth.com +qsiedu.com +qsiso.com +qsjsjt.com +qsjt.com +qsjxzz.com +qskggf.com +qskj.net +qskretkf.com +qsl.pub +qsmchina.com +qsmis.com +qsmutual.com +qsnctf.com +qsnovel.com +qspfw.com +qspfwadmin.com +qss-lb.com +qssec.com +qstatic.com +qstbg.com +qstcorp.com +qstkizve.com +qstsking.com +qsw.la +qswk.com +qswnet.com +qsxezgai.com +qsxiaoshuo.com +qsxiu.com +qsxuke.com +qsxzls.com +qsyfunds.com +qsyy.net +qszs.com +qszt.com +qszt.net +qt-edu.com +qt.com +qt119.com +qt56yun.com +qt6.com +qt86.com +qtaeixd.com +qtav.org +qtbig.com +qtbtp.com +qtcb.net +qtccolor.com +qtck.net +qtcn.org +qtctc.org +qtdebug.com +qtdream.com +qtedu.net +qteng.net +qter.org +qtest8.com +qtgz.cc +qth8.com +qthinker.net +qtke.com +qtkj.love +qtlcdn.com +qtlcdn.net +qtlcdn360.info +qtlcdn360.top +qtlcdn360.xin +qtlcdn360.xyz +qtlcdncn.info +qtlcn.com +qtlcname.com +qtlglb.com +qtlglb.info +qtlgslbcn.com +qtlgslbcn.info +qtlgslbcn.net +qto-pay.com +qtonghua.com +qtool.net +qtqsaadp.com +qtrun.com +qtshe.com +qtshisan.com +qtshu.com +qtshu.la +qtslog.com +qtsyw.com +qtsyzfc.com +qttc.net +qttunion.com +qtu8.com +qtumist.com +qtvnews.com +qtw555.com +qtx.com +qtyd.com +qu2000.com +qu2345.com +qu247.com +qu67.com +qua.com +quaita.com +qualcomm-challenge.com +qualcomm.cn.cdn.cloudflare.net +quality666.com +qualtekgz.com +qualysapi.qatp1.net +qualysguard.qpdp1.net +quan.mx +quan007.com +quan05.com +quan365.com +quanaichina.com +quancang.com +quandashi.com +quanduoduo.com +quanerp.com +quanfangtong.net +quanfangtongvip.com +quanfeng.tech +quanfensi.com +quanfs.com +quanguoban.com +quanguoyoubian.com +quangushi.com +quanhuaoffice.com +quanji.la +quanji.net +quanjiamei.com +quanjiaowang.com +quanjing.com +quanjingke.com +quanjinglian.com +quanjunkeji.com +quanjuwuye.com +quankexia.com +quanlaoda.com +quanlego.com +quanlitu.com +quanlv66.com +quanma51.com +quanmaigo.com +quanmaihuyu.com +quanmama.com +quanmamaimg.com +quanmamaonline.com +quanmeipai.com +quanmin-game.com +quanmin.tv +quanmin110.com +quanminbagua.com +quanminbb.com +quanminfu.com +quanoukeji.com +quanqiuwa.com +quanqiuweishang.com +quanquanapp.net +quanriai.com +quansheng-group.com +quanshi.com +quanshuge.com +quanshui.net +quansucloud.com +quantacn.com +quantaoyougou.com +quantil.com +quantilcn.com +quantilcn.net +quantilng.com +quantobio.com +quantongfu.com +quantuantuan.com +quantum-etc.com +quantum-info.com +quantumsc.online +quanup.com +quanwai100.com +quanwiki.com +quanxi.cc +quanxiangyun.com +quanxiankeji.com +quanxiaoha.com +quanxinfu.com +quanyaotong.com +quanyin.xyz +quanyueqk.com +quanyuesc.com +quanzhanketang.com +quanzhi.com +quanzhifu.net +quanzhougastronomy.com +quanziapp.com +quaolai.com +quarkbook.com +quarkers.com +quartzhy.com +quasarchs.com +quaspa.com +quazero.com +quba360.com +qubang.cc +qubaobei.com +qubiankeji.com +qucai.com +qucanzhan.com +quce001.com +quceaiqing.com +quchao.net +qucheng.com +quclouds.com +qudaiji.com +qudao168.com +qudaowuyou.com +qudayun.com +qudingshui.com +qudong.com +qudong51.net +qudong9.com +qudou100.com +qudushu.com +quduzixun.com +queceng.com +quechao.vip +quechen.com +quectel.com +queenl.com +quefan.com +quegame.com +quegui.run +quehu.com +queji.tw +quenergysemi.com +queniuaa.com +queniuab.com +queniuai.com +queniuak.com +queniual.com +queniuam.com +queniubc.com +queniubd.com +queniubf.com +queniubg.com +queniubh.com +queniubi.com +queniubk.com +queniubl.com +queniubm.com +queniubn.com +queniubq.com +queniubt.com +queniucdn.com +queniucdn.net +queniucf.com +queniucg.com +queniuck.com +queniucl.com +queniucm.com +queniucn.com +queniuco.com +queniucs.com +queniucw.com +queniucx.com +queniucz.com +queniuda.com +queniudd.com +queniude.com +queniudf.com +queniudg.com +queniudl.com +queniudns.com +queniudns.net +queniudo.com +queniudt.com +queniuee.com +queniueg.com +queniueh.com +queniuei.com +queniueq.com +queniuer.com +queniues.com +queniuez.com +queniufa.com +queniufc.com +queniufg.com +queniufi.com +queniufj.com +queniufm.com +queniufr.com +queniufw.com +queniufz.com +queniugd.com +queniugm.com +queniugslb.com +queniugslb.net +queniugt.com +queniugv.com +queniugw.com +queniugz.com +queniuhe.com +queniuhg.com +queniuhl.com +queniuhp.com +queniuhx.com +queniuhy.com +queniuhz.com +queniuib.com +queniuic.com +queniuif.com +queniuig.com +queniuih.com +queniuin.com +queniuiq.com +queniuit.com +queniuiv.com +queniuiy.com +queniuja.com +queniujd.com +queniuje.com +queniujf.com +queniujg.com +queniujq.com +queniujz.com +queniukk.com +queniukq.com +queniukr.com +queniuks.com +queniukt.com +queniukw.com +queniukx.com +queniukz.com +queniulb.com +queniulf.com +queniulg.com +queniuli.com +queniulp.com +queniulr.com +queniuls.com +queniulu.com +queniulv.com +queniulz.com +queniumc.com +queniumd.com +queniumf.com +queniumh.com +queniumn.com +queniumo.com +queniumy.com +queniund.com +queniunh.com +queniuni.com +queniunq.com +queniuns.com +queniuny.com +queniunz.com +queniuod.com +queniuog.com +queniuop.com +queniuos.com +queniuot.com +queniuoy.com +queniupa.com +queniupc.com +queniupe.com +queniupg.com +queniupj.com +queniupl.com +queniupq.com +queniupz.com +queniuqe.com +queniuqj.com +queniuql.com +queniuqm.com +queniuqt.com +queniuqu.com +queniuqy.com +queniuqz.com +queniurc.com +queniurj.com +queniurk.com +queniurq.com +queniuru.com +queniurv.com +queniurx.com +queniusa.com +queniusf.com +queniusg.com +queniush.com +queniusi.com +queniusj.com +queniuso.com +queniusp.com +queniusr.com +queniusv.com +queniusy.com +queniusz.com +queniutc.com +queniute.com +queniutn.com +queniutt.com +queniutx.com +queniutz.com +queniuua.com +queniuuc.com +queniuuf.com +queniuuk.com +queniuum.com +queniuuq.com +queniuus.com +queniuuy.com +queniuvb.com +queniuvc.com +queniuvg.com +queniuvi.com +queniuvk.com +queniuvq.com +queniuvu.com +queniuvx.com +queniuwb.com +queniuwf.com +queniuwh.com +queniuwk.com +queniuwq.com +queniuwx.com +queniuwz.com +queniuxd.com +queniuxe.com +queniuxk.com +queniuxr.com +queniuxx.com +queniuxy.com +queniuxz.com +queniuyb.com +queniuyf.com +queniuyg.com +queniuyk.com +queniuys.com +queniuyu.com +queniuyz.com +queniuza.com +queniuzd.com +queniuzf.com +queniuzh.com +queniuzl.com +queniuzp.com +queniuzu.com +queniuzv.com +queniuzy.com +queniuzz.com +queryrecord.com +quesela.com +queshu.com +questyleaudio.com +questyleshop.com +quexiaoxian.com +queyang.com +qufair.com +qufaya.com +qufeisoft.com +qufeizhou.com +qufenqi.com +qufenqian.vip +qufu123.com +qufumarathon.com +qufushi.com +qufutuan.com +qugame.com +quguonet.com +quhaidiao.com +quheqihuo.com +quhua.com +quhuaxue.com +quhuhao.com +quhuichang.net +quhuo.net +quick-global.com +quick-touch.com +quickapi.net +quickbass.com +quickcan.com +quickcep.com +quickddns.com +quickdetection.com +quickingdata.com +quickjoy.com +quicklaser.com +quicklyopen.com +quickpark.cc +quicksdk.com +quicksdk.net +quickswan.com +quicktvui.com +quickwis.com +quiksx.cfd +quilimen.com +quimg.com +quji.com +qujiangyizhong.com +qujie365.com +qujingm.com +qujunde.com +quk.cc +qukaa.com +qukan.cc +qukanok.com +qukanshu.com +qukantoutiao.net +qukanvideo.com +quklive.com +qukuai.com +qukuaila.com +qulaoshi.com +qule8.com +quledu.net +qulianaiba.com +qulishi.com +quluying.com +qulv.com +qumaihuishou.com +qumaishu.com +qumaiyao.com +qumaw.com +qumifeng.com +quming.com +qumingdashi.com +quminglemei.com +qumitech.com +qun-net.com +qun.hk +qun100.com +qun7.com +quna.com +qunaer.com +qunagai.com +qunale888.com +qunaly.com +qunar.com +qunar.ink +qunarcdn.com +qunarzz.com +qunba.com +qunchi.com +quncrm.com +qunfengjixie.com +qunfenxiang.net +qunhai.net +qunhaohotel.com +qunhaolawfirm.com +qunhei.com +qunhequnhe.com +qunjielong.com +qunke.com +qunkeng.com +qunliao.info +qunligroup.com +qunmi.vip +qunniao.com +qunonnet.com +qunsou.co +qunteng.net +quntengnet.com +quntuishou.com +qunwin.com +qunxiang.club +qunxingcable.com +qunxingvc.com +qunyaninfo.com +qunyingkeji.com +qunzh.com +qunzhuquan.com +qunzou.com +quoffice.com +quotationi.com +qupeiyin.com +qupingce.com +quqi.com +quqike.com +quqingting.com +quqiuhun.com +ququabc.com +ququyou.com +quqxphdm.com +qusem.com +qushiw.com +qushixi.net +qushoumiao.com +qushuba.com +qushuiying.net +qusibajjj.men +qutaiwan.com +qutanme.com +qutao.com +qutaojiao.com +qutecall.com +qutechat.com +qutemessenger.com +qutetalk.com +qutevoice.com +quthing.com +qutianshanav.com +qutingting.com +qutoutiao.net +qutouwang.com +qutu.com +qutuancan.com +qutuiwa.com +qutuly.com +quumibao.com +quumii.com +quvisa.com +quwan.com +quwangming.com +quweiwu.com +quwenqing.com +quwentxw.com +quwj.com +quwm.com +quword.com +quwuxian.com +quxds.com +quxianchang.com +quxiang.work +quxianzhuan.com +quxiaxia.com +quxingdong.com +quxintiaodong.com +quxiu.com +quxuan.com +quyangyizhong.com +quyibao.com +quyinginc.com +quyixian.com +quyiyuan.com +quyou.net +quyouhui.net +quyu.net +quyundong.com +quzhiwen.com +quzhuanxiang.com +quzhubao.com +quzwamx.com +quzwx123.org +quzz88.com +quzzgames.com +qvdv.net +qvip.net +qvkanwen.com +qvlz.com +qvxz.com +qw5599.com +qwbk.cc +qwconnect.top +qwe1e.com +qweather.com +qweather.net +qweatherapi.com +qwebapp.com +qwen.ai +qwenlm.ai +qwepgmyz.vip +qwerdns.com +qwerhost.com +qwfync.com +qwgg.com +qwgt.com +qwimm.com +qwing.com +qwmtjj360.vip +qwocs.com +qwpo2018.com +qwps.com +qwps.net +qwq.link +qwq.moe +qwq.ren +qwq.trade +qwqfzl.com +qwqk.net +qwqoffice.com +qwrmt.com +qwsy.com +qwwz.com +qx-era.com +qx-kj.com +qx-semi.com +qx.com +qx100.com +qx1000.com +qx10086.net +qx100years.com +qx121.com +qx162.com +qx66.cc +qx818.com +qxad.com +qxbnkj.com +qxbsk.com +qxckjr.com +qxcu.com +qxdaojia.com +qxdcc.com +qxen.com +qxfun.com +qxgcsc.com +qxhospital.com +qxhqxh.com +qxioqq4283.vip +qxiu.com +qxjeff.com +qxka.com +qxkp.net +qxlib.com +qxllq.com +qxme.com +qxmewmgr.com +qxmugen.com +qxnav.com +qxndt.com +qxnecn.com +qxnic.com +qxnzx.com +qxozm.com +qxqing.com +qxqkeak.com +qxqtwmgz.com +qxqxa.com +qxrcw.com +qxsdq.com +qxsfjq.com +qxshucai.com +qxswk.com +qxteacher.com +qxtongcheng.com +qxtour.com +qxtxt.com +qxueji4167.vip +qxueyou.com +qxw.cc +qxw18.com +qxwz.com +qxxsjk.com +qxy777.com +qxyjssb.com +qxzc.net +qxzsw.com +qxzxp.com +qy-marathon.com +qy-office.com +qy-polymer.com +qy-qq.com +qy-tencentclb.cloud +qy-tencentclb.com +qy-tencentclb.net +qy-tencentclb.work +qy.com +qy.net +qy266.com +qy57.com +qy6.com +qy7v7nn96e.com +qyaninfo.com +qybc.com +qybhl.com +qyc2008.com +qycn.com +qycn.net +qycn.org +qycname.com +qycylinder.com +qyd-rf.com +qydimg.com +qydqw.com +qydsj.com +qyer.com +qyerstatic.com +qyestar.com +qyfw168.com +qyg12.com +qyg30.com +qyg447.com +qyg9.com +qygbet140.vip +qygbet381.vip +qygbet427.vip +qygjyey.com +qyglzz.com +qygvip128.com +qygvip40.com +qyhgsb.com +qyhl.vip +qyhr.org +qyhxy365.com +qyiliao.com +qyins.com +qyinter.com +qyjg.com +qyjidianqi.com +qyjks.com +qykh2009.com +qykjedu.com +qymdb.com +qymgc.com +qyous.com +qyrb.com +qyrcbank.com +qyrcrs.com +qyrx.cc +qysbj.com +qysd.net +qysgf.com +qysport.com +qysrmyy.com +qyssgame.com +qysulian.com +qysuliao.com +qyszyyy.com +qyt.com +qyt1902.com +qytdesign.com +qytranslation.com +qytst.com +qytxhy.com +qyunapp.com +qyuner.com +qyuns.net +qywater.net +qywcom.com +qywd.com +qywww.net +qyx888.com +qyxa-tencentclb.cloud +qyxa-tencentclb.com +qyxa-tencentclb.net +qyxa-tencentclb.work +qyxxpd.com +qyxzfw.com +qyyt.com +qyyun.cloud +qyzba.club +qyzc.net +qyzlgame.com +qyzss.com +qz-jk.com +qz100.com +qz123.com +qz456.com +qz5z.com +qz828.com +qz96811.com +qz97.com +qz97.net +qzair.com +qzbbs.com +qzbgzz.com +qzbhgyl.com +qzbhzy.com +qzbwjx.com +qzccbank.com +qzchuxing.com +qzcia.com +qzcklm.com +qzclfc.com +qzcns.com +qzct.net +qzda.com +qzdatasoft.com +qzdswy.com +qzdxcj888.com +qzdyyy.com +qzesx.net +qzeyy.com +qzfwckj.com +qzg123.com +qzgc.net +qzgchj.com +qzgfyy.com +qzgjjp.com +qzgkwy.com +qzhaite.com +qzhlkj.net +qzhmyy.com +qzhmzx.com +qzhospital.com +qzhrkj.com +qzhsjc.com +qzhslw.com +qzhuye.com +qzhxshipping.com +qzimg.com +qzj2.com +qzjcd.com +qzjgxx.com +qzjhscl.com +qzjhsd.com +qzjianwo.com +qzjkw.net +qzjy029.com +qzjycc.com +qzjzyy002.com +qzkangfu.com +qzkcw.com +qzkey.com +qzkjyy.com +qzks.com +qzktzc.com +qzlanwei.com +qzld.com +qzldkj.com +qzljjq.com +qzlo.com +qzlwnm.com +qzmayouquan.com +qzmktjt.com +qzmtgs.com +qznovel.com +qznovelpic.com +qznovelstatic.com +qznovelvod.com +qznxt.com +qzone.cc +qzone.com +qzoneapp.com +qzonei.com +qzqcfw.com +qzqcw.com +qzqiye.com +qzqn8.com +qzqstudio.com +qzqxd.com +qzqxw.com +qzrbx.com +qzrc.com +qzrcsc.com +qzrcw.com +qzread.com +qzrencai.com +qzsdkj.com +qzsfy.com +qzsgyxx.com +qzshangwu.com +qzshly.com +qzsmxx.com +qzsqsnhdzx.com +qzssdy.com +qzsx168.com +qzsystem.com +qzsyy.com +qzszyy.com +qzt520.com +qztc.vip +qztingche.com +qztour.com +qztsecurity.com +qztszls.com +qztvxwgj.com +qzwb.com +qzwgw.com +qzww.com +qzxdianzi.com +qzxkeji.com +qzxx.com +qzyckhzx.com +qzynhhmm.com +qzyonyou.com +qzyuchao.com +qzyun.net +qzyz.com +qzyzt.com +qzzdtc.com +qzze.com +qzzgdl.com +qzzhedu.com +qzzhonghan.com +qzzhwk.com +qzzjchy.com +qzzn.com +qzzpw.net +qzzres.com +qzzsbx.com +qzzyyy.com +qzzzg.net +r-china.net +r-tms.net +r.bing.com +r.biz +r12345.com +r147emh.com +r1y.com +r2009.com +r220.cc +r2coding.com +r2yx.com +r302.cc +r51.net +r5g.cc +r5k.com +r5tao.com +r61lsi5tje.com +r6d7345371.com +r75y8c2628.com +r77777777.com +r79xqa8r7e93.com +r8.com +r8.net +r8856.com +r8857.com +r8876.com +r89gr9gr.ink +r8hr7.net +r9922.com +r9t1.com +ra022.com +ra2ol.com +raas1.com +rabbit1117.com +rabbitbbs.com +rabbitpre.com +rabbitpre.me +rabbitserve.com +rabook.com +rabschina.com +race604.com +racent.com +racetigertiming.com +rachina.org +racing-china.com +racktray.com +racpro.net +racsd.com +racymj.com +radar-ev.com +radiate-electronics.com +radicalmail.net +radida.com +radio1964.com +radio366.com +radiotj.com +radiowar.org +radissoncollection-wuxi.com +radius-america.com +radleybagssaleuk.org +raeblog.com +rafflesmedicalchina.com +ragdgs.com +ragnarokcn.com +raharyanto.com +rahisystems-cn.com +raidc.com +rail-metro.com +rail-transit.com +railcn.net +rails365.net +railsctc.com +railshj.com +railwaybill.com +railworkschina.com +raina.tech +rainbond.com +rainbowcn.com +rainbowred.com +rainbowsoft.org +rainbutterfly.xyz +rainclassroom.com +raindi.net +raineggplant.com +raingray.com +rainhj.com +rainhz.com +raink.org +rainlain.com +rainng.com +rainso.com +rainwe.com +rainyun.com +raise-win.com +raisecom.com +raisedsun.com +raisewebdesign.com +raisingsun.xyz +raiyi.com +rajaluck.work +rajax-inc.com +rajax.me +rajyj.com +rakinda-aidc.com +rakinda-xm.com +rakpqgk.com +rakutabichina.com +rakvps.com +ramadaplaza-ovwh.com +ramboplay.com +ramostear.com +rampingup.com +ramsdei.com +ramventures.com +ramwaybat.com +rancat.im +randengseo.com +randongada.com +randongma.com +randyandtheresa.com +rangercd.com +rangnihaokan.com +rango.fun +rangotec.com +rangti.com +rangxue.com +rangzong.com +ranhou.com +rankingonline.jp +ranknowcn.com +ranliao.biz +ranling.com +ranqibiao.net +rantu.com +ranwen.net +ranwen.org +ranwena.com +ranxi.net +ranyangrent.com +ranzhi.net +ranzhi.org +raobee.com +raoke.net +raoluns.com +raonie.com +raorao.com +rap-pro.com +rapidppt.com +rapoo.com +rapospectre.com +rarbg.to +rarbt.fun +rarcbank.com +rarelit.net +rarone.com +rashanghai.org +rashost.com +raspigeek.com +rastargame.com +rat.dev +rat3c.com +rate2003.com +ratingtoken.net +rationalwh.com +ratogh.com +ratoo.net +rauto.com +ravenna0943.xyz +raverstern.site +rawanfa.com +rawchen.com +raxtone.com +ray-joy.com +ray1988.com +ray8.cc +raycham.com +raychase.net +raycim.com +raycloud.com +raycom-inv.com +raycuslaser.com +raydata-asset.com +raydata-mobile.com +raydata-open.com +raydata-web.com +raydata.cc +raydata.info +raydata.pro +raydataasset.com +raydatamobile.com +raydataopen.com +raydataweb.com +raydonet.com +rayenergytech.com +rayfalling.com +rayfaydata.com +raygame3.com +raygame4.com +rayiantway.com +rayjoy.com +raykite.club +raykite.com +raykite.info +raykite.net +raykite.vip +raykite.xyz +rayli.com +raylink.live +raymage.com +raymx-micro.com +raynext.info +rayoptek.com +rayp.com +rayps.com +rayrjx.com +rayseasc.com +raysgo.com +raysilicon.com +raystek-p.com +raystesting.com +raysync.cloud +raysyun.com +raythonsoft.com +raytine.com +raytoon.net +rayuu.com +rayvision-tech.com +rayvision.com +raywit.com +razerapi.com +razersynapse.com +razerzone.com +razrlele.com +raztb.com +rb-parking.com +rb32.com +rb400.com +rbi-china.com +rbischina.org +rbkwater.com +rbladycrusaders.com +rbotai.com +rbqq.com +rbtxw.com +rbz1672.com +rbzarts.com +rbzygs.com +rc-ev.com +rc0817.com +rc1001.com +rc114.com +rc120.com +rc168.com +rc3cr.com +rc775.com +rcbc888.com +rcbuying.com +rccaijing.com +rccchina.com +rcche.com +rcdang.com +rcesssc.com +rcfans.com +rcgus.com +rchsrc.com +rchudong.com +rcjypx.com +rclbbs.com +rclhome.com +rclolci.com +rclrow.com +rclsemi.com +rcmarble.com +rcmxw.com +rcnep.com +rcolab.com +rcpx.cc +rcswo.com +rcsxzx.com +rcunxyn.com +rcuts.com +rcwl.net +rcyd.net +rcyjw.com +rcyxdk.com +rcz.cc +rczhuyu.com +rczp.org +rczx.com +rd-cn.com +rd-game.com +rd351.com +rdacs.com +rdadiy.com +rdamicro.com +rdbuy.com +rdcnzz.com +rdcolg.net +rdcv1.com +rdcv1.net +rddesign.cc +rddoc.com +rdedu.net +rdfis.com +rdfybk.com +rdfz.com +rdgcs.com +rdgcw.com +rdgz.org +rdgzxx.net +rdhyw.com +rdidc.com +rdjmgg.com +rdmicro.com +rdnsdb.com +rdplat.com +rdqczl.com +rdqh.com +rdsdk.com +rdsms.net +rdwork.com +rdxmt.com +rdyjs.com +rdympjoqbu.work +rdzjw.com +rdzs.com +rdzx.net +rdzy.net +re25.vip +reabam.com +reach-ad.com +reach-biology.com +reachace.com +reachauto.com +reachsh.com +reachsurgical.com +reachtone.com +reachwin.net +react-china.org +react.mobi +read678.com +readboy.com +readceo.com +readend.net +readers365.com +readfollow.com +readfree.net +readgps.com +readhb.com +readhr360.com +readhub.me +readke.com +readlevel.com +readlink.com +readlishi.com +readm.tech +readmeok.com +readnos.com +readnovel.com +readpai.com +readpaper.com +readpaul.com +readse.com +readten.net +readu.net +ready4go.com +reai120.com +realape.com +realapp.xin +realbiogroup.com +realcybertron.com +realfoodiescompost.com +realforcechina.com +realibox.com +realks.com +reallct.com +realliniot.com +realmax-sh.com +realme.com +realme.net +realmebbs.com +realmemobile.com +realmeservice.com +realmofswords.com +realor.net +realsee-cdn.com +realsee.com +realshark.com +realtech-inc.com +realtek-rtd.com +realtimecn.com +realtorforce.ca +realxen.com +realyuan.com +reanda.com +reapdaro.com +reardatchina.com +reasonclub.com +rebang.today +rebatesme.com +rebo-group.com +recaptcha-cn.net +recaptcha.net +rechaos.com +rechulishebei.com +recitymedia.com +reckfeng.com +recodeal.com +recolighting.com +reconova.com +recordpharm.com +recovery-soft.com +recovery-transfer.com +recoye.com +recuvachina.com +recycle366.com +red-yellow.net +redacted.ch +redatoms.com +redbaby.com +redbascket.com +redbeeai.com +redcome.com +redcross-hx.com +redcross-sha.org +reddogchina.com +redearth.com +redefine.ltd +redenmc.com +redfcv.com +redflag-linux.com +redflagseed.com +redhome.cc +redhongan.com +redhtc.com +redianduanzi.com +redianmao.com +redianyuansu.com +redianyule.com +redianzixun.com +rediao.com +redidc.com +redirector.bdn.dev +redirector.c.youtubeeducation.com +redirector.gcpcdn.gvt1.com +redirector.gvt1.com +redirector.offline-maps.gvt1.com +redirector.snap.gvt1.com +redirector.xn--ngstr-lra8j.com +redisfans.com +redmagic.com +redmart.com +redmou.com +rednetdns.com +redocn.com +redodopower.com +redoop.com +redou.com +redoufu.com +redox-med.com +redphon.com +redq.cc +redraingame.com +redrcd.com +redream.com +redredsquare.com +redsea888.com +redsh.com +redshu.com +redstarwine.com +redstonewill.com +redsun-nsh.com +redsun-rp.com +redsungd.com +redsungz.com +redtriphome.com +redug8dqjjktoapmdfmqymrvi0iupi.com +reduxingxuan.com +redyue.com +redyue.org +reed-sinopharm.com +reedoun.com +reeidc.com +reeiss.com +reeji.com +reenoo.com +reenoo.net +reeoo.com +refined-x.com +refineidea.com +refire.com +refond.com +reformdata.org +refresh-bkg.activation-v2.kaspersky.com +reg007.com +regal-marathon.com +regal-raptor.com +regenchem.com +regengbaike.com +regexlab.com +regexr-cn.com +reglogo.net +regltd.com +regtm.com +regulatory-ledger-transaction-check.com +reguo.com +rehiy.com +rehn.cc +reht.com +rehtt.com +rehuwang.com +reibootmac.com +reignwood.com +reilybrand.com +reinness.com +rejesafe.com +rejushe.com +rek8.com +rekong.com +rekonquer.com +rekoo.com +rekoo.net +rela.me +relangbang.com +relangdata.com +relativelk.com +relaychina.org +relayx.io +relenger.com +reliabiotech.com +reliangbiao.com +reliao.tv +rellet.com +reloadbuzz.com +relxtech.com +relxyanyou.com +rely87779777.com +remaijie.net +remapcity.com +remax-bj.com +remenxs.cc +remixai.com +remixicon.com +remo-ai.com +remodelife.com +remotcon.mobi +remoteaps.com +remotedu.com +remyhumanhairextension.com +renai-edu.com +renaihospital.com +renaishiyao.com +renaissancehotelhuizhou.com +renaren.com +renbenai.com +renbenzhihui.com +renbj.com +rencaijia.com +rencaijob.com +rencheng1991.com +rendajingjiluntan.com +renderbus.com +renderincloud.com +rendeyixue.com +rendiyu.com +rendna.com +rendoc.com +renead.com +renegade-project.org +renelgroup.net +renergy-me.com +renew-cmda.com +renew-cn.com +renfei.net +renfutm.com +renguokeji.com +renhaocw.com +renhe888.com +renhebusiness.com +renhence.com +renhuaicode.com +renji.com +renjian.com +renjiaoshe.com +renjiyiyuan.com +renkky.com +renle.com +renleisheji.com +renlijia.com +renliwo.com +renlu.net +renmaiku.com +renmaitong.com +renminkaiguan.com +renminyixue.com +renny.ren +renping.cc +renren-inc.com +renren-x.com +renren.com +renren.io +renrenbeidiao.com +renrenchaxun.com +renrenche.com +renrencou.com +renrendai.com +renrendoc.com +renrenfinance.com +renrening.com +renrenlun.com +renrenmoney.com +renrenpeizhen.com +renrenshaike.com +renrenshe.com +renrenshipu.com +renrensousuo.com +renrenstudy.com +renrensucai.com +renrentou.com +renrentrack.com +renrenyee.com +renrk.com +renruihr.com +renrunkeji.com +rensa-hanno.com +rensheng123.com +renshouks.com +renshouren.com +rent.work +renwen.com +renwenyishu.com +renwuduo.com +renwuji.com +renwulian.com +renwumatou.com +renyiwei.com +renzaoshu.com +renzhemao.com +repai.com +repaiapp.com +repair5g.com +repanso.com +repian.com +replays.net +replica.club +replicabest.cc +replicachinawatch.vip +replicahot.cc +replicais.com +replicaluxury.cc +replicareloj.es +replicasale.cc +replicashop.cc +replicasreloj.com +replicasrelojlujo.com +replicaswiss.co +replicaswissclocks.com +replicawatchaaa.cc +replicawatchhot.com +replicawatchshipping.com +replicawatchshop.cc +replicawatchsshop.cc +replicheorologio.com +repliquemontresdeluxe.fr +repliquesuisse.co +repont.com +reportify.cc +reportrc.com +reportway.org +reprogenix.com +reptilesworld.com +reputatioy.com +reqable.com +reqgvheo.com +rergdfh.com +reseetech.com +resemblancey.com +resemi.com +reservehemu.com +resheji.com +resistor.today +resnics.com +resnowshop.com +resona-wujl.com +resone-shinab.com +resowolf.com +respeaonsct.com +respect-lab.com +respondaudio.com +respusher.com +resset.com +resturbo.com +resuly.me +retailo2o.com +retalltech.com +retiehe.com +retopon.com +retouchpics.com +return.net +returnc.com +reveetech.com +revefrance.com +revenuads.com +reviosky.com +revolut.ltd +revolutwebapp.com +rew65.com +rewanyouxi.com +rewnat.xyz +reworlder.com +rewuwang.com +rexcdn.com +rexdf.org +rexinyisheng.com +rexsee.com +rexueqingchun.com +reyinapp.com +rezhanwang.com +rf-bed.com +rf-china.com +rf-link.com +rf.com +rf.hk +rfaexpo.com +rfc2cn.com +rfchina.com +rfchost.com +rfcmedia.streamguys1.com +rfcreader.com +rfdl88.com +rfeyao.com +rffan.info +rfgjhz.com +rfhhzx.com +rfid-e.com +rfidcardcube.com +rfidfans.com +rfidnfk.com +rfidtech.cc +rfilter.com +rfimonde-lh.akamaihd.net +rfjd.com +rfjq.com +rfk.com +rfmwave.com +rfthunder.com +rfvtgbnh.vip +rfylyp.com +rg-marathon.com +rg-pharma.com +rg950.com +rgaxobcs.com +rgb128.com +rgble.com +rgdse.shop +rgezppvk.com +rgkjyp.com +rgoo.com +rgrcb.com +rgsgnj.com +rgslb.com +rgtjf.com +rgxw.com +rgyh6t.com +rgzbgroup.hk +rgzxraiu.com +rh31.com +rh98.com +rhce.cc +rhcncpa.com +rhcqmu.com +rhctwy.com +rhcyl.com +rheaeco.com +rheemchina.com +rhexe.com +rhhz.net +rhine-inc.com +rhinosgamestwhk.com +rhinoxky.com +rhjoyhotel.org +rhkj.com +rhky.com +rhnewmaterials.com +rhoadshomebuyers.com +rhonghai.com +rhphos.com +rhsj520.com +rhspring.com +rhtimes.com +rhtzjt.com +rhusen03.com +rhwatchcn.com +rhwatches.com +rhyme.cc +rhypw.com +ri-china.com +riande.com +rianico.tech +riaway.com +ribaoapi.com +ribaocdn.com +ribencun.com +ribenguwan.com +ribio.com +ribolia.com +ricebook.com +ricequant.com +riceyun.com +rich-chang.com +rich-fc.com +rich-futures.com +rich-healthcare.com +richardfw.com +richeninfo.com +richhurry.com +richiecn.com +richinfer.net +richkays.com +richlandsfarm.com +richong.com +richseafood.com +richsuntrade.com +richtech123.com +richtechcn.com +richtj.com +ricklj.com +rickyfabrics.com +rickysu.com +rictos.com +ridgepole.com +rido-ja.com +riecent.com +rifagroup.com +rifapm.com +rifubao.com +rigen-bio.com +rigerna.com +rigger-micro.com +rightknights.com +rightpaddle.com +rigol.com +rigouwang.com +rigums.xyz +riitao.com +riji001.com +riji100zi.com +rijigu.com +rijiwang.com +rikua.com +rili11.com +rili19.com +rilijingling.com +rilingpec.com +riliri.com +rilvtong.com +rim20.com +rimaiwang.com +rin9.com +ringdoll.com +ringerswesternauoff.com +ringofelysium.com +ringofelysiumonline.com +ringpu.com +rining.com +rinlink.com +rinvay.cc +rioalc.com +riogene.com +riolu.lol +riowine.com +ripic.xyz +rippletek.com +riqicha.com +risc-v1.com +riscv-dev.tech +riscv-mcu.com +riscv-summit.com +risde.com +rise99.com +risecenter.com +risechina.org +riselinkedu.com +risen-pharma.com +risencn.com +risenenergy.com +risesoft.net +riseyears.com +risfond.com +rishiqing.com +rishuncn.com +rising-eo.com +risingauto.com +risinggas.com +riskbird.com +riskivy.com +risongtc.com +risuiwd.com +risun.com +riswing.com +ritaichina.com +ritao.hk +ritaojiang.com +ritaomeng.com +ritarpower.com +rivalsa.net +riveralydia.shop +rivergame.net +riverinepm.com +riverlimittech.net +rivocean.com +riwise.com +rix-dl.com +riya.cc +riyingkj.com +riyuandianzi.com +riyuexing.org +riyuezhuan.com +riyugo.com +riyutool.com +rizbbs.com +rizhao.net +rizhaociming.com +rizhaogongshui.com +rizhaokjg.com +rizhaosteel.com +rizhaoxl.com +rizhili.com +rizhiyi.com +rizhuti.com +rj.link +rj.net +rj668.com +rj889.net +rjaaa.com +rjcopy.com +rjdownd.com +rjetech.com +rjeye.com +rjfc110.com +rjgcz.com +rjghome.com +rjh0.com +rjhcsoft.com +rjitxy.com +rjlqq.com +rjoy.com +rjpharm.com +rjpharma.com +rjreducer.com +rjs.com +rjsjmbwx.com +rjsos.com +rjtx.net +rjty.com +rjuxl.xyz +rjxzjx.com +rjzxw.com +rk-light.com +rk120.com +rkanr.com +rkaq110.com +rkckth.com +rkdatabase.com +rkddzda.com +rkeji.com +rkgaming.com +rkkgyy.com +rklive888.com +rkrcemei.com +rksec.com +rkvir.com +rkzxhyy.com +rl-consult.com +rlair.net +rljydt.com +rlkj.com +rlkj.net +rlmeijia.com +rlnk.net +rlreader.com +rlsofa.net +rltyll.com +rlw27.com +rlydw.com +rlyl.net +rlzdh.com +rlzyxa.com +rm.run +rmall-solution.com +rmb.sh +rmbbk.com +rmbgame.net +rmbgd.com +rmburl.com +rmcteam.org +rmcvqq.sbs +rmejk.com +rmgvx.com +rmhospital.com +rmjiaju.com +rmjtxw.com +rmny.tech +rmrbwc.com +rmrun.com +rmsznet.com +rmttjkw.com +rmtv24hweblive-lh.akamaihd.net +rmtyun.com +rmwxgame.com +rmxiongan.com +rmysjzx.com +rmzs.net +rmzszp.com +rmzt.com +rmzxb.com +rn-core.com +rn-hswh.com +rnfengwo.com +rngdyy.com +rngmoe.com +rngtest.com +rnhospital.com +rnhy.net +rnmachine.com +ro50.com +ro8qwpaikd4kx.com +road-group.com +roadhb.com +roadjava.com +roadlady.com +roadoor.com +roadqu.com +roadsignads.com +roadtoempress.com +roadwaygroup.com +roai.shop +roaing.com +robam.com +robbyant.com +robei.com +roboeyeai.com +robomaster.com +roboneo.com +roboo.com +robook.com +robopeak.net +roborock.com +robosense.ai +robot-ai.org +robot-china.com +robot301.net +robotech-log.com +roboticsurg301.net +robotime.com +robotiot.org +robotphoenix.com +robotplaces.com +roboxx.ltd +roc-cnc.com +roca026.com +rocaircraft.com +rocar.net +rochat.tech +rock-chips.com +rockbrain.net +rockbundartmuseum.org +rockdata.net +rockemb.com +rockerfm.com +rocketmq.cloud +rockflow.tech +rockjitui.com +rocklogistic.com +rockontrol.com +rockorca.com +rockrobo.com +rockru.com +rockx.pub +rocky.hk +rockyaero.com +rockyenglish.com +rockyglass.com +roclee.com +rocoswatch.com +rocxgroups.com +roffar.com +roguelike.com +roguelitegames.com +rohm-chip.com +roidmi.com +roii.cc +roiland.com +rojewel.com +rokeyyan.com +rokid.com +rokidcdn.com +rokub.com +rokxyecc.com +roland-china.com +rolipscn.com +rollupjs.com +rom100.com +rom333.com +romantic-ltd.com +romantic214.com +romens.cloud +romhui.com +romielf.com +romjd.com +romleyuan.com +romney-lighting.com +romo.tech +romonupark.com +romzhijia.net +romzj.com +ronbaymat.com +roncoo.com +rondygroup.com +rong-data.com +rong-edge.com +rong-rtc.com +rong-sheng.com +rong100.com +rong360.com +ronganjx.com +ronganquan.com +rongba.com +rongbiz.com +rongbiz.net +rongbst.com +rongcfg.com +rongchain.com +rongchaodichan.com +rongcheer.com +rongchenjx.com +rongdasoft.com +rongdatamall.com +rongded.com +rongdeji.com +rongechain.com +ronggangcity.com +ronggongyeya.com +rongguang-sh.com +ronghai.com +ronghedai.com +ronghotels.com +ronghuajixie.com +ronghub.com +ronghuiad.com +ronghuisign.com +rongji.com +rongjiagroup.com +rongkang.com +rongkao.com +rongkeyiyuan.com +rongledz.com +rongmaowl.com +rongmei.net +rongnav.com +rongqu.net +rongroad.com +rongsheng.biz +rongshiedu.com +rongshu.com +rongshuweb.com +rongshuxia.com +rongstone.com +rongtai-arch.com +rongtai-china.com +rongtongworld.com +rongwenest.com +rongwengroup.com +rongxingroup.com +rongxuancast.com +rongyanshe.com +rongyao666.com +rongyaozhiguang.com +rongyi.com +rongyilian.net +rongyimao.com +rongyitechnology.com +rongyizhaofang.com +rongyuechem.com +rongzhitong.com +rongzhongleasing.com +rongzhongloan.com +rongzhougucheng.com +rongzi.com +ronpharm.com +rontgens.com +roobo.com +rooderscooters.com +rooee.com +roof325.com +roogames.com +roongeimahwo.com +roosur.com +root-servers.world +root1111.com +rootcloud.com +rootguide.org +rootintech.com +rootjl.com +roouoo.com +ropefitting.com +ropinsite.com +ror-game.com +rorotoo.com +ros-lab.com +ros6.com +rosabellass.store +rosaryshelties.com +rosbox.net +rosdn.com +rose.ren +rosecmsc.com +rosedata.com +rosefinchfund.com +rosepie.com +rosesandgold.fun +rosewin.com +rosin-china.com +rosirs-edu.com +rosmontis.com +rosnas.com +rosoo.net +rosoyp.com +rossoarts.com +rossoarts.net +rossopharm.com +rossroma.com +roswiki.com +roszj.com +rotai.com +rotiyfhp.com +rotom-x.com +rotora-china.com +rotorgroup.com +rouding.com +rouexdmv.com +roujiaosuo.com +roukabz.com +roule.org +roundexpo.com +roundyule.com +rouruan.com +roushidongwu.com +rousin.com +route78asia.com +router.tw +routerclub.com +routeryun.com +routewize.com +routuan.com +rouxiutang.com +rouzao.com +rouzhitang.com +rovbox.com +rowa.com +rowcan.com +rowlib.com +roxinq.com +roxmotor.com +royalsh.net +royalym.com +royole.com +royotech.com +royqh.net +roywang.com +rp-field.com +rp-pet.com +rpa-cn.com +rpaii.com +rpfieldcdn.com +rpg99.com +rpgmoba.com +rpo5156.com +rprnolz.com +rpy.net +rq.run +rqb99.com +rqgtzit.com +rqjtp.com +rqkr.com +rqrcw.com +rqrlxx.com +rquyzhda.com +rqyy.com +rqyz.com +rr-sc.com +rr365.com +rrajz.com +rrb365.com +rrbay.com +rrbjt.com +rrbus.com +rrchem.com +rrcimg.com +rrdtz.com +rrfed.com +rrfmn.com +rrimg.com +rrioo.com +rrjc.com +rrkf.com +rrky.com +rrl360.com +rrlicai.com +rrmj.tv +rrppt.com +rrrdai.com +rrrrdaimao.com +rrrxz.com +rrs.com +rrsurg.com +rrswl.com +rrting.net +rrtoibg.com +rrtv.vip +rrwtp.com +rrxf.online +rrxh5.cc +rrxiu.cc +rrxiu.me +rrxiu.net +rrxiuh5.cc +rrys.tv +rrys2019.com +rrys2020.com +rrysapp.com +rrzu.com +rrzuji.com +rrzwl.com +rrzxw.net +rs-xrys.com +rs485.net +rsachina.org +rsc.org +rscazvdbfpbyzqdvpy1m.com +rscazvdbfpbyzqdvpylm.com +rscygroup.com +rsdcw.com +rsdgd.com +rsdsgy.com +rsdxjd.com +rsdyy.com +rsdznjj.com +rsfang.net +rsfcxq.com +rshao.com +rshaoapp.com +rshdsz.com +rshf88.com +rshjgc.com +rsjq.org +rsjytx.com +rskjx.com +rsl.cc +rslg-china.com +rsm.download.prss.microsoft.com +rsnmxd.com +rsnschina.com +rsplcdcs.com +rspwj.com +rsq111.com +rsrlzysc.com +rss.ink +rsscc.com +rssdtec.com +rssso.com +rsttdsaaas.icu +rsttest.com +rsty77.com +rsuedu.com +rsun.com +rsw163.com +rswaf.com +rswl.cc +rsxc01.com +rsxmgl.com +rsybattery.com +rsyzs.com +rszfg.com +rszkw.com +rt-blend.com +rt-ics.com +rt-thread.com +rt-thread.io +rt-thread.org +rtacdn-os.com +rtahengtai.com +rtalink.com +rtb5.com +rtbbox.com +rtbmax.com +rtbpb.com +rtbtmc.com +rtbwave.com +rtc-web.com +rtc-web.io +rtcdeveloper.com +rtddisplay.com +rtdsoft.com +rtf1688.com +rtfcode.com +rtfcpa.com +rtftq.org +rtfund.com +rtfzfl.com +rthklive1-lh.akamaihd.net +rthklive2-lh.akamaihd.net +rthpc.com +rti-investor.com +rtjxssj.com +rtmap.com +rtmobi.cc +rtprc.org +rtrrx.com +rtsaas.com +rtsac.org +rtsc-gift.com +rtvcdn.com.au +rtxapp.com +rtxonline.com +rtxplugins.com +rtxuc.com +rtyhfg.com +rtyxpt.com +rtyy.com +ru5sq.com +rua93.online +ruan.cloud +ruan8.com +ruanchaomin.com +ruanduo.com +ruandy.com +ruanfujia.com +ruanjian60.com +ruanjiandown.com +ruanjianwuxian.com +ruanjianya.net +ruanjiesh.com +ruankao.com +ruankaodaren.com +ruankaokao.com +ruanko.com +ruanmei.com +ruansky.com +ruansky.net +ruantiku.com +ruanwen.la +ruanwen.tv +ruanwengfa.com +ruanwenhui.com +ruanwenkezhan.com +ruanwenlala.com +ruanwenpu.com +ruanwenshijie.com +ruanx.net +ruanyuan.net +ruazi.com +rubaoo.com +rubbervalley.com +rubinn.com +ruby-china.com +ruby-china.org +rubyconfchina.org +rubyer.me +rubyfoods.com +rucedu.net +ruchee.com +ruchu.club +ruczzy.com +rue123.com +rueiran.com +ruesu.com +rufei.ren +rufengda.com +ruffhousetraining.com +rufida.com +rugao35.com +rugaobbs.com +ruguoapp.com +ruguojiaoyu.com +ruhaivip.com +ruhnn.com +rui.plus +ruiaiad.com +ruian.com +ruianchayuan.com +ruianfang.com +ruianrz.com +ruibai.com +ruibaigroup.com +ruibangwl.com +ruiccm.com +ruichengmedia.com +ruichun120.com +ruicitijian.com +ruida.org +ruidaedu.com +ruidaen.com +ruidan.com +ruidang.com +ruidaxx.com +ruidengkeji.com +ruideppt.com +ruideppt.net +ruidongcloud.com +ruidroid.xyz +ruidsp.com +ruiduobao.com +ruienkj.com +ruifang-tech.com +ruifengchemical.com +ruifengdisplay.com +ruifengjk.com +ruifuwatch.com +ruige.com +ruigedf.com +ruigushop.com +ruihaimeifeng.com +ruihaozhanlan.com +ruihengyiliao.com +ruiheyuanny.com +ruihongip.com +ruihuajw.com +ruihuaxinxi.com +ruihuo.com +ruiii.com +ruiinsurance.com +ruijie.com +ruijiehuanbao.com +ruijienetworks.com +ruijiery.com +ruijieyun.com +ruijinginfo.com +ruijinintl.com +ruijinyy.com +ruikangjinshu.com +ruilibi.com +ruilimr.com +ruilinblw.com +ruiniucn.com +ruiniweier.com +ruipai.com +ruipengkeji.com +ruipengpet.com +ruipupharma.com +ruiscz.com +ruisheng.cc +ruishengseal.com +ruisilc.com +ruisizt.com +ruisong.tv +ruit56.com +ruitairt.com +ruite-tec.com +ruitengmaoyi.com +ruitian.com +ruitiancapital.com +ruitianjc.com +ruiuav.com +ruivihome.com +ruiwant.com +ruiwen.com +ruiwenruanjian.com +ruixhz.com +ruixiangbest.com +ruixiangdy.com +ruixin-eht.com +ruixing.cc +ruixueys.com +ruixuncw.com +ruixunidc.com +ruixunidc.net +ruiyang-ra.com +ruiying3d.com +ruiyingkeji.com +ruiyitech.com +ruiyuanchina.com +ruiyuanobserve.com +ruiyun.com +ruiyunit.com +ruize66.com +ruizhi-group.com +ruizhipak.com +ruizhiqi.com +ruizib.com +ruizong-gz.com +rujiazg.com +rujiu.net +rukechina.com +ruketang.com +rukodilla.com +rulandchem.com +rulei.vip +rulejianzhan.com +rulianshi.la +rumeibox.com +rumodesign.com +rumosky.com +runbaijia.com +runboyun.com +runca.net +runcmd.com +runcobo.com +runcome.com +rundamedical.com +rundapv.com +runde666.net +rundefit.com +rundejy.com +rundeschool.com +runergy.com +runff.com +runforint.com +runfox.com +runfujin.com +runhe.org +runhengfdc.com +runhuayou.biz +runjf.com +runjian.com +runjiapp.com +runkodo.com +runkunoptics.com +runlaijituan.com +runmang.com +runnar.com +runner-corp.com +runnerbar.com +running8.com +runningcheese.com +runninginchina.org +runningman-fan.com +runnoob.com +runnuokeji.com +runoob.com +runpho.com +runqi-nj.com +runqijx.com +runsheng.com +runshenggk.com +runsky.com +runsunedu.net +runtimebj.com +runtimeedu.com +runtimewh.com +runtronic.com +runtuchem.com +runwanxin.com +runwise.co +runwith.cc +runxun.com +runzechuanmei.com +runzefluidsystem.com +runzeyuan.com +runzi.cc +ruochu.com +ruodian360.com +ruofeisinian.com +ruohang.com +ruohuo.net +ruokuai.com +ruonei.com +ruons.com +ruoren.com +ruoshui.com +ruosoft.com +ruoxia.com +ruoyer.com +ruoyi.vip +ruozedata.com +ruozhu.shop +ruqimobility.com +ruralwomengd.org +ruseer.com +rusforest-sh.com +rushan.com +rushb.net +rushi.net +rushihu.com +rushivr.com +rushiwowen.org +rushmail.com +rushui.net +russellluo.com +rustc.cloud +rustdesk.work +rustfisher.com +rustfs.com +rustvnt.com +rutbr.com +ruthout.com +ruthus.com +rutron.net +ruu6373.com +ruubypay.com +ruvar.com +ruvisas.com +ruwen5.org +ruxiaoyi.com +ruyig.com +ruyigou.com +ruyile.com +ruyim.com +ruyiqiming.com +ruyishi.com +ruyo.cc +ruyo.net +ruyu.com +ruyuecx.com +ruyuexs.com +ruzong.com +ruzw.com +rv28.com +rv2go.com +rvacvzhru.com +rvcore.com +rvedu.com +rvfdp.com +rvgyckhp.com +rvkol.com +rvmcu.com +rwb66.com +rwd.hk +rwdls.com +rwjiankang.com +rwjtgc.com +rwkv.com +rwosf.space +rwrvthca.com +rwsignal.com +rwtext.com +rwxqfbj.com +rwys.com +rx-copper.com +rx-semi.com +rx4wiug6ec6r.com +rxbj.com +rxcrs.com +rxftw.com +rxgl.net +rxhospital.com +rxhui.com +rxhysm.com +rxian.com +rxjhbaby.com +rxjt.co +rxkjcn.com +rxljzy.com +rxndt.com +rxshc.com +rxwsls.com +rxwsls.net +rxxdny.com +rxyjqz.com +rxykamto.com +rxys.com +rxyushangfw.com +ry0663.com +ry0751.com +ryanbencapital.com +ryanchem.com +ryansu.tech +rybbaby.com +rybridge.com +rybyurom.com +ryc360.com +rycc.net +ryd-group.com +rydbatt.com +rydermedical.com +rydth5.com +ryeex.com +rygits.com +ryjer.com +ryjiaoyu.com +ryjoin.com +rylfj.com +rylinkworld.com +rymcu.com +rymdh.com +rymooc.com +ryone.net +rypeixun.com +rypenwu.com +rysy9191.com +rytad.com +rytx.com +rytyaofang.com +ryweike.com +ryx.store +ryxiut.com +ryxiut.net +ryxkf.com +ryyqh.com +rz-cm.com +rz.com +rz.sb +rz0375.com +rz1158.com +rz520.com +rzaide.com +rzbxgc.com +rzcdc.com +rzcdz2.com +rzfanyi.com +rzfdc.com +rzfyu.com +rzglgc.com +rzhr.com +rzhushou.com +rzhybh.com +rzkj999.com +rzline.com +rzltech.com +rzmeijia.com +rzmoizmk.com +rzok.net +rzport.com +rzrc114.com +rzsf.com +rzspx.com +rzsuetrx.com +rzszp.com +rzv5.com +rzv7.com +rzx.me +rzzyfw.com +s-02.com +s-captcha-r1.com +s-famed.com +s-jl.com +s-ns.com +s-pia.org +s-q-s.net +s-reader.com +s-ss.cc +s-tech.com +s-ts.net +s-xsenyuan.com +s-yue.com +s-zone.com +s.xyz +s.zampdsp.com +s0599.com +s0nnet.com +s10000.com +s135.com +s163.com +s1979.com +s1blsecgerto.com +s1blseclvira.com +s1craft.com +s1gh.com +s1mple.cc +s1mplecode.com +s2ceda.com +s2cinc.com +s2g2b2c.com +s361.com +s369.com +s3s9.com +s3she5k7sm.com +s4g5.com +s4yd.com +s575.com +s57o79552f.com +s5ex.com +s5s5.me +s6uu.com +s72c.com +s74xr605gt.monster +s7y3.com +s8dj.com +s936.com +s9377.com +s98s2.com +s9hospital.com +s9yun.com +sa-ec.com +sa-log.com +sa-tencentclb.cloud +sa-tencentclb.com +sa-tencentclb.net +sa-tencentclb.work +sa-token.cc +sa20.com +sa516gr70.com +sa96.com +saaas.com +saagasports.com +saasddos.com +saasops.tech +saasruanjian.com +saasta.net +saaswaf.com +saayaa.com +saberqq.com +sabxg.com +sac-china.com +sacdr.net +sachenpharm.com +sact-digital.com +sadidc.com +sae-china.org +saebbs.com +saec.cc +saegedu.com +saen.com +saf158.com +safbon.com +safdsafea.com +safe-lb.com +safeb2b.com +safecenter.com +safedocumentview.com +safeglp.com +safehoo.com +safejmp.com +safejmp.net +safeluck.com +safemini.club +safeneeds.com +safenext.com +safetyimg.com +safetystatic.com +safetyvod.com +safround.com +sagepub.com +sagewc-exp.com +sagigame.net +sagsaas.com +sagw.com +sahcqmu.com +saheo.com +sahvyw8.sbs +saibeiip.com +saibeinews.com +saibo.com +saiboauto.com +saiboyy.com +saic-audi.mobi +saic-finance.com +saic-gm.com +saic-group.com +saicdh.com +saicdt.com +saicfinance.com +saicgmac.com +saicgmf.com +saicgroup.com +saichenglogistics.com +saicjg.com +saicmaxus.com +saicmg.com +saicmobility.com +saicmotor.com +saicyun.com +saiczd.com +saiday.com +saidouwang.com +saiduo888.com +saige.com +saihu.com +saihuahong.com +saihuitong.com +saike.com +saikerept.com +saikr.com +sail-lab.net +sail.name +sail2world.com +sailaweiwangluo.com +sailfansclub.com +saili.science +sailingyun.com +sailipaint.com +sailongmetal.com +sailrnal.com +sailungroup.com +sailunkeji.com +sailuntire.com +sailway-china.com +saiminprecision.com +saimogroup.com +saimoliku.com +sainacoffee.com +saintcos.hk +sainteco.com +saintgreenchem.com +saintic.com +saintyear.com +saipujianshen.com +saipujiaoyu.com +sairaicc.com +sairui020.com +saisaiwa.com +saitenm.com +saiterobot.com +saivsi.com +saiway.com +saiyou999.com +saiyouedu.net +saiyun.net +saiyunyx.com +saizhi.com +saj110.com +sajs.com +sakata.one +saki.cc +sakura.vin +sakura286.ink +sakway.com +saky.site +salabs.org +saladvideo.com +salamatcharity.org +salasolo.com +sale8.com +saleenauto.com +saleforin.com +salesdish.com +salesman-bd.com +salg-sichuanair.com +saliai.com +salogs.com +salongweb.com +salutecc.asia +sam-tec.com +samanhua.net +samanlehua.com +samasty.com +same-tech.com +samebar.com +samedayusdtcasino.com +sameled.com +samhotele.com +saming.com +samirchen.com +samite.cc +samitead.com +samool.com +sampux.com +samsph.com +samsrchina.com +samsuncn.net +samsunganycar.com +samsungcloudcn.com +samsungconnectivity.com +samsunghealthcn.com +samsungroaming.com +samsungyx.com +samton.net +samyang.cc +samyuong.com +samzhe.com +san-health.net +san-mu.com +san-sheng.net +san-tuo.com +san-u.com +san-yang.com +san.net +sanabuy.com +sanaemio.com +sanan-e.com +sananyiliao.com +sanau.com +sanbaiyun.com +sanbanggs.com +sanbangwt.com +sanbao-steel.com +sanbao0563.com +sanbum.com +sancaiheast.com +sancanal.com +sanchuangke.com +sancov.com +sandaha.com +sandai.net +sandbean.com +sandcomp.com +sandeepin.com +sandegroup.com +sandinggas.com +sandload.com +sanduoyun.com +sanen.online +sanfangshun.com +sanfen666.com +sanfengyun.com +sanfer.com +sanfi.com +sanfinehospital.com +sanfo.com +sanfu.com +sangaopatent.com +sangbang.com +sangem.com +sangerbio.com +sangfor.com +sangfor.net +sangfor.org +sangforcloud.com +sangfordns.com +sangle.com +sangmifort.com +sangon.com +sangongzai.net +sangsir.com +sangsongtech.com +sangumc.com +sanguocard.com +sanguoh5.com +sanguohero.com +sanguoq.com +sanguosha.com +sanguows.com +sanguowudi.com +sanguozz.com +sangxingxi.com +sangxuesheng.com +sanhao.com +sanhaoradio.com +sanhaostreet.com +sanhe-medical.com +sanhepile.com +sanheqin.com +sanhetimburly.com +sanheyongjia.com +sanhome.com +sanhuagroup.com +sanhuan.com +sanhucidiao.cc +saniwaveltd.com +sanjiahospital.com +sanjiang.com +sanjiangdai.com +sanjiangtourism.com +sanjiasoft.com +sanjieke.com +sanjiexc.com +sanjinjiake.com +sanjinpufa.com +sanjiusk.net +sanjiuxs.com +sanjun.com +sankengriji.com +sanki-e.com +sanki-suzhou.com +sankki.com +sankougift.com +sankton.com +sankuai.com +sankumao.com +sanlan123.com +sanlei.net +sanlengbio.com +sanlian-group.com +sanlian-machine.com +sanlianpump.com +sanligm.com +sanliwenhua.com +sanlovalve.com +sanmanuela.com +sanmanuela.net +sanmao.com +sanmaoyou.com +sanmiaocdn.com +sanmicun.com +sannewschool.com +sanniaokeji.com +sanpowergroup.com +sanpuzhiyao.com +sanqianzhihui.com +sanqin.com +sanqindaily.com +sanqinyou.com +sanqiu.org +sanquan.com +sanrangas.com +sanrenwenku.com +sanritzgroup.com +sansancloud.com +sansanyun.com +sansg.com +sanshanwuyuan.org +sanshiok.com +sanshua.com +sansitech.com +sansky.net +santaihu.com +santanjob.com +santelvxing.com +santezjy.com +santianfilter.net +santiego.ink +santiyun.com +santongit.com +santostang.com +sanvo.com +sanway.tech +sanweihou.com +sanweimoxing.com +sanweiyiti.org +sanweiyunfuwu.com +sanwen.com +sanwen.net +sanwen8.com +sanwer.com +sanxao.com +sanxia-china.com +sanxia.com +sanxiamc.com +sanxiao56.com +sanxiaomingshi.com +sanxiapharm.com +sanxige.com +sanxin-med.com +sanxinbook.com +sanxing.com +sanxinwin.com +sanxinzgjx.com +sanyaairport.com +sanyachloe.com +sanyajob.com +sanyamotor.com +sanyanblockchain.com +sanyangma.com +sanyastar.com +sanyawater.com +sanyecao.com +sanyegame.com +sanyenet.com +sanyewu.com +sanyexin.com +sanyglobal.com +sanygroup.com +sanyhi.com +sanyibao.com +sanyichemical.com +sanyipos.com +sanyou123.com +sanyouco.com +sanyoumed.com +sanyoutj.com +sanyuanbaobao.com +sanyuanqian.com +sanyuantc.com +sanyuanzn.com +sanyue.com +sanyuesha.com +sanzangwang.com +sanzao.xyz +sanzei.com +sanzer.com +sanzhimeihua.com +sanzijing.org +sanzinfo.com +sanzkf.com +sao-ma.com +sao-tencentclb.cloud +sao-tencentclb.com +sao-tencentclb.net +sao-tencentclb.work +sao.ren +saohua.com +saoic.com +saolei123.com +saolife.com +saomadc.com +saomadiancan.com +saoniuhuo.com +saop.cc +saoshu.org +saoso.com +saowen.net +saoztfii.com +sap-nj.com +sap1000.com +sapphiretech.store +saraba1st.com +sardchina-lmgt.com +sarft.net +sarosgame.com +sasacity.com +sasecurity.com +sass.hk +sasscss.com +sasseur.com +sasseur1989.com +sassi2956.xyz +sast.fun +sast.net +sat0.net +satcomiot.com +satgssb.com +sating-tech.com +sator.tech +satpro.com +satrip.com +saturdaysoft.com +saturnbird.com +saublenew.com +savastan0.biz +savilehotelgroup.com +savokiss.com +savouer.com +sawenow.com +sawuatsurgical.com +saxydc.com +saxyit.com +sayabear.com +sayatoo.com +sayll.com +saylover.com +sayloving.com +sayodevice.com +saywash.com +sayyas.com +sazeoq8158.vip +sb1secapply4.com +sbaoe.com +sbc-mcc.com +sbf56.com +sbh15.com +sbhimalayanml.com +sbjd88.com +sbjxyq.com +sbk-h5.com +sbkh5.com +sbkk8.com +sbl-ruseldau.com +sblseceorf.com +sblsechuorb3.net +sblsecorgan.com +sbmscs.com +sbnkca.com +sbnkjl.com +sbo2.com +sbooktxt.com +sbpiping.com +sbr-info.com +sbrczx.com +sbs-mag.com +sbscn.com +sbsjk.com +sbt-sh.com +sbt56.com +sbtjt.com +sbtzy.net +sbwl.com +sbwxz.com +sbxh.org +sbycjy.com +sbzj.com +sc-001.net +sc-aaa.com +sc-admc.com +sc-dl.com +sc-edu.com +sc-glas.com +sc-hstar.com +sc-jiaoyu.com +sc-pd.com +sc-tianyu.com +sc-troy.com +sc-wx.com +sc-xngs.com +sc.gg +sc115.com +sc119.cc +sc157.com +sc1588.com +sc1618.com +sc168.com +sc2c.com +sc2car.com +sc2p.com +sc2yun.com +sc518.com +sc666.com +sc788.com +sc946.com +sc96655.com +scaffi.com +scagz.com +scanservice1.qcpp1.net +scansmt.com +scanv.com +scarbbs.com +scarclinic-cn.com +scardtech.com +scarlet-box.com +scasqhwz.com +scatc.net +scavc.com +scbaidu.com +scbaijia.com +scbao.com +scbaopo.org +scbgaudio.com +scbh15.com +scbid.com +scbnrq.com +scbotai.com +scbuilder.com +scbxmr.com +scbyx.net +sccbj.com +sccchina.net +scccyts.com +sccea.net +sccens.net +sccia8888.com +sccin.com +sccita.org +sccjjtjy.com +scclssj.com +scclzn.com +sccm.cc +sccmlj.com +sccnfb.com +sccnn.com +sccnnc.com +sccq.net +scctjywy.com +sccts.com +scctsw.com +sccvc.com +sccwz.com +sccxbe.com +sccyxh.com +scdanzhao.net +scdbzzw.com +scdccb.com +scdcs.net +scdengbang.com +scdn.im +scdn.io +scdn0077.com +scdn08xd.com +scdn0wcp.com +scdn0wes.com +scdn0xks.com +scdn10a7.com +scdn12zo.com +scdn1dcz.com +scdn1e8v.com +scdn1eul.com +scdn1kjh.com +scdn2kw9.com +scdn2lhh.com +scdn323r.com +scdn3t09.com +scdn40kn.com +scdn43uu.com +scdn46r9.com +scdn4cpe.com +scdn4esv.com +scdn4iy4.com +scdn4usw.com +scdn549v.com +scdn67mw.com +scdn6e40.com +scdn7c4e.com +scdn7gsf.com +scdn7ma2.com +scdn8ksq.com +scdn8ppt.com +scdn98um.com +scdnacsj.com +scdnazo0.com +scdnbi9w.com +scdnbiar.com +scdnc77s.com +scdncloud.com +scdndn0v.com +scdndns.com +scdndns.net +scdndsa6.com +scdndtma.com +scdne3lt.com +scdne60t.com +scdneb5k.com +scdnebrq.com +scdneufe.com +scdnf3v6.com +scdnf80r.com +scdnfu51.com +scdng8js.com +scdnga.com +scdnga.net +scdngc.com +scdngc.net +scdngs0h.com +scdnguqg.com +scdnh957.com +scdnhagn.com +scdnhfua.com +scdnhou6.com +scdnhwc.com +scdnifld.com +scdnioyt.com +scdnirdl.com +scdnj3in.com +scdnj8do.com +scdnjfj2.com +scdnjk59.com +scdnkeuo.com +scdnl05m.com +scdnl3bk.com +scdnl46h.com +scdnl9cm.com +scdnmba2.com +scdnmnrz.com +scdnmo3m.com +scdnmogt.com +scdnmskl.com +scdnn4t9.com +scdnndj2.com +scdnnm9o.com +scdnnrib.com +scdnnub6.com +scdno55z.com +scdno5zl.com +scdnoklx.com +scdnokqh.com +scdnooyg.com +scdnpe31.com +scdnq6rc.com +scdnqjg9.com +scdnqkxi.com +scdnqo8s.com +scdnqrty.com +scdnqumc.com +scdnr7p2.com +scdnr932.com +scdnrlm1.com +scdnrvy1.com +scdnsmjc.com +scdnsvg4.com +scdnt1h7.com +scdnt9n9.com +scdntop.com +scdntucs.com +scdntxla.com +scdnucc5.com +scdnukio.com +scdnulx9.com +scdnurea.com +scdnv7uq.com +scdnvij7.com +scdnvip.com +scdnw4kb.com +scdnwehb.com +scdnwljp.com +scdnwmp0.com +scdnwpqy.com +scdnwwp9.com +scdnxgev.com +scdny1t3.com +scdnydiw.com +scdnygb7.com +scdnywwp.com +scdnzrch.com +scdri.com +scdyjyzx.com +scdytv.com +scdyzx.com +scdz120.com +scdzmw.com +sce-re.com +scea.co +sceci.net +sceeo.com +sceia.org +scemrq.com +scene7-cdn.dell.com +scengine.com +scenictc.com +scensmart.com +scetop.com +scezju.com +scflcp.com +scfsino.com +scfzbs.com +scg-archi.com +scgc.net +scgchc.com +scgckj.com +scgglm.com +scgh114.com +scghsd.com +scghseed.com +scgis.net +scgj56.net +scgkw.net +scgra.com +scgxhq.com +scgxlc.com +scgyjt.com +scgzyun.com +sch-szu.com +schbrain.com +schbrilliant.com +schcnc.com +schdxww.com +schengle.com +schielecn.com +schimalayanuz.com +schk777.com +schkxy.com +schlzn.com +schneidercampus.com +scholarmate.com +scholat.com +school51.com +school888.com +schoolinweb.com +schoolpi.net +schoopia.com +schstv.com +scht.cc +schwarzeni.com +schwr.com +schxzx.com +sci-bioland.com +sci-fifans.net +sci-gz.com +sci-hub.ee +sci-hub.shop +sci-inv.com +sci-it.com +sci99.com +scialyze.com +scianet.org +sciasc.com +scichina.com +scicn.net +scidict.org +sciecure.com +sciedu.org +sciencecity.net +sciencedirect.com +sciencehr.net +sciencep.com +sciengine.com +scienjus.com +scientop.com +scientrans.com +scienward.net +scies.org +scievent.com +scifans.com +scigy.com +sciimg.com +sciirc.com +scijet.com +scilucy.com +scimall.cc +scimall.org +scimao.com +scimee.com +scinormem.com +scinorwater.com +scio.icu +sciping.com +sciscanpub.com +scisky.com +scistor.com +scisun.com +scitechoutlet.com +scitycase.com +scixh.com +sciyard.com +sciyon.com +scjcce.com +scjcdl.com +scjhg.com +scjhhb.com +scjhyq.com +scjjdd.com +scjjn.com +scjjrb.com +scjk.com +scjmm.com +scjrm.com +scjty.com +scjuchuang.com +scjygd.com +scjyx.com +scjyxw.com +scjyzb.net +scjyzbxh.com +scjz-led.com +scjzjyjc.com +scjzy.net +sckje.com +sckrskj.com +sckxjd.com +scl-cn.com +sclanyingkj.com +sclf.org +scll.cc +scloudgda.com +sclrjc.com +sclsnk.com +sclssz.com +sclsyz.com +sclvb.com +sclyxw.com +sclzfq.com +scm121.com +scmccboss.com +scmchem.com +scmfair.com +scmor.com +scmroad.com +scmsky.com +scmttec.com +scmxtv.com +scmy120.com +scmydb.com +scmylike.com +scmyns.com +scncbus.com +scncgz.net +scncrc.com +scnj.tv +scnjnews.com +scnjw.com +scnleee.com +scntv.com +scntzjrqfd.com +scnufl.com +scnyw.com +sco-marathon.com +scodereview.com +scoee.com +scommander.com +scomper.me +scoowx.com +scopus.com +scoregg.com +scowqbfk.com +scpgj.com +scpgroup.com +scpidi.com +scpolicec.com +scqckypw.com +scqcp.com +scqjxh.com +scqstv.com +scqy100.com +scraij.com +scrape.center +scratch5.com +scratchmirror.com +scratchmirror.net +scrc168.com +scrcnet.org +scrcu.com +scredcross.com +scrft.com +scriptjc.com +scrmtech.com +scrqw.com +scrsw.net +scrsy.net +scrumcn.com +scs-jianyu.com +scscms.com +scsddyf.com +scsdzxh.org +scsdzzx.com +scsema.com +scsfjt.com +scsgkyy.com +scshzx.com +scsia.org +scsjnxh.org +scsjsd.com +scslfd.com +scsltjt.com +scsmzy.com +scsntv.com +scssdd.com +scsstjt.com +scsuhuigy.com +scswyy.com +scsxth.com +scsyaszyyy.com +scsyytj.com +scszsw.com +scszxy.com +sctbc.net +sctcd.com +sctcm120.com +sctdzl.com +sctes.com +sctfia.com +sctfleasing.com +sctgo.com +sctindustries.com +sctm.cc +sctobacco.com +sctodr.com +sctszh.com +scttwy.com +sctv-tf.com +sctv.com +sctvcloud.com +sctvf.com +sctvgo.com +sctx.com +sctyhx.com +sctyxy.net +sctzsbhy.com +scubamew.com +scudcn.com +scufida.com +scujj.com +scunionpay.com +scusec.org +scutech.com +scutedu.org +scuvc.com +scw98.com +scwdwl.com +scwhx.com +scwj.net +scwlylqx.com +scwmwl.com +scwqxh.com +scwy.net +scwyzx.com +scxd56.net +scxdf.com +scxinkang.com +scxjyw.com +scxsls.com +scyanzu.com +scyarui.com +scybjc.com +scybxx.com +scyc.cc +scych.org +scyesz.com +scyf.xyz +scylzx.net +scymob.com +scyongqin.com +scyqfhw.com +scyqjs.com +scysxh.org +scytyy.net +scyvu.org +scyxcm.com +scyyhyxh.com +scyyxh.com +sczg.com +sczgzb.com +sczht.com +sczlsgs.com +sczshz.net +sczsie.com +sczsxx.com +sczuanshen.com +sczw.com +sczxmr.com +sczycp.com +sczyh30.com +sczytx.com +sd-cancer.com +sd-cellbank.com +sd-chengdasteel.com +sd-chengde.com +sd-eh.com +sd-ex.com +sd-fjzy.com +sd-gold.com +sd-gree.com +sd-guotai.com +sd-jiuyang.com +sd-jnyz.com +sd-kb.com +sd-keyuan.com +sd-nand.com +sd-port.com +sd-portfh.com +sd-rtn.com +sd-sangte.com +sd-sanju.com +sd-sma.com +sd-xd.net +sd-xingshun.com +sd-yihao.com +sd-ysjt.com +sd001.com +sd11185.com +sd173.com +sd2000.com +sd2008.cc +sd235.com +sd235.net +sd5g.com +sdacid.com +sdailong.com +sdaofu.com +sdapo.net +sdaswq.com +sdawhuagong.com +sdaxue.com +sdazgs.com +sdbao.com +sdbaoding.com +sdbaowei.com +sdbeidou.com +sdbeta.com +sdbetter.com +sdbgk.com +sdbjm.com +sdbkxh.com +sdbochen.net +sdbqfw.com +sdbx.org +sdbys.com +sdca119.com +sdcbcm.com +sdcbcnc.com +sdccg.com +sdcclh.com +sdcfdq.net +sdcgc.com +sdchelv.com +sdchem.net +sdcheshi.com +sdchild.com +sdchina.com +sdchuangyi.com +sdcia.net +sdcjtz.com +sdclimber.com +sdcmc.net +sdcoke.com +sdcpd.com +sdcqjy.com +sdcqjyjt.com +sdcxgk.com +sdcxjl.com +sdcxslzj.com +sdcyun.com +sdcz.com +sddagongrubber.com +sddaqi.com +sddcbz.com +sddcp.com +sddcxm.com +sddep.com +sddermyy.com +sddeznsm.com +sddfnk.com +sddhpharm.com +sddory.com +sddp.net +sddstore.com +sddtzx.com +sdduojing.com +sddyfxjc.com +sddyzl.com +sddyzy.com +sddzinfo.com +sddzrljx.com +sdebank.com +sdeca.org +sdeclhnfz.com +sdecloud.com +sdecu.com +sdecx.com +sdedu.net +sdedubook.com +sdeer.com +sdeerlive.com +sdenews.com +sdepci.com +sdepi.com +sderp.com +sdewj.com +sdey.net +sdeyei-h.edu +sdfeid.com +sdfey.com +sdffqaz.com +sdfhyl.com +sdflc.com +sdflon.com +sdfon.com +sdfscm.com +sdfscx.com +sdftc.com +sdfuer.net +sdfxyoule.com +sdfybj.com +sdfz.net +sdfztz.com +sdg-china.com +sdg53.com +sdgakj.com +sdgckg.com +sdgdwljt.com +sdgdxt.com +sdgh.net +sdgho.com +sdghrq.com +sdghtz.com +sdghzy.net +sdglobaltrade.com +sdglql.com +sdgmjiaoyun.com +sdgren.com +sdgsdggg.xyz +sdgsgcjsjt.com +sdgsjc.com +sdgslb.com +sdgslbc.com +sdgslbd.com +sdgswl.com +sdgsxcljt.com +sdgsxxjt.com +sdgt1985.com +sdguanfeng.com +sdguanzhou.com +sdguguo.com +sdgw.com +sdgwlc.com +sdgwy.org +sdgxdb.com +sdgxzn.com +sdgykg.com +sdgyslfz.com +sdgzkg.com +sdhack.com +sdhbcl.com +sdhdssd.com +sdhead.com +sdheguogroup.com +sdhengxingroup.com +sdhfsh.com +sdhgu.com +sdhitg.com +sdhmdp.com +sdhmjt.net +sdhmkj.com +sdhnt.com +sdhofa.com +sdholding.com +sdhongdaglass.com +sdhoukang.com +sdhqcp.com +sdhqedu.net +sdhrjt.net +sdhsg.com +sdhshbgs.com +sdhsie.com +sdhslqgj.com +sdhsrh.com +sdhssfjt.com +sdht666.com +sdhtkt.com +sdhtwl.com +sdhualigongshui.com +sdhuanneng.com +sdhxem.com +sdhxf.com +sdhxjl.com +sdhxsj.com +sdhydl.com +sdhynytc.com +sdhz12333.com +sdhzgs.com +sdi23.com +sdiandian.com +sdiccapital.com +sdicgdny.com +sdicgxxny.com +sdicin.com +sdicpower.com +sdicqzdefd.com +sdictktrust.com +sdictrade.com +sdicvc.com +sdigc.com +sdiitu.com +sdinfo.net +sdiread.com +sditol.com +sdj-tech.com +sdj88.com +sdjcf.com +sdjcsh.com +sdjcw.com +sdjiance.com +sdjiankan.com +sdjianmei.com +sdjingdao.com +sdjinghan.com +sdjinhuihb.com +sdjinke.com +sdjkdq.com +sdjky.com +sdjlxh.com +sdjnlf.com +sdjnwx.com +sdjrg.com +sdjsen.com +sdjtbd.com +sdjtcx.com +sdjtzyxy.com +sdjujiang.com +sdjuliangnet.com +sdjulong.net +sdjuming.com +sdjuxiang.com +sdjwg.com +sdjxgj.com +sdjys.org +sdjzgt.com +sdjzhc.com +sdjzsemi.com +sdkamaiduo.com +sdkbalance.com +sdkdch.com +sdkeli.com +sdkjjt.com +sdkjnn.com +sdklh.com +sdklss.work +sdknext.com +sdkserver.com +sdksrv.com +sdlaien.com +sdland-sea.com +sdland-sea.net +sdlcbyq.com +sdlfhbkj.com +sdlgjycm.com +sdlinqu.com +sdlivc.com +sdljdj.com +sdlkqx.com +sdllrc.com +sdlmzb.com +sdlongli.com +sdlookchemical.com +sdlqgf.com +sdlsgroup.com +sdlsjszp.com +sdlsxrmyy.com +sdludian.com +sdluqiao.com +sdlvbang.com +sdlvjuren.com +sdlvtai.com +sdlvxing.com +sdlxsj.com +sdly35.com +sdlyjygs.com +sdlysz.com +sdm0377.com +sdmctech.com +sdmdcm.com +sdmecl.com +sdmic.com +sdmingquan.com +sdmingshan.com +sdmjkc.com +sdmta.com +sdmtfy.com +sdmuhua.com +sdmuseum.com +sdmyzsgs.com +sdn-global-live-streaming-packager-cache-3qsdn.akamaized.net +sdndzb.com +sdnfv.org +sdnh.net +sdnjsbc.com +sdnlab.com +sdnsbd.com +sdnxs.com +sdnydb.com +sdo-shabake.com +sdo.com +sdocapp.com +sdodk.com +sdodo.com +sdointl.com +sdoke.com +sdongpo.com +sdoprofile.com +sdoyhg.com +sdpag.com +sdpea.org +sdpku.com +sdplt.com +sdptem.com +sdpua.com +sdpxyq.com +sdqcgs.com +sdqcpc.com +sdqljh.com +sdqlkr.com +sdqmy.com +sdqsqx.com +sdqte.com +sdqu.com +sdqyjtzfzcjh.com +sdqyslt.com +sdrail.com +sdrcu.com +sdricom.com +sdrixingchem.com +sdrmyy.com +sdrongya.com +sdrszp.com +sdrtgk.com +sdruile.com +sdruiqi.com +sdrunfujia.com +sdrunse.com +sdrxtf.com +sdrz12333.com +sdsaifute.com +sdsalt.com +sdsansen.com +sdsazgs.com +sdsazxh.com +sdsbjp.com +sdschdlxxhyxh.com +sdsdbjt.com +sdsdiy.com +sdsdjxh.com +sdsdsoft.com +sdsdzx.com +sdsenrong.com +sdseshealth.com +sdsfjy.com +sdsgwy.com +sdshangya.com +sdshgk.com +sdshihua.com +sdshitu.com +sdshshb.com +sdsifang.net +sdsihuanpharm.com +sdsinometal.com +sdsj.com +sdsjhhyxh.com +sdsjzyxh.com +sdsldsyy.com +sdsmartlogistics.com +sdsmefina.com +sdspyyy.com +sdsrhb.com +sdssiliao.com +sdstdc.com +sdsteelrz.com +sdstet.com +sdstg.com +sdstrong.com +sdstslyy.com +sdstudy.vip +sdswitch.com +sdswtz.com +sdsxw.com +sdsxwz.net +sdsytgcl.com +sdsyyxh.com +sdszbzz.com +sdtadm.com +sdtaikai.com +sdtcck.com +sdtdata.com +sdtdfz.com +sdteleiptv.com +sdtender.com +sdteya.com +sdtianjing.com +sdtkgl.com +sdtlpm.com +sdtlyyjt.com +sdtryyjt.com +sdtugongbucj.com +sdtvjiankang.com +sdtwxx.com +sdtxmq.com +sdtylq.net +sdtzcn.com +sdtzsb.net +sdu8cvc.com +sduept.com +sduod.com +sdushu.com +sdvps.com +sdwan.work +sdwcpm.com +sdwdhj.com +sdwdxl.com +sdweiji.com +sdweima.com +sdweiye.com +sdwen.com +sdwenlian.com +sdwenlv.com +sdwfvc.com +sdwgyy.com +sdwinnerbio.com +sdwkhvac.com +sdwljqtzjt.com +sdwlsym.com +sdwscgs.com +sdwtd.com +sdwtqqysj.com +sdwtqx.com +sdwtyy.com +sdx.microsoft.com +sdxawy.com +sdxgty.com +sdxhce.com +sdxhjtgs.com +sdxianweisumi.com +sdxiaoman.com +sdxietong.com +sdxinboao.com +sdxinglu.com +sdxingya.com +sdxjnrqjt.com +sdxjpc.com +sdxl.com +sdxli.win +sdxlkjgf.com +sdxnetcafe.com +sdxsgas.com +sdxszhny.com +sdxszs.com +sdxtsz.com +sdxtxh.com +sdxvisa.com +sdxwyy.net +sdxxjmgg.com +sdxyxhj.com +sdxzt.com +sdyftr.com +sdyhne.com +sdyhqp.com +sdyifeng.com +sdyinshuachang.com +sdyizhibi.com +sdylhg.com +sdyndcjx.com +sdysjcc.com +sdyuanbao.com +sdyxmall.com +sdyyebh010.com +sdyyjsxy.com +sdyypt.net +sdyzzyzdh.com +sdzamy.com +sdzbcg.com +sdzckj.com +sdzdb.com +sdzdxm.com +sdzgfj.com +sdzhidian.com +sdzhongjiu.com +sdzhx.com +sdzhxk.com +sdzjxx.com +sdzk.co +sdzktd.com +sdznlh.com +sdznzx.com +sdzpw.com +sdzpw.net +sdzrm.com +sdzs.com +sdzssj.com +sdzsyl.com +sdztkj.com +sdztxxkj.com +sdzx.net +sdzydfy.com +sdzzdzkj.com +se7ej39i9g.best +sea-group.org +sea-gullmall.com +seaarea.com +seacatcry.com +seacxy.com +seafile.com +seaflysoft.com +seafrom.com +seagull-digital.com +seagullwatch.com +seagullwatches.com +seahisun.com +seaide.com +sealaly.net +sealand100.com +sealandtableware.com +sealeadbattery.com +sealien.net +sealimg.com +sealion360.com +sealos.run +sealyun.com +seamanhome.com +seamaty.com +seaning.com +seanya.com +seanyxie.com +seaps.org +seapsoft.com +search616.com +searcheasy.net +searchpstatp.com +searchstatic.com +searchtb.com +searchtoutiaolive.com +seashinepm.com +seasj.com +seaskyapp.com +seasonperiod.com +seasouthgy.com +seassoon.com +seastarasset.com +seasungame.com +seasungames.com +seasunwbl.com +seatent.com +seatonjiang.com +seatopcq.com +seavalve.com +seavo.com +seawardhyacinth.com +seayao.net +seayee.com +seayoo.com +seayooassets.com +seazor.com +seb.sason.top +seblong.com +sebug.net +sec-in.com +sec-mail.cloud +sec-motor.com +sec-wiki.com +secaibi.com +secbug.cc +secbug.org +seccw.com +secdoctor.com +secdriver.com +secec.com +secfree.com +secisland.com +secjia.com +seclover.com +seco-rukutin-co-jp.com +secoo.com +secooart.com +secooimg.com +secote.com +secpulse.com +secretflow.com +secretgardenresorts.com +secretmine.net +secrss.com +secrui.com +secshow.net +secsib-eliaslias.com +secsib-kendal.com +secsilo.com +sectigochina.com +sectigochina.com.cdn.cloudflare.net +secu100.net +secure-83a.com +secure-ch-ase03.online +secure-chasle026.ink +secure-chasle029.wiki +secure-chasle039.wiki +secure-chasle049.ink +secureqin.net +securitycn.net +securityeb.com +securityinsight.com +secutimes.com +secwk.com +secwx.com +secxun.com +seducix.com +see-far.com +see-source.com +see100n.com +seebeautymedia.com +seebon.com +seebug.org +seecmedia.net +seed-china.com +seedasdan.org +seedchina.com +seeddsp.com +seedit.cc +seedit.com +seedland.cc +seedlandss.com +seedpace.com +seedsufe.com +seeed.cc +seegif.com +seehealth.net +seehu.net +seek114.com +seekbetter.me +seekchem.com +seekcy.com +seekfunbook.com +seekhill.com +seekingsoft.com +seeklane.com +seekswan.com +seekwavetech.com +seelvyou.com +seemmo.com +seemse.com +seentao.com +seepomotor.com +seepomotor.net +seerbigdata.com +seerking.com +seermylife.com +seersecret.com +seesawcoffee.com +seesea.site +seeseed.com +seetacloud.com +seetao.com +seetong.com +seewellintl.net +seewin-edu.com +seewo.com +seewoedu.com +seewoll.com +seexpo.com +seeya-tech.com +seeyii.com +seeyon.com +seeyonoversea.com +seeyouhealth.com +seeyouweb.com +seeyouyima.com +sefonsoft.com +segacnsh.com +segapi.com +segbuy.com +segmentfault.com +segmentfault.net +segotep.com +segwayrobotics.com +sehand.com +sehimalayanqj.com +seida.tech +seijoin.com +seilway.com +seily.com +seirobotics.net +seis-jun.xyz +seisman.info +seiyuex.com +sejai.com +sejianghu.com +sekede.net +sekorm.com +selboo.com +selectdataset.com +selenlictio.com +selet4.com +selfiecity.com +selfservicechina.com +selfwhostudio.com +selgrospl.com +selinuxplus.com +sellerspace.com +sellersprite.com +sellfox.com +sellingexpress.net +selypan.com +sem123.com +sem17.com +semem99.com +semeye.com +semgz.com +semi-casi.com +semi.design +semiconductorpower.com +semiconshop.com +semidata.info +semiee.com +semight.com +semigraph.net +semiinsights.com +semir.com +semiway.com +semiwebs.com +sempk.com +semptian.com +semsay.com +semw-sh.com +senaocargo.com +senbeijia.com +sencdn.com +sencha-china.com +senco.cc +sencomu.com +send2boox.com +senda360.com +sendbp.com +sendcloud.net +sendcloud.org +senderline.com +senderline.net +sendestar.com +sendijt.com +sendong.com +sendpioneer.com +sends.cc +sendsharedfiles.com +senfa.net +senge-dq.com +senge.com +senggama.online +senguo.cc +senguo.com +sengxian.com +sengzai.com +senhai.com +senhaix.com +senhe.com +senior.auto +seniverse.com +senkah.com +senken-international.com +senlianshop.com +senlinjimore.com +senmiaoliuxue.com +senmiaoschool.com +senorsen.com +senpet.com +senphoto.org +senpian.com +senra.me +sensate.hk +sense-hk.com +senseagro.com +senselock.com +senseluxury.com +senser.group +sensertek.com +sensesw.com +sensetime.com +senseyun.com +senshidahengqi.com +sensivo.com +sensors-iot.net +sensorsdata.com +sensorsdatavip.com +senssun.com +senszx.com +sentaihb.com +sentaijs.com +sentaiwpc.com +sentcss.com +sentdream.net +senteauto.com +senthink.com +sentosemi.com +sentuxueyuan.com +sentyeasy.com +senwas.com +senyada.com +senyao1718.com +senyou.com +senypc.com +senyuanhi.com +senyuanzhonggong.com +seo-lv.com +seo.tm +seo1158.com +seo123.net +seo178.com +seo371.com +seo628.com +seobti.com +seocxw.com +seodaniel.com +seofangfa.com +seoipo.com +seokoubei.com +seoqx.com +seosdc.com +seosiguan.com +seosn.com +seotcs.com +seovx.com +seowhy.com +seoxiaoxin.com +seoxuetang.com +sep.cc +sepact.com +sepcc.com +sepco1.com +sepfocus.com +sepimcsemi.com +seppec.com +septinn.com +septwolves-group.com +septwolves.com +sepu.net +sepumps.com +sequ.biz +sequoiacap.com +sequoiadb.com +sereypath.com +serholiu.com +seridc.com +seridoat.com +servasoft.com +serveclouds.com +serverless-devs.com +serverproof.net +service.urchin.com +service86.com +servicemesher.com +servicewechat.com +serviceweixin.com +servilabmedical.com +sesamestreetenglishchina.com +sesamewatermelon.com +sescar.com +sescie.com +seseds.com +sesier.com +setb2b.com +setdg.net +seteuid0.com +setshop.vip +seuic.com +sevb.com +seven-meters.com +seven7777.eu +sevendatas.com +sevenhei.com +sevenseas-china.com +sevensem.com +sevnday.com +sevnz.com +sewise.com +sex291roushipin.wiki +sex2ribenwuma.wiki +sex2xiaoluoli.wiki +sex2yingtaoshipin.wiki +sexytea2013.com +seyoo.net +seyuma-cn.com +sf-airlines.com +sf-auto.com +sf-bearing.com +sf-bsd.com +sf-card.com +sf-china.com +sf-cityrush.com +sf-dsc.com +sf-express.com +sf-financial.com +sf-freight.com +sf-international.com +sf-intra-city.com +sf-jf.com +sf-js.com +sf-laas.com +sf-pay.com +sf-saas.com +sf-zs.net +sf007.com +sf024.com +sf2021.com +sf34.com +sf7.net +sf888.net +sfacg.com +sfadx.com +sfair.com +sfata.com +sfb-100.com +sfbest.com +sfbuy.com +sfc9oyfmqg.work +sfcar.hk +sfccn.com +sfcdn.org +sfcservice.com +sfdiban.com +sfdrums.com +sfdy13168.com +sfdzh.com +sfecr.com +sffdj.com +sfgj.org +sfgy.org +sfhaa.com +sfht.com +sfi-sh.com +sfile2012.com +sfitcdp.com +sfjddna.com +sfjdml.com +sfjsgroup.com +sfjt.co +sfjx888.com +sfkedu.com +sfkj-tech.com +sfkj.vip +sfkjweb.com +sflep.com +sflmfls.com +sflqw.com +sflshz.com +sfmianhua.com +sfndns.com +sforest.in +sfpgmk.com +sfplay.net +sfqzj.com +sfrmt.com +sfs-cn.com +sfsdds.com +sfshuiwu.com +sfsigroup.com +sfsw2000.com +sfsyenergy.com +sftj.net +sftnow.com +sfund.com +sfvip1.com +sfwl.co +sfwljt.com +sfwxf.com +sfy-gmc.com +sfyb.com +sfybee.com +sfydns.com +sfygroup.com +sfys365.com +sfystatic.com +sfzj123.com +sfzk.org +sg-che.com +sg-gemsy.com +sg-gzy.com +sg-micro.com +sg-tencentclb.cloud +sg-tencentclb.com +sg-tencentclb.net +sg-tencentclb.work +sg.work +sg163.com +sg169.com +sg91.net +sgameglobal.com +sgamer.com +sgautomotive.com +sgbll.com +sgccdn.com +sgcctd.com +sgcctop.com +sgcec.com +sgcgis.com +sgchangxun.com +sgchinese.com +sgcqscgu.com +sgcyjy.com +sgda.cc +sge.sh +sgfsm.com +sgjlkyjx.com +sgjq.net +sgjsgf.com +sgjwb.com +sgjy169.com +sgjyq.com +sgla.com +sglituo.com +sgliulian.com +sgllk.com +sgmart.com +sgmlink.com +sgmsonline.com +sgmw.com +sgmwlu.com +sgmwsales.com +sgnet.cc +sgou.com +sgpjbg.com +sgplink.xyz +sgpsea.com +sgqd.com +sgqqxh.org +sgrastudio.com +sgrbcm.com +sgrcw.com +sgrsvakz.com +sgshero.com +sgshuyuan.com +sgsic.com +sgsotools.com +sgst.prod.dl.playstation.net +sgsugou.com +sgsxw.com +sgsxybiz.com +sgsyxx.net +sgt21.com +sgthzb.com +sgtmos.com +sguo.com +sgvalve.com +sgvbot.com +sgwjjc.com +sgwk.info +sgy-it.com +sgyaogan.com +sgyeyou.com +sgyhux.com +sgyouxi.com +sgyscom.com +sgyzyun.club +sgzb2.com +sgzm.com +sgzww.com +sgzww.net +sgzxedu.com +sh-3ai.com +sh-agilebot.com +sh-aia.com +sh-anfang.org +sh-anrong.com +sh-aquarium.com +sh-arpm.com +sh-autofair.com +sh-azjiadeli.com +sh-baolai.com +sh-biobond.com +sh-chenghuan.com +sh-chimbusco.com +sh-datastone.com +sh-deem.com +sh-delixi.com +sh-desu.com +sh-dongbiao.com +sh-eastwes.com +sh-edi.com +sh-eshow.com +sh-fdtw.com +sh-fxgz.com +sh-fy.com +sh-game.com +sh-gelanlishi.com +sh-gexing.com +sh-gsg.com +sh-henderson-metropolitan.com +sh-hengyuan.com +sh-hilead.com +sh-hitech.com +sh-hlrubber.com +sh-holfer.com +sh-holiday.com +sh-hs.com +sh-hting.com +sh-huate.com +sh-huayang.com +sh-hwbaoan.com +sh-hywin.com +sh-italent.com +sh-iwatani.com +sh-jiapeng.com +sh-jingjin.com +sh-jinxiang.com +sh-jjsb.com +sh-jkyy.com +sh-jzgroup.com +sh-kechen.com +sh-kelai.com +sh-kingsun.com +sh-kr.net +sh-lengdong.com +sh-liangxin.com +sh-likun.com +sh-livemusic.com +sh-meluck.com +sh-minghui.com +sh-ncn.com +sh-nemoto.com +sh-oca.com +sh-pet.com +sh-pn.com +sh-pp.com +sh-printing.com +sh-prosperity.com +sh-prosun.com +sh-putai.com +sh-puwei.com +sh-real.com +sh-recycle.org +sh-rfid.com +sh-ryjx.com +sh-saic.com +sh-sed.com +sh-service.com +sh-sfc.com +sh-sgl.com +sh-shenming.com +sh-shuguang.com +sh-sict.com +sh-sinodiet.com +sh-smartstate.com +sh-soa.com +sh-srcb.com +sh-ssci.com +sh-tangfeng.com +sh-tayor.com +sh-tencentclb.cloud +sh-tencentclb.com +sh-tencentclb.net +sh-tencentclb.work +sh-ticket.com +sh-tm.com +sh-valve.com +sh-warwick.com +sh-web.net +sh-xinao.com +sh-xixuan.com +sh-yajia.com +sh-yano.com +sh-ybxhz.com +sh-yichen.com +sh-yuai.com +sh-yuy.com +sh-zbfm.com +sh002.com +sh1011.com +sh112.com +sh12320.com +sh148.org +sh17.com +sh1nk1n-shokd.com +sh1nk1n-shokf.com +sh414.com +sh4th.com +sh51766.com +sh5mcc.com +sh5y.com +sh600696.com +sh601200.com +sh83.xyz +sh8y.com +sh91.com +sh9130.com +sh9156.com +sha-steel-yx.com +sha-steel.com +sha2777.com +sha990.com +shaaidata.com +shaangu.com +shaanxigas.com +shaanxiiot.com +shaanxirk.com +shaanxita.com +shaanyaogroup.com +shabc.com +shabc.net +shabidding.com +shabiyun.com +shachong8.com +shacumox.com +shadafang.com +shadc-tencentclb.cloud +shadc-tencentclb.com +shadc-tencentclb.net +shadc-tencentclb.work +shaddockfishing.com +shadiao.pro +shaduizi.com +shaduruanjian8.com +shafa.com +shafaguanjia.com +shagangcapital.com +shagyy.com +shaidc.com +shairport.com +shaisino.com +shaizai.com +shajdog.com +shajuta.com +shakingcloud.com +shala99.com +shalashike.com +shalfoil.com +shall-buy.com +shallserve.cc +shamiao.com +shan-yu-tech.com +shan.com +shanbay.com +shanbotv.com +shancemall.com +shanchuangjiaoyu.com +shancui1688.com +shanda960.com +shandacasual.com +shandacasual.net +shandagames.com +shandaz.com +shandechina.xin +shandian666.com +shandiandaili.com +shandiangou.com +shandianhuifu.com +shandiansiwei.com +shandingdang.com +shandingmenye.com +shandjj.com +shandong-energy.com +shandongair.com +shandongbadun.com +shandongbojun.com +shandonggangxie.com +shandonggk.com +shandonghaiyang.com +shandonghealthcare.com +shandonghuahai.com +shandonghuaye.com +shandongjiapeng.com +shandongjuli.com +shandonglanhua.com +shandongqinuo.com +shandongruyi.com +shandongsannong.com +shandongyunpin.com +shandw.com +shanedit.com +shanfengguigang.com +shang-chain.com +shang-ma.com +shang-xia.com +shang0898.com +shang168.com +shang360.com +shangair.com +shangame.com +shanganzixun.com +shangate.com +shangbangzhuan.com +shangbanla.net +shangbanzugroup.com +shangbaolai.com +shangbaowood.com +shangbiao.com +shangbiao.store +shangbiaocheng.com +shangbopharm.com +shangbw.com +shangc.net +shangc123.net +shangcaifanyi.com +shangchao668.com +shangchuanba.com +shangcon.com +shangdagc.com +shangdandan.com +shangdaotong.com +shangdejy.com +shangdian.biz +shangdiguo.com +shangdu.com +shangdu.info +shangeyun.com +shangfang56.com +shangfox.com +shanggame.com +shanggong-zj.com +shanghai-air.com +shanghai-at.com +shanghai-channel.com +shanghai-electric.com +shanghai-idea.com +shanghai-intex.com +shanghai-leather.com +shanghai-map.net +shanghai-parking.com +shanghai-pictures.com +shanghai-sports.com +shanghai-test.com +shanghaiahte.com +shanghaiairport.com +shanghaiairporttour.com +shanghaiamts.com +shanghaiata.com +shanghaiba.org +shanghaibaokai.com +shanghaibaomu.com +shanghaibaoxie.com +shanghaicaiyi.com +shanghaicg.net +shanghaichannel.net +shanghaichemical.com +shanghaiconcerthall.org +shanghaiconcrete.com +shanghaicredit.org +shanghaicup.com +shanghaidaily.com +shanghaidelong.com +shanghaidisneyresort.com +shanghaidite.com +shanghaigm.com +shanghaigobroadhospital.com +shanghaihino.com +shanghaihuanli.com +shanghaiinvest.com +shanghaiiot.org +shanghaijinyimaoyi.com +shanghailima.com +shanghailm.com +shanghaimaling.com +shanghaimart.com +shanghaimaxicheng.com +shanghaimengtaishangcheng.com +shanghaimetal.com +shanghaimuseum.net +shanghainb.com +shanghaining.com +shanghaionstar.com +shanghaiparker.com +shanghaipower.com +shanghaiqihu.com +shanghaiqilu.com +shanghaiql.org +shanghairanking.com +shanghairc.com +shanghairolexmasters.com +shanghaishuangyanpi.com +shanghaishuxie.com +shanghaitianqi114.com +shanghaitower.com +shanghaitrust.com +shanghaivast.com +shanghaivet.com +shanghaiwater.com +shanghaiweicon.com +shanghaixuejia.com +shanghaiyinyang.com +shanghaiyk.com +shanghaiyouxi.com +shanghaizhaxinhospital.com +shanghaizhenji.com +shanghcat.com +shanghongbei.com +shanghuiai.com +shanghuiwww.com +shanghuiyi.com +shangjieiot.com +shangjilian.com +shangjingsh.com +shangjinssp.com +shangjinuu.com +shangjixin.com +shangketang.com +shangli-tea.com +shanglin.net +shanglischool.com +shanglp.com +shangluo.co +shanglushan.com +shanglv51.com +shangnaxue.cc +shangnaxue.net +shangpai123.com +shangpin.com +shangpinshou.com +shangpo.com +shangpu-china.com +shangpusou.com +shangpuzhan.com +shangquanquan.com +shangque.com +shangrao-marathon.com +shangshaban.com +shangshancm.com +shangshang.com +shangshangke.me +shangshangoa.com +shangshangsp.com +shangshi360.com +shangshici.com +shangshiwl.com +shangshouweb.com +shangshu.com +shangshuce.com +shangshuyixue.com +shangtaiw.com +shangtao.net +shangtao360.com +shangtianhui.com +shangtongda.com +shangtuf.com +shanguanjixie.com +shanguansoft.com +shangui.cc +shangusec.net +shangwb.com +shangwu168.com +shangwulink.com +shangxue.com +shangxueba.com +shangyejihua.com +shangyekj.com +shangyexinzhi.com +shangyouxuan.com +shangyouze.com +shangyu-marathon.com +shangyuan029.com +shangyubank.com +shangyuer.com +shangzhang.com +shangzhibo.tv +shanhaifuture.com +shanhainengyuan.com +shanhaitujian.com +shanhaizhanji.com +shanhe.com +shanhe.kim +shanhe01.com +shanheknit.com +shanheyule.com +shanhs.com +shanhu188.com +shanhu99.com +shanhuijiangtang.com +shanhuu.com +shanjianzhan.com +shanjinqh.com +shanjuinformation.com +shankaisports.com +shanks.link +shanliao.com +shanliaoapp.com +shanling.com +shanlinjinrong.com +shanlink.com +shanlinshengwu.com +shanliulian.com +shanmeixincai.com +shanniaorecycle.com +shannon-sys.com +shannonai.com +shanqing.net +shanqu.cc +shanqx.com +shanrongmall.com +shanse8.com +shanshan-business.com +shanshan.com +shanshangame.com +shanshanhc.com +shanshanim.vip +shanshanku.com +shanshantech.com +shanshoufu.com +shanshuihotel.com +shanshuiwl.com +shansteelgroup.com +shante.me +shantoujingrui.com +shantoumama.com +shantui.com +shantuimall.com +shanwan.com +shanwan.store +shanwanli.com +shanweinews.net +shanweirc.com +shanweiyule.com +shanwel.com +shanwxxg.com +shanxiangjiaoyu.com +shanxiaobai.com +shanxichess.com +shanxidiy.com +shanxigames.com +shanxigas.com +shanxigwy.org +shanxihaoshengtong.com +shanxijianzhuzizhi.com +shanximuseum.com +shanxinj.com +shanxiol.com +shanxiranqi.com +shanxishangren.com +shanxishizheng.com +shanxiumao.com +shanxiuxia.com +shanyang666.com +shanyangwang.com +shanyaogroup.com +shanyaoo.com +shanyaoyjy.com +shanyemangfu.com +shanyetang.com +shanyhs.com +shanyishanmei.com +shanyougame.com +shanyu.com +shanyuankj.com +shanyuanms.com +shanyue.tech +shanyuechina.com +shanyzx.com +shanzhen.com +shanzhen.me +shanzhildq.com +shanzhonglei.com +shanzhuyou.com +shaoanlv007.com +shaoerbc.org +shaoerwushu.org +shaogefenhao.com +shaogood.com +shaojiu.com +shaoke.com +shaolinjingwu.com +shaolintagou.com +shaolinwushuxuexiao.com +shaolinwy.com +shaolvjt.com +shaomingyang.com +shaoniandream.com +shaoshangwang.org +shaoshilei.com +shaoxiao.net +shaoxing330.com +shaoxingwater.com +shaoyangnews.net +shaoyuncloud.com +shaphar.com +shapharqx.com +shaphc.org +shaqing.com +shaqm.com +share1diantong.com +share2dlink.com +share2uu.com +share404.com +shareate.com +sharecharger.com +sharecore.net +sharedaka.com +sharegog.com +shareinstall.com +shareinstall.net +shareintelli.com +shareitthrough.com +sharejoytech.com +sharejs.com +sharelogis.com +sharemoon.club +shareoneplanet.org +sharesdns.com +sharetome.com +sharetrace.com +sharevdi.com +sharewaf.com +sharexbar.com +sharexiang.com +sharingclass.vip +sharjahmadrasa.com +sharkisland.store +sharkselection.com +sharkshopping.com +sharpbai.com +sharpheel.com +sharpmobi.com +sharpon.com +shasx.com +shatian.org +shautomuseum.com +shawdo.com +shawnzeng.com +shaxian.biz +shayugg.com +shayujizhang.com +shayuweb.com +shazc.com +shb.ltd +shbangde.com +shbangdian.com +shbaoli.com +shbars.com +shbbq.net +shbear.com +shbetterway.com +shbg.org +shbicycle.com +shbike.com +shbio.com +shbiochip.com +shbizhen.com +shbj.com +shbjfc.com +shbkfyy.com +shbkwai.com +shbl8.com +shbnrj.com +shbobo.com +shboka.com +shbpump.com +shbqmp.com +shbtpm.com +shbxzp.com +shbyer.com +shbyw.com +shcaco3.com +shcancer.com +shcas.net +shcc-horizon.com +shcce.com +shccig.com +shccineg.com +shccio.com +shccpx.net +shccxy.com +shcd.cc +shcell.com +shcell.org +shcellgroup.com +shcfcd.com +shchangshun.com +shchnkyy.com +shchyy.net +shcifco.com +shckgs.com +shclearing.com +shclgc.net +shcljoy.com +shclkj.com +shcmer.com +shcmhr.com +shcnfb.com +shcngz.com +shcsdq.com +shcsinfo.com +shcstheatre.com +shcwmotor.com +shcxbyjt.com +shcya.com +shcz.com +shczssyq.com +shczyy.com +shdafw.com +shdancecenter.com +shdasa.com +shdata.com +shdatagroup.com +shdcjt.com +shdftz.com +shdgm.com +shdingzhidental.com +shdirong.com +shdjt.com +shdmic.com +shdmt.net +shdmu.com +shdnjt.com +shdouxie.com +shdpa.com +shdrc.org +shdrkj.com +shdsd.com +shdsn.com +shdsqs.com +shdszc.com +shdxgraphene.com +shdxk.com +shdy.com +shdy168.com +shdyiy.com +shdyty.com +shdzep.com +shdzfp.com +she120.com +sheasyoffice.com +shebao.net +shebao100.com +shebao5.com +shebao520.com +shebaomi.com +shebaotong.com +shebaowang.com +shebaozhaopian.com +shebiaotm.com +sheboo.com +sheca.com +shedejie.com +shedongyun.com +shedoor.com +shedunews.com +sheec-tencentclb.cloud +sheec-tencentclb.com +sheec-tencentclb.net +sheec-tencentclb.work +sheencity.com +sheenrun.com +sheentec.com +sheep11.com +sheepmats.com +sheinet.com +sheji.com +shejibao.com +shejiben.com +shejibiji.com +shejidaren.com +shejidaxue.com +shejidedao.com +shejidna.com +shejijia.com +shejijingsai.com +shejiku.net +shejinu.com +shejipi.com +shejiqun.com +shejis.com +shejiwo.net +shejixf.com +shejiyizhou.com +shejiyue.com +sheketiandi.com +shekou.com +shelive.net +shellpub.com +shellsec.com +shelter-china.com +shelterdome.net +shelwee.com +shen-grh.com +shen-nao.com +shen-xi.com +shen321.com +shenanhui.com +shenbanglawyer.com +shenbinghang.com +shenbingyiyuan.org +shenbisheji.com +shencai-china.com +shencaiceshi.com +shenchai.com +shenchengkeji.com +shenchengtou.com +shenchigroup.com +shenchuang.com +shenchunhui.com +shencut.com +shenda-group.com +shendatong.com +shendiaoqzj.com +shendoow.com +shendu.com +shendu123.com +shendugho.com +shenduliaojie.com +shenduwang.com +shenduwin10.com +shenduwin7.com +shenduxiyin.com +shenfagg.com +shengangzc.com +shengaohua.com +shengbaihui.com +shengbangshenghua.com +shengbaoluo.com +shengcai.net +shengcaijinrong.com +shengcaiyoushu.com +shengcaozhiwang.com +shengcekeji.com +shengchan.biz +shengdan.com +shengdaosoft.com +shengdaprint.com +shengdawood.com +shengdecw.com +shengdianhuadg.com +shengdianhuadk.com +shengejing.com +shengenqianzheng.com +shengenv.com +shengfajiaohua.com +shengfanwang.com +shenghan.org +shenghefilms.com +shengheplastic.com +shenghongpec.com +shenghu.cc +shenghua-fire.com +shenghuabao.net +shenghuaem.com +shenghuagroup.com +shenghuaxi.com +shenghui56.com +shenghuigd.com +shenghuo365.com +shenghuojia.com +shenghuorili.com +shenghuowo.com +shengjie-logistics.com +shengjing360.com +shengjinghe.com +shengjinglinye.com +shengjiu.com +shengjoy.com +shengjuewl.com +shengli.com +shenglongit.com +shengmaapp.com +shengmage.com +shengming.net +shengmingfa.com +shengminghitech.com +shengniuuz.com +shengpay.com +shengqian51.com +shengquan.com +shengqugames.com +shengren.work +shengrungroup.com +shengsci.com +shengshengkang.com +shengshizhicheng.com +shengtai.com +shengtaigroup.net +shengtian.com +shengtiangroup.com +shengtongedu.com +shengtuanyouxuan.com +shenguang.com +shengwu.store +shengwu01.com +shengxiao.net +shengxiaobj.com +shengxiaochemical.com +shengxin.ren +shengxingholdings.com +shengxinquan.net +shengxuxu.com +shengyan985.com +shengyedq.com +shengyeji.com +shengyi.ai +shengyi.biz +shengyizhuanjia.com +shengyuan.com +shengyuancc.com +shengzhaoli.com +shengzhujiage.com +shenhaoinfo.com +shenhexin.com +shenhexin.vip +shenheyuan.net +shenhongfei.com +shenhongmao.com +shenhua.cc +shenhuachina.com +shenhudong.com +sheniaoren.com +sheniaorenw.com +shenjianggroup.com +shenjiangyy.com +shenjing.com +shenjumiaosuan.com +shenkai.com +shenkelong.com +shenkexin.com +shenkong.net +shenlan01.com +shenlan02.com +shenlanbao.com +shenlaohr.com +shenling.com +shenlintech.com +shenma-inc.com +shenma.com +shenmabaike.com +shenmadsp.com +shenmapay.com +shenmayouxi.com +shenmeipharm.com +shenmikj.com +shenmo.com +shenmojiaoyu.com +shenmou.com +shennongjiazhaopin.com +shennongpharma.com +shennwu.com +shenou.com +shenousz.com +shenpinwu.com +shenpojie.com +shenpowang.com +shenpucw.com +shenqhy.com +shenqisou.com +shenqiwunet.com +shenqizhilv.com +shenquol.com +shenrongda.com +shenrongjidian.com +shenruan.org +shenruapp.com +shenshang.org +shenshi777.com +shenshijituan.com +shenshitech.org +shenshoucdn.com +shenshouwl.com +shenshouyouxi.com +shenshu.info +shenshuo.net +shenshuw.com +shenshuxs.org +shensuantang.com +shensuokeji.com +shenta.net +shentongchina.com +shentongdata.com +shentongkuaidi.com +shenweibengye.com +shenweimicro.com +shenweisupport.com +shenweixiangjiao.com +shenxianhua.com +shenxianyu.cc +shenxijixie.com +shenxingroup.com +shenxm.com +shenxuanche.com +shenyang2car.com +shenyangoffice.com +shenyd.com +shenyecg.com +shenyehd.com +shenyeyunying.com +shenyinhudong.com +shenyou.tv +shenyu.me +shenyuanquan.com +shenyunlaw.com +shenyunmedical.com +shenyunwang.com +shenzan.com +shenzaokeji.com +shenzaole.com +shenzhekou.com +shenzhen-kuaiji.com +shenzhen-world.com +shenzhenair.com +shenzhenbianhua.com +shenzhencefa.com +shenzhenew.com +shenzheninvestment.com +shenzhenjgw.com +shenzhenlianhua.com +shenzhenmakerfaire.com +shenzhenshouxin.com +shenzhenshuixie.com +shenzhentong.com +shenzhentour.com +shenzhenware.com +shenzhenygx.com +shenzhenyuren.com +shenzhoublm.com +shenzhouen.com +shenzhoufu.com +shenzhoupharma.com +shenzhyu.work +shepai1688.com +shephe.com +shepinw.com +shequfu.com +shequfu.net +sherc.net +sherlockkk.com +sherlocky.com +sherowm.com +sheshui.com +shesoleshoes.com +shetu66.com +sheui.com +shevdc.org +shewang.net +sheweikeji.com +shexcloud.com +shexgrp.com +shexian100.com +shexiannet.com +shexpocenter.com +sheying001.net +sheyingtg.com +sheyou.com +sheyuan.com +shezaixian.com +shezfy.com +shfa120.com +shfamily.com +shfangshui.com +shfayy.com +shfcw.com +shffjt.com +shfft.co +shfft.com +shfgzl.com +shfigaro.com +shfilmart.com +shfilmmuseum.org +shfinechem.com +shfirstrehab.com +shfoxmotor.com +shfq.com +shfrp.com +shfswl.com +shfte.com +shfxrc.com +shfy2020.com +shgao.com +shgaoxin.net +shgbc.org +shgbit.com +shgbitcloud.com +shgci.com +shgedu.com +shggzy.com +shgjj.com +shgjq.com +shgkh.com +shgkl.com +shgkw.org +shglgf.com +shgpo.com +shgsec.com +shgsic.com +shgskj.com +shgtheatre.com +shgushi.com +shgyg.com +shgymy.com +shhanqiao.com +shharborcity.com +shhbgm.com +shhcjt.com +shhcpm.com +shhd17.com +shhdouyue.com +shhebio.com +shhella.com +shhenghesh.com +shheywow.com +shhic.com +shhigher.com +shhiminhm.com +shhkcc.com +shhkfw.com +shhksports.com +shhkyy.com +shhl56.com +shhlgroup.com +shhmbio.com +shhmu.net +shholdingeu.com +shhorse.com +shhqcft-tencentclb.cloud +shhqcft-tencentclb.com +shhqcft-tencentclb.net +shhqcft-tencentclb.work +shhqcftfzhj-tencentclb.cloud +shhqcftfzhj-tencentclb.com +shhqcftfzhj-tencentclb.net +shhqcftfzhj-tencentclb.work +shhqcftfzhjtencentclb.cloud +shhqgc.com +shhrp.com +shhtqn.com +shhuaerkang.com +shhuayi.com +shhuayitz.com +shhuazhen.com +shhugong.com +shhuihai.com +shhuke.com +shhuo.com +shhushi.com +shhuu.com +shhweili.com +shhws.com +shhxbk.com +shhxpx.com +shhxyy.com +shhxzq.com +shhyanqing.com +shhyhy.com +shhzcj.com +shi-ming.com +shiabank.com +shianzhixuan.com +shibaili.com +shibangchina.com +shibangsy.com +shibei.com +shibeiht.com +shibeixuan.com +shibolm.com +shibor.org +shicai.biz +shicaidai.com +shicaizhanlan.com +shicehao.com +shichangbu.com +shichengbao.com +shichengyi.com +shichuangsj.com +shichuangyi.com +shichuedu.com +shichuihui.com +shicigequ.com +shicishe.com +shiciyun.com +shicuojue.com +shida66.com +shidaedu.vip +shidai5d.com +shidaohospital.com +shidapx.com +shidastudy.com +shide.com +shidegroup.com +shidenggui.com +shidianbaike.com +shidianguji.com +shidianwandao.com +shidiao136.com +shidicn.com +shidoukeji.com +shidutuozhan.com +shiepmexpo.com +shifair.com +shifan.org +shifanedu.com +shifang.tech +shifansheng.com +shifd.net +shifeiti.com +shifen.com +shifendaodu.com +shifendaojia.com +shifeng.com +shifenyuedu.com +shigaoshan.com +shiguanai.com +shiguanghuyu.com +shiguangpu.com +shiguangxu.com +shiguangyouju.com +shiguanyinger-jg.com +shihua-group.com +shihuantong.com +shihuishuo.com +shijiala.com +shijian.cc +shijian.org +shijiancn.com +shijianla.com +shijianping.com +shijiaok.com +shijicloud.com +shijie2.com +shijiebang.com +shijiechaoshi.com +shijieditu.net +shijiemap.com +shijieminghua.com +shijiemingren.com +shijiesanqingshan.com +shijieshijian.net +shijiexia.com +shijieyouxi.com +shijiezz.com +shijihr.com +shijihulian.com +shijiong.com +shijiqingqing.com +shijiretailo2o.com +shijiudao.com +shijiufang.com +shijqq.com +shijuan1.com +shijue.me +shijueju.com +shijuenian.com +shikangsi.com +shikaricharters.com +shikee.com +shikelang.cc +shikongdaoyu.com +shiku.co +shilehui.com +shileizuji.com +shilian.com +shilian.net +shilicdn.com +shilincn.com +shilitie.net +shiliuai.com +shiliupo.com +shiluetl.com +shiluoji.com +shimano-fishchina.com +shimaoco.com +shimaoenergy.com +shimaogroup.com +shimaostargroup.com +shimaotong.com +shimaowy.com +shimen.org +shimengcs.com +shimengyuan.com +shimengzhanghao.com +shimge.com +shimiduanju.com +shiming.com +shiminjia.com +shimizuchem.com +shimo.im +shimo.run +shimodev.com +shimoko.com +shimolife.com +shimonote.com +shimotx.com +shimowendang.com +shin-kinojseh.com +shinberto.com +shinco.com +shindaichem.com +shine-consultant.com +shine-ic.com +shine-tech.net +shineacc.com +shinechina.com +shinefeel.com +shinelon.com +shineoptics.com +shineray-motors.com +shinerayad.com +shinescan.tech +shinetsu.shop +shineu.com +shineway.com +shinewaytech.com +shinewing.com +shinewonder.com +shineyie.com +shineyue.com +shinger.com +shinianonline.com +shining-electric.com +shining3d.com +shiningmidas.com +shiningnew.com +shiningpharm.com +shink1n-ojasaoq.com +shinkin-jpo-coy.com +shinkinopsae.com +shinnytech.com +shinva.net +shinycg.com +shinye-ortho.com +shinyway.org +shinzoom.com +shiove.com +ship-gps.net +ship.sh +ship56.net +shipai123.com +shipfinder.com +shipgce.com +shipgroup.net +shiphr.com +shipin163.com +shipin520.com +shipinzhibojian.com +shipoe.com +shippingate.com +shippingchina.com +shippingwhale.com +shipry.com +ships66.com +shipservice.org +shiptux.com +shipurili.com +shipuxiu.com +shipxy.com +shiqi.me +shiqiao.com +shiqichuban.com +shiqidu.com +shiqitech.com +shiqu.com +shiquan56.com +shiquask.com +shiqutech.com +shirenzuojia.com +shiritianchengtech.com +shirongzhaoye.com +shisanzhi.com +shiseidochina.com +shishacharcoal.net +shishagame.com +shishangd.com +shishangfengyun.com +shishenmegeng.com +shishifanyi.com +shishijia.com +shishike.com +shishiwater.com +shiso9001.net +shisongya.com +shisukeji.com +shitac.com +shitac.net +shitairen.com +shitestunion.work +shiti.net +shitianxia.vip +shitoc.com +shitou.com +shitouboy.com +shitourom.com +shitsu.co.jp +shituyikao.com +shiwaiyun.net +shiwanbaijiu.com +shiwang1688.com +shiwangyun.com +shiweisemi.com +shiwenlu.com +shixiangren.com +shixiaojin.com +shixibiaozhi.com +shixijob.net +shixingceping.com +shixinhua.com +shixinyufang.com +shixiseng.com +shixiu.net +shixun365.com +shixunhao.com +shixunsuda.com +shixunwl.com +shiyan.com +shiyanbar.com +shiyanbar.net +shiyangdr.com +shiyanhospital.com +shiyanjia.com +shiyanlou.com +shiyculture.com +shiye.org +shiyebian.net +shiyebian.org +shiyedanwei.net +shiyi.co +shiyi11.com +shiyibao.com +shiyicdn.com +shiyide.com +shiyifacai.com +shiyingbao.com +shiyiyj.com +shiyiyx.com +shiyong.com +shiyongjun.biz +shiyou-electric.com +shiyou.me +shiyouflooring.com +shiyouhome.com +shiyousan.com +shiyu.pro +shiyu.zone +shiyuandx.com +shiyue.com +shiyuegame.com +shiyueliangpin.com +shiyund.com +shiyus.com +shiyutianqi.com +shizhanxia.com +shizhiad.work +shizhuang-inc.com +shizhuolin.com +shizhuonet.com +shj6789.com +shjakfyy.com +shjaming.com +shjayson.com +shjb600838.com +shjcm3d.com +shjd.org +shjdceo.com +shjdjx.com +shjglaser.com +shjgu.com +shjh120.com +shjhjc.com +shjiabu.com +shjinbao.com +shjincan.com +shjingmi.com +shjingxu.com +shjinnengzuche.com +shjlnzyy.com +shjob.work +shjr-tencentclb.cloud +shjr-tencentclb.com +shjr-tencentclb.net +shjr-tencentclb.work +shjsit.com +shjsrg.com +shjsst.com +shjstl.com +shjsxh.com +shjt.net +shjtos.com +shjtw.com +shjtxx.net +shjus.com +shjvguan.com +shjx-group.com +shjy18.com +shjy8888.com +shjyou.com +shjyyx.com +shjzfs.com +shjzfutures.com +shjzzjf.net +shkaihang.com +shkamoer.com +shkcn.com +shkcsj.com +shkdchem.com +shkdfua.com +shkdtfyf.vip +shkewen.com +shkg.net +shkhzc.com +shkingchem.com +shkjb.com +shkjcable.com +shkjjs.com +shkjqp.com +shkjsoft.com +shkkl.com +shklsw.com +shkm.com +shkpzx.com +shkuangjing.com +shkypump.com +shlab.tech +shlangao.com +shlawserve.com +shlayout.com +shlcxby.com +shld.com +shldfm.com +shlhbxg.com +shliafvzc.com +shliangshi.com +shlianlu.com +shlingang.com +shlinjiang.com +shlitc.com +shlixin.com +shll-gs.com +shlll.net +shlmth.com +shlongtai.com +shlp.com +shlpk.com +shlsnk.com +shlsyb.com +shlungu.com +shlys.com +shmaas.net +shmama.net +shmarathon.com +shmaur.com +shmbjy.org +shmds.com +shmds.vip +shmedia.tech +shmengyang.com +shmet.com +shmetro.com +shmfmr.net +shmhtv.com +shmhzp.com +shmljm.com +shmockup.com +shmog.org +shmondial.com +shms-expo.com +shmtu.net +shmusic.org +shmusicschool.com +shmylike.com +shmzgroup.com +shnaile.com +shnanfang.com +shnayw.com +shnb12315.com +shnbsh.com +shneuro.org +shneweye.com +shnmnm.com +shnne.com +shnsyh.com +shnti.com +shoasis.net +shoasisholding.com +shobserver.com +shockerli.net +shockley-elect.com +shoegaze.com +shoeshr.com +shofine.com +shojo.cc +shokan.org +shokdown.com +shokw.com +shokz-comm.org +sholaser.com +shollper.com +shomop.com +shomyq.com +shonfer.com +shootmedia.net +shop-isv.com +shop2cn.com +shopbackdrop.com +shopchaoren.com +shopeesell.com +shopeesz.com +shopesv.com +shopex123.com +shopimgs.com +shopin.net +shopjyh.com +shoplazza.com +shopline123.com +shopmaxmb.com +shopnc.net +shoppingchain.net +shopplus.vip +shoprobam.com +shopscrm.com +shopss.com +shoptop.com +shopwatchus.com +shopwind.net +shopxo.net +shopxo.vip +shopxx.net +shopyy.com +shorcut88.com +shorologe.com +shortof.com +shotnba.com +shou-qi.com +shoubaiart.com +shoubanjiang.com +shoubaodan.com +shoubashou.net +shoubb.com +shoubiaohuishou.com +shoubiaowang.com +shoubuluo.com +shoucangyaji.com +shouce.ren +shouce365.com +shouchaoba.com +shoucheng123.com +shoudayy.net +shoudian.com +shoudian.info +shoudian.org +shoudu.org +shouduit.com +shoudurc.com +shoudurx.com +shoufaw.com +shoufm.com +shoufu.com +shougongke.com +shougongke.net +shougoumingbiao.com +shouhaoche.com +shouhoubang.com +shouhougou.com +shouhui.com +shouhuigroup.com +shouhuisoft.com +shouhuojiyun.com +shouhuola.com +shouji.com +shouji.racing +shouji10086.com +shouji315.org +shouji56-img.com +shouji56.com +shoujibao.net +shoujidai.com +shoujiduoduo.com +shoujihuifu.com +shoujikanshu.net +shoujimi.com +shoujitouping.com +shoujiwan.com +shoujixs.net +shoujixs.org +shoukaigufen.com +shoukala.com +shoukangyiyuan.com +shoukayun.com +shoulian.org +shoumaquan.com +shoumizhibo.com +shoumm.com +shounaoxuexiao.com +shouqi-zuche.com +shouqianba.com +shouqibus.com +shouqicar.com +shouqiev.com +shouqu.me +shoushenlvcheng.com +shoutai.com +shoutanjjj.com +shouxi.com +shouxieke.net +shouxieti.com +shouxihu.net +shouxiphotos.com +shouyao.com +shouyao8.com +shouyaoholding.com +shouye-wang.com +shouyhui.com +shouyihuo.com +shouyinbei.net +shouying.tv +shouyou.com +shouyoubus.com +shouyoucdn.com +shouyoudao.com +shouyoujz.com +shouyouqianxian.com +shouyoushenqi.com +shouyoutv.com +shouyouzhijia.net +shouzhang.com +shouzhangapp.com +shouzhitao.com +shouzhuanzhidao.com +shovesoft.com +show160.com +showaamericanstory.com +showapi.com +showchina.org +showcitytimes.net +showcome.net +showdoc.cc +showerlee.com +showfay.com +showgame.com +showing9.com +showjoy.com +showkey.com +showl.com +showmeai.tech +showmebug.com +showmesse.net +showroomshanghai.com +showse.com +showself.com +showshell.com +showstart.com +showtao.com +showxiu.com +showxue.com +showyu.com +shoyoo.com +shpans.com +shpanyou.com +shpbs.com +shpd.net +shpdh.org +shpdjq.com +shpedi.com +shpenquan.com +shpgt.com +shpgx.com +shphschool.com +shpiano.com +shpingda.com +shppa.net +shps518.com +shpsncp.com +shpyedu.com +shqec.com +shqi7.net +shqinghe.com +shqingzao.com +shqipai.org +shqkxh.org +shqmxx.com +shqncs.com +shqpxc.com +shqswlgs.com +shqunlu.com +shqxjx.com +shqyg.com +shrail.com +shrbank.com +shrca.org +shrcb.com +shrcdy.com +shrenqi.com +shresource.com +shrgjt.com +shrlig.com +shrmpump.com +shrmw.com +shrrjt.com +shrtlnks.com +shruanjie.com +shruisong.net +shry.net +shryou.com +shsaic.net +shsajt.com +shsanfang.com +shsanfine.com +shsanji.com +shsanwei.com +shsbnu.net +shsby.com +shsc-valve.com +shscce.com +shsci.org +shscsc.com +shsctec.com +shsd-elec.com +shsdjsj.com +shsdnet.com +shsee.com +shsfkyy.com +shsfxxh.com +shsgbm.com +shsgyq.com +shshenbo.com +shshilin.com +shshinfo.com +shshuhui.com +shshunfeng.com +shshuxiao.com +shshzu.com +shsid.org +shsinhu.com +shsipo.com +shsixun.com +shsjb.com +shsjcb.com +shsjgj.com +shsjjh.com +shskin.com +shsktower.com +shskyland.com +shslqxh.com +shsmzj.com +shsoong-chingling.com +shsot.com +shsparkwater.com +shspdq.com +shsportschool.com +shsq.vip +shsrdzs.com +shssdc.com +shssp.org +shstcm.com +shstone.org +shstyxh.com +shsunny.com +shswim.com +shsxjy.com +shsyf.com +shsyzn.online +shsz17.com +shszsoft.com +shtalentgroup.com +shtannet.com +shtaoism.com +shtazy.com +shtbi.com +shtdgj.com +shtdsc.com +shtefu.com +shtfqx.com +shtgds.com +shthbanz.com +shthediyya.com +shtianhe.cc +shtianye.com +shtianyuqiche.com +shtic.com +shtimessquare.com +shtion.com +shtopshow.com +shtour.org +shtqzs.com +shtrhospital.com +shtsn.com +shtsp.com +shtutian.com +shtw.cc +shtwjiebao.com +shtxcj.com +shtydic.com +shu-ju.net +shu163.com +shuaigeshe.com +shuaigun.com +shuaihuajun.com +shuaiku.com +shuaiming.com +shuainiba.com +shuaipiao.com +shuaishou.com +shuaiy.com +shuaji.com +shuaji.net +shuajibao.com +shuajizhijia.net +shuakazhijia.com +shuame.com +shuang-feng.com +shuang-sen.com +shuangcheng.net +shuangda-pump.com +shuangguan.net +shuanghancn.com +shuangheng.com +shuanghui.net +shuangjing.net +shuangkou.net +shuangkuai.co +shuangle888.com +shuangliang-boiler.com +shuanglin.com +shuanglingroup.com +shuanglongdong.com +shuanglongjp.com +shuangmatbs.com +shuangmei2008.com +shuangniaoslhl.com +shuangqingtech.com +shuangtao.com +shuangtiantech.com +shuangtuan.com +shuangxian.com +shuangxingcaisu.com +shuangxingseed.com +shuangxinhui.com +shuangyanjie.com +shuangyingmenye.net +shuangyingsx.com +shuangyuejn.com +shuangzheng.org +shuangzhong.com +shuashuaapp.com +shuashuati.com +shuazhibo.com +shubiaob.com +shubl.com +shucai001.com +shucai123.com +shucaixiaoshuo.com +shuchengdt.com +shuchongread.com +shuchuandata.com +shucong.com +shudaoge.com +shudaojt.com +shudaowl.com +shudaxia.com +shudianwang.com +shudongpoo.com +shudouzi.com +shuduntech.com +shuerjia.com +shufa.com +shufa.org +shufa121.com +shufa360.com +shufa520.com +shufaai.com +shufabao.net +shufafin.com +shufaji.com +shufajia.cc +shufami.com +shufashibie.com +shufaway.com +shufawu.com +shufazidian.com +shufaziti.com +shufe.com +shufenggaoke.com +shuge.org +shuge9.com +shuguang.com +shuguanggroup.com +shuguanghuayuan.com +shuhai.com +shuhaidata.com +shuhaige.net +shuhaisc.com +shuhaitz.com +shuhaochaxun.com +shuhegroup.com +shuhenglib.com +shuhonggz.com +shuhua.com +shuhuast.com +shuhuawu.com +shuhui9.com +shui12366.com +shuibaogs.com +shuibengxinghao.com +shuicao.cc +shuichan.cc +shuichan51.com +shuichuyu.com +shuidichou.com +shuididabingchou.net +shuidigongyi.com +shuidiguanjia.com +shuidihealth.com +shuidihuzhu.com +shuidihuzhu.net +shuidike.com +shuidiopen.com +shuiditech.com +shuidixy.com +shuidyd.com +shuifuhuanbao.com +shuigongye.com +shuiguobang.com +shuijing100.com +shuijingka.com +shuijingwanwq.com +shuijingwuyu.com +shuijingyibai.com +shuijinshunzhuang.com +shuiku.cc +shuiliangye.com +shuiliantong.com +shuiliaosheji.com +shuiligroup.com +shuilongtouapp.com +shuimiao.net +shuimofang.net +shuimoshi.net +shuimozhuan.net +shuimui.com +shuimujiaju.com +shuimuyulin.com +shuinfo.com +shuini.biz +shuionland.com +shuipingce.com +shuipo.com +shuisj.com +shuitexxkj.com +shuitou001.com +shuiwushi.com +shuiwushi.net +shuixin.tech +shuiyaohuo.com +shuiye.cc +shuiyinbao.com +shuiyinwang.com +shuiyinyu.com +shuiyinyun.com +shuiyoucam.com +shuiyugame.com +shuiyuwenquan.com +shuizhi360.com +shuizhifenxi.com +shuizhili.com +shuizilong.com +shujiangweike.com +shujiariji.com +shujike.com +shuju.net +shujuapi.com +shujuba.net +shujubang.com +shujubo.com +shujujishi.com +shujulin.com +shujutang.com +shujuwa.net +shujuxian1688.com +shukeba.com +shukebox.com +shukeju.com +shukemobile.com +shukingfashion.com +shukoe.com +shukongwang.com +shuku99.com +shukuai.com +shukuai.net +shukuai3.com +shukuajing.com +shukuge.com +shukun.press +shukwai.com +shulanapp.com +shulanedu.com +shulanhealth.com +shulb.com +shulex-voc.com +shuliangtec.com +shulidata.com +shuling.vip +shulink.com +shuliyun.com +shuma7.com +shumaidata.com +shumayin.com +shumazhaopian.com +shumeipai.net +shumenol.com +shumensy.com +shumiao.com +shumiimg.com +shumilou.org +shumo.com +shun176.com +shunanholding.com +shunbangsaifu.com +shunchangzhixing.com +shunchaojinshu.com +shuncom.com +shundaoyun.com +shunde-marathon.com +shundecity.com +shundehr.com +shundeplus.com +shunderen.com +shunfalighting.com +shunfangw.com +shunfeng.cc +shunguang.com +shunhaiwang.com +shunhejieshui.com +shunhengkn.com +shunhongny.com +shunhualithium.com +shunhuishou.com +shunjing.xin +shunjunys.com +shunlitm.com +shunmi.com +shunnengnet.com +shunnengoil.com +shunqi.com +shunscom.com +shunshikj.com +shunshunliuxue.com +shuntian.cc +shuntongtong.com +shunwang.com +shunwoit.com +shunyagroup.com +shunygroup.com +shunyoubio.com +shunyuwater.com +shuoba.com +shuoba.me +shuoba.org +shuobao.com +shuobozhaopin.com +shuocdn.com +shuodedui.com +shuoedu.com +shuofangw.com +shuohong.net +shuoji1688.com +shuojuchaxu.com +shuoman.com +shuomingshuku.com +shuoniu.cc +shuoshuojie.net +shuoshuojuzi.com +shuoshuokong.com +shuoshuokong.org +shuoshuomi.com +shuoshuoxinqing.com +shuowan.com +shuozhiwu.com +shupackaging.com +shupaiyun.com +shupeng.com +shuqi.com +shuqiandiqiu.com +shuqiaozt.com +shuqiapi.com +shuqiread.com +shuqireader.com +shuquge.com +shuquge.la +shuquta.com +shuquxs.com +shuquzw.la +shuren100.com +shushangai.com +shushangyun.com +shushihome.com +shushindo.com +shushubuyue.com +shushubuyue.net +shusw.com +shutcm.com +shuti.com +shutong1680.com +shutong5858.com +shutonginfo.com +shutu.cc +shutwin.com +shuwangxing.com +shuwenxianyun.com +shuwulou.com +shuxiangmenhu.com +shuxiangmuye.com +shuxiayun.com +shuxinsp.com +shuxinyc.com +shuxuehua.com +shuxuejia.com +shuxuejingwei.com +shuxuet.com +shuxueweb.com +shuxueyingyong.com +shuya-china.com +shuyan-biotech.com +shuyang.tv +shuyangba.com +shuye.com +shuyeedu.com +shuyeidc.com +shuyfdc.com +shuyong.net +shuyuanchina.org +shuyuewu.co +shuyun.com +shuzhi9.com +shuzhiduo.com +shuzhou.cc +shuzibao.com +shuzifuyu.com +shuzigd.com +shuzigonggao.com +shuziguanxing.com +shuzijihuo.com +shuzisharing.com +shuzixiaoyuan.com +shuzixindong.com +shuziyuedong.com +shuzong.com +shwbs.org +shwdbjgs.com +shwdir.com +shwebspace.com +shweiqi.org +shwexpo.com +shwhl.com +shwilling.com +shwkwai.com +shwoody.com +shwpbbs.com +shwpg.com +shws.org +shwsfy.com +shwsg.net +shwszdh.com +shwtqx.com +shwuji.com +shwx.com +shwxzf-tencentclb.cloud +shwxzf-tencentclb.com +shwxzf-tencentclb.net +shwxzf-tencentclb.work +shwxzfjpyzc-tencentclb.cloud +shwxzfjpyzc-tencentclb.com +shwxzfjpyzc-tencentclb.net +shwxzfjpyzc-tencentclb.work +shwyky.net +shwzjt.com +shwzoo.com +shwzsh.com +shxaby.com +shxayy.com +shxbe.com +shxcj.com +shxcoal.com +shxdnt.com +shxgroup.net +shxiaoran.com +shxibank.com +shxichina.com +shxil.com +shxinbodi.com +shxincn.com +shxinhua.net +shxinping.net +shxjkjt.com +shxjycqxx.com +shxkyy.com +shxlpe.com +shxmbzcl.com +shxmhjs.com +shxnetwork.com +shxrcw.com +shxrmtzx.com +shxrmyy.com +shxseer.com +shxsj.com +shxsjedu.com +shxuanming.net +shxuou.com +shxwcb.com +shxxyun.com +shxy.net +shxyou.com +shyahs.com +shyanke.com +shyanpu.com +shyaoxu.com +shyclouds.net +shycqf.com +shydjscl.com +shydxsy.com +shyestar.com +shyfci.com +shygdz.com +shyhgj.com +shyhhema.com +shyihuoh.com +shyingt.asia +shyirijian.com +shyisai.com +shykx.com +shykz123456.com +shylwlkj.com +shymhk.com +shyndec.com +shyongci.com +shyongwo.com +shyongzeng.com +shyouai.com +shyoudao.com +shyouhuan.com +shyouth.net +shypzx.com +shyrcb.com +shyrcw.com +shyrcw.net +shyrjt.com +shysjt.com +shyuanye.com +shyueai.com +shyueyanghospital.com +shyuhuankj.com +shyumin.net +shyuwl.com +shyuzhai.com +shywly.com +shyx-bio.com +shyxhy.com +shyxi5.com +shyxwz.com +shyy6688.com +shyygh.com +shyyp.net +shyywz.com +shyyy.com +shyyyl.com +shyz07.com +shyzj.com +shyzjsxh.com +shyzsd.com +shzaiguan.com +shzbc.com +shzbh.com +shzbkj.com +shzch12333.com +shzf.com +shzfsy.com +shzfzz.net +shzgauto.com +shzgd.org +shzgt56.com +shzh.net +shzhanling.com +shzhanmeng.com +shzhiyingedu.com +shzhongru.com +shzhuran.com +shzhyx.com +shziyi.com +shzjy.com +shzkb.com +shzkbc.com +shzkbj.com +shzkie.com +shzkvalve.com +shzkw.org +shzm.org +shzq.com +shzrx.com +shzs2013.com +shzsgroup.com +shzsun.com +shzuibaichi.com +shzunma.com +shzxkq.com +shzychem.com +shzymp.com +shzytzj.com +shzyw.com +shzzks.com +si-bao.com +si-en.com +si-era.com +si-in.com +si-win.com +si.cdn.dell.com +sia1995.net +siad-c.com +siaedu.net +sialiagames.com.tw +siam.org +sian.cc +siaoao.com +sias-sha.com +siasun.com +siasuncare.com +sibangde.com +sibfi.com +sibida.net +sibinwave.com +sibojin.com +sibpt.com +sibsnet.org +sibuzyn.com +sic8d.net +sicarrier.com +sicc.cc +sicent.com +sicheng.net +sicher-elevator.com +sichuan163.com +sichuanair.com +sichuanbh.com +sichuanbojiesports.com +sichuancancer.org +sichuangwy.org +sichuannpo.com +sichuanyunzhan.com +sichw.com +siciciyu.com +sicimano.com +sickcn.com +sicosemi.com +sicreat.com +sid.cc +sidande.com +sidike.com +sidlgroup.com +sidri.com +sidvc.com +siec-ccpit.com +siengine.com +sienwater.com +sieredu.com +sieryun.com +sif.com +sifalu.com +sifang123.com +sifangbazhu.tech +sifangclub.com +sifanggroup.com +sifangoa.com +sifangvideo.com +sifary.com +sifayun.com +siff.com +sifky.com +sifou.com +sig-am.com +sigachem.com +sigas-group.com +sigchina.com +sightp.com +siglent.com +siglff.com +sigma.run +sigmachip.com +sigmamed.net +sigmastarsemi.com +sigmcdn.com +sigmoblive.com +sign-say.com +signage911.com +signcc.com +signdo.com +signinpod.com +sigujian.com +sihai-inc.com +sihaidj.com +sihaigongkao.com +sihaishuyuan.com +sihaitv.com +siheal.com +sihociho.com +sihonghui.com +sihongjob.com +sihongxian.com +sihoo.com +sihotels.com +sihuanpharm.com +sihui-electric.com +sihuisoft.com +sihuixiqu.com +sihuiyiliao.com +sihuizhongyi.com +siia-sh.com +siicenv-wuhan.com +siicfl.com +siicshc.com +siii.xyz +siilu.com +siixu.com +sijiaomao.com +sijijun.com +sijinchuanbo.com +sijiwater.com +sijiweinong.com +sikantech.com +sikem.net +sikiedu.com +sikuwu.com +sikuyi5838.asia +sikuyun.net +silanggame.com +silasbuchanan.shop +sildyn.com +sileadinc.com +silenceper.com +silexmicro.com +silianmall.com +siliansensor.com +siliantecai.com +siliaobaba.com +siliaokelijixie.com +silicon-magic.com +silicongo.com +siliconvisionlabs.com +silikron.com +silinchen.com +siling.com +silingge.com +silique.com +silkpresent.com +silkroad-ec.com +silkroad24.com +silkroadtechnologies.com +silkroddream.com +silktrek.com +sillumin.com +sillydong.com +siloon.com +silucar.com +silucg.com +siludao.com +siluecai.com +siluke.cc +siluke.info +silukex.com +siluwu.com +silvmark.store +sim800.com +simaek.com +simagic.com +simaguo.com +simanuo.com +simat-sh.com +simbajs.com +simcere.com +simcgroup.com +simchip.com +simcolux.com +simcom.com +simcomm2m.com +simcu.com +simei.cc +simei.vip +simei8.com +simengqifu.com +simglo.com +simhaoka.com +simiam.com +simici3.com +simicloud.com +simij.com +simiki.org +simingkuai.com +simingtang.com +simkeway.com +simmtime.com +simochina.com +simon96.online +simope.com +simp.red +simperfect.com +simplecreator.net +simpledatas.com +simplexue.com +simpread.pro +simsci.net +simu-tech.com +simu800.com +simul-china.com +simullink.com +simulway.com +simuwang.com +simwe.com +simxhs.com +sin-jiang-law.com +sin0sites.com +sina-cf.com +sina.com +sina.lt +sina.net +sinaapp.com +sinacdn.com +sinacloud.com +sinacloud.net +sinadaxue.com +sinaedge.com +sinaemc.com +sinaft.com +sinaimg.com +sinajs.com +sinalog.com +sinaluming.com +sinan.fun +sinanet.com +sinanode.com +sinanya.com +sinaquyong.com +sinas3.com +sinas3.net +sinashow.com +sinastorage.com +sinasws.com +sinauda.com +sinawf.com +sinbam.com +sincerelyone.com +sincetech.com +sincetimes.com +sinct.com +sindsun.com +sinepharm.com +sinereal.com +sinesafe.com +sinesemi.com +sineva-robot.com +sineva.com +sinf-test.net +sinf.net +sinflb.net +sinforcon.com +sinfotek.com +singaporepaya.com +singbon.com +singchy.com +singdown.com +singfosolar.com +singfun.com +singgnetworkcdn.com +singhead.com +singlecool.com +singlegraindatabiz.com +singmaan.com +singoo.cc +singpao.com +singse.com +singsun.net +singtaonet.com +singtown.com +singularity-ai.com +singularmedical.net +singulato.com +singworld.net +sinictek.com +sinitek.com +sinldo.com +sinlu.net +sino-agri.com +sino-composite.com +sino-corrugated.com +sino-cr.com +sino-customs.com +sino-epa.com +sino-foldingcarton.com +sino-gps.com +sino-heavymach.com +sino-info.net +sino-life.com +sino-manager.com +sino-pharm.com +sino-pigment.com +sino-sfcc.com +sino-tcm.com +sino-trading.com +sino-training.com +sino-web.net +sinoagentsh.com +sinoancher.com +sinoaqr.com +sinoaquafilter.com +sinoassist.com +sinoassistance.com +sinobaron.com +sinobasalt.com +sinobasedm.com +sinobel.com +sinobestbio.com +sinobo.com +sinobp.com +sinobrook.com +sinocache.net +sinocare.com +sinocars.com +sinocax.com +sinochem-guangdong.com +sinochem-zhfl.com +sinochem.com +sinochemb2c.com +sinochemehc.com +sinochemintl.com +sinochemitc.com +sinochemjiangsu.com +sinochemoilmarketing.com +sinochempharma.com +sinochip.net +sinoclick.com +sinocoalchem.com +sinocopy.com +sinodh.com +sinodingcheng.com +sinodis.com +sinodrive.com +sinoec.net +sinoevin.com +sinofarm.net +sinofo.com +sinofo.group +sinofusite.com +sinog2c.com +sinogeo.com +sinoglorygroup.com +sinogslb.com +sinogslb.net +sinogt.com +sinohb.com +sinohotel.com +sinohowe.com +sinohsc.com +sinohx.com +sinohydro.com +sinoid.com +sinoinfosec.com +sinoing.net +sinoinnovel.com +sinoins.com +sinointeractive.com +sinoiov.com +sinokap.com +sinolease.com +sinolinchem.com +sinolinchemintl.com +sinolines.com +sinolion.net +sinologyinstitute.com +sinolub.com +sinolube.com +sinoluhong.com +sinoma-suzhou.com +sinomach-auto.com +sinomachint.com +sinomags.com +sinomapping.com +sinomaps.com +sinomatech.com +sinomatin.com +sinomcu.com +sinomep.com +sinonet.org +sinonsh.com +sinontech.com +sinoo.cc +sinooceangroup.com +sinooceanland.com +sinopatho.com +sinopec-usa.com +sinopec.com +sinopecgroup.com +sinopecgx.com +sinopechyzx.com +sinopecnews.com +sinopecpay.com +sinopecsales.com +sinopecsenmeifj.com +sinopharm-fj.com +sinopharm-fl.com +sinopharm-gz.com +sinopharm-henan.com +sinopharm.com +sinopharmdbj.com +sinopharmholding.com +sinopharmhospital.com +sinopharmintl.com +sinopharmlrt.com +sinopharmsx.com +sinopharmzl.com +sinophex.com +sinopipevalve.com +sinopont.com +sinopr.org +sinoprinterparts.com +sinoqy.com +sinorda.com +sinoreagent.com +sinort.com +sinorusfocus.com +sinorussian21st.org +sinosam.com +sinoshan.com +sinosig.com +sinosilica.com +sinosms.com +sinoss.com +sinoss.net +sinostargroup.com +sinosteel.com +sinosun.com +sinosuntop.com +sinotau.com +sinotechline.com +sinotf.com +sinotide.com +sinotn.com +sinotone.net +sinotph.com +sinotrans.com +sinotruk.com +sinotrukinternational.com +sinotrust-group.com +sinoturning.com +sinovale.com +sinovast.com +sinovatech.com +sinovatio.com +sinovationmed.com +sinovationventures.com +sinovel.com +sinovoice.com +sinowaycarbon.com +sinowbs.com +sinowbs.org +sinowealth.com +sinowealth.com.hk +sinowel.com +sinowheelbarrow.com +sinowinfiber.com +sinoxk.com +sinoxlube.com +sinozhongyuan.com +sinozoc-ex.com +sinreweb.com +sinrey.com +sinro.com +sinsam.com +sinsche.com +sintaho.com +sintaytour.com +sintien.com +sintoacct.com +sintu.com +sinture.com +sinvofund.com +sinvta.com +sinyoung.site +sinyuan.com +sinyuee.com +sinzk.com +siobp.com +siomxity.com +siomxity.net +siozqkt.com +sipai.com +sipaphoto.com +sipatsaw.com +sipcdc.com +sipco.com +sipedu.net +sipedu.org +sipeed.com +sipgl-lcl.com +sipgzct.com +siphrd.com +sipingseo.com +sipmsg.com +sipo-sc.com +siposchina.com +sipprh.com +sipsenegal.org +sipujy.com +sipurd.com +siqiangame.com +siqiquan.org +siqxmg4256.vip +sir3.com +sir66.com +siranbio.com +sireda.com +sirenyouxiang.com +sirfang.com +sirweara.com +siryin.com +siscantech.com +siscmag.com +sisder.com +sisdown.com +sisen.com +sisensing.com +sishui123.com +sishuojixie.com +sishuok.com +sishuxuefu.com +sisi-smu.org +sisigad.com +sisijiyi.com +sisp-china.com +sissiok.com +sisuts.com +siswin.com +sitande.com +sitangtech.com +sitc.com +site-digger.com +site119.com +siteapp-static.com +sitejiu.com +sitekc.com +siteonlinetest.com +sithc.com +sitiaoyu.com +sitobiotech.com +sitong.net +sitongedu.org +sitongzixun.com +sitrigroup.com +sitronics-sh.com +situationk.com +situdata.com +siud.com +sivlab.com +siwaman.com +siweidaotu.com +siweiearth.com +siweikongjian.net +siweiw.com +siwuprint.com +six.club +sixflower.com +sixianchina.com +sixiang.im +sixianggangyin.com +sixiju.com +sixjoy.com +sixstaredu.com +sixu.life +sixue.tech +sixuexiazai.com +sixunited.com +sixyin.com +siyanhui.com +siyetian.com +siyi007.com +siyrcw.com +siyuan.cc +siyuan.me +siyuanedu.com +siyuanren.com +siyuanyl.com +siyuhome.net +siyunyatwo.com +siyuweb.com +sizebid.com +sizeofvoid.net +sizhicn.com +sizuo.com +sj-airpurge.com +sj-hospital.org +sj-lawyer.com +sj-marathon.com +sj-tmdi.com +sj0763.com +sj123.com +sj33.net +sj3g.com +sj51.net +sj6rgxtjg3tmb.com +sj998.com +sjawards.com +sjaz.com +sjbutton.com +sjbyj.com +sjcamzone.cc +sjcomic.com +sjcybz.com +sjdongwang.com +sjdshd.com +sjdzp.com +sjdzp.net +sjebh.com +sjetdz.com +sjf029.com +sjfcdn.com +sjfh168.com +sjfpro.com +sjfzxm.com +sjg8.com +sjgle.com +sjgo365.com +sjgskaipiao.com +sjhcip.com +sjhfkhgut009.com +sjhfrj.com +sjhgo.com +sjhl.cc +sjhoffice.com +sjhong.net +sjhuatong.com +sjhy.net +sjhykt.com +sjizx.com +sjjob88.com +sjjt001.com +sjjzm.com +sjkj.net +sjlbearing.com +sjlexpress.com +sjlgc.com +sjlhlawyer.com +sjlvyou.com +sjm-zdh.com +sjm.life +sjmao.net +sjmdh.com +sjmeigao.com +sjmp3.com +sjmwsw.com +sjono.com +sjooo.com +sjpif.net +sjpjyx.com +sjq315.com +sjqcj.com +sjqmtlm.com +sjrwzz.com +sjsbk.com +sjsei.com +sjsgdzx.com +sjsheji.com +sjsrm.com +sjsydq.com +sjszt.com +sjtickettech.com +sjtm.me +sjtug.org +sjtusummer.org +sjtxt.com +sjtxt.la +sjtype.com +sjvi.net +sjwec-tencentclb.cloud +sjwec-tencentclb.com +sjwec-tencentclb.net +sjwec-tencentclb.work +sjwj.com +sjwl.xyz +sjwt.net +sjwtlm.com +sjwx.info +sjwyx.com +sjxinxiwang.com +sjxqn.com +sjxs.la +sjxtcw.com +sjxydc.com +sjxyit.com +sjxysec.com +sjxyx.com +sjxzc.com +sjy-art.org +sjy2.com +sjycbl.com +sjyhotel.com +sjyl.com +sjysz.com +sjyt.net +sjytech.com +sjyx.com +sjyybz.com +sjyyt.com +sjyyy.com +sjz-marathon.com +sjz.cc +sjz110.cc +sjz44z.com +sjz7.com +sjzbasha.com +sjzbwx.com +sjzcfjd.com +sjzcmw.com +sjzez.com +sjzfeitai.com +sjzfls.com +sjzgxwl.com +sjzhr.com +sjzhushou.com +sjzjifeng.com +sjzjinliulin.com +sjzjkqgs.com +sjzjtjt.com +sjzkz.com +sjzlg.com +sjzlgz.com +sjzmama.com +sjznuanjieks.com +sjzonline.com +sjzpco.org +sjzqcrl.com +sjzrbapp.com +sjzrmyz.com +sjzshunbang.com +sjzslnyhy.com +sjzswtz.com +sjzszz.com +sjztd.com +sjzthdz.com +sjzxfy.com +sjzxh.com +sjzxtsh.com +sjzxyy.com +sjzyb.com +sjzyes.com +sjzys.com +sjzysdz.com +sjzysgz.com +sjzyxh.com +sjzyz.net +sjzzbxh.com +sjzzxmm.com +sjzzyy.com +sk163.com +sk1999.com +sk1z.com +sk2w.net +skatehere.com +skcto.com +skd6.com +skd62.com +skdj5.com +skdlabs.com +ske.cc +skeo.net +sketchcn.com +sketchupbar.com +sketchupbbs.com +skf-bearing.net +skg.com +skhb.com +skidstorm.com +skieer.com +skimit.net +skinjc.com +skinme.cc +skinpp.com +skip-links.com +skjcsc.com +skl.net +skland.com +sklbce.org +skldoor.com +sklinux.com +skmgc.com +sknbj.com +skomart.com +skongmx.com +skp-beijing.com +skpssz.com +skrskrskrskr.com +sksdwl.com +sksight.com +skslfd.com +skstravel.com +skswz.com +sktcdn.com +sktecfibre.com +sktfaker.com +skuking.com +skusoft.com +skwfls.com +skxox.com +skxsj.com +sky-deep.com +sky-fire.com +sky-ing.com +sky-mobi.com +sky123th.com +sky1shop.com +sky350.com +skyai.tech +skyallhere.com +skyao.io +skyapp1.tv +skyard.com +skyart.site +skybility.com +skybluek.com +skybogroup.com +skybright-group.com +skycaiji.com +skycedu.com +skycham.com +skycloudsoftware.com +skycn.com +skycn.net +skycnc.com +skycoleasing.com +skycorp.com +skydodi.com +skydust.net +skyeaglee.com +skyecs.com +skyee360.com +skyfeather.online +skyfollowsnow.pro +skyfont.com +skyfox.org +skyhand.vip +skyheng.com +skyislets.com +skyleon.com +skylerzhang.com +skymoons.com +skymoons.net +skymp4.cc +skynan.com +skynicecity.com +skynj.com +skype-china.net +skype-tom.com +skypixel.com +skypuretech.com +skyray-instrument.com +skyray-water.com +skyrelay-ic.com +skyrichpower.com +skyrivers.org +skyrj.com +skysea.com +skysgame.com +skysriver.com +skysrt.com +skyton123.com +skyts.net +skytv.cc +skyue.com +skyw.cc +skywalkeryacht.com +skywavewifi.com +skywek.com +skywellcorp.com +skywldh.com +skywork.ai +skyworkcdn.com +skyworth-ac.com +skyworth-cloud.com +skyworth-ea.com +skyworth.com +skyworthbox.com +skyworthdigital.com +skyworthdigitaliot.com +skyworthds.com +skyworthev.com +skyworthiot.com +skyworthlighting.com +skyworthnj.com +skyworthznxyj.com +skyxinli.com +skyyin.org +skyzhan.com +skznsb.com +sl.al +sl.fun +sl.ink +sl512.com +sl916.com +sl91d.com +slaccas.com +slagta.com +slaidor.com +slamtec.com +slanissue.com +slanmedia.com +slatic.net +slbauto.com +slbiop.com +slcad.com +slchos.com +slcyber.icu +sldhc.com +sldns1.com +slduntong.com +sle.group +sleele.com +sleepboy.com +sleepwearinc.com +slegetank.com +slengy.com +sleton.com +slfwakuang.com +slfwq.com +slgegc.com +slhwyy.com +slicejobs.com +slidestalk.com +slingbearings.com +slink8.com +slinli.com +sliun.com +slive.ytn.co.kr +slja2.com +sljob88.com +slk1.net +slkg1949.com +sllai.com +sllngy.com +sllssrq.com +slodon.net +sloer.com +slofdoro.com +slogra.com +slot-china.com +slot4.net +slotb.vip +slotph.vip +slovakia-visacenter.com +slovenia-visacenter.com +slowdark.com +slpi1.com +slpm.net +slpmg.com +slrbs.com +slreactor.com +slready.com +slshareservices.com +slspcn.com +slssx.com +slsteel.com +slswd.com +slswx7.com +sltg2019.com +sltgj.com +slthxx.com +sltv.net +sltxantonline.com +sluyu.com +slwh-dfh.com +slwwedding.com +slybjp.com +slyld.com +slyxmobi.com +slzsxx.com +slzww.com +sm-check.com +sm-cq.com +sm-main.com +sm.dell.com +sm0.fun +sm160.com +sm160.net +sm3s.com +sm597.com +sm96596.com +small-master.com +smallfighter.com +smalljun.com +smallpdfer.com +smallyuan.com +smarch.com +smarchit.com +smart-hengdi.com +smart-idc.net +smart-ptt.com +smart-rise.com +smart.com +smart.uhdnow.com +smart2pay.com +smart365ol.com +smart400.com +smartautoclub.com +smartbgp.com +smartbunniemen.com +smartcar.zone +smartcarrace.com +smartchn.com +smartcity.team +smartcitysz.com +smartcloudcon.com +smartcom.cc +smartdeep.com +smartdeer.com +smartdeer.work +smartdot.com +smartedm.com +smarteredu.net +smartermicro.com +smartgaga.com +smarthey.com +smarthomecn.com +smarthuayan.com +smartisan.com +smartisanos.com +smartisantv.com +smartjoygames.com +smartlifein.com +smartlinkio.com +smartlinku.com +smartmapx.com +smartmidea.net +smartmore.com +smartoct.com +smartont.net +smartpigai.com +smartpoweriot.com +smartqilu.net +smartroomcn.com +smarts-isoftstone.com +smartsenstech.com +smartsteps.com +smartstudy.com +smarttaixing.com +smartwebee.com +smartx-cn.com +smartx.com +smartxiantao.com +smartyao.com +smartyoke.com +smartyun8.com +smartzzx.com +smarun.com +smaryun.com +smasmj.com +smb956101.com +smbc-cardzj0.club +smbinn.com +smbxw.com +smc18.com +smc3s.com +smcalia.com +smcalib.com +smcbnokkiduran.com +smcbnokkihabak.com +smcbnokkirederc.com +smcec.com +smcic.net +smcsrj.com +smd-automation.com +smd88.com +smdcn.net +smdiban.net +smdmark.com +smdx.net +smdxx.com +sme-cn.com +sme8718.com +smebb.com +smec-cn.com +smedi.com +smei.net +smeia.net +smeiic.com +smemo.info +smeok.com +smetumen.com +smf1888.com +smfsgs.com +smfyun.com +smgpt.com +smgstar.com +smgstv.com +smgtech.net +smhsw.com +smhyplay.com +smianao.com +smianet.com +smic-sh.com +smicc.com +smicrobe.com +smics.com +smil888.com +smile2012.com +smileangelfoundation.org +smilec.cc +smilefil.com +smileyan.com +smilingwhitebear.com +smithcn.com +smjstcy.com +smkeji.com +smkgc.com +smkmake.com +smknow.com +smkxyjy.com +smlaw8.com +smlqcl.com +smmc.com +smmiki.com +smo-clinplus.com +smo-software.com +smoba.net +smobird.cc +smogfly.cloud +smogfly.club +smogfly.com +smogfly.net +smogflycloud.com +smogflycloud.net +smohan.net +smoothgroup.cc +smoreroll.com +smovie168.com +smowo.com +smpg888.com +smppw.com +smq.ltd +smqh.com +smrmyy.com +sms.imagetasks.com +sms18.com +sms9.net +smsbao.com +smshos.com +smshx.com +smskb.com +smslk1.com +smslk2.com +smslkcoffee.com +smsot.com +smsvifv.com +smswgy.com +smswriter.com +smsyun.cc +smt-dip.com +smt.net +smt2000.com +smtcdn.com +smtcdns.com +smtcdns.net +smtchinamag.com +smtcl.com +smtdc.com +smtdwx.com +smthome.net +smtphub.org +smtro.com +smtsmt.com +smtso.com +smtsvs.com +smttouch.com +smtukuzy.com +smtul.com +smtvip.com +smtw.com +smtworld.com +smudc.com +smuszh.com +smuszsh.com +smvip8.com +smwd.tech +smxdiy.com +smxgjj.com +smxin.com +smxr.com +smxrcw.net +smxs.com +smxyi.com +smxzls.com +smyfinancial.com +smyhvae.com +smynn.com +smyx.net +smyxxj.com +smyyhj.com +smyz.net +smzdm.com +smzdmimg.com +smzdwan.com +smzhongran.com +smzjy.cc +smzrmyy.com +smzsffb.com +smzy.com +sn-epe.com +sn12333.com +sn180.com +sn511.com +snack-show.com +snai.edu +snail.com +snail007.com +snailgame.net +snailovet.com +snailsleep.net +snailyun.com +snap-buy.com +snapany.com +snapdrop.net +snapemoji.net +snapgenshin.com +snaplabdevelop.com +snapp.ir +snapp.site +snapp.taxi +snappcloud.io +snappea.com +snapplay.com +snappmaps.ir +snaptube.app +snbcnyjt.com +snbiopharm.com +snbkf34.com +sncoda.com +snctaa.com +snd-cia.com +snd-stig.com +snd-yy.com +snda.com +sndcc.cc +sndgroup.com +sndhr.com +sndks.com +sndnt.com +sndo.com +sndvc.com +sndzrg0.org +sneac.com +sneb3.com +snedu.com +sneducloud.com +sneia.org +snfic.com +snfox.com +snfzsw.com +sngct.com +snh48.com +snhere.com +snhrm.com +snibe.com +sniec.net +snieri.com +snimay.com +sniuw.com +snjairport.com +snjbs.com +snjjiu.com +snjt.com +snkjol.com +snkshoe.com +snkyat.com +snltty.com +snlxgk.com +snmandarin.com +snmi.com +snmxzls.com +snoba.net +snobten.com +snodehome.com +snoone.com +snor-china.com +snowballfinance.com +snowballsecurities.com +snowballtech.com +snowbeasts.com +snowdream.tech +snowflake.pink +snowkey.com +snowlotusgroup.com +snowyimall.com +snp.cdn.dell.com +snpac.com +snpi.dell.com +snps.tech +snptc.com +snrat.com +snren.com +snrtv.com +snrunning.com +sns-china.com +snscz.com +snsfun.cc +snsfun.com +snsii.com +snsnb.com +snsqw.com +snsyhg.com +snsyx.com +sntba.com +snto.com +snupg.com +snv1.com +snwx.com +snxw.com +snycloud.com +snynas.com +snzhao.com +snzhny.com +snzsxh.com +so.car +so.com +so03290koaq.com +so03300koaq.com +so04060koaq.com +so04061koaq.com +so123.com +so126.com +so50.com +so666gslb.com +so8848.com +soapphoto.com +soar-chem.com +soargift.com +soarwatch.com +soaryoof.com +soauto.com +sobaidupan.com +sobereva.com +sobeycache.com +sobeycloud.com +sobeylingyun.com +sobeylive.com +sobili.com +sobone.com +sobot.com +sobot.io +soboten.com +sobute.com +socang.com +socay.com +soccerbar.cc +socchina.net +soche8.com +sochengyi.com +sochips.com +socialark.net +socialbasecustomercontent.com +socialbaseusercontent.com +socialbeta.com +socialjia.com +socialpls.com +socket.tw +socolar.com +socomic.com +socool-tech.com +socoologo.com +socotton.com +socpk.com +sodajs.org +sodalife.xyz +sodamc.com +sodao.com +sodasoccer.com +sodayang.com +sodc8.com +sodexo-cn.com +sodig.com +sodino.com +sodion.net +sodocloud.com +sody123.com +soeasysdk.com +soeo.net +sofa-webbing.com +sofabiao.com +sofan.one +sofang.com +sofangche.com +sofasofa.io +sofastack.tech +sofeiya.net +sofi-tech.com +sofoo.com +sofreight.com +soft128.com +soft2005.com +soft50.com +soft5566.com +soft568.com +soft6.com +soft778.com +soft8.net +soft808.com +soft8899.com +softabc.com +softbank.best +softbanks.net +softbar.com +softbingo.net +softdownd.com +softgostop.com +softhome.cc +softjinzhou.com +softmall.net +softrobottech.com +softscdn.com +softsz.com +softtest.com +software.download.prss.microsoft.com +softwarechn.com +softwarecn.com +softweek.net +softwhy.com +softwincn.com +softworker.com +sofujinyu.com +sofun.com +sogaa.net +sogalqd.com +sogaokao.com +sogeche.com +sogo.com +sogoke.com +sogood360.com +sogou-compress.com +sogou-diskmgr.com +sogou-inc.com +sogou-inner.com +sogou-kantu-pic.com +sogou-kantu.com +sogou-op.org +sogou-pdf.com +sogou-wallpaper.com +sogou.com +sogou.net +sogoucdn.com +sogoucdndl.com +sogouimecdn.com +sogowan.com +sogw.cc +soharp.com +sohfvx3149.vip +soho-yiming.com +soho3q.com +sohoblink.com +sohochina.com +sohodd.com +sohonow.com +sohotask.com +sohu-inc.com +sohu.com +sohu.net +sohuapps.com +sohucao.duapp.com +sohucs.com +sohuhistory.com +sohuiw.com +sohumail.com +sohunjug.com +sohuns.com +sohuora.com +sohurdc.com +sohusce.com +sohuu.com +soicp.com +sojex.net +sojiang.com +sojiang.net +sojianli.com +sojixun.com +sojiyin.com +sojoline.com +sojson.com +sojump.com +soke17.com +soken-sz.com +sokoban.ws +sokon.com +soku.com +sokuba.com +sokutu.com +sokyotw.com +solaking.com +solanyun.com +solar-engine.com +solarbao.com +solarbe.com +solarbio.com +solarcare.com +solarchin.com +solareast.com +solarf.net +solaridc.com +solarspace.com +solarzoom.com +solasmat.com +soldeazy.com +soldierstory-toys.com +solelybio.com +solepic.com +soletower.com +soliao.com +solidifyk.com +solidigm-asdf.com +solidigm-nvme.com +solidigm-zxcv.com +solidot.org +solidstatelion.com +soliner.com +solipharma.com +solo-launcher.com +solochex.com +soloknight.xyz +solomath.com +solooncontrols.com +solosea.com +solotoon.com +solove.design +solsticeorbit.cfd +solution9.net +solvyou.com +som88.net +somacisgraphic.hk +somama.com +somamobi.com +somd5.com +somdom.com +someabcd.com +somenchina.com +somenmian.com +something8.com +sometracking.com +somo.so +somode.com +somsds.com +sonbest.com +soncci.com +songcn.com +songcwh.com +songduwuye.com +songguike.com +songguo.com +songguo7.com +songguobox.com +songguojiankang.com +songhaifeng.com +songhaoyun.com +songhaozhi.com +songhengnet.com +songhualan.com +songhuwan.com +songjiangjituan.com +songker.com +songlei.net +songlicnc.com +songma.com +songmaogroup.com +songmiao.net +songqinnet.com +songshanlab.com +songshitang.com +songshizhao.com +songshuai.com +songshudiandian.com +songshuhui.net +songshujiedan.com +songshushuo.com +songshuyouxi.com +songsongruanwen.com +songsongyingxiao.com +songsongyun.com +songtaox.com +songtasty.com +songtianlube.com +songtsam.com +songwang168.com +songxiaocai.com +songxiaojin.com +songxing.net +songyang.net +songyangcn.com +songyanjiaye.com +songyi.net +songyongzhi.com +songyuan163.com +songyuan58.com +songyuanlove.com +songyuanshuisi.com +songzhaopian.com +songzi100.com +songziren.com +songzixian.com +sonhoo.com +sonhoshin.com +sonicmodel.net +sonicrhino.cc +soniu.net +sonkwo.com +sonkwo.hk +sonoscapebrasil.com +sonoschina.com +sontan.net +sony.com +sonybbs.com +sonyentertainmentnetwork.com +sonyong.com +sonyselect.net +soo56.com +sooal.com +sooauto.com +soocang.com +soochowchem.com +soocor.com +soodao.com +sooele.com +soofel.com +soogf.com +soogif.com +soohaid.com +soojs.com +sooker.com +soolinen.com +soolou.net +soolun.com +soomal.com +soon.guru +soonku.net +soonv.com +soonwill.com +soonyo.com +sooopu.com +sooopu.org +soopat.com +soopay.net +sooroo.com +sooshong.com +sooshu.net +soosmart.com +soosox.com +sootmoor.com +sootoo.com +sootool.net +soovalve.com +soovvi.com +sooxie.com +sooxue.com +sooyooj.com +soozhu.com +soozhuozhou.com +sopaidea.com +sophgo.com +sophgo.vip +sophnet.com +sopic.org +sopowcore.net +soq.com +soqicrm.com +soqqq.com +soquano.com +sorftime.com +soripan.net +sorswitch.com +sortdoor.com +sos919.com +sosaf.com +sosdx.com +sosg.net +soship.com +soshoo.com +soso.com +sosoba.org +sosobtc.com +sosoled.com +sosolight.com +sosomp.com +sosonc.com +sosonsk.com +sosoo.net +sosorank.com +sososnap.com +sososteel.com +sosotec.com +sosoyunpan.com +sosoyy.com +sosuo.name +sosyao.com +sotake.com +sotemall.com +sothink.com +sotongwang.com +sotouv.com +sotoy.net +sotu114.com +sou-yun.com +sou.com +souaiche.com +souajki.com +souajki.net +soubao.net +soucai.com +soucangjie.com +souche-fin.com +souche-inc.com +souche.com +soucod.com +soudao.com +soudoc.com +soudron.com +souduanzu.com +soueast-motor.com +souebao.com +soufair.com +soufang.com +soufang998.com +soufun.com +soufunimg.com +souge.cc +souget.com +sougou.com +sougu001.com +souha.net +souho.cc +souho.net +souiaico.com +souidc.com +souidc.org +soukecheng.net +soukuyou.com +soulapp.me +soulgame.mobi +soulsky.net +soulteary.com +soulu365.com +souluo.net +souluojie.com +souluopai.com +soulwonderland.com +sound-force.com +soundai.info +soundconch.com +soundems.com +soundgroup.com +soundnybio.com +soundpeats.com +soundstay.com +soupan.info +soupf.net +soupin.com +soupingguo.com +soupu.com +soupv.com +souqian.com +souqiantu.com +souqiu8.com +sour-lemon.com +source.tutorabc.com +source3g.com +sourcecodebeat.com +sourcecodecap.com +sourcecodeserver.com +sourcegcdn.com +sourcelandchina.com +sousea.com +soushai.com +sousou.com +sousou.pro +sousoudus.com +sousuoshidai.com +sousuotu.com +southbeauty.com +southbeautygroup.com +southchip.com +southcn.com +southei.com +southernfund.com +southernmindict.net +southernpec.com +southgis.com +southmoney.com +southnews.cc +southnews.net +southseagy.com +southsurvey.com +southyule.com +soutiyun.com +soutudi.so +soutushenqi.com +souvi.com +souvr.com +souwuxing.com +souxia.com +souxue8.com +souxuexiao.com +souxw.com +souya.com +souyidai.com +souyue.mobi +souyue.vip +souyunku.com +souyute.com +souziti.com +sov2ex.com +sovell.com +soven.com +sowang.com +soweather.com +sowellwell.com +sowin.com +sowotech.com +sowu.com +soxpai.com +soxyc.com +soya-protein.com +soyim.com +soyixia.net +soyiyuan.com +soyjg.com +soyo-dg.com +soyohui.com +soyoung.com +soyouso.com +soyunion.com +soyx123.com +sozdata.com +sozhe.com +sozhen.com +sozyb.com +sp.cc +sp168.com +sp588.cc +sp588.net +sp888.net +sp910.com +space1688.com +spacechina.com +spaceestar.com +spacei.net +spacemit.com +spacesystech.com +spacety.com +spamc.com +spanishknow.com +sparenode.com +spark-page.com +spark-page0.com +spark-page1.com +spark-page2.com +spark-page3.com +spark-page4.com +spark-page5.com +spark-page6.com +spark-page7.com +spark-page8.com +spark-page9.com +spark4y.com +sparkdeep.com +sparkeduapi.com +sparkeducdn.com +sparkgis.com +sparkletour.com +spasvo.com +spawor.com +spay365.com +spbao.com +spbo.com +spbycdn.biz +spbycdn.com +spbycdn.info +spc365.com +spcc-cn.com +spcc-silk.com +spccmc.com +spcdntip.com +spcdntipbak.com +spcloudhw.com +spcloudhw.net +spcywang.com +spdbh5.com +spdbuser.com +spdcat.com +spddir.com +spdex.com +spdiy.com +spdl.com +spdydns.com +spdyidea.com +speakout.hk +specchemind.com +specialcdnstatus.com +spectorfilm.com +spectrafusion.cfd +sped-ssss-pppp-eeee-dddd.com +speechless.pw +speed-hz.com +speedaf.com +speedcdns.com +speedcdns.info +speedcdns.org +speedcdnsvip.com +speedin.shop +speedmanager.net +speednt.com +speedpdf.com +speedsz.net +speedws.com +speedws.info +speedws.org +speedzonerc.com +speiyou.com +sperogenix.com +spfbiotech.com +spforum.net +spfosd.com +spg-ls.com +spgacmotorsc.com +spgcw.com +spgykj.com +sph00852.com +sphcchina.com +sphchina.com +sphkids.com +sphmc.org +sphsine.com +spibj.com +spic-coalcg.com +spicaceshi.asia +spiccq.com +spicescn.com +spicezee.com +spicgx.com +spicgxnp.com +spicgz.com +spicjs.com +spiedigitallibrary.org +spiiker.com +spin-view.com +spiritframe.org +spirithy.com +spischolar.com +spiwcn.com +splaybow.com +splayer.work +spldlkj.com +splendecor.com +splmcn.com +spmcn.com +spnchinaren.com +spochikj.com +spoience.com +spointdesign.com +sporposten.today +sport-syy.com +sportman.cc +sportnanoapi.com +sportq.com +sports-100.com +sportsdt.com +sporui.com +spoto.net +spotpear.com +spouyashop.com +spph-sx.com +spplnet.com +spprec.com +spr-atm.com +sprayv.com +sprda.org +spreadtrum.com +spreton.com +spring-mall.com +spring4all.com +spring56.com +springairlines.com +springcocoon.com +springer.com +springerlink.com +springpharma.net +springsunday.net +springtour.com +springx.fun +sprint-tech.com +sprixin.com +spsb114.com +spsicloudport.com +spsisctgroup.com +spsisncl.com +spsy.org +sptcc.com +sptccn.com +spthome.com +sptv-1.com +spug.cc +spvtime.com +spwj.com +spxgas.net +spyouxi.com +spzb.com +spzp.com +spzs.com +sq-ks.com +sq-newstar.com +sq.cc +sq1996.com +sq23.com +sq521.com +sq523.com +sq580.com +sq581.com +sqa-chn.com +sqage.com +sqchunqiu.com +sqdaily.com +sqeatin.com +sqezz.com +sqfcw.com +sqfgc.com +sqgg.cc +sqggzy.com +sqgwh.com +sqhec.com +sqhx.com +sqis.com +sqj-jiuyousport.com +sqj888.com +sqjk123.com +sqjrc.com +sqjsxy.com +sqjt.com +sqjtcy.com +sqjvx.org +sqkb.com +sqklrq.com +sql110.com +sqlpub.com +sqlsec.com +sqluck.com +sqmarathon.com +sqmn666.com +sqphb.com +sqpx.org +sqqmall.com +sqqmtj.com +sqqnh.org +sqrc.net +sqrcw.com +sqreader.com +sqrsks.com +sqrtthree.com +sqrush.com +sqs373.com +sqshmzx.net +sqsjt.net +sqstudio.com +sqswjt.com +sqsyy.com +square16.org +squarecn.com +squarefong.com +squirrelboiler.com +sqwenhua.com +sqxww.com +sqyai.com +sqyhw.com +sqzjg.com +sqzs.com +sqzw.com +sqzyxy.com +sr-139.com +srcb.com +srcbcz.com +srcbeijing.com +srccdn.com +srccdn2.com +srcge.com +srcgsre.com +srcmsh.com +srcqeece.com +sre.ink +srell.com +srfip.com +srgnmsrg.com +srgow.com +sriappalam.com +sribs.com +sric.fun +srichina.org +srici.com +sritsoft.com +srixon-china.com +srlfl.com +srlzzp.com +srmyy.com +srrcw.com +srrsh.com +srrtvu.com +srschool.net +srslyy.com +srsq.club +srt365.com +srtong.com +srun.com +srvbus.com +srw00.com +srworld.net +srx3.net +srxiayunbusiness.com +srxww.com +srxzz.com +srygz.com +srzc.com +srzdq.com +srzx.com +srzx100.com +srzxjt.com +ss-ceo.com +ss-smartech.com +ss03.net +ss1969.com +ss2007.com +ss246.com +ss256.com +ss28.com +ss8899888.com +ssalegs.store +ssaocorp.com +ssawhotels.com +ssaxx.com +ssaya.win +ssbbww.com +ssbgzzs.com +ssbifen.com +ssbjf.com +ssbjsy.com +ssbx.me +ssby.cc +ssby66.com +ssc-mcc.com +sscanmou.com +sscejia.com +sscha.com +sschengtou.com +sscity.org +sscms.com +sscmwl.com +sscom.vip +ssctp.com +sscy.net +ssdaex.com +ssdata.com +ssdax.com +ssdfans.com +ssdp.com +ssdzg.com +sseinfo.com +ssf.cc +ssfb86.com +ssfei.com +ssfetsz.org +ssffx.com +ssfqsfvd.com +ssgedm.com +ssgeek.com +ssgsemi.com +ssgz.com +sshr.net +ssia.cc +ssidc.net +ssidc.org +ssine.cc +ssine.ink +ssipex.com +ssis.asia +ssish.com +ssixvo9gaybkp5.com +ssjj2.com +ssjjss.com +ssjjtt.com +ssjlicai.com +ssjljk.com +ssjytc.com +ssjyxx.com +sskc360.com +sskgame.com +sskoo.com +ssky123.com +ssl-zs.cc +sslaaa.com +sslad.com +sslawy.com +sslceshi.com +sslchaoshi.com +sslchina.com +sslcity.com +ssldun.com +ssldun.vip +ssleye.com +sslibrary.com +sslnode.com +sslso.com +ssltgm.com +ssmc-sz.com +ssmchina.org +ssmec.com +ssmedic.com +ssmept.com +ssmys.com +ssmysh.com +ssnewyork.com +ssnm.xyz +ssnuo-ch.com +ssofair.com +ssoffo.com +ssoouu.com +ssp.group +sspaas.com +sspai.com +sspai.me +sspeeddns.com +sspjizb.com +ssports.com +ssports.net +ssptqt.com +ssqgx.com +ssqtt.com +ssqzj.com +ssrcdn.com +ssrcr.com +ssreader.com +ssrjzs.com +ssrlzy.net +sss.wiki +sss348499.com +sss437942.com +sss495830.com +sss850697.com +ssscdn.com +sssch.net +ssses.net +ssslgs.com +sssmro.com +sssmy.com +ssso.com +sst-ic.com +sst-sd.com +sst-sz.com +sstlp.com +ssuip.com +ssw777734dh1.shop +sswater.com +sswchina.com +sswl315.com +ssws.tv +ssxcycy.com +ssxf.net +ssxjd.com +ssxpxjt.com +ssxx.site +ssxxp.com +ssyapi.com +ssyar.com +ssycw.com +ssydt.com +ssyer.com +ssyssf.com +ssywh.com +ssyxlx.com +ssyxmall.com +ssyzx.net +sszgit.com +sszhg.com +sszjnc.com +sszsj.cc +st-jzx.com +st-recovery.com +st001.com +st12121.net +st123.com +st180.com +st3tzmp6gg.work +staarphewas.org +stacf.com +stachina.org +stackboom.xin +stackcc.com +stackoom.com +stackoverflow.club +stackoverflow.wiki +stage1st.com +stage3rd.com +staginfo.com +staging-controlbe.floonet.goog +staging-databe.floonet.goog +staging.databe.floonet.goog +staidson.com +standard-groups.com +standardcn.com +standardshop.net +standardsofchina.com +standteam.net +stanlyview.com +staofchina.com +stapharma.com +star-charge.com +star-elink.com +star-engine.com +star-kid.com +star-linear.com +star-meeting.com +star-new-material.com +star-river.com +star365.com +star7game.com +star7th.com +stararc-coating.com +starbaby.cc +starbaby.com +starbaysoft.com +starcharge.com +stardata360.com +starde.net +stardict.net +stardict.org +stards.com +stardust2000.com +starduster.me +starfishcloud.com +starfivetech.com +starhalo.mobi +staringos.com +starkai.com +starkettle.com +starlakelab.com +starlink.uno +starlu.com +starm.cc +starming.com +starooo.com +starpainters.net +starpiao.com +starrails.com +starrevs.com +starrockinvest.com +starrtc.com +starrydyn.com +starryfrp.com +starrymed.com +starrysurvey.com +stars-one.site +starschina.com +starschinalive.com +starscube.com +starsharbor.com +starsino.com +starsmicrosystem.com +starsshine1.com +starsshine2.com +starstech.cc +starswar.org +startcarlife.com +startcatcher.com +startcomca.net +startdt.com +startech.ltd +starting2000.com +startogether1.com +startos.com +startos.org +startssl.com +startup-partner.com +starwarschina.com +starway.net +starwaycomm.com +starworldgames.com +starworldmacau.com +starwsn.com +starxn.com +staryea.com +stat-nba.com +stat08.com +stat18.com +static-login.gog-statics.com +static.cdnetworks.com +static.eprintsw.com +static163.net +staticaa.com +staticdn.net +staticec.com +statickksmg.com +statics.cc +staticsdd.com +staticsoe.com +staticsoem.com +staticswin.com +stationpc.com +stats.ipinyou.com +statsinstall.xyz +statuslarkoffice.com +stay-bullish.com +staybrowser.com +staycu.com +stbieshu.com +stboy.com +stbs100.com +stc2002.com +stcaimcu.com +stcfa.org +stcfile.com +stcmcu.com +stcmcudata.com +stcmih.com +stcn.com +stcy168.com +stcyzls.com +stdaily.com +stdard.com +stdhgd.com +stdicloud.com +stdlibrary.com +stdmm.org +stdout.pub +stdwp.com +ste56.com +stea2008.com +steam302.xyz +steambig.com +steamboxs.com +steamcn.com +steamcommunity-a.akamaihd.net +steamdd.com +steamdt.com +steamgift.site +steamhost.info +steammm.com +steampp.net +steamproxy.net +steampy.com +steamrepcn.com +steamxdf.com +stec.net +stecn.org +stedu.net +steel-mate.com +steel-spot.com +steeljs.com +steelkey.com +steelphone.com +steelsearcher.com +stefg.org +stegameskins.com +steinberg-cn.com +stelinno.com +stellarplayer.com +stemceltech.com +step-by-step.tech +step-motor.com +stepelectric.com +stepsigriner.com +stereorise.com +steriguardmed.com +stexc.online +stfile.com +stgiantfilms.com +sthforme.com +sthfsteel.com +sthifi.com +sthke.com +sthospital.com +sticksgame.com +stjinfa.com +stjinguan.com +stjjxh.com +stkfanli.com +stklt.com +stlb520.com +stmaoyi.com +stmbuy.com +stmjsociety.com +stmybj.com +stnn.cc +stnts.com +sto-express.com +stocke.com +stockhn.com +stockradar.net +stockren.com +stockstar.com +stockwei.com +stofund.org +stointl.com +stojf.com +stone139.com +stone168.com +stone365.com +stonebtb.com +stonebuy.com +stoneios.com +stoneleague.com +stoneo2o.com +stonepoll.com +stonepoll.net +stonescloud.com +stonesm.com +stoneu.com +stonexp.com +stor-age.com +stor-helper.com +storage-asset.msi.com +storcezon.com +store12.com +storeapi.net +storecorefulfillment.download.prss.microsoft.com +storeedge.microsoft.com +storeedgefd.dsx.mp.microsoft.com +storkapp.me +stormorai.com +story520.com +storyboardworld.com +storyren.com +stosolution.com +stourweb.com +stourweb.net +stovol.club +stoyard.com +stozxmveui4pvr.com +stpolice.com +stpos.net +stqiyuan.com +stql.com +stql.org +str-mo.com +straitchain.com +strategy-sight.com +stray-soul.com +stream.baoxinwen.com +stream.dybtv.com +stream.guihet.com +stream.houstonpublicmedia.org +stream.nbbltv.com +stream.rcs.revma.com +stream.slave.jxtvnet.tv +stream.superfm99-1.com.tw +stream.wbez.org +stream.xctv.news +stream.zhystv.com +stream.zzgd.tv +stream0.tv41.ru +stream01.dqtv123.com +stream1.shopch.jp +stream2.cprnetwork.org +streamax.com +streamaxtech.com +streamcomputing.com +streamipcf.akamaized.net +streamlakeapi.com +streffy.com +strinova.com +strong-light.com +strong-study.com +strongfc.com +strongflc.com +strongled.com +stshuizhi.com +stsmt.com +stssugar.com +stswjx.com +stszcm.com +stt-bearing.com +sttanso.com +sttcq.com +sttry.com +stu-lab.com +stu-works.com +stu51.com +stubbornhuang.com +studa.net +studentboss.com +studioartiz.com +studstu.com +study-cloud.com +study163.com +studyems.com +studyez.com +studyfor.work +studyfr.net +studyget.com +studygolang.com +studyhub.fun +studyingtours.com +studypay.com +studyquicks.com +studytime.xin +studyuser.com +studyvip.com +stuhome.net +stuhui.com +stuky.net +stulip.org +stuliving.com +stuln.com +stunnel.vip +stupid77.com +stupidet.com +stuq.com +sturgeonnews.com +sturmdcp.com +stutimes.com +stvf.com +stvgame.com +stwj.com +stwyxh.com +stxfjs.com +stxsw.com +stylecdn.com +stylechina.com +styles-sys.com +stzc.com +stzzx.com +su-jiao.com +su-long.com +suaee.com +suan5.com +suanbanyun.com +suanchang.com +suandao.com +suanguaju.com +suanjiayun.com +suanjuzi.com +suanpin.com +suanst.com +suansuangua.com +suanya.com +suapp.me +suawin.com +subangjia.com +subaonet.com +subaoxw.com +subaru-li.org +subeiflower.com +subelf.net +subingkang.com +subinwechat.com +subline.org +subo.net +subom.net +subond.com +subuy.com +sucai.com +sucai77.com +sucai999.com +sucaibar.com +sucaidao.com +sucaifu.com +sucaijiayuan.com +sucaijishi.com +sucainiu.com +sucaiplus.com +sucaisucai.com +sucaitu.cc +sucaiw.com +success001.com +successhr.com +succez.com +sucdri.com +such-game.com +suchasplus.com +suchengmeizhan.com +suchugao.com +sucjg.com +sucop.com +sucoupon.com +sudaizhijia.com +sudaoa.com +sudasuta.com +sudawuye.com +suddenfix.com +sudecoating.com +sudoinfotech.com +sudu-67ph.com +sudu-72ub.com +sudu-ab6h.com +sudu-by4e.com +sudu-du9k.com +sudu-kay6.com +sudu-me6n.com +sudu-pq2y.com +sudu-q6wk.com +sudu-r8gh.com +sudu-sq56.com +sudu-tf42.com +sudu-xu9b.com +sudu-y94k.com +sudu123.net +suducha.com +sududa.com +sudundns.com +sudupower.net +sudusite.com +suease.com +suemor.com +sueon.com +sufachina.com +sufangxu.com +sufeinet.com +sufoma.com +sufont.com +sufybkt.com +sufycdn.com +sugaov.com +sugar5.club +sugarall365.com +sugarenergy.com +sugarguo.com +sugarle.com +sugessofficial.com +sugon.com +sugou.com +suguangxx.com +sugwedding.com +suhaoyy.com +suhedj.com +suhedz.com +suhergroup.com +suhuishou.com +sui.com +sui.me +suibao-jiaozhu.com +suibao.com +suibiji.com +suibo.org +suiji123.com +suijinetworks.com +suijunlaowu.com +suilengea.com +suileyoo.com +suimeng.la +suinikan.com +suiningwang.com +suiniyi.com +suiqiao.com +suirui.com +suishenyun.net +suishouji.com +suishouxie.com +suishouzj.com +suisuihu.com +suisuijiang.com +suitaichem.com +suitdaily.com +suiunited.com +suixianwang.net +suixin8.com +suixingpay.com +suixinzulin.com +suixkan.com +suixw.com +suiyichong.com +suiyifa.com +suiyiju.com +suiyuanjian.com +suizhoushi.com +suizui.net +sujh.net +sujia.cc +sujiagroup.com +sujiao1668.com +sujw.com +sujx.net +sukean.com +sukeler.com +sukeyun.com +suki.club +suki.moe +sukimon.me +sukiu.net +sukkaw.com +sukoshi.xyz +sukoutu.com +sukvm.com +sulabs.net +sulaixue.com +sulamp.com +sulandscape.com +suleapi.com +suliaodingzhi.com +suliaojian.com +sulicn.com +sulitui.com +suluf.com +sulvwenhua.com +sumaart.com +sumaarts.com +sumapay.com +sumatang.com +sumavision.com +sumcl.com +sumec.com +sumedu.com +sumeme.com +sumer.work +sumgotea.com +sumian.com +sumiao.net +sumiaowang.com +sumibuy.com +sumkoo.com +sumkoo.net +sumly.net +summall.com +summercampschina.com +summerfarm.net +summerlight.com +summerlight.name +summerpalace-china.com +summitpharmachina.com +summitviewcapital.com +sumoon.com +sumrday.net +sumscope.com +sumuda.tech +sumwin.com +sumzc.com +sumzi.com +sun-ada.net +sun-coo.com +sun-create.com +sun-feel.com +sun-hua.com +sun-park.com +sun-wish.com +sun0769.com +sun0769ns.com +sun0816.com +sun66.net +suna-opto.com +sunaas.com +sunacctg.com +sunalytools.com +sunari17.com +sunasia.com +sunbelife.com +sunbl.com +sunbloger.com +sunbo.com +sunbo367.com +sunborngame.com +sunbowhospital.com +sunboxsoft.com +sunboyu.com +suncereltd.com +suncjm.com +sundan.com +sundaydragon.com +sundayvision.net +sundns.com +sundray.com +sunear.net +sunease.net +sunemc.com +suner.cc +sunera-cn.com +sunergyworks.com +sunflowerscf.com +sunfounder.cc +sunfreight-logistics.com +sunfront.com +sunft.com +sungainyeast.com +sungari1995.com +sungent.com +sungesoft.com +sungine.com +sunglow-tec.com +sungoal.org +sungoedu.com +sungroup-energy.com +sungshu.com +sunhan.vip +sunhante.com +sunhepower.com +sunhongs.com +sunhospital.net +sunhuhotel.com +suninf.net +suninfo.com +suning.com +suningbank.com +suningcdn.com +suningcdn.net +suningcloud.com +suningdns.com +suningdns.net +suningestate.com +suninggslb.net +suningholdings.com +suninghotel.com +suninghotels.com +suningmail.com +suningpay.com +suningyunyou.com +sunjex.com +sunjiadai.xyz +sunjianjian.com +sunjs.com +sunkeydata.com +sunland.vip +sunlandlaw.com +sunlands.com +sunlandstudy.com +sunlandvip.com +sunlandzk.com +sunleader.net +sunlife-everbright.com +sunlight-tech.com +sunlogging.com +sunlogin.com +sunlogin.net +sunlons.com +sunlordinc.com +sunlune.com +sunmarr.com +sunmeihotel.com +sunmen.com +sunmi.com +sunmingxia.com +sunmmio.com +sunmmm.com +sunmnet.com +sunmoonepe.com +sunnatech.com +sunnercn.com +sunnergp.com +sunnsoft.com +sunny90.com +sunnyaiot.com +sunnychina.com +sunnyfly.com +sunnyhaitai.com +sunnyhf.com +sunnylab.work +sunnylawyer.com +sunnyms.com +sunnyoptical.com +sunnyos.com +sunnyplas.com +sunnypure.com +sunnyqi.com +sunnysemi.com +sunnyxx.com +sunocean.life +sunofbeaches.com +sunofus.org +sunon-china.com +sunon-power.com +sunonln.com +sunorensolar.com +sunorlng.com +sunowe.com +sunowo.com +sunpala.com +sunpapergroup.com +sunpeed.com +sunpowergroup.biz +sunprocn.com +sunpun.com +sunrain.com +sunrate.com +sunray2000.com +sunresin.com +sunresin.net +sunrisedutyfree.com +sunrisegroupcn.com +sunrisenan.com +sunrisesha.com +sunrizetech.com +sunrtb.com +sunrtnet.com +sunsea.net +sunseekerpower.com +sunsetcare-mirrortech.com +sunsharer.com +sunshine-power.net +sunshine-sino.com +sunshinecoasthomesearch.com +sunsili.com +sunsilu.com +sunsine.com +sunspotfund.com +sunstarasia.com +suntech-metal.com +suntech-power.com +suntechospital.com +suntgj.com +suntimehousehold.com +suntop168.com +suntray.com +suntrayoa.com +suntront.com +sunup.name +sunup3d.com +sunupcg.com +sunus-china.com +sunvim.com +sunvio.com +sunwardcap.com +sunwatt.com +sunwaygas.com +sunwayland.com +sunwaypharm.com +sunways-portal.com +sunwayworld.com +sunwayx.com +sunweihu.com +sunweiwei.com +sunwellpower.com +sunwin-china.com +sunwin2001.com +sunwinon.com +sunwoda.com +sunwoodacoustic.com +sunxiaoning.com +sunxisc.com +sunyaholding.com +sunyansong.com +sunyard.com +sunyea.com +sunyet.com +sunyitech.com +sunyoads.com +sunyuu.com +sunywo.com +sunzhongwei.com +sunzn.com +suo.im +suobao8.com +suobifa.com +suobuy.com +suoer-group.com +suofeiya.com +suofeiyashop.com +suoge.net +suolong.com +suoluomei.com +suopingbao.com +suorang.com +suosihulian.com +suotn.com +suoxin5.com +suoyiren.com +supafa.com +supaq.com +suparc.com +supcname.com +supcompute.com +supcon.com +supconauto.com +supconit.com +supdri.com +supeeder.com +supei.com +super-king.net +super-mt.com +superace.com +superacme.com +superaicdn.com +superayi.com +superbed.cc +superboss.cc +superbrandmall.com +superbrowser.com +superbrowser.hk +superbuy.com +superbuyy.com +supercachenet.com +supercachenode.com +supercalnow.com +supercarrier8.com +supercell.com +supercrm.com +superdns.org +superepoxyresin.com +superfix.com +superhcloud.com +superic.com +superiorscope.com +superjq.com +superlib.com +superlib.net +superlink.mobi +superlinkscm.com +superlitetech.com +superljq01.com +supermap.com +supermap.io +supermapcloud.com +supermapol.com +supernode.pro +superpb.com +superpowercn.com +superqq.com +superrrai77.com +supers.ltd +supersharket.com +supersocket.net +superstar-med.com +superstarkennel.com +superstars.vip +supertime-malting.com +supertracker.net +supertrw.com +supervisionus.com +supervote.cc +superwrt.com +superyd.com +superyears.com +superzl.com +supesite.com +supesoft.com +supet.com +supgroups.com +suplaymart.com +supman.com +supmea.com +supmeter.com +supmil.com +supmil.net +supoin.com +supool.com +supor.com +suporgroup.com +suporpharm.com +supplierlist.com +supplygw.com +supplywater.com +support-cn.samsung.com +supportassist.dell.com +supreme-oe.com +supwisdom.com +supwk.com +suqian360.com +suqianhospital.com +suqing.com +suqishi.com +suqnn.com +suqun-group.com +surely.cool +surerp.com +surface.download.prss.microsoft.com +surface.downloads.prss.microsoft.com +surfacetreatmentgroup.com +surfacetreatmenttechnology.com +surfcg.com +surgerii.com +surgerycast.com +surgi-plan.com +surmounthat.com +surprising.studio +sursen.com +sursenelec.com +sursung.com +surtime.com +suruicloud.com +surun-tech.com +survey.work +surveyhills.com +surveyqq.com +surveyrtk.com +surveyunion.com +survivor99.com +surwit.com +suryee.com +suseage.com +sushijiameng.com +sushiyanglao.com +sushui.com +suso56.com +susong1.com +susong51.com +susongbbs.com +susoul.com +sustcra.com +sustech.online +susudm.com +susun.cc +susungroup.com +sutanapp.com +suteidc.com +suteshop.com +suting123.com +sutpc.com +sutune.me +sutuobang.com +suujee.com +suuny0826.com +suv-trip.com +suv666.com +suwen.org +suxiangsj.com +suxiazai.com +suxieban.com +suxiege.com +suxing.me +suxuejiaoyu.com +suxx0.com +suyangroup.com +suyuantuliao.com +suyuening.com +suyugame.com +suyujoy.com +suyun.net +suyunc.com +suyunj.com +suyur.com +suyutech.com +suyuzz.com +suzhongyy.com +suzhou-marathon.com +suzhou-otsuka.com +suzhouballettheatre.com +suzhoubank.com +suzhoubeili.com +suzhoubond.com +suzhoucitymarathon.com +suzhoudyh.com +suzhouexpo.com +suzhoufashion.com +suzhouhengtai.com +suzhouhui.com +suzhoujicai.com +suzhouleasing.com +suzhoulida.com +suzhoulinsen.com +suzhousj.com +suzhouyabao.com +suzip.com +suzport.com +suzuki-china.com +suzuki-shanghai.com +svconcloud.com +sve.cc +sveir.xyz +svell.net +svenhetin.com +svfrrg.com +svgoptronics.com +svimeng.com +svinsight.com +svip51.com +svipdog.com +svipgulr.com +sviping.com +svk3o97xmyid93.com +svlik.com +svmxxaq.com +svn999.com +svnbucket.com +svnspot.com +svp6.com +svpchina.org +svqsokp.com +svrvr.com +svw-volkswagen.com +svwuc.com +svyun.com +sw-bllp.com +sw-zh.com +sw0013.com +sw163.com +sw2008.com +sw996.com +swakopuranium.com +swan366.com +swanchemical.com +swang8.com +swangwx.com +swanhub.co +swaqds.com +swarma.net +swat-js.com +swatou.com +swaywm.com +swbbsc.com +swceb.com +swchina.org +swckc.com +swdcmg.com +swdyz.com +sweet-data.com +sweetalkos.com +sweetjing.cc +sweetlove.cc +sweetmartmarketing.com +sweetome.com +sweetread.net +sweetrouble.com +sweetystory.com +swelder.com +swellfun.com +swfc-shanghai.com +swfzjt.com +swg36.com +swgocean.com +swgzs.com +swgzy.com +swhydyj.com +swhysc.com +swift-at.com +swift51.com +swiftfintech.com +swifthumb.com +swiftjava.com +swiftlet.net +swijoy.com +swip.group +swirebev.com +swirecocacola.com +swisdom.cc +swissgenie.com +swissrepicass.com +swissreplicas.cc +swisswatcheshot.com +swisswatchx.com +swit-battery.com +swit.cc +switchb2b.com +switchxiazai.com +switzerland-visacenter.com +swjjshfw.com +swjoy.com +swjsj.com +swjtjt.com +swkedou.com +swkong.com +swkpe.tw +swliuxue.com +swltools.com +swnic.com +swofcare.com +swomc.net +swoole.com +swordair.com +swordart.online +swordofmorning.com +swords.center +swordtt.com +swpubar.com +swq242xc54.com +swrjzxw.com +swrtxtb.com +swsbw.com +swsegroup.com +swskj.com +swsm.net +swsmu.com +swstsg.com +swt0.com +swtpu.com +swufe-online.com +swupdl.adobe.com +swwy.com +swxk.cc +swxxvr.com +swyun.net +swz001.com +swzj.com +swzx.com +sx-merryland.com +sx-moen.com +sx-seafood.com +sx1211.com +sx189.com +sx267.com +sx311.cc +sxaec.com +sxafz.com +sxalu.com +sxand.com +sxase.com +sxasuykzx2sq.icu +sxatcm.com +sxbada.com +sxbang.net +sxbawy.com +sxbctv.com +sxbdf.com +sxbest.com +sxbjedu.com +sxbpa.com +sxbuszp.com +sxbychem.com +sxcahosp.com +sxccb.com +sxcd-gyl.com +sxcgzh.com +sxchangshengjt.com +sxcig.com +sxcitygas.com +sxclassiclighting.com +sxcm.net +sxcntv.com +sxcoal.com +sxcp.com +sxctf.com +sxcxgf.com +sxcxldjy.com +sxcyts.com +sxcywy.com +sxczdz.com +sxd408.com +sxdagang.com +sxddy.com +sxdkj.com +sxds.com +sxdzyp.com +sxepa.org +sxepc.com +sxetcedu.com +sxfl.org +sxfoundation.com +sxfu.org +sxgbs.com +sxgdtv.com +sxggec.com +sxggzp.com +sxgjj.com +sxglpx.com +sxgoo.com +sxgq.net +sxgrw.com +sxgs.com +sxgsps.com +sxhbjt.com +sxhbjtshj.com +sxhctv.com +sxhhwl.com +sxhhyy.com +sxhimalayanqd.com +sxhiway.com +sxhjrc.com +sxhkstv.com +sxhkxy.com +sxhlcc.com +sxhlfjt.com +sxhlxy.com +sxhm.com +sxhongyuan.com +sxhospital.com +sxhtss.com +sxhtyy.com +sxhtyy.net +sxhwhb.com +sxhwls.com +sxhxbank.com +sxisa.org +sxj7k.com +sxjant.com +sxjbswyy.com +sxjcdyy.com +sxjd-cn.com +sxjdfreight.com +sxjdpm.com +sxjg-wl.com +sxjgkg.com +sxjhzsgc.com +sxjianli.com +sxjinfengjiuye.com +sxjky.com +sxjmfxky.com +sxjntech.com +sxjtyhjt.com +sxjwlkj.com +sxjxdyqfw.com +sxjxsc0.org +sxjybk.com +sxjzxww.com +sxkbzc.com +sxkids.com +sxkzxt.com +sxlcdn.com +sxldns.com +sxlfwl.com +sxlhrj.com +sxlib.com +sxlljm.com +sxlottery.net +sxlpd.com +sxls.com +sxltsj.com +sxluxiang.com +sxmda.net +sxmhgas.com +sxmty.com +sxmxwh.com +sxmyh.com +sxncb.com +sxnxs.com +sxnxxny.com +sxnycl.com +sxol.com +sxpgb.com +sxplc.com +sxpmg.com +sxpmpos.com +sxprgc.com +sxpta.com +sxpyzg.com +sxpyzx.com +sxqingyi.com +sxqzy.com +sxrb.com +sxrbw.com +sxrcw.net +sxrczx.com +sxrekord.com +sxri.net +sxrom.com +sxrqrlxh.com +sxrqxny.com +sxrszdh.com +sxrtv.com +sxrxgs.com +sxrxyc.com +sxs56.com +sxs8818.com +sxsa.org +sxsanwei.com +sxsapi.com +sxscwl.com +sxsedu.net +sxsfdxylsyzx.com +sxsfky.com +sxsfyyy.com +sxsgs.com +sxshjhyxh.com +sxshu.com +sxsim.com +sxsimg.com +sxsjgy.com +sxsjzyxh.com +sxslhg.com +sxslnews.com +sxsme.org +sxsmtgyxh.com +sxsng.com +sxsoft.com +sxsqxj.com +sxsqyjxh.org +sxsrmyy.com +sxsslz.net +sxssyh.com +sxswfzjt.com +sxsyyxh.com +sxsyyxh.net +sxsztv.com +sxszw.net +sxtbu.net +sxtcm.com +sxtgedu.net +sxtianjian.com +sxtourgroup.com +sxtourism.com +sxtppm.com +sxtqsl.com +sxtracking.com +sxtv6.com +sxtvs.com +sxudqg.com +sxuyr2nx.com +sxvtc.com +sxwao4zi6dgp.com +sxwbedu.com +sxwbs.com +sxwetalent.com +sxwlyhzp.com +sxworker.com +sxwpyx.com +sxwq.com +sxwstcm.com +sxwtdyd.com +sxww.com +sxxfj.com +sxxl.com +sxxrmyy.com +sxxsmjh.com +sxxt.net +sxxw.net +sxxyfw.com +sxxynews.com +sxxzpt.com +sxy7.com +sxyasen.com +sxyckjr.com +sxycpc.com +sxycrb.com +sxycys.com +sxygsj.com +sxyj.net +sxyqgs.asia +sxyrxb.com +sxyxqk.com +sxyyc.net +sxyyzcj.com +sxzhaobiao.com +sxzhongfei.com +sxzhyy.com +sxzkzs.com +sxzlycl.com +sxzlyy.com +sxzq.com +sxzxsdf.com +sxzydj.com +sxzyfy.com +sxzytech.com +sy-game.com +sy-home.com +sy-yy.com +sy021.com +sy118.com +sy12306.com +sy12328.com +sy17.com +sy1994.com +sy1z.com +sy2k.com +sy2z.com +sy3.com +sy76.com +syais.com +sybasebbs.com +syberos.com +syberq.com +sybj.com +sybxpu.com +sybygx.com +syc738gtwihc2.com +sycaijing.com +sycdtz.com +sychlon.com +sycontroller.com +sycreader.com +sycsgj.com +sycxzx.net +sydaxxw.com +sydcch.com +sydcdjt.com +sydey.com +sydfty.com +sydhyg.com +sydjwl.com +sydkidsedu.com +sydneyglobaltimes.com +sydtgd.com +sydw.net +sydw8.com +sydxdl.com +syeamt.com +syeg-ev.com +syepia.org +syetyy.com +syf.ink +syfabiao.com +syfb2021.com +syfj.net +syfly007.com +syfw.com +syfyyy.com +syg315.com +sygcjs.com +sygcjsxh.com +sygd.com +sygjj.com +sygjzx.com +syglyg.com +sygnew.com +syh666.com +syhccs.com +syhfxsh.com +syhhidc.com +syhhkj.com +syhl.vip +syhlgg.com +syholdings.com +syhospital.com +syhouse.net +syhsfzl.com +syhsxb.com +syhuayang.com +syhzdj.net +syhzx.com +syhzzf.com +syiptv.com +syitgz.com +syjcly.com +syjiancai.com +syjkqzw.com +syjlp.com +syjsq.com +syjt.com +syjtwlzx.com +syjtzm.com +syjyzl.com +syjzedu.com +syk2023.com +sykezheng.com +sykfff.com +sykong.com +sykt520.com +sylangyue.xyz +sylaryun.com +sylc.xyz +sylincom.com +sylixos.com +sylm2022.com +sylmg.com +sylnyx.com +syltgl.com +symama.com +symarathon.com +symbiote.work +symboltek.com +symf-crm.com +symtc.com +syn-tron.com +syn029.com +synball.com +sync.sh +syncedoffplanet.com +syncozymes.com +syngars.com +syngenemed.com +synjones.com +synjones.net +synnchem.com +synochip.com +synodc.com +synology-cn.com +synologyssb.com +syntao.com +synyan.net +synyi.com +synykj.net +syobserve.com +syoits.com +syoker.com +syoseo.com +syounggroup.com +sypglass.com +sypole.com +sypost.com +sypost.net +sypvm.com +syq666.com +syr-sce.com +syranqi.com +syrc.org +syrcb.net +syrczpw.com +syreads.com +syrecovery.com +syrhkj.com +syrinxchina.com +syrqgas.com +syrszs.com +sys-ele.com +sys321.com +syscan360.com +syscan360.net +syscan360.org +sysceo.com +sysceo.net +syscxp.com +sysdyy120.com +sysengi.com +syshell.com +syshospital.com +syshospital.org +syshosts.net +sysjnl.com +sysjoint.com +sysmaster.online +sysmini.com +sysmls.com +sysnfj.com +sysshine.com +systedata.com +systemsci.org +systemserviceable.com +systoon.com +sysu-pharm.com +sysucc.com +sysuschool.com +sysush.com +syswgw.com +sysx.tech +sysxhz.com +sysydz.net +sysyhfj.com +sysysjnk.com +syt1000.com +sytcke.com +sytfgroup.com +sythealth.com +sytjcc.com +sytlj.com +sytlw.com +syttgame.com +sytuku.com +syuan.com +syuan.net +syue.com +syw6.com +sywg.com +sywgy.com +sywtqc.com +syx-ac.com +syxb.com +syxidao.com +syxjjsw.com +syxlgame.com +syxt.cc +syxw.xyz +syxwang.com +syxwnet.com +syxzhongyi.com +syyan.site +syyc.com +syygjs.com +syyjs.com +syyl.org +syylfh.com +syyqls.com +syysjt.com +syyx.com +syyy99.com +syyyd.com +syyyj.com +syyyking.com +syyzhpc.com +syzdhyb.com +syzjjt.com +syzlzz.com +syzoukan.com +syzpw.com +syzsgroup.com +sz-3a.com +sz-acuvu.com +sz-amc.com +sz-baile.com +sz-bst.com +sz-building.com +sz-byg.com +sz-cbea.com +sz-cerberus.com +sz-changfeng.com +sz-changhong.com +sz-coin.com +sz-czzc.com +sz-dfl.com +sz-dns.net +sz-ebest.com +sz-edsy.com +sz-ekl.com +sz-el.com +sz-etong.com +sz-expressway.com +sz-fesco.com +sz-fukuda.com +sz-function.com +sz-gaokai.com +sz-hbwy.com +sz-hdenergy.com +sz-hengdeyuan.com +sz-hiragawa.com +sz-huashi.com +sz-huayuan.com +sz-hyauto.com +sz-hzt.com +sz-iso.com +sz-jiahong.com +sz-jlc.co +sz-jlc.com +sz-jyd.net +sz-kaito.com +sz-keli.com +sz-khgroup.com +sz-ky.com +sz-kye.com +sz-lcsc.com +sz-lzyy.com +sz-map.com +sz-matro.com +sz-mtr.com +sz-myjs.com +sz-news.com +sz-osckj.com +sz-printing.com +sz-qb.com +sz-rlx.com +sz-sunway.com +sz-suwan.com +sz-talant.com +sz-tianmai.com +sz-trip.com +sz-tyjx.com +sz-ua.com +sz-xingfu.com +sz-xiran.com +sz-yian.com +sz-ytq.com +sz-zhenghe.com +sz002329.com +sz0429.com +sz121.com +sz1905.com +sz1978.com +sz1z.com +sz2048.com +sz240.com +sz2g.com +sz315.org +sz3dp.com +sz3e.com +sz3gao.com +sz56t.com +sz5983.com +sz7h.com +sz800.com +sz836.com +sz886.com +sz910.com +sz96296.com +szaaci.com +szacc.com +szaccl.com +szaction.com +szadf.com +szadna.net +szadst.com +szaeia.com +szagera.com +szahotel.com +szai.com +szaiaitie.com +szaicx.com +szaid.com +szaima.com +szaipx.com +szairport.com +szaisino.com +szaiten.com +szaixian.com +szajsj.com +szamc.com +szande.com +szanjun.com +szaojin.com +szas.com +szastcg.com +szaudio.com +szaudio.net +szaupd.com +szautism.com +szbaba.com +szbaicao.com +szbaike.com +szbaleng.com +szbaoly.com +szbaoming.com +szbattery.org +szbayy.com +szbazx.com +szbbs.org +szbcase.com +szbcfurniture.com +szbdzs.com +szbeilu.com +szbeilu888.com +szbhwk.com +szbhyy.com +szbia.com +szbih.com +szbike.com +szbim.com +szbinying.com +szbiu.com +szbnrj.com +szboehospital.com +szbojay.com +szbosen.com +szbosk.com +szbrandweek.com +szbryq.com +szbubu.com +szbwgy.com +szbyzn.com +szc-ic.com +szca.com +szcat.org +szcatic.com +szcbc.com +szcfjt.com +szcfyi.com +szcgc.com +szcgkg.com +szch-cn.com +szchengli.com +szchengyue.com +szchilink.com +szchunqiu.com +szcic.com +szcidg.com +szclbxf.com +szcleanair.com +szclxzx.com +szcmer.com +szcnpiec.com +szcogo.com +szcompare.com +szcp.com +szcsot.com +szcssx.com +szcswater.com +szctch.com +szctkj.net +szcttlab.com +szctyx.com +szcua.org +szcw.com +szcwdz.com +szcxjscl.com +szcy-fintech.com +szcy99.com +szczjy.com +szczkjgs.com +szdaily.com +szdcjd.com +szddns.net +szdesigncenter.org +szdesigner.org +szdesy.com +szdf.com +szdhjt.com +szdiantu.com +szdihang.com +szdiyibo.com +szdkgssb.com +szdljt.com +szdlsjj.com +szdn1ms.com +szdpi.com +szdprt.com +szdrse.com +szds.com +szdsit.com +szdtwcw.com +szdunan.net +szduopin.com +szdwwy.com +szdwxy.com +szdwyy.com +szdx189.com +szdxfsrhyy.com +szdz123.com +szdzczp.com +szeant.com +szeastroc.com +szeasyin.com +szebus.net +szecowater.com +szects.com +szed.com +szeds.com +szedu.net +szeeg.com +szegddc.com +szeholiday.com +szeia.com +szelab.com +szelanpo.com +szelec.cc +szelight.com +szelink.com +szepiao.com +szerye.com +szesens.com +szetop.com +szeua.org +szeunon.com +szeverich.com +szfa.com +szfachina.org +szfangzhouhd.com +szfc.net +szfcol.com +szfda.net +szfdg.com +szfdzx.com +szfengtu88.com +szffmr.com +szfg.net +szfglass.com +szfirstplastic.com +szfiu.com +szfjt.com +szfolo.com +szforter.com +szftfybj.com +szftzx.net +szftzy.com +szfutong.com +szfuture.com +szfw.org +szfx.com +szfxdev.com +szfyhd.com +szfyzb.com +szfzx.org +szgalaxy.com +szgangdi.com +szgays.org +szgcyy.com +szggzy.com +szghedu.com +szghgw.com +szgky.com +szgla.com +szglby.com +szglsf.com +szgraphene.com +szgreenhulk.com +szgrjt.com +szgsjc.com +szgt.com +szgthr.com +szguanai.com +szguanghua.com +szguante.com +szguixiang.com +szguoxin.com +szgwin.com +szgwsd.com +szgymz.com +szgztg.com +szh.com +szha.org +szhaian.com +szhaicao.com +szhailan.com +szhaochuang.com +szharmony.com +szhb.org +szhddq.com +szhdy.com +szhdyic.com +szhenglian.com +szhetai.com +szhfwd.com +szhgong.com +szhightondz.com +szhiross.com +szhjwybj.com +szhk.com +szhkhui.com +szhlodz.com +szhlsg.com +szhmjp.com +szhmkeji.com +szhnsz.com +szhome.com +szhomeimg.com +szhongshe.com +szhospital.com +szhot.com +szhq.com +szhqgf.com +szhqyy.com +szhqyy120.com +szhr.com +szhrh.com +szhri.com +szhsdpa.com +szhstjt.com +szhsx.net +szhtp.com +szhua-gao.net +szhuace.com +szhuarong.com +szhuayilong.com +szhubei.com +szhuhang.com +szhulian.com +szhuodong.com +szhvac.org +szhvs.com +szhwad.com +szhxbiz.com +szhytrip.com +szhzsd.com +szhzzl.com +szicbe.com +szicc.net +szicpa.org +szida.org +szider.com +szieg.com +szihl-bayarea.com +szihl-port.com +sziia.org +szind.com +szinvent.com +sziota.com +szitcare.com +sziton.com +szitsa.org +szjags.com +szjawest.com +szjbz.cc +szjcmr.com +szjcyljt.com +szjcyy.com +szjcyyy.com +szjdsd.com +szjfh.com +szjg.net +szjgjt.com +szjhxjt.com +szjianan.com +szjiansheng.net +szjianuo.com +szjiazhao.com +szjiexikeji.com +szjinhejs.com +szjinhuanyu.com +szjinke.com +szjinxinzh.com +szjitu.com +szjjedu.com +szjkhd.com +szjkp.com +szjkxh.com +szjkyun.com +szjlkt.com +szjlwul.com +szjr-tencentclb.cloud +szjr-tencentclb.com +szjr-tencentclb.net +szjr-tencentclb.work +szjsgroup.com +szjsjlxh.com +szjsjt.com +szjtxm.com +szjuhaozn.com +szjunchuang.com +szjunfei.com +szjunlin.com +szjunrong.com +szjuquan.com +szjuwx.com +szjuyou.com +szjxcft-tencentclb.cloud +szjxcft-tencentclb.com +szjxcft-tencentclb.net +szjxcft-tencentclb.work +szjxgroup.com +szjxj.com +szjy.cc +szjyos.com +szjys.net +szjys1888.com +szjytx.com +szjyxtech.com +szjzdcjt.com +szkdxx.com +szkeda.com +szkegao.net +szkente.com +szkete.com +szkgdesign.com +szkingdom.com +szkinks.com +szkjcn.com +szkjjs.com +szkjxh.com +szknet.com +szknk.net +szknys.com +szknyy.com +szkoa.com +szkobo.com +szkosun.com +szkqyy.com +szkrd.com +szl724.com +szlaituo.com +szlande.com +szlangwei.com +szlanyou.com +szlawyers.com +szlc9.com +szlcsc.com +szlcwy.com +szldcc.com +szlddb.com +szlddj.com +szldzb.com +szledia.org +szleezen.com +szlgzxyy.com +szlhtram.com +szlianhua.com +szlianya.net +szlightlink.com +szlihuam.com +szlilun.com +szline9.com +szlinglewangluo.com +szlingsheng.com +szlmxx.com +szlnjt.com +szlnxh.com +szlongyu.com +szlottery.org +szlqjt.com +szlsnk.com +szlswl8.com +szltech.com +szltlh.com +szltour.com +szltwlw.com +szlunhua.com +szluxon.com +szlvbarcode.com +szlwbj.com +szlwtech.com +szlxl100.com +szlzsd.com +szmadigi.com +szmagellan.com +szmall.com +szmama.com +szmama.net +szmaxima.com +szmb.cc +szmc.net +szmcjsjt.com +szmcjt.com +szmcob.com +szmctc.com +szmcy.com +szmea.net +szmedtech.com +szmengqukj.com +szmgci.com +szmhthb.com +szmicrogate.com +szmieps.com +szmii.com +szmil.com +szmjd.com +szmjlcd.com +szmkd.com +szmrcd.com +szmsjs.com +szmslaser.com +szmtc.com +szmtxny.com +szmtzc.com +szmuseum.com +szmwzs.com +szmylike.com +szmynet.com +szmys.com +szmywin.com +szmyxc.com +szn360.com +sznaibeng.com +sznbm.com +sznecn.com +sznewbest.com +sznews.com +sznewworld.com +sznffc.com +sznfwt.net +szngdz.com +szniego.com +szniushi.com +sznnhg.com +szns-marathon.com +sznsyy.net +sznumberone.com +sznwriterhouse.work +szny189.com +sznyfz.com +sznyyznnj.com +szobk.com +szol.net +szolgj.com +szolxd.com +szonline.net +szooo.com +szoxstand.com +szp168.com +szpa.com +szpa.org +szpan-china.com +szpckj.com +szpclab.com +szped.com +szpengfa.net +szpgm.com +szpiaoyi.com +szpldq.net +szpllp.com +szplus.com +szpmi.org +szporter.com +szpowerfly.com +szpra.com +szprl.com +szptxx.com +szputy.com +szqf.org +szqhlx.com +szqhtkyy.com +szqhyf.com +szqiangu.com +szqinyuan.com +szqjxh.com +szqp.site +szqsq.com +szqt.net +szquanli.com +szqycl.com +szqyw.net +szqzsd.com +szrba.org +szrc-hr.com +szrcaj.com +szrcb.com +szrcfw.com +szrch.com +szrfdq.com +szrfstar.com +szrgsh.com +szrhg.com +szrj.net +szrlaw.net +szrrjc.com +szrsks.com +szrswj.com +szrtcpa.com +szruilan.com +szrunning.com +szryc.com +szrzxh.com +szs189.com +szsaibao.com +szsailong.com +szsaiwei.com +szsamr.com +szsandt.com +szsangbo.com +szschj.com +szschl.com +szsci.net +szscree.com +szsczx.com +szsdhjt.com +szsdjrmyy.com +szsdsrmyy.com +szseafoodexpo.com +szseasons.com +szsemicon.com +szsep.com +szsewo.com +szsfgc.com +szsh.com +szshtjm.com +szshuangjin.com +szshuori.com +szshutao.com +szshwy.com +szsia.com +szsing.com +szsjtjj.com +szsjxxpt.com +szskd.com +szsky.com +szslcyy.com +szslhssy.com +szsmk.com +szsmyg.com +szsnk.com +szsoa.org +szsolutia.com +szsongmao.com +szsorch.com +szsptk.com +szsq.net +szsrs.com +szssct.com +szssda.com +szssep.com +szssfor.com +szsswcs.com +szsszx.com +szsta.org +szstar.com +szstariver.com +szstartec.com +szsti.org +szstndzsw.com +szstyle.cc +szsuanli.com +szsunlaser.com +szsunwin.com +szsupvan.com +szswgcjc.com +szswjc.com +szswjs.com +szsycft-tencentclb.cloud +szsycft-tencentclb.com +szsycft-tencentclb.net +szsycft-tencentclb.work +szsyyxh.org +szszjt.com +szszlm.com +szszpx.com +szsztj.com +sztaijier.com +sztalent.org +sztanzo.com +sztara.com +sztc.com +sztcg.com +sztd123.com +szte.com +sztechand.com +szted.com +sztexun.com +szteyin.com +sztgxc.com +sztgxx.com +sztheatre.com +szthekey.com +szthxf.com +sztiaocao.com +sztino.com +sztkc.com +sztkd.com +sztljyjt.com +sztmjz.com +sztncm.com +sztongwang.com +sztopbrand.com +sztower.com +sztoys.com +sztqjf.com +sztreeent.com +sztspi.com +sztw96933.com +sztxcpa.com +sztxsz.com +sztxw.com +szty56.com +sztz.org +sztzzs.com +szuavia.org +szudad.com +szunionlab.com +szurta.org +szvannylove.com +szvca.com +szvft.com +szvi-bo.com +szvsdpco.com +szwa.com +szwaishi.com +szwale.com +szwanghong.com +szwata.com +szwb.com +szwblm.com +szwchy.com +szwdny.com +szwego.com +szweidi.com +szweijubao.com +szweita.com +szwfhp.com +szwfzs.com +szwghl.com +szwgmf.com +szwgroup.com +szwhcycyw.com +szwhxy.com +szwldq.com +szword.com +szwsm.com +szwstui.com +szwtsd.com +szwudao.com +szwuyukeji.com +szwwco.com +szwzjt.com +szwzzxyy.com +szx-ray.com +szx-tencentclb.cloud +szx-tencentclb.com +szx-tencentclb.net +szx-tencentclb.work +szx58.com +szxbbus.com +szxbjt.com +szxbyx.com +szxcqfw.com +szxcrq.com +szxcxkf.com +szxcyl.com +szxdfpr.com +szxdhj.com +szxdzb.com +szxfgcw119.com +szxhdz.com +szxihu.com +szxijili.com +szxinghe.net +szxinjiaxin.com +szxinjicheng.com +szxinyixin.com +szxiot.com +szxlga.com +szxljc.com +szxlxzb.com +szxs.work +szxsdmy.com +szxsshb.com +szxtiot.com +szxuexiao.com +szxuw.com +szxwlkj.com +szxxj.com +szxxtx.com +szxxw.com +szxyjd.com +szxyxbkle.com +szyake.com +szyakeda.com +szyansai.com +szyazhi.com +szybio.com +szycil.com +szyclmarathon.com +szydtx.com +szydxx.net +szydyy.com +szyfai.com +szyfdz.net +szygcgpt.com +szyh.org +szyhja.com +szyhoa.com +szyhznkj.com +szyibei.com +szyichengjd.com +szyin.com +szyingduoduo.com +szyinglian.com +szyingzhan.com +szyink.com +szyixx.com +szyiyue.com +szyjedu.com +szyljt.com +szymweb.com +szyns.com +szypfb.com +szyptx.net +szyqjzxh.com +szyran.com +szys.net +szys119.com +szysjt.com +szysmpay.com +szystea.com +szysxx.com +szyt-hosp.com +szyuda88.com +szyundingschool.com +szyuxin.com +szyweibo.com +szyxue.com +szyxwdz.com +szyxwkj.com +szyy0373.com +szyyda.com +szyyt.com +szyyx.com +szyzsy.com +szzbmy.com +szzesee.com +szzfbt.com +szzfgjj.com +szzh365.com +szzhangchu.com +szzhaodaxin.com +szzhijun.com +szzhsponge.com +szzhuoju.com +szzkgk.com +szzljg.com +szzntech.com +szznzn.com +szzoan.com +szzoo.net +szzs360.com +szzscq.com +szzsivf.com +szzunbao.com +szzuting.com +szzx100.com +szzxgzy.net +szzyjt.net +szzyqc.net +szzyqy.com +szzytech.com +szzywxkj.com +t-angel.com +t-d.chat +t-d.tv +t-dsyy.com +t-firefly.com +t-gafa.com +t-io.org +t-npm.com +t-ocean.com +t-t.live +t-tlearning.com +t-v.com +t-workshop.com +t.biz +t.tt +t0001.com +t003005.com +t00ls.cc +t00ls.net +t00y.com +t016vip20.com +t016vip28.com +t016vip7.com +t0377.com +t086.com +t1.ink +t10.com +t105.com +t11.co +t123yh.xyz +t139.com +t178.info +t1networks.com +t1qq.com +t1tms.com +t1y4.com +t1y5.com +t20000.com +t2audio.net +t2cn.com +t2uu.com +t3315.com +t3j4.com +t3yanzheng.com +t47888.com +t49cdn.com +t4x3.com +t4z5p5s9k4q3m4h4m3.org +t5.work +t50888.com +t528.com +t56.net +t56jy.net +t5tm.com +t5xs.com +t66.com +t6q.com +t7114.com +t7805.com +t79d6.com +t7rt5.com +t7y8.com +t7z.cc +t85.net +t8703hd304.com +t888w.com +t8f.com +t8tcdn.com +t8tms.com +t8ui6xzkw.shop +t99677.com +t9in.com +t9tms.com +ta-ly.com +ta-shang.com +ta26.com +ta313.com +ta39.com +taaas.org +taagoo.com +tabalt.net +tabbitbrowser.com +tabbypro.com +tabbywork.com +tableauxmly.com +tabuzhe.com +tabxexplorer.com +tachangxing.com +tactan.net +tadgkj.com +tadiao365.com +tadsim.com +tadsim.net +tadu.com +tadyz.com +taeapp.com +taeee.com +tafeihu.com +tag.gg +tagen-pm.com +tagjjt.com +taglyst.com +tagold.net +tagoo.club +tagphi.net +taguage.com +taguxdesign.com +tahoecn.com +tahua.net +tai-liang.com +tai1000.com +tai3399.com +tai87.com +taian.com +taianmedia.com +taiantang.net +taibumall.com +taicang.info +taicent.com +taichi-graphics.com +taichi-maker.com +taichuan.com +taichuan.net +taici.com +taicihome.com +taicike.com +taida-china.com +taida100.com +taidao.net +taidaxincai.com +taidichina.com +taidu.com +taiduhome.com +taiergroup.com +taifeng.co +taifengfans.com +taifua.com +taig.com +taigaoxiao.com +taihaikj.com +taihainet.com +taihe-hr.com +taihe.com +taihealthcare.com +taihecap.com +taihechengjian.com +taihehospital.com +taihemedia.com +taihopaint.com +taihuachem.com +taihuapharm.com +taihuawj.com +taihuboiler.com +taihucn.com +taihuoniao.com +taihutour.com +taihuwang.com +taihuwater.com +taihuxue.com +taihuyuan.com +taihuzimi.com +taiji.com +taijidf.com +taijiewuliu.com +taijiny.com +taijio.com +taijs.com +taijutv.com +taikaibyq.com +taikaihuanbao.com +taikancnc.com +taikang.com +taikanginv.com +taikangjsnc.com +taikanglife.com +taikanglife.net +taikangonline.com +taikangonline.net +taikangph.com +taikangzhijia.com +taikeji.com +taikewei.com +taikongmedia.com +taikoohui.com +taikoyc.com +taikr.com +tailgdd.com +tailingood.com +tailixiangjiao.com +taillkang.com +tailong.com +taimei.com +taimi100.com +taimls.com +tainengchong.com +taininge.online +tainingrencai.com +taiorient.com +taiott.com +taipingyangshuiwu.com +taipumed.com +taiqiedu.com +taiqigame.com +taiquan.com +tairock.com +tairos.cc +tairos.net +tairos.tech +tairui-ad.com +tais3.com +taisantech.com +taisenfurniture.com +taishangroup.com +taishansports.com +taishanxq.com +taishanyy.com +taisuyun.com +taitonglj.com +taiwandao.tw +taiwanwii.com +taiweiholding.com +taiwoagri.com +taiwu.com +taixi.cc +taixigas.com +taixingren.com +taixirobot.com +taixubio.com +taixuguoji.com +taiyangd.com +taiyanghttp.com +taiyechem.com +taiyin117.com +taiyiplus.com +taiyocablecn.com +taiyou.fund +taiyuanguanye.com +taiyuanqy.com +taizhoucitymarathon.com +taizhouwater.com +taizibao.com +tajd.net +taji-ai.com +tajiduo.com +takebackthegrid.org +takesend.com +takfat.com +takhogroup.com +takstar.com +takumi-cnc.com +takungpao.com +takusogroup.com +takwang.net +tal-china.com +tal.com +talbrain.com +talebase.com +talegenes.com +talentable.com +talentlin.com +talentran.com +talents-tech.com +talentsmag.com +talentspotgroup.com +talicai.com +taliove.com +taljdns.com +talk-cloud.net +talk-fun.com +talk.ai +talk915.com +talkgw.com +talkingchina.com +talkwithtrend.com +talkxj.com +talkyun.com +talldns.com +talldns.net +tallgu.com +talmdhome.com +taluo.com +taluo5.com +taluoji.com +talzjsj.com +tamaegis.com +tamarace.com +tamayaki.com +tamc8.com +tamensay.com +tamersunion.net +tamigos.com +tamigroup.com +tamlab.net +tamll.com +tan-gtr.com +tan.cc +tan07.com +tan14.net +tan8.com +tanapk.com +tanaqul.org +tanbao178.com +tanbj7wflr.com +tanbo.name +tanboer.com +tancdn.com +tanchinese.com +tandehao.com +tandfonline.com +tanewmaterial.com +tang-lei.com +tanganlingshi.com +tangbai.cc +tangbolitangci.com +tangchendoor.com +tangdaoya.com +tangdou.com +tangdouddn.com +tangdouedn.com +tangdoufdn.com +tangdouhdn.com +tangdouimg.com +tangdouz.com +tangeche.com +tangfc.com +tanggu11g.com +tangguobaohe.com +tanghu.net +tanghushi.com +tangjie.me +tangjihuang.com +tangkabj.com +tanglei.name +tangmingint.com +tangoic.com +tangongye.com +tangpai.cc +tangping.com +tangqingtuia1.com +tangrenmedia.com +tangruiqian.com +tangsanshu.com +tangsem.com +tangshan-marathon.com +tangshanliulin.net +tangshuang.net +tangshui.net +tangsongys.com +tangsuanradio.com +tangtang.org +tanguan.net +tangux.com +tangwai.com +tangxia.xin +tangxiagoodview.com +tangyeedu.com +tangyoufushi.fun +tangyuan.com +tanhaibo.net +tanho.com +tanjigroup.com +tanjing.online +tanjiyongjun.com +tankeai.com +tankmm.com +tankprint.online +tanksuv.com +tankywoo.com +tanling.com +tanlive.com +tanlong.org +tanluxia.com +tanma.tech +tanmer.com +tanpaifang.com +tanpoqiuer.com +tanshudata.com +tansiling.com +tansoole.com +tantaly.com +tantan123.com +tantanapp.com +tantu.com +tantu.info +tantuw.com +tanwan.com +tanwan123.net +tanwanmao.net +tanweime.com +tanwuapp.com +tanxingfuli.com +tanxinyu.work +tanxlog.istreamsche.com +tanxuling.com +tanyu.mobi +tanyuantech.com +tanzhouwater.com +tao-che-wei.com +tao-jiujiu.com +tao-star.com +tao-studio.net +tao-wu.com +tao008.com +tao123.com +tao3.cc +tao33.com +tao37.com +tao3c.com +tao66.com +tao800.com +tao8090.com +taoa.com +taoad.com +taoart.com +taoban.com +taobao-img.com +taobao.com +taobao.global +taobao.net +taobao.org +taobao.tw +taobao1111.com +taobaocdn.com +taobaocity.com +taobaotest.com +taobaotesting.com +taobeihai.com +taobiaozu.com +taobizhong.com +taoc.cc +taocange.com +taocdn.com +taoche.com +taocheche.com +taoci.com +taoci163.com +taocibao.com +taocijiaju.com +taocloudx.com +taocz.com +taodake.com +taodang8.com +taodaso.com +taodaxiang.com +taodianla.com +taodingzhi.cc +taodiqupu.com +taodocs.com +taodu.com +taoduoke.com +taodushi.cc +taoerge.com +taoex.com +taofake.com +taofang.com +taofanghaiju.com +taofeige.com +taofen8.com +taofont.com +taogede.com +taogegou.com +taogepian.com +taogouxingxuan.com +taogutang.com +taohao6.com +taohaoba.com +taohaobang.com +taohaoge.com +taohaoqu.com +taohaowan.com +taohhui.com +taohua.com +taohuaqizhi.com +taohuazu.net +taohuazu.pw +taohui.pub +taohuren.com +taoic.com +taojiaju8090.com +taojianghu.com +taojiji.com +taojin6.com +taojindi.com +taojingame.com +taojingroup.com +taojinhudong.com +taojinji.com +taojinyi.com +taoke.com +taokewenan.com +taokezhushou.com +taokouling.com +taoktv.com +taoku.com +taokuaibiao.com +taolale.com +taoliangroi.com +taolinzhen.com +taolvtong.com +taolx.com +taomanhua.com +taomee.com +taomeiju.com +taomeixie.com +taoming.com +taomingshi.com +taomingyan.com +taomobao.com +taomr.com +taonanfu.com +taonienie.com +taoniu.com +taoniupin.com +taoonelogistics.com +taooo.cc +taopb.com +taopian.org +taopiaopiao.com +taopic.com +taopinquan.com +taopuwang.com +taopxx.com +taoq.net +taoqao.com +taoquanquan.com +taor.work +taoruinyuan.com +taosaas.com +taosdata.com +taosha.club +taoshengtc.com +taoshouyou.com +taoshu.com +taoshuashua.net +taoshudang.com +taosj.com +taotao.com +taotaocar.com +taotaoit.com +taotaosports.com +taoth.com +taotian.com +taotu8.net +taotv.com +taotv.net +taou.com +taourl.com +taowangzhan.com +taoweng.site +taoxiangyoushu.com +taoxiaolu.com +taoxie.com +taoxie.com.tw +taoxuemiao.com +taoxv.com +taoyi-support.com +taoyitu.com +taoyizhu.com +taoyougou.com +taoyuanc.com +taoyuewenhua.net +taoyutaole.com +taozg.store +taozhanyun.com +taozhibook.com +taozhuo.com +taozhutu.com +tap-ad.com +tapafun.com +tapai.com +tapaijiu.com +tapapis.com +tapapks.com +tapbooster.net +tapd-app.com +tapdata.net +tapenjoy.com +tapimg.com +tapjoytech.com +tapotiexie.com +tappile.com +tapque.com +taprls.com +taprls.net +tapsvc.com +taptap-api.com +taptap.com +taptapcode.com +taptapdada.com +tapurl.com +taraniss.com +tarcoist.com +tarczp.com +tarenacn.com +tarenwang.net +targetportion.com +tarisland-zh.com +taro.zone +tarotchina.net +tarsier-infra.com +tarsocial.com +tartscenter.com +tasaiwang.com +taschb.com +tashine.com +tasiyun.com +task51.com +taskcity.com +tasly.com +taslypharma.com +tastespirit.com +tastien-external.com +tastientech.com +tastysteak.com +taswwx.com +taszk.com +taszls.com +tatatimes.com +tataxingqiu.com +tatazu.com +taterli.com +tatfook.com +tatiqrf.com +tatstm.com +tattoo77.com +tattooo.net +taurentech.net +tauris.com +taurus66.com +taurusxin.com +tav-global.com +tav-global.net +tavsiktlig.com +tawk.link +tax-edu.net +tax.vip +tax100.com +taxchina.com +taxdata.tax +taxjiangkewang.com +taxksec.com +taxnote.org +taxspirit.com +taxtaoj.xyz +taxuspharm.com +taxwen.com +tayohya.com +tazai.com +tazhe.com +tazts.com +tb-whatsapp.com +tb.biz +tb.pub +tb51.net +tb58.net +tbaas.tech +tbadc.com +tbadesign.org +tbaiq.com +tbankw.com +tbapp.com +tbcache.com +tbcdn.com +tbh5.com +tbhcc.com +tbhelper.com +tbizmail.com +tbjt18.com +tbjtss.com +tbk-app.com +tbkf.net +tbkong.com +tbl-import.com +tblk.me +tbmcas.com +tbmkt.com +tbnimg.com +tboxn.com +tbpark.com +tbq168.com +tbqjx.com +tbreeden.com +tbs321.com +tbsandbox.com +tbshare123.com +tbsite.net +tbt-tuning.com +tbt168.com +tbtopc.com +tburl.in +tbuser.com +tbwyl.com +tbxsw.com +tbyfsoft.com +tc-21.com +tc-mining.com +tc-semi.com +tc0770.com +tc108.com +tc118.com +tc12580.com +tc199.net +tc29.com +tc29.net +tc471cyhud.com +tc58.net +tc880.com +tc9011.com +tc930.com +tcbqcloud.com +tccfjt.com +tccrtzyxgs.com +tccxfw.com +tcdinfo.com +tcdj.com +tcdlive.com +tcdneo.com +tcdneo.net +tcdnext.com +tcdnhw.com +tcdnhw.net +tcdnkc.com +tcdnkcbak.com +tcdnlive.com +tcdnlivebak1.com +tcdnlivebak2.com +tcdnlp.com +tcdnos.com +tcdnos.net +tcdntip.com +tcdnv3.com +tcdnvod.com +tcdnvodbak.com +tcdnvodnew.com +tcdnvp.com +tcdnzb.com +tcdushi.com +tcecps.org +tced-transsion.com +tcedshare.com +tceic.com +tcenn.com +tceratronix.com +tcfhty.com +tcfmglobal.com +tcgcardgame.com +tcgdxyb.xyz +tcggkj.com +tcgke.com +tcgsw.com +tchbgz.com +tchbsb.com +tchong.com +tchy.net +tchzt.com +tchzx.com +tciplay.com +tcisct.com +tcjdcapital.com +tcjx688.com +tckjfast.com +tckjhigh.com +tckwj.com +tcl-cctv.com +tcl.com +tclbusiness.com +tclclouds.com +tcljd.com +tclking.com +tclkqn.com +tclogx.com +tcloud19.com +tcloudbase.com +tcloudbase.net +tcloudbaseapi.com +tcloudbaseapp.com +tcloudbasegateway.com +tcloudbasestatic.com +tcloudbh.com +tcloudbi.com +tclouddrive.com +tcloudedu.com +tcloudfamily.com +tcloudhw.com +tcloudhw.net +tcloudit.com +tcloudit.net +tcloudlive.com +tcloudscdn.com +tcloudscdn.net +tcltech.com +tclyjg.com +tcm100.com +tcm360.com +tcmer.com +tcmfrj.com +tcmmh.com +tcmppcloud.com +tcmwindow.com +tcnen.com +tcnews.cc +tcnvmms.com +tcoejox.shop +tcomall.com +tcp.hk +tcp.mk +tcp.pub +tcp5.com +tcping8.com +tcqmj.com +tcrcb.com +tcrcsc.com +tcs-y.com +tcsae.org +tcsasac.com +tcsdk.com +tcsdzz.com +tcseny.com +tcsisu.com +tcsnake.com +tcspbj.com +tcstzg.com +tcsurg.org +tctip.com +tctong.com +tctpwebank.com +tctpwebankcdn.net +tctpxwebank.com +tctran.com +tctz.com +tcvywoh.com +tcwqqdy.guru +tcwt.net +tcxmt.com +tcxw.cc +tcxwg.com +tcxx1985.com +tcxys.com +tcxzj.com +tcy1688.com +tcy365.com +tcy365.net +tcyad.com +tcyfw.com +tcylgslb.com +tczgwzw.com +tczj.net +tczmled.com +td-sf.com +td-tech.com +td22.com +td2cn.com +td300321.com +td776.com +td96.com +td98.com +tdances.com +tdasz.com +tdatamaster.com +tdataspace.com +tdbbj.com +tdchats.us +tdchatvip.us +tdd.la +tdfsm.com +tdgdy.org +tdgod.com +tdiac.com +tdict.com +tdimg.com +tdjxhb.com +tdkchina.com +tdlcdn.com +tdlcdn.net +tdmall.cc +tdmoli2.com +tdmta.com +tdns127.com +tdnsdlovs1.com +tdnsdlovs2.com +tdnsdlovs3.com +tdnsdlovs4.com +tdnsdlovs5.com +tdnsdp.com +tdnsdpovs1.com +tdnsdpovs2.com +tdnsdpovs3.com +tdnsdpovs4.com +tdnsdpovs5.com +tdnsliveovs1.com +tdnsliveovs2.com +tdnsliveovs3.com +tdnsliveovs4.com +tdnsliveovs5.com +tdnspub.com +tdnspub.net +tdnsspovs1.com +tdnsspovs2.com +tdnsspovs3.com +tdnsspovs4.com +tdnsspovs5.com +tdnssticovs1.com +tdnssticovs2.com +tdnssticovs3.com +tdnssticovs4.com +tdnssticovs5.com +tdnsv1.com +tdnsv1.net +tdnsv10.com +tdnsv10.net +tdnsv11.com +tdnsv11.net +tdnsv12.com +tdnsv12.net +tdnsv13.com +tdnsv13.net +tdnsv14.com +tdnsv14.net +tdnsv15.com +tdnsv15.net +tdnsv2.com +tdnsv2.net +tdnsv3.com +tdnsv3.net +tdnsv4.com +tdnsv4.net +tdnsv5.com +tdnsv5.net +tdnsv6.com +tdnsv6.net +tdnsv7.com +tdnsv7.net +tdnsv8.com +tdnsv8.net +tdnsv9.com +tdnsv9.net +tdnsvodovs1.com +tdnsvodovs2.com +tdnsvodovs3.com +tdnsvodovs4.com +tdnsvodovs5.com +tdnsx1.com +tdotapp.com +tdpress.com +tdqs.com +tdrffh.com +tds-1300.com +tdsf.asia +tdsfiles.com +tdshbao.com +tdsjbj.com +tdtbd.com +tdtec.com +tdun.com +tduou.com +tdwan.com +tdxz.net +tdyxmoto.com +tdzntech.com +tdzyw.com +te-ch.tech +te-silicone.com +te160.com +te5.com +te6.com +tea-gd.com +tea26.com +tea7.com +teach365.com +teachblog.net +teachclinic.com +teachcn.net +teachercn.com +teachers211.com +teachertc.com +teakki.com +teaku.com +teallang.com +tealui.com +teamall.cc +teambition.com +teambition.io +teambition.net +teambitionapis.com +teamlogs.com +teamminus.com +teamotto.net +teamshub.com +teamtop.com +teamtopgame.com +teandy.com +teatreexy.com +tebaidu.com +tebiao.net +tebie6.com +tebiefuza.cloud +tebiezan.com +tebiezhuan.com +teboncapital.com +tec73.com +tecbbs.com +tecenet.com +tech-long.com +tech-mx.com +tech-now.com +tech-sem.com +tech-sonic.net +tech002.com +tech1024.com +tech110.net +tech2ipo.com +tech2real.com +tech4joy.com +techan.com +techannet.com +techanshop.com +techantong.net +techbeat.net +techbrood.com +techdow.com +techfine.net +techflowpost.com +techgastronomy.com +techgogogo.com +techigh.net +techingrid.net +techmiao.com +techmoris.com +techo.chat +techo.pub +techo.show +techoke.com +techonegame.com +techqianmo.com +techsir.com +techsize.com +techtmt.com +techtop.com +techuangyi.com +techub.news +techug.com +techvisum.com +techwalker.com +techwell-cn.com +techwin.com +techxue.com +teclast.com +tecmz.com +tecochina.net +tecolighting.com +tecompharma.com +tecreal.com +tecyle.com +teda-veolia.com +tedagas.com +tedahotel.com +tedahr.com +tedaich.com +tedaniu.com +tedastock.com +teddycc.com +teddymobile.net +tedushi.com +tedx.net +tedy.cc +teejia.com +teeqee.com +tefact.com +tefl-china.net +tefscloud.com +tefscloud.net +tefshipping.com +tegongji.com +tegoushe.com +tegvzpvz.com +tehang.com +tehub.com +tehuituan.com +teilei.com +tejiabiao.com +tejiawang.com +tek-asia.com +tekkenthree.com +tekshanghai.com +tekuaijie.com +tel01.com +telaideyouxue.com +teld.net +telecomhb.com +telecomhr.com +telecomjs.com +telefen.com +telegerlam.cc +telegramcn.co +telegramggo.com +telegramtoke.com +telegramyug.cc +telegroiam.cc +telehr.com +teleinfoo.com +telekoml.cfd +teleland.net +telemgrasm.cc +teleows.com +telergaemoam.cc +televivi.com +telfri.net +teligen-cloud.com +teligen.net +teliute.org +telking.com +tell520.com +tellgen.com +telling.com +tellingtech.com +telllove520.com +tellmachgd.com +telnet404.com +telongzn.com +telpo.com +telrgeam.cc +telsda.com +telu.net +telunsu.net +tem.pw +temaiapi.com +temaiku.com +temch.net +temedical.com +temox.com +temp.im +tempersyi.com +temyee.com +ten.design +tenag.com +tenant-zone-dev.com +tenbilliongame.com +tencdns.com +tencdns.net +tencenst.com +tencent-blackboard.com +tencent-cloud.com +tencent-cloud.net +tencent-education.com +tencent-gcloud.com +tencent-gf.com +tencent-qejs.com +tencent-stock.com +tencent.co.id +tencent.com +tencent.com.hk +tencent.design +tencent.net +tencentads.com +tencentads.net +tencentadx.com +tencentanxin.com +tencentapigw.com +tencentapis.com +tencentapp.com +tencentapps.com +tencentbh.com +tencentbyod.com +tencentcc.com +tencentcdb.com +tencentcds.com +tencentcfs.com +tencentciam.com +tencentclb.cc +tencentclb.cloud +tencentclb.com +tencentclb.host +tencentclb.info +tencentclb.link +tencentclb.net +tencentclb.online +tencentclb.plus +tencentclb.pro +tencentclb.site +tencentclb.space +tencentclb.team +tencentclb.tech +tencentclb.top +tencentclb.vip +tencentclb.work +tencentclb.zone +tencentcloud-aiot.com +tencentcloud-demo.com +tencentcloud.com +tencentcloud.io +tencentcloudapi.com +tencentcloudapimarket.com +tencentcloudapp.com +tencentcloudbase.com +tencentcloudbase.net +tencentcloudclub.com +tencentcloudcore.com +tencentcloudcr.com +tencentcloudcs.com +tencentcloudga.com +tencentcloudga001.com +tencentcloudga001.net +tencentcloudga002.com +tencentcloudga002.net +tencentcloudga003.com +tencentcloudga003.net +tencentcloudga004.com +tencentcloudga004.net +tencentcloudga005.com +tencentcloudga005.net +tencentcloudga006.com +tencentcloudga006.net +tencentcloudga007.com +tencentcloudga007.net +tencentcloudga008.com +tencentcloudga008.net +tencentcloudga009.com +tencentcloudga009.net +tencentcloudga010.com +tencentcloudga010.net +tencentcloudga011.com +tencentcloudga011.net +tencentcloudga012.com +tencentcloudga012.net +tencentcloudga013.com +tencentcloudga013.net +tencentcloudga014.com +tencentcloudga014.net +tencentcloudga015.com +tencentcloudga015.net +tencentcloudga016.com +tencentcloudga016.net +tencentcloudga017.com +tencentcloudga017.net +tencentcloudga018.com +tencentcloudga018.net +tencentcloudga019.com +tencentcloudga019.net +tencentcloudga020.com +tencentcloudga020.net +tencentcloudga021.com +tencentcloudga021.net +tencentcloudga022.com +tencentcloudga022.net +tencentcloudga023.com +tencentcloudga023.net +tencentcloudga024.com +tencentcloudga024.net +tencentcloudga025.com +tencentcloudga025.net +tencentcloudga026.com +tencentcloudga026.net +tencentcloudga027.com +tencentcloudga027.net +tencentcloudga028.com +tencentcloudga028.net +tencentcloudga029.com +tencentcloudga029.net +tencentcloudga030.com +tencentcloudga030.net +tencentcloudipv6.com +tencentcloudlab.com +tencentcloudlive.com +tencentcloudmarket.com +tencentcloudmq.com +tencentcloudns.com +tencentcloudsandbox.com +tencentcloudsec.com +tencentcloudses.com +tencentcloudsso.com +tencentcls.com +tencentcmq.com +tencentcode.com +tencentcomics.com +tencentconsulting.com +tencentcos.cloud +tencentcos.com +tencentcos.net +tencentcs.com +tencentcsms.com +tencentdayu.com +tencentdb.com +tencentddos.com +tencentdevices.com +tencentdigitalassistant.com +tencentdmp.com +tencentdms.com +tencentedi.com +tencentehs.com +tencenteiam.com +tencentelasticsearch.com +tencentemr.com +tencentes.com +tencentexpert.com +tencentfanyi.com +tencentff.com +tencentfilm.com +tencentfoundation.org +tencentga.com +tencentgames.co +tencentgames.us +tencentgme.com +tencentgse.com +tencentgy.com +tencenthangjia.com +tencentiam.com +tencenticp.com +tencentid.com +tencentidaas.com +tencentidentity.com +tencentimage.com +tencentimage.net +tencentiotcloud.com +tencentiotmedia.com +tencentipv6.com +tencentlegalservices.com +tencentlink.com +tencentlkfz.com +tencentlog.com +tencentmail.com +tencentmdb.com +tencentmeeting.com +tencentmfa.com +tencentmovie.com +tencentmusic.com +tencentoa.com +tencentoceanus.com +tencentpay.com +tencentpic.com +tencentproxy.com +tencentrce.com +tencentrcpcsdk.com +tencentresearch.com +tencentrio.com +tencentscf.com +tencentsecsdk.com +tencentserverless.com +tencentservicewatcher.com +tencentses.com +tencentsite.com +tencentsmhcname.com +tencentsmhuc.com +tencentsource.com +tencentstart.com +tencentsuite.com +tencentsurvey.com +tencentsurvey.net +tencenttcr.com +tencenttdai.com +tencenttdmq.com +tencenttds.com +tencenttid.com +tencenttione.com +tencenttree.com +tencenttrtc.com +tencenttymaas.com +tencentud.com +tencentvpc.com +tencentweiban.com +tencentwemeet.club +tencentwepark.com +tencentwf.com +tencentwm.com +tencentwukong.com +tencentxinge.com +tencentyouth.com +tencentyun.com +tencentzhzf.com +tenchii.com +tencity.com +tendacn.com +tendawifi.com +tendbcluster.com +tendbcluster.net +tendcode.com +tendfo.com +tendis.net +tendrones.com +tendyron.com +tengamy.com +tenganxinxi.com +tengbai-it.com +tengbenyueji.com +tengbo.cc +tengchangjiancai.com +tengchu.com +tengdatumu.com +tengdawl.com +tengdazuche.com +tengen.com +tengfangyun.com +tengfeidn.com +tengfeijob.com +tengfeizhida.com +tengfun.com +tenghen.com +tenghesmart.com +tenghoo.com +tengkackjr.com +tengkaxx.com +tenglong.net +tenglonggroup.com +tengmed.com +tengmoney.com +tengning.net +tengnu999.com +tengnuobx.com +tengrant.com +tengshengchina.com +tengshiauto.com +tengtiegongyi.com +tengwen.com +tengxuan.net +tengxunlct.com +tengxunqiye.com +tengxunqiyeyou.com +tengy.com +tengya.com +tengyang666.com +tengye-vc.com +tengyeshiye.com +tengyu-group.com +tengyuejz.com +tengyunqq.com +tengzhihh.com +tengzhipp.com +tengzhou0632.com +tengzhuan.com +tenhot.net +tenio.com +tenjia.cc +tenjincn.com +tenkent.com +tenlonstudio.com +tenmh.com +tennny.com +tennoo.com +tenorforman.com +tenorshare.com +tenorshare.tw +tenovatech.com +tenpay.com +tenqent.com +tenrays.com +tensafe.com +tensgpt.com +tenshi.cc +tensorchip.com +tensorflownews.com +tensorlet.org +tenstars.net +tensuntrans.com +tensure.com +tensynchina.com +tentech.club +tentrue.com +tentx.com +tenwowfood.com +tenwukong.com +tenxapp.com +tenxcloud.com +tenxcloud.net +tenyn.com +teo-rum.com +teoacc.com +teoacc.net +teodns.com +teodns.net +teown.com +tepcb.com +tepin.hk +terabuy.com +terapark.com +terapines.com +terencemusic.com +teresahowarddoula.com +teridge.com +terminal.icu +terminus.io +terose.com +terra-master.com +terran.tech +terransforce.com +terratribes.com +terrypacking.com +terrytec.com +teruide.net +tese5.com +tesery.com +tesexiu.com +teshenqi.com +tesight.com +tesiro.com +tesolsh.com +tesoon.com +test-cignacmb.com +test.gbugs-qa.chromium.org +testbird.com +testcoo.com +testdemo.work +testeb.com +testeck.com +testerhome.com +testict.com +testin.im +testingpai.com +testinsight.net +testlrq.com +testmrrvendor.com +testroad.org +testrust.com +testshm.com +testsparkling.com +testwaf.com +testwo.com +testxy.com +tesys.online +tetcm.com +tetegu.com +teteyu.com +tetrisone.com +tetuijiudian.com +teuhui.com +teuxipet.com +tevachem.com +tewsiext.com +tex68.com +texasholdemcup.com +texasholdemcup.net +texpage.com +texpageusercontent.com +texpro-group.com +textaihua.com +textin.com +texzhongtao.com +teyonds.com +teyop.com +tez-tencentclb.cloud +tez-tencentclb.com +tez-tencentclb.net +tezhengma.com +tezhongzhuangbei.com +tezign.com +tf-bm.com +tf.wiki +tf56.com +tfauto.net +tfax.com +tfbestea.com +tfbird.com +tfbkw.com +tfbx.net +tfcaijing.com +tfcloud.com +tfclub.com +tfcsz.com +tfdsb.org +tfedu.net +tfeic.com +tfengyun.com +tff.bz +tfg2.com +tfgame.vip +tfgas.com +tfgvb.com +tfidc.net +tfkj.games +tfkyj.com +tflzhongkongban.com +tfme.com +tfmywood.com +tfogc.com +tfogc.net +tfoison.com +tfol.com +tfoyin.com +tfrl.net +tfs906.com +tfsb.net +tfsino.com +tfsmy.com +tftplay.com +tfvisa.com +tfxqrmyy.com +tfyum.net +tfzikao.com +tfzq.com +tg-vision.com +tg-vision.net +tg0123.com +tg1234.com +tg138.com +tgametalent.com +tgbus.com +tgcid.org +tgcondo.com +tgcook.com +tgcyber.com +tgect.com +tgeosmart.com +tggypn.com +tgjbs.work +tgjh.com +tgking.net +tgkjjg.com +tgldfm.com +tgljw.com +tglxh.com +tgnet.com +tgo-ai.com +tgovcloud.com +tgprocs.net +tgr365.com +tgshiguan.com +tgslsst.com +tgstech.com +tgtenty.com +tgtest.site +tgtianshanga.com +tguangxue.com +tgxuwgdi.com +tgzhz.com +tgzwmk.xyz +th-sjy.com +th-tencentclb.cloud +th-tencentclb.com +th-tencentclb.net +th-tencentclb.work +th-water.net +th.bing.com +th38.com +th99.com +thailycare.com +thaivor.com +thaiyellowpagesusa.com +thakjsbyy.com +thamco.com +thanju.com +thankbabe.com +thankyou99.com +thankyoumaris.com +thanmelin.com +thape.com +thatinterpreter.net +thatsmags.com +thatsmandarin.com +thatwind.com +thboiler.com +thcad.net +thcantech.com +thcf168.com +thclouds.com +thdangzhun.com +thdb.com +the-dahan.com +the4can.com +the5fire.com +the9.com +theantiagingshow.com +thearenacapital.com +thearyong.com +theateliercouture.com +thebeastshop.com +thebeijinger.com +thebeijingnews.com +thebird-air.com +thebizark.com +thebuddycreative.com +thecalicocafepa.com +thecfa.info +thechois.cc +thecodeway.com +thedatasys.com +thederma.com +theduapp.com +thedutchman.org +thefastcdns.com +thefastfile.com +thefastimg.com +thefastmake.com +thefastvideo.com +thefilehosting.com +thefrodo.com +thegiac.com +thegoods.asia +thegraduation.store +thegreatwall-china.com +thehanshow.com +theheirism.com +theicstock.com +thejamy.com +thejiangmen.com +thejie.com +thejoyrun.com +thekunlunbeijing.com +thekunlunjingan.com +thelalu.com +thelarkcloud.com +thelastsky.com +themebetter.com +themediumtx.org +themeoffices.com +themeol.com +themex.net +themisweeps.com +themixc.com +themulian.com +themumian.com +themusiqu.com +then9.com +thenburn.com +thenew123.com +thenewhotel.com +thenextravelmarket.com +theoborn.com +theoreticalw.com +theorychina.org +thepeak.com.my +thepoemforyou.com +thepredictivemodel.com +thepresidentialhotel.com +thepsychscrivener.com +thepuli.com +therasaganga.com +theseshepherd.com +thesetech.com +thesmartmelon.com +thesofabedshop.com +theszt.com +thetali.com +thethirdmedia.com +thetigerhood.com +thetollroadsc.icu +thetongji.com +thetoplab.com +thetype.cloud +thevaldezfamily.com +thevideosworld.com +theweina.com +thewestinpazhou.com +thewhitedragons.com +thewowa.com +thewrittencoach.com +thexinji.com +thexnode.com +theytree.com +thfdc.net +thfdcsoft.com +thffc.com +thgkyy.com +thgsjt.com +thhymj.com +thief.im +thiemechina.com +thinbug.com +thingclub.com +thingjs.com +thingskit.com +thinheal.com +think-mall.com +think-way.net +thinkcloudlab.com +thinkcmf.com +thinkdid.com +thinkdream.com +thinkeffective-usa.com +thinkeridea.com +thinkerride.com +thinkerx.com +thinkindrupal.com +thinkive.com +thinkjs.org +thinkpad.com +thinkprinter.net +thinkraz.com +thinksrc.com +thinkstu.com +thinkvo.com +thinkyea.com +thinkyeah.com +thinla.com +thinmoo.com +thinvent.com +thirtyindiantrail.com +this6.com +thishealthsummit.com +thismomentinamerica.org +thisnew.com +thisshop.com +thiztech.com +thjb.net +thjiang.com +thjjhs.com +thjunshi.com +thkconn.com +thkill.com +thm3u8.com +thmall.com +thmfvb.com +thmins.com +thmnet.com +thmovie.com +thmz.com +thmzedu.com +thny.cc +thomanmustore.shop +thomasschools.com +thoreco.com +thorn.red +thorne-eco.org +thosefree.com +thoughtworkers.org +thrbs.com +threadcn.com +threatbook.com +threatbook.net +threetong.com +threewater.net +thrive-chemicals.com +thronechina.com +throughyourlens.org +thrrip.space +ths123.com +ths8.com +thsj.com +thsolar.com +thsware.com +thtfpc.com +thufeng.net +thumbenv.com +thumedialab.com +thundercdn.com +thundercdn.net +thundercloud.group +thunderflash.net +thunderobot.com +thunderplaygame.com +thundersoft.com +thunderurl.com +thunis.com +thunisoft.com +thunlp.org +thupdi.com +thvow.com +thwater.com +thwgetsy.com +thwiki.cc +thwpmanage.com +thxddb.com +thxdx.com +thxflt.com +thxtg.org +thxy.org +thxyy.com +thyoo.com +thyristors.org +thyuu.com +thz56.com +thzab.com +thzu.cc +ti-node.com +ti-solar.com +ti0s.com +ti360.org +tiamaes.com +tian-gang.com +tian-jie.com +tian-run.com +tian10.com +tianan-cyber.com +tianan-insurance.com +tianan-life.com +tianan.com +tianan.net +tiananaq.com +tiananchem.com +tiananmenchenglou.com +tianapi.com +tianbaosi.com +tianbiao.net +tiancaixing.com +tiancaixing.net +tiancao360.com +tiancehang.com +tianchanggongjiao.com +tianchenalum.com +tianchengas.com +tianchi.com +tianchihao.com +tianchu.com +tianchuixiang.com +tianchy.com +tiancichina.com +tiancity.com +tiancitycdn.com +tiandirenfarm.com +tianditao.com +tianditu.com +tiandiyoyo.com +tiandizw.com +tianduntech.com +tiandy.com +tianehui.net +tianfeiyu.com +tianfeng.cc +tianfu-stone.com +tianfucaijing.com +tianfugroup.com +tianfuhui.xin +tianfupic.com +tianfusoftwarepark.com +tiangaicha.com +tiangang.com +tiangen.com +tiangou.xyz +tianhai.info +tianhai2002.com +tianhaixing.com +tianhebus.com +tianhejiayi.com +tianheoil.com +tianhepiano.com +tianheplaza.com +tianhetech.com +tianhongchina.com +tianhongdiaosu.com +tianhonglaser.com +tianhongsunshine.com +tianhuixile.com +tianhujy.com +tianiot.com +tianji368.com +tianjiachem.com +tianjiang-tech.com +tianjiarun.com +tianjibio.com +tianjigame.com +tianjigu.com +tianjihr.com +tianjimedia.com +tianjin-air.com +tianjin-iwc.com +tianjin-marathon.com +tianjin-patek.com +tianjinbbs.com +tianjinbohaileasing.com +tianjingames.com +tianjinwe.com +tianjiyy.com +tiankang.com +tiankong.com +tiankonghuyugames.com +tiankuojy.com +tianlaiedu.com +tianlaijiaoyu.com +tianlaikge.com +tianlailive.com +tianlala.com +tianli-blog.club +tianlian.com +tianlijianshe.com +tianliwindpower.com +tianlongshop.com +tianlun.net +tianlun100.com +tianlunano.com +tianlungas.com +tianma3600.com +tianmaijigou.com +tianmalvyou.com +tianmao.com +tianmapharma.com +tianmarketing.com +tianmawx.com +tianmaying.com +tianmimiclub.com +tianmu.mobi +tianmu.net +tianmuds.com +tianmumusic.com +tianmunews.com +tianmupe.com +tiann90.com +tiannengcarbon.com +tiannilaw.com +tianninghr.com +tiannucoating.com +tiannv.com +tianpeng.com +tianpu.com +tianqi.cc +tianqi.com +tianqi24.com +tianqi321.com +tianqiaojuyuan.com +tianqiaoyishuzhongxin.org +tianqiapi.com +tianqicloud.com +tianqihoubao.com +tianqiip.com +tianqijun.com +tianqilithium.com +tianqistatic.com +tianqiweiqi.com +tianqiyubao3.com +tianqiyubao4.com +tianqiyubao9.com +tianqizhixin.com +tianqu.com +tianquangs.com +tianquetech.com +tianqunnet.com +tianrkl.com +tianrow.com +tianruihr.com +tianrunshunteng.com +tianruo.net +tianruoyun.com +tiansdl.com +tiansenjituan.com +tianshan277.com +tianshanxt.com +tianshengdiyi.com +tianshengholdings.com +tianshenyule.com +tianshiyiyuan.com +tianshugame.com +tianshungroup.com +tiansu-china.com +tiantaichina.com +tiantaienergy.com +tiantailaw.com +tiantaishebei.com +tiantaivideo.com +tiantanbio.com +tiantang100.com +tiantang6.com +tiantangnian.com +tiantanpark.com +tiantaocs.com +tiantaxx.com +tiantexing.com +tianti.com +tiantianbannixue.com +tiantiancaige.com +tiantiancaipu.com +tiantianfm.com +tiantianfunds.com +tiantianleshuiguo.com +tiantianquce.com +tiantiantiaosheng.com +tiantianxieye.com +tiantianxuexi.com +tiantingfm.com +tiantis.com +tiantonglaw.com +tianvalue.com +tianwang.com +tianwenca.com +tianwt.com +tianwugroup.com +tianxia70.com +tianxiajiameng.com +tianxiajiaoyi.com +tianxiamaimai.com +tianxiang.com +tianxianmao.com +tianxiaputao.com +tianxiaquanchengapp.com +tianxiawangxiao.com +tianxiawushi.com +tianxiawuzei.org +tianxiaxiao.net +tianxiaxinyong.com +tianxiayouxi.com +tianxiayouyue.com +tianxin100.vip +tianxing.com +tianxingjianyiliao.com +tianxinkeji.com +tianya.com +tianya.tv +tianya66.com +tianyablog.com +tianyabook.com +tianyaclub.com +tianyaluedu.com +tianyancha.com +tianyancha.net +tianyangqz.com +tianyanqifu.com +tianyaruanwen.com +tianyaui.com +tianyecollege.com +tianyi1368.com +tianyibook.com +tianyid78.com +tianyihy.net +tianyiidc.com +tianyijue.com +tianyinzaixian.com +tianyisc.com +tianyitop.com +tianyiwangxiao.com +tianyon.com +tianyongcheng.com +tianyuanfishing.com +tianyuanjiudian.com +tianyuanpet.com +tianyucangqiongxiaoshuo.com +tianyuchaye.com +tianyuimg.com +tianyujidi.com +tianyutest.com +tianyuyuan.com +tianzeqiti.com +tianzequan.com +tianzhao.net +tianzhishui.com +tianzhitong.net +tianzhuo.com +tianzhuobj.com +tianziguoji003.com +tianzijiaoyu.com +tianziweb.net +tianzongyouxi.com +tiaodao.com +tiaofang.com +tiaoguangbolimo.com +tiaohao.com +tiaohaoba.com +tiaoka.com +tiaomama.com +tiaomaruanjian.com +tiaona.com +tiaooo.com +tiaotiaotang.net +tiaovon.com +tiaoyue.xyz +tiaozhanbei.net +tiatiatoutiao.com +tibaitong.com +tibet3.com +tibet4wd.com +tibetanbible.org +tibetannet.com +tibetcn.com +tibetcnr.com +tibetcul.com +tibetculture.net +tibetcyts.com +tibethospital.com +tibetpic.com +tiboshi.org +tic-gx.com +tica.com +ticachina.com +ticketdashi.com +ticketmars.com +ticp.io +ticp.net +ticpayidr.com +ticpsh.com +ticstore.com +ticwear.com +tidaas.com +tidb.ai +tidb.io +tidb.net +tidbcloud.com +tide-china.com +tide.fm +tidejd.com +tidemedia.com +tidepharm.com +tidesec.com +tideswing.fun +tidi.mobi +tiduyun.com +tieba.com +tiebaimg.com +tiebanzi.com +tiebaobei.com +tiedan2019.com +tiegu.com +tiehuatu.com +tiejiang.org +tiejiong.com +tiejunmedia.com +tiekuangshi.com +tielemao.com +tielingcn.com +tielu.cc +tielu.org +tielu123.com +tielujob.com +tiemeeting.com +tiemu.com +tieniujixie.com +tiens.com +tiepishihu.com +tieque.net +tiesan.com +tieshuwang.net +tietie.la +tietuku.com +tietuo.work +tieweishi.com +tieww.com +tiexing.net +tiexiuyugudao.com +tiexue.net +tiexuedanxin.net +tieyang.com +tieyou.com +tiezhima.com +tiezis.com +tifenxi.com +tiger-code.com +tiger-info.com +tiger-motion.com +tiger2doudou.com +tigerbbs.com +tigerbrokers.com +tigerbrokers.net +tigerdns.com +tigeresop.com +tigerfintech.com +tigermed.net +tigermedgrp.com +tigersecurities.com +tigeryun.com +tigr.link +tiham.com +tijian001.com +tijian123.com +tijianbao.com +tijianshangmen.com +tijianzhuanjia.com +tijox.cc +tijox.com +tijox.hk +tijox.net +tijox.org +tik2019.com +tikersport.com +tiktok-jdsprot.shop +tiktok-youku.com +tiktoknewaccount.com +tiktokrow-cdn.com +tikuol.com +tikv.org +tileywy.com +tillcn.com +tillglance.com +timanetworks.com +timbrd.com +time-weekly.com +time-year.com +time.xtracloud.net +timecoo.com +timedg.com +timedl.com +timedoo.com +timeep.com +timelate.com +timelessq.com +timemachine.icu +timenetwork.tech +timeofdate.com +timeoutbeijing.com +timeoutcn.com +timeoutshanghai.com +timephread.com +timepill.net +timeread.com +timeread.net +timesartmuseum.com +timesboom.com +timescollege.com +timesdf-hn.com +timesfortune.com +timesndt.com +timesoutlets.com +timestock.co +timetickme.com +timeticktick.com +timetw.com +timev.com +timevary.com +timewelder.com +timez.com +timi78.com +timibase.com +timing360.com +timipc.com +timitime.com +timiwc.com +timjx.com +timmerse.com +timsgrank-apphome65.com +timzuu.com +tinavi.com +tinengwang.com +tinetcloud.com +tinfinite.com +tinfo.com +ting22.com +ting27.com +ting55.com +ting89.com +tingbook.com +tingchewei.net +tingchucontrol.com +tingclass.com +tingfun.net +tinghaohr.com +tinghen.com +tinghongzz.com +tingjiandan.com +tingkanbao.com +tingke8.com +tingkez.com +tinglifangs.com +tingmall.com +tingmei.com +tingmimi.net +tingmubeef.com +tingniukeji.com +tingood.com +tingpiting.com +tingroom.com +tingshubao.net +tingshumi.com +tingshuo51.com +tingshuowan.com +tingsonglaw.com +tingtao.net +tingtingfm.com +tingtingwo.com +tingvision.com +tingxi8.com +tingxiangzu.com +tingxiaoyou.com +tingyulou.com +tingyutech.net +tiniangroup.com +tinigame.xyz +tinkad.com +tinkerpatch.com +tinktek.net +tinman798.net +tinning-automation.com +tinsecret.com +tinstu.com +tinwod.com +tinychen.com +tinycms.xyz +tinyems.com +tinyfeng.com +tinyflare.com +tinygroup.org +tinylab.org +tinymind.com +tinypixos.com +tinyservices.net +tinywan.com +tinyyuan.com +tipaipai.com +tipask.com +tipdim.org +tipdm.com +tipdm.org +tipray.com +tiprpress.com +tipsoon.com +tiqakcrxmyca6i.com +tiqiaa.com +tiqianle.com +tirechina.net +tiremay.com +tiruna-cn.com +tiscend.com +tisgame.com +tisi.org +tisino.com +tisiwi.com +tisohinge.com +tisptech.com +tita.com +tita.net +titamobi.com +titan007.com +titan24.com +titanar.com +titanlaw.com +titanm.com +titanmatrix.com +titans-ele.com +titansci.com +titapark.com +titianshanfz.com +tititxt.com +titloteka.com +titussb.com +tiuzor.com +tivitv.com +tiwb.com +tiwu.net +tixa.com +tixaapp.com +tixue.net +tiyamat.com +tiye.me +tiyeji.com +tiyep.com +tiyucdn.com +tiyufeng.com +tiyuguoji.com +tiyule.com +tiyusaishi.com +tiyushe.com +tiyuxiu.com +tizi.com +tizi365.com +tizoinfo.com +tj-fch.com +tj-guangxin.com +tj-kingdee.com +tj-model.com +tj-un.com +tj0573.com +tj1-miui-bn-stage01.kscn +tj20.com +tj2022.com +tj316bxg.com +tj47zx.net +tj9.co +tjab.org +tjafxh.com +tjaide.com +tjbb.com +tjbearing.com +tjbh.com +tjbhnews.com +tjboai.com +tjbpi.com +tjbsq.com +tjbus.com +tjbxingbian.com +tjcamp.com +tjcaoshiyabo.com +tjcecp.com +tjcep.com +tjchangxing.com +tjchildrenshospital.com +tjcid.com +tjckjr.com +tjcn.org +tjcondom.com +tjcta.org +tjculture.com +tjcyts.com +tjczjxsb.com +tjdeviser.com +tjdewy.com +tjdrzc.com +tjdyf.com +tjeco-city.com +tjeti.com +tjfengfan.com +tjfer.com +tjflcpw.com +tjfxdx.com +tjfytech.com +tjgcs.com +tjgdjt.com +tjgg88.com +tjghw.com +tjgmcg.com +tjgportnet.com +tjgtgd.com +tjhgmc.com +tjhmsj.com +tjhtcpvc.com +tjhyzyxy.com +tji.io +tjian.com +tjinsuo.com +tjjfrh.com +tjjhqyy.com +tjjiaotong.com +tjjinglang.com +tjjt360.com +tjjtjt.net +tjjwt.com +tjjwwl.com +tjjzzls.com +tjkache.com +tjkeheng.com +tjkj300.com +tjkp-tools.com +tjkpzx.com +tjkx.com +tjkximg.com +tjllhbkj.com +tjluohuzhijia.com +tjmama.com +tjmcgc.com +tjmhc.com +tjmldy.com +tjmuch.com +tjnjw.com +tjoy.biz +tjpa-china.org +tjpma.org +tjpme.com +tjportnet.com +tjqiqiu.com +tjqq.cc +tjrenliziyuan.com +tjrenmu.com +tjruien.com +tjsjnxh.com +tjsjwygg.com +tjsjx.com +tjskq.com +tjskqyy.com +tjsptech.com +tjst.net +tjstats.com +tjsylhh.com +tjszyy.com +tjtele.com +tjtjshengtu.com +tjtongrentang.com +tjtrust.com +tjtsxd.com +tjtum.work +tjtvc.com +tjubbs.net +tjumc.com +tjupdi.com +tjupt.org +tjuzj.com +tjwatergroup.com +tjwch.com +tjwch.org +tjwenjie.com +tjwf.com +tjwj88.com +tjwmschool.net +tjxdzhonda.com +tjxinyu.com +tjxiqi.com +tjxunlei888.com +tjxxcl.com +tjxz.cc +tjydyt.com +tjyun.com +tjzb.com +tjzcsj.com +tjzfcg.com +tjzfhgcj.com +tjzhongyiyao.com +tjzhyj.com +tjznjt.com +tjzxyy.com +tjzyec.com +tjzyefy.com +tjzyfw.com +tjzymob.com +tk-life.com +tk-rays.com +tk-xiong.com +tk.anythinktech.com +tk163.com +tk233.xyz +tk315.com +tkas2019.com +tkchina.com +tkckjr.com +tkcn.cc +tkd-suzhou.com +tkfashion.club +tkfff.com +tkgame.com +tkhealthcare.com +tkjzym.com +tkmedicare.com +tkpension.com +tkplusemi.com +tkqpggvx.com +tkrlab.com +tktjwhyy.com +tktk123.com +tkw.cc +tkwcn.com +tkww.hk +tkxb.net +tkxlglyy.com +tkxxd.net +tkxyy.com +tky001.com +tkzqv.com +tl-finechem.com +tl-self.com +tl-shida.com +tl-tek.com +tl-vogue.com +tl.gscm.tv +tl100.com +tl2y.com +tl50.com +tl88.net +tlang.com +tlbapm.com +tlbsbigdata.com +tlby120.com +tlbyx.com +tlcbf.com +tlcharity.com +tlcssk.com +tlfw.net +tlfzkj.com +tlgas.com +tlgslb.com +tlhjjc.com +tlhmhd.com +tlink.io +tlinkaccess.com +tlinkaccess2.com +tlinx.com +tliveapi.com +tliveapi2.com +tliveapp.com +tliveauth.com +tliveauth2.com +tlivecdn.com +tlivecdnv1.com +tlivecdnv2.com +tlivecdnv3.com +tlivecdnv4.com +tlivecloud.com +tlivecontroller.com +tlivecontroller2.com +tlivedal.com +tlivedal2.com +tlivedeliver.com +tlivedispatch.com +tlivedispatch2.com +tlivedns.com +tlivedns2.com +tlivednsv1.com +tlivegslb.com +tlivehttpdns.com +tlivehttpdns2.com +tliveigtm.com +tliveigtm2.com +tliveigtm3.com +tlivemcdn.com +tlivemcdnsched.com +tliveplay.com +tliveplaydemo.com +tliveproxy.com +tliveproxy2.com +tlivepush.com +tlivepush2.com +tlivertc.com +tlivertc2.com +tlivesdk.com +tlivesdk2.com +tlivesdkconfig.com +tlivesdkconfig2.com +tlivesource.com +tlivesrc.com +tlivesrc2.com +tlivesrcaccess.com +tlivesrcaccess2.com +tlivesrcapp.com +tlivesrcapp2.com +tlivesrcdemo.com +tlivesrcschedule.com +tlivesrcschedule2.com +tlivessl.com +tlivessl2.com +tlivestability.com +tlivestability2.com +tlivestream.com +tlivestream2.com +tliveupload.com +tliveupload2.com +tliveweb.com +tliveweb2.com +tlivewebrtc.com +tlivewebrtc2.com +tlivewebrtcpush.com +tlivewebrtcpush2.com +tlivewebrtcpushsch.com +tlivewebrtcpushsch2.com +tljas.com +tljcw.com +tljob8001.com +tljwbj.com +tljx.net +tlkuazr.com +tlomo.com +tloongroup.com +tlqwine.com +tlrcbk.com +tlryjg.com +tlsj-hd.com +tlsy.vip +tlt5.com +tlte.com +tltesoft.com +tltuan.net +tltzg.com +tlu5.com +tlwanjishan.com +tlwk.net +tlwok.com +tlxwjx.com +tlxxw.com +tly.cloud +tlyz.net +tlzey.com +tlzhjt.com +tlzyxy.com +tm-auto.com +tm0755.com +tm1949.com +tm51.com +tm5ad.com +tmaill.com +tmall.com +tmall.hk +tmall.ru +tmallalicdn.com +tmallgenie.com +tmallgenieapi.com +tmallplay.net +tmalltv.com +tmallvvv.com +tmallyc.com +tmaotech.com +tmbbs.com +tmc-youqun.com +tmcdn.net +tmctool.com +tmecd.com +tmeiju.com +tmetb.net +tmfcloud.com +tmgdb.com +tmhong.com +tmhtour.com +tmhttc.com +tmianyang.com +tmigrate.com +tmirob.com +tmisp.com +tmjbee.com +tmjd123.com +tmjiasuqi.com +tmjj.com +tmjl.ai +tmjob88.com +tmkoo.com +tmmini.com +tmoxrobot.com +tmqd.me +tmqd.so +tmqmqj.com +tmrcw.com +tmrenergy.com +tms-in.org +tms56.com +tms8.com +tmscnz.com +tmsemi.com +tmsf.com +tmshare123.com +tmsmh.com +tmsmq.com +tmsx.net +tmtforum.com +tmtmw.com +tmtpost.com +tmtpost.net +tmtsmartlife.com +tmtsmartrun.com +tmtsp.com +tmuaih.com +tmusoft.com +tmuyun.com +tmwcn.com +tmwxxcx.com +tmwzs.com +tmxmall.com +tmxxw.com +tmxz.me +tmyirick.com +tmzvps.com +tn2000.com +tnas.link +tnas.online +tnblog.net +tnblt.com +tnbz.com +tnccdn.com +tndsjka.com +tnebula.net +tnedu.com +tnettms.com +tngcjx.com +tngdigital.com.my +tnodenow.com +tnong.com +tnsou.com +tnyoo.com +tnzuwu.com +to-future.net +to2025.com +to4f.com +to999.com +toaobg.com +toast.pub +toaw.net +tobaccochina.com +tobaccosz.com +tobebetterjavaer.com +toberp.com +tobetopone.com +tobnews.com +tobo1688.com +tobosu.com +tobsnssdk.com +tochgo.com +tochinajob.com +tocomtech.com +tocosc.com +tocreating.com +today.ai +today36524.com +today99.com +todaycache.net +todaydunhuang.com +todayguizhou.com +todaygx.com +todayidc.com +todayintnet.com +todayios.com +todayisp.net +todaymedtech.com +todaynic.com +todaypublish.com +todayyj.com +todesk.com +todgo.com +todoen.com +todokeji.com +todokit.xyz +todolist.chat +todolist.email +todolist.pub +todonow.com +todoyi.com +todreamer.com +toec-gdgs.com +toec-iot.com +toec.com +toecsec.com +tofeat.com +tofengmi.com +tofflon.com +tofine.com +togoalad.com +togocareer.com +togogo.net +togoo.com +tohfox.com +tohosting.com +tohosting.net +tohours.com +toidea.com +toiue.com +tokcoder.com +tokeiaat.com +tokeimall080.com +tokeisuisukopi.com +token-ad.com +token-sensor.com +tokenglish.com +tokensky.net +tokimekiclub.org +tol24.com +tollpaymentbv.vip +tollpaymentkj.vip +tom.cat +tom.com +tom163.net +tom61.com +tomatogames.com +tomatolei.com +tomatooflove.com +tomax.xyz +tomdiy.com +tomley.com +tommsoft.com +tompda.com +tomson-group.com +tomson-riviera.com +tomwx.net +tonbao.com +tone-sun.com +tonebj.com +tonechemical.com +tonehk.com +tonewinner.com +tong-pao.com +tong-run.com +tongaokeji.com +tongbanjie.com +tongbaoyun.com +tongbb.net +tongbupan.com +tongbusj.com +tongceyiliao.com +tongchaba.com +tongcheng.cc +tongchengbx.com +tongchengchaku.com +tongchengir.com +tongchengqun.vip +tongchengxuanshang.com +tongchouba.com +tongda2000.com +tongdanet.com +tongdaohui.com +tongdaonews.com +tongdaotv.com +tongdayun.com +tongdelove.com +tongdinggroup.com +tongdun.net +tongdy.com +tongfangpc.com +tongfei.tech +tongfengkh.com +tongfu.net +tongfudun.com +tongfugroup.com +tonggao.info +tongguanbao.net +tonghanguav.com +tonghuan.com +tonghuiqiye.com +tongji.com +tongji.linezing.com +tongjia.com +tongjiai.com +tongjijs.com +tongjipf.com +tongkask.com +tongleer.com +tonglei.com +tonglian.com +tongliangrc.com +tongliaowang.com +tonglichang.com +tonglingwulian.com +tonglize.com +tongmengge.com +tongmengguo.com +tongniguoji.com +tongoiltools.com +tongpiao.com +tongquee.com +tongrenchina.org +tongrentang.com +tongrentangjb.com +tongrentangkj.com +tongrenyouxi.online +tongsha.com +tongshanbank.com +tongshiling.net +tongshuai.com +tongshun6.com +tongsuo.net +tongtaiamc.com +tongtech.com +tongtex-fashion.com +tongtianta.site +tongtongtong.com +tongtongyilian.com +tongtool.com +tongtut.com +tongwang.net +tongwei.com +tongwo.net +tongxi.net +tongxiang.net +tongxianghuicn.com +tongxiangshun.com +tongxiclub.com +tongxiehui.net +tongxigroup.com +tongxin.com +tongxin.org +tongxingbao123.com +tongxinghui.com +tongxinky.com +tongxinmao.com +tongxiong.com +tongxue.com +tongxue365.com +tongxue8.com +tongxuepie.com +tongyangship.com +tongyaoplay.com +tongyavisa.com +tongye.biz +tongye56.com +tongyehuanbao.com +tongyi.com +tongyicm.com +tongyidrying.com +tongyiplastic.com +tongyist.com +tongyonggroup.com +tongyongpe.net +tongyongts.com +tongyongzs.com +tongyoujiancai.com +tongyu369.com +tongyuan.cc +tongyuangas.com +tongyuanos.com +tongyue.com +tongyuheavy.com +tongzecn.com +tongzhuo100.com +tongzhuodn.com +tongzicha.com +tongzsf.com +tonhwa.com +toniandguychina.com +tonitech.com +tonki-tpms.com +tonksz.com +tonlyele.com +tonnp.com +tonsontec.com +tontian.com +tontime.com +tontsen.com +tony-bro.com +tonycrane.cc +tonysfarm.com +tonze.com +toobiao.com +toocf.com +toocle.com +toodaylab.com +toodudu.com +tool.la +tool.lu +tool56.com +tool77.com +tooleemesse.com +toolgg.com +toolkk.com +toolmall.com +toolmao.com +toolnb.com +toolonline.net +tools.team +toolscat.com +toolsjy.com +tooltt.com +toolwa.com +tooming.com +toomoss.com +toonechem.com +tooopen.com +tooseo.com +tootour.com +toouoo.com +top-cnc.com +top-dianjingfeng.com +top-elan.com +top-shanghai.com +top-trust.com +top100school.com +top100summit.com +top147.com +top168.com +top1game.com +top263.net +top2fun.com +top3456.com +top4xlc.com +top6000.com +topbester.com +topbiol.com +topbiz360.com +topbook.cc +topbridge.asia +topcanchina.com +topcdb.com +topcentenviro.com +topcheer.com +topchitu.com +topcj.com +topcomm.co +topcpu.net +topcrab.com +topcsic.com +topcto50.com +topdodo.com +topdoge123-a.com +tope365.com +topeastic.com +topeditsci.com +topeet.com +topeetboard.com +topexhib.net +topfisc.com +topflames.com +topfo.com +topfreeweb.net +topgoer.com +topgprs.com +topgslb.com +topgus.com +tophant.com +tophold.com +tophr.net +tophub.app +tophub.fun +tophub.today +topideal.com +topit.pro +topit5.com +topjoy.com +topjoycloud.com +topkhealth.com +topku.com +toplanit.com +toplee.com +toplevel.ink +toplife.com +toploong.com +topmba.mobi +topmediai.com +topnic.net +topnokycusdtcasino.com +topomel.com +toppdu.com +topperuse.com +topping.pro +toppingaudio.com +toppkg.com +toppollen.com +toppps.com +toppridehk.com +topproio.com +topqh.net +toprand.com +toprender.com +toprocn.com +topsage.com +topsayauto.com +topscan.com +topsedu.com +topsim.cc +topsmartinfo.com +topsmt.com +topsresearch.com +topsrx.com +topstar.art +topstarltd.com +topsunholdings.com +topsunleisure.com +topsunpower.cc +toptastewin.com +topthink.com +topthink.net +toptiao.com +toptopn.com +toptopone.com +toptubeco.com +topuc.com +topunix.com +topv1.com +topwalk.com +topway.org +topwaysoft.com +topwidgets.com +topwinchance.com +topwinfo.com +topxgun.com +topxiu.com +topxlc.com +topxlc6.com +topys.com +topyun.tv +topyun.vip +topzj.com +torch.plus +torcstark.com +toromotor.com +torovo.com +torphan.com +torrealcielo.com +toscdn.com +toshiba-gtbs.com +toshiba-semicon-storage.com +toshiba-thpc.com +toshiba-tnis.com +toshow.com +tosohbioscience.net +tosonet.com +tosound.com +tospur.com +tosstar5117.com +tosuai.com +tosunk.com +totainfo.com +totalacg.com +totenchina.com +totheglory.im +totiot.com +totochina.com +totodi.com +totope.com +totoro.pub +tototang.com +totren.com +totwoo.com +totwoseal.com +tou-tiao.com +toubang.tv +toucdn.com +touch-ck.com +touch-massageandholistictherapies.com +touch-moblie.com +touch4.me +touchat.online +touchealth.com +touchelf.com +touchev.com +touchjoin.com +touchjoint.com +touchmark.art +touchngo.com.my +touchsh.com +touchsprite.com +touchsprite.net +touchstudio.net +touduyu.com +toufu321.com +tougongjiao.com +tougub.com +touhou.casa +touhou.cd +touhou.market +touhoudog.net +toujidao.com +touker.com +toumiao.com +toupb.com +touqikan.com +tour110.com +tourboxtech.com +tourenwang.com +tourgansu.com +tourhr.com +tourjob.net +tourongjia.com +tourongzi.org +toursbms.com +tourscool.com +tourunion.com +tourye.com +tourzhenjiang.com +tourzj.com +toushivip.com +toutiao.com +toutiao.org +toutiao11.com +toutiao12.com +toutiao13.com +toutiao14.com +toutiao15.com +toutiaoapi.com +toutiaoapp.com +toutiaobashi.com +toutiaobus.com +toutiaocdn.com +toutiaocdn.net +toutiaocloud.com +toutiaocloud.net +toutiaogood.com +toutiaohao.com +toutiaohao.net +toutiaoimg.com +toutiaoimg.net +toutiaojingyan.com +toutiaojisu.com +toutiaolite.com +toutiaolite1.com +toutiaolite2.com +toutiaoliving.com +toutiaonanren.com +toutiaopan.com +toutiaopanapi.com +toutiaopic.com +toutiaoribao.net +toutiaostatic.com +toutiaovod.com +toutiaowap.com +toutiaowap.net +toutiaoyule.com +toutiaozb.com +toutoufc.com +toutoupiao.com +touwenzi.com +touwho.com +touxiang8.com +touxiang88.com +touxiangkong.com +touying.com +touzhijia.com +touzi.com +touzid.com +touzikuaibao.com +touzime.com +touzime.net +touzitiandi.com +touzizn.com +towavephone.com +towelltech.com +tower.im +tower0788.com +towinor.com +towmy.com +towngasenergy.com +towngasvcc.com +townsky.com +townsungroup.com +towntour.net +towords.com +towry.me +towyzcxc.com +toxingwang.com +toybaba.com +toycloud.com +toyean.com +toyota-nanning.com +toyoures.com +toyoutesting.com +toysir.com +toysol.com +tp-data.com +tp-hivi.com +tp.louisvuitton.com +tp82.com +tpadx.com +tpbook.com +tpccoo.com +tpdmp.com +tpdz.net +tpe-tencentclb.cloud +tpe-tencentclb.com +tpe-tencentclb.net +tpe-tencentclb.work +tpfangchan.com +tphdled.com +tpiccdn.com +tpiccdn.net +tpimg.xyz +tpjhr.com +tpjwww.com +tpkey.com +tplcd100.com +tplife.com +tplogincn.com +tpooo.com +tpoxiaozhan.com +tpqxb.com +tprtc.com +tps138.info +tpsbp.com +tpsea.com +tpsge.com +tpshleasing.com +tpsns.com +tpstatic.net +tpsxs.com +tpszw.com +tpturang.com +tpuda.com +tpumlir.org +tpy100.com +tpy119.com +tpyboard.com +tpykyy.com +tpyzq.com +tpzlj.com +tqads.com +tqapp.com +tqapp.net +tqcj.com +tqcp.net +tqcpc.com +tqcrane.com +tqcto.com +tqdianbiao.com +tqedu.net +tqgxb.com +tqhj88.com +tqiangg.com +tqiangg.net +tqiantu.com +tqip.com +tqkgjt.com +tql.ink +tqle.com +tqmall.com +tqmba.com +tqmdp.net +tqmy168.com +tqpac.com +tqqa.com +tqqyun.com +tqrobodrive.com +tqschool.net +tqshfw.com +tqshfw.net +tquic.net +tquyi.com +tqw5.com +tqwqq.com +tqybw.net +tr-test-ali.net +tr-test.net +tr-testboe.net +tr89.com +trace4me.com +tracefact.net +tracegd.com +traceint.com +tracestour.com +tracevision.tv +tracker.ink +trackingmore.com +tracup.com +tracyclass.com +tradaquan.com +tradeblazer.net +tradeleo.com +trademanager.com +trademessenger.com +tradeplus.cc +tradesns.com +tradesou.com +tradevv.com +tradew.com +tradingcomps.com +tradinghero.com +tradow.com +trae.guru +traineexp.com +trainingipv6.com +trainnets.com +trainsimchina.com +trait-wholesale.com +tranbbs.com +traneasygo.cc +tranlion.com +tranplanet.com +trans-china.com +trans4e.com +transcendchina.com +transcenta.com +transduck.com +transer-cn.com +transfarchem.com +transfarzl.com +transformer-cn.com +transformers.run +transfriend.com +transfu.com +transfun.net +translatego.net +translatellm.asia +translationchina.com +transmission-china.org +transmonkey.com +transmonkey.net +transn.com +transnanning.com +transparcel.com +transportjp.com +transrush.com +transsion-os.com +transsscoco.com +transthera.com +transwarp.io +transwiki.org +tranwit.com +tratamientoalcohol.com +tratao.com +travel-x.cc +travel6.co.uk +travelgo.com +traveling-exhibitions.com +travellaureate.com +travellingwithhotel.com +travellinkdaily.com +travelsky.com +travelsky.net +travelwuhan.com +travelyee.com +trawind.com +treatgut.com +treazr.store +treehousesub.com +treesir.pub +treetwins.com +treeyee.com +trekin.space +trellocdn.com +trend6.com +trendiano.com +trendimedia.com +trendingstar.tech +trendsbulletin.com +trendsmag.com +trendsmen.com +trendtokyo.com +trendy-global.com +trenrde.com +tressgroup.com +tretars.com +trevias.store +trewbnhj.vip +trexiu.com +trfgvb.com +trfkyy.com +trftpe.com +trgauto.cfd +trgis.com +trhealth.net +trhj.net +trhly.com +trhos.com +trhui.com +trhxt.com +triggerdelivery.com +trinasolar.com +trinitigame.com +trinova-tech.com +trioisobardev.com +triolion.com +triopen.com +triorder.com +triowin.com +trip.com +trip169.com +trip8080.com +tripbaba.com +tripbe.com +tripcdn.com +triphr.com +tripleuuu.com +triplexservice.com +tripnearby.com +tripodeck.com +tripolers.com +tripsanxia.net +triptt.com +tripurx.com +tripvivid.com +tripwirechina.com +triring.com +trisfal.com +tristarinc.com +triton-games.com +tritoninfo.net +trizenai.com +trizinfo.tech +trizlaser.com +trizmed.com +trjcn.com +trjcn.net +trjddq.com +trkj.com +trkjbj.com +trl.center +trleader.com +trli.club +trmedical.net +trnjm.com +trnox.com +troika-design.com +troila.com +trojantesting.com +tronixin.com +tronlife.com +tronlong.com +tronly.com +tronsmart.com +tropcdn.com +troubles.work +troxchina.com +trpc.center +trpc.group +trpc.tech +trpcdn.com +trpcdn.net +trqjrp.xyz +trs-logistics.com +trsjgdj.com +trsoft.vip +trsoft.xin +trsol.com +trswtz.com +trt.hk +trtb.net +trtc.io +trtcanlitv-lh.akamaihd.net +trtccloud.com +trtccloud.net +trtcrecover.com +trthealth.com +trtpazyz.com +trtquxro.com +trucker365.com +trucklc.com +trueart.com +truebuty.com +truechine.com +truedian.com +truedream.ltd +trueeyu.com +trueful.com +truekex.com +trueland.net +trueme.net +truerun.com +truesing.com +truestudio.tech +trufun.net +truimo.com +trumpeter-china.com +trumsense.com +trunktech.com +trusfort.com +trusit.net +trusple.com +trust-mro.com +trust-one.com +trust400.com +trusta-lawyer.com +trustasia.com +trustcn.com +trustdecision.com +trustedsign.com +trustexporter.com +trustie.net +trustkernel.com +trustlife.com +trustmo.com +trustmover.com +trustmta.com +trustwe.com +trutes.com +truthsinfo.com +truzem.com +trvok.com +trwl.net +tryfun.com +tryine.com +tryineapp.com +trykan.com +trylmr.com +trymoka.com +tryudesk.com +tryurbest.com +tryxue.com +tryz.net +trzhineng.com +ts-bus.com +ts-cooling.com +ts-jiabo.com +ts-juheng.com +ts-marathon.com +ts-precision.com +ts-watch.com +ts.cc +ts0775.com +ts100.com +ts16949px.com +ts16949rz.org +ts3.hk +ts3.ink +ts3.vip +ts56xh.com +tsa-lp.com +tsa-page.com +tsa-page0.com +tsa-page1.com +tsa-page2.com +tsa-page3.com +tsa-page4.com +tsa-page5.com +tsa-page6.com +tsapage.com +tsarufaq.com +tsbjschool.com +tsbtv.tv +tschina.com +tscichina.com +tscorona.com +tsdaodao.com +tsdjg.com +tsdxb.com +tsecdapi.com +tsefang.com +tsepcn.com +tses.net +tsflc.com +tsfqw.com +tsg-online.net +tsggx.com +tsgks.com +tsgyun.com +tshaisen.com +tshe.com +tshe.me +tsheducation.net +tshell.online +tshengqi888.com +tshmkj.com +tshock.cc +tshtech.com +tsichuan.com +tsinergy.com +tsing-jn.com +tsingaero.com +tsinghua-getinfo.com +tsinghua-sz.org +tsinghua-vc.com +tsinghua-wx.org +tsinghuaic.com +tsinghuajournals.com +tsinghuan.com +tsinghuawoman.com +tsinghuawuxigz.net +tsinghydrogen.com +tsingj.com +tsingmicro.com +tsingming.com +tsingoofoods.com +tsingpost.com +tsingshang.com +tsingtek.com +tsingtoo.com +tsingtuo.com +tsingyangroup.com +tsingyanresearch.com +tsj-js.com +tsj-tsy.com +tsjtsy.com +tsk-fixture.com +tskscn.com +tslib.net +tsljzs.com +tslongtai.com +tslsmart.com +tslt.tech +tsluping.com +tsm-license-test.com +tsm-license.com +tsm-yuntrust.com +tsm52dc.com +tsmtkj.com +tsn-tencentclb.cloud +tsn-tencentclb.com +tsn-tencentclb.net +tsn-tencentclb.work +tsorder.com +tsp189.com +tsparkling.com +tspsy.com +tspweb.com +tsqw.com +tsrcw.com +tsrenli.com +tsrnjs.com +tsrqjt.com +tsrqjtfc.com +tsruifeng.com +tssns.net +tsstorry.com +tssyedu.com +tssyjt.com +tstvxmt.com +tsubakichina.com +tsukistar.fun +tsunbull.com +tswjs.net +tswjs.org +tswljt.com +tswnanning.com +tswuby.com +tsxcfw.com +tsxcx.xyz +tsxgedz.com +tsxjt.com +tsxtgj.com +tsxw66.com +tsycdn.com +tsyexmail.com +tsykf.com +tsyvps.com +tsyzm.com +tszh.net +tszhjk.com +tszlsgs.com +tszxhosp.com +tszyzx.com +tt-app.com +tt-bike.com +tt-ly.com +tt286.com +tt65org.com +tt787.com +tt818k.com +tt919.com +tt96596.com +ttaidu.com +ttalkai.com +ttbba.com +ttbbss.com +ttbyte.com +ttbyte.net +ttcad.com +ttcatv.tv +ttcl.cc +ttdailynews.com +ttdnsa.com +ttdown.com +ttdsw.com +ttechhk.com +ttfly.com +ttfuav.com +ttg8.com +ttgan.com +ttge.ru +ttggxx.com +ttgjx.com +ttgood.com +ttgslb.com +ttgtm.com +ttgwm.com +ttgxlx.com +tthaoduo.com +tthigo.com +tthunder.com +ttic.cc +ttigame.com +ttime.com +ttionya.com +ttj5.com +ttjianbao.com +ttjisu.com +ttkdex.com +ttkefu.com +ttkuan.com +ttlock.com +ttmark.com +ttmass.com +ttmd5.com +ttmeiju.com +ttmm.vip +ttmn.com +ttmnq.com +ttmv.com +ttn8.com +ttnea.com +ttnongli.com +ttnqh.com +ttongda.com +ttpaicdn.com +ttpaihang.com +ttpaper.com +ttpet.com +ttpharm.com +ttplayer.co +ttplayer.com +ttpod.com +ttpp.com +ttppoo.com +ttpx.net +ttq.com +ttq.so +ttqiadar.com +ttqiancheng.com +ttriqi.com +tts8.com +ttshengbei.com +ttship.com +ttshuba.cc +ttshuba.net +ttsim.com +ttsim.net +ttsmk.com +ttstream.com +ttsz8.com +tttang.com +tttarot.com +tttcykt.com +tttelephone.com +ttthing.com +tttiti.com +tttkkt.com +tttllt.com +ttttt22222.com +tttuangou.net +tttxf.com +tttz.com +ttunion.com +ttvmexmk.com +ttwanjia.com +ttwifi.net +ttwqw.com +ttwx.com +ttwxh.com +ttxn.com +ttxs123.net +ttxs7.com +ttxsapp.com +ttxsonline.com +ttxuanpai.com +ttxx8888.com +ttyec.com +ttyfp.com +ttyfund.com +ttyinfo.com +ttyingqiu.com +ttyjf.com +ttymq.com +ttyongche.com +ttyqm.com +ttysq.com +ttyuyin.com +ttyy800.vip +ttzcw.com +ttzubao.com +ttzw365.com +ttzyw.com +tu54o7863tbf6.com +tu8.cc +tu93.biz +tu960.com +tuan800.com +tuan800.net +tuanai.com +tuanbohui.com +tuanche.com +tuancu.com +tuandai.com +tuanduishuo.com +tuang.club +tuangai.com +tuangouba.com +tuanidc.net +tuanimg.com +tuanitgx.com +tuanjiebao.com +tuanjuwang.com +tuanlin.net +tuanmeme.com +tuanok.com +tuanpibao.com +tuanping.com +tuanshan.com +tuantuangame.com +tuantuanshou.com +tuanxue360.com +tuanyougou.com +tuanyuan520.com +tuanyx.com +tuanziai.com +tubachina.com +tubanginfo.com +tubangzhu.com +tubaobao.com +tubaobaoqm.com +tubaoveneer.com +tubaoyz.com +tubatu.com +tube-cat.com +tubebbs.com +tubiaoxiu.com +tubie.art +tuboshu.com +tuboshuxinxi.xyz +tuboxu.com +tubutu.com +tuchong.com +tuchong.net +tuchuangs.com +tuchuiwang.com +tuchuiwang.net +tucoo.com +tudai.cc +tudai.com +tudan.cc +tudan.vip +tudou.com +tudoupe.com +tudouseo.com +tudouui.com +tudouxy01.com +tudouyx.com +tudu.com +tudu.im +tuer.me +tuer123.com +tuf3a353.com +tuganjue.com +tugemedical.com +tugoo.net +tugou.com +tugoucx.com +tuguaishou.com +tuguan.net +tuguiyao-gd.com +tuhaiba.com +tuhaogroup.com +tuhaokuai.com +tuhu.com +tuhu.org +tuhu.work +tui18.com +tui33.com +tuiaaaa.com +tuiaaae.com +tuiaaaf.com +tuiaaag.com +tuiabq.com +tuibear.com +tuiberry.com +tuiclick.com +tuicool.com +tuicross.com +tuidaniu.com +tuidc.com +tuideli.com +tuidragon.com +tuifeiapi.com +tuiguang91.com +tuiguangdns.com +tuiguangjia.com +tuijiantong.com +tuijianxin.com +tuijie.cc +tuikemima.com +tuikemima.net +tuikemohe.com +tuili.com +tuilidashi.xin +tuilie.com +tuilisr.com +tuiliu.net +tuilixy.net +tuimob.com +tuimotuimo.com +tuimy.com +tuipeanut.com +tuipear.com +tuipinpai.com +tuiplay.com +tuirice.com +tuishao.net +tuishark.com +tuishubang.com +tuishuge.com +tuishujun.com +tuisnake.com +tuistone.com +tuitui.info +tuitui99.com +tuituifang.com +tuituitang.com +tuiwen.net +tuixiu.com +tuiyi.cc +tuizx.com +tujia.com +tujiacdn.com +tujian.com +tujiandan.com +tujidu.com +tujixiazai.com +tuke88.com +tukedu.com +tukkk.com +tuku.com +tukujia.com +tukuppt.com +tulading.com +tuleminsu.com +tuling123.com +tulingdns.com +tulipsport.com +tuliu.com +tulsj.com +tumajewelry.com +tumanyi.com +tumchina.com +tumengtech.com +tumicomm.com +tumormed.com +tumukaoyan.com +tumukeji.com +tumwf.com +tumyu.com +tuna.wiki +tunanhuashi.com +tungee.com +tungkong.com +tungraymhe.com +tungs.store +tungshungroup.com +tungsten-alloy.com +tungsten-bar.com +tungsten-copper.com +tungsten-jewellery.com +tungsten-powder.com +tungwah.com +tunhe.com +tunhent.com +tunionfans.com +tuniu.cc +tuniu.com +tuniu.net +tuniu.org +tuniucdn.com +tuniuglobal.com +tuniuins.com +tuniuops.net +tunynet.com +tuo-pan.com +tuoaa.com +tuobeng.net +tuocad.com +tuodan.tech +tuodaneee.com +tuodangclub.com +tuodanlab.com +tuodanyy.com +tuohuangzu.com +tuojiebiotech.com +tuojunedu.com +tuolajieightscore.com +tuoluozhuan.net +tuoniaox.com +tuopaishedecta.com +tuopan808.com +tuopu.com +tuoren.com +tuotoo.com +tuotuozu.com +tuoweisi.com +tuoyuan619.com +tuoyuantec.com +tuozhe8.com +tuozheng168.com +tuozhilight.com +tupian1.com +tupian114.com +tupian1234.com +tupian365.com +tupiancunchu.com +tupiankucdn.com +tupianseo.com +tupianyun.com +tupianzj.com +tupu360.com +tuputech.com +tupuw.com +tuqiangcn.com +tuqou.com +tuquu.com +turangyq.com +turboes.com +turbomail.org +turingapi.com +turingbook.com +turingdi.com +turingfraud.net +turinggear.com +turingtopia.com +turnitin.org.in +turnitinuk.net +turs-ptt.icu +turtle-sir.com +turui-robots.com +turuio.com +tus-health.com +tusapi.com +tusay.net +tuscbec.com +tuscdn.com +tusdesign.com +tusdk.com +tusenergy.com +tushare.org +tushare.pro +tushencn.com +tushifu.com +tusholdings.com +tushu007.com +tushumi.cc +tushumi.com +tushuokeji.net +tusij.com +tusiot.com +tusmedicine.com +tusooo.com +tuspark.com +tuspass.com +tuspass.net +tusstar.com +tustt.com +tusu.cc +tusuguanjiage.com +tusujiu.com +tutdown.com +tutechanhb.com +tutengcloud.com +tutengdai.com +tutu001.com +tutuapp.com +tutucloud.com +tutudati.com +tutuge.me +tutuguai.com +tutuim.com +tutupan.com +tuvrblog.com +tuwan.com +tuwandata.com +tuwangwang.com +tuwanjun.com +tuwazhundian.com +tuweng.com +tuwenzhibo.com +tuxi.com +tuxiangyan.com +tuxiaobei.com +tuxing.art +tuxing2010.com +tuxingren.com +tuxiu.com +tuxun.fun +tuya.com +tuyacn.com +tuyansuo.com +tuyaya.com +tuye.com +tuyiqi.com +tuyitu.com +tuyiyi.com +tuyoo.com +tuyou.me +tuyougame.com +tuyoujp.com +tuyoumi.com +tuyouvpn.com +tuyouxinxi.net +tuzhan.com +tuzhan.net +tuzhanai.com +tuzhanh5.com +tuzhaozhao.com +tuzhijie.com +tuzhizhijia.com +tuzhongit.com +tuzi123.com +tuzi8.com +tuziip.com +tv-live-cctv.com +tv-live-tvsou.com +tv.cnbeijing.xyz +tv.drs.hhtv.cc +tv.nknews.org +tv002.com +tv121.com +tv189.com +tv2-zuqiu.com +tv20806.com +tv373.com +tvandnet.com +tvapk.com +tvapk.net +tvbbj.com +tvblack.com +tvcbj.com +tvcbook.com +tvccc.org +tventry.com +tvfanqie.com +tvfuwu.com +tvguo.tv +tvhf.com +tvhuan.com +tvjianshen.com +tvkuai.com +tvmao.com +tvmcloud.com +tvmining.com +tvoao.com +tvodapi.com +tvodapibk.com +tvos.com +tvt.im +tvt85.com +tvuctgze.com +tvxio.com +tvzhe.com +tvzn.com +tw-joly.com +tw-yun.com +tw2sm.com +twanxi.com +twatchesmall.com +twbuild.org +twcoal.com +twd2.me +twd2.net +twdxdl.com +tweakcube.com +twheixiong.com +twinkledeals.com +twinkstar.com +twinsel.com +twinsenliang.net +twistysocks.com +twk.cc +twmsuf.com +twoarmy.com +twoear.com +twplink.xyz +tws.com +twsapp.com +twscholar.com +twsns.com +twsz-cq.com +twszs.com +twtes18.com +twtime.vip +twtstudio.com +twty.vip +twwtn.com +twwtn.net +twyuxin.com +twyxi.com +twz1t32lzy.com +twzgn.com +twzilla.com +twzmd.com +tx-exhibition.com +tx-livetools.com +tx-trans.com +tx.lilyemby.com +tx009.com +tx1588.com +tx163.com +tx321.com +tx365.com +tx5d.com +tx8j.com +txacc1.com +txacc1.net +txbanche.com +txbapp.com +txbimg.com +txbond.com +txbyod.com +txcap.com +txcdns.com +txcdns.net +txcfgl.com +txcgoo.com +txclivecdn.com +txcloudlive.com +txcm365.com +txcm365.net +txcmapp.com +txcode.com +txcx.com +txcx.tech +txcxjd.com +txcxpt.com +txczawlfpj5.com +txdai.com +txdl1.com +txdl1.net +txdl2.com +txdl2.net +txdyt.com +txdzw.com +txelive.com +txelvb.com +txeo.net +txfba.com +txfeiyu.com +txffp.com +txfund.com +txga.com +txgirl1.com +txgirl2.com +txhsya.com +txhttpdns.net +txhy1699.com +txitech.com +txjhqh.com +txjscl.com +txjsjgs888.com +txjy689.com +txlctong.com +txleshare.com +txlivecdn.com +txlivecdn2.com +txlt.com +txlunwenw.com +txlzp.com +txmcu.com +txmdb.com +txmkf.com +txon.net +txooo.com +txqcw.net +txqq.com +txqq789.com +txresearch.com +txrjy.com +txrpic.com +txrz.com +txrzx.com +txscdn.com +txsdk.com +txsec.com +txsf.com +txssw.com +txstatic.com +txt101.com +txt321.com +txt81.com +txtag-secure.world +txtagsceru.cc +txtagscerw.cc +txtbbs.com +txtduo.com +txtelsig.com +txtshuku.org +txttgj.com +txttool.com +txtyxg.com +txuwft6117.vip +txvat.com +txvideo1.com +txvideo2.com +txwb.com +txweekly.com +txwestart.com +txwm.com +txwy.com +txwy.com.tw +txx66.com +txxy.com +txxzc.com +txy8.com +txyapp.com +txybio.com +txybk.com +txyes.com +txyfwq.com +txyscdn.com +txyscdn.net +txzb.app +txzing.com +txzqzb.com +txzuranji.com +ty-archdesign.com +ty-group.net +ty-im.com +ty-magnet.com +ty-tyre.com +ty-xxl.com +ty.ink +ty1970.com +ty2y.com +ty360.com +ty3w.net +ty8621.com +tybai.com +tyboard.net +tyc100.com +tyc13804.com +tyc13810.com +tyc13867.com +tyccdn888.com +tychemical.com +tychio.net +tycimages.com +tyclport.com +tycqxs.com +tycredit.com +tydao.com +tydcdn.com +tydesyxx.com +tydevice.com +tydgas.com +tydns.cc +tyduanju.com +tyeat.com +tyeec.net +tyepi.com +tyfo.com +tygameworld.com +tygckj.com +tyh120.com +tyhjrbl.com +tyhjzx.com +tyi365.com +tyihome.com +tyjd.cc +tyjnkj.com +tyjsq.com +tykd.com +tykmedicines.com +tylls.com +tym001.com +tymcdn.com +tymotor.cc +tyn.cc +tynlwx.com +tynxy.com +tyorient.com +tyouai.com +typany.com +type.so +typecho.work +typechodev.com +typechx.com +typeeasy.net +typhoon.vip +typicalchn.com +typora.net +typrotech.com +tyqian.com +tyqxzx.com +tyrantg.com +tyrbl.com +tyrbw.com +tyread.com +tysdmh.com +tysih.com +tysj365.com +tyst.cc +tysurl.com +tyszy.com +tytgigty.com +tytlj.com +tytuyoo.com +tytzy.com +tytzyyy.com +tytzzy.com +tyuanlv.com +tyust.net +tyututy.com +tyuyan.com +tyuyan.net +tywangcai.com +tywbw.com +tywh.com +tywheels.com +tywx.com +tywxw.la +tyxcdn.com +tyxcdn.net +tyy6.com +tyymt.com +tyzh.com +tyzhjx.com +tyzhyun.com +tyzs8.com +tyzspy.com +tz-water.com +tz100.com +tz118802.com +tz121.com +tz12306.com +tz1288.com +tz13866.com +tz13897.com +tz13898.com +tz1980.com +tz2100.com +tz777666.com +tz8733.com +tz887.com +tz8966.com +tz94.com +tz999777.com +tzada.com +tzbank.com +tzbank.net +tzbao.com +tzcpa.com +tzcul.com +tzcz.com +tzedu.org +tzfdc.com +tzfeilu.com +tzfeize.xyz +tzfile.com +tzgamepkg.com +tzgcjie.com +tzggzj.com +tzgjjt.com +tzgkuci.com +tzgsjc.com +tzhledu.net +tzhospital.com +tzhwcc.com +tzjob.com +tzjxl.com +tzjyjt.com +tzjz123.com +tzjzsw.com +tzkameng.com +tzkciz.com +tzke18.mobi +tzlib.net +tzlmt.com +tzm66.com +tzme.net +tzmem.com +tzmpqcfr.com +tzpaper.com +tzqby.com +tzqingzhifeng.com +tzqytv.com +tzrc.com +tzres.com +tzrl.com +tzsfhxx.com +tzshipping.net +tzsnw.com +tzsports.com +tzsti.com +tzsucai.com +tzswatch.com +tzswfz.com +tzsz.net +tzszyy.com +tztledu.com +tztrq.com +tztusi.com +tzujian.com +tzvec.com +tzvtc.com +tzwpco.com +tzxingtang.com +tzxwzx.com +tzyiyuantuan.com +tzyongda.com +tzyun.com +tzyy-sh.com +tzyyao.com +tzyyjt.com +tzzhkj.com +tzzhtc.com +tzzls.com +tzzp.com +tzzszb.com +tzzx.net +u-camera.com +u-carloan.com +u-cdn.com +u-cdn.net +u-con-dom.com +u-con-dom.net +u-lights.com +u-link.org +u-mro.com +u-om.com +u-qun.com +u-road.com +u-sharing.work +u-softtech.com +u-speedex.com +u-workshop.com +u.biz +u.sb +u.tools +u005.com +u0351.com +u0537.com +u062.com +u10010.com +u10086.com +u14.com +u148.net +u17.com +u17i.com +u17t.com +u1d1.com +u21a.com +u22e.com +u235.net +u2j2ha.com +u2sz.com +u3dc.com +u3dcn.com +u3dol.com +u3l120di51.com +u3v1adybl4.com +u3v3.com +u4u5.com +u4u5.tv +u51.com +u520.net +u58.com +u581.com +u5wan.com +u69cn.com +u6ex.com +u72.net +u78785.com +u8164i46a4.com +u88.com +u8e.com +u8see.com +u8sy.com +u8yb16b993.com +u8yx.com +u966.com +u9baoku.xyz +u9h.com +u9time.com +u9u8.com +u9u9.com +u9wan.com +uabkrsj.xyz +uahh.site +uakwezgc.com +uancf.com +uandi-wireless.com +uangee.com +uao-online.com +uao.so +uaomprvw.com +uascent-iot.com +uat1.bfsspadserver.8le8le.com +uatmrrvendor.com +uauc.net +uavtjxh.com +uavvv.com +uaxk.com +ub-os.com +ubaiyi.com +ubangmang.com +ubao.com +ubc-bearing.com +ubccn.com +ubeethiesemo.com +ubeihai.com +ubesh.com +ubestkid.com +ubetween.com +ubgame.com +ubicdn.com +ubiquant.com +ubismartparcel.com +ubits.club +ubixai.com +ubja.vip +ublese.com +ubmconlinereg.com +ubmsinoexpo.com +uboat100.com +uborn.net +uboxol.com +ubs001.com +ubssdic.com +ubtrobot.com +ubuant.com +ubuntukylin.com +ubuuk.com +ubuylogi.com +uc-test.com +uc-union.com +uc108.com +uc129.com +uc138.com +uc1z.com +uc2008.com +uc23.net +uc56.com +uc666.com +ucacc.com +ucai123.com +ucaiyun.com +ucancs.com +ucanrobot.com +ucantech.com +ucantech.net +ucany.net +ucarinc.com +ucassc.com +ucb6.com +ucbug.com +uccastore.com +uccbikes.com +uccpd.com +ucdchina.com +ucdok.com +ucdrs.net +ucgslb.com +ucgslb.info +ucgslb.net +ucgslb.top +uchangdi.com +uchiha.ltd +uchis.com +uchoice.cc +uchuanbo.com +ucicq.com +ucigl.com +ucjoy.com +ucl0ud.com +ucloud-edm.com +ucloud365.com +ucloudadmin.com +ucloudapi.com +ucloudgda.com +ucloudnaming.com +ucloudnaming.info +ucloudnaming.net +ucloudoss.com +uclouds3.com +ucloudstack.com +ucloudstack.net +ucloudstor.com +uclouduewaf.com +ucloudufile.com +ucly.net +ucmmine.com +ucnaming.com +ucnaming.info +ucnaming.net +ucnano.com +ucnest.com +ucpaas.com +ucpchina.com +ucpopo.com +ucren.com +ucsanya.com +ucss.ninja +uctwydx.com +ucun.tech +ucuntech.com +ucuuc.com +ucw.pub +ucweb.com +ucxsw.com +ucying.com +udache.com +udacity.com +udalogistic.com +udamall.com +udangjia.com +udasauto.com +udashi.com +udbac.com +udcgroup.com +udcn.com +uddtrip.com +udecig.com +udelivrs.com +udeskcs.com +udeskglobal.com +udfspace.com +udiannet.com +udid.vin +udns.dev +udonmai.com +udows.com +udragons.com +udream.com +udsdown.xyz +udship.com +udsstudio.com +udxd.com +uebilling.com +uebuilder.net +uecook.com +ued1.com +uedbet.bet +uedbox.com +uedna.com +ueep.com +ueeshop.com +uehchina.com +uehtml.com +ueibo.com +ueiibi.com +uelike.com +uemo.net +ueno-china.com +uenu.com +ueoqex.help +ueren.com +uestcedu.com +uestcliuxue.com +uesw215.xin +uetianshanyp.com +ueuz.com +uewaf.com +uez.com +uf-crm.com +uf-tobacco.com +ufancycase.com +ufanw.com +ufcap.com +ufcs.com +ufenqi.com +ufhost.com +ufhosted.com +ufida-lcwy.com +ufidaoa.com +ufileos.com +ufirefly.com +ufizl.com +ufkwm.com +ufo.club +ufo110.net +ufoer.com +ufojoy.com +uformwater.com +ufsoo.com +ufyct.com +ug.link +ugainian.com +ugapi.com +ugapk.com +ugbb.com +ugc-up-dom.com +ugc-up-dom.net +ugdesk.com +ugdocker.link +uggame.com +uggd.com +ugirls.tv +ugmars.com +ugmjd.com +ugnas.com +ugnx.net +ugo-china.com +ugojp.com +ugong.com +ugoshop.com +ugostar.com +ugreen.cloud +ugreengroup.com +ugshare-img.com +ugslb.com +ugslb.info +ugslb.net +ugslb.top +ugslb2.net +ugsnx.com +ugtemfeu.com +ugubl.net +ugurl.cc +ugxsd.com +uhaom.com +uhaozu.com +uhasadmin.com +uhbthn.com +uhcmu.com +uhomecp.com +uhomes.com +uhomesplus.com +uhouzz.com +uhp.cc +uhs68.com +uhuibao.com +uhuitong.com +uhuocn.com +uhut.com +uhzcdn.com +ui-lab.com +ui100day.com +ui63.com +uibep.com +uibhealthcare.com +uibmm.com +uicats.com +uicmall.com +uicom.net +uid75.com +uidec.com +uidev.tech +uidev.xyz +uihacker.com +uiiiuiii.com +uijtcareers.cfd +uik.cc +uil.ink +uileader.com +uimix.com +uincall.com +uincall400.com +uinchat.com +uincom400.com +uino.com +uipaas-assets.com +uipower.com +uiren.net +uisdc.com +uisee.com +uisheji.com +uishijie.com +uisnetwork.com +uisrc.com +uiste.com +uit-sz.com +uitab.com +uitool.net +uiu.cc +uiuihub.com +uiwow.com +ujakn.com +ujia007.com +ujianchina.net +ujiao.net +ujiaoshou.com +ujinbi.com +ujing.online +ujintan.com +ujipin.com +ujiuye.com +ujmjk.com +ujnfdfv.com +uju365.com +ujxs.com +uk-edu.com +uk-st.com +ukanshu.com +ukeban.com +ukelink.com +uker.net +ukh5.com +ukiea.com +ukin-tech.com +ukingtech.com +uklga.work +ukluhu.com +ukongm.com +ukonline2000.com +ukoo.net +ukosgolfcart.com +ukpass.org +ukpathway.com +ukpayment.xin +ukrainevisacenter.com +uku6.com +ukubang.com +ukui.org +ukupu.com +ukusk12.com +ukve4smo9gapv.com +ukvisacenterd.com +ukworldsale.com +ulab360.com +ulamps.com +ulanzou.com +ulapia.com +ule.com +ule.hk +uleapp.com +ulecdn.com +uleek.net +ulgrobot.com +uliang.vip +uliangwang.com +uliaobao.com +ulife.com +ulife.group +ulikecam.com +ulikecam.mobi +ulikecam.net +ulikepic.com +ulikestatic.com +ulinix.com +ulinix.tv +ulinkcollege.com +ulixirglobal.com +ulpay.com +ultracachenode.com +ultraeda.com +ultramanol.com +ultrarisc.com +ultrasonice.com +ulucu.com +ulvac-shanghai.com +ulvac-suzhou.com +um.run +umajor.net +umaman.com +umasoft.com +umaszdc.com +umate.net +umb.ink +umbpay.com +umc-ai.com +umcloud.com +umdac.com +umeijiaju.com +umeng.co +umeng.com +umeng100.com +umengcloud.com +umenglog.com +umetal.com +umetrip.com +umexair.com +umfintech.com +umgg.biz +umihome.com +umindex.com +uminsky.com +umiplus.com +umiwi.com +umiwx.com +umjicanvas.com +uml-tech.com +umlchina.com +umlife.net +umpay.com +umpxkvtt.com +ums86.com +umsamd.com +umtrack0.com +umtrack1.com +umtrack2.com +umva-china.com +umvcard.com +umvsoft.com +un-bug.com +un.org +un10086.com +un1c0de.xyz +una-ad.com +una-campaign.com +unachina.org +unaming.info +unaming.net +unbank.info +uncbd.com +unccr.com +uncfa.org +uncitys.com +uncle-ad.com +uncle-chen.com +unclecheers.com +uncleda.com +uncledesk.com +unclenoway.com +unclenoway.net +unclenowayapi.com +uncletalk.com +unclicks.com +uncoverman.com +under-5.shop +underfill.cc +uneatclean.com +uneed.com +unfish.net +ungifts.com +uni-bielefeld.de +uni-cent.com +uni-forest.com +uni-perfect.com +uni-ubi.com +uni6rtmp.tulix.tv +unibeauty.net +unibizp.com +unicde.com +unicloud.com +unicloudgov.com +unicloudsrv.com +unicmicro.com +unicom-cz.com +unicomgd.com +unicomjnwy.com +unicomlife.com +unicompayment.com +unicompayment.net +unicompayment.org +unicomtest.com +unicon-hibar.com +unietec.net +unifl-networks.com +uniflows.com +unifound.net +unifull.com +unifuncs.com +unifycarbon.com +unigress.com +uniham.net +unihertz.com +unilaw.net +unilumin.com +unimasdata.com +unimtx.com +uninf.com +uning.com +uninstall-tools.com +uninto.com +uniny.com +union-4.com +union-game.com +union-net.com +union-tio2.com +union400.com +union555.com +unioncyber.net +unionpay.com +unionpay.net +unionpay95516.cc +unionpayintl.com +unionpaysecure.com +uniontech.com +uniostay.com +uniow.com +unipack-tech.com +uniproud.com +uniscope.com +unisdigital.com +unisedu.com +unisemicon.com +unisguard.com +unishy.com +unisiot.com +unisoc.com +unisonal.com +unisound.com +unispc.com +unispim.com +unissoft.com +unistc.com +unistrong.com +unistrument.com +uniswdc.com +uniswl.com +unitaxgd.com +united-bearing.com +united-imaging.com +united-sqwater.com +united-water.com +unitedbank.ltd +unitedds.com +unitedmoney.com +unitek-it.com +unitemotor.com +unitexlogistics.com +uniteyun.com +unithinker.com +unitrans-agency.com +unitrans-group.com +unitree.com +unitree.work +unittec.com +unitweld.com +unitworld.net +unitymanual.com +unityonehold.com +univ-bio.com +university-hr.com +uniview.com +univista-isg.com +univsport.com +uniwaf.com +unixhot.com +unixidc.com +unixtitan.net +unjmz.com +unjs.com +unkzyy3201.vip +unlcn.com +unlgroup.com +unlimax.com +unlimithealth.com +unmou.com +unn114.com +unncahs.net +unnnnn.com +unogenius.com +unomedicalgroup.com +unparts.net +unpcn.com +unpluggedatknight.com +unpmcc.com +unqu.com +unsedu.com +unsemi.com.tw +unshan.com +unspay.com +unsuv.com +untbbsdwarfs.com +unvmax.com +unwtonews.com +unyx.com +unzg.com +uoboc.com +uochen.com +uodzhx.com +uoeee.com +uoevtxmx.com +uoften.com +uoj.ac +uoko.com +uokon.com +uomg.com +uomo.cc +uomrcipa.com +uonglong.store +uonline-sh.com +uonline-sh.net +uono4521.com +uonone.com +uooconline.com +uoolu.com +uooss.com +uoozi.com +uoria.com +uos56.com +uostools.com +uotoo.com +uouin.com +uouo123.com +uovz.com +up-et.com +up-pharma-gx.com +up-pharma.com +up135.com +up360.com +up368.com +up37.com +up4dev.com +up62.org +up71.com +upai.com +upaidui.com +upaiyun.com +upanboot.com +upanok.com +upanshadu.com +upantool.com +upashance.com +upbiao.com +upbuilder.info +upbz.net +upc-cn.com +upcave.com +upcd.org +upcdn.net +upchina.com +upchinapro.com +upchinaproduct.com +upd.kaspersky.com +update.crashlytics.com +update.microsoft.com +update1.cyou +update2.cyou +update8.com +updeals.com +updf.com +updrv.com +upe.net +upeaoktc.com +upecp.com +upengyou.com +upengyou.net +upesn.com +upetmart.com +upfos.com +uphicoo.com +upho2015.com +uphong.com +upimgku.com +upimgt.com +upin.com +upkao.com +upkk.com +upkuajing.com +uplaypc-s-ubisoft.cdn.ubi.com +uplookedu.com +uplooking.com +upluck.cc +upnono.com +upos-bstar-mirrorakam.akamaized.net +upos-bstar1-mirrorakam.akamaized.net +upos-hz-mirrorakam.akamaized.net +upowerchain.com +uppershop.hk +upppt.com +upqzfile.com +upqzfilebk.com +uprimer.net +ups001.com +ups88.net +upsapp.com +upsclan.com +upseller.com +upskyshanghai.com +upst86.com +upsunet.com +uptom.com +uptougu.com +upu-opt.com +upupbug.com +upupoo.com +upupview.com +upupw.net +upvixusa.com +upvr.net +upwater.net +upwith.me +upx8.com +upyun.com +upzxt.com +upzxt.net +uq-express.com +uqbike.com +uqche.com +uqee.com +uqeegame.com +uqiba.com +uqidata.com +uqidong.com +uqidong.net +uqipower.com +uqite.com +uqitong.com +uqseo.com +uqualities.com +uqude.com +uqulive.com +urart.cc +urbanchina.org +urbanfind.club +urbanmatters.com +urbansocialwork.org +urbetter.com +urbetter.net +urbtix.hk +urcb.com +urcove-hotels.com +urhimalayanak.com +uril6.com +uriminzokkiri.com +urit.com +uritebio.com +uritest.com +uriwh.com +url.cy +url7.me +urlos.com +urlsecajog.com +urmuyhz.com +uroandrologyseries.com +urocancer.org +urology.wiki +urongda.com +urovo.com +urovoworld.com +urpwcei.com +urq7wvyumzfdi5.com +urs-china.com +ursb.me +urselect.com +urtrust.com +urumqi-air.com +urumqimarathon.com +urumqimtr.com +urwkcgpt.com +us-ex.com +us-qianzheng.com +us.ci +us0.me +usa-gam.com +usa-idc.com +usaapcups.com +usaas.net +usaedu.net +usaeu.com +usagoodclothes.com +usalink.xyz +usao8.com +usaphoenixnews.com +usapschool.com +usashopcn.com +usayouma.com +usbing.com +usbserver.com +usbzh.com +usbzl.com +uschinagreenfund.com +uscnk.com +uscntv.com +uscoin.gold +usdcny.net +usdtmall.com +use-tencentclb.cloud +use-tencentclb.com +use-tencentclb.net +use-tencentclb.work +use-trust.com +useasp.net +useaudio.com +usecubes.com +uselesses.com +usensejn.com +userbp.com +userhostting.com +userresearch.net +useryun.net +useso.com +ushendu.com +ushengame.com +ushinef.com +ushknews.com +ushui.com +ushui.net +usidt.com +using.club +usingwin.com +usinspirationfcg.com +usitour.com +usitrip.com +usj.cc +usjticketing.com +uslawchina.com +uslk.net +usmile.com +usniuku.com +usnook.com +usocialplus.com +usoftchina.com +usoi.net +usonetrip.com +uspard.com +usportnews.com +usqiaobao.com +usryinc.com +ustack.com +ustalk.com +ustarl.com +ustbtc.com +ustc.edu +ustcers.com +ustui.com +usuredata.com +usus.ltd +usuuu.com +usw-tencentclb.cloud +usw-tencentclb.com +usw-tencentclb.net +usw-tencentclb.work +uszcn.com +utan.com +utanbaby.com +utbon.com +utc-ic.com +utcbag.com +utchk.org +utctherapeutics.com +utec.cc +utecbj.com +utecexpress.com +utepo.com +utermux.dev +utfinancing.com +utgd.net +utiao.com +utofairy.com +utogame.com +utom.design +utoper.com +utopiafar.com +utoppromo.com +utourworld.com +utovr.com +utowekcr.com +utrainee.com +utransm.com +utrustamc.com +utsource.net +uttjhu.xyz +utuqafcr.com +utvhk.com +utvmuvpi.com +uu-baidu.com +uu-proxy.com +uu-xs.net +uu.cc +uu1.com +uu11.com +uu1314.com +uu178.com +uu375.com +uu456.com +uu66.com +uu661.com +uu6o.com +uu89.com +uu898.com +uuaa.net +uuaoz.com +uucall.com +uucc.cc +uucin.com +uucl.vip +uucnn.com +uucqrdmk.com +uueasy.com +uuedutech.com +uufund.com +uufuns.com +uugai.com +uugame.com +uugtv.com +uuhdedu.com +uuhimalayanqm.com +uuid.online +uuimg.com +uukkuu.com +uuliaoning.com +uulux.com +uumachine.com +uume.com +uumeitu.com +uumnu.com +uunice.com +uunt.com +uuoog.com +uupages.com +uupan.net +uupaotui.com +uupaper.com +uupei.com +uupoop.com +uupt.com +uupython.com +uus8.com +uusama.com +uusee.com +uusense.com +uusky.com +uusoo.net +uustory.com +uustv.com +uutils.com +uutop.com +uutrip.net +uutytp.com +uuu.ovh +uuu9.com +uuujjj.com +uuulan.com +uuumi.net +uuuo.com +uuusss.com +uuutu.com +uuvisa.com +uuvps.com +uuwldh.com +uuwtq.com +uuwx.la +uuxlink.com +uuxn.com +uuxoo.com +uuxs.info +uuxs.tw +uuyoyo.com +uuzham.com +uuzhufu.com +uuzo.net +uuzuonline.com +uuzuonline.net +uuzz.com +uuzz.net +uuzzw.com +uv25h.com +uvcdns.com +uvledtek.com +uvlv75moy8.com +uvsec.com +uvwhd.com +uw36gicu5xav.com +uw3c.com +uw9.net +uwa4d.com +uwan.com +uwaysoft.com +uwenku.com +uwn.com +uwntek.com +uworter.com +uwparking.com +ux18.com +ux87.com +uxacn.com +uxdc.net +uxdzpmz.com +uxengine.net +uxiangzu.com +uxianhu.com +uxicp.com +uxier.com +uxin.com +uxin001.com +uxingroup.com +uxiting.com +uxiu.vip +uxpi.net +uxuncloud.com +uy5.net +uya04170okq.com +uya04171okq.com +uya04180okq.com +uya04181okq.com +uya04201okq.com +uyan.cc +uyang.co +uyanip.com +uyanke.com +uycnr.com +uyesee.com +uygtbsmw.vip +uyhjnm.com +uyi2.com +uyiban.com +uyiqggpa.com +uymfybcf.shop +uyou.com +uyouii.cool +uyouqu.com +uyshipin.com +uyun-cdn.com +uyunbaby.com +uyuncdn.com +uyuncdn.net +uyunce.com +uyunche.com +uyuuy.xyz +uzai.com +uzaicdn.com +uzhika.com +uzhuangji.net +uzing.net +uzise.com +uzkqymgs.com +uzosibzk.com +uzshare.com +uzzf.com +v-56.com +v-jitp-dom.com +v-jitp-dom.net +v-jitp-glo.com +v-jitp-glo.net +v-mate.mobi +v-simtone.com +v-suan.com +v.to +v007.net +v0668tm614.com +v0719.com +v1.one-tv.com +v11-360.org +v114.com +v15cdn.com +v15i.com +v1kf.com +v1lady.com +v1pin.com +v1sj.com +v1tx.com +v1zhushou.com +v2b3.com +v2ex.cc +v2kt.com +v2vm.com +v2xdatacenter.com +v2xdatasource.com +v2xengine.com +v3.com +v3best.com +v3edu.org +v3kyo4wb8i.com +v3mh.com +v4.cc +v479.com +v5.cc +v5.com +v5.net +v50307shvkaa.art +v51124-3.qpon +v51124-3a.qpon +v51124.qpon +v5595.com +v5875.com +v5cg.com +v5dun.net +v5fox.com +v5kf.com +v5ppt.com +v5shop.com +v5tv.com +v5waf.com +v61.com +v6c.cc +v6eq34ykhek5.com +v6lvs.com +v6ok.com +v78q.com +v814.com +v84z6a854d.com +v89.com +v8a5rasf64.com +v8gb.com +v9022f162g.com +v977.com +v9b5n91.com +va-etong.com +va05ex1.org +vaakwe.com +vaatn.com +vacepcvu.com +vacmic.com +vadxq.com +vaedu.net +vaeliu.com +vafox.net +vaicdn.com +vaillant99.com +vailogchina.com +vakku.com +valiant-cn.com +valinbl.com +valinresources.com +valogin.com +valuablety.com +valuablexmail.com +value500.com +valuecome.com +valuedshow.com +valuepr.net +valueq-sea.com +valueq.com +valueur.com +valurise.com +valveshow.com +valvewbg.com +vamachina.com +van-long.com +vanbaolu.com +vanbyte.com +vance-commerce.com +vanch.net +vancheer.com +vanchip.com +vanchiptech.com +vancl.com +vanclimg.com +vancss.com +vanda.cc +vandream.com +vanform.com +vangelinu.com +vangotech.com +vanguardstars.com +vanjee.net +vanjoin.com +vankang.com +vanke-hotels.com +vanke.com +vankeclub.com.hk +vankeservice.com +vankeservice.mobi +vankeweekly.com +vankeytech.com +vanlinkon.com +vanmai.com +vanmatt.com +vanokey.com +vanqun.com +vanrui.com +vansungroup.com +vanvi-cn.com +vanvps.com +vanward.com +vanwardsmart.com +vanyee.net +vanzol.com +vaopo.com +vapepie-web.com +vapps.me +vaptcha.com +vaptcha.net +varchserverqa.com +varena.com +variflight.com +varlt.com +varmilo.com +varsalmed.com +vart.cc +varygroup.com +vasdgame.com +vasee.com +vaslco.com +vasoon.com +vastlandsc.com +vastman.com +vastsea.com +vastteq.com +vatech-china.com +vattenvalve.com +vauoo.com +vautoshow.com +vayakid.com +vaydeer.com +vayol.com +vayuan.com +vazyme.com +vazymemedical.com +vbango.com +vbaoxian-cib.com +vbbobo.com +vbc08090op.com +vbidc.com +vbio-pharma.com +vbiquge.com +vbkhk.com +vbkrhk.com +vbmnmy.com +vbsemi.com +vbyko.org +vc800.com +vcarepharmatech.com +vcbeat.net +vcc808.site +vcchar.com +vcd.io +vcdnga.com +vcg.com +vchangyi.com +vchello.com +vcimg.com +vcinchina.com +vckbase.com +vclass.com +vclbroker.com +vclbrokers.com +vcled.com +vcloud-byte.com +vcloudapi.com +vcloudgtm.com +vcloudgtm.net +vcloudlive.com +vcloudlive.net +vcloudsp.com +vcloudsp.net +vcloudstc.com +vcloudstc.net +vcloudvod.com +vcloudvod.net +vcltrade.com +vclusters.com +vcnews.com +vcomic.com +vcomputes.com +vconew.com +vconew3.com +vcooline.com +vcore.hk +vcpdemo.com +vcredit.com +vcrfiw.lol +vcsint.com +vcsmemo.com +vcspark.com +vctianshanvs.com +vctnepj.monster +vcxpe.com +vdaye.com +vdbet.com +vdfly.com +vdiagnostic.com +vdian.com +vdisk.me +vdjg65fh3ac-aw1u.com +vdlya.com +vdncache.com +vdncloud.com +vdndc.com +vdnplus.com +vdnplus.net +vdnsv.com +vdobiotech.com +vdolady.com +vdongchina.com +vdson888.com +vdyoo.com +vdyoo.net +ve-imcloud.com +ve-trafficroute.com +ve-trafficroute.net +ve70.com +vearne.cc +vebaike.com +vec-contracting.com +vecentek.com +veckinc.com +veclightyear.com +vecloudgame.com +vecrp.com +vector-engine.com +vectorplaces.com +vedamobi.com +vedcdnlb.com +vedeng.com +veding.com +vedsalb.com +veecar.com +veefdev.com +veelink.com +veeqi.net +veer.com +veervr.tv +veeteam.com +veevlink.com +veew-alb-cn1.com +veew-alb-cn2.com +veew-alb-ts.com +vefast-fa.com +veg520.com +vegalb.com +vegslb.com +vegtm.net +veicplive.com +veikei.com +veilytech.com +veinbase.com +veirun.com +veiso.vip +veitor.net +vejianzhan.com +veken.com +vekinerp.com +velasx.com +velep.com +velledq.com +velocaps.com +velouras.shop +vemarsdev.com +vemarsstatic.com +vemic.com +vemte.com +vemvm.com +vendor-src-eo.com +vendue.vip +venlvcloud.com +ventoy.net +venucia.com +venuscn.com +venusgroup.asia +venusmedtech.com +venusong.site +vephp.com +veqxiu.net +ver.cc +vergilisme.com +verify5.com +verisilicon.com +verisyno.com +versa-ai.com +versolsolar.com +versoventure.com +vertciot.com +vertical-china.com +vertu.com +vertuonline.com +very361.com +veryapex.com +veryark.com +verycd.com +verycdn.net +verychem.com +verydg.com +verydoc.net +verydu.net +verydz.com +veryevent.com +verygrass.com +verygslb.com +verygslb.net +veryhappy.pw +veryhuo.com +veryide.com +veryim.com +verykuai.com +verym.com +veryns.com +veryok.net +veryol.com +verypan.com +verysource.com +verystar.net +verysync.com +veryvp.com +veryweibo.com +verywind.com +veryxiang.com +veryzhun.com +ves100.com +vestack-beta.com +vestack-cicd.com +vestack-preview.com +vestack-sandbox.com +vestack.cloud +vesystem.com +vetoolchain.com +vetscloud.com +vevor.net +vevorstatic.com +vevsmize.com +vez.me +vf5c.com +vfcdnrd.com +vfcpay.com +vfcsz.com +vfe.cc +vfinemusic.com +vfocus.net +vftfishing.com +vfuiov.sbs +vfuke.net +vfund.org +vfvdf.com +vfx123.com +vg.com +vg173.com +vg89qeas3xagd.com +vgabc.com +vgbaike.com +vgctradeunion.com +vghall.com +vghimalayandm.com +vghimalayanet.com +vgjump.com +vglook.com +vgnclub.com +vgoapp.com +vgogbuy.com +vgooo.com +vgover.com +vgoyun.com +vgtime.com +vgunxpkt.com +vgvmotor.com +vgyuhu.com +vhall.com +vhallyun.com +vhao123.com +vhengdata.com +vhiphop.com +vhisxs.com +vhong.com +vhostcp.com +vhostgo.com +vhshub.com +vhsinsurtech.com +vhxaw.com +vhzhaopin.com +vi1zen.com +vi21.net +vi586.com +via-cert.com +viablife.com +viaeda.com +vial.cc +viarmour.com +viayoo.com +viberom.com +vibrou.com +vibunion.com +vic18.com +vicanquan.com +vicbio.com +vicchen.me +vicigaming.com +vicitymall.com +vickn.com +vicl.net +vicome.com +vicovico.com +vicp.cc +vicp.fun +vicp.io +vicp.net +vicpalm.com +vicpv.com +vicrab.com +vicsdf.com +vicsz.com +victoriassecretclearance.online +victory-inflight.com +victorybio.com +viczz.com +vida-bio.com +viday.org +videaba.com +videasoft.com +video-study.com +video-voip.com +video2b.com +videocc.net +videofty.com +videohudong.com +videohupu.com +videoincloud.com +videomind.cloud +videomind.net +videoplus.cc +videotomp3.site +videougc.com +videoxiaoyouxi.com +videoyx.com +vidmate.mobi +vidmate.net +vidmatefilm.org +vidz.asia +viecoo.com +vieg.net +vientao.com +viewcoder.com +viewstock.com +viewtool.com +viewtrans.com +vifaka.com +vigogroup.com +vigorgb.com +vigorousxy.com +vigtel.com +vigtm-meeting-tencent.com +viigee.com +viiixcpe.com +viisan.com +viitalk.com +viixin.com +vijingsmart.com +vijos.org +vijs.net +vikduo.com +vikecn.com +vikilife.com +vilives.com +villachina.com +villasbalirent.com +viltd.com +vim8.org +vimage1.com +vimage2.com +vimage3.com +vimage4.com +vimdesign.com +vimge.com +vimicro.com +vimiix.com +vimin.cc +vimiy.com +vims04.com +vimsky.com +vin114.net +vin17.com +vincentqin.tech +vinchin.com +vindapaper.com +vinehoo.com +vinetreetents.com +vingoojuice.com +vinjn.com +vinkdong.com +vinlion.com +vinsondata.com +violetabeautyltd.com +violetgo.com +violinstudy.net +violinww.com +vip-chn.com +vip-lexiang.com +vip-vip-yzzy.com +vip-wifi.com +vip.com +vip10000.club +vip120.com +vip1280.net +vip150.com +vip360.work +vip3659k.com +vip7337.com +vip7787.com +vip800.com +vip8849.com +vip888.kuyun99.com +vip9982.net +vipabc.com +vipabcyun.com +vipappsina.com +vipbaihe.com +vipbcw.com +vipbla.com +vipbuluo.com +vipcaocao.com +vipchina.com +vipcto.com +vipdlt.com +vipersaudio.com +vipexam.org +vipfashion.com +vipfengfei.com +vipfengxiao.com +vipfenxiang.com +vipfinal.com +vipflonline.com +vipglobal.hk +vipgouyouhui.com +vipgs.net +vipgslb.com +vipguanjia.net +viphxw.com +vipiao.com +vipjingdong.com +vipjinron.com +vipjr.com +vipkaoyan.net +vipkid.com +vipkidcdn.com +vipkidresource.com +vipkidstatic.com +vipkj.net +viplao.com +vipleyuan.com +vipliangmei.com +viplux.com +vipmaillist.com +vipmalljf.com +vipmro.com +vipmro.net +viponlyedu.com +viposs.com +vippapi.com +vippluspai.com +vipqdd.com +vipqlz.com +vipreading.com +vips100.com +vipshare.com +vipshop.com +vipshopyao.com +vipshou.com +vipsinaapp.com +vipskill.com +vipslib.com +vipsmt.com +vipsoft.cc +vipsrc.com +vipstatic.com +vipstore.com +viptijian.com +vipwzswl.com +vipxap.com +vipxdns.com +vipxdns.info +vipxdns.net +vipxf.com +vipxs.la +vipyl.com +vipyyzz.com +vipyz-cdn1.com +vipzhuanli.com +viqq.com +virbox.com +vircloud.net +vireala.com +vireala.net +virosin.org +virscan.org +virtaicloud.com +virtualevent.net +virtualworld.pub +virtupharmako.com +virusdefender.net +visa027.com +visa163.com +visa198.com +visa800.com +visaai.com +visabao.com +visacits.com +visactor.com +visadeguo.com +visaforchina.org +visaforkorea-bj.com +visaforkorea-cd.com +visaforkorea-gz.com +visaforkorea-qd.com +visaforkorea-sh.com +visaforkorea-wh.com +visahuanqiu.com +visajx.com +visanc.com +visas.to +visasoo.com +visaun.com +visbodyfit.com +viscosefibre.com +viseator.com +visfarm.com +vishavideo.com +visheng.com +vishoor.com +visinextek.com +vision-nj.com +vision-systems-china.com +visionandview.com +visionarytech.ltd +visionbbs.com +visionchinashow.net +visioncloudapi.com +visionhacker.com +visionly.org +visionmax-sh.com +visionstar-tech.com +visionunion.com +visionvera.com +visirobot.com +visitsanya.com +visitsz.com +viskem.com +vismaasale.shop +vismadeal.shop +vista-china.net +vista123.com +vistahelmets.com +vistastory.com +visu-autotec.com +visualchina.com +visvachina.com +vitagou.com +vitagou.hk +vitalgen.com +vitaloffice.life +vitalxyz.com +vitamio.net +vitamio.org +vitamio.tv +vitarn.com +vitasoy-chn.com +vitechliu.com +viterbi-tech.com +vitesexpo.com +vitian.vip +viu777.co +vivaia.com +vivaiaschweiz.com +vivantecorp.com +vivcms.com +vivebest.com +vividict.com +vivijk.com +viviv.com +viviwin.com +vivo.com +vivo.xyz +vivoglobal.com +vivojia.com +vivojrkj.com +vivokb.com +vivosjpt.com +vivotc.com +viwik.com +vixiu.com +vixue.com +viyuan.com +vizo-dns.com +vjgmcoqs.com +vjia.com +vjiazu.com +vjifen.com +vjread.com +vjshi.com +vjtchina.com +vk6.me +vk6oqcevmd1a.com +vk8.co +vkaijiang.com +vkbaby.com +vkehu.com +vkemai.com +vkjsq.com +vkoolhf.com +vkoopp.com +vkrqtir.xyz +vkrtzzc.com +vksir.zone +vksoft.com +vku6.com +vkua.com +vkxiazai.com +vlabstatic.com +vlabvod.com +vlan.fun +vland-official.com +vlandgroup.com +vlcable.com +vliang.com +vlight.me +vlightv.com +vlink.cc +vlinkage.com +vlinkapi.com +vlinke.com +vlion.mobi +vlong.tv +vlongbiz.com +vlportal.download.prss.microsoft.com +vlrzgf.sbs +vlss.com +vlssu.com +vlwwu.com +vm.sg +vm7.com +vm888.com +vmaes.com +vmall-hw.com +vmall.cloud +vmall.com +vmallres.com +vmanhua.com +vmartaw.com +vmax-lighting.com +vmaxhome.com +vmaya.com +vmdns.xyz +vmdo.net +vmecum.com +vmengblog.com +vmeti.com +vmic.xyz +vmicloud.com +vmkj.net +vmlib.com +vmoiver.com +vmonkey.mobi +vmovier.cc +vmoviercdn.com +vmsky.com +vmtdf.com +vmtnet.com +vmuboh.com +vmuhyu.site +vmylan.com +vname.com +vnanke.com +vnet.com +vnet.mobi +vnlin.com +vnnox.com +vnpy.com +vnvn33.com +vnzmi.com +voa-lh.akamaihd.net +voa365.com +vobao.com +voc.ai +vocalmiku.com +voccdn.com +vocinno.com +vocotype.com +vod-backup.net +vod-bk-qcloud.com +vod-content.com +vod-content.net +vod-eo.com +vod-eo1.com +vod-eo2.com +vod-eo3.com +vod-eo4.com +vod-eo5.com +vod-igtm.com +vod-pro.com +vod-qcloud.com +vod-test.com +vod-upload.com +vodapis.com +vodapisbk.com +vodasafe.com +voddlb.com +vodecn.com +vodehr.com +vodeoapi.com +vodeoapibk.com +vodeointernal.com +vodeshop.com +vodinternal.com +vodinternalbk.com +vodjk.com +vodn-valve.com +vodplayvideo.com +vodplayvideo.net +vodpro-upload.com +vodpro-upload1.com +vodpro-upload2.com +vodpro-uploadbk.com +vodtcbk.com +vodxl-qcloud.com +voguecafebeijing.com +voguechinese.com +voguelife.net +vohringer.com +voice9.com +voicedic.com +voicer.info +voicer.me +voidking.com +vojs.tv +vokop.com +volc-dns.com +volc-dns.net +volc-dns.pub +volc-embed.com +volcadocean.com +volcadvc.com +volcalb.com +volcanicengine.com +volcano-force.com +volcanospring.com +volcautovod.com +volcbiz.com +volcca.com +volccdn.com +volccdn1.com +volccdn2.com +volccloudidentity.com +volcddos.com +volcddos001.com +volcdem.com +volcdn.com +volcdns-test.com +volcdns-test.net +volcdns.com +volcdns.pub +volceapi.com +volceapplog.com +volcecr.com +volcecw.com +volcengine-dns.com +volcengine-dns.net +volcengine.com +volcengine.net +volcenginealb.com +volcengineapi.com +volcenginedns.com +volcenginedns.net +volcenginepaas.com +volces.com +volcfake.com +volcfcdn.com +volcfcdnbyte.com +volcfcdndvs.com +volcfcdndvs1.com +volcfcdndvs2.com +volcfcdnplus.com +volcfcdnrd.com +volcfcdnsc.com +volcfxgjrtm.com +volcgroup.com +volcgslb-mlt.com +volcgslb.com +volcgtm.com +volchina.com +volciad.com +volcimagex.com +volcimagex.net +volcimagextest.com +volclivedvs.com +volcmagicpage.com +volcmcdn1.com +volcmcdn2.com +volcmcdn3.com +volcmcdn4.com +volcmcdnalias.com +volcmgs.com +volcmlt.com +volcmusecdn.com +volcocic.com +volcopjrtm.com +volcpartner.com +volcpartner.net +volcsirius.com +volcsiriusbd.com +volcspaceeduc.com +volctracer.com +volctraffic.com +volctranscdn.com +volcvideo.com +volcvms.com +volcvod.com +volcwaf.com +volcwaf001.com +voldp.com +voleai.com +volic.download.prss.microsoft.com +volit.com +volkswagen-anhui.com +volleyballchina.com +volleychina.org +voltmemo.com +volvocars.com +vomicer.com +voming.com +vommatec.com +voneseals.com +vonets.com +vonng.com +vonwei.com +voo0.com +vooct.com +vooec.com +vooedit.com +voole.com +voolea.com +voolga.net +voopoo.com +voovlive.com +voovlive.net +voovmeeting.com +voovnow.com +vortexfun.com +vosvmamt.com +vot8.com +vote001.com +vote8.com +votianxia.com +voto.cc +votwo.com +voxlearning.com +voxpie.com +voycn.com +vp6.co +vpabrand.com +vpal.com +vpalstatic.com +vpansou.com +vpascare.com +vpay8.com +vpbus.com +vpcs.com +vpea.ca +vpgame.com +vpgamecdn.com +vpiaotong.com +vpimg1.com +vpimg2.com +vpimg3.com +vpimg4.com +vpkupfti.sbs +vplay8.com +vplayer.net +vpmagic.com +vpn39.com +vpnsoft.net +vpnvpn.com +vpquc9rn.com +vps-vacuum.com +vps.dance +vps.im +vps234.com +vps55.com +vps911.com +vpsaa.com +vpsaa.net +vpscang.com +vpsce.com +vpser.com +vpsguo.com +vpshu.com +vpsjxw.com +vpsno.com +vpsoff.net +vpsor.com +vpsplayer.com +vpspurchase.com +vpsss.net +vpssw.com +vpsvip.com +vpsvsvps.com +vpszh.com +vptek.com +vqaq.com +vqjuice.com +vqpwg.work +vqq.com +vqs.com +vqskrzmq.com +vqu.show +vqudo.com +vqudochina.com +vqyzdzcg.shop +vr-cat.com +vr186.com +vr2.tv +vr42.com +vrbeing.com +vrbi.viveport.com +vrbig.com +vrbrothers.com +vrbt.mobi +vrcfo.com +vrdiamondtools.com +vrindabg.com +vrjie.com +vrmajor.com +vrnew.com +vrnos.com +vrp3d.com +vrpinea.com +vrpowder.com +vrqjcs.com +vrqq.org +vrrw.net +vrtyg.com +vrupup.com +vrvlink.com +vrvmanager.com +vrwuhan.com +vrzb.com +vrzhijia.com +vrzwk.com +vrzwk.net +vs-gascloud.com +vs.cm +vs2a.com +vsaker.com +vsamhos.com +vsane.com +vsaol.com +vsbclub.com +vsbuys.com +vscode.download.prss.microsoft.com +vscops.com +vsean.net +vsearch.club +vsens.com +vshabo.com +vshangdaili.com +vsharecloud.com +vsharing.com +vshoucang.com +vsjwtcdn.com +vslai.com +vsmquvds.com +vsnoon.net +vsnoon.org +vsochina.com +vsocloud.com +vsoon.net +vsooncat.com +vsooncloud.com +vsoontech.com +vsping.com +vspk.com +vsread.com +vss.cbnmtv.com +vssou.com +vsszan.com +vstarstatic.com +vstart.net +vstecs.com +vstmv.com +vstonefund.com +vstonewealth.com +vstou.com +vsun.com +vsx10.com +vsxue.com +vsyo.com +vsyy.net +vt-pharm.com +vtache.com +vtcsy.com +vteamgroup.com +vtears.com +vtepai.com +vtepai.net +vtibet.com +vtijian.com +vtmyfbax.vip +vtool.vip +vtoshop.com +vtoutiao.cc +vtradex.com +vtrois.com +vtron.site +vtstar.net +vtuzx.com +vtydgv.org +vue-js.com +vue88.com +vuejs.press +vuepush.com +vuevideo.net +vulbox.com +vulcan.dl.playstation.net +vulrange.com +vultr1.com +vultrcn.com +vultrvps.com +vumstar.com +vunion.net +vuphub.com +vurl.fun +vurl.link +vurl.pro +vurl.tech +vurl3.vip +vutimes.com +vuxmpw.com +vuz.me +vv-tool.com +vv.cc +vv1628.cc +vv27.com +vv3111.com +vv8.com +vv881.com +vv8yx.com +vv91.com +vv91.net +vvbin.com +vvebo.vip +vvfeng.com +vvgroup.com +vvhan.com +vvhcwpddaa.com +vvhunter.com +vvic.com +vving.vip +vvipcdn.com +vviptuangou.com +vvjob.com +vvmeiju.com +vvo2o.com +vvpgwg.xyz +vvpncdn.com +vvstc.com +vvtor.com +vvup.net +vvvdj.com +vvvtt.com +vvxue.com +vvzero.com +vw888.com +vwanjia.com +vwaycn.com +vwhulian.com +vwkbh1674.com +vwo50.club +vwvvwv.com +vwwmsd.com +vx56.com +vxe.com +vxia.net +vxiaocheng.com +vxiaoxin.com +vxinyou.com +vxixi.com +vxo7tu.com +vxocok3197.vip +vxras.com +vxuepin.com +vxuey.com +vxv.ink +vxwo.com +vxxsfxxs.com +vxxx.vip +vycool.com +vycxvgmk.com +vyin.com +vynior.com +vyuan8.com +vz.download.prss.microsoft.com +vz41.com +vzan.cc +vzan.com +vzbvhfql.com +vzhang.net +vzhantong.com +vzhifu.net +vzhou.net +vzhuanba.com +vzhuji.com +vzhuo.com +vzhushou.com +vzidc.com +vzimu.net +vzklb.com +vzkoo.com +vzone.me +vztkoegc.com +vzuu.com +w-e.cc +w-startech.com +w-zhong.com +w.biz +w032.com +w03voavpa5.com +w0663.com +w0x9r0k2l1.com +w0y.com +w10a.com +w10xitong.com +w123w.com +w18.net +w1989.com +w1b.com +w218.com +w2gou.com +w2n5cu58rn.com +w2solo.com +w3.wifijiangyin.com +w333.com +w3cbus.com +w3ccoo.com +w3cfuns.com +w3chtml.com +w3cjava.com +w3cplus.com +w3cschool.cc +w3ctalk.com +w3ctech.com +w3cways.com +w3h5.com +w3pop.com +w3so.com +w3techservices.com +w3tool.com +w3tt.com +w3xue.com +w5.com +w61usi4a.org +w6pdp.com +w7.cc +w7000.com +w7ghost.net +w918.com +w9188wan.com +wa5.com +wa5as4.com +waaaat.com +waakee.com +waaku.com +waakuu.com +waasee.com +wabcw.info +wabestdealmall.com +wabuw.com +wacai.com +wacai365.com +wacaijizhang.com +wacaiyun.com +wacaoren.net +wacdn.com +wader1714.com +wadkj.com +waduanzi.com +wae-logistics.com +waerfa.com +waesedu.com +waf-website.com +waf.one +wafatea.com +wafcn.com +wafunny.com +wafzi.com +wagen.cc +wagonsclub.com +waha.cc +wahahakid.org +waheaven.com +wahlap.com +wahlap.net +wahsanggroup.com +wahtaisz.com +wahuto.com +wahyao.com +waibao123.com +waibao12333.com +waibaodashi.com +waibou.com +waifushangcheng.com +waig8.com +waigamer.com +waigf.com +waigi.org +waiguofang.com +waihui321.com +waihui580.com +waihui888.com +waihuigu.net +waihuo.com +waiji.com +wailaishop.com +wailaizhe.com +wailianluntan.com +wailiantu.com +wailianvisa.com +waima.com +waimai.com +waimai.zone +waimai101.com +waimai361.com +waimaimingtang.com +waimaiwanjia.com +waimaob2c.com +waimaoniu.com +waimaoniu.net +waimaoribao.com +waimaozhuge.com +waimungfire.com +wainconnector.com +waipojia.com +waipoxin.com +waiqicha.com +waiqin365.com +waisnj.com +waiting.monster +waitingfy.com +waitsun.com +waiwmhsb.org +waiyuedu.com +waizaowang.com +wajiquan.com +wajueji.com +wajufo.com +wakaligong.com +wakeai.tech +wakedata.com +wakeofgods.com +wakeup.fun +wakingsands.com +wakkaa.com +wakuai.com +wal8.com +walanwalan.com +walatao.com +walekan.com +wali.com +wali123.com +walibao.com +walimaker.com +walk-live.com +walker-fan.com +walkera.com +walkingpad.com +walkkind.com +walknode.com +walkthechat.com +wallcoo.com +wallcoo.net +walle-web.io +wallet.io +walletio.io +wallmatechina.com +wallstcn.com +wallstreetcn.com +wallswitch.com +walltu.com +wallyt.net +walre.com +walsongreenhouse.com +walton-xuzhou.com +waltzsy.com +waluer.com +walvax.com +wamawama.com +wamila.com +wan-ka.com +wan.cc +wan.com +wan1234.com +wan123x.com +wan32.com +wan5d.com +wan68.com +wan73.com +wan77.com +wan8.com +wan886.com +wan898.com +wan95.com +wanadalu.com +wanandroid.com +wanbaapp.com +wanbexpress.com +wanbgame.com +wanbiao800.com +wanbiaogs.com +wanbiaohao.com +wanbushu.com +wanbuyu.com +wancaiinfo.com +wancaomei.com +wanchangerp.com +wanchaohotels.com +wanche100.com +wanche168.com +wanchemi.com +wancheng168.com +wanchengwenku.com +wanchuweilai.com +wanci.cc +wancibp.com +wancili.com +wanda-cti.com +wanda-gh.com +wanda-group.com +wandacinemas.com +wandaclub.cc +wandacm.com +wandafilm.com +wandahotelinvestment.com +wandahotels.com +wandanji.cc +wandaph.com +wandaplazas.com +wandarealm.com +wandavista.com +wandawic.com +wandhao.com +wandhi.com +wanding.net +wandingwangluo.com +wandipay.com +wandodo.com +wandoer.com +wandongli.com +wandoudou.com +wandouip.com +wandoujia.com +wanduoduo.com +waneziyuan.com +wanfangche.com +wanfangdata.com +wanfangtech.com +wanfangtech.net +wanfantian.com +wanfayun.com +wanfoquan.com +wanfucc.com +wanfudaluye.com +wanfuqianqiu.com +wang-li.com +wang-nan.com +wang-russell.cc +wang1314.com +wang1314.net +wanga.me +wangaiche.com +wangamela.com +wangan.com +wanganke.com +wangbaobao.org +wangbaobei.com +wangbaoqiang-cloudcdn.com +wangbixi.com +wangcaio2o.com +wangcaiwang.com +wangcanmou.com +wangchanggou.com +wangchao.de +wangchujiang.com +wangchunsheng.com +wangcms.com +wangdafeed.com +wangdahn.com +wangdai114.com +wangdai555.com +wangdaibdt.com +wangdaicaifu.com +wangdaidongfang.com +wangdaiguancha.com +wangdaishikong.com +wangdaisj.com +wangdaitiandi.com +wangdalao.com +wangdali.net +wangdaodao.com +wangdianchaxun.com +wangdianmaster.com +wangdingchang321.xyz +wangdingcup.com +wangdongjie.com +wangdu.site +wangduanwifi.com +wangeda.com +wangeditor.com +wangejiba.com +wangfujing.com +wanggongwang.com +wanggou.com +wangguai.com +wanghaifeng.net +wanghanyue.com +wanghao.me +wanghe.tv +wanghong.zone +wanghongluo.com +wanghualang.com +wanghuinet.com +wanghz.com +wangid.com +wangjianshuo.com +wangjiezhe.com +wangjm.com +wangjubao.com +wangjumeng.xin +wangjun.art +wangjunwei.com +wangkangzhong.com +wangkewang.com +wangkl.com +wangkong.com +wangle.com +wangligroup.com +wangling.net +wanglingyue.com +wanglong.com +wanglu.info +wangluoxiangmu.com +wanglv.com +wanglv.vip +wangmei360.com +wangmeng.com +wangmingdaquan.cc +wangmou.com +wangniuwms.com +wangpeiaiot.com +wangpiao.com +wangpiao.net +wangpu.net +wangqc.com +wangqi.com +wangqingzx.com +wangren.com +wangrunze.com +wangshidi.com +wangshitou.com +wangshu.la +wangshuashua.com +wangshugu.com +wangsu.com +wangsu.net +wangsucloud.com +wangsuedge.com +wangsuedge.net +wangsutong.com +wangt.cc +wangtingrui.com +wangtongtong.com +wangtu.com +wanguan.com +wanguanwl.com +wanguo-outlets.com +wanguokang.com +wanguotong.com +wangwanglive.com +wangwango.com +wangweiluo.com +wangwo.net +wangxc.club +wangxiangyule.com +wangxianyuan.com +wangxiao.net +wangxiaobao.cc +wangxiaobao.com +wangxie.org +wangxing.com +wangxingcs.com +wangxinhao.com +wangxinlicai.com +wangyangyang.vip +wangyanpiano.com +wangye6.com +wangyeyixia.com +wangyikai.com +wangyin.com +wangyinmao.com +wangyou.com +wangyou.ink +wangyou2.com +wangyouhangkong.com +wangyuan.com +wangyuedaojia.com +wangyulue.com +wangyunchuan.com +wangyunf.com +wangyuwang.com +wangzhan123.net +wangzhan31.com +wangzhan360.com +wangzhanbao.cc +wangzhanbianji.com +wangzhanchi.com +wangzhantuiguang.net +wangzhanzj.com +wangzhe.com +wangzhengzhen.com +wangzhennan.com +wangzherongyao.com +wangzhuanz.com +wanh5.com +wanhea.com +wanhebin.com +wanheweb.com +wanhi.com +wanhongbao.com +wanhongindigo.com +wanhongji.com +wanhu888.com +wanhuabao.com +wanhuaes.com +wanhuahai.com +wanhuajing.com +wanhui365.com +wanhuicar.com +wanhuida888.com +wanhuiya.com +wanhumotor.com +wanhunet.com +wanimal1983.org +wanjia.org +wanjiacc.com +wanjiachupin.com +wanjiaiot.com +wanjiashe.com +wanjiashow.com +wanjidashi.com +wanjiedata.com +wanjiedu.com +wanjiejixie.com +wanjing111.com +wanjiquan.com +wanjunshijie.com +wanjutoy.com +wanka5.com +wankacn.com +wankacn.net +wankamall.com +wanke123.com +wanke798.com +wanku.com +wanlaiwang.com +wanli.com +wanli.org +wanlian-group.com +wanlicd.com +wanliduo.com +wanliniu.com +wanlitong.com +wanlongdianqi.com +wanlongjituan.com +wanmaco.com +wanmei.com +wanmei.net +wanmeilink.com +wanmeilr.com +wanmeiyunjiao.com +wanmi.com +wanmingpiano.com +wannaenergy.com +wannaexpresso.com +wanneng56.com +wannengxiaoge.com +wannengzj.com +wannianli.net +wannianli3.com +wannianli7.com +wannianli8.com +wannianli9.com +wannianqingjianzhan.com +wannuoda.com +wanplus.com +wanpufeiliu.com +wanqianyun.com +wanqiula.com +wanqutong.com +wanren.com +wanruihuanjing.com +wanrungj.com +wansanzu.com +wansf.com +wanshahao.com +wanshancha.com +wanshangding.com +wanshanshuju.com +wanshifu.com +wanshifuapp.com +wanshitong.com +wanshouyou.net +wanshu.com +wanshuiqing.com +wanshuiwater.com +wanshulou.com +wanshuyun.com +wansixie.com +wansongpu.com +wansusyj.com +want-want.com +wantexe.com +wantgame.net +wantiangroup.com +wantiku.com +wantong-tech.net +wantowan.com +wantquotes.net +wantuju.com +wantumusic.com +wantwords.net +wantwu.com +wantxt.cc +wanwan4399.com +wanwan88.com +wanwang.com +wanwang.space +wanwang.xin +wanweiedu.com +wanweixin.com +wanwu.com +wanwudezhi.com +wanwuelian.com +wanwumall.com +wanwusc.com +wanwushuo.com +wanwuxia.com +wanwuzhinan.com +wanxia.com +wanxiangauto.com +wanxiangleasing.com +wanxiangqihang.com +wanxiangyouxian.com +wanxiaochu.com +wanxie.cc +wanxiquan.com +wanyabox.com +wanyan.com +wanyanwang.com +wanye.cc +wanyico.com +wanyijizi.com +wanyiwang.com +wanyol.com +wanyoo.com +wanyouw.com +wanyouxi.com +wanyouxi7.com +wanyr.com +wanyuannews.com +wanyuanxiang.com +wanyuanyun.com +wanyuenet.com +wanyuhengtong.com +wanyuhudong.com +wanyujy.com +wanyumi.com +wanyunshuju.com +wanyuproperty.com +wanyuwang.com +wanyx.com +wanzaiwater.com +wanzecc.com +wanzhizr.com +wanzhoujob.com +wanzhoumls.com +wanzhoumo.com +wanzhua.com +wanzhuang.com +wanzhuangkj.com +wanzhucdn.com +wanzi.cc +wanzi.com +wanzia.com +wanzjhb.com +wanzuile.com +waodown.com +waoh.fun +waoo.cc +wapone.net +waptt.com +waptw.com +war-sky.com +waralert.net +warchina.com +warcraftchina.com +warframeofficial.com +warhammertech.com +warmchina121.com +warmjar.com +warnp.org +warom.com +warpora.asia +warriorshoes.com +warriortire.com +warsk.com +warsongmobile.com +warstudy.com +warsu.com +warting.com +waruixinxi.com +warwww.com +was-expo.com +wasabi.fun +wasair.com +wasanfeng.com +wasd.plus +wasdj.com +wasee.com +washpayer.com +washun.com +washuw.com +wasintek.com +wasoinfo.com +wasonchina.com +wasu.com +wasu.tv +wasucnc.com +watch-space.com +watch-top.net +watch1905.com +watch4s.com +watchadmin.com +watchdios.com +watchds.com +watcheschep.com +watchlead.com +watchok.net +watchreplica.co +watchreplicaswiss.com +watchrm.com +watchshfw.com +watchsos.com +watchstor.com +watchtop.com +watchtraveler.com +watchwxfw.com +watchzb.com +water-cube.com +water520.com +water8848.com +waterchina.com +waterdp.com +waterdropfilter.com +waterenping.com +watergasheat.com +watergdd.com +waterjhh.com +waterlytech.com +watermc.org +watershowcg.com +watertek.com +watertu.com +wateryx.com +watyuan.com +wauee.com +wauee.net +wave-optics.com +wavecn.com +wavecommittee.com +wavedsp.tech +wavefront-optics.com +waveopt.com +waveshare.net +waveup.work +wavezones.com +wavideo.tv +wavpub.com +wawacm.com +wawayaya.net +wawayu.tv +wawlhld.com +waxiaoxia.com +waxpi.com +waxrain.com +waxsivk.com +waxxh.me +way2solo.com +wayboosz.com +waycdn.com +wayenbio.com +wayhu.cc +wayhu8.com +waylon.online +waynetechs.com +wayos.com +wayosbill.com +wayoulegal.com +wayoumi.com +wayoxi.com +waypons.com +waysundata.com +waytit.com +waytoagi.com +wayupss.store +wayzim.com +wazhuti.com +wb133.com +wb321.com +wb521.net +wb699.com +wb86.com +wbangdan.com +wbb-electric.com +wbbcdn.com +wbcm55.com +wbd99.com +wbecrisfro.com +wbeexpo.com +wbgt.net +wbh-sh.com +wbhgwbnd.com +wbiao.co +wbiao.com +wbiao120.com +wbiaohome.com +wbimg.com +wbncp.com +wbo529.com +wboll.com +wbolt.com +wbpvc.com +wbrks.com +wbsdz.com +wbstar.com +wbsz.com +wbt5.com +wbtech.com +wbtrans.com +wbw.im +wbwbwb.net +wbxcx.net +wbxinxi.com +wbzd.net +wc44.com +wcansoft.com +wcbygame.com +wccbee.com +wcccc.cc +wccg.tech +wcd.im +wcdc.center +wcfang.com +wch-ic.com +wch17.com +wch666.com +wchfgd.com +wcjbb.com +wcjbb.net +wcjm.org +wclbox.com +wcloud.com +wcnc-lh.akamaihd.net +wcode.net +wcp.hk +wcqjyw.com +wcsapi.com +wcsapi.net +wcsfa.com +wcsteasker.com +wcuhdi.com +wcwlmobi.com +wcxjs.com +wcxsw.com +wcyecs.com +wd-ljt.com +wdace.com +wdashi.com +wdaveh5game.com +wdazgscbxh2.com +wddcn.com +wddns.net +wddream.com +wdexam.com +wdf1tz.com +wdf1tz.net +wdfangyi.com +wdfok.com +wdfxw.net +wdgf.com +wdghy.com +wdiyi.com +wdj21.com +wdjimg.com +wdjky.com +wdkao.com +wdklchina.com +wdkmall.com +wdku.net +wdkud6.com +wdldl.com +wdmagnet.com +wdmcake.com +wdmuz.com +wdmyksm.com +wdnld.com +wdomob.com +wdpharma.com +wdpower.com +wdres.com +wdsdjxh.com +wdsj2.com +wdsjz.com +wdsk.net +wdstory.com +wdsz.net +wdtec.cc +wdtuishu.com +wduw.com +wdw88.com +wdwd.com +wdwlb.com +wdxmzy.com +wdxtub.com +wdycenter.com +wdyiyuan.com +wdyserver.com +wdyxgames.com +wdyy.com +wdzj.com +wdzx.com +we-ai.work +we-pass.com +we-vmaxgroup.com +we.com +we1130.com +we123.com +we2.name +we278.com +we2marry.com +we378.com +we4399.com +we4game.com +we54.com +we556.com +we7.cc +weachat.net +weadoc.com +weakyon.com +wealink.com +weand.com +weaoo.com +weapp.com +weapp.me +weareing.store +wearemanner.com +wearesellers.com +wearosbox.com +weartrends.com +weasing.com +weather-lh.akamaihd.net +weather.com +weatherat.com +weathercn.com +weatherdt.com +weatherol.com +weavatar.com +weavi.com +weaview.com +web-rakouetnsei.net +web-tinker.com +web0518.com +web0898.net +web100.cc +web176.com +web1800.com +web2008.com +web2060.com +web20share.com +web265.net +web3.xin +web3389.com +web360.pw +web3caff.com +web3gate.cc +web3gate.io +web3ling.com +web3radio.com +web89.net +web930.com +webacc.net +webacg.com +webadminsystem66.com +webank.com +webankapp.com +webankcdn.net +webanktcftp.net +webankwealth.com +webankwealthcdn.net +webankwld.com +webankwyd.com +webarcx.com +webcamx666.com +webdns263.com +webetter-ad.com +webfalse.com +webfont.com +webfoss.com +webfreecounter.com +webfunny.com +webfuwu.com +webgame138.com +webgame163.com +webgamehome.com +webgetstore.com +webgzs.com +webhek.com +webiolotech.com +webjike.com +webjx.com +webkaka.com +webkdcdn.com +webkf.net +webkv.com +webmaster.me +webmaster5u.com +webmulu.com +webofknowledge.com +webok.me +webok.net +webond.net +webpackjs.com +webportal.cc +webportalapi.com +webpower.asia +webpowerchina.com +webqxs.com +webrtc.win +websaru.net +websbook.com +websec1.com +websec1.net +websem.cc +webseo9.com +webshao.com +webshu.net +websitecname.com +websjcdn.com +websjy.com +websky.biz +websocket-test.com +websoso.com +websztz.com +webtrncdn.com +webui.fun +webullbroker.com +webuy.ai +webuy.vip +webview.tech +webworker.tech +webxgame.com +webxin.com +webyang.net +webyounger.com +webzzcdn.com +wecanbio.com +wecare-bio.com +wecarepet.com +wecash.net +wecasting.com +wecenter.com +weceshi.com +wechat.com +wechat.design +wechat.me +wechat.org +wechat77.com +wechatapp.com +wechatapp.us +wechatauthdemo.com +wechatdevelop.com +wechatify.net +wechatlegal.com +wechatlegal.net +wechatmessenger.com +wechatmessenger.us +wechatos.net +wechatpay-global.com +wechatpay.com +wechatpay.com.hk +wechatpay.com.my +weclassroom.com +wecloud.io +wecloudx.com +wecom.work +wecomput.com +wecrm.com +wecrm.net +wecycling.com +wed2008.com +wed6.com +wedate.me +wedcm.com +weddingos.com +wedengta.com +wedev.cool +wedeveloper.com +wedfairy.com +wedn.net +wedoany.com +wedoctor.com +wedoexpress.com +wedooapp.com +wedumedical.com +weebei.com +weebia.com +weedo3d.org +weedong.com +weeet.com +weefang.com +weeiy.com +weekus.com +weelv.com +weeqoo.com +weeyun.com +wefans.com +wefinger.club +wefitos.com +weflywifi.com +wefunol.com +wegame.com +wegameapi.com +wegamedesign.com +wegamedeveloper.com +wegamemail.com +wegameplus.com +wegamex.com.hk +wegdj.com +wegene.com +wego-healthcare.com +wegooooo.com +wehandbio.com +wehefei.com +wehelpwin.com +weherepost.com +wehichina.com +wei-ben.com +wei-li.com +wei-ze.com +wei2008.com +wei6.com +wei688.com +weiaixiaoshuo.com +weianet.com +weiba66.com +weibanan.com +weibang.vip +weibangong.com +weibanzhushou.com +weibo.com +weibo.tv +weibocdn.com +weibochem.com +weibohelper.com +weiboi.com +weibolj.com +weibopay.com +weibopie.com +weiboreach.com +weibosci.com +weiboums.com +weibowang.net +weiboyi.com +weibozn.com +weibu.com +weibusi.net +weicaifu.com +weicaixun.com +weicewang.com +weichai.com +weichaipower.com +weichaishi.com +weichengchemical.com +weicher-sz.com +weichewl.com +weichuanbo.com +weichuangtech.com +weichuming.com +weico.cc +weico.com +weicogif.com +weicon.cc +weicot.com +weicunmall.com +weida888.com +weidanbai.com +weidanci.com +weidansj.com +weidaoliu.com +weidian-inc.com +weidian.cc +weidian.com +weidian.gg +weidianfans.com +weidiango.com +weidianmishu.com +weidibio.com +weidoufu.com +weidown.com +weidulinchang.com +weiduruanjian.com +weiengift.com +weifengchina.com +weifenghr.com +weifengke.com +weifengtang.com +weifenpay.com +weiforyou.net +weifrom.com +weifujd.com +weigangdairy.com +weigangqin.com +weigaogroup.com +weigaoholding.com +weigaoyaoye.com +weige2006.com +weige55.com +weighment.com +weigongju.org +weiguan.com +weiguang.cc +weiguanlaw.com +weihai.tv +weihaibsy.com +weihaicollege.com +weihaifengji.com +weihaihaiwang.com +weihaisheng.com +weihaobang.com +weihaoyi.com +weiheshidai.com +weihua-newmaterial.com +weihua2.com +weihuagroup.com +weihubao.com +weihuijob.com +weihuitel.com +weihulian.com +weihuo.site +weihz.net +weii.cc +weiixxin.com +weijia1999.com +weijiancloud.com +weijianmen.com +weijingzhijia.com +weijinsuo.com +weijiu.org +weijiuxin.com +weijizongbao.com +weijj.com +weijq.com +weiju.net +weijuju.com +weikao.com +weikaowu.com +weikasen.com +weike.fm +weike21.com +weikeimg.com +weikelink.com +weikengtech.com +weikenhair.com +weikeqi-biotech.com +weikerifu.com +weikuw.com +weilai555.com +weilaicaijing.com +weilaili.com +weilairzdb.com +weilaishidai.com +weilaitianwang.com +weilaitianwang.info +weilaitiku.com +weilaiyunxiao.com +weilaizhaiju.com +weilaizhushou.com +weilan.com +weilan27.com +weilandog.com +weilanhaian.com +weilanliuxue.com +weilanwl.com +weilayun.com +weile.com +weileapp.com +weilegetu.com +weilekuiming.com +weilenicetime.com +weileryiyt.com +weiliangsport.com +weilindct.com +weiling520.com +weilingapp.com +weilinggame.com +weilinovel.net +weilitoutiao.net +weilongshipin.com +weimaelectric.com +weimagroup.com +weimai.com +weimaitu.com +weimaqi.net +weimeigu.net +weimeiyijing.com +weimen.hu +weimi24.com +weimiaocaishang.com +weimibio.com +weimingchem.com +weimingcq.com +weimingedu.com +weimingkids.com +weimingxt.com +weimisystem.com +weimizhengxing.com +weimob.com +weimob.net +weimobapp.com +weimobcloud.com +weimobdc.com +weimobqa.com +weimobwmc.com +weimoka.com +weinan.cc +weinisongdu.com +weinm.com +weinuo.work +weiot.net +weipaitang.com +weipe.vip +weiphone.com +weiphone.net +weiphp.com +weipinchu.com +weiping.com +weipu-he.com +weipu.com +weipu.live +weipugroup.com +weipuhj.com +weiputek.com +weiq.com +weiqi.cc +weiqiaocy.com +weiqiaoyun.com +weiqidaxing.com +weiqiming.com +weiqinfang.com +weiqing120.com +weiqingbao.cc +weiqiok.com +weiqitv.com +weiquyx.com +weiren.com +weirenjob.com +weiresearch.com +weiribio.com +weiruipai.net +weisanyun.com +weisay.com +weishadian.com +weishaizi.com +weishan.cc +weishan2015.com +weishang99.net +weishangagent.com +weishangmh.com +weishangshijie.com +weishangtui.vip +weishengrc.com +weishi.com +weishi016.com +weishi024.com +weishi100.com +weishigz.com +weishipin.com +weishishuyuan.com +weisiliang.com +weismarts.com +weistang.com +weisuda.net +weisurvey.com +weisurvey.net +weisuyun.com +weisuyun.net +weisyun.com +weitehui.com +weitiewang.com +weitoupiao.com +weituibao.com +weitunit.com +weituo.com +weituobang.net +weitupian.com +weitushe.com +weituya.com +weiunity.com +weivd.com +weiwall.com +weiwangpu.com +weiwangvip.com +weiwanjia.com +weiweixiao.net +weiweiyi.com +weiwenjia.com +weiwom.com +weiwss.com +weiwuhui.com +weixianmanbu.com +weixiaoduo.com +weixiaohan.com +weixiaoi.com +weixiaoqu.com +weixiaotong.com +weixiaov.club +weiximusic.com +weixin-001.com +weixin.com +weixin12315.com +weixinbang.com +weixinbiaoqing.com +weixinbridge.com +weixincall.com +weixindadang.com +weixindevelop.com +weixingate.com +weixingmap.com +weixingon.com +weixingongzuoshi.com +weixingv.com +weixinhost.com +weixinhow.com +weixinjia.net +weixinjiajia.com +weixinju.com +weixinkd.com +weixinmvp.com +weixinpy.com +weixinqing.com +weixinqn.com +weixinqz.com +weixinrensheng.com +weixinsir.com +weixinsxy.com +weixinyidu.com +weixinyunduan.com +weixistyle.com +weixiu.name +weixiu2.com +weixiuchu.com +weixiuka.com +weixjn.com +weixue100.com +weixueyuan.net +weixun.com +weixun998.com +weixuncj.com +weixunyunduan.net +weiyan.me +weiyan000.com +weiyangx.com +weiyanjiang.com +weiyapaper.com +weiye-alu.com +weiye.me +weiyes.com +weiyi.com +weiyi.link +weiyiqibj.com +weiyitec.com +weiyituku.com +weiyituliao.com +weiyiwangluo.com +weiyoubot.com +weiyours.com +weiyouxi.com +weiyu98.com +weiyueliang.com +weiyueread.com +weiyun.com +weiyun001.com +weiyunchong.com +weiyunfushi.com +weiyunjian.com +weiyuntop.com +weiyunyingxiang.com +weizhanabc.com +weizhangjilu.com +weizhangwang.com +weizhanle.com +weizhi.com +weizhike.club +weizhipin.com +weizhishu.com +weizhivet.com +weizhiyundong.list +weizhoudaoly.com +weizhuangfu.com +weizhuanji.com +weizoom.com +weizunkj.com +weja-hospital.com +wejianzhan.com +wejias.com +wejizan.com +wejizan.ink +wejoydata.com +weka.life +wekbo.com +weknow.io +wekuo.com +welain.com +welansh.com +welaw.com +welchmat.com +welcome-lt.com +welcrm.com +weledpower.com +welefen.com +weleve.com +welfull.com +welgwiyan.com +weliads.com +welian.com +welidaimkt.com +welife001.com +welife100.com +welinkpark.com +welk.co +well-dns.com +well-js.com +well-trust.com +wellaide.com +wellav.com +wellcee.com +wellhope.net +welljoint.com +welllinkio.com +wellnj.com +wellnode.com +wellongmedical.com +wellpie.com +wellplas.com +wellreach.com +wells-shipping.com +wellselectronic.com +wellsepoxy.com +wellsoon.com +wellswam.com +welltonhotel.com +welltrend-edu.com +wellwhales.com +welove520.com +welovead.com +welqua.com +welzek.com +wemagfmp.com +wemart.com +weme.fun +wemeche.com +wemediacn.com +wemomo.com +wemorefun.com +wems.net +wemtime.com +wemvp.com +wenai.net +wenancehua.com +wenancn.com +wenandaquan.com +wenangou.com +wenanwang.com +wenanzhe.com +wenbagu.com +wenbo.cc +wenbofund.com +wenbothinktank.com +wencaischool.com +wencan.com +wenchain.com +wenda1000.com +wenda123.com +wendabaike.com +wendahu.com +wendaifu.com +wendal.net +wendangdaquan.com +wendangmao.net +wendangwang.com +wendangxiazai.com +wendax.com +wendaxiaowu.com +wendns.com +wendoc.com +wendougee.com +wendu.com +wenduedu.com +wendumao.com +wenfangcn.com +wenfangjushe.com +wenfangnet.com +wenfenggroup.com +wengbi.com +wengegroup.com +wengem.com +wengkui.com +wengmeiling.com +wenguang.com +wenguangta.com +wenguangzhineng.com +wenguo.com +wenhao123.com +wenhaofan.com +wenhetong.com +wenhua.cc +wenhuakejiao.com +wenhualvyou.net +wenhui.space +wenidc.com +wenjian.net +wenjianbaike.com +wenjiangbus.com +wenjiangs.com +wenjiasu.com +wenjingnetwork.com +wenjingzhai.com +wenjiwu.com +wenju666.com +wenjuan.cc +wenjuan.com +wenjuan.link +wenjuan.ltd +wenjuan.net +wenjuan.pub +wenjuanba.com +wenjuanbang.com +wenjuanshow.com +wenjuntech.com +wenkaoba.com +wenkeju.com +wenku.in +wenku.net +wenku365.com +wenku7.com +wenku8.cc +wenku8.com +wenku8.net +wenkub.com +wenkudao.com +wenkudaquan.com +wenkunet.com +wenkuvip.com +wenkuwenku.com +wenkuxiazai.net +wenlc.com +wenli-china.com +wenlian123.com +wenliangedu.com +wenlvnews.com +wenlvpai.com +wenmeng.com +wenmi114.com +wenmingban.com +wenneart.com +wenpie.com +wenqy.com +wenroo.com +wenrouge.com +wenryxu.com +wensang.com +wensb.org +wenshaktv.com +wenshannet.com +wenshen.net +wenshenba.com +wenshendaka.com +wenshenku.com +wenshenxiu.com +wenshuba.com +wenshubang.com +wenshushu.com +wensiluo.com +wensli.com +wenstech.com +wensuocaster.com +wentab.com +wentihu.com +wentiquan.net +wentiyi.com +wentong.com +wenwen.com +wenwo.com +wenwu8.com +wenwuchina.com +wenxiaha.com +wenxiaobai.com +wenxiaoyou.com +wenxiaozhan.com +wenxiaozhan.net +wenxin-ge.com +wenxinapp.com +wenxingonline.com +wenxiql.com +wenxiu.com +wenxuan.news +wenxue100.com +wenxue360.com +wenxueapp.com +wenxuedu.com +wenxuem.com +wenxuemm.com +wenxuesk.com +wenxuesk.info +wenxuesk.net +wenxuesk.org +wenxuetiandi.com +wenyaguan.com +wenyaqi.net +wenyi188.com +wenyijcc.com +wenyoutai.com +wenyouyun.com +wenytao.com +wenyu6.com +wenyuanenviron.com +wenyucdn.com +wenyupages.com +wenzaizhibo.com +wenzhangba.com +wenzhanghui.com +wenzheng.club +wenzhihuai.com +wenzhouchayuan.com +wenzhoumajiang.com +wenzhoushuke.com +wenzhousx.com +wenziyuan.com +weoathome.com +wepiao.com +wepie.com +wepieoa.com +weplayapp.com +weplaybubble.com +weplayer.cc +weplaymore.com +weplus.com +weproedu.com +weqoocu.com +werewolf.online +werfactory.com +werings.store +werkai.com +werlchem.com +wertalk.com +wesane.com +wescrm.com +wesdom.me +weshaketv.com +weshape3d.com +weshine.im +weshineapp.com +wesimiot.com +wesing-game.com +wesingapp.com +west-motion.com +west.xyz +west263.com +west95582.com +west999.com +westanpharma.com +westaport.com +westarcloud.com +westbund.art +westbund.com +westchinago.com +westcits.com +weste.net +westendwell.ca +westfutu.com +westinfosoft.com +westingz.com +westlake-vacuum.com +westlakedata.com +westlakegenetech.com +westlakeinst.com +westlakeomics.com +westlaw.com +westleadfund.com +westmining.com +westmininggroup.com +westmonth.com +westonecloud.com +westpac.group +westsecu.com +westsh.com +westsummitcap.com +wesure100.com +wetab.link +wetest.host +wetest.net +wetest.org +wetestlab.net +wetherm.com +weti.me +weton.net +wetools.com +wetools.pro +wetrial.com +wetruetech.com +wetry.shop +wetsd.com +wetuc.com +wetv.vip +wetvinfo.com +weui.io +weuschool.com +wevul.com +wewillpro.com +wewinpe.com +wework-pro.com +wework-studio.com +weworkcloudesk.com +wewuhu.com +wex5.com +wex7.com +wexcdn.com +wexguivq.com +wexiaocheng.com +wexin.com +wey.com +weyee.com +weyesimg.com +weyhd.com +weyic.com +weyo.me +wezeit.com +wezhan.hk +wezhan.net +wezhan.us +wezhibo.net +wezhibo.tv +wezhicms.com +wezhuiyi.com +wezonet.com +wf.pub +wf121.com +wf163.com +wf66.com +wfaozhuo.com +wfbbs.com +wfc805.com +wfcgs.com +wfdaily.com +wfdata.club +wfdj.net +wfdqzx.com +wfdsjls.com +wfdyes.com +wfeil.com +wfek.com +wff168.com +wffc120.com +wffms.com +wfhbjg.com +wfhlxy.com +wfiltericf.com +wfilterngf.com +wfits.com +wfjec.com +wfjgzs.com +wfjienuo.com +wfjimg.com +wfjsd.com +wfjtjy.com +wfkji.com +wflgjx.com +wflps.com +wflushebei.com +wfmzjscl.com +wfrcsc.com +wfsanshan.com +wfshiliyy.com +wfswjt.com +wfsydzxyy.com +wfsyzx.net +wftdrh.com +wftvqcm.com +wfuyu.com +wfwzg.xyz +wfy.pub +wfzbjx.com +wfzczdh.com +wfzqhb.com +wfzssz.com +wg-views.com +wg999.com +wgc2025.com +wgce.space +wghai.net +wghaos.com +wghostk.com +wghpdi.com +wgimg.com +wgl-group.com +wglh.com +wglm.net +wgm66.com +wgmf.com +wgmotor.com +wgnds.com +wgoic.com +wgos.com +wgppt.com +wgpsec.org +wgtechjx.com +wgxdxx.com +wgxy.com +wgxy.net +wgy.cc +wh-anhua.com +wh-aojie.com +wh-badges.com +wh-baidu.com +wh-bus.com +wh-charity.com +wh-china.com +wh-dongjiang.com +wh-haipu.com +wh-hsun.com +wh-motorshow.com +wh-mx.com +wh-swhj.com +wh-yuanhang.com +wh10000.com +wh100idc.com +wh111.com +wh119.com +wh12345szzx.com +wh50.com +wh5yy.com +wh6yy.com +wh6z.com +wh702g.ren +whabl.net +whaee.com +whafxh.org +whagcg.com +whairport.com +whale-king.com +whale-plus.com +whale123.com +whalefall.space +whaleskts.com +whalet.com +whaleunique.com +whalipaycs.com +whampoa-design.com +whatbuytoday.com +whatchina.com +whatfugui.com +whatismyip.com +whatsns.com +whatswebyuo.com +whattheybuy.com +whaudio.com +whbahyxh.com +whbaishitong.com +whbbs.com +whbc2000.com +whbcrs.com +whbear.com +whbec.com +whbester.com +whbgdt.com +whbgy.net +whbhst.com +whbj88.com +whbjdn.com +whbodywell.com +whbts.com +whbuilding.com +whbwj.com +whbws.com +whbx.org +whcaijing.net +whcat.net +whcbank.com +whcbd.net +whcbs.com +whccb.com +whcch802.com +whcdc.org +whcdwater.com +whcfjsjt.com +whcfjt.com +whcfs.org +whcgtx.com +whchem.com +whchip.com +whcibe.com +whcjfc.com +whcjfq.com +whcjkq.com +whcotton.com +whcqedu.com +whcsfzjt.com +whcst.com +whcsyc.com +whctcii.com +whctfcjt.com +whctjg.com +whctv.com +whcx.group +whcx365.com +whcyit.com +whdayy.com +whdckj.com +whdhgd.com +whdjxx.com +whdlfu.com +whdlkj.com +whdonde.com +whdqhj.com +whdrawing.com +whdsck.com +whdsyy.com +whdxhzx.com +whec-tencentclb.cloud +whec-tencentclb.com +whec-tencentclb.net +whec-tencentclb.work +whecb.com +whecloud.com +whecn.com +whedu.net +whee.com +whenchat.net +whenever-online.com +wherexpress.com +wherxian.com +whetc.com +whevt.com +whewash.com +whfamous.com +whfanyi.com +whfazun.com +whfeiyou.com +whfengli.com +whfilter.com +whfles.com +whfmg.org +whfph.com +whgas.com +whgayy.com +whgdgjt.com +whggjk.com +whggjtjs.com +whggvc.net +whggzc.com +whgh.org +whghjt.com +whgjzt.com +whgk.com +whglkf.com +whgmbwg.com +whgnjt.com +whgnyy.com +whgtgh.com +whguangguyun.com +whguanshan.com +whguo.com +whgwbn.net +whgyt.com +whhaifang.com +whhaiyue.com +whhdcz.com +whhdgk.com +whhdjzzl.com +whhdky.com +whhdmt.com +whhengchang.com +whhexin.com +whhhealth.com +whhhxy.com +whhjjt.com +whhjpharm.com +whhkbyg.com +whhkgjt.com +whhksj.com +whhmgroup.com +whhmmbl.com +whhouse.com +whhpaccp.com +whhr.com +whhryd.com +whhsg.com +whhtjg.com +whhtjt.com +whhtyl.com +whhuatian.com +whhuayou.com +whhxi.com +whhxyk.com +whhykg.com +whhysound.com +whhyyy.com +whhzhn.com +whhztcm.com +whhzyj.com +whib.com +whicec.com +whichmba.net +whicu.com +whidc.com +whidf.com +whidy.net +whiee.com +whiie-expo.com +whimsywarpgame.cc +whinfo.net +whir.net +whisperto.net +white-collar.net +white-dolphin.com +whitebox.im +whitecat.com +whitecdnx.com +whitegem.net +whitemedia-china.com +whiteswanhotels.com +whizen.com +whjaco.com +whjbh.com +whjclgs.com +whjdsjfkdfd.cfd +whjf.com +whjh120.com +whjhb.org +whjiahai.com +whjiaoy.com +whjinlong.com +whjjhbj.com +whjkcj.com +whjkct.com +whjksyxx.com +whjldj.com +whjm.com +whjrjjt.com +whjrjt.com +whjrjy.com +whjst.com +whjsxx.com +whjtjt.com +whjuren.com +whjxbaby.com +whjy.net +whjylh.com +whjyx.com +whjyxh.com +whjyxx.com +whjzxh.com +whjzxx.com +whjzy.net +whjzyxh.org +whk.hk +whkakaxi.com +whkc.com +whkcy.com +whkingdom.com +whkjdxyy.com +whkjz.com +whkqd.com +whkxzl.com +whkykj.com +whlabor.com +whland.com +whlangxing.com +whleishen.com +whlexue.com +whlgchache.com +whlib.com +whlido.com +whljyl.com +whlkwy.com +whlovehome.com +whlpa.com +whlrhd.com +whlynk.com +whmama.com +whmc2005.com +whmdedu.com +whmeigao.com +whmf8.com +whminwei.com +whmj.org +whmlcy.net +whmnls.com +whmnrc.com +whmnx.com +whmoocs.com +whmvc.net +whmxrj.com +whmylike.cc +whmylikekq.com +whmzkf.com +whnewcando.com +whnfc.com +whnyd.com +who.cx +who2o.com +whoami.akamai.net +whoiscx.com +whoisreminder.net +whoisspy.ai +whongtec.com +whoolala.com +whooyan.com +whoregamer.com +whovii.com +whpantosoft.com +whpanva.com +whpcschool.com +whphbc.com +whplmd.com +whpma.org +whptc.org +whpx.net +whqcbj.com +whqcpx.com +whqcst.com +whqianxing.com +whqjjt.com +whqtdjy.com +whqtgqbwg.com +whqunyu.com +whqwyd.com +whqyw.com +whrango.com +whrayy.com +whrazf.com +whrcbank.com +whrenai.com +whres.net +whrhkj.com +whrj.com +whrl.net +whrsip.com +whrszx.com +whrtmpay.com +whrtyycg.com +whsctgs.com +whsdhyy.com +whsdsyy.com +whsgj.com +whsgyy.com +whsir.com +whsjfs.com +whsjytyy.com +whskq.com +whsladz.com +whsladz.net +whsmzc.com +whsql.org +whsrc.com +whsthjtzjt.com +whsundata.com +whsw.net +whswcyy.com +whswx.com +whsxsy88.com +whsy.org +whsyy.net +whszniao.com +whtaxi.com +whtbglass.com +whtbgroup.com +whtbq.com +whtcm.com +whtcsz.com +whtdcb.com +whtdlx.com +whtdsc.com +whtfzy.com +whthgy.com +whtime.net +whtmhh.com +whtongyun.com +whtonhe.com +whtpgbyy.com +whtpi.com +whtpyy.com +whtpyzx.com +whtran.com +whtryg.com +whtryine.com +whtsapp-part.team +whtto.com +whttsy.com +whtuff.com +whtxcloud.com +whtzb.org +whu-cveo.com +whu.pt +whualong.com +whucopm.com +whudfr.com +whudows.com +whuh.com +whuhzzs.com +whulabs.com +whulc.com +whunitedvet.com +whuss.com +whut-px.com +whutech.com +whuznhmedj.com +whvkk.com +whvms.com +whwanshun.com +whwat.com +whwater.com +whwd.com +whwdky.com +whweb.net +whwebsite.com +whweiying.com +whweo.com +whwgcm.com +whwindplus.com +whwjnwn522.vip +whwkzc.com +whwm.net +whwm.org +whwomensmarathon.com +whwtqx.com +whwuyan.com +whwx2018.com +whwxxy.com +whwz.com +whx0621.com +whxcepc.com +whxcy.com +whxh.com +whxhdn.com +whxrjt.com +whxsdn.com +whxunw.com +whxwxzxc.com +whxy.net +whxysz.net +whybh2015.com +whycan.com +whycw.com +whyec.com +whyenjoy.com +whyesi.fun +whyestar.com +whyicheng.com +whyimingkeji.com +whyinzhimei.com +whyiqitong.com +whyky.com +whyongwei.com +whyrtc.com +whys558.com +whysb.org +whysdomain.com +whyshop.com +whysodiao.com +whysw.org +whysx.com +whysxc2c.com +whyun.com +whyuntai.com +whyunzhou.fun +whyushang.com +whyyhy.com +whyyjt.com +whyyy.com +whyzrcb.com +whzb.com +whzbdw.com +whzc2008.com +whzdyy.com +whzglc.com +whzh-cw.com +whzhanyi.com +whzhaopin.net +whzhjty.com +whzhongzhi.com +whzhtd.com +whzhzxmr.com +whzjyy.com +whzjzxy.com +whzkb.com +whzph.com +whzsrc.com +whzszy.com +whzwzk.com +whzwzs.com +whzxht.com +whzxzls.com +whzydz.com +whzys.com +whzzhb.com +wibaidu.com +wicep.com +wicp.net +wicp.vip +wicresoft.com +widgetable.net +widuu.com +wietone.com +wifenxiao.com +wifi188.com +wifi6667.com +wifi8.com +wifiapi.net +wifibanlv.com +wifichain.com +wificstia.com +wifidigyy.com +wifidog.pro +wifigx.com +wifihell.com +wifijy.com +wifilu.com +wifimsl.com +wifinew.com +wifinews.com +wifiniu.com +wifire.net +wifisdk.net +wifishenqi.com +wifivpn.net +wifiwx.com +wifizj.com +wifussion.com +wigenbio.com +wiicha.com +wiihey.com +wiihg.com +wiinkle.com +wiiteer.com +wiitrans.com +wiiun.com +wiiyi.com +wikicaring.com +wikiexpo.com +wikiimgs.com +wikimbti.com +wikipediaxx.icu +wildcardx.net +wilddog.com +wilddream.net +wildfire.work +wildfirechat.net +wildgun.net +wildhorde.com +wildto.com +wildwind.com +wildwindpharm.com +wiley.com +wilhb.com +willapps.com +willcdn.com +williameva.com +williamslullaby.com +willingchem.com +willingchina.com +willnanobio.com +willsemi.com +willsfitness.net +willwin91.com +wiloon.com +wimetro.com +wimiar.com +win-haoxiang-win.com +win-ke.com +win-man.com +win007.com +win1032.com +win1064.com +win10cjb.com +win10com.com +win10d.com +win10gw.com +win10h.com +win10net.com +win10set.com +win10w.net +win10win.com +win10world.com +win10ww.com +win10xitong.com +win10zyb.com +win3000.com +win310.com +win4000.com +win71234.com +win7china.com +win7en.com +win7qijian.com +win7qjb.com +win7xzb.com +win8.net +win866.com +win8china.com +win8e.com +win8xiazai.com +winallseed.com +winature.com +winbaoxian.com +winbjb.com +winbond-ic.com +winbons.com +winbywin.com +wincellchina.com +wincheers.com +wincheers.net +wincologistics.com +wincome.group +wincomn.com +wincoprint.net +wind.ink +wind.moe +windaka.com +windbg.download.prss.microsoft.com +windcoder.com +windesign.cc +windeyenergy.com +windfone.com +windfonts.com +windin.com +windmsn.com +windoor168.com +windows10.pro +windows10zj.com +windows11.pro +windows7en.com +windowstool.net +windowsupdate.microsoft.com +windowszj.com +windpayer.com +winds.red +windsbridge.com +windsns.com +windspeedbike.com +windtch.com +windtourgame.com +wine-world.com +wine9.com +winebar-pur.com +winegame.net +winekee.com +winemagz.com +winenice.com +wines-info.com +winesinfo.com +winesou.com +wineworld.vip +winex-hk.com +winex-sh.com +winfang.com +winfreeinfo.com +wing-cafe.com +wing-id.com +wing-max.com +wingconn.com +winglinetrans.com +winglungbank.com +wingmob.com +wingon-travel.com +wingtecher.com +winheadhunter.com +winhealth.hk +winhealthgroups.com +winhlb.com +winhong.com +winicssec.com +winjoinit.com +winkingworks.com +winkkie.com +winksi.com +winlongtech.com +winmoes.com +winndoo.com +winner-hitech.com +winner-rbt.com +winner9.com +winnerholding.com +winnermicro.com +winnerracing.com +winnerway.com +winnet.cc +winningdq.com +winos.me +winotes.net +winotmk.com +winowe.com +winpe.cc +winpex-cn.com +winpexgroup.com +winrim.com +winrobot360.com +winsalesaas.com +winsenseos.com +winshang.com +winshangdata.com +winsing.net +winspay.com +winstandard.com +winstoncc.com +winsui.com +winsun3d.com +winsurface.com +wintalent.com +wintaosaas.com +winteam500.com +wintech-nano.com +wintechchina.com +wintimechina.com +winto100.com +wintodoor.com +wintom.net +wintooo.com +wintopedu.com +wintrueholding.com +wintxt.com +winvk.com +winvod.com +winvvv.com +winwebmail.com +winwin-co.com +winwin-hotel.com +winwin7.com +winwinchemical.com +winxiang.com +winxp8.com +winxuan.com +winxuancdn.com +winyoungreading.com +winziss.com +winzonelaw.com +wio2o.com +wiot.host +wipanda.com +wipcc.org +wireless-driver.com +wireless-tag.com +wirelesschina-summit.com +wiremesh001.com +wiremeshforfilter.com +wirlesshare.com +wis-park.com +wisbiom.com +wisburg.com +wiscargo.com +wischina.org +wisder.net +wisdoing.com +wisdom-braun.com +wisdomcmmi.com +wisdomep.com +wisdompharma.com +wisdomwz.com +wisdontech.com +wisdri.com +wise-iot.com +wise99.com +wiseah.com +wiseasy.com +wisebond.net +wisecity.net +wisecotech.com +wisedoo.com +wisedsp.net +wisedu.com +wiseetec.com +wisefx.com +wisegotech.com +wiseimp.com +wisekingsurgical.com +wiselong.cc +wiselong.com +wisenjoy.com +wisentbioproductschina.com +wiseqx.com +wisestcloud.com +wiseuc.com +wisevector.com +wisewatercloud.com +wish-hightech.com +wish3d.com +wishcad.com +wishdown.com +wishisp.com +wishtec.com +wisiyilink.com +wison-engineering.com +wison.com +wispower.com +wisrc.com +wistapharma.com +wistone.com +wiswonder.com +wit-parking.com +wit0.com +witcp.com +witersen.com +with366.com +withcdn.com +withmedia.net +withoutpain.net +withpinbox.com +withqiuliang.com +withwheat.com +withwinds.com +withzz.com +witintech.com +witkeyschool.com +witmart.net +witnew.net +witontek.com +witrn.com +witspring.com +wittf.ink +wityx.com +wiwide.com +wiwide.net +wixdigital.com +wiz03.com +wizitek.com +wizsci.com +wj-chem.com +wj-hospital.com +wj-hr.com +wj-lean.com +wj-park.com +wj001.com +wj0556.com +wj166.com +wjacloud.com +wjajw.com +wjasset.com +wjbfwzx.com +wjccx.com +wjcd.net +wjceo.com +wjcjt.com +wjctg.com +wjdaily.com +wjdhcms.com +wjdiy.com +wjdiy.net +wjedu.net +wjeryuan.com +wjfcw.com +wjfilm.com +wjgdyy.com +wjgslb.com +wjhh666.com +wjhotelgroup.com +wjhouses.com +wjhr.net +wjhtxx.com +wjiaxing.com +wjin.cc +wjinmiao.com +wjjfjt.com +wjjyxxw.com +wjkjxcx.com +wjlxmedia.com +wjmh8.com +wjnin.cc +wjqcw.com +wjqwy.com +wjqyw.com +wjrcb.com +wjs.com +wjshw.com +wjsldy.com +wjsms.net +wjsw.com +wjtr.com +wjttl.com +wjtzyg.com +wjvusw.shop +wjwuqiang.com +wjx.com +wjx.top +wjy01.com +wjyanghu.com +wjyh.com +wjyt-china.org +wjyw.com +wjzp.cc +wjzpgz.com +wk2.com +wk515.com +wk78.com +wkai.cc +wkandian.com +wkbins.com +wkbrowser.com +wkcdn.com +wkcw.net +wkddkyy.com +wkdimg.com +wkdty.com +wkepu.com +wkhub.com +wkimg.com +wkkshu.com +wklken.me +wkmic.com +wknky1296.com +wkopen.com +wkread.com +wksc.com +wkshipark.com +wktfkj.com +wktline.com +wkwl9.com +wkxxw.com +wkyx520.com +wkzf.com +wkzk.com +wkzstencent.com +wkzuche.com +wl369.com +wl890.com +wlaforum.com +wlai.vip +wlaiy.com +wlanadmin.com +wlanbanlv.com +wlcbnews.com +wlcbw.com +wlcxx.com +wldbs.com +wldlr.com +wldmarket.com +wlds.net +wldsb.com +wldservice.com +wlerp.com +wlfce.com +wlfimms.com +wlgkk.com +wlgooo.com +wlgou.com +wlhcc.com +wlhyjx.com +wlhyxh.com +wlinfor.com +wljhealth.com +wljyyjy.com +wlkgo.com +wlkst.com +wlku.com +wll-xyz.com +wllxcl.com +wllxx.com +wllxy.net +wlmf.vip +wlmq.com +wlmqedu.com +wlmqhytd.com +wlmqrc.com +wlmqrsks.com +wlmqwb.com +wlmqxht.com +wlnh.net +wlnkaep.xyz +wlnmp.com +wlnnosu.xyz +wlol.com +wlphp.com +wlplove.com +wlpmmm.store +wlqtpolytheatre.com +wlrcw.com +wlsgjslgy.com +wlski.com +wlstock.com +wlsx.net +wltieyaoban.com +wltong.com +wluotx.com +wlw-jcdlcxzx.com +wlwj.com +wlwltech.com +wlwx.com +wlwx.la +wlwx.org +wlxit.com +wlxmall.com +wlxtbj.com +wlxww.com +wlyfw.com +wlyjbl.com +wlyongli.com +wlysjt.com +wlyyjt.com +wlzni.com +wlzp.com +wlzp.vip +wlzz666.com +wm-dream.vip +wm-imotor.com +wm-motor.com +wm090.com +wm18.com +wm23.com +wmathor.com +wmb2b.com +wmbluegame.com +wmc-bj.net +wmc-gba.net +wmc95588.com +wmcloud.com +wmcn.com +wmdang.com +wmfanyi.com +wmgurt9zka425.com +wmhcn.net +wmiao.com +wmidgroup.com +wmimg.com +wming.com +wmintl.com +wmiyx.com +wmjk.net +wmjrc.com +wmjt.net +wmjygg.net +wmjyqd.net +wmjyszba.com +wmksj.com +wmlip.com +wmnetwork.cc +wmok.com +wmp169.com +wmphp.com +wmpic.me +wmproxy.net +wmpvp.com +wmpyol.com +wmqt.net +wmqzyyy.com +wms100.com +wmsjyun.com +wmslz.com +wmsub.com +wmupd.com +wmvideo.com +wmviv.com +wmwm.com +wmxba.com +wmxcjj.com +wmxke.com +wmxpro.com +wmxue.com +wmxxgy.com +wmxxgz.com +wmxxwh.com +wmxxxj.com +wmy-ad.com +wmyqdmm.com +wmzhe.com +wmzkt.com +wmzp.cc +wmzyw.com +wn1998.com +wn51.com +wn789.com +wnark.com +wnbsq.com +wnchengtou.com +wncpp.net +wndoor.com +wndroid.com +wnevia.com +wnform.com +wnhuifu.com +wniec.com +wniecm.com +wnjdtz.com +wnkbyon.com +wnkj88.com +wnlbs.com +wnllx.com +wnlpromain.com +wnlproyunying.com +wnlprozhanxing.com +wnlprozijia.com +wnluo.com +wnlwedu.com +wnnyjx.com +wnote.com +wnplayer.net +wnqapp.com +wnqianbao.com +wnrb.net +wnrcw.com +wns8181.com +wns888.com +wns8888.com +wns99938.com +wnshouhu.com +wnspic.com +wnspicbk.com +wnsqzone.com +wnsqzonebk.com +wnssedu.com +wnszxyy.com +wntool.com +wntzjt.com +wnuos.com +wnwb.com +wnxfs.com +wnylyx.com +wnzc.com +wnzctc.com +wnzhbb.com +wnzy.net +wo-link.tech +wo-smart.com +wo-voyage.com +wo.cc +wo116114.com +wo186.tv +wo1wan.com +wo87.com +woa.com +woaanc.com +woaap.com +woai310.com +woaidu.org +woaihaoyouxi.com +woaihuahua.com +woaihuoshan.com +woaipu.com +woaiseo.net +woaishouban.com +woaivps.com +woaixiao.com +woaiyt.com +woaizhitu.com +woaizr.com +woaizuji.com +woaoo.net +woaoocdn.com +wobaif.com +wobangzhao.com +wobeili.com +wobocn.com +wobu2.com +woc.space +woc88.com +wocaoseo.net +wochacha.com +wochaw.com +woda.com +wodasi.com +wodavip.com +wode.bid +wode.im +wodeabc.com +wodecaipu.com +wodecrowd.com +wodecun.com +wodedagong.com +wodeev.com +wodegongzi.com +wodescw.com +wodeshebao.com +wodeshucheng.com +wodeweiquan.com +wodeyt.com +wodidashi.com +wodingche.com +wodjob.com +wodocx.com +wodown.com +wodu518.com +wodunyun.com +woeoo.com +wofang.com +wofangwang.com +wofficebox.com +wofjhs.com +wofuwater.com +wogame.net +wogaosuni.com +wogg.net +wogoo.com +wohenizaiyiqi.com +woheschool.com +wohst8.com +wohuishou.club +woi3d.com +woiauto.com +woiles.com +woiwrj.com +woiyu.com +wojiacloud.com +wojiaoni.com +wojiuhuanle.com +wok.com +wokaola.com +wokeji.com +wokende.com +wokew.com +woko.cc +wol.tv +wolai.com +wolai.ren +wolaidai.com +wolansw.com +wolegou.net +wolei-tech.com +wolezhibo.com +wolf.cc +wolfbolin.com +wolfcstech.com +wolfgo.com +wolfguandan-01.com +wolfguandan-02.com +wolfguandan-03.com +wolfguandan-04.com +wolfguandan-05.com +wolfogre.com +wolianw.com +wolidou.com +wolife.com +wolighting.com +woliuda.com +wologic.net +wolong-beng.com +wolong.com +wolonge.com +wolongge.com +wolongmedia.com +wolongyin.com +wolongyoule.com +wolunliuliangji.org +wolwo.ltd +wolwobiotech.com +wom186.com +womai.com +womaiapp.com +womailink.com +woman91.com +womanforces.com +womanfriend.com +womei.org +womeifilm.com +womeimenye.com +women-heart.com +womenjie.com +womenofchina.com +wonadea.com +wonder-link.net +wonder.wiki +wondercv.com +wonderful-pr.com +wonderfulnonwoven.com +wonderfulsz.com +wonderjk.com +wonderkun.cc +wonderscloud.com +wondersgroup.com +wondershare.cc +wondershare.com +wondershare.com.br +wondershare.jp +wondershare.net +wondersmemory.com +wonderstar027.com +wonderyouxi.com +wondko.com +wonengxing588.com +wonflavour.com +wonfulplaza.com +wongcw.com +wongpeace.com +woniu.com +woniu8.com +woniubaoxian.com +woniucloud.com +woniuge.com +woniugm.com +woniuhuoche.com +woniupai.net +woniutrip.com +wonjarobot.com +wonmay.com +wonmay.net +wonnder.com +wononme.com +wonote.com +wonpearl.com +wonplug.net +woo.im +wood-china.com +wood168.net +wood888.net +woodbridgebath.com +woodbunny.com +woodchina.com +woodnn.com +woodsbrosrental.com +woodu.me +woofee-laser.com +wooffice.net +wooide.com +woola.net +wooltex.org +wooolab.com +wooomooo.com +wooqx.com +woordee.com +woosiyuan.com +woosmart.com +woowtcprc.com +wooxhome.com +wooyun.org +woozooo.com +wopaiyi.com +wopaw.com +wopop.com +wopti.net +wopus.org +woqifoundation.com +woqu.com +woquyun.com +word666.com +wordfc.com +wordlm.com +wordplay.work +wordpress.la +wordscan.net +wordscheck.com +wordstorming.com +wordsunny.com +workbenchapi.com +workchat.com +workec.com +workehr.com +workerman.net +workhelpmanila.com +workpcb.com +worksoho.com +worktile.com +worktilemail.com +workyun.com +world-machining.com +world-pet.org +world3dmodel.com +world68.com +worldbangmai.com +worldbank.org +worldbearingshub.com +worldbuy.cc +worldcps.com +worldfcdn.com +worldgoodvoices.com +worldh5.com +worldhello.net +worldhotel.com +worldhub.market +worldinout.com +worldjiasu.com +worldmr.net +worldnyjx.com +worldpathclinic.com +worldpowerliftingchina.com +worldrobotconference.com +worlds-slotsimulator.com +worldscientific.com +worldsteel.net +worlduc.com +worldwarner.com +worldwayhk.com +worldwu.com +wort.cloud +worthgarden.com +worthtech.net +woruide.net +worxperience.com +wosai-inc.com +wosaimg.com +wosenmedia.com +woshanit.com +woshao.com +woshenghotel.com +woshi100.com +woshipm.com +woshipt.com +woshiqian.com +wosign.com +wosigndoc.com +woskj2.com +wosu.streamguys1.com +wotangka.com +wotaoka.com +wotingpingshu.com +wotokol.com +wotransfer.com +wotrus.com +wotrust.com +wotta.net +wotuan.com +wotucdn.com +wotula.com +wouju.com +wouu.net +wow.fun +wowamazingthings.com +wowbbs.com +wowcat.net +wowchina.com +wowenda.com +wowenwen.com +wowgf.com +wowo6.com +wowogroup.com +wowoit.com +wowomaifang.com +wowoohr.com +wowops.com +wowoqq.com +wowoshijie.com +wowotech.net +wowotuan.com +wowoyoo.com +wowoyou.com +wowoyou.net +wowozhe.com +wowqu.cc +wowtb.com +wowtran.com +wowza-stream.wbur.org +wowza.montevideo.com.uy +wowza.ner.gov.tw +wowzx.net +woxian.com +woxiaoyun.com +woxihuan.com +woxiu.com +woxuexue.com +woxuyuan.com +woyao998.com +woyaobaoliang.com +woyaodayin.com +woyaogexing.com +woyaojiaju.com +woyaoqiudai.com +woyaosai.com +woyaozhan.com +woying.com +woyo.com +woyonghj.com +woyoo.com +woyouche.com +woyouzhuce.com +woyun.work +wozaixiaoyuan.com +wozhangwan.com +wozhishang.com +wozhongla.com +wozhuan.com +wozhuye.com +wp-hz.com +wpan123.com +wpc.124ce.sigmacdn.net +wpceo.com +wpcio.com +wpcsh.com +wpdaxue.com +wpdian.com +wpengapp.com +wpeu.net +wpeyes.com +wpgdadatong.com +wpgdadawant.com +wpglb.com +wphonelife.com +wphun.com +wping.org +wpjam.com +wpk8.com +wporder.com +wproedu.com +wps.com +wpscdn.com +wpsdns.com +wpsep.net +wpsgo.com +wpske.com +wpsmail.net +wpsoffice.com +wpsplus.com +wpt.la +wptao.com +wptea.com +wpued.com +wpurl.cc +wpweixin.com +wpxap.com +wpyou.com +wpzhiku.com +wpzysq.com +wq96f9.com +wqbook.com +wqc.so +wqchat.com +wqcsjt.com +wqdian.com +wqdian.net +wqdsq.com +wqebl.org +wqgp.com +wqhfw.com +wqhome.com +wqhunqing.com +wqian.net +wqiis.com +wqingjian.com +wqketang.com +wqlml.com +wqlrvp3510.vip +wqoiyz.com +wqop2018.com +wqshe.com +wqstatic.com +wqszwhf.com +wqtool.com +wqxsw.com +wqxuetang.com +wqycq.com +wqyunpan.com +wqzsc36ou356m.com +wqzx.net +wr88.cc +wrcdn.com +wrdtech.com +wrfou.com +wright9.com +write-bug.com +writebp.com +writingo-editor.com +writingo.net +wrjzj.com +wrkdih.com +wrlsw.com +wrltxt.com +wrlwx.com +wrmjk.com +wrsa.net +wrshg.com +wrtauto.com +wrtnode.cc +wrtnode.com +wrtsz.com +wrxdsm.com +wsaf.net +wsandos.com +wsbedu.com +wsbkwai.com +wsbuluo.com +wscdn30.com +wscdns.com +wscdns.info +wscdns.org +wscdnss.com +wsce-expo.com +wscgdns.com +wsche.com +wscloudcdn.com +wscloudcdn.org +wsclouddns.com +wscloudsec.com +wscloudvpn.com +wsclsb.net +wscn.net +wscncdn.com +wscont1.apps.microsoft.com +wscont2.apps.microsoft.com +wscp.shop +wscrm.net +wscso.com +wscstrace.com +wscvdns.com +wsdianzi.com +wsdks.com +wsdlb.com +wsdns.top +wsdqd56.com +wsdvs.com +wsdvs.info +wsdvs.net +wsdvs.org +wsecar.com +wseen.com +wselearning.com +wselearning.net +wseqtza.com +wsf1234.com +wsfdl.com +wsfdn.com +wsfff.com +wsfgx.com +wsfnk.com +wsgeogen.com +wsgjj.com +wsgjp.com +wsglb.com +wsglb.net +wsglb0.com +wsglb0.info +wsglb0.org +wsglw.com +wsglw.net +wsgph.com +wsgri.com +wsgtm1.com +wsgtm2.com +wsgtm3.com +wshang.com +wshbzc.com +wshengda2009.com +wshenm.com +wshifen.com +wshili.com +wshost.cc +wshoto.com +wshr.com +wshtgame.com +wshttpdns.com +wsimen.com +wsipv6.com +wsisp.com +wsisp.net +wsjgd688.com +wsjtxia.com +wskam.com +wskj16818.xyz +wsks.net +wskwai.com +wslivehls.com +wsljf.xyz +wsngb.com +wsonh.com +wsoso.com +wsoss.com +wsound.cc +wsoversea.com +wsoversea.info +wsoversea.net +wsoversea.org +wsqejt.com +wsrsj.com +wsrxw.com +wss.cc +wss.email +wss.ink +wss.pet +wss.show +wss.zone +wssafe.net +wssanguo.com +wssdns.com +wsssec.com +wsstplay.com +wssvs.com +wssvs.net +wssyun.com +wsszzx.com +wstong.com +wstx.com +wsukwai.com +wsurl.cc +wswebcdn.com +wswebcdn.info +wswebcdn.org +wswebpic.com +wswebpic.info +wswebpic.org +wsxa.com +wsxc.me +wsxcme.com +wsxjzp.com +wsxsdf.com +wsy.com +wsy400.com +wsy7.com +wsyhn.com +wsysdg.com +wsyuanlin.com +wsyxmall.com +wszwhg.net +wt-tech.com +wt168.com +wt222.com +wta-web.org +wtaluo.com +wtango.com +wtardseo26x6ts8tss0-dfs1.com +wtbds.com +wtbworld.com +wtc-conference.com +wtcmirni.com +wtcxs.com +wtd56.com +wtdex.com +wtdms.com +wtecl.com +wtfeng.com +wtg7ew8cvzxbk.com +wtiharbin.com +wtimm.com +wting.info +wtkj.site +wtliker.com +wtmicrowave.com +wtmtest.com +wtn-bearing.com +wto-btb.com +wto168.net +wto9000.com +wtoip.com +wtojob.com +wtoutiao.com +wtown.com +wts999.com +wtsimg.com +wtsm.net +wtsoft.net +wtszx.com +wttai.com +wttms.com +wtuce.com +wtwvision.com +wtxcdn.com +wtxcon.com +wtzw.com +wu-mart.com +wu-mi.com +wu.run +wu123.com +wu35.com +wu37.com +wu7zhi.com +wuage.com +wuahihotel.com +wuaihanfu.com +wuaiso.com +wuaitec.com +wuan888.com +wubaiyi.com +wubaiyi.net +wubaiyi.vip +wubashangban.com +wubeizi.com +wubiba.com +wubixuexi.com +wubizi.net +wublock123.com +wubuxianjing.com +wubx.net +wuchenxu.com +wuchou.org +wuchuanghui.com +wuchucloud.com +wuchucloud.net +wuchuyun.com +wuchuyun.net +wucuoxs.com +wucuozi.com +wuczfj.com +wudaai.com +wudage.com +wudajucheng.com +wudangpai.com +wudangshan.com +wudao.com +wudao28.com +wudaotech.com +wudaotv.com +wudeli.com +wudihan.com +wudingfadian.com +wuduyi.com +wueasy.com +wufafuwu.com +wufan88.com +wufangzhai.com +wufazhuce.com +wufun.net +wufunb.com +wug4.com +wuganpark.com +wugongdong.com +wuguiyunwei.com +wuguyufen.com +wugx.net +wuhaidaily.com +wuhaijy.com +wuhan-guide.com +wuhan-tour.net +wuhan.com +wuhananyu.com +wuhanbaituo.com +wuhanbiennial.com +wuhanbus.com +wuhanchengqi.com +wuhancityofdesign.com +wuhandaishu.com +wuhanev.com +wuhanfuke120.com +wuhanfukeyy.com +wuhanghyy.com +wuhanhexin.com +wuhanins.com +wuhanjingce.com +wuhankb.com +wuhankq.com +wuhanlanqing.com +wuhanlengji.com +wuhanly.com +wuhanmarathon.org +wuhanmeigao.com +wuhanmetro.com +wuhanopen.org +wuhanparking.com +wuhanpe.com +wuhanpep.com +wuhanport.com +wuhanrt.com +wuhansanzhen.com +wuhanshiliantong.shop +wuhansport.com +wuhanta.com +wuhantianqi114.com +wuhantskj.com +wuhanunion.com +wuhanup.com +wuhanwyg.com +wuhanyushidai.com +wuhanzhenye.com +wuhao13.xin +wuhexxg.com +wuhongsheng.com +wuht.net +wuhu.cc +wuhubtv.com +wuhues.com +wuhujianshe.com +wuhukj.fun +wuhusanlian.com +wuhuwater.com +wuhuzr.com +wuhzx.com +wui5.com +wuip.com +wuji-edu.com +wuji.com +wujianghongyi.com +wujianghr.com +wujiangtong.com +wujiayi.vip +wujicode.com +wujiecaifu.com +wujiehd.com +wujiehuyu.com +wujiemed.com +wujiexiang.com +wujieyouth.com +wujiit.com +wujijiasu.com +wujinimg.com +wujinpp.com +wujintool.com +wujinwater.com +wujiok.com +wujisite.com +wujistatic.com +wujitang.com +wujixiaoshuo.com +wujixsw.info +wujogroup.com +wujue.com +wukaikai.tech +wukao.com +wukong.com +wukong.la +wukongbjb.com +wukongkf.com +wukongks.com +wukonglicai.com +wukongphp.com +wukongrom.com +wukongsearch.com +wukongshuo.com +wukongtj.com +wukongwenda.com +wukongyz.com +wukypay.com +wul.ai +wulannews.com +wuli.wiki +wuliangroup.com +wuliannanjing.com +wuliaoo.com +wuliaosi.com +wuliaozhuan.com +wuliapi.com +wulicdn.com +wulincdn.com +wulincun.com +wulinfeng8.com +wuling.com +wulingauto.com +wulingnev.com +wulingzy.com +wulinn.com +wulintang.net +wuliok.com +wuliucat.com +wuliuhangye.com +wuliujie.com +wuliuren.com +wuliuyun.com +wulong365.com +wuluoyun.com +wulvxing.com +wumai.net +wumart.com +wumii.tv +wuming.com +wupdec.com +wupk.com +wuqi-micro.com +wuqing.cc +wuqiong.info +wuqizhen.com +wuqutu.com +wurenjifanzhi.com +wurenjihangyexiehui.com +wuruihong.com +wuscn.com +wuse.com +wuse.ink +wusen.net +wuseng.net +wusetu.art +wushang.com +wushen.com +wushifublog.com +wushuangol.com +wushuangtech.com +wushuangzl.com +wushuhenan.com +wushuibao.com +wushupeixunban.com +wushuzw.com +wushuzw.org +wusong.com +wusuhan.com +wusunjiance.net +wusunk.com +wusuobuneng.com +wusuobuneng.org +wuta-cam.com +wuta.cc +wutaishanfojiao.com +wutanyuhuatan.com +wuteaclub.com +wutep.com +wuthreat.com +wutianqi.com +wutongchain.com +wutongguo.com +wutongtec.com +wutongzi.com +wutos.com +wutuojia.com +wuuconix.link +wuuxiang.com +wuwangnongseed.com +wuweijob.com +wuweiyou.com +wuwenjun.net +wuwm.streamguys1.com +wuwuju.com +wuxi5h.com +wuxi9h.com +wuxiairport.com +wuxiamt.com +wuxianhaibao.com +wuxiantu.com +wuxiatools.com +wuxiatu.com +wuxibiologics.com +wuxibus.com +wuxicxl.com +wuxidiagnostics.com +wuxihospital.com +wuxihqyy.com +wuxijf.com +wuxijia.com +wuxijiekang.com +wuximarathon.com +wuximediaglobal.com +wuximhc.com +wuxin.info +wuxin.work +wuxinban.com +wuxingmu.com +wuxingzuji.com +wuxinhua.com +wuxinmuye.com +wuxipark.com +wuxiph.com +wuxishuangfan.com +wuxishuangyou.com +wuxisj.com +wuxitianlang.com +wuxiwang.net +wuxiwanli.com +wuxiwenlv.com +wuxiworld.com +wuxixdc.com +wuxixz.com +wuxiyishi.com +wuxizazhi.com +wuxizazhi.net +wuxjob.com +wuxs.org +wuxue.cc +wuxuwang.com +wuxzx.com +wuyabuluo.com +wuyang-honda.com +wuyangkeji.com +wuyangmotor.com +wuyangplatform.com +wuyantonglun.org +wuyazi.com +wuyecao.net +wuyechaorenrcw.com +wuyenews.com +wuyetongxin.com +wuyetoutiao.com +wuyi.link +wuyida.com +wuyijt.com +wuyishan.net +wuyixinyi.com +wuylh.com +wuyongwang.com +wuyou.com +wuyou.net +wuyou189.com +wuyoudagong.com +wuyoufang.com +wuyougroup.com +wuyoujianding.com +wuyoushow.com +wuyousy.com +wuyouyun.cc +wuyouyun.com +wuys.com +wuyuan.cc +wuyublog.com +wuyueart.com +wuyueit.com +wuyuidc.com +wuyukang.com +wuyumin.com +wuyuntaxue.com +wuyutai.com +wuz7.com +wuzao.com +wuzhaiba.com +wuzhenfestival.com +wuzhenpay.com +wuzhenwic.org +wuzhenwucun.com +wuzhi.me +wuzhicms.com +wuzhii.com +wuzhiq.com +wuzhiwei.net +wuzhong.com +wuzhongdc.com +wuzhongwater.com +wuzhoucj.com +wuzhoucloud.com +wuzhoudonghui.com +wuzhouhotels.com +wuzhoumed.com +wuzhouqianzheng.com +wuzhourcw.com +wuzhouwahson.com +wuzhuiso.com +wuzi8.com +wuzx.com +wvidc.com +wvkygvmu.com +wvmrczc.com +wvshare.com +wvxkezhg.com +ww-77660.com +ww2bbs.net +ww8899.com +wware.org +wwejds.com +wwenglish.com +wwenglish.org +wwentua.com +wweuzgtp.com +wwfchina.org +wwhlian.com +wwjia.com +wwjie.com +wwk888.com +wwlcargo.com +wwldz.com +wwmhdq.com +wwnet.vip +wwrcw.net +wwsgh.com +wwsq.tv +wwstat.com +www-11187.com +www-4466666.com +www-666789.com +www-76244.com +www-csb.dell.com +www-jabuank-co-jp.net +www.adobe.com +www.cbsnews.com +www.cdnetworks.com +www.cg +www.com.my +www.dell.com +www.destinationurl.com +www.djivideos.com +www.epsonconnect.com +www.filmon.com +www.gov.mo +www.htc.com +www.microsoft.com +www.nike.com +www.pxcc.com +www.pxitv.com +www.recaptcha.net +www.redhat.com +www.samsung.com +www.soundvideostar.com +www.st.com +www.szmgiptv.com +www.tutorabc.com +www.uz0.xyz +www.vive.com +www.viveport.com +www100789.com +www11ic-shinkni-ib-jp.com +www2489.com +www4-static.gog-statics.com +www48-365365.com +www5929.com +www9912.com +wwwer.net +wwwfkw.com +wwwic.net +wwwimages.adobe.com +wwwimages2.adobe.com +wwwwqq.com +wwxrmyy.com +wwxxg.com +wx-api.net +wx-data.com +wx-jsj.com +wx-xdxc.com +wx-yn.com +wx-youyan.net +wx.com +wx135.com +wx2h.com +wx2share.com +wx4.cc +wx8g.com +wx8h.com +wx8s.com +wx920.com +wx939.com +wxagame.com +wxagyy.com +wxamedia.com +wxamkfyy.com +wxappclub.com +wxappvideo.com +wxatech.com +wxavu.com +wxaz.net +wxb.com +wxb3d.com +wxbaoming.com +wxbhagv.com +wxbiao.com +wxbjyy.com +wxbkw.com +wxblockchain.com +wxboiler.com +wxboilerchina.com +wxbrandway.com +wxbsgc.com +wxccfz.com +wxccl.net +wxcec.net +wxcha.com +wxchaoshengbo.com +wxchildren.com +wxchina.com +wxchuguan.com +wxchunleikeji.com +wxcig.com +wxcjfzjt.com +wxcloudrun.com +wxcnc.com +wxcnpa.com +wxcsgd.com +wxcts.com +wxddlfsq.com +wxdegroup.com +wxdesk.com +wxdfgc.com +wxdhnt.com +wxdianju.com +wxdtsj.com +wxdw.info +wxeditor.com +wxedu.net +wxeic.com +wxf.com +wxfhqchina.com +wxfls.net +wxfncjd.com +wxfr.net +wxfsdff.com +wxfsgj.com +wxfxw.com +wxgamemini.com +wxgamemini.work +wxgateway.com +wxggxx.com +wxgjyy.com +wxglyy.com +wxgmkt.com +wxgongkaike.com +wxgrcpa.com +wxgxjt.com +wxhaifa.com +wxhand.com +wxhbjt.com +wxhbzx.com +wxhcgbds.com +wxhdzg.com +wxhgglc.com +wxhgsrm.com +wxhkexpress.com +wxhledu.com +wxhlhg.com +wxhlzx.com +wxhon.com +wxhongqiao.com +wxhouse.com +wxhrm.com +wxhsgkjt.com +wxhstx.net +wxhtkfyy.com +wxhudong.com +wxhxyk.com +wxhyts.com +wxhyzf.com +wxiao.net +wxiaoai.com +wxiat.com +wxidg.com +wxivzhvp.com +wxjava.com +wxjcgas.com +wxjgxx.com +wxjh120.com +wxjiaogun.com +wxjieyang.com +wxjkedu.com +wxjmar.com +wxjmsyzdxx.com +wxjoi.com +wxjsgs.com +wxjshx.com +wxjsxqc.com +wxjsxy.com +wxjtyf.com +wxjx123.com +wxjzh.com +wxkj666.com +wxkjwlw.com +wxkml.com +wxkou.com +wxkpharma.com +wxlele.com +wxlight.com +wxlivecdn.com +wxlongda.com +wxlongre.com +wxlpool.com +wxlxjy.com +wxlydhb.com +wxmama.com +wxmetro.net +wxmolegames.com +wxmovie.com +wxmuseum.com +wxnacy.com +wxngh.com +wxp114.com +wxp2022.vip +wxpangu.com +wxpayui.com +wxphp.com +wxpmc.com +wxq.today +wxqcgc.com +wxqxbxg.com +wxrb.com +wxrc.com +wxrcgz.com +wxrcw.com +wxrrd.com +wxsbank.com +wxscreen.com +wxscxxx.com +wxsd.com +wxsdezyyy.com +wxsell.com +wxsemzx.com +wxsemzxyy.com +wxsgf.com +wxshake.com +wxshgs.com +wxshiteng.com +wxshops.co +wxshuku.la +wxskysy.com +wxslzf.com +wxsswgs.com +wxsteed.com +wxstztg.com +wxsywater.com +wxsyyxh.com +wxszjt.com +wxt2020.com +wxtaihujx.com +wxtcm.com +wxtcxny.com +wxtdf.com +wxthe.com +wxtj.com +wxtj10086.com +wxtpb.com +wxtrirh.com +wxtrust.com +wxtyjt.com +wxtyyy.com +wxtyzyyy.com +wxurls.com +wxuse.tech +wxutil.com +wxw120.com +wxwerp.com +wxwjk5.com +wxwmdq.com +wxworklive.com +wxwtblg.com +wxwzt.com +wxxd.co +wxxfltg.com +wxxfzx.com +wxxrh.com +wxxsh.net +wxxsjyk.com +wxxsyg.com +wxxuetao.com +wxxyxnb.com +wxy1314.com +wxyhgk.com +wxyhhosp.com +wxyljgxx.com +wxyongji.com +wxystour.com +wxyuannuo.com +wxyxrc.com +wxyzedu.net +wxzfkj.com +wxzhongcai.com +wxzpw8.com +wxzq.com +wxzwb.com +wxzxw.com +wxzzz.com +wy000.com +wy100.com +wy182000.com +wy213.net +wy2fy.com +wy34.com +wy6000.com +wya1.com +wybgs.com +wybosch.com +wybzdwss.com +wycad.com +wycfw.com +wycsyyjt.com +wydbw.com +wydljx.com +wydns.com +wyduihua.com +wyfluorine.com +wygkmitk.com +wyh138.com +wyhef.com +wyhos.fun +wyins.cc +wyins.net +wyjianzhan.com +wyjsq.com +wyk8.com +wykefu.com +wykw.com +wyl.cc +wylylxx.com +wyn88.com +wynca.com +wyndhamchangshasouth.com +wyndhamgrandxian.com +wyndhamsanya.com +wynnstools.com +wyptk.com +wypxj.com +wyrj.net +wyrlzy.com +wysaid.org +wysap.com +wysbglza.vip +wysfgc.com +wyshuoshuo.com +wysls.com +wysm88.com +wyteam.net +wytracir.com +wytx.net +wytype.com +wytzgl.com +wyuetec.com +wywy.ltd +wywy6.com +wywyx.com +wyxokokok.com +wyxzxyjhyy.com +wyydsb.xin +wyyve.com +wyzc.com +wyzg.org +wyzxsd.com +wyzyz.org +wz-cjjt.com +wz-emauto.com +wz-goodcarbide.com +wz-tea.com +wz-zhongheng-zy.com +wz-zhongheng.com +wz01.com +wz121.com +wz132.com +wz141.com +wz16.net +wz5.cc +wz5.com +wzadri.com +wzbb.com +wzbhct.com +wzbks.com +wzbox.net +wzbyjt.com +wzcbd.com +wzcfjt.com +wzcggroup.com +wzchayuan.com +wzcl.net +wzclxx.com +wzdjy.com +wzdlqj.com +wzdsb.net +wzdslyy.com +wzdyn.com +wzer.net +wzes.net +wzfg.com +wzfou.com +wzg0898.com +wzg6.com +wzgbj.com +wzgemsmall.com +wzghy.com +wzguolian.com +wzgyjt.com +wzgytz.com +wzh.kim +wzhealth.com +wzhibo.net +wzhibo.tv +wzhonghe.com +wzhosp.com +wzhouhui.com +wzhouhui.net +wzhphg.com +wzhuanzhong.com +wzhust.com +wzhxlx.com +wziii.com +wzime.com +wzits.com +wzjbbus.com +wzjcsc.com +wzjrtzjt.com +wzjsjtzcpt.com +wzjsxx.com +wzjxdyf.com +wzjxyq.com +wzkelineng.com +wzkex.com +wzkuailu.com +wzkygroup.com +wzlcgf.com +wzlgjt.com +wzlijingyuanlin.com +wzlingyun.com +wzlyqy.com +wzlysz.com +wzm.com +wzmc.net +wzmfgs.com +wzmryy.com +wzmtr.com +wznas.com +wznfgs.com +wznyfz.com +wzofjt.com +wzojk.com +wzoka.com +wzotai.com +wzpcw.com +wzpkus.com +wzplc.com +wzport.com +wzpy.com +wzqbhsls.com +wzqingou.com +wzqmt.com +wzqsyy120.com +wzrc.com +wzrc.net +wzrclt.com +wzrdwl2.com +wzright.com +wzrjsp.com +wzrm-hospital.com +wzrssip.com +wzrygcht.com +wzsee.com +wzshe.com +wzshuidian.com +wzsky.net +wzspinneret.com +wzsrmyy.com +wzssx.net +wzstsj.com +wzsxj.net +wzsz.net +wzsz.org +wztf121.com +wztianshanfs.com +wztlink1013.com +wztsy.com +wzty.ltd +wzu.com +wzwqs.com +wzwtrlyy.com +wzxchem.com +wzxclc.com +wzxianggui.com +wzxinchang.com +wzxinfeng.com +wzxmkj.com +wzxszx.net +wzxywj.com +wzy2.com +wzy6.com +wzyc.com +wzyds.com +wzyestar.com +wzyzdyf.com +wzz1809.com +wzzbdz.com +wzzbtb.com +wzzcd.com +wzzhchem.com +wzzjzxx.com +wzzlovesli.com +wzznft.com +wzzp.com +wzzpw.net +wzzqqh.com +wzzsfd.com +wzzww.com +wzzyhp.com +wzzysm.com +x-abt.com +x-bull.com +x-cloud.cc +x-cmd.com +x-droners.com +x-imagine.com +x-jishu.com +x-kicks.com +x-mol.com +x-newedu.com +x-peng.com +x-ray.work +x-storm.com +x-tetris.com +x-vsion.com +x0246.com +x0769.com +x1047xv8b4.com +x1106y.mobi +x11263.com +x11296.com +x118.net +x1abo.com +x23118.com +x23119.com +x23qb.com +x23us.us +x23wxw.com +x2552.com +x2intell.com +x315.com +x3322.net +x3366.com +x33699.com +x33yq.org +x3a37ynn2n.com +x3china.com +x3cn.com +x3g1.com +x431.com +x4dp.com +x5dj.com +x5zs.com +x64go.com +x64pro.com +x66597.com +x69zw.com +x6d.com +x6tb.com +x6x8.com +x72y.com +x7game.com +x7sy.com +x7z.cc +x81zw.co +x81zw2.com +x821.com +x86android.com +x86pi.com +x8ds.com +x8sb.com +x93r91l460.com +x9gc3siwevbpc.com +xa-bank.com +xa-online.com +xa-psj.com +xa.com +xa189.net +xa30zx.com +xa4.com +xa8yuan.com +xaaycz.com +xabaotu.com +xabbs.com +xabpo.com +xacademy.cc +xacbank.com +xacg.info +xachangda.com +xachangxing.com +xachanhe.com +xachyy.com +xacitywall.com +xaclcrm.com +xacnnic.com +xacpubfs.com +xacsjsedu.com +xactad.net +xacxxy.com +xacyyxq.com +xadamai.com +xadlwx.com +xadsa.com +xadwyy.com +xadyyy.com +xaeaa.com +xaecong.com +xaedumedia.com +xaent.com +xafc.com +xafish.com +xafzjy.com +xagdyz.com +xagkwl.com +xagmsm.com +xaguanggu.com +xagxp.com +xahc971.com +xahhp.com +xahmqy.com +xahr.net +xahttd.com +xahuapu.net +xahuayi.com +xahuilong.com +xahxgy.com +xahxp.com +xaidc.com +xainjo.com +xaixs.org +xajfwy.com +xajiason.com +xajjk.com +xajjn.com +xajjwy.com +xajob.com +xajx.com +xajxcw.com +xakaili.com +xakjgzz.com +xakqby.com +xakrlab.com +xalanq.com +xalawyer.net +xalhar.net +xalyd.com +xamama.net +xaminim.com +xamv.com +xanahotelle.com +xanhr.com +xank120.com +xanway.com +xany6.com +xaocao.com +xaoji.com +xaonline.com +xaoyao.com +xapcn.com +xapi.ltd +xaqhgas.com +xarc.net +xarlm.com +xarongdi.com +xarptec.com +xarqba352.vip +xarxbio.com +xaseastar.com +xasfyw.com +xasgxy.com +xashl.com +xashuiwu.com +xashzhjz.com +xasimonds.com +xasrc.com +xasrite.com +xasun.com +xaswx.com +xasyx.com +xatc168.com +xatielu.com +xatourismgroup.com +xatvs.com +xatyds.com +xatyz.com +xatzj.com +xauat-hqc.com +xaudiopro.com +xauwvhgt.com +xavierbrooks.shop +xawb.com +xawdcy.com +xawdslzp.com +xawdz.com +xaweather.com +xawscu.com +xawyjx.com +xaxcgx.com +xaxddz.com +xaxydr.com +xaxzlsgs.com +xayabx.com +xayestar.com +xaygddc.com +xayhedu.com +xayizhou.com +xayzjc.com +xazbts.com +xazcit.com +xazls.com +xazmkm.com +xazwy.com +xazysoft.net +xazyy.com +xazzs.com +xb.app +xb0.cc +xb2s.com +xba123.com +xbaixing.com +xbaodi.com +xbaofun.com +xbase.cloud +xbase.xyz +xbatu.com +xbauto.com +xbb8.com +xbbaoan.com +xbceo.com +xbcjy.com +xbcloudprint.com +xbcpsjk.com +xbd61.com +xbdgps.com +xbds.cc +xbdym.com +xbec-tencentclb.cloud +xbec-tencentclb.com +xbec-tencentclb.net +xbec-tencentclb.work +xbeian.com +xbequge.com +xbeta.info +xbext.com +xbfashion.com +xbfnet.com +xbfzb.com +xbgjw.com +xbhb.net +xbhjgg.com +xbhy.com +xbiao.com +xbidc.com +xbiqiku.net +xbiqiku2.com +xbiquge.la +xbiqugu.info +xbiqugu.net +xbiquke.com +xbiquwx.la +xbiquzw.com +xbirder.com +xbitw.net +xbjianzhan.com +xbjob.com +xbjtkj.com +xbk.icu +xbkjvip.com +xblaw.com +xblou.com +xblqb.com +xblqugex.cc +xblsign.com +xblyw.com +xbmbw.com +xbmiaomu.com +xbniao.com +xbnj.net +xbongbong.com +xboot.org +xboxfan.com +xbpex.com +xbptc.com +xbrl-cn.org +xbrother.com +xbtest.com +xbuwrp.sbs +xbuyees.com +xbw0.com +xbwbh.com +xbwebyun.com +xbxgame.com +xbxxb.com +xbxxz.com +xbzlapp.com +xc-fc.com +xc-fund.com +xc-js.com +xc05x.com +xc1000.com +xc2500.com +xca551hgxm.com +xcabc.com +xcao.win +xcape.cc +xcar.com +xcarimg.com +xcb-family.com +xcbank.com +xcbbtf.com +xcc.com +xccrugs.com +xccy.cc +xcdesign.net +xcdn.global +xcdngyc.vip +xcdntp.vip +xcdssy.com +xcedu.net +xcex.net +xcfuer.com +xcfunds.com +xcgbb.com +xcgbie.com +xcgogo.club +xcgogo.site +xcgp.com +xcgui.com +xcgwk.com +xcgyy175.org +xcharger.net +xchjw.org +xchr-group.com +xchsgy.com +xchuxing.com +xciic.com +xcj.com +xcjd.net +xcjincheng.com +xcjmcnc.com +xcjtjt.com +xcjyxx.com +xckfsq.com +xckgq.com +xckpjs.com +xckssw.com +xckszx.com +xclawyers.org +xcljs.com +xcloudbase.com +xcmad.com +xcmg-dkrob.com +xcmg.com +xcmgmall.com +xcmobi.com +xcmsports.com +xcmwqdvc.com +xcnchinese.com +xcncp.com +xcnv.com +xcode.me +xcoder.in +xcommon.com +xcoodir.com +xcot.com +xcpapa.site +xcpapa.xyz +xcpxssx.com +xcq2022.com +xcq518.com +xcqpayy.com +xcqxcq.com +xcrc.net +xcrmyy.com +xcsc.com +xcshaifen.com +xcstuido.com +xcsyy.com +xctmr.com +xcukezmr.com +xcurrency.com +xcvec.com +xcvmbyte.com +xcvvs.com +xcwhjj.com +xcx-x.com +xcxd-inc.com +xcxd1997.com +xcxjpd.com +xcxvs.com +xcxwo.com +xcxymw.com +xcxyw.com +xcxzks.com +xcxzww.com +xcyg.net +xczhmzb.com +xczhsh.com +xczim.com +xczzs.com +xd-tech.com +xd-world.com +xd.com +xd0.co +xd0.com +xd0731.com +xd56b.com +xd57.com +xd8888.net +xda.show +xdapp.com +xdbcb8.com +xdbin.com +xdc.at +xdcdn.com +xdcdn.net +xdcg100.com +xddpay.com +xde.com +xdebike.com +xdf99.com +xdfckjz.com +xdfpr.com +xdfsjj.com +xdgalaxy.com +xdggd.com +xdgj.com +xdgkwl.com +xdglt.com +xdgogogo.com +xdhcn.com +xdhelp.com +xdhyty.com +xdiarys.com +xdingerp.com +xdiscuz.com +xdj-sz.com +xdja.com +xdjcgs.com +xdju.com +xdjunxiao.com +xdjy369.com +xdkb.net +xdkjjy.com +xdkjpx.com +xdmb.xyz +xdmssp.com +xdn001.com +xdn10000.com +xdn2.com +xdnice.com +xdnote.com +xdnphb.com +xdnsvip.com +xdnsvip.info +xdocin.com +xdowns.com +xdpaomo.com +xdper.com +xdpipe.com +xdpjump.com +xdplt.com +xdpvp.com +xdqtech.com +xdrcftv.com +xdressy.com +xdrqsb.com +xdrtc.com +xdrun.com +xdsipo.com +xdsp.mobi +xdsyzzs.com +xdter.com +xdtev.com +xdtool.com +xdtos.com +xduim.com +xdundq.work +xduoo.com +xduoyu.com +xduph.com +xdwan.com +xdweilai.com +xdwyx.com +xdxct.com +xdxdsz.com +xdxialingying.com +xdxiaoshuo.com +xdxmsy.com +xdxmwang.com +xdyanbao.com +xdystar.com +xdytuliao.com +xdyy.net +xdyy100.com +xdyyws.com +xdzhsw.com +xdzu.net +xed.plus +xedaojia.com +xedaojia.net +xedge.cc +xeeee.net +xeeger.com +xeeok.com +xefan.com +xege.org +xegymyb.xyz +xehedu.com +xeknow.com +xeltek-cn.com +xen0n.name +xender.com +xenium.mobi +xepher.fun +xesabc.com +xesapp.com +xescdn.com +xesdns.com +xesee.com +xesimg.com +xesv5.com +xet.tech +xetimes.com +xetlk.com +xetslk.com +xev-connectivity.com +xevd.co +xevddy.com +xeylon.com +xf-fund.com +xf-gtm.com +xf-world.org +xf-yun.com +xf.com +xf0797.com +xf119.xin +xf1233.com +xf21.com +xf24ms.com +xf3z.com +xf4hs.com +xf5z.com +xfabs.com +xfadx.com +xfannix.com +xfaqwlw.com +xfb315.com +xfbst.com +xfcjn.com +xfcn.com +xfconnect.com +xfcqc.com +xfdown.com +xfdp.net +xfdwz.com +xfdyb.com +xfehc.com +xfeng.me +xffbb.com +xffox.com +xfguo.org +xfhx.com +xfinfr.com +xfisp.com +xfj100.com +xfjcw.com +xfjw.net +xfjxs.com +xflapp.com +xflimg.com +xfliusheng.com +xflstatic.com +xfltd.net +xfmspps.com +xfnano.com +xfocus.net +xfocus.org +xforceplus.com +xfpaas.com +xfpass.com +xfpg119.com +xfplay.com +xfprecise.com +xfr3u4lz94.com +xframework.org +xft123.com +xftclub.com +xftransa.com +xfun233.com +xfusion.com +xfwed.com +xfwindow.com +xfx02.com +xfx168.com +xfxb.net +xfxglass.com +xfyousheng.com +xfypaper.com +xfyun.com +xfzc.com +xfzhsf.com +xfzllht.com +xg-techgroup.com +xg1234.com +xg38.com +xgamecenter.com +xgamevip.com +xgantt.net +xgate.com +xgc002.com +xgc004.com +xgc09.com +xgccm.com +xgcp.asia +xgcs55.com +xgcsczyc.com +xgcsfz.com +xgd.com +xgd666.com +xgdfz.com +xgdown.com +xgdq.com +xgdqsn.com +xggj56.com +xggjj.com +xghylt.com +xgimi.com +xgimi.net +xgiu.com +xgj-info.com +xgjdyjjt.com +xgjgas.com +xgjjw.com +xgkwx.com +xglgift.com +xglist.com +xgllreport.com +xglopto.com +xglpa.com +xgn-cy.com +xgo.cc +xgost.com +xgp365.com +xgpharma.com +xgqq.com +xgqyy.com +xgsdk.com +xgsdpm.com +xgss.net +xgsxt.net +xgsyun.com +xgt2014.com +xgtea.com +xgwx.net +xgxedu.com +xgxsignage.com +xgyszj.com +xgz.cc +xgzbwdj.com +xgzdhj.com +xgzrs.com +xh-arch.com +xh-health.com +xh-silicone.com +xh.com +xh0523.com +xh1958.com +xh39.com +xhaiwai.com +xhante.com +xhay1122.com +xhbaoguan.net +xhboke.com +xhbosn.com +xhby.net +xhbycm.net +xhcct.com +xhclaw.com +xhclub.net +xhcpa.net +xhcpas.com +xhcs.com +xhctcm.com +xhd.org +xhdjx.com +xhdnwct.com +xhdpay.com +xhdxly.com +xhedu.net +xhfk120.net +xhforex.com +xhg.com +xhgame.com +xhgamesdk.com +xhgjyc.com +xhgz.com +xhh.pw +xhhd6.com +xhhdd.cc +xhhhzs.com +xhhos.com +xhidc.com +xhily.com +xhintech.com +xhj.com +xhj.info +xhjaty.com +xhjianglong.com +xhjingling.com +xhjj.com +xhjkgj.com +xhjnyy.com +xhjs168.com +xhjt.com +xhjyxxw.com +xhkt.tv +xhlaowu.com +xhlcsl.com +xhlld002.shop +xhlsgs.com +xhma.com +xhmedia.com +xhmwxy.com +xhnews.net +xhostfire.com +xhostserver.com +xhpfw.com +xhpiano.com +xhpr.net +xhqbapp.com +xhqqt.com +xhrczp.com +xhs.com +xhscdn.com +xhscdn.net +xhsd.com +xhsd.net +xhsea.com +xhsf.com +xhslink.com +xhslw.com +xhsmlt.com +xhsrmyy.com +xhsxmt.com +xhsyqx.com +xhsyww.com +xhtheme.com +xhtw.com +xhtwb.com +xhtxgroup.com +xhu2.com +xhu218.com +xhuaian.com +xhup.club +xhw520.com +xhw81pr263.com +xhwater.com +xhwcdasha.com +xhwhouse.com +xhwtech.com +xhwx100.com +xhwyzsd.com +xhxcedu.com +xhxgt.com +xhxhr.com +xhxsw.com +xhy.com +xhyd.com +xhygroup.com +xhyksha.xyz +xhylbfyy.com +xhyljt.com +xhysh.com +xhytd.com +xhyun.vip +xhzysg.com +xi-9.com +xi-soft.com +xi.biz +xi.su +xi5jie.com +xia1ge.com +xiaa.net +xiabingbao.com +xiabor.com +xiabu.com +xiacaopu.net +xiache.net +xiachufang.com +xiada.net +xiadaolieche.com +xiadele.com +xiaditu.com +xiadts.com +xiadu.com +xiafenfa.com +xiagaoqing.com +xiagepian.com +xiageyy.com +xiaguanzhan.com +xiagujian.com +xiaheng.net +xiaiot.com +xiajuan88.com +xiakefyz.com +xiakeol.com +xialingying.cc +xialv.com +xiamag.com +xiamai.net +xiame.com +xiamen888.com +xiamenair.com +xiamenbg.com +xiamenfojiao.com +xiamenhuandongmarathon.com +xiamenjiyang.com +xiamentianqi114.com +xiamenwater.com +xiami.com +xiami.fm +xiami.net +xiamo.fun +xiamoyun.com +xiamp4.com +xian-feng.com +xian-tourism.com +xian-yao.com +xian.com +xianayi.net +xianbao.fun +xianbao.net +xianbao5.com +xianbdj.com +xianbeikeji.com +xianbey.com +xiancaotang.com +xianchengyou.com +xiancn.com +xiandaihospital.com +xiandaimuye.com +xiandaiyuwen.com +xiandanjia.com +xiandengdengguan.com +xiandp.com +xianer.net +xianfae.com +xianfan2022.com +xianfengjiayuan.com +xianfengsg.com +xianfengyiyao.com +xiang.com +xiang.xin +xiang5.com +xiang578.com +xiangange.com +xianganquan.com +xianganyu.com +xiangauto.com +xiangbababus.com +xiangbala.net +xiangbinmeigui.com +xiangbojiubo.com +xiangbosoft.com +xiangcoin.com +xiangcun.cc +xiangcun.com +xiangcunxiaoshuo.com +xiangdian.com +xiangdian.store +xiangguo.com +xiangguohe.com +xiangha.com +xianghuanji.com +xianghumarathon.com +xianghunet.com +xianghus.com +xiangjiamuye.com +xiangjiang-amc.com +xiangjiasz.com +xiangjiayaoyehz.com +xiangkanwang.com +xiangkesi.com +xiangley.com +xianglifood.com +xiangliuzi.com +xianglongpharm.com +xianglute.com +xiangmaita.com +xiangming.site +xiangmu.com +xiangni.com +xiangniya.com +xiangoo.com +xiangpeach.com +xiangpi.com +xiangpu24fa.com +xiangqiai.com +xiangqianpos.com +xiangqigame.com +xiangqin7.com +xiangqishan.com +xiangqiyouxi.com +xiangqu.com +xiangrikui.com +xiangrikuijianzhan.com +xiangrikuisite.com +xiangruichina.com +xiangruizulin.com +xiangshang360.com +xiangshangban.com +xiangshanpark.com +xiangshe.com +xiangshengbao.com +xiangshengnet.com +xiangshi.cc +xiangshi.video +xiangshitan.com +xiangshuheika.com +xiangshunjy.com +xiangsidi.com +xiangsw.com +xiangtaiyun.com +xiangtaole.com +xiangtatech.com +xiangtuan.xyz +xiangtx.com +xianguo.com +xianguomall.com +xianguotea.com +xiangw.com +xiangwushuo.com +xiangxiangmf.com +xiangxihe.com +xiangxinggroup.com +xiangxingnet.com +xiangyang-marathon.com +xiangyang.net +xiangyangwater.com +xiangyi.co +xiangyiai.com +xiangyilxj.com +xiangyu-group.com +xiangyue.life +xiangyueedu.com +xiangyueliangyuan.com +xiangyuezhongxue.com +xiangyujiankang.com +xiangyuncdn.com +xiangyungx.com +xiangyuyaoye.com +xiangzhan.com +xiangzhiren.com +xiangzhuyuan.com +xiangzi.ltd +xiangzi.tech +xiangzuanjiang.com +xiangzukeji.com +xianjian.com +xianjian10.com +xianjiaosuo.com +xianjichina.com +xianjiqun.com +xianjzyxh.org +xiankabao.com +xiankan.com +xianlai.work +xianlaicd.com +xianlaigame.com +xianlaihy.com +xianlaivip.com +xianlan315.com +xianlife.com +xianliming.com +xianmaiyangsheng.com +xianmeilai.com +xianmeisc.com +xianningmarathon.com +xianniu.com +xianniu.net +xianniuzu.com +xiannvhu.com +xianousiqi.com +xianpinyun.com +xianpp.com +xianrail.com +xianrenzhang.net +xianshiqiba.com +xianshishangmao.com +xianshu.com +xianshua.net +xianshuabao.com +xianshufang.com +xiansimo.com +xiansuan.com +xiantao-marathon.com +xiantao.com +xianweizhang.com +xianxiadao.com +xianxiadao.net +xianxiazhuanjz.com +xianxueba.com +xianyang888.com +xianyer.com +xianyongyong.com +xianyouhe.com +xianyu.mobi +xianyuange.com +xianyudanji.net +xianyugame.com +xianyugouwu.com +xianyuso.com +xianyuvr.com +xianyuwang.com +xianyuyouxi.com +xianzhanget.com +xianzhi.net +xianzhid.com +xianzhongwang.com +xianzidaer.com +xianzilaishui.com +xiao-an.com +xiao-bo.com +xiao-new.com +xiao100.com +xiao2she.com +xiao688.com +xiao84.com +xiaoa.name +xiaoac.com +xiaoaiassist.com +xiaoaiscan.net +xiaoaisound.com +xiaoantech.com +xiaoantech.net +xiaoao.com +xiaoapp.io +xiaoba001.com +xiaobai.com +xiaobaibar.net +xiaobaipan.com +xiaobaishiji.com +xiaobaishixi.com +xiaobaitool.net +xiaobaiupin.com +xiaobaivr.com +xiaobaixitong.com +xiaobal.com +xiaobangbaoxian.com +xiaobangguihua.com +xiaobangtouzi.com +xiaobao360.com +xiaobaobianli.com +xiaobaobianli.net +xiaobaodt.com +xiaobaoming.com +xiaobaoonline.com +xiaobaostudio.com +xiaobeibike.com +xiaobeigl.com +xiaobeiyangji.com +xiaobeizuqin.com +xiaobianli8.com +xiaobingxitong.com +xiaobool.com +xiaobot.net +xiaobu.tech +xiaobu121.com +xiaobuwq.com +xiaocanapp.com +xiaocanhulian.com +xiaocantech.com +xiaocaoo.com +xiaocaoyun.com +xiaoce.fun +xiaocen.com +xiaochamao.com +xiaoche001.com +xiaocheng.com +xiaochengxu029.com +xiaochengxucms.com +xiaochi198.com +xiaochixiang.com +xiaochuan010.com +xiaochuanyun.com +xiaocifang.com +xiaocms.com +xiaocx.org +xiaoda.fun +xiaodaijl.com +xiaodaka.net +xiaodangxian.com +xiaodanzi.com +xiaodao0.com +xiaodaotv.com +xiaodaozhi.com +xiaodapei.com +xiaodengvip.com +xiaodian.com +xiaodian.so +xiaodianweb.com +xiaodigu.com +xiaoding110.com +xiaodingchui.com +xiaodiyouxi.com +xiaodongxier.com +xiaodoubi.com +xiaodoukj.com +xiaodoushebao.com +xiaodouzuche.com +xiaoduoai.com +xiaoduseo.com +xiaodutv.com +xiaody.com +xiaoe-assets.com +xiaoe-live.com +xiaoe-materials.com +xiaoe-tech.com +xiaoe-tools.com +xiaoecloud.com +xiaoeeye.com +xiaoeknow.com +xiaoenai.com +xiaoerjiren.com +xiaoeryi.com +xiaoetong.com +xiaofany.com +xiaofeng.org +xiaofengtv.com +xiaofubao.com +xiaofuzi.net +xiaog.xyz +xiaogan.com +xiaogd.net +xiaogegelive.com +xiaogj.com +xiaogou111.com +xiaogou222.com +xiaogou333.com +xiaogou444.com +xiaogou555.com +xiaogou666.com +xiaogou777.com +xiaogou888.com +xiaogou999.com +xiaogouds.com +xiaogouh5.com +xiaogouzhineng.com +xiaoguaniu.com +xiaoguikuaipao.com +xiaoguo101.com +xiaoguosq.com +xiaoguowenhua.com +xiaoguoyi.com +xiaogushi.com +xiaohansong.com +xiaohe-jiankang.com +xiaohe666.com +xiaoheihegame.com +xiaoheima.com +xiaohelive.com +xiaohengmaidan.com +xiaohi.cc +xiaohongchun.com +xiaohongjituan.com +xiaohongshu-mycdn.com +xiaohongshu.com +xiaohongshu.net +xiaohongshulvyou.com +xiaohouyisheng.com +xiaohouyunyin.com +xiaohu8.com +xiaohua8.com +xiaohuabaichu.com +xiaohuabuluo.com +xiaohuai.com +xiaohuangji.com +xiaohuanxiong.com +xiaohuazhuo.com +xiaohucloud.com +xiaohufev.com +xiaohulu.com +xiaohun.net +xiaohuochai.cc +xiaohuochai.site +xiaohuohu.com +xiaohus.com +xiaohuwl.com +xiaoi.com +xiaoi.me +xiaoice.com +xiaoj.com +xiaoji.com +xiaoji001.com +xiaojian.site +xiaojiaokeji.com +xiaojiaoyar.com +xiaojiaoyu.com +xiaojiaoyu100.com +xiaojing.work +xiaojing360.com +xiaojinzi.com +xiaojiuwang.com +xiaojl.com +xiaojp.com +xiaojuchefu.com +xiaojudeng.com +xiaojukeji.com +xiaojupeijian.com +xiaoka.tv +xiaokache.com +xiaokakj.com +xiaokanba.com +xiaokanglongjiang.com +xiaokao.com +xiaokaxiu.com +xiaokcdn.com +xiaokcehui.com +xiaoke.space +xiaoke101.com +xiaokeai.com +xiaokeduo.com +xiaokepu.com +xiaokesoso.com +xiaokudang.com +xiaokuihua.net +xiaokusha.com +xiaolachuxing.com +xiaolajiao.com +xiaolanapp.com +xiaolanben.com +xiaolangtt.com +xiaolantiao.com +xiaole.com +xiaoleimob.com +xiaolianbao.com +xiaoliangkou.com +xiaolianhb.com +xiaoliebian.com +xiaolii.com +xiaolikj.online +xiaolin.in +xiaolinbysj.com +xiaolincoding.com +xiaolinsi.com +xiaolintj.com +xiaolinwl.com +xiaoliqing.net +xiaolizhuli.com +xiaolizupai.com +xiaolong.li +xiaoluboke.com +xiaoluerhuo.com +xiaoluhaohuo.com +xiaolun.net +xiaoluxuanfang.com +xiaoluyouxuan.com +xiaoluyy.com +xiaoluzhidian.com +xiaolvji.com +xiaolxiao.com +xiaoma.com +xiaoma.io +xiaoma.net +xiaomachuxing.com +xiaomagaojian.com +xiaomai.live +xiaomai5.com +xiaomaidong.com +xiaomaigongkao.com +xiaomaigui.com +xiaomaiketang.com +xiaomaiuzu.com +xiaomajia.com +xiaomaomi.online +xiaomaomv.com +xiaomape.com +xiaomark.com +xiaomashijia.com +xiaomaxitong.com +xiaomayi.net +xiaomazhixing.com +xiaomei.cc +xiaomeiti.com +xiaomeng1235.com +xiaomi.com +xiaomi.hk +xiaomi.net +xiaomi.org +xiaomi.tw +xiaomiaozai.com +xiaomicache.com +xiaomicorp.com +xiaomicorp.net +xiaomicp.com +xiaomidns.com +xiaomidns.net +xiaomiev.com +xiaomiflash.com +xiaomiinc.com +xiaomiinc.net +xiaomimimo.com +xiaomimobile.com +xiaominet.com +xiaominfo.com +xiaomingjianzhan.com +xiaomingtaiji.cc +xiaomingtaiji.com +xiaomingtaiji.net +xiaominr.com +xiaomiprint.com +xiaomiqiu.com +xiaomiquan.com +xiaomirom.com +xiaomisa.com +xiaomisa.net +xiaomisa.org +xiaomishu.com +xiaomiw.cc +xiaomiwear.com +xiaomixiaoai.com +xiaomiyoupin.com +xiaomlove.com +xiaomor.com +xiaomu.cc +xiaomuji.info +xiaomuzhi.com +xiaomy.net +xiaomyc.com +xiaonaodai.com +xiaonaonao.org +xiaonei.com +xiaonengren.com +xiaoni.com +xiaoniba.com +xiaoniu66.com +xiaoniuben.com +xiaoniuds.com +xiaoniuhululu.com +xiaopai.vip +xiaopaitech.com +xiaopaotec.com +xiaopeiqing.com +xiaopeng.com +xiaophy.com +xiaopi.com +xiaopinchuxing.com +xiaopinw.com +xiaopiu.com +xiaoqiandao.com +xiaoqiangge.com +xiaoqiling.com +xiaoqingtou.com +xiaoqinre.com +xiaoqiqiao.com +xiaoqiweb.com +xiaoquba.com +xiaoqueshe.com +xiaoquyijia.com +xiaorizi.me +xiaorui.cc +xiaoruibao.com +xiaoshengping.com +xiaoshentongzongbu.com +xiaoshidata.com +xiaoshijie.com +xiaoshituina.vip +xiaoshouhudong.com +xiaoshourc.com +xiaoshouyi.com +xiaoshuapp.com +xiaoshuiguo.com +xiaoshujiang.com +xiaoshuo.com +xiaoshuo1-sm.com +xiaoshuo2-sm.com +xiaoshuo3-sm.com +xiaoshuo4-sm.com +xiaoshuo5-sm.com +xiaoshuo520.com +xiaoshuoba.com +xiaoshuobi.cc +xiaoshuodaquan.com +xiaoshuohui.net +xiaoshuoli.com +xiaoshuowu.com +xiaoshuxiong.com +xiaositv.com +xiaot.com +xiaota.com +xiaotangketang.com +xiaote.com +xiaote.net +xiaotee.com +xiaotengyouxi.com +xiaotiancai.com +xiaoting.com +xiaotongqq.com +xiaotud.com +xiaotuzhan.com +xiaou2014.com +xiaoupan.com +xiaowang.net +xiaowangshen.com +xiaowangyun.com +xiaowangzi777.com +xiaowazi.com +xiaoweichen.com +xiaoweigod.com +xiaoweijia.net +xiaoweijiankang.com +xiaoweirobot.com +xiaowiba.com +xiaowm.com +xiaowuwl.com +xiaoxia.vip +xiaoxiaapi.com +xiaoxiang.club +xiaoxiangbz.com +xiaoxiangtoutiao.com +xiaoxiangxueyuan.com +xiaoxiangyoupin.com +xiaoxiaodangan.com +xiaoxiaoketang.com +xiaoxiaomo.com +xiaoxiaoshuo.com +xiaoxiaotong.org +xiaoxiaoyouxuan.com +xiaoxichangliu.com +xiaoxili.com +xiaoxinbk.com +xiaoxineye.com +xiaoxinrili.com +xiaoxintoutiao.com +xiaoxintuku.com +xiaoxiong360.com +xiaoxiongjita.com +xiaoxiongmeishu.com +xiaoxiongxitong.com +xiaoxiongyouhao.com +xiaoxiongzhoupu.com +xiaoxitech.com +xiaoxusd.com +xiaoya56.com +xiaoyanjiusheng.com +xiaoyantong.com +xiaoyanwenxue.com +xiaoyaodsx.com +xiaoyaoxi.com +xiaoyaoyou.com +xiaoyastar.com +xiaoyatong.com +xiaoyegejitar.com +xiaoyejidian.com +xiaoyejixie.com +xiaoyeren.com +xiaoyezi.com +xiaoyezu.com +xiaoyi.com +xiaoyiads.com +xiaoyida.com +xiaoyida.net +xiaoyiduoduo.com +xiaoying.co +xiaoying.com +xiaoying.tv +xiaoyingxiong.com +xiaoyingzhenxuan.com +xiaoyisysreset.com +xiaoyizhiqu.com +xiaoyou66.com +xiaoyouxi.co +xiaoyouxi.com +xiaoyouxi100.com +xiaoyouxiqun.com +xiaoyouzb.net +xiaoyu.com +xiaoyuananquantong.com +xiaoyuankousuan.com +xiaoyuansouti.com +xiaoyuansouti.xyz +xiaoyuanyun2.com +xiaoyuanzhao.com +xiaoyuanzhaopin.net +xiaoyuer.com +xiaoyujia.com +xiaoyun.com +xiaoyusan.com +xiaoyusanchou.com +xiaoyuxitong.com +xiaoyuzhoufm.com +xiaoz.me +xiaozhang365.com +xiaozhao365.com +xiaozhenpaotui.com +xiaozhibaoxian.com +xiaozhibo.com +xiaozhimed.com +xiaozhiyun.com +xiaozhongjishu.com +xiaozhoumo.com +xiaozhu.com +xiaozhu.hk +xiaozhu158.com +xiaozhu2.com +xiaozhua.com +xiaozhuangzhuang.com +xiaozhuanhao.com +xiaozhustatic1.com +xiaozhustatic2.com +xiaozhustatic3.com +xiaozlife.com +xiaozu365.com +xiaozuan8.com +xiaozuanbike.com +xiaozufan.com +xiaozujian.com +xiapac.com +xiapilu.com +xiappt.com +xiapu.co +xiaqu.org +xiaqunfeng.cc +xiarenzhuxin.com +xiarj.com +xiashanet.com +xiataoseo.com +xiatou.com +xiaw.net +xiawan8.com +xiawen.tv +xiawuyouke.com +xiaxs.info +xiaxs.la +xiayixing.com +xiayx.com +xiazai.live +xiazai126.com +xiazai16.com +xiazai163.com +xiazaiba.com +xiazaicc.com +xiazaidizhi.cc +xiazaijidi.com +xiazais.com +xiazaitool.com +xiazaiwx.com +xiazhougroup.com +xibaike.com +xibaiwang.com +xibanyaqz.com +xibeicanyin.com +xibeidev.com +xiberia.net +xibojiaoyu.com +xibu168.com +xibujuece.com +xiburongmei.com +xicaijing.com +xicaishe.com +xicaodesign.com +xichengo.com +xichongsm.com +xichu.net +xichuan001.com +xichuangzhu.com +xici.com +xici.net +xicp.net +xidesheng.com +xidian.cc +xidibuy.com +xidie.com +xidiglobal.com +xiduobaby.com +xie22.com +xiebanyun.com +xiebao18.com +xieboke.net +xiecdn.com +xieche.com +xieche.net +xiecheng.com +xiechuangw.com +xiedaimala.com +xiedajia.com +xiedao.com +xiediantong.com +xiefenxiang.com +xiegangsir.com +xiege.net +xiegekt.com +xiehehp.com +xiehejx.com +xiehekjkf.com +xiehepcb.com +xiehouit.com +xiehuiyi.com +xiejiahe.com +xiejianji.com +xiejiaxin.com +xiejing.com +xieliaofa.com +xielijiaoyu.com +xieliqun.com +xiemm.com +xiesk.com +xietonghuaxue.com +xiexiaoyuan.com +xiexin.com +xiexinbao.com +xiexingcun.com +xieyangzhe.com +xieyimao.com +xieyudatea.com +xiezewen.com +xiezi.tech +xiezilouzulinwang.com +xieziqiu.net +xiezixiansheng.com +xiezuocat.com +xiezuoye.com +xiezuoyisi.com +xifangw.com +xifenfei.com +xifengboke.com +xifenggroup.com +xifengjiuzhaoshang.com +xifu120.com +xifumi.com +xigaogen.com +xiggua.com +xigo.tv +xigou100.com +xigoubao.com +xigua.com +xigua110.com +xiguaapp.com +xiguabook.com +xiguaji.com +xiguang.xyz +xiguaplayer.com +xiguashipin.net +xiguavideo.net +xigushan.com +xigushan.net +xigushi.com +xihabang.com +xihachina.com +xihaiannews.com +xihaianrc.com +xihangzh.com +xihaxueche.com +xihazsww.com +xihegp.com +xiherencai.com +xihuan.me +xihusgh.com +xiimoon.com +xiinnn.com +xiji.com +xijie.com +xijie888.com +xijinfa.com +xijing01.com +xijingjianzhan.com +xijingjianzhan0.com +xijingjianzhan1.com +xijingjianzhan2.com +xijingjianzhan3.com +xijingjianzhan4.com +xijingjianzhan5.com +xijingjianzhan6.com +xijingjianzhan7.com +xijingjianzhan8.com +xijingjianzhan9.com +xikang365.net +xikcloud.com +xikii.com +xikoutourism.com +xikrs.com +xikuan.com +xikuqi.com +xilaijian.com +xilaiping.com +xilanggufen.com +xilddt.com +xilehongniang.com +xilexuan.com +xileyougame.com +xili.fan +xilian-group.com +xiliangjituan.com +xilichi.com +xiliguoji.com +xilinjie.com +xilinsi.org +xilinx-ic.com +xilipy.com +xilish.com +xilitang.com +xiliulou.com +xilu.com +xiluoxuan.com +xilvlaw.com +xima.org +xima.tv +ximalaya.com +ximalaya.fm +ximalaya.men +ximalaya.tv +ximalayadata.com +ximalayaos.com +ximeiapp.com +ximeigroup.com +ximendou.com +ximenwai.com +ximgs.net +ximiplay.com +ximitools.com +ximiyouxi.com +ximmerse.com +ximogo.com +ximuw.com +xin-health.com +xin-manganese.com +xin-yao.com +xin.com +xin.science +xin.xin +xin1234.com +xin21.xyz +xin3721.com +xin6.net +xinac.net +xinanjr.com +xinanrui.com +xinansec.com +xinaogas.com +xinaoyun.com +xinba.com +xinbaicai.com +xinbalive.com +xinbear.com +xinbiaocha.com +xinbiaochijiaoyu.com +xinboaa.com +xinbqg.com +xincache.com +xincai.com +xincailiao.com +xincainet.com +xincaise.com +xincaitong.net +xincanshu.com +xinceremed.com +xincg.com +xincha.com +xinchacha.com +xinchaipower.com +xinchanfeng.com +xinchangol.com +xinchao.com +xinchaoss.com +xinchego.com +xinchenai.com +xincheng.com +xinchengbio.com +xinchengge13.com +xinchengyue.com +xincheping.com +xinchess.com +xinchong.com +xinchuanbo.com +xinchuang-bio.com +xinchukj.com +xincj.com +xincmm.com +xincode.com +xincomm.com +xinda-bio.com +xindachem.com +xindaifu.com +xindalawyer.com +xindaohang123.com +xindasulian.com +xindawz.com +xinde.org +xindemarinenews.com +xindetihuiya.com +xindexuexi.com +xindianti.com +xindingdianxsw.com +xindingwealth.com +xindns.com +xindong.com +xindongdinglv.com +xindonghuyu123.com +xindu.cc +xinduo.com +xinduoad.com +xinenw.com +xiner-membrane.com +xineurope.com +xinexpress.com +xinfaholding.com +xinfangcidian.com +xinfangsheng.com +xinfei.com +xinfeijituan.com +xinfeipengjixie.com +xinfeiyu.net +xinfenggxgroup.com +xinfengji.com +xinfengming.com +xinfenlei.com +xinfinite.net +xinfox.net +xinfree.com +xinfuhk.com +xinfushe.com +xinfuyouxi.com +xinfuyun.net +xing-su.com +xing73.com +xingames.com +xingaochengtai.com +xingb.net +xingbangfl.com +xingbo.tv +xingchao1.com +xingchengb.org +xingcheshixian.com +xingchiauto.com +xingchuangcar.com +xingchuangtiandi.com +xingdatrip.com +xingdong.co +xingdongliu.com +xinge.com +xinge.la +xinge365.com +xingechemical.com +xingechina.com +xingefuwu.com +xingeshan.com +xingezhan.com +xingfagroup.com +xingfeiinc.com +xingfudu.com +xingfufangdai.com +xingfulaonian.com +xingfulizhaofang.com +xingfuu.com +xinggan.net +xingganggas.com +xingguanggongkao.com +xinghai365.com +xinghaigroup.com +xinghaiwaimai.com +xinghan.vip +xinghangdao.com +xinghantec.com +xinghaoyun8.com +xinghejoy.com +xinghengedu.com +xingheoa.com +xinghuaport.com +xinghuazixun.com +xinghuo100.com +xinghuo365.com +xinghuoxiaoshuo.com +xinghy.com +xinghy56.com +xingjiagames.com +xingjiaoyun.com +xingjiesj.com +xingjijy.com +xingjimob.com +xingjun-group.com +xingkec.com +xingkeqi.com +xingketech.com +xingkong.link +xingkongfy.xyz +xingkongmt.com +xingkupai.com +xinglai.com +xinglan.co +xingliao.work +xingliju.com +xinglin-tech.com +xinglingyingxue.com +xinglinpukang.com +xinglizhou.vip +xingloo.com +xingmima.com +xingming.com +xingming.net +xingmuyi.com +xingnuo.cc +xingongjiaoyu.com +xingpai.com +xingpaibilliard.com +xingpan.com +xingpin.com +xingqier.com +xingqisihuishou.com +xingqiu.tv +xingqiu520.com +xingqu11.com +xingquanke.com +xingren.com +xingronghealthcare.com +xingrongn.com +xingruan.com +xingrui-cn.com +xingrunkg.com +xingse.net +xingseapp.com +xingshangnet.com +xingshawater.com +xingshen.com +xingshu.com +xingshuishuiwu.net +xingshulin.com +xingsteel.com +xingsuyun58.com +xingtai.net +xingtai0319.com +xingtai123.com +xingtaishipping.com +xingtan.one +xingtan001.com +xingtangzp.com +xingtongsw.com +xingtu.com +xingtui520.com +xinguad.com +xinguangjian.com +xinguge.com +xinguida.com +xinguizhou.com +xingumin.net +xinguodu.com +xingvps.com +xingwajiang.com +xingwan001.com +xingxing.com +xingxingbao.com +xingxingjizhang.com +xingxingzaixian.fun +xingxingzu.com +xingxuanwaimai.com +xingyangroup.com +xingyao.com +xingyaocq.com +xingyaomob.com +xingyaoss.com +xingyaowa.com +xingyaoyd.com +xingyaozhilian.com +xingye.work +xingye1.com +xingyeace.com +xingyeai.com +xingyeddz.com +xingyigz.com +xingyihaiyang.com +xingyin.com +xingying2018.com +xingyizhai.com +xingyongli.com +xingyou99.com +xingyoucai.com +xingyuan-hb.com +xingyuan.com +xingyuebike.com +xingyuebio.com +xingyuedoor.com +xingyuehuyu.com +xingyuhuwai.com +xingyunb.com +xingyunba.com +xingyungroup.com +xingyunol.com +xingyusoft.net +xingyutc.com +xingyuyouxi.com +xingzh.xyz +xingzhean.com +xingzhige.com +xingzhiheyi.com +xingzhilan.com +xingzi-vision.com +xingzou.art +xingzoushu.com +xingzuo.com +xingzuomi.com +xingzuopei.com +xingzuowu.com +xingzuoyundns.com +xinhaiglobal.com +xinhaimineral.com +xinhaiminingepc.com +xinhaimininggroup.com +xinhaisoft.com +xinhaitravel.com +xinhanhd.com +xinhanhr.com +xinhanyx.com +xinhaolian.com +xinhaoqi.net +xinhaosi.com +xinhay.com +xinhe99.com +xinhechina.com +xinhecq.com +xinhedjq.com +xinhengshui.net +xinheshenggroup.com +xinheyun.net +xinhongru.com +xinhua-news.com +xinhua.org +xinhua08.com +xinhuaapp.com +xinhuachongming.com +xinhuachuanmeijs.com +xinhuacu.com +xinhuaiot.com +xinhuamm.net +xinhuanet.com +xinhuanet.ltd +xinhuapo.com +xinhuaprs.com +xinhuapub.com +xinhuaqipai.com +xinhuashe.org +xinhuashudian.com +xinhuasuye.com +xinhuawang.com +xinhuawz.com +xinhuaxmt.com +xinhuayimin.com +xinhuazhiyun.com +xinhuoq.com +xinhuozhi.com +xining-marathon.com +xiniu.com +xiniu3d.com +xiniugushi.com +xiniushu.com +xiniuyun.com +xinjiadiy.com +xinjianggames.com +xinjianggou.com +xinjiangqinglvyou.com +xinjiangroup.com +xinjiashangtou.com +xinjidian.com +xinjifangchan.com +xinjimo.com +xinjingst.com +xinjingxiang.com +xinjinqiu.com +xinjiren.com +xinjisuan.net +xinjiyuan.net +xinju.fun +xinjuc.com +xinjunshi.net +xinjunshicn.net +xinke-semi.com +xinkuai.com +xinlangtupian.com +xinlanshengbc.com +xinle.com +xinle366.com +xinleineng.com +xinleshan.com +xinleshiyiyuan.com +xinlexie.com +xinli001.cc +xinli001.com +xinli001.xyz +xinli001wx.com +xinli10.com +xinliangxiang.com +xinliceping.com +xinlifudao.com +xinlilw.com +xinlinghuayuan.com +xinlingletu.com +xinlip.com +xinliwanju.com +xinlixinli.net +xinlong-holding.com +xinluex.com +xinlvtu.com +xinlvyy.com +xinmaizj.com +xinmanduo.com +xinmanhua.net +xinmanyuan.com +xinmaotao.net +xinmei365.com +xinmeihu.com +xinmeijiutian.com +xinmeinuo.com +xinmem.com +xinmenglife.com +xinmeow.com +xinmeti.com +xinmima.com +xinminghui.com +xinminheng.com +xinmintian.vip +xinmizx.com +xinnakj.com +xinnet.com +xinnetdns.com +xinnetvip.com +xinniangjie.com +xinnianhua.com +xinnong.com +xinnong.net +xinnuodazu.com +xino-tech.com +xinorngyk.com +xinouhk.com +xinoujixie.com +xinpa.com +xinpeihu.net +xinpg.com +xinpianchang.com +xinpianyugao.com +xinpin-ip.com +xinping.cc +xinpingmu.com +xinpinhe.com +xinpinmao.com +xinpintoutiao.com +xinpupower.com +xinpure.com +xinqidian-sh.com +xinqigu.com +xinqing.com +xinqingyulu.com +xinqite.com +xinqiucc.com +xinqiyejia.com +xinqtech.com +xinquanedu.com +xinquji.com +xinranliu.me +xinrenxinshi.com +xinri.com +xinrong88.com +xinrui-games.com +xinrui-pharm.com +xinrui.biz +xinruipiao.com +xinruiweb.com +xinsanbanbao.com +xinsankeji.com +xinsdn.com +xinsenz.com +xinsf.cc +xinshangmeng.com +xinshangshangxin.com +xinshengdagroup.com +xinshengku.com +xinshengsemi.com +xinshi525.com +xinshiba.com +xinshipu.com +xinshishen.com +xinshouyou.com +xinshouzhanzhang.com +xinshuge.net +xinshuiny.com +xinshuru.com +xinsilu.com +xinsource.com +xinss.com +xinss.net +xinstall.com +xinstatic.com +xinszy.com +xintaikeji.com +xintairen.com +xintairencai.com +xintaishequ.com +xintaizhou.com +xintajixie.com +xinteenergy.com +xintengmenchuang.com +xintheme.com +xintiandi.com +xintianw.com +xintianya.net +xintiao100.com +xintiaogroup.com +xintiaoyouxi.com +xintongconference.com +xintongwang.com +xintrum.com +xintuan.com +xintucdn.com +xintuosoft.com +xintv.com +xinwangcj.com +xinwanr.com +xinweier.com +xinweiyun.com +xinwell.com +xinwen365.com +xinwen520.net +xinwengao.net +xinwengood.com +xinwenlianbo.tv +xinwo.com +xinwuji.com +xinwulan.com +xinxe.com +xinxi28.com +xinxianghui.com +xinxianshilb.com +xinxiansk.com +xinxianwang.com +xinxiaochina.com +xinxiaodian.com +xinxiaoqi.com +xinxiaozu.com +xinxiehe.com +xinxifabu.net +xinxinapp.net +xinxing-marathon.com +xinxing001.com +xinxing100.com +xinxing91.com +xinxinhot.net +xinxinhotel.com +xinxinjoy.com +xinxinmed.com +xinxjs.com +xinxue-edu.com +xinxuejy.com +xinxunwang.com +xinxyun.com +xinya.me +xinyali.net +xinyan-gx.com +xinyan.com +xinyanggaopin.com +xinyanglao.com +xinyanwuliu.com +xinyao168.com +xinyaoapp.com +xinyaoshi.com +xinyapharm.com +xinyayk.com +xinyegang.com +xinyetongcard.com +xinyi-tech.com +xinyi.com +xinyidc.com +xinyiglass.com +xinyihl.com +xinyinghc.com +xinyingpower.com +xinyingtec.com +xinyingyang.com +xinyisemi.com +xinyishiji.com +xinyitt.com +xinyo100.com +xinyong.net +xinyongbuy.com +xinyongsoon.com +xinyou.com +xinyoudui.com +xinyour.com +xinyu-tam.com +xinyu19.com +xinyuanclub.com +xinyuanf.com +xinyuanfin.com +xinyuanshiye.net +xinyubt.com +xinyuchen.com +xinyueclub.com +xinyuefei.com +xinyuehealth.com +xinyuejiaxiao.net +xinyueseo.com +xinyuevod.com +xinyuhole.com +xinyuhongyuan.com +xinyuncs.com +xinyunfuwu.com +xinyunit.com +xinyurc.com +xinyustone.com +xinyutengyuan.com +xinzegongshui.com +xinzengwj.net +xinzheng.cc +xinzhi.com +xinzhi.space +xinzhibang168.com +xinzhibid.com +xinzhichuangzhi.com +xinzhiguanwangyun.com +xinzhongqi.net +xinzhou.org +xinzlkj.com +xinzuojia.com +xinzushenghuo.com +xiolift.com +xiongan1dt.org +xionganxinxi.com +xiongbagk.com +xiongchuan.com +xiongf.com +xiongfengcl.com +xiongfenggroup.com +xiongge.club +xiongmaitech.com +xiongmao555.com +xiongmao789.com +xiongmaoboshi.com +xiongmaodangao.com +xiongmaojinku.com +xiongmaosaohao.com +xionguamaqui.com +xiongying.com +xiongyudl.com +xiowo.net +xioxix.com +xipu.com +xipunet.com +xipushuju.net +xiqb.com +xiqianyangyi.com +xiqiaoshantour.com +xiqifun.com +xiqinrc.com +xiqkj.com +xiqu.me +xiqu001.com +xiquebo.com +xiqueer.com +xiquepark.net +xiqueqingjian.com +xiqurongmei.com +xiquwenhua.net +xirang.com +xiri-vacuum.com +xironiot.net +xisaiwang.com +xise3.com +xishalz.com +xishanju-hn.com +xishanju.com +xishanxuexiao.com +xishaoye.com +xishiwang.com +xishixiuhair.com +xishpj.com +xishu365.com +xishuai.com +xishuai.net +xishuizk.com +xishunj.com +xisofttec.com +xitanhotel.com +xitaoinfo.com +xite-group.com +xitek.com +xitek.net +xitengbingxue.com +xitie.com +xitieba.com +xitieba.net +xitinet.com +xitmi.com +xitong-tech.com +xitong114.com +xitong5.com +xitong8.com +xitong86.com +xitongcity.com +xitongdaquan.net +xitonggho.com +xitonghe.com +xitongku.com +xitongle.com +xitongpe.com +xitongtiandi.net +xitongtiankong.com +xitongtu.net +xitongwanjia.com +xitongxz.net +xitongzhijia.com +xitongzhijia.net +xitongzijia.net +xitongzongcai.com +xitu.com +xitu.io +xituan.com +xiu.com +xiu8.com +xiuai.com +xiubiaoshi.com +xiubiaozu.com +xiucai.com +xiudodo.com +xiudtech.com +xiufa.com +xiufaxing.com +xiugei.com +xiugu.com +xiuhandingzhi.com +xiuhangzhe.com +xiuhe128.com +xiuimg.com +xiujiadian.com +xiujixia.com +xiujue.cc +xiulian.com +xiuluowang.com +xiuluren.com +xiulv.com +xiumb.com +xiumb12.com +xiumi.us +xiumius.com +xiumucn.com +xiuna.com +xiuno.com +xiuqicloud.com +xiuren.com +xiushao.com +xiusheji.com +xiushuang.com +xiushui.net +xiusifudianji.com +xiustatic.com +xiutanqi.com +xiutuan.com +xiutv.com +xiuxiandou.com +xiuxianshipin.com +xiuxiu.com +xiuxiuda.com +xiuxiustatic.com +xiuxmanhua.com +xiuzhan365.com +xiuzhanwang.com +xiuzhiwu.com +xivcdn.com +xiwan.vip +xiwang.com +xiwangame.com +xiwangchina.com +xiwangd.com +xiwanglife.com +xiwangxiaoyuan.com +xiwantrip.com +xiweigas.com +xiwenquan.com +xiwicloud.com +xiwnn.com +xiwuji.com +xiwuy.com +xixiangongjiao.com +xixianwatergroup.com +xixiaoyou.com +xixiarc.com +xixibobo.com +xixidoudizhu.com +xixig8.com +xixih.cc +xixih.net +xixik.com +xixik.net +xixinews.com +xixinghanghr.com +xixiqipai.com +xixisys.com +xixiwg.com +xiyacs.com +xiyangan.com +xiyashiji.com +xiyec-tencentclb.cloud +xiyec-tencentclb.com +xiyec-tencentclb.net +xiyec-tencentclb.work +xiyi-jt.com +xiyijiang.com +xiyijm.com +xiyin.life +xiyiqq.com +xiyogo.com +xiyongpark.com +xiyoo.com +xiyou-g.com +xiyoucdn.com +xiyouchat.com +xiyouji.com +xiyouji.work +xiyoulinux.com +xiyoupark.com +xiyouquan.com +xiyousdk.com +xiyouwebgame.com +xiyouxi.com +xiyuanshuke.com +xiyucosmetics.com +xiyuege.com +xiyuegr.com +xiyufine.com +xiyun.net +xizanggames.com +xizangguolv.net +xizangmaoniunai.com +xizangqinglv.com +xizangzl.com +xizexiao.com +xizhai2021.com +xizhang.com +xizhengtouzi.com +xizhi.com +xizi.com +xizice.com +xiziiparking.com +xiziquan.com +xiziwang.net +xj-biotech.com +xj-etyy.com +xj-tianye.com +xj-zp.com +xj120.com +xj123.info +xj169.com +xj5152.com +xj5u.com +xj71.com +xj917.com +xj96596.com +xjabc.net +xjauto.net +xjbank.com +xjbaoyouge.com +xjbdf.net +xjbhc.net +xjbuluo.com +xjc18.com +xjcc.net +xjcmtj.com +xjcysky.com +xjcysw.com +xjd2020.com +xjdaily.com +xjdkctz.com +xjdpx.com +xjdsb.com +xjdwfc.com +xjdzhyq.com +xjedu.org +xjent.com +xjesps.com +xjf.pub +xjfam.com +xjfdcw.com +xjfilm.net +xjfk.com +xjflcp.com +xjfm.com +xjfzb.com +xjgameapi.com +xjgameinfo.com +xjgc.com +xjggjy.com +xjgj.com +xjgqt.org +xjgsdm.com +xjgt.com +xjguanghui.com +xjguowang.org +xjgwy.org +xjgxjt.com +xjh.com +xjh.me +xjhgame.net +xjhjrq.com +xjhr.com +xjhsxt.com +xjhtrq.com +xjhuan.fun +xjhx120.com +xjhyktsp.com +xjhzn.com +xjietiao.com +xjishu.com +xjisme.com +xjiyou.com +xjjhjt.com +xjjnjp.org +xjjqd154.com +xjjsws.com +xjjt.com +xjks.net +xjlxw.com +xjlytz.com +xjlz365.com +xjmachine.com +xjmg.com +xjmty.com +xjnnet.net +xjnzm.com +xjoycity.com +xjpdf.com +xjphsd.com +xjpnmt.com +xjqixing.com +xjqysw.com +xjr2018.com +xjrb.com +xjrb.net +xjrc365.com +xjrmyy.com +xjshanhao.com +xjsic.com +xjsmwl.com +xjsy56.com +xjtcm.com +xjtjjt.com +xjtour.com +xjtrcw.com +xjtrry.com +xjtsnews.com +xjtssw.com +xjtucompressor.com +xjtudlc.com +xju88.com +xjwell.com +xjwljb.com +xjwyglw.com +xjxa.com +xjxbmy.com +xjxbx.com +xjxdf.com +xjxf.com +xjxhdn.com +xjxtrq.com +xjy020.com +xjygaofu.com +xjyrcw.com +xjysk.com +xjytjt.com +xjz.com +xjzclyqc.com +xjzcsq.com +xjzdjx.com +xjzhsh.com +xjzlyy.com +xjzp.net +xk41v506m7.com +xk57.com +xk857.com +xk89.com +xk9l.com +xkaczxv.com +xkaxka.com +xkbbtang.com +xkbjm.com +xkcd.in +xkcun.com +xkdywl.com +xkeirofiowef.com +xker.com +xkfyzmob.com +xkgiwdey.com +xkhouse.com +xkitd.com +xkjian.com +xkjt.com +xkjt.net +xkjxcon.com +xknow.net +xkoeccrq.com +xkonglong.com +xkpx.com +xksafe.com +xksast.com +xktech.com +xktsz.com +xkunyi.com +xkw.com +xkwe.com +xkxs.org +xkxsc.com +xkyl.vip +xkyn.com +xkyn.net +xkyy.com +xkzzz.com +xl-ai.com +xl-edu.net +xl-ele.com +xl-soft.com +xl-vip.com +xl18z.com +xl2824.com +xl5bb.com +xl5dd.com +xl5du.com +xl5dw.com +xl699.com +xlaidudu.info +xlaidudu.net +xlaomi.net +xlbsoft.com +xlcai.com +xlcgjg.com +xlcidc.com +xlcjzx.com +xlctyd.com +xlczg.com +xldlive.com +xldz.com +xlewen5.com +xlfred.com +xlgao.com +xlgjg.net +xlgogo.com +xlgtx.com +xlgxapp.com +xlhb.com +xlhbgroup.com +xlhfmj.xin +xlhhy.com +xlhk.net +xlhs.com +xlhyc.com +xlibai.com +xlinclass.com +xlisp.net +xljly.com +xljnjy.com +xljsci.com +xlkdyf.com +xlkorganic.com +xlkshop.com +xlkty.com +xllyk.com +xlm258.com +xlmarathon.com +xlmr.com +xlmz.net +xlndt.com +xlobo.com +xlongm.com +xloveyoux.com +xlpai.com +xlpan.com +xlpp.net +xlqeai.com +xlqzh.com +xlread.com +xlreads.com +xlsdn.com +xlsemi.com +xlshou.com +xlsxmj.com +xltll.com +xltnjslfd.com +xlvshi.com +xlwl95.com +xlxkgjt.com +xlxqsgf.com +xlxslny.com +xlyap.com +xlyfhw.com +xlykzz.com +xlyouxi.com +xlyouxi.net +xlysauc.com +xlysauc.net +xlysoft.net +xlyx3.com +xlyxo.com +xlyxp.com +xlzfpt.com +xlzhao.com +xlzyd.com +xlzys.com +xlzyyw.com +xm-ad.com +xm-ais.net +xm-chuang.com +xm-gzf.com +xm-olympic-museum.org +xm002.com +xm200.com +xm51.com +xm5156.com +xm680.com +xm6wpp.com +xm9.co +xm909.com +xm9m.com +xmac.app +xmafkj.com +xmaibu.com +xmalaya.com +xmamiga.com +xmanblog.net +xmantou.com +xmasg.com +xmayitxt.com +xmbankonline.com +xmbhw.com +xmbie.com +xmbike.com +xmbus.com +xmccb.com +xmcdn.com +xmchong.com +xmcimg.com +xmcord.com +xmcp.ltd +xmcwh.com +xmcx.net +xmcy.com +xmdh.com +xmeasygo.com +xmecard.com +xmerak.com +xmeye.net +xmf.com +xmfc.com +xmferry.com +xmfev.com +xmfish.com +xmfls.net +xmfunny.com +xmgd.com +xmgltwzhs.com +xmgod.site +xmgouemc.com +xmgps.com +xmgsd.com +xmgslx.com +xmguoyi.com +xmgwbn.com +xmhaicangmarathon.com +xmheigu.com +xmheitu.com +xmhitek.com +xmhlcs.org +xmhljx.net +xmhouse.com +xmht.com +xmhx.com +xmigc.com +xminfoport.com +xming.ai +xminnov.com +xminzu.com +xmisp.com +xmitic.com +xmj1688.com +xmjchyxh.com +xmjgjy.com +xmjiaruan.com +xmjim.com +xmjj3d.com +xmjled.com +xmjsci.com +xmjslh.com +xmjyw.com +xmjzykj.com +xmkanshu.com +xml-journal.net +xmldz4.com +xmlhifi.com +xmlulub.com +xmlvbarcode.com +xmmade.com +xmmama.com +xmmeiyou.com +xmmnrj.com +xmmtu.com +xmmuye.com +xmnjdwx.com +xmnovel.com +xmocloud01.com +xmonecode.com +xmos.tv +xmov.ai +xmpaoyou.com +xmparking.net +xmpbjl.com +xmpcba.com +xmqianzun.com +xmqxy.com +xmr-zh.com +xmrb.com +xmrbi.com +xmrdtx.com +xmruanci.com +xmruiyou.com +xmseaview.com +xmseeyouyima.com +xmsgame.com +xmsixian.com +xmsiyb.com +xmsj.org +xmsme.com +xmsmjk.com +xmsoft.com +xmsouhu.com +xmsoushu.com +xmspace.net +xmssie.com +xmsssyy.com +xmsumi.com +xmsuperlite.com +xmswim.com +xmtbang.com +xmtyy.net +xmuli.tech +xmvod.org +xmwan.com +xmwes.com +xmwsrc.com +xmx023.com +xmxc.com +xmxdev.com +xmxfxh.com +xmxgame.com +xmxmc.com +xmxsapp.com +xmxwl.net +xmxwz.com +xmyeditor.com +xmylhy.com +xmyouma.com +xmyzm.com +xmzangao.com +xmzdls.com +xmzgxcl.com +xmzhdz.com +xmzhkt.com +xmzibi.com +xmzjjl.com +xmzjtjckmy.com +xmzmmr.com +xmzmy.com +xmzs.org +xmzsyg.site +xmzyark.com +xmzzy.net +xn--0lqwsu2w.com +xn--1bs9ye16ez8b.com +xn--1ctq05bvu1a.com +xn--1d3a16a.com +xn--1lqq7i4w0acli.com +xn--2cyr99a.com +xn--2quu5hi8e69p.com +xn--2vra6db.com +xn--2vxsp6vi4j.com +xn--3bs35yfl6bn8a.ink +xn--3bs70igqdr64f.com +xn--3bs781ecijtrt.com +xn--3bsp13hurlcwb.com +xn--3bsx54la62v.com +xn--3bsz0pskmp89skv3a0zd724b1py.net +xn--48s50dpwnbh95ah07i.com +xn--4gq0d69oba129b9wd94ey8bs83ji3c3q7hoka.org +xn--4gq1d760bszbgdv5p12rhq5bx2yc.net +xn--4lwr21d.com +xn--4qwqc04pn0lg9h.com +xn--4xup5j.com +xn--54q249denfzw9a.net +xn--54q40czz0g7xp.com +xn--55qw7biqf7g3d004h8yuw1ctrt04sep1cjfb.com +xn--55qx2ag79c1iq.com +xn--55qzsxj5y4ozkz93dswptmau4jc88dg75ctid8raf29c.com +xn--5brz4b846h.com +xn--5kv317c.com +xn--5kv91jiz2b.com +xn--6fr61zj8c92fg34d.com +xn--6kr66fp2ep1ac5edz2hy7s2wq.com +xn--6krw3qs7jl59b.com +xn--6oq83hzb922dnorwsomx9dzkb.com +xn--6qqp94buie2ss.com +xn--6rtq6phwfhva.com +xn--6xv710dola.net +xn--730-l44eu9iitvv9h.com +xn--7mqy6dj0brts55e.com +xn--7qvz7xssa.com +xn--88-9s0f59z.com +xn--8lqrjra071bi0qgga421cs99a4qeqwm.com +xn--8ou124e6ek.net +xn--8owq8u.com +xn--8stx8olrwkucjq3b.com +xn--91-y60d638c.xyz +xn--9kr72kqwe.com +xn--9krv3x413bbyb.com +xn--9myo55bi8l.com +xn--9pr56vfna007k.com +xn--9pry86bq5ex68c.org +xn--b0t462i.com +xn--b0tn0sxy3ayhj.com +xn--b0tp7p3met2a.com +xn--b0tp7p3met2a.net +xn--b8qi619ujyk.com +xn--btvs3aw8fhtbms310k.com +xn--btvu9x9qgt8c.com +xn--bxyy83e.net +xn--cesw6hd3s99f.com +xn--cesx3oukw29l.com +xn--chq7lp8e46htw3g.com +xn--chq84itwgrb674blm6f.com +xn--chq978ctsf6v6c.com +xn--cjztj18l.com +xn--cpqr0dg9g4t0fodaq5c.com +xn--cssw8z54rj2ds2q.com +xn--czr93rxry.com +xn--czru2dx3eszw3lat53b.com +xn--dev407h.com +xn--djr48g6sik7q.com +xn--djr58xb1mzxk3mtrhfc8g.com +xn--dkr447bejn.com +xn--dkr447bejn.net +xn--dll-8n0e103bz5hg93c.site +xn--dlq10g6xfkw4a201b.com +xn--dlqu6kw2e2n3aolseyrfhn.com +xn--dlqw10borzgxh.com +xn--dtq23gl66e.com +xn--eh1a34ykpl.com +xn--fcs316auqlyoe.com +xn--fhq79jyym9nh74hfm8a.com +xn--fiq03fftg7m2c.com +xn--fiq06jqoz14s.com +xn--fiq446amrnx0i.com +xn--fiq4mgq69drxaiym2g5wnynb77huij0bchq7vj5ay61o3cwdq2ah92mlg9c.com +xn--fiq60luzcp97a7oxivr99k.org +xn--fiq6q20pz51d.com +xn--fiq73f39fwr0b4wk.net +xn--fiq7v55hnsepqz.net +xn--fiqr9gg1vdha.com +xn--fiqrtn9duw9e.cc +xn--fiqs8sr9ge7eb4b28vo92a.com +xn--fiqu59c0hf2sy.net +xn--fiqv94di0c54ipe.net +xn--fiqw8jl3h7xc25m753d.link +xn--fiqx7ci2whnj.com +xn--fjq5py34j65v.com +xn--flw351e.com +xn--glr604k.com +xn--gmqr9gdtrhuf56g.com +xn--h0tn34c.cc +xn--husx9zj2eepau0se83d.com +xn--hutn94av9amzg.net +xn--i6q33br88fkud.com +xn--igry70bi8kqt9a.org +xn--igt225itqf.com +xn--it-if7c19g5s4bps5c.com +xn--jh1a128b.com +xn--jor0b302fdhgwnccw8g.com +xn--jpr47zq87axwjc0d.com +xn--jxuv1s.net +xn--kivq8be3whsi.com +xn--l9qya49g86gm9ghpbzy1dwl0fppo.com +xn--lt0at3k.com +xn--mct72chgrm.net +xn--mes380bwhsoec.com +xn--mmz.cc +xn--mnqs00c24c2pw0ii.com +xn--mts196b.net +xn--n5q75cia631gba51vx4ag2a008o08l1t0adzay2skp4b.com +xn--n6qy1xeobw60f.net +xn--ncym25ahib.net +xn--nmqp78hmufjwu.com +xn--ntso8dsz1borbzvfm5h.com +xn--ntsp37j.net +xn--nyqx2gbsm8u0b.com +xn--ohqn1dw64cf45c8l9a1ba.com +xn--omrvgz6er31au6f.com +xn--oorz70c56jtwb49x.net +xn--p5t28ylet56a.com +xn--pss89e6xl72g.com +xn--ptua509t.com +xn--q20av2y36ac54a.com +xn--qruq25bjsj.net +xn--qzwx3ij21azka.com +xn--r8s65df7admf92a.com +xn--rhq112dhez17bejdyhl55dypc.com +xn--rhqr3ykwbm05aegjqxb.com +xn--rhqt5j7qj6mj.com +xn--rht439a44bdyk.com +xn--riqi041otpd.com +xn--ror-j59d107t.net +xn--rpv331d.com +xn--rss237b.com +xn--rss404ac6aj60e.net +xn--rsss0ke5ghnj.com +xn--ruqs20ac8b5z7av8ir2u.net +xn--ruqz9zcojm5sf19a.com +xn--s4t325g.com +xn--sgt856gbjl.cc +xn--siq0gv77a3c.com +xn--sosw2ge0bs10aoq0a.com +xn--sss604efuw.com +xn--swts8irvtrtr.com +xn--tesiro-n17nh93r.net +xn--tfr181fg2az43a.com +xn--tkr55q2oa097dyxe209c.com +xn--tlq092au7hsi3a.com +xn--tlqz3aj77agil76ww4ni2k.com +xn--tqq89g2tjj5x8xs.com +xn--vcso1ukuz.net +xn--vcsu51b3zccpm.com +xn--vcsu9p66gy1l9vpnnbk52f.com +xn--vhq3m33sbqhpsmtnuxfq.com +xn--vhq3mr8b802a.net +xn--vhq4ut2dsxd5xqnicjxxo55a756aovhik0aunm.com +xn--vhq72yfwbt0elp2cpkhtld55g73l1o6a.com +xn--vhqqbz2p62hm92e04p.com +xn--vhqr42drhf5k7b.com +xn--vhqu1kbz3bnbi.com +xn--viq463a.com +xn--vq3a5gj6c9i.com +xn--w9q313dfn4a.com +xn--w9qr0k.com +xn--w9qy23cc6adz7d.net +xn--wbsz85a2a.com +xn--wtqs2doz3b.com +xn--wxtr44c.live +xn--xcry9n251cvcar5xj6r.com +xn--xhq60k09cr85at2f494d.com +xn--xhq60kzbz07dem6azlu.com +xn--xhq8sm16c5ls.com +xn--xhqq4f5vc69qlmk6mva633mwoeiuad9562e.com +xn--xhqs8jmxkive1yest6g.com +xn--xhqs8jp0kpz2d.net +xn--xhqx10kr8o.com +xn--xkr190gv5p.com +xn--xkr26fp82clgt.com +xn--xkr999cp4fv97a.com +xn--xkrs9ba41r.com +xn--y6q834d2k3al4h.com +xn--y8jhmm6gn.moe +xn--ygtp21bwyedsq.com +xn--yhqq38bmov17mqxi.com +xn--ykr169cm1pskt.com +xn--z4q559dueav8q.com +xn--z63a11k.com +xn-ck.com +xn0.cc +xn121.com +xna8.com +xnara.org +xnb.me +xncjdx.com +xndm.tech +xndqfw.com +xndxfz.com +xndyyljt.com +xnfyy.com +xngjbus.com +xnh123.com +xnh98d9c32om.com +xnhdgame.com +xninja.org +xnjcw.com +xnjdcbs.com +xnjxnz.com +xnnpc.com +xnongren.com +xnparking.com +xnpfs.com +xnpic.com +xns315.com +xnsbdzb.com +xnsdermyy.com +xnsntr.com +xnssy.com +xnszlszgs.com +xntg.com +xntt.com +xntv.tv +xnw.com +xnw19.vip +xnwan.com +xnwatch.com +xnwbw.com +xnwmw.com +xnxy120.com +xny365.com +xnyauto.com +xnye.net +xnytjt.com +xnzjxx.com +xnzn.net +xnzxyy.com +xnzyyy.com +xo58tjrol4.work +xoao.com +xogekfb.com +xoliao.com +xooooa.com +xopenbeta.com +xoqeyeti.com +xorlink.com +xorpay.com +xoso13.com +xoso57.com +xoso64.com +xoso94.com +xoso96.com +xoss.co +xoudou.com +xox717.com +xox848.com +xoxv.net +xoxxoo.com +xoyo.com +xoyobox.com +xoyocdn.com +xoyq.net +xp535.com +xp6000.com +xp61.com +xp811.com +xp9365.com +xp94.com +xpaper.com +xpaper.net +xpccdn.com +xpcdz.com +xpcha.com +xpchina.net +xpdf.net +xpeae.com +xpeng.link +xpf.cc +xpgod.com +xpgps.cc +xphcn.com +xpj0066.com +xpj8857.com +xpkjpk.com +xpkongqipao.com +xplaymobile.com +xppgsx.com +xppjzs.com +xpsheying.com +xpsup.com +xpsy.net +xpsy3q9e5kr4.com +xptt.com +xpu93.com +xpw888.com +xpwin7.com +xpykjsws.com +xpyouxi.com +xpyx.net +xpzsgc.com +xq0356.com +xq0757.com +xq2024.com +xq5.com +xq668.com +xqb24.com +xqbase.com +xqblog.com +xqbssj.com +xqce.com +xqckg.com +xqdgroup.com +xqdjkwz.com +xqebp.org +xqfunds.com +xqgmx.com +xqhuyu.com +xqhzw.org +xqipu.com +xqishuta.com +xqiushu.com +xqjmzc.com +xqjs.net +xqllaser.com +xqltzp.com +xqmdc.com +xqmice.com +xqnmz.com +xqpharma.com +xqppt.com +xqsbw.com +xqshe.com +xqship.com +xqtzigc.com +xqu5.com +xqvxifvk.com +xqyake.com +xqyk024.com +xqymuy.com +xqypay.com +xr100.net +xray.cool +xrbulk.com +xrcch.com +xrccp.com +xrdyl.com +xrdzidonghua.com +xredu.com +xrender.com +xresgrbw.com +xrhhg.com +xrichengapp.com +xrjjk.com +xrkapp.com +xrkcdn.com +xrkmonitor.com +xrlmold.com +xrpyq.com +xrqh.com +xrqorv.com +xrso.com +xrunda.com +xrvm.com +xrwf66.com +xrxr.xyz +xrxukegi.com +xrxx365.com +xrzdsp.com +xrzhg.com +xrzww.com +xs-ir.com +xs-servers.com +xs058.com +xs3cnc.com +xs52.com +xs63.info +xs7.cc +xs7.com +xs7.la +xs920.com +xs9999.com +xsa239.com +xsappxz.com +xsb120.com +xsbja.com +xsbus.com +xscbs.com +xschu.com +xschuban.com +xscp03150xq.com +xscxzcz.com +xsdma.com +xsdmr.com +xsdnjl.com +xsdoudou.com +xsdwk.com +xsee.cc +xsesc.com +xsfaya.com +xsfc.com +xsgame.net +xsgame99.com +xsgongju.com +xsgtvacct.com +xshengyan.com +xshenshu.com +xshhotels.com +xshkvip.com +xshmzz.com +xshntc.com +xshouyou.com +xshr.com +xshrcw.com +xshts.com +xshuai.com +xshubao.org +xshuma.com +xshuoba.com +xshuoshuo.com +xsignal-ft.com +xsina.net +xsinger.me +xsj21.com +xsjedu.org +xsjgzbdf.com +xsjit.com +xsjk.net +xsjny.com +xsjom.com +xsjplm.com +xsjrc.com +xsjs-cifs.com +xsjtxt.com +xsjwyx.com +xsjxyedu.com +xsjzsy.com +xskb.org +xskhome.com +xskjw.com +xslb.me +xslb.net +xslmed.net +xsm818.com +xsmaofa.com +xsmart.com +xsmart.link +xsmoe.com +xsn168.com +xsnow.net +xsnsyh.com +xsool.com +xsp0311.com +xsphs.com +xspinfo.com +xspio.com +xsqzyyy.com +xsrm.com +xsrtvu.com +xss.tv +xssc8888.com +xssdcdn.com +xsser.date +xsshuku.com +xsskc.com +xsslyjt.com +xssz.net +xsteach.com +xsti.net +xstnet.com +xstqj.com +xsttop.com +xstv.net +xstx.info +xstzgs.com +xsui.com +xsuweb.com +xswang.com +xswdcasting.com +xsxgjsw.com +xsxlt.com +xsxzls.com +xsy-edu.com +xsy.science +xsycps.com +xsyeli.com +xsyk021.com +xsyq.cc +xsyqmztg.com +xsyx.xyz +xsyxsc.com +xsyydtfy.com +xsyzdl.com +xszhuan.com +xszrcw.com +xszsw.com +xszww2.com +xszww8.net +xt-gas.com +xt-kp.com +xt-luyou.com +xt-rent.com +xt-shipping.com +xt12333.com +xt3yy.com +xt700.com +xt7p.com +xtadmins.com +xtaike.com +xtal.cc +xtao.me +xtbank.com +xtc-edu.com +xtcaq.com +xtcfjt.com +xtcrm.com +xtdj.cc +xtedu.com +xtep.com +xthinking.net +xthtc.com +xthyjt.com +xtiai.com +xtianlang.com +xtibet.com +xtingcloud.com +xtion.net +xtjc.com +xtjcxh.org +xtjky.com +xtjlyy.com +xtjob.net +xtjsxy.net +xtjtjs.com +xtlexueu.com +xtlog.com +xtmit.com +xtmtrj.com +xtomp.com +xtong-solar.com +xtongs.com +xtoobmo.xyz +xtqarzip.com +xtransfer.com +xtrapowercn.com +xtratime.qcomgeo2.com +xtrc.net +xtrunc.com +xtsfuke.com +xttblog.com +xttz.com +xtu2.com +xtuan.com +xtuos.com +xtutoring.com +xtw-system.com +xtwzyx.com +xtx6.com +xtxcm.com +xtxh.net +xtxnxk.sbs +xtylxx.com +xtyyw.com +xtzdc.com +xtzhiliji.com +xtzjup.com +xtzpw.com +xtzy.com +xu1s.com +xu42x.net +xu8.fun +xu97.vip +xuanba.com +xuancaizi.com +xuanceo.com +xuancheng.org +xuanchuanyi.com +xuandan.com +xuandecarpet.com +xuanfengge.com +xuanhaikuwan.com +xuanhao.com +xuanhuange.com +xuanhuange.net +xuanjigame.com +xuanjingcn.com +xuanjutong.com +xuanke.com +xuankuge.com +xuanliw.com +xuanma.com +xuannaer.com +xuanqii.com +xuanquge.com +xuanqun.com +xuanruanjian.com +xuanshi.link +xuanshitou.com +xuanshu.com +xuanshu.org +xuansiwei.com +xuantaikeji.com +xuanteng.org +xuanwifi.com +xuanwonainiu.com +xuanwu88.com +xuanwumobile.com +xuanwww.com +xuanxiaodi.com +xuanxiaozhuanjia.com +xuanxuan.com +xuanxuangame.com +xuanxue.com +xuanxuewang.com +xuanyang888.com +xuanyaodang.com +xuanyaodang.net +xuanyge.info +xuanyouwang.com +xuanyuan.cloud +xuanyuan.run +xuanyuancode.com +xuanyuanhuangdi.org +xuanyuans.com +xuanyuanzjy.com +xuanyusong.com +xuanyutech.com +xuanzhi.com +xuanzhuanmumatuwen.com +xuavieres.com +xubei.com +xuchencq.com +xuchuang.com +xucongbaobao.com +xudan123.com +xudankeji.com +xudong8.com +xudongfood.com +xudoodoo.com +xue.net +xue114.com +xue126.com +xue138.com +xue163.net +xue51.com +xue63.com +xue8nav.com +xue99.com +xueanquan.com +xueba100.com +xuebaclass.com +xuebaike.net +xuebangsoft.com +xuebapan.com +xuebawang.net +xuecaijie.com +xuecan.net +xueche.com +xueche.net +xuechebu.com +xuechela.com +xuechu123.com +xuecoo.com +xueda.com +xuedao.com +xuedapei.com +xuedi.com +xuedingmiao.com +xuedong97.com +xuedou.com +xueepay.com +xueersi.com +xueersibook.com +xueerxing.com +xueeu.com +xuefa.com +xuefeiji.org +xuefenxi.com +xuefo.com +xuefo.net +xuefoxue.com +xuegaogame.com +xuegaogg.com +xuegeshui.com +xuegongkong.com +xuegui.net +xueguoedu.net +xuehai.net +xuehaiwu.com +xuehuacdn.com +xuehui.com +xuehuile.com +xuehuiwang.com +xueid.com +xueit.com +xuejia123.com +xuejian.site +xuejiaoso.com +xuejiqiao.com +xuekanba.com +xuekao.com +xuekao123.com +xuekeedu.com +xuekewang.com +xuekuaiji.com +xuekubao.com +xuekuibang.shop +xuelangapp.com +xuele.net +xueleku.com +xuelema.com +xueleyun.com +xueli9.com +xueliedu.com +xuemh.com +xueming.li +xuenarui.com +xuenb.com +xuepaijie.com +xuepaipai.com +xuepingx.com +xuepojie.com +xueqian.com +xueqinji.com +xueqiu.com +xueqiu360.com +xuerong.com +xuesai.net +xuesax.com +xuesexs.com +xueshanlinghu.com +xuesheng.com +xueshiyun.com +xueshu.com +xueshu5.com +xueshuda.com +xueshujia.com +xueshut.com +xueshuwenhai.com +xuesidaojiajiao.com +xuesongshuwood.com +xuesw.com +xuetangonline.com +xuetangx.com +xuetengedu.com +xuetianli.com +xuetimes.com +xueto.com +xuetongw.com +xuetu.net +xueui.com +xuewangshang.com +xuewangzhan.com +xuewangzhan.net +xuewei360.com +xueweigui.com +xueweijiema.com +xuewennet.com +xuewenya.com +xuexb.com +xuexi.la +xuexi199.com +xuexi365.com +xuexi365.net +xuexi612.com +xuexi613.com +xuexi616.com +xuexi637.com +xuexi665.com +xuexi682.com +xuexi683.com +xuexi684.com +xuexi707.com +xuexi719.com +xuexi721.com +xuexi725.com +xuexi727.com +xuexi733.com +xuexi734.com +xuexi782.com +xuexi784.com +xuexi786.com +xuexi806.com +xuexi807.com +xuexi823.com +xuexi824.com +xuexi825.com +xuexi826.com +xuexi827.com +xuexi828.com +xuexi829.com +xuexi848.com +xuexi851.com +xuexi859.com +xuexi860.com +xuexi861.com +xuexi863.com +xuexi864.com +xuexiaodaquan.com +xuexiaozhaopin.com +xuexibao.com +xuexicha.com +xuexicn.com +xuexigang.com +xuexili.com +xuexin365.com +xuexinjiaoshi.com +xuexito.com +xuexitong.com +xuexiuwang.com +xuexiwa.com +xuexizhiwang.com +xuexizoo.com +xuexun.com +xueyanshe.com +xueyiyun.com +xueyou.org +xueyuanjun.com +xueyuhuangjinyan.com +xuezeshi.com +xuezhangbb.com +xuezhangya.com +xuezhao.space +xuezhishi88.com +xuezhiyou.com +xuezhouyi.com +xuezizhai.com +xuezozx.com +xufa315.com +xugaoyang.com +xugt.com +xuguang.net +xuguangwangluo.com +xuhe56.com +xuheen.com +xuhenghandicraft.com +xuhongjx.com +xuhuihs.com +xujc.com +xuji.co +xujianhua.com +xujiepack.com +xujingkj.com +xujinhuancaishui.com +xujun.org +xuka.com +xulaoshi68.com +xuld.net +xulihang.me +xuliutian.com +xumenger.com +xumengwang.com +xumingxiang.com +xumucloud.com +xumurc.com +xumuren.com +xumuzx.com +xun-gou.com +xun321.com +xunbang.com +xunbao178.com +xunbaozhifu.com +xunbf.com +xunbin.com +xunbo.net +xunchabing.com +xunchanggroup.com +xundasemi.com +xundayun.com +xundekai.com +xundiesoft.com +xundns.com +xundns.net +xundupdf.com +xunerjie.com +xunfang.com +xunfeia.com +xunfeib.com +xunfeivr.com +xunfeiwl.com +xunfeixxj.com +xungejiang.com +xungou.com +xungou5.com +xunguagua.com +xunguanggame.com +xunhuai.com +xunhuanshuibeng.com +xunhupay.com +xunhuweb.com +xunicard.com +xunihao.net +xuniquan.com +xunjiecad.com +xunjiefanyi.com +xunjiepdf.com +xunjieshipin.com +xunjietupian.com +xunjk.com +xunkids.com +xunlanchina.com +xunlei.com +xunlei.net +xunleioa.com +xunlew.com +xunliandata.com +xunlianip.com +xunlong.net +xunlong.tv +xunlongsoft.com +xunlu-led.com +xunlugame.com +xunmai888.com +xunmall.net +xunmei.net +xunmeinet.com +xunmengtu.com +xunpaibao.com +xunqinji.net +xunrenzhaoren.com +xunruicms.com +xunruns.com +xunsearch.com +xunshi.cc +xunsho.com +xunshou.com +xunsl.com +xunsn.com +xunsns.com +xunta.mobi +xuntongwuxian.com +xuntou.com +xuntou.mobi +xuntuoguan.com +xunurl.com +xunvision.com +xunw.shop +xunwan.com +xunwangba.com +xunwei.tm +xunweihc.com +xunxi.com +xunxiang.site +xunxu.com +xunyangzaixian.com +xunye1975.com +xunyou.com +xunyou.mobi +xunyouyw.com +xunyuan1314.com +xunyun.com +xunzai.com +xunzhuang.net +xuooo.com +xupai.com +xupea.com +xupernode.com +xupertves.com +xuprinter.com +xupu.name +xupu120.com +xupupifu.com +xuqijt.com +xuqyfw.com +xuruowei.com +xushunda.com +xusplastic.com +xussb.com +xusss.com +xuvol.com +xuweidj.com +xuwenliang.com +xuxian.com +xuxian.me +xuxiang.com +xuxueli.com +xuxusheng.com +xuyalipin.com +xuyangny.com +xuyanmaoyi.com +xuyechem.com +xuyi.net +xuyongrongmei.com +xuyu56.com +xuyueswkj.com +xuyunjt.com +xuzai.com +xuzhi.net +xuzhoufabu.com +xuzhoujob.com +xuzhouma.com +xuzhoumuseum.com +xuzhounano.com +xuzhousports.com +xuzhouwater.com +xuzpazms.com +xv5.com +xvacuum.com +xvcdmo.com +xvista.com +xvizubkg.com +xvjhzuc.com +xvnez.org +xvuikerk.com +xvwprdk.com +xw-chip.com +xw-planning.com +xw-scm.com +xw1806.com +xw360.com +xw365.com +xw501.com +xwabx.com +xwadv.com +xwamp.com +xwan.com +xwb8.com +xwbank.com +xwcbgg.com +xwcx6.com +xwcx666.com +xwcxgroup.com +xweb.vip +xwei.tv +xwfintech.com +xwfls.com +xwfruits.com +xwg.cc +xwgl.cc +xwhb.com +xwhodesign.com +xwhosp.org +xwinvip.com +xwjqr.com +xwjr.com +xwjy.org +xwkjcms.com +xwlcdfactory.com +xwlxw.com +xwmyw.com +xwog.com +xwood.net +xwpbj.com +xwpx.com +xwscg.com +xwshensuofeng.com +xwtcmh.com +xwtele.com +xwuorvhz.com +xwx.mobi +xwxguan.com +xwxwh.com +xwy-powder.com +xwylhh.com +xwyun.net +xwzc.net +xwzxldfx.com +xx-industrial.com +xx-motor.com +xx-sapce.com +xx007.com +xx186.com +xx4a.com +xx5515.com +xx7z.co +xx8g.com +xxahsk.com +xxart.net +xxbiquge.com +xxbmm.com +xxbt.com +xxcang.com +xxccx.com +xxcig.com +xxcipharm.com +xxcmw.com +xxdao.com +xxedu123.com +xxfbiaa.xyz +xxfqc.com +xxgd888.com +xxghh.biz +xxgzz.com +xxhd-tech.com +xxhnanke.com +xxinficity.com +xxingclub.com +xxir.com +xxjdns.com +xxjqgs.com +xxjrjxc.com +xxjzg.com +xxka.com +xxkapp.com +xxkucun.com +xxkxjx.net +xxkxw.net +xxlcn.com +xxlifexx.com +xxliudsp.com +xxlsmqzs.com +xxlwin.com +xxmac.com +xxmyf.com +xxnet.vip +xxnets.net +xxnmjx.com +xxoojoke.com +xxorg.com +xxparking.com +xxpay.vip +xxpie.com +xxpkg.com +xxptcs.com +xxpysc.com +xxqb5200.net +xxqipai.com +xxqun.com +xxqzjt.com +xxrjm.com +xxrmyy.net +xxrsm.com +xxrxfilter.com +xxs8.com +xxsb.com +xxsfjx.com +xxshell.com +xxshu.com +xxspd.com +xxsrmyy.com +xxsy.com +xxsy.net +xxsypro.com +xxszxw.net +xxt139.com +xxtaotao.com +xxtiao.com +xxtjdz.com +xxtlw.com +xxtmail.com +xxw001.com +xxwmy.com +xxwolo.com +xxwxf.com +xxx1577.com +xxxbiquge.com +xxxcsf.com +xxxedu.net +xxxhhh.com +xxxx88xxxx.com +xxxx92xxxx.com +xxxx96xxxx.com +xxxxxx6.com +xxxzzlm.org +xxycw.com +xxyeyan.com +xxyfgy.com +xxyhzd.com +xxykgl.com +xxymdy.com +xxymw.com +xxyo.com +xxys2023.com +xxyw.com +xxyx.ltd +xxyy.co +xxyzh.net +xxzfgjj.com +xxzhushou.com +xxzmz.com +xxzrs.xyz +xxzsgame.com +xy-365.com +xy-asia.com +xy-ddh.com +xy-dgyx.com +xy-display.com +xy-invite.com +xy-mp.com +xy-technology.com +xy007.net +xy120.net +xy1212.com +xy1758.com +xy178.com +xy3000.com +xy36z.com +xy3yy.com +xy58.net +xy599.com +xy980.net +xyb2b.com +xybch123.com +xybhdy.com +xybj365.com +xybsyw.com +xybtv.com +xybygc.com +xybygw.com +xycad.com +xycaogen.com +xycareer.com +xycclass.com +xycdn.net +xycgd.com +xychyy.com +xycloud.com +xyclouds.com +xycms.com +xycsq.com +xyctgroup.com +xycwei.com +xycyky.com +xyda.cc +xydcname.com +xydcname.net +xydhl.com +xydpay.com +xydxcloud.com +xydyfy.com +xydz08.com +xyebbs.com +xyeidc.com +xyeyy.com +xyf6.com +xyfc.com +xyfcw.com +xyffsb.com +xyffvip.com +xyfinechem.com +xyfish.com +xyfsy.com +xyg100.com +xygdcm.com +xygmed.com +xygre.com +xygsjt.com +xygt666.com +xygtea.com +xygulou.com +xygwh.cc +xyh2021.com +xyhc.com +xyhis.com +xyhjd168.com +xyhlcd.com +xyhospital.com +xyhqsh.com +xyhtml5.com +xyhygs.com +xyict.com +xyj.link +xyj321.com +xyj618.com +xyjbglass.com +xyjj99.com +xyjs999.com +xyjtzz.com +xyjuyuan.com +xyjy.net +xyjyjt.com +xyjyy.net +xykgjt.net +xykmovie.com +xyktjt.com +xyl2002.com +xylh888.com +xylhwdu.com +xylink.com +xylive.tv +xylll.com +xylmf.com +xylofh.com +xymfqb.com +xymj.xyz +xymlcs.com +xynbnb.com +xynetweb.com +xyngas.com +xyniubi.com +xynsh.com +xyookj.com +xyous.com +xypifu.com +xyppzx.com +xypse.com +xyqb.com +xyqczy.com +xyqmall.com +xyqy88.com +xyrbszb.com +xyre.com +xyriaf.work +xyrsks.com +xyrtv.com +xysb.com +xysdyrmyygw.com +xyshoppingbag.com +xyshu8.com +xyshuk.com +xysjg.com +xysmart.com +xysstgs.com +xystatic.com +xystoy.com +xyswychgs.com +xysy.com +xysyzx.com +xyszxyy.com +xyt-tech.com +xytcw.vip +xytfy.com +xytiyu.com +xytjcpj.com +xytsoft.com +xytsw.com +xytzg.com +xytzjt.com +xyuncloud.com +xyunjiasu.com +xyunqi.com +xyusk.com +xyvcard.com +xyvcpe.com +xyvend.com +xyvending.com +xyw-wifi.com +xyw.com +xywclass.com +xywlhlh.com +xywm.com +xywy.com +xywyfw.com +xywzs.com +xyx234.com +xyx3d.com +xyxcables.com +xyxdie.com +xyxrmt.com +xyxsc.com +xyxsns.com +xyxsw.ltd +xyxww.com +xyxy.net +xyxyzz.com +xyxza.com +xyy001.com +xyyao.com +xyyb.net +xyybs.com +xyydnode.com +xyyh.xyz +xyyksy.com +xyykt.org +xyyl.com +xyyuan.fun +xyyuedu.com +xyyx82.com +xyyy999.com +xyyzi.com +xyz-jm.com +xyz1412.net +xyzcdn.net +xyzcn.com +xyzdict.com +xyzdns.xyz +xyzele.com +xyzfm.link +xyzfm.space +xyzggg.com +xyzimo.com +xyzkj.xyz +xyzmdzs.com +xyzmovie.net +xyzop.com +xyzs.com +xyzshouji.com +xyzspeaker.com +xyzsq.com +xyzttt.xyz +xyzvo.com +xyzywl.com +xz-juming.com +xz-soft.com +xz.com +xz325.com +xz3733.com +xz3z.com +xz6.com +xz6699.com +xz66gxnnjyl.com +xz6y.com +xz7.com +xz7899.com +xz8.com +xzairport.com +xzaz.com +xzb360.com +xzbaorun.com +xzbco.com +xzbhfk.com +xzbu.com +xzbzq.com +xzcblog.com +xzcbxg.com +xzccjt.com +xzcdc.com +xzcet.com +xzcjyjt.com +xzcoder.com +xzcr.com +xzcykg.com +xzdabyw.xyz +xzdag.com +xzdfcd.com +xzdfyy.com +xzdtjt.com +xzep.net +xzepa.com +xzfenghe.com +xzfesco.com +xzfhhz.com +xzfile.com +xzfwzl.com +xzgdsf.com +xzggjyzpw.com +xzgj.com +xzgjj.com +xzgqm.com +xzgtjt.com +xzgxwq.com +xzhh966888.com +xzhhbfesco.com +xzhichang.com +xzhizao.com +xzhlz.com +xzhome.com +xzhpck.com +xzhyjsjt.com +xzhzkd.com +xzis.org +xzjhgt.com +xzjiufa.com +xzjsxy.com +xzjtkg.com +xzjy.net +xzkd.com +xzking.com +xzkssb.com +xzksyy.com +xzkwjtzyy.com +xzkx.com +xzldbl.com +xzlgjt.com +xzlogo.com +xzlres.com +xzlsqy.com +xzltrq.com +xzltzc.com +xzlzf.com +xzm56.com +xzmai.com +xzn56.com +xznqcc.com +xznqnews.com +xzoo.org +xzpf110.com +xzpm.com +xzpoll.com +xzport.com +xzpxrc.com +xzqh.org +xzqixing.com +xzqrmyy.com +xzqxj.com +xzrbw.com +xzrcfc.com +xzrcyy.com +xzrdwq.com +xzriit.com +xzsckj.com +xzsdszx.com +xzsdyyy.com +xzsec.com +xzsis.com +xzskfyy.com +xzsmartmetro.com +xzsmlq.com +xzsnw.com +xzstatic.com +xzsthj.com +xzsw.net +xzswjt.com +xzszb.net +xzszjt.com +xztcm.com +xztdesign.com +xztsjf.com +xztzb.com +xzuan.com +xzw.com +xzw.pw +xzwanda.com +xzwhg.com +xzwhlyjt.com +xzwy.com +xzwyxh.com +xzx.com +xzxjkyy.com +xzxkjd.com +xzxw.com +xzxx.com +xzxxlcp.com +xzyhealth.com +xzyjl.com +xzynyy.com +xzzh.com +xzzhbsq.com +xzzhongye.com +xzzhtc.com +xzzlyy.com +xzzp.net +xzztly.com +xzzulin.com +y-feng.com +y-i-y.com +y-lotus.com +y-os.net +y.to +y007.com +y1995.com +y1v.com +y2002.com +y2374050fo.com +y2531.com +y3pm.com +y4rwk6v8s41kr.com +y5000.com +y55l6.com +y56.com +y5663.com +y5api.com +y5coin.com +y5kfpt.com +y5news.com +y5store.com +y617.com +y66b1pi5re.com +y67.net +y70qeg6506.com +y77.cc +y78r.com +y80s.com +y8cyx6fvyxk3hs.com +y8kj95k62v.com +y8l.com +y92ft2vz.com +ya-bo888.com +ya-marathon.com +ya17.com +ya19si8.lol +ya247.com +yab44.com +yabais.com +yabaite.com +yabandpay.com +yabang-qhpharm.com +yabet03.com +yabet08.com +yabet888.com +yabet99.com +yabo.com +yabo00.com +yabo0000.com +yabo016.com +yabo023.com +yabo063.com +yabo072.com +yabo077.com +yabo083.com +yabo085.com +yabo098.com +yabo159.com +yabo170.com +yabo189.com +yabo199.com +yabo2025.com +yabo552.com +yabo593.com +yabo602.com +yabo64.com +yabo6600.com +yabo691.com +yabo70.com +yabo75.com +yabo7755.com +yabolive.com +yaboo-cn.com +yaboshi0777.com +yabyy.com +yac8.com +yace17.com +yach.me +yachtsinchina.com +yacol.com +yacou.net +yacto-tech.com +yadancoffee.org +yadao8.com +yadashi.com +yadatong.net +yadilite.com +yadingtour.com +yadongjf.com +yadran.com +yadugroup.com +yadunyun.com +yaduo.com +yaeherhealth.com +yaersen.com +yaexun.com +yaeyy.com +yafangyiyuan.com +yafco.com +yafdev.com +yafeilinux.com +yafshb.com +yago-mall.com +yahacode.com +yahaha.net +yahaizi.com +yahanmr.com +yahboom.com +yahong-mold.com +yahoo001.com +yahuayunshu.com +yahuhost.com +yahui.cc +yahui.hk +yahuishou.com +yahunet.com +yahxxcl.com +yaimg.com +yaitest.com +yaiyuan.com +yajxc.com +yake123.com +yake5.com +yakgamer.com +yakjhfh.com +yakool.com +yakup.info +yalayi.com +yalewoo.com +yalianedu.com +yaliaojie.com +yalikongzhi.com +yaling8.com +yalishiyanji.com +yalj.net +yalongbay.net +yalqq8976.com +yamaijia.net +yameisj.com +yamibo.com +yamoke.com +yan-grh.com +yan-jian.com +yan678.com +yanagou.net +yananpharm.com +yanbaike.com +yanbaohui.com +yanbaolong.com +yanbeige.com +yanbinghu.com +yanbm.com +yanbmn.com +yanboyuan.com +yance.wiki +yanchebang.com +yancheng-culture.com +yanchengdj.com +yanchengjtgz.com +yanchengzx.com +yanchupiao.com +yanchupiaojia.com +yanchupiaowu.com +yandaco.com +yandianying.com +yanding.com +yanduyiyuan.com +yanedu.com +yanfabu.com +yanfen.online +yanfeng.com +yanfengauto.com +yanfukun.com +yang99.fun +yangbentong.com +yangbinlvshi.com +yangchanji.com +yangchenghudzx.com +yangchenglianhe.com +yangcheyongche.com +yangchunjian.com +yangcong.com +yangcong345.com +yangcongchufang.com +yangdongjia.com +yangfannie.com +yanggang-group.com +yanggeng.com +yanggu.tv +yangguangxinye.com +yangguanjun.com +yangguiweihuo.com +yanghd.com +yanghong.art +yanghuaxing.com +yangji.com +yangjibao.com +yangjie.li +yangjigroup.com +yangjinyou.com +yangjisen.com +yangk6668.com +yangkeduo.com +yangki.net +yangkun.net +yanglaocn.com +yanglaofuwu365.com +yanglaotiandi.com +yanglee.com +yangli.com +yangliping.com +yangliq.com +yanglong.pro +yangluojob.com +yangmao.info +yangmi.net +yangmingauction.com +yangner.com +yangnongchem.com +yangoo-global.com +yangpanzg.com +yangqi.show +yangqianguan.com +yangqimanhua.com +yangqq.com +yangqu.com +yangsam.com +yangsan.work +yangsensheng.com +yangshengliang.com +yangshengtang123.com +yangshengtv.com +yangshijz.com +yangshuolvyou.com +yangsihan.com +yangstandards.com +yangtai.com +yangtaiapp.com +yangtao.site +yangtaolujiu.com +yangtengfei.com +yangtianb.com +yangtong.com +yangtse-automobile.com +yangtse.com +yangwajia.com +yangwang.pw +yangwangauto.com +yangwc.com +yangwenlong.org +yangwenqing.com +yangxiang.com +yangxiangdb.com +yangxingzhen.com +yangxinren.com +yangyangad.com +yangyangla.com +yangyanxing.com +yangyi.vip +yangyi02.com +yangyi08.com +yangyi09.com +yangyi13.com +yangyi19.com +yangyingming.com +yangyivacuum.com +yangyongquan.com +yangyq.net +yangzhe1991.org +yangzhengfang.com +yangzhi777.com +yangzhihb.com +yangzhiriji.com +yangzhix.com +yangzhongchao.com +yangzhoutuozhan.com +yangzhouyiyuan.com +yangzhu360.com +yangziclean.com +yangzijiang.com +yangziwater.com +yangzw.vip +yanhaijing.com +yanhuamedia.net +yanhuoidc.com +yaniu.net +yanjiao.com +yanjiaoapp.com +yanjiaoweixin.com +yanjinews.com +yanjingge.com +yanjiubaogao.com +yanjiuchubanshe.com +yanjob.com +yanjun7858.com +yankay.com +yanke360.com +yankon.com +yankong.com +yanliang.com +yanliaofang.work +yanlong.shop +yanmaiyingyu.com +yannv.com +yanoda.com +yanpengjk.com +yanpk.com +yanqiao.com +yanqingshan.com +yanqueai.com +yanrongyun.com +yanshanmuyuan.com +yanshanpump.com +yanshaoutlets.com +yanshihua.com +yanshimei.com +yanshishuo.com +yanshuoshi.com +yansx.com +yanta.cc +yantai-chuanpiao.com +yantaibank.net +yantaihr.com +yantaijintai.com +yantailuoshuan.com +yantaiport.com +yantaitech.com +yantan.cc +yantangmilk.com +yantao.wiki +yantaparking.com +yantaqu.com +yantian-port.com +yantu360.net +yantubao.com +yantubbs.com +yantuchina.com +yantudq.com +yanue.net +yanweihappybirthday.com +yanwugroup.com +yanxian.org +yanxianggroup.com +yanxintong.com +yanxishe.com +yanxiu.com +yanxizhu.com +yanxurui.cc +yanyapeng.com +yanyib2b.com +yanyidakaoyan.com +yanyijingling.com +yanyin.tech +yanyiquan.com +yanyiwu.com +yanyizc.com +yanyue.net +yanyunmail.com +yanzhaorc.com +yanzhaowang.com +yanzhihuisc.com +yanzhiwu.com +yanzhoulugang.com +yao.com +yao123.com +yao51.com +yaobo.net +yaocai.com +yaocaicang.com +yaocaizhongzi.com +yaocdn.com +yaochengwang.com +yaochentech.com +yaochixie.com +yaochufa.com +yaocsoft.com +yaodou.net +yaodu365.com +yaoex.com +yaofangwang.com +yaofangwang.net +yaofei365.com +yaoge123.com +yaoguo.com +yaohaixiao.com +yaohuaglass.net +yaohuascape.com +yaohuiji.com +yaohuo.me +yaohuo168.com +yaoji.center +yaojibuyu.com +yaojidsfee.com +yaojiedianzi.com +yaojigames.com +yaojiuqq.com +yaokaihui.com +yaokantv.com +yaokeke.com +yaoky.com +yaolaifen.com +yaolan.com +yaolandairy.com +yaoliangmi.com +yaoliwang.com +yaolue.com +yaolutong.com +yaoluu.com +yaomai666.com +yaomaiche.com +yaoman.net +yaomv.com +yaonano.com +yaooxx.space +yaopaiming.com +yaopharma.com +yaopinlenglian.com +yaopinnet.com +yaoq.net +yaoqing.com +yaoqun.net +yaosai.com +yaoshagroup.com +yaoshanly.com +yaoshimiaolianhua.com +yaotia.com +yaotiannano.com +yaotongjn.com +yaotou.com +yaoudq.com +yaoujc.com +yaowan.com +yaoxiaoyi.com +yaoxuebang.com +yaoxun.net +yaoyaola.net +yaoyedan.net +yaoying.vip +yaoyouke.com +yaozh.com +yaozhigong.com +yaozhizhu.com +yaozs.com +yaozui.com +yapingkeji.com +yapingtech.com +yapp.com +yaqilian.com +yaqjyj.com +yaristyle.com +yarncm.com +yarward.com +yasee-zs.com +yashili.com +yashowmarket.com +yasishuo.com +yasiyasi.com +yasking.org +yasn.com +yasudachem.com +yasuotu.com +yasyy.com +yatai.com +yataidianli.com +yataifr.com +yataiinsur.com +yatailx.com +yataimall.com +yataioa.com +yataohome.com +yatebizhi.com +yaterv.com +yatiku.com +yatiwang.com +yato-sh.com +yatsenglobal.com +yatsoft.com +yatv.tv +yatyjx.com +yaucn.com +yauuy.com +yawancaiwu.com +yawbbs.com +yawei.cc +yaweijituan.com +yawen8.com +yawy.cc +yaxi.net +yaxiaodong.com +yaxige.com +yaxin888.com +yaxinde.com +yaxinghbkj.com +yaxuntuhang.com +yaya.love +yayaad.com +yayagushi.com +yayawan.com +yayeschool.com +yayihouse.com +yayiskq.com +yayitianyun.com +yayiyun.net +yayjrj.com +yayouapp.com +yaypool.com +yayu.net +yayunjiqi.com +yazhihg.com +yazhijian.com +yazhougoufang.com +yazuo.com +yazx.net +yb-able.com +yb1518.com +yb1867.com +yb3.cc +yb983.com +yb999.com +yba120.com +ybaby.com +ybaobx.com +ybaomall.com +ybbwy.com +ybbxkj.com +ybc1024.com +ybc35.com +ybccb.com +ybccode.com +ybcheck.com +ybchen.work +ybcjmarathon.com +ybcnjg.com +ybcxjd.com +ybcxz.com +ybdbz.com +ybdlogistic.com +ybe.net +ybgkz.com +ybgz.com +ybhdmob.com +ybi.net +ybirds.com +ybj.com +ybjjsgc.com +ybjsk.com +ybk001.com +ybk168.com +ybk6.com +yblc.com +yblcs.com +yblry.com +ybm100.com +ybmedicine.com +ybmilkgoat.com +ybqysw.com +ybrc128.com +ybren.com +ybs120.com +ybscjp.com +ybscpqtlxx.com +ybsftd.com +ybsjyyn.com +ybstjs.com +ybstwl.com +ybt168.com +ybtianshantu.com +ybtvyun.com +ybty.com +ybvip.com +ybvips.com +ybvv.com +ybw315.com +ybword.com +ybxww.com +yby1953.com +ybyiot.com +ybynet.com +ybypark.com +ybzhao.com +ybznzz.com +ybzzgh.org +yc-exp.com +yc-gc.com +yc-petronas.com +yc-yinhe.com +yc-zj.com +yc0917.com +yc123.com +yc123.net +yc12313.com +yc222.com +yc2e.com +yc360.org +yc370.com +yc8.com +yc9y.com +ycait.com +ycamlyy.com +ycandyz.com +ycangels.com +ycaqr.com +ycb.com +ycbiz.net +ycbright.com +ycbroker.com +ycbus.com +ycc.ink +yccdl.net +yccn.cc +ycd-hk.com +ycdext.net +ycdfby.com +ycdfwater.com +ycdongxu.com +ycdrh.com +ycdryy.com +ycduile.com +ycdz.shop +ycdzcc.com +yceshop.com +ycfang.net +ycfanglei.com +ycfbapp.com +ycfggc.com +ycfog.com +ycfybj.com +ycfybjy.com +ycgame.com +ycgj.cc +ycgjxx.com +ycgslb.com +ycgwl.com +ycgzgame.com +ychanfang.com +ychcqmu.com +ychdzxsh.com +ychr.com +ychromedgeie.com +ychszh.com +ychxie.com +ychxiex.com +ycig.com +ycigilink.com +yciou.com +ycis-bj.com +ycis-cq.com +ycis-schools.com +ycis-sh.com +yciyun.com +ycjhjsbyy.com +ycjingweiranqi.com +ycjintou.com +ycjinze.com +ycjklrq.com +ycjljt.com +ycjob.com +ycjsxy.com +ycjt2007.com +ycjyjt.com +ycjzzsw.com +yckceo.com +yckceo.vip +yckjzsq.com +yckkdd.com +ycku.com +ycleaning.com +yclh6.com +ycloud.online +ycloudlb.com +ycloudvip.com +yclyq.com +ycmae.com +ycmlaw.com +ycmm.com +ycnaxin.com +ycnevpds.com +ycny.com +ycoa0898.com +ycool.com +ycpack.net +ycpai.com +ycpec.com +ycphkj.com +ycpinke.com +ycpsy.com +ycqin.com +ycqq.com +ycrcrs.com +ycrcw.net +ycrh.com +ycrkb.com +ycrusher.com +ycrx360.com +ycrysw.com +ycs120.com +ycscszh.com +ycsd.work +ycsdryy.com +ycsdyyy.com +ycshengquan.com +ycsjtjt.com +ycsound.com +ycsrc.com +ycsthqrmyy.com +ycsystem.com +ycsyy.com +yct-tec.com +yctdyy.com +yctxrj.com +ycty.org +yculblog.com +ycur.net +ycwalker.com +ycwb.com +ycwljt.com +ycxba.com +ycxdryy.com +ycxicmall.com +ycxiezhu.com +ycxinxi.com +ycxm.com +ycxskw.com +ycxy.com +ycxzlsyxgs.com +ycyaw.com +ycyck.com +ycycut.com +ycyhzx.com +ycyjkj.com +ycym.com +ycypin.com +ycyunyuk.com +ycyz.com +ycyzwb.net +yczbw.com +yczfwy.com +yczihua.com +yczjkfyy.com +yczk.org +yczpw.com +yczxyy.com +yczy5.com +yd-data.com +yd-jxt.com +yd-power.com +yd-tec.com +yd166.com +yd43s2q51b.com +ydadmob.com +ydalison.com +ydamc.com +ydayc.com +ydbimg.com +ydbmed.com +ydbox.com +ydc360.com +ydcb.com +ydce.com +ydcloud.cc +yddsha2.com +yddtiyu.com +yddxkj.com +ydfeathers.com +ydfgq.com +ydgj2727.com +ydguolan.com +ydh.fun +ydhex.com +ydhexpress.com +ydhjj.com +ydhl.cc +ydhlaz11151.com +ydhn.com +ydht.com +ydhyfs.com +ydihi.com +ydimmi.com +ydjdcjc.com +ydjt1166.com +ydjt2288.com +ydjwy.net +ydjy.net +ydkj2019.com +ydl-sh.com +ydl.com +ydlcdn.com +ydlut.com +ydmel.com +ydmeng.com +ydn5.com +ydnewmedia.com +ydniu.com +ydr.me +ydsaso.com +ydscan.net +ydsjjs.com +ydsjpt.com +ydsrmyy.com +ydstatic.com +ydsyyy.com +ydt-express.com +ydt.link +ydtad.com +ydtbl.com +ydtnotary.com +ydtqd.com +yduav.com +ydvip00aa.com +ydvip00ab.com +ydvip00ac.com +ydvip00ad.com +ydvip00ae.com +ydvip00af.com +ydvip00ag.com +ydvip00ah.com +ydvip00ai.com +ydvip00aj.com +ydvip00ak.com +ydvip00al.com +ydvip00am.com +ydvip00an.com +ydvip00ao.com +ydvip00ap.com +ydvip00aq.com +ydvip00ar.com +ydvip00as.com +ydvip00at.com +ydwatch.com +ydwgame.net +ydx2.com +ydxphb.com +ydxrf.com +ydxxt.com +ydyb.com +ydycdn.com +ydyeducation.com +ydyj.net +ydylcn.com +ydyljk.com +ydylmtytv.com +ydyspc.com +ydywh.shop +ydyy120.com +ydzxyjhyy.com +ydzz.com +ye1992.com +ye3.com +ye40.com +yead.net +yeah.net +yeahka.com +yeahnic.net +yeahteen.com +yeahworld.com +yeai.com +yealink.com +yealinkvc.com +yeaosound.com +yeapcloud.net +yearlygreen.com +yearnfar.com +yeastar.com +yeasturias.com +yebaike.com +yebangyu.org +yebaojiasu.com +yebinnet.com +yeboyzq.com +yebrewing.com +yecao.net +yecaoyun.com +yecdn.com +yechangktv.com +yechengmuye.com +yedanguan365.com +yedapi.com +yedarc.com +yedejia.com +yedingding.com +yedone.com +yeduxiaoshuo.com +yee5.com +yee800.com +yeeanbao.com +yeeaoo.com +yeeauto.com +yeecai.com +yeecin.com +yeecloud.com +yeedian365.com +yeefeitrip.com +yeefire.com +yeefung.com +yeefx.net +yeekang.com +yeekit.com +yeelight.com +yeelink.net +yeelogo.com +yeemei.com +yeemen.com +yeemiao.com +yeemiao.net +yeepay.com +yeepaycdn.com +yeepbank.com +yeepiao.com +yeesha.com +yeetan.com +yeeuu.com +yeewo.net +yeeyan.com +yeeyan.org +yeezon.com +yefengs.com +yegame.com +yegaochemical.com +yegenyou.com +yegoo.com +yegrand.com +yegu168.com +yeguohd.com +yehoochina.com +yehuisteel.com +yeidc.com +yeitu.com +yejiangye.com +yejibang.com +yejienet.com +yejuu.com +yekyc.com +yelanxiaoyu.com +yelinmall.com +yelishi.net +yelixiali.com +yellowriver.org +yelook.com +yelot.com +yemacaijing.com +yemadai.com +yemajun.com +yemancomic.com +yemaosheji.com +yemaosoft.com +yemayun.com +yemeihuoguo.com +yemeisy.com +yemengstar.com +yemet.com +yemhj.com +yenlex.com +yentechnology.com +yeoebyevhq.com +yeolar.com +yeoner.com +yepaisz.com +yephy.com +yeren86.com +yergoo.com +yes-chinese.com +yes-lcd.com +yes58.net +yes88.com +yesacc.com +yesapi.net +yesbt.cc +yesbx.com +yeschool.net +yescontrols.com +yesdotnet.com +yesense.com +yeshen.com +yeshengarts.com +yeshine.net +yeshitv.com +yeshj.com +yeshu.cloud +yeshu.com +yesidos.com +yesilicon.com +yeskn.com +yesky.com +yeslicake.com +yesmyimg.com +yesmywine.com +yesonfashion.com +yesou.com +yesoulchina.com +yespearl.com +yespik.com +yespmp.com +yestar.com +yestar1992.com +yestarcorp.com +yestargz.com +yestarm.com +yestarvip.com +yestehotel.com +yeston.net +yestone.com +yesudoo.com +yesungroup.com +yesuse.net +yeswan.com +yeswood.com +yesxun.com +yetaidrink.com +yetianlian.cc +yetianlian.info +yetianzi.com +yettos.com +yetu.net +yewanba.com +yewen.us +yewuyuan.com +yexinggroup.com +yeyday.com +yeyezhenxuan.com +yeyimg.com +yeyingkf.com +yeyo.cc +yeyou.com +yeyoucdn.com +yeyoujia.com +yeyousg.com +yeyulingfeng.com +yeyun.com +yezaifei.com +yezhuwq.com +yezhuwuyou.com +yezi66.xyz +yeziapp.com +yezipi.net +yeziting.com +yezixigame.com +yezixueyuan.com +yezizhu.com +yezizx.com +yf-ec.com +yf-zs.com +yf0008168.com +yf520.com +yf77.com +yfanad.com +yfanqie.com +yfbudong.com +yfbzb.com +yfcache.com +yfcalc.com +yfcdn.net +yfchuhai.com +yfcity.net +yfcloud.com +yfcloud.io +yfcloud.work +yfd.xyz +yfdc.net +yfdns.net +yfds168.com +yfdts.net +yfdurl.com +yfdurl0.com +yfdurl1.com +yfdurl10.com +yfdurl11.com +yfdurl12.com +yfdurl13.com +yfdurl14.com +yfdurl15.com +yfdurl16.com +yfdurl17.com +yfdurl18.com +yfdurl19.com +yfdurl2.com +yfdurl20.com +yfdurl3.com +yfdurl4.com +yfdurl5.com +yfdurl6.com +yfdurl7.com +yfdurl8.com +yfdurl9.com +yfdxs.com +yfdyf.com +yfemj.com +yffood.com +yffy120.com +yffzkl.com +yfgg.com +yfgj68.com +yfhex.com +yfhhf.com +yfhl.net +yfhospital.com +yfhxtech.com +yfinds.com +yfiot.com +yfisher.com +yfjiakao.com +yfjnjc.com +yfklxz.com +yflcloud.online +yfldocker.com +yflive.net +yfm99.com +yfmac.com +yfmhgf.com +yfmhw.com +yfp2p.net +yfpayment.com +yfsafety.com +yfsail.net +yfscdn.com +yfscdn.net +yfservice.com +yfsteel.com +yfswjt.com +yfswny.com +yftxt.com +yfty88.com +yfvb.com +yfway.com +yfwnm.com +yfworld.com +yfwpt.vip +yfwqlij.xyz +yfycrc.com +yfycyboil.com +yfygxyy.com +yfyky.com +yfysjt.com +yg-pump.com +yg-st.com +yg1997.com +yg84.com +yg8898.com +ygbid.com +ygbx.com +ygc711iq.com +ygcgfw.com +ygcloud.com +ygcooler.com +ygct.com +ygdatabase.com +ygdl.com +ygdy8.net +yge.me +ygeer.com +ygei.com +yget.me +ygfengshui.com +ygfmlt.com +yggk.net +yghsh.com +ygibao.com +yginsight.com +ygjctech.com +ygjj.com +ygjoy.com +ygmsy.com +ygread.com +ygrtt.com +ygsdmedia.com +ygsf.com +ygsoft.com +ygtape.com +ygtcpa.com +ygtf.net +ygtiyu.com +ygtl.com +ygtq.net +ygvyp.com +ygwenxue.com +ygwh.cc +ygwood.com +ygx8888.com +ygxy.com +ygym.org +ygzt.net +yh-group.com +yh0.com +yh2000.com +yh31.com +yh596.com +yh598.com +yh914.com +yh99.cc +yh999999.com +yhaabva.com +yhachina.com +yhadmob.com +yham.net +yhc-card.com +yhcangchu.com +yhchj.com +yhchn.com +yhcjcw.com +yhcko.com +yhcmovie.com +yhcplatform.com +yhcqw.com +yhd.com +yhdd365.shop +yhdfa.com +yhdi.net +yhdlcs.com +yhdm5.com +yhdns.net +yhedu.com +yhees.com +yhgdiopn.vip +yhgfb-cn-static.com +yhggroup.com +yhgmjf.com +yhgzjt.com +yhhh8888.com +yhhjcc.com +yhhotel.com +yhidc.com +yhindustrial.com +yhj9.com +yhjbox.com +yhjcollege.com +yhjj.com +yhjktgfd.cc +yhjx2018.com +yhkaq.com +yhkbchao.com +yhkingdee.com +yhkz.com +yhlbx.com +yhly.shop +yhm11.com +yhmob.com +yhmsfc.com +yhmyi.com +yhpackaging.net +yhppk.com +yhqapp.com +yhqdashi.com +yhqh.net +yhqrmyy.com +yhquan365.com +yhqurl.com +yhrcb.com +yhrjk.com +yhrongde.com +yhrsks.com +yhs518.com +yhsc.com +yhshapp.com +yhsms.com +yhsp.net +yhsport.com +yhstjt.com +yhtclb.com +yhthing.com +yhtools.cc +yhtx.tv +yhtzx.net +yhurl.com +yhwch.com +yhwins.com +yhwjlp.plus +yhwomen.com +yhx3318.com +yhxincai.com +yhxmset.com +yhxs3344.net +yhxuexiao.com +yhydl.com +yhyhwy.com +yhylc71.com +yhyyjk.com +yhz2000.com +yhz365.com +yhz66.com +yhzky.net +yhzky1.net +yhzm.com +yhzrt.com +yhzuche.com +yi-fengshui.com +yi-hall.com +yi-i.com +yi-jy.com +yi-oa.com +yi-programmer.com +yi-sky.com +yi-you.org +yi-zhifu.com +yi-zhou.com +yi020.com +yi0600.com +yi114.com +yi2.net +yi6.com +yi7.com +yi958.com +yiai.me +yiaini.com +yiandrive.com +yianjiulao.com +yiapp.com +yibaijin.com +yibaixun.com +yiban.io +yiban1314.com +yibaogao.com +yibaojiankang.com +yibaotech.com +yibei.com +yibeiic.com +yibeiwangluo.com +yibenmanhua.com +yibentushu.com +yibiao-sh.com +yibite.com +yiboard.com +yiboliu.com +yiboow.com +yiboshi.com +yibotec.com +yiboyangguang.com +yicai.com +yicaiai.com +yicaiexpo.com +yicaiglobal.com +yicaihua.com +yicaiykt.com +yicamp.com +yicang.com +yicanggongyi.com +yicbo.com +yice11.com +yicha-yc.com +yichadan.com +yichafen.com +yichangly.com +yichangmarathon.com +yiche.com +yichemall.com +yichengfood.net +yichengji.com +yichengnews.com +yichengwangluo.net +yicheshi.com +yichezhi.com +yichi.tech +yichip.com +yichuan.net +yichuntv.com +yichuyifan.com +yickd.com +yiclear.com +yicloud.org +yicode.tech +yicoe.com +yicongfound.org +yiconmed.com +yicuba.com +yicungn.com +yicx.com +yida6666.com +yidaba.com +yidachem.com +yidachina.com +yidadrillcollar.com +yidagas.com +yidahospital.com +yidai.com +yidaidai.com +yidaointernational.com +yidaomall.com +yidaomobi.com +yidaplay.com +yide.com +yideamobile.com +yidejia.com +yidengxuetang.com +yidian-inc.com +yidian360.com +yidian51.com +yidiancangwei.com +yidianchina.com +yidianda.com +yidianedu.com +yidianfenqi.com +yidianhulian.com +yidianliangdiansandiansidianwudianliudianqidianbadianjiudianshi.com +yidianling.com +yidianliulan.com +yidianmail.com +yidiansz.com +yidianting.xin +yidianyuan-wawa.com +yiding-gr.com +yidingbao.shop +yidingding3.com +yidmall.com +yidns.net +yidong-food.com +yidonghua.com +yidongtimes.com +yidontek.com +yidoutang.com +yidouzhaofang.com +yidu-marathon.com +yidubbs.com +yiduchuan.com +yidui.me +yiduir.com +yidulive.com +yidumen.com +yidun.com +yiduoli.com +yiduoxinya.com +yiduqiang.com +yiduwater.com +yiec.com +yiernews.com +yiexi.com +yifajingren.com +yifake.com +yifan211.com +yifancdn.com +yifancn.com +yifanggl.com +yifanghy.com +yifanmedia.net +yifanshangplus.com +yifanyy.com +yifatong.com +yifei.com +yifei.space +yifeigufen.com +yifeimeiye.com +yifeishu.com +yifeng-filter.com +yifeng-mover.com +yifeng.com +yifenghudong.com +yifengke.com +yifengliangyou.com +yifengx.com +yifengxin.org +yifont.com +yifu.net +yifubao.com +yifucj.com +yifum.com +yifum.hk +yifum.net +yifutu.com +yigaosu.com +yige.org +yigeban.com +yigecun.com +yigerlife.com +yigomob.com +yigongdcs.com +yigonghl.com +yigood.net +yigoonet.com +yigouu.com +yiguanba.com +yiguanghuagong.com +yiguo.com +yiguoimg.com +yihafo.com +yihaikerry.net +yihaiquanyi.com +yihaishijia.com +yihang.info +yihao.com +yihao01.com +yihaocar.com +yihaodian.com +yihaodianimg.com +yihaoduozhongduan.com +yihaojiaju.com +yihaomall.com +yihaomen.com +yihaoranjd.com +yihaoyunche.com +yihchina.com +yiheda.com +yihedoors.com +yihegroup.com +yihekf.com +yihengyt.com +yiherubber.com +yihong001.com +yihong1718.com +yihtc.com +yihu.com +yihu365.com +yihuacomputer.com +yihuajiaoyu.com +yihuan.org +yihuanjt.com +yihubaijia.com +yihubg.com +yihuichuang.com +yihuikeji.vip +yihuimg.com +yihuiyun.net +yihun.com +yihuohao.com +yiibai.com +yiichina.com +yiigle.com +yiihuu.com +yiii.net +yiimoo.com +yiinet.net +yiiwo.com +yijia-ai.com +yijia.com +yijia.ink +yijia5.com +yijiakao.com +yijian-app.com +yijian119.com +yijiande.com +yijiangbao.com +yijianjiexi.com +yijianlogo.com +yijianqutu.com +yijianzj.com +yijiaqin.com +yijiaren3413.com +yijiawang.com +yijiebuyi.com +yijiedai.com +yijimaoyi.com +yijinghong.com +yijingji.com +yijingxiehui.net +yijintong.net +yijirecovery.com +yijiupi.com +yijiuplus.com +yijueculture.com +yijuedesign.com +yijueweb.com +yijun77.com +yikag.com +yikai.com +yikaiye.com +yikaiye.net +yikang.work +yikang1977.com +yikangdongf.com +yikanxs.com +yikaoapp.com +yikaochacha.com +yikaow.com +yikebus.com +yikedou.com +yikeou.com +yiketalks.com +yiketianqi.com +yikeweiqi.com +yikexue.com +yikezhengxing.com +yikouhy.com +yikuaide.com +yikuaiqu.com +yikuaixiu.com +yikuns.com +yikuyi.com +yilandezhong.com +yilantop.com +yilanvaas.com +yile8.com +yilewan.com +yileweb.com +yileyiqi.com +yileyoo.com +yileyunssp.com +yili.com +yilianapp.com +yilianmeiti.com +yilianyixue.com +yiliaosheji.com +yilibabyclub.com +yilicar.com +yiliganggou.com +yilihuo.com +yiliit.com +yilijet.com +yilikim.com +yilingarden.com +yilingshop.com +yilingsj.com +yilinweb.com +yiliqqstar.com +yilishiji.com +yiliwater.com +yiliysr.com +yillionbank.com +yilong.com +yilongnews.com +yilongweiguo.com +yilu365.com +yilule.com +yiluzouhao.com +yilvcheng.com +yima.world +yima88.com +yimaitongdao.com +yimakk.com +yimao.net +yimaoip.com +yimapay.com +yimashijie.com +yimeichu.com +yimeihui360.com +yimeima.com +yimeiya.com +yimenapp.com +yimenapp.net +yimeng.com +yimenonline.com +yimenseo.net +yimenssl.com +yimian.xyz +yimianmian.com +yimiaotui.com +yimiaoxia.com +yimidida.com +yimifund.com +yimihaodi.com +yimin.biz +yimin168.com +yimingcul.com +yimingkeji.net +yimingroup.com +yimingzhi.net +yimininfo.com +yiminjiayuan.com +yiminw.com +yiminyy.com +yimisoft.com +yimitongxue.com +yimiyisu.com +yimuapp.com +yimudoor.com +yimutian.com +yimuymc.com +yinbaitu.com +yinban.com +yinbangbroker.com +yinbian.cc +yinbin.ink +yincat.com +yinchar.com +yinchenglawyer.com +yinchengli.com +yinchengpai.com +yinchuanwater.com +yinchuanzxd.com +yindon.com +yindu.com +yinduchina.com +yindudigital.com +yindui.net +yindunjituan.com +yinduzx.com +yineitong.com +yinengjituan.net +yinengkt.com +yinengwl.com +yinerda.com +yinfeiy.com +yinfenggr.com +ying-sw.com +ying-ting.com +yingbei365.com +yingbio.com +yingbozhu.org +yingcai.cc +yingcaicheng.com +yingcankeji.com +yingchao-wikipedia.com +yingchaozhibo.com +yingcheng.net +yingchengnet.com +yingchuang.com +yingchulawyer.com +yingci86.com +yingdao.com +yingde.com +yingdev.com +yinge.cc +yinge.tech +yingeda.com +yingeye.com +yingfangkeji.com +yingfeiyun.com +yingfeng.me +yinggou.com +yingguangroup.com +yingguantx.com +yinghai.work +yinghaicar.com +yinghanhuyi.com +yinghecloud.com +yingheedu.com +yingheying.com +yinghezhong.com +yinghuaonline.com +yinghuasuan.com +yinghuiiot.com +yinghuo.art +yinghuochong.com +yinghuochong.fun +yinghuochongjz.com +yinghuodd.com +yingjia360.com +yingjianzhijia.com +yingjiesheng.com +yingjiesheng.net +yingjiesheng.org +yingjimall.com +yingjinhk.com +yingke010.com +yingkefuli.com +yingkelawyer.com +yingkounews.com +yingle.com +yingleku.com +yinglib.com +yingligroup.com +yinglisolar.com +yingliugroup.com +yinglunka.com +yingmei.me +yingmi.com +yingming.net +yingnor.com +yingpaigame.com +yingpaikeji.com +yingpengbz.com +yingpost.com +yingriliuti.com +yingrongit.com +yingshe.com +yingsheng.com +yingshi-ai.com +yingshiyou.com +yingso.fun +yingsoft.com +yingsoo.com +yingsun.net +yingsx.com +yingt.asia +yingt.fun +yingtai.com +yingtaigroup.com +yingtaorelian.com +yingtaosiyue.com +yingtaoyun.com +yingteach.com +yingtexin.net +yingtianit.com +yingtianlight.com +yingtianwang.com +yingtongshe.com +yinguobing.com +yingworks.com +yingwuyuzd.cc +yingxi.tv +yingxiahome.com +yingxiaofangan.com +yingxiaoli.com +yingxichina.com +yingxiong.com +yingxiongji.com +yingxun56.com +yingyang630.com +yingyankantu.com +yingyecraft.com +yingyijin.com +yingyinclub.com +yingyinglicai.com +yingyonghao8.com +yingyonghui.com +yingyongmiao.com +yingyongshichang.com +yingyongso.com +yingyu.com +yingyuchat.com +yingyudengji.com +yingyuehe.com +yingyushijie.com +yingyuxiaoshuo.com +yingzaocms.com +yingzhongshare.com +yingzi01.com +yingzi02.com +yingzicms.com +yingzt.com +yinhai.com +yinhang123.net +yinhangchaxun.com +yinhanghanghao.com +yinhangkadata.com +yinhangkahao.com +yinhangkaoshi.net +yinhangzhaopin.com +yinhe.com +yinhe.net +yinhecn.com +yinheyuedu.com +yinhu.com +yinhuadm.one +yinhuafu.com +yinhuatangyiyao.com +yinhuchem.com +yinhulaser.com +yini.org +yinisun.com +yinjia.com +yinjiabio.com +yinjispace.com +yinka.co +yinkunwi.work +yinlimedia.com +yinlingshuyuan.com +yinlvaa.com +yinmakeji.com +yinmaojx.com +yinmishu.com +yinning.vip +yinongtao.com +yinpiao.com +yinqiao.com +yinqiaogroup.com +yinrcw.com +yinsafe.com +yinsfinance.com +yinsha.com +yinshenxia.com +yinshua.cc +yinshuiyu.com +yinsuwl.com +yintai.com +yintechi.com +yintime.com +yinuo1000.com +yinuobeidiao.com +yinuochina.com +yinuoedu.net +yinuotech.com +yinxiang.com +yinxiangart.com +yinxianggame.com +yinxiangmall.com +yinxiangqingyang.com +yinxiangwuye.com +yinxiao.com +yinxiaobao.net +yinxinbh.com +yinxinchina.com +yinxing.com +yinxunbiao.com +yinyangresin.com +yinyangshi.com +yinyao168.com +yinyue7.com +yinyuegf.com +yinyueke.net +yinyuemeitu.com +yinyuetai.com +yinyueyouxi.com +yinyuezhizuoren.com +yinzhaowang.com +yinzhijie.com +yinzhupharma.com +yinziyan.com +yinzuo100.com +yioho.com +yioulai.com +yiovo.com +yipai.info +yipai360.com +yipaiming.com +yipaogan.com +yiparts.com +yipemail.com +yipeng888.com +yipiaoyun.com +yipigu.com +yipihuo.com +yipinbowu.com +yipingmed.com +yipingmi.vip +yipingsj.com +yipinhr.com +yipinpai.com +yipinsmart.com +yipintemian.com +yipinyiwu.com +yipsink.com +yipujiance.com +yipuping.com +yiputouzi.com +yipuwuyou.com +yiq.com +yiqi.com +yiqi35.com +yiqi4.com +yiqianbao.com +yiqianbao.net +yiqianlian.com +yiqiao88.com +yiqiaochina.com +yiqibazi.com +yiqibing.com +yiqibuduoduo.com +yiqicai.com +yiqicesuan.com +yiqichuangxiang.com +yiqicms.com +yiqifa.org +yiqifei.com +yiqifengtian.com +yiqig.com +yiqihi.com +yiqihuihui.com +yiqijian.com +yiqijixiang.com +yiqikan8.com +yiqike.com +yiqiming88.com +yiqimob.com +yiqingyuan.com +yiqinzi.com +yiqioffice.com +yiqipaipingtai.com +yiqishai.com +yiqishanyuan.com +yiqiso.com +yiqisooimg.com +yiqistore.com +yiqitp.com +yiqituodan.com +yiqiuu.com +yiqiwang.net +yiqixiaofei.com +yiqixie.com +yiqixiegushi.com +yiqiyoo.com +yiqiyou.com +yiquan-keji.com +yiquhai.com +yiqujing.com +yiquxapp.com +yirankejiao.com +yiranmeifushi.com +yiren001.com +yirendai.com +yirentong.com +yirenwuye.com +yirenzhushou.com +yirenzuji.com +yirgalab.com +yirlir.com +yirong.com +yiruan.la +yiruantong.com +yiruide.com +yiruikecorp.com +yiruituo.com +yirujs.com +yiruniot.com +yiruwijojn1.com +yiryi.com +yisa.com +yisanban.com +yisanwu.com +yisbei.com +yisell.com +yishalai.com +yishan168.com +yishang.cc +yishangwang.com +yishangye.com +yishengfanyi.com +yishengjiaoyu.com +yishidian.com +yishihui.com +yishihui.net +yishion.com +yishion.net +yishiongd.com +yishixue.com +yishouapp.com +yishs.com +yishu168.com +yishujia.net +yishujie.com +yishuliuxue.com +yishun.fun +yishutang.com +yishuzhifa.com +yishuzi.com +yishuzi.org +yishuziti.com +yisier.com +yisimeimaoyi.xyz +yiso.fun +yisocms.com +yisou.com +yisouti.com +yisouyifa.com +yissimg.com +yisu.com +yisuan.net +yisuddoscdn.com +yisuoyi.com +yit.com +yitai17.com +yitaifang.com +yitaigroup.com +yitaihdbf.com +yitanyun.com +yitao.com +yitaopu.com +yitb.com +yitcollege.com +yitechnology.com +yiteholdings.com +yitel.com +yitelish.com +yitesoft.com +yitiangroup.com +yitianshidai.com +yitianxinda.com +yitiaoyule.com +yiticm.com +yitijizhi.com +yitisports.com +yitoa.com +yitong-group.com +yitongguan.com +yitongmedia.com +yitongsolar.com +yitonyiqi.com +yitoto.cc +yitsoftware.com +yitutech.com +yituyu.com +yiubd.com +yiupin.com +yiuxiu.com +yivian.com +yivicar.com +yivizd.com +yiwaiart.com +yiwan.com +yiwangdujin.com +yiwanggo.net +yiwangtui.com +yiwanlian.net +yiwanzhushou.com +yiwealth.com +yiweb.com +yiweiads.com +yiweishi.com +yiwenyida.com +yiwenyizhi.com +yiwise.com +yiworld.com +yiwu56.com +yiwubuy.com +yiwufair.com +yiwugo.com +yiwugou.com +yiwuguan.com +yiwuku.com +yiwulianhe.com +yiwumls.com +yiwupay.com +yiwutalk.com +yiwuzhaopin.com +yiwuzhongxiyi.com +yiwz.net +yixao.com +yixao.net +yixc.com +yixi.tv +yixia.com +yixiaai.com +yixiaai.online +yixianfabu.com +yixiangzuji.com +yixiansheng.com +yixiaobang.net +yixiaoyuan.com +yixiaozu.com +yixiatong.com +yixiekeji.com +yixin-valve.com +yixin.com +yixin.im +yixin5.com +yixincao.com +yixincapital.com +yixinfinance.com +yixinfund.com +yixingart.com +yixingauto.com +yixingguanchang.com +yixinli.xin +yixintui.com +yixinu.com +yixiu.cloud +yixiubx.com +yixiuxueyuan.com +yixuan.net +yixue.com +yixue68.com +yixue99.com +yixuegr.com +yixueks.com +yixuelunwen.com +yixuexianzhi.com +yixuezp.com +yixun.com +yixunjidian.com +yixunwu.com +yiya520.com +yiyacht.com +yiyaha.com +yiyanche.com +yiyang168.com +yiyang668.com +yiyangadx.com +yiyangidc.com +yiyangzhuangyuan.com +yiyao.tv +yiyaodxt.com +yiyaohang.com +yiyaojd.com +yiyaojie.com +yiyaoqianyan.com +yiyayans.com +yiye-a.com +yiye-h.com +yiye-v.com +yiye.ai +yiyebang.com +yiyedu.com +yiyefei.com +yiyesheng.net +yiyiarts.net +yiyifoods.com +yiyimh.com +yiyisoft.com +yiyitech.com +yiyitesco.com +yiyiu.com +yiyiwawa.com +yiyongcad.com +yiyouliao.com +yiyouliuxue.com +yiyouqi.com +yiyoushu.net +yiyu.com +yiyuan.com +yiyuanjichang.com +yiyuanluye.com +yiyuanqiang.net +yiyuansoft.com +yiyuanyi.org +yiyuanzhaopin.com +yiyukj.com +yiyum.com +yiyun518.com +yiyupack.com +yiyusemi.com +yiz.vip +yizanmeiye.com +yizenb.com +yizeseafood.com +yizhanapp.com +yizhang8.com +yizhanhulian.com +yizhanzx.com +yizhaopin.com +yizhedian.com +yizhengwx.com +yizhibi.com +yizhibo.com +yizhidayu.com +yizhifubj.com +yizhijia.com +yizhikan.com +yizhiknow.com +yizhiqc.com +yizhiqingxie.com +yizhitou.com +yizhiwechat.com +yizhiweixin.com +yizhiws.com +yizhixiaogame.com +yizhoucb.com +yizhu-tech.com +yizhuan5.com +yizimg.com +yizlife.com +yizu.org +yizu.tv +yizumi-group.com +yizumi.com +yizuxing.com +yj-fun.com +yj-zn.com +yj.com +yj.ink +yj028.com +yj36.com +yj518.com +yjai.art +yjbys.com +yjbzr.com +yjcard.com +yjcf360.com +yjcp.com +yjctrip.com +yjdatasos.com +yjdzm.com +yjfs8.com +yjfy.com +yjgf.com +yjgxcx.com +yjhbqx.com +yjhnt888.com +yjhospital.com +yjhyjl.com +yjhzb.com +yjihua.com +yjijy.com +yjiyun.com +yjjsjt.com +yjk.com +yjk.im +yjkxw.org +yjldp.com +yjlhq.com +yjlin4.com +yjlink.cc +yjliquan.com +yjllq.com +yjmc.org +yjmuseum.com +yjopen.com +yjpal.com +yjpd.work +yjpoo.com +yjq.cc +yjqegc.com +yjr123.com +yjrc.com +yjrc.net +yjrcyw.com +yjro.com +yjs-cdn.com +yjs-cdn1.com +yjs-cdn10.com +yjs-cdn2.com +yjs-cdn3.com +yjs-cdn4.com +yjs-cdn5.com +yjs-cdn6.com +yjs-cdn7.com +yjs-cdn8.com +yjs-cdn9.com +yjscloud.com +yjsershi.com +yjsmodel.com +yjsops.com +yjsry.com +yjssishisi.com +yjsswjt.com +yjswsht.xyz +yjtiyu.com +yjtvw.com +yjtw.com +yjwlnet.com +yjwlo.com +yjwmidc.com +yjwujian.com +yjxbgjj.com +yjxfz.com +yjxlawyer.com +yjxsoft.com +yjydl.com +yjygjjt.com +yjygx.com +yjyxiyan.com +yjyz.com +yjz9.com +yjzcalzcxm.com +yjzf.com +yk-bio.com +yk-fm.com +yk0579.com +yk56.com +yk72e.com +ykai.com +ykazgima.com +ykccn.com +ykccn.net +ykcer.com +ykclass.com +ykcuqlt.com +ykdgd.com +ykdmsy.com +ykedu.net +ykelai.com +ykfc.net +ykhongye.com +ykimg.com +ykinvestment.com +ykjljdcss.com +ykjtb.com +ykkpict.com +ykkpict.vip +ykmanhua.com +ykmxemho.com +ykneng.com +ykplg.com +ykptg.com +ykq.ink +ykqj.com +ykqnl.com +ykqx.com +ykrc.net +ykrcx.com +yksdks.com +yksign.com +yksjjt.com +yksuit.com +ykt.io +yktchina.com +yktworld.com +yktz.net +ykuee.link +ykugyph.com +ykw18.com +ykwater.com +ykwin.com +ykxwcm.com +ykyao.com +ykyi.net +ykzls.com +ykzq.com +ykzr.com +ykzyyy.com +yl-csj.com +yl-fc.com +yl-scm.com +yl.ag +yl.vip +yl0008168.com +yl01.com +yl1001.com +yl1988.com +ylallinone.com +ylbeef.com +ylbloc.com +ylbycw.com +ylcapsule.com +ylchbyfz.com +ylcm.net +ylcncmy.com +ylcxsb.net +yldaye.com +yldayu.com +yldigitallife.com +yldmall.com +yldndl.com +yldrs.com +ylduyi.com +yldy.net +yldzhb.com +ylfd.net +ylfx.com +ylgaoshan.com +ylgjsty.com +ylgnyy.com +ylgs96332.com +ylgxgs.com +ylhags.com +ylhakc.com +ylhdgg.com +ylhdsl.com +ylhfjq.com +ylhh.net +ylhhny.com +ylhmgz.com +ylhongjin.com +ylhr.net +ylhrjxfw.com +ylhsrsrc.com +ylibi.com +ylijh.com +ylike.com +ylike.net +ylitc.net +yliyun.com +ylizu.com +yljcjt.com +yljdjx.com +yljr.com +ylkaite.com +ylkbf.com +ylkjgame.com +ylklyl.com +yllhzb.com +yllm666.xyz +yllt.icu +ylmaterial.com +ylmf.cc +ylmf123.com +ylmf888.com +ylmfeng.com +ylmfwin100.com +ylmm.com +ylnetworks.com +yloo.org +ylprinter.com +ylq.com +ylqk88.com +ylqyyr.com +ylr114.com +ylrb.com +ylrj.com +ylrq.org +ylscgl.com +ylscw.net +ylsdeyy.com +ylsdyyy.com +ylsfqyy.com +ylsmtnozzle.com +ylssgg.com +ylssofa.com +ylsssgg.com +ylstatic.com +ylstcgz.com +ylstudy.com +ylsw.net +ylt2008.com +yltapi.com +yltender.com +yltexgroup.com +yltlgjzx.com +yltpcb.com +ylturl.com +yltvb.com +yltxxx.com +ylun8.com +yluu.com +ylwdec.com +ylwl.cc +ylwltv.com +ylwpark.com +ylws.net +ylwyw.com +ylxdtww.com +ylxgf.com +ylxhmy.com +ylxw.net +ylxweb.com +ylxyct.com +ylxyyy.com +ylxyzs.com +ylxzgz.com +ylyk.com +ylyun.com +ylyz.com +ylzbsj.com +ylzbtech.com +ylzhaopin.com +ylzhsk.com +ylzknk.com +ylzmjd.com +ylzms.com +ylzpay.com +ylzsy.com +ylztwy.com +ylzuche.com +ylzxmryy.com +ylzyhb.com +ylzyjx.com +ylzz5557.com +ylzz5999.com +ylzz666.com +ylzz6777.com +ylzz755.com +ylzz877.com +ym-trans.com +ym.link +ym.run +ym.today +ym01.tech +ym23.com +ym3222333.com +ymacg.com +ymadly.com +ymailcampaign.com +ymanz.com +ymark.cc +ymars.com +ymatou.com +ymawv.la +ymbaidu.com +ymbank.com +ymcart.com +ymcart.net +ymcsepu.com +ymdoctor.com +ymechina.com +ymexf.com +ymfund.com +ymg.cc +ymgk.com +ymgkimg.com +ymhfp.com +ymhudong.com +ymhui.com +ymhuwai.com +ymhzpx.com +ymiot.net +ymisc.com +ymj9.com +ymjkj.com +ymjx8.com +ymkuzhan.com +ymlfxp.com +ymlinks.com +ymlt.net +ymlt.vip +ymm56.com +ymmfa.com +ymnsdk.com +ympc88.com +ympcb.com +ymrcw.vip +yms.cool +ymsoft.team +ymsss.com +ymsteam.com +ymt.com +ymt123.com +ymt360.com +ymtc.com +ymtie.com +ymtmt.com +ymtnet.com +ymuuy.com +ymvkt.com +ymwcds.org +ymwl.net +ymxinke.com +ymxinxi.com +ymxlass.com +ymyun.com +ymyxsw.com +ymzer.com +ymzsl.com +ymzxconf.com +ymzy.games +yn-tcm-hospital.com +yn-tobacco.com +yn2007.com +yn58.com +ynaec.com +ynairport.com +ynb2dca.com +ynbit.com +ync365.com +yncost.com +yncun.net +yncunguan.com +yncyc1990.com +yndaily.com +yndcc.com +yndkt.com +yndzdj.com +yneg-ev.com +yneit.com +ynet.com +ynfabu.com +ynfmly.com +ynfww.com +ynfwyy.com +ynfxw.com +yngas.net +yngp.com +yngsxy.net +yngw518.com +ynhkfyy.com +ynhl.net +ynho.com +ynhotel.net +ynhouse.com +ynhr.com +ynhthbkj.com +ynhuasong.com +ynhzm.com +yni84.com +ynian.com +ynjgy.com +ynjiaoyu.net +ynjkeji.com +ynjkjy.com +ynjlgroup.com +ynjtt.com +ynjttzjt.com +ynjtys.com +ynkcfc.com +ynkgyy.com +ynkm88.com +ynkmit.com +ynlygf.com +ynmbwl.com +ynmcyl.com +ynmec.com +ynmlgsgs.com +ynmzly.com +ynnits.com +ynpco.com +ynpta.com +ynpti.com +ynpublish.com +ynqjnews.net +ynqrmyy.com +ynradio.com +ynrainbow.com +ynrc.net +ynrcc.com +ynrd.com +ynscgg.com +ynsdfz.net +ynsfhq.com +ynshangji.com +ynshhyy.com +ynshijian.com +ynsjg.com +ynsjzyxh.com +ynsmyy.com +ynsnjt.com +ynsnw.com +ynsrx.com +ynsst.com +ynstl.com +ynsydwzp.com +ynsyhkgs.com +ynsyy.com +ynszfw.com +ynszk.com +ynszlyy.com +yntz.cc +yntz.net +ynurl.com +ynw360.com +ynwater.com +ynwin.com +ynwww.cc +ynxdfpr.com +ynxingexinxi.com +ynxinhua.com +ynxiu.com +ynxr.com +ynxrmyy.com +ynxxb.com +ynxxwfw.com +ynxzy.com +ynyc.com +ynyes.com +ynylhy.com +ynyp.com +ynytkc.com +ynyysc.com +ynzaojia.com +ynzbxh.com +ynzcwl.com +ynzg.org +ynzp.com +ynzqyc.com +ynzrf.com +ynzs.com +ynztrq.com +ynztzxw.com +ynzy-tobacco.com +ynzzwl.com +yo4399.com +yo9.com +yoagoa.com +yobo.ink +yobo360.com +yobochina.com +yocajr.com +yocdev.com +yocofs.com +yocopi.com +yocvn.com +yocyxc.com +yodak.net +yodao.com +yodao.info +yodao.net +yodao.org +yodiya.com +yodo1.com +yodo1api.com +yodou.com +yoduzw.com +yoe365.com +yofc.com +yofcjs.com +yofijoy.com +yofish.com +yofogo.com +yofond.com +yofond.net +yofus.com +yoga-8.com +yogeev.com +yoghourt.space +yogiyogacenter.com +yogoip.com +yogorobot.com +yoher.com +yohipay.com +yoho.org +yohobuy.com +yohui.com +yohuu.com +yojcool.com +yojochina.com +yoju360.com +yoju360.net +yoka.com +yokacdn.com +yokagames.com +yokaimg.com +yokaverse.com +yokechina.com +yokemart.com +yokmob.com +yokong.com +yokotop.com +yolanda.hk +yolcool.com +yolewa.com +yolexi.com +yolinkmob.com +yolipai.net +yoloho.com +yoloogames.com +yolyon.com +yomhy.com +yomiko.cloud +yomiko.club +yomiko.fun +yomiko.tech +yomob.com +yomocode.com +yomuzu.com +yonderep.com +yondocredit.com +yoneihan.com +yonex-china.com +yong-gang.com +yong-ming.com +yong9ai.com +yonganyiyuan.com +yongaomy.com +yongchaohuagong.com +yongche.com +yongche.org +yongchengren.com +yongdachina.com +yongdaoyun.com +yongdasteel.com +yongdugroup.com +yonggu.com +yonghe2008.com +yongheng.online +yongheyl.com +yonghongtech.com +yonghuivip.com +yonghungs.store +yongjiang.com +yongjiezb.com +yongjindl.com +yongjukeji.com +yongjx.com +yongkang56.com +yongkao.com +yonglibao.com +yonglibelt.com +yonglin.com +yonglinyy.com +yonglvtong.com +yongmei0537.com +yongnangroup.com +yongootech.com +yongpingziyuan.com +yongqianbao.com +yongqischool.net +yongridt.com +yongsheng-sl.com +yongshenggroup.com +yongshenghn.com +yongshengjituan.com +yongshikj.com +yongsy.com +yongtaitech.com +yongtaiyun.com +yongtu.net +yongwangcpa.com +yongweigroup.com +yongxiandata.com +yongxiang.work +yongxiangwz.com +yongxinby.com +yongxinfushi.com +yongxinhuangjin.com +yongxinshuo.com +yongxintex.com +yongxinxuexiao.com +yongxiuren.com +yongyi-valve.com +yongyoujia.com +yongyu.xyz +yongyuenj.com +yongzhegroup.com +yongzhentang.com +yongzhoubus.com +yonho.com +yonjan.com +yonkersz.com +yonlive.com +yonthin.com +yonyou.com +yonyouaud.com +yonyoubao.com +yonyouccs.com +yonyoucloud.com +yonyoufintech.com +yonyougov.com +yonyougx.com +yonyouny.com +yonyouoa.com +yonyouup.com +yoo-club.com +yoo616.com +yoo66.com +yooc.me +yoodb.com +yooek.com +yoofh.com +yoogene.com +yoohe.net +yoohouse.com +yoojia.com +yoojing.com +yooknet.com +yooojie.monster +yoooooooooo.com +yoopu.me +yooquma.com +yooxlife.com +yooxun.com +yooyo.com +yoozai.com +yoozhe.com +yoozhibo.cc +yoozhibo.net +yoozoo.com +yopoint.cc +yopoint.com +yoptech.com +yopu.co +yopwork.com +yopye.com +yoqoo.com +yoqoo.net +yoqoo.tv +yoqu.net +yorentown.com +york-tech.com +york33.com +yorlaw.com +yorui.net +yoseleather.com +yostar.net +yostatic.com +yotopic.com +you-mi.net +you03.com +you1ke.com +you200.com +youacc.com +youandme123.com +youba.com +youba123.com +youban.com +youbangkeyi.com +youbangyun.com +youbbs.org +youbeichefu.com +youbian.com +youbibi.com +youbike.me +youbikecn.com +youbohe.com +youboy.com +youboy.net +youboyy.com +youcaihua.net +youcaiyun.com +youcaizhushou.com +youcareyk.com +youcash.com +youcha.net +youche.com +youchedi.com +youchejiuxing.com +youchent.com +youcheyihou.com +youchuhuodong.com +youcloud.com +youda8.com +youdajx.com +youdao.com +youdaocaifu.com +youdaochem.com +youdas.com +youdashidai.com +youdawangluo.com +youde.com +youdemai.com +youdiancms.com +youdianyisi.com +youdianzhishi.com +youdingsuit.com +youdingte.com +youdong.com +youdou.mobi +youdubook.com +youduzw.com +youdwh.com +youease.net +youedata.com +youez.com +youfabiao.com +youfan.pub +youfanerbuy.com +youfang123.com +youfangou.com +youfangzx.com +youfanx.com +youfen666.com +youfengbio.com +youfubao.vip +youfujc.com +youfunlab.com +youfutongxinag.org +youfuyoucai.com +yougababy.com +youganghangmoguan.com +yougaoji.com +yougaoyx.com +yougenet.com +youginorg.com +yougou.com +yougu.tv +yougumuye.com +youguo.com +youguoquan.com +youguu.com +youhaodongxi.com +youhaosoft.com +youhaosuda.com +youhaoxinxi.com +youhro.com +youhu.net +youhua.com +youhua.pw +youhuaaa.com +youhuafuzhi.com +youhuas.com +youhuashu.com +youhugmedia.com +youhuiduo.net +youhundao.com +youhuohao.com +youhutong.com +youideal.net +youinsh.com +youj.com +youjiajk.com +youjiands.net +youjiangdati.com +youjiangzhijia.com +youjiao.com +youjiao365.net +youjiao5.com +youjiaxiao.com +youjimilk.com +youjindi.com +youjingnetwork.com +youjiuhealth.com +youjoy.tv +youju360.com +youke.co +youke.com +youked.com +youkeda.com +youkego.com +youkexueyuan.com +youkia.com +youkia.net +youking.com +youkongkan.com +youkongwan.com +youku-dns.com +youku.cdn2-youku.com +youku.com +youku.org +youkua.net +youkuaiyun.com +youkud.com +youkupic.com +youlai.tech +youlanw.com +youlechuhai.com +youlecn.com +youleliwu.com +youlesp.com +youletd.com +youleyou.com +youlian.fun +youlianfuwu.com +youliangda.com +youlianghz.com +youliao.com +youliao.love +youliaobaike.com +youliaoyi.com +youlingtong.com +youlinyouke.com +youlionbattery.com +youlishipin.com +youloft.com +youlong123.com +youlongciqing.com +youlu.com +youlu.net +youlu6.com +youlupei.com +youluwx.com +youma.cc +youmai.com +youmanvideo.com +youme.im +youmeisiji.com +youmeng020.com +youmengchuangxiang.com +youmengcms.com +youmengmob.com +youmenr.com +youmew.com +youmiad.com +youmian99.com +youmiaoyigou.com +youmideer.com +youmindao.com +youmobi.com +youneedcrydear.com +youneng.com +younet.com +young40.com +youngem.com +youngerfeel.com +younggas.com +youngjoygame.com +youngle.site +youngle.tech +youngor.com +youngsunpack.com +youni.im +younuokeji.cloud +youo.net +youol.com +youonbike.com +youpengcx.com +youpengw.com +youpin898.com +youpingame.com +youpinhaoche.com +youpinimg.com +youpinppt.com +youpinsanyue.com +youpintechs.com +youpinx.com +youplus.cc +youpont.net +youpuchina.com +youpumao.com +youpumao.xyz +youqiantu.com +youqichuyun.com +youqiong.net +youqiwu.com +youqizhan.com +youqo.com +youqoo.net +youqu.in +youqudao.com +youquhui.com +your-man.com +your360loans.com +your724sports.com +yourbin.com +yourcee.com +yourchinagent.com +yourcollect.net +yourdream.cc +youren5.com +yourjia.com +yourongsj.com +yourtion.com +yourtravelyourchoice.com +youruitech.com +youscm.com +youseen.com +yousengshe.com +yousenjiaoyu.com +youser.cc +youshang.com +youshaohua.com +yousheng.shop +youshenggz.com +youshenhudong.com +yousheyoujia.com +youshibeike.com +youshifu.com +youshihui.cc +youshikoudai.com +youshixiu.com +youshop01.com +youshop02.com +youshop03.com +youshop04.com +youshop10.com +youshu.cc +youshuge.com +youshujian.com +yousi.com +youstong.com +youtaidoors.com +youtaidu.com +youtao55.com +youtaojd.com +youthi.com +youtiandi.com +youtianli.com +youtianmetal.com +youtianz.com +youtibao.com +youto.club +youtoart.com +youtochat.com +youtoupiao.com +youtrans.net +youtu.com +youtube-dubbing.com +youtuzi.com +youtx.com +youuav.com +youuvs.com +youwanplay.com +youwawa.com +youwei-china.com +youwei.com +youweigroup.com +youweihui.com +youwo.com +youwoxing.net +youwu.today +youwusc.com +youxedu.com +youxi.com +youxi01.com +youxi377.com +youxi527.com +youxi528.com +youxi567.com +youxi8282.com +youxia.com +youxiacg.com +youxiagushi.com +youxiaju.com +youxiake.com +youxiake.net +youxiamotors.com +youxiangclub.com +youxiangyx.com +youxiaoge.com +youxiaohou.com +youxiaxiazai.com +youxibao.com +youxibaoku.com +youxibd.com +youxica.com +youxicdn.com +youxichaguan.com +youxicheng.net +youxicitang.com +youxidaxue.com +youxidr.com +youxidun.com +youxiduo.com +youxifan.com +youxigongchang.com +youxigt.com +youxigu.com +youxiguancha.com +youxigui.com +youxih.com +youxihezi.net +youxihun.com +youxiivf.com +youxila.com +youximt.com +youxin.com +youxingapp.com +youxiniao.com +youxinpai.com +youxinshi.com +youxinsign.com +youxipai.com +youxiping.com +youxiputao.com +youxiqiang.com +youxiqun.com +youxishuo.com +youxitexiao.com +youxituoluo.com +youxiuhui.com +youxiwangguo.com +youxiwugui.com +youxixf.com +youxixinzhi.com +youxixj.com +youxizhan.com +youxuan.com +youxuanan.com +youxuancdn.com +youxuandns.com +youxuangu.com +youxueke.com +youxuetong.com +youyacao.com +youyacheye.com +youyan.xyz +youyannet.com +youyantech.com +youyeetoo.com +youyegame.com +youyi-game.com +youyi800.com +youyicun.net +youyierp.com +youyigame.com +youyiguke.com +youyihuibk.com +youyijifen.com +youyijiu.com +youyiqi.com +youyiqiaogou.com +youyitape.com +youyitian.net +youyitms.com +youyiweizhan.com +youyiwms.com +youyix.com +youyixue.com +youyizhidao.com +youyo88.com +youyogame.com +youyong360.com +youyou.com +youyou001.com +youyou234.com +youyoufood.com +youyouwin.com +youyuan.com +youyudf.com +youyuegame.com +youyuela.com +youyuit.net +youyur.com +youyuwenhuay.com +youyuwo.com +youyy.com +youzack.com +youzan.com +youzanyun.com +youzhai.com +youzhan.org +youzhanjia.com +youzhao.com +youzhenhua.com +youzhi.net +youzhi99.com +youzhicai.com +youzhicn.com +youzhiwk.com +youzhixueyuan.com +youzhiying.com +youzhiyouxing.com +youzhou-knife.com +youzhu.com +youzhuan.com +youzi02.com +youzibuy.com +youzijie.com +youzijimu.com +youziku.com +youzikuaibao.com +youzipay.com +youzu.com +youzuanmy.vip +yovisun.com +yovocloud.com +yovole.com +yovyuan.com +yowhale.com +yowooa.com +yoxiha.com +yoximi.com +yoxmail.com +yoxuba.com +yoxyok.com +yoya.com +yoybuy.com +yoyiapp.com +yoyiit.com +yoyile.com +yoyo007.com +yoyo1900.com +yoyo2008.com +yoyoask.com +yoyoer.com +yoyojacky.com +yoyojie.com +yoyokko.com +yoyoogo.com +yoyosc.com +yoyotown.com +yoyou.com +yoytang.com +yoyucn.com +yoyv.com +yozodcs.com +yozodoc.com +yozodocs.com +yozooffice.com +yozosoft.com +yozsc.com +yozyn.com +yp001.com +yp007.net +ypank.com +ypattern.com +ypblkm.com +ypc-fc.com +ypfph.com +ypgyyq.com +yph-shop.com +yphbuy.com +yphuifu.com +ypiao.com +ypicw.com +ypjc.cloud +ypjiameng.com +ypjsgl.com +ypkc.com +ypkegroup.com +ypky.net +yplady.com +yplog.net +yplogistics.com +yplsw.com +ypmail.work +yppp.net +ypppt.com +yprh.com +ypshengxian.com +ypshop.net +ypstech.com +ypwater.com +ypxiixs.xyz +ypyyjt.com +ypzdw.com +ypzhushou.com +yq-zc.com +yq2404.com +yqacg.com +yqb.at +yqb.com +yqb920.com +yqbank.com +yqbdt.com +yqbimg.com +yqbimg.net +yqchjd.com +yqcn.com +yqcsbqxj.com +yqcymj.com +yqdtv.com +yqelect.com +yqfcw.net +yqfml.com +yqfoodec.com +yqfxw.net +yqh.com +yqh1969.com +yqh5.com +yqhlm.com +yqhzz.com +yqjtgs.com +yqk889.com +yqk8ku.com +yqkddm.com +yqkk.link +yqlzq.com +yqmb001.com +yqmengyou.com +yqmh.com +yqmls.com +yqmoybz.com +yqms.net +yqmsn.com +yqn.com +yqphh.com +yqqqbm.com +yqrc.com +yqrcw.com +yqrtv.com +yqsbz.com +yqslmall.com +yqsn.com +yqtg.cc +yqtkgzbk.com +yqtsgg.com +yqw188.com +yqwfpy.com +yqwxw.cc +yqwyx.xyz +yqxiuyoung.com +yqxs.cc +yqxsg.cc +yqxsge.cc +yqxxjy.com +yqy021.com +yqybzhan.com +yqyu.com +yqzww.cc +yqzww.la +yqzww.net +yqzwww.com +yqzxx.net +yr-info.com +yr17.net +yr3.com +yra2.com +yracc.com +yrapp.net +yrcbank.com +yrdart.com +yretc.com +yrglass.com +yrgx168.com +yrhct.com +yrmpay.com +yrobot.com +yrom.net +yrtgame.com +yrtyyds.com +yruan.com +yrucd.com +yrw.cc +yrw.com +yrwy.com +yrxitong.com +yrxsw.com +yryz.com +yrz.name +yrzjw.com +ys-fj.com +ys-oss.xin +ys.cc +ys001.com +ys0431.net +ys121.com +ys133.com +ys137.com +ys168.com +ys1898.com +ys2345.com +ys4fun.com +ys7.com +ys720.com +ys8.com +ys991.com +ysaedesign.com +ysali.com +ysbopet.com +ysbtv.net +ysbz168.com +yscase.com +ysch.cc +ysclass.net +yscq.com +yscro.com +ysczw.com +ysdq8.com +ysdwe.asia +ysedu.com +ysej.com +ysemi.com +ysepan.com +ysepay.com +ysext.com +ysfog.com +ysgang.com +ysgfood.com +ysghh.com +ysgtg.com +ysgushi.com +yshp.net +yshshuimitao.com +yshsports.com +yshw1.com +yshzjt.com +ysicing.net +ysidcz.com +ysiis.com +ysirv.com +ysjcyxgs.com +ysjdaijia.com +ysjf.com +ysjianzhan.com +ysjkbk.com +yskcsj.com +yskjz.com +yskjzj.com +yskxjy.com +yslcw.com +yslpaint.com +yslqo.com +yslw.com +yslyhr.com +yslzc.com +ysmeet.com +ysmiji.com +ysmine.com +ysmir.net +ysn.cc +ysnews.net +ysod.com +ysok.net +ysol.com +ysosuo.com +ysplay.com +ysrencai.com +ysrh.com +ysrzdb.com +ysslc.com +yssp88.com +yssql.com +yssrmyy.com +ysstech.com +ysszzs.com +yst100.net +ystan.com +ystb.com +ystbds.com +ysten.com +ystencdn.com +ysts.cc +ystsx.com +ystzzy.com +ysug.com +ysupan.com +ysw1950.com +ysw68.com +yswebportal.cc +yswh.com +yswlgame.com +yswswkj.com +yswu.net +yswyyds.com +ysx9999.com +ysxapp.com +ysxs8.com +ysxswz.com +ysxts.com +ysxyhtz.com +ysxzls.com +ysys.com +ysyycv.com +yszpwatch.com +yszx99.com +yszxx.net +yszyun.com +yt-ma.com +yt-taili.com +yt-xinpeng.com +yt0.cc +yt1998.com +yt2.net +yt69.com +yt698.com +yt98w.com +ytaotao.net +ytaxx.com +ytbainakeji.com +ytbbs.com +ytbfilm.com +ytbt.cc +ytcables.com +ytcbh.com +ytccr.com +ytchangyang.com +ytcj.com +ytcnc.net +ytcutv.com +ytdaily.com +ytdcloud.com +yte1.com +ytecn.com +ytedi.com +yteng.net +ytesting.com +ytf8888.com +ytfcjy.com +ytg666.com +ytgas.com +ytghnb.com +ytgos.com +ythairui.com +ytholidayplaza.com +ythospital.com +ythouse.com +ythzg.com +ytjcpj.com +ytjiage.com +ytjlc.net +ytjob.com +ytjpkj.com +ytjqjt.com +ytjunyue.com +ytkiewvf.cc +ytkj2010.com +ytlh120.com +ytlvbao.com +ytmachinery.net +ytmc.press +ytmedia.tv +ytmgz.com +ytmingju.com +ytnetgame.com +ytnstone.com +yto-jsd.com +yto-lgs.com +yto-lgs.net +yto.vip +yto.xin +yto56test.com +ytocargo.com +ytoexpress.com +ytoglobal.com +ytogroup.com +ytoholding.com +ytokj.com +ytokj.net +ytoluohan.com +ytoluohan.net +ytoluohan.xin +ytop8.com +ytphq.com +ytport.com +ytpowder.com +ytpp.com +ytpu.com +ytqh-electric.com +ytrain.com +ytrcw.com +ytrdc.com +ytrlzyw.com +ytrmtzx.com +yts88.com +ytsanchuan.com +ytsense.com +ytsexrb.com +ytsfc.com +ytshipin.com +ytsyy.com +ytszg.com +yttxcs.com +ytud.net +ytuqy.com +ytusmart.com +ytwater.com +ytxedu.com +ytxinhai.com +ytxinyan.com +ytxsc.com +ytxww.com +ytyaoye.com +ytyhdyy.com +ytyz.net +ytyz.org +ytzhihui.com +ytzq.com +ytzww.com +yu-electronics.net +yu163.com +yu4l.com +yu72.com +yu7l.com +yuaigongwu.com +yuaiweiwu.com +yuan2808.com +yuan7i.com +yuanabsorber.com +yuanbaobaoxian.com +yuanbaokc.com +yuanbaotaoche.com +yuanbei.biz +yuanben.io +yuanbin.me +yuancangipr.com +yuancdn.com +yuancefund.com +yuanchang888.com +yuanchengroup.com +yuanchuangyinyue.com +yuancoder.com +yuanda-fm.com +yuandacn.com +yuandaocn.com +yuandi.com +yuandian.club +yuandiancredit.com +yuandongsl.com +yuanf56.com +yuanfen.icu +yuanfeng021.com +yuanfeng1.com +yuanfudao.biz +yuanfudao.com +yuanfudao.ws +yuanfudaoschool.com +yuanfusc.com +yuangongbao.com +yuanhaitaiji.com +yuanhangqiche.com +yuanhangzyt.com +yuanhechem.com +yuanhengyi.com +yuanheyaoye.com +yuanhua.com +yuanhuixinhai.com +yuanjingang.com +yuanjingss.com +yuanjisong.com +yuanjoy.com +yuanlai.com +yuanlei.net +yuanley.com +yuanlian365.com +yuanlin.com +yuanlin365.com +yuanlin8.com +yuanlvkeji.com +yuanma.net +yuanmadian.com +yuanmait.com +yuanmajiaoyiw.com +yuanmatao.com +yuanmengyouxuan.com +yuano.cc +yuanpanguoji.com +yuanqiao.net +yuanqiao.pw +yuanqilt.com +yuanqingsh.com +yuanqisenlin.com +yuanrenbang.com +yuanrengu.com +yuanrenxue.com +yuansfer.com +yuanshen.com +yuanshi-sec.com +yuanshichang.com +yuanshuflow.com +yuansikeji2021.com +yuansoti.com +yuansouti.biz +yuansouti.com +yuant.net +yuantaobgjj.com +yuanteng.net +yuantest.com +yuantiku.biz +yuantiku.com +yuantiku.xyz +yuantongyizhan.com +yuantoushuo.com +yuantu.info +yuantuedu.com +yuantujun.com +yuantutech.com +yuanu.com +yuanvip.shop +yuanweish.com +yuanwind.com +yuanwsk.com +yuanxianmedia.com +yuanxinbaoxian.com +yuanxinjituan.com +yuanyaedu.com +yuanyangbj.com +yuanyangcoffee.com +yuanyangmed.com +yuanyeer.com +yuanyoumao.com +yuanyoutao.com +yuanyubusiness.com +yuanzhanapp.com +yuanzhexi.com +yuanzhi.com +yuanzhihao.life +yuanzhiyijiantong.com +yuanzidai.com +yuanzige.com +yuanzipower.com +yuanziyan.com +yuanzun.fun +yuaoq.com +yuapt.com +yubaike.com +yubangweb.com +yuboinfo.com +yuboqj.com +yucekj.com +yucezhijia.com +yuchai.com +yuchaicd.com +yuchaidiesel.com +yuchainev.com +yuchainz.com +yuchaipg.com +yuchaizm.com +yuchenpharm.com +yuchenw.com +yuchofoodmachine.com +yuchuan.org +yuchuantech.com +yuci998.com +yucoolgame.com +yucui.org +yucunkeji.com +yudamedical.com +yudeglobal.com +yudiangame.vip +yudiaomingjia.com +yudiu.com +yudoauto.com +yudouyudou.com +yuduxx.com +yue-grh.com +yue-tao.com +yue365.com +yue7.com +yuebai.tv +yueban.com +yueban.net +yuebao.ltd +yuebei.vip +yuebeist.com +yuebie.com +yueblx.com +yuebooemt.com +yuecdn.net +yuecheng.com +yuechengcn.com +yuecong.club +yueda.com +yuedainvest.com +yuedaoec.com +yuedarzzl.com +yuedatc.com +yuedianedu.com +yuedisk.com +yuedsk.com +yuedu.pro +yuedu88.com +yuedufang.com +yueduji.com +yuedujiayuan.com +yuedunovel.com +yueduwen.com +yueduwu.com +yueduwuxianpic.com +yueduyun.com +yuegongyutu.com +yuegowu.com +yuegui.shop +yueguisuchong.com +yuehaifeed.com +yuehaowy.com +yueimg.com +yueji.com +yuejiewangluo.com +yuejikeng.com +yuejob.com +yuejuanbao.com +yuejuwang.com +yuekenet.com +yuekesoft.com +yuekesoft.net +yuekeyun.com +yuelanxinghe.com +yueliangshi.com +yuelongchina.com +yuelongdzc168.com +yueloo.com +yuelu.net +yuelun.com +yuelvxing.com +yuemagroup.com +yueme.tv +yuemei.com +yuemicn.com +yueniuzq.com +yuenongren.com +yuenshui.com +yuenwooping-truelegend.com +yuenyled.com +yuepaijia.com +yueqi.com +yueqiji.com +yueqikan.com +yueqingchayuan.com +yueqiweixiu.com +yueqiyou.com +yueque.com +yuequtech.com +yuer.com +yuerbao.com +yueren123.com +yuerenjt.com +yueru.com +yuerugou.com +yuesekaer.com +yueserve.com +yueseyuewei.com +yueshenggame.com +yueshifengyin.net +yueshitv.com +yuesuoping.com +yuetengiot.com +yueting.net +yuetingapp.com +yuetj.com +yuetu.tech +yuetuvip.com +yuetuvip.net +yuewanggd.com +yuewei007.com +yueweimusic.com +yuewen.com +yuexiamen.com +yuexiangpin.com +yuexiangspace.com +yuexindianqi.com +yuexing.com +yuexingchem.com +yuexinship.com +yuexirc.com +yuexiren.com +yuexiu-finance.com +yuexiu.com +yuexiudevelopment.com +yuexiufoods.com +yuexiuleasing.com +yuexiuproperty.com +yuexunedu.com +yuexunfanyi.com +yuexw.com +yueya.net +yueyaa.com +yueyan365.com +yueyangshop.com +yueyangyy.com +yueyat.net +yueye7.com +yueyear.com +yueyouxs.com +yueyq.com +yueyu114.com +yueyuanzhiye.com +yueyues.com +yueyueworld.com +yueyueyd.com +yueyuez.com +yueyundns.com +yueyuzhushou.com +yuezeyi.com +yuezhicn.com +yuezhiding.com +yuezhinan.com +yufanlogistics.com +yufanwei.com +yufeng05.com +yufenggroup.com +yufenjiameng.com +yuflc.com +yufuid.com +yufuid.net +yugasun.com +yugenmed.com +yugew.com +yuglf.com +yugongw.com +yugudz.com +yuguimedia.com +yuguo.com +yuguowang.net +yugusoft.com +yuguz.com +yuhaids.com +yuhaiyiya.com +yuhaochemical.com +yuhaotime.com +yuhaozhixing.com +yuheii.com +yuhein.com +yuhelaw.com +yuhengcheng.com +yuhocare.com +yuhongchem.com +yuhongpharm.com +yuhou.com +yuhougame.com +yuhsoft.com +yuhuagu.com +yuhuaholding.com +yuhuanghuagong.com +yuhucoldchain.com +yuhuijob.com +yuhx.com +yui06161shga.com +yui06171shga.com +yujia.com +yujiahui.com +yujianpay.com +yujianxiaomian.com +yujiawuliu.com +yujiefs.com +yujifruit.com +yujingkj.com +yujiu.vip +yujpa.com +yujunjie.com +yujunren.com +yukaidi.com +yukaiprecision.com +yukeinfo.com +yukeweb.com +yukexinchem.com +yukicat.net +yukicomic.com +yukiovo.com +yukuai.com +yukxw.com +yulangair.com +yule114.com +yule263.com +yuledaily.com +yulefm.com +yulehezi.com +yuleie.com +yulejiaodian.com +yulekan.com +yulekoudai.com +yuleqiu.com +yulhe.com +yuli.be +yuliancn.com +yuliang-sh.com +yulicdn.com +yulinapp.com +yulincard.com +yulindxgjj.com +yulinedu.net +yulingtianxia.com +yulinhuaran.com +yulinjue.com +yulinqj.com +yulins.com +yulinshidefu.com +yulinyw.com +yuliqx.com +yulong.com +yulongdt.com +yulongjun.com +yulongpc.com +yulongsteelpipe.com +yulongtour.com +yulongwanski.com +yuloo.com +yulore.com +yulorepages.com +yulu1.com +yulu99.com +yuluju.com +yuluyao.com +yulv.net +yumao.com +yumaochuhai.com +yumaoclub.com +yumaoshu.com +yumchina.com +yumi.cc +yumi.com +yumingguwen.com +yumingyouhui.com +yummy.tech +yumstone.com +yun-ac.com +yun-app.net +yun-dns.com +yun-gu.com +yun-health.com +yun-idc.com +yun-img.com +yun-jinrong.com +yun-jintong.com +yun-kai.com +yun-live.com +yun-qu.com +yun-wp.com +yun123.com +yun5.vip +yun61.com +yun88.com +yunadmins.com +yunalias.com +yunannet.com +yunaq.com +yunarm.com +yunassess.com +yunaw.com +yunba.io +yunban.com +yunbaofei.com +yunbaolai.com +yunbaoming.com +yunbei.com +yunbiao.tv +yunbiaowulian.com +yunbiaozhun.com +yunbiji.com +yunbisai.com +yunbohealth.com +yunbook.vip +yunbu.me +yunbugame.com +yunbuzhan.com +yuncai5.com +yuncaioo.com +yuncdn.bid +yuncdn123.com +yuncdn263.com +yuncdndun.com +yunce.work +yuncechina.com +yunceng.com +yunchelogistics.com +yuncheng.com +yunchexing.com +yunchip.com +yunchonglife.com +yunchongmob.com +yunchou.com +yunchuan.info +yuncii.com +yuncitys.com +yuncloudauth.com +yuncname.com +yuncode.net +yuncuntu.com +yund.tech +yunda56.com +yundaex.com +yundagongyi.com +yundagroup.com +yundalog.com +yundaltl.com +yundangan.com +yundangnet.com +yundaomen.com +yundasys.com +yunde.net +yundianjia.com +yundianseo.com +yundiantech.com +yundingdun.com +yundongfang.com +yundonghao.com +yundongit.com +yundousoft.com +yundui.cc +yunduimedia.com +yundun.com +yundun.shop +yunduncc.com +yunduncdn.com +yunduncdns.com +yunduncname.com +yundunddos.com +yundundns.com +yunduns.com +yundunwaf.com +yundunwaf1.com +yundunwaf2.com +yundunwaf3.com +yundunwaf4.com +yundunwaf5.com +yunduocrm.com +yunduoke.net +yunduoketang.com +yunduolp.com +yundzh.com +yuneach.com +yunerba.com +yunews.net +yunexam.com +yunexpress.com +yunfabiao.com +yunface.com +yunfalv.com +yunfan.com +yunfan0739.com +yunfancdn.com +yunfancdn.net +yunfandns.com +yunfangtan.com +yunfanka.com +yunfanyouxi.com +yunfei89.com +yunfeihudong.com +yunfeitech.com +yunfeiyang.com +yunfengdie.com +yunfutang8.com +yunfutech.com +yunfuwuqiba.com +yungangbj.com +yungao-ssp.com +yungao.mobi +yungbang.com +yungengxin.com +yungongchang.com +yungotec.com +yungou618.com +yungouos.com +yungousj.net +yungpu.com +yungu.org +yunguajibao.com +yungujia.com +yunhaicangshu.com +yunhaike.com +yunhaiqiao.com +yunhaisteel.com +yunhaoka.com +yunhaoren.com +yunhe518.net +yunhedata.com +yunhehudong.com +yunheit.com +yunhesanwan.com +yunhetong.com +yunhou.com +yunhuangroup.com +yunhuaq.com +yunhuasheji.com +yunhuashu.com +yunhuijing.com +yunhulu.org +yunhuotong.net +yunifang.com +yunify.com +yunio.com +yunip.com +yunipo.com +yunji.work +yunji.xin +yunjian.com +yunjian.net +yunjiasu-cdn-dnssec.net +yunjiasu-cdn.com +yunjiasu-cdn.net +yunjiasu-dns.com +yunjiasu-dns.net +yunjiasu-test.com +yunjiasu.cc +yunjiasu360.com +yunjiasucdn.info +yunjiasucdn.net +yunjiasudns.com +yunjiasudns.net +yunjiasupreview.com +yunjiasussl.com +yunjiazheng.com +yunjichaobiao.com +yunjie.art +yunjiemi.net +yunjifarm.com +yunjiglobal.com +yunjing720.com +yunjingdian.net +yunjinggo.com +yunjinginc.com +yunjitele.com +yunjiweidian.com +yunjix.com +yunjuwuliu.com +yunkaiguan.com +yunkangdoctor.com +yunkanghealth.com +yunkanpan.com +yunkawulian.com +yunkd.com +yunke.com +yunkejituan.com +yunken.com +yunketop.com +yunkezan.com +yunkuaimai.com +yunkushop.com +yunlaiwu.com +yunlangtuanjian.com +yunlie.net +yunlietou.com +yunliketech.com +yunlinghang.com +yunlitz.com +yunlsp.com +yunlucn.cc +yunma99.com +yunmai.com +yunmayi.com +yunmc.vip +yunmd.net +yunmeipai.com +yunmell.com +yunmengdata.com +yunmianqian.com +yunmoseo.com +yunmoxing.com +yunn-tech.com +yunna.me +yunnan.vip +yunnancoffee.org +yunnandns.com +yunnanjun.com +yunnanlong.com +yunnanuu.com +yunnao.com +yunneidongli.com +yunos-inc.com +yunos-tv.com +yunos.com +yunpan.com +yunpansou.cc +yunpanx.com +yunparking.cloud +yunpay.cc +yunpei.com +yunpian.com +yunpiao.net +yunqi.org +yunqi2050.com +yunqi6.com +yunqiba.com +yunqifly.com +yunqiju.com +yunqikecrm.com +yunqishi.net +yunqishi8.com +yunqishuju.com +yunqiyqh.com +yunque360.com +yunquna.com +yunrang.fun +yunrenshi.net +yunrg.com +yunrongu.com +yunruicloud.com +yunruikj.com +yunruizz.com +yunsd.net +yunser.com +yunshan.net +yunshangdian.com +yunshangguangdong.com +yunshanghangzhou.com +yunshangkj.com +yunshangnc.com +yunshangshou.com +yunshangsuzhou.com +yunshangxuzhou.com +yunshangzhejiang.com +yunshanit.com +yunshanmedical.com +yunshanmeicai.com +yunsheng.com +yunsheng999.com +yunshibuluo.com +yunshicloud.com +yunshiketang.xyz +yunshow.com +yunshunxx.com +yunshuren.com +yunshuwh.com +yunsiya.com +yunsom.com +yunsong.com +yunsou168.com +yunssl.com +yunsuan.org +yunsuanzi.com +yunsuo.com +yuntaigo.com +yuntask.com +yuntemai.com +yunteng-group.com +yuntiancloud.com +yuntianti.com +yuntianxia.com +yuntingbo.com +yuntingiot.com +yuntisoft.com +yuntongauto.com +yuntongbu.com +yuntongcloud.com +yuntongshuke.com +yuntongxun.com +yuntongzy.com +yuntop.com +yuntsg.com +yuntu.io +yuntue.com +yuntuiweishang.com +yuntuoguan.cc +yuntus.com +yuntus.net +yuntust.com +yuntuys.com +yuntyfilter.com +yunupay.com +yunverify.com +yunvm.com +yunwei8.com +yunweibang.com +yunweipai.com +yunweiwl.com +yunwenkeji.com +yunwenxue.com +yunwins.com +yunwuxian.net +yunxi.cc +yunxi.net +yunxi.tv +yunxi10.com +yunxiacn.com +yunxianchang.com +yunxiao.com +yunxin123.com +yunxin163.com +yunxinapi.com +yunxindai.com +yunxindns.com +yunxinfa.com +yunxinfw.com +yunxing123.com +yunxingslb.com +yunxinhi.com +yunxinhy.com +yunxinrtc.com +yunxinshi.com +yunxinsvip.com +yunxinsvr.com +yunxinvcloud.com +yunxinvideo.com +yunxiren.com +yunxish.com +yunxiu.com +yunxs.com +yunxuetang.com +yunxunmedia.com +yunxya.com +yunyangwang.com +yunyazu.com +yunyi-china.com +yunyi-dd.com +yunyibiji.com +yunyichong.com +yunyihudong.com +yunyin.org +yunying001.com +yunyingbiotech.com +yunyingdashu.com +yunyingketang.com +yunyingmiao.com +yunyingpai.com +yunyingxbs.com +yunyingxuetang.com +yunyis.com +yunyiyuan.com +yunyize.com +yunyoufeitian.com +yunyouni.com +yunyousj.com +yunysr.com +yunyu123.com +yunyuba.com +yunyueqiji.com +yunyunvip.com +yunyuwuyou.com +yunzazhi.com +yunzehj.com +yunzhan365.com +yunzhangfang.com +yunzhanggui.net +yunzhanghu.com +yunzhanxinxi.com +yunzhanyou.com +yunzhifankeji.net +yunzhijia.com +yunzhirencai.com +yunzhisec.com +yunzhitai.com +yunzhixiyou.com +yunzhizao.net +yunzhonghe.com +yunzhu100.com +yunzhuan.com +yunzhuangbei.com +yunzhuxue.com +yunzitraining.com +yunzmall.com +yunzongnet.com +yunzuji.vip +yunzujia.com +yunzuoye.net +yunzz.net +yuoucn.com +yupao.com +yupaowang.com +yupeiholdings.com +yupinny.com +yupoo.com +yupu.com +yuqianshu.com +yuqiao.com +yuqiaolong.com +yuqinpin.com +yuquanhosp.com +yuque.com +yuren.org +yuriimg.com +yurongoptical.com +yurun.com +yusa.me +yusainorthwest.com +yusanmao12345.store +yushanfang.com +yushangmao.com +yushengny.com +yushengtang.com +yushexuetang.com +yushics.com +yushin88.com +yushiyan.net +yushiyuan.com +yushu5.com +yushunews.com +yusi.com +yusi.tv +yusi123.com +yusii.com +yusii.net +yusinvestment.com +yusiyy.com +yusmnfgh.vip +yusongec.com +yusuan.com +yusunjewelry.com +yusuusnw.com +yusxz.com +yutai365.com +yutainews.com +yutaoyouxi.com +yuteng.site +yutennet.com +yutian.cc +yutianedu.com +yutonad.com +yutong.com +yutongplay.vip +yutongzyc.com +yuttz.com +yutuwo.com +yuucn.com +yuudnn.com +yuwan-game.com +yuwang.com +yuwangcn.com +yuwanjianshe.com +yuwanyouxi.com +yuweikuijianzhan.com +yuweitek.com +yuweiyanwo.com +yuwell.com +yuwellgroup.com +yuwen.net +yuwen123.com +yuwen360.com +yuwenchaoshi.com +yuwenmi.com +yuwennews.com +yuwenxiandaihua.com +yux.team +yuxianall.com +yuxiangwang0525.com +yuxianxing.com +yuxiaogroup.com +yuxiaor.com +yuxiaotuo.com +yuxicorrosion.com +yuxinews.com +yuxinoulogistics.com +yuxipark.com +yuxitech.com +yuyangtec.com +yuyaoclub.com +yuyaotop.com +yuyejt.com +yuyicai.com +yuyin.tv +yuyinct.com +yuyinfanyi.com +yuyingufen.com +yuyoung32.com +yuyouyouxi.com +yuyu.com +yuyue111.com +yuyue27.com +yuyuecoat.com +yuyueshop.com +yuyuetec.com +yuyuetui.com +yuyueweb.com +yuyuezhiyangji.com +yuyunkj.com +yuyuntang.com +yuyuntech.com +yuzeli.com +yuzeli.net +yuzhengzixun.net +yuzhenhai.com +yuzhicaiexpo.com +yuzhiguo.com +yuzhike.com +yuzhong.biz +yuzhong.net +yuzhongxxw.com +yuzhoua.com +yuzhouwan.com +yuzhouyiyuan.com +yuzhua.com +yuzhuan.com +yuzhulin.com +yuzhuw.com +yuzijiaoyu.com +yuzmshanghai.org +yuzone.net +yuzua.com +yuzundaojia.com +yvkkqfy7m.shop +yvrdream.com +yvv.in +yvzfgigpiwmofux.com +yw11.com +yw160.com +yw2005.com +ywart.com +ywbank.com +ywcbs.com +ywclxp.com +ywdier.com +ywditan315.com +ywei.org +yweisugar.com +ywfby.com +ywgc.net +ywgd.com +ywhack.com +ywhqs.com +ywies-bj.com +ywies-gz.com +ywies-sh.com +ywies-shpd.com +ywindex.com +ywinf.com +ywint.net +ywit.xyz +ywjinfabag.com +ywkefu.com +ywky.org +ywlandport.com +ywnds.com +ywnz.com +ywopt.com +ywork.me +ywpark.net +ywputxks.com +ywshouyou.com +ywshouyou.net +ywsoftware.com +ywstsb.com +ywt.com +ywtd.xyz +ywtds.com +ywurl.com +ywvzxeau.com +ywwg.net +ywwl.com +ywwpay.com +ywxue.com +ywxww.net +ywyanxing.com +ywyishi.com +ywziwei.com +ywzt.org +ywzz.com +yx-g.com +yx-s.com +yx-s.net +yx0599.com +yx090.com +yx12345.com +yx1312.com +yx192.com +yx231.com +yx643.com +yx7088.com +yx74.com +yx7507.com +yx8tya36v8bp.com +yx93.com +yx988.com +yx99.com +yxacc6.com +yxad.com +yxaz.com +yxbabe.com +yxbao.com +yxbhhbkj.com +yxbk.com +yxbox91.com +yxbrand.com +yxc.hk +yxcal.com +yxcax.com +yxcc.net +yxcity.com +yxcustom.com +yxcxfw.com +yxdaily.com +yxdd.com +yxdh.com +yxdimg.com +yxdinghuo.com +yxdmgame.com +yxdou.com +yxdown.com +yxdr.com +yxduo.com +yxdwj.com +yxecg.com +yxeht.com +yxen.net +yxepqcbc.com +yxflzs.com +yxfshop.com +yxfw.com +yxfwai.com +yxgames.fun +yxgcx.com +yxgczx.com +yxgf.net +yxgxbike.com +yxgxw.com +yxgxz.com +yxgzs.com +yxhao.com +yxhapi.com +yxhenan.com +yxhhdl.com +yxhhr.com +yxhi.com +yxhimg.com +yxhjgs.com +yxholding.com +yxhqj.com +yxhy.asia +yxhyu.com +yxi.cc +yxiangzu.com +yxiannetgz.com +yxianypin.com +yxid.net +yxielts.com +yxilogistics.com +yximgs.com +yxin18.com +yxinbao.com +yxintent.com +yxit.net +yxixy.com +yxjia.com +yxjjdby.com +yxjkhb.com +yxjob.net +yxjs.org +yxjsjg.com +yxjuren.com +yxjyy.net +yxk120.com +yxkfw.com +yxkjlcd.com +yxkxyghx.org +yxlaba.com +yxlady.com +yxlady.net +yxle.net +yxlele.com +yxlink.com +yxlmdl.net +yxlqge.com +yxlsj.com +yxm.com +yxmarketing01.com +yxmcu.com +yxmxc.com +yxn.fun +yxnu.net +yxnxz.com +yxool.com +yxopt.com +yxou.com +yxph.com +yxpk.net +yxpms.com +yxptfs.com +yxqiche.com +yxrb.net +yxrcw.com +yxrj.com +yxsc33.com +yxsea.com +yxsgame.com +yxsj.net +yxsos.com +yxss.com +yxssp.com +yxsxhj.com +yxt-tattoo.com +yxt.com +yxtidc.com +yxtk.xyz +yxttzb.com +yxtvg.com +yxuankeji.com +yxun.net +yxwh5.com +yxwic.com +yxwsgame.com +yxx-china.com +yxxgame.com +yxxurl.com +yxxzbox.com +yxybb.com +yxydns.com +yxylbz.com +yxyy33.com +yxyzjx.com +yxz.me +yxzcemet.com +yxzd.info +yxzggame.com +yxzhi.com +yxzoo.com +yxzp.net +yxzq.com +yxzu.com +yxzxgy.com +yxzzd.com +yy.com +yy11.com +yy138.com +yy1986.com +yy2169.com +yy2hd.com +yy365.com +yy4080.com +yy502.com +yy520.com +yy591.com +yy845.com +yy960.com +yyarea.com +yyblly.com +yybnet.net +yybox.cc +yycec.com +yyclouds.com +yyclub.org +yyclub.work +yycoin.com +yycqc.com +yycqfw.com +yyctrade.com +yyczxt.com +yydbzz.com +yydcs.com +yyddss.vip +yydl-china.com +yyds.co +yyds.pink +yyds.space +yydsmh.com +yydsok.com +yydszp.com +yydy.com +yydzh.com +yyearth.com +yyej.com +yyestar.com +yyets.com +yyfax.com +yyfdcw.com +yyfqm.com +yyfunning.com +yyg.com +yyg120.com +yyg7.com +yygamedev.com +yyge.com +yygold.com +yygongzi.com +yygrammar.com +yyh78.com +yyha168.com +yyhao.com +yyhh.com +yyhn365.com +yyhybz.com +yyi100.com +yyijt.com +yyixx.com +yyizu.com +yyjingyan.com +yyjxkj.com +yyjzt.com +yyk100.com +yykj.site +yykj2003.com +yykj8775.com +yykpx.com +yylending.com +yylivens.com +yylm.org +yymedias.com +yyming2.com +yymoban.com +yynetwk.com +yynykj.com +yyouren.com +yyoz.com +yypf-china.com +yypjyds.com +yypt.com +yyq.com +yyquan.vip +yyqyweb.com +yyqyyyy.com +yyrc.com +yyrec.com +yyrenting.com +yyrjd.net +yyrtv.com +yysf.cc +yyshangfu.com +yystatic.com +yysweb.com +yyszfsxx.com +yyszq.com +yytad.com +yytcdn.com +yytek.com +yytfood.com +yytiflytek.com +yytingli.com +yyuap.com +yywd.com +yywlsj.com +yywords.com +yyws.net +yywsb.com +yywsbjb.com +yywszzs.com +yywt.online +yywx888.com +yywz123.com +yywzw.com +yyx.com +yyxfilm.com +yyxfplayer.com +yyxmgl.com +yyxsen.com +yyxtao.com +yyxx100.com +yyxxgame.com +yyxxgameyw.com +yyxyjt.com +yyy1389.com +yyyeee.com +yyyisp.com +yyylll.com +yyymvp.com +yyyncp.com +yyyqkq.com +yyyqm.com +yyyxbl.com +yyyy.games +yyyyy.run +yyz100.com +yyzb-live.com +yyzdjd.com +yyzdm.com +yyzf.com +yyzf.vip +yyzls.com +yyzqta.com +yyzqtb.com +yyzsoft.com +yyzw.com +yyzx.org +yyzxcj.com +yyzy-play.vip +yyzyytj.com +yyzzqk.com +yyzzsem.com +yz-iot.com +yz-kjjt.com +yz-li.com +yz-machinery.com +yz-proton.com +yz-show.com +yz-xd.com +yz0752.com +yz168.cc +yz2pp.com +yz2y.com +yz360.cc +yz3c.com +yz3l.com +yz4l.com +yzajz.com +yzbank.com +yzbhn.work +yzbo.tv +yzbpro.com +yzbqzx.net +yzbsytl.com +yzceg.com +yzckjt.com +yzcn.net +yzcnet.com +yzcrown.net +yzcsoft.com +yzcxx.com +yzcyj.net +yzcyjy.com +yzcyts.com +yzdfyy.com +yzdhxx.com +yzdir.net +yzdjkcy.com +yzdn.net +yzdryer.com +yzdx99.com +yzdxnews.com +yzdyhwh.com +yzeco.com +yzej.com +yzemd.com +yzfang.com +yzfbgjj.com +yzfc8.com +yzfcdn.com +yzfchat.com +yzfdc.net +yzfjy.com +yzfrkf.com +yzftpx.com +yzfybj.com +yzgcsj.com +yzgcyy.com +yzggdj.com +yzgjgs.com +yzgnet.com +yzgttm.com +yzgzx.com +yzh.li +yzhbw.net +yzhcloud.com +yzhdyy.com +yzhejin.com +yzhi.cc +yzhifupay.com +yzhmyy.com +yzhotels.com +yzhp.com +yzhqyy.com +yzhrhl.com +yzhsk.com +yzhuali.com +yzhx.net +yzhyai.com +yzie.net +yziin.com +yzimgs.com +yzinter.com +yzitc.com +yzj.cc +yzja.com +yzjb.com +yzjdgs88.com +yzjiaozhai.com +yzjj120.com +yzjjw.net +yzjob.net +yzjship.com +yzjsxy.com +yzjtcyjt.com +yzjtech.com +yzjyfz.com +yzkdfcw.com +yzkhfw.com +yzkimage.com +yzkjpcb.com +yzkos.com +yzlngi.com +yzlxjt.com +yzlyxx.com +yzmary.com +yzmat.com +yzmcms.com +yzmcxx.com +yzmg.com +yzmgf.com +yzmiao03.com +yzmls.com +yzmoney.com +yznano.com +yzncms.com +yznn.com +yzntv.com +yzops.net +yzpanstar.com +yzpetfood.com +yzpfbyy.com +yzport.com +yzqcw.com +yzqgamefun.com +yzqx.com +yzqzf.com +yzra900.com +yzrayy.com +yzrb.com +yzrc.net +yzren.com +yzrenai.com +yzrom.com +yzrshop.com +yzrsks.com +yzrss.com +yzrzgroup.com +yzs.com +yzs.io +yzsbh.com +yzsbhjt.com +yzsfuer.com +yzshkjxx.com +yzshyzz.com +yzsljz.com +yzsnen.com +yzsrmyy.org +yzsszw888.com +yzstudio.net +yzsz.net +yzsz3.icu +yzszsxh.com +yzszyy.com +yzt-tools.com +yzt888.com +yztcdn.com +yztchg.com +yztjb.net +yztzairport.net +yzw.cc +yzwb.com +yzwb.net +yzweekly.com +yzx0771.com +yzxcfdj.com +yzxdyrmyy.com +yzxw.com +yzxxfzy.com +yzy-gx.com +yzyhyy.com +yzyjhg.com +yzyouth.com +yzywhw.com +yzyxart.com +yzyxgame.com +yzyz.org +yzzcyy.com +yzzd.com +yzzp.com +yzzpw.com +yzzs.cc +yzzsoft.com +yzzxjyjt.com +yzzxxz.com +yzzy-online.com +yzzy20-play.com +yzzy29-play.com +yzzy31-play.com +yzzyimages.com +z-bank.com +z-henergy.com +z-inn.com +z-tek.com +z.ai +z.wiki +z0.cc +z01.com +z0ukun.com +z120.com +z12345.com +z17.link +z1987.com +z1cdn.com +z211.top +z211.vip +z28j.com +z2chain.com +z2ehospital.com +z2imc.com +z2sci.com +z2u.tv +z3145x0367.com +z316.com +z318.com +z3quant.com +z4bgpo.com +z4gwsoqmcvxt.com +z574.com +z5encrypt.com +z5w.net +z5z4.com +z668.net +z6e.com +z701.com +z729.com +z7xz.com +z82a3814j5.com +z888.net +z8cqv59kh3ip.com +z8q.cc +z99.biz +z9cdn.com +za-cosmetics.com +za-doctor.com +za8g1nx4ft.com +zabxib.com +zac1993.com +zachina.org +zack.asia +zacveh.com +zadervice.com +zaduonews.com +zaecu.com +zaeke.com +zaepi.com +zafinsvc.com +zafk120.com +zahtb.com +zahui.fan +zahuishi.com +zahuod.com +zahuoji.com +zai-art.com +zai-xian.com +zaibaoan.com +zaidu.org +zaiduu.com +zaiemei.com +zaifan.com +zaigl.com +zaiguahao.com +zaih.com +zaihuangshi.com +zaijia.com +zaijiawan.com +zailaboratory.com +zailingtech.com +zailouxia.com +zaimanhua.com +zaiminglvsuo.com +zainanjing365.com +zaitong.net +zaiwai.com +zaiweiwx.com +zaiwenai.com +zaixian100f.com +zaixianfanyi.com +zaixiangzx.com +zaixianjisuan.com +zaixiankaoshi.com +zaixianps.cc +zaixianvip.net +zaixs.com +zaiyulin.com +zaiyunli.com +zajiebao.com +zajilu.com +zajourney.com +zakc.group +zaker.com +zaku.fun +zakww.com +zalandode.com +zallcn.com +zallgo.com +zallimg.com +zalljinfu.com +zallsoon.com +zallxk.com +zamcs.com +zampdmp.com +zamplink.net +zan-live.com +zanao.com +zanba.com +zanbai.com +zancar.com +zangao.com +zangaopet.com +zangdiyg.com +zangenggroup.com +zangft.com +zanggekuangye.com +zanghaihuatxt.com +zanglikun.com +zangto.com +zangx.com +zangyitang123.com +zangyitong.com +zanig.com +zanih.com +zankee1955.com +zanlaa.com +zanmeizhibo.com +zanpic.com +zanpu.com +zanyiba.com +zaobang.com +zaoche168.com +zaodao.net +zaodian.com +zaodin.com +zaodula.com +zaofabiao.com +zaofacai.com +zaogai.com +zaojiadoc.com +zaojiance.com +zaojiance.net +zaojiao.com +zaojiaxueshe.com +zaojiu.com +zaojuge.com +zaojuzi.com +zaojv.com +zaoowoo.com +zaoqiangzhiheng.com +zaowandushu.com +zaowuyun.com +zaoyang.org +zaozuo.com +zapak.com +zapyamobile.com +zaqizaba.xyz +zarcw.com +zarsion.com +zastatic.com +zasv.com +zasv.net +zasysz.com +zasyuhkq.com +zat.cc +zatan.com +zatanb1.com +zatest.com +zaticdn.com +zattc.com +zaucyih.com +zauoehg.com +zawomkv.com +zaxdcredit.com +zaxline.com +zaxzn.com +zaysz.com +zazhipu.com +zazsz.com +zb-kc.com +zb.dehua.tv +zb.pzhgd.com +zb1.org +zb18.net +zb8.com +zb800.com +zb99.net +zbao.com +zbao56.com +zbbar.net +zbbm.net +zbbus.com +zbbx.org +zbc.pub +zbc.wiki +zbca.com +zbcars.com +zbchem.com +zbcyrq.com +zbczce.com +zbdedu.com +zbdzy.com +zbfilm.com +zbgala.com +zbgarden.cc +zbgedu.com +zbgl.net +zbgscm.com +zbhbkj.com +zbhot.com +zbhouse.com +zbhuafx.com +zbii.com +zbinfo.net +zbintel.com +zbird.com +zbisq.com +zbitcloud.com +zbiwl.com +zbj.com +zbj66.com +zbjdev.com +zbjdr.com +zbjiangsu.com +zbjimg.com +zbjsaas.com +zbjwork.com +zbjzgroup.com +zbkb.com +zblcyy.com +zblhh.com +zblhrl.com +zbling.com +zbljw.com +zblogcn.com +zblzm.xyz +zbmag.com +zbmbj.com +zbmeishu.com +zbnews.net +zbo0n.com +zbom.com +zbopr.net +zboqc.com +zbpengxuan.com +zbqlm.com +zbqtwbzr.com +zbra-inc.com +zbrhsc.com +zbrty.com +zbsfdy.com +zbsjzy.com +zbsonline.com +zbstatic1.com +zbstatic5.com +zbsyzx.com +zbszkj.com +zbt-china.com +zbt.com +zbt.net +zbt100.com +zbtaizhan.com +zbtbjt.com +zbtianao.com +zbudbq.sbs +zbusa.com +zbw315.com +zbwbbs.com +zbwdj.com +zbwg.cc +zbwmy.com +zbwpay.com +zbxcck.com +zbxinmeiti.com +zbxjgs.com +zbxsoft.com +zbxyh.com +zbxyly.com +zbyads.com +zbycg.com +zbycorp.com +zbyinghe.com +zbylc.com +zbytb.com +zbyz.net +zbz.com +zbzb.org +zbzdm.com +zbzw.com +zbzw.la +zc-gs100.com +zc-ha.com +zc-it.com +zc0317.com +zc173.com +zc532.com +zc61.com +zc6sigma.com +zcaijing.com +zcawuhvr.com +zcbearing.com +zcbgy.net +zcbm580.com +zcccc.com +zccninfo.com +zccrzx.com +zcdiesel.com +zcdlkeji.com +zcdog.com +zcdz1688.com +zcedi.com +zcedustudy.com +zcfc.com +zcfeed.com +zcfirst.com +zcfuhua.com +zcfun.com +zcfy.cc +zcgg.net +zcgou.com +zcgsfy.com +zcgsh.com +zchat.tech +zchb-water.net +zchmbx.com +zchmh.com +zchospital.com +zchrgroup.com +zcict.com +zcimg.com +zcinfo.net +zcitidc.net +zciv.com +zcjbgame.com +zcjce.com +zcjhsdk.com +zcjxedu.com +zcjxzl.com +zckb001.com +zckdwx.com +zckp.com +zclkj.com +zclock.xyz +zcloud.world +zclqzls.com +zcmlc.com +zcmol.com +zcmpark.com +zcnest.com +zcoa365.com +zcobrand.com +zcodesign.com +zcofuture.com +zcom.com +zcomc.com +zcoming.com +zcooler.com +zcosz.com +zcowh.com +zcpc.net +zcpd.cc +zcpm.net +zcpzj.com +zcqh.com +zcqss.com +zcqtz.com +zcrcw.com +zcrczp.com +zcread.com +zcry007.com +zcs.cc +zcsbbs.com +zcscz.com +zcset.com +zcsweb.com +zcszcm.com +zctec.cc +zctl.net +zctpt.com +zctt.com +zctx.com +zctzgr.com +zcwin.com +zcwlsc.com +zcwxjx.com +zcwz.com +zcxcl.com +zcxd9.com +zcxn.com +zcxsl.com +zcycdn.com +zczbzx.com +zczj.com +zczy100.com +zczy56.com +zczyofficial.com +zd-auto.com +zd-brake.com +zd-dl.com +zd-hs.com +zd-pm.com +zd-power.com +zd.biz +zd.hk +zd200572.com +zd315.net +zdanfu.com +zdao.com +zdaoxb.com +zdaq999.com +zdaye.com +zdbfjj.com +zdbiogene.com +zdbnm.com +zdcgc.com +zdcj.net +zdcjw18.com +zdcs666.com +zdctid.com +zddhr.com +zddhub.com +zddjq.com +zddr.com +zddream.com +zdepay.com +zdeqs.com +zdevo.com +zdfans.com +zdfdc.com +zdfei.com +zdfx.net +zdgkyy.com +zdgxchina.com +zdgzc.com +zdh0.com +zdh168.com +zdhaitao.com +zdhaitao.net +zdhuoyunbao.com +zdhyibiao.com +zdiao.com +zdic.net +zdjt.com +zdkfq.com +zdkqyy.com +zdlink.com +zdlpk.net +zdm.net +zdmimg.com +zdmq.com +zdmq88.com +zdmr.net +zdnph.com +zdnscloud.biz +zdnscloud.com +zdnscloud.info +zdnscloud.net +zdomo.com +zdong.net +zdpower.com +zdrcw.com +zdsdp.com +zdsee.com +zdsfy.net +zdsju.com +zdslb.com +zdsr.net +zdtent.com +zdvalves.com +zdvc.net +zdwafis.com +zdwallcovering.com +zdwang.com +zdwfy.com +zdwmq.com +zdworks.com +zdwx.com +zdwx.net +zdwx.vip +zdxlz.com +zdyfy.com +zdz.la +zdzdm.com +zdzwtesting.com +zdzxtech.com +ze-assemble.com +ze-clock.com +ze-grow.com +ze-introduce.com +ze-invite.com +ze-mp.com +ze-wx.com +zeaho.com +zealer.com +zeali.net +zealquest.com +zealsafe.net +zebangedu.com +zebracdn.com +zebraenglish.biz +zebraenglish.com +zebred.com +zecsma.com +zeda1.com +zedyer.com +zeedao.com +zeehoev.com +zeekrlife.com +zeekrline.com +zeelis.com +zeesin.com +zeeteq.com +zeetzj.com +zeewain.com +zegarkirepliki.pl +zegnau.shop +zego.im +zeguoren.com +zeheng.com +zeidei.com +zeiet.com +zeisis.com +zeisp.com +zejiexinxi.com +zeju.com +zejunpharma.com +zeku.com +zekv.com +zeldacn.com +zelinai.com +zemc.vip +zemismart.com +zen-est.com +zencheer.com +zengdefei.com +zengenti.com +zengjunpeng.com +zengjunyin.com +zenglong3d.com +zengrong.net +zengslb.com +zengyongfu.com +zengyt.com +zengzeng.net +zenha.net +zenhotspring.com +zenith-group.net +zenithfashion.asia +zenithmining.com +zenithspace.net +zenixauto.com +zenkungforging.com +zenlesszonezero.com +zenmen.com +zenner-metering.com +zeno-tech.com +zenoven.com +zenshine-pharma.com +zentao.net +zentaopm.com +zepcc.com +zepdi.com +zeperd.com +zepp.com +zeq366.net +zero2me.com +zerobreeze.com +zerocollege.com +zerogfans.com +zeroling.com +zerongjituan.com +zerontruck.com +zeroonead.com +zeropartner.com +zerotogether.net +zerseager.com +zeruns.com +zerustech.com +zesee.com +zeshengproject.com +zeshengshun.online +zeshengtecphar.com +zesidasi.com +zesmob.com +zeststore.com +zetacn.com +zetaijituan.com +zetast.com +zetbig.com +zetcloud.com +zettlernb.com +zetyun.com +zeusai.xin +zeuux.com +zeuux.org +zexiaoqiao.com +zeyouquan.com +zeyu99.com +zeyuan.shop +zeyuan123.com +zezhengcnc.com +zezhenwangluo.com +zezhuanggd.com +zf313.com +zf360.net +zf3d.com +zfancy.net +zfb369.com +zfboke.com +zfbzhsq.com +zfcm.net +zfdliot.com +zfdmkj.com +zfemc.com +zfengit.com +zffan.com +zfgy88.com +zfhz.org +zfile.vip +zfj1441.com +zfkg.com +zfkjgw.com +zfl9.com +zfnet.net +zfowed.com +zfrontier.com +zfrykj.com +zfsc.com +zfservicescn.com +zfsf.com +zfsjy.com +zfsjzx.com +zfsoft.com +zft.com +zftime.com +zfty.work +zfvnet.com +zfw.net +zfwlxt.com +zfwx.com +zfxz.com +zfyypt.com +zg-gaoling.com +zg-gyt.com +zg-import.com +zg-imsoft.com +zg-seastar.com +zg114jy.com +zg114w.com +zg114zs.com +zg118.com +zg163.net +zg3721.com +zg388.com +zg58.com +zgaode.com +zgaxr.com +zgazxxw.com +zgbaili.cc +zgbenrun.com +zgbfw.com +zgbghdw.com +zgbk.com +zgblh.com +zgbmcl.com +zgbnt.com +zgboke.com +zgbszf.com +zgby114.com +zgbywl.com +zgc-bigdata.org +zgc261.com +zgcbank.com +zgcbb.com +zgccity.com +zgcdiy.com +zgcgjn.com +zgchawang.com +zgchawenhua.com +zgchospital.com +zgchrx.com +zgcicc.com +zgcindex.org +zgcjm.org +zgcjpx.com +zgclease.com +zgclzzc.com +zgcmc.com +zgcmlm.com +zgcsa.org +zgcswhcbw.com +zgcszkw.com +zgcups.com +zgcwpark.com +zgcxbs.com +zgcznet.com +zgczrj.com +zgddek.com +zgddmx.com +zgdjw.com +zgdlfzw.com +zgdlzb.org +zgdmly.com +zgdnjj.com +zgdqcy.com +zgdqjy.com +zgdsw.com +zgdwzp.com +zgdxhbkf.com +zgdych.com +zgdydyxh.com +zgdygf.com +zgdztk.com +zgeyanwo.com +zgfllt.com +zgfp.com +zgfwgj.com +zgfxnews.com +zgfzh.com +zgfznews.com +zgfznj.com +zgg.com +zggas.com +zggbdsw.net +zggbhb.com +zggcks.com +zggd.city +zgggws.com +zgggz.com +zggjgy.com +zggjsmc.com +zggldgj.com +zgglkx.com +zgglyun.com +zggqzp.com +zggroups.com +zggtxhw.com +zggua.com +zggwy.com +zggwy.org +zggxgp.com +zggxhj.com +zggxlbc.com +zggxsmlt.com +zggye.com +zggysyw.com +zggzgg.com +zggzzk.com +zgh.com +zghaojiaoyu.com +zghaopingche.com +zghbxh.org +zghctc.com +zghdch.com +zghde.com +zghhzx.net +zghlzs.com +zghongbiao.com +zghongqi.com +zghotnews.com +zghtcd.com +zghtedu.com +zghtqk.com +zghy.com +zghzp.com +zghzsk.com +zgjcks.com +zgjct.com +zgjgw.com +zgjhjy.com +zgjianfang.com +zgjiaoyan.com +zgjiayang.com +zgjiemeng.com +zgjinglong.com +zgjjzyjy.org +zgjl123.com +zgjm.net +zgjm.org +zgjmorg.com +zgjrcw.com +zgjrjw.com +zgjrw.com +zgjscopper.com +zgjsdsj.com +zgjsks.com +zgjsqw.com +zgjsyw.com +zgjt518.com +zgjtb.com +zgjxcad.com +zgjxjjw.com +zgjymg.com +zgjzy.org +zgkao.com +zgkashi.com +zgkawah.com +zgkfzz.com +zgkjb.com +zgkjcx.com +zgkjw.org +zgkjxww.com +zgkjzx.com +zgkqth.com +zgkqw.com +zgkyb.com +zglb.org +zglcn.net +zglcxyxzz.com +zglcyx.com +zglibrary.com +zglipin.com +zgljl2012.com +zglushang.com +zglutongjituan.com +zglwb.com +zglww.net +zglxw.com +zglyfair.com +zglyrc.com +zglyz.com +zgmba.com +zgmcxw.com +zgmdbw.com +zgmh.net +zgmicro.com +zgmsbw.com +zgmsbweb.com +zgmscmpm.com +zgmxjjgs.com +zgmxl.com +zgmzgsx.com +zgmzyyzz.com +zgnfys.com +zgng.com +zgnhzx.com +zgnjm.com +zgnnwdkj.com +zgnt.cc +zgnt.net +zgnwp.com +zgny.com +zgnyw.net +zgoa.net +zgong.com +zgoog.com +zgpingshu.com +zgpj.net +zgps168.com +zgpts.com +zgpy168.com +zgqbyp.com +zgqcdt.com +zgqczj.com +zgqdrc.com +zgqkgw.com +zgqkk.com +zgqw.com +zgqywhcbw.com +zgqyzxw.com +zgqzjt.com +zgqzswdx.com +zgrcjlxh.com +zgrcjyw.com +zgrd.org +zgrdnews.com +zgrlm.com +zgruisai.com +zgrzbj.com +zgsclp.com +zgsd.net +zgsepri.com +zgserver.com +zgshenglu.com +zgshgs.com +zgshige.com +zgshige.net +zgshjj.com +zgshoes.com +zgshq.com +zgshuhuaxh.com +zgshxd.com +zgshxfw.com +zgshyshyxh.com +zgsj.com +zgsjcn.com +zgsjl8.com +zgsjshy.com +zgslb.net +zgslylw.com +zgsmile.com +zgsmmhw.com +zgsmsy.net +zgsnzj.com +zgsof.com +zgspws.com +zgsssss.com +zgsta.com +zgstly.net +zgswcn.com +zgswzys.com +zgsxzs.com +zgsyb.com +zgsydw.com +zgsynews.com +zgsyqx.com +zgsyz.com +zgszglfh.com +zgszjs.com +zgtaining.com +zgtcc.com +zgtcyswh.com +zgtghccl.com +zgtianlong.com +zgtianqi.com +zgtjqxh.com +zgtnzx.com +zgtop10.com +zgtuku.com +zgty188.com +zgtygg.com +zgtywdysxh.com +zgtzc.com +zgtzhb.com +zgtzqvk.com +zgui.com +zguonew.com +zgvmxma.com +zgw.com +zgweimeng.com +zgwhfe.com +zgwlwx.com +zgwstxc.com +zgwt.co +zgwypl.com +zgxcc.com +zgxcfx.com +zgxcw.com +zgxetnw.com +zgxh.net +zgxhm.com +zgxk.org +zgxledu.com +zgxmlsp.com +zgxnnews.com +zgxnyhyxh.com +zgxnyxh.com +zgxqwqh.com +zgxrjy.com +zgxsczdldak.com +zgxue.com +zgxytc.com +zgxyzx.net +zgxzcj.com +zgxzhjx.com +zgybsfxh.com +zgycgc.com +zgyeda.com +zgyey.com +zgyhbc.com +zgyhys.org +zgyjlf.com +zgylbx.com +zgylj.com +zgyouth.cc +zgys.net +zgyssyxh.com +zgysw.cc +zgytc.com +zgyxjt.com +zgyxzs.com +zgyygl.com +zgyyjgw.com +zgyykx.com +zgyythy.com +zgyyzn2004.com +zgyzyq.com +zgzb.com +zgzca.com +zgzcw.com +zgzcwy.com +zgzhmz.com +zgzjjcy.com +zgzjzzs.com +zgznh.com +zgznjt.com +zgzpsjz.com +zgzsa.com +zgzsrc.com +zgzszy.com +zgzy.net +zgzypyw.com +zgzyxxzs.com +zgzzs.com +zgzzxx.com +zh-an-pg-gaming.com +zh-ansheng.com +zh-brimed.com +zh-chem.com +zh-cjh.com +zh-douqiutiyu.com +zh-gs.com +zh-hbs.com +zh-heshi.com +zh-hks-slotsimulator.com +zh-hr.com +zh-hz.com +zh-itone.com +zh-jieli.com +zh-jinhang.com +zh-languan.com +zh-le-slotsimulator.com +zh-longshi.com +zh-piao.com +zh10.com +zh189.com +zh818.com +zh996.com +zha.co +zhaeec.com +zhai14.com +zhaiba.com +zhaibao.vip +zhaibian.com +zhaidou.com +zhaihai.com +zhaijihui.com +zhaijis.com +zhaikexueyuan.com +zhainanba.net +zhainanfulishe.com +zhainanhuayuan.com +zhaipan.vip +zhairport.com +zhaitushe.com +zhaiwuu.com +zhaixiaoniu.com +zhaixue.cc +zhale.me +zhan.com +zhanbanji.com +zhanbuba.com +zhanchenyouqi.com +zhanchily.com +zhandaren.com +zhandian88.com +zhandodo.com +zhang-chu.com +zhang365.com +zhangbj.com +zhangbo.org +zhangchangfa.com +zhangchi.art +zhangdongxuan.com +zhangdu.com +zhangdu5.net +zhangdu520.com +zhange8.com +zhangfeibiao.com +zhangfensir.com +zhangferry.com +zhangfupeng.com +zhanggaoyuan.com +zhangge.net +zhanghaodaren.com +zhanghetianxia.com +zhanghonghong.com +zhanghongliang.com +zhanghuang.com +zhangjet.com +zhangjiee.com +zhangjinyue.com +zhangjunbk.com +zhangkai.red +zhangketong.com +zhangkongapp.com +zhangkoubei.net +zhangku.com +zhangle.com +zhangleglobal.com +zhangli2015.com +zhanglinfeng09.com +zhangliziyun.com +zhangluya.com +zhangmen.com +zhangmen.org +zhangmenkid.com +zhangnan.xyz +zhangnq.com +zhangqi.ltd +zhangqiaokeyan.com +zhangqiongjie.com +zhangqiu.cc +zhangqiubus.com +zhangrc.site +zhangread.com +zhangrunnan.com +zhangsenhao.com +zhangshangtong.com +zhangshengcw.com +zhangshengrong.com +zhangshi.org +zhangshuchang.com +zhangsifan.com +zhangtaiwuye.com +zhangtu.com +zhangu365.com +zhangwan.net +zhangwei.li +zhangwenli.com +zhangwojumian.com +zhangxin.ltd +zhangxinhulian.com +zhangxinkeji.com +zhangxinmj.com +zhangxinxu.com +zhangxiu.com +zhangyi123.com +zhangyoubao.com +zhangyoushijie.com +zhangyu.com +zhangyu39.com +zhangyuanqiang.com +zhangyue.com +zhangyue.net +zhangyue01.com +zhangyue02.com +zhangyue03.com +zhangyuecdn.com +zhangyupeng.com +zhangzepower.com +zhangzhao.me +zhangzhengfan.com +zhangzhongpei.com +zhangzhongyun.com +zhangzhuo.ltd +zhangzidao.com +zhangzifan.com +zhangziran.com +zhangzishi.cc +zhanh.com +zhanhi.com +zhanhome.com +zhanhuidaili.com +zhanhuiniu.com +zhanhuiquan.com +zhanhuo.com +zhanid.com +zhankoo.com +zhankuaqq.com +zhanlingol.com +zhanmang.com +zhanq.net +zhanqi.net +zhanqi.tv +zhanqitv.com +zhanqu.tv +zhanruizb.com +zhanshaoyi.com +zhanshi888.com +zhanshifood.com +zhanshiren.com +zhansu.com +zhantuo.com +zhanuan.com +zhanxingfang.com +zhanyouyun.com +zhanyugroup.com +zhanzhanbao.com +zhanzhangb.com +zhanzhangs.com +zhao-meng.com +zhao123.org +zhaoba.net +zhaobeijing.com +zhaobenshan.tv +zhaobiaoziyuan.com +zhaobide.com +zhaobuxiu.com +zhaocaimall.com +zhaocaiyan.com +zhaochanpin.com +zhaochao.xyz +zhaochongwu.com +zhaoda.net +zhaodanji.com +zhaodaojia.com +zhaodedao.xyz +zhaodigroup.com +zhaodll.com +zhaodns999.com +zhaofangbang.net +zhaofenxiang.com +zhaogang.com +zhaogangimg.com +zhaogui.com +zhaohaowang.com +zhaohe.net +zhaoheng-cpm.com +zhaoiphone.com +zhaojiafang.com +zhaojiao.net +zhaojiaoan.com +zhaojiaxiao.com +zhaojs.com +zhaojunhg.com +zhaoka.com +zhaokaifeng.com +zhaokao.net +zhaokaocn.com +zhaokeli.com +zhaoketang.com +zhaokuaizhao.com +zhaolaobanla.com +zhaoliangji.com +zhaoliming.net +zhaomengtu.com +zhaoming.biz +zhaomishijie.com +zhaomu.com +zhaomuqingyun.com +zhaomxd.com +zhaoniupai.com +zhaoonline.com +zhaopianzhibo.com +zhaopin.com +zhaopin400.com +zhaopin668.com +zhaopinbao.me +zhaopingou.com +zhaopinrugao.com +zhaopintangyin.com +zhaoplc.com +zhaoqianwang.com +zhaoqiufa.com +zhaoqt.net +zhaoquanwang.vip +zhaoren.net +zhaorunsen.com +zhaosf.co +zhaosha.com +zhaoshang.net +zhaoshang100.com +zhaoshang800.com +zhaoshangbang.com +zhaoshangbao.com +zhaoshangdai.com +zhaoshayou.com +zhaosheng.com +zhaosheng365.com +zhaoshixi.com +zhaoshizhou.xyz +zhaosifang.com +zhaosuliao.com +zhaosw.com +zhaosy.com +zhaota8.com +zhaotaicaiyin.com +zhaotu.com +zhaouc.com +zhaouc.net +zhaowenyu.com +zhaowofanyi.com +zhaoxi.org +zhaoxiangliao.com +zhaoxiangyd.com +zhaoxiaoshuo.com +zhaoxin.com +zhaoxingfang.com +zhaoxitech.com +zhaoxuncaijing.com +zhaoyanblog.com +zhaoyangmao.com +zhaoyangsem.com +zhaoyangxueyuan.com +zhaoyaojd.com +zhaoyasai.com +zhaoybbk.com +zhaoyingtian.com +zhaoyinqian.com +zhaoyl.com +zhaoyo.com +zhaoyuan365.com +zhaoyun.com +zhaozhanxu.com +zhaozhishi.com +zhaozhonggong.com +zhaozongjie.com +zharev.com +zhatoufa.com +zhatuyunshu.com +zhayanwang.com +zhb1.com +zhbit.com +zhblawyer.com +zhboyang.com +zhbus.org +zhbx.net +zhby-point.com +zhcic.com +zhcidian.com +zhckw.com +zhcnews.com +zhcommerce.com +zhcomputing.com +zhcsgc.com +zhctv.com +zhcw.com +zhcyanshi.com +zhdfg.com +zhdgps.com +zhdhq.com +zhdhqc.com +zhdhqcz.com +zhdhqzy.com +zhdmwhg.com +zhdsbang.com +zhe.com +zhe800.com +zhe900.com +zhebei.com +zhebeipharm.com +zhebumai.com +zhechem.com +zhedabingchong.com +zhedu.net +zhefengle.com +zhefuhua.com +zhegu8.xyz +zheiyu.com +zhejiangcheng.com +zhejiangcircuit.com +zhejiangfa.com +zhejiangfc1998.com +zhejianghanpu.com +zhejianglab.com +zhejianglab.org +zhejiangliming.com +zhejianglong.com +zhejiangmuseum.com +zhejiangqinghe.com +zhejiangseed.com +zhejiangzhuohang.com +zhejing.tech +zhekoulieshou.com +zhekouniu.net +zhekouo.com +zhelaoda.com +zheli.com +zhelibao.com +zhelin.me +zhelixin.com +zheliyin.com +zhen-ao.com +zhen.com +zhenai.com +zhenaihn.com +zhenandl.com +zhenaoyaoye.com +zhenbanggd.com +zhenbi.com +zhenbizi.com +zhenchu.cc +zhending-chicken.com +zhendong365.com +zhendonggames.com +zhene.net +zhenfacloud.com +zhenfangyuan.com +zhenfund.com +zhengbang.com +zhengben56group.com +zhengbiaoke.com +zhengcaimall.com +zhengcaishangcheng.com +zhengchang.com +zhengdaijingji.com +zhengdaojiapei.com +zhengdaotang.com +zhengdapeanut.com +zhengdichaiqian.com +zhengdong.cc +zhengdongzulin.com +zhengerpin.com +zhengfalaw.com +zhengfayunpt.com +zhengfengnet.com +zhenggang.org +zhenggui.com +zhengguzhishen.com +zhenghai-ht.com +zhenghangplc.com +zhenghangyq.net +zhenghe.biz +zhenghewuye.com +zhenghong888.com +zhenghuiyaoye.com +zhengjia.com +zhengjianzhao.com +zhengjie.com +zhengjifb.com +zhengjimt.com +zhengkaji.com +zhenglonggroup.com +zhengmeng.net +zhengmin.com +zhengpengbo.com +zhengpic.com +zhengpinle.com +zhengqi100.com +zhengqingsong.com +zhengquan.org +zhengquan.work +zhengqun123.com +zhengruioi.com +zhengtaidianlan.com +zhengte.net +zhengtongcloud.com +zhengtoon.com +zhenguanyu.biz +zhenguanyu.com +zhenguo.com +zhengw-tech.com +zhengwei007.com +zhengwutong.com +zhengxiaoling.com +zhengxinbao.com +zhengxing021.com +zhengxingzhijia.com +zhengxinonly.com +zhengyaing.win +zhengyang-tek.com +zhengyaokeji.net +zhengyee.com +zhengyexing.com +zhengyounet.com +zhengyouyoule.com +zhengyuanfu.com +zhengyutuliao.com +zhengzai.tv +zhengzhaopai.com +zhengzhenxx.com +zhengzhou42195.com +zhengzhoubus.com +zhengzhoutools.com +zhengzhoutx.com +zhengzhouyunmei.com +zhengzihui.com +zhenhaofu.com +zhenhaotao.com +zhenhaotv.com +zhenheli.com +zhenhonggroup.com +zhenhospital.com +zhenhuadj.com +zhenhuan888.com +zhenimg.com +zhenjiatong.com +zhenjingtv.com +zhenkongbang.com +zhenlongvip.com +zhenmeidai.com +zhenmeifoods.com +zhenmeigroup.com +zhenpin.com +zhenren.com +zhenrongbao.com +zhenruhotels.com +zhenrun.press +zhensheng.com +zhenshi.com +zhenshigroup.com +zhenshua.com +zhenshungroup.com +zhensiyu.com +zhenstyle.com +zhensuo.tv +zhentaigroup.com +zhentan.la +zhentoo.com +zhenweiexpo.com +zhenwu.com +zhenxiad.com +zhenxiliangshi.com +zhenxin2014.com +zhenxinfu.com +zhenxipin.net +zhenyangshoes.com +zhenye.com +zhenyouliao.com +zhenyoumei.com +zhenyuansoft.com +zhenyunpan.com +zhenzhuchanfu.com +zheqc.com +zheshenet.com +zhetao.com +zhetian.org +zhetouniu.com +zheurl.com +zhewanji.net +zhexi.tech +zhexingzx.com +zhexinit.com +zhexinsteel.net +zheye.com +zheyibu.com +zheyinleasing.com +zheyouxinxi.com +zheyuntech.com +zhezheai.com +zhezhekan.com +zhezhewhkj.com +zhezhi.tech +zhfc.com +zhfivehospital.com +zhfund.com +zhfwq.com +zhfyhb.com +zhgc.com +zhgfanyi.com +zhgjx.com +zhgl.com +zhglory.com +zhgn.com +zhgnj.com +zhgreens.com +zhguoguo.com +zhgxjs.com +zhhainiao.com +zhhaitai.com +zhheo.com +zhhfedu.com +zhhfjt.com +zhhlaw.com +zhhlogistics.com +zhhrm.com +zhhs-china.com +zhhuahui.com +zhhuashengjt.com +zhhuihua.com +zhhy-oa.com +zhi-ming.com +zhi-niao.com +zhi.hu +zhi10.com +zhi3.net +zhiaimusic.com +zhiangit.com +zhiangroup.com +zhiannet.com +zhiantec.com +zhibaimeixue.com +zhibiao168.com +zhibiaow.com +zhibitouzi.com +zhibo.tv +zhibo8.cc +zhibo8.com +zhiboba.com +zhiboohui.com +zhiboqiao.com +zhiboyun.net +zhibs.net +zhibugongzuo.com +zhicaiwang.com +zhicall.com +zhichanli.com +zhichaoxt.com +zhicheng-champion.com +zhicheng.net +zhichepai.com +zhichepin.com +zhichi.com +zhichidata.com +zhichikeji.com +zhichiwangluo.com +zhichiweiye.com +zhicms.cc +zhicyun.com +zhidao91.com +zhidaochuanxin.com +zhidaoplan.com +zhidejian.com +zhidemai.com +zhidesoft.com +zhidi66.com +zhidianfan.com +zhidianlife.com +zhidieyun.com +zhidiy.com +zhidtech.com +zhiduopc.com +zhidx.com +zhienkeji.com +zhiexa.com +zhifa.cc +zhifa315.com +zhifang.com +zhifayangfa.com +zhifayiyuan.com +zhifeishengwu.com +zhifengtang.com +zhifou123.com +zhifoukeji.com +zhiftype.com +zhifufu.com +zhifujie.com +zhifuquanzi.com +zhifure.com +zhifux.com +zhifuzi.com +zhigaometal.com +zhige.net +zhigongfu.com +zhigou.com +zhigou888.com +zhigouyp.com +zhiguagua.com +zhiguang.me +zhigudata.com +zhiguf.com +zhiguoguo.com +zhihai.fun +zhihang100.com +zhihe.link +zhihe.mobi +zhiheiot.com +zhihejia.com +zhihejiaoyu.com +zhihemobi.com +zhihengwangchen.com +zhihepartners.com +zhihevip.com +zhihjf.com +zhihu.com +zhihu.dev +zhihua-tech.com +zhihuangjin.com +zhihudsp.com +zhihuichuangyanshi.com +zhihuiep.com +zhihuifangdong.net +zhihuihongze.com +zhihuihuiwu.com +zhihuihutong.com +zhihuiji.com +zhihuijingyingba.com +zhihuikangyang.com +zhihuimami.com +zhihuinanzhan.com +zhihuishan.com +zhihuishitang.net +zhihuishu.com +zhihuiwater.com +zhihuixiadan.com +zhihuixl.com +zhihuixuexipt.com +zhihuiya.com +zhihuiyunbo.com +zhihuizhangyu.com +zhihuizp.com +zhihuoseo.com +zhihur.com +zhiji.com +zhijia.com +zhijian114.com +zhijianbao.com +zhijianchuhai.com +zhijianfengyi.com +zhijiangames.com +zhijiannuoche.com +zhijiaow.com +zhijiaow.net +zhijiaoyi.com +zhijiapro.com +zhijiashe.com +zhijidoc.com +zhijie-edu.com +zhijieguo.com +zhijieketang.com +zhijin.com +zhijinwang.com +zhijizhibi.com +zhikaiis.com +zhikao100.com +zhikao365.net +zhikaocn.com +zhikaojy.com +zhikaowangxiao.net +zhiketong.com +zhiketong.net +zhikexun.com +zhikongyangpin.com +zhikuai.com +zhikubao.net +zhil.cloud +zhilandaren.com +zhilehuo.com +zhileiqiye.com +zhilepin.com +zhilian-nb.com +zhilian.com +zhilian.host +zhilianghui.com +zhiliangren.com +zhilianiot.com +zhiliaobiaoxun.com +zhiliaocaibao.com +zhiliaoke.com +zhilidata.com +zhilingshop.com +zhilitraffic.com +zhilongtech.com +zhiluo.net +zhima1688.com +zhimacangku.com +zhimaixiaodian.com +zhimantian.com +zhimap.com +zhimapay.net +zhimaquan.net +zhimaruanjian.com +zhimatech.com +zhimawenda.com +zhimaxkf.com +zhimei.com +zhimeibot.com +zhimeijiankang.com +zhimengdaren.com +zhimg.com +zhimi.com +zhiminglawyer.com +zhimodesign.com +zhimoe.com +zhineikaixin.com +zhinengdayi.com +zhinengjianzhan.com +zhinengxia.com +zhinengxiehui.com +zhinengyujia.com +zhinet.com +zhinianboke.com +zhiniceshi.com +zhinikefu.com +zhiniu8.com +zhinuoshuzi.com +zhinvnetwork.com +zhipan.net +zhipeix.com +zhiper.com +zhipianbang.com +zhipianbang.vip +zhipin.com +zhipingke.com +zhipucn.com +zhipuzi.com +zhiqi.info +zhiqiang.org +zhiqiapp.com +zhiqicms.com +zhiqihuo.com +zhiqihuo.org +zhiqijichu.com +zhiquanxia.com +zhiquapp.com +zhiquhuyu.work +zhiquyuan.com +zhiqwl.com +zhiren.com +zhiren.ren +zhiribao.com +zhiru.com +zhirui-inv.com +zhirui.net +zhiruiinvest.com +zhisanzhao.com +zhishanfu.com +zhishangnet.com +zhishangsoft.com +zhisheji.com +zhisheng.com +zhishengbang.com +zhishengtec.com +zhishengxinchuang-food.com +zhishi.com +zhishi.tech +zhishif.com +zhishifanli.com +zhishifenzi.com +zhishinn.com +zhishisoft.com +zhishiu.com +zhishiv.com +zhishiwu.com +zhishutang.com +zhishuyun.com +zhisiyun.com +zhisuoyi.net +zhitaiparking.com +zhitangvalve.com +zhitaosoft.com +zhitingtech.com +zhito.com +zhitongcaijing.com +zhitongpm.com +zhitouxing.com +zhituad.com +zhitui.com +zhitusoft.com +zhituwujie.com +zhituzhilian.com +zhivisaworld.com +zhiweidata.com +zhiweihome.com +zhiweisoft.com +zhiwenw.com +zhiwgx.com +zhiwo.com +zhiwo.work +zhiwu.com +zhiwushuo.com +zhiwutiyu.com +zhiwutong.com +zhixi.com +zhixiaochengxu.com +zhixiaohuoke.com +zhixiaosj.com +zhixiaowang.com +zhixin-semi.com +zhixingapp.com +zhixingit.com +zhixingjj88.com +zhixingyunke.com +zhixiu.net +zhixuan.com +zhixue.com +zhixue.org +zhixuedoc.com +zhixueyun.com +zhixunfang.com +zhixunkeji.xyz +zhiyakeji.com +zhiyanxuan.com +zhiyazz.com +zhiye.com +zhiyeapp.com +zhiyeguihua.com +zhiyequan.com +zhiyexueyuan.com +zhiyi.com +zhiyicx.com +zhiyinghui.com +zhiyingos.com +zhiyingyang.com +zhiyinhao.com +zhiyinlou.com +zhiyinmanhuawang.com +zhiyinmedia.com +zhiyoo.com +zhiyoubao.com +zhiyousx.com +zhiys.com +zhiyu-china.com +zhiyuan-robot.com +zhiyuanbang.com +zhiyuanshijie.com +zhiyuanxinglvye.com +zhiyuanyun.com +zhiyuanzhongyi.com +zhiyuapp.com +zhiyueit.com +zhiyun-cn.com +zhiyun-tech.com +zhiyunwang.net +zhiyutianqi.com +zhiyuyg.com +zhizaoyun.com +zhizeu.com +zhizhan360.com +zhizhen.com +zhizhi88.com +zhizhibaike.com +zhizhihu.com +zhizhizhi.com +zhizhizhi.net +zhizhonghl.com +zhizhoukeji.com +zhizhoumi.com +zhizhu35.net +zhizhucms.com +zhizhuip.com +zhizhuma.com +zhizhuwu.com +zhizhuyule.com +zhizhuyx.com +zhizihuan.com +zhizihuan.net +zhizugz.com +zhizunbo.com +zhizundun.com +zhizunnews.com +zhizuobiao.com +zhizuobiaojiaoyu.com +zhizuoh5.com +zhizuotu.com +zhj9.com +zhjd.org +zhjdkz.com +zhjgkg.com +zhjgkgjt.com +zhjgongjiao.com +zhjiameng.com +zhjianet.com +zhjingsai.com +zhjj.org +zhjncb.com +zhjtaq.com +zhjtong.com +zhjuche.com +zhjxwh.com +zhjypco.com +zhjzg.com +zhjzgroup.com +zhk.me +zhka.com +zhks.org +zhku.com +zhl.com +zhld.com +zhlhh.com +zhliaoshe.com +zhliqi.com +zhljq.com +zhlm.com +zhlqjt.com +zhltech.net +zhltraffic.com +zhlyen.com +zhlzw.com +zhmag.com +zhmedcenter.com +zhmeiwen.com +zhmf.com +zhmodaoli.com +zhmold.com +zhmu.com +zhmxchina.com +zhmzqi.com +zhnbj.com +zhnc-kaiyunapp.com +zhnfad.com +zhnsyh.com +zhong-yao.net +zhong.com +zhong100.com +zhongan.com +zhongan.io +zhongancloud.com +zhonganfengshang.com +zhonganguobao.com +zhonganib.com +zhonganinfo.com +zhongankang.com +zhonganweishi.com +zhongbao360.com +zhongbaounion.com +zhongbeiyouhao.com +zhongbenkeji.com +zhongbenwangluo.com +zhongbingtongxin.com +zhongbowenwu.com +zhongboxinwen.com +zhongcai.com +zhongcaistream.com +zhongcaisuo.com +zhongcetech.com +zhongche.com +zhongchebaolian.com +zhongchewuliu.com +zhongchouke.com +zhongchuang365.com +zhongchuangwenhua.com +zhongda021.com +zhongdajc.com +zhongdakang.com +zhongdazm.com +zhongdegroup.com +zhongdemetal.com +zhongdeng.com +zhongdengwang.com +zhongdeschool.com +zhongdexc.com +zhongdi168.com +zhongerp.com +zhongfeiqiao.com +zhongfu.net +zhongfuwatch.com +zhonggenggroup.com +zhonggu56.com +zhongguang.com +zhongguanpetro.com +zhongguinong.com +zhongguobaiyin.com +zhongguobingxue.com +zhongguociwang.com +zhongguoditu.com +zhongguofeng.com +zhongguogouliang.com +zhongguoguwan.com +zhongguohao123.com +zhongguohuo.com +zhongguopeixun.net +zhongguose.com +zhongguosou.com +zhongguoss.com +zhongguowangshi.com +zhongguoym.com +zhonggushipping.com +zhonghaitech.com +zhonghaojituan.com +zhonghe58.com +zhonghegame.com +zhonghengxingufen.com +zhonghengyiyao.com +zhonghhd.com +zhonghongwang.com +zhonghuacar.com +zhonghuacpa.com +zhonghuadiancang.com +zhonghuaent.com +zhonghuamba.com +zhonghuameiwang.com +zhonghuanjianbj.com +zhonghuanus.com +zhonghuaqiming.com +zhonghuasuan.com +zhonghuaying.com +zhonghuilv.com +zhonghuitj.com +zhonghuvalve.com +zhongji.cc +zhongjian.run +zhongjiangapp.com +zhongjianyiliao.com +zhongjiaochuxing.com +zhongjijidian.com +zhongjincc.com +zhongjintongsheng.com +zhongjiujiu.com +zhongjiunanshuo.com +zhongjixinyuan.com +zhongjukiln.com +zhongjunstone.com +zhongkaiedu.com +zhongkao.com +zhongkaohelp.com +zhongkecn.com +zhongkeguan.com +zhongkekc.com +zhongkerd.com +zhongkezhihang.com +zhongkongbancn.com +zhongkongdaikuan.com +zhongleny.com +zhongli.com +zhonglian.com +zhonglianbiao.com +zhonglianguanwei.com +zhongliangxny.com +zhonglianhuashu.com +zhonglianhuaxin.com +zhonglianyx.com +zhongliusp.com +zhongliuyiyuan.com +zhonglue-consulting.com +zhonglun.com +zhonglunnet.com +zhongluyuntong.com +zhongmaohr.com +zhongmei.com +zhongmeigk.com +zhongmian.com +zhongminenergy.com +zhongmingjiaoyu.net +zhongnakeji.com +zhongnengrecycling.com +zhongnice.com +zhongnongjimu.com +zhongp.com +zhongpaiwang.com +zhongpenggufen.com +zhongping.com +zhongpingcapital.com +zhongpujiancai.com +zhongqijiye.com +zhongqijt.com +zhongqingshao.com +zhongqixin360.com +zhongran.org +zhongrenbang.cc +zhongruihuacheng.com +zhongruitech.com +zhongruiyaoye.com +zhongsenmenye.com +zhongshan-hotel.com +zhongshanchengtai.com +zhongshang114.com +zhongshanpark.com +zhongshantoukong.com +zhongshanweixin.com +zhongshanzhekai.com +zhongshengdai.com +zhongshenglong.xyz +zhongshi-chem.com +zhongshiqixie.com +zhongshucan.com +zhongshungroup.com +zhongshuopg.com +zhongso.com +zhongsou.com +zhongsou.net +zhongtaihangzhou.com +zhongtaitrust.com +zhongtefamen.com +zhongtiancloud.com +zhongtieyintong.com +zhongtong.com +zhongtongshe.com +zhongtou.co +zhongtuirong.com +zhongtuobang.com +zhongtusy.com +zhongwang.com +zhongwangsc.com +zhongwei-info.com +zhongweicable.com +zhongweihotels.com +zhongweiteamtop.com +zhongwen.wiki +zhongwenhexinqikan.com +zhongwogroup.com +zhongwucan.com +zhongwulian.com +zhongxiang.com +zhongxiangdichan.net +zhongxiangwang.co +zhongxiaole.net +zhongxiaoyl.com +zhongxingglove.com +zhongxinjzzs.com +zhongxinkeji.vip +zhongxinwei.net +zhongxinzhongxue.com +zhongxisunve.com +zhongxues.com +zhongxuewuyou.net +zhongxuewy.net +zhongxunrunda.com +zhongxuntv.com +zhongxuyiyuan.com +zhongyagroup.com +zhongyangkeji.com +zhongyangweixiu.com +zhongyao365.com +zhongyapeicui.com +zhongyasmart.com +zhongyejy.com +zhongyf.com +zhongyi6.com +zhongyi9999.com +zhongyibaodian.com +zhongyiinc.com +zhongyiiot.com +zhongyiju360.com +zhongyingdp.com +zhongyingtougu.com +zhongyingyiyao.com +zhongyinlawyer.com +zhongyishangwu.com +zhongyisousuo.com +zhongyiyisheng.com +zhongyoo.com +zhongyouai.com +zhongyouex.com +zhongyougc.com +zhongyoumedia.com +zhongyu.com +zhongyu87.xyz +zhongyuan-sports.com +zhongyuanauto.com +zhongyue001.com +zhongyuefuwu.com +zhongyulian.com +zhongyunjt.net +zhongyunjy.com +zhongyunqianbao.com +zhongyuyx.com +zhongzaisheng.net +zhongzeny.com +zhongzetherapeutics.com +zhongzhaizs.com +zhongzhao.com +zhongzhen56.com +zhongzhenjiaoyu.com +zhongzhensen.com +zhongzhi-faqian.com +zhongzhide.com +zhongzhifaqian.com +zhongzhiiov.com +zhongzhilin.com +zhongzhixin.com +zhongzhixitong.com +zhongzhongkeji.com +zhongzhoulianhe.com +zhongzhouwater.com +zhongzhuang.com +zhongzilu.com +zhonshian.com +zhou.icu +zhouao.com +zhoubaitong.net +zhoubianyou.com +zhouchun.net +zhoudaosh.com +zhoufengsd.com +zhougong.com +zhouhaismart.com +zhouhing.com +zhouhoulin.com +zhoujiahong.com +zhoujianhui.com +zhoujifood.com +zhoujunji.com +zhoukaiwen.com +zhoulaoshi.club +zhoulingjie.com +zhoupu123.com +zhoupudata.com +zhouql.vip +zhouweitong.site +zhouxianghb.com +zhouxiaoben.info +zhouxingchi.info +zhouxuanyu.com +zhouyi.biz +zhouyi.cc +zhouyi114.com +zhouyiapi.com +zhouyiy.com +zhouyou360.com +zhouyouji.world +zhouzhuang.net +zhpca.com +zhpecc.com +zhpharm-sh.com +zhqgtjxh.com +zhqyue.com +zhrct.com +zhrczp.com +zhrtc.com +zhsapphire.com +zhsc.net +zhsecurity.net +zhsho.com +zhshw.com +zhsrcw.com +zhsumarc.com +zhsunway.com +zhsw.org +zhswfw.com +zhszcz.com +zht-cn.com +zhtdtech.com +zhtelecom.com +zhtfw.net +zhtgroup.com +zhthg.com +zhtlq.com +zhtmid.com +zhty.net +zhtyljt.com +zhu.today +zhuainiu.com +zhuajiyou.com +zhualeyixia.com +zhuancorp.com +zhuanfa.net +zhuanfou.com +zhuang520.com +zhuangbutong.com +zhuanghebm.com +zhuangji.net +zhuangjiba.com +zhuangjinshanhe.com +zhuangkou.com +zhuangku.com +zhuangpeitu.com +zhuangshengsheng.com +zhuangshijituansheji.com +zhuangxiang.cc +zhuangxiaomi.com +zhuangxiu.com +zhuangxiu567.com +zhuangxiubao.com +zhuangyanyanglao.com +zhuangyuantao.com +zhuangzhuang.net +zhuanhuamao.com +zhuanhuanqi.com +zhuanhuanqi.net +zhuaniao.com +zhuaninc.com +zhuankeapp.com +zhuankebang.com +zhuankezu.com +zhuanlichaxun.net +zhuanliqiao.com +zhuanmenmian.com +zhuanpinyin.com +zhuanqianba.net +zhuanspirit.com +zhuanstatic.com +zhuanwaifu.com +zhuanyejun.com +zhuanyepeixun.com +zhuanyes.com +zhuanyewanjia.com +zhuanyezhidao.com +zhuanyizhuanw.com +zhuanyun.cc +zhuanyun123.com +zhuanzfx.com +zhuanzhi.net +zhuanzhuan.com +zhuatang.com +zhuaxia.com +zhuayao.net +zhuayou.com +zhuayoukong.com +zhuayuya.com +zhuazi.com +zhubai.love +zhubai.pub +zhubaijia.com +zhubajie.com +zhubajie.la +zhubangbang.com +zhubao.com +zhubao668.com +zhubaowo.com +zhubian.com +zhubiaoju.com +zhubo123.com +zhuboqiang.com +zhuceshenzhengongsi.com +zhuceyou.com +zhuchao.cc +zhucheng.com +zhuchengdc.com +zhuchuang.club +zhudai.com +zhudianquan.com +zhufaner.com +zhufangdianping.com +zhufengpeixun.com +zhuge.com +zhuge888.com +zhugec.com +zhugeculture.com +zhugefang.com +zhugejianzhi.com +zhugexuetang.com +zhuhai-holitel.com +zhuhaidutyfree.com +zhuhaigh.com +zhuhaihuwai.com +zhuhaily.com +zhuhaimarathon.com +zhuhd.win +zhuhua.com +zhuhuotech.com +zhuige.com +zhuigong.com +zhuiguang.com +zhuiguangzhe.com +zhuihd.com +zhuihuodong.com +zhuimabk.com +zhuimeng8.com +zhuimengzhu.com +zhuinianqing.com +zhuinw.com +zhuiqu.com +zhuishu.la +zhuishukan.com +zhuishushenqi.com +zhuishuwang.com +zhuishuyun.com +zhuitiankeji.com +zhuiwan.org +zhuiyi.ai +zhuiyi123.com +zhuiyigemeng.fun +zhuji.com +zhuji.net +zhuji5.com +zhuji66.com +zhujia100.com +zhujia360.com +zhujiajiao.com +zhujianapp.com +zhujiangbeer.com +zhujiangfuji.com +zhujiangrc.com +zhujiangroad.com +zhujianptcn.com +zhujib.com +zhujibaike.com +zhujibank.com +zhujicankao.com +zhujiceping.com +zhujipindao.com +zhujipower.com +zhujirc.com +zhujisou.com +zhujitao.com +zhujiw.com +zhujiwanjia.com +zhujiwiki.com +zhujiwu.com +zhujizixun.com +zhukai.com +zhukang.tech +zhukao666.com +zhuke.com +zhul.in +zhulang.com +zhulang.net +zhulanli.com +zhulemei.com +zhuli999.com +zhulianwines.com +zhulincat.com +zhulinedu.com +zhulinweiye.com +zhulixiaolie.com +zhulogic.com +zhulong.com +zhulong360.com +zhulongjiang.com +zhulouren.com +zhulu86.com +zhulubox.com +zhulusoft.com +zhuluyy.com +zhumanggroup.com +zhumanggroup.net +zhumaweb.com +zhumengwl.com +zhumingepc.com +zhumiquan.com +zhumotech.com +zhumu.me +zhumulive.com +zhuna.net +zhunaerminsu.com +zhunbai.com +zhunc.vip +zhundao.net +zhundaoyun.com +zhuneicdn.com +zhuneijs.com +zhuniangjia.com +zhuniu.com +zhunnai.com +zhunshitianqi.com +zhunter.com +zhuntui.com +zhunzha.com +zhuo.com +zhuo.re +zhuobao.com +zhuobufan.com +zhuodai.net +zhuofan.net +zhuofansoft.com +zhuoguang.net +zhuohaomao.com +zhuohuamg.com +zhuohuan-ep.com +zhuojuead.com +zhuokai1.com +zhuolaoshi.com +zhuolaoshi.net +zhuoligk.com +zhuomaiyun.com +zhuomiles.com +zhuomogroup.com +zhuoquapp.com +zhuoqun.info +zhuoqun.xyz +zhuoqundianli.com +zhuoshigroup.com +zhuoshixiong.com +zhuotianchike.com +zhuotingwl.com +zhuoxun68.com +zhuoyachina.com +zhuoyi.com +zhuoyigame.com +zhuoyigame.site +zhuoyitm.site +zhuoyixuan.com +zhuoykeji.com +zhuoyou.com +zhuoyoutech.com +zhuoyue78.com +zhuoyuechenxing.com +zhuoyuegame.com +zhuoyuegame.net +zhuoyuesuoxue.com +zhuoyuezhongxue.com +zhuozhan.com +zhuozhengsoft.com +zhuozhoufangchan.com +zhuozhourencai.com +zhuozhuogame.com +zhupinhr.com +zhuqinit.com +zhuqiy.com +zhuqiyang.com +zhuqu.com +zhuque.me +zhushan.cc +zhushandata.com +zhushiyao.com +zhushou001.com +zhust.com +zhutao.com +zhutaostudio.com +zhutidasai.com +zhutihome.net +zhutile.com +zhutiwo.com +zhutix.com +zhutix.net +zhutix.vip +zhutou.com +zhutxia.com +zhuwang.cc +zhuwang360.com +zhuwona.com +zhux2.com +zhuxian.com +zhuxianfei.com +zhuxiaobang.com +zhuxuezi.com +zhuye.kim +zhuye.xyz +zhuye123.com +zhuyili.org +zhuyitai.com +zhuyst.cc +zhuzao.com +zhuzaobang.com +zhuzaocloud.com +zhuzhai.com +zhuzher.com +zhuzhichao.com +zhuzhou.com +zhuzhoubus.com +zhuzhoumarathon.com +zhuzhouwang.com +zhuzhutown.com +zhuzi.me +zhuzihaoke.com +zhuziplay.com +zhw2101024.com +zhwangart.com +zhwdw.com +zhwenxue.com +zhwiki.net +zhwjw.net +zhwkg.com +zhwxwz.com +zhwyy.com +zhx-mall.com +zhx2008.com +zhxbjsjt.com +zhxcn.com +zhxdfpr.com +zhxg.com +zhxgimg.com +zhxhs.net +zhxht.com +zhxinuser.com +zhxnyw.com +zhxqpt.com +zhxszq.com +zhxwq.com +zhxww.net +zhxwzx.com +zhxy1z.com +zhyccw.com +zhycn.com +zhyczx.com +zhyd.me +zhyfkj.com +zhyg.org +zhyi828.com +zhyingxiao.com +zhylwx.vip +zhylyy.com +zhyouliang.com +zhyourun.com +zhysdxl.com +zhyymall.com +zhyyz.com +zhz.com +zhzdtz.com +zhzf-group.com +zhzf360.net +zhzh.xyz +zhzpjt.com +zhzxin.com +zhzyw.com +zi-maoqu.com +zi0.cc +zi15.com +zi5.cc +zi6.cc +zianwu.com +zibaomuye.com +zibasset.com +zibll.com +ziboborui.com +ziboga.com +zibogongli.com +zibojinling.com +zibomama.com +zibomarathon.com +zibowater.com +zibozhongxue.com +zibsc.com +zichanjie.com +zichen.zone +zicini.com +zicp.fun +zicp.vip +zidan.chat +zidanduanxin.com +zidanduanxin.net +zidg.com +zidian8.com +zidiankeji.com +zidianqu.com +zidianwang.com +zidoo.tv +zidootv.com +zifandiaosu.com +zifumao.com +zigaokj.com +zige365.com +zigeer.com +zigonggroup.com +ziguhonglan.com +zihai0351.com +zihai0535.com +zihai24.com +zihaixiaochengxu.com +zihexin.com +zihexin.net +zihu.com +zihua.li +zihua01.com +zihuazhijia.com +ziir-robot.com +ziisp.com +ziji.work +zijiang.com +zijiangqy.com +zijiantty.com +zijieapi.com +zijieapi.net +zijiecdn.com +zijiecdn.net +zijieimg.com +zijieimg.net +zijiejiaodian.com +zijietiaodong.com +zijieurl.com +zijieurl.net +zijiewap.com +zijiewap.net +zijinfx.com +zijinji.com +zijinshan.net +zijintiyu.com +zijizhang.com +zikao-zikao.com +zikao.gd +zikao211.com +zikao365.com +zikao5.com +zikaobm.com +zikaocqi.com +zikaogd.com +zikaoj.com +zikaoshu.net +zikaoshu.vip +zikaosw.com +zikeys.com +zikoo-int.com +zikoo.com +zikui-design.com +zilang.net +zilhua.com +zilian5.com +ziliao8.cc +ziliao8.com +ziliaoge.com +ziliref.com +zilongame.com +zilongshanren.com +zilrms.com +ziluolanh.com +zimilan.com +zimlev.com +zimoapps.com +zimudashi.com +zimufy.com +zimuism.com +zimujiang.com +zimuzu.com +zimuzu.io +zimuzu.tv +zindall.com +zine.la +zinffer.com +zing-api.com +zingfront.com +zingke.com +zinglix.xyz +zingsemi.com +ziniao.com +ziniusoft.com +zinsight-tech.com +zintow.com +zinyon.com +zionpharma.com +ziooc.com +zip118.com +zipadc.com +zipjpg.com +ziqingi.com +ziquyun.com +zircite.com +ziroom.com +ziroomapartment.com +ziroomstay.com +ziruxing.com +zisea.com +zisen.com +zisha.com +zishapot.com +zishu.life +zishuo.com +zishuovideo.com +zisuo.com +zitbbs.com +zitengyu.com +zitern.com +ziti163.com +ziti3.com +ziti6.com +ziti88.com +ziti9.com +zitichina.com +ziticq.com +zitidi.com +zitiewang.com +zitiguanjia.com +zitijia.com +zitixiazai.org +zitiziyuan.com +zitongit.com +zituo.net +ziubao.com +zivers.com +zivoo.com +ziwanyouxi.com +ziweicn.com +ziweifu.com +ziweihuan.com +ziwoyou.net +ziwufang.com +ziwuyunjiao.com +zixia.com +zixiaomao.com +zixigua.com +zixijiaoshi.com +zixingxinwen.com +zixueguoxue.com +zixuejie.com +zixueren.com +zixuewang.cc +zixunauto.com +zixunhk.com +zixunkankan.xyz +zixuntop.com +ziy.cc +ziya1337.com +ziyainfo.com +ziyan666.com +ziyanfoods.com +ziyanmm.com +ziyaokj.com +ziye66.com +ziyexing.com +ziyi-health.com +ziyimall.com +ziying.site +ziyou.com +ziyou.studio +ziyoufa.com +ziyouma.net +ziyouwu.com +ziyouxing.net +ziyouziti.com +ziyrta.com +ziyuan.tv +ziyuan605.com +ziyuandai.com +ziyuangou.com +ziyuanku.com +ziyuanlm.com +ziyuanm.com +ziyuanniao.com +ziyuanshare.cc +ziyuantun.com +ziyuanxiyanly.com +ziyuanyuan.com +ziyuen.com +ziyun.com +ziyunshanju.com +zizailvyou.com +zizdog.com +zizhengfang.com +zizhigx.com +zizhijie.com +zizhuauto.com +zizhuhui.com +zizhupark.com +zizhuyuangongyuan.com +zizhuyunxuan.com +zizi2000.com +zizige.com +zizizaizai.com +zizizizizi.com +zizyw.com +zizzs.com +zj-art.com +zj-ccmi.com +zj-echo.com +zj-equation.com +zj-fhzx.com +zj-gold.com +zj-guojun.com +zj-hc168.com +zj-huawei.com +zj-huishi.com +zj-idc.com +zj-innolight.com +zj-jc.com +zj-jinchen.com +zj-jingyang.com +zj-lenor.com +zj-nongdu.com +zj-nuolong.com +zj-shibo.com +zj-syfj.com +zj-tattoo.com +zj-tiansong.com +zj-tuna.com +zj-tunnel.com +zj-yinlong.com +zj-zhongshe.com +zj-zhx.com +zj-zxjx.com +zj-zyhb.com +zj.com +zj01.com +zj1058.com +zj123.com +zj186.com +zj1991.com +zj1996.com +zj2460.com +zj2car.com +zj31.net +zj315.org +zj32.com +zj339.com +zj8t5.com +zj9.co +zj9.com +zj93zp.com +zj96596.com +zjabank.com +zjabhw.com +zjabjc.com +zjadgroup.com +zjaf.net +zjafl.com +zjags.com +zjaijiagroup.com +zjaikang.com +zjairports.com +zjalky.com +zjalufoil.com +zjamo.com +zjamp.com +zjanchor.com +zjanyy.com +zjaqxy.com +zjart.com +zjasem.com +zjautoparts.com +zjaxyx.com +zjaxzl.com +zjbadminton.com +zjbanger.com +zjbar.com +zjbdc.com +zjbdfood.com +zjbeacon.com +zjbelong.com +zjbhi.com +zjbicycle.com +zjbinya.com +zjblab.com +zjblast.com +zjbolunfilter.com +zjbuc.com +zjbxcn.com +zjbyte.com +zjbyte.net +zjca.org +zjcaoban.com +zjcarnet.com +zjcb.com +zjcbank.com +zjcbcm.com +zjcbjy.com +zjcbl.com +zjcdn.com +zjceia.com +zjcgmetal.com +zjchanghua.com +zjchina.org +zjchuanning.com +zjchuguo.com +zjchunhui.com +zjcio.org +zjcjjt.com +zjckw.org +zjcloud.com +zjcnbank.com +zjcnyb.com +zjcqk.com +zjcrcgas.com +zjcrjzj.com +zjcshjt.com +zjct56.com +zjctm.net +zjcuhb.com +zjcxbank.com +zjcyts.com +zjcyxh.com +zjcyyy.com +zjda.com +zjdadeyy.com +zjdashi.com +zjdata.net +zjdeju.com +zjdeluo.com +zjdetong.com +zjdfc.com +zjdg.com +zjdhky.com +zjdianying.com +zjdjc.com +zjdjqc.com +zjdjxh.com +zjdkjs.com +zjdl.com +zjdlgroup.com +zjdljc.com +zjdljt.com +zjdmxc.com +zjdnajy.com +zjdpco.com +zjdsgroup.com +zjdsz.com +zjdtkg.com +zjdxghy.com +zjdxjs.com +zjdybank.com +zjdydlc.com +zjdyjob.com +zjdzqt.com +zje.com +zjeagles.com +zjeav.com +zjeclean.com +zjecredit.org +zjedps.com +zjedu.com +zjedu.org +zjej.com +zjemec.com +zjeq.com +zjerg.com +zjetc.net +zjevt.com +zjfangchan.com +zjfcdn.com +zjfdc.net +zjfengli.com +zjfish.org +zjfj.net +zjfm.com +zjfszhsw.com +zjft.com +zjftu.org +zjfujiu.com +zjfurnace.com +zjg-edu.com +zjg-jcu.com +zjg.me +zjgas.com +zjgckg.com +zjgcreative.com +zjgengu.com +zjgeyi.com +zjgf88.com +zjgfjt.com +zjgfls.com +zjgj.com +zjgjj.com +zjgkg.com +zjgmwl.com +zjgqt.org +zjgrc.com +zjgroupedu.com +zjgrrb.com +zjgsgroup.com +zjgslb.com +zjgt.com +zjguji.com +zjgwqxh.com +zjgwsc.com +zjgwy.org +zjgwyw.org +zjgycjj.com +zjgyjt.com +zjgzcpa.com +zjgzks.com +zjgzp.com +zjgztz.com +zjgzzc.com +zjh1893.xyz +zjha.org +zjhac.com +zjhaitian.com +zjhangmo.com +zjhangyin.com +zjharbor.com +zjhbdlkj.com +zjhby.com +zjhcbank.com +zjhcly.com +zjhd.com +zjhdchem.com +zjheacc.com +zjheadway.com +zjhejiang.com +zjheliang.com +zjhengshun.com +zjhengyida.com +zjhf.org +zjhfxcl.com +zjhi.net +zjhkele.com +zjhlcnc.com +zjhlgroup.com +zjhlyyjt.com +zjhnlianzhong.com +zjhnrb.com +zjhospital.net +zjhpyy.com +zjhrnet.com +zjhsfs.com +zjhslyw.com +zjhtcm.com +zjhualing.com +zjhuazhe.com +zjhuba.com +zjhui.net +zjhwgroup.com +zjhx520.com +zjhxgf.com +zjhxw.com +zjhyrcb.com +zjhzgy.com +zjhzjt.com +zjhzjtjt.com +zjhzkq.com +zjhzxc.com +zji.net +zjian.net +zjibao.com +zjiec.com +zjiecode.com +zjiekai.com +zjiii.org +zjiis.com +zjim.org +zjimc.com +zjipc.com +zjitc.net +zjivy.com +zjj-holiday.com +zjjaxx.com +zjjcbdt.com +zjjd.org +zjjedu.com +zjjfl.com +zjjfpharm.com +zjjgy.com +zjjgylydjc.com +zjjgzdh.com +zjjh.com +zjjianhong.com +zjjiaoke.com +zjjinuo.com +zjjinzi.com +zjjizhi.com +zjjjtec.com +zjjky.com +zjjlvyou8264.com +zjjm.net +zjjmtl.com +zjjn.com +zjjnzyjx.com +zjjr.com +zjjrh.com +zjjrtv.com +zjjs.net +zjjsbank.com +zjjsit.com +zjjsjt.com +zjjstzhb.com +zjjsw.com +zjjta.com +zjjtgc.com +zjjttaa.com +zjjtwxpgs.com +zjjubao.com +zjjudong.com +zjjxjt.com +zjjxsoft.com +zjjy.com +zjjy.net +zjjytyt.com +zjjyxx.net +zjjyzx.com +zjjzxgj.com +zjjzyxh.com +zjkangzh.com +zjkbfjd.com +zjkccb.com +zjkdl.com +zjkdqz.com +zjke.com +zjkelan.com +zjkeling.com +zjkfcapital.com +zjkgdcs.com +zjkgjj.com +zjkim.com +zjkings.com +zjkjob.com +zjklfj.com +zjkmtgc.com +zjknews.com +zjknsn.com +zjkpet.com +zjks.com +zjks.net +zjkszg.com +zjkwhjj.com +zjkyjs.com +zjlande.com +zjlca.com +zjlcwg.com +zjldrcb.com +zjledfbd.com +zjlepu.com +zjlfdq.com +zjlianchi.com +zjlianhua.com +zjlianyingkj.com +zjlindu.com +zjlljt.com +zjlottery.com +zjlsbz.com +zjlsedu.org +zjlvjie.com +zjlxjs.com +zjlxtx.com +zjlzgg.com +zjma.org +zjmaerfj.com +zjmaiou.com +zjmana.com +zjmax.com +zjmc.tv +zjmct.com +zjmetal.com +zjmi-mall.com +zjmi.com +zjmichem.com +zjmif.com +zjmileasing.com +zjminb.com +zjminghong.com +zjmingzhen.com +zjmingzhuang.com +zjminong.com +zjmj.org +zjmjtec.com +zjmkzx.com +zjmobile.com +zjmrhpt.com +zjmrmf.com +zjmsbt.com +zjmtw.com +zjmuex.com +zjmycn.com +zjnad.com +zjnature.com +zjnav.cc +zjnav.com +zjndjs.com +zjnengyuan.com +zjnews.com +zjnrcb.com +zjnrg.com +zjnthkg.com +zjnzi.com +zjolcdn.com +zjoldns.com +zjorient.com +zjoubbs.com +zjpark.com +zjpcedu.com +zjpci.com +zjpec.com +zjphrcb.com +zjpia.net +zjpjmy.com +zjplan.com +zjpmw.com +zjpoetry.com +zjpost.com +zjpse.com +zjptcc.com +zjpubservice.com +zjqichuang.com +zjqinghu.com +zjqingshan.com +zjqinzijianding.com +zjqjs.com +zjqsysj.com +zjqzsy.com +zjradiology.org +zjrc.com +zjrc.net +zjrcu.com +zjrdl.com +zjrh.net +zjriji.com +zjrob.com +zjrongli.com +zjrq.com +zjrqchina.com +zjrtv.vip +zjrunqiang.com +zjrxz.com +zjsairport.com +zjsaisi.com +zjsaisiet.com +zjsalt.com +zjsanji.com +zjsanma.com +zjsaz.com +zjsbigdata.com +zjscdb.com +zjsck.com +zjscs.com +zjsdbjt.com +zjseaport.com +zjsee.org +zjsftc.com +zjsgjs.com +zjshangfeng.com +zjshcl.com +zjshibao.com +zjshijian.com +zjshining.com +zjshipyard.com +zjshjkj.com +zjshuangtu.com +zjshuhao.com +zjshuo.com +zjshwl.com +zjsight.com +zjsjcjt.com +zjsjjjt.com +zjsjky.com +zjsjty.com +zjsjtz.com +zjskgr.com +zjskjt.com +zjslep.com +zjslzh.com +zjsms.com +zjspas.com +zjssjt.com +zjsszsjy.com +zjsta.org +zjstar-electric.com +zjstm.org +zjstv.com +zjsuntex.com +zjsw.org +zjswxpx.com +zjsxkj.com +zjsxlt.com +zjsxrz.com +zjsxss.com +zjsyyhyxh.com +zjszbank.com +zjszjz.com +zjszrc.com +zjszsyy.com +zjszyyxh.com +zjszzs.com +zjt2017.com +zjtaa.net +zjtbe.com +zjtcc.com +zjtcjt.com +zjtcn.com +zjtcpm.com +zjtdw.com +zjtdyl.com +zjtea.com +zjteam.com +zjtggroup.com +zjtic.com +zjtjw.com +zjtkdz.com +zjtlcb.com +zjtmb.com +zjtmkg.com +zjtntd.com +zjtobacco.com +zjtongde.com +zjtp.com +zjtree.com +zjts.com +zjtxedu.org +zjtyphoon.com +zjtzcx.com +zjtzedu.com +zjtzwater.com +zju88.org +zjubh.com +zjuers.com +zjugis.com +zjuiwz.com +zjujournals.com +zjukf.com +zjun.info +zjuqsc.com +zjut.cc +zjvending.com +zjwandi.com +zjwanma.com +zjwater.com +zjwater.org +zjwc168.com +zjwcjm.com +zjwcqp.com +zjwebapp.com +zjwentou.com +zjwfgroup.com +zjwhhly.com +zjwhyis.com +zjwiki.com +zjwit.net +zjwjrc.com +zjwk.com +zjwmw.com +zjwqw.com +zjws.net +zjwsbidding.com +zjwttools.com +zjwu.net +zjwxbank.com +zjwzba.com +zjwzbearing.com +zjxc.com +zjxcsw.com +zjxf119.com +zjxhbj.com +zjxhedu.com +zjxhgd.com +zjxhxny.com +zjxindongyang.com +zjxindu.com +zjxinghe.com +zjxinyun.com +zjxjrc.com +zjxlmb.com +zjxltz.com +zjxlyp.com +zjxnd.com +zjxpp.com +zjxqyy.com +zjxs.work +zjxsbank.com +zjxssj.com +zjxtxs.com +zjxwjs.com +zjxwkg.com +zjxwtoy.com +zjxxkx.com +zjxxt.com +zjxymy.com +zjxzgrd.com +zjyanxing.com +zjyari.com +zjycpx.com +zjyfyxzz.com +zjyhjsjt.com +zjyhqy.com +zjyingcai.com +zjyinzuo.com +zjyiot.com +zjyiyuan.com +zjykrc.com +zjylbx.com +zjylgroup.com +zjyonder.com +zjyoutian.com +zjyq.cc +zjysgroup.com +zjytxl.com +zjyxzzs.com +zjyyc.com +zjyygy.com +zjyzpcxx.com +zjza.com +zjzajsjt.com +zjzcec.com +zjzcen.com +zjzcj.com +zjzfj.com +zjzfjs.com +zjzg.com +zjzhd.com +zjzhengding.com +zjzhengxingyiyuan.com +zjzhengyao.com +zjzhenyou.com +zjzhitan.com +zjzhongcheng.com +zjzhonglan.com +zjzhongtian.com +zjzj.net +zjzj.org +zjzjjx.com +zjzoneng.com +zjzramc.com +zjzrzyjy.com +zjzs.net +zjzsa.com +zjzsco.com +zjzsxb.com +zjzwlab.com +zjzy.com +zjzybiotech.com +zjzydns.com +zjzygroup.com +zjzyxs.com +zk0771.com +zk100.com +zk2013.com +zk5u.com +zk678.com +zk71.com +zk789.net +zkailun.com +zkauto.com +zkb77.com +zkbhj.com +zkbs.net +zkck.com +zkcmg.com +zkcrm.com +zkcserv.com +zkcx.com +zkdt.net +zke999.com +zkecopro.com +zkedrive.com +zkgenergy.com +zkh.com +zkh360.com +zkhb.group +zkhcsoft.com +zkhcsy.com +zkhgchip.com +zkhj618.com +zkicme.com +zking.com +zkjan.com +zkjds.com +zkkailiaoji.com +zkkjpa.com +zkl2333.com +zkmeiling.com +zkmob.net +zknmattress.com +zkoffcn.com +zkpeace.com +zkpk.org +zkrdlab.com +zkreen.com +zkroom.com +zkrsks.com +zksbxhyxh.com +zkscgj.com +zksglaser.com +zkshare.com +zksn.com +zksoftwaresz.com +zksps.com +zksyzy.com +zktecn.com +zkteco.com +zkteco.xin +zktecoiot.com +zktecosj.com +zktest.com +zktimecube.com +zktools.net +zktw.com +zku.net +zkunet.com +zkungfu.com +zkuyun.com +zkw2009.com +zkwtech.com +zkxblog.com +zkxww.com +zkyai.com +zkydib.com +zkyl.vip +zkyouxi.com +zkyxc.com +zkyxls.com +zkzbkj.com +zkzj.org +zkzls.com +zkzn666.com +zkzs.net +zl-steelpipe.com +zl1006.com +zl168.xyz +zl56.com +zl99.org +zlbaba.com +zlbagx.com +zlca.org +zlcool.com +zldatas.com +zldq.org +zle.com +zlf.co +zlfc.mobi +zlfedu.com +zlfind.com +zlfshop.com +zlfzyj.com +zlg.com +zlgcgl.com +zlghr.com +zlglpt.com +zlgmcu.com +zlgpy.com +zlgsj.com +zlh-zh.com +zlhome.com +zlhospital.com +zlhui.com +zlibs.com +zlingad.com +zlink-e.com +zlinkurl.com +zlitoa.cc +zlitoa.com +zljskb.com +zljweb.com +zljx.net +zlkb.net +zlketang.com +zlkj20.com +zlm4.com +zlmlt.com +zlnewlife.com +zlongame.com +zlook.com +zlprc.com +zlpumps.com +zlqb.net +zlqbk.com +zlqh.com +zlqiao.com +zlqx.com +zlr6.com +zls365.com +zlscn.net +zlsin.com +zlsoft.com +zlsqlt.com +zlsss.com +zlsyun.com +zlt365.com +zltianhen.com +zlttxl.com +zluren.com +zlview.com +zlvod.com +zlwh2026.com +zlwl.vip +zlwlhse.com +zlx.com +zlxiang.com +zly169.com +zlygjzx.com +zlygu.com +zlysgl.com +zlzlzsl.com +zlzscq.com +zlzt.com +zm-assemble.com +zm-clock.com +zm-ep.com +zm-grow.com +zm-introduce.com +zm-invite.com +zm-mp.com +zm-wx.com +zm0772.com +zm1717.com +zm30.com +zmapp.com +zmaxfilm.com +zmaxhotels.cc +zmbesta.com +zmbg.com +zmbga.com +zmc-china.com +zmcchina.com +zmccx.com +zmclearing.com +zmd5.com +zmdfcw.com +zmdfdc.com +zmdsbus.com +zmdsjob.com +zmdwater.com +zmdyzkgjt.com +zmdz.com +zmeetb.com +zmeng.cc +zmeng123.com +zmengzhu.com +zmgov.com +zmgrcw.com +zmhttp.com +zmifi.com +zmingcx.com +zmirrordemo.com +zmis.me +zmister.com +zmjiudian.com +zmjm.com +zmkmex.com +zmlearn.com +zmmek.com +zmmio.com +zmndjm.com +zmnedu.com +zmnh.com +zmnjtwx.com +zmnoa.com +zmnrz.com +zmnxbc.com +zmobuy.com +zmpal.com +zmqh.com +zmqmt.com +zmren.com +zmrenwu.com +zmshz.com +zmsq.com +zmssh.com +zmtpc.com +zmtquan.com +zmubf.com +zmufivehospital.com +zmumu.com +zmweb.net +zmwo.com +zmwxxcx.com +zmxitang.com +zmye5vly.com +zmyui.com +zmyyc.com +zmz001.com +zmz002.com +zmz003.com +zmz004.com +zmz2019.com +zmzapi.com +zmzapi.net +zmzb.com +zmzjt.com +zmzx.cc +zn99.com +znba.net +znbo.com +znc365.com +zncar.com +zncmjt.com +znczz.com +zndata.com +zndlkj.com +zndls.com +zndns.com +znds.com +znds.net +zndsbbs.com +zndsrom.com +zndstec.com +znelc.com +znfit.com +zngm.com +zngue.com +zngxjt.com +znhhmedical.com +znhospital.com +znhr.com +znhwhw.com +znjchina.com +znjj.tv +znjs.com +znjsjt.com +znjtgf.com +znjttz.com +znlc2015.com +znlcn.org +znlerp.com +znlh.com +znmq.com +znnu.com +znonline.net +znp9.com +znpin.com +znpla.space +znrfwy.com +znrom.com +znrsc.com +znshuke.com +znshuru.com +znsjw.com +znsmart.com +znstartups.com +zntb.net +zntcexpo.com +zntschool.com +zntvrom.com +zntx.cc +znum.com +znwb.com +znxdxs.com +znxhd.com +znxk.net +znyp.com +znypjy.com +znzcompass.com +znzcompass.net +znzmo.com +znzncn.com +znznet.net +znztool.com +znztv.com +znzyf.com +zo-station.com +zo5yap5sdc.com +zoassetmanagement.com +zobmxcfw.com +zocai.com +zocolor.com +zocoxx.com +zodgame.me +zoe360.com +zoebon.com +zoeeasy.com +zoeess.com +zoform.com +zofund.com +zoharforce.com +zohead.com +zohi.tv +zoioo.com +zoje.com +zojirushi-china.com +zokmetal.com +zokogo.com +zol-img.com +zol.com +zollty.com +zoloz.net +zomanbio.com +zombiescat.com +zomiu.com +zomsky.com +zon100.com +zonafs.com +zonboapp.com +zonci.com +zone-king.com +zone.id +zone139.com +zoneben.com +zoneidc.com +zoneker.com +zonelo.tech +zonen-tech.com +zoneray56.com +zoneve.com +zoneyung.com +zonezu.com +zongcaidetishenqianqi.net +zongdegongju.com +zonghangsl.com +zonghe.com +zonghe888.com +zongheng.com +zongheng001.com +zonghengke.com +zonghengxiaoshuo.com +zonglai.com +zonglikeji.com +zongming.net +zongmutech.com +zongs365.com +zongshengjituan.com +zongtiku.com +zongxiankj.com +zongyiconverge.com +zongyifile.com +zongyigame.com +zongyimobile.com +zongyionline.com +zongyiphone.com +zongyixun.com +zonhen.com +zonsengroup.com +zonsenmotor.com +zontes.com +zonxiebamboo.com +zoocer.com +zoocoffee.com +zooelab.com +zoofon.com +zookingsoft.com +zookparts.com +zoolnasm.com +zoom3g.com +zoomerstudio.com +zoomeye.org +zoomfr.com +zoomla.net +zoomlion.com +zoomwo.com +zoopda.com +zoossoft.com +zooszyservice.com +zoot.plus +zootope.ink +zooyoo.cc +zoqlan.com +zoranchem.com +zoroli.com +zorrospray.com +zorun.com +zoscape.com +zosurrdc.com +zotiser.com +zotrppzv.com +zotrus.com +zotumgxr.com +zotye.com +zou.la +zouaw.com +zoubiao.com +zoucheng.cc +zoucz.com +zoues.com +zouhong365.com +zouht.com +zouin.net +zoujiang.com +zoukankan.com +zoular.com +zoutu.com +zouzhi.world +zouzhiqiang.com +zovps.com +zowoyoo.com +zoxun.com +zoyoo.net +zoyse.com +zoyst.com +zoyuecs.com +zozen.com +zp.cc +zp.do +zp005.com +zp0716.com +zp114.net +zp365.com +zp515.com +zpan.space +zparking-tech.com +zpascal.net +zpb365.com +zpbtnpl.com +zpc-cn.com +zpcdi.com +zpchaji.com +zpcmshopping.com +zpedu.com +zpedu.org +zpfdc.com +zpgd.net +zphit.com +zphlkj.com +zphospital.com +zpjkcy.com +zplay.com +zplayworld.com +zpm.so +zpmc.com +zpmg.com +zpparts.com +zpstar.com +zpt966033.com +zptq.com +zpug.net +zpwamdew.com +zpwcb.com +zpwz.net +zpxrmyy.com +zq12369.com +zq235.com +zq6.com +zqagr.com +zqaqxh.com +zqase.com +zqbykj.com +zqcaf.com +zqcloud.com +zqcloudgame.com +zqcyzg.com +zqd086.com +zqdns37.vip +zqedu.net +zqfdc.net +zqgame.com +zqgjz1312.com +zqgreen.com +zqhthr.com +zqhuahui.com +zqhuwkc.com +zqic.net +zqids.com +zqin758.xyz +zqjcedu.com +zqjiese.com +zqjinneng.com +zqlian.com +zqlx.com +zqnf.com +zqpj.com +zqread.com +zqsign.com +zqsjf.com +zqsos.com +zqsx.net +zqtbg.com +zqtbu.com +zqtong.com +zquan.cc +zquan.org +zqvip8.cc +zqwfe.work +zqwh.com +zqwxzf.com +zqxsc.com +zqy.com +zqygame.com +zqyxf.com +zqz510.com +zqzd.com +zqzyxx.com +zr-fanuc.com +zr66.com +zrahh.com +zran88.com +zrblog.com +zrblog.net +zrbx.com +zrcaifu.com +zrcbank.com +zrfan.com +zrfe.com +zrfilm.com +zrhsh.com +zring.com +zritc.com +zrj96.com +zrkjy.com +zrlyyy.com +zrmm.com +zrpta.com +zrpwxgp.com +zrtechnology.com +zrtg-group.com +zrtg.com +zrthink.com +zrtjt.com +zrway.com +zrwjk.com +zrxdsj.com +zry97.com +zrzhpt.com +zs-ah.com +zs-e.com +zs-frd.com +zs-hospital.com +zs-jlc.com +zs-lzlj.com +zs-nj.com +zs-rh.com +zs-united.com +zs6y.com +zs8q.com +zs9.com +zs91.com +zsaber.com +zsacg.com +zsaeroengine.com +zsafedns.net +zsaipay.com +zsamc.com +zsanxing.com +zsaxi.com +zsb2c.com +zsbeike.com +zsboai.com +zsbqgz.com +zsbsoft.com +zsbus.wiki +zsbyw.com +zsc-group.com +zscbd.com +zscch.com +zsceta.com +zschem.com +zsciupd.com +zscjjt.com +zscollege.com +zsctgroup.com +zscz0768.com +zsd.name +zsdianlan.com +zsdlw.com +zsdown.com +zsedu.net +zsemall.com +zsemi.com +zsengine.com +zseoo.com +zsex.ltd +zsezt.com +zsfund.com +zsfzjs.com +zsg6.com +zsgai.com +zsgcgj.com +zsgd.com +zsgjs.com +zsglrj.com +zsgoodlighting.com +zsgsly.com +zsgzc.com +zsh.com +zsh8.com +zshandsome.com +zshc12306.com +zshcx.com +zshgsoft.com +zshhjt.com +zshield.net +zshl.com +zshnb.com +zshpldbz.com +zshsoft.com +zshszy.com +zshtys888.com +zshuoshao.store +zshuoshao.tech +zshypr.com +zsia.org +zsihuo.com +zsimc.com +zsincer.com +zsite.com +zsj18.com +zsjdxh.org +zsjhsjy.com +zsjhx.com +zsjjob.com +zsjuchuang.com +zsjz.com +zskoubei.com +zsksdw.com +zsksw.net +zslady.com +zslefx.art +zslhs.com +zslin.com +zslp021.com +zsmama.com +zsmeishiling.com +zsmls.com +zsmw.net +zsmyy.com +zsmz.com +zspharm.com +zsppsj.com +zsquant.com +zsqx.com +zsr.cc +zsscw.net +zssjzyxh.com +zssl.net +zssmk.net +zssph.com +zssubeihospital.com +zsswjt.com +zssxyy.com +zsszsh.com +zsszyy.com +zstack.io +zstack.org +zstatic.net +zstaticcdn.com +zsthk.com +zstime.com +zstled.com +zsuan.com +zsucai.com +zsufivehos.com +zsvsz.com +zswater.com +zswcn.com +zswebao.shop +zswj.com +zswmailbox.com +zswpqfep.com +zswtjt.com +zswyprkq.com +zsxfsy.com +zsxgzn.com +zsxinsha.com +zsxq.com +zsxq100.com +zsxsoft.com +zsyanxuan.com +zsyknk.com +zsynjt.com +zsysgz.com +zsythink.net +zsytit.com +zsyyart.com +zszk.net +zszq.com +zszxsz.com +zszyss.com +zt-express.com +zt-g.com +zt-info.com +zt-job.com +zt-motor.com +zt0729.xyz +zt1356.com +zt1388.com +zt17.com +zt1f.com +zt24j.com +ztautoparts.com +ztbeijixing.com +ztbest.com +ztcdata.com +ztcexam.com +ztch.ltd +ztcia.com +ztcjjt.com +ztcnwy.com +ztcpa.com +ztdgroup.com +ztdli.com +ztdsp.com +zte.net +ztedevice.com +ztedevices.com +ztedu.com +ztedu8.com +ztehotel.com +ztehotel.net +ztemall.com +ztemap.com +ztems.com +ztestin.com +ztfans.com +ztfsec.com +ztfssc.com +ztgame.com +ztgcglzx.com +ztgy.org +zthrv.com +zthsqx.com +zthx.com +zthx2004.com +ztinfoga.com +ztjczx.com +ztjhuyu.com +ztjinchi.com +ztjoin.com +ztjttz.com +ztjy61.com +ztjystore.com +ztjzgf.net +ztjzht.com +ztkm.com +ztkosen.com +ztky.com +ztkycn.com +ztlycm.com +ztmao.com +ztmvip.com +ztn.com +ztnews.net +ztno.com +ztnwork.com +ztny188.com +zto.com +zto.net +zto56.com +ztoapp.com +ztoglobal.com +ztogroup.com +ztomember.com +ztoyh.com +ztqft.com +ztqqt.com +ztrczp.com +ztrhmall.com +ztrong.com +ztsafe.com +ztshjcb.com +ztsiot.com +ztskc.com +ztt.cc +zttx-exp.com +zttx.com +ztupic.com +ztups.com +ztvcar.com +ztweld.com +ztwlbeijing.com +ztwlgyl.com +ztwzcg.com +ztwzsc.com +ztxinli.com +ztxxr.com +ztxyg.com +ztxygj.com +ztxywy.net +ztxz.cc +ztxzsjt.com +ztyang.com +ztytech.com +ztyyw.com +ztzcnc.com +ztzhbw.com +ztzhgw.com +ztzhsq.com +ztzjt.com +ztzqzg.com +ztzsnn.com +ztzupu.com +ztzy.com +ztzzls.com +zu.biz +zu1tai.com +zu3.com +zuadr.com +zuan-cheng.com +zuan88.com +zuanke8.com +zuanqianyi.com +zuanshi.com +zuanshitoupiao.com +zubei.co +zuber.im +zubunet.com +zucaijia.com +zucangbao.com +zuchang1688.com +zuche.com +zuche900.com +zuchecdn.com +zuchuan.cc +zuciz.com +zucp.net +zudequ.com +zudong.com +zuduijun.com +zueiai.net +zuezu.com +zufang.com +zufangzi.com +zugame.com +zugeliang01.com +zugeqifu.com +zuhao.space +zuhaoapp.com +zuhaofa.com +zuhaohao.com +zuhaowan.com +zuhaowan.net +zuhedaikuan.com +zuhuaizhijia.com +zuhuanhao.com +zui.com +zui5.com +zui88.com +zuiaixs.net +zuiben.com +zuibook.com +zuicool.com +zuidaima.com +zuidijia.com +zuidongxi.com +zuifengyun.com +zuifuli.com +zuigx.com +zuihaodaxue.com +zuihuimai.com +zuihuixue.com +zuijh.net +zuijiao.net +zuik.ren +zuiku.com +zuikzy.com +zuikzy.win7i.com +zuimeia.com +zuimeiqidai.com +zuimeitianqi.com +zuiqiangyingyu.net +zuiqingfeng.com +zuishidai.com +zuitang.com +zuitu.com +zuiwan.net +zuixiaoyao.com +zuixu.com +zuiyanke.com +zuiyou.com +zuiyouxi.com +zuizhifu.com +zuji360.com +zujiant.com +zujuan.com +zujuanku.com +zujuanyi.com +zuk.com +zuka666.com +zukang88.com +zuke.com +zuker.im +zulijian.com +zulin.com +zulinbao.com +zulinks.com +zulllv.com +zulong.com +zulongacmall.com +zulongtea.com +zumbacn.com +zumulv.com +zun.com +zun.gd +zun9.com +zunnou.com +zunsf.com +zunsou.com +zunxiang17.com +zunxun.com +zunxun.net +zunyibus.com +zunyihospital.com +zuo11.com +zuo3.com +zuoanedu.com +zuoanfloor.com +zuobaike.net +zuobiao.press +zuobin.net +zuocaibusiness.com +zuocaicn.com +zuocheng.net +zuodanye.com +zuodao.com +zuodashi.com +zuodia.com +zuofawang.com +zuogj.com +zuoh5.com +zuohaotu.com +zuohome.com +zuohuodong.com +zuoji-scm.com +zuojiachubanshe.com +zuojiang.com +zuojiawang.com +zuojing.com +zuojj.com +zuoli.com +zuolin.com +zuoqu.com +zuoqudashi.net +zuosa.com +zuoshangbao.com +zuoshouyisheng.com +zuoshujiang.com +zuotishi.com +zuoweibc.com +zuowen.com +zuowen.net +zuowen8.com +zuowenjing.com +zuowenjun.com +zuowenku.net +zuowenren.com +zuowenwang.net +zuowenzhitiao.com +zuoyebang.cc +zuoyebang.com +zuoyebao.com +zuoyebao.net +zuoyehezi.com +zuoyesou.com +zuoyou-sofa.com +zuozu.net +zuozuowang.net +zupig.com +zupuk.com +zupulu.com +zuqiuba.com +zuqiuba.net +zusan.com +zushouji.com +zushoushou.com +zuszw.com +zutingwan.com +zuulee.com +zuwuzhuyi.com +zuxiaoqi.com +zuxiaoyi.com +zuyaxi.com +zuyizhan.com +zuyouzu.com +zuyunfei.com +zuyushop.com +zuzheyong.com +zuzhirenshi.com +zuzitech.com +zuzuche.com +zuzuqueen.com +zviewcloud.com +zving.com +zvryuq7xg31x5g.com +zvstapp.com +zvsts.com +zvv.me +zw-tencentclb.cloud +zw-tencentclb.com +zw-tencentclb.net +zw-tencentclb.work +zw110.com +zw3dp.com +zw69.com +zw885.com +zwads.com +zwayoptik.com +zwaztizp.com +zwbdata.com +zwcad.com +zwcctv.com +zwcnw.com +zwcsm.com +zwcuo.com +zwda.com +zwdn.com +zwdns.com +zwds.cc +zwdsty.com +zwduxs.com +zwechat.com +zwefu.com +zwelec.com +zwfw.com +zwgeek.com +zwgfood.com +zwggb.com +zwgjpx.com +zwgt.net +zwgx.com +zwhuilian.com +zwhz.com +zwie2003.com +zwjczx.com +zwjhl.com +zwjiaoyu.com +zwjk.com +zwjkey.com +zwjl.net +zwk999.com +zwkf.net +zwlhome.com +zwmrxd.com +zwoasi.com +zwoptical.com +zwoptics.com +zwslshy.com +zwsmds.com +zwtianshangm.com +zwtkl8.com +zwtxipr.com +zwuoo.com +zwwank.com +zwwdm.com +zwwlgzs.com +zwwltkl.com +zwwx.com +zwxww.net +zwxx2022.com +zwying.com +zwyll.com +zwyq110.com +zwzdiy.cc +zwzrent.com +zwzsh.net +zwzyzx.com +zx-tour.com +zx-xcx.com +zx0093.com +zx017.com +zx017.net +zx0818.com +zx100.com +zx10000.com +zx110.org +zx1234.com +zx16f.com +zx181.com +zx18x.com +zx3002.com +zx350zx.com +zx42195.com +zx7b.com +zx8.com +zx98.com +zx990.com +zxb12315.com +zxblinux.com +zxbook.net +zxbzr.com +zxchemgroup.com +zxcmk.com +zxcoder.com +zxczw.com +zxd.com +zxd666.com +zxdkj.com +zxdoo.com +zxdu.net +zxdyw.com +zxerp.com +zxfsv.online +zxfw888.com +zxfwgj.com +zxgcloud.com +zxgj56.com +zxgongshui.com +zxgroup.com +zxgstock.com +zxgzs.com +zxgzw.com +zxhgroup.com +zxhmjj.com +zxhnzq.com +zxhong.com +zxhospital.com +zxhsd.com +zxhuman.com +zxhwzm.com +zxiaosi.com +zxiaoxiang.com +zxicrm.com +zxinc.org +zxingyun.com +zxinzxw.com +zxip.com +zxiti02.com +zxiu.com +zxiw.com +zxiyun.com +zxja.com +zxjkj.com +zxjsq.net +zxjy.net +zxk120.com +zxknow.com +zxkq022.com +zxky007.com +zxl.com +zxlib.com +zxliu.com +zxlo.com +zxls.com +zxmall.com +zxmn2018.com +zxmoto.com +zxmseed.com +zxneweye.com +zxnic.net +zxnrh.com +zxoid.com +zxopen.com +zxpcloud.com +zxpec.com +zxpmq.com +zxqfjt.com +zxqg.com +zxrcfw.com +zxsauto.com +zxsctf.com +zxshe.com +zxsmd.com +zxsou.com +zxstyl.com +zxswjx.com +zxsx.org +zxsxs.com +zxsygs.com +zxt2007.com +zxtang.com +zxtnetwork.com +zxttax.com +zxtw168.com +zxw1.com +zxwcbj.com +zxwindow.com +zxwyouxi.com +zxx.world +zxxk.com +zxxmr.com +zxxww.com +zxxwypsj.com +zxxxkj.com +zxxyedu.com +zxydss.com +zxyee.com +zxz.ee +zxzhijia.com +zxzls.com +zxzmail.com +zxzt123.com +zxzx8.com +zxzyl.com +zxzyy.com +zy-cam.com +zy-geo.com +zy-textiles.com +zy.com +zy100.com +zy120.com +zy169.net +zy223.com +zy234.com +zy728.com +zy91.com +zy99.net +zyactech.com +zyalc.com +zyan.cc +zyan456.com +zyanzn.com +zyark.com +zyautoe.com +zybang.com +zybaoan.com +zybest.com +zybtp.com +zybuluo.com +zybwhsb.com +zybwj.cc +zybz518.com +zyc123.com +zyccst.com +zycits.com +zycitscn.com +zycjcrz.org +zycmmt.com +zyctd.com +zycultura.com +zyczg.com +zydanxia.com +zydlks.com +zydsy.com +zydtrip.net +zydza.com +zydzkjcloud.com +zye.cc +zyea.com +zyecp.com +zyedu.org +zyfb.com +zyfbjzsc.com +zyfchina.com +zyfj.com +zyfsz.net +zygames.com +zygj.net +zygjtzjt.com +zygs.com +zygvqivs.com +zygx8.com +zygxxs.com +zyh365.com +zyhao.com +zyhbjt.com +zyhbxs.com +zyhh.cc +zyhobby.com +zyholding.com +zyhot.com +zyict.net +zying.net +zyip.com +zyiwater.com +zyixi.xyz +zyixinx.com +zyjhzyy.com +zyjiajiao.com +zyjjt.com +zyjkwh.com +zyjoygame.com +zyjtgas.com +zyjthb.com +zyjymall.com +zyjyxx.com +zyjyyun.com +zyka.cc +zykj0668.com +zykjct.com +zykjgame.com +zykjnet.com +zykpic.com +zyks-lv.com +zykths.com +zyku.net +zyl.me +zylianto.com +zylseo.com +zymc1.com +zymkcdn.com +zymkshop.com +zymreal.com +zyms8.me +zyoffice.com +zyoo.net +zyoogame.com +zyops.com +zyou100.com +zyouexpress.com +zyoulun.com +zyoung.me +zypharm.com +zyplayer.com +zyq.today +zyq366.com +zyqcs.com +zyqjg.com +zyqjs.com +zyqxt.com +zyqzyyy.com +zyrack-china.com +zyrb.com +zyrc168.com +zyrj.org +zyrm.com +zyrykbiandao.com +zys6d.com +zysd.work +zyskys.com +zysljhslt.com +zysou.com +zystarlink.com +zyswsb.com +zysxqgs.com +zysyjqrmyy.com +zyszyx.com +zyt8.com +zytang.net +zytm913.com +zyucan.com +zyue.com +zyun.vip +zyvqb.com +zywjw.com +zywsw.com +zywtc.com +zywvvd.com +zywxgames.com +zywxpress.com +zyxhmm.com +zyxintuo.com +zyxmmovie.com +zyxr.com +zyxxlyg.com +zyxyfy.com +zyxzyyy.com +zyydb.com +zyydjk.net +zyyfy.com +zyyimin.com +zyykj168.com +zyylee.com +zyz119.com +zyzhan.com +zyzl120.com +zyzw.com +zz-hh.com +zz-invest.com +zz.ci +zz123456789.xyz +zz2024.com +zz2z.com +zz314.com +zz34.com +zz597.com +zz618.com +zz6789.com +zz8j.com +zz91.com +zz96269.com +zz9ivb.com +zzairport.com +zzay.net +zzbaike.com +zzbbs.com +zzbd.org +zzboiler.com +zzboyou.com +zzbs.org +zzbtool.com +zzbtv.com +zzc9.com +zzccom.com +zzccp.com +zzcdnx.com +zzcjby.com +zzcjxy.com +zzcm1.com +zzcm2.com +zzcm5.com +zzcomm.com +zzcrcgas.com +zzd.pub +zzdengji.com +zzdh.net +zzdjw.com +zzdkdz.com +zzdl.com +zzdnews.com +zzdsj.com +zzdtec.com +zzect.com +zzepa.org +zzfcw.com +zzfeilu.com +zzfh.com +zzfly.net +zzfreshair.com +zzfriend.com +zzgcjyzx.com +zzgdapp.com +zzgeli.net +zzgjj.com +zzgkyy.com +zzgtjtgs.com +zzguest.com +zzguifan.com +zzhaofang.com +zzhaoz.com +zzhbgs.com +zzhfkm.com +zzhuanruan.com +zzhx56.com +zzhybz.com +zzicpa.com +zzidc.com +zzjdgcxx.com +zzjianyun.com +zzjidi.com +zzjldsx.com +zzjob88.com +zzjsled.com +zzjunzhi.com +zzjxbg.com +zzjyi.com +zzk001.com +zzkcjq.com +zzkehui.com +zzkjgy.com +zzkk.cc +zzksjx.com +zzlcjj.xyz +zzlgxy.net +zzliot.com +zzlirui.com +zzlive.zzc-media.com +zzllq.com +zzlongyou.com +zzlt.net +zzltsw.com +zzluohang.com +zzlvjuren.com +zzlvwang.com +zzmama.net +zzmetro.com +zzmingtai.com +zzmlb.com +zzms.com +zzmxbc.com +zzmy.net +zzmyt.com +zznah001.com +zznst.com +zznyy.com +zzprotect.com +zzptech.com +zzpzh.com +zzq12345.gearhostpreview.com +zzqckj.com +zzqfte.com +zzqiyou.com +zzqklm.com +zzqrr.com +zzqss.com +zzquan9.com +zzqudu.com +zzqxs.com +zzqz2024.com +zzqzz.com +zzrc.net +zzrcw.net +zzrmyy.com +zzrseng.com +zzs5.com +zzs5.info +zzsdyrmyy.com +zzsey.com +zzsf.com +zzsggzy.com +zzsgjj.com +zzshe.com +zzsi.com +zzsiji.com +zzsin.com +zzsjzyxh.com +zzslyy.com +zzsmt.com +zzsnewell.com +zzspider.com +zzsspnode.com +zzssptop.com +zzsteel.com +zzstep.com +zzszbsw.com +zzszxyy.com +zzt9.com +zztaoning.com +zzteacher.com +zztender.com +zztfly.com +zzthjixie.com +zztline.com +zztlj.com +zztuku.com +zztv.tv +zztvzd.com +zztxkj.com +zztyscl.com +zzun777.com +zzusah.com +zzw-hb.com +zzwah.com +zzwanshou.com +zzwenxue.com +zzwgd.com +zzwl.info +zzwljc.com +zzwonder.com +zzwqqx.com +zzwro.com +zzwtjx.com +zzwwiidd.com +zzwzj.com +zzxbn.com +zzxca.com +zzxcy.com +zzxdc.com +zzxfjxzz.com +zzxhns.com +zzxic.com +zzxmys.com +zzxw.net +zzxworld.com +zzxx.org +zzxy.net +zzy2001.com +zzyauto.com +zzycpa.com +zzyecc.com +zzyedu.org +zzyfjc.com +zzygxh.com +zzyiquan.com +zzyjs.com +zzykcd.com +zzyuam.com +zzyugang.com +zzyxxw.com +zzyyds.com +zzyyrl.com +zzz4.com +zzzdc.com +zzzdm.com +zzzfgjj.com +zzzglby.com +zzzhtc.com +zzzj.com +zzzla.com +zzzlsh.com +zzznkq.com +zzzppp.com +zzzqqp.com +zzzsxx.com +zzzxwh.net +zzzyb.com +zzzymjg.com +zzzyy.com +zzzyyy.com +zzzzaaaa.com +zzzzzz.me diff --git a/luci-app-passwall/root/usr/share/passwall/rules/chnroute b/luci-app-passwall/root/usr/share/passwall/rules/chnroute new file mode 100644 index 00000000..bde4093c --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/chnroute @@ -0,0 +1,4213 @@ +1.1.8.0/24 +1.116.0.0/15 +1.119.0.0/17 +1.119.128.0/18 +1.119.192.0/20 +1.119.208.0/22 +1.12.0.0/14 +1.180.0.0/14 +1.184.0.0/15 +1.188.0.0/14 +1.192.0.0/13 +1.2.4.0/24 +1.202.0.0/15 +1.204.0.0/14 +1.24.0.0/13 +1.45.0.0/16 +1.48.0.0/14 +1.56.0.0/13 +1.68.0.0/14 +1.8.1.0/24 +1.8.8.0/24 +1.80.0.0/13 +1.88.0.0/14 +1.92.0.0/16 +1.94.0.0/15 +101.1.0.0/22 +101.104.144.0/20 +101.104.160.0/20 +101.106.0.0/19 +101.124.0.0/16 +101.125.0.0/22 +101.125.130.0/24 +101.125.250.0/23 +101.125.252.0/22 +101.125.4.0/23 +101.125.6.0/24 +101.126.0.0/18 +101.126.128.0/19 +101.126.172.0/22 +101.126.176.0/20 +101.126.192.0/19 +101.126.228.0/22 +101.126.232.0/21 +101.126.240.0/20 +101.126.64.0/19 +101.126.96.0/20 +101.128.0.0/22 +101.129.0.0/16 +101.132.0.0/15 +101.144.0.0/12 +101.16.0.0/12 +101.197.0.0/16 +101.198.0.0/22 +101.198.160.0/19 +101.198.192.0/19 +101.198.4.0/24 +101.199.112.0/24 +101.199.128.0/23 +101.199.196.0/22 +101.199.252.0/22 +101.199.48.0/20 +101.2.172.0/22 +101.200.0.0/15 +101.203.172.0/22 +101.204.0.0/14 +101.224.0.0/13 +101.234.76.0/22 +101.236.0.0/16 +101.237.0.0/19 +101.237.128.0/20 +101.237.33.0/24 +101.237.34.0/23 +101.237.36.0/22 +101.237.40.0/24 +101.240.0.0/14 +101.245.0.0/17 +101.245.128.0/20 +101.245.144.0/22 +101.245.152.0/21 +101.245.160.0/20 +101.246.172.0/22 +101.246.176.0/20 +101.248.0.0/15 +101.251.0.0/22 +101.251.128.0/19 +101.251.160.0/20 +101.251.176.0/22 +101.251.192.0/18 +101.251.80.0/20 +101.252.0.0/15 +101.254.0.0/20 +101.254.128.0/17 +101.254.32.0/19 +101.254.64.0/18 +101.33.128.0/17 +101.34.0.0/15 +101.36.128.0/17 +101.36.64.0/20 +101.37.0.0/16 +101.39.0.0/16 +101.4.0.0/14 +101.40.0.0/16 +101.42.0.0/15 +101.49.148.0/23 +101.49.206.0/23 +101.49.208.0/24 +101.49.212.0/24 +101.50.56.0/22 +101.50.8.0/21 +101.52.112.0/21 +101.52.124.0/22 +101.52.128.0/20 +101.52.200.0/21 +101.52.212.0/22 +101.52.216.0/21 +101.52.232.0/23 +101.52.236.0/22 +101.52.240.0/20 +101.52.4.0/24 +101.52.6.0/24 +101.52.68.0/22 +101.53.100.0/22 +101.64.0.0/13 +101.72.0.0/14 +101.76.0.0/15 +101.78.0.0/22 +101.80.0.0/12 +101.96.10.0/23 +101.96.128.0/23 +101.96.130.0/24 +101.96.132.0/23 +101.96.134.0/24 +101.96.142.0/23 +101.96.144.0/20 +101.96.192.0/18 +103.1.168.0/22 +103.1.20.0/22 +103.1.8.0/22 +103.10.0.0/22 +103.10.84.0/22 +103.100.64.0/22 +103.101.124.0/23 +103.101.180.0/22 +103.102.196.0/22 +103.102.200.0/22 +103.102.213.0/24 +103.102.214.0/24 +103.103.12.0/24 +103.103.36.0/24 +103.104.155.0/24 +103.104.252.0/22 +103.105.0.0/22 +103.105.12.0/22 +103.105.180.0/22 +103.105.184.0/22 +103.105.200.0/23 +103.105.202.0/24 +103.105.220.0/22 +103.105.60.0/22 +103.106.252.0/22 +103.106.36.0/22 +103.107.0.0/22 +103.107.188.0/22 +103.107.216.0/21 +103.108.244.0/24 +103.108.247.0/24 +103.109.20.0/22 +103.110.132.0/22 +103.110.136.0/22 +103.111.172.0/22 +103.111.64.0/24 +103.113.4.0/22 +103.114.100.0/22 +103.114.212.0/23 +103.114.236.0/22 +103.115.120.0/22 +103.115.248.0/22 +103.115.92.0/22 +103.116.120.0/23 +103.116.123.0/24 +103.116.138.0/23 +103.116.76.0/23 +103.116.78.0/24 +103.116.92.0/22 +103.117.16.0/22 +103.117.220.0/22 +103.118.52.0/22 +103.118.60.0/22 +103.12.184.0/22 +103.12.232.0/22 +103.12.98.0/23 +103.120.196.0/22 +103.120.224.0/22 +103.120.72.0/22 +103.120.88.0/22 +103.121.164.0/23 +103.121.166.0/24 +103.121.250.0/24 +103.121.52.0/22 +103.122.48.0/22 +103.123.4.0/23 +103.125.236.0/22 +103.126.1.0/24 +103.126.124.0/22 +103.13.12.0/24 +103.13.244.0/22 +103.130.160.0/23 +103.131.138.0/23 +103.131.152.0/22 +103.131.168.0/22 +103.132.212.0/23 +103.132.22.0/23 +103.133.128.0/23 +103.135.160.0/22 +103.135.164.0/23 +103.135.192.0/23 +103.135.195.0/24 +103.135.196.0/22 +103.135.236.0/24 +103.137.60.0/24 +103.139.172.0/23 +103.139.212.0/23 +103.14.132.0/22 +103.14.136.0/22 +103.140.14.0/23 +103.141.10.0/23 +103.142.234.0/23 +103.142.82.0/23 +103.142.96.0/23 +103.143.16.0/22 +103.143.228.0/23 +103.144.158.0/23 +103.144.66.0/23 +103.144.70.0/24 +103.145.42.0/23 +103.146.126.0/23 +103.147.124.0/24 +103.149.242.0/24 +103.149.244.0/22 +103.15.4.0/22 +103.15.96.0/22 +103.150.10.0/23 +103.150.164.0/23 +103.150.24.0/23 +103.151.148.0/23 +103.152.186.0/23 +103.152.209.0/24 +103.152.224.0/24 +103.152.28.0/23 +103.152.56.0/23 +103.152.76.0/23 +103.154.162.0/23 +103.154.30.0/23 +103.154.41.0/24 +103.155.76.0/23 +103.156.174.0/23 +103.156.186.0/23 +103.156.68.0/23 +103.158.0.0/23 +103.158.74.0/23 +103.159.124.0/23 +103.16.124.0/22 +103.161.220.0/23 +103.161.254.0/23 +103.162.10.0/23 +103.163.180.0/24 +103.163.46.0/23 +103.164.32.0/23 +103.165.110.0/23 +103.169.50.0/23 +103.169.62.0/23 +103.17.228.0/22 +103.17.40.0/22 +103.170.212.0/23 +103.170.4.0/23 +103.174.94.0/23 +103.175.197.0/24 +103.177.28.0/23 +103.179.78.0/23 +103.181.234.0/24 +103.183.122.0/23 +103.183.124.0/23 +103.183.66.0/23 +103.184.46.0/23 +103.186.108.0/23 +103.186.4.0/23 +103.189.154.0/23 +103.189.92.0/23 +103.19.232.0/22 +103.19.46.0/23 +103.19.64.0/22 +103.190.118.0/23 +103.190.122.0/23 +103.191.102.0/24 +103.191.242.0/23 +103.192.0.0/22 +103.192.132.0/22 +103.192.16.0/20 +103.192.188.0/22 +103.192.208.0/21 +103.192.252.0/22 +103.192.8.0/21 +103.193.188.0/22 +103.193.192.0/22 +103.196.64.0/24 +103.196.88.0/21 +103.197.0.0/22 +103.197.228.0/22 +103.198.124.0/22 +103.198.180.0/23 +103.198.216.0/21 +103.198.224.0/20 +103.198.244.0/22 +103.198.60.0/22 +103.2.108.0/22 +103.2.208.0/22 +103.20.112.0/22 +103.20.128.0/22 +103.20.160.0/22 +103.20.248.0/22 +103.20.32.0/22 +103.200.136.0/21 +103.200.144.0/21 +103.200.220.0/22 +103.200.224.0/24 +103.201.192.0/24 +103.202.0.0/19 +103.202.112.0/22 +103.202.120.0/21 +103.202.128.0/20 +103.202.144.0/22 +103.202.32.0/20 +103.202.92.0/22 +103.202.96.0/20 +103.203.140.0/22 +103.203.216.0/22 +103.203.96.0/22 +103.204.72.0/22 +103.205.188.0/22 +103.205.192.0/22 +103.205.252.0/22 +103.205.4.0/22 +103.207.228.0/22 +103.208.12.0/22 +103.208.48.0/22 +103.209.112.0/22 +103.209.136.0/22 +103.21.116.0/22 +103.21.140.0/22 +103.21.176.0/22 +103.210.160.0/22 +103.210.170.0/23 +103.211.220.0/22 +103.211.44.0/22 +103.212.1.0/24 +103.212.109.0/24 +103.212.12.0/22 +103.212.2.0/24 +103.212.4.0/22 +103.212.48.0/23 +103.213.132.0/22 +103.213.144.0/23 +103.213.148.0/22 +103.213.160.0/19 +103.213.48.0/21 +103.213.60.0/22 +103.213.64.0/19 +103.213.96.0/22 +103.214.48.0/22 +103.215.140.0/22 +103.215.36.0/22 +103.215.44.0/24 +103.216.136.0/22 +103.216.152.0/22 +103.216.252.0/24 +103.216.4.0/22 +103.217.184.0/21 +103.217.192.0/20 +103.218.216.0/22 +103.219.100.0/23 +103.219.176.0/22 +103.219.184.0/22 +103.219.24.0/21 +103.219.32.0/21 +103.219.85.0/24 +103.219.86.0/23 +103.219.92.0/24 +103.22.188.0/22 +103.22.252.0/22 +103.220.124.0/22 +103.220.128.0/19 +103.220.160.0/21 +103.220.240.0/22 +103.220.52.0/22 +103.220.56.0/21 +103.220.64.0/22 +103.220.92.0/22 +103.221.140.0/22 +103.222.176.0/21 +103.222.184.0/22 +103.222.216.0/22 +103.222.33.0/24 +103.222.40.0/22 +103.223.132.0/22 +103.223.144.0/20 +103.224.220.0/22 +103.224.232.0/22 +103.226.57.0/24 +103.226.59.0/24 +103.227.120.0/22 +103.227.136.0/22 +103.227.228.0/22 +103.227.76.0/22 +103.227.80.0/22 +103.228.136.0/22 +103.228.160.0/22 +103.228.204.0/23 +103.228.208.0/22 +103.228.228.0/22 +103.229.148.0/22 +103.229.172.0/22 +103.229.212.0/22 +103.229.216.0/21 +103.229.236.0/22 +103.23.160.0/22 +103.23.8.0/22 +103.230.110.0/23 +103.230.200.0/22 +103.230.212.0/22 +103.230.236.0/22 +103.231.16.0/24 +103.231.64.0/21 +103.232.144.0/22 +103.232.166.0/23 +103.233.128.0/22 +103.233.136.0/23 +103.233.138.0/24 +103.233.162.0/23 +103.233.4.0/22 +103.233.52.0/22 +103.234.128.0/23 +103.234.131.0/24 +103.234.20.0/22 +103.234.56.0/22 +103.235.100.0/22 +103.235.136.0/22 +103.235.144.0/24 +103.235.220.0/22 +103.235.224.0/19 +103.235.85.0/24 +103.236.120.0/22 +103.236.244.0/22 +103.236.248.0/21 +103.236.52.0/22 +103.236.56.0/21 +103.236.64.0/19 +103.236.96.0/23 +103.236.98.0/24 +103.237.176.0/20 +103.237.192.0/19 +103.237.224.0/20 +103.237.240.0/21 +103.237.248.0/23 +103.237.28.0/23 +103.237.8.0/22 +103.238.0.0/21 +103.238.132.0/22 +103.238.144.0/22 +103.238.16.0/22 +103.238.160.0/22 +103.238.180.0/22 +103.238.184.0/21 +103.238.204.0/22 +103.238.48.0/24 +103.238.52.0/22 +103.238.96.0/23 +103.238.98.0/24 +103.239.152.0/22 +103.239.184.0/23 +103.239.186.0/24 +103.239.192.0/22 +103.239.204.0/22 +103.239.224.0/22 +103.239.244.0/22 +103.239.68.0/22 +103.24.116.0/22 +103.24.176.0/22 +103.24.228.0/22 +103.240.124.0/22 +103.240.16.0/22 +103.240.244.0/22 +103.240.36.0/22 +103.240.84.0/22 +103.241.95.0/24 +103.242.128.0/24 +103.242.130.0/24 +103.242.168.0/23 +103.242.172.0/22 +103.242.212.0/22 +103.243.136.0/22 +103.243.252.0/22 +103.244.232.0/22 +103.244.59.0/24 +103.244.64.0/22 +103.244.80.0/22 +103.245.128.0/22 +103.245.23.0/24 +103.246.152.0/22 +103.247.168.0/22 +103.247.176.0/22 +103.247.191.0/24 +103.248.152.0/22 +103.248.224.0/22 +103.249.136.0/24 +103.249.244.0/22 +103.249.252.0/22 +103.249.52.0/22 +103.25.156.0/24 +103.25.20.0/22 +103.25.24.0/22 +103.25.36.0/22 +103.25.64.0/23 +103.250.104.0/22 +103.250.192.0/22 +103.250.216.0/22 +103.250.248.0/21 +103.250.32.0/22 +103.251.124.0/22 +103.251.160.0/22 +103.251.204.0/23 +103.251.207.0/24 +103.251.240.0/22 +103.251.32.0/22 +103.251.84.0/22 +103.251.96.0/22 +103.252.172.0/22 +103.252.248.0/22 +103.252.36.0/22 +103.253.204.0/22 +103.253.232.0/22 +103.253.60.0/22 +103.254.112.0/22 +103.254.188.0/22 +103.254.68.0/22 +103.254.76.0/22 +103.255.140.0/22 +103.255.200.0/22 +103.255.68.0/22 +103.255.92.0/22 +103.26.0.0/22 +103.26.64.0/22 +103.26.76.0/22 +103.27.24.0/22 +103.27.240.0/22 +103.27.4.0/22 +103.28.204.0/22 +103.28.212.0/22 +103.28.8.0/24 +103.29.136.0/22 +103.29.16.0/22 +103.29.24.0/23 +103.3.112.0/20 +103.3.128.0/22 +103.3.136.0/21 +103.3.152.0/21 +103.3.96.0/22 +103.30.148.0/24 +103.30.151.0/24 +103.31.200.0/22 +103.31.48.0/22 +103.35.104.0/22 +103.36.132.0/22 +103.36.136.0/22 +103.36.164.0/22 +103.36.168.0/21 +103.36.192.0/20 +103.36.208.0/22 +103.36.220.0/22 +103.36.28.0/22 +103.36.36.0/22 +103.36.60.0/22 +103.36.96.0/22 +103.37.100.0/22 +103.37.12.0/22 +103.37.136.0/21 +103.37.144.0/20 +103.37.16.0/22 +103.37.160.0/21 +103.37.172.0/22 +103.37.44.0/22 +103.37.72.0/22 +103.38.116.0/22 +103.38.224.0/22 +103.38.232.0/22 +103.38.252.0/23 +103.38.40.0/22 +103.38.76.0/22 +103.38.84.0/22 +103.38.92.0/23 +103.39.200.0/21 +103.39.208.0/20 +103.39.224.0/21 +103.39.232.0/22 +103.39.64.0/22 +103.4.56.0/22 +103.40.12.0/22 +103.40.173.0/24 +103.40.174.0/23 +103.40.192.0/22 +103.40.232.0/22 +103.40.240.0/20 +103.41.0.0/22 +103.41.116.0/22 +103.41.164.0/22 +103.41.232.0/23 +103.42.76.0/22 +103.42.8.0/22 +103.43.132.0/24 +103.43.134.0/23 +103.43.184.0/22 +103.43.240.0/23 +103.44.144.0/22 +103.44.168.0/22 +103.44.176.0/22 +103.44.236.0/22 +103.44.240.0/20 +103.44.56.0/22 +103.44.80.0/22 +103.45.128.0/19 +103.45.160.0/22 +103.45.168.0/23 +103.45.171.0/24 +103.45.172.0/22 +103.45.176.0/20 +103.45.248.0/22 +103.45.72.0/21 +103.46.12.0/22 +103.46.128.0/21 +103.46.136.0/22 +103.46.16.0/20 +103.46.168.0/22 +103.46.32.0/19 +103.46.64.0/18 +103.47.48.0/22 +103.47.80.0/22 +103.48.232.0/23 +103.48.235.0/24 +103.49.108.0/22 +103.49.12.0/22 +103.5.192.0/23 +103.5.194.0/24 +103.5.52.0/24 +103.52.100.0/22 +103.52.104.0/23 +103.52.172.0/22 +103.52.176.0/22 +103.52.196.0/22 +103.53.124.0/22 +103.53.208.0/24 +103.53.211.0/24 +103.54.48.0/22 +103.55.172.0/22 +103.55.228.0/22 +103.56.100.0/22 +103.56.104.0/22 +103.56.152.0/22 +103.56.184.0/22 +103.56.60.0/22 +103.56.76.0/22 +103.57.12.0/22 +103.57.136.0/23 +103.57.139.0/24 +103.59.112.0/21 +103.59.124.0/22 +103.59.148.0/22 +103.59.168.0/23 +103.6.220.0/22 +103.60.164.0/22 +103.60.228.0/23 +103.60.236.0/22 +103.61.104.0/23 +103.61.153.0/24 +103.61.154.0/23 +103.61.188.0/22 +103.61.60.0/22 +103.62.88.0/23 +103.63.160.0/20 +103.63.176.0/21 +103.63.244.0/22 +103.64.140.0/22 +103.64.144.0/22 +103.64.152.0/21 +103.64.208.0/21 +103.64.24.0/21 +103.65.224.0/23 +103.65.8.0/22 +103.66.32.0/22 +103.68.128.0/22 +103.69.16.0/22 +103.7.140.0/22 +103.70.8.0/22 +103.71.200.0/23 +103.71.202.0/24 +103.71.232.0/22 +103.71.68.0/22 +103.72.113.0/24 +103.72.172.0/24 +103.73.116.0/22 +103.73.136.0/21 +103.73.144.0/22 +103.73.158.0/24 +103.73.204.0/22 +103.73.48.0/24 +103.74.24.0/21 +103.74.48.0/22 +103.74.80.0/22 +103.75.104.0/22 +103.75.152.0/22 +103.76.220.0/22 +103.76.224.0/22 +103.76.60.0/22 +103.77.132.0/22 +103.77.28.0/22 +103.78.126.0/23 +103.78.228.0/22 +103.78.60.0/22 +103.79.200.0/22 +103.79.228.0/24 +103.79.24.0/22 +103.8.220.0/22 +103.8.32.0/22 +103.8.52.0/22 +103.8.68.0/22 +103.81.123.0/24 +103.81.200.0/22 +103.81.4.0/22 +103.81.48.0/22 +103.82.224.0/22 +103.83.44.0/22 +103.83.64.0/22 +103.83.72.0/22 +103.84.170.0/23 +103.85.147.0/24 +103.85.164.0/22 +103.85.168.0/21 +103.85.176.0/22 +103.85.84.0/22 +103.87.180.0/22 +103.88.32.0/21 +103.88.64.0/22 +103.88.96.0/22 +103.89.184.0/21 +103.89.192.0/19 +103.89.224.0/21 +103.9.252.0/22 +103.9.8.0/22 +103.90.152.0/22 +103.90.176.0/22 +103.90.188.0/22 +103.90.56.0/23 +103.90.92.0/22 +103.91.176.0/22 +103.91.208.0/22 +103.92.88.0/22 +103.93.180.0/22 +103.93.204.0/22 +103.94.12.0/22 +103.94.200.0/22 +103.95.252.0/22 +103.95.68.0/22 +103.96.214.0/23 +103.96.224.0/23 +103.96.8.0/22 +103.97.112.0/23 +103.97.144.0/22 +103.97.60.0/24 +103.98.125.0/24 +103.98.127.0/24 +103.98.220.0/22 +103.98.248.0/23 +103.98.251.0/24 +103.98.252.0/22 +103.98.44.0/22 +103.98.92.0/22 +103.98.96.0/22 +103.99.104.0/22 +104.192.108.0/23 +104.192.110.0/24 +106.0.4.0/22 +106.108.0.0/14 +106.11.0.0/16 +106.112.0.0/12 +106.12.0.0/17 +106.12.128.0/18 +106.12.192.0/19 +106.12.224.0/20 +106.12.240.0/21 +106.12.250.0/23 +106.12.252.0/23 +106.12.254.0/24 +106.13.0.0/16 +106.14.0.0/15 +106.16.0.0/14 +106.2.100.0/22 +106.2.104.0/21 +106.2.112.0/21 +106.2.124.0/22 +106.2.128.0/19 +106.2.224.0/24 +106.2.232.0/21 +106.2.37.0/24 +106.2.40.0/23 +106.2.42.0/24 +106.2.45.0/24 +106.2.46.0/23 +106.2.48.0/23 +106.2.51.0/24 +106.2.52.0/22 +106.2.56.0/22 +106.2.62.0/23 +106.2.64.0/20 +106.2.81.0/24 +106.2.82.0/23 +106.2.89.0/24 +106.2.92.0/22 +106.2.96.0/24 +106.224.0.0/14 +106.228.0.0/15 +106.230.0.0/16 +106.3.0.0/19 +106.3.128.0/19 +106.3.192.0/20 +106.3.208.0/21 +106.3.224.0/21 +106.3.32.0/20 +106.3.80.0/22 +106.3.88.0/21 +106.3.96.0/22 +106.32.0.0/12 +106.4.0.0/14 +106.48.16.0/21 +106.52.0.0/14 +106.56.0.0/14 +106.60.0.0/15 +106.62.0.0/16 +106.63.0.0/17 +106.74.0.0/16 +106.75.0.0/17 +106.75.128.0/18 +106.75.208.0/20 +106.75.224.0/19 +106.8.0.0/15 +106.80.0.0/13 +106.88.0.0/14 +106.92.0.0/16 +108.165.168.0/24 +108.165.240.0/24 +109.244.0.0/16 +110.100.0.0/16 +110.112.0.0/15 +110.114.0.0/16 +110.115.128.0/17 +110.116.0.0/16 +110.120.0.0/16 +110.124.0.0/16 +110.125.128.0/17 +110.152.0.0/14 +110.156.0.0/15 +110.16.0.0/14 +110.166.0.0/15 +110.172.200.0/21 +110.173.16.0/20 +110.173.192.0/19 +110.173.32.0/20 +110.173.8.0/21 +110.176.0.0/12 +110.199.0.0/16 +110.203.0.0/23 +110.211.0.0/16 +110.218.0.0/15 +110.228.0.0/14 +110.236.0.0/15 +110.240.0.0/12 +110.40.0.0/24 +110.40.128.0/17 +110.40.13.0/24 +110.40.14.0/23 +110.40.16.0/24 +110.41.0.0/16 +110.42.0.0/15 +110.51.0.0/16 +110.52.0.0/15 +110.56.0.0/13 +110.6.0.0/15 +110.64.0.0/15 +110.72.0.0/15 +110.75.0.0/16 +110.76.0.0/18 +110.76.156.0/22 +110.76.184.0/22 +110.76.192.0/18 +110.77.0.0/17 +110.80.0.0/13 +110.88.0.0/14 +110.94.0.0/17 +110.96.0.0/16 +111.0.0.0/10 +111.112.0.0/14 +111.116.0.0/15 +111.118.200.0/21 +111.120.0.0/14 +111.124.0.0/16 +111.126.0.0/15 +111.128.0.0/16 +111.132.0.0/16 +111.142.0.0/15 +111.144.0.0/14 +111.148.0.0/16 +111.149.0.0/24 +111.160.0.0/13 +111.170.0.0/16 +111.172.0.0/14 +111.176.0.0/13 +111.186.0.0/15 +111.192.0.0/12 +111.208.121.0/24 +111.208.254.0/24 +111.210.0.0/20 +111.210.16.0/24 +111.211.192.0/18 +111.212.0.0/14 +111.221.128.0/17 +111.221.28.0/24 +111.222.0.0/16 +111.223.12.0/22 +111.224.0.0/14 +111.228.0.0/18 +111.229.0.0/16 +111.230.0.0/15 +111.235.156.0/22 +111.235.160.0/22 +111.235.164.0/23 +111.235.168.0/22 +111.235.172.0/23 +111.235.174.0/24 +111.235.178.0/23 +111.235.180.0/23 +111.235.182.0/24 +111.72.0.0/13 +111.85.0.0/16 +112.0.0.0/10 +112.109.128.0/17 +112.111.0.0/16 +112.112.0.0/14 +112.116.0.0/15 +112.122.0.0/15 +112.124.0.0/14 +112.132.0.0/16 +112.192.0.0/14 +112.224.0.0/11 +112.64.0.0/14 +112.73.96.0/19 +112.74.0.0/16 +112.80.0.0/12 +112.96.0.0/13 +113.0.0.0/13 +113.12.0.0/14 +113.128.0.0/15 +113.130.112.0/21 +113.130.96.0/20 +113.132.0.0/14 +113.136.0.0/13 +113.16.0.0/15 +113.18.0.0/16 +113.194.0.0/15 +113.197.101.0/24 +113.197.103.0/24 +113.197.104.0/23 +113.200.0.0/15 +113.204.0.0/14 +113.208.112.0/21 +113.209.128.0/17 +113.21.232.0/21 +113.213.0.0/18 +113.213.64.0/19 +113.213.96.0/20 +113.214.0.0/15 +113.218.0.0/15 +113.220.0.0/14 +113.224.0.0/12 +113.24.0.0/14 +113.240.0.0/13 +113.248.0.0/14 +113.31.144.0/20 +113.31.160.0/19 +113.31.192.0/18 +113.31.96.0/19 +113.44.0.0/16 +113.45.0.0/18 +113.45.102.0/23 +113.45.104.0/21 +113.45.112.0/22 +113.45.120.0/22 +113.45.128.0/17 +113.45.64.0/19 +113.45.96.0/22 +113.46.0.0/16 +113.47.0.0/18 +113.47.104.0/22 +113.47.110.0/24 +113.47.112.0/20 +113.47.128.0/18 +113.47.200.0/21 +113.47.216.0/21 +113.47.232.0/21 +113.47.240.0/20 +113.47.64.0/19 +113.47.96.0/21 +113.48.127.0/24 +113.48.224.0/20 +113.48.48.0/20 +113.49.0.0/19 +113.50.0.0/20 +113.50.32.0/24 +113.50.48.0/20 +113.50.64.0/20 +113.54.0.0/15 +113.56.0.0/15 +113.58.0.0/16 +113.59.0.0/17 +113.59.224.0/22 +113.62.0.0/15 +113.64.0.0/10 +113.8.0.0/15 +114.104.0.0/14 +114.110.0.0/20 +114.110.96.0/22 +114.111.0.0/23 +114.111.16.0/20 +114.111.191.0/24 +114.112.104.0/22 +114.112.136.0/21 +114.112.144.0/21 +114.112.200.0/21 +114.112.208.0/20 +114.112.24.0/21 +114.112.32.0/19 +114.112.4.0/23 +114.112.64.0/19 +114.112.96.0/21 +114.113.144.0/20 +114.113.196.0/22 +114.113.200.0/24 +114.113.203.0/24 +114.113.208.0/21 +114.113.221.0/24 +114.113.223.0/24 +114.113.224.0/20 +114.113.63.0/24 +114.113.64.0/20 +114.113.80.0/22 +114.113.84.0/24 +114.113.88.0/21 +114.113.96.0/19 +114.114.112.0/21 +114.115.0.0/16 +114.116.0.0/15 +114.118.0.0/17 +114.119.10.0/24 +114.119.117.0/24 +114.119.119.0/24 +114.119.204.0/22 +114.119.32.0/24 +114.132.0.0/16 +114.135.0.0/16 +114.138.0.0/15 +114.141.128.0/18 +114.142.142.0/23 +114.196.0.0/15 +114.212.0.0/14 +114.216.0.0/13 +114.224.0.0/11 +114.28.128.0/18 +114.28.248.0/21 +114.28.68.0/22 +114.28.72.0/21 +114.55.0.0/16 +114.60.0.0/14 +114.64.0.0/16 +114.66.0.0/18 +114.66.236.0/22 +114.66.240.0/20 +114.66.64.0/24 +114.66.72.0/21 +114.66.80.0/23 +114.67.128.0/17 +114.67.16.0/21 +114.67.48.0/24 +114.67.57.0/24 +114.67.58.0/24 +114.67.60.0/23 +114.67.62.0/24 +114.67.64.0/18 +114.80.0.0/12 +114.96.0.0/13 +115.102.0.0/16 +115.120.0.0/17 +115.120.128.0/20 +115.120.144.0/23 +115.120.148.0/22 +115.120.152.0/21 +115.120.176.0/20 +115.120.192.0/18 +115.124.16.0/20 +115.148.0.0/14 +115.152.0.0/13 +115.168.0.0/14 +115.172.32.0/21 +115.172.46.0/23 +115.173.0.0/19 +115.175.0.0/18 +115.175.104.0/22 +115.175.108.0/23 +115.175.110.0/24 +115.175.112.0/20 +115.175.128.0/17 +115.175.64.0/19 +115.175.96.0/21 +115.180.0.0/17 +115.182.0.0/15 +115.190.0.0/16 +115.191.0.0/18 +115.191.64.0/20 +115.192.0.0/11 +115.224.0.0/12 +115.24.0.0/14 +115.28.0.0/15 +115.31.64.0/22 +115.32.0.0/19 +115.32.104.0/21 +115.32.120.0/21 +115.32.128.0/19 +115.32.32.0/20 +115.32.52.0/22 +115.32.56.0/21 +115.32.64.0/19 +115.33.0.0/19 +115.33.128.0/20 +115.44.0.0/15 +115.46.0.0/16 +115.48.0.0/12 +115.84.0.0/18 +115.85.192.0/18 +116.0.89.0/24 +116.1.0.0/16 +116.112.0.0/14 +116.116.0.0/15 +116.128.128.0/18 +116.128.200.0/21 +116.128.208.0/20 +116.128.224.0/19 +116.129.0.0/16 +116.13.0.0/16 +116.130.0.0/15 +116.132.0.0/15 +116.135.0.0/16 +116.136.0.0/13 +116.144.0.0/14 +116.148.0.0/15 +116.153.0.0/16 +116.154.0.0/15 +116.16.0.0/12 +116.162.0.0/16 +116.163.0.0/18 +116.165.0.0/16 +116.167.0.0/16 +116.168.0.0/14 +116.172.128.0/17 +116.172.64.0/18 +116.174.0.0/15 +116.176.0.0/14 +116.181.0.0/16 +116.182.0.0/16 +116.192.0.0/16 +116.193.16.0/23 +116.193.18.0/24 +116.196.0.0/21 +116.196.12.0/23 +116.196.129.0/24 +116.196.130.0/23 +116.196.132.0/22 +116.196.136.0/21 +116.196.144.0/21 +116.196.152.0/22 +116.196.156.0/23 +116.196.176.0/21 +116.196.192.0/21 +116.196.218.0/23 +116.196.220.0/22 +116.196.64.0/18 +116.196.8.0/22 +116.197.160.0/21 +116.198.0.0/18 +116.198.144.0/20 +116.198.160.0/20 +116.198.176.0/21 +116.198.192.0/18 +116.198.64.0/21 +116.198.72.0/22 +116.198.80.0/21 +116.198.96.0/19 +116.199.0.0/17 +116.2.0.0/15 +116.204.0.0/17 +116.205.0.0/16 +116.207.0.0/16 +116.208.0.0/14 +116.214.128.0/22 +116.214.132.0/23 +116.214.134.0/24 +116.214.32.0/19 +116.224.0.0/12 +116.242.0.0/16 +116.246.0.0/15 +116.248.0.0/15 +116.252.0.0/15 +116.254.104.0/21 +116.255.128.0/17 +116.4.0.0/14 +116.52.0.0/14 +116.56.0.0/15 +116.58.208.0/24 +116.62.0.0/15 +116.66.123.0/24 +116.66.36.0/24 +116.66.48.0/23 +116.66.53.0/24 +116.66.54.0/23 +116.66.98.0/24 +116.68.136.0/21 +116.68.176.0/21 +116.70.64.0/18 +116.76.0.0/15 +116.78.0.0/16 +116.8.0.0/14 +116.85.0.0/16 +116.90.80.0/20 +116.95.0.0/16 +117.106.0.0/15 +117.112.0.0/13 +117.121.132.0/22 +117.122.192.0/18 +117.124.231.0/24 +117.124.232.0/22 +117.124.236.0/23 +117.124.240.0/22 +117.124.244.0/24 +117.124.246.0/24 +117.124.98.0/24 +117.126.0.0/16 +117.128.0.0/10 +117.21.0.0/16 +117.22.0.0/15 +117.24.0.0/13 +117.32.0.0/13 +117.40.0.0/14 +117.44.0.0/15 +117.48.0.0/18 +117.48.112.0/20 +117.48.128.0/19 +117.48.160.0/20 +117.48.192.0/20 +117.48.216.0/21 +117.48.224.0/20 +117.48.64.0/19 +117.50.0.0/16 +117.51.128.0/19 +117.51.160.0/23 +117.51.168.0/21 +117.57.0.0/16 +117.59.0.0/16 +117.60.0.0/14 +117.64.0.0/13 +117.72.0.0/23 +117.72.144.0/20 +117.72.16.0/23 +117.72.160.0/19 +117.72.192.0/19 +117.72.24.0/21 +117.72.240.0/21 +117.72.248.0/22 +117.72.255.0/24 +117.72.32.0/19 +117.72.64.0/18 +117.72.8.0/21 +117.73.0.0/20 +117.73.16.0/21 +117.73.252.0/22 +117.74.128.0/21 +117.74.136.0/22 +117.74.64.0/20 +117.78.0.0/18 +117.79.128.0/21 +117.79.144.0/20 +117.79.160.0/21 +117.79.224.0/20 +117.79.241.0/24 +117.79.242.0/24 +117.79.80.0/20 +117.8.0.0/13 +117.80.0.0/12 +118.102.16.0/20 +118.103.164.0/22 +118.112.0.0/13 +118.120.0.0/14 +118.124.0.0/15 +118.126.140.0/23 +118.126.142.0/24 +118.126.32.0/19 +118.126.64.0/18 +118.132.0.0/14 +118.144.0.0/16 +118.145.0.0/19 +118.145.112.0/21 +118.145.128.0/19 +118.145.160.0/21 +118.145.176.0/20 +118.145.192.0/18 +118.145.32.0/20 +118.145.64.0/19 +118.145.96.0/20 +118.178.0.0/16 +118.180.0.0/14 +118.184.128.0/17 +118.186.0.0/19 +118.186.112.0/21 +118.186.128.0/18 +118.186.208.0/21 +118.186.240.0/21 +118.186.32.0/24 +118.186.34.0/23 +118.186.36.0/22 +118.186.56.0/21 +118.186.64.0/21 +118.186.80.0/20 +118.186.96.0/20 +118.187.0.0/18 +118.187.254.0/23 +118.187.64.0/19 +118.188.18.0/23 +118.188.20.0/22 +118.188.24.0/23 +118.190.0.0/16 +118.191.0.0/21 +118.191.12.0/24 +118.191.128.0/22 +118.191.152.0/24 +118.191.192.0/23 +118.191.208.0/24 +118.191.216.0/24 +118.191.223.0/24 +118.191.224.0/24 +118.191.240.0/23 +118.191.248.0/23 +118.191.250.0/24 +118.191.8.0/22 +118.192.20.0/24 +118.192.64.0/23 +118.192.67.0/24 +118.192.68.0/23 +118.192.70.0/24 +118.193.96.0/19 +118.194.134.0/23 +118.194.164.0/22 +118.194.240.0/21 +118.194.32.0/19 +118.195.0.0/16 +118.196.0.0/16 +118.197.0.0/18 +118.197.64.0/19 +118.202.0.0/15 +118.204.0.0/17 +118.212.0.0/15 +118.215.192.0/19 +118.228.0.0/15 +118.230.0.0/16 +118.239.0.0/16 +118.24.0.0/15 +118.242.0.0/22 +118.242.16.0/22 +118.242.24.0/22 +118.242.32.0/22 +118.242.40.0/24 +118.244.0.0/21 +118.244.128.0/17 +118.247.0.0/16 +118.248.0.0/13 +118.26.116.0/22 +118.26.120.0/24 +118.26.126.0/23 +118.26.128.0/22 +118.26.136.0/22 +118.26.160.0/20 +118.26.192.0/24 +118.26.194.0/23 +118.26.197.0/24 +118.26.198.0/23 +118.26.200.0/21 +118.26.208.0/20 +118.26.224.0/19 +118.26.32.0/22 +118.26.48.0/22 +118.26.64.0/23 +118.26.68.0/23 +118.26.72.0/22 +118.26.96.0/21 +118.30.0.0/15 +118.64.0.0/21 +118.64.248.0/21 +118.65.0.0/21 +118.66.112.0/23 +118.66.184.0/24 +118.66.224.0/20 +118.66.248.0/21 +118.72.0.0/13 +118.80.0.0/15 +118.84.0.0/15 +118.88.128.0/17 +118.88.32.0/19 +118.88.64.0/18 +118.89.0.0/16 +119.0.0.0/15 +119.108.0.0/15 +119.112.0.0/12 +119.128.0.0/12 +119.144.0.0/14 +119.148.160.0/20 +119.15.136.0/23 +119.15.140.0/23 +119.161.120.0/22 +119.161.124.0/24 +119.161.183.0/24 +119.162.0.0/15 +119.164.0.0/14 +119.176.0.0/12 +119.18.208.0/21 +119.18.224.0/24 +119.18.226.0/24 +119.18.237.0/24 +119.18.239.0/24 +119.2.128.0/17 +119.23.0.0/16 +119.233.128.0/17 +119.235.128.0/24 +119.235.130.0/24 +119.235.136.0/24 +119.235.138.0/24 +119.235.143.0/24 +119.235.144.0/23 +119.235.151.0/24 +119.235.160.0/23 +119.235.167.0/24 +119.235.185.0/24 +119.248.0.0/14 +119.253.0.0/20 +119.253.249.0/24 +119.253.252.0/24 +119.253.32.0/19 +119.253.64.0/19 +119.254.0.0/16 +119.255.128.0/17 +119.255.63.0/24 +119.27.160.0/19 +119.28.28.0/24 +119.29.0.0/16 +119.3.0.0/16 +119.31.192.0/19 +119.32.0.0/15 +119.34.0.0/16 +119.36.0.0/16 +119.37.0.0/23 +119.37.12.0/24 +119.37.192.0/21 +119.37.2.0/24 +119.38.0.0/21 +119.38.192.0/19 +119.39.0.0/16 +119.4.0.0/14 +119.40.128.0/17 +119.40.41.0/24 +119.40.64.0/20 +119.41.0.0/16 +119.42.0.0/19 +119.42.136.0/21 +119.42.224.0/19 +119.44.0.0/22 +119.44.12.0/24 +119.44.16.0/22 +119.44.192.0/24 +119.44.20.0/23 +119.44.200.0/24 +119.44.205.0/24 +119.44.208.0/22 +119.44.212.0/23 +119.44.214.0/24 +119.44.217.0/24 +119.44.218.0/23 +119.44.220.0/22 +119.44.224.0/20 +119.44.23.0/24 +119.44.24.0/22 +119.44.253.0/24 +119.44.254.0/23 +119.44.28.0/23 +119.44.4.0/23 +119.44.45.0/24 +119.44.46.0/24 +119.44.50.0/23 +119.44.52.0/24 +119.44.56.0/21 +119.44.7.0/24 +119.44.8.0/22 +119.45.0.0/16 +119.48.0.0/13 +119.57.0.0/21 +119.57.100.0/23 +119.57.102.0/24 +119.57.112.0/20 +119.57.12.0/24 +119.57.132.0/22 +119.57.136.0/21 +119.57.16.0/21 +119.57.160.0/20 +119.57.190.0/23 +119.57.246.0/23 +119.57.248.0/21 +119.57.25.0/24 +119.57.28.0/22 +119.57.32.0/21 +119.57.44.0/22 +119.57.51.0/24 +119.57.52.0/22 +119.57.56.0/21 +119.57.64.0/19 +119.57.8.0/23 +119.57.96.0/22 +119.60.0.0/15 +119.62.0.0/16 +119.75.208.0/20 +119.78.0.0/15 +119.80.0.0/21 +119.80.160.0/23 +119.80.162.0/24 +119.80.192.0/21 +119.80.200.0/22 +119.80.240.0/22 +119.80.248.0/21 +119.80.8.0/22 +119.84.0.0/14 +119.88.128.0/17 +119.90.32.0/19 +119.91.0.0/16 +119.96.0.0/13 +120.0.0.0/12 +120.131.0.0/19 +120.131.124.0/22 +120.131.88.0/21 +120.132.0.0/18 +120.132.112.0/24 +120.132.116.0/22 +120.132.120.0/21 +120.132.128.0/17 +120.132.64.0/19 +120.132.96.0/20 +120.133.0.0/16 +120.134.0.0/15 +120.136.128.0/21 +120.136.140.0/22 +120.136.144.0/20 +120.136.16.0/21 +120.136.160.0/20 +120.136.176.0/21 +120.136.184.0/22 +120.136.188.0/23 +120.136.190.0/24 +120.192.0.0/10 +120.24.0.0/14 +120.31.128.0/20 +120.31.144.0/24 +120.31.66.0/23 +120.31.68.0/22 +120.32.0.0/12 +120.48.0.0/16 +120.49.0.0/17 +120.49.192.0/18 +120.52.0.0/15 +120.55.0.0/16 +120.65.0.0/16 +120.68.0.0/14 +120.72.160.0/24 +120.72.162.0/23 +120.72.164.0/22 +120.72.168.0/24 +120.72.170.0/23 +120.72.172.0/23 +120.72.174.0/24 +120.72.177.0/24 +120.72.178.0/24 +120.72.180.0/24 +120.72.182.0/23 +120.72.184.0/22 +120.72.188.0/23 +120.72.190.0/24 +120.72.32.0/19 +120.76.0.0/14 +120.80.0.0/13 +120.92.0.0/17 +120.92.128.0/18 +120.92.192.0/19 +120.92.224.0/20 +120.94.0.0/15 +121.0.16.0/20 +121.16.0.0/12 +121.192.0.0/13 +121.201.0.0/17 +121.204.0.0/14 +121.224.0.0/12 +121.248.0.0/14 +121.255.0.0/16 +121.32.0.0/14 +121.36.0.0/15 +121.39.255.0/24 +121.4.0.0/15 +121.40.0.0/14 +121.46.0.0/19 +121.46.128.0/21 +121.46.141.0/24 +121.46.192.0/21 +121.46.200.0/22 +121.46.224.0/20 +121.46.244.0/22 +121.46.248.0/22 +121.46.252.0/23 +121.46.254.0/24 +121.47.0.0/16 +121.48.0.0/15 +121.51.0.0/16 +121.52.160.0/19 +121.52.208.0/20 +121.52.224.0/19 +121.55.0.0/18 +121.56.0.0/15 +121.58.0.0/17 +121.58.156.0/22 +121.59.160.0/20 +121.59.255.0/24 +121.59.4.0/22 +121.59.8.0/21 +121.60.0.0/14 +121.69.0.0/16 +121.70.0.0/17 +121.76.0.0/15 +121.79.128.0/20 +121.79.144.0/22 +121.79.148.0/24 +121.8.0.0/13 +121.89.0.0/16 +121.91.104.0/21 +122.0.64.0/18 +122.10.133.0/24 +122.10.136.0/23 +122.102.64.0/20 +122.11.32.0/19 +122.112.0.0/22 +122.112.132.0/22 +122.112.136.0/21 +122.112.144.0/20 +122.112.160.0/19 +122.112.192.0/18 +122.112.32.0/19 +122.114.0.0/16 +122.115.0.0/20 +122.115.224.0/20 +122.115.32.0/19 +122.119.110.0/23 +122.119.112.0/23 +122.119.114.0/24 +122.119.12.0/22 +122.119.120.0/24 +122.119.122.0/24 +122.119.124.0/23 +122.119.129.0/24 +122.119.147.0/24 +122.119.160.0/23 +122.119.172.0/24 +122.119.180.0/22 +122.119.190.0/24 +122.119.20.0/22 +122.119.224.0/22 +122.119.232.0/23 +122.119.236.0/24 +122.119.24.0/23 +122.119.253.0/24 +122.119.26.0/24 +122.119.32.0/24 +122.119.4.0/23 +122.119.50.0/24 +122.119.73.0/24 +122.119.96.0/23 +122.13.0.0/16 +122.136.0.0/13 +122.14.192.0/18 +122.14.44.0/22 +122.14.62.0/24 +122.144.128.0/20 +122.144.144.0/23 +122.144.147.0/24 +122.144.152.0/23 +122.144.156.0/23 +122.144.161.0/24 +122.144.164.0/22 +122.144.168.0/22 +122.144.172.0/23 +122.144.178.0/23 +122.144.180.0/22 +122.144.192.0/21 +122.144.200.0/22 +122.144.206.0/23 +122.144.208.0/23 +122.144.211.0/24 +122.144.212.0/22 +122.144.216.0/21 +122.144.232.0/22 +122.144.236.0/23 +122.144.240.0/24 +122.144.248.0/23 +122.152.192.0/18 +122.156.0.0/14 +122.188.0.0/14 +122.192.0.0/14 +122.200.104.0/22 +122.200.120.0/22 +122.200.124.0/24 +122.200.40.0/21 +122.200.68.0/23 +122.200.78.0/24 +122.200.82.0/24 +122.200.84.0/23 +122.200.86.0/24 +122.200.92.0/23 +122.204.0.0/14 +122.224.0.0/12 +122.240.0.0/13 +122.248.48.0/21 +122.248.56.0/22 +122.4.0.0/14 +122.48.0.0/16 +122.49.16.0/20 +122.49.32.0/20 +122.49.8.0/21 +122.51.0.0/16 +122.64.0.0/16 +122.70.0.0/15 +122.72.112.0/24 +122.72.16.0/24 +122.72.3.0/24 +122.72.38.0/24 +122.72.57.0/24 +122.77.240.0/24 +122.84.0.0/16 +122.9.0.0/16 +122.90.0.0/16 +122.91.0.0/17 +122.94.0.0/16 +122.96.0.0/15 +123.101.0.0/16 +123.103.0.0/20 +123.103.16.0/21 +123.103.24.0/22 +123.103.28.0/23 +123.103.30.0/24 +123.103.40.0/21 +123.103.48.0/20 +123.103.64.0/18 +123.108.208.0/22 +123.108.212.0/23 +123.108.220.0/22 +123.108.88.0/23 +123.112.0.0/12 +123.128.0.0/13 +123.138.0.0/15 +123.144.0.0/12 +123.160.0.0/12 +123.177.0.0/16 +123.178.0.0/15 +123.180.0.0/14 +123.184.0.0/13 +123.196.112.0/20 +123.206.0.0/15 +123.232.0.0/14 +123.242.192.0/21 +123.244.0.0/14 +123.249.0.0/17 +123.253.224.0/23 +123.254.96.0/21 +123.4.0.0/14 +123.49.192.0/23 +123.49.194.0/24 +123.49.231.0/24 +123.49.232.0/24 +123.49.240.0/24 +123.49.242.0/23 +123.49.245.0/24 +123.52.0.0/14 +123.56.0.0/15 +123.58.0.0/19 +123.58.160.0/20 +123.58.180.0/24 +123.58.182.0/23 +123.58.184.0/24 +123.58.186.0/23 +123.58.188.0/22 +123.58.224.0/19 +123.58.32.0/23 +123.58.34.0/24 +123.58.36.0/24 +123.58.38.0/23 +123.58.40.0/21 +123.58.48.0/24 +123.58.50.0/24 +123.58.53.0/24 +123.58.54.0/23 +123.58.56.0/23 +123.58.59.0/24 +123.58.60.0/22 +123.58.64.0/24 +123.58.96.0/19 +123.59.0.0/16 +123.60.0.0/15 +123.64.0.0/15 +123.66.0.0/16 +123.77.0.0/16 +123.8.0.0/13 +123.82.0.0/17 +123.83.128.0/17 +123.88.0.0/15 +123.90.0.0/16 +123.96.0.0/15 +123.99.192.0/18 +124.112.0.0/13 +124.126.0.0/15 +124.128.0.0/13 +124.14.1.0/24 +124.14.16.0/21 +124.14.2.0/23 +124.14.224.0/19 +124.14.5.0/24 +124.14.64.0/18 +124.14.7.0/24 +124.14.8.0/21 +124.151.0.0/16 +124.152.0.0/16 +124.16.0.0/15 +124.160.0.0/13 +124.172.0.0/15 +124.174.0.0/16 +124.192.0.0/15 +124.196.12.0/23 +124.196.25.0/24 +124.196.26.0/23 +124.196.28.0/24 +124.196.30.0/23 +124.196.32.0/23 +124.196.40.0/22 +124.196.48.0/22 +124.196.52.0/23 +124.196.55.0/24 +124.196.56.0/23 +124.196.58.0/24 +124.196.66.0/24 +124.196.72.0/24 +124.196.77.0/24 +124.196.80.0/22 +124.196.84.0/23 +124.200.0.0/16 +124.201.0.0/17 +124.202.0.0/16 +124.203.176.0/20 +124.204.0.0/14 +124.22.0.0/15 +124.220.0.0/14 +124.224.0.0/12 +124.240.0.0/17 +124.240.128.0/18 +124.243.192.0/18 +124.248.64.0/18 +124.250.0.0/15 +124.254.0.0/18 +124.28.192.0/18 +124.29.0.0/17 +124.31.0.0/16 +124.40.128.0/18 +124.42.0.0/17 +124.47.0.0/18 +124.64.0.0/15 +124.66.0.0/17 +124.67.0.0/16 +124.70.0.0/16 +124.71.0.0/17 +124.71.128.0/18 +124.71.192.0/19 +124.71.224.0/20 +124.71.250.0/24 +124.72.0.0/13 +124.88.0.0/13 +125.104.0.0/13 +125.112.0.0/12 +125.171.0.0/16 +125.208.0.0/19 +125.208.32.0/20 +125.208.49.0/24 +125.210.0.0/15 +125.213.32.0/20 +125.214.96.0/19 +125.215.36.0/23 +125.215.40.0/24 +125.215.44.0/23 +125.215.48.0/24 +125.215.52.0/23 +125.215.54.0/24 +125.216.0.0/13 +125.24.253.0/24 +125.254.128.0/19 +125.254.160.0/20 +125.254.176.0/21 +125.254.184.0/22 +125.254.188.0/23 +125.254.190.0/24 +125.32.0.0/12 +125.58.128.0/17 +125.62.0.0/18 +125.64.0.0/11 +125.98.122.0/23 +125.98.128.0/17 +128.108.0.0/16 +128.14.116.0/24 +129.204.0.0/16 +129.211.0.0/16 +129.28.0.0/16 +132.232.0.0/16 +132.237.134.0/24 +134.175.0.0/16 +138.252.72.0/23 +139.129.0.0/16 +139.148.0.0/16 +139.155.0.0/16 +139.159.0.0/19 +139.159.112.0/22 +139.159.132.0/22 +139.159.136.0/21 +139.159.144.0/20 +139.159.160.0/19 +139.159.192.0/18 +139.159.32.0/20 +139.159.96.0/20 +139.170.0.0/16 +139.186.0.0/16 +139.189.0.0/16 +139.196.0.0/16 +139.198.0.0/15 +139.200.0.0/13 +139.208.0.0/13 +139.217.0.0/16 +139.219.0.0/16 +139.220.128.0/17 +139.224.0.0/16 +139.226.0.0/15 +139.5.60.0/22 +139.9.0.0/17 +139.9.128.0/18 +139.9.192.0/19 +139.9.224.0/20 +139.9.240.0/21 +139.9.248.0/22 +14.103.0.0/16 +14.104.0.0/13 +14.112.0.0/12 +14.134.0.0/15 +14.144.0.0/12 +14.16.0.0/12 +14.204.0.0/15 +14.208.0.0/12 +140.143.0.0/16 +140.179.0.0/16 +140.205.0.0/16 +140.206.0.0/15 +140.210.0.0/24 +140.210.128.0/19 +140.210.16.0/20 +140.210.192.0/19 +140.210.224.0/20 +140.210.32.0/22 +140.210.4.0/22 +140.210.64.0/18 +140.210.8.0/21 +140.224.0.0/16 +140.237.0.0/16 +140.240.0.0/16 +140.243.0.0/16 +140.246.0.0/16 +140.249.0.0/16 +140.250.0.0/16 +140.255.0.0/16 +140.75.0.0/16 +143.20.246.0/24 +143.64.0.0/16 +144.0.0.0/16 +144.12.0.0/16 +144.123.0.0/16 +144.225.186.0/24 +144.255.0.0/16 +144.36.146.0/23 +144.48.212.0/22 +144.48.64.0/22 +144.52.0.0/16 +144.7.0.0/17 +144.79.10.0/23 +144.79.54.0/23 +144.79.70.0/23 +145.14.71.0/24 +145.14.72.0/22 +145.14.81.0/24 +145.14.82.0/24 +145.14.84.0/24 +145.14.86.0/24 +145.14.88.0/24 +145.14.90.0/24 +146.19.167.0/24 +146.19.236.0/24 +146.196.112.0/21 +146.196.56.0/22 +146.196.68.0/22 +146.222.79.0/24 +146.222.81.0/24 +146.222.94.0/24 +146.56.192.0/18 +147.78.132.0/22 +148.70.0.0/16 +150.129.136.0/22 +150.129.192.0/22 +150.129.252.0/22 +150.138.0.0/15 +150.158.0.0/16 +150.223.0.0/16 +150.242.120.0/22 +150.242.156.0/23 +150.242.168.0/22 +150.242.184.0/22 +150.242.232.0/22 +150.242.238.0/23 +150.242.244.0/22 +150.242.248.0/22 +150.242.56.0/22 +150.242.76.0/22 +150.242.80.0/22 +150.242.96.0/22 +150.255.0.0/16 +151.247.148.0/23 +152.104.128.0/17 +152.136.0.0/16 +153.0.0.0/16 +153.101.0.0/16 +153.118.0.0/15 +153.3.0.0/16 +153.34.0.0/15 +153.36.0.0/15 +153.99.0.0/16 +154.72.42.0/24 +154.72.44.0/24 +154.72.47.0/24 +154.8.128.0/17 +154.91.158.0/23 +155.102.0.0/23 +155.102.100.0/23 +155.102.110.0/23 +155.102.112.0/21 +155.102.120.0/23 +155.102.127.0/24 +155.102.128.0/22 +155.102.132.0/23 +155.102.135.0/24 +155.102.136.0/21 +155.102.144.0/20 +155.102.16.0/22 +155.102.160.0/21 +155.102.168.0/23 +155.102.171.0/24 +155.102.173.0/24 +155.102.174.0/23 +155.102.176.0/21 +155.102.184.0/23 +155.102.193.0/24 +155.102.194.0/23 +155.102.196.0/23 +155.102.198.0/24 +155.102.2.0/24 +155.102.20.0/24 +155.102.201.0/24 +155.102.202.0/24 +155.102.204.0/22 +155.102.208.0/21 +155.102.216.0/22 +155.102.22.0/23 +155.102.220.0/23 +155.102.223.0/24 +155.102.224.0/19 +155.102.24.0/24 +155.102.26.0/23 +155.102.28.0/22 +155.102.32.0/21 +155.102.4.0/23 +155.102.40.0/23 +155.102.43.0/24 +155.102.44.0/22 +155.102.48.0/20 +155.102.65.0/24 +155.102.67.0/24 +155.102.68.0/23 +155.102.70.0/24 +155.102.74.0/23 +155.102.76.0/22 +155.102.8.0/21 +155.102.98.0/23 +155.126.176.0/23 +156.107.160.0/23 +156.107.170.0/24 +156.107.179.0/24 +156.107.181.0/24 +156.237.104.0/23 +156.242.5.0/24 +156.59.108.0/24 +157.0.0.0/16 +157.10.112.0/23 +157.10.34.0/23 +157.119.172.0/22 +157.119.252.0/22 +157.119.28.0/22 +157.122.0.0/16 +157.148.0.0/16 +157.15.104.0/23 +157.15.94.0/23 +157.156.0.0/16 +157.18.0.0/16 +157.20.246.0/23 +157.254.231.0/24 +157.255.0.0/16 +157.61.0.0/16 +157.66.164.0/23 +158.140.252.0/22 +159.226.0.0/16 +159.27.0.0/16 +159.75.0.0/16 +16.2.142.0/23 +160.19.208.0/23 +160.19.210.0/24 +160.19.76.0/23 +160.191.0.0/24 +160.20.18.0/23 +160.202.152.0/22 +160.202.212.0/22 +160.202.224.0/19 +160.22.188.0/24 +160.22.244.0/23 +160.25.194.0/23 +160.250.102.0/23 +160.250.14.0/23 +160.250.84.0/23 +160.30.230.0/23 +160.83.110.0/24 +161.163.0.0/21 +161.163.28.0/23 +161.189.0.0/16 +161.207.0.0/16 +162.105.0.0/16 +162.128.248.0/24 +162.14.0.0/16 +163.0.0.0/16 +163.125.0.0/16 +163.142.0.0/16 +163.177.0.0/16 +163.179.0.0/16 +163.181.0.0/23 +163.181.100.0/22 +163.181.104.0/22 +163.181.108.0/24 +163.181.110.0/23 +163.181.112.0/23 +163.181.116.0/23 +163.181.118.0/24 +163.181.120.0/22 +163.181.126.0/23 +163.181.128.0/23 +163.181.131.0/24 +163.181.132.0/23 +163.181.135.0/24 +163.181.136.0/21 +163.181.144.0/20 +163.181.15.0/24 +163.181.16.0/22 +163.181.160.0/24 +163.181.162.0/23 +163.181.164.0/22 +163.181.168.0/21 +163.181.176.0/21 +163.181.184.0/22 +163.181.188.0/24 +163.181.190.0/23 +163.181.192.0/23 +163.181.196.0/22 +163.181.2.0/24 +163.181.200.0/21 +163.181.209.0/24 +163.181.210.0/23 +163.181.212.0/22 +163.181.216.0/21 +163.181.22.0/23 +163.181.224.0/23 +163.181.228.0/22 +163.181.232.0/23 +163.181.234.0/24 +163.181.236.0/22 +163.181.241.0/24 +163.181.242.0/23 +163.181.244.0/22 +163.181.248.0/21 +163.181.25.0/24 +163.181.26.0/24 +163.181.32.0/21 +163.181.40.0/24 +163.181.42.0/24 +163.181.44.0/22 +163.181.48.0/21 +163.181.56.0/22 +163.181.60.0/23 +163.181.63.0/24 +163.181.66.0/23 +163.181.69.0/24 +163.181.71.0/24 +163.181.72.0/23 +163.181.74.0/24 +163.181.77.0/24 +163.181.78.0/23 +163.181.80.0/22 +163.181.85.0/24 +163.181.87.0/24 +163.181.88.0/23 +163.181.90.0/24 +163.181.92.0/24 +163.181.94.0/23 +163.181.97.0/24 +163.181.99.0/24 +163.204.0.0/16 +163.223.178.0/23 +163.227.40.0/23 +163.228.0.0/16 +163.244.246.0/24 +163.47.4.0/22 +163.5.166.0/24 +163.5.53.0/24 +163.5.79.0/24 +163.53.128.0/22 +163.53.168.0/22 +163.53.44.0/22 +163.53.60.0/22 +163.53.88.0/21 +163.61.178.0/23 +163.61.202.0/23 +163.61.214.0/23 +165.101.208.0/23 +165.101.70.0/24 +166.111.0.0/16 +167.139.0.0/16 +167.189.0.0/16 +167.220.244.0/22 +168.160.0.0/17 +168.160.152.0/24 +168.160.158.0/23 +168.160.160.0/21 +168.160.168.0/24 +168.160.224.0/19 +170.33.98.0/24 +171.104.0.0/13 +171.112.0.0/12 +171.208.0.0/12 +171.34.0.0/15 +171.36.0.0/14 +171.40.0.0/14 +171.44.0.0/16 +171.8.0.0/13 +171.80.0.0/12 +172.81.192.0/18 +174.136.239.0/24 +175.0.0.0/12 +175.102.0.0/19 +175.102.128.0/20 +175.102.144.0/21 +175.102.152.0/24 +175.102.178.0/23 +175.102.180.0/22 +175.102.184.0/22 +175.102.188.0/23 +175.102.190.0/24 +175.102.196.0/24 +175.146.0.0/15 +175.148.0.0/14 +175.152.0.0/14 +175.16.0.0/13 +175.160.0.0/12 +175.178.0.0/16 +175.184.128.0/18 +175.185.0.0/16 +175.186.0.0/15 +175.188.188.0/22 +175.190.126.0/23 +175.190.24.0/21 +175.24.0.0/15 +175.27.0.0/16 +175.30.0.0/15 +175.42.0.0/15 +175.44.0.0/16 +175.46.0.0/15 +178.219.5.0/24 +180.129.128.0/17 +180.130.0.0/16 +180.136.0.0/13 +180.149.128.0/19 +180.150.176.0/20 +180.152.0.0/13 +180.160.0.0/12 +180.178.208.0/20 +180.178.224.0/21 +180.178.232.0/22 +180.178.248.0/21 +180.184.0.0/21 +180.184.128.0/20 +180.184.14.0/24 +180.184.144.0/21 +180.184.152.0/22 +180.184.16.0/24 +180.184.160.0/20 +180.184.176.0/21 +180.184.184.0/22 +180.184.190.0/23 +180.184.192.0/18 +180.184.24.0/21 +180.184.32.0/19 +180.184.64.0/18 +180.184.8.0/23 +180.186.38.0/23 +180.186.40.0/22 +180.186.44.0/24 +180.188.16.0/20 +180.188.32.0/20 +180.200.252.0/22 +180.201.0.0/16 +180.203.0.0/22 +180.203.4.0/24 +180.208.0.0/15 +180.210.212.0/22 +180.212.0.0/15 +180.233.0.0/18 +180.235.64.0/21 +180.235.72.0/23 +180.76.128.0/17 +180.76.16.0/20 +180.76.32.0/19 +180.76.64.0/18 +180.77.0.0/16 +180.78.0.0/15 +180.84.0.0/15 +180.88.128.0/18 +180.88.96.0/19 +180.89.56.0/22 +180.89.60.0/23 +180.89.64.0/19 +180.91.192.0/20 +180.95.128.0/17 +180.96.0.0/11 +182.128.0.0/12 +182.144.0.0/13 +182.157.0.0/16 +182.174.0.0/15 +182.18.32.0/19 +182.18.5.0/24 +182.18.72.0/21 +182.18.80.0/20 +182.18.96.0/19 +182.200.0.0/13 +182.240.0.0/13 +182.254.0.0/16 +182.32.0.0/12 +182.48.112.0/21 +182.48.96.0/20 +182.50.112.0/20 +182.50.8.0/21 +182.51.114.0/23 +182.51.116.0/23 +182.51.118.0/24 +182.51.122.0/23 +182.51.124.0/24 +182.54.0.0/17 +182.61.0.0/18 +182.61.128.0/19 +182.61.192.0/22 +182.61.200.0/21 +182.61.208.0/20 +182.61.224.0/19 +182.80.0.0/13 +182.88.0.0/14 +182.92.0.0/16 +182.96.0.0/11 +183.0.0.0/10 +183.128.0.0/11 +183.160.0.0/13 +183.168.0.0/15 +183.170.0.0/16 +183.172.0.0/14 +183.184.0.0/13 +183.192.0.0/10 +183.64.0.0/13 +183.78.180.0/22 +183.81.180.0/22 +183.84.0.0/15 +183.91.144.0/20 +183.91.39.0/24 +183.91.40.0/21 +183.91.48.0/21 +183.91.56.0/24 +183.91.61.0/24 +183.91.63.0/24 +183.92.0.0/14 +185.39.51.0/24 +185.75.173.0/24 +185.75.174.0/24 +188.131.128.0/17 +192.140.160.0/19 +192.140.208.0/21 +192.144.128.0/17 +192.163.11.0/24 +192.232.97.0/24 +193.112.0.0/16 +193.233.49.0/24 +194.127.229.0/24 +194.138.202.0/23 +194.138.245.0/24 +194.231.140.0/24 +198.208.112.0/23 +198.208.17.0/24 +198.208.19.0/24 +198.208.30.0/24 +198.208.61.0/24 +198.208.63.0/24 +198.208.67.0/24 +198.23.195.0/24 +199.182.239.0/24 +199.244.144.0/24 +202.104.0.0/14 +202.108.0.0/15 +202.110.0.0/16 +202.111.0.0/17 +202.111.128.0/18 +202.111.192.0/19 +202.111.230.0/24 +202.111.240.0/23 +202.111.242.0/24 +202.111.244.0/22 +202.111.248.0/24 +202.112.0.0/13 +202.120.0.0/15 +202.122.112.0/21 +202.122.32.0/21 +202.123.106.0/23 +202.123.108.0/24 +202.123.110.0/23 +202.123.120.0/22 +202.123.96.0/24 +202.123.98.0/24 +202.125.176.0/20 +202.127.0.0/21 +202.127.12.0/22 +202.127.144.0/20 +202.127.16.0/20 +202.127.200.0/21 +202.127.216.0/21 +202.127.224.0/19 +202.127.40.0/21 +202.127.48.0/23 +202.130.0.0/19 +202.130.224.0/20 +202.130.240.0/21 +202.136.208.0/21 +202.136.216.0/23 +202.136.218.0/24 +202.136.220.0/24 +202.136.222.0/23 +202.136.255.0/24 +202.136.48.0/20 +202.136.72.0/23 +202.14.235.0/24 +202.14.236.0/23 +202.14.238.0/24 +202.140.140.0/22 +202.141.160.0/19 +202.142.16.0/20 +202.143.100.0/22 +202.143.16.0/23 +202.148.96.0/19 +202.149.224.0/19 +202.150.16.0/20 +202.153.48.0/20 +202.158.160.0/19 +202.160.140.0/22 +202.164.0.0/20 +202.168.160.0/19 +202.170.128.0/19 +202.170.216.0/21 +202.173.14.0/23 +202.173.224.0/19 +202.173.8.0/22 +202.179.240.0/20 +202.181.120.0/21 +202.181.28.0/24 +202.189.16.0/20 +202.189.3.0/24 +202.189.32.0/20 +202.189.4.0/22 +202.189.48.0/22 +202.189.8.0/21 +202.192.0.0/12 +202.38.128.0/23 +202.38.132.0/23 +202.38.134.0/24 +202.38.140.0/23 +202.38.146.0/23 +202.38.152.0/23 +202.38.164.0/22 +202.38.184.0/21 +202.38.192.0/18 +202.38.2.0/23 +202.38.64.0/18 +202.38.8.0/21 +202.4.128.0/19 +202.4.252.0/22 +202.41.152.0/21 +202.41.241.0/24 +202.41.242.0/23 +202.41.244.0/22 +202.41.248.0/21 +202.46.224.0/22 +202.46.228.0/23 +202.46.232.0/23 +202.47.104.0/21 +202.55.0.0/19 +202.57.192.0/24 +202.57.196.0/22 +202.57.200.0/23 +202.57.204.0/23 +202.59.213.0/24 +202.59.214.0/23 +202.6.202.0/23 +202.60.112.0/20 +202.60.132.0/22 +202.61.88.0/22 +202.62.112.0/22 +202.63.160.0/20 +202.65.96.0/24 +202.67.3.0/24 +202.69.16.0/20 +202.69.4.0/23 +202.72.112.0/20 +202.73.128.0/22 +202.73.240.0/20 +202.75.208.0/20 +202.75.252.0/22 +202.80.192.0/22 +202.81.176.0/20 +202.84.17.0/24 +202.85.208.0/20 +202.89.232.0/21 +202.89.96.0/22 +202.90.20.0/22 +202.90.96.0/20 +202.91.176.0/21 +202.91.184.0/23 +202.91.186.0/24 +202.91.190.0/23 +202.91.224.0/20 +202.91.240.0/21 +202.91.248.0/22 +202.93.252.0/22 +202.95.0.0/19 +202.96.0.0/13 +203.0.104.0/21 +203.100.192.0/20 +203.100.92.0/22 +203.104.32.0/20 +203.107.1.0/24 +203.107.116.0/22 +203.107.13.0/24 +203.107.2.0/24 +203.107.20.0/22 +203.107.24.0/24 +203.107.26.0/23 +203.107.28.0/22 +203.107.32.0/19 +203.107.6.0/24 +203.107.72.0/21 +203.107.80.0/21 +203.107.96.0/23 +203.110.160.0/19 +203.110.208.0/20 +203.110.232.0/23 +203.110.234.0/24 +203.114.244.0/22 +203.118.248.0/22 +203.119.114.0/23 +203.119.128.0/19 +203.119.160.0/24 +203.119.168.0/21 +203.119.176.0/20 +203.119.192.0/18 +203.119.25.0/24 +203.119.26.0/23 +203.119.28.0/22 +203.119.33.0/24 +203.119.80.0/23 +203.119.83.0/24 +203.12.91.0/24 +203.12.93.0/24 +203.129.12.0/22 +203.13.81.0/24 +203.130.32.0/22 +203.130.40.0/21 +203.132.32.0/19 +203.135.96.0/19 +203.148.0.0/18 +203.148.64.0/20 +203.148.86.0/23 +203.15.0.0/20 +203.152.64.0/19 +203.156.192.0/18 +203.160.129.0/24 +203.160.192.0/19 +203.161.192.0/19 +203.166.160.0/22 +203.166.165.0/24 +203.166.166.0/24 +203.166.172.0/24 +203.166.177.0/24 +203.166.186.0/23 +203.166.188.0/23 +203.166.191.0/24 +203.168.0.0/19 +203.170.58.0/23 +203.174.4.0/24 +203.174.96.0/19 +203.175.128.0/19 +203.176.168.0/24 +203.176.170.0/24 +203.176.92.0/22 +203.187.160.0/19 +203.189.0.0/23 +203.189.113.0/24 +203.189.115.0/24 +203.189.192.0/19 +203.189.240.0/22 +203.189.6.0/23 +203.190.100.0/23 +203.191.0.0/23 +203.191.144.0/21 +203.192.1.0/24 +203.192.16.0/24 +203.192.2.0/23 +203.192.24.0/23 +203.192.4.0/22 +203.192.8.0/21 +203.193.224.0/19 +203.194.122.0/23 +203.194.124.0/24 +203.195.113.0/24 +203.195.114.0/24 +203.195.118.0/23 +203.195.128.0/17 +203.195.64.0/19 +203.196.0.0/21 +203.2.112.0/21 +203.2.160.0/21 +203.2.64.0/21 +203.202.236.0/23 +203.207.104.0/22 +203.207.112.0/20 +203.207.128.0/18 +203.207.192.0/21 +203.207.200.0/22 +203.207.208.0/20 +203.207.224.0/19 +203.207.64.0/19 +203.207.96.0/21 +203.208.32.0/19 +203.209.224.0/19 +203.212.0.0/20 +203.212.80.0/23 +203.215.232.0/23 +203.215.236.0/24 +203.223.21.0/24 +203.25.208.0/20 +203.25.52.0/24 +203.3.112.0/21 +203.3.80.0/21 +203.32.203.0/24 +203.32.204.0/23 +203.32.212.0/24 +203.32.48.0/23 +203.32.68.0/23 +203.32.84.0/23 +203.33.145.0/24 +203.33.156.0/24 +203.33.158.0/23 +203.33.174.0/24 +203.33.185.0/24 +203.33.200.0/24 +203.33.202.0/23 +203.33.206.0/23 +203.33.21.0/24 +203.33.214.0/23 +203.33.224.0/23 +203.33.226.0/24 +203.33.26.0/24 +203.33.32.0/24 +203.33.4.0/24 +203.33.63.0/24 +203.33.64.0/24 +203.33.67.0/24 +203.33.7.0/24 +203.34.106.0/24 +203.34.113.0/24 +203.34.147.0/24 +203.34.150.0/24 +203.34.152.0/23 +203.34.161.0/24 +203.34.162.0/24 +203.34.21.0/24 +203.34.232.0/24 +203.34.240.0/24 +203.34.242.0/24 +203.34.245.0/24 +203.34.251.0/24 +203.34.27.0/24 +203.34.39.0/24 +203.34.48.0/23 +203.34.54.0/24 +203.34.56.0/23 +203.34.67.0/24 +203.34.69.0/24 +203.34.76.0/24 +203.34.92.0/24 +203.55.10.0/24 +203.55.101.0/24 +203.55.109.0/24 +203.55.110.0/24 +203.55.116.0/23 +203.55.119.0/24 +203.55.128.0/23 +203.55.13.0/24 +203.55.146.0/23 +203.55.192.0/24 +203.55.196.0/24 +203.55.2.0/23 +203.55.218.0/23 +203.55.22.0/24 +203.55.221.0/24 +203.55.224.0/24 +203.55.30.0/24 +203.55.4.0/24 +203.55.93.0/24 +203.56.1.0/24 +203.56.110.0/24 +203.56.12.0/24 +203.56.121.0/24 +203.56.161.0/24 +203.56.169.0/24 +203.56.172.0/23 +203.56.175.0/24 +203.56.183.0/24 +203.56.185.0/24 +203.56.187.0/24 +203.56.192.0/24 +203.56.198.0/24 +203.56.201.0/24 +203.56.208.0/23 +203.56.210.0/24 +203.56.214.0/24 +203.56.216.0/24 +203.56.228.0/24 +203.56.232.0/24 +203.56.24.0/24 +203.56.240.0/24 +203.56.252.0/24 +203.56.254.0/24 +203.56.38.0/24 +203.56.4.0/24 +203.56.40.0/24 +203.56.46.0/24 +203.56.68.0/23 +203.56.82.0/23 +203.56.84.0/23 +203.56.95.0/24 +203.57.101.0/24 +203.57.109.0/24 +203.57.12.0/23 +203.57.123.0/24 +203.57.157.0/24 +203.57.200.0/24 +203.57.202.0/24 +203.57.206.0/24 +203.57.222.0/24 +203.57.224.0/20 +203.57.249.0/24 +203.57.254.0/23 +203.57.28.0/24 +203.57.39.0/24 +203.57.46.0/24 +203.57.5.0/24 +203.57.58.0/24 +203.57.6.0/24 +203.57.61.0/24 +203.57.66.0/24 +203.57.69.0/24 +203.57.70.0/23 +203.57.73.0/24 +203.57.90.0/24 +203.6.224.0/20 +203.62.131.0/24 +203.62.139.0/24 +203.62.2.0/24 +203.65.240.0/22 +203.76.208.0/21 +203.76.216.0/22 +203.76.240.0/22 +203.78.48.0/20 +203.79.0.0/23 +203.8.25.0/24 +203.8.30.0/24 +203.80.144.0/20 +203.80.57.0/24 +203.82.0.0/23 +203.83.224.0/20 +203.83.56.0/21 +203.86.0.0/19 +203.86.112.0/24 +203.86.254.0/23 +203.86.43.0/24 +203.86.44.0/23 +203.86.48.0/23 +203.86.51.0/24 +203.86.52.0/22 +203.86.60.0/23 +203.86.62.0/24 +203.86.64.0/19 +203.88.192.0/19 +203.88.32.0/19 +203.90.128.0/18 +203.90.192.0/19 +203.91.120.0/21 +203.91.32.0/19 +203.93.0.0/18 +203.93.117.0/24 +203.93.120.0/21 +203.93.128.0/19 +203.93.160.0/20 +203.93.208.0/20 +203.93.224.0/19 +203.93.64.0/19 +203.93.96.0/20 +203.94.0.0/19 +203.95.0.0/23 +203.95.128.0/23 +203.95.2.0/24 +203.95.4.0/22 +203.99.20.0/22 +203.99.24.0/21 +204.14.76.0/24 +204.235.241.0/24 +206.109.75.0/24 +210.12.0.0/16 +210.13.0.0/17 +210.13.192.0/19 +210.13.224.0/24 +210.13.227.0/24 +210.13.230.0/23 +210.13.232.0/24 +210.13.236.0/23 +210.13.238.0/24 +210.13.240.0/20 +210.14.112.0/20 +210.14.128.0/19 +210.14.192.0/18 +210.14.64.0/20 +210.14.80.0/22 +210.14.84.0/24 +210.14.90.0/23 +210.14.92.0/22 +210.15.0.0/17 +210.16.160.0/19 +210.185.192.0/18 +210.192.116.0/22 +210.192.120.0/21 +210.192.96.0/20 +210.2.0.0/23 +210.2.4.0/24 +210.21.0.0/17 +210.21.192.0/18 +210.22.0.0/19 +210.22.128.0/17 +210.22.32.0/22 +210.22.48.0/20 +210.22.64.0/18 +210.25.0.0/16 +210.26.0.0/15 +210.28.0.0/14 +210.32.0.0/12 +210.48.136.0/21 +210.5.0.0/19 +210.5.128.0/19 +210.5.56.0/21 +210.51.0.0/16 +210.52.0.0/15 +210.72.0.0/17 +210.72.128.0/18 +210.72.192.0/19 +210.72.224.0/20 +210.72.240.0/21 +210.73.0.0/17 +210.73.128.0/18 +210.73.192.0/22 +210.73.204.0/24 +210.73.208.0/20 +210.73.224.0/19 +210.74.0.0/20 +210.74.107.0/24 +210.74.108.0/23 +210.74.128.0/18 +210.74.224.0/19 +210.74.35.0/24 +210.74.36.0/23 +210.74.38.0/24 +210.74.40.0/22 +210.74.44.0/23 +210.74.47.0/24 +210.74.64.0/23 +210.75.0.0/18 +210.75.192.0/18 +210.75.96.0/19 +210.76.0.0/18 +210.76.160.0/19 +210.76.192.0/19 +210.76.64.0/19 +210.77.0.0/18 +210.77.128.0/19 +210.77.176.0/20 +210.77.192.0/18 +210.77.64.0/19 +210.78.128.0/24 +210.78.134.0/23 +210.78.139.0/24 +210.78.144.0/23 +210.79.224.0/19 +210.82.0.0/15 +210.87.128.0/18 +211.100.0.0/17 +211.100.192.0/20 +211.100.224.0/19 +211.101.0.0/18 +211.101.192.0/20 +211.101.232.0/21 +211.101.240.0/21 +211.102.128.0/18 +211.102.192.0/23 +211.102.208.0/20 +211.102.240.0/21 +211.102.248.0/24 +211.102.80.0/20 +211.103.0.0/16 +211.136.0.0/13 +211.144.10.0/24 +211.144.100.0/22 +211.144.104.0/22 +211.144.108.0/23 +211.144.110.0/24 +211.144.112.0/24 +211.144.114.0/23 +211.144.118.0/23 +211.144.12.0/22 +211.144.120.0/21 +211.144.128.0/19 +211.144.16.0/24 +211.144.18.0/23 +211.144.192.0/18 +211.144.20.0/24 +211.144.22.0/24 +211.144.24.0/24 +211.144.27.0/24 +211.144.28.0/23 +211.144.32.0/19 +211.144.64.0/19 +211.144.9.0/24 +211.144.96.0/23 +211.145.0.0/18 +211.145.64.0/20 +211.146.0.0/16 +211.147.0.0/18 +211.147.128.0/18 +211.147.208.0/20 +211.147.224.0/19 +211.147.64.0/19 +211.148.0.0/18 +211.148.128.0/17 +211.149.128.0/17 +211.150.0.0/18 +211.150.100.0/23 +211.150.114.0/23 +211.150.122.0/24 +211.150.124.0/23 +211.150.128.0/24 +211.150.64.0/19 +211.150.98.0/24 +211.151.0.0/16 +211.152.0.0/17 +211.152.192.0/22 +211.152.196.0/23 +211.152.208.0/20 +211.153.0.0/16 +211.154.0.0/19 +211.154.128.0/17 +211.154.64.0/19 +211.155.108.0/22 +211.155.112.0/20 +211.155.128.0/19 +211.155.16.0/20 +211.155.160.0/20 +211.155.176.0/22 +211.155.184.0/21 +211.155.224.0/21 +211.155.232.0/22 +211.155.236.0/24 +211.155.240.0/20 +211.155.32.0/19 +211.155.80.0/20 +211.156.0.0/19 +211.156.128.0/19 +211.156.176.0/20 +211.156.192.0/20 +211.156.208.0/21 +211.156.216.0/22 +211.156.220.0/23 +211.156.223.0/24 +211.157.0.0/19 +211.157.128.0/18 +211.157.192.0/20 +211.157.219.0/24 +211.157.222.0/24 +211.157.224.0/19 +211.157.96.0/19 +211.158.0.0/16 +211.159.128.0/17 +211.159.64.0/21 +211.160.0.0/22 +211.160.112.0/23 +211.160.115.0/24 +211.160.120.0/24 +211.160.14.0/23 +211.160.16.0/21 +211.160.160.0/19 +211.160.194.0/23 +211.160.196.0/24 +211.160.202.0/23 +211.160.204.0/23 +211.160.24.0/22 +211.160.240.0/20 +211.160.28.0/23 +211.160.36.0/23 +211.160.4.0/23 +211.160.46.0/23 +211.160.62.0/23 +211.160.72.0/21 +211.160.8.0/22 +211.160.80.0/20 +211.161.0.0/20 +211.161.101.0/24 +211.161.102.0/23 +211.161.120.0/21 +211.161.192.0/22 +211.161.203.0/24 +211.161.209.0/24 +211.161.221.0/24 +211.161.224.0/20 +211.161.24.0/22 +211.161.32.0/20 +211.161.60.0/23 +211.161.62.0/24 +211.161.97.0/24 +211.162.0.0/21 +211.162.119.0/24 +211.162.120.0/21 +211.162.200.0/22 +211.162.64.0/20 +211.165.0.0/16 +211.166.0.0/16 +211.167.128.0/19 +211.167.176.0/20 +211.167.224.0/19 +211.167.64.0/18 +211.64.0.0/13 +211.80.0.0/13 +211.88.0.0/15 +211.90.0.0/17 +211.90.128.0/18 +211.90.192.0/20 +211.90.216.0/21 +211.90.224.0/19 +211.91.0.0/18 +211.91.120.0/21 +211.91.128.0/18 +211.91.216.0/21 +211.91.224.0/19 +211.91.64.0/19 +211.91.96.0/20 +211.92.0.0/17 +211.92.128.0/18 +211.92.192.0/19 +211.92.224.0/20 +211.92.244.0/22 +211.93.0.0/17 +211.93.128.0/20 +211.93.144.0/21 +211.93.160.0/19 +211.93.192.0/21 +211.93.200.0/23 +211.93.204.0/22 +211.93.211.0/24 +211.93.212.0/23 +211.93.224.0/19 +211.94.128.0/17 +211.94.37.0/24 +211.94.64.0/18 +211.95.0.0/17 +211.95.128.0/19 +211.95.192.0/18 +211.96.0.0/16 +211.97.0.0/17 +211.97.128.0/19 +211.97.160.0/21 +211.97.176.0/20 +211.97.192.0/18 +211.98.0.0/16 +211.99.128.0/18 +211.99.16.0/23 +211.99.192.0/19 +211.99.24.0/21 +211.99.32.0/19 +211.99.64.0/18 +211.99.8.0/21 +212.129.128.0/17 +212.64.0.0/17 +218.0.0.0/11 +218.100.88.0/21 +218.104.0.0/15 +218.106.0.0/16 +218.107.0.0/18 +218.107.128.0/17 +218.108.0.0/15 +218.185.240.0/21 +218.192.0.0/12 +218.240.0.0/18 +218.240.128.0/19 +218.240.160.0/21 +218.240.168.0/22 +218.240.176.0/20 +218.241.112.0/22 +218.241.116.0/23 +218.241.118.0/24 +218.241.121.0/24 +218.241.122.0/23 +218.241.124.0/22 +218.241.128.0/17 +218.241.16.0/21 +218.241.24.0/22 +218.241.96.0/20 +218.242.0.0/16 +218.244.0.0/19 +218.244.128.0/18 +218.244.192.0/20 +218.244.224.0/19 +218.244.44.0/22 +218.244.49.0/24 +218.244.52.0/23 +218.244.55.0/24 +218.244.56.0/23 +218.244.58.0/24 +218.245.0.0/17 +218.246.0.0/19 +218.246.160.0/19 +218.246.192.0/19 +218.246.32.0/22 +218.246.48.0/22 +218.246.64.0/18 +218.247.0.0/18 +218.247.128.0/17 +218.249.0.0/16 +218.56.0.0/13 +218.64.0.0/11 +218.96.0.0/24 +218.96.104.0/22 +218.96.108.0/23 +218.96.126.0/23 +218.96.128.0/24 +218.96.241.0/24 +218.96.244.0/24 +218.96.255.0/24 +218.96.64.0/22 +218.97.0.0/17 +218.97.160.0/19 +218.97.192.0/19 +218.97.240.0/20 +218.98.0.0/18 +218.98.104.0/22 +218.98.108.0/23 +218.98.111.0/24 +218.98.112.0/20 +218.98.160.0/24 +218.98.176.0/21 +218.98.192.0/24 +218.98.96.0/21 +219.128.0.0/12 +219.144.0.0/14 +219.148.0.0/15 +219.150.0.0/16 +219.151.0.0/18 +219.151.128.0/17 +219.152.0.0/14 +219.156.0.0/15 +219.158.0.0/19 +219.158.128.0/17 +219.158.32.0/20 +219.158.58.0/23 +219.158.60.0/22 +219.158.96.0/19 +219.159.0.0/16 +219.216.0.0/13 +219.224.0.0/13 +219.232.0.0/17 +219.232.144.0/24 +219.232.160.0/19 +219.232.192.0/19 +219.233.0.0/16 +219.234.128.0/17 +219.234.80.0/20 +219.234.96.0/19 +219.235.0.0/20 +219.235.128.0/19 +219.235.192.0/23 +219.235.207.0/24 +219.235.224.0/22 +219.235.228.0/23 +219.235.233.0/24 +219.235.234.0/24 +219.235.237.0/24 +219.235.251.0/24 +219.235.252.0/24 +219.235.255.0/24 +219.235.32.0/19 +219.235.64.0/18 +219.236.0.0/14 +219.242.0.0/15 +219.244.0.0/14 +219.72.0.0/16 +219.82.0.0/16 +219.83.160.0/19 +220.101.192.0/18 +220.112.0.0/22 +220.112.194.0/24 +220.112.196.0/24 +220.112.200.0/21 +220.112.40.0/21 +220.112.50.0/23 +220.112.52.0/23 +220.112.54.0/24 +220.112.8.0/24 +220.113.0.0/19 +220.113.150.0/23 +220.113.152.0/23 +220.113.154.0/24 +220.113.32.0/20 +220.113.96.0/21 +220.114.250.0/23 +220.154.0.0/20 +220.154.128.0/20 +220.154.147.0/24 +220.154.16.0/22 +220.154.64.0/20 +220.154.80.0/22 +220.160.0.0/12 +220.176.0.0/14 +220.180.0.0/16 +220.181.0.0/17 +220.181.128.0/20 +220.181.144.0/24 +220.181.148.0/22 +220.181.152.0/21 +220.181.160.0/19 +220.182.0.0/18 +220.184.0.0/13 +220.192.0.0/16 +220.193.0.0/17 +220.194.0.0/16 +220.195.0.0/17 +220.195.128.0/19 +220.195.192.0/18 +220.196.0.0/16 +220.197.0.0/17 +220.197.160.0/19 +220.197.192.0/18 +220.198.0.0/15 +220.200.0.0/17 +220.200.128.0/20 +220.200.148.0/22 +220.200.152.0/21 +220.200.160.0/19 +220.200.192.0/18 +220.201.0.0/16 +220.202.0.0/16 +220.203.0.0/17 +220.203.128.0/18 +220.203.216.0/23 +220.203.220.0/22 +220.203.224.0/19 +220.205.0.0/16 +220.206.192.0/22 +220.207.0.0/22 +220.207.176.0/22 +220.207.184.0/22 +220.207.254.0/23 +220.207.80.0/20 +220.231.0.0/18 +220.231.128.0/17 +220.232.64.0/18 +220.234.0.0/16 +220.242.180.0/24 +220.243.128.0/18 +220.248.0.0/16 +220.249.0.0/17 +220.249.128.0/18 +220.249.192.0/19 +220.249.240.0/20 +220.250.0.0/17 +221.0.0.0/13 +221.12.0.0/17 +221.12.128.0/18 +221.122.0.0/16 +221.123.0.0/24 +221.123.112.0/20 +221.123.128.0/17 +221.129.0.0/16 +221.13.0.0/16 +221.130.0.0/15 +221.133.225.0/24 +221.133.226.0/24 +221.133.228.0/22 +221.133.232.0/23 +221.133.235.0/24 +221.133.244.0/23 +221.137.0.0/16 +221.14.0.0/15 +221.172.0.0/16 +221.174.0.0/16 +221.176.0.0/13 +221.192.0.0/14 +221.196.0.0/15 +221.198.0.0/16 +221.199.0.0/17 +221.199.128.0/18 +221.199.192.0/20 +221.199.224.0/19 +221.200.0.0/13 +221.208.0.0/12 +221.224.0.0/12 +221.8.0.0/14 +222.125.0.0/16 +222.126.128.0/17 +222.128.0.0/12 +222.16.0.0/12 +222.160.0.0/14 +222.168.0.0/13 +222.176.0.0/12 +222.192.0.0/11 +222.240.0.0/13 +222.248.0.0/15 +222.35.0.0/16 +222.42.115.0/24 +222.44.0.0/15 +222.49.128.0/17 +222.50.0.0/16 +222.59.128.0/17 +222.64.0.0/11 +223.0.1.0/24 +223.0.12.0/23 +223.0.126.0/24 +223.0.15.0/24 +223.0.16.0/24 +223.0.2.0/24 +223.0.30.0/24 +223.0.40.0/23 +223.0.8.0/22 +223.128.0.0/15 +223.144.0.0/12 +223.160.0.0/20 +223.160.112.0/20 +223.160.128.0/22 +223.160.134.0/23 +223.160.136.0/21 +223.160.144.0/20 +223.160.16.0/21 +223.160.160.0/19 +223.160.192.0/19 +223.160.224.0/21 +223.160.232.0/22 +223.160.236.0/23 +223.161.194.0/23 +223.161.196.0/22 +223.161.200.0/21 +223.161.208.0/20 +223.161.224.0/19 +223.166.0.0/15 +223.192.0.0/15 +223.198.0.0/15 +223.2.0.0/15 +223.202.0.0/24 +223.202.131.0/24 +223.202.132.0/24 +223.202.134.0/23 +223.202.211.0/24 +223.202.212.0/24 +223.202.67.0/24 +223.203.100.0/24 +223.203.3.0/24 +223.203.9.0/24 +223.203.96.0/24 +223.210.0.0/19 +223.210.48.0/22 +223.212.0.0/14 +223.220.0.0/15 +223.223.176.0/20 +223.223.192.0/20 +223.240.0.0/13 +223.248.0.0/14 +223.252.194.0/24 +223.252.199.0/24 +223.252.200.0/23 +223.252.202.0/24 +223.252.205.0/24 +223.252.209.0/24 +223.252.210.0/23 +223.252.212.0/24 +223.252.214.0/23 +223.252.221.0/24 +223.252.222.0/24 +223.255.236.0/22 +223.255.252.0/23 +223.27.184.0/22 +223.4.0.0/14 +223.64.0.0/10 +223.8.0.0/13 +23.161.8.0/24 +23.162.120.0/24 +23.26.67.0/24 +27.0.128.0/24 +27.0.130.0/23 +27.0.132.0/22 +27.0.160.0/21 +27.0.204.0/22 +27.0.208.0/21 +27.106.204.0/22 +27.109.124.0/22 +27.112.0.0/21 +27.115.0.0/17 +27.128.0.0/15 +27.144.0.0/16 +27.148.0.0/14 +27.152.0.0/13 +27.16.0.0/12 +27.184.0.0/13 +27.192.0.0/11 +27.224.0.0/14 +27.36.0.0/14 +27.40.0.0/13 +27.50.128.0/17 +27.8.0.0/13 +27.98.224.0/19 +31.56.124.0/24 +36.1.0.0/16 +36.112.0.0/15 +36.114.0.0/16 +36.128.0.0/10 +36.16.0.0/12 +36.192.0.0/16 +36.206.0.0/16 +36.212.0.0/15 +36.214.0.0/16 +36.221.0.0/17 +36.248.0.0/14 +36.255.116.0/22 +36.255.128.0/22 +36.255.164.0/24 +36.32.0.0/14 +36.36.0.0/16 +36.4.0.0/14 +36.40.0.0/13 +36.48.0.0/15 +36.50.226.0/24 +36.51.224.0/23 +36.51.226.0/24 +36.51.248.0/24 +36.51.253.0/24 +36.51.254.0/24 +36.56.0.0/13 +36.96.0.0/12 +38.105.24.0/24 +38.105.26.0/23 +38.105.28.0/22 +38.134.56.0/24 +38.134.58.0/23 +38.247.24.0/22 +38.247.32.0/23 +38.247.36.0/22 +38.84.220.0/24 +38.95.118.0/23 +38.95.121.0/24 +38.95.122.0/23 +38.95.124.0/22 +39.104.0.0/14 +39.108.0.0/16 +39.125.80.0/24 +39.128.0.0/10 +39.64.0.0/11 +39.96.0.0/13 +40.125.128.0/17 +40.126.64.0/18 +40.162.0.0/16 +40.72.0.0/15 +42.100.0.0/14 +42.120.0.0/15 +42.122.0.0/16 +42.123.64.0/18 +42.156.128.0/17 +42.157.128.0/21 +42.157.160.0/19 +42.157.192.0/21 +42.158.0.0/15 +42.176.0.0/13 +42.184.0.0/15 +42.186.0.0/16 +42.187.120.0/22 +42.187.128.0/17 +42.192.0.0/15 +42.194.12.0/24 +42.194.128.0/17 +42.199.240.0/22 +42.201.32.0/19 +42.201.64.0/21 +42.201.72.0/22 +42.201.76.0/23 +42.202.0.0/15 +42.224.0.0/12 +42.240.0.0/21 +42.240.12.0/23 +42.240.128.0/17 +42.240.16.0/23 +42.240.20.0/22 +42.240.48.0/24 +42.240.8.0/22 +42.242.0.0/15 +42.244.0.0/14 +42.248.0.0/15 +42.4.0.0/14 +42.48.0.0/15 +42.51.0.0/16 +42.52.0.0/14 +42.56.0.0/14 +42.62.0.0/17 +42.63.0.0/16 +42.80.0.0/15 +42.83.128.0/22 +42.83.132.0/23 +42.83.134.0/24 +42.83.144.0/22 +42.83.189.0/24 +42.83.190.0/24 +42.83.200.0/23 +42.84.0.0/14 +42.88.0.0/13 +42.96.128.0/17 +42.97.0.0/16 +42.99.0.0/18 +43.102.128.0/21 +43.102.136.0/22 +43.102.144.0/20 +43.109.0.0/22 +43.109.10.0/24 +43.109.100.0/23 +43.109.102.0/24 +43.109.105.0/24 +43.109.107.0/24 +43.109.111.0/24 +43.109.112.0/24 +43.109.114.0/23 +43.109.116.0/23 +43.109.12.0/22 +43.109.134.0/23 +43.109.16.0/22 +43.109.21.0/24 +43.109.22.0/24 +43.109.24.0/23 +43.109.26.0/24 +43.109.28.0/24 +43.109.30.0/23 +43.109.32.0/23 +43.109.34.0/24 +43.109.37.0/24 +43.109.38.0/23 +43.109.4.0/23 +43.109.40.0/22 +43.109.44.0/23 +43.109.46.0/24 +43.109.48.0/23 +43.109.51.0/24 +43.109.53.0/24 +43.109.54.0/23 +43.109.57.0/24 +43.109.58.0/23 +43.109.60.0/22 +43.109.64.0/22 +43.109.68.0/23 +43.109.7.0/24 +43.109.70.0/24 +43.109.72.0/23 +43.109.76.0/22 +43.109.8.0/23 +43.109.83.0/24 +43.109.84.0/22 +43.109.88.0/22 +43.109.93.0/24 +43.109.94.0/24 +43.109.96.0/23 +43.136.0.0/13 +43.144.0.0/15 +43.176.0.0/14 +43.180.0.0/16 +43.192.0.0/16 +43.193.0.0/18 +43.193.64.0/23 +43.194.0.0/20 +43.194.16.0/24 +43.195.0.0/20 +43.196.0.0/16 +43.224.12.0/22 +43.224.24.0/22 +43.224.240.0/24 +43.224.52.0/23 +43.224.56.0/22 +43.224.80.0/22 +43.225.120.0/22 +43.225.180.0/22 +43.225.208.0/22 +43.225.216.0/22 +43.225.255.0/24 +43.225.76.0/22 +43.225.84.0/23 +43.225.87.0/24 +43.226.112.0/21 +43.226.128.0/19 +43.226.164.0/22 +43.226.236.0/22 +43.226.32.0/19 +43.226.64.0/20 +43.227.104.0/22 +43.227.140.0/22 +43.227.152.0/21 +43.227.160.0/20 +43.227.176.0/21 +43.227.192.0/19 +43.227.252.0/22 +43.227.56.0/21 +43.227.64.0/21 +43.227.80.0/20 +43.228.0.0/19 +43.228.116.0/22 +43.228.204.0/22 +43.228.240.0/22 +43.228.36.0/22 +43.228.40.0/21 +43.228.48.0/20 +43.228.64.0/21 +43.228.76.0/22 +43.229.184.0/22 +43.229.216.0/22 +43.229.48.0/22 +43.230.221.0/24 +43.230.222.0/23 +43.230.72.0/22 +43.231.144.0/20 +43.231.160.0/21 +43.231.168.0/22 +43.231.32.0/22 +43.231.41.0/24 +43.231.46.0/23 +43.231.96.0/20 +43.239.120.0/22 +43.239.172.0/24 +43.240.0.0/22 +43.240.124.0/22 +43.240.128.0/22 +43.240.133.0/24 +43.240.136.0/22 +43.240.156.0/22 +43.240.192.0/21 +43.240.200.0/23 +43.240.202.0/24 +43.240.204.0/22 +43.240.216.0/21 +43.240.56.0/21 +43.240.72.0/22 +43.241.16.0/22 +43.241.180.0/22 +43.241.208.0/20 +43.241.224.0/20 +43.241.240.0/22 +43.241.48.0/22 +43.241.76.0/22 +43.242.152.0/21 +43.242.164.0/22 +43.242.180.0/22 +43.242.192.0/21 +43.242.204.0/22 +43.242.252.0/22 +43.242.72.0/22 +43.242.84.0/22 +43.242.96.0/22 +43.243.12.0/22 +43.243.128.0/22 +43.243.136.0/22 +43.243.148.0/22 +43.243.156.0/22 +43.243.16.0/22 +43.243.228.0/22 +43.243.232.0/22 +43.243.244.0/22 +43.243.4.0/22 +43.243.88.0/22 +43.247.100.0/22 +43.247.176.0/20 +43.247.196.0/22 +43.247.244.0/22 +43.247.248.0/22 +43.247.4.0/24 +43.247.68.0/22 +43.247.84.0/22 +43.247.88.0/22 +43.248.0.0/22 +43.248.108.0/22 +43.248.112.0/21 +43.248.128.0/20 +43.248.184.0/21 +43.248.192.0/20 +43.248.232.0/22 +43.248.244.0/22 +43.248.48.0/22 +43.248.76.0/22 +43.248.96.0/21 +43.249.136.0/22 +43.249.144.0/22 +43.249.168.0/22 +43.249.192.0/22 +43.249.236.0/22 +43.250.112.0/22 +43.250.144.0/22 +43.250.168.0/22 +43.250.200.0/22 +43.250.236.0/22 +43.250.244.0/22 +43.250.32.0/22 +43.250.4.0/22 +43.250.96.0/22 +43.251.232.0/22 +43.251.244.0/22 +43.251.36.0/22 +43.251.4.0/22 +43.252.48.0/24 +43.254.0.0/22 +43.254.100.0/22 +43.254.104.0/23 +43.254.106.0/24 +43.254.116.0/22 +43.254.136.0/22 +43.254.140.0/23 +43.254.144.0/20 +43.254.168.0/21 +43.254.192.0/22 +43.254.200.0/22 +43.254.220.0/22 +43.254.224.0/20 +43.254.24.0/22 +43.254.240.0/22 +43.254.248.0/21 +43.254.44.0/22 +43.254.52.0/22 +43.254.8.0/22 +43.254.88.0/22 +43.255.0.0/22 +43.255.184.0/22 +43.255.192.0/22 +43.255.200.0/22 +43.255.212.0/22 +43.255.224.0/21 +43.255.68.0/22 +43.255.84.0/22 +43.255.96.0/22 +44.30.120.0/24 +44.31.216.0/24 +44.31.28.0/24 +44.31.43.0/24 +44.32.191.0/24 +44.32.69.0/24 +45.112.232.0/22 +45.113.20.0/22 +45.113.200.0/22 +45.113.206.0/24 +45.113.24.0/22 +45.113.40.0/22 +45.115.144.0/22 +45.115.164.0/22 +45.115.200.0/22 +45.115.44.0/22 +45.116.100.0/22 +45.116.140.0/22 +45.116.152.0/22 +45.116.208.0/22 +45.116.32.0/22 +45.116.52.0/22 +45.117.68.0/22 +45.117.8.0/22 +45.119.104.0/23 +45.119.116.0/22 +45.119.60.0/22 +45.119.64.0/21 +45.12.82.0/24 +45.120.100.0/22 +45.120.164.0/22 +45.120.243.0/24 +45.121.52.0/24 +45.121.55.0/24 +45.123.128.0/22 +45.123.168.0/21 +45.123.176.0/21 +45.124.124.0/22 +45.124.20.0/22 +45.124.68.0/22 +45.124.76.0/22 +45.124.80.0/22 +45.125.44.0/22 +45.125.56.0/22 +45.126.112.0/22 +45.126.120.0/22 +45.127.129.0/24 +45.127.144.0/21 +45.137.97.0/24 +45.146.82.0/24 +45.248.108.0/22 +45.248.204.0/22 +45.248.8.0/22 +45.249.212.0/22 +45.250.152.0/23 +45.250.180.0/23 +45.250.184.0/22 +45.250.188.0/24 +45.250.28.0/22 +45.250.32.0/21 +45.250.40.0/22 +45.251.120.0/22 +45.251.2.0/23 +45.251.20.0/22 +45.251.8.0/22 +45.251.88.0/21 +45.251.96.0/21 +45.252.0.0/22 +45.252.104.0/22 +45.252.48.0/22 +45.253.112.0/21 +45.253.132.0/22 +45.253.136.0/21 +45.253.144.0/20 +45.253.160.0/19 +45.253.192.0/19 +45.253.224.0/20 +45.253.24.0/22 +45.253.240.0/22 +45.253.32.0/24 +45.253.60.0/22 +45.253.96.0/20 +45.254.20.0/22 +45.254.48.0/23 +45.254.50.0/24 +45.254.64.0/20 +45.254.8.0/22 +45.255.152.0/22 +45.40.192.0/18 +45.65.20.0/22 +45.65.24.0/22 +45.82.239.0/24 +45.86.73.0/24 +46.37.112.0/24 +47.112.0.0/13 +47.120.0.0/14 +47.246.0.0/23 +47.246.12.0/23 +47.246.15.0/24 +47.246.20.0/24 +47.246.22.0/23 +47.246.24.0/24 +47.246.26.0/24 +47.246.28.0/22 +47.246.3.0/24 +47.246.36.0/22 +47.246.4.0/24 +47.246.41.0/24 +47.246.42.0/23 +47.246.44.0/23 +47.246.46.0/24 +47.246.48.0/23 +47.246.50.0/24 +47.246.57.0/24 +47.246.6.0/23 +47.246.60.0/22 +47.246.64.0/24 +47.246.8.0/24 +47.89.121.0/24 +47.89.91.0/24 +47.92.0.0/14 +47.96.0.0/12 +49.112.0.0/13 +49.120.0.0/14 +49.140.0.0/15 +49.208.0.0/14 +49.221.128.0/19 +49.221.26.0/23 +49.221.64.0/19 +49.232.0.0/14 +49.239.192.0/18 +49.4.0.0/18 +49.4.112.0/21 +49.4.120.0/22 +49.4.124.0/23 +49.4.126.0/24 +49.4.128.0/22 +49.4.64.0/19 +49.4.96.0/20 +49.52.0.0/14 +49.64.0.0/11 +49.7.0.0/16 +5.10.138.0/23 +5.10.140.0/24 +5.10.143.0/24 +50.114.121.0/24 +52.130.0.0/15 +52.80.0.0/15 +52.82.0.0/17 +52.82.128.0/23 +52.82.131.0/24 +52.82.132.0/24 +52.82.134.0/23 +52.82.136.0/24 +52.82.144.0/23 +52.82.148.0/22 +52.82.160.0/21 +52.82.170.0/23 +52.82.172.0/22 +52.82.176.0/21 +52.82.184.0/23 +52.82.187.0/24 +52.82.188.0/23 +52.82.190.0/24 +52.82.192.0/18 +52.83.0.0/16 +54.222.0.0/19 +54.222.100.0/22 +54.222.104.0/21 +54.222.112.0/22 +54.222.116.0/23 +54.222.128.0/17 +54.222.32.0/21 +54.222.45.0/24 +54.222.46.0/23 +54.222.48.0/21 +54.222.57.0/24 +54.222.60.0/22 +54.222.64.0/23 +54.222.70.0/23 +54.222.72.0/21 +54.222.80.0/21 +54.222.88.0/22 +54.222.96.0/23 +54.223.0.0/16 +58.100.0.0/15 +58.116.0.0/14 +58.128.0.0/13 +58.144.0.0/16 +58.154.0.0/15 +58.16.0.0/13 +58.192.0.0/11 +58.24.0.0/15 +58.240.0.0/12 +58.30.0.0/15 +58.32.0.0/11 +58.67.128.0/17 +58.68.236.0/24 +58.68.247.0/24 +58.82.0.0/22 +58.83.0.0/16 +58.87.64.0/18 +58.99.128.0/17 +59.107.0.0/17 +59.108.0.0/16 +59.110.0.0/16 +59.111.0.0/20 +59.111.104.0/23 +59.111.107.0/24 +59.111.109.0/24 +59.111.111.0/24 +59.111.112.0/21 +59.111.128.0/20 +59.111.144.0/24 +59.111.152.0/21 +59.111.160.0/21 +59.111.168.0/22 +59.111.17.0/24 +59.111.173.0/24 +59.111.175.0/24 +59.111.178.0/23 +59.111.18.0/23 +59.111.181.0/24 +59.111.182.0/23 +59.111.190.0/24 +59.111.192.0/23 +59.111.198.0/23 +59.111.203.0/24 +59.111.205.0/24 +59.111.21.0/24 +59.111.211.0/24 +59.111.214.0/24 +59.111.22.0/24 +59.111.224.0/21 +59.111.232.0/23 +59.111.236.0/24 +59.111.238.0/23 +59.111.24.0/21 +59.111.240.0/22 +59.111.244.0/24 +59.111.248.0/21 +59.111.32.0/24 +59.111.35.0/24 +59.111.36.0/24 +59.111.40.0/21 +59.111.64.0/19 +59.111.96.0/21 +59.151.0.0/17 +59.152.36.0/24 +59.152.38.0/23 +59.153.164.0/22 +59.153.168.0/24 +59.153.32.0/22 +59.153.4.0/23 +59.153.92.0/22 +59.172.0.0/14 +59.191.0.0/17 +59.252.0.0/16 +59.32.0.0/13 +59.40.0.0/15 +59.42.0.0/16 +59.44.0.0/14 +59.48.0.0/12 +59.64.0.0/12 +59.80.0.0/17 +59.81.102.0/23 +59.81.104.0/22 +59.81.40.0/23 +59.81.46.0/24 +59.81.64.0/23 +59.81.8.0/23 +59.81.82.0/23 +59.81.94.0/23 +59.82.0.0/17 +59.82.128.0/19 +59.83.192.0/19 +59.83.224.0/21 +59.83.232.0/22 +60.0.0.0/11 +60.160.0.0/11 +60.194.0.0/15 +60.200.0.0/24 +60.204.0.0/14 +60.208.0.0/12 +60.232.0.0/16 +60.235.0.0/16 +60.245.128.0/17 +60.247.0.0/16 +60.252.0.0/16 +60.253.128.0/17 +60.255.0.0/16 +60.63.0.0/16 +61.128.0.0/10 +61.232.0.0/14 +61.236.112.0/21 +61.236.248.0/24 +61.236.251.0/24 +61.236.80.0/20 +61.236.96.0/20 +61.237.0.0/16 +61.240.0.0/16 +61.241.0.0/17 +61.241.128.0/18 +61.241.192.0/19 +61.242.0.0/15 +61.28.108.0/24 +61.28.112.0/20 +61.28.20.0/24 +61.28.22.0/24 +61.28.49.0/24 +61.29.128.0/18 +61.4.80.0/23 +61.47.128.0/18 +61.48.0.0/13 +61.87.192.0/18 +62.234.0.0/16 +62.72.171.0/24 +63.140.0.0/24 +63.140.3.0/24 +66.102.240.0/21 +66.102.248.0/22 +66.102.252.0/24 +66.102.254.0/23 +68.79.0.0/18 +69.163.104.0/24 +69.163.106.0/24 +69.163.123.0/24 +69.230.192.0/18 +69.231.128.0/18 +69.234.192.0/18 +69.235.128.0/18 +71.131.192.0/18 +71.132.0.0/18 +71.136.64.0/18 +71.137.0.0/18 +79.133.176.0/24 +8.128.32.0/19 +8.128.4.0/22 +8.128.64.0/19 +8.128.96.0/20 +8.129.0.0/16 +8.130.0.0/15 +8.132.0.0/14 +8.136.0.0/13 +8.144.0.0/14 +8.148.0.0/19 +8.148.128.0/17 +8.148.36.0/22 +8.148.41.0/24 +8.148.43.0/24 +8.148.64.0/18 +8.149.0.0/16 +8.150.0.0/20 +8.150.16.0/21 +8.150.64.0/23 +8.152.0.0/13 +8.160.0.0/15 +8.162.0.0/18 +8.162.64.0/19 +8.163.0.0/16 +8.164.0.0/14 +8.168.0.0/15 +8.25.82.0/24 +8.38.121.0/24 +8.45.176.0/24 +8.45.52.0/24 +8.48.85.0/24 +81.173.18.0/23 +81.173.20.0/22 +81.173.28.0/24 +81.68.0.0/14 +82.156.0.0/15 +82.38.7.0/24 +87.76.221.0/24 +87.76.222.0/24 +93.95.117.0/24 +94.191.0.0/17 diff --git a/luci-app-passwall/root/usr/share/passwall/rules/chnroute6 b/luci-app-passwall/root/usr/share/passwall/rules/chnroute6 new file mode 100644 index 00000000..194c8901 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/chnroute6 @@ -0,0 +1,1552 @@ +2001:250::/30 +2001:254::/31 +2001:256:100::/48 +2001:4510:1480::/41 +2001:4510:400::/40 +2001:4511:1480::/41 +2001:678:53c::/48 +2001:7fa:5::/48 +2001:c68::/32 +2001:cc0::/32 +2001:da8::/32 +2001:daa:1::/48 +2001:daa:2::/47 +2001:daa:4::/47 +2001:daa:6::/48 +2001:dc7::/32 +2001:dd8:1::/48 +2001:dd9::/48 +2001:df6:40::/48 +2400:1160::/32 +2400:3200::/32 +2400:5280:f803::/48 +2400:5a00::/32 +2400:5a60:100::/48 +2400:5a60:2::/48 +2400:6000::/32 +2400:6600::/32 +2400:6e60:1301::/48 +2400:7100::/32 +2400:73e0::/32 +2400:75aa::/32 +2400:7fc0:220::/44 +2400:7fc0:240::/44 +2400:7fc0:2a0::/44 +2400:7fc0:2c0::/44 +2400:7fc0:4000::/40 +2400:7fc0:4100::/48 +2400:7fc0:6000::/40 +2400:7fc0:8000::/36 +2400:7fc0::/40 +2400:7fc0:a000::/36 +2400:7fc0:bb00::/40 +2400:7fc0:c000::/36 +2400:8200::/32 +2400:89c0:1010::/44 +2400:89c0:1050::/46 +2400:89c0:1130::/44 +2400:89c0:1150::/48 +2400:89c0:2100::/48 +2400:89c0:2200::/48 +2400:89c0:3010::/44 +2400:89c0:6000::/48 +2400:89c0:6100::/48 +2400:8fc0:571::/48 +2400:9020:f010::/46 +2400:9380:8001::/48 +2400:9380:8003::/48 +2400:9380:8021::/48 +2400:9380:8040::/48 +2400:9380:8140::/48 +2400:9380:8201::/48 +2400:9380:8301::/48 +2400:9380:9001::/48 +2400:9380:9009::/48 +2400:9380:9020::/47 +2400:9380:9040::/48 +2400:9380:9050::/47 +2400:9380:9060::/48 +2400:9380:9071::/48 +2400:9380:9080::/47 +2400:9380:90b1::/48 +2400:9380:90b2::/47 +2400:9380:90b4::/46 +2400:9380:9121::/48 +2400:9380:9220::/47 +2400:9380:9240::/48 +2400:9380:9250::/47 +2400:9380:9260::/48 +2400:9380:9271::/48 +2400:9380:9280::/47 +2400:9380:92b1::/48 +2400:9380:92b2::/47 +2400:9380:92b4::/46 +2400:95e0::/48 +2400:9600:8800::/48 +2400:9620::/32 +2400:a860:1::/48 +2400:a860:2::/47 +2400:a860:4::/47 +2400:a860:6::/48 +2400:a980::/29 +2400:ae00:1981::/48 +2400:b200::/32 +2400:b600::/32 +2400:b700::/48 +2400:be00::/48 +2400:cb80:e2e::/47 +2400:cb80:e30::/44 +2400:cb80:e40::/44 +2400:da00::/32 +2400:dd00::/28 +2400:e680::/32 +2400:ee00::/32 +2400:f6e0::/32 +2400:f720::/32 +2400:fe00::/32 +2401:1160::/32 +2401:1200::/48 +2401:1320::/32 +2401:1d40::/32 +2401:2780::/32 +2401:2a00:f000::/43 +2401:2e00::/32 +2401:3480:2000::/48 +2401:3480:3000::/36 +2401:3480::/36 +2401:34a0::/31 +2401:3800::/32 +2401:3880::/32 +2401:3980::/32 +2401:3a80::/32 +2401:3b80::/32 +2401:3c80::/32 +2401:3d80::/32 +2401:3e80::/32 +2401:3f80::/32 +2401:4180::/32 +2401:4280::/32 +2401:4380::/32 +2401:4480::/32 +2401:4580::/32 +2401:4680::/32 +2401:4780::/32 +2401:4880::/32 +2401:4a80::/32 +2401:5560:1000::/48 +2401:5c20:10::/48 +2401:70e0::/32 +2401:71c0::/48 +2401:7660::/48 +2401:7700::/32 +2401:7d40::/32 +2401:7e00::/32 +2401:800::/32 +2401:8be0::/48 +2401:8d00:12::/48 +2401:8d00:3::/48 +2401:8d00:4::/48 +2401:8d00:7::/48 +2401:8d00:8::/47 +2401:8d00::/47 +2401:8d00:b::/48 +2401:8d00:c::/48 +2401:8d00:f::/48 +2401:9a00:10::/46 +2401:9a00::/44 +2401:a140:1::/48 +2401:b180::/32 +2401:b400:11::/48 +2401:b400:14::/48 +2401:b400:16::/47 +2401:b400:20::/47 +2401:b400:8::/47 +2401:b400::/45 +2401:b680::/32 +2401:be00::/32 +2401:c020:14::/48 +2401:c020:6::/48 +2401:c020:8::/47 +2401:ca00::/32 +2401:cb80::/32 +2401:cc00::/32 +2401:ce00::/32 +2401:d0e0:3::/48 +2401:d180:10::/47 +2401:d180:111::/48 +2401:d180:2120::/48 +2401:d180::/46 +2401:d780::/32 +2401:d920::/48 +2401:de00::/32 +2401:ec00::/32 +2401:f860:100::/40 +2401:f860:85::/48 +2401:f860:87::/48 +2401:f860:88::/47 +2401:f860:90::/46 +2401:f860:94::/48 +2401:f860:96::/47 +2401:fa00:40::/43 +2402:1440::/32 +2402:18a0::/32 +2402:2000::/32 +2402:2620::/48 +2402:2e60::/39 +2402:34e0::/32 +2402:36e0::/44 +2402:3c00::/32 +2402:3f80:1400::/40 +2402:4440:9000::/39 +2402:4440:9200::/48 +2402:4440:9400::/48 +2402:4440:9600::/48 +2402:4440:9800::/48 +2402:4440:9810::/48 +2402:4440:9900::/48 +2402:4440:9a00::/48 +2402:4440:9b00::/48 +2402:4440:9c00::/48 +2402:4440:9d00::/48 +2402:4440:9e00::/48 +2402:4440:a000::/39 +2402:4440:a800::/46 +2402:4440:a810::/46 +2402:4b80::/32 +2402:4e00::/32 +2402:5e40::/32 +2402:5ec0::/32 +2402:6e80::/32 +2402:6f40:2::/48 +2402:6f40::/48 +2402:6fc0::/48 +2402:7040::/32 +2402:7d80:240::/48 +2402:7d80:8888::/48 +2402:7d80::/48 +2402:840:d000::/46 +2402:840:e000::/46 +2402:840:f000::/38 +2402:8bc0::/32 +2402:8cc0:200::/40 +2402:8cc0::/40 +2402:92c0::/48 +2402:93c0:100::/48 +2402:93c0:20::/48 +2402:93c0::/48 +2402:9a80::/32 +2402:a200::/32 +2402:b8c0:106::/48 +2402:b8c0:186::/48 +2402:b8c0:6::/48 +2402:b8c0:86::/48 +2402:c60::/48 +2402:d340::/32 +2402:db40:5100::/48 +2402:db40:5f00::/46 +2402:dfc0:50::/44 +2402:dfc0::/44 +2402:e480::/32 +2402:e740::/32 +2402:e7c0::/32 +2402:e880::/48 +2402:ef40::/32 +2402:f000::/32 +2402:f140:ff00::/46 +2402:f140:ff04::/48 +2402:f140:ff10::/46 +2402:f140:ff14::/48 +2402:f8c0::/42 +2403:1b80::/48 +2403:1ec0:1200::/48 +2403:1ec0:1400::/48 +2403:1ec0:1600::/48 +2403:1ec0:1610::/48 +2403:2040::/48 +2403:2b40::/32 +2403:3140::/32 +2403:4280::/47 +2403:4300::/32 +2403:4c80::/48 +2403:5c80::/48 +2403:600::/32 +2403:6740::/48 +2403:6a00::/32 +2403:7580::/32 +2403:8080:101::/48 +2403:8c00::/32 +2403:9b00:2000::/48 +2403:9b00:2400::/48 +2403:9b00:6000::/48 +2403:a100::/48 +2403:a140:100::/40 +2403:a140:10::/48 +2403:a200::/32 +2403:ac00::/32 +2403:b400::/32 +2403:c80::/32 +2403:c980::/32 +2403:d400::/32 +2403:e7c0:3::/48 +2403:f4c0::/48 +2403:ffc0:1100::/40 +2403:ffc0:1200::/39 +2404:1c40:503::/48 +2404:1c80::/32 +2404:2280:105::/48 +2404:2280:106::/47 +2404:2280:109::/48 +2404:2280:10a::/47 +2404:2280:10d::/48 +2404:2280:10f::/48 +2404:2280:112::/47 +2404:2280:115::/48 +2404:2280:116::/47 +2404:2280:11a::/47 +2404:2280:11c::/46 +2404:2280:123::/48 +2404:2280:125::/48 +2404:2280:126::/47 +2404:2280:128::/46 +2404:2280:12e::/48 +2404:2280:130::/48 +2404:2280:134::/48 +2404:2280:136::/47 +2404:2280:138::/48 +2404:2280:13b::/48 +2404:2280:13c::/47 +2404:2280:142::/48 +2404:2280:147::/48 +2404:2280:14f::/48 +2404:2280:150::/48 +2404:2280:154::/46 +2404:2280:159::/48 +2404:2280:15d::/48 +2404:2280:15e::/47 +2404:2280:160::/48 +2404:2280:170::/48 +2404:2280:177::/48 +2404:2280:17a::/47 +2404:2280:17c::/46 +2404:2280:180::/47 +2404:2280:183::/48 +2404:2280:187::/48 +2404:2280:18a::/47 +2404:2280:18c::/46 +2404:2280:190::/48 +2404:2280:193::/48 +2404:2280:196::/48 +2404:2280:198::/45 +2404:2280:1a4::/46 +2404:2280:1a8::/47 +2404:2280:1b0::/48 +2404:2280:1b2::/48 +2404:2280:1b4::/46 +2404:2280:1b8::/47 +2404:2280:1ba::/48 +2404:2280:1bf::/48 +2404:2280:1c1::/48 +2404:2280:1c2::/47 +2404:2280:1c4::/46 +2404:2280:1c8::/48 +2404:2280:1cb::/48 +2404:2280:1cc::/48 +2404:2280:1cf::/48 +2404:2280:1d0::/47 +2404:2280:1d3::/48 +2404:2280:1d4::/48 +2404:2280:1d6::/47 +2404:2280:1d8::/45 +2404:2280:1e0::/45 +2404:2280:1e8::/46 +2404:2280:1ec::/47 +2404:2280:1ee::/48 +2404:2280:1f0::/45 +2404:2280:1f8::/46 +2404:2280:201::/48 +2404:2280:202::/47 +2404:2280:204::/46 +2404:2280:208::/46 +2404:2280:20c::/47 +2404:2280:20e::/48 +2404:2280:210::/46 +2404:2280:214::/48 +2404:2280:217::/48 +2404:2280:218::/46 +2404:2280:21d::/48 +2404:2280:21e::/48 +2404:2280:221::/48 +2404:2280:259::/48 +2404:2280:25a::/47 +2404:2280:25c::/48 +2404:2280:265::/48 +2404:2280:266::/47 +2404:2280:268::/45 +2404:2280:270::/45 +2404:2280:278::/47 +2404:2280:27b::/48 +2404:2280:27c::/46 +2404:2280:282::/47 +2404:2280:284::/47 +2404:2280:288::/46 +2404:2280:28c::/48 +2404:2280:291::/48 +2404:2280:292::/48 +2404:2280:296::/47 +2404:2280:298::/46 +2404:2280:29c::/47 +2404:2280:2a0::/47 +2404:2280:2a4::/46 +2404:2280:2a9::/48 +2404:2280:2aa::/48 +2404:2280:2ad::/48 +2404:2280:2ae::/47 +2404:2280:2b1::/48 +2404:2280:2b2::/47 +2404:2280:2b5::/48 +2404:2280:2b6::/47 +2404:2280:2b8::/47 +2404:2280:2ba::/48 +2404:2280:2bc::/46 +2404:2280:2c2::/47 +2404:2280:2c5::/48 +2404:2280:2c9::/48 +2404:2280:2ca::/47 +2404:2280:2cd::/48 +2404:2280:2cf::/48 +2404:3700::/48 +2404:4dc0::/32 +2404:6380:1000::/48 +2404:6380:8001::/48 +2404:6380::/48 +2404:6500:dcb3::/48 +2404:7180:a000::/48 +2404:7180:a010::/48 +2404:7180:aa00::/48 +2404:7180:aa10::/48 +2404:7180:b001::/48 +2404:7180:b002::/48 +2404:7180:b010::/48 +2404:7180:c001::/48 +2404:7180:c002::/48 +2404:7180:c011::/48 +2404:7180:c012::/48 +2404:7180:f000::/48 +2404:7180:f010::/48 +2404:7240::/33 +2404:7600::/32 +2404:7940::/32 +2404:8d02:28c8::/48 +2404:8d02:4881::/48 +2404:bc0:1::/48 +2404:bc0:4000::/43 +2404:bc0:4100::/43 +2404:bc0:4200::/43 +2404:bc0:4300::/44 +2404:bc0:4400::/43 +2404:bc0:4500::/43 +2404:bc0:4620::/44 +2404:bc0:4f00::/43 +2404:c2c0:240::/44 +2404:c2c0:280::/44 +2404:c2c0:2c0::/44 +2404:c2c0:4000::/40 +2404:c2c0:4100::/48 +2404:c2c0:501::/48 +2404:c2c0:6000::/40 +2404:c2c0:8000::/36 +2404:c2c0::/40 +2404:c2c0:bb00::/40 +2404:c2c0:c000::/36 +2404:c300::/32 +2404:c940::/48 +2404:e280::/47 +2404:e8c0::/32 +2404:f4c0:f000::/44 +2405:1480:1000::/48 +2405:1480:2000::/48 +2405:1480:3000::/47 +2405:1640:6::/48 +2405:3140:11::/48 +2405:3140:21::/48 +2405:3140:31::/48 +2405:68c0:21::/48 +2405:6940::/48 +2405:6c0:2::/48 +2405:6c0:4::/48 +2405:6f00:c101::/48 +2405:6f00:c102::/48 +2405:6f00:c170::/47 +2405:6f00:c602::/48 +2405:7040:6000::/47 +2405:78c0:6e00::/43 +2405:8280::/32 +2405:8a40::/32 +2405:a900:ffee::/48 +2405:a900:fffe::/48 +2405:ad00::/32 +2405:b7c0::/32 +2405:d900::/32 +2405:e000::/32 +2405:f940::/32 +2406:1080::/48 +2406:1e40:f012::/47 +2406:2700::/32 +2406:280::/32 +2406:3340::/32 +2406:3640:1::/48 +2406:4440:f000::/44 +2406:4d00::/48 +2406:52c0::/32 +2406:5340:6666::/48 +2406:5340:8888::/48 +2406:6100::/32 +2406:840:1000::/47 +2406:840:100::/47 +2406:840:103::/48 +2406:840:10::/45 +2406:840:110::/48 +2406:840:1800::/48 +2406:840:1::/48 +2406:840:20::/48 +2406:840:2380::/48 +2406:840:2600::/48 +2406:840:2800::/48 +2406:840:2880::/47 +2406:840:2::/48 +2406:840:2e0::/48 +2406:840:3800::/48 +2406:840:380::/48 +2406:840:3c1::/48 +2406:840:3c2::/48 +2406:840:3e0::/48 +2406:840:4100::/47 +2406:840:410::/47 +2406:840:412::/48 +2406:840:420::/48 +2406:840:42::/48 +2406:840:43c0::/47 +2406:840:43e0::/47 +2406:840:44::/48 +2406:840:46::/48 +2406:840:4800::/47 +2406:840:480::/48 +2406:840:4880::/47 +2406:840:5100::/47 +2406:840:540::/48 +2406:840:5800::/47 +2406:840:5860::/47 +2406:840:5880::/47 +2406:840:5c00::/47 +2406:840:600::/48 +2406:840:680::/48 +2406:840:6c1::/48 +2406:840:710::/48 +2406:840:78::/47 +2406:840:7::/48 +2406:840:800::/46 +2406:840:805::/48 +2406:840:806::/48 +2406:840:80::/47 +2406:840:8100::/40 +2406:840:840::/47 +2406:840:842::/48 +2406:840:860::/48 +2406:840:880::/47 +2406:840:882::/48 +2406:840:90::/48 +2406:840:9200::/40 +2406:840:9680::/44 +2406:840:9700::/40 +2406:840:9804::/46 +2406:840:981a::/48 +2406:840:981c::/46 +2406:840:9962::/47 +2406:840:9966::/48 +2406:840:996c::/48 +2406:840:9970::/44 +2406:840:a31::/48 +2406:840:c02::/48 +2406:840:c60::/48 +2406:840:cb8::/48 +2406:840:cc2::/48 +2406:840:e072::/48 +2406:840:e080::/44 +2406:840:e0cf::/48 +2406:840:e10f::/48 +2406:840:e14f::/48 +2406:840:e260::/48 +2406:840:e280::/44 +2406:840:e301::/48 +2406:840:e302::/48 +2406:840:e304::/48 +2406:840:e306::/48 +2406:840:e330::/44 +2406:840:e600::/44 +2406:840:e620::/47 +2406:840:e80f::/48 +2406:840:eb00::/46 +2406:840:eb04::/47 +2406:840:eb07::/48 +2406:840:eb08::/48 +2406:840:eb0b::/48 +2406:840:eb0f::/48 +2406:840:eb80::/42 +2406:840:ee40::/47 +2406:840:ee44::/48 +2406:840:ee4b::/48 +2406:840:ee4d::/48 +2406:840:f0a1::/48 +2406:840:f0aa::/48 +2406:840:f380::/44 +2406:840:f401::/48 +2406:840:f402::/48 +2406:840:f44f::/48 +2406:840:f680::/44 +2406:840:f889::/48 +2406:840:fa01::/48 +2406:840:fa40::/48 +2406:840:fa60::/44 +2406:840:fc10::/44 +2406:840:fc20::/43 +2406:840:fc40::/42 +2406:840:fc90::/44 +2406:840:fca0::/43 +2406:840:fcd0::/48 +2406:840:fd40::/43 +2406:840:fd60::/48 +2406:840:fd67::/48 +2406:840:fd70::/48 +2406:840:fd77::/48 +2406:840:fd80::/48 +2406:840:fd87::/48 +2406:840:fd90::/44 +2406:840:fda0::/43 +2406:840:fdc0::/44 +2406:840:fe50::/47 +2406:840:fe73::/48 +2406:840:fe90::/46 +2406:840:fe94::/48 +2406:840:fe96::/47 +2406:840:fe98::/46 +2406:840:fe9d::/48 +2406:840:fe9e::/48 +2406:840:fea2::/47 +2406:840:fea4::/46 +2406:840:fea8::/48 +2406:840:feaa::/47 +2406:840:feac::/46 +2406:840:fec0::/48 +2406:840:fec2::/47 +2406:840:fec4::/48 +2406:840:feca::/47 +2406:840:fece::/47 +2406:840:fed1::/48 +2406:840:fed3::/48 +2406:840:fed4::/48 +2406:840:fed8::/48 +2406:840:fedb::/48 +2406:840:fedc::/48 +2406:840:feed::/48 +2406:840:fef2::/47 +2406:840:fef4::/46 +2406:840:fef8::/45 +2406:8880::/48 +2406:b640:100::/48 +2406:b640:4100::/48 +2406:cac0:200::/40 +2406:cac0::/40 +2406:cf00:1000::/43 +2406:cf00::/48 +2406:d440:100::/43 +2406:d440:200::/43 +2406:d440:300::/43 +2406:d440:ff00::/48 +2406:d440:ffff::/48 +2406:e3c0::/32 +2406:e500::/33 +2407:23c0::/48 +2407:2840::/48 +2407:37c0::/32 +2407:4980::/32 +2407:5380::/32 +2407:6c40:1100::/48 +2407:6c40:1210::/48 +2407:6c40:1500::/48 +2407:6c40:1600::/40 +2407:8f40:2::/48 +2407:9f00::/32 +2407:ad80::/32 +2407:ae80::/32 +2407:b380:8000::/48 +2407:bc00::/32 +2407:c080:4000::/37 +2407:c080:5000::/37 +2407:c080:6000::/36 +2407:c080:8000::/36 +2407:c080::/35 +2407:d9c0::/32 +2408:4000::/22 +2408:8000:1000::/36 +2408:8000:2000::/35 +2408:8000:2::/47 +2408:8000:4000::/34 +2408:8000:8000::/33 +2408:8000::/48 +2408:8001::/32 +2408:8020::/30 +2408:8024::/31 +2408:8026::/32 +2408:802a:8000::/33 +2408:802c::/32 +2408:803e::/32 +2408:8056::/32 +2408:805c::/30 +2408:8060::/33 +2408:80c2::/33 +2408:80c5::/33 +2408:80ca:8000::/34 +2408:80ca::/33 +2408:80da:8000::/34 +2408:80da::/33 +2408:80e0:4000::/34 +2408:80e0:8000::/33 +2408:80e2::/33 +2408:80e9:4000::/34 +2408:80ea:4000::/34 +2408:80ea:8000::/33 +2408:80f0:4000::/34 +2408:80f0:8000::/33 +2408:80f1:100::/43 +2408:80f1:120::/44 +2408:80f1:160::/43 +2408:80f1:180::/43 +2408:80f1:1b0::/44 +2408:80f1:1c0::/43 +2408:80f1:1e0::/44 +2408:80f1:200::/40 +2408:80f1:40::/43 +2408:80f1:70::/44 +2408:80f1:80::/41 +2408:80f1::/42 +2408:80f5:4000::/34 +2408:80f9:4000::/34 +2408:80fa:4000::/34 +2408:80fa:8000::/33 +2408:8120:1::/48 +2408:8120:2::/48 +2408:8120:7000::/36 +2408:8140:2000::/48 +2408:815f:e000::/35 +2408:8181:6000::/40 +2408:8181:8000::/40 +2408:8181::/40 +2408:8181:a000::/40 +2408:8181:a220::/44 +2408:8181:e000::/40 +2408:8182:6000::/40 +2408:8182:c000::/40 +2408:8183:4000::/40 +2408:8183:8000::/40 +2408:81a2:2000::/35 +2408:81a2:4000::/35 +2408:81a3:6000::/35 +2408:81a3:c800::/48 +2408:81a3:ca66::/48 +2408:8206::/31 +2408:8208::/29 +2408:8210::/30 +2408:8214::/31 +2408:821a::/31 +2408:8220::/31 +2408:8226::/32 +2408:822a::/31 +2408:822e::/31 +2408:8230::/29 +2408:8238::/31 +2408:823c::/31 +2408:8240::/32 +2408:8244::/30 +2408:8248::/30 +2408:824c::/32 +2408:824e::/31 +2408:8250::/30 +2408:8254::/32 +2408:8256::/31 +2408:8258::/30 +2408:825c::/31 +2408:825f::/32 +2408:8260::/32 +2408:8262::/31 +2408:8264::/31 +2408:8266::/32 +2408:826a::/32 +2408:826c::/30 +2408:8270::/32 +2408:8274::/30 +2408:8278::/31 +2408:827a::/32 +2408:8306::/31 +2408:8308::/30 +2408:8310::/30 +2408:832a::/32 +2408:832e::/31 +2408:8330::/30 +2408:8338::/32 +2408:8340::/32 +2408:8344::/30 +2408:8348::/30 +2408:834e::/31 +2408:8350::/30 +2408:8354::/32 +2408:8356::/31 +2408:8358::/30 +2408:8360::/30 +2408:8364::/31 +2408:836c::/30 +2408:8374::/30 +2408:8378::/31 +2408:837a::/32 +2408:8406:100::/41 +2408:8406:180::/42 +2408:8406:18c0::/42 +2408:8406:1900::/41 +2408:8406:1980::/42 +2408:8406:24c0::/42 +2408:8406:2500::/41 +2408:8406:2580::/42 +2408:8406:30c0::/42 +2408:8406:3100::/41 +2408:8406:3180::/42 +2408:8406:3cc0::/42 +2408:8406:3d00::/41 +2408:8406:3d80::/42 +2408:8406:48c0::/42 +2408:8406:4900::/41 +2408:8406:4980::/42 +2408:8406:54c0::/42 +2408:8406:5500::/41 +2408:8406:5580::/42 +2408:8406:60c0::/42 +2408:8406:6100::/41 +2408:8406:6180::/42 +2408:8406:6cc0::/42 +2408:8406:6d00::/41 +2408:8406:6d80::/42 +2408:8406:78c0::/42 +2408:8406:7900::/41 +2408:8406:7980::/42 +2408:8406:84c0::/42 +2408:8406:8500::/41 +2408:8406:8580::/42 +2408:8406:90c0::/42 +2408:8406:9100::/41 +2408:8406:9180::/42 +2408:8406:9cc0::/42 +2408:8406:9d00::/41 +2408:8406:9d80::/42 +2408:8406:a8c0::/42 +2408:8406:a900::/41 +2408:8406:a980::/42 +2408:8406:b4c0::/42 +2408:8406:b500::/41 +2408:8406:b580::/42 +2408:8406:c0::/42 +2408:8406:cc0::/42 +2408:8406:d00::/41 +2408:8406:d80::/42 +2408:8407:500::/42 +2408:8409:100::/41 +2408:8409:1800::/40 +2408:8409:1900::/41 +2408:8409:19a0::/43 +2408:8409:19c0::/42 +2408:8409:1a00::/42 +2408:8409:1a0::/43 +2408:8409:1c0::/42 +2408:8409:200::/42 +2408:8409:2400::/40 +2408:8409:2500::/41 +2408:8409:25a0::/43 +2408:8409:25c0::/42 +2408:8409:2600::/42 +2408:8409:3000::/40 +2408:8409:3100::/41 +2408:8409:31a0::/43 +2408:8409:31c0::/42 +2408:8409:3200::/42 +2408:8409:3c00::/40 +2408:8409:3d00::/41 +2408:8409:3da0::/43 +2408:8409:3dc0::/42 +2408:8409:3e00::/42 +2408:8409:4800::/40 +2408:8409:4900::/41 +2408:8409:49a0::/43 +2408:8409:49c0::/42 +2408:8409:4a00::/42 +2408:8409:5400::/40 +2408:8409:5500::/41 +2408:8409:55a0::/43 +2408:8409:55c0::/42 +2408:8409:5600::/42 +2408:8409:6000::/40 +2408:8409:6100::/41 +2408:8409:61a0::/43 +2408:8409:61c0::/42 +2408:8409:6200::/42 +2408:8409:6c00::/40 +2408:8409:6d00::/41 +2408:8409:6da0::/43 +2408:8409:6dc0::/42 +2408:8409:6e00::/42 +2408:8409:7800::/40 +2408:8409:7900::/41 +2408:8409:79a0::/43 +2408:8409:79c0::/42 +2408:8409:7a00::/42 +2408:8409:8400::/40 +2408:8409:8500::/41 +2408:8409:85a0::/43 +2408:8409:85c0::/42 +2408:8409:8600::/42 +2408:8409:9000::/40 +2408:8409:9100::/41 +2408:8409:91a0::/43 +2408:8409:91c0::/42 +2408:8409:9200::/42 +2408:8409:9c00::/40 +2408:8409:9d00::/41 +2408:8409:9da0::/43 +2408:8409:9dc0::/42 +2408:8409:9e00::/42 +2408:8409::/40 +2408:8409:a800::/40 +2408:8409:a900::/41 +2408:8409:a9a0::/43 +2408:8409:a9c0::/42 +2408:8409:aa00::/42 +2408:8409:b400::/40 +2408:8409:b500::/41 +2408:8409:b5a0::/43 +2408:8409:b5c0::/42 +2408:8409:b600::/42 +2408:8409:c00::/40 +2408:8409:d00::/41 +2408:8409:da0::/43 +2408:8409:dc0::/42 +2408:8409:e00::/42 +2408:840c:1a00::/40 +2408:840c:1c00::/40 +2408:840c:200::/40 +2408:840c:2700::/40 +2408:840c:2900::/40 +2408:840c:3400::/40 +2408:840c:3600::/40 +2408:840c:4e00::/40 +2408:840c:5000::/40 +2408:840c:5b00::/40 +2408:840c:5d00::/40 +2408:840c:6800::/40 +2408:840c:6a00::/40 +2408:840c:7500::/40 +2408:840c:7700::/40 +2408:840c:8200::/40 +2408:840c:8400::/40 +2408:840c:8f00::/40 +2408:840c:9100::/40 +2408:840c:9c00::/40 +2408:840c:9e00::/40 +2408:840c::/40 +2408:840c:a900::/40 +2408:840c:ab00::/40 +2408:840c:b600::/40 +2408:840c:b800::/40 +2408:840c:c300::/40 +2408:840c:c500::/40 +2408:840c:d000::/40 +2408:840c:d00::/40 +2408:840c:d200::/40 +2408:840c:dd00::/40 +2408:840c:de00::/40 +2408:840c:f00::/40 +2408:840d:1100::/42 +2408:840d:1140::/43 +2408:840d:1300::/42 +2408:840d:1a00::/42 +2408:840d:1c00::/42 +2408:840d:1e00::/42 +2408:840d:1e40::/43 +2408:840d:2000::/42 +2408:840d:200::/42 +2408:840d:2700::/42 +2408:840d:2900::/42 +2408:840d:2b00::/42 +2408:840d:2b40::/43 +2408:840d:2d00::/42 +2408:840d:3400::/42 +2408:840d:3600::/42 +2408:840d:3800::/42 +2408:840d:3840::/43 +2408:840d:3a00::/42 +2408:840d:400::/42 +2408:840d:440::/43 +2408:840d:4e00::/42 +2408:840d:5000::/42 +2408:840d:5200::/42 +2408:840d:5240::/43 +2408:840d:5400::/42 +2408:840d:5b00::/42 +2408:840d:5d00::/42 +2408:840d:5f00::/42 +2408:840d:5f40::/43 +2408:840d:600::/42 +2408:840d:6100::/42 +2408:840d:6800::/42 +2408:840d:6a00::/42 +2408:840d:6c00::/42 +2408:840d:6c40::/43 +2408:840d:6e00::/42 +2408:840d:7500::/42 +2408:840d:7700::/42 +2408:840d:7900::/42 +2408:840d:7940::/43 +2408:840d:7b00::/42 +2408:840d:8200::/42 +2408:840d:8400::/42 +2408:840d:8600::/42 +2408:840d:8640::/43 +2408:840d:8800::/42 +2408:840d:8f00::/42 +2408:840d:9100::/42 +2408:840d:9300::/42 +2408:840d:9340::/43 +2408:840d:9500::/42 +2408:840d:9c00::/42 +2408:840d:9e00::/42 +2408:840d::/42 +2408:840d:a000::/42 +2408:840d:a040::/43 +2408:840d:a200::/42 +2408:840d:a900::/42 +2408:840d:ab00::/42 +2408:840d:ad00::/42 +2408:840d:ad40::/43 +2408:840d:af00::/42 +2408:840d:b600::/42 +2408:840d:b800::/42 +2408:840d:ba00::/42 +2408:840d:ba40::/43 +2408:840d:bc00::/42 +2408:840d:c300::/42 +2408:840d:c500::/42 +2408:840d:c700::/42 +2408:840d:c740::/43 +2408:840d:c900::/42 +2408:840d:d000::/42 +2408:840d:d00::/42 +2408:840d:d200::/42 +2408:840d:d400::/42 +2408:840d:d440::/43 +2408:840d:d600::/42 +2408:840d:dd00::/42 +2408:840d:de00::/42 +2408:840d:f00::/42 +2408:840e:dd00::/40 +2408:840e:de00::/40 +2408:840f:1e0::/46 +2408:840f:1e4::/47 +2408:8410::/30 +2408:8414::/31 +2408:8417::/32 +2408:8418::/32 +2408:841a::/31 +2408:841c::/31 +2408:841e::/32 +2408:8420::/31 +2408:8422::/32 +2408:8426::/31 +2408:842a::/31 +2408:842c::/32 +2408:842e::/32 +2408:8430::/31 +2408:8434::/30 +2408:8438::/31 +2408:843c::/30 +2408:8440::/31 +2408:8444::/30 +2408:8448::/32 +2408:844b::/32 +2408:844c::/30 +2408:8452::/31 +2408:8454::/32 +2408:8456::/31 +2408:8458::/30 +2408:845c::/31 +2408:8460::/30 +2408:8464::/31 +2408:8466::/32 +2408:8469::/32 +2408:846a::/31 +2408:846c::/30 +2408:8470::/31 +2408:8474::/30 +2408:8478::/31 +2408:847a::/32 +2408:84e1::/32 +2408:84e2::/31 +2408:84e4::/30 +2408:84e9::/32 +2408:84eb::/32 +2408:84ec::/30 +2408:84f0::/28 +2408:856c::/31 +2408:8606::/31 +2408:8608::/29 +2408:8610::/30 +2408:8614::/31 +2408:861a::/31 +2408:861c::/32 +2408:8620::/31 +2408:8624::/31 +2408:8626::/32 +2408:862a::/31 +2408:862d::/32 +2408:862e::/31 +2408:8630::/29 +2408:8638::/31 +2408:863c::/31 +2408:8640::/32 +2408:8642::/32 +2408:8644::/30 +2408:8648::/31 +2408:864c::/32 +2408:864e::/31 +2408:8650::/30 +2408:8656::/31 +2408:8658::/30 +2408:865c::/31 +2408:865f::/32 +2408:8660::/32 +2408:8662::/31 +2408:8664::/31 +2408:8666::/32 +2408:866a::/31 +2408:866c::/30 +2408:8670::/32 +2408:8674::/30 +2408:8678::/31 +2408:867a::/32 +2408:8706::/31 +2408:8708::/29 +2408:8710::/30 +2408:8719::/32 +2408:871a::/31 +2408:8720::/30 +2408:8726::/32 +2408:872b::/32 +2408:872f::/32 +2408:8730::/30 +2408:8734::/31 +2408:8736::/32 +2408:8738::/32 +2408:873c::/31 +2408:8740::/32 +2408:8742::/32 +2408:8744::/30 +2408:8748::/29 +2408:8752::/32 +2408:8756::/31 +2408:8758::/30 +2408:875c::/32 +2408:8760::/32 +2408:8762::/31 +2408:8764::/31 +2408:8766::/32 +2408:8768::/32 +2408:876a::/32 +2408:876c::/30 +2408:8770::/32 +2408:8772::/31 +2408:8774::/32 +2408:8776::/31 +2408:8778::/31 +2408:877a::/32 +2408:877c::/30 +2408:8806:40::/43 +2408:8806::/42 +2408:880c::/30 +2408:8810::/30 +2408:8814::/31 +2408:8818::/31 +2408:882c::/32 +2408:883a::/32 +2408:8844::/43 +2408:8856::/31 +2408:8858::/30 +2408:8862::/31 +2408:8864::/31 +2408:8866::/32 +2408:886e::/31 +2408:8872::/32 +2408:8878::/31 +2408:887e::/32 +2408:8906:20::/44 +2408:8907:9000::/44 +2408:890c::/31 +2408:8912::/31 +2408:8914::/30 +2408:891c::/32 +2408:8920::/32 +2408:8924::/32 +2408:892c::/32 +2408:8936::/32 +2408:893a::/32 +2408:8940::/32 +2408:8948::/32 +2408:894c::/32 +2408:894e::/32 +2408:8956::/31 +2408:8958::/30 +2408:8962::/31 +2408:8964::/31 +2408:8966::/32 +2408:896c::/32 +2408:896e::/31 +2408:8972::/32 +2408:8978::/30 +2408:897e::/32 +2408:8a00:c000::/36 +2408:8a00:d000::/37 +2408:8a00:e000::/35 +2408:8a01::/36 +2408:8a02:b110::/44 +2408:8a02:b120::/44 +2408:8a04:8000::/36 +2408:8a04:e000::/40 +2408:8a05:6000::/35 +2408:8a05:8000::/36 +2408:8a06:100::/47 +2408:8a06::/47 +2408:8a21:4000::/35 +2408:8a22:9200::/39 +2408:8a22:9400::/38 +2408:8a22:9800::/40 +2408:8a22:9a00::/39 +2408:8a22:9c00::/38 +2408:8a22:a000::/37 +2408:8a23:4000::/34 +2408:8a24:4000::/34 +2408:8a26:c000::/34 +2408:8a27:4000::/35 +2409:2000::/31 +2409:2002::/32 +2409:2003::/47 +2409:27fa::/48 +2409:27fa:f000::/48 +2409:27fb::/48 +2409:27fc::/48 +2409:27fe::/33 +2409:8000::/20 +240a:2000::/40 +240a:2001:1000::/36 +240a:2001:100::/40 +240a:4002:1b00::/40 +240a:4010:8000::/33 +240a:4020:83a::/48 +240a:4020:883a::/48 +240a:4021:83a::/48 +240a:4021:883a::/48 +240a:4080:8000::/35 +240a:4084:2000::/35 +240a:4088:a000::/35 +240a:408c:2000::/35 +240a:4090:1000::/39 +240a:4090:1200::/40 +240a:4090:120::/48 +240a:4090:2010::/48 +240a:4090:2041::/48 +240a:4090:2061::/48 +240a:4090:250::/48 +240a:4090:3000::/39 +240a:4090:3200::/40 +240a:4090:5000::/39 +240a:4090:50::/48 +240a:4090:5200::/40 +240a:4090:7000::/39 +240a:4090:7200::/40 +240a:4090:8000::/34 +240a:4093::/35 +240a:4094:2000::/35 +240a:409c:2000::/35 +240a:40a4:2000::/35 +240a:40a8:8000::/35 +240a:40ac:2000::/35 +240a:40b0:283a::/48 +240a:40b0:483a::/48 +240a:40b0:683a::/48 +240a:40b0:83a::/48 +240a:40c0:8000::/43 +240a:40c0:8200::/48 +240a:40c0:8240::/48 +240a:40c0:a000::/43 +240a:40c0:c000::/43 +240a:40c0:e000::/43 +240a:40c1:2000::/43 +240a:40c1:4000::/43 +240a:40c1:6000::/43 +240a:40c1:8000::/43 +240a:40c1::/43 +240a:40c1:a000::/43 +240a:40c1:c000::/43 +240a:40c1:e000::/43 +240a:40c2:2000::/43 +240a:40c2:4000::/43 +240a:40c2:6000::/43 +240a:40c2:8000::/43 +240a:40c2::/43 +240a:40c2:a000::/43 +240a:40c2:c000::/43 +240a:40c2:e000::/43 +240a:40c3:2000::/43 +240a:40c3:4000::/43 +240a:40c3:6000::/43 +240a:40c3:8000::/43 +240a:40c3::/43 +240a:40c3:a000::/43 +240a:40c3:c000::/43 +240a:40c3:c200::/48 +240a:40c3:c240::/48 +240a:40c3:e000::/43 +240a:40c4:2000::/43 +240a:40c4:4000::/43 +240a:40c4::/43 +240a:4172::/31 +240a:4180::/31 +240a:41b0::/34 +240a:41b8:8800::/40 +240a:41b8:a000::/40 +240a:41b8:d400::/40 +240a:41b8:e400::/40 +240a:41d6::/31 +240a:41f2::/31 +240a:4208::/30 +240a:4224:9000::/44 +240a:4224:a000::/44 +240a:4224:c000::/44 +240a:4224:d000::/44 +240a:4224:e000::/44 +240a:4225:1000::/44 +240a:4225:3000::/44 +240a:4230::/31 +240a:4242::/31 +240a:4280::/26 +240a:42c0::/27 +240a:42e0::/28 +240a:42f0::/29 +240a:42f8::/30 +240a:6001::/48 +240a:a000::/20 +240a:c000::/20 +240b:e001::/32 +240b:e002::/31 +240b:e004::/30 +240b:e008::/29 +240b:e010::/32 +240c:4000::/22 +240c:c000::/20 +240d:4000::/21 +240e::/20 +2602:f46d:6::/48 +2602:f92a:a46d::/48 +2602:f92a:a46f::/48 +2602:f92a:a474::/48 +2602:f9ba:10c::/48 +2602:f9ba:a8::/48 +2602:f9f6:400::/47 +2602:f9f6::/48 +2602:fbda:600::/48 +2602:fbda:610::/48 +2602:fbda:620::/48 +2602:fbda:660::/44 +2605:9d80:8001::/48 +2605:9d80:8011::/48 +2605:9d80:8021::/48 +2605:9d80:8031::/48 +2605:9d80:8041::/48 +2605:9d80:8081::/48 +2605:9d80:9003::/48 +2605:9d80:9013::/48 +2605:9d80:9023::/48 +2605:9d80:9033::/48 +2605:9d80:9042::/48 +2605:9d80:9071::/48 +2605:9d80:9092::/48 +2620:57:4004::/48 +2804:1e48:9001::/48 +2804:1e48:9002::/48 +2a04:3e00:1002::/48 +2a04:f580:8010::/47 +2a04:f580:8090::/48 +2a04:f580:8210::/47 +2a04:f580:8290::/48 +2a04:f580:9010::/48 +2a04:f580:9012::/47 +2a04:f580:9020::/48 +2a04:f580:9030::/48 +2a04:f580:9040::/48 +2a04:f580:9050::/48 +2a04:f580:9060::/48 +2a04:f580:9070::/48 +2a04:f580:9080::/48 +2a04:f580:9210::/48 +2a04:f580:9212::/47 +2a04:f580:9220::/48 +2a04:f580:9230::/48 +2a04:f580:9240::/48 +2a04:f580:9250::/48 +2a04:f580:9260::/48 +2a04:f580:9270::/48 +2a04:f580:9280::/48 +2a04:f580:9290::/48 +2a05:1085::/32 +2a05:1087::/32 +2a06:3600:e000::/40 +2a06:3600:fb00::/40 +2a06:3600:fc00::/38 +2a06:3605::/32 +2a06:3606::/31 +2a06:9f81:4600::/43 +2a06:9f81:4620::/44 +2a06:9f81:4640::/43 +2a06:a005:260::/43 +2a06:a005:280::/43 +2a06:a005:2a0::/44 +2a06:de00:de00::/48 +2a0a:d680:8100::/47 +2a0a:d680:a31::/48 +2a0a:d681:e000::/40 +2a0a:d681:fb00::/40 +2a0a:d681:fc00::/38 +2a0b:4340:90::/48 +2a0b:4340:97::/48 +2a0c:b641:570::/47 +2a0d:c7c7:400::/38 +2a0e:aa06:400::/44 +2a0e:aa06:440::/48 +2a0e:aa06:490::/44 +2a0e:aa07:e025::/48 +2a0e:aa07:e200::/44 +2a0e:b107:14a0::/44 +2a0e:b107:1522::/48 +2a0e:b107:2440::/44 +2a0e:b107:740::/44 +2a0e:b107:da0::/44 +2a0f:1cc5:110::/44 +2a0f:1cc5:130::/44 +2a0f:1cc5:140::/44 +2a0f:1cc5:14::/46 +2a0f:1cc5:1600::/44 +2a0f:1cc5:1c00::/47 +2a0f:1cc5:1c02::/48 +2a0f:1cc5:1c30::/48 +2a0f:1cc5:1cc0::/48 +2a0f:1cc5:1d10::/47 +2a0f:1cc5:1d14::/48 +2a0f:1cc5:1f::/48 +2a0f:1cc5:2510::/44 +2a0f:1cc5:2520::/44 +2a0f:1cc5:2600::/40 +2a0f:1cc5:2d01::/48 +2a0f:1cc5:2d03::/48 +2a0f:1cc5:600::/47 +2a0f:1cc5:603::/48 +2a0f:1cc5:645::/48 +2a0f:1cc5:661::/48 +2a0f:1cc5:662::/48 +2a0f:1cc5:690::/48 +2a0f:1cc5:6a0::/48 +2a0f:1cc5:f00::/45 +2a0f:1cc5:f08::/47 +2a0f:1cc5:fff::/48 +2a0f:1cc6:b110::/47 +2a0f:2706::/32 +2a0f:6284:4c00::/44 +2a0f:6284:4c20::/44 +2a0f:6284:4c30::/48 +2a0f:6284:4c40::/43 +2a0f:6284:4c60::/44 +2a0f:6284:4c80::/43 +2a0f:6284:4ca0::/44 +2a0f:6284:4cd0::/44 +2a0f:7803:fc00::/39 +2a0f:85c1:bfe::/48 +2a0f:9400:6110::/48 +2a10:ccc0:cc1::/48 +2a10:ccc0:cc2::/48 +2a10:ccc0:ccc0::/48 +2a10:ccc0:ccc::/48 +2a12:cb46:6000::/44 +2a12:cb46::/36 +2a12:cb47:ffff::/48 +2a13:1801:180::/43 +2a13:1801:200::/44 +2a13:1802::/43 +2a13:a5c3:ff50::/44 +2a13:a5c5::/48 +2a13:aac4:f000::/44 +2a13:b487:1200::/42 +2a14:67c1:a110::/44 +2a14:67c1:b500::/47 +2a14:67c1:b511::/48 +2a14:67c1:b514::/48 +2a14:67c1:b530::/44 +2a14:67c1:b561::/48 +2a14:67c1:b563::/48 +2a14:67c1:b578::/48 +2a14:67c1:b586::/47 +2a14:67c1:b588::/47 +2a14:67c1:b590::/48 +2a14:67c1:b599::/48 +2a14:67c1:b5e0::/44 +2a14:67c3:30::/44 +2a14:67c3:6668::/45 +2a14:7580:740::/44 +2a14:7580:7a0::/48 +2a14:7580:d00::/43 +2a14:7580:d20::/46 +2a14:7580:d41::/48 +2a14:7580:d42::/47 +2a14:7580:dff::/48 +2a14:7580:fffa::/48 +2a14:7581:3814::/48 +2a14:7581:3818::/47 +2a14:7581:381b::/48 +2a14:7583:f411::/48 +2a14:7583:f4f0::/48 +2a14:7583:f4f4::/48 +2a14:7583:f4fe::/48 +2a14:7583:f701::/48 +2a14:7583:f703::/48 +2a14:7583:f704::/46 +2a14:7583:f708::/46 +2a14:7583:f70c::/48 +2a14:7583:f743::/48 +2a14:7583:f744::/48 +2a14:7583:f764::/48 +2a14:7586:6100::/46 +2a14:7586:6104::/48 +2a14:7586:6107::/48 +2a14:7586:6110::/48 +2a14:7586:6300::/44 +2a14:7dc0:506::/48 +2c0f:f7a8:8011::/48 +2c0f:f7a8:8050::/48 +2c0f:f7a8:805f::/48 +2c0f:f7a8:8150::/48 +2c0f:f7a8:815f::/48 +2c0f:f7a8:8211::/48 +2c0f:f7a8:9020::/48 +2c0f:f7a8:9041::/48 +2c0f:f7a8:9211::/48 +2c0f:f7a8:9220::/48 diff --git a/luci-app-passwall/root/usr/share/passwall/rules/direct_host b/luci-app-passwall/root/usr/share/passwall/rules/direct_host new file mode 100644 index 00000000..a3b14645 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/direct_host @@ -0,0 +1,27 @@ +cn +apple.com +microsoft.com +dyndns.com +douyucdn.cn +douyucdn2.cn +location.services.mozilla.com + +#steam +steamcontent.com +dl.steam.clngaa.com +dl.steam.ksyna.com +st.dl.bscstorage.net +st.dl.eccdnx.com +st.dl.pinyuncloud.com +cdn.mileweb.cs.steampowered.com.8686c.com +cdn-ws.content.steamchina.com +cdn-qc.content.steamchina.com +cdn-ali.content.steamchina.com +epicgames-download1-1251447533.file.myqcloud.com + +#DoT/DoH +dns.alidns.com +doh.pub +dot.pub +doh.360.cn +dot.360.cn diff --git a/luci-app-passwall/root/usr/share/passwall/rules/direct_ip b/luci-app-passwall/root/usr/share/passwall/rules/direct_ip new file mode 100644 index 00000000..b73edaa6 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/direct_ip @@ -0,0 +1,10 @@ +114.114.114.114 +114.114.115.115 +223.5.5.5 +223.6.6.6 +119.29.29.29 +180.76.76.76 +1.12.12.12 +120.53.53.53 +180.184.1.1 +180.184.2.2 diff --git a/luci-app-passwall/root/usr/share/passwall/rules/domains_excluded b/luci-app-passwall/root/usr/share/passwall/rules/domains_excluded new file mode 100644 index 00000000..f2def6f2 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/domains_excluded @@ -0,0 +1,26 @@ +courier.push.apple.com +rbsxbxp-mim.vivox.com +rbsxbxp.www.vivox.com +rbsxbxp-ws.vivox.com +rbspsxp.www.vivox.com +rbspsxp-mim.vivox.com +rbspsxp-ws.vivox.com +rbswxp.www.vivox.com +rbswxp-mim.vivox.com +disp-rbspsp-5-1.vivox.com +disp-rbsxbp-5-1.vivox.com +proxy.rbsxbp.vivox.com +proxy.rbspsp.vivox.com +proxy.rbswp.vivox.com +rbswp.vivox.com +rbsxbp.vivox.com +rbspsp.vivox.com +rbspsp.www.vivox.com +rbswp.www.vivox.com +rbsxbp.www.vivox.com +rbsxbxp.vivox.com +rbspsxp.vivox.com +rbswxp.vivox.com +Mijia Cloud +dlg.io.mi.com +marscdn.c2c.wechat.com diff --git a/luci-app-passwall/root/usr/share/passwall/rules/gfwlist b/luci-app-passwall/root/usr/share/passwall/rules/gfwlist new file mode 100644 index 00000000..743bc8c1 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/gfwlist @@ -0,0 +1,4200 @@ +000webhost.com +0rz.tw +1-apple.com.tw +1000giri.net +10beasts.net +10musume.com +12bet.com +12vpn.com +12vpn.net +1337x.to +141jj.com +1688.com.au +173ng.com +18board.com +18comic.org +1984bbs.com +1991way.com +1e100.net +1lib.sk +1point3acres.com +1pondo.tv +2008xianzhang.info +2021hkcharter.com +2047.name +2047.one +2049bbs.xyz +233abc.com +24hrs.ca +32red.com +36rain.com +404museum.com +466453.com +4bluestones.biz +4everproxy.com +4rbtv.com +4shared.com +4sqi.net +500px.com +500px.org +51.ca +51jav.org +51luoben.com +5278.cc +611study.com +611study.icu +63i.com +666pool.cn +69shuba.cx +6do.news +6do.world +6park.com +6parkbbs.com +6parker.com +6parknews.com +7capture.com +8-d.com +85cc.us +881903.com +89-64.org +8964museum.com +8z1.net +91dasai.com +91porn.com +91porny.com +91vps.club +991.com +996.icu +99btgc01.com +99cn.info +9bis.com +9bis.net +9cache.com +9gag.com +9news.com.au +a-normal-day.com +a248.e.akamai.net +aamacau.com +aave.com +abc.net.au +abc.xyz +abebooks.co.uk +abebooks.com +abematv.akamaized.net +aboluowang.com +about.gitlab.com +about.me +abplive.com +acast.com +accountkit.com +acevpn.com +acg.rip +acg18.me +acgbox.org +acgkj.com +acgnx.se +activpn.com +aculo.us +adcex.com +addictedtocoffee.de +addons.mozilla.org +addyoutube.com +adguard-vpn.com +admin.recaptcha.net +admob.com +adpl.org.hk +ads-twitter.com +adsense.com +adult-sex-games.com +adult.friendfinder.com +advanscene.com +advertfan.com +advertisercommunity.com +aei.org +aenhancers.com +aex.com +af.mil +afantibbs.com +afr.com +afreecatv.com +agnesb.fr +agoogleaday.com +agro.hk +ai.dev +ai.studio +aiosearch.com +aiph.net +airconsole.com +airitilibrary.com +airvpn.org +ait.org.tw +aiweiweiblog.com +akademiye.org +akamai.tvb.com +akamaihd.net +akiba-online.com +akiba-web.com +akile.io +akinator.com +akow.org +alabout.com +alanhou.com +alasbarricadas.org +alforattv.net +alive.bar +aljazeera.com +aljazeera.net +alkasir.com +all4mom.org +allcoin.com +allconnected.co +alldrawnsex.com +allfinegirls.com +allinfa.com +allmovie.com +alternate-tools.com +altrec.com +alwaysdata.com +alwaysdata.net +alwaysvpn.com +am730.com.hk +amazon.co.jp +amazonvideo.com +ameblo.jp +americangreencard.com +americorps.gov +amiblockedornot.com +amitabhafoundation.us +amnesty.org +amnesty.org.hk +amnestyusa.org +ampproject.org +amuletmc.com +anchor.fm +anchorfree.com +ancsconf.org +andfaraway.net +android-x86.org +android.com +androidapksfree.com +androidify.com +androidtv.com +andygod.com +angela-merkel.de +angola.org +angularjs.org +aniscartujo.com +annas-archive.gd +annas-archive.gl +annas-archive.pk +anobii.com +anonfiles.com +anonymouse.org +anthonycalzadilla.com +anthropic.com +antiwave.net +antpool.com +anuneko.com +anysex.com +ao3.org +aobo.com.au +aofriend.com +aomedia.org +aomiwang.com +aoxvpn.com +apartmentratings.com +apartments.com +apat1989.org +api-secure.recaptcha.net +api-verify.recaptcha.net +api.ai +api.palworldgame.com +api.pureapk.com +api.recaptcha.net +api.steampowered.com +apiary.io +apigee.com +apk.support +apkcombo.com +apkmirror.com +apkmonk.com +apkplz.com +apkpure.com +apkpure.net +app.box.com +app.cloudcone.com +app.element.io +app.smartmailcloud.com +appadvice.com +appbrain.com +appledaily.com +appledaily.com.tw +apps.evozi.com +appshopper.com +appsocks.net +appspot.com +appsto.re +aptoide.com +archive-it.org +archive.fo +archive.is +archive.li +archive.md +archive.org +archive.ph +archive.today +archive.vn +archiveofourown.com +archiveofourown.org +archives.gov +arctosia.com +areca-backup.org +arena.ai +arena.taipei +arethusa.su +arlingtoncemetery.mil +arte.tv +artstation.com +arvanstorage.ir +arweave.org +asacp.org +asiaharvest.org +asianage.com +asianews.it +asianfanfics.com +asiansexdiary.com +asiaone.com +asiasociety.org +ask.com +askstudent.com +askynz.net +aspi.org.au +aspistrategist.org.au +assembla.com +assets.bwbx.io +assets.nxtrace.org +assimp.org +astrill.com +atc.org.au +atchinese.com +athenaeizou.com +atlanta168.com +atnext.com +auctions.yahoo.co.jp +audacy.com +auntology.fandom.com +autodraw.com +av.movie +av01.tv +avaaz.org +avdb.in +avdb.tv +avg.com +avgle.com +avidemux.org +avistaz.to +avmo.pw +avmoo.pw +avoision.com +axios.com +axureformac.com +azirevpn.com +azurewebsites.net +b-ok.cc +b.hatena.ne.jp +babylonbee.com +backchina.com +backend-v2.crixet.com +bad.news +badiucao.com +bahamut.com.tw +baidu.jp +baijie.org +bailandaily.com +baixing.me +baizhi.org +banana-vpn.com +band.us +bandcamp.com +bandwagonhost.com +bangchen.net +bangdream.space +bangkokpost.com +bangumi.moe +bangyoulater.com +bankmobilevibe.com +bannedbook.org +banorte.com +baramangaonline.com +barnabu.co.uk +bartender.dowjones.com +barton.de +bastillepost.com +bayvoice.net +bb-chat.tv +bbc.co.uk +bbc.com +bbc.pdn.tritondigital.com +bbcchinese.com +bbchat.tv +bbci.co.uk +bbs.cantonese.asia +bbs.hanminzu.org +bbs.junglobal.net +bbs.mikocon.com +bbs.mychat.to +bbs.naixi.net +bbs.nyinfor.com +bcex.ca +bearteach.com +bebo.com +beeg.com +beepool.com +beepool.org +beevpn.com +behance.net +beijing1989.com +beijing2022.art +beijingspring.com +bell.wiki +bellingcat.com +berlinerbericht.de +berlintwitterwall.com +bestvpn.com +bestvpnanalysis.com +bestvpnforchina.net +bestvpnserver.com +bestvpnservice.com +bestvpnusa.com +bet365.com +betaclouds.net +bettergpt.chat +betterhash.net +betternet.co +bettervpn.com +bettween.com +betvictor.com +bfnn.org +bfsh.hk +bgme.me +bgvpn.com +biblesforamerica.org +bibox.com +biedian.me +big.one +bigjapanesesex.com +bignews.org +bigone.com +bild.de +biliworld.com +binance.com +binance.org +binancezh.cc +bird.so +bit-z.com +bit.do +bit.ly +bitbaby.com +bitbay.net +bitchute.com +bitcointalk.org +bitcoinworld.com +bitfinex.com +bitget.com +bithumb.com +bitmex.com +bitshare.com +bitterwinter.org +bittorrent.com +bitvise.com +bitz.ai +bjzc.org +bl-doujinsouko.com +blacked.com +blackmagicdesign.com +blackvpn.com +blinkx.com +blip.tv +blockcast.it +blockcn.com +blockedbyhk.com +blockless.com +blocktempo.com +blog.cryptographyengineering.com +blog.de +blog.excite.co.jp +blog.expofutures.com +blog.fizzik.com +blog.fuckgfw233.org +blog.jackjia.com +blog.jp +blog.martinoei.com +blog.pathtosharepoint.com +blog.pentalogic.net +blog.ranxiang.com +blog.reimu.net +blog.soylent.com +blog.tiney.com +blogblog.com +blogcatalog.com +blogcity.me +blogger.com +blogjav.net +bloglines.com +bloglovin.com +blogspot.ae +blogspot.al +blogspot.am +blogspot.ba +blogspot.be +blogspot.bg +blogspot.ca +blogspot.cat +blogspot.ch +blogspot.cl +blogspot.co.uk +blogspot.com +blogspot.com.ar +blogspot.com.au +blogspot.com.br +blogspot.com.by +blogspot.com.co +blogspot.com.cy +blogspot.com.ee +blogspot.com.eg +blogspot.com.es +blogspot.com.mt +blogspot.com.ng +blogspot.com.tr +blogspot.com.uy +blogspot.cz +blogspot.de +blogspot.dk +blogspot.fi +blogspot.fr +blogspot.gr +blogspot.hk +blogspot.hr +blogspot.hu +blogspot.ie +blogspot.in +blogspot.is +blogspot.it +blogspot.jp +blogspot.kr +blogspot.li +blogspot.lt +blogspot.lu +blogspot.md +blogspot.mk +blogspot.mx +blogspot.my +blogspot.nl +blogspot.no +blogspot.pe +blogspot.pt +blogspot.qa +blogspot.ro +blogspot.ru +blogspot.se +blogspot.sg +blogspot.si +blogspot.sk +blogspot.sn +blogspot.tw +blogspot.ug +blogtd.org +bloodshed.net +bloomberg.cn +bloomberg.com +bloomberg.de +bloombergview.com +bloomfortune.com +blubrry.com +bmdru.com +bnbstatic.com +bnext.com.tw +bnn.co +bnrmetal.com +boardreader.com +bod.asia +bolehvpn.net +boobstagram.com +book.com.tw +bookdepository.com +books.com.tw +booktopia.com.au +bookwalker.com.tw +bootstrapcdn.com +borgenmagazine.com +botanwang.com +bowenpress.com +boxpn.com +boxun.com +boxun.tv +boysmaster.com +br.st +braumeister.org +brave.com +bravotube.net +brazzers.com +breached.to +break.com +breakgfw.com +breakingtweets.com +breakwall.net +brill.com +brizzly.com +broadpressinc.com +brookings.edu +brutaltgp.com +bsky.app +bsky.network +bsky.social +bt4g.org +bt4gprx.com +bt95.com +btbit.net +btbtt.co +btbtt.me +btc.com +btc98.com +btcbank.bank +btctrade.im +btdig.com +btguard.com +btku.me +btku.org +budaedu.org +buffered.com +bullguard.com +bullog.org +bullogger.com +bumingbai.net +bunbunhk.com +busayari.com +business-humanrights.org +business.page +businessinsider.com +businesstoday.com.tw +busu.org +buzzorange.com +buzzsprout.com +bvpn.com +bwgyhw.com +bwh1.net +bx.in.th +bybit.com +bynet.co.il +bypasscensorship.org +byrut.org +c-est-simple.com +c-span.org +c-spanvideo.org +c.mi.com +c2cx.com +c3pool.com +cableav.tv +cablegatesearch.net +cachefly.com +cachefly.net +cacnw.com +cactusvpn.com +calebelston.com +calendarz.com +camfrog.com +campaign-archive.com +campaignforuyghurs.org +cams.com +canva.com +canyu.org +caobian.info +caochangqing.com +caoporn.us +cap.org.hk +carfax.com +cari.com.my +caribbeancom.com +carousell.com.hk +carrd.co +cartoonmovement.com +casatibet.org.mx +casino.williamhill.com +casinobellini.com +castbox.fm +catbox.moe +catch22.net +catchgod.com +catholic.org.hk +catholic.org.tw +cato.org +cattt.com +caus.com +cbc.ca +cbs.ntu.edu.tw +cccat.cc +cccat.co +ccfd.org.tw +cchere.com +cchostvps.xyz +cclife.org +cclifefl.org +ccthere.com +ccthere.net +cdbook.org +cdef.org +cdig.info +cdjp.org +cdn-images.mailchimp.com +cdn-telegram.org +cdn.arstechnica.net +cdn.jwplayer.com +cdn.printfriendly.com +cdn.seatguru.com +cdn.softlayer.net +cdn.statically.io +cdninstagram.com +cdp1998.org +cdp2006.org +cdpeu.org +cdpuk.co.uk +cdpweb.org +cdpwu.org +cdw.com +cecc.gov +cellulo.info +cenews.eu +centauro.com.br +centerforhumanreprod.com +centralnation.com +centurys.net +certificate-transparency.org +certificate.revocationcheck.com +cfr.org +cgdepot.org +change.org +changp.com +channelnewsasia.com +chanworld.org +chaoex.com +chaos.social +character.ai +chat.com +chat.lmsys.org +chatgpt.com +chatpdf.com +chaturbate.com +checkgfw.com +chengmingmag.com +chenguangcheng.com +chenpokong.com +chenpokongvip.com +chenshan20042005.wordpress.com +cherrysave.com +chhongbi.org +china-mmm.net +china-review.com.ua +china-week.com +china.ucanews.com +china101.com +china18.org +china21.com +china21.org +china5000.us +chinaaffairs.org +chinaaid.net +chinaaid.org +chinaaid.us +chinachange.org +chinachannel.hk +chinademocrats.org +chinadialogue.net +chinadigitaltimes.net +chinaelections.org +chinafile.com +chinafreepress.org +chinagfw.org +chinahorizon.org +chinamule.com +chinanewscenter.com +chinapress.com.my +chinasocialdemocraticparty.com +chinasoul.org +chinatopsex.com +chinauncensored.tv +chinaview.wordpress.com +chinaworker.info +chinese-memorial.org +chinese.engadget.com +chinesedailynews.com +chinesedemocracy.com +chinesegay.org +chinesen.de +chinesenews.net.au +chineseradioseattle.com +chineseupress.com +chingcheong.com +chinman.net +chobit.cc +chrdnet.com +christianfreedom.org +christianstudy.com +christiantimes.org.hk +chrlawyers.hk +chrome.com +chromecast.com +chromeexperiments.com +chromestatus.com +ci-en.jp +cia.gov +cici.com +ciciai.com +cirosantilli.com +citizencn.com +citizenlab.ca +citizenlab.org +city365.ca +citypopulation.de +civicparty.hk +civilhrfront.org +civilmedia.tw +civitai.com +cixiaoya.club +ck101.com +classicalguitarblog.net +claude.ai +claude.com +cldr.unicode.org +clearsurance.com +clementine-player.org +clinica-tibet.ru +clipconverter.cc +cloud.dify.ai +cloud.mail.ru +cloudflare-dns.com +cloudflare-ipfs.com +cloudflarestatus.com +cloudfunctions.net +club1069.com +clubhouseapi.com +clyp.it +cmcn.org +cmegroup.com +cmi.org.tw +cms.gov +cmule.com +cmx.im +cn-proxy.com +cn.fmnnow.com +cn.sandscotaicentral.com +cn.shafaqna.com +cn.theaustralian.com.au +cn.uptodown.com +cna.com.tw +cnbbnews.wordpress.com +cnbeta.com.tw +cnd.org +cnnews.chosun.com +cnpolitics.org +co.ng.mil +coat.co.jp +cobinhood.com +cochina.org +codeshare.io +codeskulptor.org +cofacts.tw +coffeemanga.to +coinbase.com +coinbene.com +coinex.com +coingecko.com +coingi.com +coinmarketcap.com +coinrail.co.kr +cointiger.com +cointobe.com +coinut.com +colacloud.net +collateralmurder.com +collateralmurder.org +comefromchina.com +comments.app +commentshk.com +communistcrimes.org +communitychoicecu.com +comparitech.com +compileheart.com +connect.facebook.net +conoha.jp +contests.twilio.com +cool18.com +coolaler.com +coolder.com +coolloud.org.tw +coolstuffinc.com +copilot.microsoft.com +cos-moe.com +cosplayjav.pl +costco.com +cotweet.com +counter.social +coursehero.com +covenantswatch.org.tw +coze.com +cpj.org +cpu-monkey.com +cq99.us +crackle.com +crashlytics.com +crazypool.org +crazyshit.com +crbug.com +crchina.org +creaders.net +creativelab5.com +cristyli.com +crocotube.com +crossfire.co.kr +crossvpn.net +crosswall.org +croxyproxy.com +crrev.com +crucial.com +crunchyroll.com +cruxpool.com +csdparty.com +csis.org +csmonitor.com +css.pixnet.in +csuchen.de +csw.org.uk +ct.org.tw +ctinets.com +ctinews.com +ctitv.com.tw +ctowc.org +cts.com.tw +ctwant.com +cuiweiping.net +culture.tw +cumlouder.com +curvefish.com +cusp.hk +cutout.pro +cutscenes.net +cw.com.tw +cyberghostvpn.com +cynscribe.com +d-fukyu.com +d.cash +d100.net +d2bay.com +d2pass.com +dabr.co.uk +dabr.me +dabr.mobi +dadazim.com +daidostup.ru +dailymail.co.uk +dailymotion.com +dailysabah.com +dailyview.tw +dajiyuan.de +dalailama.mn +dalailama.ru +dalailamacenter.org +dalailamaworld.com +dalianmeng.org +daliulian.org +danbooru.donmai.us +danke4china.net +darmau.co +darpa.mil +darrenliuwei.com +dashlane.com +data-vocabulary.org +daum.net +david-kilgour.com +dawangidc.com +daxa.cn +dazn.com +db.tt +dbgjd.com +dcard.tw +dcs-spotify.megaphone.fm +ddc.com.tw +ddex.io +deadhouse.org +deadline.com +debug.com +deck.ly +deck.new +decodet.co +deepai.org +deepmind.com +deezer.com +deja.com +delcamp.net +demo.unlock-music.dev +demosisto.hk +depositphotos.com +desc.se +desipro.de +dessci.com +deutsche-welle.de +developers.box.net +deviantart.com +deviantart.net +devio.us +devpn.com +devv.ai +diaoyuislands.org +digiland.tw +digisfera.com +diigo.com +directcreative.com +discoins.com +disconnect.me +discord.com +discord.gg +discordapp.com +discordapp.net +discuss.com.hk +dish.com +disk.yandex.com +disk.yandex.ru +disneyplus.com +disp.cc +disqus.com +dit-inc.us +diyin.org +dizhuzhishang.com +dl-laby.jp +dl.box.net +dlive.tv +dlsite.com +dlyoutube.com +dm530.net +dma.mil +dmc.nico +dmcdn.net +dmhy.org +dmm.co.jp +dns.cloudflare.com +dns.sb +dns2go.com +dnscrypt.org +dnssec.net +dnvod.tv +doc.new +docker.com +docker.io +dockerstatus.com +docs.new +documentingreality.com +doh.sb +dolc.de +dolf.org.hk +dongtaiwang.com +dongtaiwang.net +doom9.org +doosho.com +doourbest.org +dot.sb +dotplane.com +dotsub.com +dotvpn.com +doub.io +doubibackup.com +doubiyunbackup.com +doublethinklab.org +douchi.space +dougscripts.com +doujincafe.com +download.dappcdn.com +dpool.top +dpp.org.tw +dpr.info +dragonex.io +dragonsprings.org +drgan.net +dropbooks.tv +dropbox.com +dropboxapi.com +dropboxusercontent.com +dscn.info +dstk.dk +dtiblog.com +dtic.mil +dubox.com +duck.com +duckduckgo.com +duckmylife.com +duga.jp +duihua.org +duihuahrjournal.org +duplicati.com +duyaoss.com +dvdpac.com +dvorak.org +dw-world.com +dw-world.de +dw.com +dw.de +dweb.link +dwnews.com +dwnews.net +dynawebinc.com +dynu.com +dynupdate.no-ip.com +dysfz.cc +e-classical.com.tw +e-gold.com +e-hentai.org +e-hentaidb.com +e-zone.com.hk +e123.hk +e621.net +earlytibet.com +earthvpn.com +eastasiaforum.org +eastturkistangovernmentinexile.us +ebook.hyread.com.tw +ebtcbank.com +ecfa.org.tw +ecimg.tw +economist.com +edgecastcdn.net +edubridge.com +edx-cdn.org +eesti.ee +eevpn.com +efksoft.com +efukt.com +eic-av.com +eireinikotaerukai.com +eksisozluk.com +elconfidencial.com +elgoog.im +elpais.com +emule-ed2k.com +emulefans.com +en.favotter.net +encrypt.me +encyclopedia.com +enewstree.com +englishfromengland.co.uk +entermap.com +epochhk.com +epochtimes-bg.com +epochtimes-romania.com +epochtimes.co.il +epochtimes.co.kr +epochtimes.com +epochtimes.com.tw +epochtimes.de +epochtimes.fr +epochtimes.it +epochtimes.jp +epochtimes.ru +epochtimes.se +epochtimestr.com +epochweek.com +epochweekly.com +eporner.com +erights.net +eriversoft.com +ernestmandel.org +erodaizensyu.com +erodoujinlog.com +erodoujinworld.com +eromanga-kingdom.com +eromangadouzin.com +eromon.net +esg.t91y.com +eslite.com +esurance.com +etherdelta.com +ethermine.org +etherscan.com +etherscan.io +etizer.org +etokki.com +etools.ncol.com +etsy.com +eurekavpt.com +euronews.com +evchk.wikia.com +everipedia.org +evschool.net +exchristian.hk +exhentai.org +exmo.com +exmormon.org +expatshield.com +expecthim.com +expekt.com +exploader.net +expressvpn.com +exrates.me +extmatrix.com +eyevio.jp +eyny.com +f-droid.org +f2pool.com +f8.com +facebook.com +facebook.de +facebook.design +facebook.hu +facebook.in +facebook.nl +facebook.se +facebookmail.com +facebookquotes4u.com +faceless.me +facesofnyfw.com +facesoftibetanselfimmolators.info +factchecklab.org +factpedia.org +faith100.org +faiththedog.info +fakku.net +fallenark.com +falsefire.com +falunasia.info +falunau.org +falundafa-florida.org +falundafa-nc.org +falundafa-pa.net +falundafaindia.org +falunhr.org +famunion.com +fanbox.cc +fangeqiang.com +fanglizhi.info +fangong.org +fanhaolou.com +fanqiang.network +fanqiangdang.com +fanqianghou.com +fanqiangzhe.com +fanswong.com +fantv.hk +fast.com +fast.wistia.com +fastestvpn.com +fastpic.ru +fastssh.com +faststone.org +fatbtc.com +favstar.fm +faz.net +fb.com +fb.me +fb.watch +fbaddins.com +fbcdn.net +fbsbx.com +fbworkmail.com +fc2cn.com +feedburner.com +feeder.co +feedly.com +feeds.fileforum.com +feedx.net +feelssh.com +feitianacademy.org +feixiaohao.com +feministteacher.com +fengzhenghu.com +fengzhenghu.net +ff.im +fhreports.net +fiddle.jshell.net +figprayer.com +fileflyer.com +files.oaiusercontent.com +filesor.com +financetwitter.com +financialexpress.com +finchvpn.com +findyoutube.com +findyoutube.net +firearmsworld.net +firebaseio.com +fireofliberty.info +fireofliberty.org +firetweet.io +firstpost.com +firstrade.com +fish.audio +flecheinthepeche.fr +fleursdeslettres.com +flexclip.com +flexpool.io +flgjustice.org +flickr.com +flipboard.com +flipkart.com +flitto.com +flog.tw +flowgpt.com +flowhongkong.net +flypool.org +flyvpn.com +flyzy2005.com +fnac.be +fnac.com +fnc.ebc.net.tw +fochk.org +focustaiwan.tw +fofg.org +fooooo.com +forbes.com +forefront.ai +foreignaffairs.com +foreignpolicy.com +form.new +forms.new +forum.cyberctm.com +fountmedia.io +fourthinternational.org +foxgay.com +foxsub.com +fpmt.org +fpmtmexico.org +fqrouter.com +frank2019.me +franklc.com +freakshare.com +free-ss.site +free.bg +free.com.tw +freebeacon.com +freebrowser.org +freechinaweibo.com +freedom.gov +freedomhouse.org +freedominfonetweb.wordpress.com +freedomsherald.org +freegao.com +freegpt.es +freegpt.tech +freehongkong.org +freekazakhs.org +freelotto.com +freenetproject.org +freeoz.org +freess.org +freessh.us +freeterabox.com +freetibet.org +freetibetanheroes.org +freetls.fastly.net +freetribe.me +freevpn.me +freewallpaper4.me +freewechat.com +freeweibo.com +freezhihu.org +friendfeed.com +friends-of-tibet.org +friendsoftibet.org +fril.jp +fring.com +fringenetwork.com +frommel.net +frontlinedefenders.org +frootvpn.com +froth.zone +fscked.org +ft.com +ftchinese.com +ftv.com.tw +ftvnews.com.tw +ftx.com +fuchsia.dev +fuckccp.com +fuckccp.xyz +fulione.com +fullerconsideration.com +fullservicegame.com +funkyimg.com +furbo.org +furinkan.com +furrybar.com +futuremessage.org +fw.cm +fxcm-chinese.com +fxnetworks.com +g-area.org +g-queen.com +g.co +g0v.social +g6hentai.com +gab.com +gabocorp.com +gagaoolala.com +galenwu.com +game735.com +gamer.com.tw +gamez.com.tw +ganjing.com +ganjingworld.com +gaoming.net +gaopi.net +gartlive.com +garudalinux.org +gate.io +gatecoin.com +gather.com +gaymap.cc +gaywatch.com +gazotube.com +gcc.org.hk +gclubs.com +gcmasia.com +gcpnews.com +gcr.io +gdaily.org +geek-art.net +gekikame.com +gelbooru.com +generated.photos +genius.com +geph.io +get.app +get.dev +get.how +get.page +getastrill.com +getcloak.com +getfoxyproxy.org +getgom.com +geti2p.net +getlantern.org +getmalus.com +getmdl.io +getoutline.org +getsession.org +getsync.com +gettr.com +gettyimages.ae +gettyimages.ca +gettyimages.de +gettyimages.hk +gettyimages.in +gettyimages.it +gettyimages.us +getuploader.com +gfsale.com +gfw.press +gfw.report +gfwatch.org +gfwbao.com +ggpht.com +ggssl.com +ghidra-sre.org +ghostpath.com +ghut.org +giantessnight.com +giga-web.jp +girlbanker.com +git.io +gitbook.io +github.blog +github.com +github.io +githubassets.com +githubcopilot.com +githubusercontent.com +gitlab.net +gizlen.net +gjczz.com +glarity.app +glass8.eu +global.ssl.fastly.net +globaljihad.net +globalrescue.net +globalvoices.org +globalvoicesonline.org +globalvpn.net +glorystar.me +glype.com +gmail.com +gmgard.com +gmgn.ai +gmodules.com +gmp4.com +gnci.org.hk +gnews.org +go-to-zlibrary.se +go141.com +go5.dev +goagent.biz +godaddy.com +godfootsteps.org +godoc.org +gofundme.com +gohappy.com.tw +gojet.krtco.com.tw +golang.org +goldbetsports.com +golden-ages.org +goldeneyevault.com +goldenfrog.com +goldwave.com +gongm.in +goo.gl +goo.ne.jp +gooday.xyz +goodhope.school +goodnewsnetwork.org +goodreaders.com +goodreads.com +goofind.com +google.ac +google.ad +google.ae +google.af +google.ai +google.al +google.am +google.as +google.at +google.az +google.ba +google.be +google.bf +google.bg +google.bi +google.bj +google.bs +google.bt +google.by +google.ca +google.cat +google.cd +google.cf +google.cg +google.ch +google.ci +google.cl +google.cm +google.cn +google.co.ao +google.co.bw +google.co.ck +google.co.cr +google.co.id +google.co.il +google.co.in +google.co.jp +google.co.ke +google.co.kr +google.co.ls +google.co.ma +google.co.mz +google.co.nz +google.co.th +google.co.tz +google.co.ug +google.co.uk +google.co.uz +google.co.ve +google.co.vi +google.co.za +google.co.zm +google.co.zw +google.com +google.com.af +google.com.ag +google.com.ai +google.com.ar +google.com.au +google.com.bd +google.com.bh +google.com.bn +google.com.bo +google.com.br +google.com.bz +google.com.co +google.com.cu +google.com.cy +google.com.do +google.com.ec +google.com.eg +google.com.et +google.com.fj +google.com.gh +google.com.gi +google.com.gt +google.com.hk +google.com.jm +google.com.kh +google.com.kw +google.com.lb +google.com.ly +google.com.mm +google.com.mt +google.com.mx +google.com.my +google.com.na +google.com.nf +google.com.ng +google.com.ni +google.com.np +google.com.om +google.com.pa +google.com.pe +google.com.pg +google.com.ph +google.com.pk +google.com.pr +google.com.py +google.com.qa +google.com.sa +google.com.sb +google.com.sg +google.com.sl +google.com.sv +google.com.tj +google.com.tr +google.com.tw +google.com.ua +google.com.uy +google.com.vc +google.com.vn +google.cv +google.cz +google.de +google.dev +google.dj +google.dk +google.dm +google.dz +google.ee +google.es +google.eu +google.fi +google.fm +google.fr +google.ga +google.ge +google.gg +google.gl +google.gm +google.gp +google.gr +google.gy +google.hk +google.hn +google.hr +google.ht +google.hu +google.ie +google.im +google.iq +google.is +google.it +google.it.ao +google.je +google.jo +google.kg +google.ki +google.kz +google.la +google.li +google.lk +google.lt +google.lu +google.lv +google.md +google.me +google.mg +google.mk +google.ml +google.mn +google.ms +google.mu +google.mv +google.mw +google.mx +google.ne +google.nl +google.no +google.nr +google.nu +google.org +google.pl +google.pn +google.ps +google.pt +google.ro +google.rs +google.ru +google.rw +google.sc +google.se +google.sh +google.si +google.sk +google.sm +google.sn +google.so +google.sr +google.st +google.td +google.tg +google.tk +google.tl +google.tm +google.tn +google.to +google.tt +google.us +google.vg +google.vn +google.vu +google.ws +googleapis.com +googleapps.com +googlearth.com +googleartproject.com +googleblog.com +googlebot.com +googlechinawebmaster.com +googlecode.com +googlecommerce.com +googledomains.com +googledrive.com +googleearth.com +googlefiber.net +googlegroups.com +googlehosted.com +googleideas.com +googleinsidesearch.com +googlemail.com +googlemashups.com +googlepagecreator.com +googleplay.com +googleplus.com +googlescholar.com +googlesource.com +googleusercontent.com +googlevideo.com +googleweblight.com +googlezip.net +gopetition.com +goreforum.com +goregrish.com +gospelherald.com +gotdns.ch +gotquestions.org +gotrusted.com +gotw.ca +gov.ir +gov.taipei +gov.tw +grammaly.com +graph.org +graphis.ne.jp +graphql.org +gravatar.com +greasyfork.org +greatfire.org +greatfire.us7.list-manage.com +greatfirevpn.com +greatfirewallofchina.org +greenpeace.org +greenvpn.net +grindr.com +grok.com +grokipedia.com +ground.news +gsearch.media +gsp.target.com +gstatic.com +gtricks.com +gtv.org +gtv1.org +gu-chu-sum.org +guaguass.com +guishan.org +gumroad.com +gunsamerica.com +gutteruncensored.com +gvlib.com +gvm.com.tw +gvt1.com +gvt3.com +gwins.org +gwtproject.org +gzone-anime.info +h-china.org +h-moe.com +hackmd.io +hackthatphone.net +haijiao.com +haiwaikan.com +hakkatv.org.tw +halktv.com.tr +hanime.tv +hanime1.me +hardsextube.com +hautelook.com +hautelookcdn.com +hbg.com +hbo.com +hbomax.com +hdtvb.net +hdzog.com +heartyit.com +hec.su +hecaitou.net +hechaji.com +heeact.edu.tw +hegre-art.com +helixstudios.net +helloandroid.com +helloqueer.com +help.byspotify.com +helpeachpeople.com +helpster.de +hembed.com +heqinglian.net +heritage.org +herokuapp.com +herominers.com +hexieshe.com +hexieshe.xyz +hexxeh.net +heyuedi.com +hicairo.com +hiccears.com +hidden-advent.org +hide.me +hideipvpn.com +hideman.net +hidemy.name +hidemyass.com +hidemycomp.com +highrockmedia.com +hiitch.com +hikinggfw.org +himalayan-foundation.org +himemix.com +hindustantimes.com +hinet.net +hitbtc.com +hitomi.la +hiveon.net +hk-pub.com +hk.gradconnection.com +hk.jiepang.com +hk01.com +hka8964.wordpress.com +hkanews.wordpress.com +hkbookcity.com +hkchronicles.com +hkcnews.com +hkcoc.com +hkcoc.weather.com.hk +hkdc.us +hket.com +hkfaa.com +hkgalden.com +hkgolden.com +hkgpao.com +hklts.org.hk +hkmap.live +hkopentv.com +hkpeanut.com +hkreporter.com +hmoegirl.com +hmvdigital.ca +hmvdigital.com +hnjhj.com +hojemacau.com.mo +hola.com +hola.org +hole.thu.monster +holyspiritspeaks.org +home.saxo +homedepot.com +homeservershow.com +hongkong.fandom.com +hongkongfp.com +hongzhi.li +honven.xyz +hootsuite.com +hoover.org +hoovers.com +hornytrip.com +horrorporn.com +hostloc.com +hotair.com +hotcoin.com +hotspotshield.com +hottg.com +hotvpn.com +howtoforge.com +hoxx.com +hoy.tv +hpjav.com +hqcdp.org +hqjapanesesex.com +hqsbnet.wordpress.com +hqsbonline.wordpress.com +hrichina.org +hrntt.org +hrw.org +hsex.men +hsjp.net +hsselite.com +hst.net.tw +ht.ly +htkou.net +htl.li +html5rocks.com +htx.com +huaglad.com +huanghuagang.org +huaren.us +huashangnews.com +huayuworld.org +hudatoriq.web.id +hudson.org +huffingtonpost.com +huffpost.com +huggingface.co +hugoroy.eu +huhaitai.com +huhamhire.com +huhangfei.com +hulu.com +huluim.com +humanparty.me +humanrightspressawards.org +hung-ya.com +huobi.co +huobi.com +huobi.li +huobi.me +huobi.pro +huobi.sc +huobipool.com +huobipro.com +huping.net +hustlercash.com +hutianyi.net +hwayue.org.tw +hxwk.org +hybrid-analysis.com +hyperbeam.com +hyperrate.com +hypothes.is +i-scmp.com +i.111666.best +i.lithium.com +i2p2.de +i818hk.com +iam.soy +iask.ca +iavian.net +ibvpn.com +icedrive.net +icij.org +icl-fi.org +icoco.com +iconpaper.org +icu-project.org +id.heroku.com +idcflare.com +identi.ca +idiomconnection.com +idope.se +ifan.cz.cc +ifcss.org +ifreechina.wordpress.com +ifreewares.com +ift.tt +igcd.net +igfw.net +igoogle.com +igvita.com +iicns.com +iipdigital.usembassy.gov +ilbe.com +ilhamtohtiinstitute.org +illawarramercury.com.au +illusionfactory.com +ilove80.be +ilovelongtoes.com +im88.tw +imagefap.com +imageflea.com +imageglass.org +images-gaytube.com +images.prismic.io +imageshack.us +imagevenue.com +imagezilla.net +imago-images.com +imb.org +img.dlsite.jp +img.ly +img.picgo.net +imgasd.com +imgchili.net +imgur.com +imkev.com +imlive.co +improd.works +incloak.com +incredibox.fr +independent.co.uk +india.com +indiablooms.com +indianarrative.com +indiandefensenews.in +indiatoday.in +indiemerch.com +inews-api.tvb.com +info-graf.fr +infura.io +inherit.live +initiativesforchina.org +inkbunny.net +inkui.com +inmediahk.net +inoreader.com +inote.tw +insecam.org +inside.com.tw +insidevoa.com +instagram.com +institut-tibetain.org +interactivebrokers.com +internet.org +internetfreedom.org +internetpopculture.com +interseclab.org +inthenameofconfuciusmovie.com +investigating.wordpress.com +investing.com +invidio.us +inxian.com +ipdefenseforum.com +ipfire.org +ipfs.4everland.io +ipfs.io +iphone4hongkong.com +iphonetaiwan.org +iphonix.fr +ipicture.ru +ipify.org +ipjetable.net +iportal.me +ippotv.com +ipredator.se +iptvbin.com +ipvanish.com +irangov.ir +irna.ir +ironpython.net +ironsocket.com +isaacmao.com +isc.sans.edu +isgreat.org +ishr.ch +islam.org.hk +islamhouse.com +ismaelan.com +ismprofessional.net +israbox.com +issues.chromium.org +issuu.com +isupportuyghurs.org +italiatibet.org +itasoftware.com +itch.io +itemfix.com +itiger.com +itshidden.com +itweet.net +iuhrdf.org +ivacy.com +ivonblog.com +ivpn.net +iwara.tv +ixquick.com +iyouport.com +iyouport.org +j.mp +jable.tv +jamestown.org +jamyangnorbu.com +jan.ai +japan-whores.com +japanhdv.com +japantimes.co.jp +jav321.com +javakiba.org +javbus.com +javdb.com +javfinder.ai +javfor.me +javhub.net +javhuge.com +javlibrary.com +javmobile.net +javseen.com +jcpenney.com +jex.com +jgoodies.com +jhelab.org +jiangweiping.com +jiaoyou8.com +jifangge.com +jihadology.net +jiji.com +jims.net +jingpin.org +jinrizhiyi.news +jintian.net +jinx.com +jitouch.com +jkb.cc +jma.go.jp +jmsc.hku.hk +jmscult.com +joachims.org +jobnewera.wordpress.com +joinclubhouse.com +joinmastodon.org +jornaldacidadeonline.com.br +journalofdemocracy.org +jpl.nasa.gov +jsdelivr.net +jtvnw.net +jukujo-club.com +juliepost.com +juliereyc.com +junauza.com +juoaa.com +justhost.ru +justmysocks.net +justmysocks1.net +justmysockscn.com +juziyue.com +ka-wai.com +kadokawa.co.jp +kagyu.org.za +kagyuoffice.org +kagyuoffice.org.tw +kakao.com +kanald.com.tr +kannewyork.com +kanshifang.com +kantie.org +kaotic.com +karayou.com +kawaiikawaii.jp +kawase.com +kb.monitorware.com +kebrum.com +kendatire.com +kenengba.com +kepard.com +kex.com +keycdn.com +khatrimaza.org +kichiku-doujinko.com +kik.com +killwall.com +kindle4rss.com +kindleren.com +kingdomsalvation.org +kingkong.com.tw +kingstone.com.tw +kinmen.org.tw +kinmen.travel +kinokuniya.com +kiwi.kz +kk-whys.co.jp +kkbox.com +kknews.cc +knowyourmeme.com +kobo.com +kobobooks.com +kompozer.net +konachan.com +koolsolutions.com +koornk.com +koranmandarin.com +kpkuang.org +kqes.net +kraken.com +kspcoin.com +ktzhk.com +kuaichedao.co +kucoin.com +kukuku.uk +kurtmunger.com +kwcg.ca +kwongwah.com.my +kxsw.life +kzaobao.com +kzeng.info +lab.skk.moe +labiennale.org +lagranepoca.com +lala.im +lama.com.tw +lamayeshe.com +lamnia.co.uk +landofhope.tv +lantern.io +laogai.org +laogairesearch.org +laqingdan.net +larsgeorge.com +lastcombat.com +lastfm.es +lausan.hk +lbank.info +ldplayer.net +ldplayer.tw +le-vpn.com +leafyvpn.net +lecloud.net +ledger.com +left21.hk +legra.ph +leisurepro.com +lematin.ch +lenwhite.com +lesoir.be +letscorp.net +lexica.art +lhakar.org +li.taipei +liangyou.net +liangzhichuanmei.com +liaowangxizang.net +liberal.org.hk +libertysculpturepark.com +libertytimes.com.tw +library-access.sk +library.usc.cuhk.edu.hk +libredd.it +lifemiles.com +lighten.org.tw +lighti.me +lightnovel.cn +lightyearvpn.com +lih.kg +lihkg.com +like.com +lilaoshibushinilaoshi.com +line-apps.com +line-scdn.net +line.me +line.naver.jp +linear-abematv.akamaized.net +lingualeo.com +lingvodics.com +link-o-rama.com +linkedin.com +linktr.ee +linux.do +linux.org.hk +liquiditytp.com +liquidvpn.com +listennotes.com +listentoyoutube.com +litenews.hk +liuxiaobo.net +liuxiaotong.com +livecoin.net +liveleak.com +livemint.com +livestream.com +livevideo.com +livingstream.com +lmarena.ai +localbitcoins.com +localdomain.ws +lockestek.com +login.target.com +logos.com.hk +longtermly.net +longtoes.com +lookpic.com +looktoronto.com +lovart.ai +lovetvshow.com +lpsg.com +lrfz.com +lrip.org +lsd.org.hk +lsm.org +lsmchinese.org +lsmkorean.org +lt.sntp.uk +ltn.com.tw +luckydesigner.space +luckymobile.ca +ludepress.com +lupm.org +lushstories.com +lvhai.org +lvv2.com +lyfhk.net +lzjscript.com +lzmtnews.org +m.hkgalden.com +m.me +m.moegirl.org +macgamestore.com +mad-ar.ch +madewithcode.com +madonna-av.com +madou.club +madrau.com +madthumbs.com +mahjongsoul.com +main-ecnpaper-economist.content.pugpig.com +maiplus.com +makemymood.com +mandiant.com +mangabz.com +mangafox.com +mangafox.me +mangmang.run +manta.com +manus.im +manyvoices.news +marc.info +martau.com +martsangkagyuofficial.org +marxist.net +marxists.org +mash.to +mastodon.cloud +mastodon.host +mastodon.online +mastodon.social +mastodon.xyz +matainja.com +material.io +matome-plus.com +matome-plus.net +matrix.org +matters.news +matters.town +matthewdgreen.wordpress.com +mattwilcox.net +maven.neoforged.net +mcadforums.com +mcaf.ee +mcusercontent.com +md-t.org +me.me +me.ns.ci +meansys.com +media.nu.nl +mediachinese.com +mediafreakcity.com +mediawiki.org +medium.com +meee.com.tw +mega.co.nz +mega.io +mega.nz +megalodon.jp +megaproxy.com +megurineluka.com +meizhong.blog +meizhong.report +memehk.com +memes.tw +mercari.com +mercari.jp +mercatox.com +mercdn.net +mercyprophet.org +mergersandinquisitions.com +meridian-trust.org +meripet.com +merit-times.com.tw +messenger.com +meta.com +metafilter.com +metamask.io +metart.com +metarthunter.com +meteorshowersonline.com +metro.taipei +metrolife.ca +metroradio.com.hk +mewe.com +mfxmedia.com +mgoon.com +mgstage.com +mh4u.org +microvpn.com +mihua.org +mij.rip +mikanani.me +mike.cz.cc +mikesoltys.com +mindrolling.org +mingdemedia.org +minghui-school.org +minghui.or.kr +minghui.org +minghuiyw.wordpress.com +mingjinglishi.com +mingjingnews.com +mingjingtimes.com +mingpao.com +mingpaocanada.com +mingpaomonthly.com +mingpaonews.com +mingpaony.com +mingpaosf.com +mingshengbao.com +minhhue.net +miningpoolhub.com +ministrybooks.org +minzhuzhongguo.org +miraheze.org +miroguide.com +mirror.xyz +mirrorbooks.com +mirrormedia.mg +missav.com +missav.ws +mistral.ai +mitbbs.com +miuipolska.pl +mixero.com +mixi.jp +mixx.com +mizzmona.com +mji.rip +mjj.rip +mjlsh.usc.cuhk.edu.hk +mlc.ai +mlzs.work +mmaaxx.com +mo.nightlife141.com +mobatek.net +mobile01.com +mobileways.de +moby.to +mod.io +modernchinastudies.org +moeerolibrary.com +moeshare.cc +mog.com +mohu.club +mohu.rocks +mojim.com +momoshop.com.tw +mondex.org +money-link.com.tw +moneydj.com +monica.im +monitorchina.org +monocloud.me +monster.com +moodyz.com +moon.fm +moonbbs.com +moonbingo.com +moptt.tw +moresci.sale +morningsun.org +mos.ru +mosavi.io +motherless.com +movements.org +moviefap.com +mpettis.com +mpfinance.com +mpinews.com +mrtweet.com +msa-it.org +msha.gov +mstdn.social +mswe1.org +mthruf.com +mubi.com +mullvad.net +multiply.com +musixmatch.com +muzi.com +muzi.net +muzu.tv +mvg.jp +my-private-network.co.uk +my.pcloud.com +myaudiocast.com +mybet.com +mychinanews.com +mycnnews.com +myeclipseide.com +myiphide.com +myjs.tw +mykomica.org +mymoe.moe +myparagliding.com +mypikpak.com +mypopescu.com +myspacecdn.com +mytvsuper.com +mywife.cc +naacoalition.org +naitik.net +nakedsecurity.sophos.com +nakido.com +nalandabodhi.org +nalandawest.org +namu.wiki +nanopool.org +nanyang.com +nanyangpost.com +nat.moe +national-lottery.co.uk +nationalawakening.org +nationalinterest.org +nationalreview.com +nationwide.com +naughtyamerica.com +naver.com +navyfamily.navy.mil +navyreserve.navy.mil +nbcnews.com +nbtvpn.com +nbyy.tv +nchrd.org +ncn.org +ndi.org +nekoslovakia.net +neo-miracle.com +neowin.net +nephobox.com +netalert.me +netflav.com +netflix.com +netflix.net +netlify.app +netme.cc +netsarang.com +newcenturymc.com +newchen.com +newhighlandvision.com +newindianexpress.com +newmitbbs.com +news.ebc.net.tw +news.mt.co.kr +news.seehua.com +news.tvbs.com.tw +news.ycombinator.com +news1.kr +news18.com +newsancai.com +newsblur.com +newsmax.com +newstamago.com +newstapa.org +newstatesman.com +newsweek.com +newtalk.tw +newthuhole.com +newyorker.com +nexon.com +nextdigital.com.hk +nexton-net.jp +nexttv.com.tw +nf.id.au +nflxext.com +nflximg.com +nflximg.net +nflxso.net +nflxvideo.net +nftstorage.link +nga.mil +nhentai.net +nic.cz.cc +nic.gov +nicovideo.jp +nightswatch.top +nikke-en.com +nikke-jp.com +nikke-kr.com +nikke.hotcool.tw +nikkei.com +ninjaproxy.ninja +nirsoft.net +nitter.cc +nitter.net +niu.moe +niusnews.com +njactb.org +nlfreevpn.com +nmsl.website +nnews.eu +nobel.se +nodeseek.com +nokogiri.org +nokola.com +nordstrom.com +nordstromimage.com +nordstromrack.com +nordvpn.com +nos.nl +notepad-plus-plus.org +nottinghampost.com +now.com +nownews.com +noxinfluencer.com +npa.go.jp +npnt.me +npsboost.com +nradio.me +nrk.no +ntd.tv +ntdtv.com +ntdtv.com.tw +ntdtv.cz +nuexpo.com +nurgo-software.com +nusatrip.com +nutaku.net +nutsvpn.work +nuuvem.com +nvdst.com +nvtongzhisheng.org +nyaa.eu +nyaa.si +nybooks.com +nypost.com +nyt.com +nytcn.me +nytco.com +nyti.ms +nytimes.com +nytimes.map.fastly.net +nytimg.com +nytstyle.com +o3o.ca +oanda.com +oann.com +obyte.org +october-review.org +octocaptcha.com +oculus.com +oculuscdn.com +odysee.com +oex.com +officeoftibet.com +ofile.org +ogaoga.org +ogate.org +ohmyrss.com +ok.ru +okayfreedom.com +okcoin.com +okex.com +okk.tw +oklink.com +okpool.me +okx.com +old.honeynet.org +olehdtv.com +olelive.com +olevod.com +olumpo.com +omct.org +omni7.jp +omnitalk.com +omnitalk.org +omny.fm +on.cc +on2.com +onapp.com +one.one.one.one +onedrive.com +onedrive.live.com +onejav.com +onevps.com +onion.city +onion.ly +online.recoveryversion.org +onlineyoutube.com +onlygayvideo.com +onlytweets.com +onthehunt.com +ontrac.com +oojj.de +ooni.io +ooni.org +open.firstory.me +openai.com +openart.ai +opencritic.com +opendemocracy.net +openid.net +openleaks.org +opensea.io +openstreetmap.org +opentech.fund +openvpn.net +openvpn.org +openwebster.com +opus-gaming.com +ordns.he.net +oricon.co.jp +orient-doll.com +orientaldaily.com.my +orn.jp +osfoora.com +osmand.net +otcbtc.com +otto.de +ourdearamy.com +oursteps.com.au +ourtv.hk +overcast.fm +overdaily.org +overplay.net +oversea.istarshine.com +ovpn.com +ow.ly +owl.li +owltail.com +oxfordscholarship.com +ozvoice.org +pachosting.com +pacom.mil +pacopacomama.com +page.link +pages.dev +paimon.moe +pancakeswap.finance +pandafan.pub +pandapow.co +pandavpn-jp.com +pandavpnpro.com +pandora.com +panoramio.com +pao-pao.net +parkansky.com +parler.com +parse.com +parsevideo.com +partnerstack.xyz +passion.com +paste.ee +pastie.org +patreon.com +patreonusercontent.com +pawoo.net +paxful.com +payments-jp.amazon.com +pbs.org +pbworks.com +pbxes.com +pbxes.org +pcgamestorrents.com +pcij.org +pct.org.tw +pdproxy.com +pds.nasa.gov +pdst.fm +peace.ca +peing.net +pekingduck.org +pemulihan.or.id +pen.io +pendrivelinux.com +pentoy.hk +peoplenews.tw +peopo.org +perfect-privacy.com +periscope.tv +perplexity.ai +pewresearch.org +phayul.com +phmsociety.org +phncdn.com +phosphation13.rssing.com +photodharma.net +photofocus.com +photonmedia.net +piaotia.com +picacomic.com +picacomiccn.com +picasaweb.com +picsart.com +picturedip.com +picuki.com +pigav.com +pimg.tw +pin-cong.com +pin6.com +pincong.rocks +ping.fm +pinimg.com +pinoy-n.com +pinterest.at +pinterest.ca +pinterest.cl +pinterest.co.uk +pinterest.com +pinterest.com.au +pinterest.com.mx +pinterest.de +pinterest.es +pinterest.fr +pinterest.ie +pinterest.it +pinterest.jp +pinterest.nz +pinterest.ph +pinterest.pt +pinterest.se +pixeldrain.com +pixelqi.com +pixiv.net +pixiv.org +pixivsketch.net +pixnet.net +pki.goog +pkqjiasu.com +pkuanvil.com +placemix.com +play-asia.com +playboy.com +playboyplus.com +player.fm +playno1.com +playpcesor.com +plexvpn.pro +plurk.com +plus.codes +pmatehunter.com +po2b.com +podbean.com +podcast.co +podictionary.com +podwise.ai +poe.com +points-media.com +pokerstars.com +pokerstars.net +politicalchina.org +poloniex.com +polymarket.com +polymer-project.org +polymerhk.com +poolbinance.com +poolin.com +popai.pro +popvote.hk +popxi.click +popyard.org +pornhd.com +pornhub.com +pornhubdeutsch.net +pornmate.com +pornrapidshare.com +pornsharing.com +pornstarbyface.com +pornstarclub.com +porntvblog.com +poskotanews.com +post76.com +post852.com +posts.careerengine.us +potato.im +potatso.com +potvpn.com +pourquoi.tw +power.com +powerapple.com +powercx.com +ppy.sh +prayforchina.net +prcleader.org +premproxy.com +presentation.new +presentationzen.com +president.ir +presidentlee.tw +prestige-av.com +primevideo.com +prism-break.org +pritunl.com +privacybox.de +privacyguides.org +private.com +privateinternetaccess.com +privatepaste.com +privatetunnel.com +privatevpn.com +privoxy.org +procopytips.com +project-syndicate.org +prompthero.com +prosiben.de +proton.me +protonvpn.com +provpnaccounts.com +proxfree.com +proxomitron.info +proxpn.com +proxynetwork.org.uk +proxz.com +proyectoclubes.com +pscp.tv +pshvpn.com +psiphon.ca +psiphon3.com +pstatic.net +pt.im +ptt.cc +pttgame.com +ptwxz.com +pubu.com.tw +puffinbrowser.com +pullfolio.co +pure18.com +pureconcepts.net +puredns.org +pureinsight.org +purepdf.com +purevpn.com +purpose.nike.com +pursuestar.com +putty.org +pximg.net +python.com.tw +qbittorrent.org +qgirl.com.tw +qi-gong.me +qianbai.tw +qiandao.today +qianglie.com +qiangwaikan.com +qiangyou.org +qianmo.tw +qiwen.lu +qmp4.com +qoos.com +qq.co.za +qstatus.com +qtrac.eu +questvisual.com +quitccp.org +quiz.directory +quora.com +quoracdn.net +quran.com +qz.com +r-pool.net +r0.ru +r10s.jp +r18.com +radiko.jp +radio-canada.ca +radio-en-ligne.fr +radio.co +radio.garden +radioaustralia.net.au +radiohilight.net +radiojar.com +radioline.co +radiovaticana.org +radiovncr.com +radmin-vpn.com +rael.org +raggedbanner.com +raidcall.com.tw +raindrop.io +raizoji.or.jp +rakuten.co.jp +ramcity.com.au +rapidmoviez.com +rapidvpn.com +rarbgprx.org +rateyourmusic.com +rationalwiki.org +raw.githack.com +rawgit.com +rawgithub.com +rawstory.com +rcam.target.com +rcinet.ca +rd.com +reabble.com +read01.com +readingtimes.com.tw +readmoo.com +readydown.com +realcourage.org +realitykings.com +reason.com +recordedfuture.com +recoveryversion.com.tw +red-lang.org +redbubble.com +redchinacn.net +redd.it +reddit.com +reddithelp.com +redditlist.com +redditmedia.com +redditspace.com +redditstatic.com +redhotlabs.com +referer.us +reflectivecode.com +relay.firefox.com +religionnews.com +renminbao.com +rentry.co +renyurenquan.org +resilio.com +resistchina.org +retweetrank.com +reuters.com +reutersmedia.net +rfa.org +rferl.org +rfi.fr +rfi.my +riku.me +riseup.net +ritter.vg +rixcloud.com +rixcloud.us +rlwlw.com +rmbl.ws +roblox.com +robustnessiskey.com +rocket-inc.net +rocket.chat +rocksdb.org +rojo.com +rolfoundation.org +rolia.net +rolsociety.org +ronjoneswriter.com +rou.video +rsdlmonitor.com +rsf-chinese.org +rsf.org +rsshub.app +rssmeme.com +rtalabel.org +rthk.hk +rthk.org.hk +rti.org.tw +rti.tw +rtm.tnt-ea.com +rule34.xxx +rule34video.com +rumble.com +rustdesk.com +rusvpn.com +ruten.com.tw +rutracker.net +rutracker.org +rxhj.net +s-cute.com +s.yimg.com +s3-ap-northeast-1.amazonaws.com +sacks.com +sacom.hk +sadistic-v.com +sadpanda.us +safechat.com +safeguarddefenders.com +safervpn.com +sagernet.org +saintyculture.com +sakuralive.com +salvation.org.hk +sankakucomplex.com +sankei.com +sanmin.com.tw +savethedate.foo +savethesounds.info +savetibet.de +savetibet.org +savetibetstore.org +saveuighur.org +sbme.me +sbti.unun.dev +scache.vzw.com +scache1.vzw.com +scache2.vzw.com +schema.org +scmp.com +scramble.io +scratch.mit.edu +scribd.com +scriptspot.com +search.aol.com +search.com +search.xxx +search.yahoo.co.jp +searx.me +seattlefdc.com +secretchina.com +secretgarden.no +secretsline.biz +secure.hustler.com +secure.logmein.com +secure.shadowsocks.nu +secureservercdn.net +securetunnel.com +securityinabox.org +securitykiss.com +seed4.me +seevpn.com +seezone.net +sehuatang.net +sehuatang.org +sensortower.com +sesawe.net +sethwklein.net +setn.com +sevenload.com +sex.com +sex3.com +sex8.cc +sexinsex.net +sf.net +sfshibao.com +sftuk.org +shadeyouvpn.com +shadowsocks.be +shadowsocks.com.hk +shadowsocks.org +shahit.biz +share-videos.se +share.america.gov +sharecool.org +shattered.io +sheet.new +sheets.new +shellfire.de +shenyunperformingarts.org +shenyunshop.com +shenzhoufilm.com +shenzhouzhengdao.org +shiksha.com +shitjournal.org +shixiao.org +shizhao.org +shodanhq.com +shooshtime.com +shopee.tw +shopping.yahoo.co.jp +showwe.tw +shutterstock.com +shwchurch.org +shwchurch3.com +sidelinesnews.com +signal.org +silvergatebank.com +simbolostwitter.com +simianx.ai +simplecd.me +simplecd.org +simpleswap.io +simplex.chat +sina.com.hk +singaporepools.com.sg +singlelogin.se +singtao.com +singtaousa.com +sinoants.com +sinoca.com +sinocast.com +sinoinsider.com +sipml5.org +sis001.com +site.new +sitekreator.com +sitemaps.org +sites.new +six-degrees.io +sketchappsources.com +skimtube.com +skybet.com +skyvegas.com +skyxvpn.com +slacker.com +slashine.onl +sleazyfork.org +slheng.com +slickvpn.com +slides.com +slides.new +slideshare.net +slutmoonbeam.com +sm-miracle.com +smartdnsproxy.com +smh.com.au +smn.news +snapseed.com +sndcdn.com +sobees.com +soc.mil +social.datalabour.com +social.edu.ci +socialblade.com +socks-proxy.net +sockslist.net +socrec.org +softether-download.com +softether.org +softfamous.com +softwarebychuck.com +softwaredownload.gitbooks.io +sogclub.com +sogrady.me +soh.tw +sohcradio.com +sohfrance.org +solana.com +solarsystem.nasa.gov +solscan.io +solv.finance +somee.com +songjianjun.com +sora.com +sorting-algorithms.com +sos.org +sosad.fun +sosreader.com +soubory.com +soulcaliburhentai.net +soundcloud.com +soundofhope.org +soundon.fm +soup.io +south-plus.net +south-plus.org +southmongolia.org +southnews.com.tw +southpark.cc.com +sowers.org.hk +spaces.hightail.com +spacex.com +spankbang.com +sparkpool.com +spatial.io +spb.com +speakerdeck.com +speedcat.me +speedify.com +spencertipping.com +spendee.com +spicevpn.com +spideroak.com +spiderpool.com +sports.williamhill.com +spotflux.com +spotify.com +spreadsheet.new +spreadshirt.es +spreaker.com +spring4u.info +springboardplatform.com +springwood.me +sproutcore.com +squirrelvpn.com +ss-link.com +ss7.vzw.com +ssglobal.co +ssl.webpack.de +sspanel.net +ssr.tools +ssrshare.com +ssrshare.us +ssrtool.com +sstm.moe +sstmlt.moe +sstmlt.net +standard.co.uk +standupfortibet.org +standwithhk.org +starp2p.com +startpage.com +startuplivingchina.com +static-economist.com +static.pocketcasts.com +static.shemalez.com +staticflickr.com +stboy.net +stc.com.sa +steamcommunity.com +steamladder.com +steamstatic.com +steel-storm.com +steemit.com +steganos.com +stephaniered.com +sthoo.com +stitcher.com +stoptibetcrisis.net +storage.yandex.net +storagenewsletter.com +store.steampowered.com +storj.io +storm.mg +storry.tv +stoweboyd.com +straitstimes.com +straplessdildo.com +streamable.com +streamate.com +streamingthe.net +strongvpn.com +studentsforafreetibet.org +stumbleupon.com +subhd.tv +substack.com +suche.gmx.net +sugarsync.com +sugumiru18.com +suissl.com +sujiatun.wordpress.com +sumrando.com +sundayguardianlive.com +sunmedia.ca +suno.ai +suno.com +sunporno.com +supchina.com +superpages.com +supervpn.net +superzooi.com +suprememastertv.com +surfeasy.com +surfeasy.com.au +surfshark.com +surrenderat20.net +swagbucks.com +swapspace.co +swissinfo.ch +swissvpn.net +switch1.jp +switchvpn.net +sydneytoday.com +sylfoundation.org +synapse.org +syncback.com +synergyse.com +syosetu.com +t-g.com +t.co +t.me +t66y.com +taa-usa.org +taaze.tw +taedp.org.tw +tagwalk.com +tails.net +taipeisociety.org +taipeitimes.com +taisounds.com +taiwanhot.net +taiwanjustice.net +taiwanncf.org.tw +taiwannews.com.tw +taiwantt.org.tw +talkatone.com +talkboxapp.com +talkcc.com +talkonly.net +tanc.org +tanks.gg +taoism.net +tap.io +tapanwap.com +tapatalk.com +taptap.io +tardigrade.io +tarr.uspto.gov +taup.net +taweet.com +tbcollege.org +tbsec.org +tbsn.org +tbssqh.org +teachparentstech.org +technews.tw +techviz.net +teck.in +teco-hk.org +teco-mo.org +teddysun.com +tehrantimes.com +telega.one +telegra.ph +telegram.dog +telegram.me +telegram.org +telegram.space +telegramdownload.com +telesco.pe +tellapart.com +temu.com +tenor.com +tensorflow.org +tenzinpalmo.com +terabox.com +terobox.com +tew.org +textnow.com +textnow.me +tfc-taiwan.org.tw +tfhub.dev +tfiflve.com +tg-me.com +tg.dev +theatlantic.com +theatrum-belli.com +thebcomplex.com +theblaze.com +thebobs.com +thebodyshop-usa.com +thecenter.mit.edu +thechasernews.co.uk +thechinacollection.org +theconversation.com +thedalailamamovie.com +thediplomat.com +thedw.us +theepochtimes.com +thefacebook.com +thegay.com +thegioitinhoc.vn +theguardian.com +thehansindia.com +thehindu.com +thehun.net +theinitium.com +thenewslens.com +thepiratebay.org +theporndude.com +theportalwiki.com +theprint.in +thesaturdaypaper.com.au +thestandnews.com +thetatoken.org +thetibetpost.com +thetvdb.com +thewgo.org +thewirechina.com +theync.com +thinkchina.sg +thinkgeek.com +thinkingtaiwan.com +thinkwithgoogle.com +thirdmill.org +thisav.com +thomasbernhard.org +threadreaderapp.com +threads.com +threads.net +throughnightsfire.com +thuhole.com +thywords.com +tiananmenduizhi.com +tiananmenuniv.com +tiananmenuniv.net +tiandixing.org +tianti.io +tiantibooks.org +tibet-envoy.eu +tibet-initiative.de +tibet.com +tibet.net +tibet.nu +tibet.org +tibet.org.tw +tibet.to +tibet3rdpole.org +tibetaction.net +tibetanbuddhistinstitute.org +tibetancommunity.org +tibetancommunityuk.net +tibetanentrepreneurs.org +tibetanhealth.org +tibetanliberation.org +tibetansports.org +tibetanwomen.org +tibetanyouthcongress.org +tibetcorps.org +tibetexpress.net +tibetfocus.com +tibetfund.org +tibetgermany.de +tibethouse.jp +tibethouse.org +tibethouse.us +tibetmuseum.org +tibetnetwork.org +tibetoffice.ch +tibetoffice.com.au +tibetoffice.org +tibetonline.com +tibetonline.tv +tibetoralhistory.org +tibetpolicy.eu +tibetrelieffund.co.uk +tibetsociety.com +tibetsun.com +tibetsupportgroup.org +tibetswiss.ch +tibettelegraph.com +tibettimes.net +tibettruth.com +tibetwrites.org +tigervpn.com +tiktok.com +tiktokcdn-eu.com +tiktokcdn-us.com +tiktokcdn.com +tiktokv.com +tiktokv.us +tiltbrush.com +timdir.com +time.com +timesnownews.com +timesofindia.indiatimes.com +timtales.com +tinc-vpn.org +tineye.com +tingtalk.me +tiny.cc +tinychat.com +tinypaste.com +tinyurl.com +tipas.net +tkcs-collins.com +tl.gd +tma.co.jp +tmagazine.com +tmi.me +tmpp.org +tn1.shemalez.com +tn2.shemalez.com +tn3.shemalez.com +tnaflix.com +tnp.org +to-porno.com +togetter.com +token.im +tokenlon.im +tokyo-porn-tube.com +tokyocn.com +tomp3.cc +top.tv +top10vpn.com +topbtc.com +toppornsites.com +topsy.com +toptip.ca +toptoon.net +tor.eff.org +torguard.net +torlock.com +torproject.org +torrentgalaxy.to +torrentkitty.tv +torrentprivacy.com +torrentproject.se +torrenty.org +tortoisesvn.net +torvpn.com +tosh.comedycentral.com +totalvpn.com +tou.tv +tpi.org.tw +tracfone.com +tradingview.com +translate.goog +transparency.org +treemall.com.tw +trendsmap.com +tronscan.org +trouw.nl +trt.net.tr +truebuddha-md.org +trustwallet.com +truthsocial.com +tryheart.jp +tsdr.uspto.gov +tt1069.com +tttan.com +ttv.com.tw +ttvnw.net +tube8.com +tube911.com +tubeislam.com +tubepornclassic.com +tubewolf.com +tuidang.org +tukaani.org +tumblr.com +tumutanzi.com +tumview.com +tunein.com +tunein.streamguys1.com +tunnelbear.com +tunnelblick.net +tunnelr.com +tunsafe.com +turbobit.net +turbohide.com +turkistantimes.com +turntable.fm +tushycash.com +tuvpn.com +tuzaijidi.com +tv.com +tv.jtbc.joins.com +tvbanywhere.com +tvboxnow.com +tvunetworks.com +tw-blog.com +tw.jiepang.com +tw01.org +twapperkeeper.com +twaud.io +twblogger.com +tweepguide.com +tweepml.org +tweetbackup.com +tweetboard.com +tweetcs.com +tweetdeck.com +tweetedtimes.com +tweetphoto.com +tweetree.com +tweettunnel.com +tweetwally.com +tweez.net +twelve.today +twerkingbutt.com +twftp.org +twgov.tw +twgreatdaily.com +twibble.de +twibs.com +twicountry.org +twiends.com +twifan.com +twiffo.com +twiggit.org +twimg.com +twimg.edgesuite.net +twip.me +twipple.jp +twishort.com +twister.net.co +twitch.tv +twitchcdn.net +twitiq.com +twitlonger.com +twitoaster.com +twitonmsn.com +twitpic.com +twitstat.com +twitter.com +twitter.jp +twitter4j.org +twittercounter.com +twittergadget.com +twitterkr.com +twittermail.com +twitterrific.com +twittertim.es +twitturk.com +twitturly.com +twkan.com +twreporter.org +twt.tl +twtkr.com +twttr.com +tx.me +tycool.com +typepad.com +typeset.io +typora.io +u15.info +u9un.com +ua5v.com +ub0.cc +ubddns.org +uberproxy.net +uc-japan.org +uchicago.edu +udn.com +udn.com.tw +udomain.hk +uforadio.com.tw +uhdwallpapers.org +uhrp.org +uighur.nl +uku.im +ulop.net +ultrasurf.us +ultravpn.com +ultravpn.fr +unblock-us.com +unblock.cn.com +unblockdmm.com +unblocksit.es +uncyclopedia.hk +uncyclopedia.tw +underwoodammo.com +unholyknight.com +unirule.cloud +uniswap.org +unknownspace.org +unmineable.com +unseen.is +unstable.icu +unwire.hk +uocn.org +up.audio +upbit.com +updates.tdesktop.com +upghsbc.com +upmedia.mg +upornia.com +uproxy.org +uptodown.com +uraban.me +urbandictionary.com +urbansurvival.com +urchin.com +urlborg.com +urlparser.com +usacn.com +usaip.eu +uscardforum.com +uscg.mil +uscnpm.org +use.typekit.net +usercontent.goog +usfk.mil +usma.edu +usno.navy.mil +ustibetcommittee.org +ustream.tv +utopianpal.com +uujiasu.com +uukanshu.com +uupool.cn +uvwxyz.xyz +uwants.com +uyghur-j.org +uyghuraa.org +uyghuramerican.org +uyghurbiz.org +uyghurcongress.org +uyghurpen.org +uyghurstudies.org +uyghurtribunal.com +uygur.fc2web.com +uymaarip.com +v2.help +v2.hysteria.network +v2ex.com +v2fly.org +v2ray.com +v2raycn.com +valeursactuelles.com +vansky.com +vaticannews.va +vatn.org +vcf-online.org +vcfbuilder.org +vegas.williamhill.com +vegasred.com +venetianmacao.com +ventureswell.com +vercel.app +vern.cc +verybs.com +vevo.com +vewas.net +viber.com +victimsofcommunism.org +vid.me +vidble.com +video.aol.com +videobam.com +videomega.tv +videopress.com +vilanet.me +vilavpn.com +vimeo.com +vimeocdn.com +vimperator.org +vincnd.com +vine.co +vinniev.com +vip-enterprise.com +virtualrealporn.com +viu.com +viu.tv +vivaldi.com +vivthomas.com +vjav.com +vllcs.org +vmixcore.com +vmpsoft.com +vnet.link +voacambodia.com +voacantonese.com +voachinese.com +voachineseblog.com +voaindonesia.com +voanews.com +voatibetan.com +voatibetanenglish.com +vocaroo.com +vocus.cc +vod-abematv.akamaized.net +vod.wwe.com +voicettank.org +vot.org +vovo2000.com +voxer.com +vpl.bibliocommons.com +vpn.ac +vpn.cmu.edu +vpn.net +vpn.sv.cmu.edu +vpn4all.com +vpnaccount.org +vpnaccounts.com +vpncoupons.com +vpncup.com +vpndada.com +vpnforgame.net +vpngate.jp +vpngate.net +vpnhub.com +vpninja.net +vpnjack.com +vpnmaster.com +vpnmentor.com +vpnpick.com +vpnpop.com +vpnpronet.com +vpnproxymaster.com +vpnreactor.com +vpnreviewz.com +vpnsecure.me +vpnshazam.com +vpnshieldapp.com +vpntunnel.com +vpnuk.info +vpnunlimitedapp.com +vpnvip.com +vporn.com +vpsxb.net +vrchat.com +vrporn.com +vrsmash.com +vtunnel.com +vultryhw.com +w-pool.com +w3s.link +waffle1999.com +wainao.me +walletconnect.com +walletconnect.org +wallmama.com +wallpapercasa.com +wallsttv.com +wallzhihu.com +waltermartin.com +waltermartin.org +wanderinghorse.net +wangafu.net +wangjinbo.org +wango.org +want-daily.com +wanz-factory.com +warroom.org +waselpro.com +washingtonpost.com +watchinese.com +watchmygf.net +watchout.tw +wattpad.com +wav.tv +waveprotocol.org +waybig.com +waymo.com +wd.bible +wealth.com.tw +wearn.com +web.dev +web2project.net +webmproject.org +webpkgcache.com +webrtc.org +websdr.org +website.new +webwarper.net +wechatlawsuit.com +weebly.com +wefightcensorship.org +wego.here.com +weights.com +weijingsheng.org +weiming.info +weisuo.ws +welt.de +wemigrate.org +wengewang.org +wenxuecity.com +wenyunchao.com +wenzhao.ca +westca.com +westernwolves.com +westpoint.edu +wezone.net +wforum.com +whatblocked.com +whatbrowser.org +whats.new +whatsapp.com +whatsapp.net +whatsonweibo.com +wheelockslatin.com +whereiswerner.com +wheretowatch.com +whispersystems.org +whoer.net +whyx.org +widevine.com +wiki.gamerp.jp +wiki.jqueryui.com +wiki.metacubex.one +wiki.oauth.net +wiki.phonegap.com +wikibooks.org +wikidata.org +wikileaks.ch +wikileaks.com +wikileaks.de +wikileaks.eu +wikileaks.lu +wikileaks.org +wikileaks.pl +wikiless.funami.tech +wikimapia.org +wikimedia.org +wikinews.org +wikipedia.com +wikipedia.org +wikis.tw +wikisource.org +wikiunblocked.org +wikiversity.org +wikivoyage.org +wikiwand.com +wiktionary.org +willw.net +wilsoncenter.org +windscribe.com +wingamestore.com +wingy.site +wionews.com +wire.com +wiredbytes.com +wiredpen.com +wireguard.com +wisevid.com +wispbyte.com +withgoogle.com +withyoutube.com +witopia.net +wizcrafts.net +wjbk.org +wmflabs.org +wmfusercontent.org +wn.com +wnacg.com +wnacg.org +wo.tc +wo3ttt.wordpress.com +woeser.com +wokar.org +wolfax.com +wombo.ai +woolyss.com +woopie.jp +woopie.tv +wordpress.com +work2icu.org +workatruna.com +workerempowerment.org +workers.dev +worldvpn.net +wowgirls.com +wowhead.com +wowporn.com +woyaolian.org +wp.com +wpoforum.com +writesonic.com +wsj.com +wsj.net +wufafangwen.com +wufi.org.tw +wujieliulan.com +wunderground.com +wuw.red +wwitv.com +www.ajsands.com +www.antd.org +www.aolnews.com +www.clashverge.dev +www.cmoinc.org +www.dmm.com +www.eastturkistan.net +www.gmiddle.com +www.gmiddle.net +www.hoyolab.com +www.hustlercash.com +www.idlcoyote.com +www.kindleren.com +www.lorenzetti.com.br +www.m-sport.co.uk +www.monlamit.org +www.moztw.org +www.msn.com +www.oxid.it +www.powerpointninja.com +www.s4miniarchive.com +www.shadowsocks.com +www.skype.com +www.tablesgenerator.com +www.taiwanonline.cc +www.wan-press.org +www.websnapr.com +www.xicons.org +www.zensur.freerk.com +wxw.cat +wxw.moe +x-art.com +x-berry.com +x-wall.org +x.ai +x.co +x.com +x.company +x3guide.com +xbabe.com +xbookcn.com +xbtce.com +xcafe.in +xcancel.com +xcity.jp +xdaforums.com +xerotica.com +xfinity.com +xfxssr.me +xgmyd.com +xhamster.com +xianjian.tw +xiaohexie.com +xiaolan.me +xiaoma.org +xiaomi.eu +xiaxiaoqiang.net +xijie.wordpress.com +xing.com +xinjiangpolicefiles.org +xinmiao.com.hk +xjtravelguide.com +xm.com +xml-training-guide.com +xn--11xs86f.icu +xn--1jqvh729avzfcy2d8ummib.com +xn--4gq171p.com +xn--9iqy04a7fi01l.com +xn--9pr62r24a.com +xn--czq75pvv1aj5c.org +xn--i2ru8q2qg.com +xn--kcrv3utim32hx9f6qe.com +xn--ngstr-lra8j.com +xn--noss43i.com +xn--oiq.cc +xn--p8j9a0d9c9a.xn--q9jyb4c +xn--u2u927b.com +xnpool.com +xnxx.com +xpud.org +xsden.info +xskywalker.com +xt.com +xt.pub +xtube.com +xuchao.net +xuchao.org +xuehua.us +xvbelink.com +xvideos-cdn.com +xvideos.com +xvideos.es +xvinlink.com +xxx.com +xxx.xxx +xxxx.com.au +xxxymovies.com +y2mate.com +yadi.sk +yahoo.com +yahoo.com.hk +yahoo.com.tw +yakbutterblues.com +yam.com +yam.org.tw +yande.re +yangzhi.org +yasni.co.uk +yasukuni.or.jp +yeahteentube.com +yecl.net +yeelou.com +yeeyi.com +yegle.net +yes-news.com +yes123.com.tw +yesasia.com +yesasia.com.hk +yespornplease.com +yeyeclub.com +yfsp.tv +yhcw.net +yibaochina.com +yidio.com +yigeni.com +yipub.com +yizhihongxing.com +yobit.net +yobt.tv +yogichen.org +you-get.org +you.com +youjizz.com +youmaker.com +youmind.com +youpai.org +youporn.com +youporngay.com +yourepeat.com +yourlisten.com +yourlust.com +yousendit.com +youtu.be +youtube-nocookie.com +youtube.com +youtubeeducation.com +youtubegaming.com +youtubekids.com +youversion.com +youwin.com +youxu.info +yt.be +ytimg.com +ytn.co.kr +yulghun.com +yunchao.net +yunomi.tokyo +yvesgeleyn.com +yyii.org +yyjlymb.xyz +yysub.net +yzzk.com +z-lib.fm +z-lib.fo +z-lib.gd +z-lib.gl +z-lib.io +z-lib.org +z-library.ec +z-library.sk +zalmos.com +zamimg.com +zaochenbao.com +zattoo.com +zb.com +zdnet.com.tw +zello.com +zenmate.com +zenmate.com.ru +zerohedge.com +zeronet.io +zh-hans.cfsh99.com +zh.ecdm.wikia.com +zh.pokerstrategy.com +zh.wikiquote.org +zhangtianliang.com +zhanlve.org +zhao.1984.city +zhengjian.org +zhengwunet.org +zhenxiang.biz +zhizhu.top +zhongguo.ca +zhongguotese.net +zhongzidi.com +zhuatieba.com +zhuichaguoji.org +zi.media +zillionk.com +zim.vn +zinio.com +zmedia.com.tw +zmw.cn +zodgame.xyz +zonaeuropa.com +zonghexinwen.com +zoogvpn.com +zoominfo.com +zooqle.com +zootool.com +zophar.net +zorrovpn.com +zozotown.com +zpn.im +zspeeder.me +zuo.la +zuobiao.me +zuola.com +zvereff.com +zynamics.com +zyxel.com +zzcloud.me diff --git a/luci-app-passwall/root/usr/share/passwall/rules/lanlist_ipv4 b/luci-app-passwall/root/usr/share/passwall/rules/lanlist_ipv4 new file mode 100644 index 00000000..82b1600e --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/lanlist_ipv4 @@ -0,0 +1,16 @@ +0.0.0.0/8 +10.0.0.0/8 +100.64.0.0/10 +127.0.0.0/8 +169.254.0.0/16 +172.16.0.0/12 +192.0.0.0/24 +192.0.2.0/24 +192.88.99.0/24 +192.168.0.0/16 +198.51.100.0/24 +203.0.113.0/24 +224.0.0.0/4 +233.252.0.0/24 +240.0.0.0/4 +255.255.255.255/32 diff --git a/luci-app-passwall/root/usr/share/passwall/rules/lanlist_ipv6 b/luci-app-passwall/root/usr/share/passwall/rules/lanlist_ipv6 new file mode 100644 index 00000000..34ec9e31 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/lanlist_ipv6 @@ -0,0 +1,16 @@ +::/128 +::1/128 +::ffff:0:0/96 +::ffff:0:0:0/96 +64:ff9b::/96 +64:ff9b:1::/48 +100::/64 +2001::/32 +2001:20::/28 +2001:db8::/32 +2002::/16 +3fff::/20 +5f00::/16 +fc00::/7 +fe80::/64 +ff00::/8 diff --git a/luci-app-passwall/root/usr/share/passwall/rules/proxy_host b/luci-app-passwall/root/usr/share/passwall/rules/proxy_host new file mode 100644 index 00000000..72c498c5 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/proxy_host @@ -0,0 +1,13 @@ +engage.cloudflareclient.com +github.com +bing.com +c.mi.com +apple-relay.apple.com + +#google +googleapis.cn +googleapis.com +google.com.tw +google.com.hk +gstatic.com +xn--ngstr-lra8j.com diff --git a/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip b/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip new file mode 100644 index 00000000..88309f8d --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/rules/proxy_ip @@ -0,0 +1,21 @@ +149.154.160.0/20 +91.108.4.0/22 +91.108.56.0/24 +109.239.140.0/24 +67.198.55.0/24 +8.8.4.4 +8.8.8.8 +208.67.222.222 +208.67.220.220 +104.16.249.249 +104.16.248.249 +1.1.1.1 +1.1.1.2 +1.0.0.1 +9.9.9.9 +149.112.112.112 +2001:67c:4e8::/48 +2001:b28:f23c::/48 +2001:b28:f23d::/48 +2001:b28:f23f::/48 +2001:b28:f242::/48 diff --git a/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh b/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh new file mode 100755 index 00000000..38d9b773 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh @@ -0,0 +1,190 @@ +#!/bin/sh + +. /usr/share/passwall/utils.sh +APP_FILE=${APP_PATH}/app.sh + +flag=0 + +check_process() { + while busybox pgrep -af "${CONFIG}/" | grep -E 'app\.sh.*(start|stop)|nftables\.sh|iptables\.sh|subscribe\.lua' >/dev/null; do + sleep 6s + done +} + +test_url() { + local url=$1 + local try=1 + [ -n "$2" ] && try=$2 + local timeout=2 + [ -n "$3" ] && timeout=$3 + local extra_params=$4 + if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then + extra_params="--retry-all-errors ${extra_params}" + fi + local status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") + case "$status" in + 204) + status=200 + ;; + esac + echo $status +} + +test_proxy() { + local result=0 + local status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}") + if [ "$status" = "200" ]; then + result=0 + else + local status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout}) + if [ "$status2" = "200" ]; then + result=1 + else + result=2 + ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 + [ $? -eq 0 ] && { + result=1 + } + fi + fi + echo $result +} + +test_node() { + local node_id=$1 + local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') + [ -n "${_type}" ] && { + check_process + local _tmp_port=$(get_new_port 48800 tcp,udp) + NO_REC_PROCESS=1 $APP_FILE run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json + sleep 2s + local curlx="socks5h://127.0.0.1:${_tmp_port}" + local _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx") + # ç»“æŸ SS æ’件进程 + local pid_file="/tmp/etc/${CONFIG}/test_node_${node_id}_plugin.pid" + [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 + busybox pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -rf /tmp/etc/${CONFIG}/test_node_${node_id}*.* + if [ "${_proxy_status}" -eq 200 ]; then + return 0 + fi + } + return 1 +} + +test_auto_switch() { + flag=$((flag + 1)) + local b_nodes=$1 + local now_node=$2 + [ -z "$now_node" ] && { + if [ -n "$(get_cache_var "socks_${id}")" ]; then + now_node=$(get_cache_var "socks_${id}") + else + #echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šæœªçŸ¥é”™è¯¯" + return 1 + fi + } + + [ $flag -le 1 ] && { + main_node=$now_node + } + + local status=$(test_proxy) + if [ "$status" = "2" ]; then + echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šæ— æ³•è¿žæŽ¥åˆ°ç½‘ç»œï¼Œè¯·æ£€æŸ¥ç½‘ç»œæ˜¯å¦æ­£å¸¸ï¼" + return 2 + fi + + #检测主节点是å¦èƒ½ä½¿ç”¨ + if [ "$restore_switch" = "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then + test_node ${main_node} + [ $? -eq 0 ] && { + check_process + #主节点正常,切æ¢åˆ°ä¸»èŠ‚ç‚¹ + echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šç«¯å£[${socks_port}] 主节点ã€$(config_n_get $main_node type):[$(config_n_get $main_node remarks)]】正常,切æ¢åˆ°ä¸»èŠ‚ç‚¹ï¼" + NO_REC_PROCESS=1 $APP_FILE socks_node_switch flag=${id} new_node=${main_node} + [ $? -eq 0 ] && { + echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šç«¯å£[${socks_port}] 节点切æ¢å®Œæ¯•ï¼" + } + return 0 + } + fi + + if [ "$status" = "0" ]; then + #echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼š${id}ã€$(config_n_get $now_node type):[$(config_n_get $now_node remarks)]】正常。" + return 0 + elif [ "$status" = "1" ]; then + local new_node msg + if [ "$backup_node_num" -gt 1 ]; then + # 有多个åŽå¤‡èŠ‚ç‚¹æ—¶ + local first_node found node + for node in $b_nodes; do + [ -z "$first_node" ] && first_node="$node" # 记录第一个节点 + [ "$found" = "1" ] && { new_node="$node"; break; } # 找到当å‰èŠ‚ç‚¹åŽå–下一个 + [ "$node" = "$now_node" ] && found=1 # 标记找到当å‰èŠ‚ç‚¹ + done + # 如果没找到当å‰èŠ‚ç‚¹ï¼Œæˆ–è€…å½“å‰èŠ‚ç‚¹æ˜¯æœ€åŽä¸€ä¸ªï¼Œå°±å–第一个节点 + [ -z "$new_node" ] && new_node="$first_node" + msg="切æ¢åˆ°$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 下一个备用节点)检测ï¼" + else + # åªæœ‰ä¸€ä¸ªåŽå¤‡èŠ‚ç‚¹æ—¶ï¼Œä¸Žä¸»èŠ‚ç‚¹è½®è¯¢ + new_node=$([ "$now_node" = "$main_node" ] && echo "$b_nodes" || echo "$main_node") + msg="切æ¢åˆ°$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 主节点)检测ï¼" + fi + echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šç«¯å£[${socks_port}]ã€$(config_n_get $now_node type):[$(config_n_get $now_node remarks)]】异常,$msg" + test_node ${new_node} + if [ $? -eq 0 ]; then +# [ "$restore_switch" = "0" ] && { +# uci set $CONFIG.${id}.node=$new_node +# [ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node +# uci commit $CONFIG +# } + check_process + echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šç«¯å£[${socks_port}]ã€$(config_n_get $new_node type):[$(config_n_get $new_node remarks)]】正常,切æ¢åˆ°æ­¤èŠ‚ç‚¹ï¼" + NO_REC_PROCESS=1 $APP_FILE socks_node_switch flag=${id} new_node=${new_node} + [ $? -eq 0 ] && { + echolog "Socksåˆ‡æ¢æ£€æµ‹ï¼šç«¯å£[${socks_port}] 节点切æ¢å®Œæ¯•ï¼" + } + return 0 + else + test_auto_switch "${b_nodes}" ${new_node} + fi + fi +} + +start() { + id=$1 + LOCK_FILE=${LOCK_PATH}/${CONFIG}_socks_auto_switch_${id}.lock + LOG_EVENT_FILTER=$(uci -q get "${CONFIG}.global[0].log_event_filter" 2>/dev/null) + LOG_EVENT_CMD=$(uci -q get "${CONFIG}.global[0].log_event_cmd" 2>/dev/null) + main_node=$(config_n_get $id node) + socks_port=$(config_n_get $id port 0) + delay=$(config_n_get $id autoswitch_testing_time 30) + connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3) + retry_num=$(config_n_get $id autoswitch_retry_num 1) + restore_switch=$(config_n_get $id autoswitch_restore_switch 0) + probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204") + backup_node=$(config_n_get $id autoswitch_backup_node) + if [ -n "$backup_node" ]; then + backup_node=$(echo "$backup_node" | tr -s ' ' '\n' | uniq | tr -s '\n' ' ') + backup_node_num=$(printf "%s\n" "$backup_node" | wc -w) + if [ "$backup_node_num" -eq 1 ]; then + [ "$main_node" = "$backup_node" ] && return + fi + else + return + fi + while [ -n "$backup_node" ]; do + [ -f "$LOCK_FILE" ] && { + sleep 6s + continue + } + check_process + touch $LOCK_FILE + test_auto_switch "$backup_node" + rm -f $LOCK_FILE + sleep ${delay} + done +} + +start $@ diff --git a/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/luci-app-passwall/root/usr/share/passwall/subscribe.lua new file mode 100755 index 00000000..9e140544 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/subscribe.lua @@ -0,0 +1,2266 @@ +#!/usr/bin/lua + +------------------------------------------------ +-- @author William Chan +------------------------------------------------ +require 'luci.util' +require 'luci.jsonc' +require 'luci.sys' +local appname = 'passwall' +local api = require ("luci.passwall.api") +local datatypes = require "luci.cbi.datatypes" + +loadfile("/usr/share/" .. appname .. "/clash_subconverter.lua")() + +-- these global functions are accessed all the time by the event handler +-- so caching them is worth the effort +local tinsert = table.insert +local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub +local split = api.split +local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify +local base64Decode = api.base64Decode +local UrlEncode = api.UrlEncode +local UrlDecode = api.UrlDecode +local uci = api.uci +local fs = api.fs + +local has_ss_rust = api.is_finded("sslocal") +local has_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") +local DEFAULT_ALLOWINSECURE = true +local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0" +local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {} +local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {} +-- å–节点使用coreç±»åž‹ï¼ˆèŠ‚ç‚¹è®¢é˜…é¡µé¢æœªè®¾ç½®æ—¶ï¼Œè‡ªåЍå–默认) +local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}}) +local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}}) +local DEFAULT_VMESS_TYPE = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local DEFAULT_VLESS_TYPE = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local DEFAULT_HYSTERIA2_TYPE = api.get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{has_singbox,"sing-box"},{has_xray,"xray"}}) +local core_has = { + ["xray"] = has_xray, + ["sing-box"] = has_singbox, + ["shadowsocks-rust"] = has_ss_rust, + ["hysteria2"] = has_hysteria2 +} +-- 判断是å¦è¿‡æ»¤èŠ‚ç‚¹å…³é”®å­— +local function is_filter_keyword(sub_cfg, value) + local mode = DEFAULT_FILTER_KEYWORD_MODE + local discard_list = DEFAULT_FILTER_KEYWORD_DISCARD_LIST + local keep_list = DEFAULT_FILTER_KEYWORD_KEEP_LIST + if sub_cfg then + local filter_keyword_mode = sub_cfg.filter_keyword_mode or "5" -- 5 is global + if filter_keyword_mode == "0" then + mode = "0" + elseif filter_keyword_mode == "1" then + mode = "1" + discard_list = sub_cfg.filter_discard_list or {} + elseif filter_keyword_mode == "2" then + mode = "2" + keep_list = sub_cfg.filter_keep_list or {} + elseif filter_keyword_mode == "3" then + mode = "3" + keep_list = sub_cfg.filter_keep_list or {} + discard_list = sub_cfg.filter_discard_list or {} + elseif filter_keyword_mode == "4" then + mode = "4" + keep_list = sub_cfg.filter_keep_list or {} + discard_list = sub_cfg.filter_discard_list or {} + end + end + if mode == "1" then + for k,v in ipairs(discard_list) do + if value:find(v, 1, true) then + return true + end + end + elseif mode == "2" then + local result = true + for k,v in ipairs(keep_list) do + if value:find(v, 1, true) then + result = false + end + end + return result + elseif mode == "3" then + local result = false + for k,v in ipairs(discard_list) do + if value:find(v, 1, true) then + result = true + end + end + for k,v in ipairs(keep_list) do + if value:find(v, 1, true) then + result = false + end + end + return result + elseif mode == "4" then + local result = true + for k,v in ipairs(keep_list) do + if value:find(v, 1, true) then + result = false + end + end + for k,v in ipairs(discard_list) do + if value:find(v, 1, true) then + result = true + end + end + return result + end + return false +end + +local nodeResult = {} -- update result +local isDebug = false + +local log = function(...) + if isDebug == true then + local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + print(result) + else + api.log(...) + end +end + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = e + end +end + +-- 获å–å„项动æ€é…ç½®çš„å½“å‰æœåŠ¡å™¨ï¼Œå¯ä»¥ç”¨ get å’Œ set, getå¿…é¡»è¦èŽ·å–到节点表 +local CONFIG = {} +do + local function import_config(protocol) + local name = string.upper(protocol) + local szType = "@global[0]" + local option = protocol .. "_node" + + local node_id = uci:get(appname, szType, option) + CONFIG[#CONFIG + 1] = { + log = true, + remarks = name .. "节点", + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + uci:set(appname, szType, option, server) + o.newNodeId = server + end + } + end + import_config("tcp") + import_config("udp") + + if true then + local i = 0 + local option = "node" + uci:foreach(appname, "socks", function(t) + i = i + 1 + local id = t[".name"] + local node_id = t[option] + CONFIG[#CONFIG + 1] = { + log = true, + id = id, + remarks = "Socks节点列表[" .. i .. "]", + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + if not server or server == "" then + if #nodes_table > 0 then + server = nodes_table[1][".name"] + end + end + uci:set(appname, t[".name"], option, server) + o.newNodeId = server + end + } + if t.autoswitch_backup_node and #t.autoswitch_backup_node > 0 then + local flag = "Socks节点列表[" .. i .. "]备用节点的列表" + local currentNodes = {} + local newNodes = {} + for k, node_id in ipairs(t.autoswitch_backup_node) do + if node_id then + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode then + currentNodes[#currentNodes + 1] = { + log = true, + remarks = flag .. "[" .. k .. "]", + currentNode = currentNode, + set = function(o, server) + if server and server ~= "nil" then + table.insert(o.newNodes, server) + end + end + } + end + end + end + CONFIG[#CONFIG + 1] = { + remarks = flag, + currentNodes = currentNodes, + newNodes = newNodes, + set = function(o, newNodes) + if o then + if not newNodes then newNodes = o.newNodes end + uci:set_list(appname, id, "autoswitch_backup_node", newNodes or {}) + end + end + } + end + end) + end + + if true then + local i = 0 + local option = "lbss" + local function is_ip_port(str) + if type(str) ~= "string" then return false end + local ip, port = str:match("^([%d%.]+):(%d+)$") + return ip and datatypes.ipaddr(ip) and tonumber(port) and tonumber(port) <= 65535 + end + uci:foreach(appname, "haproxy_config", function(t) + i = i + 1 + local node_id = t[option] + CONFIG[#CONFIG + 1] = { + log = true, + id = t[".name"], + remarks = "HAProxyè´Ÿè½½å‡è¡¡èŠ‚ç‚¹åˆ—è¡¨[" .. i .. "]", + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + -- å¦‚æžœå½“å‰ lbss 值䏿˜¯ ip:port æ ¼å¼ï¼Œæ‰è¿›è¡Œä¿®æ”¹ + if not is_ip_port(t[option]) then + uci:set(appname, t[".name"], option, server) + o.newNodeId = server + end + end, + delete = function(o) + -- å¦‚æžœå½“å‰ lbss 值䏿˜¯ ip:port æ ¼å¼ï¼Œæ‰è¿›è¡Œåˆ é™¤ + if not is_ip_port(t[option]) then + uci:delete(appname, t[".name"]) + end + end + } + end) + end + + if true then + local i = 0 + local options = {"tcp", "udp"} + uci:foreach(appname, "acl_rule", function(t) + i = i + 1 + for index, value in ipairs(options) do + local option = value .. "_node" + local node_id = t[option] + CONFIG[#CONFIG + 1] = { + log = true, + id = t[".name"], + remarks = "访问控制列表[" .. i .. "]", + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + uci:set(appname, t[".name"], option, server) + o.newNodeId = server + end + } + end + end) + end + + uci:foreach(appname, "nodes", function(node) + local node_id = node[".name"] + if node.protocol and node.protocol == '_shunt' then + local rules = {} + uci:foreach(appname, "shunt_rules", function(e) + if e[".name"] and e.remarks then + table.insert(rules, e) + table.insert(rules, { + [".name"] = e[".name"] .. "_proxy_tag", + remarks = e.remarks .. " å‰ç½®ä»£ç†" + }) + end + end) + table.insert(rules, { + [".name"] = "default_node", + remarks = "默认" + }) + table.insert(rules, { + [".name"] = "default_proxy_tag", + remarks = "默认 å‰ç½®ä»£ç†" + }) + + for k, e in pairs(rules) do + local _node_id = node[e[".name"]] or nil + if _node_id and not _node_id:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = false, + currentNode = _node_id and uci:get_all(appname, _node_id) or nil, + remarks = "分æµ" .. e.remarks .. "节点", + set = function(o, server) + if not server then server = "" end + uci:set(appname, node_id, e[".name"], server) + o.newNodeId = server + end + } + end + end + elseif node.protocol and node.protocol == '_balancing' then + local flag = "Xrayè´Ÿè½½å‡è¡¡èŠ‚ç‚¹[" .. node_id .. "]列表" + local currentNodes = {} + local newNodes = {} + if node.balancing_node then + for k, node in pairs(node.balancing_node) do + currentNodes[#currentNodes + 1] = { + log = true, + node = node, + currentNode = (function() + if node and node:find("Socks_") then + return { Socks = node } + end + return node and uci:get_all(appname, node) or nil + end)(), + remarks = node, + set = function(o, server) + if o and server and server ~= "nil" then + table.insert(o.newNodes, server) + end + end + } + end + end + CONFIG[#CONFIG + 1] = { + remarks = flag, + currentNodes = currentNodes, + newNodes = newNodes, + set = function(o, newNodes) + if o then + if not newNodes then newNodes = o.newNodes end + uci:set_list(appname, node_id, "balancing_node", newNodes or {}) + end + end + } + + --åŽå¤‡èŠ‚ç‚¹ + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode and currentNode.fallback_node and not currentNode.fallback_node:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = true, + id = node_id, + remarks = "Xrayè´Ÿè½½å‡è¡¡èŠ‚ç‚¹[" .. node_id .. "]åŽå¤‡èŠ‚ç‚¹", + currentNode = uci:get_all(appname, currentNode.fallback_node) or nil, + set = function(o, server) + uci:set(appname, node_id, "fallback_node", server) + o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, node_id, "fallback_node") + end + } + end + elseif node.protocol and node.protocol == '_urltest' then + local flag = "Sing-Box URLTest节点[" .. node_id .. "]列表" + local currentNodes = {} + local newNodes = {} + if node.urltest_node then + for k, node in pairs(node.urltest_node) do + currentNodes[#currentNodes + 1] = { + log = true, + node = node, + currentNode = (function() + if node and node:find("Socks_") then + return { Socks = node } + end + return node and uci:get_all(appname, node) or nil + end)(), + remarks = node, + set = function(o, server) + if o and server and server ~= "nil" then + table.insert(o.newNodes, server) + end + end + } + end + end + CONFIG[#CONFIG + 1] = { + remarks = flag, + currentNodes = currentNodes, + newNodes = newNodes, + set = function(o, newNodes) + if o then + if not newNodes then newNodes = o.newNodes end + uci:set_list(appname, node_id, "urltest_node", newNodes or {}) + end + end + } + else + --å‰ç½®ä»£ç†èŠ‚ç‚¹ + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode and currentNode.preproxy_node and not currentNode.preproxy_node:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = true, + id = node_id, + remarks = "节点[" .. node_id .. "]å‰ç½®ä»£ç†èŠ‚ç‚¹", + currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil, + set = function(o, server) + uci:set(appname, node_id, "preproxy_node", server) + o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, node_id, "preproxy_node") + end + } + end + --è½åœ°èŠ‚ç‚¹ + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode and currentNode.to_node and not currentNode.to_node:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = true, + id = node_id, + remarks = "节点[" .. node_id .. "]è½åœ°èŠ‚ç‚¹", + currentNode = uci:get_all(appname, currentNode.to_node) or nil, + set = function(o, server) + uci:set(appname, node_id, "to_node", server) + o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, node_id, "to_node") + end + } + end + end + end) + + for k, v in pairs(CONFIG) do + if v.currentNodes and type(v.currentNodes) == "table" then + for kk, vv in pairs(v.currentNodes) do + if vv.currentNode == nil then + CONFIG[k].currentNodes[kk] = nil + end + end + else + if v.currentNode == nil then + if v.delete then + v.delete() + end + CONFIG[k] = nil + end + end + end +end + +-- å–æœºåœºä¿¡æ¯ï¼ˆå‰©ä½™æµé‡ã€åˆ°æœŸæ—¶é—´ï¼‰ +local subscribe_info = {} +local function get_subscribe_info(cfgid, value) + if type(cfgid) ~= "string" or cfgid == "" or type(value) ~= "string" then + return + end + local info = subscribe_info[cfgid] + if info and info.expired_date and info.expired_date ~= "" and info.rem_traffic and info.rem_traffic ~= "" then + return + end + value = value:gsub("%s+", "") + local date_patterns = {"套é¤åˆ°æœŸï¼š(.+)", "过期时间:(.+)", "有效期至:(.+)", "到期时间:(.+)", "截止日期:(.+)"} + local expired_date + for _, p in ipairs(date_patterns) do expired_date = value:match(p) or expired_date end + local rem_patterns = {"剩余æµé‡ï¼š(.+)", "æµé‡å‰©ä½™ï¼š(.+)", "å¯ç”¨æµé‡ï¼š(.+)", "套é¤å‰©ä½™ï¼š(.+)"} + local rem_traffic + for _, p in ipairs(rem_patterns) do rem_traffic = value:match(p) or rem_traffic end + subscribe_info[cfgid] = subscribe_info[cfgid] or {expired_date = "", rem_traffic = ""} + if expired_date then + local function formatDate(str) + local y, m, d = str:match("(%d%d%d%d)[-/]?(%d%d?)[-/]?(%d%d?)") + if y and m and d then + return y .. "." .. m .. "." .. d + end + return str + end + subscribe_info[cfgid]["expired_date"] = formatDate(expired_date) + end + if rem_traffic then + subscribe_info[cfgid]["rem_traffic"] = rem_traffic + end +end + +-- 设置 ss å议实现类型 +local function set_ss_implementation(ss_type, result) + if ss_type == "shadowsocks-rust" and has_ss_rust then + result.type = 'SS-Rust' + elseif ss_type == "xray" and has_xray then + result.type = 'Xray' + result.protocol = 'shadowsocks' + result.transport = 'raw' + elseif ss_type == "sing-box" and has_singbox then + result.type = 'sing-box' + result.protocol = 'shadowsocks' + else + log("跳过 SS 节点,因未适é…到 SS 核心程åºï¼Œæˆ–未正确设置节点使用类型。") + return nil + end + return result +end + +-- å¤„ç†æ•°æ® +local function processData(szType, content, add_mode, group, sub_cfg) + --log(2, content, add_mode, group) + local sub_allowinsecure = DEFAULT_ALLOWINSECURE + local sub_ss_type = DEFAULT_SS_TYPE + local sub_trojan_type = DEFAULT_TROJAN_TYPE + local sub_vmess_type = DEFAULT_VMESS_TYPE + local sub_vless_type = DEFAULT_VLESS_TYPE + local sub_hysteria2_type = DEFAULT_HYSTERIA2_TYPE + local sub_hy_up_mbps, sub_hy_down_mbps = 1000, 1000 + if sub_cfg then + if sub_cfg.allowInsecure and sub_cfg.allowInsecure ~= "1" then + sub_allowinsecure = nil + end + local ss_type = sub_cfg.ss_type or "global" + if ss_type ~= "global" and core_has[ss_type] then + sub_ss_type = ss_type + end + local trojan_type = sub_cfg.trojan_type or "global" + if trojan_type ~= "global" and core_has[trojan_type] then + sub_trojan_type = trojan_type + end + local vmess_type = sub_cfg.vmess_type or "global" + if vmess_type ~= "global" and core_has[vmess_type] then + sub_vmess_type = vmess_type + end + local vless_type = sub_cfg.vless_type or "global" + if vless_type ~= "global" and core_has[vless_type] then + sub_vless_type = vless_type + end + local hysteria2_type = sub_cfg.hysteria2_type or "global" + if hysteria2_type ~= "global" and core_has[hysteria2_type] then + sub_hysteria2_type = hysteria2_type + end + sub_hy_up_mbps = sub_cfg.hysteria_up_mbps + sub_hy_down_mbps = sub_cfg.hysteria_down_mbps + end + local result = { + timeout = 60, + add_mode = add_mode, --0为手动é…ç½®,1为导入,2为订阅 + group = group + } + --ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0) + if szType == 'ssr' then + if not has_ssr then + log("跳过 SSR 节点,因未安装 SSR æ ¸å¿ƒç¨‹åº shadowsocksr-libev。") + return nil + end + result.type = "SSR" + + local dat = split(content:gsub("/%?", "?"), "%?") + local hostInfo = split(dat[1], ':') + if dat[1]:match('%[(.*)%]') then + result.address = dat[1]:match('%[(.*)%]') + else + result.address = hostInfo[#hostInfo-5] + end + result.port = hostInfo[#hostInfo-4] + result.protocol = hostInfo[#hostInfo-3] + result.method = hostInfo[#hostInfo-2] + result.obfs = hostInfo[#hostInfo-1] + result.password = base64Decode(hostInfo[#hostInfo]) + local params = {} + for _, v in pairs(split(dat[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = v:sub(s + 1) + end + end + result.obfs_param = base64Decode(params.obfsparam) + result.protocol_param = base64Decode(params.protoparam) + -- local ssr_group = base64Decode(params.group) + -- if ssr_group then result.ssr_group = ssr_group end + result.remarks = base64Decode(params.remarks) + elseif szType == 'vmess' then + local info = jsonParse(content) + if sub_vmess_type == "sing-box" and has_singbox then + result.type = 'sing-box' + elseif sub_vmess_type == "xray" and has_xray then + result.type = "Xray" + else + log("跳过 VMess 节点,因未适é…到 VMess 核心程åºï¼Œæˆ–未正确设置节点使用类型。") + return nil + end + result.alter_id = info.aid + result.address = info.add + result.port = info.port + result.protocol = 'vmess' + result.uuid = info.id + result.remarks = info.ps + -- result.mux = 1 + -- result.mux_concurrency = 8 + + info.path = (info.path and info.path ~= "") and UrlDecode(info.path) or nil + + if not info.net then info.net = "tcp" end + info.net = string.lower(info.net) + if result.type == "sing-box" and info.net == "raw" then + info.net = "tcp" + elseif result.type == "Xray" and info.net == "tcp" then + info.net = "raw" + end + if info.net == 'h2' or info.net == 'http' then + info.net = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = info.net + end + if info.net == 'ws' then + result.ws_host = info.host + result.ws_path = info.path + if result.type == "sing-box" and info.path then + local ws_path_dat = split(info.path, "?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if info.net == "http" then + if result.type == "Xray" then + result.xhttp_mode = "stream-one" + result.xhttp_host = info.host + result.xhttp_path = info.path + else + result.http_host = (info.host and info.host ~= "") and { info.host } or nil + result.http_path = info.path + end + end + if info.net == 'raw' or info.net == 'tcp' then + if info.type and info.type ~= "http" then + info.type = "none" + end + result.tcp_guise = info.type + result.tcp_guise_http_host = (info.host and info.host ~= "") and { info.host } or nil + result.tcp_guise_http_path = (info.path and info.path ~= "") and { info.path } or nil + end + if info.net == 'kcp' or info.net == 'mkcp' then + info.net = "mkcp" + result.mkcp_guise = info.type + result.mkcp_seed = info.seed + end + if info.net == 'quic' then + result.quic_guise = info.type + result.quic_key = info.key + result.quic_security = info.securty + end + if info.net == 'grpc' then + result.grpc_serviceName = info.path + end + if info.net == 'xhttp' then + result.xhttp_host = info.host + result.xhttp_path = info.path + end + if info.net == 'httpupgrade' then + result.httpupgrade_host = info.host + result.httpupgrade_path = info.path + end + result.security = info.security or info.scy or "auto" + if info.tls == "tls" or info.tls == "1" then + result.tls = "1" + result.alpn = info.alpn + if info.fp and info.fp ~= "" then + result.utls = "1" + result.fingerprint = info.fp + end + result.tls_serverName = (info.sni and info.sni ~= "") and info.sni or info.host + result.tls_pinSHA256 = info.pcs + result.tls_CertByName = info.vcn + local insecure = info.allowinsecure or info.allowInsecure or info.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + else + result.tls = "0" + end + + if info.ech and info.ech ~= "" then + result.ech = "1" + result.ech_config = info.ech + end + + result.tcp_fast_open = info.tfo + + info.fm = (info.fm and info.fm ~= "") and UrlDecode(info.fm) or nil + result.use_finalmask = (info.fm and info.fm ~= "") and "1" or nil + result.finalmask = (info.fm and info.fm ~= "") and api.base64Encode(info.fm) or nil + + if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp") then + log("跳过节点:" .. result.remarks ..",因Sing-Box䏿”¯æŒ" .. szType .. "å议的" .. result.transport .. "传输方å¼ï¼Œéœ€æ›´æ¢Xray。") + return nil + end + elseif szType == "ss" then + result = set_ss_implementation(sub_ss_type, result) + if not result then return nil end + + --SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ] + --userinfo = websafe-base64-encode-utf8(method ":" password) + --ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1 + --ss://cmM0LW1kNTpwYXNzd2Q@192.168.100.1:8888/?plugin=obfs-local%3Bobfs%3Dhttp#Example2 + --ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888#Example3 + --ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3 + --ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp0ZXN0@xxxxxx.com:443?type=ws&path=%2Ftestpath&host=xxxxxx.com&security=tls&fp=&alpn=h3%2Ch2%2Chttp%2F1.1&sni=xxxxxx.com#test-1%40ss + --ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp4eHh4eHhAeHh4eC54eHh4eC5jb206NTYwMDE#Hong%20Kong-01 + + local idx_sp = content:find("#") or 0 + local alias = "" + if idx_sp > 0 then + alias = content:sub(idx_sp + 1, -1) + end + result.remarks = UrlDecode(alias) + local info = content:sub(1, idx_sp - 1):gsub("/%?", "?") + local params = {} + if info:find("%?") then + local find_index = info:find("%?") + local query = split(info, "%?") + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + if params.plugin then + local plugin_info = params.plugin + local idx_pn = plugin_info:find(";") + if idx_pn then + result.plugin = plugin_info:sub(1, idx_pn - 1) + result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info) + else + result.plugin = plugin_info + end + end + if result.plugin and result.plugin == "simple-obfs" then + result.plugin = "obfs-local" + end + info = info:sub(1, find_index - 1) + end + + local hostInfo = split(base64Decode(UrlDecode(info)), "@") + if hostInfo and #hostInfo > 0 then + local host_port = hostInfo[#hostInfo] + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + + local userinfo = nil + if #hostInfo > 2 then + userinfo = {} + for i = 1, #hostInfo - 1 do + tinsert(userinfo, hostInfo[i]) + end + userinfo = table.concat(userinfo, '@') + else + userinfo = base64Decode(hostInfo[1]) + end + local method, password + if userinfo:find(":") then + method = userinfo:sub(1, userinfo:find(":") - 1) + password = userinfo:sub(userinfo:find(":") + 1, #userinfo) + else + password = hostInfo[1] --一些链接用明文uuidåšå¯†ç  + end + + -- åˆ¤æ–­å¯†ç æ˜¯å¦ç»è¿‡urlç¼–ç  + local function isURLEncodedPassword(pwd) + if not pwd:find("%%[0-9A-Fa-f][0-9A-Fa-f]") then + return false + end + local ok, decoded = pcall(UrlDecode, pwd) + return ok and UrlEncode(decoded) == pwd + end + + local decoded = UrlDecode(password) + if isURLEncodedPassword(password) and decoded then + password = decoded + end + + local _method = (method or "none"):lower() + method = (_method == "chacha20-poly1305" and "chacha20-ietf-poly1305") or + (_method == "xchacha20-poly1305" and "xchacha20-ietf-poly1305") or _method + + result.method = method + result.password = password + result.tcp_fast_open = params.tfo + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + + local need_upgrade = (result.type ~= "Xray" and result.type ~= "sing-box") + and (params.type and params.type ~= "tcp") + and (params.headerType and params.headerType ~= "none") + if has_xray and (need_upgrade or params.type == "xhttp") then + result.type = "Xray" + result.protocol = "shadowsocks" + elseif has_singbox and need_upgrade then + result.type = "sing-box" + result.protocol = "shadowsocks" + end + + if result.plugin then + if result.type == 'Xray' then + -- obfs-localæ’ä»¶è½¬æ¢æˆxray支æŒçš„æ ¼å¼ + if result.plugin ~= "obfs-local" then + result.error_msg = "Xray 䏿”¯æŒ SS " .. result.plugin .. " æ’件。" + else + local obfs = result.plugin_opts:match("obfs=([^;]+)") or "" + local obfs_host = result.plugin_opts:match("obfs%-host=([^;]+)") or "" + if obfs == "" or obfs_host == "" then + result.error_msg = "SS " .. result.plugin .. " æ’件选项ä¸å®Œæ•´ã€‚" + end + if obfs == "http" then + result.transport = "raw" + result.tcp_guise = "http" + result.tcp_guise_http_host = (obfs_host and obfs_host ~= "") and { obfs_host } or nil + result.tcp_guise_http_path = { "/" } + elseif obfs == "tls" then + result.tls = "1" + result.tls_serverName = obfs_host + result.tls_allowInsecure = "1" + end + result.plugin = nil + result.plugin_opts = nil + end + elseif result.type == 'sing-box' then + if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" then + result.error_msg = "Sing-Box 䏿”¯æŒ SS " .. result.plugin .. " æ’件。" + else + result.plugin_enabled = "1" + end + else + result.plugin_enabled = "1" + end + end + + if params.type then + params.type = string.lower(params.type) + if result.type == "sing-box" and params.type == "raw" then + params.type = "tcp" + elseif result.type == "Xray" and params.type == "tcp" then + params.type = "raw" + end + if params.type == "h2" or params.type == "http" then + params.type = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = params.type + end + if result.type ~= "SS-Rust" then + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "%?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == "http" then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = (params.host and params.host ~= "") and { params.host } or nil + result.http_path = params.path + elseif result.type == "Xray" then + result.transport = "xhttp" + result.xhttp_mode = "stream-one" + result.xhttp_host = params.host + result.xhttp_path = params.path + end + end + if params.type == 'raw' or params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = (params.host and params.host ~= "") and { params.host } or nil + result.tcp_guise_http_path = (params.path and params.path ~= "") and { params.path } or nil + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + if params.path then result.grpc_serviceName = params.path end + if params.serviceName then result.grpc_serviceName = params.serviceName end + result.grpc_mode = params.mode or "gun" + end + if params.type == 'xhttp' then + if result.type ~= "Xray" then + result.error_msg = "è¯·æ›´æ¢ Xray ä»¥æ”¯æŒ xhttp 传输方å¼ã€‚" + end + result.xhttp_host = params.host + result.xhttp_path = params.path + result.xhttp_mode = params.mode or "auto" + result.use_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil + result.xhttp_extra = (params.extra and params.extra ~= "") and api.base64Encode(params.extra) or nil + local success, Data = pcall(jsonParse, params.extra) + if success and Data then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") or nil + end + end + result.tls = "0" + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host + result.alpn = params.alpn + if params.fp and params.fp ~= "" then + result.utls = "1" + result.fingerprint = params.fp + end + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + result.tls_pinSHA256 = params.pcs + result.tls_CertByName = params.vcn + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + result.reality_spiderX = params.spx or nil + result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil + result.reality_mldsa65Verify = params.pqv or nil + end + end + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + result.uot = params.udp + else + result.error_msg = "è¯·æ›´æ¢ Xray 或 Sing-Box æ¥æ”¯æŒ SS 更多的传输方å¼ã€‚" + end + end + + if params["shadow-tls"] then + if result.type ~= "sing-box" and result.type ~= "SS-Rust" then + result.error_msg = sub_ss_type .. " 䏿”¯æŒ shadow-tls æ’件。" + else + -- è§£æžSS Shadow-TLS æ’件傿•° + local function parseShadowTLSParams(b64str, out) + local ok, data = pcall(jsonParse, base64Decode(b64str)) + if not ok or type(data) ~= "table" then return "" end + if type(out) == "table" then + for k, v in pairs(data) do out[k] = v end + end + local t = {} + if data.version then t[#t+1] = "v" .. data.version .. "=1" end + if data.password then t[#t+1] = "passwd=" .. data.password end + for k, v in pairs(data) do + if k ~= "version" and k ~= "password" then + t[#t+1] = k .. "=" .. tostring(v) + end + end + return table.concat(t, ";") + end + + if result.type == "SS-Rust" then + result.plugin_enabled = "1" + result.plugin = "shadow-tls" + result.plugin_opts = parseShadowTLSParams(params["shadow-tls"]) + elseif result.type == "sing-box" then + local shadowtlsOpt = {} + parseShadowTLSParams(params["shadow-tls"], shadowtlsOpt) + if next(shadowtlsOpt) then + result.shadowtls = "1" + result.shadowtls_version = shadowtlsOpt.version or "1" + result.shadowtls_password = shadowtlsOpt.password + result.shadowtls_serverName = shadowtlsOpt.host + if shadowtlsOpt.fingerprint then + result.shadowtls_utls = "1" + result.shadowtls_fingerprint = shadowtlsOpt.fingerprint or "chrome" + end + end + end + end + end + end + elseif szType == "trojan" then + if sub_trojan_type == "sing-box" and has_singbox then + result.type = 'sing-box' + result.protocol = 'trojan' + elseif sub_trojan_type == "xray" and has_xray then + result.type = 'Xray' + result.protocol = 'trojan' + else + log("跳过 Trojan 节点,因未适é…到 Trojan 核心程åºï¼Œæˆ–未正确设置节点使用类型。") + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + if content:find("@") then + local Info = split(content, "@") + result.password = UrlDecode(Info[1]) + local port = "443" + Info[2] = (Info[2] or ""):gsub("/%?", "?") + local query = split(Info[2], "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.port = port + + result.tls = '1' + result.tls_serverName = params.peer or params.sni or "" + result.tls_pinSHA256 = params.pcs + result.tls_CertByName = params.vcn + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + + if not params.type then params.type = "tcp" end + params.type = string.lower(params.type) + if result.type == "sing-box" and params.type == "raw" then + params.type = "tcp" + elseif result.type == "Xray" and params.type == "tcp" then + params.type = "raw" + end + if params.type == "h2" or params.type == "http" then + params.type = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = params.type + end + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "%?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == "http" then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = (params.host and params.host ~= "") and { params.host } or nil + result.http_path = params.path + elseif result.type == "Xray" then + result.transport = "xhttp" + result.xhttp_mode = "stream-one" + result.xhttp_host = params.host + result.xhttp_path = params.path + end + end + if params.type == 'raw' or params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = (params.host and params.host ~= "") and { params.host } or nil + result.tcp_guise_http_path = (params.path and params.path ~= "") and { params.path } or nil + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + result.grpc_serviceName = params.serviceName or params.path + result.grpc_mode = params.mode or "gun" + end + if params.type == 'xhttp' then + result.xhttp_host = params.host + result.xhttp_path = params.path + end + if params.type == 'httpupgrade' then + result.httpupgrade_host = params.host + result.httpupgrade_path = params.path + end + + result.alpn = params.alpn + result.tcp_fast_open = params.tfo + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + + if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp") then + log("跳过节点:" .. result.remarks ..",因 Sing-Box 䏿”¯æŒ " .. szType .. " å议的 " .. result.transport .. " 传输方å¼ï¼Œéœ€æ›´æ¢ Xray。") + return nil + end + end + + elseif szType == "ssd" then + result = set_ss_implementation(sub_ss_type, result) + if not result then return nil end + result.address = content.server + result.port = content.port + result.password = content.password + result.method = content.encryption + result.plugin = content.plugin + result.plugin_opts = content.plugin_options + result.group = content.airport + result.remarks = content.remarks + elseif szType == "vless" then + if sub_vless_type == "sing-box" and has_singbox then + result.type = 'sing-box' + elseif sub_vless_type == "xray" and has_xray then + result.type = "Xray" + else + log("跳过 VLESS 节点,因未适é…到 VLESS 核心程åºï¼Œæˆ–未正确设置节点使用类型。") + return nil + end + result.protocol = "vless" + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + if content:find("@") then + local Info = split(content, "@") + result.uuid = UrlDecode(Info[1]) + local port = "443" + Info[2] = (Info[2] or ""):gsub("/%?", "?") + local query = split(Info[2], "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + + if not params.type then params.type = "tcp" end + params.type = string.lower(params.type) + if ({ xhttp=true, kcp=true, mkcp=true })[params.type] and result.type ~= "Xray" and has_xray then + result.type = "Xray" + end + if result.type == "sing-box" and params.type == "raw" then + params.type = "tcp" + elseif result.type == "Xray" and params.type == "tcp" then + params.type = "raw" + end + if params.type == "h2" or params.type == "http" then + params.type = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = params.type + end + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "%?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == "http" then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = (params.host and params.host ~= "") and { params.host } or nil + result.http_path = params.path + elseif result.type == "Xray" then + result.transport = "xhttp" + result.xhttp_mode = "stream-one" + result.xhttp_host = params.host + result.xhttp_path = params.path + end + end + if params.type == 'raw' or params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = (params.host and params.host ~= "") and { params.host } or nil + result.tcp_guise_http_path = (params.path and params.path ~= "") and { params.path } or nil + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + if params.path then result.grpc_serviceName = params.path end + if params.serviceName then result.grpc_serviceName = params.serviceName end + result.grpc_mode = params.mode or "gun" + end + if params.type == 'xhttp' then + result.xhttp_host = params.host + result.xhttp_path = params.path + result.xhttp_mode = params.mode or "auto" + result.use_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil + result.xhttp_extra = (params.extra and params.extra ~= "") and api.base64Encode(params.extra) or nil + local success, Data = pcall(jsonParse, params.extra) + if success and Data then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") or nil + end + end + if params.type == 'httpupgrade' then + result.httpupgrade_host = params.host + result.httpupgrade_path = params.path + end + result.encryption = params.encryption or "none" + result.flow = params.flow + + result.tls = "0" + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host + result.alpn = params.alpn + if params.fp and params.fp ~= "" then + result.utls = "1" + result.fingerprint = params.fp + end + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + result.tls_pinSHA256 = params.pcs + result.tls_CertByName = params.vcn + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + result.reality_spiderX = params.spx or nil + result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil + result.reality_mldsa65Verify = params.pqv or nil + end + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + end + + result.port = port + result.tcp_fast_open = params.tfo + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + + if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp") then + log("跳过节点:" .. result.remarks ..",因 Sing-Box 䏿”¯æŒ " .. szType .. " å议的 " .. result.transport .. " 传输方å¼ï¼Œéœ€æ›´æ¢ Xray。") + return nil + end + end + elseif szType == 'hysteria' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "hysteria" + else + log("跳过 Hysteria 节点,因未安装 Hysteria æ ¸å¿ƒç¨‹åº Sing-box。") + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + + local query = split(content:gsub("/%?", "?"), '%?') + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = v:sub(s + 1) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.hysteria_obfs = params.obfsParam + result.hysteria_auth_type = "string" + result.hysteria_auth_password = params.auth + result.tls_serverName = params.peer or params.sni or "" + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + result.alpn = params.alpn + result.hysteria_up_mbps = params.upmbps or sub_hy_up_mbps + result.hysteria_down_mbps = params.downmbps or sub_hy_down_mbps + result.hysteria_hop = params.mport + + elseif szType == 'hysteria2' or szType == 'hy2' then + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + local Info = content + if content:find("@") then + local contents = split(content, "@") + result.hysteria2_auth_password = UrlDecode(contents[1]) + Info = (contents[2] or ""):gsub("/%?", "?") + end + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1):lower()] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls_serverName = params.sni + result.tls_pinSHA256 = params.pcs or params.pinsha256 + result.tls_CertByName = params.vcn + local insecure = params.allowinsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + result.hysteria2_up_mbps = params.upmbps or sub_hy_up_mbps + result.hysteria2_down_mbps = params.downmbps or sub_hy_down_mbps + result.hysteria2_hop = params.mport + if params["obfs-password"] or params["obfs_password"] then + result.hysteria2_obfs_type = params.obfs or "salamander" + result.hysteria2_obfs_password = params["obfs-password"] or params["obfs_password"] + end + + if (sub_hysteria2_type == "sing-box" and has_singbox) or (sub_hysteria2_type == "xray" and has_xray) then + local is_singbox = sub_hysteria2_type == "sing-box" and has_singbox + result.type = is_singbox and 'sing-box' or 'Xray' + result.protocol = "hysteria2" + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + elseif has_hysteria2 then + result.type = "Hysteria2" + else + log("跳过 Hysteria2 节点,因未适é…到 Hysteria2 核心程åºï¼Œæˆ–未正确设置节点使用类型。") + return nil + end + elseif szType == 'tuic' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "tuic" + else + log("跳过 Tuic 节点,因未安装 Tuic æ ¸å¿ƒç¨‹åº Sing-box。") + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + local Info = content + if content:find("@", 1, true) then + local contents = split(content, "@") + local auth = contents[1] or "" + local idx = auth:find(":", 1, true) + if not idx then --修正æŸäº›é“¾æŽ¥ä¼šæŠŠuuidå’Œpassword之间的:è¿›è¡Œç¼–ç  + auth = UrlDecode(auth) + idx = auth:find(":", 1, true) + end + if idx then + result.uuid = UrlDecode(auth:sub(1, idx - 1)) + result.password = UrlDecode(auth:sub(idx + 1)) + end + Info = (contents[2] or ""):gsub("/%?", "?") + end + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1):lower()] = UrlDecode(v:sub(s + 1)) + end + end + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls_serverName = params.sni + result.tls_disable_sni = params.disable_sni + result.tuic_alpn = params.alpn or "h3" + result.tuic_congestion_control = params.congestion_control or "cubic" + result.tuic_udp_relay_mode = params.udp_relay_mode or "native" + local insecure = params.allowinsecure or params.insecure or params.allow_insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + elseif szType == "anytls" then + if has_singbox then + result.type = 'sing-box' + result.protocol = "anytls" + else + log("跳过 AnyTLS 节点,因未安装 AnyTLS æ ¸å¿ƒç¨‹åº Sing-box 1.12。") + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + if content:find("@") then + local Info = split(content, "@") + result.password = UrlDecode(Info[1]) + local port = "443" + Info[2] = (Info[2] or ""):gsub("/%?", "?") + local query = split(Info[2], "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1):lower()] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls = "0" + if not params.security or params.security == "" then + params.security = "tls" + end + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = params.sni + result.alpn = params.alpn + if params.fp and params.fp ~= "" then + result.utls = "1" + result.fingerprint = params.fp + end + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + end + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + end + result.port = port + local insecure = params.allowinsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + end + elseif szType == 'naive+https' or szType == 'naive+quic' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "naive" + else + log("跳过 NaïveProxy 节点,因未安装 NaïveProxy æ ¸å¿ƒç¨‹åº Sing-box。") + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + local Info = content + if content:find("@", 1, true) then + local contents = split(content, "@") + local auth = contents[1] or "" + local idx = auth:find(":", 1, true) + if not idx then --修正æŸäº›é“¾æŽ¥ä¼šæŠŠusernameå’Œpassword之间的:è¿›è¡Œç¼–ç  + auth = UrlDecode(auth) + idx = auth:find(":", 1, true) + end + if idx then + result.username = UrlDecode(auth:sub(1, idx - 1)) + result.password = UrlDecode(auth:sub(idx + 1)) + end + Info = (contents[2] or ""):gsub("/%?", "?") + end + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls_serverName = params.sni + result.uot = params.uot + result.naive_insecure_concurrency = params["insecure-concurrency"] or "0" + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + if szType == "naive+quic" then + result.naive_quic = "1" + result.naive_congestion_control = params.congestion_control or "bbr" + end + else + log("æš‚æ—¶ä¸æ”¯æŒ " .. szType .. " 类型的节点订阅,跳过此节点。") + return nil + end + if not result.remarks or result.remarks == "" then + if result.address and result.port then + result.remarks = result.address .. ':' .. result.port + else + result.remarks = "NULL" + end + end + return result +end + +local function curl(url, file, ua, mode) + if not url or url == "" then return 22, 404 end + local curl_args = { + "-fskL", + "--retry 3", + "--connect-timeout 3", + "-H 'Accept-Encoding: identity'", + "--dump-header -", + "-w '\\n%{http_code}'" + } + + ua = (ua and ua ~= "") and ua or "passwall" + ua = (ua == "passwall") and ("passwall/" .. api.get_version()) or ua + curl_args[#curl_args + 1] = '--user-agent "' .. ua .. '"' + if not ua:lower():find("clash", 1, true) then + curl_args[#curl_args + 1] = get_headers() + end + + local return_code, result + if mode == "direct" then + return_code, result = api.curl_base(url, file, curl_args) + elseif mode == "proxy" then + return_code, result = api.curl_proxy(url, file, curl_args) + else + return_code, result = api.curl_logic(url, file, curl_args) + end + + if result and result ~= "" then + local body, code = result:match("^(.-)%s*([0-9]+)$") + if code then + http_code = tonumber(code) or 0 + header_str = body + else + http_code = tonumber(result:match("(%d+)%s*$")) or 0 + end + end + if header_str ~= "" then + header_str = header_str:gsub("\r", "") + end + + return return_code, http_code, header_str +end + +function get_headers() + local cache_file = "/tmp/etc/" .. appname .. "_tmp/sub_curl_headers" + if fs.access(cache_file) then + return luci.sys.exec("cat " .. cache_file) + end + local headers = {} + + local function readfile(path) + local f = io.open(path, "r") + if not f then return nil end + local c = f:read("*a") + f:close() + return api.trim(c) + end + + headers[#headers + 1] = "x-device-os: OpenWrt" + + local rel = readfile("/etc/openwrt_release") + local os_ver = rel and rel:match("DISTRIB_RELEASE='([^']+)'") + if os_ver then + headers[#headers + 1] = "x-ver-os: " .. os_ver + end + + local model = readfile("/tmp/sysinfo/model") + if model then + headers[#headers + 1] = "x-device-model: " .. model + end + + local mac = readfile("/sys/class/net/eth0/address") + if mac and model then + local raw = mac .. "-" .. model + local p = io.popen("printf '%s' '" .. raw:gsub("'", "'\\''") .. "' | sha256sum") + if p then + local hash = p:read("*l") + p:close() + hash = hash and hash:match("^%w+") + if hash then + headers[#headers + 1] = "x-hwid: " .. hash + end + end + end + + local out = {} + for i = 1, #headers do + out[i] = "-H '" .. headers[i]:gsub("'", "'\\''") .. "'" + end + local headers_str = table.concat(out, " ") + local f = io.open(cache_file, "w"); if f then f:write(headers_str); f:close() end + return headers_str +end + +local function truncate_nodes(group) + for _, config in pairs(CONFIG) do + if config.currentNodes and #config.currentNodes > 0 then + local newNodes = {} + local removeNodesSet = {} + for k, v in pairs(config.currentNodes) do + if v.currentNode and v.currentNode.add_mode == "2" then + if (not group) or (group:lower() == (v.currentNode.group or ""):lower()) then + removeNodesSet[v.currentNode[".name"]] = true + end + end + end + for _, value in ipairs(config.currentNodes) do + if not removeNodesSet[value.currentNode[".name"]] then + newNodes[#newNodes + 1] = value.currentNode[".name"] + end + end + if config.set then + config.set(config, newNodes) + end + else + if config.currentNode and config.currentNode.add_mode == "2" then + if (not group) or (group:lower() == (config.currentNode.group or ""):lower()) then + if config.delete then + config.delete(config) + elseif config.set then + config.set(config, "") + end + end + end + end + end + uci:foreach(appname, "nodes", function(node) + if node.add_mode == "2" then + if (not group) or (group:lower() == (node.group or ""):lower()) then + uci:delete(appname, node['.name']) + end + end + end) + uci:foreach(appname, "subscribe_list", function(o) + if (not group) or (group:lower() == (o.remark or ""):lower()) then + uci:delete(appname, o['.name'], "md5") + end + end) + api.uci_save(uci, appname, true) +end + +local function select_node(nodes, config, parentConfig) + if config.currentNode then + local server + -- è´Ÿè½½å‡è¡¡ã€urltest中的 Socks [端å£] èŠ‚ç‚¹ä¿æŒåŽŸid + if config.currentNode["Socks"] then + server = config.currentNode.Socks + end + -- 特别优先级 cfgid + if config.currentNode[".name"] then + for index, node in pairs(nodes) do + if node[".name"] == config.currentNode[".name"] then + if config.log == nil or config.log == true then + log('æ›´æ–°ã€' .. config.remarks .. '】匹é…节点:' .. node.remarks) + end + server = node[".name"] + break + end + end + end + -- 第一优先级 类型 + 备注 + IP + ç«¯å£ + 分组 + if not server then + for index, node in pairs(nodes) do + if config.currentNode.type and config.currentNode.remarks and config.currentNode.address and config.currentNode.port then + if node.type and node.remarks and node.address and node.port then + if node.type == config.currentNode.type and node.remarks == config.currentNode.remarks and (node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port) and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log('æ›´æ–°ã€' .. config.remarks .. '】第一匹é…节点:' .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- 第二优先级 类型 + IP + ç«¯å£ + 分组 + if not server then + for index, node in pairs(nodes) do + if config.currentNode.type and config.currentNode.address and config.currentNode.port then + if node.type and node.address and node.port then + if node.type == config.currentNode.type and (node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port) and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log('æ›´æ–°ã€' .. config.remarks .. '】第二匹é…节点:' .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- 第三优先级 IP + ç«¯å£ + 分组 + if not server then + for index, node in pairs(nodes) do + if config.currentNode.address and config.currentNode.port then + if node.address and node.port then + if node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log('æ›´æ–°ã€' .. config.remarks .. '】第三匹é…节点:' .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- 第四优先级 IP + 分组 + if not server then + for index, node in pairs(nodes) do + if config.currentNode.address then + if node.address then + if node.address == config.currentNode.address and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log('æ›´æ–°ã€' .. config.remarks .. '】第四匹é…节点:' .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- 第五优先级备注 + 分组 + if not server then + for index, node in pairs(nodes) do + if config.currentNode.remarks then + if node.remarks then + if node.remarks == config.currentNode.remarks and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log('æ›´æ–°ã€' .. config.remarks .. '】第五匹é…节点:' .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + if not parentConfig then + -- 还ä¸è¡Œ éšä¾¿æ‰¾ä¸€ä¸ª + if not server then + if #nodes_table > 0 then + if config.log == nil or config.log == true then + log('ã€' .. config.remarks .. '】' .. '无法找到最匹é…的节点,当å‰å·²æ›´æ¢ä¸ºï¼š' .. nodes_table[1].remarks) + end + server = nodes_table[1][".name"] + end + end + end + if server then + if parentConfig then + config.set(parentConfig, server) + else + config.set(config, server) + end + end + else + if not parentConfig then + config.set(config, "") + end + end +end + +local function update_node(manual) + if next(nodeResult) == nil then + log("没有å¯ç”¨çš„èŠ‚ç‚¹ä¿¡æ¯æ›´æ–°ã€‚") + return + end + + local group = {} + for _, v in ipairs(nodeResult) do + group[v["remark"]:lower()] = true + end + + if manual == 0 and next(group) then + uci:foreach(appname, "nodes", function(node) + -- 如果未å‘现新节点或手动导入的节点就ä¸è¦åˆ é™¤äº†... + if node.add_mode == "2" and (node.group and group[node.group:lower()] == true) then + uci:delete(appname, node['.name']) + end + end) + end + for _, v in ipairs(nodeResult) do + local remark = v["remark"] + local list = v["list"] + local sub_cfg = v["sub_cfg"] + local domain_resolver, domain_resolver_dns, domain_resolver_dns_https, domain_strategy + local preproxy_node_group, to_node_group, outbound_iface_group, chain_node_type = "", "", "", "" + -- Subscription Group Chain Agent + local function valid_chain_node(node) + if not node then return "" end + local cp = uci:get(appname, node, "chain_proxy") or "" + local am = uci:get(appname, node, "add_mode") or "0" + chain_node_type = (cp == "" and am ~= "2") and (uci:get(appname, node, "type") or "") or "" + if chain_node_type ~= "Xray" and chain_node_type ~= "sing-box" then + chain_node_type = "" + return "" + end + return node + end + if sub_cfg then + domain_resolver = sub_cfg.domain_resolver + domain_resolver_dns = sub_cfg.domain_resolver_dns + domain_resolver_dns_https = sub_cfg.domain_resolver_dns_https + local map = { UseIPv4v6 = 1, UseIPv6v4 = 1, UseIPv4 = 1, UseIPv6 = 1 } + domain_strategy = (sub_cfg.domain_strategy and map[sub_cfg.domain_strategy]) and sub_cfg.domain_strategy or nil + preproxy_node_group = (sub_cfg.chain_proxy == "1") and valid_chain_node(sub_cfg.preproxy_node) or "" + to_node_group = (sub_cfg.chain_proxy == "2") and valid_chain_node(sub_cfg.to_node) or "" + outbound_iface_group = (sub_cfg.chain_proxy == "3") and sub_cfg.outbound_iface or "" + chain_node_type = (outbound_iface_group ~= "") and "iface" or chain_node_type + end + for _, vv in ipairs(list) do + local cfgid = uci:section(appname, "nodes", api.gen_short_uuid()) + for kkk, vvv in pairs(vv) do + if type(vvv) == "table" and next(vvv) ~= nil then + uci:set_list(appname, cfgid, kkk, vvv) + else + if kkk ~= "group" or vvv ~= "default" then + uci:set(appname, cfgid, kkk, vvv) + end + -- sing-box/xray 节点域åè§£æž + if kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then + if domain_resolver then + uci:set(appname, cfgid, "domain_resolver", domain_resolver) + if domain_resolver_dns then + uci:set(appname, cfgid, "domain_resolver_dns", domain_resolver_dns) + elseif domain_resolver_dns_https then + uci:set(appname, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https) + end + end + if domain_strategy then + local ds = domain_strategy + if vvv == "sing-box" then + local map = { UseIPv4v6 = "prefer_ipv4", UseIPv6v4 = "prefer_ipv6", UseIPv4 = "ipv4_only", UseIPv6 = "ipv6_only" } + ds = map[ds] or "" + end + uci:set(appname, cfgid, "domain_strategy", ds) + end + end + -- 订阅组链å¼ä»£ç† + if chain_node_type ~= "" and kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then + if preproxy_node_group ~="" then + uci:set(appname, cfgid, "chain_proxy", "1") + uci:set(appname, cfgid, "preproxy_node", preproxy_node_group) + elseif to_node_group ~= "" then + uci:set(appname, cfgid, "chain_proxy", "2") + uci:set(appname, cfgid, "to_node", to_node_group) + elseif outbound_iface_group ~= "" then + uci:set(appname, cfgid, "chain_proxy", "3") + uci:set(appname, cfgid, "outbound_iface", outbound_iface_group) + end + end + end + end + end + end + -- æ›´æ–°æœºåœºä¿¡æ¯ + for cfgid, info in pairs(subscribe_info) do + for key, value in pairs(info) do + if value ~= "" then + uci:set(appname, cfgid, key, value) + else + uci:delete(appname, cfgid, key) + end + end + end + + if next(CONFIG) then + local nodes = {} + uci:foreach(appname, "nodes", function(node) + nodes[#nodes + 1] = node + end) + + for _, config in pairs(CONFIG) do + if config.currentNodes and #config.currentNodes > 0 then + if config.remarks and config.currentNodes[1].log ~= false then + log('----ã€' .. config.remarks .. '】----') + end + for kk, vv in pairs(config.currentNodes) do + select_node(nodes, vv, config) + end + config.set(config) + else + select_node(nodes, config) + end + end + end + + api.uci_save(uci, appname, true) + + if arg[3] == "cron" then + if not fs.access("/var/lock/" .. appname .. ".lock") then + luci.sys.call("touch /tmp/lock/" .. appname .. "_cron.lock") + end + end + + if manual ~= 1 then + luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &") + end +end + +local function parse_link(raw, add_mode, group, sub_cfg) + if raw and #raw > 0 then + local cfgid + if sub_cfg then + cfgid = sub_cfg[".name"] + end + local nodes, szType + local node_list = {} + -- SSD ä¼¼ä¹Žæ˜¯è¿™ç§æ ¼å¼ ssd:// 开头的 + if raw:find('ssd://') then + szType = 'ssd' + local nEnd = select(2, raw:find('ssd://')) + nodes = base64Decode(raw:sub(nEnd + 1, #raw)) + nodes = jsonParse(nodes) + local extra = { + airport = nodes.airport, + port = nodes.port, + encryption = nodes.encryption, + password = nodes.password + } + local servers = {} + -- SS里é¢åŒ…ç€ å¹²è„†ç›´æŽ¥è¿™æ · + for _, server in ipairs(nodes.servers) do + tinsert(servers, setmetatable(server, { __index = extra })) + end + nodes = servers + else + -- ssd å¤–çš„æ ¼å¼ + if add_mode == "1" then + nodes = split(raw, "\n") + else + nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n") + end + end + + for _, v in ipairs(nodes) do + if v and (szType == 'ssd' or not string.match(v, "^%s*$")) then + xpcall(function () + local result + if szType == 'ssd' then + result = processData(szType, v, add_mode, group, sub_cfg) + elseif not szType then + local node = api.trim(v) + local dat = split(node, "://") + if dat and dat[1] and dat[2] then + if dat[1] == 'vmess' or dat[1] == 'ssr' then + local link = api.trim(dat[2]:gsub("#.*$", "")) + result = processData(dat[1], base64Decode(link), add_mode, group, sub_cfg) + else + local link = dat[2]:gsub("&", "&"):gsub("%s*#%s*", "#") -- 一些奇葩的链接用"&"当åš"&","#"å‰åŽå¸¦ç©ºæ ¼ + result = processData(dat[1], link, add_mode, group, sub_cfg) + end + end + else + log('跳过未知类型:' .. szType) + end + -- log(result) + if result then + if result.error_msg then + log('丢弃节点:' .. result.remarks .. " ,原因:" .. result.error_msg) + elseif not result.type then + log('丢弃节点:' .. result.remarks .. " ,找ä¸åˆ°å¯ä½¿ç”¨äºŒè¿›åˆ¶ã€‚") + elseif (add_mode == "2" and is_filter_keyword(sub_cfg, result.remarks)) or not result.address or result.remarks == "NULL" or result.address == "127.0.0.1" or + (not datatypes.hostname(result.address) and not (api.is_ip(result.address))) then + log('丢弃过滤节点:' .. result.type .. ' 节点,' .. result.remarks) + else + tinsert(node_list, result) + end + if add_mode == "2" then + get_subscribe_info(cfgid, result.remarks) + end + end + end, function (err) + --log(err) + log(v, "è§£æžé”™è¯¯ï¼Œè·³è¿‡æ­¤èŠ‚ç‚¹ã€‚") + end + ) + end + end + if #node_list > 0 then + nodeResult[#nodeResult + 1] = { + remark = group, + list = node_list, + sub_cfg = sub_cfg + } + end + log('æˆåŠŸè§£æžã€' .. group .. '】节点数é‡ï¼š' .. #node_list) + else + if add_mode == "2" then + log('获å–到的ã€' .. group .. '】订阅内容为空,å¯èƒ½æ˜¯è®¢é˜…åœ°å€æ— æ•ˆï¼Œæˆ–是网络问题,请诊断ï¼') + end + end +end + +local execute = function() + do + local subscribe_list = {} + local fail_list = {} + if arg[2] ~= "all" then + string.gsub(arg[2], '[^' .. "," .. ']+', function(w) + subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {} + end) + else + uci:foreach(appname, "subscribe_list", function(o) + subscribe_list[#subscribe_list + 1] = o + end) + end + + local manual_sub = arg[3] == "manual" + + for index, value in ipairs(subscribe_list) do + local cfgid = value[".name"] + local remark = value.remark or "" + local url = value.url or "" + local tmp_file, ua, headers + + local url_is_local + if fs.access(url) then + -- debug, reads local files. + log('正在订阅:ã€' .. remark .. '】' .. url) + url_is_local = true + tmp_file = url + else + ua = value.user_agent + local access_mode = value.access_mode + local result = (not access_mode) and "自动" or (access_mode == "direct" and "直连" or (access_mode == "proxy" and "代ç†" or "自动")) + log('正在订阅:ã€' .. remark .. '】' .. url .. ' [' .. result .. ']') + tmp_file = "/tmp/" .. cfgid + local return_code + return_code, value.http_code, headers = curl(url, tmp_file, ua, access_mode) + if return_code ~= 0 then + fail_list[#fail_list + 1] = value + luci.sys.call("rm -f " .. tmp_file) + end + end + if fs.access(tmp_file) then + if luci.sys.call("[ -f " .. tmp_file .. " ] && sed -i -e '/^[ \t]*$/d' -e '/^[ \t]*\r$/d' " .. tmp_file) == 0 then + local f = io.open(tmp_file, "r") + local stdout = f:read("*all") + f:close() + local raw_data = api.trim(stdout) + local old_md5 = value.md5 or "" + local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "") + if not manual_sub and old_md5 == new_md5 then + log('订阅:ã€' .. remark .. '】没有å˜åŒ–,无需更新。') + else + raw_data = parseClashNode(raw_data) + subscribe_info[cfgid] = parse_clash_sub_info(headers) + parse_link(raw_data, "2", remark, value) + uci:set(appname, cfgid, "md5", new_md5) + end + else + fail_list[#fail_list + 1] = value + end + if url_is_local then + value.http_code = 0 + else + luci.sys.call("rm -f " .. tmp_file) + end + end + end + + if #fail_list > 0 then + for index, value in ipairs(fail_list) do + log(string.format('ã€%s】订阅失败,å¯èƒ½æ˜¯è®¢é˜…åœ°å€æ— æ•ˆï¼Œæˆ–是网络问题,请诊断ï¼[%s]', value.remark, tostring(value.http_code))) + end + end + update_node(0) + end +end + +local function check_instance(action) + local sub_lock = "/var/lock/" .. appname .. "_subscribe.lock" + local rule_lock = "/var/lock/" .. appname .. "_rule_update.lock" + + if action == "start" then + math.randomseed(os.time() + math.floor(os.clock() * 1000)) + api.nixio.nanosleep(0, math.random(100, 1000) * 1000000) + if fs.access(sub_lock) then + log("有[订阅]实例正在è¿è¡Œï¼Œè¯·ç¨åŽå†è¯•...\n") + os.exit(0) + else + luci.sys.call("touch " .. sub_lock) + uci:revert(appname) + end + elseif action == "end" then + luci.sys.call("rm -f " .. sub_lock) + return + end + + if fs.access(rule_lock) then + log("[规则更新]实例正在è¿è¡Œï¼Œ[订阅]进入队列等待...\n") + end + while fs.access(rule_lock) do + api.nixio.nanosleep(2, 0) + end +end + +if arg[1] then + check_instance("start") + + if arg[1] == "start" then + log('开始订阅...') + xpcall(execute, function(e) + log(e) + if type(debug) == "table" and type(debug.traceback) == "function" then + log(debug.traceback()) + end + log('å‘生错误, 正在æ¢å¤æœåŠ¡') + end) + log('订阅完毕...\n') + elseif arg[1] == "add" then + local f = assert(io.open("/tmp/links.conf", 'r')) + local raw = f:read('*all') + f:close() + parse_link(raw, "1", arg[2]) + update_node(1) + luci.sys.call("rm -f /tmp/links.conf") + elseif arg[1] == "truncate" then + truncate_nodes(arg[2]) + end + + check_instance("end") +end diff --git a/luci-app-passwall/root/usr/share/passwall/tasks.sh b/luci-app-passwall/root/usr/share/passwall/tasks.sh new file mode 100755 index 00000000..564caee4 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/tasks.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +## 循环更新脚本 + +. /usr/share/passwall/utils.sh +LOCK_FILE=${LOCK_PATH}/${CONFIG}_tasks.lock + +CFG_UPDATE_INT=0 + +exec 99>"$LOCK_FILE" +flock -n 99 +if [ "$?" != 0 ]; then + exit 0 +fi + +while true +do + + if [ "$CFG_UPDATE_INT" -ne 0 ]; then + + stop_week_mode=$(config_t_get global_delay stop_week_mode) + stop_interval_mode=$(config_t_get global_delay stop_interval_mode) + stop_interval_mode=$(expr "$stop_interval_mode" \* 60) + if [ -n "$stop_week_mode" ]; then + [ "$stop_week_mode" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$stop_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG stop > /dev/null 2>&1 & } + } + fi + + start_week_mode=$(config_t_get global_delay start_week_mode) + start_interval_mode=$(config_t_get global_delay start_interval_mode) + start_interval_mode=$(expr "$start_interval_mode" \* 60) + if [ -n "$start_week_mode" ]; then + [ "$start_week_mode" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$start_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG start > /dev/null 2>&1 & } + } + fi + + restart_week_mode=$(config_t_get global_delay restart_week_mode) + restart_interval_mode=$(config_t_get global_delay restart_interval_mode) + restart_interval_mode=$(expr "$restart_interval_mode" \* 60) + if [ -n "$restart_week_mode" ]; then + [ "$restart_week_mode" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$restart_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG restart > /dev/null 2>&1 & } + } + fi + + autoupdate=$(config_t_get global_rules auto_update) + weekupdate=$(config_t_get global_rules week_update) + hourupdate=$(config_t_get global_rules interval_update) + hourupdate=$(expr "$hourupdate" \* 60) + if [ "$autoupdate" = "1" ]; then + [ "$weekupdate" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$hourupdate")" -eq 0 ] && { lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 & } + } + fi + + TMP_SUB_PATH=$TMP_PATH/sub_tasks + mkdir -p $TMP_SUB_PATH + for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get $item auto_update 0)" = "1" ]; then + cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1) + remark=$(config_n_get $item remark) + week_update=$(config_n_get $item week_update) + hour_update=$(config_n_get $item interval_update) + echo "$cfgid" >> $TMP_SUB_PATH/${week_update}_${hour_update} + fi + done + + [ -d "${TMP_SUB_PATH}" ] && { + for name in $(ls ${TMP_SUB_PATH}); do + week_update=$(echo $name | awk -F '_' '{print $1}') + hour_update=$(echo $name | awk -F '_' '{print $2}') + hour_update=$(expr "$hour_update" \* 60) + cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g') + [ "$week_update" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$hour_update")" -eq 0 ] && { lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 & } + } + + done + rm -rf $TMP_SUB_PATH + } + + fi + + CFG_UPDATE_INT=$(expr "$CFG_UPDATE_INT" + 10) + + sleep 600 + +done 2>/dev/null diff --git a/luci-app-passwall/root/usr/share/passwall/test.sh b/luci-app-passwall/root/usr/share/passwall/test.sh new file mode 100755 index 00000000..72ca0a60 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/test.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +. /usr/share/passwall/utils.sh + +test_url() { + local url=$1 + local try=1 + [ -n "$2" ] && try=$2 + local timeout=2 + [ -n "$3" ] && timeout=$3 + local extra_params=$4 + curl --help all | grep "\-\-retry-all-errors" > /dev/null + [ $? == 0 ] && extra_params="--retry-all-errors ${extra_params}" + status=$(/usr/bin/curl -I -o /dev/null -skL $extra_params --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") + case "$status" in + 204|\ + 200) + status=200 + ;; + esac + echo $status +} + +test_proxy() { + result=0 + status=$(test_url "https://www.google.com/generate_204" ${retry_num} ${connect_timeout}) + if [ "$status" = "200" ]; then + result=0 + else + status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout}) + if [ "$status2" = "200" ]; then + result=1 + else + result=2 + ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 + [ $? -eq 0 ] && { + result=1 + } + fi + fi + echo $result +} + +url_test_node() { + result=0 + local node_id=$1 + local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') + [ -n "${_type}" ] && { + if [ "${_type}" == "socks" ]; then + local _address=$(config_n_get ${node_id} address) + local _port=$(config_n_get ${node_id} port) + [ -n "${_address}" ] && [ -n "${_port}" ] && { + local curlx="socks5h://${_address}:${_port}" + local _username=$(config_n_get ${node_id} username) + local _password=$(config_n_get ${node_id} password) + [ -n "${_username}" ] && [ -n "${_password}" ] && curlx="socks5h://${_username}:${_password}@${_address}:${_port}" + } + else + local _tmp_port=$(get_new_port 48900 tcp,udp) + NO_REC_PROCESS=1 /usr/share/${CONFIG}/app.sh run_socks flag="url_test_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=url_test_${node_id}.json + local curlx="socks5h://127.0.0.1:${_tmp_port}" + fi + sleep 2s + local probeUrl=$(config_t_get global_other url_test_url https://www.google.com/generate_204) + result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_pretransfer}" -x ${curlx} "${probeUrl}") + # ç»“æŸ SS æ’件进程 + local pid_file="/tmp/etc/${CONFIG}/url_test_${node_id}_plugin.pid" + [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 + busybox pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -rf /tmp/etc/${CONFIG}/*url_test_${node_id}*.* + } + echo $result +} + +arg1=$1 +shift +case $arg1 in +test_url) + test_url $@ + ;; +url_test_node) + url_test_node $@ + ;; +esac diff --git a/luci-app-passwall/root/usr/share/passwall/utils.sh b/luci-app-passwall/root/usr/share/passwall/utils.sh new file mode 100755 index 00000000..bdcd5014 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/utils.sh @@ -0,0 +1,551 @@ +#!/bin/sh +# Copyright (C) 2022-2025 xiaorouji +# Copyright (C) 2026 Openwrt-Passwall Organization + +CONFIG=passwall +APP_PATH=/usr/share/${CONFIG} +TMP_PATH=/tmp/etc/${CONFIG} +TMP_PATH2=${TMP_PATH}_tmp +LOCK_PATH=/tmp/lock +LOG_FILE=/tmp/log/${CONFIG}.log +TMP_ACL_PATH=${TMP_PATH}/acl +TMP_BIN_PATH=${TMP_PATH}/bin +TMP_IFACE_PATH=${TMP_PATH}/iface +TMP_ROUTE_PATH=${TMP_PATH}/route +TMP_SCRIPT_FUNC_PATH=${TMP_PATH}/script_func +RULES_PATH=/usr/share/${CONFIG}/rules + +. /lib/functions/network.sh + +echolog() { + local d="$(date "+%Y-%m-%d %H:%M:%S")" + echo -e "$d: $*" >>$LOG_FILE +} + +clean_log() { + logsnum=$(cat $LOG_FILE 2>/dev/null | wc -l) + [ "$logsnum" -gt 1000 ] && { + echo "" > $LOG_FILE + echolog "日志文件过长,清空处ç†ï¼" + } +} + +config_get_type() { + local ret=$(uci -q get "${CONFIG}.${1}" 2>/dev/null) + echo "${ret:=$2}" +} + +config_n_get() { + local ret=$(uci -q get "${CONFIG}.${1}.${2}" 2>/dev/null) + echo "${ret:=$3}" +} + +config_t_get() { + local index=${4:-0} + local ret=$(uci -q get "${CONFIG}.@${1}[${index}].${2}" 2>/dev/null) + echo "${ret:=${3}}" +} + +config_t_set() { + local index=${4:-0} + local ret=$(uci -q set "${CONFIG}.@${1}[${index}].${2}=${3}" 2>/dev/null) +} + +first_type() { + [ "${1#/}" != "$1" ] && [ -x "$1" ] && echo "$1" && return + for p in "/bin/$1" "/usr/bin/$1" "${TMP_BIN_PATH:-/tmp}/$1"; do + [ -x "$p" ] && echo "$p" && return + done + command -v "$1" 2>/dev/null || command -v "$2" 2>/dev/null +} + +get_enabled_anonymous_secs() { + uci -q show "${CONFIG}" | grep "${1}\[.*\.enabled='1'" | cut -d '.' -sf2 +} + +get_geoip() { + local geo_output_path="$TMP_PATH2/geo_output" + mkdir -p ${geo_output_path} + local geoip_code="$1" + local geoip_type_flag="" + local output_path="${geo_output_path}/geoip-${geoip_code}-$2" + [ ! -s "${output_path}" ] && { + local geoip_path="$(config_t_get global_rules v2ray_location_asset)" + geoip_path="${geoip_path%*/}/geoip.dat" + local bin="$(first_type $(config_t_get global_app geoview_file) geoview)" + [ -n "$bin" ] && [ -s "$geoip_path" ] || { echo ""; return; } + case "$2" in + "ipv4") geoip_type_flag="-ipv6=false" ;; + "ipv6") geoip_type_flag="-ipv4=false" ;; + esac + "$bin" -input "$geoip_path" -list "$geoip_code" $geoip_type_flag -lowmem=true -output ${output_path} + } + [ -s "${output_path}" ] && cat "${output_path}" +} + +get_host_ip() { + local host=$2 + local count=$3 + [ -z "$count" ] && count=3 + local isip="" + local ip="" + if [ "$1" == "ipv6" ]; then + isip=$(echo $host | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + if [ -n "$isip" ]; then + ip=$(echo "$host" | tr -d '[]') + fi + else + isip=$(echo $host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}") + [ -n "$isip" ] && ip=$isip + fi + [ -z "$isip" ] && { + local t=4 + [ "$1" == "ipv6" ] && t=6 + local vpsrip=$(resolveip -$t -t $count $host | awk 'NR==1{print}') + ip=$vpsrip + } + [ -n "$ip" ] && echo "$ip" +} + +get_node_host_ip() { + local ip + local address=$(config_n_get $1 address) + [ -n "$address" ] && { + local use_ipv6=$(config_n_get $1 use_ipv6) + local network_type="ipv4" + [ "$use_ipv6" == "1" ] && network_type="ipv6" + ip=$(get_host_ip $network_type $address) + } + echo $ip +} + +get_ip_port_from() { + local __host=${1}; shift 1 + local __ipv=${1}; shift 1 + local __portv=${1}; shift 1 + local __ucipriority=${1}; shift 1 + + local val1 val2 + val2=$(echo "$__host" | sed -n ' + s/^[^#]*[#]\([0-9]*\)$/\1/p; t; + s/^\(\[[^]]*\]\)[:]\([0-9]*\)$/\2/p; t; + s/^.*[:#]\([0-9]*\)$/\1/p + ') + if [ -n "${__ucipriority}" ]; then + val2=$(config_n_get ${__host} port "${val2}") + val1=$(config_n_get ${__host} address "${__host%%${val2:+[:#]${val2}*}}") + else + val1="${__host%%${val2:+[:#]${val2}*}}" + fi + eval "${__ipv}=\"$val1\"; ${__portv}=\"$val2\"" +} + +parse_doh() { + local __doh=$1 __url_var=$2 __host_var=$3 __port_var=$4 __bootstrap_var=$5 + __doh=$(printf '%s' "$__doh" | tr -d ' \t\n') + local __url=${__doh%%,*} + local __bootstrap=${__doh#*,} + [ "$__bootstrap" = "$__doh" ] && __bootstrap="" + local __host_port=$(lua_api "get_domain_from_url(\"${__url}\")") + local __host __port + if echo "${__host_port}" | grep -q '^\[.*\]:[0-9]\+$'; then + __host=${__host_port%%]:*}] + __port=${__host_port##*:} + elif echo "${__host_port}" | grep -q ':[0-9]\+$'; then + __host=${__host_port%:*} + __port=${__host_port##*:} + else + __host=${__host_port} + __port=443 + fi + __host=${__host#[} + __host=${__host%]} + if [ "$(lua_api "is_ip(\"${__host}\")")" = "true" ]; then + __bootstrap=${__host} + fi + __bootstrap=${__bootstrap#[} + __bootstrap=${__bootstrap%]} + eval "${__url_var}='${__url}' ${__host_var}='${__host}' ${__port_var}='${__port}' ${__bootstrap_var}='${__bootstrap}'" +} + +host_from_url(){ + local f="${1}" + + ## Remove protocol part of url ## + f="${f##http://}" + f="${f##https://}" + f="${f##ftp://}" + f="${f##sftp://}" + + ## Remove username and/or username:password part of URL ## + f="${f##*:*@}" + f="${f##*@}" + + ## Remove rest of urls ## + f="${f%%/*}" + echo "${f%%:*}" +} + +hosts_foreach() { + local __hosts + eval "__hosts=\$${1}"; shift 1 + local __func=${1}; shift 1 + local __default_port=${1}; shift 1 + local __ret=1 + + [ -z "${__hosts}" ] && return 0 + local __ip __port + for __host in $(echo $__hosts | sed 's/[ ,]/\n/g'); do + get_ip_port_from "$__host" "__ip" "__port" + eval "$__func \"${__host}\" \"\${__ip}\" \"\${__port:-${__default_port}}\" \"$@\"" + __ret=$? + [ ${__ret} -ge ${ERROR_NO_CATCH:-1} ] && return ${__ret} + done +} + +check_host() { + local f=${1} + a=$(echo $f | grep "\/") + [ -n "$a" ] && return 1 + # 判断是å¦åŒ…嫿±‰å­—~ + local tmp=$(echo -n $f | awk '{print gensub(/[!-~]/,"","g",$0)}') + [ -n "$tmp" ] && return 1 + return 0 +} + +get_first_dns() { + local __hosts_val=${1}; shift 1 + __first() { + [ -z "${2}" ] && return 0 + echo "${2}#${3}" + return 1 + } + eval "hosts_foreach \"${__hosts_val}\" __first \"$@\"" +} + +get_last_dns() { + local __hosts_val=${1}; shift 1 + local __first __last + __every() { + [ -z "${2}" ] && return 0 + __last="${2}#${3}" + __first=${__first:-${__last}} + } + eval "hosts_foreach \"${__hosts_val}\" __every \"$@\"" + [ "${__first}" == "${__last}" ] || echo "${__last}" +} + +check_port_exists() { + local port=$1 + local protocol=$2 + [ -n "$protocol" ] || protocol="tcp,udp" + local result= + if [ "$protocol" = "tcp" ]; then + result=$(netstat -tln | grep -c ":$port ") + elif [ "$protocol" = "udp" ]; then + result=$(netstat -uln | grep -c ":$port ") + elif [ "$protocol" = "tcp,udp" ]; then + result=$(netstat -tuln | grep -c ":$port ") + fi + echo "${result}" +} + +get_new_port() { + local default_start_port=2001 + local min_port=1025 + local max_port=49151 + local port="$1" + local protocol=$(echo "$2" | tr 'A-Z' 'a-z') + local LOCK_FILE="${LOCK_PATH}/${CONFIG}_get_prot.lock" + while ! mkdir "$LOCK_FILE" 2>/dev/null; do + sleep 0.05 + done + if [ "$port" = "auto" ]; then + local now last_time diff last_port + now=$(date +%s 2>/dev/null) + last_time=$(get_cache_var "last_get_new_port_time") + if [ -n "$now" ] && [ -n "$last_time" ]; then + diff=$(expr "$now" - "$last_time") + [ "$diff" -lt 0 ] && diff=$(expr 0 - "$diff") + else + diff=999 + fi + if [ "$diff" -gt 10 ]; then + port=$default_start_port + else + last_port=$(get_cache_var "last_get_new_port_auto") + if [ -n "$last_port" ]; then + port=$(expr "$last_port" + 1) + else + port=$default_start_port + fi + fi + fi + [ "$port" -lt $min_port -o "$port" -gt $max_port ] && port=$default_start_port + local start_port="$port" + while :; do + if [ "$(check_port_exists "$port" "$protocol")" = 0 ]; then + break + fi + port=$(expr "$port" + 1) + if [ "$port" -gt $max_port ]; then + port=$min_port + fi + [ "$port" = "$start_port" ] && { + rmdir "$LOCK_FILE" 2>/dev/null + return 1 + } + done + if [ "$1" = "auto" ]; then + set_cache_var "last_get_new_port_auto" "$port" + [ -n "$now" ] && set_cache_var "last_get_new_port_time" "$now" + fi + rmdir "$LOCK_FILE" 2>/dev/null + echo "$port" +} + +check_ver() { + local version1="$1" + local version2="$2" + local i v1 v1_1 v1_2 v1_3 v2 v2_1 v2_2 v2_3 + IFS='.'; set -- $version1; v1_1=${1:-0}; v1_2=${2:-0}; v1_3=${3:-0} + IFS='.'; set -- $version2; v2_1=${1:-0}; v2_2=${2:-0}; v2_3=${3:-0} + IFS= + for i in 1 2 3; do + eval v1=\$v1_$i + eval v2=\$v2_$i + if [ "$v1" -gt "$v2" ]; then + # $1 大于 $2 + echo 0 + return + elif [ "$v1" -lt "$v2" ]; then + # $1 å°äºŽ $2 + echo 1 + return + fi + done + # $1 等于 $2 + echo 255 +} + +eval_set_val() { + for i in $@; do + for j in $i; do + eval $j + done + done +} + +eval_unset_val() { + for i in $@; do + for j in $i; do + eval unset $j + done + done +} + +lua_api() { + local func=${1} + [ -z "${func}" ] && { + echo "nil" + return + } + echo $(lua -e "local api = require 'luci.passwall.api' print(api.${func})") +} + +set_cache_var() { + local key="${1}" + shift 1 + local val="$@" + [ -n "${key}" ] && [ -n "${val}" ] && { + [ ! -d $TMP_PATH ] && mkdir -p $TMP_PATH + sed -i "/${key}=/d" $TMP_PATH/var >/dev/null 2>&1 + echo "${key}=\"${val}\"" >> $TMP_PATH/var + eval ${key}=\"${val}\" + } +} + +get_cache_var() { + local key="${1}" + [ -n "${key}" ] && [ -s "$TMP_PATH/var" ] && { + echo $(cat $TMP_PATH/var | grep "^${key}=" | awk -F '=' '{print $2}' | tail -n 1 | awk -F'"' '{print $2}') + } +} + +eval_cache_var() { + [ -s "$TMP_PATH/var" ] && eval $(cat "$TMP_PATH/var") +} + +has_1_65535() { + local val="$1" + val=${val//:/-} + case ",$val," in + *,1-65535,*) return 0 ;; + *) return 1 ;; + esac +} + +add_ip2route() { + local ip=$(get_host_ip "ipv4" $1) + [ -z "$ip" ] && { + echolog " - 无法解æž[${1}],路由表添加失败ï¼" + return 1 + } + local remarks="${1}" + [ "$remarks" != "$ip" ] && remarks="${1}(${ip})" + + local gateway device + network_get_gateway gateway "$2" + network_get_device device "$2" + [ -z "${device}" ] && device=$(ubus call "network.interface.$2" status 2>/dev/null | jsonfilter -e '@.device' 2>/dev/null) + [ -z "${device}" ] && [ -d "/sys/class/net/$2" ] && device="$2" + [ -z "${device}" ] && device="$2" + + if [ -n "${gateway}" ]; then + route add -host ${ip} gw ${gateway} dev ${device} >/dev/null 2>&1 + echo "$ip" >> $TMP_ROUTE_PATH/${device} + echolog " - [${remarks}]添加到接å£[${device}]路由表æˆåŠŸï¼" + else + echolog " - [${remarks}]添加到接å£[${device}]路由表失功ï¼åŽŸå› æ˜¯æ‰¾ä¸åˆ°[${device}]网关。" + fi +} + +delete_ip2route() { + [ -d "${TMP_ROUTE_PATH}" ] && { + local interface + for interface in $(ls ${TMP_ROUTE_PATH}); do + for ip in $(cat ${TMP_ROUTE_PATH}/${interface}); do + route del -host ${ip} dev ${interface} >/dev/null 2>&1 + done + done + } +} + +ln_run() { + local file_func=${1} + local ln_name=${2} + local output=${3} + + shift 3; + if [ "${file_func%%/*}" != "${file_func}" ]; then + [ ! -L "${file_func}" ] && { + ln -s "${file_func}" "${TMP_BIN_PATH}/${ln_name}" >/dev/null 2>&1 + file_func="${TMP_BIN_PATH}/${ln_name}" + } + [ -x "${file_func}" ] || echolog " - $(readlink ${file_func}) 没有执行æƒé™ï¼Œæ— æ³•å¯åŠ¨ï¼š${file_func} $*" + fi + #echo "${file_func} $*" >&2 + [ -n "${file_func}" ] || echolog " - 找ä¸åˆ° ${ln_name},无法å¯åЍ..." + [ "${output}" != "/dev/null" ] && [ "${ln_name}" != "chinadns-ng" ] && { + local persist_log_path=$(config_t_get global persist_log_path) + local sys_log=$(config_t_get global sys_log "0") + } + if [ -z "$persist_log_path" ] && [ "$sys_log" != "1" ]; then + ${file_func:-echolog " - ${ln_name}"} "$@" >${output} 2>&1 & + else + [ "${output: -1, -7}" == "TCP.log" ] && local protocol="TCP" + [ "${output: -1, -7}" == "UDP.log" ] && local protocol="UDP" + if [ -n "${persist_log_path}" ]; then + mkdir -p ${persist_log_path} + local log_file=${persist_log_path}/passwall_${protocol}_${ln_name}_$(date '+%F').log + echolog "记录到æŒä¹…性日志文件:${log_file}" + ${file_func:-echolog " - ${ln_name}"} "$@" >> ${log_file} 2>&1 & + sys_log=0 + fi + if [ "${sys_log}" == "1" ]; then + echolog "记录 ${ln_name}_${protocol} 到系统日志" + ${file_func:-echolog " - ${ln_name}"} "$@" 2>&1 | logger -t PASSWALL_${protocol}_${ln_name} & + fi + fi + [ "$NO_REC_PROCESS" = "1" ] && return + process_count=$(ls $TMP_SCRIPT_FUNC_PATH | wc -l) + process_count=$((process_count + 1)) + echo "${file_func:-echolog " - ${ln_name}"} $@ >${output}" > $TMP_SCRIPT_FUNC_PATH/$process_count +} + +is_socks_wrap() { + case "$1" in + Socks_*) return 0 ;; + *) return 1 ;; + esac +} + +kill_all() { + kill -9 $(pidof "$@") >/dev/null 2>&1 +} + +get_subscribe_host(){ + local line + uci show "${CONFIG}" | grep "=subscribe_list" | while read -r line; do + local section="$(echo "$line" | cut -d '.' -sf 2 | cut -d '=' -sf 1)" + local url="$(config_n_get $section url)" + [ -n "$url" ] || continue + url="$(host_from_url "$url")" + echo "$url" + done +} + +gen_lanlist() { + cat $RULES_PATH/lanlist_ipv4 | tr -s '\n' | grep -v "^#" +} + +gen_lanlist_6() { + cat $RULES_PATH/lanlist_ipv6 | tr -s '\n' | grep -v "^#" +} + +get_wan_ips() { + local family="$1" + local NET_ADDR + local iface + local INTERFACES=$(ubus call network.interface dump | jsonfilter -e \ + '@.interface[!(@.interface ~ /lan/) && !(@.l3_device ~ /\./) && @.route[0]].interface') + for iface in $INTERFACES; do + local addr + if [ "$family" = "ip6" ]; then + network_get_ipaddr6 addr "$iface" + case "$addr" in + ""|fe80*) continue ;; + esac + else + network_get_ipaddr addr "$iface" + case "$addr" in + ""|"0.0.0.0") continue ;; + esac + fi + case " $NET_ADDR " in + *" $addr "*) ;; + *) NET_ADDR="${NET_ADDR:+$NET_ADDR }$addr" ;; + esac + done + echo "$NET_ADDR" +} + +get_local_ips() { + local family="$1" + local ALL_IPS WAN_IPS ip NET_ADDR + if [ "$family" = "ip6" ]; then + ALL_IPS=$(ip -o -6 addr show scope global | awk '{print $4}' | cut -d/ -f1) + WAN_IPS=$(get_wan_ips ip6) + else + ALL_IPS=$(ip -o -4 addr show scope global | awk '{print $4}' | cut -d/ -f1) + WAN_IPS=$(get_wan_ips ip4) + fi + # 补充回环(scope global ä¸åŒ…å«ï¼‰ + [ "$family" = "ip6" ] && ALL_IPS="$ALL_IPS ::1" + [ "$family" != "ip6" ] && ALL_IPS="$ALL_IPS 127.0.0.1" + for ip in $ALL_IPS; do + case "$ip" in + ""|0.0.0.0|::) continue ;; + esac + case " $WAN_IPS " in + *" $ip "*) continue ;; + esac + case " $NET_ADDR " in + *" $ip "*) ;; + *) NET_ADDR="${NET_ADDR:+$NET_ADDR }$ip" ;; + esac + done + for ip in $NET_ADDR; do + echo "$ip" + done +} diff --git a/luci-app-passwall/root/usr/share/rpcd/acl.d/luci-app-passwall.json b/luci-app-passwall/root/usr/share/rpcd/acl.d/luci-app-passwall.json new file mode 100644 index 00000000..0d6f7d7e --- /dev/null +++ b/luci-app-passwall/root/usr/share/rpcd/acl.d/luci-app-passwall.json @@ -0,0 +1,11 @@ +{ + "luci-app-passwall": { + "description": "Grant UCI access for luci-app-passwall", + "read": { + "uci": [ "passwall", "passwall_server" ] + }, + "write": { + "uci": [ "passwall", "passwall_server" ] + } + } +} diff --git a/luci-app-passwall/root/usr/share/ucitrack/luci-app-passwall-server.json b/luci-app-passwall/root/usr/share/ucitrack/luci-app-passwall-server.json new file mode 100644 index 00000000..257e61be --- /dev/null +++ b/luci-app-passwall/root/usr/share/ucitrack/luci-app-passwall-server.json @@ -0,0 +1,4 @@ +{ + "config": "passwall_server", + "init": "passwall_server" +} diff --git a/luci-app-passwall/root/usr/share/ucitrack/luci-app-passwall.json b/luci-app-passwall/root/usr/share/ucitrack/luci-app-passwall.json new file mode 100644 index 00000000..b3b7140e --- /dev/null +++ b/luci-app-passwall/root/usr/share/ucitrack/luci-app-passwall.json @@ -0,0 +1,4 @@ +{ + "config": "passwall", + "init": "passwall" +} diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile new file mode 100644 index 00000000..3d8aa3cf --- /dev/null +++ b/luci-app-passwall2/Makefile @@ -0,0 +1,144 @@ +# Copyright (C) 2022-2025 xiaorouji +# Copyright (C) 2026 Openwrt-Passwall Organization +# +# This is free software, licensed under the GNU General Public License v3. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-passwall2 +PKG_VERSION:=26.5.19 +PKG_RELEASE:=1 +PKG_PO_VERSION:=$(PKG_VERSION) + +PKG_CONFIG_DEPENDS:= \ + CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin + +LUCI_TITLE:=LuCI support for PassWall 2 +LUCI_PKGARCH:=all +LUCI_DEPENDS:=+coreutils +coreutils-base64 +coreutils-nohup +curl \ + +ip-full +libuci-lua +lua +luci-compat +luci-lib-jsonc +lyaml +resolveip +tcping \ + +geoview +v2ray-geoip +v2ray-geosite \ + +unzip + +define Package/$(PKG_NAME)/config +menu "Configuration" + depends on PACKAGE_$(PKG_NAME) + +choice + prompt "Basic Core" + default PACKAGE_$(PKG_NAME)_Basic_Core_All if aarch64||arm||i386||x86_64 + default PACKAGE_$(PKG_NAME)_Basic_Core_Xray + + config PACKAGE_$(PKG_NAME)_Basic_Core_Xray + bool "Xray" + select PACKAGE_xray-core + + config PACKAGE_$(PKG_NAME)_Basic_Core_SingBox + bool "SingBox" + select PACKAGE_sing-box + + config PACKAGE_$(PKG_NAME)_Basic_Core_All + bool "All" + select PACKAGE_xray-core + select PACKAGE_sing-box +endchoice + +config PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy + bool "Iptables Transparent Proxy" + select PACKAGE_chinadns-ng + select PACKAGE_dnsmasq-full + select PACKAGE_dnsmasq_full_ipset + select PACKAGE_ipset + select PACKAGE_iptables + select PACKAGE_iptables-nft + select PACKAGE_iptables-zz-legacy + select PACKAGE_iptables-mod-conntrack-extra + select PACKAGE_iptables-mod-iprange + select PACKAGE_iptables-mod-socket + select PACKAGE_iptables-mod-tproxy + select PACKAGE_ip6tables-mod-nat + select PACKAGE_kmod-ipt-nat + default y if ! PACKAGE_firewall4 + +config PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy + bool "Nftables Transparent Proxy" + select PACKAGE_chinadns-ng + select PACKAGE_dnsmasq-full + select PACKAGE_dnsmasq_full_nftset + select PACKAGE_nftables + select PACKAGE_kmod-nft-socket + select PACKAGE_kmod-nft-tproxy + select PACKAGE_kmod-nft-nat + default y if PACKAGE_firewall4 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy + bool "Include Haproxy" + select PACKAGE_haproxy + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria + bool "Include Hysteria" + select PACKAGE_hysteria + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy + bool "Include NaiveProxy" + depends on !(arc||armeb||loongarch64||mips||mips64||powerpc||TARGET_gemini) + select PACKAGE_naiveproxy + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client + bool "Include Shadowsocks Rust Client" + depends on !i386 + select PACKAGE_shadowsocks-rust-sslocal + default y if aarch64||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server + bool "Include Shadowsocks Rust Server" + depends on !i386 + select PACKAGE_shadowsocks-rust-ssserver + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client + bool "Include ShadowsocksR Libev Client" + select PACKAGE_shadowsocksr-libev-ssr-local + select PACKAGE_shadowsocksr-libev-ssr-redir + default y + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server + bool "Include ShadowsocksR Libev Server" + select PACKAGE_shadowsocksr-libev-ssr-server + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs + bool "Include Simple-Obfs (Shadowsocks Plugin)" + select PACKAGE_simple-obfs-client + default y + +config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin + bool "Include V2ray-Plugin (Shadowsocks Plugin)" + select PACKAGE_v2ray-plugin + default y if aarch64||arm||i386||x86_64 + +endmenu +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/passwall2 +/etc/config/passwall2_server +/usr/share/passwall2/domains_excluded +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-passwall2/htdocs/luci-static/resources/view/passwall2/Sortable.min.js b/luci-app-passwall2/htdocs/luci-static/resources/view/passwall2/Sortable.min.js new file mode 100644 index 00000000..8148b9dd --- /dev/null +++ b/luci-app-passwall2/htdocs/luci-static/resources/view/passwall2/Sortable.min.js @@ -0,0 +1,2 @@ +/*! Sortable 1.15.7 - MIT | git://github.com/SortableJS/Sortable.git */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function m(t){return t.host&&t!==document&&t.host.nodeType&&t.host!==t?t.host:t.parentNode}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&g(t,e)||o&&t===n)return t}while(t!==n&&(t=m(t)))}return null}var v,b=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(b," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(b," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function D(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function E(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function jt(t){$&&$.parentNode[K]._isOutsideThisEl(t.target)}function Ht(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Rt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ht.supportPointer&&"PointerEvent"in window&&(!u||d),emptyInsertThreshold:5};for(n in G.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Xt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Pt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?f(t,"pointerdown",this._onTapStart):(f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),_t.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,N())}function Lt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Kt(t){t.draggable=!1}function Wt(){Ot=!1}function zt(t){return setTimeout(t,0)}function Gt(t){return clearTimeout(t)}Ht.prototype={constructor:Ht,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(bt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,$):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Mt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Mt.push(o)}}(o),!$&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||nt===l)){if(rt=j(l),lt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return Z({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),q("filter",n,{evt:e}),void(i&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return Z({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),q("filter",n,{evt:e}),!0}))return void(i&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!$&&n.parentNode===r&&(o=X(n),tt=r,Q=($=n).parentNode,et=$.nextSibling,nt=n,ct=a.group,dt={target:Ht.dragged=$,clientX:(e||t).clientX,clientY:(e||t).clientY},gt=dt.clientX-o.left,mt=dt.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,$.style["will-change"]="all",o=function(){q("delayEnded",i,{evt:t}),Ht.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&($.draggable=!0),i._triggerDragStart(t,e),Z({sortable:i,name:"choose",originalEvent:t}),k($,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){E($,t.trim(),Kt)}),f(l,"dragover",Ft),f(l,"mousemove",Ft),f(l,"touchmove",Ft),a.supportPointer?(f(l,"pointerup",i._onDrop),this.nativeDraggable||f(l,"pointercancel",i._onDrop)):(f(l,"mouseup",i._onDrop),f(l,"touchend",i._onDrop),f(l,"touchcancel",i._onDrop)),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,$.draggable=!0),q("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ht.eventCanceled?this._onDrop():(a.supportPointer?(f(l,"pointerup",i._disableDelayedDrag),f(l,"pointercancel",i._disableDelayedDrag)):(f(l,"mouseup",i._disableDelayedDrag),f(l,"touchend",i._disableDelayedDrag),f(l,"touchcancel",i._disableDelayedDrag)),f(l,"mousemove",i._delayedDragTouchMoveHandler),f(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&f(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){$&&Kt($),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"pointerup",this._disableDelayedDrag),p(t,"pointercancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?f(document,"pointermove",this._onTouchMove):f(document,e?"touchmove":"mousemove",this._onTouchMove):(f($,"dragend",this),f(tt,"dragstart",this._onDragStart));try{document.selection?zt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;Et=!1,tt&&$?(q("dragStarted",this,{evt:e}),this.nativeDraggable&&f(document,"dragover",jt),n=this.options,t||k($,n.dragClass,!1),k($,n.ghostClass,!0),Ht.active=this,t&&this._appendGhost(),Z({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ht){this._lastX=ht.clientX,this._lastY=ht.clientY,Yt();for(var t=document.elementFromPoint(ht.clientX,ht.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ht.clientX,ht.clientY))!==e;)e=t;if($.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ht.clientX,clientY:ht.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=m(t=e));Bt()}},_onTouchMove:function(t){if(dt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=J&&D(J,!0),a=J&&r&&r.a,l=J&&r&&r.d,e=Nt&&Dt&&S(Dt),a=(i.clientX-dt.clientX+o.x)/(a||1)+(e?e[0]-xt[0]:0)/(a||1),l=(i.clientY-dt.clientY+o.y)/(l||1)+(e?e[1]-xt[1]:0)/(l||1);if(!Ht.active&&!Et){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))E.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>E.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,J),e?t.clientX<_.left-10||t.clientY65536?(i[0]=240|(1835008&n)>>>18,i[1]=128|(258048&n)>>>12,i[2]=128|(4032&n)>>>6,i[3]=128|63&n):n>2048?(i[0]=224|(61440&n)>>>12,i[1]=128|(4032&n)>>>6,i[2]=128|63&n):n>128?(i[0]=192|(1984&n)>>>6,i[1]=128|63&n):i[0]=n,this.parsedData.push(i)}this.parsedData=Array.prototype.concat.apply([],this.parsedData),this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function e(t,e){this.typeNumber=t,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}t.prototype={getLength:function(t){return this.parsedData.length},write:function(t){for(var e=0,r=this.parsedData.length;e=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,r)},setupPositionProbePattern:function(t,e){for(var r=-1;r<=7;r++)if(!(t+r<=-1||this.moduleCount<=t+r))for(var o=-1;o<=7;o++)e+o<=-1||this.moduleCount<=e+o||(this.modules[t+r][e+o]=0<=r&&r<=6&&(0==o||6==o)||0<=o&&o<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=o&&o<=4)},getBestMaskPattern:function(){for(var t=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var o=g.getLostPoint(this);(0==r||t>o)&&(t=o,e=r)}return e},createMovieClip:function(t,e,r){var o=t.createEmptyMovieClip(e,r);this.make();for(var i=0;i>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(r=0;r<18;r++){o=!t&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,o=g.getBCHTypeInfo(r),i=0;i<15;i++){var n=!t&&1==(o>>i&1);i<6?this.modules[i][8]=n:i<8?this.modules[i+1][8]=n:this.modules[this.moduleCount-15+i][8]=n}for(i=0;i<15;i++){n=!t&&1==(o>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=n:i<9?this.modules[8][15-i-1+1]=n:this.modules[8][15-i-1]=n}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,o=this.moduleCount-1,i=7,n=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var s=0;s<2;s++)if(null==this.modules[o][a-s]){var h=!1;n>>i&1)),g.getMask(e,o,a-s)&&(h=!h),this.modules[o][a-s]=h,-1==--i&&(n++,i=7)}if((o+=r)<0||this.moduleCount<=o){o-=r,r=-r;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(t,r,o){for(var i=m.getRSBlocks(t,r),n=new _,a=0;a8*h)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*h+")");for(n.getLengthInBits()+4<=8*h&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*h||(n.put(e.PAD0,8),n.getLengthInBits()>=8*h));)n.put(e.PAD1,8);return e.createBytes(n,i)},e.createBytes=function(t,e){for(var r=0,o=0,i=0,n=new Array(e.length),a=new Array(e.length),s=0;s=0?d.get(c):0}}var m=0;for(u=0;u=0;)e^=g.G15<=0;)e^=g.G18<>>=1;return e},getPatternPosition:function(t){return g.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case i:return(e+r)%2==0;case n:return e%2==0;case a:return r%3==0;case s:return(e+r)%3==0;case h:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case l:return e*r%2+e*r%3==0;case u:return(e*r%2+e*r%3)%2==0;case f:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new p([1],0),r=0;r5&&(r+=3+n-5)}for(o=0;o=256;)t-=255;return d.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},c=0;c<8;c++)d.EXP_TABLE[c]=1<>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};var v=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];function C(){var t=!1,e=navigator.userAgent;if(/android/i.test(e)){t=!0;var r=e.toString().match(/android ([0-9]\.[0-9])/i);r&&r[1]&&(t=parseFloat(r[1]))}return t}var w=function(){var t=function(t,e){this._el=t,this._htOption=e};return t.prototype.draw=function(t){var e=this._htOption,r=this._el,o=t.getModuleCount();Math.floor(e.width/o),Math.floor(e.height/o);function i(t,e){var r=document.createElementNS("http://www.w3.org/2000/svg",t);for(var o in e)e.hasOwnProperty(o)&&r.setAttribute(o,e[o]);return r}this.clear();var n=i("svg",{viewBox:"0 0 "+String(o)+" "+String(o),width:"100%",height:"100%",fill:e.colorLight});n.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),r.appendChild(n),n.appendChild(i("rect",{fill:e.colorLight,width:"100%",height:"100%"})),n.appendChild(i("rect",{fill:e.colorDark,width:"1",height:"1",id:"template"}));for(var a=0;a'],s=0;s");for(var h=0;h');a.push("")}a.push(""),r.innerHTML=a.join("");var l=r.childNodes[0],u=(e.width-l.offsetWidth)/2,f=(e.height-l.offsetHeight)/2;u>0&&f>0&&(l.style.margin=f+"px "+u+"px")},t.prototype.clear=function(){this._el.innerHTML=""},t}():function(){function t(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}if(this._android&&this._android<=2.1){var e=1/window.devicePixelRatio,r=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(t,o,i,n,a,s,h,l,u){if("nodeName"in t&&/img/i.test(t.nodeName))for(var f=arguments.length-1;f>=1;f--)arguments[f]=arguments[f]*e;else void 0===l&&(arguments[1]*=e,arguments[2]*=e,arguments[3]*=e,arguments[4]*=e);r.apply(this,arguments)}}var o=function(t,e){this._bIsPainted=!1,this._android=C(),this._htOption=e,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=e.width,this._elCanvas.height=e.height,t.appendChild(this._elCanvas),this._el=t,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.alt="Scan me!",this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return o.prototype.draw=function(t){var e=this._elImage,r=this._oContext,o=this._htOption,i=t.getModuleCount(),n=o.width/i,a=o.height/i,s=Math.round(n),h=Math.round(a);e.style.display="none",this.clear();for(var l=0;lv.length)throw new Error("Too long data");return r}(QRCode=function(t,e){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:o.H},"string"==typeof e&&(e={text:e}),e)for(var r in e)this._htOption[r]=e[r];"string"==typeof t&&(t=document.getElementById(t)),this._htOption.useSVG&&(D=w),this._android=C(),this._el=t,this._oQRCode=null,this._oDrawing=new D(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)}).prototype.makeCode=function(t){this._oQRCode=new e(A(t,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(t),this._oQRCode.make(),this._el.title=t,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=o}(),"undefined"!=typeof module&&(module.exports=QRCode); diff --git a/luci-app-passwall2/luasrc/controller/passwall2.lua b/luci-app-passwall2/luasrc/controller/passwall2.lua new file mode 100644 index 00000000..c3520cfc --- /dev/null +++ b/luci-app-passwall2/luasrc/controller/passwall2.lua @@ -0,0 +1,932 @@ +-- Copyright (C) 2022-2025 xiaorouji +-- Copyright (C) 2026 Openwrt-Passwall Organization + +module("luci.controller.passwall2", package.seeall) +local api = require "luci.passwall2.api" +local appname = api.appname -- not available +local uci = api.uci -- in funtion index() +local http = require "luci.http" +local util = require "luci.util" +local i18n = require "luci.i18n" +local fs = api.fs +local jsonStringify = luci.jsonc.stringify +local jsonParse = luci.jsonc.parse + +function index() + if not nixio.fs.access("/etc/config/passwall2") then + if nixio.fs.access("/usr/share/passwall2/0_default_config") then + luci.sys.call('cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2') + else return end + end + local api = require "luci.passwall2.api" + local appname = api.appname -- global definitions not available + local uci = api.uci -- in function index() + entry({"admin", "services", appname}).dependent = true + entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true + entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true + entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true + local e + if uci:get(appname, "@global[0]", "hide_from_luci") ~= "1" then + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("PassWall 2"), 0) + else + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, 0) + end + e.dependent = true + e.acl_depends = { "luci-app-passwall2" } + --[[ Client ]] + entry({"admin", "services", appname, "settings"}, cbi(appname .. "/client/global"), _("Basic Settings"), 1).dependent = true + entry({"admin", "services", appname, "node_list"}, cbi(appname .. "/client/node_list"), _("Node List"), 2).dependent = true + entry({"admin", "services", appname, "node_subscribe"}, cbi(appname .. "/client/node_subscribe"), _("Node Subscribe"), 3).dependent = true + entry({"admin", "services", appname, "other"}, cbi(appname .. "/client/other", {autoapply = true}), _("Other Settings"), 92).leaf = true + if nixio.fs.access("/usr/sbin/haproxy") then + entry({"admin", "services", appname, "haproxy"}, cbi(appname .. "/client/haproxy"), _("Load Balancing"), 93).leaf = true + end + entry({"admin", "services", appname, "app_update"}, cbi(appname .. "/client/app_update"), _("App Update"), 95).leaf = true + entry({"admin", "services", appname, "rule"}, cbi(appname .. "/client/rule"), _("Rule Manage"), 96).leaf = true + if api.finded_com("geoview") then + entry({"admin", "services", appname, "geoview"}, form(appname .. "/client/geoview"), _("Geo View"), 97).leaf = true + end + entry({"admin", "services", appname, "node_subscribe_config"}, cbi(appname .. "/client/node_subscribe_config")).leaf = true + entry({"admin", "services", appname, "node_config"}, cbi(appname .. "/client/node_config")).leaf = true + entry({"admin", "services", appname, "shunt_rules"}, cbi(appname .. "/client/shunt_rules")).leaf = true + entry({"admin", "services", appname, "socks_config"}, cbi(appname .. "/client/socks_config")).leaf = true + entry({"admin", "services", appname, "acl"}, cbi(appname .. "/client/acl"), _("Access control"), 98).leaf = true + entry({"admin", "services", appname, "acl_config"}, cbi(appname .. "/client/acl_config")).leaf = true + entry({"admin", "services", appname, "log"}, form(appname .. "/client/log"), _("Runtime Logs"), 999).leaf = true + + --[[ Server ]] + entry({"admin", "services", appname, "server"}, cbi(appname .. "/server/index"), _("Server-Side"), 99).leaf = true + entry({"admin", "services", appname, "server_user"}, cbi(appname .. "/server/user")).leaf = true + + --[[ API ]] + entry({"admin", "services", appname, "server_user_update"}, call("server_user_update")).leaf = true + entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true + entry({"admin", "services", appname, "server_user_log"}, call("server_user_log")).leaf = true + entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true + entry({"admin", "services", appname, "server_clear_log"}, call("server_clear_log")).leaf = true + entry({"admin", "services", appname, "link_add_node"}, call("link_add_node")).leaf = true + entry({"admin", "services", appname, "socks_autoswitch_add_node"}, call("socks_autoswitch_add_node")).leaf = true + entry({"admin", "services", appname, "socks_autoswitch_remove_node"}, call("socks_autoswitch_remove_node")).leaf = true + entry({"admin", "services", appname, "gen_client_config"}, call("gen_client_config")).leaf = true + entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true + entry({"admin", "services", appname, "get_redir_log"}, call("get_redir_log")).leaf = true + entry({"admin", "services", appname, "get_socks_log"}, call("get_socks_log")).leaf = true + entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true + entry({"admin", "services", appname, "clear_log"}, call("clear_log")).leaf = true + entry({"admin", "services", appname, "index_status"}, call("index_status")).leaf = true + entry({"admin", "services", appname, "haproxy_status"}, call("haproxy_status")).leaf = true + entry({"admin", "services", appname, "socks_status"}, call("socks_status")).leaf = true + entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true + entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true + entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true + entry({"admin", "services", appname, "add_node"}, call("add_node")).leaf = true + entry({"admin", "services", appname, "update_node"}, call("update_node")).leaf = true + entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true + entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true + entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true + entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true + entry({"admin", "services", appname, "reassign_group"}, call("reassign_group")).leaf = true + entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true + entry({"admin", "services", appname, "save_node_order"}, call("save_node_order")).leaf = true + entry({"admin", "services", appname, "save_node_list_opt"}, call("save_node_list_opt")).leaf = true + entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true + entry({"admin", "services", appname, "rollback_rules"}, call("rollback_rules")).leaf = true + entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true + entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true + entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true + entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true + entry({"admin", "services", appname, "flush_set"}, call("flush_set")).leaf = true + + --[[Components update]] + entry({"admin", "services", appname, "check_passwall2"}, call("app_check")).leaf = true + local coms = require "luci.passwall2.com" + local com + for com, _ in pairs(coms) do + entry({"admin", "services", appname, "check_" .. com}, call("com_check", com)).leaf = true + entry({"admin", "services", appname, "update_" .. com}, call("com_update", com)).leaf = true + end + + --[[Backup]] + entry({"admin", "services", appname, "create_backup"}, call("create_backup")).leaf = true + entry({"admin", "services", appname, "restore_backup"}, call("restore_backup")).leaf = true + + --[[geoview]] + entry({"admin", "services", appname, "geo_view"}, call("geo_view")).leaf = true +end + +local function http_write_json(content) + http.prepare_content("application/json") + http.write(jsonStringify(content or {code = 1})) +end + +local function http_write_json_ok(data) + http.prepare_content("application/json") + http.write(jsonStringify({code = 1, data = data})) +end + +local function http_write_json_error(data) + http.prepare_content("application/json") + http.write(jsonStringify({code = 0, data = data})) +end + +function reset_config() + luci.sys.call('/etc/init.d/passwall2 stop') + luci.sys.call('[ -f "/usr/share/passwall2/0_default_config" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2') + http.redirect(api.url()) +end + +function show_menu() + api.sh_uci_del(appname, "@global[0]", "hide_from_luci", true) + luci.sys.call("rm -rf /tmp/luci-*") + luci.sys.call("/etc/init.d/rpcd restart >/dev/null") + http.redirect(api.url()) +end + +function hide_menu() + api.sh_uci_set(appname, "@global[0]", "hide_from_luci", "1", true) + luci.sys.call("rm -rf /tmp/luci-*") + luci.sys.call("/etc/init.d/rpcd restart >/dev/null") + http.redirect(luci.dispatcher.build_url("admin", "status", "overview")) +end + +function link_add_node() + -- Fragmented reception to overcome uhttpd limitations + local tmp_file = "/tmp/links.conf" + local chunk = http.formvalue("chunk") + local chunk_index = tonumber(http.formvalue("chunk_index")) + local total_chunks = tonumber(http.formvalue("total_chunks")) + local group = http.formvalue("group") or "default" + + if chunk and chunk_index ~= nil and total_chunks ~= nil then + -- Assemble the files in order + local mode = "a" + if chunk_index == 0 then + mode = "w" + end + local f = io.open(tmp_file, mode) + if f then + f:write(chunk) + f:close() + end + -- If it's the last piece, then it will be executed. + if chunk_index + 1 == total_chunks then + luci.sys.call("lua /usr/share/passwall2/subscribe.lua add " .. group) + end + end +end + +function socks_autoswitch_add_node() + local id = http.formvalue("id") + local key = http.formvalue("key") + if id and id ~= "" and key and key ~= "" then + uci:set(appname, id, "enable_autoswitch", "1") + local new_list = uci:get(appname, id, "autoswitch_backup_node") or {} + for i = #new_list, 1, -1 do + if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then + table.remove(new_list, i) + end + end + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e["remark"]:find(key) then + table.insert(new_list, e.id) + end + end + uci:set_list(appname, id, "autoswitch_backup_node", new_list) + api.uci_save(uci, appname) + end + http.redirect(api.url("socks_config", id)) +end + +function socks_autoswitch_remove_node() + local id = http.formvalue("id") + local key = http.formvalue("key") + if id and id ~= "" and key and key ~= "" then + uci:set(appname, id, "enable_autoswitch", "1") + local new_list = uci:get(appname, id, "autoswitch_backup_node") or {} + for i = #new_list, 1, -1 do + if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then + table.remove(new_list, i) + end + end + uci:set_list(appname, id, "autoswitch_backup_node", new_list) + api.uci_save(uci, appname) + end + http.redirect(api.url("socks_config", id)) +end + +function gen_client_config() + local id = http.formvalue("id") + local config_file = api.TMP_PATH .. "/config_" .. id + luci.sys.call(string.format("/usr/share/passwall2/app.sh run_socks flag=config_%s node=%s bind=127.0.0.1 socks_port=1080 config_file=%s no_run=1", id, id, config_file)) + if nixio.fs.access(config_file) then + http.prepare_content("application/json") + http.write(luci.sys.exec("cat " .. config_file)) + luci.sys.call("rm -f " .. config_file) + else + http.redirect(api.url("node_list")) + end +end + +function get_now_use_node() + local e = {} + local node = api.get_cache_var("ACL_GLOBAL_node") + if node then + e["global"] = node + end + http_write_json(e) +end + +function get_redir_log() + local id = http.formvalue("id") + local name = http.formvalue("name") + local file_path = "/tmp/etc/passwall2/acl/" .. id .. "/" .. name .. ".log" + if nixio.fs.access(file_path) then + local content = luci.sys.exec("tail -n 19999 '" .. file_path .. "'") + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_socks_log() + local name = http.formvalue("name") + local path = "/tmp/etc/passwall2/SOCKS_" .. name .. ".log" + if nixio.fs.access(path) then + local content = luci.sys.exec("tail -n 5000 ".. path) + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_log() + -- luci.sys.exec("[ -f /tmp/log/passwall2.log ] && sed '1!G;h;$!d' /tmp/log/passwall2.log > /tmp/log/passwall2_show.log") + http.write(luci.sys.exec("[ -f '/tmp/log/passwall2.log' ] && cat /tmp/log/passwall2.log")) +end + +function clear_log() + luci.sys.call("echo '' > /tmp/log/passwall2.log") +end + +function index_status() + local e = {} + e["global_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall2/bin/' | grep 'default' | grep 'global' >/dev/null") == 0 + http_write_json(e) +end + +function haproxy_status() + local e = {} + e["status"] = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0 + http_write_json(e) +end + +function socks_status() + local e = {} + local index = http.formvalue("index") + local id = http.formvalue("id") + e.index = index + e.socks_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v -E 'grep|acl/|acl_' | grep '%s/bin/' | grep '%s' | grep 'SOCKS_' > /dev/null", appname, id)) == 0 + local use_http = uci:get(appname, id, "http_port") or 0 + e.use_http = 0 + if tonumber(use_http) > 0 then + e.use_http = 1 + e.http_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v -E 'grep|acl/|acl_' | grep '%s/bin/' | grep '%s' | grep -E 'HTTP_|HTTP2SOCKS' > /dev/null", appname, id)) == 0 + end + http_write_json(e) +end + +function connect_status() + local e = {} + e.use_time = "" + local url = http.formvalue("url") + local result = luci.sys.exec('curl --connect-timeout 3 -o /dev/null -I -sk -w "%{http_code}:%{time_appconnect}" ' .. url) + local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") + if code ~= 0 then + local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") + if use_time:find("%.") then + e.use_time = string.format("%.2f", use_time * 1000) + else + e.use_time = string.format("%.2f", use_time / 1000) + end + e.ping_type = "curl" + end + http_write_json(e) +end + +function ping_node() + local index = http.formvalue("index") + local address = http.formvalue("address") + local port = http.formvalue("port") + local type = http.formvalue("type") or "icmp" + local e = {} + e.index = index + if type == "tcping" and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then + if api.is_ipv6(address) then + address = api.get_ipv6_only(address) + end + e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, address)) + else + e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % address) + end + http_write_json(e) +end + +function urltest_node() + local index = http.formvalue("index") + local id = http.formvalue("id") + local e = {} + e.index = index + local result = luci.sys.exec(string.format("/usr/share/passwall2/test.sh url_test_node %s %s", id, "urltest_node")) + local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") + if code ~= 0 then + local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") + if use_time:find("%.") then + e.use_time = string.format("%.2f", use_time * 1000) + else + e.use_time = string.format("%.2f", use_time / 1000) + end + end + http_write_json(e) +end + +function add_node() + local redirect = http.formvalue("redirect") + + local uuid = api.gen_short_uuid() + uci:section(appname, "nodes", uuid) + + local group = http.formvalue("group") + if group and group ~= "default" then + uci:set(appname, uuid, "group", group) + end + + uci:set(appname, uuid, "type", "Xray") + + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_config", uuid)) + else + api.uci_save(uci, appname, true, true) + http_write_json({result = uuid}) + end +end + +function update_node() + local id = http.formvalue("id") -- Node id + local data = http.formvalue("data") -- json new Data + if id and data then + local data_t = jsonParse(data) or {} + if next(data_t) then + for k, v in pairs(data_t) do + uci:set(appname, id, k, v) + end + api.uci_save(uci, appname) + http_write_json_ok() + return + end + end + http_write_json_error() +end + +function set_node() + local type = http.formvalue("type") + local config = http.formvalue("config") + local section = http.formvalue("section") + uci:set(appname, type, config, section) + api.uci_save(uci, appname, true, true) + http.redirect(api.url("log")) +end + +function copy_node() + local section = http.formvalue("section") + local uuid = api.gen_short_uuid() + uci:section(appname, "nodes", uuid) + for k, v in pairs(uci:get_all(appname, section)) do + if not k:match("^%.") and k ~= "group" then + if k == "remarks" then v = (v or "") .. "(1)" end + uci:set(appname, uuid, k, v) + end + end + uci:set(appname, uuid, "add_mode", 1) + api.uci_save(uci, appname) + http.redirect(api.url("node_config", uuid)) +end + +function clear_all_nodes() + uci:set(appname, '@global[0]', "enabled", "0") + uci:set(appname, '@global[0]', "socks_enabled", "0") + uci:set(appname, '@haproxy_config[0]', "balancing_enable", "0") + uci:delete(appname, '@global[0]', "node") + uci:foreach(appname, "socks", function(t) + uci:delete(appname, t[".name"]) + uci:set_list(appname, t[".name"], "autoswitch_backup_node", {}) + end) + uci:foreach(appname, "haproxy_config", function(t) + uci:delete(appname, t[".name"]) + end) + uci:foreach(appname, "acl_rule", function(t) + uci:delete(appname, t[".name"], "node") + end) + uci:foreach(appname, "nodes", function(node) + uci:delete(appname, node['.name']) + end) + uci:foreach(appname, "subscribe_list", function(t) + uci:delete(appname, t[".name"], "md5") + uci:delete(appname, t[".name"], "chain_proxy") + uci:delete(appname, t[".name"], "preproxy_node") + uci:delete(appname, t[".name"], "to_node") + end) + + api.uci_save(uci, appname, true, true) +end + +function delete_select_nodes() + local ids = http.formvalue("ids") + local redirect = http.formvalue("redirect") + string.gsub(ids, '[^' .. "," .. ']+', function(w) + if (uci:get(appname, "@global[0]", "node") or "") == w then + uci:delete(appname, '@global[0]', "node") + end + uci:foreach(appname, "socks", function(t) + if t["node"] == w then + uci:delete(appname, t[".name"]) + end + local changed = false + local auto_switch_node_list = uci:get(appname, t[".name"], "autoswitch_backup_node") or {} + for i = #auto_switch_node_list, 1, -1 do + if w == auto_switch_node_list[i] then + table.remove(auto_switch_node_list, i) + changed = true + end + end + if changed then + uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list) + end + end) + uci:foreach(appname, "haproxy_config", function(t) + if t["lbss"] == w then + uci:delete(appname, t[".name"]) + end + end) + uci:foreach(appname, "acl_rule", function(t) + if t["node"] == w then + uci:delete(appname, t[".name"], "node") + end + end) + uci:foreach(appname, "nodes", function(t) + if t["preproxy_node"] == w then + uci:delete(appname, t[".name"], "preproxy_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + if t["to_node"] == w then + uci:delete(appname, t[".name"], "to_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + local list_name = t["urltest_node"] and "urltest_node" or (t["balancing_node"] and "balancing_node") + if list_name then + local nodes = uci:get_list(appname, t[".name"], list_name) + if nodes then + local changed = false + local new_nodes = {} + for _, node in ipairs(nodes) do + if node ~= w then + table.insert(new_nodes, node) + else + changed = true + end + end + if changed then + uci:set_list(appname, t[".name"], list_name, new_nodes) + end + end + end + if t["fallback_node"] == w then + uci:delete(appname, t[".name"], "fallback_node") + end + end) + uci:foreach(appname, "subscribe_list", function(t) + if t["preproxy_node"] == w then + uci:delete(appname, t[".name"], "preproxy_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + if t["to_node"] == w then + uci:delete(appname, t[".name"], "to_node") + uci:delete(appname, t[".name"], "chain_proxy") + end + end) + if (uci:get(appname, w, "add_mode") or "0") == "2" then + local group = uci:get(appname, w, "group") or "" + if group ~= "" then + uci:foreach(appname, "subscribe_list", function(t) + if t["remark"] == group then + uci:delete(appname, t[".name"], "md5") + end + end) + end + end + uci:delete(appname, w) + end) + if redirect == "1" then + api.uci_save(uci, appname) + http.redirect(api.url("node_list")) + else + api.uci_save(uci, appname, true, true) + end +end + +function get_node() + local id = http.formvalue("id") + local result = {} + local show_node_info = api.uci_get_type("global_other", "show_node_info", "0") + + local function add_is_ipv6_key(o) + if o and o.address and show_node_info == "1" then + local f = api.get_ipv6_full(o.address) + if f ~= "" then + o.ipv6 = true + o.full_address = f + end + end + end + + if id then + result = uci:get_all(appname, id) + add_is_ipv6_key(result) + else + local default_nodes = {} + local other_nodes = {} + uci:foreach(appname, "nodes", function(t) + add_is_ipv6_key(t) + if not t.group or t.group == "" then + default_nodes[#default_nodes + 1] = t + else + other_nodes[#other_nodes + 1] = t + end + end) + for i = 1, #default_nodes do result[#result + 1] = default_nodes[i] end + for i = 1, #other_nodes do result[#result + 1] = other_nodes[i] end + end + http_write_json(result) +end + +function save_node_order() + local ids = http.formvalue("ids") or "" + local new_order = {} + for id in ids:gmatch("([^,]+)") do + new_order[#new_order + 1] = id + end + for idx, name in ipairs(new_order) do + luci.sys.call(string.format("uci -q reorder %s.%s=%d", appname, name, idx - 1)) + end + api.sh_uci_commit(appname) + http_write_json({ status = "ok" }) +end + +function reassign_group() + local ids = http.formvalue("ids") or "" + local group = http.formvalue("group") or "default" + for id in ids:gmatch("([^,]+)") do + if group ~="" and group ~= "default" then + api.sh_uci_set(appname, id, "group", group) + else + api.sh_uci_del(appname, id, "group") + end + end + api.sh_uci_commit(appname) + http_write_json({ status = "ok" }) +end + +function save_node_list_opt() + local option = http.formvalue("option") or "" + local value = http.formvalue("value") or "" + if option ~= "" then + api.sh_uci_set(appname, "@global_other[0]", option, value, true) + end + http_write_json({ status = "ok" }) +end + +function update_rules() + local update = http.formvalue("update") or "" + if update == "" then + http_write_json_error({ message = "missing update target" }) + return + end + luci.sys.call("lua /usr/share/passwall2/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &") + http_write_json() +end + +function rollback_rules() + local arg_type = http.formvalue("type") + if arg_type ~= "geoip" and arg_type ~= "geosite" then + http_write_json_error() + return + end + local bak_dir = "/tmp/bak_v2ray/" + local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/") + fs.move(bak_dir .. arg_type .. ".dat", geo_dir .. arg_type .. ".dat") + fs.rmdir(bak_dir) + http_write_json_ok() +end + +function server_user_update() + local id = http.formvalue("id") -- Node id + local data = http.formvalue("data") -- json new Data + if id and data then + local data_t = jsonParse(data) or {} + if next(data_t) then + for k, v in pairs(data_t) do + uci:set(appname .. "_server", id, k, v) + end + api.uci_save(uci, appname .. "_server") + http_write_json_ok() + return + end + end + http_write_json_error() +end + +function server_user_status() + local e = {} + e.index = http.formvalue("index") + e.status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/bin/' | grep -i '%s' >/dev/null", appname .. "_server", http.formvalue("id"))) == 0 + http_write_json(e) +end + +function server_user_log() + local id = http.formvalue("id") + if nixio.fs.access("/tmp/etc/passwall2_server/" .. id .. ".log") then + local content = luci.sys.exec("cat /tmp/etc/passwall2_server/" .. id .. ".log") + content = content:gsub("\n", "
") + http.write(content) + else + http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function server_get_log() + http.write(luci.sys.exec("[ -f '/tmp/log/passwall2_server.log' ] && cat /tmp/log/passwall2_server.log")) +end + +function server_clear_log() + luci.sys.call("echo '' > /tmp/log/passwall2_server.log") +end + +function app_check() + local json = api.to_check_self() + http_write_json(json) +end + +function com_check(comname) + local json = api.to_check("", comname) + http_write_json(json) +end + +function com_update(comname) + local json = nil + local task = http.formvalue("task") + if task == "extract" then + json = api.to_extract(comname, http.formvalue("file"), http.formvalue("subfix")) + elseif task == "move" then + json = api.to_move(comname, http.formvalue("file")) + else + json = api.to_download(comname, http.formvalue("url"), http.formvalue("size")) + end + + http_write_json(json) +end + +local backup_files = { + "/etc/config/passwall2", + "/etc/config/passwall2_server", + "/usr/share/passwall2/domains_excluded" +} + +function create_backup() + local date = os.date("%y%m%d%H%M") + local tar_file = "/tmp/passwall2-" .. date .. "-backup.tar.gz" + fs.remove(tar_file) + local cmd = "tar -czf " .. tar_file .. " " .. table.concat(backup_files, " ") + api.sys.call(cmd) + http.header("Content-Disposition", "attachment; filename=passwall2-" .. date .. "-backup.tar.gz") + http.header("X-Backup-Filename", "passwall2-" .. date .. "-backup.tar.gz") + http.prepare_content("application/octet-stream") + http.write(fs.readfile(tar_file)) + fs.remove(tar_file) +end + +function restore_backup() + local result = { status = "error", message = "unknown error" } + local ok, err = pcall(function() + local filename = http.formvalue("filename") + local chunk = http.formvalue("chunk") + local chunk_index = tonumber(http.formvalue("chunk_index") or "-1") + local total_chunks = tonumber(http.formvalue("total_chunks") or "-1") + if not filename then + result = { status = "error", message = "Missing filename" } + return + end + if not chunk then + result = { status = "error", message = "Missing chunk data" } + return + end + local file_path = "/tmp/" .. filename + local decoded = nixio.bin.b64decode(chunk) + if not decoded then + result = { status = "error", message = "Base64 decode failed" } + return + end + local fp = io.open(file_path, "a+") + if not fp then + result = { status = "error", message = "Failed to open file: " .. file_path } + return + end + fp:write(decoded) + fp:close() + if chunk_index + 1 == total_chunks then + api.sys.call("echo '' > /tmp/log/passwall2.log") + api.log(0, string.format(" * PassWall2 %s", i18n.translate("Configuration file uploaded successfully…"))) + local temp_dir = '/tmp/passwall2_bak' + api.sys.call("mkdir -p " .. temp_dir) + if api.sys.call("tar -xzf " .. file_path .. " -C " .. temp_dir) == 0 then + for _, backup_file in ipairs(backup_files) do + local temp_file = temp_dir .. backup_file + if fs.access(temp_file) then + api.sys.call("cp -f " .. temp_file .. " " .. backup_file) + end + end + api.log(0, string.format(" * PassWall2 %s", i18n.translate("Configuration restored successfully…"))) + api.log(0, string.format(" * PassWall2 %s", i18n.translate("Service restarting…"))) + luci.sys.call('/etc/init.d/passwall2 restart > /dev/null 2>&1 &') + luci.sys.call('/etc/init.d/passwall2_server restart > /dev/null 2>&1 &') + result = { status = "success", message = "Upload completed", path = file_path } + else + api.log(0, string.format(" * PassWall2 %s", i18n.translate("Configuration file decompression failed, please try again!"))) + result = { status = "error", message = "Decompression failed" } + end + api.sys.call("rm -rf " .. temp_dir) + fs.remove(file_path) + else + result = { status = "success", message = "Chunk received" } + end + end) + if not ok then + result = { status = "error", message = tostring(err) } + end + http_write_json(result) +end + +function geo_view() + local action = luci.http.formvalue("action") + local value = luci.http.formvalue("value") + if not value or value == "" then + http.prepare_content("text/plain") + http.write(i18n.translate("Please enter query content!")) + return + end + local function get_rules(str, type) + local rules_id = {} + uci:foreach(appname, "shunt_rules", function(s) + local list + if type == "geoip" then list = s.ip_list else list = s.domain_list end + for line in string.gmatch((list or ""), "[^\r\n]+") do + if line ~= "" and not line:find("#") then + local prefix, main = line:match("^(.-):(.*)") + if not main then main = line end + if type == "geoip" and (api.datatypes.ipaddr(str) or api.datatypes.ip6addr(str)) then + if main:find(str, 1, true) then rules_id[#rules_id + 1] = s[".name"] end + else + if main == str then rules_id[#rules_id + 1] = s[".name"] end + end + end + end + end) + return rules_id + end + local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") + local geosite_path = geo_dir .. "/geosite.dat" + local geoip_path = geo_dir .. "/geoip.dat" + local geo_type, file_path, cmd + local geo_string = "" + local bin = api.finded_com("geoview") + if action == "lookup" then + if api.datatypes.ipaddr(value) or api.datatypes.ip6addr(value) then + geo_type, file_path = "geoip", geoip_path + else + geo_type, file_path = "geosite", geosite_path + end + cmd = string.format("%q -type %q -action lookup -input %q -value %q -lowmem=true", bin, geo_type, file_path, value) + geo_string = luci.sys.exec(cmd):lower() + if geo_string ~= "" then + local lines, rules, seen = {}, {}, {} + for line in geo_string:gmatch("([^\n]+)") do + lines[#lines + 1] = geo_type .. ":" .. line + for _, r in ipairs(get_rules(line, geo_type) or {}) do + if not seen[r] then seen[r] = true; rules[#rules + 1] = r end + end + end + for _, r in ipairs(get_rules(value, geo_type) or {}) do + if not seen[r] then seen[r] = true; rules[#rules + 1] = r end + end + geo_string = table.concat(lines, "\n") + if #rules > 0 then + geo_string = geo_string .. "\n--------------------\n" + geo_string = geo_string .. i18n.translate("Rules containing this value:") .. "\n" + geo_string = geo_string .. table.concat(rules, "\n") + end + end + elseif action == "extract" then + local prefix, list = value:match("^(geoip:)(.*)$") + if not prefix then + prefix, list = value:match("^(geosite:)(.*)$") + end + if prefix and list and list ~= "" then + geo_type = prefix:sub(1, -2) + file_path = (geo_type == "geoip") and geoip_path or geosite_path + cmd = string.format("%q -type %q -action extract -input %q -list %q -lowmem=true", bin, geo_type, file_path, list) + geo_string = luci.sys.exec(cmd) + end + end + http.prepare_content("text/plain") + if geo_string and geo_string ~="" then + http.write(geo_string) + else + http.write(i18n.translate("No results were found!")) + end +end + +function subscribe_del_node() + local remark = http.formvalue("remark") + if remark and remark ~= "" then + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate " .. luci.util.shellquote(remark) .. " > /dev/null 2>&1") + end + http.status(200, "OK") +end + +function subscribe_del_all() + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1") + http.status(200, "OK") +end + +function subscribe_manual() + local section = http.formvalue("section") or "" + local current_url = http.formvalue("url") or "" + if section == "" or current_url == "" then + http_write_json({ success = false, msg = "Missing section or URL, skip." }) + return + end + local uci_url = api.sh_uci_get(appname, section, "url") + if not uci_url or uci_url == "" then + http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") }) + return + end + if uci_url ~= current_url then + api.sh_uci_set(appname, section, "url", current_url, true) + end + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &") + http_write_json({ success = true, msg = "Subscribe triggered." }) +end + +function subscribe_manual_all() + local sections = http.formvalue("sections") or "" + local urls = http.formvalue("urls") or "" + if sections == "" or urls == "" then + http_write_json({ success = false, msg = "Missing section or URL, skip." }) + return + end + local section_list = util.split(sections, ",") + local url_list = util.split(urls, ",") + -- Check if there are any unsaved configurations. + for i, section in ipairs(section_list) do + local uci_url = api.sh_uci_get(appname, section, "url") + if not uci_url or uci_url == "" then + http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") }) + return + end + end + -- Save URLs that have changed. + for i, section in ipairs(section_list) do + local current_url = url_list[i] or "" + local uci_url = api.sh_uci_get(appname, section, "url") + if current_url ~= "" and uci_url ~= current_url then + api.sh_uci_set(appname, section, "url", current_url, true) + end + end + luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &") + http_write_json({ success = true, msg = "Subscribe triggered." }) +end + +function flush_set() + local redirect = http.formvalue("redirect") or "0" + local reload = http.formvalue("reload") or "0" + if reload == "1" then + uci:set(appname, '@global[0]', "flush_set", "1") + api.uci_save(uci, appname, true, true) + else + api.sh_uci_set(appname, "@global[0]", "flush_set", "1", true) + end + if redirect == "1" then + http.redirect(api.url("log")) + end +end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua new file mode 100644 index 00000000..3df0c9f7 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua @@ -0,0 +1,68 @@ +local api = require "luci.passwall2.api" +local appname = api.appname +local sys = api.sys + +m = Map(appname) +api.set_apply_on_parse(m) + +s = m:section(TypedSection, "global", translate("ACLs"), "" .. translate("ACLs is a tools which used to designate specific IP proxy mode.") .. "") +s.anonymous = true + +o = s:option(Flag, "acl_enable", translate("Main switch")) +o.rmempty = false +o.default = false + +-- [[ ACLs Settings ]]-- +s = m:section(TypedSection, "acl_rule") +s.template = "cbi/tblsection" +s.sortable = true +s.anonymous = true +s.addremove = true +s.extedit = api.url("acl_config", "%s") +function s.create(e, t) + t = TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +---- Remarks +o = s:option(Value, "remarks", translate("Remarks")) +o.rmempty = true + +local mac_t = {} +sys.net.mac_hints(function(e, t) + mac_t[e] = { + ip = t, + mac = e + } +end) + +o = s:option(DummyValue, "sources", translate("Source")) +o.rawhtml = true +o.cfgvalue = function(t, n) + local e = '' + local v = Value.cfgvalue(t, n) or '-' + string.gsub(v, '[^' .. " " .. ']+', function(w) + local a = w + if mac_t[w] then + a = a .. ' (' .. mac_t[w].ip .. ')' + end + if #e > 0 then + e = e .. "
" + end + e = e .. a + end) + return e +end + +i = s:option(DummyValue, "interface", translate("Source Interface")) +i.cfgvalue = function(t, n) + local v = Value.cfgvalue(t, n) or '-' + return v +end + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua new file mode 100644 index 00000000..b8b77501 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua @@ -0,0 +1,382 @@ +local api = require "luci.passwall2.api" +local appname = api.appname + +m = Map(appname) +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(api.url("acl")) +end + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local sys = api.sys + +local port_validate = function(self, value, t) + return value:gsub("-", ":") +end + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + nodes_table[#nodes_table + 1] = e +end + +local dynamicList_write = function(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + t = table.concat(t, " ") + return DynamicList.write(self, section, t) +end +local doh_validate = function(self, value, t) + if value ~= "" then + local flag = 0 + local util = require "luci.util" + local val = util.split(value, ",") + local url = val[1] + val[1] = nil + for i = 1, #val do + local v = val[i] + if v then + if not datatypes.ipmask4(v) then + flag = 1 + end + end + end + if flag == 0 then + return value + end + end + return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP" +end +-- [[ ACLs Settings ]]-- +s = m:section(NamedSection, arg[1], translate("ACLs"), translate("ACLs")) +s.addremove = false +s.dynamic = false + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +---- Remarks +o = s:option(Value, "remarks", translate("Remarks")) +o.default = arg[1] +o.rmempty = false + +o = s:option(Value, "interface", translate("Source Interface")) +o:value("", translate("All")) +local iface = api.get_network_devices() +for _, d in ipairs(iface) do + o:value(d.name, d.label) +end +o.validate = function(self, value, section) + if value == "" or value:match("^[a-zA-Z0-9][a-zA-Z0-9%.%_%-]*$") then + return value + end + return nil, translate("Invalid interface name") +end + +local mac_t = {} +sys.net.mac_hints(function(e, t) + mac_t[#mac_t + 1] = { + ip = t, + mac = e + } +end) +table.sort(mac_t, function(a,b) + if #a.ip < #b.ip then + return true + elseif #a.ip == #b.ip then + if a.ip < b.ip then + return true + else + return #a.ip < #b.ip + end + end + return false +end) + +---- Source +sources = s:option(DynamicList, "sources", translate("Source")) +sources.description = "
  • " .. translate("Example:") +.. "
  • " .. translate("MAC") .. ": 00:00:00:FF:FF:FF" +.. "
  • " .. translate("IP") .. ": 192.168.1.100" +.. "
  • " .. translate("IP CIDR") .. ": 192.168.1.0/24" +.. "
  • " .. translate("IP range") .. ": 192.168.1.100-192.168.1.200" +.. "
  • " .. translate("IPSet") .. ": ipset:lanlist" +.. "
" +sources.cast = "string" +for _, key in pairs(mac_t) do + sources:value(key.mac, "%s (%s)" % {key.mac, key.ip}) +end + +sources.cfgvalue = function(self, section) + local value + if self.tag_error[section] then + value = self:formvalue(section) + else + value = self.map:get(section, self.option) + if type(value) == "string" then + local value2 = {} + string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end) + value = value2 + end + end + return value +end +sources.validate = function(self, value, t) + local err = {} + for _, v in ipairs(value) do + local flag = false + if v:find("ipset:") and v:find("ipset:") == 1 then + local ipset = v:gsub("ipset:", "") + if ipset and ipset ~= "" then + flag = true + end + end + + if flag == false and datatypes.macaddr(v) then + flag = true + end + + if flag == false and datatypes.ip4addr(v) then + flag = true + end + + if flag == false and api.iprange(v) then + flag = true + end + + if flag == false then + err[#err + 1] = v + end + end + + if #err > 0 then + self:add_error(t, "invalid", translate("Not true format, please re-enter!")) + for _, v in ipairs(err) do + self:add_error(t, "invalid", v) + end + end + + return value +end +sources.write = dynamicList_write + +---- TCP No Redir Ports +local TCP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "tcp_no_redir_ports") +o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) +o:value("", translate("Use global config") .. "(" .. TCP_NO_REDIR_PORTS .. ")") +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +---- UDP No Redir Ports +local UDP_NO_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_no_redir_ports") +o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"), + "" .. + translate("If you don't want to let the device in the list to go proxy, please choose all.") .. + "") +o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")") +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +o = s:option(DummyValue, "_hide_node_option", "") +o.template = "passwall2/cbi/hidevalue" +o.value = "1" +o:depends({ tcp_no_redir_ports = "1:65535", udp_no_redir_ports = "1:65535" }) +if TCP_NO_REDIR_PORTS == "1:65535" and UDP_NO_REDIR_PORTS == "1:65535" then + o:depends({ tcp_no_redir_ports = "", udp_no_redir_ports = "" }) +end + +local GLOBAL_ENABLED = m:get("@global[0]", "enabled") +local NODE = m:get("@global[0]", "node") +o = s:option(ListValue, "node", "" .. translate("Node") .. "") +if GLOBAL_ENABLED == "1" and NODE then + o:value("", translate("Use global config") .. "(" .. api.get_node_name(NODE) .. ")") + o.group = {""} +else + o.group = {} +end +o:depends({ _hide_node_option = "1", ['!reverse'] = true }) +o.template = appname .. "/cbi/nodes_listvalue" + +current_node_id = o:formvalue(arg[1]) +if not current_node_id then + current_node_id = m.uci:get(appname, arg[1], "node") +end +current_node = current_node_id and m.uci:get_all(appname, current_node_id) or {} + +o = s:option(DummyValue, "_hide_dns_option", "") +o.template = "passwall2/cbi/hidevalue" +o.value = "1" +o:depends({ node = "" }) +if GLOBAL_ENABLED == "1" and NODE then + o:depends({ node = NODE }) +end + +---- TCP Redir Ports +local TCP_REDIR_PORTS = m:get("@global_forwarding[0]", "tcp_redir_ports") +o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports")) +o:value("", translate("Use global config") .. "(" .. TCP_REDIR_PORTS .. ")") +o:value("1:65535", translate("All")) +o:value("22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418", translate("Common Use")) +o:value("80,443", "80,443") +o.validate = port_validate +o:depends({ _hide_node_option = "1", ['!reverse'] = true }) + +---- UDP Redir Ports +local UDP_REDIR_PORTS = m:get("@global_forwarding[0]", "udp_redir_ports") +o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports")) +o:value("", translate("Use global config") .. "(" .. UDP_REDIR_PORTS .. ")") +o:value("1:65535", translate("All")) +o.validate = port_validate +o:depends({ _hide_node_option = "1", ['!reverse'] = true }) + +o = s:option(DummyValue, "tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', + translate("The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000.")) +end + +o = s:option(ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy")) +o.default = "UseIP" +o:value("UseIP") +o:value("UseIPv4") +o:value("UseIPv6") +o:depends({ _hide_dns_option = "1", ['!reverse'] = true }) + +o = s:option(ListValue, "remote_dns_protocol", translate("Remote DNS Protocol")) +o:value("tcp", "TCP") +o:value("doh", "DoH") +o:value("udp", "UDP") +if current_node.type == "sing-box" then + o:value("tls", "TLS(DoT)") + o:value("quic", "QUIC(DoQ)") + o:value("http3", "HTTP3(DoH3)") +end +o:depends({ _hide_dns_option = "1", ['!reverse'] = true }) + +---- DNS over TCP or UDP or TLS (DoT) or QUIC (DoQ) +o = s:option(Value, "remote_dns", translate("Remote DNS")) +o.datatype = "or(ipaddr,ipaddrport)" +o.default = "1.1.1.1" +o:value("1.1.1.1", "1.1.1.1 (CloudFlare)") +o:value("1.1.1.2", "1.1.1.2 (CloudFlare-Security)") +o:value("8.8.4.4", "8.8.4.4 (Google)") +o:value("8.8.8.8", "8.8.8.8 (Google)") +o:value("9.9.9.9", "9.9.9.9 (Quad9-Recommended)") +o:value("149.112.112.112", "149.112.112.112 (Quad9-Recommended)") +o:value("208.67.220.220", "208.67.220.220 (OpenDNS)") +o:value("208.67.222.222", "208.67.222.222 (OpenDNS)") +o:depends("remote_dns_protocol", "tcp") +o:depends("remote_dns_protocol", "udp") +o:depends("remote_dns_protocol", "quic") +o:depends("remote_dns_protocol", "tls") + +---- DNS over HTTP (DoH) or DNS over HTTP3(DoH3) +o = s:option(Value, "remote_dns_doh", translate("Remote DNS DoH")) +o:value("https://1.1.1.1/dns-query", "CloudFlare") +o:value("https://1.1.1.2/dns-query", "CloudFlare-Security") +o:value("https://8.8.4.4/dns-query", "Google 8844") +o:value("https://8.8.8.8/dns-query", "Google 8888") +o:value("https://9.9.9.9/dns-query", "Quad9-Recommended 9.9.9.9") +o:value("https://149.112.112.112/dns-query", "Quad9-Recommended 149.112.112.112") +o:value("https://208.67.222.222/dns-query", "OpenDNS") +o:value("https://dns.adguard.com/dns-query,94.140.14.14", "AdGuard") +o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS") +o:value("https://doh.libredns.gr/ads,116.202.176.26", "LibreDNS (No Ads)") +o.default = "https://1.1.1.1/dns-query" +o.validate = doh_validate +o:depends("remote_dns_protocol", "doh") +o:depends("remote_dns_protocol", "http3") + +o = s:option(Value, "remote_dns_client_ip", translate("Remote DNS EDNS Client Subnet")) +o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "
" .. + translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).") +o.datatype = "ipaddr" +o:depends("remote_dns_protocol", "tcp") +o:depends("remote_dns_protocol", "doh") +o:depends("remote_dns_protocol", "udp") +o:depends("remote_dns_protocol", "http3") +o:depends("remote_dns_protocol", "quic") +o:depends("remote_dns_protocol", "tls") + +o = s:option(ListValue, "remote_dns_detour", translate("Remote DNS Outbound")) +o.default = "remote" +o:value("remote", translate("Remote")) +o:value("direct", translate("Direct")) +o:depends("remote_dns_protocol", "tcp") +o:depends("remote_dns_protocol", "doh") +o:depends("remote_dns_protocol", "udp") +o:depends("remote_dns_protocol", "http3") +o:depends("remote_dns_protocol", "quic") +o:depends("remote_dns_protocol", "tls") + +o = s:option(Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy.")) +o.default = "0" +o.rmempty = false + +o = s:option(ListValue, "remote_dns_query_strategy", translate("Remote Query Strategy")) +o.default = "UseIPv4" +o:value("UseIP") +o:value("UseIPv4") +o:value("UseIPv6") +o:depends("remote_dns_protocol", "tcp") +o:depends("remote_dns_protocol", "doh") +o:depends("remote_dns_protocol", "udp") +o:depends("remote_dns_protocol", "http3") +o:depends("remote_dns_protocol", "quic") +o:depends("remote_dns_protocol", "tls") + +o = s:option(ListValue, "dns_hosts_mode", translate("Domain Override")) +o:value("default", translate("Use global config")) +o:value("disable", translate("No patterns are used")) +o:value("custom", translate("-- custom --")) + +o = s:option(TextValue, "dns_hosts", translate("Domain Override")) +o.rows = 5 +o.wrap = "off" +o:depends("dns_hosts_mode", "custom") +o.remove = function(self, section) + local node_value = s.fields["node"]:formvalue(arg[1]) + if node_value then + local node_t = m:get(node_value) or {} + if node_t.type == "Xray" or node_t.type == "sing-box" then + AbstractValue.remove(self, section) + end + end +end + +local o_node = s.fields["node"] + +for k, v in pairs(nodes_table) do + o_node:value(v.id, v["remark"]) + o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + if v.node_type == "normal" or v.protocol == "_balancing" or v.protocol == "_urltest" then + --Shunt node has its own separate options. + s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tcp" }) + s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "doh" }) + s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "udp" }) + s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "http3" }) + s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "quic" }) + s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tls" }) + end +end + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/app_update.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/app_update.lua new file mode 100644 index 00000000..5649b016 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/app_update.lua @@ -0,0 +1,29 @@ +local api = require "luci.passwall2.api" +local appname = api.appname + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ App Settings ]]-- +s = m:section(TypedSection, "global_app", translate("App Update"), + "" .. + translate("Please confirm that your firmware supports FPU.") .. + "") +s.anonymous = true +s:append(Template(appname .. "/app_update/app_version")) + +local k, v +local com = require "luci.passwall2.com" +for k, v in pairs(com) do + o = s:option(Value, k:gsub("%-","_") .. "_file", translatef("%s App Path", v.name)) + o.default = v.default_path or ("/usr/bin/" .. k) + o.rmempty = false +end + +o = s:option(DummyValue, "tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', translate("if you want to run from memory, change the path, /tmp beginning then save the application and update it manually.")) +end + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/geoview.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/geoview.lua new file mode 100644 index 00000000..071d8e80 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/geoview.lua @@ -0,0 +1,16 @@ +local api = require "luci.passwall2.api" +local appname = "passwall2" +local fs = api.fs +local uci = api.uci + +local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") +local geosite_path = geo_dir .. "/geosite.dat" +local geoip_path = geo_dir .. "/geoip.dat" +if fs.access(geosite_path) and fs.access(geoip_path) then + f = SimpleForm(appname) + f.reset = false + f.submit = false + f:append(Template(appname .. "/rule/geoview")) +end + +return f \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua new file mode 100644 index 00000000..103af778 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua @@ -0,0 +1,387 @@ +api = require "luci.passwall2.api" +appname = api.appname +datatypes = api.datatypes +has_singbox = api.finded_com("sing-box") +has_xray = api.finded_com("xray") + +m = Map(appname) +api.set_apply_on_parse(m) + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + nodes_table[#nodes_table + 1] = e +end + +local normal_list = {} +local balancing_list = {} +local urltest_list = {} +local shunt_list = {} +local iface_list = {} +for k, v in pairs(nodes_table) do + if v.node_type == "normal" then + normal_list[#normal_list + 1] = v + end + if v.protocol and v.protocol == "_balancing" then + balancing_list[#balancing_list + 1] = v + end + if v.protocol and v.protocol == "_urltest" then + urltest_list[#urltest_list + 1] = v + end + if v.protocol and v.protocol == "_shunt" then + shunt_list[#shunt_list + 1] = v + end + if v.protocol and v.protocol == "_iface" then + iface_list[#iface_list + 1] = v + end +end + +local socks_list = {} +m.uci:foreach(appname, "socks", function(s) + if s.enabled == "1" and s.node then + socks_list[#socks_list + 1] = { + id = "Socks_" .. s[".name"], + remark = translate("Socks Config") .. " [" .. s.port .. translate("Port") .. "]", + group = "Socks" + } + end +end) + +local doh_validate = function(self, value, t) + if value ~= "" then + local flag = 0 + local util = require "luci.util" + local val = util.split(value, ",") + local url = val[1] + val[1] = nil + for i = 1, #val do + local v = val[i] + if v then + if not datatypes.ipmask4(v) and not datatypes.ipmask6(v) then + flag = 1 + end + end + end + if flag == 0 then + return value + end + end + return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP" +end + +m:append(Template(appname .. "/global/status")) + +global_cfgid = m:get("@global[0]")[".name"] + +s = m:section(TypedSection, "global") +s.anonymous = true +s.addremove = false + +s:tab("Main", translate("Main")) + +-- [[ Global Settings ]]-- +o = s:taboption("Main", Flag, "enabled", translate("Main switch")) +o.rmempty = false + +---- Node +o = s:taboption("Main", ListValue, "node", "" .. translate("Node") .. "") +o.template = appname .. "/cbi/nodes_listvalue" +o:value("", translate("Close")) +o.group = {""} + +current_node_id = m.uci:get(appname, global_cfgid, "node") +current_node = current_node_id and m.uci:get_all(appname, current_node_id) or {} + +-- Shunt Start +if (has_singbox or has_xray) and #nodes_table > 0 then + if #normal_list > 0 or #iface_list > 0 then + if current_node.protocol == "_shunt" then + local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua") + setfenv(shunt_lua, getfenv(1))(m, s, { + node_id = current_node_id, + node = current_node, + socks_list = socks_list, + urltest_list = urltest_list, + balancing_list = balancing_list, + iface_list = iface_list, + normal_list = normal_list, + verify_option = s.fields["node"], + tab = "Shunt", + tab_desc = translate("Shunt Rule") + }) + end + else + local tips = s:taboption("Main", DummyValue, "tips", " ") + tips.rawhtml = true + tips.cfgvalue = function(t, n) + return string.format('%s', translate("There are no available nodes, please add or subscribe nodes first.")) + end + tips:depends({ node = "", ["!reverse"] = true }) + for k, v in pairs(shunt_list) do + tips:depends("node", v.id) + end + for k, v in pairs(balancing_list) do + tips:depends("node", v.id) + end + end +end + +---- Check the transparent proxy component +local handle = io.popen("lsmod") +local mods = "" +if handle then + mods = handle:read("*a") or "" + handle:close() +end + +if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then + o = s:taboption("Main", Flag, "localhost_proxy", translate("Localhost Proxy"), translate("When selected, localhost can transparent proxy.")) + o.default = "1" + o.rmempty = false + + o = s:taboption("Main", Flag, "client_proxy", translate("Client Proxy"), translate("When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy.")) + o.default = "1" + o.rmempty = false +else + local html = string.format([[
%s
]], translate("Missing components, transparent proxy is unavailable.")) + o = s:taboption("Main", DummyValue, "localhost_proxy", translate("Localhost Proxy")) + o.rawhtml = true + function o.cfgvalue(self, section) + return html + end + + o = s:taboption("Main", DummyValue, "client_proxy", translate("Client Proxy")) + o.rawhtml = true + function o.cfgvalue(self, section) + return html + end +end + +node_socks_port = s:taboption("Main", Value, "node_socks_port", translate("Node") .. " Socks " .. translate("Listen Port")) +node_socks_port.default = 1070 +node_socks_port.datatype = "port" + +node_socks_bind_local = s:taboption("Main", Flag, "node_socks_bind_local", translate("Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +node_socks_bind_local.default = "1" +node_socks_bind_local:depends({ node = "", ["!reverse"] = true }) + +s:tab("DNS", translate("DNS")) + +o = s:taboption("DNS", TextValue, "direct_dns_shunt", translate("Direct domain DNS routing")) +o.description = "
    " +.. "
  • " .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.") .. "
  • " +.. "
  • " .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.") .. "
  • " +.. "
  • " .. translate("Such as:") .. "
  • " +.. "
  • " .. "domain:my-nodes.com tcp://223.5.5.5" .. "
  • " +.. "
  • " .. "domain:vpn.com udp://119.29.29.29:53" .. "
  • " +.. "
  • " .. "full:www.dnspod.com https://120.53.53.53/dns-query" .. "
  • " +.. "
  • " .. '' .. translate("Please note that the program will not start if the format is incorrect!") .. '' .. "
  • " +.. "
" +o.rows = 3 +o.wrap = "off" + +o = s:taboption("DNS", ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy")) +o.default = "UseIP" +o:value("UseIP") +o:value("UseIPv4") +o:value("UseIPv6") + +o = s:taboption("DNS", ListValue, "remote_dns_protocol", translate("Remote DNS Protocol")) +o:value("tcp", "TCP") +o:value("doh", "DoH") +o:value("udp", "UDP") +if current_node.type == "sing-box" then + o:value("tls", "TLS(DoT)") + o:value("quic", "QUIC(DoQ)") + o:value("http3", "HTTP3(DoH3)") +end + +---- DNS over TCP or UDP or TLS (DoT) or QUIC (DoQ) +o = s:taboption("DNS", Value, "remote_dns", translate("Remote DNS")) +o.datatype = "or(ipaddr,ipaddrport)" +o.default = "1.1.1.1" +o:value("1.1.1.1", "1.1.1.1 (CloudFlare)") +o:value("1.1.1.2", "1.1.1.2 (CloudFlare-Security)") +o:value("8.8.4.4", "8.8.4.4 (Google)") +o:value("8.8.8.8", "8.8.8.8 (Google)") +o:value("9.9.9.9", "9.9.9.9 (Quad9-Recommended)") +o:value("149.112.112.112", "149.112.112.112 (Quad9-Recommended)") +o:value("208.67.220.220", "208.67.220.220 (OpenDNS)") +o:value("208.67.222.222", "208.67.222.222 (OpenDNS)") +o:depends("remote_dns_protocol", "tcp") +o:depends("remote_dns_protocol", "udp") +o:depends("remote_dns_protocol", "quic") +o:depends("remote_dns_protocol", "tls") + +---- DNS over HTTP (DoH) or DNS over HTTP3(DoH3) +o = s:taboption("DNS", Value, "remote_dns_doh", translate("Remote DNS DoH")) +o.default = "https://1.1.1.1/dns-query" +o:value("https://1.1.1.1/dns-query", "CloudFlare") +o:value("https://1.1.1.2/dns-query", "CloudFlare-Security") +o:value("https://8.8.4.4/dns-query", "Google 8844") +o:value("https://8.8.8.8/dns-query", "Google 8888") +o:value("https://9.9.9.9/dns-query", "Quad9-Recommended 9.9.9.9") +o:value("https://149.112.112.112/dns-query", "Quad9-Recommended 149.112.112.112") +o:value("https://208.67.222.222/dns-query", "OpenDNS") +o:value("https://dns.adguard.com/dns-query,94.140.14.14", "AdGuard") +o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS") +o:value("https://doh.libredns.gr/ads,116.202.176.26", "LibreDNS (No Ads)") +o.validate = doh_validate +o:depends("remote_dns_protocol", "doh") +o:depends("remote_dns_protocol", "http3") + +o = s:taboption("DNS", Value, "remote_dns_client_ip", translate("Remote DNS EDNS Client Subnet")) +o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "
" .. + translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).") +o.datatype = "ipaddr" + +o = s:taboption("DNS", ListValue, "remote_dns_detour", translate("Remote DNS Outbound")) +o.default = "remote" +o:value("remote", translate("Remote")) +o:value("direct", translate("Direct")) + +o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy.")) +o.default = "0" +o.rmempty = false + +o = s:taboption("DNS", ListValue, "remote_dns_query_strategy", translate("Remote Query Strategy")) +o.default = "UseIPv4" +o:value("UseIP") +o:value("UseIPv4") +o:value("UseIPv6") + +o = s:taboption("DNS", TextValue, "dns_hosts", translate("Domain Override")) +o.rows = 5 +o.wrap = "off" +o.remove = function(self, section) + local node_value = s.fields["node"]:formvalue(global_cfgid) + if node_value then + local node_t = m:get(node_value) or {} + if node_t.type == "Xray" or node_t.type == "sing-box" then + AbstractValue.remove(self, section) + end + end +end + +o = s:taboption("DNS", Flag, "dns_redirect", translate("DNS Redirect"), translate("Force special DNS server to need proxy devices.")) +o.default = "1" +o.rmempty = false + +local prefer_nft = m:get("@global_forwarding[0]", "prefer_nft") == "1" +local set_title = api.i18n.translate(prefer_nft and "Clear NFTSET" or "Clear IPSET") +o = s:taboption("DNS", DummyValue, "clear_ipset", set_title, translate("Try this feature if the rule modification does not take effect.")) +o.rawhtml = true +function o.cfgvalue(self, section) + return string.format( + [[]], + api.url("flush_set") .. "?redirect=1&reload=1", set_title) +end + +s:tab("log", translate("Log")) +o = s:taboption("log", Flag, "log_node", translate("Enable Node Log")) +o.default = "1" +o.rmempty = false + +loglevel = s:taboption("log", ListValue, "loglevel", translate("Log Level")) +loglevel.default = "warning" +loglevel:value("debug") +loglevel:value("info") +loglevel:value("warning") +loglevel:value("error") + +s:tab("faq", "FAQ") + +o = s:taboption("faq", DummyValue, "") +o.template = appname .. "/global/faq" + +s:tab("maintain", translate("Maintain")) +o = s:taboption("maintain", DummyValue, "") +o.template = appname .. "/global/backup" + +-- [[ Socks Server ]]-- +o = s:taboption("Main", Flag, "socks_enabled", "Socks " .. translate("Main switch")) +o.rmempty = false + +s2 = m:section(TypedSection, "socks", translate("Socks Config")) +s2.template = "cbi/tblsection" +s2.anonymous = true +s2.addremove = true +s2.extedit = api.url("socks_config", "%s") +function s2.create(e, t) + local uuid = api.gen_short_uuid() + t = uuid + TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end + +o = s2:option(DummyValue, "status", translate("Status")) +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('
', n) +end + +---- Enable +o = s2:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +o = s2:option(ListValue, "node", translate("Socks Node")) +o.template = appname .. "/cbi/nodes_listvalue" +o.group = {} + +o = s2:option(DummyValue, "now_node", translate("Current Node")) +o.rawhtml = true +o.cfgvalue = function(_, n) + local current_node = api.get_cache_var("socks_" .. n) + if current_node then + local node = m:get(current_node) + if node then + return (api.get_node_remarks(node) or ""):gsub("(:)%[", "%1
[") + end + end +end + +local n = 1 +m.uci:foreach(appname, "socks", function(s) + if s[".name"] == section then + return false + end + n = n + 1 +end) + +o = s2:option(Value, "port", "Socks " .. translate("Listen Port")) +o.default = n + 1080 +o.datatype = "port" +o.rmempty = false + +if has_singbox or has_xray then + o = s2:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) + o.default = 0 + o.datatype = "port" +end + +local o_node = s.fields["node"] +local o_socks = s2.fields["node"] +for k, v in pairs(nodes_table) do + if #normal_list == 0 and #iface_list == 0 then + break + end + o_node:value(v.id, v["remark"]) + o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + o_socks:value(v.id, v["remark"]) + o_socks.group[#o_socks.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + if v.node_type == "normal" or v.protocol == "_balancing" or v.protocol == "_urltest" then + --Shunt node has its own separate options. + s.fields["remote_fakedns"]:depends({ node = v.id }) + end +end + +local footer = Template(appname .. "/global/footer") +footer.api = api +footer.global_cfgid = global_cfgid +footer.shunt_list = api.jsonc.stringify(shunt_list) + +m:append(footer) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua new file mode 100644 index 00000000..0f2ea0fa --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/haproxy.lua @@ -0,0 +1,180 @@ +local api = require "luci.passwall2.api" +local appname = api.appname +local datatypes = api.datatypes +local net = require "luci.model.network".init() + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + obj = e, + remarks = e["remark"], + group = e["group"] + } + end +end + +m = Map(appname) +api.set_apply_on_parse(m) + +m:append(Template(appname .. "/cbi/nodes_value_com")) + +-- [[ Haproxy Settings ]]-- +s = m:section(TypedSection, "global_haproxy", translate("Basic Settings")) +s.anonymous = true + +s:append(Template(appname .. "/haproxy/status")) + +---- Balancing Enable +o = s:option(Flag, "balancing_enable", translate("Enable Load Balancing")) +o.rmempty = false +o.default = false + +---- Console Login Auth +o = s:option(Flag, "console_auth", translate("Console Login Auth")) +o.default = false +o:depends("balancing_enable", true) + +---- Console Username +o = s:option(Value, "console_user", translate("Console Username")) +o.default = "" +o:depends("console_auth", true) + +---- Console Password +o = s:option(Value, "console_password", translate("Console Password")) +o.password = true +o.default = "" +o:depends("console_auth", true) + +---- Console Port +o = s:option(Value, "console_port", translate("Console Port"), translate("In the browser input routing IP plus port access, such as:192.168.1.1:1188")) +o.datatype = "port" +o.default = 1188 +o:depends("balancing_enable", true) + +o = s:option(Flag, "bind_local", translate("Haproxy Port") .. " " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" +o:depends("balancing_enable", true) + +o = s:option(ListValue, "balancingStrategy", translate("Balancing Strategy")) +o:value("roundrobin", "roundRobin") +o:value("random", "random") +o:value("leastconn", "leastConn") +o:value("source", "source") +o.default = "roundrobin" +o:depends("balancing_enable", true) + +---- Health Check Type +o = s:option(ListValue, "health_check_type", translate("Health Check Type")) +o.default = "passwall_logic" +o:value("tcp", "TCP") +o:value("passwall_logic", translate("URL Test") .. string.format("(passwall %s)", translate("Inner implement"))) +o:depends("balancing_enable", true) + +---- Passwall Inner implement Probe URL +o = s:option(Value, "health_probe_url", translate("Probe URL")) +o.default = "https://www.google.com/generate_204" +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.description = translate("The URL used to detect the connection status.") +o:depends("health_check_type", "passwall_logic") + +---- Health Check Inter +o = s:option(Value, "health_check_inter", translate("Health Check Inter")) +o.datatype = "min(20)" +o.default = 60 +o:depends("balancing_enable", true) +o.description = translate("Units:seconds") .. " ( ≥ 20s )" + +o = s:option(DummyValue, "health_check_tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', translate("When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid.")) +end +o:depends("health_check_type", "passwall_logic") + +-- [[ Balancing Settings ]]-- +s = m:section(TypedSection, "haproxy_config", translate("Node List")) +s.description = "" .. + translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "
" .. + translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. "
" +s.template = "cbi/tblsection" +s.sortable = true +s.anonymous = true +s.addremove = true + +s.create = function(e, t) + TypedSection.create(e, api.gen_short_uuid()) +end + +s.remove = function(self, section) + for k, v in pairs(self.children) do + v.rmempty = true + v.validate = nil + end + TypedSection.remove(self, section) +end + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +---- Node Address +o = s:option(Value, "lbss", translate("Node Address")) +o.template = appname .. "/cbi/nodes_value" +o.group = {} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +o.rmempty = false +o.validate = function(self, value) + if not value then return nil, translate("Node address cannot be empty.") end + local t = m:get(value) or nil + if t and t[".type"] == "nodes" then + return value + end + if datatypes.hostport(value) or datatypes.ip4addrport(value) then + return value + end + if api.is_ipv6addrport(value) then + return value + end + return nil, translate("Not valid IP format, please re-enter!") .. " (IP:Port)" +end + +---- Haproxy Port +o = s:option(Value, "haproxy_port", translate("Haproxy Port")) +o.datatype = "port" +o.default = 1181 +o.rmempty = false + +---- Node Weight +o = s:option(Value, "lbweight", translate("Node Weight")) +o.datatype = "min(1)" +o.default = 5 +o.rmempty = false + +---- Export +o = s:option(ListValue, "export", translate("Export Of Multi WAN")) +o:value(0, translate("Auto")) +local wa = require "luci.tools.webadmin" +wa.cbi_add_networks(o) +o.default = 0 +o.rmempty = false + +---- Mode +o = s:option(ListValue, "backup", translate("Mode")) +o:value(0, translate("Primary")) +o:value(1, translate("Standby")) +o.rmempty = false + +m:append(Template(appname .. "/haproxy/js")) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/include/shunt_options.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/include/shunt_options.lua new file mode 100644 index 00000000..e1218026 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/include/shunt_options.lua @@ -0,0 +1,204 @@ +local m, s, data = ... + +if not data.node_id or not data.node then + return +end + +local current_node_id = data.node_id +local node_list = data.node_list or api.get_node_list() + +local function get_cfgvalue() + return function(self, section) + return m:get(current_node_id, self.option) + end +end +local function get_write() + return function(self, section, value) + if data.verify_option then + if data.verify_option:formvalue(section) == current_node_id then + m:set(current_node_id, self.option, value) + end + else + m:set(current_node_id, self.option, value) + end + end +end +local function get_remove() + return function(self, section) + if data.verify_option then + if data.verify_option:formvalue(section) == current_node_id then + m:del(current_node_id, self.option) + end + else + m:del(current_node_id, self.option) + end + end +end + +if data.tab then + s:tab(data.tab, data.tab_desc) +end + +local function add_option(class, option_name, option_title, option_desc) + local a + if data.tab then + a = s:taboption(data.tab, class, option_name, option_title) + else + a = s:option(class, option_name, option_title) + end + if a then + if option_desc then + a.description = option_desc + end + a.cfgvalue = get_cfgvalue() + a.write = get_write() + a.remove = get_remove() + end + if data.verify_option then + a:depends(data.verify_option.option, current_node_id) + end + return a +end + +local function add_depends(o, deps) + if #o.deps > 0 then + for index, value in ipairs(o.deps) do + for k, v in pairs(deps) do + o.deps[index][k] = v + end + end + else + o:depends(deps) + end +end + +if data.node.type == "Xray" then + o = add_option(ListValue, "domainStrategy", translate("Domain Strategy")) + o:value("AsIs") + o:value("IPIfNonMatch") + o:value("IPOnDemand") + o.default = "IPOnDemand" + o.description = "
  • " .. translate("'AsIs': Only use domain for routing. Default value.") + .. "
  • " .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.") + .. "
  • " .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.") + .. "
" + + o = add_option(ListValue, "domainMatcher", translate("Domain matcher")) + o:value("hybrid") + o:value("linear") +end + +o = add_option(Flag, "fakedns", 'FakeDNS' .. " " .. translate("Main switch"), translate("Use FakeDNS work in the domain that proxy.") .. "
" .. + translate("Suitable scenarios for let the node servers get the target domain names.") .. "
" .. + translate("Such as: DNS unlocking of streaming media, reducing DNS query latency, etc.")) + +o = add_option(Flag, "write_ipset_direct", translate("Direct DNS result write to IPSet"), translate("Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core).") .. " " .. translate("Maybe conflict with some special circumstances.")) +o.default = 1 +o.rmempty = false + +if api.is_finded("geoview") then + o = add_option(Flag, "enable_geoview_ip", translate("Enable GeoIP Data Parsing")) + o.default = 1 + o.rmempty = false + o.description = "
    " + .. "
  • " .. translate("Analyzes and preloads GeoIP data to enhance the shunt performance.") .. "
  • " + .. "
  • " .. translate("Note: Increases resource usage.") .. " " .. translate("Maybe conflict with some special circumstances.") .. "
  • " + .. "
" +end + +local shunt_rules = {} +m.uci:foreach(appname, "shunt_rules", function(e) + e.id = e[".name"] + e.remarks = e.remarks or e[".name"] + e["_node_option"] = e[".name"] + e["_node_default"] = "" + e["_fakedns_option"] = e[".name"] .. "_fakedns" + e["_proxy_tag_option"] = e[".name"] .. "_proxy_tag" + table.insert(shunt_rules, e) +end) +table.insert(shunt_rules, { + id = ".default", + remarks = translate("Default"), + _node_option = "default_node", + _node_default = "_direct", + _fakedns_option = "default_fakedns", + _proxy_tag_option = "default_proxy_tag", +}) + +s2 = m:section(Table, shunt_rules, " ") +s2.config = appname +s2.sectiontype = "shunt_option_list" + +o = s2:option(DummyValue, "remarks", translate("Rule")) +o.rawhtml = true +o.cfgvalue = function(self, section) + if shunt_rules[section].id == ".default" then + return string.format('%s', shunt_rules[section].remarks) + else + return string.format('%s', api.url("shunt_rules", shunt_rules[section].id), shunt_rules[section].remarks) + end +end + +_node = s2:option(Value, "_node", translate("Node")) +_node.template = appname .. "/cbi/nodes_listvalue" +_node.group = {"","","",""} +_node:value("", translate("Close (Not use)")) +_node:value("_default", translate("Use default node")) +_node:value("_direct", translate("Direct Connection")) +_node:value("_blackhole", translate("Blackhole (Block)")) +_node.cfgvalue = function(self, section) + return m:get(current_node_id, shunt_rules[section]["_node_option"]) or shunt_rules[section]["_node_default"] +end +_node.write = function(self, section, value) + return m:set(current_node_id, shunt_rules[section]["_node_option"], value) +end +_node.remove = function(self, section) + return m:del(current_node_id, shunt_rules[section]["_node_option"]) +end + +o = s2:option(Flag, "_fakedns", string.format('FakeDNS', translate("Use FakeDNS work in the domain that proxy.") .. "\n" .. + translate("Suitable scenarios for let the node servers get the target domain names.") .. "\n" .. + translate("Such as: DNS unlocking of streaming media, reducing DNS query latency, etc."))) +o.cfgvalue = function(self, section) + return m:get(current_node_id, shunt_rules[section]["_fakedns_option"]) +end +o.write = function(self, section, value) + return m:set(current_node_id, shunt_rules[section]["_fakedns_option"], value) +end +o.remove = function(self, section) + return m:del(current_node_id, shunt_rules[section]["_fakedns_option"]) +end + +proxy_tag_node = s2:option(ListValue, "_proxy_tag", string.format('%s', + translate("Set the node to be used as a pre-proxy.") .. "\n" .. translate("Each rule has a separate switch that controls whether this rule uses the pre-proxy or not."), + translate("Preproxy"))) +proxy_tag_node.template = appname .. "/cbi/nodes_listvalue" +proxy_tag_node.group = {""} +proxy_tag_node:value("", translate("Close (Not use)")) +proxy_tag_node.cfgvalue = function(self, section) + return m:get(current_node_id, shunt_rules[section]["_proxy_tag_option"]) +end +proxy_tag_node.write = function(self, section, value) + return m:set(current_node_id, shunt_rules[section]["_proxy_tag_option"], value) +end +proxy_tag_node.remove = function(self, section) + return m:del(current_node_id, shunt_rules[section]["_proxy_tag_option"]) +end + +for k1, v1 in pairs(node_list) do + if k1 ~= "shunt_list" then + for i, v in ipairs(v1) do + _node:value(v.id, v.remark) + _node.group[#_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + + proxy_tag_node:value(v.id, v.remark) + proxy_tag_node.group[#proxy_tag_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end +end + +local footer = Template(appname .. "/include/shunt_options") +footer.api = api +footer.id = current_node_id +footer.normal_list = api.jsonc.stringify(node_list.normal_list) +m:append(footer) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/log.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/log.lua new file mode 100644 index 00000000..a9102b69 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/log.lua @@ -0,0 +1,8 @@ +local appname = "passwall2" + +f = SimpleForm(appname) +f.reset = false +f.submit = false +f:append(Template(appname .. "/log/log")) + +return f \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua new file mode 100644 index 00000000..5051bd7b --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua @@ -0,0 +1,100 @@ +api = require "luci.passwall2.api" +appname = api.appname + +m = Map(appname, translate("Node Config")) +m.redirect = api.url() +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(api.url("node_list")) +end + +fs = require "nixio.fs" +formvalue_key = "cbid." .. appname .. "." .. arg[1] .. "." + +local header = Template(appname .. "/node_config/header") +header.api = api +header.config = m.config +header.section = arg[1] +m:append(header) + +m:append(Template(appname .. "/cbi/nodes_multivalue_com")) +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +groups = {} +m.uci:foreach(appname, "nodes", function(s) + if s[".name"] ~= arg[1] then + if s.group and s.group ~= "" then + groups[s.group] = true + end + end +end) + +s = m:section(NamedSection, arg[1], "nodes", "") +s.addremove = false +s.dynamic = false + +o = s:option(DummyValue, "passwall2", " ") +o.rawhtml = true +o.template = "passwall2/node_config/link_share_man" +o.value = arg[1] + +o = s:option(Value, "remarks", translate("Node Remarks")) +o.default = translate("Remarks") +o.rmempty = false + +o = s:option(Value, "group", translate("Group Name")) +o.default = "" +o:value("", translate("default")) +for k, v in pairs(groups) do + o:value(k) +end +o.write = function(self, section, value) + value = api.trim(value) + local lower = value:lower() + + if lower == "" or lower == "default" then + return m:del(section, self.option) + end + + for _, v in ipairs(self.keylist or {}) do + if v:lower() == lower then + return m:set(section, self.option, v) + end + end + m:set(section, self.option, value) +end + +local types_dir = "/usr/lib/lua/luci/model/cbi/passwall2/client/type/" +s.val = {} +s.val["type"] = m.uci:get(appname, arg[1], "type") +s.val["protocol"] = m.uci:get(appname, arg[1], "protocol") + +if luci.http.formvalue("cbi.submit") == "1" then + local formvalue_type = luci.http.formvalue(formvalue_key .. "type") + if formvalue_type then + s.val["type"] = formvalue_type + end +end + +o = s:option(ListValue, "type", translate("Type")) + +local type_table = {} +for filename in fs.dir(types_dir) do + table.insert(type_table, filename) +end +table.sort(type_table) + +for index, value in ipairs(type_table) do + local p_func = loadfile(types_dir .. value) + setfenv(p_func, getfenv(1))(m, s) +end + +local footer = Template(appname .. "/node_config/footer") +footer.api = api +footer.config = m.config +footer.section = arg[1] + +m:append(footer) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_list.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_list.lua new file mode 100644 index 00000000..3265dcd9 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_list.lua @@ -0,0 +1,35 @@ +local api = require "luci.passwall2.api" +local appname = api.appname +local datatypes = api.datatypes +local sys = api.sys + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ Other Settings ]]-- +s = m:section(TypedSection, "global_other") +s.anonymous = true + +o = s:option(ListValue, "auto_detection_time", translate("Automatic detection delay")) +o:value("0", translate("Close")) +o:value("icmp", "Ping") +o:value("tcping", "TCP Ping") + +o = s:option(Flag, "show_node_info", translate("Show server address and port")) +o.default = "0" + +o = s:option(Value, "url_test_url", translate("URL Test Address")) +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.default = o.keylist[3] + +-- [[ Add the node via the link ]]-- +s:append(Template(appname .. "/node_list/link_add_node")) + +m:append(Template(appname .. "/node_list/node_list")) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua new file mode 100644 index 00000000..7140ac5c --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua @@ -0,0 +1,224 @@ +local api = require "luci.passwall2.api" +local appname = api.appname +local uci = api.uci +local has_ss_rust = api.is_finded("sslocal") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") +local ss_type = {} +local trojan_type = {} +local vmess_type = {} +local vless_type = {} +local hysteria2_type = {} +local xray_version = api.get_app_version("xray") +if has_ss_rust then + local s = "shadowsocks-rust" + table.insert(ss_type, s) +end +if has_singbox then + local s = "sing-box" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + table.insert(hysteria2_type, s) +end +if has_xray then + local s = "xray" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + if api.compare_versions(xray_version, ">=", "26.1.13") then + table.insert(hysteria2_type, s) + end +end +if has_hysteria2 then + local s = "hysteria2" + table.insert(hysteria2_type, s) +end + +m = Map(appname) +api.set_apply_on_parse(m) + +function m.on_before_save(self) + self.uci:foreach(appname, "subscribe_list", function(e) + self:del(e[".name"], "md5") + end) +end + +-- [[ Subscribe Settings ]]-- +s = m:section(TypedSection, "global_subscribe", "") +s.anonymous = true + +o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode")) +o:value("0", translate("Close")) +o:value("1", translate("Discard List")) +o:value("2", translate("Keep List")) +o:value("3", translate("Discard List,But Keep List First")) +o:value("4", translate("Keep List,But Discard List First")) + +o = s:option(DynamicList, "filter_discard_list", translate("Discard List")) + +o = s:option(DynamicList, "filter_keep_list", translate("Keep List")) + +if #ss_type > 0 then + o = s:option(ListValue, "ss_type", translatef("%s Node Use Type", "Shadowsocks")) + o:value("", translate("Auto")) + for key, value in pairs(ss_type) do + o:value(value) + end +end + +if #trojan_type > 0 then + o = s:option(ListValue, "trojan_type", translatef("%s Node Use Type", "Trojan")) + o:value("", translate("Auto")) + for key, value in pairs(trojan_type) do + o:value(value) + end +end + +if #vmess_type > 0 then + o = s:option(ListValue, "vmess_type", translatef("%s Node Use Type", "VMess")) + o:value("", translate("Auto")) + for key, value in pairs(vmess_type) do + o:value(value) + end +end + +if #vless_type > 0 then + o = s:option(ListValue, "vless_type", translatef("%s Node Use Type", "VLESS")) + o:value("", translate("Auto")) + for key, value in pairs(vless_type) do + o:value(value) + end +end + +if #hysteria2_type > 0 then + o = s:option(ListValue, "hysteria2_type", translatef("%s Node Use Type", "Hysteria2")) + o:value("", translate("Auto")) + for key, value in pairs(hysteria2_type) do + o:value(value) + end +end + +if #ss_type > 0 or #trojan_type > 0 or #vmess_type > 0 or #vless_type > 0 or #hysteria2_type > 0 then + o.description = string.format("%s", + translate("The configured type also applies to the core specified when manually importing nodes.")) +end + +---- Subscribe Delete All +o = s:option(DummyValue, "_stop", translate("Delete All Subscribe Node")) +o.rawhtml = true +function o.cfgvalue(self, section) + return string.format( + [[]], + translate("Delete All Subscribe Node")) +end + +o = s:option(DummyValue, "_update", translate("Manual subscription All")) +o.rawhtml = true +o.cfgvalue = function(self, section) + return string.format([[ + ]], + translate("Manual subscription All")) +end + +s = m:section(TypedSection, "subscribe_list", "", "" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "") +s.addremove = true +s.anonymous = true +s.sortable = true +s.template = "cbi/tblsection" +s.extedit = api.url("node_subscribe_config", "%s") +function s.create(e, t) + local id = TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(id)) +end + +o = s:option(Value, "remark", translate("Remarks")) +o.width = "auto" +o.rmempty = false +o.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translate("Remark cannot be empty.") + end + local duplicate = false + m.uci:foreach(appname, "subscribe_list", function(e) + if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then + duplicate = true + return false + end + end) + if duplicate or value:lower() == "default" then + return nil, translate("This remark already exists, please change a new remark.") + end + return value +end +o.write = function(self, section, value) + local old = m:get(section, self.option) or "" + if old ~= value then + m.uci:foreach(appname, "nodes", function(e) + if e["group"] and e["group"]:lower() == old:lower() then + m.uci:set(appname, e[".name"], "group", value) + end + if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then + local gs = "" + for g in e["node_group"]:gmatch("%S+") do + if api.UrlEncode(old) == g then + gs = gs .. " " .. api.UrlEncode(value) + else + gs = gs .. " " .. g + end + end + gs = api.trim(gs) + m.uci:set(appname, e[".name"], "node_group", gs) + end + end) + end + return Value.write(self, section, value) +end + +o = s:option(DummyValue, "_node_count", translate("Subscribe Info")) +o.rawhtml = true +o.cfgvalue = function(t, n) + local remark = m:get(n, "remark") or "" + local str = m:get(n, "rem_traffic") or "" + local expired_date = m:get(n, "expired_date") or "" + if expired_date ~= "" then + str = str .. (str ~= "" and "/" or "") .. expired_date + end + str = str ~= "" and "
" .. str or "" + local num = 0 + m.uci:foreach(appname, "nodes", function(s) + if s["group"] and s["group"]:lower() == remark:lower() then + num = num + 1 + end + end) + return string.format("%s%s", translate("Node num") .. ": " .. num, str) +end + +o = s:option(Value, "url", translate("Subscribe URL")) +o.width = "auto" +o.rmempty = false + +o = s:option(DummyValue, "_remove", translate("Delete the subscribed node")) +o.rawhtml = true +function o.cfgvalue(self, section) + local remark = m:get(section, "remark") or "" + return string.format( + [[]], + remark, translate("Delete the subscribed node")) +end + +o = s:option(DummyValue, "_update", translate("Manual subscription")) +o.rawhtml = true +o.cfgvalue = function(self, section) + return string.format([[ + ]], + section, translate("Manual subscription")) +end + +m:append(Template(appname .. "/node_subscribe/js")) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua new file mode 100644 index 00000000..1cc68769 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua @@ -0,0 +1,328 @@ +local api = require "luci.passwall2.api" +local appname = api.appname + +m = Map(appname) +m.redirect = api.url("node_subscribe") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +function m.on_before_save(self) + self:del(arg[1], "md5") +end + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local has_ss_rust = api.is_finded("sslocal") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") +local ss_type = {} +local trojan_type = {} +local vmess_type = {} +local vless_type = {} +local hysteria2_type = {} +local xray_version = api.get_app_version("xray") +if has_ss_rust then + local s = "shadowsocks-rust" + table.insert(ss_type, s) +end +if has_singbox then + local s = "sing-box" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + table.insert(hysteria2_type, s) +end +if has_xray then + local s = "xray" + table.insert(trojan_type, s) + table.insert(ss_type, s) + table.insert(vmess_type, s) + table.insert(vless_type, s) + if api.compare_versions(xray_version, ">=", "26.1.13") then + table.insert(hysteria2_type, s) + end +end +if has_hysteria2 then + local s = "hysteria2" + table.insert(hysteria2_type, s) +end +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + remark = e["remark"], + type = e["type"], + add_mode = e["add_mode"], + chain_proxy = e["chain_proxy"], + group = e["group"] + } + end +end + +s = m:section(NamedSection, arg[1]) +s.addremove = false +s.dynamic = false + +o = s:option(Value, "remark", translate("Subscribe Remark")) +o.rmempty = false +o.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translate("Remark cannot be empty.") + end + local duplicate = false + m.uci:foreach(appname, "subscribe_list", function(e) + if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then + duplicate = true + return false + end + end) + if duplicate or value:lower() == "default" then + return nil, translate("This remark already exists, please change a new remark.") + end + return value +end +o.write = function(self, section, value) + local old = m:get(section, self.option) or "" + if old ~= value then + m.uci:foreach(appname, "nodes", function(e) + if e["group"] and e["group"]:lower() == old:lower() then + m.uci:set(appname, e[".name"], "group", value) + end + if e["protocol"] and (e["protocol"] == "_balancing" or e["protocol"] == "_urltest") and e["node_group"] then + local gs = "" + for g in e["node_group"]:gmatch("%S+") do + if api.UrlEncode(old) == g then + gs = gs .. " " .. api.UrlEncode(value) + else + gs = gs .. " " .. g + end + end + gs = api.trim(gs) + m.uci:set(appname, e[".name"], "node_group", gs) + end + end) + end + return Value.write(self, section, value) +end + +o = s:option(TextValue, "url", translate("Subscribe URL")) +o.rows = 5 +o.rmempty = false +o.validate = function(self, value) + if not value or value == "" then + return nil, translate("URL cannot be empty.") + end + return value:gsub("%s+", ""):gsub("%z", "") +end + +o = s:option(ListValue, "domain_resolver", translate("Domain DNS Resolve")) +o.description = translate("If the node address is a domain name, this DNS will be used for resolution.") .. "
" .. + translate("Supports only Xray or Sing-box node types.") +o:value("", translate("Auto")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("https", "DoH") + +o = s:option(Value, "domain_resolver_dns", "DNS") +o.datatype = "or(ipaddr,ipaddrport)" +o:value("114.114.114.114") +o:value("223.5.5.5:53") +o.default = o.keylist[1] +o:depends({ domain_resolver = "tcp" }) +o:depends({ domain_resolver = "udp" }) + +o = s:option(Value, "domain_resolver_dns_https", "DNS") +o:value("https://120.53.53.53/dns-query", "DNSPod") +o:value("https://223.5.5.5/dns-query", "AliDNS") +o.default = o.keylist[1] +o:depends({ domain_resolver = "https" }) + +o = s:option(ListValue, "domain_strategy", translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) +o.default = "" +o:value("", translate("Auto")) +o:value("UseIPv4", translate("IPv4 Only")) +o:value("UseIPv6", translate("IPv6 Only")) + +o = s:option(Flag, "allowInsecure", translate("allowInsecure")) +o.default = "0" +o.rmempty = false +o.description = translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.") .. "
" .. + translate("Used when the node link does not include this parameter.") + +o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode")) +o.default = "5" +o:value("0", translate("Close")) +o:value("1", translate("Discard List")) +o:value("2", translate("Keep List")) +o:value("3", translate("Discard List,But Keep List First")) +o:value("4", translate("Keep List,But Discard List First")) +o:value("5", translate("Use global config")) + +o = s:option(DynamicList, "filter_discard_list", translate("Discard List")) +o:depends("filter_keyword_mode", "1") +o:depends("filter_keyword_mode", "3") +o:depends("filter_keyword_mode", "4") + +o = s:option(DynamicList, "filter_keep_list", translate("Keep List")) +o:depends("filter_keyword_mode", "2") +o:depends("filter_keyword_mode", "3") +o:depends("filter_keyword_mode", "4") + +if #ss_type > 0 then + o = s:option(ListValue, "ss_type", translatef("%s Node Use Type", "Shadowsocks")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(ss_type) do + o:value(value) + end +end + +if #trojan_type > 0 then + o = s:option(ListValue, "trojan_type", translatef("%s Node Use Type", "Trojan")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(trojan_type) do + o:value(value) + end +end + +if #vmess_type > 0 then + o = s:option(ListValue, "vmess_type", translatef("%s Node Use Type", "VMess")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(vmess_type) do + o:value(value) + end +end + +if #vless_type > 0 then + o = s:option(ListValue, "vless_type", translatef("%s Node Use Type", "VLESS")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(vless_type) do + o:value(value) + end +end + +if #hysteria2_type > 0 then + o = s:option(ListValue, "hysteria2_type", translatef("%s Node Use Type", "Hysteria2")) + o.default = "global" + o:value("global", translate("Use global config")) + for key, value in pairs(hysteria2_type) do + o:value(value) + end + + o = s:option(Value, "hysteria_up_mbps", "Hy/Hy2 " .. translate("Max upload Mbps")) + o.datatype = "uinteger" + o.default = "100" + + o = s:option(Value, "hysteria_down_mbps", "Hy/Hy2 " .. translate("Max download Mbps")) + o.datatype = "uinteger" + o.default = "100" +end + +o = s:option(Flag, "boot_update", translate("Update Once on Boot"), translate("Updates the subscription the first time runs automatically after each system boot.")) +o.default = 0 + +---- Enable auto update subscribe +o = s:option(Flag, "auto_update", translate("Enable auto update subscribe")) +o.default = 0 +o.rmempty = false + +---- Week Update +o = s:option(ListValue, "week_update", translate("Update Mode")) +o:value(8, translate("Loop Mode")) +o:value(7, translate("Every day")) +o:value(1, translate("Every Monday")) +o:value(2, translate("Every Tuesday")) +o:value(3, translate("Every Wednesday")) +o:value(4, translate("Every Thursday")) +o:value(5, translate("Every Friday")) +o:value(6, translate("Every Saturday")) +o:value(0, translate("Every Sunday")) +o.default = 7 +o:depends("auto_update", true) +o.rmempty = true + +---- Time Update +o = s:option(ListValue, "time_update", translate("Update Time(every day)")) +for t = 0, 23 do o:value(t, t .. ":00") end +o.default = 0 +o:depends("week_update", "0") +o:depends("week_update", "1") +o:depends("week_update", "2") +o:depends("week_update", "3") +o:depends("week_update", "4") +o:depends("week_update", "5") +o:depends("week_update", "6") +o:depends("week_update", "7") +o.rmempty = true + +---- Interval Update +o = s:option(ListValue, "interval_update", translate("Update Interval(hour)")) +for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end +o.default = 2 +o:depends("week_update", "8") +o.rmempty = true + +o = s:option(ListValue, "access_mode", translate("Subscribe URL Access Method")) +o.default = "" +o:value("", translate("Auto")) +o:value("direct", translate("Direct Connection")) +o:value("proxy", translate("Proxy")) + +o = s:option(Value, "user_agent", translate("User-Agent")) +o.default = "v2rayN/9.99" +o:value("curl", "Curl") +o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Linux") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Windows") +o:value("passwall2", "PassWall2") +o:value("v2rayN/9.99", "v2rayN") + +o = s:option(ListValue, "chain_proxy", translate("Chain Proxy")) +o:value("", translate("Close(Not use)")) +o:value("1", translate("Preproxy Node")) +o:value("2", translate("Landing Node")) +o:value("3", translate("Outbound Interface")) + +local descrStr = "Chained proxy works only with Xray or Sing-box nodes.
" +descrStr = descrStr .. "You can only use manual or imported nodes as chained nodes." +descrStr = translate(descrStr) .. "
" .. translate("Only support a layer of proxy.") + +o1 = s:option(ListValue, "preproxy_node", translate("Preproxy Node")) +o1:depends({ ["chain_proxy"] = "1" }) +o1.description = descrStr +o1.template = appname .. "/cbi/nodes_listvalue" +o1.group = {} + +o2 = s:option(ListValue, "to_node", translate("Landing Node")) +o2:depends({ ["chain_proxy"] = "2" }) +o2.description = descrStr +o2.template = appname .. "/cbi/nodes_listvalue" +o2.group = {} + +o3 = s:option(Value, "outbound_iface", translate("Outbound Interface")) +o3:depends({ ["chain_proxy"] = "3" }) +o3:value("", translate("All")) +local iface = api.get_network_devices() +for _, d in ipairs(iface) do + o3:value(d.name, d.label) +end + +for k, v in pairs(nodes_table) do + if (v.type == "Xray" or v.type == "sing-box") and (not v.chain_proxy or v.chain_proxy == "") and v.add_mode ~= "2" then + o1:value(v.id, v.remark) + o1.group[#o1.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + o2:value(v.id, v.remark) + o2.group[#o2.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end +end + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua new file mode 100644 index 00000000..25913c94 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua @@ -0,0 +1,262 @@ +local api = require "luci.passwall2.api" +local appname = api.appname +local fs = api.fs +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") + +local port_validate = function(self, value, t) + return value:gsub("-", ":") +end + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ Delay Settings ]]-- +s = m:section(TypedSection, "global_delay", translate("Delay Settings")) +s.anonymous = true +s.addremove = false + +---- Open and close Daemon +o = s:option(Flag, "start_daemon", translate("Open and close Daemon")) +o.default = 1 +o.rmempty = false + +---- Delay Start +o = s:option(Value, "start_delay", translate("Delay Start"), translate("Units:seconds")) +o.default = "1" +o.rmempty = true + +for index, value in ipairs({"stop", "start", "restart"}) do + o = s:option(ListValue, value .. "_week_mode", translate(value .. " automatically mode")) + o:value("", translate("Disable")) + o:value(8, translate("Loop Mode")) + o:value(7, translate("Every day")) + o:value(1, translate("Every Monday")) + o:value(2, translate("Every Tuesday")) + o:value(3, translate("Every Wednesday")) + o:value(4, translate("Every Thursday")) + o:value(5, translate("Every Friday")) + o:value(6, translate("Every Saturday")) + o:value(0, translate("Every Sunday")) + + o = s:option(ListValue, value .. "_time_mode", translate(value .. " Time(Every day)")) + for t = 0, 23 do o:value(t, t .. ":00") end + o.default = 0 + o:depends(value .. "_week_mode", "0") + o:depends(value .. "_week_mode", "1") + o:depends(value .. "_week_mode", "2") + o:depends(value .. "_week_mode", "3") + o:depends(value .. "_week_mode", "4") + o:depends(value .. "_week_mode", "5") + o:depends(value .. "_week_mode", "6") + o:depends(value .. "_week_mode", "7") + + o = s:option(ListValue, value .. "_interval_mode", translate(value .. " Interval(Hour)")) + for t = 1, 24 do o:value(t, t .. " " .. translate("Hour")) end + o.default = 2 + o:depends(value .. "_week_mode", "8") +end + +-- [[ Forwarding Settings ]]-- +s = m:section(TypedSection, "global_forwarding", translate("Forwarding Settings")) +s.anonymous = true +s.addremove = false + +---- TCP No Redir Ports +o = s:option(Value, "tcp_no_redir_ports", translate("TCP No Redir Ports")) +o.default = "disable" +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +---- UDP No Redir Ports +o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"), + "" .. + translate("Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") .. + "") +o.default = "disable" +o:value("disable", translate("No patterns are used")) +o:value("1:65535", translate("All")) +o.validate = port_validate + +---- TCP Redir Ports +o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports")) +o.default = "22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418" +o:value("1:65535", translate("All")) +o:value("22,25,53,80,143,443,465,587,853,873,993,995,5222,8080,8443,9418", translate("Common Use")) +o:value("80,443", translate("Only Web")) +o.validate = port_validate + +---- UDP Redir Ports +o = s:option(Value, "udp_redir_ports", translate("UDP Redir Ports")) +o.default = "1:65535" +o:value("1:65535", translate("All")) +o.validate = port_validate + +o = s:option(DummyValue, "tips", " ") +o.rawhtml = true +o.cfgvalue = function(t, n) + return string.format('%s', + translate("The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000.")) +end + +---- Use nftables +o = s:option(ListValue, "prefer_nft", translate("Prefer firewall tools")) +o.default = "1" +o:value("0", "Iptables") +o:value("1", "Nftables") + +---- Check the transparent proxy component +local handle = io.popen("lsmod") +local mods = "" +if handle then + mods = handle:read("*a") or "" + handle:close() +end + +if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then + o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way")) + o.default = "redirect" + o:value("redirect", "REDIRECT") + o:value("tproxy", "TPROXY") + o:depends("ipv6_tproxy", false) + o.remove = function(self, section) + -- Do not delete while hidden + end + + o = s:option(ListValue, "_tcp_proxy_way", translate("TCP Proxy Way")) + o.default = "tproxy" + o:value("tproxy", "TPROXY") + o:depends("ipv6_tproxy", true) + o.write = function(self, section, value) + self.map:set(section, "tcp_proxy_way", value) + end + + if mods:find("ip6table_mangle") or mods:find("nft_tproxy") then + ---- IPv6 TProxy + o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"), + "" .. + translate("Experimental feature. Make sure that your node supports IPv6.") .. + "") + o.default = 0 + o.rmempty = false + end +end + +o = s:option(Flag, "accept_icmp", translate("Hijacking ICMP (PING)")) +o.default = 0 + +o = s:option(Flag, "accept_icmpv6", translate("Hijacking ICMPv6 (IPv6 PING)")) +o:depends("ipv6_tproxy", true) +o.default = 0 + +o = s:option(DynamicList, "force_proxy_lan_ip", translate("Force Proxy LAN IP"), translate("By default, commonly used internal network IP ranges will be connect directly (not entering the core). If you want a certain network range to go through a proxy, please add it here.")) +o.datatype = "or(ipmask4,ipmask6)" + +if has_xray then + s_xray = m:section(TypedSection, "global_xray", "Xray " .. translate("Settings")) + s_xray.anonymous = true + s_xray.addremove = false + + o = s_xray:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists.")) + o.default = 0 + + o = s_xray:option(ListValue, "fragment_packets", translate("Fragment Packets"), translate(" \"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation.")) + o.default = "tlshello" + o:value("tlshello", "tlshello") + o:value("1-1", "1-1") + o:value("1-2", "1-2") + o:value("1-3", "1-3") + o:value("1-5", "1-5") + o:depends("fragment", true) + + o = s_xray:option(Value, "fragment_length", translate("Fragment Length"), translate("Fragmented packet length (byte)")) + o.datatype = "or(uinteger,portrange)" + o.default = "100-200" + o:depends("fragment", true) + + o = s_xray:option(Value, "fragment_delay", translate("Fragment Delay"), translate("Fragmentation interval (ms)")) + o.datatype = "or(uinteger,portrange)" + o.default = "10-20" + o:depends("fragment", true) + + o = s_xray:option(Value, "fragment_maxSplit", translate("Max Split"), translate("Limit the maximum number of splits.")) + o.datatype = "or(uinteger,portrange)" + o.default = "100-200" + o:depends("fragment", true) + + o = s_xray:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions.")) + o.default = 0 + + o = s_xray:option(Flag, "sniffing_override_dest", translate("Override the connection destination address")) + o.default = 0 + o.description = translate("Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly.") + + o = s_xray:option(Flag, "route_only", translate("Sniffing Route Only")) + o.default = 0 + o:depends("sniffing", true) + + local domains_excluded = string.format("/usr/share/%s/domains_excluded", appname) + o = s_xray:option(TextValue, "excluded_domains", translate("Excluded Domains"), translate("If the traffic sniffing result is in this list, the destination address will not be overridden.")) + o.rows = 15 + o.wrap = "off" + o.cfgvalue = function(self, section) return fs.readfile(domains_excluded) or "" end + o.write = function(self, section, value) fs.writefile(domains_excluded, value:gsub("\r\n", "\n")) end + o:depends({sniffing_override_dest = true}) + + o = s_xray:option(Value, "buffer_size", translate("Buffer Size"), translate("Buffer size for every connection (kB)")) + o.datatype = "uinteger" + + s_xray_noise = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets"),"" .. translate("To send noise packets, select \"Noise\" in Xray Settings.") .. "") + s_xray_noise.template = "cbi/tblsection" + s_xray_noise.sortable = true + s_xray_noise.anonymous = true + s_xray_noise.addremove = true + + s_xray_noise.create = function(e, t) + TypedSection.create(e, api.gen_short_uuid()) + end + + s_xray_noise.remove = function(self, section) + for k, v in pairs(self.children) do + v.rmempty = true + v.validate = nil + end + TypedSection.remove(self, section) + end + + o = s_xray_noise:option(Flag, "enabled", translate("Enable")) + o.default = 1 + o.rmempty = false + + o = s_xray_noise:option(ListValue, "type", translate("Type")) + o:value("rand", "rand") + o:value("array", "array") + o:value("str", "str") + o:value("hex", "hex") + o:value("base64", "base64") + + o = s_xray_noise:option(Value, "packet", translate("Packet | Rand Length")) + o.datatype = "minlength(1)" + o.rmempty = false + + o = s_xray_noise:option(Value, "delay", translate("Delay (ms)")) + o.datatype = "or(uinteger,portrange)" + o.rmempty = false +end + +if has_singbox then + s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings")) + s.anonymous = true + s.addremove = false + + o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"), + translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first.")) + o.default = 0 + + o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"), + translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed.")) + o.default = 0 +end + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua new file mode 100644 index 00000000..e018d45c --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua @@ -0,0 +1,107 @@ +local api = require "luci.passwall2.api" +local appname = api.appname + +m = Map(appname) +api.set_apply_on_parse(m) + +-- [[ Rule Settings ]]-- +s = m:section(TypedSection, "global_rules", translate("Rule status")) +s.anonymous = true + +o = s:option(Value, "geoip_url", translate("GeoIP Update URL")) +o:value("https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat", translate("Loyalsoldier/geoip")) +o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geoip.dat", translate("MetaCubeX/geoip")) +o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip.dat", translate("Loyalsoldier/geoip (CDN)")) +o:value("https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat", translate("MetaCubeX/geoip (CDN)")) +o:value("https://github.com/Chocolate4U/Iran-v2ray-rules/releases/latest/download/geoip.dat", translate("Chocolate4U/geoip (IR)")) +o:value("https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat", translate("runetfreedom/geoip (RU)")) +o.default = o.keylist[1] + +o = s:option(Value, "geosite_url", translate("Geosite Update URL")) +o:value("https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat", translate("Loyalsoldier/geosite")) +o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geosite.dat", translate("MetaCubeX/geosite")) +o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat", translate("Loyalsoldier/geosite (CDN)")) +o:value("https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat", translate("MetaCubeX/geosite (CDN)")) +o:value("https://github.com/Chocolate4U/Iran-v2ray-rules/releases/latest/download/geosite.dat", translate("Chocolate4U/geosite (IR)")) +o:value("https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat", translate("runetfreedom/geosite (RU)")) +o.default = o.keylist[1] + +o = s:option(Value, "v2ray_location_asset", translate("Location of Geo rule files"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are.")) +o.default = "/usr/share/v2ray/" +o.placeholder = o.default +o.rmempty = false + +---- Auto Update +o = s:option(Flag, "auto_update", translate("Enable auto update rules")) +o.default = 0 +o.rmempty = false + +---- Week Update +o = s:option(ListValue, "week_update", translate("Update Mode")) +o:value(8, translate("Loop Mode")) +o:value(7, translate("Every day")) +o:value(1, translate("Every Monday")) +o:value(2, translate("Every Tuesday")) +o:value(3, translate("Every Wednesday")) +o:value(4, translate("Every Thursday")) +o:value(5, translate("Every Friday")) +o:value(6, translate("Every Saturday")) +o:value(0, translate("Every Sunday")) +o.default = 7 +o:depends("auto_update", true) +o.rmempty = true + +---- Time Update +o = s:option(ListValue, "time_update", translate("Update Time(every day)")) +for t = 0, 23 do o:value(t, t .. ":00") end +o.default = 0 +o:depends("week_update", "0") +o:depends("week_update", "1") +o:depends("week_update", "2") +o:depends("week_update", "3") +o:depends("week_update", "4") +o:depends("week_update", "5") +o:depends("week_update", "6") +o:depends("week_update", "7") +o.rmempty = true + +---- Interval Update +o = s:option(ListValue, "interval_update", translate("Update Interval(hour)")) +for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end +o.default = 2 +o:depends("week_update", "8") +o.rmempty = true + +--- The update option is always hidden by JavaScript. +local flags = { + "geoip_update", "geosite_update" +} +for _, f in ipairs(flags) do + o = s:option(Flag, f) + o.rmempty = false +end + +s:append(Template(appname .. "/rule/rule_version")) + +s = m:section(TypedSection, "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") +s.template = "cbi/tblsection" +s.anonymous = false +s.addremove = true +s.sortable = true +s.extedit = api.url("shunt_rules", "%s") +function s.create(e, t) + TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end +function s.remove(e, t) + m.uci:foreach(appname, "nodes", function(s) + if s["protocol"] and s["protocol"] == "_shunt" then + m:del(s[".name"], t) + end + end) + TypedSection.remove(e, t) +end + +o = s:option(DummyValue, "remarks", translate("Remarks")) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/shunt_rules.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/shunt_rules.lua new file mode 100644 index 00000000..e154fa84 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/shunt_rules.lua @@ -0,0 +1,251 @@ +local api = require "luci.passwall2.api" +local appname = api.appname +local datatypes = api.datatypes + +m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule")) +m.redirect = api.url("rule") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +function m.on_before_save(self) + m:set("@global[0]", "flush_set", "1") +end + +-- Add inline CSS to map description +m.description = (m.description or "") .. [[ + +]] + +function clean_text(text) + local nbsp = string.char(0xC2, 0xA0) -- Non-breaking space (U+00A0) + local fullwidth_space = string.char(0xE3, 0x80, 0x80) -- Full-width space (U+3000) + return text + :gsub("\t", " ") + :gsub(nbsp, " ") + :gsub(fullwidth_space, " ") + :gsub("^%s+", "") + :gsub("%s+$", "\n") + :gsub("\r\n", "\n") + :gsub("[ \t]*\n[ \t]*", "\n") +end + +s = m:section(NamedSection, arg[1], "shunt_rules", "") +s.addremove = false +s.dynamic = false + +remarks = s:option(Value, "remarks", translate("Remarks")) +remarks.default = arg[1] +remarks.rmempty = false +remarks.validate = function(self, value, section) + value = api.trim(value) + if value == "" then + return nil, translate("Remark cannot be empty.") + end + return value +end + +protocol = s:option(MultiValue, "protocol", translate("Protocol")) +protocol:value("http") +protocol:value("tls") +protocol:value("quic") +protocol:value("bittorrent") +protocol.widget = "checkbox" +protocol.default = nil +protocol.optional = false + +o = s:option(MultiValue, "inbound", translate("Inbound Tag")) +o:value("tproxy", translate("Transparent proxy")) +o:value("socks", "Socks") +o.widget = "checkbox" +o.default = nil +o.optional = false + +network = s:option(ListValue, "network", translate("Network")) +network:value("tcp,udp", "TCP UDP") +network:value("tcp", "TCP") +network:value("udp", "UDP") + +source = s:option(DynamicList, "source", translate("Source")) +source.description = "
  • " .. translate("Example:") +.. "
  • " .. translate("IP") .. ": 192.168.1.100" +.. "
  • " .. translate("IP CIDR") .. ": 192.168.1.0/24" +.. "
  • " .. translate("GeoIP") .. ": geoip:private" +.. "
" +source.cast = "string" +source.cfgvalue = function(self, section) + local value + if self.tag_error[section] then + value = self:formvalue(section) + else + value = self.map:get(section, self.option) + if type(value) == "string" then + local value2 = {} + string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end) + value = value2 + end + end + return value +end +source.validate = function(self, value, t) + local err = {} + for _, v in ipairs(value) do + local flag = false + if datatypes.ip4addr(v) then + flag = true + end + + if flag == false and v:find("geoip:") and v:find("geoip:") == 1 then + flag = true + end + + if flag == false then + err[#err + 1] = v + end + end + + if #err > 0 then + self:add_error(t, "invalid", translate("Not true format, please re-enter!")) + for _, v in ipairs(err) do + self:add_error(t, "invalid", v) + end + end + + return value +end + +local dynamicList_write = function(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + t = table.concat(t, " ") + return DynamicList.write(self, section, t) +end + +source.write = dynamicList_write + +--[[ +-- Too low usage rate, hidden +sourcePort = s:option(Value, "sourcePort", translate("Source port")) +]]-- + +port = s:option(Value, "port", translate("Port")) + +domain_list = s:option(TextValue, "domain_list", translate("Domain")) +domain_list.rows = 10 +domain_list.wrap = "off" +domain_list.validate = function(self, value) + local hosts= {} + value = clean_text(value) + string.gsub(value, "[^\r\n]+", function(w) table.insert(hosts, w) end) + for index, host in ipairs(hosts) do + local flag = 1 + local tmp_host = host + if not host:find("#") and host:find("%s") then + elseif host:find("regexp:") and host:find("regexp:") == 1 then + flag = 0 + elseif host:find("domain:.") and host:find("domain:.") == 1 then + tmp_host = host:gsub("domain:", "") + elseif host:find("full:.") and host:find("full:.") == 1 then + tmp_host = host:gsub("full:", "") + elseif host:find("geosite:") and host:find("geosite:") == 1 then + flag = 0 + elseif host:find("ext:") and host:find("ext:") == 1 then + flag = 0 + elseif host:find("rule-set:", 1, true) == 1 or host:find("rs:") == 1 then + local w = host:sub(host:find(":") + 1, #host) + if w:find("local:") == 1 or w:find("remote:") == 1 then + flag = 0 + end + elseif host:find("#") and host:find("#") == 1 then + flag = 0 + end + if flag == 1 then + if not datatypes.hostname(tmp_host) then + return nil, tmp_host .. " " .. translate("Not valid domain name, please re-enter!") + end + end + end + return value +end +domain_list.description = "
    " +.. "
  • " .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.") .. "
  • " +.. "
  • " .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.") .. "
  • " +.. "
  • " .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.") .. "
  • " +.. "
  • " .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.") .. "
  • " +.. "
  • " .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.") .. "
  • " +.. "
  • " + .. translate("Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'") + .. "
      " + .. "
    • " .. translate("Such as:") .. "'rule-set:remote:https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs'" .. "
    • " + .. "
    • " .. translate("Such as:") .. "'rule-set:local:/usr/share/sing-box/geosite-cn.srs'" .. "
    • " + .. "
    " +.. "
  • " +.. "
  • " .. translate("Annotation: Begining with #") .. "
  • " +.. "
" +ip_list = s:option(TextValue, "ip_list", "IP") +ip_list.rows = 10 +ip_list.wrap = "off" +ip_list.validate = function(self, value) + local ipmasks= {} + value = clean_text(value) + string.gsub(value, "[^\r\n]+", function(w) table.insert(ipmasks, w) end) + for index, ipmask in ipairs(ipmasks) do + if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 and not ipmask:find("%s") then + elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 and not ipmask:find("%s") then + elseif ipmask:find("rule-set:", 1, true) == 1 or ipmask:find("rs:") == 1 then + local w = ipmask:sub(ipmask:find(":") + 1, #ipmask) + if w:find("local:") == 1 or w:find("remote:") == 1 then + flag = 0 + end + elseif ipmask:find("#") and ipmask:find("#") == 1 then + else + if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then + return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!") + end + end + end + return value +end +ip_list.description = "
    " +.. "
  • " .. translate("IP: such as '127.0.0.1'.") .. "
  • " +.. "
  • " .. translate("CIDR: such as '127.0.0.0/8'.") .. "
  • " +.. "
  • " .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.") .. "
  • " +.. "
  • " + .. translate("Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'") + .. "
      " + .. "
    • " .. translate("Such as:") .. "'rule-set:remote:https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs'" .. "
    • " + .. "
    • " .. translate("Such as:") .. "'rule-set:local:/usr/share/sing-box/geoip-cn.srs'" .. "
    • " + .. "
    " +.. "
  • " +.. "
  • " .. translate("Annotation: Begining with #") .. "
  • " +.. "
" + +o = s:option(Flag, "invert", "invert", translate("Invert match result.") .. " " .. translate("Only support Sing-Box.")) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua new file mode 100644 index 00000000..f3930ed4 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua @@ -0,0 +1,138 @@ +local api = require "luci.passwall2.api" +local appname = api.appname + +m = Map(appname) +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(api.url()) +end + +m:append(Template(appname .. "/cbi/nodes_dynamiclist_com")) +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + nodes_table[#nodes_table + 1] = e +end + +s = m:section(NamedSection, arg[1], translate("Socks Config"), translate("Socks Config")) +s.addremove = false +s.dynamic = false + +---- Enable +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 1 +o.rmempty = false + +local auto_switch_tip +local current_node = api.get_cache_var("socks_" .. arg[1]) +if current_node then + local n = m:get(current_node) + if n then + if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then + if n then + local remarks = api.get_node_remarks(n) + local url = api.url("node_config", n[".name"]) + auto_switch_tip = translatef("Current node: %s", string.format('%s', url, remarks)) .. "
" + end + end + end +end + +socks_node = s:option(ListValue, "node", translate("Node")) +if auto_switch_tip then + socks_node.description = auto_switch_tip +end +socks_node.template = appname .. "/cbi/nodes_listvalue" +socks_node.group = {} + +o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" + +local n = 1 +m.uci:foreach(appname, "socks", function(s) + if s[".name"] == section then + return false + end + n = n + 1 +end) + +o = s:option(Value, "port", "Socks " .. translate("Listen Port")) +o.default = n + 1080 +o.datatype = "port" +o.rmempty = false + +if has_singbox or has_xray then + o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) + o.default = 0 + o.datatype = "port" +end + +o = s:option(Flag, "log", translate("Enable") .. " " .. translate("Log")) +o.default = 1 +o.rmempty = false + +o = s:option(Flag, "enable_autoswitch", translate("Auto Switch")) +o.default = 0 +o.rmempty = false + +o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds")) +o.datatype = "min(10)" +o.default = 30 +o:depends("enable_autoswitch", true) + +o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds")) +o.datatype = "min(1)" +o.default = 3 +o:depends("enable_autoswitch", true) + +o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num")) +o.datatype = "min(1)" +o.default = 1 +o:depends("enable_autoswitch", true) + +o = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes")) +o:depends("enable_autoswitch", true) +o.template = appname .. "/cbi/nodes_dynamiclist" +o.group = {} +o.write = function(self, section, value) + local n = s.fields["node"]:formvalue(section) + local v = type(value) == "table" and value or { value } + local t = {} + for _, x in ipairs(v) do + if x and x ~= n then t[#t+1] = x end + end + return DynamicList.write(self, section, t) +end +for i, v in pairs(nodes_table) do + if v.protocol ~= "_shunt" then + o:value(v.id, v.remark) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + s.fields["enable_autoswitch"]:depends({ node = v.id }) + end + socks_node:value(v.id, v["remark"]) + socks_node.group[#socks_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end + +o = s:option(Flag, "autoswitch_restore_switch", translate("Restore Switch"), translate("When detects main node is available, switch back to the main node.")) +o:depends("enable_autoswitch", true) + +o = s:option(Value, "autoswitch_probe_url", translate("Probe URL"), translate("The URL used to detect the connection status.")) +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.default = o.keylist[3] +o:depends("enable_autoswitch", true) + +o = s:option(DummyValue, "btn") +o.template = appname .. "/socks_auto_switch/btn" +o:depends("enable_autoswitch", true) + +return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua new file mode 100644 index 00000000..f5c66225 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua @@ -0,0 +1,104 @@ +local m, s = ... + +if not api.finded_com("hysteria") then + return +end + +type_name = "Hysteria2" + +-- [[ Hysteria2 ]] + +s.fields["type"]:value(type_name, "Hysteria2") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "hysteria2_" + +local function _n(name) + return option_prefix .. name +end + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) +o:depends({ [_n("realms")] = false }) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" +o:depends({ [_n("realms")] = false }) + +o = s:option(Value, _n("hop"), translate("Port hopping range")) +o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") +o.rewrite_option = o.option +o:depends({ [_n("realms")] = false }) + +o = s:option(Value, _n("hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) +o.datatype = "or(uinteger,portrange)" +o.placeholder = "30" +o.default = "30" +o.rewrite_option = o.option +o:depends({ [_n("realms")] = false }) + +o = s:option(Flag, _n("realms"), translate("Realms")) +o.default = "0" +o.rewrite_option = o.option + +o = s:option(Value, _n("realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(DynamicList, _n("realm_stun"), translate("Realm STUN")) +o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(Value, _n("auth_password"), translate("Auth Password")) +o.password = true +o.rewrite_option = o.option + +o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o.rewrite_option = o.option + +o = s:option(Value, _n("obfs_password"), translate("Obfs Password")) +o.rewrite_option = o.option +o:depends({ [_n("obfs_type")] = "salamander" }) + +o = s:option(Flag, _n("fast_open"), translate("Fast Open")) +o.default = "0" + +o = s:option(Value, _n("tls_serverName"), translate("Domain")) + +o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) +o.default = "0" + +o = s:option(Value, _n("tls_pinSHA256"), translate("PinSHA256"),translate("Certificate fingerprint")) + +o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps")) +o.rewrite_option = o.option + +o = s:option(Value, _n("down_mbps"), translate("Max download Mbps")) +o.rewrite_option = o.option + +o = s:option(Value, _n("recv_window"), translate("QUIC stream receive window")) +o.rewrite_option = o.option + +o = s:option(Value, _n("recv_window_conn"), translate("QUIC connection receive window")) +o.rewrite_option = o.option + +o = s:option(Value, _n("idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)") +o.rewrite_option = o.option + +o = s:option(Value, _n("keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)") +o.rewrite_option = o.option + +o = s:option(Flag, _n("disable_mtu_discovery"), translate("Disable MTU detection")) +o.default = "0" +o.rewrite_option = o.option + +o = s:option(Flag, _n("lazy_start"), translate("Lazy Start")) +o.default = "0" +o.rewrite_option = o.option + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua new file mode 100644 index 00000000..621596fd --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua @@ -0,0 +1,37 @@ +local m, s = ... + +if not api.is_finded("naive") then + return +end + +type_name = "Naiveproxy" + +-- [[ Naive ]] + +s.fields["type"]:value(type_name, "NaiveProxy") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "naive_" + +local function _n(name) + return option_prefix .. name +end + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("https", translate("HTTPS")) +o:value("quic", translate("QUIC")) + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("username"), translate("Username")) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua new file mode 100644 index 00000000..f1264f1f --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua @@ -0,0 +1,847 @@ +local m, s = ... + +if not api.finded_com("xray") then + return +end + +local jsonc = api.jsonc + +type_name = "Xray" + +-- [[ Xray ]] + +s.fields["type"]:value(type_name, "Xray") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "xray_" + +local function _n(name) + return option_prefix .. name +end + +local formvalue_proto = luci.http.formvalue(formvalue_key .. _n("protocol")) + +if formvalue_proto then s.val["protocol"] = formvalue_proto end + +local arg_select_proto = luci.http.formvalue("select_proto") or "" + +local ss_method_list = { + "none", "plain", "aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero" } + +local header_type_list = { + "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns" +} + +local xray_version = api.get_app_version("xray") + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("vmess", translate("Vmess")) +o:value("vless", translate("VLESS")) +o:value("http", translate("HTTP")) +o:value("socks", translate("Socks")) +o:value("shadowsocks", translate("Shadowsocks")) +o:value("trojan", translate("Trojan")) +o:value("wireguard", translate("WireGuard")) +if api.compare_versions(xray_version, ">=", "26.1.13") then + o:value("hysteria2", translate("Hysteria2")) +end +if api.compare_versions(xray_version, ">=", "1.8.12") then + o:value("_balancing", translate("Balancing")) +end +o:value("_shunt", translate("Shunt")) +o:value("_iface", translate("Custom Interface")) +function o.custom_cfgvalue(self, section) + if arg_select_proto ~= "" then + return arg_select_proto + else + return m:get(section, self.option:sub(1 + #option_prefix)) + end +end + +local load_balancing_options = s.val["protocol"] == "_balancing" or arg_select_proto == "_balancing" +local load_shunt_options = s.val["protocol"] == "_shunt" or arg_select_proto == "_shunt" +local load_iface_options = s.val["protocol"] == "_iface" or arg_select_proto == "_iface" +local load_normal_options = true +if load_balancing_options or load_shunt_options or load_iface_options then + load_normal_options = nil +end +if not arg_select_proto:find("_") then + load_normal_options = true +end + +local netdev_list = api.get_network_devices() +local node_list = api.get_node_list() +local fallback_list = {} +local is_balancer = nil +for k, e in ipairs(node_list.balancing_list or {}) do + if e.id ~= arg[1] then + fallback_list[#fallback_list + 1] = { + id = e["id"], + remark = e["remark"], + group = e["group"], + fallback = e.o["fallback_node"], + } + else + is_balancer = true + end +end + +if load_balancing_options then -- [[ Load balancing Start ]] + o = s:option(ListValue, _n("node_add_mode"), translate("Node Addition Method")) + o:depends({ [_n("protocol")] = "_balancing" }) + o.default = "manual" + o:value("manual", translate("Manual")) + o:value("batch", translate("Batch")) + + o = s:option(MultiValue, _n("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, document")) + o:depends({ [_n("node_add_mode")] = "manual" }) + o.widget = "checkbox" + o.template = appname .. "/cbi/nodes_multivalue" + o.group = {} + for k1, v1 in pairs(node_list) do + if k1 == "socks_list" or k1 == "normal_list" then + for i, v in ipairs(v1) do + o:value(v.id, v.remark) + o.group[#o.group+1] = v.group or "" + end + end + end + -- Reading the old DynamicList + function o.cfgvalue(self, section) + return m.uci:get_list(appname, section, "balancing_node") or {} + end + -- Write-and-hold DynamicList + function o.custom_write(self, section, value) + local old = m.uci:get_list(appname, section, "balancing_node") or {} + local new, set = {}, {} + for v in value:gmatch("%S+") do + new[#new + 1] = v + set[v] = 1 + end + for _, v in ipairs(old) do + if not set[v] then + m.uci:set_list(appname, section, "balancing_node", new) + return + end + set[v] = nil + end + for _ in pairs(set) do + m.uci:set_list(appname, section, "balancing_node", new) + return + end + end + + o = s:option(MultiValue, _n("node_group"), translate("Select Group")) + o:depends({ [_n("node_add_mode")] = "batch" }) + o.widget = "checkbox" + o:value("default", translate("default")) + for k, v in pairs(groups) do + o:value(api.UrlEncode(k), k) + end + + o = s:option(Value, _n("node_match_rule"), translate("Node Matching Rules")) + o:depends({ [_n("node_add_mode")] = "batch" }) + local descrStr = "Example: ^A && B && !C && D$
" + descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" + descrStr = descrStr .. "Conditions are joined by &&, and their order does not affect the result." + o.description = translate(descrStr) + + o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy")) + o:depends({ [_n("protocol")] = "_balancing" }) + o:value("random") + o:value("roundRobin") + o:value("leastPing") + o:value("leastLoad") + o.default = "random" + + -- Fallback Node + o = s:option(ListValue, _n("fallback_node"), translate("Fallback Node")) + o.group = {"",""} + o:value("", translate("Close(Not use)")) + o:value("_direct", translate("Direct Connection")) + o:depends({ [_n("protocol")] = "_balancing" }) + o.template = appname .. "/cbi/nodes_listvalue" + -- Maximum number of fallback nesting layers + local MAX_FALLBACK_DEPTH = 3 + -- Check if a loop will form. + local function will_loop(start_id, target_id, depth) + depth = depth or 0 + -- Recursion stops after the maximum depth is exceeded. + if depth >= MAX_FALLBACK_DEPTH then + return false + end + for _, v in ipairs(fallback_list) do + if v.id == target_id then + local fb = v.fallback + -- No fallback + if not fb or fb == "" or fb == "_direct" then + return false + end + -- Loopback detected + if fb == start_id then + return true + end + -- Continue recursive checking + return will_loop(start_id, fb, depth + 1) + end + end + return false + end + -- Get fallback chain depth + local function get_fallback_depth(id, depth) + depth = depth or 0 + if depth >= MAX_FALLBACK_DEPTH then + return depth + end + for _, v in ipairs(fallback_list) do + if v.id == id then + local fb = v.fallback + if not fb or fb == "" or fb == "_direct" then + return depth + end + return get_fallback_depth(fb, depth + 1) + end + end + return depth + end + for _, v in ipairs(fallback_list) do + local depth = get_fallback_depth(v.id) + -- Once the maximum number of nested doll layers is exceeded, further selection of the balancer is not allowed. + if depth < MAX_FALLBACK_DEPTH + and not will_loop(arg[1], v.id) + then + o:value(v.id, v.remark) + o.group[#o.group + 1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + for k1, v1 in pairs(node_list) do + if k1 == "socks_list" or k1 == "normal_list" or k1 == "urltest_list" then + for i, v in ipairs(v1) do + o:value(v.id, v.remark) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + end + + o = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custom Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL.")) + o:depends({ [_n("protocol")] = "_balancing" }) + + o = s:option(Value, _n("probeUrl"), translate("Probe URL")) + o:depends({ [_n("useCustomProbeUrl")] = true }) + o:value("https://cp.cloudflare.com/", "Cloudflare") + o:value("https://www.gstatic.com/generate_204", "Gstatic") + o:value("https://www.google.com/generate_204", "Google") + o:value("https://www.youtube.com/generate_204", "YouTube") + o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") + o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") + o.default = "https://www.google.com/generate_204" + o.description = translate("The URL used to detect the connection status.") + + o = s:option(Value, _n("probeInterval"), translate("Probe Interval")) + o:depends({ [_n("protocol")] = "_balancing" }) + o.default = "1m" + o.placeholder = "1m" + o.description = translate("The interval between initiating probes.") .. "
" .. + translate("The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively.") .. "
" .. + translate("When the unit is not filled in, it defaults to seconds.") + + o = s:option(Value, _n("expected"), translate("Preferred Node Count")) + o:depends({ [_n("balancingStrategy")] = "leastLoad" }) + o.datatype = "uinteger" + o.default = "2" + o.placeholder = "2" + o.description = translate("The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them.") + + o = s:option(Value, _n("tolerance"), translate("Failure Tolerance (%)")) + o:depends({ [_n("balancingStrategy")] = "leastLoad" }) + o.datatype = "uinteger" + o.default = "10" + o.placeholder = "10" + o.description = translate("The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate.") +end -- [[ Load balancing End ]] + +if load_iface_options then -- [[ Custom Interface Start ]] + o = s:option(Value, _n("iface"), translate("Interface")) + o:depends({ [_n("protocol")] = "_iface" }) + for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) + end +end -- [[ Custom Interface End ]] + + +-- [[ Normal single node Start ]] +if load_normal_options then + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("uuid"), translate("ID")) +o.password = true +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(ListValue, _n("security"), translate("Encrypt Method")) +for a, t in ipairs(security_list) do o:value(t) end +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(Value, _n("encryption"), translate("Encrypt Method") .. " (encryption)") +o.default = "none" +o.placeholder = "none" +o:depends({ [_n("protocol")] = "vless" }) +o.validate = function(self, value) + value = api.trim(value) + return (value == "" and "none" or value) +end + +o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(ss_method_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("iv_check"), translate("IV Check")) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-128-gcm" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-256-gcm" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "chacha20-poly1305" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "xchacha20-poly1305" }) + +o = s:option(Flag, _n("uot"), translate("UDP over TCP")) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:value("xtls-rprx-vision-udp443") +o:depends({ [_n("protocol")] = "vless" }) + +---- [[hysteria2]] +o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range")) +o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) +o.datatype = "or(uinteger,portrange)" +o.placeholder = "30" +o.default = "30" +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) +o.password = true +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) +o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + +o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)") +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Value, _n("hysteria2_keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)") +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Flag, _n("hysteria2_disable_mtu_discovery"), translate("Disable MTU detection")) +o.default = "0" +o:depends({ [_n("protocol")] = "hysteria2"}) +---- [[hysteria2 end]] + +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("reality"), translate("REALITY")) +o.default = 0 +o:depends({ [_n("tls")] = true, [_n("transport")] = "raw" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "ws" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "grpc" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("tls")] = true, [_n("transport")] = "xhttp" }) + +o = s:option(ListValue, _n("alpn"), translate("alpn")) +o.default = "default" +o:value("default", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +-- o = s:option(Value, _n("minversion"), translate("minversion")) +-- o.default = "1.3" +-- o:value("1.3") +-- o:depends({ [_n("tls")] = true }) + +o = s:option(Value, _n("tls_serverName"), "SNI " .. translate("Domain")) +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +if api.compare_versions(os.date("%Y.%m.%d"), "<", "2026.6.1") then + o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) + o.default = "0" + o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + o:depends({ [_n("protocol")] = "hysteria2" }) +end + +if api.compare_versions(xray_version, ">=", "26.1.31") then + o = s:option(Value, _n("tls_pinSHA256"), translate("TLS Chain Fingerprint (SHA256)")) + o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("tls_CertByName"), translate("TLS Certificate Name (CertName)"), translate("TLS is used to verify the leaf certificate name.")) + o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + o:depends({ [_n("protocol")] = "hysteria2" }) +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(TextValue, _n("ech_config"), translate("ECH Config")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +-- [[ REALITY ]] -- +o = s:option(Value, _n("reality_publicKey"), translate("Public Key")) +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Value, _n("reality_shortId"), translate("Short Id")) +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Value, _n("reality_spiderX"), translate("Spider X")) +o.placeholder = "/" +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Flag, _n("utls"), translate("uTLS")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + +o = s:option(ListValue, _n("fingerprint"), translate("Finger Print")) +o:value("chrome") +o:value("firefox") +o:value("edge") +o:value("safari") +o:value("360") +o:value("qq") +o:value("ios") +o:value("android") +o:value("random") +o:value("randomized") +o.default = "chrome" +o:depends({ [_n("tls")] = true, [_n("utls")] = true }) +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(Flag, _n("use_mldsa65Verify"), translate("ML-DSA-65")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = true }) + +o = s:option(TextValue, _n("reality_mldsa65Verify"), "ML-DSA-65 " .. translate("Public key")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("use_mldsa65Verify")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("raw", "RAW (TCP)") +o:value("mkcp", "mKCP") +o:value("ws", "WebSocket") +o:value("grpc", "gRPC") +o:value("httpupgrade", "HttpUpgrade") +o:value("xhttp", "XHTTP") +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(Value, _n("wireguard_public_key"), translate("Public Key")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address")) +o:depends({ [_n("protocol")] = "wireguard" }) + +o = s:option(Value, _n("wireguard_mtu"), translate("MTU")) +o.default = "1420" +o:depends({ [_n("protocol")] = "wireguard" }) + +if api.compare_versions(xray_version, ">=", "1.8.0") then + o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) + o:depends({ [_n("protocol")] = "wireguard" }) +end + +o = s:option(Value, _n("wireguard_keepAlive"), translate("Keep Alive")) +o.default = "0" +o:depends({ [_n("protocol")] = "wireguard" }) + +-- [[ RAW ]]-- +o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o:depends({ [_n("transport")] = "raw" }) + +o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host")) +o:depends({ [_n("tcp_guise")] = "http" }) + +o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path")) +o.placeholder = "/" +o:depends({ [_n("tcp_guise")] = "http" }) + +-- [[ mKCP ]]-- +o = s:option(ListValue, _n("mkcp_guise"), translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests.')) +for a, t in ipairs(header_type_list) do o:value(t) end +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_domain"), translate("Camouflage Domain"), translate("Use it together with the DNS disguised type. You can fill in any domain.")) +o:depends({ [_n("mkcp_guise")] = "dns" }) + +o = s:option(Value, _n("mkcp_mtu"), translate("KCP MTU")) +o.datatype = "uinteger" +o.default = 1350 +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed")) +o:depends({ [_n("transport")] = "mkcp" }) + +-- [[ WebSocket ]]-- +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_heartbeatPeriod"), translate("HeartbeatPeriod(second)")) +o.datatype = "integer" +o:depends({ [_n("transport")] = "ws" }) + +-- [[ gRPC ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(ListValue, _n("grpc_mode"), "gRPC " .. translate("Transfer mode")) +o:value("gun") +o:value("multi") +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Flag, _n("grpc_health_check"), translate("Health check")) +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Value, _n("grpc_idle_timeout"), translate("Idle timeout")) +o.default = "10" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Value, _n("grpc_health_check_timeout"), translate("Health check timeout")) +o.default = "20" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Flag, _n("grpc_permit_without_stream"), translate("Permit without stream")) +o.default = "0" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Value, _n("grpc_initial_windows_size"), translate("Initial Windows Size")) +o.default = "0" +o:depends({ [_n("transport")] = "grpc" }) + +-- [[ HttpUpgrade ]]-- +o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HttpUpgrade Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ XHTTP ]]-- +o = s:option(ListValue, _n("xhttp_mode"), "XHTTP " .. translate("Mode")) +o:depends({ [_n("transport")] = "xhttp" }) +o.default = "auto" +o:value("auto") +o:value("packet-up") +o:value("stream-up") +o:value("stream-one") + +o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host")) +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_path"), translate("XHTTP Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Flag, _n("use_xhttp_extra"), translate("XHTTP Extra")) +o.default = "0" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(TextValue, _n("xhttp_extra"), " ", translate("An XHttpObject in JSON format, used for sharing.")) +o:depends({ [_n("use_xhttp_extra")] = true }) +o.rows = 10 +o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "xhttp_extra") + if raw then + return api.base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "xhttp_extra", api.base64Encode(value) or "") + local success, data = pcall(jsonc.parse, value) + if success and data then + local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address) + or (data.downloadSettings and data.downloadSettings.address) + if address and address ~= "" then + address = address:gsub("^%[", ""):gsub("%]$", "") + m:set(section, "download_address", address) + else + m:del(section, "download_address") + end + else + m:del(section, "download_address") + end +end +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if api.jsonc.parse(value) then + return value + else + return nil, "XHTTP Extra " .. translate("Must be JSON text!") + end +end +o.custom_remove = function(self, section, value) + m:del(section, "xhttp_extra") + m:del(section, "download_address") +end + +-- [[ User-Agent ]]-- +o = s:option(Value, _n("user_agent"), translate("User-Agent")) +o.default = "" +o:value("", translate("default")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", "chrome") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0", "firefox") +o:value("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15", "safari") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70", "edge") +o:value("Go-http-client/1.1", "golang") +o:value("curl/7.68.0", "curl") +o:depends({ [_n("tcp_guise")] = "http" }) +o:depends({ [_n("transport")] = "ws" }) +o:depends({ [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("transport")] = "xhttp" }) +o:depends({ [_n("transport")] = "grpc" }) + +-- [[ Mux.Cool ]]-- +o = s:option(Flag, _n("mux"), "Mux", translate("Enable Mux.Cool")) +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "raw" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "ws" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "grpc" }) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(Value, _n("mux_concurrency"), translate("Mux concurrency")) +o.default = -1 +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("xudp_concurrency"), translate("XUDP Mux concurrency")) +o.default = 8 +o:depends({ [_n("mux")] = true }) + +--[[FinalMask]] +o = s:option(Flag, _n("use_finalmask"), "FinalMask") +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "wireguard" }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(TextValue, _n("finalmask"), " ") +o:depends({ [_n("use_finalmask")] = true }) +o.rows = 10 +o.wrap = "off" +o.description = translate("An FinalMaskObject in JSON format, used for sharing.") .. "
" .. + translate("Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings.") +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "finalmask") + if raw then + return api.base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "finalmask", api.base64Encode(value) or "") +end +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if api.jsonc.parse(value) then + return value + else + return nil, "FinalMask " .. translate("Must be JSON text!") + end +end + +--[[Fast Open]] +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) +o.default = 0 + +--[[tcpMptcp]] +o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) +o.default = 0 + +o = s:option(Value, _n("preconns"), translate("Pre-connections"), translate("Number of early established connections to reduce latency.")) +o.datatype = "uinteger" +o.placeholder = 0 +o:depends({ [_n("protocol")] = "vless" }) + +o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve"), translate("If the node address is a domain name, this DNS will be used for resolution.")) +o:value("", translate("Auto")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("https", "HTTPS") + +o = s:option(Value, _n("domain_resolver_dns"), "DNS") +o.datatype = "or(ipaddr,ipaddrport)" +o:value("114.114.114.114") +o:value("223.5.5.5:53") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "tcp" }) +o:depends({ [_n("domain_resolver")] = "udp" }) + +o = s:option(Value, _n("domain_resolver_dns_https"), "DNS") +o:value("https://120.53.53.53/dns-query", "DNSPod") +o:value("https://223.5.5.5/dns-query", "AliDNS") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "https" }) + +o = s:option(ListValue, _n("domain_strategy"), translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) +o.default = "" +o:value("", translate("Auto")) +o:value("UseIPv4", translate("IPv4 Only")) +o:value("UseIPv6", translate("IPv6 Only")) + +local protocols = s.fields[_n("protocol")].keylist +if #protocols > 0 then + for i, v in ipairs(protocols) do + if not v:find("^_") then + s.fields[_n("address")]:depends({ [_n("protocol")] = v }) + s.fields[_n("port")]:depends({ [_n("protocol")] = v }) + s.fields[_n("domain_resolver")]:depends({ [_n("protocol")] = v }) + s.fields[_n("domain_strategy")]:depends({ [_n("protocol")] = v }) + + if v ~= "hysteria2" then + s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v }) + s.fields[_n("tcpMptcp")]:depends({ [_n("protocol")] = v }) + end + end + end +end +end +-- [[ Normal single node End ]] + +if not load_shunt_options then + o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy")) + o:value("", translate("Close(Not use)")) + if not (load_iface_options or load_balancing_options) then + -- Special node cannot be use pre-proxy. + o:value("1", translate("Preproxy Node")) + o:value("3", translate("Outbound Interface")) + end + o:value("2", translate("Landing Node")) + + o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) + o1:depends({ [_n("chain_proxy")] = "1" }) + o1.template = appname .. "/cbi/nodes_listvalue" + o1.group = {} + + o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface")) + o3:depends({ [_n("chain_proxy")] = "3" }) + o3:value("", translate("All")) + for _, d in ipairs(netdev_list) do + o3:value(d.name, d.label) + end + + o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) + o2:depends({ [_n("chain_proxy")] = "2" }) + o2.template = appname .. "/cbi/nodes_listvalue" + o2.group = {} + + for k1, v1 in pairs(node_list) do + if k1 ~= "shunt_list" and k1 ~= "iface_list" then + for i, v in ipairs(v1) do + if v.id ~= arg[1] then + o1:value(v.id, v.remark) + o1.group[#o1.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + if k1 == "normal_list" then + -- Landing Node not support use special node. + o2:value(v.id, v.remark) + o2.group[#o2.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + end + end + end +end + +api.luci_types(arg[1], m, s, type_name, option_prefix) + +if load_shunt_options then + local current_node = m.uci:get_all(appname, arg[1]) or {} + local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua") + setfenv(shunt_lua, getfenv(1))(m, s, { + node_id = arg[1], + node = current_node, + node_list = node_list, + }) +end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua new file mode 100644 index 00000000..a3c591ca --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua @@ -0,0 +1,919 @@ +local m, s = ... + +local singbox_bin = api.finded_com("sing-box") + +if not singbox_bin then + return +end + +type_name = "sing-box" + +-- [[ sing-box ]] + +s.fields["type"]:value(type_name, "Sing-Box") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "singbox_" + +local function _n(name) + return option_prefix .. name +end + +local formvalue_proto = luci.http.formvalue(formvalue_key .. _n("protocol")) + +if formvalue_proto then s.val["protocol"] = formvalue_proto end + +local arg_select_proto = luci.http.formvalue("select_proto") or "" + +local ss_method_new_list = { + "none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +local ss_method_old_list = { + "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20", +} + +local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero" } + +local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'") + +local singbox_version = api.get_app_version("sing-box"):match("[^v]+") + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("socks", "Socks") +o:value("http", "HTTP") +o:value("shadowsocks", "Shadowsocks") +if singbox_tags:find("with_shadowsocksr") then + o:value("shadowsocksr", "ShadowsocksR") +end +o:value("vmess", "Vmess") +o:value("trojan", "Trojan") +if singbox_tags:find("with_wireguard") then + o:value("wireguard", "WireGuard") +end +if singbox_tags:find("with_quic") then + o:value("hysteria", "Hysteria") +end +o:value("vless", "VLESS") +if singbox_tags:find("with_quic") then + o:value("tuic", "TUIC") +end +if singbox_tags:find("with_quic") then + o:value("hysteria2", "Hysteria2") +end +o:value("anytls", "AnyTLS") +o:value("ssh", "SSH") +if singbox_tags:find("with_naive_outbound") then + o:value("naive", "NaïveProxy") +end +o:value("_urltest", translate("URLTest")) +o:value("_shunt", translate("Shunt")) +o:value("_iface", translate("Custom Interface")) +function o.custom_cfgvalue(self, section) + if arg_select_proto ~= "" then + return arg_select_proto + else + return m:get(section, self.option:sub(1 + #option_prefix)) + end +end + +local load_urltest_options = s.val["protocol"] == "_urltest" or arg_select_proto == "_urltest" +local load_shunt_options = s.val["protocol"] == "_shunt" or arg_select_proto == "_shunt" +local load_iface_options = s.val["protocol"] == "_iface" or arg_select_proto == "_iface" +local load_normal_options = true +if load_urltest_options or load_shunt_options or load_iface_options then + load_normal_options = nil +end +if not arg_select_proto:find("_") then + load_normal_options = true +end + +local netdev_list = api.get_network_devices() +local node_list = api.get_node_list() + +if load_urltest_options then -- [[ URLTest Start ]] + o = s:option(ListValue, _n("node_add_mode"), translate("Node Addition Method")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.default = "manual" + o:value("manual", translate("Manual")) + o:value("batch", translate("Batch")) + + o = s:option(MultiValue, _n("urltest_node"), translate("URLTest node list"), translate("List of nodes to test, document")) + o:depends({ [_n("node_add_mode")] = "manual" }) + o.widget = "checkbox" + o.template = appname .. "/cbi/nodes_multivalue" + o.group = {} + for k1, v1 in pairs(node_list) do + if k1 == "socks_list" or k1 == "normal_list" then + for i, v in ipairs(v1) do + o:value(v.id, v.remark) + o.group[#o.group+1] = v.group or "" + end + end + end + -- Reading the old DynamicList + function o.cfgvalue(self, section) + return m.uci:get_list(appname, section, "urltest_node") or {} + end + -- Write-and-hold DynamicList + function o.custom_write(self, section, value) + local old = m.uci:get_list(appname, section, "urltest_node") or {} + local new, set = {}, {} + for v in value:gmatch("%S+") do + new[#new + 1] = v + set[v] = 1 + end + for _, v in ipairs(old) do + if not set[v] then + m.uci:set_list(appname, section, "urltest_node", new) + return + end + set[v] = nil + end + for _ in pairs(set) do + m.uci:set_list(appname, section, "urltest_node", new) + return + end + end + + o = s:option(MultiValue, _n("node_group"), translate("Select Group")) + o:depends({ [_n("node_add_mode")] = "batch" }) + o.widget = "checkbox" + o:value("default", translate("default")) + for k, v in pairs(groups) do + o:value(api.UrlEncode(k), k) + end + + o = s:option(Value, _n("node_match_rule"), translate("Node Matching Rules")) + o:depends({ [_n("node_add_mode")] = "batch" }) + local descrStr = "Example: ^A && B && !C && D$
" + descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" + descrStr = descrStr .. "Conditions are joined by &&, and their order does not affect the result." + o.description = translate(descrStr) + + o = s:option(Value, _n("urltest_url"), translate("Probe URL")) + o:depends({ [_n("protocol")] = "_urltest" }) + o:value("https://cp.cloudflare.com/", "Cloudflare") + o:value("https://www.gstatic.com/generate_204", "Gstatic") + o:value("https://www.google.com/generate_204", "Google") + o:value("https://www.youtube.com/generate_204", "YouTube") + o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") + o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") + o.default = "https://www.gstatic.com/generate_204" + o.description = translate("The URL used to detect the connection status.") + + o = s:option(Value, _n("urltest_interval"), translate("Test interval")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.default = "3m" + o.placeholder = "3m" + o.description = translate("The interval between initiating probes.") .. "
" .. + translate("The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively.") .. "
" .. + translate("When the unit is not filled in, it defaults to seconds.") .. "
" .. + translate("Test interval must be less or equal than idle timeout.") + + o = s:option(Value, _n("urltest_tolerance"), translate("Test tolerance"), translate("The test tolerance in milliseconds.")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.datatype = "uinteger" + o.placeholder = "50" + o.default = "50" + + o = s:option(Value, _n("urltest_idle_timeout"), translate("Idle timeout")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.placeholder = "30m" + o.default = "30m" + o.description = translate("The idle timeout.") .. "
" .. + translate("The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively.") .. "
" .. + translate("When the unit is not filled in, it defaults to seconds.") + + o = s:option(Flag, _n("urltest_interrupt_exist_connections"), translate("Interrupt existing connections")) + o:depends({ [_n("protocol")] = "_urltest" }) + o.default = "0" + o.description = translate("Interrupt existing connections when the selected outbound has changed.") +end -- [[ URLTest End ]] + +if load_iface_options then -- [[ Custom Interface Start ]] + o = s:option(Value, _n("iface"), translate("Interface")) + o:depends({ [_n("protocol")] = "_iface" }) + for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) + end +end -- [[ Custom Interface End ]] + + +-- [[ Normal single node Start ]] +if load_normal_options then + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("uuid"), translate("ID")) +o.password = true +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "tuic" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "ssh" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "shadowsocksr" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "anytls" }) +o:depends({ [_n("protocol")] = "ssh" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(ListValue, _n("security"), translate("Encrypt Method")) +for a, t in ipairs(security_list) do o:value(t) end +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(ss_method_new_list) do o:value(t) end +for a, t in ipairs(ss_method_old_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +if singbox_tags:find("with_shadowsocksr") then + o = s:option(ListValue, _n("ssr_method"), translate("Encrypt Method")) + o.rewrite_option = "method" + for a, t in ipairs(ss_method_old_list) do o:value(t) end + o:depends({ [_n("protocol")] = "shadowsocksr" }) + + local ssr_protocol_list = { + "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple", + "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5", + "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c", + "auth_chain_d", "auth_chain_e", "auth_chain_f" + } + + o = s:option(ListValue, _n("ssr_protocol"), translate("Protocol")) + for a, t in ipairs(ssr_protocol_list) do o:value(t) end + o:depends({ [_n("protocol")] = "shadowsocksr" }) + + o = s:option(Value, _n("ssr_protocol_param"), translate("Protocol_param")) + o:depends({ [_n("protocol")] = "shadowsocksr" }) + + local ssr_obfs_list = { + "plain", "http_simple", "http_post", "random_head", "tls_simple", + "tls1.0_session_auth", "tls1.2_ticket_auth" + } + + o = s:option(ListValue, _n("ssr_obfs"), translate("Obfs")) + for a, t in ipairs(ssr_obfs_list) do o:value(t) end + o:depends({ [_n("protocol")] = "shadowsocksr" }) + + o = s:option(Value, _n("ssr_obfs_param"), translate("Obfs_param")) + o:depends({ [_n("protocol")] = "shadowsocksr" }) +end + +o = s:option(Flag, _n("uot"), translate("UDP over TCP")) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Value, _n("alter_id"), "Alter ID") +o.datatype = "uinteger" +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(Flag, _n("global_padding"), "global_padding", translate("Protocol parameter. Will waste traffic randomly if enabled.")) +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(Flag, _n("authenticated_length"), "authenticated_length", translate("Protocol parameter. Enable length block encryption.")) +o.default = "0" +o:depends({ [_n("protocol")] = "vmess" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) + +if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria_hop"), translate("Port hopping range")) + o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval(second)"), translate("Example:") .. "30 (≥5)") + o.datatype = "uinteger" + o.placeholder = "30" + o.default = "30" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(ListValue, _n("hysteria_auth_type"), translate("Auth Type")) + o:value("disable", translate("Disable")) + o:value("string", translate("STRING")) + o:value("base64", translate("BASE64")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "string"}) + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "base64"}) + + o = s:option(Value, _n("hysteria_up_mbps"), translate("Max upload Mbps")) + o.default = "10" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_down_mbps"), translate("Max download Mbps")) + o.default = "50" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_recv_window"), translate("QUIC connection receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection")) + o:depends({ [_n("protocol")] = "hysteria" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(ListValue, _n("tuic_congestion_control"), translate("Congestion control algorithm")) + o.default = "cubic" + o:value("bbr", translate("BBR")) + o:value("cubic", translate("CUBIC")) + o:value("new_reno", translate("New Reno")) + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(ListValue, _n("tuic_udp_relay_mode"), translate("UDP relay mode")) + o.default = "native" + o:value("native", translate("native")) + o:value("quic", translate("QUIC")) + o:depends({ [_n("protocol")] = "tuic" }) + + --[[ + o = s:option(Flag, _n("tuic_udp_over_stream"), translate("UDP over stream")) + o:depends({ [_n("protocol")] = "tuic" }) + ]]-- + + o = s:option(Flag, _n("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) + o.default = 0 + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(Value, _n("tuic_heartbeat"), translate("Heartbeat interval(second)")) + o.datatype = "uinteger" + o.default = "3" + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(ListValue, _n("tuic_alpn"), translate("QUIC TLS ALPN")) + o.default = "default" + o:value("default", translate("Default")) + o:value("h3") + o:value("h2") + o:value("h3,h2") + o:value("http/1.1") + o:value("h2,http/1.1") + o:value("h3,h2,http/1.1") + o:value("spdy/3.1") + o:value("h3,spdy/3.1") + o:depends({ [_n("protocol")] = "tuic" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range")) + o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + + o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) + o.datatype = "or(uinteger,portrange)" + o.placeholder = "30" + o.default = "30" + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + + o = s:option(Flag, _n("hysteria2_realms"), translate("Realms")) + o.default = "0" + if api.compare_versions(singbox_version, ">=", "1.14.0") then + o:depends({ [_n("protocol")] = "hysteria2"}) + else + o:depends({ [_n("protocol")] = "__hide"}) + end + + o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN")) + o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) + o:value("", translate("Disable")) + o:value("salamander") + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) + o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + + o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s~120s)") + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(Value, _n("hysteria2_keep_alive_period"), translate("QUIC KeepAlive interval"), translate("Example:") .. "10s (2s~60s)") + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(Flag, _n("hysteria2_disable_mtu_discovery"), translate("Disable MTU detection")) + o.default = "0" + o:depends({ [_n("protocol")] = "hysteria2"}) +end + +-- [[ SSH config start ]] -- +o = s:option(TextValue, _n("ssh_priv_key"), translate("Private Key")) +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("protocol")] = "ssh" }) +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n") + return value +end + +o = s:option(Value, _n("ssh_priv_key_pp"), translate("Private Key Passphrase")) +o.password = true +o:depends({ [_n("protocol")] = "ssh" }) + +o = s:option(DynamicList, _n("ssh_host_key"), translate("Host Key"), translate("Accept any if empty.")) +o:depends({ [_n("protocol")] = "ssh" }) + +o = s:option(DynamicList, _n("ssh_host_key_algo"), translate("Host Key Algorithms")) +o:depends({ [_n("protocol")] = "ssh" }) + +o = s:option(Value, _n("ssh_client_version"), translate("Client Version"), translate("Random version will be used if empty.")) +o:depends({ [_n("protocol")] = "ssh" }) +-- [[ SSH config end ]] -- + +-- [[ naive start ]] -- +o = s:option(Value, _n("naive_insecure_concurrency"), translate("Concurrent Tunnels")) +o.datatype = "uinteger" +o.placeholder = "0" +o.default = "0" +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Flag, _n("naive_quic"), translate("QUIC")) +o.default = 0 +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(ListValue, _n("naive_congestion_control"), translate("Congestion control algorithm")) +o.default = "bbr" +o:value("bbr", translate("BBR")) +o:value("bbr2", translate("BBRv2")) +o:value("cubic", translate("CUBIC")) +o:value("reno", translate("New Reno")) +o:depends({ [_n("naive_quic")] = "1" }) +-- [[ naive end ]] -- + +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "anytls" }) + +o = s:option(ListValue, _n("alpn"), translate("ALPN")) +o.default = "default" +o:value("default", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria" }) + +o = s:option(Flag, _n("tls_disable_sni"), translate("Disable SNI"), translate("Do not send server name in ClientHello.")) +o.default = "0" +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("tls_serverName"), "SNI " .. translate("Domain")) +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.")) +o.default = "0" +o:depends({ [_n("tls")] = true }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(TextValue, _n("ech_config"), translate("ECH Config")) +o.default = "" +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n") + return value +end + +o = s:option(Value, _n("ech_query_server_name"), translate("ECH Query Domain"), translate("Overrides the domain name used for ECH HTTPS record queries.")) +o:depends({ [_n("ech")] = true }) + +if singbox_tags:find("with_utls") then + o = s:option(Flag, _n("utls"), translate("uTLS")) + o.default = "0" + o:depends({ [_n("tls")] = true }) + + o = s:option(ListValue, _n("fingerprint"), translate("Finger Print")) + o:value("chrome") + o:value("firefox") + o:value("edge") + o:value("safari") + o:value("360") + o:value("qq") + o:value("ios") + o:value("android") + o:value("random") + o:value("randomized") + o.default = "chrome" + o:depends({ [_n("utls")] = true }) + + -- [[ REALITY ]] -- + o = s:option(Flag, _n("reality"), translate("REALITY")) + o.default = 0 + o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "socks", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "anytls", [_n("tls")] = true }) + + o = s:option(Value, _n("reality_publicKey"), translate("Public Key")) + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_shortId"), translate("Short Id")) + o:depends({ [_n("reality")] = true }) +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("tcp", "TCP") +o:value("http", "HTTP") +o:value("ws", "WebSocket") +o:value("httpupgrade", "HTTPUpgrade") +if singbox_tags:find("with_quic") then + o:value("quic", "QUIC") +end +if singbox_tags:find("with_grpc") then + o:value("grpc", "gRPC") +else o:value("grpc", "gRPC-lite") +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +if singbox_tags:find("with_wireguard") then + o = s:option(Value, _n("wireguard_public_key"), translate("Public Key")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_secret_key"), translate("Private Key")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_preSharedKey"), translate("Pre shared key")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(DynamicList, _n("wireguard_local_address"), translate("Local Address")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_mtu"), translate("MTU")) + o.default = "1420" + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Flag, _n("wireguard_system_interface"), translate("System interface")) + o.default = 0 + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_interface_name"), translate("System interface name")) + o:depends({ [_n("protocol")] = "wireguard" }) + + o = s:option(Value, _n("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings.")) + o:depends({ [_n("protocol")] = "wireguard" }) +end + +-- [[ TCP ]]-- +o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o:depends({ [_n("transport")] = "tcp" }) + +o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host")) +o:depends({ [_n("tcp_guise")] = "http" }) + +o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path")) +o.placeholder = "/" +o:depends({ [_n("tcp_guise")] = "http" }) + +-- [[ HTTP ]]-- +o = s:option(DynamicList, _n("http_host"), translate("HTTP Host")) +o:depends({ [_n("transport")] = "http" }) + +o = s:option(Value, _n("http_path"), translate("HTTP Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "http" }) + +o = s:option(Flag, _n("http_h2_health_check"), translate("Health check")) +o:depends({ [_n("tls")] = true, [_n("transport")] = "http" }) + +o = s:option(Value, _n("http_h2_read_idle_timeout"), translate("Idle timeout")) +o.default = "10" +o:depends({ [_n("tls")] = true, [_n("transport")] = "http", [_n("http_h2_health_check")] = true }) + +o = s:option(Value, _n("http_h2_health_check_timeout"), translate("Health check timeout")) +o.default = "15" +o:depends({ [_n("tls")] = true, [_n("transport")] = "http", [_n("http_h2_health_check")] = true }) + +-- [[ WebSocket ]]-- +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Flag, _n("ws_enableEarlyData"), translate("Enable early data")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_maxEarlyData"), translate("Early data length")) +o.default = "1024" +o:depends({ [_n("ws_enableEarlyData")] = true }) + +o = s:option(Value, _n("ws_earlyDataHeaderName"), translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol")) +o:depends({ [_n("ws_enableEarlyData")] = true }) + +-- [[ HTTPUpgrade ]]-- +o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ gRPC ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Flag, _n("grpc_health_check"), translate("Health check")) +o:depends({ [_n("transport")] = "grpc" }) + +o = s:option(Value, _n("grpc_idle_timeout"), translate("Idle timeout")) +o.default = "10" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Value, _n("grpc_health_check_timeout"), translate("Health check timeout")) +o.default = "20" +o:depends({ [_n("grpc_health_check")] = true }) + +o = s:option(Flag, _n("grpc_permit_without_stream"), translate("Permit without stream")) +o.default = "0" +o:depends({ [_n("grpc_health_check")] = true }) + +-- [[ User-Agent ]]-- +o = s:option(Value, _n("user_agent"), translate("User-Agent")) +o.default = "" +o:value("", translate("default")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", "chrome") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0", "firefox") +o:value("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15", "safari") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70", "edge") +o:value("Go-http-client/1.1", "golang") +o:value("curl/7.68.0", "curl") +o:depends({ [_n("tcp_guise")] = "http" }) +o:depends({ [_n("transport")] = "http" }) +o:depends({ [_n("transport")] = "ws" }) +o:depends({ [_n("transport")] = "httpupgrade" }) +o:depends({ [_n("protocol")] = "naive" }) + +-- [[ Mux ]]-- +o = s:option(Flag, _n("mux"), translate("Mux")) +o.rmempty = false +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("uot")] = "" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(ListValue, _n("mux_type"), translate("Mux")) +o:value("smux") +o:value("yamux") +o:value("h2mux") +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("mux_concurrency"), translate("Mux concurrency")) +o.default = 4 +o:depends({ [_n("mux")] = true, [_n("tcpbrutal")] = false }) + +o = s:option(Flag, _n("mux_padding"), translate("Padding")) +o.default = 0 +o:depends({ [_n("mux")] = true }) + +-- [[ TCP Brutal ]]-- +o = s:option(Flag, _n("tcpbrutal"), translate("TCP Brutal")) +o.default = 0 +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("tcpbrutal_up_mbps"), translate("Max upload Mbps")) +o.default = "10" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Value, _n("tcpbrutal_down_mbps"), translate("Max download Mbps")) +o.default = "50" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Flag, _n("shadowtls"), "ShadowTLS") +o.default = 0 +o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = false }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = false }) + +o = s:option(ListValue, _n("shadowtls_version"), "ShadowTLS " .. translate("Version")) +o.default = "1" +o:value("1", "ShadowTLS v1") +o:value("2", "ShadowTLS v2") +o:value("3", "ShadowTLS v3") +o:depends({ [_n("shadowtls")] = true }) + +o = s:option(Value, _n("shadowtls_password"), "ShadowTLS " .. translate("Password")) +o.password = true +o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "2" }) +o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_version")] = "3" }) + +o = s:option(Value, _n("shadowtls_serverName"), "ShadowTLS " .. translate("Domain")) +o:depends({ [_n("shadowtls")] = true }) + +if singbox_tags:find("with_utls") then + o = s:option(Flag, _n("shadowtls_utls"), "ShadowTLS " .. translate("uTLS")) + o.default = "0" + o:depends({ [_n("shadowtls")] = true }) + + o = s:option(ListValue, _n("shadowtls_fingerprint"), "ShadowTLS " .. translate("Finger Print")) + o:value("chrome") + o:value("firefox") + o:value("edge") + o:value("safari") + -- o:value("360") + o:value("qq") + o:value("ios") + -- o:value("android") + o:value("random") + -- o:value("randomized") + o.default = "chrome" + o:depends({ [_n("shadowtls")] = true, [_n("shadowtls_utls")] = true }) +end + +-- [[ SIP003 plugin ]]-- +o = s:option(Flag, _n("plugin_enabled"), translate("plugin")) +o.default = 0 +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("plugin"), "SIP003 " .. translate("plugin")) +o.default = "obfs-local" +o:depends({ [_n("plugin_enabled")] = true }) +o:value("obfs-local") +o:value("v2ray-plugin") + +o = s:option(Value, _n("plugin_opts"), translate("opts")) +o:depends({ [_n("plugin_enabled")] = true }) + +o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve"), translate("If the node address is a domain name, this DNS will be used for resolution.")) +o:value("", translate("Auto")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("https", "HTTPS") + +o = s:option(Value, _n("domain_resolver_dns"), "DNS") +o.datatype = "or(ipaddr,ipaddrport)" +o:value("114.114.114.114") +o:value("223.5.5.5:53") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "tcp" }) +o:depends({ [_n("domain_resolver")] = "udp" }) + +o = s:option(Value, _n("domain_resolver_dns_https"), "DNS") +o:value("https://120.53.53.53/dns-query", "DNSPod") +o:value("https://223.5.5.5/dns-query", "AliDNS") +o.default = o.keylist[1] +o:depends({ [_n("domain_resolver")] = "https" }) + +o = s:option(ListValue, _n("domain_strategy"), translate("Domain Strategy"), translate("If is domain name, The requested domain name will be resolved to IP before connect.")) +o.default = "" +o:value("", translate("Auto")) +o:value("prefer_ipv4", translate("Prefer IPv4")) +o:value("prefer_ipv6", translate("Prefer IPv6")) +o:value("ipv4_only", translate("IPv4 Only")) +o:value("ipv6_only", translate("IPv6 Only")) + +local protocols = s.fields[_n("protocol")].keylist +if #protocols > 0 then + for i, v in ipairs(protocols) do + if not v:find("^_") then + local depends_condition = { [_n("protocol")] = v } + if v == "hysteria2" then + depends_condition[_n("hysteria2_realms")] = false + end + s.fields[_n("address")]:depends(depends_condition) + s.fields[_n("port")]:depends(depends_condition) + s.fields[_n("domain_resolver")]:depends(depends_condition) + s.fields[_n("domain_strategy")]:depends(depends_condition) + end + end +end +end +-- [[ Normal single node End ]] + +if not load_shunt_options then + o = s:option(ListValue, _n("chain_proxy"), translate("Chain Proxy")) + o:value("", translate("Close(Not use)")) + if not (load_iface_options or load_urltest_options) then + -- Special node cannot be use pre-proxy. + o:value("1", translate("Preproxy Node")) + o:value("3", translate("Outbound Interface")) + end + o:value("2", translate("Landing Node")) + + o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) + o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false }) + o1.template = appname .. "/cbi/nodes_listvalue" + o1.group = {} + + o3 = s:option(Value, _n("outbound_iface"), translate("Outbound Interface")) + o3:depends({ [_n("chain_proxy")] = "3" }) + o3:value("", translate("All")) + for _, d in ipairs(netdev_list) do + o3:value(d.name, d.label) + end + + o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) + o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false }) + o2.template = appname .. "/cbi/nodes_listvalue" + o2.group = {} + + for k1, v1 in pairs(node_list) do + if k1 ~= "shunt_list" and k1 ~= "iface_list" then + for i, v in ipairs(v1) do + if v.id ~= arg[1] then + o1:value(v.id, v.remark) + o1.group[#o1.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + if k1 == "normal_list" then + -- Landing Node not support use special node. + o2:value(v.id, v.remark) + o2.group[#o2.group+1] = (v.group and v.group ~= "") and v.group or translate("default") + end + end + end + end + end +end + +api.luci_types(arg[1], m, s, type_name, option_prefix) + +if load_shunt_options then + local current_node = m.uci:get_all(appname, arg[1]) or {} + local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua") + setfenv(shunt_lua, getfenv(1))(m, s, { + node_id = arg[1], + node = current_node, + node_list = node_list, + }) +end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua new file mode 100644 index 00000000..ae18e369 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua @@ -0,0 +1,72 @@ +local m, s = ... + +if not api.is_finded("sslocal") then + return +end + +type_name = "SS-Rust" + +-- [[ Shadowsocks Rust ]] + +s.fields["type"]:value(type_name, "Shadowsocks Rust") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssrust_" + +local function _n(name) + return option_prefix .. name +end + +local ssrust_encrypt_method_list = { + "none", "plain", + "aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305" +} + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true + +o = s:option(Value, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) +o.default = 0 + +o = s:option(Flag, _n("plugin_enabled"), translate("plugin")) +o.default = 0 + +o = s:option(Value, _n("plugin"), "SIP003 " .. translate("plugin"), translate("Supports custom SIP003 plugins, Make sure the plugin is installed.")) +o.default = "none" +o:value("none", translate("none")) +if api.is_finded("xray-plugin") then o:value("xray-plugin") end +if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end +if api.is_finded("obfs-local") then o:value("obfs-local") end +if api.is_finded("shadow-tls") then o:value("shadow-tls") end +o:depends({ [_n("plugin_enabled")] = true }) +o.validate = function(self, value, t) + if value and value ~= "" and value ~= "none" then + if not api.is_finded(value) then + return nil, value .. ": " .. translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(Value, _n("plugin_opts"), translate("opts")) +o:depends({ [_n("plugin_enabled")] = true }) + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua new file mode 100644 index 00000000..f23e8efa --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua @@ -0,0 +1,70 @@ +local m, s = ... + +if not api.is_finded("ssr-local") then + return +end + +type_name = "SSR" + +-- [[ ShadowsocksR Libev ]] + +s.fields["type"]:value(type_name, "ShadowsocksR Libev") + +if s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssr_" + +local function _n(name) + return option_prefix .. name +end + +local ssr_encrypt_method_list = { + "none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb", + "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", + "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", + "cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20", + "chacha20-ietf" +} + +local ssr_protocol_list = { + "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple", + "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5", + "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c", + "auth_chain_d", "auth_chain_e", "auth_chain_f" +} +local ssr_obfs_list = { + "plain", "http_simple", "http_post", "random_head", "tls_simple", + "tls1.0_session_auth", "tls1.2_ticket_auth" +} + +o = s:option(Value, _n("address"), translate("Address (Support Domain Name)")) + +o = s:option(Value, _n("port"), translate("Port")) +o.datatype = "port" + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true + +o = s:option(ListValue, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +for a, t in ipairs(ssr_protocol_list) do o:value(t) end + +o = s:option(Value, _n("protocol_param"), translate("Protocol_param")) + +o = s:option(ListValue, _n("obfs"), translate("Obfs")) +for a, t in ipairs(ssr_obfs_list) do o:value(t) end + +o = s:option(Value, _n("obfs_param"), translate("Obfs_param")) + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required")) +o.default = 0 + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/index.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/index.lua new file mode 100644 index 00000000..70bec3f8 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/index.lua @@ -0,0 +1,92 @@ +local api = require "luci.passwall2.api" + +m = Map("passwall2_server", translate("Server-Side")) +api.set_apply_on_parse(m) + +t = m:section(NamedSection, "global", "global") +t.anonymous = true +t.addremove = false + +e = t:option(Flag, "enable", translate("Enable")) +e.rmempty = false + +t = m:section(TypedSection, "user", translate("Users Manager")) +t.anonymous = true +t.addremove = true +t.sortable = true +t.template = "cbi/tblsection" +t.extedit = api.url("server_user", "%s") +function t.create(e, t) + local uuid = api.gen_uuid() + t = uuid + TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) +end +function t.remove(e, t) + e.map.proceed = true + e.map:del(t) + luci.http.redirect(api.url("server")) +end + +e = t:option(Flag, "enable", translate("Enable")) +e.width = "5%" +e.rmempty = false + +e = t:option(DummyValue, "status", translate("Status")) +e.rawhtml = true +e.cfgvalue = function(t, n) + return string.format('%s', translate("Collecting data...")) +end + +e = t:option(DummyValue, "remarks", translate("Remarks")) +e.width = "15%" + +e = t:option(DummyValue, "type", translate("Type")) +e.width = "20%" +e.rawhtml = true +e.cfgvalue = function(t, n) + local str = "" + local type = m:get(n, "type") or "" + if type == "sing-box" or type == "Xray" then + local protocol = m:get(n, "protocol") or "" + if protocol == "vmess" then + protocol = "VMess" + elseif protocol == "vless" then + protocol = "VLESS" + elseif protocol == "shadowsocks" then + protocol = "SS" + elseif protocol == "shadowsocksr" then + protocol = "SSR" + elseif protocol == "wireguard" then + protocol = "WG" + elseif protocol == "hysteria" then + protocol = "HY" + elseif protocol == "hysteria2" then + protocol = "HY2" + elseif protocol == "anytls" then + protocol = "AnyTLS" + else + protocol = protocol:gsub("^%l",string.upper) + local custom = m:get(n, "custom") or "0" + if custom == "1" then + protocol = translate("Custom Config") + end + end + if type == "sing-box" then type = "Sing-Box" end + type = type .. " " .. protocol + end + str = str .. translate(type) + return str +end + +e = t:option(DummyValue, "port", translate("Port")) + +e = t:option(Flag, "log", translate("Log")) +e.default = "1" +e.rmempty = false + +m:append(Template("passwall2/server/log")) + +m:append(Template("passwall2/server/users_list_status")) +return m + diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua new file mode 100644 index 00000000..89742db8 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua @@ -0,0 +1,131 @@ +local m, s = ... + +if not api.finded_com("hysteria") then + return +end + +local type_name = "Hysteria2" + +-- [[ Hysteria2 ]] + +s.fields["type"]:value(type_name, "Hysteria2") + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "hysteria2_" + +local function _n(name) + return option_prefix .. name +end + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("realms"), translate("Realms")) +o.default = "0" +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(DynamicList, _n("realm_stun"), translate("Realm STUN")) +o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } +o.rewrite_option = o.option +o:depends({ [_n("realms")] = "1" }) + +o = s:option(Value, _n("auth_password"), translate("Auth Password")) +o.password = true +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("obfs_password"), translate("Obfs Password")) +o.rewrite_option = o.option +o:depends({ [_n("obfs_type")] = "salamander" }) + +o = s:option(Flag, _n("udp"), translate("UDP")) +o.default = "1" +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps")) +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("down_mbps"), translate("Max download Mbps")) +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("ignoreClientBandwidth"), translate("ignoreClientBandwidth")) +o.default = "0" +o.rewrite_option = o.option +o:depends({ [_n("custom")] = false }) + +o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o.validate = function(self, value, t) + if value and value ~= "" then + if not nixio.fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end +o:depends({ [_n("custom")] = false }) + +o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o.validate = function(self, value, t) + if value and value ~= "" then + if not nixio.fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end +o:depends({ [_n("custom")] = false }) + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua new file mode 100644 index 00000000..ff99b15b --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua @@ -0,0 +1,531 @@ +local m, s = ... + +if not api.finded_com("xray") then + return +end + +local type_name = "Xray" + +-- [[ Xray ]] + +s.fields["type"]:value(type_name, "Xray") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "xray_" + +local function _n(name) + return option_prefix .. name +end + +local x_ss_method_list = { + "none", "plain", "aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +local header_type_list = { + "none", "srtp", "utp", "wechat-video", "dtls", "wireguard", "dns" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("vmess", "Vmess") +o:value("vless", "VLESS") +o:value("http", "HTTP") +o:value("socks", "Socks") +o:value("shadowsocks", "Shadowsocks") +o:value("trojan", "Trojan") +o:value("hysteria2", translate("Hysteria2")) +o:value("dokodemo-door", "dokodemo-door") +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("auth"), translate("Auth")) +o.validate = function(self, value, t) + if value and value == "1" then + local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or "" + local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or "" + if user_v == "" or pass_v == "" then + return nil, translate("Username and Password must be used together!") + end + end + return value +end +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "http" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("auth")] = true }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("auth")] = true }) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o:depends({ [_n("protocol")] = "dokodemo-door" }) + +o = s:option(Value, _n("d_address"), translate("Destination address")) +o:depends({ [_n("protocol")] = "dokodemo-door" }) + +o = s:option(Value, _n("d_port"), translate("Destination port")) +o.datatype = "port" +o:depends({ [_n("protocol")] = "dokodemo-door" }) + +o = s:option(Value, _n("decryption"), translate("Encrypt Method") .. " (decryption)") +o.default = "none" +o.placeholder = "none" +o:depends({ [_n("protocol")] = "vless" }) +o.validate = function(self, value) + value = api.trim(value) + return (value == "" and "none" or value) +end + +o = s:option(ListValue, _n("x_ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(x_ss_method_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("iv_check"), translate("IV Check")) +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(ListValue, _n("ss_network"), translate("Transport")) +o.default = "tcp,udp" +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(Flag, _n("udp_forward"), translate("UDP Forward")) +o.default = "1" +o.rmempty = false +o:depends({ [_n("protocol")] = "socks" }) + +o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password")) +for i = 1, 3 do + o:value(api.gen_uuid(1)) +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:depends({ [_n("protocol")] = "vless" }) + +---- [[ hysteria2 ]] +o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) +o.password = true +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) +o:value("", translate("Disable")) +o:value("salamander") +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) +o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + +o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control")) +o.default = 0 +o:depends({ [_n("protocol")] = "hysteria2" }) + +o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) + +o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) + +---- [[ TLS ]] +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o.validate = function(self, value, t) + if value then + local reality = s.fields[_n("reality")] and s.fields[_n("reality")]:formvalue(t) or nil + if reality and reality == "1" then return value end + if value == "1" then + local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or "" + local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or "" + if ca == "" or key == "" then + return nil, translate("Public key and Private key path can not be empty!") + end + end + return value + end +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ REALITY ]] -- +o = s:option(Flag, _n("reality"), translate("REALITY")) +o.default = 0 +o:depends({ [_n("tls")] = true }) + +o = s:option(Value, _n("reality_private_key"), translate("Private Key")) +o:depends({ [_n("reality")] = true }) + +o = s:option(DynamicList, _n("reality_shortId"), translate("Short Id")) +o:depends({ [_n("reality")] = true }) + +o = s:option(Value, _n("reality_dest"), translate("Dest")) +o.default = "google.com:443" +o:depends({ [_n("reality")] = true }) + +o = s:option(DynamicList, _n("reality_serverNames"), translate("serverNames")) +o:depends({ [_n("reality")] = true }) +function o.write(self, section, value) + local t = {} + local t2 = {} + if type(value) == "table" then + local x + for _, x in ipairs(value) do + if x and #x > 0 then + if not t2[x] then + t2[x] = x + t[#t+1] = x + end + end + end + else + t = { value } + end + return DynamicList.write(self, section, t) +end + +o = s:option(ListValue, _n("alpn"), translate("alpn")) +o.default = "h2,http/1.1" +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65")) +o.default = "0" +o:depends({ [_n("reality")] = true }) + +o = s:option(TextValue, _n("reality_mldsa65Seed"), "ML-DSA-65 " .. translate("Private Key")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("use_mldsa65Seed")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +-- o = s:option(Value, _n("minversion"), translate("minversion")) +-- o.default = "1.3" +-- o:value("1.3") +--o:depends({ [_n("tls")] = true }) + +-- [[ TLS ]] -- +o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2"}) +o.validate = function(self, value, t) + if value and value ~= "" then + if not nixio.fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2"}) +o.validate = function(self, value, t) + if value and value ~= "" then + if not nixio.fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) + +o = s:option(TextValue, _n("ech_key"), translate("ECH Key")) +o.default = "" +o.rows = 5 +o.wrap = "soft" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + return api.trim(value:gsub("[\r\n]", "")) +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("raw", "RAW") +o:value("mkcp", "mKCP") +o:value("ws", "WebSocket") +o:value("grpc", "gRPC") +o:value("httpupgrade", "HttpUpgrade") +o:value("xhttp", "XHTTP") +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ WebSocket ]]-- +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o:depends({ [_n("transport")] = "ws" }) + +-- [[ HttpUpgrade ]]-- +o = s:option(Value, _n("httpupgrade_host"), translate("HttpUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HttpUpgrade Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ XHTTP ]]-- +o = s:option(Value, _n("xhttp_host"), translate("XHTTP Host")) +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_path"), translate("XHTTP Path")) +o.placeholder = "/" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_maxuploadsize"), translate("maxUploadSize")) +o.default = "1000000" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("xhttp_maxconcurrentuploads"), translate("maxConcurrentUploads")) +o.default = "10" +o:depends({ [_n("transport")] = "xhttp" }) + +o = s:option(Value, _n("splithttp_maxuploadsize"), translate("maxUploadSize")) +o.default = "1000000" +o:depends({ [_n("transport")] = "splithttp" }) + +o = s:option(Value, _n("splithttp_maxconcurrentuploads"), translate("maxConcurrentUploads")) +o.default = "10" +o:depends({ [_n("transport")] = "splithttp" }) + +-- [[ TCP ]]-- + +o = s:option(ListValue, _n("tcp_guise"), translate("Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o:depends({ [_n("transport")] = "raw" }) + +o = s:option(DynamicList, _n("tcp_guise_http_host"), translate("HTTP Host")) +o:depends({ [_n("tcp_guise")] = "http" }) + +o = s:option(DynamicList, _n("tcp_guise_http_path"), translate("HTTP Path")) +o:depends({ [_n("tcp_guise")] = "http" }) + +-- [[ mKCP ]]-- + +o = s:option(ListValue, _n("mkcp_guise"), translate("Camouflage Type"), translate('
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests.')) +for a, t in ipairs(header_type_list) do o:value(t) end +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_domain"), translate("Camouflage Domain"), translate("Use it together with the DNS disguised type. You can fill in any domain.")) +o:depends({ [_n("mkcp_guise")] = "dns" }) + +o = s:option(Value, _n("mkcp_mtu"), translate("KCP MTU")) +o.datatype = "uinteger" +o.default = 1350 +o:depends({ [_n("transport")] = "mkcp" }) + +o = s:option(Value, _n("mkcp_seed"), translate("KCP Seed")) +o:depends({ [_n("transport")] = "mkcp" }) + +-- [[ gRPC ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +--[[FinalMask]] +o = s:option(Flag, _n("use_finalmask"), "FinalMask") +o.default = "0" +o:depends({ [_n("custom")] = false, [_n("protocol")] = "vmess" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "vless" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "trojan" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "wireguard" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "hysteria2" }) + +o = s:option(TextValue, _n("finalmask"), "FinalMask JSON") +o:depends({ [_n("use_finalmask")] = true }) +o.rows = 10 +o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "finalmask") + if raw then + return api.base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "finalmask", api.base64Encode(value) or "") +end +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if api.jsonc.parse(value) then + return value + else + return nil, "FinalMask " .. translate("Must be JSON text!") + end +end + +--[[acceptProxyProtocol]] +o = s:option(Flag, _n("acceptProxyProtocol"), translate("acceptProxyProtocol"), translate("Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used.")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +--[[Fast Open]] +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) +o.default = "0" +o:depends({ [_n("protocol")] = "vmess", [_n("custom")] = false }) +o:depends({ [_n("protocol")] = "vless", [_n("custom")] = false }) +o:depends({ [_n("protocol")] = "shadowsocks", [_n("custom")] = false }) +o:depends({ [_n("protocol")] = "trojan", [_n("custom")] = false }) + +-- [[ Fallback ]]-- +o = s:option(Flag, _n("fallback"), translate("Fallback")) +o:depends({ [_n("protocol")] = "vless", [_n("transport")] = "raw" }) +o:depends({ [_n("protocol")] = "trojan", [_n("transport")] = "raw" }) + +--[[ +o = s:option(Value, _n("fallback_alpn"), "Fallback alpn") +o:depends({ [_n("fallback")] = true }) + +o = s:option(Value, _n("fallback_path"), "Fallback path") +o:depends({ [_n("fallback")] = true }) + +o = s:option(Value, _n("fallback_dest"), "Fallback dest") +o:depends({ [_n("fallback")] = true }) + +o = s:option(Value, _n("fallback_xver"), "Fallback xver") +o.default = 0 +o:depends({ [_n("fallback")] = true }) +]]-- + +o = s:option(DynamicList, _n("fallback_list"), "Fallback", translate("format: dest,path,xver")) +o:depends({ [_n("fallback")] = true }) + +o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e.type == type_name then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + remarks = e["remark"], + group = e["group"] + } + end +end + +o = s:option(ListValue, _n("outbound_node"), translate("outbound node")) +o:value("", translate("Close")) +o:value("_socks", translate("Custom Socks")) +o:value("_http", translate("Custom HTTP")) +o:value("_iface", translate("Custom Interface")) +o.template = api.appname .. "/cbi/nodes_listvalue" +o.group = {"","","",""} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)")) +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_port"), translate("Port")) +o.datatype = "port" +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_username"), translate("Username")) +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_password"), translate("Password")) +o.password = true +o:depends({ [_n("outbound_node")] = "_socks"}) +o:depends({ [_n("outbound_node")] = "_http"}) + +o = s:option(Value, _n("outbound_node_iface"), translate("Interface")) +o:depends({ [_n("outbound_node")] = "_iface"}) +local netdev_list = api.get_network_devices() +for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) +end + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +o = s:option(ListValue, _n("loglevel"), translate("Log Level")) +o.default = "warning" +o:value("debug") +o:value("info") +o:value("warning") +o:value("error") +o:depends({ [_n("log")] = true }) + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua new file mode 100644 index 00000000..dd3cb2f4 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua @@ -0,0 +1,505 @@ +local m, s = ... + +local singbox_bin = api.finded_com("sing-box") + +if not singbox_bin then + return +end + +local type_name = "sing-box" + +-- [[ Sing-Box ]] + +s.fields["type"]:value(type_name, "Sing-Box") +if not s.fields["type"].default then + s.fields["type"].default = type_name +end + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "singbox_" + +local function _n(name) + return option_prefix .. name +end + +local singbox_tags = luci.sys.exec(singbox_bin .. " version | grep 'Tags:' | awk '{print $2}'") + +local ss_method_list = { + "none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +o:value("mixed", "Mixed") +o:value("socks", "Socks") +o:value("http", "HTTP") +o:value("shadowsocks", "Shadowsocks") +o:value("vmess", "Vmess") +o:value("vless", "VLESS") +o:value("trojan", "Trojan") +o:value("naive", "Naive") +if singbox_tags:find("with_quic") then + o:value("hysteria", "Hysteria") +end +if singbox_tags:find("with_quic") then + o:value("tuic", "TUIC") +end +if singbox_tags:find("with_quic") then + o:value("hysteria2", "Hysteria2") +end +o:value("anytls", "AnyTLS") +o:value("direct", "Direct") +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("auth"), translate("Auth")) +o.validate = function(self, value, t) + if value and value == "1" then + local user_v = s.fields[_n("username")] and s.fields[_n("username")]:formvalue(t) or "" + local pass_v = s.fields[_n("password")] and s.fields[_n("password")]:formvalue(t) or "" + if user_v == "" or pass_v == "" then + return nil, translate("Username and Password must be used together!") + end + end + return value +end +o:depends({ [_n("protocol")] = "mixed" }) +o:depends({ [_n("protocol")] = "socks" }) +o:depends({ [_n("protocol")] = "http" }) + +o = s:option(Value, _n("username"), translate("Username")) +o:depends({ [_n("auth")] = true }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "anytls" }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("auth")] = true }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "anytls" }) + +if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria_up_mbps"), translate("Max upload Mbps")) + o.default = "100" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_down_mbps"), translate("Max download Mbps")) + o.default = "100" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(ListValue, _n("hysteria_auth_type"), translate("Auth Type")) + o:value("disable", translate("Disable")) + o:value("string", translate("STRING")) + o:value("base64", translate("BASE64")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "string"}) + o:depends({ [_n("protocol")] = "hysteria", [_n("hysteria_auth_type")] = "base64"}) + + o = s:option(Value, _n("hysteria_recv_window_conn"), translate("QUIC stream receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_recv_window_client"), translate("QUIC connection receive window")) + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Value, _n("hysteria_max_conn_client"), translate("QUIC concurrent bidirectional streams")) + o.default = "1024" + o:depends({ [_n("protocol")] = "hysteria" }) + + o = s:option(Flag, _n("hysteria_disable_mtu_discovery"), translate("Disable MTU detection")) + o:depends({ [_n("protocol")] = "hysteria" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(ListValue, _n("tuic_congestion_control"), translate("Congestion control algorithm")) + o.default = "cubic" + o:value("bbr", translate("BBR")) + o:value("cubic", translate("CUBIC")) + o:value("new_reno", translate("New Reno")) + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(Flag, _n("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake")) + o.default = 0 + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(Value, _n("tuic_heartbeat"), translate("Heartbeat interval(second)")) + o.datatype = "uinteger" + o.default = "3" + o:depends({ [_n("protocol")] = "tuic" }) + + o = s:option(ListValue, _n("tuic_alpn"), translate("QUIC TLS ALPN")) + o.default = "default" + o:value("default", translate("Default")) + o:value("h3") + o:value("h2") + o:value("h3,h2") + o:value("http/1.1") + o:value("h2,http/1.1") + o:value("h3,h2,http/1.1") + o:value("spdy/3.1") + o:value("h3,spdy/3.1") + o:depends({ [_n("protocol")] = "tuic" }) +end + +if singbox_tags:find("with_quic") then + o = s:option(Flag, _n("hysteria2_realms"), translate("Realms")) + o.default = "0" + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN")) + o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } + o:depends({ [_n("hysteria2_realms")] = "1" }) + + o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) + o.password = true + o:depends({ [_n("protocol")] = "hysteria2"}) + + o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) + o:value("", translate("Disable")) + o:value("salamander") + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) + o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + + o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"), translate("Commands the client to use the BBR flow control algorithm")) + o.default = 0 + o:depends({ [_n("protocol")] = "hysteria2" }) + + o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) + + o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps")) + o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_ignore_client_bandwidth")] = false }) +end + +o = s:option(ListValue, _n("d_protocol"), translate("Destination protocol")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o:depends({ [_n("protocol")] = "direct" }) + +o = s:option(Value, _n("d_address"), translate("Destination address")) +o:depends({ [_n("protocol")] = "direct" }) + +o = s:option(Value, _n("d_port"), translate("Destination port")) +o.datatype = "port" +o:depends({ [_n("protocol")] = "direct" }) + +o = s:option(Value, _n("decryption"), translate("Encrypt Method")) +o.default = "none" +o:depends({ [_n("protocol")] = "vless" }) + +o = s:option(ListValue, _n("ss_method"), translate("Encrypt Method")) +o.rewrite_option = "method" +for a, t in ipairs(ss_method_list) do o:value(t) end +o:depends({ [_n("protocol")] = "shadowsocks" }) + +o = s:option(DynamicList, _n("uuid"), translate("ID") .. "/" .. translate("Password")) +for i = 1, 3 do + o:value(api.gen_uuid(1)) +end +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "tuic" }) + +o = s:option(ListValue, _n("flow"), translate("flow")) +o.default = "" +o:value("", translate("Disable")) +o:value("xtls-rprx-vision") +o:depends({ [_n("protocol")] = "vless" , [_n("tls")] = true }) + +o = s:option(Flag, _n("tls"), translate("TLS")) +o.default = 0 +o.validate = function(self, value, t) + if value then + local reality = s.fields[_n("reality")] and s.fields[_n("reality")]:formvalue(t) or nil + if reality and reality == "1" then return value end + if value == "1" then + local ca = s.fields[_n("tls_certificateFile")] and s.fields[_n("tls_certificateFile")]:formvalue(t) or "" + local key = s.fields[_n("tls_keyFile")] and s.fields[_n("tls_keyFile")]:formvalue(t) or "" + if ca == "" or key == "" then + return nil, translate("Public key and Private key path can not be empty!") + end + end + return value + end +end +o:depends({ [_n("protocol")] = "http" }) +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) +o:depends({ [_n("protocol")] = "anytls" }) + +-- https://github.com/SagerNet/sing-box/commit/d2a04c4e41e6cef0937331cb6d10211f431caaab +if singbox_tags:find("with_utls") then + -- [[ REALITY ]] -- + o = s:option(Flag, _n("reality"), translate("REALITY")) + o.default = 0 + o:depends({ [_n("protocol")] = "http", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true }) + o:depends({ [_n("protocol")] = "anytls", [_n("tls")] = true }) + + o = s:option(Value, _n("reality_private_key"), translate("Private Key")) + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_shortId"), translate("Short Id")) + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_handshake_server"), translate("Handshake Server")) + o.default = "google.com" + o:depends({ [_n("reality")] = true }) + + o = s:option(Value, _n("reality_handshake_server_port"), translate("Handshake Server Port")) + o.datatype = "port" + o.default = "443" + o:depends({ [_n("reality")] = true }) +end + +o = s:option(ListValue, _n("alpn"), translate("ALPN")) +o.default = "default" +o:value("default", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria" }) + +-- [[ TLS ]] -- + +o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem") +o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key") +o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key" +if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o.validate = function(self, value, t) + if value and value ~= "" then + if not fs.access(value) then + return nil, translate("Can't find this file!") + else + return value + end + end + return nil +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "naive" }) +o:depends({ [_n("protocol")] = "hysteria" }) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + +o = s:option(TextValue, _n("ech_key"), translate("ECH Key")) +o.default = "" +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("ech")] = true }) +o.validate = function(self, value) + value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n") + value = value:gsub("^%s*\n", "") + if value:sub(-1) == "\n" then + value = value:sub(1, -2) + end + return value +end + +o = s:option(ListValue, _n("transport"), translate("Transport")) +o:value("tcp", "TCP") +o:value("http", "HTTP") +o:value("ws", "WebSocket") +o:value("httpupgrade", "HTTPUpgrade") +o:value("quic", "QUIC") +o:value("grpc", "gRPC") +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ HTTP ]]-- + +o = s:option(DynamicList, _n("http_host"), translate("HTTP Host")) +o:depends({ [_n("transport")] = "http" }) + +o = s:option(Value, _n("http_path"), translate("HTTP Path")) +o:depends({ [_n("transport")] = "http" }) + +-- [[ WebSocket ]]-- + +o = s:option(Value, _n("ws_host"), translate("WebSocket Host")) +o:depends({ [_n("transport")] = "ws" }) + +o = s:option(Value, _n("ws_path"), translate("WebSocket Path")) +o:depends({ [_n("transport")] = "ws" }) + +-- [[ HTTPUpgrade ]]-- + +o = s:option(Value, _n("httpupgrade_host"), translate("HTTPUpgrade Host")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +o = s:option(Value, _n("httpupgrade_path"), translate("HTTPUpgrade Path")) +o:depends({ [_n("transport")] = "httpupgrade" }) + +-- [[ gRPC ]]-- +o = s:option(Value, _n("grpc_serviceName"), "ServiceName") +o:depends({ [_n("transport")] = "grpc" }) + +-- [[ Mux ]]-- +o = s:option(Flag, _n("mux"), translate("Mux")) +o.rmempty = false +o:depends({ [_n("protocol")] = "vmess" }) +o:depends({ [_n("protocol")] = "vless", [_n("flow")] = "" }) +o:depends({ [_n("protocol")] = "shadowsocks" }) +o:depends({ [_n("protocol")] = "trojan" }) + +-- [[ TCP Brutal ]]-- +o = s:option(Flag, _n("tcpbrutal"), translate("TCP Brutal")) +o.default = 0 +o:depends({ [_n("mux")] = true }) + +o = s:option(Value, _n("tcpbrutal_up_mbps"), translate("Max upload Mbps")) +o.default = "10" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Value, _n("tcpbrutal_down_mbps"), translate("Max download Mbps")) +o.default = "50" +o:depends({ [_n("tcpbrutal")] = true }) + +o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e.type == type_name then + nodes_table[#nodes_table + 1] = { + id = e[".name"], + remarks = e["remark"], + group = e["group"] + } + end +end + +o = s:option(ListValue, _n("outbound_node"), translate("outbound node")) +o:value("", translate("Close")) +o:value("_socks", translate("Custom Socks")) +o:value("_http", translate("Custom HTTP")) +o:value("_iface", translate("Custom Interface")) +o.template = api.appname .. "/cbi/nodes_listvalue" +o.group = {"","","",""} +for k, v in pairs(nodes_table) do + o:value(v.id, v.remarks) + o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default") +end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)")) +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_port"), translate("Port")) +o.datatype = "port" +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_username"), translate("Username")) +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_password"), translate("Password")) +o.password = true +o:depends({ [_n("outbound_node")] = "_socks" }) +o:depends({ [_n("outbound_node")] = "_http" }) + +o = s:option(Value, _n("outbound_node_iface"), translate("Interface")) +o:depends({ [_n("outbound_node")] = "_iface" }) +local netdev_list = api.get_network_devices() +for _, d in ipairs(netdev_list) do + o:value(d.name, d.label) +end + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +o = s:option(ListValue, _n("loglevel"), translate("Log Level")) +o.default = "info" +o:value("debug") +o:value("info") +o:value("warn") +o:value("error") +o:depends({ [_n("log")] = true }) + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ss-rust.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ss-rust.lua new file mode 100644 index 00000000..d0939430 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ss-rust.lua @@ -0,0 +1,77 @@ +local m, s = ... + +if not api.is_finded("ssserver") then + return +end + +local type_name = "SS-Rust" + +-- [[ Shadowsocks Rust ]] + +s.fields["type"]:value(type_name, translate("Shadowsocks Rust")) + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssrust_" + +local function _n(name) + return option_prefix .. name +end + +local ssrust_encrypt_method_list = { + "plain", "none", + "aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ssr.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ssr.lua new file mode 100644 index 00000000..02a94f61 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ssr.lua @@ -0,0 +1,108 @@ +local m, s = ... + +if not api.is_finded("ssr-server") then + return +end + +local type_name = "SSR" + +-- [[ ShadowsocksR ]] + +s.fields["type"]:value(type_name, translate("ShadowsocksR")) + +if s.val["type"] and s.val["type"] ~= type_name then + return +end + +local option_prefix = "ssr_" + +local function _n(name) + return option_prefix .. name +end + +local ssr_encrypt_method_list = { + "none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb", + "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", + "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", + "cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20", + "chacha20-ietf" +} + +local ssr_protocol_list = { + "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple", + "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5", + "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c", + "auth_chain_d", "auth_chain_e", "auth_chain_f" +} +local ssr_obfs_list = { + "plain", "http_simple", "http_post", "random_head", "tls_simple", + "tls1.0_session_auth", "tls1.2_ticket_auth" +} + +o = s:option(Flag, _n("custom"), translate("Use Custom Config")) + +o = s:option(Value, _n("port"), translate("Listen Port")) +o.datatype = "port" +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("password"), translate("Password")) +o.password = true +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("method"), translate("Encrypt Method")) +for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("protocol"), translate("Protocol")) +for a, t in ipairs(ssr_protocol_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("protocol_param"), translate("Protocol_param")) +o:depends({ [_n("custom")] = false }) + +o = s:option(ListValue, _n("obfs"), translate("Obfs")) +for a, t in ipairs(ssr_obfs_list) do o:value(t) end +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("obfs_param"), translate("Obfs_param")) +o:depends({ [_n("custom")] = false }) + +o = s:option(Value, _n("timeout"), translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 300 +o:depends({ [_n("custom")] = false }) + +o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open")) +o.default = "0" +o:depends({ [_n("custom")] = false }) + +o = s:option(TextValue, _n("custom_config"), translate("Custom Config")) +o.rows = 10 +o.wrap = "off" +o:depends({ [_n("custom")] = true }) +o.validate = function(self, value, t) + if value and api.jsonc.parse(value) then + return value + else + return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!") + end +end +o.custom_cfgvalue = function(self, section, value) + local config_str = m:get(section, "config_str") + if config_str then + return api.base64Decode(config_str) + end +end +o.custom_write = function(self, section, value) + m:set(section, "config_str", api.base64Encode(value) or "") +end + +o = s:option(Flag, _n("udp_forward"), translate("UDP Forward")) +o.default = "1" +o.rmempty = false + +o = s:option(Flag, _n("log"), translate("Log")) +o.default = "1" +o.rmempty = false + +api.luci_types(arg[1], m, s, type_name, option_prefix) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua new file mode 100644 index 00000000..c50d5ca9 --- /dev/null +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua @@ -0,0 +1,57 @@ +api = require "luci.passwall2.api" +appname = api.appname +fs = api.fs + +m = Map("passwall2_server", translate("Server Config")) +m.redirect = api.url("server") +api.set_apply_on_parse(m) + +if not arg[1] or not m:get(arg[1]) then + luci.http.redirect(m.redirect) +end + +local header = Template(appname .. "/server/config_header") +header.api = api +header.config = m.config +header.section = arg[1] +m:append(header) + +m:append(Template(appname .. "/cbi/nodes_listvalue_com")) + +s = m:section(NamedSection, arg[1], "user", "") +s.addremove = false +s.dynamic = false + +local types_dir = "/usr/lib/lua/luci/model/cbi/" .. appname .. "/server/type/" +s.val = m:get(arg[1]) or {} + +o = s:option(Flag, "enable", translate("Enable")) +o.default = "1" +o.rmempty = false + +o = s:option(Value, "remarks", translate("Remarks")) +o.default = translate("Remarks") +o.rmempty = false + +o = s:option(ListValue, "type", translate("Type")) + +local type_table = {} +for filename in fs.dir(types_dir) do + table.insert(type_table, filename) +end +table.sort(type_table, function(a, b) + return a < b +end) + +for index, value in ipairs(type_table) do + local p_func = loadfile(types_dir .. value) + setfenv(p_func, getfenv(1))(m, s) +end + +local footer = Template(appname .. "/server/config_footer") +footer.api = api +footer.config = m.config +footer.section = arg[1] +m:append(footer) + +return m diff --git a/luci-app-passwall2/luasrc/passwall2/api.lua b/luci-app-passwall2/luasrc/passwall2/api.lua new file mode 100644 index 00000000..e2510f51 --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/api.lua @@ -0,0 +1,1714 @@ +module("luci.passwall2.api", package.seeall) +appname = "passwall2" +local com = require "luci.passwall2.com" +nixio = require "nixio" +fs = require "nixio.fs" +sys = require "luci.sys" +uci = require"luci.model.uci".cursor() +util = require "luci.util" +datatypes = require "luci.cbi.datatypes" +jsonc = require "luci.jsonc" +i18n = require "luci.i18n" + +curl_args = { "-skfL", "--connect-timeout 3", "--retry 3" } +command_timeout = 300 +OPENWRT_ARCH = nil +DISTRIB_ARCH = nil + +LOG_FILE = "/tmp/log/passwall2.log" +CACHE_PATH = "/tmp/etc/passwall2_tmp" +TMP_PATH = "/tmp/etc/" .. appname +TMP_IFACE_PATH = TMP_PATH .. "/iface" + +local lang = uci:get("luci", "main", "lang") or "auto" +if lang == "auto" then + local auto_lang = uci:get(appname, "@global[0]", "auto_lang") + if auto_lang then lang = auto_lang end +end +if lang == "auto" then + lang = i18n.default +end +i18n.setlanguage(lang) + +function echolog(...) + local result = table.concat({...}, " ") + local f, err = io.open(LOG_FILE, "a") + if f and err == nil then + f:write(result .. "\n") + f:close() + end +end + +function echolog_date(...) + local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + echolog(result) +end + +function log(level, ...) + local indent = "" + if level >= 1 then + for i = 1, level, 1 do + indent = indent .. " " + end + echolog_date(indent .. "- " .. table.concat({...}, " ")) + else + echolog_date(table.concat({...}, " ")) + end +end + +function is_old_uci() + return sys.call("grep -E 'require[ \t]*\"uci\"' /usr/lib/lua/luci/model/uci.lua >/dev/null 2>&1") == 0 +end + +function uci_save(cursor, config, commit, apply) + if is_old_uci() then + cursor:save(config) + if commit then + cursor:commit(config) + if apply then + sys.call("/etc/init.d/" .. config .. " reload > /dev/null 2>&1 &") + end + end + else + commit = true + if commit then + if apply then + cursor:commit(config) + else + sh_uci_commit(config) + end + end + end +end + +function sh_uci_get(config, section, option) + local _, val = exec_call(string.format("uci -q get %s.%s.%s", config, section, option)) + return val +end + +function sh_uci_set(config, section, option, val, commit) + exec_call(string.format("uci -q set %s.%s.%s=\"%s\"", config, section, option, val)) + if commit then sh_uci_commit(config) end +end + +function sh_uci_del(config, section, option, commit) + exec_call(string.format("uci -q delete %s.%s.%s", config, section, option)) + if commit then sh_uci_commit(config) end +end + +function sh_uci_add_list(config, section, option, val, commit) + exec_call(string.format("uci -q del_list %s.%s.%s=\"%s\"", config, section, option, val)) + exec_call(string.format("uci -q add_list %s.%s.%s=\"%s\"", config, section, option, val)) + if commit then sh_uci_commit(config) end +end + +function sh_uci_commit(config) + exec_call(string.format("uci -q commit %s", config)) +end + +function set_cache_var(key, val) + sys.call(string.format('. /usr/share/passwall2/utils.sh ; set_cache_var %s "%s"', key, val)) +end + +function get_cache_var(key) + local val = sys.exec(string.format('. /usr/share/passwall2/utils.sh ; echo -n $(get_cache_var %s)', key)) + if val == "" then val = nil end + return val +end + +function get_new_port() + local cmd_format = ". /usr/share/passwall2/utils.sh ; echo -n $(get_new_port %s tcp,udp)" + return tonumber(sys.exec(string.format(cmd_format, "auto"))) +end + +function exec_call(cmd) + math.randomseed(os.time()) + local tag = "\x01__RC__" .. tostring(math.random(100000, 999999)) .. "\x01" + local f = io.popen('(' .. cmd .. '); printf "\\n' .. tag .. '%d" "$?"') + local out = f:read("*a") or "" + f:close() + local rc = out:match(tag .. "(%d+)%s*$") + if not rc then + return 255, trim(out) + end + out = out:gsub("\n?" .. tag .. "%d+%s*$", "") + return tonumber(rc), trim(out) +end + +function base64Decode(text) + if not text then return '' end + local encoded = text:gsub("%z", ""):gsub("%c", ""):gsub("_", "/"):gsub("-", "+") + local mod4 = #encoded % 4 + encoded = encoded .. string.sub('====', mod4 + 1) + local result = nixio.bin.b64decode(encoded) + if result then + return result:gsub("%z", "") + else + return text + end +end + +function base64Encode(text) + if not text then return nil end + return nixio.bin.b64encode(text) +end + +function UrlEncode(szText) + return szText:gsub("([^%w%-_%.%~])", function(c) + return string.format("%%%02X", string.byte(c)) + end) +end + +function UrlDecode(szText) + return szText and szText:gsub("%+", " "):gsub("%%(%x%x)", function(h) + return string.char(tonumber(h, 16)) + end) or nil +end + +-- Extract the domain name and port from the URL (no IP address). +function get_domain_port_from_url(url) + local scheme, domain, port = string.match(url, "^(https?)://([%w%.%-]+):?(%d*)") + if not domain then + scheme, domain, port = string.match(url, "^(https?)://(%b[])([^:/]*)/?") + end + if not domain then return nil, nil end + if domain:sub(1, 1) == "[" then domain = domain:sub(2, -2) end + port = port ~= "" and tonumber(port) or (scheme == "https" and 443 or 80) + if datatypes.ipaddr(domain) or datatypes.ip6addr(domain) then return nil, nil end + return domain, port +end + +-- Domain resolution +function domainToIPv4(domain, dns) + local Dns = dns or "223.5.5.5" + local IPs = luci.sys.exec('nslookup %s %s | awk \'/^Name:/{getline; if ($1 == "Address:") print $2}\'' % { domain, Dns }) + for IP in string.gmatch(IPs, "%S+") do + if datatypes.ipaddr(IP) and not datatypes.ip6addr(IP) then return IP end + end + return nil +end + +function curl_base(url, file, args) + if not args then args = {} end + if file then + args[#args + 1] = "-o " .. file + end + local cmd = string.format('curl %s "%s"', table_join(args), url) + return exec_call(cmd) +end + +function curl_proxy(url, file, args) + -- Use the proxy + local socks_server = get_cache_var("GLOBAL_SOCKS_server") + if socks_server and socks_server ~= "" then + if not args then args = {} end + local tmp_args = clone(args) + tmp_args[#tmp_args + 1] = "-x socks5h://" .. socks_server + return curl_base(url, file, tmp_args) + end + return nil, nil +end + +function curl_logic(url, file, args) + local return_code, result = curl_proxy(url, file, args) + if not return_code or return_code ~= 0 then + return_code, result = curl_base(url, file, args) + end + return return_code, result +end + +function curl_direct(url, file, args) + -- Direct access + if not args then args = {} end + local tmp_args = clone(args) + local domain, port = get_domain_port_from_url(url) + if domain then + local ip = domainToIPv4(domain) + if ip then + tmp_args[#tmp_args + 1] = "--resolve " .. domain .. ":" .. port .. ":" .. ip + end + end + return curl_base(url, file, tmp_args) +end + +function curl_auto(url, file, args) + local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1" + if localhost_proxy == "1" then + return curl_base(url, file, args) + else + local return_code, result = curl_proxy(url, file, args) + if not return_code or return_code ~= 0 then + return_code, result = curl_direct(url, file, args) + end + return return_code, result + end +end + +function url(...) + local url = string.format("admin/services/%s", appname) + local args = { ... } + for i, v in pairs(args) do + if v ~= "" then + url = url .. "/" .. v + end + end + return require "luci.dispatcher".build_url(url) +end + +function trim(s) + if type(s) ~= "string" then return "" end + local i, j = 1, #s + while i <= j and s:byte(i) <= 32 do i = i + 1 end + while j >= i and s:byte(j) <= 32 do j = j - 1 end + if i > j then return "" end + return s:sub(i, j) +end + +function split(full, sep) + if full then + full = full:gsub("%z", "") -- This is not very clear; sometimes it ends with a `\0`. + local off, result = 1, {} + while true do + local nStart, nEnd = full:find(sep, off) + if not nEnd then + local res = string.sub(full, off, string.len(full)) + if #res > 0 then -- Filter out `\0` + table.insert(result, res) + end + break + else + table.insert(result, string.sub(full, off, nStart - 1)) + off = nEnd + 1 + end + end + return result + end + return {} +end + +function is_exist(table, value) + for index, k in ipairs(table) do + if k == value then + return true + end + end + return false +end + +function repeat_exist(table, value) + local count = 0 + for index, k in ipairs(table) do + if k:find("-") and k == value then + count = count + 1 + end + end + if count > 1 then + return true + end + return false +end + +function remove(...) + for index, value in ipairs({...}) do + if value and #value > 0 and value ~= "/" then + sys.call(string.format("rm -rf %s", value)) + end + end +end + +function is_install(package) + if package and #package > 0 then + local file_path = "/usr/lib/opkg/info" + local file_ext = ".control" + local has = sys.call("[ -d " .. file_path .. " ]") + if has ~= 0 then + file_path = "/lib/apk/packages" + file_ext = ".list" + end + return sys.call(string.format('[ -s "%s/%s%s" ]', file_path, package, file_ext)) == 0 + end + return false +end + +function get_args(arg) + local var = {} + for i, arg_k in pairs(arg) do + if i > 0 then + local v = arg[i + 1] + if v then + if repeat_exist(arg, v) == false then + var[arg_k] = v + end + end + end + end + return var +end + +function get_function_args(arg) + local var = nil + if arg and #arg > 1 then + local param = {} + for i = 2, #arg do + param[#param + 1] = arg[i] + end + var = get_args(param) + end + return var +end + +function strToTable(str) + if str == nil or type(str) ~= "string" then + return {} + end + + return loadstring("return " .. str)() +end + +function is_normal_node(e) + if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then + return false + end + return true +end + +function is_special_node(e) + return is_normal_node(e) == false +end + +function is_ip(val) + val = trim(val):lower() + local str = val:match("%[(.-)%]") or val + return datatypes.ipaddr(str) or false +end + +function is_ipv6(val) + val = trim(val):lower() + local str = val:match("%[(.-)%]") or val + return datatypes.ip6addr(str) or false +end + +function is_ipv6addrport(val) + local address, port = val:match("%[(.-)%]:([0-9]+)$") + if address and datatypes.ip6addr(address) and datatypes.port(port) then + return true + end + return false +end + +function get_ipv6_only(val) + local result = "" + local inner = val:match("%[(.-)%]") or val + if datatypes.ip6addr(inner) then + result = inner + end + return result +end + +function get_ipv6_full(val) + local result = "" + if is_ipv6(val) then + result = val + if not val:match("%[.-%]") then + result = "[" .. result .. "]" + end + end + return result +end + +function get_ip_type(val) + if is_ipv6(val) then + return "6" + elseif datatypes.ip4addr(val) then + return "4" + end + return "" +end + +function is_mac(val) + return datatypes.macaddr(val) +end + +function ip_or_mac(val) + if val then + if get_ip_type(val) == "4" then + return "ip" + end + if is_mac(val) then + return "mac" + end + end + return "" +end + +function iprange(val) + if val then + local ipStart, ipEnd = val:match("^([^/]+)-([^/]+)$") + if (ipStart and datatypes.ip4addr(ipStart)) and (ipEnd and datatypes.ip4addr(ipEnd)) then + return true + end + end + return false +end + +function get_domain_from_url(url) + local domain = string.match(url, "//([^/]+)") + if domain then + return domain + end + return url +end + +function get_node_name(node_id) + local e + if type(node_id) == "table" then + e = node_id + else + e = uci:get_all(appname, node_id) + end + if e then + if e.type and e.remarks then + if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then + local type_name = e.type + if e.type == "sing-box" then type_name = "Sing-Box" end + local remark = "%s:[%s] " % {type_name .. " " .. i18n.translatef(e.protocol), e.remarks} + return remark + end + end + end + return "" +end + +function get_valid_nodes() + local show_node_info = uci_get_type("global_other", "show_node_info") or "0" + local nodes = {} + local default_nodes = {} + local other_nodes = {} + uci:foreach(appname, "nodes", function(e) + e.id = e[".name"] + if e.type and e.remarks then + local type_name = e.type + if e.type == "sing-box" then type_name = "Sing-Box" end + if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then + e["remark"] = trim("%s:[%s]" % {type_name .. " " .. i18n.translatef(e.protocol), e.remarks}) + e["node_type"] = "special" + if not e.group or e.group == "" then + default_nodes[#default_nodes + 1] = e + else + other_nodes[#other_nodes + 1] = e + end + end + local port = e.port or e.hysteria_hop or e.hysteria2_hop + local is_realm = (e.type == "Hysteria2" or e.protocol == 'hysteria2') and e.hysteria2_realms or nil + if (port and e.address) or is_realm then + local address = e.address + if is_ip(address) or datatypes.hostname(address) or is_realm then + if (e.type == "sing-box" or e.type == "Xray") and e.protocol then + local protocol = e.protocol + if protocol == "vmess" then + protocol = "VMess" + elseif protocol == "vless" then + protocol = "VLESS" + elseif protocol == "shadowsocks" then + protocol = "SS" + elseif protocol == "shadowsocksr" then + protocol = "SSR" + elseif protocol == "wireguard" then + protocol = "WG" + elseif protocol == "hysteria" then + protocol = "HY" + elseif protocol == "hysteria2" then + protocol = "HY2" + elseif protocol == "anytls" then + protocol = "AnyTLS" + elseif protocol == "ssh" then + protocol = "SSH" + else + protocol = protocol:gsub("^%l",string.upper) + end + type_name = type_name .. " " .. protocol + end + if is_ipv6(address) then address = get_ipv6_full(address) end + type_name = is_realm and type_name .. " Realm" or type_name + e["remark"] = trim("%s:[%s]" % {type_name, e.remarks}) + if show_node_info == "1" then + port = (port or ""):gsub(":", "-") + if not is_realm then + e["remark"] = trim("%s:[%s] %s:%s" % {type_name, e.remarks, address, port}) + end + end + e.node_type = "normal" + if not e.group or e.group == "" then + default_nodes[#default_nodes + 1] = e + else + other_nodes[#other_nodes + 1] = e + end + end + end + end + end) + for i = 1, #default_nodes do nodes[#nodes + 1] = default_nodes[i] end + for i = 1, #other_nodes do nodes[#nodes + 1] = other_nodes[i] end + return nodes +end + +function get_node_list() + local node_list = { + socks_list = {}, + normal_list = {}, + } + uci:foreach(appname, "socks", function(s) + if s.enabled == "1" and s.node then + node_list.socks_list[#node_list.socks_list + 1] = { + id = "Socks_" .. s[".name"], + remark = i18n.translate("Socks Config") .. " [" .. s.port .. i18n.translate("Port") .. "]", + group = "Socks" + } + end + end) + for k, e in ipairs(get_valid_nodes()) do + if e.node_type == "normal" then + node_list.normal_list[#node_list.normal_list + 1] = { + id = e[".name"], + remark = e["remark"], + type = e["type"], + chain_proxy = e["chain_proxy"], + group = e["group"] + } + end + if e.protocol and e.protocol:find("^_") then + local proto = e.protocol:sub(2) + if not node_list[proto .. "_list"] then + node_list[proto .. "_list"] = {} + end + node_list[proto .. "_list"][#node_list[proto .. "_list"] + 1] = { + id = e[".name"], + remark = e["remark"], + group = e["group"], + o = e, + } + end + end + return node_list +end + +function get_node_remarks(n) + local remarks = "" + if n then + local type_name = n.type + if n.type == "sing-box" then type_name = "Sing-Box" end + if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface" or n.protocol == "_urltest") then + remarks = trim("%s:[%s]" % {type_name .. " " .. i18n.translatef(n.protocol), n.remarks}) + else + if (n.type == "sing-box" or n.type == "Xray") and n.protocol then + local protocol = n.protocol + if protocol == "vmess" then + protocol = "VMess" + elseif protocol == "vless" then + protocol = "VLESS" + elseif protocol == "shadowsocks" then + protocol = "SS" + elseif protocol == "shadowsocksr" then + protocol = "SSR" + elseif protocol == "wireguard" then + protocol = "WG" + elseif protocol == "hysteria" then + protocol = "HY" + elseif protocol == "hysteria2" then + protocol = "HY2" + elseif protocol == "anytls" then + protocol = "AnyTLS" + elseif protocol == "ssh" then + protocol = "SSH" + else + protocol = protocol:gsub("^%l",string.upper) + end + type_name = type_name .. " " .. protocol + end + if (n.type == "Hysteria2" or n.protocol == 'hysteria2') and n.hysteria2_realms then + type_name = type_name .. " Realm" + end + remarks = trim("%s:[%s]" % {type_name, n.remarks}) + end + end + return remarks +end + +function get_full_node_remarks(n) + local remarks = get_node_remarks(n) + if #remarks > 0 then + local port = n.port or n.hysteria_hop or n.hysteria2_hop + if n.address and port then + port = port:gsub(":", "-") + remarks = remarks .. " " .. n.address .. ":" .. port + end + end + return remarks +end + +function gen_uuid(format) + local uuid = sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)") + if format == nil then + uuid = string.gsub(uuid, "-", "") + end + return uuid +end + +function gen_short_uuid() + return sys.exec("echo -n $(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8)") +end + +function uci_get_type(type, config, default) + local value = uci:get_first(appname, type, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. ".@" .. type .."[0]." .. config .. ")") + if (value == nil or value == "") and (default and default ~= "") then + value = default + end + return value +end + +function uci_get_type_id(id, config, default) + local value = uci:get(appname, id, config, default) or sys.exec("echo -n $(uci -q get " .. appname .. "." .. id .. "." .. config .. ")") + if (value == nil or value == "") and (default and default ~= "") then + value = default + end + return value +end + +function chmod_755(file) + if file and file ~= "" then + if not fs.access(file, "rwx", "rx", "rx") then + fs.chmod(file, 755) + end + end +end + +function get_customed_path(e) + return uci_get_type("global_app", e .. "_file") +end + +function finded_com(e) + local bin = get_app_path(e) + if not bin then return end + local s = luci.sys.exec('echo -n $(type -t -p "%s" | head -n1)' % { bin }) + if s == "" then + s = nil + end + return s +end + +function finded(e) + return luci.sys.exec('echo -n $(type -t -p "/bin/%s" -p "/usr/bin/%s" "%s" | head -n1)' % {e, e, e}) +end + +function is_finded(e) + return finded(e) ~= "" and true or false +end + +function clone(org) + local function copy(org, res) + for k,v in pairs(org) do + if type(v) ~= "table" then + res[k] = v; + else + res[k] = {}; + copy(v, res[k]) + end + end + end + + local res = {} + copy(org, res) + return res +end + +local function get_bin_version_cache(file, cmd) + sys.call("mkdir -p /tmp/etc/passwall2_tmp") + if fs.access(file) then + chmod_755(file) + local md5 = sys.exec("echo -n $(md5sum " .. file .. " | awk '{print $1}')") + if fs.access("/tmp/etc/passwall2_tmp/" .. md5) then + return sys.exec("echo -n $(cat /tmp/etc/passwall2_tmp/%s)" % md5) + else + local version = sys.exec(string.format("echo -n $(%s %s)", file, cmd)) + if version and version ~= "" then + sys.call("echo '" .. version .. "' > " .. "/tmp/etc/passwall2_tmp/" .. md5) + return version + end + end + end + return "" +end + +function get_app_path(app_name) + if com[app_name] then + local def_path = com[app_name].default_path + local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file") + path = path and (#path>0 and path or def_path) or def_path + return path + end +end + +function get_app_version(app_name, file) + if file == nil then file = get_app_path(app_name) end + return get_bin_version_cache(file, com[app_name].cmd_version) +end + +function is_file(path) + if path and #path > 1 then + if sys.exec('[ -f "%s" ] && echo -n 1' % path) == "1" then + return true + end + end + return nil +end + +function is_dir(path) + if path and #path > 1 then + if sys.exec('[ -d "%s" ] && echo -n 1' % path) == "1" then + return true + end + end + return nil +end + +function get_final_dir(path) + if is_dir(path) then + return path + else + return get_final_dir(fs.dirname(path)) + end +end + +function get_free_space(dir) + if dir == nil then dir = "/" end + if sys.call("df -k " .. dir .. " >/dev/null 2>&1") == 0 then + return tonumber(sys.exec("echo -n $(df -k " .. dir .. " | awk 'NR>1' | awk '{print $4}')")) + end + return 0 +end + +function get_file_space(file) + if file == nil then return 0 end + if fs.access(file) then + return tonumber(sys.exec("echo -n $(du -k " .. file .. " | awk '{print $1}')")) + end + return 0 +end + +function _unpack(t, i) + i = i or 1 + if t[i] ~= nil then return t[i], _unpack(t, i + 1) end +end + +function table_join(t, s) + if not s then + s = " " + end + local str = "" + for index, value in ipairs(t) do + str = str .. t[index] .. (index == #t and "" or s) + end + return str +end + +function exec(cmd, args, writer, timeout) + local os = require "os" + local nixio = require "nixio" + + local fdi, fdo = nixio.pipe() + local pid = nixio.fork() + + if pid > 0 then + fdo:close() + + if writer or timeout then + local starttime = os.time() + while true do + if timeout and os.difftime(os.time(), starttime) >= timeout then + nixio.kill(pid, nixio.const.SIGTERM) + return 1 + end + + if writer then + local buffer = fdi:read(2048) + if buffer and #buffer > 0 then + writer(buffer) + end + end + + local wpid, stat, code = nixio.waitpid(pid, "nohang") + + if wpid and stat == "exited" then return code end + + if not writer and timeout then nixio.nanosleep(1) end + end + else + local wpid, stat, code = nixio.waitpid(pid) + return wpid and stat == "exited" and code + end + elseif pid == 0 then + nixio.dup(fdo, nixio.stdout) + fdi:close() + fdo:close() + nixio.exece(cmd, args, nil) + nixio.stdout:close() + os.exit(1) + end +end + +function parseURL(url_str) + local res = {} + + -- 1. Get Scheme (http://) + local rest = url_str + local scheme, s_rest = url_str:match("^([%w%.%-%+]+)://(.+)$") + if scheme then + res.protocol = scheme + rest = s_rest + end + + -- 2. Get Authority (user:pass@host:port) and Path + local authority, path = rest:match("^([^/]+)(.*)$") + if path and path ~= "" then + res.pathname = path:match("^([^?#]*)") + end + + -- 3. Process Auth info (user:pass@) + -- Use [^@]+ to match the content before the leftmost @. + local user_info, host_port = authority:match("^([^@]+)@(.+)$") + if user_info then + local u, p = user_info:match("^([^:]+):?(.*)$") + res.username = u or "" + res.password = p or "" + else + host_port = authority + end + + -- 4. Handles Host and Port (IPv6 compatible) + -- First look for square brackets [], if not found, then look for regular colons. + local ipv6_host, ipv6_port = host_port:match("^%[(.+)%]:(%d+)$") + if ipv6_host then + res.hostname = ipv6_host + res.port = tonumber(ipv6_port) + else + -- Check if it's an IPv6 address with parentheses but no port number: [2001:db8::1] + local pure_ipv6 = host_port:match("^%[(.+)%]$") + if pure_ipv6 then + res.hostname = pure_ipv6 + else + -- IPv4 or hostname match + local h, p = host_port:match("^([^:]+):(%d+)$") + if h and p then + res.hostname = h + res.port = tonumber(p) + else + res.hostname = host_port + end + end + end + + res.host = host_port + return res +end + +function compare_versions(ver1, comp, ver2) + local table = table + + if not ver1 then ver1 = "" end + if not ver2 then ver2 = "" end + + local av1 = util.split(ver1, "[%.%-]", nil, true) + local av2 = util.split(ver2, "[%.%-]", nil, true) + + local max = table.getn(av1) + local n2 = table.getn(av2) + if (max < n2) then max = n2 end + + for i = 1, max, 1 do + local s1 = tonumber(av1[i] or 0) or 0 + local s2 = tonumber(av2[i] or 0) or 0 + + if comp == "~=" and (s1 ~= s2) then return true end + if (comp == "<" or comp == "<=") and (s1 < s2) then return true end + if (comp == ">" or comp == ">=") and (s1 > s2) then return true end + if (s1 ~= s2) then return false end + end + + return not (comp == "<" or comp == ">") +end + +local function auto_get_arch() + local arch = nixio.uname().machine or "" + if not OPENWRT_ARCH and fs.access("/usr/lib/os-release") then + OPENWRT_ARCH = sys.exec("echo -n $(grep 'OPENWRT_ARCH' /usr/lib/os-release | awk -F '[\\042\\047]' '{print $2}')") + if OPENWRT_ARCH == "" then OPENWRT_ARCH = nil end + end + if not DISTRIB_ARCH and fs.access("/etc/openwrt_release") then + DISTRIB_ARCH = sys.exec("echo -n $(grep 'DISTRIB_ARCH' /etc/openwrt_release | awk -F '[\\042\\047]' '{print $2}')") + if DISTRIB_ARCH == "" then DISTRIB_ARCH = nil end + end + + if arch:match("^i[%d]86$") then + arch = "x86" + elseif arch:match("armv5") then -- armv5l + arch = "armv5" + elseif arch:match("armv6") then + arch = "armv6" + elseif arch:match("armv7") then -- armv7l + arch = "armv7" + end + + if OPENWRT_ARCH or DISTRIB_ARCH then + if arch == "mips" then + if OPENWRT_ARCH and OPENWRT_ARCH:match("mipsel") == "mipsel" + or DISTRIB_ARCH and DISTRIB_ARCH:match("mipsel") == "mipsel" then + arch = "mipsel" + end + elseif arch == "armv7" then + if OPENWRT_ARCH and not OPENWRT_ARCH:match("vfp") and not OPENWRT_ARCH:match("neon") + or DISTRIB_ARCH and not DISTRIB_ARCH:match("vfp") and not DISTRIB_ARCH:match("neon") then + arch = "armv5" + end + end + end + + return trim(arch) +end + +local default_file_tree = { + x86_64 = "amd64", + x86 = "386", + aarch64 = "arm64", + rockchip = "arm64", + mips = "mips", + mips64 = "mips64", + mipsel = "mipsel", + mips64el = "mips64el", + armv5 = "arm.*5", + armv6 = "arm.*6[^4]*", + armv7 = "arm.*7", + armv8 = "arm64", + riscv64 = "riscv64" +} + +function get_api_json(url) + local jsonc = require "luci.jsonc" + local return_code, content = curl_logic(url, nil, curl_args) + if return_code ~= 0 or content == "" then return {} end + return jsonc.parse(content) or {} +end + +local function check_path(app_name) + local path = get_app_path(app_name) or "" + if path == "" then + return { + code = 1, + error = i18n.translatef("You did not fill in the %s path. Please save and apply then update manually.", app_name) + } + end + return { + code = 0, + app_path = path + } +end + +function to_check(arch, app_name) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + if not arch or arch == "" then arch = auto_get_arch() end + + local file_tree = com[app_name].file_tree[arch] or default_file_tree[arch] or "" + + if file_tree == "" then + return { + code = 1, + error = i18n.translate("Can't determine ARCH, or ARCH not supported.") + } + end + + local local_version = get_app_version(app_name) + local match_file_name = string.format(com[app_name].match_fmt_str, file_tree) + local json = get_api_json(com[app_name]:get_url()) + + if #json > 0 then + json = json[1] + end + + if json.tag_name == nil then + return { + code = 1, + error = i18n.translate("Get remote version info failed.") + } + end + + local remote_version = json.tag_name + if com[app_name].remote_version_str_replace then + remote_version = remote_version:gsub(com[app_name].remote_version_str_replace, "") + end + local has_update = compare_versions(local_version:match("[^v]+"), "<", remote_version:match("[^v]+")) +--[[ + if not has_update then + return { + code = 0, + local_version = local_version, + remote_version = remote_version + } + end +]] + local asset = {} + for _, v in ipairs(json.assets) do + if v.name and v.name:match(match_file_name) then + asset = v + break + end + end + if not asset.browser_download_url then + return { + code = 1, + local_version = local_version, + remote_version = remote_version, + html_url = json.html_url, + data = asset, + error = i18n.translate("New version found, but failed to get new version download url.") + } + end + + return { + code = 0, + has_update = has_update, + local_version = local_version, + remote_version = remote_version, + html_url = json.html_url, + data = asset + } +end + +function to_download(app_name, url, size) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + if not url or url == "" then + return {code = 1, error = i18n.translate("Download url is required.")} + end + + sys.call("/bin/rm -f /tmp/".. app_name .."_download.*") + + local tmp_file = trim(util.exec("mktemp -u -t ".. app_name .."_download.XXXXXX")) + + if size then + local kb1 = get_free_space("/tmp") + if tonumber(size) > tonumber(kb1) then + return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")} + end + end + + local _curl_args = clone(curl_args) + table.insert(_curl_args, "--speed-limit 51200 --speed-time 15 --max-time 300") + + local return_code, result = curl_logic(url, tmp_file, _curl_args) + result = return_code == 0 + + if not result then + exec("/bin/rm", {"-f", tmp_file}) + return { + code = 1, + error = i18n.translatef("File download failed or timed out: %s", url) + } + end + + return {code = 0, file = tmp_file, zip = com[app_name].zipped } +end + +function to_extract(app_name, file, subfix) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + if not file or file == "" or not fs.access(file) then + return {code = 1, error = i18n.translate("File path required.")} + end + + local tools_name + if com[app_name].zipped then + if not com[app_name].zipped_suffix or com[app_name].zipped_suffix == "zip" then + tools_name = "unzip" + end + if com[app_name].zipped_suffix and com[app_name].zipped_suffix == "tar.gz" then + tools_name = "tar" + end + if tools_name then + if sys.exec("echo -n $(command -v %s)" % { tools_name }) == "" then + exec("/bin/rm", {"-f", file}) + return { + code = 1, + error = i18n.translate("Not installed %s, Can't unzip!" % { tools_name }) + } + end + end + end + + sys.call("/bin/rm -rf /tmp/".. app_name .."_extract.*") + + local new_file_size = get_file_space(file) + local tmp_free_size = get_free_space("/tmp") + if tmp_free_size <= 0 or tmp_free_size <= new_file_size then + return {code = 1, error = i18n.translatef("%s not enough space.", "/tmp")} + end + + local tmp_dir = trim(util.exec("mktemp -d -t ".. app_name .."_extract.XXXXXX")) + + local output = {} + + if tools_name then + if tools_name == "unzip" then + local bin = sys.exec("echo -n $(command -v unzip)") + exec(bin, {"-o", file, app_name, "-d", tmp_dir}, function(chunk) output[#output + 1] = chunk end) + elseif tools_name == "tar" then + local bin = sys.exec("echo -n $(command -v tar)") + if com[app_name].zipped_suffix == "tar.gz" then + exec(bin, {"-zxf", file, "-C", tmp_dir}, function(chunk) output[#output + 1] = chunk end) + sys.call("/bin/mv -f " .. tmp_dir .. "/*/" .. com[app_name].name:lower() .. " " .. tmp_dir) + end + end + end + + local files = util.split(table.concat(output)) + + exec("/bin/rm", {"-f", file}) + + return {code = 0, file = tmp_dir} +end + +function to_move(app_name,file) + local result = check_path(app_name) + if result.code ~= 0 then + return result + end + + local app_path = result.app_path + local bin_path = file + local cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_download.*" + if fs.stat(file, "type") == "dir" then + bin_path = file .. "/" .. com[app_name].name:lower() + cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_extract.*" + end + + if not file or file == "" then + sys.call(cmd_rm_tmp) + return {code = 1, error = i18n.translate("Client file is required.")} + end + + local new_version = get_app_version(app_name, bin_path) + if new_version == "" then + sys.call(cmd_rm_tmp) + return { + code = 1, + error = i18n.translate("The client file is not suitable for current device.")..app_name.."__"..bin_path + } + end + + local flag = sys.call('busybox pgrep -af "passwall2/.*'.. app_name ..'" >/dev/null') + if flag == 0 then + sys.call("/etc/init.d/passwall2 stop") + end + + local old_app_size = 0 + if fs.access(app_path) then + old_app_size = get_file_space(app_path) + end + local new_app_size = get_file_space(bin_path) + local final_dir = get_final_dir(app_path) + local final_dir_free_size = get_free_space(final_dir) + if final_dir_free_size > 0 then + final_dir_free_size = final_dir_free_size + old_app_size + if new_app_size > final_dir_free_size then + sys.call(cmd_rm_tmp) + return {code = 1, error = i18n.translatef("%s not enough space.", final_dir)} + end + end + + result = exec("/bin/mv", { "-f", bin_path, app_path }, nil, command_timeout) == 0 + + sys.call(cmd_rm_tmp) + if flag == 0 then + sys.call("/etc/init.d/passwall2 restart >/dev/null 2>&1 &") + end + + if not result or not fs.access(app_path) then + return { + code = 1, + error = i18n.translatef("Can't move new file to path: %s", app_path) + } + end + + return {code = 0} +end + +function get_version() + local version = sys.exec("opkg list-installed luci-app-passwall2 2>/dev/null | awk '{print $3}'") + if not version or #version == 0 then + version = sys.exec("apk list luci-app-passwall2 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-") + end + return (version or ""):gsub("\n", ""):match("^([^-]+)") +end + +function to_check_self() + local url = "https://raw.githubusercontent.com/Openwrt-Passwall/openwrt-passwall2/main/luci-app-passwall2/Makefile" + local tmp_file = "/tmp/passwall2_makefile" + local return_code, result = curl_auto(url, tmp_file, curl_args) + result = return_code == 0 + if not result then + exec("/bin/rm", {"-f", tmp_file}) + return { + code = 1, + error = i18n.translatef("Failed") + } + end + local local_version = get_version() + local remote_version = sys.exec("echo -n $(grep '^PKG_VERSION' /tmp/passwall2_makefile | head -n 1 | awk -F '=' '{print $2}')") + exec("/bin/rm", {"-f", tmp_file}) + + local has_update = compare_versions(local_version, "<", remote_version) + if not has_update then + return { + code = 0, + local_version = local_version, + remote_version = remote_version + } + end + return { + code = 1, + has_update = true, + local_version = local_version, + remote_version = remote_version, + error = i18n.translatef("The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install.", remote_version) + } +end + +function cacheFileCompareToLogic(file, str) + local result = nil + if file and str then + local file_str = "" + if fs.access(file) then + file_str = sys.exec("cat " .. file) + end + + if file_str ~= str then + sys.call("rm -f " .. file) + result = false + else + result = true + end + + local f_out = io.open(file, "w") + if f_out then + f_out:write(str) + f_out:close() + end + end + return result +end + +function is_js_luci() + return sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 +end + +function set_apply_on_parse(map) + if not map then + return + end + local lang = uci:get("luci", "main", "lang") or "auto" + if lang == "auto" then + local http = require "luci.http" + local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or "" + for lpat in aclang:gmatch("[%w-]+") do + lpat = lpat and lpat:gsub("-", "_") + if uci:get("luci", "languages", lpat) then + lang = lpat + break + end + lpat = lpat and lpat:lower() + if uci:get("luci", "languages", lpat) then + lang = lpat + break + end + end + if lang ~= "auto" then + sh_uci_set(appname, "@global[0]", "auto_lang", lang, true) + end + end + if is_js_luci() == true then + local hide_popup_box = nil + if hide_popup_box == true then + map.apply_on_parse = false + map.on_after_apply = function(self) + if self.redirect then + os.execute("sleep 1") + luci.http.redirect(self.redirect) + end + end + else + apply_redirect(map) + local old = map.on_after_save + map.on_after_save = function(self) + if old then old(self) end + map:set("@global[0]", "timestamp", os.time()) + end + local cbi = require "luci.cbi" + map:append(cbi.Template(appname .. "/cbi/optimize_cbi_ui")) + end + end +end + +function luci_types(id, m, s, type_name, option_prefix) + local fv_type + local field_type = s.fields["type"] + if field_type then + fv_type = field_type:formvalue(id) + end + local rewrite_option_table = {} + for key, value in pairs(s.fields) do + if key:find(option_prefix) == 1 then + if not s.fields[key].not_rewrite then + if s.fields[key].rewrite_option then + if not rewrite_option_table[s.fields[key].rewrite_option] then + rewrite_option_table[s.fields[key].rewrite_option] = 1 + else + rewrite_option_table[s.fields[key].rewrite_option] = rewrite_option_table[s.fields[key].rewrite_option] + 1 + end + end + + s.fields[key].cfgvalue = function(self, section) + -- Add a custom `custom_cfgvalue` attribute. If a custom `custom_cfgvalue` function exists, the custom `cfgvalue` logic will be used. + if self.custom_cfgvalue then + return self:custom_cfgvalue(section) + else + if self.rewrite_option then + return m:get(section, self.rewrite_option) + else + if self.option:find(option_prefix) == 1 then + return m:get(section, self.option:sub(1 + #option_prefix)) + end + end + end + end + s.fields[key].write = function(self, section, value) + if s.fields["type"]:formvalue(id) == type_name then + -- Add a custom `custom_write` attribute; if a custom `custom_write` function exists, then use the custom write logic. + if self.custom_write then + self:custom_write(section, value) + else + if self.rewrite_option then + m:set(section, self.rewrite_option, value) + else + if self.option:find(option_prefix) == 1 then + m:set(section, self.option:sub(1 + #option_prefix), value) + end + end + end + end + end + s.fields[key].remove = function(self, section) + if s.fields["type"]:formvalue(id) == type_name then + -- Add a custom `custom_remove` attribute; if a custom `custom_remove` function exists, use the custom remove logic. + if self.custom_remove then + self:custom_remove(section) + else + if self.rewrite_option and rewrite_option_table[self.rewrite_option] == 1 then + m:del(section, self.rewrite_option) + else + if self.option:find(option_prefix) == 1 then + m:del(section, self.option:sub(1 + #option_prefix)) + end + end + end + end + end + end + + local deps = s.fields[key].deps + if #deps > 0 then + for index, value in ipairs(deps) do + deps[index]["type"] = type_name + end + else + s.fields[key]:depends({ type = type_name }) + end + + if fv_type and fv_type ~= type_name then + s.fields[key].rmempty = true + end + end + end +end +function format_go_time(input) + input = input and trim(input) + local N = 0 + if input and input:match("^%d+$") then + N = tonumber(input) + elseif input and input ~= "" then + for value, unit in input:gmatch("(%d+)%s*([hms])") do + value = tonumber(value) + if unit == "h" then + N = N + value * 3600 + elseif unit == "m" then + N = N + value * 60 + elseif unit == "s" then + N = N + value + end + end + end + if N <= 0 then + return "0s" + end + local result = "" + local h = math.floor(N / 3600) + local m = math.floor(N % 3600 / 60) + local s = N % 60 + if h > 0 then result = result .. h .. "h" end + if m > 0 then result = result .. m .. "m" end + if s > 0 or result == "" then result = result .. s .. "s" end + return result +end + +function apply_redirect(m) + local tmp_uci_file = "/etc/config/" .. appname .. "_redirect" + if m.redirect and m.redirect ~= "" then + if fs.access(tmp_uci_file) then + local redirect + for line in io.lines(tmp_uci_file) do + redirect = line:match("option%s+url%s+['\"]([^'\"]+)['\"]") + if redirect and redirect ~= "" then break end + end + if redirect and redirect ~= "" then + sys.call("/bin/rm -f " .. tmp_uci_file) + luci.http.redirect(redirect) + end + else + fs.writefile(tmp_uci_file, "config redirect\n") + end + m.on_after_save = function(self) + local redirect = self.redirect + if redirect and redirect ~= "" then + uci:set(appname .. "_redirect", "@redirect[0]", "url", redirect) + end + end + else + sys.call("/bin/rm -f " .. tmp_uci_file) + end +end + +function match_node_rule(name, rule) + if not name then return false end + if not rule or rule == "" then return true end + -- split rule by && + local function split_and(expr) + local t = {} + for part in expr:gmatch("[^&]+") do + part = part:gsub("^%s+", ""):gsub("%s+$", "") + if part ~= "" then + table.insert(t, part) + end + end + return t + end + -- match single condition + local function match_cond(str, cond) + if cond == "" then + return true + end + -- exclude: !xxx + if cond:sub(1, 1) == "!" then + local k = cond:sub(2) + if k == "" then return true end + return not str:find(k, 1, true) + end + -- prefix: ^xxx + if cond:sub(1, 1) == "^" then + local k = cond:sub(2) + return str:sub(1, #k) == k + end + -- suffix: xxx$ + if cond:sub(-1) == "$" then + local k = cond:sub(1, -2) + return str:sub(-#k) == k + end + -- contains + return str:find(cond, 1, true) ~= nil + end + -- AND logic + for _, cond in ipairs(split_and(rule)) do + if not match_cond(name, cond) then + return false + end + end + return true +end + +function get_core(field, candidates) + local v = uci:get(appname, "@global_subscribe[0]", field) + if v and v ~= "" then + for _, c in ipairs(candidates) do + if c[2] == v and c[1] then + return v + end + end + end + for _, c in ipairs(candidates) do + if c[1] then return c[2] end + end + return nil +end + +function cleanEmptyTables(t) + if type(t) ~= "table" then return nil end + for k, v in pairs(t) do + if type(v) == "table" then + t[k] = cleanEmptyTables(v) + end + end + return next(t) and t or nil +end + +function get_dnsmasq_server_domain() + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + local dnsmasq_server_t = {} + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if v:find("/") then + local split1 = split(v, "/") + if #split1 > 2 then + local domain = split1[2] + local upstream_dns = split1[#split1] + local upstream_dns_server + local upstream_dns_port = "53" + local dns_split = split(upstream_dns, "#") + if #dns_split > 1 then + upstream_dns_server = dns_split[1] + upstream_dns_port = dns_split[#dns_split] + else + upstream_dns_server = upstream_dns + end + dnsmasq_server_t[domain] = { + dnsmasq_dns = upstream_dns, + server = upstream_dns_server, + port = tonumber(upstream_dns_port) + } + end + end + end + end + return dnsmasq_server_t +end + +function parse_realm_uri(uri) + if type(uri) ~= "string" then return nil end + -- realm://token@server/realm_id?query + local token, server_url, realm_id, query = trim(uri):match("^realm://([^@]+)@([^/]+)/([^?]*)%??(.*)$") + if not token or not server_url or not realm_id then return nil end + realm_id = realm_id:gsub("/+$", "") + local realm = { + token = token, + server_url = server_url, + realm_id = realm_id + } + -- è§£æž query 中的 stun= + if query and query ~= "" then + local stun_servers = {} + for key, value in query:gmatch("([^&=?]+)=([^&]+)") do + if key == "stun" and value ~= "" then + stun_servers[#stun_servers + 1] = value + end + end + if #stun_servers > 0 then + realm.stun_servers = stun_servers + end + end + return realm +end + +function get_network_devices() + local _sysnet = "/sys/class/net/" + -- Map UCI interface names to their device names and vice versa + local _iface_to_dev = {} + local _dev_to_ifaces = {} + local _iface_proto = {} + uci:foreach("network", "interface", function(sec) + local name = sec[".name"] + if name ~= "loopback" then + _iface_proto[name] = sec.proto + if sec.device then + _iface_to_dev[name] = sec.device + _dev_to_ifaces[sec.device] = _dev_to_ifaces[sec.device] or {} + table.insert(_dev_to_ifaces[sec.device], name) + end + end + end) + -- Classify device type using sysfs attributes + local function classify_sysfs(dev) + if fs.stat(_sysnet .. dev .. "/bridge", "type") == "dir" then + return i18n.translate("Bridge") + elseif fs.stat(_sysnet .. dev .. "/wireless", "type") == "dir" then + return i18n.translate("Wireless Adapter") + elseif dev:match("^tun") or dev:match("^tap") or dev:match("^wg") or dev:match("^ppp") then + return i18n.translate("Tunnel Interface") + else + return i18n.translate("Ethernet Adapter") + end + end + -- Classify offline UCI interfaces by config hints + local function classify_uci(dev_name, proto) + if dev_name and dev_name:match("^br%-") then + return i18n.translate("Bridge") + elseif proto == "wireguard" or proto == "pppoe" or proto == "pptp" or proto == "l2tp" then + return i18n.translate("Tunnel Interface") + else + return i18n.translate("Interface") + end + end + + local _seen = {} + local _devices = {} + -- Active kernel devices from /sys/class/net/ + -- Skip bridge member ports (/master) and DSA master devices (/dsa) + local _iter = fs.dir(_sysnet) + if _iter then + for dev in _iter do + if dev ~= "lo" + and not dev:match("^veth") + and not dev:match("^ifb") + and not dev:match("^gre") + and not dev:match("^sit") + and not dev:match("^ip6tnl") + and not dev:match("^erspan") + and not fs.stat(_sysnet .. dev .. "/master", "type") + and not fs.stat(_sysnet .. dev .. "/dsa", "type") + then + local dtype = classify_sysfs(dev) + local label = dtype .. ': "' .. dev .. '"' + if _dev_to_ifaces[dev] then + label = label .. " (" .. table.concat(_dev_to_ifaces[dev], ", ") .. ")" + end + _devices[#_devices + 1] = { name = dev, label = label, sort = dtype .. ":" .. dev } + _seen[dev] = true + end + end + end + -- UCI interfaces whose device does not currently exist + for iface, dev in pairs(_iface_to_dev) do + if not _seen[dev] then + local dtype = classify_uci(dev, _iface_proto[iface]) + local label = dtype .. ': "' .. iface .. '"' + _devices[#_devices + 1] = { name = iface, label = label, sort = "zzz:" .. iface } + _seen[dev] = true + end + end + table.sort(_devices, function(a, b) return a.sort < b.sort end) + return _devices +end diff --git a/luci-app-passwall2/luasrc/passwall2/com.lua b/luci-app-passwall2/luasrc/passwall2/com.lua new file mode 100644 index 00000000..aefc5459 --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/com.lua @@ -0,0 +1,83 @@ +local _M = {} + +local function gh_release_url(self) + --return "https://api.github.com/repos/" .. self.repo .. "/releases/latest" + return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-release-api.json" +end + +local function gh_pre_release_url(self) + --return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1" + return "https://github.com/Openwrt-Passwall/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json" +end + +_M.hysteria = { + name = "Hysteria", + repo = "HyNetwork/hysteria", + get_url = gh_release_url, + cmd_version = "version | awk '/^Version:/ {print $2}'", + remote_version_str_replace = "app/", + zipped = false, + default_path = "/usr/bin/hysteria", + match_fmt_str = "linux%%-%s$", + file_tree = { + armv6 = "arm", + armv7 = "arm" + } +} + +_M["sing-box"] = { + name = "Sing-Box", + repo = "SagerNet/sing-box", + get_url = gh_release_url, + cmd_version = "version | awk '{print $3}' | sed -n 1P", + zipped = true, + zipped_suffix = "tar.gz", + default_path = "/usr/bin/sing-box", + match_fmt_str = "linux%%-%s", + file_tree = { + x86_64 = "amd64%-musl", + x86 = "386%-musl", + aarch64 = "arm64%-musl", + rockchip = "arm64%-musl", + mips = "mips%-softfloat", + mips64 = "mips64%-softfloat", + mipsel = "mipsle%-softfloat%-musl", + mips64el = "mips64le%-softfloat", + armv7 = "armv7%-musl", + armv8 = "arm64%-musl", + riscv64 = "riscv64%-musl" + } +} + +_M.xray = { + name = "Xray", + repo = "XTLS/Xray-core", + get_url = gh_pre_release_url, + cmd_version = "version | awk '{print $2}' | sed -n 1P", + zipped = true, + default_path = "/usr/bin/xray", + match_fmt_str = "linux%%-%s", + file_tree = { + x86_64 = "64", + x86 = "32", + mips = "mips32", + mipsel = "mips32le", + mips64el = "mips64le" + } +} + +_M.geoview = { + name = "Geoview", + repo = "snowie2000/geoview", + get_url = gh_release_url, + cmd_version = '-version 2>/dev/null | awk \'NR==1 && $1=="Geoview" {print $2}\'', + zipped = false, + default_path = "/usr/bin/geoview", + match_fmt_str = "linux%%-%s", + file_tree = { + mipsel = "mipsle", + mips64el = "mips64le" + } +} + +return _M diff --git a/luci-app-passwall2/luasrc/passwall2/server_app.lua b/luci-app-passwall2/luasrc/passwall2/server_app.lua new file mode 100644 index 00000000..360305ff --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/server_app.lua @@ -0,0 +1,244 @@ +#!/usr/bin/lua + +local action = arg[1] +local api = require "luci.passwall2.api" +local sys = api.sys +local uci = api.uci +local jsonc = api.jsonc + +local CONFIG = "passwall2_server" +local CONFIG_PATH = "/tmp/etc/" .. CONFIG +local NFT_INCLUDE_FILE = CONFIG_PATH .. "/" .. CONFIG .. ".nft" +local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log" +local TMP_BIN_PATH = CONFIG_PATH .. "/bin" +local require_dir = "luci.passwall2." + +local ipt_bin = sys.exec("echo -n $(/usr/share/passwall2/iptables.sh get_ipt_bin)") +local ip6t_bin = sys.exec("echo -n $(/usr/share/passwall2/iptables.sh get_ip6t_bin)") + +local nft_flag = api.is_finded("fw4") and "1" or "0" + +local function log(...) + local f, err = io.open(LOG_APP_FILE, "a") + if f and err == nil then + local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + f:write(str .. "\n") + f:close() + end +end + +local function cmd(cmd) + sys.call(cmd) +end + +local function ipt(arg) + if ipt_bin and #ipt_bin > 0 then + cmd(ipt_bin .. " -w " .. arg) + end +end + +local function ip6t(arg) + if ip6t_bin and #ip6t_bin > 0 then + cmd(ip6t_bin .. " -w " .. arg) + end +end + +local function ln_run(s, d, command, output) + if not output then + output = "/dev/null" + end + d = TMP_BIN_PATH .. "/" .. d + cmd(string.format('[ ! -f "%s" ] && ln -s %s %s 2>/dev/null', d, s, d)) + return string.format("%s >%s 2>&1 &", d .. " " ..command, output) +end + +local function gen_include() + cmd(string.format("echo '#!/bin/sh' > /tmp/etc/%s.include", CONFIG)) + local function extract_rules(n, a) + local _ipt = ipt_bin + if n == "6" then + _ipt = ip6t_bin + end + local result = "*" .. a + result = result .. "\n" .. sys.exec(_ipt .. '-save -t ' .. a .. ' | grep "PSW2-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"') + result = result .. "COMMIT" + return result + end + local f, err = io.open("/tmp/etc/" .. CONFIG .. ".include", "a") + if f and err == nil then + if nft_flag == "0" then + f:write(ipt_bin .. '-save -c | grep -v "PSW2-SERVER" | ' .. ipt_bin .. '-restore -c' .. "\n") + f:write(ipt_bin .. '-restore -n <<-EOT' .. "\n") + f:write(extract_rules("4", "filter") .. "\n") + f:write("EOT" .. "\n") + f:write(ip6t_bin .. '-save -c | grep -v "PSW2-SERVER" | ' .. ip6t_bin .. '-restore -c' .. "\n") + f:write(ip6t_bin .. '-restore -n <<-EOT' .. "\n") + f:write(extract_rules("6", "filter") .. "\n") + f:write("EOT" .. "\n") + f:close() + else + f:write("nft -f " .. NFT_INCLUDE_FILE .. "\n") + f:close() + end + end +end + +local function start() + local enabled = tonumber(uci:get(CONFIG, "@global[0]", "enable") or 0) + if enabled == nil or enabled == 0 then + return + end + cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH)) + cmd(string.format("touch %s", LOG_APP_FILE)) + if nft_flag == "0" then + ipt("-N PSW2-SERVER") + ipt("-I INPUT -j PSW2-SERVER") + ip6t("-N PSW2-SERVER") + ip6t("-I INPUT -j PSW2-SERVER") + else + nft_file, err = io.open(NFT_INCLUDE_FILE, "w") + nft_file:write('#!/usr/sbin/nft -f\n') + nft_file:write('add chain inet fw4 PSW2-SERVER\n') + nft_file:write('flush chain inet fw4 PSW2-SERVER\n') + nft_file:write('insert rule inet fw4 input position 0 jump PSW2-SERVER comment "PSW2-SERVER"\n') + end + uci:foreach(CONFIG, "user", function(user) + local id = user[".name"] + local enable = user.enable + if enable and tonumber(enable) == 1 then + local enable_log = user.log + local log_path = nil + if enable_log and enable_log == "1" then + log_path = CONFIG_PATH .. "/" .. id .. ".log" + else + log_path = nil + end + local remarks = user.remarks + local port = tonumber(user.port) + local bin + local config = {} + local config_file = CONFIG_PATH .. "/" .. id .. ".json" + local udp_forward = 1 + local type = user.type or "" + if type == "SSR" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + else + config = require(require_dir .. "util_shadowsocks").gen_config_server(user) + end + local udp_param = "" + udp_forward = tonumber(user.udp_forward) or 1 + if udp_forward == 1 then + udp_param = "-u" + end + type = type:lower() + bin = ln_run("/usr/bin/" .. type .. "-server", type .. "-server", "-c " .. config_file .. " " .. udp_param, log_path) + elseif type == "SS-Rust" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + else + config = require(require_dir .. "util_shadowsocks").gen_config_server(user) + end + bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path) + elseif type == "Xray" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + if log_path then + if not config.log then + config.log = {} + end + config.log.loglevel = user.loglevel + end + else + config = require(require_dir .. "util_xray").gen_config_server(user) + end + bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path) + elseif type == "sing-box" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + if log_path then + if not config.log then + config.log = {} + end + config.log.timestamp = true + config.log.disabled = false + config.log.level = user.loglevel + config.log.output = log_path + end + else + config = require(require_dir .. "util_sing-box").gen_config_server(user) + end + bin = ln_run(api.get_app_path("sing-box"), "sing-box", "run -c " .. config_file, log_path) + elseif type == "Hysteria2" then + if user.custom == "1" and user.config_str then + config = jsonc.parse(api.base64Decode(user.config_str)) + else + config = require(require_dir .. "util_hysteria2").gen_config_server(user) + end + bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path) + end + + if next(config) then + local f, err = io.open(config_file, "w") + if f and err == nil then + f:write(jsonc.stringify(config, 1)) + f:close() + end + log(string.format("%s %s - %s", remarks, api.i18n.translate("Generate configuration file and run"), config_file)) + end + + if bin then + cmd(bin) + end + + local bind_local = user.bind_local or 0 + if bind_local and tonumber(bind_local) ~= 1 and port then + if nft_flag == "0" then + ipt(string.format('-A PSW2-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + ip6t(string.format('-A PSW2-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + if udp_forward == 1 then + ipt(string.format('-A PSW2-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + ip6t(string.format('-A PSW2-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) + end + else + nft_file:write(string.format('add rule inet fw4 PSW2-SERVER meta l4proto tcp tcp dport {%s} counter accept comment "%s"\n', port, remarks)) + if udp_forward == 1 then + nft_file:write(string.format('add rule inet fw4 PSW2-SERVER meta l4proto udp udp dport {%s} counter accept comment "%s"\n', port, remarks)) + end + end + end + end + end) + if nft_flag == "1" then + nft_file:write("add rule inet fw4 PSW2-SERVER return\n") + nft_file:close() + cmd("nft -f " .. NFT_INCLUDE_FILE) + end + gen_include() +end + +local function stop() + cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH)) + if nft_flag == "0" then + ipt("-D INPUT -j PSW2-SERVER 2>/dev/null") + ipt("-F PSW2-SERVER 2>/dev/null") + ipt("-X PSW2-SERVER 2>/dev/null") + ip6t("-D INPUT -j PSW2-SERVER 2>/dev/null") + ip6t("-F PSW2-SERVER 2>/dev/null") + ip6t("-X PSW2-SERVER 2>/dev/null") + else + local nft_cmd = "handles=$(nft -a list chain inet fw4 input | grep -E \"PSW2-SERVER\" | awk -F '# handle ' '{print$2}')\n for handle in $handles; do\n nft delete rule inet fw4 input handle ${handle} 2>/dev/null\n done" + cmd(nft_cmd) + cmd("nft flush chain inet fw4 PSW2-SERVER 2>/dev/null") + cmd("nft delete chain inet fw4 PSW2-SERVER 2>/dev/null") + end + cmd(string.format("rm -rf %s %s /tmp/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG)) +end + +if action then + if action == "start" then + start() + elseif action == "stop" then + stop() + end +end diff --git a/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua b/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua new file mode 100644 index 00000000..7075dd11 --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua @@ -0,0 +1,161 @@ +module("luci.passwall2.util_hysteria2", package.seeall) +local api = require "luci.passwall2.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config_server(node) + local config = { + listen = (function() + if node.hysteria2_realms and node.hysteria2_realm_url then + local url = node.hysteria2_realm_url:gsub("/+$", "") + if node.port then + url = url .. (url:find("?") and "&lport=" or "?lport=") .. node.port + end + return url + end + return ":" .. (node.port or "0") + end)(), + tls = { + cert = node.tls_certificateFile, + key = node.tls_keyFile, + }, + obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and { + type = "salamander", + salamander = { + password = node.hysteria2_obfs_password + } + } or nil, + auth = { + type = "password", + password = node.hysteria2_auth_password + }, + bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and { + up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil, + down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil + } or nil, + ignoreClientBandwidth = (node.hysteria2_ignoreClientBandwidth == "1") and true or false, + disableUDP = (node.hysteria2_udp == "0") and true or false, + realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and { + stunServers = node.hysteria2_realm_stun + } or nil + } + return config +end + +function gen_config(var) + local node_id = var["node"] + if not node_id then + print("node Cannot be empty!") + return + end + local node = uci:get_all("passwall2", node_id) + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local server_host = var["server_host"] or (node.address or ""):lower() + local server_port = var["server_port"] or node.port + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_full(server_host) + end + + local server = server_host .. ":" .. ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-") + + local config = { + server = (function() + if node.hysteria2_realms and node.hysteria2_realm_url then + return node.hysteria2_realm_url:gsub("/+$", "") + end + return server + end)(), + realm = (node.hysteria2_realms and node.hysteria2_realm_stun) and { + stunServers = node.hysteria2_realm_stun + } or nil, + transport = { + type = "udp", + udp = node.hysteria2_hop and (function() + local udp = {} + local t = node.hysteria2_hop_interval + if not t then return nil end + if t:find("-", 1, true) then + local min, max = t:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + udp.minHopInterval = min .. "s" + udp.maxHopInterval = max .. "s" + return udp + end + end + t = tonumber((t or "30"):match("^%d+")) + t = (t and t >= 5) and t or 30 + udp.hopInterval = t .. "s" + return udp + end)() or nil + }, + obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and { + type = "salamander", + salamander = { + password = node.hysteria2_obfs_password + } + } or nil, + auth = node.hysteria2_auth_password, + tls = { + sni = node.tls_serverName, + insecure = (node.tls_allowInsecure == "1") and true or false, + pinSHA256 = (node.tls_pinSHA256) and node.tls_pinSHA256 or nil, + }, + quic = { + initStreamReceiveWindow = (node.hysteria2_recv_window) and tonumber(node.hysteria2_recv_window) or nil, + initConnReceiveWindow = (node.hysteria2_recv_window_conn) and tonumber(node.hysteria2_recv_window_conn) or nil, + maxIdleTimeout = (function(t) + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t .. "s" or "30s" + end)(node.hysteria2_idle_timeout), + keepAlivePeriod = (function(t) + t = tonumber(tostring(t or "0"):match("^%d+")) + return (t and t >= 2 and t <= 60) and t .. "s" or nil + end)(node.hysteria2_keep_alive_period), + disablePathMTUDiscovery = (node.hysteria2_disable_mtu_discovery) and true or false, + }, + bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and { + up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil, + down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil + } or nil, + fast_open = (node.fast_open == "1") and true or false, + lazy = (node.hysteria2_lazy_start == "1") and true or false, + socks5 = (local_socks_address and local_socks_port) and { + listen = local_socks_address .. ":" .. local_socks_port, + username = (local_socks_username and local_socks_password) and local_socks_username or nil, + password = (local_socks_username and local_socks_password) and local_socks_password or nil, + disableUDP = false, + } or nil, + http = (local_http_address and local_http_port) and { + listen = local_http_address .. ":" .. local_http_port, + username = (local_http_username and local_http_password) and local_http_username or nil, + password = (local_http_username and local_http_password) and local_http_password or nil, + } or nil + } + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + end +end diff --git a/luci-app-passwall2/luasrc/passwall2/util_naiveproxy.lua b/luci-app-passwall2/luasrc/passwall2/util_naiveproxy.lua new file mode 100644 index 00000000..b515c75f --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/util_naiveproxy.lua @@ -0,0 +1,43 @@ +module("luci.passwall2.util_navieproxy", package.seeall) +local api = require "luci.passwall2.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config(var) + local node_id = var["node"] + if not node_id then + print("node Cannot be empty!") + return + end + local node = uci:get_all("passwall2", node_id) + local run_type = var["run_type"] + local local_addr = var["local_addr"] + local local_port = var["local_port"] + local server_host = var["server_host"] or (node.address or ""):lower() + local server_port = var["server_port"] or node.port + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_full(server_host) + end + local server = server_host .. ":" .. server_port + + local config = { + listen = run_type .. "://" .. local_addr .. ":" .. local_port, + proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server + } + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + end +end diff --git a/luci-app-passwall2/luasrc/passwall2/util_shadowsocks.lua b/luci-app-passwall2/luasrc/passwall2/util_shadowsocks.lua new file mode 100644 index 00000000..f4645138 --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/util_shadowsocks.lua @@ -0,0 +1,139 @@ +module("luci.passwall2.util_shadowsocks", package.seeall) +local api = require "luci.passwall2.api" +local uci = api.uci +local jsonc = api.jsonc + +function gen_config_server(node) + local config = {} + config.server_port = tonumber(node.port) + config.password = node.password + config.timeout = tonumber(node.timeout) + config.fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false + config.method = node.method + + if node.type == "SS-Rust" then + config.server = "::" + config.mode = "tcp_and_udp" + else + config.server = {"[::0]", "0.0.0.0"} + end + + if node.type == "SSR" then + config.protocol = node.protocol + config.protocol_param = node.protocol_param + config.obfs = node.obfs + config.obfs_param = node.obfs_param + end + + return config +end + +local plugin_sh, plugin_bin + +function gen_config(var) + local node_id = var["node"] + if not node_id then + print("node Cannot be empty!") + return + end + local node = uci:get_all("passwall2", node_id) + local server_host = var["server_host"] or (node.address or ""):lower() + local server_port = var["server_port"] or node.port + local local_addr = var["local_addr"] + local local_port = var["local_port"] + local mode = var["mode"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + + if api.is_ipv6(server_host) then + server_host = api.get_ipv6_only(server_host) + end + local server = server_host + + local plugin_file + if node.plugin and node.plugin ~= "" and node.plugin ~= "none" then + plugin_sh = var["plugin_sh"] or "" + plugin_file = (plugin_sh ~="") and plugin_sh or node.plugin + plugin_bin = node.plugin + end + + local config = { + server = server, + server_port = tonumber(server_port), + local_address = local_addr, + local_port = tonumber(local_port), + password = node.password, + method = node.method, + timeout = tonumber(node.timeout), + fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false, + reuse_port = true + } + + if node.type == "SSR" then + config.protocol = node.protocol + config.protocol_param = node.protocol_param + config.obfs = node.obfs + config.obfs_param = node.obfs_param + elseif node.type == "SS-Rust" then + config = { + servers = { + { + address = server, + port = tonumber(server_port), + method = node.method, + password = node.password, + timeout = tonumber(node.timeout), + plugin = plugin_file or nil, + plugin_opts = (plugin_file) and node.plugin_opts or nil + } + }, + locals = {}, + fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false + } + if local_socks_address and local_socks_port then + table.insert(config.locals, { + local_address = local_socks_address, + local_port = tonumber(local_socks_port), + mode = "tcp_and_udp" + }) + end + if local_http_address and local_http_port then + table.insert(config.locals, { + protocol = "http", + local_address = local_http_address, + local_port = tonumber(local_http_port) + }) + end + end + + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + if plugin_sh and plugin_sh ~="" and plugin_bin then + local f = io.open(plugin_sh, "w") + f:write("#!/bin/sh\n") + f:write("export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:$PATH\n") + f:write(plugin_bin .. " $@ &\n") + f:write("echo $! > " .. plugin_sh:gsub("%.sh$", ".pid") .. "\n") + f:write("wait\n") + f:close() + luci.sys.call("chmod +x " .. plugin_sh) + end + end +end diff --git a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua new file mode 100644 index 00000000..8080b147 --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua @@ -0,0 +1,2470 @@ +module("luci.passwall2.util_sing-box", package.seeall) +local api = require "luci.passwall2.api" +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local appname = api.appname +local fs = api.fs +local CACHE_PATH = api.CACHE_PATH +local split = api.split +local ech_domain = {} + +local local_version = api.get_app_version("sing-box"):match("[^v]+") +local version_ge_1_13_0 = api.compare_versions(local_version, ">=", "1.13.0") + +local GLOBAL = { + DNS_SERVER = {} +} + +local GEO_VAR = { + OK = nil, + DIR = nil, + SITE_PATH = nil, + IP_PATH = nil, + SITE_TAGS = {}, + IP_TAGS = {}, + TO_SRS_PATH = "/tmp/etc/" .. appname .."_tmp/singbox_srss/" +} + +function check_geoview() + if not GEO_VAR.OK then + -- Only get once + GEO_VAR.OK = (api.finded_com("geoview") and api.compare_versions(api.get_app_version("geoview"), ">=", "0.1.10")) and 1 or 0 + end + if GEO_VAR.OK == 0 then + api.log(0, "!!! Note: Geo rules cannot be used if the Geoview component is missing or the version is too low.") + else + GEO_VAR.DIR = GEO_VAR.DIR or (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") + GEO_VAR.SITE_PATH = GEO_VAR.SITE_PATH or (GEO_VAR.DIR .. "/geosite.dat") + GEO_VAR.IP_PATH = GEO_VAR.IP_PATH or (GEO_VAR.DIR .. "/geoip.dat") + if not fs.access(GEO_VAR.TO_SRS_PATH) then + fs.mkdir(GEO_VAR.TO_SRS_PATH) + end + end + return GEO_VAR.OK +end + +function geo_convert_srs(var) + if check_geoview() ~= 1 then + return + end + local geo_path = var["geo_path"] + local prefix = var["prefix"] + local rule_name = var["rule_name"] + local output_srs_file = GEO_VAR.TO_SRS_PATH .. prefix .. "-" .. rule_name .. ".srs" + local bin = api.finded_com("geoview") + if not fs.access(output_srs_file) and bin then + local cmd = string.format("%q -type %q -action convert -input %q -list %q -output %q -lowmem=true", + bin, prefix, geo_path, rule_name, output_srs_file) + sys.call(cmd) + local status = fs.access(output_srs_file) and "success." or "failed!" + if status == "failed!" then + api.log(0, string.format(" - %s:%s convert to srs %s", prefix, rule_name, status)) + end + end +end + +local function convert_geofile() + if check_geoview() ~= 1 then + return + end + local function convert(file_path, prefix, tags) + if next(tags) and fs.access(file_path) then + local md5_file = GEO_VAR.TO_SRS_PATH .. prefix .. ".dat.md5" + local new_md5 = sys.exec("md5sum " .. file_path .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "") + local old_md5 = sys.exec("[ -f " .. md5_file .. " ] && head -n 1 " .. md5_file .. " | tr -d ' \t\n' || echo ''") + if new_md5 ~= "" and new_md5 ~= old_md5 then + sys.call("printf '%s' " .. new_md5 .. " > " .. md5_file) + sys.call("rm -rf " .. GEO_VAR.TO_SRS_PATH .. prefix .. "-*.srs" ) + end + for k in pairs(tags) do + geo_convert_srs({ + ["geo_path"] = file_path, + ["prefix"] = prefix, + ["rule_name"] = k + }) + end + end + end + --api.log(0, "V2ray/Xray Geo convert to Sing-Box rule-set:") + convert(GEO_VAR.SITE_PATH, "geosite", GEO_VAR.SITE_TAGS) + convert(GEO_VAR.IP_PATH, "geoip", GEO_VAR.IP_TAGS) +end + +function parseDNS(str) + local result_dns_server + -- [proto]://[ip] + -- [proto]://[ip]:[port] + -- https://[ip]/[path] + -- https://[ip]:[port]/[path] + local _a = api.parseURL(str) + if _a then + if _a.protocol == "tcp" or _a.protocol == "udp" or _a.protocol == "https" then + result_dns_server = { + type = _a.protocol, + server = _a.hostname + } + if _a.port then + result_dns_server.server_port = _a.port + else + if _a.protocol == "https" then + result_dns_server.server_port = 443 + else + result_dns_server.server_port = 53 + end + end + result_dns_server.path = _a.pathname + end + end + return result_dns_server +end + +function gen_outbound(flag, node, tag, proxy_table) + local result = nil + if node then + local node_id = node[".name"] + if tag == nil then + tag = node_id + end + local remarks = node.remarks + + local proxy_tag = nil + local fragment = nil + local record_fragment = nil + local run_socks_instance = true + if proxy_table ~= nil and type(proxy_table) == "table" then + proxy_tag = proxy_table.tag or nil + fragment = (proxy_table.fragment and node.protocol ~= "naive" and not node.hysteria2_realms) and true or nil + record_fragment = (proxy_table.record_fragment and node.protocol ~= "naive" and not node.hysteria2_realms) and true or nil + run_socks_instance = proxy_table.run_socks_instance + end + + if node.type ~= "sing-box" then + local relay_port = node.port + local new_port = api.get_new_port() + local config_file = string.format("%s_%s_%s.json", flag, tag, new_port) + if tag and node_id and not tag:find(node_id) then + config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port) + end + if run_socks_instance then + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s", + new_port, --flag + node_id, --node + "127.0.0.1", --bind + new_port, --socks port + config_file, --config file + (proxy_tag and relay_port) and tostring(relay_port) or "" --relay port + ) + ) + ) + end + node = { + protocol = "socks", + address = "127.0.0.1", + port = new_port + } + proxy_tag = "socks <- " .. node_id + else + if proxy_tag then + node.detour = proxy_tag + end + end + + if remarks then + tag = tag .. ":" .. remarks + end + + node.address = (node.address or ""):lower() + + result = { + _id = node_id, + _flag = flag, + _flag_proxy_tag = proxy_tag, + tag = tag, + type = node.protocol, + server = node.address, + server_port = tonumber(node.port), + domain_resolver = { + server = "local", + strategy = node.domain_strategy + }, + detour = node.detour, + } + + if api.datatypes.hostname(node.address) and node.domain_resolver and (node.domain_resolver_dns or node.domain_resolver_dns_https) then + local dns_tag = node_id .. "_dns" + local dns_proto = node.domain_resolver + local server_address + local server_port + local server_path + if dns_proto == "https" then + local _a = api.parseURL(node.domain_resolver_dns_https) + if _a then + server_address = _a.hostname + if _a.port then + server_port = _a.port + else + server_port = 443 + end + server_path = _a.pathname + end + else + server_address = node.domain_resolver_dns + server_port = 53 + local split = api.split(server_address, ":") + if #split > 1 then + server_address = split[1] + server_port = tonumber(split[#split]) + end + end + GLOBAL.DNS_SERVER[node_id] = { + server = { + tag = dns_tag, + type = dns_proto, + server = server_address, + server_port = server_port, + path = server_path, + domain_resolver = "local", + detour = "direct" + }, + domain = node.address + } + result.domain_resolver.server = dns_tag + end + + local tls = nil + if node.protocol == "hysteria" or node.protocol == "hysteria2" or node.protocol == "tuic" or node.protocol == "naive" then + node.tls = "1" + end + if node.tls == "1" then + local alpn = nil + if node.alpn and node.alpn ~= "default" then + alpn = {} + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + tls = { + enabled = true, + disable_sni = (node.tls_disable_sni == "1") and true or false, -- Do not send the server name in ClientHello. + server_name = node.tls_serverName, -- Used to verify the hostname on the returned certificate, unless the settings are insecure. It is also included in ClientHello to support virtual hosts, unless it is an IP address. + insecure = node.tls_allowInsecure == "1" or (node.tls_pinSHA256 and node.tls_pinSHA256 ~= ""), -- Accepts any server certificate. (Also compatible with xray's pinnedPeerCertSha256) + alpn = alpn, -- A list of supported application layer protocols, arranged in order of priority. If both peers support ALPN, the protocol selected will be one of these protocols; otherwise, the connection will fail. + --max_version = "1.3", + fragment = fragment, + record_fragment = record_fragment, + ech = (node.ech == "1") and (function() + local function get_ech_domain(s) --兼容xray "域å+DNS" æ ¼å¼ech + local domain, dns = s:match("^([^+]+)%+(.+)$") + if not domain or not dns then return nil end + if not (dns:match("^https?://") or dns:match("^tcp://") or dns:match("^udp://") or dns:match("^h2c://")) then + return nil + end + if not domain:match("^[%w%-%.]+%.[%a]+$") then return nil end + return domain + end + local ech = { enabled = true } + local config = node.ech_config + local qname = node.ech_query_server_name + if config and not qname then + qname = get_ech_domain(config) + if not qname and not (config:match("%-+%s*BEGIN") and config:match("%-+%s*END")) then + config = "-----BEGIN ECH CONFIGS-----\n" .. config:gsub("%s+", "") .. "\n-----END ECH CONFIGS-----" + end + end + if qname then + ech.query_server_name = qname + ech_domain[qname] = true + elseif config then + ech.config = { config } + elseif node.tls_serverName and node.tls_serverName ~= "" then + ech_domain[node.tls_serverName] = true + end + return ech + end)() or nil, + utls = (node.utls == "1" or node.reality == "1") and { + enabled = true, + fingerprint = node.fingerprint or "chrome" + } or nil, + reality = (node.reality == "1") and { + enabled = true, + public_key = node.reality_publicKey, + short_id = node.reality_shortId + } or nil + } + end + + local mux = nil + if node.mux == "1" then + mux = { + enabled = true, + protocol = node.mux_type or "h2mux", + max_connections = ( (node.tcpbrutal == "1") and 1 ) or tonumber(node.mux_concurrency) or 4, + padding = (node.mux_padding == "1") and true or false, + --min_streams = 4, + --max_streams = 0, + brutal = { + enabled = (node.tcpbrutal == "1") and true or false, + up_mbps = tonumber(node.tcpbrutal_up_mbps) or 10, + down_mbps = tonumber(node.tcpbrutal_down_mbps) or 50, + }, + } + end + + local v2ray_transport = nil + + if node.transport == "tcp" and node.tcp_guise == "http" and (node.tcp_guise_http_host or "") ~= "" then -- Simulate X-ray Raw (TCP) transmission + v2ray_transport = { + type = "http", + host = node.tcp_guise_http_host, + path = node.tcp_guise_http_path and (function() + local first = node.tcp_guise_http_path[1] + return (first == "" or not first) and "/" or first + end)() or "/", + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil, + ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil, + } + -- TLS is not enforced. If TLS is not configured, plain HTTP 1.1 will be used. + end + + if node.transport == "http" then + v2ray_transport = { + type = "http", + host = node.http_host or {}, + path = node.http_path or "/", + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + idle_timeout = (node.http_h2_health_check == "1") and node.http_h2_read_idle_timeout or nil, + ping_timeout = (node.http_h2_health_check == "1") and node.http_h2_health_check_timeout or nil, + } + -- TLS is not enforced. If TLS is not configured, plain HTTP 1.1 will be used. + end + + if node.transport == "ws" then + v2ray_transport = { + type = "ws", + path = node.ws_path or "/", + headers = (node.ws_host or node.user_agent) and { + Host = node.ws_host, + ["User-Agent"] = node.user_agent + } or nil, + max_early_data = tonumber(node.ws_maxEarlyData) or nil, + early_data_header_name = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil -- For compatibility with Xray-core, set it to Sec-WebSocket-Protocol. It needs to be consistent with the server. + } + end + + if node.transport == "httpupgrade" then + v2ray_transport = { + type = "httpupgrade", + host = node.httpupgrade_host, + path = node.httpupgrade_path or "/", + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil + } + end + + if node.transport == "quic" then + v2ray_transport = { + type = "quic" + } + -- There is no additional encryption support: it's essentially re-encryption. And Xray-core is incompatible with v2ray-core here. + end + + if node.transport == "grpc" then + v2ray_transport = { + type = "grpc", + service_name = node.grpc_serviceName, + idle_timeout = tonumber(node.grpc_idle_timeout) or nil, + ping_timeout = tonumber(node.grpc_health_check_timeout) or nil, + permit_without_stream = (node.grpc_permit_without_stream == "1") and true or nil, + } + end + + local protocol_table = nil + + if node.protocol == "socks" then + protocol_table = { + version = "5", + username = (node.username and node.password) and node.username or nil, + password = (node.username and node.password) and node.password or nil, + udp_over_tcp = node.uot == "1" and { + enabled = true, + version = 2 + } or nil, + } + end + + if node.protocol == "http" then + protocol_table = { + username = (node.username and node.password) and node.username or nil, + password = (node.username and node.password) and node.password or nil, + path = nil, + headers = nil, + tls = tls + } + end + + if node.protocol == "shadowsocks" then + protocol_table = { + method = node.method or nil, + password = node.password or "", + plugin = (node.plugin_enabled and node.plugin) or nil, + plugin_opts = (node.plugin_enabled and node.plugin_opts) or nil, + udp_over_tcp = node.uot == "1" and { + enabled = true, + version = 2 + } or nil, + multiplex = mux, + } + end + + if node.protocol == "shadowsocksr" then + protocol_table = { + method = node.method or nil, + password = node.password or "", + obfs = node.ssr_obfs, + obfs_param = node.ssr_obfs_param, + protocol = node.ssr_protocol, + protocol_param = node.ssr_protocol_param, + } + end + + if node.protocol == "trojan" then + protocol_table = { + password = node.password, + tls = tls, + multiplex = mux, + transport = v2ray_transport + } + end + + if node.protocol == "vmess" then + protocol_table = { + uuid = node.uuid, + security = node.security, + alter_id = (node.alter_id) and tonumber(node.alter_id) or 0, + global_padding = (node.global_padding == "1") and true or false, + authenticated_length = (node.authenticated_length == "1") and true or false, + tls = tls, + packet_encoding = "", -- UDP packet encoding. (Empty): Disabled. packetaddr: Supported by v2ray 5+. xudp: Supported by xray. + multiplex = mux, + transport = v2ray_transport, + } + end + + if node.protocol == "vless" then + protocol_table = { + uuid = node.uuid, + flow = (node.tls == '1' and node.flow) and node.flow or nil, + tls = tls, + packet_encoding = "xudp", -- UDP packet encoding. (Empty): Disabled. packetaddr: Supported by v2ray 5+. xudp: Supported by xray. + multiplex = mux, + transport = v2ray_transport, + } + end + + if node.protocol == "wireguard" then + if node.wireguard_reserved then + local bytes = {} + if not node.wireguard_reserved:match("[^%d,]+") then + node.wireguard_reserved:gsub("%d+", function(b) + bytes[#bytes + 1] = tonumber(b) + end) + else + local result = api.base64Decode(node.wireguard_reserved) + for i = 1, #result do + bytes[i] = result:byte(i) + end + end + node.wireguard_reserved = #bytes > 0 and bytes or nil + end + protocol_table = { + system_interface = (node.wireguard_system_interface == "1") and true or false, + interface_name = node.wireguard_interface_name, + local_address = node.wireguard_local_address, + private_key = node.wireguard_secret_key, + peer_public_key = node.wireguard_public_key, + pre_shared_key = node.wireguard_preSharedKey, + reserved = node.wireguard_reserved, + mtu = tonumber(node.wireguard_mtu), + } + end + + if node.protocol == "hysteria" then + local server_ports = {} + if node.hysteria_hop then + node.hysteria_hop = string.gsub(node.hysteria_hop, "-", ":") + for range in node.hysteria_hop:gmatch("([^,]+)") do + if range:match("^%d+:%d+$") then + table.insert(server_ports, range) + end + end + result.server_port = nil + end + protocol_table = { + server_ports = next(server_ports) and server_ports or nil, + hop_interval = (function() + if not next(server_ports) then return nil end + local v = tonumber((node.hysteria_hop_interval or "30"):match("^%d+")) + return (v and v >= 5) and (v .. "s") or "30s" + end)(), + up_mbps = tonumber(node.hysteria_up_mbps), + down_mbps = tonumber(node.hysteria_down_mbps), + obfs = node.hysteria_obfs, + auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil, + auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil, + recv_window_conn = tonumber(node.hysteria_recv_window_conn), --1.14 å°†å˜æ›´ä¸º stream_receive_window + recv_window = tonumber(node.hysteria_recv_window), --1.14 å°†å˜æ›´ä¸º connection_receive_window + disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false, --1.14 å°†å˜æ›´ä¸º disable_path_mtu_discovery + tls = tls + } + end + + if node.protocol == "shadowtls" then + protocol_table = { + version = tonumber(node.shadowtls_version), + password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.password or nil, + tls = tls, + } + end + + if node.protocol == "tuic" then + protocol_table = { + uuid = node.uuid, + password = node.password, + congestion_control = node.tuic_congestion_control or "cubic", + udp_relay_mode = node.tuic_udp_relay_mode or "native", + udp_over_stream = false, + zero_rtt_handshake = (node.tuic_zero_rtt_handshake == "1") and true or false, + heartbeat = (tonumber(node.tuic_heartbeat) or 3) .. "s", + tls = tls + } + node.tuic_alpn = (node.tuic_alpn and node.tuic_alpn ~= "default") and node.tuic_alpn or "h3" + local alpn = {} + string.gsub(node.tuic_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then protocol_table.tls.alpn = alpn end + end + + if node.protocol == "hysteria2" then + local server_ports = {} + if node.hysteria2_hop then + node.hysteria2_hop = string.gsub(node.hysteria2_hop, "-", ":") + for range in node.hysteria2_hop:gmatch("([^,]+)") do + if range:match("^%d+:%d+$") then + table.insert(server_ports, range) + end + end + result.server_port = nil + end + if node.hysteria2_realms then + server_ports = {} + end + local interval, interval_max + if next(server_ports) then + interval = "30s" + local t = node.hysteria2_hop_interval or "30s" + if t:find("-", 1, true) then + local min, max = t:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + interval = min .. "s" + interval_max = max .. "s" + end + else + t = tonumber(t:match("^%d+")) + t = (t and t >= 5) and t or 30 + interval = t .. "s" + end + end + protocol_table = { + server_ports = next(server_ports) and server_ports or nil, + hop_interval = interval, + hop_interval_max = interval_max, + up_mbps = (node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil, + down_mbps = (node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil, + obfs = node.hysteria2_obfs_type and { + type = node.hysteria2_obfs_type, + password = node.hysteria2_obfs_password + } or nil, + password = node.hysteria2_auth_password or nil, + idle_timeout = (function(t) + if not version_ge_1_14_0 then return nil end + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t or 30 + end)(node.hysteria2_idle_timeout), + keep_alive_period = (function(t) + if not version_ge_1_14_0 then return nil end + t = tonumber(tostring(t or "0"):match("^%d+")) + return (t and t >= 2 and t <= 60) and t or nil + end)(node.hysteria2_keep_alive_period), + disable_path_mtu_discovery = version_ge_1_14_0 and (tonumber(node.hysteria2_disable_mtu_discovery) == 1) or nil, + tls = tls, + realm = node.hysteria2_realms and (function() + result.server = nil + result.server_port = nil + local realm = api.parse_realm_uri(node.hysteria2_realm_url) + if realm then + realm.server_url = realm.server_url and "https://" .. realm.server_url or nil + realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun + return realm + end + return nil + end)() or nil + } + end + + if node.protocol == "anytls" then + protocol_table = { + password = (node.password and node.password ~= "") and node.password or "", + idle_session_check_interval = "30s", + idle_session_timeout = "30s", + min_idle_session = 5, + tls = tls + } + end + + if node.protocol == "ssh" then + protocol_table = { + user = (node.username and node.username ~= "") and node.username or "root", + password = (node.password and node.password ~= "") and node.password or "", + private_key = node.ssh_priv_key, + private_key_passphrase = node.ssh_priv_key_pp, + host_key = node.ssh_host_key, + host_key_algorithms = node.ssh_host_key_algo, + client_version = node.ssh_client_version + } + end + + if node.protocol == "naive" then + protocol_table = { + username = (node.username and node.username ~= "") and node.username or "", + password = (node.password and node.password ~= "") and node.password or "", + insecure_concurrency = tonumber(node.naive_insecure_concurrency or 0) > 0 and tonumber(node.naive_insecure_concurrency) or 0, + udp_over_tcp = node.uot == "1" and { + enabled = true, + version = 2 + } or false, + extra_headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + quic = node.naive_quic == "1" and true or false, + quic_congestion_control = (node.naive_quic == "1" and node.naive_congestion_control) and node.naive_congestion_control or nil, + tls = tls + } + end + + if protocol_table then + for key, value in pairs(protocol_table) do + result[key] = value + end + end + end + return result +end + +function gen_config_server(node) + local outbounds = { + { type = "direct", tag = "direct" } + } + + local tls = { + enabled = true, + certificate_path = node.tls_certificateFile, + key_path = node.tls_keyFile, + alpn = (node.alpn and node.alpn ~= "default") and (function() + local alpn = {} + string.gsub(node.alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then return alpn end + return nil + end)() or nil + } + + if node.tls == "1" and node.reality == "1" then + tls.certificate_path = nil + tls.key_path = nil + tls.server_name = node.reality_handshake_server + tls.reality = { + enabled = true, + private_key = node.reality_private_key, + short_id = { + node.reality_shortId + }, + handshake = { + server = node.reality_handshake_server, + server_port = tonumber(node.reality_handshake_server_port) + } + } + end + + if node.tls == "1" and node.ech == "1" then + tls.ech = { + enabled = true, + key = node.ech_key and { node.ech_key } or nil + } + end + + local mux = nil + if node.mux == "1" then + mux = { + enabled = true, + padding = (node.mux_padding == "1") and true or false, + brutal = { + enabled = (node.tcpbrutal == "1") and true or false, + up_mbps = tonumber(node.tcpbrutal_up_mbps) or 10, + down_mbps = tonumber(node.tcpbrutal_down_mbps) or 50, + }, + } + end + + local v2ray_transport = nil + + if node.transport == "http" then + v2ray_transport = { + type = "http", + host = node.http_host or {}, + path = node.http_path or "/", + } + end + + if node.transport == "ws" then + v2ray_transport = { + type = "ws", + path = node.ws_path or "/", + headers = (node.ws_host ~= nil) and { Host = node.ws_host } or nil, + early_data_header_name = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil -- For compatibility with Xray-core, set it to Sec-WebSocket-Protocol. It needs to be consistent with the server. + } + end + + if node.transport == "httpupgrade" then + v2ray_transport = { + type = "httpupgrade", + host = node.httpupgrade_host, + path = node.httpupgrade_path or "/", + } + end + + if node.transport == "quic" then + v2ray_transport = { + type = "quic" + } + -- There is no additional encryption support: it's essentially re-encryption. And Xray-core is incompatible with v2ray-core here. + end + + if node.transport == "grpc" then + v2ray_transport = { + type = "grpc", + service_name = node.grpc_serviceName, + } + end + + local inbound = { + type = node.protocol, + tag = "inbound", + listen = (node.bind_local == "1") and "127.0.0.1" or "::", + listen_port = tonumber(node.port), + } + + local protocol_table = nil + + if node.protocol == "mixed" then + protocol_table = { + users = (node.auth == "1") and { + { + username = node.username, + password = node.password + } + } or nil, + set_system_proxy = false + } + end + + if node.protocol == "socks" then + protocol_table = { + users = (node.auth == "1") and { + { + username = node.username, + password = node.password + } + } or nil + } + end + + if node.protocol == "http" then + protocol_table = { + users = (node.auth == "1") and { + { + username = node.username, + password = node.password + } + } or nil, + tls = (node.tls == "1") and tls or nil, + } + end + + if node.protocol == "shadowsocks" then + protocol_table = { + method = node.method, + password = node.password, + multiplex = mux, + } + end + + if node.protocol == "vmess" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + uuid = node.uuid[i], + alterId = 0, + } + end + protocol_table = { + users = users, + tls = (node.tls == "1") and tls or nil, + multiplex = mux, + transport = v2ray_transport, + } + end + end + + if node.protocol == "vless" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + uuid = node.uuid[i], + flow = node.flow, + } + end + protocol_table = { + users = users, + tls = (node.tls == "1") and tls or nil, + multiplex = mux, + transport = v2ray_transport, + } + end + end + + if node.protocol == "trojan" then + if node.uuid then + local users = {} + for i = 1, #node.uuid do + users[i] = { + name = node.uuid[i], + password = node.uuid[i], + } + end + protocol_table = { + users = users, + tls = (node.tls == "1") and tls or nil, + fallback = nil, + fallback_for_alpn = nil, + multiplex = mux, + transport = v2ray_transport, + } + end + end + + if node.protocol == "naive" then + protocol_table = { + users = { + { + username = node.username, + password = node.password + } + }, + tls = tls + } + end + + if node.protocol == "hysteria" then + protocol_table = { + up = node.hysteria_up_mbps .. " Mbps", + down = node.hysteria_down_mbps .. " Mbps", + up_mbps = tonumber(node.hysteria_up_mbps), + down_mbps = tonumber(node.hysteria_down_mbps), + obfs = node.hysteria_obfs, + users = { + { + name = "user1", + auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil, + auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil, + } + }, + recv_window_conn = node.hysteria_recv_window_conn and tonumber(node.hysteria_recv_window_conn) or nil, --1.14 to stream_receive_window + recv_window_client = node.hysteria_recv_window_client and tonumber(node.hysteria_recv_window_client) or nil, --1.14 to connection_receive_window + max_conn_client = node.hysteria_max_conn_client and tonumber(node.hysteria_max_conn_client) or nil, --1.14 to max_concurrent_streams + disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false, --1.14 to disable_path_mtu_discover + tls = tls + } + end + + if node.protocol == "tuic" then + tls.alpn = (node.tuic_alpn and node.tuic_alpn ~= "default") and (function() + local alpn = {} + string.gsub(node.tuic_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then return alpn end + return nil + end)() or nil + protocol_table = { + users = { + { + name = "user1", + uuid = node.uuid, + password = node.password + } + }, + congestion_control = node.tuic_congestion_control or "cubic", + zero_rtt_handshake = (node.tuic_zero_rtt_handshake == "1") and true or false, + heartbeat = (tonumber(node.tuic_heartbeat) or 3) .. "s", + tls = tls + } + end + + if node.protocol == "hysteria2" then + protocol_table = { + up_mbps = (node.hysteria2_ignore_client_bandwidth ~= "1" and node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil, + down_mbps = (node.hysteria2_ignore_client_bandwidth ~= "1" and node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil, + obfs = node.hysteria2_obfs_type and { + type = node.hysteria2_obfs_type, + password = node.hysteria2_obfs_password + } or nil, + users = { + { + name = "user1", + password = node.hysteria2_auth_password or nil, + } + }, + ignore_client_bandwidth = (node.hysteria2_ignore_client_bandwidth == "1") and true or false, + tls = tls, + realm = node.hysteria2_realms and (function() + local realm = api.parse_realm_uri(node.hysteria2_realm_url) + if realm then + realm.server_url = realm.server_url and "https://" .. realm.server_url or nil + realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun + realm.stun_domain_resolver = "direct" + return realm + end + return nil + end)() or nil + } + end + + if node.protocol == "anytls" then + protocol_table = { + users = { + { + name = (node.username and node.username ~= "") and node.username or "sekai", + password = node.password + } + }, + tls = tls, + } + end + + if node.protocol == "direct" then + protocol_table = { + network = (node.d_protocol ~= "TCP,UDP") and node.d_protocol or nil, + override_address = node.d_address, + override_port = tonumber(node.d_port) + } + end + + if protocol_table then + for key, value in pairs(protocol_table) do + inbound[key] = value + end + end + + local route = { + rules = { + { + ip_is_private = true, + action = node.accept_lan == "1" and "route" or "reject", + outbound = node.accept_lan == "1" and "direct" or nil + } + } + } + + if node.outbound_node then + local outbound = nil + if node.outbound_node == "_iface" and node.outbound_node_iface then + outbound = { + type = "direct", + tag = "outbound", + bind_interface = node.outbound_node_iface, + routing_mark = 255, + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface)) + else + local outbound_node_t = uci:get_all("passwall2", node.outbound_node) + if node.outbound_node == "_socks" or node.outbound_node == "_http" then + outbound_node_t = { + type = node.type, + protocol = node.outbound_node:gsub("_", ""), + address = node.outbound_node_address, + port = tonumber(node.outbound_node_port), + username = (node.outbound_node_username and node.outbound_node_username ~= "") and node.outbound_node_username or nil, + password = (node.outbound_node_password and node.outbound_node_password ~= "") and node.outbound_node_password or nil, + } + end + outbound = require("luci.passwall2.util_sing-box").gen_outbound(nil, outbound_node_t, "outbound") + end + if outbound then + route.final = outbound.tag + table.insert(outbounds, 1, outbound) + end + end + + local config = { + log = { + disabled = (not node or node.log == "0") and true or false, + level = node.loglevel or "info", + timestamp = true, + --output = logfile, + }, + dns = { + servers = { + { + type = "local", + tag = "local" + } + } + }, + inbounds = { inbound }, + outbounds = outbounds, + route = route + } + + for index, value in ipairs(config.outbounds) do + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + end + + return config +end + +function gen_config(var) + local flag = var["flag"] + local log = var["log"] or "0" + local loglevel = var["loglevel"] or "warn" + local logfile = var["logfile"] or "/dev/null" + local node_id = var["node"] + local server_host = var["server_host"] + local server_port = var["server_port"] + local tcp_proxy_way = var["tcp_proxy_way"] + local redir_port = var["redir_port"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local dns_listen_port = var["dns_listen_port"] + local direct_dns_udp_server = var["direct_dns_udp_server"] + local direct_dns_udp_port = var["direct_dns_udp_port"] + local direct_dns_query_strategy = var["direct_dns_query_strategy"] + local direct_ipset = var["direct_ipset"] + local direct_nftset = var["direct_nftset"] + local remote_dns_udp_server = var["remote_dns_udp_server"] + local remote_dns_udp_port = var["remote_dns_udp_port"] + local remote_dns_quic = var["remote_dns_quic"] + local remote_dns_tcp_server = var["remote_dns_tcp_server"] + local remote_dns_tcp_port = var["remote_dns_tcp_port"] + local remote_dns_tls = var["remote_dns_tls"] + local remote_dns_doh_url = var["remote_dns_doh_url"] + local remote_dns_doh_host = var["remote_dns_doh_host"] + local remote_dns_doh_ip = var["remote_dns_doh_ip"] + local remote_dns_doh_port = var["remote_dns_doh_port"] + local remote_dns_http3 = var["remote_dns_http3"] + local remote_dns_detour = var["remote_dns_detour"] + local remote_dns_query_strategy = var["remote_dns_query_strategy"] + local remote_dns_fake = var["remote_dns_fake"] + local remote_dns_client_ip = var["remote_dns_client_ip"] + local dns_cache = var["dns_cache"] + local tags = var["tags"] + local no_run = var["no_run"] + + local dns_domain_rules = {} + local dns = {} + local inbounds = {} + local outbounds = {} + local rule_set_table = {} + local COMMON = {} + + local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt" + + local singbox_settings = uci:get_all(appname, "@global_singbox[0]") or {} + + local route = { + rules = {} + } + + local experimental = nil + + function add_rule_set(tab) + if tab and next(tab) and tab.tag and not rule_set_table[tab.tag]then + rule_set_table[tab.tag] = tab + end + end + + function parse_rule_set(w, rs) + -- Format: remote:https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-netflix.srs' + -- Format: local:/usr/share/sing-box/geosite-netflix.srs' + local result = nil + if w and #w > 0 then + if w:find("local:") == 1 or w:find("remote:") == 1 then + local _type = w:sub(1, w:find(":") - 1) -- "local" or "remote" + w = w:sub(w:find(":") + 1, #w) + local format = nil + local filename = w:sub(-w:reverse():find("/") + 1) -- geosite-netflix.srs + local suffix = "" + local find_doc = filename:reverse():find("%.") + if find_doc then + suffix = filename:sub(-find_doc + 1) -- "srs" or "json" + end + if suffix == "srs" then + format = "binary" + elseif suffix == "json" then + format = "source" + end + if format then + local rule_set_tag = filename:sub(1, filename:find("%.") - 1) --geosite-netflix + if rule_set_tag and #rule_set_tag > 0 then + if rs then + rule_set_tag = "rs_" .. rule_set_tag + end + result = { + type = _type, + tag = rule_set_tag, + format = format, + path = _type == "local" and w or nil, + url = _type == "remote" and w or nil, + --download_detour = _type == "remote" and "", + --update_interval = _type == "remote" and "", + } + end + end + end + end + return result + end + + function geo_rule_set(prefix, rule_name) + local output_srs_file = "local:" .. GEO_VAR.TO_SRS_PATH .. prefix .. "-" .. rule_name .. ".srs" + return parse_rule_set(output_srs_file) + end + + local node = nil + if node_id then + node = uci:get_all(appname, node_id) + end + + if local_socks_port then + local inbound = { + type = "socks", + tag = "socks-in", + listen = local_socks_address, + listen_port = tonumber(local_socks_port), + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.users = { + { + username = local_socks_username, + password = local_socks_password + } + } + end + table.insert(inbounds, inbound) + table.insert(route.rules, { + action = "sniff", + inbound = inbound.tag + }) + end + + if local_http_port then + local inbound = { + type = "http", + tag = "http-in", + listen = local_http_address, + listen_port = tonumber(local_http_port) + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.users = { + { + username = local_http_username, + password = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if redir_port then + local inbound_tproxy = { + type = "tproxy", + tag = "tproxy", + listen = "::", + listen_port = tonumber(redir_port), + } + if tcp_proxy_way ~= "tproxy" then + local inbound = { + type = "redirect", + tag = "redirect_tcp", + listen = "::", + listen_port = tonumber(redir_port), + } + table.insert(inbounds, inbound) + table.insert(route.rules, { + action = "sniff", + inbound = inbound.tag + }) + + inbound_tproxy.tag = "tproxy_udp" + inbound_tproxy.network = "udp" + end + + table.insert(inbounds, inbound_tproxy) + table.insert(route.rules, { + action = "sniff", + inbound = inbound_tproxy.tag + }) + end + + if node then + if node.protocol ~= "_shunt" then + -- create shunt logic + local tmp_node = { + remarks = node.remarks, + type = "sing-box", + protocol = "_shunt", + default_node = node[".name"], + } + tmp_node.fakedns = remote_dns_fake + tmp_node.default_fakedns = remote_dns_fake + node = tmp_node + end + + if server_host and server_port then + default_node_address = server_host + default_node_port = server_port + end + + function gen_socks_config_node(node_id, socks_id, remarks) + if node_id then + socks_id = node_id:sub(1 + #"Socks_") + end + local result + local socks_node = uci:get_all(appname, socks_id) or nil + if socks_node then + if not remarks then + remarks = socks_node.port + end + result = { + [".name"] = "Socksid_" .. socks_id, + remarks = remarks, + type = "sing-box", + protocol = "socks", + address = "127.0.0.1", + port = socks_node.port, + uot = "1" + } + end + return result + end + + local nodes_list = {} + function get_urltest_batch_nodes(_node) + if #nodes_list == 0 then + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then + nodes_list[#nodes_list + 1] = { + id = e[".name"], + remarks = e["remarks"], + group = e["group"] + } + end + end + end + if not _node.node_group or _node.node_group == "" then return {} end + local nodes = {} + for g in _node.node_group:gmatch("%S+") do + g = api.UrlDecode(g) + for k, v in pairs(nodes_list) do + local gn = (v.group and v.group ~= "") and v.group or "default" + if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then + nodes[#nodes + 1] = v.id + end + end + end + return nodes + end + + function get_node_by_id(node_id) + if not node_id or node_id == "" or node_id == "nil" then return nil end + if node_id:find("Socks_") then + return gen_socks_config_node(node_id) + else + return uci:get_all(appname, node_id) + end + end + + function gen_urltest_outbound(_node) + local urltest_id = _node[".name"] + local urltest_tag = "urltest-" .. urltest_id + -- existing urltest + for _, v in ipairs(outbounds) do + if v.tag == urltest_tag then + return v, true + end + end + -- new urltest + local ut_nodes + if _node.node_add_mode and _node.node_add_mode == "batch" then + ut_nodes = get_urltest_batch_nodes(_node) + else + ut_nodes = _node.urltest_node + end + local valid_nodes = {} + for i = 1, #(ut_nodes or {}) do + local ut_node_id = ut_nodes[i] + local ut_node_tag = "ut-" .. ut_node_id + local is_new_ut_node = true + for _, outbound in ipairs(outbounds) do + if string.sub(outbound.tag, 1, #ut_node_tag) == ut_node_tag then + is_new_ut_node = false + valid_nodes[#valid_nodes + 1] = outbound.tag + break + end + end + if is_new_ut_node then + local outboundTag = gen_outbound_get_tag(flag, ut_node_id, ut_node_tag, { fragment = singbox_settings.fragment == "1" or nil, record_fragment = singbox_settings.record_fragment == "1" or nil, run_socks_instance = not no_run }) + if outboundTag then + valid_nodes[#valid_nodes + 1] = outboundTag + end + end + end + if #valid_nodes == 0 then return nil end + local outbound = { + type = "urltest", + tag = urltest_tag, + outbounds = valid_nodes, + url = _node.urltest_url or "https://www.gstatic.com/generate_204", + interval = (api.format_go_time(_node.urltest_interval) ~= "0s") and api.format_go_time(_node.urltest_interval) or "3m", + tolerance = (_node.urltest_tolerance and tonumber(_node.urltest_tolerance) > 0) and tonumber(_node.urltest_tolerance) or 50, + idle_timeout = (api.format_go_time(_node.urltest_idle_timeout) ~= "0s") and api.format_go_time(_node.urltest_idle_timeout) or "30m", + interrupt_exist_connections = (_node.urltest_interrupt_exist_connections == "true" or _node.urltest_interrupt_exist_connections == "1") and true or false + } + return outbound + end + + function set_outbound_detour(node, outbound, outbounds_table) + if not node or not outbound or not outbounds_table then return nil end + local default_outTag = outbound.tag + local last_insert_outbound + + if node.shadowtls == "1" then + local _node = { + type = "sing-box", + protocol = "shadowtls", + shadowtls_version = node.shadowtls_version, + password = (node.shadowtls_version == "2" or node.shadowtls_version == "3") and node.shadowtls_password or nil, + address = node.address, + port = node.port, + tls = "1", + tls_serverName = node.shadowtls_serverName, + utls = node.shadowtls_utls, + fingerprint = node.shadowtls_fingerprint + } + local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls") + if shadowtls_outbound then + last_insert_outbound = shadowtls_outbound + outbound.detour = outbound.tag .. "_shadowtls" + outbound.server = nil + outbound.server_port = nil + end + end + + if node.chain_proxy == "1" and node.preproxy_node then + if outbound["_flag_proxy_tag"] then + --Ignore + else + local preproxy_node = get_node_by_id(node.preproxy_node) + if preproxy_node then + local preproxy_outbound, exist + if preproxy_node.protocol == "_urltest" then + preproxy_outbound, exist = gen_urltest_outbound(preproxy_node) + else + preproxy_outbound = gen_outbound(node[".name"], preproxy_node) + end + if preproxy_outbound then + outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag + outbound.detour = preproxy_outbound.tag + if not exist then + last_insert_outbound = preproxy_outbound + end + default_outTag = outbound.tag + end + end + end + end + if node.chain_proxy == "2" and node.to_node then + local to_node = get_node_by_id(node.to_node) + if to_node then + -- Landing Node not support use special node. + if to_node.protocol:find("^_") then + to_node = nil + end + end + if to_node then + local to_outbound + if to_node.type ~= "sing-box" then + local tag = to_node[".name"] + local new_port = api.get_new_port() + table.insert(inbounds, { + type = "direct", + tag = tag, + listen = "127.0.0.1", + listen_port = new_port, + override_address = to_node.address, + override_port = tonumber(to_node.port), + }) + table.insert(rules, 1, { + action = "route", + inbound = {tag}, + outbound = outbound.tag, + }) + if to_node.tls_serverName == nil then + to_node.tls_serverName = to_node.address + end + to_node.address = "127.0.0.1" + to_node.port = new_port + to_outbound = gen_outbound(node[".name"], to_node, tag, { + tag = tag, + run_socks_instance = not no_run + }) + else + to_outbound = gen_outbound(node[".name"], to_node) + end + if to_outbound then + to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag + if to_node.type == "sing-box" then + to_outbound.detour = outbound.tag + end + table.insert(outbounds_table, to_outbound) + default_outTag = to_outbound.tag + end + end + end + if node.chain_proxy == "3" and node.outbound_iface then + outbound.detour = nil + outbound.bind_interface = node.outbound_iface + end + return default_outTag, last_insert_outbound + end + + function gen_outbound_get_tag(flag, node_id, tag, proxy_table) + if not node_id or node_id == "nil" then return nil end + local node + if type(node_id) == "string" then + node = get_node_by_id(node_id) + elseif type(node_id) == "table" then + node = node_id + end + if not tag then tag = node[".name"] end + if node then + if proxy_table.chain_proxy == "1" or proxy_table.chain_proxy == "2" then + node.chain_proxy = proxy_table.chain_proxy + node.preproxy_node = proxy_table.chain_proxy == "1" and proxy_table.preproxy_node + node.to_node = proxy_table.chain_proxy == "2" and proxy_table.to_node + proxy_table.chain_proxy = nil + proxy_table.preproxy_node = nil + proxy_table.to_node = nil + end + local outbound, exist + if node.protocol == "_urltest" then + outbound, exist = gen_urltest_outbound(node) + if exist then + return outbound.tag + end + elseif node.protocol == "_iface" then + if node.iface then + outbound = { + tag = tag, + type = "direct", + bind_interface = node.iface, + routing_mark = 255, + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) + end + else + if tag == "default" then + if default_node_address and default_node_port then + node.address = default_node_address + node.port = default_node_port + end + end + for _, _outbound in ipairs(outbounds) do + -- Avoid generating duplicate nested processes + if _outbound["_flag_proxy_tag"] and _outbound["_flag_proxy_tag"]:find("socks <- " .. node[".name"], 1, true) then + outbound = api.clone(_outbound) + outbound.tag = tag + break + end + end + if not outbound then + outbound = gen_outbound(flag, node, tag, proxy_table) + end + end + if outbound then + local default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) + table.insert(outbounds, outbound) + if last_insert_outbound then + table.insert(outbounds, last_insert_outbound) + end + return default_outbound_tag + end + end + end + + rules = {} + + if node.protocol == "_shunt" then + inner_fakedns = node.fakedns or "0" + + local function gen_shunt_node(rule_name, _node_id) + if not rule_name then return nil end + if not _node_id then _node_id = node[rule_name] end + if _node_id == "_direct" then + return "direct" + elseif _node_id == "_blackhole" then + return "block" + elseif _node_id == "_default" and rule_name ~= "default" then + return "default" + elseif _node_id then + local proxy_table = { + fragment = singbox_settings.fragment == "1", + record_fragment = singbox_settings.record_fragment == "1", + run_socks_instance = not no_run, + } + local preproxy_node_id = node[rule_name .. "_proxy_tag"] + if preproxy_node_id == _node_id then preproxy_node_id = nil end + if preproxy_node_id then + proxy_table.chain_proxy = "2" + proxy_table.to_node = _node_id + return gen_outbound_get_tag(flag, preproxy_node_id, rule_name, proxy_table) + else + return gen_outbound_get_tag(flag, _node_id, rule_name, proxy_table) + end + end + return nil + end + + --default_node + local default_node_id = node.default_node or "_direct" + COMMON.default_outbound_tag = gen_shunt_node("default", default_node_id) + + if inner_fakedns == "1" and node["default_fakedns"] == "1" then + remote_dns_fake = true + end + + --shunt rule + uci:foreach(appname, "shunt_rules", function(e) + local outboundTag = gen_shunt_node(e[".name"]) + if outboundTag and e.remarks then + if outboundTag == "default" then + outboundTag = COMMON.default_outbound_tag + end + local protocols = nil + if e["protocol"] and e["protocol"] ~= "" then + protocols = {} + string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) + table.insert(protocols, w) + end) + end + + local inboundTag = nil + if e["inbound"] and e["inbound"] ~= "" then + inboundTag = {} + if e["inbound"]:find("tproxy") then + if redir_port then + if tcp_proxy_way == "tproxy" then + table.insert(inboundTag, "tproxy") + else + table.insert(inboundTag, "redirect_tcp") + table.insert(inboundTag, "tproxy_udp") + end + end + end + if e["inbound"]:find("socks") then + if local_socks_port then + table.insert(inboundTag, "socks-in") + end + end + end + + local rule = { + action = "route", + inbound = inboundTag, + outbound = outboundTag, + protocol = protocols + } + + if outboundTag == "block" then + rule.action = "reject" + rule.outbound = nil + end + + if e.network then + local network = {} + string.gsub(e.network, '[^' .. "," .. ']+', function(w) + table.insert(network, w) + end) + rule.network = network + end + + if e.source then + local source_ip_cidr = {} + local source_is_private = false + string.gsub(e.source, '[^' .. " " .. ']+', function(w) + if w:find("geoip:") == 1 then + local _geoip = w:sub(1 + #"geoip:") + if _geoip == "private" then + source_is_private = true + end + else + table.insert(source_ip_cidr, w) + end + end) + rule.source_ip_cidr = #source_ip_cidr > 0 and source_ip_cidr or nil + rule.source_ip_is_private = source_is_private and true or nil + end + + --[[ + -- Too low usage rate, hidden + if e.sourcePort then + local source_port = {} + local source_port_range = {} + string.gsub(e.sourcePort, '[^' .. "," .. ']+', function(w) + if tonumber(w) and tonumber(w) >= 1 and tonumber(w) <= 65535 then + table.insert(source_port, tonumber(w)) + else + table.insert(source_port_range, w) + end + end) + rule.source_port = #source_port > 0 and source_port or nil + rule.source_port_range = #source_port_range > 0 and source_port_range or nil + end + ]]-- + + if e.port then + local port = {} + local port_range = {} + string.gsub(e.port, '[^' .. "," .. ']+', function(w) + if tonumber(w) and tonumber(w) >= 1 and tonumber(w) <= 65535 then + table.insert(port, tonumber(w)) + else + table.insert(port_range, w) + end + end) + rule.port = #port > 0 and port or nil + rule.port_range = #port_range > 0 and port_range or nil + end + + local rule_set = {} + + if e.domain_list then + local domain_table = { + shunt_tag = e[".name"], + outboundTag = outboundTag, + domain = {}, + domain_suffix = {}, + domain_keyword = {}, + domain_regex = {}, + rule_set = {}, + fakedns = nil, + invert = e.invert == "1" and true or nil + } + string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("geosite:") == 1 then + local _geosite = w:sub(1 + #"geosite:") + local t = geo_rule_set("geosite", _geosite) + if t then + GEO_VAR.SITE_TAGS[_geosite] = true + add_rule_set(t) + table.insert(rule_set, t.tag) + table.insert(domain_table.rule_set, t.tag) + end + elseif w:find("regexp:") == 1 then + table.insert(domain_table.domain_regex, w:sub(1 + #"regexp:")) + elseif w:find("full:") == 1 then + table.insert(domain_table.domain, w:sub(1 + #"full:")) + elseif w:find("domain:") == 1 then + table.insert(domain_table.domain_suffix, w:sub(1 + #"domain:")) + elseif w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then + w = w:sub(w:find(":") + 1, #w) + local t = parse_rule_set(w, true) + if t then + add_rule_set(t) + table.insert(rule_set, t.tag) + table.insert(domain_table.rule_set, t.tag) + end + else + table.insert(domain_table.domain_keyword, w) + end + end) + rule.domain = #domain_table.domain > 0 and domain_table.domain or nil + rule.domain_suffix = #domain_table.domain_suffix > 0 and domain_table.domain_suffix or nil + rule.domain_keyword = #domain_table.domain_keyword > 0 and domain_table.domain_keyword or nil + rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil + rule.rule_set = #domain_table.rule_set > 0 and domain_table.rule_set or nil + if inner_fakedns == "1" and node[e[".name"] .. "_fakedns"] == "1" then + domain_table.fakedns = true + end + + if outboundTag then + table.insert(dns_domain_rules, api.clone(domain_table)) + end + end + + if e.ip_list then + local ip_cidr = {} + local is_private = false + string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("geoip:") == 1 then + local _geoip = w:sub(1 + #"geoip:") + if _geoip == "private" then + is_private = true + else + local t = geo_rule_set("geoip", _geoip) + if t then + GEO_VAR.IP_TAGS[_geoip] = true + add_rule_set(t) + table.insert(rule_set, t.tag) + end + end + elseif w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then + w = w:sub(w:find(":") + 1, #w) + local t = parse_rule_set(w, true) + if t then + add_rule_set(t) + table.insert(rule_set, t.tag) + end + else + table.insert(ip_cidr, w) + end + end) + + rule.ip_is_private = is_private and true or nil + rule.ip_cidr = #ip_cidr > 0 and ip_cidr or nil + end + rule.rule_set = #rule_set > 0 and rule_set or nil + rule.invert = e.invert == "1" and true or nil + + table.insert(rules, rule) + end + end) + end + + for index, value in ipairs(rules) do + table.insert(route.rules, rules[index]) + end + end + + if COMMON.default_outbound_tag then + route.final = COMMON.default_outbound_tag + end + + dns = { + servers = {}, + rules = {}, + disable_cache = (dns_cache and dns_cache == "0") and true or false, + disable_expire = false, -- Disable DNS cache expiration. + independent_cache = false, -- Make each DNS server's cache independent for specific purposes. If enabled, it will slightly reduce performance. + reverse_mapping = true, -- After responding to a DNS query, a reverse mapping of the IP address is stored to provide the domain name for routing purposes. + } + + table.insert(dns.servers, { + type = "local", + tag = "local" + }) + + route.default_domain_resolver = { + server = "local" + } + + if direct_dns_udp_server then + table.insert(dns.servers, { + tag = "direct", + type = "udp", + server = direct_dns_udp_server, + server_port = tonumber(direct_dns_udp_port) or 53, + detour = "direct", + }) + end + + for i, v in pairs(GLOBAL.DNS_SERVER) do + if direct_dns_udp_server then + v.server.domain_resolver = "direct" + end + table.insert(dns.servers, v.server) + table.insert(dns.rules, { + action = "route", + server = v.server.tag, + domain = v.domain, + }) + end + + local direct_strategy = "prefer_ipv6" + if direct_dns_query_strategy == "UseIPv4" then + direct_strategy = "ipv4_only" + elseif direct_dns_query_strategy == "UseIPv6" then + direct_strategy = "ipv6_only" + end + + if dns_listen_port then + local dns_host = "" + if flag == "global" then + dns_host = uci:get(appname, "@global[0]", "dns_hosts") or "" + else + flag = flag:gsub("acl_", "") + local dns_hosts_mode = uci:get(appname, flag, "dns_hosts_mode") or "default" + if dns_hosts_mode == "default" then + dns_host = uci:get(appname, "@global[0]", "dns_hosts") or "" + elseif dns_hosts_mode == "disable" then + dns_host = "" + elseif dns_hosts_mode == "custom" then + dns_host = uci:get(appname, flag, "dns_hosts") or "" + end + end + if #dns_host > 0 then + local domains = {} + local hosts_server = { + tag = "hosts", + type = "hosts", + predefined = {} + } + string.gsub(dns_host, '[^' .. "\r\n" .. ']+', function(w) + local host = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $1}')", w)) + local key = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $2}')", w)) + if host ~= "" and key ~= "" then + hosts_server.predefined[host] = key + table.insert(domains, host) + end + end) + if remote_dns_doh_ip and remote_dns_doh_host ~= remote_dns_doh_ip and not api.is_ip(remote_dns_doh_host) then + hosts_server.predefined[remote_dns_doh_host] = remote_dns_doh_ip + table.insert(domains, remote_dns_doh_host) + remote_server_domain_resolver = "hosts" + end + if next(hosts_server.predefined) then + table.insert(dns.servers, hosts_server) + table.insert(dns.rules, { + query_type = { + "A", "AAAA" + }, + domain = domains, + server = "hosts" + }) + end + end + + if direct_dns_udp_server then + local nodes_domain = {} + local nodes_domain_text = sys.exec('uci show passwall2 | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u') + string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) + w = (w or ""):lower() + table.insert(nodes_domain, w) + end) + if #nodes_domain > 0 then + table.insert(dns_domain_rules, 1, { + domain = nodes_domain, + outboundTag = "direct" + }) + end + end + + remote_strategy = "prefer_ipv6" + if remote_dns_query_strategy == "UseIPv4" then + remote_strategy = "ipv4_only" + elseif remote_dns_query_strategy == "UseIPv6" then + remote_strategy = "ipv6_only" + end + + local remote_server = { + tag = "remote", + domain_resolver = "direct", + detour = COMMON.default_outbound_tag, + } + + if remote_server_domain_resolver then + remote_server.domain_resolver = remote_server_domain_resolver + end + + if remote_dns_detour == "direct" then + remote_server.detour = "direct" + end + + if remote_dns_udp_server then + local server_port = tonumber(remote_dns_udp_port) or 53 + remote_server.type = "udp" + remote_server.server = remote_dns_udp_server + remote_server.server_port = server_port + if remote_dns_quic then + remote_server.type = "quic" + remote_server.server_port = 853 + end + elseif remote_dns_tcp_server then + local server_port = tonumber(remote_dns_tcp_port) or 53 + remote_server.type = "tcp" + remote_server.server = remote_dns_tcp_server + remote_server.server_port = server_port + if remote_dns_tls then + remote_server.type = "tls" + remote_server.server_port = 853 + end + elseif remote_dns_doh_url then + local _a = api.parseURL(remote_dns_doh_url) + if _a then + remote_server.type = "https" + if remote_dns_http3 then + remote_server.type = "h3" + end + remote_server.server = _a.hostname + if _a.port then + remote_server.server_port = _a.port + else + remote_server.server_port = 443 + end + remote_server.path = _a.pathname + end + end + + table.insert(dns.servers, remote_server) + + fakedns_tag = "remote_fakeip" + if remote_dns_fake or inner_fakedns == "1" then + table.insert(dns.servers, { + tag = fakedns_tag, + type = "fakeip", + inet4_range = "198.18.0.0/16", + inet6_range = "fc00::/18", + }) + + if not experimental then + experimental = {} + end + experimental.cache_file = { + enabled = true, + store_fakeip = true, + path = CACHE_PATH .. "/singbox_" .. flag .. ".db" + } + end + + local default_dns_flag = "remote" + if node_id and redir_port then + local node = get_node_by_id(node_id) + if node.protocol == "_shunt" then + if node.default_node == "_direct" then + default_dns_flag = "direct" + end + end + else default_dns_flag = "direct" + end + dns.final = default_dns_flag + + -- DNS in order of shunt + if dns_domain_rules and #dns_domain_rules > 0 then + for index, value in ipairs(dns_domain_rules) do + if value.outboundTag and (value.domain or value.domain_suffix or value.domain_keyword or value.domain_regex or value.rule_set) then + local dns_rule = { + action = "route", + server = value.server or value.outboundTag, + domain = (value.domain and #value.domain > 0) and value.domain or nil, + domain_suffix = (value.domain_suffix and #value.domain_suffix > 0) and value.domain_suffix or nil, + domain_keyword = (value.domain_keyword and #value.domain_keyword > 0) and value.domain_keyword or nil, + domain_regex = (value.domain_regex and #value.domain_regex > 0) and value.domain_regex or nil, + rule_set = (value.rule_set and #value.rule_set > 0) and value.rule_set or nil, + disable_cache = false, + invert = value.invert, + } + if value.outboundTag == "block" then + dns_rule.action = "predefined" + dns_rule.rcode = "NOERROR" + dns_rule.disable_cache = nil + dns_rule.server = nil + end + if value.outboundTag == "direct" then + dns_rule.strategy = direct_strategy + end + if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then + dns_rule.server = "remote" + dns_rule.rewrite_ttl = 30 + dns_rule.strategy = remote_strategy + dns_rule.client_subnet = remote_dns_client_ip + if value.outboundTag ~= COMMON.default_outbound_tag and remote_server.server and remote_dns_detour ~= "direct" then + local remote_dns_server = api.clone(remote_server) + remote_dns_server.tag = value.shunt_tag + remote_dns_server.detour = value.outboundTag + table.insert(dns.servers, remote_dns_server) + dns_rule.server = remote_dns_server.tag + end + if value.fakedns then + local fakedns_dns_rule = api.clone(dns_rule) + fakedns_dns_rule.query_type = { + "A", "AAAA" + } + fakedns_dns_rule.server = fakedns_tag + fakedns_dns_rule.disable_cache = true + fakedns_dns_rule.client_subnet = nil + table.insert(dns.rules, fakedns_dns_rule) + end + end + table.insert(dns.rules, dns_rule) + end + end + end + if default_dns_flag == "remote" then + if remote_dns_fake then + -- When default is not direct and enable fakedns, default DNS use FakeDNS. + local fakedns_dns_rule = { + query_type = { + "A", "AAAA" + }, + server = fakedns_tag, + disable_cache = true, + rewrite_ttl = 30, + strategy = remote_strategy, + } + table.insert(dns.rules, fakedns_dns_rule) + else + local remote_dns_rule = { + server = "remote", + disable_cache = true, + strategy = remote_strategy, + } + table.insert(dns.rules, remote_dns_rule) + end + end + local dns_in_inbound = { + type = "direct", + tag = "dns-in", + listen = "127.0.0.1", + listen_port = tonumber(dns_listen_port), + } + table.insert(inbounds, dns_in_inbound) + table.insert(route.rules, 1, { + action = "sniff", + inbound = dns_in_inbound.tag + }) + table.insert(route.rules, 1, { + action = "hijack-dns", + inbound = dns_in_inbound.tag + }) + + local content = flag .. node_id .. jsonc.stringify(route.rules) + if api.cacheFileCompareToLogic(CACHE_TEXT_FILE, content) == false then + --clear ipset/nftset + if direct_ipset then + string.gsub(direct_ipset, '[^' .. "," .. ']+', function(w) + sys.call("ipset -q -F " .. w) + end) + local ipset_prefix_name = "psw2_" .. node_id .. "_" + local ipset_list = sys.exec("ipset list | grep 'Name: ' | grep '" .. ipset_prefix_name .. "' | awk '{print $2}'") + string.gsub(ipset_list, '[^' .. "\r\n" .. ']+', function(w) + sys.call("ipset -q -F " .. w) + end) + end + if direct_nftset then + string.gsub(direct_nftset, '[^' .. "," .. ']+', function(w) + local split = api.split(w, "#") + if #split > 3 then + local ip_type = split[1] + local family = split[2] + local table_name = split[3] + local set_name = split[4] + sys.call(string.format("nft flush set %s %s %s 2>/dev/null", family, table_name, set_name)) + end + end) + local family = "inet" + local table_name = "passwall2" + local nftset_prefix_name = "psw2_" .. node_id .. "_" + local nftset_list = sys.exec("nft -a list sets | grep -E '" .. nftset_prefix_name .. "' | awk -F 'set ' '{print $2}' | awk '{print $1}'") + string.gsub(nftset_list, '[^' .. "\r\n" .. ']+', function(w) + sys.call(string.format("nft flush set %s %s %s 2>/dev/null", family, table_name, w)) + end) + end + end + end + + if next(ech_domain) ~= nil then + table.insert(dns.servers, { + tag = "ech-dns", + type = "https", + server = "223.5.5.5" + }) + if not dns.rules then dns.rules = {} end + local domain = {} + for line, _ in pairs(ech_domain) do domain[#domain+1] = line end + table.insert(dns.rules, 1, { + domain = domain, + server = "ech-dns" + }) + end + + if COMMON.default_outbound_tag == "block" then + route.final = nil + table.insert(route.rules, { + action = "reject" + }) + end + + if next(rule_set_table) then + route.rule_set = {} + for k, v in pairs(rule_set_table) do + table.insert(route.rule_set, v) + end + end + + if inbounds or outbounds then + local config = { + log = { + disabled = log == "0" and true or false, + level = loglevel, + timestamp = true, + output = logfile, + }, + dns = dns, + inbounds = inbounds, + outbounds = outbounds, + route = route, + experimental = experimental, + } + table.insert(outbounds, { + type = "direct", + tag = "direct", + routing_mark = 255, + }) + for index, value in ipairs(config.outbounds) do + if not value["_flag_proxy_tag"] and not value.detour and value["_id"] and value.server and value.server_port and not no_run then + sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list")) + end + if not value.detour and not value.bind_interface and value.server then + value.detour = "direct" + end + if (value.server and not api.datatypes.hostname(value.server)) and not value.realm then + value.domain_resolver = nil + end + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + end + if true then + local endpoints = {} + for i = #config.outbounds, 1, -1 do + local value = config.outbounds[i] + if value.type == "wireguard" then + -- https://sing-box.sagernet.org/migration/#migrate-wireguard-outbound-to-endpoint + local endpoint = { + type = value.type, + tag = value.tag, + system = value.system_interface, + name = value.interface_name, + mtu = value.mtu, + address = value.local_address, + private_key = value.private_key, + peers = { + { + address = value.server, + port = value.server_port, + public_key = value.peer_public_key, + pre_shared_key = value.pre_shared_key, + allowed_ips = {"0.0.0.0/0"}, + reserved = value.reserved + } + }, + domain_resolver = value.domain_resolver, + detour = value.detour + } + endpoints[#endpoints + 1] = endpoint + table.remove(config.outbounds, i) + end + end + if #endpoints > 0 then + config.endpoints = endpoints + end + end + return jsonc.stringify(config, 1) + end +end + +function gen_proto_config(var) + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local server_proto = var["server_proto"] + local server_address = var["server_address"] + local server_port = var["server_port"] + local server_username = var["server_username"] + local server_password = var["server_password"] + + local inbounds = {} + local outbounds = {} + + if local_socks_address and local_socks_port then + local inbound = { + type = "socks", + tag = "socks-in", + listen = local_socks_address, + listen_port = tonumber(local_socks_port), + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.users = { + username = local_socks_username, + password = local_socks_password + } + end + table.insert(inbounds, inbound) + end + + if local_http_address and local_http_port then + local inbound = { + type = "http", + tag = "http-in", + tls = nil, + listen = local_http_address, + listen_port = tonumber(local_http_port), + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.users = { + { + username = local_http_username, + password = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then + local outbound = { + type = server_proto, + tag = "out", + server = server_address, + server_port = tonumber(server_port), + username = (server_username and server_password) and server_username or nil, + password = (server_username and server_password) and server_password or nil, + } + if outbound then table.insert(outbounds, outbound) end + end + + local config = { + log = { + disabled = true, + level = "warn", + timestamp = true, + }, + inbounds = inbounds, + outbounds = outbounds, + } + return jsonc.stringify(config, 1) +end + +function gen_front_dns_config(var) + local dns_listen_port = var["dns_listen_port"] + local direct_dns_udp_server = var["direct_dns_udp_server"] + local direct_dns_udp_port = var["direct_dns_udp_port"] + local direct_dns_query_strategy = var["direct_dns_query_strategy"] + local default_dns_udp_server = var["default_dns_udp_server"] + local default_dns_udp_port = var["default_dns_udp_port"] + + local dns = { + servers = {}, + rules = {} + } + local inbounds = {} + local outbounds = {} + local route = {} + + local direct_strategy = "prefer_ipv6" + if direct_dns_query_strategy == "UseIPv4" then + direct_strategy = "ipv4_only" + elseif direct_dns_query_strategy == "UseIPv6" then + direct_strategy = "ipv6_only" + end + + table.insert(outbounds, { + type = "direct", + tag = "direct", + routing_mark = 255, + }) + + local direct_dns_shunt = uci:get(appname, "@global[0]", "direct_dns_shunt") or "" + if #direct_dns_shunt > 0 then + local dns_server = {} + string.gsub(direct_dns_shunt, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + local domain = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $1}')", w)) + local dns = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $2}')", w)) + if domain ~= "" and dns ~= "" then + local new_dns_server = parseDNS(dns) + if new_dns_server then + if not dns_server[dns] then + dns_server[dns] = {} + end + if not dns_server[dns].server then + dns_server[dns].server = new_dns_server + dns_server[dns].server.tag = dns + dns_server[dns].server.detour = "direct" + end + if not dns_server[dns].rule then + dns_server[dns].rule = { + action = "route", + server = dns, + domain = {}, + domain_suffix = {}, + domain_keyword = {} + } + end + if domain:find("full:") == 1 then + table.insert(dns_server[dns].rule.domain, domain:sub(1 + #"full:")) + elseif domain:find("domain:") == 1 then + table.insert(dns_server[dns].rule.domain_suffix, domain:sub(1 + #"domain:")) + else + table.insert(dns_server[dns].rule.domain_keyword, domain) + end + end + end + end) + for k, v in pairs(dns_server) do + table.insert(dns.servers, v.server) + if #v.rule.domain == 0 then v.rule.domain = nil end + if #v.rule.domain_suffix == 0 then v.rule.domain_suffix = nil end + if #v.rule.domain_keyword == 0 then v.rule.domain_keyword = nil end + table.insert(dns.rules, v.rule) + end + end + + if direct_dns_udp_server then + table.insert(dns.servers, { + tag = "direct", + type = "udp", + server = direct_dns_udp_server, + server_port = tonumber(direct_dns_udp_port) or 53, + detour = "direct" + }) + local node_domain = {} + local nodes_domain_text = sys.exec('uci show passwall2 | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u') + string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) + w = (w or ""):lower() + table.insert(node_domain, w) + end) + if #node_domain > 0 then + table.insert(dns.rules, { + action = "route", + server = "direct", + domain = node_domain + }) + end + route.default_domain_resolver = { + server = "direct", + strategy = direct_strategy + } + end + + if default_dns_udp_server then + table.insert(dns.servers, { + tag = "default", + type = "udp", + server = default_dns_udp_server, + server_port = tonumber(default_dns_udp_port) or 53, + detour = "direct" + }) + dns.final = "default" + else + dns.final = "direct" + end + + local dns_in_inbound = { + type = "direct", + tag = "dns-in", + listen = "127.0.0.1", + listen_port = tonumber(dns_listen_port), + } + table.insert(inbounds, dns_in_inbound) + + route.rules = {} + table.insert(route.rules, { + action = "hijack-dns", + inbound = dns_in_inbound.tag + }) + table.insert(route.rules, { + action = "sniff", + inbound = dns_in_inbound.tag + }) + route.final = "direct" + + local config = { + log = { + disabled = true, + level = "debug", + timestamp = true, + }, + dns = dns, + inbounds = inbounds, + outbounds = outbounds, + route = route + } + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config +_G.gen_front_dns_config = gen_front_dns_config +_G.gen_proto_config = gen_proto_config +_G.geo_convert_srs = geo_convert_srs + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + if (next(GEO_VAR.SITE_TAGS) or next(GEO_VAR.IP_TAGS)) and not no_run then + convert_geofile() + end + end +end diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua new file mode 100644 index 00000000..b674e971 --- /dev/null +++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua @@ -0,0 +1,2285 @@ +module("luci.passwall2.util_xray", package.seeall) +local api = require "luci.passwall2.api" +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local appname = api.appname +local fs = api.fs +local CACHE_PATH = api.CACHE_PATH + +local GLOBAL = { + DNS_SERVER = {}, + DNS_HOSTNAME = {} +} + +local xray_version = api.get_app_version("xray") + +local function get_domain_excluded() + local path = string.format("/usr/share/%s/domains_excluded", appname) + local content = fs.readfile(path) + if not content then return nil end + local hosts = {} + string.gsub(content, '[^' .. "\n" .. ']+', function(w) + local s = api.trim(w) + if s == "" then return end + if s:find("#") and s:find("#") == 1 then return end + if not s:find("#") or s:find("#") ~= 1 then table.insert(hosts, s) end + end) + if #hosts == 0 then hosts = nil end + return hosts +end + +function parseDNS(str) + local result_dns_server + -- [proto]://[ip] + -- [proto]://[ip]:[port] + -- https://[ip]/[path] + -- https://[ip]:[port]/[path] + local _a = api.parseURL(str) + if _a then + if _a.protocol == "tcp" or _a.protocol == "udp" or _a.protocol == "https" then + result_dns_server = { + address = str + } + if _a.protocol == "udp" then + result_dns_server.address = _a.hostname + end + if _a.port then + result_dns_server.port = _a.port + else + if _a.protocol == "https" then + result_dns_server.port = 443 + else + result_dns_server.port = 53 + end + end + end + end + return result_dns_server +end + +function gen_outbound(flag, node, tag, proxy_table) + local result = nil + if node then + local node_id = node[".name"] + if tag == nil then + tag = node_id + end + local remarks = node.remarks + + local proxy_tag = nil + local fragment = nil + local noise = nil + local run_socks_instance = true + if proxy_table ~= nil and type(proxy_table) == "table" then + proxy_tag = proxy_table.tag or nil + fragment = proxy_table.fragment or nil + noise = proxy_table.noise or nil + run_socks_instance = proxy_table.run_socks_instance + end + + if node.type ~= "Xray" then + local relay_port = node.port + local new_port = api.get_new_port() + local config_file = string.format("%s_%s_%s.json", flag, tag, new_port) + if tag and node_id and not tag:find(node_id) then + config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port) + end + if run_socks_instance then + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s", + new_port, --flag + node_id, --node + "127.0.0.1", --bind + new_port, --socks port + config_file, --config file + (proxy_tag and relay_port) and tostring(relay_port) or "" --relay port + ) + ) + ) + end + node = {} + node.protocol = "socks" + node.transport = "tcp" + node.address = "127.0.0.1" + node.port = new_port + node.stream_security = "none" + proxy_tag = "socks <- " .. node_id + else + if proxy_tag then + node.proxySettings = { + tag = proxy_tag, + transportLayer = true + } + end + end + + if node.type == "Xray" then + if node.tls and node.tls == "1" then + node.stream_security = "tls" + if node.reality and node.reality == "1" then + node.stream_security = "reality" + end + end + end + + if node.protocol == "wireguard" and node.wireguard_reserved then + local bytes = {} + if not node.wireguard_reserved:match("[^%d,]+") then + node.wireguard_reserved:gsub("%d+", function(b) + bytes[#bytes + 1] = tonumber(b) + end) + else + local result = api.base64Decode(node.wireguard_reserved) + for i = 1, #result do + bytes[i] = result:byte(i) + end + end + node.wireguard_reserved = #bytes > 0 and bytes or nil + end + + if node.protocol == "hysteria2" then + node.protocol = "hysteria" + node.transport = "hysteria" + node.stream_security = "tls" + end + + if remarks then + tag = tag .. ":" .. remarks + end + + node.address = (node.address or ""):lower() + + result = { + _id = node_id, + _flag = flag, + _flag_proxy_tag = proxy_tag, + tag = tag, + proxySettings = node.proxySettings or nil, + protocol = node.protocol, + mux = { + enabled = (node.mux == "1") and true or false, + concurrency = (node.mux == "1" and ((node.mux_concurrency) and tonumber(node.mux_concurrency) or -1)) or nil, + xudpConcurrency = (node.mux == "1" and ((node.xudp_concurrency) and tonumber(node.xudp_concurrency) or 8)) or nil + } or nil, + streamSettings = (node.streamSettings or node.protocol == "vmess" or node.protocol == "vless" or node.protocol == "socks" or node.protocol == "shadowsocks" or node.protocol == "trojan" or node.protocol == "hysteria") and { + sockopt = { + mark = 255, + domainStrategy = node.domain_strategy or "UseIP", + tcpFastOpen = (node.tcp_fast_open == "1") and true or nil, + tcpMptcp = (node.tcpMptcp == "1") and true or nil + }, + network = node.transport, + security = node.stream_security, + tlsSettings = (node.stream_security == "tls") and { + serverName = node.tls_serverName, + allowInsecure = (function() + if node.tls_pinSHA256 and node.tls_pinSHA256 ~= "" then return nil end + if api.compare_versions(os.date("%Y.%m.%d"), "<", "2026.6.1") and node.tls_allowInsecure == "1" then return true end + end)(), + fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil, + pinnedPeerCertSha256 = (function() + if api.compare_versions(xray_version, "<", "26.1.31") then return nil end + if not node.tls_pinSHA256 then return "" end + return node.tls_pinSHA256 + end)(), + verifyPeerCertByName = (function() + if api.compare_versions(xray_version, "<", "26.1.31") then return nil end + if not node.tls_CertByName then return "" end + return node.tls_CertByName + end)(), + echConfigList = (node.ech == "1") and node.ech_config or nil + } or nil, + realitySettings = (node.stream_security == "reality") and { + serverName = node.tls_serverName, + publicKey = node.reality_publicKey, + shortId = node.reality_shortId or "", + spiderX = node.reality_spiderX or "/", + fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome", + mldsa65Verify = (node.use_mldsa65Verify == "1") and node.reality_mldsa65Verify or nil + } or nil, + rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and { + header = { + type = node.tcp_guise, + request = (node.tcp_guise == "http") and { + path = node.tcp_guise_http_path and (function() + local t, r = node.tcp_guise_http_path, {} + for _, v in ipairs(t) do + r[#r + 1] = (v == "" and "/" or v) + end + return r + end)() or {"/"}, + headers = (node.tcp_guise_http_host or node.user_agent) and { + Host = node.tcp_guise_http_host, + ["User-Agent"] = node.user_agent and {node.user_agent} or nil + } or nil + } or nil + } + } or nil, + kcpSettings = (node.transport == "mkcp") and { + mtu = (node.mkcp_mtu and node.mkcp_mtu ~= "") and tonumber(node.mkcp_mtu) or 1350, + tti = 50, + uplinkCapacity = 12, + downlinkCapacity = 100, + CwndMultiplier = 1, + MaxSendingWindow = 2 * 1024 * 1024 + } or nil, + wsSettings = (node.transport == "ws") and { + path = node.ws_path or "/", + host = node.ws_host, + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil, + maxEarlyData = tonumber(node.ws_maxEarlyData) or nil, + earlyDataHeaderName = (node.ws_earlyDataHeaderName) and node.ws_earlyDataHeaderName or nil, + heartbeatPeriod = tonumber(node.ws_heartbeatPeriod) or nil + } or nil, + grpcSettings = (node.transport == "grpc") and { + serviceName = node.grpc_serviceName, + multiMode = (node.grpc_mode == "multi") and true or false, + idle_timeout = node.grpc_idle_timeout and (tonumber(node.grpc_idle_timeout) < 10 and 10 or tonumber(node.grpc_idle_timeout)) or nil, + health_check_timeout = tonumber(node.grpc_health_check_timeout) or nil, + permit_without_stream = (node.grpc_permit_without_stream == "1") and true or false, + initial_windows_size = node.grpc_initial_windows_size and tonumber(node.grpc_initial_windows_size) or 0, + user_agent = node.user_agent + } or nil, + httpupgradeSettings = (node.transport == "httpupgrade") and { + path = node.httpupgrade_path or "/", + host = node.httpupgrade_host, + headers = node.user_agent and { + ["User-Agent"] = node.user_agent + } or nil + } or nil, + xhttpSettings = (node.transport == "xhttp") and { + mode = node.xhttp_mode or "auto", + path = node.xhttp_path or "/", + host = node.xhttp_host, + extra = (function() + local extra = {} + if node.xhttp_extra then + local ok, parsed = pcall(jsonc.parse, api.base64Decode(node.xhttp_extra)) + if ok and type(parsed) == "table" then + extra = parsed.extra or parsed + end + end + -- Handling User-Agent + if node.user_agent and node.user_agent ~= "" then + extra.headers = extra.headers or {} + if not extra.headers["User-Agent"] and not extra.headers["user-agent"] then + extra.headers["User-Agent"] = node.user_agent + end + end + return api.cleanEmptyTables(extra) + end)() + } or nil, + hysteriaSettings = (node.transport == "hysteria") and { + version = 2, + auth = node.hysteria2_auth_password + } or nil, + finalmask = (function() + local finalmask = {} + local TP = node.transport + if TP == "mkcp" then + local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", + dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local udp = {} + if node.mkcp_guise and node.mkcp_guise ~= "none" then + local g = { type = map[node.mkcp_guise] } + if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then + g.settings = { domain = node.mkcp_domain } + end + udp[#udp+1] = g + end + local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + if node.mkcp_seed and node.mkcp_seed ~= "" then + c.settings = { password = node.mkcp_seed } + end + udp[#udp+1] = c + finalmask.udp = udp + elseif TP == "hysteria" then + if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then + finalmask.udp = {{ + type = node.hysteria2_obfs_type, + settings = node.hysteria2_obfs_password and { + password = node.hysteria2_obfs_password + } or nil + }} + end + local up = tonumber(node.hysteria2_up_mbps) or 0 + local down = tonumber(node.hysteria2_down_mbps) or 0 + finalmask.quicParams = { + congestion = (up <= 0 and down <= 0) and "bbr" or "brutal", + brutalUp = up > 0 and (up .. "mbps") or nil, + brutalDown = down > 0 and (down .. "mbps") or nil, + udpHop = (node.hysteria2_hop) and { + ports = string.gsub(node.hysteria2_hop, ":", "-"), + interval = (function(v) + if not v then return 30 end + if v:find("-", 1, true) then + local min, max = v:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + return min .. "-" .. max + end + return 30 + end + v = tonumber((v or "30"):match("^%d+")) + return (v and v >= 5) and v or 30 + end)(node.hysteria2_hop_interval) + } or nil, + maxIdleTimeout = (function(t) + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t or 30 + end)(node.hysteria2_idle_timeout), + keepAlivePeriod = (function(t) + t = tonumber(tostring(t or "0"):match("^%d+")) + return (t and t >= 2 and t <= 60) and t or nil + end)(node.hysteria2_keep_alive_period), + disablePathMTUDiscovery = tonumber(node.hysteria2_disable_mtu_discovery) == 1 + } + end + if fragment and fragment_table and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then + finalmask.tcp = finalmask.tcp or {} + finalmask.tcp[#finalmask.tcp+1] = api.clone(fragment_table) + end + if noise and noise_table and (TP == "mkcp" or (TP == "xhttp" and node.alpn == "h3")) then + finalmask.udp = finalmask.udp or {} + finalmask.udp[#finalmask.udp+1] = api.clone(noise_table) + end + if node.finalmask and node.finalmask ~= "" then + local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) + if ok and type(fm) == "table" then + finalmask = fm + end + end + return api.cleanEmptyTables(finalmask) + end)() + } or nil, + settings = { + vnext = (node.protocol == "vmess" or node.protocol == "vless") and { + { + address = node.address, + port = tonumber(node.port), + users = { + { + id = node.uuid, + level = 0, + security = (node.protocol == "vmess") and node.security or nil, + testpre = (node.protocol == "vless") and tonumber(node.preconns) or nil, + encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil, + flow = (node.protocol == "vless" + and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none")) + and node.flow and node.flow ~= "") and node.flow or nil + } + } + } + } or nil, + servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { + { + address = node.address, + port = tonumber(node.port), + method = (node.method == "chacha20-ietf-poly1305" and "chacha20-poly1305") or + (node.method == "xchacha20-ietf-poly1305" and "xchacha20-poly1305") or + (node.method ~= "" and node.method) or nil, + ivCheck = (node.protocol == "shadowsocks") and node.iv_check == "1" or nil, + uot = (node.protocol == "shadowsocks") and node.uot == "1" or nil, + password = node.password or "", + users = (node.username and node.password) and { + { + user = node.username, + pass = node.password + } + } or nil + } + } or nil, + address = (node.protocol == "wireguard" and node.wireguard_local_address) or (node.protocol == "hysteria" and node.address) or nil, + secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil, + peers = (node.protocol == "wireguard") and { + { + publicKey = node.wireguard_public_key, + endpoint = node.address .. ":" .. node.port, + preSharedKey = node.wireguard_preSharedKey, + keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil + } + } or nil, + mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil, + reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil, + port = (node.protocol == "hysteria" and node.port) and tonumber(node.port) or nil, + version = node.protocol == "hysteria" and 2 or nil + } + } + + if node.protocol == "wireguard" then + result.settings.kernelMode = false + end + + local alpn = {} + if node.alpn and node.alpn ~= "default" then + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + if alpn and #alpn > 0 then + if result.streamSettings.tlsSettings then + result.streamSettings.tlsSettings.alpn = alpn + end + end + + if api.datatypes.hostname(node.address) and node.domain_resolver and (node.domain_resolver_dns or node.domain_resolver_dns_https) then + local dns_tag = node_id .. "_dns" + local dns_proto = node.domain_resolver + local config_address + local config_port + if dns_proto == "https" then + local _a = api.parseURL(node.domain_resolver_dns_https) + if _a then + config_address = node.domain_resolver_dns_https + if _a.port then + config_port = _a.port + else + config_port = 443 + end + if _a.hostname then + if api.datatypes.hostname(_a.hostname) then + GLOBAL.DNS_HOSTNAME[_a.hostname] = true + end + end + end + else + local server_address = node.domain_resolver_dns + local config_port = 53 + local split = api.split(server_address, ":") + if #split > 1 then + server_address = split[1] + config_port = tonumber(split[#split]) + end + config_address = server_address + if dns_proto == "tcp" then + config_address = dns_proto .. "://" .. server_address .. ":" .. config_port + end + end + GLOBAL.DNS_SERVER[node_id] = { + tag = dns_tag, + queryStrategy = node.domain_strategy or "UseIP", + address = config_address, + port = config_port, + domains = {"full:" .. node.address}, + finalQuery = true, + disableCache = false, + serveStale = true, + } + end + + end + return result +end + +function gen_config_server(node) + local settings = nil + local routing = nil + local outbounds = { + { protocol = "freedom", tag = "direct", settings = { finalRules = {{ action = "allow" }}}}, { protocol = "blackhole", tag = "blocked" } + } + + if node.protocol == "vmess" or node.protocol == "vless" then + if node.uuid then + local clients = {} + for i = 1, #node.uuid do + clients[i] = { + id = node.uuid[i], + flow = (node.protocol == "vless" + and (node.tls == "1" or (node.decryption and node.decryption ~= "" and node.decryption ~= "none")) + and node.flow and node.flow ~= "") and node.flow or nil + } + end + settings = { + clients = clients, + decryption = (node.protocol == "vless") and ((node.decryption and node.decryption ~= "") and node.decryption or "none") or nil + } + end + elseif node.protocol == "socks" then + settings = { + udp = ("1" == node.udp_forward) and true or false, + auth = ("1" == node.auth) and "password" or "noauth", + accounts = ("1" == node.auth) and { + { + user = node.username, + pass = node.password + } + } or nil + } + elseif node.protocol == "http" then + settings = { + allowTransparent = false, + accounts = ("1" == node.auth) and { + { + user = node.username, + pass = node.password + } + } or nil + } + node.transport = "tcp" + node.tcp_guise = "none" + elseif node.protocol == "shadowsocks" then + settings = { + method = node.method, + password = node.password, + ivCheck = ("1" == node.iv_check) and true or false, + network = node.ss_network or "TCP,UDP" + } + elseif node.protocol == "trojan" then + if node.uuid then + local clients = {} + for i = 1, #node.uuid do + clients[i] = { + password = node.uuid[i] + } + end + settings = { + clients = clients + } + end + elseif node.protocol == "hysteria2" then + settings = { + version = 2, + clients = node.hysteria2_auth_password and { + { auth = node.hysteria2_auth_password } + } + } + elseif node.protocol == "dokodemo-door" then + settings = { + network = node.d_protocol, + address = node.d_address, + port = tonumber(node.d_port) + } + end + + if node.fallback and node.fallback == "1" then + local fallbacks = {} + for i = 1, #node.fallback_list do + local fallbackStr = node.fallback_list[i] + if fallbackStr then + local tmp = {} + string.gsub(fallbackStr, '[^,]+', function(w) + table.insert(tmp, w) + end) + local dest = tmp[1] or "" + local path = tmp[2] + local xver = tonumber(tmp[3]) + if not dest:find("%.") then + dest = tonumber(dest) + end + fallbacks[i] = { + path = path, + dest = dest, + xver = xver + } + end + end + settings.fallbacks = fallbacks + end + + routing = { + domainStrategy = "IPOnDemand", + rules = { + { + ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, + outboundTag = (node.accept_lan == nil or node.accept_lan == "0") and "blocked" or "direct" + } + } + } + + if node.outbound_node then + local outbound = nil + if node.outbound_node == "_iface" and node.outbound_node_iface then + outbound = { + protocol = "freedom", + tag = "outbound", + streamSettings = { + sockopt = { + mark = 255, + interface = node.outbound_node_iface + } + }, + settings = { + finalRules = {{ action = "allow" }} + } + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface)) + else + local outbound_node_t = uci:get_all("passwall2", node.outbound_node) + if node.outbound_node == "_socks" or node.outbound_node == "_http" then + outbound_node_t = { + type = node.type, + protocol = node.outbound_node:gsub("_", ""), + transport = "tcp", + address = node.outbound_node_address, + port = node.outbound_node_port, + username = (node.outbound_node_username and node.outbound_node_username ~= "") and node.outbound_node_username or nil, + password = (node.outbound_node_password and node.outbound_node_password ~= "") and node.outbound_node_password or nil, + } + end + outbound = require("luci.passwall2.util_xray").gen_outbound(nil, outbound_node_t, "outbound") + end + if outbound then + table.insert(outbounds, 1, outbound) + end + end + + if node.protocol == "hysteria2" then + node.protocol = "hysteria" + node.transport = "hysteria" + node.tls = "1" + end + + local config = { + log = { + loglevel = ("1" == node.log) and node.loglevel or "none" + }, + inbounds = { + { + listen = (node.bind_local == "1") and "127.0.0.1" or nil, + port = tonumber(node.port), + protocol = node.protocol, + settings = settings, + streamSettings = { + network = node.transport, + security = "none", + tlsSettings = ("1" == node.tls) and { + disableSystemRoot = false, + certificates = { + { + certificateFile = node.tls_certificateFile, + keyFile = node.tls_keyFile + } + }, + echServerKeys = (node.ech == "1") and node.ech_key or nil + } or nil, + rawSettings = (node.transport == "raw" or node.transport == "tcp") and { + header = { + type = node.tcp_guise, + request = (node.tcp_guise == "http") and { + path = node.tcp_guise_http_path and (function() + local t, r = node.tcp_guise_http_path, {} + for _, v in ipairs(t) do + r[#r + 1] = (v == "" and "/" or v) + end + return r + end)() or {"/"}, + headers = { + Host = node.tcp_guise_http_host or {} + } + } or nil + } + } or nil, + kcpSettings = (node.transport == "mkcp") and { + mtu = (node.mkcp_mtu and node.mkcp_mtu ~= "") and tonumber(node.mkcp_mtu) or 1350, + tti = 50, + uplinkCapacity = 12, + downlinkCapacity = 100, + CwndMultiplier = 1, + MaxSendingWindow = 2 * 1024 * 1024 + } or nil, + wsSettings = (node.transport == "ws") and { + host = node.ws_host or nil, + path = node.ws_path + } or nil, + grpcSettings = (node.transport == "grpc" and node.grpc_serviceName) and { + serviceName = node.grpc_serviceName + } or nil, + httpupgradeSettings = (node.transport == "httpupgrade") and { + path = node.httpupgrade_path or "/", + host = node.httpupgrade_host + } or nil, + xhttpSettings = (node.transport == "xhttp") and { + path = node.xhttp_path or "/", + host = node.xhttp_host, + maxUploadSize = node.xhttp_maxuploadsize, + maxConcurrentUploads = node.xhttp_maxconcurrentuploads + } or nil, + hysteriaSettings = (node.transport == "hysteria") and { + version = 2 + } or nil, + finalmask = (function() + local finalmask = {} + if node.transport == "mkcp" then + local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", + dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local udp = {} + if node.mkcp_guise and node.mkcp_guise ~= "none" then + local g = { type = map[node.mkcp_guise] } + if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then + g.settings = { domain = node.mkcp_domain } + end + udp[#udp+1] = g + end + local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + if node.mkcp_seed and node.mkcp_seed ~= "" then + c.settings = { password = node.mkcp_seed } + end + udp[#udp+1] = c + finalmask.udp = udp + elseif node.transport == "hysteria" then + if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then + finalmask.udp = {{ + type = node.hysteria2_obfs_type, + settings = node.hysteria2_obfs_password and { + password = node.hysteria2_obfs_password + } or nil + }} + end + local ignore = tonumber(node.hysteria2_ignore_client_bandwidth) == 1 + local up = (not ignore) and tonumber(node.hysteria2_up_mbps) or 0 + local down = (not ignore) and tonumber(node.hysteria2_down_mbps) or 0 + finalmask.quicParams = { + congestion = (up <= 0 and down <= 0) and "bbr" or "brutal", + brutalUp = up > 0 and (up .. "mbps") or nil, + brutalDown = down > 0 and (down .. "mbps") or nil + } + end + if node.finalmask and node.finalmask ~= "" then + local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) + if ok and type(fm) == "table" then + finalmask = fm + end + end + return api.cleanEmptyTables(finalmask) + end)(), + sockopt = { + tcpFastOpen = (node.tcp_fast_open == "1") and true or nil, + acceptProxyProtocol = (node.acceptProxyProtocol and node.acceptProxyProtocol == "1") and true or false + } + } + } + }, + outbounds = outbounds, + routing = routing + } + + local alpn = {} + if node.alpn then + string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) + table.insert(alpn, w) + end) + end + if alpn and #alpn > 0 then + if config.inbounds[1].streamSettings.tlsSettings then + config.inbounds[1].streamSettings.tlsSettings.alpn = alpn + end + end + + if "1" == node.tls then + config.inbounds[1].streamSettings.security = "tls" + if "1" == node.reality then + config.inbounds[1].streamSettings.tlsSettings = nil + config.inbounds[1].streamSettings.security = "reality" + config.inbounds[1].streamSettings.realitySettings = { + show = false, + dest = node.reality_dest, + serverNames = node.reality_serverNames or {}, + privateKey = node.reality_private_key, + shortIds = node.reality_shortId or "", + mldsa65Seed = (node.use_mldsa65Seed == "1") and node.reality_mldsa65Seed or nil + } or nil + end + end + + for index, value in ipairs(config.outbounds) do + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + if value.protocol == "freedom" and api.compare_versions(xray_version, "<", "26.5.3") then -- Todo is to remove it + value.settings = nil + end + end + + return config +end + +function gen_config(var) + local flag = var["flag"] + local loglevel = var["loglevel"] or "warning" + local node_id = var["node"] + local server_host = var["server_host"] + local server_port = var["server_port"] + local tcp_proxy_way = var["tcp_proxy_way"] + local redir_port = var["redir_port"] + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local dns_listen_port = var["dns_listen_port"] + local direct_dns_udp_server = var["direct_dns_udp_server"] + local direct_dns_udp_port = var["direct_dns_udp_port"] + local direct_dns_query_strategy = var["direct_dns_query_strategy"] + local direct_ipset = var["direct_ipset"] + local direct_nftset = var["direct_nftset"] + local remote_dns_udp_server = var["remote_dns_udp_server"] + local remote_dns_udp_port = var["remote_dns_udp_port"] + local remote_dns_tcp_server = var["remote_dns_tcp_server"] + local remote_dns_tcp_port = var["remote_dns_tcp_port"] + local remote_dns_doh_url = var["remote_dns_doh_url"] + local remote_dns_doh_host = var["remote_dns_doh_host"] + local remote_dns_doh_ip = var["remote_dns_doh_ip"] + local remote_dns_doh_port = var["remote_dns_doh_port"] + local remote_dns_fake = var["remote_dns_fake"] + local remote_dns_query_strategy = var["remote_dns_query_strategy"] + local remote_dns_detour = var["remote_dns_detour"] + local dns_cache = var["dns_cache"] + local no_run = var["no_run"] + + local dns_domain_rules = {} + local dns = {} + local fakedns = nil + local inbounds = {} + local outbounds = {} + local routing = nil + local observatory = nil + local burstObservatory = nil + local strategy = nil + local COMMON = {} + + local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt" + + local xray_settings = uci:get_all(appname, "@global_xray[0]") or {} + + if xray_settings.fragment == "1" then + local delay = xray_settings.fragment_delay + fragment_table = { + type = "fragment", + settings = { + packets = xray_settings.fragment_packets, + length = xray_settings.fragment_length, + delay = delay and (delay:find("-", 1, true) and delay or tonumber(delay)) or nil, + maxSplit = xray_settings.fragment_maxSplit + } + } + end + + if xray_settings.noise == "1" then + local noises = {} + uci:foreach(appname, "xray_noise_packets", function(n) + if n.enabled == "1" then + local noise = { + rand = (n.type == "rand" and n.packet) and (n.packet:find("-", 1, true) and n.packet or tonumber(n.packet)) or nil, + type = (n.type ~= "rand") and n.type or nil, + packet = (n.type ~= "rand") and n.packet or nil, + delay = n.delay and (n.delay:find("-", 1, true) and n.delay or tonumber(n.delay)) or nil + } + table.insert(noises, noise) + end + end) + noise_table = #noises > 0 and { + type = "noise", + settings = { reset = 0, noise = noises } + } or nil + end + + local node = node_id and uci:get_all(appname, node_id) or nil + local balancers = {} + local rules = {} + + if local_socks_port then + local inbound = { + tag = "socks-in", + listen = local_socks_address, + port = tonumber(local_socks_port), + protocol = "socks", + settings = {auth = "noauth", udp = true}, + sniffing = { + enabled = xray_settings.sniffing_override_dest == "1" or node.protocol == "_shunt" + } + } + if inbound.sniffing.enabled == true then + inbound.sniffing.destOverride = {"http", "tls", "quic"} + inbound.sniffing.routeOnly = xray_settings.sniffing_override_dest ~= "1" or nil + inbound.sniffing.domainsExcluded = xray_settings.sniffing_override_dest == "1" and get_domain_excluded() or nil + end + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.settings.auth = "password" + inbound.settings.accounts = { + { + user = local_socks_username, + pass = local_socks_password + } + } + end + table.insert(inbounds, inbound) + end + + if local_http_port then + local inbound = { + listen = local_http_address, + port = tonumber(local_http_port), + protocol = "http", + settings = {allowTransparent = false} + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.settings.accounts = { + { + user = local_http_username, + pass = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + function gen_socks_config_node(node_id, socks_id, remarks) + if node_id then + socks_id = node_id:sub(1 + #"Socks_") + end + local result + local socks_node = uci:get_all(appname, socks_id) or nil + if socks_node then + if not remarks then + remarks = socks_node.port + end + result = { + [".name"] = "Socksid_" .. socks_id, + remarks = remarks, + type = "Xray", + protocol = "socks", + address = "127.0.0.1", + port = socks_node.port, + transport = "tcp", + stream_security = "none" + } + end + return result + end + + function get_node_by_id(node_id) + if not node_id or node_id == "" or node_id == "nil" then return nil end + if node_id:find("Socks_") then + return gen_socks_config_node(node_id) + else + return uci:get_all(appname, node_id) + end + end + + local nodes_list = {} + function get_balancer_batch_nodes(_node) + if #nodes_list == 0 then + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then + nodes_list[#nodes_list + 1] = { + id = e[".name"], + remarks = e["remarks"], + group = e["group"] + } + end + end + end + if not _node.node_group or _node.node_group == "" then return {} end + local nodes = {} + for g in _node.node_group:gmatch("%S+") do + g = api.UrlDecode(g) + for k, v in pairs(nodes_list) do + local gn = (v.group and v.group ~= "") and v.group or "default" + if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then + nodes[#nodes + 1] = v.id + end + end + end + return nodes + end + + function gen_loopback(outbound_tag, loopback_dst) + if not outbound_tag or outbound_tag == "" then return nil end + local inbound_tag = loopback_dst and "lo-to-" .. loopback_dst or outbound_tag .. "-lo" + local loopback_outbound = { + protocol = "loopback", + tag = outbound_tag, + settings = { inboundTag = inbound_tag } + } + local insert_index = #outbounds + 1 + if outbound_tag == "default" then + insert_index = 1 + end + table.insert(outbounds, insert_index, loopback_outbound) + return loopback_outbound + end + + function gen_balancer(_node, loopback_tag) + local balancer_id = _node[".name"] + local balancer_tag = "balancer-" .. balancer_id + local loopback_dst = balancer_id -- route destination for the loopback outbound + if not loopback_tag or loopback_tag == "" then loopback_tag = balancer_id end + -- existing balancer + for _, v in ipairs(balancers) do + if v.tag == balancer_tag then + local loopback_outbound = gen_loopback(loopback_tag, loopback_dst) + return balancer_tag, loopback_outbound + end + end + -- new balancer + local blc_nodes + if _node.node_add_mode and _node.node_add_mode == "batch" then + blc_nodes = get_balancer_batch_nodes(_node) + else + blc_nodes = _node.balancing_node + end + local valid_nodes = {} + for i = 1, #(blc_nodes or {}) do + local blc_node_id = blc_nodes[i] + local blc_node_tag = "blc-" .. blc_node_id + local is_new_blc_node = true + for _, outbound in ipairs(outbounds) do + if string.sub(outbound.tag, 1, #blc_node_tag) == blc_node_tag then + is_new_blc_node = false + valid_nodes[#valid_nodes + 1] = outbound.tag + break + end + end + if is_new_blc_node then + local outboundTag = gen_outbound_get_tag(flag, blc_node_id, blc_node_tag, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run }) + if outboundTag then + valid_nodes[#valid_nodes + 1] = outboundTag + end + end + end + if #valid_nodes == 0 then return nil end + + -- fallback node + local fallback_node_id = _node.fallback_node + fallback_node_id = (fallback_node_id and fallback_node_id ~= "") and fallback_node_id or nil + local fallback_node_tag = (fallback_node_id == "_direct") and "direct" or "blackhole" + if fallback_node_id and fallback_node_id ~= "_direct" then + local is_new_node = true + for _, outbound in ipairs(outbounds) do + if string.sub(outbound.tag, 1, #fallback_node_id) == fallback_node_id then + is_new_node = false + fallback_node_tag = outbound.tag + break + end + end + if is_new_node then + local fallback_node = get_node_by_id(fallback_node_id) + if fallback_node then + if fallback_node.protocol ~= "_balancing" then + local outboundTag = gen_outbound_get_tag(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run }) + if outboundTag then + fallback_node_tag = outboundTag + end + else + if gen_balancer(fallback_node) then + fallback_node_tag = fallback_node_id + end + end + end + end + end + if _node.balancingStrategy == "leastLoad" then + strategy = { + type = _node.balancingStrategy, + settings = { + expected = _node.expected and tonumber(_node.expected) and tonumber(_node.expected) or 2, + maxRTT = "1s", + tolerance = (function(t) + t = tonumber(t) or 0 + if t < 1 then return nil end + if t > 100 then t = 100 end + return t / 100 + end)(_node.tolerance) + } + } + else + strategy = { type = _node.balancingStrategy or "random" } + end + table.insert(balancers, { + tag = balancer_tag, + selector = api.clone(valid_nodes), + fallbackTag = fallback_node_tag, + strategy = strategy + }) + if _node.balancingStrategy == "leastPing" or _node.balancingStrategy == "leastLoad" or fallback_node_tag then + local t = api.format_go_time(_node.probeInterval) + if t == "0s" then + t = "60s" + elseif not t:find("[hm]") and tonumber(t:match("%d+")) < 10 then + t = "10s" + end + if _node.balancingStrategy == "leastLoad" then + burstObservatory = burstObservatory or { + subjectSelector = { "blc-" }, + pingConfig = { + destination = _node.useCustomProbeUrl and _node.probeUrl or nil, + interval = t, + sampling = 3, + timeout = "5s" + } + } + else + observatory = observatory or { + subjectSelector = { "blc-" }, + probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil, + probeInterval = t, + enableConcurrency = true + } + end + end + local loopback_outbound = gen_loopback(loopback_tag, loopback_dst) + local inbound_tag = loopback_outbound.settings.inboundTag + table.insert(rules, { inboundTag = { inbound_tag }, balancerTag = balancer_tag }) + return balancer_tag, loopback_outbound + end + + function set_outbound_detour(node, outbound, outbounds_table) + if not node or not outbound or not outbounds_table then return nil end + local default_outTag = outbound.tag + local last_insert_outbound + + if node.chain_proxy == "1" and node.preproxy_node then + if outbound["_flag_proxy_tag"] then + --Ignore + else + local preproxy_node = get_node_by_id(node.preproxy_node) + if preproxy_node then + local preproxy_outbound, exist + if preproxy_node.protocol == "_balancing" then + local balancer_tag, loopback_outbound = gen_balancer(preproxy_node) + if loopback_outbound then + preproxy_outbound = loopback_outbound + exist = true + end + else + preproxy_outbound = gen_outbound(node[".name"], preproxy_node) + end + if preproxy_outbound then + outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag + outbound.proxySettings = { + tag = preproxy_outbound.tag, + transportLayer = true + } + if not exist then + last_insert_outbound = preproxy_outbound + end + default_outTag = outbound.tag + end + end + end + end + if node.chain_proxy == "2" and node.to_node then + local to_node = get_node_by_id(node.to_node) + if to_node then + -- Landing Node not support use special node. + if to_node.protocol and to_node.protocol:find("^_") then + to_node = nil + end + end + if to_node then + local to_outbound + if to_node.type ~= "Xray" then + local in_tag = "inbound_" .. to_node[".name"] .. "_" .. tostring(outbound.tag) + local new_port = api.get_new_port() + table.insert(inbounds, { + tag = in_tag, + listen = "127.0.0.1", + port = new_port, + protocol = "dokodemo-door", + settings = {network = "tcp,udp", address = to_node.address, port = tonumber(to_node.port)} + }) + if to_node.tls_serverName == nil then + to_node.tls_serverName = to_node.address + end + to_node.address = "127.0.0.1" + to_node.port = new_port + table.insert(rules, 1, { + inboundTag = {in_tag}, + outboundTag = outbound.tag + }) + to_outbound = gen_outbound(node[".name"], to_node, to_node[".name"], { + tag = to_node[".name"], + run_socks_instance = not no_run + }) + else + to_outbound = gen_outbound(node[".name"], to_node) + end + if to_outbound then + to_outbound.tag = outbound.tag .. " -> " .. to_outbound.tag + if to_node.type == "Xray" then + to_outbound.proxySettings = { + tag = outbound.tag, + transportLayer = true + } + end + table.insert(outbounds_table, to_outbound) + default_outTag = to_outbound.tag + end + end + end + if node.chain_proxy == "3" and node.outbound_iface then + if outbound.streamSettings and outbound.streamSettings.sockopt then + outbound.streamSettings.sockopt.interface = node.outbound_iface + end + end + return default_outTag, last_insert_outbound + end + + function gen_outbound_get_tag(flag, node_id, tag, proxy_table) + if not node_id or node_id == "" or node_id == "nil" then return nil end + local node + if type(node_id) == "string" then + node = get_node_by_id(node_id) + elseif type(node_id) == "table" then + node = node_id + end + if not tag then tag = node[".name"] end + if node then + if proxy_table.chain_proxy == "1" or proxy_table.chain_proxy == "2" then + node.chain_proxy = proxy_table.chain_proxy + node.preproxy_node = proxy_table.chain_proxy == "1" and proxy_table.preproxy_node + node.to_node = proxy_table.chain_proxy == "2" and proxy_table.to_node + proxy_table.chain_proxy = nil + proxy_table.preproxy_node = nil + proxy_table.to_node = nil + end + if tag == "default" then + if default_node_address and default_node_port then + node.address = default_node_address + node.port = default_node_port + end + end + local outbound, has_add_outbound + for _, _outbound in ipairs(outbounds) do + -- Avoid generating duplicate nested processes + if _outbound["_flag_proxy_tag"] and _outbound["_flag_proxy_tag"]:find("socks <- " .. node[".name"], 1, true) then + outbound = api.clone(_outbound) + outbound.tag = tag + break + end + end + if node.protocol == "_balancing" then + local balancer_tag, loopback_outbound = gen_balancer(node, tag) + if loopback_outbound then + outbound = loopback_outbound + node[".name"] = outbound.tag + has_add_outbound = true + end + elseif node.protocol == "_iface" then + if node.iface then + outbound = { + tag = tag, + protocol = "freedom", + streamSettings = { + sockopt = { + mark = 255, + interface = node.iface + } + }, + settings = (api.compare_versions(xray_version, ">", "26.4.25")) and { -- Todo: Remove version check + finalRules = {{ action = "allow" }} + } or nil + } + sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) + end + end + if not outbound then + outbound = gen_outbound(flag, node, tag, proxy_table) + end + if outbound then + local default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) + if not has_add_outbound then + local insert_index = #outbounds + 1 + if tag == "default" then + insert_index = 1 + end + table.insert(outbounds, insert_index, outbound) + end + if last_insert_outbound then + table.insert(outbounds, last_insert_outbound) + end + return default_outbound_tag + end + end + end + + if node then + if node.protocol ~= "_shunt" then + -- create shunt logic + local tmp_node = { + remarks = node.remarks, + type = "Xray", + protocol = "_shunt", + default_node = node[".name"], + } + tmp_node.fakedns = remote_dns_fake + tmp_node.default_fakedns = remote_dns_fake + node = tmp_node + end + + if server_host and server_port then + default_node_address = server_host + default_node_port = server_port + end + + if node.protocol == "_shunt" then + inner_fakedns = node.fakedns or "0" + + local function gen_shunt_node(rule_name, _node_id) + if not rule_name then return nil end + if not _node_id then _node_id = node[rule_name] end + if _node_id == "_direct" then + return "direct" + elseif _node_id == "_blackhole" then + return "blackhole" + elseif _node_id == "_default" and rule_name ~= "default" then + return "default" + elseif _node_id then + local proxy_table = { + fragment = xray_settings.fragment == "1", + noise = xray_settings.noise == "1", + run_socks_instance = not no_run, + } + local preproxy_node_id = node[rule_name .. "_proxy_tag"] + if preproxy_node_id == _node_id then preproxy_node_id = nil end + if preproxy_node_id then + proxy_table.chain_proxy = "2" + proxy_table.to_node = _node_id + return gen_outbound_get_tag(flag, preproxy_node_id, rule_name, proxy_table) + else + return gen_outbound_get_tag(flag, _node_id, rule_name, proxy_table) + end + end + return nil + end + + --default_node + local default_node_id = node.default_node or "_direct" + local default_outboundTag = gen_shunt_node("default", default_node_id) + COMMON.default_outbound_tag = default_outboundTag + + if inner_fakedns == "1" and node["default_fakedns"] == "1" then + remote_dns_fake = true + end + + --shunt rule + uci:foreach(appname, "shunt_rules", function(e) + local outboundTag = gen_shunt_node(e[".name"]) + if outboundTag and e.remarks then + if outboundTag == "default" then + outboundTag = default_outboundTag + end + local protocols = nil + if e["protocol"] and e["protocol"] ~= "" then + protocols = {} + string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) + table.insert(protocols, w) + end) + end + local inboundTag = nil + if e["inbound"] and e["inbound"] ~= "" then + inboundTag = {} + if e["inbound"]:find("tproxy") then + if redir_port then + table.insert(inboundTag, "tcp_redir") + table.insert(inboundTag, "udp_redir") + end + end + if e["inbound"]:find("socks") then + if local_socks_port then + table.insert(inboundTag, "socks-in") + end + end + end + local domains = nil + if e.domain_list then + local domain_table = { + shunt_rule_name = e[".name"], + outboundTag = outboundTag, + domain = {}, + fakedns = nil, + } + domains = {} + string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end + table.insert(domains, w) + table.insert(domain_table.domain, w) + end) + if inner_fakedns == "1" and node[e[".name"] .. "_fakedns"] == "1" and #domains > 0 then + domain_table.fakedns = true + end + if outboundTag then + table.insert(dns_domain_rules, api.clone(domain_table)) + end + if #domains == 0 then + domains = nil + end + end + local ip = nil + if e.ip_list then + ip = {} + string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end + table.insert(ip, w) + end) + if #ip == 0 then ip = nil end + end + local source = nil + if e.source then + source = {} + string.gsub(e.source, '[^' .. " " .. ']+', function(w) + table.insert(source, w) + end) + end + local rule = { + ruleTag = e.remarks, + inboundTag = inboundTag, + outboundTag = outboundTag, + network = e["network"] or "tcp,udp", + source = source, + --sourcePort = e["sourcePort"] ~= "" and e["sourcePort"] or nil, + port = e["port"] ~= "" and e["port"] or nil, + protocol = protocols + } + if domains then + local _rule = api.clone(rule) + _rule.ruleTag = _rule.ruleTag .. " Domains" + _rule.domains = domains + table.insert(rules, _rule) + end + if ip then + local _rule = api.clone(rule) + _rule.ruleTag = _rule.ruleTag .. " IP" + _rule.ip = ip + table.insert(rules, _rule) + end + if not domains and not ip then + table.insert(rules, rule) + end + end + end) + + if default_outboundTag then + local rule = { + ruleTag = "default", + outboundTag = default_outboundTag, + } + if node.domainStrategy == "IPIfNonMatch" then + rule.ip = { "0.0.0.0/0", "::/0" } + else + rule.network = "tcp,udp" + end + table.insert(rules, rule) + end + + routing = { + domainStrategy = node.domainStrategy or "AsIs", + domainMatcher = node.domainMatcher or "hybrid", + balancers = #balancers > 0 and balancers or nil, + rules = rules + } + end + end + + local dns_servers = {} + local direct_dns_tag = "dns-in-direct" + local remote_dns_tag = "dns-in-remote" + local remote_fakedns_tag = "dns-in-remote-fakedns" + local default_dns_tag = "dns-in-default" + + dns = { + tag = "dns-global", + hosts = {}, + disableCache = (dns_cache and dns_cache == "0") and true or false, + disableFallback = true, + disableFallbackIfMatch = true, + servers = {}, + queryStrategy = "UseIP" + } + + for i, v in pairs(GLOBAL.DNS_SERVER) do + table.insert(dns_servers, { + server = v, + outboundTag = "direct" + }) + end + + local _direct_dns = nil + if direct_dns_udp_server then + _direct_dns = { + tag = direct_dns_tag, + address = direct_dns_udp_server, + port = tonumber(direct_dns_udp_port) or 53, + queryStrategy = (direct_dns_query_strategy and direct_dns_query_strategy ~= "") and direct_dns_query_strategy or "UseIP" + } + + if _direct_dns.address then + table.insert(dns_servers, { + outboundTag = "direct", + server = _direct_dns + }) + end + end + + if next(GLOBAL.DNS_HOSTNAME) then + local hostname = {} + for line, _ in pairs(GLOBAL.DNS_HOSTNAME) do + table.insert(hostname, line) + end + local new_dns_server + if _direct_dns then + new_dns_server = api.clone(_direct_dns) + else + new_dns_server = { + address = "localhost" + } + end + new_dns_server.tag = "dns-in-bootstrap" + new_dns_server.domains = hostname + table.insert(dns_servers, #dns_servers - 1, { + outboundTag = "direct", + server = new_dns_server + }) + end + + if dns_listen_port then + local _remote_dns_proto = "tcp" + + if not routing then + routing = { + domainStrategy = "IPOnDemand", + rules = {} + } + end + + local dns_host = "" + if flag == "global" then + dns_host = uci:get(appname, "@global[0]", "dns_hosts") or "" + else + flag = flag:gsub("acl_", "") + local dns_hosts_mode = uci:get(appname, flag, "dns_hosts_mode") or "default" + if dns_hosts_mode == "default" then + dns_host = uci:get(appname, "@global[0]", "dns_hosts") or "" + elseif dns_hosts_mode == "disable" then + dns_host = "" + elseif dns_hosts_mode == "custom" then + dns_host = uci:get(appname, flag, "dns_hosts") or "" + end + end + if #dns_host > 0 then + string.gsub(dns_host, '[^' .. "\r\n" .. ']+', function(w) + local host = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $1}')", w)) + local key = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $2}')", w)) + if host ~= "" and key ~= "" then + dns.hosts[host] = key + end + end) + end + + local _remote_dns_ip = nil + + local _remote_dns = { + tag = remote_dns_tag, + queryStrategy = (remote_dns_query_strategy and remote_dns_query_strategy ~= "") and remote_dns_query_strategy or "UseIPv4" + } + + if remote_dns_udp_server then + _remote_dns.address = remote_dns_udp_server + _remote_dns.port = tonumber(remote_dns_udp_port) or 53 + _remote_dns_proto = "udp" + _remote_dns_ip = remote_dns_udp_server + end + + if remote_dns_tcp_server then + _remote_dns.address = "tcp://" .. remote_dns_tcp_server .. ":" .. tonumber(remote_dns_tcp_port) or 53 + _remote_dns.port = tonumber(remote_dns_tcp_port) or 53 + _remote_dns_proto = "tcp" + _remote_dns_ip = remote_dns_tcp_server + end + + if remote_dns_doh_url and remote_dns_doh_host then + if remote_dns_doh_ip and remote_dns_doh_host ~= remote_dns_doh_ip and not api.is_ip(remote_dns_doh_host) then + dns.hosts[remote_dns_doh_host] = remote_dns_doh_ip + end + _remote_dns.address = remote_dns_doh_url + _remote_dns.port = tonumber(remote_dns_doh_port) or 443 + _remote_dns_ip = remote_dns_doh_ip + end + + if _remote_dns.address then + table.insert(dns_servers, { + outboundTag = remote_dns_detour == "direct" and "direct" or nil, + server = _remote_dns + }) + end + + local _remote_fakedns = nil + if remote_dns_fake or inner_fakedns == "1" then + fakedns = {} + local fakedns4 = { + ipPool = "198.18.0.0/16", + poolSize = 65535 + } + local fakedns6 = { + ipPool = "fc00::/18", + poolSize = 65535 + } + if remote_dns_query_strategy == "UseIP" then + table.insert(fakedns, fakedns4) + table.insert(fakedns, fakedns6) + elseif remote_dns_query_strategy == "UseIPv4" then + table.insert(fakedns, fakedns4) + elseif remote_dns_query_strategy == "UseIPv6" then + table.insert(fakedns, fakedns6) + end + _remote_fakedns = { + tag = remote_fakedns_tag, + address = "fakedns", + } + table.insert(dns_servers, { + server = _remote_fakedns + }) + end + + if direct_dns_udp_server then + local domain = {} + local nodes_domain_text = sys.exec('uci show passwall2 | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u') + string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) + w = (w or ""):lower() + table.insert(domain, "full:" .. w) + end) + if #domain > 0 then + table.insert(dns.servers, 1, { + tag = "dns-in-vpslist", + address = "localhost", + domains = domain, + finalQuery = true, + disableCache = false, + serveStale = true, + }) + end + end + + if dns_listen_port then + table.insert(inbounds, { + listen = "127.0.0.1", + port = tonumber(dns_listen_port), + protocol = "dokodemo-door", + tag = "dns-in", + settings = { + address = "0.0.0.0", + network = "tcp,udp" + } + }) + local direct_type_dns = { + settings = { + address = direct_dns_udp_server, + port = tonumber(direct_dns_udp_port) or 53, + network = "udp", + nonIPQuery = (api.compare_versions(xray_version, "<", "26.4.25")) and "skip" or nil, -- Todo is to remove it + blockTypes = (api.compare_versions(xray_version, "<", "26.4.25")) and { 65 } or nil, -- Todo is to remove it + rules = (api.compare_versions(xray_version, ">", "26.4.17")) and { + { + qtype = "1,28", + action = "hijack" + }, + { + qtype = 65, + action = "reject", + }, + { + action = "direct" + } + } or nil + }, + proxySettings = { + tag = "direct" + } + } + local remote_type_dns = { + settings = { + address = remote_dns_udp_server, + port = tonumber(remote_dns_udp_port) or 53, + network = _remote_dns_proto or "tcp", + nonIPQuery = (api.compare_versions(xray_version, "<", "26.4.25")) and "reject" or nil, -- Todo is to remove it + rules = (api.compare_versions(xray_version, ">", "26.4.17")) and { + { + qtype = "1,28", + action = "hijack" + }, + { + action = "reject" + } + } or nil + } + } + local type_dns = direct_type_dns + table.insert(outbounds, { + tag = "dns-out", + protocol = "dns", + proxySettings = type_dns.proxySettings, + settings = type_dns.settings + }) + table.insert(routing.rules, 1, { + inboundTag = { + "dns-in" + }, + outboundTag = "dns-out" + }) + end + + local default_dns_tag_name = remote_dns_tag + if not COMMON.default_outbound_tag or COMMON.default_outbound_tag == "direct" then + default_dns_tag_name = direct_dns_tag + end + + if dns_servers and #dns_servers > 0 then + -- Default DNS logic + local default_dns_server = nil + for index, value in ipairs(dns_servers) do + if not default_dns_server and value.server.tag == default_dns_tag_name then + default_dns_server = api.clone(value) + default_dns_server.server.tag = default_dns_tag + if value.server.tag == remote_dns_tag then + if remote_dns_fake then + default_dns_server.server = api.clone(_remote_fakedns) + default_dns_server.server.tag = default_dns_tag + else + default_dns_server.outboundTag = value.outboundTag or COMMON.default_outbound_tag + end + end + table.insert(dns_servers, 1, default_dns_server) + break + end + end + + -- Shunt rule DNS logic + if dns_domain_rules and #dns_domain_rules > 0 then + for index, value in ipairs(dns_domain_rules) do + if value.domain and value.outboundTag then + local dns_server = nil + local dns_outboundTag = value.outboundTag + if value.dns_server then + dns_server = api.clone(value.dns_server) + elseif value.outboundTag == "direct" then + dns_server = api.clone(_direct_dns) + else + if value.fakedns then + dns_server = api.clone(_remote_fakedns) + else + dns_server = api.clone(_remote_dns) + if remote_dns_detour == "direct" then + dns_outboundTag = "direct" + end + end + end + local dns_block = true -- If you do not want the blackhole rule to use DNS routing, please change it to `nil` or do not assign a value. + if dns_outboundTag == "blackhole" then + if dns_block then + local dns_block_mode = "Hosts" -- use the Hosts mode to block. + if dns_block_mode == "Hosts" then + for d_i, d_k in ipairs(value.domain) do + dns.hosts[d_k] = "0.0.0.0" + end + dns_server = nil + end + else + dns_server = nil + end + end + if dns_server then + dns_server.finalQuery = true + dns_server.domains = value.domain + if value.shunt_rule_name then + dns_server.tag = "dns-in-" .. value.shunt_rule_name + end + table.insert(dns_servers, { + outboundTag = dns_outboundTag, + server = dns_server + }) + end + end + end + end + end + + local default_rule_index = nil + for index, value in ipairs(routing.rules) do + if value.ruleTag == "default" then + default_rule_index = index + break + end + end + if default_rule_index then + local default_rule = api.clone(routing.rules[default_rule_index]) + table.remove(routing.rules, default_rule_index) + table.insert(routing.rules, default_rule) + end + + local content = flag .. node_id .. jsonc.stringify(routing.rules) + if api.cacheFileCompareToLogic(CACHE_TEXT_FILE, content) == false then + --clear ipset/nftset + if direct_ipset then + string.gsub(direct_ipset, '[^' .. "," .. ']+', function(w) + sys.call("ipset -q -F " .. w) + end) + local ipset_prefix_name = "psw2_" .. node_id .. "_" + local ipset_list = sys.exec("ipset list | grep 'Name: ' | grep '" .. ipset_prefix_name .. "' | awk '{print $2}'") + string.gsub(ipset_list, '[^' .. "\r\n" .. ']+', function(w) + sys.call("ipset -q -F " .. w) + end) + end + if direct_nftset then + string.gsub(direct_nftset, '[^' .. "," .. ']+', function(w) + local split = api.split(w, "#") + if #split > 3 then + local ip_type = split[1] + local family = split[2] + local table_name = split[3] + local set_name = split[4] + sys.call(string.format("nft flush set %s %s %s 2>/dev/null", family, table_name, set_name)) + end + end) + local family = "inet" + local table_name = "passwall2" + local nftset_prefix_name = "psw2_" .. node_id .. "_" + local nftset_list = sys.exec("nft -a list sets | grep -E '" .. nftset_prefix_name .. "' | awk -F 'set ' '{print $2}' | awk '{print $1}'") + string.gsub(nftset_list, '[^' .. "\r\n" .. ']+', function(w) + sys.call(string.format("nft flush set %s %s %s 2>/dev/null", family, table_name, w)) + end) + end + end + end + + if not next(dns.hosts) then + dns.hosts = nil + end + + for i = #dns_servers, 1, -1 do + local value = dns_servers[i] + if value.server.tag ~= direct_dns_tag and value.server.tag ~= remote_dns_tag then + -- DNS rule must be at the front, prevents being matched by rules. + if value.outboundTag and value.server.address ~= "fakedns" then + table.insert(routing.rules, 1, { + inboundTag = { + value.server.tag + }, + outboundTag = value.outboundTag, + }) + end + if (value.server.domains and #value.server.domains > 0) or value.server.tag == default_dns_tag then + -- Only keep default DNS server or has domains DNS server. + table.insert(dns.servers, 1, value.server) + end + end + end + + local has_default_dns_server = "0" + for index, value in ipairs(dns.servers) do + if value.domains == nil then + has_default_dns_server = "1" + break + end + end + + if #dns.servers == 0 or not has_default_server == "0" then + table.insert(dns.servers, 1, { + tag = "local", + address = "localhost" + }) + end + + if redir_port then + local inbound = { + port = tonumber(redir_port), + protocol = "dokodemo-door", + settings = {network = "tcp,udp", followRedirect = true}, + streamSettings = {sockopt = {tproxy = "tproxy"}}, + sniffing = { + enabled = xray_settings.sniffing_override_dest == "1" or node.protocol == "_shunt" + } + } + if inbound.sniffing.enabled == true then + inbound.sniffing.destOverride = {"http", "tls", "quic"} + inbound.sniffing.metadataOnly = false + inbound.sniffing.routeOnly = xray_settings.sniffing_override_dest ~= "1" or nil + inbound.sniffing.domainsExcluded = xray_settings.sniffing_override_dest == "1" and get_domain_excluded() or nil + end + if remote_dns_fake or inner_fakedns == "1" then + inbound.sniffing.enabled = true + if not inbound.sniffing.destOverride then + inbound.sniffing.destOverride = {"fakedns"} + inbound.sniffing.metadataOnly = true + else + table.insert(inbound.sniffing.destOverride, "fakedns") + inbound.sniffing.metadataOnly = false + end + end + + local tcp_inbound = api.clone(inbound) + tcp_inbound.tag = "tcp_redir" + tcp_inbound.settings.network = "tcp" + tcp_inbound.streamSettings.sockopt.tproxy = tcp_proxy_way + table.insert(inbounds, tcp_inbound) + + local udp_inbound = api.clone(inbound) + udp_inbound.tag = "udp_redir" + udp_inbound.settings.network = "udp" + table.insert(inbounds, udp_inbound) + end + + if inbounds or outbounds then + local config = { + log = { + --access = string.format("/tmp/etc/%s/%s_access.log", appname, "global"), + --error = string.format("/tmp/etc/%s/%s_error.log", appname, "global"), + --dnsLog = true, + loglevel = loglevel + }, + dns = dns, + fakedns = fakedns, + inbounds = inbounds, + outbounds = outbounds, + observatory = (not burstObservatory) and observatory or nil, + burstObservatory = burstObservatory, + routing = routing, + policy = { + levels = { + [0] = { + -- handshake = 4, + -- connIdle = 300, + -- uplinkOnly = 2, + -- downlinkOnly = 5, + bufferSize = xray_settings.buffer_size and tonumber(xray_settings.buffer_size) or nil, + statsUserUplink = false, + statsUserDownlink = false + } + }, + -- system = { + -- statsInboundUplink = false, + -- statsInboundDownlink = false + -- } + } + } + + local direct_outbound = { + protocol = "freedom", + tag = "direct", + settings = { + domainStrategy = (direct_dns_query_strategy and direct_dns_query_strategy ~= "") and direct_dns_query_strategy or "UseIP", + finalRules = {{ action = "allow" }} + }, + streamSettings = { + sockopt = { + mark = 255 + } + } + } + if COMMON.default_outbound_tag == "direct" then + table.insert(outbounds, 1, direct_outbound) + else + table.insert(outbounds, direct_outbound) + end + + local blackhole_outbound = { + protocol = "blackhole", + tag = "blackhole" + } + if COMMON.default_outbound_tag == "blackhole" then + table.insert(outbounds, 1, blackhole_outbound) + else + table.insert(outbounds, blackhole_outbound) + end + + for index, value in ipairs(config.outbounds) do + local s = value.settings + if not value["_flag_proxy_tag"] and value["_id"] and s and not no_run and + ((s.vnext and s.vnext[1] and s.vnext[1].address and s.vnext[1].port) or + (s.servers and s.servers[1] and s.servers[1].address and s.servers[1].port) or + (s.peers and s.peers[1] and s.peers[1].endpoint) or + (s.address and s.port)) then + sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list")) + end + for k, v in pairs(config.outbounds[index]) do + if k:find("_") == 1 then + config.outbounds[index][k] = nil + end + end + end + return jsonc.stringify(config, 1) + end +end + +function gen_proto_config(var) + local local_socks_address = var["local_socks_address"] or "0.0.0.0" + local local_socks_port = var["local_socks_port"] + local local_socks_username = var["local_socks_username"] + local local_socks_password = var["local_socks_password"] + local local_http_address = var["local_http_address"] or "0.0.0.0" + local local_http_port = var["local_http_port"] + local local_http_username = var["local_http_username"] + local local_http_password = var["local_http_password"] + local server_proto = var["server_proto"] + local server_address = var["server_address"] + local server_port = var["server_port"] + local server_username = var["server_username"] + local server_password = var["server_password"] + + local inbounds = {} + local outbounds = {} + local routing = nil + + if local_socks_address and local_socks_port then + local inbound = { + listen = local_socks_address, + port = tonumber(local_socks_port), + protocol = "socks", + settings = { + udp = true, + auth = "noauth" + } + } + if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then + inbound.settings.auth = "password" + inbound.settings.accounts = { + { + user = local_socks_username, + pass = local_socks_password + } + } + end + table.insert(inbounds, inbound) + end + + if local_http_address and local_http_port then + local inbound = { + listen = local_http_address, + port = tonumber(local_http_port), + protocol = "http", + settings = { + allowTransparent = false + } + } + if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then + inbound.settings.accounts = { + { + user = local_http_username, + pass = local_http_password + } + } + end + table.insert(inbounds, inbound) + end + + if server_proto ~= "nil" and server_address ~= "nil" and server_port ~= "nil" then + local outbound = { + protocol = server_proto, + streamSettings = { + network = "tcp", + security = "none" + }, + settings = { + servers = { + { + address = server_address, + port = tonumber(server_port), + users = (server_username and server_password) and { + { + user = server_username, + pass = server_password + } + } or nil + } + } + } + } + if outbound then table.insert(outbounds, outbound) end + end + + table.insert(outbounds, { + protocol = "freedom", + tag = "direct", + settings = (api.compare_versions(xray_version, ">", "26.4.25")) and { -- Todo: Remove version check + finalRules = {{ action = "allow" }} + } or nil, + sockopt = {mark = 255} + }) + + local config = { + log = { + loglevel = "warning" + }, + inbounds = inbounds, + outbounds = outbounds, + routing = routing + } + return jsonc.stringify(config, 1) +end + +function gen_front_dns_config(var) + local dns_listen_port = var["dns_listen_port"] + local direct_dns_udp_server = var["direct_dns_udp_server"] + local direct_dns_udp_port = var["direct_dns_udp_port"] + local default_dns_udp_server = var["default_dns_udp_server"] + local default_dns_udp_port = var["default_dns_udp_port"] + + local queryStrategy = "UseIP" + local dns = { + tag = "dns-global-direct", + disableCache = false, + disableFallback = true, + disableFallbackIfMatch = true, + queryStrategy = queryStrategy, + servers = {} + } + local inbounds = {} + local outbounds = {} + local routing = { + rules = {} + } + + table.insert(outbounds, { + tag = "direct", + protocol = "freedom", + settings = { + domainStrategy = queryStrategy + }, + streamSettings = { + sockopt = { + mark = 255 + } + } + }) + + if default_dns_udp_server then + table.insert(dns.servers, { + tag = "default", + address = default_dns_udp_server, + port = tonumber(default_dns_udp_port) or 53, + queryStrategy = queryStrategy, + }) + end + + local direct_dns_shunt = uci:get(appname, "@global[0]", "direct_dns_shunt") or "" + if #direct_dns_shunt > 0 then + local dns_server = {} + string.gsub(direct_dns_shunt, '[^' .. "\r\n" .. ']+', function(w) + if w:find("#") == 1 then return end + local domain = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $1}')", w)) + local dns = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $2}')", w)) + if domain ~= "" and dns ~= "" then + local new_dns_server = parseDNS(dns) + if new_dns_server then + if not dns_server[dns] then + dns_server[dns] = {} + end + dns_server[dns].tag = dns + dns_server[dns].queryStrategy = queryStrategy + dns_server[dns].address = new_dns_server.address + dns_server[dns].port = new_dns_server.port + dns_server[dns].finalQuery = true + if not dns_server[dns].domains then + dns_server[dns].domains = {} + end + table.insert(dns_server[dns].domains, domain) + end + end + end) + for k, v in pairs(dns_server) do + table.insert(dns.servers, v) + table.insert(routing.rules, { + inboundTag = { + v.tag + }, + outboundTag = "direct" + }) + end + end + + if direct_dns_udp_server then + local node_domain = {} + local nodes_domain_text = sys.exec('uci show passwall2 | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u') + string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) + w = (w or ""):lower() + table.insert(node_domain, "full:" .. w) + end) + if #node_domain > 0 then + table.insert(dns.servers, { + tag = "dns-in-vpslist", + address = direct_dns_udp_server, + port = tonumber(direct_dns_udp_port) or 53, + queryStrategy = queryStrategy, + domains = node_domain, + finalQuery = true, + disableCache = false, + serveStale = true, + }) + end + end + + table.insert(inbounds, { + tag = "dns-in", + listen = "127.0.0.1", + port = tonumber(dns_listen_port), + protocol = "dokodemo-door", + settings = { + address = "0.0.0.0", + network = "tcp,udp" + } + }) + + table.insert(outbounds, { + tag = "dns-out", + protocol = "dns", + proxySettings = { + tag = "direct" + }, + settings = { + address = direct_dns_udp_server, + port = tonumber(direct_dns_udp_port) or 53, + network = "udp", + nonIPQuery = "skip", + blockTypes = { + 65 + } + } + }) + + table.insert(routing.rules, { + inboundTag = { + "dns-in" + }, + outboundTag = "dns-out" + }) + + local config = { + log = { + dnsLog = true, + loglevel = "debug" + }, + dns = dns, + inbounds = inbounds, + outbounds = outbounds, + routing = routing + } + return jsonc.stringify(config, 1) +end + +_G.gen_config = gen_config +_G.gen_front_dns_config = gen_front_dns_config +_G.gen_proto_config = gen_proto_config + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + print(func(var)) + end +end diff --git a/luci-app-passwall2/luasrc/view/passwall2/app_update/app_version.htm b/luci-app-passwall2/luasrc/view/passwall2/app_update/app_version.htm new file mode 100644 index 00000000..0dcbb559 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/app_update/app_version.htm @@ -0,0 +1,212 @@ +<% +local api = require "luci.passwall2.api" +local com = require "luci.passwall2.com" +local version = {} +-%> + + + +
+ +
+
+ 〠<%=api.get_version()%> 】 + + +
+
+
+ +<%for k, v in pairs(com) do + version[k] = api.get_app_version(k)%> +
+ +
+
+ 〠<%=version[k] ~="" and version[k] or translate("Null") %> 】 + + + +
+
+
+<%end%> diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/hidevalue.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/hidevalue.htm new file mode 100644 index 00000000..c007e399 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/hidevalue.htm @@ -0,0 +1,3 @@ +
" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>" style="display: none !important"> + " /> +
diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_dynamiclist.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_dynamiclist.htm new file mode 100644 index 00000000..f516aceb --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_dynamiclist.htm @@ -0,0 +1,149 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template + +local json = require "luci.jsonc" + +-- 读å–值(keylist/vallist/group) +local values = {} +for i, key in pairs(self.keylist) do + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } +end + +-- 获å–当å‰é…置值 +local current_key = {} +local cval = self:cfgvalue(section) +if type(cval) == "table" then + for _, v in ipairs(cval) do + for item in string.gmatch(v, "[^,]+") do + current_key[#current_key+1] = item + end + end +elseif type(cval) == "string" then + for item in string.gmatch(cval, "[^,]+") do + current_key[#current_key+1] = item + end +end + +-- 分离无组节点(ungrouped)与有组节点(groupedï¼‰ï¼Œå¹¶ä¿æŒåŽŸæœ‰é¡ºåº +local ungrouped = {} +local groups = {} +local group_order = {} +for _, item in ipairs(values) do + if not item.group or item.group == "" then + table.insert(ungrouped, item) + else + local g = item.group + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) + end +end + +-- 打包数æ®ç»™ JS +local dropdown_data = { + current_key = current_key, + ungrouped = ungrouped, + groups = groups, + group_order = group_order, + cbid = cbid, +} +%> + + +
+ + + +
+ + +
+ + <%=translate("-- Please choose --")%> + + +
+ + +
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_dynamiclist_com.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_dynamiclist_com.htm new file mode 100644 index 00000000..4f932a21 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_dynamiclist_com.htm @@ -0,0 +1,654 @@ +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +-- It is the common part of the template and cannot be used independently +%> + + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue.htm new file mode 100644 index 00000000..fe15cf6e --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue.htm @@ -0,0 +1,148 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template + +local json = require "luci.jsonc" + +-- 读å–值(keylist/vallist/group) +local values = {} +for i, key in pairs(self.keylist) do + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } +end + +-- 获å–当å‰é…置值(å•值) +local current_key = nil +local cval = self:cfgvalue(section) +if type(cval) == "table" then + -- è‹¥æ„外为table,å–第一个 + for k,_ in pairs(cval) do + current_key = k + break + end +elseif type(cval) == "string" then + current_key = (cval:match("%S+")) -- å–第一个 token +end + +-- 分离无组节点(ungrouped)与有组节点(groupedï¼‰ï¼Œå¹¶ä¿æŒåŽŸæœ‰é¡ºåº +local ungrouped = {} +local groups = {} +local group_order = {} +for _, item in ipairs(values) do + if not item.group or item.group == "" then + table.insert(ungrouped, item) + else + local g = item.group + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) + end +end + +-- 如果没有é…置值,默认å–第一个(优先无组第一项,å¦åˆ™ç¬¬ä¸€ç»„第一项) +if not current_key then + if #ungrouped > 0 then + current_key = ungrouped[1].key + else + -- 找到 group_order 第一个有节点的项 + for _, g in ipairs(group_order) do + if groups[g] and #groups[g] > 0 then + current_key = groups[g][1].key + break + end + end + end +end + +-- 获å–å½“å‰ label(用于主控件显示) +local function find_label_by_key(k) + if not k then return "" end + for _, v in ipairs(values) do + if v.key == k then return v.label end + end + return "" +end +local current_label = find_label_by_key(current_key) or "" + +-- 打包数æ®ç»™ JS +local dropdown_data = { + current_key = current_key, + current_label = current_label, + ungrouped = ungrouped, + groups = groups, + group_order = group_order, + cbid = cbid, +} +%> + + +
+ + + +
+ + <%=pcdata("("..translate("Not set")..")")%> + + +
+ + +
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm new file mode 100644 index 00000000..9de708e5 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_listvalue_com.htm @@ -0,0 +1,758 @@ +<% +-- Template Developers: +-- - lwb1978 +-- - snowie2000 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +-- It is the common part of the template and cannot be used independently +%> + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_multivalue.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_multivalue.htm new file mode 100644 index 00000000..9a02b666 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_multivalue.htm @@ -0,0 +1,132 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +local json = require "luci.jsonc" +local cbid = "cbid." .. self.config .. "." .. section .. "." .. self.option + +-- è¯»å– MultiValue +local values = {} +for i, key in pairs(self.keylist) do + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } +end + +-- 获å–选中值 +local selected = {} +local cval = self:cfgvalue(section) +if type(cval) == "table" then + for _, v in pairs(cval) do + selected[v] = true + end +elseif type(cval) == "string" then + for v in cval:gmatch("%S+") do + selected[v] = true + end +end + +-- 按原顺åºåˆ†ç»„ +local groups = {} +local group_order = {} +for _, item in ipairs(values) do + local g = item.group + if not g or g == "" then + g = translate("default") + end + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) +end + +local total_count = #values +local selected_count = 0 +for _, item in ipairs(values) do + if selected[item.key] then + selected_count = selected_count + 1 + end +end + +local function idSafe(id) + return (id + :gsub("^%s+", "") + :gsub("%s+$", "") + :gsub("%s+", "-") + :gsub("[%z\1-\31\127]", "") + ) +end +%> + +
+ + + + +
+
    + <% for _, gname in ipairs(group_order) do local items = groups[gname] %> +
  • + +
    + + <%=pcdata(gname)%> + <% + local g_selected = 0 + for _, it in ipairs(items) do + if selected[it.key] then + g_selected = g_selected + 1 + end + end + %> + + (<%=g_selected%>/<%=#items%>) + +
    + + +
  • + <% end %> +
+
+ +
+ + + <%:Selected:%> <%=selected_count%>/<%=total_count%> +
+
+ + + +<%+cbi/valuefooter%> \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_multivalue_com.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_multivalue_com.htm new file mode 100644 index 00000000..646f691b --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_multivalue_com.htm @@ -0,0 +1,460 @@ +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +%> + + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value.htm new file mode 100644 index 00000000..beb3ce2a --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value.htm @@ -0,0 +1,162 @@ +<%+cbi/valueheader%> +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template + +local json = require "luci.jsonc" + +-- 读å–值(keylist/vallist/group) +local values = {{key = "", label = translate("-- Please choose --")}} +for i, key in pairs(self.keylist) do + if key and key ~= "" then + values[#values + 1] = { + key = key, + label = self.vallist[i] or key, + group = self.group and self.group[i] or nil + } + end +end + +-- 获å–当å‰é…置值(å•值) +local current_key = nil +local cval = self:cfgvalue(section) +if type(cval) == "table" then + -- è‹¥æ„外为table,å–第一个 + for k,_ in pairs(cval) do + current_key = k + break + end +elseif type(cval) == "string" then + current_key = (cval:match("%S+")) -- å–第一个 token +end + +-- 分离无组节点(ungrouped)与有组节点(groupedï¼‰ï¼Œå¹¶ä¿æŒåŽŸæœ‰é¡ºåº +local ungrouped = {} +local groups = {} +local group_order = {} +local current_key_added = false +for _, item in ipairs(values) do + if not current_key_added and current_key and current_key ~= "" and item.key == current_key then + current_key_added = true + end + if not item.group or item.group == "" then + table.insert(ungrouped, item) + else + local g = item.group + if not groups[g] then + groups[g] = {} + table.insert(group_order, g) + end + table.insert(groups[g], item) + end +end +if not current_key_added and current_key and current_key ~= "" then + table.insert(ungrouped, {key = current_key, label = current_key}) +end + +-- 如果没有é…置值,默认å–第一个(优先无组第一项,å¦åˆ™ç¬¬ä¸€ç»„第一项) +if not current_key then + if #ungrouped > 0 then + current_key = ungrouped[1].key + else + -- 找到 group_order 第一个有节点的项 + for _, g in ipairs(group_order) do + if groups[g] and #groups[g] > 0 then + current_key = groups[g][1].key + break + end + end + end +end + +-- 获å–å½“å‰ label(用于主控件显示) +local function find_label_by_key(k) + if not k then return "" end + for _, v in ipairs(values) do + if v.key == k then return v.label end + end + return "" +end +local current_label = find_label_by_key(current_key) or "" + +-- 打包数æ®ç»™ JS +local dropdown_data = { + current_key = current_key, + current_label = current_label, + ungrouped = ungrouped, + groups = groups, + group_order = group_order, + cbid = cbid, +} +%> + + +
+ + + + +
+ + <%=pcdata(translate("-- Please choose --"))%> + + +
+ + +
+ + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm new file mode 100644 index 00000000..1f784d04 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/nodes_value_com.htm @@ -0,0 +1,792 @@ +<% +-- Template Developers: +-- - lwb1978 +-- Copyright: copyright(c)2025–2027 +-- Description: Passwall(2) UI template +-- It is the common part of the template and cannot be used independently +%> + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/cbi/optimize_cbi_ui.htm b/luci-app-passwall2/luasrc/view/passwall2/cbi/optimize_cbi_ui.htm new file mode 100644 index 00000000..3fccf13c --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/cbi/optimize_cbi_ui.htm @@ -0,0 +1,22 @@ + diff --git a/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm b/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm new file mode 100644 index 00000000..aec626b8 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm @@ -0,0 +1,241 @@ +<% +local api = require "luci.passwall2.api" +-%> + +
+

<%:Backup and Restore%>

+
+ <%:Backup or Restore Client and Server Configurations.%> +
+ <%:Note: Restoring configurations across different versions may cause compatibility issues.%> +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + + + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/global/faq.htm b/luci-app-passwall2/luasrc/view/passwall2/global/faq.htm new file mode 100644 index 00000000..b3c26ff5 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/global/faq.htm @@ -0,0 +1,66 @@ +<% +local api = require "luci.passwall2.api" +-%> + +
+
+
    + <%:DNS related issues:%> +
  • 1. <%:Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off.%>
  • +
  • 2. <%:If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):%> +
    • â—¦ <%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%>
    • +
    • â—¦ <%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%>
    • +
    • â—¦ <%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%>
    • +
    +
  • +
  • 3. <%:Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed.%>
  • +
+
+
+
+ + diff --git a/luci-app-passwall2/luasrc/view/passwall2/global/footer.htm b/luci-app-passwall2/luasrc/view/passwall2/global/footer.htm new file mode 100644 index 00000000..e1ba5c58 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/global/footer.htm @@ -0,0 +1,244 @@ +<% +local api = self.api +local appname = api.appname +-%> + + \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/view/passwall2/global/status.htm b/luci-app-passwall2/luasrc/view/passwall2/global/status.htm new file mode 100644 index 00000000..03b2e56d --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/global/status.htm @@ -0,0 +1,197 @@ +<% +local api = require "luci.passwall2.api" +-%> + + + +
+
+
+
+
+
+ +
+
+
+

Core
<%:NOT RUNNING%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:Baidu Connection%>
<%:Touch Check%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:Google Connection%>
<%:Touch Check%>

+
+
+
+
+
+
+
+ +
+
+
+

<%:GitHub Connection%>
<%:Touch Check%>

+
+
+
+
+ +
diff --git a/luci-app-passwall2/luasrc/view/passwall2/haproxy/js.htm b/luci-app-passwall2/luasrc/view/passwall2/haproxy/js.htm new file mode 100644 index 00000000..aca4d853 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/haproxy/js.htm @@ -0,0 +1,238 @@ +<% +local api = require "luci.passwall2.api" +local appname = api.appname +-%> + + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/haproxy/status.htm b/luci-app-passwall2/luasrc/view/passwall2/haproxy/status.htm new file mode 100644 index 00000000..639edf43 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/haproxy/status.htm @@ -0,0 +1,30 @@ +<% +local api = require "luci.passwall2.api" +local haproxy_enable = api.uci_get_type("global_haproxy", "balancing_enable", "0") +local console_port = api.uci_get_type("global_haproxy", "console_port", "") +-%> +

+ + diff --git a/luci-app-passwall2/luasrc/view/passwall2/include/shunt_options.htm b/luci-app-passwall2/luasrc/view/passwall2/include/shunt_options.htm new file mode 100644 index 00000000..9dcc05c7 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/include/shunt_options.htm @@ -0,0 +1,76 @@ + + \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/view/passwall2/log/log.htm b/luci-app-passwall2/luasrc/view/passwall2/log/log.htm new file mode 100644 index 00000000..4e6714ed --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/log/log.htm @@ -0,0 +1,44 @@ +<% +local api = require "luci.passwall2.api" +-%> + +
+ + +
diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_config/footer.htm b/luci-app-passwall2/luasrc/view/passwall2/node_config/footer.htm new file mode 100644 index 00000000..feefc4dd --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/node_config/footer.htm @@ -0,0 +1,48 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_config/header.htm b/luci-app-passwall2/luasrc/view/passwall2/node_config/header.htm new file mode 100644 index 00000000..7ab46a96 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/node_config/header.htm @@ -0,0 +1,56 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm b/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm new file mode 100644 index 00000000..7b7ed9a6 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm @@ -0,0 +1,1863 @@ +<%+cbi/valueheader%> +<% +local api = require "luci.passwall2.api" +local appname = api.appname +local map = self.map + +local has_ss_rust = api.is_finded("sslocal") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") + +local ss_type = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}}) +local trojan_type = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}}) +local vmess_type = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local vless_type = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local hysteria2_type = api.get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{has_singbox,"sing-box"}, {has_xray,"xray"}}) + +local current_node = map:get(section) +-%> + + + + +<%+cbi/valuefooter%> diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_list/link_add_node.htm b/luci-app-passwall2/luasrc/view/passwall2/node_list/link_add_node.htm new file mode 100644 index 00000000..237cfb82 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/node_list/link_add_node.htm @@ -0,0 +1,556 @@ +<% +local api = require "luci.passwall2.api" +-%> + + + + + + + +
+
+

<%:Reassign Node Group%>

+
+
+ +
+
+ <%:default%> + +
+ + +
+
+
+
+ + +
+
+
+ + + +
+
+ + + + + + + + + +
+
+ + diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm b/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm new file mode 100644 index 00000000..115186f4 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/node_list/node_list.htm @@ -0,0 +1,1127 @@ +<% +local api = require "luci.passwall2.api" +local appname = api.appname +local uci = api.uci + +local default_node_type = "" +local shunt_rule_list = {} +local node = api.uci_get_type("global", "node") +if node then + local node_type = api.uci_get_type_id(node, "type") + local node_protocol = api.uci_get_type_id(node, "protocol") + if node_type == "Xray" and node_protocol == "_shunt" then + default_node_type = node_protocol + uci:foreach(appname, "shunt_rules", function(e) + if e[".name"] and e.remarks then + shunt_rule_list[#shunt_rule_list + 1] = e + end + end) + end +end +-%> + + + + +<% if api.is_js_luci() then -%> + +<%- else %> + +<%- end %> + + + + + + + + +
+
+ + + +
+
+
+ <%:You choose node is:%> +
+
+ <%- if default_node_type == "_shunt" then + for i, v in ipairs(shunt_rule_list) do + -%> + ')" value="<%=v.remarks%>" /> + <%- + end + -%> + <% else %> + + <% end %> + +
+
+
diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_subscribe/js.htm b/luci-app-passwall2/luasrc/view/passwall2/node_subscribe/js.htm new file mode 100644 index 00000000..a090a2ea --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/node_subscribe/js.htm @@ -0,0 +1,276 @@ +<% +local api = require "luci.passwall2.api" +-%> + + + + + diff --git a/luci-app-passwall2/luasrc/view/passwall2/rule/geoview.htm b/luci-app-passwall2/luasrc/view/passwall2/rule/geoview.htm new file mode 100644 index 00000000..7362c1c9 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/rule/geoview.htm @@ -0,0 +1,111 @@ +<% +local api = require "luci.passwall2.api" +-%> + + + +
+
    + <%:Tips:%> +
  • 1. <%:By entering a domain or IP, you can query the Geo rule list they belong to.%>
  • +
  • 2. <%:By entering a GeoIP or Geosite, you can extract the domains/IPs they contain.%>
  • +
  • 3. <%:Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct.%>
  • +
+
+
+ +
+ +
+ <%:Enter a domain or IP to query the Geo rule list they belong to.%> +
+
+
+
+ +
+ +
+ <%:Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw%> +
+
+
+
+ +
+ + \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/view/passwall2/rule/rule_version.htm b/luci-app-passwall2/luasrc/view/passwall2/rule/rule_version.htm new file mode 100644 index 00000000..f5fbce49 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/rule/rule_version.htm @@ -0,0 +1,274 @@ +<% +local api = require "luci.passwall2.api" +local fs = api.fs +local has_old_geoip = fs.access("/tmp/bak_v2ray/geoip.dat") +local has_old_geosite = fs.access("/tmp/bak_v2ray/geosite.dat") +-%> + + + + +
+ +
+
+ + +

+ + <% if has_old_geoip then %> + + <% end %> + <% if has_old_geosite then %> + + <% end %> +
+
+
+ + diff --git a/luci-app-passwall2/luasrc/view/passwall2/server/config_footer.htm b/luci-app-passwall2/luasrc/view/passwall2/server/config_footer.htm new file mode 100644 index 00000000..7b835ec2 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/server/config_footer.htm @@ -0,0 +1,27 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall2/luasrc/view/passwall2/server/config_header.htm b/luci-app-passwall2/luasrc/view/passwall2/server/config_header.htm new file mode 100644 index 00000000..1957dec4 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/server/config_header.htm @@ -0,0 +1,56 @@ +<% +local api = self.api +-%> + diff --git a/luci-app-passwall2/luasrc/view/passwall2/server/log.htm b/luci-app-passwall2/luasrc/view/passwall2/server/log.htm new file mode 100644 index 00000000..28d9dd25 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/server/log.htm @@ -0,0 +1,47 @@ +<% +local api = require "luci.passwall2.api" +-%> + +
+ + <%:Logs%> + + + +
\ No newline at end of file diff --git a/luci-app-passwall2/luasrc/view/passwall2/server/users_list_status.htm b/luci-app-passwall2/luasrc/view/passwall2/server/users_list_status.htm new file mode 100644 index 00000000..390b7d05 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/server/users_list_status.htm @@ -0,0 +1,38 @@ +<% +local api = require "luci.passwall2.api" +-%> + \ No newline at end of file diff --git a/luci-app-passwall2/luasrc/view/passwall2/socks_auto_switch/btn.htm b/luci-app-passwall2/luasrc/view/passwall2/socks_auto_switch/btn.htm new file mode 100644 index 00000000..2ad1dbe8 --- /dev/null +++ b/luci-app-passwall2/luasrc/view/passwall2/socks_auto_switch/btn.htm @@ -0,0 +1,45 @@ +<% +local api = require "luci.passwall2.api" +-%> + + + +
" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>"> + +
+ + +
+
diff --git a/luci-app-passwall2/po/fa/passwall2.po b/luci-app-passwall2/po/fa/passwall2.po new file mode 100644 index 00000000..dfb60669 --- /dev/null +++ b/luci-app-passwall2/po/fa/passwall2.po @@ -0,0 +1,2387 @@ +msgid "Auto" +msgstr "خودکار" + +msgid "RUNNING" +msgstr "در حال اجرا" + +msgid "NOT RUNNING" +msgstr "متوق٠شده" + +msgid "Working..." +msgstr "در حال کار..." + +msgid "Problem detected!" +msgstr "مشکل شناسایی شد!" + +msgid "Touch Check" +msgstr "بررسی اتصال" + +msgid "Global" +msgstr "سراسری" + +msgid "Kernel Unsupported" +msgstr "هسته پشتیبانی نمی‌شود" + +msgid "Basic Settings" +msgstr "تنظیمات پایه" + +msgid "Node List" +msgstr "لیست گره‌ها" + +msgid "Other Settings" +msgstr "تنظیمات دیگر" + +msgid "Load Balancing" +msgstr "توزیع بار" + +msgid "Enter interface" +msgstr "رابط ورود" + +msgid "Rule Manage" +msgstr "مدیریت قوانین" + +msgid "Rule List" +msgstr "لیست قوانین" + +msgid "Access control" +msgstr "کنترل دسترسی" + +msgid "Runtime Logs" +msgstr "گزارش‌های زمان اجرا" + +msgid "Node Config" +msgstr "پیکربندی گره" + +msgid "Running Status" +msgstr "وضعیت اجرا" + +msgid "Baidu Connection" +msgstr "اتصال بایدو" + +msgid "Google Connection" +msgstr "اتصال Ú¯ÙˆÚ¯Ù„" + +msgid "GitHub Connection" +msgstr "اتصال گیت‌هاب" + +msgid "Instagram Connection" +msgstr "اتصال اینستاگرام" + +msgid "Node Check" +msgstr "بررسی گره" + +msgid "Check..." +msgstr "بررسی..." + +msgid "Clear" +msgstr "پاک کردن" + +msgid "Main switch" +msgstr "سوئیچ اصلی" + +msgid "Node" +msgstr "گره" + +msgid "Edit Current Node" +msgstr "ویرایش گره ÙØ¹Ù„ÛŒ" + +msgid "Localhost Proxy" +msgstr "پروکسی میزبان محلی" + +msgid "When selected, localhost can transparent proxy." +msgstr "در صورت انتخاب، میزبان محلی می‌تواند از پروکسی Ø´ÙØ§Ù Ø§Ø³ØªÙØ§Ø¯Ù‡ کند." + +msgid "Client Proxy" +msgstr "پروکسی کلاینت" + +msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy." +msgstr "" +"در صورت انتخاب، دستگاه‌های شبکه داخلی (LAN) از پروکسی Ø´ÙØ§Ù Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌کنند. " +"در غیر این صورت، تراÙیک آن‌ها از پروکسی عبور نمی‌کند. با این حال، همچنان می‌توانید از طریق کنترل دسترسی " +"به دستگاه‌های خاص اجازه Ø§Ø³ØªÙØ§Ø¯Ù‡ از پروکسی را بدهید." + +msgid "Missing components, transparent proxy is unavailable." +msgstr "اجزای مورد نیاز ÛŒØ§ÙØª نشد، پروکسی Ø´ÙØ§Ù در دسترس نیست." + +msgid "Socks Config" +msgstr "پیکربندی Socks" + +msgid "Socks Node" +msgstr "گره Socks" + +msgid "Current Node" +msgstr "گره ÙØ¹Ù„ÛŒ" + +msgid "Listen Port" +msgstr "پورت شنود" + +msgid "0 is not use" +msgstr "0 به معنای عدم Ø§Ø³ØªÙØ§Ø¯Ù‡ است" + +msgid "Current node: %s" +msgstr "گره ÙØ¹Ù„ÛŒ: %s" + +msgid "Direct domain DNS routing" +msgstr "مسیریابی مستقیم DNS دامنه" + +msgid "Please note that the program will not start if the format is incorrect!" +msgstr "Ù„Ø·ÙØ§ توجه داشته باشید Ú©Ù‡ اگر قالب نادرست باشد، برنامه شروع نخواهد شد!" + +msgid "IP:Port mode acceptable, multi value split with english comma." +msgstr "حالت IP:Port قابل قبول است، مقادیر متعدد را با کاما انگلیسی جدا کنید." + +msgid "Direct DNS Protocol" +msgstr "پروتکل DNS مستقیم" + +msgid "Direct DNS" +msgstr "DNS مستقیم" + +msgid "Direct DNS DoH" +msgstr "DNS مستقیم DoH" + +msgid "Direct DNS EDNS Client Subnet" +msgstr "زیرشبکه کلاینت EDNS برای DNS مستقیم" + +msgid "Remote DNS Protocol" +msgstr "پروتکل DNS راه دور" + +msgid "Remote DNS" +msgstr "DNS راه دور" + +msgid "Remote DNS DoH" +msgstr "DNS راه دور DoH" + +msgid "Remote DNS EDNS Client Subnet" +msgstr "زیرشبکه کلاینت EDNS برای DNS راه دور" + +msgid "Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address)." +msgstr "به سرور DNS اطلاع دهید Ú©Ù‡ کلاینت در Ú†Ù‡ موقعیتی قرار دارد (نمی‌تواند آدرس IP خصوصی باشد)." + +msgid "This feature requires the DNS server to support the Edns Client Subnet (RFC7871)." +msgstr "این ویژگی نیازمند پشتیبانی سرور DNS از زیرشبکه کلاینت EDNS (RFC7871) است." + +msgid "Remote DNS Outbound" +msgstr "خروجی DNS راه دور" + +msgid "Remote" +msgstr "راه دور" + +msgid "Direct" +msgstr "مستقیم" + +msgid "Direct Query Strategy" +msgstr "استراتژی پرس‌وجوی مستقیم" + +msgid "Remote Query Strategy" +msgstr "استراتژی پرس‌وجوی راه دور" + +msgid "Use FakeDNS work in the domain that proxy." +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از FakeDNS در دامنه‌هایی Ú©Ù‡ پروکسی می‌شوند." + +msgid "Suitable scenarios for let the node servers get the target domain names." +msgstr "سناریوهای مناسب برای اینکه سرورهای گره نام دامنه هد٠را Ø¯Ø±ÛŒØ§ÙØª کنند." + +msgid "Such as: DNS unlocking of streaming media, reducing DNS query latency, etc." +msgstr "مانند: Ø±ÙØ¹ Ùیلتر DNS رسانه‌های جریانی، کاهش تاخیر پرس‌وجوی DNS Ùˆ غیره." + +msgid "Domain Override" +msgstr "بازنویسی دامنه" + +msgid "Direct DNS result write to IPSet" +msgstr "نتیجه DNS مستقیم در IPSet نوشته شود" + +msgid "Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core)." +msgstr "قوانین نام دامنه مستقیم منطبق را به IP در IPSet/NFTSet تبدیل کرده Ùˆ سپس مستقیماً متصل شود (بدون ورود به هسته)." + +msgid "Maybe conflict with some special circumstances." +msgstr "ممکن است با برخی شرایط خاص تداخل داشته باشد." + +msgid "DNS Redirect" +msgstr "تغییر مسیر DNS" + +msgid "Force special DNS server to need proxy devices." +msgstr "اجبار دستگاه‌های پروکسی به Ø§Ø³ØªÙØ§Ø¯Ù‡ از سرور DNS خاص." + +msgid "Clear IPSET" +msgstr "پاک کردن IPSET" + +msgid "Clear NFTSET" +msgstr "پاک کردن NFTSET" + +msgid "Try this feature if the rule modification does not take effect." +msgstr "اگر تغییر قوانین تاثیری نداشت، این ویژگی را امتحان کنید." + +msgid "About DNS issues:" +msgstr "درباره مشکلات DNS:" + +msgid "Some browsers may have built-in DNS, be sure to close. Example: Chrome. Settings - Security and Privacy - Security - Use secure DNS disabled." +msgstr "برخی مرورگرها (مانند کروم) ممکن است DNS داخلی داشته باشند؛ Ù„Ø·ÙØ§Ù‹ آن را ØºÛŒØ±ÙØ¹Ø§Ù„ کنید. مسیر: تنظیمات > امنیت Ùˆ حریم خصوصی > امنیت > Ø§Ø³ØªÙØ§Ø¯Ù‡ از DNS امن را ØºÛŒØ±ÙØ¹Ø§Ù„ کنید." + +msgid "Sometimes after restart, you can not internet. At this time, close all browsers (important), Windows Client, please `ipconfig /flushdns`. Please close the WiFi on the phone, cut the flight mode and then cut back." +msgstr "گاهی اوقات پس از راه‌اندازی مجدد، دسترسی به اینترنت قطع می‌شود. در این صورت، تمام مرورگرها را ببندید (مهم)ØŒ در کلاینت ویندوز دستور `ipconfig /flushdns` را اجرا کنید. ÙˆØ§ÛŒâ€ŒÙØ§ÛŒ گوشی را خاموش Ùˆ روشن کنید یا حالت پرواز را ÙØ¹Ø§Ù„ Ùˆ ØºÛŒØ±ÙØ¹Ø§Ù„ نمایید." + +msgid "The client DNS and the default gateway must point to this router." +msgstr "DNS کلاینت Ùˆ دروازه Ù¾ÛŒØ´â€ŒÙØ±Ø¶ باید به این روتر اشاره کنند." + +msgid "If you have a wrong DNS process, the consequences are at your own risk!" +msgstr "اگر ÙØ±Ø¢ÛŒÙ†Ø¯ DNS اشتباهی دارید، عواقب آن با خودتان است!" + +msgid "Hide menu method, input example in the address bar:" +msgstr "روش مخÙÛŒ کردن منو، مثال ورودی در نوار آدرس:" + +msgid "After the hidden to the display, input example in the address bar:" +msgstr "پس از مخÙÛŒ شدن برای نمایش، مثال ورودی در نوار آدرس:" + +msgid "Are you sure to hide?" +msgstr "آیا مطمئن هستید Ú©Ù‡ مخÙÛŒ شود؟" + +msgid "DNS related issues:" +msgstr "مشکلات مربوط به DNS:" + +msgid "Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off." +msgstr "مرورگرهای خاصی مانند Chrome دارای سرویس DNS داخلی هستند Ú©Ù‡ ممکن است بر تنظیمات تÙکیک DNS تأثیر بگذارد. می‌توانید به منوی 'تنظیمات -> حریم خصوصی Ùˆ امنیت -> Ø§Ø³ØªÙØ§Ø¯Ù‡ از DNS امن' بروید تا آن را خاموش کنید." + +msgid "If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):" +msgstr "اگر پس از راه‌اندازی مجدد قادر به دسترسی به اینترنت نیستید، Ù„Ø·ÙØ§Ù‹ سعی کنید Ú©Ø´ دستگاه‌های نهایی خود را پاک کنید (حتماً ابتدا تمام پنجره‌های برنامه مرورگر باز را ببندید، این مرحله بسیار مهم است):" + +msgid "For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'." +msgstr "برای سیستم‌های ویندوز، Command Prompt را باز کرده Ùˆ دستور 'ipconfig /flushdns' را اجرا کنید." + +msgid "For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'." +msgstr "برای سیستم‌های Ù…Ú©ØŒ ترمینال را باز کرده Ùˆ دستور 'sudo killall -HUP mDNSResponder' را اجرا کنید." + +msgid "For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi." +msgstr "برای دستگاه‌های تلÙÙ† همراه، می‌توانید با اتصال مجدد به شبکه، مانند روشن Ùˆ خاموش کردن حالت هواپیما Ùˆ اتصال مجدد به ÙˆØ§ÛŒâ€ŒÙØ§ÛŒØŒ آن را پاک کنید." + +msgid "Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed." +msgstr "Ù„Ø·ÙØ§Ù‹ مطمئن شوید Ú©Ù‡ تنظیمات شبکه دستگاه شما هم سرور DNS Ùˆ هم دروازه Ù¾ÛŒØ´â€ŒÙØ±Ø¶ را به این روتر ارجاع می‌دهد تا اطمینان حاصل شود Ú©Ù‡ پرس‌وجوهای DNS به درستی هدایت می‌شوند." + +msgid "Browser access:" +msgstr "دسترسی مرورگر:" + +msgid "Hide in main menu:" +msgstr "مخÙÛŒ کردن در منوی اصلی:" + +msgid "Show in main menu:" +msgstr "نمایش در منوی اصلی:" + +msgid "DNS Export Of Multi WAN" +msgstr "خروجی DNS برای چند WAN" + +msgid "Node Export Of Multi WAN" +msgstr "خروجی گره برای چند WAN" + +msgid "Only support Multi Wan." +msgstr "Ùقط از چند WAN پشتیبانی می‌کند." + +msgid "Not Specify" +msgstr "نامشخص" + +msgid "custom" +msgstr "Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "If not available, try clearing the cache." +msgstr "در صورت عدم دسترسی، پاک کردن Ú©Ø´ را امتحان کنید." + +msgid "Operation" +msgstr "عملیات" + +msgid "Add Node" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره" + +msgid "Add the node via the link" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره از طریق لینک" + +msgid "Enter share links, one per line. Subscription links are not supported!" +msgstr "لینک‌های اشتراک‌گذاری را وارد کنید، هر کدام در یک خط. لینک‌های اشتراک (Subscription) پشتیبانی نمی‌شوند!" + +msgid "Please enter the correct link." +msgstr "Ù„Ø·ÙØ§Ù‹ لینک صحیح را وارد کنید." + +msgid "Clear all nodes" +msgstr "پاک کردن همه گره‌ها" + +msgid "Are you sure to clear all nodes?" +msgstr "آیا از پاک کردن همه گره‌ها اطمینان دارید؟" + +msgid "Success" +msgstr "موÙقیت" + +msgid "Error" +msgstr "خطا" + +msgid "Delete select nodes" +msgstr "حذ٠گره‌های انتخاب شده" + +msgid "To Top" +msgstr "به بالا" + +msgid "Select" +msgstr "انتخاب" + +msgid "Selected:" +msgstr "انتخاب شده:" + +msgid "DeSelect" +msgstr "لغو انتخاب" + +msgid "Select all" +msgstr "انتخاب همه" + +msgid "DeSelect all" +msgstr "لغو انتخاب همه" + +msgid "Are you sure to delete select nodes?" +msgstr "آیا از حذ٠گره‌های انتخاب شده اطمینان دارید؟" + +msgid "You no select nodes !" +msgstr "شما هیچ گره‌ای انتخاب نکرده‌اید!" + +msgid "Are you sure set to" +msgstr "آیا مطمئن هستید Ú©Ù‡ تنظیم شود به" + +msgid "the server?" +msgstr "سرور؟" + +msgid "You choose node is:" +msgstr "گره انتخابی شما عبارتست از:" + +msgid "Timeout" +msgstr "مهلت زمانی" + +msgid "Node Remarks" +msgstr "توضیحات گره" + +msgid "Add Mode" +msgstr "حالت Ø§ÙØ²ÙˆØ¯Ù†" + +msgid "Save Order" +msgstr "ذخیره ترتیب" + +msgid "Saved current page order successfully." +msgstr "ترتیب ØµÙØ­Ù‡ جاری با موÙقیت ذخیره شد." + +msgid "Drag to reorder" +msgstr "برای تغییر ترتیب بکشید" + +msgid "Type" +msgstr "نوع" + +msgid "_balancing" +msgstr "_توزیع بار" + +msgid "_shunt" +msgstr "_شنت (Shunt)" + +msgid "Balancing" +msgstr "توزیع بار" + +msgid "Node Addition Method" +msgstr "روش Ø§ÙØ²ÙˆØ¯Ù† گره" + +msgid "Manual" +msgstr "دستی" + +msgid "Batch" +msgstr "دسته‌ای" + +msgid "Select Group" +msgstr "انتخاب گروه" + +msgid "Node Matching Rules" +msgstr "قوانین تطبیق گره" + +msgid "" +"Example: ^A && B && !C && D$
" +"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" +"Conditions are joined by &&, and their order does not affect the result." +msgstr "" +"مثال: ^A && B && !C && D$
" +"این بدان معناست Ú©Ù‡ توضیحات گره باید با A شروع شود (^)ØŒ شامل B باشد، ÙØ§Ù‚د C باشد (!)ØŒ Ùˆ با D پایان یابد ($).
" +"شرط‌ها با && به هم متصل می‌شوند Ùˆ ترتیب آنها تاثیری در نتیجه ندارد." + + +msgid "Balancing Strategy" +msgstr "استراتژی توزیع بار" + +msgid "Fallback Node" +msgstr "گره پشتیبان" + +msgid "Use Custom Probe URL" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از URL پروب Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL." +msgstr "به‌صورت Ù¾ÛŒØ´â€ŒÙØ±Ø¶ از URL پروب داخلی Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود، برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از URL Ø³ÙØ§Ø±Ø´ÛŒ این گزینه را ÙØ¹Ø§Ù„ کنید." + +msgid "Probe URL" +msgstr "URL پروب" + +msgid "The URL used to detect the connection status." +msgstr "آدرس URL مورد Ø§Ø³ØªÙØ§Ø¯Ù‡ برای تشخیص وضعیت اتصال." + +msgid "Probe Interval" +msgstr "ÙØ§ØµÙ„Ù‡ زمانی پروب" + +msgid "The interval between initiating probes." +msgstr "ÙØ§ØµÙ„Ù‡ زمانی بین شروع پروب‌ها." + +msgid "The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively." +msgstr "ÙØ±Ù…ت زمان عدد + واحد است، مانند '10s'ØŒ '2h45m'ØŒ Ùˆ واحدهای زمانی پشتیبانی شده sØŒ mØŒ h هستند Ú©Ù‡ به ترتیب ثانیه، دقیقه Ùˆ ساعت می‌باشند." + +msgid "When the unit is not filled in, it defaults to seconds." +msgstr "زمانی Ú©Ù‡ واحد پر نشده باشد، Ù¾ÛŒØ´â€ŒÙØ±Ø¶ ثانیه است." + +msgid "Preferred Node Count" +msgstr "تعداد گره‌های ترجیحی" + +msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them." +msgstr "توزیع‌کننده بار تعداد بهینه‌ای از گره‌ها را انتخاب می‌کند Ùˆ تراÙیک به طور تصادÙÛŒ بین آن‌ها توزیع می‌شود." + +msgid "Failure Tolerance (%)" +msgstr "تحمل شکست (%)" + +msgid "The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate." +msgstr "حداکثر نرخ شکست قابل قبول در تست سرعت. برای مثال، عدد Û± به معنای مجاز بودن نرخ شکست Û±Ùª است. + +msgid "Shunt" +msgstr "شنت (Shunt)" + +msgid "Preproxy" +msgstr "پیش‌پروکسی" + +msgid "Preproxy Node" +msgstr "گره پیش‌پروکسی" + +msgid "Set the node to be used as a pre-proxy." +msgstr "گره را طوری تنظیم کنید Ú©Ù‡ به عنوان پیش پروکسی Ø§Ø³ØªÙØ§Ø¯Ù‡ شود." + +msgid "Each rule has a separate switch that controls whether this rule uses the pre-proxy or not." +msgstr "هر قانون یک سوئیچ جداگانه دارد Ú©Ù‡ کنترل می‌کند آیا این قانون از پیش-پروکسی Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌کند یا خیر." + +msgid "Close (Not use)" +msgstr "بستن (عدم Ø§Ø³ØªÙØ§Ø¯Ù‡)" + +msgid "Use default node" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از گره Ù¾ÛŒØ´â€ŒÙØ±Ø¶" + +msgid "Direct Connection" +msgstr "اتصال مستقیم" + +msgid "Blackhole (Block)" +msgstr "سیاه‌چاله (مسدودسازی)" + +msgid "There are no available nodes, please add or subscribe nodes first." +msgstr "هیچ گره در دسترس نیست، Ù„Ø·ÙØ§Ù‹ ابتدا گره‌ها را اضاÙÙ‡ یا مشترک شوید." + +msgid "No shunt rules? Click me to go to add." +msgstr "قانون شنتی وجود ندارد؟ برای Ø§ÙØ²ÙˆØ¯Ù† اینجا کلیک کنید." + +msgid "When using, localhost will connect this node first and then use this node to connect the default node." +msgstr "در صورت Ø§Ø³ØªÙØ§Ø¯Ù‡ØŒ میزبان محلی ابتدا به این گره متصل شده Ùˆ سپس از این گره برای اتصال به گره Ù¾ÛŒØ´â€ŒÙØ±Ø¶ Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌کند." + +msgid "Domain Strategy" +msgstr "استراتژی دامنه" + +msgid "Domain matcher" +msgstr "تتطبیق‌دهنده دامنه" + +msgid "'AsIs': Only use domain for routing. Default value." +msgstr "'AsIs': Ùقط Ø§Ø³ØªÙØ§Ø¯Ù‡ از دامنه برای مسیریابی. مقدار Ù¾ÛŒØ´â€ŒÙØ±Ø¶." + +msgid "'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again." +msgstr "" +"'IPIfNonMatch': زمانی Ú©Ù‡ هیچ قانونی با دامنه ÙØ¹Ù„ÛŒ مطابقت ندارد، آن را به آدرس‌های IP " +"(رکوردهای A یا AAAA) حل می‌کند Ùˆ تمام قوانین را دوباره امتحان می‌کند." + +msgid "'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately." +msgstr "" +"'IPOnDemand': تا زمانی Ú©Ù‡ یک قانون مبتنی بر IP وجود داشته باشد، Ø¨Ù„Ø§ÙØ§ØµÙ„Ù‡ دامنه را به " +"IP حل می‌کند." + +msgid "Load balancing node list" +msgstr "لیست گره‌های توزیع بار" + +msgid "Load balancing node list, document" +msgstr "لیست گره‌های توزیع بار، مستندات" + +msgid "From Share URL" +msgstr "از لینک اشتراک‌گذاری" + +msgid "Build Share URL" +msgstr "ساخت لینک اشتراک‌گذاری" + +msgid "Generate QRCode" +msgstr "تولید کد QR" + +msgid "Export Config File" +msgstr "خروجی ÙØ§ÛŒÙ„ پیکربندی" + +msgid "Import Finished" +msgstr "وارد کردن پایان ÛŒØ§ÙØª" + +msgid "Not a supported scheme:" +msgstr "طرح پشتیبانی نشده:" + +msgid "Invalid Share URL Format" +msgstr "ÙØ±Ù…ت لینک اشتراک‌گذاری نامعتبر" + +msgid "Paste Share URL Here" +msgstr "لینک اشتراک‌گذاری را اینجا جایگذاری کنید" + +msgid "Share URL to clipboard unable." +msgstr "Ú©Ù¾ÛŒ لینک اشتراک‌گذاری در کلیپ‌بورد ناموÙÙ‚ بود." + +msgid "Share URL to clipboard successfully." +msgstr "لینک اشتراک‌گذاری با موÙقیت در کلیپ‌بورد Ú©Ù¾ÛŒ شد." + +msgid "Faltal on get option, please help in debug:" +msgstr "خطای مهلک در Ø¯Ø±ÛŒØ§ÙØª گزینه، Ù„Ø·ÙØ§Ù‹ در اشکال‌زدایی Ú©Ù…Ú© کنید:" + +msgid "Faltal on set option, please help in debug:" +msgstr "خطای مهلک در تنظیم گزینه، Ù„Ø·ÙØ§Ù‹ در اشکال‌زدایی Ú©Ù…Ú© کنید:" + +msgid "Address" +msgstr "آدرس" + +msgid "Address (Support Domain Name)" +msgstr "آدرس (پشتیبانی از نام دامنه)" + +msgid "Trojan Verify Cert" +msgstr "تایید گواهی Trojan" + +msgid "Trojan Cert Path" +msgstr "مسیر گواهی Trojan" + +msgid "Finger Print" +msgstr "اثر انگشت (Fingerprint)" + +msgid "Avoid using randomized, unless you have to." +msgstr "از Ø§Ø³ØªÙØ§Ø¯Ù‡ از تصادÙÛŒ خودداری کنید، مگر اینکه مجبور باشید." + +msgid "Original" +msgstr "اصلی" + +msgid "Transport Plugin" +msgstr "Ø§ÙØ²ÙˆÙ†Ù‡ انتقال" + +msgid "Obfs Type" +msgstr "نوع مبهم‌سازی (Obfs)" + +msgid "Obfs Password" +msgstr "رمز عبور مبهم‌سازی" + +msgid "Auth Type" +msgstr "نوع احراز هویت" + +msgid "Auth Password" +msgstr "رمز عبور احراز هویت" + +msgid "Client BBR Flow Control" +msgstr "کنترل BBR مشتری" + +msgid "Commands the client to use the BBR flow control algorithm" +msgstr "به کلاینت دستور می‌دهد تا از الگوریتم کنترل جریان BBR Ø§Ø³ØªÙØ§Ø¯Ù‡ کند" + +msgid "PinSHA256" +msgstr "PinSHA256" + +msgid "Certificate fingerprint" +msgstr "اثر انگشت گواهی" + +msgid "Max upload Mbps" +msgstr "حداکثر آپلود (Mbps)" + +msgid "Max download Mbps" +msgstr "حداکثر دانلود (Mbps)" + +msgid "QUIC stream receive window" +msgstr "پنجره Ø¯Ø±ÛŒØ§ÙØª جریان QUIC" + +msgid "QUIC connection receive window" +msgstr "پنجره Ø¯Ø±ÛŒØ§ÙØª اتصال QUIC" + +msgid "QUIC concurrent bidirectional streams" +msgstr "جریان‌های دوطرÙÙ‡ همزمان QUIC" + +msgid "QUIC KeepAlive interval" +msgstr "ÙØ§ØµÙ„Ù‡ QUIC KeepAlive" + +msgid "Disable MTU detection" +msgstr "ØºÛŒØ±ÙØ¹Ø§Ù„ کردن تشخیص MTU" + +msgid "ignoreClientBandwidth" +msgstr "نادیده Ú¯Ø±ÙØªÙ† پهنای باند کلاینت" + +msgid "Lazy Start" +msgstr "شروع تنبل (Lazy Start)" + +msgid "Encrypt Method" +msgstr "روش رمزنگاری" + +msgid "Encrypt Key" +msgstr "کلید رمزنگاری" + +msgid "Latency" +msgstr "تاخیر" + +msgid "Automatic detection delay" +msgstr "تاخیر تشخیص خودکار" + +msgid "Show server address and port" +msgstr "نمایش آدرس Ùˆ پورت سرور" + +msgid "URL Test Address" +msgstr "آدرس تست URL" + +msgid "URL Test" +msgstr "تست URL" + +msgid "Test" +msgstr "تست" + +msgid "Node num" +msgstr "شماره گره" + +msgid "Self add" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† خودکار" + +msgid "Apply" +msgstr "اعمال" + +msgid "Use" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡" + +msgid "Copy" +msgstr "Ú©Ù¾ÛŒ" + +msgid "Delay Settings" +msgstr "تنظیمات تاخیر" + +msgid "Open and close Daemon" +msgstr "باز Ùˆ بسته کردن دیمن (Daemon)" + +msgid "Delay Start" +msgstr "شروع با تاخیر" + +msgid "Units:seconds" +msgstr "واحد: ثانیه" + +msgid "Units:minutes" +msgstr "واحد: دقیقه" + +msgid "stop automatically mode" +msgstr "حالت توق٠خودکار" + +msgid "stop Time(Every day)" +msgstr "زمان توق٠(هر روز)" + +msgid "stop Interval(Hour)" +msgstr "بازه توق٠(ساعت)" + +msgid "start automatically mode" +msgstr "حالت شروع خودکار" + +msgid "start Time(Every day)" +msgstr "زمان شروع (هر روز)" + +msgid "start Interval(Hour)" +msgstr "بازه شروع (ساعت)" + +msgid "restart automatically mode" +msgstr "حالت راه‌اندازی مجدد خودکار" + +msgid "restart Time(Every day)" +msgstr "زمان راه‌اندازی مجدد (هر روز)" + +msgid "restart Interval(Hour)" +msgstr "بازه راه‌اندازی مجدد (ساعت)" + +msgid "Forwarding Settings" +msgstr "تنظیمات Ùورواردینگ" + +msgid "TCP No Redir Ports" +msgstr "پورت‌های بدون تغییر مسیر TCP" + +msgid "UDP No Redir Ports" +msgstr "پورت‌های بدون تغییر مسیر UDP" + +msgid "Fill in the ports you don't want to be forwarded by the agent, with the highest priority." +msgstr "پورت‌هایی را Ú©Ù‡ نمی‌خواهید توسط نماینده Ùوروارد شوند، با بالاترین اولویت وارد کنید." + +msgid "If you don't want to let the device in the list to go proxy, please choose all." +msgstr "اگر نمی‌خواهید دستگاه موجود در لیست پروکسی شود، Ù„Ø·ÙØ§Ù‹ همه را انتخاب کنید." + +msgid "The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000." +msgstr "تنظیمات پورت از پورت‌های تکی و بازه‌ها پشتیبانی می‌کند.
پورت‌های متعدد را با کاما (,) جدا کنید.
مثال: 21,80,443,1000:2000." + +msgid "TCP Proxy Drop Ports" +msgstr "پورت‌های حذ٠پروکسی TCP" + +msgid "UDP Proxy Drop Ports" +msgstr "پورت‌های حذ٠پروکسی UDP" + +msgid "TCP Redir Ports" +msgstr "پورت‌های تغییر مسیر TCP" + +msgid "UDP Redir Ports" +msgstr "پورت‌های تغییر مسیر UDP" + +msgid "No patterns are used" +msgstr "هیچ الگویی Ø§Ø³ØªÙØ§Ø¯Ù‡ نشده است" + +msgid "All" +msgstr "همه" + +msgid "Common Use" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ متداول" + +msgid "Only Web" +msgstr "Ùقط وب" + +msgid "or more" +msgstr "یا بیشتر" + +msgid "or less" +msgstr "یا کمتر" + +msgid "Default" +msgstr "Ù¾ÛŒØ´â€ŒÙØ±Ø¶" + +msgid "Close" +msgstr "بستن" + +msgid "Hijacking ICMP (PING)" +msgstr "ربودن ICMP (PING)" + +msgid "Hijacking ICMPv6 (IPv6 PING)" +msgstr "ربودن ICMPv6 (IPv6 PING)" + +msgid "Force Proxy LAN IP" +msgstr "IP پروکسی LAN را مجبور کنید" + +msgid "By default, commonly used internal network IP ranges will be connect directly (not entering the core). If you want a certain network range to go through a proxy, please add it here." +msgstr "به طور Ù¾ÛŒØ´â€ŒÙØ±Ø¶ØŒ محدوده‌های IP شبکه داخلی Ú©Ù‡ معمولاً Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شوند، مستقیماً متصل می‌شوند (Ùˆ وارد هسته نمی‌شوند). اگر می‌خواهید محدوده شبکه خاصی از طریق پروکسی عبور کند، Ù„Ø·ÙØ§Ù‹ آن را اینجا اضاÙÙ‡ کنید." + +msgid "Sniffing" +msgstr "شنود (Sniffing)" + +msgid "TCP Proxy Way" +msgstr "روش پروکسی TCP" + +msgid "Auto Switch" +msgstr "سوئیچ خودکار" + +msgid "When there is no server, an automatic reconnect scheme is used" +msgstr "زمانی Ú©Ù‡ هیچ سروری وجود ندارد، از طرح اتصال مجدد خودکار Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود" + +msgid "How often to test" +msgstr "هر چند وقت یکبار تست شود" + +msgid "Timeout seconds" +msgstr "ثانیه‌های مهلت زمانی" + +msgid "Timeout retry num" +msgstr "تعداد تلاش مجدد مهلت زمانی" + +msgid "Automatic switching cannot be used when this option is checked" +msgstr "زمانی Ú©Ù‡ این گزینه تیک خورده باشد، نمی‌توان از سوئیچینگ خودکار Ø§Ø³ØªÙØ§Ø¯Ù‡ کرد" + +msgid "Main node" +msgstr "گره اصلی" + +msgid "List of backup nodes" +msgstr "لیست گره‌های پشتیبان" + +msgid "Restore Switch" +msgstr "سوئیچ بازگردانی" + +msgid "When detects main node is available, switch back to the main node." +msgstr "زمانی Ú©Ù‡ در دسترس بودن گره اصلی تشخیص داده شود، به گره اصلی بازگردانده می‌شود." + +msgid "Add nodes to the standby node list by keywords" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره‌ها به لیست گره‌های آماده‌به‌کار با Ø§Ø³ØªÙØ§Ø¯Ù‡ از کلمات کلیدی" + +msgid "Delete nodes in the standby node list by keywords" +msgstr "حذ٠گره‌ها در لیست گره‌های آماده‌به‌کار با Ø§Ø³ØªÙØ§Ø¯Ù‡ از کلمات کلیدی" + +msgid "Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase." +msgstr "Ù„Ø·ÙØ§Ù‹ کلمه کلیدی گره را وارد کنید، به تمایز بین ÙØ§ØµÙ„ه، حرو٠بزرگ Ùˆ Ú©ÙˆÚ†Ú© توجه کنید." + +msgid "Enable Load Balancing" +msgstr "ÙØ¹Ø§Ù„‌سازی توزیع بار" + +msgid "Console Login Auth" +msgstr "احراز هویت ورود به کنسول" + +msgid "Console Username" +msgstr "نام کاربری کنسول" + +msgid "Console Password" +msgstr "رمز عبور کنسول" + +msgid "Console Port" +msgstr "پورت کنسول" + +msgid "In the browser input routing IP plus port access, such as:192.168.1.1:1188" +msgstr "در مرورگر IP مسیریابی به همراه پورت را وارد کنید، مانند: 192.168.1.1:1188" + +msgid "Haproxy Port" +msgstr "پورت Haproxy" + +msgid "Health Check Type" +msgstr "نوع بررسی سلامت" + +msgid "Inner implement" +msgstr "پیاده‌سازی داخلی" + +msgid "Health Check Inter" +msgstr "بازه بررسی سلامت" + +msgid "When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid." +msgstr "زمانی Ú©Ù‡ تست URL Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود، گره توزیع بار به یک گره Socks تبدیل می‌شود. زمانی Ú©Ù‡ لیست گره‌ها به صورت Ø³ÙØ§Ø±Ø´ÛŒ تنظیم شده باشد، باید یک گره Socks باشد، در غیر این صورت بررسی سلامت نامعتبر خواهد بود." + +msgid "Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group." +msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره، خروجی چند WAN تنها از چند WAN پشتیبانی می‌کند. محدوده وزن خاص بار 1-256. چندین سرور اصلی می‌توانند توزیع بار شوند، حالت آماده‌به‌کار تنها زمانی ÙØ¹Ø§Ù„ می‌شود Ú©Ù‡ سرور اصلی Ø¢Ùلاین باشد! چندین گروه قابل تنظیم است، پورت Haproxy برای هر گروه یکسان است." + +msgid "Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!" +msgstr "توجه داشته باشید Ú©Ù‡ پارامترهای پیکربندی گره برای توزیع بار باید در صورت Ø§Ø³ØªÙØ§Ø¯Ù‡ از نوع بررسی سلامت TCP یکسان باشند، در غیر این صورت نمی‌توان از آن به درستی Ø§Ø³ØªÙØ§Ø¯Ù‡ کرد!" + +msgid "Node Address" +msgstr "آدرس گره" + +msgid "Node address cannot be empty." +msgstr "آدرس گره نمی‌تواند خالی باشد." + +msgid "Node Port" +msgstr "پورت گره" + +msgid "Node Weight" +msgstr "وزن گره" + +msgid "Export Of Multi WAN" +msgstr "خروجی چند WAN" + +msgid "Main" +msgstr "اصلی" + +msgid "Mode" +msgstr "حالت" + +msgid "Primary" +msgstr "اولیه" + +msgid "Standby" +msgstr "آماده‌به‌کار" + +msgid "Check update" +msgstr "بررسی به‌روزرسانی" + +msgid "Force update" +msgstr "به‌روزرسانی اجباری" + +msgid "The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install." +msgstr "آخرین نسخه: %sØŒ در حال حاضر از به‌روزرسانی خودکار پشتیبانی نمی‌کند، اگر نیاز به به‌روزرسانی دارید، Ù„Ø·ÙØ§Ù‹ کامپایل کنید یا ÙØ§ÛŒÙ„ ipk را دانلود Ùˆ سپس دستی نصب کنید." + +msgid "Enable custom URL" +msgstr "ÙØ¹Ø§Ù„‌سازی URL Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "Rule status" +msgstr "وضعیت رول" + +msgid "Manually update" +msgstr "به‌روزرسانی دستی" + +msgid "Rollback" +msgstr "بازگردانی" + +msgid "Rollbacking..." +msgstr "در حال بازگردانی..." + +msgid "Enable auto update rules" +msgstr "ÙØ¹Ø§Ù„‌سازی به‌روزرسانی خودکار قوانین" + +msgid "Update Time(every day)" +msgstr "زمان به‌روزرسانی (هر روز)" + +msgid "Update Interval(hour)" +msgstr "بازه به‌روزرسانی (ساعت)" + +msgid "Update Mode" +msgstr "حالت به‌روزرسانی" + +msgid "Loop Mode" +msgstr "حالت حلقه" + +msgid "Every day" +msgstr "هر روز" + +msgid "Every Monday" +msgstr "هر دوشنبه" + +msgid "Every Tuesday" +msgstr "هر سه‌شنبه" + +msgid "Every Wednesday" +msgstr "هر چهارشنبه" + +msgid "Every Thursday" +msgstr "هر پنج‌شنبه" + +msgid "Every Friday" +msgstr "هر جمعه" + +msgid "Every Saturday" +msgstr "هر شنبه" + +msgid "Every Sunday" +msgstr "هر یکشنبه" + +msgid "hour" +msgstr "ساعت" + +msgid "Hour" +msgstr "ساعت" + +msgid "GeoIP Update URL" +msgstr "URL به‌روزرسانی GeoIP" + +msgid "Geosite Update URL" +msgstr "URL به‌روزرسانی Geosite" + +msgid "Location of Geo rule files" +msgstr "مکان ÙØ§ÛŒÙ„‌های قوانین Geo" + +msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." +msgstr "این متغیر دایرکتوری محل قرارگیری ÙØ§ÛŒÙ„‌های geoip.dat Ùˆ geosite.dat را مشخص می‌کند." + +msgid "Enable GeoIP Data Parsing" +msgstr "ÙØ¹Ø§Ù„‌سازی تجزیه داده‌های GeoIP" + +msgid "Analyzes and preloads GeoIP data to enhance the shunt performance." +msgstr "داده‌های GeoIP را برای بهبود عملکرد شنت تجزیه Ùˆ پیش‌بارگذاری می‌کند." + +msgid "Note: Increases resource usage." +msgstr "توجه: مصر٠منابع را Ø§ÙØ²Ø§ÛŒØ´ می‌دهد." + +msgid "Shunt Rule" +msgstr "قانون شنت" + +msgid "Please note attention to the priority, the higher the order, the higher the priority." +msgstr "Ù„Ø·ÙØ§Ù‹ به اولویت توجه کنید، هرچه ترتیب بالاتر باشد، اولویت بیشتر است." + +msgid "Update..." +msgstr "به‌روزرسانی..." + +msgid "It is the latest version" +msgstr "این آخرین نسخه است" + +msgid "Update successful" +msgstr "به‌روزرسانی موÙقیت‌آمیز بود" + +msgid "Click to update" +msgstr "برای به‌روزرسانی کلیک کنید" + +msgid "Updating..." +msgstr "در حال به‌روزرسانی..." + +msgid "Retry" +msgstr "تلاش مجدد" + +msgid "Unexpected error" +msgstr "خطای غیرمنتظره" + +msgid "Updating, are you sure to close?" +msgstr "در حال به‌روزرسانی، آیا مطمئن هستید Ú©Ù‡ ببندید؟" + +msgid "Downloading..." +msgstr "در حال دانلود..." + +msgid "Unpacking..." +msgstr "در حال استخراج..." + +msgid "Moving..." +msgstr "در حال انتقال..." + +msgid "App Update" +msgstr "به‌روزرسانی برنامه" + +msgid "Please confirm that your firmware supports FPU." +msgstr "Ù„Ø·ÙØ§Ù‹ تأیید کنید Ú©Ù‡ سیستم‌عامل شما از FPU پشتیبانی می‌کند." + +msgid "if you want to run from memory, change the path, /tmp beginning then save the application and update it manually." +msgstr "اگر می‌خواهید از Ø­Ø§ÙØ¸Ù‡ اجرا کنید، مسیر را تغییر دهید، با /tmp شروع شود سپس برنامه را ذخیره Ùˆ دستی به‌روزرسانی کنید." + +msgid "Make sure there is enough space to install %s" +msgstr "مطمئن شوید Ú©Ù‡ ÙØ¶Ø§ÛŒ کاÙÛŒ برای نصب %s وجود دارد" + +msgid "App Path" +msgstr "مسیر برنامه" + +msgid "%s App Path" +msgstr "مسیر برنامه %s" + +msgid "%s Client App Path" +msgstr "مسیر برنامه کلاینت %s" + +msgid "Node Subscribe" +msgstr "اشتراک گره" + +msgid "Subscribe Remark" +msgstr "توضیحات اشتراک" + +msgid "Subscribe Info" +msgstr "اطلاعات اشتراک" + +msgid "Subscribe URL" +msgstr "URL اشتراک" + +msgid "Subscribe URL Access Method" +msgstr "روش دسترسی به URL اشتراک" + +msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically." +msgstr "هنگام Ø§ÙØ²ÙˆØ¯Ù† اشتراک جدید، Ù„Ø·ÙØ§Ù‹ قبل از انجام اشتراک دستی، تنظیمات را ذخیره Ùˆ اعمال (Save & Apply) کنید. اگر Ùقط URL اشتراک را تغییر داده‌اید، می‌توانید به صورت دستی مشترک شوید؛ سیستم آن را به طور خودکار ذخیره می‌کند." + +msgid "Please save and apply before manually subscribing." +msgstr "Ù„Ø·ÙØ§Ù‹ قبل از اشتراک دستی، ذخیره Ùˆ اعمال کنید." + +msgid "Subscribe URL cannot be empty." +msgstr "URL اشتراک نمی‌تواند خالی باشد." + +msgid "Subscribe via proxy" +msgstr "اشتراک از طریق پروکسی" + +msgid "Update Once on Boot" +msgstr "یک بار در بوت به‌روزرسانی کنید" + +msgid "Updates the subscription the first time runs automatically after each system boot." +msgstr "اشتراک را برای اولین بار به طور خودکار پس از هر بار بوت سیستم به‌روزرسانی می‌کند." + +msgid "Enable auto update subscribe" +msgstr "ÙØ¹Ø§Ù„‌سازی به‌روزرسانی خودکار اشتراک" + +msgid "Manual subscription" +msgstr "اشتراک دستی" + +msgid "Delete All Subscribe Node" +msgstr "حذ٠همه گره‌های اشتراک" + +msgid "Delete the subscribed node" +msgstr "حذ٠گره مشترک شده" + +msgid "Are you sure you want to delete all subscribed nodes?" +msgstr "آیا مطمئن هستید Ú©Ù‡ می‌خواهید همه گره‌های مشترک شده را حذ٠کنید؟" + +msgid "Manual subscription All" +msgstr "اشتراک دستی همه" + +msgid "This remark already exists, please change a new remark." +msgstr "این توضیحات قبلاً وجود دارد، Ù„Ø·ÙØ§Ù‹ توضیحات جدیدی را انتخاب کنید." + +msgid "Remark cannot be empty." +msgstr "توضیحات نمی‌تواند خالی باشد." + +msgid "URL cannot be empty." +msgstr "URL نمی‌تواند خالی باشد." + +msgid "Filter keyword Mode" +msgstr "حالت Ùیلتر کلمه کلیدی" + +msgid "Discard List" +msgstr "لیست حذÙ" + +msgid "Keep List" +msgstr "لیست نگهداری" + +msgid "Discard List,But Keep List First" +msgstr "لیست Ø­Ø°ÙØŒ اما ابتدا لیست نگهداری" + +msgid "Keep List,But Discard List First" +msgstr "لیست نگهداری، اما ابتدا لیست حذÙ" + +msgid "Use global config" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از پیکربندی سراسری" + +msgid "User-Agent" +msgstr "User-Agent" + +msgid "Add" +msgstr "Ø§ÙØ²ÙˆØ¯Ù†" + +msgid "ACLs" +msgstr "ACLها" + +msgid "ACLs is a tools which used to designate specific IP proxy mode." +msgstr "ACL ابزاری است Ú©Ù‡ برای تعیین حالت پروکسی IP خاص Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود." + +msgid "Example:" +msgstr "مثال:" + +msgid "IP range" +msgstr "محدوده IP" + +msgid "Source Interface" +msgstr "رابط منبع" + +msgid "Bridge" +msgstr "پل شبکه" + +msgid "Wireless Adapter" +msgstr "آداپتور بی‌سیم" + +msgid "Ethernet Adapter" +msgstr "آداپتور اترنت" + +msgid "Tunnel Interface" +msgstr "رابط تونل" + +msgid "Invalid interface name" +msgstr "نام رابط نامعتبر" + +msgid "Use Interface With ACLs" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از رابط با ACLها" + +msgid "Remarks" +msgstr "توضیحات" + +msgid "Direct List" +msgstr "لیست مستقیم" + +msgid "Proxy List" +msgstr "لیست پروکسی" + +msgid "Block List" +msgstr "لیست مسدود" + +msgid "Lan IP List" +msgstr "لیست IP شبکه داخلی" + +msgid "Route Hosts" +msgstr "میزبان‌های مسیر" + +msgid "Join the direct hosts list of domain names will not proxy." +msgstr "نام دامنه‌هایی Ú©Ù‡ به لیست میزبان‌های مستقیم اضاÙÙ‡ شده‌اند، پروکسی نخواهند شد." + +msgid "These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5." +msgstr "آدرس‌های IP وارد شده در این لیست از پروکسی عبور نخواهند کرد. Ù„Ø·ÙØ§Ù‹ آدرس IP یا رنج CIDR را وارد کنید (هر خط یک مورد). مثال: 192.168.0.0/24 یا 223.5.5.5." + +msgid "These had been joined websites will use proxy. Please input the domain names of websites, every line can input only one website domain. For example: google.com." +msgstr "وب‌سایت‌های وارد شده در این لیست از پروکسی Ø§Ø³ØªÙØ§Ø¯Ù‡ خواهند کرد. Ù„Ø·ÙØ§Ù‹ نام دامنه وب‌سایت‌ها را وارد کنید، هر خط Ùقط یک نام دامنه. برای مثال: google.com." + +msgid "These had been joined ip addresses will use proxy. Please input the ip address or ip address segment, every line can input only one ip address. For example: 35.24.0.0/24 or 8.8.4.4." +msgstr "آدرس‌های IP اضاÙÙ‡ شده از پروکسی Ø§Ø³ØªÙØ§Ø¯Ù‡ خواهند کرد. Ù„Ø·ÙØ§Ù‹ آدرس IP یا بخش آدرس IP را وارد کنید، هر خط Ùقط یک آدرس IP. برای مثال: 35.24.0.0/24 یا 8.8.4.4." + +msgid "These had been joined websites will be block. Please input the domain names of websites, every line can input only one website domain. For example: twitter.com." +msgstr "وب‌سایت‌های وارد شده در این لیست مسدود خواهند شد. Ù„Ø·ÙØ§Ù‹ نام دامنه وب‌سایت‌ها را وارد کنید، هر خط Ùقط یک نام دامنه. برای مثال: twitter.com." + +msgid "The list is the IPv4 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "این لیست، لیست IP شبکه داخلی IPv4 است Ú©Ù‡ نشان‌دهنده IP اتصال مستقیم شبکه داخلی است. اگر به IP شبکه داخلی در لیست پروکسی نیاز دارید، Ù„Ø·ÙØ§Ù‹ آن را از لیست پاک کنید. به طور Ù¾ÛŒØ´â€ŒÙØ±Ø¶ این لیست را تغییر ندهید." + +msgid "The list is the IPv6 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "این لیست، لیست IP شبکه داخلی IPv6 است Ú©Ù‡ نشان‌دهنده IP اتصال مستقیم شبکه داخلی است. اگر به IP شبکه داخلی در لیست پروکسی نیاز دارید، Ù„Ø·ÙØ§Ù‹ آن را از لیست پاک کنید. به طور Ù¾ÛŒØ´â€ŒÙØ±Ø¶ این لیست را تغییر ندهید." + +msgid "Configure routing etc/hosts file, if you don't know what you are doing, please don't change the content." +msgstr "پیکربندی ÙØ§ÛŒÙ„ etc/hosts مسیریابی، اگر نمی‌دانید Ú†Ù‡ کاری انجام می‌دهید، Ù„Ø·ÙØ§Ù‹ محتوا را تغییر ندهید." + +msgid "These had been joined ip addresses will be block. Please input the ip address or ip address segment, every line can input only one ip address." +msgstr "آدرس‌های IP وارد شده در این لیست مسدود خواهند شد. Ù„Ø·ÙØ§Ù‹ آدرس IP یا بخش آدرس IP را وارد کنید، هر خط Ùقط یک آدرس IP." + +msgid "Inbound Tag" +msgstr "برچسب ورودی" + +msgid "Transparent proxy" +msgstr "پروکسی Ø´ÙØ§Ù" + +msgid "Not valid domain name, please re-enter!" +msgstr "نام دامنه معتبر نیست، Ù„Ø·ÙØ§Ù‹ دوباره وارد کنید!" + +msgid "Not valid IP format, please re-enter!" +msgstr "ÙØ±Ù…ت IP معتبر نیست، Ù„Ø·ÙØ§Ù‹ دوباره وارد کنید!" + +msgid "Not valid IPv4 format, please re-enter!" +msgstr "ÙØ±Ù…ت IPv4 نامعتبر است، Ù„Ø·ÙØ§Ù‹ دوباره وارد کنید!" + +msgid "Not valid IPv6 format, please re-enter!" +msgstr "ÙØ±Ù…ت IPv6 نامعتبر است، Ù„Ø·ÙØ§Ù‹ دوباره وارد کنید!" + +msgid "Not true format, please re-enter!" +msgstr "ÙØ±Ù…ت صحیح نیست، Ù„Ø·ÙØ§Ù‹ دوباره وارد کنید!" + +msgid "Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'." +msgstr "متن ساده (Plaintext): اگر این رشته با هر بخشی از دامنه هد٠مطابقت داشته باشد، این قانون اعمال می‌شود. مثال: قانون 'sina.com' با دامنه هد٠'sina.com'ØŒ 'sina.com.cn' Ùˆ 'www.sina.com' مطابقت دارد، اما با 'sina.cn' خیر." + +msgid "Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'." +msgstr "عبارت باقاعده (Regular expression): با 'regexp:' شروع می‌شود Ùˆ بقیه یک عبارت باقاعده است. زمانی Ú©Ù‡ عبارت باقاعده با دامنه هد٠مطابقت داشته باشد، این قانون اعمال می‌شود. مثال: قانون 'regexp:\\.goo.*\\.com$' با 'www.google.com' Ùˆ 'fonts.googleapis.com' مطابقت دارد، اما با 'google.com' خیر." + +msgid "Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'." +msgstr "زیردامنه (توصیه شده): با 'domain:' شروع می‌شود Ùˆ بقیه یک دامنه است. زمانی Ú©Ù‡ دامنه هد٠دقیقاً مقدار باشد، یا زیردامنه‌ای از مقدار باشد، این قانون اعمال می‌شود. مثال: قانون 'domain:v2ray.com' با 'www.v2ray.com' Ùˆ 'v2ray.com' مطابقت دارد، اما با 'xv2ray.com' خیر." + +msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'." +msgstr "دامنه کامل: با 'full:' شروع می‌شود Ùˆ بقیه یک دامنه است. زمانی Ú©Ù‡ دامنه هد٠دقیقاً مقدار باشد، قانون اعمال می‌شود. مثال: قانون 'domain:v2ray.com' با 'v2ray.com' مطابقت دارد، اما با 'www.v2ray.com' خیر." + +msgid "Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'" +msgstr "مجموعه قوانین Sing-Box: با 'rule-set:remote:' یا 'rule-set:local:' شروع می‌شود" + +msgid "Such as:" +msgstr "مانند:" + +msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn." +msgstr "لیست دامنه از پیش تعری٠شده: با 'geosite:' شروع می‌شود Ùˆ بقیه یک نام است، مانند geosite:google یا geosite:cn." + +msgid "Annotation: Begining with #" +msgstr "توضیحات: با # شروع می‌شود" + +msgid "Invert match result." +msgstr "معکوس کردن نتیجه تطابق." + +msgid "Only support Sing-Box." +msgstr "Ùقط پشتیبانی از Sing-Box." + +msgid "IP: such as '127.0.0.1'." +msgstr "IP: مانند '127.0.0.1'." + +msgid "CIDR: such as '127.0.0.0/8'." +msgstr "CIDR: مانند '127.0.0.0/8'." + +msgid "GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code." +msgstr "GeoIP: مانند 'geoip:cn'. با geoip: (حرو٠کوچک) شروع می‌شود Ùˆ با دو حر٠کد کشور دنبال می‌شود." + +msgid "Clear logs" +msgstr "پاک کردن گزارش‌ها" + +msgid "Password" +msgstr "رمز عبور" + +msgid "IV Check" +msgstr "بررسی IV" + +msgid "UDP over TCP" +msgstr "UDP بر روی TCP" + +msgid "Connection Timeout" +msgstr "مهلت زمانی اتصال" + +msgid "Local Port" +msgstr "پورت محلی" + +msgid "Fast Open" +msgstr "بازگشایی سریع (Fast Open)" + +msgid "Pre-connections" +msgstr "پیش‌اتصالات" + +msgid "Number of early established connections to reduce latency." +msgstr "تعداد اتصالات از پیش برقرار شده برای کاهش تاخیر." + +msgid "plugin" +msgstr "Ø§ÙØ²ÙˆÙ†Ù‡" + +msgid "Supports custom SIP003 plugins, Make sure the plugin is installed." +msgstr "پشتیبانی از Ø§ÙØ²ÙˆÙ†Ù‡â€ŒÙ‡Ø§ÛŒ Ø³ÙØ§Ø±Ø´ÛŒ SIP003ØŒ مطمئن شوید Ú©Ù‡ Ø§ÙØ²ÙˆÙ†Ù‡ نصب شده است." + +msgid "opts" +msgstr "گزینه‌ها (opts)" + +msgid "Protocol" +msgstr "پروتکل" + +msgid "Protocol_param" +msgstr "پارامتر پروتکل" + +msgid "Obfs" +msgstr "مبهم‌سازی (Obfs)" + +msgid "Obfs_param" +msgstr "پارامتر مبهم‌سازی" + +msgid "Plugin Name" +msgstr "نام Ø§ÙØ²ÙˆÙ†Ù‡" + +msgid "Plugin Arguments" +msgstr "آرگومان‌های Ø§ÙØ²ÙˆÙ†Ù‡" + +msgid "User Level" +msgstr "سطح کاربر" + +msgid "Transport" +msgstr "انتقال" + +msgid "Public Key" +msgstr "کلید عمومی" + +msgid "Private Key" +msgstr "کلید خصوصی" + +msgid "Pre shared key" +msgstr "کلید از پیش به اشتراک گذاشته شده" + +msgid "Local Address" +msgstr "آدرس محلی" + +msgid "System interface" +msgstr "رابط سیستم" + +msgid "System interface name" +msgstr "نام رابط سیستم" + +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "اعداد دهدهی جدا شده با \",\" یا رشته‌های کدگذاری شده با Base64." + +msgid "Camouflage Domain" +msgstr "دامنه استتار" + +msgid "Camouflage Type" +msgstr "نوع استتار" + +msgid "Transport Layer Encryption" +msgstr "رمزنگاری لایه انتقال" + +msgid "Whether or not transport layer encryption is enabled, \"none\" for unencrypted, \"tls\" for using TLS, \"xtls\" for using XTLS." +msgstr "اینکه رمزنگاری لایه انتقال ÙØ¹Ø§Ù„ باشد یا خیر، \"none\" برای بدون رمزنگاری، \"tls\" برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از TLSØŒ \"xtls\" برای Ø§Ø³ØªÙØ§Ø¯Ù‡ از XTLS." + +msgid "Original Trojan only supported 'tls', please choose 'tls'." +msgstr "Trojan اصلی Ùقط از 'tls' پشتیبانی می‌کند، Ù„Ø·ÙØ§Ù‹ 'tls' را انتخاب کنید." + +msgid "Transfer mode" +msgstr "حالت انتقال" + +msgid "Do not send server name in ClientHello." +msgstr "نام سرور را در ClientHello ارسال Ù†Ú©Ù†." + +msgid "Domain" +msgstr "دامنه" + +msgid "allowInsecure" +msgstr "اجازه ناامن (allowInsecure)" + +msgid "Whether unsafe connections are allowed. When checked, Certificate validation will be skipped." +msgstr "آیا اتصالات ناامن مجاز هستند. در صورت تیک خوردن، اعتبارسنجی گواهی نادیده Ú¯Ø±ÙØªÙ‡ می‌شود." + +msgid "Used when the node link does not include this parameter." +msgstr "زمانی Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود Ú©Ù‡ لینک گره شامل این پارامتر نباشد." + +msgid "%s Node Use Type" +msgstr "نوع Ø§Ø³ØªÙØ§Ø¯Ù‡ گره %s" + +msgid "UDP relay mode" +msgstr "حالت بازپخش UDP" + +msgid "Concurrent Tunnels" +msgstr "تونل‌های همزمان" + +msgid "Congestion control algorithm" +msgstr "الگوریتم کنترل ازدحام" + +msgid "Heartbeat interval(second)" +msgstr "بازه ضربان قلب (ثانیه)" + +msgid "Disable SNI" +msgstr "ØºÛŒØ±ÙØ¹Ø§Ù„ کردن SNI" + +msgid "Enable 0-RTT QUIC handshake" +msgstr "ÙØ¹Ø§Ù„‌سازی دست تکان دادن 0-RTT QUIC" + +msgid "
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests." +msgstr "
none: Ù¾ÛŒØ´â€ŒÙØ±Ø¶ØŒ بدون استتار، داده‌های ارسالی بسته‌های بدون مشخصه هستند.
srtp: مبدل شده به بسته SRTP، به عنوان داده تماس تصویری (مانند FaceTime) شناخته می‌شود.
utp: بسته‌های مبدل شده به uTP به عنوان داده دانلود شده bittorrent شناخته می‌شوند.
wechat-video: بسته‌های مبدل شده به تماس‌های تصویری WeChat.
dtls: مبدل شده به بسته DTLS 1.2.
wireguard: مبدل شده به بسته WireGuard. (نه واقعاً پروتکل WireGuard)
dns: پنهان کردن تراÙیک به عنوان درخواست‌های DNS." + +msgid "Use it together with the DNS disguised type. You can fill in any domain." +msgstr "از آن همراه با نوع استتار DNS Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید. می‌توانید هر دامنه‌ای را وارد کنید." + +msgid "Auth" +msgstr "احراز هویت" + +msgid "Socks for authentication" +msgstr "Socks برای احراز هویت" + +msgid "Socks protocol authentication, support anonymous and password." +msgstr "احراز هویت پروتکل SocksØŒ پشتیبانی از ناشناس Ùˆ رمز عبور." + +msgid "anonymous" +msgstr "ناشناس" + +msgid "User Password" +msgstr "رمز عبور کاربر" + +msgid "Username and Password must be used together!" +msgstr "نام کاربری Ùˆ رمز عبور باید با هم Ø§Ø³ØªÙØ§Ø¯Ù‡ شوند!" + +msgid "Prefer firewall tools" +msgstr "ترجیح ابزارهای ÙØ§ÛŒØ±ÙˆØ§Ù„" + +msgid "IPv6 TProxy" +msgstr "IPv6 TProxy" + +msgid "Experimental feature. Make sure that your node supports IPv6." +msgstr "ویژگی آزمایشی. مطمئن شوید Ú©Ù‡ گره شما از IPv6 پشتیبانی می‌کند." + +msgid "Status info" +msgstr "اطلاعات وضعیت" + +msgid "Big icon" +msgstr "آیکون بزرگ" + +msgid "Show node check" +msgstr "نمایش بررسی گره" + +msgid "Show Show IP111" +msgstr "نمایش نمایش IP111" + +msgid "Destination protocol" +msgstr "پروتکل مقصد" + +msgid "Destination address" +msgstr "آدرس مقصد" + +msgid "Destination port" +msgstr "پورت مقصد" + +msgid "Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used." +msgstr "آیا پروتکل PROXY Ø¯Ø±ÛŒØ§ÙØª شود، زمانی Ú©Ù‡ این گره بخواهد پشتیبان باشد یا توسط پروکسی Ùوروارد شود، باید ÙØ¹Ø§Ù„ باشد، در غیر این صورت قابل Ø§Ø³ØªÙØ§Ø¯Ù‡ نیست." + +msgid "outbound node" +msgstr "گره خروجی" + +msgid "Custom Socks" +msgstr "Socks Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "Custom HTTP" +msgstr "HTTP Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "Custom Interface" +msgstr "رابط Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "Interface" +msgstr "رابط" + +msgid "Bind Local" +msgstr "اتصال محلی (Bind Local)" + +msgid "When selected, it can only be accessed localhost." +msgstr "در صورت انتخاب، Ùقط از طریق localhost قابل دسترسی است." + +msgid "Accept LAN Access" +msgstr "پذیرش دسترسی شبکه داخلی (LAN)" + +msgid "When selected, it can accessed lan , this will not be safe!" +msgstr "در صورت انتخاب، از شبکه داخلی (LAN) قابل دسترسی خواهد بود؛ این کار امنیت را کاهش می‌دهد!" + +msgid "Enable Remote" +msgstr "ÙØ¹Ø§Ù„‌سازی راه دور" + +msgid "You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more." +msgstr "می‌توانید به Nginx/Caddy/V2ray/Xray WebSocket Ùˆ موارد دیگر Ùوروارد کنید." + +msgid "Remote Address" +msgstr "آدرس راه دور" + +msgid "Remote Port" +msgstr "پورت راه دور" + +msgid "as:" +msgstr "به عنوان:" + +msgid "Public key absolute path" +msgstr "مسیر مطلق کلید عمومی" + +msgid "Private key absolute path" +msgstr "مسیر مطلق کلید خصوصی" + +msgid "Can't find this file!" +msgstr "این ÙØ§ÛŒÙ„ پیدا نشد!" + +msgid "Public key and Private key path can not be empty!" +msgstr "مسیر کلید عمومی Ùˆ کلید خصوصی نمی‌تواند خالی باشد!" + +msgid "Server-Side" +msgstr "سمت سرور" + +msgid "Server Config" +msgstr "پیکربندی سرور" + +msgid "Users Manager" +msgstr "مدیریت کاربران" + +msgid "Logs" +msgstr "گزارش‌ها (Logs)" + +msgid "Log" +msgstr "گزارش (Log)" + +msgid "Enable Node Log" +msgstr "ÙØ¹Ø§Ù„‌سازی گزارش گره" + +msgid "Log Level" +msgstr "سطح گزارش" + +msgid "Not enabled log" +msgstr "گزارش ÙØ¹Ø§Ù„ نیست" + +msgid "UDP Forward" +msgstr "Ùوروارد UDP" + +msgid "DNS Settings" +msgstr "تنظیمات DNS" + +msgid "Null" +msgstr "تهی (Null)" + +msgid "You did not fill in the %s path. Please save and apply then update manually." +msgstr "شما مسیر %s را پر نکرده‌اید. Ù„Ø·ÙØ§Ù‹ ذخیره Ùˆ اعمال کنید سپس به صورت دستی به‌روزرسانی کنید." + +msgid "Not installed %s, Can't unzip!" +msgstr "%s نصب نشده است، استخراج امکان‌پذیر نیست!" + +msgid "Can't determine ARCH, or ARCH not supported." +msgstr "معماری (ARCH) قابل تشخیص نیست، یا پشتیبانی نمی‌شود." + +msgid "Get remote version info failed." +msgstr "Ø¯Ø±ÛŒØ§ÙØª اطلاعات نسخه راه دور ناموÙÙ‚ بود." + +msgid "New version found, but failed to get new version download url." +msgstr "نسخه جدید پیدا شد، اما Ø¯Ø±ÛŒØ§ÙØª URL دانلود نسخه جدید ناموÙÙ‚ بود." + +msgid "Download url is required." +msgstr "URL دانلود الزامی است." + +msgid "File download failed or timed out: %s" +msgstr "دانلود ÙØ§ÛŒÙ„ ناموÙÙ‚ بود یا زمان آن تمام شد: %s" + +msgid "File path required." +msgstr "مسیر ÙØ§ÛŒÙ„ الزامی است." + +msgid "%s not enough space." +msgstr "%s ÙØ¶Ø§ÛŒ کاÙÛŒ ندارد." + +msgid "Can't find client in file: %s" +msgstr "کلاینت در ÙØ§ÛŒÙ„ پیدا نشد: %s" + +msgid "Client file is required." +msgstr "ÙØ§ÛŒÙ„ کلاینت الزامی است." + +msgid "The client file is not suitable for current device." +msgstr "ÙØ§ÛŒÙ„ کلاینت برای دستگاه ÙØ¹Ù„ÛŒ مناسب نیست." + +msgid "Can't move new file to path: %s" +msgstr "انتقال ÙØ§ÛŒÙ„ جدید به مسیر امکان‌پذیر نیست: %s" + +msgid "An XHttpObject in JSON format, used for sharing." +msgstr "یک XHttpObject در ÙØ±Ù…ت JSONØŒ برای اشتراک‌گذاری Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود." + +msgid "Enable Mux.Cool" +msgstr "ÙØ¹Ø§Ù„‌سازی Mux.Cool" + +msgid "Mux concurrency" +msgstr "همزمانی Mux" + +msgid "XUDP Mux concurrency" +msgstr "همزمانی XUDP Mux" + +msgid "Padding" +msgstr "پدینگ (Padding)" + +msgid "Enable early data" +msgstr "ÙØ¹Ø§Ù„‌سازی داده‌های اولیه (Early Data)" + +msgid "Early data length" +msgstr "طول داده‌های اولیه" + +msgid "Early data header name" +msgstr "نام هدر داده‌های اولیه" + +msgid "Recommended value: Sec-WebSocket-Protocol" +msgstr "مقدار پیشنهادی: Sec-WebSocket-Protocol" + +msgid "Health check" +msgstr "بررسی سلامت" + +msgid "Health check timeout" +msgstr "مهلت زمانی بررسی سلامت" + +msgid "Permit without stream" +msgstr "اجازه بدون جریان (stream)" + +msgid "Initial Windows Size" +msgstr "اندازه اولیه پنجره" + +msgid "Excluded Domains" +msgstr "دامنه‌های استثنا شده" + +msgid "If the traffic sniffing result is in this list, the destination address will not be overridden." +msgstr "اگر نتیجه شنود تراÙیک در این لیست باشد، آدرس مقصد بازنویسی نخواهد شد." + +msgid "Buffer Size" +msgstr "اندازه Ø¨Ø§ÙØ±" + +msgid "Buffer size for every connection (kB)" +msgstr "اندازه Ø¨Ø§ÙØ± برای هر اتصال (کیلوبایت)" + +msgid "Idle Timeout" +msgstr "مهلت زمانی بیکاری" + +msgid "Hop Interval(second)" +msgstr "ÙØ§ØµÙ„Ù‡ پرش (ثانیه)" + +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "از یک مقدار ثابت یا یک محدوده تصادÙÛŒ (مثلاً 30ØŒ 5-30)ØŒ حداقل 5ØŒ پشتیبانی می‌کند." + +msgid "HeartbeatPeriod(second)" +msgstr "دوره ضربان قلب (ثانیه)" + +msgid "Override the connection destination address" +msgstr "بازنویسی آدرس مقصد اتصال" + +msgid "Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "بازنویسی آدرس مقصد اتصال با دامنه شنود شده (Sniffed Domain).
در غیر این صورت، از دامنه شنود شده Ùقط برای مسیریابی Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود.
اگر از گره‌های شنت (Shunt) Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌کنید، قوانین مربوطه را به درستی پیکربندی کنید." + +msgid "Handshake Server" +msgstr "سرور دست تکان دادن" + +msgid "Handshake Server Port" +msgstr "پورت سرور دست تکان دادن" + +msgid "Protocol parameter. Will waste traffic randomly if enabled." +msgstr "پارامتر پروتکل. در صورت ÙØ¹Ø§Ù„‌سازی، مقداری تراÙیک تصادÙÛŒ اضاÙÛŒ تولید می‌کند (برای مبهم‌سازی)." + +msgid "Protocol parameter. Enable length block encryption." +msgstr "پارامتر پروتکل. ÙØ¹Ø§Ù„‌سازی رمزنگاری بلوک طول." + +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "اثر انگشت زنجیره TLS (SHA256)" + +msgid "Once set, connects only when the server’s chain fingerprint matches." +msgstr "پس از تنظیم، Ùقط زمانی متصل می‌شود Ú©Ù‡ اثر انگشت زنجیره سرور مطابقت داشته باشد." + +msgid "TLS Certificate Name (CertName)" +msgstr "نام گواهی TLS (CertName)" + +msgid "TLS is used to verify the leaf certificate name." +msgstr "TLS برای تأیید نام گواهی برگ (Leaf Certificate) Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود." + +msgid "ECH Config" +msgstr "پیکربندی ECH" + +msgid "ECH Key" +msgstr "کلید ECH" + +msgid "ECH Query Policy" +msgstr "سیاست پرس‌وجوی ECH" + +msgid "Controls the policy used when performing DNS queries for ECH configuration." +msgstr "سیاستی Ú©Ù‡ هنگام انجام پرس‌وجوهای DNS برای پیکربندی ECH Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود را کنترل می‌کند." + +msgid "ECH Query Domain" +msgstr "دامنه پرس Ùˆ جو ECH" + +msgid "Overrides the domain name used for ECH HTTPS record queries." +msgstr "نام دامنه مورد Ø§Ø³ØªÙØ§Ø¯Ù‡ برای پرس‌وجوهای رکورد ECH HTTPS را لغو می‌کند." + +msgid "Enable Multipath TCP, need to be enabled in both server and client configuration." +msgstr "ÙØ¹Ø§Ù„‌سازی Multipath TCPØŒ باید در تنظیمات سرور Ùˆ کلاینت ÙØ¹Ø§Ù„ باشد." + +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "یک شیء FinalMaskObject با ÙØ±Ù…ت JSON Ú©Ù‡ برای اشتراک‌گذاری Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود." + +msgid "Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings." +msgstr "ماسک نهایی Ø³ÙØ§Ø±Ø´ÛŒØŒ تنظیمات mkcpØŒ hysteria2ØŒ fragmentØŒ noise Ùˆ تنظیمات مرتبط را نادیده می‌گیرد." + +msgid "Fragment" +msgstr "قطعه‌بندی (Fragment)" + +msgid "TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists." +msgstr "قطعه‌بندی TCPØŒ Ú©Ù‡ می‌تواند در برخی موارد سیستم سانسور را ÙØ±ÛŒØ¨ دهد، مانند دور زدن لیست سیاه SNI." + +msgid "Fragment Packets" +msgstr "بسته‌های قطعه‌بندی شده" + +msgid " \"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation." +msgstr " \"1-3\" برای قطعه‌بندی در لایه TCP است Ùˆ به 1 تا 3 نوشتن اول داده توسط کلاینت اعمال می‌شود. \"tlshello\" برای قطعه‌بندی بسته سلام کلاینت TLS است." + +msgid "Fragment Length" +msgstr "طول قطعه" + +msgid "Fragmented packet length (byte)" +msgstr "طول بسته قطعه‌بندی شده (بایت)" + +msgid "Fragment Delay" +msgstr "تأخیر قطعه" + +msgid "Fragmentation interval (ms)" +msgstr "بازه قطعه‌بندی (میلی‌ثانیه)" + +msgid "Max Split" +msgstr "حداکثر تقسیم" + +msgid "Limit the maximum number of splits." +msgstr "حداکثر تعداد تقسیم‌بندی‌ها را محدود کنید." + +msgid "Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first." +msgstr "تقسیم داده‌های دست تکان دادن به چندین رکورد TLS برای ÙØ±Ø§Ø± بهتر از سانسور. سربار Ú©Ù…. توصیه می‌شود ابتدا ÙØ¹Ø§Ù„ شود." + +msgid "Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed." +msgstr "تقسیم دست تکان دادن به چندین قطعه TCP. Ø§ÙØ²Ø§ÛŒØ´ مبهم‌سازی. ممکن است تاخیر را Ø§ÙØ²Ø§ÛŒØ´ دهد. Ùقط در صورت نیاز Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید." + +msgid "Noise" +msgstr "نویز (Noise)" + +msgid "UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions." +msgstr "نویز UDPØŒ در برخی شرایط می‌تواند محدودیت‌های پروتکل مبتنی بر UDP را دور بزند." + +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "برای ارسال بسته‌های نویز، \"Noise\" را در تنظیمات Xray انتخاب کنید." + +msgid "Xray Noise Packets" +msgstr "بسته‌های نویز Xray" + +msgid "Packet | Rand Length" +msgstr "طول بسته | رند" + +msgid "Delay (ms)" +msgstr "تاخیر (میلی‌ثانیه)" + +msgid "If is domain name, The requested domain name will be resolved to IP before connect." +msgstr "اگر نام دامنه است، نام دامنه درخواست شده قبل از اتصال به IP حل می‌شود." + +msgid "Domain DNS Resolve" +msgstr "حل مشکل DNS دامنه" + +msgid "If the node address is a domain name, this DNS will be used for resolution." +msgstr "اگر آدرس گره یک نام دامنه باشد، از این DNS برای حل مسئله Ø§Ø³ØªÙØ§Ø¯Ù‡ خواهد شد." + +msgid "Supports only Xray or Sing-box node types." +msgstr "Ùقط گره‌های نوع Xray یا Sing-box پشتیبانی می‌شوند." + +msgid "Chain Proxy" +msgstr "پروکسی زنجیره‌ای" + +msgid "Outbound Interface" +msgstr "رابط خروجی" + +msgid "Landing Node" +msgstr "گره ÙØ±ÙˆØ¯ (Landing Node)" + +msgid "Only support a layer of proxy." +msgstr "Ùقط از یک لایه پروکسی پشتیبانی می‌کند." + +msgid "" +"Chained proxy works only with Xray or Sing-box nodes.
" +"You can only use manual or imported nodes as chained nodes." +msgstr "" +"پروکسی زنجیره‌ای Ùقط با گره‌های Xray یا Sing-box کار می‌کند.
" +"شما Ùقط می‌توانید از گره‌های دستی یا وارد شده به عنوان گره‌های زنجیره‌ای Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید." + +msgid "Prefer IPv4" +msgstr "ترجیح IPv4" + +msgid "Prefer IPv6" +msgstr "ترجیح IPv6" + +msgid "IPv4 Only" +msgstr "Ùقط IPv4" + +msgid "IPv6 Only" +msgstr "Ùقط IPv6" + +msgid "Maintain" +msgstr "نگهداری" + +msgid "Backup and Restore" +msgstr "پشتیبان‌گیری Ùˆ بازیابی" + +msgid "Backup or Restore Client and Server Configurations." +msgstr "پشتیبان‌گیری یا بازیابی پیکربندی‌های کلاینت Ùˆ سرور." + +msgid "Note: Restoring configurations across different versions may cause compatibility issues." +msgstr "توجه: بازیابی پیکربندی‌ها در بین نسخه‌های مختل٠ممکن است باعث مشکلات سازگاری شود." + +msgid "Create Backup File" +msgstr "ایجاد ÙØ§ÛŒÙ„ پشتیبان" + +msgid "Restore Backup File" +msgstr "بازیابی ÙØ§ÛŒÙ„ پشتیبان" + +msgid "DL Backup" +msgstr "دانلود پشتیبان" + +msgid "RST Backup" +msgstr "بازنشانی پشتیبان" + +msgid "Backup failed!" +msgstr "پشتیبان‌گیری ناموÙÙ‚ بود!" + +msgid "UL Restore" +msgstr "آپلود بازیابی" + +msgid "CLOSE WIN" +msgstr "بستن پنجره" + +msgid "Restore to default configuration" +msgstr "بازیابی به پیکربندی Ù¾ÛŒØ´â€ŒÙØ±Ø¶" + +msgid "Do Reset" +msgstr "انجام بازنشانی" + +msgid "Please select a file first." +msgstr "Ù„Ø·ÙØ§Ù‹ ابتدا یک ÙØ§ÛŒÙ„ انتخاب کنید." + +msgid "Invalid file type. Please upload a .tar.gz file." +msgstr "نوع ÙØ§ÛŒÙ„ نامعتبر است. Ù„Ø·ÙØ§Ù‹ یک ÙØ§ÛŒÙ„ .tar.gz آپلود کنید." + +msgid "File size exceeds 10MB limit." +msgstr "اندازه ÙØ§ÛŒÙ„ از محدودیت 10 مگابایت بیشتر است." + +msgid "Do you want to restore the client to default settings?" +msgstr "آیا می‌خواهید کلاینت را به تنظیمات Ù¾ÛŒØ´â€ŒÙØ±Ø¶ بازگردانید؟" + +msgid "Are you sure you want to restore the client to default settings?" +msgstr "آیا مطمئن هستید Ú©Ù‡ می‌خواهید کلاینت را به تنظیمات Ù¾ÛŒØ´â€ŒÙØ±Ø¶ بازگردانید؟" + +msgid "Configuration file uploaded successfully…" +msgstr "ÙØ§ÛŒÙ„ پیکربندی با موÙقیت آپلود شد..." + +msgid "Configuration restored successfully…" +msgstr "پیکربندی با موÙقیت بازیابی شد..." + +msgid "Service restarting…" +msgstr "راه اندازی مجدد سرویس..." + +msgid "Configuration file decompression failed, please try again!" +msgstr "استخراج ÙØ§ÛŒÙ„ پیکربندی ناموÙÙ‚ بود، Ù„Ø·ÙØ§Ù‹ دوباره تلاش کنید!" + +msgid "_urltest" +msgstr "_تست URL" + +msgid "URLTest node list" +msgstr "لیست گره‌های URLTest" + +msgid "List of nodes to test, document" +msgstr "لیست گره‌ها برای تست، مستندات" + +msgid "Test interval" +msgstr "بازه تست" + +msgid "Test interval must be less or equal than idle timeout." +msgstr "بازه تست باید کمتر یا مساوی مهلت زمانی بیکاری باشد." + +msgid "Test tolerance" +msgstr "تحمل تست" + +msgid "The test tolerance in milliseconds." +msgstr "تحمل تست بر حسب میلی‌ثانیه." + +msgid "Idle timeout" +msgstr "مهلت زمانی بیکاری" + +msgid "The idle timeout." +msgstr "مهلت زمانی بیکاری." + +msgid "Interrupt existing connections" +msgstr "قطع اتصالات موجود" + +msgid "Interrupt existing connections when the selected outbound has changed." +msgstr "قطع اتصالات موجود زمانی Ú©Ù‡ خروجی انتخاب شده تغییر کرده است." + +msgid "Port hopping range" +msgstr "محدوده پرش پورت" + +msgid "Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,)." +msgstr "ÙØ±Ù…ت به صورت 1000:2000 یا 1000-2000 گروه‌های متعدد با کاما (,) جدا می‌شوند." + +msgid "Use Custom Config" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از پیکربندی Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "Custom Config" +msgstr "پیکربندی Ø³ÙØ§Ø±Ø´ÛŒ" + +msgid "Must be JSON text!" +msgstr "باید متن JSON باشد!" + +msgid "Geo View" +msgstr "نمای Geo" + +msgid "Query" +msgstr "پرس‌وجو" + +msgid "Querying" +msgstr "در حال پرس‌وجو" + +msgid "Please enter query content!" +msgstr "Ù„Ø·ÙØ§Ù‹ محتوای پرس‌وجو را وارد کنید!" + +msgid "No results were found!" +msgstr "هیچ نتیجه‌ای ÛŒØ§ÙØª نشد!" + +msgid "Rules containing this value:" +msgstr "قوانین حاوی این مقدار:" + +msgid "Domain/IP Query" +msgstr "پرس‌وجوی دامنه/IP" + +msgid "GeoIP/Geosite Query" +msgstr "پرس‌وجوی GeoIP/Geosite" + +msgid "Enter a domain or IP to query the Geo rule list they belong to." +msgstr "یک دامنه یا IP وارد کنید تا لیست قوانین Geo Ú©Ù‡ به آن تعلق دارند را جستجو کنید." + +msgid "Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw" +msgstr "یک GeoIP یا Geosite وارد کنید تا دامنه‌ها/IPهای موجود در آن استخراج شوند. ÙØ±Ù…ت: geoip:cn یا geosite:gfw" + +msgid "Tips:" +msgstr "نکات:" + +msgid "By entering a domain or IP, you can query the Geo rule list they belong to." +msgstr "با وارد کردن یک دامنه یا IPØŒ می‌توانید لیست قوانین Geo Ú©Ù‡ به آن تعلق دارند را جستجو کنید." + +msgid "By entering a GeoIP or Geosite, you can extract the domains/IPs they contain." +msgstr "با وارد کردن یک GeoIP یا GeositeØŒ می‌توانید دامنه‌ها/IPهای موجود در آن را استخراج کنید." + +msgid "Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct." +msgstr "از عملکرد پرس‌وجوی GeoIP/Geosite برای تأیید صحت قوانین Geo وارد شده Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید." + +msgid "Private Key Passphrase" +msgstr "عبارت عبور کلید خصوصی" + +msgid "Host Key" +msgstr "کلید میزبان (Host Key)" + +msgid "Accept any if empty." +msgstr "در صورت خالی بودن، همه Ù¾Ø°ÛŒØ±ÙØªÙ‡ می‌شوند." + +msgid "Host Key Algorithms" +msgstr "الگوریتم‌های کلید میزبان" + +msgid "Client Version" +msgstr "نسخه کلاینت" + +msgid "Random version will be used if empty." +msgstr "در صورت خالی بودن، از نسخه تصادÙÛŒ Ø§Ø³ØªÙØ§Ø¯Ù‡ می‌شود." + +msgid "The configured type also applies to the core specified when manually importing nodes." +msgstr "نوع پیکربندی شده همچنین به هسته مشخص شده هنگام وارد کردن دستی گره‌ها اعمال می‌شود." + +msgid "Group Name" +msgstr "نام گروه" + +msgid "Reassign Group" +msgstr "تغییر گروه" + +msgid "Reassign Node Group" +msgstr "تغییر گروه گره" + +msgid "Search nodes..." +msgstr "جستجوی گره‌ها..." + +msgid "Using..." +msgstr "در حال Ø§Ø³ØªÙØ§Ø¯Ù‡..." + +msgid "Generate configuration file and run" +msgstr "تولید ÙØ§ÛŒÙ„ پیکربندی Ùˆ اجرا" + +msgid "Start after a delay of %s seconds!" +msgstr "شروع پس از تاخیر %s ثانیه‌ای!" + +msgid "The script is already running, do not run it again. Exit." +msgstr "اسکریپت در حال اجرا است، دوباره آن را اجرا نکنید. خروج." + +msgid "Stop the script and wait for a timeout, then exit without repeating the process." +msgstr "توق٠اسکریپت Ùˆ انتظار برای مهلت زمانی، سپس خروج بدون تکرار ÙØ±Ø¢ÛŒÙ†Ø¯." + +msgid "Warning: The %s application environment is incomplete. Switch to %s. (%s)" +msgstr "هشدار: محیط برنامه %s ناقص است. سوئیچ به %s. (%s)" + +msgid "Note: Dnsmasq (%s) is below 2.90. Upgrading is recommended to improve stability." +msgstr "توجه: Dnsmasq (%s) کمتر از 2.90 است. ارتقا برای بهبود پایداری توصیه می‌شود." + +msgid "Warning: %s transparent proxy is missing basic dependency %s!" +msgstr "هشدار: پروکسی Ø´ÙØ§Ù %s وابستگی اساسی %s را ندارد!" + +msgid "Warning: Not compatible with any transparent proxy system environment." +msgstr "هشدار: با هیچ محیط سیستم پروکسی Ø´ÙØ§Ù سازگار نیست." + +msgid "%s does not have execute permissions and cannot be started: %s %s" +msgstr "%s مجوز اجرا ندارد Ùˆ نمی‌تواند شروع شود: %s %s" + +msgid "%s not found, unable to start..." +msgstr "%s پیدا نشد، شروع امکان‌پذیر نیست..." + +msgid "Socks node: [%s]%s is an invalid server address and cannot be started!" +msgstr "گره Socks: [%s]%s یک آدرس سرور نامعتبر است Ùˆ نمی‌تواند شروع شود!" + +msgid "For some reason, the configuration for this Socks service has been lost, and its startup has been aborted!" +msgstr "به دلایلی، پیکربندی این سرویس Socks از بین Ø±ÙØªÙ‡ است Ùˆ راه‌اندازی آن لغو شد!" + +msgid "Socks node: [%s]%s, start failed %s:%s %s" +msgstr "گره Socks: [%s]%sØŒ شروع ناموÙÙ‚ %s:%s %s" + +msgid "Socks node: [%s]%s, starting %s:%s" +msgstr "گره Socks: [%s]%sØŒ در حال شروع %s:%s" + +msgid "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!" +msgstr "برای ÙØ¹Ø§Ù„‌سازی پروکسی Ø´ÙØ§Ù IPv6 (آزمایشی)ØŒ Ù„Ø·ÙØ§Ù‹ اطمینان حاصل کنید Ú©Ù‡ گره Ùˆ نوع اتصال شما از IPv6 پشتیبانی می‌کند!" + +msgid "[%s] process %s error, skip this transparent proxy!" +msgstr "خطای ÙØ±Ø¢ÛŒÙ†Ø¯ [%s] %sØŒ از این پروکسی Ø´ÙØ§Ù صرÙ‌نظر کنید!" + +msgid "Analyzing the node configuration of the Socks service..." +msgstr "تحلیل پیکربندی گره سرویس Socks..." + +msgid "Log file is too long, clear it!" +msgstr "ÙØ§ÛŒÙ„ گزارش خیلی طولانی است، آن را پاک کنید!" + +msgid "The task is currently running automatically as a scheduled task; no reconfiguration of the scheduled task is required." +msgstr "وظیÙÙ‡ در حال حاضر به طور خودکار به عنوان یک وظیÙÙ‡ زمان‌بندی شده اجرا می‌شود؛ نیازی به پیکربندی مجدد وظیÙÙ‡ زمان‌بندی شده نیست." + +msgid "Scheduled tasks: Auto stop service." +msgstr "وظای٠زمان‌بندی شده: توق٠خودکار سرویس." + +msgid "Scheduled tasks: Auto start service." +msgstr "وظای٠زمان‌بندی شده: شروع خودکار سرویس." + +msgid "Scheduled tasks: Auto restart service." +msgstr "وظای٠زمان‌بندی شده: راه‌اندازی مجدد خودکار سرویس." + +msgid "Scheduled tasks: Auto update rules." +msgstr "وظای٠زمان‌بندی شده: به‌روزرسانی خودکار قوانین." + +msgid "Scheduled tasks: Auto update [%s] subscription." +msgstr "وظای٠زمان‌بندی شده: به‌روزرسانی خودکار اشتراک [%s]." + +msgid "Auto updates: Starts a cyclical update process." +msgstr "به‌روزرسانی‌های خودکار: شروع یک ÙØ±Ø¢ÛŒÙ†Ø¯ به‌روزرسانی چرخشی." + +msgid "Running in no proxy mode, it only allows scheduled tasks for starting and stopping services." +msgstr "در حالت بدون پروکسی اجرا می‌شود، Ùقط اجازه وظای٠زمان‌بندی شده برای شروع Ùˆ توق٠سرویس‌ها را می‌دهد." + +msgid "Clear scheduled commands." +msgstr "پاک کردن دستورات زمان‌بندی شده." + +msgid "Unable to resolve [%s], route table addition failed!" +msgstr "عدم توانایی در حل [%s]ØŒ Ø§ÙØ²ÙˆØ¯Ù† به جدول مسیریابی ناموÙÙ‚ بود!" + +msgid "[%s] was successfully added to the routing table of interface [%s]!" +msgstr "[%s] با موÙقیت به جدول مسیریابی رابط [%s] اضاÙÙ‡ شد!" + +msgid "Adding [%s] to the [%s] routing table failed! The reason is that the [%s] gateway cannot be found." +msgstr "Ø§ÙØ²ÙˆØ¯Ù† [%s] به جدول مسیریابی [%s] ناموÙÙ‚ بود! دلیل این است Ú©Ù‡ دروازه [%s] پیدا نمی‌شود." + +msgid "Global nodes are not enabled, skip [%s]." +msgstr "گره‌های سراسری ÙØ¹Ø§Ù„ نیستند، صرÙ‌نظر از [%s]." + +msgid "Direct DNS: %s" +msgstr "DNS مستقیم: %s" + +msgid "Remote DNS: %s" +msgstr "DNS راه دور: %s" + +msgid "The program has started. Please stop it and then restart it!" +msgstr "برنامه شروع شده است. Ù„Ø·ÙØ§Ù‹ آن را متوق٠و سپس دوباره راه‌اندازی کنید!" + +msgid "Running complete!" +msgstr "اجرا کامل شد!" + +msgid "Clearing and closing related programs and cache complete." +msgstr "پاک‌سازی Ùˆ بستن برنامه‌های مرتبط Ùˆ Ú©Ø´ کامل شد." + +msgid "Incorrect index listing method (%s), execution terminated!" +msgstr "روش Ùهرست‌بندی ایندکس نادرست (%s)ØŒ اجرا متوق٠شد!" + +msgid "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." +msgstr "تجزیه قوانین تقسیم تراÙیک [%s]-[geoip:%s] Ùˆ Ø§ÙØ²ÙˆØ¯Ù† به %s کامل شد." + +msgid "Access Control:" +msgstr "کنترل دسترسی:" + +msgid "Add node to the load balancer is directly connected to %s[%s]." +msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره به توزیع‌کننده بار مستقیماً به %s[%s] متصل است." + +msgid "Add all %s nodes to %s[%s] direct connection complete." +msgstr "Ø§ÙØ²ÙˆØ¯Ù† تمام گره‌های %s به %s[%s] اتصال مستقیم کامل شد." + +msgid "Starting to load %s firewall rules..." +msgstr "شروع بارگذاری قوانین ÙØ§ÛŒØ±ÙˆØ§Ù„ %s..." + +msgid "local network segments (%s) direct connection: %s" +msgstr "بخش‌های شبکه محلی (%s) اتصال مستقیم: %s" + +msgid "Add ISP %s DNS to the whitelist: %s" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† DNS ISP %s به لیست سÙید: %s" + +msgid "[%s]" +msgstr "[%s]" + +msgid "[%s]," +msgstr "[%s]ØŒ" + +msgid "Source iface [%s]," +msgstr "رابط منبع [%s]ØŒ" + +msgid "IP range [%s]," +msgstr "محدوده IP [%s]ØŒ" + +msgid "All device," +msgstr "همه دستگاه‌ها،" + +msgid "Does not exist, ignore." +msgstr "وجود ندارد، نادیده Ú¯Ø±ÙØªÙ†." + +msgid "not proxy %s port [%s]" +msgstr "پروکسی نکردن پورت %s [%s]" + +msgid "not proxy all %s" +msgstr "پروکسی نکردن همه %s" + +msgid "Use the %s node [%s]" +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از گره %s [%s]" + +msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server." +msgstr "Ø§Ø³ØªÙØ§Ø¯Ù‡ از گره‌ای Ù…ØªÙØ§ÙˆØª از پیکربندی سراسری، DNS به اجبار به سرور DNS اختصاصی هدایت شده است." + +msgid "Add direct DNS to %s: %s" +msgstr "Ø§ÙØ²ÙˆØ¯Ù† DNS مستقیم به %s: %s" + +msgid "Local" +msgstr "محلی" + +msgid "[Local]," +msgstr "[محلی]ØŒ" + +msgid "Clear %s." +msgstr "پاک کردن %s." + +msgid "Delete %s rules is complete." +msgstr "حذ٠قوانین %s کامل شد." + +msgid "%s firewall rules load complete!" +msgstr "بارگذاری قوانین ÙØ§ÛŒØ±ÙˆØ§Ù„ %s کامل شد!" + +msgid "Socks switch detection: Unknown error." +msgstr "تشخیص سوئیچ Socks: خطای ناشناخته." + +msgid "Socks switch detection: Unable to connect to the network. Please check if the network is working properly!" +msgstr "تشخیص سوئیچ Socks: عدم توانایی در اتصال به شبکه. Ù„Ø·ÙØ§Ù‹ بررسی کنید Ú©Ù‡ شبکه به درستی کار می‌کند!" + +msgid "Socks switch detection: Primary node ã€%s: [%s]】 is normal. Switch to the primary node!" +msgstr "تشخیص سوئیچ Socks: گره اولیه ã€%s: [%s]】 عادی است. سوئیچ به گره اولیه!" + +msgid "Socks switch detection: %s node switch complete!" +msgstr "تشخیص سوئیچ Socks: سوئیچ گره %s کامل شد!" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal." +msgstr "تشخیص سوئیچ Socks: %s ã€%s:[%s]】 عادی است." + +msgid "switch to %s test detect!" +msgstr "سوئیچ به تست تشخیص %s!" + +msgid "backup node" +msgstr "گره پشتیبان" + +msgid "next backup node" +msgstr "گره پشتیبان بعدی" + +msgid "main node" +msgstr "گره اصلی" + +msgid "Socks switch detection: Unknown error." +msgstr "تشخیص سوئیچ Socks: خطای ناشناخته." + +msgid "Socks switch detection: %s ã€%s:[%s]】 abnormal, %s" +msgstr "تشخیص سوئیچ Socks: %s ã€%s:[%s]】 غیرعادی، %s" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal, switch to this node!" +msgstr "تشخیص سوئیچ Socks: %s ã€%s:[%s]】 عادی، سوئیچ به این گره!" + +msgid "Restart dnsmasq service." +msgstr "راه‌اندازی مجدد سرویس dnsmasq." + +msgid "Console Port: %s" +msgstr "پورت کنسول: %s" + +msgid "Discard one obviously invalid node." +msgstr "حذ٠یک گره به وضوح نامعتبر." + +msgid "Entrance %s:%s" +msgstr "ورودی %s:%s" + +msgid "Node: %s:%s, Weight: %s" +msgstr "گره: %s:%sØŒ وزن: %s" + +msgid "[Rule update] instance is running; please try again later." +msgstr "نمونه [به‌روزرسانی قانون] در حال اجرا است؛ Ù„Ø·ÙØ§Ù‹ بعداً دوباره امتحان کنید." + +msgid "[Subscription] instance is running; [Rule Update] queue and wait." +msgstr "نمونه [اشتراک] در حال اجرا است؛ [به‌روزرسانی قانون] در ص٠انتظار قرار می‌گیرد." + +msgid "Start updating the rules..." +msgstr "شروع به‌روزرسانی قوانین..." + +msgid "Download file size verification error. Original file size: %sB. Downloaded file size: %sB." +msgstr "خطای تأیید اندازه ÙØ§ÛŒÙ„ دانلود شده. اندازه ÙØ§ÛŒÙ„ اصلی: %sB. اندازه ÙØ§ÛŒÙ„ دانلود شده: %sB." + +msgid "Downloaded file is empty or an error occurred while reading it." +msgstr "ÙØ§ÛŒÙ„ دانلود شده خالی است یا خطایی هنگام خواندن آن رخ داده است." + +msgid "%s Start updating..." +msgstr "%s شروع به‌روزرسانی..." + +msgid "%s version is the same and does not need to be updated." +msgstr "نسخه %s یکسان است Ùˆ نیازی به به‌روزرسانی ندارد." + +msgid "%s an error occurred during the file download process. Please try downloading again." +msgstr "%s خطایی در ÙØ±Ø¢ÛŒÙ†Ø¯ دانلود ÙØ§ÛŒÙ„ رخ داد. Ù„Ø·ÙØ§Ù‹ دوباره تلاش کنید." + +msgid "%s an error occurred while downloading the file. Please check your network or the download link and try again!" +msgstr "%s خطایی هنگام دانلود ÙØ§ÛŒÙ„ رخ داد. Ù„Ø·ÙØ§Ù‹ شبکه یا لینک دانلود را بررسی کرده Ùˆ دوباره تلاش کنید!" + +msgid "%s update success." +msgstr "%s به‌روزرسانی موÙÙ‚." + +msgid "%s update failed, please try again later or change URL." +msgstr "%s به‌روزرسانی ناموÙÙ‚ بود، Ù„Ø·ÙØ§Ù‹ بعداً تلاش کنید یا URL را تغییر دهید." + +msgid "%s update error!" +msgstr "%s خطای به‌روزرسانی!" + +msgid "Restart the service and apply the new rules." +msgstr "راه‌اندازی مجدد سرویس Ùˆ اعمال قوانین جدید." + +msgid "The rules have been updated..." +msgstr "قوانین به‌روز شده‌اند..." + +msgid "Socks node list [%s]" +msgstr "لیست گره‌های Socks [%s]" + +msgid "Backup node list" +msgstr "لیست گره‌های پشتیبان" + +msgid "HAProxy node list [%s]" +msgstr "لیست گره‌های HAProxy [%s]" + +msgid "ACL list [%s]" +msgstr "لیست ACL [%s]" + +msgid "Shunt [%s] node" +msgstr "گره شنت [%s]" + +msgid "Xray Load Balancing node [%s] list" +msgstr "لیست گره‌های توزیع بار Xray [%s]" + +msgid "Xray Load Balancing node [%s] backup node" +msgstr "گره پشتیبان گره توزیع بار Xray [%s]" + +msgid "Sing-Box URLTest node [%s] list" +msgstr "لیست گره‌های URLTest Sing-Box [%s]" + +msgid "Node [%s] preproxy node" +msgstr "گره پیش‌پروکسی گره [%s]" + +msgid "Node [%s] landing node" +msgstr "گره ÙØ±ÙˆØ¯ گره [%s]" + +msgid "Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings." +msgstr "نادیده Ú¯Ø±ÙØªÙ† گره %s به دلیل ناسازگاری با هسته برنامه %s یا تنظیمات نادرست نوع گره." + +msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." +msgstr "صرÙ‌نظر از گره: %s. زیرا Sing-Box از روش انتقال %s پروتکل %s پشتیبانی نمی‌کند، باید به جای آن از Xray Ø§Ø³ØªÙØ§Ø¯Ù‡ شود." + +msgid "Xray unsupport %s plugin." +msgstr "Xray از Ø§ÙØ²ÙˆÙ†Ù‡ %s پشتیبانی نمی‌کند." + +msgid "Plugin options Incomplete." +msgstr "گزینه‌های Ø§ÙØ²ÙˆÙ†Ù‡ ناقص است." + +msgid "Please replace %s to support %s transmission method." +msgstr "Ù„Ø·ÙØ§ برای پشتیبانی از روش انتقال %sØŒ %s را جایگزین کنید." + +msgid "Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks." +msgstr "Ù„Ø·ÙØ§Ù‹ برای پشتیبانی از روش‌های انتقال بیشتر در ShadowsocksØŒ از Xray یا Sing-Box Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید." + +msgid "unsupport %s plugin." +msgstr "پشتیبانی نکردن از Ø§ÙØ²ÙˆÙ†Ù‡ %s." + +msgid "Skip the %s node because the %s core program is not installed." +msgstr "صرÙ‌نظر از گره %s زیرا برنامه اصلی %s نصب نشده است." + +msgid "Skip the %s node, as %s type nodes require Sing-Box version 1.12 or higher." +msgstr "صرÙ‌نظر از گره %sØŒ زیرا گره‌های نوع %s به نسخه 1.12 یا بالاتر Sing-Box نیاز دارند." + +msgid "%s type node subscriptions are not currently supported, skip this node." +msgstr "اشتراک‌های گره نوع %s در حال حاضر پشتیبانی نمی‌شوند، صرÙ‌نظر از این گره." + +msgid "Update [%s]" +msgstr "به‌روزرسانی [%s]" + +msgid "Matching node:" +msgstr "گره منطبق:" + +msgid "First Matching node:" +msgstr "اولین گره منطبق:" + +msgid "Second Matching node:" +msgstr "دومین گره منطبق:" + +msgid "Third Matching node:" +msgstr "سومین گره منطبق:" + +msgid "Fourth Matching node:" +msgstr "چهارمین گره منطبق:" + +msgid "Fifth Matching node:" +msgstr "پنجمین گره منطبق:" + +msgid "Unable to find the best matching node, now replaced with:" +msgstr "عدم توانایی در ÛŒØ§ÙØªÙ† بهترین گره منطبق، اکنون جایگزین شده با:" + +msgid "Unable to find a new node. Please confirm and process manually." +msgstr "عدم توانایی در ÛŒØ§ÙØªÙ† گره جدید. Ù„Ø·ÙØ§Ù‹ تأیید Ùˆ به صورت دستی پردازش کنید." + +msgid "No node information updates are available." +msgstr "هیچ به‌روزرسانی اطلاعات گره در دسترس نیست." + +msgid "Skip unknown types:" +msgstr "صرÙ‌نظر از انواع ناشناخته:" + +msgid "Discard node: %s, Reason:" +msgstr "حذ٠گره: %sØŒ دلیل:" + +msgid "No usable binary was found." +msgstr "هیچ باینری قابل Ø§Ø³ØªÙØ§Ø¯Ù‡â€ŒØ§ÛŒ ÛŒØ§ÙØª نشد." + +msgid "Discard filter nodes: %s type node %s" +msgstr "حذ٠گره‌های Ùیلتر: نوع گره %s %s" + +msgid "Parsing error, skip this node." +msgstr "خطای تجزیه، صرÙ‌نظر از این گره." + +msgid "Successfully resolved the [%s] node, number: %s" +msgstr "گره [%s] با موÙقیت حل شد، تعداد: %s" + +msgid "Get subscription content for [%s] is empty. This may be due to an invalid subscription address or a network problem. Please diagnose the issue!" +msgstr "Ø¯Ø±ÛŒØ§ÙØª محتوای اشتراک برای [%s] خالی است. این ممکن است به دلیل آدرس اشتراک نامعتبر یا مشکل شبکه باشد. Ù„Ø·ÙØ§Ù‹ مشکل را بررسی کنید!" + +msgid "Proxy" +msgstr "پروکسی" + +msgid "[Subscription] instance is running; please try again later." +msgstr "نمونه [اشتراک] در حال اجرا است؛ Ù„Ø·ÙØ§Ù‹ بعداً دوباره امتحان کنید." + +msgid "[Rule Update] instance is running; [Subscription] queue and wait." +msgstr "نمونه [به‌روزرسانی قانون] در حال اجرا است؛ [اشتراک] در ص٠انتظار قرار دارد." + +msgid "Start subscribing..." +msgstr "شروع اشتراک‌گیری..." + +msgid "Start subscribing: %s" +msgstr "شروع اشتراک‌گیری: %s" + +msgid "Subscription: [%s] No changes, no update required." +msgstr "اشتراک: [%s] بدون تغییر، نیازی به به‌روزرسانی نیست." + +msgid "[%s] Subscription failed. This could be due to an invalid subscription address or a network issue. Please diagnose the problem! [%s]" +msgstr "[%s] اشتراک ناموÙÙ‚ بود. این می‌تواند به دلیل آدرس اشتراک نامعتبر یا مشکل شبکه باشد. Ù„Ø·ÙØ§Ù‹ مشکل را بررسی کنید! [%s]" + +msgid "Error, restoring service." +msgstr "خطا، بازیابی سرویس." + +msgid "Subscription complete..." +msgstr "اشتراک کامل شد..." + +msgid "Processing, please wait…" +msgstr "در حال پردازش، Ù„Ø·ÙØ§ صبر کنید…" diff --git a/luci-app-passwall2/po/ru/passwall2.po b/luci-app-passwall2/po/ru/passwall2.po new file mode 100644 index 00000000..cb5b8969 --- /dev/null +++ b/luci-app-passwall2/po/ru/passwall2.po @@ -0,0 +1,2385 @@ +msgid "Auto" +msgstr "Ðвто" + +msgid "RUNNING" +msgstr "Служба активна" + +msgid "NOT RUNNING" +msgstr "Служба оÑтановлена" + +msgid "Working..." +msgstr "ВыполнÑетÑÑ..." + +msgid "Problem detected!" +msgstr "Обнаружена ошибка!" + +msgid "Touch Check" +msgstr "Проверить доÑтупноÑть" + +msgid "Global" +msgstr "Глобальный режим" + +msgid "Kernel Unsupported" +msgstr "Ядро неÑовмеÑтимо" + +msgid "Basic Settings" +msgstr "Общие параметры" + +msgid "Node List" +msgstr "СпиÑок узлов" + +msgid "Other Settings" +msgstr "Дополнительные наÑтройки" + +msgid "Load Balancing" +msgstr "БаланÑировка трафика" + +msgid "Enter interface" +msgstr "Открыть интерфейÑ" + +msgid "Rule Manage" +msgstr "Управление правилами" + +msgid "Rule List" +msgstr "СпиÑок правил" + +msgid "Access control" +msgstr "Контроль доÑтупа" + +msgid "Runtime Logs" +msgstr "Журналы выполнениÑ" + +msgid "Node Config" +msgstr "Параметры узла" + +msgid "Running Status" +msgstr "СоÑтоÑние ÑиÑтемы" + +msgid "Baidu Connection" +msgstr "Baidu" + +msgid "Google Connection" +msgstr "Google" + +msgid "GitHub Connection" +msgstr "GitHub" + +msgid "Instagram Connection" +msgstr "Instagram" + +msgid "Node Check" +msgstr "Проверка узлов" + +msgid "Check..." +msgstr "Идёт проверка..." + +msgid "Clear" +msgstr "ОчиÑтить" + +msgid "Main switch" +msgstr "Включить модуль" + +msgid "Node" +msgstr "Узел" + +msgid "Edit Current Node" +msgstr "Изменить выбранный узел" + +msgid "Localhost Proxy" +msgstr "ПрокÑи Ð´Ð»Ñ Ñамого роутера" + +msgid "When selected, localhost can transparent proxy." +msgstr "ЕÑли включено, трафик Ñамого роутера будет идти через прозрачный прокÑи." + +msgid "Client Proxy" +msgstr "ПрокÑи Ð´Ð»Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ñких уÑтройÑтв" + +msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy." +msgstr "ЕÑли включено, вÑе уÑтройÑтва в локальной Ñети будут автоматичеÑки иÑпользовать прозрачный прокÑи. Ð’ противном Ñлучае прокÑи не активируетÑÑ, но вы можете добавить иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· ÑпиÑок ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ Ð´Ð¾Ñтупа." + +msgid "Missing components, transparent proxy is unavailable." +msgstr "Ðе уÑтановлены необходимые компоненты — прозрачный прокÑи недоÑтупен." + +msgid "Socks Config" +msgstr "ÐаÑтройки SOCKS-прокÑи" + +msgid "Socks Node" +msgstr "SOCKS-Ñервер" + +msgid "Current Node" +msgstr "Ðктивный Ñервер" + +msgid "Listen Port" +msgstr "Порт проÑлушиваниÑ" + +msgid "0 is not use" +msgstr "0 — отключить функцию" + +msgid "Current node: %s" +msgstr "Текущий узел: %s" + +msgid "Direct domain DNS routing" +msgstr "ПрÑÐ¼Ð°Ñ Ð¼Ð°Ñ€ÑˆÑ€ÑƒÑ‚Ð¸Ð·Ð°Ñ†Ð¸Ñ DNS домена" + +msgid "Please note that the program will not start if the format is incorrect!" +msgstr "Обратите внимание, что программа не запуÑтитÑÑ, еÑли формат указан неверно!" + +msgid "IP:Port mode acceptable, multi value split with english comma." +msgstr "ДопуÑтим формат IP:Port. ÐеÑколько значений указывайте через запÑтую." + +msgid "Direct DNS Protocol" +msgstr "Протокол прÑмого DNS" + +msgid "Direct DNS" +msgstr "ПрÑмой DNS" + +msgid "Direct DNS DoH" +msgstr "ПрÑмой DNS-over-HTTPS" + +msgid "Direct DNS EDNS Client Subnet" +msgstr "EDNS Client Subnet Ð´Ð»Ñ Ð¿Ñ€Ñмого DNS" + +msgid "Remote DNS Protocol" +msgstr "Протокол прокÑи-DNS" + +msgid "Remote DNS" +msgstr "ПрокÑи-DNS" + +msgid "Remote DNS DoH" +msgstr "ПрокÑи DNS-over-HTTPS" + +msgid "Remote DNS EDNS Client Subnet" +msgstr "EDNS Client Subnet Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐºÑи-DNS" + +msgid "Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address)." +msgstr "Сообщает DNS-Ñерверу примерное меÑтоположение клиента при запроÑе. Указывайте публичный IP-адреÑ." + +msgid "This feature requires the DNS server to support the Edns Client Subnet (RFC7871)." +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÐµÑ‚ только еÑли DNS-Ñервер поддерживает EDNS Client Subnet (RFC7871)." + +msgid "Remote DNS Outbound" +msgstr "Маршрут Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐºÑи-DNS" + +msgid "Remote" +msgstr "Через прокÑи" + +msgid "Direct" +msgstr "ПрÑмой" + +msgid "Direct Query Strategy" +msgstr "Ð¡Ñ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð¿Ñ€Ñмого запроÑа" + +msgid "Remote Query Strategy" +msgstr "Ð¡Ñ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð¿Ñ€Ð¾ÐºÑи-запроÑа" + +msgid "Use FakeDNS work in the domain that proxy." +msgstr "ИÑпользовать FakeDNS Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð², проходÑщих через прокÑи" + +msgid "Suitable scenarios for let the node servers get the target domain names." +msgstr "ПозволÑет узлам получать реальные доменные имена (вмеÑто подÑтавных адреÑов)." + +msgid "Such as: DNS unlocking of streaming media, reducing DNS query latency, etc." +msgstr "Ðапример: разблокировка Ñтриминговых ÑервиÑов, уÑкорение Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸Ð¼Ñ‘Ð½ и Ñ‚.п." + +msgid "Domain Override" +msgstr "Переопределение доменов" + +msgid "Direct DNS result write to IPSet" +msgstr "ЗапиÑывать результаты прÑмого DNS в IPSet" + +msgid "Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core)." +msgstr "IP-адреÑа доменов, подходÑщих под правила прÑмого доÑтупа, добавлÑÑŽÑ‚ÑÑ Ð² IPSet/NFTSet Ð´Ð»Ñ Ð¾Ð±Ñ…Ð¾Ð´Ð° Ñдра прокÑи." + +msgid "Maybe conflict with some special circumstances." +msgstr "Ð’ отдельных ÑлучаÑÑ… может конфликтовать Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ правилами." + +msgid "DNS Redirect" +msgstr "Перехват DNS-запроÑов" + +msgid "Force special DNS server to need proxy devices." +msgstr "Принудительно направлÑть DNS-запроÑÑ‹ уÑтройÑтв через прокÑи на выделенный Ñервер." + +msgid "Clear IPSET" +msgstr "ОчиÑтить IPSet" + +msgid "Clear NFTSET" +msgstr "ОчиÑтить NFTSet" + +msgid "Try this feature if the rule modification does not take effect." +msgstr "ИÑпользуйте, еÑли Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² правилах не применÑÑŽÑ‚ÑÑ." + +msgid "About DNS issues:" +msgstr "Важно о наÑтройке DNS:" + +msgid "Some browsers may have built-in DNS, be sure to close. Example: Chrome. Settings - Security and Privacy - Security - Use secure DNS disabled." +msgstr "Ðекоторые браузеры иÑпользуют ÑобÑтвенный DNS. Отключите Ñту функцию: в Chrome Ñто «ÐаÑтройки → КонфиденциальноÑть и безопаÑноÑть → БезопаÑноÑть → ИÑпользовать безопаÑный DNS»." + +msgid "Sometimes after restart, you can not internet. At this time, close all browsers (important), Windows Client, please `ipconfig /flushdns`. Please close the WiFi on the phone, cut the flight mode and then cut back." +msgstr "ЕÑли поÑле перезагрузки нет доÑтупа в Ñеть: закройте вÑе браузеры, в Windows выполните `ipconfig /flushdns`, на телефоне переключите авиарежим или переподключитеÑÑŒ к Wi-Fi." + +msgid "The client DNS and the default gateway must point to this router." +msgstr "Ð’ наÑтройках клиентов DNS-Ñервер и шлюз по умолчанию должны указывать на Ñтот роутер." + +msgid "If you have a wrong DNS process, the consequences are at your own risk!" +msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð½Ð°Ñтройка DNS может привеÑти к потере доÑтупа в Ñеть — дейÑтвуйте на Ñвой Ñтрах и риÑк." + +msgid "Hide menu method, input example in the address bar:" +msgstr "Чтобы Ñкрыть меню, введите в адреÑной Ñтроке:" + +msgid "After the hidden to the display, input example in the address bar:" +msgstr "Чтобы вернуть меню, введите в адреÑной Ñтроке:" + +msgid "Are you sure to hide?" +msgstr "Скрыть меню?" + +msgid "DNS related issues:" +msgstr "Возможные проблемы Ñ DNS:" + +msgid "Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off." +msgstr "Браузеры вроде Chrome могут иÑпользовать ÑобÑтвенный DNS, что конфликтует Ñ Ð½Ð°Ñтройками роутера. Отключите: «ÐаÑтройки → КонфиденциальноÑть → БезопаÑноÑть → ИÑпользовать безопаÑный DNS»." + +msgid "If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):" +msgstr "ЕÑли поÑле перезагрузки нет доÑтупа в интернет, очиÑтите кÑш DNS на уÑтройÑтвах (предварительно закройте вÑе вкладки браузера):" + +msgid "For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'." +msgstr "Windows: откройте командную Ñтроку и выполните `ipconfig /flushdns`." + +msgid "For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'." +msgstr "macOS: откройте Терминал и выполните `sudo killall -HUP mDNSResponder`." + +msgid "For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi." +msgstr "Мобильные уÑтройÑтва: переключите авиарежим или переподключитеÑÑŒ к Wi-Fi." + +msgid "Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed." +msgstr "УбедитеÑÑŒ, что в наÑтройках Ñети уÑтройÑтва DNS и шлюз по умолчанию указывают на Ñтот роутер." + +msgid "Browser access:" +msgstr "ДоÑтуп через браузер:" + +msgid "Hide in main menu:" +msgstr "Скрыть в главном меню:" + +msgid "Show in main menu:" +msgstr "Показать в главном меню:" + +msgid "DNS Export Of Multi WAN" +msgstr "Выбор WAN-интерфейÑа Ð´Ð»Ñ Ð¿Ñ€Ñмого DNS" + +msgid "Node Export Of Multi WAN" +msgstr "Выбор WAN-интерфейÑа Ð´Ð»Ñ ÑƒÐ·Ð»Ð¾Ð²" + +msgid "Only support Multi Wan." +msgstr "Работает только при наличии неÑкольких WAN-подключений." + +msgid "Not Specify" +msgstr "Ðе указывать" + +msgid "custom" +msgstr "Свой вариант" + +msgid "If not available, try clearing the cache." +msgstr "ЕÑли не работает — попробуйте очиÑтить кÑш." + +msgid "Operation" +msgstr "ДейÑтвиÑ" + +msgid "Add Node" +msgstr "Добавить узел" + +msgid "Add the node via the link" +msgstr "Добавить узел по ÑÑылке" + +msgid "Enter share links, one per line. Subscription links are not supported!" +msgstr "Введите ÑÑылки Ð´Ð»Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð°, по одной на Ñтроку. СÑылки на подпиÑки не поддерживаютÑÑ!" + +msgid "Please enter the correct link." +msgstr "ПожалуйÑта, введите корректную ÑÑылку." + +msgid "Clear all nodes" +msgstr "Удалить вÑе узлы" + +msgid "Are you sure to clear all nodes?" +msgstr "Ð’Ñ‹ дейÑтвительно хотите удалить вÑе узлы?" + +msgid "Success" +msgstr "Готово" + +msgid "Error" +msgstr "Ошибка" + +msgid "Delete select nodes" +msgstr "Удалить выбранные узлы" + +msgid "To Top" +msgstr "Ð’ начало ÑпиÑка" + +msgid "Select" +msgstr "Выбрать" + +msgid "Selected:" +msgstr "Выбрано:" + +msgid "DeSelect" +msgstr "СнÑть выделение" + +msgid "Select all" +msgstr "Выделить вÑе" + +msgid "DeSelect all" +msgstr "СнÑть выделение Ñо вÑех" + +msgid "Are you sure to delete select nodes?" +msgstr "Ð’Ñ‹ дейÑтвительно хотите удалить выбранные узлы?" + +msgid "You no select nodes !" +msgstr "Ð’Ñ‹ не выбрали ни одного узла!" + +msgid "Are you sure set to" +msgstr "Ð’Ñ‹ дейÑтвительно хотите назначить" + +msgid "the server?" +msgstr "активным Ñервером?" + +msgid "You choose node is:" +msgstr "Выбранный узел:" + +msgid "Timeout" +msgstr "Тайм-аут" + +msgid "Node Remarks" +msgstr "ОпиÑание узла" + +msgid "Add Mode" +msgstr "СпоÑоб добавлениÑ" + +msgid "Save Order" +msgstr "Сохранить порÑдок" + +msgid "Saved current page order successfully." +msgstr "ПорÑдок Ñлементов Ñохранён." + +msgid "Drag to reorder" +msgstr "Перетащите Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ€Ñдка" + +msgid "Type" +msgstr "Тип" + +msgid "_balancing" +msgstr "_balancing" + +msgid "_shunt" +msgstr "_shunt" + +msgid "Balancing" +msgstr "БаланÑировка" + +msgid "Node Addition Method" +msgstr "СпоÑоб Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑƒÐ·Ð»Ð¾Ð²" + +msgid "Manual" +msgstr "Вручную" + +msgid "Batch" +msgstr "Пакетно" + +msgid "Select Group" +msgstr "Выберите группу" + +msgid "Node Matching Rules" +msgstr "Правила отбора узлов" + +msgid "" +"Example: ^A && B && !C && D$
" +"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" +"Conditions are joined by &&, and their order does not affect the result." +msgstr "" +"Пример: ^A && B && !C && D$
" +"ОпиÑание узла должно: начинатьÑÑ Ñ A (^), Ñодержать B, не Ñодержать C (!), заканчиватьÑÑ Ð½Ð° D ($).
" +"УÑÐ»Ð¾Ð²Ð¸Ñ ÑоединÑÑŽÑ‚ÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð¼ &&, порÑдок уÑловий не влиÑет на результат." + +msgid "Balancing Strategy" +msgstr "Ðлгоритм баланÑировки" + +msgid "Fallback Node" +msgstr "ЗапаÑной узел" + +msgid "Use Custom Probe URL" +msgstr "ИÑпользовать Ñвой URL Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸" + +msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL." +msgstr "По умолчанию иÑпользуетÑÑ Ð²Ñтроенный Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸. Включите Ñту опцию, чтобы задать Ñвой URL." + +msgid "Probe URL" +msgstr "URL Ð´Ð»Ñ Ð´Ð¸Ð°Ð³Ð½Ð¾Ñтики" + +msgid "The URL used to detect the connection status." +msgstr "ÐдреÑ, иÑпользуемый Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ доÑтупноÑти ÑоединениÑ." + +msgid "Probe Interval" +msgstr "Интервал проверки" + +msgid "The interval between initiating probes." +msgstr "ПериодичноÑть проверки доÑтупноÑти." + +msgid "The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively." +msgstr "Формат: чиÑло + единица измерениÑ, например 10s, 2h45m. Поддерживаемые единицы: s (Ñекунды), m (минуты), h (чаÑÑ‹)." + +msgid "When the unit is not filled in, it defaults to seconds." +msgstr "ЕÑли единица не указана, по умолчанию иÑпользуютÑÑ Ñекунды." + +msgid "Preferred Node Count" +msgstr "КоличеÑтво предпочтительных узлов" + +msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them." +msgstr "БаланÑировщик выбирает указанное количеÑтво наилучших узлов и раÑпределÑет трафик между ними Ñлучайным образом." + +msgid "Failure Tolerance (%)" +msgstr "ДопуÑк на отказ (%)" + +msgid "The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate." +msgstr "МакÑимально допуÑтимый процент отказов при проверке ÑкороÑти. Ðапример, 1 означает допуÑтимый процент отказов в 1%." + +msgid "Shunt" +msgstr "Shunt (разделение трафика)" + +msgid "Preproxy" +msgstr "Цепочка прокÑи" + +msgid "Preproxy Node" +msgstr "Первый узел цепочки" + +msgid "Set the node to be used as a pre-proxy." +msgstr "Укажите узел, который будет иÑпользоватьÑÑ ÐºÐ°Ðº первый узел в цепочке." + +msgid "Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not." +msgstr "Укажите узел Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² качеÑтве первого узла цепочки. Каждое правило (Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Â«ÐŸÐ¾ умолчанию») имеет отдельный переключатель, определÑющий, иÑпользовать ли цепочку Ð´Ð»Ñ Ñтого правила." + +msgid "Each rule has a separate switch that controls whether this rule uses the pre-proxy or not." +msgstr "Ð”Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ правила можно отдельно включить или отключить иÑпользование цепочки." + +msgid "Close (Not use)" +msgstr "Отключено" + +msgid "Use default node" +msgstr "ИÑпользовать узел по умолчанию" + +msgid "Direct Connection" +msgstr "ПрÑмое Ñоединение" + +msgid "Blackhole (Block)" +msgstr "Блокировка (Blackhole)" + +msgid "There are no available nodes, please add or subscribe nodes first." +msgstr "Ðет доÑтупных узлов! Добавьте вручную или наÑтройте подпиÑку." + +msgid "No shunt rules? Click me to go to add." +msgstr "Ðет правил Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ°! Ðажмите, чтобы добавить." + +msgid "When using, localhost will connect this node first and then use this node to connect the default node." +msgstr "При иÑпользовании трафик Ñначала пойдёт через Ñтот узел, а затем — через оÑновной узел назначениÑ." + +msgid "Domain Strategy" +msgstr "ПорÑдок Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸Ð¼Ñ‘Ð½" + +msgid "Domain matcher" +msgstr "Ðлгоритм ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð²" + +msgid "'AsIs': Only use domain for routing. Default value." +msgstr "AsIs: иÑпользовать доменное Ð¸Ð¼Ñ ÐºÐ°Ðº еÑть. Значение по умолчанию." + +msgid "'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again." +msgstr "IPIfNonMatch: еÑли домен не подошёл ни под одно правило, разрешить его в IP-Ð°Ð´Ñ€ÐµÑ Ð¸ повторить проверку." + +msgid "'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately." +msgstr "IPOnDemand: еÑли вÑтречаетÑÑ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð¾ на оÑнове IP, Ñразу разрешать домен в адреÑ." + +msgid "Load balancing node list" +msgstr "СпиÑок узлов Ð´Ð»Ñ Ð±Ð°Ð»Ð°Ð½Ñировки" + +msgid "Load balancing node list, document" +msgstr "СпиÑок узлов Ð´Ð»Ñ Ð±Ð°Ð»Ð°Ð½Ñировки, документациÑ" + +msgid "From Share URL" +msgstr "Импорт из ÑÑылки" + +msgid "Build Share URL" +msgstr "ЭкÑпорт в ÑÑылку" + +msgid "Generate QRCode" +msgstr "Сгенерировать QR-код" + +msgid "Export Config File" +msgstr "ЭкÑпорт конфигурации" + +msgid "Import Finished" +msgstr "Импорт завершён:" + +msgid "Not a supported scheme:" +msgstr "Ðеподдерживаемый формат:" + +msgid "Invalid Share URL Format" +msgstr "Ðеверный формат ÑÑылки" + +msgid "Paste Share URL Here" +msgstr "Ð’Ñтавьте ÑÑылку Ñюда" + +msgid "Share URL to clipboard unable." +msgstr "Ðе удалоÑÑŒ Ñкопировать ÑÑылку в буфер обмена." + +msgid "Share URL to clipboard successfully." +msgstr "СÑылка Ñкопирована в буфер обмена." + +msgid "Faltal on get option, please help in debug:" +msgstr "Ошибка при чтении наÑтроек, пожалуйÑта, Ñообщите разработчикам:" + +msgid "Faltal on set option, please help in debug:" +msgstr "Ошибка при Ñохранении наÑтроек, пожалуйÑта, Ñообщите разработчикам:" + +msgid "Address" +msgstr "ÐдреÑ" + +msgid "Address (Support Domain Name)" +msgstr "ÐÐ´Ñ€ÐµÑ (поддерживаютÑÑ Ð´Ð¾Ð¼ÐµÐ½Ñ‹)" + +msgid "Trojan Verify Cert" +msgstr "ПроверÑть Ñертификат (Trojan)" + +msgid "Trojan Cert Path" +msgstr "Путь к Ñертификату (Trojan)" + +msgid "Finger Print" +msgstr "TLS отпечаток" + +msgid "Avoid using randomized, unless you have to." +msgstr "Избегайте режима randomized, еÑли в Ñтом нет оÑтрой необходимоÑти." + +msgid "Original" +msgstr "Оригинал" + +msgid "Transport Plugin" +msgstr "Плагин транÑпорта" + +msgid "global_padding" +msgstr "Включить padding-заполнение" + +msgid "authenticated_length" +msgstr "Шифровать длину пакетов" + +msgid "Obfs Type" +msgstr "Тип обфуÑкации" + +msgid "Obfs Password" +msgstr "Пароль обфуÑкации" + +msgid "Auth Type" +msgstr "Тип аутентификации" + +msgid "Auth Password" +msgstr "Пароль аутентификации" + +msgid "Client BBR Flow Control" +msgstr "Управление клиентом BBR" + +msgid "Commands the client to use the BBR flow control algorithm" +msgstr "Включает иÑпользование алгоритма ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð¼ BBR на клиенте" + +msgid "PinSHA256" +msgstr "PinSHA256" + +msgid "Certificate fingerprint" +msgstr "Хеш Ñертификата" + +msgid "Max upload Mbps" +msgstr "МакÑ. ÑкороÑть отдачи (Мбит/Ñ)" + +msgid "Max download Mbps" +msgstr "МакÑ. ÑкороÑть загрузки (Мбит/Ñ)" + +msgid "QUIC stream receive window" +msgstr "Размер окна приёма потока QUIC" + +msgid "QUIC connection receive window" +msgstr "Размер окна приёма ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ QUIC" + +msgid "QUIC concurrent bidirectional streams" +msgstr "МакÑ. количеÑтво одновременных двунаправленных потоков QUIC" + +msgid "QUIC KeepAlive interval" +msgstr "Интервал QUIC KeepAlive" + +msgid "Disable MTU detection" +msgstr "Отключить определение MTU" + +msgid "ignoreClientBandwidth" +msgstr "Игнорировать заÑвленные лимиты пропуÑкной ÑпоÑобноÑти клиента" + +msgid "Lazy Start" +msgstr "Отложенный Ñтарт" + +msgid "Encrypt Method" +msgstr "Метод шифрованиÑ" + +msgid "Encrypt Key" +msgstr "Ключ шифрованиÑ" + +msgid "Latency" +msgstr "Задержка" + +msgid "Automatic detection delay" +msgstr "Метод автопроверки" + +msgid "Show server address and port" +msgstr "Показывать Ð°Ð´Ñ€ÐµÑ Ð¸ порт узла" + +msgid "URL Test Address" +msgstr "ÐÐ´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸" + +msgid "URL Test" +msgstr "URL-теÑÑ‚" + +msgid "Test" +msgstr "Проверить" + +msgid "Node num" +msgstr "КоличеÑтво узлов" + +msgid "Self add" +msgstr "Добавлен вручную" + +msgid "Apply" +msgstr "Применить" + +msgid "Use" +msgstr "ИÑпользовать" + +msgid "Copy" +msgstr "Копировать" + +msgid "Delay Settings" +msgstr "РаÑпиÑание" + +msgid "Open and close Daemon" +msgstr "ЗапуÑкать демон" + +msgid "Delay Start" +msgstr "Отложенный запуÑк" + +msgid "Units:seconds" +msgstr "Единица: Ñекунды" + +msgid "Units:minutes" +msgstr "Единица: минуты" + +msgid "stop automatically mode" +msgstr "Режим автоотключениÑ" + +msgid "stop Time(Every day)" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ (ежедневно)" + +msgid "stop Interval(Hour)" +msgstr "Интервал Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ (чаÑÑ‹)" + +msgid "start automatically mode" +msgstr "Режим автозапуÑка" + +msgid "start Time(Every day)" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿ÑƒÑка (ежедневно)" + +msgid "start Interval(Hour)" +msgstr "Интервал запуÑка (чаÑÑ‹)" + +msgid "restart automatically mode" +msgstr "Режим автоперезапуÑка" + +msgid "restart Time(Every day)" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑка (ежедневно)" + +msgid "restart Interval(Hour)" +msgstr "Интервал перезапуÑка (чаÑÑ‹)" + +msgid "Forwarding Settings" +msgstr "ÐаÑтройки перенаправлениÑ" + +msgid "TCP No Redir Ports" +msgstr "TCP-порты без перенаправлениÑ" + +msgid "UDP No Redir Ports" +msgstr "UDP-порты без перенаправлениÑ" + +msgid "Fill in the ports you don't want to be forwarded by the agent, with the highest priority." +msgstr "Укажите порты, которые не должны обрабатыватьÑÑ Ð¿Ñ€Ð¾ÐºÑи. Эти наÑтройки имеют наивыÑший приоритет." + +msgid "If you don't want to let the device in the list to go proxy, please choose all." +msgstr "ЕÑли вы не хотите, чтобы уÑтройÑтва из ÑпиÑка иÑпользовали прокÑи, выберите «ВÑе»." + +msgid "The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000." +msgstr "ПоддерживаютÑÑ Ð¾Ñ‚Ð´ÐµÐ»ÑŒÐ½Ñ‹Ðµ порты и диапазоны.
ÐеÑколько значений указывайте через запÑтую.
Пример: 21,80,443,1000:2000." + +msgid "TCP Proxy Drop Ports" +msgstr "TCP-порты Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ прокÑи" + +msgid "UDP Proxy Drop Ports" +msgstr "UDP-порты Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ прокÑи" + +msgid "TCP Redir Ports" +msgstr "TCP-порты Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ" + +msgid "UDP Redir Ports" +msgstr "UDP-порты Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ" + +msgid "No patterns are used" +msgstr "Ðе иÑпользовать" + +msgid "All" +msgstr "Ð’Ñе" + +msgid "Common Use" +msgstr "РаÑпроÑтранённые" + +msgid "Only Web" +msgstr "Только веб" + +msgid "or more" +msgstr "и более" + +msgid "or less" +msgstr "и менее" + +msgid "Default" +msgstr "По умолчанию" + +msgid "Close" +msgstr "Отключить" + +msgid "Hijacking ICMP (PING)" +msgstr "Перехват ICMP (PING)" + +msgid "Hijacking ICMPv6 (IPv6 PING)" +msgstr "Перехват ICMPv6 (IPv6 PING)" + +msgid "Force Proxy LAN IP" +msgstr "Принудительное иÑпользование IP-адреÑа локальной Ñети (Local IP)" + +msgid "By default, commonly used internal network IP ranges will be connect directly (not entering the core). If you want a certain network range to go through a proxy, please add it here." +msgstr "По умолчанию, чаÑто иÑпользуемые диапазоны IP-адреÑов внутренней Ñети будут подключатьÑÑ Ð½Ð°Ð¿Ñ€Ñмую (без доÑтупа к Ñдру Ñети). ЕÑли вы хотите, чтобы определенный диапазон IP-адреÑов Ñети проходил через прокÑи-Ñервер, укажите Ñто здеÑÑŒ." + +msgid "Sniffing" +msgstr "Ðнализ трафика" + +msgid "TCP Proxy Way" +msgstr "Метод TCP-прокÑированиÑ" + +msgid "Auto Switch" +msgstr "Ðвтопереключение" + +msgid "When there is no server, an automatic reconnect scheme is used" +msgstr "При потере ÑвÑзи автоматичеÑки выполнÑетÑÑ Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ" + +msgid "How often to test" +msgstr "ЧаÑтота проверки" + +msgid "Timeout seconds" +msgstr "Тайм-аут (Ñек)" + +msgid "Timeout retry num" +msgstr "КоличеÑтво повторов при тайм-ауте" + +msgid "Automatic switching cannot be used when this option is checked" +msgstr "При включении Ñтой опции автопереключение недоÑтупно" + +msgid "Main node" +msgstr "ОÑновной узел" + +msgid "List of backup nodes" +msgstr "СпиÑок резервных узлов" + +msgid "Restore Switch" +msgstr "Возврат к оÑновному" + +msgid "When detects main node is available, switch back to the main node." +msgstr "При воÑÑтановлении доÑтупноÑти оÑновного узла — автоматичеÑки переключитьÑÑ Ð½Ð° него." + +msgid "Add nodes to the standby node list by keywords" +msgstr "Добавить узлы в резервный ÑпиÑок по ключевым Ñловам" + +msgid "Delete nodes in the standby node list by keywords" +msgstr "Удалить узлы из резервного ÑпиÑка по ключевым Ñловам" + +msgid "Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase." +msgstr "Введите ключевое Ñлово. Учитывайте региÑтр и пробелы." + +msgid "Enable Load Balancing" +msgstr "Включить баланÑировку" + +msgid "Console Login Auth" +msgstr "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð² конÑоли" + +msgid "Console Username" +msgstr "Логин конÑоли" + +msgid "Console Password" +msgstr "Пароль конÑоли" + +msgid "Console Port" +msgstr "Порт конÑоли" + +msgid "In the browser input routing IP plus port access, such as:192.168.1.1:1188" +msgstr "Ð’ браузере введите IP роутера и порт, например: 192.168.1.1:1188" + +msgid "Haproxy Port" +msgstr "Порт HAProxy" + +msgid "Health Check Type" +msgstr "Тип проверки доÑтупноÑти" + +msgid "Inner implement" +msgstr "Ð’Ñтроенный механизм" + +msgid "Health Check Inter" +msgstr "Интервал проверки ÑоÑтоÑниÑ" + +msgid "When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid." +msgstr "При иÑпользовании URL-теÑта узлы баланÑировки раÑÑматриваютÑÑ ÐºÐ°Ðº SOCKS-узлы. ЕÑли ÑпиÑок задан вручную, вÑе узлы должны быть типа SOCKS — иначе проверка не будет работать." + +msgid "Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group." +msgstr "Добавление узла: Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° WAN-интерфейÑа работает только при неÑкольких WAN. ВеÑ: 1–256. ÐеÑколько оÑновных узлов могут баланÑироватьÑÑ, резервные активируютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ при отказе оÑновных. Можно Ñоздать неÑколько групп — узлы Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼ портом HAProxy объединÑÑŽÑ‚ÑÑ Ð² одну группу." + +msgid "Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!" +msgstr "Важно: при иÑпользовании TCP-проверки параметры узлов в группе баланÑировки должны Ñовпадать, иначе Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ðµ будет работать корректно." + +msgid "Node Address" +msgstr "ÐÐ´Ñ€ÐµÑ Ñервера" + +msgid "Node address cannot be empty." +msgstr "ÐÐ´Ñ€ÐµÑ Ñервера не может быть пуÑтым." + +msgid "Node Port" +msgstr "Порт Ñервера" + +msgid "Node Weight" +msgstr "Ð’ÐµÑ Ð½Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸" + +msgid "Export Of Multi WAN" +msgstr "Выбор WAN-интерфейÑа" + +msgid "Main" +msgstr "ОÑновной" + +msgid "Mode" +msgstr "Режим" + +msgid "Primary" +msgstr "ОÑновной" + +msgid "Standby" +msgstr "Резервный" + +msgid "Check update" +msgstr "Проверить обновлениÑ" + +msgid "Force update" +msgstr "Принудительное обновление" + +msgid "The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install." +msgstr "ДоÑтупна верÑÐ¸Ñ %s. ÐвтоматичеÑкое обновление пока не поддерживаетÑÑ â€” Ð´Ð»Ñ ÑƒÑтановки Ñкачайте или Ñоберите ipk-пакет и уÑтановите его вручную." + +msgid "Enable custom URL" +msgstr "Включить пользовательÑкий URL" + +msgid "Rule status" +msgstr "ВерÑÐ¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»" + +msgid "Manually update" +msgstr "Обновить вручную" + +msgid "Rollback" +msgstr "Откатить" + +msgid "Rollbacking..." +msgstr "ВыполнÑетÑÑ Ð¾Ñ‚ÐºÐ°Ñ‚..." + +msgid "Enable auto update rules" +msgstr "Ðвтообновление правил" + +msgid "Update Time(every day)" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ (ежедневно)" + +msgid "Update Interval(hour)" +msgstr "Интервал Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ (чаÑÑ‹)" + +msgid "Update Mode" +msgstr "Режим обновлениÑ" + +msgid "Loop Mode" +msgstr "ЦикличеÑкий" + +msgid "Every day" +msgstr "Ежедневно" + +msgid "Every Monday" +msgstr "По понедельникам" + +msgid "Every Tuesday" +msgstr "По вторникам" + +msgid "Every Wednesday" +msgstr "По Ñредам" + +msgid "Every Thursday" +msgstr "По четвергам" + +msgid "Every Friday" +msgstr "По пÑтницам" + +msgid "Every Saturday" +msgstr "По Ñубботам" + +msgid "Every Sunday" +msgstr "По воÑкреÑеньÑм" + +msgid "hour" +msgstr "чаÑ" + +msgid "Hour" +msgstr "ЧаÑ" + +msgid "GeoIP Update URL" +msgstr "URL Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ GeoIP" + +msgid "Geosite Update URL" +msgstr "URL Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Geosite" + +msgid "Location of Geo rule files" +msgstr "Папка Ð´Ð»Ñ Geo-файлов" + +msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." +msgstr "Укажите директорию, в которой находÑÑ‚ÑÑ Ñ„Ð°Ð¹Ð»Ñ‹ geoip.dat и geosite.dat." + +msgid "Enable GeoIP Data Parsing" +msgstr "Включить анализ данных GeoIP" + +msgid "Analyzes and preloads GeoIP data to enhance the shunt performance." +msgstr "Ðнализирует и предварительно загружает данные GeoIP Ð´Ð»Ñ ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ°." + +msgid "Note: Increases resource usage." +msgstr "Примечание: увеличивает нагрузку на ÑиÑтему." + +msgid "Shunt Rule" +msgstr "Правила Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ°" + +msgid "Please note attention to the priority, the higher the order, the higher the priority." +msgstr "Обратите внимание: правила выше в ÑпиÑке имеют более выÑокий приоритет." + +msgid "Update..." +msgstr "Обновление..." + +msgid "It is the latest version" +msgstr "УÑтановлена поÑледнÑÑ Ð²ÐµÑ€ÑиÑ" + +msgid "Update successful" +msgstr "Обновление уÑпешно" + +msgid "Click to update" +msgstr "Ðажмите Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ" + +msgid "Updating..." +msgstr "Идёт обновление..." + +msgid "Retry" +msgstr "Повторить" + +msgid "Unexpected error" +msgstr "ÐÐµÐ¿Ñ€ÐµÐ´Ð²Ð¸Ð´ÐµÐ½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" + +msgid "Updating, are you sure to close?" +msgstr "Идёт обновление. Ð’Ñ‹ уверены, что хотите закрыть?" + +msgid "Downloading..." +msgstr "Загрузка..." + +msgid "Unpacking..." +msgstr "РаÑпаковка..." + +msgid "Moving..." +msgstr "Перемещение..." + +msgid "App Update" +msgstr "Обновление компонентов" + +msgid "Please confirm that your firmware supports FPU." +msgstr "УбедитеÑÑŒ, что ваша прошивка поддерживает FPU." + +msgid "if you want to run from memory, change the path, /tmp beginning then save the application and update it manually." +msgstr "ЕÑли вы хотите запуÑкать из оперативной памÑти, измените путь на начинающийÑÑ Ñ /tmp, затем Ñохраните наÑтройки и обновите компонент вручную." + +msgid "Make sure there is enough space to install %s" +msgstr "УбедитеÑÑŒ, что доÑтаточно меÑта Ð´Ð»Ñ ÑƒÑтановки %s" + +msgid "App Path" +msgstr "Путь к приложению" + +msgid "%s App Path" +msgstr "Путь к приложению %s" + +msgid "%s Client App Path" +msgstr "Путь к клиенту %s" + +msgid "Node Subscribe" +msgstr "ПодпиÑки" + +msgid "Subscribe Remark" +msgstr "Ðазвание подпиÑки" + +msgid "Subscribe Info" +msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ подпиÑке" + +msgid "Subscribe URL" +msgstr "URL подпиÑки" + +msgid "Subscribe URL Access Method" +msgstr "СпоÑоб доÑтупа к URL подпиÑки" + +msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically." +msgstr "При добавлении новой подпиÑки Ñначала Ñохраните и примените наÑтройки, затем выполните ручную подпиÑку. ЕÑли вы только изменили URL — можно Ñразу выполнить ручную подпиÑку, ÑиÑтема Ñохранит Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." + +msgid "Please save and apply before manually subscribing." +msgstr "Сохраните и примените наÑтройки перед ручной подпиÑкой." + +msgid "Subscribe URL cannot be empty." +msgstr "URL подпиÑки не может быть пуÑтым." + +msgid "Subscribe via proxy" +msgstr "ПодпиÑка через прокÑи" + +msgid "Update Once on Boot" +msgstr "ОбновлÑть один раз при загрузке" + +msgid "Updates the subscription the first time runs automatically after each system boot." +msgstr "ПодпиÑку обновлÑÑŽÑ‚ при первом запуÑке, и она автоматичеÑки активируетÑÑ Ð¿Ð¾Ñле каждой загрузки ÑиÑтемы." + +msgid "Enable auto update subscribe" +msgstr "Ðвтообновление подпиÑки" + +msgid "Manual subscription" +msgstr "Ручное обновление подпиÑки" + +msgid "Delete All Subscribe Node" +msgstr "Удалить вÑе узлы из подпиÑки" + +msgid "Delete the subscribed node" +msgstr "Удалить узел" + +msgid "Are you sure you want to delete all subscribed nodes?" +msgstr "Ð’Ñ‹ дейÑтвительно хотите удалить вÑе узлы, добавленные через подпиÑку?" + +msgid "Manual subscription All" +msgstr "Ручное обновление вÑех подпиÑок" + +msgid "This remark already exists, please change a new remark." +msgstr "Такое название уже ÑущеÑтвует, выберите другое." + +msgid "Remark cannot be empty." +msgstr "Ðазвание не может быть пуÑтым." + +msgid "URL cannot be empty." +msgstr "URL не может быть пуÑтым." + +msgid "Filter keyword Mode" +msgstr "Режим фильтрации по ключевым Ñловам" + +msgid "Discard List" +msgstr "ОтбраÑывать ÑовпадениÑ" + +msgid "Keep List" +msgstr "ОÑтавлÑть только ÑовпадениÑ" + +msgid "Discard List,But Keep List First" +msgstr "ОтбраÑывать ÑовпадениÑ, но Ñначала применить ÑпиÑок иÑключений" + +msgid "Keep List,But Discard List First" +msgstr "ОÑтавлÑть только ÑовпадениÑ, но Ñначала применить ÑпиÑок отбраÑываниÑ" + +msgid "Use global config" +msgstr "ИÑпользовать глобальные наÑтройки" + +msgid "User-Agent" +msgstr "User-Agent" + +msgid "Add" +msgstr "Добавить" + +msgid "ACLs" +msgstr "Правила доÑтупа" + +msgid "ACLs is a tools which used to designate specific IP proxy mode." +msgstr "Правила доÑтупа (ACL) позволÑÑŽÑ‚ задавать оÑобый режим прокÑи Ð´Ð»Ñ Ð¾Ñ‚Ð´ÐµÐ»ÑŒÐ½Ñ‹Ñ… IP-адреÑов." + +msgid "Example:" +msgstr "Пример:" + +msgid "IP range" +msgstr "Диапазон IP" + +msgid "Source Interface" +msgstr "Ð˜Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¸Ñточника" + +msgid "Bridge" +msgstr "МоÑÑ‚" + +msgid "Wireless Adapter" +msgstr "БеÑпроводной адаптер" + +msgid "Ethernet Adapter" +msgstr "Ethernet-адаптер" + +msgid "Tunnel Interface" +msgstr "Туннельный интерфейÑ" + +msgid "Invalid interface name" +msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа" + +msgid "Use Interface With ACLs" +msgstr "ПрименÑть правила к интерфейÑу" + +msgid "Remarks" +msgstr "ОпиÑание" + +msgid "Direct List" +msgstr "СпиÑок прÑмого доÑтупа" + +msgid "Proxy List" +msgstr "СпиÑок Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐºÑи" + +msgid "Block List" +msgstr "СпиÑок блокировки" + +msgid "Lan IP List" +msgstr "СпиÑок LAN-IP" + +msgid "Route Hosts" +msgstr "Файл hosts" + +msgid "Join the direct hosts list of domain names will not proxy." +msgstr "Домены из Ñтого ÑпиÑка будут обходить прокÑи. Правило дейÑтвует Ð´Ð»Ñ Ð²Ñех режимов и имеет наивыÑший приоритет." + +msgid "These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5." +msgstr "IP-адреÑа и подÑети из Ñтого ÑпиÑка будут обходить прокÑи. Вводите по одному значению на Ñтроку. Пример: 192.168.0.0/24 или 223.5.5.5." + +msgid "These had been joined websites will use proxy. Please input the domain names of websites, every line can input only one website domain. For example: google.com." +msgstr "Домены из Ñтого ÑпиÑка будут иÑпользовать прокÑи. Вводите по одному домену на Ñтроку. Пример: google.com." + +msgid "These had been joined ip addresses will use proxy. Please input the ip address or ip address segment, every line can input only one ip address. For example: 35.24.0.0/24 or 8.8.4.4." +msgstr "IP-адреÑа и подÑети из Ñтого ÑпиÑка будут иÑпользовать прокÑи. Вводите по одному значению на Ñтроку. Пример: 35.24.0.0/24 или 8.8.4.4." + +msgid "These had been joined websites will be block. Please input the domain names of websites, every line can input only one website domain. For example: twitter.com." +msgstr "Домены из Ñтого ÑпиÑка будут блокироватьÑÑ. Вводите по одному домену на Ñтроку. Пример: twitter.com." + +msgid "The list is the IPv4 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "СпиÑок IPv4-адреÑов локальной Ñети, которые вÑегда подключаютÑÑ Ð½Ð°Ð¿Ñ€Ñмую. ЕÑли вам нужно, чтобы LAN-IP иÑпользовал прокÑи, удалите его из Ñтого ÑпиÑка. По умолчанию не изменÑйте Ñтот ÑпиÑок." + +msgid "The list is the IPv6 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "СпиÑок IPv6-адреÑов локальной Ñети, которые вÑегда подключаютÑÑ Ð½Ð°Ð¿Ñ€Ñмую. ЕÑли вам нужно, чтобы LAN-IP иÑпользовал прокÑи, удалите его из Ñтого ÑпиÑка. По умолчанию не изменÑйте Ñтот ÑпиÑок." + +msgid "Configure routing etc/hosts file, if you don't know what you are doing, please don't change the content." +msgstr "Редактирование файла hosts роутера. ЕÑли вы не уверены в Ñвоих дейÑтвиÑÑ…, не изменÑйте Ñодержимое." + +msgid "These had been joined ip addresses will be block. Please input the ip address or ip address segment, every line can input only one ip address." +msgstr "IP-адреÑа и подÑети из Ñтого ÑпиÑка будут блокироватьÑÑ. Вводите по одному значению на Ñтроку." + +msgid "Inbound Tag" +msgstr "Метка входÑщего ÑоединениÑ" + +msgid "Transparent proxy" +msgstr "Прозрачный прокÑи" + +msgid "Not valid domain name, please re-enter!" +msgstr "Ðеверный формат домена, пожалуйÑта, введите заново!" + +msgid "Not valid IP format, please re-enter!" +msgstr "Ðеверный формат IP, пожалуйÑта, введите заново!" + +msgid "Not valid IPv4 format, please re-enter!" +msgstr "Ðеверный формат IPv4, пожалуйÑта, введите заново!" + +msgid "Not valid IPv6 format, please re-enter!" +msgstr "Ðеверный формат IPv6, пожалуйÑта, введите заново!" + +msgid "Not true format, please re-enter!" +msgstr "Ðеверный формат, пожалуйÑта, введите заново!" + +msgid "Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'." +msgstr "ТекÑÑ‚: правило Ñрабатывает, еÑли Ñтрока вÑтречаетÑÑ Ð² любом меÑте домена. Ðапример, 'sina.com' Ñовпадёт Ñ 'sina.com', 'sina.com.cn', 'www.sina.com', но не Ñ 'sina.cn'." + +msgid "Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'." +msgstr "РегулÑрное выражение: начинаетÑÑ Ñ 'regexp:', далее — шаблон. Правило Ñрабатывает при Ñовпадении. Ðапример, 'regexp:\\.goo.*\\.com$' Ñовпадёт Ñ 'www.google.com' и 'fonts.googleapis.com', но не Ñ 'google.com'." + +msgid "Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'." +msgstr "Поддомен (рекомендуетÑÑ): начинаетÑÑ Ñ 'domain:', далее — домен. Правило Ñрабатывает Ð´Ð»Ñ Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ ÑÐ¾Ð²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ любого поддомена. Ðапример, 'domain:v2ray.com' Ñовпадёт Ñ 'www.v2ray.com' и 'v2ray.com', но не Ñ 'xv2ray.com'." + +msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'." +msgstr "Полное Ñовпадение: начинаетÑÑ Ñ 'full:', далее — домен. Правило Ñрабатывает только при точном Ñовпадении. Ðапример, 'full:v2ray.com' Ñовпадёт только Ñ 'v2ray.com', но не Ñ 'www.v2ray.com'." + +msgid "Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'" +msgstr "Ðабор правил Sing-Box: начинаетÑÑ Ñ 'rule-set:remote:' или 'rule-set:local:'" + +msgid "Such as:" +msgstr "Ðапример:" + +msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn." +msgstr "Предопределённый ÑпиÑок: начинаетÑÑ Ñ 'geosite:', далее — Ð¸Ð¼Ñ Ð½Ð°Ð±Ð¾Ñ€Ð°, например geosite:google или geosite:cn." + +msgid "Annotation: Begining with #" +msgstr "Комментарий начинаетÑÑ Ñ #" + +msgid "Invert match result." +msgstr "Инвертировать результат." + +msgid "Only support Sing-Box." +msgstr "ПоддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в Sing-Box." + +msgid "IP: such as '127.0.0.1'." +msgstr "IP: например, '127.0.0.1'." + +msgid "CIDR: such as '127.0.0.0/8'." +msgstr "CIDR: например, '10.0.0.0/8'." + +msgid "GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code." +msgstr "GeoIP: например, 'geoip:cn'. Должно начинатьÑÑ Ñ 'geoip:' (Ñтрочными), далее — двухбуквенный код Ñтраны." + +msgid "Clear logs" +msgstr "ОчиÑтить журнал" + +msgid "Password" +msgstr "Пароль" + +msgid "IV Check" +msgstr "Проверка IV" + +msgid "UDP over TCP" +msgstr "UDP через TCP" + +msgid "Connection Timeout" +msgstr "Тайм-аут подключениÑ" + +msgid "Local Port" +msgstr "Локальный порт" + +msgid "Fast Open" +msgstr "Fast Open" + +msgid "Pre-connections" +msgstr "Предварительные ÑоединениÑ" + +msgid "Number of early established connections to reduce latency." +msgstr "КоличеÑтво заранее уÑтановленных Ñоединений Ð´Ð»Ñ ÑÐ½Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¸." + +msgid "plugin" +msgstr "Плагин" + +msgid "Supports custom SIP003 plugins, Make sure the plugin is installed." +msgstr "ПоддерживаютÑÑ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑкие плагины SIP003. УбедитеÑÑŒ, что плагин уÑтановлен." + +msgid "opts" +msgstr "опции" + +msgid "Protocol" +msgstr "Протокол" + +msgid "Protocol_param" +msgstr "Параметры протокола" + +msgid "Obfs" +msgstr "ОбфуÑкациÑ" + +msgid "Obfs_param" +msgstr "Параметры обфуÑкации" + +msgid "Plugin Name" +msgstr "Ðазвание плагина" + +msgid "Plugin Arguments" +msgstr "Ðргументы плагина" + +msgid "User Level" +msgstr "Уровень доÑтупа" + +msgid "Transport" +msgstr "ТранÑпорт" + +msgid "Public Key" +msgstr "Публичный ключ" + +msgid "Private Key" +msgstr "Приватный ключ" + +msgid "Pre shared key" +msgstr "Дополнительный Ñимметричный ключ" + +msgid "Local Address" +msgstr "Локальный адреÑ" + +msgid "System interface" +msgstr "СиÑтемный интерфейÑ" + +msgid "System interface name" +msgstr "Ð˜Ð¼Ñ ÑиÑтемного интерфейÑа" + +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "ДеÑÑтичные чиÑла через запÑтую или Ñтроки в кодировке Base64." + +msgid "Camouflage Domain" +msgstr "МаÑкировочный домен" + +msgid "Camouflage Type" +msgstr "Тип маÑкировки" + +msgid "Transport Layer Encryption" +msgstr "Шифрование транÑпортного уровнÑ" + +msgid "Whether or not transport layer encryption is enabled, \"none\" for unencrypted, \"tls\" for using TLS, \"xtls\" for using XTLS." +msgstr "Включено ли шифрование транÑпортного уровнÑ: «none» — без шифрованиÑ, «tls» — TLS, «xtls» — XTLS." + +msgid "Original Trojan only supported 'tls', please choose 'tls'." +msgstr "Оригинальный Trojan поддерживает только 'tls' — выберите Ñтот вариант." + +msgid "Transfer mode" +msgstr "Режим передачи" + +msgid "Do not send server name in ClientHello." +msgstr "Ðе отправлÑть Ð¸Ð¼Ñ Ñервера в ClientHello." + +msgid "Domain" +msgstr "Домен" + +msgid "allowInsecure" +msgstr "ПропуÑкать проверку Ñертификата" + +msgid "Whether unsafe connections are allowed. When checked, Certificate validation will be skipped." +msgstr "Разрешить ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð±ÐµÐ· проверки Ñертификата. При включении Ð²Ð°Ð»Ð¸Ð´Ð°Ñ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ пропущена." + +msgid "Used when the node link does not include this parameter." +msgstr "ИÑпользуетÑÑ, еÑли в ÑÑылке на узел Ñтот параметр отÑутÑтвует." + +msgid "%s Node Use Type" +msgstr "Тип иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñервера %s" + +msgid "UDP relay mode" +msgstr "Режим ретранÑлÑции UDP" + +msgid "Concurrent Tunnels" +msgstr "Одновременные туннели" + +msgid "Congestion control algorithm" +msgstr "Ðлгоритм ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ñ€ÑƒÐ·Ð¾Ðº" + +msgid "Heartbeat interval(second)" +msgstr "Интервал heartbeat-пакетов (Ñек)" + +msgid "Disable SNI" +msgstr "Отключить SNI" + +msgid "Enable 0-RTT QUIC handshake" +msgstr "Включить 0-RTT рукопожатие QUIC" + +msgid "
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests." +msgstr "
none: по умолчанию, без маÑкировки, данные отправлÑÑŽÑ‚ÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¼Ð¸ пакетами.
srtp: маÑкировка под SRTP — трафик определÑетÑÑ ÐºÐ°Ðº видеозвонок (например, FaceTime).
utp: маÑкировка под uTP — трафик определÑетÑÑ ÐºÐ°Ðº BitTorrent.
wechat-video: маÑкировка под видеозвонок WeChat.
dtls: маÑкировка под DTLS 1.2.
wireguard: маÑкировка под WireGuard (не наÑтоÑщий протокол WireGuard).
dns: маÑкировка трафика под DNS-запроÑÑ‹." + +msgid "Use it together with the DNS disguised type. You can fill in any domain." +msgstr "ИÑпользуетÑÑ Ð²Ð¼ÐµÑте Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ маÑкировки DNS. Можно указать любой домен." + +msgid "Auth" +msgstr "ÐутентификациÑ" + +msgid "Socks for authentication" +msgstr "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ SOCKS" + +msgid "Socks protocol authentication, support anonymous and password." +msgstr "Метод аутентификации SOCKS: анонимный или по логину/паролю." + +msgid "anonymous" +msgstr "анонимно" + +msgid "User Password" +msgstr "Логин и пароль" + +msgid "Username and Password must be used together!" +msgstr "Логин и пароль должны быть указаны вмеÑте!" + +msgid "Prefer firewall tools" +msgstr "Предпочтительный инÑтрумент фаервола" + +msgid "IPv6 TProxy" +msgstr "IPv6 TProxy" + +msgid "Experimental feature. Make sure that your node supports IPv6." +msgstr "ЭкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ. УбедитеÑÑŒ, что ваш Ñервер поддерживает IPv6." + +msgid "Status info" +msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ÑтатуÑе" + +msgid "Big icon" +msgstr "Крупный значок" + +msgid "Show node check" +msgstr "Показывать проверку Ñерверов" + +msgid "Show Show IP111" +msgstr "Показывать IP111" + +msgid "Destination protocol" +msgstr "Целевой протокол" + +msgid "Destination address" +msgstr "Целевой адреÑ" + +msgid "Destination port" +msgstr "Целевой порт" + +msgid "Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used." +msgstr "Принимать ли PROXY protocol. ЕÑли Ñтот Ñервер иÑпользуетÑÑ Ð´Ð»Ñ fallback или Ð¿ÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· прокÑи, Ð¾Ð¿Ñ†Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть включена, иначе работа невозможна." + +msgid "outbound node" +msgstr "ИÑходÑщий Ñервер" + +msgid "Custom Socks" +msgstr "ПользовательÑкий SOCKS" + +msgid "Custom HTTP" +msgstr "ПользовательÑкий HTTP" + +msgid "Custom Interface" +msgstr "ПользовательÑкий интерфейÑ" + +msgid "Interface" +msgstr "ИнтерфейÑ" + +msgid "Bind Local" +msgstr "Только Ð´Ð»Ñ localhost" + +msgid "When selected, it can only be accessed localhost." +msgstr "ЕÑли включено, доÑтуп возможен только Ñ Ñамого роутера." + +msgid "Accept LAN Access" +msgstr "Разрешить доÑтуп из LAN" + +msgid "When selected, it can accessed lan , this will not be safe!" +msgstr "ЕÑли включено, ÑÐµÑ€Ð²Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ доÑтупен из локальной Ñети. Это небезопаÑно! (Ðе рекомендуетÑÑ Ð±ÐµÐ· необходимоÑти)." + +msgid "Enable Remote" +msgstr "Включить перенаправление" + +msgid "You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more." +msgstr "Можно перенаправлÑть на Nginx/Caddy/V2Ray/Xray WebSocket и другие ÑервиÑÑ‹." + +msgid "Remote Address" +msgstr "Удалённый адреÑ" + +msgid "Remote Port" +msgstr "Удалённый порт" + +msgid "as:" +msgstr "например:" + +msgid "Public key absolute path" +msgstr "Полный путь к публичному ключу" + +msgid "Private key absolute path" +msgstr "Полный путь к приватному ключу" + +msgid "Can't find this file!" +msgstr "Файл не найден!" + +msgid "Public key and Private key path can not be empty!" +msgstr "Пути к публичному и приватному ключам не могут быть пуÑтыми!" + +msgid "Server-Side" +msgstr "Ð¡ÐµÑ€Ð²ÐµÑ€Ð½Ð°Ñ Ñ‡Ð°Ñть" + +msgid "Server Config" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñервера" + +msgid "Users Manager" +msgstr "Управление пользователÑми" + +msgid "Logs" +msgstr "Журнал" + +msgid "Log" +msgstr "Журнал" + +msgid "Enable Node Log" +msgstr "ЗапиÑÑŒ журнала" + +msgid "Log Level" +msgstr "Уровень запиÑи журнала" + +msgid "Not enabled log" +msgstr "ЗапиÑÑŒ журнала отключена" + +msgid "UDP Forward" +msgstr "UDP-перенаправление" + +msgid "DNS Settings" +msgstr "ÐаÑтройки DNS" + +msgid "Null" +msgstr "Ðет" + +msgid "You did not fill in the %s path. Please save and apply then update manually." +msgstr "Ð’Ñ‹ не указали путь к %s. Сохраните наÑтройки, затем выполните обновление вручную." + +msgid "Not installed %s, Can't unzip!" +msgstr "%s не уÑтановлен — раÑпаковка невозможна." + +msgid "Can't determine ARCH, or ARCH not supported." +msgstr "Ðе удалоÑÑŒ определить архитектуру, или она не поддерживаетÑÑ." + +msgid "Get remote version info failed." +msgstr "Ðе удалоÑÑŒ получить информацию о верÑии Ñ Ñервера." + +msgid "New version found, but failed to get new version download url." +msgstr "Обнаружена Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑиÑ, но не удалоÑÑŒ получить ÑÑылку Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸." + +msgid "Download url is required." +msgstr "Ðеобходимо указать URL Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸." + +msgid "File download failed or timed out: %s" +msgstr "Ошибка загрузки файла или тайм-аут: %s" + +msgid "File path required." +msgstr "Ðеобходимо указать путь к файлу." + +msgid "%s not enough space." +msgstr "ÐедоÑтаточно меÑта Ð´Ð»Ñ %s." + +msgid "Can't find client in file: %s" +msgstr "Ðе удалоÑÑŒ найти клиент в файле: %s" + +msgid "Client file is required." +msgstr "Ðеобходимо указать файл клиента." + +msgid "The client file is not suitable for current device." +msgstr "Файл клиента не подходит Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ уÑтройÑтва." + +msgid "Can't move new file to path: %s" +msgstr "Ðе удалоÑÑŒ перемеÑтить файл в: %s" + +msgid "An XHttpObject in JSON format, used for sharing." +msgstr "XHttpObject в формате JSON, иÑпользуетÑÑ Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ½Ð° наÑтройками." + +msgid "Enable Mux.Cool" +msgstr "Включить Mux.Cool" + +msgid "Mux concurrency" +msgstr "МакÑ. параллельных Ñоединений" + +msgid "XUDP Mux concurrency" +msgstr "МакÑ. параллельных Ñоединений XUDP" + +msgid "Padding" +msgstr "Заполнение" + +msgid "Enable early data" +msgstr "Включить 0-RTT данные" + +msgid "Early data length" +msgstr "МакÑ. длина 0-RTT данных" + +msgid "Early data header name" +msgstr "Ð˜Ð¼Ñ HTTP-заголовка Ð´Ð»Ñ 0-RTT" + +msgid "Recommended value: Sec-WebSocket-Protocol" +msgstr "Рекомендуемое значение: Sec-WebSocket-Protocol" + +msgid "Health check" +msgstr "Проверка доÑтупноÑти" + +msgid "Health check timeout" +msgstr "Тайм-аут проверки" + +msgid "Permit without stream" +msgstr "Проверка без активного потока" + +msgid "Initial Windows Size" +msgstr "Ðачальный размер окна" + +msgid "Excluded Domains" +msgstr "ИÑключённые домены" + +msgid "If the traffic sniffing result is in this list, the destination address will not be overridden." +msgstr "ЕÑли результат анализа трафика еÑть в Ñтом ÑпиÑке, целевой Ð°Ð´Ñ€ÐµÑ Ð½Ðµ будет заменён." + +msgid "Buffer Size" +msgstr "Размер буфера" + +msgid "Buffer size for every connection (kB)" +msgstr "Размер буфера Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (КБ)" + +msgid "Idle Timeout" +msgstr "Тайм-аут проÑтоÑ" + +msgid "Hop Interval(second)" +msgstr "Интервал прыжков (Ñекунды)" + +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "ПоддерживаетÑÑ Ñ„Ð¸ÐºÑированное значение или Ñлучайный диапазон (например, 30, 5-30), минимум 5." + +msgid "HeartbeatPeriod(second)" +msgstr "Период heartbeat-пакетов (Ñек)" + +msgid "Override the connection destination address" +msgstr "ЗаменÑть целевой Ð°Ð´Ñ€ÐµÑ ÑоединениÑ" + +msgid "Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "ЗаменÑть целевой Ð°Ð´Ñ€ÐµÑ Ð½Ð° домен, полученный при анализе трафика.
Иначе домен будет иÑпользоватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¼Ð°Ñ€ÑˆÑ€ÑƒÑ‚Ð¸Ð·Ð°Ñ†Ð¸Ð¸.
При иÑпользовании Ñерверов Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ° правильно наÑтройте правила доменной маршрутизации." + +msgid "Handshake Server" +msgstr "Сервер рукопожатиÑ" + +msgid "Handshake Server Port" +msgstr "Порт Ñервера рукопожатиÑ" + +msgid "Protocol parameter. Will waste traffic randomly if enabled." +msgstr "Параметр протокола. При включении Ñлучайным образом увеличивает раÑход трафика." + +msgid "Protocol parameter. Enable length block encryption." +msgstr "Параметр протокола. Включает шифрование блоков длины." + +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "Отпечаток цепочки TLS (SHA256)" + +msgid "Once set, connects only when the server's chain fingerprint matches." +msgstr "ПоÑле уÑтановки Ñоединение возможно только при Ñовпадении отпечатка цепочки Ñервера." + +msgid "TLS Certificate Name (CertName)" +msgstr "Ð˜Ð¼Ñ TLS-Ñертификата (CertName)" + +msgid "TLS is used to verify the leaf certificate name." +msgstr "ИÑпользуетÑÑ TLS Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ имени конечного Ñертификата." + +msgid "ECH Config" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ ECH" + +msgid "ECH Key" +msgstr "Ключ ECH" + +msgid "ECH Query Policy" +msgstr "Политика запроÑов ECH" + +msgid "Controls the policy used when performing DNS queries for ECH configuration." +msgstr "УправлÑет политикой DNS-запроÑов Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¸ ECH." + +msgid "ECH Query Domain" +msgstr "Домен запроÑа ECH" + +msgid "Overrides the domain name used for ECH HTTPS record queries." +msgstr "ПереопределÑет доменное имÑ, иÑпользуемое Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов запиÑей ECH HTTPS." + +msgid "Enable Multipath TCP, need to be enabled in both server and client configuration." +msgstr "Включить Multipath TCP. Должно быть активировано и на Ñервере, и на клиенте." + +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "Объект FinalMaskObject в формате JSON, иÑпользуемый Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ½Ð° данными." + +msgid "Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings." +msgstr "ПользовательÑÐºÐ°Ñ Ð½Ð°Ñтройка finalmask переопределÑет параметры mkcp, hysteria2, fragment, noise и ÑвÑзанные Ñ Ð½Ð¸Ð¼Ð¸ наÑтройки." + +msgid "Fragment" +msgstr "ФрагментациÑ" + +msgid "TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists." +msgstr "Ð¤Ñ€Ð°Ð³Ð¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ TCP-пакетов. Ð’ некоторых ÑлучаÑÑ… помогает обходить ÑиÑтемы цензуры, например, чёрные ÑпиÑки SNI." + +msgid "Fragment Packets" +msgstr "СпоÑоб фрагментации" + +msgid "\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation." +msgstr "«1–3» — Ñ„Ñ€Ð°Ð³Ð¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ TCP Ð´Ð»Ñ Ð¿ÐµÑ€Ð²Ñ‹Ñ… 1–3 отправок данных клиентом. «tlshello» — Ñ„Ñ€Ð°Ð³Ð¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð°ÐºÐµÑ‚Ð° TLS ClientHello." + +msgid "Fragment Length" +msgstr "Длина фрагмента" + +msgid "Fragmented packet length (byte)" +msgstr "Длина фрагментированного пакета (байт)" + +msgid "Fragment Delay" +msgstr "Задержка фрагмента" + +msgid "Fragmentation interval (ms)" +msgstr "Интервал между фрагментами (мÑ)" + +msgid "Max Split" +msgstr "МакÑимальное разделение" + +msgid "Limit the maximum number of splits." +msgstr "Ограничьте макÑимальное количеÑтво разделений." + +msgid "Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first." +msgstr "Разбивать данные Ñ€ÑƒÐºÐ¾Ð¿Ð¾Ð¶Ð°Ñ‚Ð¸Ñ Ð½Ð° неÑколько TLS-запиÑей Ð´Ð»Ñ Ð»ÑƒÑ‡ÑˆÐµÐ³Ð¾ обхода цензуры. ÐœÐ°Ð»Ð°Ñ Ð½Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°. РекомендуетÑÑ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ в первую очередь." + +msgid "Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed." +msgstr "Разбивать рукопожатие на неÑколько TCP-Ñегментов. УÑиливает маÑкировку. Может увеличить задержку. ИÑпользовать только при необходимоÑти." + +msgid "Noise" +msgstr "Шум" + +msgid "UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions." +msgstr "UDP-шум. Ð’ некоторых ÑлучаÑÑ… помогает обходить ограничениÑ, наложенные на UDP-протоколы." + +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "Чтобы отправлÑть шумовые пакеты, включите «Шум» в наÑтройках Xray." + +msgid "Xray Noise Packets" +msgstr "Пакеты шума Xray" + +msgid "Packet | Rand Length" +msgstr "Пакет | Длина ранда" + +msgid "Delay (ms)" +msgstr "Задержка (мÑ)" + +msgid "If is domain name, The requested domain name will be resolved to IP before connect." +msgstr "ЕÑли указано доменное имÑ, оно будет разрешено в IP-Ð°Ð´Ñ€ÐµÑ Ð¿ÐµÑ€ÐµÐ´ подключением." + +msgid "Domain DNS Resolve" +msgstr "Разрешение DNS-запроÑов Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°" + +msgid "If the node address is a domain name, this DNS will be used for resolution." +msgstr "ЕÑли Ð°Ð´Ñ€ÐµÑ ÑƒÐ·Ð»Ð° ÑвлÑетÑÑ Ð´Ð¾Ð¼ÐµÐ½Ð½Ñ‹Ð¼ именем, Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ иÑпользоватьÑÑ Ñтот DNS-Ñервер." + +msgid "Supports only Xray or Sing-box node types." +msgstr "ПоддерживаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ узлы типа Xray или Sing-box." + +msgid "Chain Proxy" +msgstr "Цепочка прокÑи" + +msgid "Outbound Interface" +msgstr "ИÑходÑщий интерфейÑ" + +msgid "Landing Node" +msgstr "Сервер выхода" + +msgid "Only support a layer of proxy." +msgstr "ПоддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ один уровень цепочки." + +msgid "" +"Chained proxy works only with Xray or Sing-box nodes.
" +"You can only use manual or imported nodes as chained nodes." +msgstr "" +"Цепочка прокÑи работает только Ñ Ñерверами Xray или Sing-Box.
" +"Ð’ качеÑтве звеньев цепочки можно иÑпользовать только Ñерверы, добавленные вручную или импортированные." + +msgid "Prefer IPv4" +msgstr "Предпочитать IPv4" + +msgid "Prefer IPv6" +msgstr "Предпочитать IPv6" + +msgid "IPv4 Only" +msgstr "Только IPv4" + +msgid "IPv6 Only" +msgstr "Только IPv6" + +msgid "Maintain" +msgstr "ОбÑлуживание" + +msgid "Backup and Restore" +msgstr "Резервное копирование" + +msgid "Backup or Restore Client and Server Configurations." +msgstr "Создание или воÑÑтановление резервной копии наÑтроек клиента и Ñервера." + +msgid "Note: Restoring configurations across different versions may cause compatibility issues." +msgstr "Примечание: воÑÑтановление наÑтроек между разными верÑиÑми может вызвать проблемы ÑовмеÑтимоÑти." + +msgid "Create Backup File" +msgstr "Создать резервную копию" + +msgid "Restore Backup File" +msgstr "ВоÑÑтановить из резервной копии" + +msgid "DL Backup" +msgstr "Скачать резервную копию" + +msgid "RST Backup" +msgstr "ВоÑÑтановить из копии" + +msgid "Backup failed!" +msgstr "Ошибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð¹ копии!" + +msgid "UL Restore" +msgstr "Загрузить и воÑÑтановить" + +msgid "CLOSE WIN" +msgstr "Закрыть окно" + +msgid "Restore to default configuration" +msgstr "ВоÑÑтановить наÑтройки по умолчанию" + +msgid "Do Reset" +msgstr "Выполнить ÑброÑ" + +msgid "Please select a file first." +msgstr "Сначала выберите файл." + +msgid "Invalid file type. Please upload a .tar.gz file." +msgstr "ÐедопуÑтимый тип файла. ПожалуйÑта, загрузите файл .tar.gz." + +msgid "File size exceeds 10MB limit." +msgstr "Размер файла превышает лимит 10 МБ." + +msgid "Do you want to restore the client to default settings?" +msgstr "ВоÑÑтановить наÑтройки клиента по умолчанию?" + +msgid "Are you sure you want to restore the client to default settings?" +msgstr "Ð’Ñ‹ дейÑтвительно хотите воÑÑтановить наÑтройки клиента по умолчанию?" + +msgid "Configuration file uploaded successfully…" +msgstr "Файл конфигурации уÑпешно загружен…" + +msgid "Configuration restored successfully…" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ ÑƒÑпешно воÑÑтановлена…" + +msgid "Service restarting…" +msgstr "ПерезапуÑк Ñлужбы…" + +msgid "Configuration file decompression failed, please try again!" +msgstr "Ошибка раÑпаковки файла конфигурации, попробуйте ещё раз!" + +msgid "_urltest" +msgstr "_urltest" + +msgid "URLTest node list" +msgstr "СпиÑок Ñерверов Ð´Ð»Ñ URLTest" + +msgid "List of nodes to test, document" +msgstr "СпиÑок Ñерверов Ð´Ð»Ñ Ñ‚ÐµÑтированиÑ, документациÑ" + +msgid "Test interval" +msgstr "Интервал теÑтированиÑ" + +msgid "Test interval must be less or equal than idle timeout." +msgstr "Интервал теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ должен превышать тайм-аут проÑтоÑ." + +msgid "Test tolerance" +msgstr "ДопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ð¾Ñть" + +msgid "The test tolerance in milliseconds." +msgstr "ДопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ð¾Ñть теÑта в миллиÑекундах." + +msgid "Idle timeout" +msgstr "Тайм-аут проÑтоÑ" + +msgid "The idle timeout." +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð±ÐµÐ·Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ Ð´Ð¾ отключениÑ." + +msgid "Interrupt existing connections" +msgstr "Разрывать активные ÑоединениÑ" + +msgid "Interrupt existing connections when the selected outbound has changed." +msgstr "Разрывать ÑущеÑтвующие ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ Ñмене выбранного иÑходÑщего Ñервера." + +msgid "Port hopping range" +msgstr "Диапазон Ñмены портов" + +msgid "Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,)." +msgstr "Формат: 1000:2000 или 1000-2000. ÐеÑколько групп разделÑÑŽÑ‚ÑÑ Ð·Ð°Ð¿Ñтой (,)." + +msgid "Use Custom Config" +msgstr "ИÑпользовать Ñвою конфигурацию" + +msgid "Custom Config" +msgstr "ПользовательÑÐºÐ°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ" + +msgid "Must be JSON text!" +msgstr "Должен быть JSON-текÑÑ‚!" + +msgid "Geo View" +msgstr "ПроÑмотр Geo" + +msgid "Query" +msgstr "ЗапроÑ" + +msgid "Querying" +msgstr "Идёт запроÑ..." + +msgid "Please enter query content!" +msgstr "ПожалуйÑта, введите текÑÑ‚ запроÑа!" + +msgid "No results were found!" +msgstr "Ðичего не найдено!" + +msgid "Rules containing this value:" +msgstr "Правила, Ñодержащие Ñто значение:" + +msgid "Domain/IP Query" +msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°/IP" + +msgid "GeoIP/Geosite Query" +msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ GeoIP/Geosite" + +msgid "Enter a domain or IP to query the Geo rule list they belong to." +msgstr "Введите домен или IP, чтобы узнать, в какие Geo-правила они входÑÑ‚." + +msgid "Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw" +msgstr "Введите GeoIP или Geosite, чтобы получить ÑпиÑок ÑодержащихÑÑ Ð² них доменов/IP. Формат: geoip:cn или geosite:gfw" + +msgid "Tips:" +msgstr "ПодÑказки:" + +msgid "By entering a domain or IP, you can query the Geo rule list they belong to." +msgstr "Ð’Ð²ÐµÐ´Ñ Ð´Ð¾Ð¼ÐµÐ½ или IP, можно узнать, в какие Geo-правила он входит." + +msgid "By entering a GeoIP or Geosite, you can extract the domains/IPs they contain." +msgstr "Ð’Ð²ÐµÐ´Ñ GeoIP или Geosite, можно получить ÑпиÑок ÑодержащихÑÑ Ð² них доменов/IP." + +msgid "Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct." +msgstr "ИÑпользуйте функцию запроÑа GeoIP/Geosite Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ корректноÑти введённых Geo-правил." + +msgid "Private Key Passphrase" +msgstr "ÐŸÐ°Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð° приватного ключа" + +msgid "Host Key" +msgstr "Ключ хоÑта" + +msgid "Accept any if empty." +msgstr "ЕÑли оÑтавить пуÑтым — принимать любой." + +msgid "Host Key Algorithms" +msgstr "Ðлгоритмы ключа хоÑта" + +msgid "Client Version" +msgstr "ВерÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°" + +msgid "Random version will be used if empty." +msgstr "ЕÑли оÑтавить пуÑтым — будет иÑпользована ÑÐ»ÑƒÑ‡Ð°Ð¹Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ." + +msgid "The configured type also applies to the core specified when manually importing nodes." +msgstr "Выбранный тип также применÑетÑÑ Ðº Ñдру, указанному при ручном импорте Ñерверов." + +msgid "Group Name" +msgstr "Ðазвание группы" + +msgid "Reassign Group" +msgstr "Изменить группу" + +msgid "Reassign Node Group" +msgstr "Изменить группу Ñервера" + +msgid "Search nodes..." +msgstr "ПоиÑк Ñерверов..." + +msgid "Using..." +msgstr "ИÑпользуетÑÑ." + +msgid "Generate configuration file and run" +msgstr "Сгенерировать конфигурацию и запуÑтить" + +msgid "Start after a delay of %s seconds!" +msgstr "ЗапуÑк Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ %s Ñекунд!" + +msgid "The script is already running, do not run it again. Exit." +msgstr "Скрипт уже выполнÑетÑÑ, повторный запуÑк отменён." + +msgid "Stop the script and wait for a timeout, then exit without repeating the process." +msgstr "ОÑтановка Ñкрипта и ожидание тайм-аута, выход без повторного выполнениÑ." + +msgid "Warning: The %s application environment is incomplete. Switch to %s. (%s)" +msgstr "Внимание: Ñреда Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ %s неполнаÑ. Переключение на %s. (%s)" + +msgid "Note: Dnsmasq (%s) is below 2.90. Upgrading is recommended to improve stability." +msgstr "Примечание: верÑÐ¸Ñ Dnsmasq (%s) ниже 2.90. РекомендуетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸Ñ‚ÑŒ Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ ÑтабильноÑти." + +msgid "Warning: %s transparent proxy is missing basic dependency %s!" +msgstr "Внимание: Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð·Ñ€Ð°Ñ‡Ð½Ð¾Ð³Ð¾ прокÑи %s отÑутÑтвует Ð±Ð°Ð·Ð¾Ð²Ð°Ñ Ð·Ð°Ð²Ð¸ÑимоÑть %s!" + +msgid "Warning: Not compatible with any transparent proxy system environment." +msgstr "Внимание: неÑовмеÑтимо ни Ñ Ð¾Ð´Ð½Ð¾Ð¹ Ñредой прозрачного прокÑи." + +msgid "%s does not have execute permissions and cannot be started: %s %s" +msgstr "У %s нет прав на выполнение, запуÑк невозможен: %s %s" + +msgid "%s not found, unable to start..." +msgstr "%s не найден, запуÑк невозможен..." + +msgid "Socks node: [%s]%s is an invalid server address and cannot be started!" +msgstr "SOCKS-Ñервер: [%s]%s — недопуÑтимый адреÑ, запуÑк невозможен!" + +msgid "For some reason, the configuration for this Socks service has been lost, and its startup has been aborted!" +msgstr "По неизвеÑтной причине ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñтого SOCKS-ÑервиÑа утерÑна, запуÑк отменён!" + +msgid "Socks node: [%s]%s, start failed %s:%s %s" +msgstr "SOCKS-Ñервер: [%s]%s, ошибка запуÑка %s:%s %s" + +msgid "Socks node: [%s]%s, starting %s:%s" +msgstr "SOCKS-Ñервер: [%s]%s, запуÑк %s:%s" + +msgid "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!" +msgstr "Ð”Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ ÑкÑпериментального IPv6-прокÑи (TProxy) убедитеÑÑŒ, что ваш Ñервер и тип поддерживают IPv6!" + +msgid "[%s] process %s error, skip this transparent proxy!" +msgstr "ã€%s】 ошибка процеÑÑа %s, Ñтот прозрачный прокÑи пропуÑкаетÑÑ!" + +msgid "Analyzing the node configuration of the Socks service..." +msgstr "Ðнализ конфигурации Ñервера Ð´Ð»Ñ SOCKS-ÑервиÑа..." + +msgid "Log file is too long, clear it!" +msgstr "Файл журнала Ñлишком большой, выполнÑетÑÑ Ð¾Ñ‡Ð¸Ñтка!" + +msgid "The task is currently running automatically as a scheduled task; no reconfiguration of the scheduled task is required." +msgstr "Задача уже выполнÑетÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки по раÑпиÑанию, Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð½Ð°Ñтройка не требуетÑÑ." + +msgid "Scheduled tasks: Auto stop service." +msgstr "Планировщик: автоотключение Ñлужбы." + +msgid "Scheduled tasks: Auto start service." +msgstr "Планировщик: автозапуÑк Ñлужбы." + +msgid "Scheduled tasks: Auto restart service." +msgstr "Планировщик: автоперезапуÑк Ñлужбы." + +msgid "Scheduled tasks: Auto update rules." +msgstr "Планировщик: автообновление правил." + +msgid "Scheduled tasks: Auto update [%s] subscription." +msgstr "Планировщик: автообновление подпиÑки [%s]." + +msgid "Auto updates: Starts a cyclical update process." +msgstr "Ðвтообновление: запуÑк цикличеÑкого процеÑÑа обновлениÑ." + +msgid "Running in no proxy mode, it only allows scheduled tasks for starting and stopping services." +msgstr "Работа в режиме без прокÑи: разрешены только задачи автозапуÑка и Ð°Ð²Ñ‚Ð¾Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñлужбы." + +msgid "Clear scheduled commands." +msgstr "ОчиÑтить запланированные команды." + +msgid "Unable to resolve [%s], route table addition failed!" +msgstr "Ðе удалоÑÑŒ разрешить [%s], добавление в таблицу маршрутизации не выполнено!" + +msgid "[%s] was successfully added to the routing table of interface [%s]!" +msgstr "[%s] уÑпешно добавлен в таблицу маршрутизации интерфейÑа [%s]!" + +msgid "Adding [%s] to the [%s] routing table failed! The reason is that the [%s] gateway cannot be found." +msgstr "Добавление [%s] в таблицу маршрутизации [%s] не выполнено! Причина: не найден шлюз [%s]." + +msgid "Global nodes are not enabled, skip [%s]." +msgstr "Глобальные Ñерверы не включены, [%s] пропуÑкаетÑÑ." + +msgid "Direct DNS: %s" +msgstr "ПрÑмой DNS: %s" + +msgid "Remote DNS: %s" +msgstr "ПрокÑи-DNS: %s" + +msgid "The program has started. Please stop it and then restart it!" +msgstr "Программа уже запущена. ПожалуйÑта, Ñначала оÑтановите её, затем перезапуÑтите!" + +msgid "Running complete!" +msgstr "Выполнение завершено!" + +msgid "Clearing and closing related programs and cache complete." +msgstr "ОчиÑтка и завершение ÑвÑзанных процеÑÑов и кÑша завершена." + +msgid "Incorrect index listing method (%s), execution terminated!" +msgstr "Ðеверный ÑпоÑоб перечиÑÐ»ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑов (%s), выполнение прервано!" + +msgid "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." +msgstr "Разбор правил Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ñ„Ð¸ÐºÐ° [%s]-[geoip:%s], добавление в %s завершено." + +msgid "Access Control:" +msgstr "Контроль доÑтупа:" + +msgid "Add node to the load balancer is directly connected to %s[%s]." +msgstr "Добавление Ñервера в баланÑировщик: прÑмое подключение к %s[%s] завершено." + +msgid "Add all %s nodes to %s[%s] direct connection complete." +msgstr "Добавление вÑех Ñерверов %s в %s[%s]: прÑмое подключение завершено." + +msgid "Starting to load %s firewall rules..." +msgstr "Ðачало загрузки правил фаервола %s..." + +msgid "local network segments (%s) direct connection: %s" +msgstr "Локальные подÑети (%s): прÑмое подключение: %s" + +msgid "Add ISP %s DNS to the whitelist: %s" +msgstr "Добавление DNS провайдера %s в белый ÑпиÑок: %s" + +msgid "[%s]" +msgstr "ã€%s】" + +msgid "[%s]," +msgstr "ã€%s】," + +msgid "Source iface [%s]," +msgstr "ИÑходÑщий Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ã€%s】," + +msgid "IP range [%s]," +msgstr "Диапазон IP ã€%s】," + +msgid "All device," +msgstr "Ð’Ñе уÑтройÑтва," + +msgid "Does not exist, ignore." +msgstr "Ðе ÑущеÑтвует, пропущено." + +msgid "not proxy %s port [%s]" +msgstr "не прокÑи %s порт [%s]" + +msgid "not proxy all %s" +msgstr "не прокÑи вÑе %s" + +msgid "Use the %s node [%s]" +msgstr "ИÑпользовать %s Ñервер [%s]" + +msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server." +msgstr "ИÑпользуетÑÑ Ñервер, отличный от глобальной наÑтройки: DNS принудительно перенаправлен на выделенный DNS-Ñервер." + +msgid "Add direct DNS to %s: %s" +msgstr "Добавление прÑмого DNS в %s: %s" + +msgid "Local" +msgstr "Локально" + +msgid "[Local]," +msgstr "ã€Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾ã€‘," + +msgid "Clear %s." +msgstr "ОчиÑтка %s." + +msgid "Delete %s rules is complete." +msgstr "Удаление правил %s завершено." + +msgid "%s firewall rules load complete!" +msgstr "Загрузка правил фаервола %s завершена!" + +msgid "Socks switch detection: Unknown error." +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°." + +msgid "Socks switch detection: Unable to connect to the network. Please check if the network is working properly!" +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: не удалоÑÑŒ подключитьÑÑ Ðº Ñети. ПожалуйÑта, проверьте работоÑпоÑобноÑть Ñети!" + +msgid "Socks switch detection: Primary node ã€%s: [%s]】 is normal. Switch to the primary node!" +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: оÑновной Ñервер ã€%s: [%s]】 работает нормально. Переключение на оÑновной Ñервер!" + +msgid "Socks switch detection: %s node switch complete!" +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: переключение Ñервера %s завершено!" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal." +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: %s ã€%s:[%s]】 работает нормально." + +msgid "switch to %s test detect!" +msgstr "Переключение на %s Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸!" + +msgid "backup node" +msgstr "резервный Ñервер" + +msgid "next backup node" +msgstr "Ñледующий резервный Ñервер" + +msgid "main node" +msgstr "оÑновной Ñервер" + +msgid "Socks switch detection: %s ã€%s:[%s]】 abnormal, %s" +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: %s ã€%s:[%s]】 не работает, %s" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal, switch to this node!" +msgstr "Проверка Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SOCKS: %s ã€%s:[%s]】 работает нормально, переключение на Ñтот Ñервер!" + +msgid "Restart dnsmasq service." +msgstr "ПерезапуÑк Ñлужбы dnsmasq." + +msgid "Console Port: %s" +msgstr "Порт конÑоли: %s" + +msgid "Discard one obviously invalid node." +msgstr "Отброшен 1 Ñвно некорректный Ñервер." + +msgid "Entrance %s:%s" +msgstr "Вход %s:%s" + +msgid "Node: %s:%s, Weight: %s" +msgstr "Сервер: %s:%s, веÑ: %s" + +msgid "[Rule update] instance is running; please try again later." +msgstr "ЭкземплÑÑ€ [Обновление правила] запущен; пожалуйÑта, попробуйте позже." + +msgid "[Subscription] instance is running; [Rule Update] queue and wait." +msgstr "ЭкземплÑÑ€ [ПодпиÑка] запущен; [Обновление правила] поÑтавить в очередь и ждать." + +msgid "Start updating the rules..." +msgstr "Ðачало Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»..." + +msgid "Download file size verification error. Original file size: %sB. Downloaded file size: %sB." +msgstr "Ошибка проверки размера файла. ИÑходный размер: %sB, загруженный: %sB." + +msgid "Downloaded file is empty or an error occurred while reading it." +msgstr "Загруженный файл пуÑÑ‚ или произошла ошибка при чтении." + +msgid "%s Start updating..." +msgstr "%s начало обновлениÑ..." + +msgid "%s version is the same and does not need to be updated." +msgstr "ВерÑÐ¸Ñ %s Ñовпадает, обновление не требуетÑÑ." + +msgid "%s an error occurred during the file download process. Please try downloading again." +msgstr "%s ошибка при загрузке файла. ПожалуйÑта, попробуйте ещё раз." + +msgid "%s an error occurred while downloading the file. Please check your network or the download link and try again!" +msgstr "%s ошибка при загрузке файла. ПожалуйÑта, проверьте Ñеть или ÑÑылку и повторите попытку!" + +msgid "%s update success." +msgstr "%s обновлён уÑпешно." + +msgid "%s update failed, please try again later or change URL." +msgstr "%s обновление не удалоÑÑŒ, попробуйте позже или измените URL." + +msgid "%s update error!" +msgstr "%s ошибка обновлениÑ!" + +msgid "Restart the service and apply the new rules." +msgstr "ПерезапуÑк Ñлужбы Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ñ‹Ñ… правил." + +msgid "The rules have been updated..." +msgstr "Правила обновлены..." + +msgid "Socks node list [%s]" +msgstr "СпиÑок SOCKS-Ñерверов [%s]" + +msgid "Backup node list" +msgstr "СпиÑок резервных Ñерверов" + +msgid "HAProxy node list [%s]" +msgstr "СпиÑок Ñерверов HAProxy [%s]" + +msgid "ACL list [%s]" +msgstr "СпиÑок ACL [%s]" + +msgid "Shunt [%s] node" +msgstr "Сервер Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ [%s]" + +msgid "Xray Load Balancing node [%s] list" +msgstr "СпиÑок Ñерверов баланÑировки Xray [%s]" + +msgid "Xray Load Balancing node [%s] backup node" +msgstr "Резервный Ñервер баланÑировки Xray [%s]" + +msgid "Sing-Box URLTest node [%s] list" +msgstr "СпиÑок Ñерверов Sing-Box URLTest [%s]" + +msgid "Node [%s] preproxy node" +msgstr "Сервер [%s]: звено цепочки" + +msgid "Node [%s] landing node" +msgstr "Сервер [%s]: финальное звено" + +msgid "Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings." +msgstr "ПропуÑк Ñервера %s: неÑовмеÑтимоÑть Ñ Ñдром %s или неверно задан тип иÑпользованиÑ." + +msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." +msgstr "ПропуÑк Ñервера: %s. Sing-Box не поддерживает метод передачи %s протокола %s, необходимо иÑпользовать Xray." + +msgid "Xray unsupport %s plugin." +msgstr "Xray не поддерживает плагин %s." + +msgid "Plugin options Incomplete." +msgstr "Опции плагина указаны не полноÑтью." + +msgid "Please replace %s to support %s transmission method." +msgstr "ПожалуйÑта, замените %s, чтобы поддержать метод передачи %s." + +msgid "Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks." +msgstr "ПожалуйÑта, иÑпользуйте Xray или Sing-Box Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ дополнительных методов передачи в Shadowsocks." + +msgid "unsupport %s plugin." +msgstr "не поддерживает плагин %s." + +msgid "Skip the %s node because the %s core program is not installed." +msgstr "ПропуÑк Ñервера %s: не уÑтановлено Ñдро %s." + +msgid "Skip the %s node, as %s type nodes require Sing-Box version 1.12 or higher." +msgstr "ПропуÑк Ñервера %s: Ñерверы типа %s требуют Sing-Box верÑии 1.12 или выше." + +msgid "%s type node subscriptions are not currently supported, skip this node." +msgstr "ПодпиÑки на Ñерверы типа %s пока не поддерживаютÑÑ, Ñтот Ñервер пропуÑкаетÑÑ." + +msgid "Update [%s]" +msgstr "Обновление [%s]" + +msgid "Matching node:" +msgstr "Ðайденный Ñервер:" + +msgid "First Matching node:" +msgstr "Первый подходÑщий Ñервер:" + +msgid "Second Matching node:" +msgstr "Второй подходÑщий Ñервер:" + +msgid "Third Matching node:" +msgstr "Третий подходÑщий Ñервер:" + +msgid "Fourth Matching node:" +msgstr "Четвёртый подходÑщий Ñервер:" + +msgid "Fifth Matching node:" +msgstr "ПÑтый подходÑщий Ñервер:" + +msgid "Unable to find the best matching node, now replaced with:" +msgstr "Ðе удалоÑÑŒ найти наилучший Ñервер, Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ð·Ð°Ð¼ÐµÐ½Ð°:" + +msgid "Unable to find a new node. Please confirm and process manually." +msgstr "Ðе удалоÑÑŒ найти новый Ñервер. ПожалуйÑта, проверьте и обработайте вручную." + +msgid "No node information updates are available." +msgstr "Ðет доÑтупных обновлений информации о Ñерверах." + +msgid "Skip unknown types:" +msgstr "ПропуÑк неизвеÑтных типов:" + +msgid "Discard node: %s, Reason:" +msgstr "Отброшен узел: %s, причина:" + +msgid "No usable binary was found." +msgstr "Ðе найдено пригодного иÑполнÑемого файла." + +msgid "Discard filter nodes: %s type node %s" +msgstr "Отброшены узлы фильтра: тип %s, Ñервер %s" + +msgid "Parsing error, skip this node." +msgstr "Ошибка разбора, Ñтот Ñервер пропуÑкаетÑÑ." + +msgid "Successfully resolved the [%s] node, number: %s" +msgstr "УÑпешно разобран [%s], количеÑтво узлов: %s" + +msgid "Get subscription content for [%s] is empty. This may be due to an invalid subscription address or a network problem. Please diagnose the issue!" +msgstr "Содержимое подпиÑки [%s] пуÑто. Возможно, Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки неверен или еÑть проблема Ñ Ñетью. ПожалуйÑта, проведите диагноÑтику!" + +msgid "Proxy" +msgstr "ПрокÑи" + +msgid "[Subscription] instance is running; please try again later." +msgstr "ЭкземплÑÑ€ [ПодпиÑки] запущен; пожалуйÑта, попробуйте позже." + +msgid "[Rule Update] instance is running; [Subscription] queue and wait." +msgstr "ЭкземплÑÑ€ [Обновление правила] запущен; [ПодпиÑка] ÑтавитÑÑ Ð² очередь и ожидает." + +msgid "Start subscribing..." +msgstr "Ðачало подпиÑки..." + +msgid "Start subscribing: %s" +msgstr "Ðачало подпиÑки: %s" + +msgid "Subscription: [%s] No changes, no update required." +msgstr "ПодпиÑка: [%s] изменений нет, обновление не требуетÑÑ." + +msgid "[%s] Subscription failed. This could be due to an invalid subscription address or a network issue. Please diagnose the problem! [%s]" +msgstr "[%s] Ошибка подпиÑки. Возможно, Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки неверен или еÑть проблема Ñ Ñетью. ПожалуйÑта, проведите диагноÑтику! [%s]" + +msgid "Error, restoring service." +msgstr "Ошибка, выполнÑетÑÑ Ð²Ð¾ÑÑтановление Ñлужбы." + +msgid "Subscription complete..." +msgstr "ПодпиÑка завершена..." + +msgid "Processing, please wait…" +msgstr "Обработка, пожалуйÑта, подождите…" diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po new file mode 100644 index 00000000..1010101b --- /dev/null +++ b/luci-app-passwall2/po/zh-cn/passwall2.po @@ -0,0 +1,2373 @@ +msgid "Auto" +msgstr "自动" + +msgid "RUNNING" +msgstr "è¿è¡Œä¸­" + +msgid "NOT RUNNING" +msgstr "未è¿è¡Œ" + +msgid "Working..." +msgstr "连接正常" + +msgid "Problem detected!" +msgstr "连接失败" + +msgid "Touch Check" +msgstr "点我检测" + +msgid "Global" +msgstr "全局" + +msgid "Kernel Unsupported" +msgstr "å†…æ ¸ä¸æ”¯æŒ" + +msgid "Basic Settings" +msgstr "基本设置" + +msgid "Node List" +msgstr "节点列表" + +msgid "Other Settings" +msgstr "高级设置" + +msgid "Load Balancing" +msgstr "è´Ÿè½½å‡è¡¡" + +msgid "Enter interface" +msgstr "进入界é¢" + +msgid "Rule Manage" +msgstr "规则管ç†" + +msgid "Rule List" +msgstr "规则列表" + +msgid "Access control" +msgstr "访问控制" + +msgid "Runtime Logs" +msgstr "è¿è¡Œæ—¥å¿—" + +msgid "Node Config" +msgstr "节点é…ç½®" + +msgid "Running Status" +msgstr "è¿è¡Œçжæ€" + +msgid "Baidu Connection" +msgstr "百度连接" + +msgid "Google Connection" +msgstr "谷歌连接" + +msgid "GitHub Connection" +msgstr "GitHub连接" + +msgid "Instagram Connection" +msgstr "Instagram连接" + +msgid "Node Check" +msgstr "节点检测" + +msgid "Check..." +msgstr "检测中..." + +msgid "Clear" +msgstr "清除" + +msgid "Main switch" +msgstr "主开关" + +msgid "Node" +msgstr "节点" + +msgid "Edit Current Node" +msgstr "编辑当å‰èŠ‚ç‚¹" + +msgid "Localhost Proxy" +msgstr "路由器本机代ç†" + +msgid "When selected, localhost can transparent proxy." +msgstr "当勾选时,路由器本机å¯ä»¥é€æ˜Žä»£ç†ã€‚" + +msgid "Client Proxy" +msgstr "客户端代ç†" + +msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy." +msgstr "当勾选时,局域网内的设备å¯ä»¥é€æ˜Žä»£ç†ã€‚å¦åˆ™ï¼Œå°†ä¸ä»£ç†ã€‚但您ä»ç„¶å¯ä»¥ä½¿ç”¨è®¿é—®æŽ§åˆ¶å…许指定的设备代ç†ã€‚" + +msgid "Missing components, transparent proxy is unavailable." +msgstr "ç¼ºå°‘ç»„ä»¶ï¼Œé€æ˜Žä»£ç†ä¸å¯ç”¨ã€‚" + +msgid "Socks Config" +msgstr "Socks é…ç½®" + +msgid "Socks Node" +msgstr "Socks 节点" + +msgid "Current Node" +msgstr "当å‰èŠ‚ç‚¹" + +msgid "Listen Port" +msgstr "监å¬ç«¯å£" + +msgid "0 is not use" +msgstr "0为ä¸ä½¿ç”¨" + +msgid "Current node: %s" +msgstr "当å‰èŠ‚ç‚¹ï¼š%s" + +msgid "Direct domain DNS routing" +msgstr "直连域å DNS 分æµ" + +msgid "Please note that the program will not start if the format is incorrect!" +msgstr "请注æ„,格å¼ä¸æ­£ç¡®å°†æ— æ³•å¯åЍï¼" + +msgid "IP:Port mode acceptable, multi value split with english comma." +msgstr "æŽ¥å— IP:Port å½¢å¼çš„输入,多个以英文逗å·åˆ†éš”。" + +msgid "Direct DNS Protocol" +msgstr "直连 DNS åè®®" + +msgid "Direct DNS" +msgstr "直连 DNS" + +msgid "Direct DNS DoH" +msgstr "直连 DNS DoH" + +msgid "Direct DNS EDNS Client Subnet" +msgstr "直连 DNS EDNS Client Subnet" + +msgid "Remote DNS Protocol" +msgstr "远程 DNS åè®®" + +msgid "Remote DNS" +msgstr "远程 DNS" + +msgid "Remote DNS DoH" +msgstr "远程 DNS DoH" + +msgid "Remote DNS EDNS Client Subnet" +msgstr "远程 DNS EDNS Client Subnet" + +msgid "Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address)." +msgstr "用于 DNS 查询时通知 DNS æœåŠ¡å™¨ï¼Œå®¢æˆ·ç«¯æ‰€åœ¨çš„åœ°ç†ä½ç½®ï¼ˆä¸èƒ½æ˜¯ç§æœ‰ IP 地å€ï¼‰ã€‚" + +msgid "This feature requires the DNS server to support the Edns Client Subnet (RFC7871)." +msgstr "æ­¤åŠŸèƒ½éœ€è¦ DNS æœåŠ¡å™¨æ”¯æŒ EDNS Client Subnet(RFC7871)。" + +msgid "Remote DNS Outbound" +msgstr "远程 DNS 出站" + +msgid "Remote" +msgstr "远程" + +msgid "Direct" +msgstr "直连" + +msgid "Direct Query Strategy" +msgstr "直连查询策略" + +msgid "Remote Query Strategy" +msgstr "远程查询策略" + +msgid "Use FakeDNS work in the domain that proxy." +msgstr "需è¦ä»£ç†çš„域å使用 FakeDNS。" + +msgid "Suitable scenarios for let the node servers get the target domain names." +msgstr "适åˆè®©èŠ‚ç‚¹æœåŠ¡å™¨èŽ·å–目标域å的场景。" + +msgid "Such as: DNS unlocking of streaming media, reducing DNS query latency, etc." +msgstr "例如:æµåª’体的 DNS è§£é”ã€å‡å°‘ DNS 查询延迟等。" + +msgid "Domain Override" +msgstr "域åé‡å†™" + +msgid "Direct DNS result write to IPSet" +msgstr "直连 DNS è§£æžç»“果写入到 IPSet" + +msgid "Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core)." +msgstr "将匹é…到的直连规则的域åè§£æžIP写入到 IPSet/NFTSet,然åŽç›´è¿žï¼ˆä¸è¿›å…¥å†…核)。" + +msgid "Maybe conflict with some special circumstances." +msgstr "å¯èƒ½å’ŒæŸäº›ç‰¹æ®Šæƒ…况冲çªã€‚" + +msgid "DNS Redirect" +msgstr "DNS é‡å®šå‘" + +msgid "Force special DNS server to need proxy devices." +msgstr "强制需è¦ä»£ç†çš„设备使用专用 DNS æœåŠ¡å™¨ã€‚" + +msgid "Clear IPSET" +msgstr "清空 IPSET" + +msgid "Clear NFTSET" +msgstr "清空 NFTSET" + +msgid "Try this feature if the rule modification does not take effect." +msgstr "å¦‚æžœä¿®æ”¹è§„åˆ™åŽæ²¡æœ‰ç”Ÿæ•ˆï¼Œè¯·å°è¯•此功能。" + +msgid "About DNS issues:" +msgstr "关于DNS问题:" + +msgid "Some browsers may have built-in DNS, be sure to close. Example: Chrome. Settings - Security and Privacy - Security - Use secure DNS disabled." +msgstr "部分æµè§ˆå™¨å¯èƒ½æœ‰å†…置的DNS,请务必关闭。如:chrome。 设置 - 安全和éšç§è®¾ç½® - 使用安全 DNS 关闭。" + +msgid "Sometimes after restart, you can not internet. At this time, close all browsers (important), Windows Client, please `ipconfig /flushdns`. Please close the WiFi on the phone, cut the flight mode and then cut back." +msgstr "有时候é‡å¯åŽï¼Œä¸Šä¸äº†ã€‚这时请先关闭所有æµè§ˆå™¨ï¼ˆé‡è¦ï¼‰ï¼ŒWindows客户端请`ipconfig /flushdns`。手机端请关闭WIFI,切一下飞行模å¼å†åˆ‡å›žæ¥ã€‚" + +msgid "The client DNS and the default gateway must point to this router." +msgstr "客户端DNSå’Œé»˜è®¤ç½‘å…³å¿…é¡»æŒ‡å‘æœ¬è·¯ç”±å™¨ã€‚" + +msgid "If you have a wrong DNS process, the consequences are at your own risk!" +msgstr "如果你自行é…置了错误的DNSæµç¨‹ï¼ŒåŽæžœè‡ªè´Ÿï¼" + +msgid "Hide menu method, input example in the address bar:" +msgstr "éšè—èœå•æ–¹æ³•ï¼Œåœ°å€æ è¾“入例:" + +msgid "After the hidden to the display, input example in the address bar:" +msgstr "当你éšè—åŽæƒ³å†æ¬¡æ˜¾ç¤ºï¼Œåœ°å€æ è¾“入例:" + +msgid "Are you sure to hide?" +msgstr "你确定è¦éšè—å—?" + +msgid "DNS related issues:" +msgstr "DNS相关问题:" + +msgid "Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off." +msgstr "æŸäº›æµè§ˆå™¨å¦‚Chrome等内置此功能,这会影å“设置的DNSè§£æžã€‚您å¯ä»¥è¿›å…¥ '设置->ç§éšå’Œå®‰å…¨->使用安全DNS' èœå•,将其关闭。" + +msgid "If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):" +msgstr "如果在é‡å¯åŽæ— æ³•上网,请å°è¯•清除终端设备的缓存(先关闭所有正在使用的æµè§ˆå™¨åº”用程åºï¼Œè¿™ä¸€æ­¥å°¤å…¶é‡è¦ï¼‰ï¼š" + +msgid "For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'." +msgstr "对于Windows系统,请在命令æç¤ºç¬¦ä¸­è¿è¡Œå‘½ä»¤ 'ipconfig /flushdns'." + +msgid "For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'." +msgstr "对于Mac系统,在终端中è¿è¡Œå‘½ä»¤ 'sudo killall -HUP mDNSResponder'." + +msgid "For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi." +msgstr "对于移动设备,å¯é€šè¿‡é‡æ–°æŽ¥å…¥ç½‘ç»œçš„æ–¹å¼æ¸…除。比如开关一次飞行模å¼,釿–°è¿žæŽ¥WiFi。" + +msgid "Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed." +msgstr "请确认您设备的网络设置,客户端DNSæœåŠ¡å™¨å’Œé»˜è®¤ç½‘å…³åº”å‡æŒ‡å‘本路由器,以确ä¿DNS查询正确路由。" + +msgid "Browser access:" +msgstr "æµè§ˆå™¨è®¿é—®ï¼š" + +msgid "Hide in main menu:" +msgstr "在主èœå•中éšè—:" + +msgid "Show in main menu:" +msgstr "在主èœå•中显示:" + +msgid "DNS Export Of Multi WAN" +msgstr "国内DNS指定解æžå‡ºå£" + +msgid "Node Export Of Multi WAN" +msgstr "节点指定出å£" + +msgid "Only support Multi Wan." +msgstr "åªæœ‰å¤šçº¿æŽ¥å…¥æ‰æœ‰æ•ˆã€‚" + +msgid "Not Specify" +msgstr "䏿Œ‡å®š" + +msgid "custom" +msgstr "自定义" + +msgid "If not available, try clearing the cache." +msgstr "如果无法使用,请å°è¯•清除缓存。" + +msgid "Operation" +msgstr "æ“作" + +msgid "Add Node" +msgstr "添加节点" + +msgid "Add the node via the link" +msgstr "通过链接添加节点" + +msgid "Enter share links, one per line. Subscription links are not supported!" +msgstr "输入分享链接,支æŒå¤šä¸ªèŠ‚ç‚¹ï¼Œæ¯è¡Œä¸€ä¸ªã€‚请勿输入订阅链接ï¼" + +msgid "Please enter the correct link." +msgstr "请输入正确的链接。" + +msgid "Clear all nodes" +msgstr "清空所有节点" + +msgid "Are you sure to clear all nodes?" +msgstr "ä½ ç¡®å®šè¦æ¸…空所有节点å—?" + +msgid "Success" +msgstr "æˆåŠŸ" + +msgid "Error" +msgstr "错误" + +msgid "Delete select nodes" +msgstr "删除选择的节点" + +msgid "To Top" +msgstr "置顶" + +msgid "Select" +msgstr "选择" + +msgid "Selected:" +msgstr "已选:" + +msgid "DeSelect" +msgstr "å选" + +msgid "Select all" +msgstr "全选" + +msgid "DeSelect all" +msgstr "å…¨ä¸é€‰" + +msgid "Are you sure to delete select nodes?" +msgstr "你确定è¦åˆ é™¤é€‰æ‹©çš„节点å—?" + +msgid "You no select nodes !" +msgstr "你没有选择任何节点ï¼" + +msgid "Are you sure set to" +msgstr "你确定è¦è®¾ä¸º" + +msgid "the server?" +msgstr "æœåС噍å—?" + +msgid "You choose node is:" +msgstr "你选择的节点是:" + +msgid "Timeout" +msgstr "è¶…æ—¶" + +msgid "Node Remarks" +msgstr "节点备注" + +msgid "Add Mode" +msgstr "添加方å¼" + +msgid "Save Order" +msgstr "ä¿å­˜å½“å‰é¡ºåº" + +msgid "Saved current page order successfully." +msgstr "ä¿å­˜å½“å‰é¡µé¢é¡ºåºæˆåŠŸã€‚" + +msgid "Drag to reorder" +msgstr "æ‹–åŠ¨ä»¥é‡æŽ’" + +msgid "Type" +msgstr "类型" + +msgid "_balancing" +msgstr "è´Ÿè½½å‡è¡¡" + +msgid "_shunt" +msgstr "分æµ" + +msgid "Balancing" +msgstr "è´Ÿè½½å‡è¡¡" + +msgid "Node Addition Method" +msgstr "节点添加方å¼" + +msgid "Manual" +msgstr "手动" + +msgid "Batch" +msgstr "批é‡" + +msgid "Select Group" +msgstr "选择分组" + +msgid "Node Matching Rules" +msgstr "节点匹é…规则" + +msgid "" +"Example: ^A && B && !C && D$
" +"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" +"Conditions are joined by &&, and their order does not affect the result." +msgstr "" +"示例:^A && B && !C && D$
" +"è¡¨ç¤ºèŠ‚ç‚¹å¤‡æ³¨éœ€åŒæ—¶æ»¡è¶³ï¼šä»¥ A 开头(^)ã€åŒ…å« Bã€ä¸åŒ…å« C(!)ã€å¹¶ä»¥ D 结尾($)。
" +"多个æ¡ä»¶ä½¿ç”¨ && 连接,æ¡ä»¶é¡ºåºä¸å½±å“结果。" + +msgid "Balancing Strategy" +msgstr "è´Ÿè½½å‡è¡¡ç­–ç•¥" + +msgid "Fallback Node" +msgstr "åŽå¤‡èŠ‚ç‚¹" + +msgid "Use Custom Probe URL" +msgstr "使用自定义探测网å€" + +msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL." +msgstr "默认使用内置的探测网å€ï¼Œå¯ç”¨æ­¤é€‰é¡¹ä»¥ä½¿ç”¨è‡ªå®šä¹‰æŽ¢æµ‹ç½‘å€ã€‚" + +msgid "Probe URL" +msgstr "探测网å€" + +msgid "The URL used to detect the connection status." +msgstr "用于检测连接状æ€çš„网å€ã€‚" + +msgid "Probe Interval" +msgstr "探测间隔" + +msgid "The interval between initiating probes." +msgstr "å‘起探测的间隔。" + +msgid "The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively." +msgstr "æ—¶é—´æ ¼å¼ä¸ºæ•°å­—+å•ä½ï¼Œæ¯”如"10s", "2h45m",支æŒçš„æ—¶é—´å•使œ‰ s,m,h,分别对应秒ã€åˆ†ã€æ—¶ã€‚" + +msgid "When the unit is not filled in, it defaults to seconds." +msgstr "未填写å•使—¶ï¼Œé»˜è®¤ä¸ºç§’。" + +msgid "Preferred Node Count" +msgstr "优选节点数é‡" + +msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them." +msgstr "è´Ÿè½½å‡è¡¡å™¨é€‰å‡ºæœ€ä¼˜èŠ‚ç‚¹çš„ä¸ªæ•°ï¼Œæµé‡å°†åœ¨è¿™å‡ ä¸ªèŠ‚ç‚¹ä¸­éšæœºåˆ†é…。" + +msgid "Failure Tolerance (%)" +msgstr "测速失败率容å¿åº¦ï¼ˆ%)" + +msgid "The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate." +msgstr "æœ€å¤šå¯æŽ¥å—的测速失败率,例如 1 表示å…许 1% 的测速失败率。" + +msgid "Shunt" +msgstr "分æµ" + +msgid "Preproxy" +msgstr "å‰ç½®ä»£ç†" + +msgid "Preproxy Node" +msgstr "å‰ç½®ä»£ç†èŠ‚ç‚¹" + +msgid "Set the node to be used as a pre-proxy." +msgstr "设置用作å‰ç½®ä»£ç†çš„节点。" + +msgid "Each rule has a separate switch that controls whether this rule uses the pre-proxy or not." +msgstr "æ¯æ¡è§„则都有独立开关控制本规则是å¦ä½¿ç”¨å‰ç½®ä»£ç†ã€‚" + +msgid "Close (Not use)" +msgstr "关闭 (ä¸ä½¿ç”¨)" + +msgid "Use default node" +msgstr "使用默认节点" + +msgid "Direct Connection" +msgstr "直连" + +msgid "Blackhole (Block)" +msgstr "黑洞(å±è”½ï¼‰" + +msgid "There are no available nodes, please add or subscribe nodes first." +msgstr "没有å¯ç”¨èŠ‚ç‚¹ï¼Œè¯·å…ˆæ·»åŠ æˆ–è®¢é˜…èŠ‚ç‚¹ã€‚" + +msgid "No shunt rules? Click me to go to add." +msgstr "没有分æµè§„则?点我å‰å¾€åŽ»æ·»åŠ ã€‚" + +msgid "When using, localhost will connect this node first and then use this node to connect the default node." +msgstr "当使用时,本机将首先连接到此节点,然åŽå†ä½¿ç”¨æ­¤èŠ‚ç‚¹è¿žæŽ¥åˆ°é»˜è®¤èŠ‚ç‚¹è½åœ°ã€‚" + +msgid "Domain Strategy" +msgstr "域åè§£æžç­–ç•¥" + +msgid "Domain matcher" +msgstr "域å匹é…算法" + +msgid "'AsIs': Only use domain for routing. Default value." +msgstr "AsIs:åªä½¿ç”¨åŸŸå进行路由选择。默认值。" + +msgid "'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again." +msgstr "IPIfNonMatchï¼šå½“åŸŸåæ²¡æœ‰åŒ¹é…任何规则时,将域åè§£æžæˆ IP(A 记录或 AAAA è®°å½•ï¼‰å†æ¬¡è¿›è¡ŒåŒ¹é…。" + +msgid "'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately." +msgstr "IPOnDemandï¼šå½“åŒ¹é…æ—¶ç¢°åˆ°ä»»ä½•基于 IP 的规则,将域åç«‹å³è§£æžä¸º IP 进行匹é…。" + +msgid "Load balancing node list" +msgstr "è´Ÿè½½å‡è¡¡èŠ‚ç‚¹åˆ—è¡¨" + +msgid "Load balancing node list, document" +msgstr "è´Ÿè½½å‡è¡¡èŠ‚ç‚¹åˆ—è¡¨ï¼Œæ–‡æ¡£åŽŸç†" + +msgid "From Share URL" +msgstr "导入分享URL" + +msgid "Build Share URL" +msgstr "导出分享URL" + +msgid "Generate QRCode" +msgstr "生æˆäºŒç»´ç " + +msgid "Export Config File" +msgstr "导出é…置文件" + +msgid "Import Finished" +msgstr "导入完æˆï¼š" + +msgid "Not a supported scheme:" +msgstr "䏿”¯æŒè¿™ç§æ ·å¼çš„:" + +msgid "Invalid Share URL Format" +msgstr "无效的分享URLä¿¡æ¯" + +msgid "Paste Share URL Here" +msgstr "在此处粘贴分享信æ¯" + +msgid "Share URL to clipboard unable." +msgstr "无法分享URL到剪贴æ¿ã€‚" + +msgid "Share URL to clipboard successfully." +msgstr "æˆåŠŸå¤åˆ¶åˆ†äº«URL到剪贴æ¿ã€‚" + +msgid "Faltal on get option, please help in debug:" +msgstr "代ç é”™è¯¯ï¼Œè¯·å助æ‰è™«ï¼š" + +msgid "Faltal on set option, please help in debug:" +msgstr "代ç é”™è¯¯ï¼Œè¯·å助æ‰è™«ï¼š" + +msgid "Address" +msgstr "地å€" + +msgid "Address (Support Domain Name)" +msgstr "地å€ï¼ˆæ”¯æŒåŸŸå)" + +msgid "Trojan Verify Cert" +msgstr "验è¯è¯ä¹¦" + +msgid "Trojan Cert Path" +msgstr "è¯ä¹¦è·¯å¾„" + +msgid "Finger Print" +msgstr "指纹伪造" + +msgid "Avoid using randomized, unless you have to." +msgstr "é¿å…使用 randomized , 除éžä½ å¿…é¡»è¦ã€‚" + +msgid "Original" +msgstr "原版" + +msgid "Transport Plugin" +msgstr "传输层æ’ä»¶" + +msgid "Obfs Type" +msgstr "混淆类型" + +msgid "Obfs Password" +msgstr "混淆密ç " + +msgid "Auth Type" +msgstr "认è¯ç±»åž‹" + +msgid "Auth Password" +msgstr "认è¯å¯†ç " + +msgid "Client BBR Flow Control" +msgstr "客户端 BBR æµæŽ§" + +msgid "Commands the client to use the BBR flow control algorithm" +msgstr "命令客户端使用 BBR æµé‡æŽ§åˆ¶ç®—法" + +msgid "PinSHA256" +msgstr "PinSHA256" + +msgid "Certificate fingerprint" +msgstr "è¯ä¹¦æŒ‡çº¹" + +msgid "Max upload Mbps" +msgstr "最大上行(Mbps)" + +msgid "Max download Mbps" +msgstr "最大下行(Mbps)" + +msgid "QUIC stream receive window" +msgstr "QUIC æµæŽ¥æ”¶çª—å£" + +msgid "QUIC connection receive window" +msgstr "QUIC 连接接收窗å£" + +msgid "QUIC concurrent bidirectional streams" +msgstr "QUIC å¹¶å‘åŒå‘æµçš„æœ€å¤§æ•°é‡" + +msgid "QUIC KeepAlive interval" +msgstr "QUIC KeepAlive é—´éš”" + +msgid "Disable MTU detection" +msgstr "ç¦ç”¨ MTU 检测" + +msgid "ignoreClientBandwidth" +msgstr "忽略客户端带宽设置" + +msgid "Lazy Start" +msgstr "延迟å¯åЍ" + +msgid "Encrypt Method" +msgstr "加密方å¼" + +msgid "Encrypt Key" +msgstr "加密密钥" + +msgid "Latency" +msgstr "延迟" + +msgid "Automatic detection delay" +msgstr "自动检测延迟" + +msgid "Show server address and port" +msgstr "显示æœåŠ¡å™¨åœ°å€å’Œç«¯å£" + +msgid "URL Test Address" +msgstr "URL 测试地å€" + +msgid "URL Test" +msgstr "URL 测试" + +msgid "Test" +msgstr "测试" + +msgid "Node num" +msgstr "节点数é‡" + +msgid "Self add" +msgstr "自添" + +msgid "Apply" +msgstr "应用" + +msgid "Use" +msgstr "使用" + +msgid "Copy" +msgstr "å¤åˆ¶" + +msgid "Delay Settings" +msgstr "定时é…ç½®" + +msgid "Open and close Daemon" +msgstr "å¯åŠ¨å®ˆæŠ¤è¿›ç¨‹" + +msgid "Delay Start" +msgstr "开机时延时å¯åЍ" + +msgid "Units:seconds" +msgstr "å•ä½ï¼šç§’" + +msgid "Units:minutes" +msgstr "å•ä½ï¼šåˆ†é’Ÿ" + +msgid "stop automatically mode" +msgstr "定时关闭模å¼" + +msgid "stop Time(Every day)" +msgstr "关闭时间(æ¯å¤©)" + +msgid "stop Interval(Hour)" +msgstr "关闭间隔(å°æ—¶)" + +msgid "start automatically mode" +msgstr "å®šæ—¶å¼€å¯æ¨¡å¼" + +msgid "start Time(Every day)" +msgstr "开坿—¶é—´(æ¯å¤©)" + +msgid "start Interval(Hour)" +msgstr "å¼€å¯é—´éš”(å°æ—¶)" + +msgid "restart automatically mode" +msgstr "定时é‡å¯æ¨¡å¼" + +msgid "restart Time(Every day)" +msgstr "é‡å¯æ—¶é—´(æ¯å¤©)" + +msgid "restart Interval(Hour)" +msgstr "é‡å¯é—´éš”(å°æ—¶)" + +msgid "Forwarding Settings" +msgstr "转å‘é…ç½®" + +msgid "TCP No Redir Ports" +msgstr "TCPä¸è½¬å‘端å£" + +msgid "UDP No Redir Ports" +msgstr "UDPä¸è½¬å‘端å£" + +msgid "Fill in the ports you don't want to be forwarded by the agent, with the highest priority." +msgstr "填写你ä¸å¸Œæœ›è¢«ä»£ç†è½¬å‘的端å£ï¼Œä¼˜å…ˆçº§æœ€é«˜ã€‚" + +msgid "If you don't want to let the device in the list to go proxy, please choose all." +msgstr "å¦‚æžœæ‚¨ä¸æƒ³è®©åˆ—表中的设备走代ç†ï¼Œè¯·é€‰æ‹©å…¨éƒ¨ã€‚" + +msgid "The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000." +msgstr "以上端å£è®¾ç½®æ”¯æŒå•端å£å’Œç«¯å£èŒƒå›´ã€‚
多个端å£ç”¨è‹±æ–‡é€—å·(,)隔开。
例:21,80,443,1000:2000。" + +msgid "TCP Proxy Drop Ports" +msgstr "TCP转å‘å±è”½ç«¯å£" + +msgid "UDP Proxy Drop Ports" +msgstr "UDP转å‘å±è”½ç«¯å£" + +msgid "TCP Redir Ports" +msgstr "TCP转å‘端å£" + +msgid "UDP Redir Ports" +msgstr "UDP转å‘端å£" + +msgid "No patterns are used" +msgstr "ä¸ä½¿ç”¨" + +msgid "All" +msgstr "所有" + +msgid "Common Use" +msgstr "常用的" + +msgid "Only Web" +msgstr "仅网页" + +msgid "or more" +msgstr "åŠä»¥ä¸Š" + +msgid "or less" +msgstr "åŠä»¥ä¸‹" + +msgid "Default" +msgstr "默认" + +msgid "Close" +msgstr "关闭" + +msgid "Hijacking ICMP (PING)" +msgstr "劫æŒICMP (PING)" + +msgid "Hijacking ICMPv6 (IPv6 PING)" +msgstr "劫æŒICMPv6 (IPv6 PING)" + +msgid "Force Proxy LAN IP" +msgstr "强制代ç†å†…网IP段" + +msgid "By default, commonly used internal network IP ranges will be connect directly (not entering the core). If you want a certain network range to go through a proxy, please add it here." +msgstr "默认情况下,常用内网IP网段将直连(ä¸è¿›å…¥å†…核),如果你希望æŸä¸ªç½‘段走代ç†ï¼Œè¯·åœ¨æ­¤æ·»åŠ ã€‚" + +msgid "Sniffing" +msgstr "æµé‡å—…探" + +msgid "TCP Proxy Way" +msgstr "TCPä»£ç†æ–¹å¼" + +msgid "Auto Switch" +msgstr "自动切æ¢" + +msgid "When there is no server, an automatic reconnect scheme is used" +msgstr "当没有æœåŠ¡å™¨æ—¶ï¼Œåˆ™ä½¿ç”¨è‡ªåŠ¨é‡è¿žæ–¹æ¡ˆ" + +msgid "How often to test" +msgstr "多久检测一次" + +msgid "Timeout seconds" +msgstr "è¶…æ—¶ç§’æ•°" + +msgid "Timeout retry num" +msgstr "è¶…æ—¶é‡è¯•次数" + +msgid "Automatic switching cannot be used when this option is checked" +msgstr "当勾选此选项时,ä¸èƒ½ä½¿ç”¨è‡ªåŠ¨åˆ‡æ¢" + +msgid "Main node" +msgstr "主节点" + +msgid "List of backup nodes" +msgstr "备用节点的列表" + +msgid "Restore Switch" +msgstr "æ¢å¤åˆ‡æ¢" + +msgid "When detects main node is available, switch back to the main node." +msgstr "当检测到主节点å¯ç”¨æ—¶ï¼Œåˆ‡æ¢å›žä¸»èŠ‚ç‚¹ã€‚" + +msgid "Add nodes to the standby node list by keywords" +msgstr "通过关键字添加节点到备用节点列表" + +msgid "Delete nodes in the standby node list by keywords" +msgstr "通过关键字删除备用节点列表的节点" + +msgid "Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase." +msgstr "请输入节点关键字,注æ„区分空格ã€å¤§å†™å’Œå°å†™ã€‚" + +msgid "Enable Load Balancing" +msgstr "å¼€å¯è´Ÿè½½å‡è¡¡" + +msgid "Console Login Auth" +msgstr "控制å°ç™»å½•认è¯" + +msgid "Console Username" +msgstr "控制å°è´¦å·" + +msgid "Console Password" +msgstr "控制å°å¯†ç " + +msgid "Console Port" +msgstr "控制å°ç«¯å£" + +msgid "In the browser input routing IP plus port access, such as:192.168.1.1:1188" +msgstr "在æµè§ˆå™¨è¾“入路由IP加端å£è®¿é—®ï¼Œå¦‚:192.168.1.1:1188" + +msgid "Haproxy Port" +msgstr "è´Ÿè½½å‡è¡¡ç«¯å£" + +msgid "Health Check Type" +msgstr "å¥åº·æ£€æŸ¥ç±»åž‹" + +msgid "Inner implement" +msgstr "内置实现" + +msgid "Health Check Inter" +msgstr "å¥åº·æ£€æŸ¥èŠ‚ç‚¹é—´éš”æ—¶é—´" + +msgid "When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid." +msgstr "当使用URL测试时,负载å‡è¡¡èŠ‚ç‚¹å°†è½¬æ¢æˆSocks节点。下é¢çš„节点列表自定义时必须为Socks节点,å¦åˆ™å¥åº·æ£€æŸ¥å°†æ— æ•ˆã€‚" + +msgid "Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group." +msgstr "添加节点,指定出å£åŠŸèƒ½æ˜¯ä¸ºå¤šWAN用户准备的。负载比é‡èŒƒå›´1-256。多个主æœåС噍å¯ä»¥è´Ÿè½½å‡è¡¡ï¼Œå¤‡ç”¨åªæœ‰åœ¨ä¸»æœåŠ¡å™¨ç¦»çº¿æ—¶æ‰ä¼šå¯ç”¨ï¼å¯ä»¥è®¾ç½®å¤šä¸ªç»„,负载å‡è¡¡ç«¯å£ç›¸åŒåˆ™ä¸ºä¸€ç»„。" + +msgid "Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!" +msgstr "注æ„,当使用TCPå¥åº·æ£€æŸ¥æ—¶è´Ÿè½½å‡è¡¡çš„节点é…ç½®å‚æ•°å¿…须一致,å¦åˆ™æ— æ³•正常使用ï¼" + +msgid "Node Address" +msgstr "节点地å€" + +msgid "Node address cannot be empty." +msgstr "节点地å€ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Node Port" +msgstr "节点端å£" + +msgid "Node Weight" +msgstr "负载比é‡" + +msgid "Export Of Multi WAN" +msgstr "多WAN指定出å£" + +msgid "Main" +msgstr "主è¦" + +msgid "Mode" +msgstr "模å¼" + +msgid "Primary" +msgstr "主è¦" + +msgid "Standby" +msgstr "备用" + +msgid "Check update" +msgstr "检查更新" + +msgid "Force update" +msgstr "强制更新" + +msgid "The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install." +msgstr "最新版本:%sï¼Œç›®å‰æš‚䏿”¯æŒè‡ªåŠ¨æ›´æ–°ï¼Œå¦‚éœ€æ›´æ–°ï¼Œè¯·è‡ªè¡Œç¼–è¯‘æˆ–ä¸‹è½½ipkç„¶åŽæ‰‹åŠ¨å®‰è£…ã€‚" + +msgid "Enable custom URL" +msgstr "å¯ç”¨è‡ªå®šä¹‰è§„则地å€" + +msgid "Rule status" +msgstr "规则版本" + +msgid "Manually update" +msgstr "手动更新" + +msgid "Rollback" +msgstr "回滚" + +msgid "Rollbacking..." +msgstr "回滚中..." + +msgid "Enable auto update rules" +msgstr "å¼€å¯è‡ªåŠ¨æ›´æ–°è§„åˆ™" + +msgid "Update Time(every day)" +msgstr "æ›´æ–°æ—¶é—´(æ¯å¤©)" + +msgid "Update Interval(hour)" +msgstr "æ›´æ–°é—´éš”(å°æ—¶)" + +msgid "Update Mode" +msgstr "更新模å¼" + +msgid "Loop Mode" +msgstr "循环" + +msgid "Every day" +msgstr "æ¯å¤©" + +msgid "Every Monday" +msgstr "æ¯å‘¨ä¸€" + +msgid "Every Tuesday" +msgstr "æ¯å‘¨äºŒ" + +msgid "Every Wednesday" +msgstr "æ¯å‘¨ä¸‰" + +msgid "Every Thursday" +msgstr "æ¯å‘¨å››" + +msgid "Every Friday" +msgstr "æ¯å‘¨äº”" + +msgid "Every Saturday" +msgstr "æ¯å‘¨å…­" + +msgid "Every Sunday" +msgstr "æ¯å‘¨æ—¥" + +msgid "hour" +msgstr "å°æ—¶" + +msgid "Hour" +msgstr "å°æ—¶" + +msgid "GeoIP Update URL" +msgstr "GeoIP æ›´æ–° URL" + +msgid "Geosite Update URL" +msgstr "Geosite æ›´æ–° URL" + +msgid "Location of Geo rule files" +msgstr "Geo èµ„æºæ–‡ä»¶ç›®å½•" + +msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." +msgstr "æ­¤å˜é‡æŒ‡å®šgeoip.datå’Œgeosite.dat文件所在的目录。" + +msgid "Enable GeoIP Data Parsing" +msgstr "å¼€å¯ GeoIP æ•°æ®è§£æž" + +msgid "Analyzes and preloads GeoIP data to enhance the shunt performance." +msgstr "分æžå’Œé¢„加载 GeoIP æ•°æ®ï¼Œä»¥å¢žå¼ºåˆ†æµæ•ˆæžœã€‚" + +msgid "Note: Increases resource usage." +msgstr "注:会增加一些系统资æºçš„开销。" + +msgid "Shunt Rule" +msgstr "分æµè§„则" + +msgid "Please note attention to the priority, the higher the order, the higher the priority." +msgstr "请注æ„优先级问题,排åºè¶Šä¸Šé¢ä¼˜å…ˆçº§è¶Šé«˜ã€‚" + +msgid "Update..." +msgstr "更新中" + +msgid "It is the latest version" +msgstr "已是最新版本" + +msgid "Update successful" +msgstr "æ›´æ–°æˆåŠŸ" + +msgid "Click to update" +msgstr "点击更新" + +msgid "Updating..." +msgstr "更新中" + +msgid "Retry" +msgstr "é‡è¯•" + +msgid "Unexpected error" +msgstr "æ„外错误" + +msgid "Updating, are you sure to close?" +msgstr "正在更新,你确认è¦å…³é—­å—?" + +msgid "Downloading..." +msgstr "下载中" + +msgid "Unpacking..." +msgstr "解压中" + +msgid "Moving..." +msgstr "移动中" + +msgid "App Update" +msgstr "组件更新" + +msgid "Please confirm that your firmware supports FPU." +msgstr "请确认你的固件支æŒFPU。" + +msgid "if you want to run from memory, change the path, /tmp beginning then save the application and update it manually." +msgstr "如果你希望从内存中è¿è¡Œï¼Œè¯·æ›´æ”¹è·¯å¾„,/tmp 开头,然åŽä¿å­˜åº”用åŽï¼Œå†æ‰‹åŠ¨æ›´æ–°ã€‚" + +msgid "Make sure there is enough space to install %s" +msgstr "ç¡®ä¿æœ‰è¶³å¤Ÿçš„空间安装 %s" + +msgid "App Path" +msgstr "程åºè·¯å¾„" + +msgid "%s App Path" +msgstr "%s 程åºè·¯å¾„" + +msgid "%s Client App Path" +msgstr "%s 客户端程åºè·¯å¾„" + +msgid "Node Subscribe" +msgstr "节点订阅" + +msgid "Subscribe Remark" +msgstr "订阅备注(机场)" + +msgid "Subscribe Info" +msgstr "订阅信æ¯" + +msgid "Subscribe URL" +msgstr "订阅网å€" + +msgid "Subscribe URL Access Method" +msgstr "订阅网å€è®¿é—®æ–¹å¼" + +msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically." +msgstr "新增订阅请先ä¿å­˜å¹¶åº”用åŽå†æ‰‹åŠ¨è®¢é˜…ï¼›å¦‚ä»…ä¿®æ”¹è®¢é˜…åœ°å€ï¼Œå¯ç›´æŽ¥æ‰‹åŠ¨è®¢é˜…ï¼Œç³»ç»Ÿå°†è‡ªåŠ¨ä¿å­˜ã€‚" + +msgid "Please save and apply before manually subscribing." +msgstr "请先ä¿å­˜å¹¶åº”用åŽå†æ‰‹åŠ¨è®¢é˜…ã€‚" + +msgid "Subscribe URL cannot be empty." +msgstr "订阅网å€ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Subscribe via proxy" +msgstr "通过代ç†è®¢é˜…" + +msgid "Update Once on Boot" +msgstr "开机更新一次" + +msgid "Updates the subscription the first time runs automatically after each system boot." +msgstr "è·¯ç”±æ¯æ¬¡å¯åЍåŽï¼Œé¦–次自动è¿è¡Œæ—¶æ›´æ–°è®¢é˜…。" + +msgid "Enable auto update subscribe" +msgstr "å¼€å¯è‡ªåŠ¨æ›´æ–°è®¢é˜…" + +msgid "Manual subscription" +msgstr "手动订阅" + +msgid "Delete All Subscribe Node" +msgstr "删除所有订阅节点" + +msgid "Delete the subscribed node" +msgstr "删除已订阅的节点" + +msgid "Are you sure you want to delete all subscribed nodes?" +msgstr "您确定è¦åˆ é™¤æ‰€æœ‰å·²è®¢é˜…的节点å—?" + +msgid "Manual subscription All" +msgstr "手动订阅全部链接" + +msgid "This remark already exists, please change a new remark." +msgstr "此备注已存在,请改一个新的备注。" + +msgid "Remark cannot be empty." +msgstr "备注ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "URL cannot be empty." +msgstr "网å€ä¸èƒ½ä¸ºç©ºã€‚" + +msgid "Filter keyword Mode" +msgstr "过滤关键字模å¼" + +msgid "Discard List" +msgstr "丢弃列表" + +msgid "Keep List" +msgstr "ä¿ç•™åˆ—表" + +msgid "Discard List,But Keep List First" +msgstr "丢弃列表,但ä¿ç•™åˆ—表优先" + +msgid "Keep List,But Discard List First" +msgstr "ä¿ç•™åˆ—表,但丢弃列表优先" + +msgid "Use global config" +msgstr "使用全局é…ç½®" + +msgid "User-Agent" +msgstr "用户代ç†(User-Agent)" + +msgid "Add" +msgstr "添加" + +msgid "ACLs" +msgstr "访问控制" + +msgid "ACLs is a tools which used to designate specific IP proxy mode." +msgstr "访问控制列表是用于指定特殊IPä»£ç†æ¨¡å¼çš„工具。" + +msgid "Example:" +msgstr "例:" + +msgid "IP range" +msgstr "IP 范围" + +msgid "Source Interface" +msgstr "æºæŽ¥å£" + +msgid "Bridge" +msgstr "网桥" + +msgid "Wireless Adapter" +msgstr "无线适é…器" + +msgid "Ethernet Adapter" +msgstr "以太网适é…器" + +msgid "Tunnel Interface" +msgstr "éš§é“æŽ¥å£" + +msgid "Invalid interface name" +msgstr "无效的接å£åç§°" + +msgid "Use Interface With ACLs" +msgstr "ä½¿ç”¨æŽ¥å£æŽ§åˆ¶" + +msgid "Remarks" +msgstr "备注" + +msgid "Direct List" +msgstr "直连列表" + +msgid "Proxy List" +msgstr "代ç†åˆ—表" + +msgid "Block List" +msgstr "å±è”½åˆ—表" + +msgid "Lan IP List" +msgstr "局域网IP列表" + +msgid "Route Hosts" +msgstr "路由Hosts文件" + +msgid "Join the direct hosts list of domain names will not proxy." +msgstr "加入的域åä¸èµ°ä»£ç†ï¼Œå¯¹æ‰€æœ‰æ¨¡å¼æœ‰æ•ˆã€‚且优先级最高。" + +msgid "These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5." +msgstr "加入的IP段ä¸èµ°ä»£ç†ï¼Œå¯¹æ‰€æœ‰æ¨¡å¼æœ‰æ•ˆã€‚且优先级最高。å¯è¾“å…¥IPåœ°å€æˆ–åœ°å€æ®µï¼Œå¦‚:192.168.0.0/24或223.5.5.5,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined websites will use proxy. Please input the domain names of websites, every line can input only one website domain. For example: google.com." +msgstr "加入的域å将走代ç†ã€‚输入网站域å,如:google.com,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined ip addresses will use proxy. Please input the ip address or ip address segment, every line can input only one ip address. For example: 35.24.0.0/24 or 8.8.4.4." +msgstr "加入的IP段将走代ç†ã€‚å¯è¾“å…¥IPåœ°å€æˆ–åœ°å€æ®µï¼Œå¦‚:35.24.0.0/24或8.8.4.4,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined websites will be block. Please input the domain names of websites, every line can input only one website domain. For example: twitter.com." +msgstr "加入的域åå°†å±è”½ã€‚输入网站域å,如:twitter.com,æ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "The list is the IPv4 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "列表中为IPv4的局域网IP列表,代表局域网直连IP。如果需è¦ä»£ç†åˆ—表中的局域网IP,请将其在该列表中清除,并将其添加到代ç†åˆ—表中。默认情况下ä¸è¦ä¿®æ”¹è¿™ä¸ªåˆ—表。" + +msgid "The list is the IPv6 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "列表中为IPv6的局域网IP列表,代表局域网直连IP。如果需è¦ä»£ç†åˆ—表中的局域网IP,请将其在该列表中清除,并将其添加到代ç†åˆ—表中。默认情况下ä¸è¦ä¿®æ”¹è¿™ä¸ªåˆ—表。" + +msgid "Configure routing etc/hosts file, if you don't know what you are doing, please don't change the content." +msgstr "é…置路由etc/hosts文件,如果你ä¸çŸ¥é“自己在åšä»€ä¹ˆï¼Œè¯·ä¸è¦æ”¹åŠ¨å†…å®¹ã€‚" + +msgid "These had been joined ip addresses will be block. Please input the ip address or ip address segment, every line can input only one ip address." +msgstr "加入的IP段将å±è”½ã€‚å¯è¾“å…¥IPåœ°å€æˆ–åœ°å€æ®µï¼Œæ¯ä¸ªåœ°å€æ®µä¸€è¡Œã€‚" + +msgid "Inbound Tag" +msgstr "入站标签" + +msgid "Transparent proxy" +msgstr "逿˜Žä»£ç†" + +msgid "Not valid domain name, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆåŸŸåï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not valid IP format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆIPæ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not valid IPv4 format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆIPv4æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not valid IPv6 format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆIPv6æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Not true format, please re-enter!" +msgstr "䏿˜¯æ­£ç¡®çš„æ ¼å¼ï¼Œè¯·é‡æ–°è¾“å…¥ï¼" + +msgid "Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'." +msgstr "纯字符串: 当此字符串匹é…目标域å中任æ„部分,该规则生效。比如'sina.com'å¯ä»¥åŒ¹é…'sina.com'ã€'sina.com.cn'å’Œ'www.sina.com',但ä¸åŒ¹é…'sina.cn'。" + +msgid "Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'." +msgstr "正则表达å¼: ç”±'regexp:'开始,余下部分是一个正则表达å¼ã€‚当此正则表达å¼åŒ¹é…ç›®æ ‡åŸŸåæ—¶ï¼Œè¯¥è§„则生效。例如'regexp:\\.goo.*\\.com$'匹é…'www.google.com'ã€'fonts.googleapis.com',但ä¸åŒ¹é…'google.com'。" + +msgid "Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'." +msgstr "å­åŸŸå (推è): ç”±'domain:'开始,余下部分是一个域åã€‚å½“æ­¤åŸŸåæ˜¯ç›®æ ‡åŸŸå或其å­åŸŸå时,该规则生效。例如'domain:v2ray.com'匹é…'www.v2ray.com'ã€'v2ray.com',但ä¸åŒ¹é…'xv2ray.com'。" + +msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'." +msgstr "完整匹é…: ç”±'full:'开始,余下部分是一个域å。当此域å完整匹é…ç›®æ ‡åŸŸåæ—¶ï¼Œè¯¥è§„则生效。例如'full:v2ray.com'匹é…'v2ray.com'但ä¸åŒ¹é…'www.v2ray.com'。" + +msgid "Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'" +msgstr "Sing-Box 规则集: ç”± 'rule-set:remote:' 或 'rule-set:local:' 开始" + +msgid "Such as:" +msgstr "例如:" + +msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn." +msgstr "预定义域å列表:由'geosite:'开头,余下部分是一个å称,如geosite:google或者geosite:cn。" + +msgid "Annotation: Begining with #" +msgstr "注释: ç”± # 开头" + +msgid "Invert match result." +msgstr "å选匹é…结果。" + +msgid "Only support Sing-Box." +msgstr "åªæ”¯æŒ Sing-Box。" + +msgid "IP: such as '127.0.0.1'." +msgstr "IP: 形如'127.0.0.1'。" + +msgid "CIDR: such as '127.0.0.0/8'." +msgstr "CIDR: 形如'10.0.0.0/8'." + +msgid "GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code." +msgstr "GeoIP: 形如'geoip:cn',必须以geoip:(å°å†™ï¼‰å¼€å¤´ï¼ŒåŽé¢è·ŸåŒå­—符国家代ç ï¼Œæ”¯æŒå‡ ä¹Žæ‰€æœ‰å¯ä»¥ä¸Šç½‘的国家。" + +msgid "Clear logs" +msgstr "清空日志" + +msgid "Password" +msgstr "密ç " + +msgid "IV Check" +msgstr "IV 检查" + +msgid "UDP over TCP" +msgstr "TCP å°è£… UDP" + +msgid "Connection Timeout" +msgstr "连接超时时间" + +msgid "Local Port" +msgstr "本地端å£" + +msgid "Fast Open" +msgstr "快速打开" + +msgid "Pre-connections" +msgstr "预连接" + +msgid "Number of early established connections to reduce latency." +msgstr "预连接的数é‡ï¼Œç”¨äºŽé™ä½Žå»¶è¿Ÿã€‚" + +msgid "plugin" +msgstr "æ’ä»¶" + +msgid "Supports custom SIP003 plugins, Make sure the plugin is installed." +msgstr "支æŒè‡ªå®šä¹‰ SIP003 æ’ä»¶ï¼Œè¯·ç¡®ä¿æ’件已安装。" + +msgid "opts" +msgstr "æ’件选项" + +msgid "Protocol" +msgstr "åè®®åç§°" + +msgid "Protocol_param" +msgstr "åè®®å‚æ•°" + +msgid "Obfs" +msgstr "æ··æ·†" + +msgid "Obfs_param" +msgstr "æ··æ·†å‚æ•°" + +msgid "Plugin Name" +msgstr "æ’ä»¶åç§°" + +msgid "Plugin Arguments" +msgstr "æ’件傿•°" + +msgid "User Level" +msgstr "用户等级(level)" + +msgid "Transport" +msgstr "传输方å¼" + +msgid "Public Key" +msgstr "公钥" + +msgid "Private Key" +msgstr "ç§é’¥" + +msgid "Pre shared key" +msgstr "é¢å¤–的对称加密密钥" + +msgid "Local Address" +msgstr "本地地å€" + +msgid "System interface" +msgstr "系统接å£" + +msgid "System interface name" +msgstr "系统接å£åç§°" + +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "用“,â€éš”开的å进制数字或 Base64 ç¼–ç å­—符串。" + +msgid "Camouflage Domain" +msgstr "伪装域å" + +msgid "Camouflage Type" +msgstr "伪装类型" + +msgid "Transport Layer Encryption" +msgstr "传输层加密" + +msgid "Whether or not transport layer encryption is enabled, \"none\" for unencrypted, \"tls\" for using TLS, \"xtls\" for using XTLS." +msgstr "是å¦å¯å…¥ä¼ è¾“层加密,支æŒçš„选项有 \"none\" 表示ä¸åŠ å¯†ï¼Œ\"tls\" 表示使用 TLS,\"xtls\" 表示使用 XTLS。" + +msgid "Original Trojan only supported 'tls', please choose 'tls'." +msgstr "原版Trojanåªæ”¯æŒ'tls',请选择'tls'。" + +msgid "Transfer mode" +msgstr "传输模å¼" + +msgid "Do not send server name in ClientHello." +msgstr "ä¸è¦åœ¨ ClientHello 中å‘逿œåС噍åç§°." + +msgid "Domain" +msgstr "域å" + +msgid "allowInsecure" +msgstr "å…许ä¸å®‰å…¨è¿žæŽ¥" + +msgid "Whether unsafe connections are allowed. When checked, Certificate validation will be skipped." +msgstr "是å¦å…许ä¸å®‰å…¨è¿žæŽ¥ã€‚当勾选时,将跳过è¯ä¹¦éªŒè¯ã€‚" + +msgid "Used when the node link does not include this parameter." +msgstr "当节点链接未包å«è¯¥å‚数时,将使用此设置。" + +msgid "%s Node Use Type" +msgstr "%s 节点使用类型" + +msgid "UDP relay mode" +msgstr "UDP中继模å¼" + +msgid "Concurrent Tunnels" +msgstr "å¹¶å‘éš§é“连接数" + +msgid "Congestion control algorithm" +msgstr "拥塞控制算法" + +msgid "Heartbeat interval(second)" +msgstr "ä¿æ´»å¿ƒè·³åŒ…å‘é€é—´éš”(å•ä½ï¼šç§’)" + +msgid "Disable SNI" +msgstr "关闭SNIæœåС噍å称指示" + +msgid "Enable 0-RTT QUIC handshake" +msgstr "客户端å¯ç”¨ 0-RTT QUIC è¿žæŽ¥æ¡æ‰‹" + +msgid "
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests." +msgstr "
none:默认值,ä¸è¿›è¡Œä¼ªè£…,å‘é€çš„æ•°æ®æ˜¯æ²¡æœ‰ç‰¹å¾çš„æ•°æ®åŒ…。
srtpï¼šä¼ªè£…æˆ SRTP æ•°æ®åŒ…ï¼Œä¼šè¢«è¯†åˆ«ä¸ºè§†é¢‘é€šè¯æ•°æ®ï¼ˆå¦‚ FaceTime)。
utpï¼šä¼ªè£…æˆ uTP æ•°æ®åŒ…,会被识别为 BT 下载数æ®ã€‚
wechat-video:伪装æˆå¾®ä¿¡è§†é¢‘通è¯çš„æ•°æ®åŒ…。
dtlsï¼šä¼ªè£…æˆ DTLS 1.2 æ•°æ®åŒ…。
wireguardï¼šä¼ªè£…æˆ WireGuard æ•°æ®åŒ…。(并䏿˜¯çœŸæ­£çš„ WireGuard åè®®)
dns:把æµé‡ä¼ªè£…æˆ DNS 请求。" + +msgid "Use it together with the DNS disguised type. You can fill in any domain." +msgstr "é…åˆä¼ªè£…类型 DNS 使用,å¯éšä¾¿å¡«ä¸€ä¸ªåŸŸå。" + +msgid "Auth" +msgstr "身份认è¯" + +msgid "Socks for authentication" +msgstr "Socksè®¤è¯æ–¹å¼" + +msgid "Socks protocol authentication, support anonymous and password." +msgstr "Socks åè®®çš„è®¤è¯æ–¹å¼ï¼Œæ”¯æŒåŒ¿åæ–¹å¼å’Œè´¦å·å¯†ç æ–¹å¼ã€‚" + +msgid "anonymous" +msgstr "匿å" + +msgid "User Password" +msgstr "è´¦å·å¯†ç " + +msgid "Username and Password must be used together!" +msgstr "è´¦å·å’Œå¯†ç å¿…é¡»åŒæ—¶ä½¿ç”¨ï¼" + +msgid "Prefer firewall tools" +msgstr "首选防ç«å¢™å·¥å…·" + +msgid "IPv6 TProxy" +msgstr "IPv6逿˜Žä»£ç†(TProxy)" + +msgid "Experimental feature. Make sure that your node supports IPv6." +msgstr "实验特性,请确ä¿ä½ çš„节点支æŒIPv6" + +msgid "Status info" +msgstr "状æ€ä¿¡æ¯" + +msgid "Big icon" +msgstr "大图标" + +msgid "Show node check" +msgstr "显示节点检测" + +msgid "Show Show IP111" +msgstr "显示IP111" + +msgid "Destination protocol" +msgstr "目标åè®®" + +msgid "Destination address" +msgstr "目标地å€" + +msgid "Destination port" +msgstr "目标端å£" + +msgid "Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used." +msgstr "æ˜¯å¦æŽ¥æ”¶ PROXY protocol,当该节点è¦è¢«å›žè½æˆ–被代ç†è½¬å‘时,必须å¯ç”¨ï¼Œå¦åˆ™ä¸èƒ½ä½¿ç”¨ã€‚" + +msgid "outbound node" +msgstr "出站节点" + +msgid "Custom Socks" +msgstr "自定义 Socks" + +msgid "Custom HTTP" +msgstr "自定义 HTTP" + +msgid "Custom Interface" +msgstr "自定义接å£" + +msgid "Interface" +msgstr "接å£" + +msgid "Bind Local" +msgstr "本机监å¬" + +msgid "When selected, it can only be accessed localhost." +msgstr "当勾选时,åªèƒ½æœ¬æœºè®¿é—®ã€‚" + +msgid "Accept LAN Access" +msgstr "接å—局域网访问" + +msgid "When selected, it can accessed lan , this will not be safe!" +msgstr "当勾选时,å¯ä»¥ç›´æŽ¥è®¿é—®å±€åŸŸç½‘,这将ä¸å®‰å…¨ï¼ï¼ˆéžç‰¹æ®Šæƒ…况ä¸å»ºè®®å¼€å¯ï¼‰" + +msgid "Enable Remote" +msgstr "å¯ç”¨è½¬å‘" + +msgid "You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more." +msgstr "您å¯ä»¥è½¬å‘到Nginx/Caddy/V2ray/Xray WebSocket等。" + +msgid "Remote Address" +msgstr "远程地å€" + +msgid "Remote Port" +msgstr "远程端å£" + +msgid "as:" +msgstr "如:" + +msgid "Public key absolute path" +msgstr "公钥文件ç»å¯¹è·¯å¾„" + +msgid "Private key absolute path" +msgstr "ç§é’¥æ–‡ä»¶ç»å¯¹è·¯å¾„" + +msgid "Can't find this file!" +msgstr "找ä¸åˆ°è¿™ä¸ªæ–‡ä»¶ï¼" + +msgid "Public key and Private key path can not be empty!" +msgstr "公钥和ç§é’¥æ–‡ä»¶è·¯å¾„ä¸èƒ½ä¸ºç©ºï¼" + +msgid "Server-Side" +msgstr "æœåŠ¡å™¨ç«¯" + +msgid "Server Config" +msgstr "æœåС噍é…ç½®" + +msgid "Users Manager" +msgstr "用户管ç†" + +msgid "Logs" +msgstr "日志" + +msgid "Log" +msgstr "日志" + +msgid "Enable Node Log" +msgstr "å¯ç”¨èŠ‚ç‚¹æ—¥å¿—" + +msgid "Log Level" +msgstr "日志等级" + +msgid "Not enabled log" +msgstr "未å¯ç”¨æ—¥å¿—" + +msgid "UDP Forward" +msgstr "UDP转å‘" + +msgid "DNS Settings" +msgstr "DNS设置" + +msgid "Null" +msgstr "æ— " + +msgid "You did not fill in the %s path. Please save and apply then update manually." +msgstr "您没有填写 %s 路径。请ä¿å­˜åº”用åŽå†æ‰‹åŠ¨æ›´æ–°ã€‚" + +msgid "Not installed %s, Can't unzip!" +msgstr "未安装 %s,无法解压。" + +msgid "Can't determine ARCH, or ARCH not supported." +msgstr "无法确认ARCHæž¶æž„ï¼Œæˆ–æ˜¯ä¸æ”¯æŒã€‚" + +msgid "Get remote version info failed." +msgstr "获å–远程版本信æ¯å¤±è´¥ã€‚" + +msgid "New version found, but failed to get new version download url." +msgstr "å‘现新版本,但未能获得新版本的下载地å€ã€‚" + +msgid "Download url is required." +msgstr "请指定下载地å€ã€‚" + +msgid "File download failed or timed out: %s" +msgstr "文件下载失败或超时:%s" + +msgid "File path required." +msgstr "请指定文件路径。" + +msgid "%s not enough space." +msgstr "%s 空间ä¸è¶³ã€‚" + +msgid "Can't find client in file: %s" +msgstr "无法在文件中找到客户端:%s" + +msgid "Client file is required." +msgstr "请指定客户端文件。" + +msgid "The client file is not suitable for current device." +msgstr "客户端文件ä¸é€‚åˆå½“å‰è®¾å¤‡ã€‚" + +msgid "Can't move new file to path: %s" +msgstr "无法移动新文件到:%s" + +msgid "An XHttpObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ XHttpObject,用æ¥å®žçŽ°åˆ†äº«ã€‚" + +msgid "Enable Mux.Cool" +msgstr "å¯ç”¨ Mux.Cool" + +msgid "Mux concurrency" +msgstr "最大并å‘连接数" + +msgid "XUDP Mux concurrency" +msgstr "XUDP 最大并å‘连接数" + +msgid "Padding" +msgstr "å¡«å……" + +msgid "Enable early data" +msgstr "å¯ç”¨å‰ç½®æ•°æ®" + +msgid "Early data length" +msgstr "å‰ç½®æ•°æ®æœ€å¤§é•¿åº¦" + +msgid "Early data header name" +msgstr "å‰ç½®æ•°æ® HTTP 头å" + +msgid "Recommended value: Sec-WebSocket-Protocol" +msgstr "推è值:Sec-WebSocket-Protocol" + +msgid "Health check" +msgstr "å¥åº·æ£€æŸ¥" + +msgid "Health check timeout" +msgstr "检查超时时间" + +msgid "Permit without stream" +msgstr "æ— å­è¿žæŽ¥æ—¶çš„å¥åº·æ£€æŸ¥" + +msgid "Initial Windows Size" +msgstr "åˆå§‹çª—å£å¤§å°" + +msgid "Excluded Domains" +msgstr "排除域å" + +msgid "If the traffic sniffing result is in this list, the destination address will not be overridden." +msgstr "如果æµé‡å—…探结果在此列表中,则ä¸ä¼šè¦†ç›–目标地å€ã€‚" + +msgid "Buffer Size" +msgstr "缓冲区大å°" + +msgid "Buffer size for every connection (kB)" +msgstr "æ¯ä¸€ä¸ªè¿žæŽ¥çš„缓冲区大å°ï¼ˆkB)" + +msgid "Idle Timeout" +msgstr "空闲超时" + +msgid "Hop Interval(second)" +msgstr "端å£è·³è·ƒé—´éš”(秒)" + +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "支æŒå›ºå®šå€¼æˆ–éšæœºèŒƒå›´ï¼ˆå¦‚ 30 或 5-30ï¼‰ï¼Œæœ€å° 5 秒。" + +msgid "HeartbeatPeriod(second)" +msgstr "心跳周期(å•ä½ï¼šç§’)" + +msgid "Override the connection destination address" +msgstr "覆盖连接目标地å€" + +msgid "Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "用探测出的域å覆盖连接目标地å€ã€‚
å¦åˆ™ä»…将探测得到的域å用于路由。
如使用分æµèŠ‚ç‚¹ï¼Œè¯·æ­£ç¡®è®¾ç½®åŸŸå分æµè§„则。" + +msgid "Handshake Server" +msgstr "æ¡æ‰‹æœåС噍" + +msgid "Handshake Server Port" +msgstr "æ¡æ‰‹æœåŠ¡å™¨ç«¯å£" + +msgid "Protocol parameter. Will waste traffic randomly if enabled." +msgstr "åè®®å‚æ•°ã€‚ 如果å¯ç”¨ä¼šéšæœºæµªè´¹æµé‡ã€‚" + +msgid "Protocol parameter. Enable length block encryption." +msgstr "åè®®å‚æ•°ã€‚å¯ç”¨é•¿åº¦å—加密。" + +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "TLS è¯ä¹¦é“¾æŒ‡çº¹ï¼ˆSHA256)" + +msgid "Once set, connects only when the server’s chain fingerprint matches." +msgstr "设置åŽï¼Œä»…在æœåС噍è¯ä¹¦é“¾æŒ‡çº¹åŒ¹é…时连接。" + +msgid "TLS Certificate Name (CertName)" +msgstr "TLS è¯ä¹¦å称(CertName)" + +msgid "TLS is used to verify the leaf certificate name." +msgstr "TLS ç”¨äºŽéªŒè¯ leaf è¯ä¹¦çš„ name。" + +msgid "ECH Config" +msgstr "ECH é…ç½®" + +msgid "ECH Key" +msgstr "ECH 密钥" + +msgid "ECH Query Domain" +msgstr "ECH 查询域å" + +msgid "Overrides the domain name used for ECH HTTPS record queries." +msgstr "覆盖用于 ECH HTTPS 记录查询的域å。" + +msgid "Enable Multipath TCP, need to be enabled in both server and client configuration." +msgstr "å¯ç”¨ Multipath TCP,需在æœåŠ¡ç«¯å’Œå®¢æˆ·ç«¯é…ç½®ä¸­åŒæ—¶å¯ç”¨ã€‚" + +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ FinalMaskObject,用æ¥å®žçŽ°åˆ†äº«ã€‚" + +msgid "Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings." +msgstr "自定义 finalmask 将覆盖 mkcpã€hysteria2ã€fragmentã€noise 等相关é…置。" + +msgid "Fragment" +msgstr "分片" + +msgid "TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists." +msgstr "TCP 分片,在æŸäº›æƒ…况下å¯ä»¥æ¬ºéª—审查系统,比如绕过 SNI 黑åå•。" + +msgid "Fragment Packets" +msgstr "分片方å¼" + +msgid " \"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation." +msgstr " \"1-3\" 是 TCP çš„æµåˆ‡ç‰‡ï¼Œåº”用于客户端第 1 至第 3 次写数æ®ã€‚\"tlshello\" 是 TLS æ¡æ‰‹åŒ…切片。" + +msgid "Fragment Length" +msgstr "分片包长" + +msgid "Fragmented packet length (byte)" +msgstr "分片包长 (byte)" + +msgid "Fragment Delay" +msgstr "分片延迟" + +msgid "Fragmentation interval (ms)" +msgstr "分片间隔(ms)" + +msgid "Max Split" +msgstr "最大分片数" + +msgid "Limit the maximum number of splits." +msgstr "é™åˆ¶åˆ†ç‰‡çš„æœ€å¤§æ•°é‡ã€‚" + +msgid "Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first." +msgstr "å°†æ¡æ‰‹æ•°æ®æ‹†åˆ†ä¸ºå¤šä¸ª TLS 记录,æå‡æŠ—å°é”能力,几乎ä¸å¢žåŠ å»¶è¿Ÿï¼Œå»ºè®®ä¼˜å…ˆå¯ç”¨ã€‚" + +msgid "Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed." +msgstr "å°† TLS æ¡æ‰‹æ•°æ®åˆ†ä¸ºå¤šä¸ª TCP 包å‘é€ï¼Œæé«˜ä¼ªè£…性,å¯èƒ½å¢žåŠ å»¶è¿Ÿï¼Œä»…åœ¨å°é”䏥釿—¶ä½¿ç”¨ã€‚" + +msgid "Noise" +msgstr "噪声" + +msgid "UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions." +msgstr "UDP 噪声,在æŸäº›æƒ…况下å¯ä»¥ç»•过一些针对 UDP å议的é™åˆ¶ã€‚" + +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "在 Xray 设置中勾选 “噪声†以å‘é€å™ªå£°åŒ…。" + +msgid "Xray Noise Packets" +msgstr "Xray 噪声数æ®åŒ…" + +msgid "Packet | Rand Length" +msgstr "æ•°æ®åŒ… | Rand 长度" + +msgid "Delay (ms)" +msgstr "延迟(ms)" + +msgid "If is domain name, The requested domain name will be resolved to IP before connect." +msgstr "如果是域å,域å将在请求å‘出之å‰è§£æžä¸º IP。" + +msgid "Domain DNS Resolve" +msgstr "域å DNS è§£æž" + +msgid "If the node address is a domain name, this DNS will be used for resolution." +msgstr "å¦‚æžœèŠ‚ç‚¹åœ°å€æ˜¯åŸŸå,则将使用此 DNS 进行解æžã€‚" + +msgid "Supports only Xray or Sing-box node types." +msgstr "ä»…æ”¯æŒ Xray 或 Sing-box 类型节点。" + +msgid "Chain Proxy" +msgstr "链å¼ä»£ç†" + +msgid "Outbound Interface" +msgstr "出站接å£" + +msgid "Landing Node" +msgstr "è½åœ°èŠ‚ç‚¹" + +msgid "Only support a layer of proxy." +msgstr "仅支æŒä¸€å±‚代ç†ã€‚" + +msgid "" +"Chained proxy works only with Xray or Sing-box nodes.
" +"You can only use manual or imported nodes as chained nodes." +msgstr "" +"链å¼ä»£ç†ä»…æ”¯æŒ Xray 或 Sing-box 节点。
" +"ä»…æ”¯æŒæ‰‹åŠ¨æ·»åŠ æˆ–å¯¼å…¥çš„èŠ‚ç‚¹ç”¨ä½œé“¾å¼èŠ‚ç‚¹ã€‚" + +msgid "Prefer IPv4" +msgstr "IPv4 优先" + +msgid "Prefer IPv6" +msgstr "IPv6 优先" + +msgid "IPv4 Only" +msgstr "ä»… IPv4" + +msgid "IPv6 Only" +msgstr "ä»… IPv6" + +msgid "Maintain" +msgstr "维护" + +msgid "Backup and Restore" +msgstr "备份还原" + +msgid "Backup or Restore Client and Server Configurations." +msgstr "å¤‡ä»½æˆ–è¿˜åŽŸå®¢æˆ·ç«¯åŠæœåŠ¡ç«¯é…置。" + +msgid "Note: Restoring configurations across different versions may cause compatibility issues." +msgstr "注æ„:ä¸åŒç‰ˆæœ¬é—´çš„é…ç½®æ¢å¤å¯èƒ½ä¼šå¯¼è‡´å…¼å®¹æ€§é—®é¢˜ã€‚" + +msgid "Create Backup File" +msgstr "创建备份文件" + +msgid "Restore Backup File" +msgstr "æ¢å¤å¤‡ä»½æ–‡ä»¶" + +msgid "DL Backup" +msgstr "下载备份" + +msgid "RST Backup" +msgstr "æ¢å¤å¤‡ä»½" + +msgid "Backup failed!" +msgstr "备份失败ï¼" + +msgid "UL Restore" +msgstr "上传æ¢å¤" + +msgid "CLOSE WIN" +msgstr "关闭窗å£" + +msgid "Restore to default configuration" +msgstr "æ¢å¤é»˜è®¤é…ç½®" + +msgid "Do Reset" +msgstr "执行é‡ç½®" + +msgid "Please select a file first." +msgstr "请先选择一个文件。" + +msgid "Invalid file type. Please upload a .tar.gz file." +msgstr "文件类型无效,请上传一个 .tar.gz 文件。" + +msgid "File size exceeds 10MB limit." +msgstr "文件大å°è¶…过 10MB é™åˆ¶ã€‚" + +msgid "Do you want to restore the client to default settings?" +msgstr "是å¦è¦æ¢å¤å®¢æˆ·ç«¯é»˜è®¤é…置?" + +msgid "Are you sure you want to restore the client to default settings?" +msgstr "是å¦çœŸçš„è¦æ¢å¤å®¢æˆ·ç«¯é»˜è®¤é…置?" + +msgid "Configuration file uploaded successfully…" +msgstr "é…置文件上传æˆåŠŸâ€¦" + +msgid "Configuration restored successfully…" +msgstr "é…置还原æˆåŠŸâ€¦" + +msgid "Service restarting…" +msgstr "é‡å¯æœåŠ¡ä¸­â€¦" + +msgid "Configuration file decompression failed, please try again!" +msgstr "é…置文件解压失败,请é‡è¯•ï¼" + +msgid "_urltest" +msgstr "URLTest" + +msgid "URLTest node list" +msgstr "URLTest 节点列表" + +msgid "List of nodes to test, document" +msgstr "è¦æµ‹è¯•的节点列表,文档原ç†" + +msgid "Test interval" +msgstr "测试间隔" + +msgid "Test interval must be less or equal than idle timeout." +msgstr "测试间隔时间必须å°äºŽæˆ–等于空闲超时时间。" + +msgid "Test tolerance" +msgstr "测试容差" + +msgid "The test tolerance in milliseconds." +msgstr "测试容差时间(å•ä½ï¼šæ¯«ç§’)。" + +msgid "Idle timeout" +msgstr "空闲超时" + +msgid "The idle timeout." +msgstr "空闲超时时间。" + +msgid "Interrupt existing connections" +msgstr "中断现有连接" + +msgid "Interrupt existing connections when the selected outbound has changed." +msgstr "当选择的出站å‘生å˜åŒ–时中断现有连接。" + +msgid "Port hopping range" +msgstr "端å£è·³è·ƒèŒƒå›´" + +msgid "Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,)." +msgstr "æ ¼å¼ä¸ºï¼š1000:2000 或 1000-2000 多组时用逗å·(,)隔开。" + +msgid "Use Custom Config" +msgstr "使用自定义é…ç½®" + +msgid "Custom Config" +msgstr "自定义é…ç½®" + +msgid "Must be JSON text!" +msgstr "必须是 JSON 文本内容ï¼" + +msgid "Geo View" +msgstr "Geo 查询" + +msgid "Query" +msgstr "查询" + +msgid "Querying" +msgstr "查询中" + +msgid "Please enter query content!" +msgstr "请输入查询内容ï¼" + +msgid "No results were found!" +msgstr "未找到任何结果ï¼" + +msgid "Rules containing this value:" +msgstr "所在规则列表:" + +msgid "Domain/IP Query" +msgstr "域å/IP 查询" + +msgid "GeoIP/Geosite Query" +msgstr "GeoIP/Geosite 查询" + +msgid "Enter a domain or IP to query the Geo rule list they belong to." +msgstr "输入域å/IP,查询它们所在的 Geo 规则列表。" + +msgid "Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw" +msgstr "输入 GeoIP/Geosite,æå–它们所包å«çš„域å/IP。格å¼ï¼šgeoip:cn 或 geosite:gfw" + +msgid "Tips:" +msgstr "å°è´´å£«ï¼š" + +msgid "By entering a domain or IP, you can query the Geo rule list they belong to." +msgstr "å¯ä»¥é€šè¿‡è¾“入域å/IP,查询它们所在的 Geo 规则列表。" + +msgid "By entering a GeoIP or Geosite, you can extract the domains/IPs they contain." +msgstr "å¯ä»¥é€šè¿‡è¾“å…¥ GeoIP/Geosite,æå–它们所包å«çš„域å/IP。" + +msgid "Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct." +msgstr "利用 GeoIP/Geosite 查询功能,å¯ä»¥éªŒè¯è¾“入的 Geo è§„åˆ™æ˜¯å¦æ­£ç¡®ã€‚" + +msgid "Private Key Passphrase" +msgstr "ç§é’¥æŒ‡çº¹" + +msgid "Host Key" +msgstr "主机密钥" + +msgid "Accept any if empty." +msgstr "ç•™ç©ºåˆ™ä¸æ ¡éªŒã€‚" + +msgid "Host Key Algorithms" +msgstr "主机密钥算法" + +msgid "Client Version" +msgstr "客户端版本" + +msgid "Random version will be used if empty." +msgstr "å¦‚ç•™ç©ºï¼Œåˆ™ä½¿ç”¨éšæœºç‰ˆæœ¬ã€‚" + +msgid "The configured type also applies to the core specified when manually importing nodes." +msgstr "é…ç½®çš„ç±»åž‹åŒæ ·é€‚用于手动导入节点时所指定的核心程åºã€‚" + +msgid "Group Name" +msgstr "分组å" + +msgid "Reassign Group" +msgstr "调整分组" + +msgid "Reassign Node Group" +msgstr "调整节点分组" + +msgid "Search nodes..." +msgstr "æœç´¢èŠ‚ç‚¹â€¦" + +msgid "Using..." +msgstr "使用中。" + +msgid "Generate configuration file and run" +msgstr "生æˆé…置文件并è¿è¡Œ" + +msgid "Start after a delay of %s seconds!" +msgstr "å»¶æ—¶ %s ç§’åŽå†å¯åЍ!" + +msgid "The script is already running, do not run it again. Exit." +msgstr "脚本已ç»åœ¨è¿è¡Œï¼Œä¸é‡å¤è¿è¡Œï¼Œé€€å‡º." + +msgid "Stop the script and wait for a timeout, then exit without repeating the process." +msgstr "åœæ­¢è„šæœ¬ç­‰å¾…è¶…æ—¶ï¼Œä¸é‡å¤è¿è¡Œï¼Œé€€å‡º." + +msgid "Warning: The %s application environment is incomplete. Switch to %s. (%s)" +msgstr "警告:%s 应用环境ä¸å®Œæ•´ï¼Œåˆ‡æ¢è‡³ %s。(%s)" + +msgid "Note: Dnsmasq (%s) is below 2.90. Upgrading is recommended to improve stability." +msgstr "æç¤ºï¼šDnsmasq (%s) 低于 2.90,建议å‡çº§ä»¥å¢žå¼ºç¨³å®šæ€§ã€‚" + +msgid "Warning: %s transparent proxy is missing basic dependency %s!" +msgstr "警告:%s 逿˜Žä»£ç†ç¼ºå¤±åŸºç¡€ä¾èµ– %s!" + +msgid "Warning: Not compatible with any transparent proxy system environment." +msgstr "è­¦å‘Šï¼šä¸æ»¡è¶³ä»»ä½•逿˜Žä»£ç†ç³»ç»ŸçŽ¯å¢ƒã€‚" + +msgid "%s does not have execute permissions and cannot be started: %s %s" +msgstr "%s 没有执行æƒé™ï¼Œæ— æ³•å¯åŠ¨ï¼š%s %s" + +msgid "%s not found, unable to start..." +msgstr "找ä¸åˆ° %s,无法å¯åЍ..." + +msgid "Socks node: [%s]%s is an invalid server address and cannot be started!" +msgstr "Socks节点:[%s]%s æ˜¯éžæ³•çš„æœåŠ¡å™¨åœ°å€ï¼Œæ— æ³•å¯åЍï¼" + +msgid "For some reason, the configuration for this Socks service has been lost, and its startup has been aborted!" +msgstr "æŸç§åŽŸå› ï¼Œæ­¤ Socks æœåŠ¡çš„ç›¸å…³é…置已失è”,å¯åŠ¨ä¸­æ­¢ï¼" + +msgid "Socks node: [%s]%s, start failed %s:%s %s" +msgstr "Socks节点:[%s]%s,å¯åŠ¨å¤±è´¥ %s:%s %s" + +msgid "Socks node: [%s]%s, starting %s:%s" +msgstr "Socks节点:[%s]%s,å¯åЍ %s:%s" + +msgid "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!" +msgstr "å¼€å¯å®žéªŒæ€§IPv6逿˜Žä»£ç†(TProxy),请确认您的节点åŠç±»åž‹æ”¯æŒIPv6ï¼" + +msgid "[%s] process %s error, skip this transparent proxy!" +msgstr "ã€%s】 进程 %s é”™è¯¯ï¼Œè·³è¿‡æ­¤é€æ˜Žä»£ç†ï¼" + +msgid "Analyzing the node configuration of the Socks service..." +msgstr "åˆ†æž Socks æœåŠ¡çš„èŠ‚ç‚¹é…ç½®..." + +msgid "Log file is too long, clear it!" +msgstr "日志文件过长,清空处ç†ï¼" + +msgid "The task is currently running automatically as a scheduled task; no reconfiguration of the scheduled task is required." +msgstr "当å‰ä¸ºè®¡åˆ’任务自动è¿è¡Œï¼Œä¸é‡æ–°é…置定时任务。" + +msgid "Scheduled tasks: Auto stop service." +msgstr "é…置定时任务:自动关闭æœåŠ¡ã€‚" + +msgid "Scheduled tasks: Auto start service." +msgstr "é…ç½®å®šæ—¶ä»»åŠ¡ï¼šè‡ªåŠ¨å¼€å¯æœåŠ¡ã€‚" + +msgid "Scheduled tasks: Auto restart service." +msgstr "é…置定时任务:自动é‡å¯æœåŠ¡ã€‚" + +msgid "Scheduled tasks: Auto update rules." +msgstr "é…置定时任务:自动更新规则。" + +msgid "Scheduled tasks: Auto update [%s] subscription." +msgstr "é…置定时任务:自动更新 ã€%s】 订阅。" + +msgid "Auto updates: Starts a cyclical update process." +msgstr "自动更新:å¯åŠ¨å¾ªçŽ¯æ›´æ–°è¿›ç¨‹ã€‚" + +msgid "Running in no proxy mode, it only allows scheduled tasks for starting and stopping services." +msgstr "è¿è¡ŒäºŽéžä»£ç†æ¨¡å¼ï¼Œä»…å…许æœåŠ¡å¯åœçš„定时任务。" + +msgid "Clear scheduled commands." +msgstr "清除定时执行命令。" + +msgid "Unable to resolve [%s], route table addition failed!" +msgstr "无法解æž[%s],路由表添加失败ï¼" + +msgid "[%s] was successfully added to the routing table of interface [%s]!" +msgstr "[%s]添加到接å£[%s]路由表æˆåŠŸï¼" + +msgid "Adding [%s] to the [%s] routing table failed! The reason is that the [%s] gateway cannot be found." +msgstr "[%s]添加到接å£[%s]路由表失功ï¼åŽŸå› æ˜¯æ‰¾ä¸åˆ°[%s]网关。" + +msgid "Global nodes are not enabled, skip [%s]." +msgstr "全局节点未å¯ç”¨ï¼Œè·³è¿‡ã€%s】" + +msgid "Direct DNS: %s" +msgstr "直连 DNS:%s" + +msgid "Remote DNS: %s" +msgstr "远程 DNS:%s" + +msgid "The program has started. Please stop it and then restart it!" +msgstr "程åºå·²å¯åŠ¨ï¼Œå…ˆåœæ­¢å†é‡æ–°å¯åЍ!" + +msgid "Running complete!" +msgstr "è¿è¡Œå®Œæˆï¼" + +msgid "Clearing and closing related programs and cache complete." +msgstr "清空并关闭相关程åºå’Œç¼“存完æˆã€‚" + +msgid "Incorrect index listing method (%s), execution terminated!" +msgstr "索引列举方å¼ä¸æ­£ç¡®ï¼ˆ%s),终止执行ï¼" + +msgid "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." +msgstr "è§£æžåˆ†æµè§„则[%s]-[geoip:%s]加入到 %s 完æˆ" + +msgid "Access Control:" +msgstr "访问控制:" + +msgid "Add node to the load balancer is directly connected to %s[%s]." +msgstr "加入负载å‡è¡¡çš„节点到%s[%s]直连完æˆã€‚" + +msgid "Add all %s nodes to %s[%s] direct connection complete." +msgstr "加入所有%s节点到%s[%s]直连完æˆã€‚" + +msgid "Starting to load %s firewall rules..." +msgstr "开始加载 %s 防ç«å¢™è§„则..." + +msgid "local network segments (%s) direct connection: %s" +msgstr "本机 %s 网段直连:%s" + +msgid "Add ISP %s DNS to the whitelist: %s" +msgstr "追加ISP %s DNS 到白åå•:%s" + +msgid "[%s]" +msgstr "ã€%s】" + +msgid "[%s]," +msgstr "ã€%s】," + +msgid "Source iface [%s]," +msgstr "æºæŽ¥å£ã€%s】," + +msgid "IP range [%s]," +msgstr "IP 范围ã€%s】," + +msgid "All device," +msgstr "所有设备," + +msgid "Does not exist, ignore." +msgstr "ä¸å­˜åœ¨ï¼Œå¿½ç•¥ã€‚" + +msgid "not proxy %s port [%s]" +msgstr "ä¸ä»£ç† %s ç«¯å£ [%s]" + +msgid "not proxy all %s" +msgstr "ä¸ä»£ç†æ‰€æœ‰ %s" + +msgid "Use the %s node [%s]" +msgstr "使用 %s 节点[%s]" + +msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server." +msgstr "使用与全局é…ç½®ä¸ç›¸åŒèŠ‚ç‚¹ï¼Œå·²å°†DNS强制é‡å®šå‘到专用 DNS æœåŠ¡å™¨ã€‚" + +msgid "Add direct DNS to %s: %s" +msgstr "追加直连 DNS 到 %s: %s" + +msgid "Local" +msgstr "本机" + +msgid "[Local]," +msgstr "ã€æœ¬æœºã€‘," + +msgid "Clear %s." +msgstr "清除 %s。" + +msgid "Delete %s rules is complete." +msgstr "删除 %s 规则完æˆã€‚" + +msgid "%s firewall rules load complete!" +msgstr "%s 防ç«å¢™è§„则加载完æˆï¼" + +msgid "Socks switch detection: Unknown error." +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼šæœªçŸ¥é”™è¯¯ã€‚" + +msgid "Socks switch detection: Unable to connect to the network. Please check if the network is working properly!" +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼šæ— æ³•è¿žæŽ¥åˆ°ç½‘ç»œï¼Œè¯·æ£€æŸ¥ç½‘ç»œæ˜¯å¦æ­£å¸¸ï¼" + +msgid "Socks switch detection: Primary node ã€%s: [%s]】 is normal. Switch to the primary node!" +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼š%s 主节点ã€%s:[%s]】正常,切æ¢åˆ°ä¸»èŠ‚ç‚¹ï¼" + +msgid "Socks switch detection: %s node switch complete!" +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼š%s 节点切æ¢å®Œæ¯•ï¼" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal." +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼š%s ã€%s:[%s]】 正常。" + +msgid "switch to %s test detect!" +msgstr "切æ¢åˆ° %s 检测ï¼" + +msgid "backup node" +msgstr "备用节点" + +msgid "next backup node" +msgstr "下一个备用节点" + +msgid "main node" +msgstr "主节点" + +msgid "Socks switch detection: Unknown error." +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼šæœªçŸ¥é”™è¯¯ã€‚" + +msgid "Socks switch detection: %s ã€%s:[%s]】 abnormal, %s" +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼š%s ã€%s:[%s]】 异常,%s" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal, switch to this node!" +msgstr "Socksåˆ‡æ¢æ£€æµ‹ï¼š%s ã€%s:[%s]】 正常,切æ¢åˆ°æ­¤èŠ‚ç‚¹ï¼" + +msgid "Restart dnsmasq service." +msgstr "é‡å¯ dnsmasq æœåŠ¡ã€‚" + +msgid "Console Port: %s" +msgstr "控制å°ç«¯å£ï¼š%s" + +msgid "Discard one obviously invalid node." +msgstr "丢弃 1 个明显无效的节点" + +msgid "Entrance %s:%s" +msgstr "å…¥å£ %s:%s" + +msgid "Node: %s:%s, Weight: %s" +msgstr "节点:%s:%s,æƒé‡ï¼š%s" + +msgid "[Rule update] instance is running; please try again later." +msgstr "[规则更新]实例正在è¿è¡Œï¼Œè¯·ç¨åŽå†è¯•..." + +msgid "[Subscription] instance is running; [Rule Update] queue and wait." +msgstr "[订阅]实例正在è¿è¡Œï¼Œ[规则更新]进入队列等待..." + +msgid "Start updating the rules..." +msgstr "开始更新规则..." + +msgid "Download file size verification error. Original file size: %sB. Downloaded file size: %sB." +msgstr "ä¸‹è½½æ–‡ä»¶å¤§å°æ ¡éªŒå‡ºé”™ï¼ŒåŽŸå§‹æ–‡ä»¶å¤§å° %sB,下载文件大å°ï¼š%sB。" + +msgid "Downloaded file is empty or an error occurred while reading it." +msgstr "ä¸‹è½½çš„æ–‡ä»¶ä¸ºç©ºæˆ–è¯»å–æ–‡ä»¶æ—¶å‘生错误。" + +msgid "%s Start updating..." +msgstr "%s 开始更新..." + +msgid "%s version is the same and does not need to be updated." +msgstr "%s 版本一致,无需更新。" + +msgid "%s an error occurred during the file download process. Please try downloading again." +msgstr "%s 下载文件过程出错,å°è¯•釿–°ä¸‹è½½ã€‚" + +msgid "%s an error occurred while downloading the file. Please check your network or the download link and try again!" +msgstr "%s 下载文件过程出错,请检查网络或下载链接åŽé‡è¯•ï¼" + +msgid "%s update success." +msgstr "%s æ›´æ–°æˆåŠŸã€‚" + +msgid "%s update failed, please try again later or change URL." +msgstr "%s 更新失败,请ç¨åŽå†è¯•æˆ–æ›´æ¢ URL。" + +msgid "%s update error!" +msgstr "%s æ›´æ–°å‘生错误ï¼" + +msgid "Restart the service and apply the new rules." +msgstr "é‡å¯æœåŠ¡ï¼Œåº”ç”¨æ–°çš„è§„åˆ™ã€‚" + +msgid "The rules have been updated..." +msgstr "规则更新完毕..." + +msgid "Socks node list [%s]" +msgstr "Socks 节点列表 [%s]" + +msgid "Backup node list" +msgstr "备用节点的列表" + +msgid "HAProxy node list [%s]" +msgstr "HAProxy 节点列表 [%s]" + +msgid "ACL list [%s]" +msgstr "访问控制列表 [%s]" + +msgid "Shunt [%s] node" +msgstr "åˆ†æµ [%s] 节点" + +msgid "Xray Load Balancing node [%s] list" +msgstr "Xray è´Ÿè½½å‡è¡¡èŠ‚ç‚¹ [%s] 列表" + +msgid "Xray Load Balancing node [%s] backup node" +msgstr "Xray è´Ÿè½½å‡è¡¡èŠ‚ç‚¹ [%s] åŽå¤‡èŠ‚ç‚¹" + +msgid "Sing-Box URLTest node [%s] list" +msgstr "Sing-Box URLTest 节点 [%s] 列表" + +msgid "Node [%s] preproxy node" +msgstr "节点 [%s] å‰ç½®ä»£ç†èŠ‚ç‚¹" + +msgid "Node [%s] landing node" +msgstr "节点 [%s] è½åœ°èŠ‚ç‚¹" + +msgid "Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings." +msgstr "跳过 %s 节点,因未适é…到 %s 核心程åºï¼Œæˆ–未正确设置节点使用类型。" + +msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." +msgstr "跳过节点:%s,因 Sing-Box 䏿”¯æŒ %s å议的 %s 传输方å¼ï¼Œéœ€æ›´æ¢ Xray。" + +msgid "Xray unsupport %s plugin." +msgstr "Xray 䏿”¯æŒ %s æ’件。" + +msgid "Plugin options Incomplete." +msgstr "æ’件选项ä¸å®Œæ•´ã€‚" + +msgid "Please replace %s to support %s transmission method." +msgstr "è¯·æ›´æ¢ %s ä»¥æ”¯æŒ %s 传输方å¼ã€‚" + +msgid "Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks." +msgstr "è¯·æ›´æ¢ Xray 或 Sing-Box æ¥æ”¯æŒ Shadowsocks 更多的传输方å¼ã€‚" + +msgid "unsupport %s plugin." +msgstr "䏿”¯æŒ %s æ’件。" + +msgid "Skip the %s node because the %s core program is not installed." +msgstr "跳过 %s 节点,因未安装 %s æ ¸å¿ƒç¨‹åº %s。" + +msgid "Skip the %s node, as %s type nodes require Sing-Box version 1.12 or higher." +msgstr "跳过 %s 节点,因 %s ç±»åž‹çš„èŠ‚ç‚¹éœ€è¦ Sing-Box 1.12 以上版本支æŒã€‚" + +msgid "%s type node subscriptions are not currently supported, skip this node." +msgstr "æš‚æ—¶ä¸æ”¯æŒ %s 类型的节点订阅,跳过此节点。" + +msgid "Update [%s]" +msgstr "æ›´æ–°ã€%s】" + +msgid "Matching node:" +msgstr "匹é…节点:" + +msgid "First Matching node:" +msgstr "第一匹é…节点:" + +msgid "Second Matching node:" +msgstr "第二匹é…节点:" + +msgid "Third Matching node:" +msgstr "第三匹é…节点:" + +msgid "Fourth Matching node:" +msgstr "第四匹é…节点:" + +msgid "Fifth Matching node:" +msgstr "第五匹é…节点:" + +msgid "Unable to find the best matching node, now replaced with:" +msgstr "无法找到最匹é…的节点,当å‰å·²æ›´æ¢ä¸ºï¼š" + +msgid "Unable to find a new node. Please confirm and process manually." +msgstr "无法匹é…到新节点,请手动确认处ç†ã€‚" + +msgid "No node information updates are available." +msgstr "没有å¯ç”¨çš„èŠ‚ç‚¹ä¿¡æ¯æ›´æ–°ã€‚" + +msgid "Skip unknown types:" +msgstr "跳过未知类型:" + +msgid "Discard node: %s, Reason:" +msgstr "丢弃节点: %s ,原因:" + +msgid "No usable binary was found." +msgstr "找ä¸åˆ°å¯ä½¿ç”¨äºŒè¿›åˆ¶ã€‚" + +msgid "Discard filter nodes: %s type node %s" +msgstr "丢弃过滤节点: %s 类型节点 %s" + +msgid "Parsing error, skip this node." +msgstr "è§£æžé”™è¯¯ï¼Œè·³è¿‡æ­¤èŠ‚ç‚¹ã€‚" + +msgid "Successfully resolved the [%s] node, number: %s" +msgstr "æˆåŠŸè§£æžã€%s】节点,数é‡ï¼š%s" + +msgid "Get subscription content for [%s] is empty. This may be due to an invalid subscription address or a network problem. Please diagnose the issue!" +msgstr "获å–到的ã€%s】订阅内容为空,å¯èƒ½æ˜¯è®¢é˜…åœ°å€æ— æ•ˆï¼Œæˆ–是网络问题,请诊断ï¼" + +msgid "Proxy" +msgstr "代ç†" + +msgid "[Subscription] instance is running; please try again later." +msgstr "[订阅]实例正在è¿è¡Œï¼Œè¯·ç¨åŽå†è¯•..." + +msgid "[Rule Update] instance is running; [Subscription] queue and wait." +msgstr "[规则更新]实例正在è¿è¡Œï¼Œ[订阅]进入队列等待..." + +msgid "Start subscribing..." +msgstr "开始订阅..." + +msgid "Start subscribing: %s" +msgstr "开始订阅:%s" + +msgid "Subscription: [%s] No changes, no update required." +msgstr "订阅:ã€%s】没有å˜åŒ–,无需更新。" + +msgid "[%s] Subscription failed. This could be due to an invalid subscription address or a network issue. Please diagnose the problem! [%s]" +msgstr "ã€%s】订阅失败,å¯èƒ½æ˜¯è®¢é˜…åœ°å€æ— æ•ˆï¼Œæˆ–是网络问题,请诊断ï¼[%s]" + +msgid "Error, restoring service." +msgstr "å‘生错误, 正在æ¢å¤æœåŠ¡ã€‚" + +msgid "Subscription complete..." +msgstr "订阅完毕..." + +msgid "Processing, please wait…" +msgstr "正在处ç†ï¼Œè¯·ç¨å€™ã€‚" diff --git a/luci-app-passwall2/po/zh-tw/passwall2.po b/luci-app-passwall2/po/zh-tw/passwall2.po new file mode 100644 index 00000000..efea133a --- /dev/null +++ b/luci-app-passwall2/po/zh-tw/passwall2.po @@ -0,0 +1,2379 @@ +msgid "Auto" +msgstr "自動" + +msgid "RUNNING" +msgstr "é‹è¡Œä¸­" + +msgid "NOT RUNNING" +msgstr "未é‹è¡Œ" + +msgid "Working..." +msgstr "連接正常" + +msgid "Problem detected!" +msgstr "連接失敗" + +msgid "Touch Check" +msgstr "點我檢測" + +msgid "Global" +msgstr "全局" + +msgid "Kernel Unsupported" +msgstr "å…§æ ¸ä¸æ”¯æŒ" + +msgid "Basic Settings" +msgstr "基本設置" + +msgid "Node List" +msgstr "節點列表" + +msgid "Other Settings" +msgstr "高級設置" + +msgid "Load Balancing" +msgstr "負載å‡è¡¡" + +msgid "Enter interface" +msgstr "進入界é¢" + +msgid "Rule Manage" +msgstr "è¦å‰‡ç®¡ç†" + +msgid "Rule List" +msgstr "è¦å‰‡åˆ—表" + +msgid "Access control" +msgstr "è¨ªå•æŽ§åˆ¶" + +msgid "Runtime Logs" +msgstr "é‹è¡Œæ—¥èªŒ" + +msgid "Node Config" +msgstr "節點é…ç½®" + +msgid "Running Status" +msgstr "é‹è¡Œç‹€æ…‹" + +msgid "Baidu Connection" +msgstr "百度連接" + +msgid "Google Connection" +msgstr "谷歌連接" + +msgid "GitHub Connection" +msgstr "GitHub連接" + +msgid "Instagram Connection" +msgstr "Instagram連接" + +msgid "Node Check" +msgstr "節點檢測" + +msgid "Check..." +msgstr "檢測中..." + +msgid "Clear" +msgstr "清除" + +msgid "Main switch" +msgstr "主開關" + +msgid "Node" +msgstr "節點" + +msgid "Edit Current Node" +msgstr "編輯當å‰ç¯€é»ž" + +msgid "Localhost Proxy" +msgstr "路由器本機代ç†" + +msgid "When selected, localhost can transparent proxy." +msgstr "ç•¶å‹¾é¸æ™‚,路由器本機å¯ä»¥é€æ˜Žä»£ç†ã€‚" + +msgid "Client Proxy" +msgstr "客戶端代ç†" + +msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy." +msgstr "ç•¶å‹¾é¸æ™‚,局域網內的設備å¯ä»¥é€æ˜Žä»£ç†ã€‚å¦å‰‡ï¼Œå°‡ä¸ä»£ç†ã€‚但您ä»ç„¶å¯ä»¥ä½¿ç”¨è¨ªå•控制å…許指定的設備代ç†ã€‚" + +msgid "Missing components, transparent proxy is unavailable." +msgstr "ç¼ºå°‘çµ„ä»¶ï¼Œé€æ˜Žä»£ç†ç„¡æ³•使用。" + +msgid "Socks Config" +msgstr "Socks é…ç½®" + +msgid "Socks Node" +msgstr "Socks 節點" + +msgid "Current Node" +msgstr "ç•¶å‰ç¯€é»ž" + +msgid "Listen Port" +msgstr "監è½ç«¯å£" + +msgid "0 is not use" +msgstr "0為ä¸ä½¿ç”¨" + +msgid "Current node: %s" +msgstr "ç•¶å‰ç¯€é»žï¼š%s" + +msgid "Direct domain DNS routing" +msgstr "直連網域 DNS 分æµ" + +msgid "Please note that the program will not start if the format is incorrect!" +msgstr "請注æ„,格å¼ä¸æ­£ç¢ºå°‡ç„¡æ³•啟動ï¼" + +msgid "IP:Port mode acceptable, multi value split with english comma." +msgstr "æŽ¥å— IP:Port å½¢å¼çš„輸入,多個以英文逗å·åˆ†éš”。" + +msgid "Direct DNS Protocol" +msgstr "直連 DNS å”è­°" + +msgid "Direct DNS" +msgstr "直連 DNS" + +msgid "Direct DNS DoH" +msgstr "直連 DNS DoH" + +msgid "Direct DNS EDNS Client Subnet" +msgstr "直連 DNS EDNS Client Subnet" + +msgid "Remote DNS Protocol" +msgstr "é ç¨‹ DNS å”è­°" + +msgid "Remote DNS" +msgstr "é ç¨‹ DNS" + +msgid "Remote DNS DoH" +msgstr "é ç¨‹ DNS DoH" + +msgid "Remote DNS EDNS Client Subnet" +msgstr "é ç¨‹ DNS EDNS Client Subnet" + +msgid "Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address)." +msgstr "用於 DNS 查詢時通知 DNS æœå‹™å™¨ï¼Œå®¢æˆ¶ç«¯æ‰€åœ¨çš„地ç†ä½ç½®ï¼ˆä¸èƒ½æ˜¯ç§æœ‰ IP 地å€ï¼‰ã€‚" + +msgid "This feature requires the DNS server to support the Edns Client Subnet (RFC7871)." +msgstr "æ­¤åŠŸèƒ½éœ€è¦ DNS æœå‹™å™¨æ”¯æŒ EDNS Client Subnet(RFC7871)。" + +msgid "Remote DNS Outbound" +msgstr "é ç¨‹ DNS 出站" + +msgid "Remote" +msgstr "é ç¨‹" + +msgid "Direct" +msgstr "直連" + +msgid "Direct Query Strategy" +msgstr "直連查詢策略" + +msgid "Remote Query Strategy" +msgstr "é ç¨‹æŸ¥è©¢ç­–ç•¥" + +msgid "Use FakeDNS work in the domain that proxy." +msgstr "需è¦ä»£ç†çš„域å使用 FakeDNS。" + +msgid "Suitable scenarios for let the node servers get the target domain names." +msgstr "é©åˆè®“節點伺æœå™¨å–得目標網域的場景。" + +msgid "Such as: DNS unlocking of streaming media, reducing DNS query latency, etc." +msgstr "例如:æµåª’體的 DNS è§£éŽ–ã€æ¸›å°‘ DNS 查詢延é²ç­‰ã€‚" + +msgid "Domain Override" +msgstr "域åé‡å¯«" + +msgid "Direct DNS result write to IPSet" +msgstr "直連 DNS è§£æžçµæžœå¯«å…¥åˆ° IPSet" + +msgid "Perform the matching direct domain name rules into IP to IPSet/NFTSet, and then connect directly (not entering the core)." +msgstr "將匹é…到的直連è¦å‰‡çš„網域解æžIP寫入到 IPSet/NFTSet,然後直連(ä¸é€²å…¥æ ¸å¿ƒï¼‰ã€‚" + +msgid "Maybe conflict with some special circumstances." +msgstr "å¯èƒ½å’ŒæŸäº›ç‰¹æ®Šæƒ…æ³è¡çªã€‚" + +msgid "DNS Redirect" +msgstr "DNS é‡å®šå‘" + +msgid "Force special DNS server to need proxy devices." +msgstr "強制需è¦ä»£ç†çš„設備使用專用 DNS æœå‹™å™¨ã€‚" + +msgid "Clear IPSET" +msgstr "清空 IPSET" + +msgid "Clear NFTSET" +msgstr "清空 NFTSET" + +msgid "Try this feature if the rule modification does not take effect." +msgstr "如果修改è¦å‰‡å¾Œæ²’有生效,請嘗試此功能。" + +msgid "About DNS issues:" +msgstr "關於DNSå•題:" + +msgid "Some browsers may have built-in DNS, be sure to close. Example: Chrome. Settings - Security and Privacy - Security - Use secure DNS disabled." +msgstr "部分ç€è¦½å™¨å¯èƒ½æœ‰å…§ç½®çš„DNS,請務必關閉。如:chrome。 設置 - 安全和隱ç§è¨­ç½® - 使用安全 DNS 關閉。" + +msgid "Sometimes after restart, you can not internet. At this time, close all browsers (important), Windows Client, please `ipconfig /flushdns`. Please close the WiFi on the phone, cut the flight mode and then cut back." +msgstr "有時候é‡å•Ÿå¾Œï¼Œä¸Šä¸äº†ã€‚這時請先關閉所有ç€è¦½å™¨ï¼ˆé‡è¦ï¼‰ï¼ŒWindows客戶端請`ipconfig /flushdns`。手機端請關閉WIFI,切一下飛行模å¼å†åˆ‡å›žä¾†ã€‚" + +msgid "The client DNS and the default gateway must point to this router." +msgstr "客戶端DNS和默èªç¶²é—œå¿…é ˆæŒ‡å‘æœ¬è·¯ç”±å™¨ã€‚" + +msgid "If you have a wrong DNS process, the consequences are at your own risk!" +msgstr "如果你自行é…置了錯誤的DNSæµç¨‹ï¼Œå¾Œæžœè‡ªè´Ÿï¼" + +msgid "Hide menu method, input example in the address bar:" +msgstr "éš±è—èœå–®æ–¹æ³•ï¼Œåœ°å€æ è¼¸å…¥ä¾‹ï¼š" + +msgid "After the hidden to the display, input example in the address bar:" +msgstr "ç•¶ä½ éš±è—å¾Œæƒ³å†æ¬¡é¡¯ç¤ºï¼Œåœ°å€æ è¼¸å…¥ä¾‹ï¼š" + +msgid "Are you sure to hide?" +msgstr "你確定è¦éš±è—å—?" + +msgid "DNS related issues:" +msgstr "DNS相關å•題:" + +msgid "Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off." +msgstr "æŸäº›ç€è¦½å™¨å¦‚Chrome等內置此功能,這会影響設置的DNSè§£æžã€‚您å¯ä»¥é€²å…¥ '設置->ç§éš±å’Œå®‰å…¨->使用安全DNS' èœå–®,將其關閉。" + +msgid "If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):" +msgstr "如果在é‡å•Ÿå¾Œç„¡æ³•上網,請嘗試清除终端設備的缓存(先關閉所有正在使用的ç€è¦½å™¨æ‡‰ç”¨ç¨‹åºï¼Œé€™ä¸€æ­¥å°¤å…¶é‡è¦ï¼‰ï¼š" + +msgid "For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'." +msgstr "å°æ–¼Windows系統,請在命令æç¤ºç¬¦ä¸­é‹è¡Œå‘½ä»¤ 'ipconfig /flushdns'." + +msgid "For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'." +msgstr "å°æ–¼Mac系統,在终端中é‹è¡Œå‘½ä»¤ 'sudo killall -HUP mDNSResponder'." + +msgid "For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi." +msgstr "å°æ–¼ç§»å‹•設備,å¯é€šéŽé‡æ–°æŽ¥å…¥ç¶²çµ¡çš„æ–¹å¼æ¸…除。比如開關一次飛行模å¼,釿–°é€£æŽ¥WiFi。" + +msgid "Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed." +msgstr "è«‹ç¢ºèªæ‚¨è¨­å‚™çš„網絡設置,客戶端DNSæœå‹™å™¨å’Œé»˜èªç¶²é—œæ‡‰å‡æŒ‡å‘本路由器,以確ä¿DNS查詢正確路由。" + +msgid "Browser access:" +msgstr "ç€è¦½å™¨è¨ªå•:" + +msgid "Hide in main menu:" +msgstr "在主èœå–®ä¸­éš±è—:" + +msgid "Show in main menu:" +msgstr "在主èœå–®ä¸­é¡¯ç¤ºï¼š" + +msgid "DNS Export Of Multi WAN" +msgstr "国內DNS指定解æžå‡ºå£" + +msgid "Node Export Of Multi WAN" +msgstr "節點指定出å£" + +msgid "Only support Multi Wan." +msgstr "åªæœ‰å¤šç·šæŽ¥å…¥æ‰æœ‰æ•ˆã€‚" + +msgid "Not Specify" +msgstr "䏿Œ‡å®š" + +msgid "custom" +msgstr "自定义" + +msgid "If not available, try clearing the cache." +msgstr "如果無法使用,請嘗試清除缓存。" + +msgid "Operation" +msgstr "æ“作" + +msgid "Add Node" +msgstr "添加節點" + +msgid "Add the node via the link" +msgstr "通éŽéˆæŽ¥æ·»åŠ ç¯€é»ž" + +msgid "Enter share links, one per line. Subscription links are not supported!" +msgstr "è¼¸å…¥åˆ†äº«éˆæŽ¥ï¼Œæ”¯æŒå¤šå€‹ç¯€é»žï¼Œæ¯è¡Œä¸€å€‹ã€‚è«‹å‹¿è¼¸å…¥è¨‚é–±éˆæŽ¥ï¼" + +msgid "Please enter the correct link." +msgstr "è«‹è¼¸å…¥æ­£ç¢ºçš„éˆæŽ¥ã€‚" + +msgid "Clear all nodes" +msgstr "清空所有節點" + +msgid "Are you sure to clear all nodes?" +msgstr "ä½ ç¢ºå®šè¦æ¸…空所有節點å—?" + +msgid "Success" +msgstr "æˆåŠŸ" + +msgid "Error" +msgstr "錯誤" + +msgid "Delete select nodes" +msgstr "åˆªé™¤é¸æ‹©çš„節點" + +msgid "To Top" +msgstr "置顶" + +msgid "Select" +msgstr "鏿‹©" + +msgid "Selected:" +msgstr "å·²é¸ï¼š" + +msgid "DeSelect" +msgstr "åé¸" + +msgid "Select all" +msgstr "å…¨é¸" + +msgid "DeSelect all" +msgstr "å…¨ä¸é¸" + +msgid "Are you sure to delete select nodes?" +msgstr "你確定è¦åˆªé™¤é¸æ‹©çš„節點å—?" + +msgid "You no select nodes !" +msgstr "ä½ æ²’æœ‰é¸æ‹©ä»»ä½•節點ï¼" + +msgid "Are you sure set to" +msgstr "你確定è¦è¨­ç‚º" + +msgid "the server?" +msgstr "æœå‹™å™¨å—?" + +msgid "You choose node is:" +msgstr "你鏿‹©çš„節點是:" + +msgid "Timeout" +msgstr "超時" + +msgid "Node Remarks" +msgstr "節點備注" + +msgid "Add Mode" +msgstr "添加方å¼" + +msgid "Save Order" +msgstr "儲存當å‰é †åº" + +msgid "Saved current page order successfully." +msgstr "儲存目å‰é é¢é †åºæˆåŠŸã€‚" + +msgid "Drag to reorder" +msgstr "æ‹–æ›³ä»¥é‡æŽ’" + +msgid "Type" +msgstr "類型" + +msgid "_balancing" +msgstr "負載å‡è¡¡" + +msgid "_shunt" +msgstr "分æµ" + +msgid "Balancing" +msgstr "負載å‡è¡¡" + +msgid "Node Addition Method" +msgstr "節點新增方å¼" + +msgid "Manual" +msgstr "手動" + +msgid "Batch" +msgstr "批é‡" + +msgid "Select Group" +msgstr "鏿“‡åˆ†çµ„" + +msgid "Node Matching Rules" +msgstr "節點匹é…è¦å‰‡" + +msgid "" +"Example: ^A && B && !C && D$
" +"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
" +"Conditions are joined by &&, and their order does not affect the result." +msgstr "" +"示例:^A && B && !C && D$
" +"è¡¨ç¤ºç¯€é»žå‚™è¨»éœ€åŒæ™‚滿足:以 A 開頭(^)ã€åŒ…å« Bã€ä¸åŒ…å« C(!)ã€ä¸¦ä»¥ D çµå°¾ï¼ˆ$)。
" +"多個æ¢ä»¶ä½¿ç”¨ && 連接,æ¢ä»¶é †åºä¸å½±éŸ¿çµæžœã€‚" + +msgid "Balancing Strategy" +msgstr "負載å‡è¡¡ç­–ç•¥" + +msgid "Fallback Node" +msgstr "後備節點" + +msgid "Use Custom Probe URL" +msgstr "使用自定义探測網å€" + +msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL." +msgstr "默èªä½¿ç”¨å…§ç½®çš„æŽ¢æ¸¬ç¶²å€ï¼Œå•Ÿç”¨æ­¤é¸é …以使用自定义探測網å€ã€‚" + +msgid "Probe URL" +msgstr "探測網å€" + +msgid "The URL used to detect the connection status." +msgstr "用於檢測連接状態的網å€ã€‚" + +msgid "Probe Interval" +msgstr "探測間隔" + +msgid "The interval between initiating probes." +msgstr "發起探測的間隔。" + +msgid "The time format is numbers + units, such as '10s', '2h45m', and the supported time units are s, m, h, which correspond to seconds, minutes, and hours, respectively." +msgstr "時間格å¼ç‚ºæ•¸å­—+å–®ä½ï¼Œæ¯”如"10s", "2h45m",支æŒçš„æ™‚間單使œ‰ s,m,hï¼Œåˆ†åˆ«å°æ‡‰ç§’ã€åˆ†ã€æ™‚。" + +msgid "When the unit is not filled in, it defaults to seconds." +msgstr "æœªå¡«å¯«å–®ä½æ™‚,默èªç‚ºç§’。" + +msgid "Preferred Node Count" +msgstr "優é¸ç¯€é»žæ•¸é‡" + +msgid "The load balancer selects the optimal number of nodes, and traffic is randomly distributed among them." +msgstr "負載å‡è¡¡å™¨é¸å‡ºæœ€å„ªç¯€é»žçš„個數,æµé‡å°‡åœ¨é€™å‡ å€‹ç¯€é»žä¸­éšæ©Ÿåˆ†é…。" + +msgid "Failure Tolerance (%)" +msgstr "測速失敗率容å¿åº¦ï¼ˆ%)" + +msgid "The maximum acceptable speed test failure rate. For example, 1 means allowing a 1% failure rate." +msgstr "æœ€å¤šå¯æŽ¥å—的測速失敗率,例如 1 表示å…許 1% 的測速失敗率。" + +msgid "Shunt" +msgstr "分æµ" + +msgid "Preproxy" +msgstr "å‰ç½®ä»£ç†" + +msgid "Preproxy Node" +msgstr "å‰ç½®ä»£ç†ç¯€é»ž" + +msgid "Set the node to be used as a pre-proxy." +msgstr "設置用作å‰ç½®ä»£ç†çš„節點。" + +msgid "Each rule has a separate switch that controls whether this rule uses the pre-proxy or not." +msgstr "æ¯æ¡è¦å‰‡éƒ½æœ‰ç‹¬ç«‹é–‹é—œæŽ§åˆ¶æœ¬è¦å‰‡æ˜¯å¦ä½¿ç”¨å‰ç½®ä»£ç†ã€‚" + +msgid "Close (Not use)" +msgstr "關閉 (ä¸ä½¿ç”¨)" + +msgid "Use default node" +msgstr "使用默èªç¯€é»ž" + +msgid "Direct Connection" +msgstr "直連" + +msgid "Blackhole (Block)" +msgstr "黑洞(å±è”½ï¼‰" + +msgid "There are no available nodes, please add or subscribe nodes first." +msgstr "沒有å¯ç”¨ç¯€é»žï¼Œè«‹å…ˆæ·»åŠ æˆ–è¨‚é–±ç¯€é»žã€‚" + +msgid "No shunt rules? Click me to go to add." +msgstr "沒有分æµè¦å‰‡ï¼Ÿé»žæˆ‘å‰å¾€åŽ»æ·»åŠ ã€‚" + +msgid "When using, localhost will connect this node first and then use this node to connect the default node." +msgstr "當使用時,本機將首先連接到此節點,然後å†ä½¿ç”¨æ­¤ç¯€é»žé€£æŽ¥åˆ°é»˜èªç¯€é»žè½åœ°ã€‚" + +msgid "Domain Strategy" +msgstr "域åè§£æžç­–ç•¥" + +msgid "Domain matcher" +msgstr "域å匹é…算法" + +msgid "'AsIs': Only use domain for routing. Default value." +msgstr "AsIs:åªä½¿ç”¨åŸŸåè¿›è¡Œè·¯ç”±é¸æ‹©ã€‚默èªå€¼ã€‚" + +msgid "'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again." +msgstr "IPIfNonMatchï¼šç•¶åŸŸåæ²’有匹é…任何è¦å‰‡æ™‚,將域åè§£æžæˆ IP(A 記錄或 AAAA è¨˜éŒ„ï¼‰å†æ¬¡è¿›è¡ŒåŒ¹é…。" + +msgid "'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately." +msgstr "IPOnDemandï¼šç•¶åŒ¹é…æ™‚碰到任何基於 IP çš„è¦å‰‡ï¼Œå°‡åŸŸåç«‹å³è§£æžç‚º IP 进行匹é…。" + +msgid "Load balancing node list" +msgstr "負載å‡è¡¡ç¯€é»žåˆ—表" + +msgid "Load balancing node list, document" +msgstr "負載å‡è¡¡ç¯€é»žåˆ—表,文檔原ç†" + +msgid "From Share URL" +msgstr "導入分享URL" + +msgid "Build Share URL" +msgstr "導出分享URL" + +msgid "Generate QRCode" +msgstr "生æˆäºŒç»´ç " + +msgid "Export Config File" +msgstr "導出é…置文件" + +msgid "Import Finished" +msgstr "導入完æˆï¼š" + +msgid "Not a supported scheme:" +msgstr "䏿”¯æŒé€™ç§æ¨£å¼çš„:" + +msgid "Invalid Share URL Format" +msgstr "無效的分享URLä¿¡æ¯" + +msgid "Paste Share URL Here" +msgstr "在此处粘贴分享信æ¯" + +msgid "Share URL to clipboard unable." +msgstr "無法分享URL到剪贴æ¿ã€‚" + +msgid "Share URL to clipboard successfully." +msgstr "æˆåŠŸå¾©åˆ¶åˆ†äº«URL到剪贴æ¿ã€‚" + +msgid "Faltal on get option, please help in debug:" +msgstr "代ç éŒ¯èª¤ï¼Œè«‹å”助æ‰èŸ²ï¼š" + +msgid "Faltal on set option, please help in debug:" +msgstr "代ç éŒ¯èª¤ï¼Œè«‹å”助æ‰èŸ²ï¼š" + +msgid "Address" +msgstr "地å€" + +msgid "Address (Support Domain Name)" +msgstr "地å€ï¼ˆæ”¯æŒåŸŸå)" + +msgid "Trojan Verify Cert" +msgstr "驗證證書" + +msgid "Trojan Cert Path" +msgstr "證書路径" + +msgid "Finger Print" +msgstr "指紋伪造" + +msgid "Avoid using randomized, unless you have to." +msgstr "é¿å…使用 randomized , 除éžä½ å¿…é ˆè¦ã€‚" + +msgid "Original" +msgstr "原版" + +msgid "Transport Plugin" +msgstr "傳輸層æ’ä»¶" + +msgid "Obfs Type" +msgstr "混淆類型" + +msgid "Obfs Password" +msgstr "混淆密碼" + +msgid "Auth Type" +msgstr "èªè­‰é¡žåž‹" + +msgid "Auth Password" +msgstr "èªè­‰å¯†ç¢¼" + +msgid "Client BBR Flow Control" +msgstr "客戶端 BBR æµæŽ§" + +msgid "Commands the client to use the BBR flow control algorithm" +msgstr "命令客戶端使用 BBR æµé‡æŽ§åˆ¶ç®—法" + +msgid "PinSHA256" +msgstr "PinSHA256" + +msgid "Certificate fingerprint" +msgstr "證書指紋" + +msgid "Max upload Mbps" +msgstr "最大上行(Mbps)" + +msgid "Max download Mbps" +msgstr "最大下行(Mbps)" + +msgid "QUIC stream receive window" +msgstr "QUIC æµæŽ¥æ”¶çª—å£" + +msgid "QUIC connection receive window" +msgstr "QUIC 連接接收窗å£" + +msgid "QUIC concurrent bidirectional streams" +msgstr "QUIC 並發åŒå‘æµçš„æœ€å¤§æ•¸é‡" + +msgid "QUIC KeepAlive interval" +msgstr "QUIC KeepAlive é–“éš”" + +msgid "Disable MTU detection" +msgstr "ç¦ç”¨ MTU 檢測" + +msgid "ignoreClientBandwidth" +msgstr "忽略客戶端帶宽設置" + +msgid "Lazy Start" +msgstr "延迟啟動" + +msgid "Encrypt Method" +msgstr "加密方å¼" + +msgid "Encrypt Key" +msgstr "加密密鑰" + +msgid "Latency" +msgstr "延迟" + +msgid "Automatic detection delay" +msgstr "自動檢測延迟" + +msgid "Show server address and port" +msgstr "顯示æœå‹™å™¨åœ°å€å’Œç«¯å£" + +msgid "URL Test Address" +msgstr "URL 測試地å€" + +msgid "URL Test" +msgstr "URL 測試" + +msgid "Test" +msgstr "測試" + +msgid "Node num" +msgstr "節點數é‡" + +msgid "Self add" +msgstr "自添" + +msgid "Apply" +msgstr "應用" + +msgid "Use" +msgstr "使用" + +msgid "Copy" +msgstr "復制" + +msgid "Delay Settings" +msgstr "定時é…ç½®" + +msgid "Open and close Daemon" +msgstr "啟動守護進程" + +msgid "Delay Start" +msgstr "開機時延時啟動" + +msgid "Units:seconds" +msgstr "å–®ä½ï¼šç§’" + +msgid "Units:minutes" +msgstr "å–®ä½ï¼šåˆ†é˜" + +msgid "stop automatically mode" +msgstr "定時關閉模å¼" + +msgid "stop Time(Every day)" +msgstr "關閉時間(æ¯å¤©)" + +msgid "stop Interval(Hour)" +msgstr "關閉間隔(å°æ™‚)" + +msgid "start automatically mode" +msgstr "定時開啟模å¼" + +msgid "start Time(Every day)" +msgstr "開啟時間(æ¯å¤©)" + +msgid "start Interval(Hour)" +msgstr "開啟間隔(å°æ™‚)" + +msgid "restart automatically mode" +msgstr "定時é‡å•Ÿæ¨¡å¼" + +msgid "restart Time(Every day)" +msgstr "é‡å•Ÿæ™‚é–“(æ¯å¤©)" + +msgid "restart Interval(Hour)" +msgstr "é‡å•Ÿé–“éš”(å°æ™‚)" + +msgid "Forwarding Settings" +msgstr "转發é…ç½®" + +msgid "TCP No Redir Ports" +msgstr "TCPä¸è½¬ç™¼ç«¯å£" + +msgid "UDP No Redir Ports" +msgstr "UDPä¸è½¬ç™¼ç«¯å£" + +msgid "Fill in the ports you don't want to be forwarded by the agent, with the highest priority." +msgstr "填寫你ä¸å¸Œæœ›è¢«ä»£ç†è½¬ç™¼çš„端å£ï¼Œå„ªå…ˆç´šæœ€é«˜ã€‚" + +msgid "If you don't want to let the device in the list to go proxy, please choose all." +msgstr "å¦‚æžœæ‚¨ä¸æƒ³è®©åˆ—表中的設備走代ç†ï¼Œè«‹é¸æ‹©å…¨éƒ¨ã€‚" + +msgid "The port settings support single ports and ranges.
Separate multiple ports with commas (,).
Example: 21,80,443,1000:2000." +msgstr "以上端å£è¨­ç½®æ”¯æŒå–®ç«¯å£å’Œç«¯å£ç¯„åœã€‚
多個端å£ç”¨è‹±æ–‡é€—å·(,)隔開。
例:21,80,443,1000:2000。" + +msgid "TCP Proxy Drop Ports" +msgstr "TCP转發å±è”½ç«¯å£" + +msgid "UDP Proxy Drop Ports" +msgstr "UDP转發å±è”½ç«¯å£" + +msgid "TCP Redir Ports" +msgstr "TCP转發端å£" + +msgid "UDP Redir Ports" +msgstr "UDP转發端å£" + +msgid "No patterns are used" +msgstr "ä¸ä½¿ç”¨" + +msgid "All" +msgstr "所有" + +msgid "Common Use" +msgstr "常用的" + +msgid "Only Web" +msgstr "ä»…ç¶²é " + +msgid "or more" +msgstr "åŠä»¥ä¸Š" + +msgid "or less" +msgstr "åŠä»¥ä¸‹" + +msgid "Default" +msgstr "默èª" + +msgid "Close" +msgstr "關閉" + +msgid "Hijacking ICMP (PING)" +msgstr "劫æŒICMP (PING)" + +msgid "Hijacking ICMPv6 (IPv6 PING)" +msgstr "劫æŒICMPv6 (IPv6 PING)" + +msgid "Force Proxy LAN IP" +msgstr "強制代ç†å…§ç¶²IP段" + +msgid "By default, commonly used internal network IP ranges will be connect directly (not entering the core). If you want a certain network range to go through a proxy, please add it here." +msgstr "é è¨­æƒ…æ³ä¸‹ï¼Œå¸¸ç”¨å…§ç¶²IP網段將直連(ä¸é€²å…¥æ ¸å¿ƒï¼‰ï¼Œå¦‚果你希望æŸå€‹ç¶²æ®µèµ°ä»£ç†ï¼Œè«‹åœ¨æ­¤æ–°å¢žã€‚" + +msgid "Sniffing" +msgstr "æµé‡å—…探" + +msgid "TCP Proxy Way" +msgstr "TCPä»£ç†æ–¹å¼" + +msgid "Auto Switch" +msgstr "自動切æ›" + +msgid "When there is no server, an automatic reconnect scheme is used" +msgstr "當沒有æœå‹™å™¨æ™‚,則使用自動é‡é€£æ–¹æ¡ˆ" + +msgid "How often to test" +msgstr "多久檢測一次" + +msgid "Timeout seconds" +msgstr "超時秒數" + +msgid "Timeout retry num" +msgstr "超時é‡è©¦æ¬¡æ•¸" + +msgid "Automatic switching cannot be used when this option is checked" +msgstr "ç•¶å‹¾é¸æ­¤é¸é …時,ä¸èƒ½ä½¿ç”¨è‡ªå‹•切æ›" + +msgid "Main node" +msgstr "主節點" + +msgid "List of backup nodes" +msgstr "備用節點的列表" + +msgid "Restore Switch" +msgstr "æ¢å¾©åˆ‡æ›" + +msgid "When detects main node is available, switch back to the main node." +msgstr "當檢測到主節點å¯ç”¨æ™‚,切æ›å›žä¸»ç¯€é»žã€‚" + +msgid "Add nodes to the standby node list by keywords" +msgstr "通éŽé—œé”®å­—添加節點到備用節點列表" + +msgid "Delete nodes in the standby node list by keywords" +msgstr "通éŽé—œé”®å­—刪除備用節點列表的節點" + +msgid "Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase." +msgstr "請輸入節點關键字,注æ„区分空格ã€å¤§å¯«å’Œå°å¯«ã€‚" + +msgid "Enable Load Balancing" +msgstr "開啟負載å‡è¡¡" + +msgid "Console Login Auth" +msgstr "控制臺登錄èªè­‰" + +msgid "Console Username" +msgstr "控制臺账å·" + +msgid "Console Password" +msgstr "控制臺密碼" + +msgid "Console Port" +msgstr "控制臺端å£" + +msgid "In the browser input routing IP plus port access, such as:192.168.1.1:1188" +msgstr "在ç€è¦½å™¨è¼¸å…¥è·¯ç”±IP加端å£è¨ªå•,如:192.168.1.1:1188" + +msgid "Haproxy Port" +msgstr "負載å‡è¡¡ç«¯å£" + +msgid "Health Check Type" +msgstr "å¥åº·æª¢æŸ¥é¡žåž‹" + +msgid "Inner implement" +msgstr "內置實现" + +msgid "Health Check Inter" +msgstr "å¥åº·æª¢æŸ¥ç¯€é»žé–“隔時間" + +msgid "When the URL test is used, the load balancing node will be converted into a Socks node. when node list set customizing, must be a Socks node, otherwise the health check will be invalid." +msgstr "當使用URL測試時,負載å‡è¡¡ç¯€é»žå°‡è½¬æ›æˆSocks節點。下é¢çš„節點列表自定义時必須為Socks節點,å¦å‰‡å¥åº·æª¢æŸ¥å°‡ç„¡æ•ˆã€‚" + +msgid "Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group." +msgstr "添加節點,指定出å£åŠŸèƒ½æ˜¯ç‚ºå¤šWAN用戶准備的。負載比é‡ç¯„åœ1-256。多個主æœå‹™å™¨å¯ä»¥è² è¼‰å‡è¡¡ï¼Œå‚™ç”¨åªæœ‰åœ¨ä¸»æœå‹™å™¨ç¦»ç·šæ™‚æ‰ä¼šå•Ÿç”¨ï¼å¯ä»¥è¨­ç½®å¤šå€‹ç»„,負載å‡è¡¡ç«¯å£ç›¸åŒå‰‡ç‚ºä¸€ç»„。" + +msgid "Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!" +msgstr "注æ„,當使用TCPå¥åº·æª¢æŸ¥æ™‚負載å‡è¡¡çš„節點é…ç½®åƒæ•¸å¿…須一致,å¦å‰‡ç„¡æ³•正常使用ï¼" + +msgid "Node Address" +msgstr "節點地å€" + +msgid "Node address cannot be empty." +msgstr "節點地å€ä¸èƒ½ç‚ºç©ºã€‚" + +msgid "Node Port" +msgstr "節點端å£" + +msgid "Node Weight" +msgstr "負載比é‡" + +msgid "Export Of Multi WAN" +msgstr "多WAN指定出å£" + +msgid "Main" +msgstr "主è¦" + +msgid "Mode" +msgstr "模å¼" + +msgid "Primary" +msgstr "主è¦" + +msgid "Standby" +msgstr "備用" + +msgid "Check update" +msgstr "檢查更新" + +msgid "Force update" +msgstr "強制更新" + +msgid "The latest version: %s, currently does not support automatic update, if you need to update, please compile or download the ipk and then manually install." +msgstr "最新版本:%sï¼Œç›®å‰æš«ä¸æ”¯æŒè‡ªå‹•更新,如需更新,請自行编译或下載ipk然後手動安装。" + +msgid "Enable custom URL" +msgstr "啟用自定义è¦å‰‡åœ°å€" + +msgid "Rule status" +msgstr "è¦å‰‡ç‰ˆæœ¬" + +msgid "Manually update" +msgstr "手動更新" + +msgid "Rollback" +msgstr "回滾" + +msgid "Rollbacking..." +msgstr "回滾中..." + +msgid "Enable auto update rules" +msgstr "開啟自動更新è¦å‰‡" + +msgid "Update Time(every day)" +msgstr "更新時間(æ¯å¤©)" + +msgid "Update Interval(hour)" +msgstr "æ›´æ–°é–“éš”(å°æ™‚)" + +msgid "Update Mode" +msgstr "更新模å¼" + +msgid "Loop Mode" +msgstr "循环" + +msgid "Every day" +msgstr "æ¯å¤©" + +msgid "Every Monday" +msgstr "æ¯å‘¨ä¸€" + +msgid "Every Tuesday" +msgstr "æ¯å‘¨äºŒ" + +msgid "Every Wednesday" +msgstr "æ¯å‘¨ä¸‰" + +msgid "Every Thursday" +msgstr "æ¯å‘¨å››" + +msgid "Every Friday" +msgstr "æ¯å‘¨äº”" + +msgid "Every Saturday" +msgstr "æ¯å‘¨å…­" + +msgid "Every Sunday" +msgstr "æ¯å‘¨æ—¥" + +msgid "hour" +msgstr "å°æ™‚" + +msgid "Hour" +msgstr "å°æ™‚" + +msgid "GeoIP Update URL" +msgstr "GeoIP æ›´æ–° URL" + +msgid "Geosite Update URL" +msgstr "Geosite æ›´æ–° URL" + +msgid "Location of Geo rule files" +msgstr "Geo èµ„æºæ–‡ä»¶ç›®éŒ„" + +msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." +msgstr "æ­¤è®Šé‡æŒ‡å®šgeoip.datå’Œgeosite.dat文件所在的目錄。" + +msgid "Enable GeoIP Data Parsing" +msgstr "開啟 GeoIP 數æ®è§£æž" + +msgid "Analyzes and preloads GeoIP data to enhance the shunt performance." +msgstr "分æžå’Œé¢„加载 GeoIP 數æ®ï¼Œä»¥å¢žå¼·åˆ†æµæ•ˆæžœã€‚" + +msgid "Note: Increases resource usage." +msgstr "注:会增加一些系統资æºçš„開销。" + +msgid "Shunt Rule" +msgstr "分æµè¦å‰‡" + +msgid "Please note attention to the priority, the higher the order, the higher the priority." +msgstr "請注æ„優先級å•題,排åºè¶Šä¸Šé¢å„ªå…ˆç´šè¶Šé«˜ã€‚" + +msgid "Update..." +msgstr "更新中" + +msgid "It is the latest version" +msgstr "已是最新版本" + +msgid "Update successful" +msgstr "æ›´æ–°æˆåŠŸ" + +msgid "Click to update" +msgstr "點击更新" + +msgid "Updating..." +msgstr "更新中" + +msgid "Retry" +msgstr "é‡è©¦" + +msgid "Unexpected error" +msgstr "æ„外錯誤" + +msgid "Updating, are you sure to close?" +msgstr "正在更新,你確èªè¦é—œé–‰å—?" + +msgid "Downloading..." +msgstr "下載中" + +msgid "Unpacking..." +msgstr "解压中" + +msgid "Moving..." +msgstr "移動中" + +msgid "App Update" +msgstr "组件更新" + +msgid "Please confirm that your firmware supports FPU." +msgstr "請確èªä½ çš„固件支æŒFPU。" + +msgid "if you want to run from memory, change the path, /tmp beginning then save the application and update it manually." +msgstr "如果你希望从內存中é‹è¡Œï¼Œè«‹æ›´æ”¹è·¯å¾„,/tmp 開头,然後ä¿å­˜æ‡‰ç”¨å¾Œï¼Œå†æ‰‹å‹•更新。" + +msgid "Make sure there is enough space to install %s" +msgstr "ç¢ºä¿æœ‰è¶³å¤Ÿçš„空間安装 %s" + +msgid "App Path" +msgstr "程åºè·¯å¾„" + +msgid "%s App Path" +msgstr "%s 程åºè·¯å¾„" + +msgid "%s Client App Path" +msgstr "%s 客戶端程åºè·¯å¾„" + +msgid "Node Subscribe" +msgstr "節點訂閱" + +msgid "Subscribe Remark" +msgstr "訂閱備注(機场)" + +msgid "Subscribe Info" +msgstr "訂閱信æ¯" + +msgid "Subscribe URL" +msgstr "訂閱網å€" + +msgid "Subscribe URL Access Method" +msgstr "訂閱網å€è¨ªå•æ–¹å¼" + +msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically." +msgstr "新增訂閱請先ä¿å­˜ä¸¦æ‡‰ç”¨å¾Œå†æ‰‹å‹•訂閱;如仅修改訂閱地å€ï¼Œå¯ç›´æŽ¥æ‰‹å‹•訂閱,系統將自動ä¿å­˜ã€‚" + +msgid "Please save and apply before manually subscribing." +msgstr "è«‹å…ˆä¿å­˜ä¸¦æ‡‰ç”¨å¾Œå†æ‰‹å‹•訂閱。" + +msgid "Subscribe URL cannot be empty." +msgstr "訂閱網å€ä¸èƒ½ç‚ºç©ºã€‚" + +msgid "Subscribe via proxy" +msgstr "通éŽä»£ç†è¨‚é–±" + +msgid "Update Once on Boot" +msgstr "開機更新一次" + +msgid "Updates the subscription the first time runs automatically after each system boot." +msgstr "è·¯ç”±æ¯æ¬¡å•Ÿå‹•後,首次自動執行時更新訂閱。" + +msgid "Enable auto update subscribe" +msgstr "開啟自動更新訂閱" + +msgid "Manual subscription" +msgstr "手動訂閱" + +msgid "Delete All Subscribe Node" +msgstr "刪除所有訂閱節點" + +msgid "Delete the subscribed node" +msgstr "刪除已訂閱的節點" + +msgid "Are you sure you want to delete all subscribed nodes?" +msgstr "您確定è¦åˆªé™¤æ‰€æœ‰å·²è¨‚閱的節點å—?" + +msgid "Manual subscription All" +msgstr "æ‰‹å‹•è¨‚é–±å…¨éƒ¨éˆæŽ¥" + +msgid "This remark already exists, please change a new remark." +msgstr "此備注已存在,請改一個新的備注。" + +msgid "Remark cannot be empty." +msgstr "備注ä¸èƒ½çˆ²ç©ºã€‚" + +msgid "URL cannot be empty." +msgstr "ç¶²å€ä¸èƒ½çˆ²ç©ºã€‚" + +msgid "Filter keyword Mode" +msgstr "éŽæ¿¾é—œé”®å­—模å¼" + +msgid "Discard List" +msgstr "丟棄列表" + +msgid "Keep List" +msgstr "ä¿ç•™åˆ—表" + +msgid "Discard List,But Keep List First" +msgstr "丟棄列表,但ä¿ç•™åˆ—表優先" + +msgid "Keep List,But Discard List First" +msgstr "ä¿ç•™åˆ—表,但丟棄列表優先" + +msgid "Use global config" +msgstr "使用全局é…ç½®" + +msgid "User-Agent" +msgstr "用戶代ç†(User-Agent)" + +msgid "Add" +msgstr "添加" + +msgid "ACLs" +msgstr "è¨ªå•æŽ§åˆ¶" + +msgid "ACLs is a tools which used to designate specific IP proxy mode." +msgstr "è¨ªå•æŽ§åˆ¶åˆ—è¡¨æ˜¯ç”¨æ–¼æŒ‡å®šç‰¹æ®ŠIPä»£ç†æ¨¡å¼çš„工具。" + +msgid "Example:" +msgstr "例:" + +msgid "IP range" +msgstr "IP 範åœ" + +msgid "Source Interface" +msgstr "æºæŽ¥å£" + +msgid "Bridge" +msgstr "網橋" + +msgid "Wireless Adapter" +msgstr "ç„¡ç·šé©é…器" + +msgid "Ethernet Adapter" +msgstr "乙太網é©é…器" + +msgid "Tunnel Interface" +msgstr "éš§é“介é¢" + +msgid "Invalid interface name" +msgstr "無效的介é¢å稱" + +msgid "Use Interface With ACLs" +msgstr "ä½¿ç”¨æŽ¥å£æŽ§åˆ¶" + +msgid "Remarks" +msgstr "備注" + +msgid "Direct List" +msgstr "直連列表" + +msgid "Proxy List" +msgstr "代ç†åˆ—表" + +msgid "Block List" +msgstr "å±è”½åˆ—表" + +msgid "Lan IP List" +msgstr "局域網IP列表" + +msgid "Route Hosts" +msgstr "路由Hosts文件" + +msgid "Join the direct hosts list of domain names will not proxy." +msgstr "加入的域åä¸èµ°ä»£ç†ï¼Œå°æ‰€æœ‰æ¨¡å¼æœ‰æ•ˆã€‚且優先級最高。" + +msgid "These had been joined ip addresses will not proxy. Please input the ip address or ip address segment,every line can input only one ip address. For example: 192.168.0.0/24 or 223.5.5.5." +msgstr "加入的IP段ä¸èµ°ä»£ç†ï¼Œå°æ‰€æœ‰æ¨¡å¼æœ‰æ•ˆã€‚且優先級最高。å¯è¼¸å…¥IPåœ°å€æˆ–åœ°å€æ®µï¼Œå¦‚:192.168.0.0/24或223.5.5.5,æ¯å€‹åœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined websites will use proxy. Please input the domain names of websites, every line can input only one website domain. For example: google.com." +msgstr "加入的域å將走代ç†ã€‚輸入網站域å,如:google.com,æ¯å€‹åœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined ip addresses will use proxy. Please input the ip address or ip address segment, every line can input only one ip address. For example: 35.24.0.0/24 or 8.8.4.4." +msgstr "加入的IP段將走代ç†ã€‚å¯è¼¸å…¥IPåœ°å€æˆ–åœ°å€æ®µï¼Œå¦‚:35.24.0.0/24或8.8.4.4,æ¯å€‹åœ°å€æ®µä¸€è¡Œã€‚" + +msgid "These had been joined websites will be block. Please input the domain names of websites, every line can input only one website domain. For example: twitter.com." +msgstr "加入的域åå°‡å±è”½ã€‚輸入網站域å,如:twitter.com,æ¯å€‹åœ°å€æ®µä¸€è¡Œã€‚" + +msgid "The list is the IPv4 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "列表中為IPv4的局域網IP列表,代表局域網直連IP。如果需è¦ä»£ç†åˆ—表中的局域網IP,請將其在该列表中清除,並將其添加到代ç†åˆ—è¡¨ä¸­ã€‚é»˜èªæƒ…æ³ä¸‹ä¸è¦ä¿®æ”¹é€™å€‹åˆ—表。" + +msgid "The list is the IPv6 LAN IP list, which represents the direct connection IP of the LAN. If you need the LAN IP in the proxy list, please clear it from the list. Do not modify this list by default." +msgstr "列表中為IPv6的局域網IP列表,代表局域網直連IP。如果需è¦ä»£ç†åˆ—表中的局域網IP,請將其在该列表中清除,並將其添加到代ç†åˆ—è¡¨ä¸­ã€‚é»˜èªæƒ…æ³ä¸‹ä¸è¦ä¿®æ”¹é€™å€‹åˆ—表。" + +msgid "Configure routing etc/hosts file, if you don't know what you are doing, please don't change the content." +msgstr "é…置路由etc/hosts文件,如果你ä¸çŸ¥é“自己在åšä»€éº¼ï¼Œè«‹ä¸è¦æ”¹å‹•內容。" + +msgid "These had been joined ip addresses will be block. Please input the ip address or ip address segment, every line can input only one ip address." +msgstr "加入的IP段將å±è”½ã€‚å¯è¼¸å…¥IPåœ°å€æˆ–åœ°å€æ®µï¼Œæ¯å€‹åœ°å€æ®µä¸€è¡Œã€‚" + +msgid "Inbound Tag" +msgstr "入站標签" + +msgid "Transparent proxy" +msgstr "逿˜Žä»£ç†" + +msgid "Not valid domain name, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆåŸŸåï¼Œè«‹é‡æ–°è¼¸å…¥ï¼" + +msgid "Not valid IP format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆIPæ ¼å¼ï¼Œè«‹é‡æ–°è¼¸å…¥ï¼" + +msgid "Not valid IPv4 format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆIPv4æ ¼å¼ï¼Œè«‹é‡æ–°è¼¸å…¥ï¼" + +msgid "Not valid IPv6 format, please re-enter!" +msgstr "䏿˜¯æœ‰æ•ˆIPv6æ ¼å¼ï¼Œè«‹é‡æ–°è¼¸å…¥ï¼" + +msgid "Not true format, please re-enter!" +msgstr "䏿˜¯æ­£ç¢ºçš„æ ¼å¼ï¼Œè«‹é‡æ–°è¼¸å…¥ï¼" + +msgid "Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'." +msgstr "純字符串: 當此字符串匹é…目標域å中任æ„部分,该è¦å‰‡ç”Ÿæ•ˆã€‚比如'sina.com'å¯ä»¥åŒ¹é…'sina.com'ã€'sina.com.cn'å’Œ'www.sina.com',但ä¸åŒ¹é…'sina.cn'。" + +msgid "Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'." +msgstr "正則表达å¼: ç”±'regexp:'開始,余下部分是一個正則表达å¼ã€‚當此正則表达å¼åŒ¹é…ç›®æ¨™åŸŸåæ™‚,该è¦å‰‡ç”Ÿæ•ˆã€‚例如'regexp:\\.goo.*\\.com$'匹é…'www.google.com'ã€'fonts.googleapis.com',但ä¸åŒ¹é…'google.com'。" + +msgid "Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'." +msgstr "å­åŸŸå (推è): ç”±'domain:'開始,余下部分是一個域åã€‚ç•¶æ­¤åŸŸåæ˜¯ç›®æ¨™åŸŸå或其å­åŸŸå時,该è¦å‰‡ç”Ÿæ•ˆã€‚例如'domain:v2ray.com'匹é…'www.v2ray.com'ã€'v2ray.com',但ä¸åŒ¹é…'xv2ray.com'。" + +msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'." +msgstr "完整匹é…: ç”±'full:'開始,余下部分是一個域å。當此域å完整匹é…ç›®æ¨™åŸŸåæ™‚,该è¦å‰‡ç”Ÿæ•ˆã€‚例如'full:v2ray.com'匹é…'v2ray.com'但ä¸åŒ¹é…'www.v2ray.com'。" + +msgid "Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'" +msgstr "Sing-Box è¦å‰‡é›†ï¼š ç”± 'rule-set:remote:' 或 'rule-set:local:' é–‹å§‹" + +msgid "Such as:" +msgstr "例如:" + +msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn." +msgstr "预定义域å列表:由'geosite:'開头,余下部分是一個å称,如geosite:google或者geosite:cn。" + +msgid "Annotation: Begining with #" +msgstr "注释: ç”± # 開头" + +msgid "Invert match result." +msgstr "åé¸åŒ¹é…çµæžœã€‚" + +msgid "Only support Sing-Box." +msgstr "åªæ”¯æŒ Sing-Box。" + +msgid "IP: such as '127.0.0.1'." +msgstr "IP: 形如'127.0.0.1'。" + +msgid "CIDR: such as '127.0.0.0/8'." +msgstr "CIDR: 形如'10.0.0.0/8'." + +msgid "GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code." +msgstr "GeoIP: 形如'geoip:cn',必須以geoip:(å°å¯«ï¼‰é–‹å¤´ï¼Œå¾Œé¢è·ŸåŒå­—符国家代ç ï¼Œæ”¯æŒå‡ ä¹Žæ‰€æœ‰å¯ä»¥ä¸Šç¶²çš„国家。" + +msgid "Clear logs" +msgstr "清空日誌" + +msgid "Password" +msgstr "密碼" + +msgid "IV Check" +msgstr "IV 檢查" + +msgid "UDP over TCP" +msgstr "TCP å°è£… UDP" + +msgid "Connection Timeout" +msgstr "連接超時時間" + +msgid "Local Port" +msgstr "本地端å£" + +msgid "Fast Open" +msgstr "快速打開" + +msgid "Pre-connections" +msgstr "é é€£æŽ¥" + +msgid "Number of early established connections to reduce latency." +msgstr "é é€£æŽ¥çš„æ•¸é‡ï¼Œç”¨æ–¼é™ä½Žå»¶é²ã€‚" + +msgid "plugin" +msgstr "æ’ä»¶" + +msgid "Supports custom SIP003 plugins, Make sure the plugin is installed." +msgstr "支æŒè‡ªå®šä¹‰ SIP003 æ’ä»¶ï¼Œè«‹ç¢ºä¿æ’件已安装。" + +msgid "opts" +msgstr "æ’ä»¶é¸é …" + +msgid "Protocol" +msgstr "å”è­°åç§°" + +msgid "Protocol_param" +msgstr "å”è­°åƒæ•¸" + +msgid "Obfs" +msgstr "æ··æ·†" + +msgid "Obfs_param" +msgstr "æ··æ·†åƒæ•¸" + +msgid "Plugin Name" +msgstr "æ’ä»¶åç§°" + +msgid "Plugin Arguments" +msgstr "æ’ä»¶åƒæ•¸" + +msgid "User Level" +msgstr "用戶等級(level)" + +msgid "Transport" +msgstr "傳輸方å¼" + +msgid "Public Key" +msgstr "公鑰" + +msgid "Private Key" +msgstr "ç§é‘°" + +msgid "Pre shared key" +msgstr "é¢å¤–çš„å°ç§°åР坆坆鑰" + +msgid "Local Address" +msgstr "本地地å€" + +msgid "System interface" +msgstr "系統接å£" + +msgid "System interface name" +msgstr "系統接å£åç§°" + +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "用“,â€éš”é–‹çš„å进制數字或 Base64 ç¼–ç å­—符串。" + +msgid "Camouflage Domain" +msgstr "伪装域å" + +msgid "Camouflage Type" +msgstr "伪装類型" + +msgid "Transport Layer Encryption" +msgstr "傳輸層加密" + +msgid "Whether or not transport layer encryption is enabled, \"none\" for unencrypted, \"tls\" for using TLS, \"xtls\" for using XTLS." +msgstr "是å¦å•Ÿå…¥å‚³è¼¸å±¤åŠ å¯†ï¼Œæ”¯æŒçš„é¸é …有 \"none\" 表示ä¸åŠ å¯†ï¼Œ\"tls\" 表示使用 TLS,\"xtls\" 表示使用 XTLS。" + +msgid "Original Trojan only supported 'tls', please choose 'tls'." +msgstr "原版Trojanåªæ”¯æŒ'tls'ï¼Œè«‹é¸æ‹©'tls'。" + +msgid "Transfer mode" +msgstr "傳輸模å¼" + +msgid "Do not send server name in ClientHello." +msgstr "ä¸è¦åœ¨ ClientHello ä¸­ç™¼é€æœå‹™å™¨åç§°." + +msgid "Domain" +msgstr "域å" + +msgid "allowInsecure" +msgstr "å…許ä¸å®‰å…¨é€£æŽ¥" + +msgid "Whether unsafe connections are allowed. When checked, Certificate validation will be skipped." +msgstr "是å¦å…許ä¸å®‰å…¨é€£æŽ¥ã€‚ç•¶å‹¾é¸æ™‚,將跳éŽè­‰æ›¸é©—證。" + +msgid "Used when the node link does not include this parameter." +msgstr "ç•¶ç¯€é»žé€£çµæœªåŒ…å«è©²åƒæ•¸æ™‚,將使用此設定。" + +msgid "%s Node Use Type" +msgstr "%s 節點使用類型" + +msgid "UDP relay mode" +msgstr "UDP中继模å¼" + +msgid "Concurrent Tunnels" +msgstr "並發隧é“連接數" + +msgid "Congestion control algorithm" +msgstr "拥塞控制算法" + +msgid "Heartbeat interval(second)" +msgstr "ä¿æ´»å¿ƒè·³åŒ…發é€é–“隔(單ä½ï¼šç§’)" + +msgid "Disable SNI" +msgstr "關閉SNIæœå‹™å™¨å称指示" + +msgid "Enable 0-RTT QUIC handshake" +msgstr "客戶端啟用 0-RTT QUIC é€£æŽ¥æ¡æ‰‹" + +msgid "
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)
dns: Disguising traffic as DNS requests." +msgstr "
none:默èªå€¼ï¼Œä¸è¿›è¡Œä¼ªè£…,發é€çš„æ•¸æ®æ˜¯æ²’有特å¾çš„æ•¸æ®åŒ…。
srtpï¼šä¼ªè£…æˆ SRTP 數æ®åŒ…ï¼Œä¼šè¢«è¯†åˆ«ç‚ºè¦–é¢‘é€šè¯æ•¸æ®ï¼ˆå¦‚ FaceTime)。
utpï¼šä¼ªè£…æˆ uTP 數æ®åŒ…,会被识别為 BT 下載數æ®ã€‚
wechat-video:伪装æˆå¾®ä¿¡è¦–频通è¯çš„æ•¸æ®åŒ…。
dtlsï¼šä¼ªè£…æˆ DTLS 1.2 數æ®åŒ…。
wireguardï¼šä¼ªè£…æˆ WireGuard 數æ®åŒ…。(䏦䏿˜¯çœŸæ­£çš„ WireGuard å”è­°)
dns:把æµé‡ä¼ªè£…æˆ DNS 請求。" + +msgid "Use it together with the DNS disguised type. You can fill in any domain." +msgstr "é…åˆä¼ªè£…類型 DNS 使用,å¯éšä¾¿å¡«ä¸€å€‹åŸŸå。" + +msgid "Auth" +msgstr "身份èªè­‰" + +msgid "Socks for authentication" +msgstr "Socksèªè­‰æ–¹å¼" + +msgid "Socks protocol authentication, support anonymous and password." +msgstr "Socks å”è­°çš„èªè­‰æ–¹å¼ï¼Œæ”¯æŒåŒ¿åæ–¹å¼å’Œè´¦å·å¯†ç¢¼æ–¹å¼ã€‚" + +msgid "anonymous" +msgstr "匿å" + +msgid "User Password" +msgstr "è´¦å·å¯†ç¢¼" + +msgid "Username and Password must be used together!" +msgstr "è´¦å·å’Œå¯†ç¢¼å¿…é ˆåŒæ™‚使用ï¼" + +msgid "Prefer firewall tools" +msgstr "首é¸é˜²ç«ç‰†å·¥å…·" + +msgid "IPv6 TProxy" +msgstr "IPv6逿˜Žä»£ç†(TProxy)" + +msgid "Experimental feature. Make sure that your node supports IPv6." +msgstr "實驗特性,請確ä¿ä½ çš„節點支æŒIPv6" + +msgid "Status info" +msgstr "状態信æ¯" + +msgid "Big icon" +msgstr "大图標" + +msgid "Show node check" +msgstr "顯示節點檢測" + +msgid "Show Show IP111" +msgstr "顯示IP111" + +msgid "Destination protocol" +msgstr "目標å”è­°" + +msgid "Destination address" +msgstr "目標地å€" + +msgid "Destination port" +msgstr "目標端å£" + +msgid "Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used." +msgstr "æ˜¯å¦æŽ¥æ”¶ PROXY protocol,當该節點è¦è¢«å›žè½æˆ–被代ç†è½¬ç™¼æ™‚,必須啟用,å¦å‰‡ä¸èƒ½ä½¿ç”¨ã€‚" + +msgid "outbound node" +msgstr "出站節點" + +msgid "Custom Socks" +msgstr "自定义 Socks" + +msgid "Custom HTTP" +msgstr "自定义 HTTP" + +msgid "Custom Interface" +msgstr "自定义接å£" + +msgid "Interface" +msgstr "接å£" + +msgid "Bind Local" +msgstr "本機監è½" + +msgid "When selected, it can only be accessed localhost." +msgstr "ç•¶å‹¾é¸æ™‚,åªèƒ½æœ¬æ©Ÿè¨ªå•。" + +msgid "Accept LAN Access" +msgstr "接å—局域網訪å•" + +msgid "When selected, it can accessed lan , this will not be safe!" +msgstr "ç•¶å‹¾é¸æ™‚,å¯ä»¥ç›´æŽ¥è¨ªå•局域網,這將ä¸å®‰å…¨ï¼ï¼ˆéžç‰¹æ®Šæƒ…æ³ä¸å»ºè­°é–‹å•Ÿï¼‰" + +msgid "Enable Remote" +msgstr "啟用转發" + +msgid "You can forward to Nginx/Caddy/V2ray/Xray WebSocket and more." +msgstr "您å¯ä»¥è½¬ç™¼åˆ°Nginx/Caddy/V2ray/Xray WebSocket等。" + +msgid "Remote Address" +msgstr "é ç¨‹åœ°å€" + +msgid "Remote Port" +msgstr "é ç¨‹ç«¯å£" + +msgid "as:" +msgstr "如:" + +msgid "Public key absolute path" +msgstr "公鑰文件ç»å°è·¯å¾„" + +msgid "Private key absolute path" +msgstr "ç§é‘°æ–‡ä»¶ç»å°è·¯å¾„" + +msgid "Can't find this file!" +msgstr "找ä¸åˆ°é€™å€‹æ–‡ä»¶ï¼" + +msgid "Public key and Private key path can not be empty!" +msgstr "公鑰和ç§é‘°æ–‡ä»¶è·¯å¾„ä¸èƒ½ç‚ºç©ºï¼" + +msgid "Server-Side" +msgstr "æœå‹™å™¨ç«¯" + +msgid "Server Config" +msgstr "æœå‹™å™¨é…ç½®" + +msgid "Users Manager" +msgstr "用戶管ç†" + +msgid "Logs" +msgstr "日誌" + +msgid "Log" +msgstr "日誌" + +msgid "Enable Node Log" +msgstr "啟用節點日誌" + +msgid "Log Level" +msgstr "日誌等級" + +msgid "Not enabled log" +msgstr "未啟用日誌" + +msgid "UDP Forward" +msgstr "UDP转發" + +msgid "DNS Settings" +msgstr "DNS設置" + +msgid "Null" +msgstr "ç„¡" + +msgid "You did not fill in the %s path. Please save and apply then update manually." +msgstr "您沒有填寫 %s 路径。請ä¿å­˜æ‡‰ç”¨å¾Œå†æ‰‹å‹•更新。" + +msgid "Not installed %s, Can't unzip!" +msgstr "未安装 %s,無法解压。" + +msgid "Can't determine ARCH, or ARCH not supported." +msgstr "無法確èªARCHæž¶æ§‹ï¼Œæˆ–æ˜¯ä¸æ”¯æŒã€‚" + +msgid "Get remote version info failed." +msgstr "ç²å–é ç¨‹ç‰ˆæœ¬ä¿¡æ¯å¤±æ•—。" + +msgid "New version found, but failed to get new version download url." +msgstr "發现新版本,但未能ç²å¾—新版本的下載地å€ã€‚" + +msgid "Download url is required." +msgstr "請指定下載地å€ã€‚" + +msgid "File download failed or timed out: %s" +msgstr "文件下載失敗或超時:%s" + +msgid "File path required." +msgstr "請指定文件路径。" + +msgid "%s not enough space." +msgstr "%s 空間ä¸è¶³ã€‚" + +msgid "Can't find client in file: %s" +msgstr "無法在文件中找到客戶端:%s" + +msgid "Client file is required." +msgstr "請指定客戶端文件。" + +msgid "The client file is not suitable for current device." +msgstr "客戶端文件ä¸é©åˆç•¶å‰è¨­å‚™ã€‚" + +msgid "Can't move new file to path: %s" +msgstr "無法移動新文件到:%s" + +msgid "An XHttpObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ XHttpObject,用來實现分享。" + +msgid "Enable Mux.Cool" +msgstr "啟用 Mux.Cool" + +msgid "Mux concurrency" +msgstr "最大並發連接數" + +msgid "XUDP Mux concurrency" +msgstr "XUDP 最大並發連接數" + +msgid "Padding" +msgstr "å¡«å……" + +msgid "Enable early data" +msgstr "啟用å‰ç½®æ•¸æ®" + +msgid "Early data length" +msgstr "å‰ç½®æ•¸æ®æœ€å¤§é•¿åº¦" + +msgid "Early data header name" +msgstr "å‰ç½®æ•¸æ® HTTP 头å" + +msgid "Recommended value: Sec-WebSocket-Protocol" +msgstr "推è值:Sec-WebSocket-Protocol" + +msgid "Health check" +msgstr "å¥åº·æª¢æŸ¥" + +msgid "Health check timeout" +msgstr "檢查超時時間" + +msgid "Permit without stream" +msgstr "ç„¡å­é€£æŽ¥æ™‚çš„å¥åº·æª¢æŸ¥" + +msgid "Initial Windows Size" +msgstr "åˆå§‹çª—å£å¤§å°" + +msgid "Excluded Domains" +msgstr "排除域å" + +msgid "If the traffic sniffing result is in this list, the destination address will not be overridden." +msgstr "如果æµé‡å—…æŽ¢çµæžœåœ¨æ­¤åˆ—表中,則ä¸ä¼šè¦†ç›–目標地å€ã€‚" + +msgid "Buffer Size" +msgstr "缓è¡åŒºå¤§å°" + +msgid "Buffer size for every connection (kB)" +msgstr "æ¯ä¸€å€‹é€£æŽ¥çš„缓è¡åŒºå¤§å°ï¼ˆkB)" + +msgid "Idle Timeout" +msgstr "空闲超時" + +msgid "Hop Interval(second)" +msgstr "端å£è·³èºé–“隔(秒)" + +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "支æ´å›ºå®šå€¼æˆ–隨機範åœï¼ˆå¦‚ 30 或 5-30ï¼‰ï¼Œæœ€å° 5 秒。" + +msgid "HeartbeatPeriod(second)" +msgstr "心跳周期(單ä½ï¼šç§’)" + +msgid "Override the connection destination address" +msgstr "覆盖連接目標地å€" + +msgid "Override the connection destination address with the sniffed domain.
Otherwise use sniffed domain for routing only.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "用探測出的域å覆盖連接目標地å€ã€‚
å¦å‰‡ä»…將探測得到的域å用於路由。
如使用分æµç¯€é»žï¼Œè«‹æ­£ç¢ºè¨­ç½®åŸŸå分æµè¦å‰‡ã€‚" + +msgid "Handshake Server" +msgstr "æ¡æ‰‹æœå‹™å™¨" + +msgid "Handshake Server Port" +msgstr "æ¡æ‰‹æœå‹™å™¨ç«¯å£" + +msgid "Protocol parameter. Will waste traffic randomly if enabled." +msgstr "å”è­°åƒæ•¸ã€‚ å¦‚æžœå•Ÿç”¨ä¼šéšæ©Ÿæµªè´¹æµé‡ã€‚" + +msgid "Protocol parameter. Enable length block encryption." +msgstr "å”è­°åƒæ•¸ã€‚啟用长度å—加密。" + +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "TLS æ†‘è­‰éˆæŒ‡ç´‹ï¼ˆSHA256)" + +msgid "Once set, connects only when the server’s chain fingerprint matches." +msgstr "設定後,僅在伺æœå™¨æ†‘è­‰éˆæŒ‡ç´‹åŒ¹é…時連接。" + +msgid "TLS Certificate Name (CertName)" +msgstr "TLS 憑證å稱(CertName)" + +msgid "TLS is used to verify the leaf certificate name." +msgstr "TLS 用於驗證 leaf 憑證的 name。" + +msgid "ECH Config" +msgstr "ECH é…ç½®" + +msgid "ECH Key" +msgstr "ECH 密鑰" + +msgid "ECH Query Policy" +msgstr "ECH 查詢策略" + +msgid "Controls the policy used when performing DNS queries for ECH configuration." +msgstr "控制使用 DNS 查詢 ECH é…置時的策略。" + +msgid "ECH Query Domain" +msgstr "ECH 查詢網域å" + +msgid "Overrides the domain name used for ECH HTTPS record queries." +msgstr "覆蓋用於 ECH HTTPS 記錄查詢的網域å。" + +msgid "Enable Multipath TCP, need to be enabled in both server and client configuration." +msgstr "啟用 Multipath TCP,需在æœå‹™ç«¯å’Œå®¢æˆ¶ç«¯é…ç½®ä¸­åŒæ™‚啟用。" + +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ FinalMaskObject,用來實ç¾åˆ†äº«ã€‚" + +msgid "Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings." +msgstr "自定義 finalmask 將涵蓋 mkcpã€hysteria2ã€fragmentã€noise 等相關é…置。" + +msgid "Fragment" +msgstr "分片" + +msgid "TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists." +msgstr "TCP 分片,在æŸäº›æƒ…æ³ä¸‹å¯ä»¥æ¬ºéª—å®¡æŸ¥ç³»çµ±ï¼Œæ¯”å¦‚ç»•éŽ SNI 黑å單。" + +msgid "Fragment Packets" +msgstr "分片方å¼" + +msgid " \"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation." +msgstr " \"1-3\" 是 TCP çš„æµåˆ‡ç‰‡ï¼Œæ‡‰ç”¨æ–¼å®¢æˆ¶ç«¯ç¬¬ 1 至第 3 次寫數æ®ã€‚\"tlshello\" 是 TLS æ¡æ‰‹åŒ…切片。" + +msgid "Fragment Length" +msgstr "分片包长" + +msgid "Fragmented packet length (byte)" +msgstr "分片包长 (byte)" + +msgid "Fragment Delay" +msgstr "分片延é²" + +msgid "Fragmentation interval (ms)" +msgstr "分片間隔(ms)" + +msgid "Max Split" +msgstr "最大分片數" + +msgid "Limit the maximum number of splits." +msgstr "é™åˆ¶åˆ†ç‰‡çš„æœ€å¤§æ•¸é‡ã€‚" + +msgid "Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first." +msgstr "å°‡æ¡æ‰‹æ•¸æ®æ‹†åˆ†ç‚ºå¤šå€‹ TLS 記錄,æå‡æŠ—å°é”能力,几乎ä¸å¢žåŠ å»¶è¿Ÿï¼Œå»ºè­°å„ªå…ˆå•Ÿç”¨ã€‚" + +msgid "Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed." +msgstr "å°‡ TLS æ¡æ‰‹æ•¸æ®åˆ†ç‚ºå¤šå€‹ TCP 包發é€ï¼Œæé«˜ä¼ªè£…性,å¯èƒ½å¢žåŠ å»¶è¿Ÿï¼Œä»…åœ¨å°é”䏥釿™‚使用。" + +msgid "Noise" +msgstr "噪è²" + +msgid "UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions." +msgstr "UDP 噪è²ï¼Œåœ¨æŸäº›æƒ…æ³ä¸‹å¯ä»¥ç»•éŽä¸€äº›é’ˆå° UDP å”è­°çš„é™åˆ¶ã€‚" + +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "在 Xray è¨­ç½®ä¸­å‹¾é¸ â€œå™ªè²â€ 以發é€å™ªè²åŒ…。" + +msgid "Xray Noise Packets" +msgstr "Xray å™ªè²æ•¸æ®åŒ…" + +msgid "Packet | Rand Length" +msgstr "數據包 | Rand 長度" + +msgid "Delay (ms)" +msgstr "延迟(ms)" + +msgid "If is domain name, The requested domain name will be resolved to IP before connect." +msgstr "如果是域å,域å將在請求發出之å‰è§£æžç‚º IP。" + +msgid "Domain DNS Resolve" +msgstr "域å DNS è§£æž" + +msgid "If the node address is a domain name, this DNS will be used for resolution." +msgstr "å¦‚æžœç¯€é»žåœ°å€æ˜¯åŸŸå,則將使用此 DNS 進行解æžã€‚" + +msgid "Supports only Xray or Sing-box node types." +msgstr "åƒ…æ”¯æ´ Xray 或 Sing-box 類型節點。" + +msgid "Chain Proxy" +msgstr "éˆå¼ä»£ç†" + +msgid "Outbound Interface" +msgstr "出站接å£" + +msgid "Landing Node" +msgstr "è½åœ°ç¯€é»ž" + +msgid "Only support a layer of proxy." +msgstr "仅支æŒä¸€å±¤ä»£ç†ã€‚" + +msgid "" +"Chained proxy works only with Xray or Sing-box nodes.
" +"You can only use manual or imported nodes as chained nodes." +msgstr "" +"éˆå¼ä»£ç†ä»…æ”¯æŒ Xray 或 Sing-box 節點。
" +"ä»…æ”¯æŒæ‰‹å‹•添加或導入的節點用作éˆå¼ç¯€é»žã€‚" + +msgid "Prefer IPv4" +msgstr "IPv4 優先" + +msgid "Prefer IPv6" +msgstr "IPv6 優先" + +msgid "IPv4 Only" +msgstr "ä»… IPv4" + +msgid "IPv6 Only" +msgstr "ä»… IPv6" + +msgid "Maintain" +msgstr "ç»´è­·" + +msgid "Backup and Restore" +msgstr "備份还原" + +msgid "Backup or Restore Client and Server Configurations." +msgstr "å‚™ä»½æˆ–è¿˜åŽŸå®¢æˆ¶ç«¯åŠæœå‹™ç«¯é…置。" + +msgid "Note: Restoring configurations across different versions may cause compatibility issues." +msgstr "注æ„:ä¸åŒç‰ˆæœ¬é–“çš„é…ç½®æ¢å¾©å¯èƒ½ä¼šå°Žè‡´å…¼å®¹æ€§å•題。" + +msgid "Create Backup File" +msgstr "创建備份文件" + +msgid "Restore Backup File" +msgstr "æ¢å¾©å‚™ä»½æ–‡ä»¶" + +msgid "DL Backup" +msgstr "下載備份" + +msgid "RST Backup" +msgstr "æ¢å¾©å‚™ä»½" + +msgid "Backup failed!" +msgstr "備份失敗ï¼" + +msgid "UL Restore" +msgstr "上傳æ¢å¾©" + +msgid "CLOSE WIN" +msgstr "關閉窗å£" + +msgid "Restore to default configuration" +msgstr "æ¢å¾©é»˜èªé…ç½®" + +msgid "Do Reset" +msgstr "执行é‡ç½®" + +msgid "Please select a file first." +msgstr "è«‹å…ˆé¸æ‹©ä¸€å€‹æ–‡ä»¶ã€‚" + +msgid "Invalid file type. Please upload a .tar.gz file." +msgstr "文件類型無效,請上傳一個 .tar.gz 文件。" + +msgid "File size exceeds 10MB limit." +msgstr "文件大å°è¶…éŽ 10MB é™åˆ¶ã€‚" + +msgid "Do you want to restore the client to default settings?" +msgstr "是å¦è¦æ¢å¾©å®¢æˆ¶ç«¯é»˜èªé…置?" + +msgid "Are you sure you want to restore the client to default settings?" +msgstr "是å¦çœŸçš„è¦æ¢å¾©å®¢æˆ¶ç«¯é»˜èªé…置?" + +msgid "Configuration file uploaded successfully…" +msgstr "é…置文件上傳æˆåŠŸâ€¦" + +msgid "Configuration restored successfully…" +msgstr "é…置还原æˆåŠŸâ€¦" + +msgid "Service restarting…" +msgstr "é‡å•Ÿæœå‹™ä¸­â€¦" + +msgid "Configuration file decompression failed, please try again!" +msgstr "é…置文件解压失敗,請é‡è©¦ï¼" + +msgid "_urltest" +msgstr "URLTest" + +msgid "URLTest node list" +msgstr "URLTest 節點列表" + +msgid "List of nodes to test, document" +msgstr "è¦æ¸¬è©¦çš„節點列表,文檔原ç†" + +msgid "Test interval" +msgstr "測試間隔" + +msgid "Test interval must be less or equal than idle timeout." +msgstr "æ¸¬è©¦é–“éš”æ™‚é–“å¿…é ˆå°æ–¼æˆ–等於空闲超時時間。" + +msgid "Test tolerance" +msgstr "測試容差" + +msgid "The test tolerance in milliseconds." +msgstr "測試容差時間(單ä½ï¼šæ¯«ç§’)。" + +msgid "Idle timeout" +msgstr "空闲超時" + +msgid "The idle timeout." +msgstr "空闲超時時間。" + +msgid "Interrupt existing connections" +msgstr "中斷现有連接" + +msgid "Interrupt existing connections when the selected outbound has changed." +msgstr "ç•¶é¸æ‹©çš„出站發生變化時中斷现有連接。" + +msgid "Port hopping range" +msgstr "端å£è·³è·ƒç¯„åœ" + +msgid "Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,)." +msgstr "æ ¼å¼ç‚ºï¼š1000:2000 或 1000-2000 多组時用逗å·(,)隔開。" + +msgid "Use Custom Config" +msgstr "使用自定义é…ç½®" + +msgid "Custom Config" +msgstr "自定义é…ç½®" + +msgid "Must be JSON text!" +msgstr "必須是 JSON 文本內容ï¼" + +msgid "Geo View" +msgstr "Geo 查詢" + +msgid "Query" +msgstr "查詢" + +msgid "Querying" +msgstr "查詢中" + +msgid "Please enter query content!" +msgstr "請輸入查詢內容ï¼" + +msgid "No results were found!" +msgstr "æœªæ‰¾åˆ°ä»»ä½•çµæžœï¼" + +msgid "Rules containing this value:" +msgstr "所在è¦å‰‡åˆ—表:" + +msgid "Domain/IP Query" +msgstr "域å/IP 查詢" + +msgid "GeoIP/Geosite Query" +msgstr "GeoIP/Geosite 查詢" + +msgid "Enter a domain or IP to query the Geo rule list they belong to." +msgstr "輸入域å/IP,查詢它们所在的 Geo è¦å‰‡åˆ—表。" + +msgid "Enter a GeoIP or Geosite to extract the domains/IPs they contain. Format: geoip:cn or geosite:gfw" +msgstr "輸入 GeoIP/Geosite,æå–它们所包å«çš„域å/IP。格å¼ï¼šgeoip:cn 或 geosite:gfw" + +msgid "Tips:" +msgstr "å°è´´å£«ï¼š" + +msgid "By entering a domain or IP, you can query the Geo rule list they belong to." +msgstr "å¯ä»¥é€šéŽè¼¸å…¥åŸŸå/IP,查詢它们所在的 Geo è¦å‰‡åˆ—表。" + +msgid "By entering a GeoIP or Geosite, you can extract the domains/IPs they contain." +msgstr "å¯ä»¥é€šéŽè¼¸å…¥ GeoIP/Geosite,æå–它们所包å«çš„域å/IP。" + +msgid "Use the GeoIP/Geosite query function to verify if the entered Geo rules are correct." +msgstr "利用 GeoIP/Geosite 查詢功能,å¯ä»¥é©—證輸入的 Geo è¦å‰‡æ˜¯å¦æ­£ç¢ºã€‚" + +msgid "Private Key Passphrase" +msgstr "ç§é‘°æŒ‡ç´‹" + +msgid "Host Key" +msgstr "主機密鑰" + +msgid "Accept any if empty." +msgstr "ç•™ç©ºå‰‡ä¸æ ¡é©—。" + +msgid "Host Key Algorithms" +msgstr "主機密鑰算法" + +msgid "Client Version" +msgstr "客戶端版本" + +msgid "Random version will be used if empty." +msgstr "å¦‚ç•™ç©ºï¼Œå‰‡ä½¿ç”¨éšæ©Ÿç‰ˆæœ¬ã€‚" + +msgid "The configured type also applies to the core specified when manually importing nodes." +msgstr "é…ç½®çš„é¡žåž‹åŒæ¨£é©ç”¨æ–¼æ‰‹å‹•導入節點時所指定的核心程åºã€‚" + +msgid "Group Name" +msgstr "分組å" + +msgid "Reassign Group" +msgstr "調整分組" + +msgid "Reassign Node Group" +msgstr "調整節點分組" + +msgid "Search nodes..." +msgstr "æœå°‹ç¯€é»žâ€¦" + +msgid "Using..." +msgstr "使用中。" + +msgid "Generate configuration file and run" +msgstr "生æˆé…置文件並é‹è¡Œ" + +msgid "Start after a delay of %s seconds!" +msgstr "延時 %s 秒後å†å•Ÿå‹•!" + +msgid "The script is already running, do not run it again. Exit." +msgstr "脚本已ç»åœ¨é‹è¡Œï¼Œä¸é‡å¾©é‹è¡Œï¼Œé€€å‡º." + +msgid "Stop the script and wait for a timeout, then exit without repeating the process." +msgstr "åœæ­¢è„šæœ¬ç­‰å¾…è¶…æ™‚ï¼Œä¸é‡å¾©é‹è¡Œï¼Œé€€å‡º." + +msgid "Warning: The %s application environment is incomplete. Switch to %s. (%s)" +msgstr "警告:%s 應用環境ä¸å®Œæ•´ï¼Œåˆ‡æ›è‡³ %s。 (%s)" + +msgid "Note: Dnsmasq (%s) is below 2.90. Upgrading is recommended to improve stability." +msgstr "æç¤ºï¼šDnsmasq (%s) 低於 2.90,建議å‡ç´šä»¥å¢žå¼·ç©©å®šæ€§ã€‚" + +msgid "Warning: %s transparent proxy is missing basic dependency %s!" +msgstr "警告:%s 逿˜Žä»£ç†ç¼ºå°‘基礎ä¾è³´ %sï¼" + +msgid "Warning: Not compatible with any transparent proxy system environment." +msgstr "è­¦å‘Šï¼šä¸æ»¿è¶³ä»»ä½•逿˜Žä»£ç†ç³»çµ±ç’°å¢ƒã€‚" + +msgid "%s does not have execute permissions and cannot be started: %s %s" +msgstr "%s 沒有执行權é™ï¼Œç„¡æ³•啟動:%s %s" + +msgid "%s not found, unable to start..." +msgstr "找ä¸åˆ° %s,無法啟動..." + +msgid "Socks node: [%s]%s is an invalid server address and cannot be started!" +msgstr "Socks節點:[%s]%s æ˜¯éžæ³•çš„æœå‹™å™¨åœ°å€ï¼Œç„¡æ³•啟動ï¼" + +msgid "For some reason, the configuration for this Socks service has been lost, and its startup has been aborted!" +msgstr "æŸç§åŽŸå› ï¼Œæ­¤ Socks æœå‹™çš„相關é…置已失è”,啟動中止ï¼" + +msgid "Socks node: [%s]%s, start failed %s:%s %s" +msgstr "Socks節點:[%s]%s,啟動失敗 %s:%s %s" + +msgid "Socks node: [%s]%s, starting %s:%s" +msgstr "Socks節點:[%s]%s,啟動 %s:%s" + +msgid "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!" +msgstr "開啟實驗性IPv6逿˜Žä»£ç†(TProxy)ï¼Œè«‹ç¢ºèªæ‚¨çš„節點åŠé¡žåž‹æ”¯æŒIPv6ï¼" + +msgid "[%s] process %s error, skip this transparent proxy!" +msgstr "ã€%s】 進程 %s éŒ¯èª¤ï¼Œè·³éŽæ­¤é€æ˜Žä»£ç†ï¼" + +msgid "Analyzing the node configuration of the Socks service..." +msgstr "åˆ†æž Socks æœå‹™çš„節點é…ç½®..." + +msgid "Log file is too long, clear it!" +msgstr "日誌文件éŽé•¿ï¼Œæ¸…空处ç†ï¼" + +msgid "The task is currently running automatically as a scheduled task; no reconfiguration of the scheduled task is required." +msgstr "ç•¶å‰ç‚ºè¨ˆåˆ’任務自動é‹è¡Œï¼Œä¸é‡æ–°é…置定時任務。" + +msgid "Scheduled tasks: Auto stop service." +msgstr "é…置定時任務:自動關閉æœå‹™ã€‚" + +msgid "Scheduled tasks: Auto start service." +msgstr "é…置定時任務:自動開啟æœå‹™ã€‚" + +msgid "Scheduled tasks: Auto restart service." +msgstr "é…置定時任務:自動é‡å•Ÿæœå‹™ã€‚" + +msgid "Scheduled tasks: Auto update rules." +msgstr "é…置定時任務:自動更新è¦å‰‡ã€‚" + +msgid "Scheduled tasks: Auto update [%s] subscription." +msgstr "é…置定時任務:自動更新 ã€%s】 訂閱。" + +msgid "Auto updates: Starts a cyclical update process." +msgstr "自動更新:啟動循环更新進程。" + +msgid "Running in no proxy mode, it only allows scheduled tasks for starting and stopping services." +msgstr "é‹è¡Œæ–¼éžä»£ç†æ¨¡å¼ï¼Œä»…å…許æœå‹™å•Ÿåœçš„定時任務。" + +msgid "Clear scheduled commands." +msgstr "清除定時执行命令。" + +msgid "Unable to resolve [%s], route table addition failed!" +msgstr "無法解æž[%s],路由表添加失敗ï¼" + +msgid "[%s] was successfully added to the routing table of interface [%s]!" +msgstr "[%s]添加到接å£[%s]路由表æˆåŠŸï¼" + +msgid "Adding [%s] to the [%s] routing table failed! The reason is that the [%s] gateway cannot be found." +msgstr "[%s]添加到接å£[%s]路由表失功ï¼åŽŸå› æ˜¯æ‰¾ä¸åˆ°[%s]網關。" + +msgid "Global nodes are not enabled, skip [%s]." +msgstr "全局節點未啟用,跳éŽã€%s】" + +msgid "Direct DNS: %s" +msgstr "直連 DNS:%s" + +msgid "Remote DNS: %s" +msgstr "é ç¨‹ DNS:%s" + +msgid "The program has started. Please stop it and then restart it!" +msgstr "程åºå·²å•Ÿå‹•ï¼Œå…ˆåœæ­¢å†é‡æ–°å•Ÿå‹•!" + +msgid "Running complete!" +msgstr "é‹è¡Œå®Œæˆï¼" + +msgid "Clearing and closing related programs and cache complete." +msgstr "清空並關閉相關程åºå’Œç¼“存完æˆã€‚" + +msgid "Incorrect index listing method (%s), execution terminated!" +msgstr "索引列举方å¼ä¸æ­£ç¢ºï¼ˆ%s),终止执行ï¼" + +msgid "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." +msgstr "è§£æžåˆ†æµè¦å‰‡[%s]-[geoip:%s]加入到 %s 完æˆ" + +msgid "Access Control:" +msgstr "è¨ªå•æŽ§åˆ¶ï¼š" + +msgid "Add node to the load balancer is directly connected to %s[%s]." +msgstr "加入負載å‡è¡¡çš„節點到%s[%s]直連完æˆã€‚" + +msgid "Add all %s nodes to %s[%s] direct connection complete." +msgstr "加入所有%s節點到%s[%s]直連完æˆã€‚" + +msgid "Starting to load %s firewall rules..." +msgstr "開始加载 %s 防ç«å¢™è¦å‰‡..." + +msgid "local network segments (%s) direct connection: %s" +msgstr "本機 %s 網段直連:%s" + +msgid "Add ISP %s DNS to the whitelist: %s" +msgstr "追加ISP %s DNS 到白å單:%s" + +msgid "[%s]" +msgstr "ã€%s】" + +msgid "[%s]," +msgstr "ã€%s】," + +msgid "Source iface [%s]," +msgstr "æºæŽ¥å£ã€%s】," + +msgid "IP range [%s]," +msgstr "IP 範åœã€%s】," + +msgid "All device," +msgstr "所有設備," + +msgid "Does not exist, ignore." +msgstr "ä¸å­˜åœ¨ï¼Œå¿½ç•¥ã€‚" + +msgid "not proxy %s port [%s]" +msgstr "ä¸ä»£ç† %s ç«¯å£ [%s]" + +msgid "not proxy all %s" +msgstr "ä¸ä»£ç†æ‰€æœ‰ %s" + +msgid "Use the %s node [%s]" +msgstr "使用 %s 節點[%s]" + +msgid "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server." +msgstr "使用与全局é…ç½®ä¸ç›¸åŒç¯€é»žï¼Œå·²å°‡DNS強制é‡å®šå‘到專用 DNS æœå‹™å™¨ã€‚" + +msgid "Add direct DNS to %s: %s" +msgstr "追加直連 DNS 到 %s: %s" + +msgid "Local" +msgstr "本機" + +msgid "[Local]," +msgstr "ã€æœ¬æ©Ÿã€‘," + +msgid "Clear %s." +msgstr "清除 %s。" + +msgid "Delete %s rules is complete." +msgstr "刪除 %s è¦å‰‡å®Œæˆã€‚" + +msgid "%s firewall rules load complete!" +msgstr "%s 防ç«å¢™è¦å‰‡åŠ è½½å®Œæˆï¼" + +msgid "Socks switch detection: Unknown error." +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼šæœªçŸ¥éŒ¯èª¤ã€‚" + +msgid "Socks switch detection: Unable to connect to the network. Please check if the network is working properly!" +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼šç„¡æ³•é€£æŽ¥åˆ°ç¶²çµ¡ï¼Œè«‹æª¢æŸ¥ç¶²çµ¡æ˜¯å¦æ­£å¸¸ï¼" + +msgid "Socks switch detection: Primary node ã€%s: [%s]】 is normal. Switch to the primary node!" +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼š%s 主節點ã€%s:[%s]】正常,切æ›åˆ°ä¸»ç¯€é»žï¼" + +msgid "Socks switch detection: %s node switch complete!" +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼š%s 節點切æ›å®Œæ¯•ï¼" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal." +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼š%s ã€%s:[%s]】 正常。" + +msgid "switch to %s test detect!" +msgstr "切æ›åˆ° %s 檢測ï¼" + +msgid "backup node" +msgstr "備用節點" + +msgid "next backup node" +msgstr "下一個備用節點" + +msgid "main node" +msgstr "主節點" + +msgid "Socks switch detection: Unknown error." +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼šæœªçŸ¥éŒ¯èª¤ã€‚" + +msgid "Socks switch detection: %s ã€%s:[%s]】 abnormal, %s" +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼š%s ã€%s:[%s]】 异常,%s" + +msgid "Socks switch detection: %s ã€%s:[%s]】 normal, switch to this node!" +msgstr "Socksåˆ‡æ›æª¢æ¸¬ï¼š%s ã€%s:[%s]】 正常,切æ›åˆ°æ­¤ç¯€é»žï¼" + +msgid "Restart dnsmasq service." +msgstr "é‡å•Ÿ dnsmasq æœå‹™ã€‚" + +msgid "Console Port: %s" +msgstr "控制臺端å£ï¼š%s" + +msgid "Discard one obviously invalid node." +msgstr "丟棄 1 個明顯無效的節點" + +msgid "Entrance %s:%s" +msgstr "å…¥å£ %s:%s" + +msgid "Node: %s:%s, Weight: %s" +msgstr "節點:%s:%s,權é‡ï¼š%s" + +msgid "[Rule update] instance is running; please try again later." +msgstr "[è¦å‰‡æ›´æ–°]實例正在é‹è¡Œï¼Œè«‹ç¨å¾Œå†è©¦..." + +msgid "[Subscription] instance is running; [Rule Update] queue and wait." +msgstr "[訂閱]實例正在é‹è¡Œï¼Œ[è¦å‰‡æ›´æ–°]進入隊列等待..." + +msgid "Start updating the rules..." +msgstr "é–‹å§‹æ›´æ–°è¦å‰‡..." + +msgid "Download file size verification error. Original file size: %sB. Downloaded file size: %sB." +msgstr "ä¸‹è¼‰æª”æ¡ˆå¤§å°æ ¡é©—å‡ºéŒ¯ï¼ŒåŽŸå§‹æª”æ¡ˆå¤§å° %sB,下載檔案大å°ï¼š%sB。" + +msgid "Downloaded file is empty or an error occurred while reading it." +msgstr "ä¸‹è¼‰çš„æ–‡ä»¶ç‚ºç©ºæˆ–è®€å–æ–‡ä»¶æ™‚發生錯誤。" + +msgid "%s Start updating..." +msgstr "%s é–‹å§‹æ›´æ–°..." + +msgid "%s version is the same and does not need to be updated." +msgstr "%s 版本一致,無需更新。" + +msgid "%s an error occurred during the file download process. Please try downloading again." +msgstr "%s 下載檔案éŽç¨‹å‡ºéŒ¯ï¼Œå˜—è©¦é‡æ–°ä¸‹è¼‰ã€‚" + +msgid "%s an error occurred while downloading the file. Please check your network or the download link and try again!" +msgstr "%s 下載檔案éŽç¨‹å‡ºéŒ¯ï¼Œè«‹æª¢æŸ¥ç¶²é æˆ–下載連çµå¾Œé‡è©¦ï¼" + +msgid "%s update success." +msgstr "%s æ›´æ–°æˆåŠŸã€‚" + +msgid "%s update failed, please try again later or change URL." +msgstr "%s 更新失敗,請ç¨å¾Œå†è©¦æˆ–æ›´æ› URL。" + +msgid "%s update error!" +msgstr "%s 更新發生錯誤ï¼" + +msgid "Restart the service and apply the new rules." +msgstr "é‡å•Ÿæœå‹™ï¼Œæ‡‰ç”¨æ–°çš„è¦å‰‡ã€‚" + +msgid "The rules have been updated..." +msgstr "è¦å‰‡æ›´æ–°å®Œæ¯•..." + +msgid "Socks node list [%s]" +msgstr "Socks 節點列表 [%s]" + +msgid "Backup node list" +msgstr "備用節點的列表" + +msgid "HAProxy node list [%s]" +msgstr "HAProxy 節點列表 [%s]" + +msgid "ACL list [%s]" +msgstr "è¨ªå•æŽ§åˆ¶åˆ—è¡¨ [%s]" + +msgid "Shunt [%s] node" +msgstr "åˆ†æµ [%s] 節點" + +msgid "Xray Load Balancing node [%s] list" +msgstr "Xray 負載å‡è¡¡ç¯€é»ž [%s] 列表" + +msgid "Xray Load Balancing node [%s] backup node" +msgstr "Xray 負載å‡è¡¡ç¯€é»ž [%s] 後備節點" + +msgid "Sing-Box URLTest node [%s] list" +msgstr "Sing-Box URLTest 節點 [%s] 列表" + +msgid "Node [%s] preproxy node" +msgstr "節點 [%s] å‰ç½®ä»£ç†ç¯€é»ž" + +msgid "Node [%s] landing node" +msgstr "節點 [%s] è½åœ°ç¯€é»ž" + +msgid "Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings." +msgstr "è·³éŽ %s 節點,因未é©é…到 %s 核心程åºï¼Œæˆ–未正確設置節點使用類型。" + +msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." +msgstr "è·³éŽç¯€é»žï¼š%s,因 Sing-Box 䏿”¯æŒ %s å”è­°çš„ %s 傳輸方å¼ï¼Œéœ€æ›´æ› Xray。" + +msgid "Xray unsupport %s plugin." +msgstr "Xray 䏿”¯æŒ %s æ’件。" + +msgid "Plugin options Incomplete." +msgstr "æ’ä»¶é¸é …ä¸å®Œæ•´ã€‚" + +msgid "Please replace %s to support %s transmission method." +msgstr "è«‹æ›´æ› %s ä»¥æ”¯æ´ %s 傳輸方å¼ã€‚" + +msgid "Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks." +msgstr "è«‹æ›´æ› Xray 或 Sing-Box ä¾†æ”¯æ´ Shadowsocks 更多的傳輸方å¼ã€‚" + +msgid "unsupport %s plugin." +msgstr "䏿”¯æŒ %s æ’件。" + +msgid "Skip the %s node because the %s core program is not installed." +msgstr "è·³éŽ %s 節點,因未安装 %s æ ¸å¿ƒç¨‹åº %s。" + +msgid "Skip the %s node, as %s type nodes require Sing-Box version 1.12 or higher." +msgstr "è·³éŽ %s 節點,因 %s é¡žåž‹çš„ç¯€é»žéœ€è¦ Sing-Box 1.12 以上版本支æŒã€‚" + +msgid "%s type node subscriptions are not currently supported, skip this node." +msgstr "æš«æ™‚ä¸æ”¯æŒ %s é¡žåž‹çš„ç¯€é»žè¨‚é–±ï¼Œè·³éŽæ­¤ç¯€é»žã€‚" + +msgid "Update [%s]" +msgstr "æ›´æ–°ã€%s】" + +msgid "Matching node:" +msgstr "匹é…節點:" + +msgid "First Matching node:" +msgstr "第一匹é…節點:" + +msgid "Second Matching node:" +msgstr "第二匹é…節點:" + +msgid "Third Matching node:" +msgstr "第三匹é…節點:" + +msgid "Fourth Matching node:" +msgstr "第四匹é…節點:" + +msgid "Fifth Matching node:" +msgstr "第五匹é…節點:" + +msgid "Unable to find the best matching node, now replaced with:" +msgstr "無法找到最匹é…的節點,當å‰å·²æ›´æ›ç‚ºï¼š" + +msgid "Unable to find a new node. Please confirm and process manually." +msgstr "無法匹é…到新的節點,請手動確èªè™•ç†ã€‚" + +msgid "No node information updates are available." +msgstr "沒有å¯ç”¨çš„ç¯€é»žä¿¡æ¯æ›´æ–°ã€‚" + +msgid "Skip unknown types:" +msgstr "è·³éŽæœªçŸ¥é¡žåž‹ï¼š" + +msgid "Discard node: %s, Reason:" +msgstr "丟棄節點: %s ,原因:" + +msgid "No usable binary was found." +msgstr "找ä¸åˆ°å¯ä½¿ç”¨äºŒé€²åˆ¶ã€‚" + +msgid "Discard filter nodes: %s type node %s" +msgstr "ä¸Ÿæ£„éŽæ¿¾ç¯€é»ž: %s 類型節點 %s" + +msgid "Parsing error, skip this node." +msgstr "è§£æžéŒ¯èª¤ï¼Œè·³éŽæ­¤ç¯€é»žã€‚" + +msgid "Successfully resolved the [%s] node, number: %s" +msgstr "æˆåŠŸè§£æžã€%s】節點,數é‡ï¼š%s" + +msgid "Get subscription content for [%s] is empty. This may be due to an invalid subscription address or a network problem. Please diagnose the issue!" +msgstr "ç²å–到的ã€%s】訂閱內容為空,å¯èƒ½æ˜¯è¨‚閱地å€ç„¡æ•ˆï¼Œæˆ–是網絡å•題,請診斷ï¼" + +msgid "Proxy" +msgstr "代ç†" + +msgid "[Subscription] instance is running; please try again later." +msgstr "[訂閱]實例正在é‹è¡Œï¼Œè«‹ç¨å¾Œå†è©¦..." + +msgid "[Rule Update] instance is running; [Subscription] queue and wait." +msgstr "[è¦å‰‡æ›´æ–°]實例正在é‹è¡Œï¼Œ[訂閱]進入隊列等待..." + +msgid "Start subscribing..." +msgstr "開始訂閱..." + +msgid "Start subscribing: %s" +msgstr "開始訂閱:%s" + +msgid "Subscription: [%s] No changes, no update required." +msgstr "訂閱:ã€%s】沒有變化,無需更新。" + +msgid "[%s] Subscription failed. This could be due to an invalid subscription address or a network issue. Please diagnose the problem! [%s]" +msgstr "ã€%s】訂閱失敗,å¯èƒ½æ˜¯è¨‚閱地å€ç„¡æ•ˆï¼Œæˆ–是網絡å•題,請診斷ï¼[%s]" + +msgid "Error, restoring service." +msgstr "發生錯誤, 正在æ¢å¾©æœå‹™ã€‚" + +msgid "Subscription complete..." +msgstr "訂閱完毕..." + +msgid "Processing, please wait…" +msgstr "正在處ç†ï¼Œè«‹ç¨å€™ã€‚" diff --git a/luci-app-passwall2/po/zh_Hans b/luci-app-passwall2/po/zh_Hans new file mode 120000 index 00000000..41451e4a --- /dev/null +++ b/luci-app-passwall2/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/luci-app-passwall2/po/zh_Hant b/luci-app-passwall2/po/zh_Hant new file mode 120000 index 00000000..f6e591fd --- /dev/null +++ b/luci-app-passwall2/po/zh_Hant @@ -0,0 +1 @@ +zh-tw \ No newline at end of file diff --git a/luci-app-passwall2/root/etc/config/passwall2_server b/luci-app-passwall2/root/etc/config/passwall2_server new file mode 100644 index 00000000..c9526cb2 --- /dev/null +++ b/luci-app-passwall2/root/etc/config/passwall2_server @@ -0,0 +1,4 @@ + +config global 'global' + option enable '0' + diff --git a/luci-app-passwall2/root/etc/hotplug.d/iface/98-passwall2 b/luci-app-passwall2/root/etc/hotplug.d/iface/98-passwall2 new file mode 100644 index 00000000..f80354d1 --- /dev/null +++ b/luci-app-passwall2/root/etc/hotplug.d/iface/98-passwall2 @@ -0,0 +1,35 @@ +#!/bin/sh + +[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || exit 0 + +. /usr/share/passwall2/utils.sh + +([ "$(get_cache_var "ENABLED_DEFAULT_ACL")" = "1" ] || [ "$(get_cache_var "ENABLED_ACLS")" = "1" ]) && [ -f ${LOCK_PATH}/${CONFIG}_ready.lock ] && { + + default_device=$(ip route show default 2>/dev/null | awk -F 'dev ' '{print $2}' | awk '{print $1}' | head -n1) + default6_device=$(ip -6 route show default 2>/dev/null | awk -F 'dev ' '{print $2}' | awk '{print $1}' | head -n1) + ( [ "$default_device" = "$DEVICE" ] || [ "$default6_device" = "$DEVICE" ] ) && { + + if [ "$ACTION" = "ifupdate" ]; then + USE_TABLES=$(get_cache_var "USE_TABLES") + [ -n "$USE_TABLES" ] && { ${APP_PATH}/${USE_TABLES}.sh update_wan_sets >/dev/null 2>&1 & } + exit 0 + fi + + [ ! -d ${LOCK_PATH} ] && mkdir -p ${LOCK_PATH} + LOCK_FILE="${LOCK_PATH}/${CONFIG}_ifup.lock" + if [ -s ${LOCK_FILE} ]; then + SPID=$(cat ${LOCK_FILE}) + if [ -e /proc/${SPID}/status ]; then + exit 1 + fi + cat /dev/null > ${LOCK_FILE} + fi + echo $$ > ${LOCK_FILE} + + /etc/init.d/${CONFIG} restart >/dev/null 2>&1 & + logger -p notice -t network -s "${CONFIG}: restart when $INTERFACE ifup" + + rm -rf ${LOCK_FILE} + } +} diff --git a/luci-app-passwall2/root/etc/init.d/passwall2 b/luci-app-passwall2/root/etc/init.d/passwall2 new file mode 100755 index 00000000..dfc58730 --- /dev/null +++ b/luci-app-passwall2/root/etc/init.d/passwall2 @@ -0,0 +1,85 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=15 + +. $IPKG_INSTROOT/usr/share/passwall2/utils.sh +APP_FILE=${APP_PATH}/app.sh +LOCK_FILE_DIR=/var/lock +LOCK_FILE=${LOCK_FILE_DIR}/${CONFIG}.lock + +set_lock() { + [ ! -d "$LOCK_FILE_DIR" ] && mkdir -p $LOCK_FILE_DIR + exec 999>"$LOCK_FILE" + flock -xn 999 +} + +unset_lock() { + flock -u 999 + rm -rf "$LOCK_FILE" +} + +unlock() { + failcount=1 + while [ "$failcount" -le 10 ]; do + if [ -f "$LOCK_FILE" ]; then + let "failcount++" + sleep 1s + [ "$failcount" -ge 10 ] && unset_lock + else + break + fi + done +} + +boot_func() { + local delay=$(uci -q get ${CONFIG}.@global_delay[0].start_delay || echo 1) + if [ "$delay" -gt 0 ]; then + log_i18n 0 "Start after a delay of %s seconds!" "${delay}" + sleep $delay + fi + restart boot + touch ${LOCK_FILE_DIR}/${CONFIG}_ready.lock +} + +boot() { + boot_func >/dev/null 2>&1 & +} + +start() { + set_lock + [ $? == 1 ] && log_i18n 0 "The script is already running, do not run it again. Exit." && exit 0 + $APP_FILE start + unset_lock +} + +stop() { + unlock + set_lock + [ $? == 1 ] && log_i18n 0 "Stop the script and wait for a timeout, then exit without repeating the process." && exit 0 + $APP_FILE stop + unset_lock +} + +restart() { + set_lock + [ $? == 1 ] && log_i18n 0 "The script is already running, do not run it again. Exit." && exit 0 + rule_lock=${LOCK_FILE_DIR}/${CONFIG}_rule_update.lock + sub_lock=${LOCK_FILE_DIR}/${CONFIG}_subscribe.lock + for i in $(seq 1 300); do + if [ ! -f "$rule_lock" ] && [ ! -f "$sub_lock" ]; then + break + fi + sleep 2 + done + rm -f "$rule_lock" "$sub_lock" + $APP_FILE stop + $APP_FILE start $1 + unset_lock +} + +reload() { + echo "Warning: This service does not support configuration reloading" + echo "Performing full restart instead..." + restart +} diff --git a/luci-app-passwall2/root/etc/init.d/passwall2_server b/luci-app-passwall2/root/etc/init.d/passwall2_server new file mode 100755 index 00000000..1cf39fea --- /dev/null +++ b/luci-app-passwall2/root/etc/init.d/passwall2_server @@ -0,0 +1,22 @@ +#!/bin/sh /etc/rc.common + +START=99 + +start() { + lua /usr/lib/lua/luci/passwall2/server_app.lua start +} + +stop() { + lua /usr/lib/lua/luci/passwall2/server_app.lua stop +} + +restart() { + stop + start +} + +reload() { + echo "Warning: This service does not support configuration reloading" + echo "Performing full restart instead..." + restart +} diff --git a/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 b/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 new file mode 100755 index 00000000..a85b1d90 --- /dev/null +++ b/luci-app-passwall2/root/etc/uci-defaults/luci-passwall2 @@ -0,0 +1,60 @@ +#!/bin/sh + +if [ -e "/etc/config/ucitrack" ]; then + uci -q batch <<-EOF + delete ucitrack.@passwall2[-1] + add ucitrack passwall2 + set ucitrack.@passwall2[-1].init=passwall2 + delete ucitrack.@passwall2_server[-1] + add ucitrack passwall2_server + set ucitrack.@passwall2_server[-1].init=passwall2_server + commit ucitrack +EOF +fi + +uci -q batch <<-EOF + delete firewall.passwall2 + set firewall.passwall2=include + set firewall.passwall2.type='script' + set firewall.passwall2.path='/var/etc/passwall2.include' + + delete firewall.passwall2_server + set firewall.passwall2_server=include + set firewall.passwall2_server.type='script' + set firewall.passwall2_server.path='/var/etc/passwall2_server.include' + + set dhcp.@dnsmasq[0].localuse=1 + commit dhcp + + set uhttpd.main.max_requests=50 + commit uhttpd +EOF + +if [ -x "/sbin/fw3" ]; then + uci -q set firewall.passwall2.reload='1' + uci -q set firewall.passwall2_server.reload='1' +else + uci -q delete firewall.passwall2.reload + uci -q delete firewall.passwall2.fw4_compatible + uci -q delete firewall.passwall2_server.reload + uci -q delete firewall.passwall2_server.fw4_compatible +fi +uci commit firewall + + +[ ! -s "/etc/config/passwall2" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2 + +chmod +x /usr/share/passwall2/*.sh + +[ "$(uci -q get passwall2.@global_xray[0].sniffing)" == "1" ] && [ "$(uci -q get passwall2.@global_xray[0].route_only)" != "1" ] && uci -q set passwall2.@global_xray[0].sniffing_override_dest=1 +uci -q delete passwall2.@global_xray[0].sniffing +uci -q delete passwall2.@global_xray[0].route_only +uci -q commit passwall2 + +sed -i "s#add_from#group#g" /etc/config/passwall2 2>/dev/null + +rm -f /tmp/luci-indexcache /tmp/luci-indexcache.* +rm -rf /tmp/luci-modulecache/ +killall -HUP rpcd 2>/dev/null + +exit 0 diff --git a/luci-app-passwall2/root/usr/share/passwall2/0_default_config b/luci-app-passwall2/root/usr/share/passwall2/0_default_config new file mode 100644 index 00000000..647a2d98 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/0_default_config @@ -0,0 +1,111 @@ + +config global + option enabled '0' + option node_socks_port '1070' + option localhost_proxy '1' + option client_proxy '1' + option socks_enabled '0' + option acl_enable '0' + option node 'rulenode' + option direct_dns_protocol 'auto' + option direct_dns_query_strategy 'UseIP' + option remote_dns_protocol 'tcp' + option remote_dns '1.1.1.1' + option remote_dns_query_strategy 'UseIPv4' + option dns_hosts 'cloudflare-dns.com 1.1.1.1 +dns.google.com 8.8.8.8' + option log_node '1' + option loglevel 'error' + +config global_haproxy + option balancing_enable '0' + +config global_delay + option start_daemon '1' + option start_delay '60' + +config global_forwarding + option tcp_no_redir_ports 'disable' + option udp_no_redir_ports 'disable' + option tcp_redir_ports '1:65535' + option udp_redir_ports '1:65535' + option accept_icmp '0' + option prefer_nft '1' + option tcp_proxy_way 'redirect' + option ipv6_tproxy '0' + +config global_xray + option sniffing_override_dest '0' + +config global_other + option auto_detection_time 'tcping' + option show_node_info '0' + +config global_rules + option auto_update '0' + option geosite_update '1' + option geoip_update '1' + option v2ray_location_asset '/usr/share/v2ray/' + option geoip_url 'https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat' + option geosite_url 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat' + +config global_app + option geoview_file '/usr/bin/geoview' + option xray_file '/usr/bin/xray' + option hysteria_file '/usr/bin/hysteria' + option sing_box_file '/usr/bin/sing-box' + +config global_subscribe + option filter_keyword_mode '1' + +config global_singbox + +config shunt_rules 'China' + option remarks 'China' + option network 'tcp,udp' + option domain_list 'geosite:cn' + option ip_list 'geoip:cn' + +config shunt_rules 'Iran' + option remarks 'Iran' + option network 'tcp,udp' + option domain_list 'geosite:ir +#rule-set:remote:https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geosite-ir.srs' + option ip_list 'geoip:ir +#rule-set:remote:https://raw.githubusercontent.com/Chocolate4U/Iran-sing-box-rules/rule-set/geoip-ir.srs' + +config shunt_rules 'Russia_Block' + option remarks 'Russia_Block' + option network 'tcp,udp' + option domain_list 'geosite:ru-blocked +#rule-set:remote:https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-geosite/geosite-ru-blocked.srs' + option ip_list 'geoip:ru-blocked +#rule-set:remote:https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-geoip/geoip-ru-blocked.srs' + +config shunt_rules 'Russia' + option remarks 'Russia' + option network 'tcp,udp' + option ip_list 'geoip:ru +#rule-set:remote:https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-geoip/geoip-ru.srs' + +config nodes 'examplenode' + option remarks 'Example' + option type 'Xray' + option protocol 'socks' + option address 'passwall2.github' + option port '1080' + option tls '0' + option transport 'raw' + option tcp_guise 'none' + option tcp_fast_open '0' + option tcpMptcp '0' + +config nodes 'rulenode' + option remarks 'rulenode' + option type 'Xray' + option protocol '_shunt' + option default_node 'examplenode' + option domainStrategy 'IPOnDemand' + option domainMatcher 'hybrid' + option write_ipset_direct '1' + option enable_geoview_ip '1' diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh new file mode 100755 index 00000000..b65a3217 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -0,0 +1,1353 @@ +#!/bin/sh +# Copyright (C) 2022-2025 xiaorouji +# Copyright (C) 2026 Openwrt-Passwall Organization + +. /lib/functions.sh +. /lib/functions/service.sh +. /usr/share/libubox/jshn.sh + +. /usr/share/passwall2/utils.sh +GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default +LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2 +UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua +UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua +UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua +UTIL_NAIVE=$LUA_UTIL_PATH/util_naiveproxy.lua +UTIL_HYSTERIA2=$LUA_UTIL_PATH/util_hysteria2.lua +SINGBOX_BIN=$(first_type $(config_t_get global_app sing_box_file) sing-box) +XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray) + +check_run_environment() { + local prefer_nft=$(config_t_get global_forwarding prefer_nft 1) + local dnsmasq_info=$(dnsmasq -v 2>/dev/null) + local dnsmasq_ver=$(echo "$dnsmasq_info" | sed -n '1s/.*version \([0-9.]*\).*/\1/p') + # local dnsmasq_opts=$(echo "$dnsmasq_info" | grep -i "Compile time options") + local dnsmasq_ipset=0; echo "$dnsmasq_info" | grep -qw "ipset" && dnsmasq_ipset=1 + local dnsmasq_nftset=0; echo "$dnsmasq_info" | grep -qw "nftset" && dnsmasq_nftset=1 + local has_ipt=0; { command -v iptables-legacy || command -v iptables; } >/dev/null && has_ipt=1 + local has_ipset=$(command -v ipset >/dev/null && echo 1 || echo 0) + local has_fw4=$(command -v fw4 >/dev/null && echo 1 || echo 0) + if [ "$prefer_nft" = "1" ]; then + if [ "$dnsmasq_nftset" -eq 1 ] && [ "$has_fw4" -eq 1 ]; then + USE_TABLES="nftables" + elif [ "$has_ipset" -eq 1 ] && [ "$has_ipt" -eq 1 ] && [ "$dnsmasq_ipset" -eq 1 ]; then + log_i18n 0 "Warning: The %s application environment is incomplete. Switch to %s. (%s)" "nftables (fw4)" "iptables" "has_fw4:$has_fw4/dnsmasq_nftset:$dnsmasq_nftset" + USE_TABLES="iptables" + fi + else + if [ "$has_ipset" -eq 1 ] && [ "$has_ipt" -eq 1 ] && [ "$dnsmasq_ipset" -eq 1 ]; then + USE_TABLES="iptables" + elif [ "$dnsmasq_nftset" -eq 1 ] && [ "$has_fw4" -eq 1 ]; then + log_i18n 0 "Warning: The %s application environment is incomplete. Switch to %s. (%s)" "iptables (fw3)" "nftables" "has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_ipset:$dnsmasq_ipset" + USE_TABLES="nftables" + fi + fi + + if [ -n "$USE_TABLES" ]; then + local dep_list + local file_path="/usr/lib/opkg/info" + local file_ext=".control" + [ -d "/lib/apk/packages" ] && { file_path="/lib/apk/packages"; file_ext=".list"; } + + if [ "$USE_TABLES" = "iptables" ]; then + dep_list="iptables-mod-tproxy iptables-mod-socket iptables-mod-iprange iptables-mod-conntrack-extra kmod-ipt-nat" + else + dep_list="kmod-nft-socket kmod-nft-tproxy kmod-nft-nat" + nftflag=1 + local v_num=$(echo "$dnsmasq_ver" | tr -cd '0-9') + if [ "${v_num:-0}" -lt 290 ]; then + log_i18n 0 "Note: Dnsmasq (%s) is below 2.90. Upgrading is recommended to improve stability." "${dnsmasq_ver}" + fi + fi + local pkg + for pkg in $dep_list; do + if [ ! -s "${file_path}/${pkg}${file_ext}" ]; then + log_i18n 0 "Warning: %s transparent proxy is missing basic dependency %s!" "${USE_TABLES}" "${pkg}" + fi + done + else + log 0 "$(i18n "Warning: Not compatible with any transparent proxy system environment.") (has_fw4:$has_fw4/has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_nftset:$dnsmasq_nftset/dnsmasq_ipset:$dnsmasq_ipset)" + fi +} + +run_xray() { + local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password + local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache + local loglevel log_file config_file + eval_set_val $@ + node_protocol=$(config_n_get $node protocol) + [ -n "$log_file" ] || local log_file="/dev/null" + [ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning") + + json_init + json_add_string "loglevel" "${loglevel}" + + [ -n "$flag" ] && { + busybox pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1 + json_add_string "flag" "${flag}" + } + [ -n "$socks_address" ] && [ -n "$socks_port" ] && { + json_add_string "local_socks_address" "${socks_address}" + json_add_string "local_socks_port" "${socks_port}" + [ -n "$socks_username" ] && [ -n "$socks_password" ] && { + json_add_string "local_socks_username" "${socks_username}" + json_add_string "local_socks_password" "${socks_password}" + } + } + [ -n "$http_address" ] && [ -n "$http_port" ] && { + json_add_string "local_http_address" "${http_address}" + json_add_string "local_http_port" "${http_port}" + [ -n "$http_username" ] && [ -n "$http_password" ] && { + json_add_string "local_http_username" "${http_username}" + json_add_string "local_http_password" "${http_password}" + } + } + [ -n "$dns_listen_port" ] && { + json_add_string "dns_listen_port" "${dns_listen_port}" + [ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}" + [ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0) + [ "${write_ipset_direct}" = "1" ] && { + direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp) + local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf + [ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf + if [ "${nftflag}" = "1" ]; then + local direct_nftset4="psw2_${node}_white" + local direct_nftset6="psw2_${node}_white6" + local direct_nftset="4#inet#passwall2#${direct_nftset4},6#inet#passwall2#${direct_nftset6}" + else + local direct_ipset4="psw2_${node}_white" + local direct_ipset6="psw2_${node}_white6" + local direct_ipset="${direct_ipset4},${direct_ipset6}" + fi + run_ipset_dns_server listen_port=${direct_dnsmasq_listen_port} server_dns=${AUTO_DNS} ipset="${direct_ipset}" nftset="${direct_nftset}" config_file=${direct_ipset_conf} + DIRECT_DNS_UDP_PORT=${direct_dnsmasq_listen_port} + DIRECT_DNS_UDP_SERVER="127.0.0.1" + [ -n "${direct_ipset}" ] && { + json_add_string "direct_ipset" "${direct_ipset}" + set_cache_var "node_${node}_direct_ipset4" "${direct_ipset4}" + set_cache_var "node_${node}_direct_ipset6" "${direct_ipset6}" + } + [ -n "${direct_nftset}" ] && { + json_add_string "direct_nftset" "${direct_nftset}" + set_cache_var "node_${node}_direct_nftset4" "${direct_nftset4}" + set_cache_var "node_${node}_direct_nftset6" "${direct_nftset6}" + } + } + [ "$remote_fakedns" = "1" ] && { + json_add_string "remote_dns_fake" "1" + json_add_string "remote_dns_fake_strategy" "${remote_dns_query_strategy}" + } + case "$remote_dns_protocol" in + udp) + local _dns=$(get_first_dns remote_dns_udp_server 53 | sed 's/#/:/g') + local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}') + local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}') + json_add_string "remote_dns_udp_port" "${_dns_port}" + json_add_string "remote_dns_udp_server" "${_dns_address}" + ;; + tcp) + local _dns=$(get_first_dns remote_dns_tcp_server 53 | sed 's/#/:/g') + local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}') + local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}') + json_add_string "remote_dns_tcp_port" "${_dns_port}" + json_add_string "remote_dns_tcp_server" "${_dns_address}" + ;; + doh) + local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}') + local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")") + #local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}') + local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') + local is_ip=$(lua_api "is_ip(\"${_doh_host}\")") + local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') + [ -z "${_doh_port}" ] && _doh_port=443 + local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-) + [ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} + json_add_string "remote_dns_doh_port" "${_doh_port}" + json_add_string "remote_dns_doh_url" "${_doh_url}" + json_add_string "remote_dns_doh_host" "${_doh_host}" + [ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_doh_ip" "${_doh_bootstrap}" + ;; + esac + [ -n "$remote_dns_detour" ] && json_add_string "remote_dns_detour" "${remote_dns_detour}" + [ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}" + [ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}" + } + json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}" + json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}" + json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}" + + [ -n "${redir_port}" ] && { + json_add_string "redir_port" "${redir_port}" + set_cache_var "node_${node}_redir_port" "${redir_port}" + [ -n "${tcp_proxy_way}" ] && json_add_string "tcp_proxy_way" "${tcp_proxy_way}" + } + + json_add_string "node" "${node}" + + local _json_arg="$(json_dump)" + lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file + + test_log_file=$log_file + [ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/test.log" + + $XRAY_BIN run -test -c "$config_file" > $test_log_file; local status=$? + if [ "${status}" == 0 ]; then + ln_run ${QUEUE_RUN} "$XRAY_BIN" xray $log_file run -c "$config_file" + else + _error_log_file=$test_log_file + return ${status} + fi +} + +run_singbox() { + local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password + local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache + local loglevel log_file config_file + eval_set_val $@ + local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + [ -z "$type" ] && return 1 + node_protocol=$(config_n_get $node protocol) + [ -n "$log_file" ] || local log_file="/dev/null" + [ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn") + [ "$loglevel" = "warning" ] && loglevel="warn" + local singbox_tag=$($SINGBOX_BIN version | grep 'Tags:' | awk '{print $2}') + + json_init + json_add_string "tags" "${singbox_tag}" + + if [ "$log_file" = "/dev/null" ]; then + json_add_string "log" "0" + else + json_add_string "log" "1" + json_add_string "logfile" "${log_file}" + fi + json_add_string "loglevel" "${loglevel}" + + [ -n "$flag" ] && { + busybox pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1 + json_add_string "flag" "${flag}" + } + [ -n "$socks_address" ] && [ -n "$socks_port" ] && { + json_add_string "local_socks_address" "${socks_address}" + json_add_string "local_socks_port" "${socks_port}" + [ -n "$socks_username" ] && [ -n "$socks_password" ] && { + json_add_string "local_socks_username" "${socks_username}" + json_add_string "local_socks_password" "${socks_password}" + } + } + [ -n "$http_address" ] && [ -n "$http_port" ] && { + json_add_string "local_http_address" "${http_address}" + json_add_string "local_http_port" "${http_port}" + [ -n "$http_username" ] && [ -n "$http_password" ] && { + json_add_string "local_http_username" "${http_username}" + json_add_string "local_http_password" "${http_password}" + } + } + [ -n "$dns_listen_port" ] && { + [ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0) + [ "${write_ipset_direct}" = "1" ] && { + direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp) + local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf + [ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf + if [ "${nftflag}" = "1" ]; then + local direct_nftset4="psw2_${node}_white" + local direct_nftset6="psw2_${node}_white6" + local direct_nftset="4#inet#passwall2#${direct_nftset4},6#inet#passwall2#${direct_nftset6}" + else + local direct_ipset4="psw2_${node}_white" + local direct_ipset6="psw2_${node}_white6" + local direct_ipset="${direct_ipset4},${direct_ipset6}" + fi + run_ipset_dns_server listen_port=${direct_dnsmasq_listen_port} server_dns=${AUTO_DNS} ipset="${direct_ipset}" nftset="${direct_nftset}" config_file=${direct_ipset_conf} + DIRECT_DNS_UDP_PORT=${direct_dnsmasq_listen_port} + DIRECT_DNS_UDP_SERVER="127.0.0.1" + [ -n "${direct_ipset}" ] && { + json_add_string "direct_ipset" "${direct_ipset}" + set_cache_var "node_${node}_direct_ipset4" "${direct_ipset4}" + set_cache_var "node_${node}_direct_ipset6" "${direct_ipset6}" + } + [ -n "${direct_nftset}" ] && { + json_add_string "direct_nftset" "${direct_nftset}" + set_cache_var "node_${node}_direct_nftset4" "${direct_nftset4}" + set_cache_var "node_${node}_direct_nftset6" "${direct_nftset6}" + } + } + + case "$remote_dns_protocol" in + udp|\ + quic) + local _dns=$(get_first_dns remote_dns_udp_server 53 | sed 's/#/:/g') + local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}') + local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}') + json_add_string "remote_dns_udp_port" "${_dns_port}" + json_add_string "remote_dns_udp_server" "${_dns_address}" + [ "$remote_dns_protocol" == "quic" ] && json_add_string "remote_dns_quic" "1" + ;; + tcp|\ + tls) + local _dns=$(get_first_dns remote_dns_tcp_server 53 | sed 's/#/:/g') + local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}') + local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}') + json_add_string "remote_dns_tcp_port" "${_dns_port}" + json_add_string "remote_dns_tcp_server" "${_dns_address}" + [ "$remote_dns_protocol" == "tls" ] && json_add_string "remote_dns_tls" "1" + ;; + doh|\ + http3) + local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}') + local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")") + #local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}') + local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') + local is_ip=$(lua_api "is_ip(\"${_doh_host}\")") + local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') + [ -z "${_doh_port}" ] && _doh_port=443 + local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-) + [ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} + [ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_doh_ip" "${_doh_bootstrap}" + json_add_string "remote_dns_doh_port" "${_doh_port}" + json_add_string "remote_dns_doh_url" "${_doh_url}" + json_add_string "remote_dns_doh_host" "${_doh_host}" + [ "$remote_dns_protocol" == "http3" ] && json_add_string "remote_dns_http3" "1" + ;; + esac + + [ -n "$remote_dns_detour" ] && json_add_string "remote_dns_detour" "${remote_dns_detour}" + [ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}" + [ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}" + + [ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}" + [ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}" + [ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1" + } + json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}" + json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}" + json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}" + + [ -n "${redir_port}" ] && { + json_add_string "redir_port" "${redir_port}" + set_cache_var "node_${node}_redir_port" "${redir_port}" + [ -n "${tcp_proxy_way}" ] && json_add_string "tcp_proxy_way" "${tcp_proxy_way}" + } + + json_add_string "node" "${node}" + + local _json_arg="$(json_dump)" + lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file + + test_log_file=$log_file + [ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/test.log" + + $SINGBOX_BIN check -c "$config_file" > $test_log_file 2>&1; local status=$? + if [ "${status}" == 0 ]; then + ln_run ${QUEUE_RUN} "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file" + else + _error_log_file=$test_log_file + return ${status} + fi +} + +run_socks() { + local flag node bind socks_port config_file http_port http_config_file relay_port log_file no_run + eval_set_val $@ + [ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file + [ -n "$http_port" ] || http_port=0 + [ -n "$http_config_file" ] && [ -z "$(echo ${http_config_file} | grep $TMP_PATH)" ] && http_config_file=$TMP_PATH/$http_config_file + if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then + log_file=$TMP_PATH/$log_file + else + log_file="/dev/null" + fi + local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + local remarks=$(config_n_get $node remarks) + local server_host=$(config_n_get $node address) + local server_port=$(config_n_get $node port) + [ -n "$relay_port" ] && { + server_host="127.0.0.1" + server_port=$relay_port + } + local error_msg tmp + + if [ -n "$server_host" ] && [ -n "$server_port" ]; then + check_host $server_host + [ $? != 0 ] && { + log 1 "$(i18n "Socks node: [%s]%s is an invalid server address and cannot be started!" "${$remarks}" "${server_host}")" + return 1 + } + tmp="${server_host}:${server_port}" + else + error_msg="$(i18n "For some reason, the configuration for this Socks service has been lost, and its startup has been aborted!")" + fi + + if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then + local protocol=$(config_n_get $node protocol) + if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ] || [ "$protocol" == "_urltest" ]; then + unset error_msg + fi + fi + + if [ -n "${error_msg}" ] && ([ -n "$(config_n_get $node hysteria_hop)" ] || [ -n "$(config_n_get $node hysteria2_hop)" ] || [ "$(config_n_get $node hysteria2_realms)" = "1" ]); then + unset error_msg + fi + + [ -n "${error_msg}" ] && { + [ "$bind" != "127.0.0.1" ] && log 1 "$(i18n "Socks node: [%s]%s, start failed %s:%s %s" "${remarks}" "${tmp}" "${bind}" "${socks_port}" "${error_msg}")" + return 1 + } + [ "$bind" != "127.0.0.1" ] && log 1 "$(i18n "Socks node: [%s]%s, starting %s:%s" "${remarks}" "${tmp}" "${bind}" "${socks_port}")" + + json_init + json_add_string "node" "${node}" + json_add_string "server_host" "${server_host}" + json_add_string "server_port" "${server_port}" + case "$type" in + sing-box) + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "${bind}" + json_add_string "local_http_port" "${http_port}" + } + [ -z "$relay_port" ] && { + json_add_null "server_host" + json_add_null "server_port" + } + [ "${log_file}" != "/dev/null" ] && { + local loglevel=$(config_t_get global loglevel "warn") + [ "$loglevel" = "warning" ] && loglevel="warn" + json_add_string "log" "1" + json_add_string "loglevel" "${loglevel}" + json_add_string "logfile" "${log_file}" + } + [ -n "$no_run" ] && json_add_string "no_run" "1" + json_add_string "flag" "SOCKS_${flag}" + json_add_string "local_socks_address" "${bind}" + json_add_string "local_socks_port" "${socks_port}" + json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}" + json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}" + json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}" + local _json_arg="$(json_dump)" + lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$SINGBOX_BIN" "sing-box" /dev/null run -c "$config_file" + ;; + xray) + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "${bind}" + json_add_string "local_http_port" "${http_port}" + } + [ -z "$relay_port" ] && { + json_add_null "server_host" + json_add_null "server_port" + } + [ -n "$no_run" ] && json_add_string "no_run" "1" + json_add_string "flag" "SOCKS_${flag}" + json_add_string "local_socks_address" "${bind}" + json_add_string "local_socks_port" "${socks_port}" + json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}" + json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}" + json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}" + local _json_arg="$(json_dump)" + lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$XRAY_BIN" "xray" $log_file run -c "$config_file" + ;; + naiveproxy) + json_add_string "local_addr" "${bind}" + json_add_string "local_port" "${socks_port}" + json_add_string "run_type" "socks" + local _json_arg="$(json_dump)" + lua $UTIL_NAIVE gen_config "${_json_arg}" > $config_file + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type naive)" naive $log_file "$config_file" + ;; + ssr) + json_add_string "local_addr" "${bind}" + json_add_string "local_port" "${socks_port}" + local _json_arg="$(json_dump)" + lua $UTIL_SS gen_config "${_json_arg}" > $config_file + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u + ;; + ss-rust) + json_add_string "local_socks_address" "${bind}" + json_add_string "local_socks_port" "${socks_port}" + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "${bind}" + json_add_string "local_http_port" "${http_port}" + } + [ -z "$no_run" ] && { + local plugin_sh="${config_file%.json}_plugin.sh" + json_add_string "plugin_sh" "${plugin_sh}" + } + local _json_arg="$(json_dump)" + lua $UTIL_SS gen_config "${_json_arg}" > $config_file + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v + ;; + hysteria2) + json_add_string "local_socks_address" "${bind}" + json_add_string "local_socks_port" "${socks_port}" + [ "$http_port" != "0" ] && { + http_flag=1 + config_file="${config_file//SOCKS/HTTP_SOCKS}" + json_add_string "local_http_address" "${bind}" + json_add_string "local_http_port" "${http_port}" + } + local _json_arg="$(json_dump)" + lua $UTIL_HYSTERIA2 gen_config "${_json_arg}" > $config_file + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client + ;; + esac + + # http to socks + [ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && { + json_init + json_add_string "local_http_port" "${http_port}" + json_add_string "server_proto" "socks" + json_add_string "server_address" "127.0.0.1" + json_add_string "server_port" "${socks_port}" + json_add_string "server_username" "${_username}" + json_add_string "server_password" "${_password}" + local _json_arg="$(json_dump)" + if [ -n "${SINGBOX_BIN}" ]; then + type="sing-box" + local bin="${SINGBOX_BIN}" + local util="${UTIL_SINGBOX}" + elif [ -n "${XRAY_BIN}" ]; then + type="xray" + local bin="${XRAY_BIN}" + local util="${UTIL_XRAY}" + fi + [ -n "${bin}" ] && [ -n "${util}" ] && { + lua ${util} gen_proto_config "${_json_arg}" > ${http_config_file} + [ -z "$no_run" ] && ln_run ${QUEUE_RUN} "${bin}" ${type} /dev/null run -c ${http_config_file} + } + unset bin util + } + unset http_flag + + [ -z "$no_run" ] && [ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list +} + +socks_node_switch() { + local flag new_node + eval_set_val $@ + [ -n "$flag" ] && [ -n "$new_node" ] && { + local prefix pf filename + # Kill the SS plugin process + for prefix in "" "HTTP_"; do + pf="$TMP_PATH/${prefix}SOCKS_${flag}_plugin.pid" + [ -s "$pf" ] && kill -9 "$(head -n1 "$pf")" >/dev/null 2>&1 + done + + busybox pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1 + for prefix in "" "HTTP_" "HTTP2"; do + rm -rf "$TMP_PATH/${prefix}SOCKS_${flag}"* + done + + for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do + cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename}) + [ -n "$(echo $cmd | grep "${flag}")" ] && rm -f ${TMP_SCRIPT_FUNC_PATH}/${filename} + done + local bind_local=$(config_n_get $flag bind_local 0) + local bind="0.0.0.0" + [ "$bind_local" = "1" ] && bind="127.0.0.1" + local port=$(config_n_get $flag port) + local config_file="SOCKS_${flag}.json" + local log_file="SOCKS_${flag}.log" + local log=$(config_n_get $flag log 1) + [ "$log" == "0" ] && log_file="" + local http_port=$(config_n_get $flag http_port 0) + local http_config_file="HTTP2SOCKS_${flag}.json" + LOG_FILE="/dev/null" + run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file + set_cache_var "socks_${flag}" "$new_node" + local USE_TABLES=$(get_cache_var "USE_TABLES") + [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list + } +} + +run_global() { + [ -z "$NODE" ] && return 1 + TYPE=$(echo $(config_n_get $NODE type) | tr 'A-Z' 'a-z') + [ -z "$TYPE" ] && return 1 + + if [ $PROXY_IPV6 == "1" ]; then + log_i18n 0 "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!" + fi + + TUN_DNS_PORT=15353 + TUN_DNS="127.0.0.1#${TUN_DNS_PORT}" + + V2RAY_ARGS="flag=global node=$NODE redir_port=$REDIR_PORT tcp_proxy_way=${TCP_PROXY_WAY}" + V2RAY_ARGS="${V2RAY_ARGS} dns_listen_port=${TUN_DNS_PORT} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY} dns_cache=${DNS_CACHE}" + local dns_msg="DNS: ${TUN_DNS} ($(i18n "Direct DNS: %s" "${AUTO_DNS}")" + + [ -n "$REMOTE_DNS_PROTOCOL" ] && { + V2RAY_ARGS="${V2RAY_ARGS} remote_dns_protocol=${REMOTE_DNS_PROTOCOL} remote_dns_detour=${REMOTE_DNS_DETOUR}" + case "$REMOTE_DNS_PROTOCOL" in + udp|\ + quic) + V2RAY_ARGS="${V2RAY_ARGS} remote_dns_udp_server=${REMOTE_DNS}" + dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS}")" + ;; + tcp|\ + tls) + V2RAY_ARGS="${V2RAY_ARGS} remote_dns_tcp_server=${REMOTE_DNS}" + dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS}")" + ;; + doh|\ + http3) + REMOTE_DNS_DOH=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") + V2RAY_ARGS="${V2RAY_ARGS} remote_dns_doh=${REMOTE_DNS_DOH}" + dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS_DOH}")" + ;; + esac + [ "$REMOTE_FAKEDNS" = "1" ] && { + V2RAY_ARGS="${V2RAY_ARGS} remote_fakedns=1" + dns_msg="${dns_msg} + FakeDNS " + } + + local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip) + [ -n "${_remote_dns_client_ip}" ] && V2RAY_ARGS="${V2RAY_ARGS} remote_dns_client_ip=${_remote_dns_client_ip}" + } + dns_msg="${dns_msg})" + + V2RAY_CONFIG=${GLOBAL_ACL_PATH}/global.json + V2RAY_LOG=${GLOBAL_ACL_PATH}/global.log + [ "$(config_t_get global log_node 1)" != "1" ] && V2RAY_LOG="/dev/null" + V2RAY_ARGS="${V2RAY_ARGS} log_file=${V2RAY_LOG} config_file=${V2RAY_CONFIG}" + + node_socks_port=$(config_t_get global node_socks_port 1070) + node_socks_bind_local=$(config_t_get global node_socks_bind_local 1) + node_socks_bind="127.0.0.1" + [ "${node_socks_bind_local}" != "1" ] && node_socks_bind="0.0.0.0" + V2RAY_ARGS="${V2RAY_ARGS} socks_address=${node_socks_bind} socks_port=${node_socks_port}" + set_cache_var "GLOBAL_SOCKS_server" "127.0.0.1:$node_socks_port" + + node_http_port=$(config_t_get global node_http_port 0) + [ "$node_http_port" != "0" ] && V2RAY_ARGS="${V2RAY_ARGS} http_port=${node_http_port}" + + local run_func + [ -n "${XRAY_BIN}" ] && run_func="run_xray" + [ -n "${SINGBOX_BIN}" ] && run_func="run_singbox" + if [ "${TYPE}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then + run_func="run_xray" + elif [ "${TYPE}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then + run_func="run_singbox" + fi + + ${run_func} ${V2RAY_ARGS}; local status=$? + + if [ "$status" == 0 ]; then + log 0 ${dns_msg} + else + log_i18n 0 "[%s] process %s error, skip this transparent proxy!" $(i18n "Global") "${V2RAY_CONFIG}" + cat ${_error_log_file} >> ${LOG_FILE} + unset _error_log_file + ENABLED_DEFAULT_ACL=0 + return 1 + fi + + set_cache_var "ACL_GLOBAL_node" "$NODE" + set_cache_var "ACL_GLOBAL_redir_port" "$REDIR_PORT" +} + +run_front_dns() { + local switch=0 + direct_dns_shunt=$(config_t_get global direct_dns_shunt) + direct_dns_shunt=$(echo "${direct_dns_shunt}" | grep -v "^#") + [ -n "${direct_dns_shunt}" ] && switch=1 + [ "${switch}" == "1" ] && { + local config_file="${TMP_PATH}/direct_dns.json" + local log_file="${TMP_PATH}/direct_dns.log" + log_file="/dev/null" + local listen_port=$(get_new_port 10553) + json_init + json_add_string "dns_listen_port" "${listen_port}" + json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}" + json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}" + json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}" + [ -n "${ACL_GLOBAL_node}" ] && [ -n "${TUN_DNS_PORT}" ] && { + json_add_string "default_dns_udp_server" "127.0.0.1" + json_add_string "default_dns_udp_port" "${TUN_DNS_PORT}" + } + local _json_arg="$(json_dump)" + + local prefer_core="" + [ -n "${XRAY_BIN}" ] && prefer_core="xray" + [ -n "${SINGBOX_BIN}" ] && prefer_core="sing-box" + + if [ "${prefer_core}" = "xray" ]; then + lua $UTIL_XRAY gen_front_dns_config "${_json_arg}" > $config_file + ln_run 0 "$XRAY_BIN" "xray" "${log_file}" run -c "$config_file" + elif [ "${prefer_core}" = "sing-box" ]; then + lua $UTIL_SINGBOX gen_front_dns_config "${_json_arg}" > $config_file + ln_run 0 "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file" + else + return 1 + fi + + FRONT_DNS_SERVER="127.0.0.1" + FRONT_DNS_PORT="${listen_port}" + } +} + +run_global_dnsmasq() { + [ -z "${ACL_GLOBAL_node}" ] && [ -z "${FRONT_DNS_PORT}" ] && return + local RUN_NEW_DNSMASQ=1 + RUN_NEW_DNSMASQ=${DNS_REDIRECT} + DNSMASQ_DEFAULT_DNS="${AUTO_DNS}" + DNSMASQ_LOCAL_DNS="${LOCAL_DNS:-${AUTO_DNS}}" + DNSMASQ_TUN_DNS="${TUN_DNS}" + [ -n "${FRONT_DNS_PORT}" ] && { + DNSMASQ_DEFAULT_DNS="${FRONT_DNS_SERVER}#${FRONT_DNS_PORT}" + DNSMASQ_LOCAL_DNS="${DNSMASQ_DEFAULT_DNS}" + DNSMASQ_TUN_DNS="${DNSMASQ_DEFAULT_DNS}" + } + if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then + #The old logic will be removed in the future. + #Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices. + [ "1" = "0" ] && { + DIRECT_DNSMASQ_PORT=$(get_new_port 11400) + DIRECT_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/direct_dnsmasq.conf + DIRECT_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/direct_dnsmasq.d + mkdir -p ${DIRECT_DNSMASQ_CONF_PATH} + json_init + json_add_string "LISTEN_PORT" "${DIRECT_DNSMASQ_PORT}" + json_add_string "DNSMASQ_CONF" "${DIRECT_DNSMASQ_CONF}" + json_add_string "TMP_DNSMASQ_PATH" "${DIRECT_DNSMASQ_CONF_PATH}" + lua $APP_PATH/helper_dnsmasq.lua copy_instance "$(json_dump)" + ln_run 0 "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid + set_cache_var "DIRECT_DNSMASQ_PORT" "${DIRECT_DNSMASQ_PORT}" + } + + #Rewrite the default DNS service configuration + #Modify the default dnsmasq service + lua $APP_PATH/helper_dnsmasq.lua stretch + json_init + json_add_string "FLAG" "default" + json_add_string "TMP_DNSMASQ_PATH" "${GLOBAL_DNSMASQ_CONF_PATH}" + json_add_string "DNSMASQ_CONF_FILE" "${GLOBAL_DNSMASQ_CONF}" + json_add_string "DEFAULT_DNS" "${DNSMASQ_DEFAULT_DNS}" + json_add_string "LOCAL_DNS" "${DNSMASQ_LOCAL_DNS}" + json_add_string "TUN_DNS" "${DNSMASQ_TUN_DNS}" + json_add_string "NFTFLAG" "${nftflag:-0}" + json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}" + lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)" + uci -q add_list dhcp.@dnsmasq[0].addnmount=${GLOBAL_DNSMASQ_CONF_PATH} + uci -q commit dhcp + + json_init + json_add_string "LOG" "1" + lua $APP_PATH/helper_dnsmasq.lua logic_restart "$(json_dump)" + else + #Run a copy dnsmasq instance, DNS hijack for that need proxy devices. + GLOBAL_DNSMASQ_PORT=$(get_new_port 11400) + run_copy_dnsmasq flag="default" listen_port=$GLOBAL_DNSMASQ_PORT local_dns="${DNSMASQ_LOCAL_DNS}" tun_dns="${DNSMASQ_TUN_DNS}" default_dns="${DNSMASQ_DEFAULT_DNS}" + DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT} + #dhcp.leases to hosts + $APP_PATH/lease2hosts.sh > /dev/null 2>&1 & + fi +} + +start_socks() { + [ "$SOCKS_ENABLED" = "1" ] && { + local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') + [ -n "$ids" ] && { + log_i18n 0 "Analyzing the node configuration of the Socks service..." + for id in $ids; do + local enabled=$(config_n_get $id enabled 0) + [ "$enabled" == "0" ] && continue + local node=$(config_n_get $id node) + [ -z "$node" ] && continue + local bind_local=$(config_n_get $id bind_local 0) + local bind="0.0.0.0" + [ "$bind_local" = "1" ] && bind="127.0.0.1" + local port=$(config_n_get $id port) + local config_file="SOCKS_${id}.json" + local log_file="SOCKS_${id}.log" + local log=$(config_n_get $id log 1) + [ "$log" == "0" ] && log_file="" + local http_port=$(config_n_get $id http_port 0) + local http_config_file="HTTP2SOCKS_${id}.json" + run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file + set_cache_var "socks_${id}" "$node" + + # Auto switch logic + local enable_autoswitch=$(config_n_get $id enable_autoswitch 0) + [ "$enable_autoswitch" = "1" ] && { $APP_PATH/socks_auto_switch.sh ${id} > /dev/null 2>&1 & } + done + } + } +} + +clean_crontab() { + [ -f "/tmp/lock/${CONFIG}_cron.lock" ] && return + touch /etc/crontabs/root + #sed -i "/${CONFIG}/d" /etc/crontabs/root >/dev/null 2>&1 + sed -i "/$(echo "/etc/init.d/${CONFIG}" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1 + sed -i "/$(echo "lua ${APP_PATH}/rule_update.lua log" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1 + sed -i "/$(echo "lua ${APP_PATH}/subscribe.lua start" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1 + + busybox pgrep -af "${CONFIG}/" | awk '/tasks\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -rf /tmp/lock/${CONFIG}_tasks.lock +} + +start_crontab() { + if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then + start_daemon=$(config_t_get global_delay start_daemon 0) + [ "$start_daemon" = "1" ] && { $APP_PATH/monitor.sh > /dev/null 2>&1 & } + fi + + [ -f "/tmp/lock/${CONFIG}_cron.lock" ] && { + rm -rf "/tmp/lock/${CONFIG}_cron.lock" + log_i18n 0 "The task is currently running automatically as a scheduled task; no reconfiguration of the scheduled task is required." + return + } + + clean_crontab + + [ "$ENABLED" != 1 ] && { + /etc/init.d/cron restart + return + } + + stop_week_mode=$(config_t_get global_delay stop_week_mode) + stop_time_mode=$(config_t_get global_delay stop_time_mode) + if [ -n "$stop_week_mode" ]; then + local t="0 $stop_time_mode * * $stop_week_mode" + [ "$stop_week_mode" = "7" ] && t="0 $stop_time_mode * * *" + if [ "$stop_week_mode" = "8" ]; then + update_loop=1 + else + echo "$t /etc/init.d/$CONFIG stop > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + log_i18n 0 "Scheduled tasks: Auto stop service." + fi + + start_week_mode=$(config_t_get global_delay start_week_mode) + start_time_mode=$(config_t_get global_delay start_time_mode) + if [ -n "$start_week_mode" ]; then + local t="0 $start_time_mode * * $start_week_mode" + [ "$start_week_mode" = "7" ] && t="0 $start_time_mode * * *" + if [ "$start_week_mode" = "8" ]; then + update_loop=1 + else + echo "$t /etc/init.d/$CONFIG start > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + log_i18n 0 "Scheduled tasks: Auto start service." + fi + + restart_week_mode=$(config_t_get global_delay restart_week_mode) + restart_time_mode=$(config_t_get global_delay restart_time_mode) + if [ -n "$restart_week_mode" ]; then + local t="0 $restart_time_mode * * $restart_week_mode" + [ "$restart_week_mode" = "7" ] && t="0 $restart_time_mode * * *" + if [ "$restart_week_mode" = "8" ]; then + update_loop=1 + else + echo "$t /etc/init.d/$CONFIG restart > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + log_i18n 0 "Scheduled tasks: Auto restart service." + fi + + autoupdate=$(config_t_get global_rules auto_update) + weekupdate=$(config_t_get global_rules week_update) + dayupdate=$(config_t_get global_rules time_update) + if [ "$autoupdate" = "1" ]; then + local t="0 $dayupdate * * $weekupdate" + [ "$weekupdate" = "7" ] && t="0 $dayupdate * * *" + if [ "$weekupdate" = "8" ]; then + update_loop=1 + else + echo "$t lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + log_i18n 0 "Scheduled tasks: Auto update rules." + fi + + TMP_SUB_PATH=$TMP_PATH/sub_crontabs + mkdir -p $TMP_SUB_PATH + for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get $item auto_update 0)" = "1" ]; then + cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1) + remark=$(config_n_get $item remark) + week_update=$(config_n_get $item week_update) + time_update=$(config_n_get $item time_update) + echo "$cfgid" >> $TMP_SUB_PATH/${week_update}_${time_update} + log_i18n 0 "Scheduled tasks: Auto update [%s] subscription." "${remark}" + fi + done + + [ -d "${TMP_SUB_PATH}" ] && { + for name in $(ls ${TMP_SUB_PATH}); do + week_update=$(echo $name | awk -F '_' '{print $1}') + time_update=$(echo $name | awk -F '_' '{print $2}') + cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g') + local t="0 $time_update * * $week_update" + [ "$week_update" = "7" ] && t="0 $time_update * * *" + if [ "$week_update" = "8" ]; then + update_loop=1 + else + echo "$t lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root + fi + done + rm -rf $TMP_SUB_PATH + } + + if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then + [ "$update_loop" = "1" ] && { + $APP_PATH/tasks.sh > /dev/null 2>&1 & + log_i18n 0 "Auto updates: Starts a cyclical update process." + } + else + log_i18n 0 "Running in no proxy mode, it only allows scheduled tasks for starting and stopping services." + fi + + /etc/init.d/cron restart +} + +stop_crontab() { + [ -f "/tmp/lock/${CONFIG}_cron.lock" ] && return + clean_crontab + /etc/init.d/cron restart + #log_i18n 0 "Clear scheduled commands." +} + +start_haproxy() { + [ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return + haproxy_path=$TMP_PATH/haproxy + haproxy_conf="config.cfg" + lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} + ln_run 0 "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}" +} + +run_copy_dnsmasq() { + local flag listen_port local_dns tun_dns default_dns + eval_set_val $@ + local dnsmasq_conf=$TMP_ACL_PATH/$flag/dnsmasq.conf + local dnsmasq_conf_path=$TMP_ACL_PATH/$flag/dnsmasq.d + mkdir -p $dnsmasq_conf_path + + json_init + json_add_string "LISTEN_PORT" "${listen_port}" + json_add_string "DNSMASQ_CONF" "${dnsmasq_conf}" + lua $APP_PATH/helper_dnsmasq.lua copy_instance "$(json_dump)" + + json_init + json_add_string "FLAG" "${flag}" + json_add_string "TMP_DNSMASQ_PATH" "${dnsmasq_conf_path}" + json_add_string "DNSMASQ_CONF_FILE" "${dnsmasq_conf}" + json_add_string "DEFAULT_DNS" "${default_dns}" + json_add_string "LOCAL_DNS" "${local_dns}" + json_add_string "TUN_DNS" "${tun_dns}" + json_add_string "NFTFLAG" "${nftflag:-0}" + json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}" + lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)" + + ln_run 0 "$(first_type dnsmasq)" "dnsmasq_${flag}" "/dev/null" -C $dnsmasq_conf -x $TMP_ACL_PATH/$flag/dnsmasq.pid + set_cache_var "ACL_${flag}_dns_port" "${listen_port}" +} + +run_ipset_dns_server() { + if [ -n "$(first_type chinadns-ng)" ]; then + run_ipset_chinadns_ng $@ + else + run_ipset_dnsmasq $@ + fi +} + +run_ipset_chinadns_ng() { + local listen_port server_dns ipset nftset config_file + eval_set_val $@ + [ ! -s "$TMP_ACL_PATH/vpslist" ] && { + node_servers=$(uci show "${CONFIG}" | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2) + hosts_foreach "node_servers" host_from_url | grep '[a-zA-Z]$' | sort -u | grep -v "engage.cloudflareclient.com" > $TMP_ACL_PATH/vpslist + } + + [ -n "${ipset}" ] && { + set_names=$ipset + vps_set_names="psw2_vps,psw2_vps6" + } + [ -n "${nftset}" ] && { + set_names=$(echo ${nftset} | awk -F, '{printf "%s,%s", substr($1,3), substr($2,3)}' | sed 's/#/@/g') + vps_set_names="inet@passwall2@psw2_vps,inet@passwall2@psw2_vps6" + } + cat <<-EOF > $config_file + bind-addr 127.0.0.1 + bind-port ${listen_port} + china-dns ${server_dns} + trust-dns ${server_dns} + filter-qtype 65 + add-tagchn-ip ${set_names} + default-tag chn + group vpslist + group-dnl $TMP_ACL_PATH/vpslist + group-upstream ${server_dns} + group-ipset ${vps_set_names} + EOF + ln_run 0 "$(first_type chinadns-ng)" "chinadns-ng" "/dev/null" -C $config_file -v +} + +run_ipset_dnsmasq() { + local listen_port server_dns ipset nftset cache_size dns_forward_max config_file + eval_set_val $@ + cat <<-EOF > $config_file + port=${listen_port} + no-poll + no-resolv + strict-order + cache-size=${cache_size:-0} + dns-forward-max=${dns_forward_max:-1000} + EOF + for i in $(echo ${server_dns} | sed "s#,# #g"); do + echo "server=${i}" >> $config_file + done + [ -n "${ipset}" ] && echo "ipset=${ipset}" >> $config_file + [ -n "${nftset}" ] && echo "nftset=${nftset}" >> $config_file + ln_run 0 "$(first_type dnsmasq)" "dnsmasq" "/dev/null" -C $config_file +} + +acl_app() { + local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1) + [ -n "$items" ] && { + local index=0 + local item + local redir_port dns_port dnsmasq_port + local ipt_tmp msg msg2 + redir_port=11200 + dns_port=11300 + dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400} + for item in $items; do + index=$(expr $index + 1) + local enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy + local _ip _mac _iprange _ipset _ip_or_mac source_list config_file + local sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}') + [ "$(config_n_get $sid enabled)" = "1" ] || continue + eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-) + + if [ -n "${sources}" ]; then + for s in $sources; do + local s2 + is_iprange=$(lua_api "iprange(\"${s}\")") + if [ "${is_iprange}" = "true" ]; then + s2="iprange:${s}" + elif [ -n "$(echo ${s} | grep '^ipset:')" ]; then + s2="ipset:${s}" + else + _ip_or_mac=$(lua_api "ip_or_mac(\"${s}\")") + if [ "${_ip_or_mac}" = "ip" ]; then + s2="ip:${s}" + elif [ "${_ip_or_mac}" = "mac" ]; then + s2="mac:${s}" + fi + fi + [ -n "${s2}" ] && source_list="${source_list}\n${s2}" + unset s2 + done + else + source_list="any" + fi + + local acl_path=${TMP_ACL_PATH}/$sid + mkdir -p ${acl_path} + [ -n "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list + + node=${node:-default} + tcp_no_redir_ports=${tcp_no_redir_ports:-default} + udp_no_redir_ports=${udp_no_redir_ports:-default} + [ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS + [ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS + if has_1_65535 "$tcp_no_redir_ports" && has_1_65535 "$udp_no_redir_ports"; then + unset node + fi + + [ -n "$node" ] && { + tcp_proxy_mode="global" + udp_proxy_mode="global" + direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP} + remote_dns_protocol=${remote_dns_protocol:-tcp} + remote_dns=${remote_dns:-1.1.1.1} + case "$remote_dns_protocol" in + doh|\ + http3) + remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query} + ;; + esac + remote_dns_detour=${remote_dns_detour:-remote} + remote_fakedns=${remote_fakedns:-0} + remote_dns_query_strategy=${remote_dns_query_strategy:-UseIPv4} + + local GLOBAL_node=$(get_cache_var "ACL_GLOBAL_node") + [ -n "${GLOBAL_node}" ] && GLOBAL_redir_port=$(get_cache_var "ACL_GLOBAL_redir_port") + + if [ "$node" = "default" ]; then + if [ -n "${GLOBAL_node}" ]; then + set_cache_var "ACL_${sid}_node" "${GLOBAL_node}" + set_cache_var "ACL_${sid}_redir_port" "${GLOBAL_redir_port}" + set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}" + set_cache_var "ACL_${sid}_default" "1" + else + log 1 "$(i18n "Global nodes are not enabled, skip [%s]." "${remarks}")" + fi + else + [ "$(config_get_type $node)" = "nodes" ] && { + if [ -n "${GLOBAL_node}" ] && [ "$node" = "${GLOBAL_node}" ]; then + set_cache_var "ACL_${sid}_node" "${GLOBAL_node}" + set_cache_var "ACL_${sid}_redir_port" "${GLOBAL_redir_port}" + set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}" + set_cache_var "ACL_${sid}_default" "1" + else + redir_port=$(get_new_port $(expr $redir_port + 1)) + + local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') + if [ -n "${type}" ]; then + config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json + dns_port=$(get_new_port $(expr $dns_port + 1)) + local acl_socks_port=$(get_new_port $(expr $redir_port + $index)) + local run_func + [ -n "${XRAY_BIN}" ] && run_func="run_xray" + [ -n "${SINGBOX_BIN}" ] && run_func="run_singbox" + if [ "${type}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then + run_func="run_xray" + elif [ "${type}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then + run_func="run_singbox" + fi + ${run_func} flag=acl_$sid node=$node redir_port=$redir_port tcp_proxy_way=${TCP_PROXY_WAY} \ + socks_address=127.0.0.1 socks_port=$acl_socks_port \ + dns_listen_port=${dns_port} \ + direct_dns_query_strategy=${direct_dns_query_strategy} \ + remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" \ + remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} \ + config_file=${config_file} + local status=$? + if [ "$status" != 0 ]; then + log_i18n 2 "[%s] process %s error, skip this transparent proxy!" "${remarks}" "${config_file}" + cat ${_error_log_file} >> ${LOG_FILE} + unset _error_log_file + continue + fi + fi + dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1)) + run_copy_dnsmasq flag="$sid" listen_port=$dnsmasq_port local_dns="${LOCAL_DNS:-${AUTO_DNS}}" tun_dns="127.0.0.1#${dns_port}" default_dns="${AUTO_DNS}" + #dhcp.leases to hostsMore actions + $APP_PATH/lease2hosts.sh > /dev/null 2>&1 & + + set_cache_var "ACL_${sid}_node" "$node" + set_cache_var "ACL_${sid}_redir_port" "$redir_port" + fi + } + fi + } + unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy + unset _ip _mac _iprange _ipset _ip_or_mac source_list config_file + done + unset redir_port dns_port dnsmasq_port + } +} + +start() { + busybox pgrep -f /tmp/etc/passwall2/bin > /dev/null 2>&1 && { + #log_i18n 0 "The program has started. Please stop it and then restart it!" + stop + } + mkdir -p /tmp/etc /tmp/log $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_PATH2 + get_config + export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/") + export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET + export ENABLE_DEPRECATED_GEOSITE=true + export ENABLE_DEPRECATED_GEOIP=true + export SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN=1 + ulimit -n 65535 + start_haproxy + start_socks + nftflag=0 + USE_TABLES="" + check_run_environment + if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then + [ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && { + uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1' + uci -q commit ${CONFIG} + uci -q set dhcp.@dnsmasq[0].dns_redirect='0' + uci -q commit dhcp + + json_init + json_add_string "LOG" "0" + lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)" + } + fi + mkdir -p ${GLOBAL_ACL_PATH} + [ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global + run_front_dns + run_global_dnsmasq + [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start + set_cache_var "USE_TABLES" "$USE_TABLES" + if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then + bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables) + set_cache_var "bak_bridge_nf_ipt" "$bridge_nf_ipt" + sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1 + [ "$PROXY_IPV6" == "1" ] && { + bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables) + set_cache_var "bak_bridge_nf_ip6t" "$bridge_nf_ip6t" + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1 + } + fi + run_process_queue + start_crontab + log_i18n 0 "Running complete!" + echolog "\n" + + [ "$ENABLED" = 1 ] && [ "$1" = "boot" ] && { + local cfgids item + for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get "$item" boot_update 0)" = "1" ]; then + local cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1) + cfgids="${cfgids:+$cfgids,}$cfgid" + fi + done + [ -n "$cfgids" ] && { + sleep 5 + lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 & + } + } +} + +stop() { + clean_log + eval_cache_var + [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh stop + delete_ip2route + # Kill the SS plugin process + # kill_all xray-plugin v2ray-plugin obfs-local shadow-tls + local pid_file pid + find "$TMP_PATH" -type f -name '*_plugin.pid' 2>/dev/null | while read -r pid_file; do + read -r pid < "$pid_file" + if [ -n "$pid" ]; then + kill -9 "$pid" >/dev/null 2>&1 + fi + done + busybox pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1 + busybox pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh|server_app\.lua|ujail/{print $1}' | xargs kill -9 >/dev/null 2>&1 + unset V2RAY_LOCATION_ASSET + unset XRAY_LOCATION_ASSET + unset SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN + stop_crontab + rm -rf $GLOBAL_DNSMASQ_CONF + rm -rf $GLOBAL_DNSMASQ_CONF_PATH + [ "1" = "1" ] && { + #restore logic + bak_dnsmasq_dns_redirect=$(config_t_get global dnsmasq_dns_redirect) + [ -n "${bak_dnsmasq_dns_redirect}" ] && { + uci -q set dhcp.@dnsmasq[0].dns_redirect="${bak_dnsmasq_dns_redirect}" + uci -q commit dhcp + uci -q delete ${CONFIG}.@global[0].dnsmasq_dns_redirect + uci -q commit ${CONFIG} + } + if [ -z "${ACL_default_dns_port}" ] || [ -n "${bak_dnsmasq_dns_redirect}" ]; then + uci -q del_list dhcp.@dnsmasq[0].addnmount="${GLOBAL_DNSMASQ_CONF_PATH}" + uci -q commit dhcp + + json_init + json_add_string "LOG" "0" + lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)" + fi + [ -n "${bak_bridge_nf_ipt}" ] && sysctl -w net.bridge.bridge-nf-call-iptables=${bak_bridge_nf_ipt} >/dev/null 2>&1 + [ -n "${bak_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${bak_bridge_nf_ip6t} >/dev/null 2>&1 + } + rm -rf $TMP_PATH + rm -rf /tmp/lock/${CONFIG}_socks_auto_switch* + rm -rf /tmp/lock/${CONFIG}_lease2hosts* + log_i18n 0 "Clearing and closing related programs and cache complete." + exit 0 +} + +get_direct_dns() { + RESOLVFILE=/tmp/resolv.conf.d/resolv.conf.auto + [ -f "${RESOLVFILE}" ] && [ -s "${RESOLVFILE}" ] || RESOLVFILE=/tmp/resolv.conf.auto + + ISP_DNS=$(cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -v -E '^(0\.0\.0\.0|127\.0\.0\.1)$' | awk '!seen[$0]++') + ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}' | grep -v -Fx ::1 | grep -v -Fx :: | awk '!seen[$0]++') + + DNSMASQ_UPSTREAM_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' '\n' | grep -v "\/" | awk '{if($1 ~ /#/) {sub(/#/, "#", $1); print $1} else {print $1"#53"}}' | head -2 | sed ':label;N;s/\n/,/;b label') + DEFAULT_DNS="${DNSMASQ_UPSTREAM_DNS}" + [ -z "${DEFAULT_DNS}" ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | head -2 | tr '\n' ',' | sed 's/,$//') + AUTO_DNS=${DEFAULT_DNS:-119.29.29.29} + + local AUTO_DNS_1=$(echo ${AUTO_DNS} | awk -F ',' '{print $1}') + local AUTO_DNS_2=$(echo ${AUTO_DNS} | awk -F ',' '{print $2}') + local AUTO_DNS_ADDRESS=$(echo ${AUTO_DNS_1} | awk -F '#' '{print $1}') + local AUTO_DNS_PORT=$(echo ${AUTO_DNS_1} | awk -F '#' '{print $2}') + DIRECT_DNS_UDP_SERVER=${AUTO_DNS_ADDRESS} + DIRECT_DNS_UDP_PORT=${AUTO_DNS_PORT} +} + +get_config() { + ENABLED_DEFAULT_ACL=0 + ENABLED=$(config_t_get global enabled 0) + NODE=$(config_t_get global node) + [ "$ENABLED" == 1 ] && { + [ -n "$NODE" ] && [ "$(config_get_type $NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=1 + } + ENABLED_ACLS=$(config_t_get global acl_enable 0) + [ "$ENABLED_ACLS" == 1 ] && { + [ "$(uci show ${CONFIG} | grep "@acl_rule" | grep "enabled='1'" | wc -l)" == 0 ] && ENABLED_ACLS=0 + } + SOCKS_ENABLED=$(config_t_get global socks_enabled 0) + REDIR_PORT=$(echo $(get_new_port 1041 tcp,udp)) + TCP_PROXY_WAY=$(config_t_get global_forwarding tcp_proxy_way redirect) + TCP_NO_REDIR_PORTS=$(config_t_get global_forwarding tcp_no_redir_ports 'disable') + UDP_NO_REDIR_PORTS=$(config_t_get global_forwarding udp_no_redir_ports 'disable') + TCP_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '22,25,53,143,465,587,853,993,995,80,443') + UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535') + PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0) + TCP_PROXY_MODE="global" + UDP_PROXY_MODE="global" + LOCALHOST_PROXY=$(config_t_get global localhost_proxy '1') + CLIENT_PROXY=$(config_t_get global client_proxy '1') + DIRECT_DNS_QUERY_STRATEGY=$(config_t_get global direct_dns_query_strategy UseIP) + REMOTE_DNS_PROTOCOL=$(config_t_get global remote_dns_protocol tcp) + REMOTE_DNS_DETOUR=$(config_t_get global remote_dns_detour remote) + REMOTE_DNS=$(config_t_get global remote_dns 1.1.1.1:53 | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g') + REMOTE_FAKEDNS=$(config_t_get global remote_fakedns '0') + REMOTE_DNS_QUERY_STRATEGY=$(config_t_get global remote_dns_query_strategy UseIPv4) + DNS_CACHE=$(config_t_get global dns_cache 1) + DNS_REDIRECT=$(config_t_get global dns_redirect 1) + + get_direct_dns + + DEFAULT_DNSMASQ_CONF_DIR=/tmp/dnsmasq.d + DNSMASQ_CONF_DIR=${DEFAULT_DNSMASQ_CONF_DIR} + DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')" + if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then + DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")" + if [ -n "$DNSMASQ_CONF_DIR" ]; then + DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/} + else + DNSMASQ_CONF_DIR=${DEFAULT_DNSMASQ_CONF_DIR} + fi + fi + set_cache_var GLOBAL_DNSMASQ_CONF ${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf + set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d + + QUEUE_RUN=1 +} + +arg1=$1 +shift +case $arg1 in +run_socks) + get_direct_dns + QUEUE_RUN=0 + run_socks $@ + ;; +socks_node_switch) + get_direct_dns + QUEUE_RUN=0 + socks_node_switch $@ + ;; +start) + start $@ + ;; +stop) + stop + ;; +esac diff --git a/luci-app-passwall2/root/usr/share/passwall2/domains_excluded b/luci-app-passwall2/root/usr/share/passwall2/domains_excluded new file mode 100644 index 00000000..f2def6f2 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/domains_excluded @@ -0,0 +1,26 @@ +courier.push.apple.com +rbsxbxp-mim.vivox.com +rbsxbxp.www.vivox.com +rbsxbxp-ws.vivox.com +rbspsxp.www.vivox.com +rbspsxp-mim.vivox.com +rbspsxp-ws.vivox.com +rbswxp.www.vivox.com +rbswxp-mim.vivox.com +disp-rbspsp-5-1.vivox.com +disp-rbsxbp-5-1.vivox.com +proxy.rbsxbp.vivox.com +proxy.rbspsp.vivox.com +proxy.rbswp.vivox.com +rbswp.vivox.com +rbsxbp.vivox.com +rbspsp.vivox.com +rbspsp.www.vivox.com +rbswp.www.vivox.com +rbsxbp.www.vivox.com +rbsxbxp.vivox.com +rbspsxp.vivox.com +rbswxp.vivox.com +Mijia Cloud +dlg.io.mi.com +marscdn.c2c.wechat.com diff --git a/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua b/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua new file mode 100644 index 00000000..1021568f --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua @@ -0,0 +1,236 @@ +#!/usr/bin/lua + +local api = require ("luci.passwall2.api") +local appname = api.appname +local fs = api.fs +local jsonc = api.jsonc +local uci = api.uci +local sys = api.sys + +local log = api.log + +function get_ip_port_from(str) + local result_port = sys.exec("echo -n " .. str .. " | sed -n 's/^.*[:#]\\([0-9]*\\)$/\\1/p'") + local result_ip = sys.exec(string.format("__host=%s;__varport=%s;", str, result_port) .. "echo -n ${__host%%${__varport:+[:#]${__varport}*}}") + return result_ip, result_port +end + +local var = api.get_args(arg) +local haproxy_path = var["-path"] +local haproxy_conf = var["-conf"] +local haproxy_dns = "127.0.0.1" + +local cpu_thread = sys.exec('echo -n $(cat /proc/cpuinfo | grep "processor" | wc -l)') or "1" +local health_check_type = uci:get(appname, "@global_haproxy[0]", "health_check_type") or "tcp" +local health_check_inter = uci:get(appname, "@global_haproxy[0]", "health_check_inter") or "20" +local balancingStrategy = uci:get(appname, "@global_haproxy[0]", "balancingStrategy") or "roundrobin" +local console_port = uci:get(appname, "@global_haproxy[0]", "console_port") +local bind_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0" +local bind_address = "0.0.0.0" +if bind_local == "1" then bind_address = "127.0.0.1" end + +log(0, "HAProxy: ") +log(1, api.i18n.translatef("Console Port: %s", console_port)) +fs.mkdir(haproxy_path) +local haproxy_file = haproxy_path .. "/" .. haproxy_conf + +local f_out = io.open(haproxy_file, "a") + +local haproxy_config = [[ +global + daemon + log 127.0.0.1 local2 + maxconn 60000 + stats socket {{path}}/haproxy.sock + nbthread {{nbthread}} + external-check + insecure-fork-wanted + spread-checks 50 + tune.max-checks-per-thread 5 + +defaults + mode tcp + log global + option tcplog + option dontlognull + option http-server-close + #option forwardfor except 127.0.0.0/8 + option redispatch + retries 2 + timeout http-request 10s + timeout queue 1m + timeout connect 10s + timeout client 1m + timeout server 1m + timeout http-keep-alive 10s + timeout check 10s + maxconn 3000 + +resolvers mydns + resolve_retries 1 + timeout resolve 5s + hold valid 600s +{{dns}} +]] + +haproxy_config = haproxy_config:gsub("{{path}}", haproxy_path) +haproxy_config = haproxy_config:gsub("{{nbthread}}", cpu_thread) + +local mydns = "" +local index = 0 +string.gsub(haproxy_dns, '[^' .. "," .. ']+', function(w) + index = index + 1 + local s = w:gsub("#", ":") + if not s:find(":") then + s = s .. ":53" + end + mydns = mydns .. (index > 1 and "\n" or "") .. " " .. string.format("nameserver dns%s %s", index, s) +end) +haproxy_config = haproxy_config:gsub("{{dns}}", mydns) + +f_out:write(haproxy_config) + +local listens = {} + +uci:foreach(appname, "haproxy_config", function(t) + if t.enabled == "1" then + local server_remark + local server_address + local server_port + local lbss = t.lbss + local listen_port = tonumber(t.haproxy_port) or 0 + local server_node = uci:get_all(appname, lbss) + local hop = (health_check_type == "passwall_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil + hop = hop and hop:gsub(":", "-") or nil + if server_node and server_node.address and (server_node.port or hop) then + server_remark = server_node.address .. ":" .. (server_node.port or hop) + server_address = server_node.address + server_port = server_node.port or hop + t.origin_address = server_address + t.origin_port = server_port + if health_check_type == "passwall_logic" then + if server_node.type ~= "Socks" then + local relay_port = server_node.port + local new_port = api.get_new_port() + local config_file = string.format("haproxy_%s_%s.json", t[".name"], new_port) + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s", + new_port, --flag + server_node[".name"], --node + "127.0.0.1", --bind + new_port, --socks port + config_file --config file + ) + ) + ) + server_address = "127.0.0.1" + server_port = new_port + end + end + else + server_address, server_port = get_ip_port_from(lbss) + server_remark = server_address .. ":" .. server_port + t.origin_address = server_address + t.origin_port = server_port + end + if server_address and server_port and listen_port > 0 then + if not listens[listen_port] then + listens[listen_port] = {} + end + t.server_remark = server_remark + t.server_address = server_address + t.server_port = server_port + table.insert(listens[listen_port], t) + else + log(1, api.i18n.translate("Discard one obviously invalid node.")) + end + end +end) + +local inter = tonumber((health_check_inter or "20"):match("^%d+")) +inter = (inter and inter >= 20) and inter or 20 +local inter_arg = "inter " .. inter .. "s fastinter " .. inter / 2 .. "s downinter " .. inter * 1.5 .. "s" + +local sortTable = {} +for i in pairs(listens) do + if i ~= nil then + table.insert(sortTable, i) + end +end +table.sort(sortTable, function(a,b) return (a < b) end) + +for i, port in pairs(sortTable) do + log(1, api.i18n.translatef("Entrance %s:%s", bind_address, port)) + + f_out:write("\n" .. string.format([[ +listen %s + bind %s:%s + mode tcp + balance %s +]], port, bind_address, port, balancingStrategy)) + + if health_check_type == "passwall_logic" then + f_out:write(string.format([[ + option external-check + external-check command "/usr/share/%s/haproxy_check.sh" +]], appname)) + end + + local count_M, count_B = 1, 1 + for i, o in ipairs(listens[port]) do + local remark = o.server_remark or "" + -- To prevent duplicate names from causing the program to fail to run. + if tostring(o.backup) ~= "1" then + remark = "M" .. count_M .. "-" .. remark + count_M = count_M + 1 + else + remark = "B" .. count_B .. "-" .. remark + count_B = count_B + 1 + end + local server = o.server_address .. ":" .. o.server_port + local server_conf = "server {{remark}} {{server}} weight {{weight}} {{resolvers}} check {{inter_arg}} rise 2 fall 2 {{backup}}" + server_conf = server_conf:gsub("{{remark}}", remark) + server_conf = server_conf:gsub("{{server}}", server) + server_conf = server_conf:gsub("{{weight}}", o.lbweight) + local resolvers = "resolvers mydns" + if api.is_ip(o.server_address) then + resolvers = "" + end + server_conf = server_conf:gsub("{{resolvers}}", resolvers) + server_conf = server_conf:gsub("{{inter_arg}}", inter_arg) + server_conf = server_conf:gsub("{{backup}}", tostring(o.backup) == "1" and "backup" or "") + + f_out:write(" " .. api.trim(server_conf) .. "\n") + + if o.export ~= "0" then + sys.call(string.format(". /usr/share/%s/utils.sh ; add_ip2route %s %s", appname, o.origin_address, o.export)) + end + + log(2, string.format(api.i18n.translatef("Node: %s:%s, Weight: %s", o.origin_address, o.origin_port, o.lbweight))) + end +end + +-- Console config +local console_user = uci:get(appname, "@global_haproxy[0]", "console_user") +local console_password = uci:get(appname, "@global_haproxy[0]", "console_password") +local str = [[ +listen console + bind 0.0.0.0:%s + mode http + stats refresh 30s + stats uri / + stats admin if TRUE + %s +]] +f_out:write("\n" .. string.format(str, console_port, (console_user and console_user ~= "" and console_password and console_password ~= "") and "stats auth " .. console_user .. ":" .. console_password or "")) + +f_out:close() + +-- Built-in health check URL +if health_check_type == "passwall_logic" then + local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204" + local f_url = io.open(haproxy_path .. "/Probe_URL", "w") + f_url:write(probeUrl) + f_url:close() +end diff --git a/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh b/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh new file mode 100755 index 00000000..106b4cf0 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin +CONFIG=passwall2 + +listen_address=$1 +listen_port=$2 +server_address=$3 +server_port=$4 + +busybox pgrep -af "${CONFIG}/" | grep -E 'app\.sh.*(start|stop)|nftables\.sh|iptables\.sh|subscribe\.lua' >/dev/null && { + # No detection during specific task execution + exit 0 +} + +probe_file="/tmp/etc/${CONFIG}/haproxy/Probe_URL" +probeUrl="https://www.google.com/generate_204" +if [ -f "$probe_file" ]; then + firstLine=$(head -n 1 "$probe_file" | tr -d ' \t\n') + [ -n "$firstLine" ] && probeUrl="$firstLine" +fi + +extra_params="-x socks5h://${server_address}:${server_port}" +if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then + extra_params="${extra_params} --retry-all-errors" +fi + +status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout 3 --retry 1 --max-time 6 -w "%{http_code}" "${probeUrl}") + +case "$status" in + 200|204) + exit 0 + ;; + *) + exit 1 + ;; +esac diff --git a/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.lua b/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.lua new file mode 100644 index 00000000..5ddbb744 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/helper_dnsmasq.lua @@ -0,0 +1,372 @@ +local api = require "luci.passwall2.api" +local appname = "passwall2" +local uci = api.uci +local sys = api.sys +local jsonc = api.jsonc +local fs = api.fs +local datatypes = api.datatypes +local TMP = {} + +local function tinsert(table_name, val) + if table_name and type(table_name) == "table" then + if not TMP[table_name] then + TMP[table_name] = {} + end + if TMP[table_name][val] then + return false + end + table.insert(table_name, val) + TMP[table_name][val] = true + return true + end + return false +end + +local function backup_servers() + local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server") + if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then + uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS) + api.uci_save(uci, appname, true) + end +end + +local function restore_servers() + local dns_table = {} + local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server") + if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then + for k, v in ipairs(DNSMASQ_DNS) do + tinsert(dns_table, v) + end + end + local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers") + if OLD_SERVER and #OLD_SERVER > 0 then + for k, v in ipairs(OLD_SERVER) do + tinsert(dns_table, v) + end + uci:delete(appname, "@global[0]", "dnsmasq_servers") + api.uci_save(uci, appname, true) + end + if dns_table and #dns_table > 0 then + uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table) + api.uci_save(uci, "dhcp", true) + end +end + +function stretch() + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + local dnsmasq_noresolv = uci:get("dhcp", "@dnsmasq[0]", "noresolv") + local _flag + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if not v:find("/") then + _flag = true + end + end + end + if not _flag and dnsmasq_noresolv == "1" then + uci:delete("dhcp", "@dnsmasq[0]", "noresolv") + local RESOLVFILE = "/tmp/resolv.conf.d/resolv.conf.auto" + local file = io.open(RESOLVFILE, "r") + if not file then + RESOLVFILE = "/tmp/resolv.conf.auto" + else + local size = file:seek("end") + file:close() + if size == 0 then + RESOLVFILE = "/tmp/resolv.conf.auto" + end + end + uci:set("dhcp", "@dnsmasq[0]", "resolvfile", RESOLVFILE) + api.uci_save(uci, "dhcp", true) + end +end + +function restart(var) + local LOG = var["LOG"] + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + if LOG == "1" then + api.log(0, api.i18n.translate("Restart dnsmasq service.")) + end +end + +function logic_restart(var) + local LOG = var["LOG"] + local DEFAULT_DNS = api.get_cache_var("DEFAULT_DNS") + if DEFAULT_DNS then + backup_servers() + --sys.call("sed -i '/list server/d' /etc/config/dhcp >/dev/null 2>&1") + local dns_table = {} + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if v:find("/") then + tinsert(dns_table, v) + end + end + uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table) + api.uci_save(uci, "dhcp", true) + end + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + restore_servers() + else + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + end + if LOG == "1" then + api.log(0, api.i18n.translate("Restart dnsmasq service.")) + end +end + +function copy_instance(var) + local LISTEN_PORT = var["LISTEN_PORT"] + local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"] + local conf_lines = {} + local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')") + for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do + local filter + if line:find("passwall2") then filter = true end + if line:find("ubus") then filter = true end + if line:find("dhcp") then filter = true end + if line:find("server=") == 1 then filter = true end + if line:find("port=") == 1 then filter = true end + if line:find("conf%-dir=") == 1 then + filter = true + if TMP_DNSMASQ_PATH then + local tmp_path = line:sub(1 + #"conf-dir=") + sys.call(string.format("cp -r %s/* %s/ 2>/dev/null", tmp_path, TMP_DNSMASQ_PATH)) + end + end + if line:find("address=") == 1 or (line:find("server=") == 1 and line:find("/")) then filter = nil end + if not filter then + tinsert(conf_lines, line) + end + end + tinsert(conf_lines, "port=" .. LISTEN_PORT) + if TMP_DNSMASQ_PATH then + sys.call("rm -rf " .. TMP_DNSMASQ_PATH .. "/*passwall2*") + end + if var["return"] == "1" then + return conf_lines + end + if #conf_lines > 0 then + local DNSMASQ_CONF = var["DNSMASQ_CONF"] + local conf_out = io.open(DNSMASQ_CONF, "a") + conf_out:write(table.concat(conf_lines, "\n")) + conf_out:write("\n") + conf_out:close() + end +end + +function add_rule(var) + local FLAG = var["FLAG"] + local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"] + local DNSMASQ_CONF_FILE = var["DNSMASQ_CONF_FILE"] + local LISTEN_PORT = var["LISTEN_PORT"] + local DEFAULT_DNS = var["DEFAULT_DNS"] + local LOCAL_DNS = var["LOCAL_DNS"] + local TUN_DNS = var["TUN_DNS"] + local NFTFLAG = var["NFTFLAG"] + local CACHE_PATH = api.CACHE_PATH + local CACHE_FLAG = "dnsmasq_" .. FLAG + local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG + local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt" + + local list1 = {} + + local function check_dns(domain, dns) + if domain == "" or domain:find("#") then + return false + end + if not dns then + return + end + for k,v in ipairs(list1[domain].dns) do + if dns == v then + return true + end + end + return false + end + + local function check_ipset(domain, ipset) + if domain == "" or domain:find("#") then + return false + end + if not ipset then + return + end + for k,v in ipairs(list1[domain].ipsets) do + if ipset == v then + return true + end + end + return false + end + + local function set_domain_dns(domain, dns) + if domain == "" or domain:find("#") then + return + end + if not dns then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + for line in string.gmatch(dns, '[^' .. "," .. ']+') do + if not check_dns(domain, line) then + table.insert(list1[domain].dns, line) + end + end + end + + local function set_domain_ipset(domain, ipset) + if domain == "" or domain:find("#") then + return + end + if not ipset then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + for line in string.gmatch(ipset, '[^' .. "," .. ']+') do + if not check_ipset(domain, line) then + table.insert(list1[domain].ipsets, line) + end + end + end + + local cache_text = "" + local nodes_address_md5 = sys.exec("echo -n $(uci show passwall2 | grep '\\.address') | md5sum") + local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. nodes_address_md5 .. NFTFLAG + if fs.access(CACHE_TEXT_FILE) then + for line in io.lines(CACHE_TEXT_FILE) do + cache_text = line + end + end + + if cache_text ~= new_text then + api.remove(CACHE_DNS_PATH .. "*") + end + + local dnsmasq_default_dns = TUN_DNS + + local setflag_4= (NFTFLAG == "1") and "4#inet#passwall2#" or "" + local setflag_6= (NFTFLAG == "1") and "6#inet#passwall2#" or "" + + if not fs.access(CACHE_DNS_PATH) then + fs.mkdir(CACHE_DNS_PATH) + + local fwd_dns + + -- Always use domestic DNS to resolve node domain names + if true then + fwd_dns = LOCAL_DNS + uci:foreach(appname, "nodes", function(t) + local function process_address(address) + address = (address or ""):lower() + if address == "engage.cloudflareclient.com" then return end + if datatypes.hostname(address) then + set_domain_dns(address, fwd_dns) + set_domain_ipset(address, setflag_4 .. "psw2_vps," .. setflag_6 .. "psw2_vps6") + end + end + process_address(t.address) + process_address(t.download_address) + end) + end + + if list1 and next(list1) then + local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a") + local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a") + local set_name = "ipset" + if NFTFLAG == "1" then + set_name = "nftset" + end + for key, value in pairs(list1) do + if value.dns and #value.dns > 0 then + for i, dns in ipairs(value.dns) do + server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n") + end + end + if value.ipsets and #value.ipsets > 0 then + local ipsets_str = "" + for i, ipset in ipairs(value.ipsets) do + ipsets_str = ipsets_str .. ipset .. "," + end + ipsets_str = ipsets_str:sub(1, #ipsets_str - 1) + ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n") + end + end + server_out:close() + ipset_out:close() + end + + local f_out = io.open(CACHE_TEXT_FILE, "a") + f_out:write(new_text) + f_out:close() + end + + api.remove(TMP_DNSMASQ_PATH) + fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH) + + if DNSMASQ_CONF_FILE ~= "nil" then + local conf_lines = {} + if LISTEN_PORT then + --Copy dnsmasq instance + conf_lines = copy_instance({ + ["LISTEN_PORT"] = LISTEN_PORT, + ["TMP_DNSMASQ_PATH"] = TMP_DNSMASQ_PATH, + ["return"] = "1" + }) + --dhcp.leases to hostsMore actions + local hosts = "/tmp/etc/" .. appname .. "_tmp/dhcp-hosts" + sys.call("touch " .. hosts) + tinsert(conf_lines, "addn-hosts=" .. hosts) + else + --Modify the default dnsmasq service + end + tinsert(conf_lines, string.format("conf-dir=%s", TMP_DNSMASQ_PATH)) + if dnsmasq_default_dns then + for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do + tinsert(conf_lines, string.format("server=%s", s)) + end + tinsert(conf_lines, "all-servers") + tinsert(conf_lines, "no-poll") + tinsert(conf_lines, "no-resolv") + + if FLAG == "default" then + api.set_cache_var("DEFAULT_DNS", DEFAULT_DNS) + end + end + if #conf_lines > 0 then + local conf_out = io.open(DNSMASQ_CONF_FILE, "a") + conf_out:write(table.concat(conf_lines, "\n")) + conf_out:write("\n") + conf_out:close() + end + end +end + +_G.stretch = stretch +_G.restart = restart +_G.logic_restart = logic_restart +_G.copy_instance = copy_instance +_G.add_rule = add_rule + +if arg[1] then + local func =_G[arg[1]] + if func then + local var = nil + if arg[2] then + var = jsonc.parse(arg[2]) + end + func(var) + end +end diff --git a/luci-app-passwall2/root/usr/share/passwall2/i18n.lua b/luci-app-passwall2/root/usr/share/passwall2/i18n.lua new file mode 100644 index 00000000..f2dc9332 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/i18n.lua @@ -0,0 +1,6 @@ +if #arg > 0 then + local api = require "luci.passwall2.api" + local str = arg[1] + table.remove(arg, 1) + print(api.i18n.translatef(str, unpack(arg))) +end diff --git a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh new file mode 100755 index 00000000..c3843150 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh @@ -0,0 +1,1147 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +MY_PATH=$DIR/iptables.sh +UTILS_PATH=$DIR/utils.sh +IPSET_LOCAL="psw2_local" +IPSET_PROXY_LAN="psw2_proxy_lan" +IPSET_LAN="psw2_lan" +IPSET_VPS="psw2_vps" +IPSET_WAN="psw2_wan" + +IPSET_LOCAL6="psw2_local6" +IPSET_PROXY_LAN6="psw2_proxy_lan6" +IPSET_LAN6="psw2_lan6" +IPSET_VPS6="psw2_vps6" +IPSET_WAN6="psw2_wan6" + +FWMARK="0x50535732" + +ipt=$(command -v iptables-legacy || command -v iptables) +ip6t=$(command -v ip6tables-legacy || command -v ip6tables) + +ipt_n="$ipt -t nat -w" +ipt_m="$ipt -t mangle -w" +ip6t_n="$ip6t -t nat -w" +ip6t_m="$ip6t -t mangle -w" +[ -z "$ip6t" -o -z "$(lsmod | grep 'ip6table_nat')" ] && ip6t_n="eval #$ip6t_n" +[ -z "$ip6t" -o -z "$(lsmod | grep 'ip6table_mangle')" ] && ip6t_m="eval #$ip6t_m" +FWI=$(uci -q get firewall.passwall2.path 2>/dev/null) +FAKE_IP="198.18.0.0/16" +FAKE_IP_6="fc00::/18" + +factor() { + if [ -z "$1" ] || [ -z "$2" ]; then + echo "" + elif [ "$1" == "1:65535" ]; then + echo "" + else + echo "$2 $1" + fi +} + +dst() { + echo "-m set $2 --match-set $1 dst" +} + +comment() { + local name=$(echo $1 | sed 's/ /_/g') + echo "-m comment --comment "${name}"" +} + +# Resolves invalid IP addresses for ports exceeding 15; it supports single ports and port ranges. +add_port_rules() { + local ipt_cmd="$1" + local port_list="$2" + local target="$3" + echo "$port_list" | grep -vq '[0-9]' && return + port_list=$(echo "$port_list" | tr -d ' ' | sed 's/-/:/g' | tr ',' '\n' | awk '!a[$0]++' | grep -v '^$') + [ -z "$port_list" ] && return + if echo "$port_list" | grep -q '^1:65535$'; then + eval "$ipt_cmd $target" + return + fi + local multiport_ports="" + local range_ports="" + local count=0 + local port + for port in $port_list; do + if echo "$port" | grep -q ':'; then + range_ports="$range_ports $port" + else + multiport_ports="$multiport_ports,$port" + count=$((count + 1)) + if [ "$count" -eq 15 ]; then + eval "$ipt_cmd -m multiport --dport ${multiport_ports#,} $target" + multiport_ports="" + count=0 + fi + fi + done + if [ -n "$multiport_ports" ]; then + eval "$ipt_cmd -m multiport --dport ${multiport_ports#,} $target" + fi + for port in $range_ports; do + eval "$ipt_cmd --dport $port $target" + done +} + +destroy_ipset() { + for i in "$@"; do + ipset -q -F $i + ipset -q -X $i + done +} + +insert_rule_before() { + [ $# -ge 3 ] || { + return 1 + } + local ipt_tmp="${1}"; shift + local chain="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$($ipt_tmp -n -L $chain --line-numbers 2>/dev/null | grep "$keyword" | head -n 1 | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + $ipt_tmp -A $chain $rule + else + if [ -z "${_index}" ]; then + _index=${default_index} + fi + $ipt_tmp -I $chain $_index $rule + fi +} + +insert_rule_after() { + [ $# -ge 3 ] || { + return 1 + } + local ipt_tmp="${1}"; shift + local chain="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$($ipt_tmp -n -L $chain --line-numbers 2>/dev/null | grep "$keyword" | awk 'END {print}' | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + $ipt_tmp -A $chain $rule + else + if [ -n "${_index}" ]; then + _index=$((_index + 1)) + else + _index=${default_index} + fi + $ipt_tmp -I $chain $_index $rule + fi +} + +RULE_LAST_INDEX() { + [ $# -ge 3 ] || { + log_i18n 1 "Incorrect index listing method (%s), execution terminated!" "iptables" + return 1 + } + local ipt_tmp="${1}"; shift + local chain="${1}"; shift + local list="${1}"; shift + local default="${1:-0}"; shift + local _index=$($ipt_tmp -n -L $chain --line-numbers 2>/dev/null | grep "$list" | head -n 1 | awk '{print $1}') + echo "${_index:-${default}}" +} + +REDIRECT() { + local s="-j REDIRECT" + [ -n "$1" ] && { + local s="$s --to-ports $1" + [ "$2" == "TPROXY" ] && { + local mark="-m mark --mark ${FWMARK}" + s="${mark} -j TPROXY --on-port $1" + } + } + echo $s +} + +get_redirect_ipt() { + echo "$(REDIRECT $2 $3)" +} + +get_redirect_ip6t() { + echo "$(REDIRECT $2 $3)" +} + +gen_shunt_list() { + local node=${1} + local shunt_list4_var_name=${2} + local shunt_list6_var_name=${3} + [ -z "$node" ] && continue + unset ${shunt_list4_var_name} + unset ${shunt_list6_var_name} + local _SHUNT_LIST4 _SHUNT_LIST6 + local USE_SHUNT_NODE=0 + NODE_PROTOCOL=$(config_n_get $node protocol) + [ "$NODE_PROTOCOL" = "_shunt" ] && USE_SHUNT_NODE=1 + [ "$USE_SHUNT_NODE" = "1" ] && { + local enable_geoview_ip=$(config_n_get $node enable_geoview_ip 0) + [ -z "$(first_type geoview)" ] && enable_geoview_ip=0 + local preloading=0 + preloading=$enable_geoview_ip + [ "${preloading}" = "1" ] && { + local default_node=$(config_n_get ${node} default_node _direct) + local default_outbound="redirect" + [ "$default_node" = "_direct" ] && default_outbound="direct" + local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') + for shunt_id in $shunt_ids; do + local shunt_node=$(config_n_get ${node} "${shunt_id}") + [ -n "$shunt_node" ] && { + local ipset_v4="psw2_${node}_${shunt_id}" + local ipset_v6="psw2_${node}_${shunt_id}6" + ipset -! create $ipset_v4 nethash maxelem 1048576 + ipset -! create $ipset_v6 nethash family inet6 maxelem 1048576 + local outbound="redirect" + [ "$shunt_node" = "_direct" ] && outbound="direct" + [ "$shunt_node" = "_default" ] && outbound="${default_outbound}" + _SHUNT_LIST4="${_SHUNT_LIST4} ${ipset_v4}:${outbound}" + _SHUNT_LIST6="${_SHUNT_LIST6} ${ipset_v6}:${outbound}" + + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_v4 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_v6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + [ "${enable_geoview_ip}" = "1" ] && { + local _geoip_code=$(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$_geoip_code" ] && { + get_geoip $_geoip_code ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_v4 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + get_geoip $_geoip_code ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_v6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + log 1 "$(i18n "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." "${shunt_id}" "${_geoip_code}" "IPSET")" + } + } + } + done + } + local direct_ipset4=$(get_cache_var "node_${node}_direct_ipset4") + [ -n "${direct_ipset4}" ] && { + ipset -! create ${direct_ipset4} iphash maxelem 1048576 timeout 259200 + _SHUNT_LIST4="${_SHUNT_LIST4} ${direct_ipset4}:direct" + } + local direct_ipset6=$(get_cache_var "node_${node}_direct_ipset6") + [ -n "${direct_ipset6}" ] && { + ipset -! create ${direct_ipset6} iphash family inet6 maxelem 1048576 timeout 259200 + _SHUNT_LIST6="${_SHUNT_LIST6} ${direct_ipset6}:direct" + } + } + [ -n "${_SHUNT_LIST4}" ] && eval ${shunt_list4_var_name}=\"${_SHUNT_LIST4}\" + [ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\" +} + +add_shunt_t_rule() { + local shunt_args=${1} + local t_args=${2} + local t_jump_args=${3} + local t_ports_args=${4} + [ -n "${shunt_args}" ] && { + for j in ${shunt_args}; do + local _set_name=$(echo ${j} | awk -F ':' '{print $1}') + local _outbound=$(echo ${j} | awk -F ':' '{print $2}') + [ -n "${_set_name}" ] && [ -n "${_outbound}" ] && { + local _t_arg="${t_jump_args}" + [ "${_outbound}" = "direct" ] && _t_arg="-j RETURN" + if [ -z "${t_ports_args}" ] || [ "${t_ports_args}" == "1:65535" ]; then + ${t_args} $(dst ${_set_name}) ${_t_arg} + else + add_port_rules "${t_args} $(dst ${_set_name})" "${t_ports_args}" "${_t_arg}" + fi + } + done + } +} + +load_acl() { + log_i18n 1 "Access Control:" + [ "$ENABLED_ACLS" == 1 ] && { + acl_app + for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do + eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-) + + tcp_no_redir_ports=${tcp_no_redir_ports:-default} + udp_no_redir_ports=${udp_no_redir_ports:-default} + tcp_proxy_mode="global" + udp_proxy_mode="global" + tcp_redir_ports=${tcp_redir_ports:-default} + udp_redir_ports=${udp_redir_ports:-default} + node=${node:-default} + [ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS + [ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS + [ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS + [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS + + [ -n "$(get_cache_var "ACL_${sid}_node")" ] && node=$(get_cache_var "ACL_${sid}_node") + [ -n "$(get_cache_var "ACL_${sid}_redir_port")" ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port") + [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") + [ -n "$node" ] && node_remark=$(config_n_get $node remarks) + + if [ -n "$(get_cache_var "ACL_${sid}_default")" ]; then + shunt_list4=${SHUNT_LIST4} + shunt_list6=${SHUNT_LIST6} + else + # Shunt rules IP list (import when use shunt node) + gen_shunt_list "${node}" shunt_list4 shunt_list6 + fi + + _acl_list=${TMP_ACL_PATH}/${sid}/source_list + + for i in $(cat $_acl_list); do + local _ipt_source _ipv4 + local msg + if [ -n "${interface}" ]; then + local gateway device + network_get_gateway gateway "${interface}" + network_get_device device "${interface}" + # network_get_device returns empty for non-UP interfaces (e.g. auto='0'). + # Try ubus directly, then check if the name is a kernel device. + [ -z "${device}" ] && device=$(ubus call "network.interface.${interface}" status 2>/dev/null | jsonfilter -e '@.device' 2>/dev/null) + [ -z "${device}" ] && [ -d "/sys/class/net/${interface}" ] && device="${interface}" + [ -z "${device}" ] && device="${interface}" + _ipt_source="-i ${device} " + msg=$(i18n "Source iface [%s]," "${device}") + else + msg=$(i18n "Source iface [%s]," $(i18n "All")) + fi + if [ -n "$(echo ${i} | grep '^iprange:')" ]; then + _iprange=$(echo ${i} | sed 's#iprange:##g') + _ipt_source=$(factor ${_iprange} "${_ipt_source}-m iprange --src-range") + msg="${msg}$(i18n "IP range [%s]," "${_iprange}")" + _ipv4="1" + unset _iprange + elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then + _ipset=$(echo ${i} | sed 's#ipset:##g') + msg="${msg}IPset$(i18n "[%s]," "${_ipset}")" + ipset -q list ${_ipset} >/dev/null + if [ $? -eq 0 ]; then + _ipt_source="${_ipt_source}-m set --match-set ${_ipset} src" + unset _ipset + else + log 2 "$(i18n "[%s]," "${remarks}")${msg}$(i18n "Does not exist, ignore.")" + unset _ipset + continue + fi + elif [ -n "$(echo ${i} | grep '^ip:')" ]; then + _ip=$(echo ${i} | sed 's#ip:##g') + _ipt_source=$(factor ${_ip} "${_ipt_source}-s") + msg="${msg}IP$(i18n "[%s]," "${_ip}")" + _ipv4="1" + unset _ip + elif [ -n "$(echo ${i} | grep '^mac:')" ]; then + _mac=$(echo ${i} | sed 's#mac:##g') + _ipt_source=$(factor ${_mac} "${_ipt_source}-m mac --mac-source") + msg="${msg}MAC$(i18n "[%s]," "${_mac}")" + unset _mac + elif [ -n "$(echo ${i} | grep '^any')" ]; then + msg="${msg}$(i18n "All device,")" + else + continue + fi + msg="$(i18n "[%s]," "${remarks}")${msg}" + + ipt_tmp=$ipt_n + [ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m + + [ "$tcp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$tcp_no_redir_ports"; then + [ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN" 2>/dev/null + add_port_rules "$ipt_tmp -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN" + log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")" + else + # It will return when it ends, so no extra rules are needed. + tcp_proxy_mode="disable" + log 2 "${msg}$(i18n "not proxy all %s" "TCP")" + fi + } + + [ "$udp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$udp_no_redir_ports"; then + [ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" 2>/dev/null + add_port_rules "$ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" + log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")" + else + # It will return when it ends, so no extra rules are needed. + udp_proxy_mode="disable" + log 2 "${msg}$(i18n "not proxy all %s" "UDP")" + fi + } + + if ([ "$tcp_proxy_mode" != "disable" ] || [ "$udp_proxy_mode" != "disable" ]) && [ -n "$dns_redirect_port" ]; then + $ipt_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port + $ip6t_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null + $ipt_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port + $ip6t_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null + [ -z "$(get_cache_var "ACL_${sid}_default")" ] && log 2 "${msg}$(i18n "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server.")" + else + $ipt_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN + $ip6t_n -A PSW2_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + $ipt_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN + $ip6t_n -A PSW2_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + fi + + [ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { + msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remark}")" + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${redir_port})" + ipt_j="-j PSW2_RULE" + else + msg2="${msg2}(REDIRECT:${redir_port})" + ipt_j="$(REDIRECT $redir_port)" + fi + + [ "$accept_icmp" = "1" ] && { + $ipt_n -I PSW2 $(comment "$remarks") -p icmp ${_ipt_source} $(dst $IPSET_PROXY_LAN) $(REDIRECT) + $ipt_n -A PSW2 $(comment "$remarks") -p icmp ${_ipt_source} -d $FAKE_IP $(REDIRECT) + add_shunt_t_rule "${shunt_list4}" "$ipt_n -A PSW2 $(comment "$remarks") -p icmp ${_ipt_source}" "$(REDIRECT)" + $ipt_n -A PSW2 $(comment "$remarks") -p icmp ${_ipt_source} $(REDIRECT) + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { + $ip6t_n -I PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $IPSET_PROXY_LAN6) $(REDIRECT) 2>/dev/null + $ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source} -d $FAKE_IP_6 $(REDIRECT) 2>/dev/null + add_shunt_t_rule "${shunt_list6}" "$ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source}" "$(REDIRECT)" 2>/dev/null + $ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(REDIRECT) 2>/dev/null + } + + $ipt_tmp -I PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(dst $IPSET_PROXY_LAN) ${ipt_j} + $ipt_tmp -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP ${ipt_j} + add_shunt_t_rule "${shunt_list4}" "$ipt_tmp -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source}" "${ipt_j}" $tcp_redir_ports + add_port_rules "$ipt_tmp -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "${ipt_j}" + [ -n "${is_tproxy}" ] && $ipt_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + $ip6t_m -I PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(dst $IPSET_PROXY_LAN6) -j PSW2_RULE 2>/dev/null + $ip6t_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP_6 -j PSW2_RULE 2>/dev/null + add_shunt_t_rule "${shunt_list6}" "$ip6t_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source}" "${ipt_j}" $tcp_redir_ports 2>/dev/null + add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "-j PSW2_RULE" 2>/dev/null + $ip6t_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) 2>/dev/null + } + log 2 "${msg2}" + } + $ipt_tmp -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN + [ "$_ipv4" != "1" ] && $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp -j RETURN 2>/dev/null + + [ "$udp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { + msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remark}")(TPROXY:${redir_port})" + + $ipt_m -I PSW2 $(comment "$remarks") -p udp ${_ipt_source} $(dst $IPSET_PROXY_LAN) -j PSW2_RULE + $ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source} -d $FAKE_IP -j PSW2_RULE + add_shunt_t_rule "${shunt_list4}" "$ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source}" "-j PSW2_RULE" $udp_redir_ports + add_port_rules "$ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "-j PSW2_RULE" + $ipt_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source} $(REDIRECT $redir_port TPROXY) + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + $ip6t_m -I PSW2 $(comment "$remarks") -p udp ${_ipt_source} $(dst $IPSET_PROXY_LAN6) -j PSW2_RULE 2>/dev/null + $ip6t_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source} -d $FAKE_IP_6 -j PSW2_RULE 2>/dev/null + add_shunt_t_rule "${shunt_list6}" "$ip6t_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source}" "-j PSW2_RULE" $udp_redir_ports 2>/dev/null + add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "-j PSW2_RULE" 2>/dev/null + $ip6t_m -A PSW2 $(comment "$remarks") -p udp ${_ipt_source} $(REDIRECT $redir_port TPROXY) 2>/dev/null + } + log 2 "${msg2}" + } + $ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN + [ "$_ipv4" != "1" ] && $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN 2>/dev/null + unset ipt_tmp ipt_j _ipt_source msg msg2 _ipv4 + done + unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface + unset node_remark _acl_list + done + } + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && { + local comment_d="$(i18n "Default")" + msg="$(i18n "[%s]," ${comment_d})" + local ipt_tmp=$ipt_n + [ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m + + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")" + else + TCP_PROXY_MODE="disable" + log 2 "${msg}$(i18n "not proxy all %s" "TCP")" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")" + else + UDP_PROXY_MODE="disable" + log 2 "${msg}$(i18n "not proxy all %s" "UDP")" + fi + } + + if ([ "$TCP_PROXY_MODE" != "disable" ] || [ "$UDP_PROXY_MODE" != "disable" ]) && [ -n "$NODE" ]; then + [ -n "$DNS_REDIRECT_PORT" ] && { + $ipt_n -A PSW2_DNS $(comment "${comment_d}") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A PSW2_DNS $(comment "${comment_d}") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + $ipt_n -A PSW2_DNS $(comment "${comment_d}") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A PSW2_DNS $(comment "${comment_d}") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + } + fi + + if [ "$TCP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then + msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "$(config_n_get $NODE remarks)")" + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${REDIR_PORT})" + ipt_j="-j PSW2_RULE" + else + msg2="${msg2}(REDIRECT:${REDIR_PORT})" + ipt_j="$(REDIRECT $REDIR_PORT)" + fi + + [ "$accept_icmp" = "1" ] && { + $ipt_n -I PSW2 $(comment "${comment_d}") -p icmp $(dst $IPSET_PROXY_LAN) $(REDIRECT) + $ipt_n -A PSW2 $(comment "${comment_d}") -p icmp -d $FAKE_IP $(REDIRECT) + add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_n -A PSW2 $(comment "${comment_d}") -p icmp" "$(REDIRECT)" + $ipt_n -A PSW2 $(comment "${comment_d}") -p icmp $(REDIRECT) + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { + $ip6t_n -I PSW2 $(comment "${comment_d}") -p ipv6-icmp $(dst $IPSET_PROXY_LAN6) $(REDIRECT) + $ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT) + add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp" "$(REDIRECT)" + $ip6t_n -A PSW2 $(comment "${comment_d}") -p ipv6-icmp $(REDIRECT) + } + + $ipt_tmp -I PSW2 $(comment "${comment_d}") -p tcp $(dst $IPSET_PROXY_LAN) ${ipt_j} + $ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp -d $FAKE_IP ${ipt_j} + add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp" "${ipt_j}" $TCP_REDIR_PORTS + add_port_rules "$ipt_tmp -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_REDIR_PORTS "${ipt_j}" + [ -n "${is_tproxy}" ] && $ipt_m -A PSW2 $(comment "${comment_d}") -p tcp $(REDIRECT $REDIR_PORT TPROXY) + + [ "$PROXY_IPV6" == "1" ] && { + $ip6t_m -I PSW2 $(comment "${comment_d}") -p tcp $(dst $IPSET_PROXY_LAN6) -j PSW2_RULE + $ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp -d $FAKE_IP_6 -j PSW2_RULE + add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" "-j PSW2_RULE" $TCP_REDIR_PORTS + add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp" $TCP_REDIR_PORTS "-j PSW2_RULE" + $ip6t_m -A PSW2 $(comment "${comment_d}") -p tcp $(REDIRECT $REDIR_PORT TPROXY) + } + + log 2 "${msg2}" + fi + + if [ "$UDP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then + msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "$(config_n_get $NODE remarks)")(TPROXY:${REDIR_PORT})" + + $ipt_m -I PSW2 $(comment "${comment_d}") -p udp $(dst $IPSET_PROXY_LAN) -j PSW2_RULE + $ipt_m -A PSW2 $(comment "${comment_d}") -p udp -d $FAKE_IP -j PSW2_RULE + add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_m -A PSW2 $(comment "${comment_d}") -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS + add_port_rules "$ipt_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE" + $ipt_m -A PSW2 $(comment "${comment_d}") -p udp $(REDIRECT $REDIR_PORT TPROXY) + + [ "$PROXY_IPV6" == "1" ] && { + $ip6t_m -I PSW2 $(comment "${comment_d}") -p udp $(dst $IPSET_PROXY_LAN6) -j PSW2_RULE + $ip6t_m -A PSW2 $(comment "${comment_d}") -p udp -d $FAKE_IP_6 -j PSW2_RULE + add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS + add_port_rules "$ip6t_m -A PSW2 $(comment "${comment_d}") -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE" + $ip6t_m -A PSW2 $(comment "${comment_d}") -p udp $(REDIRECT $REDIR_PORT TPROXY) + } + + log 2 "${msg2}" + fi + } +} + +filter_haproxy() { + for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do + local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1) + [ -n "$ip" ] && ipset -q add $IPSET_VPS $ip + done + log_i18n 1 "Add node to the load balancer is directly connected to %s[%s]." "ipset" "${IPSET_VPS}" +} + +filter_vpsip() { + uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "ipset" "${$IPSET_VPS}")" + uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPS6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "ipset" "${$IPSET_VPS6}")" +} + +filter_server_port() { + local address=${1} + local port=${2} + local stream=${3} + stream=$(echo ${3} | tr 'A-Z' 'a-z') + local _is_tproxy ipt_tmp + ipt_tmp=$ipt_n + _is_tproxy=${is_tproxy} + [ "$stream" == "udp" ] && _is_tproxy="TPROXY" + [ -n "${_is_tproxy}" ] && ipt_tmp=$ipt_m + + for _ipt in 4 6; do + [ "$_ipt" == "4" ] && _ipt=$ipt_tmp + [ "$_ipt" == "6" ] && _ipt=$ip6t_m + $_ipt -n -L PSW2_OUTPUT | grep -q "${address}:${port}" + if [ $? -ne 0 ]; then + $_ipt -I PSW2_OUTPUT $(comment "${address}:${port}") -p $stream -d $address --dport $port -j RETURN 2>/dev/null + fi + done +} + +filter_node() { + local node=${1} + local stream=${2} + if [ -n "$node" ]; then + local address=$(config_n_get $node address) + local port=$(config_n_get $node port) + [ -z "$address" ] && [ -z "$port" ] && { + return 1 + } + filter_server_port $address $port $stream + filter_server_port $address $port $stream + fi +} + +filter_direct_node_list() { + [ ! -s "$TMP_PATH/direct_node_list" ] && return + for _node_id in $(cat $TMP_PATH/direct_node_list | awk '!seen[$0]++'); do + filter_node "$_node_id" TCP + filter_node "$_node_id" UDP + unset _node_id + done +} + +update_wan_sets() { + [ -z "$(command -v get_wan_ips)" ] && . "$UTILS_PATH" + + local WAN_IP=$(get_wan_ips ip4) + [ -n "$WAN_IP" ] && { + ipset -F "$IPSET_WAN" + for wan_ip in $WAN_IP; do + ipset -! add "$IPSET_WAN" "$wan_ip" + done + } + + local WAN6_IP=$(get_wan_ips ip6) + [ -n "$WAN6_IP" ] && { + ipset -F "$IPSET_WAN6" + for wan6_ip in $WAN6_IP; do + ipset -! add "$IPSET_WAN6" "$wan6_ip" + done + } +} + +add_firewall_rule() { + log_i18n 0 "Starting to load %s firewall rules..." "iptables" + + ipset -! create $IPSET_LOCAL nethash maxelem 1048576 + ipset -! create $IPSET_PROXY_LAN nethash maxelem 1048576 + ipset -! create $IPSET_LAN nethash maxelem 1048576 + ipset -! create $IPSET_VPS iphash maxelem 1048576 + ipset -! create $IPSET_WAN nethash maxelem 1048576 + + ipset -! create $IPSET_LOCAL6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_PROXY_LAN6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_LAN6 nethash family inet6 maxelem 1048576 + ipset -! create $IPSET_VPS6 iphash family inet6 maxelem 1048576 + ipset -! create $IPSET_WAN6 nethash family inet6 maxelem 1048576 + + get_local_ips ip4 | sed "s/^/add $IPSET_LOCAL /" | ipset -! -R + get_local_ips ip6 | sed "s/^/add $IPSET_LOCAL6 /" | ipset -! -R + + ipset -! -R <<-EOF + $(gen_lanlist | sed -e "s/^/add $IPSET_LAN /") + EOF + + ipset -! -R <<-EOF + $(gen_lanlist_6 | sed -e "s/^/add $IPSET_LAN6 /") + EOF + + # Ignore special IP ranges + local lan_ifname lan_ip + lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname) + [ -n "$lan_ifname" ] && { + lan_ip=$(ip address show $lan_ifname | grep -w "inet" | awk '{print $2}') + lan_ip6=$(ip address show $lan_ifname | grep -w "inet6" | awk '{print $2}') + #log_i18n 1 "local network segments (%s) direct connection: %s" "IPv4" "${lan_ip}" + #log_i18n 1 "local network segments (%s) direct connection: %s" "IPv6" "${lan_ip6}" + + [ -n "$lan_ip" ] && ipset -! -R <<-EOF + $(echo $lan_ip | sed -e "s/ /\n/g" | sed -e "s/^/add $IPSET_LAN /") + EOF + + [ -n "$lan_ip6" ] && ipset -! -R <<-EOF + $(echo $lan_ip6 | sed -e "s/ /\n/g" | sed -e "s/^/add $IPSET_LAN6 /") + EOF + } + + update_wan_sets + + [ -n "$ISP_DNS" ] && { + for ispip in $ISP_DNS; do + ipset -! add $IPSET_LAN $ispip + log_i18n 1 "$(i18n "Add ISP %s DNS to the whitelist: %s" "IPv4" "${ispip}")" + done + } + + [ -n "$ISP_DNS6" ] && { + for ispip6 in $ISP_DNS6; do + ipset -! add $IPSET_LAN6 $ispip6 + log_i18n 1 "$(i18n "Add ISP %s DNS to the whitelist: %s" "IPv6" "${ispip6}")" + done + } + + # Force proxy LAN IP CIDR + force_proxy_lan_ip=$(config_t_get global_forwarding force_proxy_lan_ip) + for ip in $force_proxy_lan_ip; do + if [[ "$ip" == *::* ]]; then + ipset -! add $IPSET_PROXY_LAN6 $ip + else + ipset -! add $IPSET_PROXY_LAN $ip + fi + done + + # Shunt rules IP list (import when use shunt node) + gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6 + + # Filter all node IPs + filter_vpsip > /dev/null 2>&1 & + filter_haproxy > /dev/null 2>&1 & + + accept_icmp=$(config_t_get global_forwarding accept_icmp 0) + accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0) + + if [ "${TCP_PROXY_WAY}" = "redirect" ]; then + unset is_tproxy + elif [ "${TCP_PROXY_WAY}" = "tproxy" ]; then + is_tproxy="TPROXY" + fi + + if [ -z "${is_tproxy}" ] || [ "$accept_icmp" = "1" ]; then + IPT_N=1 + fi + + if [ -z "${is_tproxy}" ] || [ "$accept_icmpv6" = "1" ]; then + IP6T_N=1 + fi + + $ipt_n -N PSW2 + $ipt_n -A PSW2 $(dst $IPSET_LAN) -j RETURN + $ipt_n -A PSW2 $(dst $IPSET_VPS) -j RETURN + $ipt_n -A PSW2 $(comment "WAN_IP_RETURN") $(dst $IPSET_WAN) -j RETURN + + [ "$accept_icmp" = "1" ] && insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p icmp -j PSW2" + [ -z "${is_tproxy}" ] && insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW2" + + $ipt_n -N PSW2_OUTPUT + $ipt_n -A PSW2_OUTPUT $(dst $IPSET_LAN) -j RETURN + $ipt_n -A PSW2_OUTPUT $(dst $IPSET_VPS) -j RETURN + $ipt_n -A PSW2_OUTPUT -m mark --mark 255 -j RETURN + + $ipt_n -N PSW2_DNS + if [ $(config_t_get global dns_redirect "1") = "0" ]; then + #Only hijack when dest address is local IP + $ipt_n -I PREROUTING -m set --match-set $IPSET_LAN src $(dst $IPSET_LOCAL) -j PSW2_DNS + else + $ipt_n -I PREROUTING -m set --match-set $IPSET_LAN src -j PSW2_DNS + fi + + $ipt_m -N PSW2_DIVERT + $ipt_m -A PSW2_DIVERT -j MARK --set-mark ${FWMARK} + $ipt_m -A PSW2_DIVERT -j ACCEPT + + $ipt_m -N PSW2_RULE + $ipt_m -A PSW2_RULE -j CONNMARK --restore-mark + $ipt_m -A PSW2_RULE -m mark --mark ${FWMARK} -j RETURN + $ipt_m -A PSW2_RULE -p tcp -m tcp --syn -j MARK --set-xmark ${FWMARK} + $ipt_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark ${FWMARK} + $ipt_m -A PSW2_RULE -j CONNMARK --save-mark + + $ipt_m -N PSW2 + $ipt_m -A PSW2 $(dst $IPSET_LAN) -j RETURN + $ipt_m -A PSW2 $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW2 $(comment "WAN_IP_RETURN") $(dst $IPSET_WAN) -j RETURN + $ipt_m -A PSW2 -m conntrack --ctdir REPLY -j RETURN + + insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW2" + # Only TCP, UDP Invalid. + insert_rule_before "$ipt_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT" + + $ipt_m -N PSW2_OUTPUT + $ipt_m -A PSW2_OUTPUT $(dst $IPSET_LAN) -j RETURN + $ipt_m -A PSW2_OUTPUT $(dst $IPSET_VPS) -j RETURN + $ipt_m -A PSW2_OUTPUT -m conntrack --ctdir REPLY -j RETURN + $ipt_m -A PSW2_OUTPUT -m mark --mark 255 -j RETURN + + ip rule add fwmark ${FWMARK} table 999 priority 999 + ip route add local 0.0.0.0/0 dev lo table 999 + + [ "$accept_icmpv6" = "1" ] && { + $ip6t_n -N PSW2 + $ip6t_n -A PSW2 $(dst $IPSET_LAN6) -j RETURN + $ip6t_n -A PSW2 $(dst $IPSET_VPS6) -j RETURN + $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW2 + + $ip6t_n -N PSW2_OUTPUT + $ip6t_n -A PSW2_OUTPUT $(dst $IPSET_LAN6) -j RETURN + $ip6t_n -A PSW2_OUTPUT $(dst $IPSET_VPS6) -j RETURN + $ip6t_n -A PSW2_OUTPUT -m mark --mark 255 -j RETURN + } + + $ip6t_n -N PSW2_DNS + if [ $(config_t_get global dns_redirect "1") = "0" ]; then + #Only hijack when dest address is local IP + $ip6t_n -I PREROUTING -m set --match-set $IPSET_LAN6 src $(dst $IPSET_LOCAL6) -j PSW2_DNS + else + $ip6t_n -I PREROUTING -m set --match-set $IPSET_LAN6 src -j PSW2_DNS + fi + + $ip6t_m -N PSW2_DIVERT + $ip6t_m -A PSW2_DIVERT -j MARK --set-mark ${FWMARK} + $ip6t_m -A PSW2_DIVERT -j ACCEPT + + $ip6t_m -N PSW2_RULE + $ip6t_m -A PSW2_RULE -j CONNMARK --restore-mark + $ip6t_m -A PSW2_RULE -m mark --mark ${FWMARK} -j RETURN + $ip6t_m -A PSW2_RULE -p tcp -m tcp --syn -j MARK --set-xmark ${FWMARK} + $ip6t_m -A PSW2_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark ${FWMARK} + $ip6t_m -A PSW2_RULE -j CONNMARK --save-mark + + $ip6t_m -N PSW2 + $ip6t_m -A PSW2 $(dst $IPSET_LAN6) -j RETURN + $ip6t_m -A PSW2 $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW2 $(comment "WAN6_IP_RETURN") $(dst $IPSET_WAN6) -j RETURN + $ip6t_m -A PSW2 -m conntrack --ctdir REPLY -j RETURN + + insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW2" + # Only TCP, UDP Invalid. + insert_rule_before "$ip6t_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT" + + $ip6t_m -N PSW2_OUTPUT + $ip6t_m -A PSW2_OUTPUT -m mark --mark 255 -j RETURN + $ip6t_m -A PSW2_OUTPUT $(dst $IPSET_LAN6) -j RETURN + $ip6t_m -A PSW2_OUTPUT $(dst $IPSET_VPS6) -j RETURN + $ip6t_m -A PSW2_OUTPUT -m conntrack --ctdir REPLY -j RETURN + + [ -n "$AUTO_DNS" ] && { + for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do + local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') + local dns_port=$(echo $auto_dns | awk -F '#' '{print $2}') + if [[ "$dns_address" == *::* ]]; then + $ip6t_m -I PSW2_OUTPUT -p udp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + log_i18n 1 "$(i18n "Add direct DNS to %s: %s" "ip6tables" "[${dns_address}]:${dns_port:-53}")" + else + $ipt_m -I PSW2_OUTPUT -p udp -d ${dns_address} --dport ${dns_port:-53} -j RETURN + log_i18n 1 "$(i18n "Add direct DNS to %s: %s" "iptables" "${dns_address}:${dns_port:-53}")" + fi + done + } + + ip -6 rule add fwmark ${FWMARK} table 999 priority 999 + ip -6 route add local ::/0 dev lo table 999 + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && { + local ipt_tmp=$ipt_n + [ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m + + TCP_LOCALHOST_PROXY=$LOCALHOST_PROXY + UDP_LOCALHOST_PROXY=$LOCALHOST_PROXY + + msg="$(i18n "[Local],")" + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + log 1 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")" + else + unset TCP_LOCALHOST_PROXY + log 1 "${msg}$(i18n "not proxy all %s" "TCP")" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + log 1 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")" + else + unset UDP_LOCALHOST_PROXY + log 1 "${msg}$(i18n "not proxy all %s" "UDP")" + fi + } + + if [ -n "$NODE" ] && ([ "$TCP_LOCALHOST_PROXY" = "1" ] || [ "$UDP_LOCALHOST_PROXY" = "1" ]); then + [ -n "$DNS_REDIRECT_PORT" ] && { + $ipt_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A OUTPUT $(comment "PSW2_DNS") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + $ipt_n -A OUTPUT $(comment "PSW2_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A OUTPUT $(comment "PSW2_DNS") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + } + fi + + local comment_l="$(i18n "Local")" + + # Loading local router proxy TCP + if [ -n "$NODE" ] && [ "$TCP_LOCALHOST_PROXY" = "1" ]; then + [ "$accept_icmp" = "1" ] && { + $ipt_n -A OUTPUT -p icmp -j PSW2_OUTPUT + $ipt_n -I PSW2_OUTPUT -p icmp $(dst $IPSET_PROXY_LAN) $(REDIRECT) + $ipt_n -A PSW2_OUTPUT -p icmp -d $FAKE_IP $(REDIRECT) + add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_n -A PSW2_OUTPUT -p icmp" "$(REDIRECT)" + $ipt_n -A PSW2_OUTPUT -p icmp $(REDIRECT) + } + + [ "$accept_icmpv6" = "1" ] && { + $ip6t_n -A OUTPUT -p ipv6-icmp -j PSW2_OUTPUT + $ip6t_n -I PSW2_OUTPUT -p ipv6-icmp $(dst $IPSET_PROXY_LAN6) $(REDIRECT) + $ip6t_n -A PSW2_OUTPUT -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT) + add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_n -A PSW2_OUTPUT -p ipv6-icmp" "$(REDIRECT)" + $ip6t_n -A PSW2_OUTPUT -p ipv6-icmp $(REDIRECT) + } + + if [ -n "${is_tproxy}" ]; then + ipt_j="-j PSW2_RULE" + else + ipt_j="$(REDIRECT $REDIR_PORT)" + fi + + $ipt_tmp -I PSW2_OUTPUT -p tcp $(dst $IPSET_PROXY_LAN) ${ipt_j} + $ipt_tmp -A PSW2_OUTPUT -p tcp -d $FAKE_IP ${ipt_j} + add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_tmp -A PSW2_OUTPUT -p tcp" "${ipt_j}" $TCP_REDIR_PORTS + add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $TCP_REDIR_PORTS "${ipt_j}" + [ -z "${is_tproxy}" ] && $ipt_n -A OUTPUT -p tcp -j PSW2_OUTPUT + [ -n "${is_tproxy}" ] && { + $ipt_m -I PSW2 $(comment "${comment_l}") -p tcp -i lo $(dst $IPSET_PROXY_LAN) $(REDIRECT $REDIR_PORT TPROXY) + $ipt_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo $(REDIRECT $REDIR_PORT TPROXY) + $ipt_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo -j RETURN + insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p tcp -j PSW2_OUTPUT" + } + + [ "$PROXY_IPV6" == "1" ] && { + $ip6t_m -I PSW2_OUTPUT -p tcp $(dst $IPSET_PROXY_LAN6) -j PSW2_RULE + $ip6t_m -A PSW2_OUTPUT -p tcp -d $FAKE_IP_6 -j PSW2_RULE + add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2_OUTPUT -p tcp" "-j PSW2_RULE" $TCP_REDIR_PORTS + add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $TCP_REDIR_PORTS "-j PSW2_RULE" + $ip6t_m -I PSW2 $(comment "${comment_l}") -p tcp -i lo $(dst $IPSET_PROXY_LAN6) $(REDIRECT $REDIR_PORT TPROXY) + $ip6t_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo $(REDIRECT $REDIR_PORT TPROXY) + $ip6t_m -A PSW2 $(comment "${comment_l}") -p tcp -i lo -j RETURN + insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p tcp -j PSW2_OUTPUT" + } + + [ -d "${TMP_IFACE_PATH}" ] && { + for iface in $(ls ${TMP_IFACE_PATH}); do + $ipt_n -A PSW2_OUTPUT -o $iface -p tcp -j RETURN + $ipt_m -A PSW2_OUTPUT -o $iface -p tcp -j RETURN + done + } + fi + + # Loading local router proxy UDP + if [ -n "$NODE" ] && [ "$UDP_LOCALHOST_PROXY" = "1" ]; then + $ipt_m -I PSW2_OUTPUT -p udp $(dst $IPSET_PROXY_LAN) -j PSW2_RULE + $ipt_m -A PSW2_OUTPUT -p udp -d $FAKE_IP -j PSW2_RULE + add_shunt_t_rule "${SHUNT_LIST4}" "$ipt_m -A PSW2_OUTPUT -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS + add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE" + $ipt_m -I PSW2 $(comment "${comment_l}") -p udp -i lo $(dst $IPSET_PROXY_LAN) $(REDIRECT $REDIR_PORT TPROXY) + $ipt_m -A PSW2 $(comment "${comment_l}") -p udp -i lo $(REDIRECT $REDIR_PORT TPROXY) + $ipt_m -A PSW2 $(comment "${comment_l}") -p udp -i lo -j RETURN + insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p udp -j PSW2_OUTPUT" + + [ "$PROXY_IPV6" == "1" ] && { + $ip6t_m -I PSW2_OUTPUT -p udp $(dst $IPSET_PROXY_LAN6) -j PSW2_RULE + $ip6t_m -A PSW2_OUTPUT -p udp -d $FAKE_IP_6 -j PSW2_RULE + add_shunt_t_rule "${SHUNT_LIST6}" "$ip6t_m -A PSW2_OUTPUT -p udp" "-j PSW2_RULE" $UDP_REDIR_PORTS + add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $UDP_REDIR_PORTS "-j PSW2_RULE" + $ip6t_m -I PSW2 $(comment "${comment_l}") -p udp -i lo $(dst $IPSET_PROXY_LAN6) $(REDIRECT $REDIR_PORT TPROXY) + $ip6t_m -A PSW2 $(comment "${comment_l}") -p udp -i lo $(REDIRECT $REDIR_PORT TPROXY) + $ip6t_m -A PSW2 $(comment "${comment_l}") -p udp -i lo -j RETURN + insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p udp -j PSW2_OUTPUT" + } + + [ -d "${TMP_IFACE_PATH}" ] && { + for iface in $(ls ${TMP_IFACE_PATH}); do + $ipt_n -A PSW2_OUTPUT -o $iface -p udp -j RETURN + $ipt_m -A PSW2_OUTPUT -o $iface -p udp -j RETURN + done + } + fi + + $ipt_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN + insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN" + + $ip6t_m -I OUTPUT $(comment "mangle-OUTPUT-PSW2") -o lo -j RETURN + insert_rule_before "$ip6t_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -m mark --mark ${FWMARK} -j RETURN" + + $ipt_m -A PSW2 -p udp --dport 53 -j RETURN + $ip6t_m -A PSW2 -p udp --dport 53 -j RETURN + } + + load_acl + + filter_direct_node_list > /dev/null 2>&1 & + + [ -z "${IPT_N}" ] && { + for chain in "PSW2" "PSW2_OUTPUT"; do + $ipt_n -F $chain 2>/dev/null + $ipt_n -X $chain 2>/dev/null + done + } + [ -z "${IP6T_N}" ] && { + for chain in "PSW2" "PSW2_OUTPUT"; do + $ip6t_n -F $chain 2>/dev/null + $ip6t_n -X $chain 2>/dev/null + done + } + + log_i18n 0 "%s firewall rules load complete!" "iptables" +} + +del_firewall_rule() { + for ipt in "$ipt_n" "$ipt_m" "$ip6t_n" "$ip6t_m"; do + for chain in "PREROUTING" "OUTPUT"; do + for i in $(seq 1 $($ipt -nL $chain | grep -c PSW2)); do + local index=$($ipt --line-number -nL $chain | grep PSW2 | head -1 | awk '{print $1}') + $ipt -D $chain $index 2>/dev/null + done + done + for chain in "PSW2" "PSW2_OUTPUT" "PSW2_DIVERT" "PSW2_DNS" "PSW2_RULE"; do + $ipt -F $chain 2>/dev/null + $ipt -X $chain 2>/dev/null + done + done + + ip rule del fwmark ${FWMARK} 2>/dev/null + ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null + + ip -6 rule del fwmark ${FWMARK} 2>/dev/null + ip -6 route del local ::/0 dev lo table 999 2>/dev/null + + log_i18n 0 "Delete %s rules is complete." "iptables" +} + +flush_ipset() { + log_i18n 0 "Clear %s." "IPSet" + for _name in $(ipset list | grep "Name: " | grep "psw2_" | awk '{print $2}'); do + destroy_ipset ${_name} + done +} + +flush_include() { + echo '#!/bin/sh' >$FWI +} + +gen_include() { + flush_include + extract_rules() { + local _ipt="${ipt}" + [ "$1" == "6" ] && _ipt="${ip6t}" + [ -z "${_ipt}" ] && return + + echo "*$2" + ${_ipt}-save -t $2 | grep "PSW2" | grep -v "\-j PSW2$" | grep -v "socket \-j PSW2_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + echo 'COMMIT' + } + local __ipt="" + [ -n "${ipt}" ] && { + __ipt=$(cat <<- EOF + ${MY_PATH} update_wan_sets + $ipt-save -c | grep -v "PSW2" | $ipt-restore -c + $ipt-restore -n <<-EOT + $(extract_rules 4 nat) + $(extract_rules 4 mangle) + EOT + + [ "$accept_icmp" = "1" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p icmp -j PSW2") + [ -z "${is_tproxy}" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW2") + + \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW2") + \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT") + EOF + ) + } + local __ip6t="" + [ -n "${ip6t}" ] && { + __ip6t=$(cat <<- EOF + ${MY_PATH} update_wan_sets + $ip6t-save -c | grep -v "PSW2" | $ip6t-restore -c + $ip6t-restore -n <<-EOT + $(extract_rules 6 nat) + $(extract_rules 6 mangle) + EOT + + [ "$accept_icmpv6" = "1" ] && $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW2 + + \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW2") + \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "PSW2" "-p tcp -m socket -j PSW2_DIVERT") + EOF + ) + } + cat <<-EOF >> $FWI + ${__ipt} + + ${__ip6t} + + return 0 + EOF + return 0 +} + +get_ipt_bin() { + echo $ipt +} + +get_ip6t_bin() { + echo $ip6t +} + +start() { + [ "$ENABLED_DEFAULT_ACL" == 0 -a "$ENABLED_ACLS" == 0 ] && return + add_firewall_rule + gen_include +} + +stop() { + [ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH" + del_firewall_rule + destroy_ipset $IPSET_PROXY_LAN + destroy_ipset $IPSET_PROXY_LAN6 + [ $(config_t_get global flush_set "0") = "1" ] && { + uci -q delete ${CONFIG}.@global[0].flush_set + uci -q commit ${CONFIG} + flush_ipset + rm -rf $TMP_PATH2/singbox* + rm -rf $TMP_PATH2/geo_output + } + flush_include +} + +arg1=$1 +shift +case $arg1 in +RULE_LAST_INDEX) + RULE_LAST_INDEX "$@" + ;; +insert_rule_before) + insert_rule_before "$@" + ;; +insert_rule_after) + insert_rule_after "$@" + ;; +get_ipt_bin) + get_ipt_bin + ;; +get_ip6t_bin) + get_ip6t_bin + ;; +filter_direct_node_list) + filter_direct_node_list + ;; +update_wan_sets) + update_wan_sets "$@" + ;; +stop) + stop + ;; +start) + start + ;; +*) ;; +esac diff --git a/luci-app-passwall2/root/usr/share/passwall2/lease2hosts.sh b/luci-app-passwall2/root/usr/share/passwall2/lease2hosts.sh new file mode 100755 index 00000000..be667b37 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/lease2hosts.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# dhcp.leases to hosts + +. /usr/share/passwall2/utils.sh +LOCK_FILE=${LOCK_PATH}/${CONFIG}_lease2hosts.lock +LEASE_FILE="/tmp/dhcp.leases" +HOSTS_FILE="$TMP_PATH2/dhcp-hosts" +TMP_FILE="/tmp/dhcp-hosts.tmp" + +exec 99>"$LOCK_FILE" +flock -n 99 +if [ "$?" != 0 ]; then + exit 0 +fi + +reload_dnsmasq_pids() { + local pidfile pid + find $TMP_PATH/acl -type f -name 'dnsmasq.pid' 2>/dev/null | while read pidfile; do + if [ -s "$pidfile" ]; then + read pid < "$pidfile" + if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then + kill -HUP "$pid" + fi + fi + done +} + +while true; do + + if [ -f "$LEASE_FILE" ]; then + awk 'NF >= 4 && $4 != "*" {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE" + if [ -s "$TMP_FILE" ]; then + if [ ! -f "$HOSTS_FILE" ] || ! cmp -s "$TMP_FILE" "$HOSTS_FILE"; then + mv "$TMP_FILE" "$HOSTS_FILE" + reload_dnsmasq_pids + else + rm -f "$TMP_FILE" + fi + else + if [ -s "$HOSTS_FILE" ]; then + : > "$HOSTS_FILE" + reload_dnsmasq_pids + fi + rm -f "$TMP_FILE" + fi + fi + + sleep 60 + +done 2>/dev/null diff --git a/luci-app-passwall2/root/usr/share/passwall2/monitor.sh b/luci-app-passwall2/root/usr/share/passwall2/monitor.sh new file mode 100755 index 00000000..e072465a --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/monitor.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +. /usr/share/passwall2/utils.sh +LOCK_FILE=${LOCK_PATH}/${CONFIG}_monitor.lock + +ENABLED=$(config_t_get global enabled 0) +[ "$ENABLED" != 1 ] && return 1 +ENABLED=$(config_t_get global_delay start_daemon 0) +[ "$ENABLED" != 1 ] && return 1 +sleep 58s +while [ "$ENABLED" -eq 1 ]; do + [ -f "$LOCK_FILE" ] && { + sleep 6s + continue + } + touch $LOCK_FILE + [ -d ${TMP_SCRIPT_FUNC_PATH} ] && { + for filename in $(ls ${TMP_SCRIPT_FUNC_PATH} | grep -v "^_"); do + cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename}) + cmd_check=$(echo $cmd | awk -F '>' '{print $1}') + icount=$(busybox pgrep -f "$(echo $cmd_check)" | wc -l) + if [ $icount = 0 ]; then + #echo "${cmd} crashed, restarting." >> /tmp/log/passwall2.log + eval $(echo "nohup ${cmd} 2>&1 &") >/dev/null 2>&1 & + fi + done + } + + rm -f $LOCK_FILE + sleep 58s +done diff --git a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh new file mode 100755 index 00000000..a8655ac3 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh @@ -0,0 +1,1153 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +MY_PATH=$DIR/nftables.sh +UTILS_PATH=$DIR/utils.sh +NFTABLE_NAME="inet passwall2" +NFTSET_LOCAL="psw2_local" +NFTSET_PROXY_LAN="psw2_proxy_lan" +NFTSET_LAN="psw2_lan" +NFTSET_VPS="psw2_vps" +NFTSET_WAN="psw2_wan" + +NFTSET_LOCAL6="psw2_local6" +NFTSET_PROXY_LAN6="psw2_proxy_lan6" +NFTSET_LAN6="psw2_lan6" +NFTSET_VPS6="psw2_vps6" +NFTSET_WAN6="psw2_wan6" + +FWMARK="0x50535732" + +FWI=$(uci -q get firewall.passwall2.path 2>/dev/null) +FAKE_IP="198.18.0.0/16" +FAKE_IP_6="fc00::/18" + +factor() { + local ports="$1" + if [ -z "$1" ] || [ -z "$2" ] || [ "$ports" = "1:65535" ]; then + echo "" + # acl mac address + elif echo "$1" | grep -qE '([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}'; then + echo "$2 {$1}" + else + ports=$(echo "$ports" | tr -d ' ' | sed 's/:/-/g' | tr ',' '\n' | awk '!a[$0]++' | grep -v '^$') + [ -z "$ports" ] && { echo ""; return; } + if echo "$ports" | grep -q '^1-65535$'; then + echo "" + return + fi + local port + local port_list="" + for port in $ports; do + port_list="${port_list},$port" + done + port_list="${port_list#,}" + echo "$2 {$port_list}" + fi +} + +insert_rule_before() { + [ $# -ge 4 ] || { + return 1 + } + local table_name="${1}"; shift + local chain_name="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$(nft -a list chain $table_name $chain_name 2>/dev/null | grep "$keyword" | awk -F '# handle ' '{print$2}' | head -n 1 | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + nft "add rule $table_name $chain_name $rule" + else + if [ -z "${_index}" ]; then + _index=${default_index} + fi + nft "insert rule $table_name $chain_name position $_index $rule" + fi +} + +insert_rule_after() { + [ $# -ge 4 ] || { + return 1 + } + local table_name="${1}"; shift + local chain_name="${1}"; shift + local keyword="${1}"; shift + local rule="${1}"; shift + local default_index="${1}"; shift + default_index=${default_index:-0} + local _index=$(nft -a list chain $table_name $chain_name 2>/dev/null | grep "$keyword" | awk -F '# handle ' '{print$2}' | head -n 1 | awk '{print $1}') + if [ -z "${_index}" ] && [ "${default_index}" = "0" ]; then + nft "add rule $table_name $chain_name $rule" + else + if [ -n "${_index}" ]; then + _index=$((_index + 1)) + else + _index=${default_index} + fi + nft "insert rule $table_name $chain_name position $_index $rule" + fi +} + +RULE_LAST_INDEX() { + [ $# -ge 3 ] || { + log_i18n 1 "Incorrect index listing method (%s), execution terminated!" "nftables" + return 1 + } + local table_name="${1}"; shift + local chain_name="${1}"; shift + local keyword="${1}"; shift + local default="${1:-0}"; shift + local _index=$(nft -a list chain $table_name $chain_name 2>/dev/null | grep "$keyword" | awk -F '# handle ' '{print$2}' | head -n 1 | awk '{print $1}') + echo "${_index:-${default}}" +} + +REDIRECT() { + local s="counter redirect" + [ -n "$1" ] && { + local s="$s to :$1" + [ "$2" == "TPROXY" ] && { + s="counter meta mark ${FWMARK} tproxy to :$1" + } + [ "$2" == "TPROXY4" ] && { + s="counter meta mark ${FWMARK} tproxy ip to :$1" + } + [ "$2" == "TPROXY6" ] && { + s="counter meta mark ${FWMARK} tproxy ip6 to :$1" + } + + } + echo $s +} + +destroy_nftset() { + for i in "$@"; do + nft flush set $NFTABLE_NAME $i 2>/dev/null + nft delete set $NFTABLE_NAME $i 2>/dev/null + done +} + +gen_nft_tables() { + if ! nft list table "$NFTABLE_NAME" >/dev/null 2>&1; then + nft -f - <<-EOF + table $NFTABLE_NAME { + chain dstnat { + type nat hook prerouting priority dstnat - 1; policy accept; + } + chain mangle_prerouting { + type filter hook prerouting priority mangle - 1; policy accept; + } + chain mangle_output { + type route hook output priority mangle - 1; policy accept; + } + chain nat_output { + type nat hook output priority -1; policy accept; + } + } + EOF + fi +} + +insert_nftset() { + local nftset_name="${1}"; shift + local timeout_argument="${1}"; shift + local default_timeout="365d" + local suffix="" + + if [ -n "$nftset_name" ] && { [ $# -gt 0 ] || [ ! -t 0 ]; }; then + case "$timeout_argument" in + "-1") suffix="" ;; + "0") suffix=" timeout $default_timeout" ;; + *) suffix=" timeout $timeout_argument" ;; + esac + { + if [ $# -gt 0 ]; then + printf "%s\n" "$@" + else + cat + fi | tr -s ' \t' '\n' | awk -v s="$suffix" -v n="$nftset_name" -v t="$NFTABLE_NAME" ' + { + gsub(/^[ \t\r]+|[ \t\r]+$/, ""); + } + $0 != "" { + if (first == 0) { + printf "add element %s %s { \n", t, n; + first = 1; + } else { + printf ",\n"; + } + printf "%s%s", $0, s; + } + END { + if (first == 1) printf "\n }\n"; + } + ' + } | nft -f - + fi +} + +gen_nftset() { + local nftset_name="${1}"; shift + local ip_type="${1}"; shift + # 0 - don't set defalut timeout + local timeout_argument_set="${1}"; shift + # 0 - don't let element timeout(365 days) when set's timeout parameters be seted + # -1 - follow the set's timeout parameters + local timeout_argument_element="${1}"; shift + local gc_interval_time="1h" + + if ! nft list set $NFTABLE_NAME $nftset_name >/dev/null 2>&1; then + if [ "$timeout_argument_set" == "0" ]; then + nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; auto-merge; }" + else + nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; timeout $timeout_argument_set; gc-interval $gc_interval_time; auto-merge; }" + fi + fi + [ $# -gt 0 ] || [ ! -t 0 ] && insert_nftset "$nftset_name" "$timeout_argument_element" "$@" +} + +gen_shunt_list() { + local node=${1} + local shunt_list4_var_name=${2} + local shunt_list6_var_name=${3} + [ -z "$node" ] && continue + unset ${shunt_list4_var_name} + unset ${shunt_list6_var_name} + local _SHUNT_LIST4 _SHUNT_LIST6 + local USE_SHUNT_NODE=0 + NODE_PROTOCOL=$(config_n_get $node protocol) + [ "$NODE_PROTOCOL" = "_shunt" ] && USE_SHUNT_NODE=1 + [ "$USE_SHUNT_NODE" = "1" ] && { + local enable_geoview_ip=$(config_n_get $node enable_geoview_ip 0) + [ -z "$(first_type geoview)" ] && enable_geoview_ip=0 + local preloading=0 + preloading=$enable_geoview_ip + [ "${preloading}" = "1" ] && { + local default_node=$(config_n_get ${node} default_node _direct) + local default_outbound="redirect" + [ "$default_node" = "_direct" ] && default_outbound="direct" + local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') + for shunt_id in $shunt_ids; do + local shunt_node=$(config_n_get ${node} "${shunt_id}") + [ -n "$shunt_node" ] && { + local nftset_v4="psw2_${node}_${shunt_id}" + local nftset_v6="psw2_${node}_${shunt_id}6" + gen_nftset $nftset_v4 ipv4_addr 0 0 + gen_nftset $nftset_v6 ipv6_addr 0 0 + local outbound="redirect" + [ "$shunt_node" = "_direct" ] && outbound="direct" + [ "$shunt_node" = "_default" ] && outbound="${default_outbound}" + _SHUNT_LIST4="${_SHUNT_LIST4} ${nftset_v4}:${outbound}" + _SHUNT_LIST6="${_SHUNT_LIST6} ${nftset_v6}:${outbound}" + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $nftset_v4 "0" + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $nftset_v6 "0" + [ "${enable_geoview_ip}" = "1" ] && { + local _geoip_code=$(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$_geoip_code" ] && { + get_geoip $_geoip_code ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | insert_nftset $nftset_v4 "0" + get_geoip $_geoip_code ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $nftset_v6 "0" + log 1 "$(i18n "parse the traffic splitting rules[%s]-[geoip:%s] add to %s to complete." "${shunt_id}" "${_geoip_code}" "NFTSET")" + } + } + } + done + } + local direct_nftset4=$(get_cache_var "node_${node}_direct_nftset4") + [ -n "${direct_nftset4}" ] && { + gen_nftset $direct_nftset4 ipv4_addr 0 0 + _SHUNT_LIST4="${_SHUNT_LIST4} ${direct_nftset4}:direct" + } + local direct_nftset6=$(get_cache_var "node_${node}_direct_nftset6") + [ -n "${direct_nftset6}" ] && { + gen_nftset $direct_nftset6 ipv6_addr 0 0 + _SHUNT_LIST6="${_SHUNT_LIST6} ${direct_nftset6}:direct" + } + } + [ -n "${_SHUNT_LIST4}" ] && eval ${shunt_list4_var_name}=\"${_SHUNT_LIST4}\" + [ -n "${_SHUNT_LIST6}" ] && eval ${shunt_list6_var_name}=\"${_SHUNT_LIST6}\" +} + +add_shunt_t_rule() { + local shunt_args=${1} + local t_args=${2} + local t_jump_args=${3} + local t_comment=${4} + [ -n "${shunt_args}" ] && { + [ -n "${t_comment}" ] && t_comment="comment \"$t_comment\"" + for j in ${shunt_args}; do + local _set_name=$(echo ${j} | awk -F ':' '{print $1}') + local _outbound=$(echo ${j} | awk -F ':' '{print $2}') + [ -n "${_set_name}" ] && [ -n "${_outbound}" ] && { + local _t_arg="${t_jump_args}" + [ "${_outbound}" = "direct" ] && _t_arg="counter return" + ${t_args} @${_set_name} ${_t_arg} ${t_comment} + } + done + } +} + +load_acl() { + [ "$ENABLED_ACLS" == 1 ] && { + log_i18n 1 "Access Control:" + acl_app + for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do + eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-) + + tcp_no_redir_ports=${tcp_no_redir_ports:-default} + udp_no_redir_ports=${udp_no_redir_ports:-default} + tcp_proxy_mode="global" + udp_proxy_mode="global" + tcp_redir_ports=${tcp_redir_ports:-default} + udp_redir_ports=${udp_redir_ports:-default} + node=${node:-default} + [ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS + [ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS + [ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS + [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS + + [ -n "$(get_cache_var "ACL_${sid}_node")" ] && node=$(get_cache_var "ACL_${sid}_node") + [ -n "$(get_cache_var "ACL_${sid}_redir_port")" ] && redir_port=$(get_cache_var "ACL_${sid}_redir_port") + [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port") + [ -n "$node" ] && node_remark=$(config_n_get $node remarks) + + if [ -n "$(get_cache_var "ACL_${sid}_default")" ]; then + shunt_list4=${SHUNT_LIST4} + shunt_list6=${SHUNT_LIST6} + else + # Shunt rules IP list (import when use shunt node) + gen_shunt_list "${node}" shunt_list4 shunt_list6 + fi + + _acl_list=${TMP_ACL_PATH}/${sid}/source_list + + for i in $(cat $_acl_list); do + local _ipt_source _ipv4 + local msg + if [ -n "${interface}" ]; then + local gateway device + network_get_gateway gateway "${interface}" + network_get_device device "${interface}" + # network_get_device returns empty for non-UP interfaces (e.g. auto='0'). + # Try ubus directly, then check if the name is a kernel device. + [ -z "${device}" ] && device=$(ubus call "network.interface.${interface}" status 2>/dev/null | jsonfilter -e '@.device' 2>/dev/null) + [ -z "${device}" ] && [ -d "/sys/class/net/${interface}" ] && device="${interface}" + [ -z "${device}" ] && device="${interface}" + _ipt_source="iifname ${device} " + msg=$(i18n "Source iface [%s]," "${device}") + else + msg=$(i18n "Source iface [%s]," $(i18n "All")) + fi + if [ -n "$(echo ${i} | grep '^iprange:')" ]; then + _iprange=$(echo ${i} | sed 's#iprange:##g') + _ipt_source=$(factor ${_iprange} "${_ipt_source}ip saddr") + msg="${msg}$(i18n "IP range [%s]," "${_iprange}")" + _ipv4="1" + unset _iprange + elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then + _ipset=$(echo ${i} | sed 's#ipset:##g') + _ipt_source="${_ipt_source}ip daddr @${_ipset}" + msg="${msg}Nftset$(i18n "[%s]," "${_ipset}")" + unset _ipset + elif [ -n "$(echo ${i} | grep '^ip:')" ]; then + _ip=$(echo ${i} | sed 's#ip:##g') + _ipt_source=$(factor ${_ip} "${_ipt_source}ip saddr") + msg="${msg}IP$(i18n "[%s]," "${_ip}")" + _ipv4="1" + unset _ip + elif [ -n "$(echo ${i} | grep '^mac:')" ]; then + _mac=$(echo ${i} | sed 's#mac:##g') + _ipt_source=$(factor ${_mac} "${_ipt_source}ether saddr") + msg="${msg}MAC$(i18n "[%s]," "${_mac}")" + unset _mac + elif [ -n "$(echo ${i} | grep '^any')" ]; then + msg="${msg}$(i18n "All device,")" + else + continue + fi + msg="$(i18n "[%s]," "${remarks}")${msg}" + + [ "$tcp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$tcp_no_redir_ports"; then + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ${_ipt_source} ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ${_ipt_source} meta l4proto tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\"" + log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${tcp_no_redir_ports}")" + else + # It will return when it ends, so no extra rules are needed. + tcp_proxy_mode="disable" + log 2 "${msg}$(i18n "not proxy all %s" "TCP")" + fi + } + + [ "$udp_no_redir_ports" != "disable" ] && { + if ! has_1_65535 "$udp_no_redir_ports"; then + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" 2>/dev/null + log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${udp_no_redir_ports}")" + else + # It will return when it ends, so no extra rules are needed. + udp_proxy_mode="disable" + log 2 "${msg}$(i18n "not proxy all %s" "UDP")" + fi + } + + if ([ "$tcp_proxy_mode" != "disable" ] || [ "$udp_proxy_mode" != "disable" ]) && [ -n "$dns_redirect_port" ]; then + [ -n "$dns_redirect_port" ] && { + nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" + [ -z "$(get_cache_var "ACL_${sid}_default")" ] && log 2 "${msg}$(i18n "Using a node that is different from the global configuration, DNS has been forcibly redirected to a dedicated DNS server.")" + } + else + nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + fi + + [ "$tcp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { + msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "${node_remark}")" + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${redir_port})" + nft_chain="PSW2_MANGLE" + nft_j="counter jump PSW2_RULE" + else + msg2="${msg2}(REDIRECT:${redir_port})" + nft_chain="PSW2_NAT" + nft_j="$(REDIRECT $redir_port)" + fi + + [ "$accept_icmp" = "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr @$NFTSET_PROXY_LAN $(REDIRECT) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT) comment \"$remarks\"" + add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} ip daddr" "$(REDIRECT)" "$remarks" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} $(REDIRECT) comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ${_ipt_source} return comment \"$remarks\"" + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$NFTSET_PROXY_LAN6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null + add_shunt_t_rule "${shunt_list6}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr" "$(REDIRECT)" "$remarks" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} $(REDIRECT) comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} return comment \"$remarks\"" 2>/dev/null + } + + nft "insert rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} ip daddr @$NFTSET_PROXY_LAN ${nft_j} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP ${nft_j} comment \"$remarks\"" + add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip daddr" "${nft_j}" "$remarks" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ${nft_j} comment \"$remarks\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr @$NFTSET_PROXY_LAN6 counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" + add_shunt_t_rule "${shunt_list6}" "nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr" "counter jump PSW2_RULE" "$remarks" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") counter jump PSW2_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null + } + log 2 "${msg2}" + } + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp ${_ipt_source} counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null + + [ "$udp_proxy_mode" != "disable" ] && [ -n "$redir_port" ] && { + msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "${node_remark}")(TPROXY:${redir_port})" + + nft "insert rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr @$NFTSET_PROXY_LAN counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\"" + add_shunt_t_rule "${shunt_list4}" "nft add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip daddr" "counter jump PSW2_RULE" "$remarks" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" + + [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr @$NFTSET_PROXY_LAN6 counter jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" + add_shunt_t_rule "${shunt_list6}" "nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr" "counter jump PSW2_RULE" "$remarks" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null + } + log 2 "${msg2}" + } + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} counter return comment \"$remarks\"" + [ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null + unset nft_chain nft_j _ipt_source msg msg2 _ipv4 + done + unset enabled sid remarks sources tcp_proxy_mode udp_proxy_mode tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface + unset redir_port node_remark _acl_list + done + } + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && { + local comment="$(i18n "Default")" + msg="$(i18n "[%s]," ${comment})" + + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"${comment}\"" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + log 2 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")" + else + TCP_PROXY_MODE="disable" + log 2 "${msg}$(i18n "not proxy all %s" "TCP")" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"${comment}\"" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + log 2 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")" + else + UDP_PROXY_MODE="disable" + log 2 "${msg}$(i18n "not proxy all %s" "UDP")" + fi + } + + if ([ "$TCP_PROXY_MODE" != "disable" ] || [ "$UDP_PROXY_MODE" != "disable" ]) && [ -n "$NODE" ]; then + [ -n "$DNS_REDIRECT_PORT" ] && { + nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_DNS ip protocol tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_DNS meta l4proto tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"${comment}\"" + } + fi + + if [ "$TCP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then + msg2="${msg}$(i18n "Use the %s node [%s]" "TCP" "$(config_n_get $NODE remarks)")" + if [ -n "${is_tproxy}" ]; then + msg2="${msg2}(TPROXY:${REDIR_PORT})" + nft_chain="PSW2_MANGLE" + nft_j="counter jump PSW2_RULE" + else + msg2="${msg2}(REDIRECT:${REDIR_PORT})" + nft_chain="PSW2_NAT" + nft_j="$(REDIRECT $REDIR_PORT)" + fi + + [ "$accept_icmp" = "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr @$NFTSET_PROXY_LAN $(REDIRECT) comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr $FAKE_IP $(REDIRECT) comment \"${comment}\"" + add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr" "$(REDIRECT)" "${comment}" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp $(REDIRECT) comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp return comment \"${comment}\"" + } + + [ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr @$NFTSET_PROXY_LAN6 $(REDIRECT) comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"${comment}\"" + add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr" "$(REDIRECT)" "${comment}" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 $(REDIRECT) comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 return comment \"${comment}\"" + } + + nft "insert rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr @$NFTSET_PROXY_LAN ${nft_j} comment \"${comment}\"" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j} comment \"${comment}\"" + add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr" "${nft_j}" "${comment}" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j} comment \"${comment}\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment}\"" + + [ "$PROXY_IPV6" == "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_PROXY_LAN6 jump PSW2_RULE comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"${comment}\"" + add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr" "${nft_j}" "${comment}" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW2_RULE comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(REDIRECT $REDIR_PORT TPROXY) comment \"${comment}\"" + } + + log 2 "${msg2}" + fi + + if [ "$UDP_PROXY_MODE" != "disable" ] && [ -n "$NODE" ]; then + msg2="${msg}$(i18n "Use the %s node [%s]" "UDP" "$(config_n_get $NODE remarks)")(TPROXY:${REDIR_PORT})" + + nft "insert rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr @$NFTSET_PROXY_LAN counter jump PSW2_RULE comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"${comment}\"" + add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr" "counter jump PSW2_RULE" "${comment}" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment}\"" + + [ "$PROXY_IPV6" == "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_PROXY_LAN6 jump PSW2_RULE comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"${comment}\"" + add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr" "counter jump PSW2_RULE" "${comment}" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE comment \"${comment}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(REDIRECT $REDIR_PORT TPROXY) comment \"${comment}\"" + } + + log 2 "${msg2}" + udp_flag=1 + fi + } +} + +filter_haproxy() { + for item in $(uci show $CONFIG | grep ".lbss=" | cut -d "'" -f 2); do + get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1 + done | insert_nftset $NFTSET_VPS "-1" + log_i18n 1 "Add node to the load balancer is directly connected to %s[%s]." "nftset" "${NFTSET_VPS}" +} + +filter_vps_addr() { + for server_host in "$@"; do + get_host_ip "ipv4" ${server_host} + done | insert_nftset $NFTSET_VPS "-1" + + for server_host in "$@"; do + get_host_ip "ipv6" ${server_host} + done | insert_nftset $NFTSET_VPS6 "-1" +} + +filter_vpsip() { + uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | insert_nftset $NFTSET_VPS "-1" + #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv4" "nftset" "${$NFTSET_VPS}")" + uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | insert_nftset $NFTSET_VPS6 "-1" + #log 1 "$(i18n "Add all %s nodes to %s[%s] direct connection complete." "IPv6" "nftset" "${$NFTSET_VPS6}")" +} + +filter_server_port() { + local address=${1} + local port=${2} + local stream=${3} + stream=$(echo ${3} | tr 'A-Z' 'a-z') + local _is_tproxy + _is_tproxy=${is_tproxy} + [ "$stream" == "udp" ] && _is_tproxy="TPROXY" + + for _ipt in 4 6; do + [ "$_ipt" == "4" ] && _ip_type=ip + [ "$_ipt" == "6" ] && _ip_type=ip6 + nft "list chain $NFTABLE_NAME $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}" + if [ $? -ne 0 ]; then + nft "insert rule $NFTABLE_NAME $nft_output_chain meta l4proto $stream $_ip_type daddr $address $stream dport $port return comment \"${address}:${port}\"" 2>/dev/null + fi + done +} + +filter_node() { + local node=${1} + local stream=${2} + if [ -n "$node" ]; then + local address=$(config_n_get $node address) + local port=$(config_n_get $node port) + [ -z "$address" ] && [ -z "$port" ] && { + return 1 + } + filter_server_port $address $port $stream + filter_server_port $address $port $stream + fi +} + +filter_direct_node_list() { + [ ! -s "$TMP_PATH/direct_node_list" ] && return + for _node_id in $(cat $TMP_PATH/direct_node_list | awk '!seen[$0]++'); do + filter_node "$_node_id" TCP + filter_node "$_node_id" UDP + unset _node_id + done +} + +del_script_mwan3() { + [ -s "/etc/init.d/mwan3" ] && sed -i "/${CONFIG}/d" /etc/init.d/mwan3 >/dev/null 2>&1 +} + +add_script_mwan3() { + del_script_mwan3 + [ -s "/etc/init.d/mwan3" ] && { + sed -i '/start_service()/,/}/ s/^}/ \/usr\/share\/passwall2\/nftables.sh mwan3_start\n}/' /etc/init.d/mwan3 + sed -i '/stop_service().*{/a \ \/usr\/share\/passwall2\/nftables.sh mwan3_stop' /etc/init.d/mwan3 + } +} + +mwan3_stop() { + local handles=$(nft -a list chain ip mangle mwan3_hook 2>/dev/null | grep "${FWMARK}" | awk -F '# handle ' '{print$2}') + for handle in $handles; do + nft delete rule ip mangle mwan3_hook handle ${handle} 2>/dev/null + done +} + +mwan3_start() { + mwan3_stop + nft list chain ip mangle mwan3_hook >/dev/null 2>&1 && nft insert rule ip mangle mwan3_hook ct mark ${FWMARK} counter return >/dev/null 2>&1 +} + +update_wan_sets() { + [ -z "$(command -v get_wan_ips)" ] && . "$UTILS_PATH" + + local WAN_IP=$(get_wan_ips ip4) + [ -n "$WAN_IP" ] && { + nft flush set $NFTABLE_NAME $NFTSET_WAN + echo "$WAN_IP" | insert_nftset $NFTSET_WAN "-1" + } + + local WAN6_IP=$(get_wan_ips ip6) + [ -n "${WAN6_IP}" ] && { + nft flush set $NFTABLE_NAME $NFTSET_WAN6 + echo "$WAN6_IP" | insert_nftset $NFTSET_WAN6 "-1" + } +} + +add_firewall_rule() { + log_i18n 0 "Starting to load %s firewall rules..." "nftables" + gen_nft_tables + add_script_mwan3 + mwan3_start + + gen_nftset $NFTSET_LOCAL ipv4_addr 0 "-1" + gen_nftset $NFTSET_PROXY_LAN ipv4_addr 0 "-1" + gen_nftset $NFTSET_LAN ipv4_addr 0 "-1" $(gen_lanlist) + gen_nftset $NFTSET_VPS ipv4_addr 0 "-1" + gen_nftset $NFTSET_WAN ipv4_addr 0 "-1" + + gen_nftset $NFTSET_LOCAL6 ipv6_addr 0 "-1" + gen_nftset $NFTSET_PROXY_LAN6 ipv6_addr 0 "-1" + gen_nftset $NFTSET_LAN6 ipv6_addr 0 "-1" $(gen_lanlist_6) + gen_nftset $NFTSET_VPS6 ipv6_addr 0 "-1" + gen_nftset $NFTSET_WAN6 ipv6_addr 0 "-1" + + get_local_ips ip4 | insert_nftset $NFTSET_LOCAL "-1" + get_local_ips ip6 | insert_nftset $NFTSET_LOCAL6 "-1" + + # Ignore special IP ranges + local lan_ifname lan_ip + lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname) + [ -n "$lan_ifname" ] && { + lan_ip=$(ip address show $lan_ifname | grep -w "inet" | awk '{print $2}') + lan_ip6=$(ip address show $lan_ifname | grep -w "inet6" | awk '{print $2}') + #log_i18n 1 "local network segments (%s) direct connection: %s" "IPv4" "${lan_ip}" + #log_i18n 1 "local network segments (%s) direct connection: %s" "IPv6" "${lan_ip6}" + + [ -n "$lan_ip" ] && echo $lan_ip | insert_nftset $NFTSET_LAN "-1" + [ -n "$lan_ip6" ] && echo $lan_ip6 | insert_nftset $NFTSET_LAN6 "-1" + } + + update_wan_sets + + [ -n "$ISP_DNS" ] && { + echo "$ISP_DNS" | insert_nftset $NFTSET_LAN 0 + for ispip in $ISP_DNS; do + log_i18n 1 "$(i18n "Add ISP %s DNS to the whitelist: %s" "IPv4" "${ispip}")" + done + } + + [ -n "$ISP_DNS6" ] && { + echo $ISP_DNS6 | insert_nftset $NFTSET_LAN6 0 + for ispip6 in $ISP_DNS6; do + log_i18n 1 "$(i18n "Add ISP %s DNS to the whitelist: %s" "IPv6" "${ispip6}")" + done + } + + # Force proxy LAN IP CIDR + force_proxy_lan_ip=$(config_t_get global_forwarding force_proxy_lan_ip) + for ip in $force_proxy_lan_ip; do + if [[ "$ip" == *::* ]]; then + echo "$ip" | insert_nftset $NFTSET_PROXY_LAN6 0 + else + echo "$ip" | insert_nftset $NFTSET_PROXY_LAN 0 + fi + done + + # Shunt rules IP list (import when use shunt node) + gen_shunt_list "${NODE}" SHUNT_LIST4 SHUNT_LIST6 + + # Filter all node IPs + filter_vpsip > /dev/null 2>&1 & + filter_haproxy > /dev/null 2>&1 & + # Prevent some conditions + filter_vps_addr $(config_n_get $NODE address) > /dev/null 2>&1 & + filter_vps_addr $(config_n_get $NODE download_address) > /dev/null 2>&1 & + + accept_icmp=$(config_t_get global_forwarding accept_icmp 0) + accept_icmpv6=$(config_t_get global_forwarding accept_icmpv6 0) + + if [ "${TCP_PROXY_WAY}" = "redirect" ]; then + unset is_tproxy + nft_prerouting_chain="PSW2_NAT" + nft_output_chain="PSW2_OUTPUT_NAT" + elif [ "${TCP_PROXY_WAY}" = "tproxy" ]; then + is_tproxy="TPROXY" + nft_prerouting_chain="PSW2_MANGLE" + nft_output_chain="PSW2_OUTPUT_MANGLE" + fi + + nft "add chain $NFTABLE_NAME PSW2_DIVERT" + nft "flush chain $NFTABLE_NAME PSW2_DIVERT" + # Only TCP, UDP Invalid. + nft "add rule $NFTABLE_NAME PSW2_DIVERT meta l4proto tcp socket transparent 1 mark set ${FWMARK} counter accept" + + nft "add chain $NFTABLE_NAME PSW2_DNS" + nft "flush chain $NFTABLE_NAME PSW2_DNS" + if [ $(config_t_get global dns_redirect "1") = "0" ]; then + #Only hijack when dest address is local IP + nft "insert rule $NFTABLE_NAME dstnat ip saddr @${NFTSET_LAN} ip daddr @${NFTSET_LOCAL} jump PSW2_DNS" + nft "insert rule $NFTABLE_NAME dstnat ip6 saddr @${NFTSET_LAN6} ip6 daddr @${NFTSET_LOCAL6} jump PSW2_DNS" + else + nft "insert rule $NFTABLE_NAME dstnat ip saddr @${NFTSET_LAN} jump PSW2_DNS" + nft "insert rule $NFTABLE_NAME dstnat ip6 saddr @${NFTSET_LAN6} jump PSW2_DNS" + fi + + # for ipv4 ipv6 tproxy mark + nft "add chain $NFTABLE_NAME PSW2_RULE" + nft "flush chain $NFTABLE_NAME PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_RULE counter meta mark set ct mark" + nft "add rule $NFTABLE_NAME PSW2_RULE meta mark ${FWMARK} counter return" + nft "add rule $NFTABLE_NAME PSW2_RULE tcp flags & (fin|syn|rst|ack) == syn counter meta mark set ${FWMARK}" + nft "add rule $NFTABLE_NAME PSW2_RULE meta l4proto udp ct state { new, related } counter meta mark set ${FWMARK}" + nft "add rule $NFTABLE_NAME PSW2_RULE counter ct mark set mark" + + #ipv4 tproxy mode and udp + nft "add chain $NFTABLE_NAME PSW2_MANGLE" + nft "flush chain $NFTABLE_NAME PSW2_MANGLE" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ct direction reply counter return" + + nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" + nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ct direction reply counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE meta mark 255 counter return" + + # jump chains + nft "add rule $NFTABLE_NAME mangle_prerouting counter jump PSW2_DIVERT" + nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW2_MANGLE" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW2_MANGLE" + + #ipv4 tcp redirect mode + [ -z "${is_tproxy}" ] && { + nft "add chain $NFTABLE_NAME PSW2_NAT" + nft "flush chain $NFTABLE_NAME PSW2_NAT" + nft "add rule $NFTABLE_NAME PSW2_NAT ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW2_NAT ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME dstnat ip protocol tcp counter jump PSW2_NAT" + + nft "add chain $NFTABLE_NAME PSW2_OUTPUT_NAT" + nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_NAT" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip daddr @$NFTSET_VPS counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT meta mark 255 counter return" + } + + #icmp ipv6-icmp redirect + if [ "$accept_icmp" = "1" ]; then + nft "add chain $NFTABLE_NAME PSW2_ICMP_REDIRECT" + nft "flush chain $NFTABLE_NAME PSW2_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip daddr @$NFTSET_LAN counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip daddr @$NFTSET_VPS counter return" + + [ "$accept_icmpv6" = "1" ] && { + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip6 daddr @$NFTSET_LAN6 counter return" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip6 daddr @$NFTSET_VPS6 counter return" + } + + nft "add rule $NFTABLE_NAME dstnat meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" + nft "add rule $NFTABLE_NAME nat_output meta l4proto {icmp,icmpv6} counter jump PSW2_ICMP_REDIRECT" + fi + + #ipv4 wan_ip + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip daddr @$NFTSET_WAN counter return comment \"WAN_IP_RETURN\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip daddr @$NFTSET_WAN counter return comment \"WAN_IP_RETURN\"" + + ip rule add fwmark ${FWMARK} table 999 priority 999 + ip route add local 0.0.0.0/0 dev lo table 999 + + #ipv6 tproxy mode and udp + nft "add chain $NFTABLE_NAME PSW2_MANGLE_V6" + nft "flush chain $NFTABLE_NAME PSW2_MANGLE_V6" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ct direction reply counter return" + + nft "add chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" + nft "flush chain $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ct direction reply counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta mark 255 counter return" + + [ -n "$AUTO_DNS" ] && { + for auto_dns in $(echo $AUTO_DNS | tr ',' ' '); do + local dns_address=$(echo $auto_dns | awk -F '#' '{print $1}') + local dns_port=$(echo $auto_dns | awk -F '#' '{print $2}') + if [[ "$dns_address" == *::* ]]; then + nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" + log_i18n 1 "$(i18n "Add direct DNS to %s: %s" "nftables" "[${dns_address}]:${dns_port:-53}")" + else + nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr ${dns_address} $(factor ${dns_port:-53} "udp dport") counter return" + log_i18n 1 "$(i18n "Add direct DNS to %s: %s" "nftables" "${dns_address}:${dns_port:-53}")" + fi + done + } + + # jump chains + [ "$PROXY_IPV6" == "1" ] && { + nft "add rule $NFTABLE_NAME mangle_prerouting meta nfproto {ipv6} counter jump PSW2_MANGLE_V6" + nft "add rule $NFTABLE_NAME mangle_output meta nfproto {ipv6} counter jump PSW2_OUTPUT_MANGLE_V6 comment \"PSW2_OUTPUT_MANGLE\"" + + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ip6 daddr @$NFTSET_WAN6 counter return comment \"WAN6_IP_RETURN\"" + + ip -6 rule add fwmark ${FWMARK} table 999 priority 999 + ip -6 route add local ::/0 dev lo table 999 + } + + [ "$ENABLED_DEFAULT_ACL" == 1 ] && { + TCP_LOCALHOST_PROXY=$LOCALHOST_PROXY + UDP_LOCALHOST_PROXY=$LOCALHOST_PROXY + + msg="$(i18n "[Local],")" + [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return" + if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then + log 1 "${msg}$(i18n "not proxy %s port [%s]" "TCP" "${TCP_NO_REDIR_PORTS}")" + else + unset TCP_LOCALHOST_PROXY + log 1 "${msg}$(i18n "not proxy all %s" "TCP")" + fi + } + + [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return" + if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then + log 1 "${msg}$(i18n "not proxy %s port [%s]" "UDP" "${UDP_NO_REDIR_PORTS}")" + else + unset UDP_LOCALHOST_PROXY + log 1 "${msg}$(i18n "not proxy all %s" "UDP")" + fi + } + + if [ -n "$NODE" ] && ([ "$TCP_LOCALHOST_PROXY" = "1" ] || [ "$UDP_LOCALHOST_PROXY" = "1" ]); then + [ -n "$DNS_REDIRECT_PORT" ] && { + nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\"" + nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\"" + nft "add rule $NFTABLE_NAME nat_output meta l4proto udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\"" + nft "add rule $NFTABLE_NAME nat_output meta l4proto tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW2_DNS\"" + } + fi + + local comment_l="$(i18n "Local")" + + # Loading local router proxy TCP + if [ -n "$NODE" ] && [ "$TCP_LOCALHOST_PROXY" = "1" ]; then + [ "$accept_icmp" = "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr @$NFTSET_PROXY_LAN counter redirect" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP counter redirect" + add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp ip daddr" "counter redirect" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter redirect" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo ip protocol icmp counter return" + } + + [ "$accept_icmpv6" = "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr @$NFTSET_PROXY_LAN6 counter redirect" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 counter redirect" + add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 ip6 daddr" "counter redirect" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter redirect" + nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter return" + } + + if [ -n "${is_tproxy}" ]; then + nft_chain="PSW2_OUTPUT_MANGLE" + nft_j="counter jump PSW2_RULE" + else + nft_chain="PSW2_OUTPUT_NAT" + nft_j="$(REDIRECT $REDIR_PORT)" + fi + + nft "insert rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr @$NFTSET_PROXY_LAN ${nft_j}" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j}" + add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip daddr" "${nft_j}" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}" + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME nat_output ip protocol tcp counter jump PSW2_OUTPUT_NAT" + [ -n "${is_tproxy}" ] && { + nft "insert rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo ip daddr @$NFTSET_PROXY_LAN $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo counter return comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME mangle_output ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" + } + + [ "$PROXY_IPV6" == "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_PROXY_LAN6 jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" + add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr" "counter jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW2_RULE" + nft "insert rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo ip6 daddr @$NFTSET_PROXY_LAN6 $(REDIRECT $REDIR_PORT TPROXY6) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $REDIR_PORT TPROXY6) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"${comment_l}\"" + } + + [ -d "${TMP_IFACE_PATH}" ] && { + for iface in $(ls ${TMP_IFACE_PATH}); do + nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp oif $iface counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol tcp oif $iface counter return" + done + } + fi + + # Loading local router proxy UDP + if [ -n "$NODE" ] && [ "$UDP_LOCALHOST_PROXY" = "1" ]; then + nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr @$NFTSET_PROXY_LAN counter jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE" + add_shunt_t_rule "${SHUNT_LIST4}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") ip daddr" "counter jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE" + nft "insert rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo ip daddr @$NFTSET_PROXY_LAN $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo counter return comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME mangle_output ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" + + [ "$PROXY_IPV6" == "1" ] && { + nft "insert rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_PROXY_LAN6 jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" + add_shunt_t_rule "${SHUNT_LIST6}" "nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr" "counter jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE" + nft "insert rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo ip6 daddr @$NFTSET_PROXY_LAN6 $(REDIRECT $REDIR_PORT TPROXY6) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $REDIR_PORT TPROXY6) comment \"${comment_l}\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo counter return comment \"${comment_l}\"" + } + + [ -d "${TMP_IFACE_PATH}" ] && { + for iface in $(ls ${TMP_IFACE_PATH}); do + nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol udp oif $iface counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 ip protocol udp oif $iface counter return" + done + } + fi + + nft "add rule $NFTABLE_NAME mangle_output oif lo counter return comment \"PSW2_OUTPUT_MANGLE\"" + nft "add rule $NFTABLE_NAME mangle_output meta mark ${FWMARK} counter return comment \"PSW2_OUTPUT_MANGLE\"" + + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp udp dport 53 counter return" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp udp dport 53 counter return" + } + + load_acl + + filter_direct_node_list > /dev/null 2>&1 & + + log_i18n 0 "%s firewall rules load complete!" "nftables" +} + +del_firewall_rule() { + for nft in "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do + local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW2_" | awk -F '# handle ' '{print$2}') + for handle in $handles; do + nft delete rule $NFTABLE_NAME ${nft} handle ${handle} 2>/dev/null + done + done + + for handle in $(nft -a list chains | grep -E "chain PSW2_" | grep -v "PSW2_RULE" | awk -F '# handle ' '{print$2}'); do + nft delete chain $NFTABLE_NAME handle ${handle} 2>/dev/null + done + + # Need to be removed at the end, otherwise it will show "Resource busy" + nft delete chain $NFTABLE_NAME handle $(nft -a list chains | grep -E "PSW2_RULE" | awk -F '# handle ' '{print$2}') 2>/dev/null + + ip rule del fwmark ${FWMARK} 2>/dev/null + ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null + + ip -6 rule del fwmark ${FWMARK} 2>/dev/null + ip -6 route del local ::/0 dev lo table 999 2>/dev/null + + destroy_nftset $NFTSET_LOCAL + destroy_nftset $NFTSET_WAN + destroy_nftset $NFTSET_LAN + destroy_nftset $NFTSET_VPS + + destroy_nftset $NFTSET_LOCAL6 + destroy_nftset $NFTSET_WAN6 + destroy_nftset $NFTSET_LAN6 + destroy_nftset $NFTSET_VPS6 + + del_script_mwan3 + + log_i18n 0 "Delete %s rules is complete." "nftables" +} + +flush_nftset() { + log_i18n 0 "Clear %s." "NFTSet" + for _name in $(nft -a list sets | grep -E "psw2_" | awk -F 'set ' '{print $2}' | awk '{print $1}'); do + destroy_nftset ${_name} + done +} + +flush_table() { + nft flush table $NFTABLE_NAME + nft delete table $NFTABLE_NAME +} + +flush_include() { + echo '#!/bin/sh' >$FWI +} + +gen_include() { + flush_include + local nft_chain_file=$TMP_PATH/PSW2_RULE.nft + echo '#!/bin/sh' > $nft_chain_file + nft list table $NFTABLE_NAME >> $nft_chain_file + + local __nft=" " + __nft=$(cat <<- EOF + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW2)" ] && nft -f ${nft_chain_file} + + ${MY_PATH} update_wan_sets + EOF + ) + + cat <<-EOF >> $FWI + ${__nft} + + return 0 + EOF + return 0 +} + +start() { + [ "$ENABLED_DEFAULT_ACL" == 0 -a "$ENABLED_ACLS" == 0 ] && return + add_firewall_rule + gen_include +} + +stop() { + [ -z "$(command -v log_i18n)" ] && . "$UTILS_PATH" + del_firewall_rule + destroy_nftset $NFTSET_PROXY_LAN + destroy_nftset $NFTSET_PROXY_LAN6 + [ $(config_t_get global flush_set "0") = "1" ] && { + uci -q delete ${CONFIG}.@global[0].flush_set + uci -q commit ${CONFIG} + #flush_table + flush_nftset + rm -rf $TMP_PATH2/singbox* + rm -rf $TMP_PATH2/geo_output + } + flush_include +} + +arg1=$1 +shift +case $arg1 in +insert_nftset) + insert_nftset "$@" + ;; +filter_direct_node_list) + filter_direct_node_list + ;; +mwan3_start) + mwan3_start + ;; +mwan3_stop) + mwan3_stop + ;; +update_wan_sets) + update_wan_sets "$@" + ;; +stop) + stop + ;; +start) + start + ;; +*) ;; +esac diff --git a/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua b/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua new file mode 100755 index 00000000..18cb53bb --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua @@ -0,0 +1,253 @@ +#!/usr/bin/lua + +local api = require "luci.passwall2.api" +local name = api.appname +local fs = api.fs +local log = api.log +local sys = api.sys +local uci = api.uci +local jsonc = api.jsonc + +local arg1 = arg[1] +local arg2 = arg[2] +local arg3 = arg[3] + +local reboot = 0 +local geoip_update = "0" +local geosite_update = "0" + +local geoip_url = uci:get(name, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat" +local geosite_url = uci:get(name, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" +local asset_location = uci:get(name, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/" +asset_location = asset_location:match("/$") and asset_location or (asset_location .. "/") +local backup_path = "/tmp/bak_v2ray/" + +if arg3 == "cron" then + arg2 = nil +end + +-- curl +local function curl(url, file) + local http_code = 0 + local header_str = "" + local args = { + "-skL", + "--retry 3", + "--connect-timeout 3", + "--max-time 300", + "--speed-limit 51200 --speed-time 15", + '-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"', + "--dump-header -", + "-w '\\n%{http_code}'" + } + if file then + args[#args + 1] = "-o " .. file + end + local return_code, result = api.curl_auto(url, nil, args) + if result and result ~= "" then + local body, code = result:match("^(.-)%s*([0-9]+)$") + if code then + http_code = tonumber(code) or 0 + header_str = body + else + http_code = tonumber(result:match("(%d+)%s*$")) or 0 + end + end + if header_str ~= "" then + header_str = header_str:gsub("\r", "") + end + return http_code, header_str +end + +local function non_file_check(file_path, header_content) + local remote_file_size = nil + local local_file_size = tonumber(fs.stat(file_path, "size") or 0) + if local_file_size == 0 then + log(2, api.i18n.translate("Downloaded file is empty or an error occurred while reading it.")) + return true + end + if header_content and header_content ~= "" then + for size in header_content:gmatch("[Cc]ontent%-[Ll]ength:%s*(%d+)") do + local s = tonumber(size) + if s and s > 0 then + remote_file_size = s + end + end + end + if remote_file_size and remote_file_size ~= local_file_size then + log(2, api.i18n.translatef("Download file size verification error. Original file size: %sB. Downloaded file size: %sB.", remote_file_size, local_file_size)) + return true + end + return false +end + +local function fetch_geofile(geo_name, geo_type, url) + local tmp_path = "/tmp/" .. geo_name + local asset_path = asset_location .. geo_name + local down_filename = url:match("^.*/([^/?#]+)") + local sha_url = url:gsub(down_filename, down_filename .. ".sha256sum") + local sha_path = tmp_path .. ".sha256sum" + + local function verify_sha256(sha_file) + return sys.call("sha256sum -c " .. sha_file .. " > /dev/null 2>&1") == 0 + end + + local sha_verify, _ = curl(sha_url, sha_path) == 200 + if sha_verify then + local f = io.open(sha_path, "r") + if f then + local content = f:read("*l") + f:close() + if content then + content = content:gsub("(%x+)%s+.+", "%1 " .. tmp_path) + f = io.open(sha_path, "w") + if f then + f:write(content) + f:close() + end + end + end + if fs.access(asset_path) then + sys.call(string.format("cp -f %s %s", asset_path, tmp_path)) + if verify_sha256(sha_path) then + log(1, api.i18n.translatef("%s version is the same and does not need to be updated.", geo_type)) + return 0 + end + end + end + + local sret_tmp, header = curl(url, tmp_path) + if sret_tmp == 200 and non_file_check(tmp_path, header) then + log(1, api.i18n.translatef("%s an error occurred during the file download process. Please try downloading again.", geo_type)) + os.remove(tmp_path) + sret_tmp, header = curl(url, tmp_path) + if sret_tmp == 200 and non_file_check(tmp_path, header) then + sret_tmp = 0 + log(1, api.i18n.translatef("%s an error occurred while downloading the file. Please check your network or the download link and try again!", geo_type)) + end + end + if sret_tmp == 200 then + if sha_verify then + if verify_sha256(sha_path) then + sys.call(string.format("mkdir -p %s && mv -f %s %s", backup_path, asset_path, backup_path)) + sys.call(string.format("mkdir -p %s && mv -f %s %s", asset_location, tmp_path, asset_path)) + reboot = 1 + log(1, api.i18n.translatef("%s update success.", geo_type)) + else + log(1, api.i18n.translatef("%s update failed, please try again later.", geo_type)) + return 1 + end + else + if fs.access(asset_path) and sys.call(string.format("cmp -s %s %s", tmp_path, asset_path)) == 0 then + log(1, api.i18n.translatef("%s version is the same and does not need to be updated.", geo_type)) + return 0 + end + sys.call(string.format("mkdir -p %s && mv -f %s %s", backup_path, asset_path, backup_path)) + sys.call(string.format("mkdir -p %s && mv -f %s %s", asset_location, tmp_path, asset_path)) + reboot = 1 + log(1, api.i18n.translatef("%s update success.", geo_type)) + end + else + log(1, api.i18n.translatef("%s update failed, please try again later.", geo_type)) + return 1 + end + return 0 +end + +local function fetch_geoip() + fetch_geofile("geoip.dat", "geoip", geoip_url) +end + +local function fetch_geosite() + fetch_geofile("geosite.dat", "geosite", geosite_url) +end + +local function remove_tmp_geofile(name) + os.remove("/tmp/" .. name .. ".dat") + os.remove("/tmp/" .. name .. ".dat.sha256sum") +end + +if arg2 then + string.gsub(arg2, '[^' .. "," .. ']+', function(w) + if w == "geoip" then + geoip_update = "1" + end + if w == "geosite" then + geosite_update = "1" + end + end) +else + geoip_update = uci:get(name, "@global_rules[0]", "geoip_update") or "1" + geosite_update = uci:get(name, "@global_rules[0]", "geosite_update") or "1" +end +if geoip_update == "0" and geosite_update == "0" then + os.exit(0) +end + +local function check_instance(action) + local rule_lock = "/var/lock/" .. name .. "_rule_update.lock" + local sub_lock = "/var/lock/" .. name .. "_subscribe.lock" + + if action == "start" then + math.randomseed(os.time() + math.floor(os.clock() * 1000)) + api.nixio.nanosleep(0, math.random(100, 1000) * 1000000) + if fs.access(rule_lock) then + log(0, api.i18n.translatef("[Rule update] instance is running; please try again later.") .. "\n") + os.exit(0) + else + luci.sys.call("touch " .. rule_lock) + end + elseif action == "end" then + luci.sys.call("rm -f " .. rule_lock) + return + end + + if fs.access(sub_lock) then + log(0, api.i18n.translatef("[Subscription] instance is running; [Rule Update] queue and wait.") .. "\n") + end + while fs.access(sub_lock) do + api.nixio.nanosleep(2, 0) + end +end + +check_instance("start") + +log(0, api.i18n.translate("Start updating the rules...")) +local function safe_call(func, err_msg) + xpcall(func, function(e) + log(1, e) + log(1, debug.traceback()) + log(1, err_msg) + end) +end + +if geoip_update == "1" then + log(1, api.i18n.translatef("%s Start updating...", "geoip")) + safe_call(fetch_geoip, api.i18n.translatef("%s update error!", "geoip")) + remove_tmp_geofile("geoip") +end + +if geosite_update == "1" then + log(1, api.i18n.translatef("%s Start updating...", "geosite")) + safe_call(fetch_geosite, api.i18n.translatef("%s update error!", "geosite")) + remove_tmp_geofile("geosite") +end + +uci:set(name, "@global_rules[0]", "geoip_update", geoip_update) +uci:set(name, "@global_rules[0]", "geosite_update", geosite_update) +api.uci_save(uci, name, true) + +if reboot == 1 then + if arg3 == "cron" then + if not fs.access("/var/lock/" .. name .. ".lock") then + sys.call("touch /tmp/lock/" .. name .. "_cron.lock") + end + end + + log(1, api.i18n.translate("Restart the service and apply the new rules.")) + uci:set(name, "@global[0]", "flush_set", "1") + api.uci_save(uci, name, true, true) +end +log(0, api.i18n.translate("The rules have been updated...")) + +check_instance("end") diff --git a/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh b/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh new file mode 100755 index 00000000..310a2070 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/socks_auto_switch.sh @@ -0,0 +1,192 @@ +#!/bin/sh + +. /usr/share/passwall2/utils.sh +APP_FILE=${APP_PATH}/app.sh + +flag=0 + +check_process() { + while busybox pgrep -af "${CONFIG}/" | grep -E 'app\.sh.*(start|stop)|nftables\.sh|iptables\.sh|subscribe\.lua' >/dev/null; do + sleep 6s + done +} + +test_url() { + local url=$1 + local try=1 + [ -n "$2" ] && try=$2 + local timeout=2 + [ -n "$3" ] && timeout=$3 + local extra_params=$4 + if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then + extra_params="--retry-all-errors ${extra_params}" + fi + local status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") + case "$status" in + 204) + status=200 + ;; + esac + echo $status +} + +test_proxy() { + local result=0 + local status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}") + if [ "$status" = "200" ]; then + result=0 + else + local status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout}) + if [ "$status2" = "200" ]; then + result=1 + else + result=2 + ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 + [ $? -eq 0 ] && { + result=1 + } + fi + fi + echo $result +} + +test_node() { + local node_id=$1 + local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') + [ -n "${_type}" ] && { + check_process + local _tmp_port=$(get_new_port 48800 tcp,udp) + NO_REC_PROCESS=1 $APP_FILE run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json + sleep 2s + local curlx="socks5h://127.0.0.1:${_tmp_port}" + local _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx") + # Kill the SS plugin process + local pid_file="/tmp/etc/${CONFIG}/test_node_${node_id}_plugin.pid" + [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 + busybox pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -rf /tmp/etc/${CONFIG}/test_node_${node_id}*.* + if [ "${_proxy_status}" -eq 200 ]; then + return 0 + fi + } + return 1 +} + +test_auto_switch() { + flag=$((flag + 1)) + local b_nodes=$1 + local now_node=$2 + [ -z "$now_node" ] && { + if [ -n "$(get_cache_var "socks_${id}")" ]; then + now_node=$(get_cache_var "socks_${id}") + else + #log_i18n 0 "Socks switch detection: Unknown error." + return 1 + fi + } + + [ $flag -le 1 ] && { + main_node=$now_node + } + + local status=$(test_proxy) + if [ "$status" = "2" ]; then + log_i18n 0 "Socks switch detection: Unable to connect to the network. Please check if the network is working properly!" + return 2 + fi + + # Check if the main node is usable + if [ "$restore_switch" = "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then + test_node ${main_node} + [ $? -eq 0 ] && { + check_process + # The main node is working properly; switch to the main node. + log_i18n 0 "Socks switch detection: Primary node ã€%s: [%s]】 is normal. Switch to the primary node!" "${id}" "$(config_n_get $main_node type)" "$(config_n_get $main_node remarks)" + $APP_FILE socks_node_switch flag=${id} new_node=${main_node} + [ $? -eq 0 ] && { + log_i18n 0 "Socks switch detection: %s node switch complete!" "${id}" + } + return 0 + } + fi + + if [ "$status" = "0" ]; then + #log_i18n 0 "Socks switch detection: %s ã€%s:[%s]】 normal." "${id}" "$(config_n_get $now_node type)" "$(config_n_get $now_node remarks)" + return 0 + elif [ "$status" = "1" ]; then + local new_node msg + if [ "$backup_node_num" -gt 1 ]; then + # When there are multiple backup nodes + local first_node found node + for node in $b_nodes; do + [ -z "$first_node" ] && first_node="$node" # Record the first node. + [ "$found" = "1" ] && { new_node="$node"; break; } # Find the current node and then retrieve the next one. + [ "$node" = "$now_node" ] && found=1 # Mark the current node found. + done + # If the current node is not found, or if the current node is the last node, then take the first node. + [ -z "$new_node" ] && new_node="$first_node" + local msg2="$(i18n "next backup node")" + [ "$now_node" = "$main_node" ] && msg2="$(i18n "backup node")" + msg="$(i18n "switch to %s test detect!" "${msg2}")" + else + # When there is only one backup node, poll with the primary node. + new_node=$([ "$now_node" = "$main_node" ] && echo "$b_nodes" || echo "$main_node") + local msg2="$(i18n "main node")" + [ "$now_node" = "$main_node" ] && msg2="$(i18n "backup node")" + msg="$(i18n "switch to %s test detect!" "${msg2}")" + fi + log_i18n 0 "Socks switch detection: %s ã€%s:[%s]】 abnormal, %s" "${id}" "$(config_n_get $now_node type)" "$(config_n_get $now_node remarks)" "${msg}" + test_node ${new_node} + if [ $? -eq 0 ]; then +# [ "$restore_switch" = "0" ] && { +# uci set $CONFIG.${id}.node=$new_node +# [ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node +# uci commit $CONFIG +# } + check_process + log_i18n 0 "Socks switch detection: %s ã€%s:[%s]】 normal, switch to this node!" "${id}" "$(config_n_get $new_node type)" "$(config_n_get $new_node remarks)" + $APP_FILE socks_node_switch flag=${id} new_node=${new_node} + [ $? -eq 0 ] && { + log_i18n 0 "Socks switch detection: %s node switch complete!" "${id}" + } + return 0 + else + test_auto_switch "${b_nodes}" ${new_node} + fi + fi +} + +start() { + id=$1 + LOCK_FILE=${LOCK_PATH}/${CONFIG}_socks_auto_switch_${id}.lock + main_node=$(config_n_get $id node) + socks_port=$(config_n_get $id port 0) + delay=$(config_n_get $id autoswitch_testing_time 30) + connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3) + retry_num=$(config_n_get $id autoswitch_retry_num 1) + restore_switch=$(config_n_get $id autoswitch_restore_switch 0) + probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204") + backup_node=$(config_n_get $id autoswitch_backup_node) + if [ -n "$backup_node" ]; then + backup_node=$(echo "$backup_node" | tr -s ' ' '\n' | uniq | tr -s '\n' ' ') + backup_node_num=$(printf "%s\n" "$backup_node" | wc -w) + if [ "$backup_node_num" -eq 1 ]; then + [ "$main_node" = "$backup_node" ] && return + fi + else + return + fi + while [ -n "$backup_node" ]; do + [ -f "$LOCK_FILE" ] && { + sleep 6s + continue + } + check_process + touch $LOCK_FILE + test_auto_switch "$backup_node" + rm -f $LOCK_FILE + sleep ${delay} + done +} + +start $@ diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua new file mode 100755 index 00000000..35104922 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -0,0 +1,2525 @@ +#!/usr/bin/lua + +------------------------------------------------ +-- @author William Chan +------------------------------------------------ +require 'luci.util' +require 'luci.jsonc' +require 'luci.sys' +local appname = 'passwall2' +local api = require ("luci.passwall2.api") +local datatypes = require "luci.cbi.datatypes" + +-- these global functions are accessed all the time by the event handler +-- so caching them is worth the effort +local tinsert = table.insert +local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub +local split = api.split +local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify +local base64Decode = api.base64Decode +local UrlEncode = api.UrlEncode +local UrlDecode = api.UrlDecode +local uci = api.uci +local fs = api.fs +local log = api.log +local i18n = api.i18n +local lyaml = require "lyaml" + +local has_ss_rust = api.is_finded("sslocal") +local has_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir") +local has_singbox = api.finded_com("sing-box") +local has_xray = api.finded_com("xray") +local has_hysteria2 = api.finded_com("hysteria") +local DEFAULT_ALLOWINSECURE = true +local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0" +local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {} +local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {} +-- Nodes should be retrieved using the core type (if not set on the node subscription page, the default type will be used automatically). +local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}}) +local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}}) +local DEFAULT_VMESS_TYPE = api.get_core("vmess_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local DEFAULT_VLESS_TYPE = api.get_core("vless_type", {{has_xray,"xray"},{has_singbox,"sing-box"}}) +local DEFAULT_HYSTERIA2_TYPE = api.get_core("hysteria2_type", {{has_hysteria2,"hysteria2"},{has_singbox,"sing-box"},{has_xray,"xray"}}) +local core_has = { + ["xray"] = has_xray, + ["sing-box"] = has_singbox, + ["shadowsocks-rust"] = has_ss_rust, + ["hysteria2"] = has_hysteria2 +} +-- Determine whether to filter node keywords +local function is_filter_keyword(sub_cfg, value) + local mode = DEFAULT_FILTER_KEYWORD_MODE + local discard_list = DEFAULT_FILTER_KEYWORD_DISCARD_LIST + local keep_list = DEFAULT_FILTER_KEYWORD_KEEP_LIST + if sub_cfg then + local filter_keyword_mode = sub_cfg.filter_keyword_mode or "5" -- 5 is global + if filter_keyword_mode == "0" then + mode = "0" + elseif filter_keyword_mode == "1" then + mode = "1" + discard_list = sub_cfg.filter_discard_list or {} + elseif filter_keyword_mode == "2" then + mode = "2" + keep_list = sub_cfg.filter_keep_list or {} + elseif filter_keyword_mode == "3" then + mode = "3" + keep_list = sub_cfg.filter_keep_list or {} + discard_list = sub_cfg.filter_discard_list or {} + elseif filter_keyword_mode == "4" then + mode = "4" + keep_list = sub_cfg.filter_keep_list or {} + discard_list = sub_cfg.filter_discard_list or {} + end + end + if mode == "1" then + for k,v in ipairs(discard_list) do + if value:find(v, 1, true) then + return true + end + end + elseif mode == "2" then + local result = true + for k,v in ipairs(keep_list) do + if value:find(v, 1, true) then + result = false + end + end + return result + elseif mode == "3" then + local result = false + for k,v in ipairs(discard_list) do + if value:find(v, 1, true) then + result = true + end + end + for k,v in ipairs(keep_list) do + if value:find(v, 1, true) then + result = false + end + end + return result + elseif mode == "4" then + local result = true + for k,v in ipairs(keep_list) do + if value:find(v, 1, true) then + result = false + end + end + for k,v in ipairs(discard_list) do + if value:find(v, 1, true) then + result = true + end + end + return result + end + return false +end + +local nodeResult = {} -- update result +local nodes_table = {} +for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" then + nodes_table[#nodes_table + 1] = e + end +end + +-- To retrieve the current server's dynamic configurations, you can use `get` and `set`. `get` requires access to the node table. +local CONFIG = {} +do + if true then + local szType = "@global[0]" + local option = "node" + + local node_id = uci:get(appname, szType, option) + CONFIG[#CONFIG + 1] = { + log = true, + remarks = i18n.translatef("Node"), + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + uci:set(appname, szType, option, server) + o.newNodeId = server + end + } + end + + if true then + local i = 0 + local option = "node" + uci:foreach(appname, "socks", function(t) + i = i + 1 + local id = t[".name"] + local node_id = t[option] + CONFIG[#CONFIG + 1] = { + log = true, + id = id, + remarks = i18n.translatef("Socks node list [%s]", i), + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + if not server or server == "" then + if #nodes_table > 0 then + server = nodes_table[1][".name"] + end + end + uci:set(appname, t[".name"], option, server) + o.newNodeId = server + end + } + if t.autoswitch_backup_node and #t.autoswitch_backup_node > 0 then + local flag = i18n.translatef("Socks node list [%s]", i) .. " " .. i18n.translatef("Backup node list") + local currentNodes = {} + local newNodes = {} + for k, node_id in ipairs(t.autoswitch_backup_node) do + if node_id then + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode then + currentNodes[#currentNodes + 1] = { + log = true, + remarks = flag .. "[" .. k .. "]", + currentNode = currentNode, + set = function(o, server) + if server and server ~= "nil" then + table.insert(o.newNodes, server) + end + end + } + end + end + end + CONFIG[#CONFIG + 1] = { + remarks = flag, + currentNodes = currentNodes, + newNodes = newNodes, + set = function(o, newNodes) + if o then + if not newNodes then newNodes = o.newNodes end + uci:set_list(appname, id, "autoswitch_backup_node", newNodes or {}) + end + end + } + end + end) + end + + if true then + local i = 0 + local option = "lbss" + local function is_ip_port(str) + if type(str) ~= "string" then return false end + local ip, port = str:match("^([%d%.]+):(%d+)$") + return ip and datatypes.ipaddr(ip) and tonumber(port) and tonumber(port) <= 65535 + end + uci:foreach(appname, "haproxy_config", function(t) + i = i + 1 + local node_id = t[option] + CONFIG[#CONFIG + 1] = { + log = true, + id = t[".name"], + remarks = i18n.translatef("HAProxy node list [%s]", i), + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + -- Modify the LBS value only if it is not in IP:Port format. + if not is_ip_port(t[option]) then + uci:set(appname, t[".name"], option, server) + o.newNodeId = server + end + end, + delete = function(o) + -- Deletion is only performed if the current LBS value is not in IP:port format. + if not is_ip_port(t[option]) then + uci:delete(appname, t[".name"]) + end + end + } + end) + end + + if true then + local i = 0 + uci:foreach(appname, "acl_rule", function(t) + i = i + 1 + local option = "node" + local node_id = t[option] + CONFIG[#CONFIG + 1] = { + log = true, + id = t[".name"], + remarks = i18n.translatef("ACL list [%s]", i), + currentNode = node_id and uci:get_all(appname, node_id) or nil, + set = function(o, server) + uci:set(appname, t[".name"], option, server) + o.newNodeId = server + end + } + end) + end + + uci:foreach(appname, "nodes", function(node) + local node_id = node[".name"] + if node.protocol and node.protocol == '_shunt' then + local rules = {} + uci:foreach(appname, "shunt_rules", function(e) + if e[".name"] and e.remarks then + table.insert(rules, e) + table.insert(rules, { + [".name"] = e[".name"] .. "_proxy_tag", + remarks = e.remarks .. " " .. i18n.translate("Preproxy") + }) + end + end) + table.insert(rules, { + [".name"] = "default_node", + remarks = i18n.translatef("Default") + }) + table.insert(rules, { + [".name"] = "default_proxy_tag", + remarks = i18n.translatef("Default") .. " " .. i18n.translate("Preproxy") + }) + + for k, e in pairs(rules) do + local _node_id = node[e[".name"]] or nil + if _node_id and not _node_id:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = false, + currentNode = _node_id and uci:get_all(appname, _node_id) or nil, + remarks = i18n.translatef("Shunt [%s] node", e.remarks), + set = function(o, server) + if not server then server = "" end + uci:set(appname, node_id, e[".name"], server) + o.newNodeId = server + end + } + end + + end + elseif node.protocol and node.protocol == '_balancing' then + local flag = i18n.translatef("Xray Load Balancing node [%s] list", node_id) + local currentNodes = {} + local newNodes = {} + if node.balancing_node then + for k, node in pairs(node.balancing_node) do + currentNodes[#currentNodes + 1] = { + log = true, + node = node, + currentNode = (function() + if node and node:find("Socks_") then + return { Socks = node } + end + return node and uci:get_all(appname, node) or nil + end)(), + remarks = node, + set = function(o, server) + if o and server and server ~= "nil" then + table.insert(o.newNodes, server) + end + end + } + end + end + CONFIG[#CONFIG + 1] = { + remarks = flag, + currentNodes = currentNodes, + newNodes = newNodes, + set = function(o, newNodes) + if o then + if not newNodes then newNodes = o.newNodes end + uci:set_list(appname, node_id, "balancing_node", newNodes or {}) + end + end + } + + -- Backup Node + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode and currentNode.fallback_node and not currentNode.fallback_node:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = true, + id = node_id, + remarks = i18n.translatef("Xray Load Balancing node [%s] backup node", node_id), + currentNode = uci:get_all(appname, currentNode.fallback_node) or nil, + set = function(o, server) + uci:set(appname, node_id, "fallback_node", server) + o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, node_id, "fallback_node") + end + } + end + elseif node.protocol and node.protocol == '_urltest' then + local flag = i18n.translatef("Sing-Box URLTest node [%s] list", node_id) + local currentNodes = {} + local newNodes = {} + if node.urltest_node then + for k, node in pairs(node.urltest_node) do + currentNodes[#currentNodes + 1] = { + log = true, + node = node, + currentNode = (function() + if node and node:find("Socks_") then + return { Socks = node } + end + return node and uci:get_all(appname, node) or nil + end)(), + remarks = node, + set = function(o, server) + if o and server and server ~= "nil" then + table.insert(o.newNodes, server) + end + end + } + end + end + CONFIG[#CONFIG + 1] = { + remarks = flag, + currentNodes = currentNodes, + newNodes = newNodes, + set = function(o, newNodes) + if o then + if not newNodes then newNodes = o.newNodes end + uci:set_list(appname, node_id, "urltest_node", newNodes or {}) + end + end + } + else + -- Preproxy Node + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode and currentNode.preproxy_node and not currentNode.preproxy_node:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = true, + id = node_id, + remarks = i18n.translatef("Node [%s] preproxy node", node_id), + currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil, + set = function(o, server) + uci:set(appname, node_id, "preproxy_node", server) + o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, node_id, "preproxy_node") + end + } + end + -- Landing node + local currentNode = uci:get_all(appname, node_id) or nil + if currentNode and currentNode.to_node and not currentNode.to_node:find("Socks_") then + CONFIG[#CONFIG + 1] = { + log = true, + id = node_id, + remarks = i18n.translatef("Node [%s] landing node", node_id), + currentNode = uci:get_all(appname, currentNode.to_node) or nil, + set = function(o, server) + uci:set(appname, node_id, "to_node", server) + o.newNodeId = server + end, + delete = function(o) + uci:delete(appname, node_id, "to_node") + end + } + end + end + end) + + for k, v in pairs(CONFIG) do + if v.currentNodes and type(v.currentNodes) == "table" then + for kk, vv in pairs(v.currentNodes) do + if vv.currentNode == nil then + CONFIG[k].currentNodes[kk] = nil + end + end + else + if v.currentNode == nil then + if v.delete then + v.delete() + end + CONFIG[k] = nil + end + end + end +end + +-- Retrieve subscribe information (remaining data allowance, expiration time). +local subscribe_info = {} +local function get_subscribe_info(cfgid, value) + if type(cfgid) ~= "string" or cfgid == "" or type(value) ~= "string" then + return + end + value = value:gsub("%s+", "") + local date_patterns = {"套é¤åˆ°æœŸï¼š(.+)", "过期时间:(.+)", "有效期至:(.+)", "到期时间:(.+)", "截止日期:(.+)"} + local expired_date + for _, p in ipairs(date_patterns) do expired_date = value:match(p) or expired_date end + local rem_patterns = {"剩余æµé‡ï¼š(.+)", "æµé‡å‰©ä½™ï¼š(.+)", "å¯ç”¨æµé‡ï¼š(.+)", "套é¤å‰©ä½™ï¼š(.+)"} + local rem_traffic + for _, p in ipairs(rem_patterns) do rem_traffic = value:match(p) or rem_traffic end + subscribe_info[cfgid] = subscribe_info[cfgid] or {expired_date = "", rem_traffic = ""} + if expired_date then + subscribe_info[cfgid]["expired_date"] = expired_date + end + if rem_traffic then + subscribe_info[cfgid]["rem_traffic"] = rem_traffic + end +end + +-- Configure the SS protocol implementation type +local function set_ss_implementation(ss_type, result) + if ss_type == "shadowsocks-rust" and has_ss_rust then + result.type = 'SS-Rust' + elseif ss_type == "xray" and has_xray then + result.type = 'Xray' + result.protocol = 'shadowsocks' + result.transport = 'raw' + elseif ss_type == "sing-box" and has_singbox then + result.type = 'sing-box' + result.protocol = 'shadowsocks' + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "SS", "SS")) + return nil + end + return result +end + +local function parseClashNode(node, add_mode, group, sub_cfg) + local sub_allowinsecure = DEFAULT_ALLOWINSECURE + local sub_ss_type = DEFAULT_SS_TYPE + local sub_trojan_type = DEFAULT_TROJAN_TYPE + local sub_vmess_type = DEFAULT_VMESS_TYPE + local sub_vless_type = DEFAULT_VLESS_TYPE + local sub_hysteria2_type = DEFAULT_HYSTERIA2_TYPE + local sub_hy_up_mbps, sub_hy_down_mbps = 1000, 1000 + if sub_cfg then + if sub_cfg.allowInsecure and sub_cfg.allowInsecure ~= "1" then + sub_allowinsecure = nil + end + local ss_type = sub_cfg.ss_type or "global" + if ss_type ~= "global" and core_has[ss_type] then + sub_ss_type = ss_type + end + local trojan_type = sub_cfg.trojan_type or "global" + if trojan_type ~= "global" and core_has[trojan_type] then + sub_trojan_type = trojan_type + end + local vmess_type = sub_cfg.vmess_type or "global" + if vmess_type ~= "global" and core_has[vmess_type] then + sub_vmess_type = vmess_type + end + local vless_type = sub_cfg.vless_type or "global" + if vless_type ~= "global" and core_has[vless_type] then + sub_vless_type = vless_type + end + local hysteria2_type = sub_cfg.hysteria2_type or "global" + if hysteria2_type ~= "global" and core_has[hysteria2_type] then + sub_hysteria2_type = hysteria2_type + end + sub_hy_up_mbps = sub_cfg.hysteria_up_mbps + sub_hy_down_mbps = sub_cfg.hysteria_down_mbps + end + local result = { + timeout = 60, + add_mode = add_mode, -- `0` for manual configuration, `1` for import, `2` for subscription + group = group + } + result.remarks = node.name + result.address = node.server + result.port = node.port + + if node.type == 'ss' then + result = set_ss_implementation(sub_ss_type, result) + if not result then return nil end + result.method = node.cipher + result.password = node.password + if node.plugin == "obfs" then + result.plugin = "obfs-local" + elseif node.plugin == "v2ray-plugin" then + result.plugin = "v2ray-plugin" + end + if node["plugin-opts"] then + if node.plugin == "obfs" then + local plugin_opts = "" + local opts_mode = node["plugin-opts"].mode + if opts_mode then + plugin_opts = plugin_opts .. "obfs=" .. opts_mode .. ";" + end + local opts_host = node["plugin-opts"].host + if opts_host then + plugin_opts = plugin_opts .. "obfs-host=" .. opts_host + end + result.plugin_opts = plugin_opts + elseif node.plugin == "v2ray-plugin" then + local plugin_opts = "" + local opts_mode = node["plugin-opts"].mode + local opts_tls = node["plugin-opts"].tls + if opts_tls then + plugin_opts = plugin_opts .. "tls;" + end + local opts_skip_cert_verify = node["plugin-opts"]["skip-cert-verify"] + local opts_host = node["plugin-opts"].host + if opts_host then + plugin_opts = plugin_opts .. "host=" .. opts_host .. ";" + end + local opts_path = node["plugin-opts"].path + local opts_mux = node["plugin-opts"].mux + if node["plugin-opts"].headers then + --todo + end + result.plugin_opts = plugin_opts + end + end + elseif node.type == 'ssr' then + if not has_ssr then + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "SSR", "shadowsocksr-libev")) + return nil + end + result.type = "SSR" + result.method = node.cipher + result.password = node.password + result.obfs = node.obfs + result.protocol = node.protocol + result.obfs_param = node["obfs-param"] + result.protocol_param = node["protocol-param"] + elseif node.type == 'vmess' then + if sub_vmess_type == "sing-box" and has_singbox then + result.type = 'sing-box' + elseif sub_vmess_type == "xray" and has_xray then + result.type = "Xray" + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "VMess", "VMess")) + return nil + end + result.protocol = 'vmess' + result.uuid = node.uuid + result.alter_id = node.alterId + result.security = node.cipher or "auto" + result.tcp_fast_open = node.tfo + result.tls = "0" + if node.tls then + result.tls = "1" + result.tls_serverName = node.servername or "" + local insecure = node["skip-cert-verify"] + result.tls_allowInsecure = insecure and "1" or "0" + if sub_allowinsecure then + result.tls_allowInsecure = "1" + end + end + result.transport = node.network and string.lower(node.network) or "tcp" + if result.type == "sing-box" and result.transport == "raw" then + result.transport = "tcp" + elseif result.type == "Xray" and result.transport == "tcp" then + result.transport = "raw" + end + if result.transport == 'ws' then + local ws_opts = node["ws-opts"] + if ws_opts then + if ws_opts.headers then + result.ws_host = ws_opts.headers.Host or ws_opts.headers.host + end + if ws_opts.path then + result.ws_path = ws_opts.path + if ws_opts["max-early-data"] then + if result.type == "sing-box" then + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_opts["max-early-data"]) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + elseif result.type == "Xray" then + result.ws_path = result.ws_path .. "?ed=" .. ws_opts["max-early-data"] + end + end + end + end + elseif result.transport == 'h2' then + local h2_opts = node["h2-opts"] + if h2_opts then + if result.type == "sing-box" then + result.http_path = h2_opts.path + result.http_host = h2_opts.host + elseif result.type == "Xray" then + result.xhttp_mode = "stream-one" + result.xhttp_path = h2_opts.path + result.xhttp_host = h2_opts.host + end + end + elseif result.transport == 'grpc' then + local grpc_opts = node["grpc-opts"] + if grpc_opts then + result.grpc_serviceName = grpc_opts["grpc-service-name"] + end + end + elseif node.type == 'vless' then + if sub_vless_type == "sing-box" and has_singbox then + result.type = 'sing-box' + elseif sub_vless_type == "xray" and has_xray then + result.type = "Xray" + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "VLESS", "VLESS")) + return nil + end + result.protocol = "vless" + result.uuid = node.uuid + result.tcp_fast_open = node.tfo + result.encryption = node.cipher or "none" + result.flow = node.flow + result.tls = "0" + if node.tls then + result.tls = "1" + result.tls_serverName = node.servername or "" + local insecure = node["skip-cert-verify"] + result.tls_allowInsecure = insecure and "1" or "0" + if sub_allowinsecure then + result.tls_allowInsecure = "1" + end + end + if node.tls and node["reality-opts"] and node["reality-opts"]["public-key"] then + result.reality = "1" + result.reality_publicKey = (node["reality-opts"] and node["reality-opts"]["public-key"]) or nil + result.reality_shortId = (node["reality-opts"] and node["reality-opts"]["short-id"]) or nil + end + result.transport = node.network and string.lower(node.network) or "tcp" + if result.type == "sing-box" and result.transport == "raw" then + result.transport = "tcp" + elseif result.type == "Xray" and result.transport == "tcp" then + result.transport = "raw" + end + if result.transport == 'ws' then + local ws_opts = node["ws-opts"] + if ws_opts then + if ws_opts.headers then + result.ws_host = ws_opts.headers.Host or ws_opts.headers.host + end + if ws_opts.path then + result.ws_path = ws_opts.path + if ws_opts["max-early-data"] then + if result.type == "sing-box" then + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_opts["max-early-data"]) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + elseif result.type == "Xray" then + result.ws_path = result.ws_path .. "?ed=" .. ws_opts["max-early-data"] + end + end + end + end + end + elseif node.type == 'trojan' then + if sub_trojan_type == "sing-box" and has_singbox then + result.type = 'sing-box' + result.protocol = 'trojan' + elseif sub_trojan_type == "xray" and has_xray then + result.type = 'Xray' + result.protocol = 'trojan' + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "Trojan", "Trojan")) + return nil + end + result.password = node.password + result.tls = '1' + result.tls_serverName = node.sni or "" + local insecure = node["skip-cert-verify"] + result.tls_allowInsecure = insecure and "1" or "0" + if sub_allowinsecure then + result.tls_allowInsecure = "1" + end + if node.alpn then + --todo + end + if node.network == "grpc" then + if node["grpc-opts"] then + result.grpc_serviceName = node["grpc-opts"]["grpc-service-name"] + end + elseif node.network == "ws" then + local ws_opts = node["ws-opts"] + if ws_opts then + result.ws_path = ws_opts.path + if ws_opts.headers then + result.ws_host = ws_opts.headers.Host or ws_opts.headers.host + end + end + end + elseif node.type == 'anytls' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "anytls" + else + log(2, i18n.translatef("Skip the %s node because the %s core program is not installed.", "AnyTLS", "AnyTLS", "Sing-Box 1.12")) + return nil + end + result.password = node.password + result.tls = '1' + result.tls_serverName = node.sni or "" + local insecure = node["skip-cert-verify"] + result.tls_allowInsecure = insecure and "1" or "0" + if sub_allowinsecure then + result.tls_allowInsecure = "1" + end + end + if not result.remarks or result.remarks == "" then + if result.address and result.port then + result.remarks = result.address .. ':' .. result.port + else + result.remarks = "NULL" + end + end + return result +end + +-- Processing Clash data +local function processClashData(content, add_mode, group, sub_cfg) + local results = {} + for i, node in ipairs(content.proxies or {}) do + local result = parseClashNode(node, add_mode, group, sub_cfg) + if result then + table.insert(results, result) + end + end + return results +end + +-- Processing data +local function processData(szType, content, add_mode, group, sub_cfg) + --log(2, content, add_mode, group) + local sub_allowinsecure = DEFAULT_ALLOWINSECURE + local sub_ss_type = DEFAULT_SS_TYPE + local sub_trojan_type = DEFAULT_TROJAN_TYPE + local sub_vmess_type = DEFAULT_VMESS_TYPE + local sub_vless_type = DEFAULT_VLESS_TYPE + local sub_hysteria2_type = DEFAULT_HYSTERIA2_TYPE + local sub_hy_up_mbps, sub_hy_down_mbps = 1000, 1000 + if sub_cfg then + if sub_cfg.allowInsecure and sub_cfg.allowInsecure ~= "1" then + sub_allowinsecure = nil + end + local ss_type = sub_cfg.ss_type or "global" + if ss_type ~= "global" and core_has[ss_type] then + sub_ss_type = ss_type + end + local trojan_type = sub_cfg.trojan_type or "global" + if trojan_type ~= "global" and core_has[trojan_type] then + sub_trojan_type = trojan_type + end + local vmess_type = sub_cfg.vmess_type or "global" + if vmess_type ~= "global" and core_has[vmess_type] then + sub_vmess_type = vmess_type + end + local vless_type = sub_cfg.vless_type or "global" + if vless_type ~= "global" and core_has[vless_type] then + sub_vless_type = vless_type + end + local hysteria2_type = sub_cfg.hysteria2_type or "global" + if hysteria2_type ~= "global" and core_has[hysteria2_type] then + sub_hysteria2_type = hysteria2_type + end + sub_hy_up_mbps = sub_cfg.hysteria_up_mbps + sub_hy_down_mbps = sub_cfg.hysteria_down_mbps + end + local result = { + timeout = 60, + add_mode = add_mode, -- `0` for manual configuration, `1` for import, `2` for subscription + group = group + } + --ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0) + if szType == 'ssr' then + if not has_ssr then + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "SSR", "shadowsocksr-libev")) + return nil + end + result.type = "SSR" + + local dat = split(content:gsub("/%?", "?"), "%?") + local hostInfo = split(dat[1], ':') + if dat[1]:match('%[(.*)%]') then + result.address = dat[1]:match('%[(.*)%]') + else + result.address = hostInfo[#hostInfo-5] + end + result.port = hostInfo[#hostInfo-4] + result.protocol = hostInfo[#hostInfo-3] + result.method = hostInfo[#hostInfo-2] + result.obfs = hostInfo[#hostInfo-1] + result.password = base64Decode(hostInfo[#hostInfo]) + local params = {} + for _, v in pairs(split(dat[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = v:sub(s + 1) + end + end + result.obfs_param = base64Decode(params.obfsparam) + result.protocol_param = base64Decode(params.protoparam) + -- local ssr_group = base64Decode(params.group) + -- if ssr_group then result.ssr_group = ssr_group end + result.remarks = base64Decode(params.remarks) + elseif szType == 'vmess' then + local info = jsonParse(content) + if sub_vmess_type == "sing-box" and has_singbox then + result.type = 'sing-box' + elseif sub_vmess_type == "xray" and has_xray then + result.type = "Xray" + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "VMess", "VMess")) + return nil + end + result.address = info.add + result.port = info.port + result.protocol = 'vmess' + result.alter_id = info.aid + result.uuid = info.id + result.remarks = info.ps + -- result.mux = 1 + -- result.mux_concurrency = 8 + + info.path = (info.path and info.path ~= "") and UrlDecode(info.path) or nil + + if not info.net then info.net = "tcp" end + info.net = string.lower(info.net) + if result.type == "sing-box" and info.net == "raw" then + info.net = "tcp" + elseif result.type == "Xray" and info.net == "tcp" then + info.net = "raw" + end + if info.net == 'h2' or info.net == 'http' then + info.net = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = info.net + end + if info.net == 'ws' then + result.ws_host = info.host + result.ws_path = info.path + if result.type == "sing-box" and info.path then + local ws_path_dat = split(info.path, "?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if info.net == "http" then + if result.type == "Xray" then + result.xhttp_mode = "stream-one" + result.xhttp_host = info.host + result.xhttp_path = info.path + else + result.http_host = (info.host and info.host ~= "") and { info.host } or nil + result.http_path = info.path + end + end + if info.net == 'raw' or info.net == 'tcp' then + if info.type and info.type ~= "http" then + info.type = "none" + end + result.tcp_guise = info.type + result.tcp_guise_http_host = (info.host and info.host ~= "") and { info.host } or nil + result.tcp_guise_http_path = (info.path and info.path ~= "") and { info.path } or nil + end + if info.net == 'kcp' or info.net == 'mkcp' then + info.net = "mkcp" + result.mkcp_guise = info.type + result.mkcp_seed = info.seed + end + if info.net == 'quic' then + result.quic_guise = info.type + result.quic_key = info.key + result.quic_security = info.securty + end + if info.net == 'grpc' then + result.grpc_serviceName = info.path + end + if info.net == 'xhttp' or info.net == 'splithttp' then + result.xhttp_host = info.host + result.xhttp_path = info.path + result.xhttp_mode = params.mode or "auto" + result.xhttp_extra = params.extra + local success, Data = pcall(jsonParse, params.extra) + if success and Data then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = address and address ~= "" and address or nil + else + result.download_address = nil + end + end + if info.net == 'httpupgrade' then + result.httpupgrade_host = info.host + result.httpupgrade_path = info.path + end + result.security = info.security or info.scy or "auto" + if info.tls == "tls" or info.tls == "1" then + result.tls = "1" + result.alpn = info.alpn + if info.fp and info.fp ~= "" then + result.utls = "1" + result.fingerprint = info.fp + end + result.tls_serverName = (info.sni and info.sni ~= "") and info.sni or info.host + result.tls_pinSHA256 = info.pcs + result.tls_CertByName = info.vcn + local insecure = info.allowinsecure or info.allowInsecure or info.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + else + result.tls = "0" + end + + result.tcp_fast_open = info.tfo + + info.fm = (info.fm and info.fm ~= "") and UrlDecode(info.fm) or nil + result.use_finalmask = (info.fm and info.fm ~= "") and "1" or nil + result.finalmask = (info.fm and info.fm ~= "") and api.base64Encode(info.fm) or nil + + if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp") then + log(2, i18n.translatef("Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead.", result.remarks, szType, result.transport)) + return nil + end + elseif szType == "ss" then + result = set_ss_implementation(sub_ss_type, result) + if not result then return nil end + + --SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ] + --userinfo = websafe-base64-encode-utf8(method ":" password) + --ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1 + --ss://cmM0LW1kNTpwYXNzd2Q@192.168.100.1:8888/?plugin=obfs-local%3Bobfs%3Dhttp#Example2 + --ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888#Example3 + --ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3 + --ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp0ZXN0@xxxxxx.com:443?type=ws&path=%2Ftestpath&host=xxxxxx.com&security=tls&fp=&alpn=h3%2Ch2%2Chttp%2F1.1&sni=xxxxxx.com#test-1%40ss + + local idx_sp = content:find("#") or 0 + local alias = "" + if idx_sp > 0 then + alias = content:sub(idx_sp + 1, -1) + end + result.remarks = UrlDecode(alias) + local info = content:sub(1, idx_sp - 1):gsub("/%?", "?") + local params = {} + if info:find("%?") then + local find_index = info:find("%?") + local query = split(info, "%?") + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + if params.plugin then + local plugin_info = params.plugin + local idx_pn = plugin_info:find(";") + if idx_pn then + result.plugin = plugin_info:sub(1, idx_pn - 1) + result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info) + else + result.plugin = plugin_info + end + end + if result.plugin and result.plugin == "simple-obfs" then + result.plugin = "obfs-local" + end + info = info:sub(1, find_index - 1) + end + + local hostInfo = split(base64Decode(UrlDecode(info)), "@") + if hostInfo and #hostInfo > 0 then + local host_port = hostInfo[#hostInfo] + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + + local userinfo = nil + if #hostInfo > 2 then + userinfo = {} + for i = 1, #hostInfo - 1 do + tinsert(userinfo, hostInfo[i]) + end + userinfo = table.concat(userinfo, '@') + else + userinfo = base64Decode(hostInfo[1]) + end + local method, password + if userinfo:find(":") then + method = userinfo:sub(1, userinfo:find(":") - 1) + password = userinfo:sub(userinfo:find(":") + 1, #userinfo) + else + password = hostInfo[1] -- Some links use plaintext UUIDs as passwords. + end + + -- Determine if the password is URL encoded + local function isURLEncodedPassword(pwd) + if not pwd:find("%%[0-9A-Fa-f][0-9A-Fa-f]") then + return false + end + local ok, decoded = pcall(UrlDecode, pwd) + return ok and UrlEncode(decoded) == pwd + end + + local decoded = UrlDecode(password) + if isURLEncodedPassword(password) and decoded then + password = decoded + end + + local _method = (method or "none"):lower() + method = (_method == "chacha20-poly1305" and "chacha20-ietf-poly1305") or + (_method == "xchacha20-poly1305" and "xchacha20-ietf-poly1305") or _method + + result.method = method + result.password = password + result.tcp_fast_open = params.tfo + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + + local need_upgrade = (result.type ~= "Xray" and result.type ~= "sing-box") + and (params.type and params.type ~= "tcp") + and (params.headerType and params.headerType ~= "none") + if has_xray and (need_upgrade or params.type == "xhttp") then + result.type = "Xray" + result.protocol = "shadowsocks" + elseif has_singbox and need_upgrade then + result.type = "sing-box" + result.protocol = "shadowsocks" + end + + if result.plugin then + if result.type == 'Xray' then + -- The obfs-local plugin converts data to a format supported by xray. + if result.plugin ~= "obfs-local" then + result.error_msg = i18n.translatef("Xray unsupport %s plugin.", result.plugin) + else + local obfs = result.plugin_opts:match("obfs=([^;]+)") or "" + local obfs_host = result.plugin_opts:match("obfs%-host=([^;]+)") or "" + if obfs == "" or obfs_host == "" then + result.error_msg = "SS " .. result.plugin .. " " .. i18n.translatef("Plugin options Incomplete.") + end + if obfs == "http" then + result.transport = "raw" + result.tcp_guise = "http" + result.tcp_guise_http_host = (obfs_host and obfs_host ~= "") and { obfs_host } or nil + result.tcp_guise_http_path = { "/" } + elseif obfs == "tls" then + result.tls = "1" + result.tls_serverName = obfs_host + result.tls_allowInsecure = "1" + end + result.plugin = nil + result.plugin_opts = nil + end + else + result.plugin_enabled = "1" + end + end + + if params.type then + params.type = string.lower(params.type) + if result.type == "sing-box" and params.type == "raw" then + params.type = "tcp" + elseif result.type == "Xray" and params.type == "tcp" then + params.type = "raw" + end + if params.type == "h2" or params.type == "http" then + params.type = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = params.type + end + if result.type ~= "SS-Rust" then + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "%?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == "http" then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = (params.host and params.host ~= "") and { params.host } or nil + result.http_path = params.path + elseif result.type == "Xray" then + result.transport = "xhttp" + result.xhttp_mode = "stream-one" + result.xhttp_host = params.host + result.xhttp_path = params.path + end + end + if params.type == 'raw' or params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = (params.host and params.host ~= "") and { params.host } or nil + result.tcp_guise_http_path = (params.path and params.path ~= "") and { params.path } or nil + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + if params.path then result.grpc_serviceName = params.path end + if params.serviceName then result.grpc_serviceName = params.serviceName end + result.grpc_mode = params.mode or "gun" + end + if params.type == 'xhttp' then + if result.type ~= "Xray" then + result.error_msg = i18n.translatef("Please replace %s to support %s transmission method.", "Xray", "xhttp") + end + result.xhttp_host = params.host + result.xhttp_path = params.path + result.xhttp_mode = params.mode or "auto" + result.use_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil + result.xhttp_extra = (params.extra and params.extra ~= "") and api.base64Encode(params.extra) or nil + local success, Data = pcall(jsonParse, params.extra) + if success and Data then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") or nil + end + end + result.tls = "0" + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host + result.alpn = params.alpn + if params.fp and params.fp ~= "" then + result.utls = "1" + result.fingerprint = params.fp + end + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + result.tls_pinSHA256 = params.pcs + result.tls_CertByName = params.vcn + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + result.reality_spiderX = params.spx or nil + result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil + result.reality_mldsa65Verify = params.pqv or nil + end + end + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + result.uot = params.udp + elseif (params.type ~= "tcp" and params.type ~= "raw") and (params.headerType and params.headerType ~= "none") then + result.error_msg = i18n.translatef("Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks.") + end + end + + if params["shadow-tls"] then + if result.type ~= "sing-box" and result.type ~= "SS-Rust" then + result.error_msg = sub_ss_type .. " " .. i18n.translatef("unsupport %s plugin.", "shadow-tls") + else + -- Parsing SS Shadow-TLS plugin parameters + local function parseShadowTLSParams(b64str, out) + local ok, data = pcall(jsonParse, base64Decode(b64str)) + if not ok or type(data) ~= "table" then return "" end + if type(out) == "table" then + for k, v in pairs(data) do out[k] = v end + end + local t = {} + if data.version then t[#t+1] = "v" .. data.version .. "=1" end + if data.password then t[#t+1] = "passwd=" .. data.password end + for k, v in pairs(data) do + if k ~= "version" and k ~= "password" then + t[#t+1] = k .. "=" .. tostring(v) + end + end + return table.concat(t, ";") + end + + if result.type == "SS-Rust" then + result.plugin_enabled = "1" + result.plugin = "shadow-tls" + result.plugin_opts = parseShadowTLSParams(params["shadow-tls"]) + elseif result.type == "sing-box" then + local shadowtlsOpt = {} + parseShadowTLSParams(params["shadow-tls"], shadowtlsOpt) + if next(shadowtlsOpt) then + result.shadowtls = "1" + result.shadowtls_version = shadowtlsOpt.version or "1" + result.shadowtls_password = shadowtlsOpt.password + result.shadowtls_serverName = shadowtlsOpt.host + if shadowtlsOpt.fingerprint then + result.shadowtls_utls = "1" + result.shadowtls_fingerprint = shadowtlsOpt.fingerprint or "chrome" + end + end + end + end + end + end + elseif szType == "trojan" then + if sub_trojan_type == "sing-box" and has_singbox then + result.type = 'sing-box' + result.protocol = 'trojan' + elseif sub_trojan_type == "xray" and has_xray then + result.type = 'Xray' + result.protocol = 'trojan' + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "Trojan", "Trojan")) + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + if content:find("@") then + local Info = split(content, "@") + result.password = UrlDecode(Info[1]) + local port = "443" + Info[2] = (Info[2] or ""):gsub("/%?", "?") + local query = split(Info[2], "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + + result.port = port + + result.tls = '1' + result.tls_serverName = params.peer or params.sni or "" + result.tls_pinSHA256 = params.pcs + result.tls_CertByName = params.vcn + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + + if not params.type then params.type = "tcp" end + params.type = string.lower(params.type) + if result.type == "sing-box" and params.type == "raw" then + params.type = "tcp" + elseif result.type == "Xray" and params.type == "tcp" then + params.type = "raw" + end + if params.type == "h2" or params.type == "http" then + params.type = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = params.type + end + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "%?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == "http" then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = (params.host and params.host ~= "") and { params.host } or nil + result.http_path = params.path + elseif result.type == "Xray" then + result.transport = "xhttp" + result.xhttp_mode = "stream-one" + result.xhttp_host = params.host + result.xhttp_path = params.path + end + end + if params.type == 'raw' or params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = (params.host and params.host ~= "") and { params.host } or nil + result.tcp_guise_http_path = (params.path and params.path ~= "") and { params.path } or nil + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + result.grpc_serviceName = params.serviceName or params.path + result.grpc_mode = params.mode or "gun" + end + if params.type == 'xhttp' then + result.xhttp_host = params.host + result.xhttp_path = params.path + end + if params.type == 'httpupgrade' then + result.httpupgrade_host = params.host + result.httpupgrade_path = params.path + end + + result.alpn = params.alpn + result.tcp_fast_open = params.tfo + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + + if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp") then + log(2, i18n.translatef("Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead.", result.remarks, szType, result.transport)) + return nil + end + end + elseif szType == "ssd" then + result = set_ss_implementation(sub_ss_type, result) + if not result then return nil end + result.address = content.server + result.port = content.port + result.password = content.password + result.method = content.encryption + result.plugin = content.plugin + result.plugin_opts = content.plugin_options + result.group = content.airport + result.remarks = content.remarks + elseif szType == "vless" then + if sub_vless_type == "sing-box" and has_singbox then + result.type = 'sing-box' + elseif sub_vless_type == "xray" and has_xray then + result.type = "Xray" + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "VLESS", "VLESS")) + return nil + end + result.protocol = "vless" + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + if content:find("@") then + local Info = split(content, "@") + result.uuid = UrlDecode(Info[1]) + local port = "443" + Info[2] = (Info[2] or ""):gsub("/%?", "?") + local query = split(Info[2], "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + + if not params.type then params.type = "tcp" end + params.type = string.lower(params.type) + if ({ xhttp=true, kcp=true, mkcp=true })[params.type] and result.type ~= "Xray" and has_xray then + result.type = "Xray" + end + if result.type == "sing-box" and params.type == "raw" then + params.type = "tcp" + elseif result.type == "Xray" and params.type == "tcp" then + params.type = "raw" + end + if params.type == "h2" or params.type == "http" then + params.type = "http" + result.transport = (result.type == "Xray") and "xhttp" or "http" + else + result.transport = params.type + end + if params.type == 'ws' then + result.ws_host = params.host + result.ws_path = params.path + if result.type == "sing-box" and params.path then + local ws_path_dat = split(params.path, "%?") + local ws_path = ws_path_dat[1] + local ws_path_params = {} + for _, v in pairs(split(ws_path_dat[2], '&')) do + local t = split(v, '=') + ws_path_params[t[1]] = t[2] + end + if ws_path_params.ed and tonumber(ws_path_params.ed) then + result.ws_path = ws_path + result.ws_enableEarlyData = "1" + result.ws_maxEarlyData = tonumber(ws_path_params.ed) + result.ws_earlyDataHeaderName = "Sec-WebSocket-Protocol" + end + end + end + if params.type == "http" then + if result.type == "sing-box" then + result.transport = "http" + result.http_host = (params.host and params.host ~= "") and { params.host } or nil + result.http_path = params.path + elseif result.type == "Xray" then + result.transport = "xhttp" + result.xhttp_mode = "stream-one" + result.xhttp_host = params.host + result.xhttp_path = params.path + end + end + if params.type == 'raw' or params.type == 'tcp' then + result.tcp_guise = params.headerType or "none" + result.tcp_guise_http_host = (params.host and params.host ~= "") and { params.host } or nil + result.tcp_guise_http_path = (params.path and params.path ~= "") and { params.path } or nil + end + if params.type == 'kcp' or params.type == 'mkcp' then + result.transport = "mkcp" + result.mkcp_guise = params.headerType or "none" + result.mkcp_seed = params.seed + end + if params.type == 'quic' then + result.quic_guise = params.headerType or "none" + result.quic_key = params.key + result.quic_security = params.quicSecurity or "none" + end + if params.type == 'grpc' then + if params.path then result.grpc_serviceName = params.path end + if params.serviceName then result.grpc_serviceName = params.serviceName end + result.grpc_mode = params.mode or "gun" + end + if params.type == 'xhttp' or params.type == 'splithttp' then + result.xhttp_host = params.host + result.xhttp_path = params.path + result.xhttp_mode = params.mode or "auto" + result.use_xhttp_extra = (params.extra and params.extra ~= "") and "1" or nil + result.xhttp_extra = (params.extra and params.extra ~= "") and api.base64Encode(params.extra) or nil + local success, Data = pcall(jsonParse, params.extra) + if success and Data then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") or nil + end + end + if params.type == 'httpupgrade' then + result.httpupgrade_host = params.host + result.httpupgrade_path = params.path + end + result.encryption = params.encryption or "none" + result.flow = params.flow + + result.tls = "0" + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host + result.alpn = params.alpn + if params.fp and params.fp ~= "" then + result.utls = "1" + result.fingerprint = params.fp + end + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + result.tls_pinSHA256 = params.pcs + result.tls_CertByName = params.vcn + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + result.reality_spiderX = params.spx or nil + result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil + result.reality_mldsa65Verify = params.pqv or nil + end + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + end + + result.port = port + result.tcp_fast_open = params.tfo + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + + if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp") then + log(2, i18n.translatef("Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead.", result.remarks, szType, result.transport)) + return nil + end + end + elseif szType == 'hysteria' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "hysteria" + else + log(2, i18n.translatef("Skip the %s node because the %s core program is not installed.", "Hysteria", "Hysteria", "Sing-Box")) + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + + local query = split(content:gsub("/%?", "?"), '%?') + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = v:sub(s + 1) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.hysteria_obfs = params.obfsParam + result.hysteria_auth_type = "string" + result.hysteria_auth_password = params.auth + result.tls_serverName = params.peer or params.sni or "" + local insecure = params.allowinsecure or params.allowInsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + result.alpn = params.alpn + result.hysteria_up_mbps = params.upmbps or sub_hy_up_mbps + result.hysteria_down_mbps = params.downmbps or sub_hy_down_mbps + result.hysteria_hop = params.mport + + elseif szType == 'hysteria2' or szType == 'hy2' then + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + local Info = content + if content:find("@") then + local contents = split(content, "@") + result.hysteria2_auth_password = UrlDecode(contents[1]) + Info = (contents[2] or ""):gsub("/%?", "?") + end + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1):lower()] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls_serverName = params.sni + result.tls_pinSHA256 = params.pcs or params.pinsha256 + result.tls_CertByName = params.vcn + local insecure = params.allowinsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + result.hysteria2_up_mbps = params.upmbps or sub_hy_up_mbps + result.hysteria2_down_mbps = params.downmbps or sub_hy_down_mbps + result.hysteria2_hop = params.mport + if params["obfs-password"] or params["obfs_password"] then + result.hysteria2_obfs_type = "salamander" + result.hysteria2_obfs_password = params["obfs-password"] or params["obfs_password"] + end + + if (sub_hysteria2_type == "sing-box" and has_singbox) or (sub_hysteria2_type == "xray" and has_xray) then + local is_singbox = sub_hysteria2_type == "sing-box" and has_singbox + result.type = is_singbox and 'sing-box' or 'Xray' + result.protocol = "hysteria2" + result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil + result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil + elseif has_hysteria2 then + result.type = "Hysteria2" + else + log(2, i18n.translatef("Skipping the %s node is due to incompatibility with the %s core program or incorrect node usage type settings.", "Hysteria2", "Hysteria2")) + return nil + end + elseif szType == 'tuic' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "tuic" + else + log(2, i18n.translatef("Skip the %s node because the %s core program is not installed.", "Tuic", "Tuic", "Sing-Box")) + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + local Info = content + if content:find("@", 1, true) then + local contents = split(content, "@") + local auth = contents[1] or "" + local idx = auth:find(":", 1, true) + if not idx then -- Fix for some links will encode the ':' between the UUID and password. + auth = UrlDecode(auth) + idx = auth:find(":", 1, true) + end + if idx then + result.uuid = UrlDecode(auth:sub(1, idx - 1)) + result.password = UrlDecode(auth:sub(idx + 1)) + end + Info = (contents[2] or ""):gsub("/%?", "?") + end + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1):lower()] = UrlDecode(v:sub(s + 1)) + end + end + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls_serverName = params.sni + result.tls_disable_sni = params.disable_sni + result.tuic_alpn = params.alpn or "h3" + result.tuic_congestion_control = params.congestion_control or "cubic" + result.tuic_udp_relay_mode = params.udp_relay_mode or "native" + local insecure = params.allowinsecure or params.insecure or params.allow_insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + elseif szType == "anytls" then + if has_singbox then + result.type = 'sing-box' + result.protocol = "anytls" + else + log(2, i18n.translatef("Skip the %s node because the %s core program is not installed.", "AnyTLS", "AnyTLS", "Sing-Box 1.12")) + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + if content:find("@") then + local Info = split(content, "@") + result.password = UrlDecode(Info[1]) + local port = "443" + Info[2] = (Info[2] or ""):gsub("/%?", "?") + local query = split(Info[2], "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1):lower()] = UrlDecode(v:sub(s + 1)) + end + end + -- [2001:4860:4860::8888]:443 + -- 8.8.8.8:443 + if host_port:find(":") then + local sp = split(host_port, ":") + port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls = "0" + if not params.security or params.security == "" then + params.security = "tls" + end + if params.security == "tls" or params.security == "reality" then + result.tls = "1" + result.tls_serverName = params.sni + result.alpn = params.alpn + if params.fp and params.fp ~= "" then + result.utls = "1" + result.fingerprint = params.fp + end + if params.security == "reality" then + result.reality = "1" + result.reality_publicKey = params.pbk or nil + result.reality_shortId = params.sid or nil + end + end + result.port = port + local insecure = params.allowinsecure or params.insecure + result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") + end + elseif szType == 'naive+https' or szType == 'naive+quic' then + if has_singbox then + result.type = 'sing-box' + result.protocol = "naive" + else + log(2, i18n.translatef("Skip the %s node because the %s core program is not installed.", "NaïveProxy", "Sing-Box")) + return nil + end + + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + result.remarks = UrlDecode(alias) + local Info = content + if content:find("@", 1, true) then + local contents = split(content, "@") + local auth = contents[1] or "" + local idx = auth:find(":", 1, true) + if not idx then -- Fixed some links that encode the colon between username and password. + auth = UrlDecode(auth) + idx = auth:find(":", 1, true) + end + if idx then + result.username = UrlDecode(auth:sub(1, idx - 1)) + result.password = UrlDecode(auth:sub(idx + 1)) + end + Info = (contents[2] or ""):gsub("/%?", "?") + end + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local s = v:find("=", 1, true) + if s and s > 1 then + params[v:sub(1, s - 1)] = UrlDecode(v:sub(s + 1)) + end + end + if host_port:find(":") then + local sp = split(host_port, ":") + result.port = sp[#sp] + if api.is_ipv6addrport(host_port) then + result.address = api.get_ipv6_only(host_port) + else + result.address = sp[1] + end + else + result.address = host_port + end + result.tls_serverName = params.sni + result.uot = params.uot + result.naive_insecure_concurrency = params["insecure-concurrency"] or "0" + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end + if szType == "naive+quic" then + result.naive_quic = "1" + result.naive_congestion_control = params.congestion_control or "bbr" + end + else + log(2, i18n.translatef("%s type node subscriptions are not currently supported, skip this node.", szType)) + return nil + end + if not result.remarks or result.remarks == "" then + if result.address and result.port then + result.remarks = result.address .. ':' .. result.port + else + result.remarks = "NULL" + end + end + return result +end + +local function curl(url, file, ua, mode) + if not url or url == "" then return 22, 404 end + local curl_args = { + "-fskL", "-w %{http_code}", "--retry 3", "--connect-timeout 3", "-H 'Accept-Encoding: identity'" + } + if ua and ua ~= "" and ua ~= "curl" then + ua = (ua == "passwall2") and ("passwall2/" .. api.get_version()) or ua + curl_args[#curl_args + 1] = '--user-agent "' .. ua .. '"' + end + curl_args[#curl_args + 1] = get_headers() + local return_code, result + if mode == "direct" then + return_code, result = api.curl_direct(url, file, curl_args) + elseif mode == "proxy" then + return_code, result = api.curl_proxy(url, file, curl_args) + else + return_code, result = api.curl_auto(url, file, curl_args) + end + return return_code, tonumber(result) +end + +function get_headers() + local cache_file = "/tmp/etc/" .. appname .. "_tmp/sub_curl_headers" + if fs.access(cache_file) then + return luci.sys.exec("cat " .. cache_file) + end + local headers = {} + + local function readfile(path) + local f = io.open(path, "r") + if not f then return nil end + local c = f:read("*a") + f:close() + return api.trim(c) + end + + headers[#headers + 1] = "x-device-os: OpenWrt" + + local rel = readfile("/etc/openwrt_release") + local os_ver = rel and rel:match("DISTRIB_RELEASE='([^']+)'") + if os_ver then + headers[#headers + 1] = "x-ver-os: " .. os_ver + end + + local model = readfile("/tmp/sysinfo/model") + if model then + headers[#headers + 1] = "x-device-model: " .. model + end + + local mac = readfile("/sys/class/net/eth0/address") + if mac and model then + local raw = mac .. "-" .. model + local p = io.popen("printf '%s' '" .. raw:gsub("'", "'\\''") .. "' | sha256sum") + if p then + local hash = p:read("*l") + p:close() + hash = hash and hash:match("^%w+") + if hash then + headers[#headers + 1] = "x-hwid: " .. hash + end + end + end + + local out = {} + for i = 1, #headers do + out[i] = "-H '" .. headers[i]:gsub("'", "'\\''") .. "'" + end + local headers_str = table.concat(out, " ") + local f = io.open(cache_file, "w"); if f then f:write(headers_str); f:close() end + return headers_str +end + +local function truncate_nodes(group) + for _, config in pairs(CONFIG) do + if config.currentNodes and #config.currentNodes > 0 then + local newNodes = {} + local removeNodesSet = {} + for k, v in pairs(config.currentNodes) do + if v.currentNode and v.currentNode.add_mode == "2" then + if (not group) or (group:lower() == (v.currentNode.group or ""):lower()) then + removeNodesSet[v.currentNode[".name"]] = true + end + end + end + for _, value in ipairs(config.currentNodes) do + if not removeNodesSet[value.currentNode[".name"]] then + newNodes[#newNodes + 1] = value.currentNode[".name"] + end + end + if config.set then + config.set(config, newNodes) + end + else + if config.currentNode and config.currentNode.add_mode == "2" then + if (not group) or (group:lower() == (config.currentNode.group or ""):lower()) then + if config.delete then + config.delete(config) + elseif config.set then + config.set(config, "") + end + end + end + end + end + uci:foreach(appname, "nodes", function(node) + if node.add_mode == "2" then + if (not group) or (group:lower() == (node.group or ""):lower()) then + uci:delete(appname, node['.name']) + end + end + end) + uci:foreach(appname, "subscribe_list", function(o) + if (not group) or (group:lower() == (o.remark or ""):lower()) then + uci:delete(appname, o['.name'], "md5") + end + end) + api.uci_save(uci, appname, true) +end + +local function select_node(nodes, config, parentConfig) + local log_level = 1 + if parentConfig then + log_level = log_level + 1 + end + if config.currentNode then + local server + -- Load balancing, keeping the original ID of the Socks [port] node in urltest. + if config.currentNode["Socks"] then + server = config.currentNode.Socks + end + -- Special priority: cfgid + if config.currentNode[".name"] then + for index, node in pairs(nodes) do + if node[".name"] == config.currentNode[".name"] then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("Matching node:") .. " " .. node.remarks) + end + server = node[".name"] + break + end + end + end + -- First priority: Type + Notes + IP + Port + Group + if not server then + for index, node in pairs(nodes) do + if config.currentNode.type and config.currentNode.remarks and config.currentNode.address and config.currentNode.port then + if node.type and node.remarks and node.address and node.port then + if node.type == config.currentNode.type and node.remarks == config.currentNode.remarks and (node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port) and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("First Matching node:") .. " " .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- Second priority: Type + IP + Port + Group + if not server then + for index, node in pairs(nodes) do + if config.currentNode.type and config.currentNode.address and config.currentNode.port then + if node.type and node.address and node.port then + if node.type == config.currentNode.type and (node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port) and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("Second Matching node:") .. " " .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- Third priority: IP + Port + Group + if not server then + for index, node in pairs(nodes) do + if config.currentNode.address and config.currentNode.port then + if node.address and node.port then + if node.address .. ':' .. node.port == config.currentNode.address .. ':' .. config.currentNode.port and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("Third Matching node:") .. " " .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- Fourth priority: IP + Group + if not server then + for index, node in pairs(nodes) do + if config.currentNode.address then + if node.address then + if node.address == config.currentNode.address and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("Fourth Matching node:") .. " " .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + -- Fifth priority: remarks + Group + if not server then + for index, node in pairs(nodes) do + if config.currentNode.remarks then + if node.remarks then + if node.remarks == config.currentNode.remarks and node.group == config.currentNode.group then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("Fifth Matching node:") .. " " .. node.remarks) + end + server = node[".name"] + break + end + end + end + end + end + if not parentConfig then + -- If that doesn't work, just find one. + if not server then + if #nodes_table > 0 then + if config.log == nil or config.log == true then + log(log_level, i18n.translatef("Update [%s]", config.remarks) .. " " .. i18n.translatef("Unable to find the best matching node, now replaced with:") .. " " .. nodes_table[1].remarks) + end + server = nodes_table[1][".name"] + end + end + end + if server then + if parentConfig then + config.set(parentConfig, server) + else + config.set(config, server) + end + end + else + if not parentConfig then + config.set(config, "") + end + end +end + +local function update_node(manual) + if next(nodeResult) == nil then + log(1, i18n.translatef("No node information updates are available.")) + return + end + + local group = {} + for _, v in ipairs(nodeResult) do + group[v["remark"]:lower()] = true + end + + if manual == 0 and next(group) then + uci:foreach(appname, "nodes", function(node) + -- Do not delete nodes if no new nodes are found or nodes were manually imported... + if node.add_mode == "2" and (node.group and group[node.group:lower()] == true) then + uci:delete(appname, node['.name']) + end + end) + end + for _, v in ipairs(nodeResult) do + local remark = v["remark"] + local list = v["list"] + local sub_cfg = v["sub_cfg"] + local domain_resolver, domain_resolver_dns, domain_resolver_dns_https, domain_strategy + local preproxy_node_group, to_node_group, outbound_iface_group, chain_node_type = "", "", "", "" + -- Subscription Group Chain Agent + local function valid_chain_node(node) + if not node then return "" end + local cp = uci:get(appname, node, "chain_proxy") or "" + local am = uci:get(appname, node, "add_mode") or "0" + chain_node_type = (cp == "" and am ~= "2") and (uci:get(appname, node, "type") or "") or "" + if chain_node_type ~= "Xray" and chain_node_type ~= "sing-box" then + chain_node_type = "" + return "" + end + return node + end + if sub_cfg then + domain_resolver = sub_cfg.domain_resolver + domain_resolver_dns = sub_cfg.domain_resolver_dns + domain_resolver_dns_https = sub_cfg.domain_resolver_dns_https + domain_strategy = (sub_cfg.domain_strategy == "UseIPv4" or sub_cfg.domain_strategy == "UseIPv6") and sub_cfg.domain_strategy or nil + preproxy_node_group = (sub_cfg.chain_proxy == "1") and valid_chain_node(sub_cfg.preproxy_node) or "" + to_node_group = (sub_cfg.chain_proxy == "2") and valid_chain_node(sub_cfg.to_node) or "" + outbound_iface_group = (sub_cfg.chain_proxy == "3") and sub_cfg.outbound_iface or "" + chain_node_type = (outbound_iface_group ~= "") and "iface" or chain_node_type + end + for _, vv in ipairs(list) do + local cfgid = uci:section(appname, "nodes", api.gen_short_uuid()) + for kkk, vvv in pairs(vv) do + if type(vvv) == "table" and next(vvv) ~= nil then + uci:set_list(appname, cfgid, kkk, vvv) + else + if kkk ~= "group" or vvv ~= "default" then + uci:set(appname, cfgid, kkk, vvv) + end + -- Sing-Box Node Domain resolver + if kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then + if domain_resolver then + uci:set(appname, cfgid, "domain_resolver", domain_resolver) + if domain_resolver_dns then + uci:set(appname, cfgid, "domain_resolver_dns", domain_resolver_dns) + elseif domain_resolver_dns_https then + uci:set(appname, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https) + end + end + if domain_strategy then + if vvv == "sing-box" then + domain_strategy = (domain_strategy == "UseIPv4" and "ipv4_only") or (domain_strategy == "UseIPv6" and "ipv6_only") or domain_strategy + end + uci:set(appname, cfgid, "domain_strategy", domain_strategy) + end + end + -- Subscription Group Chain Agent + if chain_node_type ~= "" and kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then + if preproxy_node_group ~="" then + uci:set(appname, cfgid, "chain_proxy", "1") + uci:set(appname, cfgid, "preproxy_node", preproxy_node_group) + elseif to_node_group ~= "" then + uci:set(appname, cfgid, "chain_proxy", "2") + uci:set(appname, cfgid, "to_node", to_node_group) + elseif outbound_iface_group ~= "" then + uci:set(appname, cfgid, "chain_proxy", "3") + uci:set(appname, cfgid, "outbound_iface", outbound_iface_group) + end + end + end + end + end + end + -- Update subscription information + for cfgid, info in pairs(subscribe_info) do + for key, value in pairs(info) do + if value ~= "" then + uci:set(appname, cfgid, key, value) + else + uci:delete(appname, cfgid, key) + end + end + end + + if next(CONFIG) then + local nodes = {} + uci:foreach(appname, "nodes", function(node) + nodes[#nodes + 1] = node + end) + + for _, config in pairs(CONFIG) do + if config.currentNodes and #config.currentNodes > 0 then + if config.remarks and config.currentNodes[1].log ~= false then + log(1, i18n.translatef("Update [%s]", config.remarks)) + end + for kk, vv in pairs(config.currentNodes) do + select_node(nodes, vv, config) + end + config.set(config) + if not config.newNodes or #config.newNodes == 0 then + log(1, i18n.translatef("[%s]", config.remarks) .. " " .. i18n.translate("Unable to find a new node. Please confirm and process manually.")) + end + else + select_node(nodes, config) + end + end + end + + api.uci_save(uci, appname, true) + + if arg[3] == "cron" then + if not fs.access("/var/lock/" .. appname .. ".lock") then + luci.sys.call("touch /tmp/lock/" .. appname .. "_cron.lock") + end + end + + if manual ~= 1 then + luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &") + end +end + +local function parse_link(raw, add_mode, group, sub_cfg) + if raw and #raw > 0 then + local cfgid + if sub_cfg then + cfgid = sub_cfg[".name"] + end + local nodes, szType, clashTable + local node_list = {} + -- ssd appear to be in this format, starting with ssd://. + if raw:find('ssd://') then + szType = 'ssd' + local nEnd = select(2, raw:find('ssd://')) + nodes = base64Decode(raw:sub(nEnd + 1, #raw)) + nodes = jsonParse(nodes) + local extra = { + airport = nodes.airport, + port = nodes.port, + encryption = nodes.encryption, + password = nodes.password + } + local servers = {} + -- SS is wrapped inside, so let's just like this. + for _, server in ipairs(nodes.servers) do + tinsert(servers, setmetatable(server, { __index = extra })) + end + nodes = servers + else + -- Try parseYAML, if success, is clash. + local yamlTable = lyaml.load(raw) + if yamlTable and type(yamlTable) == "table" then + -- clash + szType = "clash" + clashTable = yamlTable + else + -- Formats other than ssd + if add_mode == "1" then + nodes = split(raw, "\n") + else + nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n") + end + end + end + + function nodeFilter(node) + if node then + if node.error_msg then + log(2, i18n.translatef("Discard node: %s, Reason:", node.remarks) .. " " .. node.error_msg) + elseif not node.type then + log(2, i18n.translatef("Discard node: %s, Reason:", node.remarks) .. " " .. i18n.translatef("No usable binary was found.")) + elseif (add_mode == "2" and is_filter_keyword(sub_cfg, node.remarks)) or not node.address or node.remarks == "NULL" or node.address == "127.0.0.1" or + (not datatypes.hostname(node.address) and not (api.is_ip(node.address))) then + log(2, i18n.translatef("Discard filter nodes: %s type node %s", node.type, node.remarks)) + else + tinsert(node_list, node) + end + if add_mode == "2" then + get_subscribe_info(cfgid, node.remarks) + end + end + end + + if szType == "clash" and clashTable then + nodes = {} + local clashNodes = processClashData(clashTable, add_mode, group, sub_cfg) + for _, v in ipairs(clashNodes) do + nodeFilter(v) + end + end + + for _, v in ipairs(nodes) do + if v and (szType == 'ssd' or not string.match(v, "^%s*$")) then + xpcall(function () + local result + if szType == 'ssd' then + result = processData(szType, v, add_mode, group, sub_cfg) + elseif not szType then + local node = api.trim(v) + local dat = split(node, "://") + if dat and dat[1] and dat[2] then + if dat[1] == 'vmess' or dat[1] == 'ssr' then + local link = api.trim(dat[2]:gsub("#.*$", "")) + result = processData(dat[1], base64Decode(link), add_mode, group, sub_cfg) + else + local link = dat[2]:gsub("&", "&"):gsub("%s*#%s*", "#") -- Some odd links use "&" as "&", and include spaces before and after "#". + result = processData(dat[1], link, add_mode, group, sub_cfg) + end + end + else + log(2, i18n.translatef("Skip unknown types:") .. " " .. szType) + end + -- log(2, result) + nodeFilter(result) + end, function (err) + --log(2, err) + log(2, v, i18n.translatef("Parsing error, skip this node.")) + end + ) + end + end + if #node_list > 0 then + nodeResult[#nodeResult + 1] = { + remark = group, + list = node_list, + sub_cfg = sub_cfg + } + end + log(2, i18n.translatef("Successfully resolved the [%s] node, number: %s", group, #node_list)) + else + if add_mode == "2" then + log(2, i18n.translatef("Get subscription content for [%s] is empty. This may be due to an invalid subscription address or a network problem. Please diagnose the issue!", group)) + end + end +end + +local execute = function() + do + local subscribe_list = {} + local fail_list = {} + if arg[2] ~= "all" then + string.gsub(arg[2], '[^' .. "," .. ']+', function(w) + subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {} + end) + else + uci:foreach(appname, "subscribe_list", function(o) + subscribe_list[#subscribe_list + 1] = o + end) + end + + local manual_sub = arg[3] == "manual" + + for index, value in ipairs(subscribe_list) do + local cfgid = value[".name"] + local remark = value.remark or "" + local url = value.url or "" + + local url_is_local + if fs.access(url) then + -- debug, reads local files. + log(1, i18n.translatef("Start subscribing: %s", 'ã€' .. remark .. '】' .. url)) + url_is_local = true + tmp_file = url + else + local ua = value.user_agent + local access_mode = value.access_mode + local result = (not access_mode) and i18n.translatef("Auto") or (access_mode == "direct" and i18n.translatef("Direct") or (access_mode == "proxy" and i18n.translatef("Proxy") or i18n.translatef("Auto"))) + log(1, i18n.translatef("Start subscribing: %s", 'ã€' .. remark .. '】' .. url .. ' [' .. result .. ']')) + tmp_file = "/tmp/" .. cfgid + local return_code + return_code, value.http_code = curl(url, tmp_file, ua, access_mode) + if return_code ~= 0 then + fail_list[#fail_list + 1] = value + luci.sys.call("rm -f " .. tmp_file) + end + end + if fs.access(tmp_file) then + if luci.sys.call("[ -f " .. tmp_file .. " ] && sed -i -e '/^[ \t]*$/d' -e '/^[ \t]*\r$/d' " .. tmp_file) == 0 then + local f = io.open(tmp_file, "r") + local stdout = f:read("*all") + f:close() + local raw_data = api.trim(stdout) + local old_md5 = value.md5 or "" + local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "") + if not manual_sub and old_md5 == new_md5 then + log(1, i18n.translatef("Subscription: [%s] No changes, no update required.", remark)) + else + parse_link(raw_data, "2", remark, value) + uci:set(appname, cfgid, "md5", new_md5) + end + else + fail_list[#fail_list + 1] = value + end + if url_is_local then + value.http_code = 0 + else + luci.sys.call("rm -f " .. tmp_file) + end + end + end + + if #fail_list > 0 then + for index, value in ipairs(fail_list) do + log(1, i18n.translatef("[%s] Subscription failed. This could be due to an invalid subscription address or a network issue. Please diagnose the problem! [%s]", value.remark, tostring(value.http_code))) + end + end + update_node(0) + end +end + +local function check_instance(action) + local sub_lock = "/var/lock/" .. appname .. "_subscribe.lock" + local rule_lock = "/var/lock/" .. appname .. "_rule_update.lock" + + if action == "start" then + math.randomseed(os.time() + math.floor(os.clock() * 1000)) + api.nixio.nanosleep(0, math.random(100, 1000) * 1000000) + if fs.access(sub_lock) then + log(0, i18n.translatef("[Subscription] instance is running; please try again later.") .. "\n") + os.exit(0) + else + luci.sys.call("touch " .. sub_lock) + uci:revert(appname) + end + elseif action == "end" then + luci.sys.call("rm -f " .. sub_lock) + return + end + + if fs.access(rule_lock) then + log(0, i18n.translatef("[Rule Update] instance is running; [Subscription] queue and wait.") .. "\n") + end + while fs.access(rule_lock) do + api.nixio.nanosleep(2, 0) + end +end + +if arg[1] then + check_instance("start") + + if arg[1] == "start" then + log(0, i18n.translatef("Start subscribing...")) + xpcall(execute, function(e) + log(1, e) + log(1, debug.traceback()) + log(1, i18n.translatef("Error, restoring service.")) + end) + log(0, i18n.translatef("Subscription complete...") .. "\n") + elseif arg[1] == "add" then + local f = assert(io.open("/tmp/links.conf", 'r')) + local raw = f:read('*all') + f:close() + parse_link(raw, "1", arg[2]) + update_node(1) + luci.sys.call("rm -f /tmp/links.conf") + elseif arg[1] == "truncate" then + truncate_nodes(arg[2]) + end + + check_instance("end") +end diff --git a/luci-app-passwall2/root/usr/share/passwall2/tasks.sh b/luci-app-passwall2/root/usr/share/passwall2/tasks.sh new file mode 100755 index 00000000..90d14512 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/tasks.sh @@ -0,0 +1,89 @@ +#!/bin/sh +## Loop update script + +. /usr/share/passwall2/utils.sh +LOCK_FILE=${LOCK_PATH}/${CONFIG}_tasks.lock + +CFG_UPDATE_INT=0 + +exec 99>"$LOCK_FILE" +flock -n 99 +if [ "$?" != 0 ]; then + exit 0 +fi + +while true +do + + if [ "$CFG_UPDATE_INT" -ne 0 ]; then + + stop_week_mode=$(config_t_get global_delay stop_week_mode) + stop_interval_mode=$(config_t_get global_delay stop_interval_mode) + stop_interval_mode=$(expr "$stop_interval_mode" \* 60) + if [ -n "$stop_week_mode" ]; then + [ "$stop_week_mode" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$stop_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG stop > /dev/null 2>&1 & } + } + fi + + start_week_mode=$(config_t_get global_delay start_week_mode) + start_interval_mode=$(config_t_get global_delay start_interval_mode) + start_interval_mode=$(expr "$start_interval_mode" \* 60) + if [ -n "$start_week_mode" ]; then + [ "$start_week_mode" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$start_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG start > /dev/null 2>&1 & } + } + fi + + restart_week_mode=$(config_t_get global_delay restart_week_mode) + restart_interval_mode=$(config_t_get global_delay restart_interval_mode) + restart_interval_mode=$(expr "$restart_interval_mode" \* 60) + if [ -n "$restart_week_mode" ]; then + [ "$restart_week_mode" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$restart_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG restart > /dev/null 2>&1 & } + } + fi + + autoupdate=$(config_t_get global_rules auto_update) + weekupdate=$(config_t_get global_rules week_update) + hourupdate=$(config_t_get global_rules interval_update) + hourupdate=$(expr "$hourupdate" \* 60) + if [ "$autoupdate" = "1" ]; then + [ "$weekupdate" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$hourupdate")" -eq 0 ] && { lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 & } + } + fi + + TMP_SUB_PATH=$TMP_PATH/sub_tasks + mkdir -p $TMP_SUB_PATH + for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do + if [ "$(config_n_get $item auto_update 0)" = "1" ]; then + cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1) + remark=$(config_n_get $item remark) + week_update=$(config_n_get $item week_update) + hour_update=$(config_n_get $item interval_update) + echo "$cfgid" >> $TMP_SUB_PATH/${week_update}_${hour_update} + fi + done + + [ -d "${TMP_SUB_PATH}" ] && { + for name in $(ls ${TMP_SUB_PATH}); do + week_update=$(echo $name | awk -F '_' '{print $1}') + hour_update=$(echo $name | awk -F '_' '{print $2}') + hour_update=$(expr "$hour_update" \* 60) + cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g') + [ "$week_update" = "8" ] && { + [ "$(expr "$CFG_UPDATE_INT" % "$hour_update")" -eq 0 ] && { lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 & } + } + + done + rm -rf $TMP_SUB_PATH + } + + fi + + CFG_UPDATE_INT=$(expr "$CFG_UPDATE_INT" + 10) + + sleep 600 + +done 2>/dev/null diff --git a/luci-app-passwall2/root/usr/share/passwall2/test.sh b/luci-app-passwall2/root/usr/share/passwall2/test.sh new file mode 100755 index 00000000..cd1084e9 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/test.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +. /usr/share/passwall2/utils.sh + +test_url() { + local url=$1 + local try=1 + [ -n "$2" ] && try=$2 + local timeout=2 + [ -n "$3" ] && timeout=$3 + local extra_params=$4 + curl --help all | grep "\-\-retry-all-errors" > /dev/null + [ $? == 0 ] && extra_params="--retry-all-errors ${extra_params}" + status=$(/usr/bin/curl -I -o /dev/null -skL $extra_params --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") + case "$status" in + 204|\ + 200) + status=200 + ;; + esac + echo $status +} + +test_proxy() { + result=0 + status=$(test_url "https://www.google.com/generate_204" ${retry_num} ${connect_timeout}) + if [ "$status" = "200" ]; then + result=0 + else + status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout}) + if [ "$status2" = "200" ]; then + result=1 + else + result=2 + ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 + [ $? -eq 0 ] && { + result=1 + } + fi + fi + echo $result +} + +url_test_node() { + result=0 + local node_id=$1 + local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') + [ -n "${_type}" ] && { + local _tmp_port=$(get_new_port 48900 tcp,udp) + NO_REC_PROCESS=1 /usr/share/${CONFIG}/app.sh run_socks flag="url_test_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=url_test_${node_id}.json + sleep 2s + local curlx="socks5h://127.0.0.1:${_tmp_port}" + local probeUrl=$(config_t_get global_other url_test_url https://www.google.com/generate_204) + result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_pretransfer}" -x ${curlx} "${probeUrl}") + # End the SS plugin process + local pid_file="/tmp/etc/${CONFIG}/url_test_${node_id}_plugin.pid" + [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 + busybox pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -rf /tmp/etc/${CONFIG}/*url_test_${node_id}*.* + } + echo $result +} + +arg1=$1 +shift +case $arg1 in +test_url) + test_url $@ + ;; +url_test_node) + url_test_node $@ + ;; +esac diff --git a/luci-app-passwall2/root/usr/share/passwall2/utils.sh b/luci-app-passwall2/root/usr/share/passwall2/utils.sh new file mode 100755 index 00000000..b345c7ee --- /dev/null +++ b/luci-app-passwall2/root/usr/share/passwall2/utils.sh @@ -0,0 +1,516 @@ +#!/bin/sh +# Copyright (C) 2022-2025 xiaorouji +# Copyright (C) 2026 Openwrt-Passwall Organization + +CONFIG=passwall2 +APP_PATH=/usr/share/${CONFIG} +TMP_PATH=/tmp/etc/${CONFIG} +TMP_PATH2=${TMP_PATH}_tmp +LOCK_PATH=/tmp/lock +LOG_FILE=/tmp/log/${CONFIG}.log +TMP_ACL_PATH=${TMP_PATH}/acl +TMP_BIN_PATH=${TMP_PATH}/bin +TMP_IFACE_PATH=${TMP_PATH}/iface +TMP_ROUTE_PATH=${TMP_PATH}/route +TMP_SCRIPT_FUNC_PATH=${TMP_PATH}/script_func +TMP_PROCESS_LIST_PATH=${TMP_PATH}/process_list + +. /lib/functions/network.sh + +config_get_type() { + local ret=$(uci -q get "${CONFIG}.${1}" 2>/dev/null) + echo "${ret:=$2}" +} + +config_n_get() { + local ret=$(uci -q get "${CONFIG}.${1}.${2}" 2>/dev/null) + echo "${ret:=$3}" +} + +config_t_get() { + local index=${4:-0} + local ret=$(uci -q get "${CONFIG}.@${1}[${index}].${2}" 2>/dev/null) + echo "${ret:=${3}}" +} + +config_t_set() { + local index=${4:-0} + local ret=$(uci -q set "${CONFIG}.@${1}[${index}].${2}=${3}" 2>/dev/null) +} + +eval_set_val() { + for i in $@; do + for j in $i; do + eval $j + done + done +} + +eval_unset_val() { + for i in $@; do + for j in $i; do + eval unset $j + done + done +} + +eval_cache_var() { + [ -s "$TMP_PATH/var" ] && eval $(cat "$TMP_PATH/var") +} + +get_cache_var() { + local key="${1}" + [ -n "${key}" ] && [ -s "$TMP_PATH/var" ] && { + echo $(cat $TMP_PATH/var | grep "^${key}=" | awk -F '=' '{print $2}' | tail -n 1 | awk -F'"' '{print $2}') + } +} + +set_cache_var() { + local key="${1}" + shift 1 + local val="$@" + [ -n "${key}" ] && [ -n "${val}" ] && { + [ ! -d $TMP_PATH ] && mkdir -p $TMP_PATH + sed -i "/${key}=/d" $TMP_PATH/var >/dev/null 2>&1 + echo "${key}=\"${val}\"" >> $TMP_PATH/var + eval ${key}=\"${val}\" + } +} + +echolog() { + echo -e "$*" >>$LOG_FILE +} + +echolog_date() { + local d="$(date "+%Y-%m-%d %H:%M:%S")" + echolog "$d: $*" +} + +i18n() { + echo "$(lua ${APP_PATH}/i18n.lua "$@")" +} + +log() { + local num="$1" + shift + local content="$@" + local indent="" + if [ "$num" -ge 1 ]; then + for i in $(seq 1 ${num}); do + indent="${indent} " + done + echolog_date "${indent}- ${content}" + else + echolog_date "${content}" + fi +} + +log_i18n() { + local num="$1" + shift + log ${num} "$(i18n "$@")" +} + +clean_log() { + logsnum=$(cat $LOG_FILE 2>/dev/null | wc -l) + [ "$logsnum" -gt 1000 ] && { + echo "" > $LOG_FILE + log_i18n 0 "Log file is too long, clear it!" + } +} + +lua_api() { + local func=${1} + [ -z "${func}" ] && { + echo "" + return + } + echo $(lua -e "local api = require 'luci.passwall2.api' print(api.${func})") +} + +check_host() { + local f=${1} + a=$(echo $f | grep "\/") + [ -n "$a" ] && return 1 + # Determine if it contains Chinese characters. + local tmp=$(echo -n $f | awk '{print gensub(/[!-~]/,"","g",$0)}') + [ -n "$tmp" ] && return 1 + return 0 +} + +first_type() { + [ "${1#/}" != "$1" ] && [ -x "$1" ] && echo "$1" && return + for p in "/bin/$1" "/usr/bin/$1" "${TMP_BIN_PATH:-/tmp}/$1"; do + [ -x "$p" ] && echo "$p" && return + done + command -v "$1" 2>/dev/null || command -v "$2" 2>/dev/null +} + +get_enabled_anonymous_secs() { + uci -q show "${CONFIG}" | grep "${1}\[.*\.enabled='1'" | cut -d '.' -sf2 +} + +get_geoip() { + local geo_output_path="$TMP_PATH2/geo_output" + mkdir -p ${geo_output_path} + local geoip_code="$1" + local geoip_type_flag="" + local output_path="${geo_output_path}/geoip-${geoip_code}-$2" + [ ! -s "${output_path}" ] && { + local geoip_path="$(config_t_get global_rules v2ray_location_asset)" + geoip_path="${geoip_path%*/}/geoip.dat" + local bin="$(first_type $(config_t_get global_app geoview_file) geoview)" + [ -n "$bin" ] && [ -s "$geoip_path" ] || { echo ""; return; } + case "$2" in + "ipv4") geoip_type_flag="-ipv6=false" ;; + "ipv6") geoip_type_flag="-ipv4=false" ;; + esac + "$bin" -input "$geoip_path" -list "$geoip_code" $geoip_type_flag -lowmem=true -output ${output_path} + } + [ -s "${output_path}" ] && cat "${output_path}" +} + +get_host_ip() { + local host=$2 + local count=$3 + [ -z "$count" ] && count=3 + local isip="" + local ip="" + if [ "$1" == "ipv6" ]; then + isip=$(echo $host | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + if [ -n "$isip" ]; then + ip=$(echo "$host" | tr -d '[]') + fi + else + isip=$(echo $host | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}") + [ -n "$isip" ] && ip=$isip + fi + [ -z "$isip" ] && { + local t=4 + [ "$1" == "ipv6" ] && t=6 + local vpsrip=$(resolveip -$t -t $count $host | awk 'NR==1{print}') + ip=$vpsrip + } + [ -n "$ip" ] && echo "$ip" +} + +get_node_host_ip() { + local ip + local address=$(config_n_get $1 address) + [ -n "$address" ] && { + local use_ipv6=$(config_n_get $1 use_ipv6) + local network_type="ipv4" + [ "$use_ipv6" == "1" ] && network_type="ipv6" + ip=$(get_host_ip $network_type $address) + } + echo $ip +} + +get_ip_port_from() { + local __host=${1}; shift 1 + local __ipv=${1}; shift 1 + local __portv=${1}; shift 1 + local __ucipriority=${1}; shift 1 + + local val1 val2 + if [ -n "${__ucipriority}" ]; then + val2=$(config_n_get ${__host} port $(echo $__host | sed -n 's/^.*[:#]\([0-9]*\)$/\1/p')) + val1=$(config_n_get ${__host} address "${__host%%${val2:+[:#]${val2}*}}") + else + val2=$(echo $__host | sed -n 's/^.*[:#]\([0-9]*\)$/\1/p') + val1="${__host%%${val2:+[:#]${val2}*}}" + fi + eval "${__ipv}=\"$val1\"; ${__portv}=\"$val2\"" +} + +host_from_url(){ + local f=${1} + + ## Remove protocol part of url ## + f="${f##http://}" + f="${f##https://}" + f="${f##ftp://}" + f="${f##sftp://}" + + ## Remove username and/or username:password part of URL ## + f="${f##*:*@}" + f="${f##*@}" + + ## Remove rest of urls ## + f="${f%%/*}" + echo "${f%%:*}" +} + +hosts_foreach() { + local __hosts + eval "__hosts=\$${1}"; shift 1 + local __func=${1}; shift 1 + local __default_port=${1}; shift 1 + local __ret=1 + + [ -z "${__hosts}" ] && return 0 + local __ip __port + for __host in $(echo $__hosts | sed 's/[ ,]/\n/g'); do + get_ip_port_from "$__host" "__ip" "__port" + eval "$__func \"${__host}\" \"\${__ip}\" \"\${__port:-${__default_port}}\" \"$@\"" + __ret=$? + [ ${__ret} -ge ${ERROR_NO_CATCH:-1} ] && return ${__ret} + done +} + +get_first_dns() { + local __hosts_val=${1}; shift 1 + __first() { + [ -z "${2}" ] && return 0 + echo "${2}#${3}" + return 1 + } + eval "hosts_foreach \"${__hosts_val}\" __first \"$@\"" +} + +get_last_dns() { + local __hosts_val=${1}; shift 1 + local __first __last + __every() { + [ -z "${2}" ] && return 0 + __last="${2}#${3}" + __first=${__first:-${__last}} + } + eval "hosts_foreach \"${__hosts_val}\" __every \"$@\"" + [ "${__first}" == "${__last}" ] || echo "${__last}" +} + +check_port_exists() { + local port=$1 + local protocol=$2 + [ -n "$protocol" ] || protocol="tcp,udp" + local result= + if [ "$protocol" = "tcp" ]; then + result=$(netstat -tln | grep -c ":$port ") + elif [ "$protocol" = "udp" ]; then + result=$(netstat -uln | grep -c ":$port ") + elif [ "$protocol" = "tcp,udp" ]; then + result=$(netstat -tuln | grep -c ":$port ") + fi + echo "${result}" +} + +get_new_port() { + local default_start_port=2001 + local min_port=1025 + local max_port=49151 + local port=$1 + local last_get_new_port_auto + if [ "$1" == "auto" ]; then + last_get_new_port_auto=$(get_cache_var "last_get_new_port_auto") + if [ -n "$last_get_new_port_auto" ]; then + port=$last_get_new_port_auto + port=$(expr $port + 1) + else + port=$default_start_port + fi + fi + [ "$port" -lt $min_port -o "$port" -gt $max_port ] && port=$default_start_port + local protocol=$(echo $2 | tr 'A-Z' 'a-z') + local result=$(check_port_exists $port $protocol) + if [ "$result" != 0 ]; then + local temp= + if [ "$port" -lt $max_port ]; then + temp=$(expr $port + 1) + elif [ "$port" -gt $min_port ]; then + temp=$(expr $port - 1) + else + temp=$default_start_port + fi + get_new_port $temp $protocol + else + [ "$1" == "auto" ] && set_cache_var "last_get_new_port_auto" "$port" + echo $port + fi +} + +has_1_65535() { + local val="$1" + val=${val//:/-} + case ",$val," in + *,1-65535,*) return 0 ;; + *) return 1 ;; + esac +} + +add_ip2route() { + local ip=$(get_host_ip "ipv4" $1) + [ -z "$ip" ] && { + log 1 "$(i18n "Unable to resolve [%s], route table addition failed!" "${1}")" + return 1 + } + local remarks="${1}" + [ "$remarks" != "$ip" ] && remarks="${1}(${ip})" + + local gateway device + network_get_gateway gateway "$2" + network_get_device device "$2" + [ -z "${device}" ] && device=$(ubus call "network.interface.$2" status 2>/dev/null | jsonfilter -e '@.device' 2>/dev/null) + [ -z "${device}" ] && [ -d "/sys/class/net/$2" ] && device="$2" + [ -z "${device}" ] && device="$2" + + if [ -n "${gateway}" ]; then + route add -host ${ip} gw ${gateway} dev ${device} >/dev/null 2>&1 + echo "$ip" >> $TMP_ROUTE_PATH/${device} + log 1 "$(i18n "[%s] was successfully added to the routing table of interface [%s]!" "${remarks}" "${device}")" + else + log 1 "$(i18n "Adding [%s] to the [%s] routing table failed! The reason is that the [%s] gateway cannot be found." "${remarks}" "${device}" "${device}")" + fi +} + +delete_ip2route() { + [ -d "${TMP_ROUTE_PATH}" ] && { + for interface in $(ls ${TMP_ROUTE_PATH}); do + for ip in $(cat ${TMP_ROUTE_PATH}/${interface}); do + route del -host ${ip} dev ${interface} >/dev/null 2>&1 + done + done + } +} + +ln_run() { + local queue_run=${1} + local file_func=${2} + local ln_name=${3} + local output=${4} + shift 4; + + if [ "${file_func%%/*}" != "${file_func}" ]; then + [ ! -L "${file_func}" ] && { + ln -s "${file_func}" "${TMP_BIN_PATH}/${ln_name}" >/dev/null 2>&1 + file_func="${TMP_BIN_PATH}/${ln_name}" + } + [ -x "${file_func}" ] || log 1 "$(i18n "%s does not have execute permissions and cannot be started: %s %s" "$(readlink ${file_func})" "${file_func}" "$*")" + fi + #echo "${file_func} $*" >&2 + [ -n "${file_func}" ] || log 1 "$(i18n "%s not found, unable to start..." "${ln_name}")" + + [ "${queue_run}" == "1" ] && { + mkdir -p $TMP_PROCESS_LIST_PATH + process_count=$(ls $TMP_PROCESS_LIST_PATH | grep -v "^_" | wc -l) + process_count=$((process_count + 1)) + echo "${file_func:-log 1 "${ln_name}"} $@ >${output}" > $TMP_PROCESS_LIST_PATH/$process_count + return + } + + ${file_func:-log 1 "${ln_name}"} "$@" >${output} 2>&1 & + + [ -n "$NO_REC_PROCESS" ] && return + + process_count=$(ls $TMP_SCRIPT_FUNC_PATH | grep -v "^_" | wc -l) + process_count=$((process_count + 1)) + echo "${file_func:-log 1 "${ln_name}"} $@ >${output}" > $TMP_SCRIPT_FUNC_PATH/$process_count +} + +run_process_queue() { + [ -d ${TMP_PROCESS_LIST_PATH} ] && { + for filename in $(ls ${TMP_PROCESS_LIST_PATH}); do + cmd=$(cat ${TMP_PROCESS_LIST_PATH}/${filename}) + cmd_check=$(echo $cmd | awk -F '>' '{print $1}') + icount=$(busybox pgrep -f "$(echo $cmd_check)" | wc -l) + if [ $icount = 0 ]; then + eval $(echo "nohup ${cmd} 2>&1 &") >/dev/null 2>&1 & + fi + rm -rf ${TMP_PROCESS_LIST_PATH}/${filename} + done + } + rm -rf ${TMP_PROCESS_LIST_PATH} +} + +kill_all() { + kill -9 $(pidof "$@") >/dev/null 2>&1 +} + +gen_lanlist() { + cat <<-EOF + 0.0.0.0/8 + 10.0.0.0/8 + 100.64.0.0/10 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.168.0.0/16 + 224.0.0.0/4 + 240.0.0.0/4 + EOF +} + +gen_lanlist_6() { + cat <<-EOF + ::/128 + ::1/128 + ::ffff:0:0/96 + ::ffff:0:0:0/96 + 64:ff9b::/96 + 100::/64 + 2001::/32 + 2001:20::/28 + 2001:db8::/32 + 2002::/16 + fc00::/7 + fe80::/10 + ff00::/8 + EOF +} + +get_wan_ips() { + local family="$1" + local NET_ADDR + local iface + local INTERFACES=$(ubus call network.interface dump | jsonfilter -e \ + '@.interface[!(@.interface ~ /lan/) && !(@.l3_device ~ /\./) && @.route[0]].interface') + for iface in $INTERFACES; do + local addr + if [ "$family" = "ip6" ]; then + network_get_ipaddr6 addr "$iface" + case "$addr" in + ""|fe80*) continue ;; + esac + else + network_get_ipaddr addr "$iface" + case "$addr" in + ""|"0.0.0.0") continue ;; + esac + fi + case " $NET_ADDR " in + *" $addr "*) ;; + *) NET_ADDR="${NET_ADDR:+$NET_ADDR }$addr" ;; + esac + done + echo "$NET_ADDR" +} + +get_local_ips() { + local family="$1" + local ALL_IPS WAN_IPS ip NET_ADDR + if [ "$family" = "ip6" ]; then + ALL_IPS=$(ip -o -6 addr show scope global | awk '{print $4}' | cut -d/ -f1) + WAN_IPS=$(get_wan_ips ip6) + else + ALL_IPS=$(ip -o -4 addr show scope global | awk '{print $4}' | cut -d/ -f1) + WAN_IPS=$(get_wan_ips ip4) + fi + # Supplementary loop (not included in scope global) + [ "$family" = "ip6" ] && ALL_IPS="$ALL_IPS ::1" + [ "$family" != "ip6" ] && ALL_IPS="$ALL_IPS 127.0.0.1" + for ip in $ALL_IPS; do + case "$ip" in + ""|0.0.0.0|::) continue ;; + esac + case " $WAN_IPS " in + *" $ip "*) continue ;; + esac + case " $NET_ADDR " in + *" $ip "*) ;; + *) NET_ADDR="${NET_ADDR:+$NET_ADDR }$ip" ;; + esac + done + for ip in $NET_ADDR; do + echo "$ip" + done +} diff --git a/luci-app-passwall2/root/usr/share/rpcd/acl.d/luci-app-passwall2.json b/luci-app-passwall2/root/usr/share/rpcd/acl.d/luci-app-passwall2.json new file mode 100644 index 00000000..ec872412 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/rpcd/acl.d/luci-app-passwall2.json @@ -0,0 +1,11 @@ +{ + "luci-app-passwall2": { + "description": "Grant UCI access for luci-app-passwall2", + "read": { + "uci": [ "passwall2", "passwall2_server" ] + }, + "write": { + "uci": [ "passwall2", "passwall2_server" ] + } + } +} diff --git a/luci-app-passwall2/root/usr/share/ucitrack/luci-app-passwall2-server.json b/luci-app-passwall2/root/usr/share/ucitrack/luci-app-passwall2-server.json new file mode 100644 index 00000000..d73b5d10 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/ucitrack/luci-app-passwall2-server.json @@ -0,0 +1,4 @@ +{ + "config": "passwall2_server", + "init": "passwall2_server" +} diff --git a/luci-app-passwall2/root/usr/share/ucitrack/luci-app-passwall2.json b/luci-app-passwall2/root/usr/share/ucitrack/luci-app-passwall2.json new file mode 100644 index 00000000..2ff857b0 --- /dev/null +++ b/luci-app-passwall2/root/usr/share/ucitrack/luci-app-passwall2.json @@ -0,0 +1,4 @@ +{ + "config": "passwall2", + "init": "passwall2" +} diff --git a/luci-app-qbittorrent/Makefile b/luci-app-qbittorrent/Makefile new file mode 100644 index 00000000..896a35f5 --- /dev/null +++ b/luci-app-qbittorrent/Makefile @@ -0,0 +1,18 @@ +# Copyright (C) 2019 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-qbittorrent +PKG_VERSION:=1.0.1 +PKG_RELEASE:=1 + +LUCI_TITLE:=LuCI support for qBittorrent +LUCI_PKGARCH:=all +LUCI_DEPENDS:=+qbittorrent + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-qbittorrent/htdocs/luci-static/resources/view/qbittorrent.js b/luci-app-qbittorrent/htdocs/luci-static/resources/view/qbittorrent.js new file mode 100644 index 00000000..2aa4e2ad --- /dev/null +++ b/luci-app-qbittorrent/htdocs/luci-static/resources/view/qbittorrent.js @@ -0,0 +1,85 @@ +'use strict'; +'require form'; +'require poll'; +'require rpc'; +'require uci'; +'require view'; + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); + +function getServiceStatus() { + return L.resolveDefault(callServiceList('qbittorrent'), {}).then(function (res) { + var isRunning = false; + try { + isRunning = res['qbittorrent']['instances']['instance1']['running']; + } catch (e) { } + return isRunning; + }); +} + +function renderStatus(isRunning, webport) { + var spanTemp = '%s %s'; + var renderHTML; + if (isRunning) { + var button = String.format('', + _('Open Web Interface'), window.location.hostname, webport); + renderHTML = spanTemp.format('green', _('qBittorrent'), _('RUNNING')) + button; + } else { + renderHTML = spanTemp.format('red', _('qBittorrent'), _('NOT RUNNING')); + } + + return renderHTML; +} + +return view.extend({ + load: function() { + return Promise.all([ + uci.load('qbittorrent') + ]); + }, + + render: function(data) { + var m, s, o; + var webport = uci.get(data[0], 'config', 'port') || '8080'; + + m = new form.Map('qbittorrent', _('qBittorrent'), + _('qBittorrent is a cross-platform free and open-source BitTorrent client. Default username & password: admin / adminadmin')); + + s = m.section(form.TypedSection); + s.anonymous = true; + s.render = function () { + poll.add(function () { + return L.resolveDefault(getServiceStatus()).then(function (res) { + var view = document.getElementById('service_status'); + view.innerHTML = renderStatus(res, webport); + }); + }); + + return E('div', { class: 'cbi-section', id: 'status_bar' }, [ + E('p', { id: 'service_status' }, _('Collecting data...')) + ]); + } + + s = m.section(form.NamedSection, 'config', 'qbittorrent'); + + o = s.option(form.Flag, 'enabled', _('Enable')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.Value, 'port', _('WebUI Listen port')); + o.datatype = 'port'; + o.default = '8080'; + o.rmempty = false; + + o = s.option(form.Value, 'profile_dir', _('Configuration files Path')); + o.default = '/etc/qbittorrent'; + o.rmempty = false; + + return m.render(); + } +}); diff --git a/luci-app-qbittorrent/po/zh_Hans/qbittorrent.po b/luci-app-qbittorrent/po/zh_Hans/qbittorrent.po new file mode 100644 index 00000000..7d4c8037 --- /dev/null +++ b/luci-app-qbittorrent/po/zh_Hans/qbittorrent.po @@ -0,0 +1,26 @@ +msgid "qBittorrent" +msgstr "qBittorrent" + +msgid "Running state" +msgstr "è¿è¡Œçжæ€" + +msgid "Open Web Interface" +msgstr "打开 Web 界é¢" + +msgid "qBittorrent is a cross-platform free and open-source BitTorrent client. Default username & password: admin / adminadmin" +msgstr "qBittorrent 是一个基于 QT 的跨平å°çš„å¼€æº BitTorrent 客户端。默认用户å & 密ç ï¼šadmin / adminadmin" + +msgid "WebUI Listen port" +msgstr "WebUI 监å¬ç«¯å£" + +msgid "Configuration files Path" +msgstr "é…置文件路径" + +msgid "RUNNING" +msgstr "è¿è¡Œä¸­" + +msgid "NOT RUNNING" +msgstr "未è¿è¡Œ" + +msgid "Collecting data..." +msgstr "收集数æ®..." diff --git a/luci-app-qbittorrent/root/etc/uci-defaults/qbittorrent b/luci-app-qbittorrent/root/etc/uci-defaults/qbittorrent new file mode 100755 index 00000000..c2df97cf --- /dev/null +++ b/luci-app-qbittorrent/root/etc/uci-defaults/qbittorrent @@ -0,0 +1,13 @@ +#!/bin/sh + +[ -f "/etc/config/ucitrack" ] && { +uci -q batch <<-EOF >/dev/null + delete ucitrack.@qbittorrent[-1] + add ucitrack qbittorrent + set ucitrack.@qbittorrent[-1].init=qbittorrent + commit ucitrack +EOF +} + +rm -f /tmp/luci-indexcache* +exit 0 diff --git a/luci-app-qbittorrent/root/usr/share/luci/menu.d/luci-app-qbittorrent.json b/luci-app-qbittorrent/root/usr/share/luci/menu.d/luci-app-qbittorrent.json new file mode 100644 index 00000000..f6ed76f8 --- /dev/null +++ b/luci-app-qbittorrent/root/usr/share/luci/menu.d/luci-app-qbittorrent.json @@ -0,0 +1,14 @@ +{ + "admin/services/qbittorrent": { + "title": "qBittorrent", + "order": 20, + "action": { + "type": "view", + "path": "qbittorrent" + }, + "depends": { + "acl": [ "luci-app-qbittorrent" ], + "uci": { "qbittorrent": true } + } + } +} diff --git a/luci-app-qbittorrent/root/usr/share/rpcd/acl.d/luci-app-qbittorrent.json b/luci-app-qbittorrent/root/usr/share/rpcd/acl.d/luci-app-qbittorrent.json new file mode 100644 index 00000000..5d8c1f25 --- /dev/null +++ b/luci-app-qbittorrent/root/usr/share/rpcd/acl.d/luci-app-qbittorrent.json @@ -0,0 +1,14 @@ +{ + "luci-app-qbittorrent": { + "description": "Grant UCI access for luci-app-qbittorrent", + "read": { + "ubus": { + "service": [ "list" ] + }, + "uci": [ "qbittorrent" ] + }, + "write": { + "uci": [ "qbittorrent" ] + } + } +} diff --git a/luci-app-qbittorrent/root/usr/share/ucitrack/luci-app-qbittorrent.json b/luci-app-qbittorrent/root/usr/share/ucitrack/luci-app-qbittorrent.json new file mode 100644 index 00000000..817358fb --- /dev/null +++ b/luci-app-qbittorrent/root/usr/share/ucitrack/luci-app-qbittorrent.json @@ -0,0 +1,4 @@ +{ + "config": "qbittorrent", + "init": "qbittorrent" +} diff --git a/luci-app-smartdns/Makefile b/luci-app-smartdns/Makefile new file mode 100644 index 00000000..ea5d973d --- /dev/null +++ b/luci-app-smartdns/Makefile @@ -0,0 +1,35 @@ +# +# Copyright 2018-2025 Nick Peng +# Licensed to the public under the GPL V3 License. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-smartdns +PKG_VERSION:=1.2025.47.2 +PKG_RELEASE:=2 + +PKG_LICENSE:=GPL-3.0-or-later +PKG_MAINTAINER:=Nick Peng + +LUCI_TITLE:=LuCI for smartdns +LUCI_DESCRIPTION:=Provides Luci for smartdns +LUCI_PKGARCH:=all +LUCI_DEPENDS:=+luci-base +smartdns \ + +PACKAGE_$(PKG_NAME)_INCLUDE_smartdns_ui:smartdns-ui + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME)/config +# shown in make menuconfig +help + $(LUCI_TITLE) + Version: $(PKG_VERSION)-$(PKG_RELEASE) + +config PACKAGE_$(PKG_NAME)_INCLUDE_smartdns_ui + bool "Include smartdns-ui" + default n +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-smartdns/ReadMe.md b/luci-app-smartdns/ReadMe.md new file mode 100644 index 00000000..51475a32 --- /dev/null +++ b/luci-app-smartdns/ReadMe.md @@ -0,0 +1,101 @@ +# luci-app-smartdns + +此仓库为smartdns独立仓库,为å•独编译使用, 在安装此界é¢å‰ï¼Œéœ€è¦å…ˆå®‰è£…smartdns进程编译脚本。 +请先安装[openwrt-smartdns](https://github.com/pymumu/openwrt-smartdns) + +仓库分为两个分支 + +1. master分支为openwrt 19.07之åŽç‰ˆæœ¬ä½¿ç”¨ï¼Œæ­¤ç‰ˆæœ¬åŸºäºŽjavascript。 +2. lede分支为lede分支使用, 此版本基于lua。 + +使用时,请使用é…套的版本。 + +## ä½¿ç”¨æ–¹å¼ + +如下命令æ“作路径为openwrtæºä»£ç æ‰€åœ¨ç›®å½•。 + +### å¤åˆ¶ä»“库中的文件到如下目录,并执行安装 + +```shell +feeds/luci/applications/luci-app-smartdns/ +./scripts/feeds install luci -a +``` + +> lede请下载lede分支 + +### 执行openwrté…ç½®, 选中luci-app-smartdns + +* 选择路径: + +LuCI > 3. Applications > luci-app-smartdns + +```shell +make menuconfig +``` + +* 编译模å¼ï¼š + +1. 若编译独立软件包,选择编译模å¼ä¸º`M` +1. 若编译到固件中,选择编译模å¼ä¸º`*` + +### 执行openwrt编译 + +仅编译软件包: + +```shell +make package/feeds/luci/applications/luci-app-smartdns/compile +``` + +编译固件以åŠè½¯ä»¶åŒ…。 + +```shell +make -j8 +``` + +## 懒人脚本 + +坿‰§è¡Œå¦‚下命令,一次性下载smartdns以åŠluci-app-smartdns。 +下列命令å¯é‡‡ç”¨å¤åˆ¶ç²˜è´´çš„æ–¹å¼æ‰§è¡Œã€‚ + +注æ„事项: + +1. 执行下列命令时,需è¦ç¡®ä¿å½“å‰è·¯å¾„为openwrt代ç è·¯å¾„。 +1. ç¡®ä¿æ‰§è¡Œè¿‡./scripts/feeds进行更新。 +1. 若是LEDE,请更æ¢`LUCIBRANCH`å˜é‡ä¸º + +```shell +LUCIBRANCH="lede" +``` + +批é‡å‘½ä»¤ï¼š + +```shell +WORKINGDIR="`pwd`/feeds/packages/net/smartdns" +mkdir $WORKINGDIR -p +rm $WORKINGDIR/* -fr +wget https://github.com/pymumu/openwrt-smartdns/archive/master.zip -O $WORKINGDIR/master.zip +unzip $WORKINGDIR/master.zip -d $WORKINGDIR +mv $WORKINGDIR/openwrt-smartdns-master/* $WORKINGDIR/ +rmdir $WORKINGDIR/openwrt-smartdns-master +rm $WORKINGDIR/master.zip + +LUCIBRANCH="master" #æ›´æ¢æ­¤å˜é‡ +WORKINGDIR="`pwd`/feeds/luci/applications/luci-app-smartdns" +mkdir $WORKINGDIR -p +rm $WORKINGDIR/* -fr +wget https://github.com/pymumu/luci-app-smartdns/archive/${LUCIBRANCH}.zip -O $WORKINGDIR/${LUCIBRANCH}.zip +unzip $WORKINGDIR/${LUCIBRANCH}.zip -d $WORKINGDIR +mv $WORKINGDIR/luci-app-smartdns-${LUCIBRANCH}/* $WORKINGDIR/ +rmdir $WORKINGDIR/luci-app-smartdns-${LUCIBRANCH} +rm $WORKINGDIR/${LUCIBRANCH}.zip + +./scripts/feeds install -a +make menuconfig + +``` + +下载完æˆåŽï¼Œæ‰§è¡Œé…置编译。 + +## 注æ„事项 + +如果安装完æˆåŽï¼Œæœªç”Ÿæ•ˆï¼Œå¯ä»¥é‡å¯è®¾å¤‡ï¼Œæ¸…空æµè§ˆå™¨ç¼“å­˜ï¼Œæˆ–ç”¨å®‰å…¨æ¨¡å¼æµè§ˆã€‚ \ No newline at end of file diff --git a/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/log.js b/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/log.js new file mode 100644 index 00000000..ff8c95f7 --- /dev/null +++ b/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/log.js @@ -0,0 +1,160 @@ +/************************************************************************* + * + * Copyright (C) 2018-2025 Ruilin Peng (Nick) . + * + * smartdns is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * smartdns is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +'use strict'; +'require dom'; +'require fs'; +'require poll'; +'require uci'; +'require view'; +'require form'; +'require ui'; + +return view.extend({ + render: function () { + var css = ` + #log_textarea { + margin-top: 10px; + } + #log_textarea pre { + background-color: #f7f7f7; + color: #333; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + font-family: Consolas, Menlo, Monaco, monospace; + font-size: 14px; + line-height: 1.5; + white-space: pre-wrap; + word-wrap: break-word; + overflow-y: auto; + max-height: 650px; + } + #.description { + background-color: #33ccff; + } + .cbi-button-danger { + background-color: #fff; + color: #f00; + border: 1px solid #f00; + border-radius: 4px; + padding: 4px 8px; + font-size: 14px; + cursor: pointer; + margin-top: 10px; + } + .cbi-button-danger:hover { + background-color: #f00; + color: #fff; + } + .cbi-section small { + margin-left: 10px; + } + .cbi-section .cbi-section-actions { + margin-top: 10px; + } + .cbi-section .cbi-section-actions-right { + text-align: right; + } + `; + + + var log_textarea = E('div', { 'id': 'log_textarea' }, + E('img', { + 'src': L.resource(['icons/loading.gif']), + 'alt': _('Loading...'), + 'style': 'vertical-align:middle' + }, _('Collecting data ...')) + ); + + var clear_log_button = E('th', {}, [ + E('button', { + 'class': 'cbi-button cbi-button-remove', + 'click': function (ev) { + ev.preventDefault(); + var button = ev.target; + button.disabled = true; + button.textContent = _('Clear Logs...'); + fs.exec('/usr/libexec/smartdns-call', ['clear_log']) + .then(function () { + button.textContent = _('Logs cleared successfully!'); + setTimeout(function () { + button.disabled = false; + button.textContent = _('Clear Logs'); + }, 5000); + // Immediately refresh log display box + var log = E('pre', { 'wrap': 'pre' }, [_('Log is clean.')]); + dom.content(log_textarea, log); + }) + .catch(function () { + button.textContent = _('Failed to clear log.'); + setTimeout(function () { + button.disabled = false; + button.textContent = _('Clear Logs'); + }, 5000); + }); + } + }, _('Clear Logs')) + ]); + + + poll.add(L.bind(function () { + return fs.exec('/usr/libexec/smartdns-call', ['tail']) + .then(function (res) { + var log = E('pre', { 'wrap': 'pre' }, [res.stdout.trim() || _('Log is clean.')]); + + dom.content(log_textarea, log); + log.scrollTop = log.scrollHeight; + }).catch(function (err) { + var log; + + if (err.toString().includes('NotFoundError')) { + log = E('pre', { 'wrap': 'pre' }, [_('Log file does not exist.')]); + } else { + log = E('pre', { 'wrap': 'pre' }, [_('Unknown error: %s').format(err)]); + } + + dom.content(log_textarea, log); + }); + })); + + var back_smartdns_button = E('th', {}, [ + E('button', { + 'class': 'cbi-button cbi-button-apply', + 'click': ui.createHandlerFn(this, function () { + window.location.href = "/cgi-bin/luci/admin/services/smartdns" + }) + }, _('Back SmartDNS')) + ]); + + return E('div', { 'class': 'cbi-map' }, [ + E('style', [css]), + E('div', { 'class': 'cbi-section' }, [ + clear_log_button, + back_smartdns_button, + log_textarea, + E('small', {}, _('Refresh every %s seconds.').format(L.env.pollinterval)), + E('div', { 'class': 'cbi-section-actions cbi-section-actions-right' }) + ]) + ]); + }, + + handleSaveApply: null, + handleSave: null, + handleReset: null +}); diff --git a/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js b/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js new file mode 100644 index 00000000..3366bf6c --- /dev/null +++ b/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js @@ -0,0 +1,1792 @@ +/************************************************************************* + * + * Copyright (C) 2018-2025 Ruilin Peng (Nick) . + * + * smartdns is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * smartdns is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +'use strict'; +'require fs'; +'require uci'; +'require form'; +'require view'; +'require poll'; +'require rpc'; +'require ui'; + +var conf = 'smartdns'; +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); +var pollAdded = false; + +function getServiceStatus() { + return L.resolveDefault(callServiceList(conf), {}) + .then(function (res) { + var is_running = false; + try { + is_running = res[conf]['instances']['smartdns']['running']; + } catch (e) { } + return is_running; + }); +} + +function smartdnsServiceStatus() { + return Promise.all([ + getServiceStatus() + ]); +} + +function smartdnsRenderStatus(res) { + var renderHTML = ""; + var isRunning = res[0]; + + var autoSetDnsmasq = uci.get_first('smartdns', 'smartdns', 'auto_set_dnsmasq'); + var smartdnsPort = uci.get_first('smartdns', 'smartdns', 'port'); + var smartdnsEnable = uci.get_first('smartdns', 'smartdns', 'enabled'); + var dnsmasqServer = uci.get_first('dhcp', 'dnsmasq', 'server'); + + var uiEnable = uci.get_first('smartdns', 'smartdns', 'ui') || "0"; + var uiPort = uci.get_first('smartdns', 'smartdns', 'ui_port') || "6080"; + + if (isRunning) { + renderHTML += "SmartDNS - " + _("RUNNING") + ""; + + if (uiEnable === '1') { + var protocol = window.location.protocol; + var hostname = window.location.hostname; + var uiLink = protocol + "//" + hostname + ":" + uiPort; + renderHTML += '  ' + _("Open the WebUI") + ''; + } + } else { + renderHTML += "SmartDNS - " + _("NOT RUNNING") + ""; + if (smartdnsEnable === '1') { + renderHTML += "
" + _("Please check the system logs and check if the configuration is valid."); + renderHTML += ""; + } + return renderHTML; + } + + if (autoSetDnsmasq === '1' && smartdnsPort != '53') { + var matchLine = "127.0.0.1#" + smartdnsPort; + + uci.unload('dhcp'); + uci.load('dhcp'); + if (dnsmasqServer == undefined || dnsmasqServer.indexOf(matchLine) < 0) { + renderHTML += "
" + _("Dnsmasq Forwarded To Smartdns Failure") + ""; + } + } + + return renderHTML; +} + +function isSmartdnsUiAvailable() { + return fs.stat('/usr/lib/smartdns_ui.so').then(function (res) { + return res && res.type === 'file'; + }).catch(function () { + return false; + }); +} + +return view.extend({ + load: function () { + return Promise.all([ + uci.load('dhcp'), + uci.load('smartdns'), + isSmartdnsUiAvailable() + ]); + }, + render: function (stats) { + var m, s, o; + var ss, so; + var servers, download_files; + var hasUi = stats[2]; + + m = new form.Map('smartdns', _('SmartDNS')); + m.title = _("SmartDNS Server"); + m.description = _("SmartDNS is a local high-performance DNS server, supports finding fastest IP, " + + "supports ad filtering, and supports avoiding DNS poisoning."); + + s = m.section(form.NamedSection, '_status'); + s.anonymous = true; + s.render = function (section_id) { + var renderStatus = function () { + return L.resolveDefault(smartdnsServiceStatus()).then(function (res) { + var view = document.getElementById("service_status"); + if (view == null) { + return; + } + + view.innerHTML = smartdnsRenderStatus(res); + }); + } + + if (pollAdded == false) { + poll.add(renderStatus, 1); + pollAdded = true; + } + + return E('div', { class: 'cbi-section' }, [ + E('div', { id: 'service_status' }, + _('Collecting data ...')) + ]); + } + + //////////////// + // Basic; + //////////////// + s = m.section(form.TypedSection, "smartdns", _("Settings"), _("General Settings")); + s.anonymous = true; + + s.tab("settings", _("General Settings")); + s.tab("advanced", _('Advanced Settings')); + s.tab("seconddns", _("Second Server Settings")); + s.tab("dns64", _("DNS64 Server Settings")); + s.tab("files", _("Download Files Setting"), _("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect.")); + s.tab("proxy", _("Proxy Server Settings")); + s.tab("custom", _("Custom Settings")); + + /////////////////////////////////////// + // Basic Settings + /////////////////////////////////////// + o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server")); + o.rmempty = false; + o.default = o.disabled; + + // server name; + o = s.taboption("settings", form.Value, "server_name", _("Server Name"), _("Smartdns server name")); + o.placeholder = "server name"; + o.datatype = "hostname"; + o.rempty = true; + + // Port; + o = s.taboption("settings", form.Value, "port", _("Local Port"), + _("Smartdns local server port, smartdns will be automatically set as main dns when the port is 53.")); + o.placeholder = 53; + o.default = 53; + o.datatype = "port"; + o.rempty = false; + + // auto-conf-dnsmasq; + o = s.taboption("settings", form.Flag, "auto_set_dnsmasq", _("Automatically Set Dnsmasq"), _("Automatically set as upstream of dnsmasq when port changes.")); + o.rmempty = false; + o.default = o.enabled; + + //WebUI + if (hasUi) { + o = s.taboption("settings", form.Flag, "ui", _("Enable WebUI"), _("Enable or disable smartdns webui plugin.")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("settings", form.Value, "ui_port", _("WebUI Port"), _("WebUI server port.")); + o.placeholder = 6080; + o.datatype = "port"; + o.rempty = false; + o.depends('ui', '1'); + + o = s.taboption("settings", form.Value, "ui_data_dir", _("WebUI Data Dir"), _("Directory for storing the webui database.")); + o.placeholder = "/var/lib/smartdns"; + o.datatype = "string"; + o.rempty = false; + o.depends('ui', '1'); + + o = s.taboption("settings", form.Value, "ui_log_max_age", _("WebUI Log Retention"), _("Number of days to retain webui logs.")); + o.placeholder = 30; + o.datatype = "uinteger"; + o.rempty = false; + o.depends('ui', '1'); + } + + /////////////////////////////////////// + // advanced settings; + /////////////////////////////////////// + // Speed check mode; + o = s.taboption("advanced", form.Value, "speed_check_mode", _("Speed Check Mode"), _("Smartdns speed check mode.")); + o.rmempty = true; + o.placeholder = "default"; + o.value("", _("default")); + o.value("ping,tcp:80,tcp:443"); + o.value("ping,tcp:443,tcp:80"); + o.value("tcp:80,tcp:443,ping"); + o.value("tcp:443,tcp:80,ping"); + o.value("tcp-syn:80,tcp-syn:443,ping"); + o.value("tcp-syn:443,tcp-syn:80,ping"); + o.value("none", _("None")); + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (value == "none") { + return true; + } + + var check_mode = value.split(","); + for (var i = 0; i < check_mode.length; i++) { + var mode = check_mode[i]; + + if (mode == "ping") { + continue; + } + + if (mode.indexOf("tcp:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP port is empty"); + } + continue; + } + + if (mode.indexOf("tcp-syn:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP SYN port is empty"); + } + continue; + } + + return _("Speed check mode is invalid."); + } + + return true; + } + + // response mode; + o = s.taboption("advanced", form.ListValue, "response_mode", _("Response Mode"), + _("Smartdns response mode, First Ping: return the first ping IP, Fastest IP: return the fastest IP, Fastest Response: return the fastest DNS response.")); + o.rmempty = true; + o.placeholder = "default"; + o.value("", _("default")); + o.value("first-ping", _("First Ping")); + o.value("fastest-ip", _("Fastest IP")); + o.value("fastest-response", _("Fastest Response")); + + // Enable TCP server; + o = s.taboption("advanced", form.Flag, "tcp_server", _("TCP Server"), _("Enable TCP DNS Server")); + o.rmempty = false; + o.default = o.enabled; + + // Enable DOT server; + o = s.taboption("advanced", form.Flag, "tls_server", _("DOT Server"), _("Enable DOT DNS Server")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("advanced", form.Value, "tls_server_port", _("DOT Server Port"), _("Smartdns DOT server port.")); + o.placeholder = 853; + o.default = 853; + o.datatype = "port"; + o.rempty = false; + o.depends('tls_server', '1'); + + // Enable DOH server; + o = s.taboption("advanced", form.Flag, "doh_server", _("DOH Server"), _("Enable DOH DNS Server")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("advanced", form.Value, "doh_server_port", _("DOH Server Port"), _("Smartdns DOH server port.")); + o.placeholder = 843; + o.default = 843; + o.datatype = "port"; + o.rempty = false; + o.depends('doh_server', '1'); + + o = s.taboption("advanced", form.Value, "bind_cert", _("Server Cert"), _("Server certificate file path.")); + o.datatype = "string"; + o.placeholder = "/var/etc/smartdns/smartdns/smartdns-cert.pem" + o.rempty = true; + o.depends('tls_server', '1'); + o.depends('doh_server', '1'); + + o = s.taboption("advanced", form.Value, "bind_cert_key", _("Server Cert Key"), _("Server certificate key file path.")); + o.datatype = "string"; + o.placeholder = "/var/etc/smartdns/smartdns/smartdns-key.pem" + o.rempty = false; + o.depends('tls_server', '1'); + o.depends('doh_server', '1'); + + o = s.taboption("advanced", form.Value, "bind_cert_key_pass", _("Server Cert Key Pass"), _("Server certificate key file password.")); + o.datatype = "string"; + o.rempty = false; + o.depends('tls_server', '1'); + o.depends('doh_server', '1'); + + // Support IPv6; + o = s.taboption("advanced", form.Flag, "ipv6_server", _("IPv6 Server"), _("Enable IPv6 DNS Server")); + o.rmempty = false; + o.default = o.enabled; + + // bind to device; + o = s.taboption("advanced", form.Flag, "bind_device", _("Bind Device"), _("Listen only on the specified interfaces.")); + o.rmempty = false; + o.default = o.enabled; + + // bind device name; + o = s.taboption("advanced", form.Value, "bind_device_name", _("Bind Device Name"), _("Name of device name listen on.")); + o.placeholder = "default"; + o.rempty = true; + o.datatype = "string"; + + // Support DualStack ip selection; + o = s.taboption("advanced", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"), + _("Enable IP selection between IPv4 and IPv6")); + o.rmempty = false; + o.default = o.enabled; + + // Domain prefetch load ; + o = s.taboption("advanced", form.Flag, "prefetch_domain", _("Domain prefetch"), + _("Enable domain prefetch, accelerate domain response speed.")); + o.rmempty = true; + o.default = o.disabled; + + // Domain Serve expired + o = s.taboption("advanced", form.Flag, "serve_expired", _("Serve expired"), + _("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish.")); + o.rmempty = false; + o.default = o.enabled; + + // cache-size; + o = s.taboption("advanced", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size")); + o.rempty = true; + + // cache-persist; + o = s.taboption("advanced", form.Flag, "cache_persist", _("Cache Persist"), _("Write cache to disk on exit and load on startup.")); + o.rmempty = false; + o.default = o.enabled; + + // resolve local hostname; + o = s.taboption("advanced", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file.")); + o.rmempty = false; + o.default = o.enabled; + + // resolve local network hostname via mDNS; + o = s.taboption("advanced", form.Flag, "mdns_lookup", _("mDNS Lookup"), _("Resolve local network hostname via mDNS protocol.")); + o.rmempty = true; + o.default = o.disabled; + + // Force AAAA SOA + o = s.taboption("advanced", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o.rmempty = true; + o.default = o.disabled; + + // Force HTTPS SOA + o = s.taboption("advanced", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA.")); + o.rmempty = false; + o.default = o.enabled; + + // ipset name; + o = s.taboption("advanced", form.Value, "ipset_name", _("IPset Name"), _("IPset name.")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var ipset = value.split(",") + for (var i = 0; i < ipset.length; i++) { + if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) { + return _("ipset name format error, format: [#[4|6]:]ipsetname"); + } + } + + return true; + } + + // Ipset no speed. + o = s.taboption("advanced", form.Value, "ipset_no_speed", _("No Speed IPset Name"), + _("Ipset name, Add domain result to ipset when speed check fails.")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var ipset = value.split(",") + for (var i = 0; i < ipset.length; i++) { + if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) { + return _("ipset name format error, format: [#[4|6]:]ipsetname"); + } + } + + return true; + } + + // NFTset name; + o = s.taboption("advanced", form.Value, "nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + // NFTset no speed. + o = s.taboption("advanced", form.Value, "nftset_no_speed", _("No Speed NFTset Name"), + _("Nftset name, Add domain result to nftset when speed check fails, format: [#[4|6]:[family#table#set]]")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + // rr-ttl; + o = s.taboption("advanced", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result.")); + o.rempty = true; + + // rr-ttl-min; + o = s.taboption("advanced", form.Value, "rr_ttl_min", _("Domain TTL Min"), + _("Minimum TTL for all domain result.")); + o.rempty = true; + o.placeholder = "600"; + o.default = 600; + o.optional = true; + + // rr-ttl-max; + o = s.taboption("advanced", form.Value, "rr_ttl_max", _("Domain TTL Max"), + _("Maximum TTL for all domain result.")); + o.rempty = true; + + // rr-ttl-reply-max; + o = s.taboption("advanced", form.Value, "rr_ttl_reply_max", _("Reply Domain TTL Max"), + _("Reply maximum TTL for all domain result.")); + o.rempty = true; + + // other args + o = s.taboption("advanced", form.Value, "server_flags", _("Additional Server Args"), + _("Additional server args, refer to the help description of the bind option.")) + o.default = "" + o.rempty = true + + // include config + download_files = uci.sections('smartdns', 'download-file'); + o = s.taboption("advanced", form.DynamicList, "conf_files", _("Include Config Files
/etc/smartdns/conf.d"), + _("Include other config files from /etc/smartdns/conf.d or custom path, can be downloaded from the download page.")); + for (var i = 0; i < download_files.length; i++) { + if (download_files[i].type == undefined) { + continue; + } + + if (download_files[i].type != 'config') { + continue + } + + o.value(download_files[i].name); + } + + o = s.taboption("advanced", form.DynamicList, "hosts_files", _("Hosts File"), _("Include hosts file.")); + o.rmempty = true; + for (var i = 0; i < download_files.length; i++) { + if (download_files[i].type == undefined) { + continue; + } + + if (download_files[i].type != 'other') { + continue + } + + o.value(download_files[i].name); + } + + /////////////////////////////////////// + // second dns server; + /////////////////////////////////////// + // Enable; + o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"), + _("Enable or disable second DNS server.")); + o.default = o.disabled; + o.rempty = true; + + // Port; + o = s.taboption("seconddns", form.Value, "seconddns_port", _("Local Port"), _("Smartdns local server port")); + o.placeholder = 6553; + o.default = 6553; + o.datatype = "port"; + o.rempty = false; + + // Enable TCP server; + o = s.taboption("seconddns", form.Flag, "seconddns_tcp_server", _("TCP Server"), _("Enable TCP DNS Server")); + o.rmempty = false; + o.default = o.enabled; + + // dns server group; + o = s.taboption("seconddns", form.Value, "seconddns_server_group", _("Server Group"), + _("Query DNS through specific dns server group, such as office, home.")); + o.rmempty = true; + o.placeholder = "default"; + o.datatype = "hostname"; + o.rempty = true; + + o = s.taboption("seconddns", form.Flag, "seconddns_no_speed_check", _("Skip Speed Check"), + _("Do not check speed.")); + o.rmempty = true; + o.default = o.disabled; + + // skip address rules; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_addr", _("Skip Address Rules"), + _("Skip address rules.")); + o.rmempty = true; + o.default = o.disabled; + + // skip name server rules; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_nameserver", _("Skip Nameserver Rule"), + _("Skip nameserver rules.")); + o.rmempty = true; + o.default = o.disabled; + + // skip ipset rules; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_ipset", _("Skip Ipset Rule"), + _("Skip ipset rules.")); + o.rmempty = true; + o.default = o.disabled; + + // skip soa address rule; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_soa", _("Skip SOA Address Rule"), + _("Skip SOA address rules.")); + o.rmempty = true; + o.default = o.disabled; + + o = s.taboption("seconddns", form.Flag, "seconddns_no_dualstack_selection", _("Skip Dualstack Selection"), + _("Skip Dualstack Selection.")); + o.rmempty = true; + o.default = o.disabled; + + // skip cache; + o = s.taboption("seconddns", form.Flag, "seconddns_no_cache", _("Skip Cache"), _("Skip Cache.")); + o.rmempty = true; + o.default = o.disabled; + + // Force AAAA SOA + o = s.taboption("seconddns", form.Flag, "seconddns_force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o.rmempty = true; + o.default = o.disabled; + + // Force HTTPS SOA + o = s.taboption("seconddns", form.Flag, "seconddns_force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA.")); + o.rmempty = true; + o.default = o.disabled; + + o = s.taboption("seconddns", form.Flag, "seconddns_no_ip_alias", _("Skip IP Alias")); + o.rmempty = true; + o.default = o.disabled; + + o = s.taboption("seconddns", form.Value, "seconddns_ipset_name", _("IPset Name"), _("IPset name.")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var ipset = value.split(",") + for (var i = 0; i < ipset.length; i++) { + if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) { + return _("ipset name format error, format: [#[4|6]:]ipsetname"); + } + } + + return true; + } + + o = s.taboption("seconddns", form.Value, "seconddns_nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + // other args + o = s.taboption("seconddns", form.Value, "seconddns_server_flags", _("Additional Server Args"), + _("Additional server args, refer to the help description of the bind option.")) + o.default = "" + o.rempty = true + + /////////////////////////////////////// + // DNS64 Settings + /////////////////////////////////////// + o = s.taboption("dns64", form.Value, "dns64", _("DNS64")); + o.placeholder = "64:ff9b::/96"; + o.datatype = "ip6addr"; + o.rempty = true; + + /////////////////////////////////////// + // download Files Settings + /////////////////////////////////////// + o = s.taboption("files", form.Flag, "enable_auto_update", _("Enable Auto Update"), _("Enable daily (weekly) auto update.")); + o.rmempty = true; + o.default = o.disabled; + o.rempty = true; + + o = s.taboption("files", form.ListValue, "auto_update_week_time", _("Update Time (Every Week)")); + o.value('*', _('Every Day')); + o.value('1', _('Every Monday')); + o.value('2', _('Every Tuesday')); + o.value('3', _('Every Wednesday')); + o.value('4', _('Every Thursday')); + o.value('5', _('Every Friday')); + o.value('6', _('Every Saturday')); + o.value('0', _('Every Sunday')); + o.default = "*"; + o.depends('enable_auto_update', '1'); + + o = s.taboption('files', form.ListValue, 'auto_update_day_time', _("Update time (every day)")); + for (var i = 0; i < 24; i++) + o.value(i, i + ':00'); + o.default = '5'; + o.depends('enable_auto_update', '1'); + + o = s.taboption("files", form.FileUpload, "upload_conf_file", _("Upload Config File"), + _("Upload smartdns config file to /etc/smartdns/conf.d")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.root_directory = "/etc/smartdns/conf.d" + + o = s.taboption("files", form.FileUpload, "upload_list_file", _("Upload Domain List File"), + _("Upload domain list file to /etc/smartdns/domain-set")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.root_directory = "/etc/smartdns/domain-set" + + o = s.taboption("files", form.FileUpload, "upload_other_file", _("Upload File")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.root_directory = "/etc/smartdns/download" + + o = s.taboption('files', form.DummyValue, "_update", _("Update Files")); + o.renderWidget = function () { + return E('button', { + 'class': 'btn cbi-button cbi-button-apply', + 'id': 'btn_update', + 'click': ui.createHandlerFn(this, function () { + return fs.exec('/etc/init.d/smartdns', ['updatefiles']) + .catch(function (e) { ui.addNotification(null, E('p', e.message), 'error') }); + }) + }, [_("Update")]); + } + + o = s.taboption('files', form.SectionValue, '__files__', form.GridSection, 'download-file', _('Download Files'), + _('List of files to download.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + + so = ss.option(form.Value, 'name', _('File Name'), _('File Name')); + so.rmempty = true; + so.datatype = 'file'; + + so = ss.option(form.Value, 'url', _('URL'), _('URL')); + so.rmempty = true; + so.datatype = 'string'; + so.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (!value.match(/^(http|https|ftp|sftp):\/\//)) { + return _("URL format error, format: http:// or https://"); + } + + return true; + } + + so = ss.option(form.ListValue, "type", _("type"), _("File Type")); + so.value("list", _("domain list (/etc/smartdns/domain-set)")); + so.value("config", _("smartdns config (/etc/smartdns/conf.d)")); + so.value("ip-set", _("ip-set file (/etc/smartdns/ip-set)")); + so.value("other", _("other file (/etc/smartdns/download)")); + so.default = "list"; + so.rempty = false; + + so = ss.option(form.Value, 'desc', _('Description'), _('Description')); + so.rmempty = true; + so.datatype = 'string'; + + /////////////////////////////////////// + // Proxy server settings; + /////////////////////////////////////// + o = s.taboption("proxy", form.Value, "proxy_server", _("Proxy Server"), _("Proxy Server URL, format: [socks5|http]://user:pass@ip:port.")); + o.datatype = 'string'; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (!value.match(/^(socks5|http):\/\//)) { + return _("Proxy server URL format error, format: [socks5|http]://user:pass@ip:port."); + } + + return true; + } + + /////////////////////////////////////// + // custom settings; + /////////////////////////////////////// + o = s.taboption("custom", form.TextValue, "custom_conf", + "", _("smartdns custom settings")); + o.rows = 20; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/custom.conf'); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/custom.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + o = s.taboption("custom", form.Flag, "coredump", _("Generate Coredump"), + _("Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core.")); + o.rmempty = true; + o.default = o.disabled; + + o = s.taboption("custom", form.ListValue, "log_level", _("Log Level")); + o.rmempty = true; + o.default = ""; + o.value("", _("default")); + o.value("debug"); + o.value("info"); + o.value("notice"); + o.value("warn"); + o.value("error"); + o.value("fatal"); + o.value("off"); + + o = s.taboption("custom", form.ListValue, "log_output_mode", _("Log Output Mode")); + o.rmempty = true; + o.default = "file"; + o.value("file", _("file")); + o.value("syslog", _("syslog")); + + o = s.taboption("custom", form.Value, "log_size", _("Log Size")); + o.rmempty = true; + o.placeholder = "default"; + o.depends("log_output_mode", "file"); + + o = s.taboption("custom", form.Value, "log_num", _("Log Number")); + o.rmempty = true; + o.placeholder = "default"; + o.depends("log_output_mode", "file"); + + o = s.taboption("custom", form.Value, "log_file", _("Log File")) + o.rmempty = true + o.placeholder = "/var/log/smartdns/smartdns.log" + o.depends("log_output_mode", "file"); + + o = s.taboption("custom", form.DummyValue, "view_log", _("View Log")); + o.renderWidget = function () { + return E('button', { + 'class': 'btn cbi-button', + 'id': 'btn_view_log', + 'click': ui.createHandlerFn(this, function () { + window.location.href = "/cgi-bin/luci/admin/services/smartdns/log"; + }) + }, [_("View Log")]); + } + var log_levels = ["debug", "info", "notice", "warn", "error", "fatal"]; + log_levels.forEach(function(level) { + o.depends({ log_output_mode: "file", log_level: level }); + }); + + o = s.taboption("custom", form.Flag, "enable_audit_log", _("Enable Audit Log")); + o.rmempty = true; + o.default = o.disabled; + o.rempty = true; + + o = s.taboption("custom", form.ListValue, "audit_log_output_mode", _("Audit Log Output Mode")); + o.rmempty = true; + o.default = "file"; + o.value("file", _("file")); + o.value("syslog", _("syslog")); + o.depends("enable_audit_log", "1"); + + o = s.taboption("custom", form.Value, "audit_log_size", _("Audit Log Size")); + o.rmempty = true; + o.placeholder = "default"; + o.depends({"enable_audit_log":"1", "audit_log_output_mode":"file"}); + + o = s.taboption("custom", form.Value, "audit_log_num", _("Audit Log Number")); + o.rmempty = true; + o.placeholder = "default"; + o.depends({"enable_audit_log":"1", "audit_log_output_mode":"file"}); + + o = s.taboption("custom", form.Value, "audit_log_file", _("Audit Log File")) + o.rmempty = true + o.placeholder = "/var/log/smartdns/smartdns-audit.log" + o.depends({"enable_audit_log":"1", "audit_log_output_mode":"file"}); + + //////////////// + // Upstream servers; + //////////////// + s = m.section(form.GridSection, "server", _("Upstream Servers"), + _("Upstream Servers, support UDP, TCP, DoT, DoH, DoQ, DoH3 protocol. Please configure multiple DNS servers, " + + "including multiple foreign DNS servers.")); + s.anonymous = true; + s.addremove = true; + s.sortable = true; + + s.tab('general', _('General Settings')); + s.tab('advanced', _('Advanced Settings')); + + // enable flag; + o = s.taboption("general", form.Flag, "enabled", _("Enable"), _("Enable")); + o.rmempty = false; + o.default = o.enabled; + o.editable = true; + + // name; + o = s.taboption("general", form.Value, "name", _("DNS Server Name"), _("DNS Server Name")); + + // IP address; + o = s.taboption("general", form.Value, "ip", _("ip"), _("DNS Server ip")); + o.datatype = "or(ipaddr, string)"; + o.rmempty = false; + + // port; + o = s.taboption("general", form.Value, "port", _("port"), _("DNS Server port")); + o.placeholder = "default"; + o.datatype = "port"; + o.rempty = true; + o.depends("type", "udp"); + o.depends("type", "tcp"); + o.depends("type", "tls"); + o.depends("type", "quic"); + + // type; + o = s.taboption("general", form.ListValue, "type", _("type"), _("DNS Server type")); + o.placeholder = "udp"; + o.value("udp", _("udp")); + o.value("tcp", _("tcp")); + o.value("tls", _("tls")); + o.value("https", _("https")); + o.value("quic", _("quic")); + o.value("h3", _("h3")); + o.default = "udp"; + o.rempty = false; + + // server group + o = s.taboption("general", form.Value, "server_group", _("Server Group"), _("DNS Server group")) + o.rmempty = true; + o.placeholder = "default"; + o.datatype = "hostname"; + o.rempty = true; + servers = uci.sections('smartdns', 'server'); + var groupnames = new Set(); + for (var i = 0; i < servers.length; i++) { + if (servers[i].server_group == undefined) { + continue; + } + groupnames.add(servers[i].server_group); + } + + for (const groupname of groupnames) { + o.value(groupname); + } + + // Advanced Options + o = s.taboption("advanced", form.Flag, "exclude_default_group", _("Exclude Default Group"), _("Exclude DNS Server from default group.")) + o.rmempty = true; + o.default = o.disabled; + o.editable = true; + o.modalonly = true; + + // blacklist_ip + o = s.taboption("advanced", form.Flag, "blacklist_ip", _("IP Blacklist Filtering"), + _("Filtering IP with blacklist")) + o.rmempty = true + o.default = o.disabled + o.modalonly = true; + + // TLS host verify + o = s.taboption("advanced", form.Value, "tls_host_verify", _("TLS Hostname Verify"), + _("Set TLS hostname to verify.")) + o.default = "" + o.datatype = "string" + o.rempty = true + o.modalonly = true; + o.depends("type", "tls"); + o.depends("type", "https"); + o.depends("type", "quic"); + o.depends("type", "h3"); + + // certificate verify + o = s.taboption("advanced", form.Flag, "no_check_certificate", _("No check certificate"), + _("Do not check certificate.")) + o.rmempty = true + o.default = o.disabled + o.modalonly = true; + o.depends("type", "tls"); + o.depends("type", "https"); + o.depends("type", "quic"); + o.depends("type", "h3"); + + // SNI host name + o = s.taboption("advanced", form.Value, "host_name", _("TLS SNI name"), + _("Sets the server name indication for query. '-' for disable SNI name.")) + o.default = "" + o.datatype = "hostname" + o.rempty = true + o.modalonly = true; + o.depends("type", "tls"); + o.depends("type", "https"); + o.depends("type", "quic"); + o.depends("type", "h3"); + + // http host + o = s.taboption("advanced", form.Value, "http_host", _("HTTP Host"), + _("Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address.")) + o.default = "" + o.datatype = "hostname" + o.rempty = true + o.modalonly = true; + o.depends("type", "https"); + o.depends("type", "h3"); + + // SPKI pin + o = s.taboption("advanced", form.Value, "spki_pin", _("TLS SPKI Pinning"), + _("Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, " + + "leaving blank to indicate that the validity of TLS is not verified.")) + o.default = "" + o.datatype = "string" + o.rempty = true + o.modalonly = true; + o.depends("type", "tls"); + o.depends("type", "https"); + o.depends("type", "quic"); + o.depends("type", "h3"); + + // mark + o = s.taboption("advanced", form.Value, "set_mark", _("Marking Packets"), + _("Set mark on packets.")) + o.default = "" + o.rempty = true + o.datatype = "uinteger" + o.modalonly = true; + + // use proxy + o = s.taboption("advanced", form.Flag, "use_proxy", _("Use Proxy"), + _("Use proxy to connect to upstream DNS server.")) + o.default = o.disabled + o.modalonly = true; + o.optional = true; + o.rempty = true; + o.validate = function (section_id, value) { + var flag = this.formvalue(section_id); + if (flag == "0") { + return true; + } + + var proxy_server = uci.sections("smartdns", "smartdns")[0].proxy_server; + var server_type = this.section.formvalue(section_id, "type"); + if (proxy_server == "" || proxy_server == undefined) { + return _("Please set proxy server first."); + } + + if (server_type == "udp" && !proxy_server.match(/^(socks5):\/\//)) { + return _("Only socks5 proxy support udp server."); + } + + return true; + } + + // fallback + o = s.taboption("advanced", form.Flag, "fallback", _("Fallback"), + _("Mark this server as a fallback server, use it only when default servers fail.")) + o.default = o.disabled + o.rmempty = true + o.modalonly = true + + // other args + o = s.taboption("advanced", form.Value, "addition_arg", _("Additional Server Args"), + _("Additional Args for upstream dns servers")) + o.default = "" + o.rempty = true + o.modalonly = true; + + //////////////// + // client rules; + //////////////// + s = m.section(form.TypedSection, "client-rule", _("Client Rules"), _("Client Rules Settings, can achieve parental control functionality.")); + s.anonymous = true; + s.nodescriptions = true; + + s.tab("basic", _('Basic Settings')); + s.tab("advanced", _('Advanced Settings')); + s.tab("block", _("DNS Block Setting")); + + o = s.taboption("basic", form.Flag, "enabled", _("Enable")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("basic", form.DynamicList, "client_addr", _("Client Address"), + _("If a client address is specified, only that client will apply this rule. You can enter an IP address, such as 1.2.3.4, or a MAC address, such as aa:bb:cc:dd:ee:ff.")); + o.rempty = true + o.rmempty = true; + o.modalonly = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (value.match(/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/([0-9]|[1-2][0-9]|3[0-2]))?$/)) { + return true; + } + + if (value.match(/^([a-fA-F0-9]*:){1,7}[a-fA-F0-9]*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$/)) { + return true; + } + + if (value.match(/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/)) { + return true; + } + + return _("Client address format error, please input ip adress or mac address."); + } + + o = s.taboption("basic", form.FileUpload, "client_addr_file", _("Client Address File"), + _("Upload client address file, same as Client Address function.")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.modalonly = true; + o.root_directory = "/etc/smartdns/ip-set" + + o = s.taboption("basic", form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, such as office, home.")) + o.rmempty = true + o.placeholder = "default" + o.datatype = "hostname" + o.rempty = true + for (const groupname of groupnames) { + o.value(groupname); + } + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var val = uci.sections('smartdns', 'server'); + for (var i = 0; i < val.length; i++) { + if (value == val[i].server_group) { + return true; + } + } + + return _('Server Group %s not exists').format(value); + + } + + // Speed check mode; + o = s.taboption("advanced", form.Value, "speed_check_mode", _("Speed Check Mode"), _("Smartdns speed check mode.")); + o.rmempty = true; + o.placeholder = "default"; + o.value("", _("default")); + o.value("ping,tcp:80,tcp:443"); + o.value("ping,tcp:443,tcp:80"); + o.value("tcp:80,tcp:443,ping"); + o.value("tcp:443,tcp:80,ping"); + o.value("tcp-syn:80,tcp-syn:443,ping"); + o.value("tcp-syn:443,tcp-syn:80,ping"); + o.value("none", _("None")); + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (value == "none") { + return true; + } + + var check_mode = value.split(","); + for (var i = 0; i < check_mode.length; i++) { + var mode = check_mode[i]; + + if (mode == "ping") { + continue; + } + + if (mode.indexOf("tcp:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP port is empty"); + } + continue; + } + + if (mode.indexOf("tcp-syn:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP SYN port is empty"); + } + continue; + } + + return _("Speed check mode is invalid."); + } + + return true; + } + + // Support DualStack ip selection; + o = s.taboption("advanced", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"), + _("Enable IP selection between IPv4 and IPv6")); + o.rmempty = false; + o.default = o.enabled; + + // Force AAAA SOA + o = s.taboption("advanced", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o.rmempty = true; + o.default = o.disabled; + + // Force HTTPS SOA + o = s.taboption("advanced", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA.")); + o.rmempty = false; + o.default = o.enabled; + + // ipset name; + o = s.taboption("advanced", form.Value, "ipset_name", _("IPset Name"), _("IPset name.")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var ipset = value.split(",") + for (var i = 0; i < ipset.length; i++) { + if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) { + return _("ipset name format error, format: [#[4|6]:]ipsetname"); + } + } + + return true; + } + + // NFTset name; + o = s.taboption("advanced", form.Value, "nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + // include config + download_files = uci.sections('smartdns', 'download-file'); + o = s.taboption("advanced", form.DynamicList, "conf_files", _("Include Config Files
/etc/smartdns/conf.d"), + _("Include other config files from /etc/smartdns/conf.d or custom path, can be downloaded from the download page.")); + for (var i = 0; i < download_files.length; i++) { + if (download_files[i].type == undefined) { + continue; + } + + if (download_files[i].type != 'config') { + continue + } + + o.value(download_files[i].name); + } + + o = s.taboption("block", form.FileUpload, "block_domain_set_file", _("Domain List File"), _("Upload domain list file.")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.editable = true + o.root_directory = "/etc/smartdns/domain-set" + + + //////////////// + // domain rules; + //////////////// + s = m.section(form.TypedSection, "domain-rule", _("Domain Rules"), _("Domain Rules Settings")); + s.anonymous = true; + s.nodescriptions = true; + + s.tab("forwarding", _('DNS Forwarding Setting')); + s.tab("block", _("DNS Block Setting")); + s.tab("domain-rule-list", _("Domain Rule List"), _("Set Specific domain rule list.")); + s.tab("domain-address", _("Domain Address"), _("Set Specific domain ip address.")); + + /////////////////////////////////////// + // domain forwarding; + /////////////////////////////////////// + o = s.taboption("forwarding", form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, such as office, home.")) + o.rmempty = true + o.placeholder = "default" + o.datatype = "hostname" + o.rempty = true + for (const groupname of groupnames) { + o.value(groupname); + } + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var val = uci.sections('smartdns', 'server'); + for (var i = 0; i < val.length; i++) { + if (value == val[i].server_group) { + return true; + } + } + + return _('Server Group %s not exists').format(value); + + } + + // Speed check mode; + o = s.taboption("forwarding", form.Value, "speed_check_mode", _("Speed Check Mode"), _("Smartdns speed check mode.")); + o.rmempty = true; + o.placeholder = "default"; + o.value("", _("default")); + o.value("ping,tcp:80,tcp:443"); + o.value("ping,tcp:443,tcp:80"); + o.value("tcp:80,tcp:443,ping"); + o.value("tcp:443,tcp:80,ping"); + o.value("tcp-syn:80,tcp-syn:443,ping"); + o.value("tcp-syn:443,tcp-syn:80,ping"); + o.value("none", _("None")); + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (value == "none") { + return true; + } + + var check_mode = value.split(","); + for (var i = 0; i < check_mode.length; i++) { + var mode = check_mode[i]; + + if (mode == "ping") { + continue; + } + + if (mode.indexOf("tcp:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP port is empty"); + } + continue; + } + + if (mode.indexOf("tcp-syn:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP SYN port is empty"); + } + continue; + } + + return _("Speed check mode is invalid."); + } + + return true; + } + + // Support DualStack ip selection; + o = s.taboption("forwarding", form.ListValue, "dualstack_ip_selection", _("Dual-stack IP Selection"), + _("Enable IP selection between IPv4 and IPv6")); + o.rmempty = true; + o.default = "default"; + o.modalonly = true; + o.value("", _("default")); + o.value("yes", _("Yes")); + o.value("no", _("No")); + + o = s.taboption("forwarding", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o.rmempty = true; + o.default = o.disabled; + + o = s.taboption("forwarding", form.Value, "ipset_name", _("IPset Name"), _("IPset name.")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var ipset = value.split(",") + for (var i = 0; i < ipset.length; i++) { + if (!ipset[i].match(/^(#[4|6]:)?[a-zA-Z0-9\-_]+$/)) { + return _("ipset name format error, format: [#[4|6]:]ipsetname"); + } + } + + return true; + } + + o = s.taboption("forwarding", form.Value, "nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/^#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + // other args + o = s.taboption("forwarding", form.Value, "addition_flag", _("Additional Rule Flag"), + _("Additional Flags for rules, read help on domain-rule for more information.")) + o.default = "" + o.rempty = true + o.modalonly = true; + + o = s.taboption("forwarding", form.FileUpload, "forwarding_domain_set_file", _("Domain List File"), + _("Upload domain list file, or configure auto download from Download File Setting page.")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.editable = true + o.root_directory = "/etc/smartdns/domain-set" + + o = s.taboption("forwarding", form.TextValue, "domain_forwarding_list", + _("Domain List"), _("Configure forwarding domain name list.")); + o.rows = 10; + o.cols = 64; + o.monospace = true; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/domain-forwarding.list').catch(function (e) { + return ""; + }); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/domain-forwarding.list', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + /////////////////////////////////////// + // domain block; + /////////////////////////////////////// + o = s.taboption("block", form.FileUpload, "block_domain_set_file", _("Domain List File"), _("Upload domain list file.")); + o.rmempty = true + o.datatype = "file" + o.rempty = true + o.editable = true + o.root_directory = "/etc/smartdns/domain-set" + + o = s.taboption("block", form.TextValue, "domain_block_list", + _("Domain List"), _("Configure block domain list.")); + o.rows = 10; + o.cols = 64; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/domain-block.list').catch(function (e) { + return ""; + }); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/domain-block.list', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + /////////////////////////////////////// + // domain rule list; + /////////////////////////////////////// + o = s.taboption('domain-rule-list', form.SectionValue, '__domain-rule-list__', form.GridSection, 'domain-rule-list', _('Domain Rule List'), + _('Configure domain rule list.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + + // enable flag; + so = ss.option(form.Flag, "enabled", _("Enable"), _("Enable")); + so.rmempty = false; + so.default = so.enabled; + so.editable = true; + + // name; + so = ss.option(form.Value, "name", _("Domain Rule Name"), _("Domain Rule Name")); + + so = ss.option(form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, such as office, home.")) + so.rmempty = true + so.placeholder = "default" + so.datatype = "hostname" + so.rempty = true + for (const groupname of groupnames) { + so.value(groupname); + } + so.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var val = uci.sections('smartdns', 'server'); + for (var i = 0; i < val.length; i++) { + if (value == val[i].server_group) { + return true; + } + } + + return _('Server Group %s not exists').format(value); + + } + + so = ss.option(form.FileUpload, "domain_list_file", _("Domain List File"), + _("Upload domain list file, or configure auto download from Download File Setting page.")); + so.rmempty = true + so.datatype = "file" + so.rempty = true + so.root_directory = "/etc/smartdns/domain-set" + + so = ss.option(form.ListValue, "block_domain_type", _("Block domain"), _("Block domain.")); + so.rmempty = true; + so.value("none", _("None")); + so.value("all", "IPv4/IPv6"); + so.value("ipv4", "IPv4"); + so.value("ipv6", "IPv6"); + so.modalonly = true; + + // Support DualStack ip selection; + so = ss.option(form.ListValue, "dualstack_ip_selection", _("Dual-stack IP Selection"), + _("Enable IP selection between IPv4 and IPv6")); + so.rmempty = true; + so.default = "default"; + so.modalonly = true; + so.value("", _("default")); + so.value("yes", _("Yes")); + so.value("no", _("No")); + + so = ss.option(form.Value, "speed_check_mode", _("Speed Check Mode"), _("Smartdns speed check mode.")); + so.rmempty = true; + so.placeholder = "default"; + so.modalonly = true; + so.value("", _("default")); + so.value("ping,tcp:80,tcp:443"); + so.value("ping,tcp:443,tcp:80"); + so.value("tcp:80,tcp:443,ping"); + so.value("tcp:443,tcp:80,ping"); + so.value("tcp-syn:80,tcp-syn:443,ping"); + so.value("tcp-syn:443,tcp-syn:80,ping"); + so.value("none", _("None")); + so.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (value == "none") { + return true; + } + + var check_mode = value.split(","); + for (var i = 0; i < check_mode.length; i++) { + var mode = check_mode[i]; + + if (mode == "ping") { + continue; + } + + if (mode.indexOf("tcp:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP port is empty"); + } + continue; + } + + if (mode.indexOf("tcp-syn:") == 0) { + var port = mode.split(":")[1]; + if (port == "") { + return _("TCP SYN port is empty"); + } + continue; + } + + return _("Speed check mode is invalid."); + } + + return true; + } + + so = ss.option(form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + so.rmempty = true; + so.default = so.disabled; + so.modalonly = true; + + + so = ss.option(form.Value, "ipset_name", _("IPset Name"), _("IPset name.")); + so.rmempty = true; + so.datatype = "hostname"; + so.rempty = true; + so.modalonly = true; + + so = ss.option(form.Value, "nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]")); + so.rmempty = true; + so.datatype = "string"; + so.rempty = true; + so.modalonly = true; + so.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + // other args + so = ss.option(form.Value, "addition_flag", _("Additional Rule Flag"), + _("Additional Flags for rules, read help on domain-rule for more information.")) + so.default = "" + so.rempty = true + so.modalonly = true; + + /////////////////////////////////////// + // domain address + /////////////////////////////////////// + o = s.taboption("domain-address", form.TextValue, "address_conf", + "", + _("Specify an IP address to return for any host in the given domains, Queries in the domains are never " + + "forwarded and always replied to with the specified IP address which may be IPv4 or IPv6.")); + o.rows = 20; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/address.conf'); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/address.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + + //////////////// + // ip rules; + //////////////// + s = m.section(form.TypedSection, "ip-rule", _("IP Rules"), _("IP Rules Settings")); + s.anonymous = true; + s.nodescriptions = true; + + s.tab("ip-rule-list", _("IP Rule List"), _("Set Specific ip rule list.")); + s.tab("blackip-list", _("IP Blacklist"), _("Set Specific ip blacklist.")); + + /////////////////////////////////////// + // ip rule list; + /////////////////////////////////////// + o = s.taboption('ip-rule-list', form.SectionValue, '__ip-rule-list__', form.GridSection, 'ip-rule-list', _('IP Rule List'), + _('Configure ip rule list.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + + // enable flag; + so = ss.option(form.Flag, "enabled", _("Enable"), _("Enable")); + so.rmempty = false; + so.default = so.enabled; + so.editable = true; + + // name; + so = ss.option(form.Value, "name", _("IP Rule Name"), _("IP Rule Name")); + so.rmempty = true; + so.datatype = "string"; + + so = ss.option(form.FileUpload, "ip_set_file", _("IP Set File"), _("Upload IP set file.")); + so.rmempty = true + so.datatype = "file" + so.modalonly = true; + so.root_directory = "/etc/smartdns/ip-set" + + so = ss.option(form.DynamicList, "ip_addr", _("IP Addresses"), _("IP addresses, CIDR format.")); + so.rmempty = true; + so.datatype = "ipaddr" + so.modalonly = true; + + so = ss.option(form.Flag, "whitelist_ip", _("Whitelist IP"), _("Whitelist IP Rule, Accept IP addresses within the range.")); + so.rmempty = true; + so.default = so.disabled; + so.modalonly = true; + + so = ss.option(form.Flag, "blacklist_ip", _("Blacklist IP"), _("Blacklist IP Rule, Decline IP addresses within the range.")); + so.rmempty = true; + so.default = so.disabled; + so.modalonly = true; + + so = ss.option(form.Flag, "ignore_ip", _("Ignore IP"), _("Do not use these IP addresses.")); + so.rmempty = true; + so.default = so.disabled; + so.modalonly = true; + + so = ss.option(form.Flag, "bogus_nxdomain", _("Bogus nxdomain"), _("Return SOA when the requested result contains a specified IP address.")); + so.rmempty = true; + so.default = so.disabled; + so.modalonly = true; + + so = ss.option(form.DynamicList, "ip_alias", _("IP alias"), _("IP Address Mapping, Can be used for CDN acceleration with Anycast IP, such as Cloudflare's CDN.")); + so.rmempty = true; + so.datatype = 'ipaddr("nomask")'; + so.modalonly = true; + + // other args + so = ss.option(form.Value, "addition_flag", _("Additional Rule Flag"), + _("Additional Flags for rules, read help on ip-rule for more information.")) + so.default = "" + so.rempty = true + so.modalonly = true; + /////////////////////////////////////// + // IP Blacklist; + /////////////////////////////////////// + // blacklist; + o = s.taboption("blackip-list", form.TextValue, "blackip_ip_conf", + "", _("Configure IP blacklists that will be filtered from the results of specific DNS server.")); + o.rows = 20; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/blacklist-ip.conf'); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/blacklist-ip.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + //////////////// + // Support + //////////////// + s = m.section(form.TypedSection, "smartdns", _("Technical Support"), + _("If you like this software, please buy me a cup of coffee.")); + s.anonymous = true; + + o = s.option(form.Button, "web"); + o.title = _("SmartDNS official website"); + o.inputtitle = _("open website"); + o.inputstyle = "apply"; + o.onclick = function () { + window.open("https://pymumu.github.io/smartdns", '_blank'); + }; + + o = s.option(form.Button, "report"); + o.title = _("Report bugs"); + o.inputtitle = _("Report bugs"); + o.inputstyle = "apply"; + o.onclick = function () { + window.open("https://github.com/pymumu/smartdns/issues", '_blank'); + }; + + o = s.option(form.Button, "Donate"); + o.title = _("Donate to smartdns"); + o.inputtitle = _("Donate"); + o.inputstyle = "apply"; + o.onclick = function () { + window.open("https://pymumu.github.io/smartdns/#donate", '_blank'); + }; + + o = s.option(form.DummyValue, "_restart", _("Restart Service")); + o.renderWidget = function () { + return E('button', { + 'class': 'btn cbi-button cbi-button-apply', + 'id': 'btn_restart', + 'click': ui.createHandlerFn(this, function () { + return fs.exec('/etc/init.d/smartdns', ['restart']) + .catch(function (e) { ui.addNotification(null, E('p', e.message), 'error') }); + }) + }, [_("Restart")]); + } + return m.render(); + } +}); diff --git a/luci-app-smartdns/po/de/smartdns.po b/luci-app-smartdns/po/de/smartdns.po new file mode 100644 index 00000000..cd5aadfd --- /dev/null +++ b/luci-app-smartdns/po/de/smartdns.po @@ -0,0 +1,946 @@ +msgid "" +msgstr "" +"PO-Revision-Date: 2023-02-28 10:31+0000\n" +"Last-Translator: oneforfun \n" +"Language-Team: German \n" +"Language: de\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.16-dev\n" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:792 +msgid "Additional Args for upstream dns servers" +msgstr "Zusätzliche Argumente für Upstream-DNS-Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:886 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1090 +msgid "" +"Additional Flags for rules, read help on domain-rule for more information." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:885 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1089 +msgid "Additional Rule Flag" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:346 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:479 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:791 +msgid "Additional Server Args" +msgstr "Zusätzliche Server Parameter" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:347 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:480 +msgid "" +"Additional server args, refer to the help description of the bind option." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:132 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:639 +msgid "Advanced Settings" +msgstr "Erweiterte Einstellungen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:253 +msgid "" +"Attempts to serve old responses from cache with a TTL of 0 in the response " +"without waiting for the actual resolution to finish." +msgstr "" +"Versuche, eine alte Antwort vom Cache mit TTL 0 zurückzugeben, ohne auf die " +"eigentliche Auflösung zu warten." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically Set Dnsmasq" +msgstr "Dnsmasq automatisch setzen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically set as upstream of dnsmasq when port changes." +msgstr "Setze automatisch als Upstream von dnsmasq when sich der Port ändert." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Bind Device" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Bind Device Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Cache Persist" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "Cache Size" +msgstr "Zwischenspeichergröße" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:121 +msgid "Collecting data ..." +msgstr "Sammle Daten..." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1100 +msgid "" +"Configure IP blacklists that will be filtered from the results of specific " +"DNS server." +msgstr "" +"Definition einer IP basierten Blockierliste, welche Ergebnisse eines " +"spezifischen DNS Servers filtert." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Configure block domain list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:950 +msgid "Configure domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +msgid "Configure forwarding domain name list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:137 +msgid "Custom Settings" +msgstr "Benutzerdefinierte Einstellungen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:805 +msgid "DNS Block Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:804 +msgid "DNS Forwarding Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:648 +msgid "DNS Server Name" +msgstr "DNS Server Name" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +msgid "DNS Server group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "DNS Server group belongs to, such as office, home." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "DNS Server ip" +msgstr "DNS-Server IP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "DNS Server port" +msgstr "DNS-Server-Port" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "DNS Server type" +msgstr "DNS-Server Typ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "DNS domain result cache size" +msgstr "DNS Domain Ergebnisspeichergröße" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:487 +msgid "DNS64" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:134 +msgid "DNS64 Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:560 +msgid "Description" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:76 +msgid "Dnsmasq Forwarded To Smartdns Failure" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:719 +msgid "Do not check certificate." +msgstr "Zertifikat nicht prüfen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:397 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:838 +msgid "Do not check speed." +msgstr "Geschwindigkeit nicht testen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Domain Address" +msgstr "Domain Adresse" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Domain List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:891 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:991 +msgid "Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:949 +msgid "Domain Rule List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:965 +msgid "Domain Rule Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "Domain TTL" +msgstr "Domäne TTL" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:336 +msgid "Domain TTL Max" +msgstr "Domäne TTL Max" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:328 +msgid "Domain TTL Min" +msgstr "Domäne TTL Min" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:246 +msgid "Domain prefetch" +msgstr "Vorabruf der Domäne" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1159 +msgid "Donate" +msgstr "Spenden" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1158 +msgid "Donate to smartdns" +msgstr "An smartdns spenden" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:526 +msgid "Download Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "Download Files Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:240 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1007 +msgid "Dual-stack IP Selection" +msgstr "Dual-Stack-IP-Auswahl" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:371 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:642 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:959 +msgid "Enable" +msgstr "aktivieren" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable Auto Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:241 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1008 +msgid "Enable IP selection between IPv4 and IPv6" +msgstr "Aktiviere Wahl zwischen IPv4 und IPv6" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "Enable IPv6 DNS Server" +msgstr "Aktivere IPv6 DNS-Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "Enable TCP DNS Server" +msgstr "Aktiviere TCP DNS Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable daily auto update." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:247 +msgid "Enable domain prefetch, accelerate domain response speed." +msgstr "" +"Aktivieren Sie Domänen-Prefetch, um die Reaktionsgeschwindigkeit der Domäne " +"zu beschleunigen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:372 +msgid "Enable or disable second DNS server." +msgstr "Aktivieren oder deaktivieren des zweiten DNS-Servers." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +msgid "Enable or disable smartdns server" +msgstr "Aktivieren oder deaktivieren des Smartdns-Servers" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude DNS Server from default group." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude Default Group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:215 +msgid "Fastest IP" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:216 +msgid "Fastest Response" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:535 +msgid "File Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +msgid "File Type" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:702 +msgid "Filtering IP with blacklist" +msgstr "Filtern von IP mit negativ-Liste" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:214 +msgid "First Ping" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA" +msgstr "Erzwinge AAAA SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA." +msgstr "Erzwinge AAAA SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA" +msgstr "Erzwinge HTTPS SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA." +msgstr "Erzwinge HTTPS SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:131 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:638 +msgid "General Settings" +msgstr "Allgemeine Einstellungen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:599 +msgid "Generate Coredump" +msgstr "Generiere Coredump" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:600 +msgid "" +"Generate Coredump file when smartdns crash, coredump file is located at /tmp/" +"smartdns.xxx.core." +msgstr "" +"Erzeugt eine Coredump-Datei, wenn smartdns abstürzt. Die Coredump-Datei " +"befindet sich unter /tmp/smartdns.xxx.core." + +#: applications/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json:3 +msgid "Grant access to LuCI app smartdns" +msgstr "Zugriff auf die LuCI-App smartdns gewähren" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:737 +msgid "HTTP Host" +msgstr "HTTP-Host" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "IP Blacklist" +msgstr "IP Negativ-Liste" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:701 +msgid "IP Blacklist Filtering" +msgstr "Filterung von IP-Blacklists" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "IPv6 Server" +msgstr "IPv6-Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1138 +msgid "If you like this software, please buy me a cup of coffee." +msgstr "" +"Wenn Ihnen diese Software gefällt, spendieren Sie mir bitte eine Tasse " +"Kaffee." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:353 +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:354 +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:283 +msgid "Ipset name, Add domain result to ipset when speed check fails." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:527 +msgid "List of files to download." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Listen only on the specified interfaces." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:153 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Local Port" +msgstr "Lokaler Port" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:624 +msgid "Log File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:608 +msgid "Log Level" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:620 +msgid "Log Number" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:604 +msgid "Log Size" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:757 +msgid "Marking Packets" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:337 +msgid "Maximum TTL for all domain result." +msgstr "Maximale TTL für alle Ergebnisse der Domäne." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:329 +msgid "Minimum TTL for all domain result." +msgstr "Minimale TTL für alle Ergebnisse der Domäne." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:316 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:471 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:877 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1081 +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:66 +msgid "NOT RUNNING" +msgstr "LÄUFT NICHT" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Name of device name listen on." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:304 +msgid "" +"Nftset name, Add domain result to nftset when speed check fails, format: " +"[#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1014 +msgid "No" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:282 +msgid "No Speed IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:303 +msgid "No Speed NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:718 +msgid "No check certificate" +msgstr "Kein Check der Zertifikate" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:177 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1000 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1025 +msgid "None" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:784 +msgid "Only socks5 proxy support udp server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:780 +msgid "Please set proxy server first." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:136 +msgid "Proxy Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server URL, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:575 +msgid "" +"Proxy server URL format error, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:390 +msgid "Query DNS through specific dns server group, such as office, home." +msgstr "" +"Abfrage von DNS über eine bestimmte DNS-Servergruppe, z. B. Büro, Zuhause." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:64 +msgid "RUNNING" +msgstr "LÄUFT" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:341 +msgid "Reply Domain TTL Max" +msgstr "Max TTL der Antwortdomäne" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:342 +msgid "Reply maximum TTL for all domain result." +msgstr "Maximale Antwort-TTL für alle Domänen-Ergebnisse." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1150 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1151 +msgid "Report bugs" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve Local Hostnames" +msgstr "Lokale Hostnamen auflösen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve local hostnames by reading Dnsmasq lease file." +msgstr "Lokale Hostnamen durch Lesen der Dnsmasq-Lease-Datei auflösen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:209 +msgid "Response Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1174 +msgid "Restart" +msgstr "Neustart" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1165 +msgid "Restart Service" +msgstr "Dienst neu starten" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:133 +msgid "Second Server Settings" +msgstr "Einstellungen für den zweiten Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:252 +msgid "Serve expired" +msgstr "Serve abgelaufen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:389 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "Server Group" +msgstr "Servergruppe" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:833 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:987 +msgid "Server Group %s not exists" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Server Name" +msgstr "Servername" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Set Specific domain ip address." +msgstr "Spezifische Domänen-IP-Adresse einstellen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +msgid "Set Specific domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "Set Specific ip blacklist." +msgstr "Spezifische IP-Blacklist einstellen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:709 +msgid "Set TLS hostname to verify." +msgstr "TLS-Hostname zur Überprüfung einstellen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:758 +msgid "Set mark on packets." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:738 +msgid "" +"Set the HTTP host used for the query. Use this parameter when the host of " +"the URL address is an IP address." +msgstr "" +"Legt den für die Abfrage verwendeten HTTP-Host fest. Verwenden Sie diesen " +"Parameter, wenn der Host der URL-Adresse eine IP-Adresse ist." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:728 +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +msgid "Settings" +msgstr "Einstellungen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:402 +msgid "Skip Address Rules" +msgstr "Adressregeln überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache" +msgstr "Cache überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache." +msgstr "Cache überspringen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:425 +msgid "Skip Dualstack Selection" +msgstr "Dualstack-Auswahl überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:426 +msgid "Skip Dualstack Selection." +msgstr "Dualstack-Auswahl überspringen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:414 +msgid "Skip Ipset Rule" +msgstr "Ipset-Regel überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:408 +msgid "Skip Nameserver Rule" +msgstr "Nameserver-Regel überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:420 +msgid "Skip SOA Address Rule" +msgstr "SOA-Adressregel überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:421 +msgid "Skip SOA address rules." +msgstr "SOA-Adressregeln überspringen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:396 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:837 +msgid "Skip Speed Check" +msgstr "Geschwindigkeitsprüfung überspringen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:403 +msgid "Skip address rules." +msgstr "Adressregeln überspringen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:415 +msgid "Skip ipset rules." +msgstr "ipset-Regeln überspringen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:409 +msgid "Skip nameserver rules." +msgstr "Nameserver-Regeln überspringen." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:95 +#: applications/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json:3 +msgid "SmartDNS" +msgstr "SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:96 +msgid "SmartDNS Server" +msgstr "SmartDNS-Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:97 +msgid "" +"SmartDNS is a local high-performance DNS server, supports finding fastest " +"IP, supports ad filtering, and supports avoiding DNS poisoning." +msgstr "" +"SmartDNS ist ein lokaler Hochleistungs-DNS-Server, der die Suche nach der " +"schnellsten IP unterstützt, die Filterung von Werbung und die Vermeidung von " +"DNS-Poisoning ermöglicht." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1142 +msgid "SmartDNS official website" +msgstr "Offizielle Website von SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Smartdns local server port" +msgstr "Lokaler Smartdns-Serverport" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:154 +msgid "" +"Smartdns local server port, smartdns will be automatically set as main dns " +"when the port is 53." +msgstr "" +"Lokaler Smartdns-Serverport, smartdns wird automatisch als Haupt-DNS " +"eingestellt, wenn 53 der Port ist." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:210 +msgid "" +"Smartdns response mode, First Ping: return the first ping IP, Fastest IP: " +"return the fastest IP, Fastest Response: return the fastest DNS response." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Smartdns server name" +msgstr "Smartdns-Servername" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Smartdns speed check mode." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1119 +msgid "" +"Specify an IP address to return for any host in the given domains, Queries " +"in the domains are never forwarded and always replied to with the specified " +"IP address which may be IPv4 or IPv6." +msgstr "" +"Geben Sie eine IP-Adresse an, die für einen beliebigen Host in den " +"angegebenen Domänen zurückgegeben werden soll. Abfragen in den Domänen " +"werden nie weitergeleitet und immer mit der angegebenen IP-Adresse " +"beantwortet, die IPv4 oder IPv6 sein kann." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Speed Check Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:202 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1050 +msgid "Speed check mode is invalid." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "TCP Server" +msgstr "TCP-Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:196 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1044 +msgid "TCP port is empty" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:708 +msgid "TLS Hostname Verify" +msgstr "Überprüfung des TLS-Hostnamens" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:727 +msgid "TLS SNI name" +msgstr "TLS-SNI-Name" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:746 +msgid "TLS SPKI Pinning" +msgstr "TLS-SPKI-Pinning" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "TTL for all domain result." +msgstr "TTL für alle Domänenergebnisse." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1137 +msgid "Technical Support" +msgstr "Technische Unterstützung" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:539 +msgid "URL" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:548 +msgid "URL format error, format: http:// or https://" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:523 +msgid "Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:514 +msgid "Update Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:500 +msgid "Upload Config File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:507 +msgid "Upload Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:508 +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:892 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:992 +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +msgid "Upload domain list file." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:501 +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:631 +msgid "Upstream Servers" +msgstr "Upstream-Server" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:632 +msgid "" +"Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS " +"servers, including multiple foreign DNS servers." +msgstr "" +"Upstream-Server, die die Protokolle UDP und TCP unterstützen. Bitte " +"konfigurieren Sie mehrere DNS-Server, einschließlich mehrerer ausländischer " +"DNS-Server." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:765 +msgid "Use Proxy" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:766 +msgid "Use proxy to connect to upstream DNS server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:747 +msgid "" +"Used to verify the validity of the TLS server, The value is Base64 encoded " +"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not " +"verified." +msgstr "" +"Wird verwendet, um die Gültigkeit des TLS-Servers zu überprüfen. Der Wert " +"ist ein Base64-kodierter SPKI-Fingerabdruck, leer lassen bedeutet, dass die " +"Gültigkeit von TLS nicht überprüft wird." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Write cache to disk on exit and load on startup." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1013 +msgid "Yes" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:172 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:213 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:611 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1012 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1020 +msgid "default" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:555 +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:670 +msgid "https" +msgstr "https" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "ip" +msgstr "IP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:295 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:452 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:858 +msgid "ipset name format error, format: [#[4|6]:]ipsetname" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1143 +msgid "open website" +msgstr "Webseite öffnen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "port" +msgstr "Port" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:556 +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:585 +msgid "smartdns custom settings" +msgstr "Benutzerdefinierte SmartDNS-Einstellungen" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:668 +msgid "tcp" +msgstr "tcp" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:669 +msgid "tls" +msgstr "tls" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "type" +msgstr "Typ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:667 +msgid "udp" +msgstr "udp" + +#~ msgid "" +#~ "DNS Server group belongs to, used with nameserver, such as office, home." +#~ msgstr "" +#~ "DNS-Server-Gruppe, zu jener der Nameserver gehört, z. B. Büro, Zuhause." + +#~ msgid "Dnsmasq Forwared To Smartdns Failure" +#~ msgstr "Fehler der Dnsmasq-Weiterleitung an Smartdns" + +#~ msgid "Sets the server name indication for query." +#~ msgstr "Legt die Anzeige des Servernamens für die Abfrage fest." + +#~ msgid "none" +#~ msgstr "kein" diff --git a/luci-app-smartdns/po/es/smartdns.po b/luci-app-smartdns/po/es/smartdns.po new file mode 100644 index 00000000..1207c435 --- /dev/null +++ b/luci-app-smartdns/po/es/smartdns.po @@ -0,0 +1,1000 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2020-07-02 17:20-0300\n" +"PO-Revision-Date: 2023-02-26 00:30+0000\n" +"Last-Translator: gallegonovato \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.16-dev\n" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:792 +msgid "Additional Args for upstream dns servers" +msgstr "Args adicionales para servidores DNS aguas arriba" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:886 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1090 +msgid "" +"Additional Flags for rules, read help on domain-rule for more information." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:885 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1089 +msgid "Additional Rule Flag" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:346 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:479 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:791 +msgid "Additional Server Args" +msgstr "Args adicionales del servidor" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:347 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:480 +msgid "" +"Additional server args, refer to the help description of the bind option." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:132 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:639 +msgid "Advanced Settings" +msgstr "Configuración avanzada" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:253 +msgid "" +"Attempts to serve old responses from cache with a TTL of 0 in the response " +"without waiting for the actual resolution to finish." +msgstr "" +"Intenta servir respuestas antiguas de la memoria caché con un TTL de 0 en la " +"respuesta sin esperar a que finalice la resolución real." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically Set Dnsmasq" +msgstr "Establecer Dnsmasq automáticamente" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically set as upstream of dnsmasq when port changes." +msgstr "" +"Establecido automáticamente como conexión ascendente de dnsmasq cuando " +"cambia el puerto." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Bind Device" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Bind Device Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Cache Persist" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "Cache Size" +msgstr "Tamaño del caché" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:121 +msgid "Collecting data ..." +msgstr "Recolectando datos..." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1100 +msgid "" +"Configure IP blacklists that will be filtered from the results of specific " +"DNS server." +msgstr "" +"Configure listas negras de IP que se filtrarán de los resultados de un " +"servidor DNS específico." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Configure block domain list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:950 +msgid "Configure domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +msgid "Configure forwarding domain name list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:137 +msgid "Custom Settings" +msgstr "Configuraciones personalizadas" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:805 +msgid "DNS Block Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:804 +msgid "DNS Forwarding Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:648 +msgid "DNS Server Name" +msgstr "Nombre del servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +msgid "DNS Server group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "DNS Server group belongs to, such as office, home." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "DNS Server ip" +msgstr "IP del servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "DNS Server port" +msgstr "Puerto del servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "DNS Server type" +msgstr "Tipo de servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "DNS domain result cache size" +msgstr "Tamaño del caché de resultados del dominio DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:487 +msgid "DNS64" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:134 +msgid "DNS64 Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:560 +msgid "Description" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:76 +msgid "Dnsmasq Forwarded To Smartdns Failure" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:719 +msgid "Do not check certificate." +msgstr "No verifique el certificado." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:397 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:838 +msgid "Do not check speed." +msgstr "No verifique la velocidad." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Domain Address" +msgstr "Dirección de dominio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Domain List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:891 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:991 +msgid "Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:949 +msgid "Domain Rule List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:965 +msgid "Domain Rule Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "Domain TTL" +msgstr "TTL del dominio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:336 +msgid "Domain TTL Max" +msgstr "TTL Máx. del dominio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:328 +msgid "Domain TTL Min" +msgstr "TTL Mín. del dominio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:246 +msgid "Domain prefetch" +msgstr "Prebúsqueda de dominios" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1159 +msgid "Donate" +msgstr "Donar" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1158 +msgid "Donate to smartdns" +msgstr "Donar a smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:526 +msgid "Download Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "Download Files Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:240 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1007 +msgid "Dual-stack IP Selection" +msgstr "Selección de IP de doble pila" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:371 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:642 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:959 +msgid "Enable" +msgstr "Activar" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable Auto Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:241 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1008 +msgid "Enable IP selection between IPv4 and IPv6" +msgstr "Activar la selección de IP entre IPv4 e IPv6" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "Enable IPv6 DNS Server" +msgstr "Activar servidor DNS IPv6" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "Enable TCP DNS Server" +msgstr "Activar el servidor DNS TCP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable daily auto update." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:247 +msgid "Enable domain prefetch, accelerate domain response speed." +msgstr "" +"Active la captación previa del dominio, acelere la velocidad de respuesta " +"del dominio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:372 +msgid "Enable or disable second DNS server." +msgstr "Activar o desactivar el segundo servidor DNS." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +msgid "Enable or disable smartdns server" +msgstr "Activar o desactivar el servidor smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude DNS Server from default group." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude Default Group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:215 +msgid "Fastest IP" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:216 +msgid "Fastest Response" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:535 +msgid "File Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +msgid "File Type" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:702 +msgid "Filtering IP with blacklist" +msgstr "Filtrado de IP con lista negra" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:214 +msgid "First Ping" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA" +msgstr "Forzar AAAA SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA." +msgstr "Forzar AAAA SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA" +msgstr "Forzar HTTPS SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA." +msgstr "Forzar HTTPS SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:131 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:638 +msgid "General Settings" +msgstr "Configuración general" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:599 +msgid "Generate Coredump" +msgstr "Generar Coredump" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:600 +msgid "" +"Generate Coredump file when smartdns crash, coredump file is located at /tmp/" +"smartdns.xxx.core." +msgstr "" +"Genere el archivo Coredump cuando smartdns falla, el archivo coredump se " +"encuentra en /tmp/smartdns.xxx.core." + +#: applications/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json:3 +msgid "Grant access to LuCI app smartdns" +msgstr "Conceder acceso a la aplicación LuCI smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:737 +msgid "HTTP Host" +msgstr "Host HTTP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "IP Blacklist" +msgstr "Lista negra de IP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:701 +msgid "IP Blacklist Filtering" +msgstr "Filtrado de la lista negra de IP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "IPv6 Server" +msgstr "Servidor IPv6" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1138 +msgid "If you like this software, please buy me a cup of coffee." +msgstr "Si le gusta este software, cómpreme una taza de café." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:353 +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:354 +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:283 +msgid "Ipset name, Add domain result to ipset when speed check fails." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:527 +msgid "List of files to download." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Listen only on the specified interfaces." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:153 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Local Port" +msgstr "Puerto local" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:624 +msgid "Log File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:608 +msgid "Log Level" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:620 +msgid "Log Number" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:604 +msgid "Log Size" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:757 +msgid "Marking Packets" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:337 +msgid "Maximum TTL for all domain result." +msgstr "TTL máximo para todos los resultados de dominio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:329 +msgid "Minimum TTL for all domain result." +msgstr "TTL mínimo para todos los resultados de dominio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:316 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:471 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:877 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1081 +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:66 +msgid "NOT RUNNING" +msgstr "NO SE ESTà EJECUTANDO" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Name of device name listen on." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:304 +msgid "" +"Nftset name, Add domain result to nftset when speed check fails, format: " +"[#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1014 +msgid "No" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:282 +msgid "No Speed IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:303 +msgid "No Speed NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:718 +msgid "No check certificate" +msgstr "No verificar el certificado" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:177 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1000 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1025 +msgid "None" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:784 +msgid "Only socks5 proxy support udp server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:780 +msgid "Please set proxy server first." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:136 +msgid "Proxy Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server URL, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:575 +msgid "" +"Proxy server URL format error, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:390 +msgid "Query DNS through specific dns server group, such as office, home." +msgstr "" +"Consulta DNS a través de un grupo de servidores dns específico, como " +"oficina, hogar." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:64 +msgid "RUNNING" +msgstr "EJECUTANDO" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:341 +msgid "Reply Domain TTL Max" +msgstr "TTL máximo del dominio de respuesta" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:342 +msgid "Reply maximum TTL for all domain result." +msgstr "Responda el TTL máximo para todos los resultados del dominio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1150 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1151 +msgid "Report bugs" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve Local Hostnames" +msgstr "Resolver nombres de host locales" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve local hostnames by reading Dnsmasq lease file." +msgstr "" +"Resuelva los nombres de host locales leyendo el archivo de concesiones de " +"Dnsmasq." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:209 +msgid "Response Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1174 +msgid "Restart" +msgstr "Reiniciar" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1165 +msgid "Restart Service" +msgstr "Reiniciar servicio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:133 +msgid "Second Server Settings" +msgstr "Segunda configuración del servidor" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:252 +msgid "Serve expired" +msgstr "Servir expirado" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:389 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "Server Group" +msgstr "Grupo de servidores" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:833 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:987 +msgid "Server Group %s not exists" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Server Name" +msgstr "Nombre del servidor" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Set Specific domain ip address." +msgstr "Establecer dirección IP de dominio específico." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +msgid "Set Specific domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "Set Specific ip blacklist." +msgstr "Establecer lista negra de IP específica." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:709 +msgid "Set TLS hostname to verify." +msgstr "Establezca el nombre de host TLS para verificar." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:758 +msgid "Set mark on packets." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:738 +msgid "" +"Set the HTTP host used for the query. Use this parameter when the host of " +"the URL address is an IP address." +msgstr "" +"Establezca el host HTTP utilizado para la consulta. Use este parámetro " +"cuando el host de la dirección URL sea una dirección IP." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:728 +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +msgid "Settings" +msgstr "Configuraciones" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:402 +msgid "Skip Address Rules" +msgstr "Omitir reglas de dirección" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache" +msgstr "Omitir caché" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache." +msgstr "Omitir caché." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:425 +msgid "Skip Dualstack Selection" +msgstr "Omitir selección de pila doble" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:426 +msgid "Skip Dualstack Selection." +msgstr "Omitir selección de pila doble." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:414 +msgid "Skip Ipset Rule" +msgstr "Omitir regla de Ipset" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:408 +msgid "Skip Nameserver Rule" +msgstr "Omitir regla de servidor de nombres" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:420 +msgid "Skip SOA Address Rule" +msgstr "Omitir regla de dirección SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:421 +msgid "Skip SOA address rules." +msgstr "Omita las reglas de dirección SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:396 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:837 +msgid "Skip Speed Check" +msgstr "Omitir comprobación de velocidad" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:403 +msgid "Skip address rules." +msgstr "Omitir reglas de dirección." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:415 +msgid "Skip ipset rules." +msgstr "Omitir las reglas de ipset." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:409 +msgid "Skip nameserver rules." +msgstr "Omitir las reglas del servidor de nombres." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:95 +#: applications/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json:3 +msgid "SmartDNS" +msgstr "SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:96 +msgid "SmartDNS Server" +msgstr "Servidor SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:97 +msgid "" +"SmartDNS is a local high-performance DNS server, supports finding fastest " +"IP, supports ad filtering, and supports avoiding DNS poisoning." +msgstr "" +"SmartDNS es un servidor DNS local de alto rendimiento, admite la búsqueda de " +"la IP más rápida, admite el filtrado de anuncios y evita el envenenamiento " +"de DNS." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1142 +msgid "SmartDNS official website" +msgstr "Sitio web oficial de SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Smartdns local server port" +msgstr "Puerto del servidor local Smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:154 +msgid "" +"Smartdns local server port, smartdns will be automatically set as main dns " +"when the port is 53." +msgstr "" +"Puerto del servidor local de Smartdns, se configurará automáticamente como " +"DNS principal cuando el puerto sea 53." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:210 +msgid "" +"Smartdns response mode, First Ping: return the first ping IP, Fastest IP: " +"return the fastest IP, Fastest Response: return the fastest DNS response." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Smartdns server name" +msgstr "Nombre del servidor de Smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Smartdns speed check mode." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1119 +msgid "" +"Specify an IP address to return for any host in the given domains, Queries " +"in the domains are never forwarded and always replied to with the specified " +"IP address which may be IPv4 or IPv6." +msgstr "" +"Especifique una dirección IP para devolver para cualquier host en los " +"dominios dados, las consultas en los dominios nunca se reenvían y siempre se " +"responden con la dirección IP especificada que puede ser IPv4 o IPv6." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Speed Check Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:202 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1050 +msgid "Speed check mode is invalid." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "TCP Server" +msgstr "Servidor TCP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:196 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1044 +msgid "TCP port is empty" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:708 +msgid "TLS Hostname Verify" +msgstr "Verificar nombre de host TLS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:727 +msgid "TLS SNI name" +msgstr "Nombre SNI de TLS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:746 +msgid "TLS SPKI Pinning" +msgstr "TLS SPKI Anclado" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "TTL for all domain result." +msgstr "TTL para todos los resultados de dominio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1137 +msgid "Technical Support" +msgstr "Soporte técnico" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:539 +msgid "URL" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:548 +msgid "URL format error, format: http:// or https://" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:523 +msgid "Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:514 +msgid "Update Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:500 +msgid "Upload Config File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:507 +msgid "Upload Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:508 +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:892 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:992 +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +msgid "Upload domain list file." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:501 +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:631 +msgid "Upstream Servers" +msgstr "Servidores aguas arriba" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:632 +msgid "" +"Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS " +"servers, including multiple foreign DNS servers." +msgstr "" +"Servidores aguas arriba, soporte UDP, protocolo TCP. Configure varios " +"servidores DNS, incluidos varios servidores DNS externos." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:765 +msgid "Use Proxy" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:766 +msgid "Use proxy to connect to upstream DNS server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:747 +msgid "" +"Used to verify the validity of the TLS server, The value is Base64 encoded " +"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not " +"verified." +msgstr "" +"Se utiliza para verificar la validez del servidor TLS. El valor es la huella " +"digital SPKI codificada en Base64, y se deja en blanco para indicar que no " +"se verifica la validez de TLS." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Write cache to disk on exit and load on startup." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1013 +msgid "Yes" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:172 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:213 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:611 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1012 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1020 +msgid "default" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:555 +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:670 +msgid "https" +msgstr "https" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "ip" +msgstr "ip" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:295 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:452 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:858 +msgid "ipset name format error, format: [#[4|6]:]ipsetname" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1143 +msgid "open website" +msgstr "abrir sitio web" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "port" +msgstr "puerto" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:556 +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:585 +msgid "smartdns custom settings" +msgstr "configuraciones personalizadas de smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:668 +msgid "tcp" +msgstr "tcp" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:669 +msgid "tls" +msgstr "tls" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "type" +msgstr "tipo" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:667 +msgid "udp" +msgstr "udp" + +#~ msgid "" +#~ "DNS Server group belongs to, used with nameserver, such as office, home." +#~ msgstr "" +#~ "El grupo del servidor DNS pertenece a, usado con el servidor de nombres, " +#~ "como la oficina, el hogar." + +#~ msgid "Dnsmasq Forwared To Smartdns Failure" +#~ msgstr "Fallo en el reenvío de dnsmasq a SmartDNS" + +#~ msgid "Sets the server name indication for query." +#~ msgstr "Establece la indicación del nombre del servidor para la consulta." + +#~ msgid "IPv4 53 Port Redirect Failure" +#~ msgstr "Error de reenvío de puerto IPv4 53" + +#~ msgid "IPv6 53 Port Redirect Failure" +#~ msgstr "Error de reenvío de puerto IPv6 53" + +#~ msgid "Redirect" +#~ msgstr "Redirigir" + +#~ msgid "Redirect 53 port to SmartDNS" +#~ msgstr "Redirigir el puerto 53 a SmartDNS" + +#~ msgid "Run as dnsmasq upstream server" +#~ msgstr "Ejecutar como servidor dnsmasq aguas arriba" + +#~ msgid "SmartDNS redirect mode" +#~ msgstr "Modo de redireccionamiento SmartDNS" + +#~ msgid "none" +#~ msgstr "ninguno" + +#~ msgid "DNS Server group belongs to," +#~ msgstr "El grupo del servidor DNS pertenece a," + +#~ msgid "" +#~ "SmartDNS is a local high-performance DNS server, supports finding fastest " +#~ "IP," +#~ msgstr "" +#~ "SmartDNS es un servidor DNS local de alto rendimiento, admite la búsqueda " +#~ "de IP más rápida," + +#~ msgid "" +#~ "Specify an IP address to return for any host in the given domains, " +#~ "Queries in the domains are never" +#~ msgstr "" +#~ "Especifique una dirección IP para devolver para cualquier host en los " +#~ "dominios dados, las consultas en los dominios nunca son" + +#~ msgid "" +#~ "Upstream Servers, support UDP, TCP protocol. Please configure multiple " +#~ "DNS servers," +#~ msgstr "" +#~ "Servidores aguas arriba, soporte UDP, protocolo TCP. Configura varios " +#~ "servidores DNS," + +#~ msgid "" +#~ "Used to verify the validity of the TLS server, The value is Base64 " +#~ "encoded SPKI fingerprint," +#~ msgstr "" +#~ "Se utiliza para verificar la validez del servidor TLS. El valor es la " +#~ "huella digital SPKI codificada en Base64," diff --git a/luci-app-smartdns/po/pt-BR/smartdns.po b/luci-app-smartdns/po/pt-BR/smartdns.po new file mode 100644 index 00000000..6ec49c1b --- /dev/null +++ b/luci-app-smartdns/po/pt-BR/smartdns.po @@ -0,0 +1,964 @@ +msgid "" +msgstr "" +"PO-Revision-Date: 2023-03-08 10:38+0000\n" +"Last-Translator: Wellington Terumi Uemura \n" +"Language-Team: Portuguese (Brazil) \n" +"Language: pt-BR\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.16.2-dev\n" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:792 +msgid "Additional Args for upstream dns servers" +msgstr "Args adicionais para servidores dns upstream" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:886 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1090 +msgid "" +"Additional Flags for rules, read help on domain-rule for more information." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:885 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1089 +msgid "Additional Rule Flag" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:346 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:479 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:791 +msgid "Additional Server Args" +msgstr "Args Adicionais Sobre o Servidor" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:347 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:480 +msgid "" +"Additional server args, refer to the help description of the bind option." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:132 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:639 +msgid "Advanced Settings" +msgstr "Configurações avançadas" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:253 +msgid "" +"Attempts to serve old responses from cache with a TTL of 0 in the response " +"without waiting for the actual resolution to finish." +msgstr "" +"Tentativas de servir respostas antigas do cache com um TTL de 0 na resposta " +"sem esperar o término da resolução real." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically Set Dnsmasq" +msgstr "Definir o Dnsmasq automaticamente" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically set as upstream of dnsmasq when port changes." +msgstr "" +"Definido automaticamente como upstream do dnsmasq quando a porta se alterar." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Bind Device" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Bind Device Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Cache Persist" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "Cache Size" +msgstr "Tamanho do Cache" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:121 +msgid "Collecting data ..." +msgstr "Coletando dados ..." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1100 +msgid "" +"Configure IP blacklists that will be filtered from the results of specific " +"DNS server." +msgstr "" +"Configure as listas negras dos IP que serão filtradas a partir dos " +"resultados de um servidor DNS específico." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Configure block domain list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:950 +msgid "Configure domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +msgid "Configure forwarding domain name list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:137 +msgid "Custom Settings" +msgstr "Configurações Personalizadas" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:805 +msgid "DNS Block Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:804 +msgid "DNS Forwarding Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:648 +msgid "DNS Server Name" +msgstr "Nome do Servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +msgid "DNS Server group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "DNS Server group belongs to, such as office, home." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "DNS Server ip" +msgstr "Endereço IP do Servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "DNS Server port" +msgstr "Porta do Servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "DNS Server type" +msgstr "Tipo do Servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "DNS domain result cache size" +msgstr "Tamanho do cache para o resultado do domínio DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:487 +msgid "DNS64" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:134 +msgid "DNS64 Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:560 +msgid "Description" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:76 +msgid "Dnsmasq Forwarded To Smartdns Failure" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:719 +msgid "Do not check certificate." +msgstr "Não verifique o certificado." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:397 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:838 +msgid "Do not check speed." +msgstr "Não verifique a velocidade." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Domain Address" +msgstr "Endereço do domínio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Domain List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:891 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:991 +msgid "Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:949 +msgid "Domain Rule List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:965 +msgid "Domain Rule Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "Domain TTL" +msgstr "TTL do domínio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:336 +msgid "Domain TTL Max" +msgstr "TTL Max. do Domínio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:328 +msgid "Domain TTL Min" +msgstr "TTL Min. do Domínio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:246 +msgid "Domain prefetch" +msgstr "Pré-aquisição do Domínio" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1159 +msgid "Donate" +msgstr "Doe" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1158 +msgid "Donate to smartdns" +msgstr "Doar para o smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:526 +msgid "Download Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "Download Files Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:240 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1007 +msgid "Dual-stack IP Selection" +msgstr "Seleção IP com pilha dupla" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:371 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:642 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:959 +msgid "Enable" +msgstr "Ativar" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable Auto Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:241 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1008 +msgid "Enable IP selection between IPv4 and IPv6" +msgstr "Ative a seleção do IP entre o IPv4 e o IPv6" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "Enable IPv6 DNS Server" +msgstr "Ativar o Servidor IPv6 do DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "Enable TCP DNS Server" +msgstr "Ative o TCP do servidor DNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable daily auto update." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:247 +msgid "Enable domain prefetch, accelerate domain response speed." +msgstr "" +"Ative a pré-aquisição do domínio, acelera a velocidade de resposta do " +"domínio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:372 +msgid "Enable or disable second DNS server." +msgstr "Ative ou desative o segundo servidor DNS." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +msgid "Enable or disable smartdns server" +msgstr "Ative ou desative o servidor smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude DNS Server from default group." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude Default Group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:215 +msgid "Fastest IP" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:216 +msgid "Fastest Response" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:535 +msgid "File Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +msgid "File Type" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:702 +msgid "Filtering IP with blacklist" +msgstr "Filtrando o IP com um alista negra" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:214 +msgid "First Ping" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA" +msgstr "Impor AAAA SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA." +msgstr "Impor AAAA SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA" +msgstr "Impor o HTTPS SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA." +msgstr "Impor o HTTPS SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:131 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:638 +msgid "General Settings" +msgstr "Configurações gerais" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:599 +msgid "Generate Coredump" +msgstr "Gerar Coredump" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:600 +msgid "" +"Generate Coredump file when smartdns crash, coredump file is located at /tmp/" +"smartdns.xxx.core." +msgstr "" +"Gere um arquivo Coredump quando o smartdns falhar, o arquivo coredump está " +"localizado em /tmp/smartdns.xxx.core." + +#: applications/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json:3 +msgid "Grant access to LuCI app smartdns" +msgstr "Conceda acesso ao LuCI app smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:737 +msgid "HTTP Host" +msgstr "Host HTTP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "IP Blacklist" +msgstr "Lista negra de IPs" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:701 +msgid "IP Blacklist Filtering" +msgstr "Filtragem da Lista Negra dos IPs" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "IPv6 Server" +msgstr "Servidor IPv6" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1138 +msgid "If you like this software, please buy me a cup of coffee." +msgstr "Caso goste deste software, por favor, me pague uma xícara de café." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:353 +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:354 +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:283 +msgid "Ipset name, Add domain result to ipset when speed check fails." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:527 +msgid "List of files to download." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Listen only on the specified interfaces." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:153 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Local Port" +msgstr "Porta Local" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:624 +msgid "Log File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:608 +msgid "Log Level" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:620 +msgid "Log Number" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:604 +msgid "Log Size" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:757 +msgid "Marking Packets" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:337 +msgid "Maximum TTL for all domain result." +msgstr "TTL máximo para todos os resultados do domínio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:329 +msgid "Minimum TTL for all domain result." +msgstr "TTL mínimo para todos os resultados do domínio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:316 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:471 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:877 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1081 +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:66 +msgid "NOT RUNNING" +msgstr "NÃO ESTà EM EXECUÇÃO" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Name of device name listen on." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:304 +msgid "" +"Nftset name, Add domain result to nftset when speed check fails, format: " +"[#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1014 +msgid "No" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:282 +msgid "No Speed IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:303 +msgid "No Speed NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:718 +msgid "No check certificate" +msgstr "Não verifique o certificado" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:177 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1000 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1025 +msgid "None" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:784 +msgid "Only socks5 proxy support udp server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:780 +msgid "Please set proxy server first." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:136 +msgid "Proxy Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server URL, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:575 +msgid "" +"Proxy server URL format error, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:390 +msgid "Query DNS through specific dns server group, such as office, home." +msgstr "" +"Consulta o DNS através de um grupo específico de servidores dns, como " +"office, casa." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:64 +msgid "RUNNING" +msgstr "EM EXECUÇÃO" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:341 +msgid "Reply Domain TTL Max" +msgstr "Responda ao domínio com TTL Max" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:342 +msgid "Reply maximum TTL for all domain result." +msgstr "Responda com TTL máximo em todos os resultados do domínio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1150 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1151 +msgid "Report bugs" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve Local Hostnames" +msgstr "Resolve os nomes dos host locais" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve local hostnames by reading Dnsmasq lease file." +msgstr "Resolve os nomes dos hosts lendo o arquivo de concessão do Dnsmasq." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:209 +msgid "Response Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1174 +msgid "Restart" +msgstr "Reiniciar" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1165 +msgid "Restart Service" +msgstr "Reiniciar o serviço" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:133 +msgid "Second Server Settings" +msgstr "Configurações do Segundo Servidor" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:252 +msgid "Serve expired" +msgstr "O servir expirou" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:389 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "Server Group" +msgstr "Grupo dos Servidores" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:833 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:987 +msgid "Server Group %s not exists" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Server Name" +msgstr "Nome do Servidor" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Set Specific domain ip address." +msgstr "Defina um endereço IP específico para o domínio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +msgid "Set Specific domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "Set Specific ip blacklist." +msgstr "Defina um IP específico para a lista negra." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:709 +msgid "Set TLS hostname to verify." +msgstr "Defina o nome do host TLS para verificar." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:758 +msgid "Set mark on packets." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:738 +msgid "" +"Set the HTTP host used for the query. Use this parameter when the host of " +"the URL address is an IP address." +msgstr "" +"Defina o host HTTP utilizado para a consulta. Use este parâmetro quando o " +"host da URL do endereço for um endereço IP." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:728 +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +msgid "Settings" +msgstr "Configurações" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:402 +msgid "Skip Address Rules" +msgstr "Ignora as Regras do Endereço" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache" +msgstr "Ignora a Cache" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache." +msgstr "Ignora a Cache." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:425 +msgid "Skip Dualstack Selection" +msgstr "Ignora a Seleção da Pilha Dupla" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:426 +msgid "Skip Dualstack Selection." +msgstr "Ignora a Seleção da Pilha Dupla." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:414 +msgid "Skip Ipset Rule" +msgstr "Ignora a Regra Ipset" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:408 +msgid "Skip Nameserver Rule" +msgstr "Ignora a Regra do Servidor de Nomes" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:420 +msgid "Skip SOA Address Rule" +msgstr "Ignorar a Regra do Endereço SOA" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:421 +msgid "Skip SOA address rules." +msgstr "Ignorar a Regra do Endereço SOA." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:396 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:837 +msgid "Skip Speed Check" +msgstr "Ignorar a Verificação da Velocidade" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:403 +msgid "Skip address rules." +msgstr "Ignora as Regras do Endereço." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:415 +msgid "Skip ipset rules." +msgstr "Ignore as regras do ipset." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:409 +msgid "Skip nameserver rules." +msgstr "Ignora a regra do servidor de nomes." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:95 +#: applications/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json:3 +msgid "SmartDNS" +msgstr "SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:96 +msgid "SmartDNS Server" +msgstr "Servidor SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:97 +msgid "" +"SmartDNS is a local high-performance DNS server, supports finding fastest " +"IP, supports ad filtering, and supports avoiding DNS poisoning." +msgstr "" +"O SmartDNS é um servidor DNS local de alto desempenho, é compatível com a " +"localização rápida do IP, suporta filtragem de anúncios e previne o " +"envenenamento do DNS." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1142 +msgid "SmartDNS official website" +msgstr "Site oficial do SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Smartdns local server port" +msgstr "Porta do servidor local Smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:154 +msgid "" +"Smartdns local server port, smartdns will be automatically set as main dns " +"when the port is 53." +msgstr "" +"Porta do servidor local do Smartdns, o smartdns será automaticamente " +"definido como dns principal quando a porta for 53." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:210 +msgid "" +"Smartdns response mode, First Ping: return the first ping IP, Fastest IP: " +"return the fastest IP, Fastest Response: return the fastest DNS response." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Smartdns server name" +msgstr "Nome do servidor Smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Smartdns speed check mode." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1119 +msgid "" +"Specify an IP address to return for any host in the given domains, Queries " +"in the domains are never forwarded and always replied to with the specified " +"IP address which may be IPv4 or IPv6." +msgstr "" +"Especifique um endereço IP para retornar para qualquer host nos domínios " +"determinados, as consultas nos domínios nunca são encaminhadas e sempre " +"respondidas de forma especificada com o endereço IP que tanto pode ser IPv4 " +"ou IPv6." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Speed Check Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:202 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1050 +msgid "Speed check mode is invalid." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "TCP Server" +msgstr "Servidor TCP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:196 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1044 +msgid "TCP port is empty" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:708 +msgid "TLS Hostname Verify" +msgstr "Verificar o Nome do Host TLS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:727 +msgid "TLS SNI name" +msgstr "Nome TLS SNI" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:746 +msgid "TLS SPKI Pinning" +msgstr "Fixação TLS SPKI" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "TTL for all domain result." +msgstr "O TTL para todos os resultados do domínio." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1137 +msgid "Technical Support" +msgstr "Suporte Técnico" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:539 +msgid "URL" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:548 +msgid "URL format error, format: http:// or https://" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:523 +msgid "Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:514 +msgid "Update Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:500 +msgid "Upload Config File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:507 +msgid "Upload Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:508 +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:892 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:992 +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +msgid "Upload domain list file." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:501 +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:631 +msgid "Upstream Servers" +msgstr "Servidores upstream" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:632 +msgid "" +"Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS " +"servers, including multiple foreign DNS servers." +msgstr "" +"Servidores upstream, suporte UDP, protocolo TCP. Configure os vários " +"servidores DNS, incluindo vários servidores DNS externos." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:765 +msgid "Use Proxy" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:766 +msgid "Use proxy to connect to upstream DNS server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:747 +msgid "" +"Used to verify the validity of the TLS server, The value is Base64 encoded " +"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not " +"verified." +msgstr "" +"Utilizado para verificar a validade do servidor TLS, o valor é a impressão " +"digital SPKI codificada com base64, deixando em branco para indicar que a " +"validade do TLS não será verificada." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Write cache to disk on exit and load on startup." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1013 +msgid "Yes" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:172 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:213 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:611 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1012 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1020 +msgid "default" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:555 +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:670 +msgid "https" +msgstr "https" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "ip" +msgstr "IP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:295 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:452 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:858 +msgid "ipset name format error, format: [#[4|6]:]ipsetname" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1143 +msgid "open website" +msgstr "abrir o website" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "port" +msgstr "porta" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:556 +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:585 +msgid "smartdns custom settings" +msgstr "configurações personalizadas do smartdns" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:668 +msgid "tcp" +msgstr "tcp" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:669 +msgid "tls" +msgstr "tls" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "type" +msgstr "tipo" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:667 +msgid "udp" +msgstr "udp" + +#~ msgid "" +#~ "DNS Server group belongs to, used with nameserver, such as office, home." +#~ msgstr "" +#~ "O grupo do Servidor DNS pertence a, usado em conjunto com o nameserver " +#~ "(nome do servidor), assim como em office, em casa." + +#~ msgid "Dnsmasq Forwared To Smartdns Failure" +#~ msgstr "Encaminhamento do Dnsmasq para Falha do Smartdns" + +#~ msgid "Sets the server name indication for query." +#~ msgstr "Define a indicação do nome do servidor para consulta." + +#~ msgid "IPv4 53 Port Redirect Failure" +#~ msgstr "Falha no Redirecionamento da Porta IPv4 53" + +#~ msgid "IPv6 53 Port Redirect Failure" +#~ msgstr "Falha no Redirecionamento da Porta IPv6 53" + +#~ msgid "Redirect" +#~ msgstr "Redirecione" + +#~ msgid "Redirect 53 port to SmartDNS" +#~ msgstr "Redirecionar a porta 53 para o SmartDNS" + +#~ msgid "Run as dnsmasq upstream server" +#~ msgstr "Executar como servidor dnsmasq upstream" + +#~ msgid "SmartDNS redirect mode" +#~ msgstr "SmartDNS, modo de redirecionamento" + +#~ msgid "none" +#~ msgstr "nenhum" diff --git a/luci-app-smartdns/po/templates/smartdns.pot b/luci-app-smartdns/po/templates/smartdns.pot new file mode 100644 index 00000000..4c50e69e --- /dev/null +++ b/luci-app-smartdns/po/templates/smartdns.pot @@ -0,0 +1,1220 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +#: log.js:80 +msgid "Loading..." +msgstr "" + +#: log.js:82 smartdns.js:146 +msgid "Collecting data ..." +msgstr "" + +#: log.js:92 +msgid "Clear Logs..." +msgstr "" + +#: log.js:95 +msgid "Logs cleared successfully!" +msgstr "" + +#: log.js:98 log.js:108 log.js:112 +msgid "Clear Logs" +msgstr "" + +#: log.js:101 log.js:119 +msgid "Log is clean." +msgstr "" + +#: log.js:105 +msgid "Failed to clear log." +msgstr "" + +#: log.js:127 +msgid "Log file does not exist." +msgstr "" + +#: log.js:129 +#, javascript-format +msgid "Unknown error: %s" +msgstr "" + +#: log.js:142 +msgid "Back SmartDNS" +msgstr "" + +#: log.js:151 +#, javascript-format +msgid "Refresh every %s seconds." +msgstr "" + +#: smartdns.js:68 +msgid "RUNNING" +msgstr "" + +#: smartdns.js:74 +msgid "Open the WebUI" +msgstr "" + +#: smartdns.js:77 +msgid "NOT RUNNING" +msgstr "" + +#: smartdns.js:79 +msgid "Please check the system logs and check if the configuration is valid." +msgstr "" + +#: smartdns.js:91 +msgid "Dnsmasq Forwarded To Smartdns Failure" +msgstr "" + +#: smartdns.js:120 +msgid "SmartDNS" +msgstr "" + +#: smartdns.js:121 +msgid "SmartDNS Server" +msgstr "" + +#: smartdns.js:122 +msgid "" +"SmartDNS is a local high-performance DNS server, supports finding fastest " +"IP, supports ad filtering, and supports avoiding DNS poisoning." +msgstr "" + +#: smartdns.js:153 +msgid "Settings" +msgstr "" + +#: smartdns.js:153 smartdns.js:156 smartdns.js:888 +msgid "General Settings" +msgstr "" + +#: smartdns.js:157 smartdns.js:889 smartdns.js:1074 +msgid "Advanced Settings" +msgstr "" + +#: smartdns.js:158 +msgid "Second Server Settings" +msgstr "" + +#: smartdns.js:159 +msgid "DNS64 Server Settings" +msgstr "" + +#: smartdns.js:160 +msgid "Download Files Setting" +msgstr "" + +#: smartdns.js:160 +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" + +#: smartdns.js:161 +msgid "Proxy Server Settings" +msgstr "" + +#: smartdns.js:162 +msgid "Custom Settings" +msgstr "" + +#: smartdns.js:167 smartdns.js:535 smartdns.js:892 smartdns.js:1077 smartdns.js:1486 smartdns.js:1677 +msgid "Enable" +msgstr "" + +#: smartdns.js:167 +msgid "Enable or disable smartdns server" +msgstr "" + +#: smartdns.js:172 +msgid "Server Name" +msgstr "" + +#: smartdns.js:172 +msgid "Smartdns server name" +msgstr "" + +#: smartdns.js:178 smartdns.js:541 +msgid "Local Port" +msgstr "" + +#: smartdns.js:179 +msgid "" +"Smartdns local server port, smartdns will be automatically set as main dns " +"when the port is 53." +msgstr "" + +#: smartdns.js:186 +msgid "Automatically Set Dnsmasq" +msgstr "" + +#: smartdns.js:186 +msgid "Automatically set as upstream of dnsmasq when port changes." +msgstr "" + +#: smartdns.js:192 +msgid "Enable WebUI" +msgstr "" + +#: smartdns.js:192 +msgid "Enable or disable smartdns webui plugin." +msgstr "" + +#: smartdns.js:196 +msgid "WebUI Port" +msgstr "" + +#: smartdns.js:196 +msgid "WebUI server port." +msgstr "" + +#: smartdns.js:202 +msgid "WebUI Data Dir" +msgstr "" + +#: smartdns.js:202 +msgid "Directory for storing the webui database." +msgstr "" + +#: smartdns.js:208 +msgid "WebUI Log Retention" +msgstr "" + +#: smartdns.js:208 +msgid "Number of days to retain webui logs." +msgstr "" + +#: smartdns.js:219 smartdns.js:1139 smartdns.js:1309 smartdns.js:1543 +msgid "Speed Check Mode" +msgstr "" + +#: smartdns.js:219 smartdns.js:1139 smartdns.js:1309 smartdns.js:1543 +msgid "Smartdns speed check mode." +msgstr "" + +#: smartdns.js:222 smartdns.js:274 smartdns.js:806 smartdns.js:1142 smartdns.js:1312 smartdns.js:1365 smartdns.js:1539 smartdns.js:1547 +msgid "default" +msgstr "" + +#: smartdns.js:229 smartdns.js:1149 smartdns.js:1319 smartdns.js:1527 smartdns.js:1554 +msgid "None" +msgstr "" + +#: smartdns.js:250 smartdns.js:1170 smartdns.js:1340 smartdns.js:1575 +msgid "TCP port is empty" +msgstr "" + +#: smartdns.js:258 smartdns.js:1178 smartdns.js:1348 smartdns.js:1583 +msgid "TCP SYN port is empty" +msgstr "" + +#: smartdns.js:263 smartdns.js:1183 smartdns.js:1353 smartdns.js:1588 +msgid "Speed check mode is invalid." +msgstr "" + +#: smartdns.js:270 +msgid "Response Mode" +msgstr "" + +#: smartdns.js:271 +msgid "" +"Smartdns response mode, First Ping: return the first ping IP, Fastest IP: " +"return the fastest IP, Fastest Response: return the fastest DNS response." +msgstr "" + +#: smartdns.js:275 +msgid "First Ping" +msgstr "" + +#: smartdns.js:276 +msgid "Fastest IP" +msgstr "" + +#: smartdns.js:277 +msgid "Fastest Response" +msgstr "" + +#: smartdns.js:280 smartdns.js:548 +msgid "TCP Server" +msgstr "" + +#: smartdns.js:280 smartdns.js:548 +msgid "Enable TCP DNS Server" +msgstr "" + +#: smartdns.js:285 +msgid "DOT Server" +msgstr "" + +#: smartdns.js:285 +msgid "Enable DOT DNS Server" +msgstr "" + +#: smartdns.js:289 +msgid "DOT Server Port" +msgstr "" + +#: smartdns.js:289 +msgid "Smartdns DOT server port." +msgstr "" + +#: smartdns.js:297 +msgid "DOH Server" +msgstr "" + +#: smartdns.js:297 +msgid "Enable DOH DNS Server" +msgstr "" + +#: smartdns.js:301 +msgid "DOH Server Port" +msgstr "" + +#: smartdns.js:301 +msgid "Smartdns DOH server port." +msgstr "" + +#: smartdns.js:308 +msgid "Server Cert" +msgstr "" + +#: smartdns.js:308 +msgid "Server certificate file path." +msgstr "" + +#: smartdns.js:315 +msgid "Server Cert Key" +msgstr "" + +#: smartdns.js:315 +msgid "Server certificate key file path." +msgstr "" + +#: smartdns.js:322 +msgid "Server Cert Key Pass" +msgstr "" + +#: smartdns.js:322 +msgid "Server certificate key file password." +msgstr "" + +#: smartdns.js:329 +msgid "IPv6 Server" +msgstr "" + +#: smartdns.js:329 +msgid "Enable IPv6 DNS Server" +msgstr "" + +#: smartdns.js:334 +msgid "Bind Device" +msgstr "" + +#: smartdns.js:334 +msgid "Listen only on the specified interfaces." +msgstr "" + +#: smartdns.js:339 +msgid "Bind Device Name" +msgstr "" + +#: smartdns.js:339 +msgid "Name of device name listen on." +msgstr "" + +#: smartdns.js:345 smartdns.js:1190 smartdns.js:1360 smartdns.js:1534 +msgid "Dual-stack IP Selection" +msgstr "" + +#: smartdns.js:346 smartdns.js:1191 smartdns.js:1361 smartdns.js:1535 +msgid "Enable IP selection between IPv4 and IPv6" +msgstr "" + +#: smartdns.js:351 +msgid "Domain prefetch" +msgstr "" + +#: smartdns.js:352 +msgid "Enable domain prefetch, accelerate domain response speed." +msgstr "" + +#: smartdns.js:357 +msgid "Serve expired" +msgstr "" + +#: smartdns.js:358 +msgid "" +"Attempts to serve old responses from cache with a TTL of 0 in the response " +"without waiting for the actual resolution to finish." +msgstr "" + +#: smartdns.js:363 +msgid "Cache Size" +msgstr "" + +#: smartdns.js:363 +msgid "DNS domain result cache size" +msgstr "" + +#: smartdns.js:367 +msgid "Cache Persist" +msgstr "" + +#: smartdns.js:367 +msgid "Write cache to disk on exit and load on startup." +msgstr "" + +#: smartdns.js:372 +msgid "Resolve Local Hostnames" +msgstr "" + +#: smartdns.js:372 +msgid "Resolve local hostnames by reading Dnsmasq lease file." +msgstr "" + +#: smartdns.js:377 +msgid "mDNS Lookup" +msgstr "" + +#: smartdns.js:377 +msgid "Resolve local network hostname via mDNS protocol." +msgstr "" + +#: smartdns.js:382 smartdns.js:600 smartdns.js:1196 smartdns.js:1369 smartdns.js:1594 +msgid "Force AAAA SOA" +msgstr "" + +#: smartdns.js:382 smartdns.js:600 smartdns.js:1196 smartdns.js:1369 smartdns.js:1594 +msgid "Force AAAA SOA." +msgstr "" + +#: smartdns.js:387 smartdns.js:605 smartdns.js:1201 +msgid "Force HTTPS SOA" +msgstr "" + +#: smartdns.js:387 smartdns.js:605 smartdns.js:1201 +msgid "Force HTTPS SOA." +msgstr "" + +#: smartdns.js:392 smartdns.js:613 smartdns.js:1206 smartdns.js:1373 smartdns.js:1600 +msgid "IPset Name" +msgstr "" + +#: smartdns.js:392 smartdns.js:613 smartdns.js:1206 smartdns.js:1373 smartdns.js:1600 +msgid "IPset name." +msgstr "" + +#: smartdns.js:404 smartdns.js:425 smartdns.js:625 smartdns.js:1218 smartdns.js:1385 +msgid "ipset name format error, format: [#[4|6]:]ipsetname" +msgstr "" + +#: smartdns.js:412 +msgid "No Speed IPset Name" +msgstr "" + +#: smartdns.js:413 +msgid "Ipset name, Add domain result to ipset when speed check fails." +msgstr "" + +#: smartdns.js:433 smartdns.js:632 smartdns.js:1226 smartdns.js:1392 smartdns.js:1606 +msgid "NFTset Name" +msgstr "" + +#: smartdns.js:433 smartdns.js:632 smartdns.js:1226 smartdns.js:1392 smartdns.js:1606 +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: smartdns.js:445 smartdns.js:466 smartdns.js:644 smartdns.js:1238 smartdns.js:1404 smartdns.js:1619 +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: smartdns.js:453 +msgid "No Speed NFTset Name" +msgstr "" + +#: smartdns.js:454 +msgid "" +"Nftset name, Add domain result to nftset when speed check fails, format: " +"[#[4|6]:[family#table#set]]" +msgstr "" + +#: smartdns.js:474 +msgid "Domain TTL" +msgstr "" + +#: smartdns.js:474 +msgid "TTL for all domain result." +msgstr "" + +#: smartdns.js:478 +msgid "Domain TTL Min" +msgstr "" + +#: smartdns.js:479 +msgid "Minimum TTL for all domain result." +msgstr "" + +#: smartdns.js:486 +msgid "Domain TTL Max" +msgstr "" + +#: smartdns.js:487 +msgid "Maximum TTL for all domain result." +msgstr "" + +#: smartdns.js:491 +msgid "Reply Domain TTL Max" +msgstr "" + +#: smartdns.js:492 +msgid "Reply maximum TTL for all domain result." +msgstr "" + +#: smartdns.js:496 smartdns.js:652 smartdns.js:1060 +msgid "Additional Server Args" +msgstr "" + +#: smartdns.js:497 smartdns.js:653 +msgid "" +"Additional server args, refer to the help description of the bind option." +msgstr "" + +#: smartdns.js:503 smartdns.js:1247 +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "" + +#: smartdns.js:504 smartdns.js:1248 +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" + +#: smartdns.js:517 +msgid "Hosts File" +msgstr "" + +#: smartdns.js:517 +msgid "Include hosts file." +msgstr "" + +#: smartdns.js:536 +msgid "Enable or disable second DNS server." +msgstr "" + +#: smartdns.js:541 +msgid "Smartdns local server port" +msgstr "" + +#: smartdns.js:553 smartdns.js:928 smartdns.js:1114 smartdns.js:1284 smartdns.js:1494 +msgid "Server Group" +msgstr "" + +#: smartdns.js:554 +msgid "Query DNS through specific dns server group, such as office, home." +msgstr "" + +#: smartdns.js:560 +msgid "Skip Speed Check" +msgstr "" + +#: smartdns.js:561 +msgid "Do not check speed." +msgstr "" + +#: smartdns.js:566 +msgid "Skip Address Rules" +msgstr "" + +#: smartdns.js:567 +msgid "Skip address rules." +msgstr "" + +#: smartdns.js:572 +msgid "Skip Nameserver Rule" +msgstr "" + +#: smartdns.js:573 +msgid "Skip nameserver rules." +msgstr "" + +#: smartdns.js:578 +msgid "Skip Ipset Rule" +msgstr "" + +#: smartdns.js:579 +msgid "Skip ipset rules." +msgstr "" + +#: smartdns.js:584 +msgid "Skip SOA Address Rule" +msgstr "" + +#: smartdns.js:585 +msgid "Skip SOA address rules." +msgstr "" + +#: smartdns.js:589 +msgid "Skip Dualstack Selection" +msgstr "" + +#: smartdns.js:590 +msgid "Skip Dualstack Selection." +msgstr "" + +#: smartdns.js:595 +msgid "Skip Cache" +msgstr "" + +#: smartdns.js:595 +msgid "Skip Cache." +msgstr "" + +#: smartdns.js:609 +msgid "Skip IP Alias" +msgstr "" + +#: smartdns.js:660 +msgid "DNS64" +msgstr "" + +#: smartdns.js:668 +msgid "Enable Auto Update" +msgstr "" + +#: smartdns.js:668 +msgid "Enable daily (weekly) auto update." +msgstr "" + +#: smartdns.js:673 +msgid "Update Time (Every Week)" +msgstr "" + +#: smartdns.js:674 +msgid "Every Day" +msgstr "" + +#: smartdns.js:675 +msgid "Every Monday" +msgstr "" + +#: smartdns.js:676 +msgid "Every Tuesday" +msgstr "" + +#: smartdns.js:677 +msgid "Every Wednesday" +msgstr "" + +#: smartdns.js:678 +msgid "Every Thursday" +msgstr "" + +#: smartdns.js:679 +msgid "Every Friday" +msgstr "" + +#: smartdns.js:680 +msgid "Every Saturday" +msgstr "" + +#: smartdns.js:681 +msgid "Every Sunday" +msgstr "" + +#: smartdns.js:685 +msgid "Update time (every day)" +msgstr "" + +#: smartdns.js:691 +msgid "Upload Config File" +msgstr "" + +#: smartdns.js:692 +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "" + +#: smartdns.js:698 +msgid "Upload Domain List File" +msgstr "" + +#: smartdns.js:699 +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "" + +#: smartdns.js:705 +msgid "Upload File" +msgstr "" + +#: smartdns.js:711 +msgid "Update Files" +msgstr "" + +#: smartdns.js:720 +msgid "Update" +msgstr "" + +#: smartdns.js:723 +msgid "Download Files" +msgstr "" + +#: smartdns.js:724 +msgid "List of files to download." +msgstr "" + +#: smartdns.js:732 +msgid "File Name" +msgstr "" + +#: smartdns.js:736 +msgid "URL" +msgstr "" + +#: smartdns.js:745 +msgid "URL format error, format: http:// or https://" +msgstr "" + +#: smartdns.js:751 smartdns.js:916 +msgid "type" +msgstr "" + +#: smartdns.js:751 +msgid "File Type" +msgstr "" + +#: smartdns.js:752 +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "" + +#: smartdns.js:753 +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "" + +#: smartdns.js:754 +msgid "ip-set file (/etc/smartdns/ip-set)" +msgstr "" + +#: smartdns.js:755 +msgid "other file (/etc/smartdns/download)" +msgstr "" + +#: smartdns.js:759 +msgid "Description" +msgstr "" + +#: smartdns.js:766 +msgid "Proxy Server" +msgstr "" + +#: smartdns.js:766 +msgid "Proxy Server URL, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: smartdns.js:774 +msgid "" +"Proxy server URL format error, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: smartdns.js:784 +msgid "smartdns custom settings" +msgstr "" + +#: smartdns.js:798 +msgid "Generate Coredump" +msgstr "" + +#: smartdns.js:799 +msgid "" +"Generate Coredump file when smartdns crash, coredump file is located at /tmp/" +"smartdns.xxx.core." +msgstr "" + +#: smartdns.js:803 +msgid "Log Level" +msgstr "" + +#: smartdns.js:815 +msgid "Log Output Mode" +msgstr "" + +#: smartdns.js:818 smartdns.js:859 +msgid "file" +msgstr "" + +#: smartdns.js:819 smartdns.js:860 +msgid "syslog" +msgstr "" + +#: smartdns.js:821 +msgid "Log Size" +msgstr "" + +#: smartdns.js:826 +msgid "Log Number" +msgstr "" + +#: smartdns.js:831 +msgid "Log File" +msgstr "" + +#: smartdns.js:836 smartdns.js:844 +msgid "View Log" +msgstr "" + +#: smartdns.js:851 +msgid "Enable Audit Log" +msgstr "" + +#: smartdns.js:856 +msgid "Audit Log Output Mode" +msgstr "" + +#: smartdns.js:863 +msgid "Audit Log Size" +msgstr "" + +#: smartdns.js:868 +msgid "Audit Log Number" +msgstr "" + +#: smartdns.js:873 +msgid "Audit Log File" +msgstr "" + +#: smartdns.js:881 +msgid "Upstream Servers" +msgstr "" + +#: smartdns.js:882 +msgid "" +"Upstream Servers, support UDP, TCP, DoT, DoH, DoQ, DoH3 protocol. Please " +"configure multiple DNS servers, including multiple foreign DNS servers." +msgstr "" + +#: smartdns.js:898 +msgid "DNS Server Name" +msgstr "" + +#: smartdns.js:901 +msgid "ip" +msgstr "" + +#: smartdns.js:901 +msgid "DNS Server ip" +msgstr "" + +#: smartdns.js:906 +msgid "port" +msgstr "" + +#: smartdns.js:906 +msgid "DNS Server port" +msgstr "" + +#: smartdns.js:916 +msgid "DNS Server type" +msgstr "" + +#: smartdns.js:918 +msgid "udp" +msgstr "" + +#: smartdns.js:919 +msgid "tcp" +msgstr "" + +#: smartdns.js:920 +msgid "tls" +msgstr "" + +#: smartdns.js:921 +msgid "https" +msgstr "" + +#: smartdns.js:922 +msgid "quic" +msgstr "" + +#: smartdns.js:923 +msgid "h3" +msgstr "" + +#: smartdns.js:928 +msgid "DNS Server group" +msgstr "" + +#: smartdns.js:947 +msgid "Exclude Default Group" +msgstr "" + +#: smartdns.js:947 +msgid "Exclude DNS Server from default group." +msgstr "" + +#: smartdns.js:954 +msgid "IP Blacklist Filtering" +msgstr "" + +#: smartdns.js:955 +msgid "Filtering IP with blacklist" +msgstr "" + +#: smartdns.js:961 +msgid "TLS Hostname Verify" +msgstr "" + +#: smartdns.js:962 +msgid "Set TLS hostname to verify." +msgstr "" + +#: smartdns.js:973 +msgid "No check certificate" +msgstr "" + +#: smartdns.js:974 +msgid "Do not check certificate." +msgstr "" + +#: smartdns.js:984 +msgid "TLS SNI name" +msgstr "" + +#: smartdns.js:985 +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "" + +#: smartdns.js:996 +msgid "HTTP Host" +msgstr "" + +#: smartdns.js:997 +msgid "" +"Set the HTTP host used for the query. Use this parameter when the host of " +"the URL address is an IP address." +msgstr "" + +#: smartdns.js:1006 +msgid "TLS SPKI Pinning" +msgstr "" + +#: smartdns.js:1007 +msgid "" +"Used to verify the validity of the TLS server, The value is Base64 encoded " +"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not " +"verified." +msgstr "" + +#: smartdns.js:1019 +msgid "Marking Packets" +msgstr "" + +#: smartdns.js:1020 +msgid "Set mark on packets." +msgstr "" + +#: smartdns.js:1027 +msgid "Use Proxy" +msgstr "" + +#: smartdns.js:1028 +msgid "Use proxy to connect to upstream DNS server." +msgstr "" + +#: smartdns.js:1042 +msgid "Please set proxy server first." +msgstr "" + +#: smartdns.js:1046 +msgid "Only socks5 proxy support udp server." +msgstr "" + +#: smartdns.js:1053 +msgid "Fallback" +msgstr "" + +#: smartdns.js:1054 +msgid "" +"Mark this server as a fallback server, use it only when default servers fail." +msgstr "" + +#: smartdns.js:1061 +msgid "Additional Args for upstream dns servers" +msgstr "" + +#: smartdns.js:1069 +msgid "Client Rules" +msgstr "" + +#: smartdns.js:1069 +msgid "Client Rules Settings, can achieve parental control functionality." +msgstr "" + +#: smartdns.js:1073 +msgid "Basic Settings" +msgstr "" + +#: smartdns.js:1075 smartdns.js:1277 +msgid "DNS Block Setting" +msgstr "" + +#: smartdns.js:1081 +msgid "Client Address" +msgstr "" + +#: smartdns.js:1082 +msgid "" +"If a client address is specified, only that client will apply this rule. You " +"can enter an IP address, such as 1.2.3.4, or a MAC address, such as aa:bb:cc:" +"dd:ee:ff." +msgstr "" + +#: smartdns.js:1103 +msgid "Client address format error, please input ip adress or mac address." +msgstr "" + +#: smartdns.js:1106 +msgid "Client Address File" +msgstr "" + +#: smartdns.js:1107 +msgid "Upload client address file, same as Client Address function." +msgstr "" + +#: smartdns.js:1114 smartdns.js:1284 smartdns.js:1494 +msgid "DNS Server group belongs to, such as office, home." +msgstr "" + +#: smartdns.js:1134 smartdns.js:1304 smartdns.js:1514 +#, javascript-format +msgid "Server Group %s not exists" +msgstr "" + +#: smartdns.js:1261 smartdns.js:1418 smartdns.js:1448 smartdns.js:1518 +msgid "Domain List File" +msgstr "" + +#: smartdns.js:1261 smartdns.js:1448 +msgid "Upload domain list file." +msgstr "" + +#: smartdns.js:1272 +msgid "Domain Rules" +msgstr "" + +#: smartdns.js:1272 +msgid "Domain Rules Settings" +msgstr "" + +#: smartdns.js:1276 +msgid "DNS Forwarding Setting" +msgstr "" + +#: smartdns.js:1278 smartdns.js:1476 +msgid "Domain Rule List" +msgstr "" + +#: smartdns.js:1278 +msgid "Set Specific domain rule list." +msgstr "" + +#: smartdns.js:1279 +msgid "Domain Address" +msgstr "" + +#: smartdns.js:1279 +msgid "Set Specific domain ip address." +msgstr "" + +#: smartdns.js:1366 smartdns.js:1540 +msgid "Yes" +msgstr "" + +#: smartdns.js:1367 smartdns.js:1541 +msgid "No" +msgstr "" + +#: smartdns.js:1412 smartdns.js:1627 smartdns.js:1724 +msgid "Additional Rule Flag" +msgstr "" + +#: smartdns.js:1413 smartdns.js:1628 +msgid "" +"Additional Flags for rules, read help on domain-rule for more information." +msgstr "" + +#: smartdns.js:1419 smartdns.js:1519 +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "" + +#: smartdns.js:1427 smartdns.js:1456 +msgid "Domain List" +msgstr "" + +#: smartdns.js:1427 +msgid "Configure forwarding domain name list." +msgstr "" + +#: smartdns.js:1456 +msgid "Configure block domain list." +msgstr "" + +#: smartdns.js:1477 +msgid "Configure domain rule list." +msgstr "" + +#: smartdns.js:1492 +msgid "Domain Rule Name" +msgstr "" + +#: smartdns.js:1525 +msgid "Block domain" +msgstr "" + +#: smartdns.js:1525 +msgid "Block domain." +msgstr "" + +#: smartdns.js:1638 +msgid "" +"Specify an IP address to return for any host in the given domains, Queries " +"in the domains are never forwarded and always replied to with the specified " +"IP address which may be IPv4 or IPv6." +msgstr "" + +#: smartdns.js:1657 +msgid "IP Rules" +msgstr "" + +#: smartdns.js:1657 +msgid "IP Rules Settings" +msgstr "" + +#: smartdns.js:1661 smartdns.js:1667 +msgid "IP Rule List" +msgstr "" + +#: smartdns.js:1661 +msgid "Set Specific ip rule list." +msgstr "" + +#: smartdns.js:1662 +msgid "IP Blacklist" +msgstr "" + +#: smartdns.js:1662 +msgid "Set Specific ip blacklist." +msgstr "" + +#: smartdns.js:1668 +msgid "Configure ip rule list." +msgstr "" + +#: smartdns.js:1683 +msgid "IP Rule Name" +msgstr "" + +#: smartdns.js:1687 +msgid "IP Set File" +msgstr "" + +#: smartdns.js:1687 +msgid "Upload IP set file." +msgstr "" + +#: smartdns.js:1693 +msgid "IP Addresses" +msgstr "" + +#: smartdns.js:1693 +msgid "IP addresses, CIDR format." +msgstr "" + +#: smartdns.js:1698 +msgid "Whitelist IP" +msgstr "" + +#: smartdns.js:1698 +msgid "Whitelist IP Rule, Accept IP addresses within the range." +msgstr "" + +#: smartdns.js:1703 +msgid "Blacklist IP" +msgstr "" + +#: smartdns.js:1703 +msgid "Blacklist IP Rule, Decline IP addresses within the range." +msgstr "" + +#: smartdns.js:1708 +msgid "Ignore IP" +msgstr "" + +#: smartdns.js:1708 +msgid "Do not use these IP addresses." +msgstr "" + +#: smartdns.js:1713 +msgid "Bogus nxdomain" +msgstr "" + +#: smartdns.js:1713 +msgid "Return SOA when the requested result contains a specified IP address." +msgstr "" + +#: smartdns.js:1718 +msgid "IP alias" +msgstr "" + +#: smartdns.js:1718 +msgid "" +"IP Address Mapping, Can be used for CDN acceleration with Anycast IP, such " +"as Cloudflare's CDN." +msgstr "" + +#: smartdns.js:1725 +msgid "Additional Flags for rules, read help on ip-rule for more information." +msgstr "" + +#: smartdns.js:1734 +msgid "" +"Configure IP blacklists that will be filtered from the results of specific " +"DNS server." +msgstr "" + +#: smartdns.js:1751 +msgid "Technical Support" +msgstr "" + +#: smartdns.js:1752 +msgid "If you like this software, please buy me a cup of coffee." +msgstr "" + +#: smartdns.js:1756 +msgid "SmartDNS official website" +msgstr "" + +#: smartdns.js:1757 +msgid "open website" +msgstr "" + +#: smartdns.js:1764 smartdns.js:1765 +msgid "Report bugs" +msgstr "" + +#: smartdns.js:1772 +msgid "Donate to smartdns" +msgstr "" + +#: smartdns.js:1773 +msgid "Donate" +msgstr "" + +#: smartdns.js:1779 +msgid "Restart Service" +msgstr "" + +#: smartdns.js:1788 +msgid "Restart" +msgstr "" \ No newline at end of file diff --git a/luci-app-smartdns/po/zh_Hans/smartdns.po b/luci-app-smartdns/po/zh_Hans/smartdns.po new file mode 100644 index 00000000..2bfc3374 --- /dev/null +++ b/luci-app-smartdns/po/zh_Hans/smartdns.po @@ -0,0 +1,1262 @@ +msgid "" +msgstr "" +"Project-Id-Version: luci-app-smartdns\n" +"POT-Creation-Date: 2025-11-13 01:05+0000\n" +"PO-Revision-Date: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.2\n" +"X-Poedit-Basepath: ../../htdocs/luci-static/resources/view/smartdns\n" +"X-Poedit-SearchPath-0: .\n" + +#: log.js:80 +msgid "Loading..." +msgstr "加载中..." + +#: log.js:82 smartdns.js:146 +msgid "Collecting data ..." +msgstr "正在收集数æ®..." + +#: log.js:92 +msgid "Clear Logs..." +msgstr "清除日志..." + +#: log.js:95 +msgid "Logs cleared successfully!" +msgstr "日志清除æˆåŠŸï¼" + +#: log.js:98 log.js:108 log.js:112 +msgid "Clear Logs" +msgstr "清除日志" + +#: log.js:101 log.js:119 +msgid "Log is clean." +msgstr "日志已清除。" + +#: log.js:105 +msgid "Failed to clear log." +msgstr "清除日志失败。" + +#: log.js:127 +msgid "Log file does not exist." +msgstr "日志文件ä¸å­˜åœ¨ã€‚" + +#: log.js:129 +#, javascript-format +msgid "Unknown error: %s" +msgstr "未知错误:%s" + +#: log.js:142 +msgid "Back SmartDNS" +msgstr "返回 SmartDNS" + +#: log.js:151 +#, javascript-format +msgid "Refresh every %s seconds." +msgstr "æ¯ %s 秒刷新。" + +#: smartdns.js:68 +msgid "RUNNING" +msgstr "è¿è¡Œä¸­" + +#: smartdns.js:74 +msgid "Open the WebUI" +msgstr "打开 WebUI" + +#: smartdns.js:77 +msgid "NOT RUNNING" +msgstr "未è¿è¡Œ" + +#: smartdns.js:79 +msgid "Please check the system logs and check if the configuration is valid." +msgstr "请检查系统日志,并检查é…置是å¦åˆæ³•。" + +#: smartdns.js:91 +msgid "Dnsmasq Forwarded To Smartdns Failure" +msgstr "é‡å®šå‘ Dnsmasq 到 SmartDNS 失败" + +#: smartdns.js:120 +msgid "SmartDNS" +msgstr "SmartDNS" + +#: smartdns.js:121 +msgid "SmartDNS Server" +msgstr "SmartDNS æœåС噍" + +#: smartdns.js:122 +msgid "" +"SmartDNS is a local high-performance DNS server, supports finding fastest " +"IP, supports ad filtering, and supports avoiding DNS poisoning." +msgstr "SmartDNS 是一个本地高性能 DNS æœåŠ¡å™¨ï¼Œæ”¯æŒè¿”回最快 IP,支æŒå¹¿å‘Šè¿‡æ»¤ã€‚" + +#: smartdns.js:153 +msgid "Settings" +msgstr "设置" + +#: smartdns.js:153 smartdns.js:156 smartdns.js:888 +msgid "General Settings" +msgstr "常规设置" + +#: smartdns.js:157 smartdns.js:889 smartdns.js:1074 +msgid "Advanced Settings" +msgstr "高级设置" + +#: smartdns.js:158 +msgid "Second Server Settings" +msgstr "第二 DNS æœåС噍" + +#: smartdns.js:159 +msgid "DNS64 Server Settings" +msgstr "DNS64 æœåС噍é…ç½®" + +#: smartdns.js:160 +msgid "Download Files Setting" +msgstr "下载文件设置" + +#: smartdns.js:160 +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" +"下载域å规则所需è¦çš„域å列表文件和 SmartDNS é…置文件,下载完æˆåŽåˆ·æ–°é¡µé¢ã€‚" + +#: smartdns.js:161 +msgid "Proxy Server Settings" +msgstr "ä»£ç†æœåŠ¡å™¨è®¾ç½®" + +#: smartdns.js:162 +msgid "Custom Settings" +msgstr "自定义设置" + +#: smartdns.js:167 smartdns.js:535 smartdns.js:892 smartdns.js:1077 +#: smartdns.js:1486 smartdns.js:1677 +msgid "Enable" +msgstr "å¯ç”¨" + +#: smartdns.js:167 +msgid "Enable or disable smartdns server" +msgstr "å¯ç”¨æˆ–ç¦ç”¨ SmartDNS æœåŠ¡" + +#: smartdns.js:172 +msgid "Server Name" +msgstr "æœåС噍åç§°" + +#: smartdns.js:172 +msgid "Smartdns server name" +msgstr "SmartDNS çš„æœåС噍å称,默认为 smartdns,留空为主机å" + +#: smartdns.js:178 smartdns.js:541 +msgid "Local Port" +msgstr "本地端å£" + +#: smartdns.js:179 +msgid "" +"Smartdns local server port, smartdns will be automatically set as main dns " +"when the port is 53." +msgstr "" +"SmartDNS 本地æœåŠ¡ç«¯å£ï¼Œå½“端å£å·è®¾ç½®ä¸º 53 时,SmartDNS 将会自动é…置为主 DNS。" + +#: smartdns.js:186 +msgid "Automatically Set Dnsmasq" +msgstr "自动设置 Dnsmasq" + +#: smartdns.js:186 +msgid "Automatically set as upstream of dnsmasq when port changes." +msgstr "ç«¯å£æ›´æ”¹æ—¶è‡ªåŠ¨è®¾ä¸º Dnsmasq 的上游。" + +#: smartdns.js:192 +msgid "Enable WebUI" +msgstr "å¯ç”¨ WebUI" + +#: smartdns.js:192 +msgid "Enable or disable smartdns webui plugin." +msgstr "å¯ç”¨æˆ–ç¦ç”¨ SmartDNS WebUI æ’件。" + +#: smartdns.js:196 +msgid "WebUI Port" +msgstr "WebUI 端å£" + +#: smartdns.js:196 +msgid "WebUI server port." +msgstr "WebUI æœåŠ¡ç«¯å£ã€‚" + +#: smartdns.js:202 +msgid "WebUI Data Dir" +msgstr "WebUI æ•°æ®åº“目录" + +#: smartdns.js:202 +msgid "Directory for storing the webui database." +msgstr "用于存储 WebUI æ•°æ®åº“的目录。" + +#: smartdns.js:208 +msgid "WebUI Log Retention" +msgstr "WebUI 日志ä¿å­˜å¤©æ•°" + +#: smartdns.js:208 +msgid "Number of days to retain webui logs." +msgstr "ä¿ç•™ WebUI 日志的天数。" + +#: smartdns.js:219 smartdns.js:1139 smartdns.js:1309 smartdns.js:1543 +msgid "Speed Check Mode" +msgstr "测速模å¼" + +#: smartdns.js:219 smartdns.js:1139 smartdns.js:1309 smartdns.js:1543 +msgid "Smartdns speed check mode." +msgstr "SmartDNS 测速模å¼ã€‚" + +#: smartdns.js:222 smartdns.js:274 smartdns.js:806 smartdns.js:1142 +#: smartdns.js:1312 smartdns.js:1365 smartdns.js:1539 smartdns.js:1547 +msgid "default" +msgstr "默认" + +#: smartdns.js:229 smartdns.js:1149 smartdns.js:1319 smartdns.js:1527 +#: smartdns.js:1554 +msgid "None" +msgstr "æ— " + +#: smartdns.js:250 smartdns.js:1170 smartdns.js:1340 smartdns.js:1575 +msgid "TCP port is empty" +msgstr "TCP 端å£å·ä¸ºç©º" + +#: smartdns.js:258 smartdns.js:1178 smartdns.js:1348 smartdns.js:1583 +msgid "TCP SYN port is empty" +msgstr "TCP SYN端å£å·ä¸ºç©º" + +#: smartdns.js:263 smartdns.js:1183 smartdns.js:1353 smartdns.js:1588 +msgid "Speed check mode is invalid." +msgstr "æµ‹é€Ÿæ¨¡å¼æ— æ•ˆã€‚" + +#: smartdns.js:270 +msgid "Response Mode" +msgstr "å“应模å¼" + +#: smartdns.js:271 +msgid "" +"Smartdns response mode, First Ping: return the first ping IP, Fastest IP: " +"return the fastest IP, Fastest Response: return the fastest DNS response." +msgstr "" +"SmartDNS å“应模å¼ï¼Œæœ€å¿« Ping:返回最早有 ping 结果的 IP,速度适中;最快 IP:返回" +"最快 IP,查询请求å¯èƒ½å»¶é•¿ï¼›æœ€å¿«å“应:返回最快å“应的结果,查询请求时间短。" + +#: smartdns.js:275 +msgid "First Ping" +msgstr "最快 Ping" + +#: smartdns.js:276 +msgid "Fastest IP" +msgstr "最快 IP" + +#: smartdns.js:277 +msgid "Fastest Response" +msgstr "最快å“应" + +#: smartdns.js:280 smartdns.js:548 +msgid "TCP Server" +msgstr "TCP æœåС噍" + +#: smartdns.js:280 smartdns.js:548 +msgid "Enable TCP DNS Server" +msgstr "å¯ç”¨ TCP æœåŠ¡å™¨ã€‚" + +#: smartdns.js:285 +msgid "DOT Server" +msgstr "DOT æœåС噍" + +#: smartdns.js:285 +msgid "Enable DOT DNS Server" +msgstr "å¯ç”¨ DOT æœåС噍" + +#: smartdns.js:289 +msgid "DOT Server Port" +msgstr "DOT æœåŠ¡å™¨ç«¯å£" + +#: smartdns.js:289 +msgid "Smartdns DOT server port." +msgstr "SmartDNS DOT æœåŠ¡å™¨ç«¯å£å·ã€‚" + +#: smartdns.js:297 +msgid "DOH Server" +msgstr "DOH æœåС噍" + +#: smartdns.js:297 +msgid "Enable DOH DNS Server" +msgstr "å¯ç”¨ DOH æœåС噍" + +#: smartdns.js:301 +msgid "DOH Server Port" +msgstr "DOH æœåŠ¡å™¨ç«¯å£" + +#: smartdns.js:301 +msgid "Smartdns DOH server port." +msgstr "SmartDNS DOH æœåŠ¡å™¨ç«¯å£å·" + +#: smartdns.js:308 +msgid "Server Cert" +msgstr "æœåС噍è¯ä¹¦" + +#: smartdns.js:308 +msgid "Server certificate file path." +msgstr "æœåС噍è¯ä¹¦æ–‡ä»¶è·¯å¾„。" + +#: smartdns.js:315 +msgid "Server Cert Key" +msgstr "æœåС噍è¯ä¹¦ç§é’¥" + +#: smartdns.js:315 +msgid "Server certificate key file path." +msgstr "æœåС噍è¯ä¹¦ç§é’¥æ–‡ä»¶è·¯å¾„。" + +#: smartdns.js:322 +msgid "Server Cert Key Pass" +msgstr "æœåС噍è¯ä¹¦ç§é’¥å¯†ç " + +#: smartdns.js:322 +msgid "Server certificate key file password." +msgstr "æœåС噍è¯ä¹¦ç§é’¥æ–‡ä»¶å¯†ç ã€‚" + +#: smartdns.js:329 +msgid "IPv6 Server" +msgstr "IPv6 æœåС噍" + +#: smartdns.js:329 +msgid "Enable IPv6 DNS Server" +msgstr "å¯ç”¨ IPv6 æœåŠ¡å™¨ã€‚" + +#: smartdns.js:334 +msgid "Bind Device" +msgstr "绑定到设备" + +#: smartdns.js:334 +msgid "Listen only on the specified interfaces." +msgstr "监å¬åœ¨æŒ‡å®šçš„设备上,é¿å…éžæœ¬åœ°ç½‘络的 DNS 查询请求。" + +#: smartdns.js:339 +msgid "Bind Device Name" +msgstr "绑定的设备åç§°" + +#: smartdns.js:339 +msgid "Name of device name listen on." +msgstr "绑定的设备å称。" + +#: smartdns.js:345 smartdns.js:1190 smartdns.js:1360 smartdns.js:1534 +msgid "Dual-stack IP Selection" +msgstr "åŒæ ˆ IP 优选" + +#: smartdns.js:346 smartdns.js:1191 smartdns.js:1361 smartdns.js:1535 +msgid "Enable IP selection between IPv4 and IPv6" +msgstr "å¯ç”¨ IPv4 å’Œ IPv6 é—´çš„ IP 优选策略。" + +#: smartdns.js:351 +msgid "Domain prefetch" +msgstr "域å预加载" + +#: smartdns.js:352 +msgid "Enable domain prefetch, accelerate domain response speed." +msgstr "å¯ç”¨åŸŸå预加载,加速域åå“应速度。" + +#: smartdns.js:357 +msgid "Serve expired" +msgstr "缓存过期æœåŠ¡" + +#: smartdns.js:358 +msgid "" +"Attempts to serve old responses from cache with a TTL of 0 in the response " +"without waiting for the actual resolution to finish." +msgstr "查询性能优化,有请求时å°è¯•回应 TTL 为 0 的过期记录,以é¿å…查询等待。" + +#: smartdns.js:363 +msgid "Cache Size" +msgstr "缓存大å°" + +#: smartdns.js:363 +msgid "DNS domain result cache size" +msgstr "缓存 DNS 的结果,缓存大å°ï¼Œé…置零则ä¸ç¼“存。" + +#: smartdns.js:367 +msgid "Cache Persist" +msgstr "æŒä¹…化缓存" + +#: smartdns.js:367 +msgid "Write cache to disk on exit and load on startup." +msgstr "退出时ä¿å­˜ Cache 到ç£ç›˜ï¼Œå¯åŠ¨æ—¶åŠ è½½ã€‚" + +#: smartdns.js:372 +msgid "Resolve Local Hostnames" +msgstr "è§£æžæœ¬åœ°ä¸»æœºå" + +#: smartdns.js:372 +msgid "Resolve local hostnames by reading Dnsmasq lease file." +msgstr "è¯»å– Dnsmasq çš„ç§Ÿçº¦æ–‡ä»¶è§£æžæœ¬åœ°ä¸»æœºå。" + +#: smartdns.js:377 +msgid "mDNS Lookup" +msgstr "mDNS 查询" + +#: smartdns.js:377 +msgid "Resolve local network hostname via mDNS protocol." +msgstr "使用 mDNS åè®®è§£æžæœ¬åœ°ç½‘络主机å。" + +#: smartdns.js:382 smartdns.js:600 smartdns.js:1196 smartdns.js:1369 +#: smartdns.js:1594 +msgid "Force AAAA SOA" +msgstr "åœç”¨ IPv6 地å€è§£æž" + +#: smartdns.js:382 smartdns.js:600 smartdns.js:1196 smartdns.js:1369 +#: smartdns.js:1594 +msgid "Force AAAA SOA." +msgstr "åœç”¨ IPv6 地å€è§£æžã€‚" + +#: smartdns.js:387 smartdns.js:605 smartdns.js:1201 +msgid "Force HTTPS SOA" +msgstr "åœç”¨ HTTPS 记录解æž" + +#: smartdns.js:387 smartdns.js:605 smartdns.js:1201 +msgid "Force HTTPS SOA." +msgstr "åœç”¨ HTTPS 记录解æžã€‚" + +#: smartdns.js:392 smartdns.js:613 smartdns.js:1206 smartdns.js:1373 +#: smartdns.js:1600 +msgid "IPset Name" +msgstr "IPset åç§°" + +#: smartdns.js:392 smartdns.js:613 smartdns.js:1206 smartdns.js:1373 +#: smartdns.js:1600 +msgid "IPset name." +msgstr "IPset å称。" + +#: smartdns.js:404 smartdns.js:425 smartdns.js:625 smartdns.js:1218 +#: smartdns.js:1385 +msgid "ipset name format error, format: [#[4|6]:]ipsetname" +msgstr "IPset åç§°æ ¼å¼é”™è¯¯ï¼Œæ ¼å¼ï¼š[#[4|6]:]ipsetname" + +#: smartdns.js:412 +msgid "No Speed IPset Name" +msgstr "无速度时 IPset åç§°" + +#: smartdns.js:413 +msgid "Ipset name, Add domain result to ipset when speed check fails." +msgstr "IPset å称,当测速失败时,将查询到的结果添加到对应的 IPset 集åˆä¸­ã€‚" + +#: smartdns.js:433 smartdns.js:632 smartdns.js:1226 smartdns.js:1392 +#: smartdns.js:1606 +msgid "NFTset Name" +msgstr "NFTset åç§°" + +#: smartdns.js:433 smartdns.js:632 smartdns.js:1226 smartdns.js:1392 +#: smartdns.js:1606 +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "NFTset å称,格å¼ï¼š[#[4|6]:[family#table#set]]" + +#: smartdns.js:445 smartdns.js:466 smartdns.js:644 smartdns.js:1238 +#: smartdns.js:1404 smartdns.js:1619 +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "NFTset åç§°æ ¼å¼é”™è¯¯ï¼Œæ ¼å¼ï¼š[#[4|6]:[family#table#set]]" + +#: smartdns.js:453 +msgid "No Speed NFTset Name" +msgstr "无速度时 NFTset åç§°" + +#: smartdns.js:454 +msgid "" +"Nftset name, Add domain result to nftset when speed check fails, format: " +"[#[4|6]:[family#table#set]]" +msgstr "NFTset å称,当测速失败时,将查询到的结果添加到对应的 NFTset 集åˆä¸­ã€‚" + +#: smartdns.js:474 +msgid "Domain TTL" +msgstr "域å TTL" + +#: smartdns.js:474 +msgid "TTL for all domain result." +msgstr "设置所有域åçš„ TTL 值。" + +#: smartdns.js:478 +msgid "Domain TTL Min" +msgstr "域å TTL 最å°å€¼" + +#: smartdns.js:479 +msgid "Minimum TTL for all domain result." +msgstr "所有域åçš„æœ€å° TTL 值。" + +#: smartdns.js:486 +msgid "Domain TTL Max" +msgstr "域å TTL 最大值" + +#: smartdns.js:487 +msgid "Maximum TTL for all domain result." +msgstr "所有域å的最大 TTL 值。" + +#: smartdns.js:491 +msgid "Reply Domain TTL Max" +msgstr "回应的域å TTL 最大值" + +#: smartdns.js:492 +msgid "Reply maximum TTL for all domain result." +msgstr "设置返回给客户端的域å TTL 最大值。" + +#: smartdns.js:496 smartdns.js:652 smartdns.js:1060 +msgid "Additional Server Args" +msgstr "é¢å¤–çš„æœåС噍傿•°" + +#: smartdns.js:497 smartdns.js:653 +msgid "" +"Additional server args, refer to the help description of the bind option." +msgstr "é¢å¤–çš„æœåС噍傿•°ï¼Œå‚考 bind 选项的帮助说明。" + +#: smartdns.js:503 smartdns.js:1247 +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "包å«é…置文件
/etc/smartdns/conf.d" + +#: smartdns.js:504 smartdns.js:1248 +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" +"包å«é…置文件,路径为 /etc/smartdns/conf.d,或自定义é…置文件路径,å¯ä»¥ä»Žä¸‹è½½é¡µ" +"é¢é…置自动下载。" + +#: smartdns.js:517 +msgid "Hosts File" +msgstr "Hosts 文件" + +#: smartdns.js:517 +msgid "Include hosts file." +msgstr "åŒ…å« hosts 文件。" + +#: smartdns.js:536 +msgid "Enable or disable second DNS server." +msgstr "是å¦å¯ç”¨ç¬¬äºŒ DNS æœåŠ¡å™¨ã€‚" + +#: smartdns.js:541 +msgid "Smartdns local server port" +msgstr "SmartDNS 本地æœåŠ¡ç«¯å£" + +#: smartdns.js:553 smartdns.js:928 smartdns.js:1114 smartdns.js:1284 +#: smartdns.js:1494 +msgid "Server Group" +msgstr "æœåŠ¡å™¨ç»„" + +#: smartdns.js:554 +msgid "Query DNS through specific dns server group, such as office, home." +msgstr "使用指定æœåŠ¡å™¨ç»„æŸ¥è¯¢ï¼Œæ¯”å¦‚ officeã€home。" + +#: smartdns.js:560 +msgid "Skip Speed Check" +msgstr "跳过测速" + +#: smartdns.js:561 +msgid "Do not check speed." +msgstr "ç¦ç”¨æµ‹é€Ÿã€‚" + +#: smartdns.js:566 +msgid "Skip Address Rules" +msgstr "跳过 address 规则" + +#: smartdns.js:567 +msgid "Skip address rules." +msgstr "跳过 address 规则。" + +#: smartdns.js:572 +msgid "Skip Nameserver Rule" +msgstr "跳过 Nameserver 规则" + +#: smartdns.js:573 +msgid "Skip nameserver rules." +msgstr "跳过 Nameserver 规则。" + +#: smartdns.js:578 +msgid "Skip Ipset Rule" +msgstr "跳过 ipset 规则" + +#: smartdns.js:579 +msgid "Skip ipset rules." +msgstr "跳过 ipset 规则。" + +#: smartdns.js:584 +msgid "Skip SOA Address Rule" +msgstr "跳过 address SOA(#) 规则" + +#: smartdns.js:585 +msgid "Skip SOA address rules." +msgstr "跳过 address SOA(#) 规则。" + +#: smartdns.js:589 +msgid "Skip Dualstack Selection" +msgstr "è·³è¿‡åŒæ ˆä¼˜é€‰" + +#: smartdns.js:590 +msgid "Skip Dualstack Selection." +msgstr "è·³è¿‡åŒæ ˆä¼˜é€‰ã€‚" + +#: smartdns.js:595 +msgid "Skip Cache" +msgstr "跳过 Cache" + +#: smartdns.js:595 +msgid "Skip Cache." +msgstr "跳过 Cache。" + +#: smartdns.js:609 +msgid "Skip IP Alias" +msgstr "跳过 IP 别å" + +#: smartdns.js:660 +msgid "DNS64" +msgstr "DNS64" + +#: smartdns.js:668 +msgid "Enable Auto Update" +msgstr "å¯ç”¨è‡ªåŠ¨æ›´æ–°" + +#: smartdns.js:668 +msgid "Enable daily (weekly) auto update." +msgstr "å¯ç”¨æ¯æ—¥ï¼ˆæ¯å‘¨ï¼‰è‡ªåŠ¨æ›´æ–°" + +#: smartdns.js:673 +msgid "Update Time (Every Week)" +msgstr "更新时间(æ¯å‘¨ï¼‰" + +#: smartdns.js:674 +msgid "Every Day" +msgstr "æ¯å¤©" + +#: smartdns.js:675 +msgid "Every Monday" +msgstr "æ¯å‘¨ä¸€" + +#: smartdns.js:676 +msgid "Every Tuesday" +msgstr "æ¯å‘¨äºŒ" + +#: smartdns.js:677 +msgid "Every Wednesday" +msgstr "æ¯å‘¨ä¸‰" + +#: smartdns.js:678 +msgid "Every Thursday" +msgstr "æ¯å‘¨å››" + +#: smartdns.js:679 +msgid "Every Friday" +msgstr "æ¯å‘¨äº”" + +#: smartdns.js:680 +msgid "Every Saturday" +msgstr "æ¯å‘¨å…­" + +#: smartdns.js:681 +msgid "Every Sunday" +msgstr "æ¯å‘¨æ—¥" + +#: smartdns.js:685 +msgid "Update time (every day)" +msgstr "更新时间(æ¯å¤©ï¼‰" + +#: smartdns.js:691 +msgid "Upload Config File" +msgstr "上传é…置文件" + +#: smartdns.js:692 +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "上传é…置文件到 /etc/smartdns/conf.d" + +#: smartdns.js:698 +msgid "Upload Domain List File" +msgstr "上传域å列表文件" + +#: smartdns.js:699 +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "上传域å列表文件到 /etc/smartdns/domain-set" + +#: smartdns.js:705 +msgid "Upload File" +msgstr "上传文件" + +#: smartdns.js:711 +msgid "Update Files" +msgstr "更新文件" + +#: smartdns.js:720 +msgid "Update" +msgstr "æ›´æ–°" + +#: smartdns.js:723 +msgid "Download Files" +msgstr "下载文件" + +#: smartdns.js:724 +msgid "List of files to download." +msgstr "下载文件列表。" + +#: smartdns.js:732 +msgid "File Name" +msgstr "文件å" + +#: smartdns.js:736 +msgid "URL" +msgstr "URL" + +#: smartdns.js:745 +msgid "URL format error, format: http:// or https://" +msgstr "URL æ ¼å¼é”™è¯¯ï¼Œæ ¼å¼ï¼šhttp:// 或 https://" + +#: smartdns.js:751 smartdns.js:916 +msgid "type" +msgstr "类型" + +#: smartdns.js:751 +msgid "File Type" +msgstr "文件类型" + +#: smartdns.js:752 +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "域å列表(/etc/smartdns/domain-set)" + +#: smartdns.js:753 +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "SmartDNS é…置文件(/etc/smartdns/conf.d)" + +#: smartdns.js:754 +msgid "ip-set file (/etc/smartdns/ip-set)" +msgstr "IP 集åˆåˆ—表文件(/etc/smartdns/ip-set)" + +#: smartdns.js:755 +msgid "other file (/etc/smartdns/download)" +msgstr "其它文件(/etc/smartdns/download)" + +#: smartdns.js:759 +msgid "Description" +msgstr "æè¿°" + +#: smartdns.js:766 +msgid "Proxy Server" +msgstr "ä»£ç†æœåС噍" + +#: smartdns.js:766 +msgid "Proxy Server URL, format: [socks5|http]://user:pass@ip:port." +msgstr "ä»£ç†æœåŠ¡å™¨åœ°å€ï¼Œæ ¼å¼ï¼š[socks5|http]://user:pass@ip:port。" + +#: smartdns.js:774 +msgid "" +"Proxy server URL format error, format: [socks5|http]://user:pass@ip:port." +msgstr "ä»£ç†æœåŠ¡å™¨åœ°å€æ ¼å¼é”™è¯¯ï¼Œæ ¼å¼ï¼š[socks5|http]://user:pass@ip:port。" + +#: smartdns.js:784 +msgid "smartdns custom settings" +msgstr "SmartDNS 自定义设置,具体é…ç½®å‚æ•°å‚考指导" + +#: smartdns.js:798 +msgid "Generate Coredump" +msgstr "ç”Ÿæˆ Coredump" + +#: smartdns.js:799 +msgid "" +"Generate Coredump file when smartdns crash, coredump file is located at /tmp/" +"smartdns.xxx.core." +msgstr "" +"当 SmartDNS å¼‚å¸¸æ—¶ç”Ÿæˆ Coredump 文件,Coredump 文件在 /tmp/smartdns.xxx.core。" + +#: smartdns.js:803 +msgid "Log Level" +msgstr "日志级别" + +#: smartdns.js:815 +msgid "Log Output Mode" +msgstr "日志输出模å¼" + +#: smartdns.js:818 smartdns.js:859 +msgid "file" +msgstr "文件" + +#: smartdns.js:819 smartdns.js:860 +msgid "syslog" +msgstr "系统日志" + +#: smartdns.js:821 +msgid "Log Size" +msgstr "日志大å°" + +#: smartdns.js:826 +msgid "Log Number" +msgstr "日志数é‡" + +#: smartdns.js:831 +msgid "Log File" +msgstr "日志文件路径" + +#: smartdns.js:836 smartdns.js:844 +msgid "View Log" +msgstr "查看日志" + +#: smartdns.js:851 +msgid "Enable Audit Log" +msgstr "å¯ç”¨å®¡è®¡æ—¥å¿—" + +#: smartdns.js:856 +msgid "Audit Log Output Mode" +msgstr "审计日志输出模å¼" + +#: smartdns.js:863 +msgid "Audit Log Size" +msgstr "审计日志大å°" + +#: smartdns.js:868 +msgid "Audit Log Number" +msgstr "审计日志数é‡" + +#: smartdns.js:873 +msgid "Audit Log File" +msgstr "审计日志文件路径" + +#: smartdns.js:881 +msgid "Upstream Servers" +msgstr "上游æœåС噍" + +#: smartdns.js:882 +msgid "" +"Upstream Servers, support UDP, TCP, DoT, DoH, DoQ, DoH3 protocol. Please " +"configure multiple DNS servers, including multiple foreign DNS servers." +msgstr "" +"上游 DNS æœåŠ¡å™¨ï¼Œæ”¯æŒ UDP,TCP,DoT,DoH,DoQ,DoH3 å议。请é…置多个上游 DNS " +"æœåŠ¡å™¨ï¼ŒåŒ…æ‹¬å¤šä¸ªå›½å†…å¤–æœåŠ¡å™¨ã€‚" + +#: smartdns.js:898 +msgid "DNS Server Name" +msgstr "DNS æœåС噍åç§°" + +#: smartdns.js:901 +msgid "ip" +msgstr "ip" + +#: smartdns.js:901 +msgid "DNS Server ip" +msgstr "DNS æœåС噍 IP" + +#: smartdns.js:906 +msgid "port" +msgstr "端å£" + +#: smartdns.js:906 +msgid "DNS Server port" +msgstr "DNS æœåŠ¡å™¨ç«¯å£" + +#: smartdns.js:916 +msgid "DNS Server type" +msgstr "å议类型" + +#: smartdns.js:918 +msgid "udp" +msgstr "udp" + +#: smartdns.js:919 +msgid "tcp" +msgstr "tcp" + +#: smartdns.js:920 +msgid "tls" +msgstr "tls" + +#: smartdns.js:921 +msgid "https" +msgstr "https" + +#: smartdns.js:922 +msgid "quic" +msgstr "quic" + +#: smartdns.js:923 +msgid "h3" +msgstr "h3" + +#: smartdns.js:928 +msgid "DNS Server group" +msgstr "æœåŠ¡å™¨ç»„" + +#: smartdns.js:947 +msgid "Exclude Default Group" +msgstr "从默认组中排除" + +#: smartdns.js:947 +msgid "Exclude DNS Server from default group." +msgstr "从 default 默认æœåŠ¡å™¨ç»„ä¸­æŽ’é™¤ã€‚" + +#: smartdns.js:954 +msgid "IP Blacklist Filtering" +msgstr "IP 黑åå•过滤" + +#: smartdns.js:955 +msgid "Filtering IP with blacklist" +msgstr "使用 IP 黑åå•过滤" + +#: smartdns.js:961 +msgid "TLS Hostname Verify" +msgstr "校验 TLS 主机å" + +#: smartdns.js:962 +msgid "Set TLS hostname to verify." +msgstr "设置校验 TLS 主机å。" + +#: smartdns.js:973 +msgid "No check certificate" +msgstr "åœç”¨è¯ä¹¦æ ¡éªŒ" + +#: smartdns.js:974 +msgid "Do not check certificate." +msgstr "䏿 ¡éªŒè¯ä¹¦çš„åˆæ³•性。" + +#: smartdns.js:984 +msgid "TLS SNI name" +msgstr "TLS SNI åç§°" + +#: smartdns.js:985 +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "设置æœåС噍 SNI å称,‘-’表示ç¦ç”¨ SNI å称。" + +#: smartdns.js:996 +msgid "HTTP Host" +msgstr "HTTP 主机" + +#: smartdns.js:997 +msgid "" +"Set the HTTP host used for the query. Use this parameter when the host of " +"the URL address is an IP address." +msgstr "设置查询时使用的 HTTP 主机,当 URL 地å€çš„ host 是 IP åœ°å€æ—¶ï¼Œä½¿ç”¨æ­¤å‚数。" + +#: smartdns.js:1006 +msgid "TLS SPKI Pinning" +msgstr "TLS SPKI 指纹" + +#: smartdns.js:1007 +msgid "" +"Used to verify the validity of the TLS server, The value is Base64 encoded " +"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not " +"verified." +msgstr "" +"用于校验 TLS æœåŠ¡å™¨çš„æœ‰æ•ˆæ€§ï¼Œæ•°å€¼ä¸º Base64 ç¼–ç çš„ SPKI 指纹,留空表示ä¸éªŒè¯ " +"TLS çš„åˆæ³•性。" + +#: smartdns.js:1019 +msgid "Marking Packets" +msgstr "æ•°æ®åŒ…标记" + +#: smartdns.js:1020 +msgid "Set mark on packets." +msgstr "设置数æ®åŒ…标记。" + +#: smartdns.js:1027 +msgid "Use Proxy" +msgstr "使用代ç†" + +#: smartdns.js:1028 +msgid "Use proxy to connect to upstream DNS server." +msgstr "使用代ç†è¿žæŽ¥ä¸Šæ¸¸ DNS æœåŠ¡å™¨ã€‚" + +#: smartdns.js:1042 +msgid "Please set proxy server first." +msgstr "è¯·å…ˆè®¾ç½®ä»£ç†æœåŠ¡å™¨ã€‚" + +#: smartdns.js:1046 +msgid "Only socks5 proxy support udp server." +msgstr "ä»… SOCKS5 ä»£ç†æ”¯æŒ UDP æœåŠ¡å™¨ã€‚" + +#: smartdns.js:1053 +msgid "Fallback" +msgstr "备用æœåС噍" + +#: smartdns.js:1054 +msgid "" +"Mark this server as a fallback server, use it only when default servers fail." +msgstr "使用该æœåŠ¡å™¨ä½œä¸ºå¤‡ç”¨æœåŠ¡å™¨ï¼Œåœ¨é»˜è®¤æœåŠ¡å™¨å¤±æ•ˆæ—¶å¯ç”¨ã€‚" + +#: smartdns.js:1061 +msgid "Additional Args for upstream dns servers" +msgstr "é¢å¤–的上游 DNS æœåС噍傿•°" + +#: smartdns.js:1069 +msgid "Client Rules" +msgstr "客户端规则" + +#: smartdns.js:1069 +msgid "Client Rules Settings, can achieve parental control functionality." +msgstr "客户端规则设置,å¯ä»¥å®žçŽ°å®¶é•¿æŽ§åˆ¶åŠŸèƒ½ã€‚" + +#: smartdns.js:1073 +msgid "Basic Settings" +msgstr "基本设置" + +#: smartdns.js:1075 smartdns.js:1277 +msgid "DNS Block Setting" +msgstr "域åå±è”½è®¾ç½®" + +#: smartdns.js:1081 +msgid "Client Address" +msgstr "客户端地å€" + +#: smartdns.js:1082 +msgid "" +"If a client address is specified, only that client will apply this rule. You " +"can enter an IP address, such as 1.2.3.4, or a MAC address, such as aa:bb:cc:" +"dd:ee:ff." +msgstr "" +"如果指定了客户端,那么对应的客户端会应用相应的规则,å¯ä»¥è¾“å…¥ IP 地å€ï¼Œå¦‚:" +"1.2.3.4,或 MAC 地å€ï¼Œå¦‚:aa:bb:cc:dd:ee:ff。" + +#: smartdns.js:1103 +msgid "Client address format error, please input ip adress or mac address." +msgstr "å®¢æˆ·ç«¯åœ°å€æ ¼å¼é”™è¯¯ï¼Œè¯·è¾“å…¥ IP åœ°å€æˆ– MAC 地å€ã€‚" + +#: smartdns.js:1106 +msgid "Client Address File" +msgstr "å®¢æˆ·ç«¯åœ°å€æ–‡ä»¶" + +#: smartdns.js:1107 +msgid "Upload client address file, same as Client Address function." +msgstr "ä¸Šä¼ å®¢æˆ·ç«¯åœ°å€æ–‡ä»¶ï¼Œä¸Žå®¢æˆ·ç«¯åœ°å€åŠŸèƒ½ç›¸åŒã€‚" + +#: smartdns.js:1114 smartdns.js:1284 smartdns.js:1494 +msgid "DNS Server group belongs to, such as office, home." +msgstr "设置æœåŠ¡å™¨ç»„ï¼Œä¾‹å¦‚ officeã€home" + +#: smartdns.js:1134 smartdns.js:1304 smartdns.js:1514 +#, javascript-format +msgid "Server Group %s not exists" +msgstr "æœåŠ¡å™¨ç»„ %s ä¸å­˜åœ¨" + +#: smartdns.js:1261 smartdns.js:1418 smartdns.js:1448 smartdns.js:1518 +msgid "Domain List File" +msgstr "域å列表文件" + +#: smartdns.js:1261 smartdns.js:1448 +msgid "Upload domain list file." +msgstr "上传域å列表文件" + +#: smartdns.js:1272 +msgid "Domain Rules" +msgstr "域å规则" + +#: smartdns.js:1272 +msgid "Domain Rules Settings" +msgstr "域å规则设置" + +#: smartdns.js:1276 +msgid "DNS Forwarding Setting" +msgstr "域å分æµè®¾ç½®" + +#: smartdns.js:1278 smartdns.js:1476 +msgid "Domain Rule List" +msgstr "域å规则列表" + +#: smartdns.js:1278 +msgid "Set Specific domain rule list." +msgstr "设置指定域å的规则列表。" + +#: smartdns.js:1279 +msgid "Domain Address" +msgstr "域å地å€" + +#: smartdns.js:1279 +msgid "Set Specific domain ip address." +msgstr "设置指定域åçš„ IP 地å€ã€‚" + +#: smartdns.js:1366 smartdns.js:1540 +msgid "Yes" +msgstr "是" + +#: smartdns.js:1367 smartdns.js:1541 +msgid "No" +msgstr "å¦" + +#: smartdns.js:1412 smartdns.js:1627 smartdns.js:1724 +msgid "Additional Rule Flag" +msgstr "é¢å¤–规则标识" + +#: smartdns.js:1413 smartdns.js:1628 +msgid "" +"Additional Flags for rules, read help on domain-rule for more information." +msgstr "é¢å¤–的规则标识,具体å‚考 domain-rule 的帮助说明。" + +#: smartdns.js:1419 smartdns.js:1519 +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "上传域å列表文件,或在下载文件设置页é¢è®¾ç½®è‡ªåŠ¨ä¸‹è½½ã€‚" + +#: smartdns.js:1427 smartdns.js:1456 +msgid "Domain List" +msgstr "域å列表" + +#: smartdns.js:1427 +msgid "Configure forwarding domain name list." +msgstr "é…置分æµåŸŸå列表" + +#: smartdns.js:1456 +msgid "Configure block domain list." +msgstr "é…ç½®å±è”½åŸŸå列表" + +#: smartdns.js:1477 +msgid "Configure domain rule list." +msgstr "é…置域å规则列表" + +#: smartdns.js:1492 +msgid "Domain Rule Name" +msgstr "域å规则åç§°" + +#: smartdns.js:1525 +msgid "Block domain" +msgstr "å±è”½åŸŸå" + +#: smartdns.js:1525 +msgid "Block domain." +msgstr "å±è”½åŸŸå。" + +#: smartdns.js:1638 +msgid "" +"Specify an IP address to return for any host in the given domains, Queries " +"in the domains are never forwarded and always replied to with the specified " +"IP address which may be IPv4 or IPv6." +msgstr "" +"é…置特定域å返回特定的 IP 地å€ï¼ŒåŸŸå查询将ä¸åˆ°ä¸Šæ¸¸æœåŠ¡å™¨è¯·æ±‚ï¼Œç›´æŽ¥è¿”å›žé…置的 IP" +"地å€ï¼Œå¯ç”¨äºŽå¹¿å‘Šå±è”½ã€‚" + +#: smartdns.js:1657 +msgid "IP Rules" +msgstr "IP 规则" + +#: smartdns.js:1657 +msgid "IP Rules Settings" +msgstr "IP 规则设置" + +#: smartdns.js:1661 smartdns.js:1667 +msgid "IP Rule List" +msgstr "IP 规则列表" + +#: smartdns.js:1661 +msgid "Set Specific ip rule list." +msgstr "设置对应 IP 的规则。" + +#: smartdns.js:1662 +msgid "IP Blacklist" +msgstr "IP 黑åå•" + +#: smartdns.js:1662 +msgid "Set Specific ip blacklist." +msgstr "设置指定的 IP 黑åå•列表。" + +#: smartdns.js:1668 +msgid "Configure ip rule list." +msgstr "é…ç½® IP 规则列表" + +#: smartdns.js:1683 +msgid "IP Rule Name" +msgstr "IP 规则åç§°" + +#: smartdns.js:1687 +msgid "IP Set File" +msgstr "IP 集åˆåˆ—表文件" + +#: smartdns.js:1687 +msgid "Upload IP set file." +msgstr "上传 IP 集åˆåˆ—表文件。" + +#: smartdns.js:1693 +msgid "IP Addresses" +msgstr "IP 地å€" + +#: smartdns.js:1693 +msgid "IP addresses, CIDR format." +msgstr "IP 地å€ï¼ŒCIDR æ ¼å¼ã€‚" + +#: smartdns.js:1698 +msgid "Whitelist IP" +msgstr "白åå•" + +#: smartdns.js:1698 +msgid "Whitelist IP Rule, Accept IP addresses within the range." +msgstr "白åå•è§„åˆ™ï¼ŒæŽ¥å—æŒ‡å®šèŒƒå›´çš„ IP 地å€ã€‚" + +#: smartdns.js:1703 +msgid "Blacklist IP" +msgstr "黑åå•" + +#: smartdns.js:1703 +msgid "Blacklist IP Rule, Decline IP addresses within the range." +msgstr "黑åå•è§„åˆ™ï¼Œæ‹’ç»æŒ‡å®šèŒƒå›´çš„ IP 地å€ã€‚" + +#: smartdns.js:1708 +msgid "Ignore IP" +msgstr "忽略 IP" + +#: smartdns.js:1708 +msgid "Do not use these IP addresses." +msgstr "忽略这些 IP 地å€" + +#: smartdns.js:1713 +msgid "Bogus nxdomain" +msgstr "å‡å†’ IP" + +#: smartdns.js:1713 +msgid "Return SOA when the requested result contains a specified IP address." +msgstr "当结果包å«å¯¹åº”范围的 IP 时,返回 SOA。" + +#: smartdns.js:1718 +msgid "IP alias" +msgstr "IP 别å" + +#: smartdns.js:1718 +msgid "" +"IP Address Mapping, Can be used for CDN acceleration with Anycast IP, such " +"as Cloudflare's CDN." +msgstr "IP åœ°å€æ˜ å°„,å¯ç”¨äºŽæ”¯æŒ Anycast IP çš„ CDN 加速,比如 Cloudflare çš„ CDN。" + +#: smartdns.js:1725 +msgid "Additional Flags for rules, read help on ip-rule for more information." +msgstr "é¢å¤–的规则标识,具体å‚考 ip-rule 的帮助说明。" + +#: smartdns.js:1734 +msgid "" +"Configure IP blacklists that will be filtered from the results of specific " +"DNS server." +msgstr "é…置需è¦ä»ŽæŒ‡å®šåŸŸåæœåŠ¡å™¨ç»“æžœè¿‡æ»¤çš„ IP 黑åå•。" + +#: smartdns.js:1751 +msgid "Technical Support" +msgstr "技术支æŒ" + +#: smartdns.js:1752 +msgid "If you like this software, please buy me a cup of coffee." +msgstr "如果本软件对你有帮助,请给作者加个蛋。" + +#: smartdns.js:1756 +msgid "SmartDNS official website" +msgstr "SmartDNS 官方网站" + +#: smartdns.js:1757 +msgid "open website" +msgstr "打开网站" + +#: smartdns.js:1764 smartdns.js:1765 +msgid "Report bugs" +msgstr "报告 Bug" + +#: smartdns.js:1772 +msgid "Donate to smartdns" +msgstr "æåŠ© SmartDNS 项目" + +#: smartdns.js:1773 +msgid "Donate" +msgstr "æåŠ©" + +#: smartdns.js:1779 +msgid "Restart Service" +msgstr "é‡å¯æœåŠ¡" + +#: smartdns.js:1788 +msgid "Restart" +msgstr "é‡å¯" + +#~ msgid "Grant access to LuCI app smartdns" +#~ msgstr "授予访问 LuCI 应用 smartdns çš„æƒé™" diff --git a/luci-app-smartdns/po/zh_Hant/smartdns.po b/luci-app-smartdns/po/zh_Hant/smartdns.po new file mode 100644 index 00000000..c904ddd5 --- /dev/null +++ b/luci-app-smartdns/po/zh_Hant/smartdns.po @@ -0,0 +1,945 @@ +msgid "" +msgstr "" +"PO-Revision-Date: 2023-03-15 14:40+0000\n" +"Last-Translator: Hulen \n" +"Language-Team: Chinese (Traditional) \n" +"Language: zh_Hant\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.16.2-dev\n" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:792 +msgid "Additional Args for upstream dns servers" +msgstr "é¡å¤–的上游 DNS 伺æœå™¨åƒæ•¸" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:886 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1090 +msgid "" +"Additional Flags for rules, read help on domain-rule for more information." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:885 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1089 +msgid "Additional Rule Flag" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:346 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:479 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:791 +msgid "Additional Server Args" +msgstr "é¡å¤–的伺æœå™¨åƒæ•¸" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:347 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:480 +msgid "" +"Additional server args, refer to the help description of the bind option." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:132 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:639 +msgid "Advanced Settings" +msgstr "進階設定" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:253 +msgid "" +"Attempts to serve old responses from cache with a TTL of 0 in the response " +"without waiting for the actual resolution to finish." +msgstr "查詢性能優化,有請求時嘗試回應 TTL 為 0 çš„éŽæœŸè¨˜éŒ„,以é¿å…查詢等待。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically Set Dnsmasq" +msgstr "自動設置 Dnsmasq" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:161 +msgid "Automatically set as upstream of dnsmasq when port changes." +msgstr "通訊埠更改時自動設為 dnsmasq 的上游。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Bind Device" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Bind Device Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:998 +msgid "Block domain." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Cache Persist" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "Cache Size" +msgstr "緩存大å°" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:121 +msgid "Collecting data ..." +msgstr "正在收集數據..." + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1100 +msgid "" +"Configure IP blacklists that will be filtered from the results of specific " +"DNS server." +msgstr "é…置需è¦ä»ŽæŒ‡å®šåŸŸå伺æœå™¨çµæžœéŽæ¿¾çš„ IP 黑å單。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Configure block domain list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:950 +msgid "Configure domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +msgid "Configure forwarding domain name list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:137 +msgid "Custom Settings" +msgstr "自定義設置" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:805 +msgid "DNS Block Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:804 +msgid "DNS Forwarding Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:648 +msgid "DNS Server Name" +msgstr "DNS 伺æœå™¨å稱" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +msgid "DNS Server group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "DNS Server group belongs to, such as office, home." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "DNS Server ip" +msgstr "DNS 伺æœå™¨ IP" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "DNS Server port" +msgstr "DNS 伺æœå™¨é€šè¨ŠåŸ " + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "DNS Server type" +msgstr "å”議類型" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:258 +msgid "DNS domain result cache size" +msgstr "ç·©å­˜ DNS çš„çµæžœï¼Œç·©å­˜å¤§å°ï¼Œé…置零則ä¸ç·©å­˜" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:487 +msgid "DNS64" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:134 +msgid "DNS64 Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:560 +msgid "Description" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:76 +msgid "Dnsmasq Forwarded To Smartdns Failure" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:719 +msgid "Do not check certificate." +msgstr "䏿 ¡é©—æ†‘è­‰çš„åˆæ³•性。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:397 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:838 +msgid "Do not check speed." +msgstr "ç¦ç”¨æ¸¬é€Ÿã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Domain Address" +msgstr "域åä½å€" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:900 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:929 +msgid "Domain List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:891 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:991 +msgid "Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:949 +msgid "Domain Rule List" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:965 +msgid "Domain Rule Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:800 +msgid "Domain Rules Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "Domain TTL" +msgstr "域å TTL" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:336 +msgid "Domain TTL Max" +msgstr "域å TTL 最大值" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:328 +msgid "Domain TTL Min" +msgstr "域å TTL 最å°å€¼" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:246 +msgid "Domain prefetch" +msgstr "域åé åŠ è¼‰" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1159 +msgid "Donate" +msgstr "æè´ˆ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1158 +msgid "Donate to smartdns" +msgstr "æè´ˆ smartdns é …ç›®" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:526 +msgid "Download Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "Download Files Setting" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:135 +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:240 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1007 +msgid "Dual-stack IP Selection" +msgstr "雙棧 IP 優é¸" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:371 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:642 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:959 +msgid "Enable" +msgstr "å¯ç”¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable Auto Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:241 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1008 +msgid "Enable IP selection between IPv4 and IPv6" +msgstr "å¯ç”¨ IPv4 å’Œ IPv6 é–“çš„ IP 優é¸ç­–ç•¥" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "Enable IPv6 DNS Server" +msgstr "å¯ç”¨ IPv6 伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "Enable TCP DNS Server" +msgstr "å¯ç”¨ TCP 伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:495 +msgid "Enable daily auto update." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:247 +msgid "Enable domain prefetch, accelerate domain response speed." +msgstr "å¯ç”¨åŸŸåé åŠ è¼‰ï¼ŒåŠ é€ŸåŸŸå響應速度。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:372 +msgid "Enable or disable second DNS server." +msgstr "是å¦å¯ç”¨ç¬¬äºŒ DNS 伺æœå™¨ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:142 +msgid "Enable or disable smartdns server" +msgstr "å¯ç”¨æˆ–ç¦ç”¨ SmartDNS æœå‹™" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude DNS Server from default group." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:694 +msgid "Exclude Default Group" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:215 +msgid "Fastest IP" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:216 +msgid "Fastest Response" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:535 +msgid "File Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +msgid "File Type" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:702 +msgid "Filtering IP with blacklist" +msgstr "使用 IP 黑åå–®éŽæ¿¾" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:214 +msgid "First Ping" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA" +msgstr "åœç”¨ IPv6 ä½å€è§£æž" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:272 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:436 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:842 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1056 +msgid "Force AAAA SOA." +msgstr "åœç”¨ IPv6 ä½å€è§£æžã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA" +msgstr "åœç”¨ HTTPS ä½å€è§£æž" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:277 +msgid "Force HTTPS SOA." +msgstr "åœç”¨ HTTPS ä½å€è§£æžã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:131 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:638 +msgid "General Settings" +msgstr "常è¦è¨­ç½®" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:599 +msgid "Generate Coredump" +msgstr "ç”Ÿæˆ coredump" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:600 +msgid "" +"Generate Coredump file when smartdns crash, coredump file is located at /tmp/" +"smartdns.xxx.core." +msgstr "" +"ç•¶ smartdns ç•°å¸¸æ™‚ç”Ÿæˆ coredump 文檔,coredump 文檔在 /tmp/smartdns.xxx.core." + +#: applications/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json:3 +msgid "Grant access to LuCI app smartdns" +msgstr "æŽˆäºˆè¨ªå• LuCI 應用 smartdns 的權é™" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:737 +msgid "HTTP Host" +msgstr "HTTP 主機" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "IP Blacklist" +msgstr "IP 黑åå–®" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:701 +msgid "IP Blacklist Filtering" +msgstr "IP 黑åå–®éŽæ¿¾" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:224 +msgid "IPv6 Server" +msgstr "IPv6 伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:440 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:846 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1062 +msgid "IPset name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1138 +msgid "If you like this software, please buy me a cup of coffee." +msgstr "如果本软件对你有帮助,请给作者加个蛋。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:353 +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:354 +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:283 +msgid "Ipset name, Add domain result to ipset when speed check fails." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:527 +msgid "List of files to download." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:229 +msgid "Listen only on the specified interfaces." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:153 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Local Port" +msgstr "本地通訊埠" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:624 +msgid "Log File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:608 +msgid "Log Level" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:620 +msgid "Log Number" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:604 +msgid "Log Size" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:757 +msgid "Marking Packets" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:337 +msgid "Maximum TTL for all domain result." +msgstr "所有域å的最大 TTL 值。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:329 +msgid "Minimum TTL for all domain result." +msgstr "所有域åçš„æœ€å° TTL 值。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:316 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:471 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:877 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1081 +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:459 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:865 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1068 +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:66 +msgid "NOT RUNNING" +msgstr "未é‹è¡Œ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:234 +msgid "Name of device name listen on." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:304 +msgid "" +"Nftset name, Add domain result to nftset when speed check fails, format: " +"[#[4|6]:[family#table#set]]" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1014 +msgid "No" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:282 +msgid "No Speed IPset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:303 +msgid "No Speed NFTset Name" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:718 +msgid "No check certificate" +msgstr "åœç”¨æ†‘證校驗" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:177 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1000 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1025 +msgid "None" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:784 +msgid "Only socks5 proxy support udp server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:780 +msgid "Please set proxy server first." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:136 +msgid "Proxy Server Settings" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:567 +msgid "Proxy Server URL, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:575 +msgid "" +"Proxy server URL format error, format: [socks5|http]://user:pass@ip:port." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:390 +msgid "Query DNS through specific dns server group, such as office, home." +msgstr "使用指定伺æœå™¨çµ„查詢,比如office, home。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:64 +msgid "RUNNING" +msgstr "é‹è¡Œä¸­" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:341 +msgid "Reply Domain TTL Max" +msgstr "回應的域å TTL 最大值" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:342 +msgid "Reply maximum TTL for all domain result." +msgstr "設置返回给用戶端的域å TTL 最大值。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1150 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1151 +msgid "Report bugs" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve Local Hostnames" +msgstr "è§£æžæœ¬åœ°ä¸»æ©Ÿå" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:267 +msgid "Resolve local hostnames by reading Dnsmasq lease file." +msgstr "è®€å– Dnsmasq çš„ç§Ÿç´„æ–‡æª”è§£æžæœ¬åœ°ä¸»æ©Ÿå。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:209 +msgid "Response Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1174 +msgid "Restart" +msgstr "é‡å•Ÿ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1165 +msgid "Restart Service" +msgstr "é‡å•Ÿæœå‹™" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:133 +msgid "Second Server Settings" +msgstr "第二 DNS 伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:252 +msgid "Serve expired" +msgstr "ç·©å­˜éŽæœŸæœå‹™" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:389 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:675 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:813 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:967 +msgid "Server Group" +msgstr "伺æœå™¨çµ„" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:833 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:987 +msgid "Server Group %s not exists" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Server Name" +msgstr "伺æœå™¨å稱" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:807 +msgid "Set Specific domain ip address." +msgstr "設置指定域åçš„ IP ä½å€ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:806 +msgid "Set Specific domain rule list." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:808 +msgid "Set Specific ip blacklist." +msgstr "設置指定的 IP 黑å單列表。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:709 +msgid "Set TLS hostname to verify." +msgstr "設置校驗 TLS 主機å。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:758 +msgid "Set mark on packets." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:738 +msgid "" +"Set the HTTP host used for the query. Use this parameter when the host of " +"the URL address is an IP address." +msgstr "" +"設置查詢時使用的 HTTP 主機,當 URL ä½å€çš„ host 是 IP ä½å€æ™‚ï¼Œä½¿ç”¨æ­¤åƒæ•¸ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:728 +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:128 +msgid "Settings" +msgstr "設置" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:402 +msgid "Skip Address Rules" +msgstr "è·³éŽ address 规則" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache" +msgstr "è·³éŽ cache" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:431 +msgid "Skip Cache." +msgstr "è·³éŽ cache。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:425 +msgid "Skip Dualstack Selection" +msgstr "è·³éŽåŒæ ˆå„ªé¸" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:426 +msgid "Skip Dualstack Selection." +msgstr "è·³éŽåŒæ ˆå„ªé¸ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:414 +msgid "Skip Ipset Rule" +msgstr "è·³éŽ ipset 规則" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:408 +msgid "Skip Nameserver Rule" +msgstr "è·³éŽ Nameserver 规則" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:420 +msgid "Skip SOA Address Rule" +msgstr "è·³éŽ address SOA(#) 规則" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:421 +msgid "Skip SOA address rules." +msgstr "è·³éŽ address SOA(#) 规則。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:396 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:837 +msgid "Skip Speed Check" +msgstr "è·³éŽæ¸¬é€Ÿ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:403 +msgid "Skip address rules." +msgstr "è·³éŽ address 规則。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:415 +msgid "Skip ipset rules." +msgstr "è·³éŽ ipset 规則。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:409 +msgid "Skip nameserver rules." +msgstr "è·³éŽ Nameserver 规則。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:95 +#: applications/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json:3 +msgid "SmartDNS" +msgstr "SmartDNS" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:96 +msgid "SmartDNS Server" +msgstr "SmartDNS 伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:97 +msgid "" +"SmartDNS is a local high-performance DNS server, supports finding fastest " +"IP, supports ad filtering, and supports avoiding DNS poisoning." +msgstr "SmartDNS 是一个本地高性能 DNS 伺æœå™¨ï¼Œæ”¯æŒè¿”回最快 IP,支æŒå»£å‘ŠéŽæ¿¾ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1142 +msgid "SmartDNS official website" +msgstr "SmartDNS 官方網站" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:377 +msgid "Smartdns local server port" +msgstr "SmartDNS 本地æœå‹™é€šè¨ŠåŸ " + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:154 +msgid "" +"Smartdns local server port, smartdns will be automatically set as main dns " +"when the port is 53." +msgstr "" +"SmartDNS 本地æœå‹™é€šè¨ŠåŸ ï¼Œç•¶é€šè¨ŠåŸ å·è¨­ç½®ç‚º 53 時,smartdns 将会自動é…置為主 " +"dns。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:210 +msgid "" +"Smartdns response mode, First Ping: return the first ping IP, Fastest IP: " +"return the fastest IP, Fastest Response: return the fastest DNS response." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:147 +msgid "Smartdns server name" +msgstr "SmartDNS 的伺æœå™¨å稱,默认為 smartdns,留空為主機å" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Smartdns speed check mode." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1119 +msgid "" +"Specify an IP address to return for any host in the given domains, Queries " +"in the domains are never forwarded and always replied to with the specified " +"IP address which may be IPv4 or IPv6." +msgstr "" +"é…置特定域å返回特定的 IP ä½å€ï¼ŒåŸŸå查詢将ä¸åˆ°ä¸Šæ¸¸ä¼ºæœå™¨è«‹æ±‚,直接返回é…置的 " +"IPä½å€ï¼Œå¯ç”¨äºŽå»£å‘Šå±è”½ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:169 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1016 +msgid "Speed Check Mode" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:202 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1050 +msgid "Speed check mode is invalid." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:219 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:384 +msgid "TCP Server" +msgstr "TCP 伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:196 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1044 +msgid "TCP port is empty" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:708 +msgid "TLS Hostname Verify" +msgstr "æ ¡é©— TLS 主機å" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:727 +msgid "TLS SNI name" +msgstr "TLS SNI å稱" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:746 +msgid "TLS SPKI Pinning" +msgstr "TLS SPKI 指紋" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:324 +msgid "TTL for all domain result." +msgstr "設置所有域åçš„ TTL 值。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1137 +msgid "Technical Support" +msgstr "技術支æŒ" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:539 +msgid "URL" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:548 +msgid "URL format error, format: http:// or https://" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:523 +msgid "Update" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:514 +msgid "Update Files" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:500 +msgid "Upload Config File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:507 +msgid "Upload Domain List File" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:508 +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:892 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:992 +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:921 +msgid "Upload domain list file." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:501 +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:631 +msgid "Upstream Servers" +msgstr "上游伺æœå™¨" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:632 +msgid "" +"Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS " +"servers, including multiple foreign DNS servers." +msgstr "" +"上游 DNS 伺æœå™¨ï¼Œæ”¯æŒ UDP,TCP å”議。请é…置多个上游 DNS 伺æœå™¨ï¼ŒåŒ…括多个国内" +"外伺æœå™¨ã€‚" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:765 +msgid "Use Proxy" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:766 +msgid "Use proxy to connect to upstream DNS server." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:747 +msgid "" +"Used to verify the validity of the TLS server, The value is Base64 encoded " +"SPKI fingerprint, leaving blank to indicate that the validity of TLS is not " +"verified." +msgstr "" +"用于校驗 TLS 伺æœå™¨çš„æœ‰æ•ˆæ€§ï¼Œæ•¸å€¼ç‚º Base64 編碼的 SPKI 指紋,留空表示ä¸é©—è­‰ " +"TLS çš„åˆæ³•性。" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:262 +msgid "Write cache to disk on exit and load on startup." +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1013 +msgid "Yes" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:172 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:213 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:611 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1012 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1020 +msgid "default" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:555 +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:670 +msgid "https" +msgstr "https" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:651 +msgid "ip" +msgstr "ip" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:295 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:452 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:858 +msgid "ipset name format error, format: [#[4|6]:]ipsetname" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:1143 +msgid "open website" +msgstr "打开網站" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:656 +msgid "port" +msgstr "通訊埠" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:556 +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:585 +msgid "smartdns custom settings" +msgstr "smartdns 自定義設置,具體é…ç½®åƒæ•¸åƒè€ƒæŒ‡å°Ž" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:668 +msgid "tcp" +msgstr "tcp" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:669 +msgid "tls" +msgstr "tls" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:554 +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:665 +msgid "type" +msgstr "類型" + +#: applications/luci-app-smartdns/htdocs/luci-static/resources/view/smartdns/smartdns.js:667 +msgid "udp" +msgstr "udp" + +#~ msgid "" +#~ "DNS Server group belongs to, used with nameserver, such as office, home." +#~ msgstr "DNS 伺æœå™¨æ‰€å±¬çµ„, é…åˆ nameserver 使用,例如:office,home。" + +#~ msgid "Dnsmasq Forwared To Smartdns Failure" +#~ msgstr "é‡å®šå‘ dnsmasq 到 smartdns 失敗" + +#~ msgid "Sets the server name indication for query." +#~ msgstr "設置查詢時使用的伺æœå™¨ SNI å稱。" + +#~ msgid "IPv4 53 Port Redirect Failure" +#~ msgstr "IPv4 53 通訊埠é‡å®šå‘失敗" + +#~ msgid "IPv6 53 Port Redirect Failure" +#~ msgstr "IPv6 53 通訊埠é‡å®šå‘失敗" + +#~ msgid "Redirect" +#~ msgstr "é‡å®šå‘" + +#~ msgid "Redirect 53 port to SmartDNS" +#~ msgstr "é‡å®šå‘ 53 通訊埠到 SmartDNS" + +#~ msgid "Run as dnsmasq upstream server" +#~ msgstr "作為 dnsmasq 的上游伺æœå™¨" + +#~ msgid "SmartDNS redirect mode" +#~ msgstr "SmartDNS é‡å®šå‘模å¼" + +#~ msgid "none" +#~ msgstr "æ— " diff --git a/luci-app-smartdns/root/usr/libexec/smartdns-call b/luci-app-smartdns/root/usr/libexec/smartdns-call new file mode 100755 index 00000000..2537792a --- /dev/null +++ b/luci-app-smartdns/root/usr/libexec/smartdns-call @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Copyright 2018-2025 Nick Peng +# Licensed to the public under the GPL V3 License. + +action=$1 +shift + +log_file="$(uci -q get smartdns.@smartdns[0].log_file)" +list_file="${log_file:-/var/log/smartdns/smartdns.log}" + +case "$action" in + tail) + if [ ! -e "$list_file" ]; then + echo "Log file does not exist." + fi + # read log + tail -n 5000 "$list_file" + ;; + clear_log) + # clear log + > $list_file + ;; +esac diff --git a/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json b/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json new file mode 100644 index 00000000..45f796c9 --- /dev/null +++ b/luci-app-smartdns/root/usr/share/luci/menu.d/luci-app-smartdns.json @@ -0,0 +1,21 @@ +{ + "admin/services/smartdns": { + "title": "SmartDNS", + "order": 60, + "action": { + "type": "view", + "path": "smartdns/smartdns" + }, + "depends": { + "acl": [ "luci-app-smartdns" ], + "uci": { "smartdns": true } + } + }, + + "admin/services/smartdns/log": { + "action": { + "type": "view", + "path": "smartdns/log" + } + } +} diff --git a/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json b/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json new file mode 100644 index 00000000..f2762301 --- /dev/null +++ b/luci-app-smartdns/root/usr/share/rpcd/acl.d/luci-app-smartdns.json @@ -0,0 +1,25 @@ +{ + "luci-app-smartdns": { + "description": "Grant access to LuCI app smartdns", + "read": { + "cgi-io": [ "exec" ], + "file": { + "/etc/smartdns/*": [ "read" ], + "/usr/libexec/smartdns-call tail": [ "exec" ], + "/usr/libexec/smartdns-call clear_log": [ "exec" ] + }, + "ubus": { + "service": [ "list" ] + }, + "uci": [ "smartdns" ] + }, + "write": { + "file": { + "/etc/smartdns/*": [ "write" ], + "/etc/init.d/smartdns restart": [ "exec" ], + "/etc/init.d/smartdns updatefiles": [ "exec" ] + }, + "uci": [ "smartdns" ] + } + } +} diff --git a/luci-app-socat/Makefile b/luci-app-socat/Makefile new file mode 100644 index 00000000..8c1754b1 --- /dev/null +++ b/luci-app-socat/Makefile @@ -0,0 +1,21 @@ +# Copyright (C) 2020 Lienol +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-socat +PKG_VERSION:=1.1 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Lienol \ + sbwml + +LUCI_TITLE:=LuCI support for Socat +LUCI_DEPENDS:=+socat +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-socat/htdocs/luci-static/resources/view/socat.js b/luci-app-socat/htdocs/luci-static/resources/view/socat.js new file mode 100644 index 00000000..d42eae4a --- /dev/null +++ b/luci-app-socat/htdocs/luci-static/resources/view/socat.js @@ -0,0 +1,148 @@ +'use strict'; +'require view'; +'require form'; +'require rpc'; +'require uci'; +'require poll'; +'require network'; + +const callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); + +return view.extend({ + load() { + return Promise.all([ + network.getHostHints() + ]); + }, + + render(data) { + let m, s, o; + const hostHints = data[0]; + + m = new form.Map('luci_socat', _('Socat'), _('Socat is a relay for bidirectional data transfer between two independent data channels.')); + + s = m.section(form.NamedSection, 'global', 'global', _('Global Settings')); + s.addremove = false; + + o = s.option(form.Flag, 'enable', _('Enabled')); + o.rmempty = true; + + s = m.section(form.GridSection, 'config', _('Port Forwarding')); + s.addremove = true; + s.anonymous = true; + s.sortable = true; + s.nodescriptions = true; + + const super_handleAdd = s.handleAdd; + s.handleAdd = function(ev) { + const uuid = Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join(''); + return super_handleAdd.call(this, ev, uuid); + }; + + s.modaltitle = function(section_id) { + return _('Socat Configuration'); + }; + + o = s.option(form.Flag, 'enable', _('Enabled')); + o.editable = true; + o.default = '1'; + o.rmempty = false; + + o = s.option(form.DummyValue, '_status', _('Status')); + o.modalonly = false; + o.cfgvalue = function() { + return '-'; + }; + + poll.add(() => { + return callServiceList('luci_socat').then(res => { + const instances = (res && res.luci_socat && res.luci_socat.instances) ? res.luci_socat.instances : {}; + + document.querySelectorAll('tr[data-sid]').forEach(row => { + let sid = row.getAttribute('data-sid'); + if (!sid) return; + sid = sid.trim(); + + const cell = row.querySelector('td[data-name="_status"]'); + if (!cell) return; + + const isRunning = !!instances[sid]; + + cell.innerHTML = isRunning ? '🟢' : '🔴'; + }); + }); + }); + + o = s.option(form.Value, 'remarks', _('Remarks')); + + o = s.option(form.ListValue, 'protocol', _('Protocol Type')); + o.value('port_forwards', _('Port Forwarding')); + o.modalonly = true; + + o = s.option(form.ListValue, 'family', _('Listen Address Family')); + o.value('', _('IPv4 and IPv6')); + o.value('4', _('IPv4 Only')); + o.value('6', _('IPv6 Only')); + o.depends('protocol', 'port_forwards'); + o.modalonly = true; + + o = s.option(form.ListValue, 'proto', _('Listen Protocol')); + o.value('tcp', 'TCP'); + o.value('udp', 'UDP'); + o.depends('protocol', 'port_forwards'); + o.textvalue = function(section_id) { + const family_val = uci.get('luci_socat', section_id, 'family'); + const proto_val = uci.get('luci_socat', section_id, 'proto'); + if (proto_val) { + if (family_val === '4') return `IPv4-${proto_val.toUpperCase()}`; + if (family_val === '6') return `IPv6-${proto_val.toUpperCase()}`; + return `ALL-${proto_val.toUpperCase()}`; + } + }; + + o = s.option(form.Value, 'listen_port', _('Listen Port')); + o.datatype = 'portrange'; + o.rmempty = false; + o.depends('protocol', 'port_forwards'); + + o = s.option(form.Flag, 'reuseaddr', _('Reuse Port'), _('Allow binding to the port even when previous connections are in TIME_WAIT, preventing restart failures.')); + o.default = '1'; + o.rmempty = false; + o.modalonly = true; + + o = s.option(form.ListValue, 'dest_proto', _('Destination Protocol')); + o.value('tcp4', 'IPv4-TCP'); + o.value('udp4', 'IPv4-UDP'); + o.value('tcp6', 'IPv6-TCP'); + o.value('udp6', 'IPv6-UDP'); + o.depends('protocol', 'port_forwards'); + + o = s.option(form.Value, 'dest_ip', _('Destination Address')); + o.rmempty = false; + o.depends('protocol', 'port_forwards'); + o.value('127.0.0.1', '127.0.0.1 (localhost)'); + hostHints.getMACHints().forEach(entry => { + const mac = entry[0]; + const hint = entry[1] || mac; + const ip = hostHints.getIPAddrByMACAddr(mac); + if (ip) + o.value(ip, `${ip} (${hint})`); + }); + + o = s.option(form.Value, 'dest_port', _('Destination Port')); + o.datatype = 'portrange'; + o.rmempty = false; + + o = s.option(form.Flag, 'firewall_accept', _('Open Firewall Port')); + o.editable = true; + o.default = '0'; + o.rmempty = false; + + return m.render(); + } +}); diff --git a/luci-app-socat/po/templates/socat.pot b/luci-app-socat/po/templates/socat.pot new file mode 100644 index 00000000..b6d455fb --- /dev/null +++ b/luci-app-socat/po/templates/socat.pot @@ -0,0 +1,97 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:113 +msgid "" +"Allow binding to the port even when previous connections are in TIME_WAIT, " +"preventing restart failures." +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:125 +msgid "Destination Address" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:137 +msgid "Destination Port" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:118 +msgid "Destination Protocol" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:32 +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:51 +msgid "Enabled" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:29 +msgid "Global Settings" +msgstr "" + +#: luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json:3 +msgid "Grant UCI access for luci-app-socat" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:89 +msgid "IPv4 Only" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:88 +msgid "IPv4 and IPv6" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:90 +msgid "IPv6 Only" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:87 +msgid "Listen Address Family" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:108 +msgid "Listen Port" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:94 +msgid "Listen Protocol" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:141 +msgid "Open Firewall Port" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:35 +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:84 +msgid "Port Forwarding" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:83 +msgid "Protocol Type" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:81 +msgid "Remarks" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:113 +msgid "Reuse Port" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:27 +#: luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json:3 +msgid "Socat" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:48 +msgid "Socat Configuration" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:27 +msgid "" +"Socat is a relay for bidirectional data transfer between two independent " +"data channels." +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:56 +msgid "Status" +msgstr "" diff --git a/luci-app-socat/po/zh_Hans/socat.po b/luci-app-socat/po/zh_Hans/socat.po new file mode 100644 index 00000000..a0226a71 --- /dev/null +++ b/luci-app-socat/po/zh_Hans/socat.po @@ -0,0 +1,107 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-22 03:12+0800\n" +"PO-Revision-Date: 2026-03-22 03:13+0800\n" +"Last-Translator: sbwml \n" +"Language-Team: Chinese\n" +"Language: zh_Hans\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:113 +msgid "" +"Allow binding to the port even when previous connections are in TIME_WAIT, " +"preventing restart failures." +msgstr "å…许在端å£å¤„于 TIME_WAIT çŠ¶æ€æ—¶ç«‹å³é‡æ–°ç»‘定,é¿å…æœåŠ¡é‡å¯å¤±è´¥ã€‚" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:125 +msgid "Destination Address" +msgstr "目标地å€" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:137 +msgid "Destination Port" +msgstr "目标端å£" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:118 +msgid "Destination Protocol" +msgstr "目标åè®®" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:32 +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:51 +msgid "Enabled" +msgstr "å¯ç”¨" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:29 +msgid "Global Settings" +msgstr "全局设置" + +#: luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json:3 +msgid "Grant UCI access for luci-app-socat" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:89 +msgid "IPv4 Only" +msgstr "ä»… IPv4" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:88 +msgid "IPv4 and IPv6" +msgstr "IPv4 å’Œ IPv6" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:90 +msgid "IPv6 Only" +msgstr "ä»… IPv6" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:87 +msgid "Listen Address Family" +msgstr "监å¬åœ°å€æ—" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:108 +msgid "Listen Port" +msgstr "监å¬ç«¯å£" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:94 +msgid "Listen Protocol" +msgstr "监å¬åè®®" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:141 +msgid "Open Firewall Port" +msgstr "打开防ç«å¢™ç«¯å£" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:35 +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:84 +msgid "Port Forwarding" +msgstr "端å£è½¬å‘" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:83 +msgid "Protocol Type" +msgstr "å议类型" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:81 +msgid "Remarks" +msgstr "备注" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:113 +msgid "Reuse Port" +msgstr "é‡ç”¨ç«¯å£" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:27 +#: luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json:3 +msgid "Socat" +msgstr "" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:48 +msgid "Socat Configuration" +msgstr "Socat é…ç½®" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:27 +msgid "" +"Socat is a relay for bidirectional data transfer between two independent " +"data channels." +msgstr "Socat 是一个在两个独立数æ®é€šé“之间进行åŒå‘æ•°æ®è½¬å‘的工具。" + +#: luci-app-socat/htdocs/luci-static/resources/view/socat.js:56 +msgid "Status" +msgstr "状æ€" diff --git a/luci-app-socat/root/etc/config/luci_socat b/luci-app-socat/root/etc/config/luci_socat new file mode 100644 index 00000000..9c4c6d2a --- /dev/null +++ b/luci-app-socat/root/etc/config/luci_socat @@ -0,0 +1,4 @@ + +config global 'global' + option enable '1' + diff --git a/luci-app-socat/root/etc/init.d/luci_socat b/luci-app-socat/root/etc/init.d/luci_socat new file mode 100755 index 00000000..64aef77b --- /dev/null +++ b/luci-app-socat/root/etc/init.d/luci_socat @@ -0,0 +1,118 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2020 Lienol +# Copyright (C) 2026 sbwml + +USE_PROCD=1 +START=99 +STOP=10 + +CONFIG="socat" +CONFIG_PATH="/var/etc/${CONFIG}" + +firewall_add_rule() { + local ports="$1" + + [ -z "$ports" ] && return 1 + + uci -q delete firewall.socat + uci set firewall.socat=rule + uci set firewall.socat.name="socat" + uci set firewall.socat.target="ACCEPT" + uci set firewall.socat.src="wan" + uci set firewall.socat.dest_port="$ports" + uci set firewall.socat.enabled="1" + uci commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 +} + +firewall_del_rule() { + uci -q delete firewall.socat + uci commit firewall 2>/dev/null + /etc/init.d/firewall reload >/dev/null 2>&1 +} + +start_instance() { + local cfg="$1" + local enable remarks protocol family proto listen_port reuseaddr + local dest_proto dest_ip dest_port firewall_accept listen socat_opts + + config_get_bool enable "$cfg" "enable" 0 + [ "$enable" -eq 0 ] && return 0 + + config_get remarks "$cfg" "remarks" "" + config_get protocol "$cfg" "protocol" "" + config_get family "$cfg" "family" "" + config_get proto "$cfg" "proto" "" + config_get listen_port "$cfg" "listen_port" "" + config_get_bool reuseaddr "$cfg" "reuseaddr" 0 + config_get dest_proto "$cfg" "dest_proto" "" + config_get dest_ip "$cfg" "dest_ip" "" + config_get dest_port "$cfg" "dest_port" "" + config_get_bool firewall_accept "$cfg" "firewall_accept" 0 + + if [ -z "$listen_port" ] || [ -z "$dest_ip" ] || [ -z "$dest_port" ]; then + return 1 + fi + + ln -sf /usr/bin/socat "${CONFIG_PATH}/${cfg}" + + socat_opts="" + [ "$reuseaddr" -eq 1 ] && socat_opts="${socat_opts},reuseaddr" + [ "$family" = "6" ] && socat_opts="${socat_opts},ipv6-v6only" + socat_opts="${socat_opts},fork" + + if [ "$protocol" = "port_forwards" ]; then + listen="${proto}${family}" + [ -z "$family" ] && listen="${proto}6" + + procd_open_instance "$cfg" + procd_set_param command "${CONFIG_PATH}/${cfg}" + procd_append_param command "${listen}-listen:${listen_port}${socat_opts}" + procd_append_param command "${dest_proto}:${dest_ip}:${dest_port}" + procd_set_param respawn 3600 5 3 + procd_set_param stdout 0 + procd_set_param stderr 0 + procd_close_instance + + if [ "$firewall_accept" -eq 1 ]; then + echo "$listen_port" >> "/var/etc/${CONFIG}.port" + fi + fi +} + +start_service() { + local global_enable accept_ports + + config_load "luci_socat" + config_get_bool global_enable "global" "enable" 0 + + if [ "$global_enable" -eq 0 ]; then + return 0 + fi + + mkdir -p "$CONFIG_PATH" + rm -f "/var/etc/${CONFIG}.port" + + config_foreach start_instance "config" + + accept_ports=$(cat "/var/etc/${CONFIG}.port" 2>/dev/null | tr '\n' ' ') + + if [ -n "$accept_ports" ]; then + firewall_add_rule "$accept_ports" + fi +} + +stop_service() { + firewall_del_rule + rm -rf "$CONFIG_PATH" "/var/etc/${CONFIG}.port" +} + +service_triggers() { + procd_add_reload_trigger "luci_socat" +} + +reload_service() { + stop + sleep 1 + start +} diff --git a/luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json b/luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json new file mode 100644 index 00000000..c4e53084 --- /dev/null +++ b/luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json @@ -0,0 +1,12 @@ +{ + "admin/services/socat": { + "title": "Socat", + "action": { + "type": "view", + "path": "socat" + }, + "depends": { + "acl": [ "luci-app-socat" ] + } + } +} diff --git a/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json b/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json new file mode 100644 index 00000000..74f55bf5 --- /dev/null +++ b/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json @@ -0,0 +1,14 @@ +{ + "luci-app-socat": { + "description": "Grant UCI access for luci-app-socat", + "read": { + "ubus": { + "service": [ "list" ] + }, + "uci": [ "luci_socat" ] + }, + "write": { + "uci": [ "luci_socat" ] + } + } +} diff --git a/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json b/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json new file mode 100644 index 00000000..d80e815a --- /dev/null +++ b/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json @@ -0,0 +1,4 @@ +{ + "config": "luci_socat", + "init": "luci_socat" +} diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile new file mode 100644 index 00000000..e40b16ea --- /dev/null +++ b/luci-app-ssr-plus/Makefile @@ -0,0 +1,218 @@ +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=luci-app-ssr-plus +LUCI_PKGARCH:=all +PKG_NAME:=luci-app-ssr-plus +PKG_VERSION:=193 +PKG_RELEASE:=23 + +PKG_CONFIG_DEPENDS:= \ + CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_DNS2TCP \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Http_Proxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Mihomo \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server + +LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Tuic/ShadowTLS/Hysteria/Socks5/Clash LuCI interface +LUCI_PKGARCH:=all +LUCI_DEPENDS:= \ + +libuci-lua +lua +luci-compat +coreutils +coreutils-base64 +dns2tcp +dnsmasq-full \ + +jq +ip-full +lua-neturl +libuci-lua +microsocks +ipt2socks +lyaml \ + +resolveip +curl +nping +unzip +xz-utils \ + +PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \ + +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:mosdns \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS:shadow-tls \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \ + +PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client:shadowsocks-rust-sslocal \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server:shadowsocks-rust-ssserver \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs:simple-obfs-client \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin:v2ray-plugin \ + +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \ + +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \ + +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server + + +define Package/$(PKG_NAME)/config + +choice + prompt "Transparent Proxy Backend" + default PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy if ! PACKAGE_firewall4 + default PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy if PACKAGE_firewall4 + +config PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy + bool "Iptables Transparent Proxy" + select PACKAGE_dnsmasq_full_ipset + select PACKAGE_ipset + select PACKAGE_iptables + select PACKAGE_iptables-zz-legacy + select PACKAGE_iptables-mod-conntrack-extra + select PACKAGE_iptables-mod-iprange + select PACKAGE_iptables-mod-socket + select PACKAGE_iptables-mod-tproxy + select PACKAGE_kmod-ipt-nat + +config PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy + bool "Nftables Transparent Proxy" + select PACKAGE_dnsmasq_full_nftset + select PACKAGE_nftables + select PACKAGE_kmod-nft-socket + select PACKAGE_kmod-nft-tproxy + select PACKAGE_kmod-nft-nat +endchoice + +choice + prompt "Shadowsocks Client Selection" + default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Client + + config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Client + bool "None" + + config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client + bool "Shadowsocks Rust" +endchoice + +choice + prompt "Shadowsocks Server Selection" + default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server + + config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server + bool "None" + + config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server + bool "Shadowsocks Rust" +endchoice + +choice + prompt "V2ray-core Selection" + default PACKAGE_$(PKG_NAME)_INCLUDE_Xray + default PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY + + config PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY + bool "None" + + config PACKAGE_$(PKG_NAME)_INCLUDE_Xray + bool "Xray-core" + select PACKAGE_xray-core +endchoice + +config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG + bool "Include ChinaDNS-NG" + default y if aarch64||arm||i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS + bool "Include MosDNS" + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Http_Proxy + bool "Include HTTP(S) Proxy Server" + select PACKAGE_3proxy + default y if (aarch64||arm||i386||loongarch64||riscv64||x86_64) + +config PACKAGE_$(PKG_NAME)_INCLUDE_Mihomo + bool "Include Mihomo (Clash Support)" + select PACKAGE_mihomo + depends on aarch64||arm||i386||loongarch64||riscv64||x86_64 + default y if aarch64||arm||i386||loongarch64||riscv64||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_GeoData + bool "Include GeoData (GeoIP and GeoSite)" + select PACKAGE_v2ray-geoip + select PACKAGE_v2ray-geosite + default y if i386||x86_64 + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS + bool "Include Shadow-TLS" + select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG + select PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client + depends on aarch64||arm||x86_64 + depends on !(TARGET_x86_geode||TARGET_x86_legacy) + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun + bool "Include Kcptun" + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy + bool "Include NaiveProxy" + depends on !(arc||armeb||mips||mips64||powerpc||TARGET_gemini) + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs + bool "Include Shadowsocks Simple Obfs Plugin" + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin + bool "Include Shadowsocks V2ray Plugin" + default n + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client + bool "Include ShadowsocksR Libev Client" + default y + +config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server + bool "Include ShadowsocksR Libev Server" + default n + +endef + + +define Package/$(PKG_NAME)/conffiles +/etc/config/shadowsocksr +/etc/ssrplus/ +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +define Package/$(PKG_NAME)/install + ifneq ($(wildcard ${CURDIR}/luasrc),) + $(INSTALL_DIR) $(1)$(LUCI_LIBRARYDIR) + cp -pR $(PKG_BUILD_DIR)/luasrc/* $(1)$(LUCI_LIBRARYDIR)/ + $(FIND) $(1)$(LUCI_LIBRARYDIR)/ -type f -name '*.luadoc' | $(XARGS) rm + $(if $(CONFIG_LUCI_SRCDIET),$(call SrcDiet,$(1)$(LUCI_LIBRARYDIR)/),true) + $(call SubstituteVersion,$(1)$(LUCI_LIBRARYDIR)/) + endif + ifneq ($(wildcard ${CURDIR}/ucode),) + $(INSTALL_DIR) $(1)$(UCODE_LIBRARYDIR) + cp -pR $(PKG_BUILD_DIR)/ucode/* $(1)$(UCODE_LIBRARYDIR)/ + $(call SubstituteVersion,$(1)$(UCODE_LIBRARYDIR)/) + endif + ifneq ($(wildcard ${CURDIR}/htdocs),) + $(INSTALL_DIR) $(1)$(HTDOCS) + cp -pR $(PKG_BUILD_DIR)/htdocs/* $(1)$(HTDOCS)/ + $(if $(CONFIG_LUCI_JSMIN),$(call JsMin,$(1)$(HTDOCS)/),true) + $(if $(CONFIG_LUCI_CSSTIDY),$(call CssTidy,$(1)$(HTDOCS)/),true) + endif + ifneq ($(wildcard ${CURDIR}/root),) + $(INSTALL_DIR) $(1)/ + cp -pR $(PKG_BUILD_DIR)/root/* $(1)/ + endif + ifneq ($(wildcard ${CURDIR}/src),) + $(call Build/Install/Default) + $(CP) $(PKG_INSTALL_DIR)/* $(1)/ + endif + if [ -d "$(1)/usr/bin" ]; then \ + chmod 0755 "$(1)/usr/bin/ssr-monitor" 2>/dev/null || true; \ + chmod 0755 "$(1)/usr/bin/ssr-rules" 2>/dev/null || true; \ + chmod 0755 "$(1)/usr/bin/ssr-switch" 2>/dev/null || true; \ + fi + if [ -f "$(1)/etc/hotplug.d/iface/99-ssrplus-pppoe" ]; then \ + chmod 0755 "$(1)/etc/hotplug.d/iface/99-ssrplus-pppoe" 2>/dev/null || true; \ + fi +endef + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua new file mode 100644 index 00000000..7db25438 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua @@ -0,0 +1,1569 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. +module("luci.controller.shadowsocksr", package.seeall) +require "nixio" +require "nixio.fs" +require "luci.util" +require "luci.template" +require "luci.sys" +local i18n = require "luci.i18n" +local datatypes = require "luci.cbi.datatypes" +local json = require "luci.jsonc" +local uci = require "luci.model.uci".cursor() +local translate = i18n.translate + +local CLASH_API_PORT = "16756" +local COMPONENT_HELPER = "/usr/share/shadowsocksr/update_components.sh" +local SERVER_DETECT_CACHE = "/tmp/ssrplus_server_detect.json" +local SERVER_DETECT_LOCK = "/tmp/ssrplus_server_detect.lock" +local CLASH_RULES_DIR = "/etc/ssrplus/clash" +local SUPPORTED_COMPONENTS = { + xray = true, + mihomo = true, + naiveproxy = true +} +local SUPPORTED_GEO_COMPONENTS = { + country_mmdb = true, + geosite = true, + v2ray_geo = true +} + +local function trim(value) + return tostring(value or ""):gsub("^%s+", ""):gsub("%s+$", "") +end + +local function parse_nonnegative_int(value) + local number = tonumber(value) + if not number then + return nil + end + number = math.floor(number) + if number < 0 then + return nil + end + return number +end + +local function sanitize_mac(value) + value = trim(value):upper():gsub("-", ":") + if value:match("^%x%x:%x%x:%x%x:%x%x:%x%x:%x%x$") then + return value + end + return "" +end + +local function normalize_client_ip(value) + value = trim(value) + if value == "" then + return "" + end + if datatypes.cidr4(value) or datatypes.ip4addr(value) then + return value + end + return "" +end + +local function get_clash_client_rule_csv_path(sid) + sid = trim(sid) + if sid == "" then + return nil + end + return string.format("%s/%s.csv", CLASH_RULES_DIR, sid) +end + +local function csv_escape(value) + value = tostring(value or "") + if value:find('[",\n\r]') then + return '"' .. value:gsub('"', '""') .. '"' + end + return value +end + +local function parse_csv_line(line) + local cols = {} + local cur = "" + local in_quote = false + local i = 1 + + while i <= #line do + local ch = line:sub(i, i) + if ch == '"' then + if in_quote and line:sub(i + 1, i + 1) == '"' then + cur = cur .. '"' + i = i + 1 + else + in_quote = not in_quote + end + elseif ch == "," and not in_quote then + cols[#cols + 1] = cur + cur = "" + else + cur = cur .. ch + end + i = i + 1 + end + + cols[#cols + 1] = cur + return cols +end + +local function read_clash_client_rules_csv(sid) + local rules = {} + local csv_path = get_clash_client_rule_csv_path(sid) + if not csv_path or not nixio.fs.access(csv_path) then + return rules + end + + local raw = nixio.fs.readfile(csv_path) + if not raw or raw == "" then + return rules + end + + local first = true + for line in tostring(raw):gsub("\r", ""):gmatch("[^\n]+") do + local text = trim(line) + if text ~= "" then + if first and text:lower() == "enabled,client,policy,remarks,client_mac" then + first = false + else + local cols = parse_csv_line(line) + if #cols >= 4 then + rules[#rules + 1] = { + id = tostring(#rules + 1), + enabled = cols[1] == "1" or tostring(cols[1] or ""):lower() == "true", + ip_addr = trim(cols[2] or ""), + policy_group = trim(cols[3] or ""), + remarks = trim(cols[4] or ""), + client_mac = sanitize_mac(cols[5] or "") + } + end + end + end + end + + return rules +end + +local function write_clash_client_rules_csv(sid, rows) + local csv_path = get_clash_client_rule_csv_path(sid) + if not csv_path then + return false + end + + nixio.fs.mkdirr(CLASH_RULES_DIR) + local lines = { "enabled,client,policy,remarks,client_mac" } + for _, row in ipairs(rows or {}) do + lines[#lines + 1] = table.concat({ + row.enabled == "1" and "1" or "0", + csv_escape(row.ip_addr or ""), + csv_escape(row.policy_group or ""), + csv_escape(row.remarks or ""), + csv_escape(row.client_mac or "") + }, ",") + end + + return nixio.fs.writefile(csv_path, table.concat(lines, "\n") .. "\n") +end + +local function collect_lan_clients() + local clients = {} + local seen = {} + + luci.sys.net.host_hints(function(mac, ipv4, _, name) + local ip = trim(ipv4) + local norm_mac = sanitize_mac(mac) + if ip ~= "" and not seen[ip] then + seen[ip] = true + clients[#clients + 1] = { + ip = ip, + mac = norm_mac, + name = trim(name) ~= "" and trim(name) or ip + } + end + end) + + table.sort(clients, function(a, b) + return tostring(a.name or a.ip) < tostring(b.name or b.ip) + end) + + return clients +end + +local function read_clash_client_rules(sid) + return read_clash_client_rules_csv(sid) +end + +local function normalize_ping_ms(value, scale) + local num = tonumber(value) + if not num or num <= 0 then + return nil + end + local scaled = scale and (num * scale) or num + if scaled > 0 and scaled < 1 then + return 1 + end + return math.floor(scaled + 0.5) +end + +local function detect_tls_handshake_ms(domain, port, path, resolve_host, server_ip, is_websocket) + if not domain or domain == "" or not port or port <= 0 then + return nil + end + + local final_host = (resolve_host and resolve_host ~= "") and resolve_host or domain + local resolve_arg = "" + if server_ip and server_ip ~= "" and final_host ~= server_ip then + resolve_arg = string.format("--resolve '%s:%d:%s' ", final_host, port, server_ip) + end + + local ws_headers = "" + if is_websocket then + ws_headers = string.format( + "-H %s -H %s -H %s -H %s ", + luci.util.shellquote("Connection: Upgrade"), + luci.util.shellquote("Upgrade: websocket"), + luci.util.shellquote("Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ=="), + luci.util.shellquote("Sec-WebSocket-Version: 13") + ) + end + + local host_header = (final_host and final_host ~= "") and ("-H " .. luci.util.shellquote("Host: " .. final_host) .. " ") or "" + local url = string.format("https://%s:%d%s", final_host, port, path or "") + local cmd = string.format( + "curl --http1.1 -m 3 -ksS -o /dev/null %s%s%s -w 'time_connect=%%{time_connect}\\ntime_appconnect=%%{time_appconnect}\\nhttp_code=%%{http_code}' '%s' 2>/dev/null", + resolve_arg, host_header, ws_headers, url + ) + local result = luci.sys.exec(cmd) or "" + local appconnect = tonumber(result:match("time_appconnect=([0-9.]+)")) + if appconnect and appconnect > 0 then + return normalize_ping_ms(appconnect, 1000) + end + local connect = tonumber(result:match("time_connect=([0-9.]+)")) + if connect and connect > 0 then + return normalize_ping_ms(connect, 1000) + end + return nil +end + +local function urlencode(str) + if not str then return "" end + return tostring(str):gsub("[^%w%-_%.~]", function(c) + return string.format("%%%02X", string.byte(c)) + end) +end + +local function is_ipv6_address(addr) + addr = tostring(addr or "") + return addr ~= "" and addr:find(":", 1, true) ~= nil +end + +local function is_local_target(addr) + addr = tostring(addr or ""):lower() + if addr == "" then + return false + end + + if addr == "localhost" or addr == "::1" or addr:match("%.local$") then + return true + end + + if is_ipv6_address(addr) then + return addr:match("^fe[89ab]") ~= nil or addr:match("^fc") ~= nil or addr:match("^fd") ~= nil + end + + local o1, o2 = addr:match("^(%d+)%.(%d+)%.") + o1 = tonumber(o1) + o2 = tonumber(o2) + if not o1 or not o2 then + return false + end + + return o1 == 10 + or o1 == 127 + or (o1 == 169 and o2 == 254) + or (o1 == 172 and o2 >= 16 and o2 <= 31) + or (o1 == 192 and o2 == 168) +end + +local function detect_tcp_connect_ms(domain, port) + if not domain or domain == "" or not port or port <= 0 then + return nil + end + + local ip_version_arg = is_ipv6_address(domain) and "-6 " or "" + local cmd = string.format( + "nping %s--tcp-connect -q -c 1 -p %d %s 2>/dev/null", + ip_version_arg, + port, + luci.util.shellquote(domain) + ) + local result = luci.sys.exec(cmd) or "" + local success = tonumber(result:match("Successful connections:%s*([0-9]+)")) + if success and success > 0 then + local avg_rtt = tonumber(result:match("Avg rtt:%s*([0-9.]+)ms")) + if avg_rtt and avg_rtt > 0 and avg_rtt < 1 and not is_local_target(domain) then + return nil + end + return normalize_ping_ms(avg_rtt) + end + + return nil +end + +local function get_clash_secret(sid) + return sid .. "_ssrplus_clash" +end + +local function get_clash_cache_file(sid) + return "/etc/ssrplus/clash/" .. sid .. ".yaml" +end + +local function get_clash_state_file(sid) + return "/etc/ssrplus/clash/" .. sid .. ".cache.db" +end + +local function clash_process_running() + return luci.sys.call("(busybox ps -w 2>/dev/null || busybox ps) | grep ssr-retcp | grep -v grep >/dev/null") == 0 +end + +local function global_client_running() + local process_list = luci.sys.exec("busybox ps -w 2>/dev/null || busybox ps") + local global_server = uci:get_first("shadowsocksr", "global", "global_server", "nil") + local global_type = global_server ~= "nil" and (uci:get("shadowsocksr", global_server, "type") or "") or "" + + if process_list:find("tcp.only.ssr.retcp") + or process_list:find("tcp.udp.ssr.retcp") + or process_list:find("local.ssr.retcp") + or process_list:find("local.udp.ssr.retcp") then + return true + end + + if (global_type == "clash" or global_type == "tuic" or global_type == "ss") + and process_list:find("ssr%-retcp") then + return true + end + + if (global_type == "clash" or global_type == "tuic" or global_type == "ss") + and process_list:find("mihomo") + and (process_list:find("/clash%-") or process_list:find("/tuic%-") or process_list:find("/ss%-")) then + return true + end + + if global_type == "socks5" + and process_list:find("ipt2socks") + and (process_list:find("%-T") or process_list:find("%-%-tcp%-only")) then + return true + end + + return false +end + +local function get_active_node_runtime(sid) + if not sid or sid == "" or sid == "nil" or uci:get("shadowsocksr", sid) ~= "servers" then + return nil, nil + end + + local stype = (uci:get("shadowsocksr", sid, "type") or ""):lower() + local proto = (uci:get("shadowsocksr", sid, "v2ray_protocol") or ""):lower() + local backend + local protocol + + if stype == "ss" then + backend = translate("Mihomo") + protocol = translate("Shadowsocks") + elseif stype == "clash" then + backend = translate("Mihomo") + protocol = translate("Clash") + elseif stype == "tuic" then + backend = translate("Mihomo") + protocol = translate("TUIC") + elseif stype == "ssr" then + backend = translate("ShadowsocksR") + elseif stype == "ss-rust" then + backend = translate("Shadowsocks-rust") + elseif stype == "v2ray" then + local proto_map = { + vmess = "VMess", + vless = "VLESS", + trojan = "Trojan", + socks = "SOCKS5", + hysteria2 = "Hysteria2", + shadowsocks = "Shadowsocks", + http = "HTTP" + } + backend = translate("Xray") + if proto_map[proto] then + protocol = translate(proto_map[proto]) + end + elseif stype == "trojan" then + backend = translate("Trojan") + elseif stype == "naiveproxy" then + backend = translate("NaiveProxy") + elseif stype == "socks5" then + backend = translate("SOCKS5") + elseif stype == "shadowtls" then + backend = translate("ShadowTLS") + elseif stype == "hysteria2" then + backend = translate("Hysteria2") + end + + if not backend or backend == "" then + backend = trim(stype) + end + + return backend, protocol +end + +local function get_running_status_text() + local sid = uci:get_first("shadowsocksr", "global", "global_server", "nil") + local backend, protocol = get_active_node_runtime(sid) + + if backend and backend ~= "" and protocol and protocol ~= "" and backend ~= protocol then + return string.format(translate("RUNNING in %s (%s) Mode"), backend, protocol) + end + + if backend and backend ~= "" then + return string.format(translate("RUNNING in %s Mode"), backend) + end + + return translate("RUNNING") +end + +local function is_active_clash_node(sid) + if not sid then return false end + if uci:get("shadowsocksr", sid) ~= "servers" then return false end + if uci:get("shadowsocksr", sid, "type") ~= "clash" then return false end + if uci:get_first("shadowsocksr", "global", "global_server") ~= sid then return false end + return clash_process_running() +end + +local function resolve_active_clash_sid(sid) + if is_active_clash_node(sid) then + return sid + end + + local current_sid = uci:get_first("shadowsocksr", "global", "global_server") + if is_active_clash_node(current_sid) then + return current_sid + end + + return nil +end + +local function clash_api_request(sid, method, path, body) + sid = resolve_active_clash_sid(sid) + if not sid then + return nil + end + local secret = get_clash_secret(sid) + local cmd = string.format( + "curl -sL -m 5 --retry 1 -w '\n__CURL_STATUS__:%%{http_code}' -H %s -H %s -X %s http://127.0.0.1:%s%s %s", + luci.util.shellquote("Content-Type: application/json"), + luci.util.shellquote("Authorization: Bearer " .. secret), + method, + CLASH_API_PORT, + path, + body and ("-d " .. luci.util.shellquote(body)) or "" + ) + local output = luci.sys.exec(cmd) + if not output or output == "" then + return nil + end + local body_output = output:gsub("\n__CURL_STATUS__:%d%d%d%s*$", "") + local code = output:match("__CURL_STATUS__:(%d%d%d)") + return { + code = tonumber(code), + body = body_output + } +end + +local function use_fw4_backend() + return luci.sys.call("command -v fw4 >/dev/null") == 0 +end + +local function parse_clash_groups(raw) + local info = json.parse(raw or "") + local proxies = info and info.proxies or nil + local groups = {} + if type(proxies) ~= "table" then + return groups + end + for name, value in pairs(proxies) do + if type(value) == "table" and type(value.all) == "table" and #value.all > 0 then + groups[#groups + 1] = { + name = name, + type = value.type or "", + now = value.now or "", + all = value.all + } + end + end + table.sort(groups, function(a, b) return tostring(a.name) < tostring(b.name) end) + return groups +end + +local function parse_kv_output(raw) + local data = {} + for line in tostring(raw or ""):gmatch("[^\r\n]+") do + local key, value = line:match("^([%w_]+)=(.*)$") + if key then + data[key] = value + end + end + return data +end + +local function with_detect_cache_lock(fn) + for _ = 1, 40 do + if nixio.fs.mkdir(SERVER_DETECT_LOCK) then + local ok, ret = pcall(fn) + nixio.fs.rmdir(SERVER_DETECT_LOCK) + if ok then + return ret + end + return nil + end + nixio.nanosleep(0, 50000000) + end + return nil +end + +local function load_detect_cache() + local raw = nixio.fs.readfile(SERVER_DETECT_CACHE) + if not raw or raw == "" then + return {} + end + local parsed = json.parse(raw) + return type(parsed) == "table" and parsed or {} +end + +local function save_detect_cache_entry(sid, data) + if not sid or sid == "" then + return + end + with_detect_cache_lock(function() + local cache = load_detect_cache() + cache[sid] = data + nixio.fs.writefile(SERVER_DETECT_CACHE, json.stringify(cache)) + end) +end + +local function read_component_state(component, action) + if not SUPPORTED_COMPONENTS[component] then + return nil, 400, "unsupported_component" + end + + local mirror = luci.http.formvalue("mirror") or "" + local cmd = string.format( + "COMPONENT_MIRROR=%s /bin/sh %s %s 2>/dev/null", + luci.util.shellquote(mirror), + luci.util.shellquote(COMPONENT_HELPER), + luci.util.shellquote(component .. "_" .. action) + ) + return parse_kv_output(luci.sys.exec(cmd)) +end + +local function read_geo_state(component, action) + if not SUPPORTED_GEO_COMPONENTS[component] then + return nil, 400, "unsupported_component" + end + + local mirror = luci.http.formvalue("mirror") or "" + local cmd = string.format( + "COMPONENT_MIRROR=%s /bin/sh %s %s 2>/dev/null", + luci.util.shellquote(mirror), + luci.util.shellquote(COMPONENT_HELPER), + luci.util.shellquote(component .. "_" .. action) + ) + return parse_kv_output(luci.sys.exec(cmd)) +end + +local function write_component_json(data) + luci.http.prepare_content("application/json") + luci.http.write_json({ + component = data.component or "xray", + installed = data.installed == "1", + current_version = data.current_version or "", + latest_version = data.latest_version or "", + previous_version = data.previous_version or "", + arch = data.arch or "", + asset = data.asset or "", + can_upgrade = data.can_upgrade == "1", + success = data.success == "1", + error = data.error or "", + message = data.message or "" + }) +end + +local function write_geo_json(data) + luci.http.prepare_content("application/json") + luci.http.write_json({ + component = data.component or "country_mmdb", + installed = data.installed == "1", + current_version = data.current_version or "", + current_version_extra = data.current_version_extra or "", + latest_version = data.latest_version or "", + can_upgrade = data.can_upgrade == "1", + success = data.success == "1", + error = data.error or "", + message = data.message or "" + }) +end + +local function shell_quote(value) + return "'" .. tostring(value or ""):gsub("'", "'\\''") .. "'" +end + +function index() + if not nixio.fs.access("/etc/config/shadowsocksr") then + call("act_reset") + end + local page + page = entry({"admin", "services", "shadowsocksr"}, alias("admin", "services", "shadowsocksr", "client"), _("ShadowSocksR Plus+"), 10) + page.dependent = true + page.acl_depends = { "luci-app-ssr-plus" } + entry({"admin", "services", "shadowsocksr", "client"}, cbi("shadowsocksr/client"), _("SSR Client"), 10).leaf = true + entry({"admin", "services", "shadowsocksr", "servers"}, arcombine(cbi("shadowsocksr/servers"), cbi("shadowsocksr/client-config")), _("Servers Nodes"), 20).leaf = true + entry({"admin", "services", "shadowsocksr", "control"}, cbi("shadowsocksr/control"), _("Access Control"), 30).leaf = true + entry({"admin", "services", "shadowsocksr", "advanced"}, cbi("shadowsocksr/advanced"), _("Advanced Settings"), 50).leaf = true + entry({"admin", "services", "shadowsocksr", "server"}, arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")), _("SSR Server"), 60).leaf = true + entry({"admin", "services", "shadowsocksr", "component"}, cbi("shadowsocksr/component"), _("Component Update"), 65).leaf = true + entry({"admin", "services", "shadowsocksr", "status"}, form("shadowsocksr/status"), _("Status"), 70).leaf = true + entry({"admin", "services", "shadowsocksr", "check"}, call("check_status")) + entry({"admin", "services", "shadowsocksr", "refresh"}, call("refresh_data")) + entry({"admin", "services", "shadowsocksr", "subscribe"}, call("subscribe")) + entry({"admin", "services", "shadowsocksr", "component_local_status"}, call("component_local_status")).leaf = true + entry({"admin", "services", "shadowsocksr", "component_set_mirror"}, call("component_set_mirror")).leaf = true + entry({"admin", "services", "shadowsocksr", "component_status"}, call("component_status")).leaf = true + entry({"admin", "services", "shadowsocksr", "component_upgrade"}, call("component_upgrade")).leaf = true + entry({"admin", "services", "shadowsocksr", "geo_local_status"}, call("geo_local_status")).leaf = true + entry({"admin", "services", "shadowsocksr", "geo_status"}, call("geo_status")).leaf = true + entry({"admin", "services", "shadowsocksr", "geo_upgrade"}, call("geo_upgrade")).leaf = true + entry({"admin", "services", "shadowsocksr", "checkport"}, call("check_port")) + entry({"admin", "services", "shadowsocksr", "log"}, form("shadowsocksr/log"), _("Log"), 80).leaf = true + entry({"admin", "services", "shadowsocksr", "get_log"}, call("get_log")).leaf = true + entry({"admin", "services", "shadowsocksr", "clear_log"}, call("clear_log")).leaf = true + entry({"admin", "services", "shadowsocksr", "run"}, call("act_status")) + entry({"admin", "services", "shadowsocksr", "ping"}, call("act_ping")) + entry({"admin", "services", "shadowsocksr", "save_order"}, call("save_order")).leaf = true + entry({"admin", "services", "shadowsocksr", "delete_node"}, call("act_delete_node")).leaf = true + entry({"admin", "services", "shadowsocksr", "add_subscribe_item"}, call("add_subscribe_item")).leaf = true + entry({"admin", "services", "shadowsocksr", "delete_subscribe_item"}, call("delete_subscribe_item")).leaf = true + entry({"admin", "services", "shadowsocksr", "toggle_subscribe_item_enabled"}, call("toggle_subscribe_item_enabled")).leaf = true + entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset")) + entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart")) + entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete")) + entry({"admin", "services", "shadowsocksr", "clash_panel"}, call("clash_panel")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_groups"}, call("clash_groups")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_switch"}, call("clash_switch")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_refresh"}, call("clash_refresh")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_reset_defaults"}, call("clash_reset_defaults")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_client_policies"}, call("clash_client_policies")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_client_rule_save"}, call("clash_client_rule_save")).leaf = true + entry({"admin", "services", "shadowsocksr", "clash_client_rule_clear"}, call("clash_client_rule_clear")).leaf = true + --[[Backup]] + entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true +end + +function subscribe() + nixio.fs.remove(SERVER_DETECT_CACHE) + local sid = luci.http.formvalue("sid") or "" + local subscribe_arg = sid ~= "" and (" " .. luci.util.shellquote(sid)) or "" + local ret = luci.sys.call(": > /var/log/ssrplus.log && /usr/bin/lua /usr/share/shadowsocksr/subscribe.lua" .. subscribe_arg .. " >>/var/log/ssrplus.log 2>&1") + luci.http.prepare_content("application/json") + luci.http.write_json({ret = ret}) +end + +function save_order() + local order = luci.http.formvalue("order") or "" + local page = parse_nonnegative_int(luci.http.formvalue("page")) or 1 + local page_size = parse_nonnegative_int(luci.http.formvalue("page_size")) or 0 + local sids = {} + local all_sections = {} + local server_sections = {} + local server_positions = {} + local section_index = {} + local page_start + local page_end + + for sid in order:gmatch("%S+") do + if uci:get("shadowsocksr", sid) == "servers" and not section_index[sid] then + sids[#sids + 1] = sid + section_index[sid] = true + end + end + + uci:foreach("shadowsocksr", nil, function(section) + all_sections[#all_sections + 1] = section[".name"] + if section[".type"] == "servers" then + server_sections[#server_sections + 1] = section[".name"] + server_positions[#server_positions + 1] = #all_sections + end + end) + + page_start = 1 + page_end = #server_sections + if page_size > 0 then + page_start = ((math.max(page, 1) - 1) * page_size) + 1 + page_end = math.min(page_start + page_size - 1, #server_sections) + end + + local page_sections = {} + local page_lookup = {} + for index = page_start, page_end do + local sid = server_sections[index] + if sid then + page_sections[#page_sections + 1] = sid + page_lookup[sid] = true + end + end + + local valid = #sids > 0 and #sids == #page_sections + if valid then + for _, sid in ipairs(sids) do + if not page_lookup[sid] then + valid = false + break + end + end + end + + if valid then + for offset, sid in ipairs(sids) do + local absolute_index = page_start + offset - 1 + local position = server_positions[absolute_index] + if not position then + valid = false + break + end + + local cmd = string.format( + "uci -q reorder %s=%d >/dev/null 2>&1", + shell_quote("shadowsocksr." .. sid), + position - 1 + ) + + if luci.sys.call(cmd) ~= 0 then + valid = false + break + end + all_sections[position] = sid + end + if valid then + valid = luci.sys.call("uci -q commit shadowsocksr >/dev/null 2>&1") == 0 + end + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ + ret = valid and 1 or 0, + count = #sids, + page = page, + page_size = page_size + }) +end + +function act_delete_node() + local sid = luci.http.formvalue("sid") + + if not sid or sid == "" then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "missing sid" }) + return + end + + local del_cmd = luci.sys.call("uci -q delete shadowsocksr." .. sid) + if del_cmd ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "delete failed" }) + return + end + + local ret_cmd = luci.sys.call("uci -q commit shadowsocksr >/dev/null 2>&1") + if ret_cmd ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "commit failed" }) + return + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 1, sid = sid }) +end + +function add_subscribe_item() + local sid = luci.sys.exec("uci add shadowsocksr server_subscribe_item"):gsub("%s+", "") + + if not sid or sid == "" then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "add failed" }) + return + end + + local alias = string.format("Subscribe %s", sid:sub(-4)) + + -- set enabled + local subscribe_enabled = luci.sys.call("uci -q set shadowsocksr." .. sid .. ".enabled=1") + if subscribe_enabled ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "set enabled failed" }) + return + end + + -- set alias + local subscribe_alias = luci.sys.call("uci -q set shadowsocksr." .. sid .. ".alias='" .. alias .. "'") + if subscribe_alias ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "set alias failed" }) + return + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 1, sid = sid, alias = alias, enabled = "1" }) +end + +function delete_subscribe_item() + local sid = trim(luci.http.formvalue("sid")) + if sid == "" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "missing sid" }) + return + end + + local delete_subscribe_set = luci.sys.call("uci -q delete shadowsocksr." .. sid .. " 2>/dev/null") + if delete_subscribe_set ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "delete failed" }) + return + end + + -- commit + local delete_subscribe_cmd = luci.sys.call("uci -q commit shadowsocksr >/dev/null 2>&1") + if delete_subscribe_cmd ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "commit failed" }) + return + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 1, sid = sid }) +end + +function toggle_subscribe_item_enabled() + local sid = trim(luci.http.formvalue("sid")) + local field = luci.http.formvalue("field") + local value = luci.http.formvalue("value") + + -- 兼容旧调用方å¼ï¼ˆåªä¼  enabled) + if not field then + field = "enabled" + value = luci.http.formvalue("enabled") == "1" and "1" or "0" + end + + -- 傿•°æ ¡éªŒ + if sid == "" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "missing sid" }) + return + end + + -- 检查 sid 对应的 section 类型 + if uci:get("shadowsocksr", sid) ~= "server_subscribe_item" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "invalid_sid" }) + return + end + + -- 白åå•:åªå…许以下字段 + local allowed_fields = { enabled = true, alias = true, url = true } + if not allowed_fields[field] then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "unsupported field" }) + return + end + + -- 处ç†å­—段值 + if field == "enabled" then + value = (value == "1" or value == "true") and "1" or "0" + elseif field == "alias" or field == "url" then + value = value and trim(value) or "" + end + + -- 转义 value 中的å•引å·ï¼ˆé¿å…ç ´å uci 命令) + local escaped_value = value:gsub("'", "'\\''") + + -- 使用外部 uci 命令设置值 + local set_cmd = string.format("uci -q set shadowsocksr.%s.%s='%s'", sid, field, escaped_value) + local set_ret = luci.sys.call(set_cmd .. " >/dev/null 2>&1") + if set_ret ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "uci set failed" }) + return + end + + -- æäº¤æ›´æ”¹ + local ret_cmd = luci.sys.call("uci -q commit shadowsocksr >/dev/null 2>&1") + if ret_cmd ~= 0 then + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 0, error = "commit failed" }) + return + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 1, sid = sid, field = field, value = value }) +end + +function component_status() + local component = luci.http.formvalue("component") + local data, status, err = read_component_state(component, "info") + if not data then + luci.http.status(status or 500, "Bad Request") + write_component_json({component = component, error = err or "bad_request"}) + return + end + write_component_json(data) +end + +function component_local_status() + local component = luci.http.formvalue("component") + local data, status, err = read_component_state(component, "local_info") + if not data then + luci.http.status(status or 500, "Bad Request") + write_component_json({component = component, error = err or "bad_request"}) + return + end + write_component_json(data) +end + +function component_set_mirror() + local mirror = luci.http.formvalue("mirror") or "direct" + local allowed = { + direct = true, + ghproxy = true, + ghproxy_cc = true, + ghfast = true, + jsdelivr = true + } + + if not allowed[mirror] then + mirror = "direct" + end + + uci:set("shadowsocksr", "@global[0]", "component_mirror", mirror) + uci:commit("shadowsocksr") + + luci.http.prepare_content("application/json") + luci.http.write_json({ ret = 1, mirror = mirror }) +end + +function component_upgrade() + local component = luci.http.formvalue("component") + local data, status, err = read_component_state(component, "upgrade") + if not data then + luci.http.status(status or 500, "Bad Request") + write_component_json({component = component, error = err or "bad_request", success = "0"}) + return + end + + local info = read_component_state(component, "info") + if info then + for key, value in pairs(info) do + if data[key] == nil or data[key] == "" then + data[key] = value + end + end + if data.success == "1" then + data.can_upgrade = info.can_upgrade + end + end + + write_component_json(data) +end + +function geo_status() + local component = luci.http.formvalue("component") + local data, status, err = read_geo_state(component, "info") + if not data then + luci.http.status(status or 500, "Bad Request") + write_geo_json({component = component, error = err or "bad_request"}) + return + end + write_geo_json(data) +end + +function geo_local_status() + local component = luci.http.formvalue("component") + local data, status, err = read_geo_state(component, "local_info") + if not data then + luci.http.status(status or 500, "Bad Request") + write_geo_json({component = component, error = err or "bad_request"}) + return + end + write_geo_json(data) +end + +function geo_upgrade() + local component = luci.http.formvalue("component") + local data, status, err = read_geo_state(component, "upgrade") + if not data then + luci.http.status(status or 500, "Bad Request") + write_geo_json({component = component, error = err or "bad_request", success = "0"}) + return + end + write_geo_json(data) +end + +function act_status() + local e = {} + e.running = global_client_running() + if e.running then + e.status_text = get_running_status_text() + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function clash_panel() + local sid = luci.http.formvalue("sid") + if uci:get("shadowsocksr", sid) ~= "servers" or uci:get("shadowsocksr", sid, "type") ~= "clash" then + luci.http.status(404, "Not Found") + return + end + luci.template.render("shadowsocksr/clash_panel", { + sid = sid, + alias = uci:get("shadowsocksr", sid, "alias") or sid + }) +end + +function clash_groups() + local sid = luci.http.formvalue("sid") + local groups = {} + local active_sid = resolve_active_clash_sid(sid) + local active = active_sid ~= nil + if active then + local raw = clash_api_request(active_sid, "GET", "/proxies") + if raw then + groups = parse_clash_groups(raw.body) + end + end + luci.http.prepare_content("application/json") + luci.http.write_json({ + active = active, + sid = active_sid, + groups = groups + }) +end + +function clash_switch() + local sid = luci.http.formvalue("sid") + local group = luci.http.formvalue("group") + local name = luci.http.formvalue("name") + if not sid or not group or not name then + luci.http.status(400, "Bad Request") + return + end + local active_sid = resolve_active_clash_sid(sid) + if not active_sid then + luci.http.status(409, "Conflict") + luci.http.prepare_content("application/json") + luci.http.write_json({success = false, message = "inactive"}) + return + end + local body = string.format('{"name":"%s"}', tostring(name):gsub('"', '\\"')) + local path = "/proxies/" .. urlencode(group) + local ret = clash_api_request(active_sid, "PUT", path, body) + luci.http.prepare_content("application/json") + luci.http.write_json({success = ret ~= nil and ret.code and ret.code >= 200 and ret.code < 300, sid = active_sid}) +end + +function clash_refresh() + local sid = luci.http.formvalue("sid") + if not sid or uci:get("shadowsocksr", sid) ~= "servers" or uci:get("shadowsocksr", sid, "type") ~= "clash" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({success = false}) + return + end + local cmd = string.format("/etc/init.d/shadowsocksr clash_cache %s >/dev/null 2>&1", luci.util.shellquote(sid)) + local ok = luci.sys.call(cmd) == 0 + local reapplied = false + if ok and is_active_clash_node(sid) then + luci.sys.call("/etc/init.d/shadowsocksr restart >/dev/null 2>&1 &") + reapplied = true + end + luci.http.prepare_content("application/json") + luci.http.write_json({ + success = ok, + cached = nixio.fs.access(get_clash_cache_file(sid)), + reapplied = reapplied + }) +end + +function clash_reset_defaults() + local sid = luci.http.formvalue("sid") + if not sid or uci:get("shadowsocksr", sid) ~= "servers" or uci:get("shadowsocksr", sid, "type") ~= "clash" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({success = false}) + return + end + + local state_file = get_clash_state_file(sid) + local cleared = false + if nixio.fs.access(state_file) then + cleared = nixio.fs.remove(state_file) or false + else + cleared = true + end + + local reapplied = false + if cleared and is_active_clash_node(sid) then + luci.sys.call("/etc/init.d/shadowsocksr restart >/dev/null 2>&1 &") + reapplied = true + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ + success = cleared, + reapplied = reapplied + }) +end + +function clash_client_policies() + local sid = luci.http.formvalue("sid") + local active_sid = resolve_active_clash_sid(sid) + local groups = {} + if active_sid then + local raw = clash_api_request(active_sid, "GET", "/proxies") + if raw then + groups = parse_clash_groups(raw.body) + end + end + + local policies = {} + local seen = {} + for _, group in ipairs(groups or {}) do + if group.name and not seen[group.name] then + seen[group.name] = true + policies[#policies + 1] = { + name = group.name, + label = group.name, + type = group.type or "" + } + end + for _, proxy_name in ipairs(group.all or {}) do + if proxy_name and proxy_name ~= "" and not seen[proxy_name] then + seen[proxy_name] = true + policies[#policies + 1] = { + name = proxy_name, + label = proxy_name, + type = "proxy" + } + end + end + end + + table.sort(policies, function(a, b) + return tostring(a.label or a.name) < tostring(b.label or b.name) + end) + + luci.http.prepare_content("application/json") + luci.http.write_json({ + active = active_sid ~= nil, + sid = active_sid, + clients = collect_lan_clients(), + rules = read_clash_client_rules(sid), + policies = policies + }) +end + +function clash_client_rule_save() + local sid = luci.http.formvalue("sid") + local rows = {} + local max_rows = tonumber(luci.http.formvalue("count") or "0") or 0 + + for index = 1, math.min(max_rows, 256) do + local prefix = string.format("rule_%d_", index) + local ip_addr = normalize_client_ip(luci.http.formvalue(prefix .. "ip_addr")) + local enabled = luci.http.formvalue(prefix .. "enabled") == "1" and "1" or "0" + local remarks = trim(luci.http.formvalue(prefix .. "remarks")) + local policy_group = trim(luci.http.formvalue(prefix .. "policy_group")) + local client_mac = sanitize_mac(luci.http.formvalue(prefix .. "client_mac")) + + if ip_addr ~= "" and policy_group ~= "" then + rows[#rows + 1] = { + enabled = enabled, + remarks = remarks, + ip_addr = ip_addr, + client_mac = client_mac, + policy_group = policy_group + } + end + end + + if not sid or sid == "" or uci:get("shadowsocksr", sid) ~= "servers" or uci:get("shadowsocksr", sid, "type") ~= "clash" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({ success = false, error = "invalid_sid" }) + return + end + + write_clash_client_rules_csv(sid, rows) + + local active_sid = resolve_active_clash_sid(sid) + local current_sid = uci:get_first("shadowsocksr", "global", "global_server") + local reapplied = false + if sid and sid ~= "" and uci:get("shadowsocksr", sid) == "servers" + and uci:get("shadowsocksr", sid, "type") == "clash" + and current_sid == sid then + luci.sys.call("/etc/init.d/shadowsocksr restart >/dev/null 2>&1 &") + reapplied = true + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ + success = true, + count = #rows, + reapplied = reapplied, + rules = read_clash_client_rules(sid) + }) +end + +function clash_client_rule_clear() + local sid = luci.http.formvalue("sid") + + if not sid or sid == "" or uci:get("shadowsocksr", sid) ~= "servers" or uci:get("shadowsocksr", sid, "type") ~= "clash" then + luci.http.status(400, "Bad Request") + luci.http.prepare_content("application/json") + luci.http.write_json({ success = false, error = "invalid_sid" }) + return + end + + local csv_path = get_clash_client_rule_csv_path(sid) + if csv_path and nixio.fs.access(csv_path) then + nixio.fs.remove(csv_path) + end + + local current_sid = uci:get_first("shadowsocksr", "global", "global_server") + local reapplied = false + if sid and sid ~= "" and uci:get("shadowsocksr", sid) == "servers" + and uci:get("shadowsocksr", sid, "type") == "clash" + and current_sid == sid then + luci.sys.call("/etc/init.d/shadowsocksr restart >/dev/null 2>&1 &") + reapplied = true + end + + luci.http.prepare_content("application/json") + luci.http.write_json({ + success = true, + reapplied = reapplied, + rules = {} + }) +end + +function act_ping() + local e = {} + local domain = luci.http.formvalue("domain") + local port = tonumber(luci.http.formvalue("port") or 0) + local transport = (luci.http.formvalue("transport") or ""):lower() + local wsPath = luci.http.formvalue("wsPath") or "" + local host = luci.http.formvalue("host") or "" + local tls_host = luci.http.formvalue("tlsHost") or "" + local tls = luci.http.formvalue("tls") + local type = (luci.http.formvalue("type") or ""):lower() + local proto = (luci.http.formvalue("proto") or ""):lower() + local reality = luci.http.formvalue("reality") + local sid = luci.http.formvalue("sid") + e.index = luci.http.formvalue("index") + + if sid and sid ~= "" and uci:get("shadowsocksr", sid) == "servers" then + domain = uci:get("shadowsocksr", sid, "server") or domain + port = tonumber(uci:get("shadowsocksr", sid, "server_port") or port or 0) + transport = (uci:get("shadowsocksr", sid, "transport") or transport or ""):lower() + wsPath = uci:get("shadowsocksr", sid, "ws_path") or wsPath + host = uci:get("shadowsocksr", sid, "ws_host") or host + tls_host = uci:get("shadowsocksr", sid, "tls_host") or tls_host + tls = uci:get("shadowsocksr", sid, "tls") or tls + type = (uci:get("shadowsocksr", sid, "type") or type or ""):lower() + proto = (uci:get("shadowsocksr", sid, "v2ray_protocol") or proto or ""):lower() + reality = uci:get("shadowsocksr", sid, "reality") or reality + end + + local is_ip = domain and domain:match("^%d+%.%d+%.%d+%.%d+$") + local probe_host = (tls_host ~= "" and tls_host) or (host ~= "" and host) or domain + local is_reality = (reality == "1" or reality == "true") + local prefers_handshake_latency = (type == "v2ray") and not is_reality + + -- 临时放行防ç«å¢™é€»è¾‘ + local use_nft = use_fw4_backend() + local iret = false + if domain then + if use_nft then + iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null") == 0 + else + iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null") == 0 + end + end + -- Hysteria2 èŠ‚ç‚¹è½»é‡ UDP ç«¯å£æ£€æµ‹ + if proto:find("hysteria2") or type:find("hysteria2") then + local udp_cmd = string.format("nping --udp -c 1 -p %d %s 2>/dev/null", port, domain) + local udp_raw = luci.sys.exec(udp_cmd) or "" + local udp_rtt = udp_raw:match("Avg rtt:%s*([0-9.]+)ms") + local udp_unreachable = udp_raw:match("[Pp]ort [Uu]nreachable") or udp_raw:match("ICMP") + local udp_sent = udp_raw:match("Raw packets sent:%s*1") + + -- UDP æœåŠ¡é€šå¸¸ä¸ä¼šä¸»åŠ¨å›žåŒ…ï¼Œæœªæ”¶åˆ°åº”ç­”ä¸ç­‰äºŽç«¯å£ä¸å¯ç”¨ã€‚ + -- 仅在出现明显的ä¸å¯è¾¾è¿¹è±¡æ—¶æ ‡è®° fail,其余视为轻é‡å¯è¾¾ã€‚ + e.socket = (udp_unreachable == nil) and (udp_sent ~= nil) + e.ping = udp_rtt and normalize_ping_ms(udp_rtt) or nil + + if not e.ping then + local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain) + e.ping = normalize_ping_ms(tonumber(luci.sys.exec(icmp_cmd))) + end + if not e.ping then + e.ping = 0 + end + elseif transport == "ws" then + -- WebSocket 探测 + local result = "" + local success = false + local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain) + e.ping = normalize_ping_ms(tonumber(luci.sys.exec(icmp_cmd))) + -- WebSocket 探测 (适用于域å,或带 SNI çš„ IP) + if not is_ip or probe_host ~= domain then + local resolve_arg = "" + local final_domain = probe_host + if is_ip and probe_host and probe_host ~= "" then + -- IP 模å¼ä¸‹ä½¿ç”¨ --resolve 强制指定 SNI,解决 TLS æ¡æ‰‹å¤±è´¥ + resolve_arg = string.format("--resolve '%s:%d:%s' ", probe_host, port, domain) + end + local prefix = (tls == '1') and "https://" or "http://" + local address = prefix .. final_domain .. ':' .. port .. wsPath + local cmd = string.format( + "curl --http1.1 -m 2 -ksN -o /dev/null %s" .. + "-w 'time_connect=%%{time_connect}\\nhttp_code=%%{http_code}' " .. + "%s" .. + "-H 'Connection: Upgrade' -H 'Upgrade: websocket' " .. + "-H 'Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==' " .. + "-H 'Sec-WebSocket-Version: 13' '%s'", + resolve_arg, + (probe_host and probe_host ~= "") and ("-H " .. luci.util.shellquote("Host: " .. probe_host) .. " ") or "", + address + ) + result = luci.sys.exec(cmd) or "" + success = (string.match(result, "http_code=(%d+)") == "101") + end + -- å¦‚æžœæ·±åº¦æŽ¢æµ‹å¤±è´¥ï¼Œæˆ–æ˜¯ä¸æ”¯æŒæ·±æµ‹çš„纯 IP + if not success then + local socket = nixio.socket("inet", "stream") + if socket then + socket:setopt("socket", "rcvtimeo", 3) + socket:setopt("socket", "sndtimeo", 3) + success = socket:connect(domain, port) + socket:close() + end + --luci.sys.exec(string.format("echo 'Node %s (ws) failed deep test, using TCP fallback' >> /tmp/ping.log", domain)) + end + e.socket = success + -- 延迟:优先 pingï¼Œå† curlï¼Œæœ€åŽ nping tcp-connect + if not e.ping then + local ping_time = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)")) + local appconnect_time = tonumber(string.match(result, "time_appconnect=(%d+.%d%d%d)")) + if appconnect_time and appconnect_time > 0 then + e.ping = normalize_ping_ms(appconnect_time, 1000) + elseif ping_time and ping_time > 0 then + e.ping = normalize_ping_ms(ping_time, 1000) + else + e.ping = detect_tcp_connect_ms(domain, port) or 0 + end + end + else + -- 3. éž WebSocket 节点的探测逻辑 (TCP / ICMP / UDP) + local socket = nixio.socket("inet", "stream") + if socket then + socket:setopt("socket", "rcvtimeo", 3) + socket:setopt("socket", "sndtimeo", 3) + e.socket = socket:connect(domain, port) + socket:close() + end + + if prefers_handshake_latency and (tls == "1" or tls_host ~= "" or proto == "vless" or proto == "vmess") then + e.ping = detect_tls_handshake_ms(domain, port, "", probe_host, domain, false) + end + + -- å»¶è¿Ÿï¼šä¼˜å…ˆçœŸå®žæ¡æ‰‹ï¼Œå† nping tcp-connect -> ping -> nping(udp) + if not e.ping then + if not is_reality then + e.ping = detect_tcp_connect_ms(domain, port) + end + end + if not e.ping then + local icmp_cmd = string.format("ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9.]*' | cut -d= -f2", domain) + e.ping = normalize_ping_ms(tonumber(luci.sys.exec(icmp_cmd))) + end + + if not e.ping then + local udp_cmd = string.format("nping --udp -c 1 -p %d %s 2>/dev/null | grep -o 'Avg rtt: [0-9.]*ms' | awk '{print $3}' | sed 's/ms//' | head -1", port, domain) + local udp_res = luci.sys.exec(udp_cmd) + if udp_res and udp_res ~= "" then + local ping_num = tonumber(udp_res) + if ping_num then e.ping = normalize_ping_ms(ping_num) end + end + end + + if (not e.ping or e.ping == 0) and domain and port > 0 then + local schemes = { "https", "http" } + for _, scheme in ipairs(schemes) do + local connect_cmd = string.format( + "curl -m 2 -ksS -o /dev/null -w 'time_connect=%%{time_connect}' %s://%s:%d 2>/dev/null", + scheme, domain, port + ) + local connect_res = luci.sys.exec(connect_cmd) or "" + local connect_time = tonumber(connect_res:match("time_connect=([0-9.]+)")) + if connect_time and connect_time > 0 then + e.ping = normalize_ping_ms(connect_time, 1000) + break + end + end + end + end + + -- 4. 清ç†é˜²ç«å¢™è§„则 + if iret then + if use_nft then + luci.sys.call("nft delete element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null") + else + luci.sys.call("ipset del ss_spec_wan_ac " .. domain .. " 2>/dev/null") + end + end + + if sid and sid ~= "" then + save_detect_cache_entry(sid, { + server = domain or "", + port = port or 0, + type = type or "", + proto = proto or "", + socket = e.socket and true or false, + ping = tonumber(e.ping) or 0, + time = os.time() + }) + end + + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function check_status() + local e = {} + local target = luci.http.formvalue("set") or "" + e.ret = luci.sys.call("curl -m 3 -sS -o /dev/null http://www." .. target .. ".com >/dev/null 2>&1") + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function refresh_data() + local set = luci.http.formvalue("set") + local retstring = loadstring("return " .. luci.sys.exec("/usr/bin/lua /usr/share/shadowsocksr/update.lua " .. set))() + luci.http.prepare_content("application/json") + luci.http.write_json(retstring) +end + +function check_port() + local retstring = "

" + local s + local server_name = "" + local uci = require "luci.model.uci".cursor() + local use_nft = use_fw4_backend() + + uci:foreach("shadowsocksr", "servers", function(s) + if s.type == "clash" then + retstring = retstring .. string.format("[%s] Clash panel node.
", s.alias or s[".name"]) + return + end + if s.alias then + server_name = s.alias + elseif s.server and s.server_port then + server_name = s.server .. ":" .. s.server_port + end + + -- 临时加入 set + local is_ipv6 = is_ipv6_address(s.server) + local iret = false + if not is_ipv6 then + if use_nft then + iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. s.server .. " } 2>/dev/null") == 0 + else + iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null") == 0 + end + end + + -- TCP 测试 + local socket = nixio.socket(is_ipv6 and "inet6" or "inet", "stream") + socket:setopt("socket", "rcvtimeo", 3) + socket:setopt("socket", "sndtimeo", 3) + local ret = socket:connect(s.server, s.server_port) + socket:close() + + if ret then + retstring = retstring .. string.format("[%s] OK.
", server_name) + else + retstring = retstring .. string.format("[%s] Error.
", server_name) + end + + -- 删除临时 set + if iret then + if use_nft then + luci.sys.call("nft delete element inet ss_spec ss_spec_wan_ac { " .. s.server .. " } 2>/dev/null") + else + luci.sys.call("ipset del ss_spec_wan_ac " .. s.server) + end + end + end) + + luci.http.prepare_content("application/json") + luci.http.write_json({ret = retstring}) +end + +function act_reset() + luci.sys.call("/etc/init.d/shadowsocksr reset >/dev/null 2>&1") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr")) +end + +function act_restart() + luci.sys.call("/etc/init.d/shadowsocksr restart > /dev/null 2>&1 &") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr")) +end + +function act_delete() + luci.sys.call("/etc/init.d/shadowsocksr restart > /dev/null 2>&1 &") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) +end + +function get_log() + luci.http.write(luci.sys.exec("[ -f '/var/log/ssrplus.log' ] && cat /var/log/ssrplus.log")) +end + +function clear_log() + luci.sys.call("echo '' > /var/log/ssrplus.log") +end + +function create_backup() + local backup_files = { + "/etc/config/shadowsocksr", + "/etc/ssrplus/*" + } + local date = os.date("%Y-%m-%d-%H-%M-%S") + local tar_file = "/tmp/shadowsocksr-" .. date .. "-backup.tar.gz" + nixio.fs.remove(tar_file) + local cmd = "tar -czf " .. tar_file .. " " .. table.concat(backup_files, " ") + luci.sys.call(cmd) + luci.http.header("Content-Disposition", "attachment; filename=shadowsocksr-" .. date .. "-backup.tar.gz") + luci.http.header("X-Backup-Filename", "shadowsocksr-" .. date .. "-backup.tar.gz") + luci.http.prepare_content("application/octet-stream") + luci.http.write(nixio.fs.readfile(tar_file)) + nixio.fs.remove(tar_file) +end diff --git a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua.rej b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua.rej new file mode 100644 index 00000000..b4ced41f --- /dev/null +++ b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua.rej @@ -0,0 +1,65 @@ +--- luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua ++++ luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua +@@ -26,6 +26,62 @@ function index() + entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset")) + entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart")) + entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete")) ++ entry({'admin', 'services', "shadowsocksr", 'ip'}, call('check_ip')) -- 获å–ip情况 ++end ++ ++function check_site(host, port) ++ local nixio = require "nixio" ++ local socket = nixio.socket("inet", "stream") ++ socket:setopt("socket", "rcvtimeo", 2) ++ socket:setopt("socket", "sndtimeo", 2) ++ local ret = socket:connect(host, port) ++ socket:close() ++ return ret ++end ++ ++function get_ip_geo_info() ++ local result = luci.sys.exec('curl --retry 3 -m 10 -LfsA "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36" http://ip-api.com/json/') ++ local json = require "luci.jsonc" ++ local info = json.parse(result) ++ ++ return { ++ flag = string.lower(info.countryCode) or "un", ++ country = get_country_name(info.countryCode) or "Unknown", ++ ip = info.query, ++ isp = info.isp ++ } ++end ++ ++function get_country_name(countryCode) ++ local country_names = { ++ US = "美国", CN = "中国", JP = "日本", GB = "英国", DE = "德国", ++ FR = "法国", BR = "巴西", IT = "æ„大利", RU = "ä¿„ç½—æ–¯", CA = "加拿大", ++ KR = "韩国", ES = "西ç­ç‰™", AU = "澳大利亚", MX = "墨西哥", ID = "å°åº¦å°¼è¥¿äºš", ++ NL = "è·å…°", TR = "土耳其", CH = "瑞士", SA = "沙特阿拉伯", SE = "瑞典", ++ PL = "波兰", BE = "比利时", AR = "阿根廷", NO = "挪å¨", AT = "奥地利", ++ TW = "å°æ¹¾", ZA = "å—éž", TH = "泰国", DK = "丹麦", MY = "马æ¥è¥¿äºš", ++ PH = "è²å¾‹å®¾", SG = "新加å¡", IE = "爱尔兰", HK = "香港", FI = "芬兰", ++ CL = "智利", PT = "è‘¡è„牙", GR = "希腊", IL = "以色列", NZ = "新西兰", ++ CZ = "æ·å…‹", RO = "罗马尼亚", VN = "è¶Šå—", UA = "乌克兰", HU = "匈牙利", ++ AE = "阿è”é…‹", CO = "哥伦比亚", IN = "å°åº¦", EG = "埃åŠ", PE = "秘é²", TW = "å°æ¹¾" ++ } ++ return country_names[countryCode] ++end ++ ++function check_ip() ++ local e = {} ++ local port = 80 ++ local geo_info = get_ip_geo_info(ip) ++ e.ip = geo_info.ip ++ e.flag = geo_info.flag ++ e.country = geo_info.country ++ e.isp = geo_info.isp ++ e.baidu = check_site('www.baidu.com', port) ++ e.taobao = check_site('www.taobao.com', port) ++ e.google = check_site('www.google.com', port) ++ e.youtube = check_site('www.youtube.com', port) ++ luci.http.prepare_content('application/json') ++ luci.http.write_json(e) + end + + function subscribe() diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua new file mode 100644 index 00000000..6ef1da15 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua @@ -0,0 +1,309 @@ +local m, s, o +local cbi = require "luci.cbi" +local uci = require "luci.model.uci".cursor() +local URL = require "url" + +-- èŽ·å– LAN IP åœ°å€ +function lanip() + local lan_ip + + -- å°è¯•从 UCI ç›´æŽ¥è¯»å– + lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F'/' '{print $1}' | tr -d '\\n'") + + -- å°è¯•从 LAN 接å£ä¿¡æ¯ä¸­è¯»å–(优先 ifnameï¼Œå† fallback 到 device) + if not lan_ip or lan_ip == "" then + lan_ip = luci.sys.exec([[ +ip -4 addr show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) 2>/dev/null \ + | grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']]) + end + + -- å–ä»»æ„一个 global IPv4 åœ°å€ + if not lan_ip or lan_ip == "" then + lan_ip = luci.sys.exec([[ +ip -4 addr show scope global 2>/dev/null \ + | grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']]) + end + + return lan_ip +end + +local lan_ip = lanip() +local server_table = {} +local type_table = {} +local function is_finded(e) + return luci.sys.exec(string.format('type -t -p "%s" -p "/usr/libexec/%s" 2>/dev/null', e, e)) ~= "" +end + +local function clash_display_name(s) + if s.type ~= "clash" or not s.clash_url or s.clash_url == "" then + return nil + end + local ok, parsed = pcall(URL.parse, s.clash_url) + if ok and parsed and parsed.host then + return "[CLASH]:" .. parsed.host + end + return "[CLASH]" +end + +uci:foreach("shadowsocksr", "servers", function(s) + if s.type ~= "tun" and s.alias then + server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.v2ray_protocol or s.type), s.alias} + elseif s.type ~= "tun" and s.server and s.server_port then + server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.v2ray_protocol or s.type), s.server, s.server_port} + elseif s.type ~= "tun" then + local display_name = clash_display_name(s) + if display_name then + server_table[s[".name"]] = display_name + end + end + if s.type and s.type ~= "tun" then + type_table[s[".name"]] = s.type + end +end) + +local key_table = {} +for key, _ in pairs(server_table) do + table.insert(key_table, key) +end + +table.sort(key_table) + +m = Map("shadowsocksr") +-- [[ global ]]-- +s = m:section(TypedSection, "global", translate("Server failsafe auto swith and custom update settings")) +s.anonymous = true + +-- o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon")) +-- o.rmempty = false +-- o.default = "1" + +o = s:option(Flag, "enable_switch", translate("Enable Auto Switch")) +o.rmempty = false +o.default = "1" + +o = s:option(Value, "switch_time", translate("Switch check cycly(second)")) +o.datatype = "uinteger" +o:depends("enable_switch", "1") +o.default = 667 + +o = s:option(Value, "switch_timeout", translate("Check timout(second)")) +o.datatype = "uinteger" +o:depends("enable_switch", "1") +o.default = 5 + +o = s:option(Value, "switch_try_count", translate("Check Try Count")) +o.datatype = "uinteger" +o:depends("enable_switch", "1") +o.default = 3 + +s:append(cbi.Template("shadowsocksr/advanced_switch_compact")) + +o = s:option(Value, "default_node_local_port", translate("Default Node Local Port")) +o.datatype = "port" +o.default = 1234 +o.rmempty = false + +o = s:option(Value, "gfwlist_url", translate("gfwlist Update url")) +o:value("https://fastly.jsdelivr.net/gh/YW5vbnltb3Vz/domain-list-community@release/gfwlist.txt", translate("v2fly/domain-list-community")) +o:value("https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt", translate("Loyalsoldier/v2ray-rules-dat")) +o:value("https://fastly.jsdelivr.net/gh/Loukky/gfwlist-by-loukky/gfwlist.txt", translate("Loukky/gfwlist-by-loukky")) +o:value("https://fastly.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt", translate("gfwlist/gfwlist")) +o.default = "https://fastly.jsdelivr.net/gh/YW5vbnltb3Vz/domain-list-community@release/gfwlist.txt" + +o = s:option(Value, "chnroute_url", translate("Chnroute Update url")) +o:value("https://ispip.clang.cn/all_cn.txt", translate("Clang.CN")) +o:value("https://ispip.clang.cn/all_cn_cidr.txt", translate("Clang.CN.CIDR")) +o:value("https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china.txt", translate("china-operator-ip")) +o.default = "https://ispip.clang.cn/all_cn.txt" + +o = s:option(Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses")) +o.rmempty = false +o.default = "1" + +o = s:option(Value, "apple_url", translate("Apple Domains Update url")) +o:value("https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf", translate("felixonmars/dnsmasq-china-list")) +o.default = "https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf" +o:depends("apple_optimization", "1") + +o = s:option(Value, "apple_dns", translate("Apple Domains DNS"), translate("If empty, Not change Apple domains parsing DNS (Default is empty)")) +o.rmempty = true +o.default = "" +o.datatype = "ip4addr" +o:depends("apple_optimization", "1") + +o = s:option(Flag, "adblock", translate("Enable adblock")) +o.rmempty = false + +o = s:option(Value, "adblock_url", translate("adblock_url")) +o:value("https://raw.githubusercontent.com/neodevpro/neodevhost/master/dnsmasq.conf", translate("NEO DEV HOST")) +o:value("https://anti-ad.net/anti-ad-for-dnsmasq.conf", translate("anti-AD")) +o.default = "https://raw.githubusercontent.com/neodevpro/neodevhost/master/dnsmasq.conf" +o:depends("adblock", "1") +o.description = translate("Support AdGuardHome and DNSMASQ format list") + +o = s:option(Button, "Reset", translate("Reset to defaults")) +o.inputstyle = "reload" +o.write = function() + luci.sys.call("/etc/init.d/shadowsocksr reset") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) +end + +-- [[ SOCKS5 Proxy ]]-- +s = m:section(TypedSection, "socks5_proxy", translate("Global SOCKS5 Proxy Server")) +s.anonymous = true +-- s.description = translate("Only Same as Global Server is supported here. If the current main program supports a built-in SOCKS5 listener, it will be enabled in-process; otherwise SSR Plus will fall back to microsocks.") + +-- Enable/Disable Option +o = s:option(Flag, "enabled", translate("Enable")) +o.default = 0 +o.rmempty = false + +-- Socks Auth +if is_finded("xray") then +o = s:option(ListValue, "socks5_auth", translate("Socks5 Auth Mode"), translate("Socks protocol auth methods, default:noauth.")) +o.default = "noauth" +o:value("noauth", "NOAUTH") +o:value("password", "PASSWORD") +o.rmempty = true + +-- Socks User +o = s:option(Value, "socks5_user", translate("Socks5 User"), translate("Only when Socks5 Auth Mode is password valid, Mandatory.")) +o.rmempty = true +o:depends("socks5_auth", "password") + +-- Socks Password +o = s:option(Value, "socks5_pass", translate("Socks5 Password"), translate("Only when Socks5 Auth Mode is password valid, Not mandatory.")) +o.password = true +o.rmempty = true +o:depends("socks5_auth", "password") + +-- Socks Mixed +o = s:option(Flag, "socks5_mixed", translate("Enabled Mixed"), translate("Mixed as an alias of socks, default:Enabled.")) +o.default = "1" +o.rmempty = false +end + +-- Local Port +o = s:option(Value, "local_port", translate("Local Port")) +o.datatype = "port" +o.default = 1080 +o.rmempty = false + +if is_finded("3proxy") then + -- [[ HTTP/HTTPS Proxy ]]-- + s = m:section(TypedSection, "http_proxy", translate("Global HTTP/HTTPS Proxy Server")) + s.anonymous = true + -- s.description = translate("Only Same as Global Server is supported here. HTTP/HTTPS proxy service is provided through 3proxy.") + + o = s:option(Flag, "enabled", translate("Enable")) + o.default = 0 + o.rmempty = false + + o = s:option(ListValue, "http_auth", translate("HTTP Auth Mode"), translate("HTTP proxy auth method, default:none.")) + o.default = "none" + o:value("none", "NONE") + o:value("password", "PASSWORD") + o.rmempty = false + + o = s:option(Value, "http_user", translate("HTTP User"), translate("Only when HTTP Auth Mode is password valid, Mandatory.")) + o.rmempty = true + o:depends("http_auth", "password") + + o = s:option(Value, "http_pass", translate("HTTP Password"), translate("Only when HTTP Auth Mode is password valid, Not mandatory.")) + o.password = true + o.rmempty = true + o:depends("http_auth", "password") + + o = s:option(Value, "local_port", translate("Local Port")) + o.datatype = "port" + o.default = 3128 + o.rmempty = false +end + +-- [[ fragmen Settings ]]-- +if is_finded("xray") then + s = m:section(TypedSection, "global_xray_fragment", translate("Xray Fragment Settings")) + s.anonymous = true + + o = s:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists.")) + o.default = 0 + + o = s:option(ListValue, "fragment_packets", translate("Fragment Packets"), translate("\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation.")) + o.default = "tlshello" + o:value("tlshello", "tlshello") + o:value("1-1", "1-1") + o:value("1-2", "1-2") + o:value("1-3", "1-3") + o:value("1-5", "1-5") + o:depends("fragment", true) + + o = s:option(Value, "fragment_length", translate("Fragment Length"), translate("Fragmented packet length (byte)")) + o.datatype = "or(uinteger,portrange)" + o.default = "100-200" + o:depends("fragment", true) + + o = s:option(Value, "fragment_delay", translate("Fragment Delay"), translate("Fragmentation interval (ms)")) + o.datatype = "or(uinteger,portrange)" + o.default = "10-20" + o:depends("fragment", true) + + o = s:option(Value, "fragment_maxSplit", translate("Max Split"), translate("Limit the maximum number of splits.")) + o.datatype = "or(uinteger,portrange)" + o.default = "100-200" + o:depends("fragment", true) + + o = s:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions.")) + o.default = 0 + + s = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets")) + s.description = translate( + "" .. translate("To send noise packets, select \"Noise\" in Xray Settings.") .. "" .. + "
" .. translate("Packet or Rand length as a string, e.g., 10-20.") .. "" .. + "
" .. translate("For specific usage, see:") .. "" .. + "" .. + "" .. translate("Click to the page") .. "") + s.template = "cbi/tblsection" + s.sortable = true + s.anonymous = true + s.addremove = true + + s.remove = function(self, section) + for k, v in pairs(self.children) do + v.rmempty = true + v.validate = nil + end + TypedSection.remove(self, section) + end + + o = s:option(Flag, "enabled", translate("Enable")) + o.default = 1 + o.rmempty = false + + o = s:option(ListValue, "type", translate("Type")) + o.default = "base64" + o:value("rand", "rand") + o:value("str", "str") + o:value("hex", "hex") + o:value("base64", "base64") + + o = s:option(Value, "domainStrategy", translate("Domain Strategy")) + o.default = "AsIs" + o:value("AsIs", "AsIs") + o:value("UseIP", "UseIP") + o:value("UseIPv4", "UseIPv4") + o:value("ForceIP", "ForceIP") + o:value("ForceIPv4", "ForceIPv4") + o.rmempty = false + + o = s:option(Value, "packet", translate("Packet | Rand Length")) + o.datatype = "minlength(1)" + o.rmempty = false + + o = s:option(Value, "delay", translate("Delay (ms)")) + o.datatype = "or(uinteger,portrange)" + o.rmempty = false + + s:append(cbi.Template("shadowsocksr/optimize_cbi_ui")) +end + +return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua new file mode 100644 index 00000000..32b6ba05 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua @@ -0,0 +1,1666 @@ +-- Copyright (C) 2017 yushi studio github.com/ywb94 +-- Licensed to the public under the GNU General Public License v3. + +require "nixio.fs" +require "luci.sys" +require "luci.http" +require "luci.jsonc" +local nixio = require "nixio" +require "luci.model.uci" +local uci = require "luci.model.uci".cursor() + +local m, s, o + +local sid = arg[1] +local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") +local b64decode = nixio.bin.b64decode +local b64encode = nixio.bin.b64encode +local xray_version = nil +local xray_version_val = 0 + +-- ç¡®ä¿æ­£ç¡®åˆ¤æ–­ç¨‹åºæ˜¯å¦å­˜åœ¨ +local function is_finded(e) + return luci.sys.exec(string.format('type -t -p "%s" -p "/usr/libexec/%s" 2>/dev/null', e, e)) ~= "" +end + +local function is_installed(e) + return luci.model.ipkg.installed(e) +end + +local function is_js_luci() + return luci.sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 +end + +-- trim +local function trim(text) + if not text or text == "" then + return "" + end + return (text:gsub("^%s*(.-)%s*$", "%1")) +end + +-- base64 è§£ç  +local function base64Decode(text) + local raw = text + if not text or text == "" then + return '' + end + text = text:gsub("%z", "") + text = text:gsub("%c", "") + text = text:gsub("%s", "") + text = text:gsub("_", "/") + text = text:gsub("-", "+") + text = text:gsub("=", "") + local mod4 = #text % 4 + text = text .. string.sub('====', mod4 + 1) + local result = b64decode(text) + if result then + return result:gsub("%z", "") + else + return raw + end +end + +-- base64 ç¼–ç  +local function base64Encode(text) + if not text or text == "" then + return '' + end + local result = b64encode(text) + if result then + result = result:gsub("%z", "") + return result + else + return text + end +end + +-- èŽ·å– Xray ç‰ˆæœ¬å· +if is_finded("xray") then + local version = luci.sys.exec("xray version 2>&1") + if version and version ~= "" then + xray_version = version:match("Xray%s+([%d%.]+)") + -- xray_version = version:match("([0-9]+%.[0-9]+%.[0-9]+)") + end +end + +-- å°† Xray 版本å·è½¬æ¢ä¸ºæ•°å­— +if xray_version and xray_version ~= "" then + local major, minor, patch = + xray_version:match("(%d+)%.?(%d*)%.?(%d*)") + + major = tonumber(major) or 0 + minor = tonumber(minor) or 0 + patch = tonumber(patch) or 0 + + xray_version_val = major * 10000 + minor * 100 + patch +end + +local function url(...) + local url = string.format("admin/services/%s", "shadowsocksr") + local args = { ... } + for i, v in ipairs(args) do + if v and v ~= "" then + url = url .. "/" .. v + end + end + return require "luci.dispatcher".build_url(url) +end + +-- 默认的ä¿å­˜å¹¶åº”用行为 +local function apply_redirect(m) + local tmp_uci_file = "/etc/config/" .. "shadowsocksr" .. "_redirect" + if m.redirect and m.redirect ~= "" then + if nixio.fs.access(tmp_uci_file) then + local redirect + for line in io.lines(tmp_uci_file) do + redirect = line:match("option%s+url%s+['\"]([^'\"]+)['\"]") + if redirect and redirect ~= "" then break end + end + if redirect and redirect ~= "" then + luci.sys.call("/bin/rm -f " .. tmp_uci_file) + luci.http.redirect(redirect) + end + else + nixio.fs.writefile(tmp_uci_file, "config redirect\n") + end + m.on_after_save = function(self) + local redirect = self.redirect + if redirect and redirect ~= "" then + m.uci:set("shadowsocksr" .. "_redirect", "@redirect[0]", "url", redirect) + end + end + else + luci.sys.call("/bin/rm -f " .. tmp_uci_file) + end +end + +local function set_apply_on_parse(map) + if not map then return end + if is_js_luci() then + apply_redirect(map) + local old = map.on_after_save + map.on_after_save = function(self) + if old then old(self) end + --map:set("@global[0]", "timestamp", os.time()) + end + end +end + +local has_ss_rust = is_finded("sslocal") or is_finded("ssserver") +local has_mihomo = is_finded("mihomo") +local has_xray = is_finded("xray") + +local server_table = {} +local encrypt_methods = { + -- ssr + "none", + "table", + "rc4", + "rc4-md5-6", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" +} + +local encrypt_methods_ss = { + -- plain + "none", + "plain", + -- aead + "aes-128-gcm", + "aes-192-gcm", + "aes-256-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + -- aead 2022 + "2022-blake3-aes-128-gcm", + "2022-blake3-aes-256-gcm", + "2022-blake3-chacha20-poly1305" + --[[ stream + "none", + "plain", + "table", + "rc4", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" ]]-- +} + +local protocol = { + -- ssr + "origin", + "verify_deflate", + "auth_sha1_v4", + "auth_aes128_sha1", + "auth_aes128_md5", + "auth_chain_a", + "auth_chain_b", + "auth_chain_c", + "auth_chain_d", + "auth_chain_e", + "auth_chain_f" +} + +local obfs = { + -- ssr + "plain", + "http_simple", + "http_post", + "random_head", + "tls1.2_ticket_auth" +} + +local securitys = { + -- vmess + "auto", + "none", + "zero", + "aes-128-gcm", + "chacha20-poly1305" +} + +local tls_flows = { + -- tls + "xtls-rprx-vision", + "xtls-rprx-vision-udp443", + "none" +} + +local function migrate_xray_protocol_nodes() + local changed = false + + uci:foreach("shadowsocksr", "servers", function(section) + local sid = section[".name"] + local stype = section.type + local proto = section.v2ray_protocol + local escaped_sid = luci.util.shellquote(sid) + + if stype == "ss" or stype == "ss-libev" then + if has_mihomo then + luci.sys.call(string.format("uci set shadowsocksr.%s.type='ss'", escaped_sid)) + changed = true + elseif has_ss_rust then + luci.sys.call(string.format("uci set shadowsocksr.%s.type='ss-rust'", escaped_sid)) + changed = true + elseif has_xray then + luci.sys.call(string.format("uci set shadowsocksr.%s.type='v2ray' && " .. "uci set shadowsocksr.%s.v2ray_protocol='shadowsocks'", escaped_sid, escaped_sid)) + changed = true + end + elseif stype == "v2ray" and proto == "shadowsocks" and has_mihomo then + luci.sys.call(string.format("uci set shadowsocksr.%s.type='ss' && " .. "uci delete shadowsocksr.%s.v2ray_protocol", escaped_sid, escaped_sid)) + changed = true + end + if stype == "hysteria2" then + luci.sys.call(string.format("uci set shadowsocksr.%s.type='v2ray' && " .. "uci set shadowsocksr.%s.v2ray_protocol='hysteria2'", escaped_sid, escaped_sid)) + changed = true + elseif stype == "trojan" then + luci.sys.call(string.format("uci set shadowsocksr.%s.type='v2ray' && " .. "uci set shadowsocksr.%s.v2ray_protocol='trojan'", escaped_sid, escaped_sid)) + changed = true + end + end) + local subscribe_sid = uci:get_first("shadowsocksr", "server_subscribe") + if subscribe_sid then + local old_options = {"xray_hy2_type", "xray_tj_type", "ss_type"} + local escaped_sub_sid = luci.util.shellquote(subscribe_sid) + for _, opt in ipairs(old_options) do + if uci:get("shadowsocksr", subscribe_sid, opt) then + luci.sys.call(string.format("uci delete shadowsocksr.%s.%s", escaped_sub_sid, opt)) + changed = true + end + end + end + if changed then + luci.sys.call("uci commit shadowsocksr") + end +end + +migrate_xray_protocol_nodes() + +m = Map("shadowsocksr", translate("Edit ShadowSocksR Server")) +m.redirect = url("servers") +if not sid or m.uci:get("shadowsocksr", sid) ~= "servers" then + luci.http.redirect(m.redirect) + return +end +-- ä¿å­˜&应用æˆåŠŸåŽè·³è½¬åˆ°èŠ‚ç‚¹åˆ—è¡¨ +set_apply_on_parse(m) +local old_after_save = m.on_after_save +m.on_after_save = function(self) + if old_after_save then old_after_save(self) end + local node_type = self.uci:get("shadowsocksr", sid, "type") + if node_type == "clash" then + luci.sys.call(string.format("/etc/init.d/shadowsocksr clash_cache %s >/dev/null 2>&1 &", sid)) + end +end + +-- [[ Servers Setting ]]-- +s = m:section(NamedSection, sid, "servers") +s.anonymous = true +s.addremove = false + +o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN/TUIC/HYSTERIA2 URL") +o.rawhtml = true +o.template = "shadowsocksr/ssrurl" +o.value = sid + +-- 新增一个选择框,用于选择 Xray 或 Trojan 核心 +o = s:option(ListValue, "type", translate("Server Node Type")) +if is_finded("xray") then + o:value("v2ray", translate("V2Ray/XRay")) +end +if is_finded("ssr-redir") then + o:value("ssr", translate("ShadowsocksR")) +end +if has_mihomo then + o:value("ss", translate("ShadowSocks")) +end +if has_ss_rust then + o:value("ss-rust", translate("ShadowSocks")) +end +if is_finded("naive") then + o:value("naiveproxy", translate("NaiveProxy")) +end +if is_finded("mihomo") then + o:value("clash", translate("Clash/Mihomo")) +end +if is_finded("mihomo") then + o:value("tuic", translate("TUIC")) +end +if is_finded("shadow-tls") and is_finded("sslocal") then + o:value("shadowtls", translate("Shadow-TLS")) +end +if is_finded("ipt2socks") then + o:value("socks5", translate("Socks5")) +end +local old_cfgvalue = o.cfgvalue +o.cfgvalue = function(self, section) + local val = self.map.uci:get("shadowsocksr", section, "type") + if old_cfgvalue then + return old_cfgvalue(self, section) + end + return val +end +o.description = translate("Using incorrect encryption mothod may causes service fail to start") + +o = s:option(Value, "alias", translate("Alias(optional)")) + +local function clash_source_formvalue(map, section, option) + local value = map:formvalue("cbid." .. map.config .. "." .. section .. "." .. option) + if value == nil then + value = map.uci:get(map.config, section, option) + end + return trim(value or "") +end + +local function validate_clash_source(self, value, section) + local clash_url = clash_source_formvalue(self.map, section, "clash_url") + local clash_path = clash_source_formvalue(self.map, section, "clash_path") + if clash_url == "" and clash_path == "" then + return nil, translate("Please specify either a Clash subscription URL or a local YAML path.") + end + return value +end + +o = s:option(Value, "clash_url", translate("Clash Subscription URL")) +o.placeholder = "https://example.com/config.yaml" +o.rmempty = true +o:depends("type", "clash") +o.validate = validate_clash_source + +o = s:option(Value, "clash_path", translate("Clash YAML Path")) +o.placeholder = "/etc/ssrplus/clash/custom.yaml" +o.rmempty = true +o:depends("type", "clash") +o.validate = validate_clash_source + +o = s:option(Value, "clash_user_agent", translate("Clash User-Agent")) +o.default = "clash" +o.rmempty = false +o:depends("type", "clash") + +o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol")) +o:value("vless", translate("VLESS")) +o:value("vmess", translate("VMess")) +o:value("trojan", translate("Trojan")) +o:value("shadowsocks", translate("ShadowSocks")) +if is_finded("xray") then + o:value("wireguard", translate("WireGuard")) +end +if is_finded("xray") then + o:value("hysteria2", translate("Hysteria2")) +end +o:value("socks", translate("Socks")) +o:value("http", translate("HTTP")) +o:depends("type", "v2ray") + +o = s:option(Value, "server", translate("Server Address")) +o.datatype = "or(host,ip6addr)" +o.rmempty = false +o:depends("type", "ssr") +o:depends("type", "ss") +o:depends("type", "ss-rust") +o:depends("type", "v2ray") +o:depends("type", "trojan") +o:depends("type", "naiveproxy") +o:depends("type", "hysteria2") +o:depends("type", "tuic") +o:depends("type", "shadowtls") +o:depends("type", "socks5") + +o = s:option(Value, "server_port", translate("Server Port")) +o.datatype = "port" +o.rmempty = true +o:depends("type", "ssr") +o:depends("type", "ss") +o:depends("type", "ss-rust") +o:depends("type", "v2ray") +o:depends("type", "trojan") +o:depends("type", "naiveproxy") +o:depends("type", "hysteria2") +o:depends("type", "tuic") +o:depends("type", "shadowtls") +o:depends("type", "socks5") + +o = s:option(Flag, "auth_enable", translate("Enable Authentication")) +o.rmempty = false +o.default = "0" +o:depends("type", "socks5") +o:depends({type = "v2ray", v2ray_protocol = "http"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) + +o = s:option(Value, "username", translate("Username")) +o.rmempty = true +o:depends("type", "naiveproxy") +o:depends({type = "socks5", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "socks", auth_enable = true}) + +o = s:option(Value, "password", translate("Password")) +o.password = true +o.rmempty = true +o:depends("type", "ssr") +o:depends("type", "ss") +o:depends("type", "ss-rust") +o:depends("type", "trojan") +o:depends("type", "naiveproxy") +o:depends("type", "shadowtls") +o:depends({type = "socks5", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", auth_enable = true}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) + +o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods) do + o:value(v) +end +o.rmempty = true +o:depends("type", "ssr") + +o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods_ss) do + if v == "none" then + o.default = "none" + o:value("none", translate("none")) + else + o:value(v, translate(v)) + end +end +o.rmempty = true +o:depends("type", "ss-rust") +o:depends("type", "ss") +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) + +o = s:option(Flag, "uot", translate("UDP over TCP")) +o.description = translate("Enable the SUoT protocol, requires server support.") +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o.default = "0" + +o = s:option(Flag, "ivCheck", translate("Bloom Filter")) +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o.default = "1" + +-- [[ Enable Shadowsocks Plugin ]]-- +o = s:option(Flag, "enable_plugin", translate("Enable Plugin")) +o.rmempty = true +o:depends("type", "ss") +o:depends("type", "ss-rust") +o.default = "0" + +-- Shadowsocks Plugin +o = s:option(ListValue, "plugin", translate("Obfs")) +o:value("none", translate("None")) +if has_mihomo or is_finded("obfs-local") then + o:value("obfs-local", translate("obfs-local")) +end +if has_mihomo or is_finded("v2ray-plugin") then + o:value("v2ray-plugin", translate("v2ray-plugin")) +end +if has_mihomo then + o:value("gost-plugin", translate("gost-plugin")) +end +if is_finded("xray-plugin") then + o:value("xray-plugin", translate("xray-plugin")) +end +if has_mihomo or is_finded("shadow-tls") then + o:value("shadow-tls", translate("shadow-tls")) +end +if has_mihomo then + o:value("restls", translate("restls")) + o:value("kcptun", translate("kcptun")) +end +o:value("custom", translate("Custom")) +o.rmempty = true +o:depends({enable_plugin = true}) + +o = s:option(Value, "custom_plugin", translate("Custom Plugin Path")) +o.placeholder = "/path/to/custom-plugin" +o:depends({plugin = "custom"}) + +o = s:option(Value, "plugin_opts", translate("Plugin Opts")) +o.rmempty = true +o:depends({enable_plugin = true}) + +o = s:option(ListValue, "protocol", translate("Protocol")) +for _, v in ipairs(protocol) do + o:value(v) +end +o.rmempty = true +o:depends("type", "ssr") + +o = s:option(Value, "protocol_param", translate("Protocol param (optional)")) +o:depends("type", "ssr") + +o = s:option(ListValue, "obfs", translate("Obfs")) +for _, v in ipairs(obfs) do + o:value(v) +end +o.rmempty = true +o:depends("type", "ssr") + +o = s:option(Value, "obfs_param", translate("Obfs param (optional)")) +o:depends("type", "ssr") + + +-- [[ Hysteria2 ]]-- +o = s:option(Value, "hy2_auth", translate("Users Authentication")) +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) +o.password = true +o.rmempty = false + +o = s:option(Flag, "flag_port_hopping", translate("Enable Port Hopping")) +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) +o.rmempty = true +o.default = "0" + +o = s:option(Value, "port_range", translate("Port hopping range")) +o.description = translate("Format as 10000:20000 or 10000-20000 Multiple groups are separated by commas (,).") +o:depends({type = "hysteria2", flag_port_hopping = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_port_hopping = true}) +o.datatype = "or(uinteger,portrange)" +o.rmempty = true + +o = s:option(Flag, "flag_transport", translate("Enable Transport Protocol Settings")) +o:depends("type", "hysteria2") +o.rmempty = true +o.default = "0" + +o = s:option(ListValue, "transport_protocol", translate("Transport Protocol")) +o:depends({type = "hysteria2", flag_transport = true}) +o:value("udp", translate("UDP")) +o.default = "udp" +o.rmempty = true + +o = s:option(Value, "hopinterval", translate("Port Hopping Interval(Unit:Second)")) +o.description = translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.") +o:depends({type = "hysteria2", flag_transport = true, flag_port_hopping = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_port_hopping = true}) +o.datatype = "or(uinteger,portrange)" +o.rmempty = true +o.default = "30" + +o = s:option(Flag, "flag_obfs", translate("Enable Obfuscation")) +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) +o.rmempty = true +o.default = "0" + +o = s:option(Flag, "lazy_mode", translate("Enable Lazy Mode")) +o:depends("type", "hysteria2") +o.rmempty = true +o.default = "0" + +o = s:option(Value, "obfs_type", translate("Obfuscation Type")) +o:depends({type = "hysteria2", flag_obfs = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_obfs = true}) +o.rmempty = true +o.placeholder = "salamander" + +o = s:option(Value, "salamander", translate("Obfuscation Password")) +o:depends({type = "hysteria2", flag_obfs = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_obfs = true}) +o.password = true +o.rmempty = true +o.placeholder = "cry_me_a_r1ver" + +o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters")) +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) +o.rmempty = true +o.default = "0" + +o = s:option(Flag, "disablepathmtudiscovery", translate("Disable QUIC path MTU discovery")) +o:depends({type = "hysteria2",flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.rmempty = true +o.default = false + +--[[Hysteria2 QUIC parameters setting]] +o = s:option(Value, "initstreamreceivewindow", translate("QUIC initStreamReceiveWindow")) +o:depends({type = "hysteria2", flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.datatype = "uinteger" +o.rmempty = true +o.default = "8388608" + +o = s:option(Value, "maxstreamreceivewindow", translate("QUIC maxStreamReceiveWindow")) +o:depends({type = "hysteria2", flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.datatype = "uinteger" +o.rmempty = true +o.default = "8388608" + +o = s:option(Value, "initconnreceivewindow", translate("QUIC initConnReceiveWindow")) +o:depends({type = "hysteria2", flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.datatype = "uinteger" +o.rmempty = true +o.default = "20971520" + +o = s:option(Value, "maxconnreceivewindow", translate("QUIC maxConnReceiveWindow")) +o:depends({type = "hysteria2", flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.datatype = "uinteger" +o.rmempty = true +o.default = "20971520" + +o = s:option(Value, "maxidletimeout", translate("QUIC maxIdleTimeout(Unit:second)")) +o:depends({type = "hysteria2", flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.rmempty = true +o.datatype = "uinteger" +o.default = "30" + +o = s:option(Value, "keepaliveperiod", translate("The keep-alive period.(Unit:second)")) +o.description = translate("Default value 0 indicatesno heartbeat.") +o:depends({type = "hysteria2", flag_quicparam = true}) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", flag_quicparam = true}) +o.rmempty = true +o.datatype = "uinteger" +o.default = "10" + + +--[[ Shadow-TLS Options ]] +o = s:option(ListValue, "shadowtls_protocol", translate("shadowTLS protocol Version")) +o:depends("type", "shadowtls") +o:value("v3", translate("Enable V3 protocol.")) +o:value("v2", translate("Enable V2 protocol.")) +o.default = "v3" +o.rmempty = true + +o = s:option(Flag, "strict", translate("TLS 1.3 Strict mode")) +o:depends("type", "shadowtls") +o.default = "1" +o.rmempty = false + +o = s:option(Flag, "fastopen", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support.")) +o:depends("type", "shadowtls") +o.default = "0" +o.rmempty = false + +o = s:option(Flag, "disable_nodelay", translate("Disable TCP No_delay")) +o:depends("type", "shadowtls") +o.default = "0" +o.rmempty = true + +o = s:option(Value, "shadowtls_sni", translate("shadow-TLS SNI")) +o:depends("type", "shadowtls") +o.datatype = "host" +o.rmempty = true +o.default = "" + +--[[ add a ListValue for Choose chain type,sslocal or vmess ]] +o = s:option(ListValue, "chain_type", translate("Shadow-TLS ChainPoxy type")) +o:depends("type", "shadowtls") +if is_finded("sslocal") then + o:value("sslocal", translate("ShadowSocks-rust Version")) +end +if is_finded("xray") then + o:value("vmess", translate("Vmess Protocol")) +end +o.default = "sslocal" +o.rmempty = false + +o = s:option(Value, "sslocal_password",translate("Shadowsocks password")) +o:depends({type = "shadowtls", chain_type = "sslocal"}) +o.rmempty = true + +o = s:option(ListValue, "sslocal_method", translate("Encrypt Method")) +o:depends({type = "shadowtls", chain_type = "sslocal"}) +for _, v in ipairs(encrypt_methods_ss) do + o:value(v) +end + +o = s:option(Value, "vmess_uuid", translate("Vmess UUID")) +o:depends({type = "shadowtls", chain_type = "vmess"}) +o.rmempty = false +o.default = uuid + +o = s:option(ListValue, "vmess_method", translate("Encrypt Method")) +o:depends({type = "shadowtls", chain_type = "vmess"}) +for _, v in ipairs(securitys) do + o:value(v, v:lower()) +end +o.rmempty = true +o.default="auto" + +-- [[ TUIC ]] +-- TuicNameId +o = s:option(Value, "tuic_uuid", translate("TUIC User UUID")) +o.password = true +o.rmempty = true +o.default = uuid +o:depends("type", "tuic") + +--Tuic IP +o = s:option(Value, "tuic_ip", translate("TUIC Server IP Address")) +o.rmempty = true +o.datatype = "ipaddr" +o.default = "" +o:depends("type", "tuic") + +-- Tuic Password +o = s:option(Value, "tuic_passwd", translate("TUIC User Password")) +o.password = true +o.rmempty = true +o.default = "" +o:depends("type", "tuic") + +o = s:option(ListValue, "udp_relay_mode", translate("UDP relay mode")) +o:depends("type", "tuic") +o:value("native", translate("native UDP characteristics")) +o:value("quic", translate("lossless UDP relay using QUIC streams")) +o.default = "native" +o.rmempty = true + +o = s:option(ListValue, "congestion_control", translate("Congestion control algorithm")) +o:depends("type", "tuic") +o:value("bbr", translate("BBR")) +o:value("cubic", translate("CUBIC")) +o:value("new_reno", translate("New Reno")) +o.default = "cubic" +o.rmempty = true + +o = s:option(Value, "heartbeat", translate("Heartbeat interval(second)")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = "3" +o.rmempty = true + +o = s:option(Value, "timeout", translate("Timeout for establishing a connection to server(second)")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = "8" +o.rmempty = true + +o = s:option(Value, "gc_interval", translate("Garbage collection interval(second)")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = "3" +o.rmempty = true + +o = s:option(Value, "gc_lifetime", translate("Garbage collection lifetime(second)")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = "15" +o.rmempty = true + +o = s:option(Value, "send_window", translate("TUIC send window")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = 20971520 +o.rmempty = true + +o = s:option(Value, "receive_window", translate("TUIC receive window")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = 10485760 +o.rmempty = true + +o = s:option(Flag, "disable_sni", translate("Disable SNI")) +o:depends("type", "tuic") +o.default = "0" +o.rmempty = true + +o = s:option(Flag, "zero_rtt_handshake", translate("Enable 0-RTT QUIC handshake")) +o:depends("type", "tuic") +o.default = "0" +o.rmempty = true + +-- Tuic settings for the local inbound socks5 server +o = s:option(Flag, "tuic_dual_stack", translate("Dual-stack Listening Socket")) +o.description = translate("If this option is not set, the socket behavior is platform dependent.") +o:depends("type", "tuic") +o.default = "0" +o.rmempty = true + +o = s:option(Value, "tuic_max_package_size", translate("Maximum packet size the socks5 server can receive from external")) +o:depends("type", "tuic") +o.datatype = "uinteger" +o.default = 1500 +o.rmempty = true + +-- AlterId +o = s:option(Value, "alter_id", translate("AlterId")) +o.datatype = "port" +o.default = 0 +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) + +-- VmessId +o = s:option(Value, "vmess_id", translate("Vmess/VLESS ID (UUID)")) +o.password = true +o.rmempty = true +o.default = uuid +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "vless"}) + +-- VLESS Encryption +o = s:option(Value, "vless_encryption", translate("VLESS Encryption")) +o.rmempty = true +o.default = "none" +o.placeholder = "none" +o:depends({type = "v2ray", v2ray_protocol = "vless"}) +o.validate = function(self, value) + value = value and value:match("^%s*(.-)%s*$") or value + return value ~= "" and value or "none" +end + +-- åŠ å¯†æ–¹å¼ +o = s:option(ListValue, "security", translate("Encrypt Method")) +for _, v in ipairs(securitys) do + o:value(v, v:upper()) +end +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) + +-- SOCKS Version +o = s:option(ListValue, "socks_ver", translate("Socks Version")) +o:value("4", "Socks4") +o:value("4a", "Socks4A") +o:value("5", "Socks5") +o.rmempty = true +o.default = "5" +o:depends({type = "v2ray", v2ray_protocol = "socks"}) + +-- 传输åè®® +o = s:option(ListValue, "transport", translate("Transport")) +o:value("raw", "RAW (TCP)") +o:value("kcp", "mKCP") +o:value("ws", "WebSocket") +o:value("httpupgrade", "HTTPUpgrade") +o:value("xhttp", "XHTTP (SplitHTTP)") +o:value("h2", "HTTP/2") +o:value("quic", "QUIC") +o:value("grpc", "gRPC") +o.rmempty = true +o:depends({type = "v2ray", v2ray_protocol = "vless"}) +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) +o:depends({type = "v2ray", v2ray_protocol = "http"}) + +-- [[ RAW部分 ]]-- +-- TCP伪装 +o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) +o:depends("transport", "raw") +o:value("none", translate("None")) +o:value("http", translate("HTTP")) +o.rmempty = true + +-- HTTP域å +o = s:option(Value, "http_host", translate("HTTP Host")) +o:depends("tcp_guise", "http") +o.rmempty = true + +-- HTTP路径 +o = s:option(Value, "http_path", translate("HTTP Path")) +o:depends("tcp_guise", "http") +o.rmempty = true + +-- [[ WS部分 ]]-- +-- WS域å +o = s:option(Value, "ws_host", translate("WebSocket Host")) +o:depends({transport = "ws", tls = false}) +o.datatype = "hostname" +o.rmempty = true + +-- WS路径 +o = s:option(Value, "ws_path", translate("WebSocket Path")) +o:depends("transport", "ws") +o.rmempty = true + +-- WSé—´éš” +o = s:option(Value, "ws_heartbeatPeriod", translate("HeartbeatPeriod(second)")) +o.datatype = "integer" +o:depends("transport", "ws") + +if is_finded("xray") then + -- WSå‰ç½®æ•°æ® + o = s:option(Value, "ws_ed", translate("Max Early Data")) + o:depends("ws_ed_enable", true) + o.datatype = "uinteger" + o:value("2048") + o.rmempty = true + + -- WSå‰ç½®æ•°æ®æ ‡å¤´ + o = s:option(Value, "ws_ed_header", translate("Early Data Header Name")) + o:depends("ws_ed_enable", true) + o:value("Sec-WebSocket-Protocol") + o.rmempty = true +end + +-- [[ httpupgrade部分 ]]-- + +-- httpupgrade域å +o = s:option(Value, "httpupgrade_host", translate("Httpupgrade Host")) +o:depends({transport = "httpupgrade", tls = false}) +o.rmempty = true + +-- httpupgrade路径 +o = s:option(Value, "httpupgrade_path", translate("Httpupgrade Path")) +o:depends("transport", "httpupgrade") +o.rmempty = true + +-- [[ XHTTP部分 ]]-- + +-- XHTTP æ¨¡å¼ +o = s:option(ListValue, "xhttp_mode", translate("XHTTP Mode")) +o:depends("transport", "xhttp") +o.default = "auto" +o:value("auto") +o:value("packet-up") +o:value("stream-up") +o:value("stream-one") + +-- XHTTP 主机 +o = s:option(Value, "xhttp_host", translate("XHTTP Host")) +o.datatype = "hostname" +o:depends("transport", "xhttp") +o.rmempty = true + +-- XHTTP 路径 +o = s:option(Value, "xhttp_path", translate("XHTTP Path")) +o.placeholder = "/" +o:depends("transport", "xhttp") +o.rmempty = true + +-- XHTTP 附加项 +o = s:option(Flag, "enable_xhttp_extra", translate("XHTTP Extra")) +o.description = translate("Enable this option to configure XHTTP Extra (JSON format).") +o.rmempty = true +o.default = "0" +o:depends("transport", "xhttp") + +o = s:option(TextValue, "xhttp_extra", " ") +o.description = translate( + "" .. translate("Configure XHTTP Extra Settings (JSON format), see:") .. "" .. + " " .. + "" .. translate("Click to the page") .. "") +o:depends("enable_xhttp_extra", true) +--o.rmempty = true +o.rows = 10 +o.wrap = "off" +o.cfgvalue = function(self, section, value) + local raw = m:get(section, "xhttp_extra") + if raw then + return base64Decode(raw) + end +end +o.write = function(self, section, value) + m:set(section, "xhttp_extra", base64Encode(value) or "") + local success, data = pcall(luci.jsonc.parse, value) + if success and data then + local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address) + or (data.downloadSettings and data.downloadSettings.address) + if address and address ~= "" then + address = address:gsub("^%[", ""):gsub("%]$", "") + m:set(section, "download_address", address) + else + m:del(section, "download_address") + end + else + m:del(section, "download_address") + end +end +o.validate = function(self, value) + value = trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + local ok, data = pcall(luci.jsonc.parse, value) + if ok and data then + return value + else + return nil, "XHTTP Extra " .. translate("Must be JSON text!") + end +end +o.remove = function(self, section, value) + m:del(section, "xhttp_extra") + m:del(section, "download_address") +end + +-- [[ H2部分 ]]-- + +-- H2域å +o = s:option(Value, "h2_host", translate("HTTP/2 Host")) +o:depends("transport", "h2") +o.rmempty = true + +-- H2路径 +o = s:option(Value, "h2_path", translate("HTTP/2 Path")) +o:depends("transport", "h2") +o.rmempty = true + +-- gRPC +o = s:option(Value, "serviceName", translate("gRPC Service Name")) +o:depends("transport", "grpc") +o.rmempty = true + +if is_finded("xray") then + -- gPRCæ¨¡å¼ + o = s:option(ListValue, "grpc_mode", translate("gRPC Mode")) + o:depends("transport", "grpc") + o:value("gun", translate("Gun")) + o:value("multi", translate("Multi")) + o.rmempty = true +end + +if is_finded("xray") then + -- gRPCåˆå§‹çª—å£ + o = s:option(Value, "initial_windows_size", translate("Initial Windows Size")) + o.datatype = "uinteger" + o:depends("transport", "grpc") + o.default = 0 + o.rmempty = true + + -- H2/gRPCå¥åº·æ£€æŸ¥ + o = s:option(Flag, "health_check", translate("H2/gRPC Health Check")) + o:depends("transport", "h2") + o:depends("transport", "grpc") + o.rmempty = true + + o = s:option(Value, "read_idle_timeout", translate("H2 Read Idle Timeout")) + o.datatype = "uinteger" + o:depends({health_check = true, transport = "h2"}) + o.default = 60 + o.rmempty = true + + o = s:option(Value, "idle_timeout", translate("gRPC Idle Timeout")) + o.datatype = "uinteger" + o:depends({health_check = true, transport = "grpc"}) + o.default = 60 + o.rmempty = true + + o = s:option(Value, "health_check_timeout", translate("Health Check Timeout")) + o.datatype = "uinteger" + o:depends("health_check", 1) + o.default = 20 + o.rmempty = true + + o = s:option(Flag, "permit_without_stream", translate("Permit Without Stream")) + o:depends({health_check = true, transport = "grpc"}) + o.rmempty = true +end + +-- [[ QUIC部分 ]]-- +o = s:option(ListValue, "quic_security", translate("QUIC Security")) +o:depends("transport", "quic") +o:value("none", translate("None")) +o:value("aes-128-gcm", translate("aes-128-gcm")) +o:value("chacha20-poly1305", translate("chacha20-poly1305")) +o.rmempty = true + +o = s:option(Value, "quic_key", translate("QUIC Key")) +o:depends("transport", "quic") +o.rmempty = true + +o = s:option(ListValue, "quic_guise", translate("Header")) +o:depends("transport", "quic") +o.rmempty = true +o:value("none", translate("None")) +o:value("srtp", translate("VideoCall (SRTP)")) +o:value("utp", translate("BitTorrent (uTP)")) +o:value("wechat-video", translate("WechatVideo")) +o:value("dtls", translate("DTLS 1.2")) +o:value("wireguard", translate("WireGuard")) + +-- [[ mKCP部分 ]]-- +o = s:option(ListValue, "kcp_guise", translate("Camouflage Type")) +o:depends("transport", "kcp") +o:value("none", translate("None")) +o:value("srtp", translate("VideoCall (SRTP)")) +o:value("utp", translate("BitTorrent (uTP)")) +o:value("wechat-video", translate("WechatVideo")) +o:value("dtls", translate("DTLS 1.2")) +o:value("wireguard", translate("WireGuard")) +o:value("dns", translate("DNS")) +o.rmempty = true + +o = s:option(Value, "kcp_domain", translate("Camouflage Domain")) +o.description = translate("Use it together with the DNS disguised type. You can fill in any domain.") +o:depends("kcp_guise", "dns") + +o = s:option(Value, "mtu", translate("MTU")) +o.datatype = "uinteger" +o:depends("transport", "kcp") +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.default = 1350 +o.rmempty = true + +o = s:option(Value, "uplink_capacity", translate("Uplink Capacity(Default:Mbps)")) +o.datatype = "uinteger" +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) +o.placeholder = 5 +o.rmempty = true + +o = s:option(Value, "downlink_capacity", translate("Downlink Capacity(Default:Mbps)")) +o.datatype = "uinteger" +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) +o.placeholder = 20 +o.rmempty = true + +o = s:option(Value, "seed", translate("Obfuscate password (optional)")) +o:depends("transport", "kcp") +o.rmempty = true + +-- [[ WireGuard 部分 ]]-- +o = s:option(Flag, "kernelmode", translate("Enabled Kernel virtual NIC TUN(optional)")) +o.description = translate( + "
    " .. + "
  • " .. translate("Linux kernel TUN virtual NIC requires system support and root privileges.") .. "
  • " .. + "
  • " .. translate("When enabled, it occupies IPv6 routing table 1023.") .. "
  • " .. + "
" +) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.default = "0" +o.rmempty = true + +o = s:option(DynamicList, "local_addresses", translate("Local addresses")) +o.datatype = "cidr" +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.rmempty = true + +o = s:option(DynamicList, "reserved", translate("Reserved bytes(optional)")) +o.description = translate("Decimal numbers separated by \",\" or Base64-encoded strings.") +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.rmempty = true + +o = s:option(Value, "private_key", translate("Private key")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.password = true +o.rmempty = true + +o = s:option(Value, "peer_pubkey", translate("Peer public key")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.rmempty = true + +o = s:option(Value, "preshared_key", translate("Pre-shared key")) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.password = true +o.rmempty = true + +o = s:option(DynamicList, "allowedips", translate("allowedIPs(optional)")) +o.description = translate("Wireguard allows only traffic from specific source IP.") +o.datatype = "cidr" +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o.default = "0.0.0.0/0" +o.rmempty = true + +-- [[ User-Agent部分 ]]-- +o = s:option(Value, "user_agent", translate("User-Agent")) +o.default = "" +o:value("", translate("Default")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", translate("chrome")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0", translate("firefox")) +o:value("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15", translate("safari")) +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70", translate("edge")) +o:value("Go-http-client/1.1", translate("golang")) +o:value("curl/7.68.0", translate("curl")) +o:depends("tcp_guise", "http") +o:depends("transport", "ws") +o:depends("transport", "httpupgrade") +o:depends("transport", "xhttp") +o:depends("transport", "grpc") + +--[[ FinalMask部分 ]]-- +o = s:option(Flag, "enable_finalmask", translate("FinalMask")) +o.rmempty = true +o.default = "0" +o:depends({type = "v2ray", v2ray_protocol = "vless"}) +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) + +o = s:option(TextValue, "finalmask", " ") +o.description = translate("An FinalMaskObject in JSON format, used for sharing.") .. "
" .. + translate("Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings.") +o:depends("enable_finalmask", true) +o.rows = 10 +o.wrap = "off" +o.custom_cfgvalue = function(self, section, value) + local raw = m:get(section, "finalmask") + if raw then + return base64Decode(raw) + end +end +o.custom_write = function(self, section, value) + m:set(section, "finalmask", base64Encode(value) or "") +end +o.validate = function(self, value) + value = trim(value):gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n") + if luci.jsonc.parse(value) then + return value + else + return nil, "FinalMask " .. translate("Must be JSON text!") + end +end + +-- [[ TLS ]]-- +o = s:option(Flag, "tls", translate("TLS")) +o.rmempty = true +o.default = "0" +o:depends({type = "v2ray", v2ray_protocol = "vless", reality = false}) +o:depends({type = "v2ray", v2ray_protocol = "vmess", reality = false}) +o:depends({type = "v2ray", v2ray_protocol = "trojan", reality = false}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks", reality = false}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2", reality = false}) +o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", reality = false}) +o:depends({type = "v2ray", v2ray_protocol = "http", reality = false}) +o:depends("type", "trojan") +o:depends("type", "hysteria2") + +-- [[ TLS部分 ]] -- +o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket")) +o:depends({type = "trojan", tls = true}) +o.default = "0" + +if is_finded("xray") then + -- [[ REALITY ]] + o = s:option(Flag, "reality", translate("REALITY")) + o.rmempty = true + o.default = "0" + o:depends({type = "v2ray", v2ray_protocol = "vless", tls = false}) + + o = s:option(Value, "reality_publickey", translate("Public key")) + o.rmempty = true + o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true}) + + o = s:option(Value, "reality_shortid", translate("Short ID")) + o.rmempty = true + o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true}) + + o = s:option(Value, "reality_spiderx", translate("spiderX")) + o.rmempty = true + o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true}) + + -- [[ XTLS ]]-- + o = s:option(ListValue, "tls_flow", translate("Flow")) + for _, v in ipairs(tls_flows) do + if v == "none" then + o.default = "none" + o:value("none", translate("none")) + else + o:value(v, translate(v)) + end + end + o.rmempty = true + o:depends({type = "v2ray", v2ray_protocol = "vless"}) + + -- [[ uTLS ]]-- + o = s:option(ListValue, "fingerprint", translate("Finger Print")) + o.default = "" + o:value("chrome", translate("chrome")) + o:value("firefox", translate("firefox")) + o:value("safari", translate("safari")) + o:value("ios", translate("ios")) + o:value("android", translate("android")) + o:value("edge", translate("edge")) + o:value("360", translate("360")) + o:value("qq", translate("qq")) + o:value("random", translate("random")) + o:value("randomized", translate("randomized")) + o:value("", translate("disable")) + o:depends({type = "v2ray", tls = true}) + o:depends({type = "v2ray", reality = true}) + + o = s:option(Flag, "enable_ech", translate("Enable ECH(optional)")) + o.rmempty = true + o.default = "0" + o:depends({type = "v2ray", tls = true}) + + o = s:option(TextValue, "ech_config", translate("ECH Config")) + o.description = translate( + "" .. translate("If it is not empty, it indicates that the Client has enabled Encrypted Client, see:") .. "" .. + " " .. + "" .. translate("Click to the page") .. "") + o:depends("enable_ech", true) + o.default = "" + o.rows = 5 + o.wrap = "soft" + o.validate = function(self, value) + -- 清ç†ç©ºè¡Œå’Œå¤šä½™æ¢è¡Œ + return (value:gsub("[\r\n]", "")):gsub("^%s*(.-)%s*$", "%1") + end + + o = s:option(ListValue, "ech_ForceQuery", translate("ECH Query Policy")) + o.description = translate("Controls the policy used when performing DNS queries for ECH configuration.") + o.default = "full" + o:value("none") + o:value("half") + o:value("full") + o:depends("enable_ech", true) + + o = s:option(Flag, "enable_mldsa65verify", translate("Enable ML-DSA-65(optional)")) + o.rmempty = true + o.default = "0" + o:depends({type = "v2ray", reality = true}) + + o = s:option(TextValue, "reality_mldsa65verify", translate("ML-DSA-65 Public key")) + o.description = translate( + "" .. translate("The client has not configured mldsa65Verify, but it will not perform the \"additional verification\" step and can still connect normally, see:") .. "" .. + " " .. + "" .. translate("Click to the page") .. "") + o:depends("enable_mldsa65verify", true) + o.default = "" + o.rows = 5 + o.wrap = "soft" + o.validate = function(self, value) + -- 清ç†ç©ºè¡Œå’Œå¤šä½™æ¢è¡Œ + return (value:gsub("[\r\n]", "")):gsub("^%s*(.-)%s*$", "%1") + end +end + +o = s:option(Value, "tls_host", translate("TLS Host")) +o.datatype = "hostname" +o:depends("tls", true) +o:depends("xtls", true) +o:depends("reality", true) +o.rmempty = true + +-- TLS ALPN +o = s:option(ListValue, "tls_alpn", translate("TLS ALPN")) +o.default = "" +o:value("", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:depends("tls", true) + +-- TUIC ALPN +o = s:option(ListValue, "tuic_alpn", translate("TUIC ALPN")) +o.default = "" +o:value("", translate("Default")) +o:value("h3") +o:value("h2") +o:value("h3,h2") +o:value("http/1.1") +o:value("h2,http/1.1") +o:value("h3,h2,http/1.1") +o:value("spdy/3.1") +o:value("h3,spdy/3.1") +o:depends("type", "tuic") + +-- IP STACK PREFERENCE +o = s:option(ListValue, "ipstack_prefer", translate("IP Stack Preference")) +o.default = "" +o:value("", translate("Default")) +o:value("v4first") +o:value("v6first") +o:depends("tuic_dual_stack", true) + +-- [[ allowInsecure ]]-- +o = s:option(Flag, "insecure", translate("allowInsecure")) +o.rmempty = false +o:depends("type", "hysteria2") +o:depends("type", "trojan") +o:depends("type", "tuic") +o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.") +-- Xray æ”¯æŒæ—¶é—´åˆ¤æ–­ +-- if os.time() < os.time({year=2026,month=6,day=1}) then +if os.date("%Y.%m.%d") < "2026.06.01" then + -- Xray 支æŒåˆ° 26.06.01 + o:depends("tls", true) + o:depends({ type = "v2ray", v2ray_protocol = "vless", reality = true }) +end + +if xray_version_val >= 260131 then + -- Xray 版本大于等于 26.1.31 + -- [[ Xray TLS pinSHA256 ]] -- + o = s:option(Value, "tls_CertSha", translate("TLS Chain Fingerprint (SHA256)"), translate("Once set, connects only when the server’s chain fingerprint matches.")) + o.rmempty = true + o:depends({type = "v2ray", tls = true}) + + -- [[ Xray TLS verify leaf certificate name ]] -- + o = s:option(Value, "tls_CertByName", translate("TLS Certificate Name (CertName)"), translate("TLS is used to verify the leaf certificate name.")) + o.rmempty = true + o:depends({type = "v2ray", tls = true}) +end + +-- [[ Hysteria2 TLS pinSHA256 ]] -- +o = s:option(Value, "pinsha256", translate("Certificate fingerprint")) +o:depends("type", "hysteria2") +o.rmempty = true + +-- [[ Mux.Cool ]] -- +o = s:option(Flag, "mux", translate("Mux"), translate("Enable Mux.Cool")) +o.rmempty = false +o.default = false +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw"}) +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "ws"}) +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "kcp"}) +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "httpupgrade"}) +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "h2"}) +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "quic"}) +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "grpc"}) +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) +o:depends({type = "v2ray", v2ray_protocol = "http"}) + +-- [[ TCP 最大并å‘连接数 ]]-- +o = s:option(Value, "concurrency", translate("concurrency")) +o.description = translate( + "
    " + .. "
  • " .. translate("Default: disable. When entering a negative number, such as -1, The Mux module will not be used to carry TCP traffic.") .. "
  • " + .. "
  • " .. translate("Min value is 1, Max value is 128. When omitted or set to 0, it equals 8.") .. "
  • " + .. "
") +o.rmempty = true +o.default = "-1" +o:value("-1", translate("disable")) +o:value("8", translate("8")) +o:depends("mux", true) + +-- [[ UDP 最大并å‘连接数 ]]-- +o = s:option(Value, "xudpConcurrency", translate("xudpConcurrency")) +o.description = translate( + "
    " + .. "
  • " .. translate("Default:16. When entering a negative number, such as -1, The Mux module will not be used to carry UDP traffic, Use original UDP transmission method of proxy protocol.") .. "
  • " + .. "
  • " .. translate("Min value is 1, Max value is 1024. When omitted or set to 0, Will same path as TCP traffic.") .. "
  • " + .. "
") +o.rmempty = true +o.default = "16" +o:value("-1", translate("disable")) +o:value("16", translate("16")) +o:depends("mux", true) + +-- [[ 对被代ç†çš„ UDP/443 æµé‡å¤„ç†æ–¹å¼ ]]-- +o = s:option(ListValue, "xudpProxyUDP443", translate("xudpProxyUDP443")) +o.description = translate( + "
    " + .. "
  • " .. translate("Default reject rejects traffic.") .. "
  • " + .. "
  • " .. translate("allow: Allows use Mux connection.") .. "
  • " + .. "
  • " .. translate("skip: Not use Mux module to carry UDP 443 traffic, Use original UDP transmission method of proxy protocol.") .. "
  • " + .. "
") +o.rmempty = true +o.default = "reject" +o:value("reject", translate("reject")) +o:value("allow", translate("allow")) +o:value("skip", translate("skip")) +o:depends("mux", true) + +-- [[ XHTTP TCP Fast Open ]]-- +--o = s:option(Flag, "tcpfastopen", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support.")) +--o.rmempty = true +--o.default = "0" +--o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"}) + +-- [[ MPTCP ]]-- +o = s:option(Flag, "mptcp", translate("MPTCP"), translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) +o.rmempty = true +o.default = "0" +o:depends({type = "v2ray", v2ray_protocol = "vless"}) +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) +o:depends({type = "v2ray", v2ray_protocol = "http"}) + +-- [[ TESTPRE ]]-- +o = s:option(Value, "preconns", translate("Pre-connections"), translate("Number of early established connections to reduce latency.")) +o.datatype = "uinteger" +o.placeholder = 0 +o:depends({type = "v2ray", v2ray_protocol = "vless"}) + +-- [[ custom_tcpcongestion 连接æœåŠ¡å™¨èŠ‚ç‚¹çš„ TCP 拥塞控制算法 ]]-- +o = s:option(ListValue, "custom_tcpcongestion", translate("custom_tcpcongestion")) +o.rmempty = true +o.default = "" +o:value("", translate("comment_tcpcongestion_disable")) +o:value("bbr", translate("BBR")) +o:value("brutal", translate("BRUTAL")) +o:value("cubic", translate("CUBIC")) +o:value("reno", translate("Reno")) +o:depends({type = "v2ray", v2ray_protocol = "vless"}) +o:depends({type = "v2ray", v2ray_protocol = "vmess"}) +o:depends({type = "v2ray", v2ray_protocol = "trojan"}) +o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) +o:depends({type = "v2ray", v2ray_protocol = "socks"}) +o:depends({type = "v2ray", v2ray_protocol = "http"}) + +-- [[ HYSTERIA2_tcpcongestion 连接æœåŠ¡å™¨èŠ‚ç‚¹çš„ TCP 拥塞控制算法 ]]-- +o = s:option(ListValue, "hy2_tcpcongestion", translate("custom_tcpcongestion")) +o.rmempty = true +o.default = "" +o:value("", translate("comment_tcpcongestion_disable")) +o:value("bbr", translate("BBR")) +o:value("brutal", translate("BRUTAL")) +o:value("force-brutal", translate("FORCE BRUTAL")) +o:value("reno", translate("Reno")) +o:value("cubic", translate("CUBIC")) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) + +-- [[ Cert ]]-- +o = s:option(Flag, "certificate", translate("Self-signed Certificate")) +o.rmempty = true +o.default = "0" +o:depends("type", "tuic") +o:depends({type = "hysteria2", insecure = false}) +o:depends({type = "trojan", tls = true, insecure = false}) +o:depends({type = "v2ray", v2ray_protocol = "vmess", tls = true, insecure = false}) +o:depends({type = "v2ray", v2ray_protocol = "vless", tls = true, insecure = false}) +o.description = translate("If you have a self-signed certificate,please check the box") + +o = s:option(DummyValue, "upload", translate("Upload")) +o.template = "shadowsocksr/certupload" +o:depends("certificate", 1) + +cert_dir = "/etc/ssl/private/" +local path + +luci.http.setfilehandler(function(meta, chunk, eof) + if not fd then + if (not meta) or (not meta.name) or (not meta.file) then + return + end + fd = nixio.open(cert_dir .. meta.file, "w") + if not fd then + path = translate("Create upload file error.") + return + end + end + if chunk and fd then + fd:write(chunk) + end + if eof and fd then + fd:close() + fd = nil + path = '/etc/ssl/private/' .. meta.file .. '' + end +end) +if luci.http.formvalue("upload") then + local f = luci.http.formvalue("ulfile") + if #f <= 0 then + path = translate("No specify upload file.") + end +end + +o = s:option(Value, "certpath", translate("Current Certificate Path")) +o:depends("certificate", 1) +o:value("/etc/ssl/private/ca.crt") +o.description = translate("Please confirm the current certificate path") +o.default = "/etc/ssl/private/ca.crt" + +o = s:option(Flag, "fast_open", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support.")) +o.rmempty = true +o.default = "0" +o:depends("type", "ssr") +o:depends("type", "ss") +o:depends("type", "ss-rust") +o:depends("type", "trojan") +o:depends("type", "hysteria2") +o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"}) +o:depends({type = "v2ray", v2ray_protocol = "hysteria2"}) + +o = s:option(Flag, "switch_enable", translate("Enable Auto Switch")) +o.rmempty = false +o.default = "1" + +if is_finded("kcptun-client") then + o = s:option(Flag, "kcp_enable", translate("KcpTun Enable")) + o.rmempty = true + o.default = "0" + o:depends("type", "ssr") + o:depends("type", "ss-rust") + o:depends("type", "ss") + + o = s:option(Value, "kcp_port", translate("KcpTun Port")) + o.datatype = "portrange" + o.default = 4000 + o:depends("type", "ssr") + o:depends("type", "ss-rust") + o:depends("type", "ss") + + o = s:option(Value, "kcp_password", translate("KcpTun Password")) + o.password = true + o:depends("type", "ssr") + o:depends("type", "ss-rust") + o:depends("type", "ss") + + o = s:option(Value, "kcp_param", translate("KcpTun Param")) + o.default = "--nocomp" + o:depends("type", "ssr") + o:depends("type", "ss-rust") + o:depends("type", "ss") +end + +return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua new file mode 100644 index 00000000..ff45ac70 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua @@ -0,0 +1,234 @@ +-- Copyright (C) 2017 yushi studio github.com/ywb94 +-- Copyright (C) 2018 lean github.com/coolsnowwolf +-- Licensed to the public under the GNU General Public License v3. + +local m, s, sec, o +local uci = require "luci.model.uci".cursor() +local URL = require "url" + +-- èŽ·å– LAN IP åœ°å€ +function lanip() + local lan_ip + + -- å°è¯•从 UCI ç›´æŽ¥è¯»å– + lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F'/' '{print $1}' | tr -d '\\n'") + + -- å°è¯•从 LAN 接å£ä¿¡æ¯ä¸­è¯»å–(优先 ifnameï¼Œå† fallback 到 device) + if not lan_ip or lan_ip == "" then + lan_ip = luci.sys.exec([[ +ip -4 addr show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) 2>/dev/null \ + | grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']]) + end + + -- å–ä»»æ„一个 global IPv4 åœ°å€ + if not lan_ip or lan_ip == "" then + lan_ip = luci.sys.exec([[ +ip -4 addr show scope global 2>/dev/null \ + | grep -w 'inet' | awk '{print $2}' | cut -d'/' -f1 | grep -v '^127\.' | head -n1 | tr -d '\n']]) + end + + return lan_ip +end + +local lan_ip = lanip() +local validation = require "luci.cbi.datatypes" +local clash_nodes = {} +local function is_finded(e) + return luci.sys.exec(string.format('type -t -p "%s" -p "/usr/libexec/%s" 2>/dev/null', e, e)) ~= "" +end + +local function clash_display_name(s) + if s.type ~= "clash" or not s.clash_url or s.clash_url == "" then + return nil + end + local ok, parsed = pcall(URL.parse, s.clash_url) + if ok and parsed and parsed.host then + return "[CLASH]:" .. parsed.host + end + return "[CLASH]" +end + +m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"), translate("

Support SS/SSR/V2RAY/XRAY/TROJAN/TUIC/HYSTERIA2/NAIVEPROXY/SOCKS5/CLASH etc.

")) +m:section(SimpleSection).template = "shadowsocksr/status" + +local server_table = {} +local server_order = {} +uci:foreach("shadowsocksr", "servers", function(s) + if s.type == "clash" then + clash_nodes[s[".name"]] = true + end + + if s.type ~= "tun" and s.alias then + server_table[s[".name"]] = "[%s]:%s" % {string.upper(s.v2ray_protocol or s.type), s.alias} + elseif s.type ~= "tun" and s.server and s.server_port then + server_table[s[".name"]] = "[%s]:%s:%s" % {string.upper(s.v2ray_protocol or s.type), s.server, s.server_port} + elseif s.type ~= "tun" then + local display_name = clash_display_name(s) + if display_name then + server_table[s[".name"]] = display_name + end + end + if s.type ~= "tun" and server_table[s[".name"]] then + table.insert(server_order, s[".name"]) + end +end) + +-- [[ Global Setting ]]-- +s = m:section(TypedSection, "global") +s.anonymous = true + +o = s:option(ListValue, "global_server", translate("Main Server")) +o:value("nil", translate("Disable")) +for _, key in ipairs(server_order) do + o:value(key, server_table[key]) +end +o.default = "nil" +o.rmempty = false + +o = s:option(DummyValue, "_clash_panel", translate("Clash Panel")) +o.template = "shadowsocksr/clash_main_panel" +o.clash_nodes = clash_nodes + +o = s:option(ListValue, "threads", translate("Multi Threads Option")) +o:value("0", translate("Auto Threads")) +o:value("1", translate("1 Thread")) +o:value("2", translate("2 Threads")) +o:value("4", translate("4 Threads")) +o:value("8", translate("8 Threads")) +o:value("16", translate("16 Threads")) +o:value("32", translate("32 Threads")) +o:value("64", translate("64 Threads")) +o:value("128", translate("128 Threads")) +o.default = "0" +o.rmempty = false + +o = s:option(ListValue, "run_mode", translate("Running Mode")) +o:value("gfw", translate("GFW List Mode")) +o:value("router", translate("IP Route Mode")) +o:value("all", translate("Global Mode")) +o.default = gfw + +o = s:option(ListValue, "dports", translate("Proxy Ports")) +o:value("1", translate("All Ports")) +o:value("2", translate("Only Common Ports")) +o:value("3", translate("Custom Ports")) +cp = s:option(Value, "custom_ports", translate("Enter Custom Ports")) +cp:depends("dports", "3") -- 仅当用户选择“Custom Portsâ€æ—¶æ˜¾ç¤º +cp.placeholder = "e.g., 80,443,8080" +o.default = 1 + +o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode")) +if is_finded("dns2tcp") then + o:value("1", translate("Use DNS2TCP query")) +end +if is_finded("mosdns") then + o:value("4", translate("Use MosDNS query")) +end +if is_finded("chinadns-ng") then + o:value("6", translate("Use ChinaDNS-NG query and cache")) +end +o:value("7", translate("Prefer module built-in DNS")) +o:value("0", translate("Use Local DNS Service listen port 5335")) +o.default = 1 + +o = s:option(Value, "tunnel_forward", translate("Anti-pollution DNS Server")) +o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)")) +o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)")) +o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)")) +o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)")) +o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)")) +o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)")) +o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)")) +o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)")) +o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)")) +o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)")) +o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)")) +o:depends("pdnsd_enable", "1") +o:depends("pdnsd_enable", "7") +o.description = translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)") +o.datatype = "ip4addrport" +o.default = "8.8.4.4:53" + +o = s:option(Value, "tunnel_forward_mosdns", translate("Anti-pollution DNS Server")) +o:value("tcp://8.8.4.4:53,tcp://8.8.8.8:53", translate("Google Public DNS")) +o:value("tcp://208.67.222.222:53,tcp://208.67.220.220:53", translate("OpenDNS")) +o:value("tcp://209.244.0.3:53,tcp://209.244.0.4:53", translate("Level 3 Public DNS-1 (209.244.0.3-4)")) +o:value("tcp://4.2.2.1:53,tcp://4.2.2.2:53", translate("Level 3 Public DNS-2 (4.2.2.1-2)")) +o:value("tcp://4.2.2.3:53,tcp://4.2.2.4:53", translate("Level 3 Public DNS-3 (4.2.2.3-4)")) +o:value("tcp://1.1.1.1:53,tcp://1.0.0.1:53", translate("Cloudflare DNS")) +o:depends("pdnsd_enable", "4") +o.description = translate("Custom DNS Server format as tcp://IP:PORT or tls://DOMAIN:PORT (tcp://8.8.8.8 or tls://dns.google:853)") +o.default = "tcp://8.8.4.4:53,tcp://8.8.8.8:53" + +o = s:option(Flag, "filter_aaaa", translate("Disable IPv6 for Overseas FQDN")) +o:depends("pdnsd_enable", "1") +o:depends("pdnsd_enable", "4") +o:depends("pdnsd_enable", "7") +o.rmempty = false +o.default = "1" + +if is_finded("chinadns-ng") then + o = s:option(Value, "chinadns_ng_tunnel_forward", translate("Anti-pollution DNS Server")) + o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)")) + o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)")) + o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)")) + o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)")) + o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)")) + o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)")) + o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)")) + o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)")) + o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)")) + o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)")) + o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)")) + o:depends("pdnsd_enable", "6") + o.default = "8.8.4.4:53" + o.description = translate( + "
    " .. + "
  • " .. translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)") .. "
  • " .. + "
  • " .. translate("Muitiple DNS server can saperate with ','") .. "
  • " .. + "
" + ) + + o = s:option(ListValue, "chinadns_ng_proto", translate("ChinaDNS-NG query protocol")) + o:value("none", translate("UDP/TCP upstream")) + o:value("tcp", translate("TCP upstream")) + o:value("udp", translate("UDP upstream")) + o:value("tls", translate("DoT upstream (Need use wolfssl version)")) + o:depends("pdnsd_enable", "6") + + o = s:option(Value, "chinadns_forward", translate("Domestic DNS Server")) + o:value("", translate("Disable ChinaDNS-NG")) + o:value("wan", translate("Use DNS from WAN")) + o:value("wan_114", translate("Use DNS from WAN and 114DNS")) + o:value("114.114.114.114:53", translate("Nanjing Xinfeng 114DNS (114.114.114.114)")) + o:value("119.29.29.29:53", translate("DNSPod Public DNS (119.29.29.29)")) + o:value("223.5.5.5:53", translate("AliYun Public DNS (223.5.5.5)")) + o:value("180.76.76.76:53", translate("Baidu Public DNS (180.76.76.76)")) + o:value("101.226.4.6:53", translate("360 Security DNS (China Telecom) (101.226.4.6)")) + o:value("123.125.81.6:53", translate("360 Security DNS (China Unicom) (123.125.81.6)")) + o:value("1.2.4.8:53", translate("CNNIC SDNS (1.2.4.8)")) + o:depends({pdnsd_enable = "6", run_mode = "router"}) + o.default = "wan" + o.description = translate("Custom DNS Server format as IP:PORT (default: disabled)") + o.validate = function(self, value, section) + if (section and value) then + if value == "wan" or value == "wan_114" then + return value + end + + if validation.ip4addrport(value) then + return value + end + + return nil, translate("Expecting: %s"):format(translate("valid address:port")) + end + + return value + end +end + +local dns_defaults_section = m:section(SimpleSection) +dns_defaults_section.template = "shadowsocksr/client_dns_defaults" + +m:section(SimpleSection).template = "shadowsocksr/status_bottom" +return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua new file mode 100644 index 00000000..8d670cd7 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua @@ -0,0 +1,30 @@ +local m, s, o + +m = SimpleForm( + "component_update", + translate("Component Update"), + translate("Check installed component versions and upgrade them online from the upstream release page.") +) +m.reset = false +m.submit = false + +s = m:section(SimpleSection) + +o = m:field(ListValue, "component_mirror", translate("Mirror URL")) +o:value("direct", translate("GitHub Direct")) +o:value("ghproxy", "mirror.ghproxy.com") +o:value("ghproxy_cc", "ghproxy.cc") +o:value("ghfast", "ghfast.top") +o:value("jsdelivr", "cdn.jsdelivr.net") +o.rmempty = false +o.cfgvalue = function(self) + return m.uci:get_first("shadowsocksr", "global", "component_mirror") or "direct" +end +o.write = function(self, section, value) + m.uci:set("shadowsocksr", "@global[0]", "component_mirror", value) + m.uci:commit("shadowsocksr") +end + +s.template = "shadowsocksr/component" + +return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua new file mode 100644 index 00000000..0d92887f --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua @@ -0,0 +1,137 @@ +require "luci.ip" +require "nixio.fs" +require "luci.sys" +local m, s, o + +m = Map("shadowsocksr") + +s = m:section(TypedSection, "access_control") +s.anonymous = true + +-- Interface control +s:tab("Interface", translate("Interface control")) +o = s:taboption("Interface", DynamicList, "Interface", translate("Interface")) +o.template = "cbi/network_netlist" +o.widget = "checkbox" +o.nocreate = true +o.unspecified = true +o.description = translate("Listen only on the given interface or, if unspecified, on all") + +-- Part of WAN +s:tab("wan_ac", translate("WAN IP AC")) + +o = s:taboption("wan_ac", DynamicList, "wan_bp_ips", translate("WAN White List IP")) +o.datatype = "ip4addr" + +o = s:taboption("wan_ac", DynamicList, "wan_fw_ips", translate("WAN Force Proxy IP")) +o.datatype = "ip4addr" + +-- Part of LAN +s:tab("lan_ac", translate("LAN IP AC")) + +o = s:taboption("lan_ac", ListValue, "lan_ac_mode", translate("LAN Access Control")) +o:value("0", translate("Disable")) +o:value("w", translate("Allow listed only")) +o:value("b", translate("Allow all except listed")) +o.rmempty = false + +o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({family = 4}, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) +o:depends("lan_ac_mode", "w") +o:depends("lan_ac_mode", "b") + +o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({family = 4}, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) + +o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({family = 4}, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) + +o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List")) +o.datatype = "ipaddr" +luci.ip.neighbors({family = 4}, function(entry) + if entry.reachable then + o:value(entry.dest:string()) + end +end) + +-- Part of Self +-- s:tab("self_ac", translate("Router Self AC")) +-- o = s:taboption("self_ac",ListValue, "router_proxy", translate("Router Self Proxy")) +-- o:value("1", translatef("Normal Proxy")) +-- o:value("0", translatef("Bypassed Proxy")) +-- o:value("2", translatef("Forwarded Proxy")) +-- o.rmempty = false + +s:tab("esc", translate("Bypass Domain List")) +local escconf = "/etc/ssrplus/white.list" +o = s:taboption("esc", TextValue, "escconf") +o.rows = 13 +o.wrap = "off" +o.rmempty = true +o.cfgvalue = function(self, section) + return nixio.fs.readfile(escconf) or "" +end +o.write = function(self, section, value) + nixio.fs.writefile(escconf, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + nixio.fs.writefile(escconf, "") +end + +s:tab("block", translate("Black Domain List")) +local blockconf = "/etc/ssrplus/black.list" +o = s:taboption("block", TextValue, "blockconf") +o.rows = 13 +o.wrap = "off" +o.rmempty = true +o.cfgvalue = function(self, section) + return nixio.fs.readfile(blockconf) or " " +end +o.write = function(self, section, value) + nixio.fs.writefile(blockconf, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + nixio.fs.writefile(blockconf, "") +end + +s:tab("denydomain", translate("Deny Domain List")) +local denydomainconf = "/etc/ssrplus/deny.list" +o = s:taboption("denydomain", TextValue, "denydomainconf") +o.rows = 13 +o.wrap = "off" +o.rmempty = true +o.cfgvalue = function(self, section) + return nixio.fs.readfile(denydomainconf) or " " +end +o.write = function(self, section, value) + nixio.fs.writefile(denydomainconf, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + nixio.fs.writefile(denydomainconf, "") +end + +if luci.sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 then + m.apply_on_parse = true + function m.on_apply(self) + luci.sys.call("/etc/init.d/shadowsocksr reload > /dev/null 2>&1 &") + end +end + +m:append(Template("shadowsocksr/control_layout")) + +return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua new file mode 100644 index 00000000..6aa8328b --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua @@ -0,0 +1,104 @@ +require "luci.util" +require "nixio.fs" +require "luci.sys" +require "luci.http" + +f = SimpleForm("logview") +f.reset = false +f.submit = false +f:append(Template("shadowsocksr/log")) + +-- 自定义 log 函数 +function log(...) + local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") + local f, err = io.open("/var/log/ssrplus.log", "a") + if f and err == nil then + f:write(result .. "\n") + f:close() + end +end + +-- 创建备份与æ¢å¤è¡¨å• +fb = SimpleForm('backup-restore') +fb.reset = false +fb.submit = false +s = fb:section(SimpleSection, translate("Backup and Restore"), translate("Backup or Restore Client and Server Configurations.") .. + "
" .. + translate("Note: Restoring configurations across different versions may cause compatibility issues.") .. + "") +s.anonymous = true +s:append(Template("shadowsocksr/backup_restore")) + +-- 定义备份目标文件和目录 +local backup_targets = { + files = { + "/etc/config/shadowsocksr" + }, + dirs = { + "/etc/ssrplus" + } +} + +local file_path = '/tmp/shadowsocksr_upload.tar.gz' +local temp_dir = '/tmp/shadowsocksr_bak' +local fd + +-- å¤„ç†æ–‡ä»¶ä¸Šä¼  +luci.http.setfilehandler(function(meta, chunk, eof) + if not fd and meta and meta.name == "ulfile" and chunk then + -- åˆå§‹åŒ–ä¸Šä¼ å¤„ç† + luci.sys.call("rm -rf " .. temp_dir) + nixio.fs.remove(file_path) + fd = nixio.open(file_path, "w") + luci.sys.call("ls /tmp/sub_md5_* >/dev/null 2>&1 && rm -f /tmp/sub_md5_*") + luci.sys.call("echo '' > /var/log/ssrplus.log") + end + + if fd and chunk then + fd:write(chunk) + end + + if eof and fd then + fd:close() + fd = nil + if nixio.fs.access(file_path) then + log(" * shadowsocksr é…置文件上传æˆåŠŸâ€¦") -- 使用自定义的 log 函数 + luci.sys.call("mkdir -p " .. temp_dir) + + if luci.sys.call("tar -xzf " .. file_path .. " -C " .. temp_dir) == 0 then + -- å¤„ç†æ–‡ä»¶è¿˜åŽŸ + for _, target in ipairs(backup_targets.files) do + local temp_file = temp_dir .. target + if nixio.fs.access(temp_file) then + luci.sys.call(string.format("cp -f '%s' '%s'", temp_file, target)) + log(" * 文件 " .. target .. " 还原æˆåŠŸâ€¦") -- 使用自定义的 log 函数 + end + end + + -- 处ç†ç›®å½•还原 + for _, target in ipairs(backup_targets.dirs) do + local temp_dir_path = temp_dir .. target + if nixio.fs.access(temp_dir_path) then + luci.sys.call(string.format("cp -rf '%s'/* '%s/'", temp_dir_path, target)) + log(" * 目录 " .. target .. " 还原æˆåŠŸâ€¦") -- 使用自定义的 log 函数 + end + end + + log(" * shadowsocksr é…置还原æˆåŠŸâ€¦") -- 使用自定义的 log 函数 + log(" * é‡å¯ shadowsocksr æœåŠ¡ä¸­â€¦\n") -- 使用自定义的 log 函数 + luci.sys.call('/etc/init.d/shadowsocksr restart > /dev/null 2>&1 &') + else + log(" * shadowsocksr é…置文件解压失败,请é‡è¯•ï¼") -- 使用自定义的 log 函数 + end + else + log(" * shadowsocksr é…置文件上传失败,请é‡è¯•ï¼") -- 使用自定义的 log 函数 + end + + -- 清ç†ä¸´æ—¶æ–‡ä»¶ + luci.sys.call("rm -rf " .. temp_dir) + nixio.fs.remove(file_path) + luci.sys.call("ls /tmp/sub_md5_* >/dev/null 2>&1 && rm -f /tmp/sub_md5_*") + end +end) + +return f, fb diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua new file mode 100644 index 00000000..2fdf777d --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua @@ -0,0 +1,396 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. +require "luci.http" +require "luci.dispatcher" +require "nixio.fs" + +local m, s, o +local sid = arg[1] + +-- ¼ÓÃÜ·½Ê½£¨SS/SSRÓã© +local encrypt_methods = { + "rc4-md5", "rc4-md5-6", "rc4", "table", + "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", + "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", + "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb", + "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb", "seed-cfb", + "salsa20", "chacha20", "chacha20-ietf" +} + +local encrypt_methods_ss = { + "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", + "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", + "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" +} + +-- Shadowsocks ¼ÓÃÜ·½·¨£¨Xray °æ£© +local v_ss_encrypt_method_list = { + "aes-128-cfb", "aes-256-cfb", "aes-128-gcm", "aes-256-gcm", + "chacha20", "chacha20-ietf", "chacha20-poly1305", "chacha20-ietf-poly1305" +} + +-- αװÀàÐÍ£¨ÓÃÓÚ mKCP/QUIC£© +local header_type_list = { + "none", "srtp", "utp", "wechat-video", "dtls", "wireguard" +} + +local protocol = {"origin"} +obfs = {"plain", "http_simple", "http_post"} + +m = Map("shadowsocksr", translate("Edit ShadowSocksR Server")) +m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server") + +if m.uci:get("shadowsocksr", sid) ~= "server_config" then + luci.http.redirect(m.redirect) + return +end + +-- [[ Server Setting ]]-- +s = m:section(NamedSection, sid, "server_config") +s.anonymous = true +s.addremove = false + +-- ========== »ù±¾ÉèÖà ========== +o = s:option(Flag, "enable", translate("Enable")) +o.default = 1 +o.rmempty = false + +o = s:option(ListValue, "type", translate("Server Type")) +o:value("socks5", translate("Socks5")) +if nixio.fs.access("/usr/bin/mihomo") or nixio.fs.access("/usr/libexec/mihomo") or nixio.fs.access("/usr/bin/ssserver") or nixio.fs.access("/usr/libexec/ssserver") then + o:value("ss", translate("ShadowSocks")) +end +if nixio.fs.access("/usr/bin/ssr-server") then + o:value("ssr", translate("ShadowsocksR")) +end +-- Xray ЭÒéÖ§³Ö +if nixio.fs.access("/usr/bin/xray") or nixio.fs.access("/usr/libexec/xray") then + o:value("vmess", "VMess (Xray)") + o:value("vless", "VLESS (Xray)") + o:value("trojan", "Trojan (Xray)") + o:value("shadowsocks", "Shadowsocks (Xray)") +end +o.default = "socks5" + +o = s:option(Value, "server_port", translate("Server Port")) +o.datatype = "port" +math.randomseed(tostring(os.time()):reverse():sub(1, 7)) +o.default = math.random(10240, 20480) +o.rmempty = false +o.description = translate("warning! Please do not reuse the port!") + +o = s:option(Value, "timeout", translate("Connection Timeout")) +o.datatype = "uinteger" +o.default = 60 +o.rmempty = false +o:depends("type", "ss") +o:depends("type", "ssr") + +o = s:option(Value, "username", translate("Username")) +o.rmempty = false +o:depends("type", "socks5") + +o = s:option(Value, "password", translate("Password")) +o.password = true +o.rmempty = false +o:depends("type", "socks5") +o:depends("type", "ss") +o:depends("type", "ssr") +o:depends("type", "trojan") +o:depends("type", "shadowsocks") + +-- ========== SS/SSR ЭÒéÌØÓÐ ========== +o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods) do o:value(v) end +o.rmempty = false +o:depends("type", "ssr") + +o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method")) +for _, v in ipairs(encrypt_methods_ss) do o:value(v) end +o.rmempty = false +o:depends("type", "ss") + +o = s:option(ListValue, "protocol", translate("Protocol")) +for _, v in ipairs(protocol) do o:value(v) end +o.rmempty = false +o:depends("type", "ssr") + +o = s:option(ListValue, "obfs", translate("Obfs")) +for _, v in ipairs(obfs) do o:value(v) end +o.rmempty = false +o:depends("type", "ssr") + +o = s:option(Value, "obfs_param", translate("Obfs param (optional)")) +o:depends("type", "ssr") + +o = s:option(Flag, "fast_open", translate("TCP Fast Open")) +o.rmempty = false +o:depends("type", "ss") +o:depends("type", "ssr") + +-- ========== Xray ЭÒéͨÓÃ×Ö¶Î ========== +-- Óû§±¸×¢ +o = s:option(Value, "remarks", translate("Remarks")) +o.default = translate("Remarks") +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") +o:depends("type", "shadowsocks") + +-- Óû§µÈ¼¶ +o = s:option(Value, "level", translate("User Level")) +o.datatype = "uinteger" +o.default = 1 +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "shadowsocks") +o:depends("type", "trojan") + +-- ========== Xray ЭÒéÈÏÖ¤×Ö¶Î ========== +-- UUID (ÓÃÓÚ vmess/vless) +o = s:option(Value, "uuid", translate("UUID")) +o.description = translate("Required for VMess/VLESS. Generate with: uuidgen") +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") + +-- Trojan ÃÜÂë +o = s:option(Value, "trojan_password", translate("Trojan Password")) +o.password = true +o.rmempty = true +o:depends("type", "trojan") + +-- Shadowsocks ÃÜÂëºÍ¼ÓÃÜ£¨Xray ÄÚÖã© +o = s:option(Value, "ss_password", translate("Shadowsocks Password")) +o.password = true +o.rmempty = true +o:depends("type", "shadowsocks") + +o = s:option(ListValue, "ss_method", translate("Encrypt Method")) +for _, v in ipairs(v_ss_encrypt_method_list) do o:value(v) end +o.default = "chacha20-ietf-poly1305" +o.rmempty = true +o:depends("type", "shadowsocks") + +o = s:option(ListValue, "ss_network", translate("Transport")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("tcp,udp", "TCP,UDP") +o.default = "tcp,udp" +o.rmempty = true +o:depends("type", "shadowsocks") + +-- VMess alterId +o = s:option(Value, "alter_id", translate("Alter ID")) +o.datatype = "uinteger" +o.default = 0 +o.rmempty = true +o:depends("type", "vmess") + +-- VLESS decryption +o = s:option(Value, "decryption", translate("Decryption")) +o.default = "none" +o.rmempty = true +o:depends("type", "vless") + +-- ========== TLS / XTLS ÉèÖà ========== +o = s:option(Flag, "tls", translate("TLS")) +o.default = 0 +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") +o:depends("type", "shadowsocks") + +o = s:option(Flag, "xtls", translate("XTLS")) +o.default = 0 +o.rmempty = true +o:depends({ type = "vless", tls = "1" }) + +o = s:option(ListValue, "flow", translate("Flow")) +o:value("xtls-rprx-origin", "xtls-rprx-origin") +o:value("xtls-rprx-origin-udp443", "xtls-rprx-origin-udp443") +o:value("xtls-rprx-direct", "xtls-rprx-direct") +o:value("xtls-rprx-direct-udp443", "xtls-rprx-direct-udp443") +o:value("xtls-rprx-splice", "xtls-rprx-splice") +o:value("xtls-rprx-splice-udp443", "xtls-rprx-splice-udp443") +o.default = "xtls-rprx-direct" +o.rmempty = true +o:depends("xtls", "1") + +o = s:option(Value, "tls_serverName", translate("Server Name (SNI)")) +o.rmempty = true +o:depends("tls", "1") + +o = s:option(Value, "tls_certificateFile", translate("Certificate File Path")) +o.description = translate("e.g.: /etc/ssl/fullchain.pem") +o.rmempty = true +o:depends("tls", "1") + +o = s:option(Value, "tls_keyFile", translate("Private Key File Path")) +o.description = translate("e.g.: /etc/ssl/private.key") +o.rmempty = true +o:depends("tls", "1") + +-- ========== ´«Êä²ãÉèÖà (Transport) ========== +o = s:option(ListValue, "transport", translate("Transport Protocol")) +o:value("tcp", "TCP") +o:value("mkcp", "mKCP") +o:value("ws", "WebSocket") +o:value("h2", "HTTP/2") +o:value("ds", "DomainSocket") +o:value("quic", "QUIC") +o.default = "tcp" +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") + +-- ----- WebSocket ÉèÖà ----- +o = s:option(Value, "ws_host", translate("WebSocket Host")) +o.rmempty = true +o:depends("transport", "ws") +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") + +o = s:option(Value, "ws_path", translate("WebSocket Path")) +o.default = "/" +o.rmempty = true +o:depends("transport", "ws") +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") + +-- ----- HTTP/2 ÉèÖà ----- +o = s:option(Value, "h2_host", translate("HTTP/2 Host")) +o.rmempty = true +o:depends("transport", "h2") +o:depends("type", "vmess") +o:depends("type", "vless") + +o = s:option(Value, "h2_path", translate("HTTP/2 Path")) +o.default = "/" +o.rmempty = true +o:depends("transport", "h2") +o:depends("type", "vmess") +o:depends("type", "vless") + +-- ----- TCP αװÉèÖà ----- +o = s:option(ListValue, "tcp_guise", translate("TCP Camouflage Type")) +o:value("none", "none") +o:value("http", "http") +o.default = "none" +o.rmempty = true +o:depends("transport", "tcp") +o:depends("type", "vmess") +o:depends("type", "vless") + +o = s:option(DynamicList, "tcp_guise_http_host", translate("HTTP Host")) +o.rmempty = true +o:depends("tcp_guise", "http") + +o = s:option(DynamicList, "tcp_guise_http_path", translate("HTTP Path")) +o.rmempty = true +o:depends("tcp_guise", "http") + +-- ----- mKCP ÉèÖà ----- +o = s:option(ListValue, "mkcp_guise", translate("mKCP Camouflage Type")) +for _, v in ipairs(header_type_list) do o:value(v) end +o.default = "none" +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_mtu", translate("KCP MTU")) +o.datatype = "uinteger" +o.default = 1350 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_tti", translate("KCP TTI")) +o.datatype = "uinteger" +o.default = 20 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_uplinkCapacity", translate("KCP Uplink Capacity")) +o.datatype = "uinteger" +o.default = 5 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_downlinkCapacity", translate("KCP Downlink Capacity")) +o.datatype = "uinteger" +o.default = 20 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Flag, "mkcp_congestion", translate("KCP Congestion Control")) +o.default = 0 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_readBufferSize", translate("KCP Read Buffer Size")) +o.datatype = "uinteger" +o.default = 1 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_writeBufferSize", translate("KCP Write Buffer Size")) +o.datatype = "uinteger" +o.default = 1 +o.rmempty = true +o:depends("transport", "mkcp") + +o = s:option(Value, "mkcp_seed", translate("KCP Seed")) +o.datatype = "uinteger" +o.rmempty = true +o:depends("transport", "mkcp") + +-- ----- DomainSocket ÉèÖà ----- +o = s:option(Value, "ds_path", translate("DomainSocket Path")) +o.description = translate("A legal file path. This file must not exist before running.") +o.rmempty = true +o:depends("transport", "ds") + +-- ----- QUIC ÉèÖà ----- +o = s:option(ListValue, "quic_security", translate("QUIC Security")) +o:value("none", "none") +o:value("aes-128-gcm", "aes-128-gcm") +o:value("chacha20-poly1305", "chacha20-poly1305") +o.default = "none" +o.rmempty = true +o:depends("transport", "quic") + +o = s:option(Value, "quic_key", translate("QUIC Key")) +o.rmempty = true +o:depends("transport", "quic") + +o = s:option(ListValue, "quic_guise", translate("QUIC Camouflage Type")) +for _, v in ipairs(header_type_list) do o:value(v) end +o.default = "none" +o.rmempty = true +o:depends("transport", "quic") + +-- ========== ·ÃÎÊ¿ØÖÆ ========== +o = s:option(Flag, "bind_local", translate("Bind Local Only")) +o.description = translate("When selected, it can only be accessed locally. Recommended when using reverse proxies.") +o.default = 0 +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") +o:depends("type", "shadowsocks") + +o = s:option(Flag, "accept_lan", translate("Accept LAN Access")) +o.description = translate("When selected, it can be accessed from LAN. This may not be safe!") +o.default = 0 +o.rmempty = true +o:depends("type", "vmess") +o:depends("type", "vless") +o:depends("type", "trojan") +o:depends("type", "shadowsocks") + +return m \ No newline at end of file diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua new file mode 100644 index 00000000..c2ac03c6 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua @@ -0,0 +1,143 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. +require "luci.http" +require "luci.dispatcher" +local m, sec, o +local encrypt_methods = { + "table", + "rc4", + "rc4-md5", + "rc4-md5-6", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" +} + +local encrypt_methods_ss = { + -- aead + "aes-128-gcm", + "aes-192-gcm", + "aes-256-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + -- aead 2022 + "2022-blake3-aes-128-gcm", + "2022-blake3-aes-256-gcm", + "2022-blake3-chacha20-poly1305" + --[[ stream + "table", + "rc4", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" ]] +} + +local protocol = { + "origin", + "verify_deflate", + "auth_sha1_v4", + "auth_aes128_sha1", + "auth_aes128_md5", + "auth_chain_a" +} + +obfs = { + "plain", + "http_simple", + "http_post", + "random_head", + "tls1.2_ticket_auth", + "tls1.2_ticket_fastauth" +} + +m = Map("shadowsocksr") +-- [[ Global Setting ]]-- +sec = m:section(TypedSection, "server_global", translate("Global Setting")) +sec.anonymous = true + +o = sec:option(Flag, "enable_server", translate("Enable Server")) +o.rmempty = false + +-- [[ Server Setting ]]-- +sec = m:section(TypedSection, "server_config", translate("Server Setting")) +sec.anonymous = true +sec.addremove = true +sec.template = "cbi/tblsection" +sec.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/server/%s") +function sec.create(...) + local sid = TypedSection.create(...) + if sid then + luci.http.redirect(sec.extedit % sid) + return + end +end + +o = sec:option(Flag, "enable", translate("Enable")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or translate("0") +end +o.rmempty = false + +o = sec:option(DummyValue, "type", translate("Server Type")) +function o.cfgvalue(self, section) + local val = Value.cfgvalue(self, section) or "ss" + if val == "vmess" then return "VMess (Xray)" + elseif val == "vless" then return "VLESS (Xray)" + elseif val == "trojan" then return "Trojan (Xray)" + elseif val == "shadowsocks" then return "Shadowsocks (Xray)" + else return val end +end + +o = sec:option(DummyValue, "server_port", translate("Server Port")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "-" +end + +o = sec:option(DummyValue, "username", translate("Username")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "-" +end + +o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method")) +function o.cfgvalue(self, section) + local method = self.map:get(section, "encrypt_method") or self.map:get(section, "encrypt_method_ss") + return method and method:upper() or "-" +end + +o = sec:option(DummyValue, "protocol", translate("Protocol")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "-" +end + +o = sec:option(DummyValue, "obfs", translate("Obfs")) +function o.cfgvalue(...) + return Value.cfgvalue(...) or "-" +end + +return m \ No newline at end of file diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua new file mode 100644 index 00000000..6e5e01e3 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua @@ -0,0 +1,776 @@ +-- Licensed to the public under the GNU General Public License v3. +require "luci.http" +require "luci.sys" +require "luci.util" +require "nixio.fs" +require "luci.dispatcher" +require "luci.model.uci" +local nixio = require "nixio" +local json = require "luci.jsonc" +local cbi = require "luci.cbi" +local uci = require "luci.model.uci".cursor() +local URL = require "url" + +local m, s, o, node +local server_count = 0 +local server_cache = {} +local server_sections = {} +local detect_cache = {} +local CLASH_YAML_DIR = "/etc/ssrplus/clash" +local CLASH_YAML_HELPER = "/usr/share/shadowsocksr/clash_yaml.lua" +local DEFAULT_SERVER_PAGE_SIZE = 50 +local SERVER_PAGE_SIZE_OPTIONS = {25, 50, 100, 200, 0} + +local function is_finded(e) + return luci.sys.exec(string.format('type -t -p "%s" -p "/usr/libexec/%s" 2>/dev/null', e, e)) ~= "" +end + +local function is_js_luci() + return luci.sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 +end + +-- ä¿å­˜å¹¶åº”用行为 +local function apply_redirect(m) + local tmp_uci_file = "/etc/config/" .. "shadowsocksr" .. "_redirect" + if m.redirect and m.redirect ~= "" then + if nixio.fs.access(tmp_uci_file) then + local redirect + for line in io.lines(tmp_uci_file) do + redirect = line:match("option%s+url%s+['\"]([^'\"]+)['\"]") + if redirect and redirect ~= "" then break end + end + if redirect and redirect ~= "" then + luci.sys.call("/bin/rm -f " .. tmp_uci_file) + luci.http.redirect(redirect) + end + else + nixio.fs.writefile(tmp_uci_file, "config redirect\n") + end + m.on_after_save = function(self) + local redirect = self.redirect + if redirect and redirect ~= "" then + m.uci:set("shadowsocksr" .. "_redirect", "@redirect[0]", "url", redirect) + end + end + else + luci.sys.call("/bin/rm -f " .. tmp_uci_file) + end +end + +local function set_apply_on_parse(map) + if not map then return end + if is_js_luci() then + apply_redirect(map) + local old = map.on_after_save + map.on_after_save = function(self) + if old then old(self) end + -- map:set("@global[0]", "timestamp", os.time()) + end + end +end + +local function trim(text) + if not text or text == "" then + return "" + end + return (text:gsub("^%s*(.-)%s*$", "%1")) +end + +local function parse_nonnegative_int(value) + local number = tonumber(value) + if not number then + return nil + end + number = math.floor(number) + if number < 0 then + return nil + end + return number +end + +local function in_list(list, target) + for _, item in ipairs(list) do + if item == target then + return true + end + end + return false +end + +local function upload_alias(filename) + local stem = tostring(filename or ""):gsub("\\", "/"):match("([^/]+)$") or "custom" + stem = stem:gsub("%.%w+$", "") + stem = trim(stem):gsub("[%c\r\n]+", " "):gsub("%s+", " ") + if stem == "" then + stem = "custom" + end + return "Clash_" .. stem +end + +local function hash_file(path) + local cmd = "md5sum " .. luci.util.shellquote(path) .. " 2>/dev/null | awk '{print $1}'" + return trim(luci.sys.exec(cmd)) +end + +local function preprocess_clash_yaml(input_path, output_path) + local cmd = string.format( + "/usr/bin/lua %s prepare %s %s >/dev/null 2>&1", + luci.util.shellquote(CLASH_YAML_HELPER), + luci.util.shellquote(input_path), + luci.util.shellquote(output_path) + ) + return luci.sys.call(cmd) == 0 +end + +local function clash_path_in_use(path, exclude_sid) + local in_use = false + + uci:foreach("shadowsocksr", "servers", function(section) + if section[".name"] ~= exclude_sid and section.clash_path == path then + in_use = true + return false + end + end) + + return in_use +end + +local function cleanup_old_clash_path(old_path, new_path, sid) + if not old_path or old_path == "" or old_path == new_path then + return + end + if old_path:sub(1, #CLASH_YAML_DIR + 1) ~= CLASH_YAML_DIR .. "/" then + return + end + if clash_path_in_use(old_path, sid) then + return + end + nixio.fs.remove(old_path) +end + +local function find_uploaded_clash_section(upload_name, final_path) + local sid + + uci:foreach("shadowsocksr", "servers", function(section) + if section.type ~= "clash" or section.yaml_upload ~= "1" then + return + end + if upload_name ~= "" and section.yaml_upload_name == upload_name then + sid = section[".name"] + return false + end + if final_path ~= "" and section.clash_path == final_path then + sid = section[".name"] + return false + end + end) + + return sid +end + +local function save_uploaded_clash_node(upload_name, final_path) + local sid = find_uploaded_clash_section(upload_name, final_path) + local old_path + local alias + + if not sid then + sid = uci:add("shadowsocksr", "servers") + end + if not sid then + return nil + end + + old_path = uci:get("shadowsocksr", sid, "clash_path") + alias = uci:get("shadowsocksr", sid, "alias") + if not alias or alias == "" then + alias = upload_alias(upload_name) + end + + uci:set("shadowsocksr", sid, "type", "clash") + uci:set("shadowsocksr", sid, "alias", alias) + uci:set("shadowsocksr", sid, "server", "127.0.0.1") + uci:set("shadowsocksr", sid, "server_port", "0") + uci:delete("shadowsocksr", sid, "clash_url") + uci:set("shadowsocksr", sid, "clash_path", final_path) + uci:set("shadowsocksr", sid, "clash_user_agent", uci:get("shadowsocksr", sid, "clash_user_agent") or "clash") + if not uci:get("shadowsocksr", sid, "switch_enable") then + uci:set("shadowsocksr", sid, "switch_enable", uci:get_first("shadowsocksr", "server_subscribe", "switch", "1") or "1") + end + uci:set("shadowsocksr", sid, "yaml_upload", "1") + uci:set("shadowsocksr", sid, "yaml_upload_name", upload_name) + uci:save("shadowsocksr") + uci:commit("shadowsocksr") + + cleanup_old_clash_path(old_path, final_path, sid) + luci.sys.call(string.format("/etc/init.d/shadowsocksr clash_cache %s >/dev/null 2>&1 &", luci.util.shellquote(sid))) + return sid, alias +end + +local has_mihomo = is_finded("mihomo") +local upload_fd +local upload_tmp_path +local upload_filename +local upload_message +local upload_errmessage + +if has_mihomo then + luci.http.setfilehandler(function(meta, chunk, eof) + if not meta or meta.name ~= "clash_yaml_file" then + return + end + + if not upload_fd then + if not meta.file or meta.file == "" then + return + end + upload_filename = tostring(meta.file):gsub("[\r\n]", "") + upload_tmp_path = string.format("/tmp/ssrplus-clash-upload-%d-%d.yaml", nixio.getpid(), os.time()) + upload_fd = nixio.open(upload_tmp_path, "w") + if not upload_fd then + upload_errmessage = translate("Failed to create temporary YAML upload file.") + upload_tmp_path = nil + upload_filename = nil + return + end + end + + if chunk and upload_fd then + upload_fd:write(chunk) + end + + if eof and upload_fd then + upload_fd:close() + upload_fd = nil + end + end) + + if luci.http.formvalue("upload_clash_yaml") then + if not upload_tmp_path or not upload_filename or not nixio.fs.access(upload_tmp_path) then + upload_errmessage = upload_errmessage or translate("No custom YAML file was selected.") + else + local hash + local final_path + local tmp_output = string.format("%s/.upload-%d-%d.yaml", CLASH_YAML_DIR, nixio.getpid(), os.time()) + local sid + local alias + + nixio.fs.mkdirr(CLASH_YAML_DIR) + nixio.fs.remove(tmp_output) + if preprocess_clash_yaml(upload_tmp_path, tmp_output) then + hash = hash_file(tmp_output) + if hash == "" then + nixio.fs.remove(tmp_output) + upload_errmessage = translate("Uploaded YAML validation or preprocessing failed.") + else + final_path = string.format("%s/%s.yaml", CLASH_YAML_DIR, hash) + luci.sys.call(string.format("mv -f %s %s", luci.util.shellquote(tmp_output), luci.util.shellquote(final_path))) + sid, alias = save_uploaded_clash_node(upload_filename, final_path) + if sid then + upload_message = string.format(translate("Custom YAML imported successfully: %s"), alias or sid) + else + upload_errmessage = translate("Uploaded YAML validation or preprocessing failed.") + end + end + else + nixio.fs.remove(tmp_output) + upload_errmessage = translate("Uploaded YAML validation or preprocessing failed.") + end + end + + if upload_tmp_path then + nixio.fs.remove(upload_tmp_path) + end + end +end + +local function preserve_when_hidden(opt, controller, enabled_value) + local original_parse = opt.parse + + opt.parse = function(self, section, novld) + local current = self.map:get(section, controller) + if current == nil then + current = self.map:formvalue("cbid." .. self.map.config .. "." .. section .. "." .. controller) + end + if tostring(current or "") ~= tostring(enabled_value) then + return + end + return original_parse(self, section, novld) + end +end + +local function migrate_legacy_subscribe_urls() + local subscribe_sid = uci:get_first("shadowsocksr", "server_subscribe") + if not subscribe_sid then + return + end + + local legacy_urls = uci:get_list("shadowsocksr", subscribe_sid, "subscribe_url") or {} + if #legacy_urls == 0 then + return + end + + local has_items = false + uci:foreach("shadowsocksr", "server_subscribe_item", function() + has_items = true + return false + end) + if has_items then + return + end + + for index, url in ipairs(legacy_urls) do + local trimmed = trim(url) + if trimmed ~= "" then + local sid_output = luci.sys.exec("uci add shadowsocksr server_subscribe_item") + local sid = sid_output:match("%S+") + if sid and sid ~= "" then + local escaped_sid = luci.util.shellquote(sid) + local alias = string.format("Subscribe %d", index) + local escaped_alias = luci.util.shellquote(alias) + local escaped_url = luci.util.shellquote(trimmed) + luci.sys.call("uci set shadowsocksr." .. escaped_sid .. ".enabled=1") + luci.sys.call("uci set shadowsocksr." .. escaped_sid .. ".alias=" .. escaped_alias) + luci.sys.call("uci set shadowsocksr." .. escaped_sid .. ".url=" .. escaped_url) + end + end + end + + luci.sys.call("uci delete shadowsocksr." .. subscribe_sid .. ".subscribe_url") + luci.sys.call("uci commit shadowsocksr") +end + +local function clash_host_port(clash_url) + if not clash_url or clash_url == "" then + return nil, nil + end + local ok, parsed = pcall(URL.parse, clash_url) + if not ok or not parsed then + return nil, nil + end + local host = parsed.host + local port = parsed.port + if not port or port == "" then + port = (parsed.scheme == "http") and "80" or "443" + end + return host, port +end + +migrate_legacy_subscribe_urls() + +uci:foreach("shadowsocksr", "servers", function(s) + server_count = server_count + 1 + server_sections[#server_sections + 1] = s[".name"] + server_cache[s[".name"]] = { + type = s.type, + v2ray_protocol = s.v2ray_protocol, + alias = s.alias, + server_port = s.server_port, + server = s.server, + transport = s.transport, + ws_path = s.ws_path, + ws_host = s.ws_host, + tls_host = s.tls_host, + tls = s.tls, + reality = s.reality, + clash_url = s.clash_url + } +end) + +local function get_server(section) + return server_cache[section] or {} +end + +do + local raw = nixio.fs.readfile("/tmp/ssrplus_server_detect.json") + if raw and raw ~= "" then + local parsed = json.parse(raw) + if type(parsed) == "table" then + detect_cache = parsed + end + end +end + +m = Map("shadowsocksr", translate("Servers subscription and manage")) +if upload_errmessage then + m.errmessage = upload_errmessage +elseif upload_message then + m.message = upload_message +end + +local style_section = m:section(SimpleSection) +style_section.template = "shadowsocksr/servers_subscribe_url_style" + +-- Server Subscribe +s = m:section(TypedSection, "server_subscribe") +s.anonymous = true + +o = s:option(Flag, "auto_update", translate("Auto Update")) +o.rmempty = false +o.description = translate("Auto Update Server subscription, GFW list and CHN route") + +o = s:option(ListValue, "config_auto_update_mode", translate("Update Mode")) +o:value("0", translate("Appointment Mode")) +o:value("1", translate("Loop Mode")) +o.default = "0" +o.rmempty = true +o:depends("auto_update", "1") + +o = s:option(ListValue, "auto_update_week_time", translate("Update cycle (Day/Week)")) +o:value('*', translate("Every Day")) +o:value("1", translate("Every Monday")) +o:value("2", translate("Every Tuesday")) +o:value("3", translate("Every Wednesday")) +o:value("4", translate("Every Thursday")) +o:value("5", translate("Every Friday")) +o:value("6", translate("Every Saturday")) +o:value("0", translate("Every Sunday")) +o.default = "*" +o.rmempty = true +o:depends({auto_update = "1", config_auto_update_mode = "0"}) + +o = s:option(ListValue, "auto_update_day_time", translate("Regular update (Hour)")) +for t = 0, 23 do + o:value(t, t .. ":00") +end +o.default = 2 +o.rmempty = true +o:depends({auto_update = "1", config_auto_update_mode = "0"}) + +o = s:option(ListValue, "auto_update_min_time", translate("Regular update (Min)")) +for i = 0, 59 do + o:value(i, i .. ":00") +end +o.default = 30 +o.rmempty = true +o:depends({auto_update = "1", config_auto_update_mode = "0"}) + +o = s:option(Value, "config_update_interval", translate("Update Interval(min)")) +o.default = "60" +o.datatype = "uinteger" +o.rmempty = true +o:depends({auto_update = "1", config_auto_update_mode = "1"}) + +o = s:option(Flag, "_subscribe_advanced_toggle", translate("Subscribe Advanced Settings")) +o.rmempty = false +o.default = "0" +o.write = function() end +o.remove = function() end + +o = s:option(Value, "filter_words", translate("Subscribe Filter Words")) +o.rmempty = true +o.description = translate("Filter Words splited by /") +o:depends("_subscribe_advanced_toggle", "1") +preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") + +o = s:option(Value, "save_words", translate("Subscribe Save Words")) +o.rmempty = true +o.description = translate("Save Words splited by /") +o:depends("_subscribe_advanced_toggle", "1") +preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") + +o = s:option(Flag, "allow_insecure", translate("Allow subscribe Insecure nodes By default")) +o.rmempty = false +o.description = translate("Subscribe nodes allows insecure connection as TLS client (insecure)") +o.default = "0" +o:depends("_subscribe_advanced_toggle", "1") +preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") + +o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch")) +o.rmempty = false +o.description = translate("Subscribe new add server default Auto-Switch on") +o.default = "1" +o:depends("_subscribe_advanced_toggle", "1") +preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") + +o = s:option(Flag, "proxy", translate("Through proxy update")) +o.rmempty = false +o.description = translate("Through proxy update list, Not Recommended ") +o.default = "1" +o:depends("_subscribe_advanced_toggle", "1") +preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") + +o = s:option(Button, "_save_subscribe_settings", translate("Save Subscribe Settings")) +o.inputstyle = "save" +o.description = translate("Save current subscribe settings") +o.write = function() end + +o = s:option(Button, "subscribe", translate("Update All Subscribe Servers")) +o.rawhtml = true +o.template = "shadowsocksr/subscribe" +o.write = function(self, section) + self.map.ssr_subscribe_requested = true +end + +o = s:option(Button, "delete", translate("Delete All Subscribe Servers")) +o.inputstyle = "reset" +o.description = string.format(translate("Server Count") .. ": %d", server_count) +o.write = function() + uci:delete_all("shadowsocksr", "servers", function(s) + if s.hashkey or s.isSubscribe then + return true + else + return false + end + end) + uci:save("shadowsocksr") + uci:commit("shadowsocksr") + for file in nixio.fs.glob("/tmp/sub_md5_*") do + nixio.fs.remove(file) + end + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "delete")) + return +end + +o = s:option(Value, "url_test_url", translate("URL Test Address")) +o:value("https://cp.cloudflare.com/", "Cloudflare") +o:value("https://www.gstatic.com/generate_204", "Gstatic") +o:value("https://www.google.com/generate_204", "Google") +o:value("https://www.youtube.com/generate_204", "YouTube") +o:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)") +o:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)") +o.default = o.keylist[3] + + +o = s:option(Value, "user_agent", translate("User-Agent")) +o.default = "v2rayN/9.99" +o:value("curl", "Curl") +o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Linux") +o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Windows") +o:value("v2rayN/9.99", "v2rayN") +o:depends("_subscribe_advanced_toggle", "1") +preserve_when_hidden(o, "_subscribe_advanced_toggle", "1") + +if has_mihomo then + o = s:option(DummyValue, "_upload_clash_yaml", translate("Upload Custom YAML File")) + o.template = "shadowsocksr/clash_yaml_upload" + o.description = translate("Upload a custom Clash/Mihomo YAML file. The file will be preprocessed and saved as a local Clash node.") +end + +s:append(cbi.Template("shadowsocksr/subscribe_schedule_compact")) + +s = m:section(TypedSection, "server_subscribe_item", translate("Subscribe URL")) +s.anonymous = true +s.addremove = true +s.sortable = true +s.template = "shadowsocksr/subscribe_actions_footer" +--s.template = "cbi/tblsection" +--s.template_addremove = "shadowsocksr/subscribe_actions_footer" +s.description = translate("Manage multiple subscribe URLs, including Clash subscriptions. Only enabled entries are included when updating all subscriptions.") + +o = s:option(Flag, "enabled", translate("Enable")) +o.rmempty = false +o.default = "1" +o.width = "1%" +function o.cfgvalue(...) + return Flag.cfgvalue(...) or "1" +end + +o = s:option(Value, "alias", translate("Alias")) +o.rmempty = true +o.width = "7.5rem" +function o.cfgvalue(self, section) + return Value.cfgvalue(self, section) or string.format("Subscribe %s", section:sub(-4)) +end + +o = s:option(Value, "url", translate("Subscribe URL")) +o.rmempty = false + +-- [[ Servers Manage ]]-- +s = m:section(TypedSection, "servers") +s.anonymous = true +s.addremove = true +s.description = translate("Node order can be dragged with the mouse and takes effect immediately. The automatic switch order of server nodes is consistent with the node order in the table.") +s.template = "shadowsocksr/server_table" +set_apply_on_parse(m) +s:append(cbi.Template("shadowsocksr/optimize_cbi_ui")) +s.extedit = luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers", "%s") + +local server_page_size = parse_nonnegative_int(luci.http.formvalue("server_page_size")) +if not server_page_size or not in_list(SERVER_PAGE_SIZE_OPTIONS, server_page_size) then + server_page_size = DEFAULT_SERVER_PAGE_SIZE +end + +local server_page_count = 1 +if server_page_size > 0 and server_count > 0 then + server_page_count = math.ceil(server_count / server_page_size) +end + +local server_page = parse_nonnegative_int(luci.http.formvalue("server_page")) or 1 +if server_page < 1 then + server_page = 1 +end +if server_page > server_page_count then + server_page = server_page_count +end + +local visible_server_sections = server_sections +local server_first_index = server_count > 0 and 1 or 0 +local server_last_index = server_count + +if server_page_size > 0 then + local first = ((server_page - 1) * server_page_size) + 1 + local last = math.min(first + server_page_size - 1, server_count) + visible_server_sections = {} + server_first_index = server_count > 0 and first or 0 + server_last_index = server_count > 0 and last or 0 + + for index = first, last do + visible_server_sections[#visible_server_sections + 1] = server_sections[index] + end +end + +s.sortable = true + +function s.cfgsections(self) + return visible_server_sections +end + +s.server_page = server_page +s.server_page_size = server_page_size +s.server_page_count = server_page_count +s.server_page_sizes = SERVER_PAGE_SIZE_OPTIONS +s.server_total = server_count +s.server_first_index = server_first_index +s.server_last_index = server_last_index +s.server_base_url = luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers") + +function s.create(self, ...) + local used_sid = {} + local next_sid = 1 + + self.map.uci:foreach(self.config, self.sectiontype, function(s) + local num = s[".name"]:match("^cfg(%x%x)") + if num then + local n = tonumber(num, 16) + if n then + used_sid[n] = true + end + end + end) + + local function get_next_sid() + while used_sid[next_sid] do + next_sid = next_sid + 1 + end + used_sid[next_sid] = true + return next_sid + end + + local sid = TypedSection.create(self, ...) + if sid then + local suffix = sid:sub(-4) + self.map.uci:delete(self.config, sid) + local id = get_next_sid() + local newsid = string.format("cfg%02x%s", id, suffix) + local success = self.map.uci:section(self.config, self.sectiontype, newsid) + if success then + --self.map.uci:save(self.config) + luci.http.redirect(self.extedit % newsid) + return + end + end +end + +o = s:option(DummyValue, "type", translate("Type")) +function o.cfgvalue(self, section) + local cfg = get_server(section) + return cfg.v2ray_protocol or cfg.type or translate("None") +end + +o = s:option(DummyValue, "alias", translate("Alias")) +function o.cfgvalue(self, section) + return get_server(section).alias or translate("None") +end + +o = s:option(DummyValue, "server_port", translate("Socket Connected")) +o.template = "shadowsocksr/socket" +o.width = "10%" +function o.cfgvalue(self, section) + self.detect_cache = detect_cache[section] + local cfg = get_server(section) + local stype = cfg.type + if stype == "clash" then + return "N/A" + end + return cfg.server_port +end +o.render = function(self, section, scope) + local cfg = get_server(section) + local stype = cfg.type + self.type = stype or "" + self.proto = cfg.v2ray_protocol or "" + self.reality = cfg.reality or "" + if stype == "clash" then + self.transport = "" + self.ws_path = "" + self.ws_host = "" + self.tls_host = "" + self.tls = "" + self.reality = "" + else + self.transport = cfg.transport or "" + self.ws_host = cfg.ws_host or "" + self.tls_host = cfg.tls_host or "" + if self.transport == 'ws' then + self.ws_path = cfg.ws_path or "" + self.tls = cfg.tls or "" + else + self.ws_path = "" + self.tls = "" + end + end + DummyValue.render(self, section, scope) +end + +o = s:option(DummyValue, "server", translate("Ping Latency")) +o.template = "shadowsocksr/ping" +o.width = "10%" +function o.cfgvalue(self, section) + self.detect_cache = detect_cache[section] + local cfg = get_server(section) + self.type = cfg.type or "" + if cfg.type == "clash" then + return "N/A" + end + return cfg.server or "N/A" +end + +local global_server = uci:get_first('shadowsocksr', 'global', 'global_server') + +node = s:option(Button, "apply_node", translate("Apply")) +node.inputstyle = "apply" +node.render = function(self, section, scope) + if section == global_server then + self.title = translate("Reapply") + else + self.title = translate("Apply") + end + Button.render(self, section, scope) +end +node.write = function(self, section) + local safe_section = luci.util.shellquote(section) + local cmd = string.format("uci set shadowsocksr.@global[0].global_server=%s && uci commit shadowsocksr", safe_section) + luci.sys.call(cmd) + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "restart")) +end + +o = s:option(Flag, "switch_enable", translate("Auto Switch")) +o.rmempty = false +function o.cfgvalue(...) + return Value.cfgvalue(...) or 1 +end + +m:append(cbi.Template("shadowsocksr/server_list")) + +m.commit_handler = function(self) + if not self.ssr_subscribe_requested then + return + end + + for _, config in ipairs(self.parsechain or {}) do + self.uci:commit(config) + end + self.ssr_subscribe_autostart = true +end + +return m diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua new file mode 100644 index 00000000..51b563d1 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua @@ -0,0 +1,284 @@ +-- Copyright (C) 2017 yushi studio +-- Licensed to the public under the GNU General Public License v3. +require "nixio.fs" +require "luci.sys" +require "luci.model.uci" +local m, s, o +local redir_run = 0 +local reudp_run = 0 +local sock5_run = 0 +local http_run = 0 +local server_run = 0 +local kcptun_run = 0 +local tunnel_run = 0 +local gfw_count = 0 +local ad_count = 0 +local ip_count = 0 +local Process_list = luci.sys.exec("busybox ps -w 2>/dev/null || busybox ps") +local uci = require "luci.model.uci".cursor() +local global_server = uci:get_first("shadowsocksr", "global", "global_server", "nil") +local global_type = global_server ~= "nil" and (uci:get("shadowsocksr", global_server, "type") or "") or "" +local global_socks_enabled = uci:get_first("shadowsocksr", "socks5_proxy", "enabled", "0") == "1" +local global_socks_server = uci:get_first("shadowsocksr", "socks5_proxy", "server", "nil") +local global_http_enabled = uci:get_first("shadowsocksr", "http_proxy", "enabled", "0") == "1" +local has_3proxy = nixio.fs.access("/usr/bin/3proxy") or nixio.fs.access("/usr/libexec/3proxy") or nixio.fs.access("/bin/3proxy") +local pdnsd_mode = uci:get_first("shadowsocksr", 'global', 'pdnsd_enable', '0') +-- html constants +font_blue = [[]] +style_blue = [[]] +font_off = [[]] +bold_on = [[]] +bold_off = [[]] +local kcptun_version = translate("Unknown") +local kcp_file = "/usr/bin/kcptun-client" +if not nixio.fs.access(kcp_file) then + kcptun_version = translate("Not exist") +else + if not nixio.fs.access(kcp_file, "rwx", "rx", "rx") then + nixio.fs.chmod(kcp_file, 755) + end + kcptun_version = "" ..luci.sys.exec(kcp_file .. " -v | awk '{printf $3}'") .. "" + if not kcptun_version or kcptun_version == "" then + kcptun_version = translate("Unknown") + end +end + +if nixio.fs.access("/etc/ssrplus/gfw_list.conf") then + gfw_count = tonumber(luci.sys.exec("cat /etc/ssrplus/gfw_list.conf | wc -l")) / 2 +end + +if nixio.fs.access("/etc/ssrplus/ad.conf") then + ad_count = tonumber(luci.sys.exec("cat /etc/ssrplus/ad.conf | wc -l")) +end + +if nixio.fs.access("/etc/ssrplus/china_ssr.txt") then + ip_count = tonumber(luci.sys.exec("cat /etc/ssrplus/china_ssr.txt | wc -l")) +end + +if nixio.fs.access("/etc/ssrplus/applechina.conf") then + apple_count = tonumber(luci.sys.exec("cat /etc/ssrplus/applechina.conf | wc -l")) +end + +if Process_list:find("udp.only.ssr.reudp") then + reudp_run = 1 +end + +--[[ +if Process_list:find("tcp.udp.dual.ssr.retcp") then + redir_run = 1 +end +]]-- + +if Process_list:find("tcp.only.ssr.retcp") then + redir_run = 1 +end + +if Process_list:find("tcp.udp.ssr.local") then + sock5_run = 1 +end + +if has_3proxy and Process_list:find("3proxy%-ssr%-http%.cfg") then + http_run = 1 +end + +if Process_list:find("tcp.udp.ssr.retcp") then + redir_run = 1 + reudp_run = 1 +end + +--[[ +if Process_list:find("nft.ssr.retcp") then + redir_run = 1 +end +]]-- + +if Process_list:find("local.ssr.retcp") then + redir_run = 1 + sock5_run = 1 +end + +--[[ +if Process_list:find("local.nft.ssr.retcp") then + redir_run = 1 + sock5_run = 1 +end +]]-- + +if Process_list:find("local.udp.ssr.retcp") then + reudp_run = 1 + redir_run = 1 + sock5_run = 1 +end + +if global_type == "socks5" and Process_list:find("ipt2socks") then + if Process_list:find("%-T") or Process_list:find("%-%-tcp%-only") then + redir_run = 1 + end + if Process_list:find("%-U") or Process_list:find("%-%-udp%-only") then + reudp_run = 1 + end + if global_socks_enabled and (global_socks_server == "same" and global_socks_server == global_server) then + sock5_run = 1 + end +end + +if (global_type == "clash" or global_type == "tuic" or global_type == "ss") and Process_list:find("ssr%-retcp") then + redir_run = 1 + reudp_run = 1 + if global_socks_enabled and (global_socks_server == "same" and global_socks_server == global_server) then + sock5_run = 1 + end +end + +if (global_type == "clash" or global_type == "tuic" or global_type == "ss") and Process_list:find("mihomo") and (Process_list:find("/clash%-") or Process_list:find("/tuic%-") or Process_list:find("/ss%-")) then + redir_run = 1 + reudp_run = 1 + if global_socks_enabled and (global_socks_server == "same" and global_socks_server == global_server) then + sock5_run = 1 + end +end + +if has_3proxy and global_http_enabled and http_run == 0 and Process_list:find("3proxy%-ssr%-http%.cfg") then + http_run = 1 +end + +if Process_list:find("kcptun.client") then + kcptun_run = 1 +end + +if Process_list:find("ssr.server") then + server_run = 1 +end + +if Process_list:find("mihomo") and Process_list:find("/ss%-server%-") then + server_run = 1 +end + +if Process_list:find("ssrplus/bin/dns2tcp") or + Process_list:find("ssrplus/bin/mosdns") or + Process_list:find("chinadns.*127.0.0.1.*5335") then + pdnsd_run = 1 +end + +if pdnsd_mode == "7" and (global_type == "clash" or global_type == "tuic" or global_type == "ss") and Process_list:find("ssr%-retcp") then + pdnsd_run = 1 +end + +if pdnsd_mode == "7" and global_type == "v2ray" and Process_list:find("ssr%-retcp%.json") then + pdnsd_run = 1 +end + +m = SimpleForm("Version") +m.reset = false +m.submit = false + +s = m:field(DummyValue, "redir_run", translate("Global Client")) +s.rawhtml = true +if redir_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off +end + +s = m:field(DummyValue, "reudp_run", translate("Game Mode UDP Relay")) +s.rawhtml = true +if reudp_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off +end + +if uci:get_first("shadowsocksr", 'global', 'pdnsd_enable', '0') ~= '0' then + s = m:field(DummyValue, "pdnsd_run", translate("DNS Anti-pollution")) + s.rawhtml = true + if pdnsd_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off + else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off + end +end + +s = m:field(DummyValue, "sock5_run", translate("Global SOCKS5 Proxy Server")) +s.rawhtml = true +if sock5_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off +end + +if has_3proxy then + s = m:field(DummyValue, "http_run", translate("Global HTTP/HTTPS Proxy Server")) + s.rawhtml = true + if http_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off + else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off + end +end + +s = m:field(DummyValue, "server_run", translate("Local Servers")) +s.rawhtml = true +if server_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off +else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off +end + +if nixio.fs.access("/usr/bin/kcptun-client") then + s = m:field(DummyValue, "kcp_version", translate("KcpTun Version")) + s.rawhtml = true + s.value = kcptun_version + s = m:field(DummyValue, "kcptun_run", translate("KcpTun")) + s.rawhtml = true + if kcptun_run == 1 then + s.value = font_blue .. bold_on .. translate("Running") .. bold_off .. font_off + else + s.value = style_blue .. bold_on .. translate("Not Running") .. bold_off .. font_off + end +end + +s = m:field(Button, "Restart", translate("Restart ShadowSocksR Plus+")) +s.inputtitle = translate("Restart Service") +s.inputstyle = "reload" +s.write = function() + luci.sys.call("/etc/init.d/shadowsocksr restart >/dev/null 2>&1 &") + luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client")) +end + +s = m:field(DummyValue, "google", translate("Google Connectivity")) +s.value = translate("No Check") +s.template = "shadowsocksr/check" + +s = m:field(DummyValue, "baidu", translate("Baidu Connectivity")) +s.value = translate("No Check") +s.template = "shadowsocksr/check" + +s = m:field(DummyValue, "gfw_data", translate("GFW List Data")) +s.rawhtml = true +s.template = "shadowsocksr/refresh" +s.value = gfw_count .. " " .. translate("Records") + +s = m:field(DummyValue, "ip_data", translate("China IP Data")) +s.rawhtml = true +s.template = "shadowsocksr/refresh" +s.value = ip_count .. " " .. translate("Records") + +if uci:get_first("shadowsocksr", 'global', 'apple_optimization', '0') ~= '0' then + s = m:field(DummyValue, "apple_data", translate("Apple Domains Data")) + s.rawhtml = true + s.template = "shadowsocksr/refresh" + s.value = apple_count .. " " .. translate("Records") +end + +if uci:get_first("shadowsocksr", 'global', 'adblock', '0') == '1' then + s = m:field(DummyValue, "ad_data", translate("Advertising Data")) + s.rawhtml = true + s.template = "shadowsocksr/refresh" + s.value = ad_count .. " " .. translate("Records") +end + +s = m:field(DummyValue, "check_port", translate("Check Server Port")) +s.template = "shadowsocksr/checkport" +s.value = translate("No Check") + +return m diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm new file mode 100644 index 00000000..c85245e8 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm @@ -0,0 +1,143 @@ + + + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm new file mode 100644 index 00000000..364b1482 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm @@ -0,0 +1,152 @@ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + + + + + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/certupload.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/certupload.htm new file mode 100644 index 00000000..f34f04d7 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/certupload.htm @@ -0,0 +1,4 @@ +<%+cbi/valueheader%> + + +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm new file mode 100644 index 00000000..4a16adce --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm @@ -0,0 +1,29 @@ +<%+cbi/valueheader%> + + +<%=self.value%> +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm new file mode 100644 index 00000000..56ee0ab2 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm @@ -0,0 +1,25 @@ +<%+cbi/valueheader%> + + +<%=self.value%> +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm new file mode 100644 index 00000000..724fbe0b --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm @@ -0,0 +1,1044 @@ +<%+cbi/valueheader%> +<% +local clash_nodes = self.clash_nodes or {} +local current_sid = self.map:get(section, "global_server") or "nil" +-%> +
+ + + + + + + + +
+ +
+<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm new file mode 100644 index 00000000..9d5cb765 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm @@ -0,0 +1,104 @@ +<%+header%> + +

<%:Clash Panel%> - <%=alias%>

+ +
+ <%:This panel is available only when the current Clash total node is active.%> +
+ +
+ +
+ +
+
+ + + +<%+footer%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm new file mode 100644 index 00000000..fa9d23eb --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm @@ -0,0 +1,74 @@ +<%+cbi/valueheader%> +<% +local stype = self.map:get(section, "type") +-%> + +<% if stype == "clash" then %> + + + +<% else %> +- +<% end %> +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_yaml_upload.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_yaml_upload.htm new file mode 100644 index 00000000..830193af --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_yaml_upload.htm @@ -0,0 +1,4 @@ +<%+cbi/valueheader%> + + +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/client_dns_defaults.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/client_dns_defaults.htm new file mode 100644 index 00000000..9091257a --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/client_dns_defaults.htm @@ -0,0 +1,78 @@ + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm new file mode 100644 index 00000000..87aee903 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm @@ -0,0 +1,446 @@ + + + + +
+ <%:Core Components%> +
+
+
+
+
+
+
+ <%:Download Source%> + <%:Address%> +
+ +
+
+
+ <%:Component%> + <%:Package Name%> +
+ +
+
+
+
+
<%:Collecting data...%>
+
+
+ + +
+
+
+
+
+
+
+ +
+ <%:Geo Database Update%> +
+
+
+
+
+
+
+ <%:Database%> + <%:Geo Resource%> +
+ +
+
+
+
+
<%:Collecting data...%>
+
+
+ +
+
+
+
+
+
+
diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/control_layout.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/control_layout.htm new file mode 100644 index 00000000..c73c57c0 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/control_layout.htm @@ -0,0 +1,9 @@ + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm new file mode 100644 index 00000000..251f14b2 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm @@ -0,0 +1,37 @@ +<% +local dsp = require "luci.dispatcher" +-%> + +
+ + +
diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm new file mode 100644 index 00000000..579d0383 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm @@ -0,0 +1,24 @@ + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ping.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ping.htm new file mode 100644 index 00000000..1db85acb --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ping.htm @@ -0,0 +1,17 @@ +<%+cbi/valueheader%> +<% + local hint = self:cfgvalue(section) + local cache = self.detect_cache + local is_clash = self.type == "clash" + local text = is_clash and "N/A" or "--- ms" + local color = is_clash and "#999999" or "#ff0000" + if not is_clash and cache and tonumber(cache.ping or 0) > 0 then + local ping = tonumber(cache.ping) + text = tostring(ping) .. " ms" + if ping < 300 then color = "#ff3300" end + if ping < 200 then color = "#ff7700" end + if ping < 100 then color = "#249400" end + end +%> +<%=text%> +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm new file mode 100644 index 00000000..ea4113d8 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm @@ -0,0 +1,37 @@ +<%+cbi/valueheader%> + + +<%=self.value%> +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm new file mode 100644 index 00000000..ff0c4860 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm @@ -0,0 +1,25 @@ +<%+cbi/valueheader%> + + + +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm new file mode 100644 index 00000000..5218cc27 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm @@ -0,0 +1,418 @@ +<%# + Copyright 2018-2019 Lienol + Licensed to the public under the Apache License 2.0. +-%> +<% +require "luci.sys" +function is_js_luci() + return luci.sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 +end +-%> +<% if is_js_luci() then -%> + +<%- else %> + +<%- end %> + + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm new file mode 100644 index 00000000..82b9eeaf --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm @@ -0,0 +1,304 @@ +<%- +local rowcnt = 0 + +function rowstyle() + rowcnt = rowcnt + 1 + if rowcnt % 2 == 0 then + return " cbi-rowstyle-1" + else + return " cbi-rowstyle-2" + end +end + +function width(o) + if o.width then + if type(o.width) == "number" then + return ' style="width:%dpx"' % o.width + end + return ' style="width:%s"' % o.width + end + return "" +end + +local has_titles = false +local has_descriptions = false + +local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous" +local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name")) + +local i, k +for i, k in pairs(self.children) do + if not k.typename then + k.typename = k.template and k.template:gsub("^.+/", "") or "" + end + + if not has_titles and k.title and #k.title > 0 then + has_titles = true + end + + if not has_descriptions and k.description and #k.description > 0 then + has_descriptions = true + end +end + +local total = tonumber(self.server_total) or 0 +local page = tonumber(self.server_page) or 1 +local page_size = tonumber(self.server_page_size) or 0 +local page_count = tonumber(self.server_page_count) or 1 +local first_index = tonumber(self.server_first_index) or 0 +local last_index = tonumber(self.server_last_index) or 0 +local page_sizes = self.server_page_sizes or {} +local base_url = self.server_base_url or "" + +local function page_url(target_page, target_size) + return string.format( + "%s?server_page=%d&server_page_size=%d", + base_url, + target_page, + target_size + ) +end + +function render_titles() + if not has_titles then + return + end + + %>><% + + local i, k + for i, k in ipairs(self.children) do + if not k.optional then + %>><% + + if k.titleref then + %>" class="cbi-title-ref" href="<%=k.titleref%>"><% + end + + write(k.title) + + if k.titleref then + %><% + end + + %><% + end + end + + if self.sortable or self.extedit or self.addremove then + %><% + end + + %><% + + rowcnt = rowcnt + 1 +end + +function render_descriptions() + if not has_descriptions then + return + end + + %><% + + local i, k + for i, k in ipairs(self.children) do + if not k.optional then + %>><% + + write(k.description) + + %><% + end + end + + if self.sortable or self.extedit or self.addremove then + %><% + end + + %><% + + rowcnt = rowcnt + 1 +end + +function render_pager() + if total == 0 then + return + end + + %> +
+ + <%=string.format(translate("Showing %d-%d of %d nodes"), first_index, last_index, total)%> + + + <% if page_count > 1 then %> + <% if page > 1 then %> + <%:Prev%> + <% end %> + <% for current = 1, page_count do %> + <% if current == page then %> + <%=current%> + <% else %> + <%=current%> + <% end %> + <% end %> + <% if page < page_count then %> + <%:Next%> + <% end %> + <% end %> + + + <%:Per page%>: + <% for _, size in ipairs(page_sizes) do %> + <% + local label = size == 0 and translate("All") or tostring(size) + local selected = size == page_size + %> + <% if selected then %> + <%=label%> + <% else %> + <%=label%> + <% end %> + <% end %> + +
+ + + <% +end +-%> + + + + +
+ <% if self.title and #self.title > 0 then -%> +

<%=self.title%>

+ <%- end %> + <%- if self.sortable then -%> + + <%- end -%> +
<%=self.description%>
+ <% render_pager() %> + + <%- + render_titles() + render_descriptions() + + local isempty, section, i, k = true, nil, nil + for i, k in ipairs(self:cfgsections()) do + isempty = false + section = k + + local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k) + local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname, true) + local colorclass = (self.extedit or self.rowcolors) and rowstyle() or "" + local scope = { + valueheader = "cbi/cell_valueheader", + valuefooter = "cbi/cell_valuefooter" + } + -%> + > + <%- + local node + for k, node in ipairs(self.children) do + if not node.optional then + node:render(section, scope or {}) + end + end + -%> + + <%- if self.sortable or self.extedit or self.addremove then -%> + + <%- end -%> + + <%- end -%> + + <%- if isempty then -%> + + + + <%- end -%> +
+
+ <% if self.extedit then -%> + onclick="location.href='<%=self.extedit:format(section)%>'" + <%- elseif type(self.extedit) == "function" then + %> onclick="location.href='<%=self:extedit(section)%>'" + <%- end + %> alt="<%:Edit%>" title="<%:Edit%>" /> + <% end; if self.addremove then %> + ', { + sid: sid + }, function(x, result) { + result = result || {}; + if (result.ret == 1) { + window.location.reload(); + return; + } + }); + return false; + " + /> + <%- end -%> +
+
<%:This section contains no values yet%>
+ <% render_pager() %> + + <% if self.error then %> +
+
    <% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%> +
  • <%=pcdata(e):gsub("\n", "
    ")%>
  • + <%- end end %>
+
+ <% end %> + + <%- if self.addremove then -%> + <% if self.template_addremove then include(self.template_addremove) else -%> +
+ <% if self.anonymous then %> + + <% else %> + <% if self.invalid_cts then -%> +
<%:Invalid%>
+ <%- end %> +
+ +
+ + <% end %> +
+ <%- end %> + <%- end -%> +
+ diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm new file mode 100644 index 00000000..8451c3d5 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/servers_subscribe_url_style.htm @@ -0,0 +1,166 @@ + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/socket.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/socket.htm new file mode 100644 index 00000000..e4ce9535 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/socket.htm @@ -0,0 +1,26 @@ +<%+cbi/valueheader%> +<% + local hint = self:cfgvalue(section) + local cache = self.detect_cache + local text = "N/A" + local color = "#999999" + if cache then + if cache.socket then + text = "ok" + color = "#249400" + else + text = "fail" + color = "#ff0000" + end + end +%> +<%=text%> + + + + + + + + +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm new file mode 100644 index 00000000..025fd51b --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm @@ -0,0 +1,1090 @@ +<%+cbi/valueheader%> +<% +local map = self.map + +local has_ss_rust = luci.sys.exec('type -t -p sslocal 2>/dev/null || type -t -p ssserver 2>/dev/null') ~= "" +local has_mihomo = luci.sys.exec('type -t -p mihomo -p /usr/libexec/mihomo 2>/dev/null') ~= "" +local has_xray = luci.sys.exec('type -t -p xray 2>/dev/null') ~= "" +-%> + + + +<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm new file mode 100644 index 00000000..e739e0fa --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm @@ -0,0 +1,23 @@ + + +
+

+ <%:Collecting data...%> +

+
diff --git a/luci-app-passwall/luasrc/view/shadowsocksr/status_bottom.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/status_bottom.htm similarity index 100% rename from luci-app-passwall/luasrc/view/shadowsocksr/status_bottom.htm rename to luci-app-ssr-plus/luasrc/view/shadowsocksr/status_bottom.htm diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm new file mode 100644 index 00000000..14ce0b7d --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm @@ -0,0 +1,257 @@ +<%+cbi/valueheader%> +<% +local dsp = require "luci.dispatcher" +local subscribe_url = dsp.build_url("admin", "services", "shadowsocksr", "subscribe") +local get_log_url = dsp.build_url("admin", "services", "shadowsocksr", "get_log") +local servers_url = dsp.build_url("admin", "services", "shadowsocksr", "servers") +local autostart = self.map and self.map.ssr_subscribe_autostart +-%> +
+ + + + + /> + +
+ +
+<%+cbi/valuefooter%> diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm new file mode 100644 index 00000000..e26d0398 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm @@ -0,0 +1,490 @@ +<%- +local rowcnt = 0 + +local function rowstyle() + rowcnt = rowcnt + 1 + if rowcnt % 2 == 0 then + return " cbi-rowstyle-1" + end + return " cbi-rowstyle-2" +end + +local function width(o) + if o.width then + if type(o.width) == "number" then + return ' style="width:%dpx"' % o.width + end + return ' style="width:%s"' % o.width + end + return "" +end +-%> + +
+ <% if self.title and #self.title > 0 then -%> +

<%=self.title%>

+ <%- end %> + <%- if self.sortable then -%> + + <%- end -%> +
<%=self.description%>
+ + + <% for _, node in ipairs(self.children) do if not node.optional and node.option ~= "_update" then -%> + + <% end end -%> + + + + <% + local isempty = true + for i, section in ipairs(self:cfgsections()) do + isempty = false + local colorclass = rowstyle() + local scope = { + valueheader = "cbi/cell_valueheader", + valuefooter = "cbi/cell_valuefooter" + } + -%> + + <% + for _, node in ipairs(self.children) do + if not node.optional and node.option ~= "_update" then + node:render(section, scope) + end + end + local alias = self.map:get(section, "alias") or string.format("Subscribe %s", section:sub(-4)) + local update_title = "Subscribe: " .. tostring(alias) + -%> + + + <%- end -%> + + <%- if isempty then -%> + + + + <%- end -%> +
><%=node.title%><%:Actions%>
+
+ + + + onclick="return window.ssrUpdateSubscribeItem(this)" + /> +
+
<%:This section contains no values yet%>
+
+ +
+ + + +
+
+
+ + + + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_enabled_autosave.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_enabled_autosave.htm new file mode 100644 index 00000000..905727f7 --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_enabled_autosave.htm @@ -0,0 +1,47 @@ + diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm new file mode 100644 index 00000000..1290eb2f --- /dev/null +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm @@ -0,0 +1,182 @@ + + + diff --git a/luci-app-ssr-plus/po/templates/ssr-plus.pot b/luci-app-ssr-plus/po/templates/ssr-plus.pot new file mode 100644 index 00000000..aad784b8 --- /dev/null +++ b/luci-app-ssr-plus/po/templates/ssr-plus.pot @@ -0,0 +1,3170 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:231 +msgid "" +"\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 " +"data writes by the client. \"tlshello\" is for TLS client hello packet " +"fragmentation." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:103 +msgid "0" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:94 +msgid "1 Thread" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:101 +msgid "128 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1503 +msgid "16" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:98 +msgid "16 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:95 +msgid "2 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:99 +msgid "32 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1334 +msgid "360" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:207 +msgid "360 Security DNS (China Telecom) (101.226.4.6)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:208 +msgid "360 Security DNS (China Unicom) (123.125.81.6)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:96 +msgid "4 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:100 +msgid "64 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1490 +msgid "8" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:97 +msgid "8 Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:260 +msgid "" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1011 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1349 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1376 +msgid "" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:51 +msgid "" +"

Support SS/SSR/V2RAY/XRAY/TROJAN/TUIC/HYSTERIA2/NAIVEPROXY/SOCKS5/CLASH " +"etc.

" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1183 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1483 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1496 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1509 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:186 +msgid "
  • " +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:354 +msgid "A legal file path. This file must not exist before running." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:387 +msgid "Accept LAN Access" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:627 +msgid "Access Control" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1035 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:235 +msgid "Actions" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1015 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:290 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:298 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:189 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:284 +msgid "Add" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:215 +msgid "Add failed:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:182 +msgid "Adding..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:221 +msgid "Additional Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:378 +msgid "Address" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:628 +msgid "Advanced Settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:274 +msgid "Advertising Data" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:205 +msgid "AliYun Public DNS (223.5.5.5)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:568 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:680 +msgid "Alias" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:373 +msgid "Alias(optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:157 +msgid "All" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:112 +msgid "All Ports" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:965 +msgid "All client proxy rules cleared and applied." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:965 +msgid "All client proxy rules cleared." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:101 +msgid "All settings saved successfully." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:35 +msgid "Allow all except listed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:34 +msgid "Allow listed only" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:471 +msgid "Allow subscribe Insecure nodes By default" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:34 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:120 +msgid "Already up to date" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:186 +msgid "Alter ID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:857 +msgid "AlterId" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1251 +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:134 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:152 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:171 +msgid "Anti-pollution DNS Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:128 +msgid "Apple Domains DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:267 +msgid "Apple Domains Data" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:123 +msgid "Apple Domains Update url" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:119 +msgid "Apple domains optimization" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:740 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:746 +msgid "Apply" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:412 +msgid "Appointment Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:112 +msgid "Are you sure you want to delete subscribe link: %s ?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:133 +msgid "Are you sure you want to restore the client to default settings?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:757 +msgid "Auto Switch" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:93 +msgid "Auto Threads" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:407 +msgid "Auto Update" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:409 +msgid "Auto Update Server subscription, GFW list and CHN route" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:791 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1549 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1565 +msgid "BBR" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1550 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1566 +msgid "BRUTAL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:25 +msgid "Backup and Restore" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:25 +msgid "Backup or Restore Client and Server Configurations." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:252 +msgid "Baidu Connectivity" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:206 +msgid "Baidu Public DNS (180.76.76.76)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:297 +msgid "Base64 sstr failed." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:378 +msgid "Bind Local Only" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1134 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1144 +msgid "BitTorrent (uTP)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:96 +msgid "Black Domain List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:508 +msgid "Bloom Filter" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:80 +msgid "Bypass Domain List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:261 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:439 +msgid "CHECK AND UPDATE" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:31 +msgid "CLOSE WIN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:209 +msgid "CNNIC SDNS (1.2.4.8)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:792 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1551 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1569 +msgid "CUBIC" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1151 +msgid "Camouflage Domain" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:919 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1140 +msgid "Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:227 +msgid "Certificate File Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1459 +msgid "Certificate fingerprint" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:21 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:27 +msgid "Check Connect" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm:17 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm:23 +msgid "Check Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:280 +msgid "Check Server Port" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:94 +msgid "Check Try Count" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:157 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:405 +msgid "Check Update" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:6 +msgid "" +"Check installed component versions and upgrade them online from the upstream " +"release page." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:89 +msgid "Check timout(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:6 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm:6 +msgid "Check..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:146 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:250 +msgid "Checking..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:261 +msgid "China IP Data" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:192 +msgid "ChinaDNS-NG query protocol" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:113 +msgid "Chnroute Update url" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:114 +msgid "Clang.CN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:115 +msgid "Clang.CN.CIDR" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:376 +msgid "Clash" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:88 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:817 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1013 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:3 +msgid "Clash Panel" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:392 +msgid "Clash Subscription URL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:404 +msgid "Clash User-Agent" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:398 +msgid "Clash YAML Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:352 +msgid "Clash/Mihomo" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1018 +msgid "Clear All Rules" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:954 +msgid "Clear all custom client proxy rules and restore empty state?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm:35 +msgid "Clear logs" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:264 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1013 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1351 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1378 +msgid "Click to the page" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1032 +msgid "Client" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:920 +msgid "Client rules exported to CSV file." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:944 +msgid "Client rules imported from CSV file. Click Save to apply." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1027 +msgid "Client supports manual IP or IP/CIDR input." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1024 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:251 +msgid "Close" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:158 +msgid "Cloudflare DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:145 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:182 +msgid "Cloudflare DNS (1.1.1.1)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:402 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:436 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm:21 +msgid "Collecting data..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:390 +msgid "Component" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:630 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:5 +msgid "Component Update" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1011 +msgid "Configure XHTTP Extra Settings (JSON format), see:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:789 +msgid "Congestion control algorithm" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:18 +msgid "Connect Error" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:16 +msgid "Connect OK" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:82 +msgid "Connection Timeout" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1362 +msgid "" +"Controls the policy used when performing DNS queries for ECH configuration." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:90 +msgid "Copy SSR to clipboard successfully." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:369 +msgid "Core Components" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:20 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:428 +msgid "Country MMDB" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:2 +msgid "Create Backup File" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1597 +msgid "Create upload file error." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:110 +msgid "Current ARCH" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1617 +msgid "Current Certificate Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:219 +msgid "Current Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:542 +msgid "Custom" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:991 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:992 +msgid "Custom Client Proxies Rules" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:148 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:187 +msgid "Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:212 +msgid "Custom DNS Server format as IP:PORT (default: disabled)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:160 +msgid "" +"Custom DNS Server format as tcp://IP:PORT or tls://DOMAIN:PORT " +"(tcp://8.8.8.8 or tls://dns.google:853)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:546 +msgid "Custom Plugin Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:114 +msgid "Custom Ports" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:269 +msgid "Custom YAML imported successfully: %s" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:708 +msgid "Custom client proxy rules saved and applied." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:708 +msgid "Custom client proxy rules saved." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1252 +msgid "" +"Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related " +"settings." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:4 +msgid "DL Backup" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1148 +msgid "DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:192 +msgid "DNS Anti-pollution" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:204 +msgid "DNSPod Public DNS (119.29.29.29)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1136 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1146 +msgid "DTLS 1.2" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:424 +msgid "Database" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm:87 +msgid "Day/Week" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1198 +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:193 +msgid "Decryption" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1226 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1399 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1411 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1425 +msgid "Default" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:101 +msgid "Default Node Local Port" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1510 +msgid "Default reject rejects traffic." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:687 +msgid "Default value 0 indicatesno heartbeat." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1484 +msgid "" +"Default: disable. When entering a negative number, such as -1, The Mux " +"module will not be used to carry TCP traffic." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1497 +msgid "" +"Default:16. When entering a negative number, such as -1, The Mux module will " +"not be used to carry UDP traffic, Use original UDP transmission method of " +"proxy protocol." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:297 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:41 +msgid "Defaults Cleared!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:297 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:41 +msgid "Defaults Restored!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1027 +msgid "" +"Define per-client Mihomo proxy targets. Rules are injected as SRC-IP-CIDR " +"entries before the original Clash rules." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:302 +msgid "Delay (ms)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:589 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:248 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:261 +msgid "Delete" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:504 +msgid "Delete All Subscribe Servers" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:130 +msgid "Delete failed:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:112 +msgid "Deny Domain List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:81 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:33 +msgid "Disable" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:200 +msgid "Disable ChinaDNS-NG" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:163 +msgid "Disable IPv6 for Overseas FQDN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:644 +msgid "Disable QUIC path MTU discovery" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:833 +msgid "Disable SNI" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:714 +msgid "Disable TCP No_delay" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:18 +msgid "Do Reset" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:131 +msgid "Do you want to restore the client to default settings?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:196 +msgid "DoT upstream (Need use wolfssl version)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:289 +msgid "Domain Strategy" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:353 +msgid "DomainSocket Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:199 +msgid "Domestic DNS Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1169 +msgid "Downlink Capacity(Default:Mbps)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:377 +msgid "Download Source" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:43 +msgid "Download failed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:844 +msgid "Dual-stack Listening Socket" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1347 +msgid "ECH Config" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1361 +msgid "ECH Query Policy" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:961 +msgid "Early Data Header Name" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:240 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:246 +msgid "Edit" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:307 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:40 +msgid "Edit ShadowSocksR Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:157 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:198 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:278 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:54 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:101 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:560 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1031 +msgid "Enable" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:838 +msgid "Enable 0-RTT QUIC handshake" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:452 +msgid "Enable Authentication" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:80 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1634 +msgid "Enable Auto Switch" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1342 +msgid "Enable ECH(optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:620 +msgid "Enable Lazy Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1369 +msgid "Enable ML-DSA-65(optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1528 +msgid "" +"Enable Multipath TCP, need to be enabled in both server and client " +"configuration." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1464 +msgid "Enable Mux.Cool" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:614 +msgid "Enable Obfuscation" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:514 +msgid "Enable Plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:582 +msgid "Enable Port Hopping" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:84 +msgid "Enable Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:595 +msgid "Enable Transport Protocol Settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:700 +msgid "Enable V2 protocol." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:699 +msgid "Enable V3 protocol." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:134 +msgid "Enable adblock" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:503 +msgid "Enable the SUoT protocol, requires server support." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1004 +msgid "Enable this option to configure XHTTP Extra (JSON format)." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1181 +msgid "Enabled Kernel virtual NIC TUN(optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:181 +msgid "Enabled Mixed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:709 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1623 +msgid "Enabling TCP Fast Open Requires Server Support." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:481 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:488 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:741 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:752 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:883 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:103 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:108 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:171 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:127 +msgid "Encrypt Method" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:115 +msgid "Enter Custom Ports" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:419 +msgid "Every Day" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:424 +msgid "Every Friday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:420 +msgid "Every Monday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:425 +msgid "Every Saturday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:426 +msgid "Every Sunday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:423 +msgid "Every Thursday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:421 +msgid "Every Tuesday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:422 +msgid "Every Wednesday" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:223 +msgid "Expecting: %s" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1019 +msgid "Export Client Rules" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:44 +msgid "Extract failed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1567 +msgid "FORCE BRUTAL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:967 +msgid "Failed to clear all client proxy rules." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:42 +msgid "Failed to create temp directory" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:230 +msgid "Failed to create temporary YAML upload file." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:37 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:77 +msgid "Failed to fetch release metadata" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:99 +msgid "Failed to query component information." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:210 +msgid "Failed to query geo database information." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:710 +msgid "Failed to save custom client proxy rules." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:219 +msgid "File Not Exist" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:461 +msgid "Filter Words splited by /" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1240 +msgid "FinalMask" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1326 +msgid "Finger Print" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1313 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:212 +msgid "Flow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:119 +msgid "" +"For Apple domains equipped with Chinese mainland CDN, always responsive to " +"Chinese CDN IP addresses" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:262 +msgid "For specific usage, see:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:589 +msgid "" +"Format as 10000:20000 or 10000-20000 Multiple groups are separated by commas " +"(,)." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:228 +msgid "Fragment" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:245 +msgid "Fragment Delay" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:240 +msgid "Fragment Length" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:231 +msgid "Fragment Packets" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:245 +msgid "Fragmentation interval (ms)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:240 +msgid "Fragmented packet length (byte)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:256 +msgid "GFW List Data" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:106 +msgid "GFW List Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:64 +msgid "Game Mode Host List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:183 +msgid "Game Mode UDP Relay" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:809 +msgid "Garbage collection interval(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:815 +msgid "Garbage collection lifetime(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:416 +msgid "Geo Database Update" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:425 +msgid "Geo Resource" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:24 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:429 +msgid "GeoSite Database" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:14 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:381 +msgid "GitHub Direct" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:175 +msgid "Global Client" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:194 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:210 +msgid "Global HTTP/HTTPS Proxy Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:108 +msgid "Global Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:152 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:201 +msgid "Global SOCKS5 Proxy Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:81 +msgid "Global Setting" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:76 +msgid "Go to relevant configuration page" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:248 +msgid "Google Connectivity" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:153 +msgid "Google Public DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:135 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:172 +msgid "Google Public DNS (8.8.4.4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:136 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:173 +msgid "Google Public DNS (8.8.8.8)" +msgstr "" + +#: applications/luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json:3 +msgid "Grant UCI access for luci-app-ssr-plus" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1075 +msgid "Gun" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1094 +msgid "H2 Read Idle Timeout" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1089 +msgid "H2/gRPC Health Check" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:421 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:922 +msgid "HTTP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:202 +msgid "HTTP Auth Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:926 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:291 +msgid "HTTP Host" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:212 +msgid "HTTP Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:931 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:295 +msgid "HTTP Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:208 +msgid "HTTP User" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:202 +msgid "HTTP proxy auth method, default:none." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1057 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:268 +msgid "HTTP/2 Host" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1062 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:274 +msgid "HTTP/2 Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1129 +msgid "Header" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1106 +msgid "Health Check Timeout" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:797 +msgid "Heartbeat interval(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:948 +msgid "HeartbeatPeriod(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm:88 +msgid "Hour" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:970 +msgid "Httpupgrade Host" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:975 +msgid "Httpupgrade Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:407 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:418 +msgid "Hysteria2" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:638 +msgid "Hysterir QUIC parameters" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:107 +msgid "IP Route Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1423 +msgid "IP Stack Preference" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:128 +msgid "If empty, Not change Apple domains parsing DNS (Default is empty)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1349 +msgid "" +"If it is not empty, it indicates that the Client has enabled Encrypted " +"Client, see:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:845 +msgid "If this option is not set, the socket behavior is platform dependent." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1436 +msgid "" +"If true, allowss insecure connection at TLS client, e.g., TLS server uses " +"unverifiable certificates." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1581 +msgid "If you have a self-signed certificate,please check the box" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1088 +msgid "Import" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1020 +msgid "Import Client Rules" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:195 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:376 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:520 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:590 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:624 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:731 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:847 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:999 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1079 +msgid "Import configuration information successfully." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1082 +msgid "Initial Windows Size" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:48 +msgid "Install failed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:108 +msgid "Installed Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:49 +msgid "Installed binary failed to run" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:13 +msgid "Interface" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:12 +msgid "Interface control" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:293 +msgid "Invalid" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1082 +msgid "Invalid format." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:330 +msgid "KCP Congestion Control" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:324 +msgid "KCP Downlink Capacity" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:306 +msgid "KCP MTU" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:335 +msgid "KCP Read Buffer Size" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:347 +msgid "KCP Seed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:312 +msgid "KCP TTI" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:318 +msgid "KCP Uplink Capacity" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:341 +msgid "KCP Write Buffer Size" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:231 +msgid "KcpTun" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1639 +msgid "KcpTun Enable" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1659 +msgid "KcpTun Param" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1653 +msgid "KcpTun Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1646 +msgid "KcpTun Port" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:228 +msgid "KcpTun Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:32 +msgid "LAN Access Control" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:48 +msgid "LAN Bypassed Host List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:56 +msgid "LAN Force Proxy Host List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:38 +msgid "LAN Host List" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:30 +msgid "LAN IP AC" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:109 +msgid "Latest Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:139 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:176 +msgid "Level 3 Public DNS (209.244.0.3)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:140 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:177 +msgid "Level 3 Public DNS (209.244.0.4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:141 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:178 +msgid "Level 3 Public DNS (4.2.2.1)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:142 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:179 +msgid "Level 3 Public DNS (4.2.2.2)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:143 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:180 +msgid "Level 3 Public DNS (4.2.2.3)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:144 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:181 +msgid "Level 3 Public DNS (4.2.2.4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:155 +msgid "Level 3 Public DNS-1 (209.244.0.3-4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:156 +msgid "Level 3 Public DNS-2 (4.2.2.1-2)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:157 +msgid "Level 3 Public DNS-3 (4.2.2.3-4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:250 +msgid "Limit the maximum number of splits." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1184 +msgid "" +"Linux kernel TUN virtual NIC requires system support and root privileges." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:18 +msgid "Listen only on the given interface or, if unspecified, on all" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:718 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:771 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:84 +msgid "Loading..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:187 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:217 +msgid "Local Port" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:219 +msgid "Local Servers" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1192 +msgid "Local addresses" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:643 +msgid "Log" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:413 +msgid "Loop Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:109 +msgid "Loukky/gfwlist-by-loukky" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:108 +msgid "Loyalsoldier/v2ray-rules-dat" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1374 +msgid "ML-DSA-65 Public key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1528 +msgid "MPTCP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1155 +msgid "MTU" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:80 +msgid "Main Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:558 +msgid "" +"Manage multiple subscribe URLs, including Clash subscriptions. Only enabled " +"entries are included when updating all subscriptions." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:38 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:78 +msgid "Matching release asset not found" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:954 +msgid "Max Early Data" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:250 +msgid "Max Split" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:850 +msgid "Maximum packet size the socks5 server can receive from external" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:372 +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:375 +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:378 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:9 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:395 +msgid "Mihomo" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1005 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1006 +msgid "Mihomo Pannel" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm:89 +msgid "Min" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1498 +msgid "" +"Min value is 1, Max value is 1024. When omitted or set to 0, Will same path " +"as TCP traffic." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1485 +msgid "" +"Min value is 1, Max value is 128. When omitted or set to 0, it equals 8." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:13 +msgid "Mirror URL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:40 +msgid "Missing gzip support" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:39 +msgid "Missing unzip support" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:41 +msgid "Missing xz support" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:181 +msgid "Mixed as an alias of socks, default:Enabled." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm:10 +msgid "Move down" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm:7 +msgid "Move up" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:188 +msgid "Muitiple DNS server can saperate with ','" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1076 +msgid "Multi" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:92 +msgid "Multi Threads Option" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1046 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1270 +msgid "Must be JSON text!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1464 +msgid "Mux" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:138 +msgid "NEO DEV HOST" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm:11 +msgid "NOT RUNNING" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:401 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:349 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:13 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:396 +msgid "NaiveProxy" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:27 +msgid "Name" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:203 +msgid "Nanjing Xinfeng 114DNS (114.114.114.114)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:793 +msgid "New Reno" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:149 +msgid "Next" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:249 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:253 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:282 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:116 +msgid "No Check" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:156 +msgid "No available Xray core to import this Hysteria2 node." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:546 +msgid "No available core (Shadowsocks or Xray) to import this node." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:738 +msgid "No available core (Xray) to import this node." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:249 +msgid "No custom YAML file was selected." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:474 +msgid "No custom client proxy rules yet." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:21 +msgid "No new data!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1613 +msgid "No specify upload file." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:94 +msgid "No subscription items found" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:615 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:32 +msgid "No switchable proxy groups found." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:582 +msgid "" +"Node order can be dragged with the mouse and takes effect immediately. The " +"automatic switch order of server nodes is consistent with the node order in " +"the table." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:255 +msgid "Noise" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:522 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:921 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1120 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1132 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1142 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:677 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:682 +msgid "None" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:180 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:188 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:197 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:206 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:215 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:224 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:236 +msgid "Not Running" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:35 +msgid "Not exist" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:108 +msgid "Not installed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:27 +msgid "" +"Note: Restoring configurations across different versions may cause " +"compatibility issues." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1539 +msgid "Number of early established connections to reduce latency." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:521 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:564 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:118 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:138 +msgid "Obfs" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:571 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:123 +msgid "Obfs param (optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1176 +msgid "Obfuscate password (optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:631 +msgid "Obfuscation Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:625 +msgid "Obfuscation Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1448 +msgid "Once set, connects only when the server’s chain fingerprint matches." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:113 +msgid "Only Common Ports" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:208 +msgid "Only when HTTP Auth Mode is password valid, Mandatory." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:212 +msgid "Only when HTTP Auth Mode is password valid, Not mandatory." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:170 +msgid "Only when Socks5 Auth Mode is password valid, Mandatory." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:175 +msgid "Only when Socks5 Auth Mode is password valid, Not mandatory." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:154 +msgid "OpenDNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:138 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:175 +msgid "OpenDNS (208.67.220.220)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:137 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:174 +msgid "OpenDNS (208.67.222.222)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:391 +msgid "Package Name" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:261 +msgid "Packet or Rand length as a string, e.g., 10-20." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:298 +msgid "Packet | Rand Length" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:68 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:69 +msgid "Panel" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:466 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:93 +msgid "Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:102 +msgid "Paste sharing link here" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1207 +msgid "Peer public key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:154 +msgid "Per page" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:14 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:23 +msgid "Perform reset" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1112 +msgid "Permit Without Stream" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:725 +msgid "Ping Latency" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1620 +msgid "Please confirm the current certificate path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:5 +msgid "Please fill in reset" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:387 +msgid "Please specify either a Clash subscription URL or a local YAML path." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:550 +msgid "Plugin Opts" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1033 +msgid "Policy" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:606 +msgid "Port Hopping Interval(Unit:Second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:588 +msgid "Port hopping range" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1539 +msgid "Pre-connections" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1211 +msgid "Pre-shared key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:130 +msgid "Prefer module built-in DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:139 +msgid "Prev" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:232 +msgid "Private Key File Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1202 +msgid "Private key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:150 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:254 +msgid "Processing..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:554 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:113 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:133 +msgid "Protocol" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:561 +msgid "Protocol param (optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:111 +msgid "Proxy Ports" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1300 +msgid "Public key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:371 +msgid "QUIC Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1125 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:367 +msgid "QUIC Key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1118 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:359 +msgid "QUIC Security" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:665 +msgid "QUIC initConnReceiveWindow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:651 +msgid "QUIC initStreamReceiveWindow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:672 +msgid "QUIC maxConnReceiveWindow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:679 +msgid "QUIC maxIdleTimeout(Unit:second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:658 +msgid "QUIC maxStreamReceiveWindow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1295 +msgid "REALITY" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:11 +msgid "RST Backup" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:429 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm:7 +msgid "RUNNING" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:422 +msgid "RUNNING in %s (%s) Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:426 +msgid "RUNNING in %s Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:604 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:752 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:802 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:93 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:228 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:253 +msgid "Ready." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:5 +msgid "Really reset all changes?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:744 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:272 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:17 +msgid "Reapply" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:259 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:264 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:270 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:277 +msgid "Records" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:10 +msgid "Refresh" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:29 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:35 +msgid "Refresh Data" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:24 +msgid "Refresh Error!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:18 +msgid "Refresh OK!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:6 +msgid "Refresh..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:431 +msgid "Regular update (Hour)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:439 +msgid "Regular update (Min)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:111 +msgid "Release Asset" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:56 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:57 +msgid "Reload YAML" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:265 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:10 +msgid "Reloading YAML..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:133 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:134 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1034 +msgid "Remarks" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1552 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1568 +msgid "Reno" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:154 +msgid "Required for VMess/VLESS. Generate with: uuidgen" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1197 +msgid "Reserved bytes(optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:998 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:999 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:62 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:63 +msgid "Reset Default Proxies Rules" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:300 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:44 +msgid "Reset Defaults Failed!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:17 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:18 +msgid "Reset complete" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:286 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:30 +msgid "Reset saved Mihomo proxy-group selections and restore YAML defaults?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:144 +msgid "Reset to defaults" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:290 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:34 +msgid "Resetting Defaults..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:120 +msgid "Resolve Dns Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:241 +msgid "Restart Service" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:240 +msgid "Restart ShadowSocksR Plus+" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:9 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:24 +msgid "Restore Backup File" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:16 +msgid "Restore to default configuration" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:178 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:186 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:195 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:204 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:213 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:222 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:234 +msgid "Running" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:105 +msgid "Running Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:403 +msgid "SOCKS5" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:301 +msgid "SS URL base64 sstr format not recognized." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:625 +msgid "SSR Client" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:629 +msgid "SSR Server" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1023 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:260 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:285 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:286 +msgid "Save" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:492 +msgid "Save Subscribe Settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:467 +msgid "Save Words splited by /" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:494 +msgid "Save current subscribe settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:82 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:105 +msgid "Save failed:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:687 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:51 +msgid "Saving..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm:77 +msgid "Second" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1573 +msgid "Self-signed Certificate" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:424 +msgid "Server Address" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:506 +msgid "Server Count" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:223 +msgid "Server Name (SNI)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:335 +msgid "Server Node Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:438 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:75 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:117 +msgid "Server Port" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:88 +msgid "Server Setting" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:58 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:107 +msgid "Server Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:73 +msgid "Server failsafe auto swith and custom update settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:626 +msgid "Servers Nodes" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:393 +msgid "Servers subscription and manage" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1289 +msgid "Session Ticket" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:358 +msgid "Shadow-TLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:726 +msgid "Shadow-TLS ChainPoxy type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:343 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:346 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:413 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:61 +msgid "ShadowSocks" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:729 +msgid "ShadowSocks-rust Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:622 +msgid "ShadowSocksR Plus+" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:51 +msgid "ShadowSocksR Plus+ Settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:405 +msgid "ShadowTLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:373 +msgid "Shadowsocks" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:166 +msgid "Shadowsocks Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:737 +msgid "Shadowsocks password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:383 +msgid "Shadowsocks-rust" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:381 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:340 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:64 +msgid "ShadowsocksR" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1304 +msgid "Short ID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:134 +msgid "Showing %d-%d of %d nodes" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:685 +msgid "Socket Connected" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:420 +msgid "Socks" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:891 +msgid "Socks Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:163 +msgid "Socks protocol auth methods, default:noauth." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:361 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:59 +msgid "Socks5" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:163 +msgid "Socks5 Auth Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:175 +msgid "Socks5 Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:170 +msgid "Socks5 User" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm:73 +msgid "Start Detection" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:205 +msgid "Starting subscription update..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:631 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:114 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:116 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:118 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:120 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:224 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:226 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:228 +msgid "Status" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm:74 +msgid "Stop Detection" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:453 +msgid "Subscribe Advanced Settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:478 +msgid "Subscribe Default Auto-Switch" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:459 +msgid "Subscribe Filter Words" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:250 +msgid "Subscribe Log" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:465 +msgid "Subscribe Save Words" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:551 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:575 +msgid "Subscribe URL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:194 +msgid "Subscribe failed, refreshing page..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:480 +msgid "Subscribe new add server default Auto-Switch on" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:473 +msgid "Subscribe nodes allows insecure connection as TLS client (insecure)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:142 +msgid "Support AdGuardHome and DNSMASQ format list" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:607 +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:84 +msgid "Switch check cycly(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:654 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:71 +msgid "Switch failed." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:651 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:68 +msgid "Switched successfully." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:644 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:61 +msgid "Switching..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:282 +msgid "TCP Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:709 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1623 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:126 +msgid "TCP Fast Open" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:228 +msgid "" +"TCP fragments, which can deceive the censorship system in some cases, such " +"as bypassing SNI blacklists." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:194 +msgid "TCP upstream" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1275 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:199 +msgid "TLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:704 +msgid "TLS 1.3 Strict mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1397 +msgid "TLS ALPN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1453 +msgid "TLS Certificate Name (CertName)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1448 +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1389 +msgid "TLS Host" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1453 +msgid "TLS is used to verify the leaf certificate name." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:379 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:355 +msgid "TUIC" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1409 +msgid "TUIC ALPN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:769 +msgid "TUIC Server IP Address" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:776 +msgid "TUIC User Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:762 +msgid "TUIC User UUID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:827 +msgid "TUIC receive window" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:821 +msgid "TUIC send window" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1376 +msgid "" +"The client has not configured mldsa65Verify, but it will not perform the " +"\"additional verification\" step and can still connect normally, see:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:10 +msgid "The content entered is incorrect!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:686 +msgid "The keep-alive period.(Unit:second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:6 +msgid "" +"The online upgrade downloads the matching Xray-core linux archive for the " +"current ARCH from the official GitHub release page." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:10 +msgid "" +"The online upgrade only tracks the latest stable Mihomo release and " +"downloads the matching linux archive for the current ARCH from the official " +"GitHub release page." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:14 +msgid "" +"The online upgrade tracks the latest NaiveProxy release and prefers OpenWrt " +"static archives matching the current ARCH before falling back to other " +"release assets." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:740 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:795 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:89 +msgid "This Clash total node is not active. Apply this node first." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:6 +msgid "" +"This panel is available only when the current Clash total node is active." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:272 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:126 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:277 +msgid "This section contains no values yet" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:485 +msgid "Through proxy update" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:487 +msgid "Through proxy update list, Not Recommended" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm:78 +msgid "Timeout" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:803 +msgid "Timeout for establishing a connection to server(second)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:260 +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:18 +msgid "Total Records:" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:900 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:177 +msgid "Transport" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:600 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:238 +msgid "Transport Protocol" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:399 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:412 +msgid "Trojan" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:160 +msgid "Trojan Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm:79 +msgid "Try Count" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:282 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:674 +msgid "Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:602 +msgid "UDP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:255 +msgid "" +"UDP noise, Under some circumstances it can bypass some UDP based protocol " +"restrictions." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:502 +msgid "UDP over TCP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:782 +msgid "UDP relay mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:195 +msgid "UDP upstream" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:193 +msgid "UDP/TCP upstream" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:30 +msgid "UL Restore" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:524 +msgid "URL Test Address" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:153 +msgid "UUID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:92 +msgid "Unable to copy SSR to clipboard." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:32 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:42 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:109 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:110 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:111 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:226 +msgid "Unknown" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:80 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:82 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:130 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:215 +msgid "Unknown error" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:36 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:76 +msgid "Unsupported ARCH" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:79 +msgid "Unsupported component" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:265 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:266 +msgid "Update" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:497 +msgid "Update All Subscribe Servers" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:447 +msgid "Update Interval(min)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:411 +msgid "Update Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:418 +msgid "Update cycle (Day/Week)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:29 +msgid "" +"Update geoip.dat and geosite.dat used by Xray/V2Ray runtime when available." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:21 +msgid "" +"Update the Country.mmdb database used by Mihomo/Clash runtime when available." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:25 +msgid "" +"Update the GeoSite.dat database used by Mihomo/Clash runtime when available." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:31 +msgid "Updating..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:157 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:406 +msgid "Upgrade" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:118 +msgid "Upgrade available" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:35 +msgid "Upgrade completed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:146 +msgid "Upgrading..." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1162 +msgid "Uplink Capacity(Default:Mbps)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1583 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/certupload.htm:3 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_yaml_upload.htm:3 +msgid "Upload" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:544 +msgid "Upload Custom YAML File" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:546 +msgid "" +"Upload a custom Clash/Mihomo YAML file. The file will be preprocessed and " +"saved as a local Clash node." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:263 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:271 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:276 +msgid "Uploaded YAML validation or preprocessing failed." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:128 +msgid "Use ChinaDNS-NG query and cache" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:201 +msgid "Use DNS from WAN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:202 +msgid "Use DNS from WAN and 114DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:122 +msgid "Use DNS2TCP query" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:131 +msgid "Use Local DNS Service listen port 5335" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:125 +msgid "Use MosDNS query" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1152 +msgid "" +"Use it together with the DNS disguised type. You can fill in any domain." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:142 +msgid "User Level" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:104 +msgid "User cancelled." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1224 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:534 +msgid "User-Agent" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:313 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1028 +msgid "Userinfo format error." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:459 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:89 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:122 +msgid "Username" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:576 +msgid "Users Authentication" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:371 +msgid "Using incorrect encryption mothod may causes service fail to start" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:28 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:430 +msgid "V2Ray GEO Databases" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:337 +msgid "V2Ray/XRay" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:409 +msgid "V2Ray/XRay protocol" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:410 +msgid "VLESS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:872 +msgid "VLESS Encryption" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:411 +msgid "VMess" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1133 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1143 +msgid "VideoCall (SRTP)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:732 +msgid "Vmess Protocol" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:747 +msgid "Vmess UUID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:864 +msgid "Vmess/VLESS ID (UUID)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:26 +msgid "WAN Force Proxy IP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:21 +msgid "WAN IP AC" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:23 +msgid "WAN White List IP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:937 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:252 +msgid "WebSocket Host" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:943 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:259 +msgid "WebSocket Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1135 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1145 +msgid "WechatVideo" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1185 +msgid "When enabled, it occupies IPv6 routing table 1023." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:388 +msgid "When selected, it can be accessed from LAN. This may not be safe!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:379 +msgid "" +"When selected, it can only be accessed locally. Recommended when using " +"reverse proxies." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:415 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1137 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1147 +msgid "WireGuard" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1217 +msgid "Wireguard allows only traffic from specific source IP." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1003 +msgid "XHTTP Extra" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:991 +msgid "XHTTP Host" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:982 +msgid "XHTTP Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:997 +msgid "XHTTP Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:207 +msgid "XTLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:394 +msgid "Xray" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:225 +msgid "Xray Fragment Settings" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:258 +msgid "Xray Noise Packets" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:5 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:394 +msgid "Xray-core" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:275 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:20 +msgid "YAML Reload Failed!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:272 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:17 +msgid "YAML Reloaded!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:137 +msgid "adblock_url" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1121 +msgid "aes-128-gcm" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1517 +msgid "allow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1511 +msgid "allow: Allows use Mux connection." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1431 +msgid "allowInsecure" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1216 +msgid "allowedIPs(optional)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1332 +msgid "android" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:139 +msgid "anti-AD" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1122 +msgid "chacha20-poly1305" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:116 +msgid "china-operator-ip" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1227 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1328 +msgid "chrome" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1548 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1564 +msgid "comment_tcpcongestion_disable" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1481 +msgid "concurrency" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1232 +msgid "curl" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1545 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1561 +msgid "custom_tcpcongestion" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1338 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1489 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1502 +msgid "disable" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:228 +msgid "e.g.: /etc/ssl/fullchain.pem" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:233 +msgid "e.g.: /etc/ssl/private.key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1230 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1333 +msgid "edge" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:124 +msgid "felixonmars/dnsmasq-china-list" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1228 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1329 +msgid "firefox" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1100 +msgid "gRPC Idle Timeout" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1073 +msgid "gRPC Mode" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1067 +msgid "gRPC Service Name" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:106 +msgid "gfwlist Update url" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:110 +msgid "gfwlist/gfwlist" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1231 +msgid "golang" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:530 +msgid "gost-plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1331 +msgid "ios" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:540 +msgid "kcptun" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:785 +msgid "lossless UDP relay using QUIC streams" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:300 +msgid "mKCP Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:46 +msgid "mihomo binary not found in archive" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:47 +msgid "naive binary not found in archive" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:784 +msgid "native UDP characteristics" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:492 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1317 +msgid "none" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:524 +msgid "obfs-local" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1335 +msgid "qq" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1336 +msgid "random" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1337 +msgid "randomized" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1516 +msgid "reject" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:539 +msgid "restls" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1229 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1330 +msgid "safari" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:719 +msgid "shadow-TLS SNI" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:536 +msgid "shadow-tls" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:697 +msgid "shadowTLS protocol Version" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1518 +msgid "skip" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1512 +msgid "" +"skip: Not use Mux module to carry UDP 443 traffic, Use original UDP " +"transmission method of proxy protocol." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1308 +msgid "spiderX" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:107 +msgid "v2fly/domain-list-community" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:527 +msgid "v2ray-plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:223 +msgid "valid address:port" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:80 +msgid "warning! Please do not reuse the port!" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:45 +msgid "xray binary not found in archive" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:533 +msgid "xray-plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1494 +msgid "xudpConcurrency" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1507 +msgid "xudpProxyUDP443" +msgstr "" diff --git a/luci-app-ssr-plus/po/zh-cn b/luci-app-ssr-plus/po/zh-cn new file mode 120000 index 00000000..8d69574d --- /dev/null +++ b/luci-app-ssr-plus/po/zh-cn @@ -0,0 +1 @@ +zh_Hans \ No newline at end of file diff --git a/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po b/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po new file mode 100644 index 00000000..4d4ff7ba --- /dev/null +++ b/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po @@ -0,0 +1,3649 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:231 +msgid "" +"\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 " +"data writes by the client. \"tlshello\" is for TLS client hello packet " +"fragmentation." +msgstr "" +"\"1-3\" 是 TCP çš„æµåˆ‡ç‰‡ï¼Œåº”用于客户端第 1 至第 3 次写数æ®ã€‚\"tlshello\" 是 " +"TLS æ¡æ‰‹åŒ…切片。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:103 +msgid "0" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:94 +msgid "1 Thread" +msgstr "å•线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:101 +msgid "128 Threads" +msgstr "128 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1503 +msgid "16" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:98 +msgid "16 Threads" +msgstr "16 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:95 +msgid "2 Threads" +msgstr "2 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:99 +msgid "32 Threads" +msgstr "32 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1334 +msgid "360" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:207 +msgid "360 Security DNS (China Telecom) (101.226.4.6)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:208 +msgid "360 Security DNS (China Unicom) (123.125.81.6)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:96 +msgid "4 Threads" +msgstr "4 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:100 +msgid "64 Threads" +msgstr "64 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1490 +msgid "8" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:97 +msgid "8 Threads" +msgstr "8 线程" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:260 +msgid "" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1011 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1349 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1376 +msgid "" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:51 +msgid "" +"

    Support SS/SSR/V2RAY/XRAY/TROJAN/TUIC/HYSTERIA2/NAIVEPROXY/SOCKS5/CLASH " +"etc.

    " +msgstr "" +"

    æ”¯æŒ SS/SSR/V2RAY/XRAY/TROJAN/TUIC/HYSTERIA2/NAIVEPROXY/SOCKS5/CLASH ç­‰å" +"议。

    " + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1183 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1483 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1496 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1509 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:186 +msgid "
    • " +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:354 +msgid "A legal file path. This file must not exist before running." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:387 +msgid "Accept LAN Access" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:627 +msgid "Access Control" +msgstr "访问控制" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1035 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:235 +msgid "Actions" +msgstr "æ“作" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1015 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:290 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:298 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:189 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:284 +msgid "Add" +msgstr "添加" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:215 +msgid "Add failed:" +msgstr "添加失败:" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:182 +msgid "Adding..." +msgstr "添加中..." + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:221 +msgid "Additional Version" +msgstr "附加版本" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:378 +msgid "Address" +msgstr "地å€" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:628 +msgid "Advanced Settings" +msgstr "高级设置" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:274 +msgid "Advertising Data" +msgstr "ã€å¹¿å‘Šå±è”½ã€‘æ•°æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:205 +msgid "AliYun Public DNS (223.5.5.5)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:568 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:680 +msgid "Alias" +msgstr "别å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:373 +msgid "Alias(optional)" +msgstr "别å(å¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:157 +msgid "All" +msgstr "全部" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:112 +msgid "All Ports" +msgstr "所有端å£ï¼ˆé»˜è®¤ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:965 +msgid "All client proxy rules cleared and applied." +msgstr "所有客户端代ç†è§„则已清空并生效。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:965 +msgid "All client proxy rules cleared." +msgstr "所有客户端代ç†è§„则已清空。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:101 +msgid "All settings saved successfully." +msgstr "所有设置ä¿å­˜æˆåŠŸã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:35 +msgid "Allow all except listed" +msgstr "除列表外主机皆å…许" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:34 +msgid "Allow listed only" +msgstr "ä»…å…许列表内主机" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:471 +msgid "Allow subscribe Insecure nodes By default" +msgstr "订阅节点å…许ä¸éªŒè¯ TLS è¯ä¹¦" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:34 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:120 +msgid "Already up to date" +msgstr "已是最新版本" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:186 +msgid "Alter ID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:857 +msgid "AlterId" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1251 +msgid "An FinalMaskObject in JSON format, used for sharing." +msgstr "JSON æ ¼å¼çš„ FinalMaskObject,用æ¥å®žçŽ°åˆ†äº«ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:134 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:152 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:171 +msgid "Anti-pollution DNS Server" +msgstr "访问国外域å DNS æœåС噍" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:128 +msgid "Apple Domains DNS" +msgstr "Apple 域å DNS" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:267 +msgid "Apple Domains Data" +msgstr "ã€Apple 域å】数æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:123 +msgid "Apple Domains Update url" +msgstr "Apple åŸŸåæ›´æ–° URL" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:119 +msgid "Apple domains optimization" +msgstr "Apple 域åè§£æžä¼˜åŒ–" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:740 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:746 +msgid "Apply" +msgstr "应用" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:412 +msgid "Appointment Mode" +msgstr "定时模å¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:112 +msgid "Are you sure you want to delete subscribe link: %s ?" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:133 +msgid "Are you sure you want to restore the client to default settings?" +msgstr "是å¦çœŸçš„è¦æ¢å¤å®¢æˆ·ç«¯é»˜è®¤é…置?" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:757 +msgid "Auto Switch" +msgstr "自动切æ¢" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:93 +msgid "Auto Threads" +msgstr "自动(CPU 线程数)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:407 +msgid "Auto Update" +msgstr "自动更新" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:409 +msgid "Auto Update Server subscription, GFW list and CHN route" +msgstr "自动更新æœåŠ¡å™¨è®¢é˜…ã€GFW 列表和中国大陆 IP 段" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:791 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1549 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1565 +msgid "BBR" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1550 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1566 +msgid "BRUTAL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:25 +msgid "Backup and Restore" +msgstr "备份还原" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:25 +msgid "Backup or Restore Client and Server Configurations." +msgstr "å¤‡ä»½æˆ–è¿˜åŽŸå®¢æˆ·ç«¯åŠæœåŠ¡ç«¯é…置。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:252 +msgid "Baidu Connectivity" +msgstr "ã€ç™¾åº¦ã€‘连通性检查" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:206 +msgid "Baidu Public DNS (180.76.76.76)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:297 +msgid "Base64 sstr failed." +msgstr "Base64 è§£ç å¤±è´¥ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:378 +msgid "Bind Local Only" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1134 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1144 +msgid "BitTorrent (uTP)" +msgstr "BT 下载(uTP)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:96 +msgid "Black Domain List" +msgstr "强制走代ç†çš„域å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:508 +msgid "Bloom Filter" +msgstr "布隆过滤器" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:80 +msgid "Bypass Domain List" +msgstr "ä¸èµ°ä»£ç†çš„域å" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:261 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:439 +msgid "CHECK AND UPDATE" +msgstr "检查并更新" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:31 +msgid "CLOSE WIN" +msgstr "关闭窗å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:209 +msgid "CNNIC SDNS (1.2.4.8)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:792 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1551 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1569 +msgid "CUBIC" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1151 +msgid "Camouflage Domain" +msgstr "伪装域å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:919 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1140 +msgid "Camouflage Type" +msgstr "伪装类型" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:227 +msgid "Certificate File Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1459 +msgid "Certificate fingerprint" +msgstr "è¯ä¹¦æŒ‡çº¹" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:21 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:27 +msgid "Check Connect" +msgstr "检查连通性" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm:17 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm:23 +msgid "Check Server" +msgstr "检查æœåС噍" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:280 +msgid "Check Server Port" +msgstr "ã€æœåŠ¡å™¨ç«¯å£ã€‘检查" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:94 +msgid "Check Try Count" +msgstr "åˆ‡æ¢æ£€æŸ¥é‡è¯•次数" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:157 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:405 +msgid "Check Update" +msgstr "检查更新" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:6 +msgid "" +"Check installed component versions and upgrade them online from the upstream " +"release page." +msgstr "检测已安装组件版本,并从上游å‘布页在线å‡çº§ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:89 +msgid "Check timout(second)" +msgstr "åˆ‡æ¢æ£€æŸ¥è¶…时时间(秒)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:6 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/checkport.htm:6 +msgid "Check..." +msgstr "正在检查..." + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:146 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:250 +msgid "Checking..." +msgstr "检查中..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:261 +msgid "China IP Data" +msgstr "ã€ä¸­å›½å¤§é™† IP 段】数æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:192 +msgid "ChinaDNS-NG query protocol" +msgstr "ChinaDNS-NG 查询åè®®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:113 +msgid "Chnroute Update url" +msgstr "中国大陆 IP 段更新 URL" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:114 +msgid "Clang.CN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:115 +msgid "Clang.CN.CIDR" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:376 +msgid "Clash" +msgstr "Clash" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:88 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:817 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1013 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:3 +msgid "Clash Panel" +msgstr "Clash 颿¿" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:392 +msgid "Clash Subscription URL" +msgstr "Clash 订阅链接" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:404 +msgid "Clash User-Agent" +msgstr "Clash User-Agent" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:398 +msgid "Clash YAML Path" +msgstr "Clash YAML 路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:352 +msgid "Clash/Mihomo" +msgstr "Clash/Mihomo" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1018 +msgid "Clear All Rules" +msgstr "清空所有规则" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:954 +msgid "Clear all custom client proxy rules and restore empty state?" +msgstr "清空所有自定义客户端代ç†è§„则,并æ¢å¤ä¸ºç©ºç™½çжæ€å—?" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm:35 +msgid "Clear logs" +msgstr "清空日志" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:264 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1013 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1351 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1378 +msgid "Click to the page" +msgstr "点击å‰å¾€" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1032 +msgid "Client" +msgstr "客户端" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:920 +msgid "Client rules exported to CSV file." +msgstr "客户端规则已导出为 CSV 文件。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:944 +msgid "Client rules imported from CSV file. Click Save to apply." +msgstr "客户端规则已从 CSV 文件导入,请点击ä¿å­˜ç”Ÿæ•ˆã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1027 +msgid "Client supports manual IP or IP/CIDR input." +msgstr "å®¢æˆ·ç«¯æ”¯æŒæ‰‹åŠ¨è¾“å…¥ IP 或 IP/CIDR。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1024 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:251 +msgid "Close" +msgstr "关闭" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:158 +msgid "Cloudflare DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:145 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:182 +msgid "Cloudflare DNS (1.1.1.1)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:402 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:436 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm:21 +msgid "Collecting data..." +msgstr "正在收集数æ®ä¸­..." + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:390 +msgid "Component" +msgstr "组件" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:630 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:5 +msgid "Component Update" +msgstr "组件å‡çº§" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1011 +msgid "Configure XHTTP Extra Settings (JSON format), see:" +msgstr "é…ç½® XHTTP é¢å¤–设置(JSON æ ¼å¼ï¼‰ï¼Œå…·ä½“请å‚è§ï¼š" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:789 +msgid "Congestion control algorithm" +msgstr "拥塞控制算法" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:18 +msgid "Connect Error" +msgstr "连接错误" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm:16 +msgid "Connect OK" +msgstr "连接正常" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:82 +msgid "Connection Timeout" +msgstr "连接超时" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1362 +msgid "" +"Controls the policy used when performing DNS queries for ECH configuration." +msgstr "控制使用 DNS 查询 ECH é…置时的策略。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:90 +msgid "Copy SSR to clipboard successfully." +msgstr "æˆåŠŸå¤åˆ¶ SSR 网å€åˆ°å‰ªè´´æ¿ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:369 +msgid "Core Components" +msgstr "核心组件" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:20 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:428 +msgid "Country MMDB" +msgstr "Country MMDB" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:2 +msgid "Create Backup File" +msgstr "创建备份文件" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1597 +msgid "Create upload file error." +msgstr "创建上传文件错误。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:110 +msgid "Current ARCH" +msgstr "当剿ž¶æž„" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1617 +msgid "Current Certificate Path" +msgstr "当å‰è¯ä¹¦è·¯å¾„" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:219 +msgid "Current Version" +msgstr "当å‰ç‰ˆæœ¬" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:542 +msgid "Custom" +msgstr "自定义" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:991 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:992 +msgid "Custom Client Proxies Rules" +msgstr "自定义客户端代ç†è§„则" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:148 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:187 +msgid "Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)" +msgstr "æ ¼å¼ä¸º IP:Port(默认:8.8.4.4:53)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:212 +msgid "Custom DNS Server format as IP:PORT (default: disabled)" +msgstr "æ ¼å¼ä¸º IP:PORT(默认:ç¦ç”¨ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:160 +msgid "" +"Custom DNS Server format as tcp://IP:PORT or tls://DOMAIN:PORT " +"(tcp://8.8.8.8 or tls://dns.google:853)" +msgstr "" +"æ ¼å¼ä¸ºtcp://IP:Port或tls://域å:Port (tcp://8.8.8.8或tls://dns.google:853)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:546 +msgid "Custom Plugin Path" +msgstr "自定义æ’件路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:114 +msgid "Custom Ports" +msgstr "自定义端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:269 +msgid "Custom YAML imported successfully: %s" +msgstr "自定义 YAML 导入æˆåŠŸï¼š%s" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:708 +msgid "Custom client proxy rules saved and applied." +msgstr "自定义客户端代ç†è§„则已ä¿å­˜å¹¶ç”Ÿæ•ˆã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:708 +msgid "Custom client proxy rules saved." +msgstr "自定义客户端代ç†è§„则已ä¿å­˜ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1252 +msgid "" +"Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related " +"settings." +msgstr "自定义 finalmask 将覆盖 mkcpã€hysteria2ã€fragmentã€noise 等相关é…置。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:4 +msgid "DL Backup" +msgstr "下载备份" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1148 +msgid "DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:192 +msgid "DNS Anti-pollution" +msgstr "DNS 防污染æœåŠ¡" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:204 +msgid "DNSPod Public DNS (119.29.29.29)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1136 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1146 +msgid "DTLS 1.2" +msgstr "DTLS 1.2 æ•°æ®åŒ…" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:424 +msgid "Database" +msgstr "æ•°æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm:87 +msgid "Day/Week" +msgstr "æ—¥/周" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1198 +msgid "Decimal numbers separated by \",\" or Base64-encoded strings." +msgstr "用“,â€éš”开的å进制数字或 Base64 ç¼–ç å­—符串。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:193 +msgid "Decryption" +msgstr "解密" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1226 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1399 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1411 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1425 +msgid "Default" +msgstr "默认" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:101 +msgid "Default Node Local Port" +msgstr "节点默认本地端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1510 +msgid "Default reject rejects traffic." +msgstr "默认 reject æ‹’ç»æµé‡ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:687 +msgid "Default value 0 indicatesno heartbeat." +msgstr "默认为 0 表示无心跳。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1484 +msgid "" +"Default: disable. When entering a negative number, such as -1, The Mux " +"module will not be used to carry TCP traffic." +msgstr "默认:ç¦ç”¨ã€‚填负数时,如 -1,ä¸ä½¿ç”¨ Mux æ¨¡å—æ‰¿è½½ TCP æµé‡ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1497 +msgid "" +"Default:16. When entering a negative number, such as -1, The Mux module will " +"not be used to carry UDP traffic, Use original UDP transmission method of " +"proxy protocol." +msgstr "" +"默认值:16。填负数时,如 -1,ä¸ä½¿ç”¨ Mux æ¨¡å—æ‰¿è½½ UDP æµé‡ã€‚将使用代ç†å议原本" +"çš„ UDP 传输方å¼ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:297 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:41 +msgid "Defaults Cleared!" +msgstr "已清空默认状æ€ï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:297 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:41 +msgid "Defaults Restored!" +msgstr "默认值已æ¢å¤ï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1027 +msgid "" +"Define per-client Mihomo proxy targets. Rules are injected as SRC-IP-CIDR " +"entries before the original Clash rules." +msgstr "" +"为æ¯ä¸ªå®¢æˆ·ç«¯æŒ‡å®š Mihomo 代ç†ç›®æ ‡ã€‚规则会以 SRC-IP-CIDR 形弿³¨å…¥åˆ°åŽŸå§‹ Clash " +"规则之å‰ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:302 +msgid "Delay (ms)" +msgstr "延迟(ms)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:589 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:248 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:261 +msgid "Delete" +msgstr "删除" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:504 +msgid "Delete All Subscribe Servers" +msgstr "删除所有订阅节点" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:130 +msgid "Delete failed:" +msgstr "删除失败:" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:112 +msgid "Deny Domain List" +msgstr "ç¦æ­¢è¿žæŽ¥çš„域å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:81 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:33 +msgid "Disable" +msgstr "åœç”¨" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:200 +msgid "Disable ChinaDNS-NG" +msgstr "直通模å¼ï¼ˆç¦ç”¨ ChinaDNS-NG)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:163 +msgid "Disable IPv6 for Overseas FQDN" +msgstr "ç¦æ­¢æµ·å¤–域å返回 IPv6 记录" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:644 +msgid "Disable QUIC path MTU discovery" +msgstr "ç¦ç”¨ QUIC å¯ç”¨ MTU 探测" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:833 +msgid "Disable SNI" +msgstr "关闭 SNI æœåС噍å称指示" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:714 +msgid "Disable TCP No_delay" +msgstr "ç¦ç”¨ TCP 无延迟" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:18 +msgid "Do Reset" +msgstr "执行é‡ç½®" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:131 +msgid "Do you want to restore the client to default settings?" +msgstr "是å¦è¦æ¢å¤å®¢æˆ·ç«¯é»˜è®¤é…置?" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:196 +msgid "DoT upstream (Need use wolfssl version)" +msgstr "DoT 上游(需使用 wolfssl 版本)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:289 +msgid "Domain Strategy" +msgstr "域åè§£æžç­–ç•¥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:353 +msgid "DomainSocket Path" +msgstr "域 Socket 路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:199 +msgid "Domestic DNS Server" +msgstr "国内 DNS æœåС噍" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1169 +msgid "Downlink Capacity(Default:Mbps)" +msgstr "下行链路容é‡ï¼ˆé»˜è®¤ï¼šMbps)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:377 +msgid "Download Source" +msgstr "下载æº" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:43 +msgid "Download failed" +msgstr "下载失败" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:844 +msgid "Dual-stack Listening Socket" +msgstr "åŒæ ˆ Socket 监å¬" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1347 +msgid "ECH Config" +msgstr "ECH é…ç½®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1361 +msgid "ECH Query Policy" +msgstr "ECH 查询策略" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:961 +msgid "Early Data Header Name" +msgstr "å‰ç½®æ•°æ®æ ‡å¤´" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:240 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:246 +msgid "Edit" +msgstr "编辑" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:307 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:40 +msgid "Edit ShadowSocksR Server" +msgstr "编辑æœåС噍é…ç½®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:157 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:198 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:278 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:54 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:101 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:560 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1031 +msgid "Enable" +msgstr "å¯ç”¨" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:838 +msgid "Enable 0-RTT QUIC handshake" +msgstr "客户端å¯ç”¨ 0-RTT QUIC è¿žæŽ¥æ¡æ‰‹" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:452 +msgid "Enable Authentication" +msgstr "å¯ç”¨ç”¨æˆ·å/密ç è®¤è¯" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:80 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1634 +msgid "Enable Auto Switch" +msgstr "å¯ç”¨è‡ªåŠ¨åˆ‡æ¢" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1342 +msgid "Enable ECH(optional)" +msgstr "å¯ç”¨ ECH (å¯é€‰)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:620 +msgid "Enable Lazy Mode" +msgstr "å¯ç”¨æ‡’狗模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1369 +msgid "Enable ML-DSA-65(optional)" +msgstr "å¯ç”¨ ML-DSA-65 (å¯é€‰)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1528 +msgid "" +"Enable Multipath TCP, need to be enabled in both server and client " +"configuration." +msgstr "å¯ç”¨ Multipath TCP,需在æœåŠ¡ç«¯å’Œå®¢æˆ·ç«¯é…ç½®ä¸­åŒæ—¶å¯ç”¨ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1464 +msgid "Enable Mux.Cool" +msgstr "å¯ç”¨ Mux.Cool" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:614 +msgid "Enable Obfuscation" +msgstr "å¯ç”¨æ··æ·†åŠŸèƒ½" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:514 +msgid "Enable Plugin" +msgstr "å¯ç”¨æ’ä»¶" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:582 +msgid "Enable Port Hopping" +msgstr "å¯ç”¨ç«¯å£è·³è·ƒ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:84 +msgid "Enable Server" +msgstr "å¯åЍæœåŠ¡ç«¯" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:595 +msgid "Enable Transport Protocol Settings" +msgstr "å¯ç”¨ä¼ è¾“å议设置" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:700 +msgid "Enable V2 protocol." +msgstr "å¼€å¯ V2 å议。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:699 +msgid "Enable V3 protocol." +msgstr "å¼€å¯ V3 å议。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:134 +msgid "Enable adblock" +msgstr "å¯ç”¨å¹¿å‘Šå±è”½" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:503 +msgid "Enable the SUoT protocol, requires server support." +msgstr "å¯ç”¨ SUoT åè®®ï¼Œéœ€è¦æœåŠ¡ç«¯æ”¯æŒã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1004 +msgid "Enable this option to configure XHTTP Extra (JSON format)." +msgstr "å¯ç”¨æ­¤é€‰é¡¹é…ç½® XHTTP 附加项(JSON æ ¼å¼ï¼‰ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1181 +msgid "Enabled Kernel virtual NIC TUN(optional)" +msgstr "å¯ç”¨å†…æ ¸çš„è™šæ‹Ÿç½‘å¡ TUN(å¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:181 +msgid "Enabled Mixed" +msgstr "å¯ç”¨ Mixed" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:709 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1623 +msgid "Enabling TCP Fast Open Requires Server Support." +msgstr "å¯ç”¨ TCP å¿«é€Ÿæ‰“å¼€éœ€è¦æœåŠ¡ç«¯æ”¯æŒã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:481 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:488 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:741 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:752 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:883 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:103 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:108 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:171 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:127 +msgid "Encrypt Method" +msgstr "加密方å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:115 +msgid "Enter Custom Ports" +msgstr "输入自定义端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:419 +msgid "Every Day" +msgstr "æ¯å¤©" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:424 +msgid "Every Friday" +msgstr "æ¯å‘¨äº”" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:420 +msgid "Every Monday" +msgstr "æ¯å‘¨ä¸€" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:425 +msgid "Every Saturday" +msgstr "æ¯å‘¨å…­" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:426 +msgid "Every Sunday" +msgstr "æ¯å‘¨æ—¥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:423 +msgid "Every Thursday" +msgstr "æ¯å‘¨å››" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:421 +msgid "Every Tuesday" +msgstr "æ¯å‘¨äºŒ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:422 +msgid "Every Wednesday" +msgstr "æ¯å‘¨ä¸‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:223 +msgid "Expecting: %s" +msgstr "应为:%s" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1019 +msgid "Export Client Rules" +msgstr "批é‡å¯¼å‡ºå®¢æˆ·ç«¯è§„则" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:44 +msgid "Extract failed" +msgstr "解压失败" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1567 +msgid "FORCE BRUTAL" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:967 +msgid "Failed to clear all client proxy rules." +msgstr "清空所有客户端代ç†è§„则失败。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:42 +msgid "Failed to create temp directory" +msgstr "创建临时目录失败" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:230 +msgid "Failed to create temporary YAML upload file." +msgstr "创建临时 YAML 上传文件失败。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:37 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:77 +msgid "Failed to fetch release metadata" +msgstr "获å–å‘布信æ¯å¤±è´¥" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:99 +msgid "Failed to query component information." +msgstr "获å–组件信æ¯å¤±è´¥ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:210 +msgid "Failed to query geo database information." +msgstr "èŽ·å– Geo æ•°æ®åº“ä¿¡æ¯å¤±è´¥ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:710 +msgid "Failed to save custom client proxy rules." +msgstr "ä¿å­˜è‡ªå®šä¹‰å®¢æˆ·ç«¯ä»£ç†è§„则失败。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:219 +msgid "File Not Exist" +msgstr "文件ä¸å­˜åœ¨" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:461 +msgid "Filter Words splited by /" +msgstr "命中关键字的节点将被丢弃。多个关键字用 / 分隔" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1240 +msgid "FinalMask" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1326 +msgid "Finger Print" +msgstr "指纹伪造" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1313 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:212 +msgid "Flow" +msgstr "æµæŽ§ï¼ˆFlow)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:119 +msgid "" +"For Apple domains equipped with Chinese mainland CDN, always responsive to " +"Chinese CDN IP addresses" +msgstr "é…备中国大陆 CDN çš„ Apple 域å,始终应答中国大陆 CDN 地å€" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:262 +msgid "For specific usage, see:" +msgstr "具体使用方法,具体请å‚è§ï¼š" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:589 +msgid "" +"Format as 10000:20000 or 10000-20000 Multiple groups are separated by commas " +"(,)." +msgstr "æ ¼å¼ä¸ºï¼š10000:20000 或 10000-20000 多组时用逗å·ï¼ˆ,)隔开。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:228 +msgid "Fragment" +msgstr "分片" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:245 +msgid "Fragment Delay" +msgstr "分片延迟" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:240 +msgid "Fragment Length" +msgstr "分片包长" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:231 +msgid "Fragment Packets" +msgstr "分片方å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:245 +msgid "Fragmentation interval (ms)" +msgstr "分片间隔(ms)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:240 +msgid "Fragmented packet length (byte)" +msgstr "分片包长 (byte)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:256 +msgid "GFW List Data" +msgstr "ã€GFW 列表】数æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:106 +msgid "GFW List Mode" +msgstr "GFW 列表模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:64 +msgid "Game Mode Host List" +msgstr "å¢žå¼ºæ¸¸æˆæ¨¡å¼å®¢æˆ·ç«¯ LAN IP" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:183 +msgid "Game Mode UDP Relay" +msgstr "æ¸¸æˆæ¨¡å¼ UDP 中继" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:809 +msgid "Garbage collection interval(second)" +msgstr "UDP æ•°æ®åŒ…片残片清ç†é—´éš”(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:815 +msgid "Garbage collection lifetime(second)" +msgstr "UDP æ•°æ®åŒ…残片在æœåŠ¡å™¨çš„ä¿ç•™æ—¶é—´ï¼ˆå•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:416 +msgid "Geo Database Update" +msgstr "Geo æ•°æ®åº“æ›´æ–°" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:425 +msgid "Geo Resource" +msgstr "Geo 资æº" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:24 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:429 +msgid "GeoSite Database" +msgstr "GeoSite æ•°æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:14 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:381 +msgid "GitHub Direct" +msgstr "GitHub 直连" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:175 +msgid "Global Client" +msgstr "TCP 逿˜Žä»£ç†" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:194 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:210 +msgid "Global HTTP/HTTPS Proxy Server" +msgstr "HTTP/HTTPS ä»£ç†æœåŠ¡ç«¯ï¼ˆå…¨å±€ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:108 +msgid "Global Mode" +msgstr "全局模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:152 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:201 +msgid "Global SOCKS5 Proxy Server" +msgstr "SOCKS5 ä»£ç†æœåŠ¡ç«¯ï¼ˆå…¨å±€ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:81 +msgid "Global Setting" +msgstr "全局设置" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:76 +msgid "Go to relevant configuration page" +msgstr "å‰å¾€ç›¸å…³é…置页é¢" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:248 +msgid "Google Connectivity" +msgstr "ã€è°·æ­Œã€‘连通性检查" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:153 +msgid "Google Public DNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:135 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:172 +msgid "Google Public DNS (8.8.4.4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:136 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:173 +msgid "Google Public DNS (8.8.8.8)" +msgstr "" + +#: applications/luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json:3 +msgid "Grant UCI access for luci-app-ssr-plus" +msgstr "授予访问 luci-app-ssr-plus é…置的æƒé™" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1075 +msgid "Gun" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1094 +msgid "H2 Read Idle Timeout" +msgstr "H2 读å–空闲超时" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1089 +msgid "H2/gRPC Health Check" +msgstr "H2/gRPC å¥åº·æ£€æŸ¥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:421 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:922 +msgid "HTTP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:202 +msgid "HTTP Auth Mode" +msgstr "HTTP è®¤è¯æ¨¡å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:926 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:291 +msgid "HTTP Host" +msgstr "HTTP 主机å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:212 +msgid "HTTP Password" +msgstr "HTTP 密ç " + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:931 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:295 +msgid "HTTP Path" +msgstr "HTTP 路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:208 +msgid "HTTP User" +msgstr "HTTP 用户å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:202 +msgid "HTTP proxy auth method, default:none." +msgstr "HTTP 代ç†è®¤è¯æ–¹å¼ï¼Œé»˜è®¤ï¼šnone。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1057 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:268 +msgid "HTTP/2 Host" +msgstr "HTTP/2 主机å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1062 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:274 +msgid "HTTP/2 Path" +msgstr "HTTP/2 路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1129 +msgid "Header" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1106 +msgid "Health Check Timeout" +msgstr "å¥åº·æ£€æŸ¥è¶…æ—¶" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:797 +msgid "Heartbeat interval(second)" +msgstr "ä¿æ´»å¿ƒè·³åŒ…å‘é€é—´éš”(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:948 +msgid "HeartbeatPeriod(second)" +msgstr "心跳周期(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm:88 +msgid "Hour" +msgstr "æ—¶" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:970 +msgid "Httpupgrade Host" +msgstr "HTTPUpgrade 主机å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:975 +msgid "Httpupgrade Path" +msgstr "HTTPUpgrade 路径" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:407 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:418 +msgid "Hysteria2" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:638 +msgid "Hysterir QUIC parameters" +msgstr "QUIC 傿•°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:107 +msgid "IP Route Mode" +msgstr "绕过中国大陆 IP 模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1423 +msgid "IP Stack Preference" +msgstr "IP 栈优先级" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:128 +msgid "If empty, Not change Apple domains parsing DNS (Default is empty)" +msgstr "å¦‚æžœä¸ºç©ºï¼Œåˆ™ä¸æ›´æ”¹ Apple 域åè§£æž DNS(默认为空)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1349 +msgid "" +"If it is not empty, it indicates that the Client has enabled Encrypted " +"Client, see:" +msgstr "如果ä¸ä¸ºç©ºï¼Œè¡¨ç¤ºå®¢æˆ·ç«¯å·²å¯ç”¨åŠ å¯†å®¢æˆ·ç«¯ï¼Œå…·ä½“è¯·å‚è§ï¼š" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:845 +msgid "If this option is not set, the socket behavior is platform dependent." +msgstr "如果未设置此选项,则 Socket 行为ä¾èµ–于平å°ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1436 +msgid "" +"If true, allowss insecure connection at TLS client, e.g., TLS server uses " +"unverifiable certificates." +msgstr "" +"是å¦å…许ä¸å®‰å…¨è¿žæŽ¥ã€‚当选择时,将ä¸ä¼šæ£€æŸ¥è¿œç«¯ä¸»æœºæ‰€æä¾›çš„ TLS è¯ä¹¦çš„æœ‰æ•ˆæ€§ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1581 +msgid "If you have a self-signed certificate,please check the box" +msgstr "如果你使用自签è¯ä¹¦ï¼Œè¯·é€‰æ‹©" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1088 +msgid "Import" +msgstr "导入é…置信æ¯" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1020 +msgid "Import Client Rules" +msgstr "批é‡å¯¼å…¥å®¢æˆ·ç«¯è§„则" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:195 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:376 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:520 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:590 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:624 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:731 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:847 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:999 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1079 +msgid "Import configuration information successfully." +msgstr "导入é…ç½®ä¿¡æ¯æˆåŠŸã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1082 +msgid "Initial Windows Size" +msgstr "åˆå§‹çª—å£å¤§å°" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:48 +msgid "Install failed" +msgstr "安装失败" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:108 +msgid "Installed Version" +msgstr "已安装版本" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:49 +msgid "Installed binary failed to run" +msgstr "新安装的二进制无法è¿è¡Œ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:13 +msgid "Interface" +msgstr "接å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:12 +msgid "Interface control" +msgstr "æŽ¥å£æŽ§åˆ¶" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:293 +msgid "Invalid" +msgstr "无效的" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1082 +msgid "Invalid format." +msgstr "无效的格å¼ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:330 +msgid "KCP Congestion Control" +msgstr "KCP 拥塞控制" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:324 +msgid "KCP Downlink Capacity" +msgstr "KCP 下行带宽容é‡" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:306 +msgid "KCP MTU" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:335 +msgid "KCP Read Buffer Size" +msgstr "KCP 读缓冲区大å°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:347 +msgid "KCP Seed" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:312 +msgid "KCP TTI" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:318 +msgid "KCP Uplink Capacity" +msgstr "KCP 上行链路容é‡" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:341 +msgid "KCP Write Buffer Size" +msgstr "KCP 写缓冲区大å°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:231 +msgid "KcpTun" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1639 +msgid "KcpTun Enable" +msgstr "KcpTun å¯ç”¨" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1659 +msgid "KcpTun Param" +msgstr "KcpTun 傿•°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1653 +msgid "KcpTun Password" +msgstr "KcpTun 密ç " + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1646 +msgid "KcpTun Port" +msgstr "KcpTun 端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:228 +msgid "KcpTun Version" +msgstr "KcpTun 版本å·" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:32 +msgid "LAN Access Control" +msgstr "内网客户端分æµä»£ç†æŽ§åˆ¶" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:48 +msgid "LAN Bypassed Host List" +msgstr "ä¸èµ°ä»£ç†çš„局域网 LAN IP" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:56 +msgid "LAN Force Proxy Host List" +msgstr "全局代ç†çš„ LAN IP" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:38 +msgid "LAN Host List" +msgstr "内网主机列表" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:30 +msgid "LAN IP AC" +msgstr "LAN IP 访问控制" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:109 +msgid "Latest Version" +msgstr "最新版本" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:139 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:176 +msgid "Level 3 Public DNS (209.244.0.3)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:140 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:177 +msgid "Level 3 Public DNS (209.244.0.4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:141 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:178 +msgid "Level 3 Public DNS (4.2.2.1)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:142 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:179 +msgid "Level 3 Public DNS (4.2.2.2)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:143 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:180 +msgid "Level 3 Public DNS (4.2.2.3)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:144 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:181 +msgid "Level 3 Public DNS (4.2.2.4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:155 +msgid "Level 3 Public DNS-1 (209.244.0.3-4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:156 +msgid "Level 3 Public DNS-2 (4.2.2.1-2)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:157 +msgid "Level 3 Public DNS-3 (4.2.2.3-4)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:250 +msgid "Limit the maximum number of splits." +msgstr "é™åˆ¶åˆ†ç‰‡çš„æœ€å¤§æ•°é‡ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1184 +msgid "" +"Linux kernel TUN virtual NIC requires system support and root privileges." +msgstr "Linux 内核 TUN 虚拟网å¡éœ€è¦ç³»ç»Ÿæ”¯æŒå’Œ root æƒé™ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:18 +msgid "Listen only on the given interface or, if unspecified, on all" +msgstr "ä»…ç›‘å¬æŒ‡å®šçš„æŽ¥å£ï¼ŒæœªæŒ‡å®šåˆ™ç›‘å¬å…¨éƒ¨ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:718 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:771 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:84 +msgid "Loading..." +msgstr "加载中..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:187 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:217 +msgid "Local Port" +msgstr "本地端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:219 +msgid "Local Servers" +msgstr "本机æœåŠ¡ç«¯" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1192 +msgid "Local addresses" +msgstr "本地地å€" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:643 +msgid "Log" +msgstr "日志" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:413 +msgid "Loop Mode" +msgstr "循环模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:109 +msgid "Loukky/gfwlist-by-loukky" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:108 +msgid "Loyalsoldier/v2ray-rules-dat" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1374 +msgid "ML-DSA-65 Public key" +msgstr "ML-DSA-65 公钥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1528 +msgid "MPTCP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1155 +msgid "MTU" +msgstr "最大传输å•å…ƒ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:80 +msgid "Main Server" +msgstr "主æœåС噍" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:558 +msgid "" +"Manage multiple subscribe URLs, including Clash subscriptions. Only enabled " +"entries are included when updating all subscriptions." +msgstr "" +"管ç†å¤šæ¡è®¢é˜… URL,包括 Clash è®¢é˜…ã€‚åªæœ‰å¯ç”¨çš„订阅项æ‰ä¼šå‚与“更新所有订阅节" +"点â€ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:38 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:78 +msgid "Matching release asset not found" +msgstr "未找到匹é…çš„å‘布资产" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:954 +msgid "Max Early Data" +msgstr "最大å‰ç½®æ•°æ®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:250 +msgid "Max Split" +msgstr "最大分片数" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:850 +msgid "Maximum packet size the socks5 server can receive from external" +msgstr "socks5 æœåС噍å¯ä»¥ä»Žå¤–部接收的最大数æ®åŒ…大å°ï¼ˆå•ä½ï¼šå­—节)" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:372 +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:375 +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:378 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:9 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:395 +msgid "Mihomo" +msgstr "Mihomo" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1005 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1006 +msgid "Mihomo Pannel" +msgstr "Mihomo 颿¿" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_schedule_compact.htm:89 +msgid "Min" +msgstr "分" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1498 +msgid "" +"Min value is 1, Max value is 1024. When omitted or set to 0, Will same path " +"as TCP traffic." +msgstr "" +"最å°å€¼ 1,最大值 1024。 çœç•¥æˆ–者填 0 时,将与 TCP æµé‡èµ°åŒä¸€æ¡è·¯ï¼Œä¹Ÿå°±æ˜¯ä¼ ç»Ÿ" +"的行为。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1485 +msgid "" +"Min value is 1, Max value is 128. When omitted or set to 0, it equals 8." +msgstr "最å°å€¼ 1,最大值 128。çœç•¥æˆ–者填 0 时都等于 8。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/component.lua:13 +msgid "Mirror URL" +msgstr "镜åƒåœ°å€" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:40 +msgid "Missing gzip support" +msgstr "缺少 gzip 支æŒ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:39 +msgid "Missing unzip support" +msgstr "缺少 unzip 支æŒ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:41 +msgid "Missing xz support" +msgstr "缺少 xz 支æŒ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:181 +msgid "Mixed as an alias of socks, default:Enabled." +msgstr "Mixed 作为 SOCKS 的别å,默认:å¯ç”¨ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm:10 +msgid "Move down" +msgstr "下移" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/optimize_cbi_ui.htm:7 +msgid "Move up" +msgstr "上移" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:188 +msgid "Muitiple DNS server can saperate with ','" +msgstr "多个上游 DNS æœåŠ¡å™¨è¯·ç”¨ ',' 分隔(注æ„用英文逗å·)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1076 +msgid "Multi" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:92 +msgid "Multi Threads Option" +msgstr "多线程并å‘转å‘" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1046 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1270 +msgid "Must be JSON text!" +msgstr "必须是 JSON 文本内容ï¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1464 +msgid "Mux" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:138 +msgid "NEO DEV HOST" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm:11 +msgid "NOT RUNNING" +msgstr "未è¿è¡Œ" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:401 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:349 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:13 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:396 +msgid "NaiveProxy" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:27 +msgid "Name" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:203 +msgid "Nanjing Xinfeng 114DNS (114.114.114.114)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:793 +msgid "New Reno" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:149 +msgid "Next" +msgstr "下一页" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:249 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:253 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:282 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:116 +msgid "No Check" +msgstr "未检查" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:156 +msgid "No available Xray core to import this Hysteria2 node." +msgstr "没有å¯ç”¨çš„ Xray 核心å¯ä»¥å¯¼å…¥æ­¤ Hysteria2 节点。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:546 +msgid "No available core (Shadowsocks or Xray) to import this node." +msgstr "没有å¯ç”¨çš„æ ¸å¿ƒï¼ˆShadowsocks 或 Xray)å¯ä»¥å¯¼å…¥æ­¤èŠ‚ç‚¹ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:738 +msgid "No available core (Xray) to import this node." +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:249 +msgid "No custom YAML file was selected." +msgstr "没有选择自定义 YAML 文件。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:474 +msgid "No custom client proxy rules yet." +msgstr "暂无自定义客户端代ç†è§„则。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:21 +msgid "No new data!" +msgstr "ä½ å·²ç»æ˜¯æœ€æ–°æ•°æ®ï¼Œæ— éœ€æ›´æ–°ï¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1613 +msgid "No specify upload file." +msgstr "没有上传è¯ä¹¦ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:94 +msgid "No subscription items found" +msgstr "没有找到任何订阅项" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:615 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:32 +msgid "No switchable proxy groups found." +msgstr "未找到å¯åˆ‡æ¢çš„代ç†ç»„。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:582 +msgid "" +"Node order can be dragged with the mouse and takes effect immediately. The " +"automatic switch order of server nodes is consistent with the node order in " +"the table." +msgstr "" +"节点顺åºå¯ç”¨é¼ æ ‡æ‹–拉åŽç«‹å³ç”Ÿæ•ˆï¼ŒæœåŠ¡å™¨èŠ‚ç‚¹è‡ªåŠ¨åˆ‡æ¢é¡ºåºå’Œè¡¨ä¸­èŠ‚ç‚¹é¡ºåºä¸€è‡´ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:255 +msgid "Noise" +msgstr "噪声" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:522 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:921 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1120 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1132 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1142 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:677 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:682 +msgid "None" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:180 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:188 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:197 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:206 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:215 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:224 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:236 +msgid "Not Running" +msgstr "未è¿è¡Œ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:35 +msgid "Not exist" +msgstr "æœªå®‰è£…å¯æ‰§è¡Œæ–‡ä»¶" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:108 +msgid "Not installed" +msgstr "未安装" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua:27 +msgid "" +"Note: Restoring configurations across different versions may cause " +"compatibility issues." +msgstr "注æ„:ä¸åŒç‰ˆæœ¬é—´çš„é…ç½®æ¢å¤å¯èƒ½ä¼šå¯¼è‡´å…¼å®¹æ€§é—®é¢˜ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1539 +msgid "Number of early established connections to reduce latency." +msgstr "预连接的数é‡ï¼Œç”¨äºŽé™ä½Žå»¶è¿Ÿã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:521 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:564 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:118 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:138 +msgid "Obfs" +msgstr "æ··æ·†æ’ä»¶" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:571 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:123 +msgid "Obfs param (optional)" +msgstr "æ··æ·†å‚æ•°ï¼ˆå¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1176 +msgid "Obfuscate password (optional)" +msgstr "混淆密ç ï¼ˆå¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:631 +msgid "Obfuscation Password" +msgstr "混淆密ç " + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:625 +msgid "Obfuscation Type" +msgstr "混淆类型" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1448 +msgid "Once set, connects only when the server’s chain fingerprint matches." +msgstr "设置åŽï¼Œä»…在æœåС噍è¯ä¹¦é“¾æŒ‡çº¹åŒ¹é…时连接。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:113 +msgid "Only Common Ports" +msgstr "仅常用端å£ï¼ˆä¸èµ° P2P æµé‡åˆ°ä»£ç†ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:208 +msgid "Only when HTTP Auth Mode is password valid, Mandatory." +msgstr "仅当 HTTP è®¤è¯æ¨¡å¼ä¸º password 时有效,必填。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:212 +msgid "Only when HTTP Auth Mode is password valid, Not mandatory." +msgstr "仅当 HTTP è®¤è¯æ¨¡å¼ä¸º password 时有效,éžå¿…填。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:170 +msgid "Only when Socks5 Auth Mode is password valid, Mandatory." +msgstr "仅当 Socks5 è®¤è¯æ–¹å¼ä¸º Password 时有效,必填。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:175 +msgid "Only when Socks5 Auth Mode is password valid, Not mandatory." +msgstr "仅当 Socks5 è®¤è¯æ–¹å¼ä¸º Password 时有效,éžå¿…填。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:154 +msgid "OpenDNS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:138 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:175 +msgid "OpenDNS (208.67.220.220)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:137 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:174 +msgid "OpenDNS (208.67.222.222)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:391 +msgid "Package Name" +msgstr "组件包åç§°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:261 +msgid "Packet or Rand length as a string, e.g., 10-20." +msgstr "æ•°æ®åŒ…或 Rand 长度以字符串形å¼è¾“入,例如:10-20。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:298 +msgid "Packet | Rand Length" +msgstr "æ•°æ®åŒ… | Rand 长度" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:68 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:69 +msgid "Panel" +msgstr "颿¿" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:466 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:93 +msgid "Password" +msgstr "密ç " + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:102 +msgid "Paste sharing link here" +msgstr "在此处粘贴分享链接" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1207 +msgid "Peer public key" +msgstr "节点公钥" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:154 +msgid "Per page" +msgstr "æ¯é¡µ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:14 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:23 +msgid "Perform reset" +msgstr "执行é‡ç½®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1112 +msgid "Permit Without Stream" +msgstr "å…è®¸æ— æ•°æ®æµ" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:725 +msgid "Ping Latency" +msgstr "Ping 延迟" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1620 +msgid "Please confirm the current certificate path" +msgstr "请选择确认所传è¯ä¹¦ï¼Œè¯ä¹¦ä¸æ­£ç¡®å°†æ— æ³•è¿è¡Œ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:5 +msgid "Please fill in reset" +msgstr "请填写 reset" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:387 +msgid "Please specify either a Clash subscription URL or a local YAML path." +msgstr "请填写 Clash 订阅 URL 或本地 YAML 路径中的至少一项。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:550 +msgid "Plugin Opts" +msgstr "æ’件傿•°" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1033 +msgid "Policy" +msgstr "ç­–ç•¥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:606 +msgid "Port Hopping Interval(Unit:Second)" +msgstr "端å£è·³è·ƒé—´éš”(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:588 +msgid "Port hopping range" +msgstr "端å£è·³è·ƒèŒƒå›´" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1539 +msgid "Pre-connections" +msgstr "预连接" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1211 +msgid "Pre-shared key" +msgstr "预共享密钥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:130 +msgid "Prefer module built-in DNS" +msgstr "优先使用模å—内置 DNS" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:139 +msgid "Prev" +msgstr "上一页" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:232 +msgid "Private Key File Path" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1202 +msgid "Private key" +msgstr "ç§é’¥" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:150 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:254 +msgid "Processing..." +msgstr "处ç†ä¸­..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:554 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:113 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:133 +msgid "Protocol" +msgstr "传输åè®®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:561 +msgid "Protocol param (optional)" +msgstr "传输åè®®å‚æ•°ï¼ˆå¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:111 +msgid "Proxy Ports" +msgstr "需è¦ä»£ç†çš„端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1300 +msgid "Public key" +msgstr "公钥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:371 +msgid "QUIC Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1125 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:367 +msgid "QUIC Key" +msgstr "QUIC 密钥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1118 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:359 +msgid "QUIC Security" +msgstr "QUIC 加密方å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:665 +msgid "QUIC initConnReceiveWindow" +msgstr "QUIC åˆå§‹çš„连接接收窗å£å¤§å°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:651 +msgid "QUIC initStreamReceiveWindow" +msgstr "QUIC åˆå§‹æµæŽ¥æ”¶çª—å£å¤§å°ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:672 +msgid "QUIC maxConnReceiveWindow" +msgstr "QUIC 最大的连接接收窗å£å¤§å°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:679 +msgid "QUIC maxIdleTimeout(Unit:second)" +msgstr "QUIC 最长空闲超时时间(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:658 +msgid "QUIC maxStreamReceiveWindow" +msgstr "QUIC æœ€å¤§çš„æµæŽ¥æ”¶çª—å£å¤§å°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1295 +msgid "REALITY" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:11 +msgid "RST Backup" +msgstr "æ¢å¤å¤‡ä»½" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:429 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/status.htm:7 +msgid "RUNNING" +msgstr "è¿è¡Œä¸­" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:422 +msgid "RUNNING in %s (%s) Mode" +msgstr "è¿è¡Œä¸­ï¼Œå½“å‰ä¸º %s(%s)模å¼" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:426 +msgid "RUNNING in %s Mode" +msgstr "è¿è¡Œä¸­ï¼Œå½“å‰ä¸º %s 模å¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:604 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:752 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:802 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:93 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:228 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:253 +msgid "Ready." +msgstr "就绪。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:5 +msgid "Really reset all changes?" +msgstr "真的é‡ç½®æ‰€æœ‰æ›´æ”¹å—?" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:744 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:272 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:17 +msgid "Reapply" +msgstr "釿–°åº”用" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:259 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:264 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:270 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:277 +msgid "Records" +msgstr "æ¡è®°å½•" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:10 +msgid "Refresh" +msgstr "æ›´æ–°" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:29 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:35 +msgid "Refresh Data" +msgstr "æ›´æ–°æ•°æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:24 +msgid "Refresh Error!" +msgstr "更新失败ï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:18 +msgid "Refresh OK!" +msgstr "æ›´æ–°æˆåŠŸï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:6 +msgid "Refresh..." +msgstr "正在更新,请ç¨å€™..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:431 +msgid "Regular update (Hour)" +msgstr "å®šæ—¶æ›´æ–°ï¼ˆå°æ—¶ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:439 +msgid "Regular update (Min)" +msgstr "定时更新(分钟)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:111 +msgid "Release Asset" +msgstr "å‘布包å" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:56 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:57 +msgid "Reload YAML" +msgstr "é‡è½½ YAML" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:265 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:10 +msgid "Reloading YAML..." +msgstr "正在é‡è½½ YAML..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:133 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:134 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1034 +msgid "Remarks" +msgstr "备注" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1552 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1568 +msgid "Reno" +msgstr "Reno" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:154 +msgid "Required for VMess/VLESS. Generate with: uuidgen" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1197 +msgid "Reserved bytes(optional)" +msgstr "ä¿ç•™å­—节(å¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:998 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:999 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:62 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:63 +msgid "Reset Default Proxies Rules" +msgstr "é‡ç½®ä»£ç†åˆ†ç»„规则" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:300 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:44 +msgid "Reset Defaults Failed!" +msgstr "é‡ç½®é»˜è®¤å€¼å¤±è´¥ï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:17 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:18 +msgid "Reset complete" +msgstr "é‡ç½®å®Œæˆ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:286 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:30 +msgid "Reset saved Mihomo proxy-group selections and restore YAML defaults?" +msgstr "è¦æ¸…空已ä¿å­˜çš„ Mihomo 分组选择,并æ¢å¤ä¸º YAML 默认值å—?" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:144 +msgid "Reset to defaults" +msgstr "æ¢å¤å‡ºåŽ‚è®¾ç½®" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:290 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:34 +msgid "Resetting Defaults..." +msgstr "正在é‡ç½®é»˜è®¤å€¼..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:120 +msgid "Resolve Dns Mode" +msgstr "DNS è§£æžæ–¹å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:241 +msgid "Restart Service" +msgstr "é‡å¯æœåŠ¡" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:240 +msgid "Restart ShadowSocksR Plus+" +msgstr "é‡å¯ ShadowSocksR Plus+" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:9 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:24 +msgid "Restore Backup File" +msgstr "æ¢å¤å¤‡ä»½æ–‡ä»¶" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:16 +msgid "Restore to default configuration" +msgstr "æ¢å¤é»˜è®¤é…ç½®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:178 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:186 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:195 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:204 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:213 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:222 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:234 +msgid "Running" +msgstr "è¿è¡Œä¸­" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:105 +msgid "Running Mode" +msgstr "è¿è¡Œæ¨¡å¼" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:403 +msgid "SOCKS5" +msgstr "SOCKS5" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:301 +msgid "SS URL base64 sstr format not recognized." +msgstr "无法识别 SS URL çš„ Base64 æ ¼å¼ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:625 +msgid "SSR Client" +msgstr "客户端" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:629 +msgid "SSR Server" +msgstr "æœåŠ¡ç«¯" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:1023 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:260 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:285 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:286 +msgid "Save" +msgstr "ä¿å­˜" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:492 +msgid "Save Subscribe Settings" +msgstr "ä¿å­˜è®¢é˜…设置" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:467 +msgid "Save Words splited by /" +msgstr "" +"命中关键字的节点将被ä¿ç•™ã€‚多个关键字用 / 分隔。此项为空则ä¸å¯ç”¨ä¿ç•™åŒ¹é…" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:494 +msgid "Save current subscribe settings" +msgstr "ä¿å­˜å½“å‰è®¢é˜…设置" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:82 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:105 +msgid "Save failed:" +msgstr "ä¿å­˜å¤±è´¥ï¼š" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:687 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:51 +msgid "Saving..." +msgstr "ä¿å­˜ä¸­..." + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm:77 +msgid "Second" +msgstr "周期" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1573 +msgid "Self-signed Certificate" +msgstr "自签è¯ä¹¦" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:424 +msgid "Server Address" +msgstr "æœåŠ¡å™¨åœ°å€" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:506 +msgid "Server Count" +msgstr "æœåŠ¡å™¨èŠ‚ç‚¹æ•°é‡" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:223 +msgid "Server Name (SNI)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:335 +msgid "Server Node Type" +msgstr "æœåŠ¡å™¨èŠ‚ç‚¹ç±»åž‹" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:438 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:75 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:117 +msgid "Server Port" +msgstr "端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:88 +msgid "Server Setting" +msgstr "æœåŠ¡ç«¯é…ç½®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:58 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:107 +msgid "Server Type" +msgstr "æœåŠ¡ç«¯ç±»åž‹" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:73 +msgid "Server failsafe auto swith and custom update settings" +msgstr "æœåŠ¡å™¨èŠ‚ç‚¹æ•…éšœè‡ªåŠ¨åˆ‡æ¢/广告å±è”½/中国大陆 IP 段数æ®åº“更新设置" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:626 +msgid "Servers Nodes" +msgstr "æœåŠ¡å™¨èŠ‚ç‚¹" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:393 +msgid "Servers subscription and manage" +msgstr "æœåŠ¡å™¨èŠ‚ç‚¹è®¢é˜…ä¸Žç®¡ç†" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1289 +msgid "Session Ticket" +msgstr "会è¯å‡­æ®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:358 +msgid "Shadow-TLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:726 +msgid "Shadow-TLS ChainPoxy type" +msgstr "代ç†é“¾ç±»åž‹" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:343 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:346 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:413 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:61 +msgid "ShadowSocks" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:729 +msgid "ShadowSocks-rust Version" +msgstr "ShadowSocks-rust 版本" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:622 +msgid "ShadowSocksR Plus+" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:51 +msgid "ShadowSocksR Plus+ Settings" +msgstr "ShadowSocksR Plus+ 设置" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:405 +msgid "ShadowTLS" +msgstr "ShadowTLS" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:373 +msgid "Shadowsocks" +msgstr "Shadowsocks" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:166 +msgid "Shadowsocks Password" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:737 +msgid "Shadowsocks password" +msgstr "shadowsocks密ç " + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:383 +msgid "Shadowsocks-rust" +msgstr "Shadowsocks-rust" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:381 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:340 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:64 +msgid "ShadowsocksR" +msgstr "ShadowsocksR" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1304 +msgid "Short ID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:134 +msgid "Showing %d-%d of %d nodes" +msgstr "当剿˜¾ç¤ºç¬¬ %d-%d 个节点,共 %d 个" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:685 +msgid "Socket Connected" +msgstr "连接测试" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:420 +msgid "Socks" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:891 +msgid "Socks Version" +msgstr "Socks 版本" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:163 +msgid "Socks protocol auth methods, default:noauth." +msgstr "Socks åè®®çš„è®¤è¯æ–¹å¼ï¼Œé»˜è®¤å€¼ï¼šnoauth。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:361 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:59 +msgid "Socks5" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:163 +msgid "Socks5 Auth Mode" +msgstr "Socks5 è®¤è¯æ–¹å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:175 +msgid "Socks5 Password" +msgstr "Socks5 密ç " + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:170 +msgid "Socks5 User" +msgstr "Socks5 用户å" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm:73 +msgid "Start Detection" +msgstr "开始探测" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:205 +msgid "Starting subscription update..." +msgstr "正在开始更新订阅..." + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:631 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:114 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:116 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:118 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:120 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:224 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:226 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:228 +msgid "Status" +msgstr "状æ€" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm:74 +msgid "Stop Detection" +msgstr "åœæ­¢æŽ¢æµ‹" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:453 +msgid "Subscribe Advanced Settings" +msgstr "订阅高级设置" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:478 +msgid "Subscribe Default Auto-Switch" +msgstr "订阅新节点自动切æ¢è®¾ç½®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:459 +msgid "Subscribe Filter Words" +msgstr "订阅节点关键字过滤" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:250 +msgid "Subscribe Log" +msgstr "订阅日志" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:465 +msgid "Subscribe Save Words" +msgstr "订阅节点关键字ä¿ç•™æ£€æŸ¥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:551 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:575 +msgid "Subscribe URL" +msgstr "订阅 URL (支æŒSS/SSR/V2/TROJAN/HY2/TUIC/CLASHç­‰)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe.htm:194 +msgid "Subscribe failed, refreshing page..." +msgstr "订阅失败,正在刷新页é¢..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:480 +msgid "Subscribe new add server default Auto-Switch on" +msgstr "订阅加入的新节点默认开å¯è‡ªåŠ¨åˆ‡æ¢" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:473 +msgid "Subscribe nodes allows insecure connection as TLS client (insecure)" +msgstr "è®¢é˜…èŠ‚ç‚¹å¼ºåˆ¶å¼€å¯ ä¸éªŒè¯TLS客户端è¯ä¹¦ (insecure)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:142 +msgid "Support AdGuardHome and DNSMASQ format list" +msgstr "åŒæ—¶æ”¯æŒ AdGuard Home å’Œ DNSMASQ æ ¼å¼çš„过滤列表" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:607 +msgid "Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5." +msgstr "支æŒå›ºå®šå€¼æˆ–éšæœºèŒƒå›´ï¼ˆå¦‚ 30 或 5-30ï¼‰ï¼Œæœ€å° 5 秒。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:84 +msgid "Switch check cycly(second)" +msgstr "è‡ªåŠ¨åˆ‡æ¢æ£€æŸ¥å‘¨æœŸï¼ˆç§’)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:654 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:71 +msgid "Switch failed." +msgstr "切æ¢å¤±è´¥ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:651 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:68 +msgid "Switched successfully." +msgstr "åˆ‡æ¢æˆåŠŸã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:644 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:61 +msgid "Switching..." +msgstr "正在切æ¢..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:282 +msgid "TCP Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:709 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1623 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:126 +msgid "TCP Fast Open" +msgstr "TCP 快速打开" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:228 +msgid "" +"TCP fragments, which can deceive the censorship system in some cases, such " +"as bypassing SNI blacklists." +msgstr "TCP 分片,在æŸäº›æƒ…况下å¯ä»¥æ¬ºéª—审查系统,比如绕过 SNI 黑åå•。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:194 +msgid "TCP upstream" +msgstr "TCP 上游" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1275 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:199 +msgid "TLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:704 +msgid "TLS 1.3 Strict mode" +msgstr "TLS 1.3 é™å®šæ¨¡å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1397 +msgid "TLS ALPN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1453 +msgid "TLS Certificate Name (CertName)" +msgstr "TLS è¯ä¹¦å称(CertName)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1448 +msgid "TLS Chain Fingerprint (SHA256)" +msgstr "TLS è¯ä¹¦é“¾æŒ‡çº¹ï¼ˆSHA256)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1389 +msgid "TLS Host" +msgstr "TLS 主机å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1453 +msgid "TLS is used to verify the leaf certificate name." +msgstr "TLS ç”¨äºŽéªŒè¯ leaf è¯ä¹¦çš„ name。" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:379 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:355 +msgid "TUIC" +msgstr "TUIC" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1409 +msgid "TUIC ALPN" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:769 +msgid "TUIC Server IP Address" +msgstr "TUIC æœåС噍 IP 地å€" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:776 +msgid "TUIC User Password" +msgstr "TUIC 用户密钥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:762 +msgid "TUIC User UUID" +msgstr "TUIC 用户 uuid" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:827 +msgid "TUIC receive window" +msgstr "接收窗å£ï¼ˆæ— éœ€ç¡®è®¤å³å¯æŽ¥æ”¶çš„æœ€å¤§å­—节数:默认8Mb)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:821 +msgid "TUIC send window" +msgstr "å‘é€çª—å£ï¼ˆæ— éœ€ç¡®è®¤å³å¯å‘é€çš„æœ€å¤§å­—节数:默认8Mb*2)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1376 +msgid "" +"The client has not configured mldsa65Verify, but it will not perform the " +"\"additional verification\" step and can still connect normally, see:" +msgstr "" +"客户端若未é…ç½® mldsa65Verify,但它ä¸ä¼šæ‰§è¡Œ \"附加验è¯\" 步骤,ä»å¯ä»¥æ­£å¸¸è¿ž" +"接,具体请å‚è§ï¼š" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/reset.htm:10 +msgid "The content entered is incorrect!" +msgstr "è¾“å…¥çš„å†…å®¹ä¸æ­£ç¡®ï¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:686 +msgid "The keep-alive period.(Unit:second)" +msgstr "心跳包å‘é€é—´éš”(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:6 +msgid "" +"The online upgrade downloads the matching Xray-core linux archive for the " +"current ARCH from the official GitHub release page." +msgstr "" +"在线å‡çº§ä¼šæ ¹æ®å½“剿ž¶æž„,从 Xray-core 官方 GitHub å‘布页下载匹é…çš„ Linux 压缩" +"包。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:10 +msgid "" +"The online upgrade only tracks the latest stable Mihomo release and " +"downloads the matching linux archive for the current ARCH from the official " +"GitHub release page." +msgstr "" +"在线å‡çº§åªè·Ÿè¸ª Mihomo 最新稳定版,并根æ®å½“剿ž¶æž„从官方 GitHub å‘布页下载匹é…" +"çš„ Linux 压缩包。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:14 +msgid "" +"The online upgrade tracks the latest NaiveProxy release and prefers OpenWrt " +"static archives matching the current ARCH before falling back to other " +"release assets." +msgstr "" +"在线å‡çº§ä¼šè·Ÿè¸ªæœ€æ–° NaiveProxy å‘å¸ƒç‰ˆï¼Œå¹¶ä¼˜å…ˆé€‰æ‹©ä¸Žå½“å‰æž¶æž„匹é…çš„ OpenWrt " +"static 压缩包,找ä¸åˆ°æ—¶å†å›žé€€åˆ°å…¶ä»–å‘布资产。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:740 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:795 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:89 +msgid "This Clash total node is not active. Apply this node first." +msgstr "该 Clash æ€»èŠ‚ç‚¹å½“å‰æœªå¯ç”¨ï¼Œè¯·å…ˆåº”用该节点。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel.htm:6 +msgid "" +"This panel is available only when the current Clash total node is active." +msgstr "è¯¥é¢æ¿ä»…åœ¨å½“å‰ Clash 总节点已å¯ç”¨æ—¶å¯ç”¨ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_table.htm:272 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:126 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:277 +msgid "This section contains no values yet" +msgstr "è¯¥éƒ¨åˆ†ç›®å‰æ— ä»»ä½•内容。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:485 +msgid "Through proxy update" +msgstr "é€šè¿‡ä»£ç†æ›´æ–°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:487 +msgid "Through proxy update list, Not Recommended" +msgstr "é€šè¿‡è·¯ç”±å™¨è‡ªèº«ä»£ç†æ›´æ–°è®¢é˜…" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm:78 +msgid "Timeout" +msgstr "è¶…æ—¶" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:803 +msgid "Timeout for establishing a connection to server(second)" +msgstr "连接超时时间(å•ä½ï¼šç§’)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:260 +msgid "To send noise packets, select \"Noise\" in Xray Settings." +msgstr "在 Xray 设置中勾选 “噪声†以å‘é€å™ªå£°åŒ…。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/refresh.htm:18 +msgid "Total Records:" +msgstr "新的总记录数:" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:900 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:177 +msgid "Transport" +msgstr "传输åè®®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:600 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:238 +msgid "Transport Protocol" +msgstr "传输åè®®" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:399 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:412 +msgid "Trojan" +msgstr "Trojan" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:160 +msgid "Trojan Password" +msgstr "Trojan 密ç " + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm:79 +msgid "Try Count" +msgstr "é‡è¯•次数" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:282 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:674 +msgid "Type" +msgstr "类型" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:602 +msgid "UDP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:255 +msgid "" +"UDP noise, Under some circumstances it can bypass some UDP based protocol " +"restrictions." +msgstr "UDP 噪声,在æŸäº›æƒ…况下å¯ä»¥ç»•过一些针对 UDP å议的é™åˆ¶ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:502 +msgid "UDP over TCP" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:782 +msgid "UDP relay mode" +msgstr "UDP 中继模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:195 +msgid "UDP upstream" +msgstr "UDP 上游" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:193 +msgid "UDP/TCP upstream" +msgstr "UDP/TCP 上游" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:30 +msgid "UL Restore" +msgstr "上传æ¢å¤" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:524 +msgid "URL Test Address" +msgstr "URL 测试地å€" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:153 +msgid "UUID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:92 +msgid "Unable to copy SSR to clipboard." +msgstr "无法å¤åˆ¶ SSR 网å€åˆ°å‰ªè´´æ¿ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:32 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua:42 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:109 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:110 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:111 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:226 +msgid "Unknown" +msgstr "未知" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:80 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:82 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:130 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:215 +msgid "Unknown error" +msgstr "未知错误" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:36 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:76 +msgid "Unsupported ARCH" +msgstr "䏿”¯æŒå½“剿ž¶æž„" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:79 +msgid "Unsupported component" +msgstr "䏿”¯æŒçš„组件" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:265 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:266 +msgid "Update" +msgstr "æ›´æ–°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:497 +msgid "Update All Subscribe Servers" +msgstr "更新所有订阅节点" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:447 +msgid "Update Interval(min)" +msgstr "更新间隔(分钟)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:411 +msgid "Update Mode" +msgstr "更新模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:418 +msgid "Update cycle (Day/Week)" +msgstr "更新周期(天/周)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:29 +msgid "" +"Update geoip.dat and geosite.dat used by Xray/V2Ray runtime when available." +msgstr "æ›´æ–° Xray/V2Ray è¿è¡Œæ—¶å¯ç”¨çš„ geoip.dat å’Œ geosite.dat æ•°æ®åº“。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:21 +msgid "" +"Update the Country.mmdb database used by Mihomo/Clash runtime when available." +msgstr "æ›´æ–° Mihomo/Clash è¿è¡Œæ—¶å¯ç”¨çš„ Country.mmdb æ•°æ®åº“。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:25 +msgid "" +"Update the GeoSite.dat database used by Mihomo/Clash runtime when available." +msgstr "æ›´æ–° Mihomo/Clash è¿è¡Œæ—¶å¯ç”¨çš„ GeoSite.dat æ•°æ®åº“。" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/subscribe_actions_footer.htm:31 +msgid "Updating..." +msgstr "更新中..." + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:157 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:406 +msgid "Upgrade" +msgstr "å‡çº§" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:118 +msgid "Upgrade available" +msgstr "å‘现å¯å‡çº§ç‰ˆæœ¬" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:35 +msgid "Upgrade completed" +msgstr "å‡çº§å®Œæˆ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:146 +msgid "Upgrading..." +msgstr "å‡çº§ä¸­..." + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1162 +msgid "Uplink Capacity(Default:Mbps)" +msgstr "上行链路容é‡ï¼ˆé»˜è®¤ï¼šMbps)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1583 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/certupload.htm:3 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_yaml_upload.htm:3 +msgid "Upload" +msgstr "上传" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:544 +msgid "Upload Custom YAML File" +msgstr "上传自定义 YAML 文件" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:546 +msgid "" +"Upload a custom Clash/Mihomo YAML file. The file will be preprocessed and " +"saved as a local Clash node." +msgstr "" +"上传自定义 Clash/Mihomo YAML 文件。文件会先åšé¢„处ç†ï¼Œå†ä¿å­˜ä¸ºæœ¬åœ° Clash 节" +"点。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:263 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:271 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:276 +msgid "Uploaded YAML validation or preprocessing failed." +msgstr "上传的 YAML 校验或预处ç†å¤±è´¥ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:128 +msgid "Use ChinaDNS-NG query and cache" +msgstr "使用 ChinaDNS-NG 查询并缓存" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:201 +msgid "Use DNS from WAN" +msgstr "使用 WAN 下å‘çš„ DNS" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:202 +msgid "Use DNS from WAN and 114DNS" +msgstr "使用 WAN 下å‘çš„ DNS å’Œ 114DNS" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:122 +msgid "Use DNS2TCP query" +msgstr "使用 DNS2TCP 查询" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:131 +msgid "Use Local DNS Service listen port 5335" +msgstr "使用本机端å£ä¸º 5335 çš„ DNS æœåŠ¡" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:125 +msgid "Use MosDNS query" +msgstr "使用 MosDNS 查询" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1152 +msgid "" +"Use it together with the DNS disguised type. You can fill in any domain." +msgstr "é…åˆä¼ªè£…类型 DNS 使用,å¯éšä¾¿å¡«ä¸€ä¸ªåŸŸå。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:142 +msgid "User Level" +msgstr "用户等级" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:104 +msgid "User cancelled." +msgstr "ç”¨æˆ·å·²å–æ¶ˆã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1224 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:534 +msgid "User-Agent" +msgstr "用户代ç†(User-Agent)" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:313 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm:1028 +msgid "Userinfo format error." +msgstr "ç”¨æˆ·ä¿¡æ¯æ ¼å¼é”™è¯¯ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:459 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:89 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:122 +msgid "Username" +msgstr "用户å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:576 +msgid "Users Authentication" +msgstr "用户验è¯" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:371 +msgid "Using incorrect encryption mothod may causes service fail to start" +msgstr "è¾“å…¥ä¸æ­£ç¡®çš„傿•°ç»„åˆå¯èƒ½ä¼šå¯¼è‡´æœåŠ¡æ— æ³•å¯åЍ" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:28 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:430 +msgid "V2Ray GEO Databases" +msgstr "V2Ray GEO æ•°æ®åº“" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:337 +msgid "V2Ray/XRay" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:409 +msgid "V2Ray/XRay protocol" +msgstr "V2Ray/XRay åè®®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:410 +msgid "VLESS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:872 +msgid "VLESS Encryption" +msgstr "VLESS 加密" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:411 +msgid "VMess" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1133 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1143 +msgid "VideoCall (SRTP)" +msgstr "视频通è¯ï¼ˆSRTP)" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:732 +msgid "Vmess Protocol" +msgstr "VMESS åè®®" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:747 +msgid "Vmess UUID" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:864 +msgid "Vmess/VLESS ID (UUID)" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:26 +msgid "WAN Force Proxy IP" +msgstr "强制走代ç†çš„ WAN IP" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:21 +msgid "WAN IP AC" +msgstr "WAN IP 访问控制" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua:23 +msgid "WAN White List IP" +msgstr "ä¸èµ°ä»£ç†çš„ WAN IP" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:937 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:252 +msgid "WebSocket Host" +msgstr "WebSocket 主机å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:943 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:259 +msgid "WebSocket Path" +msgstr "WebSocket 路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1135 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1145 +msgid "WechatVideo" +msgstr "微信视频通è¯" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1185 +msgid "When enabled, it occupies IPv6 routing table 1023." +msgstr "å¯ç”¨åŽï¼Œå°†å ç”¨ IPv6 路由表 1023。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:388 +msgid "When selected, it can be accessed from LAN. This may not be safe!" +msgstr "一旦选定,å³å¯é€šè¿‡å±€åŸŸç½‘进行访问。但这样åšå¯èƒ½å­˜åœ¨å®‰å…¨éšæ‚£ï¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:379 +msgid "" +"When selected, it can only be accessed locally. Recommended when using " +"reverse proxies." +msgstr "一旦å¯ç”¨ï¼Œå®ƒåªèƒ½åœ¨æœ¬åœ°è¿›è¡Œè®¿é—®ã€‚在使用“åå‘代ç†â€æ—¶å»ºè®®ä½¿ç”¨æ­¤åŠŸèƒ½ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:415 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1137 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1147 +msgid "WireGuard" +msgstr "WireGuard æ•°æ®åŒ…" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1217 +msgid "Wireguard allows only traffic from specific source IP." +msgstr "Wireguard ä»…å…è®¸ç‰¹å®šæº IP çš„æµé‡ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1003 +msgid "XHTTP Extra" +msgstr "XHTTP 附加项" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:991 +msgid "XHTTP Host" +msgstr "XHTTP 主机å" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:982 +msgid "XHTTP Mode" +msgstr "XHTTP 模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:997 +msgid "XHTTP Path" +msgstr "XHTTP 路径" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:207 +msgid "XTLS" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua:394 +msgid "Xray" +msgstr "Xray" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:225 +msgid "Xray Fragment Settings" +msgstr "Xray 分片设置" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:258 +msgid "Xray Noise Packets" +msgstr "Xray 噪声数æ®åŒ…" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:5 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:394 +msgid "Xray-core" +msgstr "Xray-core" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:275 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:20 +msgid "YAML Reload Failed!" +msgstr "YAML é‡è½½å¤±è´¥ï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_main_panel.htm:272 +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/clash_panel_button.htm:17 +msgid "YAML Reloaded!" +msgstr "YAML å·²é‡è½½ï¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:137 +msgid "adblock_url" +msgstr "广告å±è”½æ›´æ–° URL" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1121 +msgid "aes-128-gcm" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1517 +msgid "allow" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1511 +msgid "allow: Allows use Mux connection." +msgstr "allow:å…许走 Mux 连接。" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1431 +msgid "allowInsecure" +msgstr "å…许ä¸å®‰å…¨è¿žæŽ¥" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1216 +msgid "allowedIPs(optional)" +msgstr "allowedIPs(å¯é€‰ï¼‰" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1332 +msgid "android" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:139 +msgid "anti-AD" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1122 +msgid "chacha20-poly1305" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:116 +msgid "china-operator-ip" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1227 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1328 +msgid "chrome" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1548 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1564 +msgid "comment_tcpcongestion_disable" +msgstr "系统默认值" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1481 +msgid "concurrency" +msgstr "TCP 最大并å‘连接数" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1232 +msgid "curl" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1545 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1561 +msgid "custom_tcpcongestion" +msgstr "连接æœåŠ¡å™¨èŠ‚ç‚¹çš„ TCP 拥塞控制算法" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1338 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1489 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1502 +msgid "disable" +msgstr "ç¦ç”¨" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:228 +msgid "e.g.: /etc/ssl/fullchain.pem" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:233 +msgid "e.g.: /etc/ssl/private.key" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1230 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1333 +msgid "edge" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:124 +msgid "felixonmars/dnsmasq-china-list" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1228 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1329 +msgid "firefox" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1100 +msgid "gRPC Idle Timeout" +msgstr "gPRC 空闲超时" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1073 +msgid "gRPC Mode" +msgstr "gRPC 模å¼" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1067 +msgid "gRPC Service Name" +msgstr "gRPC æœåŠ¡åç§°" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:106 +msgid "gfwlist Update url" +msgstr "GFW 列表更新 URL" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:110 +msgid "gfwlist/gfwlist" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1231 +msgid "golang" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:530 +msgid "gost-plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1331 +msgid "ios" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:540 +msgid "kcptun" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:785 +msgid "lossless UDP relay using QUIC streams" +msgstr "使用 QUIC æµçš„æ— æŸ UDP 中继" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:300 +msgid "mKCP Camouflage Type" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:46 +msgid "mihomo binary not found in archive" +msgstr "压缩包中未找到 mihomo 二进制文件" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:47 +msgid "naive binary not found in archive" +msgstr "压缩包中未找到 naive 二进制文件" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:784 +msgid "native UDP characteristics" +msgstr "原生 UDP 特性" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:492 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1317 +msgid "none" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:524 +msgid "obfs-local" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1335 +msgid "qq" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1336 +msgid "random" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1337 +msgid "randomized" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1516 +msgid "reject" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:539 +msgid "restls" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1229 +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1330 +msgid "safari" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:719 +msgid "shadow-TLS SNI" +msgstr "æœåС噍å称指示" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:536 +msgid "shadow-tls" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:697 +msgid "shadowTLS protocol Version" +msgstr "ShadowTLS å议版本" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1518 +msgid "skip" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1512 +msgid "" +"skip: Not use Mux module to carry UDP 443 traffic, Use original UDP " +"transmission method of proxy protocol." +msgstr "" +"skip:ä¸ä½¿ç”¨ Mux æ¨¡å—æ‰¿è½½ UDP 443 æµé‡ï¼Œå°†ä½¿ç”¨ä»£ç†å议原本的 UDP 传输方å¼ã€‚" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1308 +msgid "spiderX" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:107 +msgid "v2fly/domain-list-community" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:527 +msgid "v2ray-plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua:223 +msgid "valid address:port" +msgstr "有效的地å€:端å£" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:80 +msgid "warning! Please do not reuse the port!" +msgstr "警告ï¼è¯·ä¸è¦é‡å¤ä½¿ç”¨ç«¯å£ï¼" + +#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/component.htm:45 +msgid "xray binary not found in archive" +msgstr "压缩包中未找到 xray 二进制文件" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:533 +msgid "xray-plugin" +msgstr "" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1494 +msgid "xudpConcurrency" +msgstr "UDP 最大并å‘连接数" + +#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1507 +msgid "xudpProxyUDP443" +msgstr "对被代ç†çš„ UDP/443 æµé‡å¤„ç†æ–¹å¼" + +#~ msgid "Are you sure you want to delete subscribe link: %s ? " +#~ msgstr "确定删除此订阅链接:%s å—?" + +#~ msgid "%s Node Use Type" +#~ msgstr "%s 节点使用类型" + +#~ msgid "Drag reorder applies within the current page only." +#~ msgstr "拖拽排åºä»…在当å‰åˆ†é¡µå†…生效。" + +#~ msgid "Anti-pollution DNS Server For Shunt Mode" +#~ msgstr "åˆ†æµæ¨¡å¼ä¸‹çš„访问国外域å DNS æœåС噍" + +#~ msgid "Are you sure to delete this node?" +#~ msgstr "是å¦çœŸçš„è¦åˆ é™¤è¯¥èŠ‚ç‚¹ï¼Ÿ" + +#~ msgid "Auto" +#~ msgstr "自动" + +#~ msgid "ChinaDNS-NG shunt query protocol" +#~ msgstr "ChinaDNS-NG åˆ†æµæŸ¥è¯¢åè®®" + +#~ msgid "Click here to view or manage the DNS list file" +#~ msgstr "ç‚¹å‡»æ­¤å¤„æŸ¥çœ‹æˆ–ç®¡ç† DNS 列表文件" + +#~ msgid "" +#~ "Custom DNS Server (support: IP:Port or tls://IP:Port or https://IP/dns-" +#~ "query and other format)." +#~ msgstr "" +#~ "自定义 DNS æœåŠ¡å™¨ï¼ˆæ”¯æŒæ ¼å¼ï¼šIP:端å£ã€tls://IP:端å£ã€https://IP/dns-query " +#~ "åŠå…¶ä»–æ ¼å¼ï¼‰ã€‚" + +#~ msgid "Customize Netflix IP Url" +#~ msgstr "" +#~ "自定义 Netflix IP 段更新 URL(默认项目地å€ï¼šhttps://github.com/QiuSimons/" +#~ "Netflix_IP)" + +#~ msgid "DNS Query Mode For Shunt Mode" +#~ msgstr "åˆ†æµæ¨¡å¼ä¸‹çš„ DNS 查询模å¼" + +#~ msgid "Defines the upstreams logic mode" +#~ msgstr "定义上游逻辑模å¼" + +#~ msgid "" +#~ "Defines the upstreams logic mode, possible values: load_balance, " +#~ "parallel, fastest_addr (default: load_balance)." +#~ msgstr "" +#~ "定义上游逻辑模å¼ï¼Œå¯é€‰æ‹©å€¼ï¼šè´Ÿè½½å‡è¡¡ã€å¹¶è¡ŒæŸ¥è¯¢ã€æœ€å¿«å“应(默认值:负载å‡" +#~ "衡)。" + +#~ msgid "Disable IPv6 In MosDNS Query Mode (Shunt Mode)" +#~ msgstr "ç¦æ­¢ MosDNS 返回 IPv6 记录 (åˆ†æµæ¨¡å¼)" + +#~ msgid "Disable IPv6 in MOSDNS query mode" +#~ msgstr "ç¦æ­¢ MOSDNS 返回 IPv6 记录" + +#~ msgid "Disable IPv6 query mode" +#~ msgstr "ç¦æ­¢è¿”回 IPv6 记录" + +#~ msgid "Drag to reorder" +#~ msgstr "æ‹–åŠ¨ä»¥é‡æŽ’" + +#~ msgid "Enable Netflix Mode" +#~ msgstr "å¯ç”¨ Netflix åˆ†æµæ¨¡å¼" + +#~ msgid "External Proxy Mode" +#~ msgstr "åˆ†æµæœåŠ¡å™¨ï¼ˆå‰ç½®ï¼‰ä»£ç†" + +#~ msgid "Forward Netflix Proxy through Main Proxy" +#~ msgstr "åˆ†æµæœåС噍æµé‡é€šè¿‡ä¸»æœåŠ¡èŠ‚ç‚¹ä¸­è½¬ä»£ç†è½¬å‘" + +#~ msgid "Game Mode UDP Server" +#~ msgstr "æ¸¸æˆæ¨¡å¼ UDP 中继æœåС噍" + +#~ msgid "Netflix Domain List" +#~ msgstr "Netflix 分æµåŸŸå列表" + +#~ msgid "Netflix IP Data" +#~ msgstr "ã€Netflix IP 段】数æ®åº“" + +#~ msgid "Netflix Node" +#~ msgstr "Netflix åˆ†æµæœåС噍" + +#~ msgid "Network Tunnel" +#~ msgstr "网络隧é“" + +#~ msgid "Network interface to use" +#~ msgstr "使用的网络接å£" + +#~ msgid "No available core (Trojan or Xray) to import this node." +#~ msgstr "没有å¯ç”¨çš„æ ¸å¿ƒï¼ˆTrojan 或 Xray)å¯ä»¥å¯¼å…¥æ­¤èŠ‚ç‚¹ã€‚" + +#~ msgid "Oversea Mode" +#~ msgstr "海外用户回国模å¼" + +#~ msgid "Redirect traffic to this network interface" +#~ msgstr "分æµåˆ°è¿™ä¸ªç½‘络接å£" + +#~ msgid "Client rules exported to CSV text." +#~ msgstr "客户端规则已导出为 CSV 文本。" + +#~ msgid "Client rules imported from CSV text. Click Save to apply." +#~ msgstr "客户端规则已从 CSV 文本导入,请点击ä¿å­˜ç”Ÿæ•ˆã€‚" + +#~ msgid "Same as Global Server" +#~ msgstr "与全局æœåŠ¡å™¨ç›¸åŒ" + +#~ msgid "Save Order" +#~ msgstr "ä¿å­˜å½“å‰é¡ºåº" + +#~ msgid "Save failed!" +#~ msgstr "ä¿å­˜å¤±è´¥ï¼" + +#~ msgid "Saved current page order successfully." +#~ msgstr "ä¿å­˜å½“å‰é¡µé¢é¡ºåºæˆåŠŸã€‚" + +#~ msgid "Saving the new order..." +#~ msgstr "正在ä¿å­˜æ–°çš„顺åºâ€¦" + +#~ msgid "Select DNS parse Mode" +#~ msgstr "选择 DNS è§£æžæ–¹å¼" + +#~ msgid "Server" +#~ msgstr "æœåС噍" + +#~ msgid "Set Single DNS" +#~ msgstr "设置å•个 DNS" + +#~ msgid "Supports only Xray node types." +#~ msgstr "ä»…æ”¯æŒ Xray 类型节点。" + +#~ msgid "TLS handshake test, latency for reference only" +#~ msgstr "TLSæ¡æ‰‹æµ‹è¯•,延时仅供å‚考" + +#~ msgid "Test" +#~ msgstr "测试" + +#~ msgid "Testing..." +#~ msgstr "检测中…" + +#~ msgid "" +#~ "The configured type also applies to the core specified when manually " +#~ "importing nodes." +#~ msgstr "é…ç½®çš„ç±»åž‹åŒæ ·é€‚用于手动导入节点时所指定的核心程åºã€‚" + +#~ msgid "Tips: Dnsproxy DNS Parse List Path:" +#~ msgstr "æç¤ºï¼šDnsproxy çš„ DNS è§£æžåˆ—表路径:" + +#~ msgid "To Bottom" +#~ msgstr "置底" + +#~ msgid "To Top" +#~ msgstr "置顶" + +#~ msgid "Use DNS List File" +#~ msgstr "使用 DNS 列表文件" + +#~ msgid "Use DNS2SOCKS query and cache" +#~ msgstr "使用 DNS2SOCKS 查询并缓存" + +#~ msgid "Use DNS2SOCKS-RUST query and cache" +#~ msgstr "使用 DNS2SOCKS-RUST 查询并缓存" + +#~ msgid "Use MOSDNS query (Not Support Oversea Mode)" +#~ msgstr "使用 MOSDNS 查询 (䏿”¯æŒæµ·å¤–用户回国模å¼)" + +#~ msgid "When disabled shunt mode, will same time stopped shunt service." +#~ msgstr "当åœç”¨åˆ†æµæ¨¡å¼æ—¶ï¼Œå°†åŒæ—¶åœæ­¢åˆ†æµæœåŠ¡ã€‚" + +#~ msgid "When disabled, all AAAA requests are not resolved." +#~ msgstr "当ç¦ç”¨æ—¶ï¼Œä¸è§£æžæ‰€æœ‰ AAAA 请求。" + +#~ msgid "When two or more DNS servers are deployed, enable this function." +#~ msgstr "å½“éƒ¨ç½²ä¸¤å°æˆ–两å°ä»¥ä¸Š DNS æœåŠ¡å™¨æ—¶ï¼Œéœ€è¦å¯ç”¨è¯¥åŠŸèƒ½ã€‚" + +#~ msgid "" +#~ "When use DNS list file, please ensure list file exists and is formatted " +#~ "correctly." +#~ msgstr "当使用 DNS 列表文件时,请确ä¿åˆ—è¡¨æ–‡ä»¶å­˜åœ¨å¹¶ä¸”æ ¼å¼æ­£ç¡®ã€‚" + +#~ msgid "fastest_addr" +#~ msgstr "最快å“应" + +#~ msgid "load_balance" +#~ msgstr "è´Ÿè½½å‡è¡¡" + +#~ msgid "nfip_url" +#~ msgstr "Netflix IP 段更新 URL" + +#~ msgid "parallel" +#~ msgstr "并行查询" + +#~ msgid "Congestion" +#~ msgstr "拥塞控制" + +#~ msgid "Read Buffer Size" +#~ msgstr "读å–缓冲区大å°" + +#~ msgid "TTI" +#~ msgstr "传输时间间隔" + +#~ msgid "Write Buffer Size" +#~ msgstr "写入缓冲区大å°" + +#~ msgid "IP Type" +#~ msgstr "IP 类型" + +#~ msgid "Invalid JSON format" +#~ msgstr "无效的 JSON æ ¼å¼" + +#~ msgid "" +#~ "Virtual NIC TUN of Linux kernel can be used only when system supports and " +#~ "have root permission. If used, IPv6 routing table 1023 is occupied." +#~ msgstr "" +#~ "需è¦ç³»ç»Ÿæ”¯æŒä¸”有 root æƒé™æ‰èƒ½ä½¿ç”¨ Linux å†…æ ¸çš„è™šæ‹Ÿç½‘å¡ TUN,使用åŽä¼šå ç”¨ " +#~ "IPv6 çš„ 1023 å·è·¯ç”±è¡¨ã€‚" + +#~ msgid "Wireguard reserved bytes." +#~ msgstr "Wireguard ä¿ç•™å­—节。" + +#~ msgid "Applying configuration changes… %ds" +#~ msgstr "正在等待é…置被应用… %ds" + +#~ msgid "ShadowSocks Node Use Version" +#~ msgstr "ShadowSocks 节点使用版本" + +#~ msgid "Splithttp Host" +#~ msgstr "SplitHTTP 主机å" + +#~ msgid "Splithttp Path" +#~ msgstr "SplitHTTP 路径" + +#~ msgid "Custom DNS Server for mosdns" +#~ msgstr "MosDNS 自定义 DNS æœåС噍" + +#~ msgid "ShadowSocksR Client" +#~ msgstr "ShadowSocksR 客户端" + +#~ msgid "ShadowSocksR is running" +#~ msgstr "ShadowSocksR 客户端è¿è¡Œä¸­" + +#~ msgid "ShadowSocksR is not running" +#~ msgstr "ShadowSocksR 客户端未è¿è¡Œ" + +#~ msgid "Global Server" +#~ msgstr "全局æœåС噍" + +#~ msgid "ShadowSocksR SOCK5 Proxy is running" +#~ msgstr "ShadowSocksR SOCK5 代ç†è¿è¡Œä¸­" + +#~ msgid "UDP Relay Server" +#~ msgstr "UDP 中继æœåС噍" + +#~ msgid "Servers Setting" +#~ msgstr "æœåС噍é…ç½®" + +#~ msgid "Onetime Authentication" +#~ msgstr "一次验è¯" + +#~ msgid "Authentication type" +#~ msgstr "验è¯ç±»åž‹" + +#~ msgid "" +#~ "NOTE: If the server uses the userpass authentication, the format must be " +#~ "username:password." +#~ msgstr "注æ„: 如果æœåŠ¡å™¨ä½¿ç”¨ userpass 验è¯ï¼Œæ ¼å¼å¿…须是 username:password。" + +#~ msgid "QUIC connection receive window" +#~ msgstr "QUIC 连接接收窗å£" + +#~ msgid "QUIC stream receive window" +#~ msgstr "QUIC æµæŽ¥æ”¶çª—å£" + +#~ msgid "Lazy Start" +#~ msgstr "延迟å¯åЍ" + +#~ msgid "Enable Tunnel(DNS)" +#~ msgstr "å¯ç”¨éš§é“(DNS)转å‘" + +#~ msgid "Tunnel Port" +#~ msgstr "éš§é“(DNS)本地端å£" + +#~ msgid "Forwarding Tunnel" +#~ msgstr "éš§é“(DNS)转å‘地å€" + +#~ msgid "Interfaces - WAN" +#~ msgstr "æŽ¥å£ - WAN" + +#~ msgid "Bypassed IP List" +#~ msgstr "被忽略 IP 列表" + +#~ msgid "NULL - As Global Proxy" +#~ msgstr "留空 - 作为全局代ç†" + +#~ msgid "Bypassed IP" +#~ msgstr "é¢å¤–被忽略 IP" + +#~ msgid "Forwarded IP" +#~ msgstr "å¼ºåˆ¶èµ°ä»£ç† IP" + +#~ msgid "Interfaces - LAN" +#~ msgstr "æŽ¥å£ - LAN" + +#~ msgid "ShadowSocksR Server" +#~ msgstr "ShadowSocksR æœåŠ¡ç«¯" + +#~ msgid "ShadowSocksR Server is running" +#~ msgstr "ShadowSocksR æœåŠ¡ç«¯è¿è¡Œä¸­" + +#~ msgid "ShadowSocksR Server is not running" +#~ msgstr "ShadowSocksR æœåŠ¡ç«¯æœªè¿è¡Œ" + +#~ msgid "Enable Process Monitor" +#~ msgstr "å¯ç”¨è¿›ç¨‹ç›‘控" + +#~ msgid "Running Status" +#~ msgstr "è¿è¡Œçжæ€" + +#~ msgid "Global SSR Server" +#~ msgstr "SSR æœåŠ¡ç«¯" + +#~ msgid "DNS Tunnel" +#~ msgstr "DNS éš§é“" + +#~ msgid "IPK Version" +#~ msgstr "IPK 版本å·" + +#~ msgid "IPK Installation Time" +#~ msgstr "IPK 安装时间" + +#~ msgid "Project" +#~ msgstr "项目地å€" + +#~ msgid "Enable GFW mode" +#~ msgstr "å¯ç”¨ GFW 模å¼" + +#~ msgid "Router Proxy" +#~ msgstr "路由器访问控制" + +#~ msgid "Bypassed Proxy" +#~ msgstr "ä¸èµ°ä»£ç†" + +#~ msgid "Forwarded Proxy" +#~ msgstr "强制走代ç†" + +#~ msgid "UDP Relay" +#~ msgstr "UDP 中继" + +#~ msgid "Check" +#~ msgstr "检查" + +#~ msgid "Proxy Check" +#~ msgstr "ä»£ç†æ£€æŸ¥" + +#~ msgid "Enable Process Deamon" +#~ msgstr "å¯ç”¨è¿›ç¨‹è‡ªåŠ¨å®ˆæŠ¤" + +#~ msgid "DNS Server IP and Port" +#~ msgstr "DNS æœåŠ¡å™¨åœ°å€å’Œç«¯å£" + +#~ msgid "Use SSR DNS Tunnel" +#~ msgstr "使用 SSR DNS éš§é“" + +#~ msgid "Use Other DNS Tunnel(Need to install)" +#~ msgstr "使用其他 DNS 转å‘(需è¦è‡ªå·±å®‰è£…)" + +#~ msgid "Export SSR" +#~ msgstr "导出 SSR é…置信æ¯" + +#~ msgid "Servers Manage" +#~ msgstr "æœåŠ¡å™¨ç®¡ç†" + +#~ msgid "GFW List" +#~ msgstr "GFW 列表" + +#~ msgid "Use MOSDNS query" +#~ msgstr "使用 MOSDNS 查询" + +#~ msgid "DNS Server IP:Port" +#~ msgstr "DNS æœåС噍 IP:Port" + +#~ msgid "Router Self AC" +#~ msgstr "路由器自身代ç†è®¾ç½®" + +#~ msgid "Router Self Proxy" +#~ msgstr "è·¯ç”±å™¨è‡ªèº«ä»£ç†æ–¹å¼" + +#~ msgid "Normal Proxy" +#~ msgstr "è·Ÿéšå…¨å±€è®¾ç½®" + +#~ msgid "GFW Custom List" +#~ msgstr "GFW 用户自定义列表" + +#~ msgid "Please refer to the following writing" +#~ msgstr "æ¯è¡Œä¸€ä¸ªåŸŸå,无需写å‰é¢çš„ http(s)://,æäº¤åŽå³æ—¶ç”Ÿæ•ˆ" + +#~ msgid "Plugin" +#~ msgstr "æ’ä»¶" + +#~ msgid "upload" +#~ msgstr "上传" + +#~ msgid "SOCKS5 Proxy Server Settings" +#~ msgstr "SOCKS5 ä»£ç†æœåŠ¡ç«¯è®¾ç½®" + +#~ msgid "SOCKS5 Proxy Server" +#~ msgstr "SOCKS5 ä»£ç†æœåŠ¡ç«¯" + +#~ msgid "Enable SOCKS5 Proxy Server" +#~ msgstr "å¯ç”¨ SOCKS5 ä»£ç†æœåŠ¡" + +#~ msgid "Enable WAN Access" +#~ msgstr "å…许从 WAN 访问" + +#~ msgid "Netflix IP List" +#~ msgstr "Netflix 分æµIP列表" + +#~ msgid "Reset Error" +#~ msgstr "é‡ç½®é”™è¯¯" + +#~ msgid "Selector" +#~ msgstr "选择器" + +#~ msgid "DIRECT" +#~ msgstr "直连" + +#~ msgid "REJECT" +#~ msgstr "æ‹’ç»" + +#~ msgid "Proxy" +#~ msgstr "代ç†" + +#~ msgid "Domestic" +#~ msgstr "国内" + +#~ msgid "GlobalTV" +#~ msgstr "国际æµåª’体" + +#~ msgid "AsianTV" +#~ msgstr "亚洲æµåª’体" + +#~ msgid "Others" +#~ msgstr "å…¶ä»–" + +#~ msgid "GLOBAL" +#~ msgstr "全局" + +#~ msgid "Subscribe complete, refreshing page..." +#~ msgstr "订阅完æˆï¼Œæ­£åœ¨åˆ·æ–°é¡µé¢..." + +#~ msgid "Include Mihomo (Clash Support)" +#~ msgstr "åŒ…å« Mihomo(Clash 支æŒï¼‰" diff --git a/luci-app-ssr-plus/root/etc/config/shadowsocksr b/luci-app-ssr-plus/root/etc/config/shadowsocksr new file mode 100644 index 00000000..e69de29b diff --git a/luci-app-ssr-plus/root/etc/hotplug.d/iface/99-ssrplus-pppoe b/luci-app-ssr-plus/root/etc/hotplug.d/iface/99-ssrplus-pppoe new file mode 100644 index 00000000..fc969f71 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/hotplug.d/iface/99-ssrplus-pppoe @@ -0,0 +1,22 @@ +#!/bin/sh + +[ "$ACTION" = "ifup" ] || exit 0 +[ "$INTERFACE" = "wan" ] || exit 0 + +WAN_PROTO="$(uci -q get network.wan.proto 2>/dev/null)" +[ "$WAN_PROTO" = "pppoe" ] || exit 0 + +LOCK_FILE="/var/run/ssrplus-pppoe-hotplug.lock" + +( + if ! mkdir "$LOCK_FILE" 2>/dev/null; then + exit 0 + fi + + trap 'rmdir "$LOCK_FILE" 2>/dev/null' EXIT INT TERM + + sleep 10 + /etc/init.d/shadowsocksr restart >/dev/null 2>&1 +) >/dev/null 2>&1 & + +exit 0 diff --git a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr new file mode 100755 index 00000000..1970fa94 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -0,0 +1,2453 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# Copyright (C) 2018 lean +# Copyright (C) 2020 Mattraks +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +START=95 +STOP=15 +SERVICE_DAEMONIZE=1 +NAME=shadowsocksr +LOCK_FILE=/var/lock/ssrplus.lock +LOG_FILE=/var/log/ssrplus.log +TMP_PATH=/var/etc/ssrplus +TMP_BIN_PATH=$TMP_PATH/bin +PERSIST_DIR="/usr/share/nftables.d/ruleset-post" +PERSIST_FILE="$PERSIST_DIR/99-shadowsocksr.nft" +BACKUP_DIR="/etc/ssrplus/ssrplus-persist" +BACKUP_FILE="$BACKUP_DIR/99-shadowsocksr.save" +CLASH_CONFIG_DIR="/etc/ssrplus/clash" +CLASH_API_PORT="16756" +CLASH_OUTBOUND_MARK="255" +CLASH_YAML_HELPER="/usr/share/shadowsocksr/clash_yaml.lua" +# 设置 DNSMASQ_CONF_DIR å’Œ TMP_DNSMASQ_PATH +if [ -f /etc/openwrt_release ]; then + # 获å–默认的 DNSMASQ é…ç½® ID + DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')" + # 从 conf-dir 行中æå–é…置目录路径 + if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then + DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")" + else + DNSMASQ_CONF_DIR="/tmp/dnsmasq.d" + fi + # 设置 TMP_DNSMASQ_PATHï¼Œå¹¶åŽ»é™¤è·¯å¾„æœ«å°¾çš„æ–œæ  + TMP_DNSMASQ_PATH="${DNSMASQ_CONF_DIR%*/}/dnsmasq-ssrplus.d" +fi + +chain_config_file= #generate shadowtls chain proxy config file +tcp_config_file= +udp_config_file= +shunt_config_file= +local_config_file= +shunt_dns_config_file= +tmp_local_port= +DNS2TCP_FILTER_AAAA_SUPPORTED= + +ARG_UDP= +ARG_UDP_RULES= + +dns_port="5335" #dns port +china_dns_port="5333" #china_dns_port +tmp_dns_port="300" #dns2socks temporary port +tmp_udp_port="301" #udp temporary port +tmp_udp_local_port="302" #udp socks temporary port +tmp_shunt_port="303" #shunt temporary port +tmp_shunt_local_port="304" #shunt socks temporary port +tmp_shunt_dns_port="305" #shunt dns2socks temporary port +tmp_tcp_local_port="306" #tcp socks temporary port + +server_count=0 +redir_tcp=0 +redir_udp=0 +local_enable=0 +http_enable=0 +kcp_enable_flag=0 +pdnsd_enable_flag=0 + +USE_TABLES="" +HAS_NFT=0 +HAS_IPSET=0 +HAS_IPT=0 +HAS_FW3=0 +HAS_FW4=0 +DNSMASQ_IPSET=0 +DNSMASQ_NFTSET=0 + +switch_server=$1 +CRON_FILE=/etc/crontabs/root +EXTRA_COMMANDS='reset clash_cache' +EXTRA_HELP=" reset Reset to default settings + clash_cache Download and cache Clash node config" +#extra_command "reset" "Reset to default settings" +PS="/bin/busybox ps" + +ps_list() { + if $PS -w >/dev/null 2>&1; then + $PS -w + else + $PS + fi +} + +uci_get_by_name() { + local ret=$(uci get $NAME.$1.$2 2>/dev/null) + echo ${ret:=$3} +} + +uci_get_by_type() { + local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null) + echo "${ret:=$3}" +} + +uci_set_by_name() { + uci set $NAME.$1.$2=$3 2>/dev/null + uci commit $NAME +} + +uci_set_by_type() { + uci set $NAME.@$1[0].$2=$3 2>/dev/null + uci commit $NAME +} + +uci_get_by_cfgid() { + local key="$NAME.@$1[0]" + [ -n "$2" ] && key="$key.$2" + local ret=$(uci show "$key" 2>/dev/null | awk -F '[.=]' 'NR==1 {print $2}') + echo ${ret:=$3} +} + +get_filter_aaaa() { + local ret="$(uci get $NAME.@global[0].filter_aaaa 2>/dev/null)" + [ -z "$ret" ] && ret="$(uci get $NAME.@global[0].mosdns_ipv6 2>/dev/null)" + echo "${ret:=1}" +} + +supports_dns2tcp_filter_aaaa() { + local dns2tcp_bin="${1:-$(first_type dns2tcp)}" + + [ -n "$dns2tcp_bin" ] || return 1 + + if [ -n "$DNS2TCP_FILTER_AAAA_SUPPORTED" ]; then + [ "$DNS2TCP_FILTER_AAAA_SUPPORTED" = "1" ] + return $? + fi + + if "$dns2tcp_bin" -h 2>&1 | grep -Eq '(^|[[:space:]])-A([[:space:]]|$)'; then + DNS2TCP_FILTER_AAAA_SUPPORTED=1 + return 0 + fi + + DNS2TCP_FILTER_AAAA_SUPPORTED=0 + return 1 +} + +start_dns2tcp() { + local dnsserver="$1" + local dns2tcp_bin="$(first_type dns2tcp)" + + if [ "$(get_filter_aaaa)" = "1" ]; then + if supports_dns2tcp_filter_aaaa "$dns2tcp_bin"; then + ln_start_bin "$dns2tcp_bin" dns2tcp -L "127.0.0.1#$dns_port" -R "${dnsserver/:/#}" -A + else + echolog "è­¦å‘Šï¼šå½“å‰ dns2tcp 䏿”¯æŒ AAAA è¿‡æ»¤å‚æ•°(-A),已改为ä¸å¸¦è¯¥å‚æ•°å¯åŠ¨ã€‚è¯·å‡çº§ dns2tcp 版本。" + ln_start_bin "$dns2tcp_bin" dns2tcp -L "127.0.0.1#$dns_port" -R "${dnsserver/:/#}" + fi + else + ln_start_bin "$dns2tcp_bin" dns2tcp -L "127.0.0.1#$dns_port" -R "${dnsserver/:/#}" + fi +} + +supports_builtin_dns() { + case "$1" in + clash|tuic|v2ray|ss) + return 0 + ;; + *) + return 1 + ;; + esac +} + +get_builtin_dns_fallback_mode() { + if is_finded "dns2tcp"; then + echo "1" + elif is_finded "chinadns-ng"; then + echo "6" + elif is_finded "mosdns"; then + echo "4" + else + echo "0" + fi +} + +get_dns2tcp_fallback_mode() { + if is_finded "dns2tcp"; then + echo "1" + else + echo "0" + fi +} + +force_dns2tcp_fallback() { + local reason="$1" + local fallback_mode="$(get_dns2tcp_fallback_mode)" + + if [ "$fallback_mode" = "1" ]; then + echolog "æç¤ºï¼š${reason},强制回退到 dns2tcp 模å¼ã€‚" + echo "1" + return 0 + fi + + echolog "错误:${reason},且未安装 dns2tcp,å¯åŠ¨ç»ˆæ­¢ã€‚" + return 1 +} + +is_builtin_dns_active() { + local global_server_type="$(uci_get_by_name "$GLOBAL_SERVER" type)" + case "$global_server_type" in + clash|tuic|ss) + ps_list | grep -v "grep" | grep -q "ssr-retcp" + ;; + v2ray) + ps_list | grep -v "grep" | grep -q "$TMP_PATH/.*ssr-retcp\\.json" + ;; + *) + return 1 + ;; + esac +} + +get_default_node_local_port() { + uci_get_by_type global default_node_local_port 1234 +} + +get_configured_threads() { + local threads + if [ "$(uci_get_by_type global threads 0)" = "0" ]; then + threads=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null) + else + threads=$(uci_get_by_type global threads 1) + fi + + case "$threads" in + ''|*[!0-9]*) + threads=1 + ;; + esac + + [ "$threads" -lt 1 ] && threads=1 + echo "$threads" +} + +get_clash_api_secret() { + echo "${1}_ssrplus_clash" +} + +get_clash_workdir() { + echo "$TMP_PATH/clash-$1" +} + +get_clash_cache_file() { + echo "$CLASH_CONFIG_DIR/$1.yaml" +} + +get_clash_state_file() { + echo "$CLASH_CONFIG_DIR/$1.cache.db" +} + +get_tuic_workdir() { + echo "$TMP_PATH/tuic-$1" +} + +get_tuic_runtime_file() { + echo "$(get_tuic_workdir "$1")/config.yaml" +} + +get_ss_mihomo_workdir() { + echo "$TMP_PATH/ss-$1" +} + +get_ss_mihomo_runtime_file() { + echo "$(get_ss_mihomo_workdir "$1")/config.yaml" +} + +get_ss_server_mihomo_workdir() { + echo "$TMP_PATH/ss-server-$1" +} + +get_ss_server_mihomo_runtime_file() { + echo "$(get_ss_server_mihomo_workdir "$1")/config.yaml" +} + +link_mihomo_geodata() { + local workdir="$1" + + [ -n "$workdir" ] || return 0 + + [ -s /usr/share/shadowsocksr/Country.mmdb ] && ln -sf /usr/share/shadowsocksr/Country.mmdb "$workdir/Country.mmdb" + [ -s /usr/share/shadowsocksr/Country.mmdb ] && ln -sf /usr/share/shadowsocksr/Country.mmdb "$workdir/geoip.metadb" + [ ! -e "$workdir/Country.mmdb" ] && [ -s /etc/openclash/Country.mmdb ] && ln -sf /etc/openclash/Country.mmdb "$workdir/Country.mmdb" + [ ! -e "$workdir/geoip.metadb" ] && [ -s /etc/openclash/Country.mmdb ] && ln -sf /etc/openclash/Country.mmdb "$workdir/geoip.metadb" + + if [ -s /usr/share/v2ray/geosite.dat ]; then + ln -sf /usr/share/v2ray/geosite.dat "$workdir/GeoSite.dat" + ln -sf /usr/share/v2ray/geosite.dat "$workdir/geosite.dat" + else + [ -s /etc/openclash/GeoSite.dat ] && ln -sf /etc/openclash/GeoSite.dat "$workdir/GeoSite.dat" + [ -s /etc/openclash/geosite.dat ] && ln -sf /etc/openclash/geosite.dat "$workdir/geosite.dat" + fi + + if [ -s /usr/share/v2ray/geoip.dat ]; then + ln -sf /usr/share/v2ray/geoip.dat "$workdir/geoip.dat" + else + [ -s /etc/openclash/geoip.dat ] && ln -sf /etc/openclash/geoip.dat "$workdir/geoip.dat" + fi +} + +prepare_tuic_runtime_config() { + local sid="$1" + local local_port="$2" + local socks_port="$3" + local instance_key="${4:-$sid}" + local run_mode="${5:-redir}" + local runtime_file="$(get_tuic_runtime_file "$instance_key")" + local workdir="$(get_tuic_workdir "$instance_key")" + + [ -n "$sid" ] || return 1 + [ -n "$local_port" ] || return 1 + + mkdir -p "$workdir" + if ! /usr/bin/lua "$CLASH_YAML_HELPER" tuic "$sid" "$runtime_file" "$local_port" "$socks_port" "$run_mode" >/dev/null 2>&1; then + echolog "TUIC 节点è¿è¡Œé…置生æˆå¤±è´¥ï¼š$sid" + return 1 + fi + + # Reuse existing local geodata files so Mihomo does not have to fetch them. + link_mihomo_geodata "$workdir" +} + +prepare_ss_mihomo_runtime_config() { + local sid="$1" + local local_port="$2" + local socks_port="$3" + local instance_key="${4:-$sid}" + local run_mode="${5:-redir}" + local runtime_file="$(get_ss_mihomo_runtime_file "$instance_key")" + local workdir="$(get_ss_mihomo_workdir "$instance_key")" + + [ -n "$sid" ] || return 1 + [ -n "$local_port" ] || return 1 + + mkdir -p "$workdir" + if ! /usr/bin/lua "$CLASH_YAML_HELPER" ss "$sid" "$runtime_file" "$local_port" "$socks_port" "$run_mode" >/dev/null 2>&1; then + echolog "Shadowsocks å•节点 Mihomo è¿è¡Œé…置生æˆå¤±è´¥ï¼š$sid" + return 1 + fi + + link_mihomo_geodata "$workdir" +} + +prepare_ss_server_mihomo_runtime_config() { + local sid="$1" + local runtime_file="$(get_ss_server_mihomo_runtime_file "$sid")" + local workdir="$(get_ss_server_mihomo_workdir "$sid")" + + [ -n "$sid" ] || return 1 + + mkdir -p "$workdir" + if ! /usr/bin/lua "$CLASH_YAML_HELPER" ss_server "$sid" "$runtime_file" >/dev/null 2>&1; then + echolog "Shadowsocks æœåŠ¡ç«¯ Mihomo é…置生æˆå¤±è´¥ï¼š$sid" + return 1 + fi +} + +download_clash_config() { + local sid="$1" + local clash_url="$(uci_get_by_name "$sid" clash_url)" + local clash_path="$(uci_get_by_name "$sid" clash_path)" + local clash_user_agent="$(uci_get_by_name "$sid" clash_user_agent clash)" + local cache_file="$(get_clash_cache_file "$sid")" + local tmp_file="$TMP_PATH/clash-$sid.download.yaml" + + if [ -n "$clash_path" ] && [ -s "$clash_path" ]; then + mkdir -p "$CLASH_CONFIG_DIR" + cp -f "$clash_path" "$cache_file" + echolog "Clash 本地é…置加载æˆåŠŸï¼š$clash_path" + return 0 + fi + + [ -n "$clash_url" ] || { + echolog "Clash 节点未é…置订阅 URL/本地é…置,无法å¯åŠ¨ã€‚" + return 1 + } + + mkdir -p "$CLASH_CONFIG_DIR" + if curl -fsSL --connect-timeout 15 --retry 2 --insecure -A "$clash_user_agent" "$clash_url" -o "$tmp_file"; then + if /usr/bin/lua "$CLASH_YAML_HELPER" validate "$tmp_file" >/dev/null 2>&1; then + mv -f "$tmp_file" "$cache_file" + echolog "Clash é…置下载æˆåŠŸï¼š$clash_url" + return 0 + else + echolog "Clash é…置校验失败:$clash_url" + rm -f "$tmp_file" + fi + else + echolog "Clash é…置下载失败:$clash_url" + fi + + if [ -s "$cache_file" ]; then + echolog "使用缓存的 Clash é…置继续å¯åŠ¨ã€‚" + return 0 + fi + + return 1 +} + +clash_cache() { + local sid="$2" + [ -n "$sid" ] || sid="$1" + [ -n "$sid" ] || return 1 + [ "$(uci_get_by_name "$sid" type)" = "clash" ] || return 1 + mkdir -p "$TMP_PATH" "$CLASH_CONFIG_DIR" + download_clash_config "$sid" +} + +filter_clash_yaml_proxies() { + local yaml_file="$1" + local filter_words="$(uci_get_by_type server_subscribe filter_words '过期时间/剩余æµé‡')" + local names_file="$TMP_PATH/clash-proxy-names.$$" + local removed_file="$TMP_PATH/clash-proxy-removed.$$" + local removed_count=0 + + [ -n "$yaml_file" ] && [ -s "$yaml_file" ] || return 0 + [ -n "$filter_words" ] || return 0 + + if ! /usr/bin/lua "$CLASH_YAML_HELPER" validate "$yaml_file" >/dev/null 2>&1; then + return 0 + fi + + removed_count="$(/usr/bin/lua "$CLASH_YAML_HELPER" filter "$yaml_file" "$filter_words" 2>/dev/null || echo 0)" + if [ -n "$removed_count" ] && [ "$removed_count" -gt 0 ] 2>/dev/null; then + echolog "Clash YAML 共过滤节点数é‡: $removed_count" + fi + + rm -f "$names_file" "$removed_file" +} + +prepare_clash_runtime_config() { + local sid="$1" + local local_port="$2" + local socks_port="$3" + local cache_file="$(get_clash_cache_file "$sid")" + local workdir="$(get_clash_workdir "$sid")" + local raw_file="$workdir/raw.yaml" + local overlay_file="$workdir/overlay.yaml" + local runtime_file="$workdir/config.yaml" + local state_file="$(get_clash_state_file "$sid")" + local merge_stats="" + local filled_groups=0 + local stripped_script_rules=0 + local clash_secret="$(get_clash_api_secret "$sid")" + local dns_ipv4_only="$(get_filter_aaaa)" + local dns_mode="$(uci_get_by_type global pdnsd_enable 0)" + + [ -s "$cache_file" ] || return 1 + + mkdir -p "$workdir" "$CLASH_CONFIG_DIR" + cp -f "$cache_file" "$raw_file" + filter_clash_yaml_proxies "$raw_file" + + cat >"$overlay_file" <<-EOF + redir-port: $local_port + tproxy-port: $local_port + external-controller: 127.0.0.1:$CLASH_API_PORT + secret: $clash_secret + allow-lan: true + bind-address: 0.0.0.0 + routing-mark: $CLASH_OUTBOUND_MARK + profile: + store-selected: true + tun: + enable: false + dns: + enable: $( [ "$dns_mode" = "7" ] && echo "true" || echo "false" ) + enhanced-mode: redir-host + listen: 127.0.0.1:$dns_port + ipv6: $( [ "$dns_ipv4_only" = "1" ] && echo "false" || echo "true" ) + EOF + + if [ -n "$socks_port" ] && [ "$socks_port" != "0" ]; then + echo "socks-port: $socks_port" >>"$overlay_file" + fi + + merge_stats="$(/usr/bin/lua "$CLASH_YAML_HELPER" merge "$raw_file" "$overlay_file" "$runtime_file" 2>/dev/null)" || return 1 + filled_groups="$(printf '%s\n' "$merge_stats" | sed -n 's/.*filled_groups=\([0-9][0-9]*\).*/\1/p' | tail -n1)" + stripped_script_rules="$(printf '%s\n' "$merge_stats" | sed -n 's/.*stripped_script_rules=\([0-9][0-9]*\).*/\1/p' | tail -n1)" + [ -n "$filled_groups" ] || filled_groups=0 + [ -n "$stripped_script_rules" ] || stripped_script_rules=0 + if [ "$filled_groups" -gt 0 ] 2>/dev/null; then + echolog "Clash YAML 兼容修å¤ï¼šå…±ä¸º $filled_groups 个空代ç†ç»„回填 DIRECT。" + fi + if [ "$stripped_script_rules" -gt 0 ] 2>/dev/null; then + echolog "Clash YAML 兼容修å¤ï¼šå…±ç§»é™¤ $stripped_script_rules æ¡ä¸å…¼å®¹çš„ SCRIPT 规则。" + fi + local client_policy_stats="" + local client_rules=0 + client_policy_stats="$(/usr/bin/lua "$CLASH_YAML_HELPER" append_client_policy_rules "$runtime_file" "$sid" 2>/dev/null)" || true + client_rules="$(printf '%s\n' "$client_policy_stats" | sed -n 's/.*client_rules=\([0-9][0-9]*\).*/\1/p' | tail -n1)" + [ -n "$client_rules" ] || client_rules=0 + if [ "$client_rules" -gt 0 ] 2>/dev/null; then + echolog "Clash YAML 自定义客户端代ç†è§„则已注入:$client_rules æ¡ã€‚" + fi + + # Persist Mihomo's store-selected cache across service restarts. + if [ -f "$workdir/cache.db" ] && [ ! -L "$workdir/cache.db" ]; then + if [ ! -e "$state_file" ]; then + mv -f "$workdir/cache.db" "$state_file" + else + rm -f "$workdir/cache.db" + fi + fi + rm -f "$workdir/cache.db" + ln -sf "$state_file" "$workdir/cache.db" + + # Reuse existing local geodata files so Mihomo does not have to fetch them + # during startup in environments where DNS or outbound access is not ready yet. + link_mihomo_geodata "$workdir" +} + +resolve_global_clash_socks_port() { + local socks_enabled=$(uci_get_by_type socks5_proxy enabled 0) + local socks_server=$(uci_get_by_type socks5_proxy server nil) + local socks_port=$(uci_get_by_type socks5_proxy local_port 1080) + local http_enabled=$(uci_get_by_type http_proxy enabled 0) + local http_server=$(uci_get_by_type http_proxy server nil) + local http_port="$socks_port" + local resolved_port="" + + [ "$socks_server" = "same" ] && socks_server="$GLOBAL_SERVER" + [ "$http_server" = "same" ] && http_server="$GLOBAL_SERVER" + + if [ "$socks_enabled" = "1" ] && [ "$socks_server" = "$GLOBAL_SERVER" ]; then + resolved_port="$socks_port" + fi + + if [ "$http_enabled" = "1" ] && [ "$http_server" = "$GLOBAL_SERVER" ]; then + if [ -n "$resolved_port" ] && [ "$resolved_port" != "$http_port" ]; then + echolog "Global_HTTP: Mihomo/Clash 仅支æŒå•个 socks-port,HTTP 代ç†å°†å¤ç”¨å…¨å±€ SOCKS5 ç«¯å£ $resolved_port。" + else + resolved_port="$http_port" + fi + fi + + echo "$resolved_port" +} + +supports_builtin_socks() { + case "$1" in + ss|clash|tuic|v2ray) + return 0 + ;; + *) + return 1 + ;; + esac +} + +supports_builtin_http() { + case "$1" in + clash) + return 0 + ;; + *) + return 1 + ;; + esac +} + +get_host_ip() { + local host=$(uci_get_by_name $1 server) + [ -n "$host" ] || { + echo "" + return + } + host="${host#\[}" + host="${host%\]}" + local ip="" + if echo "$host" | grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$'; then + ip="$host" + elif ! echo "$host" | grep -q ':'; then + ip=$(resolveip -4 -t 3 "$host" | awk 'NR==1{print}') + [ -z "$ip" ] && ip=$(curl -sSL "http://119.29.29.29/d?dn=$host" | awk -F ';' '{print $1}') + fi + [ -z "$ip" ] || uci_set_by_name $1 ip $ip + [ -n "$ip" ] || ip="" + + local chinadns="$(uci_get_by_type global chinadns_forward)" + if [ -n "$chinadns" ] && [ "$ip" != "$host" ]; then + grep -q "$host" "$TMP_DNSMASQ_PATH/chinadns_fixed_server.conf" 2>"/dev/null" || \ + echo -e "address=/$host/$ip" >> "$TMP_DNSMASQ_PATH/chinadns_fixed_server.conf" + fi + + echo $ip +} + +clean_log() { + local logsnum=$(cat $LOG_FILE 2>/dev/null | wc -l) + [ "$logsnum" -gt 1000 ] && { + echo "$(date "+%Y-%m-%d %H:%M:%S") 日志文件过长,清空处ç†ï¼" >$LOG_FILE + } +} + +echolog() { + local d="$(date "+%Y-%m-%d %H:%M:%S")" + echo -e "$d: $*" >>$LOG_FILE +} + +add_cron() { + touch $CRON_FILE + sed -i '/ssrplus.log/d' $CRON_FILE + if [ "$(uci_get_by_type server_subscribe auto_update 0)" -eq 1 ]; then + if [ "$(uci_get_by_type server_subscribe config_auto_update_mode 0)" = "1" ]; then + echo "* * * * * /usr/share/shadowsocksr/ssrplusupdate.sh loop >>$LOG_FILE 2>&1" >>$CRON_FILE + else + echo "$(uci_get_by_type server_subscribe auto_update_min_time) $(uci_get_by_type server_subscribe auto_update_day_time) * * $(uci_get_by_type server_subscribe auto_update_week_time) /usr/share/shadowsocksr/ssrplusupdate.sh >$LOG_FILE" >>$CRON_FILE + fi + fi + crontab $CRON_FILE +} + +del_cron() { + touch $CRON_FILE + sed -i '/ssrplus.log/d' $CRON_FILE + crontab $CRON_FILE + clean_log +} + +set_lock() { + exec 1000>"$LOCK_FILE" + flock -xn 1000 +} + +unset_lock() { + flock -u 1000 + rm -rf "$LOCK_FILE" +} + +unlock() { + failcount=1 + while [ "$failcount" -le 10 ]; do + if [ -f "$LOCK_FILE" ]; then + let "failcount++" + sleep 1s + [ "$failcount" -ge 10 ] && unset_lock + else + break + fi + done +} + +_exit() { + local rc=$1 + unset_lock + exit ${rc} +} + +first_type() { + local candidate + for candidate in "/bin/${1}" "/usr/bin/${1}" "/usr/libexec/${1}" "${TMP_BIN_PATH}/${1}"; do + [ -x "$candidate" ] && { + echo "$candidate" + return 0 + } + done + + command -v "${1}" 2>/dev/null | head -n1 +} + +is_finded() { + [ -n "$(first_type "$1")" ] +} + +has_ss_rust_client_binary() { + [ -n "$(first_type sslocal)" ] +} + +has_ss_rust_server_binary() { + [ -n "$(first_type ssserver)" ] +} + +has_mihomo_binary() { + local mihomo_bin="$(first_type mihomo)" + [ -x "$mihomo_bin" ] +} + +use_mihomo_for_ss_rust_client() { + has_ss_rust_client_binary && return 1 + has_mihomo_binary +} + +use_mihomo_for_ss_rust_server() { + has_ss_rust_server_binary && return 1 + has_mihomo_binary +} + +ln_start_bin() { + local file_func=${1} + local ln_name=${2} + shift 2 + if [ "${file_func%%/*}" != "${file_func}" ]; then + local ln_path="${TMP_BIN_PATH}/${ln_name}" + local src_real="$(readlink -f "${file_func}" 2>/dev/null || echo "${file_func}")" + local dst_real="$(readlink -f "${ln_path}" 2>/dev/null || true)" + if [ ! -L "${ln_path}" ] || [ "${dst_real}" != "${src_real}" ]; then + rm -f "${ln_path}" + ln -s "${file_func}" "${ln_path}" >/dev/null 2>&1 + fi + file_func="${ln_path}" + [ -x "${file_func}" ] || echolog "$(readlink ${file_func}) 没有执行æƒé™ï¼Œæ— æ³•å¯åŠ¨ï¼š${file_func} $*" + fi + #echo "${file_func} $*" >&2 + [ -x "${file_func}" ] || { + echolog "找ä¸åˆ° ${file_func},无法å¯åЍ..." + echolog "-----------end------------" + _exit 2 + } + ulimit -n 1000000 + ${file_func:-echolog " - ${ln_name}"} "$@" >/dev/null 2>&1 & +} + +check_run_environment() { + local dnsmasq_info=$(dnsmasq -v 2>/dev/null) + local dnsmasq_ver=$(echo "$dnsmasq_info" | sed -n '1s/.*version \([0-9.]*\).*/\1/p') + + DNSMASQ_IPSET=0; [[ "$dnsmasq_info" == *" ipset"* ]] && DNSMASQ_IPSET=1 + DNSMASQ_NFTSET=0; [[ "$dnsmasq_info" == *" nftset"* ]] && DNSMASQ_NFTSET=1 + HAS_IPT=0; { command -v iptables-legacy || command -v iptables; } >/dev/null && HAS_IPT=1 + HAS_IPSET=$(command -v ipset >/dev/null && echo 1 || echo 0) + HAS_FW3=$(command -v fw3 >/dev/null && echo 1 || echo 0) + HAS_FW4=$(command -v fw4 >/dev/null && echo 1 || echo 0) + HAS_NFT=$(command -v nft >/dev/null && echo 1 || echo 0) + + # é‡ç½® USE_TABLES + USE_TABLES="" + + if [ "$HAS_FW4" -eq 1 ]; then + if [ "$DNSMASQ_NFTSET" -eq 1 ] && [ "$HAS_NFT" -eq 1 ]; then + USE_TABLES="nftables" + else + echolog "警告:fw4 已检测到,但 nftables 环境ä¸å®Œæ•´ã€‚(has_nft:$HAS_NFT/dnsmasq_nftset:$DNSMASQ_NFTSET)" + fi + fi + + if [ -z "$USE_TABLES" ] && [ "$HAS_FW3" -eq 1 ]; then + if [ "$HAS_IPSET" -eq 1 ] && [ "$HAS_IPT" -eq 1 ] && [ "$DNSMASQ_IPSET" -eq 1 ]; then + USE_TABLES="iptables" + else + echolog "警告:fw3 已检测到,但 iptables 环境ä¸å®Œæ•´ã€‚(has_ipset:$HAS_IPSET/has_ipt:$HAS_IPT/dnsmasq_ipset:$DNSMASQ_IPSET)" + fi + fi + + if [ -n "$USE_TABLES" ]; then + local dep_list + local file_path="/usr/lib/opkg/info" + local file_ext=".control" + [ -d "/lib/apk/packages" ] && { file_path="/lib/apk/packages"; file_ext=".list"; } + + if [ "$USE_TABLES" = "iptables" ]; then + dep_list="iptables-mod-tproxy iptables-mod-socket iptables-mod-iprange iptables-mod-conntrack-extra kmod-ipt-nat" + else + dep_list="kmod-nft-socket kmod-nft-tproxy kmod-nft-nat" + local v_num=$(echo "$dnsmasq_ver" | tr -cd '0-9') + if [ "${v_num:-0}" -lt 290 ]; then + echolog "æç¤ºï¼šDnsmasq ($dnsmasq_ver) 低于 2.90,建议å‡çº§ä»¥å¢žå¼ºç¨³å®šæ€§ã€‚" + fi + fi + local pkg + for pkg in $dep_list; do + if [ ! -s "${file_path}/${pkg}${file_ext}" ]; then + echolog "警告:${USE_TABLES} 逿˜Žä»£ç†ç¼ºå¤±åŸºç¡€ä¾èµ– ${pkg}ï¼" + fi + done + else + echolog "è­¦å‘Šï¼šä¸æ»¡è¶³ä»»ä½•逿˜Žä»£ç†ç³»ç»ŸçŽ¯å¢ƒã€‚" + fi +} + +normalize_run_mode() { + local run_mode="$(uci_get_by_type global run_mode router)" + + if [ "$run_mode" = "oversea" ]; then + echolog "æç¤ºï¼šOversea Mode 已移除,自动切æ¢åˆ° IP Route Mode。" + uci_set_by_type global run_mode router + run_mode="router" + fi + + echo "${run_mode:-router}" +} + +normalize_xray_protocol_nodes() { + local changed=0 + + _migrate_xray_protocol_node() { + local section="$1" + local type="$(uci_get_by_name "$section" type)" + local v2ray_protocol="$(uci_get_by_name "$section" v2ray_protocol)" + + if [ "$type" = "ss" ] || [ "$type" = "ss-libev" ]; then + if [ -n "$(first_type mihomo)" ]; then + uci -q set "$NAME.$section.type=ss" + changed=1 + elif [ -n "$(first_type sslocal)" ]; then + uci -q set "$NAME.$section.type=ss-rust" + changed=1 + elif [ -n "$(first_type xray)" ]; then + uci -q set "$NAME.$section.type=v2ray" + uci -q set "$NAME.$section.v2ray_protocol=shadowsocks" + changed=1 + fi + elif [ "$type" = "v2ray" ] && [ "$v2ray_protocol" = "shadowsocks" ]; then + if [ -n "$(first_type mihomo)" ]; then + uci -q set "$NAME.$section.type=ss" + uci -q delete "$NAME.$section.v2ray_protocol" + changed=1 + fi + fi + if [ "$type" = "hysteria2" ]; then + echolog "æç¤ºï¼šæ£€æµ‹åˆ°åŽŸç”Ÿ Hysteria2 节点,自动è¿ç§»ä¸º Xray(Hysteria2)。" + uci -q set "$NAME.$section.type=v2ray" + uci -q set "$NAME.$section.v2ray_protocol=hysteria2" + changed=1 + elif [ "$type" = "trojan" ]; then + echolog "æç¤ºï¼šæ£€æµ‹åˆ°åŽŸç”Ÿ Trojan 节点,自动è¿ç§»ä¸º Xray(Trojan)。" + uci -q set "$NAME.$section.type=v2ray" + uci -q set "$NAME.$section.v2ray_protocol=trojan" + changed=1 + fi + } + + config_load "$NAME" + config_foreach _migrate_xray_protocol_node servers + + local subscribe_sid="$(uci_get_by_cfgid server_subscribe)" + if [ -n "$subscribe_sid" ]; then + for key in xray_hy2_type xray_tj_type ss_type; do + if uci -q get "$NAME.$subscribe_sid.$key" >/dev/null; then + uci -q delete "$NAME.$subscribe_sid.$key" + changed=1 + fi + done + fi + + if [ "$changed" = "1" ]; then + uci commit "$NAME" + fi +} + +add_dns_into_ipset() { + case "$1" in + gfw) ipset add gfwlist ${2%:*} 2>/dev/null ;; + *) ipset add ss_spec_wan_ac ${2%:*} nomatch 2>/dev/null ;; + esac +} + +start_dns() { + local ssrplus_dns="$(uci_get_by_type global pdnsd_enable 0)" + local global_server_type="$(uci_get_by_name "$GLOBAL_SERVER" type)" + local builtin_dns_enabled=0 + local dnsserver="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)" + if [ "$ssrplus_dns" = "5" ]; then + ssrplus_dns="$(force_dns2tcp_fallback "旧版 DNSPROXY 模å¼å·²ç§»é™¤")" || return 1 + uci_set_by_type global pdnsd_enable "$ssrplus_dns" + elif [ "$ssrplus_dns" = "6" ]; then + dnsserver="$(uci_get_by_type global chinadns_ng_tunnel_forward 8.8.4.4:53)" + fi + local run_mode="$(normalize_run_mode)" + + if [ "$ssrplus_dns" = "4" ] && ! is_finded "mosdns"; then + ssrplus_dns="$(force_dns2tcp_fallback "å½“å‰ DNS æ¨¡å¼ MosDNS ä¸å¯ç”¨")" || return 1 + uci_set_by_type global pdnsd_enable "$ssrplus_dns" + fi + + if [ "$ssrplus_dns" = "7" ]; then + if supports_builtin_dns "$global_server_type"; then + builtin_dns_enabled=1 + else + ssrplus_dns="$(force_dns2tcp_fallback "当å‰ä¸»èŠ‚ç‚¹ä¸æ”¯æŒæ¨¡å—内置 DNS")" || return 1 + uci_set_by_type global pdnsd_enable "$ssrplus_dns" + fi + fi + + if [ "$builtin_dns_enabled" = "1" ]; then + pdnsd_enable_flag=7 + elif [ "$ssrplus_dns" != "0" ]; then + if [ "$HAS_IPSET" -eq 1 ]; then + if [ -n "$dnsserver" ]; then + add_dns_into_ipset $run_mode $dnsserver + fi + fi + case "$ssrplus_dns" in + 1) + start_dns2tcp "$dnsserver" + pdnsd_enable_flag=1 + ;; + 4) + local filter_aaaa="$(get_filter_aaaa)" + local mosdns_dnsserver="$(uci_get_by_type global tunnel_forward_mosdns)" + output=$(for i in $(echo $mosdns_dnsserver | sed "s/,/ /g"); do + dnsserver=${i%:*} + dnsserver=${i##*/} + if [ "$HAS_IPSET" -eq 1 ]; then + add_dns_into_ipset $run_mode $dnsserver + fi + echo " - addr: $i" + echo " enable_pipeline: true" + done) + + awk -v line=14 -v text="$output" 'NR == line+1 {print text} 1' /etc/ssrplus/mosdns-config.yaml | sed "s/DNS_PORT/$dns_port/g" | sed "s/\(concurrent:\).*/\1 $(echo "$mosdns_dnsserver" | sed 's/,/ /g' | wc -w)/g"> $TMP_PATH/mosdns-config.yaml + if [ "$filter_aaaa" == "0" ]; then + sed -i "s/DNS_MODE/main_sequence_with_IPv6/g" $TMP_PATH/mosdns-config.yaml + else + sed -i "s/DNS_MODE/main_sequence_disable_IPv6/g" $TMP_PATH/mosdns-config.yaml + fi + ln_start_bin $(first_type mosdns) mosdns start -c $TMP_PATH/mosdns-config.yaml + pdnsd_enable_flag=4 + ;; + 6) + local chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)" + local chinadns_ng_dns="" + # é历æ¯ä¸ª DNS æœåС噍 + IFS=',' # è®¾ç½®åˆ†éš”ç¬¦ä¸ºé€—å· + for chinadns_ng_server in $dnsserver; do + # 处ç†å•个æœåŠ¡å™¨åœ°å€ + local chinadns_ng_ip="${chinadns_ng_server%%:*}" + local chinadns_ng_port="${chinadns_ng_server##*:}" + [ "$chinadns_ng_ip" = "$chinadns_ng_port" ] && chinadns_ng_port="53" + chinadns_ng_tls_port="853" + # æ ¹æ®å议类型格å¼åŒ–æœåŠ¡å™¨åœ°å€ + case "$chinadns_ng_proto" in + "none") + chinadns_ng_server="${chinadns_ng_ip}#${chinadns_ng_port}" + ;; + "tls") + chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_tls_port}" + ;; + *) + chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_port}" + ;; + esac + # æ·»åŠ åˆ°å‚æ•°åˆ—表 + chinadns_ng_dns="${chinadns_ng_dns} -t ${chinadns_ng_server}" + done + unset IFS # æ¢å¤é»˜è®¤åˆ†éš”符 + dnsserver="$chinadns_ng_dns" + ln_start_bin $(first_type chinadns-ng) chinadns-ng -b 127.0.0.1 -l $tmp_dns_port -l $dns_port -p 3 -d gfw $dnsserver -N --filter-qtype 64,65 -f -r --cache 4096 --cache-stale 86400 --cache-refresh 20 + echolog "ChinaDNS-NG query and cache Started!" + pdnsd_enable_flag=6 + ;; + esac + + if [ "$run_mode" = "router" ]; then + local chinadns="$(uci_get_by_type global chinadns_forward)" + if [ -n "$chinadns" ]; then + local wandns="$(ifstatus wan | jsonfilter -e '@["dns-server"][0]' || echo "119.29.29.29")" + case "$chinadns" in + "wan") chinadns="$wandns" ;; + "wan_114") chinadns="$wandns,114.114.114.114" ;; + esac + + ln_start_bin $(first_type chinadns-ng) chinadns-ng -l $china_dns_port -4 china -p 3 -c ${chinadns/:/#} -t 127.0.0.1#$dns_port -N -f -r + + cat <<-EOF >> "$TMP_DNSMASQ_PATH/chinadns_fixed_server.conf" + no-poll + no-resolv + server=127.0.0.1#$china_dns_port + EOF + fi + fi + fi + + if [ "$(uci_get_by_type global apple_optimization 1)" == "1" ]; then + local new_appledns="$(uci_get_by_type global apple_dns)" + if [ -n "$new_appledns" ]; then + sed -i 's/[[:space:]]//g' /etc/ssrplus/applechina.conf #去除所有空白字符 + local old_appledns=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' /etc/ssrplus/applechina.conf | sort -u) + if [ -n "$old_appledns" ] && [ "$old_appledns" != "$new_appledns" ]; then + sed -i "s,$(printf '%s' "$old_appledns"),$(printf '%s' "$new_appledns"),g" /etc/ssrplus/applechina.conf + fi + fi + cp -f /etc/ssrplus/applechina.conf $TMP_DNSMASQ_PATH/ + fi +} + +# ç”Ÿæˆ Xray æœåŠ¡ç«¯é…ç½® +# ç”Ÿæˆ Xray æœåŠ¡ç«¯é…ç½® +generate_xray_config() { + local type="$1" + local port="$2" + local password="$3" + local security="$4" + local method="$5" + local network="$6" + local ws_path="$7" + local ws_host="$8" + local grpc_service="$9" + local alter_id="${10}" + local tcp_guise="${11}" + local tcp_guise_http_host="${12}" + local tcp_guise_http_path="${13}" + local config_file="${14}" + + local inbound_json="" + + case "$type" in + vmess) + inbound_json="{ + \"protocol\": \"vmess\", + \"port\": $port, + \"settings\": { + \"clients\": [{\"id\": \"$password\", \"alterId\": $alter_id}] + }, + \"streamSettings\": { + \"network\": \"$network\" + } + }" + ;; + vless) + inbound_json="{ + \"protocol\": \"vless\", + \"port\": $port, + \"settings\": { + \"clients\": [{\"id\": \"$password\"}], + \"decryption\": \"none\" + }, + \"streamSettings\": { + \"network\": \"$network\" + } + }" + ;; + trojan) + inbound_json="{ + \"protocol\": \"trojan\", + \"port\": $port, + \"settings\": { + \"clients\": [{\"password\": \"$password\"}] + }, + \"streamSettings\": { + \"network\": \"$network\" + } + }" + ;; + shadowsocks) + inbound_json="{ + \"protocol\": \"shadowsocks\", + \"port\": $port, + \"settings\": { + \"method\": \"$method\", + \"password\": \"$password\" + } + }" + ;; + *) + return 1 + ;; + esac + + # 添加传输层细节 + case "$network" in + ws) + local ws_json="{\"path\": \"$ws_path\"}" + [ -n "$ws_host" ] && ws_json="{\"path\": \"$ws_path\", \"headers\": {\"Host\": \"$ws_host\"}}" + inbound_json=$(echo "$inbound_json" | sed "s/\"streamSettings\": {/\"streamSettings\": {\"wsSettings\": $ws_json, /") + ;; + grpc) + [ -n "$grpc_service" ] && inbound_json=$(echo "$inbound_json" | sed "s/\"streamSettings\": {/\"streamSettings\": {\"grpcSettings\": {\"serviceName\": \"$grpc_service\"}, /") + ;; + tcp) + # TCP HTTP 伪装 + if [ "$tcp_guise" = "http" ]; then + local tcp_json="{\"header\": {\"type\": \"http\"" + + # 添加 HTTP Host + if [ -n "$tcp_guise_http_host" ]; then + # 将空格分隔的多个 host 转æ¢ä¸º JSON æ•°ç»„æ ¼å¼ + local host_list=$(echo "$tcp_guise_http_host" | sed 's/ /","/g') + tcp_json="$tcp_json, \"request\": {\"headers\": {\"Host\": [\"$host_list\"]}}" + fi + + # 添加 HTTP Path + if [ -n "$tcp_guise_http_path" ]; then + local path_list=$(echo "$tcp_guise_http_path" | sed 's/ /","/g') + tcp_json="$tcp_json, \"response\": {\"headers\": {\"Location\": [\"$path_list\"]}}" + fi + + tcp_json="$tcp_json}}" + inbound_json=$(echo "$inbound_json" | sed "s/\"streamSettings\": {/\"streamSettings\": {\"tcpSettings\": $tcp_json, /") + fi + ;; + esac + + cat > "$config_file" << EOF +{ + "log": { + "loglevel": "warning" + }, + "inbounds": [$inbound_json], + "outbounds": [ + { + "protocol": "freedom", + "settings": {} + } + ] +} +EOF + return 0 +} + +gen_service_file() { #1-server.type 2-cfgname 3-file_path + local fastopen + if [ $(uci_get_by_name $2 fast_open) == "1" ]; then + fastopen="true" + else + fastopen="false" + fi + case $1 in + ssr) + cat <<-EOF >$3 + { + "server": "0.0.0.0", + "server_ipv6": "::", + "server_port": $(uci_get_by_name $2 server_port), + "mode": "tcp_and_udp", + "password": "$(uci_get_by_name $2 password)", + "timeout": $(uci_get_by_name $2 timeout 60), + "method": "$(uci_get_by_name $2 encrypt_method)", + "protocol": "$(uci_get_by_name $2 protocol)", + "protocol_param": "$(uci_get_by_name $2 protocol_param)", + "obfs": "$(uci_get_by_name $2 obfs)", + "obfs_param": "$(uci_get_by_name $2 obfs_param)", + "fast_open": $fastopen + } + EOF + ;; + ss) + cat <<-EOF >$3 + { + "server": "0.0.0.0", + "server_ipv6": "::", + "server_port": $(uci_get_by_name $2 server_port), + "mode": "tcp_and_udp", + "password": "$(uci_get_by_name $2 password)", + "timeout": $(uci_get_by_name $2 timeout 60), + "method": "$(uci_get_by_name $2 encrypt_method_ss)", + "protocol": "socks", + "fast_open": $fastopen + } + EOF + ;; + esac +} + +get_name() { + case "$1" in + ss) echo "ShadowSocks" ;; + ssr) echo "ShadowsocksR" ;; + esac +} + +gen_config_file() { #server1 type2 code3 local_port4 socks_port5 chain6 threads5 + case "$3" in + 1) + config_file=$tcp_config_file + chain_config_file=$(echo ${config_file}|sed 's/ssrplus\//ssrplus\/chain-/') + ;; + 2) + config_file=$udp_config_file + chain_config_file=$(echo ${config_file}|sed 's/ssrplus\//ssrplus\/chain-/') + ;; + 3) + if [ -n "$tmp_local_port" ]; then + local tmp_port=$tmp_local_port + else + local tmp_port=$tmp_shunt_local_port + fi + config_file=$shunt_config_file + chain_config_file=$(echo ${config_file}|sed 's/ssrplus\//ssrplus\/chain-/') + ;; + 4) + local ss_protocol="socks" + config_file=$local_config_file + chain_config_file=$(echo ${config_file}|sed 's/ssrplus\//ssrplus\/chain-/') + ;; + esac + case "$2" in + ss | ssr) + lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 ${ss_protocol:-redir} >$config_file + if [ "$3" == "3" ]; then + lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $tmp_port socks >$shunt_dns_config_file + fi + ;; + v2ray) + lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 >$config_file + ;; + trojan) + case "$3" in + 1) + lua /usr/share/shadowsocksr/gen_config.lua $1 nat $4 >$config_file + ;; + 2) + lua /usr/share/shadowsocksr/gen_config.lua $1 client $4 >$config_file + ;; + 3) + lua /usr/share/shadowsocksr/gen_config.lua $1 nat $4 >$config_file + lua /usr/share/shadowsocksr/gen_config.lua $1 client $tmp_port >$shunt_dns_config_file + ;; + 4) + lua /usr/share/shadowsocksr/gen_config.lua $1 client $4 >$config_file + ;; + esac + ;; + naiveproxy) + case "$3" in + 1) + lua /usr/share/shadowsocksr/gen_config.lua $1 redir $4 >$config_file + ;; + 3) + lua /usr/share/shadowsocksr/gen_config.lua $1 redir $4 >$config_file + lua /usr/share/shadowsocksr/gen_config.lua $1 socks $tmp_port >$shunt_dns_config_file + ;; + 4) + lua /usr/share/shadowsocksr/gen_config.lua $1 socks $4 >$config_file + ;; + esac + ;; + hysteria2) + lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 >$config_file + ;; + tuic) + case "$3" in + 1|2|4) + lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 >$config_file + ;; + 3) + [ -z "$6" ] && lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 >$shunt_dns_config_file || lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 >$config_file + ;; + esac + ;; + shadowtls) + case "$3" in + 1|2|4) + [ -z "$6" ] && lua /usr/share/shadowsocksr/gen_config.lua $1 $type $4 >$chain_config_file || lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 $6 >$config_file + ;; + 3) + lua /usr/share/shadowsocksr/gen_config.lua $1 $type $4 >$chain_config_file + lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 $6 >$config_file + ;; + esac + ;; + esac + sed -i 's/\\//g' $TMP_PATH/*-ssr-*.json #>/dev/null > 2>&1 +} + +start_udp() { + local udp_relay_server_type=$(uci_get_by_name $UDP_RELAY_SERVER type) + local threads=$(get_configured_threads) + local type=$udp_relay_server_type + if [ "$udp_relay_server_type" = "ss-rust" ]; then + type="ss" + fi + redir_udp=1 + case "$type" in + ss | ssr) + if [ "$udp_relay_server_type" = "ss" ]; then + redir_udp=0 + ARG_UDP="" + echolog "UDP TPROXY Relay:Mihomo å•节点由主实例处ç†ã€‚" + elif [ "$udp_relay_server_type" = "ss-rust" ] && use_mihomo_for_ss_rust_client; then + redir_udp=0 + ARG_UDP="" + echolog "UDP TPROXY Relay:ss-rust 主程åºä¸å­˜åœ¨ï¼Œå·²å›žé€€åˆ° Mihomo 主实例处ç†ã€‚" + else + gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port + if [ "$udp_relay_server_type" = "ssr" ]; then + ss_program="$(first_type ${type}-redir)" + elif [ "$udp_relay_server_type" = "ss-rust" ] || [ "$udp_relay_server_type" = "ss" ]; then + ss_program="$(first_type ${type}local)" + fi + echolog "$(get_name $type) program is: $ss_program" + old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-redir" 2>/dev/null) + if [ "$old_ss_program" != "$ss_program" ]; then + rm -rf "$TMP_PATH/bin/${type}-redir" + fi + ln_start_bin $ss_program ${type}-redir -c $udp_config_file + echolog "UDP TPROXY Relay:$(get_name $type) Started!" + fi + ;; + v2ray) + gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port + ln_start_bin $(first_type xray) v2ray run -c $udp_config_file + echolog "UDP TPROXY Relay:$($(first_type xray) version | head -1) Started!" + ;; + trojan) #client + gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_local_port + ln_start_bin $(first_type trojan) $type --config $udp_config_file + ln_start_bin $(first_type ipt2socks) ipt2socks -U -b 0.0.0.0 -4 -s 127.0.0.1 -p $tmp_udp_local_port -l $tmp_udp_port + echolog "UDP TPROXY Relay:$($(first_type trojan) --version 2>&1 | head -1) Started!" + ;; + naiveproxy) + echolog "NaïveProxy UDP TPROXY Relay not supported!" + redir_udp=0 + ARG_UDP="" + ;; + tuic) + # TUIC now uses Mihomo directly and should follow the native path. + redir_udp=0 + ARG_UDP="" + echolog "TUIC UDP relay is handled by the main Mihomo instance." + ;; + shadowtls) + gen_config_file $UDP_RELAY_SERVER $type 2 ${tmp_udp_local_port} + gen_config_file $UDP_RELAY_SERVER $type 2 ${tmp_udp_local_port} 0 chain + ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file + local chain_type=$(uci_get_by_name $UDP_RELAY_SERVER chain_type) + case ${chain_type} in + vmess) + ln_start_bin $(first_type xray) v2ray run -c $udp_config_file + echolog "UDP TPROXY Relay:shadow-tls chain-to $($(first_type xray) --version) Started!" + ;; + sslocal) + ln_start_bin $(first_type sslocal) sslocal -c $udp_config_file + echolog "UDP TPROXY Relay:shadow-tls chain-to $($(first_type sslocal) --version) Started!" + ;; + esac + ;; + socks5) + if [ "$(uci_get_by_name $UDP_RELAY_SERVER auth_enable 0)" == "1" ]; then + local auth="-a $(uci_get_by_name $UDP_RELAY_SERVER username) -k $(uci_get_by_name $UDP_RELAY_SERVER password)" + fi + for i in $(seq 1 $threads); do + ln_start_bin $(first_type ipt2socks) ipt2socks -U -r -b 0.0.0.0 -4 \ + -s $(uci_get_by_name $UDP_RELAY_SERVER server) \ + -p $(uci_get_by_name $UDP_RELAY_SERVER server_port) \ + -l $tmp_udp_port $auth + done + echolog "UDP TPROXY Relay:Socks5 via IPT2Socks $threads Threads Started!" + ;; + esac +} + +start_local() { + [ "$LOCAL_SERVER" = "nil" ] && return 1 + local local_port="${1:-$(uci_get_by_type socks5_proxy local_port)}" + local local_server_type=$(uci_get_by_name $LOCAL_SERVER type) + local probe_instance_key="$(printf '%s' "${SSR_SWITCH_PROBE_INSTANCE_KEY:-}" | tr -cd '0-9A-Za-z._-')" + local type=$local_server_type + if [ "$local_server_type" = "ss-rust" ]; then + type="ss" + fi + case "$type" in + ss | ssr) + if [ "$local_server_type" = "ssr" ]; then + gen_config_file $LOCAL_SERVER $type 4 $local_port + ss_program="$(first_type ${type}-local)" + echolog "$(get_name $type) program is: $ss_program" + old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-local" 2>/dev/null) + if [ "$old_ss_program" != "$ss_program" ]; then + rm -rf "$TMP_PATH/bin/${type}-local" + fi + ln_start_bin $ss_program ${type}-local -c $local_config_file + echolog "Global_Socks5:$(get_name $type) Started!" + elif [ "$local_server_type" = "ss" ] || { [ "$local_server_type" = "ss-rust" ] && use_mihomo_for_ss_rust_client; }; then + local mihomo_bin="$(first_type mihomo)" + local instance_key="${LOCAL_SERVER}-local" + [ -n "$probe_instance_key" ] && instance_key="$probe_instance_key" + [ -x "$mihomo_bin" ] || { + echolog "Global_Socks5:Mihomo 内核ä¸å­˜åœ¨ï¼Œè¯·ç¡®è®¤ /usr/bin/mihomo 或 /usr/libexec/mihomo 坿‰§è¡Œã€‚" + return 1 + } + prepare_ss_mihomo_runtime_config "$LOCAL_SERVER" "$local_port" "$local_port" "$instance_key" "socks" || return 1 + local ss_workdir="$(get_ss_mihomo_workdir "$instance_key")" + ln_start_bin "$mihomo_bin" ss-local -d "$ss_workdir" -f "$ss_workdir/config.yaml" + if [ "$local_server_type" = "ss-rust" ]; then + echolog "Global_Socks5:ss-rust 主程åºä¸å­˜åœ¨ï¼Œå·²å›žé€€åˆ° Mihomo (Shadowsocks) å¯åŠ¨ã€‚" + else + echolog "Global_Socks5:Mihomo (Shadowsocks) Started!" + fi + else + gen_config_file $LOCAL_SERVER $type 4 $local_port + ss_program="$(first_type sslocal)" + echolog "ShadowSocks program is: $ss_program" + old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-local" 2>/dev/null) + if [ "$old_ss_program" != "$ss_program" ]; then + rm -rf "$TMP_PATH/bin/${type}-local" + fi + ln_start_bin $ss_program ${type}-local -c $local_config_file + echolog "Global_Socks5:Shadowsocks-rust Started!" + fi + ;; + v2ray) + if [ "$_local" == "2" ]; then + gen_config_file $LOCAL_SERVER $type 4 0 $local_port + ln_start_bin $(first_type xray) v2ray run -c $local_config_file + fi + echolog "Global_Socks5:$($(first_type xray) version | head -1) Started!" + ;; + trojan) #client + gen_config_file $LOCAL_SERVER $type 4 $local_port + ln_start_bin $(first_type trojan) $type --config $local_config_file + echolog "Global_Socks5:$($(first_type trojan) --version 2>&1 | head -1) Started!" + ;; + naiveproxy) + gen_config_file $LOCAL_SERVER $type 4 $local_port + ln_start_bin $(first_type naive) naive --config $local_config_file + echolog "Global_Socks5:$($(first_type naive) --version | head -1) Started!" + ;; + tuic) + local mihomo_bin="$(first_type mihomo)" + local instance_key="${LOCAL_SERVER}-local" + [ -n "$probe_instance_key" ] && instance_key="$probe_instance_key" + [ -x "$mihomo_bin" ] || { + echolog "Global_Socks5:Mihomo 内核ä¸å­˜åœ¨ï¼Œè¯·ç¡®è®¤ /usr/bin/mihomo 或 /usr/libexec/mihomo 坿‰§è¡Œã€‚" + return 1 + } + prepare_tuic_runtime_config "$LOCAL_SERVER" "$local_port" "$local_port" "$instance_key" "socks" || return 1 + local tuic_workdir="$(get_tuic_workdir "$instance_key")" + ln_start_bin "$mihomo_bin" tuic-local -d "$tuic_workdir" -f "$tuic_workdir/config.yaml" + echolog "Global_Socks5:Mihomo (TUIC) Started!" + ;; + shadowtls) + #respective config for global socks and main node + if [ "$_local" == "2" ]; then + gen_config_file $LOCAL_SERVER $type 4 "10${tmp_tcp_local_port}" + gen_config_file $LOCAL_SERVER $type 4 0 $local_port chain/"10${tmp_tcp_local_port}" + ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_local_config_file + local chain_type=$(uci_get_by_name $LOCAL_SERVER chain_type) + case ${chain_type} in + vmess) + ln_start_bin $(first_type xray) v2ray run -c $local_config_file + echolog "Global Socks5 Proxy:shadow-tls chain-to$($(first_type xray) --version) Started!" + ;; + sslocal) + ln_start_bin $(first_type sslocal) sslocal -c $local_config_file + echolog "Global Socks5 Proxy:shadow-tls chain-to$($(first_type sslocal) --version) Started!" + ;; + esac + fi + ;; + clash) + echolog "Global_Socks5:Clash total node is only supported when using Same as Global Server." + return 1 + ;; + socks5) + echolog "Global_Socks5:Socks5 transparent-only node cannot be used as generic Socks outbound." + return 1 + ;; + *) + local listenip='-i 0.0.0.0' + [ -e /proc/sys/net/ipv6 ] && listenip='-i ::' + ln_start_bin $(first_type microsocks) microsocks $listenip -p $local_port tcp-udp-ssr-local + echolog "Global_Socks5:$type Started!" + ;; + esac + local_enable=1 + return 0 +} + +start_local_with_port() { + start_local "$1" +} + +gen_3proxy_config() { + local cfg_file="$1" + local listen_port="$2" + local relay_socks_port="$3" + local auth_mode="$4" + local auth_user="$5" + local auth_pass="$6" + + cat <<-EOF >"$cfg_file" + daemon + pidfile $TMP_PATH/3proxy.pid + nserver 8.8.8.8 + nscache 65536 + timeouts 1 5 30 60 180 1800 15 60 + authcache ip 60 + internal 0.0.0.0 + external 0.0.0.0 + flush + EOF + + if [ "$auth_mode" = "password" ] && [ -n "$auth_user" ]; then + cat <<-EOF >>"$cfg_file" + auth strong + users $auth_user:CL:$auth_pass + allow $auth_user + EOF + else + cat <<-'EOF' >>"$cfg_file" + auth none + allow * + EOF + fi + + cat <<-EOF >>"$cfg_file" + parent 1000 socks5 127.0.0.1 $relay_socks_port + proxy -n -a -p$listen_port + flush + EOF +} + +start_http_proxy() { + [ "$HTTP_SERVER" = "nil" ] && return 1 + + local http_local_port=$(uci_get_by_type http_proxy local_port 3128) + local http_auth_mode=$(uci_get_by_type http_proxy http_auth none) + local http_user=$(uci_get_by_type http_proxy http_user) + local http_pass=$(uci_get_by_type http_proxy http_pass) + local http_server_type=$(uci_get_by_name $HTTP_SERVER type) + local need_local_start=1 + local prev_local_server="$LOCAL_SERVER" + local prev_local_config_file="$local_config_file" + local prev_local_flag="$local_enable" + local prev_local_mode="$_local" + local http_config_file="$TMP_PATH/3proxy-ssr-http.cfg" + local global_socks_enabled=$(uci_get_by_type socks5_proxy enabled 0) + local global_socks_port=$(uci_get_by_type socks5_proxy local_port 1080) + local global_socks_server=$(uci_get_by_type socks5_proxy server nil) + local resolved_socks_server="$global_socks_server" + local http_socks_port="$global_socks_port" + + if [ -z "$http_socks_port" ] || [ "$http_socks_port" = "0" ]; then + http_socks_port=1080 + fi + + [ "$http_local_port" = "$http_socks_port" ] && { + echolog "Global_HTTP: HTTP 监å¬ç«¯å£ä¸Žä¸Šæ¸¸ SOCKS5 端å£ä¸èƒ½ç›¸åŒã€‚" + return 1 + } + + if [ "$resolved_socks_server" = "same" ]; then + resolved_socks_server="$GLOBAL_SERVER" + fi + + if [ "$global_socks_enabled" = "1" ] && [ "$http_socks_port" = "$global_socks_port" ] && [ "$resolved_socks_server" != "$HTTP_SERVER" ]; then + echolog "Global_HTTP: Relay SOCKS5 Port 已被全局 SOCKS5 代ç†å ç”¨ï¼Œè¯·æ”¹ç”¨å…¶ä»–端å£ã€‚" + return 1 + fi + + if [ "$http_auth_mode" = "password" ] && [ -z "$http_user" ]; then + echolog "Global_HTTP: HTTP è®¤è¯æ¨¡å¼ä¸º password 时必须填写用户å。" + return 1 + fi + + case "$http_server_type" in + socks5) + echolog "Global_HTTP: 当å‰èŠ‚ç‚¹ç±»åž‹ä¸æ”¯æŒä½œä¸º 3proxy 的上游 SOCKS5 出å£ã€‚" + return 1 + ;; + esac + + if [ "$http_server_type" = "clash" ]; then + if [ "$HTTP_SERVER" != "$GLOBAL_SERVER" ]; then + echolog "Global_HTTP: Clash 节点仅支æŒé€‰æ‹© Same as Global Server 进行å¤ç”¨ã€‚" + return 1 + fi + if [ "$http_socks_port" != "$global_socks_port" ] && [ "$global_socks_enabled" = "1" ] && [ "$resolved_socks_server" = "$HTTP_SERVER" ]; then + echolog "Global_HTTP: Mihomo/Clash 仅支æŒå•个 socks-port,请让 HTTP 代ç†ä¸Žå…¨å±€ SOCKS5 使用相åŒçš„上游 SOCKS5 端å£ã€‚" + return 1 + fi + fi + + if supports_builtin_http "$http_server_type" && [ "$HTTP_SERVER" = "$GLOBAL_SERVER" ]; then + need_local_start=0 + elif [ "$global_socks_enabled" = "1" ] && [ "$resolved_socks_server" = "$HTTP_SERVER" ] && [ "$global_socks_port" = "$http_socks_port" ]; then + need_local_start=0 + else + LOCAL_SERVER="$HTTP_SERVER" + local_config_file="$TMP_PATH/tcp-http-ssr-local.json" + _local="2" + local_enable=0 + start_local_with_port "$http_socks_port" || { + LOCAL_SERVER="$prev_local_server" + local_config_file="$prev_local_config_file" + local_enable="$prev_local_flag" + _local="$prev_local_mode" + return 1 + } + LOCAL_SERVER="$prev_local_server" + local_config_file="$prev_local_config_file" + local_enable="$prev_local_flag" + _local="$prev_local_mode" + fi + + [ "$need_local_start" = "0" ] && echolog "Global_HTTP: Reuse existing local Socks5 upstream on port $http_socks_port." + + gen_3proxy_config "$http_config_file" "$http_local_port" "$http_socks_port" "$http_auth_mode" "$http_user" "$http_pass" + ln_start_bin $(first_type 3proxy) 3proxy "$http_config_file" + echolog "Global_HTTP:3proxy HTTP/HTTPS Proxy Started!" + http_enable=1 + return 0 +} + +get_udp_relay_mode() { + local node="$1" + local type + local proto + local socks_ver + + type=$(uci_get_by_name "$node" type) + [ "$type" = "ss-rust" ] && type="ss" + + case "$type" in + ss|ssr|hysteria2) + echo "native" + ;; + clash|tuic) + echo "native" + ;; + trojan|shadowtls) + echo "split" + ;; + socks5) + echo "split" + ;; + naiveproxy) + echo "disabled" + ;; + v2ray) + proto=$(uci_get_by_name "$node" v2ray_protocol) + case "$proto" in + http) + echo "disabled" + ;; + socks) + socks_ver=$(uci_get_by_name "$node" socks_ver 5) + [ "$socks_ver" = "5" ] && echo "native" || echo "disabled" + ;; + *) + echo "native" + ;; + esac + ;; + *) + echo "disabled" + ;; + esac +} + +Start_Run() { + local threads=$(get_configured_threads) + local global_server_type=$(uci_get_by_name $GLOBAL_SERVER type) + if [ "$(uci_get_by_name $GLOBAL_SERVER kcp_enable 0)" == "1" ] && [ "$global_server_type" != "ss" ]; then + [ ! -f "/usr/bin/kcptun-client" ] && return 1 + local kcp_str=$(/usr/bin/kcptun-client -v | grep kcptun | wc -l) + [ "0" == "$kcp_str" ] && return 1 + local kcp_server=$(uci_get_by_name $GLOBAL_SERVER server) + local kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port) + local server_port=$(uci_get_by_name $GLOBAL_SERVER server_port) + local password=$(uci_get_by_name $GLOBAL_SERVER kcp_password) + local kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param) + [ "$password" != "" ] && password="--key "$password + service_start /usr/bin/kcptun-client -r $kcp_server:$kcp_port -l :$server_port $password $kcp_param + kcp_enable_flag=1 + ARG_UDP="" + fi + if [ "$_local" == "1" ]; then + local socks_port=$(uci_get_by_type socks5_proxy local_port) + tcp_config_file=$TMP_PATH/local-ssr-retcp.json + [ "$mode" == "tcp,udp" ] && tcp_config_file=$TMP_PATH/local-udp-ssr-retcp.json + #[ "$mode" == "tcp,udp" ] && { + # if [ "$USE_TABLES" = "nftables" ]; then + # # nftables / fw4 + # tcp_config_file=$TMP_PATH/local-nft-ssr-retcp.json + # elif [ "$USE_TABLES" = "iptables" ]; then + # # iptables / fw3 + # tcp_config_file=$TMP_PATH/local-udp-ssr-retcp.json + # fi + #} + fi + local tcp_port=$(get_default_node_local_port) + local type=$global_server_type + if [ "$global_server_type" = "ss-rust" ]; then + type="ss" + fi + case "$type" in + ss | ssr) + if [ "$global_server_type" = "ssr" ]; then + gen_config_file $GLOBAL_SERVER $type 1 $tcp_port + ss_program="$(first_type ${type}-redir)" + echolog "$(get_name $type) program is: $ss_program" + old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-redir" 2>/dev/null) + if [ "$old_ss_program" != "$ss_program" ]; then + rm -rf "$TMP_PATH/bin/${type}-redir" + fi + for i in $(seq 1 $threads); do + ln_start_bin $ss_program ${type}-redir -c $tcp_config_file + done + echolog "Main node:$(get_name $type) $threads Threads Started!" + elif [ "$global_server_type" = "ss" ] || { [ "$global_server_type" = "ss-rust" ] && use_mihomo_for_ss_rust_client; }; then + local mihomo_bin="$(first_type mihomo)" + local ss_socks_port=0 + [ -x "$mihomo_bin" ] || { + echolog "Main node:Mihomo 内核ä¸å­˜åœ¨ï¼Œè¯·ç¡®è®¤ /usr/bin/mihomo 或 /usr/libexec/mihomo 坿‰§è¡Œã€‚" + return 1 + } + if [ "$_local" = "1" ] && [ "$LOCAL_SERVER" = "$GLOBAL_SERVER" ]; then + ss_socks_port=$(uci_get_by_type socks5_proxy local_port 1080) + fi + prepare_ss_mihomo_runtime_config "$GLOBAL_SERVER" "$tcp_port" "$ss_socks_port" "$GLOBAL_SERVER" "redir" || return 1 + local ss_workdir="$(get_ss_mihomo_workdir "$GLOBAL_SERVER")" + ln_start_bin "$mihomo_bin" ssr-retcp -d "$ss_workdir" -f "$ss_workdir/config.yaml" + if [ "$global_server_type" = "ss-rust" ]; then + echolog "Main node:ss-rust 主程åºä¸å­˜åœ¨ï¼Œå·²å›žé€€åˆ° Mihomo (Shadowsocks) å¯åŠ¨ã€‚" + else + echolog "Main node:Mihomo (Shadowsocks) Started!" + fi + else + gen_config_file $GLOBAL_SERVER $type 1 $tcp_port + ss_program="$(first_type sslocal)" + echolog "ShadowSocks program is: $ss_program" + old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-redir" 2>/dev/null) + if [ "$old_ss_program" != "$ss_program" ]; then + rm -rf "$TMP_PATH/bin/${type}-redir" + fi + ln_start_bin $ss_program ${type}-redir -c $tcp_config_file + echolog "Main node:Shadowsocks-rust Started!" + fi + ;; + v2ray) + gen_config_file $GLOBAL_SERVER $type 1 $tcp_port $socks_port + ln_start_bin $(first_type xray) v2ray run -c $tcp_config_file + echolog "Main node:$($(first_type xray) version | head -1) Started!" + ;; + trojan) + gen_config_file $GLOBAL_SERVER $type 1 $tcp_port + for i in $(seq 1 $threads); do + ln_start_bin $(first_type $type) $type --config $tcp_config_file + done + echolog "Main node:$($(first_type $type) --version 2>&1 | head -1) , $threads Threads Started!" + ;; + naiveproxy) + gen_config_file $GLOBAL_SERVER $type 1 $tcp_port + ln_start_bin $(first_type naive) naive $tcp_config_file + echolog "Main node:$($(first_type naive) --version 2>&1 | head -1) , $threads Threads Started!" + ;; + tuic) + local mihomo_bin="$(first_type mihomo)" + local tuic_socks_port=0 + [ -x "$mihomo_bin" ] || { + echolog "Main node:Mihomo 内核ä¸å­˜åœ¨ï¼Œè¯·ç¡®è®¤ /usr/bin/mihomo 或 /usr/libexec/mihomo 坿‰§è¡Œã€‚" + return 1 + } + if [ "$_local" = "1" ] && [ "$LOCAL_SERVER" = "$GLOBAL_SERVER" ]; then + tuic_socks_port=$(uci_get_by_type socks5_proxy local_port 1080) + fi + prepare_tuic_runtime_config "$GLOBAL_SERVER" "$tcp_port" "$tuic_socks_port" "$GLOBAL_SERVER" "redir" || return 1 + local tuic_workdir="$(get_tuic_workdir "$GLOBAL_SERVER")" + ln_start_bin "$mihomo_bin" ssr-retcp -d "$tuic_workdir" -f "$tuic_workdir/config.yaml" + echolog "Main node:Mihomo (TUIC) Started!" + ;; + shadowtls) + if [ -z "$socks_port" ]; then + gen_config_file $GLOBAL_SERVER $type 1 "10${tmp_tcp_local_port}" + gen_config_file $GLOBAL_SERVER $type 1 "10${tmp_tcp_local_port}" 0 chain + else + gen_config_file $GLOBAL_SERVER $type 1 "10${tmp_tcp_local_port}" + gen_config_file $GLOBAL_SERVER $type 1 "10${tmp_tcp_local_port}" $socks_port chain + fi + local chain_type=$(uci_get_by_name $GLOBAL_SERVER chain_type) + case ${chain_type} in + vmess) + ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file + ln_start_bin $(first_type xray) v2ray run -c $tcp_config_file + echolog "Mian node:shadow-tls chain-to $($(first_type xray) --version) Started!" + ;; + sslocal) + ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file + ln_start_bin $(first_type sslocal) sslocal -c $tcp_config_file + echolog "Main node:shadow-tls chain-to $($(first_type sslocal) --version) Started!" + ;; + esac + ;; + clash) + local clash_socks_port=0 + local mihomo_bin="$(first_type mihomo)" + clash_socks_port="$(resolve_global_clash_socks_port)" + if [ -z "$clash_socks_port" ] && [ "$_local" == "1" ] && [ "$LOCAL_SERVER" = "$GLOBAL_SERVER" ]; then + clash_socks_port=$(uci_get_by_type socks5_proxy local_port 1080) + fi + [ -x "$mihomo_bin" ] || { + echolog "Main node:Mihomo 内核ä¸å­˜åœ¨ï¼Œè¯·ç¡®è®¤ /usr/bin/mihomo 或 /usr/libexec/mihomo 坿‰§è¡Œã€‚" + return 1 + } + download_clash_config "$GLOBAL_SERVER" || { + echolog "Main node:Clash é…ç½®ä¸å¯ç”¨ï¼Œå¯åŠ¨ä¸­æ­¢ã€‚" + return 1 + } + prepare_clash_runtime_config "$GLOBAL_SERVER" "$tcp_port" "$clash_socks_port" || { + echolog "Main node:Clash è¿è¡Œé…置生æˆå¤±è´¥ï¼Œå¯åŠ¨ä¸­æ­¢ã€‚" + return 1 + } + local clash_workdir="$(get_clash_workdir "$GLOBAL_SERVER")" + ln_start_bin "$mihomo_bin" ssr-retcp -d "$clash_workdir" -f "$clash_workdir/config.yaml" + echolog "Main node:Mihomo (Clash) Started!" + ;; + socks5) + local ipt2socks_bin="$(first_type ipt2socks)" + local auth_opts="" + [ -x "$ipt2socks_bin" ] || { + echolog "Main node:Socks5 缺少 ipt2socks,无法å¯åЍ逿˜Žä»£ç†ã€‚" + return 1 + } + if [ "$(uci_get_by_name $GLOBAL_SERVER auth_enable 0)" = "1" ]; then + auth_opts="-a $(uci_get_by_name $GLOBAL_SERVER username) -k $(uci_get_by_name $GLOBAL_SERVER password)" + fi + for i in $(seq 1 $threads); do + ln_start_bin "$ipt2socks_bin" ipt2socks \ + -T -R -r -b 0.0.0.0 -4 \ + -s "$(uci_get_by_name $GLOBAL_SERVER server)" \ + -p "$(uci_get_by_name $GLOBAL_SERVER server_port)" \ + -l "$tcp_port" $auth_opts + done + echolog "Main node:Socks5 via IPT2Socks $threads Threads Started!" + ;; + esac + redir_tcp=1 + return 0 +} + +load_config() { + if [ -z "$switch_server" ]; then + GLOBAL_SERVER=$(uci_get_by_type global global_server nil) + else + GLOBAL_SERVER=$switch_server + fi + if [ "$(uci_get_by_type socks5_proxy enabled 0)" == "1" ]; then + uci -q set "$NAME.@socks5_proxy[0].server=same" + else + uci -q set "$NAME.@socks5_proxy[0].server=nil" + fi + if [ "$(uci_get_by_type http_proxy enabled 0)" == "1" ]; then + uci -q set "$NAME.@http_proxy[0].server=same" + else + uci -q set "$NAME.@http_proxy[0].server=nil" + fi + uci -q commit "$NAME" + if [ "$(uci_get_by_type socks5_proxy enabled 0)" == "1" ]; then + # åªæœ‰å¼€å¯ 全局socks æ‰éœ€è¦å–值 + LOCAL_SERVER=$(uci_get_by_type socks5_proxy server nil) + else + # æ²¡æœ‰å¼€å¯ è®¾ç½®ä¸º nil + LOCAL_SERVER=nil + fi + if [ "$(uci_get_by_type http_proxy enabled 0)" == "1" ]; then + HTTP_SERVER=$(uci_get_by_type http_proxy server nil) + else + HTTP_SERVER=nil + fi + if [ "$GLOBAL_SERVER" == "nil" ]; then + [ "$HTTP_SERVER" = "same" ] && HTTP_SERVER=nil + mode="tcp,udp" + _local="2" + local_config_file=$TMP_PATH/tcp-udp-ssr-local.json + start_local + return 1 + fi + UDP_RELAY_SERVER=$GLOBAL_SERVER + local udp_mode=$(get_udp_relay_mode "$GLOBAL_SERVER") + tcp_config_file=$TMP_PATH/tcp-only-ssr-retcp.json + case "$udp_mode" in + disabled) + echolog "æç¤ºï¼šå½“å‰èŠ‚ç‚¹ç±»åž‹ä¸æä¾› UDP 逿˜Žä»£ç†ï¼Œä¹Ÿä¸ä¼šå¯ç”¨ä»»ä½• UDP 规则,仅å¯ç”¨ TCP 逿˜Žä»£ç†ã€‚" + mode="tcp" + ARG_UDP="" + ARG_UDP_RULES="-y" + udp_config_file="" + ;; + native) + mode="tcp,udp" + tcp_config_file=$TMP_PATH/tcp-udp-ssr-retcp.json + ARG_UDP="-u" + ARG_UDP_RULES="" + ;; + split) + mode="udp" + udp_config_file=$TMP_PATH/udp-only-ssr-reudp.json + ARG_UDP="-U" + ARG_UDP_RULES="" + start_udp + mode="tcp" + ;; + esac + case "$LOCAL_SERVER" in + nil) + _local="0" + ;; + "$GLOBAL_SERVER"|same) + _local="1" + LOCAL_SERVER=$GLOBAL_SERVER + local_config_file=$TMP_PATH/tcp-udp-ssr-local.json + if ! supports_builtin_socks "$(uci_get_by_name $GLOBAL_SERVER type)"; then + start_local + fi + local_enable=0 + ;; + *) + _local="2" + local_config_file=$TMP_PATH/tcp-udp-ssr-local.json + start_local + ;; + esac + [ "$HTTP_SERVER" = "same" ] && HTTP_SERVER=$GLOBAL_SERVER + return 0 +} + +check_server() { + ENABLE_SERVER=$(uci_get_by_type global global_server nil) + if [ "$ENABLE_SERVER" == "nil" ]; then + return 1 + else + local STYPE=$(uci_get_by_name $ENABLE_SERVER type nil) + if [ "$STYPE" == "nil" ]; then + local CFGID=$(uci_get_by_cfgid servers type nil) + if [ "$CFGID" == "nil" ]; then + uci_set_by_type global global_server 'nil' + else + uci_set_by_type global global_server $CFGID + fi + /etc/init.d/shadowsocksr restart + fi + fi +} + +start_server() { + [ "$(uci_get_by_type server_global enable_server 0)" == "0" ] && return 0 + server_service() { + [ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1 + let server_count=server_count+1 + if [ "$server_count" == "1" ]; then + if [ "$USE_TABLES" = "nftables" ]; then + # nftables / fw4 + if nft list table inet fw4 >/dev/null 2>&1; then + if ! nft list chain inet fw4 SSR-SERVER-RULE >/dev/null 2>&1; then + nft add chain inet fw4 SSR-SERVER-RULE 2>/dev/null + fi + if ! nft list chain inet fw4 input 2>/dev/null | grep -q "jump SSR-SERVER-RULE"; then + nft insert rule inet fw4 input jump SSR-SERVER-RULE comment \"SSR Server Input Hook\" 2>/dev/null + fi + nft flush chain inet fw4 SSR-SERVER-RULE 2>/dev/null + fi + elif [ "$USE_TABLES" = "iptables" ]; then + # iptables / fw3 + if ! (iptables-save -t filter | grep -q "SSR-SERVER-RULE"); then + iptables -N SSR-SERVER-RULE + iptables -t filter -I INPUT -j SSR-SERVER-RULE + fi + fi + fi + local node_type=$(uci_get_by_name $1 type) + local type=$node_type + if [ "$node_type" = "ss-rust" ]; then + type="ss" + fi + case "$type" in + ss | ssr) + if [ "$node_type" = "ss" ] || { [ "$node_type" = "ss-rust" ] && use_mihomo_for_ss_rust_server; }; then + local mihomo_bin="$(first_type mihomo)" + [ -x "$mihomo_bin" ] || { + echolog "Server:Mihomo 内核ä¸å­˜åœ¨ï¼Œè¯·ç¡®è®¤ /usr/bin/mihomo 或 /usr/libexec/mihomo 坿‰§è¡Œã€‚" + return 1 + } + prepare_ss_server_mihomo_runtime_config "$1" || return 1 + local ss_server_workdir="$(get_ss_server_mihomo_workdir "$1")" + ln_start_bin "$mihomo_bin" ss-server-$server_count -d "$ss_server_workdir" -f "$ss_server_workdir/config.yaml" + if [ "$node_type" = "ss-rust" ]; then + echolog "Server:ss-rust 主程åºä¸å­˜åœ¨ï¼Œå·²å›žé€€åˆ° Mihomo Shadowsocks Server$server_count å¯åŠ¨ã€‚" + else + echolog "Server:Mihomo Shadowsocks Server$server_count Started!" + fi + else + gen_service_file ${type} $1 $TMP_PATH/ssr-server$server_count.json + if [ "$node_type" = "ssr" ]; then + ss_program="$(first_type ${type}-server)" + elif [ "$node_type" = "ss-rust" ] || [ "$node_type" = "ss" ]; then + ss_program="$(first_type ${type}server)" + fi + old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-server" 2>/dev/null) + if [ "$old_ss_program" != "$ss_program" ]; then + rm -rf "$TMP_PATH/bin/${type}-server" + fi + ln_start_bin $ss_program ${type}-server -c $TMP_PATH/ssr-server$server_count.json + echolog "Server: $(get_name ${type}) Server$server_count Started!" + fi + ;; + socks5) + local listenip='-i 0.0.0.0' + [ -e /proc/sys/net/ipv6 ] && listenip='-i ::' + local username=$(uci_get_by_name $1 username) + local password=$(uci_get_by_name $1 password) + local auth_opts="" + if [ -n "$username" ]; then + auth_opts="-u $username" + [ -n "$password" ] && auth_opts="$auth_opts -P $password" + fi + ln_start_bin $(first_type microsocks) microsocks $listenip -p $(uci_get_by_name $1 server_port) -1 $auth_opts ssr-server$server_count + echolog "Server:Socks5 Server$server_count Started!" + ;; + vmess|vless|trojan|shadowsocks) + # Xray æœåŠ¡ç«¯æ”¯æŒ + local port=$(uci_get_by_name "$1" server_port) + local uuid=$(uci_get_by_name "$1" uuid) + local trojan_pass=$(uci_get_by_name "$1" trojan_password) + local ss_pass=$(uci_get_by_name "$1" ss_password) + local security=$(uci_get_by_name "$1" security "auto") + local network=$(uci_get_by_name "$1" network "tcp") + local ws_path=$(uci_get_by_name "$1" ws_path "/") + local ws_host=$(uci_get_by_name "$1" ws_host "") + local grpc_service=$(uci_get_by_name "$1" grpc_service "") + local alter_id=$(uci_get_by_name "$1" alter_id "0") + local tcp_guise=$(uci_get_by_name "$1" tcp_guise "none") + local tcp_guise_http_host=$(uci_get_by_name "$1" tcp_guise_http_host "") + local tcp_guise_http_path=$(uci_get_by_name "$1" tcp_guise_http_path "") + + # 确定密ç /UUID + local password="" + local method="" + if [ "$type" = "vmess" ] || [ "$type" = "vless" ]; then + password="$uuid" + elif [ "$type" = "trojan" ]; then + password="$trojan_pass" + elif [ "$type" = "shadowsocks" ]; then + password="$ss_pass" + method="$security" + [ -z "$method" ] && method="chacha20-ietf-poly1305" + fi + + [ -z "$password" ] && { + echolog "Server: $type æœåŠ¡ç«¯ç¼ºå°‘å¯†ç /UUID,跳过å¯åЍ" + return 1 + } + + local config_file="$TMP_PATH/xray-server-$server_count.json" + + # ç”Ÿæˆ Xray é…ç½® + generate_xray_config "$type" "$port" "$password" "$security" "$method" "$network" "$ws_path" "$ws_host" "$grpc_service" "$alter_id" "$tcp_guise" "$tcp_guise_http_host" "$tcp_guise_http_path" "$config_file" + + if [ $? -ne 0 ]; then + echolog "Server: Xray $type é…置生æˆå¤±è´¥" + return 1 + fi + + local xray_bin=$(first_type xray) + if [ -z "$xray_bin" ]; then + echolog "Server: xray-core 未安装,无法å¯åЍ $type æœåŠ¡ç«¯" + return 1 + fi + + ln_start_bin "$xray_bin" xray-server-$server_count run -c "$config_file" + echolog "Server: Xray $type æœåŠ¡ç«¯ Server$server_count å·²å¯åЍ (端å£: $port)" + ;; + esac + server_port=$(uci_get_by_name $1 server_port) + if [ "$USE_TABLES" = "nftables" ]; then + # nftables / fw4 + nft add rule inet fw4 SSR-SERVER-RULE tcp dport $server_port accept + nft add rule inet fw4 SSR-SERVER-RULE udp dport $server_port accept + elif [ "$USE_TABLES" = "iptables" ]; then + # iptables / fw3 + iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $server_port -j ACCEPT + iptables -t filter -A SSR-SERVER-RULE -p udp --dport $server_port -j ACCEPT + fi + return 0 + } + gen_serv_include() { + local FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) + [ -n "$FWI" ] || return 0 + if [ ! -f $FWI ]; then + echo '#!/bin/sh' >$FWI + fi + if [ "$USE_TABLES" = "nftables" ]; then + # nftables / fw4 + cat <<-'EOF' >>"$FWI" + # ç¡®ä¿è¡¨å­˜åœ¨ + if nft list table inet fw4 >/dev/null 2>&1; then + # 如果ä¸å­˜åœ¨ SSR-SERVER-RULE 链,则创建 + if ! nft list chain inet fw4 SSR-SERVER-RULE >/dev/null 2>&1; then + nft add chain inet fw4 SSR-SERVER-RULE 2>/dev/null + fi + # 从 input 链跳转到 SSR-SERVER-RULE(如果未添加) + if ! nft list chain inet fw4 input | grep -q 'jump SSR-SERVER-RULE'; then + nft insert rule inet fw4 input jump SSR-SERVER-RULE comment \"SSR Server Input Hook\" 2>/dev/null + fi + # 已存在则清空链 + nft flush chain inet fw4 SSR-SERVER-RULE 2>/dev/null + fi + EOF + elif [ "$USE_TABLES" = "iptables" ]; then + # iptables / fw3 + extract_rules() { + echo "*filter" + iptables-save -t filter | grep SSR-SERVER-RULE | sed -e "s/^-A INPUT/-I INPUT/" + echo 'COMMIT' + } + cat <<-EOF >>$FWI + iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c + iptables-restore -n <<-EOT + $(extract_rules) + EOT + EOF + fi + } + + config_load $NAME + config_foreach server_service server_config + gen_serv_include + return 0 +} + +start_switch() { + if [ "$(uci_get_by_name $GLOBAL_SERVER type)" = "clash" ] || [ "$(uci_get_by_name $GLOBAL_SERVER type)" = "tuic" ]; then + echolog "æç¤ºï¼šMihomo 托管节点ä¸å¯ç”¨ SSR Plus 自动切æ¢é€»è¾‘。" + return 0 + fi + if [ "$(uci_get_by_type global enable_switch 0)" == "1" ]; then + if [ -z "$switch_server" ]; then + local switch_time=$(uci_get_by_type global switch_time)s + local switch_timeout=$(uci_get_by_type global switch_timeout) + service_start /usr/bin/ssr-switch start $switch_time $switch_timeout + fi + fi +} + +start_monitor() { + if [ $(uci_get_by_type global monitor_enable 1) == "1" ]; then + let total_count=server_count+redir_tcp+redir_udp+kcp_enable_flag+local_enable+pdnsd_enable_flag + if [ $total_count -gt 0 ]; then + service_start /usr/bin/ssr-monitor $server_count $redir_tcp $redir_udp $kcp_enable_flag $local_enable $pdnsd_enable_flag + fi + fi +} + +start_xhttp_addr() { + local xhttp_addr_file="/etc/ssrplus/xhttp_address.txt" + local tmp_file="/tmp/.xhttp_addr.tmp" + + # 收集所有节点的 download_address å€¼ï¼ŒåŽ»æŽ‰ç©ºè¡Œå¹¶åŽ»é‡æŽ’åº + { + for sec in "$GLOBAL_SERVER" "$UDP_RELAY_SERVER"; do + local addr + addr=$(uci_get_by_name "$sec" download_address) + [ -n "$addr" ] && echo "$addr" + done + } | grep -v '^$' | sort -u > "$tmp_file" + + # 如果没有 download_address 地å€ï¼Œåˆ é™¤æ—§æ–‡ä»¶å¹¶é€€å‡º + if [ ! -s "$tmp_file" ]; then + [ -f "$xhttp_addr_file" ] && rm -f "$xhttp_addr_file" + rm -f "$tmp_file" + return 0 + fi + + # 比较 MD5 判断 download_address åœ°å€æ˜¯å¦æœ‰å˜åŒ– + local md5_new md5_old + md5_new=$(md5sum "$tmp_file" | awk '{print $1}') + if [ -f "$xhttp_addr_file" ]; then + md5_old=$(md5sum "$xhttp_addr_file" | awk '{print $1}') + else + md5_old="" + fi + + # MD5 ä¸åŒæ›´æ–° download_address åœ°å€æ–‡ä»¶ + if [ "$md5_new" != "$md5_old" ]; then + mv -f "$tmp_file" "$xhttp_addr_file" + logger -t ssrplus-xhttp "download_address.txt updated" + else + rm -f "$tmp_file" + fi +} + +start_rules() { + local server=$(get_host_ip $GLOBAL_SERVER) + local local_port=$(get_default_node_local_port) + local lan_ac_ips=$(uci_get_by_type access_control lan_ac_ips) + local lan_ac_mode=$(uci_get_by_type access_control lan_ac_mode) + if [ "$kcp_enable_flag" == "0" -a "$redir_udp" == "1" ]; then + local udp_server=$(get_host_ip $UDP_RELAY_SERVER) + local udp_local_port=$tmp_udp_port + fi + if [ -n "$lan_ac_ips" ]; then + case "$lan_ac_mode" in + w | W | b | B) local ac_ips="$lan_ac_mode$lan_ac_ips" ;; + esac + fi + gfwmode() { + case "$(normalize_run_mode)" in + gfw) echo "-g" ;; + router) echo "-r" ;; + all) echo "-z" ;; + esac + } + if [ "$(uci_get_by_type global dports)" == "3" ]; then + local custom_ports=$(uci_get_by_name $GLOBAL_SERVER custom_ports) # custom_ports å­˜å‚¨äº†ç”¨æˆ·è‡ªå®šä¹‰çš„ç«¯å£ + if [ -n "$custom_ports" ]; then + local proxyport="-m multiport --dports $custom_ports" + fi + else + if [ "$(uci_get_by_type global dports 1)" == "2" ]; then + local proxyport="-m multiport --dports 22,53,587,465,995,993,143,80,443,853,9418" + fi + fi + + get_arg_out() { + case "$(uci_get_by_type access_control router_proxy 1)" in + 1) echo "-o" ;; + 2) echo "-O" ;; + esac + } + if [ "$USE_TABLES" = "nftables" ]; then + ARG_A="-A" + # Restore nft persistence rules + if [ -f "$BACKUP_FILE" ]; then + mkdir -p "$PERSIST_DIR" + mv "$BACKUP_FILE" "$PERSIST_FILE" + rm -rf "$BACKUP_DIR" + fi + elif [ "$USE_TABLES" = "iptables" ]; then + ARG_A="" + fi + /usr/share/shadowsocksr/gfw2ipset.sh + /usr/bin/ssr-rules \ + -s "$server" \ + -l "$local_port" \ + -S "$udp_server" \ + -L "$udp_local_port" \ + -a "$ac_ips" \ + -i "/etc/ssrplus/china_ssr.txt" \ + -b "$(uci_get_by_type access_control wan_bp_ips)" \ + -w "$(uci_get_by_type access_control wan_fw_ips)" \ + -B "$(uci_get_by_type access_control lan_bp_ips)" \ + -p "$(uci_get_by_type access_control lan_fp_ips)" \ + -G "$(uci_get_by_type access_control lan_gm_ips)" \ + -m "$(uci_get_by_type access_control Interface)" \ + -D "$proxyport" \ + $(get_arg_out) $(gfwmode) $ARG_UDP $ARG_UDP_RULES $ARG_A + + return $? + } + +start() { + set_lock + echolog "----------start------------" + mkdir -p /var/run /var/lock /var/log $DNSMASQ_CONF_DIR $TMP_BIN_PATH $TMP_DNSMASQ_PATH $CLASH_CONFIG_DIR + echo "conf-dir=${TMP_DNSMASQ_PATH}" >"$DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf" + check_run_environment + normalize_run_mode >/dev/null + normalize_xray_protocol_nodes + if load_config; then + Start_Run + start_http_proxy + start_xhttp_addr + start_rules + start_dns + # Restore ipsets after rules creation + if [ "$HAS_IPSET" -eq 1 ]; then + for setname in gfwlist china blacklist whitelist; do + [ "$setname" = "gfwlist" ] && [ "$run_mode" != "gfw" ] && continue + if [ -f "/tmp/ssrplus_save/${setname}.save" ]; then + ipset restore -! < "/tmp/ssrplus_save/${setname}.save" 2>/dev/null + fi + done + fi + add_cron + start_switch + else + echolog "未å¯åŠ¨ä¸»èŠ‚ç‚¹ï¼Œç¦æ­¢è¿žæŽ¥çš„åŸŸåæ­£åœ¨åŠ è½½ã€‚" + cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf + echolog "ç¦æ­¢è¿žæŽ¥çš„域å加载完毕。" + if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then + echolog "未å¯åŠ¨ä¸»èŠ‚ç‚¹ï¼Œå¹¿å‘Šè¿‡æ»¤æ­£åœ¨åŠ è½½ã€‚" + cp -f /etc/ssrplus/ad.conf "$TMP_DNSMASQ_PATH/" + if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then + # Optimize: Batch filter using grep instead of looping sed + for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do + if [ -s "$list_file" ]; then + # Clean list file (remove comments and empty lines) + grep -vE '^\s*#|^\s*$' "$list_file" | sed 's/\r//g' > "${list_file}.clean" + if [ -s "${list_file}.clean" ]; then + tmp_file="$TMP_DNSMASQ_PATH/ad.conf.tmp" + awk -v list="${list_file}.clean" ' + BEGIN { + while ((getline line < list) > 0) { + gsub(/\r/, "", line) + if (line != "") { + domain[line] = 1 + # æ”¯æŒæ³›åŸŸå + domain["*." line] = 1 + } + } + close(list) + } + { + keep = 1 + # åŒ¹é… server=/domain/ + if (match($0, /^server=\/([^\/]+)\//, m)) { + if (m[1] in domain) keep = 0 + } + # åŒ¹é… ipset=/domain/ + if (match($0, /^ipset=\/([^\/]+)\//, m)) { + if (m[1] in domain) keep = 0 + } + if (keep) print + } + ' "$TMP_DNSMASQ_PATH/ad.conf" > "$tmp_file" + mv "$tmp_file" "$TMP_DNSMASQ_PATH/ad.conf" + fi + rm -f "${list_file}.clean" + fi + done + fi + echolog "广告过滤加载完毕。" + fi + start_http_proxy + fi + /etc/init.d/dnsmasq restart >/dev/null 2>&1 + check_server + if [ "$USE_TABLES" = "nftables" ]; then + local CURRENT_SERVER="$(uci_get_by_type global global_server nil)" + if [ "$CURRENT_SERVER" != "nil" ]; then + uci set shadowsocksr.@global[0].old_global_server="$CURRENT_SERVER" + uci commit shadowsocksr + fi + fi + start_server + start_monitor + clean_log + echolog "-----------end------------" + unset_lock +} + +boot() { + echolog "bootï¼" + mkdir -p /var/run /var/lock /var/log $DNSMASQ_CONF_DIR $TMP_BIN_PATH $TMP_DNSMASQ_PATH + start +} + +stop() { + unlock + set_lock + check_run_environment + # Save ipsets before stopping to persist transparent proxy state + if [ "$HAS_IPSET" -eq 1 ]; then + mkdir -p /tmp/ssrplus_save + local run_mode="$(uci_get_by_type global run_mode)" + if [ "$run_mode" = "gfw" ]; then + ipset save gfwlist > /tmp/ssrplus_save/gfwlist.save 2>/dev/null + fi + for setname in china blacklist whitelist; do + ipset save $setname > /tmp/ssrplus_save/$setname.save 2>/dev/null + done + fi + if [ "$USE_TABLES" = "nftables" ]; then + # Save nft rules before stopping to persist transparent proxy state + if [ -f "$PERSIST_FILE" ]; then + mkdir -p "$BACKUP_DIR" + mv "$PERSIST_FILE" "$BACKUP_FILE" + fi + /usr/bin/ssr-rules -K + local OLD_SERVER="$(uci_get_by_type global old_global_server nil)" + local NEW_SERVER="$(uci_get_by_type global global_server nil)" + if [ "$OLD_SERVER" != "nil" ] && [ "$NEW_SERVER" != "nil" ] && [ "$OLD_SERVER" != "$NEW_SERVER" ]; then + /usr/bin/ssr-rules -X + fi + uci delete shadowsocksr.@global[0].old_global_server 2>/dev/null + uci commit shadowsocksr + fi + /usr/bin/ssr-rules -f + local srulecount=0 + if [ "$USE_TABLES" = "nftables" ]; then + # nftables / fw4 + #local srulecount=$(nft list ruleset 2>/dev/null | grep -c 'SSR-SERVER-RULE') + if nft list chain inet fw4 SSR-SERVER-RULE >/dev/null 2>&1; then + srulecount=$(nft list chain inet fw4 SSR-SERVER-RULE | grep SSR-SERVER-RULE | wc -l) + fi + elif [ "$USE_TABLES" = "iptables" ]; then + # iptables / fw3 + srulecount=$(iptables -L | grep SSR-SERVER-RULE | wc -l) + fi + if [ $srulecount -gt 0 ]; then + if [ "$USE_TABLES" = "nftables" ]; then + # nftables / fw4 + if nft list table inet fw4 >/dev/null 2>&1; then + if nft list chain inet fw4 SSR-SERVER-RULE >/dev/null 2>&1; then + for handle in $(nft --handle list chain inet fw4 input 2>/dev/null | \ + grep 'jump SSR-SERVER-RULE' | awk '{for(i=1;i<=NF;i++) if($i=="handle") print $(i+1)}'); do + nft delete rule inet fw4 input handle $handle 2>/dev/null || true + done + nft flush chain inet fw4 SSR-SERVER-RULE 2>/dev/null || true + nft delete chain inet fw4 SSR-SERVER-RULE 2>/dev/null || true + fi + fi + elif [ "$USE_TABLES" = "iptables" ]; then + # iptables / fw3 + if iptables-save -t filter | grep -q "SSR-SERVER-RULE"; then + logger -t ssr-rules "Flushing and deleting SSR-SERVER-RULE chain (iptables)" + iptables -F SSR-SERVER-RULE 2>/dev/null || true + iptables -t filter -D INPUT -j SSR-SERVER-RULE 2>/dev/null || true + iptables -X SSR-SERVER-RULE 2>/dev/null || true + fi + fi + fi + if [ -z "$switch_server" ]; then + ps_list | grep -v "grep" | grep ssr-switch | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & + rm -f /var/lock/ssr-switch.lock + killall -q -9 kcptun-client + fi + ps_list | grep -v "grep" | grep ssr-monitor | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & + ps_list | grep -v "grep" | grep ssr-rules | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & + ps_list | grep -v "grep" | grep "sleep 0000" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & + ( \ + # Graceful kill first, so programs have the chance to stop its subprocesses + ps_list | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill >/dev/null 2>&1 ; \ + sleep 3s; \ + # Force kill hanged programs + ps_list | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 ; \ + ) + killall -q -9 v2ray-plugin obfs-local xray-plugin shadow-tls + rm -f /var/lock/ssr-monitor.lock + if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then + uci -q del "dhcp.@dnsmasq[0].noresolv" + uci -q del_list "dhcp.@dnsmasq[0].server"="127.0.0.1#$china_dns_port" + uci -q rename "dhcp.@dnsmasq[0]._orig_noresolv"="noresolv" + uci -q rename "dhcp.@dnsmasq[0]._orig_server"="server" + uci -q del "dhcp.@dnsmasq[0]._unused_ssrp_changed" + uci -q commit "dhcp" + fi + if [ -f "$DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf" ]; then + rm -rf $DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf \ + $TMP_DNSMASQ_PATH \ + $TMP_PATH/*-ssr-*.json \ + $TMP_PATH/3proxy* \ + $TMP_PATH/clash-* \ + $TMP_PATH/ssr-server*.json \ + $TMP_PATH/*-config-*.json + + /etc/init.d/dnsmasq restart >/dev/null 2>&1 + fi + del_cron + unset_lock +} + +reset() { + stop + set_lock + rm -rf /etc/config/shadowsocksr $LOG_FILE + [ -f "/etc/ssrplus/xhttp_address.txt" ] && rm -f /etc/ssrplus/xhttp_address.txt + touch /etc/config/shadowsocksr $LOG_FILE + cp /usr/share/shadowsocksr/shadowsocksr.config /etc/config/shadowsocksr + unset_lock +} diff --git a/luci-app-ssr-plus/root/etc/ssrplus/ad.conf b/luci-app-ssr-plus/root/etc/ssrplus/ad.conf new file mode 100644 index 00000000..e69de29b diff --git a/luci-app-ssr-plus/root/etc/ssrplus/applechina.conf b/luci-app-ssr-plus/root/etc/ssrplus/applechina.conf new file mode 100644 index 00000000..bc8a7658 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/applechina.conf @@ -0,0 +1,173 @@ +server=/a1.mzstatic.com/114.114.114.114 +server=/a2.mzstatic.com/114.114.114.114 +server=/a3.mzstatic.com/114.114.114.114 +server=/a4.mzstatic.com/114.114.114.114 +server=/a5.mzstatic.com/114.114.114.114 +server=/adcdownload.apple.com.akadns.net/114.114.114.114 +server=/adcdownload.apple.com/114.114.114.114 +server=/amp-api-updates.apps.apple.com/114.114.114.114 +server=/amp-api.media.apple.com/114.114.114.114 +server=/api-p-ap-c.smoot.apple.com/114.114.114.114 +server=/api-p-ap-d.smoot.apple.com/114.114.114.114 +server=/api-p-ap-e.smoot.apple.com/114.114.114.114 +server=/app-site-association.cdn-apple.com/114.114.114.114 +server=/appldnld.apple.com/114.114.114.114 +server=/appldnld.g.aaplimg.com/114.114.114.114 +server=/appleid.cdn-apple.com/114.114.114.114 +server=/apps.apple.com/114.114.114.114 +server=/apps.mzstatic.com/114.114.114.114 +server=/bag-cdn.itunes-apple.com.akadns.net/114.114.114.114 +server=/cdn-cn1.apple-mapkit.com/114.114.114.114 +server=/cdn-cn2.apple-mapkit.com/114.114.114.114 +server=/cdn-cn3.apple-mapkit.com/114.114.114.114 +server=/cdn-cn4.apple-mapkit.com/114.114.114.114 +server=/cdn.apple-mapkit.com/114.114.114.114 +server=/cdn1.apple-mapkit.com/114.114.114.114 +server=/cdn2.apple-mapkit.com/114.114.114.114 +server=/cdn3.apple-mapkit.com/114.114.114.114 +server=/cdn4.apple-mapkit.com/114.114.114.114 +server=/cds-cdn.v.aaplimg.com/114.114.114.114 +server=/cds.apple.com.akadns.net/114.114.114.114 +server=/cds.apple.com/114.114.114.114 +server=/cdsassets.apple.com/114.114.114.114 +server=/cl1-cdn.origin-apple.com.akadns.net/114.114.114.114 +server=/cl1.apple.com/114.114.114.114 +server=/cl2-cn.apple.com/114.114.114.114 +server=/cl2.apple.com/114.114.114.114 +server=/cl3-cdn.origin-apple.com.akadns.net/114.114.114.114 +server=/cl3.apple.com/114.114.114.114 +server=/cl4-cdn.origin-apple.com.akadns.net/114.114.114.114 +server=/cl4-cn.apple.com/114.114.114.114 +server=/cl4.apple.com/114.114.114.114 +server=/cl5-cdn.origin-apple.com.akadns.net/114.114.114.114 +server=/cl5.apple.com/114.114.114.114 +server=/clientflow.apple.com.akadns.net/114.114.114.114 +server=/clientflow.apple.com/114.114.114.114 +server=/cn-smp-paymentservices.apple.com/114.114.114.114 +server=/configuration.apple.com.akadns.net/114.114.114.114 +server=/configuration.apple.com/114.114.114.114 +server=/crl.apple.com/114.114.114.114 +server=/cstat.apple.com/114.114.114.114 +server=/cstat.cdn-apple.com/114.114.114.114 +server=/dd-cdn.origin-apple.com.akadns.net/114.114.114.114 +server=/dejavu.apple.com/114.114.114.114 +server=/devstreaming-cdn.apple.com/114.114.114.114 +server=/download.developer.apple.com/114.114.114.114 +server=/experiments.apple.com/114.114.114.114 +server=/gs-loc-cn.apple.com/114.114.114.114 +server=/gs-loc.apple.com/114.114.114.114 +server=/gsp10-ssl-cn.ls.apple.com/114.114.114.114 +server=/gsp12-cn.ls.apple.com/114.114.114.114 +server=/gsp13-cn.ls.apple.com/114.114.114.114 +server=/gsp4-cn.ls.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114 +server=/gsp4-cn.ls.apple.com.edgekey.net/114.114.114.114 +server=/gsp4-cn.ls.apple.com/114.114.114.114 +server=/gsp5-cn.ls.apple.com/114.114.114.114 +server=/gsp85-cn-ssl.ls.apple.com/114.114.114.114 +server=/gspe19-2-cn-ssl.ls-apple.com.akadns.net/114.114.114.114 +server=/gspe19-2-cn-ssl.ls.apple.com/114.114.114.114 +server=/gspe19-cn-ssl.ls.apple.com/114.114.114.114 +server=/gspe19-cn.ls-apple.com.akadns.net/114.114.114.114 +server=/gspe19-cn.ls.apple.com/114.114.114.114 +server=/gspe21-ssl.ls.apple.com/114.114.114.114 +server=/gspe21.ls.apple.com/114.114.114.114 +server=/gspe35-ssl.ls.apple.com/114.114.114.114 +server=/gspe79-cn-ssl.ls.apple.com/114.114.114.114 +server=/guzzoni-apple-com.v.aaplimg.com/114.114.114.114 +server=/guzzoni.apple.com/114.114.114.114 +server=/guzzoni.smoot.apple.com/114.114.114.114 +server=/iadsdk.apple.com/114.114.114.114 +server=/icloud-cdn.icloud.com.akadns.net/114.114.114.114 +server=/icloud.cdn-apple.com/114.114.114.114 +server=/images.apple.com.akadns.net/114.114.114.114 +server=/images.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114 +server=/images.apple.com/114.114.114.114 +server=/init-kt.apple.com/114.114.114.114 +server=/init-p01md-lb.push-apple.com.akadns.net/114.114.114.114 +server=/init-p01md.apple.com/114.114.114.114 +server=/init-p01st-lb.push-apple.com.akadns.net/114.114.114.114 +server=/init-p01st.push.apple.com/114.114.114.114 +server=/init-s01st-lb.push-apple.com.akadns.net/114.114.114.114 +server=/init-s01st.push.apple.com/114.114.114.114 +server=/init.ess.apple.com/114.114.114.114 +server=/iosapps.itunes.g.aaplimg.com/114.114.114.114 +server=/ipcdn.apple.com/114.114.114.114 +server=/iphone-ld.apple.com/114.114.114.114 +server=/iphone-ld.origin-apple.com.akadns.net/114.114.114.114 +server=/is-ssl.mzstatic.com-cn-lb.itunes-apple.com.akadns.net/114.114.114.114 +server=/is1-ssl.mzstatic.com/114.114.114.114 +server=/is1.mzstatic.com/114.114.114.114 +server=/is2-ssl.mzstatic.com/114.114.114.114 +server=/is2.mzstatic.com/114.114.114.114 +server=/is3-ssl.mzstatic.com/114.114.114.114 +server=/is3.mzstatic.com/114.114.114.114 +server=/is4-ssl.mzstatic.com/114.114.114.114 +server=/is4.mzstatic.com/114.114.114.114 +server=/is5-ssl.mzstatic.com/114.114.114.114 +server=/is5.mzstatic.com/114.114.114.114 +server=/itunes-apple.com.akadns.net/114.114.114.114 +server=/itunes.apple.com/114.114.114.114 +server=/itunesconnect.apple.com/114.114.114.114 +server=/mesu-cdn.apple.com.akadns.net/114.114.114.114 +server=/mesu-china.apple.com.akadns.net/114.114.114.114 +server=/mesu.apple.com/114.114.114.114 +server=/ml.cdn-apple.com/114.114.114.114 +server=/music.apple.com/114.114.114.114 +server=/ocsp-lb.apple.com.akadns.net/114.114.114.114 +server=/ocsp.apple.com/114.114.114.114 +server=/ocsp2-lb.apple.com.akadns.net/114.114.114.114 +server=/ocsp2.apple.com/114.114.114.114 +server=/oscdn.apple.com/114.114.114.114 +server=/oscdn.origin-apple.com.akadns.net/114.114.114.114 +server=/osxapps.itunes.g.aaplimg.com/114.114.114.114 +server=/pancake.apple.com/114.114.114.114 +server=/pancake.cdn-apple.com.akadns.net/114.114.114.114 +server=/pba0.apple.com/114.114.114.114 +server=/probe.siri.apple.com/114.114.114.114 +server=/prod-support.apple-support.akadns.net/114.114.114.114 +server=/publicassets.cdn-apple.com/114.114.114.114 +server=/reserve-prime.apple.com/114.114.114.114 +server=/s.mzstatic.com/114.114.114.114 +server=/seed-sequoia.siri.apple.com/114.114.114.114 +server=/seed-swallow.siri.apple.com/114.114.114.114 +server=/seed.siri.apple.com/114.114.114.114 +server=/sequoia.apple.com/114.114.114.114 +server=/sh-pod2-smp-device.apple.com/114.114.114.114 +server=/shazam-insights.cdn-apple.com/114.114.114.114 +server=/smp-device-content.apple.com/114.114.114.114 +server=/static.gc.apple.com/114.114.114.114 +server=/stocks-sparkline-lb.apple.com.akadns.net/114.114.114.114 +server=/stocks-sparkline.apple.com/114.114.114.114 +server=/store.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114 +server=/store.apple.com.edgekey.net/114.114.114.114 +server=/store.apple.com/114.114.114.114 +server=/store.storeimages.apple.com.akadns.net/114.114.114.114 +server=/store.storeimages.cdn-apple.com/114.114.114.114 +server=/support-china.apple-support.akadns.net/114.114.114.114 +server=/support.apple.com/114.114.114.114 +server=/swallow-apple-com.v.aaplimg.com/114.114.114.114 +server=/swallow.apple.com/114.114.114.114 +server=/swcatalog-cdn.apple.com.akadns.net/114.114.114.114 +server=/swcatalog.apple.com/114.114.114.114 +server=/swcdn.apple.com/114.114.114.114 +server=/swcdn.g.aaplimg.com/114.114.114.114 +server=/swdist.apple.com.akadns.net/114.114.114.114 +server=/swdist.apple.com/114.114.114.114 +server=/swscan-cdn.apple.com.akadns.net/114.114.114.114 +server=/swscan.apple.com/114.114.114.114 +server=/sylvan.apple.com/114.114.114.114 +server=/tj-pod1-smp-device.apple.com/114.114.114.114 +server=/updates-http.cdn-apple.com.akadns.net/114.114.114.114 +server=/updates-http.cdn-apple.com/114.114.114.114 +server=/updates.cdn-apple.com/114.114.114.114 +server=/valid.apple.com/114.114.114.114 +server=/valid.origin-apple.com.akadns.net/114.114.114.114 +server=/weather-data.apple.com.akadns.net/114.114.114.114 +server=/weather-data.apple.com/114.114.114.114 +server=/weather-map.apple.com/114.114.114.114 +server=/weather-map2.apple.com/114.114.114.114 +server=/weatherkit.apple.com/114.114.114.114 +server=/www.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114 +server=/www.apple.com.edgekey.net/114.114.114.114 +server=/www.apple.com/114.114.114.114 +server=/xp.apple.com/114.114.114.114 diff --git a/luci-app-ssr-plus/root/etc/ssrplus/black.list b/luci-app-ssr-plus/root/etc/ssrplus/black.list new file mode 100644 index 00000000..e69de29b diff --git a/luci-app-ssr-plus/root/etc/ssrplus/china_ssr.txt b/luci-app-ssr-plus/root/etc/ssrplus/china_ssr.txt new file mode 100644 index 00000000..d3548833 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/china_ssr.txt @@ -0,0 +1,8612 @@ +1.0.1.0/24 +1.0.2.0/23 +1.0.8.0/21 +1.0.32.0/19 +1.1.0.0/24 +1.1.2.0/23 +1.1.4.0/22 +1.1.8.0/24 +1.1.9.0/24 +1.1.10.0/23 +1.1.12.0/22 +1.1.16.0/20 +1.1.32.0/19 +1.2.0.0/23 +1.2.2.0/24 +1.2.4.0/24 +1.2.5.0/24 +1.2.6.0/23 +1.2.8.0/24 +1.2.9.0/24 +1.2.10.0/23 +1.2.12.0/22 +1.2.16.0/20 +1.2.32.0/19 +1.2.64.0/18 +1.3.0.0/16 +1.4.1.0/24 +1.4.2.0/23 +1.4.4.0/24 +1.4.5.0/24 +1.4.6.0/23 +1.4.8.0/21 +1.4.16.0/20 +1.4.32.0/19 +1.4.64.0/18 +1.8.0.0/16 +1.10.0.0/21 +1.10.8.0/23 +1.10.11.0/24 +1.10.12.0/22 +1.10.16.0/20 +1.10.32.0/19 +1.10.64.0/18 +1.12.0.0/14 +1.24.0.0/13 +1.45.0.0/16 +1.48.0.0/15 +1.50.0.0/16 +1.51.0.0/16 +1.56.0.0/13 +1.68.0.0/14 +1.80.0.0/13 +1.88.0.0/14 +1.92.0.0/15 +1.94.0.0/15 +1.116.0.0/15 +1.118.0.0/16 +1.119.0.0/17 +1.119.128.0/17 +1.180.0.0/14 +1.184.0.0/15 +1.188.0.0/14 +1.192.0.0/13 +1.202.0.0/15 +1.204.0.0/14 +14.0.0.0/21 +14.0.12.0/22 +14.1.0.0/22 +14.1.24.0/22 +14.1.96.0/22 +14.1.108.0/22 +14.16.0.0/12 +14.102.128.0/22 +14.102.156.0/22 +14.102.180.0/22 +14.103.0.0/16 +14.104.0.0/13 +14.112.0.0/12 +14.130.0.0/15 +14.134.0.0/15 +14.144.0.0/12 +14.192.60.0/22 +14.192.76.0/22 +14.196.0.0/15 +14.204.0.0/15 +14.208.0.0/12 +27.0.128.0/22 +27.0.132.0/22 +27.0.160.0/22 +27.0.164.0/22 +27.0.188.0/22 +27.0.204.0/22 +27.0.208.0/22 +27.0.212.0/22 +27.8.0.0/13 +27.16.0.0/12 +27.34.232.0/21 +27.36.0.0/14 +27.40.0.0/13 +27.50.40.0/21 +27.50.128.0/17 +27.54.72.0/21 +27.54.152.0/21 +27.54.192.0/18 +27.98.208.0/20 +27.98.224.0/19 +27.99.128.0/17 +27.103.0.0/16 +27.106.128.0/18 +27.106.204.0/22 +27.109.32.0/19 +27.109.124.0/22 +27.112.0.0/18 +27.112.80.0/20 +27.112.112.0/22 +27.112.116.0/22 +27.113.128.0/18 +27.115.0.0/17 +27.116.44.0/22 +27.121.72.0/21 +27.121.120.0/21 +27.128.0.0/15 +27.131.220.0/22 +27.144.0.0/16 +27.148.0.0/14 +27.152.0.0/13 +27.184.0.0/13 +27.192.0.0/11 +27.224.0.0/14 +36.0.0.0/22 +36.0.8.0/21 +36.0.16.0/20 +36.0.32.0/19 +36.0.64.0/18 +36.0.128.0/17 +36.1.0.0/16 +36.4.0.0/14 +36.16.0.0/12 +36.32.0.0/14 +36.36.0.0/16 +36.37.0.0/19 +36.37.36.0/23 +36.37.39.0/24 +36.37.40.0/21 +36.37.48.0/20 +36.40.0.0/13 +36.48.0.0/15 +36.51.0.0/16 +36.56.0.0/13 +36.96.0.0/11 +36.128.0.0/10 +36.192.0.0/11 +36.248.0.0/14 +36.254.0.0/16 +36.255.116.0/22 +36.255.128.0/22 +36.255.164.0/22 +36.255.172.0/22 +36.255.176.0/22 +39.0.0.0/24 +39.0.2.0/23 +39.0.4.0/22 +39.0.8.0/21 +39.0.16.0/20 +39.0.32.0/19 +39.0.64.0/18 +39.0.128.0/17 +39.64.0.0/11 +39.96.0.0/13 +39.104.0.0/14 +39.108.0.0/16 +39.128.0.0/10 +40.72.0.0/15 +40.125.128.0/17 +40.126.64.0/18 +42.0.0.0/22 +42.0.8.0/21 +42.0.16.0/21 +42.0.24.0/22 +42.0.32.0/19 +42.0.128.0/17 +42.1.0.0/19 +42.1.32.0/20 +42.1.48.0/21 +42.1.56.0/22 +42.1.128.0/17 +42.4.0.0/14 +42.48.0.0/15 +42.50.0.0/16 +42.51.0.0/16 +42.52.0.0/14 +42.56.0.0/14 +42.62.0.0/17 +42.62.128.0/19 +42.62.160.0/20 +42.62.180.0/22 +42.62.184.0/21 +42.63.0.0/16 +42.80.0.0/15 +42.83.64.0/20 +42.83.80.0/22 +42.83.88.0/21 +42.83.96.0/19 +42.83.128.0/17 +42.84.0.0/14 +42.88.0.0/13 +42.96.64.0/19 +42.96.96.0/21 +42.96.108.0/22 +42.96.112.0/20 +42.96.128.0/17 +42.97.0.0/16 +42.99.0.0/18 +42.99.64.0/19 +42.99.96.0/20 +42.99.112.0/22 +42.99.120.0/21 +42.100.0.0/14 +42.120.0.0/15 +42.122.0.0/16 +42.123.0.0/19 +42.123.36.0/22 +42.123.40.0/21 +42.123.48.0/20 +42.123.64.0/18 +42.123.128.0/17 +42.128.0.0/12 +42.156.0.0/19 +42.156.36.0/22 +42.156.40.0/21 +42.156.48.0/20 +42.156.64.0/18 +42.156.128.0/17 +42.157.0.0/16 +42.158.0.0/16 +42.159.0.0/16 +42.160.0.0/12 +42.176.0.0/13 +42.184.0.0/15 +42.186.0.0/16 +42.187.0.0/18 +42.187.64.0/19 +42.187.96.0/20 +42.187.112.0/21 +42.187.120.0/22 +42.187.128.0/17 +42.192.0.0/15 +42.194.0.0/21 +42.194.8.0/22 +42.194.12.0/22 +42.194.16.0/20 +42.194.32.0/19 +42.194.64.0/18 +42.194.128.0/17 +42.195.0.0/16 +42.196.0.0/14 +42.201.0.0/17 +42.202.0.0/15 +42.204.0.0/14 +42.208.0.0/12 +42.224.0.0/12 +42.240.0.0/17 +42.240.128.0/17 +42.242.0.0/15 +42.244.0.0/14 +42.248.0.0/13 +43.136.0.0/13 +43.144.0.0/13 +43.176.0.0/12 +43.192.0.0/14 +43.196.0.0/15 +43.224.12.0/22 +43.224.24.0/22 +43.224.44.0/22 +43.224.52.0/22 +43.224.56.0/22 +43.224.64.0/22 +43.224.68.0/22 +43.224.72.0/22 +43.224.80.0/22 +43.224.100.0/22 +43.224.144.0/22 +43.224.160.0/22 +43.224.176.0/22 +43.224.184.0/22 +43.224.200.0/22 +43.224.204.0/22 +43.224.208.0/22 +43.224.212.0/22 +43.224.216.0/22 +43.224.240.0/22 +43.225.76.0/22 +43.225.84.0/22 +43.225.120.0/22 +43.225.172.0/22 +43.225.180.0/22 +43.225.208.0/22 +43.225.216.0/22 +43.225.220.0/22 +43.225.224.0/22 +43.225.228.0/22 +43.225.232.0/22 +43.225.236.0/22 +43.225.240.0/22 +43.225.244.0/22 +43.225.252.0/22 +43.226.32.0/22 +43.226.36.0/22 +43.226.40.0/22 +43.226.44.0/22 +43.226.48.0/22 +43.226.52.0/22 +43.226.56.0/22 +43.226.60.0/22 +43.226.64.0/22 +43.226.68.0/22 +43.226.72.0/22 +43.226.76.0/22 +43.226.80.0/22 +43.226.84.0/22 +43.226.88.0/22 +43.226.92.0/22 +43.226.96.0/22 +43.226.100.0/22 +43.226.104.0/22 +43.226.108.0/22 +43.226.112.0/22 +43.226.116.0/22 +43.226.120.0/22 +43.226.128.0/22 +43.226.132.0/22 +43.226.136.0/22 +43.226.140.0/22 +43.226.144.0/22 +43.226.148.0/22 +43.226.152.0/22 +43.226.156.0/22 +43.226.160.0/22 +43.226.164.0/22 +43.226.168.0/22 +43.226.172.0/22 +43.226.176.0/22 +43.226.180.0/22 +43.226.184.0/22 +43.226.188.0/22 +43.226.192.0/22 +43.226.196.0/22 +43.226.200.0/22 +43.226.204.0/22 +43.226.208.0/22 +43.226.212.0/22 +43.226.236.0/22 +43.226.240.0/22 +43.226.244.0/22 +43.226.248.0/22 +43.226.252.0/22 +43.227.0.0/22 +43.227.4.0/22 +43.227.8.0/22 +43.227.32.0/22 +43.227.36.0/22 +43.227.40.0/22 +43.227.44.0/22 +43.227.48.0/22 +43.227.52.0/22 +43.227.56.0/22 +43.227.60.0/22 +43.227.64.0/22 +43.227.68.0/22 +43.227.72.0/22 +43.227.76.0/22 +43.227.80.0/22 +43.227.84.0/22 +43.227.88.0/22 +43.227.92.0/22 +43.227.96.0/22 +43.227.100.0/22 +43.227.104.0/22 +43.227.136.0/22 +43.227.140.0/22 +43.227.144.0/22 +43.227.152.0/22 +43.227.156.0/22 +43.227.160.0/22 +43.227.164.0/22 +43.227.168.0/22 +43.227.172.0/22 +43.227.176.0/22 +43.227.180.0/22 +43.227.188.0/22 +43.227.192.0/22 +43.227.196.0/22 +43.227.200.0/22 +43.227.204.0/22 +43.227.208.0/22 +43.227.212.0/22 +43.227.216.0/22 +43.227.220.0/22 +43.227.232.0/22 +43.227.248.0/22 +43.227.252.0/22 +43.228.0.0/22 +43.228.4.0/22 +43.228.8.0/22 +43.228.12.0/22 +43.228.16.0/22 +43.228.20.0/22 +43.228.24.0/22 +43.228.28.0/22 +43.228.32.0/22 +43.228.36.0/22 +43.228.40.0/22 +43.228.44.0/22 +43.228.48.0/22 +43.228.52.0/22 +43.228.56.0/22 +43.228.60.0/22 +43.228.64.0/22 +43.228.68.0/22 +43.228.76.0/22 +43.228.100.0/22 +43.228.116.0/22 +43.228.120.0/22 +43.228.132.0/22 +43.228.136.0/22 +43.228.148.0/22 +43.228.152.0/22 +43.228.188.0/22 +43.228.204.0/22 +43.228.240.0/22 +43.229.40.0/22 +43.229.48.0/22 +43.229.56.0/22 +43.229.96.0/22 +43.229.136.0/22 +43.229.140.0/22 +43.229.144.0/22 +43.229.168.0/22 +43.229.172.0/22 +43.229.176.0/22 +43.229.180.0/22 +43.229.184.0/22 +43.229.188.0/22 +43.229.192.0/22 +43.229.196.0/22 +43.229.216.0/22 +43.229.220.0/22 +43.229.232.0/22 +43.229.236.0/22 +43.230.20.0/22 +43.230.32.0/22 +43.230.68.0/22 +43.230.72.0/22 +43.230.84.0/22 +43.230.124.0/22 +43.230.136.0/22 +43.230.220.0/22 +43.230.224.0/22 +43.230.228.0/22 +43.230.232.0/22 +43.230.236.0/22 +43.230.240.0/22 +43.230.244.0/22 +43.230.248.0/22 +43.230.252.0/22 +43.231.32.0/22 +43.231.36.0/22 +43.231.40.0/22 +43.231.44.0/22 +43.231.80.0/22 +43.231.84.0/22 +43.231.88.0/22 +43.231.92.0/22 +43.231.96.0/22 +43.231.100.0/22 +43.231.104.0/22 +43.231.108.0/22 +43.231.136.0/22 +43.231.140.0/22 +43.231.144.0/22 +43.231.148.0/22 +43.231.152.0/22 +43.231.156.0/22 +43.231.160.0/22 +43.231.164.0/22 +43.231.168.0/22 +43.231.172.0/22 +43.231.176.0/22 +43.231.180.0/22 +43.236.0.0/22 +43.236.4.0/22 +43.236.8.0/22 +43.236.12.0/22 +43.236.16.0/22 +43.236.20.0/22 +43.236.24.0/22 +43.236.28.0/22 +43.236.32.0/22 +43.236.36.0/22 +43.236.40.0/22 +43.236.44.0/22 +43.236.48.0/22 +43.236.52.0/22 +43.236.56.0/22 +43.236.60.0/22 +43.236.64.0/22 +43.236.68.0/22 +43.236.72.0/22 +43.236.76.0/22 +43.236.80.0/22 +43.236.84.0/22 +43.236.88.0/22 +43.236.92.0/22 +43.236.96.0/22 +43.236.100.0/22 +43.236.104.0/22 +43.236.108.0/22 +43.236.112.0/22 +43.236.116.0/22 +43.236.120.0/22 +43.236.124.0/22 +43.236.128.0/22 +43.236.132.0/22 +43.236.136.0/22 +43.236.140.0/22 +43.236.144.0/22 +43.236.148.0/22 +43.236.152.0/22 +43.236.156.0/22 +43.236.160.0/22 +43.236.164.0/22 +43.236.168.0/22 +43.236.172.0/22 +43.236.176.0/22 +43.236.180.0/22 +43.236.184.0/22 +43.236.188.0/22 +43.236.192.0/22 +43.236.196.0/22 +43.236.200.0/22 +43.236.204.0/22 +43.236.208.0/22 +43.236.212.0/22 +43.236.216.0/22 +43.236.220.0/22 +43.236.224.0/22 +43.236.228.0/22 +43.236.232.0/22 +43.236.236.0/22 +43.236.240.0/22 +43.236.244.0/22 +43.236.248.0/22 +43.236.252.0/22 +43.237.0.0/22 +43.237.4.0/22 +43.237.8.0/22 +43.237.12.0/22 +43.237.16.0/22 +43.237.20.0/22 +43.237.24.0/22 +43.237.28.0/22 +43.237.32.0/22 +43.237.36.0/22 +43.237.40.0/22 +43.237.44.0/22 +43.237.48.0/22 +43.237.52.0/22 +43.237.56.0/22 +43.237.60.0/22 +43.237.64.0/22 +43.237.68.0/22 +43.237.72.0/22 +43.237.76.0/22 +43.237.80.0/22 +43.237.84.0/22 +43.237.88.0/22 +43.237.92.0/22 +43.237.96.0/22 +43.237.100.0/22 +43.237.104.0/22 +43.237.108.0/22 +43.237.112.0/22 +43.237.116.0/22 +43.237.120.0/22 +43.237.124.0/22 +43.237.128.0/22 +43.237.132.0/22 +43.237.136.0/22 +43.237.140.0/22 +43.237.144.0/22 +43.237.148.0/22 +43.237.152.0/22 +43.237.156.0/22 +43.237.160.0/22 +43.237.164.0/22 +43.237.168.0/22 +43.237.172.0/22 +43.237.176.0/22 +43.237.180.0/22 +43.237.184.0/22 +43.237.188.0/22 +43.237.192.0/22 +43.237.200.0/22 +43.237.204.0/22 +43.237.208.0/22 +43.237.212.0/22 +43.237.216.0/22 +43.237.220.0/22 +43.237.224.0/22 +43.237.228.0/22 +43.237.232.0/22 +43.237.236.0/22 +43.237.240.0/22 +43.237.244.0/22 +43.237.248.0/22 +43.237.252.0/22 +43.238.0.0/22 +43.238.4.0/22 +43.238.8.0/22 +43.238.12.0/22 +43.238.16.0/22 +43.238.20.0/22 +43.238.24.0/22 +43.238.28.0/22 +43.238.32.0/22 +43.238.36.0/22 +43.238.40.0/22 +43.238.44.0/22 +43.238.48.0/22 +43.238.52.0/22 +43.238.56.0/22 +43.238.60.0/22 +43.238.64.0/22 +43.238.68.0/22 +43.238.72.0/22 +43.238.76.0/22 +43.238.80.0/22 +43.238.84.0/22 +43.238.88.0/22 +43.238.92.0/22 +43.238.96.0/22 +43.238.100.0/22 +43.238.104.0/22 +43.238.108.0/22 +43.238.112.0/22 +43.238.116.0/22 +43.238.120.0/22 +43.238.124.0/22 +43.238.128.0/22 +43.238.132.0/22 +43.238.136.0/22 +43.238.140.0/22 +43.238.144.0/22 +43.238.148.0/22 +43.238.152.0/22 +43.238.156.0/22 +43.238.160.0/22 +43.238.164.0/22 +43.238.168.0/22 +43.238.172.0/22 +43.238.176.0/22 +43.238.180.0/22 +43.238.184.0/22 +43.238.188.0/22 +43.238.192.0/22 +43.238.196.0/22 +43.238.200.0/22 +43.238.204.0/22 +43.238.208.0/22 +43.238.212.0/22 +43.238.216.0/22 +43.238.220.0/22 +43.238.224.0/22 +43.238.228.0/22 +43.238.232.0/22 +43.238.236.0/22 +43.238.240.0/22 +43.238.244.0/22 +43.238.248.0/22 +43.238.252.0/22 +43.239.0.0/22 +43.239.4.0/22 +43.239.8.0/21 +43.239.16.0/22 +43.239.20.0/22 +43.239.24.0/22 +43.239.28.0/22 +43.239.32.0/22 +43.239.36.0/22 +43.239.40.0/22 +43.239.44.0/22 +43.239.48.0/22 +43.239.116.0/22 +43.239.120.0/22 +43.239.172.0/22 +43.239.176.0/22 +43.240.0.0/22 +43.240.56.0/22 +43.240.60.0/22 +43.240.68.0/22 +43.240.72.0/22 +43.240.76.0/22 +43.240.84.0/22 +43.240.124.0/22 +43.240.128.0/22 +43.240.132.0/22 +43.240.136.0/22 +43.240.144.0/22 +43.240.156.0/22 +43.240.160.0/22 +43.240.164.0/22 +43.240.168.0/22 +43.240.172.0/22 +43.240.176.0/22 +43.240.180.0/22 +43.240.184.0/22 +43.240.188.0/22 +43.240.192.0/22 +43.240.196.0/22 +43.240.200.0/22 +43.240.204.0/22 +43.240.208.0/22 +43.240.212.0/22 +43.240.216.0/22 +43.240.220.0/22 +43.240.240.0/22 +43.240.244.0/22 +43.240.248.0/22 +43.240.252.0/22 +43.241.0.0/22 +43.241.4.0/22 +43.241.8.0/22 +43.241.12.0/22 +43.241.16.0/22 +43.241.20.0/22 +43.241.48.0/22 +43.241.76.0/22 +43.241.80.0/22 +43.241.84.0/22 +43.241.88.0/22 +43.241.92.0/22 +43.241.112.0/22 +43.241.168.0/22 +43.241.172.0/22 +43.241.176.0/22 +43.241.180.0/22 +43.241.184.0/22 +43.241.208.0/22 +43.241.212.0/22 +43.241.216.0/22 +43.241.220.0/22 +43.241.224.0/22 +43.241.228.0/22 +43.241.232.0/22 +43.241.236.0/22 +43.241.240.0/22 +43.241.248.0/22 +43.241.252.0/22 +43.242.8.0/22 +43.242.12.0/22 +43.242.16.0/21 +43.242.24.0/22 +43.242.28.0/22 +43.242.44.0/22 +43.242.48.0/22 +43.242.52.0/22 +43.242.56.0/22 +43.242.60.0/22 +43.242.64.0/22 +43.242.72.0/22 +43.242.76.0/22 +43.242.80.0/22 +43.242.84.0/22 +43.242.88.0/22 +43.242.92.0/22 +43.242.96.0/22 +43.242.144.0/22 +43.242.148.0/22 +43.242.152.0/22 +43.242.156.0/22 +43.242.160.0/22 +43.242.164.0/22 +43.242.168.0/22 +43.242.180.0/22 +43.242.188.0/22 +43.242.192.0/22 +43.242.196.0/22 +43.242.204.0/22 +43.242.216.0/22 +43.242.220.0/22 +43.242.252.0/22 +43.243.4.0/22 +43.243.8.0/22 +43.243.12.0/22 +43.243.16.0/22 +43.243.88.0/22 +43.243.128.0/22 +43.243.136.0/22 +43.243.144.0/22 +43.243.148.0/22 +43.243.156.0/22 +43.243.180.0/22 +43.243.228.0/22 +43.243.232.0/22 +43.243.244.0/22 +43.246.0.0/22 +43.246.4.0/22 +43.246.8.0/22 +43.246.12.0/22 +43.246.16.0/22 +43.246.20.0/22 +43.246.24.0/22 +43.246.28.0/22 +43.246.32.0/22 +43.246.36.0/22 +43.246.40.0/22 +43.246.44.0/22 +43.246.48.0/22 +43.246.52.0/22 +43.246.56.0/22 +43.246.60.0/22 +43.246.64.0/22 +43.246.68.0/22 +43.246.72.0/22 +43.246.76.0/22 +43.246.80.0/22 +43.246.84.0/22 +43.246.88.0/22 +43.246.92.0/22 +43.246.96.0/22 +43.246.112.0/22 +43.246.228.0/22 +43.247.4.0/22 +43.247.8.0/22 +43.247.44.0/22 +43.247.48.0/22 +43.247.68.0/22 +43.247.76.0/22 +43.247.84.0/22 +43.247.88.0/22 +43.247.92.0/22 +43.247.96.0/22 +43.247.100.0/22 +43.247.108.0/22 +43.247.112.0/22 +43.247.148.0/22 +43.247.152.0/22 +43.247.176.0/22 +43.247.180.0/22 +43.247.184.0/22 +43.247.188.0/22 +43.247.196.0/22 +43.247.200.0/22 +43.247.204.0/22 +43.247.208.0/22 +43.247.212.0/22 +43.247.216.0/22 +43.247.220.0/22 +43.247.224.0/22 +43.247.228.0/22 +43.247.232.0/22 +43.247.236.0/22 +43.247.240.0/22 +43.247.244.0/22 +43.247.248.0/22 +43.247.252.0/22 +43.248.0.0/22 +43.248.4.0/22 +43.248.20.0/22 +43.248.28.0/22 +43.248.48.0/22 +43.248.76.0/22 +43.248.80.0/22 +43.248.84.0/22 +43.248.88.0/22 +43.248.92.0/22 +43.248.96.0/22 +43.248.100.0/22 +43.248.104.0/22 +43.248.108.0/22 +43.248.112.0/22 +43.248.116.0/22 +43.248.120.0/22 +43.248.124.0/22 +43.248.128.0/22 +43.248.132.0/22 +43.248.136.0/22 +43.248.140.0/22 +43.248.144.0/22 +43.248.148.0/22 +43.248.176.0/22 +43.248.180.0/22 +43.248.184.0/22 +43.248.188.0/22 +43.248.192.0/22 +43.248.196.0/22 +43.248.200.0/22 +43.248.204.0/22 +43.248.208.0/22 +43.248.228.0/22 +43.248.232.0/22 +43.248.244.0/22 +43.249.4.0/22 +43.249.8.0/22 +43.249.120.0/22 +43.249.132.0/22 +43.249.136.0/22 +43.249.144.0/22 +43.249.148.0/22 +43.249.152.0/22 +43.249.156.0/22 +43.249.160.0/22 +43.249.164.0/22 +43.249.168.0/22 +43.249.192.0/22 +43.249.236.0/22 +43.250.4.0/22 +43.250.12.0/22 +43.250.16.0/22 +43.250.20.0/22 +43.250.28.0/22 +43.250.32.0/22 +43.250.36.0/22 +43.250.72.0/22 +43.250.96.0/22 +43.250.100.0/22 +43.250.104.0/22 +43.250.108.0/22 +43.250.112.0/22 +43.250.116.0/22 +43.250.128.0/22 +43.250.144.0/22 +43.250.148.0/22 +43.250.160.0/22 +43.250.168.0/22 +43.250.172.0/22 +43.250.176.0/22 +43.250.200.0/22 +43.250.212.0/22 +43.250.216.0/22 +43.250.220.0/22 +43.250.236.0/22 +43.250.244.0/22 +43.251.4.0/22 +43.251.8.0/22 +43.251.36.0/22 +43.251.100.0/22 +43.251.116.0/22 +43.251.192.0/22 +43.251.232.0/22 +43.251.236.0/22 +43.251.244.0/22 +43.252.48.0/22 +43.252.56.0/22 +43.254.0.0/22 +43.254.4.0/22 +43.254.8.0/22 +43.254.24.0/22 +43.254.36.0/22 +43.254.44.0/22 +43.254.52.0/22 +43.254.64.0/22 +43.254.72.0/22 +43.254.84.0/22 +43.254.88.0/22 +43.254.92.0/22 +43.254.100.0/22 +43.254.104.0/22 +43.254.112.0/22 +43.254.116.0/22 +43.254.128.0/22 +43.254.136.0/22 +43.254.140.0/22 +43.254.144.0/22 +43.254.148.0/22 +43.254.152.0/22 +43.254.156.0/22 +43.254.168.0/22 +43.254.172.0/22 +43.254.180.0/22 +43.254.184.0/22 +43.254.188.0/22 +43.254.192.0/22 +43.254.196.0/22 +43.254.200.0/22 +43.254.208.0/22 +43.254.220.0/22 +43.254.224.0/22 +43.254.228.0/22 +43.254.232.0/22 +43.254.236.0/22 +43.254.240.0/22 +43.254.248.0/22 +43.254.252.0/22 +43.255.0.0/22 +43.255.4.0/22 +43.255.8.0/22 +43.255.16.0/22 +43.255.48.0/22 +43.255.64.0/22 +43.255.68.0/22 +43.255.72.0/22 +43.255.76.0/22 +43.255.84.0/22 +43.255.96.0/22 +43.255.144.0/22 +43.255.176.0/22 +43.255.184.0/22 +43.255.192.0/22 +43.255.200.0/22 +43.255.204.0/22 +43.255.208.0/22 +43.255.212.0/22 +43.255.224.0/22 +43.255.228.0/22 +43.255.232.0/22 +43.255.244.0/22 +45.40.192.0/18 +45.65.16.0/22 +45.65.20.0/22 +45.65.24.0/22 +45.65.28.0/22 +45.112.132.0/22 +45.112.188.0/22 +45.112.208.0/22 +45.112.212.0/22 +45.112.216.0/22 +45.112.220.0/22 +45.112.228.0/22 +45.112.232.0/22 +45.112.236.0/22 +45.113.12.0/22 +45.113.16.0/22 +45.113.20.0/22 +45.113.24.0/22 +45.113.28.0/22 +45.113.40.0/22 +45.113.52.0/22 +45.113.56.0/22 +45.113.72.0/22 +45.113.144.0/22 +45.113.148.0/22 +45.113.168.0/22 +45.113.176.0/22 +45.113.184.0/22 +45.113.200.0/22 +45.113.204.0/22 +45.113.208.0/22 +45.113.212.0/22 +45.113.216.0/22 +45.113.220.0/22 +45.113.240.0/22 +45.113.252.0/22 +45.114.0.0/22 +45.114.32.0/22 +45.114.40.0/22 +45.114.52.0/22 +45.114.96.0/22 +45.114.124.0/22 +45.114.136.0/22 +45.114.196.0/22 +45.114.200.0/22 +45.114.228.0/22 +45.114.252.0/22 +45.115.44.0/22 +45.115.100.0/22 +45.115.120.0/22 +45.115.132.0/22 +45.115.144.0/22 +45.115.156.0/22 +45.115.164.0/22 +45.115.200.0/22 +45.115.212.0/22 +45.115.228.0/22 +45.115.236.0/22 +45.115.244.0/22 +45.115.248.0/22 +45.116.16.0/22 +45.116.24.0/22 +45.116.32.0/22 +45.116.36.0/22 +45.116.52.0/22 +45.116.96.0/22 +45.116.100.0/22 +45.116.140.0/22 +45.116.152.0/22 +45.116.208.0/22 +45.117.8.0/22 +45.117.20.0/22 +45.117.68.0/22 +45.117.124.0/22 +45.117.252.0/22 +45.119.52.0/22 +45.119.60.0/22 +45.119.64.0/22 +45.119.68.0/22 +45.119.72.0/22 +45.119.104.0/22 +45.119.116.0/22 +45.119.232.0/22 +45.120.100.0/22 +45.120.140.0/22 +45.120.164.0/22 +45.120.240.0/22 +45.121.52.0/22 +45.121.64.0/22 +45.121.68.0/22 +45.121.72.0/22 +45.121.92.0/22 +45.121.96.0/22 +45.121.172.0/22 +45.121.176.0/22 +45.121.212.0/22 +45.121.240.0/22 +45.121.244.0/22 +45.121.248.0/22 +45.121.252.0/22 +45.122.0.0/22 +45.122.4.0/22 +45.122.8.0/22 +45.122.12.0/22 +45.122.16.0/22 +45.122.20.0/22 +45.122.24.0/22 +45.122.28.0/22 +45.122.32.0/22 +45.122.36.0/22 +45.122.40.0/22 +45.122.60.0/22 +45.122.64.0/22 +45.122.68.0/22 +45.122.72.0/22 +45.122.76.0/22 +45.122.80.0/22 +45.122.84.0/22 +45.122.88.0/22 +45.122.92.0/22 +45.122.96.0/21 +45.122.104.0/22 +45.122.108.0/22 +45.122.112.0/22 +45.122.116.0/22 +45.122.160.0/22 +45.122.164.0/22 +45.122.168.0/22 +45.122.172.0/22 +45.122.176.0/22 +45.122.180.0/22 +45.122.184.0/22 +45.122.188.0/22 +45.122.192.0/22 +45.122.196.0/22 +45.122.200.0/22 +45.122.204.0/22 +45.122.208.0/22 +45.122.212.0/22 +45.122.216.0/22 +45.123.28.0/22 +45.123.32.0/22 +45.123.36.0/22 +45.123.44.0/22 +45.123.48.0/22 +45.123.52.0/22 +45.123.56.0/22 +45.123.60.0/22 +45.123.64.0/22 +45.123.68.0/22 +45.123.72.0/22 +45.123.76.0/22 +45.123.80.0/22 +45.123.84.0/22 +45.123.88.0/22 +45.123.120.0/22 +45.123.128.0/22 +45.123.132.0/22 +45.123.136.0/22 +45.123.148.0/22 +45.123.152.0/22 +45.123.156.0/22 +45.123.164.0/22 +45.123.168.0/22 +45.123.172.0/22 +45.123.176.0/22 +45.123.180.0/22 +45.123.184.0/22 +45.123.204.0/22 +45.123.212.0/22 +45.123.224.0/22 +45.123.228.0/22 +45.123.232.0/22 +45.123.236.0/22 +45.123.240.0/22 +45.123.244.0/22 +45.123.248.0/22 +45.123.252.0/22 +45.124.0.0/22 +45.124.20.0/22 +45.124.28.0/22 +45.124.32.0/22 +45.124.36.0/22 +45.124.44.0/22 +45.124.68.0/22 +45.124.76.0/22 +45.124.80.0/22 +45.124.100.0/22 +45.124.124.0/22 +45.124.172.0/22 +45.124.176.0/22 +45.124.208.0/22 +45.124.248.0/22 +45.125.16.0/22 +45.125.24.0/22 +45.125.44.0/22 +45.125.52.0/22 +45.125.56.0/22 +45.125.76.0/22 +45.125.80.0/22 +45.125.84.0/22 +45.125.88.0/22 +45.125.92.0/22 +45.125.96.0/22 +45.125.100.0/22 +45.125.136.0/22 +45.126.48.0/22 +45.126.52.0/22 +45.126.100.0/22 +45.126.108.0/22 +45.126.112.0/22 +45.126.116.0/22 +45.126.120.0/22 +45.126.212.0/22 +45.126.220.0/22 +45.127.8.0/22 +45.127.12.0/22 +45.127.128.0/22 +45.127.144.0/22 +45.127.148.0/22 +45.127.156.0/22 +45.127.216.0/22 +45.248.8.0/22 +45.248.80.0/22 +45.248.84.0/22 +45.248.88.0/22 +45.248.96.0/22 +45.248.100.0/22 +45.248.104.0/22 +45.248.108.0/22 +45.248.128.0/22 +45.248.132.0/22 +45.248.204.0/22 +45.248.208.0/22 +45.248.212.0/22 +45.248.216.0/22 +45.248.220.0/22 +45.248.224.0/22 +45.248.228.0/22 +45.248.232.0/22 +45.248.236.0/22 +45.248.240.0/22 +45.248.244.0/22 +45.248.248.0/22 +45.248.252.0/22 +45.249.0.0/22 +45.249.4.0/22 +45.249.12.0/22 +45.249.16.0/22 +45.249.20.0/22 +45.249.24.0/22 +45.249.28.0/22 +45.249.32.0/22 +45.249.36.0/22 +45.249.112.0/22 +45.249.188.0/22 +45.249.192.0/22 +45.249.196.0/22 +45.249.200.0/22 +45.249.204.0/22 +45.249.208.0/22 +45.249.212.0/22 +45.250.12.0/22 +45.250.16.0/22 +45.250.28.0/22 +45.250.32.0/22 +45.250.36.0/22 +45.250.40.0/22 +45.250.76.0/22 +45.250.80.0/22 +45.250.84.0/22 +45.250.88.0/22 +45.250.92.0/22 +45.250.96.0/22 +45.250.104.0/22 +45.250.108.0/22 +45.250.112.0/22 +45.250.116.0/22 +45.250.120.0/22 +45.250.124.0/22 +45.250.128.0/22 +45.250.132.0/22 +45.250.136.0/22 +45.250.140.0/22 +45.250.144.0/22 +45.250.148.0/22 +45.250.152.0/22 +45.250.164.0/22 +45.250.180.0/22 +45.250.184.0/22 +45.250.188.0/22 +45.250.192.0/22 +45.251.0.0/22 +45.251.8.0/22 +45.251.16.0/22 +45.251.20.0/22 +45.251.52.0/22 +45.251.84.0/22 +45.251.88.0/22 +45.251.92.0/22 +45.251.96.0/22 +45.251.100.0/22 +45.251.120.0/22 +45.251.124.0/22 +45.251.136.0/22 +45.251.140.0/22 +45.251.144.0/22 +45.251.148.0/22 +45.251.152.0/22 +45.251.156.0/22 +45.251.160.0/22 +45.251.164.0/22 +45.251.168.0/22 +45.251.172.0/22 +45.251.176.0/22 +45.251.180.0/22 +45.251.184.0/22 +45.251.188.0/22 +45.251.192.0/22 +45.251.196.0/22 +45.251.200.0/22 +45.251.204.0/22 +45.251.208.0/22 +45.251.212.0/22 +45.251.216.0/22 +45.251.220.0/22 +45.251.224.0/22 +45.251.240.0/22 +45.252.0.0/22 +45.252.4.0/22 +45.252.8.0/22 +45.252.12.0/22 +45.252.16.0/22 +45.252.20.0/22 +45.252.24.0/22 +45.252.28.0/22 +45.252.32.0/22 +45.252.36.0/22 +45.252.40.0/22 +45.252.44.0/22 +45.252.48.0/22 +45.252.84.0/22 +45.252.88.0/22 +45.252.92.0/22 +45.252.96.0/22 +45.252.100.0/22 +45.252.104.0/22 +45.252.108.0/22 +45.252.112.0/22 +45.252.116.0/22 +45.252.120.0/22 +45.252.124.0/22 +45.252.128.0/22 +45.252.132.0/22 +45.252.136.0/22 +45.252.140.0/22 +45.252.144.0/22 +45.252.148.0/22 +45.252.152.0/22 +45.252.156.0/22 +45.252.160.0/22 +45.252.164.0/22 +45.252.168.0/22 +45.252.172.0/22 +45.252.176.0/22 +45.252.192.0/22 +45.252.196.0/22 +45.252.200.0/22 +45.252.204.0/22 +45.252.208.0/22 +45.252.212.0/22 +45.252.216.0/22 +45.252.220.0/22 +45.252.224.0/22 +45.252.228.0/22 +45.252.232.0/22 +45.253.0.0/22 +45.253.4.0/22 +45.253.8.0/22 +45.253.12.0/22 +45.253.16.0/22 +45.253.20.0/22 +45.253.24.0/22 +45.253.28.0/22 +45.253.32.0/22 +45.253.36.0/22 +45.253.40.0/22 +45.253.44.0/22 +45.253.48.0/22 +45.253.52.0/22 +45.253.56.0/22 +45.253.60.0/22 +45.253.64.0/22 +45.253.68.0/22 +45.253.72.0/22 +45.253.76.0/22 +45.253.80.0/22 +45.253.84.0/22 +45.253.92.0/22 +45.253.96.0/22 +45.253.100.0/22 +45.253.104.0/22 +45.253.108.0/22 +45.253.112.0/22 +45.253.116.0/22 +45.253.120.0/22 +45.253.132.0/22 +45.253.136.0/22 +45.253.140.0/22 +45.253.144.0/22 +45.253.148.0/22 +45.253.152.0/22 +45.253.156.0/22 +45.253.160.0/22 +45.253.164.0/22 +45.253.168.0/22 +45.253.172.0/22 +45.253.176.0/22 +45.253.180.0/22 +45.253.184.0/22 +45.253.188.0/22 +45.253.192.0/22 +45.253.196.0/22 +45.253.200.0/22 +45.253.204.0/22 +45.253.208.0/22 +45.253.212.0/22 +45.253.216.0/22 +45.253.220.0/22 +45.253.224.0/22 +45.253.228.0/22 +45.253.232.0/22 +45.253.236.0/22 +45.253.240.0/22 +45.253.244.0/22 +45.254.0.0/22 +45.254.4.0/22 +45.254.8.0/22 +45.254.12.0/22 +45.254.16.0/22 +45.254.20.0/22 +45.254.24.0/22 +45.254.28.0/22 +45.254.40.0/22 +45.254.48.0/22 +45.254.52.0/22 +45.254.56.0/22 +45.254.60.0/22 +45.254.64.0/22 +45.254.68.0/22 +45.254.72.0/22 +45.254.76.0/22 +45.254.80.0/22 +45.254.84.0/22 +45.254.88.0/22 +45.254.92.0/22 +45.254.96.0/22 +45.254.100.0/22 +45.254.104.0/22 +45.254.108.0/22 +45.254.112.0/22 +45.254.116.0/22 +45.254.120.0/22 +45.254.124.0/22 +45.254.128.0/22 +45.254.132.0/22 +45.254.136.0/22 +45.254.140.0/22 +45.254.144.0/22 +45.254.148.0/22 +45.254.152.0/22 +45.254.156.0/22 +45.254.160.0/22 +45.254.164.0/22 +45.254.168.0/22 +45.254.172.0/22 +45.254.176.0/22 +45.254.180.0/22 +45.254.184.0/22 +45.254.188.0/22 +45.254.192.0/22 +45.254.196.0/22 +45.254.200.0/22 +45.254.204.0/22 +45.254.208.0/22 +45.254.212.0/22 +45.254.216.0/22 +45.254.220.0/22 +45.254.224.0/22 +45.254.228.0/22 +45.254.236.0/22 +45.254.240.0/22 +45.254.248.0/22 +45.255.0.0/22 +45.255.4.0/22 +45.255.8.0/22 +45.255.12.0/22 +45.255.16.0/22 +45.255.20.0/22 +45.255.24.0/22 +45.255.28.0/22 +45.255.32.0/22 +45.255.36.0/22 +45.255.40.0/22 +45.255.44.0/22 +45.255.48.0/22 +45.255.52.0/22 +45.255.56.0/22 +45.255.60.0/22 +45.255.64.0/22 +45.255.68.0/22 +45.255.72.0/22 +45.255.76.0/22 +45.255.80.0/22 +45.255.84.0/22 +45.255.88.0/22 +45.255.92.0/22 +45.255.96.0/22 +45.255.100.0/22 +45.255.104.0/22 +45.255.108.0/22 +45.255.112.0/22 +45.255.116.0/22 +45.255.120.0/22 +45.255.124.0/22 +45.255.132.0/22 +45.255.136.0/22 +45.255.140.0/22 +45.255.144.0/22 +45.255.148.0/22 +45.255.152.0/22 +45.255.156.0/22 +45.255.160.0/22 +45.255.164.0/22 +45.255.168.0/22 +45.255.172.0/22 +45.255.176.0/22 +45.255.180.0/22 +45.255.184.0/22 +45.255.188.0/22 +45.255.192.0/22 +45.255.196.0/22 +45.255.200.0/22 +45.255.204.0/22 +45.255.208.0/22 +45.255.212.0/22 +45.255.216.0/22 +45.255.220.0/22 +45.255.224.0/22 +45.255.228.0/22 +45.255.232.0/22 +45.255.236.0/22 +45.255.240.0/22 +45.255.244.0/22 +45.255.248.0/22 +47.92.0.0/14 +47.96.0.0/11 +49.4.0.0/14 +49.51.0.0/16 +49.52.0.0/14 +49.64.0.0/11 +49.112.0.0/13 +49.120.0.0/14 +49.128.0.0/24 +49.128.2.0/23 +49.128.4.0/22 +49.140.0.0/15 +49.152.0.0/14 +49.208.0.0/15 +49.210.0.0/15 +49.220.0.0/14 +49.232.0.0/14 +49.239.0.0/18 +49.239.192.0/18 +49.246.224.0/19 +52.80.0.0/15 +52.82.0.0/15 +52.130.0.0/15 +54.222.0.0/15 +57.176.0.0/15 +58.14.0.0/15 +58.16.0.0/16 +58.17.0.0/17 +58.17.128.0/17 +58.18.0.0/16 +58.19.0.0/16 +58.20.0.0/16 +58.21.0.0/16 +58.22.0.0/15 +58.24.0.0/15 +58.30.0.0/15 +58.32.0.0/13 +58.40.0.0/15 +58.42.0.0/16 +58.43.0.0/16 +58.44.0.0/14 +58.48.0.0/13 +58.56.0.0/15 +58.58.0.0/16 +58.59.0.0/17 +58.59.128.0/17 +58.60.0.0/14 +58.65.232.0/21 +58.66.0.0/15 +58.68.128.0/17 +58.82.0.0/17 +58.83.0.0/17 +58.83.128.0/17 +58.87.64.0/18 +58.99.128.0/17 +58.100.0.0/15 +58.116.0.0/14 +58.128.0.0/13 +58.144.0.0/16 +58.154.0.0/15 +58.192.0.0/15 +58.194.0.0/15 +58.196.0.0/15 +58.198.0.0/15 +58.200.0.0/13 +58.208.0.0/12 +58.240.0.0/15 +58.242.0.0/15 +58.244.0.0/15 +58.246.0.0/15 +58.248.0.0/13 +59.32.0.0/13 +59.40.0.0/15 +59.42.0.0/16 +59.43.0.0/16 +59.44.0.0/14 +59.48.0.0/16 +59.49.0.0/17 +59.49.128.0/17 +59.50.0.0/16 +59.51.0.0/17 +59.51.128.0/17 +59.52.0.0/14 +59.56.0.0/14 +59.60.0.0/15 +59.62.0.0/15 +59.64.0.0/14 +59.68.0.0/14 +59.72.0.0/15 +59.74.0.0/15 +59.76.0.0/16 +59.77.0.0/16 +59.78.0.0/15 +59.80.0.0/15 +59.82.0.0/15 +59.107.0.0/17 +59.107.128.0/17 +59.108.0.0/15 +59.110.0.0/15 +59.151.0.0/17 +59.152.16.0/22 +59.152.20.0/22 +59.152.24.0/22 +59.152.28.0/22 +59.152.32.0/22 +59.152.36.0/22 +59.152.64.0/22 +59.152.68.0/22 +59.152.72.0/22 +59.152.76.0/22 +59.152.112.0/22 +59.152.116.0/22 +59.153.4.0/22 +59.153.32.0/22 +59.153.60.0/22 +59.153.64.0/22 +59.153.68.0/22 +59.153.72.0/22 +59.153.92.0/22 +59.153.116.0/22 +59.153.136.0/22 +59.153.152.0/22 +59.153.164.0/22 +59.153.168.0/22 +59.153.172.0/22 +59.153.176.0/22 +59.153.180.0/22 +59.153.184.0/22 +59.153.188.0/22 +59.153.192.0/22 +59.155.0.0/16 +59.172.0.0/15 +59.174.0.0/15 +59.191.0.0/17 +59.192.0.0/10 +60.0.0.0/13 +60.8.0.0/15 +60.10.0.0/16 +60.11.0.0/16 +60.12.0.0/16 +60.13.0.0/18 +60.13.64.0/18 +60.13.128.0/17 +60.14.0.0/15 +60.16.0.0/13 +60.24.0.0/14 +60.28.0.0/15 +60.30.0.0/16 +60.31.0.0/16 +60.55.0.0/16 +60.63.0.0/16 +60.160.0.0/15 +60.162.0.0/15 +60.164.0.0/15 +60.166.0.0/15 +60.168.0.0/13 +60.176.0.0/12 +60.194.0.0/15 +60.200.0.0/14 +60.204.0.0/16 +60.205.0.0/16 +60.206.0.0/15 +60.208.0.0/13 +60.216.0.0/15 +60.218.0.0/15 +60.220.0.0/14 +60.232.0.0/15 +60.235.0.0/16 +60.245.128.0/17 +60.247.0.0/16 +60.252.0.0/16 +60.253.128.0/17 +60.255.0.0/16 +61.4.80.0/22 +61.4.84.0/22 +61.4.88.0/21 +61.4.176.0/20 +61.8.160.0/20 +61.14.212.0/22 +61.14.216.0/22 +61.14.220.0/22 +61.14.240.0/22 +61.14.244.0/22 +61.28.0.0/20 +61.28.16.0/20 +61.28.32.0/19 +61.28.64.0/18 +61.29.128.0/18 +61.29.192.0/19 +61.29.224.0/20 +61.29.240.0/21 +61.29.248.0/22 +61.29.254.0/23 +61.45.128.0/18 +61.45.224.0/20 +61.47.128.0/18 +61.48.0.0/14 +61.52.0.0/15 +61.54.0.0/16 +61.55.0.0/16 +61.87.192.0/18 +61.128.0.0/15 +61.130.0.0/15 +61.132.0.0/16 +61.133.0.0/17 +61.133.128.0/17 +61.134.0.0/18 +61.134.64.0/19 +61.134.96.0/19 +61.134.128.0/18 +61.134.192.0/18 +61.135.0.0/16 +61.136.0.0/18 +61.136.64.0/18 +61.136.128.0/17 +61.137.0.0/17 +61.137.128.0/17 +61.138.0.0/18 +61.138.64.0/18 +61.138.128.0/18 +61.138.192.0/18 +61.139.0.0/17 +61.139.128.0/18 +61.139.192.0/18 +61.140.0.0/14 +61.144.0.0/14 +61.148.0.0/15 +61.150.0.0/15 +61.152.0.0/16 +61.153.0.0/16 +61.154.0.0/15 +61.156.0.0/16 +61.157.0.0/16 +61.158.0.0/17 +61.158.128.0/17 +61.159.0.0/18 +61.159.64.0/18 +61.159.128.0/17 +61.160.0.0/16 +61.161.0.0/18 +61.161.64.0/18 +61.161.128.0/17 +61.162.0.0/16 +61.163.0.0/16 +61.164.0.0/16 +61.165.0.0/16 +61.166.0.0/16 +61.167.0.0/16 +61.168.0.0/16 +61.169.0.0/16 +61.170.0.0/15 +61.172.0.0/14 +61.176.0.0/16 +61.177.0.0/16 +61.178.0.0/16 +61.179.0.0/16 +61.180.0.0/17 +61.180.128.0/17 +61.181.0.0/16 +61.182.0.0/16 +61.183.0.0/16 +61.184.0.0/14 +61.188.0.0/16 +61.189.0.0/17 +61.189.128.0/17 +61.190.0.0/15 +61.232.0.0/14 +61.236.0.0/15 +61.240.0.0/14 +62.234.0.0/16 +68.79.0.0/18 +69.230.192.0/18 +69.231.128.0/18 +69.234.192.0/18 +69.235.128.0/18 +71.131.192.0/18 +71.132.0.0/18 +71.136.64.0/18 +71.137.0.0/18 +81.68.0.0/14 +82.156.0.0/15 +94.191.0.0/17 +101.0.0.0/22 +101.1.0.0/22 +101.2.172.0/22 +101.4.0.0/14 +101.16.0.0/12 +101.33.128.0/17 +101.34.0.0/15 +101.36.0.0/18 +101.36.64.0/19 +101.36.128.0/17 +101.37.0.0/16 +101.38.0.0/15 +101.40.0.0/15 +101.42.0.0/15 +101.47.0.0/16 +101.48.0.0/15 +101.50.8.0/22 +101.50.12.0/22 +101.50.56.0/22 +101.52.0.0/16 +101.53.100.0/22 +101.54.0.0/16 +101.55.224.0/21 +101.64.0.0/13 +101.72.0.0/14 +101.76.0.0/15 +101.78.0.0/22 +101.78.32.0/19 +101.80.0.0/12 +101.96.0.0/21 +101.96.8.0/22 +101.96.16.0/20 +101.96.128.0/17 +101.99.96.0/19 +101.101.64.0/19 +101.101.100.0/24 +101.101.102.0/23 +101.101.104.0/21 +101.101.112.0/20 +101.102.64.0/19 +101.102.100.0/23 +101.102.102.0/24 +101.102.104.0/21 +101.102.112.0/20 +101.104.0.0/14 +101.110.64.0/19 +101.110.96.0/20 +101.110.116.0/22 +101.110.120.0/21 +101.120.0.0/14 +101.124.0.0/15 +101.126.0.0/16 +101.128.0.0/22 +101.128.8.0/21 +101.128.16.0/20 +101.128.32.0/19 +101.129.0.0/16 +101.130.0.0/15 +101.132.0.0/14 +101.144.0.0/12 +101.192.0.0/14 +101.196.0.0/16 +101.197.0.0/16 +101.198.0.0/15 +101.200.0.0/15 +101.203.128.0/19 +101.203.160.0/21 +101.203.172.0/22 +101.203.176.0/20 +101.204.0.0/14 +101.224.0.0/13 +101.232.0.0/15 +101.234.64.0/21 +101.234.76.0/22 +101.234.80.0/20 +101.234.96.0/19 +101.236.0.0/14 +101.240.0.0/14 +101.244.0.0/16 +101.245.0.0/16 +101.246.0.0/15 +101.248.0.0/15 +101.251.0.0/22 +101.251.8.0/21 +101.251.16.0/20 +101.251.32.0/19 +101.251.64.0/18 +101.251.128.0/17 +101.252.0.0/15 +101.254.0.0/16 +103.1.8.0/22 +103.1.20.0/22 +103.1.24.0/22 +103.1.72.0/22 +103.1.88.0/22 +103.1.168.0/22 +103.2.108.0/22 +103.2.156.0/22 +103.2.164.0/22 +103.2.200.0/22 +103.2.204.0/22 +103.2.208.0/22 +103.2.212.0/22 +103.3.84.0/22 +103.3.88.0/22 +103.3.92.0/22 +103.3.96.0/22 +103.3.100.0/22 +103.3.104.0/22 +103.3.108.0/22 +103.3.112.0/22 +103.3.116.0/22 +103.3.120.0/22 +103.3.124.0/22 +103.3.128.0/22 +103.3.132.0/22 +103.3.136.0/22 +103.3.140.0/22 +103.3.148.0/22 +103.3.152.0/22 +103.3.156.0/22 +103.4.56.0/22 +103.4.168.0/22 +103.4.184.0/22 +103.4.224.0/22 +103.5.36.0/22 +103.5.52.0/22 +103.5.56.0/22 +103.5.152.0/22 +103.5.168.0/22 +103.5.192.0/22 +103.5.252.0/22 +103.6.76.0/22 +103.6.108.0/22 +103.6.220.0/22 +103.6.228.0/22 +103.7.28.0/22 +103.7.140.0/22 +103.7.212.0/22 +103.7.216.0/22 +103.7.220.0/22 +103.8.0.0/22 +103.8.4.0/22 +103.8.8.0/22 +103.8.32.0/22 +103.8.52.0/22 +103.8.68.0/22 +103.8.108.0/22 +103.8.156.0/22 +103.8.200.0/22 +103.8.204.0/22 +103.8.220.0/22 +103.9.8.0/22 +103.9.24.0/22 +103.9.108.0/22 +103.9.152.0/22 +103.9.248.0/22 +103.9.252.0/22 +103.10.0.0/22 +103.10.16.0/22 +103.10.84.0/22 +103.10.140.0/22 +103.11.16.0/22 +103.11.168.0/22 +103.11.180.0/22 +103.12.32.0/22 +103.12.68.0/22 +103.12.92.0/22 +103.12.98.0/23 +103.12.136.0/22 +103.12.184.0/22 +103.12.232.0/22 +103.13.12.0/22 +103.13.124.0/22 +103.13.144.0/22 +103.13.196.0/22 +103.13.220.0/22 +103.13.244.0/22 +103.14.84.0/22 +103.14.100.0/22 +103.14.132.0/22 +103.14.136.0/22 +103.14.156.0/22 +103.14.240.0/22 +103.15.4.0/22 +103.15.8.0/22 +103.15.16.0/22 +103.15.96.0/22 +103.15.200.0/22 +103.16.52.0/22 +103.16.80.0/22 +103.16.84.0/22 +103.16.88.0/22 +103.16.108.0/22 +103.16.124.0/22 +103.17.40.0/22 +103.17.64.0/22 +103.17.120.0/22 +103.17.136.0/22 +103.17.160.0/22 +103.17.204.0/22 +103.17.228.0/22 +103.18.186.0/23 +103.18.192.0/22 +103.18.206.0/23 +103.18.208.0/22 +103.18.212.0/22 +103.18.224.0/22 +103.19.12.0/22 +103.19.40.0/22 +103.19.44.0/22 +103.19.50.0/23 +103.19.64.0/22 +103.19.68.0/22 +103.19.72.0/22 +103.19.232.0/22 +103.20.12.0/22 +103.20.32.0/22 +103.20.44.0/22 +103.20.68.0/22 +103.20.112.0/22 +103.20.128.0/22 +103.20.160.0/22 +103.20.248.0/22 +103.21.112.0/22 +103.21.116.0/22 +103.21.136.0/22 +103.21.140.0/22 +103.21.176.0/22 +103.21.208.0/22 +103.21.240.0/22 +103.22.0.0/22 +103.22.4.0/22 +103.22.8.0/22 +103.22.12.0/22 +103.22.16.0/22 +103.22.20.0/22 +103.22.24.0/22 +103.22.28.0/22 +103.22.32.0/22 +103.22.36.0/22 +103.22.40.0/22 +103.22.44.0/22 +103.22.48.0/22 +103.22.52.0/22 +103.22.56.0/22 +103.22.60.0/22 +103.22.64.0/22 +103.22.68.0/22 +103.22.72.0/22 +103.22.76.0/22 +103.22.80.0/22 +103.22.84.0/22 +103.22.88.0/22 +103.22.92.0/22 +103.22.100.0/22 +103.22.104.0/22 +103.22.108.0/22 +103.22.112.0/22 +103.22.116.0/22 +103.22.120.0/22 +103.22.124.0/22 +103.22.188.0/22 +103.22.228.0/22 +103.22.252.0/22 +103.23.8.0/22 +103.23.56.0/22 +103.23.160.0/22 +103.23.164.0/22 +103.23.176.0/22 +103.23.228.0/22 +103.24.24.0/22 +103.24.116.0/22 +103.24.128.0/22 +103.24.144.0/22 +103.24.176.0/22 +103.24.184.0/22 +103.24.220.0/22 +103.24.228.0/22 +103.24.252.0/22 +103.25.8.0/23 +103.25.20.0/22 +103.25.24.0/22 +103.25.28.0/22 +103.25.32.0/22 +103.25.36.0/22 +103.25.40.0/22 +103.25.48.0/22 +103.25.64.0/22 +103.25.68.0/22 +103.25.148.0/22 +103.25.156.0/22 +103.25.216.0/22 +103.26.0.0/22 +103.26.64.0/22 +103.26.76.0/22 +103.26.132.0/22 +103.26.156.0/22 +103.26.160.0/22 +103.26.228.0/22 +103.26.240.0/22 +103.27.4.0/22 +103.27.12.0/22 +103.27.24.0/22 +103.27.56.0/22 +103.27.96.0/22 +103.27.184.0/22 +103.27.208.0/22 +103.27.212.0/22 +103.27.240.0/22 +103.28.4.0/22 +103.28.8.0/22 +103.28.184.0/22 +103.28.204.0/22 +103.28.212.0/22 +103.29.16.0/22 +103.29.24.0/23 +103.29.29.0/24 +103.29.128.0/22 +103.29.132.0/22 +103.29.136.0/22 +103.29.236.0/23 +103.30.20.0/22 +103.30.96.0/22 +103.30.104.0/23 +103.30.106.0/23 +103.30.148.0/22 +103.30.200.0/22 +103.30.228.0/22 +103.30.236.0/22 +103.31.0.0/22 +103.31.48.0/22 +103.31.52.0/22 +103.31.56.0/22 +103.31.60.0/22 +103.31.64.0/22 +103.31.68.0/22 +103.31.148.0/22 +103.31.160.0/22 +103.31.168.0/22 +103.31.200.0/22 +103.31.236.0/22 +103.31.242.0/23 +103.32.0.0/22 +103.32.4.0/22 +103.32.8.0/22 +103.32.12.0/22 +103.32.16.0/22 +103.32.20.0/22 +103.32.24.0/22 +103.32.28.0/22 +103.32.32.0/22 +103.32.36.0/22 +103.32.40.0/22 +103.32.44.0/22 +103.32.48.0/22 +103.32.52.0/22 +103.32.56.0/22 +103.32.60.0/22 +103.32.64.0/22 +103.32.68.0/22 +103.32.72.0/22 +103.32.76.0/22 +103.32.80.0/22 +103.32.84.0/22 +103.32.88.0/22 +103.32.92.0/22 +103.32.96.0/22 +103.32.100.0/22 +103.32.104.0/22 +103.32.108.0/22 +103.32.112.0/22 +103.32.116.0/22 +103.32.120.0/22 +103.32.124.0/22 +103.32.128.0/22 +103.32.132.0/22 +103.32.136.0/22 +103.32.140.0/22 +103.32.144.0/22 +103.32.148.0/22 +103.32.152.0/22 +103.32.156.0/22 +103.32.160.0/22 +103.32.164.0/22 +103.32.168.0/22 +103.32.172.0/22 +103.32.176.0/22 +103.32.180.0/22 +103.32.184.0/22 +103.32.188.0/22 +103.32.192.0/22 +103.32.196.0/22 +103.32.200.0/22 +103.32.204.0/22 +103.32.208.0/22 +103.32.212.0/22 +103.32.216.0/22 +103.32.220.0/22 +103.32.224.0/22 +103.32.228.0/22 +103.32.232.0/22 +103.32.236.0/22 +103.32.240.0/22 +103.32.244.0/22 +103.32.248.0/22 +103.32.252.0/22 +103.33.0.0/22 +103.33.4.0/22 +103.33.8.0/22 +103.33.12.0/22 +103.33.16.0/22 +103.33.20.0/22 +103.33.24.0/22 +103.33.28.0/22 +103.33.32.0/22 +103.33.36.0/22 +103.33.40.0/22 +103.33.44.0/22 +103.33.48.0/22 +103.33.52.0/22 +103.33.56.0/22 +103.33.60.0/22 +103.33.64.0/22 +103.33.68.0/22 +103.33.72.0/22 +103.33.76.0/22 +103.33.80.0/22 +103.33.84.0/22 +103.33.88.0/22 +103.33.92.0/22 +103.33.96.0/22 +103.33.100.0/22 +103.33.104.0/22 +103.33.108.0/22 +103.33.112.0/22 +103.33.116.0/22 +103.33.120.0/22 +103.33.124.0/22 +103.33.128.0/22 +103.33.132.0/22 +103.33.136.0/22 +103.33.140.0/22 +103.33.144.0/22 +103.33.148.0/22 +103.33.152.0/22 +103.33.156.0/22 +103.33.160.0/22 +103.33.164.0/22 +103.33.168.0/22 +103.33.172.0/22 +103.33.176.0/22 +103.33.180.0/22 +103.33.184.0/22 +103.33.188.0/22 +103.33.192.0/22 +103.33.196.0/22 +103.33.200.0/22 +103.33.204.0/22 +103.33.208.0/22 +103.33.212.0/22 +103.33.216.0/22 +103.33.220.0/22 +103.33.224.0/22 +103.33.228.0/22 +103.33.232.0/22 +103.33.236.0/22 +103.33.240.0/22 +103.33.244.0/22 +103.33.248.0/22 +103.33.252.0/22 +103.34.0.0/22 +103.34.4.0/22 +103.34.8.0/22 +103.34.12.0/22 +103.34.16.0/22 +103.34.20.0/22 +103.34.24.0/22 +103.34.28.0/22 +103.34.32.0/22 +103.34.36.0/22 +103.34.40.0/22 +103.34.44.0/22 +103.34.48.0/22 +103.34.52.0/22 +103.34.56.0/22 +103.34.60.0/22 +103.34.64.0/22 +103.34.68.0/22 +103.34.72.0/22 +103.34.76.0/22 +103.34.80.0/22 +103.34.84.0/22 +103.34.88.0/22 +103.34.92.0/22 +103.34.96.0/22 +103.34.100.0/22 +103.34.104.0/22 +103.34.108.0/22 +103.34.112.0/22 +103.34.116.0/22 +103.34.120.0/22 +103.34.124.0/22 +103.34.128.0/22 +103.34.132.0/22 +103.34.136.0/22 +103.34.140.0/22 +103.34.144.0/22 +103.34.148.0/22 +103.34.152.0/22 +103.34.156.0/22 +103.34.160.0/22 +103.34.164.0/22 +103.34.168.0/22 +103.34.172.0/22 +103.34.176.0/22 +103.34.180.0/22 +103.34.184.0/22 +103.34.188.0/22 +103.34.192.0/22 +103.34.196.0/22 +103.34.200.0/22 +103.34.204.0/22 +103.34.208.0/22 +103.34.212.0/22 +103.34.216.0/22 +103.34.220.0/22 +103.34.224.0/22 +103.34.228.0/22 +103.34.232.0/22 +103.34.236.0/22 +103.34.240.0/22 +103.34.244.0/22 +103.34.248.0/22 +103.34.252.0/22 +103.35.0.0/22 +103.35.4.0/22 +103.35.8.0/22 +103.35.12.0/22 +103.35.16.0/22 +103.35.20.0/22 +103.35.24.0/22 +103.35.28.0/22 +103.35.32.0/22 +103.35.36.0/22 +103.35.40.0/22 +103.35.44.0/22 +103.35.48.0/22 +103.35.104.0/22 +103.35.116.0/22 +103.35.180.0/22 +103.35.220.0/22 +103.36.28.0/22 +103.36.36.0/22 +103.36.56.0/22 +103.36.60.0/22 +103.36.64.0/22 +103.36.72.0/22 +103.36.96.0/22 +103.36.132.0/22 +103.36.136.0/22 +103.36.160.0/22 +103.36.164.0/22 +103.36.168.0/22 +103.36.172.0/22 +103.36.176.0/22 +103.36.180.0/22 +103.36.184.0/22 +103.36.188.0/22 +103.36.192.0/22 +103.36.196.0/22 +103.36.200.0/22 +103.36.204.0/22 +103.36.208.0/22 +103.36.212.0/22 +103.36.216.0/22 +103.36.220.0/22 +103.36.224.0/22 +103.36.228.0/22 +103.36.232.0/22 +103.36.236.0/22 +103.36.240.0/22 +103.36.244.0/22 +103.37.12.0/22 +103.37.16.0/22 +103.37.24.0/22 +103.37.44.0/22 +103.37.52.0/22 +103.37.56.0/22 +103.37.72.0/22 +103.37.100.0/22 +103.37.104.0/22 +103.37.136.0/22 +103.37.140.0/22 +103.37.144.0/22 +103.37.148.0/22 +103.37.152.0/22 +103.37.156.0/22 +103.37.160.0/22 +103.37.164.0/22 +103.37.172.0/22 +103.37.176.0/22 +103.37.188.0/22 +103.37.208.0/22 +103.37.212.0/22 +103.37.216.0/21 +103.37.248.0/22 +103.37.252.0/22 +103.38.0.0/22 +103.38.32.0/22 +103.38.40.0/22 +103.38.44.0/22 +103.38.56.0/22 +103.38.76.0/22 +103.38.84.0/22 +103.38.92.0/22 +103.38.96.0/22 +103.38.116.0/22 +103.38.132.0/22 +103.38.140.0/22 +103.38.224.0/22 +103.38.228.0/22 +103.38.232.0/22 +103.39.64.0/22 +103.39.88.0/22 +103.39.100.0/22 +103.39.104.0/22 +103.39.160.0/22 +103.39.164.0/22 +103.39.168.0/22 +103.39.172.0/22 +103.39.176.0/22 +103.39.180.0/22 +103.39.184.0/22 +103.39.188.0/22 +103.39.200.0/22 +103.39.204.0/22 +103.39.208.0/22 +103.39.212.0/22 +103.39.216.0/22 +103.39.220.0/22 +103.39.224.0/22 +103.39.228.0/22 +103.39.232.0/22 +103.40.12.0/22 +103.40.16.0/22 +103.40.20.0/22 +103.40.24.0/22 +103.40.28.0/22 +103.40.32.0/22 +103.40.36.0/22 +103.40.40.0/22 +103.40.44.0/22 +103.40.88.0/22 +103.40.100.0/22 +103.40.158.0/23 +103.40.192.0/22 +103.40.212.0/22 +103.40.220.0/22 +103.40.228.0/22 +103.40.232.0/22 +103.40.236.0/22 +103.40.240.0/22 +103.40.244.0/22 +103.40.248.0/22 +103.40.252.0/22 +103.41.0.0/22 +103.41.16.0/22 +103.41.52.0/22 +103.41.116.0/22 +103.41.140.0/22 +103.41.148.0/22 +103.41.152.0/22 +103.41.160.0/22 +103.41.164.0/22 +103.41.220.0/22 +103.41.224.0/22 +103.41.228.0/22 +103.41.232.0/22 +103.42.8.0/22 +103.42.24.0/22 +103.42.28.0/22 +103.42.32.0/22 +103.42.64.0/22 +103.42.68.0/22 +103.42.76.0/22 +103.42.104.0/22 +103.42.180.0/22 +103.42.232.0/22 +103.43.16.0/22 +103.43.84.0/22 +103.43.96.0/22 +103.43.100.0/22 +103.43.104.0/22 +103.43.124.0/22 +103.43.132.0/22 +103.43.184.0/22 +103.43.192.0/22 +103.43.196.0/22 +103.43.208.0/22 +103.43.220.0/22 +103.43.224.0/22 +103.43.240.0/22 +103.44.56.0/22 +103.44.80.0/22 +103.44.120.0/22 +103.44.124.0/22 +103.44.132.0/22 +103.44.144.0/22 +103.44.168.0/22 +103.44.176.0/22 +103.44.180.0/22 +103.44.184.0/22 +103.44.188.0/22 +103.44.192.0/22 +103.44.196.0/22 +103.44.200.0/22 +103.44.204.0/22 +103.44.224.0/22 +103.44.236.0/22 +103.44.240.0/22 +103.44.244.0/22 +103.44.248.0/22 +103.44.252.0/22 +103.45.0.0/22 +103.45.4.0/22 +103.45.8.0/22 +103.45.12.0/22 +103.45.16.0/22 +103.45.20.0/22 +103.45.24.0/22 +103.45.28.0/22 +103.45.32.0/22 +103.45.36.0/22 +103.45.40.0/22 +103.45.44.0/22 +103.45.48.0/22 +103.45.52.0/22 +103.45.56.0/22 +103.45.60.0/22 +103.45.72.0/22 +103.45.76.0/22 +103.45.80.0/22 +103.45.84.0/22 +103.45.88.0/22 +103.45.92.0/22 +103.45.96.0/22 +103.45.100.0/22 +103.45.104.0/22 +103.45.108.0/22 +103.45.112.0/22 +103.45.116.0/22 +103.45.120.0/22 +103.45.124.0/22 +103.45.128.0/22 +103.45.132.0/22 +103.45.136.0/22 +103.45.140.0/22 +103.45.144.0/22 +103.45.148.0/22 +103.45.152.0/22 +103.45.156.0/22 +103.45.160.0/22 +103.45.164.0/22 +103.45.168.0/22 +103.45.172.0/22 +103.45.176.0/22 +103.45.180.0/22 +103.45.184.0/22 +103.45.188.0/22 +103.45.192.0/22 +103.45.196.0/22 +103.45.200.0/22 +103.45.204.0/22 +103.45.208.0/22 +103.45.212.0/22 +103.45.216.0/22 +103.45.220.0/22 +103.45.224.0/22 +103.45.248.0/22 +103.46.0.0/22 +103.46.12.0/22 +103.46.16.0/22 +103.46.20.0/22 +103.46.24.0/22 +103.46.28.0/22 +103.46.32.0/22 +103.46.36.0/22 +103.46.40.0/22 +103.46.44.0/22 +103.46.48.0/22 +103.46.52.0/22 +103.46.56.0/22 +103.46.60.0/22 +103.46.64.0/22 +103.46.68.0/22 +103.46.72.0/22 +103.46.76.0/22 +103.46.80.0/22 +103.46.84.0/22 +103.46.88.0/22 +103.46.92.0/22 +103.46.96.0/22 +103.46.100.0/22 +103.46.104.0/22 +103.46.108.0/22 +103.46.112.0/22 +103.46.116.0/22 +103.46.120.0/22 +103.46.124.0/22 +103.46.128.0/22 +103.46.132.0/22 +103.46.136.0/22 +103.46.152.0/22 +103.46.156.0/22 +103.46.160.0/22 +103.46.164.0/22 +103.46.168.0/22 +103.46.172.0/22 +103.46.176.0/22 +103.46.180.0/22 +103.46.244.0/22 +103.46.248.0/22 +103.47.4.0/22 +103.47.20.0/22 +103.47.36.0/22 +103.47.40.0/22 +103.47.48.0/22 +103.47.80.0/22 +103.47.96.0/22 +103.47.108.0/22 +103.47.116.0/22 +103.47.120.0/22 +103.47.136.0/22 +103.47.140.0/22 +103.47.212.0/22 +103.48.52.0/22 +103.48.92.0/22 +103.48.148.0/22 +103.48.152.0/22 +103.48.156.0/22 +103.48.202.0/23 +103.48.216.0/22 +103.48.220.0/22 +103.48.224.0/22 +103.48.228.0/22 +103.48.232.0/22 +103.48.236.0/22 +103.48.240.0/22 +103.48.244.0/22 +103.49.12.0/22 +103.49.20.0/22 +103.49.72.0/22 +103.49.76.0/22 +103.49.96.0/22 +103.49.108.0/22 +103.49.128.0/22 +103.49.176.0/22 +103.49.180.0/22 +103.49.196.0/22 +103.50.36.0/22 +103.50.44.0/22 +103.50.48.0/22 +103.50.52.0/22 +103.50.56.0/22 +103.50.60.0/22 +103.50.64.0/22 +103.50.68.0/22 +103.50.72.0/22 +103.50.108.0/22 +103.50.112.0/22 +103.50.116.0/22 +103.50.120.0/22 +103.50.124.0/22 +103.50.132.0/22 +103.50.136.0/22 +103.50.140.0/22 +103.50.172.0/22 +103.50.176.0/22 +103.50.180.0/22 +103.50.184.0/22 +103.50.188.0/22 +103.50.192.0/22 +103.50.196.0/22 +103.50.200.0/22 +103.50.220.0/22 +103.50.224.0/22 +103.50.228.0/22 +103.50.232.0/22 +103.50.236.0/22 +103.50.240.0/22 +103.50.244.0/22 +103.50.248.0/22 +103.52.40.0/22 +103.52.72.0/22 +103.52.76.0/22 +103.52.80.0/22 +103.52.84.0/22 +103.52.96.0/22 +103.52.100.0/22 +103.52.104.0/22 +103.52.160.0/22 +103.52.164.0/22 +103.52.172.0/22 +103.52.176.0/22 +103.52.184.0/22 +103.52.196.0/22 +103.53.64.0/22 +103.53.68.0/22 +103.53.92.0/22 +103.53.100.0/22 +103.53.124.0/22 +103.53.128.0/22 +103.53.132.0/22 +103.53.136.0/22 +103.53.140.0/22 +103.53.144.0/22 +103.53.180.0/22 +103.53.204.0/22 +103.53.208.0/22 +103.53.212.0/22 +103.53.236.0/22 +103.53.248.0/22 +103.54.8.0/22 +103.54.48.0/22 +103.54.160.0/22 +103.54.164.0/22 +103.54.212.0/22 +103.54.240.0/22 +103.55.80.0/22 +103.55.120.0/22 +103.55.152.0/22 +103.55.172.0/22 +103.55.204.0/22 +103.55.208.0/22 +103.55.228.0/22 +103.55.236.0/22 +103.56.8.0/22 +103.56.16.0/22 +103.56.20.0/22 +103.56.32.0/22 +103.56.56.0/22 +103.56.60.0/22 +103.56.72.0/22 +103.56.76.0/22 +103.56.94.0/23 +103.56.100.0/22 +103.56.104.0/22 +103.56.140.0/22 +103.56.152.0/22 +103.56.184.0/22 +103.56.200.0/22 +103.57.12.0/22 +103.57.52.0/22 +103.57.56.0/22 +103.57.76.0/22 +103.57.136.0/22 +103.57.196.0/22 +103.58.24.0/22 +103.59.76.0/22 +103.59.100.0/22 +103.59.112.0/22 +103.59.116.0/22 +103.59.120.0/22 +103.59.124.0/22 +103.59.128.0/22 +103.59.148.0/22 +103.59.164.0/22 +103.59.168.0/23 +103.60.32.0/22 +103.60.44.0/22 +103.60.164.0/22 +103.60.228.0/22 +103.60.236.0/22 +103.61.60.0/22 +103.61.104.0/22 +103.61.140.0/22 +103.61.152.0/22 +103.61.156.0/22 +103.61.160.0/22 +103.61.172.0/22 +103.61.176.0/22 +103.61.188.0/22 +103.62.24.0/22 +103.62.52.0/22 +103.62.72.0/22 +103.62.76.0/22 +103.62.80.0/22 +103.62.84.0/22 +103.62.88.0/22 +103.62.96.0/22 +103.62.100.0/22 +103.62.104.0/22 +103.62.108.0/22 +103.62.112.0/22 +103.62.116.0/22 +103.62.120.0/22 +103.62.124.0/22 +103.62.128.0/22 +103.62.132.0/22 +103.62.156.0/22 +103.62.160.0/22 +103.62.164.0/22 +103.62.168.0/22 +103.62.172.0/22 +103.62.176.0/22 +103.62.180.0/22 +103.62.184.0/22 +103.62.188.0/22 +103.62.192.0/22 +103.62.204.0/22 +103.62.208.0/22 +103.62.212.0/22 +103.62.216.0/22 +103.62.220.0/22 +103.62.224.0/22 +103.63.32.0/22 +103.63.36.0/22 +103.63.40.0/22 +103.63.44.0/22 +103.63.48.0/22 +103.63.52.0/22 +103.63.56.0/22 +103.63.60.0/22 +103.63.64.0/22 +103.63.68.0/22 +103.63.72.0/22 +103.63.76.0/22 +103.63.80.0/22 +103.63.84.0/22 +103.63.88.0/22 +103.63.140.0/22 +103.63.144.0/22 +103.63.152.0/22 +103.63.160.0/22 +103.63.164.0/22 +103.63.168.0/22 +103.63.172.0/22 +103.63.176.0/22 +103.63.180.0/22 +103.63.184.0/22 +103.63.192.0/22 +103.63.196.0/22 +103.63.200.0/22 +103.63.204.0/22 +103.63.208.0/22 +103.63.240.0/22 +103.63.244.0/22 +103.63.248.0/22 +103.63.252.0/22 +103.64.0.0/22 +103.64.4.0/22 +103.64.24.0/22 +103.64.28.0/22 +103.64.32.0/22 +103.64.36.0/22 +103.64.40.0/22 +103.64.44.0/22 +103.64.48.0/22 +103.64.52.0/22 +103.64.56.0/22 +103.64.60.0/22 +103.64.64.0/22 +103.64.68.0/22 +103.64.72.0/22 +103.64.76.0/22 +103.64.80.0/22 +103.64.84.0/22 +103.64.88.0/22 +103.64.92.0/22 +103.64.96.0/22 +103.64.100.0/22 +103.64.104.0/22 +103.64.108.0/22 +103.64.112.0/22 +103.64.116.0/22 +103.64.120.0/22 +103.64.124.0/22 +103.64.140.0/22 +103.64.144.0/22 +103.64.152.0/22 +103.64.156.0/22 +103.64.160.0/22 +103.64.164.0/22 +103.64.168.0/22 +103.64.172.0/22 +103.64.176.0/22 +103.64.180.0/22 +103.64.184.0/22 +103.64.188.0/22 +103.64.192.0/22 +103.64.196.0/22 +103.64.200.0/22 +103.64.204.0/22 +103.64.208.0/22 +103.64.212.0/22 +103.64.216.0/22 +103.64.220.0/22 +103.64.224.0/22 +103.64.228.0/22 +103.64.232.0/22 +103.64.236.0/22 +103.64.240.0/22 +103.64.244.0/22 +103.64.248.0/22 +103.64.252.0/22 +103.65.0.0/22 +103.65.4.0/22 +103.65.8.0/22 +103.65.12.0/22 +103.65.16.0/22 +103.65.36.0/22 +103.65.40.0/22 +103.65.48.0/22 +103.65.52.0/22 +103.65.56.0/22 +103.65.60.0/22 +103.65.64.0/22 +103.65.68.0/22 +103.65.72.0/22 +103.65.76.0/22 +103.65.80.0/22 +103.65.84.0/22 +103.65.88.0/22 +103.65.92.0/22 +103.65.100.0/22 +103.65.104.0/22 +103.65.108.0/22 +103.65.112.0/22 +103.65.144.0/22 +103.65.148.0/22 +103.65.152.0/22 +103.65.156.0/22 +103.65.160.0/22 +103.65.164.0/22 +103.65.168.0/22 +103.65.172.0/22 +103.65.204.0/23 +103.65.206.0/23 +103.65.224.0/23 +103.66.32.0/22 +103.66.40.0/22 +103.66.92.0/22 +103.66.108.0/22 +103.66.200.0/22 +103.66.216.0/22 +103.66.240.0/22 +103.66.244.0/22 +103.66.248.0/22 +103.66.252.0/22 +103.67.0.0/22 +103.67.4.0/22 +103.67.8.0/22 +103.67.100.0/22 +103.67.104.0/22 +103.67.108.0/22 +103.67.112.0/22 +103.67.116.0/22 +103.67.120.0/22 +103.67.124.0/22 +103.67.128.0/22 +103.67.132.0/22 +103.67.136.0/22 +103.67.140.0/22 +103.67.144.0/22 +103.67.148.0/22 +103.67.172.0/22 +103.67.192.0/22 +103.67.212.0/22 +103.67.252.0/22 +103.68.64.0/22 +103.68.88.0/22 +103.68.100.0/22 +103.68.128.0/22 +103.68.192.0/22 +103.69.16.0/22 +103.69.62.0/23 +103.69.116.0/22 +103.69.132.0/22 +103.69.152.0/22 +103.70.8.0/22 +103.70.14.0/23 +103.70.148.0/22 +103.70.220.0/22 +103.70.224.0/22 +103.70.236.0/22 +103.70.252.0/22 +103.71.0.0/22 +103.71.48.0/22 +103.71.68.0/22 +103.71.72.0/22 +103.71.80.0/22 +103.71.84.0/22 +103.71.88.0/22 +103.71.120.0/22 +103.71.124.0/22 +103.71.128.0/22 +103.71.144.0/22 +103.71.196.0/22 +103.71.200.0/22 +103.71.232.0/22 +103.72.12.0/22 +103.72.16.0/22 +103.72.20.0/22 +103.72.24.0/22 +103.72.28.0/22 +103.72.32.0/22 +103.72.36.0/22 +103.72.40.0/22 +103.72.44.0/22 +103.72.48.0/22 +103.72.52.0/22 +103.72.112.0/22 +103.72.116.0/22 +103.72.120.0/22 +103.72.124.0/22 +103.72.128.0/22 +103.72.132.0/22 +103.72.148.0/22 +103.72.172.0/22 +103.72.180.0/22 +103.72.224.0/22 +103.72.228.0/22 +103.72.232.0/22 +103.72.236.0/22 +103.72.240.0/22 +103.72.244.0/22 +103.72.248.0/22 +103.72.252.0/22 +103.73.0.0/22 +103.73.4.0/22 +103.73.8.0/22 +103.73.12.0/22 +103.73.16.0/22 +103.73.20.0/22 +103.73.24.0/22 +103.73.28.0/22 +103.73.48.0/22 +103.73.116.0/22 +103.73.120.0/22 +103.73.128.0/22 +103.73.132.0/22 +103.73.136.0/22 +103.73.140.0/22 +103.73.144.0/22 +103.73.168.0/22 +103.73.176.0/22 +103.73.204.0/22 +103.73.208.0/22 +103.73.240.0/22 +103.73.244.0/22 +103.73.248.0/22 +103.74.24.0/22 +103.74.28.0/22 +103.74.32.0/22 +103.74.36.0/22 +103.74.40.0/22 +103.74.44.0/22 +103.74.48.0/22 +103.74.56.0/22 +103.74.60.0/22 +103.74.80.0/22 +103.74.124.0/22 +103.74.148.0/22 +103.74.152.0/22 +103.74.156.0/22 +103.74.204.0/22 +103.74.232.0/22 +103.75.88.0/22 +103.75.92.0/22 +103.75.104.0/22 +103.75.108.0/22 +103.75.112.0/22 +103.75.120.0/22 +103.75.128.0/22 +103.75.144.0/22 +103.75.152.0/22 +103.75.236.0/24 +103.76.60.0/22 +103.76.64.0/22 +103.76.68.0/22 +103.76.72.0/22 +103.76.92.0/22 +103.76.216.0/22 +103.76.220.0/22 +103.76.224.0/22 +103.77.28.0/22 +103.77.52.0/22 +103.77.56.0/22 +103.77.72.0/22 +103.77.88.0/22 +103.77.92.0/22 +103.77.132.0/22 +103.77.148.0/22 +103.77.220.0/22 +103.78.56.0/22 +103.78.60.0/22 +103.78.64.0/22 +103.78.68.0/22 +103.78.124.0/22 +103.78.172.0/22 +103.78.176.0/22 +103.78.196.0/22 +103.78.228.0/22 +103.79.24.0/22 +103.79.28.0/22 +103.79.36.0/22 +103.79.40.0/22 +103.79.44.0/22 +103.79.52.0/22 +103.79.56.0/22 +103.79.60.0/22 +103.79.64.0/22 +103.79.68.0/22 +103.79.80.0/22 +103.79.84.0/22 +103.79.120.0/22 +103.79.136.0/22 +103.79.188.0/22 +103.79.192.0/22 +103.79.196.0/22 +103.79.200.0/22 +103.79.204.0/22 +103.79.208.0/22 +103.79.212.0/22 +103.79.228.0/23 +103.79.240.0/22 +103.80.28.0/22 +103.80.44.0/22 +103.80.72.0/22 +103.80.176.0/22 +103.80.180.0/22 +103.80.184.0/22 +103.80.192.0/22 +103.80.200.0/22 +103.80.232.0/22 +103.81.4.0/22 +103.81.8.0/22 +103.81.16.0/22 +103.81.20.0/22 +103.81.44.0/22 +103.81.48.0/22 +103.81.96.0/22 +103.81.120.0/22 +103.81.148.0/22 +103.81.164.0/22 +103.81.168.0/22 +103.81.183.0/24 +103.81.184.0/22 +103.81.200.0/22 +103.81.232.0/22 +103.82.52.0/22 +103.82.60.0/22 +103.82.68.0/22 +103.82.84.0/22 +103.82.104.0/22 +103.82.224.0/22 +103.82.236.0/22 +103.83.44.0/22 +103.83.52.0/22 +103.83.60.0/22 +103.83.64.0/22 +103.83.72.0/22 +103.83.112.0/22 +103.83.120.0/22 +103.83.180.0/22 +103.84.0.0/22 +103.84.12.0/22 +103.84.16.0/22 +103.84.20.0/22 +103.84.24.0/22 +103.84.28.0/22 +103.84.48.0/22 +103.84.64.0/22 +103.84.72.0/22 +103.84.136.0/22 +103.85.20.0/22 +103.85.24.0/22 +103.85.44.0/22 +103.85.48.0/22 +103.85.84.0/22 +103.85.136.0/22 +103.85.144.0/22 +103.85.164.0/22 +103.85.168.0/22 +103.85.172.0/22 +103.85.176.0/22 +103.85.224.0/22 +103.86.28.0/22 +103.86.32.0/22 +103.86.60.0/22 +103.86.80.0/22 +103.86.84.0/22 +103.86.204.0/22 +103.86.208.0/22 +103.86.212.0/22 +103.86.216.0/22 +103.86.220.0/22 +103.86.224.0/22 +103.86.228.0/22 +103.86.232.0/22 +103.86.236.0/22 +103.86.240.0/22 +103.86.244.0/22 +103.86.248.0/22 +103.86.252.0/22 +103.87.0.0/22 +103.87.4.0/22 +103.87.20.0/22 +103.87.32.0/22 +103.87.72.0/22 +103.87.96.0/22 +103.87.132.0/22 +103.87.180.0/22 +103.87.224.0/22 +103.88.4.0/22 +103.88.8.0/22 +103.88.12.0/22 +103.88.16.0/22 +103.88.20.0/22 +103.88.32.0/22 +103.88.36.0/22 +103.88.60.0/22 +103.88.64.0/22 +103.88.72.0/22 +103.88.96.0/22 +103.88.164.0/22 +103.88.176.0/22 +103.88.188.0/22 +103.88.212.0/22 +103.89.28.0/22 +103.89.96.0/22 +103.89.100.0/22 +103.89.104.0/22 +103.89.108.0/22 +103.89.112.0/22 +103.89.116.0/22 +103.89.148.0/22 +103.89.172.0/22 +103.89.184.0/22 +103.89.188.0/22 +103.89.192.0/22 +103.89.196.0/22 +103.89.200.0/22 +103.89.204.0/22 +103.89.208.0/22 +103.89.212.0/22 +103.89.216.0/22 +103.89.220.0/22 +103.89.224.0/22 +103.89.228.0/22 +103.90.52.0/22 +103.90.92.0/22 +103.90.100.0/22 +103.90.104.0/22 +103.90.108.0/22 +103.90.112.0/22 +103.90.116.0/22 +103.90.120.0/22 +103.90.124.0/22 +103.90.128.0/22 +103.90.132.0/22 +103.90.152.0/22 +103.90.168.0/22 +103.90.173.0/24 +103.90.176.0/22 +103.90.188.0/22 +103.90.192.0/22 +103.91.36.0/22 +103.91.40.0/22 +103.91.108.0/22 +103.91.112.0/23 +103.91.138.0/23 +103.91.152.0/22 +103.91.176.0/22 +103.91.200.0/22 +103.91.208.0/22 +103.91.212.0/22 +103.91.236.0/22 +103.91.252.0/22 +103.92.0.0/22 +103.92.4.0/22 +103.92.8.0/22 +103.92.12.0/22 +103.92.48.0/22 +103.92.52.0/22 +103.92.56.0/22 +103.92.60.0/22 +103.92.64.0/22 +103.92.68.0/22 +103.92.72.0/22 +103.92.76.0/22 +103.92.80.0/22 +103.92.86.0/24 +103.92.88.0/22 +103.92.108.0/22 +103.92.124.0/22 +103.92.128.0/24 +103.92.132.0/22 +103.92.156.0/22 +103.92.164.0/22 +103.92.168.0/22 +103.92.172.0/22 +103.92.176.0/22 +103.92.180.0/22 +103.92.184.0/22 +103.92.188.0/22 +103.92.192.0/22 +103.92.236.0/22 +103.92.240.0/22 +103.92.244.0/22 +103.92.248.0/22 +103.92.252.0/22 +103.93.0.0/22 +103.93.4.0/22 +103.93.28.0/22 +103.93.76.0/22 +103.93.84.0/22 +103.93.152.0/22 +103.93.180.0/22 +103.93.204.0/22 +103.94.12.0/22 +103.94.20.0/22 +103.94.28.0/22 +103.94.32.0/22 +103.94.36.0/22 +103.94.40.0/22 +103.94.44.0/22 +103.94.72.0/22 +103.94.88.0/22 +103.94.116.0/22 +103.94.160.0/22 +103.94.200.0/22 +103.95.52.0/22 +103.95.64.0/22 +103.95.68.0/22 +103.95.88.0/22 +103.95.92.0/22 +103.95.128.0/22 +103.95.136.0/22 +103.95.140.0/22 +103.95.144.0/22 +103.95.152.0/22 +103.95.216.0/22 +103.95.220.0/22 +103.95.224.0/22 +103.95.236.0/22 +103.95.240.0/22 +103.95.244.0/22 +103.95.248.0/22 +103.95.252.0/22 +103.96.0.0/22 +103.96.8.0/22 +103.96.80.0/22 +103.96.124.0/22 +103.96.136.0/22 +103.96.140.0/24 +103.96.152.0/22 +103.96.156.0/22 +103.96.160.0/22 +103.96.164.0/22 +103.96.168.0/22 +103.96.172.0/22 +103.96.176.0/22 +103.96.180.0/22 +103.96.184.0/22 +103.96.188.0/22 +103.96.192.0/22 +103.96.196.0/22 +103.96.200.0/22 +103.96.204.0/22 +103.96.208.0/22 +103.96.212.0/22 +103.96.216.0/22 +103.97.8.0/22 +103.97.12.0/22 +103.97.16.0/22 +103.97.20.0/22 +103.97.24.0/22 +103.97.28.0/22 +103.97.32.0/22 +103.97.36.0/22 +103.97.40.0/22 +103.97.56.0/22 +103.97.60.0/22 +103.97.64.0/22 +103.97.68.0/22 +103.97.72.0/22 +103.97.80.0/22 +103.97.112.0/22 +103.97.116.0/22 +103.97.128.0/22 +103.97.144.0/22 +103.97.148.0/22 +103.97.188.0/22 +103.97.192.0/22 +103.97.228.0/23 +103.98.28.0/23 +103.98.40.0/22 +103.98.44.0/22 +103.98.48.0/22 +103.98.56.0/22 +103.98.80.0/22 +103.98.88.0/22 +103.98.92.0/22 +103.98.96.0/22 +103.98.100.0/22 +103.98.124.0/22 +103.98.136.0/22 +103.98.140.0/22 +103.98.144.0/22 +103.98.164.0/22 +103.98.168.0/22 +103.98.180.0/22 +103.98.196.0/22 +103.98.216.0/22 +103.98.220.0/22 +103.98.224.0/22 +103.98.228.0/22 +103.98.232.0/22 +103.98.240.0/22 +103.98.244.0/22 +103.98.248.0/22 +103.98.252.0/22 +103.99.40.0/23 +103.99.52.0/22 +103.99.56.0/22 +103.99.60.0/22 +103.99.76.0/22 +103.99.104.0/22 +103.99.116.0/22 +103.99.120.0/22 +103.99.152.0/22 +103.99.220.0/22 +103.99.232.0/22 +103.99.236.0/22 +103.100.0.0/22 +103.100.32.0/22 +103.100.40.0/22 +103.100.48.0/22 +103.100.52.0/22 +103.100.56.0/22 +103.100.60.0/22 +103.100.64.0/22 +103.100.68.0/22 +103.100.88.0/22 +103.100.116.0/22 +103.100.144.0/22 +103.100.236.0/22 +103.100.240.0/22 +103.100.248.0/22 +103.100.252.0/22 +103.101.4.0/22 +103.101.8.0/22 +103.101.12.0/22 +103.101.28.0/22 +103.101.60.0/22 +103.101.120.0/22 +103.101.124.0/22 +103.101.144.0/22 +103.101.148.0/22 +103.101.180.0/22 +103.101.184.0/22 +103.102.76.0/22 +103.102.80.0/22 +103.102.168.0/22 +103.102.172.0/22 +103.102.180.0/22 +103.102.184.0/22 +103.102.188.0/22 +103.102.192.0/22 +103.102.196.0/22 +103.102.200.0/22 +103.102.208.0/22 +103.102.212.0/22 +103.103.12.0/22 +103.103.16.0/22 +103.103.36.0/22 +103.103.68.0/22 +103.103.72.0/22 +103.103.176.0/22 +103.103.188.0/22 +103.103.200.0/22 +103.103.204.0/22 +103.103.220.0/22 +103.103.224.0/22 +103.103.228.0/22 +103.103.232.0/22 +103.103.248.0/22 +103.103.252.0/22 +103.104.0.0/22 +103.104.4.0/22 +103.104.36.0/22 +103.104.40.0/22 +103.104.64.0/22 +103.104.104.0/22 +103.104.152.0/22 +103.104.168.0/22 +103.104.172.0/22 +103.104.188.0/22 +103.104.198.0/23 +103.104.252.0/22 +103.105.0.0/22 +103.105.4.0/22 +103.105.12.0/22 +103.105.16.0/22 +103.105.23.0/24 +103.105.60.0/22 +103.105.116.0/22 +103.105.132.0/22 +103.105.180.0/22 +103.105.184.0/22 +103.105.200.0/22 +103.105.204.0/22 +103.105.220.0/22 +103.106.36.0/22 +103.106.40.0/22 +103.106.44.0/22 +103.106.60.0/22 +103.106.68.0/22 +103.106.96.0/22 +103.106.120.0/22 +103.106.128.0/22 +103.106.132.0/22 +103.106.160.0/22 +103.106.196.0/22 +103.106.202.0/23 +103.106.212.0/22 +103.106.244.0/22 +103.106.252.0/22 +103.107.0.0/22 +103.107.28.0/22 +103.107.32.0/22 +103.107.44.0/22 +103.107.72.0/22 +103.107.108.0/22 +103.107.164.0/22 +103.107.168.0/22 +103.107.188.0/22 +103.107.192.0/22 +103.107.208.0/22 +103.107.212.0/22 +103.107.216.0/22 +103.107.220.0/22 +103.108.52.0/22 +103.108.160.0/22 +103.108.164.0/22 +103.108.184.0/23 +103.108.188.0/23 +103.108.192.0/22 +103.108.196.0/22 +103.108.208.0/22 +103.108.212.0/22 +103.108.224.0/22 +103.108.244.0/22 +103.109.20.0/22 +103.109.48.0/22 +103.109.88.0/22 +103.109.106.0/23 +103.109.248.0/22 +103.110.80.0/23 +103.110.92.0/22 +103.110.116.0/22 +103.110.132.0/22 +103.110.136.0/22 +103.110.152.0/22 +103.110.156.0/22 +103.110.188.0/22 +103.110.204.0/22 +103.111.64.0/22 +103.111.172.0/22 +103.111.252.0/22 +103.112.28.0/22 +103.112.68.0/22 +103.112.72.0/22 +103.112.88.0/22 +103.112.92.0/22 +103.112.96.0/22 +103.112.108.0/22 +103.112.112.0/22 +103.112.116.0/22 +103.112.140.0/22 +103.112.172.0/22 +103.112.184.0/22 +103.113.4.0/22 +103.113.92.0/22 +103.113.144.0/22 +103.113.220.0/22 +103.113.232.0/22 +103.113.236.0/22 +103.114.4.0/22 +103.114.28.0/22 +103.114.68.0/22 +103.114.72.0/22 +103.114.100.0/22 +103.114.132.0/22 +103.114.148.0/22 +103.114.156.0/22 +103.114.176.0/22 +103.114.212.0/22 +103.114.236.0/22 +103.114.240.0/22 +103.115.16.0/22 +103.115.40.0/22 +103.115.44.0/22 +103.115.48.0/22 +103.115.52.0/22 +103.115.56.0/22 +103.115.60.0/22 +103.115.64.0/22 +103.115.68.0/22 +103.115.92.0/22 +103.115.120.0/22 +103.115.148.0/22 +103.115.204.0/23 +103.115.248.0/22 +103.116.20.0/22 +103.116.40.0/22 +103.116.64.0/22 +103.116.72.0/22 +103.116.76.0/22 +103.116.92.0/22 +103.116.120.0/22 +103.116.128.0/22 +103.116.132.0/23 +103.116.148.0/22 +103.116.184.0/22 +103.116.206.0/23 +103.116.220.0/22 +103.116.224.0/22 +103.116.228.0/22 +103.117.16.0/22 +103.117.72.0/22 +103.117.88.0/22 +103.117.136.0/22 +103.117.188.0/22 +103.117.220.0/22 +103.118.36.0/22 +103.118.52.0/22 +103.118.56.0/22 +103.118.60.0/22 +103.118.64.0/22 +103.118.68.0/22 +103.118.72.0/22 +103.118.88.0/22 +103.118.173.0/24 +103.118.192.0/22 +103.118.196.0/22 +103.118.200.0/22 +103.118.204.0/22 +103.118.208.0/22 +103.118.212.0/22 +103.118.216.0/22 +103.118.220.0/22 +103.118.240.0/22 +103.118.244.0/22 +103.118.248.0/22 +103.118.252.0/22 +103.119.0.0/22 +103.119.12.0/22 +103.119.16.0/22 +103.119.28.0/22 +103.119.44.0/22 +103.119.104.0/22 +103.119.115.0/24 +103.119.156.0/22 +103.119.180.0/22 +103.119.200.0/22 +103.119.224.0/22 +103.120.52.0/22 +103.120.72.0/22 +103.120.88.0/22 +103.120.96.0/22 +103.120.100.0/22 +103.120.140.0/22 +103.120.196.0/22 +103.120.224.0/22 +103.121.52.0/22 +103.121.92.0/22 +103.121.160.0/22 +103.121.164.0/22 +103.121.250.0/24 +103.121.252.0/22 +103.122.48.0/22 +103.122.176.0/22 +103.122.192.0/22 +103.122.240.0/22 +103.123.4.0/22 +103.123.56.0/22 +103.123.88.0/22 +103.123.92.0/22 +103.123.116.0/22 +103.123.160.0/22 +103.123.176.0/22 +103.123.200.0/22 +103.123.204.0/22 +103.123.208.0/22 +103.123.212.0/22 +103.124.24.0/22 +103.124.48.0/22 +103.124.64.0/22 +103.124.212.0/22 +103.124.216.0/22 +103.125.20.0/22 +103.125.44.0/22 +103.125.132.0/22 +103.125.164.0/22 +103.125.196.0/22 +103.125.236.0/22 +103.125.248.0/22 +103.126.0.0/22 +103.126.16.0/22 +103.126.44.0/22 +103.126.100.0/22 +103.126.124.0/22 +103.126.128.0/22 +103.126.132.0/22 +103.126.208.0/22 +103.129.52.0/22 +103.130.132.0/22 +103.130.152.0/24 +103.130.160.0/22 +103.130.228.0/22 +103.131.20.0/22 +103.131.36.0/22 +103.131.152.0/22 +103.131.168.0/22 +103.131.176.0/22 +103.131.224.0/22 +103.131.228.0/22 +103.131.240.0/22 +103.132.60.0/22 +103.132.64.0/22 +103.132.68.0/22 +103.132.72.0/22 +103.132.76.0/22 +103.132.80.0/22 +103.132.104.0/22 +103.132.108.0/22 +103.132.112.0/22 +103.132.116.0/22 +103.132.120.0/22 +103.132.160.0/22 +103.132.164.0/22 +103.132.188.0/22 +103.132.208.0/22 +103.132.212.0/22 +103.132.234.0/23 +103.133.12.0/22 +103.133.40.0/22 +103.133.128.0/22 +103.133.136.0/22 +103.133.176.0/22 +103.133.232.0/22 +103.134.12.0/24 +103.134.196.0/22 +103.135.80.0/22 +103.135.124.0/22 +103.135.148.0/22 +103.135.156.0/22 +103.135.160.0/22 +103.135.164.0/22 +103.135.176.0/22 +103.135.184.0/22 +103.135.192.0/22 +103.135.196.0/22 +103.135.236.0/22 +103.136.128.0/22 +103.136.232.0/22 +103.137.58.0/23 +103.137.60.0/24 +103.137.76.0/22 +103.137.136.0/23 +103.137.149.0/24 +103.137.180.0/22 +103.137.236.0/22 +103.138.2.0/23 +103.138.12.0/23 +103.138.80.0/22 +103.138.134.0/23 +103.138.156.0/23 +103.138.208.0/23 +103.138.220.0/23 +103.138.246.0/23 +103.138.248.0/23 +103.139.0.0/23 +103.139.2.0/23 +103.139.22.0/23 +103.139.92.0/23 +103.139.113.0/24 +103.139.134.0/23 +103.139.136.0/23 +103.139.172.0/23 +103.139.204.0/23 +103.139.212.0/23 +103.140.8.0/23 +103.140.14.0/23 +103.140.70.0/23 +103.140.126.0/23 +103.140.140.0/23 +103.140.144.0/23 +103.140.152.0/23 +103.140.192.0/23 +103.140.228.0/23 +103.141.10.0/23 +103.141.58.0/23 +103.141.128.0/23 +103.141.186.0/23 +103.141.242.0/23 +103.142.28.0/23 +103.142.58.0/23 +103.142.82.0/23 +103.142.96.0/23 +103.142.102.0/23 +103.142.122.0/23 +103.142.128.0/23 +103.142.140.0/23 +103.142.154.0/23 +103.142.156.0/23 +103.142.172.0/23 +103.142.180.0/23 +103.142.186.0/23 +103.142.190.0/23 +103.142.220.0/23 +103.142.230.0/24 +103.142.234.0/23 +103.142.238.0/23 +103.142.248.0/23 +103.143.16.0/23 +103.143.18.0/23 +103.143.31.0/24 +103.143.74.0/23 +103.143.120.0/23 +103.143.124.0/23 +103.143.132.0/23 +103.143.134.0/23 +103.143.174.0/23 +103.143.228.0/23 +103.144.40.0/23 +103.144.52.0/23 +103.144.66.0/23 +103.144.70.0/23 +103.144.72.0/23 +103.144.108.0/23 +103.144.136.0/23 +103.144.148.0/23 +103.144.158.0/23 +103.144.240.0/23 +103.145.38.0/23 +103.145.40.0/23 +103.145.42.0/23 +103.145.60.0/23 +103.145.72.0/23 +103.145.80.0/23 +103.145.86.0/23 +103.145.92.0/23 +103.145.94.0/23 +103.145.98.0/23 +103.145.106.0/23 +103.145.122.0/23 +103.145.188.0/23 +103.145.190.0/23 +103.146.72.0/23 +103.146.88.0/23 +103.146.90.0/23 +103.146.124.0/23 +103.146.126.0/23 +103.146.138.0/23 +103.146.230.0/23 +103.146.236.0/23 +103.146.252.0/23 +103.147.12.0/23 +103.147.124.0/23 +103.147.198.0/23 +103.147.206.0/23 +103.148.174.0/23 +103.149.6.0/23 +103.149.17.0/24 +103.149.44.0/23 +103.149.110.0/23 +103.149.132.0/23 +103.149.144.0/23 +103.149.156.0/23 +103.149.181.0/24 +103.149.210.0/23 +103.149.214.0/23 +103.149.220.0/23 +103.149.242.0/23 +103.149.244.0/23 +103.149.246.0/23 +103.149.248.0/23 +103.150.24.0/23 +103.150.66.0/23 +103.150.72.0/23 +103.150.122.0/23 +103.150.126.0/23 +103.150.128.0/23 +103.150.130.0/23 +103.150.146.0/23 +103.150.164.0/23 +103.150.172.0/23 +103.150.180.0/23 +103.150.200.0/23 +103.150.210.0/23 +103.150.214.0/23 +103.150.216.0/23 +103.150.244.0/23 +103.151.4.0/23 +103.151.44.0/23 +103.151.138.0/23 +103.151.142.0/23 +103.151.148.0/23 +103.151.150.0/23 +103.151.158.0/23 +103.151.178.0/23 +103.151.206.0/23 +103.151.216.0/23 +103.151.228.0/23 +103.152.14.0/23 +103.152.24.0/23 +103.152.28.0/23 +103.152.30.0/23 +103.152.56.0/23 +103.152.76.0/23 +103.152.98.0/23 +103.152.112.0/23 +103.152.120.0/23 +103.152.122.0/23 +103.152.132.0/23 +103.152.152.0/23 +103.152.168.0/23 +103.152.170.0/23 +103.152.186.0/23 +103.152.190.0/23 +103.152.192.0/23 +103.152.200.0/23 +103.152.208.0/23 +103.152.224.0/23 +103.152.226.0/23 +103.152.246.0/23 +103.152.250.0/23 +103.153.4.0/23 +103.153.36.0/23 +103.153.100.0/23 +103.153.114.0/23 +103.153.122.0/23 +103.153.128.0/23 +103.153.132.0/23 +103.153.138.0/23 +103.153.146.0/23 +103.153.160.0/23 +103.154.18.0/23 +103.154.30.0/23 +103.154.32.0/23 +103.154.40.0/23 +103.154.66.0/23 +103.154.162.0/23 +103.154.164.0/23 +103.154.168.0/23 +103.154.242.0/23 +103.155.14.0/23 +103.155.16.0/23 +103.155.34.0/23 +103.155.48.0/23 +103.155.76.0/23 +103.155.100.0/23 +103.155.110.0/23 +103.155.120.0/23 +103.155.214.0/23 +103.155.248.0/23 +103.156.28.0/23 +103.156.68.0/23 +103.156.78.0/23 +103.156.104.0/23 +103.156.158.0/23 +103.156.174.0/23 +103.156.186.0/23 +103.156.228.0/23 +103.157.30.0/23 +103.157.138.0/23 +103.157.174.0/23 +103.157.212.0/23 +103.157.234.0/23 +103.157.254.0/23 +103.158.0.0/23 +103.158.8.0/23 +103.158.16.0/23 +103.158.190.0/23 +103.158.200.0/23 +103.158.224.0/23 +103.159.80.0/23 +103.159.122.0/23 +103.159.124.0/23 +103.159.134.0/23 +103.159.142.0/23 +103.160.32.0/23 +103.160.34.0/23 +103.160.112.0/23 +103.160.114.0/23 +103.160.244.0/23 +103.160.254.0/23 +103.161.14.0/23 +103.161.102.0/23 +103.161.138.0/23 +103.161.208.0/23 +103.161.220.0/23 +103.161.254.0/23 +103.162.10.0/23 +103.162.32.0/23 +103.162.116.0/23 +103.163.28.0/23 +103.163.32.0/23 +103.163.46.0/23 +103.163.74.0/23 +103.163.180.0/23 +103.164.4.0/23 +103.164.32.0/23 +103.164.40.0/23 +103.164.42.0/23 +103.164.64.0/23 +103.164.76.0/23 +103.164.178.0/23 +103.165.44.0/23 +103.165.52.0/23 +103.165.82.0/23 +103.165.110.0/23 +103.166.20.0/23 +103.166.50.0/23 +103.166.52.0/23 +103.166.54.0/23 +103.166.84.0/23 +103.166.138.0/23 +103.166.242.0/23 +103.166.246.0/23 +103.167.0.0/23 +103.167.36.0/23 +103.168.98.0/23 +103.168.170.0/23 +103.169.50.0/23 +103.169.62.0/23 +103.169.108.0/23 +103.169.162.0/23 +103.169.202.0/23 +103.169.216.0/23 +103.170.4.0/23 +103.170.72.0/23 +103.170.134.0/23 +103.170.210.0/23 +103.170.212.0/23 +103.171.32.0/23 +103.171.166.0/23 +103.171.214.0/23 +103.172.32.0/23 +103.172.160.0/23 +103.172.191.0/24 +103.173.102.0/23 +103.173.182.0/23 +103.173.184.0/23 +103.174.94.0/23 +103.175.14.0/23 +103.175.98.0/23 +103.175.114.0/23 +103.175.118.0/23 +103.176.52.0/23 +103.176.222.0/23 +103.176.244.0/23 +103.177.28.0/23 +103.177.44.0/23 +103.177.70.0/23 +103.177.136.0/23 +103.177.162.0/23 +103.178.56.0/23 +103.178.240.0/23 +103.179.76.0/23 +103.179.78.0/23 +103.180.108.0/23 +103.180.226.0/23 +103.181.164.0/23 +103.181.234.0/23 +103.183.26.0/23 +103.183.66.0/23 +103.183.122.0/23 +103.183.124.0/23 +103.184.44.0/23 +103.184.46.0/23 +103.184.60.0/23 +103.185.78.0/23 +103.185.80.0/23 +103.185.228.0/23 +103.186.4.0/23 +103.186.108.0/23 +103.186.112.0/23 +103.186.136.0/23 +103.186.158.0/23 +103.186.162.0/23 +103.186.228.0/23 +103.189.92.0/23 +103.189.140.0/23 +103.189.152.0/23 +103.189.154.0/23 +103.190.20.0/23 +103.190.71.0/24 +103.190.104.0/23 +103.190.116.0/23 +103.190.118.0/23 +103.190.122.0/23 +103.191.102.0/23 +103.191.242.0/23 +103.192.0.0/22 +103.192.4.0/22 +103.192.8.0/22 +103.192.12.0/22 +103.192.16.0/22 +103.192.20.0/22 +103.192.24.0/22 +103.192.28.0/22 +103.192.48.0/22 +103.192.52.0/22 +103.192.56.0/22 +103.192.84.0/22 +103.192.88.0/22 +103.192.92.0/22 +103.192.96.0/22 +103.192.100.0/22 +103.192.104.0/22 +103.192.108.0/22 +103.192.112.0/22 +103.192.128.0/22 +103.192.132.0/22 +103.192.136.0/22 +103.192.140.0/22 +103.192.144.0/22 +103.192.164.0/22 +103.192.188.0/22 +103.192.208.0/22 +103.192.212.0/22 +103.192.216.0/22 +103.192.252.0/22 +103.193.40.0/22 +103.193.44.0/22 +103.193.120.0/22 +103.193.140.0/22 +103.193.160.0/22 +103.193.188.0/22 +103.193.192.0/22 +103.193.212.0/22 +103.193.216.0/22 +103.193.220.0/22 +103.193.224.0/22 +103.193.228.0/22 +103.193.232.0/22 +103.193.236.0/22 +103.194.16.0/22 +103.195.104.0/22 +103.195.112.0/22 +103.195.148.0/22 +103.195.152.0/22 +103.195.160.0/22 +103.196.64.0/22 +103.196.72.0/22 +103.196.88.0/22 +103.196.92.0/22 +103.196.96.0/22 +103.196.168.0/22 +103.196.204.0/22 +103.197.180.0/22 +103.197.228.0/22 +103.198.20.0/22 +103.198.60.0/22 +103.198.64.0/22 +103.198.72.0/22 +103.198.124.0/22 +103.198.156.0/22 +103.198.180.0/22 +103.198.196.0/22 +103.198.216.0/22 +103.198.220.0/22 +103.198.224.0/22 +103.198.228.0/22 +103.198.232.0/22 +103.198.236.0/22 +103.198.240.0/22 +103.198.244.0/22 +103.199.164.0/22 +103.199.196.0/22 +103.199.228.0/22 +103.199.248.0/22 +103.199.252.0/22 +103.200.52.0/22 +103.200.64.0/22 +103.200.68.0/22 +103.200.136.0/22 +103.200.140.0/22 +103.200.144.0/22 +103.200.148.0/22 +103.200.152.0/22 +103.200.156.0/22 +103.200.160.0/22 +103.200.164.0/22 +103.200.168.0/22 +103.200.172.0/22 +103.200.176.0/22 +103.200.180.0/22 +103.200.184.0/22 +103.200.188.0/22 +103.200.192.0/22 +103.200.220.0/22 +103.200.224.0/22 +103.200.228.0/22 +103.200.232.0/22 +103.200.236.0/22 +103.200.240.0/22 +103.200.244.0/22 +103.200.248.0/22 +103.200.252.0/22 +103.201.0.0/22 +103.201.4.0/22 +103.201.8.0/22 +103.201.12.0/22 +103.201.16.0/22 +103.201.20.0/22 +103.201.28.0/22 +103.201.32.0/22 +103.201.36.0/22 +103.201.40.0/22 +103.201.44.0/22 +103.201.48.0/22 +103.201.52.0/22 +103.201.56.0/22 +103.201.60.0/22 +103.201.64.0/22 +103.201.76.0/22 +103.201.80.0/22 +103.201.84.0/22 +103.201.88.0/22 +103.201.92.0/22 +103.201.96.0/22 +103.201.100.0/22 +103.201.104.0/22 +103.201.108.0/22 +103.201.112.0/22 +103.201.116.0/22 +103.201.120.0/22 +103.201.152.0/22 +103.201.156.0/22 +103.201.160.0/22 +103.201.164.0/22 +103.201.168.0/22 +103.201.172.0/22 +103.201.176.0/22 +103.201.180.0/22 +103.201.184.0/22 +103.201.188.0/22 +103.201.192.0/22 +103.201.196.0/22 +103.201.200.0/22 +103.201.204.0/22 +103.201.208.0/22 +103.201.212.0/22 +103.201.216.0/22 +103.201.220.0/22 +103.201.224.0/22 +103.201.228.0/22 +103.201.232.0/22 +103.201.236.0/22 +103.201.240.0/22 +103.201.244.0/22 +103.201.248.0/22 +103.201.252.0/22 +103.202.0.0/22 +103.202.4.0/22 +103.202.8.0/22 +103.202.12.0/22 +103.202.16.0/22 +103.202.20.0/22 +103.202.24.0/22 +103.202.28.0/22 +103.202.32.0/22 +103.202.36.0/22 +103.202.40.0/22 +103.202.44.0/22 +103.202.56.0/22 +103.202.60.0/22 +103.202.64.0/22 +103.202.68.0/22 +103.202.72.0/22 +103.202.76.0/22 +103.202.80.0/22 +103.202.84.0/22 +103.202.88.0/22 +103.202.92.0/22 +103.202.96.0/22 +103.202.100.0/22 +103.202.104.0/22 +103.202.108.0/22 +103.202.112.0/22 +103.202.116.0/22 +103.202.120.0/22 +103.202.124.0/22 +103.202.128.0/22 +103.202.132.0/22 +103.202.136.0/22 +103.202.140.0/22 +103.202.144.0/22 +103.202.152.0/22 +103.202.156.0/22 +103.202.160.0/22 +103.202.164.0/22 +103.202.168.0/22 +103.202.172.0/22 +103.202.176.0/22 +103.202.180.0/22 +103.202.184.0/22 +103.202.188.0/22 +103.202.192.0/22 +103.202.196.0/22 +103.202.200.0/21 +103.202.212.0/22 +103.202.228.0/22 +103.202.236.0/22 +103.202.240.0/22 +103.202.244.0/22 +103.202.248.0/22 +103.202.252.0/22 +103.203.0.0/22 +103.203.4.0/22 +103.203.8.0/22 +103.203.12.0/22 +103.203.16.0/22 +103.203.20.0/22 +103.203.24.0/22 +103.203.28.0/22 +103.203.32.0/22 +103.203.56.0/22 +103.203.96.0/22 +103.203.100.0/22 +103.203.104.0/22 +103.203.108.0/22 +103.203.112.0/22 +103.203.116.0/22 +103.203.120.0/22 +103.203.124.0/22 +103.203.128.0/22 +103.203.140.0/22 +103.203.164.0/22 +103.203.168.0/22 +103.203.192.0/22 +103.203.200.0/22 +103.203.212.0/22 +103.203.216.0/22 +103.204.24.0/22 +103.204.72.0/22 +103.204.88.0/22 +103.204.112.0/22 +103.204.136.0/22 +103.204.140.0/22 +103.204.144.0/22 +103.204.148.0/22 +103.204.152.0/22 +103.204.196.0/22 +103.204.216.0/23 +103.204.232.0/22 +103.204.236.0/22 +103.205.4.0/22 +103.205.8.0/22 +103.205.40.0/22 +103.205.44.0/22 +103.205.52.0/22 +103.205.108.0/22 +103.205.116.0/22 +103.205.120.0/22 +103.205.136.0/22 +103.205.162.0/24 +103.205.188.0/22 +103.205.192.0/22 +103.205.196.0/22 +103.205.200.0/22 +103.205.236.0/22 +103.205.248.0/22 +103.205.252.0/22 +103.206.0.0/22 +103.206.44.0/22 +103.206.148.0/22 +103.207.48.0/22 +103.207.104.0/22 +103.207.184.0/22 +103.207.188.0/22 +103.207.192.0/22 +103.207.196.0/22 +103.207.200.0/22 +103.207.204.0/22 +103.207.208.0/22 +103.207.212.0/22 +103.207.220.0/22 +103.207.228.0/22 +103.207.232.0/22 +103.208.12.0/22 +103.208.16.0/22 +103.208.28.0/22 +103.208.40.0/22 +103.208.44.0/22 +103.208.48.0/22 +103.209.112.0/22 +103.209.136.0/22 +103.209.200.0/22 +103.209.208.0/22 +103.209.216.0/22 +103.210.96.0/22 +103.210.156.0/22 +103.210.160.0/22 +103.210.164.0/22 +103.210.168.0/22 +103.210.172.0/22 +103.210.176.0/22 +103.210.180.0/22 +103.210.184.0/22 +103.210.188.0/22 +103.210.216.0/22 +103.211.44.0/22 +103.211.96.0/22 +103.211.100.0/22 +103.211.156.0/22 +103.211.164.0/22 +103.211.192.0/22 +103.211.220.0/22 +103.211.224.0/22 +103.211.248.0/22 +103.212.0.0/22 +103.212.4.0/22 +103.212.8.0/22 +103.212.12.0/22 +103.212.44.0/22 +103.212.48.0/22 +103.212.84.0/22 +103.212.100.0/22 +103.212.108.0/22 +103.212.148.0/22 +103.212.164.0/22 +103.212.196.0/22 +103.212.200.0/22 +103.212.228.0/22 +103.212.252.0/22 +103.213.40.0/22 +103.213.44.0/22 +103.213.48.0/22 +103.213.52.0/22 +103.213.56.0/22 +103.213.60.0/22 +103.213.64.0/22 +103.213.68.0/22 +103.213.72.0/22 +103.213.76.0/22 +103.213.80.0/22 +103.213.84.0/22 +103.213.88.0/22 +103.213.92.0/22 +103.213.96.0/22 +103.213.132.0/22 +103.213.136.0/22 +103.213.140.0/22 +103.213.144.0/22 +103.213.148.0/22 +103.213.152.0/22 +103.213.156.0/22 +103.213.160.0/22 +103.213.164.0/22 +103.213.168.0/22 +103.213.172.0/22 +103.213.176.0/22 +103.213.180.0/22 +103.213.184.0/22 +103.213.188.0/22 +103.214.48.0/22 +103.214.84.0/22 +103.214.212.0/22 +103.214.240.0/22 +103.214.244.0/22 +103.215.28.0/22 +103.215.32.0/22 +103.215.36.0/22 +103.215.44.0/22 +103.215.48.0/22 +103.215.100.0/22 +103.215.108.0/22 +103.215.116.0/22 +103.215.120.0/22 +103.215.140.0/22 +103.216.4.0/22 +103.216.8.0/22 +103.216.12.0/22 +103.216.16.0/22 +103.216.20.0/22 +103.216.24.0/22 +103.216.28.0/22 +103.216.32.0/22 +103.216.36.0/22 +103.216.40.0/22 +103.216.44.0/22 +103.216.64.0/22 +103.216.108.0/22 +103.216.136.0/22 +103.216.152.0/22 +103.216.224.0/22 +103.216.228.0/22 +103.216.240.0/22 +103.216.244.0/22 +103.216.248.0/22 +103.216.252.0/22 +103.217.0.0/22 +103.217.4.0/22 +103.217.8.0/22 +103.217.12.0/22 +103.217.16.0/22 +103.217.20.0/22 +103.217.24.0/22 +103.217.28.0/22 +103.217.32.0/22 +103.217.36.0/22 +103.217.40.0/22 +103.217.44.0/22 +103.217.48.0/22 +103.217.52.0/22 +103.217.56.0/22 +103.217.60.0/22 +103.217.168.0/22 +103.217.180.0/22 +103.217.184.0/22 +103.217.188.0/22 +103.217.192.0/22 +103.217.196.0/22 +103.217.200.0/22 +103.217.204.0/22 +103.218.8.0/22 +103.218.12.0/22 +103.218.16.0/22 +103.218.20.0/22 +103.218.28.0/22 +103.218.32.0/22 +103.218.36.0/22 +103.218.40.0/22 +103.218.44.0/22 +103.218.48.0/22 +103.218.52.0/22 +103.218.56.0/22 +103.218.60.0/22 +103.218.64.0/22 +103.218.68.0/22 +103.218.72.0/22 +103.218.76.0/22 +103.218.80.0/22 +103.218.84.0/22 +103.218.88.0/22 +103.218.92.0/22 +103.218.192.0/22 +103.218.196.0/22 +103.218.200.0/22 +103.218.204.0/22 +103.218.208.0/22 +103.218.212.0/22 +103.218.216.0/22 +103.219.24.0/22 +103.219.28.0/22 +103.219.32.0/22 +103.219.36.0/22 +103.219.64.0/22 +103.219.84.0/22 +103.219.88.0/22 +103.219.92.0/22 +103.219.96.0/22 +103.219.100.0/22 +103.219.176.0/22 +103.219.184.0/22 +103.220.48.0/22 +103.220.52.0/22 +103.220.56.0/22 +103.220.60.0/22 +103.220.64.0/22 +103.220.92.0/22 +103.220.96.0/22 +103.220.100.0/22 +103.220.104.0/22 +103.220.108.0/22 +103.220.116.0/22 +103.220.120.0/22 +103.220.124.0/22 +103.220.128.0/22 +103.220.132.0/22 +103.220.136.0/22 +103.220.140.0/22 +103.220.144.0/22 +103.220.148.0/22 +103.220.152.0/22 +103.220.160.0/22 +103.220.164.0/22 +103.220.168.0/22 +103.220.172.0/22 +103.220.176.0/22 +103.220.180.0/22 +103.220.184.0/22 +103.220.188.0/22 +103.220.192.0/22 +103.220.196.0/22 +103.220.200.0/22 +103.220.240.0/22 +103.220.244.0/22 +103.220.248.0/22 +103.220.252.0/22 +103.221.0.0/22 +103.221.4.0/22 +103.221.8.0/22 +103.221.12.0/22 +103.221.16.0/22 +103.221.20.0/22 +103.221.24.0/22 +103.221.28.0/22 +103.221.32.0/22 +103.221.36.0/22 +103.221.40.0/22 +103.221.44.0/22 +103.221.48.0/22 +103.221.88.0/22 +103.221.92.0/22 +103.221.96.0/22 +103.221.100.0/22 +103.221.104.0/22 +103.221.108.0/22 +103.221.112.0/22 +103.221.116.0/22 +103.221.120.0/22 +103.221.124.0/22 +103.221.128.0/22 +103.221.132.0/22 +103.221.136.0/22 +103.221.140.0/22 +103.221.144.0/22 +103.221.148.0/22 +103.221.152.0/22 +103.221.156.0/22 +103.221.160.0/22 +103.221.164.0/22 +103.221.168.0/22 +103.221.172.0/22 +103.221.176.0/22 +103.221.180.0/22 +103.221.184.0/22 +103.221.188.0/22 +103.221.192.0/22 +103.221.196.0/22 +103.221.200.0/22 +103.221.204.0/22 +103.222.0.0/22 +103.222.4.0/22 +103.222.8.0/22 +103.222.12.0/22 +103.222.16.0/22 +103.222.24.0/22 +103.222.28.0/22 +103.222.32.0/22 +103.222.36.0/22 +103.222.40.0/22 +103.222.44.0/22 +103.222.48.0/22 +103.222.52.0/22 +103.222.56.0/22 +103.222.60.0/22 +103.222.64.0/22 +103.222.68.0/22 +103.222.72.0/22 +103.222.76.0/22 +103.222.80.0/22 +103.222.84.0/22 +103.222.88.0/22 +103.222.92.0/22 +103.222.96.0/22 +103.222.100.0/22 +103.222.104.0/22 +103.222.108.0/22 +103.222.112.0/22 +103.222.116.0/22 +103.222.120.0/22 +103.222.124.0/22 +103.222.128.0/22 +103.222.132.0/22 +103.222.136.0/22 +103.222.140.0/22 +103.222.144.0/22 +103.222.148.0/22 +103.222.152.0/22 +103.222.156.0/22 +103.222.160.0/22 +103.222.164.0/22 +103.222.168.0/22 +103.222.172.0/22 +103.222.176.0/22 +103.222.180.0/22 +103.222.184.0/22 +103.222.188.0/22 +103.222.192.0/22 +103.222.196.0/22 +103.222.200.0/22 +103.222.204.0/22 +103.222.208.0/22 +103.222.212.0/22 +103.222.216.0/22 +103.222.220.0/22 +103.222.224.0/22 +103.222.228.0/22 +103.222.232.0/22 +103.222.240.0/22 +103.222.244.0/22 +103.223.16.0/22 +103.223.20.0/22 +103.223.24.0/22 +103.223.28.0/22 +103.223.32.0/22 +103.223.36.0/22 +103.223.40.0/22 +103.223.44.0/22 +103.223.48.0/22 +103.223.52.0/22 +103.223.56.0/22 +103.223.60.0/22 +103.223.64.0/22 +103.223.68.0/22 +103.223.72.0/22 +103.223.76.0/22 +103.223.80.0/22 +103.223.84.0/22 +103.223.88.0/22 +103.223.92.0/22 +103.223.96.0/22 +103.223.100.0/22 +103.223.104.0/22 +103.223.108.0/22 +103.223.112.0/22 +103.223.116.0/22 +103.223.120.0/22 +103.223.124.0/22 +103.223.128.0/22 +103.223.132.0/22 +103.223.140.0/22 +103.223.144.0/22 +103.223.148.0/22 +103.223.152.0/22 +103.223.156.0/22 +103.223.160.0/22 +103.223.164.0/22 +103.223.168.0/22 +103.223.172.0/22 +103.223.176.0/22 +103.223.180.0/22 +103.223.188.0/22 +103.223.192.0/22 +103.223.196.0/22 +103.223.200.0/22 +103.223.204.0/22 +103.223.208.0/22 +103.223.212.0/22 +103.223.216.0/22 +103.223.220.0/22 +103.223.224.0/22 +103.223.228.0/22 +103.223.232.0/22 +103.223.236.0/22 +103.223.240.0/22 +103.223.244.0/22 +103.223.248.0/22 +103.223.252.0/22 +103.224.0.0/22 +103.224.40.0/22 +103.224.44.0/22 +103.224.60.0/22 +103.224.80.0/22 +103.224.220.0/22 +103.224.224.0/22 +103.224.228.0/22 +103.224.232.0/22 +103.225.84.0/22 +103.226.16.0/22 +103.226.40.0/22 +103.226.56.0/22 +103.226.60.0/22 +103.226.80.0/22 +103.226.132.0/22 +103.226.156.0/22 +103.226.180.0/22 +103.226.196.0/22 +103.227.48.0/22 +103.227.72.0/22 +103.227.76.0/22 +103.227.80.0/22 +103.227.100.0/22 +103.227.120.0/22 +103.227.132.0/22 +103.227.136.0/22 +103.227.196.0/22 +103.227.204.0/22 +103.227.212.0/22 +103.227.228.0/22 +103.228.12.0/22 +103.228.88.0/22 +103.228.136.0/22 +103.228.160.0/22 +103.228.176.0/22 +103.228.204.0/22 +103.228.208.0/22 +103.228.228.0/22 +103.228.232.0/22 +103.229.20.0/22 +103.229.60.0/22 +103.229.136.0/22 +103.229.148.0/22 +103.229.172.0/22 +103.229.212.0/22 +103.229.216.0/22 +103.229.220.0/22 +103.229.228.0/22 +103.229.236.0/22 +103.229.240.0/22 +103.230.0.0/22 +103.230.28.0/22 +103.230.44.0/22 +103.230.96.0/22 +103.230.196.0/22 +103.230.200.0/22 +103.230.204.0/22 +103.230.212.0/22 +103.230.236.0/22 +103.231.16.0/22 +103.231.20.0/22 +103.231.64.0/22 +103.231.68.0/22 +103.231.180.0/22 +103.231.184.0/22 +103.231.244.0/22 +103.232.4.0/22 +103.232.144.0/22 +103.232.188.0/22 +103.232.212.0/22 +103.233.4.0/22 +103.233.44.0/22 +103.233.52.0/22 +103.233.104.0/22 +103.233.128.0/22 +103.233.136.0/22 +103.233.162.0/23 +103.233.228.0/22 +103.234.0.0/22 +103.234.20.0/22 +103.234.56.0/22 +103.234.128.0/22 +103.234.172.0/22 +103.234.180.0/22 +103.234.244.0/22 +103.235.16.0/22 +103.235.48.0/22 +103.235.56.0/22 +103.235.60.0/22 +103.235.80.0/22 +103.235.84.0/22 +103.235.100.0/22 +103.235.128.0/22 +103.235.132.0/22 +103.235.136.0/22 +103.235.140.0/22 +103.235.144.0/22 +103.235.148.0/22 +103.235.184.0/22 +103.235.192.0/22 +103.235.200.0/22 +103.235.220.0/22 +103.235.224.0/22 +103.235.228.0/22 +103.235.232.0/22 +103.235.236.0/22 +103.235.240.0/22 +103.235.244.0/22 +103.235.248.0/22 +103.235.252.0/22 +103.236.0.0/22 +103.236.4.0/22 +103.236.8.0/22 +103.236.12.0/22 +103.236.16.0/22 +103.236.20.0/22 +103.236.24.0/22 +103.236.28.0/22 +103.236.32.0/22 +103.236.36.0/22 +103.236.40.0/22 +103.236.44.0/22 +103.236.48.0/22 +103.236.52.0/22 +103.236.56.0/22 +103.236.60.0/22 +103.236.64.0/22 +103.236.68.0/22 +103.236.72.0/22 +103.236.76.0/22 +103.236.80.0/22 +103.236.84.0/22 +103.236.88.0/22 +103.236.92.0/22 +103.236.96.0/22 +103.236.120.0/22 +103.236.184.0/22 +103.236.220.0/22 +103.236.232.0/22 +103.236.240.0/22 +103.236.244.0/22 +103.236.248.0/22 +103.236.252.0/22 +103.237.0.0/22 +103.237.4.0/22 +103.237.8.0/22 +103.237.12.0/22 +103.237.24.0/22 +103.237.28.0/22 +103.237.68.0/22 +103.237.88.0/22 +103.237.152.0/22 +103.237.176.0/22 +103.237.180.0/22 +103.237.184.0/22 +103.237.188.0/22 +103.237.192.0/22 +103.237.196.0/22 +103.237.200.0/22 +103.237.204.0/22 +103.237.208.0/22 +103.237.212.0/22 +103.237.216.0/22 +103.237.220.0/22 +103.237.224.0/22 +103.237.228.0/22 +103.237.232.0/22 +103.237.236.0/22 +103.237.240.0/22 +103.237.244.0/22 +103.237.248.0/22 +103.237.252.0/22 +103.238.0.0/22 +103.238.4.0/22 +103.238.16.0/22 +103.238.20.0/22 +103.238.24.0/22 +103.238.28.0/22 +103.238.32.0/22 +103.238.36.0/22 +103.238.40.0/22 +103.238.44.0/22 +103.238.48.0/22 +103.238.52.0/22 +103.238.56.0/22 +103.238.88.0/22 +103.238.92.0/22 +103.238.96.0/22 +103.238.132.0/22 +103.238.140.0/22 +103.238.144.0/22 +103.238.160.0/22 +103.238.164.0/22 +103.238.168.0/22 +103.238.172.0/22 +103.238.176.0/22 +103.238.180.0/22 +103.238.184.0/22 +103.238.188.0/22 +103.238.196.0/22 +103.238.204.0/22 +103.238.252.0/22 +103.239.0.0/22 +103.239.44.0/22 +103.239.68.0/22 +103.239.152.0/22 +103.239.156.0/22 +103.239.180.0/22 +103.239.184.0/22 +103.239.192.0/22 +103.239.196.0/22 +103.239.204.0/22 +103.239.208.0/22 +103.239.224.0/22 +103.239.244.0/22 +103.240.16.0/22 +103.240.36.0/22 +103.240.72.0/22 +103.240.84.0/22 +103.240.124.0/22 +103.240.172.0/22 +103.240.188.0/22 +103.240.244.0/22 +103.241.12.0/22 +103.241.72.0/22 +103.241.92.0/22 +103.241.96.0/22 +103.241.160.0/22 +103.241.184.0/22 +103.241.188.0/22 +103.241.220.0/22 +103.242.12.0/22 +103.242.64.0/22 +103.242.128.0/22 +103.242.132.0/22 +103.242.160.0/22 +103.242.168.0/22 +103.242.172.0/22 +103.242.176.0/22 +103.242.200.0/22 +103.242.212.0/22 +103.242.220.0/22 +103.242.240.0/22 +103.243.136.0/22 +103.243.252.0/22 +103.244.16.0/22 +103.244.58.0/23 +103.244.60.0/22 +103.244.64.0/22 +103.244.68.0/22 +103.244.72.0/22 +103.244.76.0/22 +103.244.80.0/22 +103.244.84.0/22 +103.244.116.0/22 +103.244.164.0/22 +103.244.232.0/22 +103.244.252.0/22 +103.245.23.0/24 +103.245.52.0/22 +103.245.60.0/22 +103.245.80.0/22 +103.245.124.0/22 +103.245.128.0/22 +103.246.8.0/22 +103.246.12.0/22 +103.246.120.0/22 +103.246.124.0/22 +103.246.132.0/22 +103.246.152.0/22 +103.246.156.0/22 +103.247.168.0/22 +103.247.172.0/22 +103.247.176.0/22 +103.247.200.0/22 +103.247.212.0/22 +103.248.0.0/23 +103.248.64.0/22 +103.248.100.0/22 +103.248.124.0/22 +103.248.152.0/22 +103.248.168.0/22 +103.248.192.0/22 +103.248.212.0/22 +103.248.224.0/22 +103.249.8.0/22 +103.249.12.0/22 +103.249.52.0/22 +103.249.104.0/22 +103.249.128.0/22 +103.249.136.0/22 +103.249.144.0/22 +103.249.164.0/22 +103.249.168.0/22 +103.249.172.0/22 +103.249.176.0/22 +103.249.188.0/22 +103.249.192.0/22 +103.249.244.0/22 +103.249.252.0/22 +103.250.32.0/22 +103.250.104.0/22 +103.250.124.0/22 +103.250.180.0/22 +103.250.192.0/22 +103.250.216.0/22 +103.250.224.0/22 +103.250.236.0/22 +103.250.248.0/22 +103.250.252.0/22 +103.251.32.0/22 +103.251.84.0/22 +103.251.96.0/22 +103.251.124.0/22 +103.251.128.0/22 +103.251.160.0/22 +103.251.192.0/22 +103.251.204.0/22 +103.251.240.0/22 +103.252.28.0/22 +103.252.36.0/22 +103.252.64.0/22 +103.252.96.0/22 +103.252.104.0/22 +103.252.172.0/22 +103.252.204.0/22 +103.252.208.0/22 +103.252.232.0/22 +103.252.248.0/22 +103.253.4.0/22 +103.253.60.0/22 +103.253.204.0/22 +103.253.220.0/22 +103.253.224.0/22 +103.253.232.0/22 +103.254.8.0/22 +103.254.20.0/22 +103.254.64.0/22 +103.254.68.0/22 +103.254.72.0/22 +103.254.76.0/22 +103.254.112.0/22 +103.254.176.0/22 +103.254.188.0/22 +103.254.196.0/24 +103.254.220.0/22 +103.255.56.0/22 +103.255.68.0/22 +103.255.88.0/22 +103.255.92.0/22 +103.255.136.0/22 +103.255.140.0/22 +103.255.184.0/22 +103.255.200.0/22 +103.255.212.0/22 +103.255.228.0/22 +106.0.0.0/24 +106.0.2.0/23 +106.0.4.0/22 +106.0.8.0/21 +106.0.16.0/20 +106.0.44.0/22 +106.0.64.0/18 +106.2.0.0/15 +106.4.0.0/14 +106.8.0.0/15 +106.11.0.0/16 +106.12.0.0/14 +106.16.0.0/12 +106.32.0.0/12 +106.48.0.0/15 +106.50.0.0/16 +106.52.0.0/14 +106.56.0.0/13 +106.74.0.0/16 +106.75.0.0/16 +106.80.0.0/12 +106.108.0.0/14 +106.112.0.0/13 +106.120.0.0/13 +106.224.0.0/12 +109.244.0.0/16 +110.6.0.0/15 +110.16.0.0/14 +110.34.40.0/22 +110.34.44.0/22 +110.40.0.0/14 +110.44.12.0/22 +110.44.144.0/20 +110.48.0.0/16 +110.51.0.0/16 +110.52.0.0/15 +110.56.0.0/13 +110.64.0.0/15 +110.72.0.0/15 +110.75.0.0/17 +110.75.128.0/19 +110.75.160.0/19 +110.75.192.0/18 +110.76.0.0/19 +110.76.32.0/19 +110.76.132.0/22 +110.76.156.0/22 +110.76.184.0/22 +110.76.192.0/18 +110.77.0.0/17 +110.80.0.0/13 +110.88.0.0/14 +110.92.68.0/22 +110.93.32.0/19 +110.94.0.0/15 +110.96.0.0/11 +110.152.0.0/14 +110.156.0.0/15 +110.165.32.0/19 +110.166.0.0/15 +110.172.192.0/18 +110.173.0.0/19 +110.173.32.0/20 +110.173.64.0/19 +110.173.96.0/19 +110.173.192.0/19 +110.176.0.0/13 +110.184.0.0/13 +110.192.0.0/11 +110.228.0.0/14 +110.232.32.0/19 +110.236.0.0/15 +110.240.0.0/12 +111.0.0.0/10 +111.66.0.0/16 +111.67.192.0/20 +111.68.64.0/19 +111.72.0.0/13 +111.85.0.0/16 +111.91.192.0/19 +111.92.240.0/22 +111.92.248.0/22 +111.92.252.0/22 +111.112.0.0/15 +111.114.0.0/15 +111.116.0.0/15 +111.118.200.0/21 +111.119.64.0/18 +111.119.128.0/19 +111.120.0.0/14 +111.124.0.0/16 +111.126.0.0/15 +111.128.0.0/11 +111.160.0.0/13 +111.170.0.0/16 +111.172.0.0/14 +111.176.0.0/13 +111.186.0.0/15 +111.192.0.0/12 +111.208.0.0/14 +111.212.0.0/14 +111.221.28.0/24 +111.221.128.0/17 +111.222.0.0/16 +111.223.4.0/22 +111.223.8.0/22 +111.223.12.0/22 +111.223.16.0/22 +111.223.240.0/22 +111.223.248.0/22 +111.224.0.0/14 +111.228.0.0/14 +111.235.96.0/19 +111.235.156.0/22 +111.235.160.0/19 +112.0.0.0/10 +112.64.0.0/15 +112.66.0.0/15 +112.73.0.0/16 +112.74.0.0/15 +112.80.0.0/13 +112.88.0.0/13 +112.96.0.0/15 +112.98.0.0/15 +112.100.0.0/14 +112.109.128.0/17 +112.111.0.0/16 +112.112.0.0/14 +112.116.0.0/15 +112.122.0.0/15 +112.124.0.0/14 +112.128.0.0/14 +112.132.0.0/16 +112.137.48.0/21 +112.192.0.0/14 +112.224.0.0/11 +113.0.0.0/13 +113.8.0.0/15 +113.11.192.0/19 +113.12.0.0/14 +113.16.0.0/15 +113.18.0.0/16 +113.21.232.0/22 +113.21.236.0/22 +113.24.0.0/14 +113.31.0.0/16 +113.44.0.0/14 +113.48.0.0/14 +113.52.160.0/19 +113.52.228.0/22 +113.54.0.0/15 +113.56.0.0/15 +113.58.0.0/16 +113.59.0.0/17 +113.59.224.0/22 +113.62.0.0/15 +113.64.0.0/11 +113.96.0.0/12 +113.112.0.0/13 +113.120.0.0/13 +113.128.0.0/15 +113.130.96.0/20 +113.130.112.0/21 +113.132.0.0/14 +113.136.0.0/13 +113.194.0.0/15 +113.197.100.0/22 +113.200.0.0/15 +113.202.0.0/16 +113.204.0.0/14 +113.208.96.0/19 +113.208.128.0/17 +113.209.0.0/16 +113.212.0.0/18 +113.212.88.0/22 +113.212.100.0/22 +113.212.184.0/21 +113.213.0.0/17 +113.214.0.0/15 +113.218.0.0/15 +113.220.0.0/14 +113.224.0.0/12 +113.240.0.0/13 +113.248.0.0/14 +114.28.0.0/16 +114.31.64.0/22 +114.31.68.0/22 +114.54.0.0/15 +114.60.0.0/14 +114.64.0.0/14 +114.68.0.0/16 +114.79.64.0/18 +114.80.0.0/12 +114.96.0.0/13 +114.104.0.0/14 +114.110.0.0/20 +114.110.64.0/18 +114.111.0.0/19 +114.111.160.0/19 +114.112.0.0/14 +114.116.0.0/16 +114.117.0.0/17 +114.117.128.0/17 +114.118.0.0/16 +114.119.0.0/17 +114.119.192.0/21 +114.119.200.0/22 +114.119.204.0/22 +114.119.208.0/20 +114.119.224.0/19 +114.132.0.0/16 +114.134.184.0/22 +114.134.188.0/23 +114.135.0.0/16 +114.138.0.0/15 +114.141.64.0/21 +114.141.80.0/22 +114.141.84.0/22 +114.141.128.0/18 +114.142.136.0/21 +114.196.0.0/15 +114.198.248.0/21 +114.208.0.0/14 +114.212.0.0/15 +114.214.0.0/16 +114.215.0.0/16 +114.216.0.0/13 +114.224.0.0/12 +114.240.0.0/12 +115.24.0.0/14 +115.28.0.0/15 +115.31.64.0/22 +115.31.68.0/22 +115.31.72.0/22 +115.31.76.0/22 +115.32.0.0/14 +115.42.56.0/22 +115.44.0.0/15 +115.46.0.0/16 +115.47.0.0/16 +115.48.0.0/12 +115.69.64.0/20 +115.84.0.0/18 +115.84.192.0/19 +115.85.192.0/18 +115.100.0.0/14 +115.104.0.0/14 +115.120.0.0/14 +115.124.16.0/20 +115.148.0.0/14 +115.152.0.0/15 +115.154.0.0/15 +115.156.0.0/15 +115.158.0.0/16 +115.159.0.0/16 +115.166.64.0/19 +115.168.0.0/14 +115.172.0.0/14 +115.180.0.0/15 +115.182.0.0/16 +115.183.0.0/16 +115.187.0.0/22 +115.187.4.0/22 +115.187.8.0/22 +115.187.12.0/22 +115.190.0.0/15 +115.192.0.0/11 +115.224.0.0/12 +116.0.8.0/21 +116.0.24.0/21 +116.1.0.0/16 +116.2.0.0/15 +116.4.0.0/14 +116.8.0.0/14 +116.13.0.0/16 +116.16.0.0/12 +116.50.0.0/20 +116.52.0.0/14 +116.56.0.0/15 +116.58.128.0/20 +116.58.208.0/20 +116.60.0.0/14 +116.66.0.0/17 +116.66.176.0/22 +116.68.136.0/22 +116.68.140.0/22 +116.68.176.0/22 +116.68.180.0/22 +116.69.0.0/16 +116.70.0.0/17 +116.76.0.0/15 +116.78.0.0/15 +116.85.0.0/16 +116.89.144.0/20 +116.89.240.0/22 +116.90.80.0/20 +116.90.184.0/21 +116.95.0.0/16 +116.112.0.0/14 +116.116.0.0/15 +116.128.0.0/10 +116.192.0.0/16 +116.193.16.0/20 +116.193.32.0/19 +116.193.152.0/22 +116.193.164.0/22 +116.193.176.0/21 +116.194.0.0/15 +116.196.0.0/17 +116.196.128.0/18 +116.196.192.0/18 +116.197.160.0/22 +116.197.164.0/22 +116.198.0.0/16 +116.199.0.0/17 +116.199.128.0/19 +116.204.0.0/17 +116.204.132.0/22 +116.204.216.0/22 +116.204.232.0/22 +116.205.0.0/16 +116.207.0.0/16 +116.208.0.0/14 +116.212.160.0/20 +116.213.44.0/22 +116.213.64.0/18 +116.213.128.0/17 +116.214.32.0/19 +116.214.64.0/20 +116.214.128.0/17 +116.215.0.0/16 +116.216.0.0/14 +116.224.0.0/12 +116.242.0.0/15 +116.244.0.0/15 +116.246.0.0/15 +116.248.0.0/15 +116.251.64.0/18 +116.252.0.0/15 +116.254.104.0/22 +116.254.108.0/22 +116.254.128.0/17 +116.255.128.0/17 +117.8.0.0/13 +117.21.0.0/16 +117.22.0.0/15 +117.24.0.0/13 +117.32.0.0/13 +117.40.0.0/14 +117.44.0.0/15 +117.48.0.0/14 +117.53.48.0/20 +117.53.176.0/20 +117.57.0.0/16 +117.58.0.0/17 +117.59.0.0/16 +117.60.0.0/14 +117.64.0.0/13 +117.72.0.0/15 +117.74.64.0/20 +117.74.80.0/20 +117.74.128.0/17 +117.75.0.0/16 +117.76.0.0/14 +117.80.0.0/12 +117.100.0.0/15 +117.103.16.0/20 +117.103.40.0/21 +117.103.72.0/21 +117.103.128.0/20 +117.104.168.0/21 +117.106.0.0/15 +117.112.0.0/13 +117.120.64.0/18 +117.120.128.0/17 +117.121.0.0/17 +117.121.128.0/18 +117.121.192.0/21 +117.122.128.0/17 +117.124.0.0/14 +117.128.0.0/10 +118.24.0.0/15 +118.26.0.0/19 +118.26.32.0/22 +118.26.40.0/21 +118.26.48.0/21 +118.26.56.0/21 +118.26.64.0/19 +118.26.96.0/21 +118.26.112.0/21 +118.26.120.0/21 +118.26.128.0/22 +118.26.133.0/24 +118.26.134.0/23 +118.26.136.0/21 +118.26.160.0/20 +118.26.188.0/22 +118.26.192.0/18 +118.28.0.0/15 +118.30.0.0/16 +118.31.0.0/16 +118.64.0.0/15 +118.66.0.0/16 +118.67.112.0/20 +118.72.0.0/13 +118.80.0.0/15 +118.84.0.0/15 +118.88.32.0/19 +118.88.64.0/18 +118.88.128.0/17 +118.89.0.0/16 +118.91.240.0/20 +118.102.16.0/20 +118.102.32.0/21 +118.103.164.0/22 +118.103.168.0/22 +118.103.172.0/22 +118.103.176.0/22 +118.112.0.0/13 +118.120.0.0/14 +118.124.0.0/15 +118.126.0.0/16 +118.127.128.0/19 +118.132.0.0/14 +118.144.0.0/14 +118.178.0.0/16 +118.180.0.0/14 +118.184.0.0/17 +118.184.128.0/17 +118.186.0.0/15 +118.188.0.0/16 +118.190.0.0/16 +118.191.0.0/21 +118.191.8.0/22 +118.191.12.0/24 +118.191.16.0/21 +118.191.64.0/20 +118.191.80.0/22 +118.191.128.0/19 +118.191.176.0/20 +118.191.192.0/20 +118.191.208.0/24 +118.191.216.0/22 +118.191.223.0/24 +118.191.224.0/24 +118.191.240.0/20 +118.192.0.0/16 +118.193.0.0/21 +118.193.8.0/21 +118.193.48.0/21 +118.193.96.0/19 +118.193.128.0/17 +118.194.0.0/17 +118.194.128.0/18 +118.194.192.0/19 +118.194.224.0/22 +118.194.240.0/21 +118.195.0.0/17 +118.195.128.0/17 +118.196.0.0/14 +118.202.0.0/15 +118.204.0.0/14 +118.212.0.0/16 +118.213.0.0/16 +118.215.192.0/18 +118.224.0.0/14 +118.228.0.0/15 +118.230.0.0/16 +118.239.0.0/16 +118.242.0.0/16 +118.244.0.0/14 +118.248.0.0/13 +119.0.0.0/15 +119.2.0.0/19 +119.2.128.0/17 +119.3.0.0/16 +119.4.0.0/14 +119.10.0.0/17 +119.15.136.0/21 +119.16.0.0/16 +119.18.192.0/20 +119.18.208.0/21 +119.18.224.0/20 +119.18.240.0/20 +119.19.0.0/16 +119.20.0.0/14 +119.27.64.0/18 +119.27.128.0/19 +119.27.160.0/19 +119.27.192.0/18 +119.28.0.0/15 +119.30.48.0/20 +119.31.192.0/19 +119.32.0.0/14 +119.36.0.0/16 +119.37.0.0/17 +119.37.128.0/18 +119.37.192.0/18 +119.38.0.0/17 +119.38.128.0/18 +119.38.192.0/20 +119.38.208.0/20 +119.38.224.0/19 +119.39.0.0/16 +119.40.0.0/18 +119.40.64.0/20 +119.40.128.0/17 +119.41.0.0/16 +119.42.0.0/19 +119.42.128.0/21 +119.42.136.0/21 +119.42.224.0/19 +119.44.0.0/15 +119.48.0.0/13 +119.57.0.0/16 +119.58.0.0/16 +119.59.128.0/17 +119.60.0.0/16 +119.61.0.0/16 +119.62.0.0/16 +119.63.32.0/19 +119.75.208.0/20 +119.78.0.0/15 +119.80.0.0/16 +119.82.208.0/20 +119.84.0.0/14 +119.88.0.0/14 +119.96.0.0/13 +119.108.0.0/15 +119.112.0.0/13 +119.120.0.0/13 +119.128.0.0/12 +119.144.0.0/14 +119.148.160.0/20 +119.148.176.0/20 +119.151.192.0/18 +119.160.200.0/21 +119.161.120.0/22 +119.161.124.0/22 +119.161.128.0/17 +119.162.0.0/15 +119.164.0.0/14 +119.176.0.0/12 +119.232.0.0/15 +119.235.128.0/18 +119.248.0.0/14 +119.252.96.0/21 +119.252.240.0/20 +119.253.0.0/16 +119.254.0.0/15 +120.0.0.0/12 +120.24.0.0/14 +120.30.0.0/16 +120.31.0.0/16 +120.32.0.0/13 +120.40.0.0/14 +120.44.0.0/15 +120.46.0.0/16 +120.47.0.0/16 +120.48.0.0/15 +120.52.0.0/16 +120.53.0.0/16 +120.54.0.0/15 +120.64.0.0/14 +120.68.0.0/14 +120.72.32.0/19 +120.72.128.0/17 +120.76.0.0/14 +120.80.0.0/13 +120.88.8.0/21 +120.90.0.0/15 +120.92.0.0/16 +120.94.0.0/16 +120.95.0.0/16 +120.128.0.0/14 +120.132.0.0/17 +120.132.128.0/17 +120.133.0.0/16 +120.134.0.0/15 +120.136.16.0/22 +120.136.20.0/22 +120.136.128.0/18 +120.137.0.0/17 +120.143.128.0/19 +120.192.0.0/10 +121.0.8.0/21 +121.0.16.0/20 +121.4.0.0/15 +121.8.0.0/13 +121.16.0.0/13 +121.24.0.0/14 +121.28.0.0/15 +121.30.0.0/16 +121.31.0.0/16 +121.32.0.0/14 +121.36.0.0/16 +121.37.0.0/16 +121.38.0.0/15 +121.40.0.0/14 +121.46.0.0/18 +121.46.76.0/22 +121.46.128.0/17 +121.47.0.0/16 +121.48.0.0/15 +121.50.8.0/21 +121.51.0.0/16 +121.52.160.0/19 +121.52.208.0/20 +121.52.224.0/19 +121.54.176.0/21 +121.54.188.0/22 +121.55.0.0/18 +121.56.0.0/15 +121.58.0.0/17 +121.58.136.0/21 +121.58.144.0/20 +121.58.160.0/21 +121.59.0.0/16 +121.60.0.0/14 +121.68.0.0/14 +121.76.0.0/15 +121.79.128.0/18 +121.89.0.0/16 +121.91.104.0/21 +121.100.128.0/17 +121.101.0.0/18 +121.101.208.0/20 +121.192.0.0/16 +121.193.0.0/16 +121.194.0.0/15 +121.196.0.0/14 +121.200.192.0/21 +121.201.0.0/16 +121.204.0.0/14 +121.224.0.0/12 +121.248.0.0/14 +121.255.0.0/16 +122.0.64.0/18 +122.0.128.0/17 +122.4.0.0/14 +122.8.0.0/17 +122.8.192.0/18 +122.9.0.0/16 +122.10.128.0/22 +122.10.132.0/23 +122.10.136.0/23 +122.10.164.0/22 +122.10.168.0/21 +122.10.176.0/20 +122.10.192.0/22 +122.10.200.0/21 +122.10.208.0/21 +122.10.216.0/22 +122.10.228.0/22 +122.10.232.0/21 +122.10.240.0/22 +122.11.0.0/17 +122.12.0.0/16 +122.13.0.0/16 +122.14.0.0/17 +122.14.128.0/18 +122.14.192.0/18 +122.48.0.0/16 +122.49.0.0/18 +122.51.0.0/16 +122.64.0.0/11 +122.96.0.0/15 +122.102.0.0/20 +122.102.64.0/20 +122.102.80.0/20 +122.112.0.0/18 +122.112.64.0/18 +122.112.128.0/17 +122.113.0.0/16 +122.114.0.0/16 +122.115.0.0/17 +122.115.128.0/19 +122.115.160.0/19 +122.115.192.0/19 +122.115.224.0/19 +122.119.0.0/16 +122.128.100.0/22 +122.128.120.0/21 +122.136.0.0/13 +122.144.128.0/17 +122.152.192.0/18 +122.156.0.0/14 +122.188.0.0/14 +122.192.0.0/14 +122.198.0.0/16 +122.200.40.0/22 +122.200.44.0/22 +122.200.64.0/18 +122.201.48.0/20 +122.204.0.0/14 +122.224.0.0/12 +122.240.0.0/13 +122.248.24.0/21 +122.248.48.0/20 +122.255.64.0/21 +123.0.128.0/18 +123.4.0.0/14 +123.8.0.0/13 +123.49.128.0/17 +123.50.160.0/19 +123.52.0.0/14 +123.56.0.0/15 +123.58.0.0/20 +123.58.16.0/20 +123.58.32.0/19 +123.58.64.0/19 +123.58.96.0/19 +123.58.128.0/18 +123.58.224.0/20 +123.58.240.0/20 +123.59.0.0/16 +123.60.0.0/16 +123.61.0.0/16 +123.62.0.0/16 +123.64.0.0/11 +123.96.0.0/15 +123.98.0.0/17 +123.99.128.0/17 +123.100.0.0/19 +123.101.0.0/16 +123.103.0.0/17 +123.108.128.0/20 +123.108.208.0/20 +123.112.0.0/12 +123.128.0.0/13 +123.136.80.0/20 +123.137.0.0/16 +123.138.0.0/15 +123.144.0.0/14 +123.148.0.0/16 +123.149.0.0/16 +123.150.0.0/15 +123.152.0.0/13 +123.160.0.0/14 +123.164.0.0/14 +123.168.0.0/14 +123.172.0.0/15 +123.174.0.0/15 +123.176.60.0/22 +123.176.80.0/20 +123.177.0.0/16 +123.178.0.0/15 +123.180.0.0/14 +123.184.0.0/14 +123.188.0.0/14 +123.196.0.0/15 +123.199.128.0/17 +123.206.0.0/15 +123.232.0.0/14 +123.242.0.0/17 +123.242.192.0/22 +123.242.196.0/22 +123.244.0.0/14 +123.249.0.0/16 +123.253.108.0/22 +123.253.240.0/22 +123.254.96.0/22 +123.254.100.0/22 +124.6.64.0/18 +124.14.0.0/15 +124.16.0.0/15 +124.20.0.0/16 +124.21.0.0/20 +124.21.16.0/20 +124.21.32.0/19 +124.21.64.0/18 +124.21.128.0/17 +124.22.0.0/15 +124.28.192.0/18 +124.29.0.0/17 +124.31.0.0/16 +124.40.112.0/20 +124.40.128.0/18 +124.40.192.0/19 +124.40.240.0/22 +124.42.0.0/17 +124.42.128.0/17 +124.47.0.0/18 +124.64.0.0/15 +124.66.0.0/17 +124.67.0.0/16 +124.68.0.0/15 +124.70.0.0/15 +124.72.0.0/16 +124.73.0.0/16 +124.74.0.0/15 +124.76.0.0/14 +124.88.0.0/16 +124.89.0.0/17 +124.89.128.0/17 +124.90.0.0/15 +124.92.0.0/14 +124.108.8.0/21 +124.108.40.0/21 +124.109.96.0/21 +124.112.0.0/15 +124.114.0.0/15 +124.116.0.0/16 +124.117.0.0/16 +124.118.0.0/15 +124.126.0.0/15 +124.128.0.0/13 +124.147.128.0/17 +124.150.137.0/24 +124.151.0.0/16 +124.152.0.0/16 +124.160.0.0/16 +124.161.0.0/16 +124.162.0.0/16 +124.163.0.0/16 +124.164.0.0/14 +124.172.0.0/15 +124.174.0.0/15 +124.192.0.0/15 +124.196.0.0/16 +124.200.0.0/13 +124.220.0.0/14 +124.224.0.0/16 +124.225.0.0/16 +124.226.0.0/15 +124.228.0.0/14 +124.232.0.0/15 +124.234.0.0/15 +124.236.0.0/14 +124.240.0.0/17 +124.240.128.0/18 +124.242.0.0/16 +124.243.192.0/18 +124.248.0.0/17 +124.249.0.0/16 +124.250.0.0/15 +124.254.0.0/18 +125.31.192.0/18 +125.32.0.0/16 +125.33.0.0/16 +125.34.0.0/16 +125.35.0.0/17 +125.35.128.0/17 +125.36.0.0/14 +125.40.0.0/13 +125.58.128.0/17 +125.61.128.0/17 +125.62.0.0/18 +125.64.0.0/13 +125.72.0.0/16 +125.73.0.0/16 +125.74.0.0/15 +125.76.0.0/17 +125.76.128.0/17 +125.77.0.0/16 +125.78.0.0/15 +125.80.0.0/13 +125.88.0.0/13 +125.96.0.0/15 +125.98.0.0/16 +125.104.0.0/13 +125.112.0.0/12 +125.169.0.0/16 +125.171.0.0/16 +125.208.0.0/18 +125.210.0.0/16 +125.211.0.0/16 +125.213.0.0/17 +125.214.96.0/19 +125.215.0.0/18 +125.216.0.0/15 +125.218.0.0/16 +125.219.0.0/16 +125.220.0.0/15 +125.222.0.0/15 +125.254.128.0/18 +125.254.192.0/18 +128.108.0.0/16 +129.28.0.0/16 +129.204.0.0/16 +129.211.0.0/16 +132.232.0.0/16 +134.175.0.0/16 +137.59.59.0/24 +137.59.88.0/22 +139.5.56.0/22 +139.5.60.0/22 +139.5.80.0/22 +139.5.92.0/22 +139.5.108.0/22 +139.5.128.0/22 +139.5.160.0/22 +139.5.192.0/22 +139.5.204.0/22 +139.5.212.0/22 +139.5.244.0/22 +139.9.0.0/16 +139.129.0.0/16 +139.148.0.0/16 +139.155.0.0/16 +139.159.0.0/16 +139.170.0.0/16 +139.176.0.0/16 +139.183.0.0/16 +139.186.0.0/16 +139.189.0.0/16 +139.196.0.0/14 +139.200.0.0/13 +139.208.0.0/13 +139.217.0.0/16 +139.219.0.0/16 +139.220.0.0/15 +139.224.0.0/16 +139.226.0.0/15 +140.75.0.0/16 +140.143.0.0/16 +140.179.0.0/16 +140.205.0.0/16 +140.206.0.0/15 +140.210.0.0/17 +140.210.128.0/17 +140.224.0.0/16 +140.237.0.0/16 +140.240.0.0/16 +140.243.0.0/16 +140.246.0.0/16 +140.249.0.0/16 +140.250.0.0/16 +140.255.0.0/16 +142.70.0.0/16 +142.86.0.0/16 +143.64.0.0/16 +144.0.0.0/16 +144.7.0.0/16 +144.12.0.0/16 +144.48.64.0/22 +144.48.88.0/22 +144.48.156.0/22 +144.48.180.0/22 +144.48.184.0/22 +144.48.204.0/22 +144.48.208.0/22 +144.48.212.0/22 +144.48.220.0/22 +144.48.252.0/22 +144.52.0.0/16 +144.123.0.0/16 +144.255.0.0/16 +146.56.192.0/18 +146.196.56.0/22 +146.196.68.0/22 +146.196.72.0/22 +146.196.92.0/22 +146.196.112.0/22 +146.196.116.0/22 +146.196.124.0/22 +148.70.0.0/16 +149.41.0.0/16 +150.0.0.0/16 +150.115.0.0/16 +150.121.0.0/16 +150.122.0.0/16 +150.129.136.0/22 +150.129.192.0/22 +150.129.216.0/22 +150.129.252.0/22 +150.138.0.0/15 +150.158.0.0/16 +150.223.0.0/16 +150.242.0.0/22 +150.242.4.0/22 +150.242.8.0/22 +150.242.28.0/22 +150.242.44.0/22 +150.242.48.0/22 +150.242.52.0/22 +150.242.56.0/22 +150.242.76.0/22 +150.242.80.0/22 +150.242.92.0/22 +150.242.96.0/22 +150.242.112.0/22 +150.242.116.0/22 +150.242.120.0/22 +150.242.152.0/22 +150.242.156.0/22 +150.242.160.0/22 +150.242.164.0/22 +150.242.168.0/22 +150.242.184.0/22 +150.242.188.0/22 +150.242.192.0/22 +150.242.212.0/22 +150.242.224.0/22 +150.242.232.0/22 +150.242.236.0/22 +150.242.240.0/22 +150.242.244.0/22 +150.242.248.0/22 +150.248.0.0/16 +150.255.0.0/16 +152.104.128.0/17 +152.136.0.0/16 +153.0.0.0/16 +153.3.0.0/16 +153.34.0.0/15 +153.36.0.0/15 +153.99.0.0/16 +153.101.0.0/16 +153.118.0.0/15 +154.8.128.0/17 +157.0.0.0/16 +157.18.0.0/16 +157.61.0.0/16 +157.119.8.0/22 +157.119.12.0/22 +157.119.16.0/22 +157.119.28.0/22 +157.119.132.0/22 +157.119.136.0/22 +157.119.140.0/22 +157.119.144.0/22 +157.119.148.0/22 +157.119.152.0/22 +157.119.156.0/22 +157.119.160.0/22 +157.119.164.0/22 +157.119.172.0/22 +157.119.192.0/22 +157.119.196.0/22 +157.119.240.0/22 +157.119.252.0/22 +157.122.0.0/16 +157.148.0.0/16 +157.156.0.0/16 +157.255.0.0/16 +158.60.0.0/16 +158.79.0.0/16 +159.27.0.0/16 +159.75.0.0/16 +159.226.0.0/16 +160.19.208.0/22 +160.19.212.0/22 +160.19.216.0/22 +160.20.48.0/22 +160.202.60.0/22 +160.202.148.0/22 +160.202.152.0/22 +160.202.168.0/22 +160.202.212.0/22 +160.202.216.0/22 +160.202.220.0/22 +160.202.224.0/22 +160.202.228.0/22 +160.202.232.0/22 +160.202.236.0/22 +160.202.240.0/22 +160.202.244.0/22 +160.202.248.0/22 +160.202.252.0/22 +160.238.64.0/22 +161.120.0.0/16 +161.189.0.0/16 +161.207.0.0/16 +162.14.0.0/16 +162.105.0.0/16 +163.0.0.0/16 +163.47.4.0/22 +163.53.0.0/22 +163.53.4.0/22 +163.53.8.0/22 +163.53.12.0/22 +163.53.36.0/22 +163.53.40.0/22 +163.53.44.0/22 +163.53.48.0/22 +163.53.52.0/22 +163.53.56.0/22 +163.53.60.0/22 +163.53.64.0/22 +163.53.88.0/22 +163.53.92.0/22 +163.53.96.0/22 +163.53.100.0/22 +163.53.104.0/22 +163.53.108.0/22 +163.53.112.0/22 +163.53.116.0/22 +163.53.120.0/22 +163.53.124.0/22 +163.53.128.0/22 +163.53.132.0/22 +163.53.136.0/22 +163.53.160.0/22 +163.53.164.0/22 +163.53.168.0/22 +163.53.172.0/22 +163.53.188.0/22 +163.53.220.0/22 +163.53.240.0/22 +163.125.0.0/16 +163.142.0.0/16 +163.177.0.0/16 +163.179.0.0/16 +163.204.0.0/16 +163.228.0.0/16 +164.52.0.0/17 +166.111.0.0/16 +167.139.0.0/16 +167.189.0.0/16 +167.220.244.0/22 +168.160.0.0/16 +170.179.0.0/16 +171.8.0.0/13 +171.34.0.0/15 +171.36.0.0/14 +171.40.0.0/13 +171.80.0.0/14 +171.84.0.0/14 +171.88.0.0/13 +171.104.0.0/13 +171.112.0.0/14 +171.116.0.0/14 +171.120.0.0/13 +171.208.0.0/12 +172.81.192.0/18 +175.0.0.0/12 +175.16.0.0/13 +175.24.0.0/16 +175.25.0.0/16 +175.26.0.0/16 +175.27.0.0/16 +175.30.0.0/15 +175.42.0.0/15 +175.44.0.0/16 +175.46.0.0/15 +175.48.0.0/12 +175.64.0.0/11 +175.102.0.0/16 +175.106.128.0/17 +175.111.144.0/22 +175.111.148.0/22 +175.111.152.0/22 +175.111.156.0/22 +175.111.160.0/22 +175.111.164.0/22 +175.111.168.0/22 +175.111.172.0/22 +175.111.184.0/22 +175.146.0.0/15 +175.148.0.0/14 +175.152.0.0/14 +175.158.96.0/22 +175.160.0.0/12 +175.176.156.0/22 +175.176.176.0/22 +175.176.188.0/22 +175.178.0.0/16 +175.184.128.0/18 +175.185.0.0/16 +175.186.0.0/15 +175.188.0.0/14 +180.76.0.0/16 +180.77.0.0/16 +180.78.0.0/15 +180.84.0.0/15 +180.86.0.0/16 +180.88.0.0/14 +180.94.56.0/21 +180.94.96.0/20 +180.94.120.0/22 +180.94.124.0/22 +180.95.128.0/17 +180.96.0.0/11 +180.129.128.0/17 +180.130.0.0/16 +180.136.0.0/13 +180.148.16.0/21 +180.148.152.0/21 +180.148.216.0/21 +180.148.224.0/19 +180.149.128.0/19 +180.149.236.0/22 +180.150.160.0/19 +180.152.0.0/13 +180.160.0.0/12 +180.178.112.0/22 +180.178.116.0/22 +180.178.192.0/18 +180.184.0.0/15 +180.186.0.0/16 +180.187.0.0/16 +180.188.0.0/17 +180.189.148.0/22 +180.200.252.0/22 +180.201.0.0/16 +180.202.0.0/15 +180.208.0.0/15 +180.210.212.0/22 +180.210.224.0/19 +180.212.0.0/15 +180.222.224.0/19 +180.223.0.0/16 +180.233.0.0/18 +180.233.64.0/19 +180.233.144.0/22 +180.235.64.0/19 +180.235.112.0/22 +182.16.144.0/22 +182.16.148.0/22 +182.16.192.0/19 +182.18.0.0/17 +182.23.184.0/21 +182.23.200.0/21 +182.32.0.0/12 +182.48.96.0/19 +182.49.0.0/16 +182.50.0.0/20 +182.50.112.0/20 +182.51.0.0/16 +182.54.0.0/17 +182.54.244.0/22 +182.61.0.0/16 +182.80.0.0/14 +182.84.0.0/14 +182.88.0.0/14 +182.92.0.0/16 +182.96.0.0/12 +182.112.0.0/12 +182.128.0.0/12 +182.144.0.0/13 +182.157.0.0/16 +182.160.64.0/19 +182.174.0.0/15 +182.200.0.0/13 +182.236.128.0/17 +182.237.24.0/22 +182.237.28.0/22 +182.238.0.0/16 +182.239.0.0/19 +182.240.0.0/13 +182.254.0.0/16 +182.255.60.0/22 +183.0.0.0/10 +183.64.0.0/13 +183.78.160.0/22 +183.78.164.0/22 +183.78.180.0/22 +183.81.172.0/22 +183.81.180.0/22 +183.84.0.0/15 +183.91.128.0/22 +183.91.136.0/21 +183.91.144.0/20 +183.92.0.0/14 +183.128.0.0/11 +183.160.0.0/13 +183.168.0.0/15 +183.170.0.0/16 +183.172.0.0/14 +183.182.0.0/19 +183.184.0.0/13 +183.192.0.0/10 +185.203.36.0/22 +188.131.128.0/17 +192.51.188.0/24 +192.55.46.0/24 +192.55.68.0/22 +192.102.204.0/23 +192.124.154.0/24 +192.140.128.0/22 +192.140.132.0/22 +192.140.136.0/22 +192.140.156.0/22 +192.140.160.0/22 +192.140.164.0/22 +192.140.168.0/22 +192.140.172.0/22 +192.140.176.0/22 +192.140.180.0/22 +192.140.184.0/22 +192.140.188.0/22 +192.140.192.0/22 +192.140.196.0/22 +192.140.200.0/22 +192.140.204.0/22 +192.140.208.0/22 +192.140.212.0/22 +192.144.128.0/17 +192.197.113.0/24 +193.112.0.0/16 +198.175.100.0/22 +199.212.57.0/24 +202.0.100.0/23 +202.0.122.0/23 +202.0.176.0/22 +202.3.128.0/23 +202.4.128.0/19 +202.4.252.0/22 +202.5.208.0/22 +202.5.212.0/22 +202.5.216.0/22 +202.6.6.0/23 +202.6.66.0/23 +202.6.72.0/23 +202.6.87.0/24 +202.6.88.0/23 +202.6.92.0/23 +202.6.103.0/24 +202.6.108.0/24 +202.6.110.0/23 +202.6.114.0/24 +202.6.176.0/20 +202.8.0.0/24 +202.8.2.0/23 +202.8.4.0/23 +202.8.12.0/24 +202.8.24.0/24 +202.8.77.0/24 +202.8.120.0/22 +202.8.128.0/19 +202.8.192.0/20 +202.9.32.0/24 +202.9.34.0/23 +202.9.48.0/23 +202.9.51.0/24 +202.9.52.0/23 +202.9.54.0/24 +202.9.57.0/24 +202.9.58.0/23 +202.10.64.0/20 +202.10.112.0/22 +202.10.116.0/22 +202.10.120.0/22 +202.10.124.0/22 +202.12.1.0/24 +202.12.2.0/24 +202.12.17.0/24 +202.12.18.0/24 +202.12.19.0/24 +202.12.72.0/24 +202.12.84.0/23 +202.12.96.0/24 +202.12.98.0/23 +202.12.106.0/24 +202.12.111.0/24 +202.12.116.0/24 +202.14.64.0/23 +202.14.69.0/24 +202.14.73.0/24 +202.14.74.0/23 +202.14.76.0/24 +202.14.78.0/23 +202.14.88.0/24 +202.14.97.0/24 +202.14.104.0/23 +202.14.108.0/23 +202.14.111.0/24 +202.14.114.0/23 +202.14.118.0/23 +202.14.124.0/23 +202.14.127.0/24 +202.14.129.0/24 +202.14.135.0/24 +202.14.136.0/24 +202.14.149.0/24 +202.14.151.0/24 +202.14.157.0/24 +202.14.158.0/23 +202.14.169.0/24 +202.14.170.0/23 +202.14.172.0/22 +202.14.176.0/24 +202.14.184.0/23 +202.14.208.0/23 +202.14.213.0/24 +202.14.219.0/24 +202.14.220.0/24 +202.14.222.0/23 +202.14.225.0/24 +202.14.226.0/23 +202.14.231.0/24 +202.14.235.0/24 +202.14.236.0/23 +202.14.238.0/24 +202.14.239.0/24 +202.14.246.0/24 +202.14.251.0/24 +202.20.66.0/24 +202.20.79.0/24 +202.20.87.0/24 +202.20.88.0/23 +202.20.90.0/24 +202.20.94.0/23 +202.20.114.0/24 +202.20.117.0/24 +202.20.120.0/24 +202.20.125.0/24 +202.20.126.0/24 +202.20.127.0/24 +202.21.48.0/22 +202.21.52.0/22 +202.21.56.0/22 +202.21.60.0/22 +202.21.131.0/24 +202.21.132.0/24 +202.21.141.0/24 +202.21.142.0/24 +202.21.147.0/24 +202.21.148.0/24 +202.21.150.0/23 +202.21.152.0/23 +202.21.154.0/24 +202.21.156.0/24 +202.22.248.0/22 +202.22.252.0/22 +202.27.12.0/24 +202.27.14.0/24 +202.27.136.0/23 +202.36.226.0/24 +202.38.0.0/23 +202.38.2.0/23 +202.38.8.0/21 +202.38.48.0/20 +202.38.64.0/19 +202.38.96.0/19 +202.38.128.0/23 +202.38.130.0/23 +202.38.132.0/23 +202.38.134.0/24 +202.38.135.0/24 +202.38.136.0/23 +202.38.138.0/24 +202.38.140.0/23 +202.38.142.0/23 +202.38.146.0/23 +202.38.149.0/24 +202.38.150.0/23 +202.38.152.0/23 +202.38.154.0/23 +202.38.156.0/24 +202.38.158.0/23 +202.38.160.0/23 +202.38.164.0/22 +202.38.168.0/23 +202.38.170.0/24 +202.38.171.0/24 +202.38.176.0/23 +202.38.184.0/21 +202.38.192.0/18 +202.40.4.0/23 +202.40.7.0/24 +202.40.15.0/24 +202.40.135.0/24 +202.40.136.0/24 +202.40.140.0/24 +202.40.143.0/24 +202.40.144.0/23 +202.40.150.0/24 +202.40.155.0/24 +202.40.156.0/24 +202.40.158.0/23 +202.40.162.0/24 +202.41.8.0/23 +202.41.11.0/24 +202.41.12.0/23 +202.41.128.0/24 +202.41.130.0/23 +202.41.152.0/21 +202.41.192.0/24 +202.41.196.0/22 +202.41.200.0/22 +202.41.240.0/20 +202.43.76.0/22 +202.43.144.0/20 +202.44.16.0/20 +202.44.48.0/22 +202.44.67.0/24 +202.44.74.0/24 +202.44.97.0/24 +202.44.129.0/24 +202.44.132.0/23 +202.44.146.0/23 +202.45.0.0/23 +202.45.2.0/24 +202.45.15.0/24 +202.45.16.0/20 +202.46.16.0/23 +202.46.18.0/24 +202.46.20.0/23 +202.46.32.0/19 +202.46.128.0/24 +202.46.224.0/20 +202.47.82.0/23 +202.47.96.0/22 +202.47.100.0/22 +202.47.104.0/22 +202.47.108.0/22 +202.47.126.0/24 +202.47.128.0/24 +202.47.130.0/23 +202.52.33.0/24 +202.52.34.0/24 +202.52.47.0/24 +202.52.143.0/24 +202.53.140.0/24 +202.53.143.0/24 +202.57.192.0/22 +202.57.196.0/22 +202.57.200.0/22 +202.57.204.0/22 +202.57.212.0/22 +202.57.216.0/22 +202.57.240.0/20 +202.58.0.0/24 +202.58.104.0/22 +202.58.112.0/22 +202.59.0.0/24 +202.59.1.0/24 +202.59.212.0/22 +202.59.236.0/24 +202.59.240.0/24 +202.60.48.0/21 +202.60.96.0/21 +202.60.112.0/20 +202.60.132.0/22 +202.60.136.0/21 +202.60.144.0/20 +202.61.68.0/22 +202.61.76.0/22 +202.61.88.0/22 +202.61.123.0/24 +202.61.127.0/24 +202.62.112.0/22 +202.62.248.0/22 +202.62.252.0/24 +202.62.255.0/24 +202.63.80.0/24 +202.63.81.0/24 +202.63.82.0/23 +202.63.84.0/22 +202.63.88.0/21 +202.63.160.0/19 +202.63.248.0/22 +202.63.253.0/24 +202.65.0.0/21 +202.65.8.0/23 +202.65.96.0/22 +202.65.100.0/22 +202.65.104.0/22 +202.65.108.0/22 +202.66.168.0/22 +202.67.0.0/22 +202.69.4.0/22 +202.69.16.0/20 +202.70.0.0/19 +202.70.96.0/20 +202.70.192.0/20 +202.71.32.0/22 +202.71.36.0/22 +202.71.40.0/22 +202.71.44.0/22 +202.72.40.0/21 +202.72.80.0/20 +202.72.112.0/22 +202.72.116.0/22 +202.72.120.0/22 +202.72.124.0/22 +202.73.128.0/22 +202.73.240.0/22 +202.73.244.0/22 +202.73.248.0/22 +202.73.252.0/22 +202.74.8.0/21 +202.74.36.0/24 +202.74.42.0/24 +202.74.52.0/24 +202.74.80.0/20 +202.74.254.0/23 +202.75.208.0/20 +202.75.252.0/22 +202.76.252.0/22 +202.77.80.0/21 +202.77.92.0/22 +202.78.8.0/21 +202.79.224.0/21 +202.79.248.0/22 +202.80.192.0/21 +202.80.200.0/21 +202.81.0.0/22 +202.81.176.0/22 +202.81.180.0/22 +202.81.184.0/22 +202.81.188.0/22 +202.83.252.0/22 +202.84.0.0/22 +202.84.4.0/22 +202.84.8.0/21 +202.84.16.0/23 +202.84.22.0/24 +202.84.24.0/21 +202.85.208.0/20 +202.86.249.0/24 +202.86.252.0/22 +202.87.80.0/20 +202.88.32.0/22 +202.89.8.0/21 +202.89.96.0/22 +202.89.108.0/22 +202.89.119.0/24 +202.89.232.0/21 +202.90.0.0/22 +202.90.16.0/22 +202.90.20.0/22 +202.90.24.0/22 +202.90.28.0/22 +202.90.37.0/24 +202.90.96.0/22 +202.90.100.0/22 +202.90.104.0/22 +202.90.108.0/22 +202.90.112.0/20 +202.90.193.0/24 +202.90.196.0/24 +202.90.205.0/24 +202.90.224.0/20 +202.91.0.0/22 +202.91.36.0/22 +202.91.96.0/20 +202.91.128.0/22 +202.91.176.0/20 +202.91.224.0/19 +202.92.0.0/22 +202.92.8.0/21 +202.92.48.0/20 +202.92.252.0/22 +202.93.0.0/22 +202.93.252.0/22 +202.94.74.0/24 +202.94.81.0/24 +202.94.92.0/22 +202.95.240.0/21 +202.95.252.0/22 +202.96.0.0/18 +202.96.64.0/21 +202.96.72.0/21 +202.96.80.0/20 +202.96.96.0/21 +202.96.104.0/21 +202.96.112.0/20 +202.96.128.0/21 +202.96.136.0/21 +202.96.144.0/20 +202.96.160.0/21 +202.96.168.0/21 +202.96.176.0/20 +202.96.192.0/21 +202.96.200.0/21 +202.96.208.0/20 +202.96.224.0/21 +202.96.232.0/21 +202.96.240.0/20 +202.97.0.0/21 +202.97.8.0/21 +202.97.16.0/20 +202.97.32.0/19 +202.97.64.0/19 +202.97.96.0/20 +202.97.112.0/20 +202.97.128.0/18 +202.97.192.0/19 +202.97.224.0/21 +202.97.232.0/21 +202.97.240.0/20 +202.98.0.0/21 +202.98.8.0/21 +202.98.16.0/20 +202.98.32.0/21 +202.98.40.0/21 +202.98.48.0/20 +202.98.64.0/19 +202.98.96.0/21 +202.98.104.0/21 +202.98.112.0/20 +202.98.128.0/19 +202.98.160.0/21 +202.98.168.0/21 +202.98.176.0/20 +202.98.192.0/21 +202.98.200.0/21 +202.98.208.0/20 +202.98.224.0/21 +202.98.232.0/21 +202.98.240.0/20 +202.99.0.0/18 +202.99.64.0/19 +202.99.96.0/21 +202.99.104.0/21 +202.99.112.0/20 +202.99.128.0/19 +202.99.160.0/21 +202.99.168.0/21 +202.99.176.0/20 +202.99.192.0/21 +202.99.200.0/21 +202.99.208.0/20 +202.99.224.0/21 +202.99.232.0/21 +202.99.240.0/20 +202.100.0.0/21 +202.100.8.0/21 +202.100.16.0/20 +202.100.32.0/19 +202.100.64.0/21 +202.100.72.0/21 +202.100.80.0/20 +202.100.96.0/21 +202.100.104.0/21 +202.100.112.0/20 +202.100.128.0/21 +202.100.136.0/21 +202.100.144.0/20 +202.100.160.0/21 +202.100.168.0/21 +202.100.176.0/20 +202.100.192.0/21 +202.100.200.0/21 +202.100.208.0/20 +202.100.224.0/19 +202.101.0.0/18 +202.101.64.0/19 +202.101.96.0/19 +202.101.128.0/18 +202.101.192.0/19 +202.101.224.0/21 +202.101.232.0/21 +202.101.240.0/20 +202.102.0.0/19 +202.102.32.0/19 +202.102.64.0/18 +202.102.128.0/21 +202.102.136.0/21 +202.102.144.0/20 +202.102.160.0/19 +202.102.192.0/21 +202.102.200.0/21 +202.102.208.0/20 +202.102.224.0/21 +202.102.232.0/21 +202.102.240.0/20 +202.103.0.0/21 +202.103.8.0/21 +202.103.16.0/20 +202.103.32.0/19 +202.103.64.0/19 +202.103.96.0/21 +202.103.104.0/21 +202.103.112.0/20 +202.103.128.0/18 +202.103.192.0/19 +202.103.224.0/21 +202.103.232.0/21 +202.103.240.0/20 +202.104.0.0/15 +202.106.0.0/16 +202.107.0.0/17 +202.107.128.0/17 +202.108.0.0/16 +202.109.0.0/16 +202.110.0.0/18 +202.110.64.0/18 +202.110.128.0/18 +202.110.192.0/18 +202.111.0.0/17 +202.111.128.0/19 +202.111.160.0/19 +202.111.192.0/18 +202.112.0.0/16 +202.113.0.0/20 +202.113.16.0/20 +202.113.32.0/19 +202.113.64.0/18 +202.113.128.0/18 +202.113.192.0/19 +202.113.224.0/20 +202.113.240.0/20 +202.114.0.0/19 +202.114.32.0/19 +202.114.64.0/18 +202.114.128.0/17 +202.115.0.0/19 +202.115.32.0/19 +202.115.64.0/18 +202.115.128.0/17 +202.116.0.0/19 +202.116.32.0/20 +202.116.48.0/20 +202.116.64.0/19 +202.116.96.0/19 +202.116.128.0/17 +202.117.0.0/18 +202.117.64.0/18 +202.117.128.0/17 +202.118.0.0/19 +202.118.32.0/19 +202.118.64.0/18 +202.118.128.0/17 +202.119.0.0/19 +202.119.32.0/19 +202.119.64.0/20 +202.119.80.0/20 +202.119.96.0/19 +202.119.128.0/17 +202.120.0.0/18 +202.120.64.0/18 +202.120.128.0/17 +202.121.0.0/16 +202.122.0.0/21 +202.122.32.0/21 +202.122.64.0/19 +202.122.112.0/21 +202.122.120.0/21 +202.122.128.0/24 +202.122.132.0/24 +202.123.96.0/20 +202.123.116.0/22 +202.123.120.0/22 +202.124.16.0/21 +202.124.24.0/22 +202.125.107.0/24 +202.125.109.0/24 +202.125.112.0/20 +202.125.176.0/20 +202.127.0.0/23 +202.127.2.0/24 +202.127.3.0/24 +202.127.4.0/24 +202.127.5.0/24 +202.127.6.0/23 +202.127.12.0/22 +202.127.16.0/20 +202.127.40.0/21 +202.127.48.0/20 +202.127.112.0/20 +202.127.128.0/20 +202.127.144.0/20 +202.127.160.0/21 +202.127.192.0/23 +202.127.194.0/23 +202.127.196.0/22 +202.127.200.0/21 +202.127.208.0/24 +202.127.209.0/24 +202.127.212.0/22 +202.127.216.0/21 +202.127.224.0/19 +202.129.208.0/24 +202.130.0.0/19 +202.130.39.0/24 +202.130.224.0/19 +202.131.16.0/21 +202.131.48.0/20 +202.131.208.0/20 +202.133.32.0/20 +202.134.58.0/24 +202.134.128.0/20 +202.134.208.0/22 +202.134.212.0/22 +202.134.216.0/22 +202.134.220.0/22 +202.136.48.0/20 +202.136.208.0/20 +202.136.224.0/20 +202.136.248.0/22 +202.137.231.0/24 +202.140.140.0/22 +202.140.144.0/22 +202.140.148.0/22 +202.140.152.0/22 +202.140.156.0/22 +202.141.160.0/19 +202.142.16.0/20 +202.143.4.0/22 +202.143.16.0/20 +202.143.32.0/20 +202.143.56.0/21 +202.143.100.0/22 +202.143.104.0/22 +202.144.196.0/22 +202.146.160.0/20 +202.146.186.0/24 +202.146.188.0/22 +202.146.196.0/22 +202.146.200.0/21 +202.147.144.0/20 +202.148.32.0/20 +202.148.64.0/19 +202.148.96.0/19 +202.149.32.0/19 +202.149.160.0/19 +202.149.224.0/19 +202.150.16.0/20 +202.150.32.0/20 +202.150.56.0/22 +202.150.192.0/20 +202.150.224.0/19 +202.151.0.0/22 +202.151.33.0/24 +202.151.128.0/19 +202.152.176.0/20 +202.153.0.0/22 +202.153.7.0/24 +202.153.48.0/20 +202.157.192.0/19 +202.158.160.0/19 +202.158.242.0/24 +202.160.140.0/22 +202.160.156.0/22 +202.160.176.0/20 +202.162.67.0/24 +202.162.75.0/24 +202.164.0.0/20 +202.164.96.0/19 +202.165.176.0/20 +202.165.208.0/20 +202.165.239.0/24 +202.165.240.0/23 +202.165.243.0/24 +202.165.245.0/24 +202.165.251.0/24 +202.165.252.0/22 +202.166.224.0/19 +202.168.80.0/22 +202.168.128.0/22 +202.168.132.0/22 +202.168.136.0/22 +202.168.140.0/22 +202.168.160.0/20 +202.168.176.0/20 +202.170.128.0/19 +202.170.216.0/21 +202.170.224.0/19 +202.171.216.0/21 +202.171.232.0/24 +202.171.235.0/24 +202.172.0.0/22 +202.172.7.0/24 +202.173.0.0/22 +202.173.6.0/24 +202.173.8.0/21 +202.173.112.0/22 +202.173.224.0/19 +202.174.64.0/20 +202.174.124.0/22 +202.176.224.0/19 +202.179.160.0/22 +202.179.164.0/22 +202.179.168.0/22 +202.179.172.0/22 +202.179.240.0/20 +202.180.128.0/19 +202.180.208.0/21 +202.181.8.0/22 +202.181.28.0/22 +202.181.112.0/20 +202.182.32.0/20 +202.182.192.0/19 +202.189.0.0/18 +202.189.80.0/20 +202.189.184.0/21 +202.191.0.0/24 +202.191.68.0/22 +202.191.72.0/21 +202.191.80.0/20 +202.192.0.0/13 +202.200.0.0/14 +202.204.0.0/14 +203.0.4.0/22 +203.0.10.0/23 +203.0.18.0/24 +203.0.24.0/24 +203.0.42.0/23 +203.0.45.0/24 +203.0.46.0/23 +203.0.81.0/24 +203.0.82.0/23 +203.0.90.0/23 +203.0.96.0/23 +203.0.104.0/21 +203.0.114.0/23 +203.0.122.0/24 +203.0.128.0/24 +203.0.130.0/23 +203.0.132.0/22 +203.0.137.0/24 +203.0.142.0/24 +203.0.144.0/24 +203.0.146.0/24 +203.0.148.0/24 +203.0.150.0/23 +203.0.152.0/24 +203.0.177.0/24 +203.0.224.0/24 +203.1.4.0/22 +203.1.18.0/24 +203.1.26.0/23 +203.1.65.0/24 +203.1.66.0/23 +203.1.70.0/23 +203.1.76.0/23 +203.1.90.0/24 +203.1.97.0/24 +203.1.98.0/23 +203.1.100.0/22 +203.1.108.0/24 +203.1.253.0/24 +203.1.254.0/24 +203.2.64.0/21 +203.2.73.0/24 +203.2.112.0/21 +203.2.126.0/23 +203.2.140.0/24 +203.2.150.0/24 +203.2.152.0/22 +203.2.156.0/23 +203.2.160.0/21 +203.2.180.0/23 +203.2.196.0/23 +203.2.209.0/24 +203.2.214.0/23 +203.2.226.0/23 +203.2.229.0/24 +203.2.236.0/23 +203.3.68.0/24 +203.3.72.0/23 +203.3.75.0/24 +203.3.80.0/21 +203.3.96.0/22 +203.3.105.0/24 +203.3.112.0/21 +203.3.120.0/24 +203.3.123.0/24 +203.3.135.0/24 +203.3.139.0/24 +203.3.143.0/24 +203.4.132.0/23 +203.4.134.0/24 +203.4.151.0/24 +203.4.152.0/22 +203.4.174.0/23 +203.4.180.0/24 +203.4.186.0/24 +203.4.205.0/24 +203.4.208.0/22 +203.4.227.0/24 +203.4.230.0/23 +203.5.4.0/23 +203.5.7.0/24 +203.5.8.0/23 +203.5.11.0/24 +203.5.21.0/24 +203.5.22.0/24 +203.5.44.0/24 +203.5.46.0/23 +203.5.52.0/22 +203.5.56.0/23 +203.5.60.0/23 +203.5.114.0/23 +203.5.118.0/24 +203.5.120.0/24 +203.5.172.0/24 +203.5.180.0/23 +203.5.182.0/24 +203.5.185.0/24 +203.5.186.0/24 +203.5.188.0/23 +203.5.190.0/24 +203.5.195.0/24 +203.5.214.0/23 +203.5.218.0/23 +203.6.131.0/24 +203.6.136.0/24 +203.6.138.0/23 +203.6.142.0/24 +203.6.150.0/23 +203.6.157.0/24 +203.6.159.0/24 +203.6.224.0/20 +203.6.248.0/23 +203.7.129.0/24 +203.7.138.0/23 +203.7.147.0/24 +203.7.150.0/23 +203.7.158.0/24 +203.7.192.0/23 +203.7.200.0/24 +203.8.0.0/24 +203.8.8.0/24 +203.8.23.0/24 +203.8.70.0/24 +203.8.82.0/24 +203.8.86.0/23 +203.8.91.0/24 +203.8.110.0/23 +203.8.115.0/24 +203.8.166.0/23 +203.8.169.0/24 +203.8.173.0/24 +203.8.184.0/24 +203.8.186.0/23 +203.8.190.0/23 +203.8.192.0/24 +203.8.197.0/24 +203.8.198.0/23 +203.8.203.0/24 +203.8.209.0/24 +203.8.210.0/23 +203.8.212.0/22 +203.8.217.0/24 +203.8.220.0/24 +203.9.32.0/24 +203.9.36.0/23 +203.9.57.0/24 +203.9.63.0/24 +203.9.65.0/24 +203.9.70.0/23 +203.9.72.0/24 +203.9.75.0/24 +203.9.76.0/23 +203.9.96.0/22 +203.9.100.0/23 +203.9.108.0/24 +203.9.158.0/24 +203.10.34.0/24 +203.10.56.0/24 +203.10.74.0/23 +203.10.84.0/22 +203.10.88.0/24 +203.10.95.0/24 +203.10.125.0/24 +203.11.70.0/24 +203.11.76.0/22 +203.11.82.0/24 +203.11.84.0/22 +203.11.100.0/22 +203.11.109.0/24 +203.11.117.0/24 +203.11.122.0/24 +203.11.126.0/24 +203.11.136.0/22 +203.11.141.0/24 +203.11.142.0/23 +203.11.180.0/22 +203.11.208.0/22 +203.12.16.0/24 +203.12.19.0/24 +203.12.24.0/24 +203.12.57.0/24 +203.12.65.0/24 +203.12.66.0/24 +203.12.70.0/23 +203.12.87.0/24 +203.12.100.0/23 +203.12.103.0/24 +203.12.114.0/24 +203.12.118.0/24 +203.12.130.0/24 +203.12.137.0/24 +203.12.196.0/22 +203.12.211.0/24 +203.12.219.0/24 +203.12.226.0/24 +203.12.240.0/22 +203.13.18.0/24 +203.13.24.0/24 +203.13.44.0/23 +203.13.88.0/23 +203.13.92.0/22 +203.13.173.0/24 +203.13.224.0/23 +203.13.227.0/24 +203.13.233.0/24 +203.14.24.0/22 +203.14.33.0/24 +203.14.56.0/24 +203.14.61.0/24 +203.14.62.0/24 +203.14.104.0/24 +203.14.114.0/23 +203.14.118.0/24 +203.14.162.0/24 +203.14.192.0/24 +203.14.194.0/23 +203.14.214.0/24 +203.14.231.0/24 +203.14.246.0/24 +203.15.0.0/20 +203.15.20.0/23 +203.15.22.0/24 +203.15.87.0/24 +203.15.88.0/23 +203.15.105.0/24 +203.15.112.0/21 +203.15.130.0/23 +203.15.149.0/24 +203.15.151.0/24 +203.15.156.0/22 +203.15.174.0/24 +203.15.227.0/24 +203.15.232.0/21 +203.15.240.0/23 +203.15.246.0/24 +203.16.10.0/24 +203.16.12.0/23 +203.16.16.0/21 +203.16.27.0/24 +203.16.38.0/24 +203.16.49.0/24 +203.16.50.0/23 +203.16.58.0/24 +203.16.63.0/24 +203.16.133.0/24 +203.16.161.0/24 +203.16.162.0/24 +203.16.186.0/23 +203.16.228.0/24 +203.16.238.0/24 +203.16.240.0/24 +203.16.245.0/24 +203.17.2.0/24 +203.17.18.0/24 +203.17.28.0/24 +203.17.39.0/24 +203.17.56.0/24 +203.17.74.0/23 +203.17.88.0/23 +203.17.136.0/24 +203.17.164.0/24 +203.17.187.0/24 +203.17.190.0/23 +203.17.231.0/24 +203.17.233.0/24 +203.17.248.0/24 +203.17.249.0/24 +203.17.255.0/24 +203.18.2.0/23 +203.18.4.0/24 +203.18.7.0/24 +203.18.31.0/24 +203.18.37.0/24 +203.18.48.0/23 +203.18.52.0/24 +203.18.72.0/22 +203.18.80.0/23 +203.18.87.0/24 +203.18.100.0/23 +203.18.105.0/24 +203.18.107.0/24 +203.18.110.0/24 +203.18.129.0/24 +203.18.131.0/24 +203.18.132.0/23 +203.18.144.0/24 +203.18.153.0/24 +203.18.199.0/24 +203.18.208.0/24 +203.18.211.0/24 +203.18.215.0/24 +203.19.1.0/24 +203.19.18.0/24 +203.19.24.0/24 +203.19.30.0/24 +203.19.32.0/21 +203.19.41.0/24 +203.19.44.0/23 +203.19.46.0/24 +203.19.58.0/24 +203.19.60.0/23 +203.19.64.0/24 +203.19.68.0/24 +203.19.72.0/24 +203.19.101.0/24 +203.19.111.0/24 +203.19.131.0/24 +203.19.133.0/24 +203.19.144.0/24 +203.19.147.0/24 +203.19.149.0/24 +203.19.156.0/24 +203.19.176.0/24 +203.19.178.0/23 +203.19.208.0/24 +203.19.228.0/22 +203.19.233.0/24 +203.19.242.0/24 +203.19.248.0/23 +203.19.255.0/24 +203.20.17.0/24 +203.20.40.0/23 +203.20.44.0/24 +203.20.48.0/24 +203.20.61.0/24 +203.20.65.0/24 +203.20.84.0/23 +203.20.89.0/24 +203.20.106.0/23 +203.20.115.0/24 +203.20.117.0/24 +203.20.118.0/23 +203.20.122.0/24 +203.20.126.0/23 +203.20.135.0/24 +203.20.136.0/21 +203.20.150.0/24 +203.20.230.0/24 +203.20.232.0/24 +203.20.236.0/24 +203.21.0.0/23 +203.21.2.0/24 +203.21.8.0/24 +203.21.10.0/24 +203.21.18.0/24 +203.21.33.0/24 +203.21.34.0/24 +203.21.41.0/24 +203.21.44.0/24 +203.21.68.0/24 +203.21.82.0/24 +203.21.96.0/22 +203.21.124.0/24 +203.21.136.0/23 +203.21.145.0/24 +203.21.206.0/24 +203.22.24.0/24 +203.22.28.0/23 +203.22.31.0/24 +203.22.68.0/24 +203.22.76.0/24 +203.22.78.0/24 +203.22.84.0/24 +203.22.87.0/24 +203.22.92.0/22 +203.22.99.0/24 +203.22.106.0/24 +203.22.122.0/23 +203.22.131.0/24 +203.22.163.0/24 +203.22.166.0/24 +203.22.170.0/24 +203.22.176.0/21 +203.22.194.0/24 +203.22.242.0/23 +203.22.245.0/24 +203.22.246.0/24 +203.22.252.0/23 +203.23.0.0/24 +203.23.47.0/24 +203.23.61.0/24 +203.23.62.0/23 +203.23.73.0/24 +203.23.85.0/24 +203.23.92.0/22 +203.23.98.0/24 +203.23.107.0/24 +203.23.112.0/24 +203.23.130.0/24 +203.23.140.0/23 +203.23.172.0/24 +203.23.182.0/24 +203.23.186.0/23 +203.23.192.0/24 +203.23.197.0/24 +203.23.198.0/24 +203.23.204.0/22 +203.23.224.0/24 +203.23.226.0/23 +203.23.228.0/22 +203.23.249.0/24 +203.23.251.0/24 +203.24.13.0/24 +203.24.18.0/24 +203.24.27.0/24 +203.24.43.0/24 +203.24.56.0/24 +203.24.58.0/24 +203.24.67.0/24 +203.24.74.0/24 +203.24.79.0/24 +203.24.80.0/23 +203.24.84.0/23 +203.24.86.0/24 +203.24.90.0/24 +203.24.111.0/24 +203.24.112.0/24 +203.24.116.0/24 +203.24.122.0/23 +203.24.145.0/24 +203.24.152.0/23 +203.24.157.0/24 +203.24.161.0/24 +203.24.167.0/24 +203.24.186.0/23 +203.24.199.0/24 +203.24.202.0/24 +203.24.212.0/23 +203.24.217.0/24 +203.24.219.0/24 +203.24.244.0/24 +203.25.19.0/24 +203.25.20.0/23 +203.25.46.0/24 +203.25.48.0/21 +203.25.64.0/23 +203.25.91.0/24 +203.25.99.0/24 +203.25.100.0/24 +203.25.106.0/24 +203.25.131.0/24 +203.25.135.0/24 +203.25.138.0/24 +203.25.147.0/24 +203.25.153.0/24 +203.25.154.0/23 +203.25.164.0/24 +203.25.166.0/24 +203.25.174.0/23 +203.25.180.0/24 +203.25.182.0/24 +203.25.191.0/24 +203.25.199.0/24 +203.25.200.0/24 +203.25.202.0/23 +203.25.208.0/20 +203.25.229.0/24 +203.25.235.0/24 +203.25.236.0/24 +203.25.242.0/24 +203.26.12.0/24 +203.26.34.0/24 +203.26.49.0/24 +203.26.50.0/24 +203.26.55.0/24 +203.26.56.0/23 +203.26.60.0/24 +203.26.65.0/24 +203.26.68.0/24 +203.26.76.0/24 +203.26.80.0/24 +203.26.84.0/24 +203.26.97.0/24 +203.26.102.0/23 +203.26.115.0/24 +203.26.116.0/24 +203.26.129.0/24 +203.26.143.0/24 +203.26.144.0/24 +203.26.148.0/23 +203.26.154.0/24 +203.26.158.0/23 +203.26.170.0/24 +203.26.173.0/24 +203.26.176.0/24 +203.26.185.0/24 +203.26.202.0/23 +203.26.210.0/24 +203.26.214.0/24 +203.26.222.0/24 +203.26.224.0/24 +203.26.228.0/24 +203.26.232.0/24 +203.27.0.0/24 +203.27.10.0/24 +203.27.15.0/24 +203.27.16.0/24 +203.27.20.0/24 +203.27.22.0/23 +203.27.40.0/24 +203.27.45.0/24 +203.27.53.0/24 +203.27.65.0/24 +203.27.66.0/24 +203.27.81.0/24 +203.27.88.0/24 +203.27.102.0/24 +203.27.109.0/24 +203.27.117.0/24 +203.27.121.0/24 +203.27.122.0/23 +203.27.125.0/24 +203.27.200.0/24 +203.27.202.0/24 +203.27.233.0/24 +203.27.241.0/24 +203.27.250.0/24 +203.28.10.0/24 +203.28.12.0/24 +203.28.33.0/24 +203.28.34.0/23 +203.28.43.0/24 +203.28.44.0/24 +203.28.54.0/24 +203.28.56.0/24 +203.28.73.0/24 +203.28.74.0/24 +203.28.76.0/24 +203.28.86.0/24 +203.28.88.0/24 +203.28.112.0/24 +203.28.131.0/24 +203.28.136.0/24 +203.28.140.0/24 +203.28.145.0/24 +203.28.165.0/24 +203.28.169.0/24 +203.28.170.0/24 +203.28.178.0/23 +203.28.185.0/24 +203.28.187.0/24 +203.28.196.0/24 +203.28.226.0/23 +203.28.239.0/24 +203.29.2.0/24 +203.29.8.0/23 +203.29.13.0/24 +203.29.14.0/24 +203.29.28.0/24 +203.29.46.0/24 +203.29.57.0/24 +203.29.61.0/24 +203.29.63.0/24 +203.29.69.0/24 +203.29.73.0/24 +203.29.81.0/24 +203.29.90.0/24 +203.29.95.0/24 +203.29.100.0/24 +203.29.103.0/24 +203.29.112.0/24 +203.29.120.0/22 +203.29.182.0/23 +203.29.187.0/24 +203.29.189.0/24 +203.29.190.0/24 +203.29.205.0/24 +203.29.210.0/24 +203.29.217.0/24 +203.29.227.0/24 +203.29.231.0/24 +203.29.233.0/24 +203.29.234.0/24 +203.29.248.0/24 +203.29.254.0/23 +203.30.16.0/23 +203.30.25.0/24 +203.30.27.0/24 +203.30.29.0/24 +203.30.66.0/24 +203.30.81.0/24 +203.30.87.0/24 +203.30.111.0/24 +203.30.121.0/24 +203.30.123.0/24 +203.30.152.0/24 +203.30.156.0/24 +203.30.162.0/24 +203.30.173.0/24 +203.30.175.0/24 +203.30.187.0/24 +203.30.194.0/24 +203.30.217.0/24 +203.30.220.0/24 +203.30.222.0/24 +203.30.232.0/23 +203.30.235.0/24 +203.30.240.0/23 +203.30.246.0/24 +203.30.250.0/23 +203.31.45.0/24 +203.31.46.0/24 +203.31.49.0/24 +203.31.51.0/24 +203.31.54.0/23 +203.31.69.0/24 +203.31.72.0/24 +203.31.80.0/24 +203.31.85.0/24 +203.31.97.0/24 +203.31.105.0/24 +203.31.106.0/24 +203.31.108.0/23 +203.31.124.0/24 +203.31.162.0/24 +203.31.174.0/24 +203.31.177.0/24 +203.31.181.0/24 +203.31.187.0/24 +203.31.189.0/24 +203.31.204.0/24 +203.31.220.0/24 +203.31.222.0/23 +203.31.225.0/24 +203.31.229.0/24 +203.31.248.0/23 +203.31.253.0/24 +203.32.20.0/24 +203.32.48.0/23 +203.32.56.0/24 +203.32.60.0/24 +203.32.62.0/24 +203.32.68.0/23 +203.32.76.0/24 +203.32.81.0/24 +203.32.84.0/23 +203.32.95.0/24 +203.32.102.0/24 +203.32.105.0/24 +203.32.130.0/24 +203.32.133.0/24 +203.32.140.0/24 +203.32.152.0/24 +203.32.186.0/23 +203.32.192.0/24 +203.32.196.0/24 +203.32.203.0/24 +203.32.204.0/23 +203.32.212.0/24 +203.33.4.0/24 +203.33.7.0/24 +203.33.8.0/21 +203.33.21.0/24 +203.33.26.0/24 +203.33.32.0/24 +203.33.63.0/24 +203.33.64.0/24 +203.33.67.0/24 +203.33.68.0/24 +203.33.73.0/24 +203.33.79.0/24 +203.33.100.0/24 +203.33.122.0/24 +203.33.129.0/24 +203.33.131.0/24 +203.33.145.0/24 +203.33.156.0/24 +203.33.158.0/23 +203.33.174.0/24 +203.33.185.0/24 +203.33.200.0/24 +203.33.202.0/23 +203.33.204.0/24 +203.33.206.0/23 +203.33.214.0/23 +203.33.224.0/23 +203.33.226.0/24 +203.33.233.0/24 +203.33.243.0/24 +203.33.250.0/24 +203.34.4.0/24 +203.34.21.0/24 +203.34.27.0/24 +203.34.39.0/24 +203.34.48.0/23 +203.34.54.0/24 +203.34.56.0/23 +203.34.67.0/24 +203.34.69.0/24 +203.34.76.0/24 +203.34.92.0/24 +203.34.106.0/24 +203.34.113.0/24 +203.34.147.0/24 +203.34.150.0/24 +203.34.152.0/23 +203.34.161.0/24 +203.34.162.0/24 +203.34.187.0/24 +203.34.192.0/21 +203.34.204.0/22 +203.34.232.0/24 +203.34.240.0/24 +203.34.242.0/24 +203.34.245.0/24 +203.34.251.0/24 +203.55.2.0/23 +203.55.4.0/24 +203.55.10.0/24 +203.55.13.0/24 +203.55.22.0/24 +203.55.30.0/24 +203.55.93.0/24 +203.55.101.0/24 +203.55.109.0/24 +203.55.110.0/24 +203.55.116.0/23 +203.55.119.0/24 +203.55.128.0/23 +203.55.146.0/23 +203.55.192.0/24 +203.55.196.0/24 +203.55.218.0/23 +203.55.221.0/24 +203.55.224.0/24 +203.56.1.0/24 +203.56.4.0/24 +203.56.12.0/24 +203.56.24.0/24 +203.56.38.0/24 +203.56.40.0/24 +203.56.46.0/24 +203.56.48.0/21 +203.56.68.0/23 +203.56.82.0/23 +203.56.84.0/23 +203.56.95.0/24 +203.56.110.0/24 +203.56.121.0/24 +203.56.161.0/24 +203.56.169.0/24 +203.56.172.0/23 +203.56.175.0/24 +203.56.183.0/24 +203.56.185.0/24 +203.56.187.0/24 +203.56.192.0/24 +203.56.198.0/24 +203.56.201.0/24 +203.56.208.0/23 +203.56.210.0/24 +203.56.214.0/24 +203.56.216.0/24 +203.56.227.0/24 +203.56.228.0/24 +203.56.231.0/24 +203.56.232.0/24 +203.56.240.0/24 +203.56.252.0/24 +203.56.254.0/24 +203.57.5.0/24 +203.57.6.0/24 +203.57.12.0/23 +203.57.28.0/24 +203.57.39.0/24 +203.57.46.0/24 +203.57.58.0/24 +203.57.61.0/24 +203.57.66.0/24 +203.57.69.0/24 +203.57.70.0/23 +203.57.73.0/24 +203.57.90.0/24 +203.57.101.0/24 +203.57.109.0/24 +203.57.123.0/24 +203.57.157.0/24 +203.57.200.0/24 +203.57.202.0/24 +203.57.206.0/24 +203.57.222.0/24 +203.57.224.0/20 +203.57.246.0/23 +203.57.249.0/24 +203.57.253.0/24 +203.57.254.0/23 +203.62.2.0/24 +203.62.131.0/24 +203.62.139.0/24 +203.62.161.0/24 +203.62.197.0/24 +203.62.228.0/22 +203.62.234.0/24 +203.62.246.0/24 +203.76.160.0/22 +203.76.168.0/22 +203.76.208.0/22 +203.76.212.0/22 +203.76.216.0/22 +203.76.240.0/22 +203.76.244.0/22 +203.77.180.0/22 +203.78.48.0/20 +203.78.156.0/22 +203.79.0.0/20 +203.79.32.0/20 +203.80.4.0/23 +203.80.32.0/20 +203.80.57.0/24 +203.80.129.0/24 +203.80.132.0/22 +203.80.136.0/21 +203.80.144.0/20 +203.81.0.0/21 +203.81.16.0/20 +203.81.244.0/22 +203.82.0.0/23 +203.82.16.0/21 +203.82.112.0/22 +203.82.116.0/22 +203.82.120.0/22 +203.82.124.0/22 +203.82.224.0/22 +203.82.228.0/22 +203.82.232.0/22 +203.82.236.0/22 +203.83.0.0/22 +203.83.8.0/22 +203.83.12.0/22 +203.83.56.0/21 +203.83.224.0/20 +203.86.0.0/19 +203.86.32.0/19 +203.86.64.0/20 +203.86.80.0/20 +203.86.96.0/19 +203.86.250.0/24 +203.86.254.0/23 +203.88.32.0/19 +203.88.192.0/19 +203.89.0.0/22 +203.89.8.0/21 +203.89.100.0/22 +203.89.133.0/24 +203.89.136.0/22 +203.89.144.0/24 +203.90.0.0/22 +203.90.8.0/22 +203.90.12.0/22 +203.90.128.0/19 +203.90.160.0/19 +203.90.192.0/19 +203.91.32.0/19 +203.91.96.0/20 +203.91.120.0/21 +203.92.0.0/22 +203.92.6.0/24 +203.92.160.0/19 +203.93.0.0/22 +203.93.4.0/22 +203.93.8.0/24 +203.93.9.0/24 +203.93.10.0/23 +203.93.12.0/22 +203.93.16.0/20 +203.93.32.0/19 +203.93.64.0/18 +203.93.128.0/21 +203.93.136.0/22 +203.93.140.0/24 +203.93.141.0/24 +203.93.142.0/23 +203.93.144.0/20 +203.93.160.0/19 +203.93.192.0/18 +203.94.0.0/22 +203.94.4.0/22 +203.94.8.0/21 +203.94.16.0/20 +203.95.0.0/21 +203.95.96.0/20 +203.95.112.0/20 +203.95.128.0/18 +203.95.200.0/22 +203.95.204.0/22 +203.95.208.0/22 +203.95.224.0/19 +203.99.8.0/21 +203.99.16.0/20 +203.99.80.0/20 +203.100.32.0/20 +203.100.48.0/21 +203.100.58.0/24 +203.100.60.0/24 +203.100.63.0/24 +203.100.80.0/20 +203.100.96.0/19 +203.100.192.0/20 +203.104.32.0/20 +203.105.96.0/19 +203.105.128.0/19 +203.107.0.0/17 +203.110.160.0/19 +203.110.208.0/20 +203.110.232.0/23 +203.110.234.0/24 +203.114.80.0/22 +203.114.84.0/22 +203.114.88.0/22 +203.114.92.0/22 +203.114.244.0/22 +203.118.192.0/19 +203.118.241.0/24 +203.118.248.0/22 +203.119.24.0/21 +203.119.32.0/22 +203.119.80.0/22 +203.119.85.0/24 +203.119.113.0/24 +203.119.114.0/23 +203.119.116.0/22 +203.119.120.0/21 +203.119.128.0/17 +203.123.58.0/24 +203.128.32.0/19 +203.128.96.0/19 +203.128.224.0/21 +203.129.8.0/21 +203.130.32.0/19 +203.132.32.0/19 +203.134.240.0/21 +203.135.96.0/20 +203.135.112.0/20 +203.135.160.0/20 +203.142.219.0/24 +203.142.224.0/19 +203.144.96.0/19 +203.145.0.0/19 +203.148.0.0/18 +203.148.64.0/20 +203.148.80.0/22 +203.148.86.0/23 +203.149.92.0/22 +203.152.64.0/19 +203.152.128.0/19 +203.153.0.0/22 +203.156.192.0/18 +203.158.16.0/21 +203.160.52.0/22 +203.160.104.0/21 +203.160.129.0/24 +203.160.192.0/19 +203.161.0.0/22 +203.161.180.0/24 +203.161.183.0/24 +203.161.192.0/19 +203.166.160.0/19 +203.167.28.0/22 +203.168.0.0/19 +203.170.58.0/23 +203.171.0.0/22 +203.171.208.0/24 +203.171.224.0/20 +203.174.4.0/24 +203.174.6.0/24 +203.174.7.0/24 +203.174.96.0/19 +203.175.128.0/19 +203.175.192.0/18 +203.176.0.0/18 +203.176.64.0/19 +203.176.168.0/21 +203.184.80.0/20 +203.185.189.0/24 +203.187.160.0/19 +203.189.0.0/23 +203.189.6.0/23 +203.189.112.0/22 +203.189.192.0/19 +203.189.240.0/22 +203.190.96.0/20 +203.190.249.0/24 +203.191.0.0/23 +203.191.2.0/24 +203.191.5.0/24 +203.191.7.0/24 +203.191.16.0/20 +203.191.64.0/18 +203.191.133.0/24 +203.191.144.0/21 +203.191.152.0/21 +203.192.0.0/19 +203.193.224.0/19 +203.194.120.0/21 +203.195.64.0/19 +203.195.112.0/21 +203.195.128.0/17 +203.196.0.0/21 +203.196.8.0/21 +203.196.28.0/22 +203.201.181.0/24 +203.201.182.0/24 +203.202.236.0/22 +203.205.64.0/19 +203.205.128.0/17 +203.207.64.0/20 +203.207.80.0/21 +203.207.88.0/22 +203.207.92.0/22 +203.207.96.0/20 +203.207.112.0/20 +203.207.128.0/18 +203.207.192.0/21 +203.207.200.0/21 +203.207.208.0/20 +203.207.224.0/19 +203.208.0.0/20 +203.208.16.0/22 +203.208.32.0/19 +203.209.224.0/19 +203.212.0.0/20 +203.212.80.0/20 +203.215.232.0/21 +203.217.164.0/22 +203.223.0.0/20 +203.223.16.0/21 +204.52.191.0/24 +210.2.0.0/20 +210.2.16.0/20 +210.5.0.0/19 +210.5.56.0/21 +210.5.128.0/20 +210.5.144.0/20 +210.7.56.0/22 +210.7.60.0/22 +210.12.0.0/18 +210.12.64.0/18 +210.12.128.0/18 +210.12.192.0/18 +210.13.0.0/18 +210.13.64.0/18 +210.13.128.0/17 +210.14.64.0/19 +210.14.112.0/20 +210.14.128.0/19 +210.14.160.0/19 +210.14.192.0/19 +210.14.224.0/19 +210.15.0.0/19 +210.15.32.0/19 +210.15.64.0/19 +210.15.96.0/19 +210.15.128.0/18 +210.16.104.0/22 +210.16.128.0/18 +210.21.0.0/17 +210.21.128.0/17 +210.22.0.0/16 +210.23.32.0/19 +210.25.0.0/16 +210.26.0.0/15 +210.28.0.0/14 +210.32.0.0/14 +210.36.0.0/14 +210.40.0.0/13 +210.51.0.0/16 +210.52.0.0/18 +210.52.64.0/18 +210.52.128.0/17 +210.53.0.0/17 +210.53.128.0/17 +210.56.192.0/19 +210.72.0.0/17 +210.72.128.0/19 +210.72.160.0/19 +210.72.192.0/18 +210.73.0.0/19 +210.73.32.0/19 +210.73.64.0/18 +210.73.128.0/17 +210.74.0.0/19 +210.74.32.0/19 +210.74.64.0/19 +210.74.96.0/19 +210.74.128.0/19 +210.74.160.0/19 +210.74.192.0/18 +210.75.0.0/16 +210.76.0.0/19 +210.76.32.0/19 +210.76.64.0/18 +210.76.128.0/17 +210.77.0.0/16 +210.78.0.0/19 +210.78.32.0/19 +210.78.64.0/18 +210.78.128.0/19 +210.78.160.0/19 +210.78.192.0/18 +210.79.64.0/18 +210.79.224.0/19 +210.82.0.0/15 +210.87.128.0/20 +210.87.144.0/20 +210.87.160.0/19 +210.185.192.0/18 +210.192.96.0/19 +211.64.0.0/14 +211.68.0.0/15 +211.70.0.0/15 +211.80.0.0/16 +211.81.0.0/16 +211.82.0.0/16 +211.83.0.0/16 +211.84.0.0/15 +211.86.0.0/15 +211.88.0.0/16 +211.89.0.0/16 +211.90.0.0/15 +211.92.0.0/15 +211.94.0.0/15 +211.96.0.0/15 +211.98.0.0/16 +211.99.0.0/18 +211.99.64.0/19 +211.99.96.0/19 +211.99.128.0/17 +211.100.0.0/16 +211.101.0.0/18 +211.101.64.0/18 +211.101.128.0/17 +211.102.0.0/16 +211.103.0.0/17 +211.103.128.0/17 +211.136.0.0/14 +211.140.0.0/15 +211.142.0.0/17 +211.142.128.0/17 +211.143.0.0/16 +211.144.0.0/15 +211.146.0.0/16 +211.147.0.0/16 +211.148.0.0/14 +211.152.0.0/15 +211.154.0.0/16 +211.155.0.0/18 +211.155.64.0/19 +211.155.96.0/19 +211.155.128.0/17 +211.156.0.0/14 +211.160.0.0/14 +211.164.0.0/14 +212.64.0.0/17 +212.129.128.0/17 +218.0.0.0/16 +218.1.0.0/16 +218.2.0.0/15 +218.4.0.0/15 +218.6.0.0/16 +218.7.0.0/16 +218.8.0.0/15 +218.10.0.0/16 +218.11.0.0/16 +218.12.0.0/16 +218.13.0.0/16 +218.14.0.0/15 +218.16.0.0/14 +218.20.0.0/16 +218.21.0.0/17 +218.21.128.0/17 +218.22.0.0/15 +218.24.0.0/15 +218.26.0.0/16 +218.27.0.0/16 +218.28.0.0/15 +218.30.0.0/15 +218.56.0.0/14 +218.60.0.0/15 +218.62.0.0/17 +218.62.128.0/17 +218.63.0.0/16 +218.64.0.0/15 +218.66.0.0/16 +218.67.0.0/17 +218.67.128.0/17 +218.68.0.0/15 +218.70.0.0/15 +218.72.0.0/14 +218.76.0.0/15 +218.78.0.0/15 +218.80.0.0/14 +218.84.0.0/14 +218.88.0.0/13 +218.96.0.0/15 +218.98.0.0/17 +218.98.128.0/18 +218.98.192.0/19 +218.98.224.0/19 +218.99.0.0/16 +218.100.88.0/21 +218.100.96.0/19 +218.100.128.0/17 +218.104.0.0/17 +218.104.128.0/19 +218.104.160.0/19 +218.104.192.0/21 +218.104.200.0/21 +218.104.208.0/20 +218.104.224.0/19 +218.105.0.0/16 +218.106.0.0/15 +218.108.0.0/16 +218.109.0.0/16 +218.185.192.0/19 +218.185.240.0/21 +218.192.0.0/16 +218.193.0.0/16 +218.194.0.0/16 +218.195.0.0/16 +218.196.0.0/14 +218.200.0.0/14 +218.204.0.0/15 +218.206.0.0/15 +218.240.0.0/14 +218.244.0.0/15 +218.246.0.0/15 +218.249.0.0/16 +219.72.0.0/16 +219.82.0.0/16 +219.83.128.0/17 +219.90.68.0/22 +219.90.72.0/22 +219.90.76.0/22 +219.128.0.0/12 +219.144.0.0/14 +219.148.0.0/16 +219.149.0.0/17 +219.149.128.0/18 +219.149.192.0/18 +219.150.0.0/19 +219.150.32.0/19 +219.150.64.0/19 +219.150.96.0/20 +219.150.112.0/20 +219.150.128.0/17 +219.151.0.0/19 +219.151.32.0/19 +219.151.64.0/18 +219.151.128.0/17 +219.152.0.0/15 +219.154.0.0/15 +219.156.0.0/15 +219.158.0.0/17 +219.158.128.0/17 +219.159.0.0/18 +219.159.64.0/18 +219.159.128.0/17 +219.216.0.0/15 +219.218.0.0/15 +219.220.0.0/16 +219.221.0.0/16 +219.222.0.0/15 +219.224.0.0/15 +219.226.0.0/16 +219.227.0.0/16 +219.228.0.0/15 +219.230.0.0/15 +219.232.0.0/14 +219.236.0.0/15 +219.238.0.0/15 +219.242.0.0/15 +219.244.0.0/14 +220.101.192.0/18 +220.112.0.0/14 +220.152.128.0/17 +220.154.0.0/15 +220.158.240.0/22 +220.160.0.0/11 +220.192.0.0/15 +220.194.0.0/15 +220.196.0.0/14 +220.200.0.0/13 +220.231.0.0/18 +220.231.128.0/17 +220.232.64.0/18 +220.234.0.0/16 +220.242.0.0/15 +220.247.136.0/21 +220.248.0.0/14 +220.252.0.0/16 +221.0.0.0/15 +221.2.0.0/16 +221.3.0.0/17 +221.3.128.0/17 +221.4.0.0/16 +221.5.0.0/17 +221.5.128.0/17 +221.6.0.0/16 +221.7.0.0/19 +221.7.32.0/19 +221.7.64.0/19 +221.7.96.0/19 +221.7.128.0/17 +221.8.0.0/15 +221.10.0.0/16 +221.11.0.0/17 +221.11.128.0/18 +221.11.192.0/19 +221.11.224.0/19 +221.12.0.0/17 +221.12.128.0/18 +221.13.0.0/18 +221.13.64.0/19 +221.13.96.0/19 +221.13.128.0/17 +221.14.0.0/15 +221.122.0.0/15 +221.128.128.0/17 +221.129.0.0/16 +221.130.0.0/15 +221.133.224.0/19 +221.136.0.0/16 +221.137.0.0/16 +221.172.0.0/14 +221.176.0.0/13 +221.192.0.0/15 +221.194.0.0/16 +221.195.0.0/16 +221.196.0.0/15 +221.198.0.0/16 +221.199.0.0/19 +221.199.32.0/20 +221.199.48.0/20 +221.199.64.0/18 +221.199.128.0/18 +221.199.192.0/20 +221.199.224.0/19 +221.200.0.0/14 +221.204.0.0/15 +221.206.0.0/16 +221.207.0.0/18 +221.207.64.0/18 +221.207.128.0/17 +221.208.0.0/14 +221.212.0.0/16 +221.213.0.0/16 +221.214.0.0/15 +221.216.0.0/13 +221.224.0.0/13 +221.232.0.0/14 +221.236.0.0/15 +221.238.0.0/16 +221.239.0.0/17 +221.239.128.0/17 +222.16.0.0/15 +222.18.0.0/15 +222.20.0.0/15 +222.22.0.0/16 +222.23.0.0/16 +222.24.0.0/15 +222.26.0.0/15 +222.28.0.0/14 +222.32.0.0/11 +222.64.0.0/13 +222.72.0.0/15 +222.74.0.0/16 +222.75.0.0/16 +222.76.0.0/14 +222.80.0.0/15 +222.82.0.0/16 +222.83.0.0/17 +222.83.128.0/17 +222.84.0.0/16 +222.85.0.0/17 +222.85.128.0/17 +222.86.0.0/15 +222.88.0.0/15 +222.90.0.0/15 +222.92.0.0/14 +222.125.0.0/16 +222.126.128.0/17 +222.128.0.0/14 +222.132.0.0/14 +222.136.0.0/13 +222.160.0.0/15 +222.162.0.0/16 +222.163.0.0/19 +222.163.32.0/19 +222.163.64.0/18 +222.163.128.0/17 +222.168.0.0/15 +222.170.0.0/15 +222.172.0.0/17 +222.172.128.0/17 +222.173.0.0/16 +222.174.0.0/15 +222.176.0.0/13 +222.184.0.0/13 +222.192.0.0/14 +222.196.0.0/15 +222.198.0.0/16 +222.199.0.0/16 +222.200.0.0/14 +222.204.0.0/15 +222.206.0.0/15 +222.208.0.0/13 +222.216.0.0/15 +222.218.0.0/16 +222.219.0.0/16 +222.220.0.0/15 +222.222.0.0/15 +222.240.0.0/13 +222.248.0.0/16 +222.249.0.0/17 +222.249.128.0/19 +222.249.160.0/20 +222.249.176.0/20 +222.249.192.0/18 +223.0.0.0/15 +223.2.0.0/15 +223.4.0.0/14 +223.8.0.0/13 +223.20.0.0/15 +223.27.184.0/22 +223.29.208.0/22 +223.29.252.0/22 +223.64.0.0/11 +223.96.0.0/12 +223.112.0.0/14 +223.116.0.0/15 +223.120.128.0/17 +223.121.128.0/17 +223.122.128.0/17 +223.123.128.0/17 +223.124.0.0/14 +223.128.0.0/15 +223.144.0.0/12 +223.160.0.0/14 +223.166.0.0/15 +223.192.0.0/15 +223.198.0.0/15 +223.201.0.0/16 +223.202.0.0/15 +223.208.0.0/14 +223.212.0.0/15 +223.214.0.0/15 +223.220.0.0/15 +223.223.176.0/20 +223.223.192.0/20 +223.240.0.0/13 +223.248.0.0/14 +223.252.128.0/17 +223.254.0.0/16 +223.255.0.0/17 +223.255.236.0/22 +223.255.252.0/23 diff --git a/luci-app-ssr-plus/root/etc/ssrplus/deny.list b/luci-app-ssr-plus/root/etc/ssrplus/deny.list new file mode 100644 index 00000000..dc4344e7 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/deny.list @@ -0,0 +1,14 @@ +gvod.aiseejapp.atianqi.com +stat.pandora.xiaomi.com +upgrade.mishop.pandora.xiaomi.com +logonext.tv.kuyun.com +config.kuyun.com +mishop.pandora.xiaomi.com +dvb.pandora.xiaomi.com +api.ad.xiaomi.com +de.pandora.xiaomi.com +data.mistat.xiaomi.com +jellyfish.pandora.xiaomi.com +gallery.pandora.xiaomi.com +o2o.api.xiaomi.com +bss.pandora.xiaomi.com \ No newline at end of file diff --git a/luci-app-ssr-plus/root/etc/ssrplus/dnsproxy_dns.list b/luci-app-ssr-plus/root/etc/ssrplus/dnsproxy_dns.list new file mode 100644 index 00000000..8010cc1b --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/dnsproxy_dns.list @@ -0,0 +1,17 @@ +# cloudflare-dns.com +sdns://AgcAAAAAAAAADjEwNC4xNi4yNDkuMjQ5ABJjbG91ZGZsYXJlLWRucy5jb20KL2Rucy1xdWVyeQ +# Google +sdns://AgUAAAAAAAAABzguOC40LjQgsKKKE4EwvtIbNjGjagI2607EdKSVHowYZtyvD9iPrkkHOC44LjQuNAovZG5zLXF1ZXJ5 +# dns.sb +sdns://AgcAAAAAAAAADzE4NS4yMjIuMjIyLjIyMiAOp5Svj-oV-Fz-65-8H2VKHLKJ0egmfEgrdPeAQlUFFA8xODUuMjIyLjIyMi4yMjIKL2Rucy1xdWVyeQ +# Quad9 +sdns://AgMAAAAAAAAADTE0OS4xMTIuMTEyLjkgsBkgdEu7dsmrBT4B4Ht-BQ5HPSD3n3vqQ1-v5DydJC8SZG5zOS5xdWFkOS5uZXQ6NDQzCi9kbnMtcXVlcnk +sdns://AQMAAAAAAAAADDkuOS45Ljk6ODQ0MyBnyEe4yHWM0SAkVUO-dWdG3zTfHYTAC4xHA2jfgh2GPhkyLmRuc2NyeXB0LWNlcnQucXVhZDkubmV0 +# AdGuard +sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20 +# Cloudflare +sdns://AgcAAAAAAAAABzEuMC4wLjGgENk8mGSlIfMGXMOlIlCcKvq7AVgcrZxtjon911-ep0cg63Ul-I8NlFj4GplQGb_TTLiczclX57DvMV8Q-JdjgRgSZG5zLmNsb3VkZmxhcmUuY29tCi9kbnMtcXVlcnk +# TWNIC-101 +sdns://AgcAAAAAAAAAACC2vD25TAYM7EnyCH8Xw1-0g5OccnTsGH9vQUUH0njRtAxkbnMudHduaWMudHcKL2Rucy1xdWVyeQ +# cs-tx +sdns://AQYAAAAAAAAADTIwOS41OC4xNDcuMzYgMTNyrVlWMsJBa4cvCY-FG925ZShMbL6aTxkJZDDbqVoeMi5kbnNjcnlwdC1jZXJ0LmNyeXB0b3N0b3JtLmlz diff --git a/luci-app-ssr-plus/root/etc/ssrplus/gfw_base.conf b/luci-app-ssr-plus/root/etc/ssrplus/gfw_base.conf new file mode 100644 index 00000000..d47df256 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/gfw_base.conf @@ -0,0 +1,110 @@ +server=/91smartyun.pt/127.0.0.1#5335 +ipset=/91smartyun.pt/gfwlist +server=/adobe.com/127.0.0.1#5335 +ipset=/adobe.com/gfwlist +server=/amazonaws.com/127.0.0.1#5335 +ipset=/amazonaws.com/gfwlist +server=/ampproject.org/127.0.0.1#5335 +ipset=/ampproject.org/gfwlist +server=/apple.news/127.0.0.1#5335 +ipset=/apple.news/gfwlist +server=/aws.amazon.com/127.0.0.1#5335 +ipset=/aws.amazon.com/gfwlist +server=/azureedge.net/127.0.0.1#5335 +ipset=/azureedge.net/gfwlist +server=/backpackers.com.tw/127.0.0.1#5335 +ipset=/backpackers.com.tw/gfwlist +server=/bitfinex.com/127.0.0.1#5335 +ipset=/bitfinex.com/gfwlist +server=/buzzfeed.com/127.0.0.1#5335 +ipset=/buzzfeed.com/gfwlist +server=/clockwise.ee/127.0.0.1#5335 +ipset=/clockwise.ee/gfwlist +server=/cloudfront.net/127.0.0.1#5335 +ipset=/cloudfront.net/gfwlist +server=/coindesk.com/127.0.0.1#5335 +ipset=/coindesk.com/gfwlist +server=/coinsquare.io/127.0.0.1#5335 +ipset=/coinsquare.io/gfwlist +server=/cryptocompare.com/127.0.0.1#5335 +ipset=/cryptocompare.com/gfwlist +server=/dropboxstatic.com/127.0.0.1#5335 +ipset=/dropboxstatic.com/gfwlist +server=/eurecom.fr/127.0.0.1#5335 +ipset=/eurecom.fr/gfwlist +server=/gdax.com/127.0.0.1#5335 +ipset=/gdax.com/gfwlist +server=/github.com/127.0.0.1#5335 +ipset=/github.com/gfwlist +server=/kknews.cc/127.0.0.1#5335 +ipset=/kknews.cc/gfwlist +server=/nutaq.com/127.0.0.1#5335 +ipset=/nutaq.com/gfwlist +server=/openairinterface.org/127.0.0.1#5335 +ipset=/openairinterface.org/gfwlist +server=/skype.com/127.0.0.1#5335 +ipset=/skype.com/gfwlist +server=/sublimetext.com/127.0.0.1#5335 +ipset=/sublimetext.com/gfwlist +server=/textnow.com/127.0.0.1#5335 +ipset=/textnow.com/gfwlist +server=/textnow.me/127.0.0.1#5335 +ipset=/textnow.me/gfwlist +server=/trouter.io/127.0.0.1#5335 +ipset=/trouter.io/gfwlist +server=/t66y.com/127.0.0.1#5335 +ipset=/t66y.com/gfwlist +server=/uploaded.net/127.0.0.1#5335 +ipset=/uploaded.net/gfwlist +server=/v2rayssr.com/127.0.0.1#5335 +ipset=/v2rayssr.com/gfwlist +server=/whatsapp.com/127.0.0.1#5335 +ipset=/whatsapp.com/gfwlist +server=/whatsapp.net/127.0.0.1#5335 +ipset=/whatsapp.net/gfwlist +server=/wsj.net/127.0.0.1#5335 +ipset=/wsj.net/gfwlist +server=/google.com/127.0.0.1#5335 +ipset=/google.com/gfwlist +server=/google.com.hk/127.0.0.1#5335 +ipset=/google.com.hk/gfwlist +server=/gstatic.com/127.0.0.1#5335 +ipset=/gstatic.com/gfwlist +server=/googleusercontent.com/127.0.0.1#5335 +ipset=/googleusercontent.com/gfwlist +server=/googlepages.com/127.0.0.1#5335 +ipset=/googlepages.com/gfwlist +server=/googlevideo.com/127.0.0.1#5335 +ipset=/googlevideo.com/gfwlist +server=/googlecode.com/127.0.0.1#5335 +ipset=/googlecode.com/gfwlist +server=/googleapis.com/127.0.0.1#5335 +ipset=/googleapis.com/gfwlist +server=/googlesource.com/127.0.0.1#5335 +ipset=/googlesource.com/gfwlist +server=/googledrive.com/127.0.0.1#5335 +ipset=/googledrive.com/gfwlist +server=/ggpht.com/127.0.0.1#5335 +ipset=/ggpht.com/gfwlist +server=/youtube.com/127.0.0.1#5335 +ipset=/youtube.com/gfwlist +server=/youtu.be/127.0.0.1#5335 +ipset=/youtu.be/gfwlist +server=/ytimg.com/127.0.0.1#5335 +ipset=/ytimg.com/gfwlist +server=/twitter.com/127.0.0.1#5335 +ipset=/twitter.com/gfwlist +server=/facebook.com/127.0.0.1#5335 +ipset=/facebook.com/gfwlist +server=/fastly.net/127.0.0.1#5335 +ipset=/fastly.net/gfwlist +server=/akamai.net/127.0.0.1#5335 +ipset=/akamai.net/gfwlist +server=/akamaiedge.net/127.0.0.1#5335 +ipset=/akamaiedge.net/gfwlist +server=/akamaihd.net/127.0.0.1#5335 +ipset=/akamaihd.net/gfwlist +server=/edgesuite.net/127.0.0.1#5335 +ipset=/edgesuite.net/gfwlist +server=/edgekey.net/127.0.0.1#5335 +ipset=/edgekey.net/gfwlist diff --git a/luci-app-ssr-plus/root/etc/ssrplus/gfw_list.conf b/luci-app-ssr-plus/root/etc/ssrplus/gfw_list.conf new file mode 100644 index 00000000..a44d3714 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/gfw_list.conf @@ -0,0 +1,35608 @@ +server=/samebags.com/127.0.0.1#5335 +ipset=/samebags.com/gfwlist +server=/premiumhd.net/127.0.0.1#5335 +ipset=/premiumhd.net/gfwlist +server=/facebool.com/127.0.0.1#5335 +ipset=/facebool.com/gfwlist +server=/disneystore.com/127.0.0.1#5335 +ipset=/disneystore.com/gfwlist +server=/lcsmerch.com/127.0.0.1#5335 +ipset=/lcsmerch.com/gfwlist +server=/hentais.tube/127.0.0.1#5335 +ipset=/hentais.tube/gfwlist +server=/teenport.com/127.0.0.1#5335 +ipset=/teenport.com/gfwlist +server=/zeit.sh/127.0.0.1#5335 +ipset=/zeit.sh/gfwlist +server=/mrvideosdesexo.xxx/127.0.0.1#5335 +ipset=/mrvideosdesexo.xxx/gfwlist +server=/xxxindiantv.com/127.0.0.1#5335 +ipset=/xxxindiantv.com/gfwlist +server=/visacheckout.org/127.0.0.1#5335 +ipset=/visacheckout.org/gfwlist +server=/discordapp.net/127.0.0.1#5335 +ipset=/discordapp.net/gfwlist +server=/kaggle.com/127.0.0.1#5335 +ipset=/kaggle.com/gfwlist +server=/bbycontent.net/127.0.0.1#5335 +ipset=/bbycontent.net/gfwlist +server=/imagebam.com/127.0.0.1#5335 +ipset=/imagebam.com/gfwlist +server=/oreillystatic.com/127.0.0.1#5335 +ipset=/oreillystatic.com/gfwlist +server=/ahxxx.club/127.0.0.1#5335 +ipset=/ahxxx.club/gfwlist +server=/duckduckco.com/127.0.0.1#5335 +ipset=/duckduckco.com/gfwlist +server=/duyaoss.com/127.0.0.1#5335 +ipset=/duyaoss.com/gfwlist +server=/buyitnow.org/127.0.0.1#5335 +ipset=/buyitnow.org/gfwlist +server=/paypali.net/127.0.0.1#5335 +ipset=/paypali.net/gfwlist +server=/nvidia.com.tr/127.0.0.1#5335 +ipset=/nvidia.com.tr/gfwlist +server=/applepaycash.tv/127.0.0.1#5335 +ipset=/applepaycash.tv/gfwlist +server=/livestream.com/127.0.0.1#5335 +ipset=/livestream.com/gfwlist +server=/homebrew.bintray.com/127.0.0.1#5335 +ipset=/homebrew.bintray.com/gfwlist +server=/bustylornamorgan.com/127.0.0.1#5335 +ipset=/bustylornamorgan.com/gfwlist +server=/18acg.us/127.0.0.1#5335 +ipset=/18acg.us/gfwlist +server=/google.co.ke/127.0.0.1#5335 +ipset=/google.co.ke/gfwlist +server=/itunes.mx/127.0.0.1#5335 +ipset=/itunes.mx/gfwlist +server=/beatssingaporeshop.com/127.0.0.1#5335 +ipset=/beatssingaporeshop.com/gfwlist +server=/beatsbydreuk.net/127.0.0.1#5335 +ipset=/beatsbydreuk.net/gfwlist +server=/hentaiclub.net/127.0.0.1#5335 +ipset=/hentaiclub.net/gfwlist +server=/cloudchoose.com/127.0.0.1#5335 +ipset=/cloudchoose.com/gfwlist +server=/codeforces.com/127.0.0.1#5335 +ipset=/codeforces.com/gfwlist +server=/lizol.co.in/127.0.0.1#5335 +ipset=/lizol.co.in/gfwlist +server=/applecomputer.com.hk/127.0.0.1#5335 +ipset=/applecomputer.com.hk/gfwlist +server=/bridgestonearena.com/127.0.0.1#5335 +ipset=/bridgestonearena.com/gfwlist +server=/vpngate.net/127.0.0.1#5335 +ipset=/vpngate.net/gfwlist +server=/developer-advisor.com/127.0.0.1#5335 +ipset=/developer-advisor.com/gfwlist +server=/81jia.tv/127.0.0.1#5335 +ipset=/81jia.tv/gfwlist +server=/youtube.co.uk/127.0.0.1#5335 +ipset=/youtube.co.uk/gfwlist +server=/youporngay.com/127.0.0.1#5335 +ipset=/youporngay.com/gfwlist +server=/alphabet.pt/127.0.0.1#5335 +ipset=/alphabet.pt/gfwlist +server=/itfromtheinside.com/127.0.0.1#5335 +ipset=/itfromtheinside.com/gfwlist +server=/teenchoice.com/127.0.0.1#5335 +ipset=/teenchoice.com/gfwlist +server=/filmespornos.net/127.0.0.1#5335 +ipset=/filmespornos.net/gfwlist +server=/ftvnews.com.tw/127.0.0.1#5335 +ipset=/ftvnews.com.tw/gfwlist +server=/kindle.co.jp/127.0.0.1#5335 +ipset=/kindle.co.jp/gfwlist +server=/terraform.io/127.0.0.1#5335 +ipset=/terraform.io/gfwlist +server=/faycbok.com/127.0.0.1#5335 +ipset=/faycbok.com/gfwlist +server=/scpwiki.com/127.0.0.1#5335 +ipset=/scpwiki.com/gfwlist +server=/sexyandfunny.com/127.0.0.1#5335 +ipset=/sexyandfunny.com/gfwlist +server=/google.vg/127.0.0.1#5335 +ipset=/google.vg/gfwlist +server=/runporn.com/127.0.0.1#5335 +ipset=/runporn.com/gfwlist +server=/alivertsm.com/127.0.0.1#5335 +ipset=/alivertsm.com/gfwlist +server=/camwhores.forum/127.0.0.1#5335 +ipset=/camwhores.forum/gfwlist +server=/wolfatbestbuy.net/127.0.0.1#5335 +ipset=/wolfatbestbuy.net/gfwlist +server=/legaltracker.com/127.0.0.1#5335 +ipset=/legaltracker.com/gfwlist +server=/centervillage.co.jp/127.0.0.1#5335 +ipset=/centervillage.co.jp/gfwlist +server=/cshive.com/127.0.0.1#5335 +ipset=/cshive.com/gfwlist +server=/fox13memphis.com/127.0.0.1#5335 +ipset=/fox13memphis.com/gfwlist +server=/appleone.cloud/127.0.0.1#5335 +ipset=/appleone.cloud/gfwlist +server=/aiaa.org/127.0.0.1#5335 +ipset=/aiaa.org/gfwlist +server=/yahoo.rw/127.0.0.1#5335 +ipset=/yahoo.rw/gfwlist +server=/dudethrill.com/127.0.0.1#5335 +ipset=/dudethrill.com/gfwlist +server=/ouplaw.com/127.0.0.1#5335 +ipset=/ouplaw.com/gfwlist +server=/anthemthegame.com/127.0.0.1#5335 +ipset=/anthemthegame.com/gfwlist +server=/adobetag.com/127.0.0.1#5335 +ipset=/adobetag.com/gfwlist +server=/kingkong.com.tw/127.0.0.1#5335 +ipset=/kingkong.com.tw/gfwlist +server=/appleos.tv/127.0.0.1#5335 +ipset=/appleos.tv/gfwlist +server=/igayporn.tv/127.0.0.1#5335 +ipset=/igayporn.tv/gfwlist +server=/beatsheadphonesonline.com/127.0.0.1#5335 +ipset=/beatsheadphonesonline.com/gfwlist +server=/maturetube.com/127.0.0.1#5335 +ipset=/maturetube.com/gfwlist +server=/visasoutheasteurope.com/127.0.0.1#5335 +ipset=/visasoutheasteurope.com/gfwlist +server=/trueamateurs.com/127.0.0.1#5335 +ipset=/trueamateurs.com/gfwlist +server=/telesco.pe/127.0.0.1#5335 +ipset=/telesco.pe/gfwlist +server=/monsterbeatsoutlet.us/127.0.0.1#5335 +ipset=/monsterbeatsoutlet.us/gfwlist +server=/gettyimages.it/127.0.0.1#5335 +ipset=/gettyimages.it/gfwlist +server=/videodesexo.blog/127.0.0.1#5335 +ipset=/videodesexo.blog/gfwlist +server=/hpiie.org/127.0.0.1#5335 +ipset=/hpiie.org/gfwlist +server=/ipadair.ie/127.0.0.1#5335 +ipset=/ipadair.ie/gfwlist +server=/20thcenturystudios.com.br/127.0.0.1#5335 +ipset=/20thcenturystudios.com.br/gfwlist +server=/beatsbydreoksale.com/127.0.0.1#5335 +ipset=/beatsbydreoksale.com/gfwlist +server=/paypal-security.org/127.0.0.1#5335 +ipset=/paypal-security.org/gfwlist +server=/visa.com.hk/127.0.0.1#5335 +ipset=/visa.com.hk/gfwlist +server=/webcamtubexxx.com/127.0.0.1#5335 +ipset=/webcamtubexxx.com/gfwlist +server=/hanime.tv/127.0.0.1#5335 +ipset=/hanime.tv/gfwlist +server=/beatsbymusic.net/127.0.0.1#5335 +ipset=/beatsbymusic.net/gfwlist +server=/czechvr.com/127.0.0.1#5335 +ipset=/czechvr.com/gfwlist +server=/licdn.cn.cdn20.com/127.0.0.1#5335 +ipset=/licdn.cn.cdn20.com/gfwlist +server=/sourceforge.net/127.0.0.1#5335 +ipset=/sourceforge.net/gfwlist +server=/amazonianblog.com/127.0.0.1#5335 +ipset=/amazonianblog.com/gfwlist +server=/visa.com.vn/127.0.0.1#5335 +ipset=/visa.com.vn/gfwlist +server=/gaypinoyporn.com/127.0.0.1#5335 +ipset=/gaypinoyporn.com/gfwlist +server=/blogspot.pt/127.0.0.1#5335 +ipset=/blogspot.pt/gfwlist +server=/xnxxsexmovies.com/127.0.0.1#5335 +ipset=/xnxxsexmovies.com/gfwlist +server=/ultimaonline.com/127.0.0.1#5335 +ipset=/ultimaonline.com/gfwlist +server=/paypal-latam.com/127.0.0.1#5335 +ipset=/paypal-latam.com/gfwlist +server=/echichimato.com/127.0.0.1#5335 +ipset=/echichimato.com/gfwlist +server=/escort24h.net/127.0.0.1#5335 +ipset=/escort24h.net/gfwlist +server=/apple.pk/127.0.0.1#5335 +ipset=/apple.pk/gfwlist +server=/oculus2014.com/127.0.0.1#5335 +ipset=/oculus2014.com/gfwlist +server=/intel.co.za/127.0.0.1#5335 +ipset=/intel.co.za/gfwlist +server=/pornmegaload.com/127.0.0.1#5335 +ipset=/pornmegaload.com/gfwlist +server=/facboo.com/127.0.0.1#5335 +ipset=/facboo.com/gfwlist +server=/jtube.space/127.0.0.1#5335 +ipset=/jtube.space/gfwlist +server=/pornomovies.mobi/127.0.0.1#5335 +ipset=/pornomovies.mobi/gfwlist +server=/facebookswagemea.com/127.0.0.1#5335 +ipset=/facebookswagemea.com/gfwlist +server=/mapbox.com/127.0.0.1#5335 +ipset=/mapbox.com/gfwlist +server=/eurosexscene.com/127.0.0.1#5335 +ipset=/eurosexscene.com/gfwlist +server=/kanzhongguo.com/127.0.0.1#5335 +ipset=/kanzhongguo.com/gfwlist +server=/directtv.net/127.0.0.1#5335 +ipset=/directtv.net/gfwlist +server=/swisssigngroup.ch/127.0.0.1#5335 +ipset=/swisssigngroup.ch/gfwlist +server=/muycerdas.xxx/127.0.0.1#5335 +ipset=/muycerdas.xxx/gfwlist +server=/facebuk.com/127.0.0.1#5335 +ipset=/facebuk.com/gfwlist +server=/monsterbeatsau.com/127.0.0.1#5335 +ipset=/monsterbeatsau.com/gfwlist +server=/yandex.com.am/127.0.0.1#5335 +ipset=/yandex.com.am/gfwlist +server=/softbankbb.com/127.0.0.1#5335 +ipset=/softbankbb.com/gfwlist +server=/finishinfo.nl/127.0.0.1#5335 +ipset=/finishinfo.nl/gfwlist +server=/webex.com.hk/127.0.0.1#5335 +ipset=/webex.com.hk/gfwlist +server=/pornzone.com/127.0.0.1#5335 +ipset=/pornzone.com/gfwlist +server=/microsoft.be/127.0.0.1#5335 +ipset=/microsoft.be/gfwlist +server=/bravoporn.com/127.0.0.1#5335 +ipset=/bravoporn.com/gfwlist +server=/mitao.bar/127.0.0.1#5335 +ipset=/mitao.bar/gfwlist +server=/illusionxz.com/127.0.0.1#5335 +ipset=/illusionxz.com/gfwlist +server=/paypal-qrshopping.org/127.0.0.1#5335 +ipset=/paypal-qrshopping.org/gfwlist +server=/nikeconfluence.com/127.0.0.1#5335 +ipset=/nikeconfluence.com/gfwlist +server=/applewatch.hk/127.0.0.1#5335 +ipset=/applewatch.hk/gfwlist +server=/foxfiles.com/127.0.0.1#5335 +ipset=/foxfiles.com/gfwlist +server=/sony.at/127.0.0.1#5335 +ipset=/sony.at/gfwlist +server=/openamt.com/127.0.0.1#5335 +ipset=/openamt.com/gfwlist +server=/applemusic.com.au/127.0.0.1#5335 +ipset=/applemusic.com.au/gfwlist +server=/manhub.com/127.0.0.1#5335 +ipset=/manhub.com/gfwlist +server=/hentaiz.mobi/127.0.0.1#5335 +ipset=/hentaiz.mobi/gfwlist +server=/covid19-rx.org/127.0.0.1#5335 +ipset=/covid19-rx.org/gfwlist +server=/sexcartoon.biz/127.0.0.1#5335 +ipset=/sexcartoon.biz/gfwlist +server=/hentai-ani.me/127.0.0.1#5335 +ipset=/hentai-ani.me/gfwlist +server=/gandi.net/127.0.0.1#5335 +ipset=/gandi.net/gfwlist +server=/ebaylisting.com/127.0.0.1#5335 +ipset=/ebaylisting.com/gfwlist +server=/xxxvideoamatoriali.com/127.0.0.1#5335 +ipset=/xxxvideoamatoriali.com/gfwlist +server=/persiankitty.com/127.0.0.1#5335 +ipset=/persiankitty.com/gfwlist +server=/i-book.com/127.0.0.1#5335 +ipset=/i-book.com/gfwlist +server=/spiedigitallibrary.org/127.0.0.1#5335 +ipset=/spiedigitallibrary.org/gfwlist +server=/hentaicomics.life/127.0.0.1#5335 +ipset=/hentaicomics.life/gfwlist +server=/icloud.ee/127.0.0.1#5335 +ipset=/icloud.ee/gfwlist +server=/muscdn.com/127.0.0.1#5335 +ipset=/muscdn.com/gfwlist +server=/xn--8uq428d76d.tokyo/127.0.0.1#5335 +ipset=/xn--8uq428d76d.tokyo/gfwlist +server=/mytving.com/127.0.0.1#5335 +ipset=/mytving.com/gfwlist +server=/topfreepornvideos.com/127.0.0.1#5335 +ipset=/topfreepornvideos.com/gfwlist +server=/yahoo.sh/127.0.0.1#5335 +ipset=/yahoo.sh/gfwlist +server=/stepfamilyporn.com/127.0.0.1#5335 +ipset=/stepfamilyporn.com/gfwlist +server=/vim.org/127.0.0.1#5335 +ipset=/vim.org/gfwlist +server=/nvidia.no/127.0.0.1#5335 +ipset=/nvidia.no/gfwlist +server=/seqingx.com/127.0.0.1#5335 +ipset=/seqingx.com/gfwlist +server=/liverail.tv/127.0.0.1#5335 +ipset=/liverail.tv/gfwlist +server=/espn.net/127.0.0.1#5335 +ipset=/espn.net/gfwlist +server=/beatsheadphones-discount.com/127.0.0.1#5335 +ipset=/beatsheadphones-discount.com/gfwlist +server=/dvdstudiopro.info/127.0.0.1#5335 +ipset=/dvdstudiopro.info/gfwlist +server=/khotruyentranhx.com/127.0.0.1#5335 +ipset=/khotruyentranhx.com/gfwlist +server=/gettyimages.co.jp/127.0.0.1#5335 +ipset=/gettyimages.co.jp/gfwlist +server=/avstar9.com/127.0.0.1#5335 +ipset=/avstar9.com/gfwlist +server=/javseen.tv/127.0.0.1#5335 +ipset=/javseen.tv/gfwlist +server=/amateur-gallery-post.com/127.0.0.1#5335 +ipset=/amateur-gallery-post.com/gfwlist +server=/movefreerewards.com/127.0.0.1#5335 +ipset=/movefreerewards.com/gfwlist +server=/ebayon.com/127.0.0.1#5335 +ipset=/ebayon.com/gfwlist +server=/live.com.au/127.0.0.1#5335 +ipset=/live.com.au/gfwlist +server=/easttouch.com.hk/127.0.0.1#5335 +ipset=/easttouch.com.hk/gfwlist +server=/neuralink.com/127.0.0.1#5335 +ipset=/neuralink.com/gfwlist +server=/europornstar.com/127.0.0.1#5335 +ipset=/europornstar.com/gfwlist +server=/realestatejournal.com/127.0.0.1#5335 +ipset=/realestatejournal.com/gfwlist +server=/ero-labs.net/127.0.0.1#5335 +ipset=/ero-labs.net/gfwlist +server=/qingse.one/127.0.0.1#5335 +ipset=/qingse.one/gfwlist +server=/oculusblog.com/127.0.0.1#5335 +ipset=/oculusblog.com/gfwlist +server=/youngtube.me/127.0.0.1#5335 +ipset=/youngtube.me/gfwlist +server=/xxxlucah.com/127.0.0.1#5335 +ipset=/xxxlucah.com/gfwlist +server=/bmwmotorcycleusa.com/127.0.0.1#5335 +ipset=/bmwmotorcycleusa.com/gfwlist +server=/vendu.com/127.0.0.1#5335 +ipset=/vendu.com/gfwlist +server=/facebook-newsroom.org/127.0.0.1#5335 +ipset=/facebook-newsroom.org/gfwlist +server=/disneychannelonstage.com/127.0.0.1#5335 +ipset=/disneychannelonstage.com/gfwlist +server=/filmesporno.net.br/127.0.0.1#5335 +ipset=/filmesporno.net.br/gfwlist +server=/iphonefc.com/127.0.0.1#5335 +ipset=/iphonefc.com/gfwlist +server=/arabxnxx.org/127.0.0.1#5335 +ipset=/arabxnxx.org/gfwlist +server=/google.bj/127.0.0.1#5335 +ipset=/google.bj/gfwlist +server=/tvbweekly.com/127.0.0.1#5335 +ipset=/tvbweekly.com/gfwlist +server=/avsee01.tv/127.0.0.1#5335 +ipset=/avsee01.tv/gfwlist +server=/nikegadgets.com/127.0.0.1#5335 +ipset=/nikegadgets.com/gfwlist +server=/turborepo.org/127.0.0.1#5335 +ipset=/turborepo.org/gfwlist +server=/mature.nl/127.0.0.1#5335 +ipset=/mature.nl/gfwlist +server=/ampproject.net/127.0.0.1#5335 +ipset=/ampproject.net/gfwlist +server=/tnt-ea.com/127.0.0.1#5335 +ipset=/tnt-ea.com/gfwlist +server=/huffingtonpost.in/127.0.0.1#5335 +ipset=/huffingtonpost.in/gfwlist +server=/veet.co.nz/127.0.0.1#5335 +ipset=/veet.co.nz/gfwlist +server=/lovesexdurex.com/127.0.0.1#5335 +ipset=/lovesexdurex.com/gfwlist +server=/paypal-status.com/127.0.0.1#5335 +ipset=/paypal-status.com/gfwlist +server=/volvotrucks.cl/127.0.0.1#5335 +ipset=/volvotrucks.cl/gfwlist +server=/periscope.tv/127.0.0.1#5335 +ipset=/periscope.tv/gfwlist +server=/interracial-sites.com/127.0.0.1#5335 +ipset=/interracial-sites.com/gfwlist +server=/mini-connected.lv/127.0.0.1#5335 +ipset=/mini-connected.lv/gfwlist +server=/vrfun18.com/127.0.0.1#5335 +ipset=/vrfun18.com/gfwlist +server=/twttr.net/127.0.0.1#5335 +ipset=/twttr.net/gfwlist +server=/yahoo.com.pa/127.0.0.1#5335 +ipset=/yahoo.com.pa/gfwlist +server=/omtrdc.net/127.0.0.1#5335 +ipset=/omtrdc.net/gfwlist +server=/pornoh.info/127.0.0.1#5335 +ipset=/pornoh.info/gfwlist +server=/paypal-luxury.com/127.0.0.1#5335 +ipset=/paypal-luxury.com/gfwlist +server=/theporndude.com/127.0.0.1#5335 +ipset=/theporndude.com/gfwlist +server=/hentaiaction.net/127.0.0.1#5335 +ipset=/hentaiaction.net/gfwlist +server=/pixnet.net/127.0.0.1#5335 +ipset=/pixnet.net/gfwlist +server=/r18lu.com/127.0.0.1#5335 +ipset=/r18lu.com/gfwlist +server=/hackerfacebook.com/127.0.0.1#5335 +ipset=/hackerfacebook.com/gfwlist +server=/rupress.org/127.0.0.1#5335 +ipset=/rupress.org/gfwlist +server=/eventsinfocus.org/127.0.0.1#5335 +ipset=/eventsinfocus.org/gfwlist +server=/xnxxarab.cc/127.0.0.1#5335 +ipset=/xnxxarab.cc/gfwlist +server=/chinatimes.com.tw/127.0.0.1#5335 +ipset=/chinatimes.com.tw/gfwlist +server=/hbo.com/127.0.0.1#5335 +ipset=/hbo.com/gfwlist +server=/shopee.es/127.0.0.1#5335 +ipset=/shopee.es/gfwlist +server=/akamaihd.com/127.0.0.1#5335 +ipset=/akamaihd.com/gfwlist +server=/hentaizap.com/127.0.0.1#5335 +ipset=/hentaizap.com/gfwlist +server=/windows.net/127.0.0.1#5335 +ipset=/windows.net/gfwlist +server=/machosaonatural.com.br/127.0.0.1#5335 +ipset=/machosaonatural.com.br/gfwlist +server=/compresspdf.new/127.0.0.1#5335 +ipset=/compresspdf.new/gfwlist +server=/amazonvideo.com/127.0.0.1#5335 +ipset=/amazonvideo.com/gfwlist +server=/fbjav.com/127.0.0.1#5335 +ipset=/fbjav.com/gfwlist +server=/docleradn.com/127.0.0.1#5335 +ipset=/docleradn.com/gfwlist +server=/airmax360.com/127.0.0.1#5335 +ipset=/airmax360.com/gfwlist +server=/xn--pearsonenespaol-brb.com/127.0.0.1#5335 +ipset=/xn--pearsonenespaol-brb.com/gfwlist +server=/hpeventcenter.com/127.0.0.1#5335 +ipset=/hpeventcenter.com/gfwlist +server=/apple.co/127.0.0.1#5335 +ipset=/apple.co/gfwlist +server=/18porno.tv/127.0.0.1#5335 +ipset=/18porno.tv/gfwlist +server=/r18.com/127.0.0.1#5335 +ipset=/r18.com/gfwlist +server=/starbucks.co.nz/127.0.0.1#5335 +ipset=/starbucks.co.nz/gfwlist +server=/justlesbianpussy.com/127.0.0.1#5335 +ipset=/justlesbianpussy.com/gfwlist +server=/noc.syosetu.com/127.0.0.1#5335 +ipset=/noc.syosetu.com/gfwlist +server=/certificate-transparency.org/127.0.0.1#5335 +ipset=/certificate-transparency.org/gfwlist +server=/snapads.com/127.0.0.1#5335 +ipset=/snapads.com/gfwlist +server=/txdirectv.com/127.0.0.1#5335 +ipset=/txdirectv.com/gfwlist +server=/youflix.is/127.0.0.1#5335 +ipset=/youflix.is/gfwlist +server=/foxsports.com.co/127.0.0.1#5335 +ipset=/foxsports.com.co/gfwlist +server=/bmw.lv/127.0.0.1#5335 +ipset=/bmw.lv/gfwlist +server=/rmbl.ws/127.0.0.1#5335 +ipset=/rmbl.ws/gfwlist +server=/myfoxla.com/127.0.0.1#5335 +ipset=/myfoxla.com/gfwlist +server=/microsoftteams.com/127.0.0.1#5335 +ipset=/microsoftteams.com/gfwlist +server=/harica.gr/127.0.0.1#5335 +ipset=/harica.gr/gfwlist +server=/visa.com.mx/127.0.0.1#5335 +ipset=/visa.com.mx/gfwlist +server=/readthedocs.com/127.0.0.1#5335 +ipset=/readthedocs.com/gfwlist +server=/uug26.com/127.0.0.1#5335 +ipset=/uug26.com/gfwlist +server=/bmw-motorrad.pl/127.0.0.1#5335 +ipset=/bmw-motorrad.pl/gfwlist +server=/akamam.com/127.0.0.1#5335 +ipset=/akamam.com/gfwlist +server=/redtube9.com/127.0.0.1#5335 +ipset=/redtube9.com/gfwlist +server=/mycardbenefits.com/127.0.0.1#5335 +ipset=/mycardbenefits.com/gfwlist +server=/leecountytimes.com/127.0.0.1#5335 +ipset=/leecountytimes.com/gfwlist +server=/sexasia.net/127.0.0.1#5335 +ipset=/sexasia.net/gfwlist +server=/mcrouter.net/127.0.0.1#5335 +ipset=/mcrouter.net/gfwlist +server=/bloomberg.tv/127.0.0.1#5335 +ipset=/bloomberg.tv/gfwlist +server=/lagranepoca.com/127.0.0.1#5335 +ipset=/lagranepoca.com/gfwlist +server=/ikea.es/127.0.0.1#5335 +ipset=/ikea.es/gfwlist +server=/n0vadesktop.com/127.0.0.1#5335 +ipset=/n0vadesktop.com/gfwlist +server=/google.tl/127.0.0.1#5335 +ipset=/google.tl/gfwlist +server=/disneyjuniortreataday.com/127.0.0.1#5335 +ipset=/disneyjuniortreataday.com/gfwlist +server=/minidealer.com/127.0.0.1#5335 +ipset=/minidealer.com/gfwlist +server=/webex.es/127.0.0.1#5335 +ipset=/webex.es/gfwlist +server=/intelemeastore.com/127.0.0.1#5335 +ipset=/intelemeastore.com/gfwlist +server=/nlt-media.com/127.0.0.1#5335 +ipset=/nlt-media.com/gfwlist +server=/pinterest.uk/127.0.0.1#5335 +ipset=/pinterest.uk/gfwlist +server=/avsforum.com/127.0.0.1#5335 +ipset=/avsforum.com/gfwlist +server=/cnnlabs.com/127.0.0.1#5335 +ipset=/cnnlabs.com/gfwlist +server=/sexmomsex.com/127.0.0.1#5335 +ipset=/sexmomsex.com/gfwlist +server=/mbheadphone.com/127.0.0.1#5335 +ipset=/mbheadphone.com/gfwlist +server=/xn--gtvq61aiijy0b.xn--hxt814e/127.0.0.1#5335 +ipset=/xn--gtvq61aiijy0b.xn--hxt814e/gfwlist +server=/buynikechina.com/127.0.0.1#5335 +ipset=/buynikechina.com/gfwlist +server=/durex.com.my/127.0.0.1#5335 +ipset=/durex.com.my/gfwlist +server=/pearsonhighered.com/127.0.0.1#5335 +ipset=/pearsonhighered.com/gfwlist +server=/dongtaiwang.com/127.0.0.1#5335 +ipset=/dongtaiwang.com/gfwlist +server=/visualstudio.com/127.0.0.1#5335 +ipset=/visualstudio.com/gfwlist +server=/ikea.co.ph/127.0.0.1#5335 +ipset=/ikea.co.ph/gfwlist +server=/jiyou520.com/127.0.0.1#5335 +ipset=/jiyou520.com/gfwlist +server=/pocketcasts.com/127.0.0.1#5335 +ipset=/pocketcasts.com/gfwlist +server=/ero-labs.com/127.0.0.1#5335 +ipset=/ero-labs.com/gfwlist +server=/immxd.com/127.0.0.1#5335 +ipset=/immxd.com/gfwlist +server=/bmw.com.ky/127.0.0.1#5335 +ipset=/bmw.com.ky/gfwlist +server=/hooligapps.com/127.0.0.1#5335 +ipset=/hooligapps.com/gfwlist +server=/embase.com/127.0.0.1#5335 +ipset=/embase.com/gfwlist +server=/3dadultgames.net/127.0.0.1#5335 +ipset=/3dadultgames.net/gfwlist +server=/amazon.com/127.0.0.1#5335 +ipset=/amazon.com/gfwlist +server=/cheapbeatsbydremonster.com/127.0.0.1#5335 +ipset=/cheapbeatsbydremonster.com/gfwlist +server=/fastly.com/127.0.0.1#5335 +ipset=/fastly.com/gfwlist +server=/wwwfacebok.com/127.0.0.1#5335 +ipset=/wwwfacebok.com/gfwlist +server=/drebeats-singaporecheap.net/127.0.0.1#5335 +ipset=/drebeats-singaporecheap.net/gfwlist +server=/hcomic.net/127.0.0.1#5335 +ipset=/hcomic.net/gfwlist +server=/dlib.eastview.com/127.0.0.1#5335 +ipset=/dlib.eastview.com/gfwlist +server=/masseffect.com/127.0.0.1#5335 +ipset=/masseffect.com/gfwlist +server=/ducksear.ch/127.0.0.1#5335 +ipset=/ducksear.ch/gfwlist +server=/passion-hd.com/127.0.0.1#5335 +ipset=/passion-hd.com/gfwlist +server=/secret-flirt-hub.com/127.0.0.1#5335 +ipset=/secret-flirt-hub.com/gfwlist +server=/minirichmond.com/127.0.0.1#5335 +ipset=/minirichmond.com/gfwlist +server=/google.lu/127.0.0.1#5335 +ipset=/google.lu/gfwlist +server=/alibabacloud.com.my/127.0.0.1#5335 +ipset=/alibabacloud.com.my/gfwlist +server=/veet.be/127.0.0.1#5335 +ipset=/veet.be/gfwlist +server=/alteraforum.com/127.0.0.1#5335 +ipset=/alteraforum.com/gfwlist +server=/shahvatsaraa.com/127.0.0.1#5335 +ipset=/shahvatsaraa.com/gfwlist +server=/xxxcomics.org/127.0.0.1#5335 +ipset=/xxxcomics.org/gfwlist +server=/porzo.tv/127.0.0.1#5335 +ipset=/porzo.tv/gfwlist +server=/sovec.net/127.0.0.1#5335 +ipset=/sovec.net/gfwlist +server=/stupidcams.com/127.0.0.1#5335 +ipset=/stupidcams.com/gfwlist +server=/carekit.org/127.0.0.1#5335 +ipset=/carekit.org/gfwlist +server=/apple.hu/127.0.0.1#5335 +ipset=/apple.hu/gfwlist +server=/o2action.co.kr/127.0.0.1#5335 +ipset=/o2action.co.kr/gfwlist +server=/minisaskatoon.com/127.0.0.1#5335 +ipset=/minisaskatoon.com/gfwlist +server=/nflximg.net/127.0.0.1#5335 +ipset=/nflximg.net/gfwlist +server=/hentai2games.com/127.0.0.1#5335 +ipset=/hentai2games.com/gfwlist +server=/avn.com/127.0.0.1#5335 +ipset=/avn.com/gfwlist +server=/google.by/127.0.0.1#5335 +ipset=/google.by/gfwlist +server=/abellalist.com/127.0.0.1#5335 +ipset=/abellalist.com/gfwlist +server=/dkcloud.cc/127.0.0.1#5335 +ipset=/dkcloud.cc/gfwlist +server=/mudvod.tv/127.0.0.1#5335 +ipset=/mudvod.tv/gfwlist +server=/wasdj.com/127.0.0.1#5335 +ipset=/wasdj.com/gfwlist +server=/myhentaigallery.com/127.0.0.1#5335 +ipset=/myhentaigallery.com/gfwlist +server=/swingerpornfun.com/127.0.0.1#5335 +ipset=/swingerpornfun.com/gfwlist +server=/shahvani.site/127.0.0.1#5335 +ipset=/shahvani.site/gfwlist +server=/naughtysophie.com/127.0.0.1#5335 +ipset=/naughtysophie.com/gfwlist +server=/smartonesolutions.hk/127.0.0.1#5335 +ipset=/smartonesolutions.hk/gfwlist +server=/minihalifax.com/127.0.0.1#5335 +ipset=/minihalifax.com/gfwlist +server=/firestonecomercial.co.cr/127.0.0.1#5335 +ipset=/firestonecomercial.co.cr/gfwlist +server=/onlyfreelatinaporn.com/127.0.0.1#5335 +ipset=/onlyfreelatinaporn.com/gfwlist +server=/cairnspost.com.au/127.0.0.1#5335 +ipset=/cairnspost.com.au/gfwlist +server=/easy.ac/127.0.0.1#5335 +ipset=/easy.ac/gfwlist +server=/hugesex.tv/127.0.0.1#5335 +ipset=/hugesex.tv/gfwlist +server=/opengraphprotocol.org/127.0.0.1#5335 +ipset=/opengraphprotocol.org/gfwlist +server=/vilavpn.xyz/127.0.0.1#5335 +ipset=/vilavpn.xyz/gfwlist +server=/pornsoldiers.com/127.0.0.1#5335 +ipset=/pornsoldiers.com/gfwlist +server=/firestoneip.com/127.0.0.1#5335 +ipset=/firestoneip.com/gfwlist +server=/ocul.us/127.0.0.1#5335 +ipset=/ocul.us/gfwlist +server=/microsoftcloudsummit.com/127.0.0.1#5335 +ipset=/microsoftcloudsummit.com/gfwlist +server=/hplipopensource.com/127.0.0.1#5335 +ipset=/hplipopensource.com/gfwlist +server=/zoofilianet.com/127.0.0.1#5335 +ipset=/zoofilianet.com/gfwlist +server=/intel.ua/127.0.0.1#5335 +ipset=/intel.ua/gfwlist +server=/eroprofile.com/127.0.0.1#5335 +ipset=/eroprofile.com/gfwlist +server=/xn--xsq421m.com/127.0.0.1#5335 +ipset=/xn--xsq421m.com/gfwlist +server=/eromanga-mainichi.com/127.0.0.1#5335 +ipset=/eromanga-mainichi.com/gfwlist +server=/facebooksite.net/127.0.0.1#5335 +ipset=/facebooksite.net/gfwlist +server=/javcc.cc/127.0.0.1#5335 +ipset=/javcc.cc/gfwlist +server=/gimy.cc/127.0.0.1#5335 +ipset=/gimy.cc/gfwlist +server=/honkaiimpact3.com/127.0.0.1#5335 +ipset=/honkaiimpact3.com/gfwlist +server=/line.me/127.0.0.1#5335 +ipset=/line.me/gfwlist +server=/plumperpass.com/127.0.0.1#5335 +ipset=/plumperpass.com/gfwlist +server=/durex.no/127.0.0.1#5335 +ipset=/durex.no/gfwlist +server=/abema-tv.com/127.0.0.1#5335 +ipset=/abema-tv.com/gfwlist +server=/sony.cz/127.0.0.1#5335 +ipset=/sony.cz/gfwlist +server=/porndex.com/127.0.0.1#5335 +ipset=/porndex.com/gfwlist +server=/faecebok.com/127.0.0.1#5335 +ipset=/faecebok.com/gfwlist +server=/e-goods.ru/127.0.0.1#5335 +ipset=/e-goods.ru/gfwlist +server=/boslife.biz/127.0.0.1#5335 +ipset=/boslife.biz/gfwlist +server=/onepornlist.com/127.0.0.1#5335 +ipset=/onepornlist.com/gfwlist +server=/ntdtv-dc.com/127.0.0.1#5335 +ipset=/ntdtv-dc.com/gfwlist +server=/pornzog.com/127.0.0.1#5335 +ipset=/pornzog.com/gfwlist +server=/disneymagicmoments.co.uk/127.0.0.1#5335 +ipset=/disneymagicmoments.co.uk/gfwlist +server=/astm.org/127.0.0.1#5335 +ipset=/astm.org/gfwlist +server=/gofucker.com/127.0.0.1#5335 +ipset=/gofucker.com/gfwlist +server=/intramuscularinjection.info/127.0.0.1#5335 +ipset=/intramuscularinjection.info/gfwlist +server=/camerfirma.com/127.0.0.1#5335 +ipset=/camerfirma.com/gfwlist +server=/sony.com.hk/127.0.0.1#5335 +ipset=/sony.com.hk/gfwlist +server=/ebayinc.net/127.0.0.1#5335 +ipset=/ebayinc.net/gfwlist +server=/lesbiansubmission.com/127.0.0.1#5335 +ipset=/lesbiansubmission.com/gfwlist +server=/paypa1.com/127.0.0.1#5335 +ipset=/paypa1.com/gfwlist +server=/pctlwm.com/127.0.0.1#5335 +ipset=/pctlwm.com/gfwlist +server=/volvogroup.ru/127.0.0.1#5335 +ipset=/volvogroup.ru/gfwlist +server=/pearsonassessment.se/127.0.0.1#5335 +ipset=/pearsonassessment.se/gfwlist +server=/ifuckedmy.mom/127.0.0.1#5335 +ipset=/ifuckedmy.mom/gfwlist +server=/chimeforchange.org/127.0.0.1#5335 +ipset=/chimeforchange.org/gfwlist +server=/intelrxt.com/127.0.0.1#5335 +ipset=/intelrxt.com/gfwlist +server=/oneocsp.microsoft.com/127.0.0.1#5335 +ipset=/oneocsp.microsoft.com/gfwlist +server=/hilostripper.com/127.0.0.1#5335 +ipset=/hilostripper.com/gfwlist +server=/txxx1.com/127.0.0.1#5335 +ipset=/txxx1.com/gfwlist +server=/signalbar.com/127.0.0.1#5335 +ipset=/signalbar.com/gfwlist +server=/rule34.world/127.0.0.1#5335 +ipset=/rule34.world/gfwlist +server=/goodreads.com/127.0.0.1#5335 +ipset=/goodreads.com/gfwlist +server=/hairypornsite.com/127.0.0.1#5335 +ipset=/hairypornsite.com/gfwlist +server=/beatsincanada.com/127.0.0.1#5335 +ipset=/beatsincanada.com/gfwlist +server=/thebayuk.com/127.0.0.1#5335 +ipset=/thebayuk.com/gfwlist +server=/ebaymarketplace.net/127.0.0.1#5335 +ipset=/ebaymarketplace.net/gfwlist +server=/localizestatus.com/127.0.0.1#5335 +ipset=/localizestatus.com/gfwlist +server=/thotvids.com/127.0.0.1#5335 +ipset=/thotvids.com/gfwlist +server=/erogazo-jp.net/127.0.0.1#5335 +ipset=/erogazo-jp.net/gfwlist +server=/akaint.net/127.0.0.1#5335 +ipset=/akaint.net/gfwlist +server=/acm.org/127.0.0.1#5335 +ipset=/acm.org/gfwlist +server=/whyiwantciscotelepresence.com/127.0.0.1#5335 +ipset=/whyiwantciscotelepresence.com/gfwlist +server=/awetv.com/127.0.0.1#5335 +ipset=/awetv.com/gfwlist +server=/sensueel.net/127.0.0.1#5335 +ipset=/sensueel.net/gfwlist +server=/eprc.com.hk/127.0.0.1#5335 +ipset=/eprc.com.hk/gfwlist +server=/youtube-nocookie.com/127.0.0.1#5335 +ipset=/youtube-nocookie.com/gfwlist +server=/paypal-login.com/127.0.0.1#5335 +ipset=/paypal-login.com/gfwlist +server=/macbook.wang/127.0.0.1#5335 +ipset=/macbook.wang/gfwlist +server=/xn--4vq475g.com/127.0.0.1#5335 +ipset=/xn--4vq475g.com/gfwlist +server=/ikea.sk/127.0.0.1#5335 +ipset=/ikea.sk/gfwlist +server=/xxxscenes.net/127.0.0.1#5335 +ipset=/xxxscenes.net/gfwlist +server=/mini.com.pe/127.0.0.1#5335 +ipset=/mini.com.pe/gfwlist +server=/codeish.io/127.0.0.1#5335 +ipset=/codeish.io/gfwlist +server=/hpcatridge.com/127.0.0.1#5335 +ipset=/hpcatridge.com/gfwlist +server=/yahoo.st/127.0.0.1#5335 +ipset=/yahoo.st/gfwlist +server=/starbuckssummergame.com/127.0.0.1#5335 +ipset=/starbuckssummergame.com/gfwlist +server=/adultfriendfinder.com/127.0.0.1#5335 +ipset=/adultfriendfinder.com/gfwlist +server=/showup.tv/127.0.0.1#5335 +ipset=/showup.tv/gfwlist +server=/daretoku-eromanga.info/127.0.0.1#5335 +ipset=/daretoku-eromanga.info/gfwlist +server=/wowpornlist.xyz/127.0.0.1#5335 +ipset=/wowpornlist.xyz/gfwlist +server=/justpicsplease.com/127.0.0.1#5335 +ipset=/justpicsplease.com/gfwlist +server=/readthedocs.io/127.0.0.1#5335 +ipset=/readthedocs.io/gfwlist +server=/zoho.com.au/127.0.0.1#5335 +ipset=/zoho.com.au/gfwlist +server=/sonykigyo.jp/127.0.0.1#5335 +ipset=/sonykigyo.jp/gfwlist +server=/vscode.blob.core.windows.net/127.0.0.1#5335 +ipset=/vscode.blob.core.windows.net/gfwlist +server=/ve-dash-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/ve-dash-uk-live.akamaized.net/gfwlist +server=/qualcomm.sc.omtrdc.net/127.0.0.1#5335 +ipset=/qualcomm.sc.omtrdc.net/gfwlist +server=/teenagefucking.com/127.0.0.1#5335 +ipset=/teenagefucking.com/gfwlist +server=/intel.uz/127.0.0.1#5335 +ipset=/intel.uz/gfwlist +server=/facebook.shop/127.0.0.1#5335 +ipset=/facebook.shop/gfwlist +server=/edcity.hk/127.0.0.1#5335 +ipset=/edcity.hk/gfwlist +server=/5278.cc/127.0.0.1#5335 +ipset=/5278.cc/gfwlist +server=/nbys.tv/127.0.0.1#5335 +ipset=/nbys.tv/gfwlist +server=/youtubecisco.com/127.0.0.1#5335 +ipset=/youtubecisco.com/gfwlist +server=/animezilla.com/127.0.0.1#5335 +ipset=/animezilla.com/gfwlist +server=/fundinginstitutional.com/127.0.0.1#5335 +ipset=/fundinginstitutional.com/gfwlist +server=/metart.com/127.0.0.1#5335 +ipset=/metart.com/gfwlist +server=/httpsfacebook.com/127.0.0.1#5335 +ipset=/httpsfacebook.com/gfwlist +server=/icegay.tv/127.0.0.1#5335 +ipset=/icegay.tv/gfwlist +server=/animal-porn.net/127.0.0.1#5335 +ipset=/animal-porn.net/gfwlist +server=/airwick.co.uk/127.0.0.1#5335 +ipset=/airwick.co.uk/gfwlist +server=/beatsbysdrbre.com/127.0.0.1#5335 +ipset=/beatsbysdrbre.com/gfwlist +server=/fblitho.com/127.0.0.1#5335 +ipset=/fblitho.com/gfwlist +server=/iphonehangzhou.com/127.0.0.1#5335 +ipset=/iphonehangzhou.com/gfwlist +server=/orientalasianporn.com/127.0.0.1#5335 +ipset=/orientalasianporn.com/gfwlist +server=/av11.org/127.0.0.1#5335 +ipset=/av11.org/gfwlist +server=/alphabet.com.mx/127.0.0.1#5335 +ipset=/alphabet.com.mx/gfwlist +server=/goduckgo.com/127.0.0.1#5335 +ipset=/goduckgo.com/gfwlist +server=/18-teen-porn.com/127.0.0.1#5335 +ipset=/18-teen-porn.com/gfwlist +server=/pornofint.com/127.0.0.1#5335 +ipset=/pornofint.com/gfwlist +server=/gfjizz.com/127.0.0.1#5335 +ipset=/gfjizz.com/gfwlist +server=/monsterbeats-cheap.com/127.0.0.1#5335 +ipset=/monsterbeats-cheap.com/gfwlist +server=/pinterest.info/127.0.0.1#5335 +ipset=/pinterest.info/gfwlist +server=/azuredevopslaunch.com/127.0.0.1#5335 +ipset=/azuredevopslaunch.com/gfwlist +server=/volvotrucks.se/127.0.0.1#5335 +ipset=/volvotrucks.se/gfwlist +server=/otaku-168.com/127.0.0.1#5335 +ipset=/otaku-168.com/gfwlist +server=/mini.mu/127.0.0.1#5335 +ipset=/mini.mu/gfwlist +server=/bioone.org/127.0.0.1#5335 +ipset=/bioone.org/gfwlist +server=/cnnamador.com/127.0.0.1#5335 +ipset=/cnnamador.com/gfwlist +server=/hentai3dvideo.biz/127.0.0.1#5335 +ipset=/hentai3dvideo.biz/gfwlist +server=/biowarestore.com/127.0.0.1#5335 +ipset=/biowarestore.com/gfwlist +server=/veet.fr/127.0.0.1#5335 +ipset=/veet.fr/gfwlist +server=/lolibus.cc/127.0.0.1#5335 +ipset=/lolibus.cc/gfwlist +server=/fetishpapa.com/127.0.0.1#5335 +ipset=/fetishpapa.com/gfwlist +server=/linkjunkies.com/127.0.0.1#5335 +ipset=/linkjunkies.com/gfwlist +server=/inoreader.com/127.0.0.1#5335 +ipset=/inoreader.com/gfwlist +server=/go-gaytube.com/127.0.0.1#5335 +ipset=/go-gaytube.com/gfwlist +server=/kindle.in/127.0.0.1#5335 +ipset=/kindle.in/gfwlist +server=/dandalinvoa.com/127.0.0.1#5335 +ipset=/dandalinvoa.com/gfwlist +server=/cygames.jp/127.0.0.1#5335 +ipset=/cygames.jp/gfwlist +server=/alt3-mtalk.google.com/127.0.0.1#5335 +ipset=/alt3-mtalk.google.com/gfwlist +server=/hentai69.online/127.0.0.1#5335 +ipset=/hentai69.online/gfwlist +server=/metacloud.com/127.0.0.1#5335 +ipset=/metacloud.com/gfwlist +server=/weav.xyz/127.0.0.1#5335 +ipset=/weav.xyz/gfwlist +server=/facebooklogs.com/127.0.0.1#5335 +ipset=/facebooklogs.com/gfwlist +server=/uun82.com/127.0.0.1#5335 +ipset=/uun82.com/gfwlist +server=/audio-ak-spotify-com.akamaized.net/127.0.0.1#5335 +ipset=/audio-ak-spotify-com.akamaized.net/gfwlist +server=/xn--xsq605n.com/127.0.0.1#5335 +ipset=/xn--xsq605n.com/gfwlist +server=/beatsboxingdayuksale.com/127.0.0.1#5335 +ipset=/beatsboxingdayuksale.com/gfwlist +server=/apple.lk/127.0.0.1#5335 +ipset=/apple.lk/gfwlist +server=/vmwhorizonair.com/127.0.0.1#5335 +ipset=/vmwhorizonair.com/gfwlist +server=/akamaisingapore.net/127.0.0.1#5335 +ipset=/akamaisingapore.net/gfwlist +server=/sukebei.nyaa.si/127.0.0.1#5335 +ipset=/sukebei.nyaa.si/gfwlist +server=/youtube.ni/127.0.0.1#5335 +ipset=/youtube.ni/gfwlist +server=/femdomcc.net/127.0.0.1#5335 +ipset=/femdomcc.net/gfwlist +server=/abc-studios.com/127.0.0.1#5335 +ipset=/abc-studios.com/gfwlist +server=/cheapbeatsbydreoutlet.com/127.0.0.1#5335 +ipset=/cheapbeatsbydreoutlet.com/gfwlist +server=/nvidia.jp/127.0.0.1#5335 +ipset=/nvidia.jp/gfwlist +server=/nvidia.com.pl/127.0.0.1#5335 +ipset=/nvidia.com.pl/gfwlist +server=/travelex.com.au/127.0.0.1#5335 +ipset=/travelex.com.au/gfwlist +server=/gnews.org/127.0.0.1#5335 +ipset=/gnews.org/gfwlist +server=/eboobstore.com/127.0.0.1#5335 +ipset=/eboobstore.com/gfwlist +server=/vanish.com.br/127.0.0.1#5335 +ipset=/vanish.com.br/gfwlist +server=/swiftbank.us/127.0.0.1#5335 +ipset=/swiftbank.us/gfwlist +server=/naver.jp/127.0.0.1#5335 +ipset=/naver.jp/gfwlist +server=/google.se/127.0.0.1#5335 +ipset=/google.se/gfwlist +server=/dawngate.com/127.0.0.1#5335 +ipset=/dawngate.com/gfwlist +server=/icloud.de/127.0.0.1#5335 +ipset=/icloud.de/gfwlist +server=/mini.be/127.0.0.1#5335 +ipset=/mini.be/gfwlist +server=/illusionn4.com/127.0.0.1#5335 +ipset=/illusionn4.com/gfwlist +server=/pornmd.com/127.0.0.1#5335 +ipset=/pornmd.com/gfwlist +server=/stufferdb.com/127.0.0.1#5335 +ipset=/stufferdb.com/gfwlist +server=/ebaybank.com/127.0.0.1#5335 +ipset=/ebaybank.com/gfwlist +server=/porn-list.site/127.0.0.1#5335 +ipset=/porn-list.site/gfwlist +server=/foxbusiness.tv/127.0.0.1#5335 +ipset=/foxbusiness.tv/gfwlist +server=/quickiepage.com/127.0.0.1#5335 +ipset=/quickiepage.com/gfwlist +server=/gettyimages.co.nz/127.0.0.1#5335 +ipset=/gettyimages.co.nz/gfwlist +server=/doujin-freee.com/127.0.0.1#5335 +ipset=/doujin-freee.com/gfwlist +server=/illusionn5.com/127.0.0.1#5335 +ipset=/illusionn5.com/gfwlist +server=/sankei-ad-info.com/127.0.0.1#5335 +ipset=/sankei-ad-info.com/gfwlist +server=/applelink.com/127.0.0.1#5335 +ipset=/applelink.com/gfwlist +server=/nyahentai.re/127.0.0.1#5335 +ipset=/nyahentai.re/gfwlist +server=/youtube.co.ug/127.0.0.1#5335 +ipset=/youtube.co.ug/gfwlist +server=/youtube.pt/127.0.0.1#5335 +ipset=/youtube.pt/gfwlist +server=/nikebetterworld.info/127.0.0.1#5335 +ipset=/nikebetterworld.info/gfwlist +server=/bmwmontreal.ca/127.0.0.1#5335 +ipset=/bmwmontreal.ca/gfwlist +server=/dollarphotoclub.com/127.0.0.1#5335 +ipset=/dollarphotoclub.com/gfwlist +server=/jenkins.io/127.0.0.1#5335 +ipset=/jenkins.io/gfwlist +server=/volvotruckcenter.kz/127.0.0.1#5335 +ipset=/volvotruckcenter.kz/gfwlist +server=/bestbuybusinessadvantageaccount.com/127.0.0.1#5335 +ipset=/bestbuybusinessadvantageaccount.com/gfwlist +server=/lineshoppingseller.com/127.0.0.1#5335 +ipset=/lineshoppingseller.com/gfwlist +server=/kumo.com/127.0.0.1#5335 +ipset=/kumo.com/gfwlist +server=/visacards.com/127.0.0.1#5335 +ipset=/visacards.com/gfwlist +server=/nab.demdex.net/127.0.0.1#5335 +ipset=/nab.demdex.net/gfwlist +server=/jibemobile.com/127.0.0.1#5335 +ipset=/jibemobile.com/gfwlist +server=/wheelworks.net/127.0.0.1#5335 +ipset=/wheelworks.net/gfwlist +server=/businessinsider.jp/127.0.0.1#5335 +ipset=/businessinsider.jp/gfwlist +server=/boxofficemojo.com/127.0.0.1#5335 +ipset=/boxofficemojo.com/gfwlist +server=/m2m.com/127.0.0.1#5335 +ipset=/m2m.com/gfwlist +server=/lightbridge.com/127.0.0.1#5335 +ipset=/lightbridge.com/gfwlist +server=/momsexypics.com/127.0.0.1#5335 +ipset=/momsexypics.com/gfwlist +server=/fury.co/127.0.0.1#5335 +ipset=/fury.co/gfwlist +server=/topchats.com/127.0.0.1#5335 +ipset=/topchats.com/gfwlist +server=/xl-gaytube.com/127.0.0.1#5335 +ipset=/xl-gaytube.com/gfwlist +server=/szcheapmonsterheadphones.com/127.0.0.1#5335 +ipset=/szcheapmonsterheadphones.com/gfwlist +server=/visa.com.py/127.0.0.1#5335 +ipset=/visa.com.py/gfwlist +server=/dettol.com.hk/127.0.0.1#5335 +ipset=/dettol.com.hk/gfwlist +server=/dettolsitishield.co.in/127.0.0.1#5335 +ipset=/dettolsitishield.co.in/gfwlist +server=/hightopnikes.com/127.0.0.1#5335 +ipset=/hightopnikes.com/gfwlist +server=/ebay-delivery.com/127.0.0.1#5335 +ipset=/ebay-delivery.com/gfwlist +server=/bmw-motorrad.com.py/127.0.0.1#5335 +ipset=/bmw-motorrad.com.py/gfwlist +server=/bmw.vn/127.0.0.1#5335 +ipset=/bmw.vn/gfwlist +server=/hellokittybeats.com/127.0.0.1#5335 +ipset=/hellokittybeats.com/gfwlist +server=/apple.dk/127.0.0.1#5335 +ipset=/apple.dk/gfwlist +server=/topexhib.net/127.0.0.1#5335 +ipset=/topexhib.net/gfwlist +server=/hentaiera.com/127.0.0.1#5335 +ipset=/hentaiera.com/gfwlist +server=/svensksexfilm.com/127.0.0.1#5335 +ipset=/svensksexfilm.com/gfwlist +server=/citizenlab.ca/127.0.0.1#5335 +ipset=/citizenlab.ca/gfwlist +server=/pornacho.com/127.0.0.1#5335 +ipset=/pornacho.com/gfwlist +server=/doujinfree.com/127.0.0.1#5335 +ipset=/doujinfree.com/gfwlist +server=/xn--gogl-0nd52e.com/127.0.0.1#5335 +ipset=/xn--gogl-0nd52e.com/gfwlist +server=/ceicdata.com/127.0.0.1#5335 +ipset=/ceicdata.com/gfwlist +server=/thomsonreuters.cn/127.0.0.1#5335 +ipset=/thomsonreuters.cn/gfwlist +server=/lesboerotica.net/127.0.0.1#5335 +ipset=/lesboerotica.net/gfwlist +server=/youtube.sv/127.0.0.1#5335 +ipset=/youtube.sv/gfwlist +server=/pakistanporntube.net/127.0.0.1#5335 +ipset=/pakistanporntube.net/gfwlist +server=/alhs.link/127.0.0.1#5335 +ipset=/alhs.link/gfwlist +server=/ignites.com/127.0.0.1#5335 +ipset=/ignites.com/gfwlist +server=/ikea.ph/127.0.0.1#5335 +ipset=/ikea.ph/gfwlist +server=/duckduckgo.ca/127.0.0.1#5335 +ipset=/duckduckgo.ca/gfwlist +server=/xvideos.com/127.0.0.1#5335 +ipset=/xvideos.com/gfwlist +server=/youtube.bg/127.0.0.1#5335 +ipset=/youtube.bg/gfwlist +server=/getadblock.com/127.0.0.1#5335 +ipset=/getadblock.com/gfwlist +server=/hentai.pro/127.0.0.1#5335 +ipset=/hentai.pro/gfwlist +server=/bmw-corporate-sales.com/127.0.0.1#5335 +ipset=/bmw-corporate-sales.com/gfwlist +server=/amateursecrets.net/127.0.0.1#5335 +ipset=/amateursecrets.net/gfwlist +server=/shopfacebook.com/127.0.0.1#5335 +ipset=/shopfacebook.com/gfwlist +server=/mypornbookmarks.com/127.0.0.1#5335 +ipset=/mypornbookmarks.com/gfwlist +server=/bigboobsalert.com/127.0.0.1#5335 +ipset=/bigboobsalert.com/gfwlist +server=/nudeandhairy.com/127.0.0.1#5335 +ipset=/nudeandhairy.com/gfwlist +server=/githubpreview.dev/127.0.0.1#5335 +ipset=/githubpreview.dev/gfwlist +server=/pornopantry.com/127.0.0.1#5335 +ipset=/pornopantry.com/gfwlist +server=/baselinestudy.com/127.0.0.1#5335 +ipset=/baselinestudy.com/gfwlist +server=/braventures.com/127.0.0.1#5335 +ipset=/braventures.com/gfwlist +server=/disney.ru/127.0.0.1#5335 +ipset=/disney.ru/gfwlist +server=/xxvideoss.org/127.0.0.1#5335 +ipset=/xxvideoss.org/gfwlist +server=/conan.xxx/127.0.0.1#5335 +ipset=/conan.xxx/gfwlist +server=/findmyipad.com/127.0.0.1#5335 +ipset=/findmyipad.com/gfwlist +server=/flickr.com/127.0.0.1#5335 +ipset=/flickr.com/gfwlist +server=/ipod.co.za/127.0.0.1#5335 +ipset=/ipod.co.za/gfwlist +server=/iwantmature.com/127.0.0.1#5335 +ipset=/iwantmature.com/gfwlist +server=/hclips.com/127.0.0.1#5335 +ipset=/hclips.com/gfwlist +server=/macosxlion.com/127.0.0.1#5335 +ipset=/macosxlion.com/gfwlist +server=/dartpad.dev/127.0.0.1#5335 +ipset=/dartpad.dev/gfwlist +server=/applewatchsport.com/127.0.0.1#5335 +ipset=/applewatchsport.com/gfwlist +server=/wifesharingpics.com/127.0.0.1#5335 +ipset=/wifesharingpics.com/gfwlist +server=/google.com.np/127.0.0.1#5335 +ipset=/google.com.np/gfwlist +server=/googil.com/127.0.0.1#5335 +ipset=/googil.com/gfwlist +server=/cloudinary.com/127.0.0.1#5335 +ipset=/cloudinary.com/gfwlist +server=/canon.nl/127.0.0.1#5335 +ipset=/canon.nl/gfwlist +server=/blogspot.com.by/127.0.0.1#5335 +ipset=/blogspot.com.by/gfwlist +server=/tesla-cdn.thron.com/127.0.0.1#5335 +ipset=/tesla-cdn.thron.com/gfwlist +server=/braintreegateway.com/127.0.0.1#5335 +ipset=/braintreegateway.com/gfwlist +server=/zoopornmd.com/127.0.0.1#5335 +ipset=/zoopornmd.com/gfwlist +server=/fuckmatureporn.com/127.0.0.1#5335 +ipset=/fuckmatureporn.com/gfwlist +server=/llnw-trials.com/127.0.0.1#5335 +ipset=/llnw-trials.com/gfwlist +server=/amdfanstore.com/127.0.0.1#5335 +ipset=/amdfanstore.com/gfwlist +server=/beatsbydressolo.com/127.0.0.1#5335 +ipset=/beatsbydressolo.com/gfwlist +server=/rarbgaccess.org/127.0.0.1#5335 +ipset=/rarbgaccess.org/gfwlist +server=/drebeatscanada.com/127.0.0.1#5335 +ipset=/drebeatscanada.com/gfwlist +server=/nflximg.com/127.0.0.1#5335 +ipset=/nflximg.com/gfwlist +server=/wholesalediscountpurses.com/127.0.0.1#5335 +ipset=/wholesalediscountpurses.com/gfwlist +server=/wvm0agb4.me/127.0.0.1#5335 +ipset=/wvm0agb4.me/gfwlist +server=/debian.org/127.0.0.1#5335 +ipset=/debian.org/gfwlist +server=/idol-sagasukun.com/127.0.0.1#5335 +ipset=/idol-sagasukun.com/gfwlist +server=/scpdb.org/127.0.0.1#5335 +ipset=/scpdb.org/gfwlist +server=/india.com/127.0.0.1#5335 +ipset=/india.com/gfwlist +server=/vanish.com.mx/127.0.0.1#5335 +ipset=/vanish.com.mx/gfwlist +server=/page3.com/127.0.0.1#5335 +ipset=/page3.com/gfwlist +server=/signalprocessingsociety.org/127.0.0.1#5335 +ipset=/signalprocessingsociety.org/gfwlist +server=/bmwgroupdirect.com/127.0.0.1#5335 +ipset=/bmwgroupdirect.com/gfwlist +server=/avcrempie.com/127.0.0.1#5335 +ipset=/avcrempie.com/gfwlist +server=/movefreeoffers.com/127.0.0.1#5335 +ipset=/movefreeoffers.com/gfwlist +server=/pearsonclinical.ca/127.0.0.1#5335 +ipset=/pearsonclinical.ca/gfwlist +server=/google.fr/127.0.0.1#5335 +ipset=/google.fr/gfwlist +server=/foxnewschannel.com/127.0.0.1#5335 +ipset=/foxnewschannel.com/gfwlist +server=/touhouwiki.net/127.0.0.1#5335 +ipset=/touhouwiki.net/gfwlist +server=/youtube.it/127.0.0.1#5335 +ipset=/youtube.it/gfwlist +server=/1lib.education/127.0.0.1#5335 +ipset=/1lib.education/gfwlist +server=/forbiddenmomsarchive.com/127.0.0.1#5335 +ipset=/forbiddenmomsarchive.com/gfwlist +server=/animalincum.com/127.0.0.1#5335 +ipset=/animalincum.com/gfwlist +server=/alphabet.pl/127.0.0.1#5335 +ipset=/alphabet.pl/gfwlist +server=/alteraforums.com/127.0.0.1#5335 +ipset=/alteraforums.com/gfwlist +server=/xxxstreams.org/127.0.0.1#5335 +ipset=/xxxstreams.org/gfwlist +server=/imgix.com/127.0.0.1#5335 +ipset=/imgix.com/gfwlist +server=/mini-connected.se/127.0.0.1#5335 +ipset=/mini-connected.se/gfwlist +server=/chubbypornonly.com/127.0.0.1#5335 +ipset=/chubbypornonly.com/gfwlist +server=/radeon.com/127.0.0.1#5335 +ipset=/radeon.com/gfwlist +server=/hplaptopbattery.com/127.0.0.1#5335 +ipset=/hplaptopbattery.com/gfwlist +server=/google.fm/127.0.0.1#5335 +ipset=/google.fm/gfwlist +server=/hqseek.com/127.0.0.1#5335 +ipset=/hqseek.com/gfwlist +server=/zeetv.com/127.0.0.1#5335 +ipset=/zeetv.com/gfwlist +server=/shadowcomplex.com/127.0.0.1#5335 +ipset=/shadowcomplex.com/gfwlist +server=/get.rsvp/127.0.0.1#5335 +ipset=/get.rsvp/gfwlist +server=/maturesinhd.com/127.0.0.1#5335 +ipset=/maturesinhd.com/gfwlist +server=/cheapbeats365.com/127.0.0.1#5335 +ipset=/cheapbeats365.com/gfwlist +server=/svc.ms/127.0.0.1#5335 +ipset=/svc.ms/gfwlist +server=/asextube.net/127.0.0.1#5335 +ipset=/asextube.net/gfwlist +server=/intel.hu/127.0.0.1#5335 +ipset=/intel.hu/gfwlist +server=/directvcincinnatioh.com/127.0.0.1#5335 +ipset=/directvcincinnatioh.com/gfwlist +server=/starbucks.ca/127.0.0.1#5335 +ipset=/starbucks.ca/gfwlist +server=/muryouav.net/127.0.0.1#5335 +ipset=/muryouav.net/gfwlist +server=/directvcrossvilletn.com/127.0.0.1#5335 +ipset=/directvcrossvilletn.com/gfwlist +server=/msft.net/127.0.0.1#5335 +ipset=/msft.net/gfwlist +server=/teensloveanal.com/127.0.0.1#5335 +ipset=/teensloveanal.com/gfwlist +server=/beats1.tv/127.0.0.1#5335 +ipset=/beats1.tv/gfwlist +server=/apple-pay.wang/127.0.0.1#5335 +ipset=/apple-pay.wang/gfwlist +server=/ocsp.microsoft.com/127.0.0.1#5335 +ipset=/ocsp.microsoft.com/gfwlist +server=/atttvnow.com/127.0.0.1#5335 +ipset=/atttvnow.com/gfwlist +server=/milofetch.com/127.0.0.1#5335 +ipset=/milofetch.com/gfwlist +server=/telegram-cdn.org/127.0.0.1#5335 +ipset=/telegram-cdn.org/gfwlist +server=/researchkit.hk/127.0.0.1#5335 +ipset=/researchkit.hk/gfwlist +server=/airport.eu/127.0.0.1#5335 +ipset=/airport.eu/gfwlist +server=/ieeer10.org/127.0.0.1#5335 +ipset=/ieeer10.org/gfwlist +server=/paramountplus.com/127.0.0.1#5335 +ipset=/paramountplus.com/gfwlist +server=/nuget.org/127.0.0.1#5335 +ipset=/nuget.org/gfwlist +server=/bbcpersian.com/127.0.0.1#5335 +ipset=/bbcpersian.com/gfwlist +server=/idvd.eu/127.0.0.1#5335 +ipset=/idvd.eu/gfwlist +server=/garena.co.th/127.0.0.1#5335 +ipset=/garena.co.th/gfwlist +server=/scholar.google.dk/127.0.0.1#5335 +ipset=/scholar.google.dk/gfwlist +server=/1lib.eu/127.0.0.1#5335 +ipset=/1lib.eu/gfwlist +server=/intel.ly/127.0.0.1#5335 +ipset=/intel.ly/gfwlist +server=/ohyeah1080.com/127.0.0.1#5335 +ipset=/ohyeah1080.com/gfwlist +server=/xxxpornmovs.com/127.0.0.1#5335 +ipset=/xxxpornmovs.com/gfwlist +server=/czechwifeswap.com/127.0.0.1#5335 +ipset=/czechwifeswap.com/gfwlist +server=/facebookmanager.info/127.0.0.1#5335 +ipset=/facebookmanager.info/gfwlist +server=/siska.video/127.0.0.1#5335 +ipset=/siska.video/gfwlist +server=/4tubefree.net/127.0.0.1#5335 +ipset=/4tubefree.net/gfwlist +server=/97dounai.top/127.0.0.1#5335 +ipset=/97dounai.top/gfwlist +server=/wmt.co/127.0.0.1#5335 +ipset=/wmt.co/gfwlist +server=/attic.io/127.0.0.1#5335 +ipset=/attic.io/gfwlist +server=/drmario-world.com/127.0.0.1#5335 +ipset=/drmario-world.com/gfwlist +server=/zingtruyen.net/127.0.0.1#5335 +ipset=/zingtruyen.net/gfwlist +server=/dctbeatsbydre.com/127.0.0.1#5335 +ipset=/dctbeatsbydre.com/gfwlist +server=/smm99999.com/127.0.0.1#5335 +ipset=/smm99999.com/gfwlist +server=/anonproxy.info/127.0.0.1#5335 +ipset=/anonproxy.info/gfwlist +server=/shopify.com/127.0.0.1#5335 +ipset=/shopify.com/gfwlist +server=/zndsk.com/127.0.0.1#5335 +ipset=/zndsk.com/gfwlist +server=/kingstagram.com/127.0.0.1#5335 +ipset=/kingstagram.com/gfwlist +server=/metaporn.com/127.0.0.1#5335 +ipset=/metaporn.com/gfwlist +server=/mini.ch/127.0.0.1#5335 +ipset=/mini.ch/gfwlist +server=/buyitnow.net/127.0.0.1#5335 +ipset=/buyitnow.net/gfwlist +server=/newsexwap.com/127.0.0.1#5335 +ipset=/newsexwap.com/gfwlist +server=/blogspot.nl/127.0.0.1#5335 +ipset=/blogspot.nl/gfwlist +server=/canon.co.za/127.0.0.1#5335 +ipset=/canon.co.za/gfwlist +server=/aesworkshops.com/127.0.0.1#5335 +ipset=/aesworkshops.com/gfwlist +server=/danemarket.com/127.0.0.1#5335 +ipset=/danemarket.com/gfwlist +server=/bmw-world.net/127.0.0.1#5335 +ipset=/bmw-world.net/gfwlist +server=/pornobrasileiro.tv/127.0.0.1#5335 +ipset=/pornobrasileiro.tv/gfwlist +server=/tabustudios.co/127.0.0.1#5335 +ipset=/tabustudios.co/gfwlist +server=/attproxy.com/127.0.0.1#5335 +ipset=/attproxy.com/gfwlist +server=/hayabusa.dev/127.0.0.1#5335 +ipset=/hayabusa.dev/gfwlist +server=/yahoo-news.com.hk/127.0.0.1#5335 +ipset=/yahoo-news.com.hk/gfwlist +server=/hotwifemovies.com/127.0.0.1#5335 +ipset=/hotwifemovies.com/gfwlist +server=/v2ex.com/127.0.0.1#5335 +ipset=/v2ex.com/gfwlist +server=/ikea.hr/127.0.0.1#5335 +ipset=/ikea.hr/gfwlist +server=/hk01.com/127.0.0.1#5335 +ipset=/hk01.com/gfwlist +server=/boy18tube.com/127.0.0.1#5335 +ipset=/boy18tube.com/gfwlist +server=/google.com.ua/127.0.0.1#5335 +ipset=/google.com.ua/gfwlist +server=/hrsaz.com/127.0.0.1#5335 +ipset=/hrsaz.com/gfwlist +server=/boodigogo.com/127.0.0.1#5335 +ipset=/boodigogo.com/gfwlist +server=/fsacebok.com/127.0.0.1#5335 +ipset=/fsacebok.com/gfwlist +server=/beats-bydrecheapsale.com/127.0.0.1#5335 +ipset=/beats-bydrecheapsale.com/gfwlist +server=/alt8-mtalk.google.com/127.0.0.1#5335 +ipset=/alt8-mtalk.google.com/gfwlist +server=/facebookpay.com/127.0.0.1#5335 +ipset=/facebookpay.com/gfwlist +server=/pearson.ch/127.0.0.1#5335 +ipset=/pearson.ch/gfwlist +server=/intel.ma/127.0.0.1#5335 +ipset=/intel.ma/gfwlist +server=/canon.ua/127.0.0.1#5335 +ipset=/canon.ua/gfwlist +server=/usaco.org/127.0.0.1#5335 +ipset=/usaco.org/gfwlist +server=/scopus.com/127.0.0.1#5335 +ipset=/scopus.com/gfwlist +server=/mortein.co.in/127.0.0.1#5335 +ipset=/mortein.co.in/gfwlist +server=/savitahd.net/127.0.0.1#5335 +ipset=/savitahd.net/gfwlist +server=/5i01.com/127.0.0.1#5335 +ipset=/5i01.com/gfwlist +server=/facebookemail.com/127.0.0.1#5335 +ipset=/facebookemail.com/gfwlist +server=/faproulette.co/127.0.0.1#5335 +ipset=/faproulette.co/gfwlist +server=/bmw-voli.me/127.0.0.1#5335 +ipset=/bmw-voli.me/gfwlist +server=/pearson.com.hk/127.0.0.1#5335 +ipset=/pearson.com.hk/gfwlist +server=/webex.de/127.0.0.1#5335 +ipset=/webex.de/gfwlist +server=/men.com/127.0.0.1#5335 +ipset=/men.com/gfwlist +server=/skypeassets.net/127.0.0.1#5335 +ipset=/skypeassets.net/gfwlist +server=/xxxfree.watch/127.0.0.1#5335 +ipset=/xxxfree.watch/gfwlist +server=/verisign.co.in/127.0.0.1#5335 +ipset=/verisign.co.in/gfwlist +server=/alphera.co.nz/127.0.0.1#5335 +ipset=/alphera.co.nz/gfwlist +server=/stateofthemap.org/127.0.0.1#5335 +ipset=/stateofthemap.org/gfwlist +server=/mobileporngames.com/127.0.0.1#5335 +ipset=/mobileporngames.com/gfwlist +server=/strip-poker.xxx/127.0.0.1#5335 +ipset=/strip-poker.xxx/gfwlist +server=/tytporno.online/127.0.0.1#5335 +ipset=/tytporno.online/gfwlist +server=/bestbuycharityclassic.com/127.0.0.1#5335 +ipset=/bestbuycharityclassic.com/gfwlist +server=/scholar.google.li/127.0.0.1#5335 +ipset=/scholar.google.li/gfwlist +server=/unwire.hk/127.0.0.1#5335 +ipset=/unwire.hk/gfwlist +server=/google.sr/127.0.0.1#5335 +ipset=/google.sr/gfwlist +server=/kubeacademy.com/127.0.0.1#5335 +ipset=/kubeacademy.com/gfwlist +server=/e-bay.it/127.0.0.1#5335 +ipset=/e-bay.it/gfwlist +server=/fontawesome.com/127.0.0.1#5335 +ipset=/fontawesome.com/gfwlist +server=/soundofhope.kr/127.0.0.1#5335 +ipset=/soundofhope.kr/gfwlist +server=/globalriskregulator.com/127.0.0.1#5335 +ipset=/globalriskregulator.com/gfwlist +server=/paofuyun.me/127.0.0.1#5335 +ipset=/paofuyun.me/gfwlist +server=/pornoisy.com/127.0.0.1#5335 +ipset=/pornoisy.com/gfwlist +server=/calgon.ch/127.0.0.1#5335 +ipset=/calgon.ch/gfwlist +server=/xxxporndig.com/127.0.0.1#5335 +ipset=/xxxporndig.com/gfwlist +server=/v2fly.org/127.0.0.1#5335 +ipset=/v2fly.org/gfwlist +server=/ipad.co.kr/127.0.0.1#5335 +ipset=/ipad.co.kr/gfwlist +server=/udn.com/127.0.0.1#5335 +ipset=/udn.com/gfwlist +server=/ikea.com.pt/127.0.0.1#5335 +ipset=/ikea.com.pt/gfwlist +server=/minirichmond.ca/127.0.0.1#5335 +ipset=/minirichmond.ca/gfwlist +server=/fxnetworks.com/127.0.0.1#5335 +ipset=/fxnetworks.com/gfwlist +server=/beatsbydreoutletsale.com/127.0.0.1#5335 +ipset=/beatsbydreoutletsale.com/gfwlist +server=/virsto.net/127.0.0.1#5335 +ipset=/virsto.net/gfwlist +server=/gayapatal.com/127.0.0.1#5335 +ipset=/gayapatal.com/gfwlist +server=/facebooktv.org/127.0.0.1#5335 +ipset=/facebooktv.org/gfwlist +server=/beatsbydrecolors.com/127.0.0.1#5335 +ipset=/beatsbydrecolors.com/gfwlist +server=/adultgames.me/127.0.0.1#5335 +ipset=/adultgames.me/gfwlist +server=/zoo-xvideo.com/127.0.0.1#5335 +ipset=/zoo-xvideo.com/gfwlist +server=/nextwork.hk/127.0.0.1#5335 +ipset=/nextwork.hk/gfwlist +server=/applestore.de/127.0.0.1#5335 +ipset=/applestore.de/gfwlist +server=/azurecomm.net/127.0.0.1#5335 +ipset=/azurecomm.net/gfwlist +server=/adult3dfantasycomics.com/127.0.0.1#5335 +ipset=/adult3dfantasycomics.com/gfwlist +server=/directvbundles.com/127.0.0.1#5335 +ipset=/directvbundles.com/gfwlist +server=/iijav.com/127.0.0.1#5335 +ipset=/iijav.com/gfwlist +server=/serialssolutions.com/127.0.0.1#5335 +ipset=/serialssolutions.com/gfwlist +server=/salecheaphandbags.com/127.0.0.1#5335 +ipset=/salecheaphandbags.com/gfwlist +server=/vixvids.to/127.0.0.1#5335 +ipset=/vixvids.to/gfwlist +server=/geeksquadcentral.com/127.0.0.1#5335 +ipset=/geeksquadcentral.com/gfwlist +server=/myhpsupport.com/127.0.0.1#5335 +ipset=/myhpsupport.com/gfwlist +server=/vipoo.es/127.0.0.1#5335 +ipset=/vipoo.es/gfwlist +server=/xn--uis17aj9kmuf.com/127.0.0.1#5335 +ipset=/xn--uis17aj9kmuf.com/gfwlist +server=/buycheapbeatsbus.com/127.0.0.1#5335 +ipset=/buycheapbeatsbus.com/gfwlist +server=/bmw-golfsport.com/127.0.0.1#5335 +ipset=/bmw-golfsport.com/gfwlist +server=/hbo.com.edgesuite.net/127.0.0.1#5335 +ipset=/hbo.com.edgesuite.net/gfwlist +server=/giratina.com/127.0.0.1#5335 +ipset=/giratina.com/gfwlist +server=/honawalaan.com/127.0.0.1#5335 +ipset=/honawalaan.com/gfwlist +server=/thottok.com/127.0.0.1#5335 +ipset=/thottok.com/gfwlist +server=/durexusa.com/127.0.0.1#5335 +ipset=/durexusa.com/gfwlist +server=/nikecdn.com/127.0.0.1#5335 +ipset=/nikecdn.com/gfwlist +server=/sciencedirectassets.com/127.0.0.1#5335 +ipset=/sciencedirectassets.com/gfwlist +server=/minibrossard.com/127.0.0.1#5335 +ipset=/minibrossard.com/gfwlist +server=/paypal-online.org/127.0.0.1#5335 +ipset=/paypal-online.org/gfwlist +server=/awseducate.net/127.0.0.1#5335 +ipset=/awseducate.net/gfwlist +server=/kirbysuperstarultra.com/127.0.0.1#5335 +ipset=/kirbysuperstarultra.com/gfwlist +server=/disney.ph/127.0.0.1#5335 +ipset=/disney.ph/gfwlist +server=/youtube.bh/127.0.0.1#5335 +ipset=/youtube.bh/gfwlist +server=/globalsign.com.sg/127.0.0.1#5335 +ipset=/globalsign.com.sg/gfwlist +server=/flipnotestudio.com/127.0.0.1#5335 +ipset=/flipnotestudio.com/gfwlist +server=/amazon.in/127.0.0.1#5335 +ipset=/amazon.in/gfwlist +server=/paypal-scoop.com/127.0.0.1#5335 +ipset=/paypal-scoop.com/gfwlist +server=/vs-cmaf-pushb-ww-live.akamaized.net/127.0.0.1#5335 +ipset=/vs-cmaf-pushb-ww-live.akamaized.net/gfwlist +server=/youngpornvideos.com/127.0.0.1#5335 +ipset=/youngpornvideos.com/gfwlist +server=/yandex.co.il/127.0.0.1#5335 +ipset=/yandex.co.il/gfwlist +server=/sexyseeker.com/127.0.0.1#5335 +ipset=/sexyseeker.com/gfwlist +server=/ggjav.com/127.0.0.1#5335 +ipset=/ggjav.com/gfwlist +server=/beatsbydreforyououtlet.com/127.0.0.1#5335 +ipset=/beatsbydreforyououtlet.com/gfwlist +server=/follasian.com/127.0.0.1#5335 +ipset=/follasian.com/gfwlist +server=/adultdvdmarketplace.com/127.0.0.1#5335 +ipset=/adultdvdmarketplace.com/gfwlist +server=/xxxmofo.com/127.0.0.1#5335 +ipset=/xxxmofo.com/gfwlist +server=/gitstar.com/127.0.0.1#5335 +ipset=/gitstar.com/gfwlist +server=/pixtronix.com/127.0.0.1#5335 +ipset=/pixtronix.com/gfwlist +server=/redfaptube.com/127.0.0.1#5335 +ipset=/redfaptube.com/gfwlist +server=/danskpornofilm.com/127.0.0.1#5335 +ipset=/danskpornofilm.com/gfwlist +server=/smutty.com/127.0.0.1#5335 +ipset=/smutty.com/gfwlist +server=/talksport.com/127.0.0.1#5335 +ipset=/talksport.com/gfwlist +server=/latintubeporn.com/127.0.0.1#5335 +ipset=/latintubeporn.com/gfwlist +server=/analhomeporn.com/127.0.0.1#5335 +ipset=/analhomeporn.com/gfwlist +server=/coedcherry.com/127.0.0.1#5335 +ipset=/coedcherry.com/gfwlist +server=/javbraze.com/127.0.0.1#5335 +ipset=/javbraze.com/gfwlist +server=/brazzer.com/127.0.0.1#5335 +ipset=/brazzer.com/gfwlist +server=/apple.co.hu/127.0.0.1#5335 +ipset=/apple.co.hu/gfwlist +server=/hkbn.com.hk/127.0.0.1#5335 +ipset=/hkbn.com.hk/gfwlist +server=/iphone-vip1.com/127.0.0.1#5335 +ipset=/iphone-vip1.com/gfwlist +server=/vmware.com/127.0.0.1#5335 +ipset=/vmware.com/gfwlist +server=/ypmate.com/127.0.0.1#5335 +ipset=/ypmate.com/gfwlist +server=/duck.co/127.0.0.1#5335 +ipset=/duck.co/gfwlist +server=/bmw.ca/127.0.0.1#5335 +ipset=/bmw.ca/gfwlist +server=/researchkit.org/127.0.0.1#5335 +ipset=/researchkit.org/gfwlist +server=/cloudlive.com/127.0.0.1#5335 +ipset=/cloudlive.com/gfwlist +server=/sexygloz.com/127.0.0.1#5335 +ipset=/sexygloz.com/gfwlist +server=/ciscoknowledgenetwork.com/127.0.0.1#5335 +ipset=/ciscoknowledgenetwork.com/gfwlist +server=/pdncommunity.com/127.0.0.1#5335 +ipset=/pdncommunity.com/gfwlist +server=/yahoo.ph/127.0.0.1#5335 +ipset=/yahoo.ph/gfwlist +server=/needforspeedtimeattack.com/127.0.0.1#5335 +ipset=/needforspeedtimeattack.com/gfwlist +server=/worldemojiday.com/127.0.0.1#5335 +ipset=/worldemojiday.com/gfwlist +server=/beatsfactoroutlets.com/127.0.0.1#5335 +ipset=/beatsfactoroutlets.com/gfwlist +server=/manhwahentai.me/127.0.0.1#5335 +ipset=/manhwahentai.me/gfwlist +server=/nike.com.hk/127.0.0.1#5335 +ipset=/nike.com.hk/gfwlist +server=/spotifycdn.com/127.0.0.1#5335 +ipset=/spotifycdn.com/gfwlist +server=/scholar.google.com.eg/127.0.0.1#5335 +ipset=/scholar.google.com.eg/gfwlist +server=/title.sh/127.0.0.1#5335 +ipset=/title.sh/gfwlist +server=/triokini.com/127.0.0.1#5335 +ipset=/triokini.com/gfwlist +server=/xxxyoungxxx.com/127.0.0.1#5335 +ipset=/xxxyoungxxx.com/gfwlist +server=/visasavingsedge.ca/127.0.0.1#5335 +ipset=/visasavingsedge.ca/gfwlist +server=/echocdn.com/127.0.0.1#5335 +ipset=/echocdn.com/gfwlist +server=/amateur-home-sex.com/127.0.0.1#5335 +ipset=/amateur-home-sex.com/gfwlist +server=/fixtracking.com/127.0.0.1#5335 +ipset=/fixtracking.com/gfwlist +server=/highwirepress.com/127.0.0.1#5335 +ipset=/highwirepress.com/gfwlist +server=/celebrityslips.com/127.0.0.1#5335 +ipset=/celebrityslips.com/gfwlist +server=/nurofen.co.uk/127.0.0.1#5335 +ipset=/nurofen.co.uk/gfwlist +server=/disney.es/127.0.0.1#5335 +ipset=/disney.es/gfwlist +server=/blogspot.ug/127.0.0.1#5335 +ipset=/blogspot.ug/gfwlist +server=/facebokk.com/127.0.0.1#5335 +ipset=/facebokk.com/gfwlist +server=/lezpoo.com/127.0.0.1#5335 +ipset=/lezpoo.com/gfwlist +server=/sportswomanoftheyear.co.uk/127.0.0.1#5335 +ipset=/sportswomanoftheyear.co.uk/gfwlist +server=/appbridge.io/127.0.0.1#5335 +ipset=/appbridge.io/gfwlist +server=/teamneedforspeed.com/127.0.0.1#5335 +ipset=/teamneedforspeed.com/gfwlist +server=/r-new-sale.blog.jp/127.0.0.1#5335 +ipset=/r-new-sale.blog.jp/gfwlist +server=/freehdinterracialporn.in/127.0.0.1#5335 +ipset=/freehdinterracialporn.in/gfwlist +server=/ffmpeg.org/127.0.0.1#5335 +ipset=/ffmpeg.org/gfwlist +server=/liveporngirls.com/127.0.0.1#5335 +ipset=/liveporngirls.com/gfwlist +server=/mirrorsedge2.com/127.0.0.1#5335 +ipset=/mirrorsedge2.com/gfwlist +server=/01.org/127.0.0.1#5335 +ipset=/01.org/gfwlist +server=/alphabetfinance.net/127.0.0.1#5335 +ipset=/alphabetfinance.net/gfwlist +server=/camrabbit.com/127.0.0.1#5335 +ipset=/camrabbit.com/gfwlist +server=/intel.nu/127.0.0.1#5335 +ipset=/intel.nu/gfwlist +server=/pornpaw.com/127.0.0.1#5335 +ipset=/pornpaw.com/gfwlist +server=/emac.co.in/127.0.0.1#5335 +ipset=/emac.co.in/gfwlist +server=/altmetric.com/127.0.0.1#5335 +ipset=/altmetric.com/gfwlist +server=/azure.microsoft.com/127.0.0.1#5335 +ipset=/azure.microsoft.com/gfwlist +server=/drebeatssolocybermondaysale.com/127.0.0.1#5335 +ipset=/drebeatssolocybermondaysale.com/gfwlist +server=/insiderdevtour.com/127.0.0.1#5335 +ipset=/insiderdevtour.com/gfwlist +server=/mastercard.ch/127.0.0.1#5335 +ipset=/mastercard.ch/gfwlist +server=/libgen.fun/127.0.0.1#5335 +ipset=/libgen.fun/gfwlist +server=/visa.com.ms/127.0.0.1#5335 +ipset=/visa.com.ms/gfwlist +server=/mucinex.cn/127.0.0.1#5335 +ipset=/mucinex.cn/gfwlist +server=/apple.xyz/127.0.0.1#5335 +ipset=/apple.xyz/gfwlist +server=/paypalnet.net/127.0.0.1#5335 +ipset=/paypalnet.net/gfwlist +server=/hentai.toys/127.0.0.1#5335 +ipset=/hentai.toys/gfwlist +server=/privatecasting-x.com/127.0.0.1#5335 +ipset=/privatecasting-x.com/gfwlist +server=/foxnewsplayer-a.akamaihd.net/127.0.0.1#5335 +ipset=/foxnewsplayer-a.akamaihd.net/gfwlist +server=/bellsouth.net/127.0.0.1#5335 +ipset=/bellsouth.net/gfwlist +server=/sgp1.fun/127.0.0.1#5335 +ipset=/sgp1.fun/gfwlist +server=/bellesa.co/127.0.0.1#5335 +ipset=/bellesa.co/gfwlist +server=/tropictube.com/127.0.0.1#5335 +ipset=/tropictube.com/gfwlist +server=/virsto.com/127.0.0.1#5335 +ipset=/virsto.com/gfwlist +server=/getboxer.com/127.0.0.1#5335 +ipset=/getboxer.com/gfwlist +server=/dirty.games/127.0.0.1#5335 +ipset=/dirty.games/gfwlist +server=/vfsco.nl/127.0.0.1#5335 +ipset=/vfsco.nl/gfwlist +server=/nudes7.com/127.0.0.1#5335 +ipset=/nudes7.com/gfwlist +server=/zeit-world.com/127.0.0.1#5335 +ipset=/zeit-world.com/gfwlist +server=/mixvintagesex.com/127.0.0.1#5335 +ipset=/mixvintagesex.com/gfwlist +server=/fansnudes.com/127.0.0.1#5335 +ipset=/fansnudes.com/gfwlist +server=/kijij.ca/127.0.0.1#5335 +ipset=/kijij.ca/gfwlist +server=/hotstar.com/127.0.0.1#5335 +ipset=/hotstar.com/gfwlist +server=/amateurs-fuck.com/127.0.0.1#5335 +ipset=/amateurs-fuck.com/gfwlist +server=/lin.ee/127.0.0.1#5335 +ipset=/lin.ee/gfwlist +server=/l-0005.dc-msedge.net/127.0.0.1#5335 +ipset=/l-0005.dc-msedge.net/gfwlist +server=/agag.tw/127.0.0.1#5335 +ipset=/agag.tw/gfwlist +server=/volvomerchandise.com/127.0.0.1#5335 +ipset=/volvomerchandise.com/gfwlist +server=/xmoviesforyou.com/127.0.0.1#5335 +ipset=/xmoviesforyou.com/gfwlist +server=/quora.com/127.0.0.1#5335 +ipset=/quora.com/gfwlist +server=/iop.org/127.0.0.1#5335 +ipset=/iop.org/gfwlist +server=/ebayvalet.com/127.0.0.1#5335 +ipset=/ebayvalet.com/gfwlist +server=/oculus3d.com/127.0.0.1#5335 +ipset=/oculus3d.com/gfwlist +server=/instagify.com/127.0.0.1#5335 +ipset=/instagify.com/gfwlist +server=/beatsbydreformall2013-nl.com/127.0.0.1#5335 +ipset=/beatsbydreformall2013-nl.com/gfwlist +server=/oyeloca.com/127.0.0.1#5335 +ipset=/oyeloca.com/gfwlist +server=/foofle.com/127.0.0.1#5335 +ipset=/foofle.com/gfwlist +server=/directvpomise.com/127.0.0.1#5335 +ipset=/directvpomise.com/gfwlist +server=/aliverewind.com/127.0.0.1#5335 +ipset=/aliverewind.com/gfwlist +server=/cbsi.video/127.0.0.1#5335 +ipset=/cbsi.video/gfwlist +server=/bmwmotorshowblog.com/127.0.0.1#5335 +ipset=/bmwmotorshowblog.com/gfwlist +server=/b-ok.org/127.0.0.1#5335 +ipset=/b-ok.org/gfwlist +server=/xsava.xyz/127.0.0.1#5335 +ipset=/xsava.xyz/gfwlist +server=/flow.org/127.0.0.1#5335 +ipset=/flow.org/gfwlist +server=/adultepic.com/127.0.0.1#5335 +ipset=/adultepic.com/gfwlist +server=/lysol.cl/127.0.0.1#5335 +ipset=/lysol.cl/gfwlist +server=/crr.com/127.0.0.1#5335 +ipset=/crr.com/gfwlist +server=/immidio.com/127.0.0.1#5335 +ipset=/immidio.com/gfwlist +server=/thomsonreuters.com/127.0.0.1#5335 +ipset=/thomsonreuters.com/gfwlist +server=/bigboobbundle.com/127.0.0.1#5335 +ipset=/bigboobbundle.com/gfwlist +server=/bmw.bs/127.0.0.1#5335 +ipset=/bmw.bs/gfwlist +server=/hentaihand.com/127.0.0.1#5335 +ipset=/hentaihand.com/gfwlist +server=/macbookair.com/127.0.0.1#5335 +ipset=/macbookair.com/gfwlist +server=/bloomberg.co.kr/127.0.0.1#5335 +ipset=/bloomberg.co.kr/gfwlist +server=/mrpornlive.com/127.0.0.1#5335 +ipset=/mrpornlive.com/gfwlist +server=/bigtitangelawhite.com/127.0.0.1#5335 +ipset=/bigtitangelawhite.com/gfwlist +server=/meridian.net/127.0.0.1#5335 +ipset=/meridian.net/gfwlist +server=/erome.it/127.0.0.1#5335 +ipset=/erome.it/gfwlist +server=/mediafiles-cisco.com/127.0.0.1#5335 +ipset=/mediafiles-cisco.com/gfwlist +server=/hentaibar.com/127.0.0.1#5335 +ipset=/hentaibar.com/gfwlist +server=/sb-telecom.net/127.0.0.1#5335 +ipset=/sb-telecom.net/gfwlist +server=/amiibo.com/127.0.0.1#5335 +ipset=/amiibo.com/gfwlist +server=/ikea.com.do/127.0.0.1#5335 +ipset=/ikea.com.do/gfwlist +server=/youtube.ph/127.0.0.1#5335 +ipset=/youtube.ph/gfwlist +server=/12diasderegalosdeitunes.com.co/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.com.co/gfwlist +server=/senzuritv.net/127.0.0.1#5335 +ipset=/senzuritv.net/gfwlist +server=/xn--gtvz22d.wang/127.0.0.1#5335 +ipset=/xn--gtvz22d.wang/gfwlist +server=/reabble.com/127.0.0.1#5335 +ipset=/reabble.com/gfwlist +server=/bdsm123.xyz/127.0.0.1#5335 +ipset=/bdsm123.xyz/gfwlist +server=/beastythumbs.com/127.0.0.1#5335 +ipset=/beastythumbs.com/gfwlist +server=/yourcolonic.com/127.0.0.1#5335 +ipset=/yourcolonic.com/gfwlist +server=/ebayshoesstore.com/127.0.0.1#5335 +ipset=/ebayshoesstore.com/gfwlist +server=/playno1.com/127.0.0.1#5335 +ipset=/playno1.com/gfwlist +server=/applestore.com.ro/127.0.0.1#5335 +ipset=/applestore.com.ro/gfwlist +server=/ebayinc.org/127.0.0.1#5335 +ipset=/ebayinc.org/gfwlist +server=/storage.live.com/127.0.0.1#5335 +ipset=/storage.live.com/gfwlist +server=/cheapcustombeatsbydre.com/127.0.0.1#5335 +ipset=/cheapcustombeatsbydre.com/gfwlist +server=/casquebeatsdocteurdre.com/127.0.0.1#5335 +ipset=/casquebeatsdocteurdre.com/gfwlist +server=/ikea.com.lv/127.0.0.1#5335 +ipset=/ikea.com.lv/gfwlist +server=/account-paypal.info/127.0.0.1#5335 +ipset=/account-paypal.info/gfwlist +server=/google.de/127.0.0.1#5335 +ipset=/google.de/gfwlist +server=/evilx.su/127.0.0.1#5335 +ipset=/evilx.su/gfwlist +server=/artstation.com/127.0.0.1#5335 +ipset=/artstation.com/gfwlist +server=/freshscat.com/127.0.0.1#5335 +ipset=/freshscat.com/gfwlist +server=/hpconnected.net/127.0.0.1#5335 +ipset=/hpconnected.net/gfwlist +server=/wbvm4s.com/127.0.0.1#5335 +ipset=/wbvm4s.com/gfwlist +server=/binance.com/127.0.0.1#5335 +ipset=/binance.com/gfwlist +server=/mini.is/127.0.0.1#5335 +ipset=/mini.is/gfwlist +server=/rea-asia.com/127.0.0.1#5335 +ipset=/rea-asia.com/gfwlist +server=/youtube.az/127.0.0.1#5335 +ipset=/youtube.az/gfwlist +server=/hacklang.org/127.0.0.1#5335 +ipset=/hacklang.org/gfwlist +server=/webtoons.com/127.0.0.1#5335 +ipset=/webtoons.com/gfwlist +server=/volvogroup.mx/127.0.0.1#5335 +ipset=/volvogroup.mx/gfwlist +server=/myavsuper.com/127.0.0.1#5335 +ipset=/myavsuper.com/gfwlist +server=/csakporno.hu/127.0.0.1#5335 +ipset=/csakporno.hu/gfwlist +server=/animeidhentai.com/127.0.0.1#5335 +ipset=/animeidhentai.com/gfwlist +server=/consul.io/127.0.0.1#5335 +ipset=/consul.io/gfwlist +server=/volvobuses.com.au/127.0.0.1#5335 +ipset=/volvobuses.com.au/gfwlist +server=/beatsbydrestudio.com/127.0.0.1#5335 +ipset=/beatsbydrestudio.com/gfwlist +server=/paypal-survey.com/127.0.0.1#5335 +ipset=/paypal-survey.com/gfwlist +server=/valuegb.com/127.0.0.1#5335 +ipset=/valuegb.com/gfwlist +server=/world3d.biz/127.0.0.1#5335 +ipset=/world3d.biz/gfwlist +server=/yuvutu.com/127.0.0.1#5335 +ipset=/yuvutu.com/gfwlist +server=/prettynubiles.com/127.0.0.1#5335 +ipset=/prettynubiles.com/gfwlist +server=/zooporn.shiksha/127.0.0.1#5335 +ipset=/zooporn.shiksha/gfwlist +server=/mastercard.com.ar/127.0.0.1#5335 +ipset=/mastercard.com.ar/gfwlist +server=/xinmeitulu.com/127.0.0.1#5335 +ipset=/xinmeitulu.com/gfwlist +server=/borderlessprepaid.com/127.0.0.1#5335 +ipset=/borderlessprepaid.com/gfwlist +server=/miraheze.org/127.0.0.1#5335 +ipset=/miraheze.org/gfwlist +server=/6parknews.com/127.0.0.1#5335 +ipset=/6parknews.com/gfwlist +server=/drebeatsbuy.com/127.0.0.1#5335 +ipset=/drebeatsbuy.com/gfwlist +server=/enpirion.com/127.0.0.1#5335 +ipset=/enpirion.com/gfwlist +server=/miniso.co.id/127.0.0.1#5335 +ipset=/miniso.co.id/gfwlist +server=/acgfabu.com/127.0.0.1#5335 +ipset=/acgfabu.com/gfwlist +server=/date2night.xyz/127.0.0.1#5335 +ipset=/date2night.xyz/gfwlist +server=/minicanada.ca/127.0.0.1#5335 +ipset=/minicanada.ca/gfwlist +server=/gamedownloads-rockstargames-com.akamaized.net/127.0.0.1#5335 +ipset=/gamedownloads-rockstargames-com.akamaized.net/gfwlist +server=/bandwagonhost.com/127.0.0.1#5335 +ipset=/bandwagonhost.com/gfwlist +server=/alpherafs.ca/127.0.0.1#5335 +ipset=/alpherafs.ca/gfwlist +server=/javcdn.cc/127.0.0.1#5335 +ipset=/javcdn.cc/gfwlist +server=/bridgestonecomercial.com.mx/127.0.0.1#5335 +ipset=/bridgestonecomercial.com.mx/gfwlist +server=/nijie.info/127.0.0.1#5335 +ipset=/nijie.info/gfwlist +server=/dkr.com/127.0.0.1#5335 +ipset=/dkr.com/gfwlist +server=/facdebook.com/127.0.0.1#5335 +ipset=/facdebook.com/gfwlist +server=/japanxxxfilms.com/127.0.0.1#5335 +ipset=/japanxxxfilms.com/gfwlist +server=/cms-twdigitalassets.com/127.0.0.1#5335 +ipset=/cms-twdigitalassets.com/gfwlist +server=/malaypornhub.com/127.0.0.1#5335 +ipset=/malaypornhub.com/gfwlist +server=/animehentaihub.com/127.0.0.1#5335 +ipset=/animehentaihub.com/gfwlist +server=/curvybbwwives.com/127.0.0.1#5335 +ipset=/curvybbwwives.com/gfwlist +server=/weareebay.com/127.0.0.1#5335 +ipset=/weareebay.com/gfwlist +server=/bejewled-stars.com/127.0.0.1#5335 +ipset=/bejewled-stars.com/gfwlist +server=/topcuckolds.com/127.0.0.1#5335 +ipset=/topcuckolds.com/gfwlist +server=/aspbjournals.org/127.0.0.1#5335 +ipset=/aspbjournals.org/gfwlist +server=/intel.com.br/127.0.0.1#5335 +ipset=/intel.com.br/gfwlist +server=/bloombergbriefs.com/127.0.0.1#5335 +ipset=/bloombergbriefs.com/gfwlist +server=/freebasics.net/127.0.0.1#5335 +ipset=/freebasics.net/gfwlist +server=/google.com.hk/127.0.0.1#5335 +ipset=/google.com.hk/gfwlist +server=/meetfasttrack.com/127.0.0.1#5335 +ipset=/meetfasttrack.com/gfwlist +server=/xvideosamadoras.com/127.0.0.1#5335 +ipset=/xvideosamadoras.com/gfwlist +server=/baeb.com/127.0.0.1#5335 +ipset=/baeb.com/gfwlist +server=/macos.com.au/127.0.0.1#5335 +ipset=/macos.com.au/gfwlist +server=/mastercard.com.eg/127.0.0.1#5335 +ipset=/mastercard.com.eg/gfwlist +server=/hpbuiltforlearning.com/127.0.0.1#5335 +ipset=/hpbuiltforlearning.com/gfwlist +server=/clitgames.com/127.0.0.1#5335 +ipset=/clitgames.com/gfwlist +server=/nikesnowboarding.com/127.0.0.1#5335 +ipset=/nikesnowboarding.com/gfwlist +server=/sexvid.xxx/127.0.0.1#5335 +ipset=/sexvid.xxx/gfwlist +server=/pornogrund.com/127.0.0.1#5335 +ipset=/pornogrund.com/gfwlist +server=/pornlulu.com/127.0.0.1#5335 +ipset=/pornlulu.com/gfwlist +server=/youtube.co.th/127.0.0.1#5335 +ipset=/youtube.co.th/gfwlist +server=/newscommercial.co.uk/127.0.0.1#5335 +ipset=/newscommercial.co.uk/gfwlist +server=/xxxvideor.com/127.0.0.1#5335 +ipset=/xxxvideor.com/gfwlist +server=/sexinsex.net/127.0.0.1#5335 +ipset=/sexinsex.net/gfwlist +server=/daftporn.com/127.0.0.1#5335 +ipset=/daftporn.com/gfwlist +server=/beatsbydreoutletscheap.com/127.0.0.1#5335 +ipset=/beatsbydreoutletscheap.com/gfwlist +server=/mini-connected.dk/127.0.0.1#5335 +ipset=/mini-connected.dk/gfwlist +server=/google.dm/127.0.0.1#5335 +ipset=/google.dm/gfwlist +server=/starbuckscard.ph/127.0.0.1#5335 +ipset=/starbuckscard.ph/gfwlist +server=/nike.xn--hxt814e/127.0.0.1#5335 +ipset=/nike.xn--hxt814e/gfwlist +server=/terapeak.com.hk/127.0.0.1#5335 +ipset=/terapeak.com.hk/gfwlist +server=/theverge.com/127.0.0.1#5335 +ipset=/theverge.com/gfwlist +server=/youtube.com.py/127.0.0.1#5335 +ipset=/youtube.com.py/gfwlist +server=/cisconetspace.info/127.0.0.1#5335 +ipset=/cisconetspace.info/gfwlist +server=/youtube.co.hu/127.0.0.1#5335 +ipset=/youtube.co.hu/gfwlist +server=/xmalay.com/127.0.0.1#5335 +ipset=/xmalay.com/gfwlist +server=/wowindianporn.com/127.0.0.1#5335 +ipset=/wowindianporn.com/gfwlist +server=/google.com.mx/127.0.0.1#5335 +ipset=/google.com.mx/gfwlist +server=/watchmygf.to/127.0.0.1#5335 +ipset=/watchmygf.to/gfwlist +server=/nikerunningshoes.com/127.0.0.1#5335 +ipset=/nikerunningshoes.com/gfwlist +server=/ipadaustralia.com/127.0.0.1#5335 +ipset=/ipadaustralia.com/gfwlist +server=/foxsports.cl/127.0.0.1#5335 +ipset=/foxsports.cl/gfwlist +server=/duckduckgo.in/127.0.0.1#5335 +ipset=/duckduckgo.in/gfwlist +server=/collins.co.uk/127.0.0.1#5335 +ipset=/collins.co.uk/gfwlist +server=/playbar.biz/127.0.0.1#5335 +ipset=/playbar.biz/gfwlist +server=/youtube.tn/127.0.0.1#5335 +ipset=/youtube.tn/gfwlist +server=/tubepornclassic.com/127.0.0.1#5335 +ipset=/tubepornclassic.com/gfwlist +server=/amandalist.com/127.0.0.1#5335 +ipset=/amandalist.com/gfwlist +server=/allswingersclubs.org/127.0.0.1#5335 +ipset=/allswingersclubs.org/gfwlist +server=/macbook.hk/127.0.0.1#5335 +ipset=/macbook.hk/gfwlist +server=/50dh.app/127.0.0.1#5335 +ipset=/50dh.app/gfwlist +server=/sony.no/127.0.0.1#5335 +ipset=/sony.no/gfwlist +server=/radiyoyacuvoa.com/127.0.0.1#5335 +ipset=/radiyoyacuvoa.com/gfwlist +server=/pwnedpasswords.com/127.0.0.1#5335 +ipset=/pwnedpasswords.com/gfwlist +server=/intel.lk/127.0.0.1#5335 +ipset=/intel.lk/gfwlist +server=/apple.bs/127.0.0.1#5335 +ipset=/apple.bs/gfwlist +server=/go-lang.net/127.0.0.1#5335 +ipset=/go-lang.net/gfwlist +server=/banatfun.com/127.0.0.1#5335 +ipset=/banatfun.com/gfwlist +server=/johnpersons.com/127.0.0.1#5335 +ipset=/johnpersons.com/gfwlist +server=/nextwork.tw/127.0.0.1#5335 +ipset=/nextwork.tw/gfwlist +server=/office365.com/127.0.0.1#5335 +ipset=/office365.com/gfwlist +server=/thebankerdatabase.com/127.0.0.1#5335 +ipset=/thebankerdatabase.com/gfwlist +server=/animal-hentai.com/127.0.0.1#5335 +ipset=/animal-hentai.com/gfwlist +server=/samsungknox.com/127.0.0.1#5335 +ipset=/samsungknox.com/gfwlist +server=/veetclub.it/127.0.0.1#5335 +ipset=/veetclub.it/gfwlist +server=/bmw-connecteddrive.at/127.0.0.1#5335 +ipset=/bmw-connecteddrive.at/gfwlist +server=/hotstar-cdn.net/127.0.0.1#5335 +ipset=/hotstar-cdn.net/gfwlist +server=/l-0005.l-msedge.net/127.0.0.1#5335 +ipset=/l-0005.l-msedge.net/gfwlist +server=/fapster.xxx/127.0.0.1#5335 +ipset=/fapster.xxx/gfwlist +server=/d2pass.com/127.0.0.1#5335 +ipset=/d2pass.com/gfwlist +server=/magentomobile.com/127.0.0.1#5335 +ipset=/magentomobile.com/gfwlist +server=/gayvl.net/127.0.0.1#5335 +ipset=/gayvl.net/gfwlist +server=/facebock.com/127.0.0.1#5335 +ipset=/facebock.com/gfwlist +server=/facerbooik.com/127.0.0.1#5335 +ipset=/facerbooik.com/gfwlist +server=/ping.pe/127.0.0.1#5335 +ipset=/ping.pe/gfwlist +server=/camgirlstemple.com/127.0.0.1#5335 +ipset=/camgirlstemple.com/gfwlist +server=/beats-bydre-mall.com/127.0.0.1#5335 +ipset=/beats-bydre-mall.com/gfwlist +server=/milfsexstart.nl/127.0.0.1#5335 +ipset=/milfsexstart.nl/gfwlist +server=/machigoto.jp/127.0.0.1#5335 +ipset=/machigoto.jp/gfwlist +server=/monsterbeats365buy.com/127.0.0.1#5335 +ipset=/monsterbeats365buy.com/gfwlist +server=/newbienudes.com/127.0.0.1#5335 +ipset=/newbienudes.com/gfwlist +server=/studiofow.com/127.0.0.1#5335 +ipset=/studiofow.com/gfwlist +server=/beatsheadphoness.com/127.0.0.1#5335 +ipset=/beatsheadphoness.com/gfwlist +server=/pyrobot.org/127.0.0.1#5335 +ipset=/pyrobot.org/gfwlist +server=/befuck.com/127.0.0.1#5335 +ipset=/befuck.com/gfwlist +server=/bimbim.com/127.0.0.1#5335 +ipset=/bimbim.com/gfwlist +server=/yahoo.co.id/127.0.0.1#5335 +ipset=/yahoo.co.id/gfwlist +server=/minisaskatoon.ca/127.0.0.1#5335 +ipset=/minisaskatoon.ca/gfwlist +server=/macbookair.hk/127.0.0.1#5335 +ipset=/macbookair.hk/gfwlist +server=/wiivc.net/127.0.0.1#5335 +ipset=/wiivc.net/gfwlist +server=/bridgestone-korea.co.kr/127.0.0.1#5335 +ipset=/bridgestone-korea.co.kr/gfwlist +server=/bestbuy.com/127.0.0.1#5335 +ipset=/bestbuy.com/gfwlist +server=/trannyvideosxxx.com/127.0.0.1#5335 +ipset=/trannyvideosxxx.com/gfwlist +server=/catalina.hk/127.0.0.1#5335 +ipset=/catalina.hk/gfwlist +server=/lelavement.com/127.0.0.1#5335 +ipset=/lelavement.com/gfwlist +server=/udacity.com/127.0.0.1#5335 +ipset=/udacity.com/gfwlist +server=/sexzy4.com/127.0.0.1#5335 +ipset=/sexzy4.com/gfwlist +server=/spankbang1.com/127.0.0.1#5335 +ipset=/spankbang1.com/gfwlist +server=/pixnet.tw/127.0.0.1#5335 +ipset=/pixnet.tw/gfwlist +server=/beatsbydrdrebiz.com/127.0.0.1#5335 +ipset=/beatsbydrdrebiz.com/gfwlist +server=/applecoronavirus.com/127.0.0.1#5335 +ipset=/applecoronavirus.com/gfwlist +server=/goodsdunk.net/127.0.0.1#5335 +ipset=/goodsdunk.net/gfwlist +server=/youtube.com.pt/127.0.0.1#5335 +ipset=/youtube.com.pt/gfwlist +server=/uncams.com/127.0.0.1#5335 +ipset=/uncams.com/gfwlist +server=/salesforce.com/127.0.0.1#5335 +ipset=/salesforce.com/gfwlist +server=/travelex.co.nz/127.0.0.1#5335 +ipset=/travelex.co.nz/gfwlist +server=/vaultproject.io/127.0.0.1#5335 +ipset=/vaultproject.io/gfwlist +server=/cervical-exam.com/127.0.0.1#5335 +ipset=/cervical-exam.com/gfwlist +server=/microsoftnewsforkids.net/127.0.0.1#5335 +ipset=/microsoftnewsforkids.net/gfwlist +server=/brandporno.com/127.0.0.1#5335 +ipset=/brandporno.com/gfwlist +server=/anyhentai.com/127.0.0.1#5335 +ipset=/anyhentai.com/gfwlist +server=/travelex.bh/127.0.0.1#5335 +ipset=/travelex.bh/gfwlist +server=/ieeer8.org/127.0.0.1#5335 +ipset=/ieeer8.org/gfwlist +server=/rat.xxx/127.0.0.1#5335 +ipset=/rat.xxx/gfwlist +server=/tmdb.org/127.0.0.1#5335 +ipset=/tmdb.org/gfwlist +server=/playsexygame.com/127.0.0.1#5335 +ipset=/playsexygame.com/gfwlist +server=/akacrypto.net/127.0.0.1#5335 +ipset=/akacrypto.net/gfwlist +server=/atlassian.com/127.0.0.1#5335 +ipset=/atlassian.com/gfwlist +server=/cheapmonstersbeatsonsale.com/127.0.0.1#5335 +ipset=/cheapmonstersbeatsonsale.com/gfwlist +server=/semanticscholar.org/127.0.0.1#5335 +ipset=/semanticscholar.org/gfwlist +server=/vmware20mosaic.com/127.0.0.1#5335 +ipset=/vmware20mosaic.com/gfwlist +server=/iphonese.tv/127.0.0.1#5335 +ipset=/iphonese.tv/gfwlist +server=/vfsco.ru/127.0.0.1#5335 +ipset=/vfsco.ru/gfwlist +server=/kubernetes.io/127.0.0.1#5335 +ipset=/kubernetes.io/gfwlist +server=/eastbabes.com/127.0.0.1#5335 +ipset=/eastbabes.com/gfwlist +server=/google.sh/127.0.0.1#5335 +ipset=/google.sh/gfwlist +server=/facebook.ca/127.0.0.1#5335 +ipset=/facebook.ca/gfwlist +server=/epicgames.com/127.0.0.1#5335 +ipset=/epicgames.com/gfwlist +server=/beatsbydrdremall.com/127.0.0.1#5335 +ipset=/beatsbydrdremall.com/gfwlist +server=/nhncorp.jp/127.0.0.1#5335 +ipset=/nhncorp.jp/gfwlist +server=/pics.ee/127.0.0.1#5335 +ipset=/pics.ee/gfwlist +server=/blog.descargasgay.com/127.0.0.1#5335 +ipset=/blog.descargasgay.com/gfwlist +server=/smuttymoms.com/127.0.0.1#5335 +ipset=/smuttymoms.com/gfwlist +server=/ueberamazon.de/127.0.0.1#5335 +ipset=/ueberamazon.de/gfwlist +server=/yahoo.pt/127.0.0.1#5335 +ipset=/yahoo.pt/gfwlist +server=/getsexgames.com/127.0.0.1#5335 +ipset=/getsexgames.com/gfwlist +server=/investorschronicle.co.uk/127.0.0.1#5335 +ipset=/investorschronicle.co.uk/gfwlist +server=/connected-drive.com/127.0.0.1#5335 +ipset=/connected-drive.com/gfwlist +server=/udemycdn.com/127.0.0.1#5335 +ipset=/udemycdn.com/gfwlist +server=/one.one.one/127.0.0.1#5335 +ipset=/one.one.one/gfwlist +server=/nozomi.la/127.0.0.1#5335 +ipset=/nozomi.la/gfwlist +server=/bloomberggovernment.com/127.0.0.1#5335 +ipset=/bloomberggovernment.com/gfwlist +server=/logitechg.fr/127.0.0.1#5335 +ipset=/logitechg.fr/gfwlist +server=/steam.cdn.slingshot.co.nz/127.0.0.1#5335 +ipset=/steam.cdn.slingshot.co.nz/gfwlist +server=/g.dev/127.0.0.1#5335 +ipset=/g.dev/gfwlist +server=/videosection.com/127.0.0.1#5335 +ipset=/videosection.com/gfwlist +server=/mulheresafoder.com/127.0.0.1#5335 +ipset=/mulheresafoder.com/gfwlist +server=/woodmancastingx.com/127.0.0.1#5335 +ipset=/woodmancastingx.com/gfwlist +server=/imac.com/127.0.0.1#5335 +ipset=/imac.com/gfwlist +server=/cartoonporn.com/127.0.0.1#5335 +ipset=/cartoonporn.com/gfwlist +server=/bili2.cc/127.0.0.1#5335 +ipset=/bili2.cc/gfwlist +server=/beatsbydresold.com/127.0.0.1#5335 +ipset=/beatsbydresold.com/gfwlist +server=/kktv.me/127.0.0.1#5335 +ipset=/kktv.me/gfwlist +server=/phimsex47.club/127.0.0.1#5335 +ipset=/phimsex47.club/gfwlist +server=/wwwwebay.com/127.0.0.1#5335 +ipset=/wwwwebay.com/gfwlist +server=/disneytickets.co.uk/127.0.0.1#5335 +ipset=/disneytickets.co.uk/gfwlist +server=/hulufree.com/127.0.0.1#5335 +ipset=/hulufree.com/gfwlist +server=/wnacg.com/127.0.0.1#5335 +ipset=/wnacg.com/gfwlist +server=/ikea.pr/127.0.0.1#5335 +ipset=/ikea.pr/gfwlist +server=/minispace.com/127.0.0.1#5335 +ipset=/minispace.com/gfwlist +server=/cuckoldvideos.xxx/127.0.0.1#5335 +ipset=/cuckoldvideos.xxx/gfwlist +server=/opensourceinsights.dev/127.0.0.1#5335 +ipset=/opensourceinsights.dev/gfwlist +server=/connectcommerce.hk/127.0.0.1#5335 +ipset=/connectcommerce.hk/gfwlist +server=/zohocdn.com/127.0.0.1#5335 +ipset=/zohocdn.com/gfwlist +server=/netflix.net/127.0.0.1#5335 +ipset=/netflix.net/gfwlist +server=/pornohd.plus/127.0.0.1#5335 +ipset=/pornohd.plus/gfwlist +server=/battleforcecomix.com/127.0.0.1#5335 +ipset=/battleforcecomix.com/gfwlist +server=/imgur.com/127.0.0.1#5335 +ipset=/imgur.com/gfwlist +server=/pingguotv.xyz/127.0.0.1#5335 +ipset=/pingguotv.xyz/gfwlist +server=/ipod.com.sg/127.0.0.1#5335 +ipset=/ipod.com.sg/gfwlist +server=/avcens.xyz/127.0.0.1#5335 +ipset=/avcens.xyz/gfwlist +server=/pbabes.com/127.0.0.1#5335 +ipset=/pbabes.com/gfwlist +server=/paypal-cash.com/127.0.0.1#5335 +ipset=/paypal-cash.com/gfwlist +server=/pornguide.blog/127.0.0.1#5335 +ipset=/pornguide.blog/gfwlist +server=/yahoo.sn/127.0.0.1#5335 +ipset=/yahoo.sn/gfwlist +server=/enfabebe.com.mx/127.0.0.1#5335 +ipset=/enfabebe.com.mx/gfwlist +server=/massagerepublic.com/127.0.0.1#5335 +ipset=/massagerepublic.com/gfwlist +server=/worldcurrencycard.co.za/127.0.0.1#5335 +ipset=/worldcurrencycard.co.za/gfwlist +server=/myvisaluxuryhotels.com/127.0.0.1#5335 +ipset=/myvisaluxuryhotels.com/gfwlist +server=/erodougazo.com/127.0.0.1#5335 +ipset=/erodougazo.com/gfwlist +server=/mdlf.xyz/127.0.0.1#5335 +ipset=/mdlf.xyz/gfwlist +server=/weblive-hamivideo.cdn.hinet.net/127.0.0.1#5335 +ipset=/weblive-hamivideo.cdn.hinet.net/gfwlist +server=/bmw.bb/127.0.0.1#5335 +ipset=/bmw.bb/gfwlist +server=/pornhubs.video/127.0.0.1#5335 +ipset=/pornhubs.video/gfwlist +server=/fivestarpornsites.com/127.0.0.1#5335 +ipset=/fivestarpornsites.com/gfwlist +server=/avhd101.com/127.0.0.1#5335 +ipset=/avhd101.com/gfwlist +server=/tnaflix.com/127.0.0.1#5335 +ipset=/tnaflix.com/gfwlist +server=/google.nr/127.0.0.1#5335 +ipset=/google.nr/gfwlist +server=/applepay.hamburg/127.0.0.1#5335 +ipset=/applepay.hamburg/gfwlist +server=/kampalaexclusiveescorts.com/127.0.0.1#5335 +ipset=/kampalaexclusiveescorts.com/gfwlist +server=/pp-soc.com/127.0.0.1#5335 +ipset=/pp-soc.com/gfwlist +server=/steamdb.info/127.0.0.1#5335 +ipset=/steamdb.info/gfwlist +server=/apple.cz/127.0.0.1#5335 +ipset=/apple.cz/gfwlist +server=/visa.com.lc/127.0.0.1#5335 +ipset=/visa.com.lc/gfwlist +server=/certinomis.com/127.0.0.1#5335 +ipset=/certinomis.com/gfwlist +server=/awsbraket.com/127.0.0.1#5335 +ipset=/awsbraket.com/gfwlist +server=/animesexhq.com/127.0.0.1#5335 +ipset=/animesexhq.com/gfwlist +server=/monsterbeatstang.com/127.0.0.1#5335 +ipset=/monsterbeatstang.com/gfwlist +server=/hentai2w.com/127.0.0.1#5335 +ipset=/hentai2w.com/gfwlist +server=/evemodels.com/127.0.0.1#5335 +ipset=/evemodels.com/gfwlist +server=/porntea.com/127.0.0.1#5335 +ipset=/porntea.com/gfwlist +server=/cloudflare-quic.com/127.0.0.1#5335 +ipset=/cloudflare-quic.com/gfwlist +server=/disney-plus.net/127.0.0.1#5335 +ipset=/disney-plus.net/gfwlist +server=/line-apps-rc.com/127.0.0.1#5335 +ipset=/line-apps-rc.com/gfwlist +server=/cambridge.org/127.0.0.1#5335 +ipset=/cambridge.org/gfwlist +server=/inside.com.tw/127.0.0.1#5335 +ipset=/inside.com.tw/gfwlist +server=/ichat.co.in/127.0.0.1#5335 +ipset=/ichat.co.in/gfwlist +server=/kannewyork.com/127.0.0.1#5335 +ipset=/kannewyork.com/gfwlist +server=/alphabet.mx/127.0.0.1#5335 +ipset=/alphabet.mx/gfwlist +server=/cdkworkshop.com/127.0.0.1#5335 +ipset=/cdkworkshop.com/gfwlist +server=/5fang.cc/127.0.0.1#5335 +ipset=/5fang.cc/gfwlist +server=/tctsx28d.xyz/127.0.0.1#5335 +ipset=/tctsx28d.xyz/gfwlist +server=/escortdude.com/127.0.0.1#5335 +ipset=/escortdude.com/gfwlist +server=/ksyp10.com/127.0.0.1#5335 +ipset=/ksyp10.com/gfwlist +server=/mini.com.cy/127.0.0.1#5335 +ipset=/mini.com.cy/gfwlist +server=/volvobuses.om/127.0.0.1#5335 +ipset=/volvobuses.om/gfwlist +server=/enemanozzle.info/127.0.0.1#5335 +ipset=/enemanozzle.info/gfwlist +server=/alphera.com.es/127.0.0.1#5335 +ipset=/alphera.com.es/gfwlist +server=/hpcontinuum.com/127.0.0.1#5335 +ipset=/hpcontinuum.com/gfwlist +server=/audiencenetwork.tv/127.0.0.1#5335 +ipset=/audiencenetwork.tv/gfwlist +server=/yahoo.com.bd/127.0.0.1#5335 +ipset=/yahoo.com.bd/gfwlist +server=/ebayinkblog.com/127.0.0.1#5335 +ipset=/ebayinkblog.com/gfwlist +server=/govforce.com/127.0.0.1#5335 +ipset=/govforce.com/gfwlist +server=/awssecworkshops.com/127.0.0.1#5335 +ipset=/awssecworkshops.com/gfwlist +server=/bmw-art-journey.com/127.0.0.1#5335 +ipset=/bmw-art-journey.com/gfwlist +server=/omniroot.com/127.0.0.1#5335 +ipset=/omniroot.com/gfwlist +server=/swiftfinancial.net/127.0.0.1#5335 +ipset=/swiftfinancial.net/gfwlist +server=/imdb.to/127.0.0.1#5335 +ipset=/imdb.to/gfwlist +server=/jsbridgestone.com/127.0.0.1#5335 +ipset=/jsbridgestone.com/gfwlist +server=/mcdelivery.co.id/127.0.0.1#5335 +ipset=/mcdelivery.co.id/gfwlist +server=/thismon.ee/127.0.0.1#5335 +ipset=/thismon.ee/gfwlist +server=/quickoffice.com/127.0.0.1#5335 +ipset=/quickoffice.com/gfwlist +server=/facebook.wang/127.0.0.1#5335 +ipset=/facebook.wang/gfwlist +server=/free64all.com/127.0.0.1#5335 +ipset=/free64all.com/gfwlist +server=/ebaysocial.ru/127.0.0.1#5335 +ipset=/ebaysocial.ru/gfwlist +server=/vanish.com.tr/127.0.0.1#5335 +ipset=/vanish.com.tr/gfwlist +server=/quicinc.com/127.0.0.1#5335 +ipset=/quicinc.com/gfwlist +server=/pinterest.be/127.0.0.1#5335 +ipset=/pinterest.be/gfwlist +server=/filmesporno.com.br/127.0.0.1#5335 +ipset=/filmesporno.com.br/gfwlist +server=/hsprepack.akamaized.net/127.0.0.1#5335 +ipset=/hsprepack.akamaized.net/gfwlist +server=/verisign.net/127.0.0.1#5335 +ipset=/verisign.net/gfwlist +server=/mhhanman.xyz/127.0.0.1#5335 +ipset=/mhhanman.xyz/gfwlist +server=/bmwarchiv.at/127.0.0.1#5335 +ipset=/bmwarchiv.at/gfwlist +server=/hxc10.vip/127.0.0.1#5335 +ipset=/hxc10.vip/gfwlist +server=/famous-nudes.com/127.0.0.1#5335 +ipset=/famous-nudes.com/gfwlist +server=/aavs.xyz/127.0.0.1#5335 +ipset=/aavs.xyz/gfwlist +server=/bestbuycanada.com/127.0.0.1#5335 +ipset=/bestbuycanada.com/gfwlist +server=/bmw-connecteddrive.dk/127.0.0.1#5335 +ipset=/bmw-connecteddrive.dk/gfwlist +server=/escort.guide/127.0.0.1#5335 +ipset=/escort.guide/gfwlist +server=/scholar.google.es/127.0.0.1#5335 +ipset=/scholar.google.es/gfwlist +server=/igoogle.com/127.0.0.1#5335 +ipset=/igoogle.com/gfwlist +server=/apple.no/127.0.0.1#5335 +ipset=/apple.no/gfwlist +server=/ggoogle.com/127.0.0.1#5335 +ipset=/ggoogle.com/gfwlist +server=/applecard.tv/127.0.0.1#5335 +ipset=/applecard.tv/gfwlist +server=/epicreads.com/127.0.0.1#5335 +ipset=/epicreads.com/gfwlist +server=/minivalueservice.com/127.0.0.1#5335 +ipset=/minivalueservice.com/gfwlist +server=/heroesofthestorm.com/127.0.0.1#5335 +ipset=/heroesofthestorm.com/gfwlist +server=/xnxxhamster.net/127.0.0.1#5335 +ipset=/xnxxhamster.net/gfwlist +server=/blogspot.com.uy/127.0.0.1#5335 +ipset=/blogspot.com.uy/gfwlist +server=/xeon.com/127.0.0.1#5335 +ipset=/xeon.com/gfwlist +server=/101xxx.xyz/127.0.0.1#5335 +ipset=/101xxx.xyz/gfwlist +server=/adobetechcommcallback.com/127.0.0.1#5335 +ipset=/adobetechcommcallback.com/gfwlist +server=/pinterest.com.py/127.0.0.1#5335 +ipset=/pinterest.com.py/gfwlist +server=/topmanga.biz/127.0.0.1#5335 +ipset=/topmanga.biz/gfwlist +server=/efuckt.com/127.0.0.1#5335 +ipset=/efuckt.com/gfwlist +server=/blinkload.zone/127.0.0.1#5335 +ipset=/blinkload.zone/gfwlist +server=/mybabehotz.com/127.0.0.1#5335 +ipset=/mybabehotz.com/gfwlist +server=/apple.de/127.0.0.1#5335 +ipset=/apple.de/gfwlist +server=/pinterest.com.uy/127.0.0.1#5335 +ipset=/pinterest.com.uy/gfwlist +server=/voaportugues.com/127.0.0.1#5335 +ipset=/voaportugues.com/gfwlist +server=/cursecdn.com/127.0.0.1#5335 +ipset=/cursecdn.com/gfwlist +server=/annstores.net/127.0.0.1#5335 +ipset=/annstores.net/gfwlist +server=/wolfatbestbuy.com/127.0.0.1#5335 +ipset=/wolfatbestbuy.com/gfwlist +server=/applepay.hk/127.0.0.1#5335 +ipset=/applepay.hk/gfwlist +server=/xn--80aaazx1an0a.lol/127.0.0.1#5335 +ipset=/xn--80aaazx1an0a.lol/gfwlist +server=/s-msn.com/127.0.0.1#5335 +ipset=/s-msn.com/gfwlist +server=/feet9.com/127.0.0.1#5335 +ipset=/feet9.com/gfwlist +server=/ioinformatics.org/127.0.0.1#5335 +ipset=/ioinformatics.org/gfwlist +server=/themessengeradelaide.com.au/127.0.0.1#5335 +ipset=/themessengeradelaide.com.au/gfwlist +server=/exploreintel.com/127.0.0.1#5335 +ipset=/exploreintel.com/gfwlist +server=/facebooi.com/127.0.0.1#5335 +ipset=/facebooi.com/gfwlist +server=/scholar.google.co.ve/127.0.0.1#5335 +ipset=/scholar.google.co.ve/gfwlist +server=/alphabet.com.es/127.0.0.1#5335 +ipset=/alphabet.com.es/gfwlist +server=/akamainewzealand.com/127.0.0.1#5335 +ipset=/akamainewzealand.com/gfwlist +server=/buzzardflapper.com/127.0.0.1#5335 +ipset=/buzzardflapper.com/gfwlist +server=/honestpornreviews.com/127.0.0.1#5335 +ipset=/honestpornreviews.com/gfwlist +server=/amateurporndump.com/127.0.0.1#5335 +ipset=/amateurporndump.com/gfwlist +server=/amebame.com/127.0.0.1#5335 +ipset=/amebame.com/gfwlist +server=/line-apps.com/127.0.0.1#5335 +ipset=/line-apps.com/gfwlist +server=/camelphat.com/127.0.0.1#5335 +ipset=/camelphat.com/gfwlist +server=/techatbloomberg.com/127.0.0.1#5335 +ipset=/techatbloomberg.com/gfwlist +server=/winhec.com/127.0.0.1#5335 +ipset=/winhec.com/gfwlist +server=/hotgirl.asia/127.0.0.1#5335 +ipset=/hotgirl.asia/gfwlist +server=/pvt.sexy/127.0.0.1#5335 +ipset=/pvt.sexy/gfwlist +server=/animestigma.com/127.0.0.1#5335 +ipset=/animestigma.com/gfwlist +server=/google.bt/127.0.0.1#5335 +ipset=/google.bt/gfwlist +server=/becomeindex.com/127.0.0.1#5335 +ipset=/becomeindex.com/gfwlist +server=/disney.dk/127.0.0.1#5335 +ipset=/disney.dk/gfwlist +server=/videobreakdown.com/127.0.0.1#5335 +ipset=/videobreakdown.com/gfwlist +server=/oculus.com/127.0.0.1#5335 +ipset=/oculus.com/gfwlist +server=/joyhentai.com/127.0.0.1#5335 +ipset=/joyhentai.com/gfwlist +server=/apple.at/127.0.0.1#5335 +ipset=/apple.at/gfwlist +server=/experience-vmware.com/127.0.0.1#5335 +ipset=/experience-vmware.com/gfwlist +server=/nvidiaforhp.com/127.0.0.1#5335 +ipset=/nvidiaforhp.com/gfwlist +server=/facebookphotos.com/127.0.0.1#5335 +ipset=/facebookphotos.com/gfwlist +server=/mini-connected.ie/127.0.0.1#5335 +ipset=/mini-connected.ie/gfwlist +server=/visacheckout.net/127.0.0.1#5335 +ipset=/visacheckout.net/gfwlist +server=/zweiporn.com/127.0.0.1#5335 +ipset=/zweiporn.com/gfwlist +server=/airport.com/127.0.0.1#5335 +ipset=/airport.com/gfwlist +server=/buyaapl.com/127.0.0.1#5335 +ipset=/buyaapl.com/gfwlist +server=/realcleardefense.com/127.0.0.1#5335 +ipset=/realcleardefense.com/gfwlist +server=/maktoob.com/127.0.0.1#5335 +ipset=/maktoob.com/gfwlist +server=/linefriends.com.tw/127.0.0.1#5335 +ipset=/linefriends.com.tw/gfwlist +server=/ebaytopratedseller.net/127.0.0.1#5335 +ipset=/ebaytopratedseller.net/gfwlist +server=/database.asahi.com/127.0.0.1#5335 +ipset=/database.asahi.com/gfwlist +server=/analytictech.com/127.0.0.1#5335 +ipset=/analytictech.com/gfwlist +server=/foxsportsworld.com/127.0.0.1#5335 +ipset=/foxsportsworld.com/gfwlist +server=/avgle.com/127.0.0.1#5335 +ipset=/avgle.com/gfwlist +server=/ixquick.com/127.0.0.1#5335 +ipset=/ixquick.com/gfwlist +server=/backroomcastingcouch.com/127.0.0.1#5335 +ipset=/backroomcastingcouch.com/gfwlist +server=/xknoop.com/127.0.0.1#5335 +ipset=/xknoop.com/gfwlist +server=/canon.lu/127.0.0.1#5335 +ipset=/canon.lu/gfwlist +server=/nikerunner.com/127.0.0.1#5335 +ipset=/nikerunner.com/gfwlist +server=/registerhulu.com/127.0.0.1#5335 +ipset=/registerhulu.com/gfwlist +server=/yandex.com.ge/127.0.0.1#5335 +ipset=/yandex.com.ge/gfwlist +server=/durex.ru/127.0.0.1#5335 +ipset=/durex.ru/gfwlist +server=/wisekey.com.hk/127.0.0.1#5335 +ipset=/wisekey.com.hk/gfwlist +server=/volvotrucks.ch/127.0.0.1#5335 +ipset=/volvotrucks.ch/gfwlist +server=/detaliczny.com/127.0.0.1#5335 +ipset=/detaliczny.com/gfwlist +server=/visa.co.ao/127.0.0.1#5335 +ipset=/visa.co.ao/gfwlist +server=/dreamtoplay.com/127.0.0.1#5335 +ipset=/dreamtoplay.com/gfwlist +server=/paypal-notify.com/127.0.0.1#5335 +ipset=/paypal-notify.com/gfwlist +server=/buydrdrebeatbox.com/127.0.0.1#5335 +ipset=/buydrdrebeatbox.com/gfwlist +server=/tryfunctions.com/127.0.0.1#5335 +ipset=/tryfunctions.com/gfwlist +server=/scoregroup.com/127.0.0.1#5335 +ipset=/scoregroup.com/gfwlist +server=/pypl.info/127.0.0.1#5335 +ipset=/pypl.info/gfwlist +server=/nlsexfilmpjes.com/127.0.0.1#5335 +ipset=/nlsexfilmpjes.com/gfwlist +server=/family.co.jp/127.0.0.1#5335 +ipset=/family.co.jp/gfwlist +server=/finish.com.tr/127.0.0.1#5335 +ipset=/finish.com.tr/gfwlist +server=/porndiscount.org/127.0.0.1#5335 +ipset=/porndiscount.org/gfwlist +server=/ds-vod-abematv.akamaized.net/127.0.0.1#5335 +ipset=/ds-vod-abematv.akamaized.net/gfwlist +server=/ikea.at/127.0.0.1#5335 +ipset=/ikea.at/gfwlist +server=/altera.com/127.0.0.1#5335 +ipset=/altera.com/gfwlist +server=/xhamster.desi/127.0.0.1#5335 +ipset=/xhamster.desi/gfwlist +server=/scholar.google.fr/127.0.0.1#5335 +ipset=/scholar.google.fr/gfwlist +server=/wolterskluwer.com/127.0.0.1#5335 +ipset=/wolterskluwer.com/gfwlist +server=/youskbe.com/127.0.0.1#5335 +ipset=/youskbe.com/gfwlist +server=/cameraboys.com/127.0.0.1#5335 +ipset=/cameraboys.com/gfwlist +server=/intel.ar/127.0.0.1#5335 +ipset=/intel.ar/gfwlist +server=/bmw-connecteddrive.nl/127.0.0.1#5335 +ipset=/bmw-connecteddrive.nl/gfwlist +server=/google.com.cu/127.0.0.1#5335 +ipset=/google.com.cu/gfwlist +server=/paypal-survey.org/127.0.0.1#5335 +ipset=/paypal-survey.org/gfwlist +server=/nikehyperdunk.com/127.0.0.1#5335 +ipset=/nikehyperdunk.com/gfwlist +server=/ieeenano.org/127.0.0.1#5335 +ipset=/ieeenano.org/gfwlist +server=/monstercockland.com/127.0.0.1#5335 +ipset=/monstercockland.com/gfwlist +server=/shopee.com.my/127.0.0.1#5335 +ipset=/shopee.com.my/gfwlist +server=/volvotrucks.com.kw/127.0.0.1#5335 +ipset=/volvotrucks.com.kw/gfwlist +server=/my-enema.com/127.0.0.1#5335 +ipset=/my-enema.com/gfwlist +server=/vanish.it/127.0.0.1#5335 +ipset=/vanish.it/gfwlist +server=/social.com/127.0.0.1#5335 +ipset=/social.com/gfwlist +server=/scholar.google.hu/127.0.0.1#5335 +ipset=/scholar.google.hu/gfwlist +server=/huluim.com/127.0.0.1#5335 +ipset=/huluim.com/gfwlist +server=/andygod.com/127.0.0.1#5335 +ipset=/andygod.com/gfwlist +server=/wikia.com/127.0.0.1#5335 +ipset=/wikia.com/gfwlist +server=/ipadmini.cm/127.0.0.1#5335 +ipset=/ipadmini.cm/gfwlist +server=/pdf.new/127.0.0.1#5335 +ipset=/pdf.new/gfwlist +server=/cebay.com/127.0.0.1#5335 +ipset=/cebay.com/gfwlist +server=/xxxfiles.com/127.0.0.1#5335 +ipset=/xxxfiles.com/gfwlist +server=/foxtube.com/127.0.0.1#5335 +ipset=/foxtube.com/gfwlist +server=/2ch.hk/127.0.0.1#5335 +ipset=/2ch.hk/gfwlist +server=/cbsstatic.com/127.0.0.1#5335 +ipset=/cbsstatic.com/gfwlist +server=/appletips.net/127.0.0.1#5335 +ipset=/appletips.net/gfwlist +server=/vxxsred.xyz/127.0.0.1#5335 +ipset=/vxxsred.xyz/gfwlist +server=/pokemon-moon.com/127.0.0.1#5335 +ipset=/pokemon-moon.com/gfwlist +server=/facebookthreads.net/127.0.0.1#5335 +ipset=/facebookthreads.net/gfwlist +server=/avizoone.com/127.0.0.1#5335 +ipset=/avizoone.com/gfwlist +server=/durexcanada.com/127.0.0.1#5335 +ipset=/durexcanada.com/gfwlist +server=/mypornwap.fun/127.0.0.1#5335 +ipset=/mypornwap.fun/gfwlist +server=/microsoftpartnersolutions.com/127.0.0.1#5335 +ipset=/microsoftpartnersolutions.com/gfwlist +server=/erogazo-ngo.com/127.0.0.1#5335 +ipset=/erogazo-ngo.com/gfwlist +server=/iebay.com/127.0.0.1#5335 +ipset=/iebay.com/gfwlist +server=/docker.com/127.0.0.1#5335 +ipset=/docker.com/gfwlist +server=/rumporn.com/127.0.0.1#5335 +ipset=/rumporn.com/gfwlist +server=/alphabet.us/127.0.0.1#5335 +ipset=/alphabet.us/gfwlist +server=/momsneversayno.com/127.0.0.1#5335 +ipset=/momsneversayno.com/gfwlist +server=/pricelessmarketingengine.com/127.0.0.1#5335 +ipset=/pricelessmarketingengine.com/gfwlist +server=/bmw-motorrad.se/127.0.0.1#5335 +ipset=/bmw-motorrad.se/gfwlist +server=/bestpornclip.com/127.0.0.1#5335 +ipset=/bestpornclip.com/gfwlist +server=/soccerfanz.com.my/127.0.0.1#5335 +ipset=/soccerfanz.com.my/gfwlist +server=/wiley.com/127.0.0.1#5335 +ipset=/wiley.com/gfwlist +server=/beatsonblackfriday2013.com/127.0.0.1#5335 +ipset=/beatsonblackfriday2013.com/gfwlist +server=/visa.fr/127.0.0.1#5335 +ipset=/visa.fr/gfwlist +server=/shequ8.cam/127.0.0.1#5335 +ipset=/shequ8.cam/gfwlist +server=/starbucks.ch/127.0.0.1#5335 +ipset=/starbucks.ch/gfwlist +server=/torrentkitty.tv/127.0.0.1#5335 +ipset=/torrentkitty.tv/gfwlist +server=/mini.dz/127.0.0.1#5335 +ipset=/mini.dz/gfwlist +server=/girlsongirlstube.com/127.0.0.1#5335 +ipset=/girlsongirlstube.com/gfwlist +server=/niuc2.com/127.0.0.1#5335 +ipset=/niuc2.com/gfwlist +server=/speedracegear.com/127.0.0.1#5335 +ipset=/speedracegear.com/gfwlist +server=/hpuae.com/127.0.0.1#5335 +ipset=/hpuae.com/gfwlist +server=/yahoo.com.tw/127.0.0.1#5335 +ipset=/yahoo.com.tw/gfwlist +server=/nikkan-gendai.com/127.0.0.1#5335 +ipset=/nikkan-gendai.com/gfwlist +server=/buyonlineheadphones.com/127.0.0.1#5335 +ipset=/buyonlineheadphones.com/gfwlist +server=/truedepth3d.com/127.0.0.1#5335 +ipset=/truedepth3d.com/gfwlist +server=/ichigocandy.com/127.0.0.1#5335 +ipset=/ichigocandy.com/gfwlist +server=/royalsocietypublishing.org/127.0.0.1#5335 +ipset=/royalsocietypublishing.org/gfwlist +server=/zoomingin.tv/127.0.0.1#5335 +ipset=/zoomingin.tv/gfwlist +server=/discordapp.io/127.0.0.1#5335 +ipset=/discordapp.io/gfwlist +server=/sndcdn.com/127.0.0.1#5335 +ipset=/sndcdn.com/gfwlist +server=/modelsfreecams.com/127.0.0.1#5335 +ipset=/modelsfreecams.com/gfwlist +server=/daytontrucktires.com/127.0.0.1#5335 +ipset=/daytontrucktires.com/gfwlist +server=/ero-kawa.com/127.0.0.1#5335 +ipset=/ero-kawa.com/gfwlist +server=/cabletvdirectv.com/127.0.0.1#5335 +ipset=/cabletvdirectv.com/gfwlist +server=/getdrebeatssale.com/127.0.0.1#5335 +ipset=/getdrebeatssale.com/gfwlist +server=/apple.co.kr/127.0.0.1#5335 +ipset=/apple.co.kr/gfwlist +server=/dealerspeed.net/127.0.0.1#5335 +ipset=/dealerspeed.net/gfwlist +server=/rm2029.com/127.0.0.1#5335 +ipset=/rm2029.com/gfwlist +server=/x1337x.ws/127.0.0.1#5335 +ipset=/x1337x.ws/gfwlist +server=/pinkcore.com/127.0.0.1#5335 +ipset=/pinkcore.com/gfwlist +server=/dirtyscat.org/127.0.0.1#5335 +ipset=/dirtyscat.org/gfwlist +server=/bisq.network/127.0.0.1#5335 +ipset=/bisq.network/gfwlist +server=/0x0.st/127.0.0.1#5335 +ipset=/0x0.st/gfwlist +server=/durex.co.th/127.0.0.1#5335 +ipset=/durex.co.th/gfwlist +server=/pullstring.net/127.0.0.1#5335 +ipset=/pullstring.net/gfwlist +server=/dmmapis.com/127.0.0.1#5335 +ipset=/dmmapis.com/gfwlist +server=/pornodebolivia.net/127.0.0.1#5335 +ipset=/pornodebolivia.net/gfwlist +server=/adultdvdtalk.com/127.0.0.1#5335 +ipset=/adultdvdtalk.com/gfwlist +server=/free-abbywinters.com/127.0.0.1#5335 +ipset=/free-abbywinters.com/gfwlist +server=/aflamsexhd.com/127.0.0.1#5335 +ipset=/aflamsexhd.com/gfwlist +server=/sexyculo.com/127.0.0.1#5335 +ipset=/sexyculo.com/gfwlist +server=/sony.it/127.0.0.1#5335 +ipset=/sony.it/gfwlist +server=/faronics.co.uk/127.0.0.1#5335 +ipset=/faronics.co.uk/gfwlist +server=/bridgestonerewards.com/127.0.0.1#5335 +ipset=/bridgestonerewards.com/gfwlist +server=/disney.com.tw/127.0.0.1#5335 +ipset=/disney.com.tw/gfwlist +server=/herokussl.com/127.0.0.1#5335 +ipset=/herokussl.com/gfwlist +server=/harpercollins.com.au/127.0.0.1#5335 +ipset=/harpercollins.com.au/gfwlist +server=/camwhores-tv.com/127.0.0.1#5335 +ipset=/camwhores-tv.com/gfwlist +server=/instagramhashtags.net/127.0.0.1#5335 +ipset=/instagramhashtags.net/gfwlist +server=/ebayy.com/127.0.0.1#5335 +ipset=/ebayy.com/gfwlist +server=/google.co.jp/127.0.0.1#5335 +ipset=/google.co.jp/gfwlist +server=/7mm.tv/127.0.0.1#5335 +ipset=/7mm.tv/gfwlist +server=/findhername.net/127.0.0.1#5335 +ipset=/findhername.net/gfwlist +server=/thenipslip.com/127.0.0.1#5335 +ipset=/thenipslip.com/gfwlist +server=/bmw-antilles.fr/127.0.0.1#5335 +ipset=/bmw-antilles.fr/gfwlist +server=/yandexcloud.net/127.0.0.1#5335 +ipset=/yandexcloud.net/gfwlist +server=/ubi.com/127.0.0.1#5335 +ipset=/ubi.com/gfwlist +server=/inventorship.com.au/127.0.0.1#5335 +ipset=/inventorship.com.au/gfwlist +server=/ds-linear-abematv.akamaized.net/127.0.0.1#5335 +ipset=/ds-linear-abematv.akamaized.net/gfwlist +server=/recelebrity.com/127.0.0.1#5335 +ipset=/recelebrity.com/gfwlist +server=/trello.com/127.0.0.1#5335 +ipset=/trello.com/gfwlist +server=/nikeelite.com/127.0.0.1#5335 +ipset=/nikeelite.com/gfwlist +server=/beatsblackfridayretails.com/127.0.0.1#5335 +ipset=/beatsblackfridayretails.com/gfwlist +server=/whatsapp.com/127.0.0.1#5335 +ipset=/whatsapp.com/gfwlist +server=/durex.pl/127.0.0.1#5335 +ipset=/durex.pl/gfwlist +server=/na-att-idns.net/127.0.0.1#5335 +ipset=/na-att-idns.net/gfwlist +server=/babypink.to/127.0.0.1#5335 +ipset=/babypink.to/gfwlist +server=/xvideoscom.me/127.0.0.1#5335 +ipset=/xvideoscom.me/gfwlist +server=/ipod.ch/127.0.0.1#5335 +ipset=/ipod.ch/gfwlist +server=/veryladyboy.com/127.0.0.1#5335 +ipset=/veryladyboy.com/gfwlist +server=/bloombergquint.com/127.0.0.1#5335 +ipset=/bloombergquint.com/gfwlist +server=/animalsporn.tv/127.0.0.1#5335 +ipset=/animalsporn.tv/gfwlist +server=/volvo.ca/127.0.0.1#5335 +ipset=/volvo.ca/gfwlist +server=/hulunet.com/127.0.0.1#5335 +ipset=/hulunet.com/gfwlist +server=/firestonetire.com/127.0.0.1#5335 +ipset=/firestonetire.com/gfwlist +server=/thepornarea.com/127.0.0.1#5335 +ipset=/thepornarea.com/gfwlist +server=/asianporntrends.com/127.0.0.1#5335 +ipset=/asianporntrends.com/gfwlist +server=/mahajantech.com/127.0.0.1#5335 +ipset=/mahajantech.com/gfwlist +server=/shopibay.net/127.0.0.1#5335 +ipset=/shopibay.net/gfwlist +server=/mbeats-tech.com/127.0.0.1#5335 +ipset=/mbeats-tech.com/gfwlist +server=/cnnarabic.com/127.0.0.1#5335 +ipset=/cnnarabic.com/gfwlist +server=/fxnetwork.com/127.0.0.1#5335 +ipset=/fxnetwork.com/gfwlist +server=/google.net/127.0.0.1#5335 +ipset=/google.net/gfwlist +server=/google.ga/127.0.0.1#5335 +ipset=/google.ga/gfwlist +server=/google.no/127.0.0.1#5335 +ipset=/google.no/gfwlist +server=/drebeatsforsaleus.com/127.0.0.1#5335 +ipset=/drebeatsforsaleus.com/gfwlist +server=/c4slive.com/127.0.0.1#5335 +ipset=/c4slive.com/gfwlist +server=/youtube.is/127.0.0.1#5335 +ipset=/youtube.is/gfwlist +server=/mscrl.microsoft.com/127.0.0.1#5335 +ipset=/mscrl.microsoft.com/gfwlist +server=/facebboc.com/127.0.0.1#5335 +ipset=/facebboc.com/gfwlist +server=/macruby.net/127.0.0.1#5335 +ipset=/macruby.net/gfwlist +server=/txvlog.com/127.0.0.1#5335 +ipset=/txvlog.com/gfwlist +server=/itunesfestivals.com/127.0.0.1#5335 +ipset=/itunesfestivals.com/gfwlist +server=/vercel.events/127.0.0.1#5335 +ipset=/vercel.events/gfwlist +server=/pastebin.com/127.0.0.1#5335 +ipset=/pastebin.com/gfwlist +server=/enfagrow4.com/127.0.0.1#5335 +ipset=/enfagrow4.com/gfwlist +server=/applenews.tv/127.0.0.1#5335 +ipset=/applenews.tv/gfwlist +server=/volvogroup.com.br/127.0.0.1#5335 +ipset=/volvogroup.com.br/gfwlist +server=/harpercollins.ca/127.0.0.1#5335 +ipset=/harpercollins.ca/gfwlist +server=/knowswho.co.jp/127.0.0.1#5335 +ipset=/knowswho.co.jp/gfwlist +server=/rarbgget.org/127.0.0.1#5335 +ipset=/rarbgget.org/gfwlist +server=/palcomix.com/127.0.0.1#5335 +ipset=/palcomix.com/gfwlist +server=/18jms.com/127.0.0.1#5335 +ipset=/18jms.com/gfwlist +server=/gratisvideokijken.nl/127.0.0.1#5335 +ipset=/gratisvideokijken.nl/gfwlist +server=/osm.org/127.0.0.1#5335 +ipset=/osm.org/gfwlist +server=/me-gay.com/127.0.0.1#5335 +ipset=/me-gay.com/gfwlist +server=/notion.site/127.0.0.1#5335 +ipset=/notion.site/gfwlist +server=/keytransparency.foo/127.0.0.1#5335 +ipset=/keytransparency.foo/gfwlist +server=/google.ru/127.0.0.1#5335 +ipset=/google.ru/gfwlist +server=/asm.org/127.0.0.1#5335 +ipset=/asm.org/gfwlist +server=/lushstories.com/127.0.0.1#5335 +ipset=/lushstories.com/gfwlist +server=/foxcredit.org/127.0.0.1#5335 +ipset=/foxcredit.org/gfwlist +server=/applestore.com.hk/127.0.0.1#5335 +ipset=/applestore.com.hk/gfwlist +server=/google.com.gt/127.0.0.1#5335 +ipset=/google.com.gt/gfwlist +server=/charlestonroadregistry.com/127.0.0.1#5335 +ipset=/charlestonroadregistry.com/gfwlist +server=/asha.org/127.0.0.1#5335 +ipset=/asha.org/gfwlist +server=/creativesdk.com/127.0.0.1#5335 +ipset=/creativesdk.com/gfwlist +server=/airhorn.solutions/127.0.0.1#5335 +ipset=/airhorn.solutions/gfwlist +server=/bittrex.com/127.0.0.1#5335 +ipset=/bittrex.com/gfwlist +server=/cloudrobotics.com/127.0.0.1#5335 +ipset=/cloudrobotics.com/gfwlist +server=/java.net/127.0.0.1#5335 +ipset=/java.net/gfwlist +server=/pokemon-sun.com/127.0.0.1#5335 +ipset=/pokemon-sun.com/gfwlist +server=/koubaibu.jp/127.0.0.1#5335 +ipset=/koubaibu.jp/gfwlist +server=/volvobuses.de/127.0.0.1#5335 +ipset=/volvobuses.de/gfwlist +server=/easymatureporn.com/127.0.0.1#5335 +ipset=/easymatureporn.com/gfwlist +server=/extremepornfilms.com/127.0.0.1#5335 +ipset=/extremepornfilms.com/gfwlist +server=/uun99.com/127.0.0.1#5335 +ipset=/uun99.com/gfwlist +server=/ebayclassifieds.info/127.0.0.1#5335 +ipset=/ebayclassifieds.info/gfwlist +server=/manyvids.com/127.0.0.1#5335 +ipset=/manyvids.com/gfwlist +server=/gmossp-sp.jp/127.0.0.1#5335 +ipset=/gmossp-sp.jp/gfwlist +server=/pearson.cl/127.0.0.1#5335 +ipset=/pearson.cl/gfwlist +server=/epochcar.com/127.0.0.1#5335 +ipset=/epochcar.com/gfwlist +server=/lululu.one/127.0.0.1#5335 +ipset=/lululu.one/gfwlist +server=/cinemax.com/127.0.0.1#5335 +ipset=/cinemax.com/gfwlist +server=/whatisairwatch.com/127.0.0.1#5335 +ipset=/whatisairwatch.com/gfwlist +server=/pvzgw2.com/127.0.0.1#5335 +ipset=/pvzgw2.com/gfwlist +server=/1e100.net/127.0.0.1#5335 +ipset=/1e100.net/gfwlist +server=/dlsitestudio.com/127.0.0.1#5335 +ipset=/dlsitestudio.com/gfwlist +server=/dettol.net/127.0.0.1#5335 +ipset=/dettol.net/gfwlist +server=/nike-fr.com/127.0.0.1#5335 +ipset=/nike-fr.com/gfwlist +server=/tedcdn.com/127.0.0.1#5335 +ipset=/tedcdn.com/gfwlist +server=/youtube.com.ua/127.0.0.1#5335 +ipset=/youtube.com.ua/gfwlist +server=/vsezoo.com/127.0.0.1#5335 +ipset=/vsezoo.com/gfwlist +server=/intunewiki.com/127.0.0.1#5335 +ipset=/intunewiki.com/gfwlist +server=/erotic-hentai.com/127.0.0.1#5335 +ipset=/erotic-hentai.com/gfwlist +server=/beatsdreforsale.com/127.0.0.1#5335 +ipset=/beatsdreforsale.com/gfwlist +server=/bmw-driving-center.co.kr/127.0.0.1#5335 +ipset=/bmw-driving-center.co.kr/gfwlist +server=/intel.dz/127.0.0.1#5335 +ipset=/intel.dz/gfwlist +server=/conair.me/127.0.0.1#5335 +ipset=/conair.me/gfwlist +server=/cloudyzgirl.com/127.0.0.1#5335 +ipset=/cloudyzgirl.com/gfwlist +server=/applewatch.tv/127.0.0.1#5335 +ipset=/applewatch.tv/gfwlist +server=/hkt-enterprise.com/127.0.0.1#5335 +ipset=/hkt-enterprise.com/gfwlist +server=/nvidia.it/127.0.0.1#5335 +ipset=/nvidia.it/gfwlist +server=/welcomix.com/127.0.0.1#5335 +ipset=/welcomix.com/gfwlist +server=/cispaletter.com/127.0.0.1#5335 +ipset=/cispaletter.com/gfwlist +server=/drdrebeatsuk.com/127.0.0.1#5335 +ipset=/drdrebeatsuk.com/gfwlist +server=/volvotrucks.tn/127.0.0.1#5335 +ipset=/volvotrucks.tn/gfwlist +server=/adbecrsl.com/127.0.0.1#5335 +ipset=/adbecrsl.com/gfwlist +server=/newscorp.com/127.0.0.1#5335 +ipset=/newscorp.com/gfwlist +server=/paypal-profile.com/127.0.0.1#5335 +ipset=/paypal-profile.com/gfwlist +server=/vfsco.bg/127.0.0.1#5335 +ipset=/vfsco.bg/gfwlist +server=/quiksee.com/127.0.0.1#5335 +ipset=/quiksee.com/gfwlist +server=/awsstatic.com/127.0.0.1#5335 +ipset=/awsstatic.com/gfwlist +server=/bmw.md/127.0.0.1#5335 +ipset=/bmw.md/gfwlist +server=/facebookdating.net/127.0.0.1#5335 +ipset=/facebookdating.net/gfwlist +server=/62fh1bnj.me/127.0.0.1#5335 +ipset=/62fh1bnj.me/gfwlist +server=/porngladiator.com/127.0.0.1#5335 +ipset=/porngladiator.com/gfwlist +server=/cfake.com/127.0.0.1#5335 +ipset=/cfake.com/gfwlist +server=/myxxgirl.com/127.0.0.1#5335 +ipset=/myxxgirl.com/gfwlist +server=/dmed.technology/127.0.0.1#5335 +ipset=/dmed.technology/gfwlist +server=/cricketcountry.com/127.0.0.1#5335 +ipset=/cricketcountry.com/gfwlist +server=/pinterest.ru/127.0.0.1#5335 +ipset=/pinterest.ru/gfwlist +server=/peoplenews.tw/127.0.0.1#5335 +ipset=/peoplenews.tw/gfwlist +server=/ikea.com.my/127.0.0.1#5335 +ipset=/ikea.com.my/gfwlist +server=/naturemag.org/127.0.0.1#5335 +ipset=/naturemag.org/gfwlist +server=/intel.tv/127.0.0.1#5335 +ipset=/intel.tv/gfwlist +server=/steamserver.net/127.0.0.1#5335 +ipset=/steamserver.net/gfwlist +server=/realcuckoldsex.com/127.0.0.1#5335 +ipset=/realcuckoldsex.com/gfwlist +server=/torproject.org/127.0.0.1#5335 +ipset=/torproject.org/gfwlist +server=/narumiya.xii.jp/127.0.0.1#5335 +ipset=/narumiya.xii.jp/gfwlist +server=/daytonbmw.com/127.0.0.1#5335 +ipset=/daytonbmw.com/gfwlist +server=/netflixdnstest5.com/127.0.0.1#5335 +ipset=/netflixdnstest5.com/gfwlist +server=/nude-pics.org/127.0.0.1#5335 +ipset=/nude-pics.org/gfwlist +server=/applepay.jp/127.0.0.1#5335 +ipset=/applepay.jp/gfwlist +server=/jav321.com/127.0.0.1#5335 +ipset=/jav321.com/gfwlist +server=/finish.lv/127.0.0.1#5335 +ipset=/finish.lv/gfwlist +server=/fbinfer.com/127.0.0.1#5335 +ipset=/fbinfer.com/gfwlist +server=/amateurcuckoldporn.com/127.0.0.1#5335 +ipset=/amateurcuckoldporn.com/gfwlist +server=/bareporno.com/127.0.0.1#5335 +ipset=/bareporno.com/gfwlist +server=/keyporntube.com/127.0.0.1#5335 +ipset=/keyporntube.com/gfwlist +server=/snap-dev.net/127.0.0.1#5335 +ipset=/snap-dev.net/gfwlist +server=/researchkit.net/127.0.0.1#5335 +ipset=/researchkit.net/gfwlist +server=/sokmil.com/127.0.0.1#5335 +ipset=/sokmil.com/gfwlist +server=/telesec.de/127.0.0.1#5335 +ipset=/telesec.de/gfwlist +server=/mastercard.com/127.0.0.1#5335 +ipset=/mastercard.com/gfwlist +server=/insiderintelligence.com/127.0.0.1#5335 +ipset=/insiderintelligence.com/gfwlist +server=/bridgestonemarketing.com/127.0.0.1#5335 +ipset=/bridgestonemarketing.com/gfwlist +server=/amatporn.com/127.0.0.1#5335 +ipset=/amatporn.com/gfwlist +server=/connectcommerce.info/127.0.0.1#5335 +ipset=/connectcommerce.info/gfwlist +server=/shit-porn.net/127.0.0.1#5335 +ipset=/shit-porn.net/gfwlist +server=/bmw-ghana.com/127.0.0.1#5335 +ipset=/bmw-ghana.com/gfwlist +server=/microsoftads.com/127.0.0.1#5335 +ipset=/microsoftads.com/gfwlist +server=/lolclub.org/127.0.0.1#5335 +ipset=/lolclub.org/gfwlist +server=/vanish.at/127.0.0.1#5335 +ipset=/vanish.at/gfwlist +server=/gfycat.com/127.0.0.1#5335 +ipset=/gfycat.com/gfwlist +server=/google.be/127.0.0.1#5335 +ipset=/google.be/gfwlist +server=/magicalmirai.com/127.0.0.1#5335 +ipset=/magicalmirai.com/gfwlist +server=/vfsco.lv/127.0.0.1#5335 +ipset=/vfsco.lv/gfwlist +server=/oann.com/127.0.0.1#5335 +ipset=/oann.com/gfwlist +server=/smartonesolutions.com.hk/127.0.0.1#5335 +ipset=/smartonesolutions.com.hk/gfwlist +server=/coolloud.org.tw/127.0.0.1#5335 +ipset=/coolloud.org.tw/gfwlist +server=/pittpatt.com/127.0.0.1#5335 +ipset=/pittpatt.com/gfwlist +server=/yourfreeporn.tv/127.0.0.1#5335 +ipset=/yourfreeporn.tv/gfwlist +server=/kmc-av.com/127.0.0.1#5335 +ipset=/kmc-av.com/gfwlist +server=/blackfridaydrebeatsshop.com/127.0.0.1#5335 +ipset=/blackfridaydrebeatsshop.com/gfwlist +server=/zdusercontent.com/127.0.0.1#5335 +ipset=/zdusercontent.com/gfwlist +server=/kindleoasis.info/127.0.0.1#5335 +ipset=/kindleoasis.info/gfwlist +server=/pornhat.com/127.0.0.1#5335 +ipset=/pornhat.com/gfwlist +server=/youtube.com.ng/127.0.0.1#5335 +ipset=/youtube.com.ng/gfwlist +server=/exxxtrasmall1.com/127.0.0.1#5335 +ipset=/exxxtrasmall1.com/gfwlist +server=/vmwdemo.com/127.0.0.1#5335 +ipset=/vmwdemo.com/gfwlist +server=/facebzook.com/127.0.0.1#5335 +ipset=/facebzook.com/gfwlist +server=/renderos.com/127.0.0.1#5335 +ipset=/renderos.com/gfwlist +server=/thomsonreuters.com.my/127.0.0.1#5335 +ipset=/thomsonreuters.com.my/gfwlist +server=/putty.org/127.0.0.1#5335 +ipset=/putty.org/gfwlist +server=/voahausa.com/127.0.0.1#5335 +ipset=/voahausa.com/gfwlist +server=/porndeepfake.net/127.0.0.1#5335 +ipset=/porndeepfake.net/gfwlist +server=/apple-mapkit.com/127.0.0.1#5335 +ipset=/apple-mapkit.com/gfwlist +server=/moxing.news/127.0.0.1#5335 +ipset=/moxing.news/gfwlist +server=/nekoxxx.com/127.0.0.1#5335 +ipset=/nekoxxx.com/gfwlist +server=/fei.ru/127.0.0.1#5335 +ipset=/fei.ru/gfwlist +server=/applecomputer.hu/127.0.0.1#5335 +ipset=/applecomputer.hu/gfwlist +server=/iphone.com/127.0.0.1#5335 +ipset=/iphone.com/gfwlist +server=/mdpi.com/127.0.0.1#5335 +ipset=/mdpi.com/gfwlist +server=/nginx.org/127.0.0.1#5335 +ipset=/nginx.org/gfwlist +server=/sexanime.net/127.0.0.1#5335 +ipset=/sexanime.net/gfwlist +server=/artstationmedia.com/127.0.0.1#5335 +ipset=/artstationmedia.com/gfwlist +server=/bridgestone.com.br/127.0.0.1#5335 +ipset=/bridgestone.com.br/gfwlist +server=/google.com.bn/127.0.0.1#5335 +ipset=/google.com.bn/gfwlist +server=/shopdisney.com/127.0.0.1#5335 +ipset=/shopdisney.com/gfwlist +server=/foxsports.net/127.0.0.1#5335 +ipset=/foxsports.net/gfwlist +server=/beatsep.com/127.0.0.1#5335 +ipset=/beatsep.com/gfwlist +server=/paypal-merchantloyalty.com/127.0.0.1#5335 +ipset=/paypal-merchantloyalty.com/gfwlist +server=/atwiki.jp/127.0.0.1#5335 +ipset=/atwiki.jp/gfwlist +server=/bmw-connecteddrive.pt/127.0.0.1#5335 +ipset=/bmw-connecteddrive.pt/gfwlist +server=/nikeonlinestore.com/127.0.0.1#5335 +ipset=/nikeonlinestore.com/gfwlist +server=/mastercard.com.sa/127.0.0.1#5335 +ipset=/mastercard.com.sa/gfwlist +server=/amateuralbum.net/127.0.0.1#5335 +ipset=/amateuralbum.net/gfwlist +server=/xvxxtube.com/127.0.0.1#5335 +ipset=/xvxxtube.com/gfwlist +server=/bucketeer.jp/127.0.0.1#5335 +ipset=/bucketeer.jp/gfwlist +server=/logitechio.com.cn/127.0.0.1#5335 +ipset=/logitechio.com.cn/gfwlist +server=/ikea.hu/127.0.0.1#5335 +ipset=/ikea.hu/gfwlist +server=/edge-skype-com.s-0001.s-msedge.net/127.0.0.1#5335 +ipset=/edge-skype-com.s-0001.s-msedge.net/gfwlist +server=/sexgalaxy.net/127.0.0.1#5335 +ipset=/sexgalaxy.net/gfwlist +server=/jstage.jst.go.jp/127.0.0.1#5335 +ipset=/jstage.jst.go.jp/gfwlist +server=/amateurblowjobporn.com/127.0.0.1#5335 +ipset=/amateurblowjobporn.com/gfwlist +server=/watchteencam.com/127.0.0.1#5335 +ipset=/watchteencam.com/gfwlist +server=/facebookawards.com/127.0.0.1#5335 +ipset=/facebookawards.com/gfwlist +server=/cloudflare-dns.com/127.0.0.1#5335 +ipset=/cloudflare-dns.com/gfwlist +server=/porngeek.com/127.0.0.1#5335 +ipset=/porngeek.com/gfwlist +server=/bmwgroup-posdigital.com/127.0.0.1#5335 +ipset=/bmwgroup-posdigital.com/gfwlist +server=/bridgestone.com.mx/127.0.0.1#5335 +ipset=/bridgestone.com.mx/gfwlist +server=/hqtube.xxx/127.0.0.1#5335 +ipset=/hqtube.xxx/gfwlist +server=/deutschsex.com/127.0.0.1#5335 +ipset=/deutschsex.com/gfwlist +server=/hidive.com/127.0.0.1#5335 +ipset=/hidive.com/gfwlist +server=/lolusercontent.com/127.0.0.1#5335 +ipset=/lolusercontent.com/gfwlist +server=/ikea.co.at/127.0.0.1#5335 +ipset=/ikea.co.at/gfwlist +server=/pinterest.co.uk/127.0.0.1#5335 +ipset=/pinterest.co.uk/gfwlist +server=/volvotrucks.com.ua/127.0.0.1#5335 +ipset=/volvotrucks.com.ua/gfwlist +server=/wrenchead.com/127.0.0.1#5335 +ipset=/wrenchead.com/gfwlist +server=/1337x.is/127.0.0.1#5335 +ipset=/1337x.is/gfwlist +server=/mariokart8.com/127.0.0.1#5335 +ipset=/mariokart8.com/gfwlist +server=/bangher.net/127.0.0.1#5335 +ipset=/bangher.net/gfwlist +server=/cnbetacdn.com/127.0.0.1#5335 +ipset=/cnbetacdn.com/gfwlist +server=/pearsonassessment.dk/127.0.0.1#5335 +ipset=/pearsonassessment.dk/gfwlist +server=/bloombergbeta.com/127.0.0.1#5335 +ipset=/bloombergbeta.com/gfwlist +server=/gittigidiyor.net/127.0.0.1#5335 +ipset=/gittigidiyor.net/gfwlist +server=/pricelessarabia.com/127.0.0.1#5335 +ipset=/pricelessarabia.com/gfwlist +server=/booksinprint.com/127.0.0.1#5335 +ipset=/booksinprint.com/gfwlist +server=/letsencrypt.org/127.0.0.1#5335 +ipset=/letsencrypt.org/gfwlist +server=/toppornsites.net/127.0.0.1#5335 +ipset=/toppornsites.net/gfwlist +server=/visa.com.bs/127.0.0.1#5335 +ipset=/visa.com.bs/gfwlist +server=/morisawa.co.jp/127.0.0.1#5335 +ipset=/morisawa.co.jp/gfwlist +server=/nikeaw77.com/127.0.0.1#5335 +ipset=/nikeaw77.com/gfwlist +server=/cordcloud.org/127.0.0.1#5335 +ipset=/cordcloud.org/gfwlist +server=/igkbroker.com/127.0.0.1#5335 +ipset=/igkbroker.com/gfwlist +server=/omotenashi.cygames.jp/127.0.0.1#5335 +ipset=/omotenashi.cygames.jp/gfwlist +server=/blogspot.al/127.0.0.1#5335 +ipset=/blogspot.al/gfwlist +server=/myfoxzone.com/127.0.0.1#5335 +ipset=/myfoxzone.com/gfwlist +server=/nvidia.be/127.0.0.1#5335 +ipset=/nvidia.be/gfwlist +server=/playwarcraft3.com/127.0.0.1#5335 +ipset=/playwarcraft3.com/gfwlist +server=/bbhub.io/127.0.0.1#5335 +ipset=/bbhub.io/gfwlist +server=/vercel.store/127.0.0.1#5335 +ipset=/vercel.store/gfwlist +server=/google.co.il/127.0.0.1#5335 +ipset=/google.co.il/gfwlist +server=/hegre.com/127.0.0.1#5335 +ipset=/hegre.com/gfwlist +server=/enfagrow.com.bn/127.0.0.1#5335 +ipset=/enfagrow.com.bn/gfwlist +server=/pornwild.to/127.0.0.1#5335 +ipset=/pornwild.to/gfwlist +server=/nicodic.jp/127.0.0.1#5335 +ipset=/nicodic.jp/gfwlist +server=/justporno.es/127.0.0.1#5335 +ipset=/justporno.es/gfwlist +server=/kindle.de/127.0.0.1#5335 +ipset=/kindle.de/gfwlist +server=/yahoo.bi/127.0.0.1#5335 +ipset=/yahoo.bi/gfwlist +server=/amazon.ae/127.0.0.1#5335 +ipset=/amazon.ae/gfwlist +server=/mageconf.com/127.0.0.1#5335 +ipset=/mageconf.com/gfwlist +server=/voatiengviet.com/127.0.0.1#5335 +ipset=/voatiengviet.com/gfwlist +server=/boylove1.cc/127.0.0.1#5335 +ipset=/boylove1.cc/gfwlist +server=/latencytop.com/127.0.0.1#5335 +ipset=/latencytop.com/gfwlist +server=/alexa.com/127.0.0.1#5335 +ipset=/alexa.com/gfwlist +server=/porncana.com/127.0.0.1#5335 +ipset=/porncana.com/gfwlist +server=/shopee.vn/127.0.0.1#5335 +ipset=/shopee.vn/gfwlist +server=/hentaistube.com/127.0.0.1#5335 +ipset=/hentaistube.com/gfwlist +server=/seniortgp.com/127.0.0.1#5335 +ipset=/seniortgp.com/gfwlist +server=/wikinews.org/127.0.0.1#5335 +ipset=/wikinews.org/gfwlist +server=/gettyimages.com.mx/127.0.0.1#5335 +ipset=/gettyimages.com.mx/gfwlist +server=/3movs.com/127.0.0.1#5335 +ipset=/3movs.com/gfwlist +server=/geeksquadonline.com/127.0.0.1#5335 +ipset=/geeksquadonline.com/gfwlist +server=/alphera-finance.com.hk/127.0.0.1#5335 +ipset=/alphera-finance.com.hk/gfwlist +server=/hustler.com/127.0.0.1#5335 +ipset=/hustler.com/gfwlist +server=/openstreetmaps.org/127.0.0.1#5335 +ipset=/openstreetmaps.org/gfwlist +server=/launchpad.net/127.0.0.1#5335 +ipset=/launchpad.net/gfwlist +server=/ikea.pt/127.0.0.1#5335 +ipset=/ikea.pt/gfwlist +server=/blacktowhite.net/127.0.0.1#5335 +ipset=/blacktowhite.net/gfwlist +server=/youtube.ee/127.0.0.1#5335 +ipset=/youtube.ee/gfwlist +server=/hddirectv.com/127.0.0.1#5335 +ipset=/hddirectv.com/gfwlist +server=/visa.com.jm/127.0.0.1#5335 +ipset=/visa.com.jm/gfwlist +server=/justporno.sex/127.0.0.1#5335 +ipset=/justporno.sex/gfwlist +server=/pornoweb.win/127.0.0.1#5335 +ipset=/pornoweb.win/gfwlist +server=/battlefieldbadcompany2.com/127.0.0.1#5335 +ipset=/battlefieldbadcompany2.com/gfwlist +server=/adobeexchange.com/127.0.0.1#5335 +ipset=/adobeexchange.com/gfwlist +server=/localizejs.com/127.0.0.1#5335 +ipset=/localizejs.com/gfwlist +server=/bmworegon.com/127.0.0.1#5335 +ipset=/bmworegon.com/gfwlist +server=/pcre.org/127.0.0.1#5335 +ipset=/pcre.org/gfwlist +server=/ilove-movies.com/127.0.0.1#5335 +ipset=/ilove-movies.com/gfwlist +server=/applescreensavers.com/127.0.0.1#5335 +ipset=/applescreensavers.com/gfwlist +server=/hentailegendado.com/127.0.0.1#5335 +ipset=/hentailegendado.com/gfwlist +server=/xn--x-qeu1ji09tzlg.biz/127.0.0.1#5335 +ipset=/xn--x-qeu1ji09tzlg.biz/gfwlist +server=/instagramkusu.com/127.0.0.1#5335 +ipset=/instagramkusu.com/gfwlist +server=/nikefoundation.org/127.0.0.1#5335 +ipset=/nikefoundation.org/gfwlist +server=/vercel-status.com/127.0.0.1#5335 +ipset=/vercel-status.com/gfwlist +server=/qzav.tv/127.0.0.1#5335 +ipset=/qzav.tv/gfwlist +server=/hdtube1.com/127.0.0.1#5335 +ipset=/hdtube1.com/gfwlist +server=/bmw-connecteddrive.ro/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ro/gfwlist +server=/mybeatsbydrestudio.com/127.0.0.1#5335 +ipset=/mybeatsbydrestudio.com/gfwlist +server=/beatsbydrdrecustom.com/127.0.0.1#5335 +ipset=/beatsbydrdrecustom.com/gfwlist +server=/metropolitana.tokyo/127.0.0.1#5335 +ipset=/metropolitana.tokyo/gfwlist +server=/gimy.co/127.0.0.1#5335 +ipset=/gimy.co/gfwlist +server=/e-bay.com/127.0.0.1#5335 +ipset=/e-bay.com/gfwlist +server=/gannett-cdn.com/127.0.0.1#5335 +ipset=/gannett-cdn.com/gfwlist +server=/vol.moe/127.0.0.1#5335 +ipset=/vol.moe/gfwlist +server=/razer.com/127.0.0.1#5335 +ipset=/razer.com/gfwlist +server=/nurofen.hr/127.0.0.1#5335 +ipset=/nurofen.hr/gfwlist +server=/xiaofu.me/127.0.0.1#5335 +ipset=/xiaofu.me/gfwlist +server=/jneurosci.org/127.0.0.1#5335 +ipset=/jneurosci.org/gfwlist +server=/paypal-gifts.com/127.0.0.1#5335 +ipset=/paypal-gifts.com/gfwlist +server=/yahoofinance.com/127.0.0.1#5335 +ipset=/yahoofinance.com/gfwlist +server=/voxops.net/127.0.0.1#5335 +ipset=/voxops.net/gfwlist +server=/okex.com/127.0.0.1#5335 +ipset=/okex.com/gfwlist +server=/rustup.rs/127.0.0.1#5335 +ipset=/rustup.rs/gfwlist +server=/teenporntube.xxx/127.0.0.1#5335 +ipset=/teenporntube.xxx/gfwlist +server=/iphonecase5.com/127.0.0.1#5335 +ipset=/iphonecase5.com/gfwlist +server=/akamai-cdn.com/127.0.0.1#5335 +ipset=/akamai-cdn.com/gfwlist +server=/iqq3.cc/127.0.0.1#5335 +ipset=/iqq3.cc/gfwlist +server=/extrajapaneseporn.com/127.0.0.1#5335 +ipset=/extrajapaneseporn.com/gfwlist +server=/bydrebeats.com/127.0.0.1#5335 +ipset=/bydrebeats.com/gfwlist +server=/pagecdn.io/127.0.0.1#5335 +ipset=/pagecdn.io/gfwlist +server=/facebookcareer.com/127.0.0.1#5335 +ipset=/facebookcareer.com/gfwlist +server=/mastercard.cl/127.0.0.1#5335 +ipset=/mastercard.cl/gfwlist +server=/componentkit.org/127.0.0.1#5335 +ipset=/componentkit.org/gfwlist +server=/mywife.cc/127.0.0.1#5335 +ipset=/mywife.cc/gfwlist +server=/facebook.nl/127.0.0.1#5335 +ipset=/facebook.nl/gfwlist +server=/keytransparency.com/127.0.0.1#5335 +ipset=/keytransparency.com/gfwlist +server=/wwwxoom.com/127.0.0.1#5335 +ipset=/wwwxoom.com/gfwlist +server=/amd.com/127.0.0.1#5335 +ipset=/amd.com/gfwlist +server=/japteenx.com/127.0.0.1#5335 +ipset=/japteenx.com/gfwlist +server=/hulucall.com/127.0.0.1#5335 +ipset=/hulucall.com/gfwlist +server=/microsoftonline.com/127.0.0.1#5335 +ipset=/microsoftonline.com/gfwlist +server=/graiasmovies.com/127.0.0.1#5335 +ipset=/graiasmovies.com/gfwlist +server=/nikeidshoes.com/127.0.0.1#5335 +ipset=/nikeidshoes.com/gfwlist +server=/google.rs/127.0.0.1#5335 +ipset=/google.rs/gfwlist +server=/myfoxny.com/127.0.0.1#5335 +ipset=/myfoxny.com/gfwlist +server=/xvideos.tv.br/127.0.0.1#5335 +ipset=/xvideos.tv.br/gfwlist +server=/foxnews.tv/127.0.0.1#5335 +ipset=/foxnews.tv/gfwlist +server=/hongmaodan100.com/127.0.0.1#5335 +ipset=/hongmaodan100.com/gfwlist +server=/topbeatsforsale.com/127.0.0.1#5335 +ipset=/topbeatsforsale.com/gfwlist +server=/pearsonperu.pe/127.0.0.1#5335 +ipset=/pearsonperu.pe/gfwlist +server=/gayrawclub.com/127.0.0.1#5335 +ipset=/gayrawclub.com/gfwlist +server=/chromebook.com/127.0.0.1#5335 +ipset=/chromebook.com/gfwlist +server=/newsconcierge.com.au/127.0.0.1#5335 +ipset=/newsconcierge.com.au/gfwlist +server=/velkaepocha.cz/127.0.0.1#5335 +ipset=/velkaepocha.cz/gfwlist +server=/homo.xxx/127.0.0.1#5335 +ipset=/homo.xxx/gfwlist +server=/mini.re/127.0.0.1#5335 +ipset=/mini.re/gfwlist +server=/ieeemagnetics.org/127.0.0.1#5335 +ipset=/ieeemagnetics.org/gfwlist +server=/halfjapan.com/127.0.0.1#5335 +ipset=/halfjapan.com/gfwlist +server=/outlook.com/127.0.0.1#5335 +ipset=/outlook.com/gfwlist +server=/filmeporno.blog/127.0.0.1#5335 +ipset=/filmeporno.blog/gfwlist +server=/xxbook.cc/127.0.0.1#5335 +ipset=/xxbook.cc/gfwlist +server=/huffingtonpost.gr/127.0.0.1#5335 +ipset=/huffingtonpost.gr/gfwlist +server=/592r.com/127.0.0.1#5335 +ipset=/592r.com/gfwlist +server=/beatsbydreauofficial.com/127.0.0.1#5335 +ipset=/beatsbydreauofficial.com/gfwlist +server=/cuckwatchingwife.com/127.0.0.1#5335 +ipset=/cuckwatchingwife.com/gfwlist +server=/cockofhorse.com/127.0.0.1#5335 +ipset=/cockofhorse.com/gfwlist +server=/nutaku.com/127.0.0.1#5335 +ipset=/nutaku.com/gfwlist +server=/mature-nl.eu/127.0.0.1#5335 +ipset=/mature-nl.eu/gfwlist +server=/paypalnetwork.info/127.0.0.1#5335 +ipset=/paypalnetwork.info/gfwlist +server=/azadiradio.com/127.0.0.1#5335 +ipset=/azadiradio.com/gfwlist +server=/anaconda.com/127.0.0.1#5335 +ipset=/anaconda.com/gfwlist +server=/affirmtrust.com/127.0.0.1#5335 +ipset=/affirmtrust.com/gfwlist +server=/microsoft.fi/127.0.0.1#5335 +ipset=/microsoft.fi/gfwlist +server=/iphone4.com.br/127.0.0.1#5335 +ipset=/iphone4.com.br/gfwlist +server=/tyler-brown.com/127.0.0.1#5335 +ipset=/tyler-brown.com/gfwlist +server=/buypass.com/127.0.0.1#5335 +ipset=/buypass.com/gfwlist +server=/uplust.com/127.0.0.1#5335 +ipset=/uplust.com/gfwlist +server=/nvidia.asia/127.0.0.1#5335 +ipset=/nvidia.asia/gfwlist +server=/teendreams.com/127.0.0.1#5335 +ipset=/teendreams.com/gfwlist +server=/longman.ch/127.0.0.1#5335 +ipset=/longman.ch/gfwlist +server=/starbucks.com.gr/127.0.0.1#5335 +ipset=/starbucks.com.gr/gfwlist +server=/fout.jp/127.0.0.1#5335 +ipset=/fout.jp/gfwlist +server=/google.com.tw/127.0.0.1#5335 +ipset=/google.com.tw/gfwlist +server=/intel.ch/127.0.0.1#5335 +ipset=/intel.ch/gfwlist +server=/apa.org/127.0.0.1#5335 +ipset=/apa.org/gfwlist +server=/strikingly.com/127.0.0.1#5335 +ipset=/strikingly.com/gfwlist +server=/yahoo.tl/127.0.0.1#5335 +ipset=/yahoo.tl/gfwlist +server=/xiaogirls.com/127.0.0.1#5335 +ipset=/xiaogirls.com/gfwlist +server=/cargigileads.com/127.0.0.1#5335 +ipset=/cargigileads.com/gfwlist +server=/google.com.kh/127.0.0.1#5335 +ipset=/google.com.kh/gfwlist +server=/coinonecorp.com/127.0.0.1#5335 +ipset=/coinonecorp.com/gfwlist +server=/javfuck.net/127.0.0.1#5335 +ipset=/javfuck.net/gfwlist +server=/iskoot.com/127.0.0.1#5335 +ipset=/iskoot.com/gfwlist +server=/2o7.net/127.0.0.1#5335 +ipset=/2o7.net/gfwlist +server=/scholar.google.com.vn/127.0.0.1#5335 +ipset=/scholar.google.com.vn/gfwlist +server=/comments.app/127.0.0.1#5335 +ipset=/comments.app/gfwlist +server=/thebanker.com/127.0.0.1#5335 +ipset=/thebanker.com/gfwlist +server=/skysports.com/127.0.0.1#5335 +ipset=/skysports.com/gfwlist +server=/freenode.net/127.0.0.1#5335 +ipset=/freenode.net/gfwlist +server=/mini.ru/127.0.0.1#5335 +ipset=/mini.ru/gfwlist +server=/1lib.cloud/127.0.0.1#5335 +ipset=/1lib.cloud/gfwlist +server=/supadou.blogism.jp/127.0.0.1#5335 +ipset=/supadou.blogism.jp/gfwlist +server=/maddenrewards.com/127.0.0.1#5335 +ipset=/maddenrewards.com/gfwlist +server=/freyalist.com/127.0.0.1#5335 +ipset=/freyalist.com/gfwlist +server=/naughty.com/127.0.0.1#5335 +ipset=/naughty.com/gfwlist +server=/sacduc.com/127.0.0.1#5335 +ipset=/sacduc.com/gfwlist +server=/nypost.help/127.0.0.1#5335 +ipset=/nypost.help/gfwlist +server=/17mimei.club/127.0.0.1#5335 +ipset=/17mimei.club/gfwlist +server=/pornotube69.nl/127.0.0.1#5335 +ipset=/pornotube69.nl/gfwlist +server=/visa.be/127.0.0.1#5335 +ipset=/visa.be/gfwlist +server=/musical.ly/127.0.0.1#5335 +ipset=/musical.ly/gfwlist +server=/app0le.com/127.0.0.1#5335 +ipset=/app0le.com/gfwlist +server=/gaytube.com/127.0.0.1#5335 +ipset=/gaytube.com/gfwlist +server=/delicious.com.au/127.0.0.1#5335 +ipset=/delicious.com.au/gfwlist +server=/facebook-studio.com/127.0.0.1#5335 +ipset=/facebook-studio.com/gfwlist +server=/macreach.com/127.0.0.1#5335 +ipset=/macreach.com/gfwlist +server=/naughtygamesource.com/127.0.0.1#5335 +ipset=/naughtygamesource.com/gfwlist +server=/blogspot.co.uk/127.0.0.1#5335 +ipset=/blogspot.co.uk/gfwlist +server=/minecraft.net/127.0.0.1#5335 +ipset=/minecraft.net/gfwlist +server=/androidify.com/127.0.0.1#5335 +ipset=/androidify.com/gfwlist +server=/bmw-motorrad.be/127.0.0.1#5335 +ipset=/bmw-motorrad.be/gfwlist +server=/vs-hls-push-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vs-hls-push-uk-live.akamaized.net/gfwlist +server=/foxsmallbusinesscenter.com/127.0.0.1#5335 +ipset=/foxsmallbusinesscenter.com/gfwlist +server=/nikesellorder.com/127.0.0.1#5335 +ipset=/nikesellorder.com/gfwlist +server=/asianscreens.com/127.0.0.1#5335 +ipset=/asianscreens.com/gfwlist +server=/jmcomic1.city/127.0.0.1#5335 +ipset=/jmcomic1.city/gfwlist +server=/twistys.com/127.0.0.1#5335 +ipset=/twistys.com/gfwlist +server=/deutschepornos-kostenlos.net/127.0.0.1#5335 +ipset=/deutschepornos-kostenlos.net/gfwlist +server=/sdcountybmw.com/127.0.0.1#5335 +ipset=/sdcountybmw.com/gfwlist +server=/bmw-classic.com/127.0.0.1#5335 +ipset=/bmw-classic.com/gfwlist +server=/heptio.com/127.0.0.1#5335 +ipset=/heptio.com/gfwlist +server=/visa.co.nz/127.0.0.1#5335 +ipset=/visa.co.nz/gfwlist +server=/libgen.me/127.0.0.1#5335 +ipset=/libgen.me/gfwlist +server=/bmw.hu/127.0.0.1#5335 +ipset=/bmw.hu/gfwlist +server=/xn--mtswd61ejxq.com/127.0.0.1#5335 +ipset=/xn--mtswd61ejxq.com/gfwlist +server=/terapeak.hk/127.0.0.1#5335 +ipset=/terapeak.hk/gfwlist +server=/favepornvids.com/127.0.0.1#5335 +ipset=/favepornvids.com/gfwlist +server=/ted.com/127.0.0.1#5335 +ipset=/ted.com/gfwlist +server=/nikebbn.com/127.0.0.1#5335 +ipset=/nikebbn.com/gfwlist +server=/oed.com/127.0.0.1#5335 +ipset=/oed.com/gfwlist +server=/apple-cloudkit.com/127.0.0.1#5335 +ipset=/apple-cloudkit.com/gfwlist +server=/bmw.hn/127.0.0.1#5335 +ipset=/bmw.hn/gfwlist +server=/povpornonly.com/127.0.0.1#5335 +ipset=/povpornonly.com/gfwlist +server=/mylust.com/127.0.0.1#5335 +ipset=/mylust.com/gfwlist +server=/reiporno.com/127.0.0.1#5335 +ipset=/reiporno.com/gfwlist +server=/asiansex.sexy/127.0.0.1#5335 +ipset=/asiansex.sexy/gfwlist +server=/vfsco.es/127.0.0.1#5335 +ipset=/vfsco.es/gfwlist +server=/pearsoneducacion.net/127.0.0.1#5335 +ipset=/pearsoneducacion.net/gfwlist +server=/apple.nl/127.0.0.1#5335 +ipset=/apple.nl/gfwlist +server=/brightcove.net/127.0.0.1#5335 +ipset=/brightcove.net/gfwlist +server=/boshancy.com/127.0.0.1#5335 +ipset=/boshancy.com/gfwlist +server=/facebookexchange.com/127.0.0.1#5335 +ipset=/facebookexchange.com/gfwlist +server=/xnxx.health/127.0.0.1#5335 +ipset=/xnxx.health/gfwlist +server=/adult-web-site.net/127.0.0.1#5335 +ipset=/adult-web-site.net/gfwlist +server=/zzgays.com/127.0.0.1#5335 +ipset=/zzgays.com/gfwlist +server=/beatsbydreirelandonlines.com/127.0.0.1#5335 +ipset=/beatsbydreirelandonlines.com/gfwlist +server=/hentaia.net/127.0.0.1#5335 +ipset=/hentaia.net/gfwlist +server=/google.co.th/127.0.0.1#5335 +ipset=/google.co.th/gfwlist +server=/adidas.pl/127.0.0.1#5335 +ipset=/adidas.pl/gfwlist +server=/google.la/127.0.0.1#5335 +ipset=/google.la/gfwlist +server=/teenporngallery.net/127.0.0.1#5335 +ipset=/teenporngallery.net/gfwlist +server=/bigblackdicklover.com/127.0.0.1#5335 +ipset=/bigblackdicklover.com/gfwlist +server=/miniinvasion.ca/127.0.0.1#5335 +ipset=/miniinvasion.ca/gfwlist +server=/intel.ca/127.0.0.1#5335 +ipset=/intel.ca/gfwlist +server=/erofus.com/127.0.0.1#5335 +ipset=/erofus.com/gfwlist +server=/novinhagostosa10.com/127.0.0.1#5335 +ipset=/novinhagostosa10.com/gfwlist +server=/mirrormedia.mg/127.0.0.1#5335 +ipset=/mirrormedia.mg/gfwlist +server=/pearsonactivelearn.com/127.0.0.1#5335 +ipset=/pearsonactivelearn.com/gfwlist +server=/linotype.com/127.0.0.1#5335 +ipset=/linotype.com/gfwlist +server=/bmw-motorrad.bh/127.0.0.1#5335 +ipset=/bmw-motorrad.bh/gfwlist +server=/pantswalker.net/127.0.0.1#5335 +ipset=/pantswalker.net/gfwlist +server=/alphera.ie/127.0.0.1#5335 +ipset=/alphera.ie/gfwlist +server=/zeeuk.com/127.0.0.1#5335 +ipset=/zeeuk.com/gfwlist +server=/ve-uhd-push-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/ve-uhd-push-uk-live.akamaized.net/gfwlist +server=/glam0ur.com/127.0.0.1#5335 +ipset=/glam0ur.com/gfwlist +server=/ccav691api.com/127.0.0.1#5335 +ipset=/ccav691api.com/gfwlist +server=/bbycloud.com/127.0.0.1#5335 +ipset=/bbycloud.com/gfwlist +server=/bmw-motorrad.no/127.0.0.1#5335 +ipset=/bmw-motorrad.no/gfwlist +server=/icloudsetup.com/127.0.0.1#5335 +ipset=/icloudsetup.com/gfwlist +server=/abema.io/127.0.0.1#5335 +ipset=/abema.io/gfwlist +server=/netvigator.com/127.0.0.1#5335 +ipset=/netvigator.com/gfwlist +server=/fli8.xyz/127.0.0.1#5335 +ipset=/fli8.xyz/gfwlist +server=/erogazou-pinkline.com/127.0.0.1#5335 +ipset=/erogazou-pinkline.com/gfwlist +server=/jpg4.info/127.0.0.1#5335 +ipset=/jpg4.info/gfwlist +server=/virtualtaboo.com/127.0.0.1#5335 +ipset=/virtualtaboo.com/gfwlist +server=/netflix.com/127.0.0.1#5335 +ipset=/netflix.com/gfwlist +server=/pstorage.space/127.0.0.1#5335 +ipset=/pstorage.space/gfwlist +server=/applestoreonline.com/127.0.0.1#5335 +ipset=/applestoreonline.com/gfwlist +server=/dettolarabia.com/127.0.0.1#5335 +ipset=/dettolarabia.com/gfwlist +server=/trustwave.com/127.0.0.1#5335 +ipset=/trustwave.com/gfwlist +server=/eroyakuba.com/127.0.0.1#5335 +ipset=/eroyakuba.com/gfwlist +server=/encoretvb.com/127.0.0.1#5335 +ipset=/encoretvb.com/gfwlist +server=/grannytube.net/127.0.0.1#5335 +ipset=/grannytube.net/gfwlist +server=/eacodigos.com/127.0.0.1#5335 +ipset=/eacodigos.com/gfwlist +server=/intel.mw/127.0.0.1#5335 +ipset=/intel.mw/gfwlist +server=/porndigger.me/127.0.0.1#5335 +ipset=/porndigger.me/gfwlist +server=/slackdemo.com/127.0.0.1#5335 +ipset=/slackdemo.com/gfwlist +server=/bmw-connecteddrive.tw/127.0.0.1#5335 +ipset=/bmw-connecteddrive.tw/gfwlist +server=/charticulator.com/127.0.0.1#5335 +ipset=/charticulator.com/gfwlist +server=/7mmtv.sx/127.0.0.1#5335 +ipset=/7mmtv.sx/gfwlist +server=/yahoo.by/127.0.0.1#5335 +ipset=/yahoo.by/gfwlist +server=/cutt.ly/127.0.0.1#5335 +ipset=/cutt.ly/gfwlist +server=/mycartoonsexgames.com/127.0.0.1#5335 +ipset=/mycartoonsexgames.com/gfwlist +server=/google.com.qa/127.0.0.1#5335 +ipset=/google.com.qa/gfwlist +server=/analpornosex.com/127.0.0.1#5335 +ipset=/analpornosex.com/gfwlist +server=/asianporn.rest/127.0.0.1#5335 +ipset=/asianporn.rest/gfwlist +server=/exposedlatinas.com/127.0.0.1#5335 +ipset=/exposedlatinas.com/gfwlist +server=/swissid.ch/127.0.0.1#5335 +ipset=/swissid.ch/gfwlist +server=/ksescortclub.com/127.0.0.1#5335 +ipset=/ksescortclub.com/gfwlist +server=/applestore.com.ee/127.0.0.1#5335 +ipset=/applestore.com.ee/gfwlist +server=/tegrazone.co.kr/127.0.0.1#5335 +ipset=/tegrazone.co.kr/gfwlist +server=/drebeatsheadphones-nz.com/127.0.0.1#5335 +ipset=/drebeatsheadphones-nz.com/gfwlist +server=/ftvmilfs.com/127.0.0.1#5335 +ipset=/ftvmilfs.com/gfwlist +server=/picasa.com/127.0.0.1#5335 +ipset=/picasa.com/gfwlist +server=/zoom.com/127.0.0.1#5335 +ipset=/zoom.com/gfwlist +server=/xoom.com/127.0.0.1#5335 +ipset=/xoom.com/gfwlist +server=/pokemonbank.com/127.0.0.1#5335 +ipset=/pokemonbank.com/gfwlist +server=/adaptivecards.io/127.0.0.1#5335 +ipset=/adaptivecards.io/gfwlist +server=/i-book.net/127.0.0.1#5335 +ipset=/i-book.net/gfwlist +server=/openweather.co.uk/127.0.0.1#5335 +ipset=/openweather.co.uk/gfwlist +server=/loveparents.org/127.0.0.1#5335 +ipset=/loveparents.org/gfwlist +server=/google.tg/127.0.0.1#5335 +ipset=/google.tg/gfwlist +server=/brasiltudoliberado.com/127.0.0.1#5335 +ipset=/brasiltudoliberado.com/gfwlist +server=/beatspascher-fr.net/127.0.0.1#5335 +ipset=/beatspascher-fr.net/gfwlist +server=/theporntoplist.com/127.0.0.1#5335 +ipset=/theporntoplist.com/gfwlist +server=/vintagemedicalpictures.com/127.0.0.1#5335 +ipset=/vintagemedicalpictures.com/gfwlist +server=/nikemarketing.com/127.0.0.1#5335 +ipset=/nikemarketing.com/gfwlist +server=/youpornru.com/127.0.0.1#5335 +ipset=/youpornru.com/gfwlist +server=/cambridgeschoolshakespeare.com/127.0.0.1#5335 +ipset=/cambridgeschoolshakespeare.com/gfwlist +server=/onedinesfree.com/127.0.0.1#5335 +ipset=/onedinesfree.com/gfwlist +server=/termius.com/127.0.0.1#5335 +ipset=/termius.com/gfwlist +server=/hypnoporn.net/127.0.0.1#5335 +ipset=/hypnoporn.net/gfwlist +server=/espn.com/127.0.0.1#5335 +ipset=/espn.com/gfwlist +server=/nikkei.co.jp/127.0.0.1#5335 +ipset=/nikkei.co.jp/gfwlist +server=/seedmov18.com/127.0.0.1#5335 +ipset=/seedmov18.com/gfwlist +server=/tourporno.com/127.0.0.1#5335 +ipset=/tourporno.com/gfwlist +server=/mini-coupe.ca/127.0.0.1#5335 +ipset=/mini-coupe.ca/gfwlist +server=/akamaihd-staging.net/127.0.0.1#5335 +ipset=/akamaihd-staging.net/gfwlist +server=/realamericanstories.com/127.0.0.1#5335 +ipset=/realamericanstories.com/gfwlist +server=/google-syndication.com/127.0.0.1#5335 +ipset=/google-syndication.com/gfwlist +server=/singlelogin.app/127.0.0.1#5335 +ipset=/singlelogin.app/gfwlist +server=/marvel.com/127.0.0.1#5335 +ipset=/marvel.com/gfwlist +server=/xn--9kr7l.com/127.0.0.1#5335 +ipset=/xn--9kr7l.com/gfwlist +server=/facebokbook.com/127.0.0.1#5335 +ipset=/facebokbook.com/gfwlist +server=/pornogayphy.com/127.0.0.1#5335 +ipset=/pornogayphy.com/gfwlist +server=/hotporntubes.com/127.0.0.1#5335 +ipset=/hotporntubes.com/gfwlist +server=/mastercard.us/127.0.0.1#5335 +ipset=/mastercard.us/gfwlist +server=/spiritofecstasy.com/127.0.0.1#5335 +ipset=/spiritofecstasy.com/gfwlist +server=/freepornq.com/127.0.0.1#5335 +ipset=/freepornq.com/gfwlist +server=/ravm.tv/127.0.0.1#5335 +ipset=/ravm.tv/gfwlist +server=/2kgames.com/127.0.0.1#5335 +ipset=/2kgames.com/gfwlist +server=/bluefootcms.com/127.0.0.1#5335 +ipset=/bluefootcms.com/gfwlist +server=/eastore.com/127.0.0.1#5335 +ipset=/eastore.com/gfwlist +server=/2013beatsbydrdreonline.com/127.0.0.1#5335 +ipset=/2013beatsbydrdreonline.com/gfwlist +server=/enfamama.com.ar/127.0.0.1#5335 +ipset=/enfamama.com.ar/gfwlist +server=/monotype.com/127.0.0.1#5335 +ipset=/monotype.com/gfwlist +server=/starwarsbattlefront.com/127.0.0.1#5335 +ipset=/starwarsbattlefront.com/gfwlist +server=/visa.no/127.0.0.1#5335 +ipset=/visa.no/gfwlist +server=/akamah.com/127.0.0.1#5335 +ipset=/akamah.com/gfwlist +server=/fandom.com/127.0.0.1#5335 +ipset=/fandom.com/gfwlist +server=/tver.co.jp/127.0.0.1#5335 +ipset=/tver.co.jp/gfwlist +server=/fashionnike.com/127.0.0.1#5335 +ipset=/fashionnike.com/gfwlist +server=/javsin.tv/127.0.0.1#5335 +ipset=/javsin.tv/gfwlist +server=/exxxtrasmall.com/127.0.0.1#5335 +ipset=/exxxtrasmall.com/gfwlist +server=/financialsoccer.ca/127.0.0.1#5335 +ipset=/financialsoccer.ca/gfwlist +server=/zatrahal.online/127.0.0.1#5335 +ipset=/zatrahal.online/gfwlist +server=/fbinnovation.com/127.0.0.1#5335 +ipset=/fbinnovation.com/gfwlist +server=/gfarchive.com/127.0.0.1#5335 +ipset=/gfarchive.com/gfwlist +server=/az764295.vo.msecnd.net/127.0.0.1#5335 +ipset=/az764295.vo.msecnd.net/gfwlist +server=/firestonecomercial.cl/127.0.0.1#5335 +ipset=/firestonecomercial.cl/gfwlist +server=/impact-ad.jp/127.0.0.1#5335 +ipset=/impact-ad.jp/gfwlist +server=/volvotruckcenter.it/127.0.0.1#5335 +ipset=/volvotruckcenter.it/gfwlist +server=/pornoelena.net/127.0.0.1#5335 +ipset=/pornoelena.net/gfwlist +server=/ignitesasia.com/127.0.0.1#5335 +ipset=/ignitesasia.com/gfwlist +server=/evanottyvideos.com/127.0.0.1#5335 +ipset=/evanottyvideos.com/gfwlist +server=/feacbooke.com/127.0.0.1#5335 +ipset=/feacbooke.com/gfwlist +server=/bcovlive.io/127.0.0.1#5335 +ipset=/bcovlive.io/gfwlist +server=/wikihow.com/127.0.0.1#5335 +ipset=/wikihow.com/gfwlist +server=/mini-qatar.com/127.0.0.1#5335 +ipset=/mini-qatar.com/gfwlist +server=/idelreal.org/127.0.0.1#5335 +ipset=/idelreal.org/gfwlist +server=/omnitek.tv/127.0.0.1#5335 +ipset=/omnitek.tv/gfwlist +server=/monsterbeatsbydres.com/127.0.0.1#5335 +ipset=/monsterbeatsbydres.com/gfwlist +server=/epochtimes-bg.com/127.0.0.1#5335 +ipset=/epochtimes-bg.com/gfwlist +server=/starbucksrewardsstarland.com/127.0.0.1#5335 +ipset=/starbucksrewardsstarland.com/gfwlist +server=/nu-bay.com/127.0.0.1#5335 +ipset=/nu-bay.com/gfwlist +server=/mastercard.co.in/127.0.0.1#5335 +ipset=/mastercard.co.in/gfwlist +server=/amateuranalvideos.com/127.0.0.1#5335 +ipset=/amateuranalvideos.com/gfwlist +server=/asiansmaster.com/127.0.0.1#5335 +ipset=/asiansmaster.com/gfwlist +server=/facebook.net/127.0.0.1#5335 +ipset=/facebook.net/gfwlist +server=/minisojordan.com/127.0.0.1#5335 +ipset=/minisojordan.com/gfwlist +server=/youtube.com.tn/127.0.0.1#5335 +ipset=/youtube.com.tn/gfwlist +server=/finlitsummit.org/127.0.0.1#5335 +ipset=/finlitsummit.org/gfwlist +server=/bookfi.net/127.0.0.1#5335 +ipset=/bookfi.net/gfwlist +server=/ebayradio.com/127.0.0.1#5335 +ipset=/ebayradio.com/gfwlist +server=/swisssign-group.ch/127.0.0.1#5335 +ipset=/swisssign-group.ch/gfwlist +server=/realvision.com/127.0.0.1#5335 +ipset=/realvision.com/gfwlist +server=/ipod.com.hk/127.0.0.1#5335 +ipset=/ipod.com.hk/gfwlist +server=/bbgevent.com/127.0.0.1#5335 +ipset=/bbgevent.com/gfwlist +server=/sexguide.ro/127.0.0.1#5335 +ipset=/sexguide.ro/gfwlist +server=/travelexch.com/127.0.0.1#5335 +ipset=/travelexch.com/gfwlist +server=/creativecommons.engineering/127.0.0.1#5335 +ipset=/creativecommons.engineering/gfwlist +server=/londonreal.tv/127.0.0.1#5335 +ipset=/londonreal.tv/gfwlist +server=/ipad3.com/127.0.0.1#5335 +ipset=/ipad3.com/gfwlist +server=/azadliq.org/127.0.0.1#5335 +ipset=/azadliq.org/gfwlist +server=/visualstudio.eu/127.0.0.1#5335 +ipset=/visualstudio.eu/gfwlist +server=/bookclubgirl.com/127.0.0.1#5335 +ipset=/bookclubgirl.com/gfwlist +server=/sluttyrat.com/127.0.0.1#5335 +ipset=/sluttyrat.com/gfwlist +server=/headlinejobs.hk/127.0.0.1#5335 +ipset=/headlinejobs.hk/gfwlist +server=/ie8.co/127.0.0.1#5335 +ipset=/ie8.co/gfwlist +server=/sexygirlfriendtube.com/127.0.0.1#5335 +ipset=/sexygirlfriendtube.com/gfwlist +server=/netlify.app/127.0.0.1#5335 +ipset=/netlify.app/gfwlist +server=/mini.co.kr/127.0.0.1#5335 +ipset=/mini.co.kr/gfwlist +server=/creampiehomevideos.com/127.0.0.1#5335 +ipset=/creampiehomevideos.com/gfwlist +server=/appledaily.com.tw/127.0.0.1#5335 +ipset=/appledaily.com.tw/gfwlist +server=/sci-hub.mksa.top/127.0.0.1#5335 +ipset=/sci-hub.mksa.top/gfwlist +server=/domywife.com/127.0.0.1#5335 +ipset=/domywife.com/gfwlist +server=/dreamworks.com/127.0.0.1#5335 +ipset=/dreamworks.com/gfwlist +server=/dirtyshack.com/127.0.0.1#5335 +ipset=/dirtyshack.com/gfwlist +server=/canonical.com/127.0.0.1#5335 +ipset=/canonical.com/gfwlist +server=/volvotrucks.ro/127.0.0.1#5335 +ipset=/volvotrucks.ro/gfwlist +server=/bmwdealercareers.com/127.0.0.1#5335 +ipset=/bmwdealercareers.com/gfwlist +server=/canon-ois.qa/127.0.0.1#5335 +ipset=/canon-ois.qa/gfwlist +server=/weltweitwachsen.de/127.0.0.1#5335 +ipset=/weltweitwachsen.de/gfwlist +server=/visa.sx/127.0.0.1#5335 +ipset=/visa.sx/gfwlist +server=/ebonywebcamhub.com/127.0.0.1#5335 +ipset=/ebonywebcamhub.com/gfwlist +server=/xo104.com/127.0.0.1#5335 +ipset=/xo104.com/gfwlist +server=/aboutamazon.it/127.0.0.1#5335 +ipset=/aboutamazon.it/gfwlist +server=/facebookmarketingpartners.com/127.0.0.1#5335 +ipset=/facebookmarketingpartners.com/gfwlist +server=/scc.ott.hinet.net/127.0.0.1#5335 +ipset=/scc.ott.hinet.net/gfwlist +server=/jetfuelapps.com/127.0.0.1#5335 +ipset=/jetfuelapps.com/gfwlist +server=/jambotube.com/127.0.0.1#5335 +ipset=/jambotube.com/gfwlist +server=/gtvmediagroupfairfund.com/127.0.0.1#5335 +ipset=/gtvmediagroupfairfund.com/gfwlist +server=/tbr.tangbr.net/127.0.0.1#5335 +ipset=/tbr.tangbr.net/gfwlist +server=/apple.ru/127.0.0.1#5335 +ipset=/apple.ru/gfwlist +server=/zdassets.com/127.0.0.1#5335 +ipset=/zdassets.com/gfwlist +server=/derpibooru.org/127.0.0.1#5335 +ipset=/derpibooru.org/gfwlist +server=/shopee.com.mx/127.0.0.1#5335 +ipset=/shopee.com.mx/gfwlist +server=/stripparadise.com/127.0.0.1#5335 +ipset=/stripparadise.com/gfwlist +server=/54647.global/127.0.0.1#5335 +ipset=/54647.global/gfwlist +server=/businessinsider.mx/127.0.0.1#5335 +ipset=/businessinsider.mx/gfwlist +server=/supanimegames.com/127.0.0.1#5335 +ipset=/supanimegames.com/gfwlist +server=/paypal.us/127.0.0.1#5335 +ipset=/paypal.us/gfwlist +server=/ntd.com/127.0.0.1#5335 +ipset=/ntd.com/gfwlist +server=/scholar.google.com.pa/127.0.0.1#5335 +ipset=/scholar.google.com.pa/gfwlist +server=/okazudouga.tokyo/127.0.0.1#5335 +ipset=/okazudouga.tokyo/gfwlist +server=/cloudflareinsights.com/127.0.0.1#5335 +ipset=/cloudflareinsights.com/gfwlist +server=/facebookpoke.org/127.0.0.1#5335 +ipset=/facebookpoke.org/gfwlist +server=/messytube.com/127.0.0.1#5335 +ipset=/messytube.com/gfwlist +server=/arirangmeari.com/127.0.0.1#5335 +ipset=/arirangmeari.com/gfwlist +server=/ruinedking.com/127.0.0.1#5335 +ipset=/ruinedking.com/gfwlist +server=/monsterbeatsbydrenew.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrenew.com/gfwlist +server=/xvidios.xxx/127.0.0.1#5335 +ipset=/xvidios.xxx/gfwlist +server=/8muses.xxx/127.0.0.1#5335 +ipset=/8muses.xxx/gfwlist +server=/facebook.cc/127.0.0.1#5335 +ipset=/facebook.cc/gfwlist +server=/softbank-robotics.com/127.0.0.1#5335 +ipset=/softbank-robotics.com/gfwlist +server=/bmwgroup-gaad.com/127.0.0.1#5335 +ipset=/bmwgroup-gaad.com/gfwlist +server=/amaaozn.com/127.0.0.1#5335 +ipset=/amaaozn.com/gfwlist +server=/microsoftiotinsiderlabs.com/127.0.0.1#5335 +ipset=/microsoftiotinsiderlabs.com/gfwlist +server=/wwe9.com/127.0.0.1#5335 +ipset=/wwe9.com/gfwlist +server=/akamii.com/127.0.0.1#5335 +ipset=/akamii.com/gfwlist +server=/yahoodns.net/127.0.0.1#5335 +ipset=/yahoodns.net/gfwlist +server=/fansta.me/127.0.0.1#5335 +ipset=/fansta.me/gfwlist +server=/mastercard.co.uk/127.0.0.1#5335 +ipset=/mastercard.co.uk/gfwlist +server=/pussy-pics.net/127.0.0.1#5335 +ipset=/pussy-pics.net/gfwlist +server=/adidas.com.tw/127.0.0.1#5335 +ipset=/adidas.com.tw/gfwlist +server=/meendo.com/127.0.0.1#5335 +ipset=/meendo.com/gfwlist +server=/kyodonews.jp/127.0.0.1#5335 +ipset=/kyodonews.jp/gfwlist +server=/pornoboliviaxxx.com/127.0.0.1#5335 +ipset=/pornoboliviaxxx.com/gfwlist +server=/nvidia.co.kr/127.0.0.1#5335 +ipset=/nvidia.co.kr/gfwlist +server=/ios-icloud.com/127.0.0.1#5335 +ipset=/ios-icloud.com/gfwlist +server=/tamilsexvideos.cc/127.0.0.1#5335 +ipset=/tamilsexvideos.cc/gfwlist +server=/youtube.ae/127.0.0.1#5335 +ipset=/youtube.ae/gfwlist +server=/blogspot.com.ng/127.0.0.1#5335 +ipset=/blogspot.com.ng/gfwlist +server=/steamdeck.com/127.0.0.1#5335 +ipset=/steamdeck.com/gfwlist +server=/aboutamazon.co.uk/127.0.0.1#5335 +ipset=/aboutamazon.co.uk/gfwlist +server=/netflav.com/127.0.0.1#5335 +ipset=/netflav.com/gfwlist +server=/beatsdrdre2014.com/127.0.0.1#5335 +ipset=/beatsdrdre2014.com/gfwlist +server=/swingerporntube.com/127.0.0.1#5335 +ipset=/swingerporntube.com/gfwlist +server=/garena.vn/127.0.0.1#5335 +ipset=/garena.vn/gfwlist +server=/genshinh.com/127.0.0.1#5335 +ipset=/genshinh.com/gfwlist +server=/trendyporn.com/127.0.0.1#5335 +ipset=/trendyporn.com/gfwlist +server=/pornhdtube.tv/127.0.0.1#5335 +ipset=/pornhdtube.tv/gfwlist +server=/zoom.us/127.0.0.1#5335 +ipset=/zoom.us/gfwlist +server=/moviepost.com/127.0.0.1#5335 +ipset=/moviepost.com/gfwlist +server=/avxde.org/127.0.0.1#5335 +ipset=/avxde.org/gfwlist +server=/milfnut.com/127.0.0.1#5335 +ipset=/milfnut.com/gfwlist +server=/googletagservices.com/127.0.0.1#5335 +ipset=/googletagservices.com/gfwlist +server=/googleacquisitionmigration.com/127.0.0.1#5335 +ipset=/googleacquisitionmigration.com/gfwlist +server=/i.org/127.0.0.1#5335 +ipset=/i.org/gfwlist +server=/hplfmedia.com/127.0.0.1#5335 +ipset=/hplfmedia.com/gfwlist +server=/xbnat.com/127.0.0.1#5335 +ipset=/xbnat.com/gfwlist +server=/nudistsexvideos.com/127.0.0.1#5335 +ipset=/nudistsexvideos.com/gfwlist +server=/starbucks.co.uk/127.0.0.1#5335 +ipset=/starbucks.co.uk/gfwlist +server=/slack-core.com/127.0.0.1#5335 +ipset=/slack-core.com/gfwlist +server=/travelexae.com/127.0.0.1#5335 +ipset=/travelexae.com/gfwlist +server=/crazyxxxworld.com/127.0.0.1#5335 +ipset=/crazyxxxworld.com/gfwlist +server=/hp-invent.com/127.0.0.1#5335 +ipset=/hp-invent.com/gfwlist +server=/w.org/127.0.0.1#5335 +ipset=/w.org/gfwlist +server=/x.org/127.0.0.1#5335 +ipset=/x.org/gfwlist +server=/bs-adreview.com/127.0.0.1#5335 +ipset=/bs-adreview.com/gfwlist +server=/swisssigner.ch/127.0.0.1#5335 +ipset=/swisssigner.ch/gfwlist +server=/wallet.com/127.0.0.1#5335 +ipset=/wallet.com/gfwlist +server=/atos.net/127.0.0.1#5335 +ipset=/atos.net/gfwlist +server=/disney.gr/127.0.0.1#5335 +ipset=/disney.gr/gfwlist +server=/gogoanime.wiki/127.0.0.1#5335 +ipset=/gogoanime.wiki/gfwlist +server=/youtube.com.lb/127.0.0.1#5335 +ipset=/youtube.com.lb/gfwlist +server=/tvnaviweb.jp/127.0.0.1#5335 +ipset=/tvnaviweb.jp/gfwlist +server=/david-laserscanner.com/127.0.0.1#5335 +ipset=/david-laserscanner.com/gfwlist +server=/sweetmlif.net/127.0.0.1#5335 +ipset=/sweetmlif.net/gfwlist +server=/vod-dash-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vod-dash-uk-live.akamaized.net/gfwlist +server=/reastatic.net/127.0.0.1#5335 +ipset=/reastatic.net/gfwlist +server=/tubemogul.com/127.0.0.1#5335 +ipset=/tubemogul.com/gfwlist +server=/mastercard.com.kw/127.0.0.1#5335 +ipset=/mastercard.com.kw/gfwlist +server=/webex.com.mx/127.0.0.1#5335 +ipset=/webex.com.mx/gfwlist +server=/intel.cl/127.0.0.1#5335 +ipset=/intel.cl/gfwlist +server=/skinstrip.net/127.0.0.1#5335 +ipset=/skinstrip.net/gfwlist +server=/whisolutions.com/127.0.0.1#5335 +ipset=/whisolutions.com/gfwlist +server=/500caocao.com/127.0.0.1#5335 +ipset=/500caocao.com/gfwlist +server=/lysol.com.mx/127.0.0.1#5335 +ipset=/lysol.com.mx/gfwlist +server=/clincha.cn/127.0.0.1#5335 +ipset=/clincha.cn/gfwlist +server=/yahoo.co.th/127.0.0.1#5335 +ipset=/yahoo.co.th/gfwlist +server=/ctitv.com.tw/127.0.0.1#5335 +ipset=/ctitv.com.tw/gfwlist +server=/punishbang.com/127.0.0.1#5335 +ipset=/punishbang.com/gfwlist +server=/bit.ly/127.0.0.1#5335 +ipset=/bit.ly/gfwlist +server=/chedteb.eu/127.0.0.1#5335 +ipset=/chedteb.eu/gfwlist +server=/bwin.com/127.0.0.1#5335 +ipset=/bwin.com/gfwlist +server=/visiontimes.it/127.0.0.1#5335 +ipset=/visiontimes.it/gfwlist +server=/mature-tube.sexy/127.0.0.1#5335 +ipset=/mature-tube.sexy/gfwlist +server=/sourceforge.com/127.0.0.1#5335 +ipset=/sourceforge.com/gfwlist +server=/51dh.site/127.0.0.1#5335 +ipset=/51dh.site/gfwlist +server=/themathsfactor.com/127.0.0.1#5335 +ipset=/themathsfactor.com/gfwlist +server=/bodyfluids-jav.com/127.0.0.1#5335 +ipset=/bodyfluids-jav.com/gfwlist +server=/bestrecipes.com.au/127.0.0.1#5335 +ipset=/bestrecipes.com.au/gfwlist +server=/videosporno.com.br/127.0.0.1#5335 +ipset=/videosporno.com.br/gfwlist +server=/kompoz.com/127.0.0.1#5335 +ipset=/kompoz.com/gfwlist +server=/canon.ba/127.0.0.1#5335 +ipset=/canon.ba/gfwlist +server=/ozodlik.org/127.0.0.1#5335 +ipset=/ozodlik.org/gfwlist +server=/garena.ph/127.0.0.1#5335 +ipset=/garena.ph/gfwlist +server=/blogspot.hr/127.0.0.1#5335 +ipset=/blogspot.hr/gfwlist +server=/tranny.one/127.0.0.1#5335 +ipset=/tranny.one/gfwlist +server=/hentai44.com/127.0.0.1#5335 +ipset=/hentai44.com/gfwlist +server=/ikea.sg/127.0.0.1#5335 +ipset=/ikea.sg/gfwlist +server=/lihkg.com/127.0.0.1#5335 +ipset=/lihkg.com/gfwlist +server=/flash-xxx.com/127.0.0.1#5335 +ipset=/flash-xxx.com/gfwlist +server=/miniso.ge/127.0.0.1#5335 +ipset=/miniso.ge/gfwlist +server=/pearsononlineacademy.com/127.0.0.1#5335 +ipset=/pearsononlineacademy.com/gfwlist +server=/cloudflareclient.com/127.0.0.1#5335 +ipset=/cloudflareclient.com/gfwlist +server=/campuslondon.com/127.0.0.1#5335 +ipset=/campuslondon.com/gfwlist +server=/tryfuckmenow.com/127.0.0.1#5335 +ipset=/tryfuckmenow.com/gfwlist +server=/nesaporn.com/127.0.0.1#5335 +ipset=/nesaporn.com/gfwlist +server=/xnxx2.org/127.0.0.1#5335 +ipset=/xnxx2.org/gfwlist +server=/zenodo.org/127.0.0.1#5335 +ipset=/zenodo.org/gfwlist +server=/lsj2.shop/127.0.0.1#5335 +ipset=/lsj2.shop/gfwlist +server=/ajsjx.com/127.0.0.1#5335 +ipset=/ajsjx.com/gfwlist +server=/fakehub.com/127.0.0.1#5335 +ipset=/fakehub.com/gfwlist +server=/bmw-connecteddrive.bg/127.0.0.1#5335 +ipset=/bmw-connecteddrive.bg/gfwlist +server=/scholar.google.com.my/127.0.0.1#5335 +ipset=/scholar.google.com.my/gfwlist +server=/netflixtechblog.com/127.0.0.1#5335 +ipset=/netflixtechblog.com/gfwlist +server=/dopaminegirl.com/127.0.0.1#5335 +ipset=/dopaminegirl.com/gfwlist +server=/freexxx.win/127.0.0.1#5335 +ipset=/freexxx.win/gfwlist +server=/tdesktop.com/127.0.0.1#5335 +ipset=/tdesktop.com/gfwlist +server=/himalaya.exchange/127.0.0.1#5335 +ipset=/himalaya.exchange/gfwlist +server=/acgfbw.com/127.0.0.1#5335 +ipset=/acgfbw.com/gfwlist +server=/live.eu/127.0.0.1#5335 +ipset=/live.eu/gfwlist +server=/cnbcfm.com/127.0.0.1#5335 +ipset=/cnbcfm.com/gfwlist +server=/playvids.com/127.0.0.1#5335 +ipset=/playvids.com/gfwlist +server=/uninhibitedcomix.com/127.0.0.1#5335 +ipset=/uninhibitedcomix.com/gfwlist +server=/moms-sex-videos.com/127.0.0.1#5335 +ipset=/moms-sex-videos.com/gfwlist +server=/rukoebxx.com/127.0.0.1#5335 +ipset=/rukoebxx.com/gfwlist +server=/msinnovationchallenge.com/127.0.0.1#5335 +ipset=/msinnovationchallenge.com/gfwlist +server=/xnxx-com.cfd/127.0.0.1#5335 +ipset=/xnxx-com.cfd/gfwlist +server=/alibabacloud.com.tw/127.0.0.1#5335 +ipset=/alibabacloud.com.tw/gfwlist +server=/levelsex.com/127.0.0.1#5335 +ipset=/levelsex.com/gfwlist +server=/tantaly.com/127.0.0.1#5335 +ipset=/tantaly.com/gfwlist +server=/nvidia.eu/127.0.0.1#5335 +ipset=/nvidia.eu/gfwlist +server=/z-lib.org/127.0.0.1#5335 +ipset=/z-lib.org/gfwlist +server=/vipbeatsbydre.com/127.0.0.1#5335 +ipset=/vipbeatsbydre.com/gfwlist +server=/dogmovie.net/127.0.0.1#5335 +ipset=/dogmovie.net/gfwlist +server=/dettol.com.my/127.0.0.1#5335 +ipset=/dettol.com.my/gfwlist +server=/teenpornvideo.xxx/127.0.0.1#5335 +ipset=/teenpornvideo.xxx/gfwlist +server=/yomiuri-shimbun.pressreader.com/127.0.0.1#5335 +ipset=/yomiuri-shimbun.pressreader.com/gfwlist +server=/pornhubpremium.com/127.0.0.1#5335 +ipset=/pornhubpremium.com/gfwlist +server=/internationalconnectionsacademy.com/127.0.0.1#5335 +ipset=/internationalconnectionsacademy.com/gfwlist +server=/bigassporn.tv/127.0.0.1#5335 +ipset=/bigassporn.tv/gfwlist +server=/xxxreal.com/127.0.0.1#5335 +ipset=/xxxreal.com/gfwlist +server=/volvotruckcenter.nl/127.0.0.1#5335 +ipset=/volvotruckcenter.nl/gfwlist +server=/bmw-motorrad.com.pe/127.0.0.1#5335 +ipset=/bmw-motorrad.com.pe/gfwlist +server=/free-wap-tube.com/127.0.0.1#5335 +ipset=/free-wap-tube.com/gfwlist +server=/covid19rx.org/127.0.0.1#5335 +ipset=/covid19rx.org/gfwlist +server=/xxxbullet.com/127.0.0.1#5335 +ipset=/xxxbullet.com/gfwlist +server=/nike23.com/127.0.0.1#5335 +ipset=/nike23.com/gfwlist +server=/facxebook.com/127.0.0.1#5335 +ipset=/facxebook.com/gfwlist +server=/yusjb.com/127.0.0.1#5335 +ipset=/yusjb.com/gfwlist +server=/webobjects.net/127.0.0.1#5335 +ipset=/webobjects.net/gfwlist +server=/google.org/127.0.0.1#5335 +ipset=/google.org/gfwlist +server=/disney.my.sentry.io/127.0.0.1#5335 +ipset=/disney.my.sentry.io/gfwlist +server=/instagrampartners.com/127.0.0.1#5335 +ipset=/instagrampartners.com/gfwlist +server=/truyen-hentai.ru/127.0.0.1#5335 +ipset=/truyen-hentai.ru/gfwlist +server=/cumlouder.com/127.0.0.1#5335 +ipset=/cumlouder.com/gfwlist +server=/hentaizilla.com/127.0.0.1#5335 +ipset=/hentaizilla.com/gfwlist +server=/mini.co.il/127.0.0.1#5335 +ipset=/mini.co.il/gfwlist +server=/thothub.ru/127.0.0.1#5335 +ipset=/thothub.ru/gfwlist +server=/diamondgirls.co.uk/127.0.0.1#5335 +ipset=/diamondgirls.co.uk/gfwlist +server=/shitjav.com/127.0.0.1#5335 +ipset=/shitjav.com/gfwlist +server=/dtlgalleryint.cloudapp.net/127.0.0.1#5335 +ipset=/dtlgalleryint.cloudapp.net/gfwlist +server=/darkness-risen.com/127.0.0.1#5335 +ipset=/darkness-risen.com/gfwlist +server=/github.io/127.0.0.1#5335 +ipset=/github.io/gfwlist +server=/adsensecustomsearchads.com/127.0.0.1#5335 +ipset=/adsensecustomsearchads.com/gfwlist +server=/badaas.com/127.0.0.1#5335 +ipset=/badaas.com/gfwlist +server=/ebaycafe.com/127.0.0.1#5335 +ipset=/ebaycafe.com/gfwlist +server=/uun97.com/127.0.0.1#5335 +ipset=/uun97.com/gfwlist +server=/nodesource.com/127.0.0.1#5335 +ipset=/nodesource.com/gfwlist +server=/bmw.co.il/127.0.0.1#5335 +ipset=/bmw.co.il/gfwlist +server=/cloudc.one/127.0.0.1#5335 +ipset=/cloudc.one/gfwlist +server=/voyeurporntapes.com/127.0.0.1#5335 +ipset=/voyeurporntapes.com/gfwlist +server=/mega.io/127.0.0.1#5335 +ipset=/mega.io/gfwlist +server=/psg-int-eastus.cloudapp.net/127.0.0.1#5335 +ipset=/psg-int-eastus.cloudapp.net/gfwlist +server=/webcam-teen.net/127.0.0.1#5335 +ipset=/webcam-teen.net/gfwlist +server=/dcard.cc/127.0.0.1#5335 +ipset=/dcard.cc/gfwlist +server=/youtube.ug/127.0.0.1#5335 +ipset=/youtube.ug/gfwlist +server=/shuziyimin.org/127.0.0.1#5335 +ipset=/shuziyimin.org/gfwlist +server=/islamiccenterofnewlondon.com/127.0.0.1#5335 +ipset=/islamiccenterofnewlondon.com/gfwlist +server=/who.int/127.0.0.1#5335 +ipset=/who.int/gfwlist +server=/shemaletubevideos.com/127.0.0.1#5335 +ipset=/shemaletubevideos.com/gfwlist +server=/incezt.net/127.0.0.1#5335 +ipset=/incezt.net/gfwlist +server=/girlfuckshorse.net/127.0.0.1#5335 +ipset=/girlfuckshorse.net/gfwlist +server=/facebook-login.com/127.0.0.1#5335 +ipset=/facebook-login.com/gfwlist +server=/luckyissue.com/127.0.0.1#5335 +ipset=/luckyissue.com/gfwlist +server=/amerikayidzayn.com/127.0.0.1#5335 +ipset=/amerikayidzayn.com/gfwlist +server=/ipod.cm/127.0.0.1#5335 +ipset=/ipod.cm/gfwlist +server=/sonystoragemedia.co.jp/127.0.0.1#5335 +ipset=/sonystoragemedia.co.jp/gfwlist +server=/blz-contentstack.com/127.0.0.1#5335 +ipset=/blz-contentstack.com/gfwlist +server=/myq2.com/127.0.0.1#5335 +ipset=/myq2.com/gfwlist +server=/fapvid.com/127.0.0.1#5335 +ipset=/fapvid.com/gfwlist +server=/postgresql.org/127.0.0.1#5335 +ipset=/postgresql.org/gfwlist +server=/mytrannycams.com/127.0.0.1#5335 +ipset=/mytrannycams.com/gfwlist +server=/cheapbeatsbydreshop.com/127.0.0.1#5335 +ipset=/cheapbeatsbydreshop.com/gfwlist +server=/bmw-motorrad.nl/127.0.0.1#5335 +ipset=/bmw-motorrad.nl/gfwlist +server=/braveux.com/127.0.0.1#5335 +ipset=/braveux.com/gfwlist +server=/dazndn.com/127.0.0.1#5335 +ipset=/dazndn.com/gfwlist +server=/deepfakeporn.net/127.0.0.1#5335 +ipset=/deepfakeporn.net/gfwlist +server=/thesexbible.com/127.0.0.1#5335 +ipset=/thesexbible.com/gfwlist +server=/jizzhut.com/127.0.0.1#5335 +ipset=/jizzhut.com/gfwlist +server=/techhub.ms/127.0.0.1#5335 +ipset=/techhub.ms/gfwlist +server=/vgg8.com/127.0.0.1#5335 +ipset=/vgg8.com/gfwlist +server=/ccna5.net/127.0.0.1#5335 +ipset=/ccna5.net/gfwlist +server=/canon.ru/127.0.0.1#5335 +ipset=/canon.ru/gfwlist +server=/huashundg.com/127.0.0.1#5335 +ipset=/huashundg.com/gfwlist +server=/monsterbeatsbydre-nz.com/127.0.0.1#5335 +ipset=/monsterbeatsbydre-nz.com/gfwlist +server=/ohpornocasero.com/127.0.0.1#5335 +ipset=/ohpornocasero.com/gfwlist +server=/porncomics.com/127.0.0.1#5335 +ipset=/porncomics.com/gfwlist +server=/visa.com.sv/127.0.0.1#5335 +ipset=/visa.com.sv/gfwlist +server=/bmw-group.com/127.0.0.1#5335 +ipset=/bmw-group.com/gfwlist +server=/pornxs.com/127.0.0.1#5335 +ipset=/pornxs.com/gfwlist +server=/youx.xxx/127.0.0.1#5335 +ipset=/youx.xxx/gfwlist +server=/compose-spec.io/127.0.0.1#5335 +ipset=/compose-spec.io/gfwlist +server=/radiomango.fm/127.0.0.1#5335 +ipset=/radiomango.fm/gfwlist +server=/scat-shop.net/127.0.0.1#5335 +ipset=/scat-shop.net/gfwlist +server=/npmjs.org/127.0.0.1#5335 +ipset=/npmjs.org/gfwlist +server=/gdansk-amazon.com/127.0.0.1#5335 +ipset=/gdansk-amazon.com/gfwlist +server=/hyperdreams.com/127.0.0.1#5335 +ipset=/hyperdreams.com/gfwlist +server=/fastly-terrarium.com/127.0.0.1#5335 +ipset=/fastly-terrarium.com/gfwlist +server=/adobehiddentreasures.com/127.0.0.1#5335 +ipset=/adobehiddentreasures.com/gfwlist +server=/appleid.hamburg/127.0.0.1#5335 +ipset=/appleid.hamburg/gfwlist +server=/comsoc.org/127.0.0.1#5335 +ipset=/comsoc.org/gfwlist +server=/nudography.com/127.0.0.1#5335 +ipset=/nudography.com/gfwlist +server=/mastercard.com.pe/127.0.0.1#5335 +ipset=/mastercard.com.pe/gfwlist +server=/nikeairhuarache.com/127.0.0.1#5335 +ipset=/nikeairhuarache.com/gfwlist +server=/chwr7s8u.com/127.0.0.1#5335 +ipset=/chwr7s8u.com/gfwlist +server=/cartoonsexfantazy.com/127.0.0.1#5335 +ipset=/cartoonsexfantazy.com/gfwlist +server=/road-crew.com/127.0.0.1#5335 +ipset=/road-crew.com/gfwlist +server=/ieeedeis.org/127.0.0.1#5335 +ipset=/ieeedeis.org/gfwlist +server=/rbmavericks.com/127.0.0.1#5335 +ipset=/rbmavericks.com/gfwlist +server=/senpaiheat.com/127.0.0.1#5335 +ipset=/senpaiheat.com/gfwlist +server=/nflhotsalejerseys.com/127.0.0.1#5335 +ipset=/nflhotsalejerseys.com/gfwlist +server=/codethemicrobit.com/127.0.0.1#5335 +ipset=/codethemicrobit.com/gfwlist +server=/durex.lv/127.0.0.1#5335 +ipset=/durex.lv/gfwlist +server=/wp-themes.com/127.0.0.1#5335 +ipset=/wp-themes.com/gfwlist +server=/homealonemilfs.com/127.0.0.1#5335 +ipset=/homealonemilfs.com/gfwlist +server=/wikiquote.org/127.0.0.1#5335 +ipset=/wikiquote.org/gfwlist +server=/110xnxx.com/127.0.0.1#5335 +ipset=/110xnxx.com/gfwlist +server=/xgaytube.com/127.0.0.1#5335 +ipset=/xgaytube.com/gfwlist +server=/archiveofourown.net/127.0.0.1#5335 +ipset=/archiveofourown.net/gfwlist +server=/volvotrucks.bg/127.0.0.1#5335 +ipset=/volvotrucks.bg/gfwlist +server=/studywatchbyverily.org/127.0.0.1#5335 +ipset=/studywatchbyverily.org/gfwlist +server=/svobodnaevropa.bg/127.0.0.1#5335 +ipset=/svobodnaevropa.bg/gfwlist +server=/metrotoons.com/127.0.0.1#5335 +ipset=/metrotoons.com/gfwlist +server=/amourangels.com/127.0.0.1#5335 +ipset=/amourangels.com/gfwlist +server=/directvsports.com/127.0.0.1#5335 +ipset=/directvsports.com/gfwlist +server=/niconico.com/127.0.0.1#5335 +ipset=/niconico.com/gfwlist +server=/comdotgame.com/127.0.0.1#5335 +ipset=/comdotgame.com/gfwlist +server=/iknowthatgirl.com/127.0.0.1#5335 +ipset=/iknowthatgirl.com/gfwlist +server=/headphones-cool.com/127.0.0.1#5335 +ipset=/headphones-cool.com/gfwlist +server=/office.net/127.0.0.1#5335 +ipset=/office.net/gfwlist +server=/paypal-notice.com/127.0.0.1#5335 +ipset=/paypal-notice.com/gfwlist +server=/foxsoccerplus.com/127.0.0.1#5335 +ipset=/foxsoccerplus.com/gfwlist +server=/cna.com.tw/127.0.0.1#5335 +ipset=/cna.com.tw/gfwlist +server=/aboutamazon.fr/127.0.0.1#5335 +ipset=/aboutamazon.fr/gfwlist +server=/discord-activities.com/127.0.0.1#5335 +ipset=/discord-activities.com/gfwlist +server=/i-o-u.info/127.0.0.1#5335 +ipset=/i-o-u.info/gfwlist +server=/slideshare.net/127.0.0.1#5335 +ipset=/slideshare.net/gfwlist +server=/nintendo.co.kr/127.0.0.1#5335 +ipset=/nintendo.co.kr/gfwlist +server=/canon.ro/127.0.0.1#5335 +ipset=/canon.ro/gfwlist +server=/intimateinvasions.com/127.0.0.1#5335 +ipset=/intimateinvasions.com/gfwlist +server=/visafintechfasttrack.com/127.0.0.1#5335 +ipset=/visafintechfasttrack.com/gfwlist +server=/svsgames.org/127.0.0.1#5335 +ipset=/svsgames.org/gfwlist +server=/hpconnected.com/127.0.0.1#5335 +ipset=/hpconnected.com/gfwlist +server=/bmw.lu/127.0.0.1#5335 +ipset=/bmw.lu/gfwlist +server=/xn--gtvz22d.xn--hxt814e/127.0.0.1#5335 +ipset=/xn--gtvz22d.xn--hxt814e/gfwlist +server=/pornov1080.name/127.0.0.1#5335 +ipset=/pornov1080.name/gfwlist +server=/hotcuckoldwife.com/127.0.0.1#5335 +ipset=/hotcuckoldwife.com/gfwlist +server=/smplace.com/127.0.0.1#5335 +ipset=/smplace.com/gfwlist +server=/moefuns.co/127.0.0.1#5335 +ipset=/moefuns.co/gfwlist +server=/deadspacegame.com/127.0.0.1#5335 +ipset=/deadspacegame.com/gfwlist +server=/pornogram.xxx/127.0.0.1#5335 +ipset=/pornogram.xxx/gfwlist +server=/beatsbydreireland-sales.com/127.0.0.1#5335 +ipset=/beatsbydreireland-sales.com/gfwlist +server=/waranlov.com/127.0.0.1#5335 +ipset=/waranlov.com/gfwlist +server=/glamourtits.com/127.0.0.1#5335 +ipset=/glamourtits.com/gfwlist +server=/personaltrainermath.com/127.0.0.1#5335 +ipset=/personaltrainermath.com/gfwlist +server=/boswp.com/127.0.0.1#5335 +ipset=/boswp.com/gfwlist +server=/harvard.xxx/127.0.0.1#5335 +ipset=/harvard.xxx/gfwlist +server=/naughtymachinima.com/127.0.0.1#5335 +ipset=/naughtymachinima.com/gfwlist +server=/chinaclothesstore.com/127.0.0.1#5335 +ipset=/chinaclothesstore.com/gfwlist +server=/av-baron.com/127.0.0.1#5335 +ipset=/av-baron.com/gfwlist +server=/economist.com/127.0.0.1#5335 +ipset=/economist.com/gfwlist +server=/amdigital.co.uk/127.0.0.1#5335 +ipset=/amdigital.co.uk/gfwlist +server=/facebpook.com/127.0.0.1#5335 +ipset=/facebpook.com/gfwlist +server=/lpsg.com/127.0.0.1#5335 +ipset=/lpsg.com/gfwlist +server=/dicela.net/127.0.0.1#5335 +ipset=/dicela.net/gfwlist +server=/stockagainstphotography.com/127.0.0.1#5335 +ipset=/stockagainstphotography.com/gfwlist +server=/wto.org/127.0.0.1#5335 +ipset=/wto.org/gfwlist +server=/hashicorp.com/127.0.0.1#5335 +ipset=/hashicorp.com/gfwlist +server=/hp-ww.com/127.0.0.1#5335 +ipset=/hp-ww.com/gfwlist +server=/bmwdcsnet.net/127.0.0.1#5335 +ipset=/bmwdcsnet.net/gfwlist +server=/bmw-connecteddrive.pl/127.0.0.1#5335 +ipset=/bmw-connecteddrive.pl/gfwlist +server=/applestore.com.bn/127.0.0.1#5335 +ipset=/applestore.com.bn/gfwlist +server=/intel.sa/127.0.0.1#5335 +ipset=/intel.sa/gfwlist +server=/visa.com.dm/127.0.0.1#5335 +ipset=/visa.com.dm/gfwlist +server=/facebookloginhelp.net/127.0.0.1#5335 +ipset=/facebookloginhelp.net/gfwlist +server=/enfabebe.com.do/127.0.0.1#5335 +ipset=/enfabebe.com.do/gfwlist +server=/vjav.com/127.0.0.1#5335 +ipset=/vjav.com/gfwlist +server=/akamaihd.net/127.0.0.1#5335 +ipset=/akamaihd.net/gfwlist +server=/porngames.games/127.0.0.1#5335 +ipset=/porngames.games/gfwlist +server=/veet.com.mx/127.0.0.1#5335 +ipset=/veet.com.mx/gfwlist +server=/sexy-photos.net/127.0.0.1#5335 +ipset=/sexy-photos.net/gfwlist +server=/wantblogger.com/127.0.0.1#5335 +ipset=/wantblogger.com/gfwlist +server=/vkuservideo.net/127.0.0.1#5335 +ipset=/vkuservideo.net/gfwlist +server=/bmw.com.au/127.0.0.1#5335 +ipset=/bmw.com.au/gfwlist +server=/oxfordscholarlyeditions.com/127.0.0.1#5335 +ipset=/oxfordscholarlyeditions.com/gfwlist +server=/pornkind.net/127.0.0.1#5335 +ipset=/pornkind.net/gfwlist +server=/nikkei-cnbc.co.jp/127.0.0.1#5335 +ipset=/nikkei-cnbc.co.jp/gfwlist +server=/ebaytradingassistant.com/127.0.0.1#5335 +ipset=/ebaytradingassistant.com/gfwlist +server=/porndr.com/127.0.0.1#5335 +ipset=/porndr.com/gfwlist +server=/debug.com/127.0.0.1#5335 +ipset=/debug.com/gfwlist +server=/stin31.ru/127.0.0.1#5335 +ipset=/stin31.ru/gfwlist +server=/hpstore.com/127.0.0.1#5335 +ipset=/hpstore.com/gfwlist +server=/nxtdig.com.hk/127.0.0.1#5335 +ipset=/nxtdig.com.hk/gfwlist +server=/watchmygf.me/127.0.0.1#5335 +ipset=/watchmygf.me/gfwlist +server=/facebomok.com/127.0.0.1#5335 +ipset=/facebomok.com/gfwlist +server=/shoping.com/127.0.0.1#5335 +ipset=/shoping.com/gfwlist +server=/scholar.google.bg/127.0.0.1#5335 +ipset=/scholar.google.bg/gfwlist +server=/hotmail.co/127.0.0.1#5335 +ipset=/hotmail.co/gfwlist +server=/mini.com.do/127.0.0.1#5335 +ipset=/mini.com.do/gfwlist +server=/sonypicturestelevisiongames.com/127.0.0.1#5335 +ipset=/sonypicturestelevisiongames.com/gfwlist +server=/netvideogirls.com/127.0.0.1#5335 +ipset=/netvideogirls.com/gfwlist +server=/innovations-i.com/127.0.0.1#5335 +ipset=/innovations-i.com/gfwlist +server=/bitfinex.com/127.0.0.1#5335 +ipset=/bitfinex.com/gfwlist +server=/godaddy.com/127.0.0.1#5335 +ipset=/godaddy.com/gfwlist +server=/verisign.sg/127.0.0.1#5335 +ipset=/verisign.sg/gfwlist +server=/3dsexvilla.com/127.0.0.1#5335 +ipset=/3dsexvilla.com/gfwlist +server=/static.fun/127.0.0.1#5335 +ipset=/static.fun/gfwlist +server=/bmw-connecteddrive.se/127.0.0.1#5335 +ipset=/bmw-connecteddrive.se/gfwlist +server=/ssl-lvlt.cdn.ea.com/127.0.0.1#5335 +ipset=/ssl-lvlt.cdn.ea.com/gfwlist +server=/beatsneon.com/127.0.0.1#5335 +ipset=/beatsneon.com/gfwlist +server=/savvyshopper.net.au/127.0.0.1#5335 +ipset=/savvyshopper.net.au/gfwlist +server=/muchohentai.com/127.0.0.1#5335 +ipset=/muchohentai.com/gfwlist +server=/freechatnow.com/127.0.0.1#5335 +ipset=/freechatnow.com/gfwlist +server=/binancezh.link/127.0.0.1#5335 +ipset=/binancezh.link/gfwlist +server=/fap18.net/127.0.0.1#5335 +ipset=/fap18.net/gfwlist +server=/web.app/127.0.0.1#5335 +ipset=/web.app/gfwlist +server=/canon.sk/127.0.0.1#5335 +ipset=/canon.sk/gfwlist +server=/cooliphonecasesstore.com/127.0.0.1#5335 +ipset=/cooliphonecasesstore.com/gfwlist +server=/xvedo.net/127.0.0.1#5335 +ipset=/xvedo.net/gfwlist +server=/faphouse.com/127.0.0.1#5335 +ipset=/faphouse.com/gfwlist +server=/businessinsider.nl/127.0.0.1#5335 +ipset=/businessinsider.nl/gfwlist +server=/mini-connected.de/127.0.0.1#5335 +ipset=/mini-connected.de/gfwlist +server=/johren.games/127.0.0.1#5335 +ipset=/johren.games/gfwlist +server=/gouri.xyz/127.0.0.1#5335 +ipset=/gouri.xyz/gfwlist +server=/lantern.io/127.0.0.1#5335 +ipset=/lantern.io/gfwlist +server=/cnbc.com/127.0.0.1#5335 +ipset=/cnbc.com/gfwlist +server=/porner.tv/127.0.0.1#5335 +ipset=/porner.tv/gfwlist +server=/pixiv.co.jp/127.0.0.1#5335 +ipset=/pixiv.co.jp/gfwlist +server=/nurofen.cz/127.0.0.1#5335 +ipset=/nurofen.cz/gfwlist +server=/harpercollinschristian.com/127.0.0.1#5335 +ipset=/harpercollinschristian.com/gfwlist +server=/ctfassets.net/127.0.0.1#5335 +ipset=/ctfassets.net/gfwlist +server=/cloupia.net/127.0.0.1#5335 +ipset=/cloupia.net/gfwlist +server=/google.com.kw/127.0.0.1#5335 +ipset=/google.com.kw/gfwlist +server=/yaeby.info/127.0.0.1#5335 +ipset=/yaeby.info/gfwlist +server=/glasamerike.net/127.0.0.1#5335 +ipset=/glasamerike.net/gfwlist +server=/pearsoninstitute.ac.za/127.0.0.1#5335 +ipset=/pearsoninstitute.ac.za/gfwlist +server=/thesimssocial.com/127.0.0.1#5335 +ipset=/thesimssocial.com/gfwlist +server=/minimotorsport.com/127.0.0.1#5335 +ipset=/minimotorsport.com/gfwlist +server=/travelex.be/127.0.0.1#5335 +ipset=/travelex.be/gfwlist +server=/viewgals.com/127.0.0.1#5335 +ipset=/viewgals.com/gfwlist +server=/falundafa.org/127.0.0.1#5335 +ipset=/falundafa.org/gfwlist +server=/wipower.com/127.0.0.1#5335 +ipset=/wipower.com/gfwlist +server=/disneynow.com/127.0.0.1#5335 +ipset=/disneynow.com/gfwlist +server=/findtubes.com/127.0.0.1#5335 +ipset=/findtubes.com/gfwlist +server=/webex.com/127.0.0.1#5335 +ipset=/webex.com/gfwlist +server=/chicagolandbmw.com/127.0.0.1#5335 +ipset=/chicagolandbmw.com/gfwlist +server=/wnacg.org/127.0.0.1#5335 +ipset=/wnacg.org/gfwlist +server=/bmw.ba/127.0.0.1#5335 +ipset=/bmw.ba/gfwlist +server=/brightcovecdn.com/127.0.0.1#5335 +ipset=/brightcovecdn.com/gfwlist +server=/mortein.com.ng/127.0.0.1#5335 +ipset=/mortein.com.ng/gfwlist +server=/disneyenconcert.com/127.0.0.1#5335 +ipset=/disneyenconcert.com/gfwlist +server=/llnw.net/127.0.0.1#5335 +ipset=/llnw.net/gfwlist +server=/bestbuyrewardzone.ca/127.0.0.1#5335 +ipset=/bestbuyrewardzone.ca/gfwlist +server=/xxx-porn.info/127.0.0.1#5335 +ipset=/xxx-porn.info/gfwlist +server=/careersatfb.com/127.0.0.1#5335 +ipset=/careersatfb.com/gfwlist +server=/fox47.com/127.0.0.1#5335 +ipset=/fox47.com/gfwlist +server=/hpceo.com/127.0.0.1#5335 +ipset=/hpceo.com/gfwlist +server=/faceboox.com/127.0.0.1#5335 +ipset=/faceboox.com/gfwlist +server=/votolia.com/127.0.0.1#5335 +ipset=/votolia.com/gfwlist +server=/bmw-connecteddrive.be/127.0.0.1#5335 +ipset=/bmw-connecteddrive.be/gfwlist +server=/amateur-porn-clips.com/127.0.0.1#5335 +ipset=/amateur-porn-clips.com/gfwlist +server=/sni1dcb6gl.wpc.edgecastcdn.net/127.0.0.1#5335 +ipset=/sni1dcb6gl.wpc.edgecastcdn.net/gfwlist +server=/cotolia.com/127.0.0.1#5335 +ipset=/cotolia.com/gfwlist +server=/whatsapp.cc/127.0.0.1#5335 +ipset=/whatsapp.cc/gfwlist +server=/fotolia.com/127.0.0.1#5335 +ipset=/fotolia.com/gfwlist +server=/megapornfreehd.com/127.0.0.1#5335 +ipset=/megapornfreehd.com/gfwlist +server=/vkuservideo.com/127.0.0.1#5335 +ipset=/vkuservideo.com/gfwlist +server=/mit.edu/127.0.0.1#5335 +ipset=/mit.edu/gfwlist +server=/myfbfans.com/127.0.0.1#5335 +ipset=/myfbfans.com/gfwlist +server=/handjobtube4free.com/127.0.0.1#5335 +ipset=/handjobtube4free.com/gfwlist +server=/nikefootballjersey.com/127.0.0.1#5335 +ipset=/nikefootballjersey.com/gfwlist +server=/galleryarchives.com/127.0.0.1#5335 +ipset=/galleryarchives.com/gfwlist +server=/mytimesplus.co.uk/127.0.0.1#5335 +ipset=/mytimesplus.co.uk/gfwlist +server=/v8.dev/127.0.0.1#5335 +ipset=/v8.dev/gfwlist +server=/alphabet.jp/127.0.0.1#5335 +ipset=/alphabet.jp/gfwlist +server=/attssl.com/127.0.0.1#5335 +ipset=/attssl.com/gfwlist +server=/sexmex.xxx/127.0.0.1#5335 +ipset=/sexmex.xxx/gfwlist +server=/paypal-integration.com/127.0.0.1#5335 +ipset=/paypal-integration.com/gfwlist +server=/pccwsolutions.com/127.0.0.1#5335 +ipset=/pccwsolutions.com/gfwlist +server=/yourflashporn.com/127.0.0.1#5335 +ipset=/yourflashporn.com/gfwlist +server=/fox32.com/127.0.0.1#5335 +ipset=/fox32.com/gfwlist +server=/dowjones.io/127.0.0.1#5335 +ipset=/dowjones.io/gfwlist +server=/faceobk.com/127.0.0.1#5335 +ipset=/faceobk.com/gfwlist +server=/vanish.nl/127.0.0.1#5335 +ipset=/vanish.nl/gfwlist +server=/adx.promo/127.0.0.1#5335 +ipset=/adx.promo/gfwlist +server=/disney.co.jp/127.0.0.1#5335 +ipset=/disney.co.jp/gfwlist +server=/1monsterbeatsbydreus.com/127.0.0.1#5335 +ipset=/1monsterbeatsbydreus.com/gfwlist +server=/ebayopensource.net/127.0.0.1#5335 +ipset=/ebayopensource.net/gfwlist +server=/alphera.com/127.0.0.1#5335 +ipset=/alphera.com/gfwlist +server=/line-beta.me/127.0.0.1#5335 +ipset=/line-beta.me/gfwlist +server=/hbogoasia.id/127.0.0.1#5335 +ipset=/hbogoasia.id/gfwlist +server=/linux.org/127.0.0.1#5335 +ipset=/linux.org/gfwlist +server=/thefappening.pro/127.0.0.1#5335 +ipset=/thefappening.pro/gfwlist +server=/localpresshk.com/127.0.0.1#5335 +ipset=/localpresshk.com/gfwlist +server=/regex101.com/127.0.0.1#5335 +ipset=/regex101.com/gfwlist +server=/snapvolumes.com/127.0.0.1#5335 +ipset=/snapvolumes.com/gfwlist +server=/sarennasworld.com/127.0.0.1#5335 +ipset=/sarennasworld.com/gfwlist +server=/google.cl/127.0.0.1#5335 +ipset=/google.cl/gfwlist +server=/openstreetmap.com/127.0.0.1#5335 +ipset=/openstreetmap.com/gfwlist +server=/heads4-ak-spotify-com.akamaized.net/127.0.0.1#5335 +ipset=/heads4-ak-spotify-com.akamaized.net/gfwlist +server=/freehulu.com/127.0.0.1#5335 +ipset=/freehulu.com/gfwlist +server=/shinhangmc.com/127.0.0.1#5335 +ipset=/shinhangmc.com/gfwlist +server=/beatsbydre.jp/127.0.0.1#5335 +ipset=/beatsbydre.jp/gfwlist +server=/swpr.livedoor.blog/127.0.0.1#5335 +ipset=/swpr.livedoor.blog/gfwlist +server=/amateurthreesomeporn.com/127.0.0.1#5335 +ipset=/amateurthreesomeporn.com/gfwlist +server=/whatsapp.tv/127.0.0.1#5335 +ipset=/whatsapp.tv/gfwlist +server=/yahoo.co.mz/127.0.0.1#5335 +ipset=/yahoo.co.mz/gfwlist +server=/acpica.com/127.0.0.1#5335 +ipset=/acpica.com/gfwlist +server=/xshr.online/127.0.0.1#5335 +ipset=/xshr.online/gfwlist +server=/scifisex.net/127.0.0.1#5335 +ipset=/scifisex.net/gfwlist +server=/nudeteenladies.com/127.0.0.1#5335 +ipset=/nudeteenladies.com/gfwlist +server=/microsoft.by/127.0.0.1#5335 +ipset=/microsoft.by/gfwlist +server=/mingw.org/127.0.0.1#5335 +ipset=/mingw.org/gfwlist +server=/skysports.fr/127.0.0.1#5335 +ipset=/skysports.fr/gfwlist +server=/riotgames.info/127.0.0.1#5335 +ipset=/riotgames.info/gfwlist +server=/ipadair.hk/127.0.0.1#5335 +ipset=/ipadair.hk/gfwlist +server=/xnxxpornvid.com/127.0.0.1#5335 +ipset=/xnxxpornvid.com/gfwlist +server=/web.dev/127.0.0.1#5335 +ipset=/web.dev/gfwlist +server=/webmoneyinfo.com/127.0.0.1#5335 +ipset=/webmoneyinfo.com/gfwlist +server=/amazonalexavoxcon.com/127.0.0.1#5335 +ipset=/amazonalexavoxcon.com/gfwlist +server=/appe-store.com/127.0.0.1#5335 +ipset=/appe-store.com/gfwlist +server=/bvfce6wz.xyz/127.0.0.1#5335 +ipset=/bvfce6wz.xyz/gfwlist +server=/bmwclassic.com/127.0.0.1#5335 +ipset=/bmwclassic.com/gfwlist +server=/theguardiandns.com/127.0.0.1#5335 +ipset=/theguardiandns.com/gfwlist +server=/eduplus.hk/127.0.0.1#5335 +ipset=/eduplus.hk/gfwlist +server=/manurefetish.com/127.0.0.1#5335 +ipset=/manurefetish.com/gfwlist +server=/pinterest.nz/127.0.0.1#5335 +ipset=/pinterest.nz/gfwlist +server=/wldfnjh.com/127.0.0.1#5335 +ipset=/wldfnjh.com/gfwlist +server=/bmw-motorrad.gt/127.0.0.1#5335 +ipset=/bmw-motorrad.gt/gfwlist +server=/visa.com.sg/127.0.0.1#5335 +ipset=/visa.com.sg/gfwlist +server=/multicurrencycashpassport.com/127.0.0.1#5335 +ipset=/multicurrencycashpassport.com/gfwlist +server=/travelex.co.in/127.0.0.1#5335 +ipset=/travelex.co.in/gfwlist +server=/leakxxx.com/127.0.0.1#5335 +ipset=/leakxxx.com/gfwlist +server=/youtube.qa/127.0.0.1#5335 +ipset=/youtube.qa/gfwlist +server=/pinterest.com.pe/127.0.0.1#5335 +ipset=/pinterest.com.pe/gfwlist +server=/respawnbyrazer.com/127.0.0.1#5335 +ipset=/respawnbyrazer.com/gfwlist +server=/quip.com/127.0.0.1#5335 +ipset=/quip.com/gfwlist +server=/mepn.com/127.0.0.1#5335 +ipset=/mepn.com/gfwlist +server=/go.dev/127.0.0.1#5335 +ipset=/go.dev/gfwlist +server=/thestandnews.com/127.0.0.1#5335 +ipset=/thestandnews.com/gfwlist +server=/perfectkickz.net/127.0.0.1#5335 +ipset=/perfectkickz.net/gfwlist +server=/beatswirelesscheap.com/127.0.0.1#5335 +ipset=/beatswirelesscheap.com/gfwlist +server=/huluasks.com/127.0.0.1#5335 +ipset=/huluasks.com/gfwlist +server=/babushky.club/127.0.0.1#5335 +ipset=/babushky.club/gfwlist +server=/rust-lang.org/127.0.0.1#5335 +ipset=/rust-lang.org/gfwlist +server=/facebookfacebook.com/127.0.0.1#5335 +ipset=/facebookfacebook.com/gfwlist +server=/apple.cl/127.0.0.1#5335 +ipset=/apple.cl/gfwlist +server=/dynacw.com.tw/127.0.0.1#5335 +ipset=/dynacw.com.tw/gfwlist +server=/canon.uz/127.0.0.1#5335 +ipset=/canon.uz/gfwlist +server=/bbestmall.com/127.0.0.1#5335 +ipset=/bbestmall.com/gfwlist +server=/tegrazone.jp/127.0.0.1#5335 +ipset=/tegrazone.jp/gfwlist +server=/51luoli.info/127.0.0.1#5335 +ipset=/51luoli.info/gfwlist +server=/bmw-lebanon.com/127.0.0.1#5335 +ipset=/bmw-lebanon.com/gfwlist +server=/pcloud.tw/127.0.0.1#5335 +ipset=/pcloud.tw/gfwlist +server=/jokerlu1.cc/127.0.0.1#5335 +ipset=/jokerlu1.cc/gfwlist +server=/audio4-ak-spotify-com.akamaized.net/127.0.0.1#5335 +ipset=/audio4-ak-spotify-com.akamaized.net/gfwlist +server=/beatsbydreforsalesonline.com/127.0.0.1#5335 +ipset=/beatsbydreforsalesonline.com/gfwlist +server=/vrpornranked.com/127.0.0.1#5335 +ipset=/vrpornranked.com/gfwlist +server=/mini.jp/127.0.0.1#5335 +ipset=/mini.jp/gfwlist +server=/microsoftreactor.info/127.0.0.1#5335 +ipset=/microsoftreactor.info/gfwlist +server=/nikepioneer.com/127.0.0.1#5335 +ipset=/nikepioneer.com/gfwlist +server=/mini.com.tw/127.0.0.1#5335 +ipset=/mini.com.tw/gfwlist +server=/applepencil.net/127.0.0.1#5335 +ipset=/applepencil.net/gfwlist +server=/vagrantup.com/127.0.0.1#5335 +ipset=/vagrantup.com/gfwlist +server=/intelsecurity.com/127.0.0.1#5335 +ipset=/intelsecurity.com/gfwlist +server=/angelbeats.jp/127.0.0.1#5335 +ipset=/angelbeats.jp/gfwlist +server=/okaapps.com/127.0.0.1#5335 +ipset=/okaapps.com/gfwlist +server=/heraldsun.com.au/127.0.0.1#5335 +ipset=/heraldsun.com.au/gfwlist +server=/bustydanniashe.com/127.0.0.1#5335 +ipset=/bustydanniashe.com/gfwlist +server=/mujikorea.net/127.0.0.1#5335 +ipset=/mujikorea.net/gfwlist +server=/wogx.com/127.0.0.1#5335 +ipset=/wogx.com/gfwlist +server=/streamporn.pw/127.0.0.1#5335 +ipset=/streamporn.pw/gfwlist +server=/fapdude.com/127.0.0.1#5335 +ipset=/fapdude.com/gfwlist +server=/fbboostyourbusiness.com/127.0.0.1#5335 +ipset=/fbboostyourbusiness.com/gfwlist +server=/codeish.co/127.0.0.1#5335 +ipset=/codeish.co/gfwlist +server=/patentgold.net/127.0.0.1#5335 +ipset=/patentgold.net/gfwlist +server=/uun87.com/127.0.0.1#5335 +ipset=/uun87.com/gfwlist +server=/kyodonews.net/127.0.0.1#5335 +ipset=/kyodonews.net/gfwlist +server=/intagram.com/127.0.0.1#5335 +ipset=/intagram.com/gfwlist +server=/minihk.com/127.0.0.1#5335 +ipset=/minihk.com/gfwlist +server=/contentful.com/127.0.0.1#5335 +ipset=/contentful.com/gfwlist +server=/gaybubble.com/127.0.0.1#5335 +ipset=/gaybubble.com/gfwlist +server=/dnaindia.com/127.0.0.1#5335 +ipset=/dnaindia.com/gfwlist +server=/csis-prod.s3.amazonaws.com/127.0.0.1#5335 +ipset=/csis-prod.s3.amazonaws.com/gfwlist +server=/steamvideo-a.akamaihd.net/127.0.0.1#5335 +ipset=/steamvideo-a.akamaihd.net/gfwlist +server=/hdb1.app/127.0.0.1#5335 +ipset=/hdb1.app/gfwlist +server=/plug.game/127.0.0.1#5335 +ipset=/plug.game/gfwlist +server=/chinaeconomicreview.com/127.0.0.1#5335 +ipset=/chinaeconomicreview.com/gfwlist +server=/vercel.live/127.0.0.1#5335 +ipset=/vercel.live/gfwlist +server=/theintelstore.com/127.0.0.1#5335 +ipset=/theintelstore.com/gfwlist +server=/fastlylb.net/127.0.0.1#5335 +ipset=/fastlylb.net/gfwlist +server=/lenkino.xxx/127.0.0.1#5335 +ipset=/lenkino.xxx/gfwlist +server=/sankei-ad.net/127.0.0.1#5335 +ipset=/sankei-ad.net/gfwlist +server=/fuskator.com/127.0.0.1#5335 +ipset=/fuskator.com/gfwlist +server=/monsterbeatscasques.com/127.0.0.1#5335 +ipset=/monsterbeatscasques.com/gfwlist +server=/paypalhere.info/127.0.0.1#5335 +ipset=/paypalhere.info/gfwlist +server=/attvoip.com/127.0.0.1#5335 +ipset=/attvoip.com/gfwlist +server=/intel.ee/127.0.0.1#5335 +ipset=/intel.ee/gfwlist +server=/verisign.ch/127.0.0.1#5335 +ipset=/verisign.ch/gfwlist +server=/jmcomic2.moe/127.0.0.1#5335 +ipset=/jmcomic2.moe/gfwlist +server=/reut.rs/127.0.0.1#5335 +ipset=/reut.rs/gfwlist +server=/myfreeporngames.com/127.0.0.1#5335 +ipset=/myfreeporngames.com/gfwlist +server=/makesenseofdata.com/127.0.0.1#5335 +ipset=/makesenseofdata.com/gfwlist +server=/letsjerk.cc/127.0.0.1#5335 +ipset=/letsjerk.cc/gfwlist +server=/svscomics.asia/127.0.0.1#5335 +ipset=/svscomics.asia/gfwlist +server=/mini.se/127.0.0.1#5335 +ipset=/mini.se/gfwlist +server=/ikea.com.om/127.0.0.1#5335 +ipset=/ikea.com.om/gfwlist +server=/offresspecialesbmw.ca/127.0.0.1#5335 +ipset=/offresspecialesbmw.ca/gfwlist +server=/ietf.org/127.0.0.1#5335 +ipset=/ietf.org/gfwlist +server=/ebay.com.mt/127.0.0.1#5335 +ipset=/ebay.com.mt/gfwlist +server=/katestube.com/127.0.0.1#5335 +ipset=/katestube.com/gfwlist +server=/yahoosandbox.com/127.0.0.1#5335 +ipset=/yahoosandbox.com/gfwlist +server=/spacely.com.au/127.0.0.1#5335 +ipset=/spacely.com.au/gfwlist +server=/assistirhentai.com/127.0.0.1#5335 +ipset=/assistirhentai.com/gfwlist +server=/bmw-motorrad.ee/127.0.0.1#5335 +ipset=/bmw-motorrad.ee/gfwlist +server=/attwirelessinternet.com/127.0.0.1#5335 +ipset=/attwirelessinternet.com/gfwlist +server=/gazounabi.com/127.0.0.1#5335 +ipset=/gazounabi.com/gfwlist +server=/jerk-porn.com/127.0.0.1#5335 +ipset=/jerk-porn.com/gfwlist +server=/fakku.net/127.0.0.1#5335 +ipset=/fakku.net/gfwlist +server=/tkb008.xyz/127.0.0.1#5335 +ipset=/tkb008.xyz/gfwlist +server=/starbucks.fr/127.0.0.1#5335 +ipset=/starbucks.fr/gfwlist +server=/minecraftshop.com/127.0.0.1#5335 +ipset=/minecraftshop.com/gfwlist +server=/porngo.tube/127.0.0.1#5335 +ipset=/porngo.tube/gfwlist +server=/wetpussygames.com/127.0.0.1#5335 +ipset=/wetpussygames.com/gfwlist +server=/facebood.com/127.0.0.1#5335 +ipset=/facebood.com/gfwlist +server=/ntdtv.ru/127.0.0.1#5335 +ipset=/ntdtv.ru/gfwlist +server=/bmwarchiv.de/127.0.0.1#5335 +ipset=/bmwarchiv.de/gfwlist +server=/visabg.com/127.0.0.1#5335 +ipset=/visabg.com/gfwlist +server=/feceboox.com/127.0.0.1#5335 +ipset=/feceboox.com/gfwlist +server=/iphone5casescovers.com/127.0.0.1#5335 +ipset=/iphone5casescovers.com/gfwlist +server=/volvotrucks.co.mz/127.0.0.1#5335 +ipset=/volvotrucks.co.mz/gfwlist +server=/alpinelinux.org/127.0.0.1#5335 +ipset=/alpinelinux.org/gfwlist +server=/dba.dk/127.0.0.1#5335 +ipset=/dba.dk/gfwlist +server=/pali.ltd/127.0.0.1#5335 +ipset=/pali.ltd/gfwlist +server=/livrariart.com.br/127.0.0.1#5335 +ipset=/livrariart.com.br/gfwlist +server=/imlive.com/127.0.0.1#5335 +ipset=/imlive.com/gfwlist +server=/mvk.com/127.0.0.1#5335 +ipset=/mvk.com/gfwlist +server=/mrcong.com/127.0.0.1#5335 +ipset=/mrcong.com/gfwlist +server=/scoreland.com/127.0.0.1#5335 +ipset=/scoreland.com/gfwlist +server=/fburl.com/127.0.0.1#5335 +ipset=/fburl.com/gfwlist +server=/beatselectronicsllc.tt.omtrdc.net/127.0.0.1#5335 +ipset=/beatselectronicsllc.tt.omtrdc.net/gfwlist +server=/keyhole.com/127.0.0.1#5335 +ipset=/keyhole.com/gfwlist +server=/linecorp.com/127.0.0.1#5335 +ipset=/linecorp.com/gfwlist +server=/fuqqt.com/127.0.0.1#5335 +ipset=/fuqqt.com/gfwlist +server=/csnjcbnxdnb.com/127.0.0.1#5335 +ipset=/csnjcbnxdnb.com/gfwlist +server=/porn7.net/127.0.0.1#5335 +ipset=/porn7.net/gfwlist +server=/onindiansex.com/127.0.0.1#5335 +ipset=/onindiansex.com/gfwlist +server=/youtube.com.br/127.0.0.1#5335 +ipset=/youtube.com.br/gfwlist +server=/xbrasilporno.com/127.0.0.1#5335 +ipset=/xbrasilporno.com/gfwlist +server=/beatsbydreforstore.com/127.0.0.1#5335 +ipset=/beatsbydreforstore.com/gfwlist +server=/fapteencam.com/127.0.0.1#5335 +ipset=/fapteencam.com/gfwlist +server=/connectedcommerce.tv/127.0.0.1#5335 +ipset=/connectedcommerce.tv/gfwlist +server=/siteripz.net/127.0.0.1#5335 +ipset=/siteripz.net/gfwlist +server=/twinkspornos.com/127.0.0.1#5335 +ipset=/twinkspornos.com/gfwlist +server=/ctyun.online/127.0.0.1#5335 +ipset=/ctyun.online/gfwlist +server=/18eighteen.com/127.0.0.1#5335 +ipset=/18eighteen.com/gfwlist +server=/msn.com/127.0.0.1#5335 +ipset=/msn.com/gfwlist +server=/bigtitsextapes.com/127.0.0.1#5335 +ipset=/bigtitsextapes.com/gfwlist +server=/javspanking.com/127.0.0.1#5335 +ipset=/javspanking.com/gfwlist +server=/dynacw.com.cn/127.0.0.1#5335 +ipset=/dynacw.com.cn/gfwlist +server=/spotifycharts.com/127.0.0.1#5335 +ipset=/spotifycharts.com/gfwlist +server=/newsadds.com.au/127.0.0.1#5335 +ipset=/newsadds.com.au/gfwlist +server=/riot.im/127.0.0.1#5335 +ipset=/riot.im/gfwlist +server=/animalforsex.com/127.0.0.1#5335 +ipset=/animalforsex.com/gfwlist +server=/maturepornonly.com/127.0.0.1#5335 +ipset=/maturepornonly.com/gfwlist +server=/youtube.ge/127.0.0.1#5335 +ipset=/youtube.ge/gfwlist +server=/minigeorgian.ca/127.0.0.1#5335 +ipset=/minigeorgian.ca/gfwlist +server=/muji.net/127.0.0.1#5335 +ipset=/muji.net/gfwlist +server=/erodouga.8sp.biz/127.0.0.1#5335 +ipset=/erodouga.8sp.biz/gfwlist +server=/chatango.com/127.0.0.1#5335 +ipset=/chatango.com/gfwlist +server=/findbare.com/127.0.0.1#5335 +ipset=/findbare.com/gfwlist +server=/thelancet.com/127.0.0.1#5335 +ipset=/thelancet.com/gfwlist +server=/ebenporno.com/127.0.0.1#5335 +ipset=/ebenporno.com/gfwlist +server=/moystoys.com/127.0.0.1#5335 +ipset=/moystoys.com/gfwlist +server=/google.as/127.0.0.1#5335 +ipset=/google.as/gfwlist +server=/appledaily.com.hk/127.0.0.1#5335 +ipset=/appledaily.com.hk/gfwlist +server=/firestonecomercial.com.br/127.0.0.1#5335 +ipset=/firestonecomercial.com.br/gfwlist +server=/hongkongpost.gov.hk/127.0.0.1#5335 +ipset=/hongkongpost.gov.hk/gfwlist +server=/verily.com/127.0.0.1#5335 +ipset=/verily.com/gfwlist +server=/duckduckgo.jp/127.0.0.1#5335 +ipset=/duckduckgo.jp/gfwlist +server=/twlegs.com/127.0.0.1#5335 +ipset=/twlegs.com/gfwlist +server=/dettol.com.br/127.0.0.1#5335 +ipset=/dettol.com.br/gfwlist +server=/mansurfer.com/127.0.0.1#5335 +ipset=/mansurfer.com/gfwlist +server=/eacashcard.com/127.0.0.1#5335 +ipset=/eacashcard.com/gfwlist +server=/hacksear.ch/127.0.0.1#5335 +ipset=/hacksear.ch/gfwlist +server=/mcdelivery.com.au/127.0.0.1#5335 +ipset=/mcdelivery.com.au/gfwlist +server=/nugettest.org/127.0.0.1#5335 +ipset=/nugettest.org/gfwlist +server=/softbank-jp.com/127.0.0.1#5335 +ipset=/softbank-jp.com/gfwlist +server=/skysportsracing.com/127.0.0.1#5335 +ipset=/skysportsracing.com/gfwlist +server=/onlinegeeksquad.com/127.0.0.1#5335 +ipset=/onlinegeeksquad.com/gfwlist +server=/mygaysites.com/127.0.0.1#5335 +ipset=/mygaysites.com/gfwlist +server=/twitch.tv/127.0.0.1#5335 +ipset=/twitch.tv/gfwlist +server=/beatssaleus.com/127.0.0.1#5335 +ipset=/beatssaleus.com/gfwlist +server=/gayharem.com/127.0.0.1#5335 +ipset=/gayharem.com/gfwlist +server=/strepsils.es/127.0.0.1#5335 +ipset=/strepsils.es/gfwlist +server=/porntsunami.com/127.0.0.1#5335 +ipset=/porntsunami.com/gfwlist +server=/d-upp.com/127.0.0.1#5335 +ipset=/d-upp.com/gfwlist +server=/pornxxx.bid/127.0.0.1#5335 +ipset=/pornxxx.bid/gfwlist +server=/yahoo.im/127.0.0.1#5335 +ipset=/yahoo.im/gfwlist +server=/hulusports.com/127.0.0.1#5335 +ipset=/hulusports.com/gfwlist +server=/firestonetire.ca/127.0.0.1#5335 +ipset=/firestonetire.ca/gfwlist +server=/favepornmovs.com/127.0.0.1#5335 +ipset=/favepornmovs.com/gfwlist +server=/jdbimgs.com/127.0.0.1#5335 +ipset=/jdbimgs.com/gfwlist +server=/tubev.sex/127.0.0.1#5335 +ipset=/tubev.sex/gfwlist +server=/beatsbydreforshop2013-nl.com/127.0.0.1#5335 +ipset=/beatsbydreforshop2013-nl.com/gfwlist +server=/pussyshine.info/127.0.0.1#5335 +ipset=/pussyshine.info/gfwlist +server=/alphabet.com/127.0.0.1#5335 +ipset=/alphabet.com/gfwlist +server=/twoo.com/127.0.0.1#5335 +ipset=/twoo.com/gfwlist +server=/lss55.com/127.0.0.1#5335 +ipset=/lss55.com/gfwlist +server=/ninecommentaries.com/127.0.0.1#5335 +ipset=/ninecommentaries.com/gfwlist +server=/ahmia.fi/127.0.0.1#5335 +ipset=/ahmia.fi/gfwlist +server=/windowsphone.com/127.0.0.1#5335 +ipset=/windowsphone.com/gfwlist +server=/paypal-service.org/127.0.0.1#5335 +ipset=/paypal-service.org/gfwlist +server=/pinkpussy.tv/127.0.0.1#5335 +ipset=/pinkpussy.tv/gfwlist +server=/norsk.mobi/127.0.0.1#5335 +ipset=/norsk.mobi/gfwlist +server=/cheapwirelessbeats.com/127.0.0.1#5335 +ipset=/cheapwirelessbeats.com/gfwlist +server=/cultura-kolomna.ru/127.0.0.1#5335 +ipset=/cultura-kolomna.ru/gfwlist +server=/bestamateurcumshots.com/127.0.0.1#5335 +ipset=/bestamateurcumshots.com/gfwlist +server=/elsevier.io/127.0.0.1#5335 +ipset=/elsevier.io/gfwlist +server=/voatibetan.com/127.0.0.1#5335 +ipset=/voatibetan.com/gfwlist +server=/erogazoufactory.com/127.0.0.1#5335 +ipset=/erogazoufactory.com/gfwlist +server=/av-top.com/127.0.0.1#5335 +ipset=/av-top.com/gfwlist +server=/sankakucomplex.com/127.0.0.1#5335 +ipset=/sankakucomplex.com/gfwlist +server=/paypal-engineering.com/127.0.0.1#5335 +ipset=/paypal-engineering.com/gfwlist +server=/beatspascher.net/127.0.0.1#5335 +ipset=/beatspascher.net/gfwlist +server=/alt7-mtalk.google.com/127.0.0.1#5335 +ipset=/alt7-mtalk.google.com/gfwlist +server=/hentaixxx.vip/127.0.0.1#5335 +ipset=/hentaixxx.vip/gfwlist +server=/efukt.com/127.0.0.1#5335 +ipset=/efukt.com/gfwlist +server=/xxxgirls88.com/127.0.0.1#5335 +ipset=/xxxgirls88.com/gfwlist +server=/gettyimages.ie/127.0.0.1#5335 +ipset=/gettyimages.ie/gfwlist +server=/myporno.photos/127.0.0.1#5335 +ipset=/myporno.photos/gfwlist +server=/isexomega.tw/127.0.0.1#5335 +ipset=/isexomega.tw/gfwlist +server=/fse.tv/127.0.0.1#5335 +ipset=/fse.tv/gfwlist +server=/5mb48g.com/127.0.0.1#5335 +ipset=/5mb48g.com/gfwlist +server=/sun.com/127.0.0.1#5335 +ipset=/sun.com/gfwlist +server=/beatsaudiobydre.net/127.0.0.1#5335 +ipset=/beatsaudiobydre.net/gfwlist +server=/gandhara.ru/127.0.0.1#5335 +ipset=/gandhara.ru/gfwlist +server=/azureplanetscale.info/127.0.0.1#5335 +ipset=/azureplanetscale.info/gfwlist +server=/pornrox.com/127.0.0.1#5335 +ipset=/pornrox.com/gfwlist +server=/bigsex.tv/127.0.0.1#5335 +ipset=/bigsex.tv/gfwlist +server=/asianboygay.com/127.0.0.1#5335 +ipset=/asianboygay.com/gfwlist +server=/amateurhomevids.com/127.0.0.1#5335 +ipset=/amateurhomevids.com/gfwlist +server=/inkchoice.com/127.0.0.1#5335 +ipset=/inkchoice.com/gfwlist +server=/amapornofilme.com/127.0.0.1#5335 +ipset=/amapornofilme.com/gfwlist +server=/activeteachonline.com/127.0.0.1#5335 +ipset=/activeteachonline.com/gfwlist +server=/yahoo.es/127.0.0.1#5335 +ipset=/yahoo.es/gfwlist +server=/google.co.ao/127.0.0.1#5335 +ipset=/google.co.ao/gfwlist +server=/171xx.com/127.0.0.1#5335 +ipset=/171xx.com/gfwlist +server=/anyporn.com/127.0.0.1#5335 +ipset=/anyporn.com/gfwlist +server=/sexy-more.com/127.0.0.1#5335 +ipset=/sexy-more.com/gfwlist +server=/momentumms.com/127.0.0.1#5335 +ipset=/momentumms.com/gfwlist +server=/sexxxtape.net/127.0.0.1#5335 +ipset=/sexxxtape.net/gfwlist +server=/ebayadvertising.com/127.0.0.1#5335 +ipset=/ebayadvertising.com/gfwlist +server=/nii.ac.jp/127.0.0.1#5335 +ipset=/nii.ac.jp/gfwlist +server=/appleappstore.tv/127.0.0.1#5335 +ipset=/appleappstore.tv/gfwlist +server=/infinitetoons.com/127.0.0.1#5335 +ipset=/infinitetoons.com/gfwlist +server=/mini.co.th/127.0.0.1#5335 +ipset=/mini.co.th/gfwlist +server=/cuckporn.com/127.0.0.1#5335 +ipset=/cuckporn.com/gfwlist +server=/tokyoporns.com/127.0.0.1#5335 +ipset=/tokyoporns.com/gfwlist +server=/vfsco.com/127.0.0.1#5335 +ipset=/vfsco.com/gfwlist +server=/navercorp.com/127.0.0.1#5335 +ipset=/navercorp.com/gfwlist +server=/tandf.co.uk/127.0.0.1#5335 +ipset=/tandf.co.uk/gfwlist +server=/microsoft.ge/127.0.0.1#5335 +ipset=/microsoft.ge/gfwlist +server=/javmost.com/127.0.0.1#5335 +ipset=/javmost.com/gfwlist +server=/lovethiscity.com/127.0.0.1#5335 +ipset=/lovethiscity.com/gfwlist +server=/seneporno.com/127.0.0.1#5335 +ipset=/seneporno.com/gfwlist +server=/adventuresbydisney.com/127.0.0.1#5335 +ipset=/adventuresbydisney.com/gfwlist +server=/asiamoviepass.com/127.0.0.1#5335 +ipset=/asiamoviepass.com/gfwlist +server=/tianbiav10.com/127.0.0.1#5335 +ipset=/tianbiav10.com/gfwlist +server=/damplips.com/127.0.0.1#5335 +ipset=/damplips.com/gfwlist +server=/volvotrucks.lt/127.0.0.1#5335 +ipset=/volvotrucks.lt/gfwlist +server=/boycall.com/127.0.0.1#5335 +ipset=/boycall.com/gfwlist +server=/mcstories.com/127.0.0.1#5335 +ipset=/mcstories.com/gfwlist +server=/akamai-access.net/127.0.0.1#5335 +ipset=/akamai-access.net/gfwlist +server=/bumptop.org/127.0.0.1#5335 +ipset=/bumptop.org/gfwlist +server=/fuck.sc/127.0.0.1#5335 +ipset=/fuck.sc/gfwlist +server=/mastercard.fi/127.0.0.1#5335 +ipset=/mastercard.fi/gfwlist +server=/odysee.com/127.0.0.1#5335 +ipset=/odysee.com/gfwlist +server=/ebayprivacycenter.com/127.0.0.1#5335 +ipset=/ebayprivacycenter.com/gfwlist +server=/durex.pt/127.0.0.1#5335 +ipset=/durex.pt/gfwlist +server=/pnas.org/127.0.0.1#5335 +ipset=/pnas.org/gfwlist +server=/boringcompany.com/127.0.0.1#5335 +ipset=/boringcompany.com/gfwlist +server=/apkcombo.com/127.0.0.1#5335 +ipset=/apkcombo.com/gfwlist +server=/infotimes.com.tw/127.0.0.1#5335 +ipset=/infotimes.com.tw/gfwlist +server=/lingeriepornonly.com/127.0.0.1#5335 +ipset=/lingeriepornonly.com/gfwlist +server=/orgasmlist.com/127.0.0.1#5335 +ipset=/orgasmlist.com/gfwlist +server=/uplay-istrip.com/127.0.0.1#5335 +ipset=/uplay-istrip.com/gfwlist +server=/smartline.com.au/127.0.0.1#5335 +ipset=/smartline.com.au/gfwlist +server=/wide-youtube.l.google.com/127.0.0.1#5335 +ipset=/wide-youtube.l.google.com/gfwlist +server=/xhub.tv/127.0.0.1#5335 +ipset=/xhub.tv/gfwlist +server=/bmw-connecteddrive.com.hr/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com.hr/gfwlist +server=/unityads.unitychina.cn/127.0.0.1#5335 +ipset=/unityads.unitychina.cn/gfwlist +server=/superpapermario.com/127.0.0.1#5335 +ipset=/superpapermario.com/gfwlist +server=/qdmomentum.com/127.0.0.1#5335 +ipset=/qdmomentum.com/gfwlist +server=/blogspot.cl/127.0.0.1#5335 +ipset=/blogspot.cl/gfwlist +server=/practicalmoneyskills.jp/127.0.0.1#5335 +ipset=/practicalmoneyskills.jp/gfwlist +server=/realclearfoundation.org/127.0.0.1#5335 +ipset=/realclearfoundation.org/gfwlist +server=/feedburner.com/127.0.0.1#5335 +ipset=/feedburner.com/gfwlist +server=/airwick.com.br/127.0.0.1#5335 +ipset=/airwick.com.br/gfwlist +server=/techtimes.com/127.0.0.1#5335 +ipset=/techtimes.com/gfwlist +server=/espncdn.com/127.0.0.1#5335 +ipset=/espncdn.com/gfwlist +server=/amazonaws.com/127.0.0.1#5335 +ipset=/amazonaws.com/gfwlist +server=/ikea.com.pl/127.0.0.1#5335 +ipset=/ikea.com.pl/gfwlist +server=/acjj.net/127.0.0.1#5335 +ipset=/acjj.net/gfwlist +server=/wuso.me/127.0.0.1#5335 +ipset=/wuso.me/gfwlist +server=/bestbuy-communityrelations.com/127.0.0.1#5335 +ipset=/bestbuy-communityrelations.com/gfwlist +server=/ituneas.com/127.0.0.1#5335 +ipset=/ituneas.com/gfwlist +server=/kyodo-d.jp/127.0.0.1#5335 +ipset=/kyodo-d.jp/gfwlist +server=/blogspot.cz/127.0.0.1#5335 +ipset=/blogspot.cz/gfwlist +server=/vancouverbmwretailers.ca/127.0.0.1#5335 +ipset=/vancouverbmwretailers.ca/gfwlist +server=/spearhead.kr/127.0.0.1#5335 +ipset=/spearhead.kr/gfwlist +server=/visa.co.il/127.0.0.1#5335 +ipset=/visa.co.il/gfwlist +server=/thai-xxx.com/127.0.0.1#5335 +ipset=/thai-xxx.com/gfwlist +server=/facebook-inc.com/127.0.0.1#5335 +ipset=/facebook-inc.com/gfwlist +server=/cloudsync-prod.s3.amazonaws.com/127.0.0.1#5335 +ipset=/cloudsync-prod.s3.amazonaws.com/gfwlist +server=/waplog.com/127.0.0.1#5335 +ipset=/waplog.com/gfwlist +server=/nvidia.dk/127.0.0.1#5335 +ipset=/nvidia.dk/gfwlist +server=/xgsp.tv/127.0.0.1#5335 +ipset=/xgsp.tv/gfwlist +server=/monsterbeats-headphone.com/127.0.0.1#5335 +ipset=/monsterbeats-headphone.com/gfwlist +server=/youtube.co.id/127.0.0.1#5335 +ipset=/youtube.co.id/gfwlist +server=/disneyturkiye.com.tr/127.0.0.1#5335 +ipset=/disneyturkiye.com.tr/gfwlist +server=/iphone.ru/127.0.0.1#5335 +ipset=/iphone.ru/gfwlist +server=/pics.vc/127.0.0.1#5335 +ipset=/pics.vc/gfwlist +server=/redwap.pro/127.0.0.1#5335 +ipset=/redwap.pro/gfwlist +server=/hyperscan.io/127.0.0.1#5335 +ipset=/hyperscan.io/gfwlist +server=/sandisk.fr/127.0.0.1#5335 +ipset=/sandisk.fr/gfwlist +server=/ccievoicelabs.com/127.0.0.1#5335 +ipset=/ccievoicelabs.com/gfwlist +server=/mini-stjohns.ca/127.0.0.1#5335 +ipset=/mini-stjohns.ca/gfwlist +server=/xkorean.cam/127.0.0.1#5335 +ipset=/xkorean.cam/gfwlist +server=/yomiuri-ryokou.co.jp/127.0.0.1#5335 +ipset=/yomiuri-ryokou.co.jp/gfwlist +server=/discord.media/127.0.0.1#5335 +ipset=/discord.media/gfwlist +server=/thomsonreuters.com.tr/127.0.0.1#5335 +ipset=/thomsonreuters.com.tr/gfwlist +server=/timestalks.com/127.0.0.1#5335 +ipset=/timestalks.com/gfwlist +server=/geek-squad.net/127.0.0.1#5335 +ipset=/geek-squad.net/gfwlist +server=/pornvideotop.com/127.0.0.1#5335 +ipset=/pornvideotop.com/gfwlist +server=/qt-project.org/127.0.0.1#5335 +ipset=/qt-project.org/gfwlist +server=/ciscospark.ca/127.0.0.1#5335 +ipset=/ciscospark.ca/gfwlist +server=/headphoneshome.com/127.0.0.1#5335 +ipset=/headphoneshome.com/gfwlist +server=/nurofen.bg/127.0.0.1#5335 +ipset=/nurofen.bg/gfwlist +server=/visa.com.br/127.0.0.1#5335 +ipset=/visa.com.br/gfwlist +server=/pearsonassessments.com/127.0.0.1#5335 +ipset=/pearsonassessments.com/gfwlist +server=/bigbigshop.com/127.0.0.1#5335 +ipset=/bigbigshop.com/gfwlist +server=/streamhentaimovies.com/127.0.0.1#5335 +ipset=/streamhentaimovies.com/gfwlist +server=/hpgraphicspartners.com/127.0.0.1#5335 +ipset=/hpgraphicspartners.com/gfwlist +server=/cnn.com/127.0.0.1#5335 +ipset=/cnn.com/gfwlist +server=/teengirlfriendtube.com/127.0.0.1#5335 +ipset=/teengirlfriendtube.com/gfwlist +server=/adult-list.com/127.0.0.1#5335 +ipset=/adult-list.com/gfwlist +server=/realclearworld.com/127.0.0.1#5335 +ipset=/realclearworld.com/gfwlist +server=/volvotruckcenter.es/127.0.0.1#5335 +ipset=/volvotruckcenter.es/gfwlist +server=/braintreepayments.tv/127.0.0.1#5335 +ipset=/braintreepayments.tv/gfwlist +server=/pokemonrubysapphire.com/127.0.0.1#5335 +ipset=/pokemonrubysapphire.com/gfwlist +server=/yomiuri.co.jp/127.0.0.1#5335 +ipset=/yomiuri.co.jp/gfwlist +server=/finishinfo.cl/127.0.0.1#5335 +ipset=/finishinfo.cl/gfwlist +server=/volvotrucks.uy/127.0.0.1#5335 +ipset=/volvotrucks.uy/gfwlist +server=/viet69.news/127.0.0.1#5335 +ipset=/viet69.news/gfwlist +server=/suxib.com/127.0.0.1#5335 +ipset=/suxib.com/gfwlist +server=/theclubprive.com/127.0.0.1#5335 +ipset=/theclubprive.com/gfwlist +server=/thelittleslush.com/127.0.0.1#5335 +ipset=/thelittleslush.com/gfwlist +server=/starbuckscoffeegear.com/127.0.0.1#5335 +ipset=/starbuckscoffeegear.com/gfwlist +server=/indiangfvideos.com/127.0.0.1#5335 +ipset=/indiangfvideos.com/gfwlist +server=/leporno.org/127.0.0.1#5335 +ipset=/leporno.org/gfwlist +server=/thebestfetishsites.com/127.0.0.1#5335 +ipset=/thebestfetishsites.com/gfwlist +server=/family-sex.me/127.0.0.1#5335 +ipset=/family-sex.me/gfwlist +server=/bitchmomporn.com/127.0.0.1#5335 +ipset=/bitchmomporn.com/gfwlist +server=/creamlemon.info/127.0.0.1#5335 +ipset=/creamlemon.info/gfwlist +server=/fotolia.cc/127.0.0.1#5335 +ipset=/fotolia.cc/gfwlist +server=/niketrainer.com/127.0.0.1#5335 +ipset=/niketrainer.com/gfwlist +server=/zohomerchandise.com/127.0.0.1#5335 +ipset=/zohomerchandise.com/gfwlist +server=/youtube.com.ro/127.0.0.1#5335 +ipset=/youtube.com.ro/gfwlist +server=/fulib711.shop/127.0.0.1#5335 +ipset=/fulib711.shop/gfwlist +server=/sexsaoy.com/127.0.0.1#5335 +ipset=/sexsaoy.com/gfwlist +server=/uhtube.me/127.0.0.1#5335 +ipset=/uhtube.me/gfwlist +server=/beatscheap-uk.com/127.0.0.1#5335 +ipset=/beatscheap-uk.com/gfwlist +server=/kjj05.cn/127.0.0.1#5335 +ipset=/kjj05.cn/gfwlist +server=/ie11.com/127.0.0.1#5335 +ipset=/ie11.com/gfwlist +server=/garena.sg/127.0.0.1#5335 +ipset=/garena.sg/gfwlist +server=/mini.com.sg/127.0.0.1#5335 +ipset=/mini.com.sg/gfwlist +server=/roku.com/127.0.0.1#5335 +ipset=/roku.com/gfwlist +server=/bmw.it/127.0.0.1#5335 +ipset=/bmw.it/gfwlist +server=/xn--urs05q.jp/127.0.0.1#5335 +ipset=/xn--urs05q.jp/gfwlist +server=/kotlinlang.org/127.0.0.1#5335 +ipset=/kotlinlang.org/gfwlist +server=/imdb.com/127.0.0.1#5335 +ipset=/imdb.com/gfwlist +server=/epochtimes.nl/127.0.0.1#5335 +ipset=/epochtimes.nl/gfwlist +server=/trmini.com/127.0.0.1#5335 +ipset=/trmini.com/gfwlist +server=/paisapay.tv/127.0.0.1#5335 +ipset=/paisapay.tv/gfwlist +server=/coursera.community/127.0.0.1#5335 +ipset=/coursera.community/gfwlist +server=/jwpsrv.com/127.0.0.1#5335 +ipset=/jwpsrv.com/gfwlist +server=/vkgo.app/127.0.0.1#5335 +ipset=/vkgo.app/gfwlist +server=/gamesfuckgirls.com/127.0.0.1#5335 +ipset=/gamesfuckgirls.com/gfwlist +server=/nudecelebforum.com/127.0.0.1#5335 +ipset=/nudecelebforum.com/gfwlist +server=/pornwebmasters.com/127.0.0.1#5335 +ipset=/pornwebmasters.com/gfwlist +server=/disneyme.com/127.0.0.1#5335 +ipset=/disneyme.com/gfwlist +server=/vanitha.in/127.0.0.1#5335 +ipset=/vanitha.in/gfwlist +server=/babesandgirls.com/127.0.0.1#5335 +ipset=/babesandgirls.com/gfwlist +server=/thawte.fr/127.0.0.1#5335 +ipset=/thawte.fr/gfwlist +server=/site.com/127.0.0.1#5335 +ipset=/site.com/gfwlist +server=/ieee-pels.org/127.0.0.1#5335 +ipset=/ieee-pels.org/gfwlist +server=/google.sc/127.0.0.1#5335 +ipset=/google.sc/gfwlist +server=/appleone.tech/127.0.0.1#5335 +ipset=/appleone.tech/gfwlist +server=/facebook.in/127.0.0.1#5335 +ipset=/facebook.in/gfwlist +server=/amerikaninsesi.com/127.0.0.1#5335 +ipset=/amerikaninsesi.com/gfwlist +server=/bbci.co.uk/127.0.0.1#5335 +ipset=/bbci.co.uk/gfwlist +server=/madpeople.net/127.0.0.1#5335 +ipset=/madpeople.net/gfwlist +server=/chatwhores.net/127.0.0.1#5335 +ipset=/chatwhores.net/gfwlist +server=/bmw-motorrad-test-ride.com/127.0.0.1#5335 +ipset=/bmw-motorrad-test-ride.com/gfwlist +server=/braintreepayments.info/127.0.0.1#5335 +ipset=/braintreepayments.info/gfwlist +server=/monsterbeatstienda.com/127.0.0.1#5335 +ipset=/monsterbeatstienda.com/gfwlist +server=/ginmoe.com/127.0.0.1#5335 +ipset=/ginmoe.com/gfwlist +server=/sapphicpornonly.com/127.0.0.1#5335 +ipset=/sapphicpornonly.com/gfwlist +server=/foxcincy.com/127.0.0.1#5335 +ipset=/foxcincy.com/gfwlist +server=/darknun.com/127.0.0.1#5335 +ipset=/darknun.com/gfwlist +server=/bloombergforeducation.com/127.0.0.1#5335 +ipset=/bloombergforeducation.com/gfwlist +server=/free-xxx-porn.org/127.0.0.1#5335 +ipset=/free-xxx-porn.org/gfwlist +server=/mindmeld.com/127.0.0.1#5335 +ipset=/mindmeld.com/gfwlist +server=/mobilevrxxx.com/127.0.0.1#5335 +ipset=/mobilevrxxx.com/gfwlist +server=/12diasderegalosdeitunes.com.ni/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.com.ni/gfwlist +server=/realclearbooks.com/127.0.0.1#5335 +ipset=/realclearbooks.com/gfwlist +server=/tonicmovies.com/127.0.0.1#5335 +ipset=/tonicmovies.com/gfwlist +server=/asian-max.com/127.0.0.1#5335 +ipset=/asian-max.com/gfwlist +server=/shemalestube.com/127.0.0.1#5335 +ipset=/shemalestube.com/gfwlist +server=/ancensored.com/127.0.0.1#5335 +ipset=/ancensored.com/gfwlist +server=/clubtubes.com/127.0.0.1#5335 +ipset=/clubtubes.com/gfwlist +server=/nikefuelband.com/127.0.0.1#5335 +ipset=/nikefuelband.com/gfwlist +server=/zunked.com/127.0.0.1#5335 +ipset=/zunked.com/gfwlist +server=/xvideoporno.tv/127.0.0.1#5335 +ipset=/xvideoporno.tv/gfwlist +server=/wnacg.link/127.0.0.1#5335 +ipset=/wnacg.link/gfwlist +server=/adobe.io/127.0.0.1#5335 +ipset=/adobe.io/gfwlist +server=/easportsmma.com/127.0.0.1#5335 +ipset=/easportsmma.com/gfwlist +server=/cuebic.biz/127.0.0.1#5335 +ipset=/cuebic.biz/gfwlist +server=/foxtv.com/127.0.0.1#5335 +ipset=/foxtv.com/gfwlist +server=/anal.casa/127.0.0.1#5335 +ipset=/anal.casa/gfwlist +server=/playvalorant.com/127.0.0.1#5335 +ipset=/playvalorant.com/gfwlist +server=/rebrandly.com/127.0.0.1#5335 +ipset=/rebrandly.com/gfwlist +server=/fi11.com/127.0.0.1#5335 +ipset=/fi11.com/gfwlist +server=/best3dhere.com/127.0.0.1#5335 +ipset=/best3dhere.com/gfwlist +server=/starbucks.dk/127.0.0.1#5335 +ipset=/starbucks.dk/gfwlist +server=/intel-research.net/127.0.0.1#5335 +ipset=/intel-research.net/gfwlist +server=/ieee-ccnc.org/127.0.0.1#5335 +ipset=/ieee-ccnc.org/gfwlist +server=/perfectsexnow.com/127.0.0.1#5335 +ipset=/perfectsexnow.com/gfwlist +server=/trendmicro.com/127.0.0.1#5335 +ipset=/trendmicro.com/gfwlist +server=/toptoonsites.com/127.0.0.1#5335 +ipset=/toptoonsites.com/gfwlist +server=/softbankusa.net/127.0.0.1#5335 +ipset=/softbankusa.net/gfwlist +server=/geoport.com/127.0.0.1#5335 +ipset=/geoport.com/gfwlist +server=/google.je/127.0.0.1#5335 +ipset=/google.je/gfwlist +server=/vanithaveedu.com/127.0.0.1#5335 +ipset=/vanithaveedu.com/gfwlist +server=/ebay.com.ar/127.0.0.1#5335 +ipset=/ebay.com.ar/gfwlist +server=/japan-whores.com/127.0.0.1#5335 +ipset=/japan-whores.com/gfwlist +server=/opte.org/127.0.0.1#5335 +ipset=/opte.org/gfwlist +server=/wetchicks.org/127.0.0.1#5335 +ipset=/wetchicks.org/gfwlist +server=/vscode-sync.trafficmanager.net/127.0.0.1#5335 +ipset=/vscode-sync.trafficmanager.net/gfwlist +server=/fotoiia.com/127.0.0.1#5335 +ipset=/fotoiia.com/gfwlist +server=/myvodafone.com.ws/127.0.0.1#5335 +ipset=/myvodafone.com.ws/gfwlist +server=/mini-grouparchiv.de/127.0.0.1#5335 +ipset=/mini-grouparchiv.de/gfwlist +server=/microsoft-sap-events.com/127.0.0.1#5335 +ipset=/microsoft-sap-events.com/gfwlist +server=/ebaygroup.com/127.0.0.1#5335 +ipset=/ebaygroup.com/gfwlist +server=/chikiporn.com/127.0.0.1#5335 +ipset=/chikiporn.com/gfwlist +server=/cumasianporn.com/127.0.0.1#5335 +ipset=/cumasianporn.com/gfwlist +server=/twitchsvc.net/127.0.0.1#5335 +ipset=/twitchsvc.net/gfwlist +server=/cashify.net/127.0.0.1#5335 +ipset=/cashify.net/gfwlist +server=/sony-asia.com/127.0.0.1#5335 +ipset=/sony-asia.com/gfwlist +server=/mingpaocanada.com/127.0.0.1#5335 +ipset=/mingpaocanada.com/gfwlist +server=/gwins.org/127.0.0.1#5335 +ipset=/gwins.org/gfwlist +server=/buyingfacebooklikes.com/127.0.0.1#5335 +ipset=/buyingfacebooklikes.com/gfwlist +server=/yahoosportsbook.com/127.0.0.1#5335 +ipset=/yahoosportsbook.com/gfwlist +server=/pornv.org/127.0.0.1#5335 +ipset=/pornv.org/gfwlist +server=/gayporn.com/127.0.0.1#5335 +ipset=/gayporn.com/gfwlist +server=/poopeegirls.com/127.0.0.1#5335 +ipset=/poopeegirls.com/gfwlist +server=/coursera.help/127.0.0.1#5335 +ipset=/coursera.help/gfwlist +server=/smart-edge.com/127.0.0.1#5335 +ipset=/smart-edge.com/gfwlist +server=/everydayporn.co/127.0.0.1#5335 +ipset=/everydayporn.co/gfwlist +server=/thecleversense.com/127.0.0.1#5335 +ipset=/thecleversense.com/gfwlist +server=/hentaigasm.com/127.0.0.1#5335 +ipset=/hentaigasm.com/gfwlist +server=/pornid.xxx/127.0.0.1#5335 +ipset=/pornid.xxx/gfwlist +server=/bigbeans.solutions/127.0.0.1#5335 +ipset=/bigbeans.solutions/gfwlist +server=/overthumbs.com/127.0.0.1#5335 +ipset=/overthumbs.com/gfwlist +server=/purenudism.com/127.0.0.1#5335 +ipset=/purenudism.com/gfwlist +server=/steambroadcast.akamaized.net/127.0.0.1#5335 +ipset=/steambroadcast.akamaized.net/gfwlist +server=/mac.wang/127.0.0.1#5335 +ipset=/mac.wang/gfwlist +server=/ie9.com/127.0.0.1#5335 +ipset=/ie9.com/gfwlist +server=/xpee.com/127.0.0.1#5335 +ipset=/xpee.com/gfwlist +server=/creamasia.com/127.0.0.1#5335 +ipset=/creamasia.com/gfwlist +server=/iphone-vip5.com/127.0.0.1#5335 +ipset=/iphone-vip5.com/gfwlist +server=/google.com.pg/127.0.0.1#5335 +ipset=/google.com.pg/gfwlist +server=/kindnudist.com/127.0.0.1#5335 +ipset=/kindnudist.com/gfwlist +server=/xn--ngstr-lra8j.com/127.0.0.1#5335 +ipset=/xn--ngstr-lra8j.com/gfwlist +server=/anatomy.tv/127.0.0.1#5335 +ipset=/anatomy.tv/gfwlist +server=/blogspot.my/127.0.0.1#5335 +ipset=/blogspot.my/gfwlist +server=/dungeonkeeper.com/127.0.0.1#5335 +ipset=/dungeonkeeper.com/gfwlist +server=/tidelift.com/127.0.0.1#5335 +ipset=/tidelift.com/gfwlist +server=/youtube.se/127.0.0.1#5335 +ipset=/youtube.se/gfwlist +server=/fetish-bb.com/127.0.0.1#5335 +ipset=/fetish-bb.com/gfwlist +server=/myfoxdetroit.com/127.0.0.1#5335 +ipset=/myfoxdetroit.com/gfwlist +server=/es-visiontimes.com/127.0.0.1#5335 +ipset=/es-visiontimes.com/gfwlist +server=/sigmoidoscopeexam.com/127.0.0.1#5335 +ipset=/sigmoidoscopeexam.com/gfwlist +server=/yahoo.ie/127.0.0.1#5335 +ipset=/yahoo.ie/gfwlist +server=/voanews.eu/127.0.0.1#5335 +ipset=/voanews.eu/gfwlist +server=/facebookstudios.net/127.0.0.1#5335 +ipset=/facebookstudios.net/gfwlist +server=/vhxqa6.com/127.0.0.1#5335 +ipset=/vhxqa6.com/gfwlist +server=/steamusercontent.com/127.0.0.1#5335 +ipset=/steamusercontent.com/gfwlist +server=/crossborderexpansion.com/127.0.0.1#5335 +ipset=/crossborderexpansion.com/gfwlist +server=/sexgamefun.com/127.0.0.1#5335 +ipset=/sexgamefun.com/gfwlist +server=/bmwusrideracademy.com/127.0.0.1#5335 +ipset=/bmwusrideracademy.com/gfwlist +server=/amzn.to/127.0.0.1#5335 +ipset=/amzn.to/gfwlist +server=/applemusicconnect.com/127.0.0.1#5335 +ipset=/applemusicconnect.com/gfwlist +server=/badoinkvr.com/127.0.0.1#5335 +ipset=/badoinkvr.com/gfwlist +server=/foxsports.info/127.0.0.1#5335 +ipset=/foxsports.info/gfwlist +server=/foxsuper6.com/127.0.0.1#5335 +ipset=/foxsuper6.com/gfwlist +server=/microsoftinternetsafety.net/127.0.0.1#5335 +ipset=/microsoftinternetsafety.net/gfwlist +server=/intgram.com/127.0.0.1#5335 +ipset=/intgram.com/gfwlist +server=/bridgestone-tac-oman.com/127.0.0.1#5335 +ipset=/bridgestone-tac-oman.com/gfwlist +server=/arphic.com.cn/127.0.0.1#5335 +ipset=/arphic.com.cn/gfwlist +server=/miaomwu.com/127.0.0.1#5335 +ipset=/miaomwu.com/gfwlist +server=/qmttqg3k.me/127.0.0.1#5335 +ipset=/qmttqg3k.me/gfwlist +server=/hqcollect.net/127.0.0.1#5335 +ipset=/hqcollect.net/gfwlist +server=/bmw.co.cr/127.0.0.1#5335 +ipset=/bmw.co.cr/gfwlist +server=/imageshack.com/127.0.0.1#5335 +ipset=/imageshack.com/gfwlist +server=/cherrybrady.com/127.0.0.1#5335 +ipset=/cherrybrady.com/gfwlist +server=/photoshop.com/127.0.0.1#5335 +ipset=/photoshop.com/gfwlist +server=/rarbgmirror.com/127.0.0.1#5335 +ipset=/rarbgmirror.com/gfwlist +server=/storiesonline.net/127.0.0.1#5335 +ipset=/storiesonline.net/gfwlist +server=/hindiweb.com/127.0.0.1#5335 +ipset=/hindiweb.com/gfwlist +server=/1jsa22.vip/127.0.0.1#5335 +ipset=/1jsa22.vip/gfwlist +server=/minivaughanwest.ca/127.0.0.1#5335 +ipset=/minivaughanwest.ca/gfwlist +server=/hpsignage.com/127.0.0.1#5335 +ipset=/hpsignage.com/gfwlist +server=/javlands.net/127.0.0.1#5335 +ipset=/javlands.net/gfwlist +server=/ubisoftconnect.com/127.0.0.1#5335 +ipset=/ubisoftconnect.com/gfwlist +server=/coolinet.net/127.0.0.1#5335 +ipset=/coolinet.net/gfwlist +server=/azure-devices.net/127.0.0.1#5335 +ipset=/azure-devices.net/gfwlist +server=/imperiodefamosas.com/127.0.0.1#5335 +ipset=/imperiodefamosas.com/gfwlist +server=/voyeurstyle.com/127.0.0.1#5335 +ipset=/voyeurstyle.com/gfwlist +server=/shopee.cl/127.0.0.1#5335 +ipset=/shopee.cl/gfwlist +server=/shopdrebeats.com/127.0.0.1#5335 +ipset=/shopdrebeats.com/gfwlist +server=/theyxxx.com/127.0.0.1#5335 +ipset=/theyxxx.com/gfwlist +server=/ipodshop.com.au/127.0.0.1#5335 +ipset=/ipodshop.com.au/gfwlist +server=/horsecock.guru/127.0.0.1#5335 +ipset=/horsecock.guru/gfwlist +server=/heroku-charge.com/127.0.0.1#5335 +ipset=/heroku-charge.com/gfwlist +server=/uug22.com/127.0.0.1#5335 +ipset=/uug22.com/gfwlist +server=/microsoftsqlserver.com/127.0.0.1#5335 +ipset=/microsoftsqlserver.com/gfwlist +server=/matureporner.com/127.0.0.1#5335 +ipset=/matureporner.com/gfwlist +server=/vmwarehorizon.com/127.0.0.1#5335 +ipset=/vmwarehorizon.com/gfwlist +server=/hornywhores.net/127.0.0.1#5335 +ipset=/hornywhores.net/gfwlist +server=/verisign.pro/127.0.0.1#5335 +ipset=/verisign.pro/gfwlist +server=/foundationdb.org/127.0.0.1#5335 +ipset=/foundationdb.org/gfwlist +server=/porno365.net/127.0.0.1#5335 +ipset=/porno365.net/gfwlist +server=/amazon.es/127.0.0.1#5335 +ipset=/amazon.es/gfwlist +server=/matters.one/127.0.0.1#5335 +ipset=/matters.one/gfwlist +server=/volvotrucks.hr/127.0.0.1#5335 +ipset=/volvotrucks.hr/gfwlist +server=/alivevmax.com/127.0.0.1#5335 +ipset=/alivevmax.com/gfwlist +server=/geeksquad.net/127.0.0.1#5335 +ipset=/geeksquad.net/gfwlist +server=/instagramcn.com/127.0.0.1#5335 +ipset=/instagramcn.com/gfwlist +server=/itunes.org/127.0.0.1#5335 +ipset=/itunes.org/gfwlist +server=/mrssiren.com/127.0.0.1#5335 +ipset=/mrssiren.com/gfwlist +server=/reachtheworldonfacebook.com/127.0.0.1#5335 +ipset=/reachtheworldonfacebook.com/gfwlist +server=/pornburst.xxx/127.0.0.1#5335 +ipset=/pornburst.xxx/gfwlist +server=/nintendo.co.za/127.0.0.1#5335 +ipset=/nintendo.co.za/gfwlist +server=/whvuxtub.com/127.0.0.1#5335 +ipset=/whvuxtub.com/gfwlist +server=/fb.gg/127.0.0.1#5335 +ipset=/fb.gg/gfwlist +server=/720video.tv/127.0.0.1#5335 +ipset=/720video.tv/gfwlist +server=/commerceos.com/127.0.0.1#5335 +ipset=/commerceos.com/gfwlist +server=/spotifycodes.com/127.0.0.1#5335 +ipset=/spotifycodes.com/gfwlist +server=/gaysheaven.blogspot.com/127.0.0.1#5335 +ipset=/gaysheaven.blogspot.com/gfwlist +server=/poop-pee.online/127.0.0.1#5335 +ipset=/poop-pee.online/gfwlist +server=/minilondon.ca/127.0.0.1#5335 +ipset=/minilondon.ca/gfwlist +server=/google.ms/127.0.0.1#5335 +ipset=/google.ms/gfwlist +server=/nikeairrift.com/127.0.0.1#5335 +ipset=/nikeairrift.com/gfwlist +server=/ippstatic.com/127.0.0.1#5335 +ipset=/ippstatic.com/gfwlist +server=/cisco.mobi/127.0.0.1#5335 +ipset=/cisco.mobi/gfwlist +server=/girl-secret.com/127.0.0.1#5335 +ipset=/girl-secret.com/gfwlist +server=/bmwworld.tv/127.0.0.1#5335 +ipset=/bmwworld.tv/gfwlist +server=/tandfonline.com/127.0.0.1#5335 +ipset=/tandfonline.com/gfwlist +server=/bmw.com.ge/127.0.0.1#5335 +ipset=/bmw.com.ge/gfwlist +server=/ciscosoftware.com/127.0.0.1#5335 +ipset=/ciscosoftware.com/gfwlist +server=/muyzorras.com/127.0.0.1#5335 +ipset=/muyzorras.com/gfwlist +server=/healthreach.hk/127.0.0.1#5335 +ipset=/healthreach.hk/gfwlist +server=/overleaf.com/127.0.0.1#5335 +ipset=/overleaf.com/gfwlist +server=/gaypad.net/127.0.0.1#5335 +ipset=/gaypad.net/gfwlist +server=/intel.com.py/127.0.0.1#5335 +ipset=/intel.com.py/gfwlist +server=/ikea.co.id/127.0.0.1#5335 +ipset=/ikea.co.id/gfwlist +server=/runnike.com/127.0.0.1#5335 +ipset=/runnike.com/gfwlist +server=/wildcamporn.com/127.0.0.1#5335 +ipset=/wildcamporn.com/gfwlist +server=/foxnebraska.com/127.0.0.1#5335 +ipset=/foxnebraska.com/gfwlist +server=/verisign.com.cn/127.0.0.1#5335 +ipset=/verisign.com.cn/gfwlist +server=/plusporn.net/127.0.0.1#5335 +ipset=/plusporn.net/gfwlist +server=/gridaware.app/127.0.0.1#5335 +ipset=/gridaware.app/gfwlist +server=/divas.com.uy/127.0.0.1#5335 +ipset=/divas.com.uy/gfwlist +server=/primepornlist.com/127.0.0.1#5335 +ipset=/primepornlist.com/gfwlist +server=/geeksquadprotectionplan.org/127.0.0.1#5335 +ipset=/geeksquadprotectionplan.org/gfwlist +server=/mcdelivery.com.my/127.0.0.1#5335 +ipset=/mcdelivery.com.my/gfwlist +server=/zooxxxsexporn.red/127.0.0.1#5335 +ipset=/zooxxxsexporn.red/gfwlist +server=/pornhdvideos.tv/127.0.0.1#5335 +ipset=/pornhdvideos.tv/gfwlist +server=/bongacams.com/127.0.0.1#5335 +ipset=/bongacams.com/gfwlist +server=/thomsonreuters.com.sg/127.0.0.1#5335 +ipset=/thomsonreuters.com.sg/gfwlist +server=/beatsbydrediscountonline.net/127.0.0.1#5335 +ipset=/beatsbydrediscountonline.net/gfwlist +server=/instagramhilesi.org/127.0.0.1#5335 +ipset=/instagramhilesi.org/gfwlist +server=/gettyimages.ch/127.0.0.1#5335 +ipset=/gettyimages.ch/gfwlist +server=/fareastpornhub.com/127.0.0.1#5335 +ipset=/fareastpornhub.com/gfwlist +server=/begin-trade.com/127.0.0.1#5335 +ipset=/begin-trade.com/gfwlist +server=/chargenowusa.com/127.0.0.1#5335 +ipset=/chargenowusa.com/gfwlist +server=/strepsils.com.ar/127.0.0.1#5335 +ipset=/strepsils.com.ar/gfwlist +server=/verizon.com/127.0.0.1#5335 +ipset=/verizon.com/gfwlist +server=/judeporn.com/127.0.0.1#5335 +ipset=/judeporn.com/gfwlist +server=/monsterbeatsheadphones.net/127.0.0.1#5335 +ipset=/monsterbeatsheadphones.net/gfwlist +server=/miniso-bh.com/127.0.0.1#5335 +ipset=/miniso-bh.com/gfwlist +server=/cultoferotica.com/127.0.0.1#5335 +ipset=/cultoferotica.com/gfwlist +server=/pornoid.com/127.0.0.1#5335 +ipset=/pornoid.com/gfwlist +server=/datalore.io/127.0.0.1#5335 +ipset=/datalore.io/gfwlist +server=/fnmt.es/127.0.0.1#5335 +ipset=/fnmt.es/gfwlist +server=/thefacebook.com/127.0.0.1#5335 +ipset=/thefacebook.com/gfwlist +server=/newcastlenewslocal.com.au/127.0.0.1#5335 +ipset=/newcastlenewslocal.com.au/gfwlist +server=/enemas4fun.com/127.0.0.1#5335 +ipset=/enemas4fun.com/gfwlist +server=/privatebrowsingmyths.com/127.0.0.1#5335 +ipset=/privatebrowsingmyths.com/gfwlist +server=/alibabacloud.com.au/127.0.0.1#5335 +ipset=/alibabacloud.com.au/gfwlist +server=/stripskunk.com/127.0.0.1#5335 +ipset=/stripskunk.com/gfwlist +server=/intel.sv/127.0.0.1#5335 +ipset=/intel.sv/gfwlist +server=/geolytics.com/127.0.0.1#5335 +ipset=/geolytics.com/gfwlist +server=/dowjones.com/127.0.0.1#5335 +ipset=/dowjones.com/gfwlist +server=/herexxx.com/127.0.0.1#5335 +ipset=/herexxx.com/gfwlist +server=/elib.maruzen.co.jp/127.0.0.1#5335 +ipset=/elib.maruzen.co.jp/gfwlist +server=/ieeesystemscouncil.org/127.0.0.1#5335 +ipset=/ieeesystemscouncil.org/gfwlist +server=/nikeasia.com/127.0.0.1#5335 +ipset=/nikeasia.com/gfwlist +server=/gigaxvideos.com/127.0.0.1#5335 +ipset=/gigaxvideos.com/gfwlist +server=/inxporn.com/127.0.0.1#5335 +ipset=/inxporn.com/gfwlist +server=/vnware.net/127.0.0.1#5335 +ipset=/vnware.net/gfwlist +server=/20thcenturystudios.com.au/127.0.0.1#5335 +ipset=/20thcenturystudios.com.au/gfwlist +server=/classicnike.com/127.0.0.1#5335 +ipset=/classicnike.com/gfwlist +server=/flatpak.org/127.0.0.1#5335 +ipset=/flatpak.org/gfwlist +server=/photo-image.monster/127.0.0.1#5335 +ipset=/photo-image.monster/gfwlist +server=/xxx-hentai.blogspot.com/127.0.0.1#5335 +ipset=/xxx-hentai.blogspot.com/gfwlist +server=/spaceexplored.com/127.0.0.1#5335 +ipset=/spaceexplored.com/gfwlist +server=/powershellgallery.com/127.0.0.1#5335 +ipset=/powershellgallery.com/gfwlist +server=/clasporno.org/127.0.0.1#5335 +ipset=/clasporno.org/gfwlist +server=/movidius.net/127.0.0.1#5335 +ipset=/movidius.net/gfwlist +server=/firestonerewards.com/127.0.0.1#5335 +ipset=/firestonerewards.com/gfwlist +server=/ibookpartner.com/127.0.0.1#5335 +ipset=/ibookpartner.com/gfwlist +server=/fox29.com/127.0.0.1#5335 +ipset=/fox29.com/gfwlist +server=/yahoo.gl/127.0.0.1#5335 +ipset=/yahoo.gl/gfwlist +server=/minitoronto.ca/127.0.0.1#5335 +ipset=/minitoronto.ca/gfwlist +server=/53world.com/127.0.0.1#5335 +ipset=/53world.com/gfwlist +server=/beatsbydrecybermondaydeals2013.com/127.0.0.1#5335 +ipset=/beatsbydrecybermondaydeals2013.com/gfwlist +server=/hentaiathome.net/127.0.0.1#5335 +ipset=/hentaiathome.net/gfwlist +server=/bmw-me.com/127.0.0.1#5335 +ipset=/bmw-me.com/gfwlist +server=/nvidia.co.in/127.0.0.1#5335 +ipset=/nvidia.co.in/gfwlist +server=/nbcsports.com/127.0.0.1#5335 +ipset=/nbcsports.com/gfwlist +server=/paypal-online.net/127.0.0.1#5335 +ipset=/paypal-online.net/gfwlist +server=/situero.com/127.0.0.1#5335 +ipset=/situero.com/gfwlist +server=/tubevintageporn.com/127.0.0.1#5335 +ipset=/tubevintageporn.com/gfwlist +server=/mom-gfs.com/127.0.0.1#5335 +ipset=/mom-gfs.com/gfwlist +server=/steam.apac.qtlglb.com/127.0.0.1#5335 +ipset=/steam.apac.qtlglb.com/gfwlist +server=/xpoleuno.com/127.0.0.1#5335 +ipset=/xpoleuno.com/gfwlist +server=/cashpassportglobe.com/127.0.0.1#5335 +ipset=/cashpassportglobe.com/gfwlist +server=/nudistlog.com/127.0.0.1#5335 +ipset=/nudistlog.com/gfwlist +server=/globalsign.fr/127.0.0.1#5335 +ipset=/globalsign.fr/gfwlist +server=/titsandtugs.com/127.0.0.1#5335 +ipset=/titsandtugs.com/gfwlist +server=/porn300.com/127.0.0.1#5335 +ipset=/porn300.com/gfwlist +server=/paypal-biz.com/127.0.0.1#5335 +ipset=/paypal-biz.com/gfwlist +server=/google.mn/127.0.0.1#5335 +ipset=/google.mn/gfwlist +server=/pinkvelvetvault.com/127.0.0.1#5335 +ipset=/pinkvelvetvault.com/gfwlist +server=/minitakesthestates.com/127.0.0.1#5335 +ipset=/minitakesthestates.com/gfwlist +server=/cenkei.com/127.0.0.1#5335 +ipset=/cenkei.com/gfwlist +server=/bidvestbank.co.za/127.0.0.1#5335 +ipset=/bidvestbank.co.za/gfwlist +server=/pearson.co.jp/127.0.0.1#5335 +ipset=/pearson.co.jp/gfwlist +server=/foxsmallbusinesscenter.net/127.0.0.1#5335 +ipset=/foxsmallbusinesscenter.net/gfwlist +server=/bigtithitomi.com/127.0.0.1#5335 +ipset=/bigtithitomi.com/gfwlist +server=/vanish.ru/127.0.0.1#5335 +ipset=/vanish.ru/gfwlist +server=/hsex.tv/127.0.0.1#5335 +ipset=/hsex.tv/gfwlist +server=/facebok.com/127.0.0.1#5335 +ipset=/facebok.com/gfwlist +server=/travelex.ca/127.0.0.1#5335 +ipset=/travelex.ca/gfwlist +server=/dev.to/127.0.0.1#5335 +ipset=/dev.to/gfwlist +server=/teentube.pro/127.0.0.1#5335 +ipset=/teentube.pro/gfwlist +server=/intel.cr/127.0.0.1#5335 +ipset=/intel.cr/gfwlist +server=/roloflix.com/127.0.0.1#5335 +ipset=/roloflix.com/gfwlist +server=/pm.me/127.0.0.1#5335 +ipset=/pm.me/gfwlist +server=/liveauction.com/127.0.0.1#5335 +ipset=/liveauction.com/gfwlist +server=/d1k2us671qcoau.cloudfront.net/127.0.0.1#5335 +ipset=/d1k2us671qcoau.cloudfront.net/gfwlist +server=/hplargeformatremote.com/127.0.0.1#5335 +ipset=/hplargeformatremote.com/gfwlist +server=/ccpsx.com/127.0.0.1#5335 +ipset=/ccpsx.com/gfwlist +server=/timesmembership.com/127.0.0.1#5335 +ipset=/timesmembership.com/gfwlist +server=/mangoporn.net/127.0.0.1#5335 +ipset=/mangoporn.net/gfwlist +server=/shopbmwmotorcycles.com/127.0.0.1#5335 +ipset=/shopbmwmotorcycles.com/gfwlist +server=/canon.tj/127.0.0.1#5335 +ipset=/canon.tj/gfwlist +server=/rfa.org/127.0.0.1#5335 +ipset=/rfa.org/gfwlist +server=/blackhomeporn.com/127.0.0.1#5335 +ipset=/blackhomeporn.com/gfwlist +server=/interactive-examples.mdn.mozilla.net/127.0.0.1#5335 +ipset=/interactive-examples.mdn.mozilla.net/gfwlist +server=/amateursexpussy.com/127.0.0.1#5335 +ipset=/amateursexpussy.com/gfwlist +server=/aalah.me/127.0.0.1#5335 +ipset=/aalah.me/gfwlist +server=/1lib.tw/127.0.0.1#5335 +ipset=/1lib.tw/gfwlist +server=/mimei.store/127.0.0.1#5335 +ipset=/mimei.store/gfwlist +server=/leaksmodels.com/127.0.0.1#5335 +ipset=/leaksmodels.com/gfwlist +server=/google.me/127.0.0.1#5335 +ipset=/google.me/gfwlist +server=/momsgiveass.com/127.0.0.1#5335 +ipset=/momsgiveass.com/gfwlist +server=/cdn77.org/127.0.0.1#5335 +ipset=/cdn77.org/gfwlist +server=/sankie.net/127.0.0.1#5335 +ipset=/sankie.net/gfwlist +server=/vk.me/127.0.0.1#5335 +ipset=/vk.me/gfwlist +server=/asiansexdiary.com/127.0.0.1#5335 +ipset=/asiansexdiary.com/gfwlist +server=/ioe.com/127.0.0.1#5335 +ipset=/ioe.com/gfwlist +server=/needgayporn.com/127.0.0.1#5335 +ipset=/needgayporn.com/gfwlist +server=/google.com.do/127.0.0.1#5335 +ipset=/google.com.do/gfwlist +server=/babeimpact.com/127.0.0.1#5335 +ipset=/babeimpact.com/gfwlist +server=/sexxx.cfd/127.0.0.1#5335 +ipset=/sexxx.cfd/gfwlist +server=/faceboooik.com/127.0.0.1#5335 +ipset=/faceboooik.com/gfwlist +server=/visa.com.pe/127.0.0.1#5335 +ipset=/visa.com.pe/gfwlist +server=/antarvasnaclips.com/127.0.0.1#5335 +ipset=/antarvasnaclips.com/gfwlist +server=/tube2011.com/127.0.0.1#5335 +ipset=/tube2011.com/gfwlist +server=/beck-online.beck.de/127.0.0.1#5335 +ipset=/beck-online.beck.de/gfwlist +server=/applepaymerchantsupplies.info/127.0.0.1#5335 +ipset=/applepaymerchantsupplies.info/gfwlist +server=/dreamamateurs.com/127.0.0.1#5335 +ipset=/dreamamateurs.com/gfwlist +server=/tophd.xxx/127.0.0.1#5335 +ipset=/tophd.xxx/gfwlist +server=/drebyby.com/127.0.0.1#5335 +ipset=/drebyby.com/gfwlist +server=/mini-corporate-sales.com/127.0.0.1#5335 +ipset=/mini-corporate-sales.com/gfwlist +server=/sankei-shougakukai.jp/127.0.0.1#5335 +ipset=/sankei-shougakukai.jp/gfwlist +server=/sexyhomewives.com/127.0.0.1#5335 +ipset=/sexyhomewives.com/gfwlist +server=/truyentranh86.com/127.0.0.1#5335 +ipset=/truyentranh86.com/gfwlist +server=/tsescortsdirectory.com/127.0.0.1#5335 +ipset=/tsescortsdirectory.com/gfwlist +server=/attwirelesssolutions.com/127.0.0.1#5335 +ipset=/attwirelesssolutions.com/gfwlist +server=/highporn.net/127.0.0.1#5335 +ipset=/highporn.net/gfwlist +server=/babycondom.com/127.0.0.1#5335 +ipset=/babycondom.com/gfwlist +server=/factwire.org/127.0.0.1#5335 +ipset=/factwire.org/gfwlist +server=/cambro.tv/127.0.0.1#5335 +ipset=/cambro.tv/gfwlist +server=/o365weve.com/127.0.0.1#5335 +ipset=/o365weve.com/gfwlist +server=/momhomeporn.com/127.0.0.1#5335 +ipset=/momhomeporn.com/gfwlist +server=/payppal.com/127.0.0.1#5335 +ipset=/payppal.com/gfwlist +server=/hqbabes.com/127.0.0.1#5335 +ipset=/hqbabes.com/gfwlist +server=/b-ok.cc/127.0.0.1#5335 +ipset=/b-ok.cc/gfwlist +server=/volvopenta.us/127.0.0.1#5335 +ipset=/volvopenta.us/gfwlist +server=/myfoxmaine.com/127.0.0.1#5335 +ipset=/myfoxmaine.com/gfwlist +server=/skyoceanrescue.com/127.0.0.1#5335 +ipset=/skyoceanrescue.com/gfwlist +server=/xiuren.org/127.0.0.1#5335 +ipset=/xiuren.org/gfwlist +server=/nurofen.com/127.0.0.1#5335 +ipset=/nurofen.com/gfwlist +server=/visacarddesignlab.com/127.0.0.1#5335 +ipset=/visacarddesignlab.com/gfwlist +server=/bmwiventures.com/127.0.0.1#5335 +ipset=/bmwiventures.com/gfwlist +server=/durexloveclub.com/127.0.0.1#5335 +ipset=/durexloveclub.com/gfwlist +server=/woolitecarpet.com/127.0.0.1#5335 +ipset=/woolitecarpet.com/gfwlist +server=/dump.xxx/127.0.0.1#5335 +ipset=/dump.xxx/gfwlist +server=/bmw-motorrad-service-inclusive.com/127.0.0.1#5335 +ipset=/bmw-motorrad-service-inclusive.com/gfwlist +server=/bingsandbox.com/127.0.0.1#5335 +ipset=/bingsandbox.com/gfwlist +server=/amateurwifetits.com/127.0.0.1#5335 +ipset=/amateurwifetits.com/gfwlist +server=/youtube.ro/127.0.0.1#5335 +ipset=/youtube.ro/gfwlist +server=/thieme-connect.de/127.0.0.1#5335 +ipset=/thieme-connect.de/gfwlist +server=/bestfreetube.xxx/127.0.0.1#5335 +ipset=/bestfreetube.xxx/gfwlist +server=/hothomemade.com/127.0.0.1#5335 +ipset=/hothomemade.com/gfwlist +server=/medone-education.thieme.com/127.0.0.1#5335 +ipset=/medone-education.thieme.com/gfwlist +server=/thomsonreuters.ru/127.0.0.1#5335 +ipset=/thomsonreuters.ru/gfwlist +server=/pearsonenespanol.com/127.0.0.1#5335 +ipset=/pearsonenespanol.com/gfwlist +server=/inasian.club/127.0.0.1#5335 +ipset=/inasian.club/gfwlist +server=/asianpornjav.com/127.0.0.1#5335 +ipset=/asianpornjav.com/gfwlist +server=/ebay.nl/127.0.0.1#5335 +ipset=/ebay.nl/gfwlist +server=/directtvdeals.tv/127.0.0.1#5335 +ipset=/directtvdeals.tv/gfwlist +server=/blogspot.si/127.0.0.1#5335 +ipset=/blogspot.si/gfwlist +server=/ed21.cc/127.0.0.1#5335 +ipset=/ed21.cc/gfwlist +server=/softether.org/127.0.0.1#5335 +ipset=/softether.org/gfwlist +server=/awseducate.org/127.0.0.1#5335 +ipset=/awseducate.org/gfwlist +server=/facebookmarketing.info/127.0.0.1#5335 +ipset=/facebookmarketing.info/gfwlist +server=/youtube.nl/127.0.0.1#5335 +ipset=/youtube.nl/gfwlist +server=/iqq2.cc/127.0.0.1#5335 +ipset=/iqq2.cc/gfwlist +server=/googlee.com/127.0.0.1#5335 +ipset=/googlee.com/gfwlist +server=/yahoo.me/127.0.0.1#5335 +ipset=/yahoo.me/gfwlist +server=/google.cg/127.0.0.1#5335 +ipset=/google.cg/gfwlist +server=/videojs.com/127.0.0.1#5335 +ipset=/videojs.com/gfwlist +server=/lobstertube.com/127.0.0.1#5335 +ipset=/lobstertube.com/gfwlist +server=/visa.com.kz/127.0.0.1#5335 +ipset=/visa.com.kz/gfwlist +server=/forthebadge.com/127.0.0.1#5335 +ipset=/forthebadge.com/gfwlist +server=/rfi.fr/127.0.0.1#5335 +ipset=/rfi.fr/gfwlist +server=/fuxporn.com/127.0.0.1#5335 +ipset=/fuxporn.com/gfwlist +server=/youtube.lu/127.0.0.1#5335 +ipset=/youtube.lu/gfwlist +server=/currently.com/127.0.0.1#5335 +ipset=/currently.com/gfwlist +server=/veetarabia.com/127.0.0.1#5335 +ipset=/veetarabia.com/gfwlist +server=/akamaietpphishingtest.com/127.0.0.1#5335 +ipset=/akamaietpphishingtest.com/gfwlist +server=/free-strip-games.com/127.0.0.1#5335 +ipset=/free-strip-games.com/gfwlist +server=/businessinsider.com.au/127.0.0.1#5335 +ipset=/businessinsider.com.au/gfwlist +server=/babesandstars.com/127.0.0.1#5335 +ipset=/babesandstars.com/gfwlist +server=/facebookpoker.info/127.0.0.1#5335 +ipset=/facebookpoker.info/gfwlist +server=/microsoft.lv/127.0.0.1#5335 +ipset=/microsoft.lv/gfwlist +server=/dazn.com/127.0.0.1#5335 +ipset=/dazn.com/gfwlist +server=/sony.lu/127.0.0.1#5335 +ipset=/sony.lu/gfwlist +server=/sinchew.my/127.0.0.1#5335 +ipset=/sinchew.my/gfwlist +server=/mastercard.com.hk/127.0.0.1#5335 +ipset=/mastercard.com.hk/gfwlist +server=/nintendo.ch/127.0.0.1#5335 +ipset=/nintendo.ch/gfwlist +server=/lge.com/127.0.0.1#5335 +ipset=/lge.com/gfwlist +server=/volvotrucks.com.bn/127.0.0.1#5335 +ipset=/volvotrucks.com.bn/gfwlist +server=/dartlang.org/127.0.0.1#5335 +ipset=/dartlang.org/gfwlist +server=/visa.com.bo/127.0.0.1#5335 +ipset=/visa.com.bo/gfwlist +server=/nudevietnam.com/127.0.0.1#5335 +ipset=/nudevietnam.com/gfwlist +server=/alt1-mtalk.google.com/127.0.0.1#5335 +ipset=/alt1-mtalk.google.com/gfwlist +server=/wikifeet.com/127.0.0.1#5335 +ipset=/wikifeet.com/gfwlist +server=/exec-appointments.com/127.0.0.1#5335 +ipset=/exec-appointments.com/gfwlist +server=/ladies.com/127.0.0.1#5335 +ipset=/ladies.com/gfwlist +server=/strepsilsarabia.com/127.0.0.1#5335 +ipset=/strepsilsarabia.com/gfwlist +server=/fuckup.xxx/127.0.0.1#5335 +ipset=/fuckup.xxx/gfwlist +server=/sexhubhd.com/127.0.0.1#5335 +ipset=/sexhubhd.com/gfwlist +server=/sexo123.net/127.0.0.1#5335 +ipset=/sexo123.net/gfwlist +server=/pankwire.com/127.0.0.1#5335 +ipset=/pankwire.com/gfwlist +server=/foxuv.com/127.0.0.1#5335 +ipset=/foxuv.com/gfwlist +server=/macruby.org/127.0.0.1#5335 +ipset=/macruby.org/gfwlist +server=/fortawesome.com/127.0.0.1#5335 +ipset=/fortawesome.com/gfwlist +server=/ikea.com.ua/127.0.0.1#5335 +ipset=/ikea.com.ua/gfwlist +server=/isheppc.com/127.0.0.1#5335 +ipset=/isheppc.com/gfwlist +server=/handjobcumvideos.com/127.0.0.1#5335 +ipset=/handjobcumvideos.com/gfwlist +server=/headphonesbeatsbydre.com/127.0.0.1#5335 +ipset=/headphonesbeatsbydre.com/gfwlist +server=/dronedj.com/127.0.0.1#5335 +ipset=/dronedj.com/gfwlist +server=/myrimmingporn.com/127.0.0.1#5335 +ipset=/myrimmingporn.com/gfwlist +server=/bmw-businessdrive.com/127.0.0.1#5335 +ipset=/bmw-businessdrive.com/gfwlist +server=/cybertrust.ne.jp/127.0.0.1#5335 +ipset=/cybertrust.ne.jp/gfwlist +server=/azurecosmosdb.net/127.0.0.1#5335 +ipset=/azurecosmosdb.net/gfwlist +server=/farfetch-apps.com/127.0.0.1#5335 +ipset=/farfetch-apps.com/gfwlist +server=/anybunny.tv/127.0.0.1#5335 +ipset=/anybunny.tv/gfwlist +server=/gfashion.com/127.0.0.1#5335 +ipset=/gfashion.com/gfwlist +server=/fanhaodian.com/127.0.0.1#5335 +ipset=/fanhaodian.com/gfwlist +server=/seqing.one/127.0.0.1#5335 +ipset=/seqing.one/gfwlist +server=/mypornstarbook.net/127.0.0.1#5335 +ipset=/mypornstarbook.net/gfwlist +server=/corepublishingsolutions.com/127.0.0.1#5335 +ipset=/corepublishingsolutions.com/gfwlist +server=/exgfvideos.xxx/127.0.0.1#5335 +ipset=/exgfvideos.xxx/gfwlist +server=/buycheapbeatsbydreshop.com/127.0.0.1#5335 +ipset=/buycheapbeatsbydreshop.com/gfwlist +server=/shopee.com.co/127.0.0.1#5335 +ipset=/shopee.com.co/gfwlist +server=/oxyporn.com/127.0.0.1#5335 +ipset=/oxyporn.com/gfwlist +server=/ebay-online.com/127.0.0.1#5335 +ipset=/ebay-online.com/gfwlist +server=/allover30.com/127.0.0.1#5335 +ipset=/allover30.com/gfwlist +server=/ieee-tems.org/127.0.0.1#5335 +ipset=/ieee-tems.org/gfwlist +server=/auntymaza.com/127.0.0.1#5335 +ipset=/auntymaza.com/gfwlist +server=/nomadlandmovie.ch/127.0.0.1#5335 +ipset=/nomadlandmovie.ch/gfwlist +server=/applemusic.co/127.0.0.1#5335 +ipset=/applemusic.co/gfwlist +server=/un.org/127.0.0.1#5335 +ipset=/un.org/gfwlist +server=/itunesmatch.com/127.0.0.1#5335 +ipset=/itunesmatch.com/gfwlist +server=/crossfitfirestone.com/127.0.0.1#5335 +ipset=/crossfitfirestone.com/gfwlist +server=/intel.fi/127.0.0.1#5335 +ipset=/intel.fi/gfwlist +server=/xdir.vip/127.0.0.1#5335 +ipset=/xdir.vip/gfwlist +server=/paypalinc.com/127.0.0.1#5335 +ipset=/paypalinc.com/gfwlist +server=/mastercard.ae/127.0.0.1#5335 +ipset=/mastercard.ae/gfwlist +server=/mcd.com/127.0.0.1#5335 +ipset=/mcd.com/gfwlist +server=/babesmachine.com/127.0.0.1#5335 +ipset=/babesmachine.com/gfwlist +server=/xgroovy.com/127.0.0.1#5335 +ipset=/xgroovy.com/gfwlist +server=/hairydivas.com/127.0.0.1#5335 +ipset=/hairydivas.com/gfwlist +server=/applescript.info/127.0.0.1#5335 +ipset=/applescript.info/gfwlist +server=/pixhost.to/127.0.0.1#5335 +ipset=/pixhost.to/gfwlist +server=/yomilogi.com/127.0.0.1#5335 +ipset=/yomilogi.com/gfwlist +server=/polymer-project.org/127.0.0.1#5335 +ipset=/polymer-project.org/gfwlist +server=/crystalgunnsworld.com/127.0.0.1#5335 +ipset=/crystalgunnsworld.com/gfwlist +server=/xxgasm.com/127.0.0.1#5335 +ipset=/xxgasm.com/gfwlist +server=/indiancolleges.com/127.0.0.1#5335 +ipset=/indiancolleges.com/gfwlist +server=/clubsweethearts.com/127.0.0.1#5335 +ipset=/clubsweethearts.com/gfwlist +server=/bmw-connecteddrive.cz/127.0.0.1#5335 +ipset=/bmw-connecteddrive.cz/gfwlist +server=/webmproject.org/127.0.0.1#5335 +ipset=/webmproject.org/gfwlist +server=/frontiersin.org/127.0.0.1#5335 +ipset=/frontiersin.org/gfwlist +server=/seiron-sankei.com/127.0.0.1#5335 +ipset=/seiron-sankei.com/gfwlist +server=/microsoft.ru/127.0.0.1#5335 +ipset=/microsoft.ru/gfwlist +server=/ipad.wang/127.0.0.1#5335 +ipset=/ipad.wang/gfwlist +server=/coupangcdn.com/127.0.0.1#5335 +ipset=/coupangcdn.com/gfwlist +server=/translatewiki.net/127.0.0.1#5335 +ipset=/translatewiki.net/gfwlist +server=/minimarkham.ca/127.0.0.1#5335 +ipset=/minimarkham.ca/gfwlist +server=/initproducts.com/127.0.0.1#5335 +ipset=/initproducts.com/gfwlist +server=/windowsphone-int.com/127.0.0.1#5335 +ipset=/windowsphone-int.com/gfwlist +server=/wish.com/127.0.0.1#5335 +ipset=/wish.com/gfwlist +server=/babes34.pro/127.0.0.1#5335 +ipset=/babes34.pro/gfwlist +server=/visualstudio-staging.com/127.0.0.1#5335 +ipset=/visualstudio-staging.com/gfwlist +server=/omg.blog/127.0.0.1#5335 +ipset=/omg.blog/gfwlist +server=/pornexpress.net/127.0.0.1#5335 +ipset=/pornexpress.net/gfwlist +server=/whatisworkspaceone.com/127.0.0.1#5335 +ipset=/whatisworkspaceone.com/gfwlist +server=/monsterbeats-solo.com/127.0.0.1#5335 +ipset=/monsterbeats-solo.com/gfwlist +server=/vercel.blog/127.0.0.1#5335 +ipset=/vercel.blog/gfwlist +server=/alpherafinancialservices.es/127.0.0.1#5335 +ipset=/alpherafinancialservices.es/gfwlist +server=/tig-ol-bitties.live/127.0.0.1#5335 +ipset=/tig-ol-bitties.live/gfwlist +server=/epochtimes.com/127.0.0.1#5335 +ipset=/epochtimes.com/gfwlist +server=/yahoo.la/127.0.0.1#5335 +ipset=/yahoo.la/gfwlist +server=/fox4news.com/127.0.0.1#5335 +ipset=/fox4news.com/gfwlist +server=/poshtestgallery.cloudapp.net/127.0.0.1#5335 +ipset=/poshtestgallery.cloudapp.net/gfwlist +server=/sony.ua/127.0.0.1#5335 +ipset=/sony.ua/gfwlist +server=/modeloswebcambogota.com/127.0.0.1#5335 +ipset=/modeloswebcambogota.com/gfwlist +server=/drebeatshome.com/127.0.0.1#5335 +ipset=/drebeatshome.com/gfwlist +server=/babesaround.com/127.0.0.1#5335 +ipset=/babesaround.com/gfwlist +server=/jav2be.com/127.0.0.1#5335 +ipset=/jav2be.com/gfwlist +server=/tiava.com/127.0.0.1#5335 +ipset=/tiava.com/gfwlist +server=/scholar.google.co.cr/127.0.0.1#5335 +ipset=/scholar.google.co.cr/gfwlist +server=/erolabs.com/127.0.0.1#5335 +ipset=/erolabs.com/gfwlist +server=/handbagsoutletebay.com/127.0.0.1#5335 +ipset=/handbagsoutletebay.com/gfwlist +server=/ebay-stories.com/127.0.0.1#5335 +ipset=/ebay-stories.com/gfwlist +server=/bestbuygsm.com/127.0.0.1#5335 +ipset=/bestbuygsm.com/gfwlist +server=/builtfromebay.com/127.0.0.1#5335 +ipset=/builtfromebay.com/gfwlist +server=/dishworld.com/127.0.0.1#5335 +ipset=/dishworld.com/gfwlist +server=/reckittbenckiser.tv/127.0.0.1#5335 +ipset=/reckittbenckiser.tv/gfwlist +server=/amazonstudiosguilds.com/127.0.0.1#5335 +ipset=/amazonstudiosguilds.com/gfwlist +server=/monotypeimaging.com/127.0.0.1#5335 +ipset=/monotypeimaging.com/gfwlist +server=/freepornvideos.life/127.0.0.1#5335 +ipset=/freepornvideos.life/gfwlist +server=/godoc.org/127.0.0.1#5335 +ipset=/godoc.org/gfwlist +server=/chromecast.com/127.0.0.1#5335 +ipset=/chromecast.com/gfwlist +server=/instachecker.com/127.0.0.1#5335 +ipset=/instachecker.com/gfwlist +server=/crazyxxx3dworld.com/127.0.0.1#5335 +ipset=/crazyxxx3dworld.com/gfwlist +server=/coqnu.com/127.0.0.1#5335 +ipset=/coqnu.com/gfwlist +server=/ebscohost.com/127.0.0.1#5335 +ipset=/ebscohost.com/gfwlist +server=/cuckvideos.com/127.0.0.1#5335 +ipset=/cuckvideos.com/gfwlist +server=/asn-online.org/127.0.0.1#5335 +ipset=/asn-online.org/gfwlist +server=/appleone.website/127.0.0.1#5335 +ipset=/appleone.website/gfwlist +server=/theweek.in/127.0.0.1#5335 +ipset=/theweek.in/gfwlist +server=/jijiji.ca/127.0.0.1#5335 +ipset=/jijiji.ca/gfwlist +server=/disney.be/127.0.0.1#5335 +ipset=/disney.be/gfwlist +server=/intel.lt/127.0.0.1#5335 +ipset=/intel.lt/gfwlist +server=/voalingala.com/127.0.0.1#5335 +ipset=/voalingala.com/gfwlist +server=/paypaal.com/127.0.0.1#5335 +ipset=/paypaal.com/gfwlist +server=/thestationbymaker.com/127.0.0.1#5335 +ipset=/thestationbymaker.com/gfwlist +server=/adult3dcomics.com/127.0.0.1#5335 +ipset=/adult3dcomics.com/gfwlist +server=/bridgestone.com.tw/127.0.0.1#5335 +ipset=/bridgestone.com.tw/gfwlist +server=/ww9094.com/127.0.0.1#5335 +ipset=/ww9094.com/gfwlist +server=/needforspeeddriftkings.com/127.0.0.1#5335 +ipset=/needforspeeddriftkings.com/gfwlist +server=/tubegalore.com/127.0.0.1#5335 +ipset=/tubegalore.com/gfwlist +server=/svoboda.org/127.0.0.1#5335 +ipset=/svoboda.org/gfwlist +server=/video-one.com/127.0.0.1#5335 +ipset=/video-one.com/gfwlist +server=/javout.co/127.0.0.1#5335 +ipset=/javout.co/gfwlist +server=/mdn.mozit.cloud/127.0.0.1#5335 +ipset=/mdn.mozit.cloud/gfwlist +server=/fljmh1.com/127.0.0.1#5335 +ipset=/fljmh1.com/gfwlist +server=/huloo.tv/127.0.0.1#5335 +ipset=/huloo.tv/gfwlist +server=/av01.tv/127.0.0.1#5335 +ipset=/av01.tv/gfwlist +server=/cnn.io/127.0.0.1#5335 +ipset=/cnn.io/gfwlist +server=/dubaihotties.org/127.0.0.1#5335 +ipset=/dubaihotties.org/gfwlist +server=/wixanswers.com/127.0.0.1#5335 +ipset=/wixanswers.com/gfwlist +server=/chargenow.com/127.0.0.1#5335 +ipset=/chargenow.com/gfwlist +server=/realclearinvestigations.com/127.0.0.1#5335 +ipset=/realclearinvestigations.com/gfwlist +server=/myporno.cz/127.0.0.1#5335 +ipset=/myporno.cz/gfwlist +server=/nvidia.es/127.0.0.1#5335 +ipset=/nvidia.es/gfwlist +server=/ikea.mx/127.0.0.1#5335 +ipset=/ikea.mx/gfwlist +server=/xnxxcom.club/127.0.0.1#5335 +ipset=/xnxxcom.club/gfwlist +server=/cuckfilmswifefuck.com/127.0.0.1#5335 +ipset=/cuckfilmswifefuck.com/gfwlist +server=/sarajevopodopsadom.com/127.0.0.1#5335 +ipset=/sarajevopodopsadom.com/gfwlist +server=/googletraveladservices.com/127.0.0.1#5335 +ipset=/googletraveladservices.com/gfwlist +server=/onlyiphone5case.com/127.0.0.1#5335 +ipset=/onlyiphone5case.com/gfwlist +server=/pp6.info/127.0.0.1#5335 +ipset=/pp6.info/gfwlist +server=/bodgirls.com/127.0.0.1#5335 +ipset=/bodgirls.com/gfwlist +server=/xvideosjingxiang.com/127.0.0.1#5335 +ipset=/xvideosjingxiang.com/gfwlist +server=/intel.sn/127.0.0.1#5335 +ipset=/intel.sn/gfwlist +server=/desiresecrets.com/127.0.0.1#5335 +ipset=/desiresecrets.com/gfwlist +server=/ebayvakantiehuizen.com/127.0.0.1#5335 +ipset=/ebayvakantiehuizen.com/gfwlist +server=/binance.info/127.0.0.1#5335 +ipset=/binance.info/gfwlist +server=/nodejs.org/127.0.0.1#5335 +ipset=/nodejs.org/gfwlist +server=/celebsroulette.com/127.0.0.1#5335 +ipset=/celebsroulette.com/gfwlist +server=/daboja18.com/127.0.0.1#5335 +ipset=/daboja18.com/gfwlist +server=/scholar.google.com.pk/127.0.0.1#5335 +ipset=/scholar.google.com.pk/gfwlist +server=/hentaipornonly.com/127.0.0.1#5335 +ipset=/hentaipornonly.com/gfwlist +server=/miniso.co.tz/127.0.0.1#5335 +ipset=/miniso.co.tz/gfwlist +server=/sex-amateur-clips.com/127.0.0.1#5335 +ipset=/sex-amateur-clips.com/gfwlist +server=/microsoft.com/127.0.0.1#5335 +ipset=/microsoft.com/gfwlist +server=/erolabs.net/127.0.0.1#5335 +ipset=/erolabs.net/gfwlist +server=/the-m-festival.com/127.0.0.1#5335 +ipset=/the-m-festival.com/gfwlist +server=/osmfoundation.org/127.0.0.1#5335 +ipset=/osmfoundation.org/gfwlist +server=/paypal-communications.net/127.0.0.1#5335 +ipset=/paypal-communications.net/gfwlist +server=/scoop.sh/127.0.0.1#5335 +ipset=/scoop.sh/gfwlist +server=/9hentaiz.com/127.0.0.1#5335 +ipset=/9hentaiz.com/gfwlist +server=/sankei-digital.co.jp/127.0.0.1#5335 +ipset=/sankei-digital.co.jp/gfwlist +server=/ap.org/127.0.0.1#5335 +ipset=/ap.org/gfwlist +server=/nijioma.blog/127.0.0.1#5335 +ipset=/nijioma.blog/gfwlist +server=/xxx-porn-tube.com/127.0.0.1#5335 +ipset=/xxx-porn-tube.com/gfwlist +server=/oxfordpoliticstrove.com/127.0.0.1#5335 +ipset=/oxfordpoliticstrove.com/gfwlist +server=/mini.cz/127.0.0.1#5335 +ipset=/mini.cz/gfwlist +server=/homemadeamateur.com/127.0.0.1#5335 +ipset=/homemadeamateur.com/gfwlist +server=/electrek.co/127.0.0.1#5335 +ipset=/electrek.co/gfwlist +server=/bridgestone.co.in/127.0.0.1#5335 +ipset=/bridgestone.co.in/gfwlist +server=/paypalonline.net/127.0.0.1#5335 +ipset=/paypalonline.net/gfwlist +server=/pchomepay.com.tw/127.0.0.1#5335 +ipset=/pchomepay.com.tw/gfwlist +server=/ebayclassifieds.com/127.0.0.1#5335 +ipset=/ebayclassifieds.com/gfwlist +server=/akamaizercentral.com/127.0.0.1#5335 +ipset=/akamaizercentral.com/gfwlist +server=/youtube.com.om/127.0.0.1#5335 +ipset=/youtube.com.om/gfwlist +server=/monsterbeatsdrdrecheap.com/127.0.0.1#5335 +ipset=/monsterbeatsdrdrecheap.com/gfwlist +server=/mobilefacebook.com/127.0.0.1#5335 +ipset=/mobilefacebook.com/gfwlist +server=/intel.dk/127.0.0.1#5335 +ipset=/intel.dk/gfwlist +server=/pururin.to/127.0.0.1#5335 +ipset=/pururin.to/gfwlist +server=/javmodel.com/127.0.0.1#5335 +ipset=/javmodel.com/gfwlist +server=/doceapower.com/127.0.0.1#5335 +ipset=/doceapower.com/gfwlist +server=/eroticart-top100.com/127.0.0.1#5335 +ipset=/eroticart-top100.com/gfwlist +server=/miniyaletown.ca/127.0.0.1#5335 +ipset=/miniyaletown.ca/gfwlist +server=/volvotrucks.de/127.0.0.1#5335 +ipset=/volvotrucks.de/gfwlist +server=/alibabacloud.com.hk/127.0.0.1#5335 +ipset=/alibabacloud.com.hk/gfwlist +server=/ahpornogratuit.com/127.0.0.1#5335 +ipset=/ahpornogratuit.com/gfwlist +server=/applefinalcutproworld.org/127.0.0.1#5335 +ipset=/applefinalcutproworld.org/gfwlist +server=/tubebdsm.com/127.0.0.1#5335 +ipset=/tubebdsm.com/gfwlist +server=/worldcoinpay.com/127.0.0.1#5335 +ipset=/worldcoinpay.com/gfwlist +server=/nikeitalia.com/127.0.0.1#5335 +ipset=/nikeitalia.com/gfwlist +server=/moapi1.club/127.0.0.1#5335 +ipset=/moapi1.club/gfwlist +server=/ieeecss.org/127.0.0.1#5335 +ipset=/ieeecss.org/gfwlist +server=/xujan.com/127.0.0.1#5335 +ipset=/xujan.com/gfwlist +server=/wwe.com/127.0.0.1#5335 +ipset=/wwe.com/gfwlist +server=/cbsig.net/127.0.0.1#5335 +ipset=/cbsig.net/gfwlist +server=/fusker.xxx/127.0.0.1#5335 +ipset=/fusker.xxx/gfwlist +server=/neurology.org/127.0.0.1#5335 +ipset=/neurology.org/gfwlist +server=/0dzn.com/127.0.0.1#5335 +ipset=/0dzn.com/gfwlist +server=/thinkwithgoogle.com/127.0.0.1#5335 +ipset=/thinkwithgoogle.com/gfwlist +server=/friendfeed-api.com/127.0.0.1#5335 +ipset=/friendfeed-api.com/gfwlist +server=/masalaseen.net/127.0.0.1#5335 +ipset=/masalaseen.net/gfwlist +server=/thegay.com/127.0.0.1#5335 +ipset=/thegay.com/gfwlist +server=/careerjournal.com/127.0.0.1#5335 +ipset=/careerjournal.com/gfwlist +server=/sensualmothers.com/127.0.0.1#5335 +ipset=/sensualmothers.com/gfwlist +server=/beatselectronics.com/127.0.0.1#5335 +ipset=/beatselectronics.com/gfwlist +server=/buymeacoffee.com/127.0.0.1#5335 +ipset=/buymeacoffee.com/gfwlist +server=/bloombergview.com/127.0.0.1#5335 +ipset=/bloombergview.com/gfwlist +server=/duckduckgo.co.uk/127.0.0.1#5335 +ipset=/duckduckgo.co.uk/gfwlist +server=/gettyimages.co.uk/127.0.0.1#5335 +ipset=/gettyimages.co.uk/gfwlist +server=/h528.com/127.0.0.1#5335 +ipset=/h528.com/gfwlist +server=/skebetter.com/127.0.0.1#5335 +ipset=/skebetter.com/gfwlist +server=/beatsbydremall2013.com/127.0.0.1#5335 +ipset=/beatsbydremall2013.com/gfwlist +server=/link69.com/127.0.0.1#5335 +ipset=/link69.com/gfwlist +server=/freenetproject.org/127.0.0.1#5335 +ipset=/freenetproject.org/gfwlist +server=/certsign.ro/127.0.0.1#5335 +ipset=/certsign.ro/gfwlist +server=/asakonet.co.jp/127.0.0.1#5335 +ipset=/asakonet.co.jp/gfwlist +server=/blogspot.jp/127.0.0.1#5335 +ipset=/blogspot.jp/gfwlist +server=/desire-xx.supertop-100.com/127.0.0.1#5335 +ipset=/desire-xx.supertop-100.com/gfwlist +server=/sshs.xyz/127.0.0.1#5335 +ipset=/sshs.xyz/gfwlist +server=/porm.club/127.0.0.1#5335 +ipset=/porm.club/gfwlist +server=/cheap-beatsbydre.com/127.0.0.1#5335 +ipset=/cheap-beatsbydre.com/gfwlist +server=/2lib.org/127.0.0.1#5335 +ipset=/2lib.org/gfwlist +server=/hu1u.com/127.0.0.1#5335 +ipset=/hu1u.com/gfwlist +server=/taptotokyo.com/127.0.0.1#5335 +ipset=/taptotokyo.com/gfwlist +server=/actalis.com/127.0.0.1#5335 +ipset=/actalis.com/gfwlist +server=/bootysource.com/127.0.0.1#5335 +ipset=/bootysource.com/gfwlist +server=/teen-sexy.com/127.0.0.1#5335 +ipset=/teen-sexy.com/gfwlist +server=/dettol.be/127.0.0.1#5335 +ipset=/dettol.be/gfwlist +server=/doujins.com/127.0.0.1#5335 +ipset=/doujins.com/gfwlist +server=/midentsolutions.com/127.0.0.1#5335 +ipset=/midentsolutions.com/gfwlist +server=/bmw.co.ke/127.0.0.1#5335 +ipset=/bmw.co.ke/gfwlist +server=/xvideos-xxxx.com/127.0.0.1#5335 +ipset=/xvideos-xxxx.com/gfwlist +server=/sharpdaily.tw/127.0.0.1#5335 +ipset=/sharpdaily.tw/gfwlist +server=/thekarups.com/127.0.0.1#5335 +ipset=/thekarups.com/gfwlist +server=/4gtv.tv/127.0.0.1#5335 +ipset=/4gtv.tv/gfwlist +server=/amateurhousewifefuck.com/127.0.0.1#5335 +ipset=/amateurhousewifefuck.com/gfwlist +server=/beatsbydrefr.com/127.0.0.1#5335 +ipset=/beatsbydrefr.com/gfwlist +server=/8kpornvids.com/127.0.0.1#5335 +ipset=/8kpornvids.com/gfwlist +server=/theebayshop.com/127.0.0.1#5335 +ipset=/theebayshop.com/gfwlist +server=/visa.com.az/127.0.0.1#5335 +ipset=/visa.com.az/gfwlist +server=/nanonamad.com/127.0.0.1#5335 +ipset=/nanonamad.com/gfwlist +server=/onlineapplestore.com/127.0.0.1#5335 +ipset=/onlineapplestore.com/gfwlist +server=/amateurswingersmovies.com/127.0.0.1#5335 +ipset=/amateurswingersmovies.com/gfwlist +server=/paygonline.com/127.0.0.1#5335 +ipset=/paygonline.com/gfwlist +server=/rbdigitallab.com/127.0.0.1#5335 +ipset=/rbdigitallab.com/gfwlist +server=/yahoo.pl/127.0.0.1#5335 +ipset=/yahoo.pl/gfwlist +server=/adidas.com.sa/127.0.0.1#5335 +ipset=/adidas.com.sa/gfwlist +server=/oxfordfirstsource.com/127.0.0.1#5335 +ipset=/oxfordfirstsource.com/gfwlist +server=/facebookconnect.com/127.0.0.1#5335 +ipset=/facebookconnect.com/gfwlist +server=/thepornbest.com/127.0.0.1#5335 +ipset=/thepornbest.com/gfwlist +server=/disneymagicmoments.de/127.0.0.1#5335 +ipset=/disneymagicmoments.de/gfwlist +server=/bbycontent.com/127.0.0.1#5335 +ipset=/bbycontent.com/gfwlist +server=/bethesdagamestudios.com/127.0.0.1#5335 +ipset=/bethesdagamestudios.com/gfwlist +server=/uflash.tv/127.0.0.1#5335 +ipset=/uflash.tv/gfwlist +server=/slack-msgs.com/127.0.0.1#5335 +ipset=/slack-msgs.com/gfwlist +server=/youtube.sn/127.0.0.1#5335 +ipset=/youtube.sn/gfwlist +server=/blink.org/127.0.0.1#5335 +ipset=/blink.org/gfwlist +server=/googlestore.com/127.0.0.1#5335 +ipset=/googlestore.com/gfwlist +server=/av69.us/127.0.0.1#5335 +ipset=/av69.us/gfwlist +server=/trustdoc.ch/127.0.0.1#5335 +ipset=/trustdoc.ch/gfwlist +server=/nvidia.ru/127.0.0.1#5335 +ipset=/nvidia.ru/gfwlist +server=/likeseiyu.com/127.0.0.1#5335 +ipset=/likeseiyu.com/gfwlist +server=/libgen.rs/127.0.0.1#5335 +ipset=/libgen.rs/gfwlist +server=/peachy18.com/127.0.0.1#5335 +ipset=/peachy18.com/gfwlist +server=/selfloversworld.com/127.0.0.1#5335 +ipset=/selfloversworld.com/gfwlist +server=/videos4sale.com/127.0.0.1#5335 +ipset=/videos4sale.com/gfwlist +server=/minioakville.com/127.0.0.1#5335 +ipset=/minioakville.com/gfwlist +server=/bili888.com/127.0.0.1#5335 +ipset=/bili888.com/gfwlist +server=/ieee-ecce.org/127.0.0.1#5335 +ipset=/ieee-ecce.org/gfwlist +server=/dettol.co.nz/127.0.0.1#5335 +ipset=/dettol.co.nz/gfwlist +server=/gitstar.net/127.0.0.1#5335 +ipset=/gitstar.net/gfwlist +server=/eff.org/127.0.0.1#5335 +ipset=/eff.org/gfwlist +server=/faceboom.com/127.0.0.1#5335 +ipset=/faceboom.com/gfwlist +server=/cartoonregistry.com/127.0.0.1#5335 +ipset=/cartoonregistry.com/gfwlist +server=/nintendo.ru/127.0.0.1#5335 +ipset=/nintendo.ru/gfwlist +server=/makebettercode.com/127.0.0.1#5335 +ipset=/makebettercode.com/gfwlist +server=/veet.se/127.0.0.1#5335 +ipset=/veet.se/gfwlist +server=/fox6now.com/127.0.0.1#5335 +ipset=/fox6now.com/gfwlist +server=/archivx.to/127.0.0.1#5335 +ipset=/archivx.to/gfwlist +server=/thegayoffice.com/127.0.0.1#5335 +ipset=/thegayoffice.com/gfwlist +server=/aaagradeheadphones.com/127.0.0.1#5335 +ipset=/aaagradeheadphones.com/gfwlist +server=/discordmerch.com/127.0.0.1#5335 +ipset=/discordmerch.com/gfwlist +server=/blogspot.kr/127.0.0.1#5335 +ipset=/blogspot.kr/gfwlist +server=/truyenhentai.xyz/127.0.0.1#5335 +ipset=/truyenhentai.xyz/gfwlist +server=/vk.cc/127.0.0.1#5335 +ipset=/vk.cc/gfwlist +server=/dailyporn.club/127.0.0.1#5335 +ipset=/dailyporn.club/gfwlist +server=/braeburncapital.com/127.0.0.1#5335 +ipset=/braeburncapital.com/gfwlist +server=/fbrell.com/127.0.0.1#5335 +ipset=/fbrell.com/gfwlist +server=/amateurpornsexvideos.com/127.0.0.1#5335 +ipset=/amateurpornsexvideos.com/gfwlist +server=/blogspot.se/127.0.0.1#5335 +ipset=/blogspot.se/gfwlist +server=/uun93.com/127.0.0.1#5335 +ipset=/uun93.com/gfwlist +server=/zaobao.com/127.0.0.1#5335 +ipset=/zaobao.com/gfwlist +server=/buyoculus.com/127.0.0.1#5335 +ipset=/buyoculus.com/gfwlist +server=/bmwstep.com/127.0.0.1#5335 +ipset=/bmwstep.com/gfwlist +server=/greatretroporn.com/127.0.0.1#5335 +ipset=/greatretroporn.com/gfwlist +server=/bravotube.net/127.0.0.1#5335 +ipset=/bravotube.net/gfwlist +server=/hanime.me/127.0.0.1#5335 +ipset=/hanime.me/gfwlist +server=/jobmarket.com.hk/127.0.0.1#5335 +ipset=/jobmarket.com.hk/gfwlist +server=/applefruity.com/127.0.0.1#5335 +ipset=/applefruity.com/gfwlist +server=/visa.hu/127.0.0.1#5335 +ipset=/visa.hu/gfwlist +server=/videoskaseros.com/127.0.0.1#5335 +ipset=/videoskaseros.com/gfwlist +server=/paypalcommunity.net/127.0.0.1#5335 +ipset=/paypalcommunity.net/gfwlist +server=/paypal-viewpoints.net/127.0.0.1#5335 +ipset=/paypal-viewpoints.net/gfwlist +server=/newdrediscount.com/127.0.0.1#5335 +ipset=/newdrediscount.com/gfwlist +server=/pchomeonline.com.tw/127.0.0.1#5335 +ipset=/pchomeonline.com.tw/gfwlist +server=/gog.com/127.0.0.1#5335 +ipset=/gog.com/gfwlist +server=/akamaietpmalwaretest.com/127.0.0.1#5335 +ipset=/akamaietpmalwaretest.com/gfwlist +server=/volvotrucks.hu/127.0.0.1#5335 +ipset=/volvotrucks.hu/gfwlist +server=/blogspot.cv/127.0.0.1#5335 +ipset=/blogspot.cv/gfwlist +server=/festinhasbrasil.com/127.0.0.1#5335 +ipset=/festinhasbrasil.com/gfwlist +server=/miniso.ua/127.0.0.1#5335 +ipset=/miniso.ua/gfwlist +server=/adidas.co.uk/127.0.0.1#5335 +ipset=/adidas.co.uk/gfwlist +server=/instangram.com/127.0.0.1#5335 +ipset=/instangram.com/gfwlist +server=/bestpornsites.guide/127.0.0.1#5335 +ipset=/bestpornsites.guide/gfwlist +server=/internet.org/127.0.0.1#5335 +ipset=/internet.org/gfwlist +server=/besthandjobporn.com/127.0.0.1#5335 +ipset=/besthandjobporn.com/gfwlist +server=/ikea.sa/127.0.0.1#5335 +ipset=/ikea.sa/gfwlist +server=/housing.com/127.0.0.1#5335 +ipset=/housing.com/gfwlist +server=/nudebeachpussy.com/127.0.0.1#5335 +ipset=/nudebeachpussy.com/gfwlist +server=/intel.bh/127.0.0.1#5335 +ipset=/intel.bh/gfwlist +server=/microsoft.cat/127.0.0.1#5335 +ipset=/microsoft.cat/gfwlist +server=/pvue1.com/127.0.0.1#5335 +ipset=/pvue1.com/gfwlist +server=/thomsonreuters.co.nz/127.0.0.1#5335 +ipset=/thomsonreuters.co.nz/gfwlist +server=/ebay.in/127.0.0.1#5335 +ipset=/ebay.in/gfwlist +server=/s8ds5gfm.xyz/127.0.0.1#5335 +ipset=/s8ds5gfm.xyz/gfwlist +server=/minimontroyal.ca/127.0.0.1#5335 +ipset=/minimontroyal.ca/gfwlist +server=/usvimosquitoproject.com/127.0.0.1#5335 +ipset=/usvimosquitoproject.com/gfwlist +server=/bmw-connecteddrive.lv/127.0.0.1#5335 +ipset=/bmw-connecteddrive.lv/gfwlist +server=/firestonedrivestore.com/127.0.0.1#5335 +ipset=/firestonedrivestore.com/gfwlist +server=/miniso-np.com/127.0.0.1#5335 +ipset=/miniso-np.com/gfwlist +server=/xxxv.mobi/127.0.0.1#5335 +ipset=/xxxv.mobi/gfwlist +server=/enteentegeh.de/127.0.0.1#5335 +ipset=/enteentegeh.de/gfwlist +server=/homefuckingmovies.com/127.0.0.1#5335 +ipset=/homefuckingmovies.com/gfwlist +server=/casquebeatsenligne.com/127.0.0.1#5335 +ipset=/casquebeatsenligne.com/gfwlist +server=/playcover.io/127.0.0.1#5335 +ipset=/playcover.io/gfwlist +server=/battlebreakers.com/127.0.0.1#5335 +ipset=/battlebreakers.com/gfwlist +server=/pornos.live/127.0.0.1#5335 +ipset=/pornos.live/gfwlist +server=/vrsexgames.biz/127.0.0.1#5335 +ipset=/vrsexgames.biz/gfwlist +server=/onenote.net/127.0.0.1#5335 +ipset=/onenote.net/gfwlist +server=/oldhornymilfs.com/127.0.0.1#5335 +ipset=/oldhornymilfs.com/gfwlist +server=/ok.xxx/127.0.0.1#5335 +ipset=/ok.xxx/gfwlist +server=/paypal-login.us/127.0.0.1#5335 +ipset=/paypal-login.us/gfwlist +server=/bing.com/127.0.0.1#5335 +ipset=/bing.com/gfwlist +server=/desktopmovies.org/127.0.0.1#5335 +ipset=/desktopmovies.org/gfwlist +server=/facebookcredits.info/127.0.0.1#5335 +ipset=/facebookcredits.info/gfwlist +server=/nab.com.au/127.0.0.1#5335 +ipset=/nab.com.au/gfwlist +server=/applestore.me/127.0.0.1#5335 +ipset=/applestore.me/gfwlist +server=/gravatar.com/127.0.0.1#5335 +ipset=/gravatar.com/gfwlist +server=/farfetch.com/127.0.0.1#5335 +ipset=/farfetch.com/gfwlist +server=/giantessbooru.com/127.0.0.1#5335 +ipset=/giantessbooru.com/gfwlist +server=/920share.com/127.0.0.1#5335 +ipset=/920share.com/gfwlist +server=/intel.co.jp/127.0.0.1#5335 +ipset=/intel.co.jp/gfwlist +server=/persianepochtimes.com/127.0.0.1#5335 +ipset=/persianepochtimes.com/gfwlist +server=/ync.ne.jp/127.0.0.1#5335 +ipset=/ync.ne.jp/gfwlist +server=/mybestbuyclaims.com/127.0.0.1#5335 +ipset=/mybestbuyclaims.com/gfwlist +server=/gsrc.io/127.0.0.1#5335 +ipset=/gsrc.io/gfwlist +server=/paypalnetwork.net/127.0.0.1#5335 +ipset=/paypalnetwork.net/gfwlist +server=/intel.ng/127.0.0.1#5335 +ipset=/intel.ng/gfwlist +server=/powerbi.com/127.0.0.1#5335 +ipset=/powerbi.com/gfwlist +server=/httpfacebook.com/127.0.0.1#5335 +ipset=/httpfacebook.com/gfwlist +server=/beatsbydresale-uk.com/127.0.0.1#5335 +ipset=/beatsbydresale-uk.com/gfwlist +server=/lolita.bet/127.0.0.1#5335 +ipset=/lolita.bet/gfwlist +server=/applfe.com/127.0.0.1#5335 +ipset=/applfe.com/gfwlist +server=/bmw.com.kh/127.0.0.1#5335 +ipset=/bmw.com.kh/gfwlist +server=/jsdelivr.net/127.0.0.1#5335 +ipset=/jsdelivr.net/gfwlist +server=/pornmovies2.me/127.0.0.1#5335 +ipset=/pornmovies2.me/gfwlist +server=/youtube.com.ve/127.0.0.1#5335 +ipset=/youtube.com.ve/gfwlist +server=/a-teenz.com/127.0.0.1#5335 +ipset=/a-teenz.com/gfwlist +server=/whatsapp-plus.me/127.0.0.1#5335 +ipset=/whatsapp-plus.me/gfwlist +server=/nikeshoes-store.com/127.0.0.1#5335 +ipset=/nikeshoes-store.com/gfwlist +server=/scat-japan.com/127.0.0.1#5335 +ipset=/scat-japan.com/gfwlist +server=/nvidia.ro/127.0.0.1#5335 +ipset=/nvidia.ro/gfwlist +server=/saffrontech.com/127.0.0.1#5335 +ipset=/saffrontech.com/gfwlist +server=/appleworldwidedeveloper.sc.omtrdc.net/127.0.0.1#5335 +ipset=/appleworldwidedeveloper.sc.omtrdc.net/gfwlist +server=/puretaboo.com/127.0.0.1#5335 +ipset=/puretaboo.com/gfwlist +server=/bustyarianna.com/127.0.0.1#5335 +ipset=/bustyarianna.com/gfwlist +server=/freindfeed.com/127.0.0.1#5335 +ipset=/freindfeed.com/gfwlist +server=/avstar1.com/127.0.0.1#5335 +ipset=/avstar1.com/gfwlist +server=/ieee-npss.org/127.0.0.1#5335 +ipset=/ieee-npss.org/gfwlist +server=/intel.co.uk/127.0.0.1#5335 +ipset=/intel.co.uk/gfwlist +server=/intel.ec/127.0.0.1#5335 +ipset=/intel.ec/gfwlist +server=/pornocd.ru/127.0.0.1#5335 +ipset=/pornocd.ru/gfwlist +server=/pokemonwifi.net/127.0.0.1#5335 +ipset=/pokemonwifi.net/gfwlist +server=/blogspot.com.mt/127.0.0.1#5335 +ipset=/blogspot.com.mt/gfwlist +server=/hentairules.net/127.0.0.1#5335 +ipset=/hentairules.net/gfwlist +server=/duckduckgo.mx/127.0.0.1#5335 +ipset=/duckduckgo.mx/gfwlist +server=/hp-printing.com/127.0.0.1#5335 +ipset=/hp-printing.com/gfwlist +server=/da-files.com/127.0.0.1#5335 +ipset=/da-files.com/gfwlist +server=/ieee-ras.org/127.0.0.1#5335 +ipset=/ieee-ras.org/gfwlist +server=/canada-beatsbydre.com/127.0.0.1#5335 +ipset=/canada-beatsbydre.com/gfwlist +server=/ftadviser.com/127.0.0.1#5335 +ipset=/ftadviser.com/gfwlist +server=/mini.sk/127.0.0.1#5335 +ipset=/mini.sk/gfwlist +server=/velocloud.com/127.0.0.1#5335 +ipset=/velocloud.com/gfwlist +server=/donttrack.us/127.0.0.1#5335 +ipset=/donttrack.us/gfwlist +server=/microsoftlatamaitour.com/127.0.0.1#5335 +ipset=/microsoftlatamaitour.com/gfwlist +server=/bmwsfl.net/127.0.0.1#5335 +ipset=/bmwsfl.net/gfwlist +server=/foxsports.com.ec/127.0.0.1#5335 +ipset=/foxsports.com.ec/gfwlist +server=/officialheadphone.com/127.0.0.1#5335 +ipset=/officialheadphone.com/gfwlist +server=/older.tube/127.0.0.1#5335 +ipset=/older.tube/gfwlist +server=/52hyse.com/127.0.0.1#5335 +ipset=/52hyse.com/gfwlist +server=/youtube.dk/127.0.0.1#5335 +ipset=/youtube.dk/gfwlist +server=/azure-sphere.com/127.0.0.1#5335 +ipset=/azure-sphere.com/gfwlist +server=/twca.com.tw/127.0.0.1#5335 +ipset=/twca.com.tw/gfwlist +server=/hotporn.today/127.0.0.1#5335 +ipset=/hotporn.today/gfwlist +server=/sony.com.co/127.0.0.1#5335 +ipset=/sony.com.co/gfwlist +server=/signalusers.org/127.0.0.1#5335 +ipset=/signalusers.org/gfwlist +server=/sankei.jp/127.0.0.1#5335 +ipset=/sankei.jp/gfwlist +server=/foxdoua.com/127.0.0.1#5335 +ipset=/foxdoua.com/gfwlist +server=/nicesshop.net/127.0.0.1#5335 +ipset=/nicesshop.net/gfwlist +server=/businesscatalyst.com/127.0.0.1#5335 +ipset=/businesscatalyst.com/gfwlist +server=/wmfusercontent.org/127.0.0.1#5335 +ipset=/wmfusercontent.org/gfwlist +server=/on.cc/127.0.0.1#5335 +ipset=/on.cc/gfwlist +server=/disneyjunior.com/127.0.0.1#5335 +ipset=/disneyjunior.com/gfwlist +server=/nikeshoeswon.com/127.0.0.1#5335 +ipset=/nikeshoeswon.com/gfwlist +server=/cuckoldinterracialwife.com/127.0.0.1#5335 +ipset=/cuckoldinterracialwife.com/gfwlist +server=/zeebioskop.com/127.0.0.1#5335 +ipset=/zeebioskop.com/gfwlist +server=/foxon.com/127.0.0.1#5335 +ipset=/foxon.com/gfwlist +server=/interactivesex.xxx/127.0.0.1#5335 +ipset=/interactivesex.xxx/gfwlist +server=/durex.com.pe/127.0.0.1#5335 +ipset=/durex.com.pe/gfwlist +server=/manporn.xxx/127.0.0.1#5335 +ipset=/manporn.xxx/gfwlist +server=/bustyinescudna.com/127.0.0.1#5335 +ipset=/bustyinescudna.com/gfwlist +server=/youtubeeducation.com/127.0.0.1#5335 +ipset=/youtubeeducation.com/gfwlist +server=/google.at/127.0.0.1#5335 +ipset=/google.at/gfwlist +server=/windows8.hk/127.0.0.1#5335 +ipset=/windows8.hk/gfwlist +server=/amsterdamluxescort.com/127.0.0.1#5335 +ipset=/amsterdamluxescort.com/gfwlist +server=/youtubefanfest.com/127.0.0.1#5335 +ipset=/youtubefanfest.com/gfwlist +server=/bloomberglabs.com/127.0.0.1#5335 +ipset=/bloomberglabs.com/gfwlist +server=/visadigitalconcierge.com/127.0.0.1#5335 +ipset=/visadigitalconcierge.com/gfwlist +server=/bestbuy-int.com/127.0.0.1#5335 +ipset=/bestbuy-int.com/gfwlist +server=/pinterest.co.at/127.0.0.1#5335 +ipset=/pinterest.co.at/gfwlist +server=/hpinkjet.com/127.0.0.1#5335 +ipset=/hpinkjet.com/gfwlist +server=/xplr.co/127.0.0.1#5335 +ipset=/xplr.co/gfwlist +server=/directvoffercodes.com/127.0.0.1#5335 +ipset=/directvoffercodes.com/gfwlist +server=/quip-cdn.com/127.0.0.1#5335 +ipset=/quip-cdn.com/gfwlist +server=/beth.games/127.0.0.1#5335 +ipset=/beth.games/gfwlist +server=/xn--r8jwklh769hk43amcfoyl3z3a.com/127.0.0.1#5335 +ipset=/xn--r8jwklh769hk43amcfoyl3z3a.com/gfwlist +server=/ipfs.eternum.io/127.0.0.1#5335 +ipset=/ipfs.eternum.io/gfwlist +server=/pornhail.com/127.0.0.1#5335 +ipset=/pornhail.com/gfwlist +server=/xbx.lv/127.0.0.1#5335 +ipset=/xbx.lv/gfwlist +server=/faceobook.com/127.0.0.1#5335 +ipset=/faceobook.com/gfwlist +server=/newsxtend.com.au/127.0.0.1#5335 +ipset=/newsxtend.com.au/gfwlist +server=/brave.com/127.0.0.1#5335 +ipset=/brave.com/gfwlist +server=/friendfeed-media.com/127.0.0.1#5335 +ipset=/friendfeed-media.com/gfwlist +server=/ikea.fr/127.0.0.1#5335 +ipset=/ikea.fr/gfwlist +server=/whichav.video/127.0.0.1#5335 +ipset=/whichav.video/gfwlist +server=/beatssbyaustralia.com/127.0.0.1#5335 +ipset=/beatssbyaustralia.com/gfwlist +server=/xnxx3.com/127.0.0.1#5335 +ipset=/xnxx3.com/gfwlist +server=/qualcomm.de/127.0.0.1#5335 +ipset=/qualcomm.de/gfwlist +server=/managed-pki.ch/127.0.0.1#5335 +ipset=/managed-pki.ch/gfwlist +server=/newsfeed.com/127.0.0.1#5335 +ipset=/newsfeed.com/gfwlist +server=/xxxpornozinho.blog.br/127.0.0.1#5335 +ipset=/xxxpornozinho.blog.br/gfwlist +server=/freeadultgames.tv/127.0.0.1#5335 +ipset=/freeadultgames.tv/gfwlist +server=/onbeatsbydresale.com/127.0.0.1#5335 +ipset=/onbeatsbydresale.com/gfwlist +server=/nikkei4946.com/127.0.0.1#5335 +ipset=/nikkei4946.com/gfwlist +server=/firestonecomercial.com.ar/127.0.0.1#5335 +ipset=/firestonecomercial.com.ar/gfwlist +server=/telekom.com/127.0.0.1#5335 +ipset=/telekom.com/gfwlist +server=/twitterflightschool.com/127.0.0.1#5335 +ipset=/twitterflightschool.com/gfwlist +server=/certificat2.com/127.0.0.1#5335 +ipset=/certificat2.com/gfwlist +server=/geilegratisporno.com/127.0.0.1#5335 +ipset=/geilegratisporno.com/gfwlist +server=/amazon.de/127.0.0.1#5335 +ipset=/amazon.de/gfwlist +server=/faceboak.com/127.0.0.1#5335 +ipset=/faceboak.com/gfwlist +server=/limelight.com/127.0.0.1#5335 +ipset=/limelight.com/gfwlist +server=/nikefirm.com/127.0.0.1#5335 +ipset=/nikefirm.com/gfwlist +server=/airsextube.com/127.0.0.1#5335 +ipset=/airsextube.com/gfwlist +server=/appspot.com/127.0.0.1#5335 +ipset=/appspot.com/gfwlist +server=/pornxvideos.tv/127.0.0.1#5335 +ipset=/pornxvideos.tv/gfwlist +server=/videos6.com/127.0.0.1#5335 +ipset=/videos6.com/gfwlist +server=/748av.com/127.0.0.1#5335 +ipset=/748av.com/gfwlist +server=/disney.sg/127.0.0.1#5335 +ipset=/disney.sg/gfwlist +server=/intellinuxwireless.net/127.0.0.1#5335 +ipset=/intellinuxwireless.net/gfwlist +server=/1drv.ms/127.0.0.1#5335 +ipset=/1drv.ms/gfwlist +server=/h-top.supertop-100.com/127.0.0.1#5335 +ipset=/h-top.supertop-100.com/gfwlist +server=/typography.com/127.0.0.1#5335 +ipset=/typography.com/gfwlist +server=/peepholecam.com/127.0.0.1#5335 +ipset=/peepholecam.com/gfwlist +server=/atandt.com/127.0.0.1#5335 +ipset=/atandt.com/gfwlist +server=/ieee-isto.org/127.0.0.1#5335 +ipset=/ieee-isto.org/gfwlist +server=/intellinuxgraphics.com/127.0.0.1#5335 +ipset=/intellinuxgraphics.com/gfwlist +server=/ikea.com.tr/127.0.0.1#5335 +ipset=/ikea.com.tr/gfwlist +server=/findsav.com/127.0.0.1#5335 +ipset=/findsav.com/gfwlist +server=/alotporn.com/127.0.0.1#5335 +ipset=/alotporn.com/gfwlist +server=/bmw-museum.net/127.0.0.1#5335 +ipset=/bmw-museum.net/gfwlist +server=/alphera.es/127.0.0.1#5335 +ipset=/alphera.es/gfwlist +server=/beatsbydrecybermondaydeals2013.net/127.0.0.1#5335 +ipset=/beatsbydrecybermondaydeals2013.net/gfwlist +server=/bloombergtax.com/127.0.0.1#5335 +ipset=/bloombergtax.com/gfwlist +server=/sexdollsshow.com/127.0.0.1#5335 +ipset=/sexdollsshow.com/gfwlist +server=/jav4you.org/127.0.0.1#5335 +ipset=/jav4you.org/gfwlist +server=/panoramio.com/127.0.0.1#5335 +ipset=/panoramio.com/gfwlist +server=/fasttrackreadysupport.com/127.0.0.1#5335 +ipset=/fasttrackreadysupport.com/gfwlist +server=/socrec.org/127.0.0.1#5335 +ipset=/socrec.org/gfwlist +server=/bmwondemandusa.com/127.0.0.1#5335 +ipset=/bmwondemandusa.com/gfwlist +server=/reconjet.com/127.0.0.1#5335 +ipset=/reconjet.com/gfwlist +server=/mini-connected.no/127.0.0.1#5335 +ipset=/mini-connected.no/gfwlist +server=/ebay.com.my/127.0.0.1#5335 +ipset=/ebay.com.my/gfwlist +server=/drdrebeats-chen.com/127.0.0.1#5335 +ipset=/drdrebeats-chen.com/gfwlist +server=/hot-sex-photos.com/127.0.0.1#5335 +ipset=/hot-sex-photos.com/gfwlist +server=/yahoo.tg/127.0.0.1#5335 +ipset=/yahoo.tg/gfwlist +server=/fine-art-nude.org/127.0.0.1#5335 +ipset=/fine-art-nude.org/gfwlist +server=/gayroom.com/127.0.0.1#5335 +ipset=/gayroom.com/gfwlist +server=/fuckingawesome.com/127.0.0.1#5335 +ipset=/fuckingawesome.com/gfwlist +server=/darknaija.com/127.0.0.1#5335 +ipset=/darknaija.com/gfwlist +server=/fappeningbook.com/127.0.0.1#5335 +ipset=/fappeningbook.com/gfwlist +server=/gamboporn.com/127.0.0.1#5335 +ipset=/gamboporn.com/gfwlist +server=/bmwwholesaleconnect.com/127.0.0.1#5335 +ipset=/bmwwholesaleconnect.com/gfwlist +server=/nyaa.net/127.0.0.1#5335 +ipset=/nyaa.net/gfwlist +server=/b3boos.com/127.0.0.1#5335 +ipset=/b3boos.com/gfwlist +server=/xvidios.blog/127.0.0.1#5335 +ipset=/xvidios.blog/gfwlist +server=/akamaized.net/127.0.0.1#5335 +ipset=/akamaized.net/gfwlist +server=/spotifyforbrands.com/127.0.0.1#5335 +ipset=/spotifyforbrands.com/gfwlist +server=/u9a9.com/127.0.0.1#5335 +ipset=/u9a9.com/gfwlist +server=/elifesciences.org/127.0.0.1#5335 +ipset=/elifesciences.org/gfwlist +server=/volvobuses.no/127.0.0.1#5335 +ipset=/volvobuses.no/gfwlist +server=/nike-air-max.com/127.0.0.1#5335 +ipset=/nike-air-max.com/gfwlist +server=/vod-abematv.akamaized.net/127.0.0.1#5335 +ipset=/vod-abematv.akamaized.net/gfwlist +server=/evropaelire.org/127.0.0.1#5335 +ipset=/evropaelire.org/gfwlist +server=/sinchew.com.my/127.0.0.1#5335 +ipset=/sinchew.com.my/gfwlist +server=/ayudanintendo.com/127.0.0.1#5335 +ipset=/ayudanintendo.com/gfwlist +server=/omoplanet.com/127.0.0.1#5335 +ipset=/omoplanet.com/gfwlist +server=/sony.cl/127.0.0.1#5335 +ipset=/sony.cl/gfwlist +server=/pikabu.monster/127.0.0.1#5335 +ipset=/pikabu.monster/gfwlist +server=/nikkei.com/127.0.0.1#5335 +ipset=/nikkei.com/gfwlist +server=/mature-amateur-sex.com/127.0.0.1#5335 +ipset=/mature-amateur-sex.com/gfwlist +server=/mortein.com.pk/127.0.0.1#5335 +ipset=/mortein.com.pk/gfwlist +server=/bmwasia.com/127.0.0.1#5335 +ipset=/bmwasia.com/gfwlist +server=/appleaustralia.com/127.0.0.1#5335 +ipset=/appleaustralia.com/gfwlist +server=/youngteenhomeporn.com/127.0.0.1#5335 +ipset=/youngteenhomeporn.com/gfwlist +server=/bmw-connecteddrive.lu/127.0.0.1#5335 +ipset=/bmw-connecteddrive.lu/gfwlist +server=/flirtmoms.com/127.0.0.1#5335 +ipset=/flirtmoms.com/gfwlist +server=/my9nj.com/127.0.0.1#5335 +ipset=/my9nj.com/gfwlist +server=/nikeliuxiang.com/127.0.0.1#5335 +ipset=/nikeliuxiang.com/gfwlist +server=/mastercardadvisors.com/127.0.0.1#5335 +ipset=/mastercardadvisors.com/gfwlist +server=/scholar.google.no/127.0.0.1#5335 +ipset=/scholar.google.no/gfwlist +server=/r18av.com/127.0.0.1#5335 +ipset=/r18av.com/gfwlist +server=/vanish.com.pe/127.0.0.1#5335 +ipset=/vanish.com.pe/gfwlist +server=/orgasm.com/127.0.0.1#5335 +ipset=/orgasm.com/gfwlist +server=/youtube.ba/127.0.0.1#5335 +ipset=/youtube.ba/gfwlist +server=/elpube-scat-movies.blogspot.com/127.0.0.1#5335 +ipset=/elpube-scat-movies.blogspot.com/gfwlist +server=/hulutv.com/127.0.0.1#5335 +ipset=/hulutv.com/gfwlist +server=/gnom-cham.com/127.0.0.1#5335 +ipset=/gnom-cham.com/gfwlist +server=/ibonedyourmom.com/127.0.0.1#5335 +ipset=/ibonedyourmom.com/gfwlist +server=/pornocarioca.com/127.0.0.1#5335 +ipset=/pornocarioca.com/gfwlist +server=/addthisedge.com/127.0.0.1#5335 +ipset=/addthisedge.com/gfwlist +server=/pearsoned.co.nz/127.0.0.1#5335 +ipset=/pearsoned.co.nz/gfwlist +server=/manga-mill.com/127.0.0.1#5335 +ipset=/manga-mill.com/gfwlist +server=/nvidia.co.at/127.0.0.1#5335 +ipset=/nvidia.co.at/gfwlist +server=/andysparis.com/127.0.0.1#5335 +ipset=/andysparis.com/gfwlist +server=/alpherafs.my/127.0.0.1#5335 +ipset=/alpherafs.my/gfwlist +server=/imac.co/127.0.0.1#5335 +ipset=/imac.co/gfwlist +server=/icloud.si/127.0.0.1#5335 +ipset=/icloud.si/gfwlist +server=/redd.it/127.0.0.1#5335 +ipset=/redd.it/gfwlist +server=/litv.tv/127.0.0.1#5335 +ipset=/litv.tv/gfwlist +server=/thesims.com/127.0.0.1#5335 +ipset=/thesims.com/gfwlist +server=/apple.pt/127.0.0.1#5335 +ipset=/apple.pt/gfwlist +server=/netarabic.com/127.0.0.1#5335 +ipset=/netarabic.com/gfwlist +server=/rootsigning.com/127.0.0.1#5335 +ipset=/rootsigning.com/gfwlist +server=/lovesexbody.com/127.0.0.1#5335 +ipset=/lovesexbody.com/gfwlist +server=/airmay.com/127.0.0.1#5335 +ipset=/airmay.com/gfwlist +server=/avstar8.com/127.0.0.1#5335 +ipset=/avstar8.com/gfwlist +server=/firmaprofesional.com/127.0.0.1#5335 +ipset=/firmaprofesional.com/gfwlist +server=/arxiv.org/127.0.0.1#5335 +ipset=/arxiv.org/gfwlist +server=/arabianchicks.com/127.0.0.1#5335 +ipset=/arabianchicks.com/gfwlist +server=/siege-amazon.com/127.0.0.1#5335 +ipset=/siege-amazon.com/gfwlist +server=/nixos.org/127.0.0.1#5335 +ipset=/nixos.org/gfwlist +server=/javhd3x.com/127.0.0.1#5335 +ipset=/javhd3x.com/gfwlist +server=/pornotree.com/127.0.0.1#5335 +ipset=/pornotree.com/gfwlist +server=/1xbet.co.ke/127.0.0.1#5335 +ipset=/1xbet.co.ke/gfwlist +server=/bmw.co.za/127.0.0.1#5335 +ipset=/bmw.co.za/gfwlist +server=/khayannpyar.blogspot.com/127.0.0.1#5335 +ipset=/khayannpyar.blogspot.com/gfwlist +server=/ptt.cc/127.0.0.1#5335 +ipset=/ptt.cc/gfwlist +server=/heroku.co/127.0.0.1#5335 +ipset=/heroku.co/gfwlist +server=/da3dsoul.dev/127.0.0.1#5335 +ipset=/da3dsoul.dev/gfwlist +server=/verisign.hk/127.0.0.1#5335 +ipset=/verisign.hk/gfwlist +server=/fbidb.io/127.0.0.1#5335 +ipset=/fbidb.io/gfwlist +server=/cartoonscity.com/127.0.0.1#5335 +ipset=/cartoonscity.com/gfwlist +server=/vanish.se/127.0.0.1#5335 +ipset=/vanish.se/gfwlist +server=/faronics.kayako.com/127.0.0.1#5335 +ipset=/faronics.kayako.com/gfwlist +server=/xn--p8j9a0d9c9a.xn--q9jyb4c/127.0.0.1#5335 +ipset=/xn--p8j9a0d9c9a.xn--q9jyb4c/gfwlist +server=/bestporntube.me/127.0.0.1#5335 +ipset=/bestporntube.me/gfwlist +server=/javfull.net/127.0.0.1#5335 +ipset=/javfull.net/gfwlist +server=/topcoder.com/127.0.0.1#5335 +ipset=/topcoder.com/gfwlist +server=/miniusaservice.com/127.0.0.1#5335 +ipset=/miniusaservice.com/gfwlist +server=/recoiljs.org/127.0.0.1#5335 +ipset=/recoiljs.org/gfwlist +server=/meraki-go.com/127.0.0.1#5335 +ipset=/meraki-go.com/gfwlist +server=/faceebok.com/127.0.0.1#5335 +ipset=/faceebok.com/gfwlist +server=/steamstatic.com/127.0.0.1#5335 +ipset=/steamstatic.com/gfwlist +server=/repsils.no/127.0.0.1#5335 +ipset=/repsils.no/gfwlist +server=/yahoo.ch/127.0.0.1#5335 +ipset=/yahoo.ch/gfwlist +server=/intel.se/127.0.0.1#5335 +ipset=/intel.se/gfwlist +server=/foxsports.com.py/127.0.0.1#5335 +ipset=/foxsports.com.py/gfwlist +server=/api.news/127.0.0.1#5335 +ipset=/api.news/gfwlist +server=/mendeley.com/127.0.0.1#5335 +ipset=/mendeley.com/gfwlist +server=/wixmp.com/127.0.0.1#5335 +ipset=/wixmp.com/gfwlist +server=/ciscolivehls-i.akamaihd.net/127.0.0.1#5335 +ipset=/ciscolivehls-i.akamaihd.net/gfwlist +server=/applf.com/127.0.0.1#5335 +ipset=/applf.com/gfwlist +server=/futanarihq.com/127.0.0.1#5335 +ipset=/futanarihq.com/gfwlist +server=/jmcomic.moe/127.0.0.1#5335 +ipset=/jmcomic.moe/gfwlist +server=/ipleadership.org/127.0.0.1#5335 +ipset=/ipleadership.org/gfwlist +server=/babepedia.com/127.0.0.1#5335 +ipset=/babepedia.com/gfwlist +server=/slotbitches.com/127.0.0.1#5335 +ipset=/slotbitches.com/gfwlist +server=/ikea.com.ro/127.0.0.1#5335 +ipset=/ikea.com.ro/gfwlist +server=/112263.com/127.0.0.1#5335 +ipset=/112263.com/gfwlist +server=/volvotruckcenter.be/127.0.0.1#5335 +ipset=/volvotruckcenter.be/gfwlist +server=/ura-akiba.jp/127.0.0.1#5335 +ipset=/ura-akiba.jp/gfwlist +server=/tfhub.dev/127.0.0.1#5335 +ipset=/tfhub.dev/gfwlist +server=/bmw-welt.com/127.0.0.1#5335 +ipset=/bmw-welt.com/gfwlist +server=/bmwpittsburgh.com/127.0.0.1#5335 +ipset=/bmwpittsburgh.com/gfwlist +server=/jinmantiankong.com/127.0.0.1#5335 +ipset=/jinmantiankong.com/gfwlist +server=/xxxsexzoo.com/127.0.0.1#5335 +ipset=/xxxsexzoo.com/gfwlist +server=/venmo.s3.amazonaws.com/127.0.0.1#5335 +ipset=/venmo.s3.amazonaws.com/gfwlist +server=/xnxxsexclips.com/127.0.0.1#5335 +ipset=/xnxxsexclips.com/gfwlist +server=/dojindb.net/127.0.0.1#5335 +ipset=/dojindb.net/gfwlist +server=/tbib.org/127.0.0.1#5335 +ipset=/tbib.org/gfwlist +server=/mobile.de/127.0.0.1#5335 +ipset=/mobile.de/gfwlist +server=/blogspot.ie/127.0.0.1#5335 +ipset=/blogspot.ie/gfwlist +server=/freehdvideos.xxx/127.0.0.1#5335 +ipset=/freehdvideos.xxx/gfwlist +server=/alphabet.co.za/127.0.0.1#5335 +ipset=/alphabet.co.za/gfwlist +server=/xxxvideo.world/127.0.0.1#5335 +ipset=/xxxvideo.world/gfwlist +server=/donkeykongcountryreturns.com/127.0.0.1#5335 +ipset=/donkeykongcountryreturns.com/gfwlist +server=/2beatsdre.com/127.0.0.1#5335 +ipset=/2beatsdre.com/gfwlist +server=/3d-comics.com/127.0.0.1#5335 +ipset=/3d-comics.com/gfwlist +server=/camgirlvideos.org/127.0.0.1#5335 +ipset=/camgirlvideos.org/gfwlist +server=/duckduckgo.dk/127.0.0.1#5335 +ipset=/duckduckgo.dk/gfwlist +server=/onestore.ms/127.0.0.1#5335 +ipset=/onestore.ms/gfwlist +server=/watchmyexgf.net/127.0.0.1#5335 +ipset=/watchmyexgf.net/gfwlist +server=/heinonline.org/127.0.0.1#5335 +ipset=/heinonline.org/gfwlist +server=/ddg.gg/127.0.0.1#5335 +ipset=/ddg.gg/gfwlist +server=/macbook.tw/127.0.0.1#5335 +ipset=/macbook.tw/gfwlist +server=/ixnxx.tv/127.0.0.1#5335 +ipset=/ixnxx.tv/gfwlist +server=/what-fan.net/127.0.0.1#5335 +ipset=/what-fan.net/gfwlist +server=/ebayjewelry.com/127.0.0.1#5335 +ipset=/ebayjewelry.com/gfwlist +server=/onsaletrend.com/127.0.0.1#5335 +ipset=/onsaletrend.com/gfwlist +server=/hmd.site/127.0.0.1#5335 +ipset=/hmd.site/gfwlist +server=/dgwav.com/127.0.0.1#5335 +ipset=/dgwav.com/gfwlist +server=/facebookland.com/127.0.0.1#5335 +ipset=/facebookland.com/gfwlist +server=/db.tt/127.0.0.1#5335 +ipset=/db.tt/gfwlist +server=/bmw-motorrad.pa/127.0.0.1#5335 +ipset=/bmw-motorrad.pa/gfwlist +server=/getcomposer.org/127.0.0.1#5335 +ipset=/getcomposer.org/gfwlist +server=/akamai-platform-internal.net/127.0.0.1#5335 +ipset=/akamai-platform-internal.net/gfwlist +server=/sego8.xyz/127.0.0.1#5335 +ipset=/sego8.xyz/gfwlist +server=/airwick.si/127.0.0.1#5335 +ipset=/airwick.si/gfwlist +server=/bmwjamaica.com/127.0.0.1#5335 +ipset=/bmwjamaica.com/gfwlist +server=/pornozona.tv/127.0.0.1#5335 +ipset=/pornozona.tv/gfwlist +server=/comodo.net/127.0.0.1#5335 +ipset=/comodo.net/gfwlist +server=/githubapp.com/127.0.0.1#5335 +ipset=/githubapp.com/gfwlist +server=/usatodaynetworkservice.com/127.0.0.1#5335 +ipset=/usatodaynetworkservice.com/gfwlist +server=/apple.co.th/127.0.0.1#5335 +ipset=/apple.co.th/gfwlist +server=/javwide.tv/127.0.0.1#5335 +ipset=/javwide.tv/gfwlist +server=/haitenjp.com/127.0.0.1#5335 +ipset=/haitenjp.com/gfwlist +server=/visaluxuryhotelcollection.com.br/127.0.0.1#5335 +ipset=/visaluxuryhotelcollection.com.br/gfwlist +server=/volvobuses.mx/127.0.0.1#5335 +ipset=/volvobuses.mx/gfwlist +server=/topyoungporn.com/127.0.0.1#5335 +ipset=/topyoungporn.com/gfwlist +server=/shopifystatus.com/127.0.0.1#5335 +ipset=/shopifystatus.com/gfwlist +server=/danmarkbeatsbydrdre.com/127.0.0.1#5335 +ipset=/danmarkbeatsbydrdre.com/gfwlist +server=/oxfordaasc.com/127.0.0.1#5335 +ipset=/oxfordaasc.com/gfwlist +server=/thepornlinks.com/127.0.0.1#5335 +ipset=/thepornlinks.com/gfwlist +server=/snapseed.com/127.0.0.1#5335 +ipset=/snapseed.com/gfwlist +server=/tictoc.video/127.0.0.1#5335 +ipset=/tictoc.video/gfwlist +server=/vmtestdrive.com/127.0.0.1#5335 +ipset=/vmtestdrive.com/gfwlist +server=/volvotrucks.mn/127.0.0.1#5335 +ipset=/volvotrucks.mn/gfwlist +server=/gogocdn.net/127.0.0.1#5335 +ipset=/gogocdn.net/gfwlist +server=/comodoca.com/127.0.0.1#5335 +ipset=/comodoca.com/gfwlist +server=/ipadpro.buzz/127.0.0.1#5335 +ipset=/ipadpro.buzz/gfwlist +server=/hulu.com/127.0.0.1#5335 +ipset=/hulu.com/gfwlist +server=/bmw-mountains.com/127.0.0.1#5335 +ipset=/bmw-mountains.com/gfwlist +server=/google.com.sl/127.0.0.1#5335 +ipset=/google.com.sl/gfwlist +server=/wwwfacebook.com/127.0.0.1#5335 +ipset=/wwwfacebook.com/gfwlist +server=/adultgameson.com/127.0.0.1#5335 +ipset=/adultgameson.com/gfwlist +server=/myfoxatlanta.com/127.0.0.1#5335 +ipset=/myfoxatlanta.com/gfwlist +server=/beatspaschers.net/127.0.0.1#5335 +ipset=/beatspaschers.net/gfwlist +server=/stackoverflow.email/127.0.0.1#5335 +ipset=/stackoverflow.email/gfwlist +server=/lysol.net/127.0.0.1#5335 +ipset=/lysol.net/gfwlist +server=/spankwire.com/127.0.0.1#5335 +ipset=/spankwire.com/gfwlist +server=/nurofen.at/127.0.0.1#5335 +ipset=/nurofen.at/gfwlist +server=/facebooik.com/127.0.0.1#5335 +ipset=/facebooik.com/gfwlist +server=/spankmonster.com/127.0.0.1#5335 +ipset=/spankmonster.com/gfwlist +server=/miniso.co/127.0.0.1#5335 +ipset=/miniso.co/gfwlist +server=/businessinsider.co.za/127.0.0.1#5335 +ipset=/businessinsider.co.za/gfwlist +server=/brazzers-porno.online/127.0.0.1#5335 +ipset=/brazzers-porno.online/gfwlist +server=/sportstream.com/127.0.0.1#5335 +ipset=/sportstream.com/gfwlist +server=/yourdailypornvideos.ws/127.0.0.1#5335 +ipset=/yourdailypornvideos.ws/gfwlist +server=/facebook-hardware.com/127.0.0.1#5335 +ipset=/facebook-hardware.com/gfwlist +server=/sexandsplash.com/127.0.0.1#5335 +ipset=/sexandsplash.com/gfwlist +server=/realcleareducation.com/127.0.0.1#5335 +ipset=/realcleareducation.com/gfwlist +server=/shopee.co.id/127.0.0.1#5335 +ipset=/shopee.co.id/gfwlist +server=/fishmpegs.com/127.0.0.1#5335 +ipset=/fishmpegs.com/gfwlist +server=/submityourflicks.com/127.0.0.1#5335 +ipset=/submityourflicks.com/gfwlist +server=/ieee-edusociety.org/127.0.0.1#5335 +ipset=/ieee-edusociety.org/gfwlist +server=/bloomberg.cn/127.0.0.1#5335 +ipset=/bloomberg.cn/gfwlist +server=/redtube.com/127.0.0.1#5335 +ipset=/redtube.com/gfwlist +server=/clearlinux.org/127.0.0.1#5335 +ipset=/clearlinux.org/gfwlist +server=/tweetdeck.com/127.0.0.1#5335 +ipset=/tweetdeck.com/gfwlist +server=/connectcommerce.tv/127.0.0.1#5335 +ipset=/connectcommerce.tv/gfwlist +server=/aboutamazon.eu/127.0.0.1#5335 +ipset=/aboutamazon.eu/gfwlist +server=/picacn.xyz/127.0.0.1#5335 +ipset=/picacn.xyz/gfwlist +server=/yibaochina.com/127.0.0.1#5335 +ipset=/yibaochina.com/gfwlist +server=/hentaidude.com/127.0.0.1#5335 +ipset=/hentaidude.com/gfwlist +server=/gostorego.com/127.0.0.1#5335 +ipset=/gostorego.com/gfwlist +server=/intel.com.pe/127.0.0.1#5335 +ipset=/intel.com.pe/gfwlist +server=/waskucity.com/127.0.0.1#5335 +ipset=/waskucity.com/gfwlist +server=/apple-expo.eu/127.0.0.1#5335 +ipset=/apple-expo.eu/gfwlist +server=/4chan.org/127.0.0.1#5335 +ipset=/4chan.org/gfwlist +server=/discoveryplus.com/127.0.0.1#5335 +ipset=/discoveryplus.com/gfwlist +server=/paypal-sptam.com/127.0.0.1#5335 +ipset=/paypal-sptam.com/gfwlist +server=/feacbook.com/127.0.0.1#5335 +ipset=/feacbook.com/gfwlist +server=/amp.dev/127.0.0.1#5335 +ipset=/amp.dev/gfwlist +server=/xxxifuck.com/127.0.0.1#5335 +ipset=/xxxifuck.com/gfwlist +server=/nikepress.com/127.0.0.1#5335 +ipset=/nikepress.com/gfwlist +server=/nintendo3ds.com/127.0.0.1#5335 +ipset=/nintendo3ds.com/gfwlist +server=/hentaixxxvids.com/127.0.0.1#5335 +ipset=/hentaixxxvids.com/gfwlist +server=/spreadprivacy.com/127.0.0.1#5335 +ipset=/spreadprivacy.com/gfwlist +server=/shadbase.com/127.0.0.1#5335 +ipset=/shadbase.com/gfwlist +server=/zishy.com/127.0.0.1#5335 +ipset=/zishy.com/gfwlist +server=/dailytelegraph.com.au/127.0.0.1#5335 +ipset=/dailytelegraph.com.au/gfwlist +server=/insider.com/127.0.0.1#5335 +ipset=/insider.com/gfwlist +server=/hqtrannytube.com/127.0.0.1#5335 +ipset=/hqtrannytube.com/gfwlist +server=/41maonn.com/127.0.0.1#5335 +ipset=/41maonn.com/gfwlist +server=/furaffinity.net/127.0.0.1#5335 +ipset=/furaffinity.net/gfwlist +server=/hentai.game/127.0.0.1#5335 +ipset=/hentai.game/gfwlist +server=/bmw-connected-drive.com/127.0.0.1#5335 +ipset=/bmw-connected-drive.com/gfwlist +server=/kamisama-maeda-lab.com/127.0.0.1#5335 +ipset=/kamisama-maeda-lab.com/gfwlist +server=/yahoo.bt/127.0.0.1#5335 +ipset=/yahoo.bt/gfwlist +server=/microsoft.vn/127.0.0.1#5335 +ipset=/microsoft.vn/gfwlist +server=/mojang.com/127.0.0.1#5335 +ipset=/mojang.com/gfwlist +server=/naughtytugs.com/127.0.0.1#5335 +ipset=/naughtytugs.com/gfwlist +server=/perverttube.com/127.0.0.1#5335 +ipset=/perverttube.com/gfwlist +server=/pearsonclinical.no/127.0.0.1#5335 +ipset=/pearsonclinical.no/gfwlist +server=/instagda.com/127.0.0.1#5335 +ipset=/instagda.com/gfwlist +server=/thestandard.com.hk/127.0.0.1#5335 +ipset=/thestandard.com.hk/gfwlist +server=/twittercommunity.com/127.0.0.1#5335 +ipset=/twittercommunity.com/gfwlist +server=/youtube.md/127.0.0.1#5335 +ipset=/youtube.md/gfwlist +server=/whychooseview.com/127.0.0.1#5335 +ipset=/whychooseview.com/gfwlist +server=/amazon-adsystem.com/127.0.0.1#5335 +ipset=/amazon-adsystem.com/gfwlist +server=/penisbot.com/127.0.0.1#5335 +ipset=/penisbot.com/gfwlist +server=/uverse.com/127.0.0.1#5335 +ipset=/uverse.com/gfwlist +server=/nataliefiore.com/127.0.0.1#5335 +ipset=/nataliefiore.com/gfwlist +server=/bmw.com.bd/127.0.0.1#5335 +ipset=/bmw.com.bd/gfwlist +server=/shemalebestlabel.com/127.0.0.1#5335 +ipset=/shemalebestlabel.com/gfwlist +server=/microsoftstore.com.hk/127.0.0.1#5335 +ipset=/microsoftstore.com.hk/gfwlist +server=/imoviestage.com/127.0.0.1#5335 +ipset=/imoviestage.com/gfwlist +server=/oraclefoundation.org/127.0.0.1#5335 +ipset=/oraclefoundation.org/gfwlist +server=/amateurgalore.net/127.0.0.1#5335 +ipset=/amateurgalore.net/gfwlist +server=/epochtimes.com.sg/127.0.0.1#5335 +ipset=/epochtimes.com.sg/gfwlist +server=/minivictoria.com/127.0.0.1#5335 +ipset=/minivictoria.com/gfwlist +server=/shopifycloud.com/127.0.0.1#5335 +ipset=/shopifycloud.com/gfwlist +server=/icloud.ro/127.0.0.1#5335 +ipset=/icloud.ro/gfwlist +server=/attcenter.com/127.0.0.1#5335 +ipset=/attcenter.com/gfwlist +server=/canon-cmos-sensors.com/127.0.0.1#5335 +ipset=/canon-cmos-sensors.com/gfwlist +server=/xvideosbrasileiro.net/127.0.0.1#5335 +ipset=/xvideosbrasileiro.net/gfwlist +server=/ebaytrading.com/127.0.0.1#5335 +ipset=/ebaytrading.com/gfwlist +server=/pornolaba.mobi/127.0.0.1#5335 +ipset=/pornolaba.mobi/gfwlist +server=/calgon.fr/127.0.0.1#5335 +ipset=/calgon.fr/gfwlist +server=/visa.fi/127.0.0.1#5335 +ipset=/visa.fi/gfwlist +server=/kscisco.com/127.0.0.1#5335 +ipset=/kscisco.com/gfwlist +server=/akamaientrypoint.net/127.0.0.1#5335 +ipset=/akamaientrypoint.net/gfwlist +server=/bidorbuyindia.com/127.0.0.1#5335 +ipset=/bidorbuyindia.com/gfwlist +server=/vanishstains.com/127.0.0.1#5335 +ipset=/vanishstains.com/gfwlist +server=/sportswomenoftheyear.co.uk/127.0.0.1#5335 +ipset=/sportswomenoftheyear.co.uk/gfwlist +server=/dyncdn.me/127.0.0.1#5335 +ipset=/dyncdn.me/gfwlist +server=/holdemstripem.com/127.0.0.1#5335 +ipset=/holdemstripem.com/gfwlist +server=/material.io/127.0.0.1#5335 +ipset=/material.io/gfwlist +server=/vagina.nl/127.0.0.1#5335 +ipset=/vagina.nl/gfwlist +server=/camwhoria.com/127.0.0.1#5335 +ipset=/camwhoria.com/gfwlist +server=/eachpay.com/127.0.0.1#5335 +ipset=/eachpay.com/gfwlist +server=/cloudflarestatus.com/127.0.0.1#5335 +ipset=/cloudflarestatus.com/gfwlist +server=/jizzbunker.com/127.0.0.1#5335 +ipset=/jizzbunker.com/gfwlist +server=/superstation.com.tw/127.0.0.1#5335 +ipset=/superstation.com.tw/gfwlist +server=/newmonsterbeatsheadphones.com/127.0.0.1#5335 +ipset=/newmonsterbeatsheadphones.com/gfwlist +server=/acgwr.com/127.0.0.1#5335 +ipset=/acgwr.com/gfwlist +server=/intel.gl/127.0.0.1#5335 +ipset=/intel.gl/gfwlist +server=/canon.ch/127.0.0.1#5335 +ipset=/canon.ch/gfwlist +server=/piapp.com.tw/127.0.0.1#5335 +ipset=/piapp.com.tw/gfwlist +server=/redporn.xxx/127.0.0.1#5335 +ipset=/redporn.xxx/gfwlist +server=/sex-for-work.com/127.0.0.1#5335 +ipset=/sex-for-work.com/gfwlist +server=/mastercardconnect.com/127.0.0.1#5335 +ipset=/mastercardconnect.com/gfwlist +server=/getporn.tv/127.0.0.1#5335 +ipset=/getporn.tv/gfwlist +server=/scholar.google.com.ec/127.0.0.1#5335 +ipset=/scholar.google.com.ec/gfwlist +server=/gotblop.com/127.0.0.1#5335 +ipset=/gotblop.com/gfwlist +server=/freesexyindians.org/127.0.0.1#5335 +ipset=/freesexyindians.org/gfwlist +server=/playboy.com/127.0.0.1#5335 +ipset=/playboy.com/gfwlist +server=/nimg.jp/127.0.0.1#5335 +ipset=/nimg.jp/gfwlist +server=/thieme-connect.com/127.0.0.1#5335 +ipset=/thieme-connect.com/gfwlist +server=/nvidia.com.ua/127.0.0.1#5335 +ipset=/nvidia.com.ua/gfwlist +server=/apple.se/127.0.0.1#5335 +ipset=/apple.se/gfwlist +server=/nikeshoesretro.com/127.0.0.1#5335 +ipset=/nikeshoesretro.com/gfwlist +server=/osiri-suki-club.com/127.0.0.1#5335 +ipset=/osiri-suki-club.com/gfwlist +server=/nikeresponsibility.com/127.0.0.1#5335 +ipset=/nikeresponsibility.com/gfwlist +server=/bmw-motorrad.com.hr/127.0.0.1#5335 +ipset=/bmw-motorrad.com.hr/gfwlist +server=/pearsonassessment.de/127.0.0.1#5335 +ipset=/pearsonassessment.de/gfwlist +server=/mysinchew.com/127.0.0.1#5335 +ipset=/mysinchew.com/gfwlist +server=/kindle4rss.com/127.0.0.1#5335 +ipset=/kindle4rss.com/gfwlist +server=/yourbrain.com/127.0.0.1#5335 +ipset=/yourbrain.com/gfwlist +server=/cloudfunctions.net/127.0.0.1#5335 +ipset=/cloudfunctions.net/gfwlist +server=/veet.com.my/127.0.0.1#5335 +ipset=/veet.com.my/gfwlist +server=/appleimac.com/127.0.0.1#5335 +ipset=/appleimac.com/gfwlist +server=/cgkate.jinvod.com/127.0.0.1#5335 +ipset=/cgkate.jinvod.com/gfwlist +server=/nikeairmaxshoes.com/127.0.0.1#5335 +ipset=/nikeairmaxshoes.com/gfwlist +server=/opentgc.com/127.0.0.1#5335 +ipset=/opentgc.com/gfwlist +server=/slackhq.com/127.0.0.1#5335 +ipset=/slackhq.com/gfwlist +server=/wowstars.com/127.0.0.1#5335 +ipset=/wowstars.com/gfwlist +server=/steamunlocked.net/127.0.0.1#5335 +ipset=/steamunlocked.net/gfwlist +server=/beatsone.net/127.0.0.1#5335 +ipset=/beatsone.net/gfwlist +server=/sexy-older-women.com/127.0.0.1#5335 +ipset=/sexy-older-women.com/gfwlist +server=/joiasmr.com/127.0.0.1#5335 +ipset=/joiasmr.com/gfwlist +server=/dailymail.com/127.0.0.1#5335 +ipset=/dailymail.com/gfwlist +server=/bmw-connecteddrive.ee/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ee/gfwlist +server=/widgets.stripst.com/127.0.0.1#5335 +ipset=/widgets.stripst.com/gfwlist +server=/breakdown.me/127.0.0.1#5335 +ipset=/breakdown.me/gfwlist +server=/stimorolsex.com/127.0.0.1#5335 +ipset=/stimorolsex.com/gfwlist +server=/xxxvirtualworld.com/127.0.0.1#5335 +ipset=/xxxvirtualworld.com/gfwlist +server=/whyfacebook.com/127.0.0.1#5335 +ipset=/whyfacebook.com/gfwlist +server=/facebookphonenumber.net/127.0.0.1#5335 +ipset=/facebookphonenumber.net/gfwlist +server=/canon.lt/127.0.0.1#5335 +ipset=/canon.lt/gfwlist +server=/drebeats-australia.com/127.0.0.1#5335 +ipset=/drebeats-australia.com/gfwlist +server=/hpmini.com/127.0.0.1#5335 +ipset=/hpmini.com/gfwlist +server=/besttube4you.com/127.0.0.1#5335 +ipset=/besttube4you.com/gfwlist +server=/supercoach.com.au/127.0.0.1#5335 +ipset=/supercoach.com.au/gfwlist +server=/mastercard.com.tw/127.0.0.1#5335 +ipset=/mastercard.com.tw/gfwlist +server=/netflixdnstest3.com/127.0.0.1#5335 +ipset=/netflixdnstest3.com/gfwlist +server=/funnyfacebook.org/127.0.0.1#5335 +ipset=/funnyfacebook.org/gfwlist +server=/bitbucket.io/127.0.0.1#5335 +ipset=/bitbucket.io/gfwlist +server=/ebay68.com/127.0.0.1#5335 +ipset=/ebay68.com/gfwlist +server=/blogspot.co.il/127.0.0.1#5335 +ipset=/blogspot.co.il/gfwlist +server=/scorevideos.com/127.0.0.1#5335 +ipset=/scorevideos.com/gfwlist +server=/3dsexy.net/127.0.0.1#5335 +ipset=/3dsexy.net/gfwlist +server=/softbank.jp/127.0.0.1#5335 +ipset=/softbank.jp/gfwlist +server=/adultbay.org/127.0.0.1#5335 +ipset=/adultbay.org/gfwlist +server=/google.ws/127.0.0.1#5335 +ipset=/google.ws/gfwlist +server=/xxbay.com/127.0.0.1#5335 +ipset=/xxbay.com/gfwlist +server=/meetsmartbook.com/127.0.0.1#5335 +ipset=/meetsmartbook.com/gfwlist +server=/vhxqa3.com/127.0.0.1#5335 +ipset=/vhxqa3.com/gfwlist +server=/gateway.dev/127.0.0.1#5335 +ipset=/gateway.dev/gfwlist +server=/foxsports2.com/127.0.0.1#5335 +ipset=/foxsports2.com/gfwlist +server=/recode.net/127.0.0.1#5335 +ipset=/recode.net/gfwlist +server=/dexterhorn.com/127.0.0.1#5335 +ipset=/dexterhorn.com/gfwlist +server=/nfsworld.com/127.0.0.1#5335 +ipset=/nfsworld.com/gfwlist +server=/volvotrucks.ru/127.0.0.1#5335 +ipset=/volvotrucks.ru/gfwlist +server=/ecchinohentai.ru/127.0.0.1#5335 +ipset=/ecchinohentai.ru/gfwlist +server=/lldns.net/127.0.0.1#5335 +ipset=/lldns.net/gfwlist +server=/cosplay-jav.com/127.0.0.1#5335 +ipset=/cosplay-jav.com/gfwlist +server=/sublimedirectory.com/127.0.0.1#5335 +ipset=/sublimedirectory.com/gfwlist +server=/starbucks.com.kz/127.0.0.1#5335 +ipset=/starbucks.com.kz/gfwlist +server=/mastercard.bg/127.0.0.1#5335 +ipset=/mastercard.bg/gfwlist +server=/dubai-escort-list.com/127.0.0.1#5335 +ipset=/dubai-escort-list.com/gfwlist +server=/thenewporn.com/127.0.0.1#5335 +ipset=/thenewporn.com/gfwlist +server=/windowscommunity.net/127.0.0.1#5335 +ipset=/windowscommunity.net/gfwlist +server=/logitechg.com.cn/127.0.0.1#5335 +ipset=/logitechg.com.cn/gfwlist +server=/woflthenewsstation.com/127.0.0.1#5335 +ipset=/woflthenewsstation.com/gfwlist +server=/beatsbysdrdres.com/127.0.0.1#5335 +ipset=/beatsbysdrdres.com/gfwlist +server=/epochtimes.co.kr/127.0.0.1#5335 +ipset=/epochtimes.co.kr/gfwlist +server=/bmw.ly/127.0.0.1#5335 +ipset=/bmw.ly/gfwlist +server=/vintageamateurporn.com/127.0.0.1#5335 +ipset=/vintageamateurporn.com/gfwlist +server=/jsdelivr.com/127.0.0.1#5335 +ipset=/jsdelivr.com/gfwlist +server=/sexvr.com/127.0.0.1#5335 +ipset=/sexvr.com/gfwlist +server=/bmwproductnews.com/127.0.0.1#5335 +ipset=/bmwproductnews.com/gfwlist +server=/spotify.com/127.0.0.1#5335 +ipset=/spotify.com/gfwlist +server=/blogspot.pe/127.0.0.1#5335 +ipset=/blogspot.pe/gfwlist +server=/vod360.net/127.0.0.1#5335 +ipset=/vod360.net/gfwlist +server=/cisco.com/127.0.0.1#5335 +ipset=/cisco.com/gfwlist +server=/myfreecams.com/127.0.0.1#5335 +ipset=/myfreecams.com/gfwlist +server=/linuxfromscratch.org/127.0.0.1#5335 +ipset=/linuxfromscratch.org/gfwlist +server=/bmw-connecteddrive.com.kw/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com.kw/gfwlist +server=/dettol.hu/127.0.0.1#5335 +ipset=/dettol.hu/gfwlist +server=/buypass.no/127.0.0.1#5335 +ipset=/buypass.no/gfwlist +server=/4greedy.com/127.0.0.1#5335 +ipset=/4greedy.com/gfwlist +server=/device-manager.us/127.0.0.1#5335 +ipset=/device-manager.us/gfwlist +server=/abema.tv/127.0.0.1#5335 +ipset=/abema.tv/gfwlist +server=/biggggg.com/127.0.0.1#5335 +ipset=/biggggg.com/gfwlist +server=/poopee-puke.com/127.0.0.1#5335 +ipset=/poopee-puke.com/gfwlist +server=/hackfacebookid.com/127.0.0.1#5335 +ipset=/hackfacebookid.com/gfwlist +server=/sony.com.hn/127.0.0.1#5335 +ipset=/sony.com.hn/gfwlist +server=/amateurwivesvideos.com/127.0.0.1#5335 +ipset=/amateurwivesvideos.com/gfwlist +server=/cios.org/127.0.0.1#5335 +ipset=/cios.org/gfwlist +server=/inlethd.com/127.0.0.1#5335 +ipset=/inlethd.com/gfwlist +server=/ytimg.com/127.0.0.1#5335 +ipset=/ytimg.com/gfwlist +server=/zohopublic.com/127.0.0.1#5335 +ipset=/zohopublic.com/gfwlist +server=/transarmuito.com/127.0.0.1#5335 +ipset=/transarmuito.com/gfwlist +server=/javmost.xyz/127.0.0.1#5335 +ipset=/javmost.xyz/gfwlist +server=/pornimg.xyz/127.0.0.1#5335 +ipset=/pornimg.xyz/gfwlist +server=/bandag.com/127.0.0.1#5335 +ipset=/bandag.com/gfwlist +server=/rbsgr.com/127.0.0.1#5335 +ipset=/rbsgr.com/gfwlist +server=/nailedhard.com/127.0.0.1#5335 +ipset=/nailedhard.com/gfwlist +server=/itcanwait.com/127.0.0.1#5335 +ipset=/itcanwait.com/gfwlist +server=/bmw.com.mx/127.0.0.1#5335 +ipset=/bmw.com.mx/gfwlist +server=/bridgestonewx.com/127.0.0.1#5335 +ipset=/bridgestonewx.com/gfwlist +server=/questvisual.com/127.0.0.1#5335 +ipset=/questvisual.com/gfwlist +server=/avmoo.com/127.0.0.1#5335 +ipset=/avmoo.com/gfwlist +server=/thevirtualsexreview.com/127.0.0.1#5335 +ipset=/thevirtualsexreview.com/gfwlist +server=/paypal-gpplus.com/127.0.0.1#5335 +ipset=/paypal-gpplus.com/gfwlist +server=/bitflyer.jp/127.0.0.1#5335 +ipset=/bitflyer.jp/gfwlist +server=/pinterest.se/127.0.0.1#5335 +ipset=/pinterest.se/gfwlist +server=/technics.com/127.0.0.1#5335 +ipset=/technics.com/gfwlist +server=/azuredns-prd.org/127.0.0.1#5335 +ipset=/azuredns-prd.org/gfwlist +server=/spicybigtits.com/127.0.0.1#5335 +ipset=/spicybigtits.com/gfwlist +server=/wix-code.com/127.0.0.1#5335 +ipset=/wix-code.com/gfwlist +server=/nikedunks.net/127.0.0.1#5335 +ipset=/nikedunks.net/gfwlist +server=/netflixinvestor.com/127.0.0.1#5335 +ipset=/netflixinvestor.com/gfwlist +server=/hentainhaven.com/127.0.0.1#5335 +ipset=/hentainhaven.com/gfwlist +server=/scatolo-guromania.com/127.0.0.1#5335 +ipset=/scatolo-guromania.com/gfwlist +server=/tvb.com.au/127.0.0.1#5335 +ipset=/tvb.com.au/gfwlist +server=/harpercollins.co.in/127.0.0.1#5335 +ipset=/harpercollins.co.in/gfwlist +server=/adwords-community.com/127.0.0.1#5335 +ipset=/adwords-community.com/gfwlist +server=/redtubepremium.com/127.0.0.1#5335 +ipset=/redtubepremium.com/gfwlist +server=/fuckcuck.com/127.0.0.1#5335 +ipset=/fuckcuck.com/gfwlist +server=/scholar.google.com.br/127.0.0.1#5335 +ipset=/scholar.google.com.br/gfwlist +server=/nicovideo.jp/127.0.0.1#5335 +ipset=/nicovideo.jp/gfwlist +server=/facebooki.com/127.0.0.1#5335 +ipset=/facebooki.com/gfwlist +server=/ikea.eg/127.0.0.1#5335 +ipset=/ikea.eg/gfwlist +server=/scoretv.tv/127.0.0.1#5335 +ipset=/scoretv.tv/gfwlist +server=/bmw-connecteddrive.ca/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ca/gfwlist +server=/bmw-motorrad.com.au/127.0.0.1#5335 +ipset=/bmw-motorrad.com.au/gfwlist +server=/kinkyfamily.com/127.0.0.1#5335 +ipset=/kinkyfamily.com/gfwlist +server=/crazylivecams.com/127.0.0.1#5335 +ipset=/crazylivecams.com/gfwlist +server=/streamingdisney.net/127.0.0.1#5335 +ipset=/streamingdisney.net/gfwlist +server=/hentaiprno.com/127.0.0.1#5335 +ipset=/hentaiprno.com/gfwlist +server=/nextdigital.com.tw/127.0.0.1#5335 +ipset=/nextdigital.com.tw/gfwlist +server=/fuckingfreemovies.com/127.0.0.1#5335 +ipset=/fuckingfreemovies.com/gfwlist +server=/uber-assets.com/127.0.0.1#5335 +ipset=/uber-assets.com/gfwlist +server=/adultdeepfakes.com/127.0.0.1#5335 +ipset=/adultdeepfakes.com/gfwlist +server=/mingkyaa.com/127.0.0.1#5335 +ipset=/mingkyaa.com/gfwlist +server=/dropboxmail.com/127.0.0.1#5335 +ipset=/dropboxmail.com/gfwlist +server=/topface.com/127.0.0.1#5335 +ipset=/topface.com/gfwlist +server=/ftchinese.com/127.0.0.1#5335 +ipset=/ftchinese.com/gfwlist +server=/intel.bs/127.0.0.1#5335 +ipset=/intel.bs/gfwlist +server=/cosmosdb.info/127.0.0.1#5335 +ipset=/cosmosdb.info/gfwlist +server=/inteliotmarketplace.com/127.0.0.1#5335 +ipset=/inteliotmarketplace.com/gfwlist +server=/xxxhub123.com/127.0.0.1#5335 +ipset=/xxxhub123.com/gfwlist +server=/eighteen-store18x.jp/127.0.0.1#5335 +ipset=/eighteen-store18x.jp/gfwlist +server=/adsenseformobileapps.com/127.0.0.1#5335 +ipset=/adsenseformobileapps.com/gfwlist +server=/hoge.7jp.info/127.0.0.1#5335 +ipset=/hoge.7jp.info/gfwlist +server=/pa9pal.com/127.0.0.1#5335 +ipset=/pa9pal.com/gfwlist +server=/paypalhere.com/127.0.0.1#5335 +ipset=/paypalhere.com/gfwlist +server=/estudiopenthouse.com/127.0.0.1#5335 +ipset=/estudiopenthouse.com/gfwlist +server=/nudevista.link/127.0.0.1#5335 +ipset=/nudevista.link/gfwlist +server=/sexy-torrents.com/127.0.0.1#5335 +ipset=/sexy-torrents.com/gfwlist +server=/pornkro.com/127.0.0.1#5335 +ipset=/pornkro.com/gfwlist +server=/ninpu.cyou/127.0.0.1#5335 +ipset=/ninpu.cyou/gfwlist +server=/animedao-tv.com/127.0.0.1#5335 +ipset=/animedao-tv.com/gfwlist +server=/asiangfvideos.com/127.0.0.1#5335 +ipset=/asiangfvideos.com/gfwlist +server=/tophdsex.com/127.0.0.1#5335 +ipset=/tophdsex.com/gfwlist +server=/mini.it/127.0.0.1#5335 +ipset=/mini.it/gfwlist +server=/hpcampus.com/127.0.0.1#5335 +ipset=/hpcampus.com/gfwlist +server=/youtube.com.hr/127.0.0.1#5335 +ipset=/youtube.com.hr/gfwlist +server=/bigbigchannel.com.hk/127.0.0.1#5335 +ipset=/bigbigchannel.com.hk/gfwlist +server=/arcgisonline.com/127.0.0.1#5335 +ipset=/arcgisonline.com/gfwlist +server=/doctor-videos.com/127.0.0.1#5335 +ipset=/doctor-videos.com/gfwlist +server=/pornsearchengine.com/127.0.0.1#5335 +ipset=/pornsearchengine.com/gfwlist +server=/steam.ru.qtlglb.com/127.0.0.1#5335 +ipset=/steam.ru.qtlglb.com/gfwlist +server=/onlycartoonsex.com/127.0.0.1#5335 +ipset=/onlycartoonsex.com/gfwlist +server=/ntdvn.com/127.0.0.1#5335 +ipset=/ntdvn.com/gfwlist +server=/raspbian.org/127.0.0.1#5335 +ipset=/raspbian.org/gfwlist +server=/playoverwatch.com/127.0.0.1#5335 +ipset=/playoverwatch.com/gfwlist +server=/tsuradou.noonvob.com/127.0.0.1#5335 +ipset=/tsuradou.noonvob.com/gfwlist +server=/mini-dubai.com/127.0.0.1#5335 +ipset=/mini-dubai.com/gfwlist +server=/durex.com.sg/127.0.0.1#5335 +ipset=/durex.com.sg/gfwlist +server=/garena.tw/127.0.0.1#5335 +ipset=/garena.tw/gfwlist +server=/canon.com.al/127.0.0.1#5335 +ipset=/canon.com.al/gfwlist +server=/ilife.eu/127.0.0.1#5335 +ipset=/ilife.eu/gfwlist +server=/pornxp.com/127.0.0.1#5335 +ipset=/pornxp.com/gfwlist +server=/google.co.mz/127.0.0.1#5335 +ipset=/google.co.mz/gfwlist +server=/pretty-ass.xyz/127.0.0.1#5335 +ipset=/pretty-ass.xyz/gfwlist +server=/bmwbikes.com/127.0.0.1#5335 +ipset=/bmwbikes.com/gfwlist +server=/sling.com/127.0.0.1#5335 +ipset=/sling.com/gfwlist +server=/monstershopcheapbeats.net/127.0.0.1#5335 +ipset=/monstershopcheapbeats.net/gfwlist +server=/shopee.in/127.0.0.1#5335 +ipset=/shopee.in/gfwlist +server=/quicktake.video/127.0.0.1#5335 +ipset=/quicktake.video/gfwlist +server=/gamebeforethegame.com/127.0.0.1#5335 +ipset=/gamebeforethegame.com/gfwlist +server=/apple.sg/127.0.0.1#5335 +ipset=/apple.sg/gfwlist +server=/akamaietpcompromisedmalwaretest.com/127.0.0.1#5335 +ipset=/akamaietpcompromisedmalwaretest.com/gfwlist +server=/cell.com/127.0.0.1#5335 +ipset=/cell.com/gfwlist +server=/dell.com/127.0.0.1#5335 +ipset=/dell.com/gfwlist +server=/garena.co.id/127.0.0.1#5335 +ipset=/garena.co.id/gfwlist +server=/sex4arabxxx.com/127.0.0.1#5335 +ipset=/sex4arabxxx.com/gfwlist +server=/ebsco.com/127.0.0.1#5335 +ipset=/ebsco.com/gfwlist +server=/whatsapp-plus.info/127.0.0.1#5335 +ipset=/whatsapp-plus.info/gfwlist +server=/itools.info/127.0.0.1#5335 +ipset=/itools.info/gfwlist +server=/trannytube.tv/127.0.0.1#5335 +ipset=/trannytube.tv/gfwlist +server=/pornicom.com/127.0.0.1#5335 +ipset=/pornicom.com/gfwlist +server=/slinginternational.com/127.0.0.1#5335 +ipset=/slinginternational.com/gfwlist +server=/pinterest.co/127.0.0.1#5335 +ipset=/pinterest.co/gfwlist +server=/theporndude.cc/127.0.0.1#5335 +ipset=/theporndude.cc/gfwlist +server=/cilk.com/127.0.0.1#5335 +ipset=/cilk.com/gfwlist +server=/cuckoldinterracialporn.com/127.0.0.1#5335 +ipset=/cuckoldinterracialporn.com/gfwlist +server=/clinicalkey.com/127.0.0.1#5335 +ipset=/clinicalkey.com/gfwlist +server=/nurxxx.mobi/127.0.0.1#5335 +ipset=/nurxxx.mobi/gfwlist +server=/volvotrucks.cz/127.0.0.1#5335 +ipset=/volvotrucks.cz/gfwlist +server=/intel.mp/127.0.0.1#5335 +ipset=/intel.mp/gfwlist +server=/starbucks.vn/127.0.0.1#5335 +ipset=/starbucks.vn/gfwlist +server=/freexxx.best/127.0.0.1#5335 +ipset=/freexxx.best/gfwlist +server=/edge.steam-dns.top.comcast.net/127.0.0.1#5335 +ipset=/edge.steam-dns.top.comcast.net/gfwlist +server=/sony.co.kr/127.0.0.1#5335 +ipset=/sony.co.kr/gfwlist +server=/nenitas.club/127.0.0.1#5335 +ipset=/nenitas.club/gfwlist +server=/roshy.tv/127.0.0.1#5335 +ipset=/roshy.tv/gfwlist +server=/vkuserlive.net/127.0.0.1#5335 +ipset=/vkuserlive.net/gfwlist +server=/moviesneek.com/127.0.0.1#5335 +ipset=/moviesneek.com/gfwlist +server=/zoohun.com/127.0.0.1#5335 +ipset=/zoohun.com/gfwlist +server=/lsawards.com/127.0.0.1#5335 +ipset=/lsawards.com/gfwlist +server=/z5.app/127.0.0.1#5335 +ipset=/z5.app/gfwlist +server=/bejeweledstars.com/127.0.0.1#5335 +ipset=/bejeweledstars.com/gfwlist +server=/momomall.com.tw/127.0.0.1#5335 +ipset=/momomall.com.tw/gfwlist +server=/grannygetsafacial.com/127.0.0.1#5335 +ipset=/grannygetsafacial.com/gfwlist +server=/binancezh.cc/127.0.0.1#5335 +ipset=/binancezh.cc/gfwlist +server=/newlineporn.com/127.0.0.1#5335 +ipset=/newlineporn.com/gfwlist +server=/plos.org/127.0.0.1#5335 +ipset=/plos.org/gfwlist +server=/3lib.net/127.0.0.1#5335 +ipset=/3lib.net/gfwlist +server=/scholar.google.com.uy/127.0.0.1#5335 +ipset=/scholar.google.com.uy/gfwlist +server=/hackday.com.au/127.0.0.1#5335 +ipset=/hackday.com.au/gfwlist +server=/miniso.ie/127.0.0.1#5335 +ipset=/miniso.ie/gfwlist +server=/volvopenta.fr/127.0.0.1#5335 +ipset=/volvopenta.fr/gfwlist +server=/hanime.xxx/127.0.0.1#5335 +ipset=/hanime.xxx/gfwlist +server=/aoaou.iillii.net/127.0.0.1#5335 +ipset=/aoaou.iillii.net/gfwlist +server=/picasaweb.org/127.0.0.1#5335 +ipset=/picasaweb.org/gfwlist +server=/nikeaustralia.com/127.0.0.1#5335 +ipset=/nikeaustralia.com/gfwlist +server=/firestonecomercial.com.co/127.0.0.1#5335 +ipset=/firestonecomercial.com.co/gfwlist +server=/bookstagram.com/127.0.0.1#5335 +ipset=/bookstagram.com/gfwlist +server=/vanish.com.hr/127.0.0.1#5335 +ipset=/vanish.com.hr/gfwlist +server=/intel.rw/127.0.0.1#5335 +ipset=/intel.rw/gfwlist +server=/marketwatch.com/127.0.0.1#5335 +ipset=/marketwatch.com/gfwlist +server=/bmwmass.net/127.0.0.1#5335 +ipset=/bmwmass.net/gfwlist +server=/hotcandyland.com/127.0.0.1#5335 +ipset=/hotcandyland.com/gfwlist +server=/oculus-china.com/127.0.0.1#5335 +ipset=/oculus-china.com/gfwlist +server=/twitpic.com/127.0.0.1#5335 +ipset=/twitpic.com/gfwlist +server=/ebaybenefits.com/127.0.0.1#5335 +ipset=/ebaybenefits.com/gfwlist +server=/google.vu/127.0.0.1#5335 +ipset=/google.vu/gfwlist +server=/casimages.com/127.0.0.1#5335 +ipset=/casimages.com/gfwlist +server=/xcams.com/127.0.0.1#5335 +ipset=/xcams.com/gfwlist +server=/webhosting.com/127.0.0.1#5335 +ipset=/webhosting.com/gfwlist +server=/pubmatic.com/127.0.0.1#5335 +ipset=/pubmatic.com/gfwlist +server=/xvideo.run/127.0.0.1#5335 +ipset=/xvideo.run/gfwlist +server=/myavok.com/127.0.0.1#5335 +ipset=/myavok.com/gfwlist +server=/erothots.co/127.0.0.1#5335 +ipset=/erothots.co/gfwlist +server=/cartoonpornonly.com/127.0.0.1#5335 +ipset=/cartoonpornonly.com/gfwlist +server=/beatsfranceofficiel.com/127.0.0.1#5335 +ipset=/beatsfranceofficiel.com/gfwlist +server=/azuremarketplace.microsoft.com/127.0.0.1#5335 +ipset=/azuremarketplace.microsoft.com/gfwlist +server=/sissy.eu.org/127.0.0.1#5335 +ipset=/sissy.eu.org/gfwlist +server=/scholar.google.co.za/127.0.0.1#5335 +ipset=/scholar.google.co.za/gfwlist +server=/gaystream.pw/127.0.0.1#5335 +ipset=/gaystream.pw/gfwlist +server=/indienudes.com/127.0.0.1#5335 +ipset=/indienudes.com/gfwlist +server=/x99av.com/127.0.0.1#5335 +ipset=/x99av.com/gfwlist +server=/uuk28.com/127.0.0.1#5335 +ipset=/uuk28.com/gfwlist +server=/nflxvideo.net/127.0.0.1#5335 +ipset=/nflxvideo.net/gfwlist +server=/myhulu.com/127.0.0.1#5335 +ipset=/myhulu.com/gfwlist +server=/bmwchampionship.com/127.0.0.1#5335 +ipset=/bmwchampionship.com/gfwlist +server=/nuuporn.com/127.0.0.1#5335 +ipset=/nuuporn.com/gfwlist +server=/pornspark.com/127.0.0.1#5335 +ipset=/pornspark.com/gfwlist +server=/wsj.com/127.0.0.1#5335 +ipset=/wsj.com/gfwlist +server=/facebookflow.com/127.0.0.1#5335 +ipset=/facebookflow.com/gfwlist +server=/volvotrucks.my/127.0.0.1#5335 +ipset=/volvotrucks.my/gfwlist +server=/facebook.se/127.0.0.1#5335 +ipset=/facebook.se/gfwlist +server=/enfa.com.vn/127.0.0.1#5335 +ipset=/enfa.com.vn/gfwlist +server=/vmworld2013.com/127.0.0.1#5335 +ipset=/vmworld2013.com/gfwlist +server=/aventertainments.com/127.0.0.1#5335 +ipset=/aventertainments.com/gfwlist +server=/12diasderegalosdeitunes.co/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.co/gfwlist +server=/fleshlyx.com/127.0.0.1#5335 +ipset=/fleshlyx.com/gfwlist +server=/sora6.com/127.0.0.1#5335 +ipset=/sora6.com/gfwlist +server=/bmw-ottawa.ca/127.0.0.1#5335 +ipset=/bmw-ottawa.ca/gfwlist +server=/draftjs.org/127.0.0.1#5335 +ipset=/draftjs.org/gfwlist +server=/youtube.com.jm/127.0.0.1#5335 +ipset=/youtube.com.jm/gfwlist +server=/hbogo.eu/127.0.0.1#5335 +ipset=/hbogo.eu/gfwlist +server=/gogo-load.com/127.0.0.1#5335 +ipset=/gogo-load.com/gfwlist +server=/mcdindonesia.com/127.0.0.1#5335 +ipset=/mcdindonesia.com/gfwlist +server=/icegaytube.tv/127.0.0.1#5335 +ipset=/icegaytube.tv/gfwlist +server=/mailonsunday.co.uk/127.0.0.1#5335 +ipset=/mailonsunday.co.uk/gfwlist +server=/amerikiskhma.com/127.0.0.1#5335 +ipset=/amerikiskhma.com/gfwlist +server=/icloudos.net/127.0.0.1#5335 +ipset=/icloudos.net/gfwlist +server=/nikey.com/127.0.0.1#5335 +ipset=/nikey.com/gfwlist +server=/sciencemag.org/127.0.0.1#5335 +ipset=/sciencemag.org/gfwlist +server=/brandeasygo.com/127.0.0.1#5335 +ipset=/brandeasygo.com/gfwlist +server=/nintendo.com.pt/127.0.0.1#5335 +ipset=/nintendo.com.pt/gfwlist +server=/faketaxi.com/127.0.0.1#5335 +ipset=/faketaxi.com/gfwlist +server=/home-made-porn-movies.com/127.0.0.1#5335 +ipset=/home-made-porn-movies.com/gfwlist +server=/firestone.com.co/127.0.0.1#5335 +ipset=/firestone.com.co/gfwlist +server=/tesla.services/127.0.0.1#5335 +ipset=/tesla.services/gfwlist +server=/epochshop.com/127.0.0.1#5335 +ipset=/epochshop.com/gfwlist +server=/easypic.com/127.0.0.1#5335 +ipset=/easypic.com/gfwlist +server=/ebaystyle.com/127.0.0.1#5335 +ipset=/ebaystyle.com/gfwlist +server=/mansionglobal.com/127.0.0.1#5335 +ipset=/mansionglobal.com/gfwlist +server=/pridetube.com/127.0.0.1#5335 +ipset=/pridetube.com/gfwlist +server=/livemodels.co/127.0.0.1#5335 +ipset=/livemodels.co/gfwlist +server=/veet.com.ar/127.0.0.1#5335 +ipset=/veet.com.ar/gfwlist +server=/hentai.io/127.0.0.1#5335 +ipset=/hentai.io/gfwlist +server=/ceskeporno.cz/127.0.0.1#5335 +ipset=/ceskeporno.cz/gfwlist +server=/youtube.be/127.0.0.1#5335 +ipset=/youtube.be/gfwlist +server=/prostate-exam-info.com/127.0.0.1#5335 +ipset=/prostate-exam-info.com/gfwlist +server=/vfsco.fr/127.0.0.1#5335 +ipset=/vfsco.fr/gfwlist +server=/gemini.yahoo.com/127.0.0.1#5335 +ipset=/gemini.yahoo.com/gfwlist +server=/aadmv.com/127.0.0.1#5335 +ipset=/aadmv.com/gfwlist +server=/youtube.hr/127.0.0.1#5335 +ipset=/youtube.hr/gfwlist +server=/pornlist18.com/127.0.0.1#5335 +ipset=/pornlist18.com/gfwlist +server=/beatsbydreaustralia-sale.com/127.0.0.1#5335 +ipset=/beatsbydreaustralia-sale.com/gfwlist +server=/macruby.com/127.0.0.1#5335 +ipset=/macruby.com/gfwlist +server=/xgirls.webcam/127.0.0.1#5335 +ipset=/xgirls.webcam/gfwlist +server=/dogfartnetwork.com/127.0.0.1#5335 +ipset=/dogfartnetwork.com/gfwlist +server=/kutjeporno.com/127.0.0.1#5335 +ipset=/kutjeporno.com/gfwlist +server=/sexmummy.com/127.0.0.1#5335 +ipset=/sexmummy.com/gfwlist +server=/secure-paypal.info/127.0.0.1#5335 +ipset=/secure-paypal.info/gfwlist +server=/fast.com/127.0.0.1#5335 +ipset=/fast.com/gfwlist +server=/hkgpao.com/127.0.0.1#5335 +ipset=/hkgpao.com/gfwlist +server=/instanttelegram.com/127.0.0.1#5335 +ipset=/instanttelegram.com/gfwlist +server=/xvideos.co/127.0.0.1#5335 +ipset=/xvideos.co/gfwlist +server=/yiqilai99.cn/127.0.0.1#5335 +ipset=/yiqilai99.cn/gfwlist +server=/igcdn.com/127.0.0.1#5335 +ipset=/igcdn.com/gfwlist +server=/vanitaonline.com/127.0.0.1#5335 +ipset=/vanitaonline.com/gfwlist +server=/avday.tv/127.0.0.1#5335 +ipset=/avday.tv/gfwlist +server=/justmysocks4.net/127.0.0.1#5335 +ipset=/justmysocks4.net/gfwlist +server=/xboxone.com/127.0.0.1#5335 +ipset=/xboxone.com/gfwlist +server=/yt.be/127.0.0.1#5335 +ipset=/yt.be/gfwlist +server=/stepmom.one/127.0.0.1#5335 +ipset=/stepmom.one/gfwlist +server=/vanish.pl/127.0.0.1#5335 +ipset=/vanish.pl/gfwlist +server=/scholar.google.com.do/127.0.0.1#5335 +ipset=/scholar.google.com.do/gfwlist +server=/darwinsourcecode.com/127.0.0.1#5335 +ipset=/darwinsourcecode.com/gfwlist +server=/blogspot.ca/127.0.0.1#5335 +ipset=/blogspot.ca/gfwlist +server=/sponichi.co.jp/127.0.0.1#5335 +ipset=/sponichi.co.jp/gfwlist +server=/musclegirlflix.com/127.0.0.1#5335 +ipset=/musclegirlflix.com/gfwlist +server=/seagroup.com/127.0.0.1#5335 +ipset=/seagroup.com/gfwlist +server=/nikekid.com/127.0.0.1#5335 +ipset=/nikekid.com/gfwlist +server=/bmwsports.com/127.0.0.1#5335 +ipset=/bmwsports.com/gfwlist +server=/czechlesbians.com/127.0.0.1#5335 +ipset=/czechlesbians.com/gfwlist +server=/amazon.com.mx/127.0.0.1#5335 +ipset=/amazon.com.mx/gfwlist +server=/catcert.cat/127.0.0.1#5335 +ipset=/catcert.cat/gfwlist +server=/nextjs.org/127.0.0.1#5335 +ipset=/nextjs.org/gfwlist +server=/jerkofftocelebs.com/127.0.0.1#5335 +ipset=/jerkofftocelebs.com/gfwlist +server=/topartporn.com/127.0.0.1#5335 +ipset=/topartporn.com/gfwlist +server=/rbe996.com/127.0.0.1#5335 +ipset=/rbe996.com/gfwlist +server=/e-szigno.hu/127.0.0.1#5335 +ipset=/e-szigno.hu/gfwlist +server=/lustylist.com/127.0.0.1#5335 +ipset=/lustylist.com/gfwlist +server=/cuckoldwifesex.com/127.0.0.1#5335 +ipset=/cuckoldwifesex.com/gfwlist +server=/beatbydreuk2014.com/127.0.0.1#5335 +ipset=/beatbydreuk2014.com/gfwlist +server=/visa.com.ar/127.0.0.1#5335 +ipset=/visa.com.ar/gfwlist +server=/twavking.com/127.0.0.1#5335 +ipset=/twavking.com/gfwlist +server=/bmj.com/127.0.0.1#5335 +ipset=/bmj.com/gfwlist +server=/alfera.com.hk/127.0.0.1#5335 +ipset=/alfera.com.hk/gfwlist +server=/tube-sex-videos.com/127.0.0.1#5335 +ipset=/tube-sex-videos.com/gfwlist +server=/helixstudios.net/127.0.0.1#5335 +ipset=/helixstudios.net/gfwlist +server=/heroero.com/127.0.0.1#5335 +ipset=/heroero.com/gfwlist +server=/oxfordclinicalpsych.com/127.0.0.1#5335 +ipset=/oxfordclinicalpsych.com/gfwlist +server=/meilleurpornos.com/127.0.0.1#5335 +ipset=/meilleurpornos.com/gfwlist +server=/ikea.com.tw/127.0.0.1#5335 +ipset=/ikea.com.tw/gfwlist +server=/pearson.co.in/127.0.0.1#5335 +ipset=/pearson.co.in/gfwlist +server=/sucksex.com/127.0.0.1#5335 +ipset=/sucksex.com/gfwlist +server=/pppds.com/127.0.0.1#5335 +ipset=/pppds.com/gfwlist +server=/bcicdn.com/127.0.0.1#5335 +ipset=/bcicdn.com/gfwlist +server=/brandelectronic.com/127.0.0.1#5335 +ipset=/brandelectronic.com/gfwlist +server=/pearsonvue.net/127.0.0.1#5335 +ipset=/pearsonvue.net/gfwlist +server=/nurumassage.net/127.0.0.1#5335 +ipset=/nurumassage.net/gfwlist +server=/mingshengbao.com/127.0.0.1#5335 +ipset=/mingshengbao.com/gfwlist +server=/transcamslive.com/127.0.0.1#5335 +ipset=/transcamslive.com/gfwlist +server=/2013beatsbydrdreshop.com/127.0.0.1#5335 +ipset=/2013beatsbydrdreshop.com/gfwlist +server=/onedrive.co/127.0.0.1#5335 +ipset=/onedrive.co/gfwlist +server=/tubepornlist.com/127.0.0.1#5335 +ipset=/tubepornlist.com/gfwlist +server=/instamgram.com/127.0.0.1#5335 +ipset=/instamgram.com/gfwlist +server=/spankingtube.com/127.0.0.1#5335 +ipset=/spankingtube.com/gfwlist +server=/myamateurgirls.net/127.0.0.1#5335 +ipset=/myamateurgirls.net/gfwlist +server=/google.sk/127.0.0.1#5335 +ipset=/google.sk/gfwlist +server=/cartoonporno.xxx/127.0.0.1#5335 +ipset=/cartoonporno.xxx/gfwlist +server=/hentaiz.cc/127.0.0.1#5335 +ipset=/hentaiz.cc/gfwlist +server=/fbcdn-a.akamaihd.net/127.0.0.1#5335 +ipset=/fbcdn-a.akamaihd.net/gfwlist +server=/simply-hentai.com/127.0.0.1#5335 +ipset=/simply-hentai.com/gfwlist +server=/krymr.com/127.0.0.1#5335 +ipset=/krymr.com/gfwlist +server=/youtube.gr/127.0.0.1#5335 +ipset=/youtube.gr/gfwlist +server=/attbelieves.com/127.0.0.1#5335 +ipset=/attbelieves.com/gfwlist +server=/sony-semicon.co.jp/127.0.0.1#5335 +ipset=/sony-semicon.co.jp/gfwlist +server=/pobl-content.com/127.0.0.1#5335 +ipset=/pobl-content.com/gfwlist +server=/volvotrucks.kr/127.0.0.1#5335 +ipset=/volvotrucks.kr/gfwlist +server=/mini-windsor.com/127.0.0.1#5335 +ipset=/mini-windsor.com/gfwlist +server=/hoes.com/127.0.0.1#5335 +ipset=/hoes.com/gfwlist +server=/facebookmail.com/127.0.0.1#5335 +ipset=/facebookmail.com/gfwlist +server=/netflixdnstest8.com/127.0.0.1#5335 +ipset=/netflixdnstest8.com/gfwlist +server=/niceporn.tv/127.0.0.1#5335 +ipset=/niceporn.tv/gfwlist +server=/ubnw.net/127.0.0.1#5335 +ipset=/ubnw.net/gfwlist +server=/vfsco.cl/127.0.0.1#5335 +ipset=/vfsco.cl/gfwlist +server=/sekswebsite.nl/127.0.0.1#5335 +ipset=/sekswebsite.nl/gfwlist +server=/cloudproxy.app/127.0.0.1#5335 +ipset=/cloudproxy.app/gfwlist +server=/daftsex-hd.com/127.0.0.1#5335 +ipset=/daftsex-hd.com/gfwlist +server=/mjv-art.org/127.0.0.1#5335 +ipset=/mjv-art.org/gfwlist +server=/marketing-cloud.com/127.0.0.1#5335 +ipset=/marketing-cloud.com/gfwlist +server=/yahoo.ro/127.0.0.1#5335 +ipset=/yahoo.ro/gfwlist +server=/netsolssl.com/127.0.0.1#5335 +ipset=/netsolssl.com/gfwlist +server=/motherporn.ovh/127.0.0.1#5335 +ipset=/motherporn.ovh/gfwlist +server=/malayalamanorama.com/127.0.0.1#5335 +ipset=/malayalamanorama.com/gfwlist +server=/apple.co.jp/127.0.0.1#5335 +ipset=/apple.co.jp/gfwlist +server=/ebayinc.com/127.0.0.1#5335 +ipset=/ebayinc.com/gfwlist +server=/licdn.com/127.0.0.1#5335 +ipset=/licdn.com/gfwlist +server=/yourwifemymeat.com/127.0.0.1#5335 +ipset=/yourwifemymeat.com/gfwlist +server=/vanish.co.id/127.0.0.1#5335 +ipset=/vanish.co.id/gfwlist +server=/alldrawingshere.com/127.0.0.1#5335 +ipset=/alldrawingshere.com/gfwlist +server=/ckcdn.com/127.0.0.1#5335 +ipset=/ckcdn.com/gfwlist +server=/ppe.lawyer/127.0.0.1#5335 +ipset=/ppe.lawyer/gfwlist +server=/gradeuptube.com/127.0.0.1#5335 +ipset=/gradeuptube.com/gfwlist +server=/xvideosnovinhas.com/127.0.0.1#5335 +ipset=/xvideosnovinhas.com/gfwlist +server=/cryptocompare.com/127.0.0.1#5335 +ipset=/cryptocompare.com/gfwlist +server=/18-teen-xxx.com/127.0.0.1#5335 +ipset=/18-teen-xxx.com/gfwlist +server=/avstar.me/127.0.0.1#5335 +ipset=/avstar.me/gfwlist +server=/zhengjian.org/127.0.0.1#5335 +ipset=/zhengjian.org/gfwlist +server=/fuck6teen.com/127.0.0.1#5335 +ipset=/fuck6teen.com/gfwlist +server=/40somethingmag.com/127.0.0.1#5335 +ipset=/40somethingmag.com/gfwlist +server=/yahoo.com.ag/127.0.0.1#5335 +ipset=/yahoo.com.ag/gfwlist +server=/brazzfan.com/127.0.0.1#5335 +ipset=/brazzfan.com/gfwlist +server=/epoch.org.il/127.0.0.1#5335 +ipset=/epoch.org.il/gfwlist +server=/faceboob.com/127.0.0.1#5335 +ipset=/faceboob.com/gfwlist +server=/myatos.net/127.0.0.1#5335 +ipset=/myatos.net/gfwlist +server=/getpocket.com/127.0.0.1#5335 +ipset=/getpocket.com/gfwlist +server=/landofhope.tv/127.0.0.1#5335 +ipset=/landofhope.tv/gfwlist +server=/pornktube.com/127.0.0.1#5335 +ipset=/pornktube.com/gfwlist +server=/mininanaimo.com/127.0.0.1#5335 +ipset=/mininanaimo.com/gfwlist +server=/freecartoons.biz/127.0.0.1#5335 +ipset=/freecartoons.biz/gfwlist +server=/rarbgto.org/127.0.0.1#5335 +ipset=/rarbgto.org/gfwlist +server=/pinksporn.com/127.0.0.1#5335 +ipset=/pinksporn.com/gfwlist +server=/sexjk.com/127.0.0.1#5335 +ipset=/sexjk.com/gfwlist +server=/xnxx-sex-tube.com/127.0.0.1#5335 +ipset=/xnxx-sex-tube.com/gfwlist +server=/volvobuses.co.nz/127.0.0.1#5335 +ipset=/volvobuses.co.nz/gfwlist +server=/aboutyourmini.com/127.0.0.1#5335 +ipset=/aboutyourmini.com/gfwlist +server=/wetnhorny.com/127.0.0.1#5335 +ipset=/wetnhorny.com/gfwlist +server=/vrporncat.com/127.0.0.1#5335 +ipset=/vrporncat.com/gfwlist +server=/ubisoft-uplay-savegames.s3.amazonaws.com/127.0.0.1#5335 +ipset=/ubisoft-uplay-savegames.s3.amazonaws.com/gfwlist +server=/xsvod.xyz/127.0.0.1#5335 +ipset=/xsvod.xyz/gfwlist +server=/disco-api.com/127.0.0.1#5335 +ipset=/disco-api.com/gfwlist +server=/nikestore.com.au/127.0.0.1#5335 +ipset=/nikestore.com.au/gfwlist +server=/pageview.mobi/127.0.0.1#5335 +ipset=/pageview.mobi/gfwlist +server=/ptt3.cc/127.0.0.1#5335 +ipset=/ptt3.cc/gfwlist +server=/feook.com/127.0.0.1#5335 +ipset=/feook.com/gfwlist +server=/google.td/127.0.0.1#5335 +ipset=/google.td/gfwlist +server=/voa.gov/127.0.0.1#5335 +ipset=/voa.gov/gfwlist +server=/vmwidm-ads.com/127.0.0.1#5335 +ipset=/vmwidm-ads.com/gfwlist +server=/sexgamesbox.com/127.0.0.1#5335 +ipset=/sexgamesbox.com/gfwlist +server=/masseffectarchives.com/127.0.0.1#5335 +ipset=/masseffectarchives.com/gfwlist +server=/fmcebook.com/127.0.0.1#5335 +ipset=/fmcebook.com/gfwlist +server=/xn--czrs0t4phtr3a.cn/127.0.0.1#5335 +ipset=/xn--czrs0t4phtr3a.cn/gfwlist +server=/fbworkmail.com/127.0.0.1#5335 +ipset=/fbworkmail.com/gfwlist +server=/sb.sb/127.0.0.1#5335 +ipset=/sb.sb/gfwlist +server=/cheapbeatsbydreoutlet-nz.com/127.0.0.1#5335 +ipset=/cheapbeatsbydreoutlet-nz.com/gfwlist +server=/azurecomcdn.net/127.0.0.1#5335 +ipset=/azurecomcdn.net/gfwlist +server=/ebaynyc.com/127.0.0.1#5335 +ipset=/ebaynyc.com/gfwlist +server=/japanesebeauties.net/127.0.0.1#5335 +ipset=/japanesebeauties.net/gfwlist +server=/staxus.com/127.0.0.1#5335 +ipset=/staxus.com/gfwlist +server=/volvotrucks.hk/127.0.0.1#5335 +ipset=/volvotrucks.hk/gfwlist +server=/discord.design/127.0.0.1#5335 +ipset=/discord.design/gfwlist +server=/pinterest.de/127.0.0.1#5335 +ipset=/pinterest.de/gfwlist +server=/stacyvandenbergboobs.com/127.0.0.1#5335 +ipset=/stacyvandenbergboobs.com/gfwlist +server=/ikea.in/127.0.0.1#5335 +ipset=/ikea.in/gfwlist +server=/ip.sb/127.0.0.1#5335 +ipset=/ip.sb/gfwlist +server=/codeberg.org/127.0.0.1#5335 +ipset=/codeberg.org/gfwlist +server=/westlaw.com/127.0.0.1#5335 +ipset=/westlaw.com/gfwlist +server=/phun.org/127.0.0.1#5335 +ipset=/phun.org/gfwlist +server=/atdmt2.com/127.0.0.1#5335 +ipset=/atdmt2.com/gfwlist +server=/visaeurope.si/127.0.0.1#5335 +ipset=/visaeurope.si/gfwlist +server=/girlsway.com/127.0.0.1#5335 +ipset=/girlsway.com/gfwlist +server=/epochtimes.it/127.0.0.1#5335 +ipset=/epochtimes.it/gfwlist +server=/pacifickitchenandhome.com/127.0.0.1#5335 +ipset=/pacifickitchenandhome.com/gfwlist +server=/mplstudios.com/127.0.0.1#5335 +ipset=/mplstudios.com/gfwlist +server=/mgo-images.com/127.0.0.1#5335 +ipset=/mgo-images.com/gfwlist +server=/lettherebeporn.com/127.0.0.1#5335 +ipset=/lettherebeporn.com/gfwlist +server=/theshoppingexpresslane.net/127.0.0.1#5335 +ipset=/theshoppingexpresslane.net/gfwlist +server=/jitsi.org/127.0.0.1#5335 +ipset=/jitsi.org/gfwlist +server=/miniwholesaleconnect.com/127.0.0.1#5335 +ipset=/miniwholesaleconnect.com/gfwlist +server=/paypal-referral.com/127.0.0.1#5335 +ipset=/paypal-referral.com/gfwlist +server=/badjojo.com/127.0.0.1#5335 +ipset=/badjojo.com/gfwlist +server=/binancezh.be/127.0.0.1#5335 +ipset=/binancezh.be/gfwlist +server=/moviesfree4u.xyz/127.0.0.1#5335 +ipset=/moviesfree4u.xyz/gfwlist +server=/bbycastatic.ca/127.0.0.1#5335 +ipset=/bbycastatic.ca/gfwlist +server=/app-dynamics.com/127.0.0.1#5335 +ipset=/app-dynamics.com/gfwlist +server=/freepornhentaigames.com/127.0.0.1#5335 +ipset=/freepornhentaigames.com/gfwlist +server=/bmwgroup-classic-heart.com/127.0.0.1#5335 +ipset=/bmwgroup-classic-heart.com/gfwlist +server=/github.com/127.0.0.1#5335 +ipset=/github.com/gfwlist +server=/appledarwin.com/127.0.0.1#5335 +ipset=/appledarwin.com/gfwlist +server=/beatsheadphonesusamall.com/127.0.0.1#5335 +ipset=/beatsheadphonesusamall.com/gfwlist +server=/ind.sh/127.0.0.1#5335 +ipset=/ind.sh/gfwlist +server=/cuckoldporntube.com/127.0.0.1#5335 +ipset=/cuckoldporntube.com/gfwlist +server=/agzy1.com/127.0.0.1#5335 +ipset=/agzy1.com/gfwlist +server=/thenextweb.com/127.0.0.1#5335 +ipset=/thenextweb.com/gfwlist +server=/bridgestonetyre.com.my/127.0.0.1#5335 +ipset=/bridgestonetyre.com.my/gfwlist +server=/milfslesbian.com/127.0.0.1#5335 +ipset=/milfslesbian.com/gfwlist +server=/pornoboard.net/127.0.0.1#5335 +ipset=/pornoboard.net/gfwlist +server=/ibradome.com/127.0.0.1#5335 +ipset=/ibradome.com/gfwlist +server=/fuckthathussy.com/127.0.0.1#5335 +ipset=/fuckthathussy.com/gfwlist +server=/sexmerci.com/127.0.0.1#5335 +ipset=/sexmerci.com/gfwlist +server=/opentranslatorstothings.org/127.0.0.1#5335 +ipset=/opentranslatorstothings.org/gfwlist +server=/collective99.com/127.0.0.1#5335 +ipset=/collective99.com/gfwlist +server=/thenationalpulse.com/127.0.0.1#5335 +ipset=/thenationalpulse.com/gfwlist +server=/bmia.org/127.0.0.1#5335 +ipset=/bmia.org/gfwlist +server=/huffingtonpost.co.uk/127.0.0.1#5335 +ipset=/huffingtonpost.co.uk/gfwlist +server=/adultsexgame.biz/127.0.0.1#5335 +ipset=/adultsexgame.biz/gfwlist +server=/minilaval.com/127.0.0.1#5335 +ipset=/minilaval.com/gfwlist +server=/visa.com.kh/127.0.0.1#5335 +ipset=/visa.com.kh/gfwlist +server=/horse-cum.net/127.0.0.1#5335 +ipset=/horse-cum.net/gfwlist +server=/visa.nl/127.0.0.1#5335 +ipset=/visa.nl/gfwlist +server=/fox38corpuschristi.com/127.0.0.1#5335 +ipset=/fox38corpuschristi.com/gfwlist +server=/bwh8.net/127.0.0.1#5335 +ipset=/bwh8.net/gfwlist +server=/practicalmoneyskills.ca/127.0.0.1#5335 +ipset=/practicalmoneyskills.ca/gfwlist +server=/kktv.com.tw/127.0.0.1#5335 +ipset=/kktv.com.tw/gfwlist +server=/hentaifc.com/127.0.0.1#5335 +ipset=/hentaifc.com/gfwlist +server=/crececonebay.com/127.0.0.1#5335 +ipset=/crececonebay.com/gfwlist +server=/zteman.net/127.0.0.1#5335 +ipset=/zteman.net/gfwlist +server=/javplatform.com/127.0.0.1#5335 +ipset=/javplatform.com/gfwlist +server=/instafollower.com/127.0.0.1#5335 +ipset=/instafollower.com/gfwlist +server=/beastiegals.com/127.0.0.1#5335 +ipset=/beastiegals.com/gfwlist +server=/intel.cz/127.0.0.1#5335 +ipset=/intel.cz/gfwlist +server=/applemalaysia.com.my/127.0.0.1#5335 +ipset=/applemalaysia.com.my/gfwlist +server=/disneymusicpromotion.com/127.0.0.1#5335 +ipset=/disneymusicpromotion.com/gfwlist +server=/applestore.ph/127.0.0.1#5335 +ipset=/applestore.ph/gfwlist +server=/pages.dev/127.0.0.1#5335 +ipset=/pages.dev/gfwlist +server=/paypal-apac.com/127.0.0.1#5335 +ipset=/paypal-apac.com/gfwlist +server=/paypal-center.com/127.0.0.1#5335 +ipset=/paypal-center.com/gfwlist +server=/iamremarkable.org/127.0.0.1#5335 +ipset=/iamremarkable.org/gfwlist +server=/pornshare.biz/127.0.0.1#5335 +ipset=/pornshare.biz/gfwlist +server=/adobecontent.io/127.0.0.1#5335 +ipset=/adobecontent.io/gfwlist +server=/airwick.ch/127.0.0.1#5335 +ipset=/airwick.ch/gfwlist +server=/ubuntu.net/127.0.0.1#5335 +ipset=/ubuntu.net/gfwlist +server=/etheadphones.com/127.0.0.1#5335 +ipset=/etheadphones.com/gfwlist +server=/fbfeedback.com/127.0.0.1#5335 +ipset=/fbfeedback.com/gfwlist +server=/langsuirs.com/127.0.0.1#5335 +ipset=/langsuirs.com/gfwlist +server=/microsoft.tv/127.0.0.1#5335 +ipset=/microsoft.tv/gfwlist +server=/faseboox.com/127.0.0.1#5335 +ipset=/faseboox.com/gfwlist +server=/img4.uk/127.0.0.1#5335 +ipset=/img4.uk/gfwlist +server=/pictoa.com/127.0.0.1#5335 +ipset=/pictoa.com/gfwlist +server=/jav24.com/127.0.0.1#5335 +ipset=/jav24.com/gfwlist +server=/beastysexlinks.com/127.0.0.1#5335 +ipset=/beastysexlinks.com/gfwlist +server=/calgon.ru/127.0.0.1#5335 +ipset=/calgon.ru/gfwlist +server=/scitation.org/127.0.0.1#5335 +ipset=/scitation.org/gfwlist +server=/sexykittenporn.com/127.0.0.1#5335 +ipset=/sexykittenporn.com/gfwlist +server=/hentai.name/127.0.0.1#5335 +ipset=/hentai.name/gfwlist +server=/latinaabuse.com/127.0.0.1#5335 +ipset=/latinaabuse.com/gfwlist +server=/onlysiterip.com/127.0.0.1#5335 +ipset=/onlysiterip.com/gfwlist +server=/volvobuses.us/127.0.0.1#5335 +ipset=/volvobuses.us/gfwlist +server=/herokucharge.com/127.0.0.1#5335 +ipset=/herokucharge.com/gfwlist +server=/nikereuseashoe.com/127.0.0.1#5335 +ipset=/nikereuseashoe.com/gfwlist +server=/bmw-motorrad.gr/127.0.0.1#5335 +ipset=/bmw-motorrad.gr/gfwlist +server=/bmw-konzernarchiv.de/127.0.0.1#5335 +ipset=/bmw-konzernarchiv.de/gfwlist +server=/ashemaletv.com/127.0.0.1#5335 +ipset=/ashemaletv.com/gfwlist +server=/4porn.com/127.0.0.1#5335 +ipset=/4porn.com/gfwlist +server=/mingpaovan.com/127.0.0.1#5335 +ipset=/mingpaovan.com/gfwlist +server=/itunesradio.tw/127.0.0.1#5335 +ipset=/itunesradio.tw/gfwlist +server=/cixp.net/127.0.0.1#5335 +ipset=/cixp.net/gfwlist +server=/htyj-bj.com/127.0.0.1#5335 +ipset=/htyj-bj.com/gfwlist +server=/wikidot.com/127.0.0.1#5335 +ipset=/wikidot.com/gfwlist +server=/sshs.club/127.0.0.1#5335 +ipset=/sshs.club/gfwlist +server=/x1337x.eu/127.0.0.1#5335 +ipset=/x1337x.eu/gfwlist +server=/firestone.co.cr/127.0.0.1#5335 +ipset=/firestone.co.cr/gfwlist +server=/intel.nz/127.0.0.1#5335 +ipset=/intel.nz/gfwlist +server=/atube.xxx/127.0.0.1#5335 +ipset=/atube.xxx/gfwlist +server=/intel.com.ec/127.0.0.1#5335 +ipset=/intel.com.ec/gfwlist +server=/pascherbeatsmonster.com/127.0.0.1#5335 +ipset=/pascherbeatsmonster.com/gfwlist +server=/wholekidsfoundation.org/127.0.0.1#5335 +ipset=/wholekidsfoundation.org/gfwlist +server=/parse.com/127.0.0.1#5335 +ipset=/parse.com/gfwlist +server=/organicmaps.app/127.0.0.1#5335 +ipset=/organicmaps.app/gfwlist +server=/doeda.com/127.0.0.1#5335 +ipset=/doeda.com/gfwlist +server=/instastyle.tv/127.0.0.1#5335 +ipset=/instastyle.tv/gfwlist +server=/ruby-lang.org/127.0.0.1#5335 +ipset=/ruby-lang.org/gfwlist +server=/cmmedia.com.tw/127.0.0.1#5335 +ipset=/cmmedia.com.tw/gfwlist +server=/google.gm/127.0.0.1#5335 +ipset=/google.gm/gfwlist +server=/linear-abematv.akamaized.net/127.0.0.1#5335 +ipset=/linear-abematv.akamaized.net/gfwlist +server=/fetishbank.net/127.0.0.1#5335 +ipset=/fetishbank.net/gfwlist +server=/fightforux.com/127.0.0.1#5335 +ipset=/fightforux.com/gfwlist +server=/pwmnet.com/127.0.0.1#5335 +ipset=/pwmnet.com/gfwlist +server=/jerkmate.com/127.0.0.1#5335 +ipset=/jerkmate.com/gfwlist +server=/fox7austin.com/127.0.0.1#5335 +ipset=/fox7austin.com/gfwlist +server=/scala-lang.org/127.0.0.1#5335 +ipset=/scala-lang.org/gfwlist +server=/disneyinflight.com/127.0.0.1#5335 +ipset=/disneyinflight.com/gfwlist +server=/gamesstack.com/127.0.0.1#5335 +ipset=/gamesstack.com/gfwlist +server=/volvotrucks.co.bw/127.0.0.1#5335 +ipset=/volvotrucks.co.bw/gfwlist +server=/tiberiumalliances.com/127.0.0.1#5335 +ipset=/tiberiumalliances.com/gfwlist +server=/kaamuu.com/127.0.0.1#5335 +ipset=/kaamuu.com/gfwlist +server=/commandandconquer.com/127.0.0.1#5335 +ipset=/commandandconquer.com/gfwlist +server=/finish.bg/127.0.0.1#5335 +ipset=/finish.bg/gfwlist +server=/vporn.com/127.0.0.1#5335 +ipset=/vporn.com/gfwlist +server=/bmw.com.ar/127.0.0.1#5335 +ipset=/bmw.com.ar/gfwlist +server=/intel.co.cr/127.0.0.1#5335 +ipset=/intel.co.cr/gfwlist +server=/kechtube.com/127.0.0.1#5335 +ipset=/kechtube.com/gfwlist +server=/dreamforce.com/127.0.0.1#5335 +ipset=/dreamforce.com/gfwlist +server=/beatsbydresstudio.com/127.0.0.1#5335 +ipset=/beatsbydresstudio.com/gfwlist +server=/2beeg.me/127.0.0.1#5335 +ipset=/2beeg.me/gfwlist +server=/google.com/127.0.0.1#5335 +ipset=/google.com/gfwlist +server=/imzog.com/127.0.0.1#5335 +ipset=/imzog.com/gfwlist +server=/swegold.com/127.0.0.1#5335 +ipset=/swegold.com/gfwlist +server=/sexyfucking.ru/127.0.0.1#5335 +ipset=/sexyfucking.ru/gfwlist +server=/sensualgirls.org/127.0.0.1#5335 +ipset=/sensualgirls.org/gfwlist +server=/bululusexdoll.com/127.0.0.1#5335 +ipset=/bululusexdoll.com/gfwlist +server=/ebaycourse.com/127.0.0.1#5335 +ipset=/ebaycourse.com/gfwlist +server=/intel.sx/127.0.0.1#5335 +ipset=/intel.sx/gfwlist +server=/12diasderegalosdeitunes.co.ni/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.co.ni/gfwlist +server=/vanish.co.za/127.0.0.1#5335 +ipset=/vanish.co.za/gfwlist +server=/alfera.com.my/127.0.0.1#5335 +ipset=/alfera.com.my/gfwlist +server=/youtube.no/127.0.0.1#5335 +ipset=/youtube.no/gfwlist +server=/woolite.com/127.0.0.1#5335 +ipset=/woolite.com/gfwlist +server=/businessweekmag.com/127.0.0.1#5335 +ipset=/businessweekmag.com/gfwlist +server=/fox23.com/127.0.0.1#5335 +ipset=/fox23.com/gfwlist +server=/huobitoken.com/127.0.0.1#5335 +ipset=/huobitoken.com/gfwlist +server=/thepornmap.com/127.0.0.1#5335 +ipset=/thepornmap.com/gfwlist +server=/pokemonhome.com/127.0.0.1#5335 +ipset=/pokemonhome.com/gfwlist +server=/77maott.com/127.0.0.1#5335 +ipset=/77maott.com/gfwlist +server=/volvotrucks.lv/127.0.0.1#5335 +ipset=/volvotrucks.lv/gfwlist +server=/modeltv.com/127.0.0.1#5335 +ipset=/modeltv.com/gfwlist +server=/jpg4.pw/127.0.0.1#5335 +ipset=/jpg4.pw/gfwlist +server=/facegbook.com/127.0.0.1#5335 +ipset=/facegbook.com/gfwlist +server=/bmw-plant-munich.com/127.0.0.1#5335 +ipset=/bmw-plant-munich.com/gfwlist +server=/appleone.film/127.0.0.1#5335 +ipset=/appleone.film/gfwlist +server=/mini-georgia.com/127.0.0.1#5335 +ipset=/mini-georgia.com/gfwlist +server=/fundraisingwithfacebook.com/127.0.0.1#5335 +ipset=/fundraisingwithfacebook.com/gfwlist +server=/hpfeedback.com/127.0.0.1#5335 +ipset=/hpfeedback.com/gfwlist +server=/leagueoflegends.net/127.0.0.1#5335 +ipset=/leagueoflegends.net/gfwlist +server=/xxx-ways.com/127.0.0.1#5335 +ipset=/xxx-ways.com/gfwlist +server=/youtube.al/127.0.0.1#5335 +ipset=/youtube.al/gfwlist +server=/fetishes.cam/127.0.0.1#5335 +ipset=/fetishes.cam/gfwlist +server=/webex.ca/127.0.0.1#5335 +ipset=/webex.ca/gfwlist +server=/primevideo.cc/127.0.0.1#5335 +ipset=/primevideo.cc/gfwlist +server=/streamporn.cc/127.0.0.1#5335 +ipset=/streamporn.cc/gfwlist +server=/lecoin.cc/127.0.0.1#5335 +ipset=/lecoin.cc/gfwlist +server=/ebay.de/127.0.0.1#5335 +ipset=/ebay.de/gfwlist +server=/ameblo.jp/127.0.0.1#5335 +ipset=/ameblo.jp/gfwlist +server=/miniso.pe/127.0.0.1#5335 +ipset=/miniso.pe/gfwlist +server=/servicetalk.io/127.0.0.1#5335 +ipset=/servicetalk.io/gfwlist +server=/facebooklogin.com/127.0.0.1#5335 +ipset=/facebooklogin.com/gfwlist +server=/unityads.unity3d.com/127.0.0.1#5335 +ipset=/unityads.unity3d.com/gfwlist +server=/beatsbydreinexpensive.com/127.0.0.1#5335 +ipset=/beatsbydreinexpensive.com/gfwlist +server=/softbank-telecom.net/127.0.0.1#5335 +ipset=/softbank-telecom.net/gfwlist +server=/ikea.com.de/127.0.0.1#5335 +ipset=/ikea.com.de/gfwlist +server=/2bit8.com/127.0.0.1#5335 +ipset=/2bit8.com/gfwlist +server=/rb-crisis.com/127.0.0.1#5335 +ipset=/rb-crisis.com/gfwlist +server=/uug25.com/127.0.0.1#5335 +ipset=/uug25.com/gfwlist +server=/alphabet.eu/127.0.0.1#5335 +ipset=/alphabet.eu/gfwlist +server=/porn.to/127.0.0.1#5335 +ipset=/porn.to/gfwlist +server=/vpornvideos.com/127.0.0.1#5335 +ipset=/vpornvideos.com/gfwlist +server=/drunk6.com/127.0.0.1#5335 +ipset=/drunk6.com/gfwlist +server=/vimeo-staging.com/127.0.0.1#5335 +ipset=/vimeo-staging.com/gfwlist +server=/fbinc.com/127.0.0.1#5335 +ipset=/fbinc.com/gfwlist +server=/dkk37.com/127.0.0.1#5335 +ipset=/dkk37.com/gfwlist +server=/pinterest.kr/127.0.0.1#5335 +ipset=/pinterest.kr/gfwlist +server=/vjmedia.com.hk/127.0.0.1#5335 +ipset=/vjmedia.com.hk/gfwlist +server=/taose.tv/127.0.0.1#5335 +ipset=/taose.tv/gfwlist +server=/bridgestone-plt-eng.com/127.0.0.1#5335 +ipset=/bridgestone-plt-eng.com/gfwlist +server=/miniso.ma/127.0.0.1#5335 +ipset=/miniso.ma/gfwlist +server=/dirtyleague.com/127.0.0.1#5335 +ipset=/dirtyleague.com/gfwlist +server=/javmenu.com/127.0.0.1#5335 +ipset=/javmenu.com/gfwlist +server=/getdirect.tv/127.0.0.1#5335 +ipset=/getdirect.tv/gfwlist +server=/steampipe-kr.akamaized.net/127.0.0.1#5335 +ipset=/steampipe-kr.akamaized.net/gfwlist +server=/adobeaemcloud.com/127.0.0.1#5335 +ipset=/adobeaemcloud.com/gfwlist +server=/paypal.com/127.0.0.1#5335 +ipset=/paypal.com/gfwlist +server=/crosswalk-project.net/127.0.0.1#5335 +ipset=/crosswalk-project.net/gfwlist +server=/nikecloud.com/127.0.0.1#5335 +ipset=/nikecloud.com/gfwlist +server=/easportsworld.com/127.0.0.1#5335 +ipset=/easportsworld.com/gfwlist +server=/starbuckspoq.com/127.0.0.1#5335 +ipset=/starbuckspoq.com/gfwlist +server=/binancezh.mobi/127.0.0.1#5335 +ipset=/binancezh.mobi/gfwlist +server=/twinprime.com/127.0.0.1#5335 +ipset=/twinprime.com/gfwlist +server=/179na.com/127.0.0.1#5335 +ipset=/179na.com/gfwlist +server=/adidas.be/127.0.0.1#5335 +ipset=/adidas.be/gfwlist +server=/googleventures.com/127.0.0.1#5335 +ipset=/googleventures.com/gfwlist +server=/camvideos.org/127.0.0.1#5335 +ipset=/camvideos.org/gfwlist +server=/beatsheadphonesforcheap.net/127.0.0.1#5335 +ipset=/beatsheadphonesforcheap.net/gfwlist +server=/tubetop69.com/127.0.0.1#5335 +ipset=/tubetop69.com/gfwlist +server=/cloudinsights.com/127.0.0.1#5335 +ipset=/cloudinsights.com/gfwlist +server=/joysporn.com/127.0.0.1#5335 +ipset=/joysporn.com/gfwlist +server=/bmwvalueservice.com/127.0.0.1#5335 +ipset=/bmwvalueservice.com/gfwlist +server=/visa.com.vc/127.0.0.1#5335 +ipset=/visa.com.vc/gfwlist +server=/finish.co.za/127.0.0.1#5335 +ipset=/finish.co.za/gfwlist +server=/incestvidz.com/127.0.0.1#5335 +ipset=/incestvidz.com/gfwlist +server=/beatsbydresales.us/127.0.0.1#5335 +ipset=/beatsbydresales.us/gfwlist +server=/openresty.org/127.0.0.1#5335 +ipset=/openresty.org/gfwlist +server=/canon.pt/127.0.0.1#5335 +ipset=/canon.pt/gfwlist +server=/canon.fi/127.0.0.1#5335 +ipset=/canon.fi/gfwlist +server=/globalsign.ch/127.0.0.1#5335 +ipset=/globalsign.ch/gfwlist +server=/artstor.org/127.0.0.1#5335 +ipset=/artstor.org/gfwlist +server=/thefoxnation.com/127.0.0.1#5335 +ipset=/thefoxnation.com/gfwlist +server=/3pornstarmovies.com/127.0.0.1#5335 +ipset=/3pornstarmovies.com/gfwlist +server=/jmcomic1.me/127.0.0.1#5335 +ipset=/jmcomic1.me/gfwlist +server=/ieeefoundation.org/127.0.0.1#5335 +ipset=/ieeefoundation.org/gfwlist +server=/pornjk.com/127.0.0.1#5335 +ipset=/pornjk.com/gfwlist +server=/baterias-hp.com/127.0.0.1#5335 +ipset=/baterias-hp.com/gfwlist +server=/ipad.de/127.0.0.1#5335 +ipset=/ipad.de/gfwlist +server=/xn--x-qeu1ji09tzlg.net/127.0.0.1#5335 +ipset=/xn--x-qeu1ji09tzlg.net/gfwlist +server=/porno.org.in/127.0.0.1#5335 +ipset=/porno.org.in/gfwlist +server=/miniso-nz.com/127.0.0.1#5335 +ipset=/miniso-nz.com/gfwlist +server=/worldscientific.com/127.0.0.1#5335 +ipset=/worldscientific.com/gfwlist +server=/mypornadviser.com/127.0.0.1#5335 +ipset=/mypornadviser.com/gfwlist +server=/bmw-motorrad.rs/127.0.0.1#5335 +ipset=/bmw-motorrad.rs/gfwlist +server=/bestbuycanadaltd.ca/127.0.0.1#5335 +ipset=/bestbuycanadaltd.ca/gfwlist +server=/ebay.jp/127.0.0.1#5335 +ipset=/ebay.jp/gfwlist +server=/momon-ga.com/127.0.0.1#5335 +ipset=/momon-ga.com/gfwlist +server=/x.co/127.0.0.1#5335 +ipset=/x.co/gfwlist +server=/pornultras.com/127.0.0.1#5335 +ipset=/pornultras.com/gfwlist +server=/t.co/127.0.0.1#5335 +ipset=/t.co/gfwlist +server=/uun98.com/127.0.0.1#5335 +ipset=/uun98.com/gfwlist +server=/netacad.net/127.0.0.1#5335 +ipset=/netacad.net/gfwlist +server=/couplecam.co.uk/127.0.0.1#5335 +ipset=/couplecam.co.uk/gfwlist +server=/placesdocs.com/127.0.0.1#5335 +ipset=/placesdocs.com/gfwlist +server=/vimeogoods.com/127.0.0.1#5335 +ipset=/vimeogoods.com/gfwlist +server=/dropboxforums.com/127.0.0.1#5335 +ipset=/dropboxforums.com/gfwlist +server=/g.co/127.0.0.1#5335 +ipset=/g.co/gfwlist +server=/lolfanart.net/127.0.0.1#5335 +ipset=/lolfanart.net/gfwlist +server=/pixiv.me/127.0.0.1#5335 +ipset=/pixiv.me/gfwlist +server=/iphoto.wang/127.0.0.1#5335 +ipset=/iphoto.wang/gfwlist +server=/nasty.singles/127.0.0.1#5335 +ipset=/nasty.singles/gfwlist +server=/bmw.az/127.0.0.1#5335 +ipset=/bmw.az/gfwlist +server=/lihksnap.com/127.0.0.1#5335 +ipset=/lihksnap.com/gfwlist +server=/ck101.com/127.0.0.1#5335 +ipset=/ck101.com/gfwlist +server=/bestbuytradein.com/127.0.0.1#5335 +ipset=/bestbuytradein.com/gfwlist +server=/paypalcorp.com/127.0.0.1#5335 +ipset=/paypalcorp.com/gfwlist +server=/wtfpeople.com/127.0.0.1#5335 +ipset=/wtfpeople.com/gfwlist +server=/developer.microsoft.com/127.0.0.1#5335 +ipset=/developer.microsoft.com/gfwlist +server=/selectanescort.com/127.0.0.1#5335 +ipset=/selectanescort.com/gfwlist +server=/vector.im/127.0.0.1#5335 +ipset=/vector.im/gfwlist +server=/dgg.gg/127.0.0.1#5335 +ipset=/dgg.gg/gfwlist +server=/adgoogle.net/127.0.0.1#5335 +ipset=/adgoogle.net/gfwlist +server=/oath.com/127.0.0.1#5335 +ipset=/oath.com/gfwlist +server=/thepornbin.com/127.0.0.1#5335 +ipset=/thepornbin.com/gfwlist +server=/thetranny.com/127.0.0.1#5335 +ipset=/thetranny.com/gfwlist +server=/alphabet.co.uk/127.0.0.1#5335 +ipset=/alphabet.co.uk/gfwlist +server=/thesun.ie/127.0.0.1#5335 +ipset=/thesun.ie/gfwlist +server=/frprn.com/127.0.0.1#5335 +ipset=/frprn.com/gfwlist +server=/tufos.com.br/127.0.0.1#5335 +ipset=/tufos.com.br/gfwlist +server=/hdporncomics.com/127.0.0.1#5335 +ipset=/hdporncomics.com/gfwlist +server=/intel.gs/127.0.0.1#5335 +ipset=/intel.gs/gfwlist +server=/cups.org/127.0.0.1#5335 +ipset=/cups.org/gfwlist +server=/opera.com/127.0.0.1#5335 +ipset=/opera.com/gfwlist +server=/applestore.ch/127.0.0.1#5335 +ipset=/applestore.ch/gfwlist +server=/monsterdrebeats-usa.com/127.0.0.1#5335 +ipset=/monsterdrebeats-usa.com/gfwlist +server=/freessl.com/127.0.0.1#5335 +ipset=/freessl.com/gfwlist +server=/postegro.it/127.0.0.1#5335 +ipset=/postegro.it/gfwlist +server=/75m.co/127.0.0.1#5335 +ipset=/75m.co/gfwlist +server=/freewechat.com/127.0.0.1#5335 +ipset=/freewechat.com/gfwlist +server=/atubex.com/127.0.0.1#5335 +ipset=/atubex.com/gfwlist +server=/thehentaiworld.com/127.0.0.1#5335 +ipset=/thehentaiworld.com/gfwlist +server=/mini.com.ph/127.0.0.1#5335 +ipset=/mini.com.ph/gfwlist +server=/johren.net/127.0.0.1#5335 +ipset=/johren.net/gfwlist +server=/shopifycdn.com/127.0.0.1#5335 +ipset=/shopifycdn.com/gfwlist +server=/hdzog.com/127.0.0.1#5335 +ipset=/hdzog.com/gfwlist +server=/fqcebook.com/127.0.0.1#5335 +ipset=/fqcebook.com/gfwlist +server=/edgedatg.com/127.0.0.1#5335 +ipset=/edgedatg.com/gfwlist +server=/freepornhdonlinegay.com/127.0.0.1#5335 +ipset=/freepornhdonlinegay.com/gfwlist +server=/dealtree.org/127.0.0.1#5335 +ipset=/dealtree.org/gfwlist +server=/ohgratisporrfilm.com/127.0.0.1#5335 +ipset=/ohgratisporrfilm.com/gfwlist +server=/manhuntdaily.com/127.0.0.1#5335 +ipset=/manhuntdaily.com/gfwlist +server=/att-rsvp.com/127.0.0.1#5335 +ipset=/att-rsvp.com/gfwlist +server=/bmw-connecteddrive.jp/127.0.0.1#5335 +ipset=/bmw-connecteddrive.jp/gfwlist +server=/v2ph.com/127.0.0.1#5335 +ipset=/v2ph.com/gfwlist +server=/porzo.com/127.0.0.1#5335 +ipset=/porzo.com/gfwlist +server=/app-measurement.com/127.0.0.1#5335 +ipset=/app-measurement.com/gfwlist +server=/beatsforme.com/127.0.0.1#5335 +ipset=/beatsforme.com/gfwlist +server=/typesquare.com/127.0.0.1#5335 +ipset=/typesquare.com/gfwlist +server=/ashemaletube.com/127.0.0.1#5335 +ipset=/ashemaletube.com/gfwlist +server=/azureiotsolutions.com/127.0.0.1#5335 +ipset=/azureiotsolutions.com/gfwlist +server=/shywifeswap.com/127.0.0.1#5335 +ipset=/shywifeswap.com/gfwlist +server=/applw.com/127.0.0.1#5335 +ipset=/applw.com/gfwlist +server=/airwick.pt/127.0.0.1#5335 +ipset=/airwick.pt/gfwlist +server=/snapstore.io/127.0.0.1#5335 +ipset=/snapstore.io/gfwlist +server=/clickedu.co.uk/127.0.0.1#5335 +ipset=/clickedu.co.uk/gfwlist +server=/firebaseio.com/127.0.0.1#5335 +ipset=/firebaseio.com/gfwlist +server=/mastercard.com.ng/127.0.0.1#5335 +ipset=/mastercard.com.ng/gfwlist +server=/hpwsn.com/127.0.0.1#5335 +ipset=/hpwsn.com/gfwlist +server=/acgdv.com/127.0.0.1#5335 +ipset=/acgdv.com/gfwlist +server=/geotrust.com/127.0.0.1#5335 +ipset=/geotrust.com/gfwlist +server=/cheapbeatsie.com/127.0.0.1#5335 +ipset=/cheapbeatsie.com/gfwlist +server=/mortein.com.au/127.0.0.1#5335 +ipset=/mortein.com.au/gfwlist +server=/starbucks.co.th/127.0.0.1#5335 +ipset=/starbucks.co.th/gfwlist +server=/realclearreligion.org/127.0.0.1#5335 +ipset=/realclearreligion.org/gfwlist +server=/eroelog.com/127.0.0.1#5335 +ipset=/eroelog.com/gfwlist +server=/publichealthdepartment.info/127.0.0.1#5335 +ipset=/publichealthdepartment.info/gfwlist +server=/ebayrtm.com/127.0.0.1#5335 +ipset=/ebayrtm.com/gfwlist +server=/guccimuseo.com/127.0.0.1#5335 +ipset=/guccimuseo.com/gfwlist +server=/businessweekly.com.tw/127.0.0.1#5335 +ipset=/businessweekly.com.tw/gfwlist +server=/intel.re/127.0.0.1#5335 +ipset=/intel.re/gfwlist +server=/apple.uk/127.0.0.1#5335 +ipset=/apple.uk/gfwlist +server=/passion.com/127.0.0.1#5335 +ipset=/passion.com/gfwlist +server=/good-gay.com/127.0.0.1#5335 +ipset=/good-gay.com/gfwlist +server=/google.hn/127.0.0.1#5335 +ipset=/google.hn/gfwlist +server=/news.com.au/127.0.0.1#5335 +ipset=/news.com.au/gfwlist +server=/hongkongfp.com/127.0.0.1#5335 +ipset=/hongkongfp.com/gfwlist +server=/geeksquadwebroot.org/127.0.0.1#5335 +ipset=/geeksquadwebroot.org/gfwlist +server=/imagefap.com/127.0.0.1#5335 +ipset=/imagefap.com/gfwlist +server=/google.com.uy/127.0.0.1#5335 +ipset=/google.com.uy/gfwlist +server=/foxsportsnetmilwaukee.com/127.0.0.1#5335 +ipset=/foxsportsnetmilwaukee.com/gfwlist +server=/mikuexpo.com/127.0.0.1#5335 +ipset=/mikuexpo.com/gfwlist +server=/intel.ph/127.0.0.1#5335 +ipset=/intel.ph/gfwlist +server=/matrix.to/127.0.0.1#5335 +ipset=/matrix.to/gfwlist +server=/alhs.xyz/127.0.0.1#5335 +ipset=/alhs.xyz/gfwlist +server=/hpmarketplace.com/127.0.0.1#5335 +ipset=/hpmarketplace.com/gfwlist +server=/nicomanga.jp/127.0.0.1#5335 +ipset=/nicomanga.jp/gfwlist +server=/tubelombia.net/127.0.0.1#5335 +ipset=/tubelombia.net/gfwlist +server=/thecandidbay.com/127.0.0.1#5335 +ipset=/thecandidbay.com/gfwlist +server=/igaychat.com/127.0.0.1#5335 +ipset=/igaychat.com/gfwlist +server=/epochweek.com/127.0.0.1#5335 +ipset=/epochweek.com/gfwlist +server=/mingpao.com/127.0.0.1#5335 +ipset=/mingpao.com/gfwlist +server=/comicsporno.es/127.0.0.1#5335 +ipset=/comicsporno.es/gfwlist +server=/awflapp.top/127.0.0.1#5335 +ipset=/awflapp.top/gfwlist +server=/hentaidude.xxx/127.0.0.1#5335 +ipset=/hentaidude.xxx/gfwlist +server=/aspnetcdn.com/127.0.0.1#5335 +ipset=/aspnetcdn.com/gfwlist +server=/faronics.tech/127.0.0.1#5335 +ipset=/faronics.tech/gfwlist +server=/12diasderegalosdeitunes.com.ve/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.com.ve/gfwlist +server=/applesurveys.com/127.0.0.1#5335 +ipset=/applesurveys.com/gfwlist +server=/minimoncton.ca/127.0.0.1#5335 +ipset=/minimoncton.ca/gfwlist +server=/gettyimages.no/127.0.0.1#5335 +ipset=/gettyimages.no/gfwlist +server=/acrobat.com/127.0.0.1#5335 +ipset=/acrobat.com/gfwlist +server=/czechstreets.com/127.0.0.1#5335 +ipset=/czechstreets.com/gfwlist +server=/tmsnrt.rs/127.0.0.1#5335 +ipset=/tmsnrt.rs/gfwlist +server=/hotmovs.com/127.0.0.1#5335 +ipset=/hotmovs.com/gfwlist +server=/ashleysageellison.com/127.0.0.1#5335 +ipset=/ashleysageellison.com/gfwlist +server=/ocsp-responder.com/127.0.0.1#5335 +ipset=/ocsp-responder.com/gfwlist +server=/myanmar-porn.com/127.0.0.1#5335 +ipset=/myanmar-porn.com/gfwlist +server=/sexmutant.com/127.0.0.1#5335 +ipset=/sexmutant.com/gfwlist +server=/pokemonbw.com/127.0.0.1#5335 +ipset=/pokemonbw.com/gfwlist +server=/sexbq.com/127.0.0.1#5335 +ipset=/sexbq.com/gfwlist +server=/vmwarestuff.com/127.0.0.1#5335 +ipset=/vmwarestuff.com/gfwlist +server=/bmwcharitygolf.com/127.0.0.1#5335 +ipset=/bmwcharitygolf.com/gfwlist +server=/men18.net/127.0.0.1#5335 +ipset=/men18.net/gfwlist +server=/machotube.tv/127.0.0.1#5335 +ipset=/machotube.tv/gfwlist +server=/dellcdn.com/127.0.0.1#5335 +ipset=/dellcdn.com/gfwlist +server=/parastorage.com/127.0.0.1#5335 +ipset=/parastorage.com/gfwlist +server=/applenewsformat.com/127.0.0.1#5335 +ipset=/applenewsformat.com/gfwlist +server=/pokemonchampionships.com/127.0.0.1#5335 +ipset=/pokemonchampionships.com/gfwlist +server=/putinho.net/127.0.0.1#5335 +ipset=/putinho.net/gfwlist +server=/itsbetterwhenyouwinit.com/127.0.0.1#5335 +ipset=/itsbetterwhenyouwinit.com/gfwlist +server=/51mh.app/127.0.0.1#5335 +ipset=/51mh.app/gfwlist +server=/porn91.org/127.0.0.1#5335 +ipset=/porn91.org/gfwlist +server=/appleappstore.net/127.0.0.1#5335 +ipset=/appleappstore.net/gfwlist +server=/corbinfisher.com/127.0.0.1#5335 +ipset=/corbinfisher.com/gfwlist +server=/incestflix.com/127.0.0.1#5335 +ipset=/incestflix.com/gfwlist +server=/bighead.group/127.0.0.1#5335 +ipset=/bighead.group/gfwlist +server=/trixhentai.com/127.0.0.1#5335 +ipset=/trixhentai.com/gfwlist +server=/xnalgas.com/127.0.0.1#5335 +ipset=/xnalgas.com/gfwlist +server=/umass.edu/127.0.0.1#5335 +ipset=/umass.edu/gfwlist +server=/rakuten.co.jp/127.0.0.1#5335 +ipset=/rakuten.co.jp/gfwlist +server=/google.li/127.0.0.1#5335 +ipset=/google.li/gfwlist +server=/adobesigncdn.com/127.0.0.1#5335 +ipset=/adobesigncdn.com/gfwlist +server=/verisign.se/127.0.0.1#5335 +ipset=/verisign.se/gfwlist +server=/ideal-teens.com/127.0.0.1#5335 +ipset=/ideal-teens.com/gfwlist +server=/monsterbeatsbydrdrestudio.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrdrestudio.com/gfwlist +server=/javscatsex.com/127.0.0.1#5335 +ipset=/javscatsex.com/gfwlist +server=/dtvce.com/127.0.0.1#5335 +ipset=/dtvce.com/gfwlist +server=/cs4hs.com/127.0.0.1#5335 +ipset=/cs4hs.com/gfwlist +server=/mm9c63ae.xyz/127.0.0.1#5335 +ipset=/mm9c63ae.xyz/gfwlist +server=/microsoftstore.com/127.0.0.1#5335 +ipset=/microsoftstore.com/gfwlist +server=/bandpage.com/127.0.0.1#5335 +ipset=/bandpage.com/gfwlist +server=/prothots.com/127.0.0.1#5335 +ipset=/prothots.com/gfwlist +server=/heroesofdragonage.com/127.0.0.1#5335 +ipset=/heroesofdragonage.com/gfwlist +server=/chengjuanseo.com/127.0.0.1#5335 +ipset=/chengjuanseo.com/gfwlist +server=/pornjav.org/127.0.0.1#5335 +ipset=/pornjav.org/gfwlist +server=/darivoa.com/127.0.0.1#5335 +ipset=/darivoa.com/gfwlist +server=/myhomemadesex.com/127.0.0.1#5335 +ipset=/myhomemadesex.com/gfwlist +server=/foxsports-newyork.com/127.0.0.1#5335 +ipset=/foxsports-newyork.com/gfwlist +server=/18qt.com/127.0.0.1#5335 +ipset=/18qt.com/gfwlist +server=/bmw-motorrad-motorsport.com/127.0.0.1#5335 +ipset=/bmw-motorrad-motorsport.com/gfwlist +server=/nature.com/127.0.0.1#5335 +ipset=/nature.com/gfwlist +server=/huluspain.com/127.0.0.1#5335 +ipset=/huluspain.com/gfwlist +server=/golang.com/127.0.0.1#5335 +ipset=/golang.com/gfwlist +server=/ebayenterprise.tv/127.0.0.1#5335 +ipset=/ebayenterprise.tv/gfwlist +server=/sankei.co.jp/127.0.0.1#5335 +ipset=/sankei.co.jp/gfwlist +server=/emojipedia.org/127.0.0.1#5335 +ipset=/emojipedia.org/gfwlist +server=/facebool.info/127.0.0.1#5335 +ipset=/facebool.info/gfwlist +server=/privacytools.io/127.0.0.1#5335 +ipset=/privacytools.io/gfwlist +server=/jiayoulu.com/127.0.0.1#5335 +ipset=/jiayoulu.com/gfwlist +server=/miniso.jp/127.0.0.1#5335 +ipset=/miniso.jp/gfwlist +server=/ebaysweden.com/127.0.0.1#5335 +ipset=/ebaysweden.com/gfwlist +server=/pearsonclinical.be/127.0.0.1#5335 +ipset=/pearsonclinical.be/gfwlist +server=/wal.co/127.0.0.1#5335 +ipset=/wal.co/gfwlist +server=/sony.ro/127.0.0.1#5335 +ipset=/sony.ro/gfwlist +server=/blackshemalevideo.com/127.0.0.1#5335 +ipset=/blackshemalevideo.com/gfwlist +server=/xbooru.com/127.0.0.1#5335 +ipset=/xbooru.com/gfwlist +server=/globalsign.es/127.0.0.1#5335 +ipset=/globalsign.es/gfwlist +server=/directvatlantaga.com/127.0.0.1#5335 +ipset=/directvatlantaga.com/gfwlist +server=/enemarotica.com/127.0.0.1#5335 +ipset=/enemarotica.com/gfwlist +server=/hbomax.com/127.0.0.1#5335 +ipset=/hbomax.com/gfwlist +server=/xboxlive.com/127.0.0.1#5335 +ipset=/xboxlive.com/gfwlist +server=/visaeverywhereshop.com/127.0.0.1#5335 +ipset=/visaeverywhereshop.com/gfwlist +server=/riotcdn.net/127.0.0.1#5335 +ipset=/riotcdn.net/gfwlist +server=/sankei-call.jp/127.0.0.1#5335 +ipset=/sankei-call.jp/gfwlist +server=/drebeatssite.com/127.0.0.1#5335 +ipset=/drebeatssite.com/gfwlist +server=/pleasuremore.com/127.0.0.1#5335 +ipset=/pleasuremore.com/gfwlist +server=/3789av.com/127.0.0.1#5335 +ipset=/3789av.com/gfwlist +server=/2789av.com/127.0.0.1#5335 +ipset=/2789av.com/gfwlist +server=/britsexcash.com/127.0.0.1#5335 +ipset=/britsexcash.com/gfwlist +server=/pornreactor.cc/127.0.0.1#5335 +ipset=/pornreactor.cc/gfwlist +server=/veet.tv/127.0.0.1#5335 +ipset=/veet.tv/gfwlist +server=/iproperty.com.sg/127.0.0.1#5335 +ipset=/iproperty.com.sg/gfwlist +server=/bmw-auslieferungszentrum.com/127.0.0.1#5335 +ipset=/bmw-auslieferungszentrum.com/gfwlist +server=/visadns.com/127.0.0.1#5335 +ipset=/visadns.com/gfwlist +server=/feedherfuckher.com/127.0.0.1#5335 +ipset=/feedherfuckher.com/gfwlist +server=/fgirl.ch/127.0.0.1#5335 +ipset=/fgirl.ch/gfwlist +server=/softbankhawksstore.jp/127.0.0.1#5335 +ipset=/softbankhawksstore.jp/gfwlist +server=/pearsonclinical.se/127.0.0.1#5335 +ipset=/pearsonclinical.se/gfwlist +server=/heartbreakers.info/127.0.0.1#5335 +ipset=/heartbreakers.info/gfwlist +server=/ikea.bg/127.0.0.1#5335 +ipset=/ikea.bg/gfwlist +server=/volvobuses.hu/127.0.0.1#5335 +ipset=/volvobuses.hu/gfwlist +server=/wiifit.com/127.0.0.1#5335 +ipset=/wiifit.com/gfwlist +server=/samsungqbe.com/127.0.0.1#5335 +ipset=/samsungqbe.com/gfwlist +server=/bzazi.com/127.0.0.1#5335 +ipset=/bzazi.com/gfwlist +server=/x-artvideo.net/127.0.0.1#5335 +ipset=/x-artvideo.net/gfwlist +server=/yandex.pl/127.0.0.1#5335 +ipset=/yandex.pl/gfwlist +server=/wikia.org/127.0.0.1#5335 +ipset=/wikia.org/gfwlist +server=/bidong9.com/127.0.0.1#5335 +ipset=/bidong9.com/gfwlist +server=/sandisk.co.kr/127.0.0.1#5335 +ipset=/sandisk.co.kr/gfwlist +server=/veporno.net/127.0.0.1#5335 +ipset=/veporno.net/gfwlist +server=/darwinsource.org/127.0.0.1#5335 +ipset=/darwinsource.org/gfwlist +server=/ciscoconnectcloud.com/127.0.0.1#5335 +ipset=/ciscoconnectcloud.com/gfwlist +server=/avmoo.click/127.0.0.1#5335 +ipset=/avmoo.click/gfwlist +server=/sae.org/127.0.0.1#5335 +ipset=/sae.org/gfwlist +server=/chatwhores.com/127.0.0.1#5335 +ipset=/chatwhores.com/gfwlist +server=/meetyourdevices.com/127.0.0.1#5335 +ipset=/meetyourdevices.com/gfwlist +server=/visa.sk/127.0.0.1#5335 +ipset=/visa.sk/gfwlist +server=/mini.com.bn/127.0.0.1#5335 +ipset=/mini.com.bn/gfwlist +server=/facebookphoto.com/127.0.0.1#5335 +ipset=/facebookphoto.com/gfwlist +server=/mywaytopay.net/127.0.0.1#5335 +ipset=/mywaytopay.net/gfwlist +server=/jpav.us/127.0.0.1#5335 +ipset=/jpav.us/gfwlist +server=/clearasil.us/127.0.0.1#5335 +ipset=/clearasil.us/gfwlist +server=/just.xxx/127.0.0.1#5335 +ipset=/just.xxx/gfwlist +server=/naturalvoices.com/127.0.0.1#5335 +ipset=/naturalvoices.com/gfwlist +server=/freegaypornhdtube.com/127.0.0.1#5335 +ipset=/freegaypornhdtube.com/gfwlist +server=/google.sm/127.0.0.1#5335 +ipset=/google.sm/gfwlist +server=/vilavpn6.xyz/127.0.0.1#5335 +ipset=/vilavpn6.xyz/gfwlist +server=/xxbb9.com/127.0.0.1#5335 +ipset=/xxbb9.com/gfwlist +server=/youtube.com.gt/127.0.0.1#5335 +ipset=/youtube.com.gt/gfwlist +server=/applepodcasts.com/127.0.0.1#5335 +ipset=/applepodcasts.com/gfwlist +server=/google.com.eg/127.0.0.1#5335 +ipset=/google.com.eg/gfwlist +server=/ebalovo.com/127.0.0.1#5335 +ipset=/ebalovo.com/gfwlist +server=/thieme.de/127.0.0.1#5335 +ipset=/thieme.de/gfwlist +server=/openjsf.org/127.0.0.1#5335 +ipset=/openjsf.org/gfwlist +server=/youassporn.com/127.0.0.1#5335 +ipset=/youassporn.com/gfwlist +server=/85st.com/127.0.0.1#5335 +ipset=/85st.com/gfwlist +server=/binance.net/127.0.0.1#5335 +ipset=/binance.net/gfwlist +server=/projectmurphy.net/127.0.0.1#5335 +ipset=/projectmurphy.net/gfwlist +server=/paypal-mobilemoney.com/127.0.0.1#5335 +ipset=/paypal-mobilemoney.com/gfwlist +server=/goldgay.tv/127.0.0.1#5335 +ipset=/goldgay.tv/gfwlist +server=/google.ci/127.0.0.1#5335 +ipset=/google.ci/gfwlist +server=/duckduckgo.uk/127.0.0.1#5335 +ipset=/duckduckgo.uk/gfwlist +server=/bdsm.com/127.0.0.1#5335 +ipset=/bdsm.com/gfwlist +server=/frostbite.com/127.0.0.1#5335 +ipset=/frostbite.com/gfwlist +server=/justporno.tv/127.0.0.1#5335 +ipset=/justporno.tv/gfwlist +server=/googlevideo.com/127.0.0.1#5335 +ipset=/googlevideo.com/gfwlist +server=/dacebook.com/127.0.0.1#5335 +ipset=/dacebook.com/gfwlist +server=/thecuckold.com/127.0.0.1#5335 +ipset=/thecuckold.com/gfwlist +server=/bmw-i-pure-impulse.com/127.0.0.1#5335 +ipset=/bmw-i-pure-impulse.com/gfwlist +server=/simonsgirls.com/127.0.0.1#5335 +ipset=/simonsgirls.com/gfwlist +server=/mysdn.net/127.0.0.1#5335 +ipset=/mysdn.net/gfwlist +server=/mailhealth.com/127.0.0.1#5335 +ipset=/mailhealth.com/gfwlist +server=/gacebook.com/127.0.0.1#5335 +ipset=/gacebook.com/gfwlist +server=/facebook.com/127.0.0.1#5335 +ipset=/facebook.com/gfwlist +server=/skysportsonline.com/127.0.0.1#5335 +ipset=/skysportsonline.com/gfwlist +server=/hp3dprinter.com/127.0.0.1#5335 +ipset=/hp3dprinter.com/gfwlist +server=/iphone.es/127.0.0.1#5335 +ipset=/iphone.es/gfwlist +server=/nichepornsite.com/127.0.0.1#5335 +ipset=/nichepornsite.com/gfwlist +server=/bmw.co.nz/127.0.0.1#5335 +ipset=/bmw.co.nz/gfwlist +server=/bitstamp.net/127.0.0.1#5335 +ipset=/bitstamp.net/gfwlist +server=/microsoft.se/127.0.0.1#5335 +ipset=/microsoft.se/gfwlist +server=/ieee.ca/127.0.0.1#5335 +ipset=/ieee.ca/gfwlist +server=/wireshark.org/127.0.0.1#5335 +ipset=/wireshark.org/gfwlist +server=/bmw-motorrad.lu/127.0.0.1#5335 +ipset=/bmw-motorrad.lu/gfwlist +server=/redditmedia.com/127.0.0.1#5335 +ipset=/redditmedia.com/gfwlist +server=/nationalgeographicpartners.com/127.0.0.1#5335 +ipset=/nationalgeographicpartners.com/gfwlist +server=/applestore.com.pl/127.0.0.1#5335 +ipset=/applestore.com.pl/gfwlist +server=/foxla.com/127.0.0.1#5335 +ipset=/foxla.com/gfwlist +server=/paypal-labs.com/127.0.0.1#5335 +ipset=/paypal-labs.com/gfwlist +server=/conscrypt.com/127.0.0.1#5335 +ipset=/conscrypt.com/gfwlist +server=/rebates.jp/127.0.0.1#5335 +ipset=/rebates.jp/gfwlist +server=/guruofporn.com/127.0.0.1#5335 +ipset=/guruofporn.com/gfwlist +server=/sony.com.ec/127.0.0.1#5335 +ipset=/sony.com.ec/gfwlist +server=/pimg.tw/127.0.0.1#5335 +ipset=/pimg.tw/gfwlist +server=/pornuj.cz/127.0.0.1#5335 +ipset=/pornuj.cz/gfwlist +server=/hipaa6020.com/127.0.0.1#5335 +ipset=/hipaa6020.com/gfwlist +server=/xxvids.net/127.0.0.1#5335 +ipset=/xxvids.net/gfwlist +server=/dot-mac.de/127.0.0.1#5335 +ipset=/dot-mac.de/gfwlist +server=/nytcn.me/127.0.0.1#5335 +ipset=/nytcn.me/gfwlist +server=/foxstudiolot.com/127.0.0.1#5335 +ipset=/foxstudiolot.com/gfwlist +server=/speybay.com/127.0.0.1#5335 +ipset=/speybay.com/gfwlist +server=/rbc007.com/127.0.0.1#5335 +ipset=/rbc007.com/gfwlist +server=/directtv-dish.com/127.0.0.1#5335 +ipset=/directtv-dish.com/gfwlist +server=/hentaivn.la/127.0.0.1#5335 +ipset=/hentaivn.la/gfwlist +server=/dl-iphone.com/127.0.0.1#5335 +ipset=/dl-iphone.com/gfwlist +server=/thefind.com/127.0.0.1#5335 +ipset=/thefind.com/gfwlist +server=/gamcore.com/127.0.0.1#5335 +ipset=/gamcore.com/gfwlist +server=/bridgestoneperformancemedia.net/127.0.0.1#5335 +ipset=/bridgestoneperformancemedia.net/gfwlist +server=/vmwarevmc.com/127.0.0.1#5335 +ipset=/vmwarevmc.com/gfwlist +server=/gogoanime.vc/127.0.0.1#5335 +ipset=/gogoanime.vc/gfwlist +server=/vfsco.de/127.0.0.1#5335 +ipset=/vfsco.de/gfwlist +server=/hentai4manga.com/127.0.0.1#5335 +ipset=/hentai4manga.com/gfwlist +server=/freebsd.org/127.0.0.1#5335 +ipset=/freebsd.org/gfwlist +server=/sonorousporn.com/127.0.0.1#5335 +ipset=/sonorousporn.com/gfwlist +server=/qualcomm.co.jp/127.0.0.1#5335 +ipset=/qualcomm.co.jp/gfwlist +server=/ruten.com.tw/127.0.0.1#5335 +ipset=/ruten.com.tw/gfwlist +server=/factograph.info/127.0.0.1#5335 +ipset=/factograph.info/gfwlist +server=/verisign.com.tw/127.0.0.1#5335 +ipset=/verisign.com.tw/gfwlist +server=/yahoo.co.ve/127.0.0.1#5335 +ipset=/yahoo.co.ve/gfwlist +server=/wikia.nocookie.net/127.0.0.1#5335 +ipset=/wikia.nocookie.net/gfwlist +server=/bmw.nl/127.0.0.1#5335 +ipset=/bmw.nl/gfwlist +server=/bloombergarcade.com/127.0.0.1#5335 +ipset=/bloombergarcade.com/gfwlist +server=/google.cv/127.0.0.1#5335 +ipset=/google.cv/gfwlist +server=/minisoindia.com/127.0.0.1#5335 +ipset=/minisoindia.com/gfwlist +server=/vaultify.com/127.0.0.1#5335 +ipset=/vaultify.com/gfwlist +server=/appdynamics.fr/127.0.0.1#5335 +ipset=/appdynamics.fr/gfwlist +server=/mastercard.ua/127.0.0.1#5335 +ipset=/mastercard.ua/gfwlist +server=/uug27.com/127.0.0.1#5335 +ipset=/uug27.com/gfwlist +server=/crosswalk-project.com/127.0.0.1#5335 +ipset=/crosswalk-project.com/gfwlist +server=/bmwusaservice.com/127.0.0.1#5335 +ipset=/bmwusaservice.com/gfwlist +server=/grannylovesbbc.com/127.0.0.1#5335 +ipset=/grannylovesbbc.com/gfwlist +server=/volvo.com/127.0.0.1#5335 +ipset=/volvo.com/gfwlist +server=/xfuckonline.com/127.0.0.1#5335 +ipset=/xfuckonline.com/gfwlist +server=/bmw.ee/127.0.0.1#5335 +ipset=/bmw.ee/gfwlist +server=/inhumanity.com/127.0.0.1#5335 +ipset=/inhumanity.com/gfwlist +server=/click-url.com/127.0.0.1#5335 +ipset=/click-url.com/gfwlist +server=/bnef.com/127.0.0.1#5335 +ipset=/bnef.com/gfwlist +server=/pycon.org/127.0.0.1#5335 +ipset=/pycon.org/gfwlist +server=/firstanalvideos.com/127.0.0.1#5335 +ipset=/firstanalvideos.com/gfwlist +server=/beatsbydrecheaponlinesales.com/127.0.0.1#5335 +ipset=/beatsbydrecheaponlinesales.com/gfwlist +server=/pinterest.mx/127.0.0.1#5335 +ipset=/pinterest.mx/gfwlist +server=/justdoit.us/127.0.0.1#5335 +ipset=/justdoit.us/gfwlist +server=/rentaride.de/127.0.0.1#5335 +ipset=/rentaride.de/gfwlist +server=/m-power.com/127.0.0.1#5335 +ipset=/m-power.com/gfwlist +server=/dowjoneson.com/127.0.0.1#5335 +ipset=/dowjoneson.com/gfwlist +server=/seehorsepenis.com/127.0.0.1#5335 +ipset=/seehorsepenis.com/gfwlist +server=/foxtel.com/127.0.0.1#5335 +ipset=/foxtel.com/gfwlist +server=/zapper.fi/127.0.0.1#5335 +ipset=/zapper.fi/gfwlist +server=/pros.ee/127.0.0.1#5335 +ipset=/pros.ee/gfwlist +server=/strepsils.ch/127.0.0.1#5335 +ipset=/strepsils.ch/gfwlist +server=/nudedxxx.com/127.0.0.1#5335 +ipset=/nudedxxx.com/gfwlist +server=/hotstarext.com/127.0.0.1#5335 +ipset=/hotstarext.com/gfwlist +server=/realclearmarkets.com/127.0.0.1#5335 +ipset=/realclearmarkets.com/gfwlist +server=/lnkd.in/127.0.0.1#5335 +ipset=/lnkd.in/gfwlist +server=/paylike.com/127.0.0.1#5335 +ipset=/paylike.com/gfwlist +server=/custombeatsforcheap.com/127.0.0.1#5335 +ipset=/custombeatsforcheap.com/gfwlist +server=/epochmall.com/127.0.0.1#5335 +ipset=/epochmall.com/gfwlist +server=/lolibus.top/127.0.0.1#5335 +ipset=/lolibus.top/gfwlist +server=/videopress.com/127.0.0.1#5335 +ipset=/videopress.com/gfwlist +server=/fanfox.net/127.0.0.1#5335 +ipset=/fanfox.net/gfwlist +server=/bmwofannapolis.com/127.0.0.1#5335 +ipset=/bmwofannapolis.com/gfwlist +server=/powersunitedvr.com/127.0.0.1#5335 +ipset=/powersunitedvr.com/gfwlist +server=/ieee-cas.org/127.0.0.1#5335 +ipset=/ieee-cas.org/gfwlist +server=/startupschool.org/127.0.0.1#5335 +ipset=/startupschool.org/gfwlist +server=/paypal-retail.com/127.0.0.1#5335 +ipset=/paypal-retail.com/gfwlist +server=/needforspeedeliminator.com/127.0.0.1#5335 +ipset=/needforspeedeliminator.com/gfwlist +server=/terk.nl/127.0.0.1#5335 +ipset=/terk.nl/gfwlist +server=/netflav1.com/127.0.0.1#5335 +ipset=/netflav1.com/gfwlist +server=/panasonic.jp/127.0.0.1#5335 +ipset=/panasonic.jp/gfwlist +server=/yahoo.ge/127.0.0.1#5335 +ipset=/yahoo.ge/gfwlist +server=/petardas.xxx/127.0.0.1#5335 +ipset=/petardas.xxx/gfwlist +server=/telegram.space/127.0.0.1#5335 +ipset=/telegram.space/gfwlist +server=/youtube.com.sv/127.0.0.1#5335 +ipset=/youtube.com.sv/gfwlist +server=/ahsexfilme.com/127.0.0.1#5335 +ipset=/ahsexfilme.com/gfwlist +server=/beatsbydresalesonline-australia.com/127.0.0.1#5335 +ipset=/beatsbydresalesonline-australia.com/gfwlist +server=/beatsbydresingapores.com/127.0.0.1#5335 +ipset=/beatsbydresingapores.com/gfwlist +server=/epochtimes.eu/127.0.0.1#5335 +ipset=/epochtimes.eu/gfwlist +server=/bmw-yachtsport.com/127.0.0.1#5335 +ipset=/bmw-yachtsport.com/gfwlist +server=/bmw.in/127.0.0.1#5335 +ipset=/bmw.in/gfwlist +server=/microsoftlatamholiday.com/127.0.0.1#5335 +ipset=/microsoftlatamholiday.com/gfwlist +server=/visa.ro/127.0.0.1#5335 +ipset=/visa.ro/gfwlist +server=/adultgamesportal.com/127.0.0.1#5335 +ipset=/adultgamesportal.com/gfwlist +server=/tubeshemales.com/127.0.0.1#5335 +ipset=/tubeshemales.com/gfwlist +server=/apple.hr/127.0.0.1#5335 +ipset=/apple.hr/gfwlist +server=/google.mu/127.0.0.1#5335 +ipset=/google.mu/gfwlist +server=/hdabla.net/127.0.0.1#5335 +ipset=/hdabla.net/gfwlist +server=/playhearthstone.com/127.0.0.1#5335 +ipset=/playhearthstone.com/gfwlist +server=/howtohackfacebook-account.com/127.0.0.1#5335 +ipset=/howtohackfacebook-account.com/gfwlist +server=/bmw.com.mt/127.0.0.1#5335 +ipset=/bmw.com.mt/gfwlist +server=/hamsterfucktube.com/127.0.0.1#5335 +ipset=/hamsterfucktube.com/gfwlist +server=/beatscustomblackfriday.com/127.0.0.1#5335 +ipset=/beatscustomblackfriday.com/gfwlist +server=/17mimei.com/127.0.0.1#5335 +ipset=/17mimei.com/gfwlist +server=/aoc.cat/127.0.0.1#5335 +ipset=/aoc.cat/gfwlist +server=/777tv.net/127.0.0.1#5335 +ipset=/777tv.net/gfwlist +server=/beatsbydre-studio.com/127.0.0.1#5335 +ipset=/beatsbydre-studio.com/gfwlist +server=/bitly.com/127.0.0.1#5335 +ipset=/bitly.com/gfwlist +server=/bnetshopus.akamaized.net/127.0.0.1#5335 +ipset=/bnetshopus.akamaized.net/gfwlist +server=/foxrichmond.com/127.0.0.1#5335 +ipset=/foxrichmond.com/gfwlist +server=/collectionofbestporn.com/127.0.0.1#5335 +ipset=/collectionofbestporn.com/gfwlist +server=/yahoo.vg/127.0.0.1#5335 +ipset=/yahoo.vg/gfwlist +server=/avstar09.me/127.0.0.1#5335 +ipset=/avstar09.me/gfwlist +server=/miitomo.com/127.0.0.1#5335 +ipset=/miitomo.com/gfwlist +server=/aibaobei.me/127.0.0.1#5335 +ipset=/aibaobei.me/gfwlist +server=/hentaiero.net/127.0.0.1#5335 +ipset=/hentaiero.net/gfwlist +server=/carebay.com/127.0.0.1#5335 +ipset=/carebay.com/gfwlist +server=/speedtest.com.hk/127.0.0.1#5335 +ipset=/speedtest.com.hk/gfwlist +server=/loanbuilder.com/127.0.0.1#5335 +ipset=/loanbuilder.com/gfwlist +server=/bmw-motorrad.com.mx/127.0.0.1#5335 +ipset=/bmw-motorrad.com.mx/gfwlist +server=/javjack.com/127.0.0.1#5335 +ipset=/javjack.com/gfwlist +server=/linkshit.com/127.0.0.1#5335 +ipset=/linkshit.com/gfwlist +server=/do.co/127.0.0.1#5335 +ipset=/do.co/gfwlist +server=/ethereum.org/127.0.0.1#5335 +ipset=/ethereum.org/gfwlist +server=/whatsappbrand.com/127.0.0.1#5335 +ipset=/whatsappbrand.com/gfwlist +server=/nativeincolour.com.au/127.0.0.1#5335 +ipset=/nativeincolour.com.au/gfwlist +server=/nbcuniversal.com/127.0.0.1#5335 +ipset=/nbcuniversal.com/gfwlist +server=/pinterest.jp/127.0.0.1#5335 +ipset=/pinterest.jp/gfwlist +server=/ebayanunsios.net/127.0.0.1#5335 +ipset=/ebayanunsios.net/gfwlist +server=/trustcor.com/127.0.0.1#5335 +ipset=/trustcor.com/gfwlist +server=/dinotube.com/127.0.0.1#5335 +ipset=/dinotube.com/gfwlist +server=/freefacebookads.net/127.0.0.1#5335 +ipset=/freefacebookads.net/gfwlist +server=/icloud.se/127.0.0.1#5335 +ipset=/icloud.se/gfwlist +server=/surface.com/127.0.0.1#5335 +ipset=/surface.com/gfwlist +server=/applepaycash.net/127.0.0.1#5335 +ipset=/applepaycash.net/gfwlist +server=/freebs.com/127.0.0.1#5335 +ipset=/freebs.com/gfwlist +server=/line-scdn.net/127.0.0.1#5335 +ipset=/line-scdn.net/gfwlist +server=/bitbank.cc/127.0.0.1#5335 +ipset=/bitbank.cc/gfwlist +server=/gaybf.com/127.0.0.1#5335 +ipset=/gaybf.com/gfwlist +server=/rabbitscams.com/127.0.0.1#5335 +ipset=/rabbitscams.com/gfwlist +server=/telegram-porn.com/127.0.0.1#5335 +ipset=/telegram-porn.com/gfwlist +server=/hentai69.life/127.0.0.1#5335 +ipset=/hentai69.life/gfwlist +server=/nextmag.com.tw/127.0.0.1#5335 +ipset=/nextmag.com.tw/gfwlist +server=/xxxnxx.me/127.0.0.1#5335 +ipset=/xxxnxx.me/gfwlist +server=/splatoon2tournament.com/127.0.0.1#5335 +ipset=/splatoon2tournament.com/gfwlist +server=/tvbanywhere.com.sg/127.0.0.1#5335 +ipset=/tvbanywhere.com.sg/gfwlist +server=/paypa1.org/127.0.0.1#5335 +ipset=/paypa1.org/gfwlist +server=/alterauserforum.com/127.0.0.1#5335 +ipset=/alterauserforum.com/gfwlist +server=/battlefieldv.com/127.0.0.1#5335 +ipset=/battlefieldv.com/gfwlist +server=/livingyourambition.com/127.0.0.1#5335 +ipset=/livingyourambition.com/gfwlist +server=/zoho.eu/127.0.0.1#5335 +ipset=/zoho.eu/gfwlist +server=/drmgmggyi-mm.blogspot.com/127.0.0.1#5335 +ipset=/drmgmggyi-mm.blogspot.com/gfwlist +server=/mysimsracing.com/127.0.0.1#5335 +ipset=/mysimsracing.com/gfwlist +server=/gr-assets.com/127.0.0.1#5335 +ipset=/gr-assets.com/gfwlist +server=/ehtracker.org/127.0.0.1#5335 +ipset=/ehtracker.org/gfwlist +server=/hpdreamcolor.com/127.0.0.1#5335 +ipset=/hpdreamcolor.com/gfwlist +server=/googlecode.com/127.0.0.1#5335 +ipset=/googlecode.com/gfwlist +server=/huffingtonpost.de/127.0.0.1#5335 +ipset=/huffingtonpost.de/gfwlist +server=/travelex.com.om/127.0.0.1#5335 +ipset=/travelex.com.om/gfwlist +server=/disney.pl/127.0.0.1#5335 +ipset=/disney.pl/gfwlist +server=/xda-developers.com/127.0.0.1#5335 +ipset=/xda-developers.com/gfwlist +server=/nan-net.com/127.0.0.1#5335 +ipset=/nan-net.com/gfwlist +server=/hentaiz.co/127.0.0.1#5335 +ipset=/hentaiz.co/gfwlist +server=/termux.dev/127.0.0.1#5335 +ipset=/termux.dev/gfwlist +server=/pingxiangpuer.com/127.0.0.1#5335 +ipset=/pingxiangpuer.com/gfwlist +server=/amazonpay.in/127.0.0.1#5335 +ipset=/amazonpay.in/gfwlist +server=/truebeachporn.com/127.0.0.1#5335 +ipset=/truebeachporn.com/gfwlist +server=/ebayit.com/127.0.0.1#5335 +ipset=/ebayit.com/gfwlist +server=/volvotrucks.am/127.0.0.1#5335 +ipset=/volvotrucks.am/gfwlist +server=/youjizz.sex/127.0.0.1#5335 +ipset=/youjizz.sex/gfwlist +server=/tribler.org/127.0.0.1#5335 +ipset=/tribler.org/gfwlist +server=/bmw-grouparchives.com/127.0.0.1#5335 +ipset=/bmw-grouparchives.com/gfwlist +server=/zencoder.com/127.0.0.1#5335 +ipset=/zencoder.com/gfwlist +server=/freedomplatform.tv/127.0.0.1#5335 +ipset=/freedomplatform.tv/gfwlist +server=/ninemediaroom.com.au/127.0.0.1#5335 +ipset=/ninemediaroom.com.au/gfwlist +server=/dilcdn.com/127.0.0.1#5335 +ipset=/dilcdn.com/gfwlist +server=/bbgwatch.com/127.0.0.1#5335 +ipset=/bbgwatch.com/gfwlist +server=/billpoint.info/127.0.0.1#5335 +ipset=/billpoint.info/gfwlist +server=/blogspot.co.nz/127.0.0.1#5335 +ipset=/blogspot.co.nz/gfwlist +server=/enfamil.es/127.0.0.1#5335 +ipset=/enfamil.es/gfwlist +server=/aorus.com/127.0.0.1#5335 +ipset=/aorus.com/gfwlist +server=/ohentai.org/127.0.0.1#5335 +ipset=/ohentai.org/gfwlist +server=/ebay-25-assets.s3-us-west-1.amazonaws.com/127.0.0.1#5335 +ipset=/ebay-25-assets.s3-us-west-1.amazonaws.com/gfwlist +server=/mastercard.es/127.0.0.1#5335 +ipset=/mastercard.es/gfwlist +server=/login-paypal.info/127.0.0.1#5335 +ipset=/login-paypal.info/gfwlist +server=/nudistic.com/127.0.0.1#5335 +ipset=/nudistic.com/gfwlist +server=/huffingtonpost.com/127.0.0.1#5335 +ipset=/huffingtonpost.com/gfwlist +server=/fontshop.com/127.0.0.1#5335 +ipset=/fontshop.com/gfwlist +server=/cnivogue.com.au/127.0.0.1#5335 +ipset=/cnivogue.com.au/gfwlist +server=/turbogvideos.com/127.0.0.1#5335 +ipset=/turbogvideos.com/gfwlist +server=/elgaronline.com/127.0.0.1#5335 +ipset=/elgaronline.com/gfwlist +server=/ikea.com.sg/127.0.0.1#5335 +ipset=/ikea.com.sg/gfwlist +server=/erovizor.ru/127.0.0.1#5335 +ipset=/erovizor.ru/gfwlist +server=/141hongkong.com/127.0.0.1#5335 +ipset=/141hongkong.com/gfwlist +server=/adobess.com/127.0.0.1#5335 +ipset=/adobess.com/gfwlist +server=/mcdelivery.co.kr/127.0.0.1#5335 +ipset=/mcdelivery.co.kr/gfwlist +server=/leakedmeat.com/127.0.0.1#5335 +ipset=/leakedmeat.com/gfwlist +server=/facvebook.com/127.0.0.1#5335 +ipset=/facvebook.com/gfwlist +server=/bmw-authority-vehicles.com/127.0.0.1#5335 +ipset=/bmw-authority-vehicles.com/gfwlist +server=/amerikaninsesi.org/127.0.0.1#5335 +ipset=/amerikaninsesi.org/gfwlist +server=/connectionslearning.com/127.0.0.1#5335 +ipset=/connectionslearning.com/gfwlist +server=/satan18av.com/127.0.0.1#5335 +ipset=/satan18av.com/gfwlist +server=/rssing.com/127.0.0.1#5335 +ipset=/rssing.com/gfwlist +server=/ikea.pl/127.0.0.1#5335 +ipset=/ikea.pl/gfwlist +server=/mini-tahiti.com/127.0.0.1#5335 +ipset=/mini-tahiti.com/gfwlist +server=/gputechconf.com/127.0.0.1#5335 +ipset=/gputechconf.com/gfwlist +server=/shopbmwusa.com/127.0.0.1#5335 +ipset=/shopbmwusa.com/gfwlist +server=/wawatv.net/127.0.0.1#5335 +ipset=/wawatv.net/gfwlist +server=/towerauction.com/127.0.0.1#5335 +ipset=/towerauction.com/gfwlist +server=/hdouban2.com/127.0.0.1#5335 +ipset=/hdouban2.com/gfwlist +server=/fury.help/127.0.0.1#5335 +ipset=/fury.help/gfwlist +server=/azureiotcentral.com/127.0.0.1#5335 +ipset=/azureiotcentral.com/gfwlist +server=/spektral.cc/127.0.0.1#5335 +ipset=/spektral.cc/gfwlist +server=/workplace.com/127.0.0.1#5335 +ipset=/workplace.com/gfwlist +server=/canon.com.by/127.0.0.1#5335 +ipset=/canon.com.by/gfwlist +server=/manhunt.net/127.0.0.1#5335 +ipset=/manhunt.net/gfwlist +server=/google.ps/127.0.0.1#5335 +ipset=/google.ps/gfwlist +server=/bootyliciousmag.com/127.0.0.1#5335 +ipset=/bootyliciousmag.com/gfwlist +server=/xxxtubeasian.net/127.0.0.1#5335 +ipset=/xxxtubeasian.net/gfwlist +server=/enfagrow.com.ph/127.0.0.1#5335 +ipset=/enfagrow.com.ph/gfwlist +server=/akamai-platform.net/127.0.0.1#5335 +ipset=/akamai-platform.net/gfwlist +server=/youtube.com.bo/127.0.0.1#5335 +ipset=/youtube.com.bo/gfwlist +server=/vpro.com/127.0.0.1#5335 +ipset=/vpro.com/gfwlist +server=/intel.ae/127.0.0.1#5335 +ipset=/intel.ae/gfwlist +server=/itsfuck.com/127.0.0.1#5335 +ipset=/itsfuck.com/gfwlist +server=/bumpshare.com/127.0.0.1#5335 +ipset=/bumpshare.com/gfwlist +server=/tukif.com/127.0.0.1#5335 +ipset=/tukif.com/gfwlist +server=/sony.com.ar/127.0.0.1#5335 +ipset=/sony.com.ar/gfwlist +server=/fi11tv1.com/127.0.0.1#5335 +ipset=/fi11tv1.com/gfwlist +server=/pinterest.pt/127.0.0.1#5335 +ipset=/pinterest.pt/gfwlist +server=/scholarpedia.org/127.0.0.1#5335 +ipset=/scholarpedia.org/gfwlist +server=/visa.co.za/127.0.0.1#5335 +ipset=/visa.co.za/gfwlist +server=/censorship.ai/127.0.0.1#5335 +ipset=/censorship.ai/gfwlist +server=/futureshop.ca/127.0.0.1#5335 +ipset=/futureshop.ca/gfwlist +server=/srebrenica360.com/127.0.0.1#5335 +ipset=/srebrenica360.com/gfwlist +server=/visaluxuryhotels.com/127.0.0.1#5335 +ipset=/visaluxuryhotels.com/gfwlist +server=/nudekenya.com/127.0.0.1#5335 +ipset=/nudekenya.com/gfwlist +server=/hpsoftware.com/127.0.0.1#5335 +ipset=/hpsoftware.com/gfwlist +server=/blogspot.com.au/127.0.0.1#5335 +ipset=/blogspot.com.au/gfwlist +server=/minisothailand.com/127.0.0.1#5335 +ipset=/minisothailand.com/gfwlist +server=/w.wiki/127.0.0.1#5335 +ipset=/w.wiki/gfwlist +server=/localbitcoinschain.com/127.0.0.1#5335 +ipset=/localbitcoinschain.com/gfwlist +server=/gbluebooks.blogspot.com/127.0.0.1#5335 +ipset=/gbluebooks.blogspot.com/gfwlist +server=/nudematurewomenpics.com/127.0.0.1#5335 +ipset=/nudematurewomenpics.com/gfwlist +server=/newisiknowledge.com/127.0.0.1#5335 +ipset=/newisiknowledge.com/gfwlist +server=/edninfo.com/127.0.0.1#5335 +ipset=/edninfo.com/gfwlist +server=/vaginacontest.com/127.0.0.1#5335 +ipset=/vaginacontest.com/gfwlist +server=/intheknow.com.au/127.0.0.1#5335 +ipset=/intheknow.com.au/gfwlist +server=/maddenchampionship.com/127.0.0.1#5335 +ipset=/maddenchampionship.com/gfwlist +server=/beatsblackfridaydeals.net/127.0.0.1#5335 +ipset=/beatsblackfridaydeals.net/gfwlist +server=/starbucksforlife.com/127.0.0.1#5335 +ipset=/starbucksforlife.com/gfwlist +server=/doclercdn.com/127.0.0.1#5335 +ipset=/doclercdn.com/gfwlist +server=/vanish.no/127.0.0.1#5335 +ipset=/vanish.no/gfwlist +server=/google.co.bw/127.0.0.1#5335 +ipset=/google.co.bw/gfwlist +server=/microsoftreactor.net/127.0.0.1#5335 +ipset=/microsoftreactor.net/gfwlist +server=/themoviedb.org/127.0.0.1#5335 +ipset=/themoviedb.org/gfwlist +server=/volvosaatio.fi/127.0.0.1#5335 +ipset=/volvosaatio.fi/gfwlist +server=/dettol.co.ke/127.0.0.1#5335 +ipset=/dettol.co.ke/gfwlist +server=/akamai-regression.net/127.0.0.1#5335 +ipset=/akamai-regression.net/gfwlist +server=/hardsextube.com/127.0.0.1#5335 +ipset=/hardsextube.com/gfwlist +server=/xnxx2.it/127.0.0.1#5335 +ipset=/xnxx2.it/gfwlist +server=/thomsonreuters.co.uk/127.0.0.1#5335 +ipset=/thomsonreuters.co.uk/gfwlist +server=/entermediadb.org/127.0.0.1#5335 +ipset=/entermediadb.org/gfwlist +server=/gettyimages.nl/127.0.0.1#5335 +ipset=/gettyimages.nl/gfwlist +server=/shadowsocks.org/127.0.0.1#5335 +ipset=/shadowsocks.org/gfwlist +server=/deepmind.com/127.0.0.1#5335 +ipset=/deepmind.com/gfwlist +server=/yandex.tj/127.0.0.1#5335 +ipset=/yandex.tj/gfwlist +server=/steezylist.com/127.0.0.1#5335 +ipset=/steezylist.com/gfwlist +server=/iamakamai.com/127.0.0.1#5335 +ipset=/iamakamai.com/gfwlist +server=/directvonline.com/127.0.0.1#5335 +ipset=/directvonline.com/gfwlist +server=/faceboobok.com/127.0.0.1#5335 +ipset=/faceboobok.com/gfwlist +server=/blogspot.co.ke/127.0.0.1#5335 +ipset=/blogspot.co.ke/gfwlist +server=/linemobile.com/127.0.0.1#5335 +ipset=/linemobile.com/gfwlist +server=/fulanax.com/127.0.0.1#5335 +ipset=/fulanax.com/gfwlist +server=/femjoy.com/127.0.0.1#5335 +ipset=/femjoy.com/gfwlist +server=/azure-mobile.net/127.0.0.1#5335 +ipset=/azure-mobile.net/gfwlist +server=/bestbuyus.com/127.0.0.1#5335 +ipset=/bestbuyus.com/gfwlist +server=/oppainorakuen.com/127.0.0.1#5335 +ipset=/oppainorakuen.com/gfwlist +server=/cheapbeatsbydrestudioutlet.com/127.0.0.1#5335 +ipset=/cheapbeatsbydrestudioutlet.com/gfwlist +server=/softbankmobile.net/127.0.0.1#5335 +ipset=/softbankmobile.net/gfwlist +server=/bloombergapps.com/127.0.0.1#5335 +ipset=/bloombergapps.com/gfwlist +server=/manototv.com/127.0.0.1#5335 +ipset=/manototv.com/gfwlist +server=/allfinegirls.com/127.0.0.1#5335 +ipset=/allfinegirls.com/gfwlist +server=/sing68.com/127.0.0.1#5335 +ipset=/sing68.com/gfwlist +server=/zavat.pw/127.0.0.1#5335 +ipset=/zavat.pw/gfwlist +server=/fanatical.com/127.0.0.1#5335 +ipset=/fanatical.com/gfwlist +server=/billpoint.tv/127.0.0.1#5335 +ipset=/billpoint.tv/gfwlist +server=/hotzxgirl.com/127.0.0.1#5335 +ipset=/hotzxgirl.com/gfwlist +server=/onlineteenhub.com/127.0.0.1#5335 +ipset=/onlineteenhub.com/gfwlist +server=/btt804.com/127.0.0.1#5335 +ipset=/btt804.com/gfwlist +server=/gumtree.sg/127.0.0.1#5335 +ipset=/gumtree.sg/gfwlist +server=/volvogroup.kr/127.0.0.1#5335 +ipset=/volvogroup.kr/gfwlist +server=/custombeatsny.com/127.0.0.1#5335 +ipset=/custombeatsny.com/gfwlist +server=/visaitalia.com/127.0.0.1#5335 +ipset=/visaitalia.com/gfwlist +server=/beatsbydre-chen.com/127.0.0.1#5335 +ipset=/beatsbydre-chen.com/gfwlist +server=/monstercasquebeatspascher.net/127.0.0.1#5335 +ipset=/monstercasquebeatspascher.net/gfwlist +server=/microsoftiotcentral.com/127.0.0.1#5335 +ipset=/microsoftiotcentral.com/gfwlist +server=/hotstunners.com/127.0.0.1#5335 +ipset=/hotstunners.com/gfwlist +server=/theman.in/127.0.0.1#5335 +ipset=/theman.in/gfwlist +server=/visa.com.hn/127.0.0.1#5335 +ipset=/visa.com.hn/gfwlist +server=/fireside.fm/127.0.0.1#5335 +ipset=/fireside.fm/gfwlist +server=/sandisk.com/127.0.0.1#5335 +ipset=/sandisk.com/gfwlist +server=/foxest.com/127.0.0.1#5335 +ipset=/foxest.com/gfwlist +server=/mature-porn-flix.com/127.0.0.1#5335 +ipset=/mature-porn-flix.com/gfwlist +server=/verilylifesciences.com/127.0.0.1#5335 +ipset=/verilylifesciences.com/gfwlist +server=/monstersbeatbydres.com/127.0.0.1#5335 +ipset=/monstersbeatbydres.com/gfwlist +server=/drdrebeatsdesale.com/127.0.0.1#5335 +ipset=/drdrebeatsdesale.com/gfwlist +server=/momsyoungboys.net/127.0.0.1#5335 +ipset=/momsyoungboys.net/gfwlist +server=/niketraining.com/127.0.0.1#5335 +ipset=/niketraining.com/gfwlist +server=/ebay.co.za/127.0.0.1#5335 +ipset=/ebay.co.za/gfwlist +server=/minilaval.ca/127.0.0.1#5335 +ipset=/minilaval.ca/gfwlist +server=/amateurmommymovies.com/127.0.0.1#5335 +ipset=/amateurmommymovies.com/gfwlist +server=/scholar.google.cz/127.0.0.1#5335 +ipset=/scholar.google.cz/gfwlist +server=/hcomicbook.com/127.0.0.1#5335 +ipset=/hcomicbook.com/gfwlist +server=/hentaivn.de/127.0.0.1#5335 +ipset=/hentaivn.de/gfwlist +server=/moeimg.net/127.0.0.1#5335 +ipset=/moeimg.net/gfwlist +server=/observable.net/127.0.0.1#5335 +ipset=/observable.net/gfwlist +server=/porn34.me/127.0.0.1#5335 +ipset=/porn34.me/gfwlist +server=/oldje.com/127.0.0.1#5335 +ipset=/oldje.com/gfwlist +server=/xiaoyaoge.xyz/127.0.0.1#5335 +ipset=/xiaoyaoge.xyz/gfwlist +server=/verisign.com/127.0.0.1#5335 +ipset=/verisign.com/gfwlist +server=/ebayla.org/127.0.0.1#5335 +ipset=/ebayla.org/gfwlist +server=/ntdtv.jp/127.0.0.1#5335 +ipset=/ntdtv.jp/gfwlist +server=/google.bs/127.0.0.1#5335 +ipset=/google.bs/gfwlist +server=/avgod.club/127.0.0.1#5335 +ipset=/avgod.club/gfwlist +server=/z5.com/127.0.0.1#5335 +ipset=/z5.com/gfwlist +server=/ikea.dk/127.0.0.1#5335 +ipset=/ikea.dk/gfwlist +server=/sony.co.nz/127.0.0.1#5335 +ipset=/sony.co.nz/gfwlist +server=/cnnpolitics.com/127.0.0.1#5335 +ipset=/cnnpolitics.com/gfwlist +server=/google.com.na/127.0.0.1#5335 +ipset=/google.com.na/gfwlist +server=/zoo-tube8.com/127.0.0.1#5335 +ipset=/zoo-tube8.com/gfwlist +server=/book4you.org/127.0.0.1#5335 +ipset=/book4you.org/gfwlist +server=/foxrad.io/127.0.0.1#5335 +ipset=/foxrad.io/gfwlist +server=/teslazta.net/127.0.0.1#5335 +ipset=/teslazta.net/gfwlist +server=/books.com.tw/127.0.0.1#5335 +ipset=/books.com.tw/gfwlist +server=/bmwworld.net/127.0.0.1#5335 +ipset=/bmwworld.net/gfwlist +server=/googleadapis.com/127.0.0.1#5335 +ipset=/googleadapis.com/gfwlist +server=/alt5-mtalk.google.com/127.0.0.1#5335 +ipset=/alt5-mtalk.google.com/gfwlist +server=/facebookvacation.com/127.0.0.1#5335 +ipset=/facebookvacation.com/gfwlist +server=/mastercard.pl/127.0.0.1#5335 +ipset=/mastercard.pl/gfwlist +server=/bekijkporno.nl/127.0.0.1#5335 +ipset=/bekijkporno.nl/gfwlist +server=/citas-para-mayoresde50.ec/127.0.0.1#5335 +ipset=/citas-para-mayoresde50.ec/gfwlist +server=/codivorexxx.com/127.0.0.1#5335 +ipset=/codivorexxx.com/gfwlist +server=/h0930.com/127.0.0.1#5335 +ipset=/h0930.com/gfwlist +server=/yandex.fi/127.0.0.1#5335 +ipset=/yandex.fi/gfwlist +server=/nerdnudes.com/127.0.0.1#5335 +ipset=/nerdnudes.com/gfwlist +server=/worldsfastestgamer.net/127.0.0.1#5335 +ipset=/worldsfastestgamer.net/gfwlist +server=/postimages.org/127.0.0.1#5335 +ipset=/postimages.org/gfwlist +server=/jable.tv/127.0.0.1#5335 +ipset=/jable.tv/gfwlist +server=/netflixdnstest1.com/127.0.0.1#5335 +ipset=/netflixdnstest1.com/gfwlist +server=/bingworld.com/127.0.0.1#5335 +ipset=/bingworld.com/gfwlist +server=/pornhub-deutsch.net/127.0.0.1#5335 +ipset=/pornhub-deutsch.net/gfwlist +server=/pokemonletsgopikachu.com/127.0.0.1#5335 +ipset=/pokemonletsgopikachu.com/gfwlist +server=/antarvasnax.com/127.0.0.1#5335 +ipset=/antarvasnax.com/gfwlist +server=/instagmania.com/127.0.0.1#5335 +ipset=/instagmania.com/gfwlist +server=/stlouisbmw.net/127.0.0.1#5335 +ipset=/stlouisbmw.net/gfwlist +server=/bokepvidz.com/127.0.0.1#5335 +ipset=/bokepvidz.com/gfwlist +server=/asproex.com/127.0.0.1#5335 +ipset=/asproex.com/gfwlist +server=/bandcamp.com/127.0.0.1#5335 +ipset=/bandcamp.com/gfwlist +server=/nudeteen.org/127.0.0.1#5335 +ipset=/nudeteen.org/gfwlist +server=/google.com.cy/127.0.0.1#5335 +ipset=/google.com.cy/gfwlist +server=/veet.com.pk/127.0.0.1#5335 +ipset=/veet.com.pk/gfwlist +server=/bmw-connecteddrive.co.uk/127.0.0.1#5335 +ipset=/bmw-connecteddrive.co.uk/gfwlist +server=/tvbanywhere.com/127.0.0.1#5335 +ipset=/tvbanywhere.com/gfwlist +server=/pashtovoa.com/127.0.0.1#5335 +ipset=/pashtovoa.com/gfwlist +server=/swisssigner.com/127.0.0.1#5335 +ipset=/swisssigner.com/gfwlist +server=/applepremiumreseller.com.au/127.0.0.1#5335 +ipset=/applepremiumreseller.com.au/gfwlist +server=/myfavoritearcade.com/127.0.0.1#5335 +ipset=/myfavoritearcade.com/gfwlist +server=/vaultify.info/127.0.0.1#5335 +ipset=/vaultify.info/gfwlist +server=/6asianporn.com/127.0.0.1#5335 +ipset=/6asianporn.com/gfwlist +server=/ieee-region6.org/127.0.0.1#5335 +ipset=/ieee-region6.org/gfwlist +server=/zee5.com/127.0.0.1#5335 +ipset=/zee5.com/gfwlist +server=/japanknowledge.com/127.0.0.1#5335 +ipset=/japanknowledge.com/gfwlist +server=/facebooik.org/127.0.0.1#5335 +ipset=/facebooik.org/gfwlist +server=/javtube.net/127.0.0.1#5335 +ipset=/javtube.net/gfwlist +server=/iphone.host/127.0.0.1#5335 +ipset=/iphone.host/gfwlist +server=/foxnews.cc/127.0.0.1#5335 +ipset=/foxnews.cc/gfwlist +server=/youtube.co/127.0.0.1#5335 +ipset=/youtube.co/gfwlist +server=/cbsi.live.ott.irdeto.com/127.0.0.1#5335 +ipset=/cbsi.live.ott.irdeto.com/gfwlist +server=/kkfcc03.com/127.0.0.1#5335 +ipset=/kkfcc03.com/gfwlist +server=/shakethesnake.com/127.0.0.1#5335 +ipset=/shakethesnake.com/gfwlist +server=/redwap.me/127.0.0.1#5335 +ipset=/redwap.me/gfwlist +server=/tiava1.com/127.0.0.1#5335 +ipset=/tiava1.com/gfwlist +server=/skokka.com/127.0.0.1#5335 +ipset=/skokka.com/gfwlist +server=/volvotruckcenter.fi/127.0.0.1#5335 +ipset=/volvotruckcenter.fi/gfwlist +server=/pearsoneducationbooks.com/127.0.0.1#5335 +ipset=/pearsoneducationbooks.com/gfwlist +server=/hpuniversity.info/127.0.0.1#5335 +ipset=/hpuniversity.info/gfwlist +server=/xboyvids.com/127.0.0.1#5335 +ipset=/xboyvids.com/gfwlist +server=/dcard.tw/127.0.0.1#5335 +ipset=/dcard.tw/gfwlist +server=/blogspot.co.za/127.0.0.1#5335 +ipset=/blogspot.co.za/gfwlist +server=/battlefield5.com/127.0.0.1#5335 +ipset=/battlefield5.com/gfwlist +server=/xxxaporn.com/127.0.0.1#5335 +ipset=/xxxaporn.com/gfwlist +server=/youtube.soy/127.0.0.1#5335 +ipset=/youtube.soy/gfwlist +server=/itsoc.org/127.0.0.1#5335 +ipset=/itsoc.org/gfwlist +server=/craigslist.org/127.0.0.1#5335 +ipset=/craigslist.org/gfwlist +server=/sahabatsetiasmartone.com/127.0.0.1#5335 +ipset=/sahabatsetiasmartone.com/gfwlist +server=/applepay.com.tw/127.0.0.1#5335 +ipset=/applepay.com.tw/gfwlist +server=/asianxxxjoy.com/127.0.0.1#5335 +ipset=/asianxxxjoy.com/gfwlist +server=/reneerossvideos.com/127.0.0.1#5335 +ipset=/reneerossvideos.com/gfwlist +server=/directtv-deals.tv/127.0.0.1#5335 +ipset=/directtv-deals.tv/gfwlist +server=/genshinimpact.com/127.0.0.1#5335 +ipset=/genshinimpact.com/gfwlist +server=/porn2012.com/127.0.0.1#5335 +ipset=/porn2012.com/gfwlist +server=/facewook.com/127.0.0.1#5335 +ipset=/facewook.com/gfwlist +server=/fullxxxmovies.net/127.0.0.1#5335 +ipset=/fullxxxmovies.net/gfwlist +server=/directvdeals.com/127.0.0.1#5335 +ipset=/directvdeals.com/gfwlist +server=/epochtimes.de/127.0.0.1#5335 +ipset=/epochtimes.de/gfwlist +server=/manhuabika.com/127.0.0.1#5335 +ipset=/manhuabika.com/gfwlist +server=/paypal-database.com/127.0.0.1#5335 +ipset=/paypal-database.com/gfwlist +server=/pinterest.com.bo/127.0.0.1#5335 +ipset=/pinterest.com.bo/gfwlist +server=/paypalme.com/127.0.0.1#5335 +ipset=/paypalme.com/gfwlist +server=/news.co.uk/127.0.0.1#5335 +ipset=/news.co.uk/gfwlist +server=/o365weve-ppe.com/127.0.0.1#5335 +ipset=/o365weve-ppe.com/gfwlist +server=/cosmosdb.net/127.0.0.1#5335 +ipset=/cosmosdb.net/gfwlist +server=/beatsbydre-us.com/127.0.0.1#5335 +ipset=/beatsbydre-us.com/gfwlist +server=/wii-u.com/127.0.0.1#5335 +ipset=/wii-u.com/gfwlist +server=/bmw-motorrad.com/127.0.0.1#5335 +ipset=/bmw-motorrad.com/gfwlist +server=/12diasderegalosdeitunes.gt/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.gt/gfwlist +server=/faphdporn.com/127.0.0.1#5335 +ipset=/faphdporn.com/gfwlist +server=/stackpath.com/127.0.0.1#5335 +ipset=/stackpath.com/gfwlist +server=/theaffairs.com/127.0.0.1#5335 +ipset=/theaffairs.com/gfwlist +server=/encuentroscasualesoecuador.com/127.0.0.1#5335 +ipset=/encuentroscasualesoecuador.com/gfwlist +server=/bmw.co.jp/127.0.0.1#5335 +ipset=/bmw.co.jp/gfwlist +server=/instagtram.com/127.0.0.1#5335 +ipset=/instagtram.com/gfwlist +server=/airwick.ro/127.0.0.1#5335 +ipset=/airwick.ro/gfwlist +server=/javtasty.com/127.0.0.1#5335 +ipset=/javtasty.com/gfwlist +server=/vimeocdn.com/127.0.0.1#5335 +ipset=/vimeocdn.com/gfwlist +server=/bluehatnights.com/127.0.0.1#5335 +ipset=/bluehatnights.com/gfwlist +server=/myvodafone.com.au/127.0.0.1#5335 +ipset=/myvodafone.com.au/gfwlist +server=/piwheels.org/127.0.0.1#5335 +ipset=/piwheels.org/gfwlist +server=/monsterbeatsbydrefactory.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrefactory.com/gfwlist +server=/apibay.org/127.0.0.1#5335 +ipset=/apibay.org/gfwlist +server=/ehgt.org/127.0.0.1#5335 +ipset=/ehgt.org/gfwlist +server=/disneymagicmoments.it/127.0.0.1#5335 +ipset=/disneymagicmoments.it/gfwlist +server=/doujinnomori.com/127.0.0.1#5335 +ipset=/doujinnomori.com/gfwlist +server=/visa.com.ru/127.0.0.1#5335 +ipset=/visa.com.ru/gfwlist +server=/goldnikeclub.com/127.0.0.1#5335 +ipset=/goldnikeclub.com/gfwlist +server=/6-ar.com/127.0.0.1#5335 +ipset=/6-ar.com/gfwlist +server=/ebayvietnam.net/127.0.0.1#5335 +ipset=/ebayvietnam.net/gfwlist +server=/digitalid.ch/127.0.0.1#5335 +ipset=/digitalid.ch/gfwlist +server=/akamai-thailand.com/127.0.0.1#5335 +ipset=/akamai-thailand.com/gfwlist +server=/xhamster.xxx/127.0.0.1#5335 +ipset=/xhamster.xxx/gfwlist +server=/bestbuy.ca/127.0.0.1#5335 +ipset=/bestbuy.ca/gfwlist +server=/cherry-tale.com/127.0.0.1#5335 +ipset=/cherry-tale.com/gfwlist +server=/disney.in/127.0.0.1#5335 +ipset=/disney.in/gfwlist +server=/canon.fr/127.0.0.1#5335 +ipset=/canon.fr/gfwlist +server=/youtube.si/127.0.0.1#5335 +ipset=/youtube.si/gfwlist +server=/faproulette.online/127.0.0.1#5335 +ipset=/faproulette.online/gfwlist +server=/go-disneyworldgo.com/127.0.0.1#5335 +ipset=/go-disneyworldgo.com/gfwlist +server=/directvinternet.com/127.0.0.1#5335 +ipset=/directvinternet.com/gfwlist +server=/facebokok.com/127.0.0.1#5335 +ipset=/facebokok.com/gfwlist +server=/ikea.cz/127.0.0.1#5335 +ipset=/ikea.cz/gfwlist +server=/sundanceignite2016.com/127.0.0.1#5335 +ipset=/sundanceignite2016.com/gfwlist +server=/gemfury.com/127.0.0.1#5335 +ipset=/gemfury.com/gfwlist +server=/bmw-connecteddrive.sg/127.0.0.1#5335 +ipset=/bmw-connecteddrive.sg/gfwlist +server=/geforce.com/127.0.0.1#5335 +ipset=/geforce.com/gfwlist +server=/dtv2009offers.com/127.0.0.1#5335 +ipset=/dtv2009offers.com/gfwlist +server=/nexcat.com/127.0.0.1#5335 +ipset=/nexcat.com/gfwlist +server=/nowjav.com/127.0.0.1#5335 +ipset=/nowjav.com/gfwlist +server=/bridgestonerapiddelivery.com/127.0.0.1#5335 +ipset=/bridgestonerapiddelivery.com/gfwlist +server=/wal-mart.com/127.0.0.1#5335 +ipset=/wal-mart.com/gfwlist +server=/c-spanvideo.org/127.0.0.1#5335 +ipset=/c-spanvideo.org/gfwlist +server=/99thz.cc/127.0.0.1#5335 +ipset=/99thz.cc/gfwlist +server=/bmw.com.pa/127.0.0.1#5335 +ipset=/bmw.com.pa/gfwlist +server=/singtaola.com/127.0.0.1#5335 +ipset=/singtaola.com/gfwlist +server=/128100.xyz/127.0.0.1#5335 +ipset=/128100.xyz/gfwlist +server=/empornium.site/127.0.0.1#5335 +ipset=/empornium.site/gfwlist +server=/novinhabucetuda.com/127.0.0.1#5335 +ipset=/novinhabucetuda.com/gfwlist +server=/wwwdecide.com/127.0.0.1#5335 +ipset=/wwwdecide.com/gfwlist +server=/apornvideo.com/127.0.0.1#5335 +ipset=/apornvideo.com/gfwlist +server=/uun86.com/127.0.0.1#5335 +ipset=/uun86.com/gfwlist +server=/nflxsearch.net/127.0.0.1#5335 +ipset=/nflxsearch.net/gfwlist +server=/esp32.com/127.0.0.1#5335 +ipset=/esp32.com/gfwlist +server=/hoyoverse.com/127.0.0.1#5335 +ipset=/hoyoverse.com/gfwlist +server=/pornluxme.com/127.0.0.1#5335 +ipset=/pornluxme.com/gfwlist +server=/vimeoondemand.com/127.0.0.1#5335 +ipset=/vimeoondemand.com/gfwlist +server=/binancezh.pro/127.0.0.1#5335 +ipset=/binancezh.pro/gfwlist +server=/cherryasia.com/127.0.0.1#5335 +ipset=/cherryasia.com/gfwlist +server=/facebookportal.com/127.0.0.1#5335 +ipset=/facebookportal.com/gfwlist +server=/ecapi-pchome.cdn.hinet.net/127.0.0.1#5335 +ipset=/ecapi-pchome.cdn.hinet.net/gfwlist +server=/pornotime.net/127.0.0.1#5335 +ipset=/pornotime.net/gfwlist +server=/playcover.workers.dev/127.0.0.1#5335 +ipset=/playcover.workers.dev/gfwlist +server=/eromanga-cafe.com/127.0.0.1#5335 +ipset=/eromanga-cafe.com/gfwlist +server=/monsterbydrebeat.com/127.0.0.1#5335 +ipset=/monsterbydrebeat.com/gfwlist +server=/leaguehighschool.com/127.0.0.1#5335 +ipset=/leaguehighschool.com/gfwlist +server=/dettol.pt/127.0.0.1#5335 +ipset=/dettol.pt/gfwlist +server=/veet.com/127.0.0.1#5335 +ipset=/veet.com/gfwlist +server=/explorespanking.com/127.0.0.1#5335 +ipset=/explorespanking.com/gfwlist +server=/spore.com/127.0.0.1#5335 +ipset=/spore.com/gfwlist +server=/dot.net/127.0.0.1#5335 +ipset=/dot.net/gfwlist +server=/viacomcbs.com/127.0.0.1#5335 +ipset=/viacomcbs.com/gfwlist +server=/youtubego.co.in/127.0.0.1#5335 +ipset=/youtubego.co.in/gfwlist +server=/mini-connected.ch/127.0.0.1#5335 +ipset=/mini-connected.ch/gfwlist +server=/strepsils.ru/127.0.0.1#5335 +ipset=/strepsils.ru/gfwlist +server=/kk.stream/127.0.0.1#5335 +ipset=/kk.stream/gfwlist +server=/designeriphonescases.com/127.0.0.1#5335 +ipset=/designeriphonescases.com/gfwlist +server=/porn-star.com/127.0.0.1#5335 +ipset=/porn-star.com/gfwlist +server=/onlinexxxgames.com/127.0.0.1#5335 +ipset=/onlinexxxgames.com/gfwlist +server=/shotwithgeforce.com/127.0.0.1#5335 +ipset=/shotwithgeforce.com/gfwlist +server=/mcdonalds.com.hk/127.0.0.1#5335 +ipset=/mcdonalds.com.hk/gfwlist +server=/heyzo.com/127.0.0.1#5335 +ipset=/heyzo.com/gfwlist +server=/hpcodewarsbcn.com/127.0.0.1#5335 +ipset=/hpcodewarsbcn.com/gfwlist +server=/dmm-extension.com/127.0.0.1#5335 +ipset=/dmm-extension.com/gfwlist +server=/windowsupdate.com/127.0.0.1#5335 +ipset=/windowsupdate.com/gfwlist +server=/akamaiphillipines.net/127.0.0.1#5335 +ipset=/akamaiphillipines.net/gfwlist +server=/visa-atm.com/127.0.0.1#5335 +ipset=/visa-atm.com/gfwlist +server=/pornbozz.com/127.0.0.1#5335 +ipset=/pornbozz.com/gfwlist +server=/linegame.jp/127.0.0.1#5335 +ipset=/linegame.jp/gfwlist +server=/xn--gogl-1nd42e.com/127.0.0.1#5335 +ipset=/xn--gogl-1nd42e.com/gfwlist +server=/bmw.com.mo/127.0.0.1#5335 +ipset=/bmw.com.mo/gfwlist +server=/bdawnvr.xyz/127.0.0.1#5335 +ipset=/bdawnvr.xyz/gfwlist +server=/bloomberglaw.com/127.0.0.1#5335 +ipset=/bloomberglaw.com/gfwlist +server=/qualcomm.com/127.0.0.1#5335 +ipset=/qualcomm.com/gfwlist +server=/scoreuniverse.com/127.0.0.1#5335 +ipset=/scoreuniverse.com/gfwlist +server=/czechmassage.com/127.0.0.1#5335 +ipset=/czechmassage.com/gfwlist +server=/attexperts.com/127.0.0.1#5335 +ipset=/attexperts.com/gfwlist +server=/soundofhope.org/127.0.0.1#5335 +ipset=/soundofhope.org/gfwlist +server=/swissign.com/127.0.0.1#5335 +ipset=/swissign.com/gfwlist +server=/dndbeyond.com/127.0.0.1#5335 +ipset=/dndbeyond.com/gfwlist +server=/thawte.de/127.0.0.1#5335 +ipset=/thawte.de/gfwlist +server=/picpost.com/127.0.0.1#5335 +ipset=/picpost.com/gfwlist +server=/animalzoosex.me/127.0.0.1#5335 +ipset=/animalzoosex.me/gfwlist +server=/motionpictureser.com/127.0.0.1#5335 +ipset=/motionpictureser.com/gfwlist +server=/shopee.sg/127.0.0.1#5335 +ipset=/shopee.sg/gfwlist +server=/bloombergspace.com/127.0.0.1#5335 +ipset=/bloombergspace.com/gfwlist +server=/lghvacstory.com/127.0.0.1#5335 +ipset=/lghvacstory.com/gfwlist +server=/instagram-press.com/127.0.0.1#5335 +ipset=/instagram-press.com/gfwlist +server=/theepochtimessubscribe.com/127.0.0.1#5335 +ipset=/theepochtimessubscribe.com/gfwlist +server=/pleasurebabe.com/127.0.0.1#5335 +ipset=/pleasurebabe.com/gfwlist +server=/tube2012.com/127.0.0.1#5335 +ipset=/tube2012.com/gfwlist +server=/unlocklimitlesslearning.com/127.0.0.1#5335 +ipset=/unlocklimitlesslearning.com/gfwlist +server=/anm.co.uk/127.0.0.1#5335 +ipset=/anm.co.uk/gfwlist +server=/newsensations.com/127.0.0.1#5335 +ipset=/newsensations.com/gfwlist +server=/hulugo.com/127.0.0.1#5335 +ipset=/hulugo.com/gfwlist +server=/nubileset.com/127.0.0.1#5335 +ipset=/nubileset.com/gfwlist +server=/pornachi.com/127.0.0.1#5335 +ipset=/pornachi.com/gfwlist +server=/verhentai.tv/127.0.0.1#5335 +ipset=/verhentai.tv/gfwlist +server=/shoptraivip.com/127.0.0.1#5335 +ipset=/shoptraivip.com/gfwlist +server=/anibooru.com/127.0.0.1#5335 +ipset=/anibooru.com/gfwlist +server=/scholar.google.com.sv/127.0.0.1#5335 +ipset=/scholar.google.com.sv/gfwlist +server=/archlinux.org/127.0.0.1#5335 +ipset=/archlinux.org/gfwlist +server=/every1dns.net/127.0.0.1#5335 +ipset=/every1dns.net/gfwlist +server=/zoozhamster.com/127.0.0.1#5335 +ipset=/zoozhamster.com/gfwlist +server=/googel.com/127.0.0.1#5335 +ipset=/googel.com/gfwlist +server=/binance.me/127.0.0.1#5335 +ipset=/binance.me/gfwlist +server=/pre-bmwgroup.jobs/127.0.0.1#5335 +ipset=/pre-bmwgroup.jobs/gfwlist +server=/freeuseporn.com/127.0.0.1#5335 +ipset=/freeuseporn.com/gfwlist +server=/nbabot.net/127.0.0.1#5335 +ipset=/nbabot.net/gfwlist +server=/hentaifromhell.org/127.0.0.1#5335 +ipset=/hentaifromhell.org/gfwlist +server=/aboutporno.net/127.0.0.1#5335 +ipset=/aboutporno.net/gfwlist +server=/sourcingforebay.tv/127.0.0.1#5335 +ipset=/sourcingforebay.tv/gfwlist +server=/hketgroup.com/127.0.0.1#5335 +ipset=/hketgroup.com/gfwlist +server=/91qk41rf.com/127.0.0.1#5335 +ipset=/91qk41rf.com/gfwlist +server=/nintendo.at/127.0.0.1#5335 +ipset=/nintendo.at/gfwlist +server=/sldolls.com/127.0.0.1#5335 +ipset=/sldolls.com/gfwlist +server=/speeddreamride.com/127.0.0.1#5335 +ipset=/speeddreamride.com/gfwlist +server=/disney.my/127.0.0.1#5335 +ipset=/disney.my/gfwlist +server=/hdouga.com/127.0.0.1#5335 +ipset=/hdouga.com/gfwlist +server=/instagranm.com/127.0.0.1#5335 +ipset=/instagranm.com/gfwlist +server=/hellven.net/127.0.0.1#5335 +ipset=/hellven.net/gfwlist +server=/bridgestone.co.th/127.0.0.1#5335 +ipset=/bridgestone.co.th/gfwlist +server=/amazonworkdocs.com/127.0.0.1#5335 +ipset=/amazonworkdocs.com/gfwlist +server=/ghettotube.com/127.0.0.1#5335 +ipset=/ghettotube.com/gfwlist +server=/useplannr.com/127.0.0.1#5335 +ipset=/useplannr.com/gfwlist +server=/disney.se/127.0.0.1#5335 +ipset=/disney.se/gfwlist +server=/fontexplorerx.com/127.0.0.1#5335 +ipset=/fontexplorerx.com/gfwlist +server=/yahoo.si/127.0.0.1#5335 +ipset=/yahoo.si/gfwlist +server=/fescebook.com/127.0.0.1#5335 +ipset=/fescebook.com/gfwlist +server=/arabgirls.us/127.0.0.1#5335 +ipset=/arabgirls.us/gfwlist +server=/eroterest.net/127.0.0.1#5335 +ipset=/eroterest.net/gfwlist +server=/justnudepic.com/127.0.0.1#5335 +ipset=/justnudepic.com/gfwlist +server=/nikeairmaxs.com/127.0.0.1#5335 +ipset=/nikeairmaxs.com/gfwlist +server=/fox35orlando.com/127.0.0.1#5335 +ipset=/fox35orlando.com/gfwlist +server=/seksmet.nl/127.0.0.1#5335 +ipset=/seksmet.nl/gfwlist +server=/visa.pt/127.0.0.1#5335 +ipset=/visa.pt/gfwlist +server=/celebgramme.com/127.0.0.1#5335 +ipset=/celebgramme.com/gfwlist +server=/d2mrry2to5rg.com/127.0.0.1#5335 +ipset=/d2mrry2to5rg.com/gfwlist +server=/ebayoncampus.com/127.0.0.1#5335 +ipset=/ebayoncampus.com/gfwlist +server=/sankei-eiga.co.jp/127.0.0.1#5335 +ipset=/sankei-eiga.co.jp/gfwlist +server=/renminbao.com/127.0.0.1#5335 +ipset=/renminbao.com/gfwlist +server=/youtrannytube.com/127.0.0.1#5335 +ipset=/youtrannytube.com/gfwlist +server=/vmwgcomms.com/127.0.0.1#5335 +ipset=/vmwgcomms.com/gfwlist +server=/vidmpreview.com/127.0.0.1#5335 +ipset=/vidmpreview.com/gfwlist +server=/finehub.com/127.0.0.1#5335 +ipset=/finehub.com/gfwlist +server=/nyt.net/127.0.0.1#5335 +ipset=/nyt.net/gfwlist +server=/curseforge.com/127.0.0.1#5335 +ipset=/curseforge.com/gfwlist +server=/francemail.com/127.0.0.1#5335 +ipset=/francemail.com/gfwlist +server=/nutaku.net/127.0.0.1#5335 +ipset=/nutaku.net/gfwlist +server=/vfsco.se/127.0.0.1#5335 +ipset=/vfsco.se/gfwlist +server=/04647.club/127.0.0.1#5335 +ipset=/04647.club/gfwlist +server=/miniworkshop.com/127.0.0.1#5335 +ipset=/miniworkshop.com/gfwlist +server=/nike-org.com/127.0.0.1#5335 +ipset=/nike-org.com/gfwlist +server=/paypal-business.org/127.0.0.1#5335 +ipset=/paypal-business.org/gfwlist +server=/bmw.com.ph/127.0.0.1#5335 +ipset=/bmw.com.ph/gfwlist +server=/bookclubcorner.com/127.0.0.1#5335 +ipset=/bookclubcorner.com/gfwlist +server=/xnxx4porn.com/127.0.0.1#5335 +ipset=/xnxx4porn.com/gfwlist +server=/eurobabeindex.com/127.0.0.1#5335 +ipset=/eurobabeindex.com/gfwlist +server=/braintreeps.com/127.0.0.1#5335 +ipset=/braintreeps.com/gfwlist +server=/siterips.org/127.0.0.1#5335 +ipset=/siterips.org/gfwlist +server=/drebeats-singapore.net/127.0.0.1#5335 +ipset=/drebeats-singapore.net/gfwlist +server=/czechhunter.com/127.0.0.1#5335 +ipset=/czechhunter.com/gfwlist +server=/bili999.com/127.0.0.1#5335 +ipset=/bili999.com/gfwlist +server=/volvotrucks.sg/127.0.0.1#5335 +ipset=/volvotrucks.sg/gfwlist +server=/vct.news/127.0.0.1#5335 +ipset=/vct.news/gfwlist +server=/cashbycashapp.com/127.0.0.1#5335 +ipset=/cashbycashapp.com/gfwlist +server=/beats-headphones.us/127.0.0.1#5335 +ipset=/beats-headphones.us/gfwlist +server=/alphera.co.in/127.0.0.1#5335 +ipset=/alphera.co.in/gfwlist +server=/shegods.com/127.0.0.1#5335 +ipset=/shegods.com/gfwlist +server=/webex.co.uk/127.0.0.1#5335 +ipset=/webex.co.uk/gfwlist +server=/driverxxx.com/127.0.0.1#5335 +ipset=/driverxxx.com/gfwlist +server=/youtube.hu/127.0.0.1#5335 +ipset=/youtube.hu/gfwlist +server=/alphabet.asia/127.0.0.1#5335 +ipset=/alphabet.asia/gfwlist +server=/claravenger.com/127.0.0.1#5335 +ipset=/claravenger.com/gfwlist +server=/epicbrowser.com/127.0.0.1#5335 +ipset=/epicbrowser.com/gfwlist +server=/beatsbydrdres.com/127.0.0.1#5335 +ipset=/beatsbydrdres.com/gfwlist +server=/beatsbydreboxingdayca.com/127.0.0.1#5335 +ipset=/beatsbydreboxingdayca.com/gfwlist +server=/youtube.co.jp/127.0.0.1#5335 +ipset=/youtube.co.jp/gfwlist +server=/admob.com/127.0.0.1#5335 +ipset=/admob.com/gfwlist +server=/paypal-plaza.com/127.0.0.1#5335 +ipset=/paypal-plaza.com/gfwlist +server=/alterauserforums.com/127.0.0.1#5335 +ipset=/alterauserforums.com/gfwlist +server=/vfsco.com.br/127.0.0.1#5335 +ipset=/vfsco.com.br/gfwlist +server=/cfwives.com/127.0.0.1#5335 +ipset=/cfwives.com/gfwlist +server=/rbbusinessshop.com/127.0.0.1#5335 +ipset=/rbbusinessshop.com/gfwlist +server=/steamgames.com/127.0.0.1#5335 +ipset=/steamgames.com/gfwlist +server=/aziani.com/127.0.0.1#5335 +ipset=/aziani.com/gfwlist +server=/youpornxvideos.net/127.0.0.1#5335 +ipset=/youpornxvideos.net/gfwlist +server=/bmw.tt/127.0.0.1#5335 +ipset=/bmw.tt/gfwlist +server=/directvlosangeles.com/127.0.0.1#5335 +ipset=/directvlosangeles.com/gfwlist +server=/javgrown.com/127.0.0.1#5335 +ipset=/javgrown.com/gfwlist +server=/sonypicturesanimation.com/127.0.0.1#5335 +ipset=/sonypicturesanimation.com/gfwlist +server=/canon-emea.com/127.0.0.1#5335 +ipset=/canon-emea.com/gfwlist +server=/escortgirls.be/127.0.0.1#5335 +ipset=/escortgirls.be/gfwlist +server=/faceboot.com/127.0.0.1#5335 +ipset=/faceboot.com/gfwlist +server=/gopivotal.com/127.0.0.1#5335 +ipset=/gopivotal.com/gfwlist +server=/tvmedia.net.au/127.0.0.1#5335 +ipset=/tvmedia.net.au/gfwlist +server=/geeksquad.com/127.0.0.1#5335 +ipset=/geeksquad.com/gfwlist +server=/time.gov/127.0.0.1#5335 +ipset=/time.gov/gfwlist +server=/amplifyframework.com/127.0.0.1#5335 +ipset=/amplifyframework.com/gfwlist +server=/licensebuttons.net/127.0.0.1#5335 +ipset=/licensebuttons.net/gfwlist +server=/scolle.net/127.0.0.1#5335 +ipset=/scolle.net/gfwlist +server=/microsoft365.com/127.0.0.1#5335 +ipset=/microsoft365.com/gfwlist +server=/pypl.tv/127.0.0.1#5335 +ipset=/pypl.tv/gfwlist +server=/zeenews-fonts.s3.amazonaws.com/127.0.0.1#5335 +ipset=/zeenews-fonts.s3.amazonaws.com/gfwlist +server=/groupfun.com/127.0.0.1#5335 +ipset=/groupfun.com/gfwlist +server=/paypalbeacon.com/127.0.0.1#5335 +ipset=/paypalbeacon.com/gfwlist +server=/mray.club/127.0.0.1#5335 +ipset=/mray.club/gfwlist +server=/pornoweb.hu/127.0.0.1#5335 +ipset=/pornoweb.hu/gfwlist +server=/4pig.com/127.0.0.1#5335 +ipset=/4pig.com/gfwlist +server=/zoig.com/127.0.0.1#5335 +ipset=/zoig.com/gfwlist +server=/pokemonvgc.com/127.0.0.1#5335 +ipset=/pokemonvgc.com/gfwlist +server=/booking.com/127.0.0.1#5335 +ipset=/booking.com/gfwlist +server=/intel.sy/127.0.0.1#5335 +ipset=/intel.sy/gfwlist +server=/paypal-signin.us/127.0.0.1#5335 +ipset=/paypal-signin.us/gfwlist +server=/yuraku.8v8.be/127.0.0.1#5335 +ipset=/yuraku.8v8.be/gfwlist +server=/foxsportssupports.com/127.0.0.1#5335 +ipset=/foxsportssupports.com/gfwlist +server=/yahoo.com.om/127.0.0.1#5335 +ipset=/yahoo.com.om/gfwlist +server=/google.dk/127.0.0.1#5335 +ipset=/google.dk/gfwlist +server=/globaledu.org/127.0.0.1#5335 +ipset=/globaledu.org/gfwlist +server=/veet.com.sg/127.0.0.1#5335 +ipset=/veet.com.sg/gfwlist +server=/wealth.com.tw/127.0.0.1#5335 +ipset=/wealth.com.tw/gfwlist +server=/downloadpass.com/127.0.0.1#5335 +ipset=/downloadpass.com/gfwlist +server=/global-sci.org/127.0.0.1#5335 +ipset=/global-sci.org/gfwlist +server=/paragon.com/127.0.0.1#5335 +ipset=/paragon.com/gfwlist +server=/bangkokstreetwhores.com/127.0.0.1#5335 +ipset=/bangkokstreetwhores.com/gfwlist +server=/genshin-porn.com/127.0.0.1#5335 +ipset=/genshin-porn.com/gfwlist +server=/mastercard.com.ph/127.0.0.1#5335 +ipset=/mastercard.com.ph/gfwlist +server=/shopee.com/127.0.0.1#5335 +ipset=/shopee.com/gfwlist +server=/123sex.top/127.0.0.1#5335 +ipset=/123sex.top/gfwlist +server=/sonydesign.com/127.0.0.1#5335 +ipset=/sonydesign.com/gfwlist +server=/myconstructionworld.net/127.0.0.1#5335 +ipset=/myconstructionworld.net/gfwlist +server=/celebforum.co/127.0.0.1#5335 +ipset=/celebforum.co/gfwlist +server=/streamable.com/127.0.0.1#5335 +ipset=/streamable.com/gfwlist +server=/foxkansas.com/127.0.0.1#5335 +ipset=/foxkansas.com/gfwlist +server=/fbcdn.com/127.0.0.1#5335 +ipset=/fbcdn.com/gfwlist +server=/retrohomevideos.com/127.0.0.1#5335 +ipset=/retrohomevideos.com/gfwlist +server=/wearehairy.com/127.0.0.1#5335 +ipset=/wearehairy.com/gfwlist +server=/dcard.io/127.0.0.1#5335 +ipset=/dcard.io/gfwlist +server=/youtube.sa/127.0.0.1#5335 +ipset=/youtube.sa/gfwlist +server=/21hub.com/127.0.0.1#5335 +ipset=/21hub.com/gfwlist +server=/foxlexington.com/127.0.0.1#5335 +ipset=/foxlexington.com/gfwlist +server=/lindylist.org/127.0.0.1#5335 +ipset=/lindylist.org/gfwlist +server=/dvh30n.vip/127.0.0.1#5335 +ipset=/dvh30n.vip/gfwlist +server=/property.com.au/127.0.0.1#5335 +ipset=/property.com.au/gfwlist +server=/pussy3dporn.com/127.0.0.1#5335 +ipset=/pussy3dporn.com/gfwlist +server=/gcolle.net/127.0.0.1#5335 +ipset=/gcolle.net/gfwlist +server=/paypal.info/127.0.0.1#5335 +ipset=/paypal.info/gfwlist +server=/xuite.net/127.0.0.1#5335 +ipset=/xuite.net/gfwlist +server=/google.ne/127.0.0.1#5335 +ipset=/google.ne/gfwlist +server=/rethink.net/127.0.0.1#5335 +ipset=/rethink.net/gfwlist +server=/tinyurl.com/127.0.0.1#5335 +ipset=/tinyurl.com/gfwlist +server=/trikepatrol.com/127.0.0.1#5335 +ipset=/trikepatrol.com/gfwlist +server=/ettrade.com.hk/127.0.0.1#5335 +ipset=/ettrade.com.hk/gfwlist +server=/volvotrucks.tm/127.0.0.1#5335 +ipset=/volvotrucks.tm/gfwlist +server=/aacrjournals.org/127.0.0.1#5335 +ipset=/aacrjournals.org/gfwlist +server=/gmoney.org/127.0.0.1#5335 +ipset=/gmoney.org/gfwlist +server=/youtube.com.pk/127.0.0.1#5335 +ipset=/youtube.com.pk/gfwlist +server=/fox46charlotte.com/127.0.0.1#5335 +ipset=/fox46charlotte.com/gfwlist +server=/apple-store.wang/127.0.0.1#5335 +ipset=/apple-store.wang/gfwlist +server=/phprcdn.com/127.0.0.1#5335 +ipset=/phprcdn.com/gfwlist +server=/sagepub.com/127.0.0.1#5335 +ipset=/sagepub.com/gfwlist +server=/onlyhomemadeanal.com/127.0.0.1#5335 +ipset=/onlyhomemadeanal.com/gfwlist +server=/direectv.com/127.0.0.1#5335 +ipset=/direectv.com/gfwlist +server=/durex.co.nz/127.0.0.1#5335 +ipset=/durex.co.nz/gfwlist +server=/meitula.net/127.0.0.1#5335 +ipset=/meitula.net/gfwlist +server=/flyflv.com/127.0.0.1#5335 +ipset=/flyflv.com/gfwlist +server=/api-p.videomarket.jp/127.0.0.1#5335 +ipset=/api-p.videomarket.jp/gfwlist +server=/applestore.qa/127.0.0.1#5335 +ipset=/applestore.qa/gfwlist +server=/strepsils.co.kr/127.0.0.1#5335 +ipset=/strepsils.co.kr/gfwlist +server=/mini101.ca/127.0.0.1#5335 +ipset=/mini101.ca/gfwlist +server=/area51.to/127.0.0.1#5335 +ipset=/area51.to/gfwlist +server=/minimotoringschool.com/127.0.0.1#5335 +ipset=/minimotoringschool.com/gfwlist +server=/bbthat.com/127.0.0.1#5335 +ipset=/bbthat.com/gfwlist +server=/freejavporn.mobi/127.0.0.1#5335 +ipset=/freejavporn.mobi/gfwlist +server=/huanyuju.com/127.0.0.1#5335 +ipset=/huanyuju.com/gfwlist +server=/chobit.cc/127.0.0.1#5335 +ipset=/chobit.cc/gfwlist +server=/huluinstantmessenger.com/127.0.0.1#5335 +ipset=/huluinstantmessenger.com/gfwlist +server=/gameuxmasterguide.com/127.0.0.1#5335 +ipset=/gameuxmasterguide.com/gfwlist +server=/alphabet.lu/127.0.0.1#5335 +ipset=/alphabet.lu/gfwlist +server=/mastercard.be/127.0.0.1#5335 +ipset=/mastercard.be/gfwlist +server=/foxnewsgo.tv/127.0.0.1#5335 +ipset=/foxnewsgo.tv/gfwlist +server=/ipodtouch.co/127.0.0.1#5335 +ipset=/ipodtouch.co/gfwlist +server=/tjsbfj.com/127.0.0.1#5335 +ipset=/tjsbfj.com/gfwlist +server=/markzuckerberg.com/127.0.0.1#5335 +ipset=/markzuckerberg.com/gfwlist +server=/visa.tc/127.0.0.1#5335 +ipset=/visa.tc/gfwlist +server=/totalmateria.com/127.0.0.1#5335 +ipset=/totalmateria.com/gfwlist +server=/dnaspaces.io/127.0.0.1#5335 +ipset=/dnaspaces.io/gfwlist +server=/bmw.co.uk/127.0.0.1#5335 +ipset=/bmw.co.uk/gfwlist +server=/angle.com.tw/127.0.0.1#5335 +ipset=/angle.com.tw/gfwlist +server=/facebook-pmdcenter.net/127.0.0.1#5335 +ipset=/facebook-pmdcenter.net/gfwlist +server=/nvidia.com.ve/127.0.0.1#5335 +ipset=/nvidia.com.ve/gfwlist +server=/nicoseiga.jp/127.0.0.1#5335 +ipset=/nicoseiga.jp/gfwlist +server=/durex.com.hr/127.0.0.1#5335 +ipset=/durex.com.hr/gfwlist +server=/69story.com/127.0.0.1#5335 +ipset=/69story.com/gfwlist +server=/microsoftonline-p.com/127.0.0.1#5335 +ipset=/microsoftonline-p.com/gfwlist +server=/aliveitsm.com/127.0.0.1#5335 +ipset=/aliveitsm.com/gfwlist +server=/coova.com/127.0.0.1#5335 +ipset=/coova.com/gfwlist +server=/ipod.es/127.0.0.1#5335 +ipset=/ipod.es/gfwlist +server=/leagueoflegends.ca/127.0.0.1#5335 +ipset=/leagueoflegends.ca/gfwlist +server=/examroom.info/127.0.0.1#5335 +ipset=/examroom.info/gfwlist +server=/nintendo.net/127.0.0.1#5335 +ipset=/nintendo.net/gfwlist +server=/linseysworld.com/127.0.0.1#5335 +ipset=/linseysworld.com/gfwlist +server=/veet.cl/127.0.0.1#5335 +ipset=/veet.cl/gfwlist +server=/pornsos.com/127.0.0.1#5335 +ipset=/pornsos.com/gfwlist +server=/kingcomix.com/127.0.0.1#5335 +ipset=/kingcomix.com/gfwlist +server=/volvotrucks.co.ao/127.0.0.1#5335 +ipset=/volvotrucks.co.ao/gfwlist +server=/beegfree.com/127.0.0.1#5335 +ipset=/beegfree.com/gfwlist +server=/fleshbot.com/127.0.0.1#5335 +ipset=/fleshbot.com/gfwlist +server=/bsw.co.jp/127.0.0.1#5335 +ipset=/bsw.co.jp/gfwlist +server=/freepornpreview.net/127.0.0.1#5335 +ipset=/freepornpreview.net/gfwlist +server=/hothdsex.xxx/127.0.0.1#5335 +ipset=/hothdsex.xxx/gfwlist +server=/horseporn.tv/127.0.0.1#5335 +ipset=/horseporn.tv/gfwlist +server=/imagecurl.org/127.0.0.1#5335 +ipset=/imagecurl.org/gfwlist +server=/floppy-tits.com/127.0.0.1#5335 +ipset=/floppy-tits.com/gfwlist +server=/mastercard.cz/127.0.0.1#5335 +ipset=/mastercard.cz/gfwlist +server=/volvogroup.fr/127.0.0.1#5335 +ipset=/volvogroup.fr/gfwlist +server=/881903.com/127.0.0.1#5335 +ipset=/881903.com/gfwlist +server=/webcams.tv/127.0.0.1#5335 +ipset=/webcams.tv/gfwlist +server=/contactossexoecuador.com/127.0.0.1#5335 +ipset=/contactossexoecuador.com/gfwlist +server=/bbystatic.com/127.0.0.1#5335 +ipset=/bbystatic.com/gfwlist +server=/netflixdnstest9.com/127.0.0.1#5335 +ipset=/netflixdnstest9.com/gfwlist +server=/suruga-ya.jp/127.0.0.1#5335 +ipset=/suruga-ya.jp/gfwlist +server=/girlssexxxx.com/127.0.0.1#5335 +ipset=/girlssexxxx.com/gfwlist +server=/sony.be/127.0.0.1#5335 +ipset=/sony.be/gfwlist +server=/bmw-saudiarabia.com/127.0.0.1#5335 +ipset=/bmw-saudiarabia.com/gfwlist +server=/ero-anime.net/127.0.0.1#5335 +ipset=/ero-anime.net/gfwlist +server=/intel.af/127.0.0.1#5335 +ipset=/intel.af/gfwlist +server=/whoreasianporn.com/127.0.0.1#5335 +ipset=/whoreasianporn.com/gfwlist +server=/qualcomm.co.uk/127.0.0.1#5335 +ipset=/qualcomm.co.uk/gfwlist +server=/cheapbeatsbydrestudioedition.com/127.0.0.1#5335 +ipset=/cheapbeatsbydrestudioedition.com/gfwlist +server=/maddenseason.net/127.0.0.1#5335 +ipset=/maddenseason.net/gfwlist +server=/verisign.vn/127.0.0.1#5335 +ipset=/verisign.vn/gfwlist +server=/wildfreevideos.com/127.0.0.1#5335 +ipset=/wildfreevideos.com/gfwlist +server=/intel.com.my/127.0.0.1#5335 +ipset=/intel.com.my/gfwlist +server=/yahoo.com.mt/127.0.0.1#5335 +ipset=/yahoo.com.mt/gfwlist +server=/spiceworksstatic.com/127.0.0.1#5335 +ipset=/spiceworksstatic.com/gfwlist +server=/uhairy.com/127.0.0.1#5335 +ipset=/uhairy.com/gfwlist +server=/pricelesshongkong.com/127.0.0.1#5335 +ipset=/pricelesshongkong.com/gfwlist +server=/hkteducation.com/127.0.0.1#5335 +ipset=/hkteducation.com/gfwlist +server=/mini.kz/127.0.0.1#5335 +ipset=/mini.kz/gfwlist +server=/justindianporn.me/127.0.0.1#5335 +ipset=/justindianporn.me/gfwlist +server=/google.com.af/127.0.0.1#5335 +ipset=/google.com.af/gfwlist +server=/paypalonline.org/127.0.0.1#5335 +ipset=/paypalonline.org/gfwlist +server=/rea.io/127.0.0.1#5335 +ipset=/rea.io/gfwlist +server=/bmwcolorado.com/127.0.0.1#5335 +ipset=/bmwcolorado.com/gfwlist +server=/financialadvisoriq.com/127.0.0.1#5335 +ipset=/financialadvisoriq.com/gfwlist +server=/instantssl.com/127.0.0.1#5335 +ipset=/instantssl.com/gfwlist +server=/strepsils.com.hk/127.0.0.1#5335 +ipset=/strepsils.com.hk/gfwlist +server=/teen-girl.net/127.0.0.1#5335 +ipset=/teen-girl.net/gfwlist +server=/iwara.tv/127.0.0.1#5335 +ipset=/iwara.tv/gfwlist +server=/nudewomenpics.net/127.0.0.1#5335 +ipset=/nudewomenpics.net/gfwlist +server=/facebook.design/127.0.0.1#5335 +ipset=/facebook.design/gfwlist +server=/mini.com.uy/127.0.0.1#5335 +ipset=/mini.com.uy/gfwlist +server=/illusion.jp/127.0.0.1#5335 +ipset=/illusion.jp/gfwlist +server=/i-scmp.com/127.0.0.1#5335 +ipset=/i-scmp.com/gfwlist +server=/kindteenporn.com/127.0.0.1#5335 +ipset=/kindteenporn.com/gfwlist +server=/ikea.co.kr/127.0.0.1#5335 +ipset=/ikea.co.kr/gfwlist +server=/volvotrucks.gr/127.0.0.1#5335 +ipset=/volvotrucks.gr/gfwlist +server=/hentaiknight.com/127.0.0.1#5335 +ipset=/hentaiknight.com/gfwlist +server=/foxplus.com/127.0.0.1#5335 +ipset=/foxplus.com/gfwlist +server=/adult3dtoons.com/127.0.0.1#5335 +ipset=/adult3dtoons.com/gfwlist +server=/hkcsl.com/127.0.0.1#5335 +ipset=/hkcsl.com/gfwlist +server=/nurofen.it/127.0.0.1#5335 +ipset=/nurofen.it/gfwlist +server=/instagramn.com/127.0.0.1#5335 +ipset=/instagramn.com/gfwlist +server=/dafahao.com/127.0.0.1#5335 +ipset=/dafahao.com/gfwlist +server=/zerohedge.com/127.0.0.1#5335 +ipset=/zerohedge.com/gfwlist +server=/adobe-aemassets-value.com/127.0.0.1#5335 +ipset=/adobe-aemassets-value.com/gfwlist +server=/login-account.net/127.0.0.1#5335 +ipset=/login-account.net/gfwlist +server=/tubetria.mobi/127.0.0.1#5335 +ipset=/tubetria.mobi/gfwlist +server=/gaysitessearch.cc/127.0.0.1#5335 +ipset=/gaysitessearch.cc/gfwlist +server=/nikeselling.com/127.0.0.1#5335 +ipset=/nikeselling.com/gfwlist +server=/satnym.com/127.0.0.1#5335 +ipset=/satnym.com/gfwlist +server=/flow.dev/127.0.0.1#5335 +ipset=/flow.dev/gfwlist +server=/beats-deal.com/127.0.0.1#5335 +ipset=/beats-deal.com/gfwlist +server=/bigdickorgasm.com/127.0.0.1#5335 +ipset=/bigdickorgasm.com/gfwlist +server=/linefriends.com/127.0.0.1#5335 +ipset=/linefriends.com/gfwlist +server=/yourcolonoscopy.com/127.0.0.1#5335 +ipset=/yourcolonoscopy.com/gfwlist +server=/comodo.com/127.0.0.1#5335 +ipset=/comodo.com/gfwlist +server=/beatsmusic.wang/127.0.0.1#5335 +ipset=/beatsmusic.wang/gfwlist +server=/powerbook.eu/127.0.0.1#5335 +ipset=/powerbook.eu/gfwlist +server=/bmwoftulsa.com/127.0.0.1#5335 +ipset=/bmwoftulsa.com/gfwlist +server=/wkap.nl/127.0.0.1#5335 +ipset=/wkap.nl/gfwlist +server=/blogspot.cf/127.0.0.1#5335 +ipset=/blogspot.cf/gfwlist +server=/paypal.com.sg/127.0.0.1#5335 +ipset=/paypal.com.sg/gfwlist +server=/ebaymotorsblog.com/127.0.0.1#5335 +ipset=/ebaymotorsblog.com/gfwlist +server=/youtube.com.bd/127.0.0.1#5335 +ipset=/youtube.com.bd/gfwlist +server=/knoxemm.com/127.0.0.1#5335 +ipset=/knoxemm.com/gfwlist +server=/wdc.com/127.0.0.1#5335 +ipset=/wdc.com/gfwlist +server=/beats-seller.com/127.0.0.1#5335 +ipset=/beats-seller.com/gfwlist +server=/voyeurhit.com/127.0.0.1#5335 +ipset=/voyeurhit.com/gfwlist +server=/mrlivecam.com/127.0.0.1#5335 +ipset=/mrlivecam.com/gfwlist +server=/appcloud.com/127.0.0.1#5335 +ipset=/appcloud.com/gfwlist +server=/mini.hu/127.0.0.1#5335 +ipset=/mini.hu/gfwlist +server=/discord.gifts/127.0.0.1#5335 +ipset=/discord.gifts/gfwlist +server=/els-cdn.com/127.0.0.1#5335 +ipset=/els-cdn.com/gfwlist +server=/visceralgames.com/127.0.0.1#5335 +ipset=/visceralgames.com/gfwlist +server=/volvotrucks.com.tw/127.0.0.1#5335 +ipset=/volvotrucks.com.tw/gfwlist +server=/chinapress.com.my/127.0.0.1#5335 +ipset=/chinapress.com.my/gfwlist +server=/dettol.cz/127.0.0.1#5335 +ipset=/dettol.cz/gfwlist +server=/paypal-activate.info/127.0.0.1#5335 +ipset=/paypal-activate.info/gfwlist +server=/bmw.se/127.0.0.1#5335 +ipset=/bmw.se/gfwlist +server=/nike-us.com/127.0.0.1#5335 +ipset=/nike-us.com/gfwlist +server=/appstore.my/127.0.0.1#5335 +ipset=/appstore.my/gfwlist +server=/ebay.it/127.0.0.1#5335 +ipset=/ebay.it/gfwlist +server=/iza.ne.jp/127.0.0.1#5335 +ipset=/iza.ne.jp/gfwlist +server=/adguard-vpn.com/127.0.0.1#5335 +ipset=/adguard-vpn.com/gfwlist +server=/scmp.com/127.0.0.1#5335 +ipset=/scmp.com/gfwlist +server=/voanouvel.com/127.0.0.1#5335 +ipset=/voanouvel.com/gfwlist +server=/f3b7q2p3.ssl.hwcdn.net/127.0.0.1#5335 +ipset=/f3b7q2p3.ssl.hwcdn.net/gfwlist +server=/goragay.com/127.0.0.1#5335 +ipset=/goragay.com/gfwlist +server=/abc.com/127.0.0.1#5335 +ipset=/abc.com/gfwlist +server=/bbc.com/127.0.0.1#5335 +ipset=/bbc.com/gfwlist +server=/shopping-days.net/127.0.0.1#5335 +ipset=/shopping-days.net/gfwlist +server=/naaktevrouwenporno.com/127.0.0.1#5335 +ipset=/naaktevrouwenporno.com/gfwlist +server=/mypearsonshop.mx/127.0.0.1#5335 +ipset=/mypearsonshop.mx/gfwlist +server=/tailwindtraders.com/127.0.0.1#5335 +ipset=/tailwindtraders.com/gfwlist +server=/paypalcredit.com/127.0.0.1#5335 +ipset=/paypalcredit.com/gfwlist +server=/pinterest.co.in/127.0.0.1#5335 +ipset=/pinterest.co.in/gfwlist +server=/blogspot.com.es/127.0.0.1#5335 +ipset=/blogspot.com.es/gfwlist +server=/videolan.org/127.0.0.1#5335 +ipset=/videolan.org/gfwlist +server=/nbc.com/127.0.0.1#5335 +ipset=/nbc.com/gfwlist +server=/facebookgraphsearch.info/127.0.0.1#5335 +ipset=/facebookgraphsearch.info/gfwlist +server=/nurofengel.com/127.0.0.1#5335 +ipset=/nurofengel.com/gfwlist +server=/bmw-motorrad.hu/127.0.0.1#5335 +ipset=/bmw-motorrad.hu/gfwlist +server=/av234567.com/127.0.0.1#5335 +ipset=/av234567.com/gfwlist +server=/89.com/127.0.0.1#5335 +ipset=/89.com/gfwlist +server=/girlstryanal.com/127.0.0.1#5335 +ipset=/girlstryanal.com/gfwlist +server=/beats-dre-us.com/127.0.0.1#5335 +ipset=/beats-dre-us.com/gfwlist +server=/darwinsource.com/127.0.0.1#5335 +ipset=/darwinsource.com/gfwlist +server=/travelex.com.my/127.0.0.1#5335 +ipset=/travelex.com.my/gfwlist +server=/sexbookecuador.com/127.0.0.1#5335 +ipset=/sexbookecuador.com/gfwlist +server=/topvids.net/127.0.0.1#5335 +ipset=/topvids.net/gfwlist +server=/vmwarecertificationvideos.com/127.0.0.1#5335 +ipset=/vmwarecertificationvideos.com/gfwlist +server=/miniusatires.com/127.0.0.1#5335 +ipset=/miniusatires.com/gfwlist +server=/pleasefuck.org/127.0.0.1#5335 +ipset=/pleasefuck.org/gfwlist +server=/paypalshopping.com/127.0.0.1#5335 +ipset=/paypalshopping.com/gfwlist +server=/canon.me/127.0.0.1#5335 +ipset=/canon.me/gfwlist +server=/battle.net/127.0.0.1#5335 +ipset=/battle.net/gfwlist +server=/scnshop.cc/127.0.0.1#5335 +ipset=/scnshop.cc/gfwlist +server=/baicaonetwork.com/127.0.0.1#5335 +ipset=/baicaonetwork.com/gfwlist +server=/intel.mx/127.0.0.1#5335 +ipset=/intel.mx/gfwlist +server=/hdjavonline.com/127.0.0.1#5335 +ipset=/hdjavonline.com/gfwlist +server=/yahoo.com.bo/127.0.0.1#5335 +ipset=/yahoo.com.bo/gfwlist +server=/ogp.me/127.0.0.1#5335 +ipset=/ogp.me/gfwlist +server=/dumpxxx.net/127.0.0.1#5335 +ipset=/dumpxxx.net/gfwlist +server=/fjlkajhgfa.top/127.0.0.1#5335 +ipset=/fjlkajhgfa.top/gfwlist +server=/youtube.co.ma/127.0.0.1#5335 +ipset=/youtube.co.ma/gfwlist +server=/firestone.cl/127.0.0.1#5335 +ipset=/firestone.cl/gfwlist +server=/usatoday.com/127.0.0.1#5335 +ipset=/usatoday.com/gfwlist +server=/18av.mm-cg.com/127.0.0.1#5335 +ipset=/18av.mm-cg.com/gfwlist +server=/pearson.pl/127.0.0.1#5335 +ipset=/pearson.pl/gfwlist +server=/yahoo.dj/127.0.0.1#5335 +ipset=/yahoo.dj/gfwlist +server=/teeztube.com/127.0.0.1#5335 +ipset=/teeztube.com/gfwlist +server=/xxxsexanal.com/127.0.0.1#5335 +ipset=/xxxsexanal.com/gfwlist +server=/launchpadlibrarian.org/127.0.0.1#5335 +ipset=/launchpadlibrarian.org/gfwlist +server=/directvcookevilletn.com/127.0.0.1#5335 +ipset=/directvcookevilletn.com/gfwlist +server=/e-bay.net/127.0.0.1#5335 +ipset=/e-bay.net/gfwlist +server=/adultgamesapk.com/127.0.0.1#5335 +ipset=/adultgamesapk.com/gfwlist +server=/ikea.com.cy/127.0.0.1#5335 +ipset=/ikea.com.cy/gfwlist +server=/amazon.jp/127.0.0.1#5335 +ipset=/amazon.jp/gfwlist +server=/womenwill.in/127.0.0.1#5335 +ipset=/womenwill.in/gfwlist +server=/mastercard.co.th/127.0.0.1#5335 +ipset=/mastercard.co.th/gfwlist +server=/pchome.com.tw/127.0.0.1#5335 +ipset=/pchome.com.tw/gfwlist +server=/feacboo.com/127.0.0.1#5335 +ipset=/feacboo.com/gfwlist +server=/sesenovel.com/127.0.0.1#5335 +ipset=/sesenovel.com/gfwlist +server=/tagapie.com.tw/127.0.0.1#5335 +ipset=/tagapie.com.tw/gfwlist +server=/clipseksi.com/127.0.0.1#5335 +ipset=/clipseksi.com/gfwlist +server=/collaboraoffice.com/127.0.0.1#5335 +ipset=/collaboraoffice.com/gfwlist +server=/thawte.com/127.0.0.1#5335 +ipset=/thawte.com/gfwlist +server=/dealsbeatsblackfriday.com/127.0.0.1#5335 +ipset=/dealsbeatsblackfriday.com/gfwlist +server=/youtube.pr/127.0.0.1#5335 +ipset=/youtube.pr/gfwlist +server=/sehuatang.net/127.0.0.1#5335 +ipset=/sehuatang.net/gfwlist +server=/hentaikey.com/127.0.0.1#5335 +ipset=/hentaikey.com/gfwlist +server=/zaobao.com.sg/127.0.0.1#5335 +ipset=/zaobao.com.sg/gfwlist +server=/bmw.is/127.0.0.1#5335 +ipset=/bmw.is/gfwlist +server=/elephanttube.com/127.0.0.1#5335 +ipset=/elephanttube.com/gfwlist +server=/bidbay.com/127.0.0.1#5335 +ipset=/bidbay.com/gfwlist +server=/yamoon.club/127.0.0.1#5335 +ipset=/yamoon.club/gfwlist +server=/voaafaanoromoo.com/127.0.0.1#5335 +ipset=/voaafaanoromoo.com/gfwlist +server=/mings-fashion.com/127.0.0.1#5335 +ipset=/mings-fashion.com/gfwlist +server=/latamvmwareforum.com/127.0.0.1#5335 +ipset=/latamvmwareforum.com/gfwlist +server=/marvelsuperheroseptember.com/127.0.0.1#5335 +ipset=/marvelsuperheroseptember.com/gfwlist +server=/nintendonetwork.net/127.0.0.1#5335 +ipset=/nintendonetwork.net/gfwlist +server=/bmwmotorrad.com.au/127.0.0.1#5335 +ipset=/bmwmotorrad.com.au/gfwlist +server=/javsex.asia/127.0.0.1#5335 +ipset=/javsex.asia/gfwlist +server=/sexxxxfilms.com/127.0.0.1#5335 +ipset=/sexxxxfilms.com/gfwlist +server=/facdbook.com/127.0.0.1#5335 +ipset=/facdbook.com/gfwlist +server=/youtube.ua/127.0.0.1#5335 +ipset=/youtube.ua/gfwlist +server=/hdporn1080.net/127.0.0.1#5335 +ipset=/hdporn1080.net/gfwlist +server=/heydouga.com/127.0.0.1#5335 +ipset=/heydouga.com/gfwlist +server=/ecchi.xxx/127.0.0.1#5335 +ipset=/ecchi.xxx/gfwlist +server=/khanacademy.org/127.0.0.1#5335 +ipset=/khanacademy.org/gfwlist +server=/bigdick.com/127.0.0.1#5335 +ipset=/bigdick.com/gfwlist +server=/facebook-ebook.com/127.0.0.1#5335 +ipset=/facebook-ebook.com/gfwlist +server=/cloudflarestream.com/127.0.0.1#5335 +ipset=/cloudflarestream.com/gfwlist +server=/ethereum.foundation/127.0.0.1#5335 +ipset=/ethereum.foundation/gfwlist +server=/eromanga-hentai.com/127.0.0.1#5335 +ipset=/eromanga-hentai.com/gfwlist +server=/ebay-inc.org/127.0.0.1#5335 +ipset=/ebay-inc.org/gfwlist +server=/telekom.de/127.0.0.1#5335 +ipset=/telekom.de/gfwlist +server=/slashdot.org/127.0.0.1#5335 +ipset=/slashdot.org/gfwlist +server=/mktroute.com/127.0.0.1#5335 +ipset=/mktroute.com/gfwlist +server=/taleofthenight.com/127.0.0.1#5335 +ipset=/taleofthenight.com/gfwlist +server=/playsexgames.xxx/127.0.0.1#5335 +ipset=/playsexgames.xxx/gfwlist +server=/battlefieldheroes.com/127.0.0.1#5335 +ipset=/battlefieldheroes.com/gfwlist +server=/ebaymainstreet.com/127.0.0.1#5335 +ipset=/ebaymainstreet.com/gfwlist +server=/cqcorea.com/127.0.0.1#5335 +ipset=/cqcorea.com/gfwlist +server=/bustykellykay.com/127.0.0.1#5335 +ipset=/bustykellykay.com/gfwlist +server=/whorevintagesex.com/127.0.0.1#5335 +ipset=/whorevintagesex.com/gfwlist +server=/pivotalinitiative.com/127.0.0.1#5335 +ipset=/pivotalinitiative.com/gfwlist +server=/cheapbeats.us/127.0.0.1#5335 +ipset=/cheapbeats.us/gfwlist +server=/novostrong.com/127.0.0.1#5335 +ipset=/novostrong.com/gfwlist +server=/yahoo.at/127.0.0.1#5335 +ipset=/yahoo.at/gfwlist +server=/archlinuxarm.org/127.0.0.1#5335 +ipset=/archlinuxarm.org/gfwlist +server=/bluemix.com/127.0.0.1#5335 +ipset=/bluemix.com/gfwlist +server=/91gay.me/127.0.0.1#5335 +ipset=/91gay.me/gfwlist +server=/superuser.com/127.0.0.1#5335 +ipset=/superuser.com/gfwlist +server=/vfsco.sk/127.0.0.1#5335 +ipset=/vfsco.sk/gfwlist +server=/yourporndump.com/127.0.0.1#5335 +ipset=/yourporndump.com/gfwlist +server=/mini.com.mk/127.0.0.1#5335 +ipset=/mini.com.mk/gfwlist +server=/genitourinaryexam.com/127.0.0.1#5335 +ipset=/genitourinaryexam.com/gfwlist +server=/qatarescortsvip.com/127.0.0.1#5335 +ipset=/qatarescortsvip.com/gfwlist +server=/shopee.id/127.0.0.1#5335 +ipset=/shopee.id/gfwlist +server=/pearson-studium.ch/127.0.0.1#5335 +ipset=/pearson-studium.ch/gfwlist +server=/8kcosplay.com/127.0.0.1#5335 +ipset=/8kcosplay.com/gfwlist +server=/bmw-abudhabi.com/127.0.0.1#5335 +ipset=/bmw-abudhabi.com/gfwlist +server=/momoshop.com.tw/127.0.0.1#5335 +ipset=/momoshop.com.tw/gfwlist +server=/directvconnect.com/127.0.0.1#5335 +ipset=/directvconnect.com/gfwlist +server=/serverlesslibrary.net/127.0.0.1#5335 +ipset=/serverlesslibrary.net/gfwlist +server=/afappyending.com/127.0.0.1#5335 +ipset=/afappyending.com/gfwlist +server=/msunlimitedcloudsummit.com/127.0.0.1#5335 +ipset=/msunlimitedcloudsummit.com/gfwlist +server=/sagernet.org/127.0.0.1#5335 +ipset=/sagernet.org/gfwlist +server=/dykycl.com/127.0.0.1#5335 +ipset=/dykycl.com/gfwlist +server=/babosas.com/127.0.0.1#5335 +ipset=/babosas.com/gfwlist +server=/bridgestone.com.sg/127.0.0.1#5335 +ipset=/bridgestone.com.sg/gfwlist +server=/xvideo.com/127.0.0.1#5335 +ipset=/xvideo.com/gfwlist +server=/ladyboygold.com/127.0.0.1#5335 +ipset=/ladyboygold.com/gfwlist +server=/gockhuatviet.com/127.0.0.1#5335 +ipset=/gockhuatviet.com/gfwlist +server=/sm.ms/127.0.0.1#5335 +ipset=/sm.ms/gfwlist +server=/bmwsummerschool.com/127.0.0.1#5335 +ipset=/bmwsummerschool.com/gfwlist +server=/simgbb.com/127.0.0.1#5335 +ipset=/simgbb.com/gfwlist +server=/mushymush.tv/127.0.0.1#5335 +ipset=/mushymush.tv/gfwlist +server=/fuzokudx.com/127.0.0.1#5335 +ipset=/fuzokudx.com/gfwlist +server=/buckbuild.com/127.0.0.1#5335 +ipset=/buckbuild.com/gfwlist +server=/gelbooru.me/127.0.0.1#5335 +ipset=/gelbooru.me/gfwlist +server=/windowsmarketplace.com/127.0.0.1#5335 +ipset=/windowsmarketplace.com/gfwlist +server=/dojin-dl.com/127.0.0.1#5335 +ipset=/dojin-dl.com/gfwlist +server=/agendaweek.com/127.0.0.1#5335 +ipset=/agendaweek.com/gfwlist +server=/mastercard.at/127.0.0.1#5335 +ipset=/mastercard.at/gfwlist +server=/vodafone.com.tr/127.0.0.1#5335 +ipset=/vodafone.com.tr/gfwlist +server=/nikeinstock.com/127.0.0.1#5335 +ipset=/nikeinstock.com/gfwlist +server=/met-nude.com/127.0.0.1#5335 +ipset=/met-nude.com/gfwlist +server=/carstagram.com/127.0.0.1#5335 +ipset=/carstagram.com/gfwlist +server=/lojaiphone.com.br/127.0.0.1#5335 +ipset=/lojaiphone.com.br/gfwlist +server=/bangbros.com/127.0.0.1#5335 +ipset=/bangbros.com/gfwlist +server=/binancezh.kim/127.0.0.1#5335 +ipset=/binancezh.kim/gfwlist +server=/jamanetwork.com/127.0.0.1#5335 +ipset=/jamanetwork.com/gfwlist +server=/chinadigitaltimes.net/127.0.0.1#5335 +ipset=/chinadigitaltimes.net/gfwlist +server=/xxxmovies.pro/127.0.0.1#5335 +ipset=/xxxmovies.pro/gfwlist +server=/kindle.jp/127.0.0.1#5335 +ipset=/kindle.jp/gfwlist +server=/bmwhk.com/127.0.0.1#5335 +ipset=/bmwhk.com/gfwlist +server=/binancezh.biz/127.0.0.1#5335 +ipset=/binancezh.biz/gfwlist +server=/wariowarediy.com/127.0.0.1#5335 +ipset=/wariowarediy.com/gfwlist +server=/xzone.to/127.0.0.1#5335 +ipset=/xzone.to/gfwlist +server=/sony.pt/127.0.0.1#5335 +ipset=/sony.pt/gfwlist +server=/crates.io/127.0.0.1#5335 +ipset=/crates.io/gfwlist +server=/xxxtubenote.com/127.0.0.1#5335 +ipset=/xxxtubenote.com/gfwlist +server=/perfectshemales.com/127.0.0.1#5335 +ipset=/perfectshemales.com/gfwlist +server=/homephoneplus.com/127.0.0.1#5335 +ipset=/homephoneplus.com/gfwlist +server=/wordpress.org/127.0.0.1#5335 +ipset=/wordpress.org/gfwlist +server=/paypass.net/127.0.0.1#5335 +ipset=/paypass.net/gfwlist +server=/eaplay.com/127.0.0.1#5335 +ipset=/eaplay.com/gfwlist +server=/globalsign.com.au/127.0.0.1#5335 +ipset=/globalsign.com.au/gfwlist +server=/bitwarden.com/127.0.0.1#5335 +ipset=/bitwarden.com/gfwlist +server=/xx-map.com/127.0.0.1#5335 +ipset=/xx-map.com/gfwlist +server=/facebooklogin.info/127.0.0.1#5335 +ipset=/facebooklogin.info/gfwlist +server=/dice.se/127.0.0.1#5335 +ipset=/dice.se/gfwlist +server=/milfzr.com/127.0.0.1#5335 +ipset=/milfzr.com/gfwlist +server=/getzola.org/127.0.0.1#5335 +ipset=/getzola.org/gfwlist +server=/elsevier-ae.com/127.0.0.1#5335 +ipset=/elsevier-ae.com/gfwlist +server=/sublimetext.com/127.0.0.1#5335 +ipset=/sublimetext.com/gfwlist +server=/paypal-activate.com/127.0.0.1#5335 +ipset=/paypal-activate.com/gfwlist +server=/xxx-blog.to/127.0.0.1#5335 +ipset=/xxx-blog.to/gfwlist +server=/ero-comic-hunter.net/127.0.0.1#5335 +ipset=/ero-comic-hunter.net/gfwlist +server=/beatsbydreofficialdanmark.com/127.0.0.1#5335 +ipset=/beatsbydreofficialdanmark.com/gfwlist +server=/shopmonsterbeats.com/127.0.0.1#5335 +ipset=/shopmonsterbeats.com/gfwlist +server=/hentai0.com/127.0.0.1#5335 +ipset=/hentai0.com/gfwlist +server=/enemainformation.com/127.0.0.1#5335 +ipset=/enemainformation.com/gfwlist +server=/pearson-anaya.com/127.0.0.1#5335 +ipset=/pearson-anaya.com/gfwlist +server=/ilife.wang/127.0.0.1#5335 +ipset=/ilife.wang/gfwlist +server=/directv-4-you.com/127.0.0.1#5335 +ipset=/directv-4-you.com/gfwlist +server=/ingka.dev/127.0.0.1#5335 +ipset=/ingka.dev/gfwlist +server=/dropbox.com/127.0.0.1#5335 +ipset=/dropbox.com/gfwlist +server=/comeav.com/127.0.0.1#5335 +ipset=/comeav.com/gfwlist +server=/flic.kr/127.0.0.1#5335 +ipset=/flic.kr/gfwlist +server=/ipod.is/127.0.0.1#5335 +ipset=/ipod.is/gfwlist +server=/youtube.com.sg/127.0.0.1#5335 +ipset=/youtube.com.sg/gfwlist +server=/ssl-images-amazon.com/127.0.0.1#5335 +ipset=/ssl-images-amazon.com/gfwlist +server=/apple-pay.rs/127.0.0.1#5335 +ipset=/apple-pay.rs/gfwlist +server=/malayporn.space/127.0.0.1#5335 +ipset=/malayporn.space/gfwlist +server=/hentai-top100.supertop-100.com/127.0.0.1#5335 +ipset=/hentai-top100.supertop-100.com/gfwlist +server=/verizonenterprise.com/127.0.0.1#5335 +ipset=/verizonenterprise.com/gfwlist +server=/xattractive.com/127.0.0.1#5335 +ipset=/xattractive.com/gfwlist +server=/xo.com/127.0.0.1#5335 +ipset=/xo.com/gfwlist +server=/bmwmotorrad.com.sg/127.0.0.1#5335 +ipset=/bmwmotorrad.com.sg/gfwlist +server=/meadjohnson.net/127.0.0.1#5335 +ipset=/meadjohnson.net/gfwlist +server=/uo.com/127.0.0.1#5335 +ipset=/uo.com/gfwlist +server=/jayspov.net/127.0.0.1#5335 +ipset=/jayspov.net/gfwlist +server=/appleinsider.com/127.0.0.1#5335 +ipset=/appleinsider.com/gfwlist +server=/squarefoot.com.hk/127.0.0.1#5335 +ipset=/squarefoot.com.hk/gfwlist +server=/youtube.com.tr/127.0.0.1#5335 +ipset=/youtube.com.tr/gfwlist +server=/beatsshopstore.com/127.0.0.1#5335 +ipset=/beatsshopstore.com/gfwlist +server=/topxxxpornvids.com/127.0.0.1#5335 +ipset=/topxxxpornvids.com/gfwlist +server=/serviporno.com/127.0.0.1#5335 +ipset=/serviporno.com/gfwlist +server=/pornloser.com/127.0.0.1#5335 +ipset=/pornloser.com/gfwlist +server=/dulceecuador.com/127.0.0.1#5335 +ipset=/dulceecuador.com/gfwlist +server=/go.com/127.0.0.1#5335 +ipset=/go.com/gfwlist +server=/hbfile.net/127.0.0.1#5335 +ipset=/hbfile.net/gfwlist +server=/venmo.com/127.0.0.1#5335 +ipset=/venmo.com/gfwlist +server=/marketodesigner.com/127.0.0.1#5335 +ipset=/marketodesigner.com/gfwlist +server=/tidalhifi.com/127.0.0.1#5335 +ipset=/tidalhifi.com/gfwlist +server=/bazel.build/127.0.0.1#5335 +ipset=/bazel.build/gfwlist +server=/wp.com/127.0.0.1#5335 +ipset=/wp.com/gfwlist +server=/bbc-anal.com/127.0.0.1#5335 +ipset=/bbc-anal.com/gfwlist +server=/googlecapital.com/127.0.0.1#5335 +ipset=/googlecapital.com/gfwlist +server=/hp.com/127.0.0.1#5335 +ipset=/hp.com/gfwlist +server=/dreprofy.com/127.0.0.1#5335 +ipset=/dreprofy.com/gfwlist +server=/mastercard.fr/127.0.0.1#5335 +ipset=/mastercard.fr/gfwlist +server=/iphone.wang/127.0.0.1#5335 +ipset=/iphone.wang/gfwlist +server=/amateure-xtreme.com/127.0.0.1#5335 +ipset=/amateure-xtreme.com/gfwlist +server=/milfhunter.com/127.0.0.1#5335 +ipset=/milfhunter.com/gfwlist +server=/nypostreprints.com/127.0.0.1#5335 +ipset=/nypostreprints.com/gfwlist +server=/wixstatic.com/127.0.0.1#5335 +ipset=/wixstatic.com/gfwlist +server=/womenwill.com/127.0.0.1#5335 +ipset=/womenwill.com/gfwlist +server=/whosthehost.com/127.0.0.1#5335 +ipset=/whosthehost.com/gfwlist +server=/coreduo.com/127.0.0.1#5335 +ipset=/coreduo.com/gfwlist +server=/aboutamazon.com/127.0.0.1#5335 +ipset=/aboutamazon.com/gfwlist +server=/beatshopuk.com/127.0.0.1#5335 +ipset=/beatshopuk.com/gfwlist +server=/hqxxxmovies.com/127.0.0.1#5335 +ipset=/hqxxxmovies.com/gfwlist +server=/spicystory.net/127.0.0.1#5335 +ipset=/spicystory.net/gfwlist +server=/googledanmark.com/127.0.0.1#5335 +ipset=/googledanmark.com/gfwlist +server=/youtube.gt/127.0.0.1#5335 +ipset=/youtube.gt/gfwlist +server=/hm.com/127.0.0.1#5335 +ipset=/hm.com/gfwlist +server=/adobetechcommdemo.com/127.0.0.1#5335 +ipset=/adobetechcommdemo.com/gfwlist +server=/hulustream.com/127.0.0.1#5335 +ipset=/hulustream.com/gfwlist +server=/default.exp-tas.com/127.0.0.1#5335 +ipset=/default.exp-tas.com/gfwlist +server=/deluxe.com.hk/127.0.0.1#5335 +ipset=/deluxe.com.hk/gfwlist +server=/javcc.com/127.0.0.1#5335 +ipset=/javcc.com/gfwlist +server=/volvobuses.hk/127.0.0.1#5335 +ipset=/volvobuses.hk/gfwlist +server=/cochranelibrary.com/127.0.0.1#5335 +ipset=/cochranelibrary.com/gfwlist +server=/kenya4.com/127.0.0.1#5335 +ipset=/kenya4.com/gfwlist +server=/itunesparty.com/127.0.0.1#5335 +ipset=/itunesparty.com/gfwlist +server=/underhentai.net/127.0.0.1#5335 +ipset=/underhentai.net/gfwlist +server=/bitchesgirls.com/127.0.0.1#5335 +ipset=/bitchesgirls.com/gfwlist +server=/beatspromotions.com/127.0.0.1#5335 +ipset=/beatspromotions.com/gfwlist +server=/wwwitunes.com/127.0.0.1#5335 +ipset=/wwwitunes.com/gfwlist +server=/dev-guardianapis.com/127.0.0.1#5335 +ipset=/dev-guardianapis.com/gfwlist +server=/54647.online/127.0.0.1#5335 +ipset=/54647.online/gfwlist +server=/momspornvideos.com/127.0.0.1#5335 +ipset=/momspornvideos.com/gfwlist +server=/avstar09.com/127.0.0.1#5335 +ipset=/avstar09.com/gfwlist +server=/nintendo.dk/127.0.0.1#5335 +ipset=/nintendo.dk/gfwlist +server=/newestbeatsbydre.com/127.0.0.1#5335 +ipset=/newestbeatsbydre.com/gfwlist +server=/primemomsex.com/127.0.0.1#5335 +ipset=/primemomsex.com/gfwlist +server=/tryboobs.com/127.0.0.1#5335 +ipset=/tryboobs.com/gfwlist +server=/hulurussia.com/127.0.0.1#5335 +ipset=/hulurussia.com/gfwlist +server=/bangkokbangers.com/127.0.0.1#5335 +ipset=/bangkokbangers.com/gfwlist +server=/coinbase.com/127.0.0.1#5335 +ipset=/coinbase.com/gfwlist +server=/realclearpolicy.com/127.0.0.1#5335 +ipset=/realclearpolicy.com/gfwlist +server=/cloudflareok.com/127.0.0.1#5335 +ipset=/cloudflareok.com/gfwlist +server=/sandisk.in/127.0.0.1#5335 +ipset=/sandisk.in/gfwlist +server=/pki-posta.ch/127.0.0.1#5335 +ipset=/pki-posta.ch/gfwlist +server=/esri.com/127.0.0.1#5335 +ipset=/esri.com/gfwlist +server=/foxnewsaroundtheworld.com/127.0.0.1#5335 +ipset=/foxnewsaroundtheworld.com/gfwlist +server=/thecompaqstore.com/127.0.0.1#5335 +ipset=/thecompaqstore.com/gfwlist +server=/apple-enews.com/127.0.0.1#5335 +ipset=/apple-enews.com/gfwlist +server=/approvedusedbmw.com/127.0.0.1#5335 +ipset=/approvedusedbmw.com/gfwlist +server=/100bucksbabes.com/127.0.0.1#5335 +ipset=/100bucksbabes.com/gfwlist +server=/rexxx.org/127.0.0.1#5335 +ipset=/rexxx.org/gfwlist +server=/gravitytank.com/127.0.0.1#5335 +ipset=/gravitytank.com/gfwlist +server=/javdove.com/127.0.0.1#5335 +ipset=/javdove.com/gfwlist +server=/deutsch-sexfilme.com/127.0.0.1#5335 +ipset=/deutsch-sexfilme.com/gfwlist +server=/rt.com/127.0.0.1#5335 +ipset=/rt.com/gfwlist +server=/razersupport.com/127.0.0.1#5335 +ipset=/razersupport.com/gfwlist +server=/youngpornhd.com/127.0.0.1#5335 +ipset=/youngpornhd.com/gfwlist +server=/instagram-engineering.com/127.0.0.1#5335 +ipset=/instagram-engineering.com/gfwlist +server=/amp.akamaized.net/127.0.0.1#5335 +ipset=/amp.akamaized.net/gfwlist +server=/funnyordie.com/127.0.0.1#5335 +ipset=/funnyordie.com/gfwlist +server=/ft.com/127.0.0.1#5335 +ipset=/ft.com/gfwlist +server=/akamai-thailand.net/127.0.0.1#5335 +ipset=/akamai-thailand.net/gfwlist +server=/cambridgedigital.net/127.0.0.1#5335 +ipset=/cambridgedigital.net/gfwlist +server=/ebay.us/127.0.0.1#5335 +ipset=/ebay.us/gfwlist +server=/ieee-pes.org/127.0.0.1#5335 +ipset=/ieee-pes.org/gfwlist +server=/tsumino.com/127.0.0.1#5335 +ipset=/tsumino.com/gfwlist +server=/badteenspunished.com/127.0.0.1#5335 +ipset=/badteenspunished.com/gfwlist +server=/sony.com.au/127.0.0.1#5335 +ipset=/sony.com.au/gfwlist +server=/siteripz.com/127.0.0.1#5335 +ipset=/siteripz.com/gfwlist +server=/sexuria.com/127.0.0.1#5335 +ipset=/sexuria.com/gfwlist +server=/dezyred.com/127.0.0.1#5335 +ipset=/dezyred.com/gfwlist +server=/beats-sale.com/127.0.0.1#5335 +ipset=/beats-sale.com/gfwlist +server=/pornhat.one/127.0.0.1#5335 +ipset=/pornhat.one/gfwlist +server=/thenewslens.com/127.0.0.1#5335 +ipset=/thenewslens.com/gfwlist +server=/nikebuy.com/127.0.0.1#5335 +ipset=/nikebuy.com/gfwlist +server=/applemx-icloud.com/127.0.0.1#5335 +ipset=/applemx-icloud.com/gfwlist +server=/tr.com/127.0.0.1#5335 +ipset=/tr.com/gfwlist +server=/electronjs.org/127.0.0.1#5335 +ipset=/electronjs.org/gfwlist +server=/uusextoy.com/127.0.0.1#5335 +ipset=/uusextoy.com/gfwlist +server=/google.com.sv/127.0.0.1#5335 +ipset=/google.com.sv/gfwlist +server=/porntoplinks.com/127.0.0.1#5335 +ipset=/porntoplinks.com/gfwlist +server=/proton.me/127.0.0.1#5335 +ipset=/proton.me/gfwlist +server=/faasbook.com/127.0.0.1#5335 +ipset=/faasbook.com/gfwlist +server=/dogfart.com/127.0.0.1#5335 +ipset=/dogfart.com/gfwlist +server=/xvideos2.com/127.0.0.1#5335 +ipset=/xvideos2.com/gfwlist +server=/amazon.sg/127.0.0.1#5335 +ipset=/amazon.sg/gfwlist +server=/nflxext.com/127.0.0.1#5335 +ipset=/nflxext.com/gfwlist +server=/lupoporno.com/127.0.0.1#5335 +ipset=/lupoporno.com/gfwlist +server=/vodafone.co.uk/127.0.0.1#5335 +ipset=/vodafone.co.uk/gfwlist +server=/xgaytube.tv/127.0.0.1#5335 +ipset=/xgaytube.tv/gfwlist +server=/asianthumbs.org/127.0.0.1#5335 +ipset=/asianthumbs.org/gfwlist +server=/ikea.lv/127.0.0.1#5335 +ipset=/ikea.lv/gfwlist +server=/thzu.cc/127.0.0.1#5335 +ipset=/thzu.cc/gfwlist +server=/atscaleconference.com/127.0.0.1#5335 +ipset=/atscaleconference.com/gfwlist +server=/sexdollpornhd.com/127.0.0.1#5335 +ipset=/sexdollpornhd.com/gfwlist +server=/cherrypai.com/127.0.0.1#5335 +ipset=/cherrypai.com/gfwlist +server=/visa.es/127.0.0.1#5335 +ipset=/visa.es/gfwlist +server=/eworld.com/127.0.0.1#5335 +ipset=/eworld.com/gfwlist +server=/meuhentai.com/127.0.0.1#5335 +ipset=/meuhentai.com/gfwlist +server=/auricularesbeatsbaratosshop.com/127.0.0.1#5335 +ipset=/auricularesbeatsbaratosshop.com/gfwlist +server=/3d-xxx.com/127.0.0.1#5335 +ipset=/3d-xxx.com/gfwlist +server=/applestore.cm/127.0.0.1#5335 +ipset=/applestore.cm/gfwlist +server=/dw.com/127.0.0.1#5335 +ipset=/dw.com/gfwlist +server=/hentai-gif-anime.com/127.0.0.1#5335 +ipset=/hentai-gif-anime.com/gfwlist +server=/patreon.com/127.0.0.1#5335 +ipset=/patreon.com/gfwlist +server=/travelex.com.hk/127.0.0.1#5335 +ipset=/travelex.com.hk/gfwlist +server=/eroticbeautyhub.com/127.0.0.1#5335 +ipset=/eroticbeautyhub.com/gfwlist +server=/voaindonesia.com/127.0.0.1#5335 +ipset=/voaindonesia.com/gfwlist +server=/ebayforeclosure.org/127.0.0.1#5335 +ipset=/ebayforeclosure.org/gfwlist +server=/paypal-security.net/127.0.0.1#5335 +ipset=/paypal-security.net/gfwlist +server=/manoto1.tv/127.0.0.1#5335 +ipset=/manoto1.tv/gfwlist +server=/webpkgcache.com/127.0.0.1#5335 +ipset=/webpkgcache.com/gfwlist +server=/yourdirtymind.com/127.0.0.1#5335 +ipset=/yourdirtymind.com/gfwlist +server=/quicktime.com/127.0.0.1#5335 +ipset=/quicktime.com/gfwlist +server=/pornpics.com/127.0.0.1#5335 +ipset=/pornpics.com/gfwlist +server=/volvobuses.sg/127.0.0.1#5335 +ipset=/volvobuses.sg/gfwlist +server=/ikea.ae/127.0.0.1#5335 +ipset=/ikea.ae/gfwlist +server=/europalibera.org/127.0.0.1#5335 +ipset=/europalibera.org/gfwlist +server=/google.co.ma/127.0.0.1#5335 +ipset=/google.co.ma/gfwlist +server=/starbucks.ie/127.0.0.1#5335 +ipset=/starbucks.ie/gfwlist +server=/veetbangladesh.com/127.0.0.1#5335 +ipset=/veetbangladesh.com/gfwlist +server=/ysm.yahoo.com/127.0.0.1#5335 +ipset=/ysm.yahoo.com/gfwlist +server=/disneyarena.com/127.0.0.1#5335 +ipset=/disneyarena.com/gfwlist +server=/globalvoicesonline.org/127.0.0.1#5335 +ipset=/globalvoicesonline.org/gfwlist +server=/hentaifreak.org/127.0.0.1#5335 +ipset=/hentaifreak.org/gfwlist +server=/pricelesssurprises.com/127.0.0.1#5335 +ipset=/pricelesssurprises.com/gfwlist +server=/quiz.directory/127.0.0.1#5335 +ipset=/quiz.directory/gfwlist +server=/lesbian8.com/127.0.0.1#5335 +ipset=/lesbian8.com/gfwlist +server=/sandisk.co.jp/127.0.0.1#5335 +ipset=/sandisk.co.jp/gfwlist +server=/bmw.sk/127.0.0.1#5335 +ipset=/bmw.sk/gfwlist +server=/skillshare.com/127.0.0.1#5335 +ipset=/skillshare.com/gfwlist +server=/sony-olympus-medical.com/127.0.0.1#5335 +ipset=/sony-olympus-medical.com/gfwlist +server=/fuckgames.xxx/127.0.0.1#5335 +ipset=/fuckgames.xxx/gfwlist +server=/zoo-porno.biz/127.0.0.1#5335 +ipset=/zoo-porno.biz/gfwlist +server=/simplyipod.com/127.0.0.1#5335 +ipset=/simplyipod.com/gfwlist +server=/newhampshirebmw.com/127.0.0.1#5335 +ipset=/newhampshirebmw.com/gfwlist +server=/xxxindianporn2.com/127.0.0.1#5335 +ipset=/xxxindianporn2.com/gfwlist +server=/girlfriendgalleries.net/127.0.0.1#5335 +ipset=/girlfriendgalleries.net/gfwlist +server=/hpsupport.com/127.0.0.1#5335 +ipset=/hpsupport.com/gfwlist +server=/bellotube.com/127.0.0.1#5335 +ipset=/bellotube.com/gfwlist +server=/voyeurweb.com/127.0.0.1#5335 +ipset=/voyeurweb.com/gfwlist +server=/fox247.com/127.0.0.1#5335 +ipset=/fox247.com/gfwlist +server=/gv.com/127.0.0.1#5335 +ipset=/gv.com/gfwlist +server=/hdporn92.com/127.0.0.1#5335 +ipset=/hdporn92.com/gfwlist +server=/gaymaletube.com/127.0.0.1#5335 +ipset=/gaymaletube.com/gfwlist +server=/ebayfashion.net/127.0.0.1#5335 +ipset=/ebayfashion.net/gfwlist +server=/fuckableteens.net/127.0.0.1#5335 +ipset=/fuckableteens.net/gfwlist +server=/projectvoyeur.com/127.0.0.1#5335 +ipset=/projectvoyeur.com/gfwlist +server=/google.co.cr/127.0.0.1#5335 +ipset=/google.co.cr/gfwlist +server=/youtube.com.tw/127.0.0.1#5335 +ipset=/youtube.com.tw/gfwlist +server=/excitebots.com/127.0.0.1#5335 +ipset=/excitebots.com/gfwlist +server=/visaconciergelac.com/127.0.0.1#5335 +ipset=/visaconciergelac.com/gfwlist +server=/facebookswagstore.com/127.0.0.1#5335 +ipset=/facebookswagstore.com/gfwlist +server=/mybukkakeporn.com/127.0.0.1#5335 +ipset=/mybukkakeporn.com/gfwlist +server=/static-nike.com/127.0.0.1#5335 +ipset=/static-nike.com/gfwlist +server=/nikestares.com/127.0.0.1#5335 +ipset=/nikestares.com/gfwlist +server=/instagram-brand.com/127.0.0.1#5335 +ipset=/instagram-brand.com/gfwlist +server=/fbreg.com/127.0.0.1#5335 +ipset=/fbreg.com/gfwlist +server=/twitterstat.us/127.0.0.1#5335 +ipset=/twitterstat.us/gfwlist +server=/elpornoamateur.com/127.0.0.1#5335 +ipset=/elpornoamateur.com/gfwlist +server=/easynike.com/127.0.0.1#5335 +ipset=/easynike.com/gfwlist +server=/finevids.xxx/127.0.0.1#5335 +ipset=/finevids.xxx/gfwlist +server=/pinterest.pe/127.0.0.1#5335 +ipset=/pinterest.pe/gfwlist +server=/foxnewsgo.org/127.0.0.1#5335 +ipset=/foxnewsgo.org/gfwlist +server=/sex.cam/127.0.0.1#5335 +ipset=/sex.cam/gfwlist +server=/purextc.com/127.0.0.1#5335 +ipset=/purextc.com/gfwlist +server=/yoursigmoidoscopy.com/127.0.0.1#5335 +ipset=/yoursigmoidoscopy.com/gfwlist +server=/familystrokes.com/127.0.0.1#5335 +ipset=/familystrokes.com/gfwlist +server=/bmw-motorrad.co.id/127.0.0.1#5335 +ipset=/bmw-motorrad.co.id/gfwlist +server=/slackcertified.com/127.0.0.1#5335 +ipset=/slackcertified.com/gfwlist +server=/x-art.com/127.0.0.1#5335 +ipset=/x-art.com/gfwlist +server=/pricelessbeijing.com/127.0.0.1#5335 +ipset=/pricelessbeijing.com/gfwlist +server=/ebaymall.com/127.0.0.1#5335 +ipset=/ebaymall.com/gfwlist +server=/xn--qoq462m.com/127.0.0.1#5335 +ipset=/xn--qoq462m.com/gfwlist +server=/hentaicloud.com/127.0.0.1#5335 +ipset=/hentaicloud.com/gfwlist +server=/mucinexprofessional.com/127.0.0.1#5335 +ipset=/mucinexprofessional.com/gfwlist +server=/yahoo.cm/127.0.0.1#5335 +ipset=/yahoo.cm/gfwlist +server=/fau11.com/127.0.0.1#5335 +ipset=/fau11.com/gfwlist +server=/littleasians.com/127.0.0.1#5335 +ipset=/littleasians.com/gfwlist +server=/hanime1.me/127.0.0.1#5335 +ipset=/hanime1.me/gfwlist +server=/statsmakemecry.com/127.0.0.1#5335 +ipset=/statsmakemecry.com/gfwlist +server=/jorropo.net/127.0.0.1#5335 +ipset=/jorropo.net/gfwlist +server=/billpointnewzealand.com/127.0.0.1#5335 +ipset=/billpointnewzealand.com/gfwlist +server=/gfw.report/127.0.0.1#5335 +ipset=/gfw.report/gfwlist +server=/opensourceinsight.dev/127.0.0.1#5335 +ipset=/opensourceinsight.dev/gfwlist +server=/avatargarenanow-a.akamaihd.net/127.0.0.1#5335 +ipset=/avatargarenanow-a.akamaihd.net/gfwlist +server=/duck.com/127.0.0.1#5335 +ipset=/duck.com/gfwlist +server=/fuck.com/127.0.0.1#5335 +ipset=/fuck.com/gfwlist +server=/starcraft.com/127.0.0.1#5335 +ipset=/starcraft.com/gfwlist +server=/instgram.com/127.0.0.1#5335 +ipset=/instgram.com/gfwlist +server=/netlify.com/127.0.0.1#5335 +ipset=/netlify.com/gfwlist +server=/streamlatina.com/127.0.0.1#5335 +ipset=/streamlatina.com/gfwlist +server=/pornvideos.casa/127.0.0.1#5335 +ipset=/pornvideos.casa/gfwlist +server=/javwide.com/127.0.0.1#5335 +ipset=/javwide.com/gfwlist +server=/facebookhome.cc/127.0.0.1#5335 +ipset=/facebookhome.cc/gfwlist +server=/syzbj36.xyz/127.0.0.1#5335 +ipset=/syzbj36.xyz/gfwlist +server=/apple-expo.com/127.0.0.1#5335 +ipset=/apple-expo.com/gfwlist +server=/akamaitechnologies.com/127.0.0.1#5335 +ipset=/akamaitechnologies.com/gfwlist +server=/tubegold.xxx/127.0.0.1#5335 +ipset=/tubegold.xxx/gfwlist +server=/facesbooc.com/127.0.0.1#5335 +ipset=/facesbooc.com/gfwlist +server=/youtube.sg/127.0.0.1#5335 +ipset=/youtube.sg/gfwlist +server=/vanish.ie/127.0.0.1#5335 +ipset=/vanish.ie/gfwlist +server=/swoosh.com/127.0.0.1#5335 +ipset=/swoosh.com/gfwlist +server=/javscat.net/127.0.0.1#5335 +ipset=/javscat.net/gfwlist +server=/apple.hamburg/127.0.0.1#5335 +ipset=/apple.hamburg/gfwlist +server=/sex.xxx/127.0.0.1#5335 +ipset=/sex.xxx/gfwlist +server=/bitcoin.org/127.0.0.1#5335 +ipset=/bitcoin.org/gfwlist +server=/img-prod-cms-rt-microsoft-com.akamaized.net/127.0.0.1#5335 +ipset=/img-prod-cms-rt-microsoft-com.akamaized.net/gfwlist +server=/linemyshop.com/127.0.0.1#5335 +ipset=/linemyshop.com/gfwlist +server=/disneysubscription.com/127.0.0.1#5335 +ipset=/disneysubscription.com/gfwlist +server=/get.dev/127.0.0.1#5335 +ipset=/get.dev/gfwlist +server=/pornofrog.com/127.0.0.1#5335 +ipset=/pornofrog.com/gfwlist +server=/go-lang.org/127.0.0.1#5335 +ipset=/go-lang.org/gfwlist +server=/tutanota.com/127.0.0.1#5335 +ipset=/tutanota.com/gfwlist +server=/bmw-connecteddrive.my/127.0.0.1#5335 +ipset=/bmw-connecteddrive.my/gfwlist +server=/mini.com.gr/127.0.0.1#5335 +ipset=/mini.com.gr/gfwlist +server=/5lml.com/127.0.0.1#5335 +ipset=/5lml.com/gfwlist +server=/avinin.com/127.0.0.1#5335 +ipset=/avinin.com/gfwlist +server=/familysexsimulator.com/127.0.0.1#5335 +ipset=/familysexsimulator.com/gfwlist +server=/wired.com/127.0.0.1#5335 +ipset=/wired.com/gfwlist +server=/buzzav.com/127.0.0.1#5335 +ipset=/buzzav.com/gfwlist +server=/dettol.com.sg/127.0.0.1#5335 +ipset=/dettol.com.sg/gfwlist +server=/intel.az/127.0.0.1#5335 +ipset=/intel.az/gfwlist +server=/hpservices.com/127.0.0.1#5335 +ipset=/hpservices.com/gfwlist +server=/zeriamerikes.com/127.0.0.1#5335 +ipset=/zeriamerikes.com/gfwlist +server=/fragrancebay.com/127.0.0.1#5335 +ipset=/fragrancebay.com/gfwlist +server=/starbuckssummergame.ca/127.0.0.1#5335 +ipset=/starbuckssummergame.ca/gfwlist +server=/minilondon.co/127.0.0.1#5335 +ipset=/minilondon.co/gfwlist +server=/ads.youtube.com/127.0.0.1#5335 +ipset=/ads.youtube.com/gfwlist +server=/pixinsight.com.tw/127.0.0.1#5335 +ipset=/pixinsight.com.tw/gfwlist +server=/atlasonepoint.com/127.0.0.1#5335 +ipset=/atlasonepoint.com/gfwlist +server=/billpoint.us/127.0.0.1#5335 +ipset=/billpoint.us/gfwlist +server=/holaporno.xxx/127.0.0.1#5335 +ipset=/holaporno.xxx/gfwlist +server=/nijinchu.com/127.0.0.1#5335 +ipset=/nijinchu.com/gfwlist +server=/btt904.com/127.0.0.1#5335 +ipset=/btt904.com/gfwlist +server=/s-msft.com/127.0.0.1#5335 +ipset=/s-msft.com/gfwlist +server=/bmwstepconnections.com/127.0.0.1#5335 +ipset=/bmwstepconnections.com/gfwlist +server=/hotpornbible.com/127.0.0.1#5335 +ipset=/hotpornbible.com/gfwlist +server=/imgcrl.org/127.0.0.1#5335 +ipset=/imgcrl.org/gfwlist +server=/manytoon.com/127.0.0.1#5335 +ipset=/manytoon.com/gfwlist +server=/freehentaistream.com/127.0.0.1#5335 +ipset=/freehentaistream.com/gfwlist +server=/evise.com/127.0.0.1#5335 +ipset=/evise.com/gfwlist +server=/xxx-porn-fuck.com/127.0.0.1#5335 +ipset=/xxx-porn-fuck.com/gfwlist +server=/familysimulator.io/127.0.0.1#5335 +ipset=/familysimulator.io/gfwlist +server=/lgsalesportal.com/127.0.0.1#5335 +ipset=/lgsalesportal.com/gfwlist +server=/beatsfactorycollection.com/127.0.0.1#5335 +ipset=/beatsfactorycollection.com/gfwlist +server=/xlstudio.com/127.0.0.1#5335 +ipset=/xlstudio.com/gfwlist +server=/faapy.com/127.0.0.1#5335 +ipset=/faapy.com/gfwlist +server=/yandex.jobs/127.0.0.1#5335 +ipset=/yandex.jobs/gfwlist +server=/volvobuses.com.tw/127.0.0.1#5335 +ipset=/volvobuses.com.tw/gfwlist +server=/venmo.org/127.0.0.1#5335 +ipset=/venmo.org/gfwlist +server=/illusiony.com/127.0.0.1#5335 +ipset=/illusiony.com/gfwlist +server=/facebookgraphsearch.com/127.0.0.1#5335 +ipset=/facebookgraphsearch.com/gfwlist +server=/racked.com/127.0.0.1#5335 +ipset=/racked.com/gfwlist +server=/viewerswives.net/127.0.0.1#5335 +ipset=/viewerswives.net/gfwlist +server=/thaichix.com/127.0.0.1#5335 +ipset=/thaichix.com/gfwlist +server=/webobjects.co.uk/127.0.0.1#5335 +ipset=/webobjects.co.uk/gfwlist +server=/monsterbeatsforsale.com/127.0.0.1#5335 +ipset=/monsterbeatsforsale.com/gfwlist +server=/xvideosx.com.br/127.0.0.1#5335 +ipset=/xvideosx.com.br/gfwlist +server=/cbsservice.aws.syncbak.com/127.0.0.1#5335 +ipset=/cbsservice.aws.syncbak.com/gfwlist +server=/albastudio.co/127.0.0.1#5335 +ipset=/albastudio.co/gfwlist +server=/fetishpornonly.com/127.0.0.1#5335 +ipset=/fetishpornonly.com/gfwlist +server=/worldhack.com/127.0.0.1#5335 +ipset=/worldhack.com/gfwlist +server=/myfoxchicago.com/127.0.0.1#5335 +ipset=/myfoxchicago.com/gfwlist +server=/fortnite.com/127.0.0.1#5335 +ipset=/fortnite.com/gfwlist +server=/yahoo.is/127.0.0.1#5335 +ipset=/yahoo.is/gfwlist +server=/alphabet.de/127.0.0.1#5335 +ipset=/alphabet.de/gfwlist +server=/yomiuri-johkai.co.jp/127.0.0.1#5335 +ipset=/yomiuri-johkai.co.jp/gfwlist +server=/link2galleries.com/127.0.0.1#5335 +ipset=/link2galleries.com/gfwlist +server=/geforce.co.kr/127.0.0.1#5335 +ipset=/geforce.co.kr/gfwlist +server=/exploitedteensasia.com/127.0.0.1#5335 +ipset=/exploitedteensasia.com/gfwlist +server=/bustyoldsluts.com/127.0.0.1#5335 +ipset=/bustyoldsluts.com/gfwlist +server=/fap-xxx.com/127.0.0.1#5335 +ipset=/fap-xxx.com/gfwlist +server=/geti2p.net/127.0.0.1#5335 +ipset=/geti2p.net/gfwlist +server=/hulu.us/127.0.0.1#5335 +ipset=/hulu.us/gfwlist +server=/comodoca4.com/127.0.0.1#5335 +ipset=/comodoca4.com/gfwlist +server=/spankred3d.com/127.0.0.1#5335 +ipset=/spankred3d.com/gfwlist +server=/scholar.google.com.py/127.0.0.1#5335 +ipset=/scholar.google.com.py/gfwlist +server=/beatsbydrdreoutlet.com/127.0.0.1#5335 +ipset=/beatsbydrdreoutlet.com/gfwlist +server=/myfoxcharlotte.com/127.0.0.1#5335 +ipset=/myfoxcharlotte.com/gfwlist +server=/somanylolies.com/127.0.0.1#5335 +ipset=/somanylolies.com/gfwlist +server=/fulltaboo.tv/127.0.0.1#5335 +ipset=/fulltaboo.tv/gfwlist +server=/letsencrypt.com/127.0.0.1#5335 +ipset=/letsencrypt.com/gfwlist +server=/disneyhentai.com/127.0.0.1#5335 +ipset=/disneyhentai.com/gfwlist +server=/yo1health.com/127.0.0.1#5335 +ipset=/yo1health.com/gfwlist +server=/bcrncdn.com/127.0.0.1#5335 +ipset=/bcrncdn.com/gfwlist +server=/adobeaemcloud.net/127.0.0.1#5335 +ipset=/adobeaemcloud.net/gfwlist +server=/conscrypt.org/127.0.0.1#5335 +ipset=/conscrypt.org/gfwlist +server=/thaigirls.net/127.0.0.1#5335 +ipset=/thaigirls.net/gfwlist +server=/facnbook.com/127.0.0.1#5335 +ipset=/facnbook.com/gfwlist +server=/intercamcashpassport.com.mx/127.0.0.1#5335 +ipset=/intercamcashpassport.com.mx/gfwlist +server=/cloudflare-ipfs.com/127.0.0.1#5335 +ipset=/cloudflare-ipfs.com/gfwlist +server=/ebayca.com/127.0.0.1#5335 +ipset=/ebayca.com/gfwlist +server=/webrtc.org/127.0.0.1#5335 +ipset=/webrtc.org/gfwlist +server=/nikeusa.com/127.0.0.1#5335 +ipset=/nikeusa.com/gfwlist +server=/v2ray.cool/127.0.0.1#5335 +ipset=/v2ray.cool/gfwlist +server=/icloud.ch/127.0.0.1#5335 +ipset=/icloud.ch/gfwlist +server=/ebay.co.ve/127.0.0.1#5335 +ipset=/ebay.co.ve/gfwlist +server=/bmw-jordan.com/127.0.0.1#5335 +ipset=/bmw-jordan.com/gfwlist +server=/canon.hu/127.0.0.1#5335 +ipset=/canon.hu/gfwlist +server=/porn-stalker.fr/127.0.0.1#5335 +ipset=/porn-stalker.fr/gfwlist +server=/topbeatsbydrdreoutlet.com/127.0.0.1#5335 +ipset=/topbeatsbydrdreoutlet.com/gfwlist +server=/microsoft.de/127.0.0.1#5335 +ipset=/microsoft.de/gfwlist +server=/minidurham.ca/127.0.0.1#5335 +ipset=/minidurham.ca/gfwlist +server=/leannecrowvideos.com/127.0.0.1#5335 +ipset=/leannecrowvideos.com/gfwlist +server=/freebasics.com/127.0.0.1#5335 +ipset=/freebasics.com/gfwlist +server=/bmw-albania.com/127.0.0.1#5335 +ipset=/bmw-albania.com/gfwlist +server=/wildxxxhardcore.com/127.0.0.1#5335 +ipset=/wildxxxhardcore.com/gfwlist +server=/blogspot.mk/127.0.0.1#5335 +ipset=/blogspot.mk/gfwlist +server=/drebeats-france.com/127.0.0.1#5335 +ipset=/drebeats-france.com/gfwlist +server=/dagfs.com/127.0.0.1#5335 +ipset=/dagfs.com/gfwlist +server=/paypalshopping.net/127.0.0.1#5335 +ipset=/paypalshopping.net/gfwlist +server=/sex-hot-sites.com/127.0.0.1#5335 +ipset=/sex-hot-sites.com/gfwlist +server=/verisign.com.br/127.0.0.1#5335 +ipset=/verisign.com.br/gfwlist +server=/perfectnaked.com/127.0.0.1#5335 +ipset=/perfectnaked.com/gfwlist +server=/hplip.net/127.0.0.1#5335 +ipset=/hplip.net/gfwlist +server=/animegal.net/127.0.0.1#5335 +ipset=/animegal.net/gfwlist +server=/xxxstreams.eu/127.0.0.1#5335 +ipset=/xxxstreams.eu/gfwlist +server=/chaturbate.com/127.0.0.1#5335 +ipset=/chaturbate.com/gfwlist +server=/nikeclub.com/127.0.0.1#5335 +ipset=/nikeclub.com/gfwlist +server=/kktix.com/127.0.0.1#5335 +ipset=/kktix.com/gfwlist +server=/hotladyhere.com/127.0.0.1#5335 +ipset=/hotladyhere.com/gfwlist +server=/ahvideosexe.com/127.0.0.1#5335 +ipset=/ahvideosexe.com/gfwlist +server=/instagramlogin.com/127.0.0.1#5335 +ipset=/instagramlogin.com/gfwlist +server=/centos.org/127.0.0.1#5335 +ipset=/centos.org/gfwlist +server=/oauthz.com/127.0.0.1#5335 +ipset=/oauthz.com/gfwlist +server=/x1337x.se/127.0.0.1#5335 +ipset=/x1337x.se/gfwlist +server=/mach-os.net/127.0.0.1#5335 +ipset=/mach-os.net/gfwlist +server=/tsmodelstube.com/127.0.0.1#5335 +ipset=/tsmodelstube.com/gfwlist +server=/hornygfporn.com/127.0.0.1#5335 +ipset=/hornygfporn.com/gfwlist +server=/gloryofheracles.com/127.0.0.1#5335 +ipset=/gloryofheracles.com/gfwlist +server=/booksc.me/127.0.0.1#5335 +ipset=/booksc.me/gfwlist +server=/eca.hinet.net/127.0.0.1#5335 +ipset=/eca.hinet.net/gfwlist +server=/vkontakte.ru/127.0.0.1#5335 +ipset=/vkontakte.ru/gfwlist +server=/crit-staging.com/127.0.0.1#5335 +ipset=/crit-staging.com/gfwlist +server=/fabuyemian.com/127.0.0.1#5335 +ipset=/fabuyemian.com/gfwlist +server=/yourdoll.com/127.0.0.1#5335 +ipset=/yourdoll.com/gfwlist +server=/beatsua.com/127.0.0.1#5335 +ipset=/beatsua.com/gfwlist +server=/newtalk.tw/127.0.0.1#5335 +ipset=/newtalk.tw/gfwlist +server=/nikeshoesmarket.com/127.0.0.1#5335 +ipset=/nikeshoesmarket.com/gfwlist +server=/petiteballerinasfucked.com/127.0.0.1#5335 +ipset=/petiteballerinasfucked.com/gfwlist +server=/vimeo.fr/127.0.0.1#5335 +ipset=/vimeo.fr/gfwlist +server=/mastercard.pt/127.0.0.1#5335 +ipset=/mastercard.pt/gfwlist +server=/nikegenealogy.com/127.0.0.1#5335 +ipset=/nikegenealogy.com/gfwlist +server=/yahoo.com.sg/127.0.0.1#5335 +ipset=/yahoo.com.sg/gfwlist +server=/windy.com/127.0.0.1#5335 +ipset=/windy.com/gfwlist +server=/sony.lt/127.0.0.1#5335 +ipset=/sony.lt/gfwlist +server=/facebookcoronavirus.com/127.0.0.1#5335 +ipset=/facebookcoronavirus.com/gfwlist +server=/livephotos.tv/127.0.0.1#5335 +ipset=/livephotos.tv/gfwlist +server=/att-japan.com/127.0.0.1#5335 +ipset=/att-japan.com/gfwlist +server=/ikea.com.gr/127.0.0.1#5335 +ipset=/ikea.com.gr/gfwlist +server=/zeit.co/127.0.0.1#5335 +ipset=/zeit.co/gfwlist +server=/hairyclassic.com/127.0.0.1#5335 +ipset=/hairyclassic.com/gfwlist +server=/zeitworld.com/127.0.0.1#5335 +ipset=/zeitworld.com/gfwlist +server=/gaymenring.com/127.0.0.1#5335 +ipset=/gaymenring.com/gfwlist +server=/liberapay.org/127.0.0.1#5335 +ipset=/liberapay.org/gfwlist +server=/independentoperatorcn.com/127.0.0.1#5335 +ipset=/independentoperatorcn.com/gfwlist +server=/javscatting.com/127.0.0.1#5335 +ipset=/javscatting.com/gfwlist +server=/rakuten-static.com/127.0.0.1#5335 +ipset=/rakuten-static.com/gfwlist +server=/s-bluemix.net/127.0.0.1#5335 +ipset=/s-bluemix.net/gfwlist +server=/primevideo.tv/127.0.0.1#5335 +ipset=/primevideo.tv/gfwlist +server=/javbus22.com/127.0.0.1#5335 +ipset=/javbus22.com/gfwlist +server=/visa.ca/127.0.0.1#5335 +ipset=/visa.ca/gfwlist +server=/directvhouston.com/127.0.0.1#5335 +ipset=/directvhouston.com/gfwlist +server=/gloryholeswallow.com/127.0.0.1#5335 +ipset=/gloryholeswallow.com/gfwlist +server=/ebayglobalshipping.com/127.0.0.1#5335 +ipset=/ebayglobalshipping.com/gfwlist +server=/ozeex.com/127.0.0.1#5335 +ipset=/ozeex.com/gfwlist +server=/donsnaughtymodels.com/127.0.0.1#5335 +ipset=/donsnaughtymodels.com/gfwlist +server=/facebo-ok.com/127.0.0.1#5335 +ipset=/facebo-ok.com/gfwlist +server=/anime-rule34-world.b-cdn.net/127.0.0.1#5335 +ipset=/anime-rule34-world.b-cdn.net/gfwlist +server=/dropboxforum.com/127.0.0.1#5335 +ipset=/dropboxforum.com/gfwlist +server=/mini.nc/127.0.0.1#5335 +ipset=/mini.nc/gfwlist +server=/taiwannews.com.tw/127.0.0.1#5335 +ipset=/taiwannews.com.tw/gfwlist +server=/paypal-europe.com/127.0.0.1#5335 +ipset=/paypal-europe.com/gfwlist +server=/reallesbianexposed.com/127.0.0.1#5335 +ipset=/reallesbianexposed.com/gfwlist +server=/discordsays.com/127.0.0.1#5335 +ipset=/discordsays.com/gfwlist +server=/bmwdelawarevalley.com/127.0.0.1#5335 +ipset=/bmwdelawarevalley.com/gfwlist +server=/haisetu.net/127.0.0.1#5335 +ipset=/haisetu.net/gfwlist +server=/casquebeatsbydrdresolohd.com/127.0.0.1#5335 +ipset=/casquebeatsbydrdresolohd.com/gfwlist +server=/icloud.com/127.0.0.1#5335 +ipset=/icloud.com/gfwlist +server=/extraindiansex.com/127.0.0.1#5335 +ipset=/extraindiansex.com/gfwlist +server=/abow.jp/127.0.0.1#5335 +ipset=/abow.jp/gfwlist +server=/plusone8.com/127.0.0.1#5335 +ipset=/plusone8.com/gfwlist +server=/appleonline.com/127.0.0.1#5335 +ipset=/appleonline.com/gfwlist +server=/famouspornstars.com/127.0.0.1#5335 +ipset=/famouspornstars.com/gfwlist +server=/shopee.io/127.0.0.1#5335 +ipset=/shopee.io/gfwlist +server=/publicsexhub.com/127.0.0.1#5335 +ipset=/publicsexhub.com/gfwlist +server=/yandex.ru/127.0.0.1#5335 +ipset=/yandex.ru/gfwlist +server=/amateur-pussies.com/127.0.0.1#5335 +ipset=/amateur-pussies.com/gfwlist +server=/nikeshoescity.com/127.0.0.1#5335 +ipset=/nikeshoescity.com/gfwlist +server=/amazonaws.co.uk/127.0.0.1#5335 +ipset=/amazonaws.co.uk/gfwlist +server=/lgappstv.com/127.0.0.1#5335 +ipset=/lgappstv.com/gfwlist +server=/beatsbydresaleonlines-nz.com/127.0.0.1#5335 +ipset=/beatsbydresaleonlines-nz.com/gfwlist +server=/microsoftadc.com/127.0.0.1#5335 +ipset=/microsoftadc.com/gfwlist +server=/tps138.info/127.0.0.1#5335 +ipset=/tps138.info/gfwlist +server=/onmanorama.com/127.0.0.1#5335 +ipset=/onmanorama.com/gfwlist +server=/bmw.rs/127.0.0.1#5335 +ipset=/bmw.rs/gfwlist +server=/rarbg.me/127.0.0.1#5335 +ipset=/rarbg.me/gfwlist +server=/joinside.org/127.0.0.1#5335 +ipset=/joinside.org/gfwlist +server=/girlsxxx.net/127.0.0.1#5335 +ipset=/girlsxxx.net/gfwlist +server=/kamisama-day.jp/127.0.0.1#5335 +ipset=/kamisama-day.jp/gfwlist +server=/hpcomputers.com/127.0.0.1#5335 +ipset=/hpcomputers.com/gfwlist +server=/linearcollider.org/127.0.0.1#5335 +ipset=/linearcollider.org/gfwlist +server=/lizardporn.com/127.0.0.1#5335 +ipset=/lizardporn.com/gfwlist +server=/youtube.co.at/127.0.0.1#5335 +ipset=/youtube.co.at/gfwlist +server=/youtube.rs/127.0.0.1#5335 +ipset=/youtube.rs/gfwlist +server=/bestpremiumpornsite.com/127.0.0.1#5335 +ipset=/bestpremiumpornsite.com/gfwlist +server=/dweb.link/127.0.0.1#5335 +ipset=/dweb.link/gfwlist +server=/youtube.co.cr/127.0.0.1#5335 +ipset=/youtube.co.cr/gfwlist +server=/facwebook.com/127.0.0.1#5335 +ipset=/facwebook.com/gfwlist +server=/akastream.com/127.0.0.1#5335 +ipset=/akastream.com/gfwlist +server=/createspace.com/127.0.0.1#5335 +ipset=/createspace.com/gfwlist +server=/volvotrucks.nl/127.0.0.1#5335 +ipset=/volvotrucks.nl/gfwlist +server=/instagramizlenme.com/127.0.0.1#5335 +ipset=/instagramizlenme.com/gfwlist +server=/earngeek.com/127.0.0.1#5335 +ipset=/earngeek.com/gfwlist +server=/googleapis.com/127.0.0.1#5335 +ipset=/googleapis.com/gfwlist +server=/beatspillnewcolor.com/127.0.0.1#5335 +ipset=/beatspillnewcolor.com/gfwlist +server=/sandisk.co.uk/127.0.0.1#5335 +ipset=/sandisk.co.uk/gfwlist +server=/positivessl.com/127.0.0.1#5335 +ipset=/positivessl.com/gfwlist +server=/shyav.com/127.0.0.1#5335 +ipset=/shyav.com/gfwlist +server=/mariobroswii.com/127.0.0.1#5335 +ipset=/mariobroswii.com/gfwlist +server=/pornodrome.tv/127.0.0.1#5335 +ipset=/pornodrome.tv/gfwlist +server=/pearsonassessment.nl/127.0.0.1#5335 +ipset=/pearsonassessment.nl/gfwlist +server=/xvideos-porn-video.com/127.0.0.1#5335 +ipset=/xvideos-porn-video.com/gfwlist +server=/vfsco.pl/127.0.0.1#5335 +ipset=/vfsco.pl/gfwlist +server=/briantreepayments.tv/127.0.0.1#5335 +ipset=/briantreepayments.tv/gfwlist +server=/bmw-motorrad.dz/127.0.0.1#5335 +ipset=/bmw-motorrad.dz/gfwlist +server=/bloombergnext.com/127.0.0.1#5335 +ipset=/bloombergnext.com/gfwlist +server=/beatsbydreoordopjes.com/127.0.0.1#5335 +ipset=/beatsbydreoordopjes.com/gfwlist +server=/touchsmartpc.com/127.0.0.1#5335 +ipset=/touchsmartpc.com/gfwlist +server=/freefblikes.com/127.0.0.1#5335 +ipset=/freefblikes.com/gfwlist +server=/youtubego.id/127.0.0.1#5335 +ipset=/youtubego.id/gfwlist +server=/appdomain.cloud/127.0.0.1#5335 +ipset=/appdomain.cloud/gfwlist +server=/pornmadeathome.com/127.0.0.1#5335 +ipset=/pornmadeathome.com/gfwlist +server=/applecentar.co.rs/127.0.0.1#5335 +ipset=/applecentar.co.rs/gfwlist +server=/oncars.in/127.0.0.1#5335 +ipset=/oncars.in/gfwlist +server=/fontshop-prod-responsive-images.s3.amazonaws.com/127.0.0.1#5335 +ipset=/fontshop-prod-responsive-images.s3.amazonaws.com/gfwlist +server=/applepay.berlin/127.0.0.1#5335 +ipset=/applepay.berlin/gfwlist +server=/cnnmoneystream.com/127.0.0.1#5335 +ipset=/cnnmoneystream.com/gfwlist +server=/bridgestonetire.com/127.0.0.1#5335 +ipset=/bridgestonetire.com/gfwlist +server=/adidas.hu/127.0.0.1#5335 +ipset=/adidas.hu/gfwlist +server=/telebay.com/127.0.0.1#5335 +ipset=/telebay.com/gfwlist +server=/bingagencyawards.com/127.0.0.1#5335 +ipset=/bingagencyawards.com/gfwlist +server=/thebeatsbydre.com/127.0.0.1#5335 +ipset=/thebeatsbydre.com/gfwlist +server=/ikea.my/127.0.0.1#5335 +ipset=/ikea.my/gfwlist +server=/rule34h.com/127.0.0.1#5335 +ipset=/rule34h.com/gfwlist +server=/facebookmsn.com/127.0.0.1#5335 +ipset=/facebookmsn.com/gfwlist +server=/facebookporn.org/127.0.0.1#5335 +ipset=/facebookporn.org/gfwlist +server=/globalsign.net/127.0.0.1#5335 +ipset=/globalsign.net/gfwlist +server=/billmelater.com/127.0.0.1#5335 +ipset=/billmelater.com/gfwlist +server=/libgen.st/127.0.0.1#5335 +ipset=/libgen.st/gfwlist +server=/xinfhw.com/127.0.0.1#5335 +ipset=/xinfhw.com/gfwlist +server=/bmw-asia.com/127.0.0.1#5335 +ipset=/bmw-asia.com/gfwlist +server=/pixiv.org/127.0.0.1#5335 +ipset=/pixiv.org/gfwlist +server=/downloadsforipod.com/127.0.0.1#5335 +ipset=/downloadsforipod.com/gfwlist +server=/alphabet.lv/127.0.0.1#5335 +ipset=/alphabet.lv/gfwlist +server=/pornxvideos.win/127.0.0.1#5335 +ipset=/pornxvideos.win/gfwlist +server=/free-aa.com/127.0.0.1#5335 +ipset=/free-aa.com/gfwlist +server=/sislovesme.com/127.0.0.1#5335 +ipset=/sislovesme.com/gfwlist +server=/cbspressexpress.com/127.0.0.1#5335 +ipset=/cbspressexpress.com/gfwlist +server=/hex.pm/127.0.0.1#5335 +ipset=/hex.pm/gfwlist +server=/sanspo.com/127.0.0.1#5335 +ipset=/sanspo.com/gfwlist +server=/ptt.sex/127.0.0.1#5335 +ipset=/ptt.sex/gfwlist +server=/mingpaomonthly.com/127.0.0.1#5335 +ipset=/mingpaomonthly.com/gfwlist +server=/titanfall.com/127.0.0.1#5335 +ipset=/titanfall.com/gfwlist +server=/durex.ro/127.0.0.1#5335 +ipset=/durex.ro/gfwlist +server=/momsbangteens.com/127.0.0.1#5335 +ipset=/momsbangteens.com/gfwlist +server=/realmaturesfuck.com/127.0.0.1#5335 +ipset=/realmaturesfuck.com/gfwlist +server=/12diasderegalosdeitunes.co.cr/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.co.cr/gfwlist +server=/xnxx2.info/127.0.0.1#5335 +ipset=/xnxx2.info/gfwlist +server=/thegatewaypundit.com/127.0.0.1#5335 +ipset=/thegatewaypundit.com/gfwlist +server=/zononi.com/127.0.0.1#5335 +ipset=/zononi.com/gfwlist +server=/amazonauthorinsights.com/127.0.0.1#5335 +ipset=/amazonauthorinsights.com/gfwlist +server=/vrbgay.com/127.0.0.1#5335 +ipset=/vrbgay.com/gfwlist +server=/xn--fiqs8sxootzz.xn--hxt814e/127.0.0.1#5335 +ipset=/xn--fiqs8sxootzz.xn--hxt814e/gfwlist +server=/nintendowii.com/127.0.0.1#5335 +ipset=/nintendowii.com/gfwlist +server=/oculusforbusiness.com/127.0.0.1#5335 +ipset=/oculusforbusiness.com/gfwlist +server=/xxnxx-porn.com/127.0.0.1#5335 +ipset=/xxnxx-porn.com/gfwlist +server=/vokevr.com/127.0.0.1#5335 +ipset=/vokevr.com/gfwlist +server=/accountpaypal.net/127.0.0.1#5335 +ipset=/accountpaypal.net/gfwlist +server=/shelfstuff.com/127.0.0.1#5335 +ipset=/shelfstuff.com/gfwlist +server=/facebookatschool.com/127.0.0.1#5335 +ipset=/facebookatschool.com/gfwlist +server=/yourmomsgotbigtits.com/127.0.0.1#5335 +ipset=/yourmomsgotbigtits.com/gfwlist +server=/applexpo.net/127.0.0.1#5335 +ipset=/applexpo.net/gfwlist +server=/justmysocks1.net/127.0.0.1#5335 +ipset=/justmysocks1.net/gfwlist +server=/weeklytimesnow.com.au/127.0.0.1#5335 +ipset=/weeklytimesnow.com.au/gfwlist +server=/hotfiesta.com/127.0.0.1#5335 +ipset=/hotfiesta.com/gfwlist +server=/pixplug.in/127.0.0.1#5335 +ipset=/pixplug.in/gfwlist +server=/smallteenpussy.com/127.0.0.1#5335 +ipset=/smallteenpussy.com/gfwlist +server=/line.biz/127.0.0.1#5335 +ipset=/line.biz/gfwlist +server=/usa-beatsbydreheadphonesonsale.net/127.0.0.1#5335 +ipset=/usa-beatsbydreheadphonesonsale.net/gfwlist +server=/mingpaotor.com/127.0.0.1#5335 +ipset=/mingpaotor.com/gfwlist +server=/erodoujinshi-world.com/127.0.0.1#5335 +ipset=/erodoujinshi-world.com/gfwlist +server=/akahost.net/127.0.0.1#5335 +ipset=/akahost.net/gfwlist +server=/mythicentertainment.net/127.0.0.1#5335 +ipset=/mythicentertainment.net/gfwlist +server=/vervesex.com/127.0.0.1#5335 +ipset=/vervesex.com/gfwlist +server=/bluemix.net/127.0.0.1#5335 +ipset=/bluemix.net/gfwlist +server=/12diasderegalosdeitunes.com/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.com/gfwlist +server=/half.tv/127.0.0.1#5335 +ipset=/half.tv/gfwlist +server=/microsoftadvertising.com/127.0.0.1#5335 +ipset=/microsoftadvertising.com/gfwlist +server=/vidown.com/127.0.0.1#5335 +ipset=/vidown.com/gfwlist +server=/cnet.com/127.0.0.1#5335 +ipset=/cnet.com/gfwlist +server=/spacex.com/127.0.0.1#5335 +ipset=/spacex.com/gfwlist +server=/freegaysexgames.com/127.0.0.1#5335 +ipset=/freegaysexgames.com/gfwlist +server=/ikea.jo/127.0.0.1#5335 +ipset=/ikea.jo/gfwlist +server=/starbucks.com.sg/127.0.0.1#5335 +ipset=/starbucks.com.sg/gfwlist +server=/nikefrance.com/127.0.0.1#5335 +ipset=/nikefrance.com/gfwlist +server=/justduckit.com/127.0.0.1#5335 +ipset=/justduckit.com/gfwlist +server=/bmw-drivingexperience.com/127.0.0.1#5335 +ipset=/bmw-drivingexperience.com/gfwlist +server=/bypasscensorship.org/127.0.0.1#5335 +ipset=/bypasscensorship.org/gfwlist +server=/hbo.map.fastly.net/127.0.0.1#5335 +ipset=/hbo.map.fastly.net/gfwlist +server=/zoho.in/127.0.0.1#5335 +ipset=/zoho.in/gfwlist +server=/fapporn.me/127.0.0.1#5335 +ipset=/fapporn.me/gfwlist +server=/etpress.com.hk/127.0.0.1#5335 +ipset=/etpress.com.hk/gfwlist +server=/ebayclassifieds.tv/127.0.0.1#5335 +ipset=/ebayclassifieds.tv/gfwlist +server=/neuerporno.com/127.0.0.1#5335 +ipset=/neuerporno.com/gfwlist +server=/ozvoice.org/127.0.0.1#5335 +ipset=/ozvoice.org/gfwlist +server=/thedailysnkr.com/127.0.0.1#5335 +ipset=/thedailysnkr.com/gfwlist +server=/jkforum.net/127.0.0.1#5335 +ipset=/jkforum.net/gfwlist +server=/finishinfo.it/127.0.0.1#5335 +ipset=/finishinfo.it/gfwlist +server=/teensnow.com/127.0.0.1#5335 +ipset=/teensnow.com/gfwlist +server=/americasvoice.news/127.0.0.1#5335 +ipset=/americasvoice.news/gfwlist +server=/redis.io/127.0.0.1#5335 +ipset=/redis.io/gfwlist +server=/liverail.com/127.0.0.1#5335 +ipset=/liverail.com/gfwlist +server=/hbomaxdash.s.llnwi.net/127.0.0.1#5335 +ipset=/hbomaxdash.s.llnwi.net/gfwlist +server=/contest.com/127.0.0.1#5335 +ipset=/contest.com/gfwlist +server=/githubassets.com/127.0.0.1#5335 +ipset=/githubassets.com/gfwlist +server=/pahabicilemezsurprizler.com/127.0.0.1#5335 +ipset=/pahabicilemezsurprizler.com/gfwlist +server=/verisign.dk/127.0.0.1#5335 +ipset=/verisign.dk/gfwlist +server=/beatswholesale.us/127.0.0.1#5335 +ipset=/beatswholesale.us/gfwlist +server=/swissign.li/127.0.0.1#5335 +ipset=/swissign.li/gfwlist +server=/stepmaturesex.com/127.0.0.1#5335 +ipset=/stepmaturesex.com/gfwlist +server=/iphoneplus.wang/127.0.0.1#5335 +ipset=/iphoneplus.wang/gfwlist +server=/stripselector.com/127.0.0.1#5335 +ipset=/stripselector.com/gfwlist +server=/ituneslogin.net/127.0.0.1#5335 +ipset=/ituneslogin.net/gfwlist +server=/instituteofwar.org/127.0.0.1#5335 +ipset=/instituteofwar.org/gfwlist +server=/javhub.net/127.0.0.1#5335 +ipset=/javhub.net/gfwlist +server=/whimn.com.au/127.0.0.1#5335 +ipset=/whimn.com.au/gfwlist +server=/indiansexmms2.com/127.0.0.1#5335 +ipset=/indiansexmms2.com/gfwlist +server=/weekly-economist.com/127.0.0.1#5335 +ipset=/weekly-economist.com/gfwlist +server=/volvotrucks.kg/127.0.0.1#5335 +ipset=/volvotrucks.kg/gfwlist +server=/watch-ebay.org/127.0.0.1#5335 +ipset=/watch-ebay.org/gfwlist +server=/facebook-forum.com/127.0.0.1#5335 +ipset=/facebook-forum.com/gfwlist +server=/uplay.com/127.0.0.1#5335 +ipset=/uplay.com/gfwlist +server=/outletnike.com/127.0.0.1#5335 +ipset=/outletnike.com/gfwlist +server=/mini.tn/127.0.0.1#5335 +ipset=/mini.tn/gfwlist +server=/hket.com/127.0.0.1#5335 +ipset=/hket.com/gfwlist +server=/nke6.com/127.0.0.1#5335 +ipset=/nke6.com/gfwlist +server=/intel.ie/127.0.0.1#5335 +ipset=/intel.ie/gfwlist +server=/dirtyship.com/127.0.0.1#5335 +ipset=/dirtyship.com/gfwlist +server=/colombianas.webcam/127.0.0.1#5335 +ipset=/colombianas.webcam/gfwlist +server=/fonts.com/127.0.0.1#5335 +ipset=/fonts.com/gfwlist +server=/porn-discounts.com/127.0.0.1#5335 +ipset=/porn-discounts.com/gfwlist +server=/mit.net/127.0.0.1#5335 +ipset=/mit.net/gfwlist +server=/365buymy.com/127.0.0.1#5335 +ipset=/365buymy.com/gfwlist +server=/huluad.com/127.0.0.1#5335 +ipset=/huluad.com/gfwlist +server=/golos-ameriki.ru/127.0.0.1#5335 +ipset=/golos-ameriki.ru/gfwlist +server=/bmwspecialoffers.ca/127.0.0.1#5335 +ipset=/bmwspecialoffers.ca/gfwlist +server=/sego8.cc/127.0.0.1#5335 +ipset=/sego8.cc/gfwlist +server=/pearson.fr/127.0.0.1#5335 +ipset=/pearson.fr/gfwlist +server=/yahoo.mw/127.0.0.1#5335 +ipset=/yahoo.mw/gfwlist +server=/autumn-jade.com/127.0.0.1#5335 +ipset=/autumn-jade.com/gfwlist +server=/fury.io/127.0.0.1#5335 +ipset=/fury.io/gfwlist +server=/amateurpornonly.com/127.0.0.1#5335 +ipset=/amateurpornonly.com/gfwlist +server=/highcolonic.info/127.0.0.1#5335 +ipset=/highcolonic.info/gfwlist +server=/appleinclegal.com/127.0.0.1#5335 +ipset=/appleinclegal.com/gfwlist +server=/hornysexgame.com/127.0.0.1#5335 +ipset=/hornysexgame.com/gfwlist +server=/bmw-group.net/127.0.0.1#5335 +ipset=/bmw-group.net/gfwlist +server=/hentaibros.com/127.0.0.1#5335 +ipset=/hentaibros.com/gfwlist +server=/52fuliji.cc/127.0.0.1#5335 +ipset=/52fuliji.cc/gfwlist +server=/att.net/127.0.0.1#5335 +ipset=/att.net/gfwlist +server=/bmw.lk/127.0.0.1#5335 +ipset=/bmw.lk/gfwlist +server=/nextdigital.com.hk/127.0.0.1#5335 +ipset=/nextdigital.com.hk/gfwlist +server=/gayasiantheater.com/127.0.0.1#5335 +ipset=/gayasiantheater.com/gfwlist +server=/microsoft.hu/127.0.0.1#5335 +ipset=/microsoft.hu/gfwlist +server=/debank.com/127.0.0.1#5335 +ipset=/debank.com/gfwlist +server=/beats-bydreoutletonline.com/127.0.0.1#5335 +ipset=/beats-bydreoutletonline.com/gfwlist +server=/1337xx.to/127.0.0.1#5335 +ipset=/1337xx.to/gfwlist +server=/page.link/127.0.0.1#5335 +ipset=/page.link/gfwlist +server=/gputechconf.com.au/127.0.0.1#5335 +ipset=/gputechconf.com.au/gfwlist +server=/oath.cloud/127.0.0.1#5335 +ipset=/oath.cloud/gfwlist +server=/paypal-apps.com/127.0.0.1#5335 +ipset=/paypal-apps.com/gfwlist +server=/newenergyfinance.com/127.0.0.1#5335 +ipset=/newenergyfinance.com/gfwlist +server=/hpconnected.us/127.0.0.1#5335 +ipset=/hpconnected.us/gfwlist +server=/applepaysupplies.tv/127.0.0.1#5335 +ipset=/applepaysupplies.tv/gfwlist +server=/volvobuses.com.pt/127.0.0.1#5335 +ipset=/volvobuses.com.pt/gfwlist +server=/airwick.es/127.0.0.1#5335 +ipset=/airwick.es/gfwlist +server=/speedrun.com/127.0.0.1#5335 +ipset=/speedrun.com/gfwlist +server=/google.ht/127.0.0.1#5335 +ipset=/google.ht/gfwlist +server=/lewdvrgames.com/127.0.0.1#5335 +ipset=/lewdvrgames.com/gfwlist +server=/hdpornt.com/127.0.0.1#5335 +ipset=/hdpornt.com/gfwlist +server=/disneyinternational.com/127.0.0.1#5335 +ipset=/disneyinternational.com/gfwlist +server=/masterintelligence.com/127.0.0.1#5335 +ipset=/masterintelligence.com/gfwlist +server=/deepl.com/127.0.0.1#5335 +ipset=/deepl.com/gfwlist +server=/paypal-team.com/127.0.0.1#5335 +ipset=/paypal-team.com/gfwlist +server=/instagramtakiphilesi.com/127.0.0.1#5335 +ipset=/instagramtakiphilesi.com/gfwlist +server=/pornpros.com/127.0.0.1#5335 +ipset=/pornpros.com/gfwlist +server=/2gayboys.com/127.0.0.1#5335 +ipset=/2gayboys.com/gfwlist +server=/afpforum.com/127.0.0.1#5335 +ipset=/afpforum.com/gfwlist +server=/bigtopsites.com/127.0.0.1#5335 +ipset=/bigtopsites.com/gfwlist +server=/anime-tube.pw/127.0.0.1#5335 +ipset=/anime-tube.pw/gfwlist +server=/eropasture.com/127.0.0.1#5335 +ipset=/eropasture.com/gfwlist +server=/twitteroauth.com/127.0.0.1#5335 +ipset=/twitteroauth.com/gfwlist +server=/scholar.google.de/127.0.0.1#5335 +ipset=/scholar.google.de/gfwlist +server=/ohsexfilm.com/127.0.0.1#5335 +ipset=/ohsexfilm.com/gfwlist +server=/gateway.pinata.cloud/127.0.0.1#5335 +ipset=/gateway.pinata.cloud/gfwlist +server=/minneapolisbmw.com/127.0.0.1#5335 +ipset=/minneapolisbmw.com/gfwlist +server=/pokemongoldsilver.com/127.0.0.1#5335 +ipset=/pokemongoldsilver.com/gfwlist +server=/hpdriver.com/127.0.0.1#5335 +ipset=/hpdriver.com/gfwlist +server=/valvesoftware.com/127.0.0.1#5335 +ipset=/valvesoftware.com/gfwlist +server=/rsshub.app/127.0.0.1#5335 +ipset=/rsshub.app/gfwlist +server=/beatsbydrdre-headphones.com/127.0.0.1#5335 +ipset=/beatsbydrdre-headphones.com/gfwlist +server=/0emm.com/127.0.0.1#5335 +ipset=/0emm.com/gfwlist +server=/shopify.dev/127.0.0.1#5335 +ipset=/shopify.dev/gfwlist +server=/xn--74q035i.xn--hxt814e/127.0.0.1#5335 +ipset=/xn--74q035i.xn--hxt814e/gfwlist +server=/calendarserver.org/127.0.0.1#5335 +ipset=/calendarserver.org/gfwlist +server=/anysex.com/127.0.0.1#5335 +ipset=/anysex.com/gfwlist +server=/d2anahhhmp1ffz.cloudfront.net/127.0.0.1#5335 +ipset=/d2anahhhmp1ffz.cloudfront.net/gfwlist +server=/snapwebcams.com/127.0.0.1#5335 +ipset=/snapwebcams.com/gfwlist +server=/dis.gd/127.0.0.1#5335 +ipset=/dis.gd/gfwlist +server=/foxsoccershop.com/127.0.0.1#5335 +ipset=/foxsoccershop.com/gfwlist +server=/fbhome.com/127.0.0.1#5335 +ipset=/fbhome.com/gfwlist +server=/ohpornovideo.com/127.0.0.1#5335 +ipset=/ohpornovideo.com/gfwlist +server=/terapeak.info/127.0.0.1#5335 +ipset=/terapeak.info/gfwlist +server=/privatemarketplaces.us/127.0.0.1#5335 +ipset=/privatemarketplaces.us/gfwlist +server=/typenetwork.com/127.0.0.1#5335 +ipset=/typenetwork.com/gfwlist +server=/bastropfirestone.com/127.0.0.1#5335 +ipset=/bastropfirestone.com/gfwlist +server=/beurettesvideo.com/127.0.0.1#5335 +ipset=/beurettesvideo.com/gfwlist +server=/mini-lebanon.com/127.0.0.1#5335 +ipset=/mini-lebanon.com/gfwlist +server=/paradisehotelquizfox.com/127.0.0.1#5335 +ipset=/paradisehotelquizfox.com/gfwlist +server=/buypass-ssl.com/127.0.0.1#5335 +ipset=/buypass-ssl.com/gfwlist +server=/newsgawakaru.com/127.0.0.1#5335 +ipset=/newsgawakaru.com/gfwlist +server=/www-paypal.info/127.0.0.1#5335 +ipset=/www-paypal.info/gfwlist +server=/ipod.ru/127.0.0.1#5335 +ipset=/ipod.ru/gfwlist +server=/demdex.net/127.0.0.1#5335 +ipset=/demdex.net/gfwlist +server=/deps.dev/127.0.0.1#5335 +ipset=/deps.dev/gfwlist +server=/cosplayeromania.jp/127.0.0.1#5335 +ipset=/cosplayeromania.jp/gfwlist +server=/epochtimes.com.br/127.0.0.1#5335 +ipset=/epochtimes.com.br/gfwlist +server=/xlecx.org/127.0.0.1#5335 +ipset=/xlecx.org/gfwlist +server=/customnikeshoes.com/127.0.0.1#5335 +ipset=/customnikeshoes.com/gfwlist +server=/volvotruckcenter.kr/127.0.0.1#5335 +ipset=/volvotruckcenter.kr/gfwlist +server=/whatsapp.info/127.0.0.1#5335 +ipset=/whatsapp.info/gfwlist +server=/monsterbeatsfactory.net/127.0.0.1#5335 +ipset=/monsterbeatsfactory.net/gfwlist +server=/directvrichmond.com/127.0.0.1#5335 +ipset=/directvrichmond.com/gfwlist +server=/fbbmarket.com/127.0.0.1#5335 +ipset=/fbbmarket.com/gfwlist +server=/ikea.com.pr/127.0.0.1#5335 +ipset=/ikea.com.pr/gfwlist +server=/fetishtown.net/127.0.0.1#5335 +ipset=/fetishtown.net/gfwlist +server=/terrapeak.com/127.0.0.1#5335 +ipset=/terrapeak.com/gfwlist +server=/prime-video.com/127.0.0.1#5335 +ipset=/prime-video.com/gfwlist +server=/stonefoxlingerie.com/127.0.0.1#5335 +ipset=/stonefoxlingerie.com/gfwlist +server=/3d-toon.com/127.0.0.1#5335 +ipset=/3d-toon.com/gfwlist +server=/canon.ge/127.0.0.1#5335 +ipset=/canon.ge/gfwlist +server=/hppavillionlaptop.com/127.0.0.1#5335 +ipset=/hppavillionlaptop.com/gfwlist +server=/microsoftuwp.com/127.0.0.1#5335 +ipset=/microsoftuwp.com/gfwlist +server=/openmaps.org/127.0.0.1#5335 +ipset=/openmaps.org/gfwlist +server=/durex.dk/127.0.0.1#5335 +ipset=/durex.dk/gfwlist +server=/wankizer.com/127.0.0.1#5335 +ipset=/wankizer.com/gfwlist +server=/theinitium.com/127.0.0.1#5335 +ipset=/theinitium.com/gfwlist +server=/sharkyporn.com/127.0.0.1#5335 +ipset=/sharkyporn.com/gfwlist +server=/cheapbeatsbydrenz.net/127.0.0.1#5335 +ipset=/cheapbeatsbydrenz.net/gfwlist +server=/shesfreaky.com/127.0.0.1#5335 +ipset=/shesfreaky.com/gfwlist +server=/topescort.nl/127.0.0.1#5335 +ipset=/topescort.nl/gfwlist +server=/pornojux.com/127.0.0.1#5335 +ipset=/pornojux.com/gfwlist +server=/dmgmediaprivacy.co.uk/127.0.0.1#5335 +ipset=/dmgmediaprivacy.co.uk/gfwlist +server=/nintendo.eu/127.0.0.1#5335 +ipset=/nintendo.eu/gfwlist +server=/ebi.ac.uk/127.0.0.1#5335 +ipset=/ebi.ac.uk/gfwlist +server=/cheapbeatsbus.com/127.0.0.1#5335 +ipset=/cheapbeatsbus.com/gfwlist +server=/bestbuy-jobs.com/127.0.0.1#5335 +ipset=/bestbuy-jobs.com/gfwlist +server=/imac.one/127.0.0.1#5335 +ipset=/imac.one/gfwlist +server=/clip16.com/127.0.0.1#5335 +ipset=/clip16.com/gfwlist +server=/viewpointsfromfacebook.com/127.0.0.1#5335 +ipset=/viewpointsfromfacebook.com/gfwlist +server=/geeksquad.tv/127.0.0.1#5335 +ipset=/geeksquad.tv/gfwlist +server=/latex-project.org/127.0.0.1#5335 +ipset=/latex-project.org/gfwlist +server=/wetandpuffy.com/127.0.0.1#5335 +ipset=/wetandpuffy.com/gfwlist +server=/pmatehunter.com/127.0.0.1#5335 +ipset=/pmatehunter.com/gfwlist +server=/epochtimes.com.au/127.0.0.1#5335 +ipset=/epochtimes.com.au/gfwlist +server=/thz7.net/127.0.0.1#5335 +ipset=/thz7.net/gfwlist +server=/alphabet.cz/127.0.0.1#5335 +ipset=/alphabet.cz/gfwlist +server=/adguard.com/127.0.0.1#5335 +ipset=/adguard.com/gfwlist +server=/bmw-motorrad.com.my/127.0.0.1#5335 +ipset=/bmw-motorrad.com.my/gfwlist +server=/liketruyen.net/127.0.0.1#5335 +ipset=/liketruyen.net/gfwlist +server=/nubiles-porn.com/127.0.0.1#5335 +ipset=/nubiles-porn.com/gfwlist +server=/all-sex-links.com/127.0.0.1#5335 +ipset=/all-sex-links.com/gfwlist +server=/embed.ly/127.0.0.1#5335 +ipset=/embed.ly/gfwlist +server=/incommon-rsa.org/127.0.0.1#5335 +ipset=/incommon-rsa.org/gfwlist +server=/pornfuror.com/127.0.0.1#5335 +ipset=/pornfuror.com/gfwlist +server=/starbucks.com.tr/127.0.0.1#5335 +ipset=/starbucks.com.tr/gfwlist +server=/spreadporn.org/127.0.0.1#5335 +ipset=/spreadporn.org/gfwlist +server=/volvospares.com/127.0.0.1#5335 +ipset=/volvospares.com/gfwlist +server=/pornohut.info/127.0.0.1#5335 +ipset=/pornohut.info/gfwlist +server=/wd.com/127.0.0.1#5335 +ipset=/wd.com/gfwlist +server=/dotcernpilot.info/127.0.0.1#5335 +ipset=/dotcernpilot.info/gfwlist +server=/foxcreativeuniversity.com/127.0.0.1#5335 +ipset=/foxcreativeuniversity.com/gfwlist +server=/porndisk.com/127.0.0.1#5335 +ipset=/porndisk.com/gfwlist +server=/bloombergradio.com/127.0.0.1#5335 +ipset=/bloombergradio.com/gfwlist +server=/visa.com.co/127.0.0.1#5335 +ipset=/visa.com.co/gfwlist +server=/yandex.com.ua/127.0.0.1#5335 +ipset=/yandex.com.ua/gfwlist +server=/vodafone.de/127.0.0.1#5335 +ipset=/vodafone.de/gfwlist +server=/ikea.co.pl/127.0.0.1#5335 +ipset=/ikea.co.pl/gfwlist +server=/xxx.xxx/127.0.0.1#5335 +ipset=/xxx.xxx/gfwlist +server=/addison-wesley.ch/127.0.0.1#5335 +ipset=/addison-wesley.ch/gfwlist +server=/voaafrique.com/127.0.0.1#5335 +ipset=/voaafrique.com/gfwlist +server=/intel.us/127.0.0.1#5335 +ipset=/intel.us/gfwlist +server=/psg-int-centralus.cloudapp.net/127.0.0.1#5335 +ipset=/psg-int-centralus.cloudapp.net/gfwlist +server=/fb.com/127.0.0.1#5335 +ipset=/fb.com/gfwlist +server=/passport.net/127.0.0.1#5335 +ipset=/passport.net/gfwlist +server=/hplaptop.com/127.0.0.1#5335 +ipset=/hplaptop.com/gfwlist +server=/ea.com/127.0.0.1#5335 +ipset=/ea.com/gfwlist +server=/jtvnw.net/127.0.0.1#5335 +ipset=/jtvnw.net/gfwlist +server=/voxcreative.com/127.0.0.1#5335 +ipset=/voxcreative.com/gfwlist +server=/youtube.com.ph/127.0.0.1#5335 +ipset=/youtube.com.ph/gfwlist +server=/zb.com/127.0.0.1#5335 +ipset=/zb.com/gfwlist +server=/nikedunksshoes.com/127.0.0.1#5335 +ipset=/nikedunksshoes.com/gfwlist +server=/mainichibooks.com/127.0.0.1#5335 +ipset=/mainichibooks.com/gfwlist +server=/farfetch.net/127.0.0.1#5335 +ipset=/farfetch.net/gfwlist +server=/explicittube.com/127.0.0.1#5335 +ipset=/explicittube.com/gfwlist +server=/ttvnw.net/127.0.0.1#5335 +ipset=/ttvnw.net/gfwlist +server=/volvobuses.be/127.0.0.1#5335 +ipset=/volvobuses.be/gfwlist +server=/luvmov.com/127.0.0.1#5335 +ipset=/luvmov.com/gfwlist +server=/paypalnetwork.org/127.0.0.1#5335 +ipset=/paypalnetwork.org/gfwlist +server=/bmw-world.tv/127.0.0.1#5335 +ipset=/bmw-world.tv/gfwlist +server=/facebookworld.com/127.0.0.1#5335 +ipset=/facebookworld.com/gfwlist +server=/alt6-mtalk.google.com/127.0.0.1#5335 +ipset=/alt6-mtalk.google.com/gfwlist +server=/16fhgdty.xyz/127.0.0.1#5335 +ipset=/16fhgdty.xyz/gfwlist +server=/adultfreex.com/127.0.0.1#5335 +ipset=/adultfreex.com/gfwlist +server=/historyofdota.com/127.0.0.1#5335 +ipset=/historyofdota.com/gfwlist +server=/alpherafs.ie/127.0.0.1#5335 +ipset=/alpherafs.ie/gfwlist +server=/finishkilpailu.fi/127.0.0.1#5335 +ipset=/finishkilpailu.fi/gfwlist +server=/google.rw/127.0.0.1#5335 +ipset=/google.rw/gfwlist +server=/attglobal.net/127.0.0.1#5335 +ipset=/attglobal.net/gfwlist +server=/alivevm.com/127.0.0.1#5335 +ipset=/alivevm.com/gfwlist +server=/aranzadi.es/127.0.0.1#5335 +ipset=/aranzadi.es/gfwlist +server=/gaypornlove.net/127.0.0.1#5335 +ipset=/gaypornlove.net/gfwlist +server=/0cgdklr5sfwj.com/127.0.0.1#5335 +ipset=/0cgdklr5sfwj.com/gfwlist +server=/younger19.com/127.0.0.1#5335 +ipset=/younger19.com/gfwlist +server=/psyccareers.com/127.0.0.1#5335 +ipset=/psyccareers.com/gfwlist +server=/me.com/127.0.0.1#5335 +ipset=/me.com/gfwlist +server=/zohouniversity.com/127.0.0.1#5335 +ipset=/zohouniversity.com/gfwlist +server=/javbus.com/127.0.0.1#5335 +ipset=/javbus.com/gfwlist +server=/nebay.net/127.0.0.1#5335 +ipset=/nebay.net/gfwlist +server=/thepornscat.com/127.0.0.1#5335 +ipset=/thepornscat.com/gfwlist +server=/blogspot.td/127.0.0.1#5335 +ipset=/blogspot.td/gfwlist +server=/canon.co.il/127.0.0.1#5335 +ipset=/canon.co.il/gfwlist +server=/69-sexgames.com/127.0.0.1#5335 +ipset=/69-sexgames.com/gfwlist +server=/kijijiraps.ca/127.0.0.1#5335 +ipset=/kijijiraps.ca/gfwlist +server=/mofosnetwork.com/127.0.0.1#5335 +ipset=/mofosnetwork.com/gfwlist +server=/yahoo.com.vn/127.0.0.1#5335 +ipset=/yahoo.com.vn/gfwlist +server=/gettyimages.pt/127.0.0.1#5335 +ipset=/gettyimages.pt/gfwlist +server=/srwwu.uno/127.0.0.1#5335 +ipset=/srwwu.uno/gfwlist +server=/microsoft.uz/127.0.0.1#5335 +ipset=/microsoft.uz/gfwlist +server=/pinterest.com.vn/127.0.0.1#5335 +ipset=/pinterest.com.vn/gfwlist +server=/cabletv.com.hk/127.0.0.1#5335 +ipset=/cabletv.com.hk/gfwlist +server=/diablo3.com/127.0.0.1#5335 +ipset=/diablo3.com/gfwlist +server=/nakadashi.to/127.0.0.1#5335 +ipset=/nakadashi.to/gfwlist +server=/oreilly.review/127.0.0.1#5335 +ipset=/oreilly.review/gfwlist +server=/hot-teens.com/127.0.0.1#5335 +ipset=/hot-teens.com/gfwlist +server=/makeitopen.com/127.0.0.1#5335 +ipset=/makeitopen.com/gfwlist +server=/dynacw.com/127.0.0.1#5335 +ipset=/dynacw.com/gfwlist +server=/lede-project.org/127.0.0.1#5335 +ipset=/lede-project.org/gfwlist +server=/beatsbydresonline-nz.com/127.0.0.1#5335 +ipset=/beatsbydresonline-nz.com/gfwlist +server=/beatsbydresalemall2013.com/127.0.0.1#5335 +ipset=/beatsbydresalemall2013.com/gfwlist +server=/porcore.com/127.0.0.1#5335 +ipset=/porcore.com/gfwlist +server=/powerappscdn.net/127.0.0.1#5335 +ipset=/powerappscdn.net/gfwlist +server=/rakuten.ca/127.0.0.1#5335 +ipset=/rakuten.ca/gfwlist +server=/rk.com/127.0.0.1#5335 +ipset=/rk.com/gfwlist +server=/elasticbeanstalk.com/127.0.0.1#5335 +ipset=/elasticbeanstalk.com/gfwlist +server=/vk.com/127.0.0.1#5335 +ipset=/vk.com/gfwlist +server=/oxlife.co/127.0.0.1#5335 +ipset=/oxlife.co/gfwlist +server=/internationalsaimoe.com/127.0.0.1#5335 +ipset=/internationalsaimoe.com/gfwlist +server=/idservice.inc/127.0.0.1#5335 +ipset=/idservice.inc/gfwlist +server=/bffshd.com/127.0.0.1#5335 +ipset=/bffshd.com/gfwlist +server=/squirrelgroup.net/127.0.0.1#5335 +ipset=/squirrelgroup.net/gfwlist +server=/blogspot.sk/127.0.0.1#5335 +ipset=/blogspot.sk/gfwlist +server=/microsoft.ua/127.0.0.1#5335 +ipset=/microsoft.ua/gfwlist +server=/bountyhunterporn.com/127.0.0.1#5335 +ipset=/bountyhunterporn.com/gfwlist +server=/ipadair.cl/127.0.0.1#5335 +ipset=/ipadair.cl/gfwlist +server=/takegoto.com/127.0.0.1#5335 +ipset=/takegoto.com/gfwlist +server=/ikea.au/127.0.0.1#5335 +ipset=/ikea.au/gfwlist +server=/av69.tv/127.0.0.1#5335 +ipset=/av69.tv/gfwlist +server=/logitech.com.cn/127.0.0.1#5335 +ipset=/logitech.com.cn/gfwlist +server=/hbogoasia.sg/127.0.0.1#5335 +ipset=/hbogoasia.sg/gfwlist +server=/cbsplaylistserver.aws.syncbak.com/127.0.0.1#5335 +ipset=/cbsplaylistserver.aws.syncbak.com/gfwlist +server=/hpprinterinstalls.com/127.0.0.1#5335 +ipset=/hpprinterinstalls.com/gfwlist +server=/intercom.com/127.0.0.1#5335 +ipset=/intercom.com/gfwlist +server=/nikehelp.com/127.0.0.1#5335 +ipset=/nikehelp.com/gfwlist +server=/mallandrinhas.net/127.0.0.1#5335 +ipset=/mallandrinhas.net/gfwlist +server=/gettyimages.be/127.0.0.1#5335 +ipset=/gettyimages.be/gfwlist +server=/2k.com/127.0.0.1#5335 +ipset=/2k.com/gfwlist +server=/bestgames-2022.com/127.0.0.1#5335 +ipset=/bestgames-2022.com/gfwlist +server=/apple.is/127.0.0.1#5335 +ipset=/apple.is/gfwlist +server=/pinterest.co.nz/127.0.0.1#5335 +ipset=/pinterest.co.nz/gfwlist +server=/finishbrasil.com.br/127.0.0.1#5335 +ipset=/finishbrasil.com.br/gfwlist +server=/skype-edf.akadns.net/127.0.0.1#5335 +ipset=/skype-edf.akadns.net/gfwlist +server=/mastercard.com.co/127.0.0.1#5335 +ipset=/mastercard.com.co/gfwlist +server=/pornyeah.com/127.0.0.1#5335 +ipset=/pornyeah.com/gfwlist +server=/microsoft.ee/127.0.0.1#5335 +ipset=/microsoft.ee/gfwlist +server=/intel.md/127.0.0.1#5335 +ipset=/intel.md/gfwlist +server=/58avgo.com/127.0.0.1#5335 +ipset=/58avgo.com/gfwlist +server=/ass4all.com/127.0.0.1#5335 +ipset=/ass4all.com/gfwlist +server=/myxvids.com/127.0.0.1#5335 +ipset=/myxvids.com/gfwlist +server=/youtube.my/127.0.0.1#5335 +ipset=/youtube.my/gfwlist +server=/lasvegasbmw.com/127.0.0.1#5335 +ipset=/lasvegasbmw.com/gfwlist +server=/healthcarecareeronline.com/127.0.0.1#5335 +ipset=/healthcarecareeronline.com/gfwlist +server=/randyblue.com/127.0.0.1#5335 +ipset=/randyblue.com/gfwlist +server=/avstar6.com/127.0.0.1#5335 +ipset=/avstar6.com/gfwlist +server=/vipstudiocali.com/127.0.0.1#5335 +ipset=/vipstudiocali.com/gfwlist +server=/nikewear.com/127.0.0.1#5335 +ipset=/nikewear.com/gfwlist +server=/myaccountglobalcash.com/127.0.0.1#5335 +ipset=/myaccountglobalcash.com/gfwlist +server=/petite.one/127.0.0.1#5335 +ipset=/petite.one/gfwlist +server=/ro89.com/127.0.0.1#5335 +ipset=/ro89.com/gfwlist +server=/annualpelvicexam.com/127.0.0.1#5335 +ipset=/annualpelvicexam.com/gfwlist +server=/mybestbuy.com/127.0.0.1#5335 +ipset=/mybestbuy.com/gfwlist +server=/blogspot.bj/127.0.0.1#5335 +ipset=/blogspot.bj/gfwlist +server=/radiosvoboda.org/127.0.0.1#5335 +ipset=/radiosvoboda.org/gfwlist +server=/xhamsterlive.com/127.0.0.1#5335 +ipset=/xhamsterlive.com/gfwlist +server=/akamai.com/127.0.0.1#5335 +ipset=/akamai.com/gfwlist +server=/unraveltwo.com/127.0.0.1#5335 +ipset=/unraveltwo.com/gfwlist +server=/bluehatil.com/127.0.0.1#5335 +ipset=/bluehatil.com/gfwlist +server=/juliamiles.com/127.0.0.1#5335 +ipset=/juliamiles.com/gfwlist +server=/sexytuber.com/127.0.0.1#5335 +ipset=/sexytuber.com/gfwlist +server=/adorevids.com/127.0.0.1#5335 +ipset=/adorevids.com/gfwlist +server=/lavteam.org/127.0.0.1#5335 +ipset=/lavteam.org/gfwlist +server=/facebookwork.com/127.0.0.1#5335 +ipset=/facebookwork.com/gfwlist +server=/iwork.se/127.0.0.1#5335 +ipset=/iwork.se/gfwlist +server=/nurofen.hu/127.0.0.1#5335 +ipset=/nurofen.hu/gfwlist +server=/thinkboxsoftware.com/127.0.0.1#5335 +ipset=/thinkboxsoftware.com/gfwlist +server=/pornsexer.com/127.0.0.1#5335 +ipset=/pornsexer.com/gfwlist +server=/sellercommunity.com/127.0.0.1#5335 +ipset=/sellercommunity.com/gfwlist +server=/mastercard.co.id/127.0.0.1#5335 +ipset=/mastercard.co.id/gfwlist +server=/mirar.xxx/127.0.0.1#5335 +ipset=/mirar.xxx/gfwlist +server=/callabitch.org/127.0.0.1#5335 +ipset=/callabitch.org/gfwlist +server=/brightcove.com/127.0.0.1#5335 +ipset=/brightcove.com/gfwlist +server=/morteincam.com/127.0.0.1#5335 +ipset=/morteincam.com/gfwlist +server=/new-jero.net/127.0.0.1#5335 +ipset=/new-jero.net/gfwlist +server=/iphoto.no/127.0.0.1#5335 +ipset=/iphoto.no/gfwlist +server=/play4free.com/127.0.0.1#5335 +ipset=/play4free.com/gfwlist +server=/huluteam.com/127.0.0.1#5335 +ipset=/huluteam.com/gfwlist +server=/pornking.fun/127.0.0.1#5335 +ipset=/pornking.fun/gfwlist +server=/myhelpinglab.com/127.0.0.1#5335 +ipset=/myhelpinglab.com/gfwlist +server=/oxfordmusiconline.com/127.0.0.1#5335 +ipset=/oxfordmusiconline.com/gfwlist +server=/stripchat.com/127.0.0.1#5335 +ipset=/stripchat.com/gfwlist +server=/supermario3dworld.com/127.0.0.1#5335 +ipset=/supermario3dworld.com/gfwlist +server=/huffingtonpost.com.au/127.0.0.1#5335 +ipset=/huffingtonpost.com.au/gfwlist +server=/pornoko.net/127.0.0.1#5335 +ipset=/pornoko.net/gfwlist +server=/thebeatsbydre.net/127.0.0.1#5335 +ipset=/thebeatsbydre.net/gfwlist +server=/torrindex.net/127.0.0.1#5335 +ipset=/torrindex.net/gfwlist +server=/google.com.pe/127.0.0.1#5335 +ipset=/google.com.pe/gfwlist +server=/vodafone.com/127.0.0.1#5335 +ipset=/vodafone.com/gfwlist +server=/dribbble.com/127.0.0.1#5335 +ipset=/dribbble.com/gfwlist +server=/applestore.sg/127.0.0.1#5335 +ipset=/applestore.sg/gfwlist +server=/pokemonswordshield.com/127.0.0.1#5335 +ipset=/pokemonswordshield.com/gfwlist +server=/btcbox.co.jp/127.0.0.1#5335 +ipset=/btcbox.co.jp/gfwlist +server=/alexanderstreet.com/127.0.0.1#5335 +ipset=/alexanderstreet.com/gfwlist +server=/picasaweb.net/127.0.0.1#5335 +ipset=/picasaweb.net/gfwlist +server=/youtube.lt/127.0.0.1#5335 +ipset=/youtube.lt/gfwlist +server=/hptouchpointmanager.com/127.0.0.1#5335 +ipset=/hptouchpointmanager.com/gfwlist +server=/usvimosquito.com/127.0.0.1#5335 +ipset=/usvimosquito.com/gfwlist +server=/desiporn.tube/127.0.0.1#5335 +ipset=/desiporn.tube/gfwlist +server=/akadeem.net/127.0.0.1#5335 +ipset=/akadeem.net/gfwlist +server=/llnwd.net/127.0.0.1#5335 +ipset=/llnwd.net/gfwlist +server=/beatsbydrehd.com/127.0.0.1#5335 +ipset=/beatsbydrehd.com/gfwlist +server=/google.ee/127.0.0.1#5335 +ipset=/google.ee/gfwlist +server=/tgp6.com/127.0.0.1#5335 +ipset=/tgp6.com/gfwlist +server=/amateur-porn-tube.net/127.0.0.1#5335 +ipset=/amateur-porn-tube.net/gfwlist +server=/powerautomate.com/127.0.0.1#5335 +ipset=/powerautomate.com/gfwlist +server=/javtag.net/127.0.0.1#5335 +ipset=/javtag.net/gfwlist +server=/volvotrucks.pl/127.0.0.1#5335 +ipset=/volvotrucks.pl/gfwlist +server=/epochtimes.fr/127.0.0.1#5335 +ipset=/epochtimes.fr/gfwlist +server=/freedirecttvspecial.com/127.0.0.1#5335 +ipset=/freedirecttvspecial.com/gfwlist +server=/freematuresgallery.com/127.0.0.1#5335 +ipset=/freematuresgallery.com/gfwlist +server=/iina.io/127.0.0.1#5335 +ipset=/iina.io/gfwlist +server=/foxnewspolitics.com/127.0.0.1#5335 +ipset=/foxnewspolitics.com/gfwlist +server=/zb.io/127.0.0.1#5335 +ipset=/zb.io/gfwlist +server=/hotgirlsclips.com/127.0.0.1#5335 +ipset=/hotgirlsclips.com/gfwlist +server=/foxd.tv/127.0.0.1#5335 +ipset=/foxd.tv/gfwlist +server=/forthethrone.com/127.0.0.1#5335 +ipset=/forthethrone.com/gfwlist +server=/visualstudio.net/127.0.0.1#5335 +ipset=/visualstudio.net/gfwlist +server=/conda.io/127.0.0.1#5335 +ipset=/conda.io/gfwlist +server=/xvideo.vlog.br/127.0.0.1#5335 +ipset=/xvideo.vlog.br/gfwlist +server=/nordstrom.com/127.0.0.1#5335 +ipset=/nordstrom.com/gfwlist +server=/vipheadphones.com/127.0.0.1#5335 +ipset=/vipheadphones.com/gfwlist +server=/premiumpornlist.com/127.0.0.1#5335 +ipset=/premiumpornlist.com/gfwlist +server=/hpprintersupplies.com/127.0.0.1#5335 +ipset=/hpprintersupplies.com/gfwlist +server=/intel.tw/127.0.0.1#5335 +ipset=/intel.tw/gfwlist +server=/freeteenporn.xxx/127.0.0.1#5335 +ipset=/freeteenporn.xxx/gfwlist +server=/1lib.to/127.0.0.1#5335 +ipset=/1lib.to/gfwlist +server=/thomsonreuters.com.pe/127.0.0.1#5335 +ipset=/thomsonreuters.com.pe/gfwlist +server=/freesitexxx.com/127.0.0.1#5335 +ipset=/freesitexxx.com/gfwlist +server=/hcaptcha.com/127.0.0.1#5335 +ipset=/hcaptcha.com/gfwlist +server=/oculusdiving.com/127.0.0.1#5335 +ipset=/oculusdiving.com/gfwlist +server=/pearsonschoolsandfecolleges.co.uk/127.0.0.1#5335 +ipset=/pearsonschoolsandfecolleges.co.uk/gfwlist +server=/beatsdreoutletsale.com/127.0.0.1#5335 +ipset=/beatsdreoutletsale.com/gfwlist +server=/demoprint.com/127.0.0.1#5335 +ipset=/demoprint.com/gfwlist +server=/v.gd/127.0.0.1#5335 +ipset=/v.gd/gfwlist +server=/huluqa.com/127.0.0.1#5335 +ipset=/huluqa.com/gfwlist +server=/casquesbeatsaudio.com/127.0.0.1#5335 +ipset=/casquesbeatsaudio.com/gfwlist +server=/onlyleaks.me/127.0.0.1#5335 +ipset=/onlyleaks.me/gfwlist +server=/sextubeset.com/127.0.0.1#5335 +ipset=/sextubeset.com/gfwlist +server=/youtube.by/127.0.0.1#5335 +ipset=/youtube.by/gfwlist +server=/family-simulator.io/127.0.0.1#5335 +ipset=/family-simulator.io/gfwlist +server=/tktube.com/127.0.0.1#5335 +ipset=/tktube.com/gfwlist +server=/freesexalbum.com/127.0.0.1#5335 +ipset=/freesexalbum.com/gfwlist +server=/casquemonsterbeatsbydre2013.com/127.0.0.1#5335 +ipset=/casquemonsterbeatsbydre2013.com/gfwlist +server=/kinkypeepz.com/127.0.0.1#5335 +ipset=/kinkypeepz.com/gfwlist +server=/video01.org/127.0.0.1#5335 +ipset=/video01.org/gfwlist +server=/asme.org/127.0.0.1#5335 +ipset=/asme.org/gfwlist +server=/yeyuehuachao11.com/127.0.0.1#5335 +ipset=/yeyuehuachao11.com/gfwlist +server=/shopbydre.com/127.0.0.1#5335 +ipset=/shopbydre.com/gfwlist +server=/erosberry.com/127.0.0.1#5335 +ipset=/erosberry.com/gfwlist +server=/intel.nl/127.0.0.1#5335 +ipset=/intel.nl/gfwlist +server=/bingapistatistics.com/127.0.0.1#5335 +ipset=/bingapistatistics.com/gfwlist +server=/seaofsolitude.com/127.0.0.1#5335 +ipset=/seaofsolitude.com/gfwlist +server=/6mature9.com/127.0.0.1#5335 +ipset=/6mature9.com/gfwlist +server=/besterpornos.com/127.0.0.1#5335 +ipset=/besterpornos.com/gfwlist +server=/gosq.co/127.0.0.1#5335 +ipset=/gosq.co/gfwlist +server=/aapl.tw/127.0.0.1#5335 +ipset=/aapl.tw/gfwlist +server=/truyengihay.net/127.0.0.1#5335 +ipset=/truyengihay.net/gfwlist +server=/sankei-kurashi.com/127.0.0.1#5335 +ipset=/sankei-kurashi.com/gfwlist +server=/hpindigopress.com/127.0.0.1#5335 +ipset=/hpindigopress.com/gfwlist +server=/bmw.fr/127.0.0.1#5335 +ipset=/bmw.fr/gfwlist +server=/msauth.net/127.0.0.1#5335 +ipset=/msauth.net/gfwlist +server=/activelearnprimary.co.uk/127.0.0.1#5335 +ipset=/activelearnprimary.co.uk/gfwlist +server=/dell-brand.com/127.0.0.1#5335 +ipset=/dell-brand.com/gfwlist +server=/championshipseriesleague.com/127.0.0.1#5335 +ipset=/championshipseriesleague.com/gfwlist +server=/bmw.com.sv/127.0.0.1#5335 +ipset=/bmw.com.sv/gfwlist +server=/spankbang.com/127.0.0.1#5335 +ipset=/spankbang.com/gfwlist +server=/shemaletube.pro/127.0.0.1#5335 +ipset=/shemaletube.pro/gfwlist +server=/needforspeedundergroundeast.com/127.0.0.1#5335 +ipset=/needforspeedundergroundeast.com/gfwlist +server=/sslpaypal.org/127.0.0.1#5335 +ipset=/sslpaypal.org/gfwlist +server=/etnet.com.hk/127.0.0.1#5335 +ipset=/etnet.com.hk/gfwlist +server=/beatsdrenewcolorful4usale.com/127.0.0.1#5335 +ipset=/beatsdrenewcolorful4usale.com/gfwlist +server=/facebooe.com/127.0.0.1#5335 +ipset=/facebooe.com/gfwlist +server=/uxxxporn.com/127.0.0.1#5335 +ipset=/uxxxporn.com/gfwlist +server=/dkbeatsbydre.com/127.0.0.1#5335 +ipset=/dkbeatsbydre.com/gfwlist +server=/dldshare.net/127.0.0.1#5335 +ipset=/dldshare.net/gfwlist +server=/coomer.party/127.0.0.1#5335 +ipset=/coomer.party/gfwlist +server=/google.sn/127.0.0.1#5335 +ipset=/google.sn/gfwlist +server=/beats-bydrestore.com/127.0.0.1#5335 +ipset=/beats-bydrestore.com/gfwlist +server=/cherrypornhd.com/127.0.0.1#5335 +ipset=/cherrypornhd.com/gfwlist +server=/seemyporn.com/127.0.0.1#5335 +ipset=/seemyporn.com/gfwlist +server=/blogspot.rs/127.0.0.1#5335 +ipset=/blogspot.rs/gfwlist +server=/bridgestonecomercial.com.br/127.0.0.1#5335 +ipset=/bridgestonecomercial.com.br/gfwlist +server=/dualeotruyen1s.com/127.0.0.1#5335 +ipset=/dualeotruyen1s.com/gfwlist +server=/tail-f.com/127.0.0.1#5335 +ipset=/tail-f.com/gfwlist +server=/sexxxx.rodeo/127.0.0.1#5335 +ipset=/sexxxx.rodeo/gfwlist +server=/bromo.com/127.0.0.1#5335 +ipset=/bromo.com/gfwlist +server=/yogalayout.com/127.0.0.1#5335 +ipset=/yogalayout.com/gfwlist +server=/hornygamer.com/127.0.0.1#5335 +ipset=/hornygamer.com/gfwlist +server=/jiuzhouyihuo.com/127.0.0.1#5335 +ipset=/jiuzhouyihuo.com/gfwlist +server=/parstream.net/127.0.0.1#5335 +ipset=/parstream.net/gfwlist +server=/xlinkz.to/127.0.0.1#5335 +ipset=/xlinkz.to/gfwlist +server=/mini-connected.nl/127.0.0.1#5335 +ipset=/mini-connected.nl/gfwlist +server=/indianpornfast.com/127.0.0.1#5335 +ipset=/indianpornfast.com/gfwlist +server=/drdrebeatsbillig.com/127.0.0.1#5335 +ipset=/drdrebeatsbillig.com/gfwlist +server=/youtube.co.kr/127.0.0.1#5335 +ipset=/youtube.co.kr/gfwlist +server=/vfsco.it/127.0.0.1#5335 +ipset=/vfsco.it/gfwlist +server=/openweave.io/127.0.0.1#5335 +ipset=/openweave.io/gfwlist +server=/xapplist.com/127.0.0.1#5335 +ipset=/xapplist.com/gfwlist +server=/shopee.tw/127.0.0.1#5335 +ipset=/shopee.tw/gfwlist +server=/beatsbydrestorevip.com/127.0.0.1#5335 +ipset=/beatsbydrestorevip.com/gfwlist +server=/garena.com/127.0.0.1#5335 +ipset=/garena.com/gfwlist +server=/bmw.bg/127.0.0.1#5335 +ipset=/bmw.bg/gfwlist +server=/gearspop.com/127.0.0.1#5335 +ipset=/gearspop.com/gfwlist +server=/fire-emblem-heroes.com/127.0.0.1#5335 +ipset=/fire-emblem-heroes.com/gfwlist +server=/exoticuganda.com/127.0.0.1#5335 +ipset=/exoticuganda.com/gfwlist +server=/europepmc.org/127.0.0.1#5335 +ipset=/europepmc.org/gfwlist +server=/toon-3d.com/127.0.0.1#5335 +ipset=/toon-3d.com/gfwlist +server=/miniwidget.ca/127.0.0.1#5335 +ipset=/miniwidget.ca/gfwlist +server=/alchemysynth.com/127.0.0.1#5335 +ipset=/alchemysynth.com/gfwlist +server=/mini.am/127.0.0.1#5335 +ipset=/mini.am/gfwlist +server=/reaxys.com/127.0.0.1#5335 +ipset=/reaxys.com/gfwlist +server=/mini-connected.at/127.0.0.1#5335 +ipset=/mini-connected.at/gfwlist +server=/ebaybags.com/127.0.0.1#5335 +ipset=/ebaybags.com/gfwlist +server=/appleone.space/127.0.0.1#5335 +ipset=/appleone.space/gfwlist +server=/yamaxun.com/127.0.0.1#5335 +ipset=/yamaxun.com/gfwlist +server=/briantreepayments.net/127.0.0.1#5335 +ipset=/briantreepayments.net/gfwlist +server=/developria.com/127.0.0.1#5335 +ipset=/developria.com/gfwlist +server=/kali.org/127.0.0.1#5335 +ipset=/kali.org/gfwlist +server=/amazonlaunchpad.com/127.0.0.1#5335 +ipset=/amazonlaunchpad.com/gfwlist +server=/headphonessupply.com/127.0.0.1#5335 +ipset=/headphonessupply.com/gfwlist +server=/icloudos.de/127.0.0.1#5335 +ipset=/icloudos.de/gfwlist +server=/influencersgonewild.com/127.0.0.1#5335 +ipset=/influencersgonewild.com/gfwlist +server=/one889.app/127.0.0.1#5335 +ipset=/one889.app/gfwlist +server=/city-hentai.com/127.0.0.1#5335 +ipset=/city-hentai.com/gfwlist +server=/poweredbyintel.com/127.0.0.1#5335 +ipset=/poweredbyintel.com/gfwlist +server=/brightcove.imgix.net/127.0.0.1#5335 +ipset=/brightcove.imgix.net/gfwlist +server=/sb-mobile.jp/127.0.0.1#5335 +ipset=/sb-mobile.jp/gfwlist +server=/aerogardcn.com/127.0.0.1#5335 +ipset=/aerogardcn.com/gfwlist +server=/beatsbydrespeakers.com/127.0.0.1#5335 +ipset=/beatsbydrespeakers.com/gfwlist +server=/serbiporno.net/127.0.0.1#5335 +ipset=/serbiporno.net/gfwlist +server=/volvotrucks.co.nz/127.0.0.1#5335 +ipset=/volvotrucks.co.nz/gfwlist +server=/chuporno.com/127.0.0.1#5335 +ipset=/chuporno.com/gfwlist +server=/gooddaychicago.com/127.0.0.1#5335 +ipset=/gooddaychicago.com/gfwlist +server=/bestbuysolutions.net/127.0.0.1#5335 +ipset=/bestbuysolutions.net/gfwlist +server=/valoryirene.com/127.0.0.1#5335 +ipset=/valoryirene.com/gfwlist +server=/shp.ee/127.0.0.1#5335 +ipset=/shp.ee/gfwlist +server=/javpush.com/127.0.0.1#5335 +ipset=/javpush.com/gfwlist +server=/bnetcmsus-a.akamaihd.net/127.0.0.1#5335 +ipset=/bnetcmsus-a.akamaihd.net/gfwlist +server=/hot-arab-films.com/127.0.0.1#5335 +ipset=/hot-arab-films.com/gfwlist +server=/clipsbai.com/127.0.0.1#5335 +ipset=/clipsbai.com/gfwlist +server=/capitaliq.com/127.0.0.1#5335 +ipset=/capitaliq.com/gfwlist +server=/ciscojabbervideo.net/127.0.0.1#5335 +ipset=/ciscojabbervideo.net/gfwlist +server=/bokep.net/127.0.0.1#5335 +ipset=/bokep.net/gfwlist +server=/mini.lu/127.0.0.1#5335 +ipset=/mini.lu/gfwlist +server=/qmap.pub/127.0.0.1#5335 +ipset=/qmap.pub/gfwlist +server=/booksc.eu/127.0.0.1#5335 +ipset=/booksc.eu/gfwlist +server=/nesaporn.mobi/127.0.0.1#5335 +ipset=/nesaporn.mobi/gfwlist +server=/softbankventuresasia.com/127.0.0.1#5335 +ipset=/softbankventuresasia.com/gfwlist +server=/pinterest.ca/127.0.0.1#5335 +ipset=/pinterest.ca/gfwlist +server=/69loli.com/127.0.0.1#5335 +ipset=/69loli.com/gfwlist +server=/yahoo.co.il/127.0.0.1#5335 +ipset=/yahoo.co.il/gfwlist +server=/squarecdn.com/127.0.0.1#5335 +ipset=/squarecdn.com/gfwlist +server=/identrust.net/127.0.0.1#5335 +ipset=/identrust.net/gfwlist +server=/booth.pm/127.0.0.1#5335 +ipset=/booth.pm/gfwlist +server=/canon.bg/127.0.0.1#5335 +ipset=/canon.bg/gfwlist +server=/appleenews.com/127.0.0.1#5335 +ipset=/appleenews.com/gfwlist +server=/mult34.com/127.0.0.1#5335 +ipset=/mult34.com/gfwlist +server=/google.ml/127.0.0.1#5335 +ipset=/google.ml/gfwlist +server=/tomonews.net/127.0.0.1#5335 +ipset=/tomonews.net/gfwlist +server=/imagepost.com/127.0.0.1#5335 +ipset=/imagepost.com/gfwlist +server=/custom-iphonecase.com/127.0.0.1#5335 +ipset=/custom-iphonecase.com/gfwlist +server=/hgsacx.com/127.0.0.1#5335 +ipset=/hgsacx.com/gfwlist +server=/myfoxdc.com/127.0.0.1#5335 +ipset=/myfoxdc.com/gfwlist +server=/youtube.com.do/127.0.0.1#5335 +ipset=/youtube.com.do/gfwlist +server=/foxnetworks.info/127.0.0.1#5335 +ipset=/foxnetworks.info/gfwlist +server=/phimsexnhanh.club/127.0.0.1#5335 +ipset=/phimsexnhanh.club/gfwlist +server=/porndudecasting.com/127.0.0.1#5335 +ipset=/porndudecasting.com/gfwlist +server=/xecce.com/127.0.0.1#5335 +ipset=/xecce.com/gfwlist +server=/euroipad.com/127.0.0.1#5335 +ipset=/euroipad.com/gfwlist +server=/touchid.wang/127.0.0.1#5335 +ipset=/touchid.wang/gfwlist +server=/bitly.is/127.0.0.1#5335 +ipset=/bitly.is/gfwlist +server=/kyodoimages.jp/127.0.0.1#5335 +ipset=/kyodoimages.jp/gfwlist +server=/sweetsinner.com/127.0.0.1#5335 +ipset=/sweetsinner.com/gfwlist +server=/ekhindi.com/127.0.0.1#5335 +ipset=/ekhindi.com/gfwlist +server=/epoch.cloud/127.0.0.1#5335 +ipset=/epoch.cloud/gfwlist +server=/friendbook.info/127.0.0.1#5335 +ipset=/friendbook.info/gfwlist +server=/thisismoney.co.uk/127.0.0.1#5335 +ipset=/thisismoney.co.uk/gfwlist +server=/google.it/127.0.0.1#5335 +ipset=/google.it/gfwlist +server=/yahoo.com.pr/127.0.0.1#5335 +ipset=/yahoo.com.pr/gfwlist +server=/thesafeporn.com/127.0.0.1#5335 +ipset=/thesafeporn.com/gfwlist +server=/gayasianamateurs.com/127.0.0.1#5335 +ipset=/gayasianamateurs.com/gfwlist +server=/youtube.kr/127.0.0.1#5335 +ipset=/youtube.kr/gfwlist +server=/shegg.com/127.0.0.1#5335 +ipset=/shegg.com/gfwlist +server=/muse.jhu.edu/127.0.0.1#5335 +ipset=/muse.jhu.edu/gfwlist +server=/luoli.info/127.0.0.1#5335 +ipset=/luoli.info/gfwlist +server=/directvsavings.com/127.0.0.1#5335 +ipset=/directvsavings.com/gfwlist +server=/hddgames.cc/127.0.0.1#5335 +ipset=/hddgames.cc/gfwlist +server=/ebay.com.ph/127.0.0.1#5335 +ipset=/ebay.com.ph/gfwlist +server=/indianpornvideos2.com/127.0.0.1#5335 +ipset=/indianpornvideos2.com/gfwlist +server=/cortanaanalytics.com/127.0.0.1#5335 +ipset=/cortanaanalytics.com/gfwlist +server=/thelegendarystarfy.com/127.0.0.1#5335 +ipset=/thelegendarystarfy.com/gfwlist +server=/gogole.com/127.0.0.1#5335 +ipset=/gogole.com/gfwlist +server=/kodi.tv/127.0.0.1#5335 +ipset=/kodi.tv/gfwlist +server=/xxxtubeset.com/127.0.0.1#5335 +ipset=/xxxtubeset.com/gfwlist +server=/blackstonespoliceservice.com/127.0.0.1#5335 +ipset=/blackstonespoliceservice.com/gfwlist +server=/usercontent.dev/127.0.0.1#5335 +ipset=/usercontent.dev/gfwlist +server=/outbound.io/127.0.0.1#5335 +ipset=/outbound.io/gfwlist +server=/applefilmaker.com/127.0.0.1#5335 +ipset=/applefilmaker.com/gfwlist +server=/wofl.tv/127.0.0.1#5335 +ipset=/wofl.tv/gfwlist +server=/sexmodel.wordpress.com/127.0.0.1#5335 +ipset=/sexmodel.wordpress.com/gfwlist +server=/instagran.com/127.0.0.1#5335 +ipset=/instagran.com/gfwlist +server=/yandex.de/127.0.0.1#5335 +ipset=/yandex.de/gfwlist +server=/beatsdre-monster.com/127.0.0.1#5335 +ipset=/beatsdre-monster.com/gfwlist +server=/xxx2023.com/127.0.0.1#5335 +ipset=/xxx2023.com/gfwlist +server=/steamcontent.com/127.0.0.1#5335 +ipset=/steamcontent.com/gfwlist +server=/certinomis.fr/127.0.0.1#5335 +ipset=/certinomis.fr/gfwlist +server=/javtrust.com/127.0.0.1#5335 +ipset=/javtrust.com/gfwlist +server=/topanime.biz/127.0.0.1#5335 +ipset=/topanime.biz/gfwlist +server=/hentaiseason.com/127.0.0.1#5335 +ipset=/hentaiseason.com/gfwlist +server=/bestiality.guru/127.0.0.1#5335 +ipset=/bestiality.guru/gfwlist +server=/cheapmonsterbeatssale.com/127.0.0.1#5335 +ipset=/cheapmonsterbeatssale.com/gfwlist +server=/paypal-innovationlab.com/127.0.0.1#5335 +ipset=/paypal-innovationlab.com/gfwlist +server=/shields.io/127.0.0.1#5335 +ipset=/shields.io/gfwlist +server=/bmwstartupgarage.com/127.0.0.1#5335 +ipset=/bmwstartupgarage.com/gfwlist +server=/avstar05.me/127.0.0.1#5335 +ipset=/avstar05.me/gfwlist +server=/zuckerberg.net/127.0.0.1#5335 +ipset=/zuckerberg.net/gfwlist +server=/jwt.ms/127.0.0.1#5335 +ipset=/jwt.ms/gfwlist +server=/ebay.be/127.0.0.1#5335 +ipset=/ebay.be/gfwlist +server=/intel.de/127.0.0.1#5335 +ipset=/intel.de/gfwlist +server=/pornoitaliano.com/127.0.0.1#5335 +ipset=/pornoitaliano.com/gfwlist +server=/leaguoflegends.com/127.0.0.1#5335 +ipset=/leaguoflegends.com/gfwlist +server=/chatsex.xxx/127.0.0.1#5335 +ipset=/chatsex.xxx/gfwlist +server=/sharmota.com/127.0.0.1#5335 +ipset=/sharmota.com/gfwlist +server=/vfsco.us/127.0.0.1#5335 +ipset=/vfsco.us/gfwlist +server=/ieee-vics.org/127.0.0.1#5335 +ipset=/ieee-vics.org/gfwlist +server=/minilangley.com/127.0.0.1#5335 +ipset=/minilangley.com/gfwlist +server=/raponlinereview.com/127.0.0.1#5335 +ipset=/raponlinereview.com/gfwlist +server=/volvobuses.com/127.0.0.1#5335 +ipset=/volvobuses.com/gfwlist +server=/over18arcade.com/127.0.0.1#5335 +ipset=/over18arcade.com/gfwlist +server=/fsdn.com/127.0.0.1#5335 +ipset=/fsdn.com/gfwlist +server=/googledomains.com/127.0.0.1#5335 +ipset=/googledomains.com/gfwlist +server=/yeswegays.com/127.0.0.1#5335 +ipset=/yeswegays.com/gfwlist +server=/swisssign-group.li/127.0.0.1#5335 +ipset=/swisssign-group.li/gfwlist +server=/msdn.com/127.0.0.1#5335 +ipset=/msdn.com/gfwlist +server=/nbyy.tv/127.0.0.1#5335 +ipset=/nbyy.tv/gfwlist +server=/simplifycommerce.com/127.0.0.1#5335 +ipset=/simplifycommerce.com/gfwlist +server=/espn.hb.omtrdc.net/127.0.0.1#5335 +ipset=/espn.hb.omtrdc.net/gfwlist +server=/hentaitube.online/127.0.0.1#5335 +ipset=/hentaitube.online/gfwlist +server=/nextstop.com/127.0.0.1#5335 +ipset=/nextstop.com/gfwlist +server=/niosii.com/127.0.0.1#5335 +ipset=/niosii.com/gfwlist +server=/adultgamestop.com/127.0.0.1#5335 +ipset=/adultgamestop.com/gfwlist +server=/apple.ee/127.0.0.1#5335 +ipset=/apple.ee/gfwlist +server=/live-patreon-marketing.pantheonsite.io/127.0.0.1#5335 +ipset=/live-patreon-marketing.pantheonsite.io/gfwlist +server=/alphera-finance.in/127.0.0.1#5335 +ipset=/alphera-finance.in/gfwlist +server=/youtubemobilesupport.com/127.0.0.1#5335 +ipset=/youtubemobilesupport.com/gfwlist +server=/thepornbet.com/127.0.0.1#5335 +ipset=/thepornbet.com/gfwlist +server=/galaxymobile.jp/127.0.0.1#5335 +ipset=/galaxymobile.jp/gfwlist +server=/volvobuses.fi/127.0.0.1#5335 +ipset=/volvobuses.fi/gfwlist +server=/masaladesi.com/127.0.0.1#5335 +ipset=/masaladesi.com/gfwlist +server=/redlightcenter.com/127.0.0.1#5335 +ipset=/redlightcenter.com/gfwlist +server=/disneystreaming.com/127.0.0.1#5335 +ipset=/disneystreaming.com/gfwlist +server=/xerotica.com/127.0.0.1#5335 +ipset=/xerotica.com/gfwlist +server=/ikea.ee/127.0.0.1#5335 +ipset=/ikea.ee/gfwlist +server=/k8s.io/127.0.0.1#5335 +ipset=/k8s.io/gfwlist +server=/blogblog.com/127.0.0.1#5335 +ipset=/blogblog.com/gfwlist +server=/ekolojik.org/127.0.0.1#5335 +ipset=/ekolojik.org/gfwlist +server=/facebgook.com/127.0.0.1#5335 +ipset=/facebgook.com/gfwlist +server=/beatsshop-uk.com/127.0.0.1#5335 +ipset=/beatsshop-uk.com/gfwlist +server=/camsvids.tv/127.0.0.1#5335 +ipset=/camsvids.tv/gfwlist +server=/jetfuelapp.com/127.0.0.1#5335 +ipset=/jetfuelapp.com/gfwlist +server=/gsccdn.com/127.0.0.1#5335 +ipset=/gsccdn.com/gfwlist +server=/attdns.com/127.0.0.1#5335 +ipset=/attdns.com/gfwlist +server=/vmwareemeablog.com/127.0.0.1#5335 +ipset=/vmwareemeablog.com/gfwlist +server=/bmw-product-highlights.com/127.0.0.1#5335 +ipset=/bmw-product-highlights.com/gfwlist +server=/vscode.search.windows.net/127.0.0.1#5335 +ipset=/vscode.search.windows.net/gfwlist +server=/jizzboom.com/127.0.0.1#5335 +ipset=/jizzboom.com/gfwlist +server=/whatsapp.org/127.0.0.1#5335 +ipset=/whatsapp.org/gfwlist +server=/netflixdnstest10.com/127.0.0.1#5335 +ipset=/netflixdnstest10.com/gfwlist +server=/toprealvideos.com/127.0.0.1#5335 +ipset=/toprealvideos.com/gfwlist +server=/needforspeedredline.com/127.0.0.1#5335 +ipset=/needforspeedredline.com/gfwlist +server=/bmw.pl/127.0.0.1#5335 +ipset=/bmw.pl/gfwlist +server=/dvdstudiopro.net/127.0.0.1#5335 +ipset=/dvdstudiopro.net/gfwlist +server=/qt.io/127.0.0.1#5335 +ipset=/qt.io/gfwlist +server=/boltdns.net/127.0.0.1#5335 +ipset=/boltdns.net/gfwlist +server=/mastercard.az/127.0.0.1#5335 +ipset=/mastercard.az/gfwlist +server=/porndork.com/127.0.0.1#5335 +ipset=/porndork.com/gfwlist +server=/asahi.com/127.0.0.1#5335 +ipset=/asahi.com/gfwlist +server=/vimeostatus.com/127.0.0.1#5335 +ipset=/vimeostatus.com/gfwlist +server=/omg.adult/127.0.0.1#5335 +ipset=/omg.adult/gfwlist +server=/amateurslovesporn.com/127.0.0.1#5335 +ipset=/amateurslovesporn.com/gfwlist +server=/googlefinland.com/127.0.0.1#5335 +ipset=/googlefinland.com/gfwlist +server=/shellcheck.net/127.0.0.1#5335 +ipset=/shellcheck.net/gfwlist +server=/volvotrucks.co.zm/127.0.0.1#5335 +ipset=/volvotrucks.co.zm/gfwlist +server=/attalascom.com/127.0.0.1#5335 +ipset=/attalascom.com/gfwlist +server=/discord.store/127.0.0.1#5335 +ipset=/discord.store/gfwlist +server=/angulardart.org/127.0.0.1#5335 +ipset=/angulardart.org/gfwlist +server=/cybertrust.co.jp/127.0.0.1#5335 +ipset=/cybertrust.co.jp/gfwlist +server=/mini-jordan.com/127.0.0.1#5335 +ipset=/mini-jordan.com/gfwlist +server=/tandberg.com/127.0.0.1#5335 +ipset=/tandberg.com/gfwlist +server=/tryrating.com/127.0.0.1#5335 +ipset=/tryrating.com/gfwlist +server=/hpbestbuy.com/127.0.0.1#5335 +ipset=/hpbestbuy.com/gfwlist +server=/familyporn.tv/127.0.0.1#5335 +ipset=/familyporn.tv/gfwlist +server=/axios.com/127.0.0.1#5335 +ipset=/axios.com/gfwlist +server=/pornodanke.com/127.0.0.1#5335 +ipset=/pornodanke.com/gfwlist +server=/imacsources.com/127.0.0.1#5335 +ipset=/imacsources.com/gfwlist +server=/insidefilms.com/127.0.0.1#5335 +ipset=/insidefilms.com/gfwlist +server=/camwhoreshd.com/127.0.0.1#5335 +ipset=/camwhoreshd.com/gfwlist +server=/gwiki.net/127.0.0.1#5335 +ipset=/gwiki.net/gfwlist +server=/epochmediagroup.com/127.0.0.1#5335 +ipset=/epochmediagroup.com/gfwlist +server=/ebayenterprise.net/127.0.0.1#5335 +ipset=/ebayenterprise.net/gfwlist +server=/hentaisub.info/127.0.0.1#5335 +ipset=/hentaisub.info/gfwlist +server=/cheapbeatsbydremall.com/127.0.0.1#5335 +ipset=/cheapbeatsbydremall.com/gfwlist +server=/muji.com/127.0.0.1#5335 +ipset=/muji.com/gfwlist +server=/macbookair.com.es/127.0.0.1#5335 +ipset=/macbookair.com.es/gfwlist +server=/iphone5.com/127.0.0.1#5335 +ipset=/iphone5.com/gfwlist +server=/rolsociety.org/127.0.0.1#5335 +ipset=/rolsociety.org/gfwlist +server=/digitalplayground.com/127.0.0.1#5335 +ipset=/digitalplayground.com/gfwlist +server=/2371tom.com/127.0.0.1#5335 +ipset=/2371tom.com/gfwlist +server=/google.mv/127.0.0.1#5335 +ipset=/google.mv/gfwlist +server=/apkpure.com/127.0.0.1#5335 +ipset=/apkpure.com/gfwlist +server=/fotolja.com/127.0.0.1#5335 +ipset=/fotolja.com/gfwlist +server=/nintendo-europe-sales.com/127.0.0.1#5335 +ipset=/nintendo-europe-sales.com/gfwlist +server=/jav-vr.net/127.0.0.1#5335 +ipset=/jav-vr.net/gfwlist +server=/updatetube.com/127.0.0.1#5335 +ipset=/updatetube.com/gfwlist +server=/kindleoasis.jp/127.0.0.1#5335 +ipset=/kindleoasis.jp/gfwlist +server=/durex.es/127.0.0.1#5335 +ipset=/durex.es/gfwlist +server=/nikeshoesinc.com/127.0.0.1#5335 +ipset=/nikeshoesinc.com/gfwlist +server=/getdropbox.com/127.0.0.1#5335 +ipset=/getdropbox.com/gfwlist +server=/bastillepost.com/127.0.0.1#5335 +ipset=/bastillepost.com/gfwlist +server=/ikea.ch/127.0.0.1#5335 +ipset=/ikea.ch/gfwlist +server=/ikea.gr/127.0.0.1#5335 +ipset=/ikea.gr/gfwlist +server=/camster.com/127.0.0.1#5335 +ipset=/camster.com/gfwlist +server=/trueanal.com/127.0.0.1#5335 +ipset=/trueanal.com/gfwlist +server=/foxsports.pe/127.0.0.1#5335 +ipset=/foxsports.pe/gfwlist +server=/milta1980.co.uk/127.0.0.1#5335 +ipset=/milta1980.co.uk/gfwlist +server=/indiangirlsclub.com/127.0.0.1#5335 +ipset=/indiangirlsclub.com/gfwlist +server=/justswallows.com/127.0.0.1#5335 +ipset=/justswallows.com/gfwlist +server=/bmw-motorrad.co/127.0.0.1#5335 +ipset=/bmw-motorrad.co/gfwlist +server=/google.hu/127.0.0.1#5335 +ipset=/google.hu/gfwlist +server=/sissy-university.com/127.0.0.1#5335 +ipset=/sissy-university.com/gfwlist +server=/bmw-connecteddrive.ru/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ru/gfwlist +server=/hkbnes.net/127.0.0.1#5335 +ipset=/hkbnes.net/gfwlist +server=/hdouban.com/127.0.0.1#5335 +ipset=/hdouban.com/gfwlist +server=/dogspics.net/127.0.0.1#5335 +ipset=/dogspics.net/gfwlist +server=/avpanda.cc/127.0.0.1#5335 +ipset=/avpanda.cc/gfwlist +server=/oxfordwesternmusic.com/127.0.0.1#5335 +ipset=/oxfordwesternmusic.com/gfwlist +server=/disney.asia/127.0.0.1#5335 +ipset=/disney.asia/gfwlist +server=/scholar.google.com.au/127.0.0.1#5335 +ipset=/scholar.google.com.au/gfwlist +server=/bmw-museum.com/127.0.0.1#5335 +ipset=/bmw-museum.com/gfwlist +server=/foxgay.com/127.0.0.1#5335 +ipset=/foxgay.com/gfwlist +server=/gfpics.com/127.0.0.1#5335 +ipset=/gfpics.com/gfwlist +server=/vmwlabconnect.com/127.0.0.1#5335 +ipset=/vmwlabconnect.com/gfwlist +server=/indiansexpussy.com/127.0.0.1#5335 +ipset=/indiansexpussy.com/gfwlist +server=/t21ipau.nikkei.co.jp/127.0.0.1#5335 +ipset=/t21ipau.nikkei.co.jp/gfwlist +server=/kyodo-d.info/127.0.0.1#5335 +ipset=/kyodo-d.info/gfwlist +server=/qwant.it/127.0.0.1#5335 +ipset=/qwant.it/gfwlist +server=/ebay-cz.com/127.0.0.1#5335 +ipset=/ebay-cz.com/gfwlist +server=/mariadb.org/127.0.0.1#5335 +ipset=/mariadb.org/gfwlist +server=/mat6tube.com/127.0.0.1#5335 +ipset=/mat6tube.com/gfwlist +server=/acmvalidationsaws.com/127.0.0.1#5335 +ipset=/acmvalidationsaws.com/gfwlist +server=/hkbigman.net/127.0.0.1#5335 +ipset=/hkbigman.net/gfwlist +server=/beatsbydreheadphones-nz.com/127.0.0.1#5335 +ipset=/beatsbydreheadphones-nz.com/gfwlist +server=/scala-sbt.org/127.0.0.1#5335 +ipset=/scala-sbt.org/gfwlist +server=/appleiphone.net/127.0.0.1#5335 +ipset=/appleiphone.net/gfwlist +server=/3animalsextube.com/127.0.0.1#5335 +ipset=/3animalsextube.com/gfwlist +server=/macintoshsoftware.com/127.0.0.1#5335 +ipset=/macintoshsoftware.com/gfwlist +server=/onlyhentaistuff.com/127.0.0.1#5335 +ipset=/onlyhentaistuff.com/gfwlist +server=/sharizelvideos.com/127.0.0.1#5335 +ipset=/sharizelvideos.com/gfwlist +server=/indianporngirls.com/127.0.0.1#5335 +ipset=/indianporngirls.com/gfwlist +server=/scholar.google.lt/127.0.0.1#5335 +ipset=/scholar.google.lt/gfwlist +server=/minicaribbean.com/127.0.0.1#5335 +ipset=/minicaribbean.com/gfwlist +server=/vfsco.ch/127.0.0.1#5335 +ipset=/vfsco.ch/gfwlist +server=/javhard.org/127.0.0.1#5335 +ipset=/javhard.org/gfwlist +server=/adidas.ru/127.0.0.1#5335 +ipset=/adidas.ru/gfwlist +server=/yourfantasybeginsnow.com/127.0.0.1#5335 +ipset=/yourfantasybeginsnow.com/gfwlist +server=/milfpornpics.xxx/127.0.0.1#5335 +ipset=/milfpornpics.xxx/gfwlist +server=/mickey.tv/127.0.0.1#5335 +ipset=/mickey.tv/gfwlist +server=/bmw-diplomatic-sales.com/127.0.0.1#5335 +ipset=/bmw-diplomatic-sales.com/gfwlist +server=/appleid.hk/127.0.0.1#5335 +ipset=/appleid.hk/gfwlist +server=/paypal-photocard.com/127.0.0.1#5335 +ipset=/paypal-photocard.com/gfwlist +server=/misa-prod.s3.ap-northeast-1.amazonaws.com/127.0.0.1#5335 +ipset=/misa-prod.s3.ap-northeast-1.amazonaws.com/gfwlist +server=/infowars.com/127.0.0.1#5335 +ipset=/infowars.com/gfwlist +server=/lyzsxx.com/127.0.0.1#5335 +ipset=/lyzsxx.com/gfwlist +server=/bsw.jp/127.0.0.1#5335 +ipset=/bsw.jp/gfwlist +server=/4ertik.live/127.0.0.1#5335 +ipset=/4ertik.live/gfwlist +server=/gitlab.net/127.0.0.1#5335 +ipset=/gitlab.net/gfwlist +server=/kissjav.li/127.0.0.1#5335 +ipset=/kissjav.li/gfwlist +server=/kaob3.xyz/127.0.0.1#5335 +ipset=/kaob3.xyz/gfwlist +server=/tblop.com/127.0.0.1#5335 +ipset=/tblop.com/gfwlist +server=/oxfordscholarship.com/127.0.0.1#5335 +ipset=/oxfordscholarship.com/gfwlist +server=/wellmaturetube.com/127.0.0.1#5335 +ipset=/wellmaturetube.com/gfwlist +server=/porkahd.co/127.0.0.1#5335 +ipset=/porkahd.co/gfwlist +server=/strepsils.com.ph/127.0.0.1#5335 +ipset=/strepsils.com.ph/gfwlist +server=/minneapolisbmw.net/127.0.0.1#5335 +ipset=/minneapolisbmw.net/gfwlist +server=/the-japan-news.com/127.0.0.1#5335 +ipset=/the-japan-news.com/gfwlist +server=/pornogramxxx.com/127.0.0.1#5335 +ipset=/pornogramxxx.com/gfwlist +server=/ibb.co/127.0.0.1#5335 +ipset=/ibb.co/gfwlist +server=/nintendo.de/127.0.0.1#5335 +ipset=/nintendo.de/gfwlist +server=/spotifyjobs.com/127.0.0.1#5335 +ipset=/spotifyjobs.com/gfwlist +server=/canon.kz/127.0.0.1#5335 +ipset=/canon.kz/gfwlist +server=/theclyster.com/127.0.0.1#5335 +ipset=/theclyster.com/gfwlist +server=/youtube.ng/127.0.0.1#5335 +ipset=/youtube.ng/gfwlist +server=/ipns.co/127.0.0.1#5335 +ipset=/ipns.co/gfwlist +server=/microsoft.rs/127.0.0.1#5335 +ipset=/microsoft.rs/gfwlist +server=/enemasupplier.com/127.0.0.1#5335 +ipset=/enemasupplier.com/gfwlist +server=/beatsbydrecustomwireless.com/127.0.0.1#5335 +ipset=/beatsbydrecustomwireless.com/gfwlist +server=/google.co.ug/127.0.0.1#5335 +ipset=/google.co.ug/gfwlist +server=/mashaalradio.com/127.0.0.1#5335 +ipset=/mashaalradio.com/gfwlist +server=/wireless.radio/127.0.0.1#5335 +ipset=/wireless.radio/gfwlist +server=/vultr.com/127.0.0.1#5335 +ipset=/vultr.com/gfwlist +server=/nyti.ms/127.0.0.1#5335 +ipset=/nyti.ms/gfwlist +server=/renchead.com/127.0.0.1#5335 +ipset=/renchead.com/gfwlist +server=/azureiotsuite.com/127.0.0.1#5335 +ipset=/azureiotsuite.com/gfwlist +server=/i.jeded.com/127.0.0.1#5335 +ipset=/i.jeded.com/gfwlist +server=/swingers-homemade-videos.com/127.0.0.1#5335 +ipset=/swingers-homemade-videos.com/gfwlist +server=/visamiddleeast.com/127.0.0.1#5335 +ipset=/visamiddleeast.com/gfwlist +server=/banatal3arab.com/127.0.0.1#5335 +ipset=/banatal3arab.com/gfwlist +server=/proxyadult.org/127.0.0.1#5335 +ipset=/proxyadult.org/gfwlist +server=/visaluxuryhotelcollection.com.mx/127.0.0.1#5335 +ipset=/visaluxuryhotelcollection.com.mx/gfwlist +server=/gastrointestinalexam.com/127.0.0.1#5335 +ipset=/gastrointestinalexam.com/gfwlist +server=/imovie.eu/127.0.0.1#5335 +ipset=/imovie.eu/gfwlist +server=/wantmywife.com/127.0.0.1#5335 +ipset=/wantmywife.com/gfwlist +server=/avstar2.com/127.0.0.1#5335 +ipset=/avstar2.com/gfwlist +server=/dawngatechronicles.com/127.0.0.1#5335 +ipset=/dawngatechronicles.com/gfwlist +server=/ohsexotube.com/127.0.0.1#5335 +ipset=/ohsexotube.com/gfwlist +server=/facultyopinions.com/127.0.0.1#5335 +ipset=/facultyopinions.com/gfwlist +server=/azureedge.net/127.0.0.1#5335 +ipset=/azureedge.net/gfwlist +server=/faicbooc.com/127.0.0.1#5335 +ipset=/faicbooc.com/gfwlist +server=/cash.app/127.0.0.1#5335 +ipset=/cash.app/gfwlist +server=/applewatchedition.com/127.0.0.1#5335 +ipset=/applewatchedition.com/gfwlist +server=/filme2.xxx/127.0.0.1#5335 +ipset=/filme2.xxx/gfwlist +server=/dssott.com/127.0.0.1#5335 +ipset=/dssott.com/gfwlist +server=/duckmovie.com/127.0.0.1#5335 +ipset=/duckmovie.com/gfwlist +server=/earpod.net/127.0.0.1#5335 +ipset=/earpod.net/gfwlist +server=/ss7.app/127.0.0.1#5335 +ipset=/ss7.app/gfwlist +server=/ipfs.anonymize.com/127.0.0.1#5335 +ipset=/ipfs.anonymize.com/gfwlist +server=/megapornpics.com/127.0.0.1#5335 +ipset=/megapornpics.com/gfwlist +server=/ipodcleaner.com/127.0.0.1#5335 +ipset=/ipodcleaner.com/gfwlist +server=/facebof.com/127.0.0.1#5335 +ipset=/facebof.com/gfwlist +server=/apyarstorybooks.blogspot.com/127.0.0.1#5335 +ipset=/apyarstorybooks.blogspot.com/gfwlist +server=/activelearnprimary.com.au/127.0.0.1#5335 +ipset=/activelearnprimary.com.au/gfwlist +server=/deepfreeze.tech/127.0.0.1#5335 +ipset=/deepfreeze.tech/gfwlist +server=/swingersexorgy.com/127.0.0.1#5335 +ipset=/swingersexorgy.com/gfwlist +server=/leavinghpinc.com/127.0.0.1#5335 +ipset=/leavinghpinc.com/gfwlist +server=/foampositeshoes.com/127.0.0.1#5335 +ipset=/foampositeshoes.com/gfwlist +server=/pornadoo.com/127.0.0.1#5335 +ipset=/pornadoo.com/gfwlist +server=/ilecture.co.nz/127.0.0.1#5335 +ipset=/ilecture.co.nz/gfwlist +server=/volvotrucks.pe/127.0.0.1#5335 +ipset=/volvotrucks.pe/gfwlist +server=/office.com/127.0.0.1#5335 +ipset=/office.com/gfwlist +server=/pinterestmail.com/127.0.0.1#5335 +ipset=/pinterestmail.com/gfwlist +server=/immoral.jp/127.0.0.1#5335 +ipset=/immoral.jp/gfwlist +server=/visa.com.gt/127.0.0.1#5335 +ipset=/visa.com.gt/gfwlist +server=/bodyandsoul.com.au/127.0.0.1#5335 +ipset=/bodyandsoul.com.au/gfwlist +server=/veet.no/127.0.0.1#5335 +ipset=/veet.no/gfwlist +server=/premiumbooty.com/127.0.0.1#5335 +ipset=/premiumbooty.com/gfwlist +server=/nineteentube.com/127.0.0.1#5335 +ipset=/nineteentube.com/gfwlist +server=/adidas.at/127.0.0.1#5335 +ipset=/adidas.at/gfwlist +server=/saleblackfridaydrebeats.com/127.0.0.1#5335 +ipset=/saleblackfridaydrebeats.com/gfwlist +server=/youtube.mn/127.0.0.1#5335 +ipset=/youtube.mn/gfwlist +server=/paypal-activate.org/127.0.0.1#5335 +ipset=/paypal-activate.org/gfwlist +server=/icloud-isupport.com/127.0.0.1#5335 +ipset=/icloud-isupport.com/gfwlist +server=/south-plus.net/127.0.0.1#5335 +ipset=/south-plus.net/gfwlist +server=/foxsports.com.pe/127.0.0.1#5335 +ipset=/foxsports.com.pe/gfwlist +server=/mydirtyhobby.com/127.0.0.1#5335 +ipset=/mydirtyhobby.com/gfwlist +server=/adultgames18.com/127.0.0.1#5335 +ipset=/adultgames18.com/gfwlist +server=/internetexplorer.co/127.0.0.1#5335 +ipset=/internetexplorer.co/gfwlist +server=/ifontcloud.com/127.0.0.1#5335 +ipset=/ifontcloud.com/gfwlist +server=/strepsils.pt/127.0.0.1#5335 +ipset=/strepsils.pt/gfwlist +server=/darksidemagazine.com/127.0.0.1#5335 +ipset=/darksidemagazine.com/gfwlist +server=/crazyshit.com/127.0.0.1#5335 +ipset=/crazyshit.com/gfwlist +server=/bustymomsvideo.com/127.0.0.1#5335 +ipset=/bustymomsvideo.com/gfwlist +server=/archiveofourown.com/127.0.0.1#5335 +ipset=/archiveofourown.com/gfwlist +server=/kidsnikeshoes.com/127.0.0.1#5335 +ipset=/kidsnikeshoes.com/gfwlist +server=/macports.org/127.0.0.1#5335 +ipset=/macports.org/gfwlist +server=/wetplace.com/127.0.0.1#5335 +ipset=/wetplace.com/gfwlist +server=/eromanga-school.com/127.0.0.1#5335 +ipset=/eromanga-school.com/gfwlist +server=/babesbang.com/127.0.0.1#5335 +ipset=/babesbang.com/gfwlist +server=/alpherafinancialservices.in/127.0.0.1#5335 +ipset=/alpherafinancialservices.in/gfwlist +server=/mask.icloud.com/127.0.0.1#5335 +ipset=/mask.icloud.com/gfwlist +server=/photos18.com/127.0.0.1#5335 +ipset=/photos18.com/gfwlist +server=/gohentai.net/127.0.0.1#5335 +ipset=/gohentai.net/gfwlist +server=/venmo.info/127.0.0.1#5335 +ipset=/venmo.info/gfwlist +server=/mini.in/127.0.0.1#5335 +ipset=/mini.in/gfwlist +server=/yandex.fr/127.0.0.1#5335 +ipset=/yandex.fr/gfwlist +server=/dianapost.com/127.0.0.1#5335 +ipset=/dianapost.com/gfwlist +server=/grss-ieee.org/127.0.0.1#5335 +ipset=/grss-ieee.org/gfwlist +server=/fandom.zendesk.com/127.0.0.1#5335 +ipset=/fandom.zendesk.com/gfwlist +server=/escortrankings.uk/127.0.0.1#5335 +ipset=/escortrankings.uk/gfwlist +server=/ptzwx.com/127.0.0.1#5335 +ipset=/ptzwx.com/gfwlist +server=/strepsils.si/127.0.0.1#5335 +ipset=/strepsils.si/gfwlist +server=/uriminzokkiri.com/127.0.0.1#5335 +ipset=/uriminzokkiri.com/gfwlist +server=/as-hls-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/as-hls-uk-live.akamaized.net/gfwlist +server=/winudf.com/127.0.0.1#5335 +ipset=/winudf.com/gfwlist +server=/boylove.live/127.0.0.1#5335 +ipset=/boylove.live/gfwlist +server=/paypal-center.org/127.0.0.1#5335 +ipset=/paypal-center.org/gfwlist +server=/discordactivities.com/127.0.0.1#5335 +ipset=/discordactivities.com/gfwlist +server=/familymart.com.my/127.0.0.1#5335 +ipset=/familymart.com.my/gfwlist +server=/bmw-motorrad.pt/127.0.0.1#5335 +ipset=/bmw-motorrad.pt/gfwlist +server=/nikefind.com/127.0.0.1#5335 +ipset=/nikefind.com/gfwlist +server=/nintendoswitch.net/127.0.0.1#5335 +ipset=/nintendoswitch.net/gfwlist +server=/nicky.xxx/127.0.0.1#5335 +ipset=/nicky.xxx/gfwlist +server=/sxarab.top/127.0.0.1#5335 +ipset=/sxarab.top/gfwlist +server=/airsupportapp.com/127.0.0.1#5335 +ipset=/airsupportapp.com/gfwlist +server=/tati-log.com/127.0.0.1#5335 +ipset=/tati-log.com/gfwlist +server=/akatns.net/127.0.0.1#5335 +ipset=/akatns.net/gfwlist +server=/zhainanjidid.top/127.0.0.1#5335 +ipset=/zhainanjidid.top/gfwlist +server=/porngo.com/127.0.0.1#5335 +ipset=/porngo.com/gfwlist +server=/zeenews.com/127.0.0.1#5335 +ipset=/zeenews.com/gfwlist +server=/facebookcanadianelectionintegrityinitiative.com/127.0.0.1#5335 +ipset=/facebookcanadianelectionintegrityinitiative.com/gfwlist +server=/casquebeatsfracheter.com/127.0.0.1#5335 +ipset=/casquebeatsfracheter.com/gfwlist +server=/ibm.eu/127.0.0.1#5335 +ipset=/ibm.eu/gfwlist +server=/analscreen.com/127.0.0.1#5335 +ipset=/analscreen.com/gfwlist +server=/tube8.com/127.0.0.1#5335 +ipset=/tube8.com/gfwlist +server=/airwick.sk/127.0.0.1#5335 +ipset=/airwick.sk/gfwlist +server=/clco.cc/127.0.0.1#5335 +ipset=/clco.cc/gfwlist +server=/intel.ba/127.0.0.1#5335 +ipset=/intel.ba/gfwlist +server=/imgsmail.ru/127.0.0.1#5335 +ipset=/imgsmail.ru/gfwlist +server=/duckduckgo.com.mx/127.0.0.1#5335 +ipset=/duckduckgo.com.mx/gfwlist +server=/machogaytube.com/127.0.0.1#5335 +ipset=/machogaytube.com/gfwlist +server=/bitporno.com/127.0.0.1#5335 +ipset=/bitporno.com/gfwlist +server=/pearsoncmg.com/127.0.0.1#5335 +ipset=/pearsoncmg.com/gfwlist +server=/underlords.com/127.0.0.1#5335 +ipset=/underlords.com/gfwlist +server=/karger.com/127.0.0.1#5335 +ipset=/karger.com/gfwlist +server=/beatsdre.net/127.0.0.1#5335 +ipset=/beatsdre.net/gfwlist +server=/aebn.com/127.0.0.1#5335 +ipset=/aebn.com/gfwlist +server=/revenue-performance-management.com/127.0.0.1#5335 +ipset=/revenue-performance-management.com/gfwlist +server=/coithienthai.com/127.0.0.1#5335 +ipset=/coithienthai.com/gfwlist +server=/epochtimeshk.org/127.0.0.1#5335 +ipset=/epochtimeshk.org/gfwlist +server=/watch-porn.net/127.0.0.1#5335 +ipset=/watch-porn.net/gfwlist +server=/google.com.ag/127.0.0.1#5335 +ipset=/google.com.ag/gfwlist +server=/yahoo.com.gt/127.0.0.1#5335 +ipset=/yahoo.com.gt/gfwlist +server=/mini.com.pl/127.0.0.1#5335 +ipset=/mini.com.pl/gfwlist +server=/miniso.by/127.0.0.1#5335 +ipset=/miniso.by/gfwlist +server=/beatsbydres-shop.com/127.0.0.1#5335 +ipset=/beatsbydres-shop.com/gfwlist +server=/pokemon.com/127.0.0.1#5335 +ipset=/pokemon.com/gfwlist +server=/nijifeti.com/127.0.0.1#5335 +ipset=/nijifeti.com/gfwlist +server=/videoindexer.ai/127.0.0.1#5335 +ipset=/videoindexer.ai/gfwlist +server=/youporner.eu/127.0.0.1#5335 +ipset=/youporner.eu/gfwlist +server=/wmflabs.org/127.0.0.1#5335 +ipset=/wmflabs.org/gfwlist +server=/widevine.com/127.0.0.1#5335 +ipset=/widevine.com/gfwlist +server=/realestate.com.au/127.0.0.1#5335 +ipset=/realestate.com.au/gfwlist +server=/calgon.tv/127.0.0.1#5335 +ipset=/calgon.tv/gfwlist +server=/javsex.to/127.0.0.1#5335 +ipset=/javsex.to/gfwlist +server=/mylf.com/127.0.0.1#5335 +ipset=/mylf.com/gfwlist +server=/fm4.jp/127.0.0.1#5335 +ipset=/fm4.jp/gfwlist +server=/ipod.com.tw/127.0.0.1#5335 +ipset=/ipod.com.tw/gfwlist +server=/zaobao.sg/127.0.0.1#5335 +ipset=/zaobao.sg/gfwlist +server=/xbox360.eu/127.0.0.1#5335 +ipset=/xbox360.eu/gfwlist +server=/swisssign-group.com/127.0.0.1#5335 +ipset=/swisssign-group.com/gfwlist +server=/askubuntu.com/127.0.0.1#5335 +ipset=/askubuntu.com/gfwlist +server=/nfsc.global/127.0.0.1#5335 +ipset=/nfsc.global/gfwlist +server=/sociolotron.com/127.0.0.1#5335 +ipset=/sociolotron.com/gfwlist +server=/myfonts.net/127.0.0.1#5335 +ipset=/myfonts.net/gfwlist +server=/krux.com/127.0.0.1#5335 +ipset=/krux.com/gfwlist +server=/github.community/127.0.0.1#5335 +ipset=/github.community/gfwlist +server=/gputechconf.co.kr/127.0.0.1#5335 +ipset=/gputechconf.co.kr/gfwlist +server=/morganclaypool.com/127.0.0.1#5335 +ipset=/morganclaypool.com/gfwlist +server=/xn--6eup7j.net/127.0.0.1#5335 +ipset=/xn--6eup7j.net/gfwlist +server=/youtube.com.hn/127.0.0.1#5335 +ipset=/youtube.com.hn/gfwlist +server=/packer.io/127.0.0.1#5335 +ipset=/packer.io/gfwlist +server=/bethsoft.com/127.0.0.1#5335 +ipset=/bethsoft.com/gfwlist +server=/epikporn.com/127.0.0.1#5335 +ipset=/epikporn.com/gfwlist +server=/filmporno.it/127.0.0.1#5335 +ipset=/filmporno.it/gfwlist +server=/moez-m.com/127.0.0.1#5335 +ipset=/moez-m.com/gfwlist +server=/microsoftgamestack.com/127.0.0.1#5335 +ipset=/microsoftgamestack.com/gfwlist +server=/9to5terminal.com/127.0.0.1#5335 +ipset=/9to5terminal.com/gfwlist +server=/anilos.com/127.0.0.1#5335 +ipset=/anilos.com/gfwlist +server=/travelex.it/127.0.0.1#5335 +ipset=/travelex.it/gfwlist +server=/asproexapi.com/127.0.0.1#5335 +ipset=/asproexapi.com/gfwlist +server=/yahoo.com.lb/127.0.0.1#5335 +ipset=/yahoo.com.lb/gfwlist +server=/isca-speech.org/127.0.0.1#5335 +ipset=/isca-speech.org/gfwlist +server=/icloud.fr/127.0.0.1#5335 +ipset=/icloud.fr/gfwlist +server=/v8project.org/127.0.0.1#5335 +ipset=/v8project.org/gfwlist +server=/avgigi.com/127.0.0.1#5335 +ipset=/avgigi.com/gfwlist +server=/pornomineiro.com/127.0.0.1#5335 +ipset=/pornomineiro.com/gfwlist +server=/veet.us/127.0.0.1#5335 +ipset=/veet.us/gfwlist +server=/yiqiedoushiganggangkaishi.org/127.0.0.1#5335 +ipset=/yiqiedoushiganggangkaishi.org/gfwlist +server=/porno800.com/127.0.0.1#5335 +ipset=/porno800.com/gfwlist +server=/yarnpkg.com/127.0.0.1#5335 +ipset=/yarnpkg.com/gfwlist +server=/visa.mn/127.0.0.1#5335 +ipset=/visa.mn/gfwlist +server=/adidas.co.in/127.0.0.1#5335 +ipset=/adidas.co.in/gfwlist +server=/cc18.tv/127.0.0.1#5335 +ipset=/cc18.tv/gfwlist +server=/sky.com/127.0.0.1#5335 +ipset=/sky.com/gfwlist +server=/facebook.org/127.0.0.1#5335 +ipset=/facebook.org/gfwlist +server=/beatsbydrdrestore.com/127.0.0.1#5335 +ipset=/beatsbydrdrestore.com/gfwlist +server=/insider-intelligence.com/127.0.0.1#5335 +ipset=/insider-intelligence.com/gfwlist +server=/gclubs.com/127.0.0.1#5335 +ipset=/gclubs.com/gfwlist +server=/sustainthesound.com/127.0.0.1#5335 +ipset=/sustainthesound.com/gfwlist +server=/budatt.com/127.0.0.1#5335 +ipset=/budatt.com/gfwlist +server=/kilmeadeandfriends.com/127.0.0.1#5335 +ipset=/kilmeadeandfriends.com/gfwlist +server=/nikenews.com/127.0.0.1#5335 +ipset=/nikenews.com/gfwlist +server=/bestporncomix.com/127.0.0.1#5335 +ipset=/bestporncomix.com/gfwlist +server=/onenote.com/127.0.0.1#5335 +ipset=/onenote.com/gfwlist +server=/javtorrent.me/127.0.0.1#5335 +ipset=/javtorrent.me/gfwlist +server=/bmwmass.com/127.0.0.1#5335 +ipset=/bmwmass.com/gfwlist +server=/facebookpokerchips.info/127.0.0.1#5335 +ipset=/facebookpokerchips.info/gfwlist +server=/researchkit.tv/127.0.0.1#5335 +ipset=/researchkit.tv/gfwlist +server=/free3dadultgames.com/127.0.0.1#5335 +ipset=/free3dadultgames.com/gfwlist +server=/facebookstudios.org/127.0.0.1#5335 +ipset=/facebookstudios.org/gfwlist +server=/zeplin.io/127.0.0.1#5335 +ipset=/zeplin.io/gfwlist +server=/ourshemales.com/127.0.0.1#5335 +ipset=/ourshemales.com/gfwlist +server=/beeg.com/127.0.0.1#5335 +ipset=/beeg.com/gfwlist +server=/macbookair.co.uk/127.0.0.1#5335 +ipset=/macbookair.co.uk/gfwlist +server=/milfs-now.com/127.0.0.1#5335 +ipset=/milfs-now.com/gfwlist +server=/dengiamerika.com/127.0.0.1#5335 +ipset=/dengiamerika.com/gfwlist +server=/sex0098.com/127.0.0.1#5335 +ipset=/sex0098.com/gfwlist +server=/discordpartygames.com/127.0.0.1#5335 +ipset=/discordpartygames.com/gfwlist +server=/twitterinc.com/127.0.0.1#5335 +ipset=/twitterinc.com/gfwlist +server=/miniso.my/127.0.0.1#5335 +ipset=/miniso.my/gfwlist +server=/pearsonassessment.be/127.0.0.1#5335 +ipset=/pearsonassessment.be/gfwlist +server=/wujieliulan.com/127.0.0.1#5335 +ipset=/wujieliulan.com/gfwlist +server=/onsalekey.com/127.0.0.1#5335 +ipset=/onsalekey.com/gfwlist +server=/issitedownrightnow.com/127.0.0.1#5335 +ipset=/issitedownrightnow.com/gfwlist +server=/disneysrivieraresort.com/127.0.0.1#5335 +ipset=/disneysrivieraresort.com/gfwlist +server=/canon.lv/127.0.0.1#5335 +ipset=/canon.lv/gfwlist +server=/directvmonitoring.com/127.0.0.1#5335 +ipset=/directvmonitoring.com/gfwlist +server=/strepsils.at/127.0.0.1#5335 +ipset=/strepsils.at/gfwlist +server=/kenyanporn.blogspot.com/127.0.0.1#5335 +ipset=/kenyanporn.blogspot.com/gfwlist +server=/amplifyapp.com/127.0.0.1#5335 +ipset=/amplifyapp.com/gfwlist +server=/lge.co.kr/127.0.0.1#5335 +ipset=/lge.co.kr/gfwlist +server=/beatsbydrsmonsterinusa.com/127.0.0.1#5335 +ipset=/beatsbydrsmonsterinusa.com/gfwlist +server=/pornocaserotube.com/127.0.0.1#5335 +ipset=/pornocaserotube.com/gfwlist +server=/q13.com/127.0.0.1#5335 +ipset=/q13.com/gfwlist +server=/adult-home-videos.com/127.0.0.1#5335 +ipset=/adult-home-videos.com/gfwlist +server=/pornofilmlist.com/127.0.0.1#5335 +ipset=/pornofilmlist.com/gfwlist +server=/steamcommunity.com/127.0.0.1#5335 +ipset=/steamcommunity.com/gfwlist +server=/onlineporn-vids.com/127.0.0.1#5335 +ipset=/onlineporn-vids.com/gfwlist +server=/airwick.cl/127.0.0.1#5335 +ipset=/airwick.cl/gfwlist +server=/ebayads.net/127.0.0.1#5335 +ipset=/ebayads.net/gfwlist +server=/amazon-jp-recruiting.com/127.0.0.1#5335 +ipset=/amazon-jp-recruiting.com/gfwlist +server=/worldsex.com/127.0.0.1#5335 +ipset=/worldsex.com/gfwlist +server=/bbbaihu.vip/127.0.0.1#5335 +ipset=/bbbaihu.vip/gfwlist +server=/haho.moe/127.0.0.1#5335 +ipset=/haho.moe/gfwlist +server=/bloomsburydesignlibrary.com/127.0.0.1#5335 +ipset=/bloomsburydesignlibrary.com/gfwlist +server=/pearson-intl.com/127.0.0.1#5335 +ipset=/pearson-intl.com/gfwlist +server=/facbook.com/127.0.0.1#5335 +ipset=/facbook.com/gfwlist +server=/bmw-motorrad.jp/127.0.0.1#5335 +ipset=/bmw-motorrad.jp/gfwlist +server=/hqdesexo.com/127.0.0.1#5335 +ipset=/hqdesexo.com/gfwlist +server=/suruga-ya.com/127.0.0.1#5335 +ipset=/suruga-ya.com/gfwlist +server=/usertrust.com/127.0.0.1#5335 +ipset=/usertrust.com/gfwlist +server=/rakuten.com.tw/127.0.0.1#5335 +ipset=/rakuten.com.tw/gfwlist +server=/xxxfile.org/127.0.0.1#5335 +ipset=/xxxfile.org/gfwlist +server=/hamsterporn.tv/127.0.0.1#5335 +ipset=/hamsterporn.tv/gfwlist +server=/isgame365.cc/127.0.0.1#5335 +ipset=/isgame365.cc/gfwlist +server=/googleoptimize.com/127.0.0.1#5335 +ipset=/googleoptimize.com/gfwlist +server=/garotaporno.com/127.0.0.1#5335 +ipset=/garotaporno.com/gfwlist +server=/intel.pe/127.0.0.1#5335 +ipset=/intel.pe/gfwlist +server=/beatsbydreshops.net/127.0.0.1#5335 +ipset=/beatsbydreshops.net/gfwlist +server=/nikecraft.com/127.0.0.1#5335 +ipset=/nikecraft.com/gfwlist +server=/boylabs.net/127.0.0.1#5335 +ipset=/boylabs.net/gfwlist +server=/hpsmartstage.com/127.0.0.1#5335 +ipset=/hpsmartstage.com/gfwlist +server=/stark-verlag.ch/127.0.0.1#5335 +ipset=/stark-verlag.ch/gfwlist +server=/visadpsonline.us/127.0.0.1#5335 +ipset=/visadpsonline.us/gfwlist +server=/menshin-channel.com/127.0.0.1#5335 +ipset=/menshin-channel.com/gfwlist +server=/sonyprotechnosupport.co.jp/127.0.0.1#5335 +ipset=/sonyprotechnosupport.co.jp/gfwlist +server=/applepaysupplies.com/127.0.0.1#5335 +ipset=/applepaysupplies.com/gfwlist +server=/devcon.org/127.0.0.1#5335 +ipset=/devcon.org/gfwlist +server=/thomsonreuters.co.kr/127.0.0.1#5335 +ipset=/thomsonreuters.co.kr/gfwlist +server=/apple.fr/127.0.0.1#5335 +ipset=/apple.fr/gfwlist +server=/macbookpro.com/127.0.0.1#5335 +ipset=/macbookpro.com/gfwlist +server=/ebayopen.com/127.0.0.1#5335 +ipset=/ebayopen.com/gfwlist +server=/bmw.de/127.0.0.1#5335 +ipset=/bmw.de/gfwlist +server=/copro.pw/127.0.0.1#5335 +ipset=/copro.pw/gfwlist +server=/volvotrucks.al/127.0.0.1#5335 +ipset=/volvotrucks.al/gfwlist +server=/rule34.xxx/127.0.0.1#5335 +ipset=/rule34.xxx/gfwlist +server=/facfebook.com/127.0.0.1#5335 +ipset=/facfebook.com/gfwlist +server=/xnxx2.pro/127.0.0.1#5335 +ipset=/xnxx2.pro/gfwlist +server=/edisebay.com/127.0.0.1#5335 +ipset=/edisebay.com/gfwlist +server=/yahoo.as/127.0.0.1#5335 +ipset=/yahoo.as/gfwlist +server=/bmw.sn/127.0.0.1#5335 +ipset=/bmw.sn/gfwlist +server=/yahoo.fr/127.0.0.1#5335 +ipset=/yahoo.fr/gfwlist +server=/bbcmedia.co.uk/127.0.0.1#5335 +ipset=/bbcmedia.co.uk/gfwlist +server=/paypal-communication.com/127.0.0.1#5335 +ipset=/paypal-communication.com/gfwlist +server=/rumah123.com/127.0.0.1#5335 +ipset=/rumah123.com/gfwlist +server=/zoosexfarm.com/127.0.0.1#5335 +ipset=/zoosexfarm.com/gfwlist +server=/icloude.com/127.0.0.1#5335 +ipset=/icloude.com/gfwlist +server=/youpornlist.com/127.0.0.1#5335 +ipset=/youpornlist.com/gfwlist +server=/strikinglycdn.com/127.0.0.1#5335 +ipset=/strikinglycdn.com/gfwlist +server=/sbitravelcard.com/127.0.0.1#5335 +ipset=/sbitravelcard.com/gfwlist +server=/ipodnano.com/127.0.0.1#5335 +ipset=/ipodnano.com/gfwlist +server=/disneybaby.com/127.0.0.1#5335 +ipset=/disneybaby.com/gfwlist +server=/veet.ca/127.0.0.1#5335 +ipset=/veet.ca/gfwlist +server=/xboxone.eu/127.0.0.1#5335 +ipset=/xboxone.eu/gfwlist +server=/pokemon-sunmoon.com/127.0.0.1#5335 +ipset=/pokemon-sunmoon.com/gfwlist +server=/mdn.mozillademos.org/127.0.0.1#5335 +ipset=/mdn.mozillademos.org/gfwlist +server=/aliveipc.com/127.0.0.1#5335 +ipset=/aliveipc.com/gfwlist +server=/homemadefucktube.com/127.0.0.1#5335 +ipset=/homemadefucktube.com/gfwlist +server=/vanish.si/127.0.0.1#5335 +ipset=/vanish.si/gfwlist +server=/cherrypimps.com/127.0.0.1#5335 +ipset=/cherrypimps.com/gfwlist +server=/ikea.com.mx/127.0.0.1#5335 +ipset=/ikea.com.mx/gfwlist +server=/beatsbydre-outlet.com/127.0.0.1#5335 +ipset=/beatsbydre-outlet.com/gfwlist +server=/porn4days.cc/127.0.0.1#5335 +ipset=/porn4days.cc/gfwlist +server=/hentai-for.net/127.0.0.1#5335 +ipset=/hentai-for.net/gfwlist +server=/behance.net/127.0.0.1#5335 +ipset=/behance.net/gfwlist +server=/brotli.org/127.0.0.1#5335 +ipset=/brotli.org/gfwlist +server=/newsamerica.com/127.0.0.1#5335 +ipset=/newsamerica.com/gfwlist +server=/customizedbeatsdre.com/127.0.0.1#5335 +ipset=/customizedbeatsdre.com/gfwlist +server=/xwebporn.com/127.0.0.1#5335 +ipset=/xwebporn.com/gfwlist +server=/medium.systems/127.0.0.1#5335 +ipset=/medium.systems/gfwlist +server=/ciscolive.com/127.0.0.1#5335 +ipset=/ciscolive.com/gfwlist +server=/hkej.com/127.0.0.1#5335 +ipset=/hkej.com/gfwlist +server=/windowsuem.com/127.0.0.1#5335 +ipset=/windowsuem.com/gfwlist +server=/bonedathome.com/127.0.0.1#5335 +ipset=/bonedathome.com/gfwlist +server=/mochajs.org/127.0.0.1#5335 +ipset=/mochajs.org/gfwlist +server=/link.theplatform.com/127.0.0.1#5335 +ipset=/link.theplatform.com/gfwlist +server=/omniture.com/127.0.0.1#5335 +ipset=/omniture.com/gfwlist +server=/microsoftnews.org/127.0.0.1#5335 +ipset=/microsoftnews.org/gfwlist +server=/bmwdealerdirect.com/127.0.0.1#5335 +ipset=/bmwdealerdirect.com/gfwlist +server=/mach-os.com/127.0.0.1#5335 +ipset=/mach-os.com/gfwlist +server=/mini.nl/127.0.0.1#5335 +ipset=/mini.nl/gfwlist +server=/mastercard.com.lb/127.0.0.1#5335 +ipset=/mastercard.com.lb/gfwlist +server=/limeteensex.com/127.0.0.1#5335 +ipset=/limeteensex.com/gfwlist +server=/bloombergindustry.com/127.0.0.1#5335 +ipset=/bloombergindustry.com/gfwlist +server=/nurgay.to/127.0.0.1#5335 +ipset=/nurgay.to/gfwlist +server=/netflixdnstest4.com/127.0.0.1#5335 +ipset=/netflixdnstest4.com/gfwlist +server=/canon.com.mt/127.0.0.1#5335 +ipset=/canon.com.mt/gfwlist +server=/hentaifox.com/127.0.0.1#5335 +ipset=/hentaifox.com/gfwlist +server=/breasthealthinfo.com/127.0.0.1#5335 +ipset=/breasthealthinfo.com/gfwlist +server=/thecuckoldporn.com/127.0.0.1#5335 +ipset=/thecuckoldporn.com/gfwlist +server=/drebeats-solo.com/127.0.0.1#5335 +ipset=/drebeats-solo.com/gfwlist +server=/visa.is/127.0.0.1#5335 +ipset=/visa.is/gfwlist +server=/youtubego.co.id/127.0.0.1#5335 +ipset=/youtubego.co.id/gfwlist +server=/finishwin.be/127.0.0.1#5335 +ipset=/finishwin.be/gfwlist +server=/cheapbeatsbydrefau.com/127.0.0.1#5335 +ipset=/cheapbeatsbydrefau.com/gfwlist +server=/b3bos.com/127.0.0.1#5335 +ipset=/b3bos.com/gfwlist +server=/vdoav.com/127.0.0.1#5335 +ipset=/vdoav.com/gfwlist +server=/adultartsites.com/127.0.0.1#5335 +ipset=/adultartsites.com/gfwlist +server=/alphabet.com.pt/127.0.0.1#5335 +ipset=/alphabet.com.pt/gfwlist +server=/ebayclassifiedsgroup.info/127.0.0.1#5335 +ipset=/ebayclassifiedsgroup.info/gfwlist +server=/applepay.tv/127.0.0.1#5335 +ipset=/applepay.tv/gfwlist +server=/arabysexy.mobi/127.0.0.1#5335 +ipset=/arabysexy.mobi/gfwlist +server=/mastercard.co.ke/127.0.0.1#5335 +ipset=/mastercard.co.ke/gfwlist +server=/beatsep.net/127.0.0.1#5335 +ipset=/beatsep.net/gfwlist +server=/beatsbydreol.com/127.0.0.1#5335 +ipset=/beatsbydreol.com/gfwlist +server=/twifuli.com/127.0.0.1#5335 +ipset=/twifuli.com/gfwlist +server=/youtube.com.pe/127.0.0.1#5335 +ipset=/youtube.com.pe/gfwlist +server=/sony.com.vn/127.0.0.1#5335 +ipset=/sony.com.vn/gfwlist +server=/beats-soaho.com/127.0.0.1#5335 +ipset=/beats-soaho.com/gfwlist +server=/bitvise.com/127.0.0.1#5335 +ipset=/bitvise.com/gfwlist +server=/bmw.co.kr/127.0.0.1#5335 +ipset=/bmw.co.kr/gfwlist +server=/xvideos5.com.br/127.0.0.1#5335 +ipset=/xvideos5.com.br/gfwlist +server=/nijieronavi.com/127.0.0.1#5335 +ipset=/nijieronavi.com/gfwlist +server=/adelaidenow.com.au/127.0.0.1#5335 +ipset=/adelaidenow.com.au/gfwlist +server=/discountedporn.com/127.0.0.1#5335 +ipset=/discountedporn.com/gfwlist +server=/igniteseurope.com/127.0.0.1#5335 +ipset=/igniteseurope.com/gfwlist +server=/redporno.cz/127.0.0.1#5335 +ipset=/redporno.cz/gfwlist +server=/starbucks.com.bn/127.0.0.1#5335 +ipset=/starbucks.com.bn/gfwlist +server=/xnostars.com/127.0.0.1#5335 +ipset=/xnostars.com/gfwlist +server=/icloud.is/127.0.0.1#5335 +ipset=/icloud.is/gfwlist +server=/bbwmilftube.com/127.0.0.1#5335 +ipset=/bbwmilftube.com/gfwlist +server=/milflove.live/127.0.0.1#5335 +ipset=/milflove.live/gfwlist +server=/r10s.com/127.0.0.1#5335 +ipset=/r10s.com/gfwlist +server=/icloud.fi/127.0.0.1#5335 +ipset=/icloud.fi/gfwlist +server=/facebookdusexe.org/127.0.0.1#5335 +ipset=/facebookdusexe.org/gfwlist +server=/mobile01.com/127.0.0.1#5335 +ipset=/mobile01.com/gfwlist +server=/googletagmanager.com/127.0.0.1#5335 +ipset=/googletagmanager.com/gfwlist +server=/visaicsdirect.com/127.0.0.1#5335 +ipset=/visaicsdirect.com/gfwlist +server=/ciscotr.com/127.0.0.1#5335 +ipset=/ciscotr.com/gfwlist +server=/beatsbydressale.com/127.0.0.1#5335 +ipset=/beatsbydressale.com/gfwlist +server=/sextubish.com/127.0.0.1#5335 +ipset=/sextubish.com/gfwlist +server=/volvotrucks.be/127.0.0.1#5335 +ipset=/volvotrucks.be/gfwlist +server=/dechamora.com/127.0.0.1#5335 +ipset=/dechamora.com/gfwlist +server=/move-free.net/127.0.0.1#5335 +ipset=/move-free.net/gfwlist +server=/pornteen123.com/127.0.0.1#5335 +ipset=/pornteen123.com/gfwlist +server=/applewallet.tv/127.0.0.1#5335 +ipset=/applewallet.tv/gfwlist +server=/sony.com.br/127.0.0.1#5335 +ipset=/sony.com.br/gfwlist +server=/pornfidelity.com/127.0.0.1#5335 +ipset=/pornfidelity.com/gfwlist +server=/hyu2.com/127.0.0.1#5335 +ipset=/hyu2.com/gfwlist +server=/directvmetropolisil.com/127.0.0.1#5335 +ipset=/directvmetropolisil.com/gfwlist +server=/detentiongirls.com/127.0.0.1#5335 +ipset=/detentiongirls.com/gfwlist +server=/bbg.gov/127.0.0.1#5335 +ipset=/bbg.gov/gfwlist +server=/ikea.no/127.0.0.1#5335 +ipset=/ikea.no/gfwlist +server=/java.com/127.0.0.1#5335 +ipset=/java.com/gfwlist +server=/javdoe.com/127.0.0.1#5335 +ipset=/javdoe.com/gfwlist +server=/applereach.com/127.0.0.1#5335 +ipset=/applereach.com/gfwlist +server=/erotic-photos.net/127.0.0.1#5335 +ipset=/erotic-photos.net/gfwlist +server=/volvotrucks.es/127.0.0.1#5335 +ipset=/volvotrucks.es/gfwlist +server=/kodi.wiki/127.0.0.1#5335 +ipset=/kodi.wiki/gfwlist +server=/oppai-doga.info/127.0.0.1#5335 +ipset=/oppai-doga.info/gfwlist +server=/nintendo.it/127.0.0.1#5335 +ipset=/nintendo.it/gfwlist +server=/blogspot.re/127.0.0.1#5335 +ipset=/blogspot.re/gfwlist +server=/cmpaas.com/127.0.0.1#5335 +ipset=/cmpaas.com/gfwlist +server=/xvideoz.win/127.0.0.1#5335 +ipset=/xvideoz.win/gfwlist +server=/beatsbydrecheaper.com/127.0.0.1#5335 +ipset=/beatsbydrecheaper.com/gfwlist +server=/attwirelessonline.com/127.0.0.1#5335 +ipset=/attwirelessonline.com/gfwlist +server=/nbc.co/127.0.0.1#5335 +ipset=/nbc.co/gfwlist +server=/yahoo.co.jp/127.0.0.1#5335 +ipset=/yahoo.co.jp/gfwlist +server=/applepay.rs/127.0.0.1#5335 +ipset=/applepay.rs/gfwlist +server=/amazon.red/127.0.0.1#5335 +ipset=/amazon.red/gfwlist +server=/happymeal.com.au/127.0.0.1#5335 +ipset=/happymeal.com.au/gfwlist +server=/maturesexual.com/127.0.0.1#5335 +ipset=/maturesexual.com/gfwlist +server=/intel.la/127.0.0.1#5335 +ipset=/intel.la/gfwlist +server=/fruitycams.com/127.0.0.1#5335 +ipset=/fruitycams.com/gfwlist +server=/bridgestonecomercial.com.ar/127.0.0.1#5335 +ipset=/bridgestonecomercial.com.ar/gfwlist +server=/multipornfor.me/127.0.0.1#5335 +ipset=/multipornfor.me/gfwlist +server=/wix.com/127.0.0.1#5335 +ipset=/wix.com/gfwlist +server=/blogspot.com/127.0.0.1#5335 +ipset=/blogspot.com/gfwlist +server=/sambaporno.com/127.0.0.1#5335 +ipset=/sambaporno.com/gfwlist +server=/aria.ms/127.0.0.1#5335 +ipset=/aria.ms/gfwlist +server=/applestore.bg/127.0.0.1#5335 +ipset=/applestore.bg/gfwlist +server=/awsthinkbox.com/127.0.0.1#5335 +ipset=/awsthinkbox.com/gfwlist +server=/asahishimbun.sc.omtrdc.net/127.0.0.1#5335 +ipset=/asahishimbun.sc.omtrdc.net/gfwlist +server=/thisvid.com/127.0.0.1#5335 +ipset=/thisvid.com/gfwlist +server=/facebooksz.com/127.0.0.1#5335 +ipset=/facebooksz.com/gfwlist +server=/paypallabs.com/127.0.0.1#5335 +ipset=/paypallabs.com/gfwlist +server=/eachpay.net/127.0.0.1#5335 +ipset=/eachpay.net/gfwlist +server=/cheapbeatsbydresale.com/127.0.0.1#5335 +ipset=/cheapbeatsbydresale.com/gfwlist +server=/paypal-login.org/127.0.0.1#5335 +ipset=/paypal-login.org/gfwlist +server=/momtarts3d.com/127.0.0.1#5335 +ipset=/momtarts3d.com/gfwlist +server=/jable.org/127.0.0.1#5335 +ipset=/jable.org/gfwlist +server=/espressif.com/127.0.0.1#5335 +ipset=/espressif.com/gfwlist +server=/analcamshow.com/127.0.0.1#5335 +ipset=/analcamshow.com/gfwlist +server=/adobe-video-partner-finder.com/127.0.0.1#5335 +ipset=/adobe-video-partner-finder.com/gfwlist +server=/dev-theguardian.com/127.0.0.1#5335 +ipset=/dev-theguardian.com/gfwlist +server=/dropbox-dns.com/127.0.0.1#5335 +ipset=/dropbox-dns.com/gfwlist +server=/videosdesexo.com.br/127.0.0.1#5335 +ipset=/videosdesexo.com.br/gfwlist +server=/85tube.com/127.0.0.1#5335 +ipset=/85tube.com/gfwlist +server=/ebonyinlove.com/127.0.0.1#5335 +ipset=/ebonyinlove.com/gfwlist +server=/fox.tv/127.0.0.1#5335 +ipset=/fox.tv/gfwlist +server=/tristatebmw.com/127.0.0.1#5335 +ipset=/tristatebmw.com/gfwlist +server=/escobarvip.it/127.0.0.1#5335 +ipset=/escobarvip.it/gfwlist +server=/apigee.com/127.0.0.1#5335 +ipset=/apigee.com/gfwlist +server=/bang-movies.com/127.0.0.1#5335 +ipset=/bang-movies.com/gfwlist +server=/marvelparty.net/127.0.0.1#5335 +ipset=/marvelparty.net/gfwlist +server=/cloupia.com/127.0.0.1#5335 +ipset=/cloupia.com/gfwlist +server=/huffingtonpost.com.mx/127.0.0.1#5335 +ipset=/huffingtonpost.com.mx/gfwlist +server=/bmw-connecteddrive.co.za/127.0.0.1#5335 +ipset=/bmw-connecteddrive.co.za/gfwlist +server=/shopee.fr/127.0.0.1#5335 +ipset=/shopee.fr/gfwlist +server=/cython.org/127.0.0.1#5335 +ipset=/cython.org/gfwlist +server=/bintray.com/127.0.0.1#5335 +ipset=/bintray.com/gfwlist +server=/imagecurl.com/127.0.0.1#5335 +ipset=/imagecurl.com/gfwlist +server=/xxxgames.games/127.0.0.1#5335 +ipset=/xxxgames.games/gfwlist +server=/pornhubselect.com/127.0.0.1#5335 +ipset=/pornhubselect.com/gfwlist +server=/zoosexnet.com/127.0.0.1#5335 +ipset=/zoosexnet.com/gfwlist +server=/igetnaughty.com/127.0.0.1#5335 +ipset=/igetnaughty.com/gfwlist +server=/aporntv.com/127.0.0.1#5335 +ipset=/aporntv.com/gfwlist +server=/clojure.org/127.0.0.1#5335 +ipset=/clojure.org/gfwlist +server=/riotgames.com/127.0.0.1#5335 +ipset=/riotgames.com/gfwlist +server=/python.org/127.0.0.1#5335 +ipset=/python.org/gfwlist +server=/ikea.co.jp/127.0.0.1#5335 +ipset=/ikea.co.jp/gfwlist +server=/blogspot.co.id/127.0.0.1#5335 +ipset=/blogspot.co.id/gfwlist +server=/1to1computing.com.au/127.0.0.1#5335 +ipset=/1to1computing.com.au/gfwlist +server=/jerkdolls.com/127.0.0.1#5335 +ipset=/jerkdolls.com/gfwlist +server=/milfmovs.com/127.0.0.1#5335 +ipset=/milfmovs.com/gfwlist +server=/vanishcentroamerica.com/127.0.0.1#5335 +ipset=/vanishcentroamerica.com/gfwlist +server=/dansmovies.com/127.0.0.1#5335 +ipset=/dansmovies.com/gfwlist +server=/epochhk.com/127.0.0.1#5335 +ipset=/epochhk.com/gfwlist +server=/gotraffic.net/127.0.0.1#5335 +ipset=/gotraffic.net/gfwlist +server=/1classtube.com/127.0.0.1#5335 +ipset=/1classtube.com/gfwlist +server=/drebeats-monsterusa.com/127.0.0.1#5335 +ipset=/drebeats-monsterusa.com/gfwlist +server=/epochtimes.com.ua/127.0.0.1#5335 +ipset=/epochtimes.com.ua/gfwlist +server=/beatsbydrebeatsby.com/127.0.0.1#5335 +ipset=/beatsbydrebeatsby.com/gfwlist +server=/billmelater.net/127.0.0.1#5335 +ipset=/billmelater.net/gfwlist +server=/abeatsbydrdre.com/127.0.0.1#5335 +ipset=/abeatsbydrdre.com/gfwlist +server=/sex.com/127.0.0.1#5335 +ipset=/sex.com/gfwlist +server=/wzlthw.com/127.0.0.1#5335 +ipset=/wzlthw.com/gfwlist +server=/tsundora.com/127.0.0.1#5335 +ipset=/tsundora.com/gfwlist +server=/drebeatsstudio2013.com/127.0.0.1#5335 +ipset=/drebeatsstudio2013.com/gfwlist +server=/88kkn.com/127.0.0.1#5335 +ipset=/88kkn.com/gfwlist +server=/analqts.com/127.0.0.1#5335 +ipset=/analqts.com/gfwlist +server=/twinktube.sexy/127.0.0.1#5335 +ipset=/twinktube.sexy/gfwlist +server=/4club.com/127.0.0.1#5335 +ipset=/4club.com/gfwlist +server=/nikeit.com/127.0.0.1#5335 +ipset=/nikeit.com/gfwlist +server=/hdpornmax.net/127.0.0.1#5335 +ipset=/hdpornmax.net/gfwlist +server=/p-events-delivery.akamaized.net/127.0.0.1#5335 +ipset=/p-events-delivery.akamaized.net/gfwlist +server=/guangming.com.my/127.0.0.1#5335 +ipset=/guangming.com.my/gfwlist +server=/microsoftnews.cc/127.0.0.1#5335 +ipset=/microsoftnews.cc/gfwlist +server=/next.com/127.0.0.1#5335 +ipset=/next.com/gfwlist +server=/nicolepeters.com/127.0.0.1#5335 +ipset=/nicolepeters.com/gfwlist +server=/quicktime.eu/127.0.0.1#5335 +ipset=/quicktime.eu/gfwlist +server=/bigcocker.com/127.0.0.1#5335 +ipset=/bigcocker.com/gfwlist +server=/cherrypanpan.com/127.0.0.1#5335 +ipset=/cherrypanpan.com/gfwlist +server=/hdxnxx.xxx/127.0.0.1#5335 +ipset=/hdxnxx.xxx/gfwlist +server=/cheapbeatsla.com/127.0.0.1#5335 +ipset=/cheapbeatsla.com/gfwlist +server=/nbys1.tv/127.0.0.1#5335 +ipset=/nbys1.tv/gfwlist +server=/blaoshi.cc/127.0.0.1#5335 +ipset=/blaoshi.cc/gfwlist +server=/aboutamazon.jp/127.0.0.1#5335 +ipset=/aboutamazon.jp/gfwlist +server=/bb33.net/127.0.0.1#5335 +ipset=/bb33.net/gfwlist +server=/xnxx.net/127.0.0.1#5335 +ipset=/xnxx.net/gfwlist +server=/disney.no/127.0.0.1#5335 +ipset=/disney.no/gfwlist +server=/sci-hub.se/127.0.0.1#5335 +ipset=/sci-hub.se/gfwlist +server=/pornobuzz.net/127.0.0.1#5335 +ipset=/pornobuzz.net/gfwlist +server=/webcamjackers.com/127.0.0.1#5335 +ipset=/webcamjackers.com/gfwlist +server=/headphones-outlet-online.com/127.0.0.1#5335 +ipset=/headphones-outlet-online.com/gfwlist +server=/microsoft.is/127.0.0.1#5335 +ipset=/microsoft.is/gfwlist +server=/starfox.com/127.0.0.1#5335 +ipset=/starfox.com/gfwlist +server=/tabooporn.tv/127.0.0.1#5335 +ipset=/tabooporn.tv/gfwlist +server=/adobeoobe.com/127.0.0.1#5335 +ipset=/adobeoobe.com/gfwlist +server=/adobeku.com/127.0.0.1#5335 +ipset=/adobeku.com/gfwlist +server=/nakedamateurmilf.com/127.0.0.1#5335 +ipset=/nakedamateurmilf.com/gfwlist +server=/daindianporn.com/127.0.0.1#5335 +ipset=/daindianporn.com/gfwlist +server=/limedia.tw/127.0.0.1#5335 +ipset=/limedia.tw/gfwlist +server=/syhacked.com/127.0.0.1#5335 +ipset=/syhacked.com/gfwlist +server=/fedoraforum.org/127.0.0.1#5335 +ipset=/fedoraforum.org/gfwlist +server=/msftnet.org/127.0.0.1#5335 +ipset=/msftnet.org/gfwlist +server=/facebookenespanol.com/127.0.0.1#5335 +ipset=/facebookenespanol.com/gfwlist +server=/67maoab.com/127.0.0.1#5335 +ipset=/67maoab.com/gfwlist +server=/miniso-au.com/127.0.0.1#5335 +ipset=/miniso-au.com/gfwlist +server=/xxxwow.net/127.0.0.1#5335 +ipset=/xxxwow.net/gfwlist +server=/donkparty.com/127.0.0.1#5335 +ipset=/donkparty.com/gfwlist +server=/paypal-excelinvoicing.com/127.0.0.1#5335 +ipset=/paypal-excelinvoicing.com/gfwlist +server=/fuckmaturepussy.com/127.0.0.1#5335 +ipset=/fuckmaturepussy.com/gfwlist +server=/freesexgames.games/127.0.0.1#5335 +ipset=/freesexgames.games/gfwlist +server=/xn--cck4d8b3009a.com/127.0.0.1#5335 +ipset=/xn--cck4d8b3009a.com/gfwlist +server=/marketingcloud.com/127.0.0.1#5335 +ipset=/marketingcloud.com/gfwlist +server=/hdfreeporn.net/127.0.0.1#5335 +ipset=/hdfreeporn.net/gfwlist +server=/volvotruckcenter.dk/127.0.0.1#5335 +ipset=/volvotruckcenter.dk/gfwlist +server=/gcld-line.com/127.0.0.1#5335 +ipset=/gcld-line.com/gfwlist +server=/bluekai.com/127.0.0.1#5335 +ipset=/bluekai.com/gfwlist +server=/videostravestis.xxx/127.0.0.1#5335 +ipset=/videostravestis.xxx/gfwlist +server=/bayvoice.net/127.0.0.1#5335 +ipset=/bayvoice.net/gfwlist +server=/needforspeedtherun.com/127.0.0.1#5335 +ipset=/needforspeedtherun.com/gfwlist +server=/aljazeera.com/127.0.0.1#5335 +ipset=/aljazeera.com/gfwlist +server=/188channel.com/127.0.0.1#5335 +ipset=/188channel.com/gfwlist +server=/cpz.to/127.0.0.1#5335 +ipset=/cpz.to/gfwlist +server=/vod-sub-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vod-sub-uk-live.akamaized.net/gfwlist +server=/googleapps.com/127.0.0.1#5335 +ipset=/googleapps.com/gfwlist +server=/famousnudes.com/127.0.0.1#5335 +ipset=/famousnudes.com/gfwlist +server=/all3dsexpics.com/127.0.0.1#5335 +ipset=/all3dsexpics.com/gfwlist +server=/rectovaginalexam.com/127.0.0.1#5335 +ipset=/rectovaginalexam.com/gfwlist +server=/tiktokv.com/127.0.0.1#5335 +ipset=/tiktokv.com/gfwlist +server=/harpercollinsspeakersbureau.com/127.0.0.1#5335 +ipset=/harpercollinsspeakersbureau.com/gfwlist +server=/hentainanime.com/127.0.0.1#5335 +ipset=/hentainanime.com/gfwlist +server=/dlercloud.com/127.0.0.1#5335 +ipset=/dlercloud.com/gfwlist +server=/issquareup.com/127.0.0.1#5335 +ipset=/issquareup.com/gfwlist +server=/smartcommunitiescoalition.com/127.0.0.1#5335 +ipset=/smartcommunitiescoalition.com/gfwlist +server=/jjdong7.com/127.0.0.1#5335 +ipset=/jjdong7.com/gfwlist +server=/cheapmonsterbeatsusa.us/127.0.0.1#5335 +ipset=/cheapmonsterbeatsusa.us/gfwlist +server=/epochtimes.ru/127.0.0.1#5335 +ipset=/epochtimes.ru/gfwlist +server=/myfistingporn.com/127.0.0.1#5335 +ipset=/myfistingporn.com/gfwlist +server=/directtvreviews.com/127.0.0.1#5335 +ipset=/directtvreviews.com/gfwlist +server=/gelbooru.com/127.0.0.1#5335 +ipset=/gelbooru.com/gfwlist +server=/volvotrucks.ge/127.0.0.1#5335 +ipset=/volvotrucks.ge/gfwlist +server=/mortein.com.br/127.0.0.1#5335 +ipset=/mortein.com.br/gfwlist +server=/1watchmygf.com/127.0.0.1#5335 +ipset=/1watchmygf.com/gfwlist +server=/adwords.com/127.0.0.1#5335 +ipset=/adwords.com/gfwlist +server=/bmw-motorrad.cl/127.0.0.1#5335 +ipset=/bmw-motorrad.cl/gfwlist +server=/bentobox.tv/127.0.0.1#5335 +ipset=/bentobox.tv/gfwlist +server=/qckprn.com/127.0.0.1#5335 +ipset=/qckprn.com/gfwlist +server=/pornpander.com/127.0.0.1#5335 +ipset=/pornpander.com/gfwlist +server=/paypal-database.us/127.0.0.1#5335 +ipset=/paypal-database.us/gfwlist +server=/pornolab.net/127.0.0.1#5335 +ipset=/pornolab.net/gfwlist +server=/bnbstatic.com/127.0.0.1#5335 +ipset=/bnbstatic.com/gfwlist +server=/googlecert.net/127.0.0.1#5335 +ipset=/googlecert.net/gfwlist +server=/foxsportsflorida.com/127.0.0.1#5335 +ipset=/foxsportsflorida.com/gfwlist +server=/bloomberglp.com/127.0.0.1#5335 +ipset=/bloomberglp.com/gfwlist +server=/livexxx.me/127.0.0.1#5335 +ipset=/livexxx.me/gfwlist +server=/bmw-motorrad.fr/127.0.0.1#5335 +ipset=/bmw-motorrad.fr/gfwlist +server=/intel.it/127.0.0.1#5335 +ipset=/intel.it/gfwlist +server=/cuckoldingwifey.com/127.0.0.1#5335 +ipset=/cuckoldingwifey.com/gfwlist +server=/sohcradio.com/127.0.0.1#5335 +ipset=/sohcradio.com/gfwlist +server=/realclear.com/127.0.0.1#5335 +ipset=/realclear.com/gfwlist +server=/google.co.uz/127.0.0.1#5335 +ipset=/google.co.uz/gfwlist +server=/durexukraine.com/127.0.0.1#5335 +ipset=/durexukraine.com/gfwlist +server=/finishinfo.com.au/127.0.0.1#5335 +ipset=/finishinfo.com.au/gfwlist +server=/bmw-connecteddrive.com.au/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com.au/gfwlist +server=/stxmosquito.com/127.0.0.1#5335 +ipset=/stxmosquito.com/gfwlist +server=/bloombergtax1.com/127.0.0.1#5335 +ipset=/bloombergtax1.com/gfwlist +server=/bustysammieblack.com/127.0.0.1#5335 +ipset=/bustysammieblack.com/gfwlist +server=/whoreslag.com/127.0.0.1#5335 +ipset=/whoreslag.com/gfwlist +server=/www-paypal.us/127.0.0.1#5335 +ipset=/www-paypal.us/gfwlist +server=/openthread.io/127.0.0.1#5335 +ipset=/openthread.io/gfwlist +server=/blowjobqueens.net/127.0.0.1#5335 +ipset=/blowjobqueens.net/gfwlist +server=/foxweatherwatch.com/127.0.0.1#5335 +ipset=/foxweatherwatch.com/gfwlist +server=/ipadair.tw/127.0.0.1#5335 +ipset=/ipadair.tw/gfwlist +server=/walmart-content.com/127.0.0.1#5335 +ipset=/walmart-content.com/gfwlist +server=/sirenxxxstudios.com/127.0.0.1#5335 +ipset=/sirenxxxstudios.com/gfwlist +server=/attwifi.com/127.0.0.1#5335 +ipset=/attwifi.com/gfwlist +server=/paypal-communications.com/127.0.0.1#5335 +ipset=/paypal-communications.com/gfwlist +server=/manoramanews.com/127.0.0.1#5335 +ipset=/manoramanews.com/gfwlist +server=/realgfporn.com/127.0.0.1#5335 +ipset=/realgfporn.com/gfwlist +server=/nikesportswear.com/127.0.0.1#5335 +ipset=/nikesportswear.com/gfwlist +server=/porno365.website/127.0.0.1#5335 +ipset=/porno365.website/gfwlist +server=/yahoo.com.do/127.0.0.1#5335 +ipset=/yahoo.com.do/gfwlist +server=/anacams.com/127.0.0.1#5335 +ipset=/anacams.com/gfwlist +server=/bestbuyrewards.com/127.0.0.1#5335 +ipset=/bestbuyrewards.com/gfwlist +server=/facebooklivestaging.org/127.0.0.1#5335 +ipset=/facebooklivestaging.org/gfwlist +server=/backdoorlesbians.com/127.0.0.1#5335 +ipset=/backdoorlesbians.com/gfwlist +server=/hentaiblue.com/127.0.0.1#5335 +ipset=/hentaiblue.com/gfwlist +server=/managedpki.com/127.0.0.1#5335 +ipset=/managedpki.com/gfwlist +server=/beascoremodel.com/127.0.0.1#5335 +ipset=/beascoremodel.com/gfwlist +server=/alpherafinance.com.hk/127.0.0.1#5335 +ipset=/alpherafinance.com.hk/gfwlist +server=/mini-oman.com/127.0.0.1#5335 +ipset=/mini-oman.com/gfwlist +server=/porngogo.supertop-100.com/127.0.0.1#5335 +ipset=/porngogo.supertop-100.com/gfwlist +server=/nintendo.pt/127.0.0.1#5335 +ipset=/nintendo.pt/gfwlist +server=/dollarphotosclub.com/127.0.0.1#5335 +ipset=/dollarphotosclub.com/gfwlist +server=/hot-sex-tube.com/127.0.0.1#5335 +ipset=/hot-sex-tube.com/gfwlist +server=/szabadeuropa.hu/127.0.0.1#5335 +ipset=/szabadeuropa.hu/gfwlist +server=/verisign.asia/127.0.0.1#5335 +ipset=/verisign.asia/gfwlist +server=/footstockings.com/127.0.0.1#5335 +ipset=/footstockings.com/gfwlist +server=/finishinfo.ru/127.0.0.1#5335 +ipset=/finishinfo.ru/gfwlist +server=/beatsaudios.net/127.0.0.1#5335 +ipset=/beatsaudios.net/gfwlist +server=/definebabe.com/127.0.0.1#5335 +ipset=/definebabe.com/gfwlist +server=/sankeishop.jp/127.0.0.1#5335 +ipset=/sankeishop.jp/gfwlist +server=/scientificlinux.org/127.0.0.1#5335 +ipset=/scientificlinux.org/gfwlist +server=/lolshop.co.kr/127.0.0.1#5335 +ipset=/lolshop.co.kr/gfwlist +server=/researchandcare.org/127.0.0.1#5335 +ipset=/researchandcare.org/gfwlist +server=/lovebeatsdr.com/127.0.0.1#5335 +ipset=/lovebeatsdr.com/gfwlist +server=/bmw-motorcycles.vn/127.0.0.1#5335 +ipset=/bmw-motorcycles.vn/gfwlist +server=/phxbmw.com/127.0.0.1#5335 +ipset=/phxbmw.com/gfwlist +server=/18push.com/127.0.0.1#5335 +ipset=/18push.com/gfwlist +server=/hpeurope.com/127.0.0.1#5335 +ipset=/hpeurope.com/gfwlist +server=/hardcore-sex-filme.com/127.0.0.1#5335 +ipset=/hardcore-sex-filme.com/gfwlist +server=/bobvoyeur.com/127.0.0.1#5335 +ipset=/bobvoyeur.com/gfwlist +server=/istripper.com/127.0.0.1#5335 +ipset=/istripper.com/gfwlist +server=/canon.hr/127.0.0.1#5335 +ipset=/canon.hr/gfwlist +server=/youngpornonly.com/127.0.0.1#5335 +ipset=/youngpornonly.com/gfwlist +server=/apple.it/127.0.0.1#5335 +ipset=/apple.it/gfwlist +server=/volvobuses.ma/127.0.0.1#5335 +ipset=/volvobuses.ma/gfwlist +server=/nintendo.com.hk/127.0.0.1#5335 +ipset=/nintendo.com.hk/gfwlist +server=/shopifysvc.com/127.0.0.1#5335 +ipset=/shopifysvc.com/gfwlist +server=/blackboxgames.com/127.0.0.1#5335 +ipset=/blackboxgames.com/gfwlist +server=/1pondo.tv/127.0.0.1#5335 +ipset=/1pondo.tv/gfwlist +server=/xn--mts47c3w9b1qr.net/127.0.0.1#5335 +ipset=/xn--mts47c3w9b1qr.net/gfwlist +server=/jade-net-home.com/127.0.0.1#5335 +ipset=/jade-net-home.com/gfwlist +server=/scholar.google.pl/127.0.0.1#5335 +ipset=/scholar.google.pl/gfwlist +server=/deepfreeze.co.uk/127.0.0.1#5335 +ipset=/deepfreeze.co.uk/gfwlist +server=/yahoo.co.tz/127.0.0.1#5335 +ipset=/yahoo.co.tz/gfwlist +server=/teatroporno.com/127.0.0.1#5335 +ipset=/teatroporno.com/gfwlist +server=/businesswebwise.com/127.0.0.1#5335 +ipset=/businesswebwise.com/gfwlist +server=/drdreprobeatssale.com/127.0.0.1#5335 +ipset=/drdreprobeatssale.com/gfwlist +server=/lokinet.org/127.0.0.1#5335 +ipset=/lokinet.org/gfwlist +server=/book18.org/127.0.0.1#5335 +ipset=/book18.org/gfwlist +server=/fapforfun.net/127.0.0.1#5335 +ipset=/fapforfun.net/gfwlist +server=/hot-cartoon.com/127.0.0.1#5335 +ipset=/hot-cartoon.com/gfwlist +server=/scival.com/127.0.0.1#5335 +ipset=/scival.com/gfwlist +server=/science.com/127.0.0.1#5335 +ipset=/science.com/gfwlist +server=/impala-media-production.s3.amazonaws.com/127.0.0.1#5335 +ipset=/impala-media-production.s3.amazonaws.com/gfwlist +server=/lol-europe.com/127.0.0.1#5335 +ipset=/lol-europe.com/gfwlist +server=/repe21.com/127.0.0.1#5335 +ipset=/repe21.com/gfwlist +server=/teacherfucksteens.com/127.0.0.1#5335 +ipset=/teacherfucksteens.com/gfwlist +server=/bmw.lc/127.0.0.1#5335 +ipset=/bmw.lc/gfwlist +server=/babesnetwork.com/127.0.0.1#5335 +ipset=/babesnetwork.com/gfwlist +server=/tube18.sex/127.0.0.1#5335 +ipset=/tube18.sex/gfwlist +server=/bmw-motorrad-now-or-never.com/127.0.0.1#5335 +ipset=/bmw-motorrad-now-or-never.com/gfwlist +server=/gab.com/127.0.0.1#5335 +ipset=/gab.com/gfwlist +server=/pornoorzel.com/127.0.0.1#5335 +ipset=/pornoorzel.com/gfwlist +server=/sego8.co/127.0.0.1#5335 +ipset=/sego8.co/gfwlist +server=/yaddal.tv/127.0.0.1#5335 +ipset=/yaddal.tv/gfwlist +server=/nikeplus.com/127.0.0.1#5335 +ipset=/nikeplus.com/gfwlist +server=/xn--m1abbbgjah.lol/127.0.0.1#5335 +ipset=/xn--m1abbbgjah.lol/gfwlist +server=/devopsassessment.net/127.0.0.1#5335 +ipset=/devopsassessment.net/gfwlist +server=/yahoo.hu/127.0.0.1#5335 +ipset=/yahoo.hu/gfwlist +server=/berlincompanions.com/127.0.0.1#5335 +ipset=/berlincompanions.com/gfwlist +server=/intel.vu/127.0.0.1#5335 +ipset=/intel.vu/gfwlist +server=/bmw-tahiti.com/127.0.0.1#5335 +ipset=/bmw-tahiti.com/gfwlist +server=/drdreheadphonekey.com/127.0.0.1#5335 +ipset=/drdreheadphonekey.com/gfwlist +server=/yahoo.com.kw/127.0.0.1#5335 +ipset=/yahoo.com.kw/gfwlist +server=/ebay.sg/127.0.0.1#5335 +ipset=/ebay.sg/gfwlist +server=/workstations.tv/127.0.0.1#5335 +ipset=/workstations.tv/gfwlist +server=/fcaebook.com/127.0.0.1#5335 +ipset=/fcaebook.com/gfwlist +server=/dicela.com/127.0.0.1#5335 +ipset=/dicela.com/gfwlist +server=/see.xxx/127.0.0.1#5335 +ipset=/see.xxx/gfwlist +server=/nytchina.com/127.0.0.1#5335 +ipset=/nytchina.com/gfwlist +server=/nikefr.com/127.0.0.1#5335 +ipset=/nikefr.com/gfwlist +server=/pdxbmw.com/127.0.0.1#5335 +ipset=/pdxbmw.com/gfwlist +server=/mmonsterheadphones.net/127.0.0.1#5335 +ipset=/mmonsterheadphones.net/gfwlist +server=/tiltbrush.com/127.0.0.1#5335 +ipset=/tiltbrush.com/gfwlist +server=/scholar.google.co.jp/127.0.0.1#5335 +ipset=/scholar.google.co.jp/gfwlist +server=/likuoo.video/127.0.0.1#5335 +ipset=/likuoo.video/gfwlist +server=/ftop.ru/127.0.0.1#5335 +ipset=/ftop.ru/gfwlist +server=/powerbeats2wireless.com/127.0.0.1#5335 +ipset=/powerbeats2wireless.com/gfwlist +server=/infolinker.com.tw/127.0.0.1#5335 +ipset=/infolinker.com.tw/gfwlist +server=/minimarkham.com/127.0.0.1#5335 +ipset=/minimarkham.com/gfwlist +server=/gittigidiyorsikayet.com/127.0.0.1#5335 +ipset=/gittigidiyorsikayet.com/gfwlist +server=/apple.sa/127.0.0.1#5335 +ipset=/apple.sa/gfwlist +server=/heartbreakers.gallery/127.0.0.1#5335 +ipset=/heartbreakers.gallery/gfwlist +server=/xxx.com/127.0.0.1#5335 +ipset=/xxx.com/gfwlist +server=/inkedravens.com/127.0.0.1#5335 +ipset=/inkedravens.com/gfwlist +server=/porndude2.com/127.0.0.1#5335 +ipset=/porndude2.com/gfwlist +server=/dirctv.com/127.0.0.1#5335 +ipset=/dirctv.com/gfwlist +server=/cams.com/127.0.0.1#5335 +ipset=/cams.com/gfwlist +server=/ecgapp.net/127.0.0.1#5335 +ipset=/ecgapp.net/gfwlist +server=/tastyblacks.com/127.0.0.1#5335 +ipset=/tastyblacks.com/gfwlist +server=/laowang.vip/127.0.0.1#5335 +ipset=/laowang.vip/gfwlist +server=/apple.kr/127.0.0.1#5335 +ipset=/apple.kr/gfwlist +server=/extensionworkshop.com/127.0.0.1#5335 +ipset=/extensionworkshop.com/gfwlist +server=/teraperk.com/127.0.0.1#5335 +ipset=/teraperk.com/gfwlist +server=/aljazeera.net/127.0.0.1#5335 +ipset=/aljazeera.net/gfwlist +server=/allhen.online/127.0.0.1#5335 +ipset=/allhen.online/gfwlist +server=/airwick.at/127.0.0.1#5335 +ipset=/airwick.at/gfwlist +server=/csgfnmdb.com/127.0.0.1#5335 +ipset=/csgfnmdb.com/gfwlist +server=/firewire.eu/127.0.0.1#5335 +ipset=/firewire.eu/gfwlist +server=/mobileme.dk/127.0.0.1#5335 +ipset=/mobileme.dk/gfwlist +server=/bmw-qatar.com/127.0.0.1#5335 +ipset=/bmw-qatar.com/gfwlist +server=/trust-provider.com/127.0.0.1#5335 +ipset=/trust-provider.com/gfwlist +server=/jav.dog/127.0.0.1#5335 +ipset=/jav.dog/gfwlist +server=/publicpornvideo.com/127.0.0.1#5335 +ipset=/publicpornvideo.com/gfwlist +server=/eablackbox.com/127.0.0.1#5335 +ipset=/eablackbox.com/gfwlist +server=/mypornfox.com/127.0.0.1#5335 +ipset=/mypornfox.com/gfwlist +server=/desiraesworld.com/127.0.0.1#5335 +ipset=/desiraesworld.com/gfwlist +server=/appule.com/127.0.0.1#5335 +ipset=/appule.com/gfwlist +server=/esmatube.com/127.0.0.1#5335 +ipset=/esmatube.com/gfwlist +server=/bmwgroup-plants.com/127.0.0.1#5335 +ipset=/bmwgroup-plants.com/gfwlist +server=/ntdtv.org/127.0.0.1#5335 +ipset=/ntdtv.org/gfwlist +server=/wwwmfacebook.com/127.0.0.1#5335 +ipset=/wwwmfacebook.com/gfwlist +server=/edu-research.org/127.0.0.1#5335 +ipset=/edu-research.org/gfwlist +server=/watchjavonline.com/127.0.0.1#5335 +ipset=/watchjavonline.com/gfwlist +server=/ptapjmp.com/127.0.0.1#5335 +ipset=/ptapjmp.com/gfwlist +server=/stream-mydirtyhobby.biz/127.0.0.1#5335 +ipset=/stream-mydirtyhobby.biz/gfwlist +server=/love7.xyz/127.0.0.1#5335 +ipset=/love7.xyz/gfwlist +server=/bdsmlibrary.com/127.0.0.1#5335 +ipset=/bdsmlibrary.com/gfwlist +server=/dart.dev/127.0.0.1#5335 +ipset=/dart.dev/gfwlist +server=/nakedasiansex.com/127.0.0.1#5335 +ipset=/nakedasiansex.com/gfwlist +server=/branchportal.com/127.0.0.1#5335 +ipset=/branchportal.com/gfwlist +server=/pornobrasil.org/127.0.0.1#5335 +ipset=/pornobrasil.org/gfwlist +server=/xvideosbrasil.com/127.0.0.1#5335 +ipset=/xvideosbrasil.com/gfwlist +server=/sexoquente.blog/127.0.0.1#5335 +ipset=/sexoquente.blog/gfwlist +server=/fb.watch/127.0.0.1#5335 +ipset=/fb.watch/gfwlist +server=/mono-project.com/127.0.0.1#5335 +ipset=/mono-project.com/gfwlist +server=/facebooa.com/127.0.0.1#5335 +ipset=/facebooa.com/gfwlist +server=/pinterest.com.au/127.0.0.1#5335 +ipset=/pinterest.com.au/gfwlist +server=/hornybutt.com/127.0.0.1#5335 +ipset=/hornybutt.com/gfwlist +server=/rokutime.com/127.0.0.1#5335 +ipset=/rokutime.com/gfwlist +server=/binads.com/127.0.0.1#5335 +ipset=/binads.com/gfwlist +server=/applewatch.wang/127.0.0.1#5335 +ipset=/applewatch.wang/gfwlist +server=/rtings.com/127.0.0.1#5335 +ipset=/rtings.com/gfwlist +server=/compass.is/127.0.0.1#5335 +ipset=/compass.is/gfwlist +server=/xn--tkry91n.com/127.0.0.1#5335 +ipset=/xn--tkry91n.com/gfwlist +server=/sextvx.com/127.0.0.1#5335 +ipset=/sextvx.com/gfwlist +server=/renzhe.cloud/127.0.0.1#5335 +ipset=/renzhe.cloud/gfwlist +server=/faceid99.net/127.0.0.1#5335 +ipset=/faceid99.net/gfwlist +server=/amz123.com/127.0.0.1#5335 +ipset=/amz123.com/gfwlist +server=/icuminside.com/127.0.0.1#5335 +ipset=/icuminside.com/gfwlist +server=/hypodermic-injection.com/127.0.0.1#5335 +ipset=/hypodermic-injection.com/gfwlist +server=/beatsbydrdresale.net/127.0.0.1#5335 +ipset=/beatsbydrdresale.net/gfwlist +server=/homemadepornclip.com/127.0.0.1#5335 +ipset=/homemadepornclip.com/gfwlist +server=/camwhores.video/127.0.0.1#5335 +ipset=/camwhores.video/gfwlist +server=/mmaaxx.com/127.0.0.1#5335 +ipset=/mmaaxx.com/gfwlist +server=/xxxporn.su/127.0.0.1#5335 +ipset=/xxxporn.su/gfwlist +server=/2013cheapestbeats.com/127.0.0.1#5335 +ipset=/2013cheapestbeats.com/gfwlist +server=/twitter.jp/127.0.0.1#5335 +ipset=/twitter.jp/gfwlist +server=/nike-uk.com/127.0.0.1#5335 +ipset=/nike-uk.com/gfwlist +server=/google.cat/127.0.0.1#5335 +ipset=/google.cat/gfwlist +server=/dazn-api.com/127.0.0.1#5335 +ipset=/dazn-api.com/gfwlist +server=/statics-marketingsites-eas-ms-com.akamaized.net/127.0.0.1#5335 +ipset=/statics-marketingsites-eas-ms-com.akamaized.net/gfwlist +server=/celebritystorysite.com/127.0.0.1#5335 +ipset=/celebritystorysite.com/gfwlist +server=/fuck55.net/127.0.0.1#5335 +ipset=/fuck55.net/gfwlist +server=/icevirtuallibrary.com/127.0.0.1#5335 +ipset=/icevirtuallibrary.com/gfwlist +server=/mastercard.lu/127.0.0.1#5335 +ipset=/mastercard.lu/gfwlist +server=/fbrpms.com/127.0.0.1#5335 +ipset=/fbrpms.com/gfwlist +server=/linkedin.at/127.0.0.1#5335 +ipset=/linkedin.at/gfwlist +server=/gettyimages.hk/127.0.0.1#5335 +ipset=/gettyimages.hk/gfwlist +server=/fontbook.com/127.0.0.1#5335 +ipset=/fontbook.com/gfwlist +server=/money-link.com.tw/127.0.0.1#5335 +ipset=/money-link.com.tw/gfwlist +server=/naked.com/127.0.0.1#5335 +ipset=/naked.com/gfwlist +server=/fox.com/127.0.0.1#5335 +ipset=/fox.com/gfwlist +server=/bmw.mq/127.0.0.1#5335 +ipset=/bmw.mq/gfwlist +server=/best-sex-games.com/127.0.0.1#5335 +ipset=/best-sex-games.com/gfwlist +server=/blackandstacked.com/127.0.0.1#5335 +ipset=/blackandstacked.com/gfwlist +server=/ebaymotors.org/127.0.0.1#5335 +ipset=/ebaymotors.org/gfwlist +server=/dirtydoglinks.com/127.0.0.1#5335 +ipset=/dirtydoglinks.com/gfwlist +server=/shooshtime.com/127.0.0.1#5335 +ipset=/shooshtime.com/gfwlist +server=/n3ro.wtf/127.0.0.1#5335 +ipset=/n3ro.wtf/gfwlist +server=/joyclub.de/127.0.0.1#5335 +ipset=/joyclub.de/gfwlist +server=/drebeatspill.com/127.0.0.1#5335 +ipset=/drebeatspill.com/gfwlist +server=/bmw.mn/127.0.0.1#5335 +ipset=/bmw.mn/gfwlist +server=/ebayshop.com/127.0.0.1#5335 +ipset=/ebayshop.com/gfwlist +server=/yandex.lt/127.0.0.1#5335 +ipset=/yandex.lt/gfwlist +server=/estudio360.com.co/127.0.0.1#5335 +ipset=/estudio360.com.co/gfwlist +server=/stxmosquitoproject.org/127.0.0.1#5335 +ipset=/stxmosquitoproject.org/gfwlist +server=/hentaiheroes.com/127.0.0.1#5335 +ipset=/hentaiheroes.com/gfwlist +server=/clickserver.googleads.com/127.0.0.1#5335 +ipset=/clickserver.googleads.com/gfwlist +server=/ipod.no/127.0.0.1#5335 +ipset=/ipod.no/gfwlist +server=/tubeenema.com/127.0.0.1#5335 +ipset=/tubeenema.com/gfwlist +server=/singtaobooks.com/127.0.0.1#5335 +ipset=/singtaobooks.com/gfwlist +server=/marketexecutive.net/127.0.0.1#5335 +ipset=/marketexecutive.net/gfwlist +server=/veet.ro/127.0.0.1#5335 +ipset=/veet.ro/gfwlist +server=/javgg.net/127.0.0.1#5335 +ipset=/javgg.net/gfwlist +server=/starwars.com/127.0.0.1#5335 +ipset=/starwars.com/gfwlist +server=/camwhores.tv/127.0.0.1#5335 +ipset=/camwhores.tv/gfwlist +server=/embs.org/127.0.0.1#5335 +ipset=/embs.org/gfwlist +server=/openmidas.com/127.0.0.1#5335 +ipset=/openmidas.com/gfwlist +server=/disney-studio.com/127.0.0.1#5335 +ipset=/disney-studio.com/gfwlist +server=/fakings.com/127.0.0.1#5335 +ipset=/fakings.com/gfwlist +server=/bmw.com.uy/127.0.0.1#5335 +ipset=/bmw.com.uy/gfwlist +server=/freexxxporn.org/127.0.0.1#5335 +ipset=/freexxxporn.org/gfwlist +server=/xxxhubvideos.com/127.0.0.1#5335 +ipset=/xxxhubvideos.com/gfwlist +server=/dartsearch.net/127.0.0.1#5335 +ipset=/dartsearch.net/gfwlist +server=/wheelpop.com/127.0.0.1#5335 +ipset=/wheelpop.com/gfwlist +server=/softbankci.com/127.0.0.1#5335 +ipset=/softbankci.com/gfwlist +server=/wikimediacloud.org/127.0.0.1#5335 +ipset=/wikimediacloud.org/gfwlist +server=/beatssbydredanmark.com/127.0.0.1#5335 +ipset=/beatssbydredanmark.com/gfwlist +server=/diddykongracing.com/127.0.0.1#5335 +ipset=/diddykongracing.com/gfwlist +server=/bugzilla.org/127.0.0.1#5335 +ipset=/bugzilla.org/gfwlist +server=/bgov.com/127.0.0.1#5335 +ipset=/bgov.com/gfwlist +server=/hpayshop.com/127.0.0.1#5335 +ipset=/hpayshop.com/gfwlist +server=/termux.org/127.0.0.1#5335 +ipset=/termux.org/gfwlist +server=/poshtestgallery.com/127.0.0.1#5335 +ipset=/poshtestgallery.com/gfwlist +server=/airport-gov-cn.com/127.0.0.1#5335 +ipset=/airport-gov-cn.com/gfwlist +server=/mspairlift.com/127.0.0.1#5335 +ipset=/mspairlift.com/gfwlist +server=/riotgames.tv/127.0.0.1#5335 +ipset=/riotgames.tv/gfwlist +server=/ankarazirvesi2018.com/127.0.0.1#5335 +ipset=/ankarazirvesi2018.com/gfwlist +server=/bmw-motorrad-authorities.com/127.0.0.1#5335 +ipset=/bmw-motorrad-authorities.com/gfwlist +server=/sony.kz/127.0.0.1#5335 +ipset=/sony.kz/gfwlist +server=/hdrplusdata.org/127.0.0.1#5335 +ipset=/hdrplusdata.org/gfwlist +server=/volvo.se/127.0.0.1#5335 +ipset=/volvo.se/gfwlist +server=/ebayhabit.com/127.0.0.1#5335 +ipset=/ebayhabit.com/gfwlist +server=/torcidadeouro.com/127.0.0.1#5335 +ipset=/torcidadeouro.com/gfwlist +server=/facebookhome.info/127.0.0.1#5335 +ipset=/facebookhome.info/gfwlist +server=/xbox.org/127.0.0.1#5335 +ipset=/xbox.org/gfwlist +server=/pinterest.engineering/127.0.0.1#5335 +ipset=/pinterest.engineering/gfwlist +server=/wegamedeveloper.com/127.0.0.1#5335 +ipset=/wegamedeveloper.com/gfwlist +server=/okx.com/127.0.0.1#5335 +ipset=/okx.com/gfwlist +server=/wzmyg.com/127.0.0.1#5335 +ipset=/wzmyg.com/gfwlist +server=/monsterbeats-solo.net/127.0.0.1#5335 +ipset=/monsterbeats-solo.net/gfwlist +server=/eaaccess.com/127.0.0.1#5335 +ipset=/eaaccess.com/gfwlist +server=/abclider.com/127.0.0.1#5335 +ipset=/abclider.com/gfwlist +server=/comodoca2.com/127.0.0.1#5335 +ipset=/comodoca2.com/gfwlist +server=/sakuralive.com/127.0.0.1#5335 +ipset=/sakuralive.com/gfwlist +server=/visa.se/127.0.0.1#5335 +ipset=/visa.se/gfwlist +server=/zootube1.com/127.0.0.1#5335 +ipset=/zootube1.com/gfwlist +server=/hp-webplatform.com/127.0.0.1#5335 +ipset=/hp-webplatform.com/gfwlist +server=/rbspeakup.com/127.0.0.1#5335 +ipset=/rbspeakup.com/gfwlist +server=/fetishpornfilms.com/127.0.0.1#5335 +ipset=/fetishpornfilms.com/gfwlist +server=/beatfactoryoutlets.com/127.0.0.1#5335 +ipset=/beatfactoryoutlets.com/gfwlist +server=/battlefield.com/127.0.0.1#5335 +ipset=/battlefield.com/gfwlist +server=/moveaws.com/127.0.0.1#5335 +ipset=/moveaws.com/gfwlist +server=/openwrt.org/127.0.0.1#5335 +ipset=/openwrt.org/gfwlist +server=/supermariogalaxy.com/127.0.0.1#5335 +ipset=/supermariogalaxy.com/gfwlist +server=/tuta.io/127.0.0.1#5335 +ipset=/tuta.io/gfwlist +server=/paaypal.com/127.0.0.1#5335 +ipset=/paaypal.com/gfwlist +server=/naiadsystems.com/127.0.0.1#5335 +ipset=/naiadsystems.com/gfwlist +server=/hpusertraining.com/127.0.0.1#5335 +ipset=/hpusertraining.com/gfwlist +server=/yahoo.cl/127.0.0.1#5335 +ipset=/yahoo.cl/gfwlist +server=/huluusa.com/127.0.0.1#5335 +ipset=/huluusa.com/gfwlist +server=/ebayimg.com/127.0.0.1#5335 +ipset=/ebayimg.com/gfwlist +server=/visa.com.tr/127.0.0.1#5335 +ipset=/visa.com.tr/gfwlist +server=/ok.ru/127.0.0.1#5335 +ipset=/ok.ru/gfwlist +server=/bmw-motorrad.co.za/127.0.0.1#5335 +ipset=/bmw-motorrad.co.za/gfwlist +server=/javextreme.net/127.0.0.1#5335 +ipset=/javextreme.net/gfwlist +server=/nowe.com/127.0.0.1#5335 +ipset=/nowe.com/gfwlist +server=/yinmh.com/127.0.0.1#5335 +ipset=/yinmh.com/gfwlist +server=/iporntoo.com/127.0.0.1#5335 +ipset=/iporntoo.com/gfwlist +server=/appl4e.com/127.0.0.1#5335 +ipset=/appl4e.com/gfwlist +server=/thisav.org/127.0.0.1#5335 +ipset=/thisav.org/gfwlist +server=/videosdesexo.br.com/127.0.0.1#5335 +ipset=/videosdesexo.br.com/gfwlist +server=/nbcuni.com/127.0.0.1#5335 +ipset=/nbcuni.com/gfwlist +server=/ubisoft.com/127.0.0.1#5335 +ipset=/ubisoft.com/gfwlist +server=/nudeteenboys.net/127.0.0.1#5335 +ipset=/nudeteenboys.net/gfwlist +server=/voasomali.com/127.0.0.1#5335 +ipset=/voasomali.com/gfwlist +server=/medow.ru/127.0.0.1#5335 +ipset=/medow.ru/gfwlist +server=/beatsbydreonlie2013-nl.com/127.0.0.1#5335 +ipset=/beatsbydreonlie2013-nl.com/gfwlist +server=/xboxab.com/127.0.0.1#5335 +ipset=/xboxab.com/gfwlist +server=/povr.com/127.0.0.1#5335 +ipset=/povr.com/gfwlist +server=/appletaiwan.com/127.0.0.1#5335 +ipset=/appletaiwan.com/gfwlist +server=/youtube.mx/127.0.0.1#5335 +ipset=/youtube.mx/gfwlist +server=/wirelessgroup.co.uk/127.0.0.1#5335 +ipset=/wirelessgroup.co.uk/gfwlist +server=/ya.ru/127.0.0.1#5335 +ipset=/ya.ru/gfwlist +server=/cheapheadsetshop.com/127.0.0.1#5335 +ipset=/cheapheadsetshop.com/gfwlist +server=/ltn.com.tw/127.0.0.1#5335 +ipset=/ltn.com.tw/gfwlist +server=/calgonit.com/127.0.0.1#5335 +ipset=/calgonit.com/gfwlist +server=/sonypcl.jp/127.0.0.1#5335 +ipset=/sonypcl.jp/gfwlist +server=/paypalhere.tv/127.0.0.1#5335 +ipset=/paypalhere.tv/gfwlist +server=/sexmadeathome.com/127.0.0.1#5335 +ipset=/sexmadeathome.com/gfwlist +server=/bmwconnecteddrive.com/127.0.0.1#5335 +ipset=/bmwconnecteddrive.com/gfwlist +server=/sexy-beauties.com/127.0.0.1#5335 +ipset=/sexy-beauties.com/gfwlist +server=/69games.xxx/127.0.0.1#5335 +ipset=/69games.xxx/gfwlist +server=/canon.cz/127.0.0.1#5335 +ipset=/canon.cz/gfwlist +server=/dajiyuan.eu/127.0.0.1#5335 +ipset=/dajiyuan.eu/gfwlist +server=/vod-thumb-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vod-thumb-uk-live.akamaized.net/gfwlist +server=/lgecareers.com/127.0.0.1#5335 +ipset=/lgecareers.com/gfwlist +server=/voacantonese.com/127.0.0.1#5335 +ipset=/voacantonese.com/gfwlist +server=/boobpedia.com/127.0.0.1#5335 +ipset=/boobpedia.com/gfwlist +server=/10musume.com/127.0.0.1#5335 +ipset=/10musume.com/gfwlist +server=/thumbzilla.com/127.0.0.1#5335 +ipset=/thumbzilla.com/gfwlist +server=/starbucks.com.mx/127.0.0.1#5335 +ipset=/starbucks.com.mx/gfwlist +server=/smartoneholdings.com/127.0.0.1#5335 +ipset=/smartoneholdings.com/gfwlist +server=/ikea.co.uk/127.0.0.1#5335 +ipset=/ikea.co.uk/gfwlist +server=/drebeats-studio.com/127.0.0.1#5335 +ipset=/drebeats-studio.com/gfwlist +server=/airwick.ca/127.0.0.1#5335 +ipset=/airwick.ca/gfwlist +server=/whispersystems.org/127.0.0.1#5335 +ipset=/whispersystems.org/gfwlist +server=/paypal-prepaid.com/127.0.0.1#5335 +ipset=/paypal-prepaid.com/gfwlist +server=/hentaiporn.com/127.0.0.1#5335 +ipset=/hentaiporn.com/gfwlist +server=/wwwinstagram.com/127.0.0.1#5335 +ipset=/wwwinstagram.com/gfwlist +server=/cartoon-sex.tv/127.0.0.1#5335 +ipset=/cartoon-sex.tv/gfwlist +server=/cheapbeatsbydrdrepro.com/127.0.0.1#5335 +ipset=/cheapbeatsbydrdrepro.com/gfwlist +server=/shemalespoiledwhore.com/127.0.0.1#5335 +ipset=/shemalespoiledwhore.com/gfwlist +server=/nike-usa.com/127.0.0.1#5335 +ipset=/nike-usa.com/gfwlist +server=/hpinstantink.ca/127.0.0.1#5335 +ipset=/hpinstantink.ca/gfwlist +server=/hshsxkj.com/127.0.0.1#5335 +ipset=/hshsxkj.com/gfwlist +server=/tvbeventpower.com.hk/127.0.0.1#5335 +ipset=/tvbeventpower.com.hk/gfwlist +server=/wwwicloud.com/127.0.0.1#5335 +ipset=/wwwicloud.com/gfwlist +server=/wuyefuli.org/127.0.0.1#5335 +ipset=/wuyefuli.org/gfwlist +server=/newschristmasshopping.com/127.0.0.1#5335 +ipset=/newschristmasshopping.com/gfwlist +server=/bloombergtaxtech.com/127.0.0.1#5335 +ipset=/bloombergtaxtech.com/gfwlist +server=/mymmode.com/127.0.0.1#5335 +ipset=/mymmode.com/gfwlist +server=/girlfriendvids.net/127.0.0.1#5335 +ipset=/girlfriendvids.net/gfwlist +server=/fapnado.com/127.0.0.1#5335 +ipset=/fapnado.com/gfwlist +server=/mypearsonshop.com.mx/127.0.0.1#5335 +ipset=/mypearsonshop.com.mx/gfwlist +server=/sony.com.bo/127.0.0.1#5335 +ipset=/sony.com.bo/gfwlist +server=/intelvmwarecybersecurity.com/127.0.0.1#5335 +ipset=/intelvmwarecybersecurity.com/gfwlist +server=/928.plus/127.0.0.1#5335 +ipset=/928.plus/gfwlist +server=/xozilla.com/127.0.0.1#5335 +ipset=/xozilla.com/gfwlist +server=/bitquick.co/127.0.0.1#5335 +ipset=/bitquick.co/gfwlist +server=/bidong25.com/127.0.0.1#5335 +ipset=/bidong25.com/gfwlist +server=/macosforge.org/127.0.0.1#5335 +ipset=/macosforge.org/gfwlist +server=/topescortbabes.com/127.0.0.1#5335 +ipset=/topescortbabes.com/gfwlist +server=/xxxhdvideo.mobi/127.0.0.1#5335 +ipset=/xxxhdvideo.mobi/gfwlist +server=/wwwebay.com/127.0.0.1#5335 +ipset=/wwwebay.com/gfwlist +server=/themilfmovies.com/127.0.0.1#5335 +ipset=/themilfmovies.com/gfwlist +server=/gizmoxxx.com/127.0.0.1#5335 +ipset=/gizmoxxx.com/gfwlist +server=/buyaapl.net/127.0.0.1#5335 +ipset=/buyaapl.net/gfwlist +server=/n15zev3w.shop/127.0.0.1#5335 +ipset=/n15zev3w.shop/gfwlist +server=/sis001.com/127.0.0.1#5335 +ipset=/sis001.com/gfwlist +server=/adobedc.net/127.0.0.1#5335 +ipset=/adobedc.net/gfwlist +server=/minivilledequebec.com/127.0.0.1#5335 +ipset=/minivilledequebec.com/gfwlist +server=/teachmyass.com/127.0.0.1#5335 +ipset=/teachmyass.com/gfwlist +server=/favelaporno.com/127.0.0.1#5335 +ipset=/favelaporno.com/gfwlist +server=/yandex.uz/127.0.0.1#5335 +ipset=/yandex.uz/gfwlist +server=/47gyosei.jp/127.0.0.1#5335 +ipset=/47gyosei.jp/gfwlist +server=/ebaymag.com/127.0.0.1#5335 +ipset=/ebaymag.com/gfwlist +server=/icloudhome.com/127.0.0.1#5335 +ipset=/icloudhome.com/gfwlist +server=/rtm.tnt-ea.com/127.0.0.1#5335 +ipset=/rtm.tnt-ea.com/gfwlist +server=/girls2see.ch/127.0.0.1#5335 +ipset=/girls2see.ch/gfwlist +server=/herokucdn.com/127.0.0.1#5335 +ipset=/herokucdn.com/gfwlist +server=/hpspeaker.com/127.0.0.1#5335 +ipset=/hpspeaker.com/gfwlist +server=/jav.gallery/127.0.0.1#5335 +ipset=/jav.gallery/gfwlist +server=/globalsecurity.org/127.0.0.1#5335 +ipset=/globalsecurity.org/gfwlist +server=/tubesex.me/127.0.0.1#5335 +ipset=/tubesex.me/gfwlist +server=/daoc.net/127.0.0.1#5335 +ipset=/daoc.net/gfwlist +server=/theav.cc/127.0.0.1#5335 +ipset=/theav.cc/gfwlist +server=/disney-asia.com/127.0.0.1#5335 +ipset=/disney-asia.com/gfwlist +server=/esposasymaridos.com/127.0.0.1#5335 +ipset=/esposasymaridos.com/gfwlist +server=/bustykerrymarie.com/127.0.0.1#5335 +ipset=/bustykerrymarie.com/gfwlist +server=/apple.hn/127.0.0.1#5335 +ipset=/apple.hn/gfwlist +server=/binance.cloud/127.0.0.1#5335 +ipset=/binance.cloud/gfwlist +server=/hackerguardian.com/127.0.0.1#5335 +ipset=/hackerguardian.com/gfwlist +server=/picacomic.xyz/127.0.0.1#5335 +ipset=/picacomic.xyz/gfwlist +server=/ams02.space/127.0.0.1#5335 +ipset=/ams02.space/gfwlist +server=/xvideos.blog/127.0.0.1#5335 +ipset=/xvideos.blog/gfwlist +server=/young-amateur-movies.com/127.0.0.1#5335 +ipset=/young-amateur-movies.com/gfwlist +server=/cheerwholesale.us/127.0.0.1#5335 +ipset=/cheerwholesale.us/gfwlist +server=/eamythic.net/127.0.0.1#5335 +ipset=/eamythic.net/gfwlist +server=/beatsbydrediscount.com/127.0.0.1#5335 +ipset=/beatsbydrediscount.com/gfwlist +server=/amazingcuckold.com/127.0.0.1#5335 +ipset=/amazingcuckold.com/gfwlist +server=/webcamgirls.chat/127.0.0.1#5335 +ipset=/webcamgirls.chat/gfwlist +server=/virtualearth.net/127.0.0.1#5335 +ipset=/virtualearth.net/gfwlist +server=/home-sex-tapes.com/127.0.0.1#5335 +ipset=/home-sex-tapes.com/gfwlist +server=/nvidia.com/127.0.0.1#5335 +ipset=/nvidia.com/gfwlist +server=/modelmediaus.com/127.0.0.1#5335 +ipset=/modelmediaus.com/gfwlist +server=/facebook-texas-holdem.com/127.0.0.1#5335 +ipset=/facebook-texas-holdem.com/gfwlist +server=/unstyle.us/127.0.0.1#5335 +ipset=/unstyle.us/gfwlist +server=/ccav69.info/127.0.0.1#5335 +ipset=/ccav69.info/gfwlist +server=/paypal-gift.com/127.0.0.1#5335 +ipset=/paypal-gift.com/gfwlist +server=/muji.eu/127.0.0.1#5335 +ipset=/muji.eu/gfwlist +server=/xoom-experience.com/127.0.0.1#5335 +ipset=/xoom-experience.com/gfwlist +server=/binancezh.live/127.0.0.1#5335 +ipset=/binancezh.live/gfwlist +server=/transpornsites.com/127.0.0.1#5335 +ipset=/transpornsites.com/gfwlist +server=/playartifact.com/127.0.0.1#5335 +ipset=/playartifact.com/gfwlist +server=/nomulus.foo/127.0.0.1#5335 +ipset=/nomulus.foo/gfwlist +server=/lliusno.com/127.0.0.1#5335 +ipset=/lliusno.com/gfwlist +server=/softbank-telecom.com/127.0.0.1#5335 +ipset=/softbank-telecom.com/gfwlist +server=/bmw-connecteddrive.no/127.0.0.1#5335 +ipset=/bmw-connecteddrive.no/gfwlist +server=/geeksquad.ca/127.0.0.1#5335 +ipset=/geeksquad.ca/gfwlist +server=/nakedmodelsxxx.com/127.0.0.1#5335 +ipset=/nakedmodelsxxx.com/gfwlist +server=/homemoviestube.com/127.0.0.1#5335 +ipset=/homemoviestube.com/gfwlist +server=/jmcomic.me/127.0.0.1#5335 +ipset=/jmcomic.me/gfwlist +server=/yourgynexam.com/127.0.0.1#5335 +ipset=/yourgynexam.com/gfwlist +server=/dettol.ie/127.0.0.1#5335 +ipset=/dettol.ie/gfwlist +server=/onefifteen.net/127.0.0.1#5335 +ipset=/onefifteen.net/gfwlist +server=/hentaigamer.org/127.0.0.1#5335 +ipset=/hentaigamer.org/gfwlist +server=/static-cisco.com/127.0.0.1#5335 +ipset=/static-cisco.com/gfwlist +server=/wanokokorosoh.com/127.0.0.1#5335 +ipset=/wanokokorosoh.com/gfwlist +server=/myappleid.com/127.0.0.1#5335 +ipset=/myappleid.com/gfwlist +server=/onlyincestporn.com/127.0.0.1#5335 +ipset=/onlyincestporn.com/gfwlist +server=/ladsp.com/127.0.0.1#5335 +ipset=/ladsp.com/gfwlist +server=/bmw.co.ao/127.0.0.1#5335 +ipset=/bmw.co.ao/gfwlist +server=/betterexplained.com/127.0.0.1#5335 +ipset=/betterexplained.com/gfwlist +server=/appletv.fr/127.0.0.1#5335 +ipset=/appletv.fr/gfwlist +server=/storyful.com/127.0.0.1#5335 +ipset=/storyful.com/gfwlist +server=/bmw.es/127.0.0.1#5335 +ipset=/bmw.es/gfwlist +server=/sub147.com/127.0.0.1#5335 +ipset=/sub147.com/gfwlist +server=/berkeley.edu/127.0.0.1#5335 +ipset=/berkeley.edu/gfwlist +server=/miniso.ca/127.0.0.1#5335 +ipset=/miniso.ca/gfwlist +server=/instaadder.com/127.0.0.1#5335 +ipset=/instaadder.com/gfwlist +server=/novinhasdozapzap.com/127.0.0.1#5335 +ipset=/novinhasdozapzap.com/gfwlist +server=/beatspascher-bydre.com/127.0.0.1#5335 +ipset=/beatspascher-bydre.com/gfwlist +server=/tawny-peaks.com/127.0.0.1#5335 +ipset=/tawny-peaks.com/gfwlist +server=/codeforaliving.io/127.0.0.1#5335 +ipset=/codeforaliving.io/gfwlist +server=/bmwauslieferungszentrum.com/127.0.0.1#5335 +ipset=/bmwauslieferungszentrum.com/gfwlist +server=/nbcnews.com/127.0.0.1#5335 +ipset=/nbcnews.com/gfwlist +server=/www-cdn.icloud.com.akadns.net/127.0.0.1#5335 +ipset=/www-cdn.icloud.com.akadns.net/gfwlist +server=/bbc.net.uk/127.0.0.1#5335 +ipset=/bbc.net.uk/gfwlist +server=/volvotrucks.co.za/127.0.0.1#5335 +ipset=/volvotrucks.co.za/gfwlist +server=/appleaustralia.net.au/127.0.0.1#5335 +ipset=/appleaustralia.net.au/gfwlist +server=/jav-1080.com/127.0.0.1#5335 +ipset=/jav-1080.com/gfwlist +server=/my-magazine.me/127.0.0.1#5335 +ipset=/my-magazine.me/gfwlist +server=/xlgirls.com/127.0.0.1#5335 +ipset=/xlgirls.com/gfwlist +server=/cnshopin.com/127.0.0.1#5335 +ipset=/cnshopin.com/gfwlist +server=/wisecoin.com/127.0.0.1#5335 +ipset=/wisecoin.com/gfwlist +server=/paypal-corp.com/127.0.0.1#5335 +ipset=/paypal-corp.com/gfwlist +server=/9to5google.com/127.0.0.1#5335 +ipset=/9to5google.com/gfwlist +server=/jmcomic.mobi/127.0.0.1#5335 +ipset=/jmcomic.mobi/gfwlist +server=/supjav.com/127.0.0.1#5335 +ipset=/supjav.com/gfwlist +server=/fappcelebs.com/127.0.0.1#5335 +ipset=/fappcelebs.com/gfwlist +server=/porngamesverse.com/127.0.0.1#5335 +ipset=/porngamesverse.com/gfwlist +server=/fox46.com/127.0.0.1#5335 +ipset=/fox46.com/gfwlist +server=/hornychat.net/127.0.0.1#5335 +ipset=/hornychat.net/gfwlist +server=/reddit.com/127.0.0.1#5335 +ipset=/reddit.com/gfwlist +server=/nikkansports.com/127.0.0.1#5335 +ipset=/nikkansports.com/gfwlist +server=/asianpornmovies.com/127.0.0.1#5335 +ipset=/asianpornmovies.com/gfwlist +server=/ieeemce.org/127.0.0.1#5335 +ipset=/ieeemce.org/gfwlist +server=/258porn.com/127.0.0.1#5335 +ipset=/258porn.com/gfwlist +server=/anal.media/127.0.0.1#5335 +ipset=/anal.media/gfwlist +server=/jjgirls.com/127.0.0.1#5335 +ipset=/jjgirls.com/gfwlist +server=/gopivotal.net/127.0.0.1#5335 +ipset=/gopivotal.net/gfwlist +server=/pornvideotube.online/127.0.0.1#5335 +ipset=/pornvideotube.online/gfwlist +server=/openvpn.net/127.0.0.1#5335 +ipset=/openvpn.net/gfwlist +server=/rosemarydoll.com/127.0.0.1#5335 +ipset=/rosemarydoll.com/gfwlist +server=/hdhole.com/127.0.0.1#5335 +ipset=/hdhole.com/gfwlist +server=/youtube.com.hk/127.0.0.1#5335 +ipset=/youtube.com.hk/gfwlist +server=/cdnpure.com/127.0.0.1#5335 +ipset=/cdnpure.com/gfwlist +server=/xvideostravestis.xxx/127.0.0.1#5335 +ipset=/xvideostravestis.xxx/gfwlist +server=/vrporn.com/127.0.0.1#5335 +ipset=/vrporn.com/gfwlist +server=/ppaypal.com/127.0.0.1#5335 +ipset=/ppaypal.com/gfwlist +server=/paypal-secure.net/127.0.0.1#5335 +ipset=/paypal-secure.net/gfwlist +server=/cliphunter.com/127.0.0.1#5335 +ipset=/cliphunter.com/gfwlist +server=/facebookgames.com/127.0.0.1#5335 +ipset=/facebookgames.com/gfwlist +server=/pornhost.com/127.0.0.1#5335 +ipset=/pornhost.com/gfwlist +server=/apl-hamivideo.cdn.hinet.net/127.0.0.1#5335 +ipset=/apl-hamivideo.cdn.hinet.net/gfwlist +server=/vmwsalesrewards.com/127.0.0.1#5335 +ipset=/vmwsalesrewards.com/gfwlist +server=/xxx-files.org/127.0.0.1#5335 +ipset=/xxx-files.org/gfwlist +server=/allhorsesex.com/127.0.0.1#5335 +ipset=/allhorsesex.com/gfwlist +server=/xscale.com/127.0.0.1#5335 +ipset=/xscale.com/gfwlist +server=/babesandbitches.net/127.0.0.1#5335 +ipset=/babesandbitches.net/gfwlist +server=/settv.com.tw/127.0.0.1#5335 +ipset=/settv.com.tw/gfwlist +server=/nikefoamposites.com/127.0.0.1#5335 +ipset=/nikefoamposites.com/gfwlist +server=/pentium.com/127.0.0.1#5335 +ipset=/pentium.com/gfwlist +server=/azurestackvalidation.com/127.0.0.1#5335 +ipset=/azurestackvalidation.com/gfwlist +server=/bmwperformancecenter.com/127.0.0.1#5335 +ipset=/bmwperformancecenter.com/gfwlist +server=/ukipad.com/127.0.0.1#5335 +ipset=/ukipad.com/gfwlist +server=/yandex.st/127.0.0.1#5335 +ipset=/yandex.st/gfwlist +server=/ebaycoins.com/127.0.0.1#5335 +ipset=/ebaycoins.com/gfwlist +server=/gosq.com/127.0.0.1#5335 +ipset=/gosq.com/gfwlist +server=/sexiframe.com/127.0.0.1#5335 +ipset=/sexiframe.com/gfwlist +server=/citytourgirls.com/127.0.0.1#5335 +ipset=/citytourgirls.com/gfwlist +server=/pincong.rocks/127.0.0.1#5335 +ipset=/pincong.rocks/gfwlist +server=/hunk.ws/127.0.0.1#5335 +ipset=/hunk.ws/gfwlist +server=/blpprofessional.com/127.0.0.1#5335 +ipset=/blpprofessional.com/gfwlist +server=/tgirlcentral.com/127.0.0.1#5335 +ipset=/tgirlcentral.com/gfwlist +server=/uhub.com/127.0.0.1#5335 +ipset=/uhub.com/gfwlist +server=/datasheets360.com/127.0.0.1#5335 +ipset=/datasheets360.com/gfwlist +server=/airwick.us/127.0.0.1#5335 +ipset=/airwick.us/gfwlist +server=/hentaihaven.me/127.0.0.1#5335 +ipset=/hentaihaven.me/gfwlist +server=/shireyishunjian.com/127.0.0.1#5335 +ipset=/shireyishunjian.com/gfwlist +server=/adidas.cz/127.0.0.1#5335 +ipset=/adidas.cz/gfwlist +server=/rarbg.is/127.0.0.1#5335 +ipset=/rarbg.is/gfwlist +server=/businessinsider.com/127.0.0.1#5335 +ipset=/businessinsider.com/gfwlist +server=/visa.gr/127.0.0.1#5335 +ipset=/visa.gr/gfwlist +server=/storm.mg/127.0.0.1#5335 +ipset=/storm.mg/gfwlist +server=/cockyboys.com/127.0.0.1#5335 +ipset=/cockyboys.com/gfwlist +server=/netflix.com.edgesuite.net/127.0.0.1#5335 +ipset=/netflix.com.edgesuite.net/gfwlist +server=/monsterbeatsmall.com/127.0.0.1#5335 +ipset=/monsterbeatsmall.com/gfwlist +server=/18doujin.com/127.0.0.1#5335 +ipset=/18doujin.com/gfwlist +server=/itunes.us/127.0.0.1#5335 +ipset=/itunes.us/gfwlist +server=/thetimes.co.uk/127.0.0.1#5335 +ipset=/thetimes.co.uk/gfwlist +server=/tellapart.com/127.0.0.1#5335 +ipset=/tellapart.com/gfwlist +server=/smutindia.com/127.0.0.1#5335 +ipset=/smutindia.com/gfwlist +server=/netpornsex.net/127.0.0.1#5335 +ipset=/netpornsex.net/gfwlist +server=/qualcommlabs.com/127.0.0.1#5335 +ipset=/qualcommlabs.com/gfwlist +server=/applepaysupplies.net/127.0.0.1#5335 +ipset=/applepaysupplies.net/gfwlist +server=/faeboook.com/127.0.0.1#5335 +ipset=/faeboook.com/gfwlist +server=/ecimg.tw/127.0.0.1#5335 +ipset=/ecimg.tw/gfwlist +server=/duckduckgo.ke/127.0.0.1#5335 +ipset=/duckduckgo.ke/gfwlist +server=/gen.lib.rus.ec/127.0.0.1#5335 +ipset=/gen.lib.rus.ec/gfwlist +server=/nukemanga.com/127.0.0.1#5335 +ipset=/nukemanga.com/gfwlist +server=/guardianapps.co.uk/127.0.0.1#5335 +ipset=/guardianapps.co.uk/gfwlist +server=/durex.com.tr/127.0.0.1#5335 +ipset=/durex.com.tr/gfwlist +server=/earphonescheapest.com/127.0.0.1#5335 +ipset=/earphonescheapest.com/gfwlist +server=/c-ij.com/127.0.0.1#5335 +ipset=/c-ij.com/gfwlist +server=/desihoes.com/127.0.0.1#5335 +ipset=/desihoes.com/gfwlist +server=/exxxtra.net/127.0.0.1#5335 +ipset=/exxxtra.net/gfwlist +server=/reuters.com/127.0.0.1#5335 +ipset=/reuters.com/gfwlist +server=/payhulu.com/127.0.0.1#5335 +ipset=/payhulu.com/gfwlist +server=/veporn.com/127.0.0.1#5335 +ipset=/veporn.com/gfwlist +server=/homofans.blogspot.com/127.0.0.1#5335 +ipset=/homofans.blogspot.com/gfwlist +server=/amznl.com/127.0.0.1#5335 +ipset=/amznl.com/gfwlist +server=/thepornlistdude.com/127.0.0.1#5335 +ipset=/thepornlistdude.com/gfwlist +server=/incentivetravelgifts.com/127.0.0.1#5335 +ipset=/incentivetravelgifts.com/gfwlist +server=/volvotrucks.rs/127.0.0.1#5335 +ipset=/volvotrucks.rs/gfwlist +server=/reuters.tv/127.0.0.1#5335 +ipset=/reuters.tv/gfwlist +server=/intel.si/127.0.0.1#5335 +ipset=/intel.si/gfwlist +server=/vfsco.ie/127.0.0.1#5335 +ipset=/vfsco.ie/gfwlist +server=/ah-me.com/127.0.0.1#5335 +ipset=/ah-me.com/gfwlist +server=/sonybo.co.jp/127.0.0.1#5335 +ipset=/sonybo.co.jp/gfwlist +server=/sexwebvideo.com/127.0.0.1#5335 +ipset=/sexwebvideo.com/gfwlist +server=/businessinsider.fr/127.0.0.1#5335 +ipset=/businessinsider.fr/gfwlist +server=/digitalassetlinks.org/127.0.0.1#5335 +ipset=/digitalassetlinks.org/gfwlist +server=/javfor.me/127.0.0.1#5335 +ipset=/javfor.me/gfwlist +server=/monsterbeatstudio.com/127.0.0.1#5335 +ipset=/monsterbeatstudio.com/gfwlist +server=/booloo.com/127.0.0.1#5335 +ipset=/booloo.com/gfwlist +server=/php.net/127.0.0.1#5335 +ipset=/php.net/gfwlist +server=/snapcraft.io/127.0.0.1#5335 +ipset=/snapcraft.io/gfwlist +server=/beatsstudiohodetelefoner.com/127.0.0.1#5335 +ipset=/beatsstudiohodetelefoner.com/gfwlist +server=/redditmail.com/127.0.0.1#5335 +ipset=/redditmail.com/gfwlist +server=/ikea.om/127.0.0.1#5335 +ipset=/ikea.om/gfwlist +server=/canon.ee/127.0.0.1#5335 +ipset=/canon.ee/gfwlist +server=/marketolive.com/127.0.0.1#5335 +ipset=/marketolive.com/gfwlist +server=/4porn4.com/127.0.0.1#5335 +ipset=/4porn4.com/gfwlist +server=/reconinstruments.com/127.0.0.1#5335 +ipset=/reconinstruments.com/gfwlist +server=/scholar.google.com.ly/127.0.0.1#5335 +ipset=/scholar.google.com.ly/gfwlist +server=/asianporn.sexy/127.0.0.1#5335 +ipset=/asianporn.sexy/gfwlist +server=/emagic.de/127.0.0.1#5335 +ipset=/emagic.de/gfwlist +server=/qkjuyet.com/127.0.0.1#5335 +ipset=/qkjuyet.com/gfwlist +server=/xxxpornotuber.com/127.0.0.1#5335 +ipset=/xxxpornotuber.com/gfwlist +server=/ipple.com/127.0.0.1#5335 +ipset=/ipple.com/gfwlist +server=/jkbeats.com/127.0.0.1#5335 +ipset=/jkbeats.com/gfwlist +server=/topnudemalecelebs.com/127.0.0.1#5335 +ipset=/topnudemalecelebs.com/gfwlist +server=/universalpicturesinternational.com/127.0.0.1#5335 +ipset=/universalpicturesinternational.com/gfwlist +server=/vilavpn.com/127.0.0.1#5335 +ipset=/vilavpn.com/gfwlist +server=/skyoceanrescue.de/127.0.0.1#5335 +ipset=/skyoceanrescue.de/gfwlist +server=/namemybeats.com/127.0.0.1#5335 +ipset=/namemybeats.com/gfwlist +server=/facebooj.com/127.0.0.1#5335 +ipset=/facebooj.com/gfwlist +server=/shikorina.net/127.0.0.1#5335 +ipset=/shikorina.net/gfwlist +server=/moneywithfacebook.com/127.0.0.1#5335 +ipset=/moneywithfacebook.com/gfwlist +server=/facecbgook.com/127.0.0.1#5335 +ipset=/facecbgook.com/gfwlist +server=/sissy.game/127.0.0.1#5335 +ipset=/sissy.game/gfwlist +server=/wiipartyu.com/127.0.0.1#5335 +ipset=/wiipartyu.com/gfwlist +server=/chatwhores.org/127.0.0.1#5335 +ipset=/chatwhores.org/gfwlist +server=/awstrack.me/127.0.0.1#5335 +ipset=/awstrack.me/gfwlist +server=/anaconda.org/127.0.0.1#5335 +ipset=/anaconda.org/gfwlist +server=/bangbrosnetwork.com/127.0.0.1#5335 +ipset=/bangbrosnetwork.com/gfwlist +server=/discord.tools/127.0.0.1#5335 +ipset=/discord.tools/gfwlist +server=/hottestfilms.com/127.0.0.1#5335 +ipset=/hottestfilms.com/gfwlist +server=/chromeos.dev/127.0.0.1#5335 +ipset=/chromeos.dev/gfwlist +server=/xnxxx.cc/127.0.0.1#5335 +ipset=/xnxxx.cc/gfwlist +server=/signal.org/127.0.0.1#5335 +ipset=/signal.org/gfwlist +server=/intercom.io/127.0.0.1#5335 +ipset=/intercom.io/gfwlist +server=/starbucks.co.id/127.0.0.1#5335 +ipset=/starbucks.co.id/gfwlist +server=/imaypb.com/127.0.0.1#5335 +ipset=/imaypb.com/gfwlist +server=/hpdrivers.com/127.0.0.1#5335 +ipset=/hpdrivers.com/gfwlist +server=/taiwansex.tw/127.0.0.1#5335 +ipset=/taiwansex.tw/gfwlist +server=/hptv.fun/127.0.0.1#5335 +ipset=/hptv.fun/gfwlist +server=/typeisbeautiful.com/127.0.0.1#5335 +ipset=/typeisbeautiful.com/gfwlist +server=/svipshipin.store/127.0.0.1#5335 +ipset=/svipshipin.store/gfwlist +server=/vipergirls.to/127.0.0.1#5335 +ipset=/vipergirls.to/gfwlist +server=/archive.org/127.0.0.1#5335 +ipset=/archive.org/gfwlist +server=/qoo10.jp/127.0.0.1#5335 +ipset=/qoo10.jp/gfwlist +server=/zuckerberg.com/127.0.0.1#5335 +ipset=/zuckerberg.com/gfwlist +server=/cbsinteractive.com/127.0.0.1#5335 +ipset=/cbsinteractive.com/gfwlist +server=/awempire.com/127.0.0.1#5335 +ipset=/awempire.com/gfwlist +server=/empflix.com/127.0.0.1#5335 +ipset=/empflix.com/gfwlist +server=/onstream.cc/127.0.0.1#5335 +ipset=/onstream.cc/gfwlist +server=/mycomicsxxx.com/127.0.0.1#5335 +ipset=/mycomicsxxx.com/gfwlist +server=/github.dev/127.0.0.1#5335 +ipset=/github.dev/gfwlist +server=/cam4.com/127.0.0.1#5335 +ipset=/cam4.com/gfwlist +server=/shameless.com/127.0.0.1#5335 +ipset=/shameless.com/gfwlist +server=/pornjam.com/127.0.0.1#5335 +ipset=/pornjam.com/gfwlist +server=/nintendoswitchtogether.com/127.0.0.1#5335 +ipset=/nintendoswitchtogether.com/gfwlist +server=/moeero-library.com/127.0.0.1#5335 +ipset=/moeero-library.com/gfwlist +server=/noisullifb.com/127.0.0.1#5335 +ipset=/noisullifb.com/gfwlist +server=/perfectgirls.net/127.0.0.1#5335 +ipset=/perfectgirls.net/gfwlist +server=/intel.in/127.0.0.1#5335 +ipset=/intel.in/gfwlist +server=/primevideo.org/127.0.0.1#5335 +ipset=/primevideo.org/gfwlist +server=/authorxml.com/127.0.0.1#5335 +ipset=/authorxml.com/gfwlist +server=/wwwpornhub.pro/127.0.0.1#5335 +ipset=/wwwpornhub.pro/gfwlist +server=/logitechg.com/127.0.0.1#5335 +ipset=/logitechg.com/gfwlist +server=/hawaiibmw.com/127.0.0.1#5335 +ipset=/hawaiibmw.com/gfwlist +server=/management-azure-devices.net/127.0.0.1#5335 +ipset=/management-azure-devices.net/gfwlist +server=/xgames.zone/127.0.0.1#5335 +ipset=/xgames.zone/gfwlist +server=/xsela.cc/127.0.0.1#5335 +ipset=/xsela.cc/gfwlist +server=/netfapx.com/127.0.0.1#5335 +ipset=/netfapx.com/gfwlist +server=/vox-cdn.com/127.0.0.1#5335 +ipset=/vox-cdn.com/gfwlist +server=/youtube.ly/127.0.0.1#5335 +ipset=/youtube.ly/gfwlist +server=/hentai.desi/127.0.0.1#5335 +ipset=/hentai.desi/gfwlist +server=/javday.tv/127.0.0.1#5335 +ipset=/javday.tv/gfwlist +server=/enematube.com/127.0.0.1#5335 +ipset=/enematube.com/gfwlist +server=/dontbubble.us/127.0.0.1#5335 +ipset=/dontbubble.us/gfwlist +server=/services-exchange.com/127.0.0.1#5335 +ipset=/services-exchange.com/gfwlist +server=/brasilincesto.com/127.0.0.1#5335 +ipset=/brasilincesto.com/gfwlist +server=/marketo.co.uk/127.0.0.1#5335 +ipset=/marketo.co.uk/gfwlist +server=/nintendo-europe.com/127.0.0.1#5335 +ipset=/nintendo-europe.com/gfwlist +server=/nxtdig.com.tw/127.0.0.1#5335 +ipset=/nxtdig.com.tw/gfwlist +server=/blogspot.co.at/127.0.0.1#5335 +ipset=/blogspot.co.at/gfwlist +server=/watchanimeattheoffice.com/127.0.0.1#5335 +ipset=/watchanimeattheoffice.com/gfwlist +server=/dojin.com/127.0.0.1#5335 +ipset=/dojin.com/gfwlist +server=/intel.my/127.0.0.1#5335 +ipset=/intel.my/gfwlist +server=/nintendo.co.uk/127.0.0.1#5335 +ipset=/nintendo.co.uk/gfwlist +server=/bmw-motorrad.co.uk/127.0.0.1#5335 +ipset=/bmw-motorrad.co.uk/gfwlist +server=/tgirlpostop.com/127.0.0.1#5335 +ipset=/tgirlpostop.com/gfwlist +server=/minivaughanwest.com/127.0.0.1#5335 +ipset=/minivaughanwest.com/gfwlist +server=/ippog.org/127.0.0.1#5335 +ipset=/ippog.org/gfwlist +server=/aeasyshop.com/127.0.0.1#5335 +ipset=/aeasyshop.com/gfwlist +server=/bmw-eg.com/127.0.0.1#5335 +ipset=/bmw-eg.com/gfwlist +server=/visb.org/127.0.0.1#5335 +ipset=/visb.org/gfwlist +server=/faebok.com/127.0.0.1#5335 +ipset=/faebok.com/gfwlist +server=/mcdonalds.no/127.0.0.1#5335 +ipset=/mcdonalds.no/gfwlist +server=/paypal-special.com/127.0.0.1#5335 +ipset=/paypal-special.com/gfwlist +server=/bunnylust.com/127.0.0.1#5335 +ipset=/bunnylust.com/gfwlist +server=/scholar.google.com.pr/127.0.0.1#5335 +ipset=/scholar.google.com.pr/gfwlist +server=/itunesu.net/127.0.0.1#5335 +ipset=/itunesu.net/gfwlist +server=/directvforhotels.com/127.0.0.1#5335 +ipset=/directvforhotels.com/gfwlist +server=/youtube.co.nz/127.0.0.1#5335 +ipset=/youtube.co.nz/gfwlist +server=/moneyswift.online/127.0.0.1#5335 +ipset=/moneyswift.online/gfwlist +server=/durex.co.il/127.0.0.1#5335 +ipset=/durex.co.il/gfwlist +server=/microsoftnewskids.com/127.0.0.1#5335 +ipset=/microsoftnewskids.com/gfwlist +server=/hetzner.de/127.0.0.1#5335 +ipset=/hetzner.de/gfwlist +server=/bmw-military-sales.com/127.0.0.1#5335 +ipset=/bmw-military-sales.com/gfwlist +server=/buyitnow.com/127.0.0.1#5335 +ipset=/buyitnow.com/gfwlist +server=/goldteenporn.com/127.0.0.1#5335 +ipset=/goldteenporn.com/gfwlist +server=/pornmz.net/127.0.0.1#5335 +ipset=/pornmz.net/gfwlist +server=/oxforddnb.com/127.0.0.1#5335 +ipset=/oxforddnb.com/gfwlist +server=/applicationinsights.io/127.0.0.1#5335 +ipset=/applicationinsights.io/gfwlist +server=/get.new/127.0.0.1#5335 +ipset=/get.new/gfwlist +server=/sssins.com/127.0.0.1#5335 +ipset=/sssins.com/gfwlist +server=/mastercard.hr/127.0.0.1#5335 +ipset=/mastercard.hr/gfwlist +server=/playnintendo.com/127.0.0.1#5335 +ipset=/playnintendo.com/gfwlist +server=/amazon.co.jp/127.0.0.1#5335 +ipset=/amazon.co.jp/gfwlist +server=/visa.com.ge/127.0.0.1#5335 +ipset=/visa.com.ge/gfwlist +server=/didce.com/127.0.0.1#5335 +ipset=/didce.com/gfwlist +server=/milkmanbook.com/127.0.0.1#5335 +ipset=/milkmanbook.com/gfwlist +server=/itu.int/127.0.0.1#5335 +ipset=/itu.int/gfwlist +server=/beatscheap-nz.com/127.0.0.1#5335 +ipset=/beatscheap-nz.com/gfwlist +server=/zbporn.com/127.0.0.1#5335 +ipset=/zbporn.com/gfwlist +server=/verisigninc.com/127.0.0.1#5335 +ipset=/verisigninc.com/gfwlist +server=/lucasentertainment.com/127.0.0.1#5335 +ipset=/lucasentertainment.com/gfwlist +server=/intercomcdn.com/127.0.0.1#5335 +ipset=/intercomcdn.com/gfwlist +server=/embl.fr/127.0.0.1#5335 +ipset=/embl.fr/gfwlist +server=/tunsafe.com/127.0.0.1#5335 +ipset=/tunsafe.com/gfwlist +server=/editorx.com/127.0.0.1#5335 +ipset=/editorx.com/gfwlist +server=/pixanalytics.com/127.0.0.1#5335 +ipset=/pixanalytics.com/gfwlist +server=/wholeplanetfoundation.org/127.0.0.1#5335 +ipset=/wholeplanetfoundation.org/gfwlist +server=/txxx.com/127.0.0.1#5335 +ipset=/txxx.com/gfwlist +server=/lightxxxtube.com/127.0.0.1#5335 +ipset=/lightxxxtube.com/gfwlist +server=/trustsign.ch/127.0.0.1#5335 +ipset=/trustsign.ch/gfwlist +server=/schemer.com/127.0.0.1#5335 +ipset=/schemer.com/gfwlist +server=/pinterest.it/127.0.0.1#5335 +ipset=/pinterest.it/gfwlist +server=/milfpornonly.com/127.0.0.1#5335 +ipset=/milfpornonly.com/gfwlist +server=/msropendata.com/127.0.0.1#5335 +ipset=/msropendata.com/gfwlist +server=/zobry.site/127.0.0.1#5335 +ipset=/zobry.site/gfwlist +server=/ie10.com/127.0.0.1#5335 +ipset=/ie10.com/gfwlist +server=/google.com.py/127.0.0.1#5335 +ipset=/google.com.py/gfwlist +server=/azuredigitaltwins.net/127.0.0.1#5335 +ipset=/azuredigitaltwins.net/gfwlist +server=/pornobom.com.br/127.0.0.1#5335 +ipset=/pornobom.com.br/gfwlist +server=/jmlr.org/127.0.0.1#5335 +ipset=/jmlr.org/gfwlist +server=/bloombergtv.mn/127.0.0.1#5335 +ipset=/bloombergtv.mn/gfwlist +server=/link-o-rama.com/127.0.0.1#5335 +ipset=/link-o-rama.com/gfwlist +server=/drebeatstudio.com/127.0.0.1#5335 +ipset=/drebeatstudio.com/gfwlist +server=/milffox.com/127.0.0.1#5335 +ipset=/milffox.com/gfwlist +server=/digitalcertvalidation.com/127.0.0.1#5335 +ipset=/digitalcertvalidation.com/gfwlist +server=/facebookstories.com/127.0.0.1#5335 +ipset=/facebookstories.com/gfwlist +server=/themercury.com.au/127.0.0.1#5335 +ipset=/themercury.com.au/gfwlist +server=/zoom.com.cn/127.0.0.1#5335 +ipset=/zoom.com.cn/gfwlist +server=/trans500.com/127.0.0.1#5335 +ipset=/trans500.com/gfwlist +server=/faceboof.com/127.0.0.1#5335 +ipset=/faceboof.com/gfwlist +server=/radiofarda.com/127.0.0.1#5335 +ipset=/radiofarda.com/gfwlist +server=/warp.plus/127.0.0.1#5335 +ipset=/warp.plus/gfwlist +server=/paypalbenefits.com/127.0.0.1#5335 +ipset=/paypalbenefits.com/gfwlist +server=/qualcomm.co.id/127.0.0.1#5335 +ipset=/qualcomm.co.id/gfwlist +server=/findacard.com/127.0.0.1#5335 +ipset=/findacard.com/gfwlist +server=/nvidia.fr/127.0.0.1#5335 +ipset=/nvidia.fr/gfwlist +server=/bmw.pt/127.0.0.1#5335 +ipset=/bmw.pt/gfwlist +server=/yaptube.com/127.0.0.1#5335 +ipset=/yaptube.com/gfwlist +server=/studiobeatsbydrdre.com/127.0.0.1#5335 +ipset=/studiobeatsbydrdre.com/gfwlist +server=/rubygems.org/127.0.0.1#5335 +ipset=/rubygems.org/gfwlist +server=/yahoo.com.mx/127.0.0.1#5335 +ipset=/yahoo.com.mx/gfwlist +server=/makecode.org/127.0.0.1#5335 +ipset=/makecode.org/gfwlist +server=/caijinglengyan.com/127.0.0.1#5335 +ipset=/caijinglengyan.com/gfwlist +server=/hentaiworld.tv/127.0.0.1#5335 +ipset=/hentaiworld.tv/gfwlist +server=/nudistbeachporn.com/127.0.0.1#5335 +ipset=/nudistbeachporn.com/gfwlist +server=/ultradonkey.com/127.0.0.1#5335 +ipset=/ultradonkey.com/gfwlist +server=/cbssports.com/127.0.0.1#5335 +ipset=/cbssports.com/gfwlist +server=/tsthai.com/127.0.0.1#5335 +ipset=/tsthai.com/gfwlist +server=/durex.com/127.0.0.1#5335 +ipset=/durex.com/gfwlist +server=/monbeats2013.com/127.0.0.1#5335 +ipset=/monbeats2013.com/gfwlist +server=/tiaz.site/127.0.0.1#5335 +ipset=/tiaz.site/gfwlist +server=/atlantaminidealers.com/127.0.0.1#5335 +ipset=/atlantaminidealers.com/gfwlist +server=/slack-files.com/127.0.0.1#5335 +ipset=/slack-files.com/gfwlist +server=/ddh.gg/127.0.0.1#5335 +ipset=/ddh.gg/gfwlist +server=/espndotcom.tt.omtrdc.net/127.0.0.1#5335 +ipset=/espndotcom.tt.omtrdc.net/gfwlist +server=/lovegirls.cam/127.0.0.1#5335 +ipset=/lovegirls.cam/gfwlist +server=/mastercardworldwide.com/127.0.0.1#5335 +ipset=/mastercardworldwide.com/gfwlist +server=/hentai2read.com/127.0.0.1#5335 +ipset=/hentai2read.com/gfwlist +server=/jove.com/127.0.0.1#5335 +ipset=/jove.com/gfwlist +server=/amateur-fetish.com/127.0.0.1#5335 +ipset=/amateur-fetish.com/gfwlist +server=/illusionze.com/127.0.0.1#5335 +ipset=/illusionze.com/gfwlist +server=/amazon.nl/127.0.0.1#5335 +ipset=/amazon.nl/gfwlist +server=/x3vid.com/127.0.0.1#5335 +ipset=/x3vid.com/gfwlist +server=/bbcpornonly.com/127.0.0.1#5335 +ipset=/bbcpornonly.com/gfwlist +server=/nuki-dokoro.com/127.0.0.1#5335 +ipset=/nuki-dokoro.com/gfwlist +server=/hentai247.net/127.0.0.1#5335 +ipset=/hentai247.net/gfwlist +server=/casquebeatsofficiel-fr.com/127.0.0.1#5335 +ipset=/casquebeatsofficiel-fr.com/gfwlist +server=/dollnight.com/127.0.0.1#5335 +ipset=/dollnight.com/gfwlist +server=/appleone.chat/127.0.0.1#5335 +ipset=/appleone.chat/gfwlist +server=/javhdonline.com/127.0.0.1#5335 +ipset=/javhdonline.com/gfwlist +server=/hentaihub.xxx/127.0.0.1#5335 +ipset=/hentaihub.xxx/gfwlist +server=/latampartneruniversity.com/127.0.0.1#5335 +ipset=/latampartneruniversity.com/gfwlist +server=/facecbook.com/127.0.0.1#5335 +ipset=/facecbook.com/gfwlist +server=/60plusmilfs.com/127.0.0.1#5335 +ipset=/60plusmilfs.com/gfwlist +server=/50plusmilfs.com/127.0.0.1#5335 +ipset=/50plusmilfs.com/gfwlist +server=/myfreeblack.com/127.0.0.1#5335 +ipset=/myfreeblack.com/gfwlist +server=/bmw.com.bn/127.0.0.1#5335 +ipset=/bmw.com.bn/gfwlist +server=/fox49.tv/127.0.0.1#5335 +ipset=/fox49.tv/gfwlist +server=/pearsonelt.ch/127.0.0.1#5335 +ipset=/pearsonelt.ch/gfwlist +server=/collins.in/127.0.0.1#5335 +ipset=/collins.in/gfwlist +server=/thaicherry.com/127.0.0.1#5335 +ipset=/thaicherry.com/gfwlist +server=/chocam.com/127.0.0.1#5335 +ipset=/chocam.com/gfwlist +server=/brill.com/127.0.0.1#5335 +ipset=/brill.com/gfwlist +server=/internetexxxplorer.com/127.0.0.1#5335 +ipset=/internetexxxplorer.com/gfwlist +server=/hboasia.com/127.0.0.1#5335 +ipset=/hboasia.com/gfwlist +server=/mastercard.eu/127.0.0.1#5335 +ipset=/mastercard.eu/gfwlist +server=/accv.es/127.0.0.1#5335 +ipset=/accv.es/gfwlist +server=/bcvp0rtal.com/127.0.0.1#5335 +ipset=/bcvp0rtal.com/gfwlist +server=/fotoscaserasx.com/127.0.0.1#5335 +ipset=/fotoscaserasx.com/gfwlist +server=/udnfunlife.com/127.0.0.1#5335 +ipset=/udnfunlife.com/gfwlist +server=/newsmax.in/127.0.0.1#5335 +ipset=/newsmax.in/gfwlist +server=/youtube.ru/127.0.0.1#5335 +ipset=/youtube.ru/gfwlist +server=/nurofen.es/127.0.0.1#5335 +ipset=/nurofen.es/gfwlist +server=/pscp.tv/127.0.0.1#5335 +ipset=/pscp.tv/gfwlist +server=/excedo.com/127.0.0.1#5335 +ipset=/excedo.com/gfwlist +server=/stocking-tease.com/127.0.0.1#5335 +ipset=/stocking-tease.com/gfwlist +server=/topcartoonsites.com/127.0.0.1#5335 +ipset=/topcartoonsites.com/gfwlist +server=/adult-sex-games.com/127.0.0.1#5335 +ipset=/adult-sex-games.com/gfwlist +server=/homemadeanalporn.com/127.0.0.1#5335 +ipset=/homemadeanalporn.com/gfwlist +server=/adobeexperienceawards.com/127.0.0.1#5335 +ipset=/adobeexperienceawards.com/gfwlist +server=/pki-post.ch/127.0.0.1#5335 +ipset=/pki-post.ch/gfwlist +server=/hp3dsamplepromo.com/127.0.0.1#5335 +ipset=/hp3dsamplepromo.com/gfwlist +server=/mewe.com/127.0.0.1#5335 +ipset=/mewe.com/gfwlist +server=/gputechconf.eu/127.0.0.1#5335 +ipset=/gputechconf.eu/gfwlist +server=/tokyo-sports.co.jp/127.0.0.1#5335 +ipset=/tokyo-sports.co.jp/gfwlist +server=/mcdonalds.se/127.0.0.1#5335 +ipset=/mcdonalds.se/gfwlist +server=/2013beatsbydreshop.com/127.0.0.1#5335 +ipset=/2013beatsbydreshop.com/gfwlist +server=/zooporn.pro/127.0.0.1#5335 +ipset=/zooporn.pro/gfwlist +server=/pornosphere.com/127.0.0.1#5335 +ipset=/pornosphere.com/gfwlist +server=/i91av.org/127.0.0.1#5335 +ipset=/i91av.org/gfwlist +server=/erito.com/127.0.0.1#5335 +ipset=/erito.com/gfwlist +server=/fox9.com/127.0.0.1#5335 +ipset=/fox9.com/gfwlist +server=/durex.ie/127.0.0.1#5335 +ipset=/durex.ie/gfwlist +server=/facebook-program.com/127.0.0.1#5335 +ipset=/facebook-program.com/gfwlist +server=/amebaowndme.com/127.0.0.1#5335 +ipset=/amebaowndme.com/gfwlist +server=/bmwartjourney.com/127.0.0.1#5335 +ipset=/bmwartjourney.com/gfwlist +server=/volvotruckrental.be/127.0.0.1#5335 +ipset=/volvotruckrental.be/gfwlist +server=/paramount.com/127.0.0.1#5335 +ipset=/paramount.com/gfwlist +server=/scene7.com/127.0.0.1#5335 +ipset=/scene7.com/gfwlist +server=/indian-free-xnxx.com/127.0.0.1#5335 +ipset=/indian-free-xnxx.com/gfwlist +server=/easports.com/127.0.0.1#5335 +ipset=/easports.com/gfwlist +server=/avstar04.com/127.0.0.1#5335 +ipset=/avstar04.com/gfwlist +server=/apple.co.uk/127.0.0.1#5335 +ipset=/apple.co.uk/gfwlist +server=/bloombergsurvey.com/127.0.0.1#5335 +ipset=/bloombergsurvey.com/gfwlist +server=/javhdporn.com/127.0.0.1#5335 +ipset=/javhdporn.com/gfwlist +server=/huluapp.com/127.0.0.1#5335 +ipset=/huluapp.com/gfwlist +server=/icloudo.net/127.0.0.1#5335 +ipset=/icloudo.net/gfwlist +server=/vfsforgit.com/127.0.0.1#5335 +ipset=/vfsforgit.com/gfwlist +server=/icloud.sk/127.0.0.1#5335 +ipset=/icloud.sk/gfwlist +server=/adultgamereviews.com/127.0.0.1#5335 +ipset=/adultgamereviews.com/gfwlist +server=/swjedifallenorder.com/127.0.0.1#5335 +ipset=/swjedifallenorder.com/gfwlist +server=/kusugurizanmai.com/127.0.0.1#5335 +ipset=/kusugurizanmai.com/gfwlist +server=/nbcolympics.com/127.0.0.1#5335 +ipset=/nbcolympics.com/gfwlist +server=/sony.pl/127.0.0.1#5335 +ipset=/sony.pl/gfwlist +server=/nownews.com/127.0.0.1#5335 +ipset=/nownews.com/gfwlist +server=/kindle.it/127.0.0.1#5335 +ipset=/kindle.it/gfwlist +server=/foxsports.com.ve/127.0.0.1#5335 +ipset=/foxsports.com.ve/gfwlist +server=/161sex.com/127.0.0.1#5335 +ipset=/161sex.com/gfwlist +server=/jizzle.com/127.0.0.1#5335 +ipset=/jizzle.com/gfwlist +server=/docs.rs/127.0.0.1#5335 +ipset=/docs.rs/gfwlist +server=/verisign.es/127.0.0.1#5335 +ipset=/verisign.es/gfwlist +server=/scharferporno.com/127.0.0.1#5335 +ipset=/scharferporno.com/gfwlist +server=/hentaihaven.xxx/127.0.0.1#5335 +ipset=/hentaihaven.xxx/gfwlist +server=/bmw.com.pe/127.0.0.1#5335 +ipset=/bmw.com.pe/gfwlist +server=/hentaimovieplanet.com/127.0.0.1#5335 +ipset=/hentaimovieplanet.com/gfwlist +server=/democracy.earth/127.0.0.1#5335 +ipset=/democracy.earth/gfwlist +server=/ipodnano.net/127.0.0.1#5335 +ipset=/ipodnano.net/gfwlist +server=/discordcdn.com/127.0.0.1#5335 +ipset=/discordcdn.com/gfwlist +server=/lonestarnaughtygirls.com/127.0.0.1#5335 +ipset=/lonestarnaughtygirls.com/gfwlist +server=/drebeatsdeutschland.net/127.0.0.1#5335 +ipset=/drebeatsdeutschland.net/gfwlist +server=/bestbuyideax.com/127.0.0.1#5335 +ipset=/bestbuyideax.com/gfwlist +server=/xfreehd.com/127.0.0.1#5335 +ipset=/xfreehd.com/gfwlist +server=/ccnsite.com/127.0.0.1#5335 +ipset=/ccnsite.com/gfwlist +server=/volvotrucks.co.uk/127.0.0.1#5335 +ipset=/volvotrucks.co.uk/gfwlist +server=/attspecial.com/127.0.0.1#5335 +ipset=/attspecial.com/gfwlist +server=/momsteachsex.com/127.0.0.1#5335 +ipset=/momsteachsex.com/gfwlist +server=/janor6.net/127.0.0.1#5335 +ipset=/janor6.net/gfwlist +server=/uniswap.org/127.0.0.1#5335 +ipset=/uniswap.org/gfwlist +server=/washa.tv/127.0.0.1#5335 +ipset=/washa.tv/gfwlist +server=/idnike.com/127.0.0.1#5335 +ipset=/idnike.com/gfwlist +server=/bmw-connecteddrive.ch/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ch/gfwlist +server=/directvdealer.com/127.0.0.1#5335 +ipset=/directvdealer.com/gfwlist +server=/awstrust.com/127.0.0.1#5335 +ipset=/awstrust.com/gfwlist +server=/bmw.hr/127.0.0.1#5335 +ipset=/bmw.hr/gfwlist +server=/finishinfo.se/127.0.0.1#5335 +ipset=/finishinfo.se/gfwlist +server=/realmilwaukeenow.com/127.0.0.1#5335 +ipset=/realmilwaukeenow.com/gfwlist +server=/pinterest.at/127.0.0.1#5335 +ipset=/pinterest.at/gfwlist +server=/itunesessentials.com/127.0.0.1#5335 +ipset=/itunesessentials.com/gfwlist +server=/eenike.com/127.0.0.1#5335 +ipset=/eenike.com/gfwlist +server=/cisco-returns.com/127.0.0.1#5335 +ipset=/cisco-returns.com/gfwlist +server=/apple.ro/127.0.0.1#5335 +ipset=/apple.ro/gfwlist +server=/volvotrucks.md/127.0.0.1#5335 +ipset=/volvotrucks.md/gfwlist +server=/appleipodsettlement.com/127.0.0.1#5335 +ipset=/appleipodsettlement.com/gfwlist +server=/shemalehd.sex/127.0.0.1#5335 +ipset=/shemalehd.sex/gfwlist +server=/starbucks.ad/127.0.0.1#5335 +ipset=/starbucks.ad/gfwlist +server=/h-flash.com/127.0.0.1#5335 +ipset=/h-flash.com/gfwlist +server=/rundf665.cyou/127.0.0.1#5335 +ipset=/rundf665.cyou/gfwlist +server=/fastlane.tools/127.0.0.1#5335 +ipset=/fastlane.tools/gfwlist +server=/kindgirls.com/127.0.0.1#5335 +ipset=/kindgirls.com/gfwlist +server=/famousinternetgirls.com/127.0.0.1#5335 +ipset=/famousinternetgirls.com/gfwlist +server=/mcdonalds.com/127.0.0.1#5335 +ipset=/mcdonalds.com/gfwlist +server=/sign.new/127.0.0.1#5335 +ipset=/sign.new/gfwlist +server=/chroniclesec.com/127.0.0.1#5335 +ipset=/chroniclesec.com/gfwlist +server=/ddd-smart.net/127.0.0.1#5335 +ipset=/ddd-smart.net/gfwlist +server=/sextop1.net/127.0.0.1#5335 +ipset=/sextop1.net/gfwlist +server=/xxxtubegf.com/127.0.0.1#5335 +ipset=/xxxtubegf.com/gfwlist +server=/hulugans.com/127.0.0.1#5335 +ipset=/hulugans.com/gfwlist +server=/paheal.net/127.0.0.1#5335 +ipset=/paheal.net/gfwlist +server=/allfet.net/127.0.0.1#5335 +ipset=/allfet.net/gfwlist +server=/pussyporntubes.com/127.0.0.1#5335 +ipset=/pussyporntubes.com/gfwlist +server=/favebook.com/127.0.0.1#5335 +ipset=/favebook.com/gfwlist +server=/beatselectronic.net/127.0.0.1#5335 +ipset=/beatselectronic.net/gfwlist +server=/meetandfuckgames.com/127.0.0.1#5335 +ipset=/meetandfuckgames.com/gfwlist +server=/marvelsuperwar.com/127.0.0.1#5335 +ipset=/marvelsuperwar.com/gfwlist +server=/spotify.map.fastlylb.net/127.0.0.1#5335 +ipset=/spotify.map.fastlylb.net/gfwlist +server=/fastlane.ci/127.0.0.1#5335 +ipset=/fastlane.ci/gfwlist +server=/shemaletrannypics.com/127.0.0.1#5335 +ipset=/shemaletrannypics.com/gfwlist +server=/adulti01.com/127.0.0.1#5335 +ipset=/adulti01.com/gfwlist +server=/applestore.com.tw/127.0.0.1#5335 +ipset=/applestore.com.tw/gfwlist +server=/xnxx-cdn.com/127.0.0.1#5335 +ipset=/xnxx-cdn.com/gfwlist +server=/porn-sex-video.me/127.0.0.1#5335 +ipset=/porn-sex-video.me/gfwlist +server=/raspberrypi.org/127.0.0.1#5335 +ipset=/raspberrypi.org/gfwlist +server=/bloomberg.fm/127.0.0.1#5335 +ipset=/bloomberg.fm/gfwlist +server=/vhxqa2.com/127.0.0.1#5335 +ipset=/vhxqa2.com/gfwlist +server=/mini.by/127.0.0.1#5335 +ipset=/mini.by/gfwlist +server=/girlsfuck-tube.com/127.0.0.1#5335 +ipset=/girlsfuck-tube.com/gfwlist +server=/40momporntube.com/127.0.0.1#5335 +ipset=/40momporntube.com/gfwlist +server=/pornyteen.com/127.0.0.1#5335 +ipset=/pornyteen.com/gfwlist +server=/epigeum.com/127.0.0.1#5335 +ipset=/epigeum.com/gfwlist +server=/salebeatslasteststyle4you.com/127.0.0.1#5335 +ipset=/salebeatslasteststyle4you.com/gfwlist +server=/xxxhentai.net/127.0.0.1#5335 +ipset=/xxxhentai.net/gfwlist +server=/ebay.ie/127.0.0.1#5335 +ipset=/ebay.ie/gfwlist +server=/e-tugra.com/127.0.0.1#5335 +ipset=/e-tugra.com/gfwlist +server=/esm.run/127.0.0.1#5335 +ipset=/esm.run/gfwlist +server=/yahoo.co.bw/127.0.0.1#5335 +ipset=/yahoo.co.bw/gfwlist +server=/dropbox.tech/127.0.0.1#5335 +ipset=/dropbox.tech/gfwlist +server=/badasianpussy.com/127.0.0.1#5335 +ipset=/badasianpussy.com/gfwlist +server=/monsterbeatsbydre-usa.com/127.0.0.1#5335 +ipset=/monsterbeatsbydre-usa.com/gfwlist +server=/coronavirusnow.com/127.0.0.1#5335 +ipset=/coronavirusnow.com/gfwlist +server=/blackamateurfuck.com/127.0.0.1#5335 +ipset=/blackamateurfuck.com/gfwlist +server=/xxxtubezoo.com/127.0.0.1#5335 +ipset=/xxxtubezoo.com/gfwlist +server=/paypal-secure.org/127.0.0.1#5335 +ipset=/paypal-secure.org/gfwlist +server=/ubuntu-touch.io/127.0.0.1#5335 +ipset=/ubuntu-touch.io/gfwlist +server=/venmo-touch.com/127.0.0.1#5335 +ipset=/venmo-touch.com/gfwlist +server=/notepad-plus-plus.org/127.0.0.1#5335 +ipset=/notepad-plus-plus.org/gfwlist +server=/bmw-sports.com/127.0.0.1#5335 +ipset=/bmw-sports.com/gfwlist +server=/creampieforgranny.com/127.0.0.1#5335 +ipset=/creampieforgranny.com/gfwlist +server=/bdsmland.org/127.0.0.1#5335 +ipset=/bdsmland.org/gfwlist +server=/jiuse905.com/127.0.0.1#5335 +ipset=/jiuse905.com/gfwlist +server=/beatscasque-france.com/127.0.0.1#5335 +ipset=/beatscasque-france.com/gfwlist +server=/bmw.ht/127.0.0.1#5335 +ipset=/bmw.ht/gfwlist +server=/yahoo.dk/127.0.0.1#5335 +ipset=/yahoo.dk/gfwlist +server=/hornygirlsonline.org/127.0.0.1#5335 +ipset=/hornygirlsonline.org/gfwlist +server=/yaoiotaku.com/127.0.0.1#5335 +ipset=/yaoiotaku.com/gfwlist +server=/bitsquare.io/127.0.0.1#5335 +ipset=/bitsquare.io/gfwlist +server=/starwarstheoldrepublic.com/127.0.0.1#5335 +ipset=/starwarstheoldrepublic.com/gfwlist +server=/asahicom.jp/127.0.0.1#5335 +ipset=/asahicom.jp/gfwlist +server=/golang.org/127.0.0.1#5335 +ipset=/golang.org/gfwlist +server=/visainfinite.ca/127.0.0.1#5335 +ipset=/visainfinite.ca/gfwlist +server=/bmw.cc/127.0.0.1#5335 +ipset=/bmw.cc/gfwlist +server=/foxnewsnetwork.com/127.0.0.1#5335 +ipset=/foxnewsnetwork.com/gfwlist +server=/visainfiniteluxuryhotels.ca/127.0.0.1#5335 +ipset=/visainfiniteluxuryhotels.ca/gfwlist +server=/bloombergstatus.com/127.0.0.1#5335 +ipset=/bloombergstatus.com/gfwlist +server=/yarininsuyu.com/127.0.0.1#5335 +ipset=/yarininsuyu.com/gfwlist +server=/xxxxvideo.uno/127.0.0.1#5335 +ipset=/xxxxvideo.uno/gfwlist +server=/melonbooks.co.jp/127.0.0.1#5335 +ipset=/melonbooks.co.jp/gfwlist +server=/realamericanstories.info/127.0.0.1#5335 +ipset=/realamericanstories.info/gfwlist +server=/disneyadsales.com/127.0.0.1#5335 +ipset=/disneyadsales.com/gfwlist +server=/needforspeedlightning.com/127.0.0.1#5335 +ipset=/needforspeedlightning.com/gfwlist +server=/ebaycom.com/127.0.0.1#5335 +ipset=/ebaycom.com/gfwlist +server=/d-trust.net/127.0.0.1#5335 +ipset=/d-trust.net/gfwlist +server=/gfpornmovies.com/127.0.0.1#5335 +ipset=/gfpornmovies.com/gfwlist +server=/iphoneacessorios.com.br/127.0.0.1#5335 +ipset=/iphoneacessorios.com.br/gfwlist +server=/redgifs.com/127.0.0.1#5335 +ipset=/redgifs.com/gfwlist +server=/fox26houston.com/127.0.0.1#5335 +ipset=/fox26houston.com/gfwlist +server=/upjav.cc/127.0.0.1#5335 +ipset=/upjav.cc/gfwlist +server=/blazor.net/127.0.0.1#5335 +ipset=/blazor.net/gfwlist +server=/nextwork.com.tw/127.0.0.1#5335 +ipset=/nextwork.com.tw/gfwlist +server=/blogspot.lt/127.0.0.1#5335 +ipset=/blogspot.lt/gfwlist +server=/merakigo.com/127.0.0.1#5335 +ipset=/merakigo.com/gfwlist +server=/onefifteen.org/127.0.0.1#5335 +ipset=/onefifteen.org/gfwlist +server=/life-global.org/127.0.0.1#5335 +ipset=/life-global.org/gfwlist +server=/shockingmovies.com/127.0.0.1#5335 +ipset=/shockingmovies.com/gfwlist +server=/pca.st/127.0.0.1#5335 +ipset=/pca.st/gfwlist +server=/drbizzaro.com/127.0.0.1#5335 +ipset=/drbizzaro.com/gfwlist +server=/camgoddess.tv/127.0.0.1#5335 +ipset=/camgoddess.tv/gfwlist +server=/gaythebest.com/127.0.0.1#5335 +ipset=/gaythebest.com/gfwlist +server=/databank.worldbank.org/127.0.0.1#5335 +ipset=/databank.worldbank.org/gfwlist +server=/6arabs.com/127.0.0.1#5335 +ipset=/6arabs.com/gfwlist +server=/xxxpicz.com/127.0.0.1#5335 +ipset=/xxxpicz.com/gfwlist +server=/volvotrucks.ee/127.0.0.1#5335 +ipset=/volvotrucks.ee/gfwlist +server=/xenoblade.com/127.0.0.1#5335 +ipset=/xenoblade.com/gfwlist +server=/icloud-content.com/127.0.0.1#5335 +ipset=/icloud-content.com/gfwlist +server=/gemfire.net/127.0.0.1#5335 +ipset=/gemfire.net/gfwlist +server=/udn.com.tw/127.0.0.1#5335 +ipset=/udn.com.tw/gfwlist +server=/vivaxnxx.com/127.0.0.1#5335 +ipset=/vivaxnxx.com/gfwlist +server=/forbiddenasian.com/127.0.0.1#5335 +ipset=/forbiddenasian.com/gfwlist +server=/ydn.com.tw/127.0.0.1#5335 +ipset=/ydn.com.tw/gfwlist +server=/mktorest.com/127.0.0.1#5335 +ipset=/mktorest.com/gfwlist +server=/epochtimes.com.tw/127.0.0.1#5335 +ipset=/epochtimes.com.tw/gfwlist +server=/pornhubdeutsch.net/127.0.0.1#5335 +ipset=/pornhubdeutsch.net/gfwlist +server=/ebay-us.com/127.0.0.1#5335 +ipset=/ebay-us.com/gfwlist +server=/volvopenta.com/127.0.0.1#5335 +ipset=/volvopenta.com/gfwlist +server=/faststone.org/127.0.0.1#5335 +ipset=/faststone.org/gfwlist +server=/googledrive.com/127.0.0.1#5335 +ipset=/googledrive.com/gfwlist +server=/mybmw.ca/127.0.0.1#5335 +ipset=/mybmw.ca/gfwlist +server=/iproperty.com/127.0.0.1#5335 +ipset=/iproperty.com/gfwlist +server=/truyen-hentai.fr/127.0.0.1#5335 +ipset=/truyen-hentai.fr/gfwlist +server=/brdteengal.com/127.0.0.1#5335 +ipset=/brdteengal.com/gfwlist +server=/attpurchasing.com/127.0.0.1#5335 +ipset=/attpurchasing.com/gfwlist +server=/hzmn.net/127.0.0.1#5335 +ipset=/hzmn.net/gfwlist +server=/xxxassfuck.com/127.0.0.1#5335 +ipset=/xxxassfuck.com/gfwlist +server=/xvideos-dl.top/127.0.0.1#5335 +ipset=/xvideos-dl.top/gfwlist +server=/adidas.dk/127.0.0.1#5335 +ipset=/adidas.dk/gfwlist +server=/yahoo.com.tj/127.0.0.1#5335 +ipset=/yahoo.com.tj/gfwlist +server=/gamer2-cds.cdn.hinet.net/127.0.0.1#5335 +ipset=/gamer2-cds.cdn.hinet.net/gfwlist +server=/mingky.org/127.0.0.1#5335 +ipset=/mingky.org/gfwlist +server=/ebayenterprise.info/127.0.0.1#5335 +ipset=/ebayenterprise.info/gfwlist +server=/yandex.ee/127.0.0.1#5335 +ipset=/yandex.ee/gfwlist +server=/beatsoutlet.net/127.0.0.1#5335 +ipset=/beatsoutlet.net/gfwlist +server=/amazonvideodirect.com/127.0.0.1#5335 +ipset=/amazonvideodirect.com/gfwlist +server=/bmwtampabay.com/127.0.0.1#5335 +ipset=/bmwtampabay.com/gfwlist +server=/dealbay.com/127.0.0.1#5335 +ipset=/dealbay.com/gfwlist +server=/opensuse.org/127.0.0.1#5335 +ipset=/opensuse.org/gfwlist +server=/zeronet.io/127.0.0.1#5335 +ipset=/zeronet.io/gfwlist +server=/finishinfo.jp/127.0.0.1#5335 +ipset=/finishinfo.jp/gfwlist +server=/pornstreams.tv/127.0.0.1#5335 +ipset=/pornstreams.tv/gfwlist +server=/newmonst1erbeatsto1re.com/127.0.0.1#5335 +ipset=/newmonst1erbeatsto1re.com/gfwlist +server=/qq.design/127.0.0.1#5335 +ipset=/qq.design/gfwlist +server=/townsvillebulletin.com.au/127.0.0.1#5335 +ipset=/townsvillebulletin.com.au/gfwlist +server=/javmuch.com/127.0.0.1#5335 +ipset=/javmuch.com/gfwlist +server=/jbe-platform.com/127.0.0.1#5335 +ipset=/jbe-platform.com/gfwlist +server=/huffpostbrasil.com/127.0.0.1#5335 +ipset=/huffpostbrasil.com/gfwlist +server=/totoleak.com/127.0.0.1#5335 +ipset=/totoleak.com/gfwlist +server=/facebook30.net/127.0.0.1#5335 +ipset=/facebook30.net/gfwlist +server=/mastercard.my/127.0.0.1#5335 +ipset=/mastercard.my/gfwlist +server=/sexarea.org/127.0.0.1#5335 +ipset=/sexarea.org/gfwlist +server=/digicert.com/127.0.0.1#5335 +ipset=/digicert.com/gfwlist +server=/straightouttasomewhere.com/127.0.0.1#5335 +ipset=/straightouttasomewhere.com/gfwlist +server=/vtvan.com/127.0.0.1#5335 +ipset=/vtvan.com/gfwlist +server=/filmesdesexo.blog/127.0.0.1#5335 +ipset=/filmesdesexo.blog/gfwlist +server=/netflixdnstest2.com/127.0.0.1#5335 +ipset=/netflixdnstest2.com/gfwlist +server=/pornoslon.me/127.0.0.1#5335 +ipset=/pornoslon.me/gfwlist +server=/cashpassport.com/127.0.0.1#5335 +ipset=/cashpassport.com/gfwlist +server=/osdn.net/127.0.0.1#5335 +ipset=/osdn.net/gfwlist +server=/doujin-eromanga.com/127.0.0.1#5335 +ipset=/doujin-eromanga.com/gfwlist +server=/youtube.com.ec/127.0.0.1#5335 +ipset=/youtube.com.ec/gfwlist +server=/icloudbox.net/127.0.0.1#5335 +ipset=/icloudbox.net/gfwlist +server=/google.kg/127.0.0.1#5335 +ipset=/google.kg/gfwlist +server=/paypal-proserv.com/127.0.0.1#5335 +ipset=/paypal-proserv.com/gfwlist +server=/cheapbeatsbydreonsale.com/127.0.0.1#5335 +ipset=/cheapbeatsbydreonsale.com/gfwlist +server=/facbool.com/127.0.0.1#5335 +ipset=/facbool.com/gfwlist +server=/tencent.design/127.0.0.1#5335 +ipset=/tencent.design/gfwlist +server=/localizecdn.com/127.0.0.1#5335 +ipset=/localizecdn.com/gfwlist +server=/shadowslaves.com/127.0.0.1#5335 +ipset=/shadowslaves.com/gfwlist +server=/office365tw.com/127.0.0.1#5335 +ipset=/office365tw.com/gfwlist +server=/onedrive.co.uk/127.0.0.1#5335 +ipset=/onedrive.co.uk/gfwlist +server=/xogogo.com/127.0.0.1#5335 +ipset=/xogogo.com/gfwlist +server=/github.blog/127.0.0.1#5335 +ipset=/github.blog/gfwlist +server=/yahoo.com.pk/127.0.0.1#5335 +ipset=/yahoo.com.pk/gfwlist +server=/macromedia.com/127.0.0.1#5335 +ipset=/macromedia.com/gfwlist +server=/appleone.club/127.0.0.1#5335 +ipset=/appleone.club/gfwlist +server=/volvobuses.tn/127.0.0.1#5335 +ipset=/volvobuses.tn/gfwlist +server=/nubilefilms.com/127.0.0.1#5335 +ipset=/nubilefilms.com/gfwlist +server=/admeld.com/127.0.0.1#5335 +ipset=/admeld.com/gfwlist +server=/worldsecuresystems.com/127.0.0.1#5335 +ipset=/worldsecuresystems.com/gfwlist +server=/freeanimalporn.net/127.0.0.1#5335 +ipset=/freeanimalporn.net/gfwlist +server=/redmatureporn.com/127.0.0.1#5335 +ipset=/redmatureporn.com/gfwlist +server=/3dsexgames.biz/127.0.0.1#5335 +ipset=/3dsexgames.biz/gfwlist +server=/voadeewanews.com/127.0.0.1#5335 +ipset=/voadeewanews.com/gfwlist +server=/bttzyw.com/127.0.0.1#5335 +ipset=/bttzyw.com/gfwlist +server=/gorin.jp/127.0.0.1#5335 +ipset=/gorin.jp/gfwlist +server=/pornprosnetwork.com/127.0.0.1#5335 +ipset=/pornprosnetwork.com/gfwlist +server=/singtaoopo.com/127.0.0.1#5335 +ipset=/singtaoopo.com/gfwlist +server=/xkeezmovies.com/127.0.0.1#5335 +ipset=/xkeezmovies.com/gfwlist +server=/bestialitytaboo.tv/127.0.0.1#5335 +ipset=/bestialitytaboo.tv/gfwlist +server=/sexy-models.net/127.0.0.1#5335 +ipset=/sexy-models.net/gfwlist +server=/centrino.com/127.0.0.1#5335 +ipset=/centrino.com/gfwlist +server=/paulsimon-music.com/127.0.0.1#5335 +ipset=/paulsimon-music.com/gfwlist +server=/beatsodre.com/127.0.0.1#5335 +ipset=/beatsodre.com/gfwlist +server=/simcity-buildit.com/127.0.0.1#5335 +ipset=/simcity-buildit.com/gfwlist +server=/jstor.org/127.0.0.1#5335 +ipset=/jstor.org/gfwlist +server=/urlgalleries.net/127.0.0.1#5335 +ipset=/urlgalleries.net/gfwlist +server=/businessinsider.com.pl/127.0.0.1#5335 +ipset=/businessinsider.com.pl/gfwlist +server=/wowyoungporn.com/127.0.0.1#5335 +ipset=/wowyoungporn.com/gfwlist +server=/rbeuroinfo.com/127.0.0.1#5335 +ipset=/rbeuroinfo.com/gfwlist +server=/265sdwe3.com/127.0.0.1#5335 +ipset=/265sdwe3.com/gfwlist +server=/iwank.tv/127.0.0.1#5335 +ipset=/iwank.tv/gfwlist +server=/cdnjs.com/127.0.0.1#5335 +ipset=/cdnjs.com/gfwlist +server=/privateclassics.com/127.0.0.1#5335 +ipset=/privateclassics.com/gfwlist +server=/feedly.com/127.0.0.1#5335 +ipset=/feedly.com/gfwlist +server=/xnxx.tv/127.0.0.1#5335 +ipset=/xnxx.tv/gfwlist +server=/bmw-connecteddrive.fr/127.0.0.1#5335 +ipset=/bmw-connecteddrive.fr/gfwlist +server=/rbnainternational.com/127.0.0.1#5335 +ipset=/rbnainternational.com/gfwlist +server=/wankoz.com/127.0.0.1#5335 +ipset=/wankoz.com/gfwlist +server=/analfuckvideo.com/127.0.0.1#5335 +ipset=/analfuckvideo.com/gfwlist +server=/microsofttradein.com/127.0.0.1#5335 +ipset=/microsofttradein.com/gfwlist +server=/statics-marketingsites-wcus-ms-com.akamaized.net/127.0.0.1#5335 +ipset=/statics-marketingsites-wcus-ms-com.akamaized.net/gfwlist +server=/c4rex.co/127.0.0.1#5335 +ipset=/c4rex.co/gfwlist +server=/fapopedia.net/127.0.0.1#5335 +ipset=/fapopedia.net/gfwlist +server=/kamababa.com/127.0.0.1#5335 +ipset=/kamababa.com/gfwlist +server=/videosdepornografia.blog.br/127.0.0.1#5335 +ipset=/videosdepornografia.blog.br/gfwlist +server=/thomsonreuters.com.au/127.0.0.1#5335 +ipset=/thomsonreuters.com.au/gfwlist +server=/thrixxx.com/127.0.0.1#5335 +ipset=/thrixxx.com/gfwlist +server=/amazontrust.com/127.0.0.1#5335 +ipset=/amazontrust.com/gfwlist +server=/porndroids.com/127.0.0.1#5335 +ipset=/porndroids.com/gfwlist +server=/viddeo-jav.net/127.0.0.1#5335 +ipset=/viddeo-jav.net/gfwlist +server=/qmov.com/127.0.0.1#5335 +ipset=/qmov.com/gfwlist +server=/seasidestory.tokyo/127.0.0.1#5335 +ipset=/seasidestory.tokyo/gfwlist +server=/nikebiz.info/127.0.0.1#5335 +ipset=/nikebiz.info/gfwlist +server=/4hu.tv/127.0.0.1#5335 +ipset=/4hu.tv/gfwlist +server=/crustwebsites.net/127.0.0.1#5335 +ipset=/crustwebsites.net/gfwlist +server=/srtcdn.net/127.0.0.1#5335 +ipset=/srtcdn.net/gfwlist +server=/facebookw.com/127.0.0.1#5335 +ipset=/facebookw.com/gfwlist +server=/monsterbeatsstore.com/127.0.0.1#5335 +ipset=/monsterbeatsstore.com/gfwlist +server=/volvotrucks.id/127.0.0.1#5335 +ipset=/volvotrucks.id/gfwlist +server=/sextubebox.com/127.0.0.1#5335 +ipset=/sextubebox.com/gfwlist +server=/femalefounderscomp.com/127.0.0.1#5335 +ipset=/femalefounderscomp.com/gfwlist +server=/sexecherche.com/127.0.0.1#5335 +ipset=/sexecherche.com/gfwlist +server=/classymomsex.com/127.0.0.1#5335 +ipset=/classymomsex.com/gfwlist +server=/pokemonblackwhite.com/127.0.0.1#5335 +ipset=/pokemonblackwhite.com/gfwlist +server=/monsterbeats-onsale.com/127.0.0.1#5335 +ipset=/monsterbeats-onsale.com/gfwlist +server=/amazonsdi.com/127.0.0.1#5335 +ipset=/amazonsdi.com/gfwlist +server=/iwantgalleries.com/127.0.0.1#5335 +ipset=/iwantgalleries.com/gfwlist +server=/kimosex.com/127.0.0.1#5335 +ipset=/kimosex.com/gfwlist +server=/bdsmstreak.com/127.0.0.1#5335 +ipset=/bdsmstreak.com/gfwlist +server=/optimumssl.com/127.0.0.1#5335 +ipset=/optimumssl.com/gfwlist +server=/sqlserveronlinux.com/127.0.0.1#5335 +ipset=/sqlserveronlinux.com/gfwlist +server=/ctee.com.tw/127.0.0.1#5335 +ipset=/ctee.com.tw/gfwlist +server=/eiu.com/127.0.0.1#5335 +ipset=/eiu.com/gfwlist +server=/doujin-info.net/127.0.0.1#5335 +ipset=/doujin-info.net/gfwlist +server=/dropboxpartners.com/127.0.0.1#5335 +ipset=/dropboxpartners.com/gfwlist +server=/scholar.google.gr/127.0.0.1#5335 +ipset=/scholar.google.gr/gfwlist +server=/bitflyer.com/127.0.0.1#5335 +ipset=/bitflyer.com/gfwlist +server=/appleworldwidedeveloper.hb-api.omtrdc.net/127.0.0.1#5335 +ipset=/appleworldwidedeveloper.hb-api.omtrdc.net/gfwlist +server=/oneapi.com/127.0.0.1#5335 +ipset=/oneapi.com/gfwlist +server=/amazon.it/127.0.0.1#5335 +ipset=/amazon.it/gfwlist +server=/mvideoporno.xxx/127.0.0.1#5335 +ipset=/mvideoporno.xxx/gfwlist +server=/fappeningthots.com/127.0.0.1#5335 +ipset=/fappeningthots.com/gfwlist +server=/buddymedia.com/127.0.0.1#5335 +ipset=/buddymedia.com/gfwlist +server=/ipod.com.fr/127.0.0.1#5335 +ipset=/ipod.com.fr/gfwlist +server=/thegithubshop.com/127.0.0.1#5335 +ipset=/thegithubshop.com/gfwlist +server=/mu6bce1c.xyz/127.0.0.1#5335 +ipset=/mu6bce1c.xyz/gfwlist +server=/google.com.gh/127.0.0.1#5335 +ipset=/google.com.gh/gfwlist +server=/stacksnippets.net/127.0.0.1#5335 +ipset=/stacksnippets.net/gfwlist +server=/shenyunperformingarts.org/127.0.0.1#5335 +ipset=/shenyunperformingarts.org/gfwlist +server=/gotporn.com/127.0.0.1#5335 +ipset=/gotporn.com/gfwlist +server=/voabambara.com/127.0.0.1#5335 +ipset=/voabambara.com/gfwlist +server=/porngub.com/127.0.0.1#5335 +ipset=/porngub.com/gfwlist +server=/vscode-cdn.net/127.0.0.1#5335 +ipset=/vscode-cdn.net/gfwlist +server=/sexsim.com/127.0.0.1#5335 +ipset=/sexsim.com/gfwlist +server=/veet.co.kr/127.0.0.1#5335 +ipset=/veet.co.kr/gfwlist +server=/pandamovies.pw/127.0.0.1#5335 +ipset=/pandamovies.pw/gfwlist +server=/paypal-center.info/127.0.0.1#5335 +ipset=/paypal-center.info/gfwlist +server=/watch-my-gf.com/127.0.0.1#5335 +ipset=/watch-my-gf.com/gfwlist +server=/zohowebstatic.com/127.0.0.1#5335 +ipset=/zohowebstatic.com/gfwlist +server=/paypal-marketing.com/127.0.0.1#5335 +ipset=/paypal-marketing.com/gfwlist +server=/hackthedrive.com/127.0.0.1#5335 +ipset=/hackthedrive.com/gfwlist +server=/liketwice.com/127.0.0.1#5335 +ipset=/liketwice.com/gfwlist +server=/target.com/127.0.0.1#5335 +ipset=/target.com/gfwlist +server=/viu.tv/127.0.0.1#5335 +ipset=/viu.tv/gfwlist +server=/art1lib.com/127.0.0.1#5335 +ipset=/art1lib.com/gfwlist +server=/theuab.net/127.0.0.1#5335 +ipset=/theuab.net/gfwlist +server=/djreprints.com/127.0.0.1#5335 +ipset=/djreprints.com/gfwlist +server=/sexu.com/127.0.0.1#5335 +ipset=/sexu.com/gfwlist +server=/2013pascherbeatsbydre.com/127.0.0.1#5335 +ipset=/2013pascherbeatsbydre.com/gfwlist +server=/sspanel.net/127.0.0.1#5335 +ipset=/sspanel.net/gfwlist +server=/vmwxw.com/127.0.0.1#5335 +ipset=/vmwxw.com/gfwlist +server=/proctoscopeexam.com/127.0.0.1#5335 +ipset=/proctoscopeexam.com/gfwlist +server=/facebook4business.com/127.0.0.1#5335 +ipset=/facebook4business.com/gfwlist +server=/mdnkids.com/127.0.0.1#5335 +ipset=/mdnkids.com/gfwlist +server=/realclearenergy.org/127.0.0.1#5335 +ipset=/realclearenergy.org/gfwlist +server=/jusmynote.wordpress.com/127.0.0.1#5335 +ipset=/jusmynote.wordpress.com/gfwlist +server=/monsterbeatsbydreshop.com/127.0.0.1#5335 +ipset=/monsterbeatsbydreshop.com/gfwlist +server=/silkengirl.com/127.0.0.1#5335 +ipset=/silkengirl.com/gfwlist +server=/pornbest.org/127.0.0.1#5335 +ipset=/pornbest.org/gfwlist +server=/visa.hk/127.0.0.1#5335 +ipset=/visa.hk/gfwlist +server=/bmw-connecteddrive.lt/127.0.0.1#5335 +ipset=/bmw-connecteddrive.lt/gfwlist +server=/monsterdrebeats-usa.net/127.0.0.1#5335 +ipset=/monsterdrebeats-usa.net/gfwlist +server=/foxneo.com/127.0.0.1#5335 +ipset=/foxneo.com/gfwlist +server=/cisco-warrantyfinder.com/127.0.0.1#5335 +ipset=/cisco-warrantyfinder.com/gfwlist +server=/weverse.io/127.0.0.1#5335 +ipset=/weverse.io/gfwlist +server=/ftvgirls.com/127.0.0.1#5335 +ipset=/ftvgirls.com/gfwlist +server=/bukkake.link/127.0.0.1#5335 +ipset=/bukkake.link/gfwlist +server=/snapchat.com/127.0.0.1#5335 +ipset=/snapchat.com/gfwlist +server=/primecurves.com/127.0.0.1#5335 +ipset=/primecurves.com/gfwlist +server=/ahpornotube.com/127.0.0.1#5335 +ipset=/ahpornotube.com/gfwlist +server=/iwantporn.net/127.0.0.1#5335 +ipset=/iwantporn.net/gfwlist +server=/bmwzentrum.com/127.0.0.1#5335 +ipset=/bmwzentrum.com/gfwlist +server=/mastercard.de/127.0.0.1#5335 +ipset=/mastercard.de/gfwlist +server=/alphabet.org.uk/127.0.0.1#5335 +ipset=/alphabet.org.uk/gfwlist +server=/umamusume.akamaized.net/127.0.0.1#5335 +ipset=/umamusume.akamaized.net/gfwlist +server=/yahoo.com.uy/127.0.0.1#5335 +ipset=/yahoo.com.uy/gfwlist +server=/mwhentai.net/127.0.0.1#5335 +ipset=/mwhentai.net/gfwlist +server=/hbogoasia.hk/127.0.0.1#5335 +ipset=/hbogoasia.hk/gfwlist +server=/bmw-connecteddrive.co.nz/127.0.0.1#5335 +ipset=/bmw-connecteddrive.co.nz/gfwlist +server=/hotmail.net/127.0.0.1#5335 +ipset=/hotmail.net/gfwlist +server=/youtube.com.ly/127.0.0.1#5335 +ipset=/youtube.com.ly/gfwlist +server=/caime.xyz/127.0.0.1#5335 +ipset=/caime.xyz/gfwlist +server=/curve.fi/127.0.0.1#5335 +ipset=/curve.fi/gfwlist +server=/monsterbeatsshops.net/127.0.0.1#5335 +ipset=/monsterbeatsshops.net/gfwlist +server=/vanish.sk/127.0.0.1#5335 +ipset=/vanish.sk/gfwlist +server=/hentai2.net/127.0.0.1#5335 +ipset=/hentai2.net/gfwlist +server=/enfabebe.com/127.0.0.1#5335 +ipset=/enfabebe.com/gfwlist +server=/bmwgroup.jobs/127.0.0.1#5335 +ipset=/bmwgroup.jobs/gfwlist +server=/lacomics.org/127.0.0.1#5335 +ipset=/lacomics.org/gfwlist +server=/homedepot-static.com/127.0.0.1#5335 +ipset=/homedepot-static.com/gfwlist +server=/postyourgirls.ws/127.0.0.1#5335 +ipset=/postyourgirls.ws/gfwlist +server=/onlynudes.org/127.0.0.1#5335 +ipset=/onlynudes.org/gfwlist +server=/leagueoflegends.co.kr/127.0.0.1#5335 +ipset=/leagueoflegends.co.kr/gfwlist +server=/mastercard.com.mx/127.0.0.1#5335 +ipset=/mastercard.com.mx/gfwlist +server=/duoweiweek.com/127.0.0.1#5335 +ipset=/duoweiweek.com/gfwlist +server=/sexvideos.tel/127.0.0.1#5335 +ipset=/sexvideos.tel/gfwlist +server=/integral7.com/127.0.0.1#5335 +ipset=/integral7.com/gfwlist +server=/now.sh/127.0.0.1#5335 +ipset=/now.sh/gfwlist +server=/madshi.net/127.0.0.1#5335 +ipset=/madshi.net/gfwlist +server=/visa.com/127.0.0.1#5335 +ipset=/visa.com/gfwlist +server=/techstreet.com/127.0.0.1#5335 +ipset=/techstreet.com/gfwlist +server=/vanish.es/127.0.0.1#5335 +ipset=/vanish.es/gfwlist +server=/adventofcode.com/127.0.0.1#5335 +ipset=/adventofcode.com/gfwlist +server=/mastercard.com.gt/127.0.0.1#5335 +ipset=/mastercard.com.gt/gfwlist +server=/applestore.co.uk/127.0.0.1#5335 +ipset=/applestore.co.uk/gfwlist +server=/sheflix.com/127.0.0.1#5335 +ipset=/sheflix.com/gfwlist +server=/9ccms.me/127.0.0.1#5335 +ipset=/9ccms.me/gfwlist +server=/verisign.com.vn/127.0.0.1#5335 +ipset=/verisign.com.vn/gfwlist +server=/apple.ca/127.0.0.1#5335 +ipset=/apple.ca/gfwlist +server=/thehulubraintrust.com/127.0.0.1#5335 +ipset=/thehulubraintrust.com/gfwlist +server=/older-women-porn.com/127.0.0.1#5335 +ipset=/older-women-porn.com/gfwlist +server=/5q5zu9f1.me/127.0.0.1#5335 +ipset=/5q5zu9f1.me/gfwlist +server=/whereilive.com.au/127.0.0.1#5335 +ipset=/whereilive.com.au/gfwlist +server=/microsoftsilverlight.com/127.0.0.1#5335 +ipset=/microsoftsilverlight.com/gfwlist +server=/bmw-motorrad.fi/127.0.0.1#5335 +ipset=/bmw-motorrad.fi/gfwlist +server=/sextubedot.com/127.0.0.1#5335 +ipset=/sextubedot.com/gfwlist +server=/whatbrowser.org/127.0.0.1#5335 +ipset=/whatbrowser.org/gfwlist +server=/amateurgirlfriends.net/127.0.0.1#5335 +ipset=/amateurgirlfriends.net/gfwlist +server=/globalsign.nl/127.0.0.1#5335 +ipset=/globalsign.nl/gfwlist +server=/mini.my/127.0.0.1#5335 +ipset=/mini.my/gfwlist +server=/clubhouseapi.com/127.0.0.1#5335 +ipset=/clubhouseapi.com/gfwlist +server=/sale-nikeshoes.com/127.0.0.1#5335 +ipset=/sale-nikeshoes.com/gfwlist +server=/fapxl.com/127.0.0.1#5335 +ipset=/fapxl.com/gfwlist +server=/hentaicore.net/127.0.0.1#5335 +ipset=/hentaicore.net/gfwlist +server=/wsjmediakit.com/127.0.0.1#5335 +ipset=/wsjmediakit.com/gfwlist +server=/haskell.org/127.0.0.1#5335 +ipset=/haskell.org/gfwlist +server=/moviesarena.com/127.0.0.1#5335 +ipset=/moviesarena.com/gfwlist +server=/beatsbydreaustraliaonline.com/127.0.0.1#5335 +ipset=/beatsbydreaustraliaonline.com/gfwlist +server=/scholar.google.fi/127.0.0.1#5335 +ipset=/scholar.google.fi/gfwlist +server=/visa.com.gy/127.0.0.1#5335 +ipset=/visa.com.gy/gfwlist +server=/ebaystore77.com/127.0.0.1#5335 +ipset=/ebaystore77.com/gfwlist +server=/cheapmonsterbeatsbydrdre.com/127.0.0.1#5335 +ipset=/cheapmonsterbeatsbydrdre.com/gfwlist +server=/scientificamerican.com/127.0.0.1#5335 +ipset=/scientificamerican.com/gfwlist +server=/ebayopensource.com/127.0.0.1#5335 +ipset=/ebayopensource.com/gfwlist +server=/xtube.com/127.0.0.1#5335 +ipset=/xtube.com/gfwlist +server=/0xxx.ws/127.0.0.1#5335 +ipset=/0xxx.ws/gfwlist +server=/omobi.cc/127.0.0.1#5335 +ipset=/omobi.cc/gfwlist +server=/bestbuy-audio.com/127.0.0.1#5335 +ipset=/bestbuy-audio.com/gfwlist +server=/herodex.org/127.0.0.1#5335 +ipset=/herodex.org/gfwlist +server=/deps.info/127.0.0.1#5335 +ipset=/deps.info/gfwlist +server=/hpsuresupply.com/127.0.0.1#5335 +ipset=/hpsuresupply.com/gfwlist +server=/worldflipper.jp/127.0.0.1#5335 +ipset=/worldflipper.jp/gfwlist +server=/foxneodigital.com/127.0.0.1#5335 +ipset=/foxneodigital.com/gfwlist +server=/hpccp.com/127.0.0.1#5335 +ipset=/hpccp.com/gfwlist +server=/mini.no/127.0.0.1#5335 +ipset=/mini.no/gfwlist +server=/amateursexstart.nl/127.0.0.1#5335 +ipset=/amateursexstart.nl/gfwlist +server=/accountkit.com/127.0.0.1#5335 +ipset=/accountkit.com/gfwlist +server=/facebookcovers.org/127.0.0.1#5335 +ipset=/facebookcovers.org/gfwlist +server=/besztbuy.com/127.0.0.1#5335 +ipset=/besztbuy.com/gfwlist +server=/digitaldesire.com/127.0.0.1#5335 +ipset=/digitaldesire.com/gfwlist +server=/canon.com.mk/127.0.0.1#5335 +ipset=/canon.com.mk/gfwlist +server=/applemusicfestival.com/127.0.0.1#5335 +ipset=/applemusicfestival.com/gfwlist +server=/xn--d4ty0ojsqzfd.com/127.0.0.1#5335 +ipset=/xn--d4ty0ojsqzfd.com/gfwlist +server=/notion.new/127.0.0.1#5335 +ipset=/notion.new/gfwlist +server=/scholar.google.co.th/127.0.0.1#5335 +ipset=/scholar.google.co.th/gfwlist +server=/4beatsbydre.com/127.0.0.1#5335 +ipset=/4beatsbydre.com/gfwlist +server=/5beatsbydre.com/127.0.0.1#5335 +ipset=/5beatsbydre.com/gfwlist +server=/erotera.blogo.jp/127.0.0.1#5335 +ipset=/erotera.blogo.jp/gfwlist +server=/beatsbydreheadphonesolo.com/127.0.0.1#5335 +ipset=/beatsbydreheadphonesolo.com/gfwlist +server=/mostly.jp/127.0.0.1#5335 +ipset=/mostly.jp/gfwlist +server=/drebeats-singapore.com/127.0.0.1#5335 +ipset=/drebeats-singapore.com/gfwlist +server=/google.lt/127.0.0.1#5335 +ipset=/google.lt/gfwlist +server=/disneylatino.com/127.0.0.1#5335 +ipset=/disneylatino.com/gfwlist +server=/grupobmw.com/127.0.0.1#5335 +ipset=/grupobmw.com/gfwlist +server=/minisolife.co.za/127.0.0.1#5335 +ipset=/minisolife.co.za/gfwlist +server=/fox-news.com/127.0.0.1#5335 +ipset=/fox-news.com/gfwlist +server=/monsterbeatsbydrdrecanada.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrdrecanada.com/gfwlist +server=/pinterest.co.kr/127.0.0.1#5335 +ipset=/pinterest.co.kr/gfwlist +server=/localbitcoins.com/127.0.0.1#5335 +ipset=/localbitcoins.com/gfwlist +server=/propertysex.com/127.0.0.1#5335 +ipset=/propertysex.com/gfwlist +server=/h2porn.com/127.0.0.1#5335 +ipset=/h2porn.com/gfwlist +server=/acmvalidations.com/127.0.0.1#5335 +ipset=/acmvalidations.com/gfwlist +server=/appleid-uk.us/127.0.0.1#5335 +ipset=/appleid-uk.us/gfwlist +server=/appyq.com/127.0.0.1#5335 +ipset=/appyq.com/gfwlist +server=/wasmer.io/127.0.0.1#5335 +ipset=/wasmer.io/gfwlist +server=/enfamil.com/127.0.0.1#5335 +ipset=/enfamil.com/gfwlist +server=/pejyyah.com/127.0.0.1#5335 +ipset=/pejyyah.com/gfwlist +server=/enfamil.pl/127.0.0.1#5335 +ipset=/enfamil.pl/gfwlist +server=/cy22.tv/127.0.0.1#5335 +ipset=/cy22.tv/gfwlist +server=/ebayexpress.sg/127.0.0.1#5335 +ipset=/ebayexpress.sg/gfwlist +server=/casualhomemadesex.com/127.0.0.1#5335 +ipset=/casualhomemadesex.com/gfwlist +server=/91porn.com/127.0.0.1#5335 +ipset=/91porn.com/gfwlist +server=/ffotolia.com/127.0.0.1#5335 +ipset=/ffotolia.com/gfwlist +server=/gfotolia.com/127.0.0.1#5335 +ipset=/gfotolia.com/gfwlist +server=/bmw-tunisia.com/127.0.0.1#5335 +ipset=/bmw-tunisia.com/gfwlist +server=/alphera.ca/127.0.0.1#5335 +ipset=/alphera.ca/gfwlist +server=/tubinge.com/127.0.0.1#5335 +ipset=/tubinge.com/gfwlist +server=/ibeatsbydre.com/127.0.0.1#5335 +ipset=/ibeatsbydre.com/gfwlist +server=/spotify.design/127.0.0.1#5335 +ipset=/spotify.design/gfwlist +server=/zzcartoon.com/127.0.0.1#5335 +ipset=/zzcartoon.com/gfwlist +server=/ladyboygold.eu/127.0.0.1#5335 +ipset=/ladyboygold.eu/gfwlist +server=/lethalhardcorevr.com/127.0.0.1#5335 +ipset=/lethalhardcorevr.com/gfwlist +server=/retroclassicporn.com/127.0.0.1#5335 +ipset=/retroclassicporn.com/gfwlist +server=/ipadmini.lk/127.0.0.1#5335 +ipset=/ipadmini.lk/gfwlist +server=/9anime.cz/127.0.0.1#5335 +ipset=/9anime.cz/gfwlist +server=/shadowsocks.com/127.0.0.1#5335 +ipset=/shadowsocks.com/gfwlist +server=/chla3.com/127.0.0.1#5335 +ipset=/chla3.com/gfwlist +server=/young-webcam.net/127.0.0.1#5335 +ipset=/young-webcam.net/gfwlist +server=/vilavpn2.xyz/127.0.0.1#5335 +ipset=/vilavpn2.xyz/gfwlist +server=/durexindia.com/127.0.0.1#5335 +ipset=/durexindia.com/gfwlist +server=/protonmail.com/127.0.0.1#5335 +ipset=/protonmail.com/gfwlist +server=/aplestore.com/127.0.0.1#5335 +ipset=/aplestore.com/gfwlist +server=/scholar.google.hn/127.0.0.1#5335 +ipset=/scholar.google.hn/gfwlist +server=/youtube.com.es/127.0.0.1#5335 +ipset=/youtube.com.es/gfwlist +server=/letmejerk.fun/127.0.0.1#5335 +ipset=/letmejerk.fun/gfwlist +server=/movefrees.com/127.0.0.1#5335 +ipset=/movefrees.com/gfwlist +server=/medium.com/127.0.0.1#5335 +ipset=/medium.com/gfwlist +server=/insidemacintosh.com/127.0.0.1#5335 +ipset=/insidemacintosh.com/gfwlist +server=/gslink.us/127.0.0.1#5335 +ipset=/gslink.us/gfwlist +server=/ehwiki.org/127.0.0.1#5335 +ipset=/ehwiki.org/gfwlist +server=/twhentai.com/127.0.0.1#5335 +ipset=/twhentai.com/gfwlist +server=/terapeak.com/127.0.0.1#5335 +ipset=/terapeak.com/gfwlist +server=/fbooktaiwan.com/127.0.0.1#5335 +ipset=/fbooktaiwan.com/gfwlist +server=/bmw.am/127.0.0.1#5335 +ipset=/bmw.am/gfwlist +server=/gisplanning.com/127.0.0.1#5335 +ipset=/gisplanning.com/gfwlist +server=/bmw.com.ni/127.0.0.1#5335 +ipset=/bmw.com.ni/gfwlist +server=/bestlistofporn.com/127.0.0.1#5335 +ipset=/bestlistofporn.com/gfwlist +server=/beatspills.com/127.0.0.1#5335 +ipset=/beatspills.com/gfwlist +server=/volvobuses.ru/127.0.0.1#5335 +ipset=/volvobuses.ru/gfwlist +server=/18p2p.com/127.0.0.1#5335 +ipset=/18p2p.com/gfwlist +server=/pinterest.hu/127.0.0.1#5335 +ipset=/pinterest.hu/gfwlist +server=/hackfacebook.com/127.0.0.1#5335 +ipset=/hackfacebook.com/gfwlist +server=/f6988.com/127.0.0.1#5335 +ipset=/f6988.com/gfwlist +server=/luxuretv.fun/127.0.0.1#5335 +ipset=/luxuretv.fun/gfwlist +server=/veet.de/127.0.0.1#5335 +ipset=/veet.de/gfwlist +server=/wordpress.com/127.0.0.1#5335 +ipset=/wordpress.com/gfwlist +server=/bridgestone.com.co/127.0.0.1#5335 +ipset=/bridgestone.com.co/gfwlist +server=/ricefever.com/127.0.0.1#5335 +ipset=/ricefever.com/gfwlist +server=/spotify.com.edgesuite.net/127.0.0.1#5335 +ipset=/spotify.com.edgesuite.net/gfwlist +server=/paypal-optimizer.com/127.0.0.1#5335 +ipset=/paypal-optimizer.com/gfwlist +server=/xvds.tv/127.0.0.1#5335 +ipset=/xvds.tv/gfwlist +server=/soirt4.fun/127.0.0.1#5335 +ipset=/soirt4.fun/gfwlist +server=/jav-subtitles.com/127.0.0.1#5335 +ipset=/jav-subtitles.com/gfwlist +server=/rhodeislandbmw.com/127.0.0.1#5335 +ipset=/rhodeislandbmw.com/gfwlist +server=/videoxxxporn.biz/127.0.0.1#5335 +ipset=/videoxxxporn.biz/gfwlist +server=/xtubezoo.com/127.0.0.1#5335 +ipset=/xtubezoo.com/gfwlist +server=/beatsbydre-headphonesshop.com/127.0.0.1#5335 +ipset=/beatsbydre-headphonesshop.com/gfwlist +server=/beejp.net/127.0.0.1#5335 +ipset=/beejp.net/gfwlist +server=/pornvideobb.com/127.0.0.1#5335 +ipset=/pornvideobb.com/gfwlist +server=/famifun.com.tw/127.0.0.1#5335 +ipset=/famifun.com.tw/gfwlist +server=/beatsbestdeals.com/127.0.0.1#5335 +ipset=/beatsbestdeals.com/gfwlist +server=/24porn.com/127.0.0.1#5335 +ipset=/24porn.com/gfwlist +server=/uguisupapa.net/127.0.0.1#5335 +ipset=/uguisupapa.net/gfwlist +server=/xnxvideos.org/127.0.0.1#5335 +ipset=/xnxvideos.org/gfwlist +server=/bromite.org/127.0.0.1#5335 +ipset=/bromite.org/gfwlist +server=/airitilibrary.com/127.0.0.1#5335 +ipset=/airitilibrary.com/gfwlist +server=/applestore.cc/127.0.0.1#5335 +ipset=/applestore.cc/gfwlist +server=/itunbes.com/127.0.0.1#5335 +ipset=/itunbes.com/gfwlist +server=/btec.co.uk/127.0.0.1#5335 +ipset=/btec.co.uk/gfwlist +server=/intercomassets.com/127.0.0.1#5335 +ipset=/intercomassets.com/gfwlist +server=/rocksdb.org/127.0.0.1#5335 +ipset=/rocksdb.org/gfwlist +server=/foxnewssunday.com/127.0.0.1#5335 +ipset=/foxnewssunday.com/gfwlist +server=/flowtype.org/127.0.0.1#5335 +ipset=/flowtype.org/gfwlist +server=/alivercm.com/127.0.0.1#5335 +ipset=/alivercm.com/gfwlist +server=/clipsex.asia/127.0.0.1#5335 +ipset=/clipsex.asia/gfwlist +server=/futpromos.com/127.0.0.1#5335 +ipset=/futpromos.com/gfwlist +server=/hutpromos.com/127.0.0.1#5335 +ipset=/hutpromos.com/gfwlist +server=/science.org/127.0.0.1#5335 +ipset=/science.org/gfwlist +server=/blogspot.vn/127.0.0.1#5335 +ipset=/blogspot.vn/gfwlist +server=/webkitgtk.org/127.0.0.1#5335 +ipset=/webkitgtk.org/gfwlist +server=/bmw.co.id/127.0.0.1#5335 +ipset=/bmw.co.id/gfwlist +server=/mcrouter.org/127.0.0.1#5335 +ipset=/mcrouter.org/gfwlist +server=/nushemale.com/127.0.0.1#5335 +ipset=/nushemale.com/gfwlist +server=/hdpornvideo.xxx/127.0.0.1#5335 +ipset=/hdpornvideo.xxx/gfwlist +server=/planetsuzy.org/127.0.0.1#5335 +ipset=/planetsuzy.org/gfwlist +server=/avelip.com/127.0.0.1#5335 +ipset=/avelip.com/gfwlist +server=/akamaietpcompromisedcnctest.com/127.0.0.1#5335 +ipset=/akamaietpcompromisedcnctest.com/gfwlist +server=/falundafa.org.tw/127.0.0.1#5335 +ipset=/falundafa.org.tw/gfwlist +server=/darkcategories.com/127.0.0.1#5335 +ipset=/darkcategories.com/gfwlist +server=/japanesegirlspictures.com/127.0.0.1#5335 +ipset=/japanesegirlspictures.com/gfwlist +server=/hotescortdusseldorf.com/127.0.0.1#5335 +ipset=/hotescortdusseldorf.com/gfwlist +server=/sg1lib.org/127.0.0.1#5335 +ipset=/sg1lib.org/gfwlist +server=/monsterbeatsheadphone.com/127.0.0.1#5335 +ipset=/monsterbeatsheadphone.com/gfwlist +server=/videosporno.life/127.0.0.1#5335 +ipset=/videosporno.life/gfwlist +server=/intel.mk/127.0.0.1#5335 +ipset=/intel.mk/gfwlist +server=/paypalsurvey.com/127.0.0.1#5335 +ipset=/paypalsurvey.com/gfwlist +server=/bmw-calgary.ca/127.0.0.1#5335 +ipset=/bmw-calgary.ca/gfwlist +server=/foxmediacloud.com/127.0.0.1#5335 +ipset=/foxmediacloud.com/gfwlist +server=/cloudflaressl.com/127.0.0.1#5335 +ipset=/cloudflaressl.com/gfwlist +server=/kastatic.org/127.0.0.1#5335 +ipset=/kastatic.org/gfwlist +server=/via0.com/127.0.0.1#5335 +ipset=/via0.com/gfwlist +server=/kindleoasisnews.com/127.0.0.1#5335 +ipset=/kindleoasisnews.com/gfwlist +server=/hulugermany.com/127.0.0.1#5335 +ipset=/hulugermany.com/gfwlist +server=/el-ladies.com/127.0.0.1#5335 +ipset=/el-ladies.com/gfwlist +server=/foxnewsaffiliates.com/127.0.0.1#5335 +ipset=/foxnewsaffiliates.com/gfwlist +server=/beatsdreinau.com/127.0.0.1#5335 +ipset=/beatsdreinau.com/gfwlist +server=/supremacy.com/127.0.0.1#5335 +ipset=/supremacy.com/gfwlist +server=/appleaccount.net/127.0.0.1#5335 +ipset=/appleaccount.net/gfwlist +server=/paypal-support.com/127.0.0.1#5335 +ipset=/paypal-support.com/gfwlist +server=/trithucvn.org/127.0.0.1#5335 +ipset=/trithucvn.org/gfwlist +server=/visanet.net/127.0.0.1#5335 +ipset=/visanet.net/gfwlist +server=/appleid-applemx.com/127.0.0.1#5335 +ipset=/appleid-applemx.com/gfwlist +server=/google.co.id/127.0.0.1#5335 +ipset=/google.co.id/gfwlist +server=/computingreviews.com/127.0.0.1#5335 +ipset=/computingreviews.com/gfwlist +server=/nejm.org/127.0.0.1#5335 +ipset=/nejm.org/gfwlist +server=/qprize.com/127.0.0.1#5335 +ipset=/qprize.com/gfwlist +server=/huluhuluhuluhulu10.work/127.0.0.1#5335 +ipset=/huluhuluhuluhulu10.work/gfwlist +server=/mostpopularpornsites.com/127.0.0.1#5335 +ipset=/mostpopularpornsites.com/gfwlist +server=/directvmurfreesborotn.com/127.0.0.1#5335 +ipset=/directvmurfreesborotn.com/gfwlist +server=/xbox.eu/127.0.0.1#5335 +ipset=/xbox.eu/gfwlist +server=/18h.mm-cg.com/127.0.0.1#5335 +ipset=/18h.mm-cg.com/gfwlist +server=/porncrash.com/127.0.0.1#5335 +ipset=/porncrash.com/gfwlist +server=/foxsports.com/127.0.0.1#5335 +ipset=/foxsports.com/gfwlist +server=/advertisercommunity.com/127.0.0.1#5335 +ipset=/advertisercommunity.com/gfwlist +server=/bestporngames.com/127.0.0.1#5335 +ipset=/bestporngames.com/gfwlist +server=/3movs.xyz/127.0.0.1#5335 +ipset=/3movs.xyz/gfwlist +server=/travelex.fr/127.0.0.1#5335 +ipset=/travelex.fr/gfwlist +server=/facboox.com/127.0.0.1#5335 +ipset=/facboox.com/gfwlist +server=/newsexxxx.com/127.0.0.1#5335 +ipset=/newsexxxx.com/gfwlist +server=/lysol.co.cr/127.0.0.1#5335 +ipset=/lysol.co.cr/gfwlist +server=/unity.com/127.0.0.1#5335 +ipset=/unity.com/gfwlist +server=/hentai2012.com/127.0.0.1#5335 +ipset=/hentai2012.com/gfwlist +server=/vkmessenger.com/127.0.0.1#5335 +ipset=/vkmessenger.com/gfwlist +server=/nettyinternet.com/127.0.0.1#5335 +ipset=/nettyinternet.com/gfwlist +server=/youtube.de/127.0.0.1#5335 +ipset=/youtube.de/gfwlist +server=/amateurxx.org/127.0.0.1#5335 +ipset=/amateurxx.org/gfwlist +server=/guardianapis.com/127.0.0.1#5335 +ipset=/guardianapis.com/gfwlist +server=/veet.co.in/127.0.0.1#5335 +ipset=/veet.co.in/gfwlist +server=/harperacademic.com/127.0.0.1#5335 +ipset=/harperacademic.com/gfwlist +server=/keepmovingwithmovefree.com/127.0.0.1#5335 +ipset=/keepmovingwithmovefree.com/gfwlist +server=/bridgestone.com/127.0.0.1#5335 +ipset=/bridgestone.com/gfwlist +server=/vk-portal.net/127.0.0.1#5335 +ipset=/vk-portal.net/gfwlist +server=/webobjects.com/127.0.0.1#5335 +ipset=/webobjects.com/gfwlist +server=/nikestore.com/127.0.0.1#5335 +ipset=/nikestore.com/gfwlist +server=/ipfs.best-practice.se/127.0.0.1#5335 +ipset=/ipfs.best-practice.se/gfwlist +server=/pse.is/127.0.0.1#5335 +ipset=/pse.is/gfwlist +server=/volvobuses.it/127.0.0.1#5335 +ipset=/volvobuses.it/gfwlist +server=/ganjing.com/127.0.0.1#5335 +ipset=/ganjing.com/gfwlist +server=/crazy-amateurs.com/127.0.0.1#5335 +ipset=/crazy-amateurs.com/gfwlist +server=/youtube.co.tz/127.0.0.1#5335 +ipset=/youtube.co.tz/gfwlist +server=/fullhdxxx.com/127.0.0.1#5335 +ipset=/fullhdxxx.com/gfwlist +server=/paypal.so/127.0.0.1#5335 +ipset=/paypal.so/gfwlist +server=/aiv-cdn.net/127.0.0.1#5335 +ipset=/aiv-cdn.net/gfwlist +server=/pinterest.com/127.0.0.1#5335 +ipset=/pinterest.com/gfwlist +server=/mktdns.com/127.0.0.1#5335 +ipset=/mktdns.com/gfwlist +server=/api.ai/127.0.0.1#5335 +ipset=/api.ai/gfwlist +server=/iafd.com/127.0.0.1#5335 +ipset=/iafd.com/gfwlist +server=/videoleak.me/127.0.0.1#5335 +ipset=/videoleak.me/gfwlist +server=/meadjohnson.com.tw/127.0.0.1#5335 +ipset=/meadjohnson.com.tw/gfwlist +server=/googleearth.com/127.0.0.1#5335 +ipset=/googleearth.com/gfwlist +server=/celebsporno.com/127.0.0.1#5335 +ipset=/celebsporno.com/gfwlist +server=/megaphone.fm/127.0.0.1#5335 +ipset=/megaphone.fm/gfwlist +server=/xh-porn.com/127.0.0.1#5335 +ipset=/xh-porn.com/gfwlist +server=/sextreffen-portale.com/127.0.0.1#5335 +ipset=/sextreffen-portale.com/gfwlist +server=/hypodermicinjectiononline.com/127.0.0.1#5335 +ipset=/hypodermicinjectiononline.com/gfwlist +server=/akastream.net/127.0.0.1#5335 +ipset=/akastream.net/gfwlist +server=/appletvapp.apple/127.0.0.1#5335 +ipset=/appletvapp.apple/gfwlist +server=/clarivate.com/127.0.0.1#5335 +ipset=/clarivate.com/gfwlist +server=/blogspot.com.ee/127.0.0.1#5335 +ipset=/blogspot.com.ee/gfwlist +server=/pwabuilder.com/127.0.0.1#5335 +ipset=/pwabuilder.com/gfwlist +server=/rushporn.online/127.0.0.1#5335 +ipset=/rushporn.online/gfwlist +server=/hanzhen.xmulib.org/127.0.0.1#5335 +ipset=/hanzhen.xmulib.org/gfwlist +server=/centrino.net/127.0.0.1#5335 +ipset=/centrino.net/gfwlist +server=/facebooksignup.net/127.0.0.1#5335 +ipset=/facebooksignup.net/gfwlist +server=/vfsco.com.tr/127.0.0.1#5335 +ipset=/vfsco.com.tr/gfwlist +server=/milfs-gone-wild.com/127.0.0.1#5335 +ipset=/milfs-gone-wild.com/gfwlist +server=/chillingo.com/127.0.0.1#5335 +ipset=/chillingo.com/gfwlist +server=/pornvidhd.club/127.0.0.1#5335 +ipset=/pornvidhd.club/gfwlist +server=/hentaicovid.com/127.0.0.1#5335 +ipset=/hentaicovid.com/gfwlist +server=/adidas.se/127.0.0.1#5335 +ipset=/adidas.se/gfwlist +server=/vfsco.co.za/127.0.0.1#5335 +ipset=/vfsco.co.za/gfwlist +server=/artnudegalleries.com/127.0.0.1#5335 +ipset=/artnudegalleries.com/gfwlist +server=/sextubexxl.com/127.0.0.1#5335 +ipset=/sextubexxl.com/gfwlist +server=/redxxx.cc/127.0.0.1#5335 +ipset=/redxxx.cc/gfwlist +server=/arabxn.com/127.0.0.1#5335 +ipset=/arabxn.com/gfwlist +server=/camvideos.tv/127.0.0.1#5335 +ipset=/camvideos.tv/gfwlist +server=/herokuapp.com/127.0.0.1#5335 +ipset=/herokuapp.com/gfwlist +server=/beatsmusic.com/127.0.0.1#5335 +ipset=/beatsmusic.com/gfwlist +server=/youtube.jp/127.0.0.1#5335 +ipset=/youtube.jp/gfwlist +server=/scathd.com/127.0.0.1#5335 +ipset=/scathd.com/gfwlist +server=/sextoystop.com/127.0.0.1#5335 +ipset=/sextoystop.com/gfwlist +server=/camstagestudio.com/127.0.0.1#5335 +ipset=/camstagestudio.com/gfwlist +server=/ccstatic.org/127.0.0.1#5335 +ipset=/ccstatic.org/gfwlist +server=/gettyimages.fr/127.0.0.1#5335 +ipset=/gettyimages.fr/gfwlist +server=/fury.blog/127.0.0.1#5335 +ipset=/fury.blog/gfwlist +server=/maileoch.com/127.0.0.1#5335 +ipset=/maileoch.com/gfwlist +server=/nextwork.com.hk/127.0.0.1#5335 +ipset=/nextwork.com.hk/gfwlist +server=/1bigclub.com/127.0.0.1#5335 +ipset=/1bigclub.com/gfwlist +server=/bmw.by/127.0.0.1#5335 +ipset=/bmw.by/gfwlist +server=/mitpressjournals.org/127.0.0.1#5335 +ipset=/mitpressjournals.org/gfwlist +server=/gobeatsye.com/127.0.0.1#5335 +ipset=/gobeatsye.com/gfwlist +server=/xn--d1acpjx3f.xn--p1ai/127.0.0.1#5335 +ipset=/xn--d1acpjx3f.xn--p1ai/gfwlist +server=/lcgirls.com/127.0.0.1#5335 +ipset=/lcgirls.com/gfwlist +server=/spizoo.com/127.0.0.1#5335 +ipset=/spizoo.com/gfwlist +server=/pricelessafrica.com/127.0.0.1#5335 +ipset=/pricelessafrica.com/gfwlist +server=/fox42kptm.com/127.0.0.1#5335 +ipset=/fox42kptm.com/gfwlist +server=/xhot.pro/127.0.0.1#5335 +ipset=/xhot.pro/gfwlist +server=/html5rocks.com/127.0.0.1#5335 +ipset=/html5rocks.com/gfwlist +server=/ieee-aess.org/127.0.0.1#5335 +ipset=/ieee-aess.org/gfwlist +server=/zoo-hardcore.com/127.0.0.1#5335 +ipset=/zoo-hardcore.com/gfwlist +server=/pictocum.com/127.0.0.1#5335 +ipset=/pictocum.com/gfwlist +server=/zukunftswerkstatt.de/127.0.0.1#5335 +ipset=/zukunftswerkstatt.de/gfwlist +server=/mangahasu.se/127.0.0.1#5335 +ipset=/mangahasu.se/gfwlist +server=/fox10news.com/127.0.0.1#5335 +ipset=/fox10news.com/gfwlist +server=/intel.co.kr/127.0.0.1#5335 +ipset=/intel.co.kr/gfwlist +server=/seematureporn.com/127.0.0.1#5335 +ipset=/seematureporn.com/gfwlist +server=/vfsco.be/127.0.0.1#5335 +ipset=/vfsco.be/gfwlist +server=/atnext.com/127.0.0.1#5335 +ipset=/atnext.com/gfwlist +server=/zooyouporn.com/127.0.0.1#5335 +ipset=/zooyouporn.com/gfwlist +server=/damnhotz.com/127.0.0.1#5335 +ipset=/damnhotz.com/gfwlist +server=/asmhentai.com/127.0.0.1#5335 +ipset=/asmhentai.com/gfwlist +server=/fairmarket.com/127.0.0.1#5335 +ipset=/fairmarket.com/gfwlist +server=/scandalplanet.com/127.0.0.1#5335 +ipset=/scandalplanet.com/gfwlist +server=/chocolatey.org/127.0.0.1#5335 +ipset=/chocolatey.org/gfwlist +server=/iceporncasting.com/127.0.0.1#5335 +ipset=/iceporncasting.com/gfwlist +server=/imperial.insendi.com/127.0.0.1#5335 +ipset=/imperial.insendi.com/gfwlist +server=/illusnoi.com/127.0.0.1#5335 +ipset=/illusnoi.com/gfwlist +server=/intellij.com/127.0.0.1#5335 +ipset=/intellij.com/gfwlist +server=/wxoyt.com/127.0.0.1#5335 +ipset=/wxoyt.com/gfwlist +server=/shopeemobile.com/127.0.0.1#5335 +ipset=/shopeemobile.com/gfwlist +server=/mini-connected.com/127.0.0.1#5335 +ipset=/mini-connected.com/gfwlist +server=/pornfoolery.com/127.0.0.1#5335 +ipset=/pornfoolery.com/gfwlist +server=/wowgirls.com/127.0.0.1#5335 +ipset=/wowgirls.com/gfwlist +server=/polygon.com/127.0.0.1#5335 +ipset=/polygon.com/gfwlist +server=/sexbombo.com/127.0.0.1#5335 +ipset=/sexbombo.com/gfwlist +server=/intellij.net/127.0.0.1#5335 +ipset=/intellij.net/gfwlist +server=/sankei-kaihatsu.co.jp/127.0.0.1#5335 +ipset=/sankei-kaihatsu.co.jp/gfwlist +server=/truyen-hentai.com/127.0.0.1#5335 +ipset=/truyen-hentai.com/gfwlist +server=/minisexdoll.com/127.0.0.1#5335 +ipset=/minisexdoll.com/gfwlist +server=/yahoo.nl/127.0.0.1#5335 +ipset=/yahoo.nl/gfwlist +server=/telex.cc/127.0.0.1#5335 +ipset=/telex.cc/gfwlist +server=/volvopenta.com.br/127.0.0.1#5335 +ipset=/volvopenta.com.br/gfwlist +server=/golosameriki.com/127.0.0.1#5335 +ipset=/golosameriki.com/gfwlist +server=/videosmadeathome.com/127.0.0.1#5335 +ipset=/videosmadeathome.com/gfwlist +server=/chemnetbase.com/127.0.0.1#5335 +ipset=/chemnetbase.com/gfwlist +server=/facebookgroups.com/127.0.0.1#5335 +ipset=/facebookgroups.com/gfwlist +server=/akamaiphillipines.com/127.0.0.1#5335 +ipset=/akamaiphillipines.com/gfwlist +server=/thefacebook.net/127.0.0.1#5335 +ipset=/thefacebook.net/gfwlist +server=/cozydrdrebeats.com/127.0.0.1#5335 +ipset=/cozydrdrebeats.com/gfwlist +server=/onlineinstagram.com/127.0.0.1#5335 +ipset=/onlineinstagram.com/gfwlist +server=/velostrata.com/127.0.0.1#5335 +ipset=/velostrata.com/gfwlist +server=/ebay.pk/127.0.0.1#5335 +ipset=/ebay.pk/gfwlist +server=/hkcnews.com/127.0.0.1#5335 +ipset=/hkcnews.com/gfwlist +server=/yahoo.co.in/127.0.0.1#5335 +ipset=/yahoo.co.in/gfwlist +server=/anallivecams.com/127.0.0.1#5335 +ipset=/anallivecams.com/gfwlist +server=/kenyaraha.net/127.0.0.1#5335 +ipset=/kenyaraha.net/gfwlist +server=/bondagesm.xyz/127.0.0.1#5335 +ipset=/bondagesm.xyz/gfwlist +server=/openstreetmap.net/127.0.0.1#5335 +ipset=/openstreetmap.net/gfwlist +server=/scholar.google.at/127.0.0.1#5335 +ipset=/scholar.google.at/gfwlist +server=/llnwi.net/127.0.0.1#5335 +ipset=/llnwi.net/gfwlist +server=/vxnbbrs.xyz/127.0.0.1#5335 +ipset=/vxnbbrs.xyz/gfwlist +server=/githubhackathon.com/127.0.0.1#5335 +ipset=/githubhackathon.com/gfwlist +server=/beatsbydreuk.com/127.0.0.1#5335 +ipset=/beatsbydreuk.com/gfwlist +server=/hkgolden.media/127.0.0.1#5335 +ipset=/hkgolden.media/gfwlist +server=/erome.com/127.0.0.1#5335 +ipset=/erome.com/gfwlist +server=/realclearhistory.com/127.0.0.1#5335 +ipset=/realclearhistory.com/gfwlist +server=/ccdc.cam.ac.uk/127.0.0.1#5335 +ipset=/ccdc.cam.ac.uk/gfwlist +server=/wildfanny.com/127.0.0.1#5335 +ipset=/wildfanny.com/gfwlist +server=/duckduckgo.nl/127.0.0.1#5335 +ipset=/duckduckgo.nl/gfwlist +server=/furrypornvideos.com/127.0.0.1#5335 +ipset=/furrypornvideos.com/gfwlist +server=/xxxvideos247.com/127.0.0.1#5335 +ipset=/xxxvideos247.com/gfwlist +server=/studioluxus.com/127.0.0.1#5335 +ipset=/studioluxus.com/gfwlist +server=/1337x.gd/127.0.0.1#5335 +ipset=/1337x.gd/gfwlist +server=/alphabet.es/127.0.0.1#5335 +ipset=/alphabet.es/gfwlist +server=/sharethis.com/127.0.0.1#5335 +ipset=/sharethis.com/gfwlist +server=/japan-forward.com/127.0.0.1#5335 +ipset=/japan-forward.com/gfwlist +server=/docker.io/127.0.0.1#5335 +ipset=/docker.io/gfwlist +server=/firefox.com/127.0.0.1#5335 +ipset=/firefox.com/gfwlist +server=/tiktokcdn.com/127.0.0.1#5335 +ipset=/tiktokcdn.com/gfwlist +server=/logicoolg.com/127.0.0.1#5335 +ipset=/logicoolg.com/gfwlist +server=/youtube.ch/127.0.0.1#5335 +ipset=/youtube.ch/gfwlist +server=/boysfood.com/127.0.0.1#5335 +ipset=/boysfood.com/gfwlist +server=/babesinporn.com/127.0.0.1#5335 +ipset=/babesinporn.com/gfwlist +server=/ptt2.cc/127.0.0.1#5335 +ipset=/ptt2.cc/gfwlist +server=/applecomputer.co.in/127.0.0.1#5335 +ipset=/applecomputer.co.in/gfwlist +server=/ipodcentre.nl/127.0.0.1#5335 +ipset=/ipodcentre.nl/gfwlist +server=/byteoversea.com/127.0.0.1#5335 +ipset=/byteoversea.com/gfwlist +server=/nikeprice.com/127.0.0.1#5335 +ipset=/nikeprice.com/gfwlist +server=/seemilfporn.com/127.0.0.1#5335 +ipset=/seemilfporn.com/gfwlist +server=/vrpornmania.com/127.0.0.1#5335 +ipset=/vrpornmania.com/gfwlist +server=/jqueryui.com/127.0.0.1#5335 +ipset=/jqueryui.com/gfwlist +server=/planetminecraft.com/127.0.0.1#5335 +ipset=/planetminecraft.com/gfwlist +server=/cableav.tv/127.0.0.1#5335 +ipset=/cableav.tv/gfwlist +server=/disneycareers.com/127.0.0.1#5335 +ipset=/disneycareers.com/gfwlist +server=/dyttapi.com/127.0.0.1#5335 +ipset=/dyttapi.com/gfwlist +server=/redhdtube.xxx/127.0.0.1#5335 +ipset=/redhdtube.xxx/gfwlist +server=/dirtyflix.com/127.0.0.1#5335 +ipset=/dirtyflix.com/gfwlist +server=/vfsco.kr/127.0.0.1#5335 +ipset=/vfsco.kr/gfwlist +server=/apple-watch.com.ru/127.0.0.1#5335 +ipset=/apple-watch.com.ru/gfwlist +server=/thetimes.ie/127.0.0.1#5335 +ipset=/thetimes.ie/gfwlist +server=/paypalgivingfund.org/127.0.0.1#5335 +ipset=/paypalgivingfund.org/gfwlist +server=/volvobuses.com.br/127.0.0.1#5335 +ipset=/volvobuses.com.br/gfwlist +server=/drdreheadphonesusstore.com/127.0.0.1#5335 +ipset=/drdreheadphonesusstore.com/gfwlist +server=/minikelowna.com/127.0.0.1#5335 +ipset=/minikelowna.com/gfwlist +server=/k9vidz.com/127.0.0.1#5335 +ipset=/k9vidz.com/gfwlist +server=/msocdn.com/127.0.0.1#5335 +ipset=/msocdn.com/gfwlist +server=/gettyimages.fi/127.0.0.1#5335 +ipset=/gettyimages.fi/gfwlist +server=/voadeewaradio.com/127.0.0.1#5335 +ipset=/voadeewaradio.com/gfwlist +server=/3dhentaix.com/127.0.0.1#5335 +ipset=/3dhentaix.com/gfwlist +server=/instagramphoto.com/127.0.0.1#5335 +ipset=/instagramphoto.com/gfwlist +server=/zeenite.com/127.0.0.1#5335 +ipset=/zeenite.com/gfwlist +server=/truthordarepics.com/127.0.0.1#5335 +ipset=/truthordarepics.com/gfwlist +server=/hpdrivers.org/127.0.0.1#5335 +ipset=/hpdrivers.org/gfwlist +server=/opengraphprotocol.com/127.0.0.1#5335 +ipset=/opengraphprotocol.com/gfwlist +server=/adult789.futoka.jp/127.0.0.1#5335 +ipset=/adult789.futoka.jp/gfwlist +server=/fimfiction.net/127.0.0.1#5335 +ipset=/fimfiction.net/gfwlist +server=/bmw-carit.de/127.0.0.1#5335 +ipset=/bmw-carit.de/gfwlist +server=/thepornblender.com/127.0.0.1#5335 +ipset=/thepornblender.com/gfwlist +server=/machos.net/127.0.0.1#5335 +ipset=/machos.net/gfwlist +server=/onedrive.live.com/127.0.0.1#5335 +ipset=/onedrive.live.com/gfwlist +server=/att.tv/127.0.0.1#5335 +ipset=/att.tv/gfwlist +server=/pornmaster.fun/127.0.0.1#5335 +ipset=/pornmaster.fun/gfwlist +server=/latticedata.com/127.0.0.1#5335 +ipset=/latticedata.com/gfwlist +server=/imsrbx.xyz/127.0.0.1#5335 +ipset=/imsrbx.xyz/gfwlist +server=/bmwgroup-classic.com/127.0.0.1#5335 +ipset=/bmwgroup-classic.com/gfwlist +server=/vanish.co.uk/127.0.0.1#5335 +ipset=/vanish.co.uk/gfwlist +server=/fox2detroit.com/127.0.0.1#5335 +ipset=/fox2detroit.com/gfwlist +server=/heywire.com/127.0.0.1#5335 +ipset=/heywire.com/gfwlist +server=/intell.com/127.0.0.1#5335 +ipset=/intell.com/gfwlist +server=/91fans.org/127.0.0.1#5335 +ipset=/91fans.org/gfwlist +server=/roborecall.com/127.0.0.1#5335 +ipset=/roborecall.com/gfwlist +server=/collabora.org/127.0.0.1#5335 +ipset=/collabora.org/gfwlist +server=/syosetu.com/127.0.0.1#5335 +ipset=/syosetu.com/gfwlist +server=/hxcsxs.pro/127.0.0.1#5335 +ipset=/hxcsxs.pro/gfwlist +server=/lusthero.com/127.0.0.1#5335 +ipset=/lusthero.com/gfwlist +server=/xxmovz.com/127.0.0.1#5335 +ipset=/xxmovz.com/gfwlist +server=/ipadair.jp/127.0.0.1#5335 +ipset=/ipadair.jp/gfwlist +server=/ams.org/127.0.0.1#5335 +ipset=/ams.org/gfwlist +server=/disney.bg/127.0.0.1#5335 +ipset=/disney.bg/gfwlist +server=/bmw.at/127.0.0.1#5335 +ipset=/bmw.at/gfwlist +server=/ahentaitv.com/127.0.0.1#5335 +ipset=/ahentaitv.com/gfwlist +server=/drebeats-monster.com/127.0.0.1#5335 +ipset=/drebeats-monster.com/gfwlist +server=/canon.ca/127.0.0.1#5335 +ipset=/canon.ca/gfwlist +server=/neowin.net/127.0.0.1#5335 +ipset=/neowin.net/gfwlist +server=/wholefoods.com/127.0.0.1#5335 +ipset=/wholefoods.com/gfwlist +server=/now.com.hk/127.0.0.1#5335 +ipset=/now.com.hk/gfwlist +server=/mini.com.ec/127.0.0.1#5335 +ipset=/mini.com.ec/gfwlist +server=/mypornads.com/127.0.0.1#5335 +ipset=/mypornads.com/gfwlist +server=/xoxoteiras.com/127.0.0.1#5335 +ipset=/xoxoteiras.com/gfwlist +server=/midatlanticbmwmotorcycles.com/127.0.0.1#5335 +ipset=/midatlanticbmwmotorcycles.com/gfwlist +server=/imgbb.com/127.0.0.1#5335 +ipset=/imgbb.com/gfwlist +server=/1drv.com/127.0.0.1#5335 +ipset=/1drv.com/gfwlist +server=/nikedawn.com/127.0.0.1#5335 +ipset=/nikedawn.com/gfwlist +server=/kiji.ca/127.0.0.1#5335 +ipset=/kiji.ca/gfwlist +server=/bbc.co.uk/127.0.0.1#5335 +ipset=/bbc.co.uk/gfwlist +server=/ospray.org/127.0.0.1#5335 +ipset=/ospray.org/gfwlist +server=/universalstudioshollywood.com/127.0.0.1#5335 +ipset=/universalstudioshollywood.com/gfwlist +server=/pornhd8k.net/127.0.0.1#5335 +ipset=/pornhd8k.net/gfwlist +server=/mkt.com/127.0.0.1#5335 +ipset=/mkt.com/gfwlist +server=/seselah.com/127.0.0.1#5335 +ipset=/seselah.com/gfwlist +server=/rferl.org/127.0.0.1#5335 +ipset=/rferl.org/gfwlist +server=/boulx.com/127.0.0.1#5335 +ipset=/boulx.com/gfwlist +server=/google.com.tj/127.0.0.1#5335 +ipset=/google.com.tj/gfwlist +server=/yandex.sx/127.0.0.1#5335 +ipset=/yandex.sx/gfwlist +server=/xxxccc4.com/127.0.0.1#5335 +ipset=/xxxccc4.com/gfwlist +server=/x.company/127.0.0.1#5335 +ipset=/x.company/gfwlist +server=/itnel.com/127.0.0.1#5335 +ipset=/itnel.com/gfwlist +server=/wrds-www.wharton.upenn.edu/127.0.0.1#5335 +ipset=/wrds-www.wharton.upenn.edu/gfwlist +server=/crazyxxx3dworld.net/127.0.0.1#5335 +ipset=/crazyxxx3dworld.net/gfwlist +server=/voabangla.com/127.0.0.1#5335 +ipset=/voabangla.com/gfwlist +server=/weinvoiceit.com/127.0.0.1#5335 +ipset=/weinvoiceit.com/gfwlist +server=/googlefiber.net/127.0.0.1#5335 +ipset=/googlefiber.net/gfwlist +server=/pornditos.com/127.0.0.1#5335 +ipset=/pornditos.com/gfwlist +server=/yourporngod.com/127.0.0.1#5335 +ipset=/yourporngod.com/gfwlist +server=/pornhits.com/127.0.0.1#5335 +ipset=/pornhits.com/gfwlist +server=/muncloud.dog/127.0.0.1#5335 +ipset=/muncloud.dog/gfwlist +server=/eprintsw.com/127.0.0.1#5335 +ipset=/eprintsw.com/gfwlist +server=/adobegov.com/127.0.0.1#5335 +ipset=/adobegov.com/gfwlist +server=/vmwareviewpoint.com/127.0.0.1#5335 +ipset=/vmwareviewpoint.com/gfwlist +server=/momtube.club/127.0.0.1#5335 +ipset=/momtube.club/gfwlist +server=/barrons-conferences.com/127.0.0.1#5335 +ipset=/barrons-conferences.com/gfwlist +server=/beatsbydrestudio-australia.com/127.0.0.1#5335 +ipset=/beatsbydrestudio-australia.com/gfwlist +server=/foxdcg.com/127.0.0.1#5335 +ipset=/foxdcg.com/gfwlist +server=/canonfoundation.org/127.0.0.1#5335 +ipset=/canonfoundation.org/gfwlist +server=/netpornsex.com/127.0.0.1#5335 +ipset=/netpornsex.com/gfwlist +server=/maturescam.com/127.0.0.1#5335 +ipset=/maturescam.com/gfwlist +server=/b6b33.com/127.0.0.1#5335 +ipset=/b6b33.com/gfwlist +server=/applewatch.tw/127.0.0.1#5335 +ipset=/applewatch.tw/gfwlist +server=/papalah.com/127.0.0.1#5335 +ipset=/papalah.com/gfwlist +server=/facewbook.co/127.0.0.1#5335 +ipset=/facewbook.co/gfwlist +server=/rea.design/127.0.0.1#5335 +ipset=/rea.design/gfwlist +server=/sexyhumorgames.com/127.0.0.1#5335 +ipset=/sexyhumorgames.com/gfwlist +server=/facecbook.org/127.0.0.1#5335 +ipset=/facecbook.org/gfwlist +server=/foxcincy.net/127.0.0.1#5335 +ipset=/foxcincy.net/gfwlist +server=/foxsports.co/127.0.0.1#5335 +ipset=/foxsports.co/gfwlist +server=/bridgestone-asiapacific.com/127.0.0.1#5335 +ipset=/bridgestone-asiapacific.com/gfwlist +server=/xnxxhd.tv/127.0.0.1#5335 +ipset=/xnxxhd.tv/gfwlist +server=/fury.dev/127.0.0.1#5335 +ipset=/fury.dev/gfwlist +server=/blogspot.tw/127.0.0.1#5335 +ipset=/blogspot.tw/gfwlist +server=/cstatic.net/127.0.0.1#5335 +ipset=/cstatic.net/gfwlist +server=/rstatic.net/127.0.0.1#5335 +ipset=/rstatic.net/gfwlist +server=/annamilk.com/127.0.0.1#5335 +ipset=/annamilk.com/gfwlist +server=/itunes.ca/127.0.0.1#5335 +ipset=/itunes.ca/gfwlist +server=/nikeadidas.com/127.0.0.1#5335 +ipset=/nikeadidas.com/gfwlist +server=/huffpostarabi.com/127.0.0.1#5335 +ipset=/huffpostarabi.com/gfwlist +server=/connectionseducation.com/127.0.0.1#5335 +ipset=/connectionseducation.com/gfwlist +server=/notion-static.com/127.0.0.1#5335 +ipset=/notion-static.com/gfwlist +server=/asknudes.com/127.0.0.1#5335 +ipset=/asknudes.com/gfwlist +server=/yandex.aero/127.0.0.1#5335 +ipset=/yandex.aero/gfwlist +server=/freebeacon.com/127.0.0.1#5335 +ipset=/freebeacon.com/gfwlist +server=/google.com.bo/127.0.0.1#5335 +ipset=/google.com.bo/gfwlist +server=/esperanzagomez.org/127.0.0.1#5335 +ipset=/esperanzagomez.org/gfwlist +server=/ibeatsbydre.cc/127.0.0.1#5335 +ipset=/ibeatsbydre.cc/gfwlist +server=/azureedge-test.net/127.0.0.1#5335 +ipset=/azureedge-test.net/gfwlist +server=/disneyiejobs.com/127.0.0.1#5335 +ipset=/disneyiejobs.com/gfwlist +server=/post852.com/127.0.0.1#5335 +ipset=/post852.com/gfwlist +server=/services-apple.net/127.0.0.1#5335 +ipset=/services-apple.net/gfwlist +server=/55dndn.com/127.0.0.1#5335 +ipset=/55dndn.com/gfwlist +server=/beatsdrdrecuffie.net/127.0.0.1#5335 +ipset=/beatsdrdrecuffie.net/gfwlist +server=/fotiolia.com/127.0.0.1#5335 +ipset=/fotiolia.com/gfwlist +server=/sonytc.co.jp/127.0.0.1#5335 +ipset=/sonytc.co.jp/gfwlist +server=/new-akiba.com/127.0.0.1#5335 +ipset=/new-akiba.com/gfwlist +server=/asebay.com/127.0.0.1#5335 +ipset=/asebay.com/gfwlist +server=/sexhdmovs.com/127.0.0.1#5335 +ipset=/sexhdmovs.com/gfwlist +server=/yeyuehuachao13.com/127.0.0.1#5335 +ipset=/yeyuehuachao13.com/gfwlist +server=/intel.ga/127.0.0.1#5335 +ipset=/intel.ga/gfwlist +server=/webex.fr/127.0.0.1#5335 +ipset=/webex.fr/gfwlist +server=/paypal-community.com/127.0.0.1#5335 +ipset=/paypal-community.com/gfwlist +server=/foxsoccerplus.tv/127.0.0.1#5335 +ipset=/foxsoccerplus.tv/gfwlist +server=/foxnews.net/127.0.0.1#5335 +ipset=/foxnews.net/gfwlist +server=/collegejournal.com/127.0.0.1#5335 +ipset=/collegejournal.com/gfwlist +server=/digitalplaygroundnetwork.com/127.0.0.1#5335 +ipset=/digitalplaygroundnetwork.com/gfwlist +server=/adultgamingroom.com/127.0.0.1#5335 +ipset=/adultgamingroom.com/gfwlist +server=/yourpelvicexam.com/127.0.0.1#5335 +ipset=/yourpelvicexam.com/gfwlist +server=/minisokorea.com/127.0.0.1#5335 +ipset=/minisokorea.com/gfwlist +server=/durex.com.ng/127.0.0.1#5335 +ipset=/durex.com.ng/gfwlist +server=/redislabs.com/127.0.0.1#5335 +ipset=/redislabs.com/gfwlist +server=/dettol.com.au/127.0.0.1#5335 +ipset=/dettol.com.au/gfwlist +server=/kingofpics.com/127.0.0.1#5335 +ipset=/kingofpics.com/gfwlist +server=/freebrowser.org/127.0.0.1#5335 +ipset=/freebrowser.org/gfwlist +server=/originalhulu.com/127.0.0.1#5335 +ipset=/originalhulu.com/gfwlist +server=/pornsites.xxx/127.0.0.1#5335 +ipset=/pornsites.xxx/gfwlist +server=/yahoo.cz/127.0.0.1#5335 +ipset=/yahoo.cz/gfwlist +server=/wholefoodsmarket.com/127.0.0.1#5335 +ipset=/wholefoodsmarket.com/gfwlist +server=/youtube.pa/127.0.0.1#5335 +ipset=/youtube.pa/gfwlist +server=/firstpelvicexam.com/127.0.0.1#5335 +ipset=/firstpelvicexam.com/gfwlist +server=/av-channel.com/127.0.0.1#5335 +ipset=/av-channel.com/gfwlist +server=/lfai.foundation/127.0.0.1#5335 +ipset=/lfai.foundation/gfwlist +server=/urchin.com/127.0.0.1#5335 +ipset=/urchin.com/gfwlist +server=/extremetube.com/127.0.0.1#5335 +ipset=/extremetube.com/gfwlist +server=/mommystoytime.com/127.0.0.1#5335 +ipset=/mommystoytime.com/gfwlist +server=/dlmobilegarena-a.akamaihd.net/127.0.0.1#5335 +ipset=/dlmobilegarena-a.akamaihd.net/gfwlist +server=/lmmbtc.com/127.0.0.1#5335 +ipset=/lmmbtc.com/gfwlist +server=/hotindianxxxsex.com/127.0.0.1#5335 +ipset=/hotindianxxxsex.com/gfwlist +server=/shianyuanfang.com/127.0.0.1#5335 +ipset=/shianyuanfang.com/gfwlist +server=/txqzz34r.com/127.0.0.1#5335 +ipset=/txqzz34r.com/gfwlist +server=/vmwareusergroupstore.com/127.0.0.1#5335 +ipset=/vmwareusergroupstore.com/gfwlist +server=/asagaku.com/127.0.0.1#5335 +ipset=/asagaku.com/gfwlist +server=/qumingwz.com/127.0.0.1#5335 +ipset=/qumingwz.com/gfwlist +server=/babyzone.com/127.0.0.1#5335 +ipset=/babyzone.com/gfwlist +server=/girlfriendhomeporn.com/127.0.0.1#5335 +ipset=/girlfriendhomeporn.com/gfwlist +server=/sexlikereal.com/127.0.0.1#5335 +ipset=/sexlikereal.com/gfwlist +server=/ebaytv.org/127.0.0.1#5335 +ipset=/ebaytv.org/gfwlist +server=/newssyndication.com/127.0.0.1#5335 +ipset=/newssyndication.com/gfwlist +server=/bcove.video/127.0.0.1#5335 +ipset=/bcove.video/gfwlist +server=/freudbox.com/127.0.0.1#5335 +ipset=/freudbox.com/gfwlist +server=/xboxstudios.com/127.0.0.1#5335 +ipset=/xboxstudios.com/gfwlist +server=/fastlylabs.com/127.0.0.1#5335 +ipset=/fastlylabs.com/gfwlist +server=/ipod.tw/127.0.0.1#5335 +ipset=/ipod.tw/gfwlist +server=/hp3d.com/127.0.0.1#5335 +ipset=/hp3d.com/gfwlist +server=/scoreland2.com/127.0.0.1#5335 +ipset=/scoreland2.com/gfwlist +server=/ryokoyomiuri.co.jp/127.0.0.1#5335 +ipset=/ryokoyomiuri.co.jp/gfwlist +server=/burningcamel.com/127.0.0.1#5335 +ipset=/burningcamel.com/gfwlist +server=/xxvideos.xxx/127.0.0.1#5335 +ipset=/xxvideos.xxx/gfwlist +server=/twistedlinks.net/127.0.0.1#5335 +ipset=/twistedlinks.net/gfwlist +server=/hentai-archive.com/127.0.0.1#5335 +ipset=/hentai-archive.com/gfwlist +server=/myfoxphilly.com/127.0.0.1#5335 +ipset=/myfoxphilly.com/gfwlist +server=/bmw-motorrad.com.tr/127.0.0.1#5335 +ipset=/bmw-motorrad.com.tr/gfwlist +server=/skunkgirl.cc/127.0.0.1#5335 +ipset=/skunkgirl.cc/gfwlist +server=/facebuok.com/127.0.0.1#5335 +ipset=/facebuok.com/gfwlist +server=/finishinfo.no/127.0.0.1#5335 +ipset=/finishinfo.no/gfwlist +server=/paypal-network.org/127.0.0.1#5335 +ipset=/paypal-network.org/gfwlist +server=/xoomcom.com/127.0.0.1#5335 +ipset=/xoomcom.com/gfwlist +server=/abbywintersfree.com/127.0.0.1#5335 +ipset=/abbywintersfree.com/gfwlist +server=/airwick.pl/127.0.0.1#5335 +ipset=/airwick.pl/gfwlist +server=/dialga.com/127.0.0.1#5335 +ipset=/dialga.com/gfwlist +server=/tanflix.com/127.0.0.1#5335 +ipset=/tanflix.com/gfwlist +server=/nintendo.be/127.0.0.1#5335 +ipset=/nintendo.be/gfwlist +server=/vsmarketplacebadge.apphb.com/127.0.0.1#5335 +ipset=/vsmarketplacebadge.apphb.com/gfwlist +server=/vrpornjack.com/127.0.0.1#5335 +ipset=/vrpornjack.com/gfwlist +server=/fifastreet.com/127.0.0.1#5335 +ipset=/fifastreet.com/gfwlist +server=/tokyomotion.com/127.0.0.1#5335 +ipset=/tokyomotion.com/gfwlist +server=/tvbusa.com/127.0.0.1#5335 +ipset=/tvbusa.com/gfwlist +server=/xlovecam.com/127.0.0.1#5335 +ipset=/xlovecam.com/gfwlist +server=/cloudflare.net/127.0.0.1#5335 +ipset=/cloudflare.net/gfwlist +server=/fljmh.com/127.0.0.1#5335 +ipset=/fljmh.com/gfwlist +server=/m5ir5np1.shop/127.0.0.1#5335 +ipset=/m5ir5np1.shop/gfwlist +server=/cas.org/127.0.0.1#5335 +ipset=/cas.org/gfwlist +server=/starcraft2.com/127.0.0.1#5335 +ipset=/starcraft2.com/gfwlist +server=/eurogirlsescort.com/127.0.0.1#5335 +ipset=/eurogirlsescort.com/gfwlist +server=/4channel.org/127.0.0.1#5335 +ipset=/4channel.org/gfwlist +server=/cylink0122.icu/127.0.0.1#5335 +ipset=/cylink0122.icu/gfwlist +server=/appl-e.com/127.0.0.1#5335 +ipset=/appl-e.com/gfwlist +server=/6parkbbs.com/127.0.0.1#5335 +ipset=/6parkbbs.com/gfwlist +server=/xsrxpwvg.com/127.0.0.1#5335 +ipset=/xsrxpwvg.com/gfwlist +server=/beatsdrdre-solo.com/127.0.0.1#5335 +ipset=/beatsdrdre-solo.com/gfwlist +server=/porn2018.com/127.0.0.1#5335 +ipset=/porn2018.com/gfwlist +server=/ebaycar.com/127.0.0.1#5335 +ipset=/ebaycar.com/gfwlist +server=/neotokyo.supertop-100.com/127.0.0.1#5335 +ipset=/neotokyo.supertop-100.com/gfwlist +server=/ikea.jp/127.0.0.1#5335 +ipset=/ikea.jp/gfwlist +server=/mageconf.com.ua/127.0.0.1#5335 +ipset=/mageconf.com.ua/gfwlist +server=/uporno.xxx/127.0.0.1#5335 +ipset=/uporno.xxx/gfwlist +server=/nxta.org/127.0.0.1#5335 +ipset=/nxta.org/gfwlist +server=/xcafe.com/127.0.0.1#5335 +ipset=/xcafe.com/gfwlist +server=/root-signing.ch/127.0.0.1#5335 +ipset=/root-signing.ch/gfwlist +server=/lovemstudios.com/127.0.0.1#5335 +ipset=/lovemstudios.com/gfwlist +server=/google.ca/127.0.0.1#5335 +ipset=/google.ca/gfwlist +server=/microsoft.dk/127.0.0.1#5335 +ipset=/microsoft.dk/gfwlist +server=/txcloud.net/127.0.0.1#5335 +ipset=/txcloud.net/gfwlist +server=/ieeeday.org/127.0.0.1#5335 +ipset=/ieeeday.org/gfwlist +server=/scholar.google.nl/127.0.0.1#5335 +ipset=/scholar.google.nl/gfwlist +server=/acs.org/127.0.0.1#5335 +ipset=/acs.org/gfwlist +server=/masterwanker.com/127.0.0.1#5335 +ipset=/masterwanker.com/gfwlist +server=/hardsex8.com/127.0.0.1#5335 +ipset=/hardsex8.com/gfwlist +server=/ebay-vacation.com/127.0.0.1#5335 +ipset=/ebay-vacation.com/gfwlist +server=/qporno.xxx/127.0.0.1#5335 +ipset=/qporno.xxx/gfwlist +server=/playstation.com/127.0.0.1#5335 +ipset=/playstation.com/gfwlist +server=/custombeatsbydrebuy.com/127.0.0.1#5335 +ipset=/custombeatsbydrebuy.com/gfwlist +server=/xnxx-xxx.win/127.0.0.1#5335 +ipset=/xnxx-xxx.win/gfwlist +server=/att.com/127.0.0.1#5335 +ipset=/att.com/gfwlist +server=/pricelesspick.com/127.0.0.1#5335 +ipset=/pricelesspick.com/gfwlist +server=/microsoftreactor.org/127.0.0.1#5335 +ipset=/microsoftreactor.org/gfwlist +server=/tube.bz/127.0.0.1#5335 +ipset=/tube.bz/gfwlist +server=/91rb.com/127.0.0.1#5335 +ipset=/91rb.com/gfwlist +server=/cotweet.com/127.0.0.1#5335 +ipset=/cotweet.com/gfwlist +server=/hentainstream.com/127.0.0.1#5335 +ipset=/hentainstream.com/gfwlist +server=/powerofresolve.com/127.0.0.1#5335 +ipset=/powerofresolve.com/gfwlist +server=/bmwbkk.de/127.0.0.1#5335 +ipset=/bmwbkk.de/gfwlist +server=/s-books.com/127.0.0.1#5335 +ipset=/s-books.com/gfwlist +server=/rrtis.com/127.0.0.1#5335 +ipset=/rrtis.com/gfwlist +server=/xn--9trs65b.com/127.0.0.1#5335 +ipset=/xn--9trs65b.com/gfwlist +server=/desktopmovie.org/127.0.0.1#5335 +ipset=/desktopmovie.org/gfwlist +server=/dotfacebook.com/127.0.0.1#5335 +ipset=/dotfacebook.com/gfwlist +server=/mailonline.com/127.0.0.1#5335 +ipset=/mailonline.com/gfwlist +server=/bridgestone.co.jp/127.0.0.1#5335 +ipset=/bridgestone.co.jp/gfwlist +server=/pornohoo.com.mx/127.0.0.1#5335 +ipset=/pornohoo.com.mx/gfwlist +server=/videosamadoresreais.com/127.0.0.1#5335 +ipset=/videosamadoresreais.com/gfwlist +server=/javleak.com/127.0.0.1#5335 +ipset=/javleak.com/gfwlist +server=/protonmail.ch/127.0.0.1#5335 +ipset=/protonmail.ch/gfwlist +server=/netlifystatus.com/127.0.0.1#5335 +ipset=/netlifystatus.com/gfwlist +server=/pornfind.org/127.0.0.1#5335 +ipset=/pornfind.org/gfwlist +server=/mortein.co.nz/127.0.0.1#5335 +ipset=/mortein.co.nz/gfwlist +server=/honkaistarrail.com/127.0.0.1#5335 +ipset=/honkaistarrail.com/gfwlist +server=/volvogrouptruckcenter.nl/127.0.0.1#5335 +ipset=/volvogrouptruckcenter.nl/gfwlist +server=/rarbggo.org/127.0.0.1#5335 +ipset=/rarbggo.org/gfwlist +server=/joylovedolls.com/127.0.0.1#5335 +ipset=/joylovedolls.com/gfwlist +server=/hentaiverse.org/127.0.0.1#5335 +ipset=/hentaiverse.org/gfwlist +server=/javhd.com/127.0.0.1#5335 +ipset=/javhd.com/gfwlist +server=/playpornogames.com/127.0.0.1#5335 +ipset=/playpornogames.com/gfwlist +server=/blender.org/127.0.0.1#5335 +ipset=/blender.org/gfwlist +server=/topbeatsdealer.com/127.0.0.1#5335 +ipset=/topbeatsdealer.com/gfwlist +server=/bmw-adventskalender.com/127.0.0.1#5335 +ipset=/bmw-adventskalender.com/gfwlist +server=/nytstyle.com/127.0.0.1#5335 +ipset=/nytstyle.com/gfwlist +server=/www-bestbuystores.com/127.0.0.1#5335 +ipset=/www-bestbuystores.com/gfwlist +server=/huluitaly.com/127.0.0.1#5335 +ipset=/huluitaly.com/gfwlist +server=/shopdurex.com/127.0.0.1#5335 +ipset=/shopdurex.com/gfwlist +server=/mini.co.cr/127.0.0.1#5335 +ipset=/mini.co.cr/gfwlist +server=/scholar.google.cn/127.0.0.1#5335 +ipset=/scholar.google.cn/gfwlist +server=/bmw-connecteddrive.com.cy/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com.cy/gfwlist +server=/ministcatharines.ca/127.0.0.1#5335 +ipset=/ministcatharines.ca/gfwlist +server=/thisvidscat.net/127.0.0.1#5335 +ipset=/thisvidscat.net/gfwlist +server=/hbogo.com/127.0.0.1#5335 +ipset=/hbogo.com/gfwlist +server=/ateam-oracle.com/127.0.0.1#5335 +ipset=/ateam-oracle.com/gfwlist +server=/foxnewspodcasts.com/127.0.0.1#5335 +ipset=/foxnewspodcasts.com/gfwlist +server=/ciattackers.com/127.0.0.1#5335 +ipset=/ciattackers.com/gfwlist +server=/pvue2.com/127.0.0.1#5335 +ipset=/pvue2.com/gfwlist +server=/vsassets.io/127.0.0.1#5335 +ipset=/vsassets.io/gfwlist +server=/volvotrucks.com.br/127.0.0.1#5335 +ipset=/volvotrucks.com.br/gfwlist +server=/apple-darwin.org/127.0.0.1#5335 +ipset=/apple-darwin.org/gfwlist +server=/venmo.net/127.0.0.1#5335 +ipset=/venmo.net/gfwlist +server=/z676869.com/127.0.0.1#5335 +ipset=/z676869.com/gfwlist +server=/hoolu.com/127.0.0.1#5335 +ipset=/hoolu.com/gfwlist +server=/hotgaylist.com/127.0.0.1#5335 +ipset=/hotgaylist.com/gfwlist +server=/reachporn.com/127.0.0.1#5335 +ipset=/reachporn.com/gfwlist +server=/blogspot.is/127.0.0.1#5335 +ipset=/blogspot.is/gfwlist +server=/orzqwq.com/127.0.0.1#5335 +ipset=/orzqwq.com/gfwlist +server=/femalestars.com/127.0.0.1#5335 +ipset=/femalestars.com/gfwlist +server=/google.co.in/127.0.0.1#5335 +ipset=/google.co.in/gfwlist +server=/brocaproject.com/127.0.0.1#5335 +ipset=/brocaproject.com/gfwlist +server=/strepsils.com.tw/127.0.0.1#5335 +ipset=/strepsils.com.tw/gfwlist +server=/aerogard.com.au/127.0.0.1#5335 +ipset=/aerogard.com.au/gfwlist +server=/airwick.co.in/127.0.0.1#5335 +ipset=/airwick.co.in/gfwlist +server=/applecentre.info/127.0.0.1#5335 +ipset=/applecentre.info/gfwlist +server=/ecpa.fr/127.0.0.1#5335 +ipset=/ecpa.fr/gfwlist +server=/pornoamateurlatino.net/127.0.0.1#5335 +ipset=/pornoamateurlatino.net/gfwlist +server=/vikiporn.com/127.0.0.1#5335 +ipset=/vikiporn.com/gfwlist +server=/facebook-corp.com/127.0.0.1#5335 +ipset=/facebook-corp.com/gfwlist +server=/scorepass.com/127.0.0.1#5335 +ipset=/scorepass.com/gfwlist +server=/javhub.me/127.0.0.1#5335 +ipset=/javhub.me/gfwlist +server=/16885858.com/127.0.0.1#5335 +ipset=/16885858.com/gfwlist +server=/shemaleporn.fun/127.0.0.1#5335 +ipset=/shemaleporn.fun/gfwlist +server=/xbabe.com/127.0.0.1#5335 +ipset=/xbabe.com/gfwlist +server=/xxxporn123.com/127.0.0.1#5335 +ipset=/xxxporn123.com/gfwlist +server=/volvotrucks.in/127.0.0.1#5335 +ipset=/volvotrucks.in/gfwlist +server=/intel.bo/127.0.0.1#5335 +ipset=/intel.bo/gfwlist +server=/sony.com.mx/127.0.0.1#5335 +ipset=/sony.com.mx/gfwlist +server=/hentaihere.com/127.0.0.1#5335 +ipset=/hentaihere.com/gfwlist +server=/beatsdrdrekaufenschweiz.net/127.0.0.1#5335 +ipset=/beatsdrdrekaufenschweiz.net/gfwlist +server=/apple.net/127.0.0.1#5335 +ipset=/apple.net/gfwlist +server=/riotgames.net/127.0.0.1#5335 +ipset=/riotgames.net/gfwlist +server=/tsyum.com/127.0.0.1#5335 +ipset=/tsyum.com/gfwlist +server=/intel.pl/127.0.0.1#5335 +ipset=/intel.pl/gfwlist +server=/ministjohns.ca/127.0.0.1#5335 +ipset=/ministjohns.ca/gfwlist +server=/aboutamazon.es/127.0.0.1#5335 +ipset=/aboutamazon.es/gfwlist +server=/asianpornonly.com/127.0.0.1#5335 +ipset=/asianpornonly.com/gfwlist +server=/entrust.net/127.0.0.1#5335 +ipset=/entrust.net/gfwlist +server=/foxtel.com.au/127.0.0.1#5335 +ipset=/foxtel.com.au/gfwlist +server=/uwpcommunitytoolkit.com/127.0.0.1#5335 +ipset=/uwpcommunitytoolkit.com/gfwlist +server=/ebay.es/127.0.0.1#5335 +ipset=/ebay.es/gfwlist +server=/getfedora.org/127.0.0.1#5335 +ipset=/getfedora.org/gfwlist +server=/pacopacomama.com/127.0.0.1#5335 +ipset=/pacopacomama.com/gfwlist +server=/blizzard.com/127.0.0.1#5335 +ipset=/blizzard.com/gfwlist +server=/foxpoker.com/127.0.0.1#5335 +ipset=/foxpoker.com/gfwlist +server=/30plusgirls.com/127.0.0.1#5335 +ipset=/30plusgirls.com/gfwlist +server=/iphone-zh.com/127.0.0.1#5335 +ipset=/iphone-zh.com/gfwlist +server=/radiotavisupleba.ge/127.0.0.1#5335 +ipset=/radiotavisupleba.ge/gfwlist +server=/facebook30.org/127.0.0.1#5335 +ipset=/facebook30.org/gfwlist +server=/aliveprofiler.com/127.0.0.1#5335 +ipset=/aliveprofiler.com/gfwlist +server=/1jjdg2.vip/127.0.0.1#5335 +ipset=/1jjdg2.vip/gfwlist +server=/minilat.com/127.0.0.1#5335 +ipset=/minilat.com/gfwlist +server=/9anime.to/127.0.0.1#5335 +ipset=/9anime.to/gfwlist +server=/dmmrex.com/127.0.0.1#5335 +ipset=/dmmrex.com/gfwlist +server=/movetv.com/127.0.0.1#5335 +ipset=/movetv.com/gfwlist +server=/apkmirror.com/127.0.0.1#5335 +ipset=/apkmirror.com/gfwlist +server=/aboutamazon.pl/127.0.0.1#5335 +ipset=/aboutamazon.pl/gfwlist +server=/next.hk/127.0.0.1#5335 +ipset=/next.hk/gfwlist +server=/applepay.co.rs/127.0.0.1#5335 +ipset=/applepay.co.rs/gfwlist +server=/madonna-av.com/127.0.0.1#5335 +ipset=/madonna-av.com/gfwlist +server=/firebaseapp.com/127.0.0.1#5335 +ipset=/firebaseapp.com/gfwlist +server=/yourporn.sexy/127.0.0.1#5335 +ipset=/yourporn.sexy/gfwlist +server=/porngem.com/127.0.0.1#5335 +ipset=/porngem.com/gfwlist +server=/gayheaven.org/127.0.0.1#5335 +ipset=/gayheaven.org/gfwlist +server=/bustymerilyn.com/127.0.0.1#5335 +ipset=/bustymerilyn.com/gfwlist +server=/qqgamedesign.com/127.0.0.1#5335 +ipset=/qqgamedesign.com/gfwlist +server=/ooni.org/127.0.0.1#5335 +ipset=/ooni.org/gfwlist +server=/viralporn.com/127.0.0.1#5335 +ipset=/viralporn.com/gfwlist +server=/imperial.ac.uk/127.0.0.1#5335 +ipset=/imperial.ac.uk/gfwlist +server=/huffpost.com/127.0.0.1#5335 +ipset=/huffpost.com/gfwlist +server=/foxtvdvd.com/127.0.0.1#5335 +ipset=/foxtvdvd.com/gfwlist +server=/fbmessenger.com/127.0.0.1#5335 +ipset=/fbmessenger.com/gfwlist +server=/tracking-location.com/127.0.0.1#5335 +ipset=/tracking-location.com/gfwlist +server=/a2z.com/127.0.0.1#5335 +ipset=/a2z.com/gfwlist +server=/thedreadwolfrises.com/127.0.0.1#5335 +ipset=/thedreadwolfrises.com/gfwlist +server=/9news.com.au/127.0.0.1#5335 +ipset=/9news.com.au/gfwlist +server=/getoutline.org/127.0.0.1#5335 +ipset=/getoutline.org/gfwlist +server=/exs8fkw0.xyz/127.0.0.1#5335 +ipset=/exs8fkw0.xyz/gfwlist +server=/xxeronetxx.info/127.0.0.1#5335 +ipset=/xxeronetxx.info/gfwlist +server=/youtube.com.my/127.0.0.1#5335 +ipset=/youtube.com.my/gfwlist +server=/hdgaytube.xxx/127.0.0.1#5335 +ipset=/hdgaytube.xxx/gfwlist +server=/ntdimg.com/127.0.0.1#5335 +ipset=/ntdimg.com/gfwlist +server=/flagrasamadores.net/127.0.0.1#5335 +ipset=/flagrasamadores.net/gfwlist +server=/jizzonline.com/127.0.0.1#5335 +ipset=/jizzonline.com/gfwlist +server=/visa.com.vi/127.0.0.1#5335 +ipset=/visa.com.vi/gfwlist +server=/xvideos-cdn.com/127.0.0.1#5335 +ipset=/xvideos-cdn.com/gfwlist +server=/nikkei.jp/127.0.0.1#5335 +ipset=/nikkei.jp/gfwlist +server=/pickinguppussy.com/127.0.0.1#5335 +ipset=/pickinguppussy.com/gfwlist +server=/burstly.net/127.0.0.1#5335 +ipset=/burstly.net/gfwlist +server=/intelfreepress.com/127.0.0.1#5335 +ipset=/intelfreepress.com/gfwlist +server=/ikea.co.de/127.0.0.1#5335 +ipset=/ikea.co.de/gfwlist +server=/sonypictures.com/127.0.0.1#5335 +ipset=/sonypictures.com/gfwlist +server=/pornojefe.com/127.0.0.1#5335 +ipset=/pornojefe.com/gfwlist +server=/amd.com.cn/127.0.0.1#5335 +ipset=/amd.com.cn/gfwlist +server=/gigaporn.org/127.0.0.1#5335 +ipset=/gigaporn.org/gfwlist +server=/prpops.com/127.0.0.1#5335 +ipset=/prpops.com/gfwlist +server=/itcfonts.com/127.0.0.1#5335 +ipset=/itcfonts.com/gfwlist +server=/sh-xuxingda.com/127.0.0.1#5335 +ipset=/sh-xuxingda.com/gfwlist +server=/public-sex-porn.com/127.0.0.1#5335 +ipset=/public-sex-porn.com/gfwlist +server=/instagram-press.net/127.0.0.1#5335 +ipset=/instagram-press.net/gfwlist +server=/uun78.com/127.0.0.1#5335 +ipset=/uun78.com/gfwlist +server=/bmwgroupclassic.com/127.0.0.1#5335 +ipset=/bmwgroupclassic.com/gfwlist +server=/beatsbydrdre-store.us/127.0.0.1#5335 +ipset=/beatsbydrdre-store.us/gfwlist +server=/seemygf.com/127.0.0.1#5335 +ipset=/seemygf.com/gfwlist +server=/javdisk.com/127.0.0.1#5335 +ipset=/javdisk.com/gfwlist +server=/castro.fm/127.0.0.1#5335 +ipset=/castro.fm/gfwlist +server=/startupjournal.com/127.0.0.1#5335 +ipset=/startupjournal.com/gfwlist +server=/attonlineoffers.com/127.0.0.1#5335 +ipset=/attonlineoffers.com/gfwlist +server=/protondb.com/127.0.0.1#5335 +ipset=/protondb.com/gfwlist +server=/washingtondcbmw.com/127.0.0.1#5335 +ipset=/washingtondcbmw.com/gfwlist +server=/mings.hk/127.0.0.1#5335 +ipset=/mings.hk/gfwlist +server=/mallheadphone.com/127.0.0.1#5335 +ipset=/mallheadphone.com/gfwlist +server=/fantasiasguatemala.com/127.0.0.1#5335 +ipset=/fantasiasguatemala.com/gfwlist +server=/ahtranny.com/127.0.0.1#5335 +ipset=/ahtranny.com/gfwlist +server=/code.org/127.0.0.1#5335 +ipset=/code.org/gfwlist +server=/niketracking.com/127.0.0.1#5335 +ipset=/niketracking.com/gfwlist +server=/xbahis44.com/127.0.0.1#5335 +ipset=/xbahis44.com/gfwlist +server=/paypal-recargacelular.com/127.0.0.1#5335 +ipset=/paypal-recargacelular.com/gfwlist +server=/ciscospark.com/127.0.0.1#5335 +ipset=/ciscospark.com/gfwlist +server=/18commic.com/127.0.0.1#5335 +ipset=/18commic.com/gfwlist +server=/spankingstudio.com/127.0.0.1#5335 +ipset=/spankingstudio.com/gfwlist +server=/facebookook.com/127.0.0.1#5335 +ipset=/facebookook.com/gfwlist +server=/zeebiz.com/127.0.0.1#5335 +ipset=/zeebiz.com/gfwlist +server=/jwpcdn.com/127.0.0.1#5335 +ipset=/jwpcdn.com/gfwlist +server=/vk-cdn.me/127.0.0.1#5335 +ipset=/vk-cdn.me/gfwlist +server=/zopim.com/127.0.0.1#5335 +ipset=/zopim.com/gfwlist +server=/libgen.is/127.0.0.1#5335 +ipset=/libgen.is/gfwlist +server=/omekinteractive.com/127.0.0.1#5335 +ipset=/omekinteractive.com/gfwlist +server=/bestbuy.info/127.0.0.1#5335 +ipset=/bestbuy.info/gfwlist +server=/huluaction.com/127.0.0.1#5335 +ipset=/huluaction.com/gfwlist +server=/blogspot.be/127.0.0.1#5335 +ipset=/blogspot.be/gfwlist +server=/beatsdre4cheap.com/127.0.0.1#5335 +ipset=/beatsdre4cheap.com/gfwlist +server=/hnext.jp/127.0.0.1#5335 +ipset=/hnext.jp/gfwlist +server=/youtu.be/127.0.0.1#5335 +ipset=/youtu.be/gfwlist +server=/fox51tns.net/127.0.0.1#5335 +ipset=/fox51tns.net/gfwlist +server=/annualreviews.org/127.0.0.1#5335 +ipset=/annualreviews.org/gfwlist +server=/p16-tiktokcdn-com.akamaized.net/127.0.0.1#5335 +ipset=/p16-tiktokcdn-com.akamaized.net/gfwlist +server=/minishop.ca/127.0.0.1#5335 +ipset=/minishop.ca/gfwlist +server=/rude.com/127.0.0.1#5335 +ipset=/rude.com/gfwlist +server=/rbrandlibrary.com/127.0.0.1#5335 +ipset=/rbrandlibrary.com/gfwlist +server=/iyalc.com/127.0.0.1#5335 +ipset=/iyalc.com/gfwlist +server=/sankei-tours.com/127.0.0.1#5335 +ipset=/sankei-tours.com/gfwlist +server=/asexdoll.com/127.0.0.1#5335 +ipset=/asexdoll.com/gfwlist +server=/sibreal.org/127.0.0.1#5335 +ipset=/sibreal.org/gfwlist +server=/myebay.com/127.0.0.1#5335 +ipset=/myebay.com/gfwlist +server=/pokemonsunmoon.com/127.0.0.1#5335 +ipset=/pokemonsunmoon.com/gfwlist +server=/unrealengine.com/127.0.0.1#5335 +ipset=/unrealengine.com/gfwlist +server=/sexemulator.com/127.0.0.1#5335 +ipset=/sexemulator.com/gfwlist +server=/git-scm.com/127.0.0.1#5335 +ipset=/git-scm.com/gfwlist +server=/adobexdplatform.com/127.0.0.1#5335 +ipset=/adobexdplatform.com/gfwlist +server=/hbonow.com/127.0.0.1#5335 +ipset=/hbonow.com/gfwlist +server=/bmw-connecteddrive.gr/127.0.0.1#5335 +ipset=/bmw-connecteddrive.gr/gfwlist +server=/emerald.com/127.0.0.1#5335 +ipset=/emerald.com/gfwlist +server=/kristenbjorn.com/127.0.0.1#5335 +ipset=/kristenbjorn.com/gfwlist +server=/pinterest.es/127.0.0.1#5335 +ipset=/pinterest.es/gfwlist +server=/forbesimg.com/127.0.0.1#5335 +ipset=/forbesimg.com/gfwlist +server=/mtt.org/127.0.0.1#5335 +ipset=/mtt.org/gfwlist +server=/bitnamiapp.com/127.0.0.1#5335 +ipset=/bitnamiapp.com/gfwlist +server=/shahvani.com/127.0.0.1#5335 +ipset=/shahvani.com/gfwlist +server=/hkbn.net/127.0.0.1#5335 +ipset=/hkbn.net/gfwlist +server=/sony.com.ni/127.0.0.1#5335 +ipset=/sony.com.ni/gfwlist +server=/yandex.eu/127.0.0.1#5335 +ipset=/yandex.eu/gfwlist +server=/appdynamics.info/127.0.0.1#5335 +ipset=/appdynamics.info/gfwlist +server=/flutterapp.com/127.0.0.1#5335 +ipset=/flutterapp.com/gfwlist +server=/amazon-fashions.com/127.0.0.1#5335 +ipset=/amazon-fashions.com/gfwlist +server=/iphoto.eu/127.0.0.1#5335 +ipset=/iphoto.eu/gfwlist +server=/facebookpmdcenter.com/127.0.0.1#5335 +ipset=/facebookpmdcenter.com/gfwlist +server=/bigcharts.com/127.0.0.1#5335 +ipset=/bigcharts.com/gfwlist +server=/mybeatsbydreuk.com/127.0.0.1#5335 +ipset=/mybeatsbydreuk.com/gfwlist +server=/emome.net/127.0.0.1#5335 +ipset=/emome.net/gfwlist +server=/pornfu.tv/127.0.0.1#5335 +ipset=/pornfu.tv/gfwlist +server=/sexflexible.com/127.0.0.1#5335 +ipset=/sexflexible.com/gfwlist +server=/kopfhorergunstigshop.com/127.0.0.1#5335 +ipset=/kopfhorergunstigshop.com/gfwlist +server=/bestbuyforbusiness.ca/127.0.0.1#5335 +ipset=/bestbuyforbusiness.ca/gfwlist +server=/sexsiam.com/127.0.0.1#5335 +ipset=/sexsiam.com/gfwlist +server=/hpeclipse.com/127.0.0.1#5335 +ipset=/hpeclipse.com/gfwlist +server=/nowe.hk/127.0.0.1#5335 +ipset=/nowe.hk/gfwlist +server=/xxx18teen.net/127.0.0.1#5335 +ipset=/xxx18teen.net/gfwlist +server=/anypornhd.com/127.0.0.1#5335 +ipset=/anypornhd.com/gfwlist +server=/yahoo.cd/127.0.0.1#5335 +ipset=/yahoo.cd/gfwlist +server=/zeetv.co.uk/127.0.0.1#5335 +ipset=/zeetv.co.uk/gfwlist +server=/9cdn.net/127.0.0.1#5335 +ipset=/9cdn.net/gfwlist +server=/nike.com/127.0.0.1#5335 +ipset=/nike.com/gfwlist +server=/like.com/127.0.0.1#5335 +ipset=/like.com/gfwlist +server=/finishinfo.be/127.0.0.1#5335 +ipset=/finishinfo.be/gfwlist +server=/facebvook.com/127.0.0.1#5335 +ipset=/facebvook.com/gfwlist +server=/drbeatsukmart.com/127.0.0.1#5335 +ipset=/drbeatsukmart.com/gfwlist +server=/cygames.co.jp/127.0.0.1#5335 +ipset=/cygames.co.jp/gfwlist +server=/3dsexplay.xyz/127.0.0.1#5335 +ipset=/3dsexplay.xyz/gfwlist +server=/nudedrawer.com/127.0.0.1#5335 +ipset=/nudedrawer.com/gfwlist +server=/definefetish.com/127.0.0.1#5335 +ipset=/definefetish.com/gfwlist +server=/bmw-lao.la/127.0.0.1#5335 +ipset=/bmw-lao.la/gfwlist +server=/highbolt.net/127.0.0.1#5335 +ipset=/highbolt.net/gfwlist +server=/wirelessreach.com/127.0.0.1#5335 +ipset=/wirelessreach.com/gfwlist +server=/ferabook.com/127.0.0.1#5335 +ipset=/ferabook.com/gfwlist +server=/mini-connected.pt/127.0.0.1#5335 +ipset=/mini-connected.pt/gfwlist +server=/mangahome.com/127.0.0.1#5335 +ipset=/mangahome.com/gfwlist +server=/blubrry.com/127.0.0.1#5335 +ipset=/blubrry.com/gfwlist +server=/toomadporn.pro/127.0.0.1#5335 +ipset=/toomadporn.pro/gfwlist +server=/verisign.com.hk/127.0.0.1#5335 +ipset=/verisign.com.hk/gfwlist +server=/uun85.com/127.0.0.1#5335 +ipset=/uun85.com/gfwlist +server=/tacamateurs.com/127.0.0.1#5335 +ipset=/tacamateurs.com/gfwlist +server=/akam.net/127.0.0.1#5335 +ipset=/akam.net/gfwlist +server=/infura.io/127.0.0.1#5335 +ipset=/infura.io/gfwlist +server=/dtsell.com/127.0.0.1#5335 +ipset=/dtsell.com/gfwlist +server=/missav.com/127.0.0.1#5335 +ipset=/missav.com/gfwlist +server=/mcdonalds.ca/127.0.0.1#5335 +ipset=/mcdonalds.ca/gfwlist +server=/atypi.org/127.0.0.1#5335 +ipset=/atypi.org/gfwlist +server=/msn.net/127.0.0.1#5335 +ipset=/msn.net/gfwlist +server=/nsfw.xxx/127.0.0.1#5335 +ipset=/nsfw.xxx/gfwlist +server=/discord.dev/127.0.0.1#5335 +ipset=/discord.dev/gfwlist +server=/kompoz2.com/127.0.0.1#5335 +ipset=/kompoz2.com/gfwlist +server=/pornovideow.com/127.0.0.1#5335 +ipset=/pornovideow.com/gfwlist +server=/sneakerskick.com/127.0.0.1#5335 +ipset=/sneakerskick.com/gfwlist +server=/firstasianpussy.com/127.0.0.1#5335 +ipset=/firstasianpussy.com/gfwlist +server=/intel.ru/127.0.0.1#5335 +ipset=/intel.ru/gfwlist +server=/bmwgroupinfobahn.com/127.0.0.1#5335 +ipset=/bmwgroupinfobahn.com/gfwlist +server=/metacpan.org/127.0.0.1#5335 +ipset=/metacpan.org/gfwlist +server=/hentaipros.com/127.0.0.1#5335 +ipset=/hentaipros.com/gfwlist +server=/real-mature-porn.com/127.0.0.1#5335 +ipset=/real-mature-porn.com/gfwlist +server=/hsex.men/127.0.0.1#5335 +ipset=/hsex.men/gfwlist +server=/stickofjoy.com/127.0.0.1#5335 +ipset=/stickofjoy.com/gfwlist +server=/wsj.jobs/127.0.0.1#5335 +ipset=/wsj.jobs/gfwlist +server=/dx9527.cc/127.0.0.1#5335 +ipset=/dx9527.cc/gfwlist +server=/studywatchbyverily.com/127.0.0.1#5335 +ipset=/studywatchbyverily.com/gfwlist +server=/mastercard.se/127.0.0.1#5335 +ipset=/mastercard.se/gfwlist +server=/photolia.net/127.0.0.1#5335 +ipset=/photolia.net/gfwlist +server=/hot-gayporn.com/127.0.0.1#5335 +ipset=/hot-gayporn.com/gfwlist +server=/flipfap.com/127.0.0.1#5335 +ipset=/flipfap.com/gfwlist +server=/sukebelinks.com/127.0.0.1#5335 +ipset=/sukebelinks.com/gfwlist +server=/vercel.app/127.0.0.1#5335 +ipset=/vercel.app/gfwlist +server=/imilfs.com/127.0.0.1#5335 +ipset=/imilfs.com/gfwlist +server=/bravotube.tv/127.0.0.1#5335 +ipset=/bravotube.tv/gfwlist +server=/neweconomyforum.com/127.0.0.1#5335 +ipset=/neweconomyforum.com/gfwlist +server=/volvotrucks.com.au/127.0.0.1#5335 +ipset=/volvotrucks.com.au/gfwlist +server=/princesscum.com/127.0.0.1#5335 +ipset=/princesscum.com/gfwlist +server=/my20dc.com/127.0.0.1#5335 +ipset=/my20dc.com/gfwlist +server=/xpornplease.com/127.0.0.1#5335 +ipset=/xpornplease.com/gfwlist +server=/applemusic.hamburg/127.0.0.1#5335 +ipset=/applemusic.hamburg/gfwlist +server=/verizonwireless.com/127.0.0.1#5335 +ipset=/verizonwireless.com/gfwlist +server=/qorno.com/127.0.0.1#5335 +ipset=/qorno.com/gfwlist +server=/issquaredown.com/127.0.0.1#5335 +ipset=/issquaredown.com/gfwlist +server=/nvidia.ch/127.0.0.1#5335 +ipset=/nvidia.ch/gfwlist +server=/ipfs.lain.la/127.0.0.1#5335 +ipset=/ipfs.lain.la/gfwlist +server=/googl.com/127.0.0.1#5335 +ipset=/googl.com/gfwlist +server=/beatsbydretoutlet.com/127.0.0.1#5335 +ipset=/beatsbydretoutlet.com/gfwlist +server=/mucinex.com.cn/127.0.0.1#5335 +ipset=/mucinex.com.cn/gfwlist +server=/bestbeats4u.com/127.0.0.1#5335 +ipset=/bestbeats4u.com/gfwlist +server=/intel.fr/127.0.0.1#5335 +ipset=/intel.fr/gfwlist +server=/imonsterbeats.com/127.0.0.1#5335 +ipset=/imonsterbeats.com/gfwlist +server=/swapsmut.com/127.0.0.1#5335 +ipset=/swapsmut.com/gfwlist +server=/gamepedia.com/127.0.0.1#5335 +ipset=/gamepedia.com/gfwlist +server=/youtube.uy/127.0.0.1#5335 +ipset=/youtube.uy/gfwlist +server=/dirtyasiantube.com/127.0.0.1#5335 +ipset=/dirtyasiantube.com/gfwlist +server=/billpoint.com/127.0.0.1#5335 +ipset=/billpoint.com/gfwlist +server=/q13fox.com/127.0.0.1#5335 +ipset=/q13fox.com/gfwlist +server=/bmwmotorcycles.com/127.0.0.1#5335 +ipset=/bmwmotorcycles.com/gfwlist +server=/mickybells.com/127.0.0.1#5335 +ipset=/mickybells.com/gfwlist +server=/fluidpreview.com/127.0.0.1#5335 +ipset=/fluidpreview.com/gfwlist +server=/vercel.com/127.0.0.1#5335 +ipset=/vercel.com/gfwlist +server=/kikdirty.com/127.0.0.1#5335 +ipset=/kikdirty.com/gfwlist +server=/pccwglobal.com/127.0.0.1#5335 +ipset=/pccwglobal.com/gfwlist +server=/nickscipio.com/127.0.0.1#5335 +ipset=/nickscipio.com/gfwlist +server=/carbon.com/127.0.0.1#5335 +ipset=/carbon.com/gfwlist +server=/ieee.org/127.0.0.1#5335 +ipset=/ieee.org/gfwlist +server=/gigantits.com/127.0.0.1#5335 +ipset=/gigantits.com/gfwlist +server=/nhentai.to/127.0.0.1#5335 +ipset=/nhentai.to/gfwlist +server=/nurofen.ru/127.0.0.1#5335 +ipset=/nurofen.ru/gfwlist +server=/facbeok.com/127.0.0.1#5335 +ipset=/facbeok.com/gfwlist +server=/lucahmelayu.club/127.0.0.1#5335 +ipset=/lucahmelayu.club/gfwlist +server=/conquerwithcharacter.com/127.0.0.1#5335 +ipset=/conquerwithcharacter.com/gfwlist +server=/wnoaissulli1.com/127.0.0.1#5335 +ipset=/wnoaissulli1.com/gfwlist +server=/sexnaweb.net/127.0.0.1#5335 +ipset=/sexnaweb.net/gfwlist +server=/blackmonsterterror.com/127.0.0.1#5335 +ipset=/blackmonsterterror.com/gfwlist +server=/porn-images-xxx.com/127.0.0.1#5335 +ipset=/porn-images-xxx.com/gfwlist +server=/intelcloudfinder.com/127.0.0.1#5335 +ipset=/intelcloudfinder.com/gfwlist +server=/xvideosincesto.com/127.0.0.1#5335 +ipset=/xvideosincesto.com/gfwlist +server=/highdefinitionbeatsbydre.com/127.0.0.1#5335 +ipset=/highdefinitionbeatsbydre.com/gfwlist +server=/eroshiko.net/127.0.0.1#5335 +ipset=/eroshiko.net/gfwlist +server=/momo.dm/127.0.0.1#5335 +ipset=/momo.dm/gfwlist +server=/ads.yahoo.com/127.0.0.1#5335 +ipset=/ads.yahoo.com/gfwlist +server=/lolislove.info/127.0.0.1#5335 +ipset=/lolislove.info/gfwlist +server=/facebookappcenter.info/127.0.0.1#5335 +ipset=/facebookappcenter.info/gfwlist +server=/pornguz.com/127.0.0.1#5335 +ipset=/pornguz.com/gfwlist +server=/hentai.tv/127.0.0.1#5335 +ipset=/hentai.tv/gfwlist +server=/javhard.net/127.0.0.1#5335 +ipset=/javhard.net/gfwlist +server=/facebooklikeexchange.com/127.0.0.1#5335 +ipset=/facebooklikeexchange.com/gfwlist +server=/hcaptchastatus.com/127.0.0.1#5335 +ipset=/hcaptchastatus.com/gfwlist +server=/t66y.com/127.0.0.1#5335 +ipset=/t66y.com/gfwlist +server=/mtalk.google.com/127.0.0.1#5335 +ipset=/mtalk.google.com/gfwlist +server=/9hentai.to/127.0.0.1#5335 +ipset=/9hentai.to/gfwlist +server=/duckduckco.de/127.0.0.1#5335 +ipset=/duckduckco.de/gfwlist +server=/xposed.info/127.0.0.1#5335 +ipset=/xposed.info/gfwlist +server=/pearson.com/127.0.0.1#5335 +ipset=/pearson.com/gfwlist +server=/gofundme.com/127.0.0.1#5335 +ipset=/gofundme.com/gfwlist +server=/onlyindianporn.tv/127.0.0.1#5335 +ipset=/onlyindianporn.tv/gfwlist +server=/apple.cm/127.0.0.1#5335 +ipset=/apple.cm/gfwlist +server=/edgemeplease.com/127.0.0.1#5335 +ipset=/edgemeplease.com/gfwlist +server=/githubstatus.com/127.0.0.1#5335 +ipset=/githubstatus.com/gfwlist +server=/v-has.com/127.0.0.1#5335 +ipset=/v-has.com/gfwlist +server=/documentforce.com/127.0.0.1#5335 +ipset=/documentforce.com/gfwlist +server=/ikea.ro/127.0.0.1#5335 +ipset=/ikea.ro/gfwlist +server=/ebay-course.com/127.0.0.1#5335 +ipset=/ebay-course.com/gfwlist +server=/imac-applecomputer.com/127.0.0.1#5335 +ipset=/imac-applecomputer.com/gfwlist +server=/bridgestonecomercial.co.cr/127.0.0.1#5335 +ipset=/bridgestonecomercial.co.cr/gfwlist +server=/ckck.fun/127.0.0.1#5335 +ipset=/ckck.fun/gfwlist +server=/news.net.au/127.0.0.1#5335 +ipset=/news.net.au/gfwlist +server=/playporngames.com/127.0.0.1#5335 +ipset=/playporngames.com/gfwlist +server=/40shopping.com/127.0.0.1#5335 +ipset=/40shopping.com/gfwlist +server=/businessinsider.es/127.0.0.1#5335 +ipset=/businessinsider.es/gfwlist +server=/erotikaweb.hu/127.0.0.1#5335 +ipset=/erotikaweb.hu/gfwlist +server=/marketing-nirvana.com/127.0.0.1#5335 +ipset=/marketing-nirvana.com/gfwlist +server=/dropboxinsiders.com/127.0.0.1#5335 +ipset=/dropboxinsiders.com/gfwlist +server=/slack-edge.com/127.0.0.1#5335 +ipset=/slack-edge.com/gfwlist +server=/cyyeshb.com/127.0.0.1#5335 +ipset=/cyyeshb.com/gfwlist +server=/hp3dmetals.com/127.0.0.1#5335 +ipset=/hp3dmetals.com/gfwlist +server=/buycheapbeatsbydre.com/127.0.0.1#5335 +ipset=/buycheapbeatsbydre.com/gfwlist +server=/voazimbabwe.com/127.0.0.1#5335 +ipset=/voazimbabwe.com/gfwlist +server=/adultblogranking.com/127.0.0.1#5335 +ipset=/adultblogranking.com/gfwlist +server=/visa.com.ng/127.0.0.1#5335 +ipset=/visa.com.ng/gfwlist +server=/theatlantic.com/127.0.0.1#5335 +ipset=/theatlantic.com/gfwlist +server=/qualcomm.com.br/127.0.0.1#5335 +ipset=/qualcomm.com.br/gfwlist +server=/vmware.tt.omtrdc.net/127.0.0.1#5335 +ipset=/vmware.tt.omtrdc.net/gfwlist +server=/3arabporn.com/127.0.0.1#5335 +ipset=/3arabporn.com/gfwlist +server=/pinterest.cl/127.0.0.1#5335 +ipset=/pinterest.cl/gfwlist +server=/litbus-anime.com/127.0.0.1#5335 +ipset=/litbus-anime.com/gfwlist +server=/hoolu.tv/127.0.0.1#5335 +ipset=/hoolu.tv/gfwlist +server=/directvplans.com/127.0.0.1#5335 +ipset=/directvplans.com/gfwlist +server=/bacsitinhyeu.vn/127.0.0.1#5335 +ipset=/bacsitinhyeu.vn/gfwlist +server=/beatsbydreoslo.com/127.0.0.1#5335 +ipset=/beatsbydreoslo.com/gfwlist +server=/visa.cz/127.0.0.1#5335 +ipset=/visa.cz/gfwlist +server=/youtube.co.ae/127.0.0.1#5335 +ipset=/youtube.co.ae/gfwlist +server=/monsterdrebeats-canada.net/127.0.0.1#5335 +ipset=/monsterdrebeats-canada.net/gfwlist +server=/azurecosmosdb.info/127.0.0.1#5335 +ipset=/azurecosmosdb.info/gfwlist +server=/scholar.google.com.tw/127.0.0.1#5335 +ipset=/scholar.google.com.tw/gfwlist +server=/hbogo.co.th/127.0.0.1#5335 +ipset=/hbogo.co.th/gfwlist +server=/rabbitsreviews.com/127.0.0.1#5335 +ipset=/rabbitsreviews.com/gfwlist +server=/jgg18.xyz/127.0.0.1#5335 +ipset=/jgg18.xyz/gfwlist +server=/vk.design/127.0.0.1#5335 +ipset=/vk.design/gfwlist +server=/xn--90wwvt03e.com/127.0.0.1#5335 +ipset=/xn--90wwvt03e.com/gfwlist +server=/thunderbird.net/127.0.0.1#5335 +ipset=/thunderbird.net/gfwlist +server=/tubxporn.xxx/127.0.0.1#5335 +ipset=/tubxporn.xxx/gfwlist +server=/cloudflarebolt.com/127.0.0.1#5335 +ipset=/cloudflarebolt.com/gfwlist +server=/cencoastbmw.com/127.0.0.1#5335 +ipset=/cencoastbmw.com/gfwlist +server=/bdsmcafe.com/127.0.0.1#5335 +ipset=/bdsmcafe.com/gfwlist +server=/pornogratis.vlog.br/127.0.0.1#5335 +ipset=/pornogratis.vlog.br/gfwlist +server=/appdynamics.de/127.0.0.1#5335 +ipset=/appdynamics.de/gfwlist +server=/erlang.org/127.0.0.1#5335 +ipset=/erlang.org/gfwlist +server=/mastercard.om/127.0.0.1#5335 +ipset=/mastercard.om/gfwlist +server=/sonybsc.com/127.0.0.1#5335 +ipset=/sonybsc.com/gfwlist +server=/groups.com/127.0.0.1#5335 +ipset=/groups.com/gfwlist +server=/go141.com/127.0.0.1#5335 +ipset=/go141.com/gfwlist +server=/nikeinc.com/127.0.0.1#5335 +ipset=/nikeinc.com/gfwlist +server=/awsglobalaccelerator.com/127.0.0.1#5335 +ipset=/awsglobalaccelerator.com/gfwlist +server=/playshowtv.com/127.0.0.1#5335 +ipset=/playshowtv.com/gfwlist +server=/24porn.pro/127.0.0.1#5335 +ipset=/24porn.pro/gfwlist +server=/hippyhillscomix.com/127.0.0.1#5335 +ipset=/hippyhillscomix.com/gfwlist +server=/anyshemale.com/127.0.0.1#5335 +ipset=/anyshemale.com/gfwlist +server=/findvrporn.com/127.0.0.1#5335 +ipset=/findvrporn.com/gfwlist +server=/pearsonclinical.es/127.0.0.1#5335 +ipset=/pearsonclinical.es/gfwlist +server=/monsterbeatsale.com/127.0.0.1#5335 +ipset=/monsterbeatsale.com/gfwlist +server=/porn300.online/127.0.0.1#5335 +ipset=/porn300.online/gfwlist +server=/catalinacruz.com/127.0.0.1#5335 +ipset=/catalinacruz.com/gfwlist +server=/faceboonk.com/127.0.0.1#5335 +ipset=/faceboonk.com/gfwlist +server=/asp-cc.com/127.0.0.1#5335 +ipset=/asp-cc.com/gfwlist +server=/twister.net.co/127.0.0.1#5335 +ipset=/twister.net.co/gfwlist +server=/binancezh.ink/127.0.0.1#5335 +ipset=/binancezh.ink/gfwlist +server=/qualcommhalo.com/127.0.0.1#5335 +ipset=/qualcommhalo.com/gfwlist +server=/visaeurope.at/127.0.0.1#5335 +ipset=/visaeurope.at/gfwlist +server=/porntrex.com/127.0.0.1#5335 +ipset=/porntrex.com/gfwlist +server=/hotteenfreecam.com/127.0.0.1#5335 +ipset=/hotteenfreecam.com/gfwlist +server=/flathub.org/127.0.0.1#5335 +ipset=/flathub.org/gfwlist +server=/fulldesisex.com/127.0.0.1#5335 +ipset=/fulldesisex.com/gfwlist +server=/monstersexporn.net/127.0.0.1#5335 +ipset=/monstersexporn.net/gfwlist +server=/gaito.xyz/127.0.0.1#5335 +ipset=/gaito.xyz/gfwlist +server=/hornybitches.org/127.0.0.1#5335 +ipset=/hornybitches.org/gfwlist +server=/misshotgirls.com/127.0.0.1#5335 +ipset=/misshotgirls.com/gfwlist +server=/icloudads.net/127.0.0.1#5335 +ipset=/icloudads.net/gfwlist +server=/bmw.com.ve/127.0.0.1#5335 +ipset=/bmw.com.ve/gfwlist +server=/airwick.com.au/127.0.0.1#5335 +ipset=/airwick.com.au/gfwlist +server=/heavy-r.com/127.0.0.1#5335 +ipset=/heavy-r.com/gfwlist +server=/amazonlumberyard.wang/127.0.0.1#5335 +ipset=/amazonlumberyard.wang/gfwlist +server=/javynow.com/127.0.0.1#5335 +ipset=/javynow.com/gfwlist +server=/vanish.dk/127.0.0.1#5335 +ipset=/vanish.dk/gfwlist +server=/hoyo.link/127.0.0.1#5335 +ipset=/hoyo.link/gfwlist +server=/inclusivegrowthscore.com/127.0.0.1#5335 +ipset=/inclusivegrowthscore.com/gfwlist +server=/speedfantasybid.com/127.0.0.1#5335 +ipset=/speedfantasybid.com/gfwlist +server=/gayasianxxx.com/127.0.0.1#5335 +ipset=/gayasianxxx.com/gfwlist +server=/tumblr.com/127.0.0.1#5335 +ipset=/tumblr.com/gfwlist +server=/dirtypornvids.com/127.0.0.1#5335 +ipset=/dirtypornvids.com/gfwlist +server=/69tubesex.com/127.0.0.1#5335 +ipset=/69tubesex.com/gfwlist +server=/ibm.us/127.0.0.1#5335 +ipset=/ibm.us/gfwlist +server=/fececbook.com/127.0.0.1#5335 +ipset=/fececbook.com/gfwlist +server=/oiobbs.com/127.0.0.1#5335 +ipset=/oiobbs.com/gfwlist +server=/jerkmate.tv/127.0.0.1#5335 +ipset=/jerkmate.tv/gfwlist +server=/disney-studio.net/127.0.0.1#5335 +ipset=/disney-studio.net/gfwlist +server=/shadowsocks.nl/127.0.0.1#5335 +ipset=/shadowsocks.nl/gfwlist +server=/acebooik.com/127.0.0.1#5335 +ipset=/acebooik.com/gfwlist +server=/appla.com/127.0.0.1#5335 +ipset=/appla.com/gfwlist +server=/mcdonaldsparties.com.au/127.0.0.1#5335 +ipset=/mcdonaldsparties.com.au/gfwlist +server=/www.sb/127.0.0.1#5335 +ipset=/www.sb/gfwlist +server=/vixen.com/127.0.0.1#5335 +ipset=/vixen.com/gfwlist +server=/namethatporn.com/127.0.0.1#5335 +ipset=/namethatporn.com/gfwlist +server=/ieee.tv/127.0.0.1#5335 +ipset=/ieee.tv/gfwlist +server=/dettol.ch/127.0.0.1#5335 +ipset=/dettol.ch/gfwlist +server=/sony.si/127.0.0.1#5335 +ipset=/sony.si/gfwlist +server=/beatsbydrehd.net/127.0.0.1#5335 +ipset=/beatsbydrehd.net/gfwlist +server=/famima.vn/127.0.0.1#5335 +ipset=/famima.vn/gfwlist +server=/office365love.com/127.0.0.1#5335 +ipset=/office365love.com/gfwlist +server=/fox5dc.com/127.0.0.1#5335 +ipset=/fox5dc.com/gfwlist +server=/pubmatic.co.jp/127.0.0.1#5335 +ipset=/pubmatic.co.jp/gfwlist +server=/amateur-cougar.com/127.0.0.1#5335 +ipset=/amateur-cougar.com/gfwlist +server=/beatsbydrdredanmark.com/127.0.0.1#5335 +ipset=/beatsbydrdredanmark.com/gfwlist +server=/pornelephant.com/127.0.0.1#5335 +ipset=/pornelephant.com/gfwlist +server=/vodafone.com.au/127.0.0.1#5335 +ipset=/vodafone.com.au/gfwlist +server=/camsoda.com/127.0.0.1#5335 +ipset=/camsoda.com/gfwlist +server=/appdynamics.com/127.0.0.1#5335 +ipset=/appdynamics.com/gfwlist +server=/scaleflex.com/127.0.0.1#5335 +ipset=/scaleflex.com/gfwlist +server=/absolutewhores.com/127.0.0.1#5335 +ipset=/absolutewhores.com/gfwlist +server=/wixipedia.net/127.0.0.1#5335 +ipset=/wixipedia.net/gfwlist +server=/ironna.jp/127.0.0.1#5335 +ipset=/ironna.jp/gfwlist +server=/google.cz/127.0.0.1#5335 +ipset=/google.cz/gfwlist +server=/cheapbeats4sale.net/127.0.0.1#5335 +ipset=/cheapbeats4sale.net/gfwlist +server=/j2objc.org/127.0.0.1#5335 +ipset=/j2objc.org/gfwlist +server=/beatsshop-usa.com/127.0.0.1#5335 +ipset=/beatsshop-usa.com/gfwlist +server=/greenend.org.uk/127.0.0.1#5335 +ipset=/greenend.org.uk/gfwlist +server=/gifnuki.com/127.0.0.1#5335 +ipset=/gifnuki.com/gfwlist +server=/sway.com/127.0.0.1#5335 +ipset=/sway.com/gfwlist +server=/lanasbigboobs.com/127.0.0.1#5335 +ipset=/lanasbigboobs.com/gfwlist +server=/hotpornfile.org/127.0.0.1#5335 +ipset=/hotpornfile.org/gfwlist +server=/bbcfmt.s.llnwi.net/127.0.0.1#5335 +ipset=/bbcfmt.s.llnwi.net/gfwlist +server=/freesexvideos2k.com/127.0.0.1#5335 +ipset=/freesexvideos2k.com/gfwlist +server=/whatboyswant.com/127.0.0.1#5335 +ipset=/whatboyswant.com/gfwlist +server=/fuckvideos.biz/127.0.0.1#5335 +ipset=/fuckvideos.biz/gfwlist +server=/clinical-videos.com/127.0.0.1#5335 +ipset=/clinical-videos.com/gfwlist +server=/kingkongapp.com/127.0.0.1#5335 +ipset=/kingkongapp.com/gfwlist +server=/wsjplus.com/127.0.0.1#5335 +ipset=/wsjplus.com/gfwlist +server=/content-ause1-ur-discovery1.uplynk.com/127.0.0.1#5335 +ipset=/content-ause1-ur-discovery1.uplynk.com/gfwlist +server=/hayabusa.io/127.0.0.1#5335 +ipset=/hayabusa.io/gfwlist +server=/ciscolearningsociety.org/127.0.0.1#5335 +ipset=/ciscolearningsociety.org/gfwlist +server=/yahoo.no/127.0.0.1#5335 +ipset=/yahoo.no/gfwlist +server=/fapsafari.com/127.0.0.1#5335 +ipset=/fapsafari.com/gfwlist +server=/lewdweb.net/127.0.0.1#5335 +ipset=/lewdweb.net/gfwlist +server=/coursera.org/127.0.0.1#5335 +ipset=/coursera.org/gfwlist +server=/cosplayporntube.com/127.0.0.1#5335 +ipset=/cosplayporntube.com/gfwlist +server=/stackoverflow.com/127.0.0.1#5335 +ipset=/stackoverflow.com/gfwlist +server=/tgtube.com/127.0.0.1#5335 +ipset=/tgtube.com/gfwlist +server=/scholar.google.ca/127.0.0.1#5335 +ipset=/scholar.google.ca/gfwlist +server=/volvotrucks.jp/127.0.0.1#5335 +ipset=/volvotrucks.jp/gfwlist +server=/canon.az/127.0.0.1#5335 +ipset=/canon.az/gfwlist +server=/hktshop.com/127.0.0.1#5335 +ipset=/hktshop.com/gfwlist +server=/hentai-vostfr.net/127.0.0.1#5335 +ipset=/hentai-vostfr.net/gfwlist +server=/manhwa24h.com/127.0.0.1#5335 +ipset=/manhwa24h.com/gfwlist +server=/incesto.blog.br/127.0.0.1#5335 +ipset=/incesto.blog.br/gfwlist +server=/ebay.co.uk/127.0.0.1#5335 +ipset=/ebay.co.uk/gfwlist +server=/rule34.xyz/127.0.0.1#5335 +ipset=/rule34.xyz/gfwlist +server=/xzxxporn.com/127.0.0.1#5335 +ipset=/xzxxporn.com/gfwlist +server=/mi9cdn.com/127.0.0.1#5335 +ipset=/mi9cdn.com/gfwlist +server=/orithegame.com/127.0.0.1#5335 +ipset=/orithegame.com/gfwlist +server=/applepaysupplies.berlin/127.0.0.1#5335 +ipset=/applepaysupplies.berlin/gfwlist +server=/sexypornpictures.org/127.0.0.1#5335 +ipset=/sexypornpictures.org/gfwlist +server=/alfera.my/127.0.0.1#5335 +ipset=/alfera.my/gfwlist +server=/microsoftaccountguard.com/127.0.0.1#5335 +ipset=/microsoftaccountguard.com/gfwlist +server=/mom50.com/127.0.0.1#5335 +ipset=/mom50.com/gfwlist +server=/doi.info/127.0.0.1#5335 +ipset=/doi.info/gfwlist +server=/volvotrucks.com.tr/127.0.0.1#5335 +ipset=/volvotrucks.com.tr/gfwlist +server=/sexjobs.it/127.0.0.1#5335 +ipset=/sexjobs.it/gfwlist +server=/ifuckedtheboss.com/127.0.0.1#5335 +ipset=/ifuckedtheboss.com/gfwlist +server=/bigboobswives.com/127.0.0.1#5335 +ipset=/bigboobswives.com/gfwlist +server=/finishinfo.cz/127.0.0.1#5335 +ipset=/finishinfo.cz/gfwlist +server=/oursexgames.com/127.0.0.1#5335 +ipset=/oursexgames.com/gfwlist +server=/uun83.com/127.0.0.1#5335 +ipset=/uun83.com/gfwlist +server=/bigbuckbunny.org/127.0.0.1#5335 +ipset=/bigbuckbunny.org/gfwlist +server=/myfonts.com/127.0.0.1#5335 +ipset=/myfonts.com/gfwlist +server=/fastindianporn.com/127.0.0.1#5335 +ipset=/fastindianporn.com/gfwlist +server=/kindleoasis.com/127.0.0.1#5335 +ipset=/kindleoasis.com/gfwlist +server=/facebook-privacy.com/127.0.0.1#5335 +ipset=/facebook-privacy.com/gfwlist +server=/enemasexfetish.com/127.0.0.1#5335 +ipset=/enemasexfetish.com/gfwlist +server=/canon.gr/127.0.0.1#5335 +ipset=/canon.gr/gfwlist +server=/burstlyrewards.com/127.0.0.1#5335 +ipset=/burstlyrewards.com/gfwlist +server=/applestore.com.ru/127.0.0.1#5335 +ipset=/applestore.com.ru/gfwlist +server=/cloudlatex.io/127.0.0.1#5335 +ipset=/cloudlatex.io/gfwlist +server=/paypal-signin.com/127.0.0.1#5335 +ipset=/paypal-signin.com/gfwlist +server=/topfantasyart.com/127.0.0.1#5335 +ipset=/topfantasyart.com/gfwlist +server=/intelcloudbuilders.com/127.0.0.1#5335 +ipset=/intelcloudbuilders.com/gfwlist +server=/mysims.com/127.0.0.1#5335 +ipset=/mysims.com/gfwlist +server=/foxsports.com.br/127.0.0.1#5335 +ipset=/foxsports.com.br/gfwlist +server=/mcdonalds.it/127.0.0.1#5335 +ipset=/mcdonalds.it/gfwlist +server=/take2games.com/127.0.0.1#5335 +ipset=/take2games.com/gfwlist +server=/water-and-power.com/127.0.0.1#5335 +ipset=/water-and-power.com/gfwlist +server=/mynike.com/127.0.0.1#5335 +ipset=/mynike.com/gfwlist +server=/binance.co/127.0.0.1#5335 +ipset=/binance.co/gfwlist +server=/milftugs.com/127.0.0.1#5335 +ipset=/milftugs.com/gfwlist +server=/youtube.in/127.0.0.1#5335 +ipset=/youtube.in/gfwlist +server=/sabuibo.net/127.0.0.1#5335 +ipset=/sabuibo.net/gfwlist +server=/ikea.fi/127.0.0.1#5335 +ipset=/ikea.fi/gfwlist +server=/picsee.co/127.0.0.1#5335 +ipset=/picsee.co/gfwlist +server=/zettai-ero.com/127.0.0.1#5335 +ipset=/zettai-ero.com/gfwlist +server=/taradinhos.com/127.0.0.1#5335 +ipset=/taradinhos.com/gfwlist +server=/mastercard.gr/127.0.0.1#5335 +ipset=/mastercard.gr/gfwlist +server=/wankz.com/127.0.0.1#5335 +ipset=/wankz.com/gfwlist +server=/voanews.com/127.0.0.1#5335 +ipset=/voanews.com/gfwlist +server=/sohfrance.org/127.0.0.1#5335 +ipset=/sohfrance.org/gfwlist +server=/madthumbs.com/127.0.0.1#5335 +ipset=/madthumbs.com/gfwlist +server=/bookshome.world/127.0.0.1#5335 +ipset=/bookshome.world/gfwlist +server=/bloombergsef.com/127.0.0.1#5335 +ipset=/bloombergsef.com/gfwlist +server=/flirt4free.com/127.0.0.1#5335 +ipset=/flirt4free.com/gfwlist +server=/letmejerk.com/127.0.0.1#5335 +ipset=/letmejerk.com/gfwlist +server=/microsofteca.com/127.0.0.1#5335 +ipset=/microsofteca.com/gfwlist +server=/beatsbydreaustraliasales.com/127.0.0.1#5335 +ipset=/beatsbydreaustraliasales.com/gfwlist +server=/fappenist.com/127.0.0.1#5335 +ipset=/fappenist.com/gfwlist +server=/paypalhere.net/127.0.0.1#5335 +ipset=/paypalhere.net/gfwlist +server=/calgoncarbon-china.com/127.0.0.1#5335 +ipset=/calgoncarbon-china.com/gfwlist +server=/directvgrandslam.com/127.0.0.1#5335 +ipset=/directvgrandslam.com/gfwlist +server=/primevideo.info/127.0.0.1#5335 +ipset=/primevideo.info/gfwlist +server=/javvids.com/127.0.0.1#5335 +ipset=/javvids.com/gfwlist +server=/mirailab.tech/127.0.0.1#5335 +ipset=/mirailab.tech/gfwlist +server=/cerdas.com/127.0.0.1#5335 +ipset=/cerdas.com/gfwlist +server=/mpweekly.com/127.0.0.1#5335 +ipset=/mpweekly.com/gfwlist +server=/erotic-artsites.com/127.0.0.1#5335 +ipset=/erotic-artsites.com/gfwlist +server=/yandex.org/127.0.0.1#5335 +ipset=/yandex.org/gfwlist +server=/userapi.com/127.0.0.1#5335 +ipset=/userapi.com/gfwlist +server=/amateurpornhouse.com/127.0.0.1#5335 +ipset=/amateurpornhouse.com/gfwlist +server=/myradio.hk/127.0.0.1#5335 +ipset=/myradio.hk/gfwlist +server=/pornstripgames.com/127.0.0.1#5335 +ipset=/pornstripgames.com/gfwlist +server=/100beatscheap.com/127.0.0.1#5335 +ipset=/100beatscheap.com/gfwlist +server=/starbucks.com.co/127.0.0.1#5335 +ipset=/starbucks.com.co/gfwlist +server=/msecnd.net/127.0.0.1#5335 +ipset=/msecnd.net/gfwlist +server=/intel.bi/127.0.0.1#5335 +ipset=/intel.bi/gfwlist +server=/vanishstains.com.au/127.0.0.1#5335 +ipset=/vanishstains.com.au/gfwlist +server=/exiporn.com/127.0.0.1#5335 +ipset=/exiporn.com/gfwlist +server=/bmwcustomapparel.com/127.0.0.1#5335 +ipset=/bmwcustomapparel.com/gfwlist +server=/pornhun.xyz/127.0.0.1#5335 +ipset=/pornhun.xyz/gfwlist +server=/pornoxo.com/127.0.0.1#5335 +ipset=/pornoxo.com/gfwlist +server=/fuckteenvids.com/127.0.0.1#5335 +ipset=/fuckteenvids.com/gfwlist +server=/walmart.pharmacy/127.0.0.1#5335 +ipset=/walmart.pharmacy/gfwlist +server=/facerbook.com/127.0.0.1#5335 +ipset=/facerbook.com/gfwlist +server=/kama-nk.ru/127.0.0.1#5335 +ipset=/kama-nk.ru/gfwlist +server=/cashify.com/127.0.0.1#5335 +ipset=/cashify.com/gfwlist +server=/cuckold69.com/127.0.0.1#5335 +ipset=/cuckold69.com/gfwlist +server=/cool-comics.com/127.0.0.1#5335 +ipset=/cool-comics.com/gfwlist +server=/realtype.co.jp/127.0.0.1#5335 +ipset=/realtype.co.jp/gfwlist +server=/karinahart.com/127.0.0.1#5335 +ipset=/karinahart.com/gfwlist +server=/cs.co/127.0.0.1#5335 +ipset=/cs.co/gfwlist +server=/rb.net/127.0.0.1#5335 +ipset=/rb.net/gfwlist +server=/redxxxvideos.com/127.0.0.1#5335 +ipset=/redxxxvideos.com/gfwlist +server=/dettol.cl/127.0.0.1#5335 +ipset=/dettol.cl/gfwlist +server=/xvideosup.com.br/127.0.0.1#5335 +ipset=/xvideosup.com.br/gfwlist +server=/applebk.net/127.0.0.1#5335 +ipset=/applebk.net/gfwlist +server=/flaru.com/127.0.0.1#5335 +ipset=/flaru.com/gfwlist +server=/intel.eg/127.0.0.1#5335 +ipset=/intel.eg/gfwlist +server=/hentaitk.com/127.0.0.1#5335 +ipset=/hentaitk.com/gfwlist +server=/amazonvideo.cc/127.0.0.1#5335 +ipset=/amazonvideo.cc/gfwlist +server=/applecare.hamburg/127.0.0.1#5335 +ipset=/applecare.hamburg/gfwlist +server=/bestbuy-giftcard.info/127.0.0.1#5335 +ipset=/bestbuy-giftcard.info/gfwlist +server=/scholar.google.com.cu/127.0.0.1#5335 +ipset=/scholar.google.com.cu/gfwlist +server=/drdrebeatsale.com/127.0.0.1#5335 +ipset=/drdrebeatsale.com/gfwlist +server=/sexpornpictures.com/127.0.0.1#5335 +ipset=/sexpornpictures.com/gfwlist +server=/bmw-worldfinal.com/127.0.0.1#5335 +ipset=/bmw-worldfinal.com/gfwlist +server=/chyoa.com/127.0.0.1#5335 +ipset=/chyoa.com/gfwlist +server=/townofsins.com/127.0.0.1#5335 +ipset=/townofsins.com/gfwlist +server=/bdsmsexgame.com/127.0.0.1#5335 +ipset=/bdsmsexgame.com/gfwlist +server=/u.nu/127.0.0.1#5335 +ipset=/u.nu/gfwlist +server=/xxx2022.com/127.0.0.1#5335 +ipset=/xxx2022.com/gfwlist +server=/sheshaft.com/127.0.0.1#5335 +ipset=/sheshaft.com/gfwlist +server=/picasaweb.com/127.0.0.1#5335 +ipset=/picasaweb.com/gfwlist +server=/hummingbird.ms/127.0.0.1#5335 +ipset=/hummingbird.ms/gfwlist +server=/jdavsp.pw/127.0.0.1#5335 +ipset=/jdavsp.pw/gfwlist +server=/bvdinfo.com/127.0.0.1#5335 +ipset=/bvdinfo.com/gfwlist +server=/trycuckold.com/127.0.0.1#5335 +ipset=/trycuckold.com/gfwlist +server=/erocurves.com/127.0.0.1#5335 +ipset=/erocurves.com/gfwlist +server=/onlinefucktube.com/127.0.0.1#5335 +ipset=/onlinefucktube.com/gfwlist +server=/9now.com.au/127.0.0.1#5335 +ipset=/9now.com.au/gfwlist +server=/apple.fi/127.0.0.1#5335 +ipset=/apple.fi/gfwlist +server=/moemax.net/127.0.0.1#5335 +ipset=/moemax.net/gfwlist +server=/whatthefox.com/127.0.0.1#5335 +ipset=/whatthefox.com/gfwlist +server=/terragraph.com/127.0.0.1#5335 +ipset=/terragraph.com/gfwlist +server=/facebook.us/127.0.0.1#5335 +ipset=/facebook.us/gfwlist +server=/logitech.biz/127.0.0.1#5335 +ipset=/logitech.biz/gfwlist +server=/messenger.com/127.0.0.1#5335 +ipset=/messenger.com/gfwlist +server=/wifehomeporn.com/127.0.0.1#5335 +ipset=/wifehomeporn.com/gfwlist +server=/disneymagicmoments.gr/127.0.0.1#5335 +ipset=/disneymagicmoments.gr/gfwlist +server=/mini.ie/127.0.0.1#5335 +ipset=/mini.ie/gfwlist +server=/eromangajukujo.com/127.0.0.1#5335 +ipset=/eromangajukujo.com/gfwlist +server=/39group.info/127.0.0.1#5335 +ipset=/39group.info/gfwlist +server=/ero-labs.site/127.0.0.1#5335 +ipset=/ero-labs.site/gfwlist +server=/womenwill.com.br/127.0.0.1#5335 +ipset=/womenwill.com.br/gfwlist +server=/my13la.com/127.0.0.1#5335 +ipset=/my13la.com/gfwlist +server=/quanben-xiaoshuo.com/127.0.0.1#5335 +ipset=/quanben-xiaoshuo.com/gfwlist +server=/applestore.co.hu/127.0.0.1#5335 +ipset=/applestore.co.hu/gfwlist +server=/mastercard.si/127.0.0.1#5335 +ipset=/mastercard.si/gfwlist +server=/ebay.com/127.0.0.1#5335 +ipset=/ebay.com/gfwlist +server=/intelcapital.net/127.0.0.1#5335 +ipset=/intelcapital.net/gfwlist +server=/beatsbydre-outletsale.net/127.0.0.1#5335 +ipset=/beatsbydre-outletsale.net/gfwlist +server=/nikeswim.com/127.0.0.1#5335 +ipset=/nikeswim.com/gfwlist +server=/adobecc.com/127.0.0.1#5335 +ipset=/adobecc.com/gfwlist +server=/businesstoday.com.tw/127.0.0.1#5335 +ipset=/businesstoday.com.tw/gfwlist +server=/newsprestigenetwork.com.au/127.0.0.1#5335 +ipset=/newsprestigenetwork.com.au/gfwlist +server=/foxcharlotte.com/127.0.0.1#5335 +ipset=/foxcharlotte.com/gfwlist +server=/epochtimes-romania.com/127.0.0.1#5335 +ipset=/epochtimes-romania.com/gfwlist +server=/bustydustystash.com/127.0.0.1#5335 +ipset=/bustydustystash.com/gfwlist +server=/acasadasbrasileirinhas.com.br/127.0.0.1#5335 +ipset=/acasadasbrasileirinhas.com.br/gfwlist +server=/lbtube.com/127.0.0.1#5335 +ipset=/lbtube.com/gfwlist +server=/disneymagicmoments.fr/127.0.0.1#5335 +ipset=/disneymagicmoments.fr/gfwlist +server=/nabtravellercard.com.au/127.0.0.1#5335 +ipset=/nabtravellercard.com.au/gfwlist +server=/paypal-center.net/127.0.0.1#5335 +ipset=/paypal-center.net/gfwlist +server=/watchout.tw/127.0.0.1#5335 +ipset=/watchout.tw/gfwlist +server=/banned.video/127.0.0.1#5335 +ipset=/banned.video/gfwlist +server=/sf.net/127.0.0.1#5335 +ipset=/sf.net/gfwlist +server=/popjav.tv/127.0.0.1#5335 +ipset=/popjav.tv/gfwlist +server=/he.net/127.0.0.1#5335 +ipset=/he.net/gfwlist +server=/xx9.app/127.0.0.1#5335 +ipset=/xx9.app/gfwlist +server=/ebay.co.nz/127.0.0.1#5335 +ipset=/ebay.co.nz/gfwlist +server=/spotifycdn.net/127.0.0.1#5335 +ipset=/spotifycdn.net/gfwlist +server=/blogspot.com.co/127.0.0.1#5335 +ipset=/blogspot.com.co/gfwlist +server=/brandproducts1688.com/127.0.0.1#5335 +ipset=/brandproducts1688.com/gfwlist +server=/sextube.desi/127.0.0.1#5335 +ipset=/sextube.desi/gfwlist +server=/shops-disney.com/127.0.0.1#5335 +ipset=/shops-disney.com/gfwlist +server=/instagram-help.com/127.0.0.1#5335 +ipset=/instagram-help.com/gfwlist +server=/justusboys.com/127.0.0.1#5335 +ipset=/justusboys.com/gfwlist +server=/lnstagram-help.com/127.0.0.1#5335 +ipset=/lnstagram-help.com/gfwlist +server=/sexwithhorse.net/127.0.0.1#5335 +ipset=/sexwithhorse.net/gfwlist +server=/instagramm.com/127.0.0.1#5335 +ipset=/instagramm.com/gfwlist +server=/new3dcomics.com/127.0.0.1#5335 +ipset=/new3dcomics.com/gfwlist +server=/xxxbule.com/127.0.0.1#5335 +ipset=/xxxbule.com/gfwlist +server=/skype.com/127.0.0.1#5335 +ipset=/skype.com/gfwlist +server=/visabusinessinsights.com/127.0.0.1#5335 +ipset=/visabusinessinsights.com/gfwlist +server=/sex-douga.jp/127.0.0.1#5335 +ipset=/sex-douga.jp/gfwlist +server=/appstore.ph/127.0.0.1#5335 +ipset=/appstore.ph/gfwlist +server=/nvidia.com.br/127.0.0.1#5335 +ipset=/nvidia.com.br/gfwlist +server=/topless.com.ua/127.0.0.1#5335 +ipset=/topless.com.ua/gfwlist +server=/coinone.co.kr/127.0.0.1#5335 +ipset=/coinone.co.kr/gfwlist +server=/universalorlando.com/127.0.0.1#5335 +ipset=/universalorlando.com/gfwlist +server=/huobi.pro/127.0.0.1#5335 +ipset=/huobi.pro/gfwlist +server=/steamcommunity-a.akamaihd.net/127.0.0.1#5335 +ipset=/steamcommunity-a.akamaihd.net/gfwlist +server=/volvotrucks.no/127.0.0.1#5335 +ipset=/volvotrucks.no/gfwlist +server=/paisapay.info/127.0.0.1#5335 +ipset=/paisapay.info/gfwlist +server=/vfsco.at/127.0.0.1#5335 +ipset=/vfsco.at/gfwlist +server=/hentaifox.tv/127.0.0.1#5335 +ipset=/hentaifox.tv/gfwlist +server=/sleazyneasy.com/127.0.0.1#5335 +ipset=/sleazyneasy.com/gfwlist +server=/sikiswap.com/127.0.0.1#5335 +ipset=/sikiswap.com/gfwlist +server=/magentocommerce.com/127.0.0.1#5335 +ipset=/magentocommerce.com/gfwlist +server=/xamarin.com/127.0.0.1#5335 +ipset=/xamarin.com/gfwlist +server=/ipfs.fleek.co/127.0.0.1#5335 +ipset=/ipfs.fleek.co/gfwlist +server=/dailymail.com.au/127.0.0.1#5335 +ipset=/dailymail.com.au/gfwlist +server=/mini-clubs-international.com/127.0.0.1#5335 +ipset=/mini-clubs-international.com/gfwlist +server=/paofu.cloud/127.0.0.1#5335 +ipset=/paofu.cloud/gfwlist +server=/bwbx.io/127.0.0.1#5335 +ipset=/bwbx.io/gfwlist +server=/japan18tube.com/127.0.0.1#5335 +ipset=/japan18tube.com/gfwlist +server=/qualphone.com/127.0.0.1#5335 +ipset=/qualphone.com/gfwlist +server=/viacbs.com/127.0.0.1#5335 +ipset=/viacbs.com/gfwlist +server=/ebay.com.ec/127.0.0.1#5335 +ipset=/ebay.com.ec/gfwlist +server=/pussymomsex.com/127.0.0.1#5335 +ipset=/pussymomsex.com/gfwlist +server=/skate2.com/127.0.0.1#5335 +ipset=/skate2.com/gfwlist +server=/faceobok.com/127.0.0.1#5335 +ipset=/faceobok.com/gfwlist +server=/thai69.com/127.0.0.1#5335 +ipset=/thai69.com/gfwlist +server=/aka-ai.com/127.0.0.1#5335 +ipset=/aka-ai.com/gfwlist +server=/boobieblog.com/127.0.0.1#5335 +ipset=/boobieblog.com/gfwlist +server=/askfacebook.net/127.0.0.1#5335 +ipset=/askfacebook.net/gfwlist +server=/minie.com/127.0.0.1#5335 +ipset=/minie.com/gfwlist +server=/hpstore-emea.com/127.0.0.1#5335 +ipset=/hpstore-emea.com/gfwlist +server=/mininanaimo.ca/127.0.0.1#5335 +ipset=/mininanaimo.ca/gfwlist +server=/greatergothammini.com/127.0.0.1#5335 +ipset=/greatergothammini.com/gfwlist +server=/facebookpoke.net/127.0.0.1#5335 +ipset=/facebookpoke.net/gfwlist +server=/gaypornhdfree.com/127.0.0.1#5335 +ipset=/gaypornhdfree.com/gfwlist +server=/dynacw.com.hk/127.0.0.1#5335 +ipset=/dynacw.com.hk/gfwlist +server=/ebayfrance.com/127.0.0.1#5335 +ipset=/ebayfrance.com/gfwlist +server=/bmw-motorrad.uy/127.0.0.1#5335 +ipset=/bmw-motorrad.uy/gfwlist +server=/chinese-porn-videos.com/127.0.0.1#5335 +ipset=/chinese-porn-videos.com/gfwlist +server=/geeksquadcares.com/127.0.0.1#5335 +ipset=/geeksquadcares.com/gfwlist +server=/bmwmc.net/127.0.0.1#5335 +ipset=/bmwmc.net/gfwlist +server=/microbit.org/127.0.0.1#5335 +ipset=/microbit.org/gfwlist +server=/ikea.co.om/127.0.0.1#5335 +ipset=/ikea.co.om/gfwlist +server=/hentai.pink/127.0.0.1#5335 +ipset=/hentai.pink/gfwlist +server=/asto.re/127.0.0.1#5335 +ipset=/asto.re/gfwlist +server=/cern.ch/127.0.0.1#5335 +ipset=/cern.ch/gfwlist +server=/beatscollection2014.com/127.0.0.1#5335 +ipset=/beatscollection2014.com/gfwlist +server=/microsoftdiplomados.com/127.0.0.1#5335 +ipset=/microsoftdiplomados.com/gfwlist +server=/mixasiansex.com/127.0.0.1#5335 +ipset=/mixasiansex.com/gfwlist +server=/literatumonline.com/127.0.0.1#5335 +ipset=/literatumonline.com/gfwlist +server=/facebookpaper.com/127.0.0.1#5335 +ipset=/facebookpaper.com/gfwlist +server=/visa.com.tw/127.0.0.1#5335 +ipset=/visa.com.tw/gfwlist +server=/apple.si/127.0.0.1#5335 +ipset=/apple.si/gfwlist +server=/callersbane.com/127.0.0.1#5335 +ipset=/callersbane.com/gfwlist +server=/agu.org/127.0.0.1#5335 +ipset=/agu.org/gfwlist +server=/ferronetwork.com/127.0.0.1#5335 +ipset=/ferronetwork.com/gfwlist +server=/motherless.com/127.0.0.1#5335 +ipset=/motherless.com/gfwlist +server=/paypal-forward.com/127.0.0.1#5335 +ipset=/paypal-forward.com/gfwlist +server=/xn--6eup7j.com/127.0.0.1#5335 +ipset=/xn--6eup7j.com/gfwlist +server=/londonmithraeum.com/127.0.0.1#5335 +ipset=/londonmithraeum.com/gfwlist +server=/dettol.co.id/127.0.0.1#5335 +ipset=/dettol.co.id/gfwlist +server=/doseofporn.com/127.0.0.1#5335 +ipset=/doseofporn.com/gfwlist +server=/paxful.com/127.0.0.1#5335 +ipset=/paxful.com/gfwlist +server=/vfsco.no/127.0.0.1#5335 +ipset=/vfsco.no/gfwlist +server=/lotcrap.com/127.0.0.1#5335 +ipset=/lotcrap.com/gfwlist +server=/digitalpack.com/127.0.0.1#5335 +ipset=/digitalpack.com/gfwlist +server=/bmwgroup-werke.com/127.0.0.1#5335 +ipset=/bmwgroup-werke.com/gfwlist +server=/finish.co.kr/127.0.0.1#5335 +ipset=/finish.co.kr/gfwlist +server=/mrskin.com/127.0.0.1#5335 +ipset=/mrskin.com/gfwlist +server=/comicunivers.com/127.0.0.1#5335 +ipset=/comicunivers.com/gfwlist +server=/haplorrhini.com/127.0.0.1#5335 +ipset=/haplorrhini.com/gfwlist +server=/intellij.org/127.0.0.1#5335 +ipset=/intellij.org/gfwlist +server=/zhaimankan.com/127.0.0.1#5335 +ipset=/zhaimankan.com/gfwlist +server=/youngamateursporn.com/127.0.0.1#5335 +ipset=/youngamateursporn.com/gfwlist +server=/lbfmaddiction.com/127.0.0.1#5335 +ipset=/lbfmaddiction.com/gfwlist +server=/theclub.com.hk/127.0.0.1#5335 +ipset=/theclub.com.hk/gfwlist +server=/google.com.ai/127.0.0.1#5335 +ipset=/google.com.ai/gfwlist +server=/solarcity.com/127.0.0.1#5335 +ipset=/solarcity.com/gfwlist +server=/kslive.tv/127.0.0.1#5335 +ipset=/kslive.tv/gfwlist +server=/pinimg.com/127.0.0.1#5335 +ipset=/pinimg.com/gfwlist +server=/xnxxarabsex.com/127.0.0.1#5335 +ipset=/xnxxarabsex.com/gfwlist +server=/realpornclip.com/127.0.0.1#5335 +ipset=/realpornclip.com/gfwlist +server=/vimeobusiness.com/127.0.0.1#5335 +ipset=/vimeobusiness.com/gfwlist +server=/eroxia.com/127.0.0.1#5335 +ipset=/eroxia.com/gfwlist +server=/sextube.fm/127.0.0.1#5335 +ipset=/sextube.fm/gfwlist +server=/bmwgroup.at/127.0.0.1#5335 +ipset=/bmwgroup.at/gfwlist +server=/bnetproduct-a.akamaihd.net/127.0.0.1#5335 +ipset=/bnetproduct-a.akamaihd.net/gfwlist +server=/12diasderegalosdeitunes.pe/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.pe/gfwlist +server=/ebay.pl/127.0.0.1#5335 +ipset=/ebay.pl/gfwlist +server=/fullsexmovs.com/127.0.0.1#5335 +ipset=/fullsexmovs.com/gfwlist +server=/sss.xxx/127.0.0.1#5335 +ipset=/sss.xxx/gfwlist +server=/quatrowireless.com/127.0.0.1#5335 +ipset=/quatrowireless.com/gfwlist +server=/123-hp.com/127.0.0.1#5335 +ipset=/123-hp.com/gfwlist +server=/hotasianbabes.com/127.0.0.1#5335 +ipset=/hotasianbabes.com/gfwlist +server=/acheter-followers-instagram.com/127.0.0.1#5335 +ipset=/acheter-followers-instagram.com/gfwlist +server=/steampowered.com/127.0.0.1#5335 +ipset=/steampowered.com/gfwlist +server=/cumswappingsis.com/127.0.0.1#5335 +ipset=/cumswappingsis.com/gfwlist +server=/dfp6rglgjqszk.cloudfront.net/127.0.0.1#5335 +ipset=/dfp6rglgjqszk.cloudfront.net/gfwlist +server=/clients1.google.com/127.0.0.1#5335 +ipset=/clients1.google.com/gfwlist +server=/vod-hls-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vod-hls-uk-live.akamaized.net/gfwlist +server=/bmw-motorrad.co.nz/127.0.0.1#5335 +ipset=/bmw-motorrad.co.nz/gfwlist +server=/applecarbon.com/127.0.0.1#5335 +ipset=/applecarbon.com/gfwlist +server=/nudevista.club/127.0.0.1#5335 +ipset=/nudevista.club/gfwlist +server=/amazon.com.tr/127.0.0.1#5335 +ipset=/amazon.com.tr/gfwlist +server=/javtorrent.tk/127.0.0.1#5335 +ipset=/javtorrent.tk/gfwlist +server=/boodigo.com/127.0.0.1#5335 +ipset=/boodigo.com/gfwlist +server=/riotgames.jp/127.0.0.1#5335 +ipset=/riotgames.jp/gfwlist +server=/gordonmoore.com/127.0.0.1#5335 +ipset=/gordonmoore.com/gfwlist +server=/adobecreativityawards.com/127.0.0.1#5335 +ipset=/adobecreativityawards.com/gfwlist +server=/scatvids.club/127.0.0.1#5335 +ipset=/scatvids.club/gfwlist +server=/ebayjob.com/127.0.0.1#5335 +ipset=/ebayjob.com/gfwlist +server=/viacomcbspressexpress.com/127.0.0.1#5335 +ipset=/viacomcbspressexpress.com/gfwlist +server=/nhentai.net/127.0.0.1#5335 +ipset=/nhentai.net/gfwlist +server=/holloporn.com/127.0.0.1#5335 +ipset=/holloporn.com/gfwlist +server=/foxnetworksinfo.com/127.0.0.1#5335 +ipset=/foxnetworksinfo.com/gfwlist +server=/swoo.sh/127.0.0.1#5335 +ipset=/swoo.sh/gfwlist +server=/fox28media.com/127.0.0.1#5335 +ipset=/fox28media.com/gfwlist +server=/desertbmw.com/127.0.0.1#5335 +ipset=/desertbmw.com/gfwlist +server=/voatibetanenglish.com/127.0.0.1#5335 +ipset=/voatibetanenglish.com/gfwlist +server=/arcadewank.com/127.0.0.1#5335 +ipset=/arcadewank.com/gfwlist +server=/epochtime.com/127.0.0.1#5335 +ipset=/epochtime.com/gfwlist +server=/1337xto.to/127.0.0.1#5335 +ipset=/1337xto.to/gfwlist +server=/cnix-gov-cn.com/127.0.0.1#5335 +ipset=/cnix-gov-cn.com/gfwlist +server=/ebaycommercenetwork.com/127.0.0.1#5335 +ipset=/ebaycommercenetwork.com/gfwlist +server=/managedmeetingrooms.com/127.0.0.1#5335 +ipset=/managedmeetingrooms.com/gfwlist +server=/ads-twitter.com/127.0.0.1#5335 +ipset=/ads-twitter.com/gfwlist +server=/myboylove.com/127.0.0.1#5335 +ipset=/myboylove.com/gfwlist +server=/xandr.com/127.0.0.1#5335 +ipset=/xandr.com/gfwlist +server=/mybmw.com/127.0.0.1#5335 +ipset=/mybmw.com/gfwlist +server=/rolls-roycemotorcarsna.com/127.0.0.1#5335 +ipset=/rolls-roycemotorcarsna.com/gfwlist +server=/drebeats-singaporecheap.com/127.0.0.1#5335 +ipset=/drebeats-singaporecheap.com/gfwlist +server=/ladyboypornonly.com/127.0.0.1#5335 +ipset=/ladyboypornonly.com/gfwlist +server=/ijavhd.com/127.0.0.1#5335 +ipset=/ijavhd.com/gfwlist +server=/api-extractor.com/127.0.0.1#5335 +ipset=/api-extractor.com/gfwlist +server=/guardianproject.info/127.0.0.1#5335 +ipset=/guardianproject.info/gfwlist +server=/truyen18.xyz/127.0.0.1#5335 +ipset=/truyen18.xyz/gfwlist +server=/firesidegatherings.com/127.0.0.1#5335 +ipset=/firesidegatherings.com/gfwlist +server=/x6av.com/127.0.0.1#5335 +ipset=/x6av.com/gfwlist +server=/nudistvoyeurbeach.com/127.0.0.1#5335 +ipset=/nudistvoyeurbeach.com/gfwlist +server=/3hentai.net/127.0.0.1#5335 +ipset=/3hentai.net/gfwlist +server=/zee5.in/127.0.0.1#5335 +ipset=/zee5.in/gfwlist +server=/bmw-iraq.com/127.0.0.1#5335 +ipset=/bmw-iraq.com/gfwlist +server=/azure-dns.net/127.0.0.1#5335 +ipset=/azure-dns.net/gfwlist +server=/youtubego.com.br/127.0.0.1#5335 +ipset=/youtubego.com.br/gfwlist +server=/90seconds.asia/127.0.0.1#5335 +ipset=/90seconds.asia/gfwlist +server=/ikea.lt/127.0.0.1#5335 +ipset=/ikea.lt/gfwlist +server=/flexsig.com/127.0.0.1#5335 +ipset=/flexsig.com/gfwlist +server=/babesource.com/127.0.0.1#5335 +ipset=/babesource.com/gfwlist +server=/ubereats.com/127.0.0.1#5335 +ipset=/ubereats.com/gfwlist +server=/facebookporn.net/127.0.0.1#5335 +ipset=/facebookporn.net/gfwlist +server=/smartexpos.com/127.0.0.1#5335 +ipset=/smartexpos.com/gfwlist +server=/hpcomputerservices.com/127.0.0.1#5335 +ipset=/hpcomputerservices.com/gfwlist +server=/avstar07.com/127.0.0.1#5335 +ipset=/avstar07.com/gfwlist +server=/ywbclx.top/127.0.0.1#5335 +ipset=/ywbclx.top/gfwlist +server=/yahoo.com.my/127.0.0.1#5335 +ipset=/yahoo.com.my/gfwlist +server=/egghead.io/127.0.0.1#5335 +ipset=/egghead.io/gfwlist +server=/volvogroup.pl/127.0.0.1#5335 +ipset=/volvogroup.pl/gfwlist +server=/amazon.jobs/127.0.0.1#5335 +ipset=/amazon.jobs/gfwlist +server=/silverchair-cdn.com/127.0.0.1#5335 +ipset=/silverchair-cdn.com/gfwlist +server=/intc.com/127.0.0.1#5335 +ipset=/intc.com/gfwlist +server=/addthis.com/127.0.0.1#5335 +ipset=/addthis.com/gfwlist +server=/bmw.ch/127.0.0.1#5335 +ipset=/bmw.ch/gfwlist +server=/slutdump.com/127.0.0.1#5335 +ipset=/slutdump.com/gfwlist +server=/visa.com.lk/127.0.0.1#5335 +ipset=/visa.com.lk/gfwlist +server=/airav.wiki/127.0.0.1#5335 +ipset=/airav.wiki/gfwlist +server=/accessfacebookfromschool.com/127.0.0.1#5335 +ipset=/accessfacebookfromschool.com/gfwlist +server=/teensloveporn.net/127.0.0.1#5335 +ipset=/teensloveporn.net/gfwlist +server=/fbcdn.net/127.0.0.1#5335 +ipset=/fbcdn.net/gfwlist +server=/edx-cdn.org/127.0.0.1#5335 +ipset=/edx-cdn.org/gfwlist +server=/footseen.com/127.0.0.1#5335 +ipset=/footseen.com/gfwlist +server=/pornoscanner.com/127.0.0.1#5335 +ipset=/pornoscanner.com/gfwlist +server=/javhdporn.net/127.0.0.1#5335 +ipset=/javhdporn.net/gfwlist +server=/ebay-inc.com/127.0.0.1#5335 +ipset=/ebay-inc.com/gfwlist +server=/avstar5.com/127.0.0.1#5335 +ipset=/avstar5.com/gfwlist +server=/topsexart.com/127.0.0.1#5335 +ipset=/topsexart.com/gfwlist +server=/calgon.pt/127.0.0.1#5335 +ipset=/calgon.pt/gfwlist +server=/91se.fun/127.0.0.1#5335 +ipset=/91se.fun/gfwlist +server=/karlajames.com/127.0.0.1#5335 +ipset=/karlajames.com/gfwlist +server=/sexmovies24.com/127.0.0.1#5335 +ipset=/sexmovies24.com/gfwlist +server=/nike.gy/127.0.0.1#5335 +ipset=/nike.gy/gfwlist +server=/milehighmedia.com/127.0.0.1#5335 +ipset=/milehighmedia.com/gfwlist +server=/xn--3et96bj49ahpq.com/127.0.0.1#5335 +ipset=/xn--3et96bj49ahpq.com/gfwlist +server=/trueamateurmodels.com/127.0.0.1#5335 +ipset=/trueamateurmodels.com/gfwlist +server=/volvogroup.pe/127.0.0.1#5335 +ipset=/volvogroup.pe/gfwlist +server=/engineeringvillage.com/127.0.0.1#5335 +ipset=/engineeringvillage.com/gfwlist +server=/youtube.fi/127.0.0.1#5335 +ipset=/youtube.fi/gfwlist +server=/ebay.vn/127.0.0.1#5335 +ipset=/ebay.vn/gfwlist +server=/livecamclips.com/127.0.0.1#5335 +ipset=/livecamclips.com/gfwlist +server=/flirtyhoookup.com/127.0.0.1#5335 +ipset=/flirtyhoookup.com/gfwlist +server=/microsofthouse.com/127.0.0.1#5335 +ipset=/microsofthouse.com/gfwlist +server=/speedxtra.com/127.0.0.1#5335 +ipset=/speedxtra.com/gfwlist +server=/ebayclassifiedsgroup.com/127.0.0.1#5335 +ipset=/ebayclassifiedsgroup.com/gfwlist +server=/bmw-motorrad.co.th/127.0.0.1#5335 +ipset=/bmw-motorrad.co.th/gfwlist +server=/garena.my/127.0.0.1#5335 +ipset=/garena.my/gfwlist +server=/instagramsepeti.com/127.0.0.1#5335 +ipset=/instagramsepeti.com/gfwlist +server=/globalsign.com/127.0.0.1#5335 +ipset=/globalsign.com/gfwlist +server=/iphone.cm/127.0.0.1#5335 +ipset=/iphone.cm/gfwlist +server=/ems-ph.org/127.0.0.1#5335 +ipset=/ems-ph.org/gfwlist +server=/pornwhite.com/127.0.0.1#5335 +ipset=/pornwhite.com/gfwlist +server=/gettyimages.in/127.0.0.1#5335 +ipset=/gettyimages.in/gfwlist +server=/hardcoregayblog.com/127.0.0.1#5335 +ipset=/hardcoregayblog.com/gfwlist +server=/bestescortgirls.nl/127.0.0.1#5335 +ipset=/bestescortgirls.nl/gfwlist +server=/nightclub.eu/127.0.0.1#5335 +ipset=/nightclub.eu/gfwlist +server=/ukwhoswho.com/127.0.0.1#5335 +ipset=/ukwhoswho.com/gfwlist +server=/coitustube.com/127.0.0.1#5335 +ipset=/coitustube.com/gfwlist +server=/beats4salecheap.com/127.0.0.1#5335 +ipset=/beats4salecheap.com/gfwlist +server=/pornmagnet.org/127.0.0.1#5335 +ipset=/pornmagnet.org/gfwlist +server=/applecare.wang/127.0.0.1#5335 +ipset=/applecare.wang/gfwlist +server=/wa.me/127.0.0.1#5335 +ipset=/wa.me/gfwlist +server=/needforspeedtakedown.com/127.0.0.1#5335 +ipset=/needforspeedtakedown.com/gfwlist +server=/cliphayho.com/127.0.0.1#5335 +ipset=/cliphayho.com/gfwlist +server=/runwayescorts.com/127.0.0.1#5335 +ipset=/runwayescorts.com/gfwlist +server=/riotforgegames.com/127.0.0.1#5335 +ipset=/riotforgegames.com/gfwlist +server=/x-fetish.org/127.0.0.1#5335 +ipset=/x-fetish.org/gfwlist +server=/s-xoom.com/127.0.0.1#5335 +ipset=/s-xoom.com/gfwlist +server=/gfleaks.com/127.0.0.1#5335 +ipset=/gfleaks.com/gfwlist +server=/eamythic.com/127.0.0.1#5335 +ipset=/eamythic.com/gfwlist +server=/tiffany-towers.com/127.0.0.1#5335 +ipset=/tiffany-towers.com/gfwlist +server=/hpwellnesscentral.com/127.0.0.1#5335 +ipset=/hpwellnesscentral.com/gfwlist +server=/myradio.com.hk/127.0.0.1#5335 +ipset=/myradio.com.hk/gfwlist +server=/cbsistatic.com/127.0.0.1#5335 +ipset=/cbsistatic.com/gfwlist +server=/hbogoasia.tw/127.0.0.1#5335 +ipset=/hbogoasia.tw/gfwlist +server=/wiifitu.com/127.0.0.1#5335 +ipset=/wiifitu.com/gfwlist +server=/airwatchqa.com/127.0.0.1#5335 +ipset=/airwatchqa.com/gfwlist +server=/futunited.com/127.0.0.1#5335 +ipset=/futunited.com/gfwlist +server=/spermyporn.com/127.0.0.1#5335 +ipset=/spermyporn.com/gfwlist +server=/eskimotube.com/127.0.0.1#5335 +ipset=/eskimotube.com/gfwlist +server=/slutclit.com/127.0.0.1#5335 +ipset=/slutclit.com/gfwlist +server=/adidas.com/127.0.0.1#5335 +ipset=/adidas.com/gfwlist +server=/durex-shop.ch/127.0.0.1#5335 +ipset=/durex-shop.ch/gfwlist +server=/iphonexs.tv/127.0.0.1#5335 +ipset=/iphonexs.tv/gfwlist +server=/yahoo.lu/127.0.0.1#5335 +ipset=/yahoo.lu/gfwlist +server=/myfoxtampabay.com/127.0.0.1#5335 +ipset=/myfoxtampabay.com/gfwlist +server=/gloryholefucking.com/127.0.0.1#5335 +ipset=/gloryholefucking.com/gfwlist +server=/microsoftnews.com/127.0.0.1#5335 +ipset=/microsoftnews.com/gfwlist +server=/standardsuniversity.org/127.0.0.1#5335 +ipset=/standardsuniversity.org/gfwlist +server=/gate.cc/127.0.0.1#5335 +ipset=/gate.cc/gfwlist +server=/iphonecases100.com/127.0.0.1#5335 +ipset=/iphonecases100.com/gfwlist +server=/bmw-pma.com.sg/127.0.0.1#5335 +ipset=/bmw-pma.com.sg/gfwlist +server=/akamaa.com/127.0.0.1#5335 +ipset=/akamaa.com/gfwlist +server=/swiftfinancial.com/127.0.0.1#5335 +ipset=/swiftfinancial.com/gfwlist +server=/zb.app/127.0.0.1#5335 +ipset=/zb.app/gfwlist +server=/sex.sex/127.0.0.1#5335 +ipset=/sex.sex/gfwlist +server=/applefinalcutproworld.net/127.0.0.1#5335 +ipset=/applefinalcutproworld.net/gfwlist +server=/afp.com/127.0.0.1#5335 +ipset=/afp.com/gfwlist +server=/bmw-werk-berlin.de/127.0.0.1#5335 +ipset=/bmw-werk-berlin.de/gfwlist +server=/zb.live/127.0.0.1#5335 +ipset=/zb.live/gfwlist +server=/get.app/127.0.0.1#5335 +ipset=/get.app/gfwlist +server=/scholar.google.ch/127.0.0.1#5335 +ipset=/scholar.google.ch/gfwlist +server=/mylittlenieces.com/127.0.0.1#5335 +ipset=/mylittlenieces.com/gfwlist +server=/megahdporno.net/127.0.0.1#5335 +ipset=/megahdporno.net/gfwlist +server=/adidas.it/127.0.0.1#5335 +ipset=/adidas.it/gfwlist +server=/youngheaven.com/127.0.0.1#5335 +ipset=/youngheaven.com/gfwlist +server=/pearson.com.ar/127.0.0.1#5335 +ipset=/pearson.com.ar/gfwlist +server=/alt4-mtalk.google.com/127.0.0.1#5335 +ipset=/alt4-mtalk.google.com/gfwlist +server=/gettyimages.se/127.0.0.1#5335 +ipset=/gettyimages.se/gfwlist +server=/nuddess.com/127.0.0.1#5335 +ipset=/nuddess.com/gfwlist +server=/onani-daisuki.com/127.0.0.1#5335 +ipset=/onani-daisuki.com/gfwlist +server=/coursera-for-business.org/127.0.0.1#5335 +ipset=/coursera-for-business.org/gfwlist +server=/gamesathletes.com/127.0.0.1#5335 +ipset=/gamesathletes.com/gfwlist +server=/alphabet.com.lv/127.0.0.1#5335 +ipset=/alphabet.com.lv/gfwlist +server=/hdreporn.com/127.0.0.1#5335 +ipset=/hdreporn.com/gfwlist +server=/decrypt.day/127.0.0.1#5335 +ipset=/decrypt.day/gfwlist +server=/espn.co.uk/127.0.0.1#5335 +ipset=/espn.co.uk/gfwlist +server=/sandisk.id/127.0.0.1#5335 +ipset=/sandisk.id/gfwlist +server=/scholar.google.hr/127.0.0.1#5335 +ipset=/scholar.google.hr/gfwlist +server=/beatsbydregot.com/127.0.0.1#5335 +ipset=/beatsbydregot.com/gfwlist +server=/tesla.com/127.0.0.1#5335 +ipset=/tesla.com/gfwlist +server=/dickhardon.com/127.0.0.1#5335 +ipset=/dickhardon.com/gfwlist +server=/imageshack.us/127.0.0.1#5335 +ipset=/imageshack.us/gfwlist +server=/baselinestudy.org/127.0.0.1#5335 +ipset=/baselinestudy.org/gfwlist +server=/mucinex.co.nz/127.0.0.1#5335 +ipset=/mucinex.co.nz/gfwlist +server=/xingrz.me/127.0.0.1#5335 +ipset=/xingrz.me/gfwlist +server=/cash2.com/127.0.0.1#5335 +ipset=/cash2.com/gfwlist +server=/unrealtournament.com/127.0.0.1#5335 +ipset=/unrealtournament.com/gfwlist +server=/travelex.de/127.0.0.1#5335 +ipset=/travelex.de/gfwlist +server=/jwplayer.com/127.0.0.1#5335 +ipset=/jwplayer.com/gfwlist +server=/swingercuckoldporn.com/127.0.0.1#5335 +ipset=/swingercuckoldporn.com/gfwlist +server=/pagespeedmobilizer.com/127.0.0.1#5335 +ipset=/pagespeedmobilizer.com/gfwlist +server=/casquebeatsdre2013.com/127.0.0.1#5335 +ipset=/casquebeatsdre2013.com/gfwlist +server=/homepornking.com/127.0.0.1#5335 +ipset=/homepornking.com/gfwlist +server=/iphone.net.gr/127.0.0.1#5335 +ipset=/iphone.net.gr/gfwlist +server=/blogspot.lu/127.0.0.1#5335 +ipset=/blogspot.lu/gfwlist +server=/intel.com/127.0.0.1#5335 +ipset=/intel.com/gfwlist +server=/bdsm-mov.net/127.0.0.1#5335 +ipset=/bdsm-mov.net/gfwlist +server=/iwaponline.com/127.0.0.1#5335 +ipset=/iwaponline.com/gfwlist +server=/applehongkong.com.hk/127.0.0.1#5335 +ipset=/applehongkong.com.hk/gfwlist +server=/visiontimes.fr/127.0.0.1#5335 +ipset=/visiontimes.fr/gfwlist +server=/69luolie.com/127.0.0.1#5335 +ipset=/69luolie.com/gfwlist +server=/ieee-into-focus.org/127.0.0.1#5335 +ipset=/ieee-into-focus.org/gfwlist +server=/hotladsworld.com/127.0.0.1#5335 +ipset=/hotladsworld.com/gfwlist +server=/edengay.net/127.0.0.1#5335 +ipset=/edengay.net/gfwlist +server=/beatsbydreexecutivesale.com/127.0.0.1#5335 +ipset=/beatsbydreexecutivesale.com/gfwlist +server=/akadns.com/127.0.0.1#5335 +ipset=/akadns.com/gfwlist +server=/googlemail.com/127.0.0.1#5335 +ipset=/googlemail.com/gfwlist +server=/jabcomix.com/127.0.0.1#5335 +ipset=/jabcomix.com/gfwlist +server=/fujinkoron.jp/127.0.0.1#5335 +ipset=/fujinkoron.jp/gfwlist +server=/ponyanimalsex.com/127.0.0.1#5335 +ipset=/ponyanimalsex.com/gfwlist +server=/facebookappcenter.net/127.0.0.1#5335 +ipset=/facebookappcenter.net/gfwlist +server=/bigtitsgallery.net/127.0.0.1#5335 +ipset=/bigtitsgallery.net/gfwlist +server=/crazyxxx3dworld.org/127.0.0.1#5335 +ipset=/crazyxxx3dworld.org/gfwlist +server=/gitbook.com/127.0.0.1#5335 +ipset=/gitbook.com/gfwlist +server=/absoluporn.com/127.0.0.1#5335 +ipset=/absoluporn.com/gfwlist +server=/paypal.com.hk/127.0.0.1#5335 +ipset=/paypal.com.hk/gfwlist +server=/worldpornvideos.com/127.0.0.1#5335 +ipset=/worldpornvideos.com/gfwlist +server=/indiansexstories.net/127.0.0.1#5335 +ipset=/indiansexstories.net/gfwlist +server=/nvidia.com.mx/127.0.0.1#5335 +ipset=/nvidia.com.mx/gfwlist +server=/qdiehzz7.me/127.0.0.1#5335 +ipset=/qdiehzz7.me/gfwlist +server=/arabnek.com/127.0.0.1#5335 +ipset=/arabnek.com/gfwlist +server=/nonktube.com/127.0.0.1#5335 +ipset=/nonktube.com/gfwlist +server=/nlm.io/127.0.0.1#5335 +ipset=/nlm.io/gfwlist +server=/pokemonultrasunmoon.com/127.0.0.1#5335 +ipset=/pokemonultrasunmoon.com/gfwlist +server=/sp.cool/127.0.0.1#5335 +ipset=/sp.cool/gfwlist +server=/facetook.com/127.0.0.1#5335 +ipset=/facetook.com/gfwlist +server=/animalporn.me/127.0.0.1#5335 +ipset=/animalporn.me/gfwlist +server=/desipornfilms.com/127.0.0.1#5335 +ipset=/desipornfilms.com/gfwlist +server=/casquedrdrebeatssfr.com/127.0.0.1#5335 +ipset=/casquedrdrebeatssfr.com/gfwlist +server=/milfmaturesex.net/127.0.0.1#5335 +ipset=/milfmaturesex.net/gfwlist +server=/bbc.in/127.0.0.1#5335 +ipset=/bbc.in/gfwlist +server=/hypnohub.net/127.0.0.1#5335 +ipset=/hypnohub.net/gfwlist +server=/paypal-online.info/127.0.0.1#5335 +ipset=/paypal-online.info/gfwlist +server=/scholar.google.com.bo/127.0.0.1#5335 +ipset=/scholar.google.com.bo/gfwlist +server=/masalabin.com/127.0.0.1#5335 +ipset=/masalabin.com/gfwlist +server=/twttr.com/127.0.0.1#5335 +ipset=/twttr.com/gfwlist +server=/mafia-linkz.to/127.0.0.1#5335 +ipset=/mafia-linkz.to/gfwlist +server=/awscommandlineinterface.com/127.0.0.1#5335 +ipset=/awscommandlineinterface.com/gfwlist +server=/vpro.net/127.0.0.1#5335 +ipset=/vpro.net/gfwlist +server=/bmw.ma/127.0.0.1#5335 +ipset=/bmw.ma/gfwlist +server=/pise.pw/127.0.0.1#5335 +ipset=/pise.pw/gfwlist +server=/pornobae.com/127.0.0.1#5335 +ipset=/pornobae.com/gfwlist +server=/minnano-av.com/127.0.0.1#5335 +ipset=/minnano-av.com/gfwlist +server=/gamesofdesire.com/127.0.0.1#5335 +ipset=/gamesofdesire.com/gfwlist +server=/xxxgratisfilms.com/127.0.0.1#5335 +ipset=/xxxgratisfilms.com/gfwlist +server=/autodesk.com/127.0.0.1#5335 +ipset=/autodesk.com/gfwlist +server=/tearapeak.com/127.0.0.1#5335 +ipset=/tearapeak.com/gfwlist +server=/foxphiladelphia.com/127.0.0.1#5335 +ipset=/foxphiladelphia.com/gfwlist +server=/livejasmin.com/127.0.0.1#5335 +ipset=/livejasmin.com/gfwlist +server=/bmw-motorrad.com.ar/127.0.0.1#5335 +ipset=/bmw-motorrad.com.ar/gfwlist +server=/nudelive.com/127.0.0.1#5335 +ipset=/nudelive.com/gfwlist +server=/gtv.org/127.0.0.1#5335 +ipset=/gtv.org/gfwlist +server=/blizzardgearstore.com/127.0.0.1#5335 +ipset=/blizzardgearstore.com/gfwlist +server=/hotsexydolls.com/127.0.0.1#5335 +ipset=/hotsexydolls.com/gfwlist +server=/thomsonreuters.co.jp/127.0.0.1#5335 +ipset=/thomsonreuters.co.jp/gfwlist +server=/oreilly.com/127.0.0.1#5335 +ipset=/oreilly.com/gfwlist +server=/mysql.com/127.0.0.1#5335 +ipset=/mysql.com/gfwlist +server=/kijji.ca/127.0.0.1#5335 +ipset=/kijji.ca/gfwlist +server=/visa.com.hr/127.0.0.1#5335 +ipset=/visa.com.hr/gfwlist +server=/ig.me/127.0.0.1#5335 +ipset=/ig.me/gfwlist +server=/2mdn.net/127.0.0.1#5335 +ipset=/2mdn.net/gfwlist +server=/steampipe.akamaized.net/127.0.0.1#5335 +ipset=/steampipe.akamaized.net/gfwlist +server=/travelex.com.tr/127.0.0.1#5335 +ipset=/travelex.com.tr/gfwlist +server=/takens.tw/127.0.0.1#5335 +ipset=/takens.tw/gfwlist +server=/moviesanywhere.com/127.0.0.1#5335 +ipset=/moviesanywhere.com/gfwlist +server=/youjizz.com/127.0.0.1#5335 +ipset=/youjizz.com/gfwlist +server=/tubemovies4k.com/127.0.0.1#5335 +ipset=/tubemovies4k.com/gfwlist +server=/superjapanesesex.com/127.0.0.1#5335 +ipset=/superjapanesesex.com/gfwlist +server=/kinklive.com/127.0.0.1#5335 +ipset=/kinklive.com/gfwlist +server=/pornone.com/127.0.0.1#5335 +ipset=/pornone.com/gfwlist +server=/infrapedia.com/127.0.0.1#5335 +ipset=/infrapedia.com/gfwlist +server=/apple.in/127.0.0.1#5335 +ipset=/apple.in/gfwlist +server=/ingka.com/127.0.0.1#5335 +ipset=/ingka.com/gfwlist +server=/facebocke.com/127.0.0.1#5335 +ipset=/facebocke.com/gfwlist +server=/realclearhealth.com/127.0.0.1#5335 +ipset=/realclearhealth.com/gfwlist +server=/rocketfishproducts.com/127.0.0.1#5335 +ipset=/rocketfishproducts.com/gfwlist +server=/facebookbrand.com/127.0.0.1#5335 +ipset=/facebookbrand.com/gfwlist +server=/facebookcheats.com/127.0.0.1#5335 +ipset=/facebookcheats.com/gfwlist +server=/modular.im/127.0.0.1#5335 +ipset=/modular.im/gfwlist +server=/duckduckgo.sg/127.0.0.1#5335 +ipset=/duckduckgo.sg/gfwlist +server=/pearsonassessment.fr/127.0.0.1#5335 +ipset=/pearsonassessment.fr/gfwlist +server=/now.com/127.0.0.1#5335 +ipset=/now.com/gfwlist +server=/bmw-connecteddrive.com.br/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com.br/gfwlist +server=/xnxxporn.de/127.0.0.1#5335 +ipset=/xnxxporn.de/gfwlist +server=/pinterest.fr/127.0.0.1#5335 +ipset=/pinterest.fr/gfwlist +server=/facebooknews.com/127.0.0.1#5335 +ipset=/facebooknews.com/gfwlist +server=/faronics.eu/127.0.0.1#5335 +ipset=/faronics.eu/gfwlist +server=/adultvideotop.com/127.0.0.1#5335 +ipset=/adultvideotop.com/gfwlist +server=/abc.xyz/127.0.0.1#5335 +ipset=/abc.xyz/gfwlist +server=/linuxmint.com/127.0.0.1#5335 +ipset=/linuxmint.com/gfwlist +server=/girlswelustfor.com/127.0.0.1#5335 +ipset=/girlswelustfor.com/gfwlist +server=/wikawika.xyz/127.0.0.1#5335 +ipset=/wikawika.xyz/gfwlist +server=/intel.lu/127.0.0.1#5335 +ipset=/intel.lu/gfwlist +server=/zeit-world.co.uk/127.0.0.1#5335 +ipset=/zeit-world.co.uk/gfwlist +server=/realteengirls.com/127.0.0.1#5335 +ipset=/realteengirls.com/gfwlist +server=/unkoscene.com/127.0.0.1#5335 +ipset=/unkoscene.com/gfwlist +server=/is.gd/127.0.0.1#5335 +ipset=/is.gd/gfwlist +server=/mini-connected.lu/127.0.0.1#5335 +ipset=/mini-connected.lu/gfwlist +server=/47news.jp/127.0.0.1#5335 +ipset=/47news.jp/gfwlist +server=/rbgraduates.com/127.0.0.1#5335 +ipset=/rbgraduates.com/gfwlist +server=/google.lv/127.0.0.1#5335 +ipset=/google.lv/gfwlist +server=/mymasturbators.com/127.0.0.1#5335 +ipset=/mymasturbators.com/gfwlist +server=/8thstreetlatinas.com/127.0.0.1#5335 +ipset=/8thstreetlatinas.com/gfwlist +server=/juliamovies.com/127.0.0.1#5335 +ipset=/juliamovies.com/gfwlist +server=/nmbmw.com/127.0.0.1#5335 +ipset=/nmbmw.com/gfwlist +server=/trellocdn.com/127.0.0.1#5335 +ipset=/trellocdn.com/gfwlist +server=/devtools-paypal.com/127.0.0.1#5335 +ipset=/devtools-paypal.com/gfwlist +server=/swingers.theadulthub.com/127.0.0.1#5335 +ipset=/swingers.theadulthub.com/gfwlist +server=/qwant.de/127.0.0.1#5335 +ipset=/qwant.de/gfwlist +server=/wifewantstoplay.com/127.0.0.1#5335 +ipset=/wifewantstoplay.com/gfwlist +server=/vfsco.ee/127.0.0.1#5335 +ipset=/vfsco.ee/gfwlist +server=/youtube.am/127.0.0.1#5335 +ipset=/youtube.am/gfwlist +server=/pornoreino.com/127.0.0.1#5335 +ipset=/pornoreino.com/gfwlist +server=/vmw.com/127.0.0.1#5335 +ipset=/vmw.com/gfwlist +server=/canon.se/127.0.0.1#5335 +ipset=/canon.se/gfwlist +server=/nikeshoes21.com/127.0.0.1#5335 +ipset=/nikeshoes21.com/gfwlist +server=/beatsbydreaustraliaonlines.com/127.0.0.1#5335 +ipset=/beatsbydreaustraliaonlines.com/gfwlist +server=/flipshare.com/127.0.0.1#5335 +ipset=/flipshare.com/gfwlist +server=/camgirlfinder.net/127.0.0.1#5335 +ipset=/camgirlfinder.net/gfwlist +server=/ssx3.com/127.0.0.1#5335 +ipset=/ssx3.com/gfwlist +server=/candycumcity.com/127.0.0.1#5335 +ipset=/candycumcity.com/gfwlist +server=/scatville.com/127.0.0.1#5335 +ipset=/scatville.com/gfwlist +server=/applewatchseries3.net/127.0.0.1#5335 +ipset=/applewatchseries3.net/gfwlist +server=/mkto-c0100.com/127.0.0.1#5335 +ipset=/mkto-c0100.com/gfwlist +server=/bmw.bm/127.0.0.1#5335 +ipset=/bmw.bm/gfwlist +server=/skyoceanrescue.it/127.0.0.1#5335 +ipset=/skyoceanrescue.it/gfwlist +server=/withyoutube.com/127.0.0.1#5335 +ipset=/withyoutube.com/gfwlist +server=/pornqd.com/127.0.0.1#5335 +ipset=/pornqd.com/gfwlist +server=/moozporn.com/127.0.0.1#5335 +ipset=/moozporn.com/gfwlist +server=/sandisk.ae/127.0.0.1#5335 +ipset=/sandisk.ae/gfwlist +server=/hentaicomics.asia/127.0.0.1#5335 +ipset=/hentaicomics.asia/gfwlist +server=/bmw.co.th/127.0.0.1#5335 +ipset=/bmw.co.th/gfwlist +server=/bestcamsites.net/127.0.0.1#5335 +ipset=/bestcamsites.net/gfwlist +server=/boundhub.com/127.0.0.1#5335 +ipset=/boundhub.com/gfwlist +server=/youtube.hk/127.0.0.1#5335 +ipset=/youtube.hk/gfwlist +server=/pyhapp.com/127.0.0.1#5335 +ipset=/pyhapp.com/gfwlist +server=/xchina.co/127.0.0.1#5335 +ipset=/xchina.co/gfwlist +server=/bmw-i.jp/127.0.0.1#5335 +ipset=/bmw-i.jp/gfwlist +server=/tryengineering.org/127.0.0.1#5335 +ipset=/tryengineering.org/gfwlist +server=/hbogoasia.ph/127.0.0.1#5335 +ipset=/hbogoasia.ph/gfwlist +server=/chinadecoding.com/127.0.0.1#5335 +ipset=/chinadecoding.com/gfwlist +server=/ipoditouch.com/127.0.0.1#5335 +ipset=/ipoditouch.com/gfwlist +server=/faronics.com/127.0.0.1#5335 +ipset=/faronics.com/gfwlist +server=/88gals.com/127.0.0.1#5335 +ipset=/88gals.com/gfwlist +server=/zencdn.net/127.0.0.1#5335 +ipset=/zencdn.net/gfwlist +server=/mini-srilanka.com/127.0.0.1#5335 +ipset=/mini-srilanka.com/gfwlist +server=/mrporngeek.com/127.0.0.1#5335 +ipset=/mrporngeek.com/gfwlist +server=/visafulfillment.com/127.0.0.1#5335 +ipset=/visafulfillment.com/gfwlist +server=/volvobuses.ca/127.0.0.1#5335 +ipset=/volvobuses.ca/gfwlist +server=/selectyourgame.com/127.0.0.1#5335 +ipset=/selectyourgame.com/gfwlist +server=/q10.jp/127.0.0.1#5335 +ipset=/q10.jp/gfwlist +server=/tubetubetube.com/127.0.0.1#5335 +ipset=/tubetubetube.com/gfwlist +server=/tubous.com/127.0.0.1#5335 +ipset=/tubous.com/gfwlist +server=/spotify-everywhere.com/127.0.0.1#5335 +ipset=/spotify-everywhere.com/gfwlist +server=/dvdtrailertube.com/127.0.0.1#5335 +ipset=/dvdtrailertube.com/gfwlist +server=/friendfeed.com/127.0.0.1#5335 +ipset=/friendfeed.com/gfwlist +server=/hifixxx.fun/127.0.0.1#5335 +ipset=/hifixxx.fun/gfwlist +server=/google.co/127.0.0.1#5335 +ipset=/google.co/gfwlist +server=/kichikuou.com/127.0.0.1#5335 +ipset=/kichikuou.com/gfwlist +server=/babes34.com/127.0.0.1#5335 +ipset=/babes34.com/gfwlist +server=/elsevier.com/127.0.0.1#5335 +ipset=/elsevier.com/gfwlist +server=/tsquare.tv/127.0.0.1#5335 +ipset=/tsquare.tv/gfwlist +server=/starbucksslovakia.sk/127.0.0.1#5335 +ipset=/starbucksslovakia.sk/gfwlist +server=/darkageofcamelot.com/127.0.0.1#5335 +ipset=/darkageofcamelot.com/gfwlist +server=/starbucksromania.ro/127.0.0.1#5335 +ipset=/starbucksromania.ro/gfwlist +server=/avstar06.me/127.0.0.1#5335 +ipset=/avstar06.me/gfwlist +server=/cuckoldwifetube.com/127.0.0.1#5335 +ipset=/cuckoldwifetube.com/gfwlist +server=/yzzk.com/127.0.0.1#5335 +ipset=/yzzk.com/gfwlist +server=/mediawiki.org/127.0.0.1#5335 +ipset=/mediawiki.org/gfwlist +server=/starbucksreserve.com/127.0.0.1#5335 +ipset=/starbucksreserve.com/gfwlist +server=/starbucksforlife.ca/127.0.0.1#5335 +ipset=/starbucksforlife.ca/gfwlist +server=/starbuckscoffeegearstore.com/127.0.0.1#5335 +ipset=/starbuckscoffeegearstore.com/gfwlist +server=/sharks-lagoon.fr/127.0.0.1#5335 +ipset=/sharks-lagoon.fr/gfwlist +server=/starbuckscoffee.cz/127.0.0.1#5335 +ipset=/starbuckscoffee.cz/gfwlist +server=/starbuckscardb2b.com/127.0.0.1#5335 +ipset=/starbuckscardb2b.com/gfwlist +server=/volvobrandshop.com/127.0.0.1#5335 +ipset=/volvobrandshop.com/gfwlist +server=/starbucksavie.ca/127.0.0.1#5335 +ipset=/starbucksavie.ca/gfwlist +server=/ebayworlds.com/127.0.0.1#5335 +ipset=/ebayworlds.com/gfwlist +server=/starbucksathome.com/127.0.0.1#5335 +ipset=/starbucksathome.com/gfwlist +server=/insidevoa.com/127.0.0.1#5335 +ipset=/insidevoa.com/gfwlist +server=/starbucks.tt/127.0.0.1#5335 +ipset=/starbucks.tt/gfwlist +server=/webgirlsonline.net/127.0.0.1#5335 +ipset=/webgirlsonline.net/gfwlist +server=/starbucks.se/127.0.0.1#5335 +ipset=/starbucks.se/gfwlist +server=/starbucks.ru/127.0.0.1#5335 +ipset=/starbucks.ru/gfwlist +server=/starbucks.rs/127.0.0.1#5335 +ipset=/starbucks.rs/gfwlist +server=/freecodecamp.org/127.0.0.1#5335 +ipset=/freecodecamp.org/gfwlist +server=/starbucks.pt/127.0.0.1#5335 +ipset=/starbucks.pt/gfwlist +server=/bmw-motorrad.sa/127.0.0.1#5335 +ipset=/bmw-motorrad.sa/gfwlist +server=/paypal-portal.com/127.0.0.1#5335 +ipset=/paypal-portal.com/gfwlist +server=/starbucks.pl/127.0.0.1#5335 +ipset=/starbucks.pl/gfwlist +server=/apple.me/127.0.0.1#5335 +ipset=/apple.me/gfwlist +server=/b-ok.global/127.0.0.1#5335 +ipset=/b-ok.global/gfwlist +server=/kendralist.com/127.0.0.1#5335 +ipset=/kendralist.com/gfwlist +server=/erohentai.net/127.0.0.1#5335 +ipset=/erohentai.net/gfwlist +server=/screenwisetrends.com/127.0.0.1#5335 +ipset=/screenwisetrends.com/gfwlist +server=/starbucks.nl/127.0.0.1#5335 +ipset=/starbucks.nl/gfwlist +server=/cuckoldwifesexxx.com/127.0.0.1#5335 +ipset=/cuckoldwifesexxx.com/gfwlist +server=/sexfilmstube.com/127.0.0.1#5335 +ipset=/sexfilmstube.com/gfwlist +server=/starbucks.it/127.0.0.1#5335 +ipset=/starbucks.it/gfwlist +server=/ebayd.com/127.0.0.1#5335 +ipset=/ebayd.com/gfwlist +server=/xxxhd.pro/127.0.0.1#5335 +ipset=/xxxhd.pro/gfwlist +server=/ebay-fashion.com/127.0.0.1#5335 +ipset=/ebay-fashion.com/gfwlist +server=/starbucks.in/127.0.0.1#5335 +ipset=/starbucks.in/gfwlist +server=/koalaporn.com/127.0.0.1#5335 +ipset=/koalaporn.com/gfwlist +server=/pornofiles.ru/127.0.0.1#5335 +ipset=/pornofiles.ru/gfwlist +server=/zoomobileporn.com/127.0.0.1#5335 +ipset=/zoomobileporn.com/gfwlist +server=/paypalcreditcard.com/127.0.0.1#5335 +ipset=/paypalcreditcard.com/gfwlist +server=/starbucks.hu/127.0.0.1#5335 +ipset=/starbucks.hu/gfwlist +server=/faceboik.com/127.0.0.1#5335 +ipset=/faceboik.com/gfwlist +server=/bestbuyphotoworkshoptours.com/127.0.0.1#5335 +ipset=/bestbuyphotoworkshoptours.com/gfwlist +server=/starbucks.com.uy/127.0.0.1#5335 +ipset=/starbucks.com.uy/gfwlist +server=/starbucks.com.pe/127.0.0.1#5335 +ipset=/starbucks.com.pe/gfwlist +server=/starbucks.com.my/127.0.0.1#5335 +ipset=/starbucks.com.my/gfwlist +server=/starbucks.com.kh/127.0.0.1#5335 +ipset=/starbucks.com.kh/gfwlist +server=/starbucks.com.hk/127.0.0.1#5335 +ipset=/starbucks.com.hk/gfwlist +server=/starbucks.com.cy/127.0.0.1#5335 +ipset=/starbucks.com.cy/gfwlist +server=/durex.fr/127.0.0.1#5335 +ipset=/durex.fr/gfwlist +server=/starbucks.com/127.0.0.1#5335 +ipset=/starbucks.com/gfwlist +server=/hxdoll.com/127.0.0.1#5335 +ipset=/hxdoll.com/gfwlist +server=/starbucks.co.jp/127.0.0.1#5335 +ipset=/starbucks.co.jp/gfwlist +server=/starbucks.bg/127.0.0.1#5335 +ipset=/starbucks.bg/gfwlist +server=/starbucks.be/127.0.0.1#5335 +ipset=/starbucks.be/gfwlist +server=/starbucks.at/127.0.0.1#5335 +ipset=/starbucks.at/gfwlist +server=/apple.my/127.0.0.1#5335 +ipset=/apple.my/gfwlist +server=/disneymagicmoments.co.za/127.0.0.1#5335 +ipset=/disneymagicmoments.co.za/gfwlist +server=/starbucks-stars.com/127.0.0.1#5335 +ipset=/starbucks-stars.com/gfwlist +server=/sbuxcard.com/127.0.0.1#5335 +ipset=/sbuxcard.com/gfwlist +server=/hpto.net/127.0.0.1#5335 +ipset=/hpto.net/gfwlist +server=/sbux.com.my/127.0.0.1#5335 +ipset=/sbux.com.my/gfwlist +server=/hulu.tv/127.0.0.1#5335 +ipset=/hulu.tv/gfwlist +server=/scenesource.me/127.0.0.1#5335 +ipset=/scenesource.me/gfwlist +server=/thinkofliving.com/127.0.0.1#5335 +ipset=/thinkofliving.com/gfwlist +server=/javheroine.com/127.0.0.1#5335 +ipset=/javheroine.com/gfwlist +server=/realtor.com/127.0.0.1#5335 +ipset=/realtor.com/gfwlist +server=/caribbeancompr.com/127.0.0.1#5335 +ipset=/caribbeancompr.com/gfwlist +server=/porn-portal.com/127.0.0.1#5335 +ipset=/porn-portal.com/gfwlist +server=/realcommercial.com.au/127.0.0.1#5335 +ipset=/realcommercial.com.au/gfwlist +server=/rea.tech/127.0.0.1#5335 +ipset=/rea.tech/gfwlist +server=/adblockplus.org/127.0.0.1#5335 +ipset=/adblockplus.org/gfwlist +server=/rea.global/127.0.0.1#5335 +ipset=/rea.global/gfwlist +server=/rea-group.com/127.0.0.1#5335 +ipset=/rea-group.com/gfwlist +server=/iphonecollcase.com/127.0.0.1#5335 +ipset=/iphonecollcase.com/gfwlist +server=/adobe.com/127.0.0.1#5335 +ipset=/adobe.com/gfwlist +server=/8008206616.com/127.0.0.1#5335 +ipset=/8008206616.com/gfwlist +server=/adbkm.com/127.0.0.1#5335 +ipset=/adbkm.com/gfwlist +server=/proptiger.com/127.0.0.1#5335 +ipset=/proptiger.com/gfwlist +server=/myfun.com/127.0.0.1#5335 +ipset=/myfun.com/gfwlist +server=/move.com/127.0.0.1#5335 +ipset=/move.com/gfwlist +server=/technews.tw/127.0.0.1#5335 +ipset=/technews.tw/gfwlist +server=/makaan.com/127.0.0.1#5335 +ipset=/makaan.com/gfwlist +server=/iproperty.com.my/127.0.0.1#5335 +ipset=/iproperty.com.my/gfwlist +server=/housingcdn.com/127.0.0.1#5335 +ipset=/housingcdn.com/gfwlist +server=/hometrack.com.au/127.0.0.1#5335 +ipset=/hometrack.com.au/gfwlist +server=/bmwi.jp/127.0.0.1#5335 +ipset=/bmwi.jp/gfwlist +server=/facesounds.com/127.0.0.1#5335 +ipset=/facesounds.com/gfwlist +server=/azathabar.com/127.0.0.1#5335 +ipset=/azathabar.com/gfwlist +server=/playboyplus.com/127.0.0.1#5335 +ipset=/playboyplus.com/gfwlist +server=/123videos.tv/127.0.0.1#5335 +ipset=/123videos.tv/gfwlist +server=/shemalemodelstube.com/127.0.0.1#5335 +ipset=/shemalemodelstube.com/gfwlist +server=/reckittbenckiser.net/127.0.0.1#5335 +ipset=/reckittbenckiser.net/gfwlist +server=/reckittbenckiser.com/127.0.0.1#5335 +ipset=/reckittbenckiser.com/gfwlist +server=/reckitt.net/127.0.0.1#5335 +ipset=/reckitt.net/gfwlist +server=/rbplc.com/127.0.0.1#5335 +ipset=/rbplc.com/gfwlist +server=/rbgrads.com/127.0.0.1#5335 +ipset=/rbgrads.com/gfwlist +server=/pplusstatic.com/127.0.0.1#5335 +ipset=/pplusstatic.com/gfwlist +server=/rb.com/127.0.0.1#5335 +ipset=/rb.com/gfwlist +server=/porntry.com/127.0.0.1#5335 +ipset=/porntry.com/gfwlist +server=/offerairjordanlebron.com/127.0.0.1#5335 +ipset=/offerairjordanlebron.com/gfwlist +server=/gettr.com/127.0.0.1#5335 +ipset=/gettr.com/gfwlist +server=/avxhm.se/127.0.0.1#5335 +ipset=/avxhm.se/gfwlist +server=/woolite.us/127.0.0.1#5335 +ipset=/woolite.us/gfwlist +server=/kobe-pastel.com/127.0.0.1#5335 +ipset=/kobe-pastel.com/gfwlist +server=/woolite.pl/127.0.0.1#5335 +ipset=/woolite.pl/gfwlist +server=/woolite.ca/127.0.0.1#5335 +ipset=/woolite.ca/gfwlist +server=/veetcentroamerica.com/127.0.0.1#5335 +ipset=/veetcentroamerica.com/gfwlist +server=/veet.ru/127.0.0.1#5335 +ipset=/veet.ru/gfwlist +server=/visa.gp/127.0.0.1#5335 +ipset=/visa.gp/gfwlist +server=/veet.pt/127.0.0.1#5335 +ipset=/veet.pt/gfwlist +server=/veet.nl/127.0.0.1#5335 +ipset=/veet.nl/gfwlist +server=/creativecloud.com/127.0.0.1#5335 +ipset=/creativecloud.com/gfwlist +server=/veet.jp/127.0.0.1#5335 +ipset=/veet.jp/gfwlist +server=/thesffblog.com/127.0.0.1#5335 +ipset=/thesffblog.com/gfwlist +server=/nudevista.com/127.0.0.1#5335 +ipset=/nudevista.com/gfwlist +server=/veet.hu/127.0.0.1#5335 +ipset=/veet.hu/gfwlist +server=/sexbomba.ru/127.0.0.1#5335 +ipset=/sexbomba.ru/gfwlist +server=/veet.fi/127.0.0.1#5335 +ipset=/veet.fi/gfwlist +server=/veet.es/127.0.0.1#5335 +ipset=/veet.es/gfwlist +server=/myhentaicomics.com/127.0.0.1#5335 +ipset=/myhentaicomics.com/gfwlist +server=/newxxx24.cc/127.0.0.1#5335 +ipset=/newxxx24.cc/gfwlist +server=/veet.dk/127.0.0.1#5335 +ipset=/veet.dk/gfwlist +server=/veet.com.tr/127.0.0.1#5335 +ipset=/veet.com.tr/gfwlist +server=/veet.com.ph/127.0.0.1#5335 +ipset=/veet.com.ph/gfwlist +server=/beatsfactoryoutles.com/127.0.0.1#5335 +ipset=/beatsfactoryoutles.com/gfwlist +server=/veet.com.hk/127.0.0.1#5335 +ipset=/veet.com.hk/gfwlist +server=/veet.com.co/127.0.0.1#5335 +ipset=/veet.com.co/gfwlist +server=/veet.com.br/127.0.0.1#5335 +ipset=/veet.com.br/gfwlist +server=/swisssigngroup.com/127.0.0.1#5335 +ipset=/swisssigngroup.com/gfwlist +server=/veet.com.bd/127.0.0.1#5335 +ipset=/veet.com.bd/gfwlist +server=/fox5storm.com/127.0.0.1#5335 +ipset=/fox5storm.com/gfwlist +server=/newsupermariobrosu.com/127.0.0.1#5335 +ipset=/newsupermariobrosu.com/gfwlist +server=/veet.com.au/127.0.0.1#5335 +ipset=/veet.com.au/gfwlist +server=/discordapp.com/127.0.0.1#5335 +ipset=/discordapp.com/gfwlist +server=/veet.co.za/127.0.0.1#5335 +ipset=/veet.co.za/gfwlist +server=/18porncomic.com/127.0.0.1#5335 +ipset=/18porncomic.com/gfwlist +server=/mastercard.com.ve/127.0.0.1#5335 +ipset=/mastercard.com.ve/gfwlist +server=/veet.co.id/127.0.0.1#5335 +ipset=/veet.co.id/gfwlist +server=/veet.ch/127.0.0.1#5335 +ipset=/veet.ch/gfwlist +server=/porndeals.com/127.0.0.1#5335 +ipset=/porndeals.com/gfwlist +server=/icloudo.de/127.0.0.1#5335 +ipset=/icloudo.de/gfwlist +server=/phncdn.com/127.0.0.1#5335 +ipset=/phncdn.com/gfwlist +server=/tubepornup.com/127.0.0.1#5335 +ipset=/tubepornup.com/gfwlist +server=/vanishinfo.cz/127.0.0.1#5335 +ipset=/vanishinfo.cz/gfwlist +server=/vanishbancaseulook.com.br/127.0.0.1#5335 +ipset=/vanishbancaseulook.com.br/gfwlist +server=/vanisharabia.com/127.0.0.1#5335 +ipset=/vanisharabia.com/gfwlist +server=/renovacionxboxlive.com/127.0.0.1#5335 +ipset=/renovacionxboxlive.com/gfwlist +server=/mastercardbusinessnetwork.com/127.0.0.1#5335 +ipset=/mastercardbusinessnetwork.com/gfwlist +server=/vanish.hu/127.0.0.1#5335 +ipset=/vanish.hu/gfwlist +server=/nudefiles.net/127.0.0.1#5335 +ipset=/nudefiles.net/gfwlist +server=/abematv.akamaized.net/127.0.0.1#5335 +ipset=/abematv.akamaized.net/gfwlist +server=/milfthreesomes.com/127.0.0.1#5335 +ipset=/milfthreesomes.com/gfwlist +server=/vanish.fi/127.0.0.1#5335 +ipset=/vanish.fi/gfwlist +server=/xxxgames.biz/127.0.0.1#5335 +ipset=/xxxgames.biz/gfwlist +server=/vanish.de/127.0.0.1#5335 +ipset=/vanish.de/gfwlist +server=/vanish.com.sg/127.0.0.1#5335 +ipset=/vanish.com.sg/gfwlist +server=/nikeproduct.com/127.0.0.1#5335 +ipset=/nikeproduct.com/gfwlist +server=/vanish.com.my/127.0.0.1#5335 +ipset=/vanish.com.my/gfwlist +server=/royalcams.com/127.0.0.1#5335 +ipset=/royalcams.com/gfwlist +server=/niceanimegames.com/127.0.0.1#5335 +ipset=/niceanimegames.com/gfwlist +server=/epochtimestr.com/127.0.0.1#5335 +ipset=/epochtimestr.com/gfwlist +server=/seaporn.org/127.0.0.1#5335 +ipset=/seaporn.org/gfwlist +server=/mail.ru/127.0.0.1#5335 +ipset=/mail.ru/gfwlist +server=/hayabusa.media/127.0.0.1#5335 +ipset=/hayabusa.media/gfwlist +server=/mucinex.ca/127.0.0.1#5335 +ipset=/mucinex.ca/gfwlist +server=/vanish.co.nz/127.0.0.1#5335 +ipset=/vanish.co.nz/gfwlist +server=/game-platform.net/127.0.0.1#5335 +ipset=/game-platform.net/gfwlist +server=/ciscopartnermarketing.com/127.0.0.1#5335 +ipset=/ciscopartnermarketing.com/gfwlist +server=/vanish.co.il/127.0.0.1#5335 +ipset=/vanish.co.il/gfwlist +server=/sexei.net/127.0.0.1#5335 +ipset=/sexei.net/gfwlist +server=/area120.com/127.0.0.1#5335 +ipset=/area120.com/gfwlist +server=/vanish.cl/127.0.0.1#5335 +ipset=/vanish.cl/gfwlist +server=/verisign.co.uk/127.0.0.1#5335 +ipset=/verisign.co.uk/gfwlist +server=/static-hamivideo.cdn.hinet.net/127.0.0.1#5335 +ipset=/static-hamivideo.cdn.hinet.net/gfwlist +server=/bmw-welt.net/127.0.0.1#5335 +ipset=/bmw-welt.net/gfwlist +server=/miniso.uz/127.0.0.1#5335 +ipset=/miniso.uz/gfwlist +server=/vanish.be/127.0.0.1#5335 +ipset=/vanish.be/gfwlist +server=/pornerbros.com/127.0.0.1#5335 +ipset=/pornerbros.com/gfwlist +server=/spraynwash.com/127.0.0.1#5335 +ipset=/spraynwash.com/gfwlist +server=/google.iq/127.0.0.1#5335 +ipset=/google.iq/gfwlist +server=/strepsils.us/127.0.0.1#5335 +ipset=/strepsils.us/gfwlist +server=/xn--hhr917d3fecva.xyz/127.0.0.1#5335 +ipset=/xn--hhr917d3fecva.xyz/gfwlist +server=/ntdca.com/127.0.0.1#5335 +ipset=/ntdca.com/gfwlist +server=/grabpussy.com/127.0.0.1#5335 +ipset=/grabpussy.com/gfwlist +server=/strepsils.ro/127.0.0.1#5335 +ipset=/strepsils.ro/gfwlist +server=/strepsils.pl/127.0.0.1#5335 +ipset=/strepsils.pl/gfwlist +server=/strepsils.net/127.0.0.1#5335 +ipset=/strepsils.net/gfwlist +server=/sextubehub.com/127.0.0.1#5335 +ipset=/sextubehub.com/gfwlist +server=/strepsils.ie/127.0.0.1#5335 +ipset=/strepsils.ie/gfwlist +server=/strepsils.hu/127.0.0.1#5335 +ipset=/strepsils.hu/gfwlist +server=/javfv.com/127.0.0.1#5335 +ipset=/javfv.com/gfwlist +server=/vhx.tv/127.0.0.1#5335 +ipset=/vhx.tv/gfwlist +server=/strepsils.fr/127.0.0.1#5335 +ipset=/strepsils.fr/gfwlist +server=/strepsils.fi/127.0.0.1#5335 +ipset=/strepsils.fi/gfwlist +server=/strepsils.com.au/127.0.0.1#5335 +ipset=/strepsils.com.au/gfwlist +server=/bustynudebabes.com/127.0.0.1#5335 +ipset=/bustynudebabes.com/gfwlist +server=/mastercard.com.bh/127.0.0.1#5335 +ipset=/mastercard.com.bh/gfwlist +server=/getfappy.com/127.0.0.1#5335 +ipset=/getfappy.com/gfwlist +server=/strepsils.com.br/127.0.0.1#5335 +ipset=/strepsils.com.br/gfwlist +server=/strepsils.co.za/127.0.0.1#5335 +ipset=/strepsils.co.za/gfwlist +server=/cdninstagram.com/127.0.0.1#5335 +ipset=/cdninstagram.com/gfwlist +server=/strepsils.co.nz/127.0.0.1#5335 +ipset=/strepsils.co.nz/gfwlist +server=/thtmod1.com/127.0.0.1#5335 +ipset=/thtmod1.com/gfwlist +server=/dobendan.de/127.0.0.1#5335 +ipset=/dobendan.de/gfwlist +server=/cepacol.com/127.0.0.1#5335 +ipset=/cepacol.com/gfwlist +server=/beatsdresolo2013.com/127.0.0.1#5335 +ipset=/beatsdresolo2013.com/gfwlist +server=/minimoncton.com/127.0.0.1#5335 +ipset=/minimoncton.com/gfwlist +server=/linguee.com/127.0.0.1#5335 +ipset=/linguee.com/gfwlist +server=/nurofensk-prod-env.eu-west-1.elasticbeanstalk.com/127.0.0.1#5335 +ipset=/nurofensk-prod-env.eu-west-1.elasticbeanstalk.com/gfwlist +server=/nurofen.sk/127.0.0.1#5335 +ipset=/nurofen.sk/gfwlist +server=/nurofen.ro/127.0.0.1#5335 +ipset=/nurofen.ro/gfwlist +server=/cmhalq.com/127.0.0.1#5335 +ipset=/cmhalq.com/gfwlist +server=/nurofen.pt/127.0.0.1#5335 +ipset=/nurofen.pt/gfwlist +server=/icloud.jp/127.0.0.1#5335 +ipset=/icloud.jp/gfwlist +server=/nurofen.pl/127.0.0.1#5335 +ipset=/nurofen.pl/gfwlist +server=/desktopmovie.com/127.0.0.1#5335 +ipset=/desktopmovie.com/gfwlist +server=/bridgestone.co.cr/127.0.0.1#5335 +ipset=/bridgestone.co.cr/gfwlist +server=/hentaiasmr.moe/127.0.0.1#5335 +ipset=/hentaiasmr.moe/gfwlist +server=/nurofen.co.za/127.0.0.1#5335 +ipset=/nurofen.co.za/gfwlist +server=/beatbydrekopen.com/127.0.0.1#5335 +ipset=/beatbydrekopen.com/gfwlist +server=/puresexmovies.com/127.0.0.1#5335 +ipset=/puresexmovies.com/gfwlist +server=/dldlinks.com/127.0.0.1#5335 +ipset=/dldlinks.com/gfwlist +server=/sorcerersarena.com/127.0.0.1#5335 +ipset=/sorcerersarena.com/gfwlist +server=/nurofen.fr/127.0.0.1#5335 +ipset=/nurofen.fr/gfwlist +server=/sandisk.sg/127.0.0.1#5335 +ipset=/sandisk.sg/gfwlist +server=/nurofen.com.sg/127.0.0.1#5335 +ipset=/nurofen.com.sg/gfwlist +server=/w3schools.com/127.0.0.1#5335 +ipset=/w3schools.com/gfwlist +server=/nurofen.com.au/127.0.0.1#5335 +ipset=/nurofen.com.au/gfwlist +server=/nurofen.net/127.0.0.1#5335 +ipset=/nurofen.net/gfwlist +server=/faceboon.com/127.0.0.1#5335 +ipset=/faceboon.com/gfwlist +server=/google.com.mm/127.0.0.1#5335 +ipset=/google.com.mm/gfwlist +server=/myfreepaysite.com/127.0.0.1#5335 +ipset=/myfreepaysite.com/gfwlist +server=/nurofen.co.il/127.0.0.1#5335 +ipset=/nurofen.co.il/gfwlist +server=/mucinex.tv/127.0.0.1#5335 +ipset=/mucinex.tv/gfwlist +server=/mucinex.net/127.0.0.1#5335 +ipset=/mucinex.net/gfwlist +server=/mucinex.com/127.0.0.1#5335 +ipset=/mucinex.com/gfwlist +server=/faceidglobal.com/127.0.0.1#5335 +ipset=/faceidglobal.com/gfwlist +server=/vanish.com.ar/127.0.0.1#5335 +ipset=/vanish.com.ar/gfwlist +server=/schiffvitamins.com/127.0.0.1#5335 +ipset=/schiffvitamins.com/gfwlist +server=/bestialityvideo.us/127.0.0.1#5335 +ipset=/bestialityvideo.us/gfwlist +server=/pifpafarabia.com/127.0.0.1#5335 +ipset=/pifpafarabia.com/gfwlist +server=/toosexyvaginas.com/127.0.0.1#5335 +ipset=/toosexyvaginas.com/gfwlist +server=/cheapheadphonesland.com/127.0.0.1#5335 +ipset=/cheapheadphonesland.com/gfwlist +server=/iphone-x.tv/127.0.0.1#5335 +ipset=/iphone-x.tv/gfwlist +server=/playnft.es.ht/127.0.0.1#5335 +ipset=/playnft.es.ht/gfwlist +server=/toppornguide.com/127.0.0.1#5335 +ipset=/toppornguide.com/gfwlist +server=/mortein.com/127.0.0.1#5335 +ipset=/mortein.com/gfwlist +server=/foxsportsracing.com/127.0.0.1#5335 +ipset=/foxsportsracing.com/gfwlist +server=/akasha.world/127.0.0.1#5335 +ipset=/akasha.world/gfwlist +server=/meadjohnson.com.hk/127.0.0.1#5335 +ipset=/meadjohnson.com.hk/gfwlist +server=/intel.gr/127.0.0.1#5335 +ipset=/intel.gr/gfwlist +server=/meadjohnson.com/127.0.0.1#5335 +ipset=/meadjohnson.com/gfwlist +server=/sandisk.com.au/127.0.0.1#5335 +ipset=/sandisk.com.au/gfwlist +server=/lysol.ca/127.0.0.1#5335 +ipset=/lysol.ca/gfwlist +server=/finishinfo.fi/127.0.0.1#5335 +ipset=/finishinfo.fi/gfwlist +server=/finishinfo.com.ar/127.0.0.1#5335 +ipset=/finishinfo.com.ar/gfwlist +server=/mini.com.co/127.0.0.1#5335 +ipset=/mini.com.co/gfwlist +server=/registry.google/127.0.0.1#5335 +ipset=/registry.google/gfwlist +server=/finishdishwashing.com/127.0.0.1#5335 +ipset=/finishdishwashing.com/gfwlist +server=/whengirlsplay.com/127.0.0.1#5335 +ipset=/whengirlsplay.com/gfwlist +server=/finishdishwashing.ca/127.0.0.1#5335 +ipset=/finishdishwashing.ca/gfwlist +server=/finisharabia.com/127.0.0.1#5335 +ipset=/finisharabia.com/gfwlist +server=/myfoxboston.com/127.0.0.1#5335 +ipset=/myfoxboston.com/gfwlist +server=/finish.sk/127.0.0.1#5335 +ipset=/finish.sk/gfwlist +server=/japanfist.org/127.0.0.1#5335 +ipset=/japanfist.org/gfwlist +server=/finish.si/127.0.0.1#5335 +ipset=/finish.si/gfwlist +server=/perverse.sex/127.0.0.1#5335 +ipset=/perverse.sex/gfwlist +server=/youtube.com.gr/127.0.0.1#5335 +ipset=/youtube.com.gr/gfwlist +server=/infinitetube.com/127.0.0.1#5335 +ipset=/infinitetube.com/gfwlist +server=/bridgestonegolf.com/127.0.0.1#5335 +ipset=/bridgestonegolf.com/gfwlist +server=/finish.pl/127.0.0.1#5335 +ipset=/finish.pl/gfwlist +server=/finish.hu/127.0.0.1#5335 +ipset=/finish.hu/gfwlist +server=/prostores.com/127.0.0.1#5335 +ipset=/prostores.com/gfwlist +server=/finish.gr/127.0.0.1#5335 +ipset=/finish.gr/gfwlist +server=/grannylovesyoungcock.com/127.0.0.1#5335 +ipset=/grannylovesyoungcock.com/gfwlist +server=/finish.fr/127.0.0.1#5335 +ipset=/finish.fr/gfwlist +server=/finish.es/127.0.0.1#5335 +ipset=/finish.es/gfwlist +server=/finish.de/127.0.0.1#5335 +ipset=/finish.de/gfwlist +server=/hqporner.com/127.0.0.1#5335 +ipset=/hqporner.com/gfwlist +server=/google.co.vi/127.0.0.1#5335 +ipset=/google.co.vi/gfwlist +server=/finish.com.hr/127.0.0.1#5335 +ipset=/finish.com.hr/gfwlist +server=/yahoo.com.tr/127.0.0.1#5335 +ipset=/yahoo.com.tr/gfwlist +server=/finish.co.nz/127.0.0.1#5335 +ipset=/finish.co.nz/gfwlist +server=/youtube.com.bh/127.0.0.1#5335 +ipset=/youtube.com.bh/gfwlist +server=/wpewebkit.org/127.0.0.1#5335 +ipset=/wpewebkit.org/gfwlist +server=/buyminibeatbox.com/127.0.0.1#5335 +ipset=/buyminibeatbox.com/gfwlist +server=/pornobrasil.com/127.0.0.1#5335 +ipset=/pornobrasil.com/gfwlist +server=/nutramigen.pl/127.0.0.1#5335 +ipset=/nutramigen.pl/gfwlist +server=/pornoecuadorxxx.com/127.0.0.1#5335 +ipset=/pornoecuadorxxx.com/gfwlist +server=/enspireformula.com/127.0.0.1#5335 +ipset=/enspireformula.com/gfwlist +server=/huobiasia.vip/127.0.0.1#5335 +ipset=/huobiasia.vip/gfwlist +server=/enfamil.pt/127.0.0.1#5335 +ipset=/enfamil.pt/gfwlist +server=/enfamil.ca/127.0.0.1#5335 +ipset=/enfamil.ca/gfwlist +server=/enfamama.com.ph/127.0.0.1#5335 +ipset=/enfamama.com.ph/gfwlist +server=/facebooll.com/127.0.0.1#5335 +ipset=/facebooll.com/gfwlist +server=/thomsonreuters.ca/127.0.0.1#5335 +ipset=/thomsonreuters.ca/gfwlist +server=/enfagrow.com.sg/127.0.0.1#5335 +ipset=/enfagrow.com.sg/gfwlist +server=/enfagrow.com.my/127.0.0.1#5335 +ipset=/enfagrow.com.my/gfwlist +server=/applestore.net.gr/127.0.0.1#5335 +ipset=/applestore.net.gr/gfwlist +server=/enfagrow.co.in/127.0.0.1#5335 +ipset=/enfagrow.co.in/gfwlist +server=/enfabebe3.com.ar/127.0.0.1#5335 +ipset=/enfabebe3.com.ar/gfwlist +server=/mini.at/127.0.0.1#5335 +ipset=/mini.at/gfwlist +server=/sexhd.pics/127.0.0.1#5335 +ipset=/sexhd.pics/gfwlist +server=/hentaiplay.net/127.0.0.1#5335 +ipset=/hentaiplay.net/gfwlist +server=/enfabebe.com.ve/127.0.0.1#5335 +ipset=/enfabebe.com.ve/gfwlist +server=/enfabebe.com.pe/127.0.0.1#5335 +ipset=/enfabebe.com.pe/gfwlist +server=/enfabebe.com.ec/127.0.0.1#5335 +ipset=/enfabebe.com.ec/gfwlist +server=/enfabebe.com.co/127.0.0.1#5335 +ipset=/enfabebe.com.co/gfwlist +server=/enfabebe.com.br/127.0.0.1#5335 +ipset=/enfabebe.com.br/gfwlist +server=/enfababy.com/127.0.0.1#5335 +ipset=/enfababy.com/gfwlist +server=/enfaaplus.com/127.0.0.1#5335 +ipset=/enfaaplus.com/gfwlist +server=/xxxn.tv/127.0.0.1#5335 +ipset=/xxxn.tv/gfwlist +server=/enfa.co.id/127.0.0.1#5335 +ipset=/enfa.co.id/gfwlist +server=/zoos.gold/127.0.0.1#5335 +ipset=/zoos.gold/gfwlist +server=/bannedbook.org/127.0.0.1#5335 +ipset=/bannedbook.org/gfwlist +server=/bebepremium3.com.bo/127.0.0.1#5335 +ipset=/bebepremium3.com.bo/gfwlist +server=/mrpinks.com/127.0.0.1#5335 +ipset=/mrpinks.com/gfwlist +server=/drdreheadphonebeats.com/127.0.0.1#5335 +ipset=/drdreheadphonebeats.com/gfwlist +server=/trydurex.tv/127.0.0.1#5335 +ipset=/trydurex.tv/gfwlist +server=/trydurex.net/127.0.0.1#5335 +ipset=/trydurex.net/gfwlist +server=/hooloo.tv/127.0.0.1#5335 +ipset=/hooloo.tv/gfwlist +server=/playbydurex.com/127.0.0.1#5335 +ipset=/playbydurex.com/gfwlist +server=/durexchina.com/127.0.0.1#5335 +ipset=/durexchina.com/gfwlist +server=/brutalfetish.com/127.0.0.1#5335 +ipset=/brutalfetish.com/gfwlist +server=/microsoft.it/127.0.0.1#5335 +ipset=/microsoft.it/gfwlist +server=/durexcam.com/127.0.0.1#5335 +ipset=/durexcam.com/gfwlist +server=/amateurarchiver.com/127.0.0.1#5335 +ipset=/amateurarchiver.com/gfwlist +server=/hentai4free.net/127.0.0.1#5335 +ipset=/hentai4free.net/gfwlist +server=/gputechconf.com.tw/127.0.0.1#5335 +ipset=/gputechconf.com.tw/gfwlist +server=/dodgersexcartoons.com/127.0.0.1#5335 +ipset=/dodgersexcartoons.com/gfwlist +server=/watchinese.com/127.0.0.1#5335 +ipset=/watchinese.com/gfwlist +server=/quanben.io/127.0.0.1#5335 +ipset=/quanben.io/gfwlist +server=/docs.com/127.0.0.1#5335 +ipset=/docs.com/gfwlist +server=/marketo.net/127.0.0.1#5335 +ipset=/marketo.net/gfwlist +server=/xxx-videos.tv/127.0.0.1#5335 +ipset=/xxx-videos.tv/gfwlist +server=/durex.mx/127.0.0.1#5335 +ipset=/durex.mx/gfwlist +server=/awsedstart.com/127.0.0.1#5335 +ipset=/awsedstart.com/gfwlist +server=/google.bf/127.0.0.1#5335 +ipset=/google.bf/gfwlist +server=/durex.it/127.0.0.1#5335 +ipset=/durex.it/gfwlist +server=/durex.hu/127.0.0.1#5335 +ipset=/durex.hu/gfwlist +server=/rolls-roycecullinan.com/127.0.0.1#5335 +ipset=/rolls-roycecullinan.com/gfwlist +server=/starbucks.com.ar/127.0.0.1#5335 +ipset=/starbucks.com.ar/gfwlist +server=/amateuranalporn.com/127.0.0.1#5335 +ipset=/amateuranalporn.com/gfwlist +server=/mcdonaldsarabia.com/127.0.0.1#5335 +ipset=/mcdonaldsarabia.com/gfwlist +server=/bmw-motorsport.com/127.0.0.1#5335 +ipset=/bmw-motorsport.com/gfwlist +server=/durex.fi/127.0.0.1#5335 +ipset=/durex.fi/gfwlist +server=/durex.ee/127.0.0.1#5335 +ipset=/durex.ee/gfwlist +server=/verisign.biz/127.0.0.1#5335 +ipset=/verisign.biz/gfwlist +server=/durex.de/127.0.0.1#5335 +ipset=/durex.de/gfwlist +server=/jetbrains.net/127.0.0.1#5335 +ipset=/jetbrains.net/gfwlist +server=/elixir-lang.org/127.0.0.1#5335 +ipset=/elixir-lang.org/gfwlist +server=/fap666.com/127.0.0.1#5335 +ipset=/fap666.com/gfwlist +server=/durex.com.pk/127.0.0.1#5335 +ipset=/durex.com.pk/gfwlist +server=/durex.com.ph/127.0.0.1#5335 +ipset=/durex.com.ph/gfwlist +server=/intel.yt/127.0.0.1#5335 +ipset=/intel.yt/gfwlist +server=/naughtymag.com/127.0.0.1#5335 +ipset=/naughtymag.com/gfwlist +server=/adhelpnews.com/127.0.0.1#5335 +ipset=/adhelpnews.com/gfwlist +server=/durex.com.bd/127.0.0.1#5335 +ipset=/durex.com.bd/gfwlist +server=/bmw.cz/127.0.0.1#5335 +ipset=/bmw.cz/gfwlist +server=/visiontimesjp.com/127.0.0.1#5335 +ipset=/visiontimesjp.com/gfwlist +server=/durex.com.au/127.0.0.1#5335 +ipset=/durex.com.au/gfwlist +server=/disney.com.hk/127.0.0.1#5335 +ipset=/disney.com.hk/gfwlist +server=/2buybeatsbydre.com/127.0.0.1#5335 +ipset=/2buybeatsbydre.com/gfwlist +server=/durex.co.uk/127.0.0.1#5335 +ipset=/durex.co.uk/gfwlist +server=/durex.co.id/127.0.0.1#5335 +ipset=/durex.co.id/gfwlist +server=/aimsciences.org/127.0.0.1#5335 +ipset=/aimsciences.org/gfwlist +server=/popcap.com/127.0.0.1#5335 +ipset=/popcap.com/gfwlist +server=/iphoneclaro.com.br/127.0.0.1#5335 +ipset=/iphoneclaro.com.br/gfwlist +server=/durex.be/127.0.0.1#5335 +ipset=/durex.be/gfwlist +server=/durex.at/127.0.0.1#5335 +ipset=/durex.at/gfwlist +server=/economistgroup.com/127.0.0.1#5335 +ipset=/economistgroup.com/gfwlist +server=/pricelesshonolulu.com/127.0.0.1#5335 +ipset=/pricelesshonolulu.com/gfwlist +server=/durex-shopline.com/127.0.0.1#5335 +ipset=/durex-shopline.com/gfwlist +server=/dotherex.com/127.0.0.1#5335 +ipset=/dotherex.com/gfwlist +server=/dewitwithdurex.com/127.0.0.1#5335 +ipset=/dewitwithdurex.com/gfwlist +server=/bloomberglive.com/127.0.0.1#5335 +ipset=/bloomberglive.com/gfwlist +server=/parler.com/127.0.0.1#5335 +ipset=/parler.com/gfwlist +server=/bmw.cw/127.0.0.1#5335 +ipset=/bmw.cw/gfwlist +server=/dettolcleannaija.com/127.0.0.1#5335 +ipset=/dettolcleannaija.com/gfwlist +server=/dettol.ru/127.0.0.1#5335 +ipset=/dettol.ru/gfwlist +server=/dettol.pl/127.0.0.1#5335 +ipset=/dettol.pl/gfwlist +server=/dettol.pk/127.0.0.1#5335 +ipset=/dettol.pk/gfwlist +server=/dettol.nl/127.0.0.1#5335 +ipset=/dettol.nl/gfwlist +server=/dettol.fr/127.0.0.1#5335 +ipset=/dettol.fr/gfwlist +server=/dettol.com.ng/127.0.0.1#5335 +ipset=/dettol.com.ng/gfwlist +server=/dettol.com.eg/127.0.0.1#5335 +ipset=/dettol.com.eg/gfwlist +server=/dettol.com.bd/127.0.0.1#5335 +ipset=/dettol.com.bd/gfwlist +server=/dettol.com/127.0.0.1#5335 +ipset=/dettol.com/gfwlist +server=/dettol.co.uk/127.0.0.1#5335 +ipset=/dettol.co.uk/gfwlist +server=/dettol.co.in/127.0.0.1#5335 +ipset=/dettol.co.in/gfwlist +server=/dettol.at/127.0.0.1#5335 +ipset=/dettol.at/gfwlist +server=/dettol-prize.com/127.0.0.1#5335 +ipset=/dettol-prize.com/gfwlist +server=/paypalbrasil.com/127.0.0.1#5335 +ipset=/paypalbrasil.com/gfwlist +server=/calgon.nl/127.0.0.1#5335 +ipset=/calgon.nl/gfwlist +server=/goldsexvideos.com/127.0.0.1#5335 +ipset=/goldsexvideos.com/gfwlist +server=/calgon.it/127.0.0.1#5335 +ipset=/calgon.it/gfwlist +server=/calgon.ie/127.0.0.1#5335 +ipset=/calgon.ie/gfwlist +server=/cht.com.tw/127.0.0.1#5335 +ipset=/cht.com.tw/gfwlist +server=/calgon.es/127.0.0.1#5335 +ipset=/calgon.es/gfwlist +server=/famousinternetgirlsgalleries.com/127.0.0.1#5335 +ipset=/famousinternetgirlsgalleries.com/gfwlist +server=/calgon.de/127.0.0.1#5335 +ipset=/calgon.de/gfwlist +server=/swiftbank.info/127.0.0.1#5335 +ipset=/swiftbank.info/gfwlist +server=/calgon.com.tr/127.0.0.1#5335 +ipset=/calgon.com.tr/gfwlist +server=/yahoo.com.nf/127.0.0.1#5335 +ipset=/yahoo.com.nf/gfwlist +server=/mastercardrestaurant.com/127.0.0.1#5335 +ipset=/mastercardrestaurant.com/gfwlist +server=/gamer.com.tw/127.0.0.1#5335 +ipset=/gamer.com.tw/gfwlist +server=/calgon.com/127.0.0.1#5335 +ipset=/calgon.com/gfwlist +server=/calgon.co.uk/127.0.0.1#5335 +ipset=/calgon.co.uk/gfwlist +server=/calgon.be/127.0.0.1#5335 +ipset=/calgon.be/gfwlist +server=/mobatek.net/127.0.0.1#5335 +ipset=/mobatek.net/gfwlist +server=/nvidia.com.pe/127.0.0.1#5335 +ipset=/nvidia.com.pe/gfwlist +server=/calgon.at/127.0.0.1#5335 +ipset=/calgon.at/gfwlist +server=/iphone-sh.com/127.0.0.1#5335 +ipset=/iphone-sh.com/gfwlist +server=/dotfreesex.com/127.0.0.1#5335 +ipset=/dotfreesex.com/gfwlist +server=/ipadair.com.es/127.0.0.1#5335 +ipset=/ipadair.com.es/gfwlist +server=/airwickarabia.com/127.0.0.1#5335 +ipset=/airwickarabia.com/gfwlist +server=/vfsco.mx/127.0.0.1#5335 +ipset=/vfsco.mx/gfwlist +server=/airwick.tv/127.0.0.1#5335 +ipset=/airwick.tv/gfwlist +server=/google.st/127.0.0.1#5335 +ipset=/google.st/gfwlist +server=/macbookair.jp/127.0.0.1#5335 +ipset=/macbookair.jp/gfwlist +server=/airwick.se/127.0.0.1#5335 +ipset=/airwick.se/gfwlist +server=/airwick.ru/127.0.0.1#5335 +ipset=/airwick.ru/gfwlist +server=/airwick.no/127.0.0.1#5335 +ipset=/airwick.no/gfwlist +server=/oxfordreference.com/127.0.0.1#5335 +ipset=/oxfordreference.com/gfwlist +server=/hotnudegirls.net/127.0.0.1#5335 +ipset=/hotnudegirls.net/gfwlist +server=/applecentar.rs/127.0.0.1#5335 +ipset=/applecentar.rs/gfwlist +server=/google.com.bz/127.0.0.1#5335 +ipset=/google.com.bz/gfwlist +server=/applestore.wang/127.0.0.1#5335 +ipset=/applestore.wang/gfwlist +server=/airwick.net/127.0.0.1#5335 +ipset=/airwick.net/gfwlist +server=/wifesexorgy.com/127.0.0.1#5335 +ipset=/wifesexorgy.com/gfwlist +server=/foxcorporation.com/127.0.0.1#5335 +ipset=/foxcorporation.com/gfwlist +server=/volvopenta.nl/127.0.0.1#5335 +ipset=/volvopenta.nl/gfwlist +server=/microsoft-give.com/127.0.0.1#5335 +ipset=/microsoft-give.com/gfwlist +server=/apple-online.com/127.0.0.1#5335 +ipset=/apple-online.com/gfwlist +server=/airwick.ie/127.0.0.1#5335 +ipset=/airwick.ie/gfwlist +server=/cheaperbeatsbydresale.com/127.0.0.1#5335 +ipset=/cheaperbeatsbydresale.com/gfwlist +server=/ethiosex2.wordpress.com/127.0.0.1#5335 +ipset=/ethiosex2.wordpress.com/gfwlist +server=/taknai.com/127.0.0.1#5335 +ipset=/taknai.com/gfwlist +server=/kobbeatssbydredk.com/127.0.0.1#5335 +ipset=/kobbeatssbydredk.com/gfwlist +server=/sony.ie/127.0.0.1#5335 +ipset=/sony.ie/gfwlist +server=/airwick.hr/127.0.0.1#5335 +ipset=/airwick.hr/gfwlist +server=/rarbgmirror.org/127.0.0.1#5335 +ipset=/rarbgmirror.org/gfwlist +server=/airwick.fr/127.0.0.1#5335 +ipset=/airwick.fr/gfwlist +server=/airwick.fi/127.0.0.1#5335 +ipset=/airwick.fi/gfwlist +server=/airwick.dk/127.0.0.1#5335 +ipset=/airwick.dk/gfwlist +server=/redtub3xxx.com/127.0.0.1#5335 +ipset=/redtub3xxx.com/gfwlist +server=/airwick.cz/127.0.0.1#5335 +ipset=/airwick.cz/gfwlist +server=/airwick.com.tr/127.0.0.1#5335 +ipset=/airwick.com.tr/gfwlist +server=/airwick.com.mx/127.0.0.1#5335 +ipset=/airwick.com.mx/gfwlist +server=/chinesespanking.com/127.0.0.1#5335 +ipset=/chinesespanking.com/gfwlist +server=/airwick.com/127.0.0.1#5335 +ipset=/airwick.com/gfwlist +server=/airwick.co.za/127.0.0.1#5335 +ipset=/airwick.co.za/gfwlist +server=/universalpictures.com/127.0.0.1#5335 +ipset=/universalpictures.com/gfwlist +server=/ktvu.com/127.0.0.1#5335 +ipset=/ktvu.com/gfwlist +server=/fafacebook.com/127.0.0.1#5335 +ipset=/fafacebook.com/gfwlist +server=/hpjav.tv/127.0.0.1#5335 +ipset=/hpjav.tv/gfwlist +server=/xn--qhrx81fxh2a.xn--55qx5d.hk/127.0.0.1#5335 +ipset=/xn--qhrx81fxh2a.xn--55qx5d.hk/gfwlist +server=/stackpath.dev/127.0.0.1#5335 +ipset=/stackpath.dev/gfwlist +server=/cnnmoney.ch/127.0.0.1#5335 +ipset=/cnnmoney.ch/gfwlist +server=/steamusercontent-a.akamaihd.net/127.0.0.1#5335 +ipset=/steamusercontent-a.akamaihd.net/gfwlist +server=/akafms.net/127.0.0.1#5335 +ipset=/akafms.net/gfwlist +server=/amazonliterarypartnership.com/127.0.0.1#5335 +ipset=/amazonliterarypartnership.com/gfwlist +server=/mcdonalds.co.uk/127.0.0.1#5335 +ipset=/mcdonalds.co.uk/gfwlist +server=/golang.net/127.0.0.1#5335 +ipset=/golang.net/gfwlist +server=/mcdelivery.com.sg/127.0.0.1#5335 +ipset=/mcdelivery.com.sg/gfwlist +server=/doubleclick.net/127.0.0.1#5335 +ipset=/doubleclick.net/gfwlist +server=/instagor.com/127.0.0.1#5335 +ipset=/instagor.com/gfwlist +server=/aboutmcdonalds.com/127.0.0.1#5335 +ipset=/aboutmcdonalds.com/gfwlist +server=/huanghuagang.org/127.0.0.1#5335 +ipset=/huanghuagang.org/gfwlist +server=/hkreadingcity.net/127.0.0.1#5335 +ipset=/hkreadingcity.net/gfwlist +server=/xn--r8jwklh769h2mc880dk1o431a.com/127.0.0.1#5335 +ipset=/xn--r8jwklh769h2mc880dk1o431a.com/gfwlist +server=/fffdm.com/127.0.0.1#5335 +ipset=/fffdm.com/gfwlist +server=/fzdm.com/127.0.0.1#5335 +ipset=/fzdm.com/gfwlist +server=/familymart.com.ph/127.0.0.1#5335 +ipset=/familymart.com.ph/gfwlist +server=/ebayedu.com/127.0.0.1#5335 +ipset=/ebayedu.com/gfwlist +server=/mastercard.com.tr/127.0.0.1#5335 +ipset=/mastercard.com.tr/gfwlist +server=/family.com.tw/127.0.0.1#5335 +ipset=/family.com.tw/gfwlist +server=/apina.biz/127.0.0.1#5335 +ipset=/apina.biz/gfwlist +server=/ikea.it/127.0.0.1#5335 +ipset=/ikea.it/gfwlist +server=/esp8266.com/127.0.0.1#5335 +ipset=/esp8266.com/gfwlist +server=/nijiyome.jp/127.0.0.1#5335 +ipset=/nijiyome.jp/gfwlist +server=/dlsite.com.tw/127.0.0.1#5335 +ipset=/dlsite.com.tw/gfwlist +server=/dlsite.com/127.0.0.1#5335 +ipset=/dlsite.com/gfwlist +server=/ci-en.net/127.0.0.1#5335 +ipset=/ci-en.net/gfwlist +server=/sankeibiz.jp/127.0.0.1#5335 +ipset=/sankeibiz.jp/gfwlist +server=/114av.xyz/127.0.0.1#5335 +ipset=/114av.xyz/gfwlist +server=/swtor.net/127.0.0.1#5335 +ipset=/swtor.net/gfwlist +server=/lilith-soft.com/127.0.0.1#5335 +ipset=/lilith-soft.com/gfwlist +server=/fackebook.com/127.0.0.1#5335 +ipset=/fackebook.com/gfwlist +server=/itasoftware.com/127.0.0.1#5335 +ipset=/itasoftware.com/gfwlist +server=/avxhm.is/127.0.0.1#5335 +ipset=/avxhm.is/gfwlist +server=/beatsbydrdreus.com/127.0.0.1#5335 +ipset=/beatsbydrdreus.com/gfwlist +server=/paipal.com/127.0.0.1#5335 +ipset=/paipal.com/gfwlist +server=/foxcincy.jobs/127.0.0.1#5335 +ipset=/foxcincy.jobs/gfwlist +server=/youtube.com.gh/127.0.0.1#5335 +ipset=/youtube.com.gh/gfwlist +server=/toolforge.org/127.0.0.1#5335 +ipset=/toolforge.org/gfwlist +server=/wiktionary.org/127.0.0.1#5335 +ipset=/wiktionary.org/gfwlist +server=/globalsign.com.hk/127.0.0.1#5335 +ipset=/globalsign.com.hk/gfwlist +server=/wikivoyage.org/127.0.0.1#5335 +ipset=/wikivoyage.org/gfwlist +server=/expresswifi.com/127.0.0.1#5335 +ipset=/expresswifi.com/gfwlist +server=/exascale-tech.com/127.0.0.1#5335 +ipset=/exascale-tech.com/gfwlist +server=/wikiversity.org/127.0.0.1#5335 +ipset=/wikiversity.org/gfwlist +server=/wikisource.org/127.0.0.1#5335 +ipset=/wikisource.org/gfwlist +server=/wikipedia.org/127.0.0.1#5335 +ipset=/wikipedia.org/gfwlist +server=/cinepornogratis.com/127.0.0.1#5335 +ipset=/cinepornogratis.com/gfwlist +server=/sexharlot.com/127.0.0.1#5335 +ipset=/sexharlot.com/gfwlist +server=/wikimedia.org/127.0.0.1#5335 +ipset=/wikimedia.org/gfwlist +server=/wikimediafoundation.org/127.0.0.1#5335 +ipset=/wikimediafoundation.org/gfwlist +server=/truyenkk1.com/127.0.0.1#5335 +ipset=/truyenkk1.com/gfwlist +server=/wikidata.org/127.0.0.1#5335 +ipset=/wikidata.org/gfwlist +server=/wikibooks.org/127.0.0.1#5335 +ipset=/wikibooks.org/gfwlist +server=/ebc.net.tw/127.0.0.1#5335 +ipset=/ebc.net.tw/gfwlist +server=/starbucksrewardsstarland.ca/127.0.0.1#5335 +ipset=/starbucksrewardsstarland.ca/gfwlist +server=/wdfiles.com/127.0.0.1#5335 +ipset=/wdfiles.com/gfwlist +server=/nftstorage.link/127.0.0.1#5335 +ipset=/nftstorage.link/gfwlist +server=/firstgynexam.com/127.0.0.1#5335 +ipset=/firstgynexam.com/gfwlist +server=/twcomix.com/127.0.0.1#5335 +ipset=/twcomix.com/gfwlist +server=/wholesaleonlinemart.com/127.0.0.1#5335 +ipset=/wholesaleonlinemart.com/gfwlist +server=/cortexrpg.com/127.0.0.1#5335 +ipset=/cortexrpg.com/gfwlist +server=/muthead.com/127.0.0.1#5335 +ipset=/muthead.com/gfwlist +server=/beatscheapforsale.com/127.0.0.1#5335 +ipset=/beatscheapforsale.com/gfwlist +server=/hutao.cloud/127.0.0.1#5335 +ipset=/hutao.cloud/gfwlist +server=/disney.hu/127.0.0.1#5335 +ipset=/disney.hu/gfwlist +server=/sweetsext.com/127.0.0.1#5335 +ipset=/sweetsext.com/gfwlist +server=/yabang.org/127.0.0.1#5335 +ipset=/yabang.org/gfwlist +server=/bmw-connecteddrive.es/127.0.0.1#5335 +ipset=/bmw-connecteddrive.es/gfwlist +server=/pornkai.com/127.0.0.1#5335 +ipset=/pornkai.com/gfwlist +server=/zeeentertainment.com/127.0.0.1#5335 +ipset=/zeeentertainment.com/gfwlist +server=/stc-server.com/127.0.0.1#5335 +ipset=/stc-server.com/gfwlist +server=/paper-attachments.s3.amazonaws.com/127.0.0.1#5335 +ipset=/paper-attachments.s3.amazonaws.com/gfwlist +server=/mailonsunday.ie/127.0.0.1#5335 +ipset=/mailonsunday.ie/gfwlist +server=/ssrpass.pw/127.0.0.1#5335 +ipset=/ssrpass.pw/gfwlist +server=/bmwmyanmar.com/127.0.0.1#5335 +ipset=/bmwmyanmar.com/gfwlist +server=/ssplive.pw/127.0.0.1#5335 +ipset=/ssplive.pw/gfwlist +server=/visa.lt/127.0.0.1#5335 +ipset=/visa.lt/gfwlist +server=/sony.com.gt/127.0.0.1#5335 +ipset=/sony.com.gt/gfwlist +server=/maying.co/127.0.0.1#5335 +ipset=/maying.co/gfwlist +server=/vaultify.net/127.0.0.1#5335 +ipset=/vaultify.net/gfwlist +server=/intel.wf/127.0.0.1#5335 +ipset=/intel.wf/gfwlist +server=/gfw.press/127.0.0.1#5335 +ipset=/gfw.press/gfwlist +server=/geph.io/127.0.0.1#5335 +ipset=/geph.io/gfwlist +server=/hottestheadphonesonline.com/127.0.0.1#5335 +ipset=/hottestheadphonesonline.com/gfwlist +server=/acheterfollowersinstagram.com/127.0.0.1#5335 +ipset=/acheterfollowersinstagram.com/gfwlist +server=/cloudn.me/127.0.0.1#5335 +ipset=/cloudn.me/gfwlist +server=/pinflix.com/127.0.0.1#5335 +ipset=/pinflix.com/gfwlist +server=/ark.to/127.0.0.1#5335 +ipset=/ark.to/gfwlist +server=/amytele.com/127.0.0.1#5335 +ipset=/amytele.com/gfwlist +server=/aaex.uk/127.0.0.1#5335 +ipset=/aaex.uk/gfwlist +server=/slack.com/127.0.0.1#5335 +ipset=/slack.com/gfwlist +server=/xcg123.com/127.0.0.1#5335 +ipset=/xcg123.com/gfwlist +server=/vilavpn7.xyz/127.0.0.1#5335 +ipset=/vilavpn7.xyz/gfwlist +server=/vilavpn5.xyz/127.0.0.1#5335 +ipset=/vilavpn5.xyz/gfwlist +server=/vilavpn4.xyz/127.0.0.1#5335 +ipset=/vilavpn4.xyz/gfwlist +server=/msfteducation.ca/127.0.0.1#5335 +ipset=/msfteducation.ca/gfwlist +server=/mastercard.ru/127.0.0.1#5335 +ipset=/mastercard.ru/gfwlist +server=/nvidia.co.jp/127.0.0.1#5335 +ipset=/nvidia.co.jp/gfwlist +server=/vilavpn1.xyz/127.0.0.1#5335 +ipset=/vilavpn1.xyz/gfwlist +server=/watchdisneyfe.com/127.0.0.1#5335 +ipset=/watchdisneyfe.com/gfwlist +server=/surflite.net/127.0.0.1#5335 +ipset=/surflite.net/gfwlist +server=/molesports.com/127.0.0.1#5335 +ipset=/molesports.com/gfwlist +server=/visa.com.ag/127.0.0.1#5335 +ipset=/visa.com.ag/gfwlist +server=/geek-squad.org/127.0.0.1#5335 +ipset=/geek-squad.org/gfwlist +server=/swisstsa.ch/127.0.0.1#5335 +ipset=/swisstsa.ch/gfwlist +server=/crunchyroll.com/127.0.0.1#5335 +ipset=/crunchyroll.com/gfwlist +server=/nexitcore.com/127.0.0.1#5335 +ipset=/nexitcore.com/gfwlist +server=/sexfilm.al.ru/127.0.0.1#5335 +ipset=/sexfilm.al.ru/gfwlist +server=/nexitallysafe.com/127.0.0.1#5335 +ipset=/nexitallysafe.com/gfwlist +server=/intel.mn/127.0.0.1#5335 +ipset=/intel.mn/gfwlist +server=/gog-statics.com/127.0.0.1#5335 +ipset=/gog-statics.com/gfwlist +server=/n3ro.net/127.0.0.1#5335 +ipset=/n3ro.net/gfwlist +server=/n3ro.lol/127.0.0.1#5335 +ipset=/n3ro.lol/gfwlist +server=/justmysocks2.net/127.0.0.1#5335 +ipset=/justmysocks2.net/gfwlist +server=/justmysocks.net/127.0.0.1#5335 +ipset=/justmysocks.net/gfwlist +server=/hitun.io/127.0.0.1#5335 +ipset=/hitun.io/gfwlist +server=/duyaossr.com/127.0.0.1#5335 +ipset=/duyaossr.com/gfwlist +server=/dleris.best/127.0.0.1#5335 +ipset=/dleris.best/gfwlist +server=/dlercloud.me/127.0.0.1#5335 +ipset=/dlercloud.me/gfwlist +server=/gyakusimei.com/127.0.0.1#5335 +ipset=/gyakusimei.com/gfwlist +server=/cortanaskills.com/127.0.0.1#5335 +ipset=/cortanaskills.com/gfwlist +server=/youtube.com.sa/127.0.0.1#5335 +ipset=/youtube.com.sa/gfwlist +server=/cylink.pro/127.0.0.1#5335 +ipset=/cylink.pro/gfwlist +server=/geeksquad.cc/127.0.0.1#5335 +ipset=/geeksquad.cc/gfwlist +server=/bmw-motorrad-abudhabi.com/127.0.0.1#5335 +ipset=/bmw-motorrad-abudhabi.com/gfwlist +server=/ubisoft-orbit-savegames.s3.amazonaws.com/127.0.0.1#5335 +ipset=/ubisoft-orbit-savegames.s3.amazonaws.com/gfwlist +server=/twinkboyfriends.tv/127.0.0.1#5335 +ipset=/twinkboyfriends.tv/gfwlist +server=/googleblog.com/127.0.0.1#5335 +ipset=/googleblog.com/gfwlist +server=/hpgift.com/127.0.0.1#5335 +ipset=/hpgift.com/gfwlist +server=/springerlink.com/127.0.0.1#5335 +ipset=/springerlink.com/gfwlist +server=/geodesummit.com/127.0.0.1#5335 +ipset=/geodesummit.com/gfwlist +server=/rarbgunblock.com/127.0.0.1#5335 +ipset=/rarbgunblock.com/gfwlist +server=/youtubei.googleapis.com/127.0.0.1#5335 +ipset=/youtubei.googleapis.com/gfwlist +server=/escapestudios.co.uk/127.0.0.1#5335 +ipset=/escapestudios.co.uk/gfwlist +server=/yimg.com/127.0.0.1#5335 +ipset=/yimg.com/gfwlist +server=/rarbgproxy.org/127.0.0.1#5335 +ipset=/rarbgproxy.org/gfwlist +server=/rarbgaccessed.org/127.0.0.1#5335 +ipset=/rarbgaccessed.org/gfwlist +server=/proxyrarbg.org/127.0.0.1#5335 +ipset=/proxyrarbg.org/gfwlist +server=/mamacitaz.com/127.0.0.1#5335 +ipset=/mamacitaz.com/gfwlist +server=/shapelcounset.xyz/127.0.0.1#5335 +ipset=/shapelcounset.xyz/gfwlist +server=/xdporner.com/127.0.0.1#5335 +ipset=/xdporner.com/gfwlist +server=/pornhub00.com/127.0.0.1#5335 +ipset=/pornhub00.com/gfwlist +server=/xjavporn.com/127.0.0.1#5335 +ipset=/xjavporn.com/gfwlist +server=/rarbg.to/127.0.0.1#5335 +ipset=/rarbg.to/gfwlist +server=/thepiratebay.org/127.0.0.1#5335 +ipset=/thepiratebay.org/gfwlist +server=/gayforit.eu/127.0.0.1#5335 +ipset=/gayforit.eu/gfwlist +server=/pirates-forum.org/127.0.0.1#5335 +ipset=/pirates-forum.org/gfwlist +server=/mastercard.com.ge/127.0.0.1#5335 +ipset=/mastercard.com.ge/gfwlist +server=/demonoid.is/127.0.0.1#5335 +ipset=/demonoid.is/gfwlist +server=/btdig.com/127.0.0.1#5335 +ipset=/btdig.com/gfwlist +server=/porntitan.com/127.0.0.1#5335 +ipset=/porntitan.com/gfwlist +server=/1337x.tw/127.0.0.1#5335 +ipset=/1337x.tw/gfwlist +server=/1337x.st/127.0.0.1#5335 +ipset=/1337x.st/gfwlist +server=/truyenwk.com/127.0.0.1#5335 +ipset=/truyenwk.com/gfwlist +server=/1337x.to/127.0.0.1#5335 +ipset=/1337x.to/gfwlist +server=/porkbun.com/127.0.0.1#5335 +ipset=/porkbun.com/gfwlist +server=/volvotrucks.kz/127.0.0.1#5335 +ipset=/volvotrucks.kz/gfwlist +server=/yastatic.net/127.0.0.1#5335 +ipset=/yastatic.net/gfwlist +server=/fcebook.com/127.0.0.1#5335 +ipset=/fcebook.com/gfwlist +server=/ebayaustralia.com/127.0.0.1#5335 +ipset=/ebayaustralia.com/gfwlist +server=/binanceapi.com/127.0.0.1#5335 +ipset=/binanceapi.com/gfwlist +server=/yandex.tm/127.0.0.1#5335 +ipset=/yandex.tm/gfwlist +server=/yandex.net/127.0.0.1#5335 +ipset=/yandex.net/gfwlist +server=/yandex.md/127.0.0.1#5335 +ipset=/yandex.md/gfwlist +server=/cnnikebrand.com/127.0.0.1#5335 +ipset=/cnnikebrand.com/gfwlist +server=/porndish.com/127.0.0.1#5335 +ipset=/porndish.com/gfwlist +server=/yandex.kg/127.0.0.1#5335 +ipset=/yandex.kg/gfwlist +server=/yandex.com.tr/127.0.0.1#5335 +ipset=/yandex.com.tr/gfwlist +server=/yandex.com.ru/127.0.0.1#5335 +ipset=/yandex.com.ru/gfwlist +server=/looporn.com/127.0.0.1#5335 +ipset=/looporn.com/gfwlist +server=/yandex.com/127.0.0.1#5335 +ipset=/yandex.com/gfwlist +server=/yandex.by/127.0.0.1#5335 +ipset=/yandex.by/gfwlist +server=/yandex.az/127.0.0.1#5335 +ipset=/yandex.az/gfwlist +server=/alicloud.com/127.0.0.1#5335 +ipset=/alicloud.com/gfwlist +server=/elephantsdream.org/127.0.0.1#5335 +ipset=/elephantsdream.org/gfwlist +server=/yimg.jp/127.0.0.1#5335 +ipset=/yimg.jp/gfwlist +server=/rarbgprx.org/127.0.0.1#5335 +ipset=/rarbgprx.org/gfwlist +server=/yho.com/127.0.0.1#5335 +ipset=/yho.com/gfwlist +server=/yahoomusic.com/127.0.0.1#5335 +ipset=/yahoomusic.com/gfwlist +server=/xvxx.stream/127.0.0.1#5335 +ipset=/xvxx.stream/gfwlist +server=/yahoohealth.com/127.0.0.1#5335 +ipset=/yahoohealth.com/gfwlist +server=/kavkazr.com/127.0.0.1#5335 +ipset=/kavkazr.com/gfwlist +server=/nikeitaly.com/127.0.0.1#5335 +ipset=/nikeitaly.com/gfwlist +server=/yahooapis.com/127.0.0.1#5335 +ipset=/yahooapis.com/gfwlist +server=/techcrunch.com/127.0.0.1#5335 +ipset=/techcrunch.com/gfwlist +server=/yasarang.net/127.0.0.1#5335 +ipset=/yasarang.net/gfwlist +server=/myguide.hk/127.0.0.1#5335 +ipset=/myguide.hk/gfwlist +server=/yahoo.ws/127.0.0.1#5335 +ipset=/yahoo.ws/gfwlist +server=/yahoo.tn/127.0.0.1#5335 +ipset=/yahoo.tn/gfwlist +server=/yahoo.tm/127.0.0.1#5335 +ipset=/yahoo.tm/gfwlist +server=/yahoo.tk/127.0.0.1#5335 +ipset=/yahoo.tk/gfwlist +server=/mastercardcenter.org/127.0.0.1#5335 +ipset=/mastercardcenter.org/gfwlist +server=/yahoo.sr/127.0.0.1#5335 +ipset=/yahoo.sr/gfwlist +server=/pornobox.net/127.0.0.1#5335 +ipset=/pornobox.net/gfwlist +server=/finish.co.uk/127.0.0.1#5335 +ipset=/finish.co.uk/gfwlist +server=/yahoo.sk/127.0.0.1#5335 +ipset=/yahoo.sk/gfwlist +server=/yahoo.sg/127.0.0.1#5335 +ipset=/yahoo.sg/gfwlist +server=/yahoo.se/127.0.0.1#5335 +ipset=/yahoo.se/gfwlist +server=/yahoo.ru/127.0.0.1#5335 +ipset=/yahoo.ru/gfwlist +server=/ggdiao.com/127.0.0.1#5335 +ipset=/ggdiao.com/gfwlist +server=/yahoo.pn/127.0.0.1#5335 +ipset=/yahoo.pn/gfwlist +server=/pearsonelt.com/127.0.0.1#5335 +ipset=/pearsonelt.com/gfwlist +server=/yahoo.net/127.0.0.1#5335 +ipset=/yahoo.net/gfwlist +server=/dragoniscoming.com/127.0.0.1#5335 +ipset=/dragoniscoming.com/gfwlist +server=/discord.new/127.0.0.1#5335 +ipset=/discord.new/gfwlist +server=/yahoo.mx/127.0.0.1#5335 +ipset=/yahoo.mx/gfwlist +server=/dailymailonline.com/127.0.0.1#5335 +ipset=/dailymailonline.com/gfwlist +server=/llnw.com/127.0.0.1#5335 +ipset=/llnw.com/gfwlist +server=/bmwgroup.com/127.0.0.1#5335 +ipset=/bmwgroup.com/gfwlist +server=/sverigebeatsbydrdre.com/127.0.0.1#5335 +ipset=/sverigebeatsbydrdre.com/gfwlist +server=/elog-ch.com/127.0.0.1#5335 +ipset=/elog-ch.com/gfwlist +server=/igoshopping.net/127.0.0.1#5335 +ipset=/igoshopping.net/gfwlist +server=/cumshotlist.com/127.0.0.1#5335 +ipset=/cumshotlist.com/gfwlist +server=/intel.sr/127.0.0.1#5335 +ipset=/intel.sr/gfwlist +server=/ikea.be/127.0.0.1#5335 +ipset=/ikea.be/gfwlist +server=/yahoo.mk/127.0.0.1#5335 +ipset=/yahoo.mk/gfwlist +server=/yahoo.md/127.0.0.1#5335 +ipset=/yahoo.md/gfwlist +server=/movenetworks.com/127.0.0.1#5335 +ipset=/movenetworks.com/gfwlist +server=/wisekey.com/127.0.0.1#5335 +ipset=/wisekey.com/gfwlist +server=/yahoo.lt/127.0.0.1#5335 +ipset=/yahoo.lt/gfwlist +server=/yahoo.jo/127.0.0.1#5335 +ipset=/yahoo.jo/gfwlist +server=/yahoo.je/127.0.0.1#5335 +ipset=/yahoo.je/gfwlist +server=/blogoverflow.com/127.0.0.1#5335 +ipset=/blogoverflow.com/gfwlist +server=/pigav.com/127.0.0.1#5335 +ipset=/pigav.com/gfwlist +server=/dogecoin.com/127.0.0.1#5335 +ipset=/dogecoin.com/gfwlist +server=/yahoo.in/127.0.0.1#5335 +ipset=/yahoo.in/gfwlist +server=/yahoo.hr/127.0.0.1#5335 +ipset=/yahoo.hr/gfwlist +server=/ahegao.online/127.0.0.1#5335 +ipset=/ahegao.online/gfwlist +server=/yahoo.hk/127.0.0.1#5335 +ipset=/yahoo.hk/gfwlist +server=/apexprint.com.hk/127.0.0.1#5335 +ipset=/apexprint.com.hk/gfwlist +server=/yahoo.gy/127.0.0.1#5335 +ipset=/yahoo.gy/gfwlist +server=/snapkit.co/127.0.0.1#5335 +ipset=/snapkit.co/gfwlist +server=/gettyimages.es/127.0.0.1#5335 +ipset=/gettyimages.es/gfwlist +server=/night.livedoor.biz/127.0.0.1#5335 +ipset=/night.livedoor.biz/gfwlist +server=/bmw.com.py/127.0.0.1#5335 +ipset=/bmw.com.py/gfwlist +server=/yahoo.gr/127.0.0.1#5335 +ipset=/yahoo.gr/gfwlist +server=/yahoo.gp/127.0.0.1#5335 +ipset=/yahoo.gp/gfwlist +server=/verizonfios.com/127.0.0.1#5335 +ipset=/verizonfios.com/gfwlist +server=/yahoo.gm/127.0.0.1#5335 +ipset=/yahoo.gm/gfwlist +server=/pinterest.ch/127.0.0.1#5335 +ipset=/pinterest.ch/gfwlist +server=/rocksdb.com/127.0.0.1#5335 +ipset=/rocksdb.com/gfwlist +server=/meraki.hk/127.0.0.1#5335 +ipset=/meraki.hk/gfwlist +server=/javmany.com/127.0.0.1#5335 +ipset=/javmany.com/gfwlist +server=/drunkenstepfather.com/127.0.0.1#5335 +ipset=/drunkenstepfather.com/gfwlist +server=/520aa.tv/127.0.0.1#5335 +ipset=/520aa.tv/gfwlist +server=/sony.rs/127.0.0.1#5335 +ipset=/sony.rs/gfwlist +server=/yahoo.gg/127.0.0.1#5335 +ipset=/yahoo.gg/gfwlist +server=/yahoo.fm/127.0.0.1#5335 +ipset=/yahoo.fm/gfwlist +server=/fbredex.com/127.0.0.1#5335 +ipset=/fbredex.com/gfwlist +server=/yahoo.ee/127.0.0.1#5335 +ipset=/yahoo.ee/gfwlist +server=/wballiance.com/127.0.0.1#5335 +ipset=/wballiance.com/gfwlist +server=/nvidia.lu/127.0.0.1#5335 +ipset=/nvidia.lu/gfwlist +server=/urukawa.com/127.0.0.1#5335 +ipset=/urukawa.com/gfwlist +server=/roughman.net/127.0.0.1#5335 +ipset=/roughman.net/gfwlist +server=/wapm.io/127.0.0.1#5335 +ipset=/wapm.io/gfwlist +server=/yahoo.com.vc/127.0.0.1#5335 +ipset=/yahoo.com.vc/gfwlist +server=/zlib.life/127.0.0.1#5335 +ipset=/zlib.life/gfwlist +server=/dreambmw.ca/127.0.0.1#5335 +ipset=/dreambmw.ca/gfwlist +server=/yahoo.com.ua/127.0.0.1#5335 +ipset=/yahoo.com.ua/gfwlist +server=/yahoo.sm/127.0.0.1#5335 +ipset=/yahoo.sm/gfwlist +server=/iw8j.cc/127.0.0.1#5335 +ipset=/iw8j.cc/gfwlist +server=/yahoo.com.sv/127.0.0.1#5335 +ipset=/yahoo.com.sv/gfwlist +server=/chickteases.com/127.0.0.1#5335 +ipset=/chickteases.com/gfwlist +server=/jwplatform.com/127.0.0.1#5335 +ipset=/jwplatform.com/gfwlist +server=/mypornolab.click/127.0.0.1#5335 +ipset=/mypornolab.click/gfwlist +server=/yahoo.com.py/127.0.0.1#5335 +ipset=/yahoo.com.py/gfwlist +server=/yahoo.com.ph/127.0.0.1#5335 +ipset=/yahoo.com.ph/gfwlist +server=/proporn.com/127.0.0.1#5335 +ipset=/proporn.com/gfwlist +server=/yahoo.com.pe/127.0.0.1#5335 +ipset=/yahoo.com.pe/gfwlist +server=/youporn-germany.com/127.0.0.1#5335 +ipset=/youporn-germany.com/gfwlist +server=/kubeapps.com/127.0.0.1#5335 +ipset=/kubeapps.com/gfwlist +server=/jerkdude.com/127.0.0.1#5335 +ipset=/jerkdude.com/gfwlist +server=/yahoo.com.ly/127.0.0.1#5335 +ipset=/yahoo.com.ly/gfwlist +server=/uoherald.com/127.0.0.1#5335 +ipset=/uoherald.com/gfwlist +server=/ebahy.com/127.0.0.1#5335 +ipset=/ebahy.com/gfwlist +server=/codecademy.com/127.0.0.1#5335 +ipset=/codecademy.com/gfwlist +server=/squareup.com/127.0.0.1#5335 +ipset=/squareup.com/gfwlist +server=/homedepot.com/127.0.0.1#5335 +ipset=/homedepot.com/gfwlist +server=/visa.com.tt/127.0.0.1#5335 +ipset=/visa.com.tt/gfwlist +server=/dragonagemovie.com/127.0.0.1#5335 +ipset=/dragonagemovie.com/gfwlist +server=/casquemonsterbeats.com/127.0.0.1#5335 +ipset=/casquemonsterbeats.com/gfwlist +server=/yahoo.com.eg/127.0.0.1#5335 +ipset=/yahoo.com.eg/gfwlist +server=/officecdn-microsoft-com.akamaized.net/127.0.0.1#5335 +ipset=/officecdn-microsoft-com.akamaized.net/gfwlist +server=/yahoo.com.co/127.0.0.1#5335 +ipset=/yahoo.com.co/gfwlist +server=/yahoo.com.bz/127.0.0.1#5335 +ipset=/yahoo.com.bz/gfwlist +server=/mastercard.inc/127.0.0.1#5335 +ipset=/mastercard.inc/gfwlist +server=/yahoo.com.br/127.0.0.1#5335 +ipset=/yahoo.com.br/gfwlist +server=/sony.com.tw/127.0.0.1#5335 +ipset=/sony.com.tw/gfwlist +server=/paypal-brandcentral.com/127.0.0.1#5335 +ipset=/paypal-brandcentral.com/gfwlist +server=/trustedanalytics.net/127.0.0.1#5335 +ipset=/trustedanalytics.net/gfwlist +server=/yahoo.com.au/127.0.0.1#5335 +ipset=/yahoo.com.au/gfwlist +server=/yahoo.com.ar/127.0.0.1#5335 +ipset=/yahoo.com.ar/gfwlist +server=/porn1videos.com/127.0.0.1#5335 +ipset=/porn1videos.com/gfwlist +server=/yahoo.com.ai/127.0.0.1#5335 +ipset=/yahoo.com.ai/gfwlist +server=/yahoo.com.af/127.0.0.1#5335 +ipset=/yahoo.com.af/gfwlist +server=/bmw-sudan.com/127.0.0.1#5335 +ipset=/bmw-sudan.com/gfwlist +server=/yahoo.co.za/127.0.0.1#5335 +ipset=/yahoo.co.za/gfwlist +server=/cloudburstresearch.com/127.0.0.1#5335 +ipset=/cloudburstresearch.com/gfwlist +server=/offrezdesipods.com/127.0.0.1#5335 +ipset=/offrezdesipods.com/gfwlist +server=/nude-share.com/127.0.0.1#5335 +ipset=/nude-share.com/gfwlist +server=/yahoo.co.uz/127.0.0.1#5335 +ipset=/yahoo.co.uz/gfwlist +server=/yahoo.co.uk/127.0.0.1#5335 +ipset=/yahoo.co.uk/gfwlist +server=/yahoo.co.nz/127.0.0.1#5335 +ipset=/yahoo.co.nz/gfwlist +server=/yahoo.co.kr/127.0.0.1#5335 +ipset=/yahoo.co.kr/gfwlist +server=/yahoo.co.cr/127.0.0.1#5335 +ipset=/yahoo.co.cr/gfwlist +server=/yahoo.co.ck/127.0.0.1#5335 +ipset=/yahoo.co.ck/gfwlist +server=/cheapwireless04.com/127.0.0.1#5335 +ipset=/cheapwireless04.com/gfwlist +server=/yahoo.co.ao/127.0.0.1#5335 +ipset=/yahoo.co.ao/gfwlist +server=/yahoo.cg/127.0.0.1#5335 +ipset=/yahoo.cg/gfwlist +server=/lustteens.net/127.0.0.1#5335 +ipset=/lustteens.net/gfwlist +server=/themarvelexperiencetour.com/127.0.0.1#5335 +ipset=/themarvelexperiencetour.com/gfwlist +server=/yahoo.cat/127.0.0.1#5335 +ipset=/yahoo.cat/gfwlist +server=/yahoo.ca/127.0.0.1#5335 +ipset=/yahoo.ca/gfwlist +server=/beatsinsingapore.com/127.0.0.1#5335 +ipset=/beatsinsingapore.com/gfwlist +server=/yahoo.bs/127.0.0.1#5335 +ipset=/yahoo.bs/gfwlist +server=/yahoo.bg/127.0.0.1#5335 +ipset=/yahoo.bg/gfwlist +server=/xxxstreams.watch/127.0.0.1#5335 +ipset=/xxxstreams.watch/gfwlist +server=/trannygem.com/127.0.0.1#5335 +ipset=/trannygem.com/gfwlist +server=/yahoo.ba/127.0.0.1#5335 +ipset=/yahoo.ba/gfwlist +server=/riotpoints.com/127.0.0.1#5335 +ipset=/riotpoints.com/gfwlist +server=/xv1.monster/127.0.0.1#5335 +ipset=/xv1.monster/gfwlist +server=/yahoo.am/127.0.0.1#5335 +ipset=/yahoo.am/gfwlist +server=/lanternal.com/127.0.0.1#5335 +ipset=/lanternal.com/gfwlist +server=/javhd.pro/127.0.0.1#5335 +ipset=/javhd.pro/gfwlist +server=/rapefilms.net/127.0.0.1#5335 +ipset=/rapefilms.net/gfwlist +server=/accountpaypal.org/127.0.0.1#5335 +ipset=/accountpaypal.org/gfwlist +server=/nurofen.de/127.0.0.1#5335 +ipset=/nurofen.de/gfwlist +server=/ycombinator.com/127.0.0.1#5335 +ipset=/ycombinator.com/gfwlist +server=/aps.org/127.0.0.1#5335 +ipset=/aps.org/gfwlist +server=/intel.com.ph/127.0.0.1#5335 +ipset=/intel.com.ph/gfwlist +server=/sandisk.nl/127.0.0.1#5335 +ipset=/sandisk.nl/gfwlist +server=/sandisk.hk/127.0.0.1#5335 +ipset=/sandisk.hk/gfwlist +server=/welcometobestbuy.ca/127.0.0.1#5335 +ipset=/welcometobestbuy.ca/gfwlist +server=/mini.co.uk/127.0.0.1#5335 +ipset=/mini.co.uk/gfwlist +server=/sandisk.de/127.0.0.1#5335 +ipset=/sandisk.de/gfwlist +server=/ichineseporn.com/127.0.0.1#5335 +ipset=/ichineseporn.com/gfwlist +server=/sandisk.com.tw/127.0.0.1#5335 +ipset=/sandisk.com.tw/gfwlist +server=/qwapi.com/127.0.0.1#5335 +ipset=/qwapi.com/gfwlist +server=/sandisk.com.tr/127.0.0.1#5335 +ipset=/sandisk.com.tr/gfwlist +server=/attsavings.com/127.0.0.1#5335 +ipset=/attsavings.com/gfwlist +server=/sandisk.com.br/127.0.0.1#5335 +ipset=/sandisk.com.br/gfwlist +server=/lysol.com/127.0.0.1#5335 +ipset=/lysol.com/gfwlist +server=/foxsportsla.com/127.0.0.1#5335 +ipset=/foxsportsla.com/gfwlist +server=/timelinestoryteller.com/127.0.0.1#5335 +ipset=/timelinestoryteller.com/gfwlist +server=/vmware-techcenter.com/127.0.0.1#5335 +ipset=/vmware-techcenter.com/gfwlist +server=/vmworld.com/127.0.0.1#5335 +ipset=/vmworld.com/gfwlist +server=/sonybuilding.jp/127.0.0.1#5335 +ipset=/sonybuilding.jp/gfwlist +server=/g-technology.com/127.0.0.1#5335 +ipset=/g-technology.com/gfwlist +server=/uber.com/127.0.0.1#5335 +ipset=/uber.com/gfwlist +server=/tonec.com/127.0.0.1#5335 +ipset=/tonec.com/gfwlist +server=/registeridm.com/127.0.0.1#5335 +ipset=/registeridm.com/gfwlist +server=/hornyelephant.com/127.0.0.1#5335 +ipset=/hornyelephant.com/gfwlist +server=/hairy-women-pussy.net/127.0.0.1#5335 +ipset=/hairy-women-pussy.net/gfwlist +server=/lewdthots.com/127.0.0.1#5335 +ipset=/lewdthots.com/gfwlist +server=/internetdownloadmanager.com/127.0.0.1#5335 +ipset=/internetdownloadmanager.com/gfwlist +server=/x.com/127.0.0.1#5335 +ipset=/x.com/gfwlist +server=/sonylatvija.com/127.0.0.1#5335 +ipset=/sonylatvija.com/gfwlist +server=/disneymagicmoments.gen.tr/127.0.0.1#5335 +ipset=/disneymagicmoments.gen.tr/gfwlist +server=/sonyglobalsolutions.jp/127.0.0.1#5335 +ipset=/sonyglobalsolutions.jp/gfwlist +server=/monster-beats-by-dr-dre.com/127.0.0.1#5335 +ipset=/monster-beats-by-dr-dre.com/gfwlist +server=/sonydna.com/127.0.0.1#5335 +ipset=/sonydna.com/gfwlist +server=/japanbeast.com/127.0.0.1#5335 +ipset=/japanbeast.com/gfwlist +server=/amazon-lantern.com/127.0.0.1#5335 +ipset=/amazon-lantern.com/gfwlist +server=/sony.se/127.0.0.1#5335 +ipset=/sony.se/gfwlist +server=/cheapbeatsshopbydre.com/127.0.0.1#5335 +ipset=/cheapbeatsshopbydre.com/gfwlist +server=/visakorea.com/127.0.0.1#5335 +ipset=/visakorea.com/gfwlist +server=/sony.nl/127.0.0.1#5335 +ipset=/sony.nl/gfwlist +server=/sony.net/127.0.0.1#5335 +ipset=/sony.net/gfwlist +server=/sony.lv/127.0.0.1#5335 +ipset=/sony.lv/gfwlist +server=/sony.hu/127.0.0.1#5335 +ipset=/sony.hu/gfwlist +server=/sony.hr/127.0.0.1#5335 +ipset=/sony.hr/gfwlist +server=/appexchange.com/127.0.0.1#5335 +ipset=/appexchange.com/gfwlist +server=/sony.gr/127.0.0.1#5335 +ipset=/sony.gr/gfwlist +server=/yaburi.men/127.0.0.1#5335 +ipset=/yaburi.men/gfwlist +server=/cnbeta.com/127.0.0.1#5335 +ipset=/cnbeta.com/gfwlist +server=/sony.fr/127.0.0.1#5335 +ipset=/sony.fr/gfwlist +server=/yibei.org/127.0.0.1#5335 +ipset=/yibei.org/gfwlist +server=/sony.fi/127.0.0.1#5335 +ipset=/sony.fi/gfwlist +server=/realamericanstories.org/127.0.0.1#5335 +ipset=/realamericanstories.org/gfwlist +server=/intel.ro/127.0.0.1#5335 +ipset=/intel.ro/gfwlist +server=/sony.es/127.0.0.1#5335 +ipset=/sony.es/gfwlist +server=/sony.ee/127.0.0.1#5335 +ipset=/sony.ee/gfwlist +server=/boyfriendtv.com/127.0.0.1#5335 +ipset=/boyfriendtv.com/gfwlist +server=/sony.dk/127.0.0.1#5335 +ipset=/sony.dk/gfwlist +server=/onlygayvideo.com/127.0.0.1#5335 +ipset=/onlygayvideo.com/gfwlist +server=/sony.de/127.0.0.1#5335 +ipset=/sony.de/gfwlist +server=/naked-girls.me/127.0.0.1#5335 +ipset=/naked-girls.me/gfwlist +server=/sony.com.tr/127.0.0.1#5335 +ipset=/sony.com.tr/gfwlist +server=/adidas.ch/127.0.0.1#5335 +ipset=/adidas.ch/gfwlist +server=/twvid.com/127.0.0.1#5335 +ipset=/twvid.com/gfwlist +server=/get.page/127.0.0.1#5335 +ipset=/get.page/gfwlist +server=/vmworld2010.com/127.0.0.1#5335 +ipset=/vmworld2010.com/gfwlist +server=/sony.com.ph/127.0.0.1#5335 +ipset=/sony.com.ph/gfwlist +server=/vfsco.fi/127.0.0.1#5335 +ipset=/vfsco.fi/gfwlist +server=/1to1conference.com.au/127.0.0.1#5335 +ipset=/1to1conference.com.au/gfwlist +server=/adultartlinks.supertop-100.com/127.0.0.1#5335 +ipset=/adultartlinks.supertop-100.com/gfwlist +server=/sony.com.pe/127.0.0.1#5335 +ipset=/sony.com.pe/gfwlist +server=/atom.io/127.0.0.1#5335 +ipset=/atom.io/gfwlist +server=/sony.com.pa/127.0.0.1#5335 +ipset=/sony.com.pa/gfwlist +server=/sony.com.my/127.0.0.1#5335 +ipset=/sony.com.my/gfwlist +server=/sony.com.mk/127.0.0.1#5335 +ipset=/sony.com.mk/gfwlist +server=/sony.com.do/127.0.0.1#5335 +ipset=/sony.com.do/gfwlist +server=/dependabot.com/127.0.0.1#5335 +ipset=/dependabot.com/gfwlist +server=/peacocktv.com/127.0.0.1#5335 +ipset=/peacocktv.com/gfwlist +server=/sony.co.uk/127.0.0.1#5335 +ipset=/sony.co.uk/gfwlist +server=/sony.co.th/127.0.0.1#5335 +ipset=/sony.co.th/gfwlist +server=/sony.co.jp/127.0.0.1#5335 +ipset=/sony.co.jp/gfwlist +server=/sony.co.in/127.0.0.1#5335 +ipset=/sony.co.in/gfwlist +server=/sony.co.id/127.0.0.1#5335 +ipset=/sony.co.id/gfwlist +server=/sony.co.cr/127.0.0.1#5335 +ipset=/sony.co.cr/gfwlist +server=/sony.ch/127.0.0.1#5335 +ipset=/sony.ch/gfwlist +server=/sony.ca/127.0.0.1#5335 +ipset=/sony.ca/gfwlist +server=/globalsign.co.uk/127.0.0.1#5335 +ipset=/globalsign.co.uk/gfwlist +server=/verisign.in/127.0.0.1#5335 +ipset=/verisign.in/gfwlist +server=/sony.bg/127.0.0.1#5335 +ipset=/sony.bg/gfwlist +server=/sony.ba/127.0.0.1#5335 +ipset=/sony.ba/gfwlist +server=/sony-promotion.eu/127.0.0.1#5335 +ipset=/sony-promotion.eu/gfwlist +server=/sony-mea.com/127.0.0.1#5335 +ipset=/sony-mea.com/gfwlist +server=/sony-latin.com/127.0.0.1#5335 +ipset=/sony-latin.com/gfwlist +server=/tensorflow.org/127.0.0.1#5335 +ipset=/tensorflow.org/gfwlist +server=/sony-europe.com/127.0.0.1#5335 +ipset=/sony-europe.com/gfwlist +server=/camwhoresbay.com/127.0.0.1#5335 +ipset=/camwhoresbay.com/gfwlist +server=/whychoosevmwareeuc.com/127.0.0.1#5335 +ipset=/whychoosevmwareeuc.com/gfwlist +server=/momsteachsex.info/127.0.0.1#5335 +ipset=/momsteachsex.info/gfwlist +server=/df-bet.com/127.0.0.1#5335 +ipset=/df-bet.com/gfwlist +server=/worldescortindex.com/127.0.0.1#5335 +ipset=/worldescortindex.com/gfwlist +server=/snap.com/127.0.0.1#5335 +ipset=/snap.com/gfwlist +server=/pornaxo.com/127.0.0.1#5335 +ipset=/pornaxo.com/gfwlist +server=/sc-cdn.net/127.0.0.1#5335 +ipset=/sc-cdn.net/gfwlist +server=/wise-research.com/127.0.0.1#5335 +ipset=/wise-research.com/gfwlist +server=/smartonerobotics.com/127.0.0.1#5335 +ipset=/smartonerobotics.com/gfwlist +server=/dialogflow.com/127.0.0.1#5335 +ipset=/dialogflow.com/gfwlist +server=/sony.com.sv/127.0.0.1#5335 +ipset=/sony.com.sv/gfwlist +server=/wiisports.com/127.0.0.1#5335 +ipset=/wiisports.com/gfwlist +server=/s-rewards.hk/127.0.0.1#5335 +ipset=/s-rewards.hk/gfwlist +server=/s-cashonmobile.com/127.0.0.1#5335 +ipset=/s-cashonmobile.com/gfwlist +server=/ip73.com/127.0.0.1#5335 +ipset=/ip73.com/gfwlist +server=/12diasderegalosdeitunes.co.ve/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.co.ve/gfwlist +server=/hkcircleapp.com/127.0.0.1#5335 +ipset=/hkcircleapp.com/gfwlist +server=/barkadahansasmartone.com/127.0.0.1#5335 +ipset=/barkadahansasmartone.com/gfwlist +server=/appleone.community/127.0.0.1#5335 +ipset=/appleone.community/gfwlist +server=/samsunggalaxyfriends.com/127.0.0.1#5335 +ipset=/samsunggalaxyfriends.com/gfwlist +server=/canon-cee.com/127.0.0.1#5335 +ipset=/canon-cee.com/gfwlist +server=/fcfacebook.com/127.0.0.1#5335 +ipset=/fcfacebook.com/gfwlist +server=/ntc.party/127.0.0.1#5335 +ipset=/ntc.party/gfwlist +server=/nuvid.com/127.0.0.1#5335 +ipset=/nuvid.com/gfwlist +server=/vmwarelearning.com/127.0.0.1#5335 +ipset=/vmwarelearning.com/gfwlist +server=/samsungapps.com/127.0.0.1#5335 +ipset=/samsungapps.com/gfwlist +server=/bloombergprep.com/127.0.0.1#5335 +ipset=/bloombergprep.com/gfwlist +server=/samsung.com/127.0.0.1#5335 +ipset=/samsung.com/gfwlist +server=/vanish.co.in/127.0.0.1#5335 +ipset=/vanish.co.in/gfwlist +server=/galaxyappstore.com/127.0.0.1#5335 +ipset=/galaxyappstore.com/gfwlist +server=/steelbrick.com/127.0.0.1#5335 +ipset=/steelbrick.com/gfwlist +server=/xvideosnovinha.com.br/127.0.0.1#5335 +ipset=/xvideosnovinha.com.br/gfwlist +server=/sforce.com/127.0.0.1#5335 +ipset=/sforce.com/gfwlist +server=/sfdcstatic.com/127.0.0.1#5335 +ipset=/sfdcstatic.com/gfwlist +server=/sequence.com/127.0.0.1#5335 +ipset=/sequence.com/gfwlist +server=/dataliberation.org/127.0.0.1#5335 +ipset=/dataliberation.org/gfwlist +server=/google.com.ni/127.0.0.1#5335 +ipset=/google.com.ni/gfwlist +server=/salesforceliveagent.com/127.0.0.1#5335 +ipset=/salesforceliveagent.com/gfwlist +server=/salesforceiq.com/127.0.0.1#5335 +ipset=/salesforceiq.com/gfwlist +server=/line-apps-beta.com/127.0.0.1#5335 +ipset=/line-apps-beta.com/gfwlist +server=/straightpornstuds.com/127.0.0.1#5335 +ipset=/straightpornstuds.com/gfwlist +server=/2chav.com/127.0.0.1#5335 +ipset=/2chav.com/gfwlist +server=/pearsonclinical.eu/127.0.0.1#5335 +ipset=/pearsonclinical.eu/gfwlist +server=/salesforce.org/127.0.0.1#5335 +ipset=/salesforce.org/gfwlist +server=/faceboook.com/127.0.0.1#5335 +ipset=/faceboook.com/gfwlist +server=/unbrandedproducts.com/127.0.0.1#5335 +ipset=/unbrandedproducts.com/gfwlist +server=/quotable.com/127.0.0.1#5335 +ipset=/quotable.com/gfwlist +server=/pardot.com/127.0.0.1#5335 +ipset=/pardot.com/gfwlist +server=/microsoft.ca/127.0.0.1#5335 +ipset=/microsoft.ca/gfwlist +server=/force.com/127.0.0.1#5335 +ipset=/force.com/gfwlist +server=/exacttarget.com/127.0.0.1#5335 +ipset=/exacttarget.com/gfwlist +server=/liboggirls.net/127.0.0.1#5335 +ipset=/liboggirls.net/gfwlist +server=/minikelowna.ca/127.0.0.1#5335 +ipset=/minikelowna.ca/gfwlist +server=/einstein.com/127.0.0.1#5335 +ipset=/einstein.com/gfwlist +server=/desk.com/127.0.0.1#5335 +ipset=/desk.com/gfwlist +server=/google.mk/127.0.0.1#5335 +ipset=/google.mk/gfwlist +server=/demandware.com/127.0.0.1#5335 +ipset=/demandware.com/gfwlist +server=/drdrebeatsforu.com/127.0.0.1#5335 +ipset=/drdrebeatsforu.com/gfwlist +server=/ilife.gr/127.0.0.1#5335 +ipset=/ilife.gr/gfwlist +server=/cloudcraze.com/127.0.0.1#5335 +ipset=/cloudcraze.com/gfwlist +server=/chatter.com/127.0.0.1#5335 +ipset=/chatter.com/gfwlist +server=/beyondcore.com/127.0.0.1#5335 +ipset=/beyondcore.com/gfwlist +server=/razerzone.jp/127.0.0.1#5335 +ipset=/razerzone.jp/gfwlist +server=/razerzone.com/127.0.0.1#5335 +ipset=/razerzone.com/gfwlist +server=/newhentai.org/127.0.0.1#5335 +ipset=/newhentai.org/gfwlist +server=/qwant.fr/127.0.0.1#5335 +ipset=/qwant.fr/gfwlist +server=/ieee-sensors.org/127.0.0.1#5335 +ipset=/ieee-sensors.org/gfwlist +server=/soso7778.com/127.0.0.1#5335 +ipset=/soso7778.com/gfwlist +server=/shemalestardb.com/127.0.0.1#5335 +ipset=/shemalestardb.com/gfwlist +server=/qwant.com/127.0.0.1#5335 +ipset=/qwant.com/gfwlist +server=/intel.ag/127.0.0.1#5335 +ipset=/intel.ag/gfwlist +server=/mongodb.org/127.0.0.1#5335 +ipset=/mongodb.org/gfwlist +server=/uplinq.com/127.0.0.1#5335 +ipset=/uplinq.com/gfwlist +server=/bestialitysextaboo.com/127.0.0.1#5335 +ipset=/bestialitysextaboo.com/gfwlist +server=/snapdragonbooth.com/127.0.0.1#5335 +ipset=/snapdragonbooth.com/gfwlist +server=/snapdragon.cn/127.0.0.1#5335 +ipset=/snapdragon.cn/gfwlist +server=/minilangley.ca/127.0.0.1#5335 +ipset=/minilangley.ca/gfwlist +server=/qualcommventures.cn/127.0.0.1#5335 +ipset=/qualcommventures.cn/gfwlist +server=/qualcommretail.com/127.0.0.1#5335 +ipset=/qualcommretail.com/gfwlist +server=/avfox.cc/127.0.0.1#5335 +ipset=/avfox.cc/gfwlist +server=/sexxxhd.com/127.0.0.1#5335 +ipset=/sexxxhd.com/gfwlist +server=/volvobuses.pk/127.0.0.1#5335 +ipset=/volvobuses.pk/gfwlist +server=/qualcommmea.com/127.0.0.1#5335 +ipset=/qualcommmea.com/gfwlist +server=/qualcomm.fr/127.0.0.1#5335 +ipset=/qualcomm.fr/gfwlist +server=/lexisnexis.com/127.0.0.1#5335 +ipset=/lexisnexis.com/gfwlist +server=/qualcomm.com.tw/127.0.0.1#5335 +ipset=/qualcomm.com.tw/gfwlist +server=/qualcomm.co.kr/127.0.0.1#5335 +ipset=/qualcomm.co.kr/gfwlist +server=/qualcomm.co.in/127.0.0.1#5335 +ipset=/qualcomm.co.in/gfwlist +server=/whatsapp-plus.net/127.0.0.1#5335 +ipset=/whatsapp-plus.net/gfwlist +server=/mypearson.com/127.0.0.1#5335 +ipset=/mypearson.com/gfwlist +server=/qctconnect.com/127.0.0.1#5335 +ipset=/qctconnect.com/gfwlist +server=/patenttruth.org/127.0.0.1#5335 +ipset=/patenttruth.org/gfwlist +server=/pavpal.com/127.0.0.1#5335 +ipset=/pavpal.com/gfwlist +server=/mhshosting.com/127.0.0.1#5335 +ipset=/mhshosting.com/gfwlist +server=/imod.com/127.0.0.1#5335 +ipset=/imod.com/gfwlist +server=/vip-beats.com/127.0.0.1#5335 +ipset=/vip-beats.com/gfwlist +server=/gobianywhere.com/127.0.0.1#5335 +ipset=/gobianywhere.com/gfwlist +server=/cdmatech.com/127.0.0.1#5335 +ipset=/cdmatech.com/gfwlist +server=/sexgames.xxx/127.0.0.1#5335 +ipset=/sexgames.xxx/gfwlist +server=/donmai.us/127.0.0.1#5335 +ipset=/donmai.us/gfwlist +server=/berkanawireless.com/127.0.0.1#5335 +ipset=/berkanawireless.com/gfwlist +server=/bridgestonemerchandise.com/127.0.0.1#5335 +ipset=/bridgestonemerchandise.com/gfwlist +server=/cheap-nike.com/127.0.0.1#5335 +ipset=/cheap-nike.com/gfwlist +server=/jpg4us.net/127.0.0.1#5335 +ipset=/jpg4us.net/gfwlist +server=/volvotrucks.az/127.0.0.1#5335 +ipset=/volvotrucks.az/gfwlist +server=/stockingfetishvideo.com/127.0.0.1#5335 +ipset=/stockingfetishvideo.com/gfwlist +server=/ebayfashion.com/127.0.0.1#5335 +ipset=/ebayfashion.com/gfwlist +server=/genkai-hounyo.com/127.0.0.1#5335 +ipset=/genkai-hounyo.com/gfwlist +server=/bmw-motorrad.ua/127.0.0.1#5335 +ipset=/bmw-motorrad.ua/gfwlist +server=/pccw.com/127.0.0.1#5335 +ipset=/pccw.com/gfwlist +server=/hktpremier.com/127.0.0.1#5335 +ipset=/hktpremier.com/gfwlist +server=/hkt.com/127.0.0.1#5335 +ipset=/hkt.com/gfwlist +server=/media-rockstargames-com.akamaized.net/127.0.0.1#5335 +ipset=/media-rockstargames-com.akamaized.net/gfwlist +server=/scholar.google.com.hk/127.0.0.1#5335 +ipset=/scholar.google.com.hk/gfwlist +server=/hkt-eye.com/127.0.0.1#5335 +ipset=/hkt-eye.com/gfwlist +server=/esmarthealth.com/127.0.0.1#5335 +ipset=/esmarthealth.com/gfwlist +server=/drdrebeats-headphone.com/127.0.0.1#5335 +ipset=/drdrebeats-headphone.com/gfwlist +server=/panasonic.com/127.0.0.1#5335 +ipset=/panasonic.com/gfwlist +server=/facebookofsex.com/127.0.0.1#5335 +ipset=/facebookofsex.com/gfwlist +server=/oracleinfinity.io/127.0.0.1#5335 +ipset=/oracleinfinity.io/gfwlist +server=/oracleimg.com/127.0.0.1#5335 +ipset=/oracleimg.com/gfwlist +server=/oraclecloud.com/127.0.0.1#5335 +ipset=/oraclecloud.com/gfwlist +server=/oracle.com/127.0.0.1#5335 +ipset=/oracle.com/gfwlist +server=/jquerymobile.com/127.0.0.1#5335 +ipset=/jquerymobile.com/gfwlist +server=/openweathermap.org/127.0.0.1#5335 +ipset=/openweathermap.org/gfwlist +server=/nvidia.tt.omtrdc.net/127.0.0.1#5335 +ipset=/nvidia.tt.omtrdc.net/gfwlist +server=/tegrazone.kr/127.0.0.1#5335 +ipset=/tegrazone.kr/gfwlist +server=/mini.com.pa/127.0.0.1#5335 +ipset=/mini.com.pa/gfwlist +server=/steamstore-a.akamaihd.net/127.0.0.1#5335 +ipset=/steamstore-a.akamaihd.net/gfwlist +server=/tegrazone.com/127.0.0.1#5335 +ipset=/tegrazone.com/gfwlist +server=/deno.land/127.0.0.1#5335 +ipset=/deno.land/gfwlist +server=/hdready.xxx/127.0.0.1#5335 +ipset=/hdready.xxx/gfwlist +server=/pensions-expert.com/127.0.0.1#5335 +ipset=/pensions-expert.com/gfwlist +server=/nvidiagrid.net/127.0.0.1#5335 +ipset=/nvidiagrid.net/gfwlist +server=/fans-here.com/127.0.0.1#5335 +ipset=/fans-here.com/gfwlist +server=/nvidia.tw/127.0.0.1#5335 +ipset=/nvidia.tw/gfwlist +server=/nvidia.se/127.0.0.1#5335 +ipset=/nvidia.se/gfwlist +server=/reckittprofessional.com/127.0.0.1#5335 +ipset=/reckittprofessional.com/gfwlist +server=/pornoprive.xxx/127.0.0.1#5335 +ipset=/pornoprive.xxx/gfwlist +server=/nvidia.mx/127.0.0.1#5335 +ipset=/nvidia.mx/gfwlist +server=/yahoo.de/127.0.0.1#5335 +ipset=/yahoo.de/gfwlist +server=/nvidia.in/127.0.0.1#5335 +ipset=/nvidia.in/gfwlist +server=/microsoft.pt/127.0.0.1#5335 +ipset=/microsoft.pt/gfwlist +server=/nvidia.fi/127.0.0.1#5335 +ipset=/nvidia.fi/gfwlist +server=/candidforum-videos.com/127.0.0.1#5335 +ipset=/candidforum-videos.com/gfwlist +server=/nvidia.de/127.0.0.1#5335 +ipset=/nvidia.de/gfwlist +server=/cncrivals.com/127.0.0.1#5335 +ipset=/cncrivals.com/gfwlist +server=/nvidia.cz/127.0.0.1#5335 +ipset=/nvidia.cz/gfwlist +server=/love-sextoys.co.uk/127.0.0.1#5335 +ipset=/love-sextoys.co.uk/gfwlist +server=/nvidia.com.tw/127.0.0.1#5335 +ipset=/nvidia.com.tw/gfwlist +server=/enemaprocedure.com/127.0.0.1#5335 +ipset=/enemaprocedure.com/gfwlist +server=/thunderbolttechnology.net/127.0.0.1#5335 +ipset=/thunderbolttechnology.net/gfwlist +server=/nvidia.co.uk/127.0.0.1#5335 +ipset=/nvidia.co.uk/gfwlist +server=/nvidia.at/127.0.0.1#5335 +ipset=/nvidia.at/gfwlist +server=/gputechconf.jp/127.0.0.1#5335 +ipset=/gputechconf.jp/gfwlist +server=/gputechconf.in/127.0.0.1#5335 +ipset=/gputechconf.in/gfwlist +server=/durex.se/127.0.0.1#5335 +ipset=/durex.se/gfwlist +server=/anon-v.lol/127.0.0.1#5335 +ipset=/anon-v.lol/gfwlist +server=/lolespor.com/127.0.0.1#5335 +ipset=/lolespor.com/gfwlist +server=/taxidrivermovie.com/127.0.0.1#5335 +ipset=/taxidrivermovie.com/gfwlist +server=/instagramtakipcisatinal.net/127.0.0.1#5335 +ipset=/instagramtakipcisatinal.net/gfwlist +server=/geforce.co.uk/127.0.0.1#5335 +ipset=/geforce.co.uk/gfwlist +server=/hdxx.tv/127.0.0.1#5335 +ipset=/hdxx.tv/gfwlist +server=/megaporno.com.br/127.0.0.1#5335 +ipset=/megaporno.com.br/gfwlist +server=/pstatic.net/127.0.0.1#5335 +ipset=/pstatic.net/gfwlist +server=/famosascalvas.com/127.0.0.1#5335 +ipset=/famosascalvas.com/gfwlist +server=/maxis.com/127.0.0.1#5335 +ipset=/maxis.com/gfwlist +server=/ywoos.com/127.0.0.1#5335 +ipset=/ywoos.com/gfwlist +server=/springernature.com/127.0.0.1#5335 +ipset=/springernature.com/gfwlist +server=/grafolio.com/127.0.0.1#5335 +ipset=/grafolio.com/gfwlist +server=/mxmcdn.net/127.0.0.1#5335 +ipset=/mxmcdn.net/gfwlist +server=/musixmatch.com/127.0.0.1#5335 +ipset=/musixmatch.com/gfwlist +server=/cafr.ca/127.0.0.1#5335 +ipset=/cafr.ca/gfwlist +server=/paypalinsuranceservices.org/127.0.0.1#5335 +ipset=/paypalinsuranceservices.org/gfwlist +server=/poofetish.com/127.0.0.1#5335 +ipset=/poofetish.com/gfwlist +server=/mozilla.org/127.0.0.1#5335 +ipset=/mozilla.org/gfwlist +server=/mozilla.net/127.0.0.1#5335 +ipset=/mozilla.net/gfwlist +server=/crocotube.com/127.0.0.1#5335 +ipset=/crocotube.com/gfwlist +server=/nordstrommedia.com/127.0.0.1#5335 +ipset=/nordstrommedia.com/gfwlist +server=/illusion111.com/127.0.0.1#5335 +ipset=/illusion111.com/gfwlist +server=/mozilla.com/127.0.0.1#5335 +ipset=/mozilla.com/gfwlist +server=/developer.mozilla.org/127.0.0.1#5335 +ipset=/developer.mozilla.org/gfwlist +server=/quoracdn.net/127.0.0.1#5335 +ipset=/quoracdn.net/gfwlist +server=/indiansexstories2.net/127.0.0.1#5335 +ipset=/indiansexstories2.net/gfwlist +server=/yahoo.com.ec/127.0.0.1#5335 +ipset=/yahoo.com.ec/gfwlist +server=/beatsoutletanytime.com/127.0.0.1#5335 +ipset=/beatsoutletanytime.com/gfwlist +server=/img-s-msn-com.akamaized.net/127.0.0.1#5335 +ipset=/img-s-msn-com.akamaized.net/gfwlist +server=/media-imdb.com/127.0.0.1#5335 +ipset=/media-imdb.com/gfwlist +server=/cityoflove.com/127.0.0.1#5335 +ipset=/cityoflove.com/gfwlist +server=/intelinsight.com/127.0.0.1#5335 +ipset=/intelinsight.com/gfwlist +server=/thinkquarterly.co.uk/127.0.0.1#5335 +ipset=/thinkquarterly.co.uk/gfwlist +server=/winhec.net/127.0.0.1#5335 +ipset=/winhec.net/gfwlist +server=/jadult.net/127.0.0.1#5335 +ipset=/jadult.net/gfwlist +server=/jerkmatelive.org/127.0.0.1#5335 +ipset=/jerkmatelive.org/gfwlist +server=/windowssearch.com/127.0.0.1#5335 +ipset=/windowssearch.com/gfwlist +server=/windows.nl/127.0.0.1#5335 +ipset=/windows.nl/gfwlist +server=/alphabet.lt/127.0.0.1#5335 +ipset=/alphabet.lt/gfwlist +server=/windows.com/127.0.0.1#5335 +ipset=/windows.com/gfwlist +server=/windows-int.net/127.0.0.1#5335 +ipset=/windows-int.net/gfwlist +server=/paypal-mainstreet.net/127.0.0.1#5335 +ipset=/paypal-mainstreet.net/gfwlist +server=/wbd.ms/127.0.0.1#5335 +ipset=/wbd.ms/gfwlist +server=/facebooksafety.com/127.0.0.1#5335 +ipset=/facebooksafety.com/gfwlist +server=/hsxhr.cc/127.0.0.1#5335 +ipset=/hsxhr.cc/gfwlist +server=/vsallin.net/127.0.0.1#5335 +ipset=/vsallin.net/gfwlist +server=/userpxt.io/127.0.0.1#5335 +ipset=/userpxt.io/gfwlist +server=/google.az/127.0.0.1#5335 +ipset=/google.az/gfwlist +server=/tfsallin.net/127.0.0.1#5335 +ipset=/tfsallin.net/gfwlist +server=/cruel-furies.com/127.0.0.1#5335 +ipset=/cruel-furies.com/gfwlist +server=/facebookshop.com/127.0.0.1#5335 +ipset=/facebookshop.com/gfwlist +server=/castingcouch-x.com/127.0.0.1#5335 +ipset=/castingcouch-x.com/gfwlist +server=/ipostnaked.com/127.0.0.1#5335 +ipset=/ipostnaked.com/gfwlist +server=/motorshowblog.com/127.0.0.1#5335 +ipset=/motorshowblog.com/gfwlist +server=/headphoneshotsales.com/127.0.0.1#5335 +ipset=/headphoneshotsales.com/gfwlist +server=/perfectjizz.com/127.0.0.1#5335 +ipset=/perfectjizz.com/gfwlist +server=/geceguby.ru/127.0.0.1#5335 +ipset=/geceguby.ru/gfwlist +server=/staffhub.ms/127.0.0.1#5335 +ipset=/staffhub.ms/gfwlist +server=/skypeassets.com/127.0.0.1#5335 +ipset=/skypeassets.com/gfwlist +server=/skype.net/127.0.0.1#5335 +ipset=/skype.net/gfwlist +server=/sharepointonline.com/127.0.0.1#5335 +ipset=/sharepointonline.com/gfwlist +server=/rou.video/127.0.0.1#5335 +ipset=/rou.video/gfwlist +server=/mini.mq/127.0.0.1#5335 +ipset=/mini.mq/gfwlist +server=/girlscanner.cc/127.0.0.1#5335 +ipset=/girlscanner.cc/gfwlist +server=/alt2-mtalk.google.com/127.0.0.1#5335 +ipset=/alt2-mtalk.google.com/gfwlist +server=/viacom.com/127.0.0.1#5335 +ipset=/viacom.com/gfwlist +server=/sfbassets.net/127.0.0.1#5335 +ipset=/sfbassets.net/gfwlist +server=/pinterest.com.ec/127.0.0.1#5335 +ipset=/pinterest.com.ec/gfwlist +server=/eyny.com/127.0.0.1#5335 +ipset=/eyny.com/gfwlist +server=/sfbassets.com/127.0.0.1#5335 +ipset=/sfbassets.com/gfwlist +server=/s-microsoft.com/127.0.0.1#5335 +ipset=/s-microsoft.com/gfwlist +server=/akamaietpcnctest.com/127.0.0.1#5335 +ipset=/akamaietpcnctest.com/gfwlist +server=/beatsbydreonlines-uk.com/127.0.0.1#5335 +ipset=/beatsbydreonlines-uk.com/gfwlist +server=/pearson-schule.ch/127.0.0.1#5335 +ipset=/pearson-schule.ch/gfwlist +server=/projectsangam.com/127.0.0.1#5335 +ipset=/projectsangam.com/gfwlist +server=/pixapp.net/127.0.0.1#5335 +ipset=/pixapp.net/gfwlist +server=/54647.org/127.0.0.1#5335 +ipset=/54647.org/gfwlist +server=/lowergiseries.com/127.0.0.1#5335 +ipset=/lowergiseries.com/gfwlist +server=/nikeshoponline.com/127.0.0.1#5335 +ipset=/nikeshoponline.com/gfwlist +server=/informs.org/127.0.0.1#5335 +ipset=/informs.org/gfwlist +server=/outingsapp.com/127.0.0.1#5335 +ipset=/outingsapp.com/gfwlist +server=/tubepatrol.org/127.0.0.1#5335 +ipset=/tubepatrol.org/gfwlist +server=/opticsforthecloud.net/127.0.0.1#5335 +ipset=/opticsforthecloud.net/gfwlist +server=/runningnike.com/127.0.0.1#5335 +ipset=/runningnike.com/gfwlist +server=/bitballoon.com/127.0.0.1#5335 +ipset=/bitballoon.com/gfwlist +server=/illusionas.com/127.0.0.1#5335 +ipset=/illusionas.com/gfwlist +server=/pugpig-stage.com/127.0.0.1#5335 +ipset=/pugpig-stage.com/gfwlist +server=/niosii.net/127.0.0.1#5335 +ipset=/niosii.net/gfwlist +server=/mymicrosoft.com/127.0.0.1#5335 +ipset=/mymicrosoft.com/gfwlist +server=/bmwgroupdesignworks.com/127.0.0.1#5335 +ipset=/bmwgroupdesignworks.com/gfwlist +server=/msudalosti.com/127.0.0.1#5335 +ipset=/msudalosti.com/gfwlist +server=/msturing.org/127.0.0.1#5335 +ipset=/msturing.org/gfwlist +server=/adanaatikhaber.com/127.0.0.1#5335 +ipset=/adanaatikhaber.com/gfwlist +server=/vilavpn3.xyz/127.0.0.1#5335 +ipset=/vilavpn3.xyz/gfwlist +server=/topporn.me/127.0.0.1#5335 +ipset=/topporn.me/gfwlist +server=/msft.info/127.0.0.1#5335 +ipset=/msft.info/gfwlist +server=/geraldoatlarge.com/127.0.0.1#5335 +ipset=/geraldoatlarge.com/gfwlist +server=/screens-lab.jp/127.0.0.1#5335 +ipset=/screens-lab.jp/gfwlist +server=/kanzhongguo.eu/127.0.0.1#5335 +ipset=/kanzhongguo.eu/gfwlist +server=/msedge.net/127.0.0.1#5335 +ipset=/msedge.net/gfwlist +server=/mschallenge2018.com/127.0.0.1#5335 +ipset=/mschallenge2018.com/gfwlist +server=/binancezh.info/127.0.0.1#5335 +ipset=/binancezh.info/gfwlist +server=/ms365surfaceoffer.com/127.0.0.1#5335 +ipset=/ms365surfaceoffer.com/gfwlist +server=/ms-studiosmedia.com/127.0.0.1#5335 +ipset=/ms-studiosmedia.com/gfwlist +server=/disneymagicmoments.pl/127.0.0.1#5335 +ipset=/disneymagicmoments.pl/gfwlist +server=/mpnevolution.com/127.0.0.1#5335 +ipset=/mpnevolution.com/gfwlist +server=/manoramaonline.com/127.0.0.1#5335 +ipset=/manoramaonline.com/gfwlist +server=/vepornhd.club/127.0.0.1#5335 +ipset=/vepornhd.club/gfwlist +server=/morphcharts.com/127.0.0.1#5335 +ipset=/morphcharts.com/gfwlist +server=/freeviewplus.net.au/127.0.0.1#5335 +ipset=/freeviewplus.net.au/gfwlist +server=/microsoftstream.com/127.0.0.1#5335 +ipset=/microsoftstream.com/gfwlist +server=/microsoftsiteselection.com/127.0.0.1#5335 +ipset=/microsoftsiteselection.com/gfwlist +server=/microsoftready.com/127.0.0.1#5335 +ipset=/microsoftready.com/gfwlist +server=/telegra.ph/127.0.0.1#5335 +ipset=/telegra.ph/gfwlist +server=/microsoftpartnercommunity.com/127.0.0.1#5335 +ipset=/microsoftpartnercommunity.com/gfwlist +server=/microsoftlinc.com/127.0.0.1#5335 +ipset=/microsoftlinc.com/gfwlist +server=/microsofthouse.net/127.0.0.1#5335 +ipset=/microsofthouse.net/gfwlist +server=/beatsdanmark2013.com/127.0.0.1#5335 +ipset=/beatsdanmark2013.com/gfwlist +server=/microsoftcommunitytraining.com/127.0.0.1#5335 +ipset=/microsoftcommunitytraining.com/gfwlist +server=/microsoftcloudworkshop.com/127.0.0.1#5335 +ipset=/microsoftcloudworkshop.com/gfwlist +server=/theporndude.vip/127.0.0.1#5335 +ipset=/theporndude.vip/gfwlist +server=/megacamz.com/127.0.0.1#5335 +ipset=/megacamz.com/gfwlist +server=/microsoftadvertisingregionalawards.com/127.0.0.1#5335 +ipset=/microsoftadvertisingregionalawards.com/gfwlist +server=/microsoft-sbs-domains.com/127.0.0.1#5335 +ipset=/microsoft-sbs-domains.com/gfwlist +server=/easportsfootball.com/127.0.0.1#5335 +ipset=/easportsfootball.com/gfwlist +server=/microsoft-int.com/127.0.0.1#5335 +ipset=/microsoft-int.com/gfwlist +server=/live.net/127.0.0.1#5335 +ipset=/live.net/gfwlist +server=/live.com/127.0.0.1#5335 +ipset=/live.com/gfwlist +server=/ameba.jp/127.0.0.1#5335 +ipset=/ameba.jp/gfwlist +server=/anthemgame.com/127.0.0.1#5335 +ipset=/anthemgame.com/gfwlist +server=/celeron.net/127.0.0.1#5335 +ipset=/celeron.net/gfwlist +server=/figma.com/127.0.0.1#5335 +ipset=/figma.com/gfwlist +server=/applecomputers.co.nz/127.0.0.1#5335 +ipset=/applecomputers.co.nz/gfwlist +server=/rink.hockeyapp.net/127.0.0.1#5335 +ipset=/rink.hockeyapp.net/gfwlist +server=/aka-ai.net/127.0.0.1#5335 +ipset=/aka-ai.net/gfwlist +server=/18comic.cc/127.0.0.1#5335 +ipset=/18comic.cc/gfwlist +server=/lgbtq.games/127.0.0.1#5335 +ipset=/lgbtq.games/gfwlist +server=/hamivideo.hinet.net/127.0.0.1#5335 +ipset=/hamivideo.hinet.net/gfwlist +server=/entrustdatacard.com/127.0.0.1#5335 +ipset=/entrustdatacard.com/gfwlist +server=/fundfire.com/127.0.0.1#5335 +ipset=/fundfire.com/gfwlist +server=/beats-headphones-buy-cheap.com/127.0.0.1#5335 +ipset=/beats-headphones-buy-cheap.com/gfwlist +server=/nintendo.nl/127.0.0.1#5335 +ipset=/nintendo.nl/gfwlist +server=/nubiles.net/127.0.0.1#5335 +ipset=/nubiles.net/gfwlist +server=/tik-tokapi.com/127.0.0.1#5335 +ipset=/tik-tokapi.com/gfwlist +server=/tvmost.com.hk/127.0.0.1#5335 +ipset=/tvmost.com.hk/gfwlist +server=/facebookadvertisingsecrets.com/127.0.0.1#5335 +ipset=/facebookadvertisingsecrets.com/gfwlist +server=/bmw-vancouver.ca/127.0.0.1#5335 +ipset=/bmw-vancouver.ca/gfwlist +server=/ieeeusa.org/127.0.0.1#5335 +ipset=/ieeeusa.org/gfwlist +server=/lspimg.com/127.0.0.1#5335 +ipset=/lspimg.com/gfwlist +server=/hoodamateurs.com/127.0.0.1#5335 +ipset=/hoodamateurs.com/gfwlist +server=/huffpostmaghreb.com/127.0.0.1#5335 +ipset=/huffpostmaghreb.com/gfwlist +server=/ingads.com/127.0.0.1#5335 +ipset=/ingads.com/gfwlist +server=/imaginecup.pl/127.0.0.1#5335 +ipset=/imaginecup.pl/gfwlist +server=/32bm.cc/127.0.0.1#5335 +ipset=/32bm.cc/gfwlist +server=/internetexplorer.com/127.0.0.1#5335 +ipset=/internetexplorer.com/gfwlist +server=/xb18.me/127.0.0.1#5335 +ipset=/xb18.me/gfwlist +server=/beatsbydresolohdonline-canada.com/127.0.0.1#5335 +ipset=/beatsbydresolohdonline-canada.com/gfwlist +server=/touchid.tv/127.0.0.1#5335 +ipset=/touchid.tv/gfwlist +server=/intelserveredge.com/127.0.0.1#5335 +ipset=/intelserveredge.com/gfwlist +server=/scholar.google.cat/127.0.0.1#5335 +ipset=/scholar.google.cat/gfwlist +server=/cambridgemaths.org/127.0.0.1#5335 +ipset=/cambridgemaths.org/gfwlist +server=/beatsbydrdre4sale.com/127.0.0.1#5335 +ipset=/beatsbydrdre4sale.com/gfwlist +server=/drebeatsoldes.com/127.0.0.1#5335 +ipset=/drebeatsoldes.com/gfwlist +server=/onahodouga.com/127.0.0.1#5335 +ipset=/onahodouga.com/gfwlist +server=/bmw.com.gt/127.0.0.1#5335 +ipset=/bmw.com.gt/gfwlist +server=/hotmail.org/127.0.0.1#5335 +ipset=/hotmail.org/gfwlist +server=/tvappstore.net/127.0.0.1#5335 +ipset=/tvappstore.net/gfwlist +server=/hotmail.eu/127.0.0.1#5335 +ipset=/hotmail.eu/gfwlist +server=/foxcredit.com/127.0.0.1#5335 +ipset=/foxcredit.com/gfwlist +server=/adulttoontube.com/127.0.0.1#5335 +ipset=/adulttoontube.com/gfwlist +server=/smutstone.com/127.0.0.1#5335 +ipset=/smutstone.com/gfwlist +server=/hololens.com/127.0.0.1#5335 +ipset=/hololens.com/gfwlist +server=/lepornofrais.com/127.0.0.1#5335 +ipset=/lepornofrais.com/gfwlist +server=/gigjam.com/127.0.0.1#5335 +ipset=/gigjam.com/gfwlist +server=/jpavcom.com/127.0.0.1#5335 +ipset=/jpavcom.com/gfwlist +server=/9to5toys.com/127.0.0.1#5335 +ipset=/9to5toys.com/gfwlist +server=/gearstactics.com/127.0.0.1#5335 +ipset=/gearstactics.com/gfwlist +server=/washingtonpost.com/127.0.0.1#5335 +ipset=/washingtonpost.com/gfwlist +server=/management-azure-devices-int.net/127.0.0.1#5335 +ipset=/management-azure-devices-int.net/gfwlist +server=/applehongkong.com/127.0.0.1#5335 +ipset=/applehongkong.com/gfwlist +server=/gears5.com/127.0.0.1#5335 +ipset=/gears5.com/gfwlist +server=/foxsports.co.ve/127.0.0.1#5335 +ipset=/foxsports.co.ve/gfwlist +server=/gettyimages.ae/127.0.0.1#5335 +ipset=/gettyimages.ae/gfwlist +server=/magento.net/127.0.0.1#5335 +ipset=/magento.net/gfwlist +server=/ulifestyle.com.hk/127.0.0.1#5335 +ipset=/ulifestyle.com.hk/gfwlist +server=/alphabet.at/127.0.0.1#5335 +ipset=/alphabet.at/gfwlist +server=/origin.tv/127.0.0.1#5335 +ipset=/origin.tv/gfwlist +server=/bmw-connecteddrive.com/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com/gfwlist +server=/efproject.net/127.0.0.1#5335 +ipset=/efproject.net/gfwlist +server=/dat.foundation/127.0.0.1#5335 +ipset=/dat.foundation/gfwlist +server=/ebayauction.com/127.0.0.1#5335 +ipset=/ebayauction.com/gfwlist +server=/bookshome.info/127.0.0.1#5335 +ipset=/bookshome.info/gfwlist +server=/am730.com.hk/127.0.0.1#5335 +ipset=/am730.com.hk/gfwlist +server=/beats4outlets.com/127.0.0.1#5335 +ipset=/beats4outlets.com/gfwlist +server=/disney.ch/127.0.0.1#5335 +ipset=/disney.ch/gfwlist +server=/jav01.cc/127.0.0.1#5335 +ipset=/jav01.cc/gfwlist +server=/bmw-rrdays.com/127.0.0.1#5335 +ipset=/bmw-rrdays.com/gfwlist +server=/mini.fr/127.0.0.1#5335 +ipset=/mini.fr/gfwlist +server=/crmdynint.com/127.0.0.1#5335 +ipset=/crmdynint.com/gfwlist +server=/ciscoresearch.com/127.0.0.1#5335 +ipset=/ciscoresearch.com/gfwlist +server=/hentai-moon.com/127.0.0.1#5335 +ipset=/hentai-moon.com/gfwlist +server=/crmdynint-gcc.com/127.0.0.1#5335 +ipset=/crmdynint-gcc.com/gfwlist +server=/entermediadb.net/127.0.0.1#5335 +ipset=/entermediadb.net/gfwlist +server=/gu-web.net/127.0.0.1#5335 +ipset=/gu-web.net/gfwlist +server=/4u4c.com/127.0.0.1#5335 +ipset=/4u4c.com/gfwlist +server=/paypalindia.com/127.0.0.1#5335 +ipset=/paypalindia.com/gfwlist +server=/coreml.net/127.0.0.1#5335 +ipset=/coreml.net/gfwlist +server=/cloudappsecurity.com/127.0.0.1#5335 +ipset=/cloudappsecurity.com/gfwlist +server=/amateurwifefuck.com/127.0.0.1#5335 +ipset=/amateurwifefuck.com/gfwlist +server=/cloudapp.net/127.0.0.1#5335 +ipset=/cloudapp.net/gfwlist +server=/youtube.vn/127.0.0.1#5335 +ipset=/youtube.vn/gfwlist +server=/lubetube.com/127.0.0.1#5335 +ipset=/lubetube.com/gfwlist +server=/applecom.com/127.0.0.1#5335 +ipset=/applecom.com/gfwlist +server=/now-tv.com/127.0.0.1#5335 +ipset=/now-tv.com/gfwlist +server=/coinglass.com/127.0.0.1#5335 +ipset=/coinglass.com/gfwlist +server=/youtube.cz/127.0.0.1#5335 +ipset=/youtube.cz/gfwlist +server=/mini.ua/127.0.0.1#5335 +ipset=/mini.ua/gfwlist +server=/bmw.com.tw/127.0.0.1#5335 +ipset=/bmw.com.tw/gfwlist +server=/applestore.com.au/127.0.0.1#5335 +ipset=/applestore.com.au/gfwlist +server=/mini.ca/127.0.0.1#5335 +ipset=/mini.ca/gfwlist +server=/centralvalidation.com/127.0.0.1#5335 +ipset=/centralvalidation.com/gfwlist +server=/bmwgroup.net/127.0.0.1#5335 +ipset=/bmwgroup.net/gfwlist +server=/thesims4.com/127.0.0.1#5335 +ipset=/thesims4.com/gfwlist +server=/brazilpartneruniversity.com/127.0.0.1#5335 +ipset=/brazilpartneruniversity.com/gfwlist +server=/heroku.com/127.0.0.1#5335 +ipset=/heroku.com/gfwlist +server=/osakamotion.net/127.0.0.1#5335 +ipset=/osakamotion.net/gfwlist +server=/collector.xhamster.com/127.0.0.1#5335 +ipset=/collector.xhamster.com/gfwlist +server=/asp.net/127.0.0.1#5335 +ipset=/asp.net/gfwlist +server=/princeton.edu/127.0.0.1#5335 +ipset=/princeton.edu/gfwlist +server=/gdsrx888.com/127.0.0.1#5335 +ipset=/gdsrx888.com/gfwlist +server=/barelist.com/127.0.0.1#5335 +ipset=/barelist.com/gfwlist +server=/battlelog.com/127.0.0.1#5335 +ipset=/battlelog.com/gfwlist +server=/applicationinsights.net/127.0.0.1#5335 +ipset=/applicationinsights.net/gfwlist +server=/camfinder.com/127.0.0.1#5335 +ipset=/camfinder.com/gfwlist +server=/ebay.at/127.0.0.1#5335 +ipset=/ebay.at/gfwlist +server=/musicbay.net/127.0.0.1#5335 +ipset=/musicbay.net/gfwlist +server=/blogspot.com.ar/127.0.0.1#5335 +ipset=/blogspot.com.ar/gfwlist +server=/aka.ms/127.0.0.1#5335 +ipset=/aka.ms/gfwlist +server=/m12.vc/127.0.0.1#5335 +ipset=/m12.vc/gfwlist +server=/teensnow.link/127.0.0.1#5335 +ipset=/teensnow.link/gfwlist +server=/faceboop.com/127.0.0.1#5335 +ipset=/faceboop.com/gfwlist +server=/playshow.io/127.0.0.1#5335 +ipset=/playshow.io/gfwlist +server=/adobetarget.com/127.0.0.1#5335 +ipset=/adobetarget.com/gfwlist +server=/wwtbam.com/127.0.0.1#5335 +ipset=/wwtbam.com/gfwlist +server=/91sesex.xyz/127.0.0.1#5335 +ipset=/91sesex.xyz/gfwlist +server=/webcammedellin.co/127.0.0.1#5335 +ipset=/webcammedellin.co/gfwlist +server=/paypall.com/127.0.0.1#5335 +ipset=/paypall.com/gfwlist +server=/steam.eca.qtlglb.com/127.0.0.1#5335 +ipset=/steam.eca.qtlglb.com/gfwlist +server=/mini.cc/127.0.0.1#5335 +ipset=/mini.cc/gfwlist +server=/qualcommventures.com/127.0.0.1#5335 +ipset=/qualcommventures.com/gfwlist +server=/hdsexxx.net/127.0.0.1#5335 +ipset=/hdsexxx.net/gfwlist +server=/egotastic.com/127.0.0.1#5335 +ipset=/egotastic.com/gfwlist +server=/xn--hckl3e1e8a8ajin0czf.net/127.0.0.1#5335 +ipset=/xn--hckl3e1e8a8ajin0czf.net/gfwlist +server=/nike.ci/127.0.0.1#5335 +ipset=/nike.ci/gfwlist +server=/naughtyhentai.biz/127.0.0.1#5335 +ipset=/naughtyhentai.biz/gfwlist +server=/microsoft.si/127.0.0.1#5335 +ipset=/microsoft.si/gfwlist +server=/convrgencegame.com/127.0.0.1#5335 +ipset=/convrgencegame.com/gfwlist +server=/yourpelvicultrasound.com/127.0.0.1#5335 +ipset=/yourpelvicultrasound.com/gfwlist +server=/goodporno.cc/127.0.0.1#5335 +ipset=/goodporno.cc/gfwlist +server=/microsoft.red/127.0.0.1#5335 +ipset=/microsoft.red/gfwlist +server=/curbed.com/127.0.0.1#5335 +ipset=/curbed.com/gfwlist +server=/shemaleleaks.com/127.0.0.1#5335 +ipset=/shemaleleaks.com/gfwlist +server=/googlearth.com/127.0.0.1#5335 +ipset=/googlearth.com/gfwlist +server=/urduvoa.com/127.0.0.1#5335 +ipset=/urduvoa.com/gfwlist +server=/mastercardcenterforinclusivegrowth.org/127.0.0.1#5335 +ipset=/mastercardcenterforinclusivegrowth.org/gfwlist +server=/minipetfriendly.com/127.0.0.1#5335 +ipset=/minipetfriendly.com/gfwlist +server=/youtube.pl/127.0.0.1#5335 +ipset=/youtube.pl/gfwlist +server=/microsoft.net/127.0.0.1#5335 +ipset=/microsoft.net/gfwlist +server=/relateiq.com/127.0.0.1#5335 +ipset=/relateiq.com/gfwlist +server=/amateurest.com/127.0.0.1#5335 +ipset=/amateurest.com/gfwlist +server=/paypal-specialoffers.com/127.0.0.1#5335 +ipset=/paypal-specialoffers.com/gfwlist +server=/sandisk.es/127.0.0.1#5335 +ipset=/sandisk.es/gfwlist +server=/cloudlock.com/127.0.0.1#5335 +ipset=/cloudlock.com/gfwlist +server=/nudewifeporn.com/127.0.0.1#5335 +ipset=/nudewifeporn.com/gfwlist +server=/microsoft.lt/127.0.0.1#5335 +ipset=/microsoft.lt/gfwlist +server=/microsoft.jp/127.0.0.1#5335 +ipset=/microsoft.jp/gfwlist +server=/fdiintelligence.com/127.0.0.1#5335 +ipset=/fdiintelligence.com/gfwlist +server=/w3.org/127.0.0.1#5335 +ipset=/w3.org/gfwlist +server=/javlibrary.com/127.0.0.1#5335 +ipset=/javlibrary.com/gfwlist +server=/safechat.com/127.0.0.1#5335 +ipset=/safechat.com/gfwlist +server=/beatsbydre-store.com/127.0.0.1#5335 +ipset=/beatsbydre-store.com/gfwlist +server=/avbebe.com/127.0.0.1#5335 +ipset=/avbebe.com/gfwlist +server=/autodraw.com/127.0.0.1#5335 +ipset=/autodraw.com/gfwlist +server=/microsoft.io/127.0.0.1#5335 +ipset=/microsoft.io/gfwlist +server=/paypal-galactic.com/127.0.0.1#5335 +ipset=/paypal-galactic.com/gfwlist +server=/scholar.google.se/127.0.0.1#5335 +ipset=/scholar.google.se/gfwlist +server=/vaginal-ultrasound.com/127.0.0.1#5335 +ipset=/vaginal-ultrasound.com/gfwlist +server=/mac.com.au/127.0.0.1#5335 +ipset=/mac.com.au/gfwlist +server=/momsboysmovies.net/127.0.0.1#5335 +ipset=/momsboysmovies.net/gfwlist +server=/microsoft.eu/127.0.0.1#5335 +ipset=/microsoft.eu/gfwlist +server=/microsoft.es/127.0.0.1#5335 +ipset=/microsoft.es/gfwlist +server=/google.bg/127.0.0.1#5335 +ipset=/google.bg/gfwlist +server=/voatour.com/127.0.0.1#5335 +ipset=/voatour.com/gfwlist +server=/disneymovieinsiders.com/127.0.0.1#5335 +ipset=/disneymovieinsiders.com/gfwlist +server=/pypl.net/127.0.0.1#5335 +ipset=/pypl.net/gfwlist +server=/swisssign.ch/127.0.0.1#5335 +ipset=/swisssign.ch/gfwlist +server=/fbthirdpartypixel.net/127.0.0.1#5335 +ipset=/fbthirdpartypixel.net/gfwlist +server=/pieceofplastic.com/127.0.0.1#5335 +ipset=/pieceofplastic.com/gfwlist +server=/heaven-burns-red.com/127.0.0.1#5335 +ipset=/heaven-burns-red.com/gfwlist +server=/visa.pl/127.0.0.1#5335 +ipset=/visa.pl/gfwlist +server=/fantasticyoungporn.com/127.0.0.1#5335 +ipset=/fantasticyoungporn.com/gfwlist +server=/rocksdb.net/127.0.0.1#5335 +ipset=/rocksdb.net/gfwlist +server=/sony.com/127.0.0.1#5335 +ipset=/sony.com/gfwlist +server=/b-ok.africa/127.0.0.1#5335 +ipset=/b-ok.africa/gfwlist +server=/nikeincchemistry.com/127.0.0.1#5335 +ipset=/nikeincchemistry.com/gfwlist +server=/pornpair.com/127.0.0.1#5335 +ipset=/pornpair.com/gfwlist +server=/half.com/127.0.0.1#5335 +ipset=/half.com/gfwlist +server=/telegram.me/127.0.0.1#5335 +ipset=/telegram.me/gfwlist +server=/mastercard.by/127.0.0.1#5335 +ipset=/mastercard.by/gfwlist +server=/xxxclub.club/127.0.0.1#5335 +ipset=/xxxclub.club/gfwlist +server=/pornhat.tv/127.0.0.1#5335 +ipset=/pornhat.tv/gfwlist +server=/microsoft.ch/127.0.0.1#5335 +ipset=/microsoft.ch/gfwlist +server=/virtualrealgay.com/127.0.0.1#5335 +ipset=/virtualrealgay.com/gfwlist +server=/cbsnews.com/127.0.0.1#5335 +ipset=/cbsnews.com/gfwlist +server=/metamind.io/127.0.0.1#5335 +ipset=/metamind.io/gfwlist +server=/google.pn/127.0.0.1#5335 +ipset=/google.pn/gfwlist +server=/greginhollywood.com/127.0.0.1#5335 +ipset=/greginhollywood.com/gfwlist +server=/foxsportsgo.com/127.0.0.1#5335 +ipset=/foxsportsgo.com/gfwlist +server=/youtube.com.co/127.0.0.1#5335 +ipset=/youtube.com.co/gfwlist +server=/discountporn.club/127.0.0.1#5335 +ipset=/discountporn.club/gfwlist +server=/areyoucreditwise.com/127.0.0.1#5335 +ipset=/areyoucreditwise.com/gfwlist +server=/enemabasics.com/127.0.0.1#5335 +ipset=/enemabasics.com/gfwlist +server=/amateuroldsluts.com/127.0.0.1#5335 +ipset=/amateuroldsluts.com/gfwlist +server=/walmart.com/127.0.0.1#5335 +ipset=/walmart.com/gfwlist +server=/analpornhouse.com/127.0.0.1#5335 +ipset=/analpornhouse.com/gfwlist +server=/nikekd.com/127.0.0.1#5335 +ipset=/nikekd.com/gfwlist +server=/9to5mac.com/127.0.0.1#5335 +ipset=/9to5mac.com/gfwlist +server=/bubbaporn.com/127.0.0.1#5335 +ipset=/bubbaporn.com/gfwlist +server=/udemy.com/127.0.0.1#5335 +ipset=/udemy.com/gfwlist +server=/ozodi.org/127.0.0.1#5335 +ipset=/ozodi.org/gfwlist +server=/faronicslabs.com/127.0.0.1#5335 +ipset=/faronicslabs.com/gfwlist +server=/playerjs.io/127.0.0.1#5335 +ipset=/playerjs.io/gfwlist +server=/sprinklesapp.com/127.0.0.1#5335 +ipset=/sprinklesapp.com/gfwlist +server=/microsoft.az/127.0.0.1#5335 +ipset=/microsoft.az/gfwlist +server=/canon.de/127.0.0.1#5335 +ipset=/canon.de/gfwlist +server=/naoconto.com/127.0.0.1#5335 +ipset=/naoconto.com/gfwlist +server=/onedrive.org/127.0.0.1#5335 +ipset=/onedrive.org/gfwlist +server=/pvp.net/127.0.0.1#5335 +ipset=/pvp.net/gfwlist +server=/onedrive.net/127.0.0.1#5335 +ipset=/onedrive.net/gfwlist +server=/onedrive.eu/127.0.0.1#5335 +ipset=/onedrive.eu/gfwlist +server=/packagist.org/127.0.0.1#5335 +ipset=/packagist.org/gfwlist +server=/onedrive.com/127.0.0.1#5335 +ipset=/onedrive.com/gfwlist +server=/livefilestore.com/127.0.0.1#5335 +ipset=/livefilestore.com/gfwlist +server=/zoophilist.net/127.0.0.1#5335 +ipset=/zoophilist.net/gfwlist +server=/ebaymotors.ca/127.0.0.1#5335 +ipset=/ebaymotors.ca/gfwlist +server=/msnkids.com/127.0.0.1#5335 +ipset=/msnkids.com/gfwlist +server=/yahoo.az/127.0.0.1#5335 +ipset=/yahoo.az/gfwlist +server=/scholar.google.com.sg/127.0.0.1#5335 +ipset=/scholar.google.com.sg/gfwlist +server=/xnxx.com/127.0.0.1#5335 +ipset=/xnxx.com/gfwlist +server=/msnewskids.org/127.0.0.1#5335 +ipset=/msnewskids.org/gfwlist +server=/fecbook.com/127.0.0.1#5335 +ipset=/fecbook.com/gfwlist +server=/embl-hamburg.de/127.0.0.1#5335 +ipset=/embl-hamburg.de/gfwlist +server=/msnewskids.net/127.0.0.1#5335 +ipset=/msnewskids.net/gfwlist +server=/msnewskids.com/127.0.0.1#5335 +ipset=/msnewskids.com/gfwlist +server=/enjoyfuck.com/127.0.0.1#5335 +ipset=/enjoyfuck.com/gfwlist +server=/bs-awh.ne.jp/127.0.0.1#5335 +ipset=/bs-awh.ne.jp/gfwlist +server=/clannad-movie.jp/127.0.0.1#5335 +ipset=/clannad-movie.jp/gfwlist +server=/microsoftnewskids.org/127.0.0.1#5335 +ipset=/microsoftnewskids.org/gfwlist +server=/microsoftnewskids.net/127.0.0.1#5335 +ipset=/microsoftnewskids.net/gfwlist +server=/kimogirl.cc/127.0.0.1#5335 +ipset=/kimogirl.cc/gfwlist +server=/microsoftnewsforkids.org/127.0.0.1#5335 +ipset=/microsoftnewsforkids.org/gfwlist +server=/swiftfinancial.info/127.0.0.1#5335 +ipset=/swiftfinancial.info/gfwlist +server=/svaboda.org/127.0.0.1#5335 +ipset=/svaboda.org/gfwlist +server=/facbebook.com/127.0.0.1#5335 +ipset=/facbebook.com/gfwlist +server=/foxdeportes.net/127.0.0.1#5335 +ipset=/foxdeportes.net/gfwlist +server=/ahorsecock.com/127.0.0.1#5335 +ipset=/ahorsecock.com/gfwlist +server=/foxnation.com/127.0.0.1#5335 +ipset=/foxnation.com/gfwlist +server=/wiseid.com/127.0.0.1#5335 +ipset=/wiseid.com/gfwlist +server=/microsoftnewsforkids.com/127.0.0.1#5335 +ipset=/microsoftnewsforkids.com/gfwlist +server=/microsoftnews.net/127.0.0.1#5335 +ipset=/microsoftnews.net/gfwlist +server=/renovacionoffice.com/127.0.0.1#5335 +ipset=/renovacionoffice.com/gfwlist +server=/sstatic.net/127.0.0.1#5335 +ipset=/sstatic.net/gfwlist +server=/microsoftmxfilantropia.com/127.0.0.1#5335 +ipset=/microsoftmxfilantropia.com/gfwlist +server=/monsterbeatsbydrdre-nz.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrdre-nz.com/gfwlist +server=/amabitch.com/127.0.0.1#5335 +ipset=/amabitch.com/gfwlist +server=/zeit-world.org/127.0.0.1#5335 +ipset=/zeit-world.org/gfwlist +server=/amateurpages.com/127.0.0.1#5335 +ipset=/amateurpages.com/gfwlist +server=/cilk.net/127.0.0.1#5335 +ipset=/cilk.net/gfwlist +server=/cheapbeatsaustraliasale.com/127.0.0.1#5335 +ipset=/cheapbeatsaustraliasale.com/gfwlist +server=/airwick.it/127.0.0.1#5335 +ipset=/airwick.it/gfwlist +server=/masalladeloslimites.com/127.0.0.1#5335 +ipset=/masalladeloslimites.com/gfwlist +server=/afriboyz.com/127.0.0.1#5335 +ipset=/afriboyz.com/gfwlist +server=/voanoticias.com/127.0.0.1#5335 +ipset=/voanoticias.com/gfwlist +server=/guambmw.com/127.0.0.1#5335 +ipset=/guambmw.com/gfwlist +server=/flipwithsurface.com/127.0.0.1#5335 +ipset=/flipwithsurface.com/gfwlist +server=/dictate.ms/127.0.0.1#5335 +ipset=/dictate.ms/gfwlist +server=/wellfuckedwife.com/127.0.0.1#5335 +ipset=/wellfuckedwife.com/gfwlist +server=/subscene.com/127.0.0.1#5335 +ipset=/subscene.com/gfwlist +server=/hentaix.me/127.0.0.1#5335 +ipset=/hentaix.me/gfwlist +server=/kkbox.com/127.0.0.1#5335 +ipset=/kkbox.com/gfwlist +server=/ads.pubmatic.com/127.0.0.1#5335 +ipset=/ads.pubmatic.com/gfwlist +server=/exgirlfriendmarket.com/127.0.0.1#5335 +ipset=/exgirlfriendmarket.com/gfwlist +server=/lepornochaud.com/127.0.0.1#5335 +ipset=/lepornochaud.com/gfwlist +server=/bisyoujyogyaruge.topaz.ne.jp/127.0.0.1#5335 +ipset=/bisyoujyogyaruge.topaz.ne.jp/gfwlist +server=/adobesign.com/127.0.0.1#5335 +ipset=/adobesign.com/gfwlist +server=/minihalifax.ca/127.0.0.1#5335 +ipset=/minihalifax.ca/gfwlist +server=/dailybasis.com/127.0.0.1#5335 +ipset=/dailybasis.com/gfwlist +server=/harpercollins.co.uk/127.0.0.1#5335 +ipset=/harpercollins.co.uk/gfwlist +server=/bing.net/127.0.0.1#5335 +ipset=/bing.net/gfwlist +server=/theinstagramhack.com/127.0.0.1#5335 +ipset=/theinstagramhack.com/gfwlist +server=/azure-dns.org/127.0.0.1#5335 +ipset=/azure-dns.org/gfwlist +server=/azure-dns.info/127.0.0.1#5335 +ipset=/azure-dns.info/gfwlist +server=/mocloudplus.com/127.0.0.1#5335 +ipset=/mocloudplus.com/gfwlist +server=/ebayincconnectedcommerce.net/127.0.0.1#5335 +ipset=/ebayincconnectedcommerce.net/gfwlist +server=/disney.it/127.0.0.1#5335 +ipset=/disney.it/gfwlist +server=/steamofporn.com/127.0.0.1#5335 +ipset=/steamofporn.com/gfwlist +server=/tomatespodres.com/127.0.0.1#5335 +ipset=/tomatespodres.com/gfwlist +server=/gsuite.com/127.0.0.1#5335 +ipset=/gsuite.com/gfwlist +server=/windowsazure.com/127.0.0.1#5335 +ipset=/windowsazure.com/gfwlist +server=/workspaceone.com/127.0.0.1#5335 +ipset=/workspaceone.com/gfwlist +server=/picacomic.com/127.0.0.1#5335 +ipset=/picacomic.com/gfwlist +server=/trafficmanager.net/127.0.0.1#5335 +ipset=/trafficmanager.net/gfwlist +server=/bestpornsites.eu/127.0.0.1#5335 +ipset=/bestpornsites.eu/gfwlist +server=/awsloft-johannesburg.com/127.0.0.1#5335 +ipset=/awsloft-johannesburg.com/gfwlist +server=/foxsoccermatchpass.com/127.0.0.1#5335 +ipset=/foxsoccermatchpass.com/gfwlist +server=/starbucks.co.za/127.0.0.1#5335 +ipset=/starbucks.co.za/gfwlist +server=/jetbrains.com/127.0.0.1#5335 +ipset=/jetbrains.com/gfwlist +server=/hotcumporn.com/127.0.0.1#5335 +ipset=/hotcumporn.com/gfwlist +server=/huffingtonpost.it/127.0.0.1#5335 +ipset=/huffingtonpost.it/gfwlist +server=/direcpath.com/127.0.0.1#5335 +ipset=/direcpath.com/gfwlist +server=/gotcosmos.com/127.0.0.1#5335 +ipset=/gotcosmos.com/gfwlist +server=/devopsms.com/127.0.0.1#5335 +ipset=/devopsms.com/gfwlist +server=/beats-bydreuk.com/127.0.0.1#5335 +ipset=/beats-bydreuk.com/gfwlist +server=/pricelesssantiago.com/127.0.0.1#5335 +ipset=/pricelesssantiago.com/gfwlist +server=/printeron.com/127.0.0.1#5335 +ipset=/printeron.com/gfwlist +server=/visa.com.ph/127.0.0.1#5335 +ipset=/visa.com.ph/gfwlist +server=/embed-cdn.com/127.0.0.1#5335 +ipset=/embed-cdn.com/gfwlist +server=/minidowntown.com/127.0.0.1#5335 +ipset=/minidowntown.com/gfwlist +server=/azurewebsites.net/127.0.0.1#5335 +ipset=/azurewebsites.net/gfwlist +server=/ebaypark.com/127.0.0.1#5335 +ipset=/ebaypark.com/gfwlist +server=/azuresmartspaces.net/127.0.0.1#5335 +ipset=/azuresmartspaces.net/gfwlist +server=/md.hkgolden.com/127.0.0.1#5335 +ipset=/md.hkgolden.com/gfwlist +server=/ero-mangalife.com/127.0.0.1#5335 +ipset=/ero-mangalife.com/gfwlist +server=/newbrazz.com/127.0.0.1#5335 +ipset=/newbrazz.com/gfwlist +server=/javdb.com/127.0.0.1#5335 +ipset=/javdb.com/gfwlist +server=/azureserviceprofiler.com/127.0.0.1#5335 +ipset=/azureserviceprofiler.com/gfwlist +server=/msgamesresearch.com/127.0.0.1#5335 +ipset=/msgamesresearch.com/gfwlist +server=/youlucky.com/127.0.0.1#5335 +ipset=/youlucky.com/gfwlist +server=/enemahistory.com/127.0.0.1#5335 +ipset=/enemahistory.com/gfwlist +server=/lovemarca.com/127.0.0.1#5335 +ipset=/lovemarca.com/gfwlist +server=/cheapbeatsdrdresolo.com/127.0.0.1#5335 +ipset=/cheapbeatsdrdresolo.com/gfwlist +server=/anal-pantyhose.com/127.0.0.1#5335 +ipset=/anal-pantyhose.com/gfwlist +server=/maddenseason.info/127.0.0.1#5335 +ipset=/maddenseason.info/gfwlist +server=/steampipe-partner.akamaized.net/127.0.0.1#5335 +ipset=/steampipe-partner.akamaized.net/gfwlist +server=/poisontube.com/127.0.0.1#5335 +ipset=/poisontube.com/gfwlist +server=/hpstore.corpmerchandise.com/127.0.0.1#5335 +ipset=/hpstore.corpmerchandise.com/gfwlist +server=/eafootballworld.com/127.0.0.1#5335 +ipset=/eafootballworld.com/gfwlist +server=/yahoo.com.es/127.0.0.1#5335 +ipset=/yahoo.com.es/gfwlist +server=/cam69.com/127.0.0.1#5335 +ipset=/cam69.com/gfwlist +server=/azuredns-prd.info/127.0.0.1#5335 +ipset=/azuredns-prd.info/gfwlist +server=/largecamtube.com/127.0.0.1#5335 +ipset=/largecamtube.com/gfwlist +server=/siri.com/127.0.0.1#5335 +ipset=/siri.com/gfwlist +server=/prd-priconne-redive.akamaized.net/127.0.0.1#5335 +ipset=/prd-priconne-redive.akamaized.net/gfwlist +server=/azuredigitaltwins.com/127.0.0.1#5335 +ipset=/azuredigitaltwins.com/gfwlist +server=/openapiplatform.com/127.0.0.1#5335 +ipset=/openapiplatform.com/gfwlist +server=/azuredigitaltwin.com/127.0.0.1#5335 +ipset=/azuredigitaltwin.com/gfwlist +server=/get.how/127.0.0.1#5335 +ipset=/get.how/gfwlist +server=/azuredatabricks.net/127.0.0.1#5335 +ipset=/azuredatabricks.net/gfwlist +server=/facebkkk.com/127.0.0.1#5335 +ipset=/facebkkk.com/gfwlist +server=/yahoo.lv/127.0.0.1#5335 +ipset=/yahoo.lv/gfwlist +server=/playz.jp/127.0.0.1#5335 +ipset=/playz.jp/gfwlist +server=/veryshortintroductions.com/127.0.0.1#5335 +ipset=/veryshortintroductions.com/gfwlist +server=/typekit.com/127.0.0.1#5335 +ipset=/typekit.com/gfwlist +server=/paypal-exchanges.com/127.0.0.1#5335 +ipset=/paypal-exchanges.com/gfwlist +server=/mini-e.com/127.0.0.1#5335 +ipset=/mini-e.com/gfwlist +server=/azurecosmosdb.com/127.0.0.1#5335 +ipset=/azurecosmosdb.com/gfwlist +server=/mobilepornmovies.com/127.0.0.1#5335 +ipset=/mobilepornmovies.com/gfwlist +server=/azurecosmos.net/127.0.0.1#5335 +ipset=/azurecosmos.net/gfwlist +server=/azurecontainer.io/127.0.0.1#5335 +ipset=/azurecontainer.io/gfwlist +server=/stadia.dev/127.0.0.1#5335 +ipset=/stadia.dev/gfwlist +server=/redkix.com/127.0.0.1#5335 +ipset=/redkix.com/gfwlist +server=/attwatchtv.com/127.0.0.1#5335 +ipset=/attwatchtv.com/gfwlist +server=/pearson.com.au/127.0.0.1#5335 +ipset=/pearson.com.au/gfwlist +server=/brokenteens.com/127.0.0.1#5335 +ipset=/brokenteens.com/gfwlist +server=/bestbuy.com.mx/127.0.0.1#5335 +ipset=/bestbuy.com.mx/gfwlist +server=/ebayclassifies.com/127.0.0.1#5335 +ipset=/ebayclassifies.com/gfwlist +server=/sexycandidgirls.com/127.0.0.1#5335 +ipset=/sexycandidgirls.com/gfwlist +server=/fullbookmm.blogspot.com/127.0.0.1#5335 +ipset=/fullbookmm.blogspot.com/gfwlist +server=/aflamsex.net/127.0.0.1#5335 +ipset=/aflamsex.net/gfwlist +server=/gucci.com/127.0.0.1#5335 +ipset=/gucci.com/gfwlist +server=/thetype.com/127.0.0.1#5335 +ipset=/thetype.com/gfwlist +server=/verilystudyhub.com/127.0.0.1#5335 +ipset=/verilystudyhub.com/gfwlist +server=/2014cheapbeatsbydre.com/127.0.0.1#5335 +ipset=/2014cheapbeatsbydre.com/gfwlist +server=/azure.com/127.0.0.1#5335 +ipset=/azure.com/gfwlist +server=/minivilledequebec.ca/127.0.0.1#5335 +ipset=/minivilledequebec.ca/gfwlist +server=/azure-test.net/127.0.0.1#5335 +ipset=/azure-test.net/gfwlist +server=/pki.goog/127.0.0.1#5335 +ipset=/pki.goog/gfwlist +server=/braintreepayments.com/127.0.0.1#5335 +ipset=/braintreepayments.com/gfwlist +server=/azure-devices-int.net/127.0.0.1#5335 +ipset=/azure-devices-int.net/gfwlist +server=/translatetheweb.com/127.0.0.1#5335 +ipset=/translatetheweb.com/gfwlist +server=/londonhotescort.com/127.0.0.1#5335 +ipset=/londonhotescort.com/gfwlist +server=/oculusvr.com/127.0.0.1#5335 +ipset=/oculusvr.com/gfwlist +server=/inaporn.com/127.0.0.1#5335 +ipset=/inaporn.com/gfwlist +server=/paypal-knowledge.com/127.0.0.1#5335 +ipset=/paypal-knowledge.com/gfwlist +server=/oculusconnect.com/127.0.0.1#5335 +ipset=/oculusconnect.com/gfwlist +server=/managed-pki.de/127.0.0.1#5335 +ipset=/managed-pki.de/gfwlist +server=/wiiugamepad.com/127.0.0.1#5335 +ipset=/wiiugamepad.com/gfwlist +server=/oculusbrand.com/127.0.0.1#5335 +ipset=/oculusbrand.com/gfwlist +server=/googlecompare.co.uk/127.0.0.1#5335 +ipset=/googlecompare.co.uk/gfwlist +server=/nikebetrue.com/127.0.0.1#5335 +ipset=/nikebetrue.com/gfwlist +server=/bmw-pakistan.com/127.0.0.1#5335 +ipset=/bmw-pakistan.com/gfwlist +server=/superadultgames.com/127.0.0.1#5335 +ipset=/superadultgames.com/gfwlist +server=/youtube.googleapis.com/127.0.0.1#5335 +ipset=/youtube.googleapis.com/gfwlist +server=/x18r.com/127.0.0.1#5335 +ipset=/x18r.com/gfwlist +server=/wsjbarrons.com/127.0.0.1#5335 +ipset=/wsjbarrons.com/gfwlist +server=/volvotrucks.com.pt/127.0.0.1#5335 +ipset=/volvotrucks.com.pt/gfwlist +server=/streamate.com/127.0.0.1#5335 +ipset=/streamate.com/gfwlist +server=/thisispolaris.com/127.0.0.1#5335 +ipset=/thisispolaris.com/gfwlist +server=/cloudflarestorage.com/127.0.0.1#5335 +ipset=/cloudflarestorage.com/gfwlist +server=/ikea.co.ca/127.0.0.1#5335 +ipset=/ikea.co.ca/gfwlist +server=/binoculus.com/127.0.0.1#5335 +ipset=/binoculus.com/gfwlist +server=/intel.pa/127.0.0.1#5335 +ipset=/intel.pa/gfwlist +server=/mycdn.me/127.0.0.1#5335 +ipset=/mycdn.me/gfwlist +server=/1degree.com.au/127.0.0.1#5335 +ipset=/1degree.com.au/gfwlist +server=/webgata.net/127.0.0.1#5335 +ipset=/webgata.net/gfwlist +server=/mydirectvchannels.com/127.0.0.1#5335 +ipset=/mydirectvchannels.com/gfwlist +server=/rocksextube.com/127.0.0.1#5335 +ipset=/rocksextube.com/gfwlist +server=/volvobuses.kr/127.0.0.1#5335 +ipset=/volvobuses.kr/gfwlist +server=/tube8.fr/127.0.0.1#5335 +ipset=/tube8.fr/gfwlist +server=/filmeporno.xxx/127.0.0.1#5335 +ipset=/filmeporno.xxx/gfwlist +server=/iutunes.com/127.0.0.1#5335 +ipset=/iutunes.com/gfwlist +server=/cartoontube.com/127.0.0.1#5335 +ipset=/cartoontube.com/gfwlist +server=/logitech.fr/127.0.0.1#5335 +ipset=/logitech.fr/gfwlist +server=/theaustralian.com.au/127.0.0.1#5335 +ipset=/theaustralian.com.au/gfwlist +server=/ieee-ceda.org/127.0.0.1#5335 +ipset=/ieee-ceda.org/gfwlist +server=/voathai.com/127.0.0.1#5335 +ipset=/voathai.com/gfwlist +server=/lolstatic.com/127.0.0.1#5335 +ipset=/lolstatic.com/gfwlist +server=/xxxtubedot.com/127.0.0.1#5335 +ipset=/xxxtubedot.com/gfwlist +server=/logitech.com/127.0.0.1#5335 +ipset=/logitech.com/gfwlist +server=/comicbox.xyz/127.0.0.1#5335 +ipset=/comicbox.xyz/gfwlist +server=/supersexeamateur.com/127.0.0.1#5335 +ipset=/supersexeamateur.com/gfwlist +server=/headphoneses.com/127.0.0.1#5335 +ipset=/headphoneses.com/gfwlist +server=/mini-connected.pl/127.0.0.1#5335 +ipset=/mini-connected.pl/gfwlist +server=/youtube.lv/127.0.0.1#5335 +ipset=/youtube.lv/gfwlist +server=/logi.com/127.0.0.1#5335 +ipset=/logi.com/gfwlist +server=/pinterest.dk/127.0.0.1#5335 +ipset=/pinterest.dk/gfwlist +server=/lgelectronics.122.2o7.net/127.0.0.1#5335 +ipset=/lgelectronics.122.2o7.net/gfwlist +server=/freesexgames.ws/127.0.0.1#5335 +ipset=/freesexgames.ws/gfwlist +server=/vipshoes2.com/127.0.0.1#5335 +ipset=/vipshoes2.com/gfwlist +server=/baazee.com/127.0.0.1#5335 +ipset=/baazee.com/gfwlist +server=/hotfucktube.com/127.0.0.1#5335 +ipset=/hotfucktube.com/gfwlist +server=/lgrecyclingprogram.com/127.0.0.1#5335 +ipset=/lgrecyclingprogram.com/gfwlist +server=/avple.tv/127.0.0.1#5335 +ipset=/avple.tv/gfwlist +server=/lghvac.com/127.0.0.1#5335 +ipset=/lghvac.com/gfwlist +server=/mandatewire.com/127.0.0.1#5335 +ipset=/mandatewire.com/gfwlist +server=/google.com.vc/127.0.0.1#5335 +ipset=/google.com.vc/gfwlist +server=/nintendo.fr/127.0.0.1#5335 +ipset=/nintendo.fr/gfwlist +server=/vcloudair.net/127.0.0.1#5335 +ipset=/vcloudair.net/gfwlist +server=/bmw.nc/127.0.0.1#5335 +ipset=/bmw.nc/gfwlist +server=/jfengtime.com/127.0.0.1#5335 +ipset=/jfengtime.com/gfwlist +server=/erotictube.me/127.0.0.1#5335 +ipset=/erotictube.me/gfwlist +server=/vfsco.com.au/127.0.0.1#5335 +ipset=/vfsco.com.au/gfwlist +server=/lg.com/127.0.0.1#5335 +ipset=/lg.com/gfwlist +server=/trustisfps.com/127.0.0.1#5335 +ipset=/trustisfps.com/gfwlist +server=/public-trust.com/127.0.0.1#5335 +ipset=/public-trust.com/gfwlist +server=/yaoimangaonline.com/127.0.0.1#5335 +ipset=/yaoimangaonline.com/gfwlist +server=/trustedanalytics.com/127.0.0.1#5335 +ipset=/trustedanalytics.com/gfwlist +server=/nvidia.com.au/127.0.0.1#5335 +ipset=/nvidia.com.au/gfwlist +server=/kink.com/127.0.0.1#5335 +ipset=/kink.com/gfwlist +server=/openvinotoolkit.org/127.0.0.1#5335 +ipset=/openvinotoolkit.org/gfwlist +server=/gothdporn.com/127.0.0.1#5335 +ipset=/gothdporn.com/gfwlist +server=/shopee.com.br/127.0.0.1#5335 +ipset=/shopee.com.br/gfwlist +server=/beatsdreus.com/127.0.0.1#5335 +ipset=/beatsdreus.com/gfwlist +server=/nextfilm.com.hk/127.0.0.1#5335 +ipset=/nextfilm.com.hk/gfwlist +server=/2adultflashgames.com/127.0.0.1#5335 +ipset=/2adultflashgames.com/gfwlist +server=/foxcollegesports.com/127.0.0.1#5335 +ipset=/foxcollegesports.com/gfwlist +server=/siport.com/127.0.0.1#5335 +ipset=/siport.com/gfwlist +server=/htvncdn.net/127.0.0.1#5335 +ipset=/htvncdn.net/gfwlist +server=/sensorynetworks.com/127.0.0.1#5335 +ipset=/sensorynetworks.com/gfwlist +server=/patreoncommunity.com/127.0.0.1#5335 +ipset=/patreoncommunity.com/gfwlist +server=/bloombergpolarlake.com/127.0.0.1#5335 +ipset=/bloombergpolarlake.com/gfwlist +server=/azattyq.org/127.0.0.1#5335 +ipset=/azattyq.org/gfwlist +server=/iphoto.se/127.0.0.1#5335 +ipset=/iphoto.se/gfwlist +server=/photonicssociety.org/127.0.0.1#5335 +ipset=/photonicssociety.org/gfwlist +server=/researchintel.com/127.0.0.1#5335 +ipset=/researchintel.com/gfwlist +server=/pintool.com/127.0.0.1#5335 +ipset=/pintool.com/gfwlist +server=/apnews.com/127.0.0.1#5335 +ipset=/apnews.com/gfwlist +server=/pentium.net/127.0.0.1#5335 +ipset=/pentium.net/gfwlist +server=/pc.com/127.0.0.1#5335 +ipset=/pc.com/gfwlist +server=/optanedifference.com/127.0.0.1#5335 +ipset=/optanedifference.com/gfwlist +server=/opendroneid.org/127.0.0.1#5335 +ipset=/opendroneid.org/gfwlist +server=/google.pl/127.0.0.1#5335 +ipset=/google.pl/gfwlist +server=/249dw7.cn/127.0.0.1#5335 +ipset=/249dw7.cn/gfwlist +server=/ibook.co.nz/127.0.0.1#5335 +ipset=/ibook.co.nz/gfwlist +server=/mastercard.com.br/127.0.0.1#5335 +ipset=/mastercard.com.br/gfwlist +server=/booksc.org/127.0.0.1#5335 +ipset=/booksc.org/gfwlist +server=/niken7.com/127.0.0.1#5335 +ipset=/niken7.com/gfwlist +server=/pornoaid.com/127.0.0.1#5335 +ipset=/pornoaid.com/gfwlist +server=/nextgenerationcenter.com/127.0.0.1#5335 +ipset=/nextgenerationcenter.com/gfwlist +server=/ciscocontest.com/127.0.0.1#5335 +ipset=/ciscocontest.com/gfwlist +server=/loverslab.com/127.0.0.1#5335 +ipset=/loverslab.com/gfwlist +server=/hipzoom.net/127.0.0.1#5335 +ipset=/hipzoom.net/gfwlist +server=/nevex.com/127.0.0.1#5335 +ipset=/nevex.com/gfwlist +server=/nist.gov/127.0.0.1#5335 +ipset=/nist.gov/gfwlist +server=/geelongadvertiser.com.au/127.0.0.1#5335 +ipset=/geelongadvertiser.com.au/gfwlist +server=/instantfap.com/127.0.0.1#5335 +ipset=/instantfap.com/gfwlist +server=/movidius.com/127.0.0.1#5335 +ipset=/movidius.com/gfwlist +server=/hpstorethailand.com/127.0.0.1#5335 +ipset=/hpstorethailand.com/gfwlist +server=/headphones-dre.com/127.0.0.1#5335 +ipset=/headphones-dre.com/gfwlist +server=/zeit-world.net/127.0.0.1#5335 +ipset=/zeit-world.net/gfwlist +server=/lookinside.com/127.0.0.1#5335 +ipset=/lookinside.com/gfwlist +server=/inteltechnologyprovider.com/127.0.0.1#5335 +ipset=/inteltechnologyprovider.com/gfwlist +server=/intelstore.com/127.0.0.1#5335 +ipset=/intelstore.com/gfwlist +server=/yaoyaomumu.com/127.0.0.1#5335 +ipset=/yaoyaomumu.com/gfwlist +server=/postimg.cc/127.0.0.1#5335 +ipset=/postimg.cc/gfwlist +server=/eu-consumer-empowerment.com/127.0.0.1#5335 +ipset=/eu-consumer-empowerment.com/gfwlist +server=/monsterbeatssydneyaustralia.com/127.0.0.1#5335 +ipset=/monsterbeatssydneyaustralia.com/gfwlist +server=/intelsoftwarenetwork.com/127.0.0.1#5335 +ipset=/intelsoftwarenetwork.com/gfwlist +server=/myavfun.com/127.0.0.1#5335 +ipset=/myavfun.com/gfwlist +server=/brew.sh/127.0.0.1#5335 +ipset=/brew.sh/gfwlist +server=/blogspot.sn/127.0.0.1#5335 +ipset=/blogspot.sn/gfwlist +server=/porn555.com/127.0.0.1#5335 +ipset=/porn555.com/gfwlist +server=/foxacrossamerica.com/127.0.0.1#5335 +ipset=/foxacrossamerica.com/gfwlist +server=/intelsalestraining.com/127.0.0.1#5335 +ipset=/intelsalestraining.com/gfwlist +server=/costco.com/127.0.0.1#5335 +ipset=/costco.com/gfwlist +server=/tittykings.com/127.0.0.1#5335 +ipset=/tittykings.com/gfwlist +server=/poringa.net/127.0.0.1#5335 +ipset=/poringa.net/gfwlist +server=/pypa.io/127.0.0.1#5335 +ipset=/pypa.io/gfwlist +server=/intelrealsense.com/127.0.0.1#5335 +ipset=/intelrealsense.com/gfwlist +server=/intelquark.com/127.0.0.1#5335 +ipset=/intelquark.com/gfwlist +server=/bmwmotorradhk.com/127.0.0.1#5335 +ipset=/bmwmotorradhk.com/gfwlist +server=/xxxjapanesemovies.com/127.0.0.1#5335 +ipset=/xxxjapanesemovies.com/gfwlist +server=/newsmart.jp/127.0.0.1#5335 +ipset=/newsmart.jp/gfwlist +server=/nhentai.io/127.0.0.1#5335 +ipset=/nhentai.io/gfwlist +server=/thomsonreutersmexico.com/127.0.0.1#5335 +ipset=/thomsonreutersmexico.com/gfwlist +server=/intelnervana.com/127.0.0.1#5335 +ipset=/intelnervana.com/gfwlist +server=/wankgames.com/127.0.0.1#5335 +ipset=/wankgames.com/gfwlist +server=/naughtyblog.org/127.0.0.1#5335 +ipset=/naughtyblog.org/gfwlist +server=/cuntempire.com/127.0.0.1#5335 +ipset=/cuntempire.com/gfwlist +server=/fbsupport-covid.net/127.0.0.1#5335 +ipset=/fbsupport-covid.net/gfwlist +server=/realzoomovies.com/127.0.0.1#5335 +ipset=/realzoomovies.com/gfwlist +server=/avnana5.com/127.0.0.1#5335 +ipset=/avnana5.com/gfwlist +server=/hcpdts.com/127.0.0.1#5335 +ipset=/hcpdts.com/gfwlist +server=/logicool.co.jp/127.0.0.1#5335 +ipset=/logicool.co.jp/gfwlist +server=/sexy3dtoon.com/127.0.0.1#5335 +ipset=/sexy3dtoon.com/gfwlist +server=/intelgo.net/127.0.0.1#5335 +ipset=/intelgo.net/gfwlist +server=/iphone4.com/127.0.0.1#5335 +ipset=/iphone4.com/gfwlist +server=/bandgirlz.com/127.0.0.1#5335 +ipset=/bandgirlz.com/gfwlist +server=/intelforchange.com/127.0.0.1#5335 +ipset=/intelforchange.com/gfwlist +server=/inteleventexpress.com/127.0.0.1#5335 +ipset=/inteleventexpress.com/gfwlist +server=/vpngate.jp/127.0.0.1#5335 +ipset=/vpngate.jp/gfwlist +server=/benliton.com/127.0.0.1#5335 +ipset=/benliton.com/gfwlist +server=/intelcapital.com/127.0.0.1#5335 +ipset=/intelcapital.com/gfwlist +server=/thepornlist.com/127.0.0.1#5335 +ipset=/thepornlist.com/gfwlist +server=/nikelink.com/127.0.0.1#5335 +ipset=/nikelink.com/gfwlist +server=/intelapacstore.com/127.0.0.1#5335 +ipset=/intelapacstore.com/gfwlist +server=/bmw-connecteddrive.ie/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ie/gfwlist +server=/radiomarsho.com/127.0.0.1#5335 +ipset=/radiomarsho.com/gfwlist +server=/intelamericasstore.com/127.0.0.1#5335 +ipset=/intelamericasstore.com/gfwlist +server=/bmwlat.com/127.0.0.1#5335 +ipset=/bmwlat.com/gfwlist +server=/adobepress.ch/127.0.0.1#5335 +ipset=/adobepress.ch/gfwlist +server=/amazon.com.br/127.0.0.1#5335 +ipset=/amazon.com.br/gfwlist +server=/bttzyw.net/127.0.0.1#5335 +ipset=/bttzyw.net/gfwlist +server=/intel-university-collaboration.net/127.0.0.1#5335 +ipset=/intel-university-collaboration.net/gfwlist +server=/payypal.com/127.0.0.1#5335 +ipset=/payypal.com/gfwlist +server=/pornorips.com/127.0.0.1#5335 +ipset=/pornorips.com/gfwlist +server=/dandanzan.cc/127.0.0.1#5335 +ipset=/dandanzan.cc/gfwlist +server=/mini.dk/127.0.0.1#5335 +ipset=/mini.dk/gfwlist +server=/intel.tj/127.0.0.1#5335 +ipset=/intel.tj/gfwlist +server=/comicuniverse.org/127.0.0.1#5335 +ipset=/comicuniverse.org/gfwlist +server=/protonstatus.com/127.0.0.1#5335 +ipset=/protonstatus.com/gfwlist +server=/blogspot.hk/127.0.0.1#5335 +ipset=/blogspot.hk/gfwlist +server=/alterauserforums.net/127.0.0.1#5335 +ipset=/alterauserforums.net/gfwlist +server=/easic.com/127.0.0.1#5335 +ipset=/easic.com/gfwlist +server=/akamai-trials.com/127.0.0.1#5335 +ipset=/akamai-trials.com/gfwlist +server=/foxsoccerplus.net/127.0.0.1#5335 +ipset=/foxsoccerplus.net/gfwlist +server=/machigle-sp.com/127.0.0.1#5335 +ipset=/machigle-sp.com/gfwlist +server=/coreextreme.com/127.0.0.1#5335 +ipset=/coreextreme.com/gfwlist +server=/bmw.kz/127.0.0.1#5335 +ipset=/bmw.kz/gfwlist +server=/amateurcool.com/127.0.0.1#5335 +ipset=/amateurcool.com/gfwlist +server=/faacebook.com/127.0.0.1#5335 +ipset=/faacebook.com/gfwlist +server=/rentaride.com/127.0.0.1#5335 +ipset=/rentaride.com/gfwlist +server=/clusterconnection.com/127.0.0.1#5335 +ipset=/clusterconnection.com/gfwlist +server=/imhentai.xxx/127.0.0.1#5335 +ipset=/imhentai.xxx/gfwlist +server=/mrloli.com/127.0.0.1#5335 +ipset=/mrloli.com/gfwlist +server=/facebookexchange.net/127.0.0.1#5335 +ipset=/facebookexchange.net/gfwlist +server=/mini-connected.ee/127.0.0.1#5335 +ipset=/mini-connected.ee/gfwlist +server=/chips.com/127.0.0.1#5335 +ipset=/chips.com/gfwlist +server=/newyorker.com/127.0.0.1#5335 +ipset=/newyorker.com/gfwlist +server=/akami.com/127.0.0.1#5335 +ipset=/akami.com/gfwlist +server=/marvelsdoubleagent.com/127.0.0.1#5335 +ipset=/marvelsdoubleagent.com/gfwlist +server=/iwantavnow.com/127.0.0.1#5335 +ipset=/iwantavnow.com/gfwlist +server=/alphera.com.my/127.0.0.1#5335 +ipset=/alphera.com.my/gfwlist +server=/bigboss.video/127.0.0.1#5335 +ipset=/bigboss.video/gfwlist +server=/bmw-motorrad.bo/127.0.0.1#5335 +ipset=/bmw-motorrad.bo/gfwlist +server=/ipod.com/127.0.0.1#5335 +ipset=/ipod.com/gfwlist +server=/starbucksrtd.com/127.0.0.1#5335 +ipset=/starbucksrtd.com/gfwlist +server=/celeron.com/127.0.0.1#5335 +ipset=/celeron.com/gfwlist +server=/buyaltera.com/127.0.0.1#5335 +ipset=/buyaltera.com/gfwlist +server=/vfsco.hu/127.0.0.1#5335 +ipset=/vfsco.hu/gfwlist +server=/mini.com.tr/127.0.0.1#5335 +ipset=/mini.com.tr/gfwlist +server=/monsterbeatsalestore.com/127.0.0.1#5335 +ipset=/monsterbeatsalestore.com/gfwlist +server=/alterauserforum.net/127.0.0.1#5335 +ipset=/alterauserforum.net/gfwlist +server=/kingextre.me/127.0.0.1#5335 +ipset=/kingextre.me/gfwlist +server=/alteraforums.net/127.0.0.1#5335 +ipset=/alteraforums.net/gfwlist +server=/volvotrucks.mk/127.0.0.1#5335 +ipset=/volvotrucks.mk/gfwlist +server=/bestbuybusiness.com/127.0.0.1#5335 +ipset=/bestbuybusiness.com/gfwlist +server=/foxfaq.com/127.0.0.1#5335 +ipset=/foxfaq.com/gfwlist +server=/evilangel.com/127.0.0.1#5335 +ipset=/evilangel.com/gfwlist +server=/worldemojiawards.com/127.0.0.1#5335 +ipset=/worldemojiawards.com/gfwlist +server=/mini.com.ar/127.0.0.1#5335 +ipset=/mini.com.ar/gfwlist +server=/crysis.jp/127.0.0.1#5335 +ipset=/crysis.jp/gfwlist +server=/readthedocs-hosted.com/127.0.0.1#5335 +ipset=/readthedocs-hosted.com/gfwlist +server=/beats-bydreoutletsale.net/127.0.0.1#5335 +ipset=/beats-bydreoutletsale.net/gfwlist +server=/cbscorporation.com/127.0.0.1#5335 +ipset=/cbscorporation.com/gfwlist +server=/garenanow.com/127.0.0.1#5335 +ipset=/garenanow.com/gfwlist +server=/overcast.fm/127.0.0.1#5335 +ipset=/overcast.fm/gfwlist +server=/airwatchexpress.com/127.0.0.1#5335 +ipset=/airwatchexpress.com/gfwlist +server=/findmybeats.com/127.0.0.1#5335 +ipset=/findmybeats.com/gfwlist +server=/durex.com.co/127.0.0.1#5335 +ipset=/durex.com.co/gfwlist +server=/yourvoyeurvideos.com/127.0.0.1#5335 +ipset=/yourvoyeurvideos.com/gfwlist +server=/topsexygames.com/127.0.0.1#5335 +ipset=/topsexygames.com/gfwlist +server=/assylum.com/127.0.0.1#5335 +ipset=/assylum.com/gfwlist +server=/paypalcommunity.org/127.0.0.1#5335 +ipset=/paypalcommunity.org/gfwlist +server=/nikebetterworld.net/127.0.0.1#5335 +ipset=/nikebetterworld.net/gfwlist +server=/southfloridamini.com/127.0.0.1#5335 +ipset=/southfloridamini.com/gfwlist +server=/hkgolden.com/127.0.0.1#5335 +ipset=/hkgolden.com/gfwlist +server=/pogo.com/127.0.0.1#5335 +ipset=/pogo.com/gfwlist +server=/intel.vn/127.0.0.1#5335 +ipset=/intel.vn/gfwlist +server=/visualarts.gr.jp/127.0.0.1#5335 +ipset=/visualarts.gr.jp/gfwlist +server=/intel.vg/127.0.0.1#5335 +ipset=/intel.vg/gfwlist +server=/masterpassteststore.com/127.0.0.1#5335 +ipset=/masterpassteststore.com/gfwlist +server=/maximumerotica.com/127.0.0.1#5335 +ipset=/maximumerotica.com/gfwlist +server=/intel.lc/127.0.0.1#5335 +ipset=/intel.lc/gfwlist +server=/nextmgz.com/127.0.0.1#5335 +ipset=/nextmgz.com/gfwlist +server=/intel.uy/127.0.0.1#5335 +ipset=/intel.uy/gfwlist +server=/javscreens.com/127.0.0.1#5335 +ipset=/javscreens.com/gfwlist +server=/digicert-cn.com/127.0.0.1#5335 +ipset=/digicert-cn.com/gfwlist +server=/yahoo.com.hk/127.0.0.1#5335 +ipset=/yahoo.com.hk/gfwlist +server=/voandebele.com/127.0.0.1#5335 +ipset=/voandebele.com/gfwlist +server=/cyber-bay.info/127.0.0.1#5335 +ipset=/cyber-bay.info/gfwlist +server=/intel.tt/127.0.0.1#5335 +ipset=/intel.tt/gfwlist +server=/ebayseller.com/127.0.0.1#5335 +ipset=/ebayseller.com/gfwlist +server=/hentaivideos.net/127.0.0.1#5335 +ipset=/hentaivideos.net/gfwlist +server=/foxnewsgo.net/127.0.0.1#5335 +ipset=/foxnewsgo.net/gfwlist +server=/voyeurpapa.com/127.0.0.1#5335 +ipset=/voyeurpapa.com/gfwlist +server=/disqusservice.com/127.0.0.1#5335 +ipset=/disqusservice.com/gfwlist +server=/scholar.google.com.gt/127.0.0.1#5335 +ipset=/scholar.google.com.gt/gfwlist +server=/intel.tn/127.0.0.1#5335 +ipset=/intel.tn/gfwlist +server=/intel.tm/127.0.0.1#5335 +ipset=/intel.tm/gfwlist +server=/nikeseason.com/127.0.0.1#5335 +ipset=/nikeseason.com/gfwlist +server=/akamaized-staging.net/127.0.0.1#5335 +ipset=/akamaized-staging.net/gfwlist +server=/intel.tl/127.0.0.1#5335 +ipset=/intel.tl/gfwlist +server=/intel.tf/127.0.0.1#5335 +ipset=/intel.tf/gfwlist +server=/foxbet.com/127.0.0.1#5335 +ipset=/foxbet.com/gfwlist +server=/facebookads.com/127.0.0.1#5335 +ipset=/facebookads.com/gfwlist +server=/libgen.life/127.0.0.1#5335 +ipset=/libgen.life/gfwlist +server=/element.io/127.0.0.1#5335 +ipset=/element.io/gfwlist +server=/hentairank.supertop-100.com/127.0.0.1#5335 +ipset=/hentairank.supertop-100.com/gfwlist +server=/amazon.ca/127.0.0.1#5335 +ipset=/amazon.ca/gfwlist +server=/bestfreetube.net/127.0.0.1#5335 +ipset=/bestfreetube.net/gfwlist +server=/intel.st/127.0.0.1#5335 +ipset=/intel.st/gfwlist +server=/gold-gay.com/127.0.0.1#5335 +ipset=/gold-gay.com/gfwlist +server=/theindianleaks.com/127.0.0.1#5335 +ipset=/theindianleaks.com/gfwlist +server=/account-paypal.net/127.0.0.1#5335 +ipset=/account-paypal.net/gfwlist +server=/intel.sk/127.0.0.1#5335 +ipset=/intel.sk/gfwlist +server=/mywifecuckold.com/127.0.0.1#5335 +ipset=/mywifecuckold.com/gfwlist +server=/softbankbb.net/127.0.0.1#5335 +ipset=/softbankbb.net/gfwlist +server=/tex-talk.net/127.0.0.1#5335 +ipset=/tex-talk.net/gfwlist +server=/applecare.eu/127.0.0.1#5335 +ipset=/applecare.eu/gfwlist +server=/icloudpay.net/127.0.0.1#5335 +ipset=/icloudpay.net/gfwlist +server=/otbm.com/127.0.0.1#5335 +ipset=/otbm.com/gfwlist +server=/facevbook.com/127.0.0.1#5335 +ipset=/facevbook.com/gfwlist +server=/huffingtonpost.es/127.0.0.1#5335 +ipset=/huffingtonpost.es/gfwlist +server=/edgefonts.net/127.0.0.1#5335 +ipset=/edgefonts.net/gfwlist +server=/sony.eu/127.0.0.1#5335 +ipset=/sony.eu/gfwlist +server=/20thcenturystudios.jp/127.0.0.1#5335 +ipset=/20thcenturystudios.jp/gfwlist +server=/petardas.com/127.0.0.1#5335 +ipset=/petardas.com/gfwlist +server=/intel.pn/127.0.0.1#5335 +ipset=/intel.pn/gfwlist +server=/ahtops.com/127.0.0.1#5335 +ipset=/ahtops.com/gfwlist +server=/exhentai.org/127.0.0.1#5335 +ipset=/exhentai.org/gfwlist +server=/touchsmartpc.net/127.0.0.1#5335 +ipset=/touchsmartpc.net/gfwlist +server=/hqbutt.com/127.0.0.1#5335 +ipset=/hqbutt.com/gfwlist +server=/iloveinterracial.com/127.0.0.1#5335 +ipset=/iloveinterracial.com/gfwlist +server=/ftcdn.net/127.0.0.1#5335 +ipset=/ftcdn.net/gfwlist +server=/facebook.tv/127.0.0.1#5335 +ipset=/facebook.tv/gfwlist +server=/volvopenta.es/127.0.0.1#5335 +ipset=/volvopenta.es/gfwlist +server=/drdrebeatssale7.com/127.0.0.1#5335 +ipset=/drdrebeatssale7.com/gfwlist +server=/faceabook.com/127.0.0.1#5335 +ipset=/faceabook.com/gfwlist +server=/leagueoflegends.org/127.0.0.1#5335 +ipset=/leagueoflegends.org/gfwlist +server=/foxbusiness.com/127.0.0.1#5335 +ipset=/foxbusiness.com/gfwlist +server=/watchmygirlfriend.tv/127.0.0.1#5335 +ipset=/watchmygirlfriend.tv/gfwlist +server=/yespornplease.com/127.0.0.1#5335 +ipset=/yespornplease.com/gfwlist +server=/blpcareers.com/127.0.0.1#5335 +ipset=/blpcareers.com/gfwlist +server=/headphonepubs.com/127.0.0.1#5335 +ipset=/headphonepubs.com/gfwlist +server=/womenwill.id/127.0.0.1#5335 +ipset=/womenwill.id/gfwlist +server=/pearsonclinical.de/127.0.0.1#5335 +ipset=/pearsonclinical.de/gfwlist +server=/brazzers.xxx/127.0.0.1#5335 +ipset=/brazzers.xxx/gfwlist +server=/paxlicense.org/127.0.0.1#5335 +ipset=/paxlicense.org/gfwlist +server=/intel.mu/127.0.0.1#5335 +ipset=/intel.mu/gfwlist +server=/experiencebillmelater.com/127.0.0.1#5335 +ipset=/experiencebillmelater.com/gfwlist +server=/intel.mt/127.0.0.1#5335 +ipset=/intel.mt/gfwlist +server=/wixsite.com/127.0.0.1#5335 +ipset=/wixsite.com/gfwlist +server=/bmw.kg/127.0.0.1#5335 +ipset=/bmw.kg/gfwlist +server=/truefi.io/127.0.0.1#5335 +ipset=/truefi.io/gfwlist +server=/applestore.com.eg/127.0.0.1#5335 +ipset=/applestore.com.eg/gfwlist +server=/nexitally.com/127.0.0.1#5335 +ipset=/nexitally.com/gfwlist +server=/bmwlifestyle.ca/127.0.0.1#5335 +ipset=/bmwlifestyle.ca/gfwlist +server=/erabaru.net/127.0.0.1#5335 +ipset=/erabaru.net/gfwlist +server=/discord.co/127.0.0.1#5335 +ipset=/discord.co/gfwlist +server=/nhentaihaven.com/127.0.0.1#5335 +ipset=/nhentaihaven.com/gfwlist +server=/buyfast-paysmart.net/127.0.0.1#5335 +ipset=/buyfast-paysmart.net/gfwlist +server=/intel.mg/127.0.0.1#5335 +ipset=/intel.mg/gfwlist +server=/instagramci.com/127.0.0.1#5335 +ipset=/instagramci.com/gfwlist +server=/facebooknude.com/127.0.0.1#5335 +ipset=/facebooknude.com/gfwlist +server=/gauleporno.xxx/127.0.0.1#5335 +ipset=/gauleporno.xxx/gfwlist +server=/orlandohurricane.com/127.0.0.1#5335 +ipset=/orlandohurricane.com/gfwlist +server=/intel.me/127.0.0.1#5335 +ipset=/intel.me/gfwlist +server=/volvobuses.pl/127.0.0.1#5335 +ipset=/volvobuses.pl/gfwlist +server=/porndoepremium.com/127.0.0.1#5335 +ipset=/porndoepremium.com/gfwlist +server=/knovel.com/127.0.0.1#5335 +ipset=/knovel.com/gfwlist +server=/intel.ke/127.0.0.1#5335 +ipset=/intel.ke/gfwlist +server=/intel.jp/127.0.0.1#5335 +ipset=/intel.jp/gfwlist +server=/stripe.com/127.0.0.1#5335 +ipset=/stripe.com/gfwlist +server=/ebaytechblog.com/127.0.0.1#5335 +ipset=/ebaytechblog.com/gfwlist +server=/intel.je/127.0.0.1#5335 +ipset=/intel.je/gfwlist +server=/intel.io/127.0.0.1#5335 +ipset=/intel.io/gfwlist +server=/nivod.tv/127.0.0.1#5335 +ipset=/nivod.tv/gfwlist +server=/avcar.vip/127.0.0.1#5335 +ipset=/avcar.vip/gfwlist +server=/bingvisualsearch.com/127.0.0.1#5335 +ipset=/bingvisualsearch.com/gfwlist +server=/fucktube.com/127.0.0.1#5335 +ipset=/fucktube.com/gfwlist +server=/huffingtonpost.jp/127.0.0.1#5335 +ipset=/huffingtonpost.jp/gfwlist +server=/intel.ht/127.0.0.1#5335 +ipset=/intel.ht/gfwlist +server=/intel.hn/127.0.0.1#5335 +ipset=/intel.hn/gfwlist +server=/monitrix.net/127.0.0.1#5335 +ipset=/monitrix.net/gfwlist +server=/intel.hk/127.0.0.1#5335 +ipset=/intel.hk/gfwlist +server=/microsoft.cl/127.0.0.1#5335 +ipset=/microsoft.cl/gfwlist +server=/intel.gy/127.0.0.1#5335 +ipset=/intel.gy/gfwlist +server=/466453.com/127.0.0.1#5335 +ipset=/466453.com/gfwlist +server=/theguardian.com/127.0.0.1#5335 +ipset=/theguardian.com/gfwlist +server=/intel.gt/127.0.0.1#5335 +ipset=/intel.gt/gfwlist +server=/alphabet.uk/127.0.0.1#5335 +ipset=/alphabet.uk/gfwlist +server=/xshaker.net/127.0.0.1#5335 +ipset=/xshaker.net/gfwlist +server=/viralcum.com/127.0.0.1#5335 +ipset=/viralcum.com/gfwlist +server=/ebay.ch/127.0.0.1#5335 +ipset=/ebay.ch/gfwlist +server=/youtube.com.ni/127.0.0.1#5335 +ipset=/youtube.com.ni/gfwlist +server=/intel.gm/127.0.0.1#5335 +ipset=/intel.gm/gfwlist +server=/walmartimages.com/127.0.0.1#5335 +ipset=/walmartimages.com/gfwlist +server=/intel.ge/127.0.0.1#5335 +ipset=/intel.ge/gfwlist +server=/intel.gd/127.0.0.1#5335 +ipset=/intel.gd/gfwlist +server=/fc2ppv.tv/127.0.0.1#5335 +ipset=/fc2ppv.tv/gfwlist +server=/startpath.com/127.0.0.1#5335 +ipset=/startpath.com/gfwlist +server=/smartcommunitiescoalition.org/127.0.0.1#5335 +ipset=/smartcommunitiescoalition.org/gfwlist +server=/applepaysupplies.info/127.0.0.1#5335 +ipset=/applepaysupplies.info/gfwlist +server=/avstar02.me/127.0.0.1#5335 +ipset=/avstar02.me/gfwlist +server=/jav-legend.com/127.0.0.1#5335 +ipset=/jav-legend.com/gfwlist +server=/enterprisessl.com/127.0.0.1#5335 +ipset=/enterprisessl.com/gfwlist +server=/intel.es/127.0.0.1#5335 +ipset=/intel.es/gfwlist +server=/vitukali.com/127.0.0.1#5335 +ipset=/vitukali.com/gfwlist +server=/cheapbeatsbydre-au.com/127.0.0.1#5335 +ipset=/cheapbeatsbydre-au.com/gfwlist +server=/fssta.com/127.0.0.1#5335 +ipset=/fssta.com/gfwlist +server=/facebooksecurity.net/127.0.0.1#5335 +ipset=/facebooksecurity.net/gfwlist +server=/anaconda.cloud/127.0.0.1#5335 +ipset=/anaconda.cloud/gfwlist +server=/madvagina.com/127.0.0.1#5335 +ipset=/madvagina.com/gfwlist +server=/gigabyte.com/127.0.0.1#5335 +ipset=/gigabyte.com/gfwlist +server=/serving-sys.com/127.0.0.1#5335 +ipset=/serving-sys.com/gfwlist +server=/babes.com/127.0.0.1#5335 +ipset=/babes.com/gfwlist +server=/intel.com.ve/127.0.0.1#5335 +ipset=/intel.com.ve/gfwlist +server=/dachix.com/127.0.0.1#5335 +ipset=/dachix.com/gfwlist +server=/intel.com.uy/127.0.0.1#5335 +ipset=/intel.com.uy/gfwlist +server=/intel.com.tw/127.0.0.1#5335 +ipset=/intel.com.tw/gfwlist +server=/intel.com.tr/127.0.0.1#5335 +ipset=/intel.com.tr/gfwlist +server=/icloudo.com/127.0.0.1#5335 +ipset=/icloudo.com/gfwlist +server=/pichunter.com/127.0.0.1#5335 +ipset=/pichunter.com/gfwlist +server=/amzn.asia/127.0.0.1#5335 +ipset=/amzn.asia/gfwlist +server=/nunuyy.cc/127.0.0.1#5335 +ipset=/nunuyy.cc/gfwlist +server=/jav.guru/127.0.0.1#5335 +ipset=/jav.guru/gfwlist +server=/tellmewhygame.com/127.0.0.1#5335 +ipset=/tellmewhygame.com/gfwlist +server=/kemono.party/127.0.0.1#5335 +ipset=/kemono.party/gfwlist +server=/bridge-studio.co.uk/127.0.0.1#5335 +ipset=/bridge-studio.co.uk/gfwlist +server=/intel.com.pr/127.0.0.1#5335 +ipset=/intel.com.pr/gfwlist +server=/visaglobalfinance.com/127.0.0.1#5335 +ipset=/visaglobalfinance.com/gfwlist +server=/sxyprn.com/127.0.0.1#5335 +ipset=/sxyprn.com/gfwlist +server=/malvastudios.com/127.0.0.1#5335 +ipset=/malvastudios.com/gfwlist +server=/needforspeedproven.com/127.0.0.1#5335 +ipset=/needforspeedproven.com/gfwlist +server=/fxporn.net/127.0.0.1#5335 +ipset=/fxporn.net/gfwlist +server=/intel.com.mx/127.0.0.1#5335 +ipset=/intel.com.mx/gfwlist +server=/intel.com.jm/127.0.0.1#5335 +ipset=/intel.com.jm/gfwlist +server=/bmw.ro/127.0.0.1#5335 +ipset=/bmw.ro/gfwlist +server=/intel.com.hk/127.0.0.1#5335 +ipset=/intel.com.hk/gfwlist +server=/intel.com.co/127.0.0.1#5335 +ipset=/intel.com.co/gfwlist +server=/google.tt/127.0.0.1#5335 +ipset=/google.tt/gfwlist +server=/nuita.net/127.0.0.1#5335 +ipset=/nuita.net/gfwlist +server=/intel.com.bo/127.0.0.1#5335 +ipset=/intel.com.bo/gfwlist +server=/vercel.pub/127.0.0.1#5335 +ipset=/vercel.pub/gfwlist +server=/intel.com.au/127.0.0.1#5335 +ipset=/intel.com.au/gfwlist +server=/google.mw/127.0.0.1#5335 +ipset=/google.mw/gfwlist +server=/mangahentai.me/127.0.0.1#5335 +ipset=/mangahentai.me/gfwlist +server=/bmwgroupna.com/127.0.0.1#5335 +ipset=/bmwgroupna.com/gfwlist +server=/monsterbeatsbydrdre-usa.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrdre-usa.com/gfwlist +server=/pugpig.com/127.0.0.1#5335 +ipset=/pugpig.com/gfwlist +server=/intel.co.il/127.0.0.1#5335 +ipset=/intel.co.il/gfwlist +server=/toget.com.tw/127.0.0.1#5335 +ipset=/toget.com.tw/gfwlist +server=/fapphub.com/127.0.0.1#5335 +ipset=/fapphub.com/gfwlist +server=/skypedata.akadns.net/127.0.0.1#5335 +ipset=/skypedata.akadns.net/gfwlist +server=/qmov.net/127.0.0.1#5335 +ipset=/qmov.net/gfwlist +server=/intel.co.id/127.0.0.1#5335 +ipset=/intel.co.id/gfwlist +server=/pornxxxplace.com/127.0.0.1#5335 +ipset=/pornxxxplace.com/gfwlist +server=/creativecommons.org/127.0.0.1#5335 +ipset=/creativecommons.org/gfwlist +server=/volvotrucks.at/127.0.0.1#5335 +ipset=/volvotrucks.at/gfwlist +server=/adobesc.com/127.0.0.1#5335 +ipset=/adobesc.com/gfwlist +server=/intel.co.ae/127.0.0.1#5335 +ipset=/intel.co.ae/gfwlist +server=/redtube.com.br/127.0.0.1#5335 +ipset=/redtube.com.br/gfwlist +server=/ieee-uffc.org/127.0.0.1#5335 +ipset=/ieee-uffc.org/gfwlist +server=/intel.cm/127.0.0.1#5335 +ipset=/intel.cm/gfwlist +server=/iphone-vip4.com/127.0.0.1#5335 +ipset=/iphone-vip4.com/gfwlist +server=/intel.cg/127.0.0.1#5335 +ipset=/intel.cg/gfwlist +server=/intel.cc/127.0.0.1#5335 +ipset=/intel.cc/gfwlist +server=/huobi.me/127.0.0.1#5335 +ipset=/huobi.me/gfwlist +server=/stackexchange.com/127.0.0.1#5335 +ipset=/stackexchange.com/gfwlist +server=/seamonkey-project.org/127.0.0.1#5335 +ipset=/seamonkey-project.org/gfwlist +server=/bmw.com.sg/127.0.0.1#5335 +ipset=/bmw.com.sg/gfwlist +server=/appleafrica.com/127.0.0.1#5335 +ipset=/appleafrica.com/gfwlist +server=/brepolis.net/127.0.0.1#5335 +ipset=/brepolis.net/gfwlist +server=/paypalcommunity.com/127.0.0.1#5335 +ipset=/paypalcommunity.com/gfwlist +server=/vagabundasdoorkut.net/127.0.0.1#5335 +ipset=/vagabundasdoorkut.net/gfwlist +server=/gayporno.fm/127.0.0.1#5335 +ipset=/gayporno.fm/gfwlist +server=/whoreteensex.com/127.0.0.1#5335 +ipset=/whoreteensex.com/gfwlist +server=/intel.bg/127.0.0.1#5335 +ipset=/intel.bg/gfwlist +server=/akamci.com/127.0.0.1#5335 +ipset=/akamci.com/gfwlist +server=/peach-cherry.com/127.0.0.1#5335 +ipset=/peach-cherry.com/gfwlist +server=/intel.at/127.0.0.1#5335 +ipset=/intel.at/gfwlist +server=/analdin.com/127.0.0.1#5335 +ipset=/analdin.com/gfwlist +server=/intel.ai/127.0.0.1#5335 +ipset=/intel.ai/gfwlist +server=/brewmp.com/127.0.0.1#5335 +ipset=/brewmp.com/gfwlist +server=/cocktailsandcocktalk.com/127.0.0.1#5335 +ipset=/cocktailsandcocktalk.com/gfwlist +server=/1vwapi4d.xyz/127.0.0.1#5335 +ipset=/1vwapi4d.xyz/gfwlist +server=/mgo.com/127.0.0.1#5335 +ipset=/mgo.com/gfwlist +server=/dailymail.dk/127.0.0.1#5335 +ipset=/dailymail.dk/gfwlist +server=/stripcamfun.com/127.0.0.1#5335 +ipset=/stripcamfun.com/gfwlist +server=/echosign.com/127.0.0.1#5335 +ipset=/echosign.com/gfwlist +server=/haskellstack.org/127.0.0.1#5335 +ipset=/haskellstack.org/gfwlist +server=/intel.ac/127.0.0.1#5335 +ipset=/intel.ac/gfwlist +server=/s81c.com/127.0.0.1#5335 +ipset=/s81c.com/gfwlist +server=/haveibeenpwned.com/127.0.0.1#5335 +ipset=/haveibeenpwned.com/gfwlist +server=/bmw.com.ec/127.0.0.1#5335 +ipset=/bmw.com.ec/gfwlist +server=/wwwapple.net/127.0.0.1#5335 +ipset=/wwwapple.net/gfwlist +server=/ibm.net/127.0.0.1#5335 +ipset=/ibm.net/gfwlist +server=/hq69.com/127.0.0.1#5335 +ipset=/hq69.com/gfwlist +server=/minuporno.com/127.0.0.1#5335 +ipset=/minuporno.com/gfwlist +server=/bnext.com.tw/127.0.0.1#5335 +ipset=/bnext.com.tw/gfwlist +server=/driving.co.uk/127.0.0.1#5335 +ipset=/driving.co.uk/gfwlist +server=/ivintageporn.com/127.0.0.1#5335 +ipset=/ivintageporn.com/gfwlist +server=/sunbingo.co.uk/127.0.0.1#5335 +ipset=/sunbingo.co.uk/gfwlist +server=/voakorea.com/127.0.0.1#5335 +ipset=/voakorea.com/gfwlist +server=/hpbundle.com/127.0.0.1#5335 +ipset=/hpbundle.com/gfwlist +server=/miktex.org/127.0.0.1#5335 +ipset=/miktex.org/gfwlist +server=/www8-hp.com/127.0.0.1#5335 +ipset=/www8-hp.com/gfwlist +server=/mini-me.com/127.0.0.1#5335 +ipset=/mini-me.com/gfwlist +server=/hbogoasia.com/127.0.0.1#5335 +ipset=/hbogoasia.com/gfwlist +server=/touchsmartpc.org/127.0.0.1#5335 +ipset=/touchsmartpc.org/gfwlist +server=/bmw-clubs-international.com/127.0.0.1#5335 +ipset=/bmw-clubs-international.com/gfwlist +server=/oup.com/127.0.0.1#5335 +ipset=/oup.com/gfwlist +server=/nine.com.au/127.0.0.1#5335 +ipset=/nine.com.au/gfwlist +server=/premobay.com/127.0.0.1#5335 +ipset=/premobay.com/gfwlist +server=/pornmz.com/127.0.0.1#5335 +ipset=/pornmz.com/gfwlist +server=/adulters.org/127.0.0.1#5335 +ipset=/adulters.org/gfwlist +server=/pinterest.id/127.0.0.1#5335 +ipset=/pinterest.id/gfwlist +server=/serviceshp.com/127.0.0.1#5335 +ipset=/serviceshp.com/gfwlist +server=/printspots.net/127.0.0.1#5335 +ipset=/printspots.net/gfwlist +server=/printspots.com/127.0.0.1#5335 +ipset=/printspots.com/gfwlist +server=/jenporno.cz/127.0.0.1#5335 +ipset=/jenporno.cz/gfwlist +server=/bmw-ksa.com/127.0.0.1#5335 +ipset=/bmw-ksa.com/gfwlist +server=/printersetupsupport.com/127.0.0.1#5335 +ipset=/printersetupsupport.com/gfwlist +server=/wholefoodsmarket.co.uk/127.0.0.1#5335 +ipset=/wholefoodsmarket.co.uk/gfwlist +server=/intel.by/127.0.0.1#5335 +ipset=/intel.by/gfwlist +server=/starbucks.no/127.0.0.1#5335 +ipset=/starbucks.no/gfwlist +server=/heads-ak-spotify-com.akamaized.net/127.0.0.1#5335 +ipset=/heads-ak-spotify-com.akamaized.net/gfwlist +server=/porstoporno.site/127.0.0.1#5335 +ipset=/porstoporno.site/gfwlist +server=/instantink.com/127.0.0.1#5335 +ipset=/instantink.com/gfwlist +server=/i-123-hp.com/127.0.0.1#5335 +ipset=/i-123-hp.com/gfwlist +server=/vivaldi.com/127.0.0.1#5335 +ipset=/vivaldi.com/gfwlist +server=/hpwallart.com/127.0.0.1#5335 +ipset=/hpwallart.com/gfwlist +server=/wsj.net/127.0.0.1#5335 +ipset=/wsj.net/gfwlist +server=/fbmarketing.com/127.0.0.1#5335 +ipset=/fbmarketing.com/gfwlist +server=/google.com.ly/127.0.0.1#5335 +ipset=/google.com.ly/gfwlist +server=/hpveer.com/127.0.0.1#5335 +ipset=/hpveer.com/gfwlist +server=/freeav.tv/127.0.0.1#5335 +ipset=/freeav.tv/gfwlist +server=/hptrainingcenter.com/127.0.0.1#5335 +ipset=/hptrainingcenter.com/gfwlist +server=/chatwhores.tv/127.0.0.1#5335 +ipset=/chatwhores.tv/gfwlist +server=/hptouch.com/127.0.0.1#5335 +ipset=/hptouch.com/gfwlist +server=/scholar.google.co.kr/127.0.0.1#5335 +ipset=/scholar.google.co.kr/gfwlist +server=/deiightfuidates.net/127.0.0.1#5335 +ipset=/deiightfuidates.net/gfwlist +server=/didilist.com/127.0.0.1#5335 +ipset=/didilist.com/gfwlist +server=/acces-vod.com/127.0.0.1#5335 +ipset=/acces-vod.com/gfwlist +server=/amodoll.com/127.0.0.1#5335 +ipset=/amodoll.com/gfwlist +server=/azureplanetscale.net/127.0.0.1#5335 +ipset=/azureplanetscale.net/gfwlist +server=/scnsrc.me/127.0.0.1#5335 +ipset=/scnsrc.me/gfwlist +server=/privatemarketplaces.net/127.0.0.1#5335 +ipset=/privatemarketplaces.net/gfwlist +server=/mobilemarketo.com/127.0.0.1#5335 +ipset=/mobilemarketo.com/gfwlist +server=/addthiscdn.com/127.0.0.1#5335 +ipset=/addthiscdn.com/gfwlist +server=/xvidzz.com/127.0.0.1#5335 +ipset=/xvidzz.com/gfwlist +server=/elog-ch.net/127.0.0.1#5335 +ipset=/elog-ch.net/gfwlist +server=/hpstore-china.com/127.0.0.1#5335 +ipset=/hpstore-china.com/gfwlist +server=/aflamporn.com/127.0.0.1#5335 +ipset=/aflamporn.com/gfwlist +server=/thanksloyalty.com/127.0.0.1#5335 +ipset=/thanksloyalty.com/gfwlist +server=/beatsireland.net/127.0.0.1#5335 +ipset=/beatsireland.net/gfwlist +server=/my29tv.com/127.0.0.1#5335 +ipset=/my29tv.com/gfwlist +server=/mini-ksa.com/127.0.0.1#5335 +ipset=/mini-ksa.com/gfwlist +server=/badvirtue.com/127.0.0.1#5335 +ipset=/badvirtue.com/gfwlist +server=/nextmedia.com/127.0.0.1#5335 +ipset=/nextmedia.com/gfwlist +server=/hpsprocket.com/127.0.0.1#5335 +ipset=/hpsprocket.com/gfwlist +server=/sandisk.it/127.0.0.1#5335 +ipset=/sandisk.it/gfwlist +server=/bby.com/127.0.0.1#5335 +ipset=/bby.com/gfwlist +server=/lolstatic-a.akamaihd.net/127.0.0.1#5335 +ipset=/lolstatic-a.akamaihd.net/gfwlist +server=/inikesneakers.com/127.0.0.1#5335 +ipset=/inikesneakers.com/gfwlist +server=/ghostgames.com/127.0.0.1#5335 +ipset=/ghostgames.com/gfwlist +server=/omafotze.com/127.0.0.1#5335 +ipset=/omafotze.com/gfwlist +server=/youtube.sk/127.0.0.1#5335 +ipset=/youtube.sk/gfwlist +server=/91tv.tw/127.0.0.1#5335 +ipset=/91tv.tw/gfwlist +server=/hpsmartupdate.com/127.0.0.1#5335 +ipset=/hpsmartupdate.com/gfwlist +server=/youtube.pe/127.0.0.1#5335 +ipset=/youtube.pe/gfwlist +server=/foxhq.com/127.0.0.1#5335 +ipset=/foxhq.com/gfwlist +server=/fedoramagazine.org/127.0.0.1#5335 +ipset=/fedoramagazine.org/gfwlist +server=/volvogroup.de/127.0.0.1#5335 +ipset=/volvogroup.de/gfwlist +server=/bridgestone.com.ar/127.0.0.1#5335 +ipset=/bridgestone.com.ar/gfwlist +server=/niketradeweb.com/127.0.0.1#5335 +ipset=/niketradeweb.com/gfwlist +server=/nsfw247.to/127.0.0.1#5335 +ipset=/nsfw247.to/gfwlist +server=/fosebook.com/127.0.0.1#5335 +ipset=/fosebook.com/gfwlist +server=/hpsmarts.com/127.0.0.1#5335 +ipset=/hpsmarts.com/gfwlist +server=/symcb.com/127.0.0.1#5335 +ipset=/symcb.com/gfwlist +server=/adsense.com/127.0.0.1#5335 +ipset=/adsense.com/gfwlist +server=/hpsmart.com/127.0.0.1#5335 +ipset=/hpsmart.com/gfwlist +server=/want-media.com/127.0.0.1#5335 +ipset=/want-media.com/gfwlist +server=/hpshopping.hk/127.0.0.1#5335 +ipset=/hpshopping.hk/gfwlist +server=/nikeairmax.com/127.0.0.1#5335 +ipset=/nikeairmax.com/gfwlist +server=/ratedgross.com/127.0.0.1#5335 +ipset=/ratedgross.com/gfwlist +server=/hpshoping.com/127.0.0.1#5335 +ipset=/hpshoping.com/gfwlist +server=/toppornoduro.com/127.0.0.1#5335 +ipset=/toppornoduro.com/gfwlist +server=/inmediahk.net/127.0.0.1#5335 +ipset=/inmediahk.net/gfwlist +server=/pcmarket.com.hk/127.0.0.1#5335 +ipset=/pcmarket.com.hk/gfwlist +server=/cometotheduckside.com/127.0.0.1#5335 +ipset=/cometotheduckside.com/gfwlist +server=/hpshop.com/127.0.0.1#5335 +ipset=/hpshop.com/gfwlist +server=/hpdesignjetl25500.com/127.0.0.1#5335 +ipset=/hpdesignjetl25500.com/gfwlist +server=/asiancamgirllive.com/127.0.0.1#5335 +ipset=/asiancamgirllive.com/gfwlist +server=/fapmovz.com/127.0.0.1#5335 +ipset=/fapmovz.com/gfwlist +server=/crowdtangle.com/127.0.0.1#5335 +ipset=/crowdtangle.com/gfwlist +server=/currenttime.tv/127.0.0.1#5335 +ipset=/currenttime.tv/gfwlist +server=/hpserver.com/127.0.0.1#5335 +ipset=/hpserver.com/gfwlist +server=/hpsalescentral.com/127.0.0.1#5335 +ipset=/hpsalescentral.com/gfwlist +server=/volvobuses.co/127.0.0.1#5335 +ipset=/volvobuses.co/gfwlist +server=/pornocomic.net/127.0.0.1#5335 +ipset=/pornocomic.net/gfwlist +server=/ipfs.io/127.0.0.1#5335 +ipset=/ipfs.io/gfwlist +server=/directvadsales.com/127.0.0.1#5335 +ipset=/directvadsales.com/gfwlist +server=/volvotrucks.com/127.0.0.1#5335 +ipset=/volvotrucks.com/gfwlist +server=/hentaiz.vip/127.0.0.1#5335 +ipset=/hentaiz.vip/gfwlist +server=/hpprinterdrivers.com/127.0.0.1#5335 +ipset=/hpprinterdrivers.com/gfwlist +server=/hpphotoscanners.com/127.0.0.1#5335 +ipset=/hpphotoscanners.com/gfwlist +server=/hppage5000.com/127.0.0.1#5335 +ipset=/hppage5000.com/gfwlist +server=/slack-redir.net/127.0.0.1#5335 +ipset=/slack-redir.net/gfwlist +server=/youtube.com.by/127.0.0.1#5335 +ipset=/youtube.com.by/gfwlist +server=/thaicuties.com/127.0.0.1#5335 +ipset=/thaicuties.com/gfwlist +server=/hponlinehelp.com/127.0.0.1#5335 +ipset=/hponlinehelp.com/gfwlist +server=/dengeamerika.com/127.0.0.1#5335 +ipset=/dengeamerika.com/gfwlist +server=/mastercardmoments.com/127.0.0.1#5335 +ipset=/mastercardmoments.com/gfwlist +server=/fesebook.com/127.0.0.1#5335 +ipset=/fesebook.com/gfwlist +server=/hpmobile.com/127.0.0.1#5335 +ipset=/hpmobile.com/gfwlist +server=/twitcomike.jp/127.0.0.1#5335 +ipset=/twitcomike.jp/gfwlist +server=/mut.ch/127.0.0.1#5335 +ipset=/mut.ch/gfwlist +server=/hpmicrcartridge.com/127.0.0.1#5335 +ipset=/hpmicrcartridge.com/gfwlist +server=/hpmemorychips.com/127.0.0.1#5335 +ipset=/hpmemorychips.com/gfwlist +server=/apple.be/127.0.0.1#5335 +ipset=/apple.be/gfwlist +server=/youtube.com.uy/127.0.0.1#5335 +ipset=/youtube.com.uy/gfwlist +server=/verizonbusinessfios.com/127.0.0.1#5335 +ipset=/verizonbusinessfios.com/gfwlist +server=/iphone4s.com/127.0.0.1#5335 +ipset=/iphone4s.com/gfwlist +server=/eporner.com/127.0.0.1#5335 +ipset=/eporner.com/gfwlist +server=/alibabacloud.com/127.0.0.1#5335 +ipset=/alibabacloud.com/gfwlist +server=/dettolthailand.com/127.0.0.1#5335 +ipset=/dettolthailand.com/gfwlist +server=/mastercard.qa/127.0.0.1#5335 +ipset=/mastercard.qa/gfwlist +server=/mythicentertainment.com/127.0.0.1#5335 +ipset=/mythicentertainment.com/gfwlist +server=/hpkeyboard.com/127.0.0.1#5335 +ipset=/hpkeyboard.com/gfwlist +server=/hpinstantink.com/127.0.0.1#5335 +ipset=/hpinstantink.com/gfwlist +server=/facebooklive.com/127.0.0.1#5335 +ipset=/facebooklive.com/gfwlist +server=/hpinc.net/127.0.0.1#5335 +ipset=/hpinc.net/gfwlist +server=/foxsports.com.gt/127.0.0.1#5335 +ipset=/foxsports.com.gt/gfwlist +server=/hpinc.info/127.0.0.1#5335 +ipset=/hpinc.info/gfwlist +server=/crystalmiss.com/127.0.0.1#5335 +ipset=/crystalmiss.com/gfwlist +server=/ekhokavkaza.com/127.0.0.1#5335 +ipset=/ekhokavkaza.com/gfwlist +server=/paypaly.com/127.0.0.1#5335 +ipset=/paypaly.com/gfwlist +server=/images-amazon.com/127.0.0.1#5335 +ipset=/images-amazon.com/gfwlist +server=/hpgpas.com/127.0.0.1#5335 +ipset=/hpgpas.com/gfwlist +server=/pornovesem.tv/127.0.0.1#5335 +ipset=/pornovesem.tv/gfwlist +server=/visaplus.com/127.0.0.1#5335 +ipset=/visaplus.com/gfwlist +server=/cheap-beats-by-dre.net/127.0.0.1#5335 +ipset=/cheap-beats-by-dre.net/gfwlist +server=/tube188.com/127.0.0.1#5335 +ipset=/tube188.com/gfwlist +server=/pornmate.com/127.0.0.1#5335 +ipset=/pornmate.com/gfwlist +server=/facebookmobile.com/127.0.0.1#5335 +ipset=/facebookmobile.com/gfwlist +server=/cashpassport.net/127.0.0.1#5335 +ipset=/cashpassport.net/gfwlist +server=/cheapdrebeats8.net/127.0.0.1#5335 +ipset=/cheapdrebeats8.net/gfwlist +server=/cnnmoney.com/127.0.0.1#5335 +ipset=/cnnmoney.com/gfwlist +server=/ntdtv.kr/127.0.0.1#5335 +ipset=/ntdtv.kr/gfwlist +server=/hpfaqs.com/127.0.0.1#5335 +ipset=/hpfaqs.com/gfwlist +server=/itunes.com/127.0.0.1#5335 +ipset=/itunes.com/gfwlist +server=/stripe.network/127.0.0.1#5335 +ipset=/stripe.network/gfwlist +server=/hpeprint.com/127.0.0.1#5335 +ipset=/hpeprint.com/gfwlist +server=/hpengage.com/127.0.0.1#5335 +ipset=/hpengage.com/gfwlist +server=/auricularemonsterbeats.com/127.0.0.1#5335 +ipset=/auricularemonsterbeats.com/gfwlist +server=/amazon-launchpad.com/127.0.0.1#5335 +ipset=/amazon-launchpad.com/gfwlist +server=/ubistatic3-a.akamaihd.net/127.0.0.1#5335 +ipset=/ubistatic3-a.akamaihd.net/gfwlist +server=/hpdownloadstore.com/127.0.0.1#5335 +ipset=/hpdownloadstore.com/gfwlist +server=/datawav.club/127.0.0.1#5335 +ipset=/datawav.club/gfwlist +server=/asus.com/127.0.0.1#5335 +ipset=/asus.com/gfwlist +server=/hpdesktopcomputer.com/127.0.0.1#5335 +ipset=/hpdesktopcomputer.com/gfwlist +server=/hpdaas.com/127.0.0.1#5335 +ipset=/hpdaas.com/gfwlist +server=/tvcastlive-hamivideo.cdn.hinet.net/127.0.0.1#5335 +ipset=/tvcastlive-hamivideo.cdn.hinet.net/gfwlist +server=/bridgestone.cl/127.0.0.1#5335 +ipset=/bridgestone.cl/gfwlist +server=/hpcustomersupport.com/127.0.0.1#5335 +ipset=/hpcustomersupport.com/gfwlist +server=/hpcu.org/127.0.0.1#5335 +ipset=/hpcu.org/gfwlist +server=/your-server.de/127.0.0.1#5335 +ipset=/your-server.de/gfwlist +server=/bingads.com/127.0.0.1#5335 +ipset=/bingads.com/gfwlist +server=/scholar.google.is/127.0.0.1#5335 +ipset=/scholar.google.is/gfwlist +server=/eilieili.cc/127.0.0.1#5335 +ipset=/eilieili.cc/gfwlist +server=/scholar.google.com.pe/127.0.0.1#5335 +ipset=/scholar.google.com.pe/gfwlist +server=/foxsports.uy/127.0.0.1#5335 +ipset=/foxsports.uy/gfwlist +server=/jav19.com/127.0.0.1#5335 +ipset=/jav19.com/gfwlist +server=/faceid99.com/127.0.0.1#5335 +ipset=/faceid99.com/gfwlist +server=/voxfieldguide.com/127.0.0.1#5335 +ipset=/voxfieldguide.com/gfwlist +server=/hpconnectedstage.com/127.0.0.1#5335 +ipset=/hpconnectedstage.com/gfwlist +server=/bikaios.xyz/127.0.0.1#5335 +ipset=/bikaios.xyz/gfwlist +server=/freeporn.com/127.0.0.1#5335 +ipset=/freeporn.com/gfwlist +server=/dvdstudiopro.org/127.0.0.1#5335 +ipset=/dvdstudiopro.org/gfwlist +server=/hpconnected.org/127.0.0.1#5335 +ipset=/hpconnected.org/gfwlist +server=/coova.org/127.0.0.1#5335 +ipset=/coova.org/gfwlist +server=/kundun1069.com/127.0.0.1#5335 +ipset=/kundun1069.com/gfwlist +server=/hpcmw.net/127.0.0.1#5335 +ipset=/hpcmw.net/gfwlist +server=/ikea.co.il/127.0.0.1#5335 +ipset=/ikea.co.il/gfwlist +server=/shoers.com/127.0.0.1#5335 +ipset=/shoers.com/gfwlist +server=/vnanchoi.ca/127.0.0.1#5335 +ipset=/vnanchoi.ca/gfwlist +server=/change.org/127.0.0.1#5335 +ipset=/change.org/gfwlist +server=/google.so/127.0.0.1#5335 +ipset=/google.so/gfwlist +server=/paily.net/127.0.0.1#5335 +ipset=/paily.net/gfwlist +server=/wsjwine.com/127.0.0.1#5335 +ipset=/wsjwine.com/gfwlist +server=/hpbluecarpet.net/127.0.0.1#5335 +ipset=/hpbluecarpet.net/gfwlist +server=/hpbluecarpet.com/127.0.0.1#5335 +ipset=/hpbluecarpet.com/gfwlist +server=/ecert.gov.hk/127.0.0.1#5335 +ipset=/ecert.gov.hk/gfwlist +server=/9hentai.ru/127.0.0.1#5335 +ipset=/9hentai.ru/gfwlist +server=/fuckbookecuador.com/127.0.0.1#5335 +ipset=/fuckbookecuador.com/gfwlist +server=/hpallinoneprinter.com/127.0.0.1#5335 +ipset=/hpallinoneprinter.com/gfwlist +server=/mastercard.co.il/127.0.0.1#5335 +ipset=/mastercard.co.il/gfwlist +server=/bmw-motorrad.ca/127.0.0.1#5335 +ipset=/bmw-motorrad.ca/gfwlist +server=/adultcamslover.com/127.0.0.1#5335 +ipset=/adultcamslover.com/gfwlist +server=/ikea.hk/127.0.0.1#5335 +ipset=/ikea.hk/gfwlist +server=/api.viu.now.com/127.0.0.1#5335 +ipset=/api.viu.now.com/gfwlist +server=/disney.co.uk/127.0.0.1#5335 +ipset=/disney.co.uk/gfwlist +server=/mofos.com/127.0.0.1#5335 +ipset=/mofos.com/gfwlist +server=/mwf-service.akamaized.net/127.0.0.1#5335 +ipset=/mwf-service.akamaized.net/gfwlist +server=/unusualporn.net/127.0.0.1#5335 +ipset=/unusualporn.net/gfwlist +server=/financeleadsonline.com/127.0.0.1#5335 +ipset=/financeleadsonline.com/gfwlist +server=/hp.io/127.0.0.1#5335 +ipset=/hp.io/gfwlist +server=/adultmagazinespdf.com/127.0.0.1#5335 +ipset=/adultmagazinespdf.com/gfwlist +server=/4myminicard.com/127.0.0.1#5335 +ipset=/4myminicard.com/gfwlist +server=/69vj.com/127.0.0.1#5335 +ipset=/69vj.com/gfwlist +server=/sa78gs.wpc.edgecastcdn.net/127.0.0.1#5335 +ipset=/sa78gs.wpc.edgecastcdn.net/gfwlist +server=/alpherafs.in/127.0.0.1#5335 +ipset=/alpherafs.in/gfwlist +server=/duckduckgo.org/127.0.0.1#5335 +ipset=/duckduckgo.org/gfwlist +server=/hotmail.com/127.0.0.1#5335 +ipset=/hotmail.com/gfwlist +server=/hp-mns.com/127.0.0.1#5335 +ipset=/hp-mns.com/gfwlist +server=/hp-invent.info/127.0.0.1#5335 +ipset=/hp-invent.info/gfwlist +server=/hp-infolab.com/127.0.0.1#5335 +ipset=/hp-infolab.com/gfwlist +server=/nhentaihaven.org/127.0.0.1#5335 +ipset=/nhentaihaven.org/gfwlist +server=/hp-imagine.com/127.0.0.1#5335 +ipset=/hp-imagine.com/gfwlist +server=/gaming-notebooks.com/127.0.0.1#5335 +ipset=/gaming-notebooks.com/gfwlist +server=/e-cba.org/127.0.0.1#5335 +ipset=/e-cba.org/gfwlist +server=/cheapshoesvip.com/127.0.0.1#5335 +ipset=/cheapshoesvip.com/gfwlist +server=/optica.org/127.0.0.1#5335 +ipset=/optica.org/gfwlist +server=/businessinsider.de/127.0.0.1#5335 +ipset=/businessinsider.de/gfwlist +server=/compaq.org/127.0.0.1#5335 +ipset=/compaq.org/gfwlist +server=/filesmonster.vip/127.0.0.1#5335 +ipset=/filesmonster.vip/gfwlist +server=/dianepoppos.com/127.0.0.1#5335 +ipset=/dianepoppos.com/gfwlist +server=/campushp.com/127.0.0.1#5335 +ipset=/campushp.com/gfwlist +server=/pornlistdude.com/127.0.0.1#5335 +ipset=/pornlistdude.com/gfwlist +server=/diyarbakirescort.com/127.0.0.1#5335 +ipset=/diyarbakirescort.com/gfwlist +server=/supermariorun.com/127.0.0.1#5335 +ipset=/supermariorun.com/gfwlist +server=/faebookc.com/127.0.0.1#5335 +ipset=/faebookc.com/gfwlist +server=/fox5atlanta.com/127.0.0.1#5335 +ipset=/fox5atlanta.com/gfwlist +server=/fecbbok.com/127.0.0.1#5335 +ipset=/fecbbok.com/gfwlist +server=/hexdocs.pm/127.0.0.1#5335 +ipset=/hexdocs.pm/gfwlist +server=/travelex.qa/127.0.0.1#5335 +ipset=/travelex.qa/gfwlist +server=/nudeeroticteens.com/127.0.0.1#5335 +ipset=/nudeeroticteens.com/gfwlist +server=/scdn.co/127.0.0.1#5335 +ipset=/scdn.co/gfwlist +server=/fantasti.cc/127.0.0.1#5335 +ipset=/fantasti.cc/gfwlist +server=/ntdtv.com.tw/127.0.0.1#5335 +ipset=/ntdtv.com.tw/gfwlist +server=/fawgaf.xyz/127.0.0.1#5335 +ipset=/fawgaf.xyz/gfwlist +server=/jos.com/127.0.0.1#5335 +ipset=/jos.com/gfwlist +server=/coupang.com/127.0.0.1#5335 +ipset=/coupang.com/gfwlist +server=/bmw.ps/127.0.0.1#5335 +ipset=/bmw.ps/gfwlist +server=/analvids.com/127.0.0.1#5335 +ipset=/analvids.com/gfwlist +server=/fpacebook.com/127.0.0.1#5335 +ipset=/fpacebook.com/gfwlist +server=/damduc.org/127.0.0.1#5335 +ipset=/damduc.org/gfwlist +server=/vod-thumb-ww-live.akamaized.net/127.0.0.1#5335 +ipset=/vod-thumb-ww-live.akamaized.net/gfwlist +server=/kraken.com/127.0.0.1#5335 +ipset=/kraken.com/gfwlist +server=/instagramtips.com/127.0.0.1#5335 +ipset=/instagramtips.com/gfwlist +server=/csifund.org/127.0.0.1#5335 +ipset=/csifund.org/gfwlist +server=/durex.co.za/127.0.0.1#5335 +ipset=/durex.co.za/gfwlist +server=/shopminiusa.com/127.0.0.1#5335 +ipset=/shopminiusa.com/gfwlist +server=/thepervs.com/127.0.0.1#5335 +ipset=/thepervs.com/gfwlist +server=/chtf.org.tw/127.0.0.1#5335 +ipset=/chtf.org.tw/gfwlist +server=/steam.cdn.webra.ru/127.0.0.1#5335 +ipset=/steam.cdn.webra.ru/gfwlist +server=/onlyprime.ru/127.0.0.1#5335 +ipset=/onlyprime.ru/gfwlist +server=/orgyxxxhub.com/127.0.0.1#5335 +ipset=/orgyxxxhub.com/gfwlist +server=/16honeys.com/127.0.0.1#5335 +ipset=/16honeys.com/gfwlist +server=/appleiservices.com/127.0.0.1#5335 +ipset=/appleiservices.com/gfwlist +server=/love6.tv/127.0.0.1#5335 +ipset=/love6.tv/gfwlist +server=/kimchi.tv/127.0.0.1#5335 +ipset=/kimchi.tv/gfwlist +server=/bedstegratisporno.com/127.0.0.1#5335 +ipset=/bedstegratisporno.com/gfwlist +server=/hetzner.com/127.0.0.1#5335 +ipset=/hetzner.com/gfwlist +server=/hetzner.cloud/127.0.0.1#5335 +ipset=/hetzner.cloud/gfwlist +server=/dropboxusercontent.com/127.0.0.1#5335 +ipset=/dropboxusercontent.com/gfwlist +server=/quicktime.tv/127.0.0.1#5335 +ipset=/quicktime.tv/gfwlist +server=/att-idns.net/127.0.0.1#5335 +ipset=/att-idns.net/gfwlist +server=/lollipopescorts.com/127.0.0.1#5335 +ipset=/lollipopescorts.com/gfwlist +server=/nbcudigitaladops.com/127.0.0.1#5335 +ipset=/nbcudigitaladops.com/gfwlist +server=/authy.com/127.0.0.1#5335 +ipset=/authy.com/gfwlist +server=/mini-stjohns.com/127.0.0.1#5335 +ipset=/mini-stjohns.com/gfwlist +server=/bmw-motorrad.at/127.0.0.1#5335 +ipset=/bmw-motorrad.at/gfwlist +server=/xn--ggle-55da.com/127.0.0.1#5335 +ipset=/xn--ggle-55da.com/gfwlist +server=/xn--flw351e.com/127.0.0.1#5335 +ipset=/xn--flw351e.com/gfwlist +server=/mastercard.ie/127.0.0.1#5335 +ipset=/mastercard.ie/gfwlist +server=/swisssign.li/127.0.0.1#5335 +ipset=/swisssign.li/gfwlist +server=/pinkporno.com/127.0.0.1#5335 +ipset=/pinkporno.com/gfwlist +server=/oreil.ly/127.0.0.1#5335 +ipset=/oreil.ly/gfwlist +server=/intellinuxgraphics.net/127.0.0.1#5335 +ipset=/intellinuxgraphics.net/gfwlist +server=/lencr.org/127.0.0.1#5335 +ipset=/lencr.org/gfwlist +server=/avstar04.me/127.0.0.1#5335 +ipset=/avstar04.me/gfwlist +server=/waterdamagesandiego.org/127.0.0.1#5335 +ipset=/waterdamagesandiego.org/gfwlist +server=/ibeats-uk.com/127.0.0.1#5335 +ipset=/ibeats-uk.com/gfwlist +server=/homepornvideo.net/127.0.0.1#5335 +ipset=/homepornvideo.net/gfwlist +server=/reactjs.com/127.0.0.1#5335 +ipset=/reactjs.com/gfwlist +server=/apornotube.net/127.0.0.1#5335 +ipset=/apornotube.net/gfwlist +server=/ebay.com.au/127.0.0.1#5335 +ipset=/ebay.com.au/gfwlist +server=/gay.bingo/127.0.0.1#5335 +ipset=/gay.bingo/gfwlist +server=/withgoogle.com/127.0.0.1#5335 +ipset=/withgoogle.com/gfwlist +server=/hentai01.com/127.0.0.1#5335 +ipset=/hentai01.com/gfwlist +server=/apple.us/127.0.0.1#5335 +ipset=/apple.us/gfwlist +server=/keiba.net/127.0.0.1#5335 +ipset=/keiba.net/gfwlist +server=/dns.sb/127.0.0.1#5335 +ipset=/dns.sb/gfwlist +server=/erolabs.game/127.0.0.1#5335 +ipset=/erolabs.game/gfwlist +server=/launchpad.wang/127.0.0.1#5335 +ipset=/launchpad.wang/gfwlist +server=/forhertube.com/127.0.0.1#5335 +ipset=/forhertube.com/gfwlist +server=/teamskeet.com/127.0.0.1#5335 +ipset=/teamskeet.com/gfwlist +server=/mac-mini.com/127.0.0.1#5335 +ipset=/mac-mini.com/gfwlist +server=/stripecdn.com/127.0.0.1#5335 +ipset=/stripecdn.com/gfwlist +server=/koreanpornmovie.com/127.0.0.1#5335 +ipset=/koreanpornmovie.com/gfwlist +server=/vscode-sync-insiders.trafficmanager.net/127.0.0.1#5335 +ipset=/vscode-sync-insiders.trafficmanager.net/gfwlist +server=/bmw-motorrad-dubai.com/127.0.0.1#5335 +ipset=/bmw-motorrad-dubai.com/gfwlist +server=/webappfieldguide.com/127.0.0.1#5335 +ipset=/webappfieldguide.com/gfwlist +server=/vmwidm.com/127.0.0.1#5335 +ipset=/vmwidm.com/gfwlist +server=/waze.com/127.0.0.1#5335 +ipset=/waze.com/gfwlist +server=/waymo.com/127.0.0.1#5335 +ipset=/waymo.com/gfwlist +server=/fnacebook.com/127.0.0.1#5335 +ipset=/fnacebook.com/gfwlist +server=/fox10.tv/127.0.0.1#5335 +ipset=/fox10.tv/gfwlist +server=/fox7.com/127.0.0.1#5335 +ipset=/fox7.com/gfwlist +server=/ebayclub.com/127.0.0.1#5335 +ipset=/ebayclub.com/gfwlist +server=/bmw-grouparchiv.de/127.0.0.1#5335 +ipset=/bmw-grouparchiv.de/gfwlist +server=/verilystudywatch.org/127.0.0.1#5335 +ipset=/verilystudywatch.org/gfwlist +server=/casoneexchange.com/127.0.0.1#5335 +ipset=/casoneexchange.com/gfwlist +server=/verilystudywatch.com/127.0.0.1#5335 +ipset=/verilystudywatch.com/gfwlist +server=/aokwholesale.net/127.0.0.1#5335 +ipset=/aokwholesale.net/gfwlist +server=/fapcat.com/127.0.0.1#5335 +ipset=/fapcat.com/gfwlist +server=/cobatt.com/127.0.0.1#5335 +ipset=/cobatt.com/gfwlist +server=/soccerfinancier.ca/127.0.0.1#5335 +ipset=/soccerfinancier.ca/gfwlist +server=/cumteenporn.com/127.0.0.1#5335 +ipset=/cumteenporn.com/gfwlist +server=/seiroganmania.com/127.0.0.1#5335 +ipset=/seiroganmania.com/gfwlist +server=/watchindianporn.net/127.0.0.1#5335 +ipset=/watchindianporn.net/gfwlist +server=/discord.com/127.0.0.1#5335 +ipset=/discord.com/gfwlist +server=/hotmonsterbeats.com/127.0.0.1#5335 +ipset=/hotmonsterbeats.com/gfwlist +server=/bienvenuechezbestbuy.ca/127.0.0.1#5335 +ipset=/bienvenuechezbestbuy.ca/gfwlist +server=/minifs.com/127.0.0.1#5335 +ipset=/minifs.com/gfwlist +server=/pornaroma.com/127.0.0.1#5335 +ipset=/pornaroma.com/gfwlist +server=/unfiltered.news/127.0.0.1#5335 +ipset=/unfiltered.news/gfwlist +server=/aclweb.org/127.0.0.1#5335 +ipset=/aclweb.org/gfwlist +server=/ffprofile.com/127.0.0.1#5335 +ipset=/ffprofile.com/gfwlist +server=/scholar.google.com.ni/127.0.0.1#5335 +ipset=/scholar.google.com.ni/gfwlist +server=/txvia.com/127.0.0.1#5335 +ipset=/txvia.com/gfwlist +server=/cbsiam.com/127.0.0.1#5335 +ipset=/cbsiam.com/gfwlist +server=/vbejeyv.shop/127.0.0.1#5335 +ipset=/vbejeyv.shop/gfwlist +server=/youtube.com.mk/127.0.0.1#5335 +ipset=/youtube.com.mk/gfwlist +server=/mysocialworklab.com/127.0.0.1#5335 +ipset=/mysocialworklab.com/gfwlist +server=/thinkquarterly.com/127.0.0.1#5335 +ipset=/thinkquarterly.com/gfwlist +server=/youtube.co.ve/127.0.0.1#5335 +ipset=/youtube.co.ve/gfwlist +server=/vscode.dev/127.0.0.1#5335 +ipset=/vscode.dev/gfwlist +server=/yammer.com/127.0.0.1#5335 +ipset=/yammer.com/gfwlist +server=/analpornonly.com/127.0.0.1#5335 +ipset=/analpornonly.com/gfwlist +server=/02weqj32.com/127.0.0.1#5335 +ipset=/02weqj32.com/gfwlist +server=/volvogroup.jp/127.0.0.1#5335 +ipset=/volvogroup.jp/gfwlist +server=/launchpadlibrarian.com/127.0.0.1#5335 +ipset=/launchpadlibrarian.com/gfwlist +server=/vs-cmaf-push-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vs-cmaf-push-uk-live.akamaized.net/gfwlist +server=/hath.network/127.0.0.1#5335 +ipset=/hath.network/gfwlist +server=/mathoverflow.net/127.0.0.1#5335 +ipset=/mathoverflow.net/gfwlist +server=/sony-hes.co.jp/127.0.0.1#5335 +ipset=/sony-hes.co.jp/gfwlist +server=/synergyse.com/127.0.0.1#5335 +ipset=/synergyse.com/gfwlist +server=/blogspot.sg/127.0.0.1#5335 +ipset=/blogspot.sg/gfwlist +server=/matureladiesxxx.com/127.0.0.1#5335 +ipset=/matureladiesxxx.com/gfwlist +server=/casque-fr.com/127.0.0.1#5335 +ipset=/casque-fr.com/gfwlist +server=/stxmosquitoproject.com/127.0.0.1#5335 +ipset=/stxmosquitoproject.com/gfwlist +server=/beatsbydreausale.net/127.0.0.1#5335 +ipset=/beatsbydreausale.net/gfwlist +server=/amamanualofstyle.com/127.0.0.1#5335 +ipset=/amamanualofstyle.com/gfwlist +server=/getbraintree.com/127.0.0.1#5335 +ipset=/getbraintree.com/gfwlist +server=/realclearpublicaffairs.com/127.0.0.1#5335 +ipset=/realclearpublicaffairs.com/gfwlist +server=/webex.co.kr/127.0.0.1#5335 +ipset=/webex.co.kr/gfwlist +server=/animalpornxxx.me/127.0.0.1#5335 +ipset=/animalpornxxx.me/gfwlist +server=/faceboo.com/127.0.0.1#5335 +ipset=/faceboo.com/gfwlist +server=/stcroixmosquitoproject.com/127.0.0.1#5335 +ipset=/stcroixmosquitoproject.com/gfwlist +server=/beddit.tv/127.0.0.1#5335 +ipset=/beddit.tv/gfwlist +server=/stcroixmosquito.com/127.0.0.1#5335 +ipset=/stcroixmosquito.com/gfwlist +server=/mottainai.info/127.0.0.1#5335 +ipset=/mottainai.info/gfwlist +server=/mirrorsedge.com/127.0.0.1#5335 +ipset=/mirrorsedge.com/gfwlist +server=/realclearscience.com/127.0.0.1#5335 +ipset=/realclearscience.com/gfwlist +server=/fictionmania.tv/127.0.0.1#5335 +ipset=/fictionmania.tv/gfwlist +server=/solveforx.com/127.0.0.1#5335 +ipset=/solveforx.com/gfwlist +server=/cashpassport.com.br/127.0.0.1#5335 +ipset=/cashpassport.com.br/gfwlist +server=/alohatube.com/127.0.0.1#5335 +ipset=/alohatube.com/gfwlist +server=/xnxx18.pro/127.0.0.1#5335 +ipset=/xnxx18.pro/gfwlist +server=/screenwisetrendspanel.com/127.0.0.1#5335 +ipset=/screenwisetrendspanel.com/gfwlist +server=/webobjects.de/127.0.0.1#5335 +ipset=/webobjects.de/gfwlist +server=/saynow.com/127.0.0.1#5335 +ipset=/saynow.com/gfwlist +server=/fi11.cn/127.0.0.1#5335 +ipset=/fi11.cn/gfwlist +server=/run.app/127.0.0.1#5335 +ipset=/run.app/gfwlist +server=/ridepenguin.com/127.0.0.1#5335 +ipset=/ridepenguin.com/gfwlist +server=/setn.com/127.0.0.1#5335 +ipset=/setn.com/gfwlist +server=/revolv.com/127.0.0.1#5335 +ipset=/revolv.com/gfwlist +server=/gettyimages.de/127.0.0.1#5335 +ipset=/gettyimages.de/gfwlist +server=/bmwmotorsport.com/127.0.0.1#5335 +ipset=/bmwmotorsport.com/gfwlist +server=/colegialasdeverdad.com/127.0.0.1#5335 +ipset=/colegialasdeverdad.com/gfwlist +server=/pvr-hamivideo.cdn.hinet.net/127.0.0.1#5335 +ipset=/pvr-hamivideo.cdn.hinet.net/gfwlist +server=/adwordsexpress.com/127.0.0.1#5335 +ipset=/adwordsexpress.com/gfwlist +server=/ajplus.net/127.0.0.1#5335 +ipset=/ajplus.net/gfwlist +server=/muji.tw/127.0.0.1#5335 +ipset=/muji.tw/gfwlist +server=/publishproxy.com/127.0.0.1#5335 +ipset=/publishproxy.com/gfwlist +server=/google.com.au/127.0.0.1#5335 +ipset=/google.com.au/gfwlist +server=/heavyfetish.com/127.0.0.1#5335 +ipset=/heavyfetish.com/gfwlist +server=/thehealthsite.com/127.0.0.1#5335 +ipset=/thehealthsite.com/gfwlist +server=/21naturals.com/127.0.0.1#5335 +ipset=/21naturals.com/gfwlist +server=/mytokenapi.com/127.0.0.1#5335 +ipset=/mytokenapi.com/gfwlist +server=/projectara.com/127.0.0.1#5335 +ipset=/projectara.com/gfwlist +server=/privacysandbox.com/127.0.0.1#5335 +ipset=/privacysandbox.com/gfwlist +server=/arewereadyyet.com/127.0.0.1#5335 +ipset=/arewereadyyet.com/gfwlist +server=/pixate.com/127.0.0.1#5335 +ipset=/pixate.com/gfwlist +server=/canon.com.au/127.0.0.1#5335 +ipset=/canon.com.au/gfwlist +server=/sorairi.info/127.0.0.1#5335 +ipset=/sorairi.info/gfwlist +server=/picnik.com/127.0.0.1#5335 +ipset=/picnik.com/gfwlist +server=/bejav.net/127.0.0.1#5335 +ipset=/bejav.net/gfwlist +server=/pornma.com/127.0.0.1#5335 +ipset=/pornma.com/gfwlist +server=/myyoungmomisnude.com/127.0.0.1#5335 +ipset=/myyoungmomisnude.com/gfwlist +server=/economistgroupcareers.com/127.0.0.1#5335 +ipset=/economistgroupcareers.com/gfwlist +server=/charmescorts.com/127.0.0.1#5335 +ipset=/charmescorts.com/gfwlist +server=/kijijii.ca/127.0.0.1#5335 +ipset=/kijijii.ca/gfwlist +server=/dogofcum.com/127.0.0.1#5335 +ipset=/dogofcum.com/gfwlist +server=/guo.media/127.0.0.1#5335 +ipset=/guo.media/gfwlist +server=/youtube.cl/127.0.0.1#5335 +ipset=/youtube.cl/gfwlist +server=/botframework.com/127.0.0.1#5335 +ipset=/botframework.com/gfwlist +server=/epochtimes.se/127.0.0.1#5335 +ipset=/epochtimes.se/gfwlist +server=/singlelogin.me/127.0.0.1#5335 +ipset=/singlelogin.me/gfwlist +server=/visiontimes.com/127.0.0.1#5335 +ipset=/visiontimes.com/gfwlist +server=/actalis.it/127.0.0.1#5335 +ipset=/actalis.it/gfwlist +server=/google.is/127.0.0.1#5335 +ipset=/google.is/gfwlist +server=/riot.com/127.0.0.1#5335 +ipset=/riot.com/gfwlist +server=/bmw-rp.com/127.0.0.1#5335 +ipset=/bmw-rp.com/gfwlist +server=/ebayca.org/127.0.0.1#5335 +ipset=/ebayca.org/gfwlist +server=/grandfuckauto.xxx/127.0.0.1#5335 +ipset=/grandfuckauto.xxx/gfwlist +server=/18schoolgirlz.me/127.0.0.1#5335 +ipset=/18schoolgirlz.me/gfwlist +server=/oneworldmanystories.com/127.0.0.1#5335 +ipset=/oneworldmanystories.com/gfwlist +server=/hpapplicationscenter.com/127.0.0.1#5335 +ipset=/hpapplicationscenter.com/gfwlist +server=/mastercard.com.my/127.0.0.1#5335 +ipset=/mastercard.com.my/gfwlist +server=/pornfuck.net/127.0.0.1#5335 +ipset=/pornfuck.net/gfwlist +server=/on2.com/127.0.0.1#5335 +ipset=/on2.com/gfwlist +server=/on.here/127.0.0.1#5335 +ipset=/on.here/gfwlist +server=/cbsi.com/127.0.0.1#5335 +ipset=/cbsi.com/gfwlist +server=/avseesee.com/127.0.0.1#5335 +ipset=/avseesee.com/gfwlist +server=/titsbox.com/127.0.0.1#5335 +ipset=/titsbox.com/gfwlist +server=/nest.com/127.0.0.1#5335 +ipset=/nest.com/gfwlist +server=/near.by/127.0.0.1#5335 +ipset=/near.by/gfwlist +server=/6sextube.com/127.0.0.1#5335 +ipset=/6sextube.com/gfwlist +server=/girlfur.com/127.0.0.1#5335 +ipset=/girlfur.com/gfwlist +server=/moodstocks.com/127.0.0.1#5335 +ipset=/moodstocks.com/gfwlist +server=/appleclub.com.hk/127.0.0.1#5335 +ipset=/appleclub.com.hk/gfwlist +server=/beatsdrdre-headphones.com/127.0.0.1#5335 +ipset=/beatsdrdre-headphones.com/gfwlist +server=/mfg-inspector.com/127.0.0.1#5335 +ipset=/mfg-inspector.com/gfwlist +server=/fucksexhub.com/127.0.0.1#5335 +ipset=/fucksexhub.com/gfwlist +server=/dragonhentai.net/127.0.0.1#5335 +ipset=/dragonhentai.net/gfwlist +server=/meet.new/127.0.0.1#5335 +ipset=/meet.new/gfwlist +server=/hifiporn.fun/127.0.0.1#5335 +ipset=/hifiporn.fun/gfwlist +server=/tx5ptbp7.com/127.0.0.1#5335 +ipset=/tx5ptbp7.com/gfwlist +server=/customizedbeatsbydre.com/127.0.0.1#5335 +ipset=/customizedbeatsbydre.com/gfwlist +server=/rapidssl.com/127.0.0.1#5335 +ipset=/rapidssl.com/gfwlist +server=/madewithcode.com/127.0.0.1#5335 +ipset=/madewithcode.com/gfwlist +server=/listinganalytics.net/127.0.0.1#5335 +ipset=/listinganalytics.net/gfwlist +server=/yahoo.ae/127.0.0.1#5335 +ipset=/yahoo.ae/gfwlist +server=/keytransparency.org/127.0.0.1#5335 +ipset=/keytransparency.org/gfwlist +server=/xcity.jp/127.0.0.1#5335 +ipset=/xcity.jp/gfwlist +server=/sexcord.com/127.0.0.1#5335 +ipset=/sexcord.com/gfwlist +server=/alpherafs.com.my/127.0.0.1#5335 +ipset=/alpherafs.com.my/gfwlist +server=/joeswall.com/127.0.0.1#5335 +ipset=/joeswall.com/gfwlist +server=/plantsvszombies2.com/127.0.0.1#5335 +ipset=/plantsvszombies2.com/gfwlist +server=/op.gg/127.0.0.1#5335 +ipset=/op.gg/gfwlist +server=/ebaya.com/127.0.0.1#5335 +ipset=/ebaya.com/gfwlist +server=/impermium.com/127.0.0.1#5335 +ipset=/impermium.com/gfwlist +server=/only3x.com/127.0.0.1#5335 +ipset=/only3x.com/gfwlist +server=/topadultgames.biz/127.0.0.1#5335 +ipset=/topadultgames.biz/gfwlist +server=/amateurbdsmporn.com/127.0.0.1#5335 +ipset=/amateurbdsmporn.com/gfwlist +server=/hwgo.com/127.0.0.1#5335 +ipset=/hwgo.com/gfwlist +server=/hereistheporn.com/127.0.0.1#5335 +ipset=/hereistheporn.com/gfwlist +server=/hentailabs.com/127.0.0.1#5335 +ipset=/hentailabs.com/gfwlist +server=/playforceone.com/127.0.0.1#5335 +ipset=/playforceone.com/gfwlist +server=/deepfake-porn.com/127.0.0.1#5335 +ipset=/deepfake-porn.com/gfwlist +server=/adorable-teens.net/127.0.0.1#5335 +ipset=/adorable-teens.net/gfwlist +server=/metro.co.uk/127.0.0.1#5335 +ipset=/metro.co.uk/gfwlist +server=/ikea.com.kw/127.0.0.1#5335 +ipset=/ikea.com.kw/gfwlist +server=/bmw-motorrad.it/127.0.0.1#5335 +ipset=/bmw-motorrad.it/gfwlist +server=/beatbydreheadphonesonsale.com/127.0.0.1#5335 +ipset=/beatbydreheadphonesonsale.com/gfwlist +server=/girls.xyz/127.0.0.1#5335 +ipset=/girls.xyz/gfwlist +server=/hobonichielog.com/127.0.0.1#5335 +ipset=/hobonichielog.com/gfwlist +server=/scholar.google.co.in/127.0.0.1#5335 +ipset=/scholar.google.co.in/gfwlist +server=/luscious.net/127.0.0.1#5335 +ipset=/luscious.net/gfwlist +server=/blogspot.ch/127.0.0.1#5335 +ipset=/blogspot.ch/gfwlist +server=/smartone.com/127.0.0.1#5335 +ipset=/smartone.com/gfwlist +server=/mobilelive-hamivideo.cdn.hinet.net/127.0.0.1#5335 +ipset=/mobilelive-hamivideo.cdn.hinet.net/gfwlist +server=/gvt9.com/127.0.0.1#5335 +ipset=/gvt9.com/gfwlist +server=/funshemale.com/127.0.0.1#5335 +ipset=/funshemale.com/gfwlist +server=/wwwapplemusic.com/127.0.0.1#5335 +ipset=/wwwapplemusic.com/gfwlist +server=/elephantlist.com/127.0.0.1#5335 +ipset=/elephantlist.com/gfwlist +server=/tidal.com/127.0.0.1#5335 +ipset=/tidal.com/gfwlist +server=/gvt6.com/127.0.0.1#5335 +ipset=/gvt6.com/gfwlist +server=/bmwmotorrad.co.kr/127.0.0.1#5335 +ipset=/bmwmotorrad.co.kr/gfwlist +server=/2013newbeatsworld.com/127.0.0.1#5335 +ipset=/2013newbeatsworld.com/gfwlist +server=/springer.com/127.0.0.1#5335 +ipset=/springer.com/gfwlist +server=/battlefield1943.com/127.0.0.1#5335 +ipset=/battlefield1943.com/gfwlist +server=/gvt2.com/127.0.0.1#5335 +ipset=/gvt2.com/gfwlist +server=/volvobuses.my/127.0.0.1#5335 +ipset=/volvobuses.my/gfwlist +server=/4everland.io/127.0.0.1#5335 +ipset=/4everland.io/gfwlist +server=/gvt1.com/127.0.0.1#5335 +ipset=/gvt1.com/gfwlist +server=/bmw.dz/127.0.0.1#5335 +ipset=/bmw.dz/gfwlist +server=/gstatic.com/127.0.0.1#5335 +ipset=/gstatic.com/gfwlist +server=/friendfed.com/127.0.0.1#5335 +ipset=/friendfed.com/gfwlist +server=/buyitnow.tv/127.0.0.1#5335 +ipset=/buyitnow.tv/gfwlist +server=/ysporn.com/127.0.0.1#5335 +ipset=/ysporn.com/gfwlist +server=/gooogle.com/127.0.0.1#5335 +ipset=/gooogle.com/gfwlist +server=/6twseb.com/127.0.0.1#5335 +ipset=/6twseb.com/gfwlist +server=/goolge.com/127.0.0.1#5335 +ipset=/goolge.com/gfwlist +server=/googlr.com/127.0.0.1#5335 +ipset=/googlr.com/gfwlist +server=/espadoldettol.com.ar/127.0.0.1#5335 +ipset=/espadoldettol.com.ar/gfwlist +server=/pornobrasil.blog.br/127.0.0.1#5335 +ipset=/pornobrasil.blog.br/gfwlist +server=/e621.net/127.0.0.1#5335 +ipset=/e621.net/gfwlist +server=/mini-connected.be/127.0.0.1#5335 +ipset=/mini-connected.be/gfwlist +server=/fasebook.com/127.0.0.1#5335 +ipset=/fasebook.com/gfwlist +server=/cloudflarewarp.com/127.0.0.1#5335 +ipset=/cloudflarewarp.com/gfwlist +server=/googlesverige.com/127.0.0.1#5335 +ipset=/googlesverige.com/gfwlist +server=/indaznlab.com/127.0.0.1#5335 +ipset=/indaznlab.com/gfwlist +server=/nikesku.com/127.0.0.1#5335 +ipset=/nikesku.com/gfwlist +server=/projectapex.com/127.0.0.1#5335 +ipset=/projectapex.com/gfwlist +server=/anime-pictures.net/127.0.0.1#5335 +ipset=/anime-pictures.net/gfwlist +server=/cheapnikedunks.com/127.0.0.1#5335 +ipset=/cheapnikedunks.com/gfwlist +server=/wariolandshakeit.com/127.0.0.1#5335 +ipset=/wariolandshakeit.com/gfwlist +server=/hentai24h.tv/127.0.0.1#5335 +ipset=/hentai24h.tv/gfwlist +server=/teenrave.org/127.0.0.1#5335 +ipset=/teenrave.org/gfwlist +server=/primeindianporn.com/127.0.0.1#5335 +ipset=/primeindianporn.com/gfwlist +server=/ebaypakistan.net/127.0.0.1#5335 +ipset=/ebaypakistan.net/gfwlist +server=/ebay.mn/127.0.0.1#5335 +ipset=/ebay.mn/gfwlist +server=/firestonebpco.com/127.0.0.1#5335 +ipset=/firestonebpco.com/gfwlist +server=/herringnetwork.com/127.0.0.1#5335 +ipset=/herringnetwork.com/gfwlist +server=/opinionjournal.com/127.0.0.1#5335 +ipset=/opinionjournal.com/gfwlist +server=/rule34.us/127.0.0.1#5335 +ipset=/rule34.us/gfwlist +server=/monsterbeatscommunity.com/127.0.0.1#5335 +ipset=/monsterbeatscommunity.com/gfwlist +server=/dynafleetonline.com/127.0.0.1#5335 +ipset=/dynafleetonline.com/gfwlist +server=/googleplus.com/127.0.0.1#5335 +ipset=/googleplus.com/gfwlist +server=/googleplay.com/127.0.0.1#5335 +ipset=/googleplay.com/gfwlist +server=/googlephotos.com/127.0.0.1#5335 +ipset=/googlephotos.com/gfwlist +server=/playmation.com/127.0.0.1#5335 +ipset=/playmation.com/gfwlist +server=/googlepagecreator.com/127.0.0.1#5335 +ipset=/googlepagecreator.com/gfwlist +server=/googlemaps.com/127.0.0.1#5335 +ipset=/googlemaps.com/gfwlist +server=/fgacebook.com/127.0.0.1#5335 +ipset=/fgacebook.com/gfwlist +server=/bestbuycanada.ca/127.0.0.1#5335 +ipset=/bestbuycanada.ca/gfwlist +server=/xfockers.com/127.0.0.1#5335 +ipset=/xfockers.com/gfwlist +server=/avinetworks.com/127.0.0.1#5335 +ipset=/avinetworks.com/gfwlist +server=/googlefiber.com/127.0.0.1#5335 +ipset=/googlefiber.com/gfwlist +server=/weiyuksj.com/127.0.0.1#5335 +ipset=/weiyuksj.com/gfwlist +server=/volvotrucks.net/127.0.0.1#5335 +ipset=/volvotrucks.net/gfwlist +server=/nikeoutletstores.com/127.0.0.1#5335 +ipset=/nikeoutletstores.com/gfwlist +server=/mastercardacademy.com/127.0.0.1#5335 +ipset=/mastercardacademy.com/gfwlist +server=/thefappeningblog.com/127.0.0.1#5335 +ipset=/thefappeningblog.com/gfwlist +server=/visabank.org/127.0.0.1#5335 +ipset=/visabank.org/gfwlist +server=/apple.news/127.0.0.1#5335 +ipset=/apple.news/gfwlist +server=/wenzhao.ca/127.0.0.1#5335 +ipset=/wenzhao.ca/gfwlist +server=/microad.co.jp/127.0.0.1#5335 +ipset=/microad.co.jp/gfwlist +server=/neow.in/127.0.0.1#5335 +ipset=/neow.in/gfwlist +server=/ocbmwdealers.com/127.0.0.1#5335 +ipset=/ocbmwdealers.com/gfwlist +server=/myfoxhouston.com/127.0.0.1#5335 +ipset=/myfoxhouston.com/gfwlist +server=/bmw.tm/127.0.0.1#5335 +ipset=/bmw.tm/gfwlist +server=/bitstream.com/127.0.0.1#5335 +ipset=/bitstream.com/gfwlist +server=/savitabhabhi.com/127.0.0.1#5335 +ipset=/savitabhabhi.com/gfwlist +server=/googlecommerce.com/127.0.0.1#5335 +ipset=/googlecommerce.com/gfwlist +server=/ikea.com.hk/127.0.0.1#5335 +ipset=/ikea.com.hk/gfwlist +server=/facebol.com/127.0.0.1#5335 +ipset=/facebol.com/gfwlist +server=/libraryofthumbs.com/127.0.0.1#5335 +ipset=/libraryofthumbs.com/gfwlist +server=/statuspage.io/127.0.0.1#5335 +ipset=/statuspage.io/gfwlist +server=/epochtimes.jp/127.0.0.1#5335 +ipset=/epochtimes.jp/gfwlist +server=/googlebot.com/127.0.0.1#5335 +ipset=/googlebot.com/gfwlist +server=/google.ventures/127.0.0.1#5335 +ipset=/google.ventures/gfwlist +server=/google.dev/127.0.0.1#5335 +ipset=/google.dev/gfwlist +server=/google.berlin/127.0.0.1#5335 +ipset=/google.berlin/gfwlist +server=/google-access.net/127.0.0.1#5335 +ipset=/google-access.net/gfwlist +server=/pornoincreible.com/127.0.0.1#5335 +ipset=/pornoincreible.com/gfwlist +server=/priceless.org/127.0.0.1#5335 +ipset=/priceless.org/gfwlist +server=/ffacebook.com/127.0.0.1#5335 +ipset=/ffacebook.com/gfwlist +server=/goo.gl/127.0.0.1#5335 +ipset=/goo.gl/gfwlist +server=/napiszex.com/127.0.0.1#5335 +ipset=/napiszex.com/gfwlist +server=/gonglchuangl.net/127.0.0.1#5335 +ipset=/gonglchuangl.net/gfwlist +server=/gogle.com/127.0.0.1#5335 +ipset=/gogle.com/gfwlist +server=/instagramtr.com/127.0.0.1#5335 +ipset=/instagramtr.com/gfwlist +server=/gmodules.com/127.0.0.1#5335 +ipset=/gmodules.com/gfwlist +server=/awsautopilot.com/127.0.0.1#5335 +ipset=/awsautopilot.com/gfwlist +server=/gipscorp.com/127.0.0.1#5335 +ipset=/gipscorp.com/gfwlist +server=/c-span.org/127.0.0.1#5335 +ipset=/c-span.org/gfwlist +server=/getbumptop.com/127.0.0.1#5335 +ipset=/getbumptop.com/gfwlist +server=/gerritcodereview.com/127.0.0.1#5335 +ipset=/gerritcodereview.com/gfwlist +server=/videodelivery.net/127.0.0.1#5335 +ipset=/videodelivery.net/gfwlist +server=/gimy.tv/127.0.0.1#5335 +ipset=/gimy.tv/gfwlist +server=/g.page/127.0.0.1#5335 +ipset=/g.page/gfwlist +server=/ctv.com.tw/127.0.0.1#5335 +ipset=/ctv.com.tw/gfwlist +server=/porngameshub.com/127.0.0.1#5335 +ipset=/porngameshub.com/gfwlist +server=/g-tun.com/127.0.0.1#5335 +ipset=/g-tun.com/gfwlist +server=/fuchsia.dev/127.0.0.1#5335 +ipset=/fuchsia.dev/gfwlist +server=/volvopenta.se/127.0.0.1#5335 +ipset=/volvopenta.se/gfwlist +server=/enf-cmnf.com/127.0.0.1#5335 +ipset=/enf-cmnf.com/gfwlist +server=/zooporn.video/127.0.0.1#5335 +ipset=/zooporn.video/gfwlist +server=/ad.games.dmm.com/127.0.0.1#5335 +ipset=/ad.games.dmm.com/gfwlist +server=/ikea.com/127.0.0.1#5335 +ipset=/ikea.com/gfwlist +server=/pinyinxiang.com/127.0.0.1#5335 +ipset=/pinyinxiang.com/gfwlist +server=/workplaceusecases.com/127.0.0.1#5335 +ipset=/workplaceusecases.com/gfwlist +server=/okkisokuho.com/127.0.0.1#5335 +ipset=/okkisokuho.com/gfwlist +server=/fflick.com/127.0.0.1#5335 +ipset=/fflick.com/gfwlist +server=/episodic.com/127.0.0.1#5335 +ipset=/episodic.com/gfwlist +server=/udndata.com/127.0.0.1#5335 +ipset=/udndata.com/gfwlist +server=/paidpornsites.com/127.0.0.1#5335 +ipset=/paidpornsites.com/gfwlist +server=/ganjingworld.com/127.0.0.1#5335 +ipset=/ganjingworld.com/gfwlist +server=/needforspeedoverdrive.com/127.0.0.1#5335 +ipset=/needforspeedoverdrive.com/gfwlist +server=/myfappening.org/127.0.0.1#5335 +ipset=/myfappening.org/gfwlist +server=/bmwchampionshipusa.com/127.0.0.1#5335 +ipset=/bmwchampionshipusa.com/gfwlist +server=/mastercard.hu/127.0.0.1#5335 +ipset=/mastercard.hu/gfwlist +server=/cherrynudes.com/127.0.0.1#5335 +ipset=/cherrynudes.com/gfwlist +server=/icloud.lv/127.0.0.1#5335 +ipset=/icloud.lv/gfwlist +server=/twnextdigital.com/127.0.0.1#5335 +ipset=/twnextdigital.com/gfwlist +server=/2013beatshdcybermonday.com/127.0.0.1#5335 +ipset=/2013beatshdcybermonday.com/gfwlist +server=/acgdg.com/127.0.0.1#5335 +ipset=/acgdg.com/gfwlist +server=/fuckmypakistanigf.com/127.0.0.1#5335 +ipset=/fuckmypakistanigf.com/gfwlist +server=/salesforcemarketingcloud.com/127.0.0.1#5335 +ipset=/salesforcemarketingcloud.com/gfwlist +server=/nubilesunscripted.com/127.0.0.1#5335 +ipset=/nubilesunscripted.com/gfwlist +server=/crossmediapanel.com/127.0.0.1#5335 +ipset=/crossmediapanel.com/gfwlist +server=/coova.net/127.0.0.1#5335 +ipset=/coova.net/gfwlist +server=/purelyceleb.com/127.0.0.1#5335 +ipset=/purelyceleb.com/gfwlist +server=/cookiechoices.org/127.0.0.1#5335 +ipset=/cookiechoices.org/gfwlist +server=/nekora.main.jp/127.0.0.1#5335 +ipset=/nekora.main.jp/gfwlist +server=/ieeecsc.org/127.0.0.1#5335 +ipset=/ieeecsc.org/gfwlist +server=/smpte.org/127.0.0.1#5335 +ipset=/smpte.org/gfwlist +server=/google.gr/127.0.0.1#5335 +ipset=/google.gr/gfwlist +server=/codespot.com/127.0.0.1#5335 +ipset=/codespot.com/gfwlist +server=/cobrasearch.com/127.0.0.1#5335 +ipset=/cobrasearch.com/gfwlist +server=/ciscowebseminars.com/127.0.0.1#5335 +ipset=/ciscowebseminars.com/gfwlist +server=/ixxx.com/127.0.0.1#5335 +ipset=/ixxx.com/gfwlist +server=/chronicle.security/127.0.0.1#5335 +ipset=/chronicle.security/gfwlist +server=/intel.sg/127.0.0.1#5335 +ipset=/intel.sg/gfwlist +server=/onlinemonsterbeatsonsale.com/127.0.0.1#5335 +ipset=/onlinemonsterbeatsonsale.com/gfwlist +server=/steam.cdn.orcon.net.nz/127.0.0.1#5335 +ipset=/steam.cdn.orcon.net.nz/gfwlist +server=/mastercard.md/127.0.0.1#5335 +ipset=/mastercard.md/gfwlist +server=/hbrowse.com/127.0.0.1#5335 +ipset=/hbrowse.com/gfwlist +server=/nutramigen.net/127.0.0.1#5335 +ipset=/nutramigen.net/gfwlist +server=/2ch.net/127.0.0.1#5335 +ipset=/2ch.net/gfwlist +server=/mini-antilles.fr/127.0.0.1#5335 +ipset=/mini-antilles.fr/gfwlist +server=/grandepornogratis.com/127.0.0.1#5335 +ipset=/grandepornogratis.com/gfwlist +server=/5ch.net/127.0.0.1#5335 +ipset=/5ch.net/gfwlist +server=/mzstatic.com/127.0.0.1#5335 +ipset=/mzstatic.com/gfwlist +server=/winticket.jp/127.0.0.1#5335 +ipset=/winticket.jp/gfwlist +server=/bumptunes.com/127.0.0.1#5335 +ipset=/bumptunes.com/gfwlist +server=/buycheapbeatsdreuk.com/127.0.0.1#5335 +ipset=/buycheapbeatsdreuk.com/gfwlist +server=/foxnewsradio.com/127.0.0.1#5335 +ipset=/foxnewsradio.com/gfwlist +server=/bumptop.net/127.0.0.1#5335 +ipset=/bumptop.net/gfwlist +server=/bumptop.com/127.0.0.1#5335 +ipset=/bumptop.com/gfwlist +server=/javpost.net/127.0.0.1#5335 +ipset=/javpost.net/gfwlist +server=/adulterfree.com/127.0.0.1#5335 +ipset=/adulterfree.com/gfwlist +server=/bumptop.ca/127.0.0.1#5335 +ipset=/bumptop.ca/gfwlist +server=/javcl.com/127.0.0.1#5335 +ipset=/javcl.com/gfwlist +server=/foxtelevisionstations.com/127.0.0.1#5335 +ipset=/foxtelevisionstations.com/gfwlist +server=/bmw-world.com/127.0.0.1#5335 +ipset=/bmw-world.com/gfwlist +server=/binance.cc/127.0.0.1#5335 +ipset=/binance.cc/gfwlist +server=/doujinland.info/127.0.0.1#5335 +ipset=/doujinland.info/gfwlist +server=/streamxxx.tv/127.0.0.1#5335 +ipset=/streamxxx.tv/gfwlist +server=/ebay.com.hk/127.0.0.1#5335 +ipset=/ebay.com.hk/gfwlist +server=/apture.com/127.0.0.1#5335 +ipset=/apture.com/gfwlist +server=/zooskoolvideos.com/127.0.0.1#5335 +ipset=/zooskoolvideos.com/gfwlist +server=/6park.com/127.0.0.1#5335 +ipset=/6park.com/gfwlist +server=/himalaya-exchange.zendesk.com/127.0.0.1#5335 +ipset=/himalaya-exchange.zendesk.com/gfwlist +server=/appbridge.it/127.0.0.1#5335 +ipset=/appbridge.it/gfwlist +server=/twinkybf.com/127.0.0.1#5335 +ipset=/twinkybf.com/gfwlist +server=/ipod.eu/127.0.0.1#5335 +ipset=/ipod.eu/gfwlist +server=/nikeshoes4u.com/127.0.0.1#5335 +ipset=/nikeshoes4u.com/gfwlist +server=/foxdeportes.tv/127.0.0.1#5335 +ipset=/foxdeportes.tv/gfwlist +server=/triballo.net/127.0.0.1#5335 +ipset=/triballo.net/gfwlist +server=/scholar.google.si/127.0.0.1#5335 +ipset=/scholar.google.si/gfwlist +server=/curvyerotic.com/127.0.0.1#5335 +ipset=/curvyerotic.com/gfwlist +server=/arabidopsis.org/127.0.0.1#5335 +ipset=/arabidopsis.org/gfwlist +server=/nflxso.net/127.0.0.1#5335 +ipset=/nflxso.net/gfwlist +server=/1ucrs.com/127.0.0.1#5335 +ipset=/1ucrs.com/gfwlist +server=/dreammovies.com/127.0.0.1#5335 +ipset=/dreammovies.com/gfwlist +server=/ciscokinetic.com/127.0.0.1#5335 +ipset=/ciscokinetic.com/gfwlist +server=/shopee.ph/127.0.0.1#5335 +ipset=/shopee.ph/gfwlist +server=/6xxxvideos.com/127.0.0.1#5335 +ipset=/6xxxvideos.com/gfwlist +server=/stonefoxproductions.com/127.0.0.1#5335 +ipset=/stonefoxproductions.com/gfwlist +server=/google.to/127.0.0.1#5335 +ipset=/google.to/gfwlist +server=/myoctocat.com/127.0.0.1#5335 +ipset=/myoctocat.com/gfwlist +server=/google.tn/127.0.0.1#5335 +ipset=/google.tn/gfwlist +server=/google.tm/127.0.0.1#5335 +ipset=/google.tm/gfwlist +server=/tubexclips.com/127.0.0.1#5335 +ipset=/tubexclips.com/gfwlist +server=/beatdrdres.com/127.0.0.1#5335 +ipset=/beatdrdres.com/gfwlist +server=/vmwareidentity.com/127.0.0.1#5335 +ipset=/vmwareidentity.com/gfwlist +server=/paypalhere.org/127.0.0.1#5335 +ipset=/paypalhere.org/gfwlist +server=/firestone.com.br/127.0.0.1#5335 +ipset=/firestone.com.br/gfwlist +server=/pornhub.org/127.0.0.1#5335 +ipset=/pornhub.org/gfwlist +server=/91avfuli.com/127.0.0.1#5335 +ipset=/91avfuli.com/gfwlist +server=/korewaeroi.com/127.0.0.1#5335 +ipset=/korewaeroi.com/gfwlist +server=/pchomeec.tw/127.0.0.1#5335 +ipset=/pchomeec.tw/gfwlist +server=/google.si/127.0.0.1#5335 +ipset=/google.si/gfwlist +server=/eromazofu.com/127.0.0.1#5335 +ipset=/eromazofu.com/gfwlist +server=/familysimulator.com/127.0.0.1#5335 +ipset=/familysimulator.com/gfwlist +server=/xn--7hv594h.com/127.0.0.1#5335 +ipset=/xn--7hv594h.com/gfwlist +server=/internetofeverything.com/127.0.0.1#5335 +ipset=/internetofeverything.com/gfwlist +server=/casquebeatssolo.net/127.0.0.1#5335 +ipset=/casquebeatssolo.net/gfwlist +server=/google.pt/127.0.0.1#5335 +ipset=/google.pt/gfwlist +server=/gtlsca.nat.gov.tw/127.0.0.1#5335 +ipset=/gtlsca.nat.gov.tw/gfwlist +server=/fracebook.com/127.0.0.1#5335 +ipset=/fracebook.com/gfwlist +server=/webofknowledge.com/127.0.0.1#5335 +ipset=/webofknowledge.com/gfwlist +server=/sextubespot.com/127.0.0.1#5335 +ipset=/sextubespot.com/gfwlist +server=/applemasters.info/127.0.0.1#5335 +ipset=/applemasters.info/gfwlist +server=/bestbuystores.com/127.0.0.1#5335 +ipset=/bestbuystores.com/gfwlist +server=/nikebetterworld.com/127.0.0.1#5335 +ipset=/nikebetterworld.com/gfwlist +server=/pearsoned.com/127.0.0.1#5335 +ipset=/pearsoned.com/gfwlist +server=/init.shop/127.0.0.1#5335 +ipset=/init.shop/gfwlist +server=/4kporn.xxx/127.0.0.1#5335 +ipset=/4kporn.xxx/gfwlist +server=/1lib.pl/127.0.0.1#5335 +ipset=/1lib.pl/gfwlist +server=/google.nu/127.0.0.1#5335 +ipset=/google.nu/gfwlist +server=/visa.co.cr/127.0.0.1#5335 +ipset=/visa.co.cr/gfwlist +server=/monster-beats-headphones.com/127.0.0.1#5335 +ipset=/monster-beats-headphones.com/gfwlist +server=/videochampion.com/127.0.0.1#5335 +ipset=/videochampion.com/gfwlist +server=/strepsils.hr/127.0.0.1#5335 +ipset=/strepsils.hr/gfwlist +server=/google.nl/127.0.0.1#5335 +ipset=/google.nl/gfwlist +server=/kidspot.com.au/127.0.0.1#5335 +ipset=/kidspot.com.au/gfwlist +server=/gitbook.io/127.0.0.1#5335 +ipset=/gitbook.io/gfwlist +server=/intel.com.ar/127.0.0.1#5335 +ipset=/intel.com.ar/gfwlist +server=/smashed.xxx/127.0.0.1#5335 +ipset=/smashed.xxx/gfwlist +server=/verisign.fr/127.0.0.1#5335 +ipset=/verisign.fr/gfwlist +server=/google.mg/127.0.0.1#5335 +ipset=/google.mg/gfwlist +server=/waterfox.net/127.0.0.1#5335 +ipset=/waterfox.net/gfwlist +server=/javfree.sh/127.0.0.1#5335 +ipset=/javfree.sh/gfwlist +server=/marketo.com/127.0.0.1#5335 +ipset=/marketo.com/gfwlist +server=/onlyindianporn2.com/127.0.0.1#5335 +ipset=/onlyindianporn2.com/gfwlist +server=/disney.com.au/127.0.0.1#5335 +ipset=/disney.com.au/gfwlist +server=/mini.com/127.0.0.1#5335 +ipset=/mini.com/gfwlist +server=/ebay.org/127.0.0.1#5335 +ipset=/ebay.org/gfwlist +server=/thesundaytimes.co.uk/127.0.0.1#5335 +ipset=/thesundaytimes.co.uk/gfwlist +server=/xxvideo.mobi/127.0.0.1#5335 +ipset=/xxvideo.mobi/gfwlist +server=/javqd.com/127.0.0.1#5335 +ipset=/javqd.com/gfwlist +server=/gfpornvideos.com/127.0.0.1#5335 +ipset=/gfpornvideos.com/gfwlist +server=/guccitimeless.com/127.0.0.1#5335 +ipset=/guccitimeless.com/gfwlist +server=/google.kz/127.0.0.1#5335 +ipset=/google.kz/gfwlist +server=/google.ki/127.0.0.1#5335 +ipset=/google.ki/gfwlist +server=/shufflesex.com/127.0.0.1#5335 +ipset=/shufflesex.com/gfwlist +server=/hentaimama.io/127.0.0.1#5335 +ipset=/hentaimama.io/gfwlist +server=/ieeesmc.org/127.0.0.1#5335 +ipset=/ieeesmc.org/gfwlist +server=/google.jo/127.0.0.1#5335 +ipset=/google.jo/gfwlist +server=/beatsbydrecasquesfr.com/127.0.0.1#5335 +ipset=/beatsbydrecasquesfr.com/gfwlist +server=/applestore.com.my/127.0.0.1#5335 +ipset=/applestore.com.my/gfwlist +server=/powerofresolve.ca/127.0.0.1#5335 +ipset=/powerofresolve.ca/gfwlist +server=/google.im/127.0.0.1#5335 +ipset=/google.im/gfwlist +server=/google.ie/127.0.0.1#5335 +ipset=/google.ie/gfwlist +server=/showybeauty.com/127.0.0.1#5335 +ipset=/showybeauty.com/gfwlist +server=/pinterest.ph/127.0.0.1#5335 +ipset=/pinterest.ph/gfwlist +server=/travelex.com/127.0.0.1#5335 +ipset=/travelex.com/gfwlist +server=/bmwccrc.ca/127.0.0.1#5335 +ipset=/bmwccrc.ca/gfwlist +server=/foxsoccer.net/127.0.0.1#5335 +ipset=/foxsoccer.net/gfwlist +server=/google.hr/127.0.0.1#5335 +ipset=/google.hr/gfwlist +server=/visa.co.ve/127.0.0.1#5335 +ipset=/visa.co.ve/gfwlist +server=/google.gl/127.0.0.1#5335 +ipset=/google.gl/gfwlist +server=/anigema.jp/127.0.0.1#5335 +ipset=/anigema.jp/gfwlist +server=/google.gg/127.0.0.1#5335 +ipset=/google.gg/gfwlist +server=/google.ge/127.0.0.1#5335 +ipset=/google.ge/gfwlist +server=/yahoo.dm/127.0.0.1#5335 +ipset=/yahoo.dm/gfwlist +server=/repo.new/127.0.0.1#5335 +ipset=/repo.new/gfwlist +server=/duckduckgo.co/127.0.0.1#5335 +ipset=/duckduckgo.co/gfwlist +server=/softbank-ipo.com/127.0.0.1#5335 +ipset=/softbank-ipo.com/gfwlist +server=/eroero69.work/127.0.0.1#5335 +ipset=/eroero69.work/gfwlist +server=/google.fi/127.0.0.1#5335 +ipset=/google.fi/gfwlist +server=/ebaysocial.com/127.0.0.1#5335 +ipset=/ebaysocial.com/gfwlist +server=/cartoon3thumbs.com/127.0.0.1#5335 +ipset=/cartoon3thumbs.com/gfwlist +server=/pornper.com/127.0.0.1#5335 +ipset=/pornper.com/gfwlist +server=/pearsonclinical.com.br/127.0.0.1#5335 +ipset=/pearsonclinical.com.br/gfwlist +server=/google.es/127.0.0.1#5335 +ipset=/google.es/gfwlist +server=/boyloves.cc/127.0.0.1#5335 +ipset=/boyloves.cc/gfwlist +server=/fbf8.com/127.0.0.1#5335 +ipset=/fbf8.com/gfwlist +server=/automobile.fr/127.0.0.1#5335 +ipset=/automobile.fr/gfwlist +server=/applestore.co.jp/127.0.0.1#5335 +ipset=/applestore.co.jp/gfwlist +server=/similar-porn.fun/127.0.0.1#5335 +ipset=/similar-porn.fun/gfwlist +server=/scat-enema.com/127.0.0.1#5335 +ipset=/scat-enema.com/gfwlist +server=/secom.co.jp/127.0.0.1#5335 +ipset=/secom.co.jp/gfwlist +server=/foxfdm.com/127.0.0.1#5335 +ipset=/foxfdm.com/gfwlist +server=/pornheed.com/127.0.0.1#5335 +ipset=/pornheed.com/gfwlist +server=/bmw-special-sales.com/127.0.0.1#5335 +ipset=/bmw-special-sales.com/gfwlist +server=/google.dj/127.0.0.1#5335 +ipset=/google.dj/gfwlist +server=/skysports.ie/127.0.0.1#5335 +ipset=/skysports.ie/gfwlist +server=/remirepo.net/127.0.0.1#5335 +ipset=/remirepo.net/gfwlist +server=/tubedna.com/127.0.0.1#5335 +ipset=/tubedna.com/gfwlist +server=/myfoxlubbock.com/127.0.0.1#5335 +ipset=/myfoxlubbock.com/gfwlist +server=/acaric.co.jp/127.0.0.1#5335 +ipset=/acaric.co.jp/gfwlist +server=/apple.ch/127.0.0.1#5335 +ipset=/apple.ch/gfwlist +server=/opensource.guide/127.0.0.1#5335 +ipset=/opensource.guide/gfwlist +server=/kindindianporn.com/127.0.0.1#5335 +ipset=/kindindianporn.com/gfwlist +server=/pvp.tv/127.0.0.1#5335 +ipset=/pvp.tv/gfwlist +server=/scholar.google.cl/127.0.0.1#5335 +ipset=/scholar.google.cl/gfwlist +server=/bmw-connecteddrive.hu/127.0.0.1#5335 +ipset=/bmw-connecteddrive.hu/gfwlist +server=/youtube.iq/127.0.0.1#5335 +ipset=/youtube.iq/gfwlist +server=/chomp.com/127.0.0.1#5335 +ipset=/chomp.com/gfwlist +server=/nikefootballcleats.com/127.0.0.1#5335 +ipset=/nikefootballcleats.com/gfwlist +server=/blznav.akamaized.net/127.0.0.1#5335 +ipset=/blznav.akamaized.net/gfwlist +server=/google.com.tr/127.0.0.1#5335 +ipset=/google.com.tr/gfwlist +server=/collegepornonly.com/127.0.0.1#5335 +ipset=/collegepornonly.com/gfwlist +server=/bloombergtradingchallenge.com/127.0.0.1#5335 +ipset=/bloombergtradingchallenge.com/gfwlist +server=/4ertik.one/127.0.0.1#5335 +ipset=/4ertik.one/gfwlist +server=/leagueoflegendsscripts.com/127.0.0.1#5335 +ipset=/leagueoflegendsscripts.com/gfwlist +server=/filmsexeporno.com/127.0.0.1#5335 +ipset=/filmsexeporno.com/gfwlist +server=/bridgestonevan.com/127.0.0.1#5335 +ipset=/bridgestonevan.com/gfwlist +server=/ipod.co.nz/127.0.0.1#5335 +ipset=/ipod.co.nz/gfwlist +server=/teen-lover.net/127.0.0.1#5335 +ipset=/teen-lover.net/gfwlist +server=/facebook.br/127.0.0.1#5335 +ipset=/facebook.br/gfwlist +server=/google.com.pr/127.0.0.1#5335 +ipset=/google.com.pr/gfwlist +server=/sweetandmaxwell.co.uk/127.0.0.1#5335 +ipset=/sweetandmaxwell.co.uk/gfwlist +server=/pinterest.ie/127.0.0.1#5335 +ipset=/pinterest.ie/gfwlist +server=/peachyforum.com/127.0.0.1#5335 +ipset=/peachyforum.com/gfwlist +server=/google.com.pk/127.0.0.1#5335 +ipset=/google.com.pk/gfwlist +server=/google.com.ph/127.0.0.1#5335 +ipset=/google.com.ph/gfwlist +server=/xnxx-teens.com/127.0.0.1#5335 +ipset=/xnxx-teens.com/gfwlist +server=/pornheli.com/127.0.0.1#5335 +ipset=/pornheli.com/gfwlist +server=/google.com.pa/127.0.0.1#5335 +ipset=/google.com.pa/gfwlist +server=/google.com.om/127.0.0.1#5335 +ipset=/google.com.om/gfwlist +server=/google.com.ng/127.0.0.1#5335 +ipset=/google.com.ng/gfwlist +server=/top100sexgames.com/127.0.0.1#5335 +ipset=/top100sexgames.com/gfwlist +server=/horse4sex.com/127.0.0.1#5335 +ipset=/horse4sex.com/gfwlist +server=/ebay.ph/127.0.0.1#5335 +ipset=/ebay.ph/gfwlist +server=/bookmark.xxx/127.0.0.1#5335 +ipset=/bookmark.xxx/gfwlist +server=/ero-manga-platinum.net/127.0.0.1#5335 +ipset=/ero-manga-platinum.net/gfwlist +server=/applecomputer.com.tw/127.0.0.1#5335 +ipset=/applecomputer.com.tw/gfwlist +server=/javdove8.xyz/127.0.0.1#5335 +ipset=/javdove8.xyz/gfwlist +server=/visa.co.id/127.0.0.1#5335 +ipset=/visa.co.id/gfwlist +server=/imoviegallery.com/127.0.0.1#5335 +ipset=/imoviegallery.com/gfwlist +server=/getlantern.org/127.0.0.1#5335 +ipset=/getlantern.org/gfwlist +server=/pleasuregirl.net/127.0.0.1#5335 +ipset=/pleasuregirl.net/gfwlist +server=/macmini.com/127.0.0.1#5335 +ipset=/macmini.com/gfwlist +server=/data.com/127.0.0.1#5335 +ipset=/data.com/gfwlist +server=/google.com.jm/127.0.0.1#5335 +ipset=/google.com.jm/gfwlist +server=/static9.net.au/127.0.0.1#5335 +ipset=/static9.net.au/gfwlist +server=/google.com.gi/127.0.0.1#5335 +ipset=/google.com.gi/gfwlist +server=/iphine.com/127.0.0.1#5335 +ipset=/iphine.com/gfwlist +server=/sexgamesclub.com/127.0.0.1#5335 +ipset=/sexgamesclub.com/gfwlist +server=/graphengine.io/127.0.0.1#5335 +ipset=/graphengine.io/gfwlist +server=/alivevue.com/127.0.0.1#5335 +ipset=/alivevue.com/gfwlist +server=/google.com.fj/127.0.0.1#5335 +ipset=/google.com.fj/gfwlist +server=/zooporno.biz/127.0.0.1#5335 +ipset=/zooporno.biz/gfwlist +server=/needforspeedshowdown.com/127.0.0.1#5335 +ipset=/needforspeedshowdown.com/gfwlist +server=/miniargentina.com/127.0.0.1#5335 +ipset=/miniargentina.com/gfwlist +server=/google.com.et/127.0.0.1#5335 +ipset=/google.com.et/gfwlist +server=/meijinsen.jp/127.0.0.1#5335 +ipset=/meijinsen.jp/gfwlist +server=/volvotrucks.ma/127.0.0.1#5335 +ipset=/volvotrucks.ma/gfwlist +server=/headset987.com/127.0.0.1#5335 +ipset=/headset987.com/gfwlist +server=/attinternetservice.com/127.0.0.1#5335 +ipset=/attinternetservice.com/gfwlist +server=/google.com.ec/127.0.0.1#5335 +ipset=/google.com.ec/gfwlist +server=/mobileinternational.com/127.0.0.1#5335 +ipset=/mobileinternational.com/gfwlist +server=/mini-connected.fr/127.0.0.1#5335 +ipset=/mini-connected.fr/gfwlist +server=/bridgestonecomercial.com.co/127.0.0.1#5335 +ipset=/bridgestonecomercial.com.co/gfwlist +server=/staticflickr.com/127.0.0.1#5335 +ipset=/staticflickr.com/gfwlist +server=/illusion.co.jp/127.0.0.1#5335 +ipset=/illusion.co.jp/gfwlist +server=/hdtube.co/127.0.0.1#5335 +ipset=/hdtube.co/gfwlist +server=/linuxfoundation.org/127.0.0.1#5335 +ipset=/linuxfoundation.org/gfwlist +server=/ciscoturk.net/127.0.0.1#5335 +ipset=/ciscoturk.net/gfwlist +server=/hentaistream.com/127.0.0.1#5335 +ipset=/hentaistream.com/gfwlist +server=/xn--ztsq84g.cn/127.0.0.1#5335 +ipset=/xn--ztsq84g.cn/gfwlist +server=/ladybaba.net/127.0.0.1#5335 +ipset=/ladybaba.net/gfwlist +server=/google.com.co/127.0.0.1#5335 +ipset=/google.com.co/gfwlist +server=/doubleclick.com/127.0.0.1#5335 +ipset=/doubleclick.com/gfwlist +server=/illusionl.com/127.0.0.1#5335 +ipset=/illusionl.com/gfwlist +server=/sbnation.com/127.0.0.1#5335 +ipset=/sbnation.com/gfwlist +server=/outdoorpublicsex.com/127.0.0.1#5335 +ipset=/outdoorpublicsex.com/gfwlist +server=/bmw.com.br/127.0.0.1#5335 +ipset=/bmw.com.br/gfwlist +server=/mox.moe/127.0.0.1#5335 +ipset=/mox.moe/gfwlist +server=/wifi-mx.com/127.0.0.1#5335 +ipset=/wifi-mx.com/gfwlist +server=/rpmfusion.org/127.0.0.1#5335 +ipset=/rpmfusion.org/gfwlist +server=/pornsites.com/127.0.0.1#5335 +ipset=/pornsites.com/gfwlist +server=/eastweek.com.hk/127.0.0.1#5335 +ipset=/eastweek.com.hk/gfwlist +server=/vl4x.net/127.0.0.1#5335 +ipset=/vl4x.net/gfwlist +server=/ouroath.com/127.0.0.1#5335 +ipset=/ouroath.com/gfwlist +server=/google.com.ar/127.0.0.1#5335 +ipset=/google.com.ar/gfwlist +server=/quatrum.com.br/127.0.0.1#5335 +ipset=/quatrum.com.br/gfwlist +server=/cybermondaybeats4sale.com/127.0.0.1#5335 +ipset=/cybermondaybeats4sale.com/gfwlist +server=/clipcake.com/127.0.0.1#5335 +ipset=/clipcake.com/gfwlist +server=/pagecdn.com/127.0.0.1#5335 +ipset=/pagecdn.com/gfwlist +server=/deviantart.net/127.0.0.1#5335 +ipset=/deviantart.net/gfwlist +server=/8teenxxx.com/127.0.0.1#5335 +ipset=/8teenxxx.com/gfwlist +server=/videos-rockstargames-com.akamaized.net/127.0.0.1#5335 +ipset=/videos-rockstargames-com.akamaized.net/gfwlist +server=/google.co.zw/127.0.0.1#5335 +ipset=/google.co.zw/gfwlist +server=/nikegolf.ca/127.0.0.1#5335 +ipset=/nikegolf.ca/gfwlist +server=/egta.com/127.0.0.1#5335 +ipset=/egta.com/gfwlist +server=/dungeonkeeper.com.cn/127.0.0.1#5335 +ipset=/dungeonkeeper.com.cn/gfwlist +server=/coinonecore.com/127.0.0.1#5335 +ipset=/coinonecore.com/gfwlist +server=/google.co.za/127.0.0.1#5335 +ipset=/google.co.za/gfwlist +server=/mini.md/127.0.0.1#5335 +ipset=/mini.md/gfwlist +server=/verizon.net/127.0.0.1#5335 +ipset=/verizon.net/gfwlist +server=/porntube.com/127.0.0.1#5335 +ipset=/porntube.com/gfwlist +server=/google.co.ve/127.0.0.1#5335 +ipset=/google.co.ve/gfwlist +server=/flashtranny.com/127.0.0.1#5335 +ipset=/flashtranny.com/gfwlist +server=/minisovietam.vn/127.0.0.1#5335 +ipset=/minisovietam.vn/gfwlist +server=/google.co.tz/127.0.0.1#5335 +ipset=/google.co.tz/gfwlist +server=/verygoodnike.com/127.0.0.1#5335 +ipset=/verygoodnike.com/gfwlist +server=/google.co.nz/127.0.0.1#5335 +ipset=/google.co.nz/gfwlist +server=/facebookhub.com/127.0.0.1#5335 +ipset=/facebookhub.com/gfwlist +server=/google.co.ls/127.0.0.1#5335 +ipset=/google.co.ls/gfwlist +server=/google.co.kr/127.0.0.1#5335 +ipset=/google.co.kr/gfwlist +server=/paypal-hrsystem.com/127.0.0.1#5335 +ipset=/paypal-hrsystem.com/gfwlist +server=/sexpornimg.com/127.0.0.1#5335 +ipset=/sexpornimg.com/gfwlist +server=/google.com.vn/127.0.0.1#5335 +ipset=/google.com.vn/gfwlist +server=/cloudvolumes.com/127.0.0.1#5335 +ipset=/cloudvolumes.com/gfwlist +server=/geinoueroch.com/127.0.0.1#5335 +ipset=/geinoueroch.com/gfwlist +server=/bloombergmedia.com/127.0.0.1#5335 +ipset=/bloombergmedia.com/gfwlist +server=/thesun.co.uk/127.0.0.1#5335 +ipset=/thesun.co.uk/gfwlist +server=/bokepseks.org/127.0.0.1#5335 +ipset=/bokepseks.org/gfwlist +server=/everia.club/127.0.0.1#5335 +ipset=/everia.club/gfwlist +server=/moxing.mobi/127.0.0.1#5335 +ipset=/moxing.mobi/gfwlist +server=/itaeromanga.com/127.0.0.1#5335 +ipset=/itaeromanga.com/gfwlist +server=/vidspornoduro.com/127.0.0.1#5335 +ipset=/vidspornoduro.com/gfwlist +server=/vfsco.lt/127.0.0.1#5335 +ipset=/vfsco.lt/gfwlist +server=/negoziomonsterbeats.com/127.0.0.1#5335 +ipset=/negoziomonsterbeats.com/gfwlist +server=/pirouvr.com/127.0.0.1#5335 +ipset=/pirouvr.com/gfwlist +server=/xnxx-sex-videos.com/127.0.0.1#5335 +ipset=/xnxx-sex-videos.com/gfwlist +server=/video.fc2.com/127.0.0.1#5335 +ipset=/video.fc2.com/gfwlist +server=/google.cm/127.0.0.1#5335 +ipset=/google.cm/gfwlist +server=/origin.com/127.0.0.1#5335 +ipset=/origin.com/gfwlist +server=/appleid.com/127.0.0.1#5335 +ipset=/appleid.com/gfwlist +server=/monsterproduct.net/127.0.0.1#5335 +ipset=/monsterproduct.net/gfwlist +server=/google.ch/127.0.0.1#5335 +ipset=/google.ch/gfwlist +server=/skyporn.online/127.0.0.1#5335 +ipset=/skyporn.online/gfwlist +server=/babestube.com/127.0.0.1#5335 +ipset=/babestube.com/gfwlist +server=/masturbate2gether.com/127.0.0.1#5335 +ipset=/masturbate2gether.com/gfwlist +server=/7tb.cc/127.0.0.1#5335 +ipset=/7tb.cc/gfwlist +server=/porn-bokep.com/127.0.0.1#5335 +ipset=/porn-bokep.com/gfwlist +server=/moapi1.online/127.0.0.1#5335 +ipset=/moapi1.online/gfwlist +server=/google.cf/127.0.0.1#5335 +ipset=/google.cf/gfwlist +server=/newscareers.co.uk/127.0.0.1#5335 +ipset=/newscareers.co.uk/gfwlist +server=/scholar.google.co.il/127.0.0.1#5335 +ipset=/scholar.google.co.il/gfwlist +server=/google.cd/127.0.0.1#5335 +ipset=/google.cd/gfwlist +server=/redzonechannel.com/127.0.0.1#5335 +ipset=/redzonechannel.com/gfwlist +server=/google.bi/127.0.0.1#5335 +ipset=/google.bi/gfwlist +server=/elpadrote.com/127.0.0.1#5335 +ipset=/elpadrote.com/gfwlist +server=/bridgestone-bandag.com/127.0.0.1#5335 +ipset=/bridgestone-bandag.com/gfwlist +server=/google.ba/127.0.0.1#5335 +ipset=/google.ba/gfwlist +server=/bmwcitychallenge.com/127.0.0.1#5335 +ipset=/bmwcitychallenge.com/gfwlist +server=/meta.com/127.0.0.1#5335 +ipset=/meta.com/gfwlist +server=/illusionn3.com/127.0.0.1#5335 +ipset=/illusionn3.com/gfwlist +server=/dobbyporn.com/127.0.0.1#5335 +ipset=/dobbyporn.com/gfwlist +server=/google.am/127.0.0.1#5335 +ipset=/google.am/gfwlist +server=/shopee.co.th/127.0.0.1#5335 +ipset=/shopee.co.th/gfwlist +server=/facebookck.com/127.0.0.1#5335 +ipset=/facebookck.com/gfwlist +server=/ministeagathe.com/127.0.0.1#5335 +ipset=/ministeagathe.com/gfwlist +server=/google.al/127.0.0.1#5335 +ipset=/google.al/gfwlist +server=/lih.kg/127.0.0.1#5335 +ipset=/lih.kg/gfwlist +server=/google.ad/127.0.0.1#5335 +ipset=/google.ad/gfwlist +server=/travelex.co.jp/127.0.0.1#5335 +ipset=/travelex.co.jp/gfwlist +server=/51pincha.cc/127.0.0.1#5335 +ipset=/51pincha.cc/gfwlist +server=/volvobuses.ph/127.0.0.1#5335 +ipset=/volvobuses.ph/gfwlist +server=/visagiftcard.us/127.0.0.1#5335 +ipset=/visagiftcard.us/gfwlist +server=/starbucks.ph/127.0.0.1#5335 +ipset=/starbucks.ph/gfwlist +server=/mirrorsedge.jp/127.0.0.1#5335 +ipset=/mirrorsedge.jp/gfwlist +server=/ebayheels.com/127.0.0.1#5335 +ipset=/ebayheels.com/gfwlist +server=/douwriteright.com/127.0.0.1#5335 +ipset=/douwriteright.com/gfwlist +server=/fdacebook.info/127.0.0.1#5335 +ipset=/fdacebook.info/gfwlist +server=/nintendonyc.com/127.0.0.1#5335 +ipset=/nintendonyc.com/gfwlist +server=/hentaidirectory.org/127.0.0.1#5335 +ipset=/hentaidirectory.org/gfwlist +server=/r18.clickme.net/127.0.0.1#5335 +ipset=/r18.clickme.net/gfwlist +server=/hnalady.com/127.0.0.1#5335 +ipset=/hnalady.com/gfwlist +server=/svscomics.com/127.0.0.1#5335 +ipset=/svscomics.com/gfwlist +server=/collection-3d.com/127.0.0.1#5335 +ipset=/collection-3d.com/gfwlist +server=/barium-enema.com/127.0.0.1#5335 +ipset=/barium-enema.com/gfwlist +server=/elrepo.org/127.0.0.1#5335 +ipset=/elrepo.org/gfwlist +server=/milfbundle.com/127.0.0.1#5335 +ipset=/milfbundle.com/gfwlist +server=/new.day/127.0.0.1#5335 +ipset=/new.day/gfwlist +server=/gfx.ms/127.0.0.1#5335 +ipset=/gfx.ms/gfwlist +server=/brazzers.com/127.0.0.1#5335 +ipset=/brazzers.com/gfwlist +server=/cougarsexmovies.com/127.0.0.1#5335 +ipset=/cougarsexmovies.com/gfwlist +server=/iam.soy/127.0.0.1#5335 +ipset=/iam.soy/gfwlist +server=/passiontimes.hk/127.0.0.1#5335 +ipset=/passiontimes.hk/gfwlist +server=/hey.boo/127.0.0.1#5335 +ipset=/hey.boo/gfwlist +server=/sony.com.sg/127.0.0.1#5335 +ipset=/sony.com.sg/gfwlist +server=/xoteens.com/127.0.0.1#5335 +ipset=/xoteens.com/gfwlist +server=/youtube.es/127.0.0.1#5335 +ipset=/youtube.es/gfwlist +server=/illianacomputerrecycling.com/127.0.0.1#5335 +ipset=/illianacomputerrecycling.com/gfwlist +server=/yahoo.nu/127.0.0.1#5335 +ipset=/yahoo.nu/gfwlist +server=/apole.com/127.0.0.1#5335 +ipset=/apole.com/gfwlist +server=/visa.ie/127.0.0.1#5335 +ipset=/visa.ie/gfwlist +server=/mini.co.id/127.0.0.1#5335 +ipset=/mini.co.id/gfwlist +server=/zooredtube.com/127.0.0.1#5335 +ipset=/zooredtube.com/gfwlist +server=/fireemblemawakening.com/127.0.0.1#5335 +ipset=/fireemblemawakening.com/gfwlist +server=/easports.jp/127.0.0.1#5335 +ipset=/easports.jp/gfwlist +server=/oxfordartonline.com/127.0.0.1#5335 +ipset=/oxfordartonline.com/gfwlist +server=/finishinfo.com/127.0.0.1#5335 +ipset=/finishinfo.com/gfwlist +server=/durex.nl/127.0.0.1#5335 +ipset=/durex.nl/gfwlist +server=/sfx.ms/127.0.0.1#5335 +ipset=/sfx.ms/gfwlist +server=/telega.one/127.0.0.1#5335 +ipset=/telega.one/gfwlist +server=/googlesyndication.com/127.0.0.1#5335 +ipset=/googlesyndication.com/gfwlist +server=/bigtitsmodelsdirectory.com/127.0.0.1#5335 +ipset=/bigtitsmodelsdirectory.com/gfwlist +server=/cbsaavideo.com/127.0.0.1#5335 +ipset=/cbsaavideo.com/gfwlist +server=/googleadservices.com/127.0.0.1#5335 +ipset=/googleadservices.com/gfwlist +server=/wikisexguide.com/127.0.0.1#5335 +ipset=/wikisexguide.com/gfwlist +server=/esbeatsbydrebuy.com/127.0.0.1#5335 +ipset=/esbeatsbydrebuy.com/gfwlist +server=/google-analytics.com/127.0.0.1#5335 +ipset=/google-analytics.com/gfwlist +server=/happymeal.co.nz/127.0.0.1#5335 +ipset=/happymeal.co.nz/gfwlist +server=/v2ray.com/127.0.0.1#5335 +ipset=/v2ray.com/gfwlist +server=/ragnaporn.com/127.0.0.1#5335 +ipset=/ragnaporn.com/gfwlist +server=/foxrobots.com/127.0.0.1#5335 +ipset=/foxrobots.com/gfwlist +server=/dtci.co/127.0.0.1#5335 +ipset=/dtci.co/gfwlist +server=/blogspot.ro/127.0.0.1#5335 +ipset=/blogspot.ro/gfwlist +server=/bmw-connecteddrive.mx/127.0.0.1#5335 +ipset=/bmw-connecteddrive.mx/gfwlist +server=/bmwmagazine.de/127.0.0.1#5335 +ipset=/bmwmagazine.de/gfwlist +server=/spiritclubs.com/127.0.0.1#5335 +ipset=/spiritclubs.com/gfwlist +server=/adservice.google.com/127.0.0.1#5335 +ipset=/adservice.google.com/gfwlist +server=/mt-ssul1.com/127.0.0.1#5335 +ipset=/mt-ssul1.com/gfwlist +server=/kindleoasis.us/127.0.0.1#5335 +ipset=/kindleoasis.us/gfwlist +server=/bmw-motorrad.de/127.0.0.1#5335 +ipset=/bmw-motorrad.de/gfwlist +server=/applestore.co.ug/127.0.0.1#5335 +ipset=/applestore.co.ug/gfwlist +server=/ntdtv.ca/127.0.0.1#5335 +ipset=/ntdtv.ca/gfwlist +server=/100shmar.net/127.0.0.1#5335 +ipset=/100shmar.net/gfwlist +server=/xxxshame.com/127.0.0.1#5335 +ipset=/xxxshame.com/gfwlist +server=/vox.com/127.0.0.1#5335 +ipset=/vox.com/gfwlist +server=/icloud.org/127.0.0.1#5335 +ipset=/icloud.org/gfwlist +server=/brand-protection-team.com/127.0.0.1#5335 +ipset=/brand-protection-team.com/gfwlist +server=/potenza.jp/127.0.0.1#5335 +ipset=/potenza.jp/gfwlist +server=/pornhuub.xyz/127.0.0.1#5335 +ipset=/pornhuub.xyz/gfwlist +server=/acer-group.com/127.0.0.1#5335 +ipset=/acer-group.com/gfwlist +server=/colorprotechnology.com/127.0.0.1#5335 +ipset=/colorprotechnology.com/gfwlist +server=/disney.de/127.0.0.1#5335 +ipset=/disney.de/gfwlist +server=/porntop.com/127.0.0.1#5335 +ipset=/porntop.com/gfwlist +server=/youav.com/127.0.0.1#5335 +ipset=/youav.com/gfwlist +server=/blackfridaydrebeatsnew.com/127.0.0.1#5335 +ipset=/blackfridaydrebeatsnew.com/gfwlist +server=/monsterheadphone.net/127.0.0.1#5335 +ipset=/monsterheadphone.net/gfwlist +server=/thegeorgiascene.com/127.0.0.1#5335 +ipset=/thegeorgiascene.com/gfwlist +server=/tubemature.tv/127.0.0.1#5335 +ipset=/tubemature.tv/gfwlist +server=/mundomais.com.br/127.0.0.1#5335 +ipset=/mundomais.com.br/gfwlist +server=/tug.org/127.0.0.1#5335 +ipset=/tug.org/gfwlist +server=/blogspot.ru/127.0.0.1#5335 +ipset=/blogspot.ru/gfwlist +server=/graias.com/127.0.0.1#5335 +ipset=/graias.com/gfwlist +server=/businessinsider.in/127.0.0.1#5335 +ipset=/businessinsider.in/gfwlist +server=/blogspot.qa/127.0.0.1#5335 +ipset=/blogspot.qa/gfwlist +server=/milfvr.com/127.0.0.1#5335 +ipset=/milfvr.com/gfwlist +server=/marranazas.com/127.0.0.1#5335 +ipset=/marranazas.com/gfwlist +server=/itunes.co/127.0.0.1#5335 +ipset=/itunes.co/gfwlist +server=/blogspot.mx/127.0.0.1#5335 +ipset=/blogspot.mx/gfwlist +server=/gettyimages.com.au/127.0.0.1#5335 +ipset=/gettyimages.com.au/gfwlist +server=/blogspot.md/127.0.0.1#5335 +ipset=/blogspot.md/gfwlist +server=/shemaleporn.xxx/127.0.0.1#5335 +ipset=/shemaleporn.xxx/gfwlist +server=/virtualrealtrans.com/127.0.0.1#5335 +ipset=/virtualrealtrans.com/gfwlist +server=/nikefree.com/127.0.0.1#5335 +ipset=/nikefree.com/gfwlist +server=/paypal-media.com/127.0.0.1#5335 +ipset=/paypal-media.com/gfwlist +server=/applecare.berlin/127.0.0.1#5335 +ipset=/applecare.berlin/gfwlist +server=/blogspot.li/127.0.0.1#5335 +ipset=/blogspot.li/gfwlist +server=/blogspot.it/127.0.0.1#5335 +ipset=/blogspot.it/gfwlist +server=/beatsbydredanmarks.com/127.0.0.1#5335 +ipset=/beatsbydredanmarks.com/gfwlist +server=/blogspot.in/127.0.0.1#5335 +ipset=/blogspot.in/gfwlist +server=/bmw-motorrad.cz/127.0.0.1#5335 +ipset=/bmw-motorrad.cz/gfwlist +server=/garena.live/127.0.0.1#5335 +ipset=/garena.live/gfwlist +server=/blogspot.hu/127.0.0.1#5335 +ipset=/blogspot.hu/gfwlist +server=/appleiphonecell.com/127.0.0.1#5335 +ipset=/appleiphonecell.com/gfwlist +server=/justporn.link/127.0.0.1#5335 +ipset=/justporn.link/gfwlist +server=/blogspot.gr/127.0.0.1#5335 +ipset=/blogspot.gr/gfwlist +server=/youtube.at/127.0.0.1#5335 +ipset=/youtube.at/gfwlist +server=/blogspot.fr/127.0.0.1#5335 +ipset=/blogspot.fr/gfwlist +server=/newsnowfox.com/127.0.0.1#5335 +ipset=/newsnowfox.com/gfwlist +server=/blogspot.fi/127.0.0.1#5335 +ipset=/blogspot.fi/gfwlist +server=/blogspot.dk/127.0.0.1#5335 +ipset=/blogspot.dk/gfwlist +server=/blogspot.de/127.0.0.1#5335 +ipset=/blogspot.de/gfwlist +server=/pricelessaruba.com/127.0.0.1#5335 +ipset=/pricelessaruba.com/gfwlist +server=/momo5188.com/127.0.0.1#5335 +ipset=/momo5188.com/gfwlist +server=/scholar.google.co.id/127.0.0.1#5335 +ipset=/scholar.google.co.id/gfwlist +server=/nudity911.com/127.0.0.1#5335 +ipset=/nudity911.com/gfwlist +server=/blogspot.com.tr/127.0.0.1#5335 +ipset=/blogspot.com.tr/gfwlist +server=/mofosex.com/127.0.0.1#5335 +ipset=/mofosex.com/gfwlist +server=/bwh88.net/127.0.0.1#5335 +ipset=/bwh88.net/gfwlist +server=/hentaihaven.red/127.0.0.1#5335 +ipset=/hentaihaven.red/gfwlist +server=/duckduckhack.com/127.0.0.1#5335 +ipset=/duckduckhack.com/gfwlist +server=/camsoda1.com/127.0.0.1#5335 +ipset=/camsoda1.com/gfwlist +server=/ninemsn.com.au/127.0.0.1#5335 +ipset=/ninemsn.com.au/gfwlist +server=/visa.dk/127.0.0.1#5335 +ipset=/visa.dk/gfwlist +server=/cc18tv.com/127.0.0.1#5335 +ipset=/cc18tv.com/gfwlist +server=/szwinnertechnology.com/127.0.0.1#5335 +ipset=/szwinnertechnology.com/gfwlist +server=/officialdrdre.com/127.0.0.1#5335 +ipset=/officialdrdre.com/gfwlist +server=/jiuse904.com/127.0.0.1#5335 +ipset=/jiuse904.com/gfwlist +server=/blogspot.com.cy/127.0.0.1#5335 +ipset=/blogspot.com.cy/gfwlist +server=/botorch.org/127.0.0.1#5335 +ipset=/botorch.org/gfwlist +server=/blogspot.com.br/127.0.0.1#5335 +ipset=/blogspot.com.br/gfwlist +server=/capitalgames.com/127.0.0.1#5335 +ipset=/capitalgames.com/gfwlist +server=/nurofen.no/127.0.0.1#5335 +ipset=/nurofen.no/gfwlist +server=/joyourself.com/127.0.0.1#5335 +ipset=/joyourself.com/gfwlist +server=/openapiservice.com/127.0.0.1#5335 +ipset=/openapiservice.com/gfwlist +server=/bannedbook.net/127.0.0.1#5335 +ipset=/bannedbook.net/gfwlist +server=/finish.pt/127.0.0.1#5335 +ipset=/finish.pt/gfwlist +server=/akamaitechnologies.net/127.0.0.1#5335 +ipset=/akamaitechnologies.net/gfwlist +server=/foxdeportes.com/127.0.0.1#5335 +ipset=/foxdeportes.com/gfwlist +server=/lsnzxzy1.com/127.0.0.1#5335 +ipset=/lsnzxzy1.com/gfwlist +server=/asiangirlsnextdoor.com/127.0.0.1#5335 +ipset=/asiangirlsnextdoor.com/gfwlist +server=/petardashd.com.ve/127.0.0.1#5335 +ipset=/petardashd.com.ve/gfwlist +server=/primeday.info/127.0.0.1#5335 +ipset=/primeday.info/gfwlist +server=/beatsbydredealscybermonday.com/127.0.0.1#5335 +ipset=/beatsbydredealscybermonday.com/gfwlist +server=/paypal-prepagata.net/127.0.0.1#5335 +ipset=/paypal-prepagata.net/gfwlist +server=/yale.edu/127.0.0.1#5335 +ipset=/yale.edu/gfwlist +server=/blogspot.am/127.0.0.1#5335 +ipset=/blogspot.am/gfwlist +server=/boobsrealm.com/127.0.0.1#5335 +ipset=/boobsrealm.com/gfwlist +server=/ecoforme.jp/127.0.0.1#5335 +ipset=/ecoforme.jp/gfwlist +server=/igpublish.com/127.0.0.1#5335 +ipset=/igpublish.com/gfwlist +server=/blogspot.ae/127.0.0.1#5335 +ipset=/blogspot.ae/gfwlist +server=/blogger.com/127.0.0.1#5335 +ipset=/blogger.com/gfwlist +server=/comixzilla.com/127.0.0.1#5335 +ipset=/comixzilla.com/gfwlist +server=/macintosh.eu/127.0.0.1#5335 +ipset=/macintosh.eu/gfwlist +server=/gigabyte2.azureedge.net/127.0.0.1#5335 +ipset=/gigabyte2.azureedge.net/gfwlist +server=/jokerlu1.info/127.0.0.1#5335 +ipset=/jokerlu1.info/gfwlist +server=/faronicswise.com/127.0.0.1#5335 +ipset=/faronicswise.com/gfwlist +server=/myclitgames.com/127.0.0.1#5335 +ipset=/myclitgames.com/gfwlist +server=/blogterest.net/127.0.0.1#5335 +ipset=/blogterest.net/gfwlist +server=/nikegrid.com/127.0.0.1#5335 +ipset=/nikegrid.com/gfwlist +server=/etwealth.com/127.0.0.1#5335 +ipset=/etwealth.com/gfwlist +server=/facebookinc.com/127.0.0.1#5335 +ipset=/facebookinc.com/gfwlist +server=/intelatom.net/127.0.0.1#5335 +ipset=/intelatom.net/gfwlist +server=/faronics.com.sg/127.0.0.1#5335 +ipset=/faronics.com.sg/gfwlist +server=/strepsils.com.co/127.0.0.1#5335 +ipset=/strepsils.com.co/gfwlist +server=/faronics.ca/127.0.0.1#5335 +ipset=/faronics.ca/gfwlist +server=/deepfreeze.net/127.0.0.1#5335 +ipset=/deepfreeze.net/gfwlist +server=/volvobuses.ch/127.0.0.1#5335 +ipset=/volvobuses.ch/gfwlist +server=/pornbraze.com/127.0.0.1#5335 +ipset=/pornbraze.com/gfwlist +server=/sci-hub.ee/127.0.0.1#5335 +ipset=/sci-hub.ee/gfwlist +server=/deepfreeze.eu/127.0.0.1#5335 +ipset=/deepfreeze.eu/gfwlist +server=/pornoingyen.hu/127.0.0.1#5335 +ipset=/pornoingyen.hu/gfwlist +server=/nvidia.pl/127.0.0.1#5335 +ipset=/nvidia.pl/gfwlist +server=/techliquidators.com/127.0.0.1#5335 +ipset=/techliquidators.com/gfwlist +server=/lolpcs.com/127.0.0.1#5335 +ipset=/lolpcs.com/gfwlist +server=/mainichi-athletepartners.jp/127.0.0.1#5335 +ipset=/mainichi-athletepartners.jp/gfwlist +server=/disney.com.br/127.0.0.1#5335 +ipset=/disney.com.br/gfwlist +server=/getwsone.com/127.0.0.1#5335 +ipset=/getwsone.com/gfwlist +server=/adultgamescollector.com/127.0.0.1#5335 +ipset=/adultgamescollector.com/gfwlist +server=/beatbd.com/127.0.0.1#5335 +ipset=/beatbd.com/gfwlist +server=/account-paypal.org/127.0.0.1#5335 +ipset=/account-paypal.org/gfwlist +server=/volvotrucks.co.il/127.0.0.1#5335 +ipset=/volvotrucks.co.il/gfwlist +server=/limertw.cc/127.0.0.1#5335 +ipset=/limertw.cc/gfwlist +server=/air-watch.com/127.0.0.1#5335 +ipset=/air-watch.com/gfwlist +server=/vsphere.net/127.0.0.1#5335 +ipset=/vsphere.net/gfwlist +server=/nfscdict.com/127.0.0.1#5335 +ipset=/nfscdict.com/gfwlist +server=/rakuya.com.tw/127.0.0.1#5335 +ipset=/rakuya.com.tw/gfwlist +server=/fox23maine.com/127.0.0.1#5335 +ipset=/fox23maine.com/gfwlist +server=/vsphere.com/127.0.0.1#5335 +ipset=/vsphere.com/gfwlist +server=/hyper.is/127.0.0.1#5335 +ipset=/hyper.is/gfwlist +server=/ghcr.io/127.0.0.1#5335 +ipset=/ghcr.io/gfwlist +server=/bmw.com.tr/127.0.0.1#5335 +ipset=/bmw.com.tr/gfwlist +server=/physiology.org/127.0.0.1#5335 +ipset=/physiology.org/gfwlist +server=/xbahis33.com/127.0.0.1#5335 +ipset=/xbahis33.com/gfwlist +server=/disney.cz/127.0.0.1#5335 +ipset=/disney.cz/gfwlist +server=/hentaicore.org/127.0.0.1#5335 +ipset=/hentaicore.org/gfwlist +server=/erofights.com/127.0.0.1#5335 +ipset=/erofights.com/gfwlist +server=/rakuten.ne.jp/127.0.0.1#5335 +ipset=/rakuten.ne.jp/gfwlist +server=/beatsbydrdre-officials5.com/127.0.0.1#5335 +ipset=/beatsbydrdre-officials5.com/gfwlist +server=/dombosco.com.br/127.0.0.1#5335 +ipset=/dombosco.com.br/gfwlist +server=/livesexasian.com/127.0.0.1#5335 +ipset=/livesexasian.com/gfwlist +server=/100classicbooks.com/127.0.0.1#5335 +ipset=/100classicbooks.com/gfwlist +server=/yahoo.com.na/127.0.0.1#5335 +ipset=/yahoo.com.na/gfwlist +server=/cloudhealthtech.com/127.0.0.1#5335 +ipset=/cloudhealthtech.com/gfwlist +server=/cloudcredibility.com/127.0.0.1#5335 +ipset=/cloudcredibility.com/gfwlist +server=/visa.de/127.0.0.1#5335 +ipset=/visa.de/gfwlist +server=/dockerizer.com/127.0.0.1#5335 +ipset=/dockerizer.com/gfwlist +server=/bitnamistudio.com/127.0.0.1#5335 +ipset=/bitnamistudio.com/gfwlist +server=/nikechosen.com/127.0.0.1#5335 +ipset=/nikechosen.com/gfwlist +server=/drkogyi.com/127.0.0.1#5335 +ipset=/drkogyi.com/gfwlist +server=/corporatecashpassport.com/127.0.0.1#5335 +ipset=/corporatecashpassport.com/gfwlist +server=/illusionh.com/127.0.0.1#5335 +ipset=/illusionh.com/gfwlist +server=/youtube.com.pa/127.0.0.1#5335 +ipset=/youtube.com.pa/gfwlist +server=/bitnami.com/127.0.0.1#5335 +ipset=/bitnami.com/gfwlist +server=/2kcoretech.online/127.0.0.1#5335 +ipset=/2kcoretech.online/gfwlist +server=/disneymagicmoments.es/127.0.0.1#5335 +ipset=/disneymagicmoments.es/gfwlist +server=/cosplayworld.net/127.0.0.1#5335 +ipset=/cosplayworld.net/gfwlist +server=/nginxconfig.io/127.0.0.1#5335 +ipset=/nginxconfig.io/gfwlist +server=/workspaceair.com/127.0.0.1#5335 +ipset=/workspaceair.com/gfwlist +server=/oranum.com/127.0.0.1#5335 +ipset=/oranum.com/gfwlist +server=/cashback69.com/127.0.0.1#5335 +ipset=/cashback69.com/gfwlist +server=/fox5ny.com/127.0.0.1#5335 +ipset=/fox5ny.com/gfwlist +server=/legsex.com/127.0.0.1#5335 +ipset=/legsex.com/gfwlist +server=/ikea.bh/127.0.0.1#5335 +ipset=/ikea.bh/gfwlist +server=/oculusrift.com/127.0.0.1#5335 +ipset=/oculusrift.com/gfwlist +server=/fffucked.com/127.0.0.1#5335 +ipset=/fffucked.com/gfwlist +server=/animalsporn.net/127.0.0.1#5335 +ipset=/animalsporn.net/gfwlist +server=/sony-africa.com/127.0.0.1#5335 +ipset=/sony-africa.com/gfwlist +server=/ncl.edu.tw/127.0.0.1#5335 +ipset=/ncl.edu.tw/gfwlist +server=/tabootube.xxx/127.0.0.1#5335 +ipset=/tabootube.xxx/gfwlist +server=/bloombergchina.com/127.0.0.1#5335 +ipset=/bloombergchina.com/gfwlist +server=/binancezh.net/127.0.0.1#5335 +ipset=/binancezh.net/gfwlist +server=/whychoosehorizon.com/127.0.0.1#5335 +ipset=/whychoosehorizon.com/gfwlist +server=/vmwservices.com/127.0.0.1#5335 +ipset=/vmwservices.com/gfwlist +server=/ebayshop111.com/127.0.0.1#5335 +ipset=/ebayshop111.com/gfwlist +server=/t21.nikkei.co.jp/127.0.0.1#5335 +ipset=/t21.nikkei.co.jp/gfwlist +server=/buyaple.com/127.0.0.1#5335 +ipset=/buyaple.com/gfwlist +server=/12diasdepresentesdeitunes.com/127.0.0.1#5335 +ipset=/12diasdepresentesdeitunes.com/gfwlist +server=/5mo.fun/127.0.0.1#5335 +ipset=/5mo.fun/gfwlist +server=/line.naver.jp/127.0.0.1#5335 +ipset=/line.naver.jp/gfwlist +server=/socialmediagirls.com/127.0.0.1#5335 +ipset=/socialmediagirls.com/gfwlist +server=/bmwcenternet.com/127.0.0.1#5335 +ipset=/bmwcenternet.com/gfwlist +server=/amazondevicesupport.com/127.0.0.1#5335 +ipset=/amazondevicesupport.com/gfwlist +server=/rclon.com/127.0.0.1#5335 +ipset=/rclon.com/gfwlist +server=/ikea.ma/127.0.0.1#5335 +ipset=/ikea.ma/gfwlist +server=/bmw-mdrivetour.com/127.0.0.1#5335 +ipset=/bmw-mdrivetour.com/gfwlist +server=/vmwlearningplatform.com/127.0.0.1#5335 +ipset=/vmwlearningplatform.com/gfwlist +server=/tteshop.com/127.0.0.1#5335 +ipset=/tteshop.com/gfwlist +server=/stateofthemap.com/127.0.0.1#5335 +ipset=/stateofthemap.com/gfwlist +server=/scatsite.com/127.0.0.1#5335 +ipset=/scatsite.com/gfwlist +server=/prodrive-japan.com/127.0.0.1#5335 +ipset=/prodrive-japan.com/gfwlist +server=/thomsonreuters.in/127.0.0.1#5335 +ipset=/thomsonreuters.in/gfwlist +server=/visa.co.ni/127.0.0.1#5335 +ipset=/visa.co.ni/gfwlist +server=/ikea.com.in/127.0.0.1#5335 +ipset=/ikea.com.in/gfwlist +server=/placemyad.com.au/127.0.0.1#5335 +ipset=/placemyad.com.au/gfwlist +server=/vmwarelearningplatform.com/127.0.0.1#5335 +ipset=/vmwarelearningplatform.com/gfwlist +server=/samsungcloud.com/127.0.0.1#5335 +ipset=/samsungcloud.com/gfwlist +server=/paypal-comunidad.com/127.0.0.1#5335 +ipset=/paypal-comunidad.com/gfwlist +server=/appleoriginalproductions.com/127.0.0.1#5335 +ipset=/appleoriginalproductions.com/gfwlist +server=/mirrorsedge.net/127.0.0.1#5335 +ipset=/mirrorsedge.net/gfwlist +server=/carcare-and-tireshop.jp/127.0.0.1#5335 +ipset=/carcare-and-tireshop.jp/gfwlist +server=/vmwaregrid.com/127.0.0.1#5335 +ipset=/vmwaregrid.com/gfwlist +server=/facebookbrand.net/127.0.0.1#5335 +ipset=/facebookbrand.net/gfwlist +server=/foxsoccer.tv/127.0.0.1#5335 +ipset=/foxsoccer.tv/gfwlist +server=/clubseventeen.com/127.0.0.1#5335 +ipset=/clubseventeen.com/gfwlist +server=/vmwaredemandcenter.com/127.0.0.1#5335 +ipset=/vmwaredemandcenter.com/gfwlist +server=/yande.re/127.0.0.1#5335 +ipset=/yande.re/gfwlist +server=/cindymovies.com/127.0.0.1#5335 +ipset=/cindymovies.com/gfwlist +server=/applefinalcutproworld.com/127.0.0.1#5335 +ipset=/applefinalcutproworld.com/gfwlist +server=/camfox.com/127.0.0.1#5335 +ipset=/camfox.com/gfwlist +server=/vmwareausnews.com/127.0.0.1#5335 +ipset=/vmwareausnews.com/gfwlist +server=/verisign.de/127.0.0.1#5335 +ipset=/verisign.de/gfwlist +server=/yahoo.ps/127.0.0.1#5335 +ipset=/yahoo.ps/gfwlist +server=/bamtoki.com/127.0.0.1#5335 +ipset=/bamtoki.com/gfwlist +server=/dlercloud.org/127.0.0.1#5335 +ipset=/dlercloud.org/gfwlist +server=/akamai-staging.net/127.0.0.1#5335 +ipset=/akamai-staging.net/gfwlist +server=/viet69.link/127.0.0.1#5335 +ipset=/viet69.link/gfwlist +server=/microsofttranslator.com/127.0.0.1#5335 +ipset=/microsofttranslator.com/gfwlist +server=/softbankrobotics.com/127.0.0.1#5335 +ipset=/softbankrobotics.com/gfwlist +server=/vmware-cloudmanagement.com/127.0.0.1#5335 +ipset=/vmware-cloudmanagement.com/gfwlist +server=/babesofindia.com/127.0.0.1#5335 +ipset=/babesofindia.com/gfwlist +server=/vmmark.com/127.0.0.1#5335 +ipset=/vmmark.com/gfwlist +server=/business-i.jp/127.0.0.1#5335 +ipset=/business-i.jp/gfwlist +server=/facebook30.com/127.0.0.1#5335 +ipset=/facebook30.com/gfwlist +server=/enemaexperiences.com/127.0.0.1#5335 +ipset=/enemaexperiences.com/gfwlist +server=/vmglobal.net/127.0.0.1#5335 +ipset=/vmglobal.net/gfwlist +server=/vfabric.net/127.0.0.1#5335 +ipset=/vfabric.net/gfwlist +server=/maxgo.com/127.0.0.1#5335 +ipset=/maxgo.com/gfwlist +server=/termux.com/127.0.0.1#5335 +ipset=/termux.com/gfwlist +server=/vcanedge.com/127.0.0.1#5335 +ipset=/vcanedge.com/gfwlist +server=/ssdevrd.com/127.0.0.1#5335 +ipset=/ssdevrd.com/gfwlist +server=/blackamateursvideos.com/127.0.0.1#5335 +ipset=/blackamateursvideos.com/gfwlist +server=/bmwusfactory.com/127.0.0.1#5335 +ipset=/bmwusfactory.com/gfwlist +server=/youtube.bo/127.0.0.1#5335 +ipset=/youtube.bo/gfwlist +server=/drdre-beats.com/127.0.0.1#5335 +ipset=/drdre-beats.com/gfwlist +server=/electbabe.com/127.0.0.1#5335 +ipset=/electbabe.com/gfwlist +server=/klik.me/127.0.0.1#5335 +ipset=/klik.me/gfwlist +server=/hwslabs.com/127.0.0.1#5335 +ipset=/hwslabs.com/gfwlist +server=/greenplum.net/127.0.0.1#5335 +ipset=/greenplum.net/gfwlist +server=/beatsbydre-club.com/127.0.0.1#5335 +ipset=/beatsbydre-club.com/gfwlist +server=/cisconetapp.com/127.0.0.1#5335 +ipset=/cisconetapp.com/gfwlist +server=/gelbooru.wjcodes.com/127.0.0.1#5335 +ipset=/gelbooru.wjcodes.com/gfwlist +server=/eliteindianporn.com/127.0.0.1#5335 +ipset=/eliteindianporn.com/gfwlist +server=/hochi.news/127.0.0.1#5335 +ipset=/hochi.news/gfwlist +server=/hentairead.info/127.0.0.1#5335 +ipset=/hentairead.info/gfwlist +server=/youngmommyfucksme.com/127.0.0.1#5335 +ipset=/youngmommyfucksme.com/gfwlist +server=/rarbgunblock.org/127.0.0.1#5335 +ipset=/rarbgunblock.org/gfwlist +server=/cpedge.com/127.0.0.1#5335 +ipset=/cpedge.com/gfwlist +server=/bollywoodlife.com/127.0.0.1#5335 +ipset=/bollywoodlife.com/gfwlist +server=/pornhubapparel.com/127.0.0.1#5335 +ipset=/pornhubapparel.com/gfwlist +server=/rolls-roycemotorcars.com/127.0.0.1#5335 +ipset=/rolls-roycemotorcars.com/gfwlist +server=/archiveofourown.org/127.0.0.1#5335 +ipset=/archiveofourown.org/gfwlist +server=/bookmybridgestonetyre.com/127.0.0.1#5335 +ipset=/bookmybridgestonetyre.com/gfwlist +server=/cfblob.com/127.0.0.1#5335 +ipset=/cfblob.com/gfwlist +server=/costco-static.com/127.0.0.1#5335 +ipset=/costco-static.com/gfwlist +server=/duckduckgo.pl/127.0.0.1#5335 +ipset=/duckduckgo.pl/gfwlist +server=/filmeleporno.xxx/127.0.0.1#5335 +ipset=/filmeleporno.xxx/gfwlist +server=/monsterbeatssales.com/127.0.0.1#5335 +ipset=/monsterbeatssales.com/gfwlist +server=/4cdn.org/127.0.0.1#5335 +ipset=/4cdn.org/gfwlist +server=/akamai.co.kr/127.0.0.1#5335 +ipset=/akamai.co.kr/gfwlist +server=/telegram.dog/127.0.0.1#5335 +ipset=/telegram.dog/gfwlist +server=/collabora.co.uk/127.0.0.1#5335 +ipset=/collabora.co.uk/gfwlist +server=/cloudcone.net/127.0.0.1#5335 +ipset=/cloudcone.net/gfwlist +server=/besthentaitube.com/127.0.0.1#5335 +ipset=/besthentaitube.com/gfwlist +server=/cnyes.com/127.0.0.1#5335 +ipset=/cnyes.com/gfwlist +server=/cloudcone.com/127.0.0.1#5335 +ipset=/cloudcone.com/gfwlist +server=/ikea.is/127.0.0.1#5335 +ipset=/ikea.is/gfwlist +server=/aweencore.com/127.0.0.1#5335 +ipset=/aweencore.com/gfwlist +server=/melonstube.com/127.0.0.1#5335 +ipset=/melonstube.com/gfwlist +server=/jilhub.com/127.0.0.1#5335 +ipset=/jilhub.com/gfwlist +server=/armovs.com/127.0.0.1#5335 +ipset=/armovs.com/gfwlist +server=/hitxhot.com/127.0.0.1#5335 +ipset=/hitxhot.com/gfwlist +server=/cisco.evergage.com/127.0.0.1#5335 +ipset=/cisco.evergage.com/gfwlist +server=/nikeshoesgroup.com/127.0.0.1#5335 +ipset=/nikeshoesgroup.com/gfwlist +server=/tettediferro.it/127.0.0.1#5335 +ipset=/tettediferro.it/gfwlist +server=/tailf.com/127.0.0.1#5335 +ipset=/tailf.com/gfwlist +server=/hindawi.com/127.0.0.1#5335 +ipset=/hindawi.com/gfwlist +server=/thomsonreuters.com.hk/127.0.0.1#5335 +ipset=/thomsonreuters.com.hk/gfwlist +server=/thecamdude.com/127.0.0.1#5335 +ipset=/thecamdude.com/gfwlist +server=/wet-ass-pussy.com/127.0.0.1#5335 +ipset=/wet-ass-pussy.com/gfwlist +server=/toplayerserver.com/127.0.0.1#5335 +ipset=/toplayerserver.com/gfwlist +server=/appdynamics.org/127.0.0.1#5335 +ipset=/appdynamics.org/gfwlist +server=/dmm.co.jp/127.0.0.1#5335 +ipset=/dmm.co.jp/gfwlist +server=/climateone.blogspot.co.id/127.0.0.1#5335 +ipset=/climateone.blogspot.co.id/gfwlist +server=/appdynamics.jp/127.0.0.1#5335 +ipset=/appdynamics.jp/gfwlist +server=/foxandfriends.com/127.0.0.1#5335 +ipset=/foxandfriends.com/gfwlist +server=/beatsbydre-sell.com/127.0.0.1#5335 +ipset=/beatsbydre-sell.com/gfwlist +server=/appdynamics.co.uk/127.0.0.1#5335 +ipset=/appdynamics.co.uk/gfwlist +server=/rule34.asia/127.0.0.1#5335 +ipset=/rule34.asia/gfwlist +server=/facebookcom.com/127.0.0.1#5335 +ipset=/facebookcom.com/gfwlist +server=/konachan.wjcodes.com/127.0.0.1#5335 +ipset=/konachan.wjcodes.com/gfwlist +server=/nytco.com/127.0.0.1#5335 +ipset=/nytco.com/gfwlist +server=/boylove.cc/127.0.0.1#5335 +ipset=/boylove.cc/gfwlist +server=/elite.com/127.0.0.1#5335 +ipset=/elite.com/gfwlist +server=/vfsco.pe/127.0.0.1#5335 +ipset=/vfsco.pe/gfwlist +server=/bcovlive-a.akamaihd.net/127.0.0.1#5335 +ipset=/bcovlive-a.akamaihd.net/gfwlist +server=/virtuata.com/127.0.0.1#5335 +ipset=/virtuata.com/gfwlist +server=/ssl.com/127.0.0.1#5335 +ipset=/ssl.com/gfwlist +server=/ciscoinvestments.com/127.0.0.1#5335 +ipset=/ciscoinvestments.com/gfwlist +server=/worldofwarcraft.com/127.0.0.1#5335 +ipset=/worldofwarcraft.com/gfwlist +server=/versly.com/127.0.0.1#5335 +ipset=/versly.com/gfwlist +server=/cowboom.com/127.0.0.1#5335 +ipset=/cowboom.com/gfwlist +server=/accountpaypal.com/127.0.0.1#5335 +ipset=/accountpaypal.com/gfwlist +server=/tandberg-china.com/127.0.0.1#5335 +ipset=/tandberg-china.com/gfwlist +server=/myfoxtampa.com/127.0.0.1#5335 +ipset=/myfoxtampa.com/gfwlist +server=/hoyolab.com/127.0.0.1#5335 +ipset=/hoyolab.com/gfwlist +server=/nintendo.no/127.0.0.1#5335 +ipset=/nintendo.no/gfwlist +server=/mornporn.com/127.0.0.1#5335 +ipset=/mornporn.com/gfwlist +server=/regiongold.com/127.0.0.1#5335 +ipset=/regiongold.com/gfwlist +server=/parstream.org/127.0.0.1#5335 +ipset=/parstream.org/gfwlist +server=/top100nl.net/127.0.0.1#5335 +ipset=/top100nl.net/gfwlist +server=/greatfire.org/127.0.0.1#5335 +ipset=/greatfire.org/gfwlist +server=/free-sns.com/127.0.0.1#5335 +ipset=/free-sns.com/gfwlist +server=/camelspaceeffect.com/127.0.0.1#5335 +ipset=/camelspaceeffect.com/gfwlist +server=/githubusercontent.com/127.0.0.1#5335 +ipset=/githubusercontent.com/gfwlist +server=/obsrvbl.com/127.0.0.1#5335 +ipset=/obsrvbl.com/gfwlist +server=/allporncomic.com/127.0.0.1#5335 +ipset=/allporncomic.com/gfwlist +server=/netacad.com/127.0.0.1#5335 +ipset=/netacad.com/gfwlist +server=/cloudflare.com/127.0.0.1#5335 +ipset=/cloudflare.com/gfwlist +server=/mysdn.info/127.0.0.1#5335 +ipset=/mysdn.info/gfwlist +server=/zoofiction.com/127.0.0.1#5335 +ipset=/zoofiction.com/gfwlist +server=/mysdn.com/127.0.0.1#5335 +ipset=/mysdn.com/gfwlist +server=/myciscobenefits.com/127.0.0.1#5335 +ipset=/myciscobenefits.com/gfwlist +server=/multiplydiversity.com/127.0.0.1#5335 +ipset=/multiplydiversity.com/gfwlist +server=/adultgames.games/127.0.0.1#5335 +ipset=/adultgames.games/gfwlist +server=/securepaypal.info/127.0.0.1#5335 +ipset=/securepaypal.info/gfwlist +server=/beatsbydrefriday.com/127.0.0.1#5335 +ipset=/beatsbydrefriday.com/gfwlist +server=/bmw-motorrad.ch/127.0.0.1#5335 +ipset=/bmw-motorrad.ch/gfwlist +server=/onlyams.com/127.0.0.1#5335 +ipset=/onlyams.com/gfwlist +server=/matters.news/127.0.0.1#5335 +ipset=/matters.news/gfwlist +server=/facebookdevelopergarage.com/127.0.0.1#5335 +ipset=/facebookdevelopergarage.com/gfwlist +server=/scholar.google.it/127.0.0.1#5335 +ipset=/scholar.google.it/gfwlist +server=/gpstheseries.com/127.0.0.1#5335 +ipset=/gpstheseries.com/gfwlist +server=/devm2m.com/127.0.0.1#5335 +ipset=/devm2m.com/gfwlist +server=/xxxdinotube.com/127.0.0.1#5335 +ipset=/xxxdinotube.com/gfwlist +server=/careerfundas.com/127.0.0.1#5335 +ipset=/careerfundas.com/gfwlist +server=/badsexygirl.com/127.0.0.1#5335 +ipset=/badsexygirl.com/gfwlist +server=/coreoptics.net/127.0.0.1#5335 +ipset=/coreoptics.net/gfwlist +server=/managedpki.ne.jp/127.0.0.1#5335 +ipset=/managedpki.ne.jp/gfwlist +server=/beatthatquote.com/127.0.0.1#5335 +ipset=/beatthatquote.com/gfwlist +server=/foxnewshealth.com/127.0.0.1#5335 +ipset=/foxnewshealth.com/gfwlist +server=/connect-in-canada.com/127.0.0.1#5335 +ipset=/connect-in-canada.com/gfwlist +server=/celebritygay.com/127.0.0.1#5335 +ipset=/celebritygay.com/gfwlist +server=/mdialog.com/127.0.0.1#5335 +ipset=/mdialog.com/gfwlist +server=/seancody.com/127.0.0.1#5335 +ipset=/seancody.com/gfwlist +server=/ciscovideo.com/127.0.0.1#5335 +ipset=/ciscovideo.com/gfwlist +server=/ciscotaccc.com/127.0.0.1#5335 +ipset=/ciscotaccc.com/gfwlist +server=/psiphon3.com/127.0.0.1#5335 +ipset=/psiphon3.com/gfwlist +server=/ciscospark.jp/127.0.0.1#5335 +ipset=/ciscospark.jp/gfwlist +server=/dutrai.com/127.0.0.1#5335 +ipset=/dutrai.com/gfwlist +server=/severreal.org/127.0.0.1#5335 +ipset=/severreal.org/gfwlist +server=/mini.co.me/127.0.0.1#5335 +ipset=/mini.co.me/gfwlist +server=/bmw-oman.com/127.0.0.1#5335 +ipset=/bmw-oman.com/gfwlist +server=/acheterdesfollowersinstagram.com/127.0.0.1#5335 +ipset=/acheterdesfollowersinstagram.com/gfwlist +server=/beatsdresale2013.com/127.0.0.1#5335 +ipset=/beatsdresale2013.com/gfwlist +server=/fbwat.ch/127.0.0.1#5335 +ipset=/fbwat.ch/gfwlist +server=/volvotrucks.it/127.0.0.1#5335 +ipset=/volvotrucks.it/gfwlist +server=/sex-teen.net/127.0.0.1#5335 +ipset=/sex-teen.net/gfwlist +server=/ciscoprice.com/127.0.0.1#5335 +ipset=/ciscoprice.com/gfwlist +server=/gfrevenge.com/127.0.0.1#5335 +ipset=/gfrevenge.com/gfwlist +server=/ciscopowercube.com/127.0.0.1#5335 +ipset=/ciscopowercube.com/gfwlist +server=/cisconetspace.net/127.0.0.1#5335 +ipset=/cisconetspace.net/gfwlist +server=/cisconetspace.com/127.0.0.1#5335 +ipset=/cisconetspace.com/gfwlist +server=/ciscolearningsystem.com/127.0.0.1#5335 +ipset=/ciscolearningsystem.com/gfwlist +server=/horsedick.net/127.0.0.1#5335 +ipset=/horsedick.net/gfwlist +server=/mol.im/127.0.0.1#5335 +ipset=/mol.im/gfwlist +server=/mastercardidtheftalerts.com/127.0.0.1#5335 +ipset=/mastercardidtheftalerts.com/gfwlist +server=/777xporn.com/127.0.0.1#5335 +ipset=/777xporn.com/gfwlist +server=/ciscoerate.com/127.0.0.1#5335 +ipset=/ciscoerate.com/gfwlist +server=/ciscoconnectcloud.org/127.0.0.1#5335 +ipset=/ciscoconnectcloud.org/gfwlist +server=/ciscoconnectcloud.net/127.0.0.1#5335 +ipset=/ciscoconnectcloud.net/gfwlist +server=/myporngay.com/127.0.0.1#5335 +ipset=/myporngay.com/gfwlist +server=/ciscoccservice.com/127.0.0.1#5335 +ipset=/ciscoccservice.com/gfwlist +server=/twitchcdn.net/127.0.0.1#5335 +ipset=/twitchcdn.net/gfwlist +server=/airav.cc/127.0.0.1#5335 +ipset=/airav.cc/gfwlist +server=/tssp.best/127.0.0.1#5335 +ipset=/tssp.best/gfwlist +server=/cdnlab.live/127.0.0.1#5335 +ipset=/cdnlab.live/gfwlist +server=/barrons-advisor.com/127.0.0.1#5335 +ipset=/barrons-advisor.com/gfwlist +server=/beatsheadphonesale.com/127.0.0.1#5335 +ipset=/beatsheadphonesale.com/gfwlist +server=/cciesecuritylabs.com/127.0.0.1#5335 +ipset=/cciesecuritylabs.com/gfwlist +server=/disneynewseries.com/127.0.0.1#5335 +ipset=/disneynewseries.com/gfwlist +server=/pornodoido.com/127.0.0.1#5335 +ipset=/pornodoido.com/gfwlist +server=/cciernslabs.com/127.0.0.1#5335 +ipset=/cciernslabs.com/gfwlist +server=/academynetriders.com/127.0.0.1#5335 +ipset=/academynetriders.com/gfwlist +server=/volvotrucks.com.co/127.0.0.1#5335 +ipset=/volvotrucks.com.co/gfwlist +server=/dierectv.com/127.0.0.1#5335 +ipset=/dierectv.com/gfwlist +server=/webex.com.br/127.0.0.1#5335 +ipset=/webex.com.br/gfwlist +server=/discord.gift/127.0.0.1#5335 +ipset=/discord.gift/gfwlist +server=/evgld7cg58l8.com/127.0.0.1#5335 +ipset=/evgld7cg58l8.com/gfwlist +server=/womensnikeshox.com/127.0.0.1#5335 +ipset=/womensnikeshox.com/gfwlist +server=/bmw-security-vehicles.com/127.0.0.1#5335 +ipset=/bmw-security-vehicles.com/gfwlist +server=/beatsbydre-outletstore.com/127.0.0.1#5335 +ipset=/beatsbydre-outletstore.com/gfwlist +server=/finish.at/127.0.0.1#5335 +ipset=/finish.at/gfwlist +server=/shemalez.com/127.0.0.1#5335 +ipset=/shemalez.com/gfwlist +server=/webex.co.jp/127.0.0.1#5335 +ipset=/webex.co.jp/gfwlist +server=/webex.co.it/127.0.0.1#5335 +ipset=/webex.co.it/gfwlist +server=/as-dash-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/as-dash-uk-live.akamaized.net/gfwlist +server=/webex.co.in/127.0.0.1#5335 +ipset=/webex.co.in/gfwlist +server=/faceebot.com/127.0.0.1#5335 +ipset=/faceebot.com/gfwlist +server=/instagainer.com/127.0.0.1#5335 +ipset=/instagainer.com/gfwlist +server=/platinumlinks.org/127.0.0.1#5335 +ipset=/platinumlinks.org/gfwlist +server=/hp.company/127.0.0.1#5335 +ipset=/hp.company/gfwlist +server=/vpejey.xyz/127.0.0.1#5335 +ipset=/vpejey.xyz/gfwlist +server=/tradevip1.com/127.0.0.1#5335 +ipset=/tradevip1.com/gfwlist +server=/canon.si/127.0.0.1#5335 +ipset=/canon.si/gfwlist +server=/uux68.com/127.0.0.1#5335 +ipset=/uux68.com/gfwlist +server=/papermc.io/127.0.0.1#5335 +ipset=/papermc.io/gfwlist +server=/blizzak-juken.jp/127.0.0.1#5335 +ipset=/blizzak-juken.jp/gfwlist +server=/xvirtual.com/127.0.0.1#5335 +ipset=/xvirtual.com/gfwlist +server=/foxinc.com/127.0.0.1#5335 +ipset=/foxinc.com/gfwlist +server=/free-avx.jp/127.0.0.1#5335 +ipset=/free-avx.jp/gfwlist +server=/nintendo.se/127.0.0.1#5335 +ipset=/nintendo.se/gfwlist +server=/hentai-gamer.com/127.0.0.1#5335 +ipset=/hentai-gamer.com/gfwlist +server=/appstore.co.id/127.0.0.1#5335 +ipset=/appstore.co.id/gfwlist +server=/newsukadops.com/127.0.0.1#5335 +ipset=/newsukadops.com/gfwlist +server=/akamaitech.com/127.0.0.1#5335 +ipset=/akamaitech.com/gfwlist +server=/applehealth.com.hk/127.0.0.1#5335 +ipset=/applehealth.com.hk/gfwlist +server=/canon.no/127.0.0.1#5335 +ipset=/canon.no/gfwlist +server=/wiisportsresort.com/127.0.0.1#5335 +ipset=/wiisportsresort.com/gfwlist +server=/nverxs.xyz/127.0.0.1#5335 +ipset=/nverxs.xyz/gfwlist +server=/binancezh.com/127.0.0.1#5335 +ipset=/binancezh.com/gfwlist +server=/visadigital.com/127.0.0.1#5335 +ipset=/visadigital.com/gfwlist +server=/riotpin.com/127.0.0.1#5335 +ipset=/riotpin.com/gfwlist +server=/canon.it/127.0.0.1#5335 +ipset=/canon.it/gfwlist +server=/google.dz/127.0.0.1#5335 +ipset=/google.dz/gfwlist +server=/canon.ie/127.0.0.1#5335 +ipset=/canon.ie/gfwlist +server=/adobetcstrialdvd.com/127.0.0.1#5335 +ipset=/adobetcstrialdvd.com/gfwlist +server=/nfscofficial.com/127.0.0.1#5335 +ipset=/nfscofficial.com/gfwlist +server=/monsterbeats8beatsbydre.com/127.0.0.1#5335 +ipset=/monsterbeats8beatsbydre.com/gfwlist +server=/bmw.com.my/127.0.0.1#5335 +ipset=/bmw.com.my/gfwlist +server=/gfysex.com/127.0.0.1#5335 +ipset=/gfysex.com/gfwlist +server=/dogatch.jp/127.0.0.1#5335 +ipset=/dogatch.jp/gfwlist +server=/otokonokoland.com/127.0.0.1#5335 +ipset=/otokonokoland.com/gfwlist +server=/amakings.com/127.0.0.1#5335 +ipset=/amakings.com/gfwlist +server=/visaeurope.ch/127.0.0.1#5335 +ipset=/visaeurope.ch/gfwlist +server=/geileomas.com/127.0.0.1#5335 +ipset=/geileomas.com/gfwlist +server=/canon.es/127.0.0.1#5335 +ipset=/canon.es/gfwlist +server=/canon-cna.com/127.0.0.1#5335 +ipset=/canon-cna.com/gfwlist +server=/beatsbydrdre-onsale.com/127.0.0.1#5335 +ipset=/beatsbydrdre-onsale.com/gfwlist +server=/amazonprimevideos.com/127.0.0.1#5335 +ipset=/amazonprimevideos.com/gfwlist +server=/kaktuz.com/127.0.0.1#5335 +ipset=/kaktuz.com/gfwlist +server=/sexyhub.com/127.0.0.1#5335 +ipset=/sexyhub.com/gfwlist +server=/forbes.com/127.0.0.1#5335 +ipset=/forbes.com/gfwlist +server=/debugproject.com/127.0.0.1#5335 +ipset=/debugproject.com/gfwlist +server=/firestonecompleteautocare.com/127.0.0.1#5335 +ipset=/firestonecompleteautocare.com/gfwlist +server=/canon.com.tw/127.0.0.1#5335 +ipset=/canon.com.tw/gfwlist +server=/canon.com.tr/127.0.0.1#5335 +ipset=/canon.com.tr/gfwlist +server=/canon.com.my/127.0.0.1#5335 +ipset=/canon.com.my/gfwlist +server=/javjunkies.com/127.0.0.1#5335 +ipset=/javjunkies.com/gfwlist +server=/ebayenterprise.com/127.0.0.1#5335 +ipset=/ebayenterprise.com/gfwlist +server=/brourou.com/127.0.0.1#5335 +ipset=/brourou.com/gfwlist +server=/deutschewelle.h-cdn.com/127.0.0.1#5335 +ipset=/deutschewelle.h-cdn.com/gfwlist +server=/canon.com/127.0.0.1#5335 +ipset=/canon.com/gfwlist +server=/canon.co.uk/127.0.0.1#5335 +ipset=/canon.co.uk/gfwlist +server=/aiasahi.jp/127.0.0.1#5335 +ipset=/aiasahi.jp/gfwlist +server=/canon.be/127.0.0.1#5335 +ipset=/canon.be/gfwlist +server=/mini.com.br/127.0.0.1#5335 +ipset=/mini.com.br/gfwlist +server=/applestor.com/127.0.0.1#5335 +ipset=/applestor.com/gfwlist +server=/google.com.bh/127.0.0.1#5335 +ipset=/google.com.bh/gfwlist +server=/canon.at/127.0.0.1#5335 +ipset=/canon.at/gfwlist +server=/mainichi.jp/127.0.0.1#5335 +ipset=/mainichi.jp/gfwlist +server=/canon.am/127.0.0.1#5335 +ipset=/canon.am/gfwlist +server=/scholar.google.ro/127.0.0.1#5335 +ipset=/scholar.google.ro/gfwlist +server=/virginpornlinks.com/127.0.0.1#5335 +ipset=/virginpornlinks.com/gfwlist +server=/verisign.jobs/127.0.0.1#5335 +ipset=/verisign.jobs/gfwlist +server=/mini-connected.cz/127.0.0.1#5335 +ipset=/mini-connected.cz/gfwlist +server=/canon-se.com.tw/127.0.0.1#5335 +ipset=/canon-se.com.tw/gfwlist +server=/macbook.co/127.0.0.1#5335 +ipset=/macbook.co/gfwlist +server=/enema-videos.com/127.0.0.1#5335 +ipset=/enema-videos.com/gfwlist +server=/ero-ma-nia.com/127.0.0.1#5335 +ipset=/ero-ma-nia.com/gfwlist +server=/canon-europa.com/127.0.0.1#5335 +ipset=/canon-europa.com/gfwlist +server=/magicmovies.com/127.0.0.1#5335 +ipset=/magicmovies.com/gfwlist +server=/canon.pl/127.0.0.1#5335 +ipset=/canon.pl/gfwlist +server=/scatkings.com/127.0.0.1#5335 +ipset=/scatkings.com/gfwlist +server=/kijjiji.ca/127.0.0.1#5335 +ipset=/kijjiji.ca/gfwlist +server=/repswing.com/127.0.0.1#5335 +ipset=/repswing.com/gfwlist +server=/xvideos.red/127.0.0.1#5335 +ipset=/xvideos.red/gfwlist +server=/canon-emirates.ae/127.0.0.1#5335 +ipset=/canon-emirates.ae/gfwlist +server=/canon-ebm.com.hk/127.0.0.1#5335 +ipset=/canon-ebm.com.hk/gfwlist +server=/paypal-redeem.com/127.0.0.1#5335 +ipset=/paypal-redeem.com/gfwlist +server=/18av.pro/127.0.0.1#5335 +ipset=/18av.pro/gfwlist +server=/brilliant.org/127.0.0.1#5335 +ipset=/brilliant.org/gfwlist +server=/facebook-texas-holdem.net/127.0.0.1#5335 +ipset=/facebook-texas-holdem.net/gfwlist +server=/mastercardbiz.ca/127.0.0.1#5335 +ipset=/mastercardbiz.ca/gfwlist +server=/adultism.com/127.0.0.1#5335 +ipset=/adultism.com/gfwlist +server=/avstar4.com/127.0.0.1#5335 +ipset=/avstar4.com/gfwlist +server=/samsungdm.com/127.0.0.1#5335 +ipset=/samsungdm.com/gfwlist +server=/puripuriunkomura.com/127.0.0.1#5335 +ipset=/puripuriunkomura.com/gfwlist +server=/asianprivatetube.com/127.0.0.1#5335 +ipset=/asianprivatetube.com/gfwlist +server=/scienceonline.org/127.0.0.1#5335 +ipset=/scienceonline.org/gfwlist +server=/wifeinterracialfuck.com/127.0.0.1#5335 +ipset=/wifeinterracialfuck.com/gfwlist +server=/sony.ru/127.0.0.1#5335 +ipset=/sony.ru/gfwlist +server=/bwh1.net/127.0.0.1#5335 +ipset=/bwh1.net/gfwlist +server=/pugetsoundmini.com/127.0.0.1#5335 +ipset=/pugetsoundmini.com/gfwlist +server=/mega.co.nz/127.0.0.1#5335 +ipset=/mega.co.nz/gfwlist +server=/google.com.sg/127.0.0.1#5335 +ipset=/google.com.sg/gfwlist +server=/googleanalytics.com/127.0.0.1#5335 +ipset=/googleanalytics.com/gfwlist +server=/mydirectgroove.com/127.0.0.1#5335 +ipset=/mydirectgroove.com/gfwlist +server=/le-direct.tv/127.0.0.1#5335 +ipset=/le-direct.tv/gfwlist +server=/youtube.mk/127.0.0.1#5335 +ipset=/youtube.mk/gfwlist +server=/newsprinters.co.uk/127.0.0.1#5335 +ipset=/newsprinters.co.uk/gfwlist +server=/dropboxcaptcha.com/127.0.0.1#5335 +ipset=/dropboxcaptcha.com/gfwlist +server=/successwithteams.com/127.0.0.1#5335 +ipset=/successwithteams.com/gfwlist +server=/diretv.com/127.0.0.1#5335 +ipset=/diretv.com/gfwlist +server=/directvsundayticket.com/127.0.0.1#5335 +ipset=/directvsundayticket.com/gfwlist +server=/paypalservice.com/127.0.0.1#5335 +ipset=/paypalservice.com/gfwlist +server=/bestbhy.com/127.0.0.1#5335 +ipset=/bestbhy.com/gfwlist +server=/directvrebate.com/127.0.0.1#5335 +ipset=/directvrebate.com/gfwlist +server=/directvpromotions.com/127.0.0.1#5335 +ipset=/directvpromotions.com/gfwlist +server=/directvpromise.com/127.0.0.1#5335 +ipset=/directvpromise.com/gfwlist +server=/barrons.com/127.0.0.1#5335 +ipset=/barrons.com/gfwlist +server=/directvnow.com/127.0.0.1#5335 +ipset=/directvnow.com/gfwlist +server=/airwick.be/127.0.0.1#5335 +ipset=/airwick.be/gfwlist +server=/directvnewhampshire.com/127.0.0.1#5335 +ipset=/directvnewhampshire.com/gfwlist +server=/superearsenjoy.com/127.0.0.1#5335 +ipset=/superearsenjoy.com/gfwlist +server=/kijii.ca/127.0.0.1#5335 +ipset=/kijii.ca/gfwlist +server=/myfoxtwincities.com/127.0.0.1#5335 +ipset=/myfoxtwincities.com/gfwlist +server=/directvkentucky.com/127.0.0.1#5335 +ipset=/directvkentucky.com/gfwlist +server=/cashpassport.ca/127.0.0.1#5335 +ipset=/cashpassport.ca/gfwlist +server=/grannylister.com/127.0.0.1#5335 +ipset=/grannylister.com/gfwlist +server=/fritchy.com/127.0.0.1#5335 +ipset=/fritchy.com/gfwlist +server=/attstadium.com/127.0.0.1#5335 +ipset=/attstadium.com/gfwlist +server=/moov.hk/127.0.0.1#5335 +ipset=/moov.hk/gfwlist +server=/toonsexblog.com/127.0.0.1#5335 +ipset=/toonsexblog.com/gfwlist +server=/laracasts.com/127.0.0.1#5335 +ipset=/laracasts.com/gfwlist +server=/directvdsl.tv/127.0.0.1#5335 +ipset=/directvdsl.tv/gfwlist +server=/tiktok.com/127.0.0.1#5335 +ipset=/tiktok.com/gfwlist +server=/yogify.com/127.0.0.1#5335 +ipset=/yogify.com/gfwlist +server=/directvdealsnow.com/127.0.0.1#5335 +ipset=/directvdealsnow.com/gfwlist +server=/fox32chicago.com/127.0.0.1#5335 +ipset=/fox32chicago.com/gfwlist +server=/hentairox.com/127.0.0.1#5335 +ipset=/hentairox.com/gfwlist +server=/realclearpolitics.com/127.0.0.1#5335 +ipset=/realclearpolitics.com/gfwlist +server=/directvbusiness.com/127.0.0.1#5335 +ipset=/directvbusiness.com/gfwlist +server=/nikestyles.com/127.0.0.1#5335 +ipset=/nikestyles.com/gfwlist +server=/routledgehandbooks.com/127.0.0.1#5335 +ipset=/routledgehandbooks.com/gfwlist +server=/book.com.tw/127.0.0.1#5335 +ipset=/book.com.tw/gfwlist +server=/ajtalk.com/127.0.0.1#5335 +ipset=/ajtalk.com/gfwlist +server=/verizondigitalmedia.com/127.0.0.1#5335 +ipset=/verizondigitalmedia.com/gfwlist +server=/directvboston.com/127.0.0.1#5335 +ipset=/directvboston.com/gfwlist +server=/bestbuys.com/127.0.0.1#5335 +ipset=/bestbuys.com/gfwlist +server=/directv-newyork.com/127.0.0.1#5335 +ipset=/directv-newyork.com/gfwlist +server=/instafallow.com/127.0.0.1#5335 +ipset=/instafallow.com/gfwlist +server=/firstsearch.oclc.org/127.0.0.1#5335 +ipset=/firstsearch.oclc.org/gfwlist +server=/freeb.com/127.0.0.1#5335 +ipset=/freeb.com/gfwlist +server=/dkrecttv.com/127.0.0.1#5335 +ipset=/dkrecttv.com/gfwlist +server=/young-xxx.net/127.0.0.1#5335 +ipset=/young-xxx.net/gfwlist +server=/meme111.com/127.0.0.1#5335 +ipset=/meme111.com/gfwlist +server=/hdvideosporn.net/127.0.0.1#5335 +ipset=/hdvideosporn.net/gfwlist +server=/direcpath.net/127.0.0.1#5335 +ipset=/direcpath.net/gfwlist +server=/hentaistream.tv/127.0.0.1#5335 +ipset=/hentaistream.tv/gfwlist +server=/mcdonalds.hk/127.0.0.1#5335 +ipset=/mcdonalds.hk/gfwlist +server=/softbanktelecom.com/127.0.0.1#5335 +ipset=/softbanktelecom.com/gfwlist +server=/hotgoo.com/127.0.0.1#5335 +ipset=/hotgoo.com/gfwlist +server=/boylove.com/127.0.0.1#5335 +ipset=/boylove.com/gfwlist +server=/zorglist.com/127.0.0.1#5335 +ipset=/zorglist.com/gfwlist +server=/loveamateurfacials.com/127.0.0.1#5335 +ipset=/loveamateurfacials.com/gfwlist +server=/booru.org/127.0.0.1#5335 +ipset=/booru.org/gfwlist +server=/3danimeworld.com/127.0.0.1#5335 +ipset=/3danimeworld.com/gfwlist +server=/infocert.digital/127.0.0.1#5335 +ipset=/infocert.digital/gfwlist +server=/mini.si/127.0.0.1#5335 +ipset=/mini.si/gfwlist +server=/tvpromise.com/127.0.0.1#5335 +ipset=/tvpromise.com/gfwlist +server=/porngames.tv/127.0.0.1#5335 +ipset=/porngames.tv/gfwlist +server=/pinkworld.com/127.0.0.1#5335 +ipset=/pinkworld.com/gfwlist +server=/yes123.com.tw/127.0.0.1#5335 +ipset=/yes123.com.tw/gfwlist +server=/synaptic.net/127.0.0.1#5335 +ipset=/synaptic.net/gfwlist +server=/safebooru.org/127.0.0.1#5335 +ipset=/safebooru.org/gfwlist +server=/sundayready.com/127.0.0.1#5335 +ipset=/sundayready.com/gfwlist +server=/susiewildin.com/127.0.0.1#5335 +ipset=/susiewildin.com/gfwlist +server=/girlsdelta.com/127.0.0.1#5335 +ipset=/girlsdelta.com/gfwlist +server=/hotbeatsonsale.com/127.0.0.1#5335 +ipset=/hotbeatsonsale.com/gfwlist +server=/bmw-motorrad.ro/127.0.0.1#5335 +ipset=/bmw-motorrad.ro/gfwlist +server=/visa.com.cy/127.0.0.1#5335 +ipset=/visa.com.cy/gfwlist +server=/8xxx.net/127.0.0.1#5335 +ipset=/8xxx.net/gfwlist +server=/bmwsafari.com/127.0.0.1#5335 +ipset=/bmwsafari.com/gfwlist +server=/enterprisepaging.com/127.0.0.1#5335 +ipset=/enterprisepaging.com/gfwlist +server=/foxaffiliateportal.com/127.0.0.1#5335 +ipset=/foxaffiliateportal.com/gfwlist +server=/directvbusinessmarket.com/127.0.0.1#5335 +ipset=/directvbusinessmarket.com/gfwlist +server=/naizitv.top/127.0.0.1#5335 +ipset=/naizitv.top/gfwlist +server=/swissstick.com/127.0.0.1#5335 +ipset=/swissstick.com/gfwlist +server=/bmw-connecteddrive.sk/127.0.0.1#5335 +ipset=/bmw-connecteddrive.sk/gfwlist +server=/microsoft.ro/127.0.0.1#5335 +ipset=/microsoft.ro/gfwlist +server=/cbs.com/127.0.0.1#5335 +ipset=/cbs.com/gfwlist +server=/customdrdrebeats.com/127.0.0.1#5335 +ipset=/customdrdrebeats.com/gfwlist +server=/currently.net/127.0.0.1#5335 +ipset=/currently.net/gfwlist +server=/ntdtv.com/127.0.0.1#5335 +ipset=/ntdtv.com/gfwlist +server=/oudoll.com/127.0.0.1#5335 +ipset=/oudoll.com/gfwlist +server=/ebaychina.net/127.0.0.1#5335 +ipset=/ebaychina.net/gfwlist +server=/enablementadobe.com/127.0.0.1#5335 +ipset=/enablementadobe.com/gfwlist +server=/18comic.vip/127.0.0.1#5335 +ipset=/18comic.vip/gfwlist +server=/acgvipss.com/127.0.0.1#5335 +ipset=/acgvipss.com/gfwlist +server=/nexpart.com/127.0.0.1#5335 +ipset=/nexpart.com/gfwlist +server=/headphonesol.com/127.0.0.1#5335 +ipset=/headphonesol.com/gfwlist +server=/pearsonvue.com/127.0.0.1#5335 +ipset=/pearsonvue.com/gfwlist +server=/beatsmonstersales.com/127.0.0.1#5335 +ipset=/beatsmonstersales.com/gfwlist +server=/attuverseonline.com/127.0.0.1#5335 +ipset=/attuverseonline.com/gfwlist +server=/attuverseoffers.com/127.0.0.1#5335 +ipset=/attuverseoffers.com/gfwlist +server=/attsuppliers.com/127.0.0.1#5335 +ipset=/attsuppliers.com/gfwlist +server=/opencollective.com/127.0.0.1#5335 +ipset=/opencollective.com/gfwlist +server=/anidom.com/127.0.0.1#5335 +ipset=/anidom.com/gfwlist +server=/slackb.com/127.0.0.1#5335 +ipset=/slackb.com/gfwlist +server=/niketaiwan.net/127.0.0.1#5335 +ipset=/niketaiwan.net/gfwlist +server=/m.me/127.0.0.1#5335 +ipset=/m.me/gfwlist +server=/matures-loving-sex.com/127.0.0.1#5335 +ipset=/matures-loving-sex.com/gfwlist +server=/musickit.net/127.0.0.1#5335 +ipset=/musickit.net/gfwlist +server=/attpublicpolicy.com/127.0.0.1#5335 +ipset=/attpublicpolicy.com/gfwlist +server=/gitlab-assets.oss-cn-hongkong.aliyuncs.com/127.0.0.1#5335 +ipset=/gitlab-assets.oss-cn-hongkong.aliyuncs.com/gfwlist +server=/attnetclient.com/127.0.0.1#5335 +ipset=/attnetclient.com/gfwlist +server=/attjoy.com/127.0.0.1#5335 +ipset=/attjoy.com/gfwlist +server=/attcollaborate.com/127.0.0.1#5335 +ipset=/attcollaborate.com/gfwlist +server=/goldengate.hu/127.0.0.1#5335 +ipset=/goldengate.hu/gfwlist +server=/attbusiness.net/127.0.0.1#5335 +ipset=/attbusiness.net/gfwlist +server=/sexbebin.com/127.0.0.1#5335 +ipset=/sexbebin.com/gfwlist +server=/iphoneimessage.com/127.0.0.1#5335 +ipset=/iphoneimessage.com/gfwlist +server=/1pornlist.com/127.0.0.1#5335 +ipset=/1pornlist.com/gfwlist +server=/eadultgames.com/127.0.0.1#5335 +ipset=/eadultgames.com/gfwlist +server=/fameregistry.com/127.0.0.1#5335 +ipset=/fameregistry.com/gfwlist +server=/cumfox.com/127.0.0.1#5335 +ipset=/cumfox.com/gfwlist +server=/att.jobs/127.0.0.1#5335 +ipset=/att.jobs/gfwlist +server=/gwktravelex.nl/127.0.0.1#5335 +ipset=/gwktravelex.nl/gfwlist +server=/youngermommy.com/127.0.0.1#5335 +ipset=/youngermommy.com/gfwlist +server=/porn-discounts.xxx/127.0.0.1#5335 +ipset=/porn-discounts.xxx/gfwlist +server=/pixnet.cc/127.0.0.1#5335 +ipset=/pixnet.cc/gfwlist +server=/att-promotions.com/127.0.0.1#5335 +ipset=/att-promotions.com/gfwlist +server=/digital-id.ch/127.0.0.1#5335 +ipset=/digital-id.ch/gfwlist +server=/t.me/127.0.0.1#5335 +ipset=/t.me/gfwlist +server=/att-mail.com/127.0.0.1#5335 +ipset=/att-mail.com/gfwlist +server=/f-droid.org/127.0.0.1#5335 +ipset=/f-droid.org/gfwlist +server=/sarapbabe.com/127.0.0.1#5335 +ipset=/sarapbabe.com/gfwlist +server=/att-bundles.com/127.0.0.1#5335 +ipset=/att-bundles.com/gfwlist +server=/accbusiness.com/127.0.0.1#5335 +ipset=/accbusiness.com/gfwlist +server=/miohentai.com/127.0.0.1#5335 +ipset=/miohentai.com/gfwlist +server=/bitbucket.org/127.0.0.1#5335 +ipset=/bitbucket.org/gfwlist +server=/volvobuses.in/127.0.0.1#5335 +ipset=/volvobuses.in/gfwlist +server=/person.com/127.0.0.1#5335 +ipset=/person.com/gfwlist +server=/xn--kput3imi374g.xn--hxt814e/127.0.0.1#5335 +ipset=/xn--kput3imi374g.xn--hxt814e/gfwlist +server=/ebayhots.com/127.0.0.1#5335 +ipset=/ebayhots.com/gfwlist +server=/mini.tm/127.0.0.1#5335 +ipset=/mini.tm/gfwlist +server=/line-cdn.net/127.0.0.1#5335 +ipset=/line-cdn.net/gfwlist +server=/beatsallsale.com/127.0.0.1#5335 +ipset=/beatsallsale.com/gfwlist +server=/ao3.org/127.0.0.1#5335 +ipset=/ao3.org/gfwlist +server=/xn--fiqs8sxootzz.cn/127.0.0.1#5335 +ipset=/xn--fiqs8sxootzz.cn/gfwlist +server=/qinav.com/127.0.0.1#5335 +ipset=/qinav.com/gfwlist +server=/wwapple.net/127.0.0.1#5335 +ipset=/wwapple.net/gfwlist +server=/gobuyonlinestore.net/127.0.0.1#5335 +ipset=/gobuyonlinestore.net/gfwlist +server=/pornhub.com/127.0.0.1#5335 +ipset=/pornhub.com/gfwlist +server=/applestore.com.pt/127.0.0.1#5335 +ipset=/applestore.com.pt/gfwlist +server=/webobjects.eu/127.0.0.1#5335 +ipset=/webobjects.eu/gfwlist +server=/freeomovie.to/127.0.0.1#5335 +ipset=/freeomovie.to/gfwlist +server=/kubakuba.global/127.0.0.1#5335 +ipset=/kubakuba.global/gfwlist +server=/freearabsexx.com/127.0.0.1#5335 +ipset=/freearabsexx.com/gfwlist +server=/canon-me.com/127.0.0.1#5335 +ipset=/canon-me.com/gfwlist +server=/pearsonclinical.fr/127.0.0.1#5335 +ipset=/pearsonclinical.fr/gfwlist +server=/etbc.com.hk/127.0.0.1#5335 +ipset=/etbc.com.hk/gfwlist +server=/quicktime.net/127.0.0.1#5335 +ipset=/quicktime.net/gfwlist +server=/rprimelab.com/127.0.0.1#5335 +ipset=/rprimelab.com/gfwlist +server=/speedhunters.com/127.0.0.1#5335 +ipset=/speedhunters.com/gfwlist +server=/177picyy.com/127.0.0.1#5335 +ipset=/177picyy.com/gfwlist +server=/pornovenezolanox.com/127.0.0.1#5335 +ipset=/pornovenezolanox.com/gfwlist +server=/quicktime.com.au/127.0.0.1#5335 +ipset=/quicktime.com.au/gfwlist +server=/quicktime.cc/127.0.0.1#5335 +ipset=/quicktime.cc/gfwlist +server=/camelot-europe.com/127.0.0.1#5335 +ipset=/camelot-europe.com/gfwlist +server=/xn--xsq959n.com/127.0.0.1#5335 +ipset=/xn--xsq959n.com/gfwlist +server=/xn--gmq92kd2rm1kx34a.com/127.0.0.1#5335 +ipset=/xn--gmq92kd2rm1kx34a.com/gfwlist +server=/catmiimi.com/127.0.0.1#5335 +ipset=/catmiimi.com/gfwlist +server=/la-mama.ru/127.0.0.1#5335 +ipset=/la-mama.ru/gfwlist +server=/oanencore.com/127.0.0.1#5335 +ipset=/oanencore.com/gfwlist +server=/newton.com/127.0.0.1#5335 +ipset=/newton.com/gfwlist +server=/achat-followers-instagram.com/127.0.0.1#5335 +ipset=/achat-followers-instagram.com/gfwlist +server=/macreach.net/127.0.0.1#5335 +ipset=/macreach.net/gfwlist +server=/macpazar.com/127.0.0.1#5335 +ipset=/macpazar.com/gfwlist +server=/practicalbusinessskills.com/127.0.0.1#5335 +ipset=/practicalbusinessskills.com/gfwlist +server=/kphimsex.net/127.0.0.1#5335 +ipset=/kphimsex.net/gfwlist +server=/macosx.info/127.0.0.1#5335 +ipset=/macosx.info/gfwlist +server=/volvobuses.fr/127.0.0.1#5335 +ipset=/volvobuses.fr/gfwlist +server=/visa.so/127.0.0.1#5335 +ipset=/visa.so/gfwlist +server=/youtube.com.az/127.0.0.1#5335 +ipset=/youtube.com.az/gfwlist +server=/bikac.xyz/127.0.0.1#5335 +ipset=/bikac.xyz/gfwlist +server=/google.com.lb/127.0.0.1#5335 +ipset=/google.com.lb/gfwlist +server=/icashpassport.com.mx/127.0.0.1#5335 +ipset=/icashpassport.com.mx/gfwlist +server=/bmw-motorrad.dk/127.0.0.1#5335 +ipset=/bmw-motorrad.dk/gfwlist +server=/bmw-int1.com/127.0.0.1#5335 +ipset=/bmw-int1.com/gfwlist +server=/yomiuri-systec.co.jp/127.0.0.1#5335 +ipset=/yomiuri-systec.co.jp/gfwlist +server=/disney.fi/127.0.0.1#5335 +ipset=/disney.fi/gfwlist +server=/disney.io/127.0.0.1#5335 +ipset=/disney.io/gfwlist +server=/eac-cdn.com/127.0.0.1#5335 +ipset=/eac-cdn.com/gfwlist +server=/supercell.com/127.0.0.1#5335 +ipset=/supercell.com/gfwlist +server=/macboxset.com/127.0.0.1#5335 +ipset=/macboxset.com/gfwlist +server=/scholar.google.com/127.0.0.1#5335 +ipset=/scholar.google.com/gfwlist +server=/emblstatic.net/127.0.0.1#5335 +ipset=/emblstatic.net/gfwlist +server=/mac.rs/127.0.0.1#5335 +ipset=/mac.rs/gfwlist +server=/singpao.com.hk/127.0.0.1#5335 +ipset=/singpao.com.hk/gfwlist +server=/oxfordhandbooks.com/127.0.0.1#5335 +ipset=/oxfordhandbooks.com/gfwlist +server=/mac.eu/127.0.0.1#5335 +ipset=/mac.eu/gfwlist +server=/javpub.me/127.0.0.1#5335 +ipset=/javpub.me/gfwlist +server=/familypornhd.com/127.0.0.1#5335 +ipset=/familypornhd.com/gfwlist +server=/mac.com/127.0.0.1#5335 +ipset=/mac.com/gfwlist +server=/milfporn.pro/127.0.0.1#5335 +ipset=/milfporn.pro/gfwlist +server=/noodlemagazine.com/127.0.0.1#5335 +ipset=/noodlemagazine.com/gfwlist +server=/bangyourwife.com/127.0.0.1#5335 +ipset=/bangyourwife.com/gfwlist +server=/facebookblueprint.net/127.0.0.1#5335 +ipset=/facebookblueprint.net/gfwlist +server=/ksd235qw.com/127.0.0.1#5335 +ipset=/ksd235qw.com/gfwlist +server=/bmwmagazine.com/127.0.0.1#5335 +ipset=/bmwmagazine.com/gfwlist +server=/vgcareers.net/127.0.0.1#5335 +ipset=/vgcareers.net/gfwlist +server=/anyxxx.pro/127.0.0.1#5335 +ipset=/anyxxx.pro/gfwlist +server=/instaplayer.net/127.0.0.1#5335 +ipset=/instaplayer.net/gfwlist +server=/volvotrucks.qa/127.0.0.1#5335 +ipset=/volvotrucks.qa/gfwlist +server=/foxsportsuniversity.com/127.0.0.1#5335 +ipset=/foxsportsuniversity.com/gfwlist +server=/nudecams.cam/127.0.0.1#5335 +ipset=/nudecams.cam/gfwlist +server=/minivictoria.ca/127.0.0.1#5335 +ipset=/minivictoria.ca/gfwlist +server=/yahoo.co.vi/127.0.0.1#5335 +ipset=/yahoo.co.vi/gfwlist +server=/iwork.wang/127.0.0.1#5335 +ipset=/iwork.wang/gfwlist +server=/ischool.com/127.0.0.1#5335 +ipset=/ischool.com/gfwlist +server=/applenews.hamburg/127.0.0.1#5335 +ipset=/applenews.hamburg/gfwlist +server=/ipa-iphone.net/127.0.0.1#5335 +ipset=/ipa-iphone.net/gfwlist +server=/akamaimagicmath.net/127.0.0.1#5335 +ipset=/akamaimagicmath.net/gfwlist +server=/iosinthecar.com/127.0.0.1#5335 +ipset=/iosinthecar.com/gfwlist +server=/voxmedia.com/127.0.0.1#5335 +ipset=/voxmedia.com/gfwlist +server=/hentaipapa.com/127.0.0.1#5335 +ipset=/hentaipapa.com/gfwlist +server=/bestiphonestuff.com/127.0.0.1#5335 +ipset=/bestiphonestuff.com/gfwlist +server=/amerikaovozi.com/127.0.0.1#5335 +ipset=/amerikaovozi.com/gfwlist +server=/imessage.tv/127.0.0.1#5335 +ipset=/imessage.tv/gfwlist +server=/ikids.com/127.0.0.1#5335 +ipset=/ikids.com/gfwlist +server=/epochstories.com/127.0.0.1#5335 +ipset=/epochstories.com/gfwlist +server=/beatsbydrecheap-outletstore.com/127.0.0.1#5335 +ipset=/beatsbydrecheap-outletstore.com/gfwlist +server=/swisstsa.li/127.0.0.1#5335 +ipset=/swisstsa.li/gfwlist +server=/firewire.cl/127.0.0.1#5335 +ipset=/firewire.cl/gfwlist +server=/finalcutpro.com/127.0.0.1#5335 +ipset=/finalcutpro.com/gfwlist +server=/freefacebook.net/127.0.0.1#5335 +ipset=/freefacebook.net/gfwlist +server=/facetime.net/127.0.0.1#5335 +ipset=/facetime.net/gfwlist +server=/hulunetwork.com/127.0.0.1#5335 +ipset=/hulunetwork.com/gfwlist +server=/promonsterbeatsbydre.com/127.0.0.1#5335 +ipset=/promonsterbeatsbydre.com/gfwlist +server=/shopbeatsdre.com/127.0.0.1#5335 +ipset=/shopbeatsdre.com/gfwlist +server=/lostbetsgames.com/127.0.0.1#5335 +ipset=/lostbetsgames.com/gfwlist +server=/park-now.com/127.0.0.1#5335 +ipset=/park-now.com/gfwlist +server=/bbyintl.com/127.0.0.1#5335 +ipset=/bbyintl.com/gfwlist +server=/bdsmbunker.com/127.0.0.1#5335 +ipset=/bdsmbunker.com/gfwlist +server=/google.com.bd/127.0.0.1#5335 +ipset=/google.com.bd/gfwlist +server=/leaguesharp.info/127.0.0.1#5335 +ipset=/leaguesharp.info/gfwlist +server=/ipfs.eth.aragon.network/127.0.0.1#5335 +ipset=/ipfs.eth.aragon.network/gfwlist +server=/emac.in/127.0.0.1#5335 +ipset=/emac.in/gfwlist +server=/pogobeta.com/127.0.0.1#5335 +ipset=/pogobeta.com/gfwlist +server=/uun95.com/127.0.0.1#5335 +ipset=/uun95.com/gfwlist +server=/dvdstudiopro.us/127.0.0.1#5335 +ipset=/dvdstudiopro.us/gfwlist +server=/only-xxx-porn.com/127.0.0.1#5335 +ipset=/only-xxx-porn.com/gfwlist +server=/mini.com.py/127.0.0.1#5335 +ipset=/mini.com.py/gfwlist +server=/azure.net/127.0.0.1#5335 +ipset=/azure.net/gfwlist +server=/embl.de/127.0.0.1#5335 +ipset=/embl.de/gfwlist +server=/dvdstudiopro.com/127.0.0.1#5335 +ipset=/dvdstudiopro.com/gfwlist +server=/beatsbydre2081.com/127.0.0.1#5335 +ipset=/beatsbydre2081.com/gfwlist +server=/whonix.org/127.0.0.1#5335 +ipset=/whonix.org/gfwlist +server=/dvdstudiopro.biz/127.0.0.1#5335 +ipset=/dvdstudiopro.biz/gfwlist +server=/macrumors.com/127.0.0.1#5335 +ipset=/macrumors.com/gfwlist +server=/dotmac.de/127.0.0.1#5335 +ipset=/dotmac.de/gfwlist +server=/bmw-m.com/127.0.0.1#5335 +ipset=/bmw-m.com/gfwlist +server=/digitalhub.com/127.0.0.1#5335 +ipset=/digitalhub.com/gfwlist +server=/cheapestbeatsdrdre.com/127.0.0.1#5335 +ipset=/cheapestbeatsdrdre.com/gfwlist +server=/nextechafrica.net/127.0.0.1#5335 +ipset=/nextechafrica.net/gfwlist +server=/appcenter.ms/127.0.0.1#5335 +ipset=/appcenter.ms/gfwlist +server=/desktopmovies.net/127.0.0.1#5335 +ipset=/desktopmovies.net/gfwlist +server=/gcrtires.com/127.0.0.1#5335 +ipset=/gcrtires.com/gfwlist +server=/desktopmovie.net/127.0.0.1#5335 +ipset=/desktopmovie.net/gfwlist +server=/online-deals.net/127.0.0.1#5335 +ipset=/online-deals.net/gfwlist +server=/dashwood360.com/127.0.0.1#5335 +ipset=/dashwood360.com/gfwlist +server=/fotolia.tv/127.0.0.1#5335 +ipset=/fotolia.tv/gfwlist +server=/niziero.info/127.0.0.1#5335 +ipset=/niziero.info/gfwlist +server=/parstream.com/127.0.0.1#5335 +ipset=/parstream.com/gfwlist +server=/boxun.com/127.0.0.1#5335 +ipset=/boxun.com/gfwlist +server=/disneyinternationalhd.com/127.0.0.1#5335 +ipset=/disneyinternationalhd.com/gfwlist +server=/dropboxbusiness.com/127.0.0.1#5335 +ipset=/dropboxbusiness.com/gfwlist +server=/nurofen.ie/127.0.0.1#5335 +ipset=/nurofen.ie/gfwlist +server=/faccebook.com/127.0.0.1#5335 +ipset=/faccebook.com/gfwlist +server=/ssl-certificate.ch/127.0.0.1#5335 +ipset=/ssl-certificate.ch/gfwlist +server=/volvotruckcenter.se/127.0.0.1#5335 +ipset=/volvotruckcenter.se/gfwlist +server=/xxnxx-sex.com/127.0.0.1#5335 +ipset=/xxnxx-sex.com/gfwlist +server=/alphabet.biz/127.0.0.1#5335 +ipset=/alphabet.biz/gfwlist +server=/faacebok.com/127.0.0.1#5335 +ipset=/faacebok.com/gfwlist +server=/duckduckgo.com/127.0.0.1#5335 +ipset=/duckduckgo.com/gfwlist +server=/forzamotorsport.net/127.0.0.1#5335 +ipset=/forzamotorsport.net/gfwlist +server=/paypal-search.com/127.0.0.1#5335 +ipset=/paypal-search.com/gfwlist +server=/dreamteamfc.com/127.0.0.1#5335 +ipset=/dreamteamfc.com/gfwlist +server=/apyle.com/127.0.0.1#5335 +ipset=/apyle.com/gfwlist +server=/epochtimes.co.uk/127.0.0.1#5335 +ipset=/epochtimes.co.uk/gfwlist +server=/appye.com/127.0.0.1#5335 +ipset=/appye.com/gfwlist +server=/appmediagroup.com/127.0.0.1#5335 +ipset=/appmediagroup.com/gfwlist +server=/12diasderegalosdeitunes.com.hn/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.com.hn/gfwlist +server=/blogebay.com/127.0.0.1#5335 +ipset=/blogebay.com/gfwlist +server=/indian-pornstars.com/127.0.0.1#5335 +ipset=/indian-pornstars.com/gfwlist +server=/applle.com/127.0.0.1#5335 +ipset=/applle.com/gfwlist +server=/xxx-fap.com/127.0.0.1#5335 +ipset=/xxx-fap.com/gfwlist +server=/swisssign.net/127.0.0.1#5335 +ipset=/swisssign.net/gfwlist +server=/applezh.com/127.0.0.1#5335 +ipset=/applezh.com/gfwlist +server=/ebayt.com/127.0.0.1#5335 +ipset=/ebayt.com/gfwlist +server=/paisapay.cc/127.0.0.1#5335 +ipset=/paisapay.cc/gfwlist +server=/appleweb.net/127.0.0.1#5335 +ipset=/appleweb.net/gfwlist +server=/statics-marketingsites-eus-ms-com.akamaized.net/127.0.0.1#5335 +ipset=/statics-marketingsites-eus-ms-com.akamaized.net/gfwlist +server=/ctwant.com/127.0.0.1#5335 +ipset=/ctwant.com/gfwlist +server=/gonike.com/127.0.0.1#5335 +ipset=/gonike.com/gfwlist +server=/facebookclub.com/127.0.0.1#5335 +ipset=/facebookclub.com/gfwlist +server=/bowsersinsidestory.com/127.0.0.1#5335 +ipset=/bowsersinsidestory.com/gfwlist +server=/orgypornonly.com/127.0.0.1#5335 +ipset=/orgypornonly.com/gfwlist +server=/boslife.net/127.0.0.1#5335 +ipset=/boslife.net/gfwlist +server=/appleshop.co.uk/127.0.0.1#5335 +ipset=/appleshop.co.uk/gfwlist +server=/appleshare.info/127.0.0.1#5335 +ipset=/appleshare.info/gfwlist +server=/cpan.org/127.0.0.1#5335 +ipset=/cpan.org/gfwlist +server=/pricelesstv.com/127.0.0.1#5335 +ipset=/pricelesstv.com/gfwlist +server=/ntnews.com.au/127.0.0.1#5335 +ipset=/ntnews.com.au/gfwlist +server=/apples-msk.ru/127.0.0.1#5335 +ipset=/apples-msk.ru/gfwlist +server=/minidealernet.com/127.0.0.1#5335 +ipset=/minidealernet.com/gfwlist +server=/bestxxxsites.com/127.0.0.1#5335 +ipset=/bestxxxsites.com/gfwlist +server=/secretbabes.co.uk/127.0.0.1#5335 +ipset=/secretbabes.co.uk/gfwlist +server=/applereach.net/127.0.0.1#5335 +ipset=/applereach.net/gfwlist +server=/applepremiumresellers.com.au/127.0.0.1#5335 +ipset=/applepremiumresellers.com.au/gfwlist +server=/amazon.co.uk/127.0.0.1#5335 +ipset=/amazon.co.uk/gfwlist +server=/visiontimes.net/127.0.0.1#5335 +ipset=/visiontimes.net/gfwlist +server=/biomedcentral.com/127.0.0.1#5335 +ipset=/biomedcentral.com/gfwlist +server=/iceporn.com/127.0.0.1#5335 +ipset=/iceporn.com/gfwlist +server=/bossagency.co.uk/127.0.0.1#5335 +ipset=/bossagency.co.uk/gfwlist +server=/appleonline.net/127.0.0.1#5335 +ipset=/appleonline.net/gfwlist +server=/applemagickeyboard.com/127.0.0.1#5335 +ipset=/applemagickeyboard.com/gfwlist +server=/ygugu4.com/127.0.0.1#5335 +ipset=/ygugu4.com/gfwlist +server=/pearsoncanada.ca/127.0.0.1#5335 +ipset=/pearsoncanada.ca/gfwlist +server=/brazzersnetwork.com/127.0.0.1#5335 +ipset=/brazzersnetwork.com/gfwlist +server=/yourlust.com/127.0.0.1#5335 +ipset=/yourlust.com/gfwlist +server=/huffingtonpost.ca/127.0.0.1#5335 +ipset=/huffingtonpost.ca/gfwlist +server=/mtvnservices.com/127.0.0.1#5335 +ipset=/mtvnservices.com/gfwlist +server=/muji.com.hk/127.0.0.1#5335 +ipset=/muji.com.hk/gfwlist +server=/huloo.cc/127.0.0.1#5335 +ipset=/huloo.cc/gfwlist +server=/oreno3d.com/127.0.0.1#5335 +ipset=/oreno3d.com/gfwlist +server=/httpwwwfacebook.com/127.0.0.1#5335 +ipset=/httpwwwfacebook.com/gfwlist +server=/omgteens.com/127.0.0.1#5335 +ipset=/omgteens.com/gfwlist +server=/vmwarecloud.com/127.0.0.1#5335 +ipset=/vmwarecloud.com/gfwlist +server=/sharepoint.com/127.0.0.1#5335 +ipset=/sharepoint.com/gfwlist +server=/pornmaturetube.com/127.0.0.1#5335 +ipset=/pornmaturetube.com/gfwlist +server=/applefilmmaker.com/127.0.0.1#5335 +ipset=/applefilmmaker.com/gfwlist +server=/iamakamai.net/127.0.0.1#5335 +ipset=/iamakamai.net/gfwlist +server=/monsterbeatshere.com/127.0.0.1#5335 +ipset=/monsterbeatshere.com/gfwlist +server=/disneytvajobs.com/127.0.0.1#5335 +ipset=/disneytvajobs.com/gfwlist +server=/animesex.me/127.0.0.1#5335 +ipset=/animesex.me/gfwlist +server=/appleexpo.eu/127.0.0.1#5335 +ipset=/appleexpo.eu/gfwlist +server=/secretchina.com/127.0.0.1#5335 +ipset=/secretchina.com/gfwlist +server=/foxredeem.com/127.0.0.1#5335 +ipset=/foxredeem.com/gfwlist +server=/belamionline.com/127.0.0.1#5335 +ipset=/belamionline.com/gfwlist +server=/dojinmanga.net/127.0.0.1#5335 +ipset=/dojinmanga.net/gfwlist +server=/applecomputerinc.info/127.0.0.1#5335 +ipset=/applecomputerinc.info/gfwlist +server=/ebayetc.com/127.0.0.1#5335 +ipset=/ebayetc.com/gfwlist +server=/pornnetworkdeals.com/127.0.0.1#5335 +ipset=/pornnetworkdeals.com/gfwlist +server=/ikea.ca/127.0.0.1#5335 +ipset=/ikea.ca/gfwlist +server=/applecomputerimac.com/127.0.0.1#5335 +ipset=/applecomputerimac.com/gfwlist +server=/applecomputer.kr/127.0.0.1#5335 +ipset=/applecomputer.kr/gfwlist +server=/hhtdq17.com/127.0.0.1#5335 +ipset=/hhtdq17.com/gfwlist +server=/magento.com/127.0.0.1#5335 +ipset=/magento.com/gfwlist +server=/google.com.mt/127.0.0.1#5335 +ipset=/google.com.mt/gfwlist +server=/bridgestonegz.com/127.0.0.1#5335 +ipset=/bridgestonegz.com/gfwlist +server=/applecomputer.com/127.0.0.1#5335 +ipset=/applecomputer.com/gfwlist +server=/applecomputer.co.nz/127.0.0.1#5335 +ipset=/applecomputer.co.nz/gfwlist +server=/applecomputer-imac.com/127.0.0.1#5335 +ipset=/applecomputer-imac.com/gfwlist +server=/borwap.com/127.0.0.1#5335 +ipset=/borwap.com/gfwlist +server=/disneyplus.bn5x.net/127.0.0.1#5335 +ipset=/disneyplus.bn5x.net/gfwlist +server=/mobileview.page/127.0.0.1#5335 +ipset=/mobileview.page/gfwlist +server=/youtube.co.za/127.0.0.1#5335 +ipset=/youtube.co.za/gfwlist +server=/simility.com/127.0.0.1#5335 +ipset=/simility.com/gfwlist +server=/beatsbydreblackfridaypro.com/127.0.0.1#5335 +ipset=/beatsbydreblackfridaypro.com/gfwlist +server=/pinkcore.net/127.0.0.1#5335 +ipset=/pinkcore.net/gfwlist +server=/now-ashare.com/127.0.0.1#5335 +ipset=/now-ashare.com/gfwlist +server=/reurl.cc/127.0.0.1#5335 +ipset=/reurl.cc/gfwlist +server=/rockettube.com/127.0.0.1#5335 +ipset=/rockettube.com/gfwlist +server=/evernote.com/127.0.0.1#5335 +ipset=/evernote.com/gfwlist +server=/voacambodia.com/127.0.0.1#5335 +ipset=/voacambodia.com/gfwlist +server=/appleaustralia.com.au/127.0.0.1#5335 +ipset=/appleaustralia.com.au/gfwlist +server=/talentlens.com/127.0.0.1#5335 +ipset=/talentlens.com/gfwlist +server=/electricluxury.com/127.0.0.1#5335 +ipset=/electricluxury.com/gfwlist +server=/ebaydlassifieds.com/127.0.0.1#5335 +ipset=/ebaydlassifieds.com/gfwlist +server=/gay0day.com/127.0.0.1#5335 +ipset=/gay0day.com/gfwlist +server=/thotbook.tv/127.0.0.1#5335 +ipset=/thotbook.tv/gfwlist +server=/realamericanstories.tv/127.0.0.1#5335 +ipset=/realamericanstories.tv/gfwlist +server=/bmw-gta.ca/127.0.0.1#5335 +ipset=/bmw-gta.ca/gfwlist +server=/kisscos.net/127.0.0.1#5335 +ipset=/kisscos.net/gfwlist +server=/apple-usa.net/127.0.0.1#5335 +ipset=/apple-usa.net/gfwlist +server=/beatsbydre-headphones.com/127.0.0.1#5335 +ipset=/beatsbydre-headphones.com/gfwlist +server=/youtube.com.jo/127.0.0.1#5335 +ipset=/youtube.com.jo/gfwlist +server=/tubesafari.com/127.0.0.1#5335 +ipset=/tubesafari.com/gfwlist +server=/forzarc.com/127.0.0.1#5335 +ipset=/forzarc.com/gfwlist +server=/erogazopple.com/127.0.0.1#5335 +ipset=/erogazopple.com/gfwlist +server=/bml.info/127.0.0.1#5335 +ipset=/bml.info/gfwlist +server=/duckduckgo.de/127.0.0.1#5335 +ipset=/duckduckgo.de/gfwlist +server=/ebaysoho.com/127.0.0.1#5335 +ipset=/ebaysoho.com/gfwlist +server=/itunes-radio.net/127.0.0.1#5335 +ipset=/itunes-radio.net/gfwlist +server=/apple-livephotoskit.com/127.0.0.1#5335 +ipset=/apple-livephotoskit.com/gfwlist +server=/rgpub.io/127.0.0.1#5335 +ipset=/rgpub.io/gfwlist +server=/savethedate.foo/127.0.0.1#5335 +ipset=/savethedate.foo/gfwlist +server=/apple-inc.net/127.0.0.1#5335 +ipset=/apple-inc.net/gfwlist +server=/apple-hk.com/127.0.0.1#5335 +ipset=/apple-hk.com/gfwlist +server=/illusiongw.com/127.0.0.1#5335 +ipset=/illusiongw.com/gfwlist +server=/adultsexgames.biz/127.0.0.1#5335 +ipset=/adultsexgames.biz/gfwlist +server=/ebayuae.net/127.0.0.1#5335 +ipset=/ebayuae.net/gfwlist +server=/thenewgirlspooping.com/127.0.0.1#5335 +ipset=/thenewgirlspooping.com/gfwlist +server=/apple-dns.net/127.0.0.1#5335 +ipset=/apple-dns.net/gfwlist +server=/alliancesages.com/127.0.0.1#5335 +ipset=/alliancesages.com/gfwlist +server=/apple-dns.com/127.0.0.1#5335 +ipset=/apple-dns.com/gfwlist +server=/vintage-erotica-forum.com/127.0.0.1#5335 +ipset=/vintage-erotica-forum.com/gfwlist +server=/apple-darwin.net/127.0.0.1#5335 +ipset=/apple-darwin.net/gfwlist +server=/cdngarenanow-a.akamaihd.net/127.0.0.1#5335 +ipset=/cdngarenanow-a.akamaihd.net/gfwlist +server=/apple-darwin.com/127.0.0.1#5335 +ipset=/apple-darwin.com/gfwlist +server=/nijiclamp.com/127.0.0.1#5335 +ipset=/nijiclamp.com/gfwlist +server=/mystrikingly.com/127.0.0.1#5335 +ipset=/mystrikingly.com/gfwlist +server=/mastercard.co.za/127.0.0.1#5335 +ipset=/mastercard.co.za/gfwlist +server=/eakorea.co.kr/127.0.0.1#5335 +ipset=/eakorea.co.kr/gfwlist +server=/nikefreeshoes.com/127.0.0.1#5335 +ipset=/nikefreeshoes.com/gfwlist +server=/doom.com/127.0.0.1#5335 +ipset=/doom.com/gfwlist +server=/jodic-forum.org/127.0.0.1#5335 +ipset=/jodic-forum.org/gfwlist +server=/tyms2022.com/127.0.0.1#5335 +ipset=/tyms2022.com/gfwlist +server=/miniccrc.ca/127.0.0.1#5335 +ipset=/miniccrc.ca/gfwlist +server=/viet69.dev/127.0.0.1#5335 +ipset=/viet69.dev/gfwlist +server=/ap0le.com/127.0.0.1#5335 +ipset=/ap0le.com/gfwlist +server=/airtunes.net/127.0.0.1#5335 +ipset=/airtunes.net/gfwlist +server=/diabloimmortal.com/127.0.0.1#5335 +ipset=/diabloimmortal.com/gfwlist +server=/tnntoday.com/127.0.0.1#5335 +ipset=/tnntoday.com/gfwlist +server=/airtunes.info/127.0.0.1#5335 +ipset=/airtunes.info/gfwlist +server=/alt.com/127.0.0.1#5335 +ipset=/alt.com/gfwlist +server=/airport.brussels/127.0.0.1#5335 +ipset=/airport.brussels/gfwlist +server=/a0pple.net/127.0.0.1#5335 +ipset=/a0pple.net/gfwlist +server=/2022.dev/127.0.0.1#5335 +ipset=/2022.dev/gfwlist +server=/wixapps.net/127.0.0.1#5335 +ipset=/wixapps.net/gfwlist +server=/18avx.com/127.0.0.1#5335 +ipset=/18avx.com/gfwlist +server=/shazam.com/127.0.0.1#5335 +ipset=/shazam.com/gfwlist +server=/huobigroup.com/127.0.0.1#5335 +ipset=/huobigroup.com/gfwlist +server=/eroticbeauties.net/127.0.0.1#5335 +ipset=/eroticbeauties.net/gfwlist +server=/horsedicks.net/127.0.0.1#5335 +ipset=/horsedicks.net/gfwlist +server=/dnsvisa.com/127.0.0.1#5335 +ipset=/dnsvisa.com/gfwlist +server=/appleone.host/127.0.0.1#5335 +ipset=/appleone.host/gfwlist +server=/appleone.guide/127.0.0.1#5335 +ipset=/appleone.guide/gfwlist +server=/paypal-prepagata.com/127.0.0.1#5335 +ipset=/paypal-prepagata.com/gfwlist +server=/terapeack.com/127.0.0.1#5335 +ipset=/terapeack.com/gfwlist +server=/cheapbagshoes.com/127.0.0.1#5335 +ipset=/cheapbagshoes.com/gfwlist +server=/123hplaserjet.com/127.0.0.1#5335 +ipset=/123hplaserjet.com/gfwlist +server=/cdn.jsdelivr.net/127.0.0.1#5335 +ipset=/cdn.jsdelivr.net/gfwlist +server=/appleone.blog/127.0.0.1#5335 +ipset=/appleone.blog/gfwlist +server=/appleone.audio/127.0.0.1#5335 +ipset=/appleone.audio/gfwlist +server=/appletv.wang/127.0.0.1#5335 +ipset=/appletv.wang/gfwlist +server=/shopcustomizedbeats.com/127.0.0.1#5335 +ipset=/shopcustomizedbeats.com/gfwlist +server=/vkmessenger.app/127.0.0.1#5335 +ipset=/vkmessenger.app/gfwlist +server=/appletv.com/127.0.0.1#5335 +ipset=/appletv.com/gfwlist +server=/sevgikurtulmaz.com/127.0.0.1#5335 +ipset=/sevgikurtulmaz.com/gfwlist +server=/kenxxx.com/127.0.0.1#5335 +ipset=/kenxxx.com/gfwlist +server=/redsexhub.com/127.0.0.1#5335 +ipset=/redsexhub.com/gfwlist +server=/paypal-donations.com/127.0.0.1#5335 +ipset=/paypal-donations.com/gfwlist +server=/appleid.berlin/127.0.0.1#5335 +ipset=/appleid.berlin/gfwlist +server=/deeper.com/127.0.0.1#5335 +ipset=/deeper.com/gfwlist +server=/colorfulstage.com/127.0.0.1#5335 +ipset=/colorfulstage.com/gfwlist +server=/microsoft.cz/127.0.0.1#5335 +ipset=/microsoft.cz/gfwlist +server=/lesbianpics.org/127.0.0.1#5335 +ipset=/lesbianpics.org/gfwlist +server=/appleid-iclou.com/127.0.0.1#5335 +ipset=/appleid-iclou.com/gfwlist +server=/appleid-applemx.us/127.0.0.1#5335 +ipset=/appleid-applemx.us/gfwlist +server=/ertk.net/127.0.0.1#5335 +ipset=/ertk.net/gfwlist +server=/the-monster-beats.com/127.0.0.1#5335 +ipset=/the-monster-beats.com/gfwlist +server=/mypornhere.com/127.0.0.1#5335 +ipset=/mypornhere.com/gfwlist +server=/beatswirelesscuffie.com/127.0.0.1#5335 +ipset=/beatswirelesscuffie.com/gfwlist +server=/binance.org/127.0.0.1#5335 +ipset=/binance.org/gfwlist +server=/betternike.com/127.0.0.1#5335 +ipset=/betternike.com/gfwlist +server=/technologyandsociety.org/127.0.0.1#5335 +ipset=/technologyandsociety.org/gfwlist +server=/foxnewsb2b.com/127.0.0.1#5335 +ipset=/foxnewsb2b.com/gfwlist +server=/benaughty.fun/127.0.0.1#5335 +ipset=/benaughty.fun/gfwlist +server=/vfsco.ca/127.0.0.1#5335 +ipset=/vfsco.ca/gfwlist +server=/sexy-babe-pics.com/127.0.0.1#5335 +ipset=/sexy-babe-pics.com/gfwlist +server=/duga.jp/127.0.0.1#5335 +ipset=/duga.jp/gfwlist +server=/facebcook.com/127.0.0.1#5335 +ipset=/facebcook.com/gfwlist +server=/canonproprinters.com/127.0.0.1#5335 +ipset=/canonproprinters.com/gfwlist +server=/beatsbydreonlines-ireland.com/127.0.0.1#5335 +ipset=/beatsbydreonlines-ireland.com/gfwlist +server=/npmjs.com/127.0.0.1#5335 +ipset=/npmjs.com/gfwlist +server=/affect3dstore.com/127.0.0.1#5335 +ipset=/affect3dstore.com/gfwlist +server=/largeporntube.com/127.0.0.1#5335 +ipset=/largeporntube.com/gfwlist +server=/ebay-authenticate.net/127.0.0.1#5335 +ipset=/ebay-authenticate.net/gfwlist +server=/google.co.uk/127.0.0.1#5335 +ipset=/google.co.uk/gfwlist +server=/cuntwars.com/127.0.0.1#5335 +ipset=/cuntwars.com/gfwlist +server=/nationalgeographic.com/127.0.0.1#5335 +ipset=/nationalgeographic.com/gfwlist +server=/amazon.fr/127.0.0.1#5335 +ipset=/amazon.fr/gfwlist +server=/botstop.com/127.0.0.1#5335 +ipset=/botstop.com/gfwlist +server=/arphic.com/127.0.0.1#5335 +ipset=/arphic.com/gfwlist +server=/ibooksauthor.com/127.0.0.1#5335 +ipset=/ibooksauthor.com/gfwlist +server=/wiremoneytoirelandwithxoomeasierandcheaper.com/127.0.0.1#5335 +ipset=/wiremoneytoirelandwithxoomeasierandcheaper.com/gfwlist +server=/wionews.com/127.0.0.1#5335 +ipset=/wionews.com/gfwlist +server=/kindle.com/127.0.0.1#5335 +ipset=/kindle.com/gfwlist +server=/alphabet.no/127.0.0.1#5335 +ipset=/alphabet.no/gfwlist +server=/anon-v.com/127.0.0.1#5335 +ipset=/anon-v.com/gfwlist +server=/bmw.dk/127.0.0.1#5335 +ipset=/bmw.dk/gfwlist +server=/ibook.com/127.0.0.1#5335 +ipset=/ibook.com/gfwlist +server=/ithaisex.com/127.0.0.1#5335 +ipset=/ithaisex.com/gfwlist +server=/magentoliveconference.com/127.0.0.1#5335 +ipset=/magentoliveconference.com/gfwlist +server=/applewallet.com/127.0.0.1#5335 +ipset=/applewallet.com/gfwlist +server=/torrentleen.com/127.0.0.1#5335 +ipset=/torrentleen.com/gfwlist +server=/mywaytopay.info/127.0.0.1#5335 +ipset=/mywaytopay.info/gfwlist +server=/firestonecomercial.com.mx/127.0.0.1#5335 +ipset=/firestonecomercial.com.mx/gfwlist +server=/bondagecomixxx.net/127.0.0.1#5335 +ipset=/bondagecomixxx.net/gfwlist +server=/kmff17.com/127.0.0.1#5335 +ipset=/kmff17.com/gfwlist +server=/applepay.info/127.0.0.1#5335 +ipset=/applepay.info/gfwlist +server=/hentai-books.com/127.0.0.1#5335 +ipset=/hentai-books.com/gfwlist +server=/youtube.co.zw/127.0.0.1#5335 +ipset=/youtube.co.zw/gfwlist +server=/shemaleporntube.tv/127.0.0.1#5335 +ipset=/shemaleporntube.tv/gfwlist +server=/beatsbeatsmonster.com/127.0.0.1#5335 +ipset=/beatsbeatsmonster.com/gfwlist +server=/zind.cloud/127.0.0.1#5335 +ipset=/zind.cloud/gfwlist +server=/easysexporn.com/127.0.0.1#5335 +ipset=/easysexporn.com/gfwlist +server=/apple-pay.com/127.0.0.1#5335 +ipset=/apple-pay.com/gfwlist +server=/needforspeedboost.com/127.0.0.1#5335 +ipset=/needforspeedboost.com/gfwlist +server=/gayboystube.com/127.0.0.1#5335 +ipset=/gayboystube.com/gfwlist +server=/applenews.berlin/127.0.0.1#5335 +ipset=/applenews.berlin/gfwlist +server=/cex.io/127.0.0.1#5335 +ipset=/cex.io/gfwlist +server=/download.visualstudio.microsoft.com/127.0.0.1#5335 +ipset=/download.visualstudio.microsoft.com/gfwlist +server=/pornokrol.com/127.0.0.1#5335 +ipset=/pornokrol.com/gfwlist +server=/nsfwmemes.com/127.0.0.1#5335 +ipset=/nsfwmemes.com/gfwlist +server=/biorxiv.org/127.0.0.1#5335 +ipset=/biorxiv.org/gfwlist +server=/hkopentv.com/127.0.0.1#5335 +ipset=/hkopentv.com/gfwlist +server=/applemusic.wang/127.0.0.1#5335 +ipset=/applemusic.wang/gfwlist +server=/sextreffensite.com/127.0.0.1#5335 +ipset=/sextreffensite.com/gfwlist +server=/espnqa.com/127.0.0.1#5335 +ipset=/espnqa.com/gfwlist +server=/myrewardzone.com/127.0.0.1#5335 +ipset=/myrewardzone.com/gfwlist +server=/beautyandthebeastmusical.co.uk/127.0.0.1#5335 +ipset=/beautyandthebeastmusical.co.uk/gfwlist +server=/applemusic.com/127.0.0.1#5335 +ipset=/applemusic.com/gfwlist +server=/bmw.com.co/127.0.0.1#5335 +ipset=/bmw.com.co/gfwlist +server=/xxxpornzeed.com/127.0.0.1#5335 +ipset=/xxxpornzeed.com/gfwlist +server=/javbangers.com/127.0.0.1#5335 +ipset=/javbangers.com/gfwlist +server=/stackoverflowbusiness.com/127.0.0.1#5335 +ipset=/stackoverflowbusiness.com/gfwlist +server=/applemusic.berlin/127.0.0.1#5335 +ipset=/applemusic.berlin/gfwlist +server=/cheapbeatssale4u.com/127.0.0.1#5335 +ipset=/cheapbeatssale4u.com/gfwlist +server=/rakuten.tw/127.0.0.1#5335 +ipset=/rakuten.tw/gfwlist +server=/verisign.info/127.0.0.1#5335 +ipset=/verisign.info/gfwlist +server=/typekit.net/127.0.0.1#5335 +ipset=/typekit.net/gfwlist +server=/home-made-videos.com/127.0.0.1#5335 +ipset=/home-made-videos.com/gfwlist +server=/fujossy.jp/127.0.0.1#5335 +ipset=/fujossy.jp/gfwlist +server=/blizzcon-a.akamaihd.net/127.0.0.1#5335 +ipset=/blizzcon-a.akamaihd.net/gfwlist +server=/nsimg.net/127.0.0.1#5335 +ipset=/nsimg.net/gfwlist +server=/starwarskids.com/127.0.0.1#5335 +ipset=/starwarskids.com/gfwlist +server=/francecasquebeatssolde.com/127.0.0.1#5335 +ipset=/francecasquebeatssolde.com/gfwlist +server=/ehv.cc/127.0.0.1#5335 +ipset=/ehv.cc/gfwlist +server=/wwwpaypass.com/127.0.0.1#5335 +ipset=/wwwpaypass.com/gfwlist +server=/trycloudflare.com/127.0.0.1#5335 +ipset=/trycloudflare.com/gfwlist +server=/wwwmacbookair.com/127.0.0.1#5335 +ipset=/wwwmacbookair.com/gfwlist +server=/macbooksale.com/127.0.0.1#5335 +ipset=/macbooksale.com/gfwlist +server=/facebook-pmdcenter.org/127.0.0.1#5335 +ipset=/facebook-pmdcenter.org/gfwlist +server=/clipsaoyai.com/127.0.0.1#5335 +ipset=/clipsaoyai.com/gfwlist +server=/gvt3.com/127.0.0.1#5335 +ipset=/gvt3.com/gfwlist +server=/macbookpro.us/127.0.0.1#5335 +ipset=/macbookpro.us/gfwlist +server=/macbookpro.net/127.0.0.1#5335 +ipset=/macbookpro.net/gfwlist +server=/macbookpro.com.au/127.0.0.1#5335 +ipset=/macbookpro.com.au/gfwlist +server=/epochtimes.pl/127.0.0.1#5335 +ipset=/epochtimes.pl/gfwlist +server=/macbookpro.co/127.0.0.1#5335 +ipset=/macbookpro.co/gfwlist +server=/wonporn.net/127.0.0.1#5335 +ipset=/wonporn.net/gfwlist +server=/facebhook.com/127.0.0.1#5335 +ipset=/facebhook.com/gfwlist +server=/macbookair.net/127.0.0.1#5335 +ipset=/macbookair.net/gfwlist +server=/apple.es/127.0.0.1#5335 +ipset=/apple.es/gfwlist +server=/macbookair.es/127.0.0.1#5335 +ipset=/macbookair.es/gfwlist +server=/macbookair.com.au/127.0.0.1#5335 +ipset=/macbookair.com.au/gfwlist +server=/bmwm.com/127.0.0.1#5335 +ipset=/bmwm.com/gfwlist +server=/macbookair.co.kr/127.0.0.1#5335 +ipset=/macbookair.co.kr/gfwlist +server=/redwap-xxx.com/127.0.0.1#5335 +ipset=/redwap-xxx.com/gfwlist +server=/iana.org/127.0.0.1#5335 +ipset=/iana.org/gfwlist +server=/redamateurtube.com/127.0.0.1#5335 +ipset=/redamateurtube.com/gfwlist +server=/blzmedia-a.akamaihd.net/127.0.0.1#5335 +ipset=/blzmedia-a.akamaihd.net/gfwlist +server=/dragonage.com/127.0.0.1#5335 +ipset=/dragonage.com/gfwlist +server=/braintreepayments.org/127.0.0.1#5335 +ipset=/braintreepayments.org/gfwlist +server=/hammerandchisel.ssl.zendesk.com/127.0.0.1#5335 +ipset=/hammerandchisel.ssl.zendesk.com/gfwlist +server=/gfpornbox.com/127.0.0.1#5335 +ipset=/gfpornbox.com/gfwlist +server=/21centuryaccess.com/127.0.0.1#5335 +ipset=/21centuryaccess.com/gfwlist +server=/wwwipodlounge.com/127.0.0.1#5335 +ipset=/wwwipodlounge.com/gfwlist +server=/bmw.be/127.0.0.1#5335 +ipset=/bmw.be/gfwlist +server=/cwcams.com/127.0.0.1#5335 +ipset=/cwcams.com/gfwlist +server=/starfieldtech.com/127.0.0.1#5335 +ipset=/starfieldtech.com/gfwlist +server=/myipod.net/127.0.0.1#5335 +ipset=/myipod.net/gfwlist +server=/bestbuy24x7solutions.com/127.0.0.1#5335 +ipset=/bestbuy24x7solutions.com/gfwlist +server=/zzycdz.com/127.0.0.1#5335 +ipset=/zzycdz.com/gfwlist +server=/thomsonreuters.com.br/127.0.0.1#5335 +ipset=/thomsonreuters.com.br/gfwlist +server=/audiobeatsau.com/127.0.0.1#5335 +ipset=/audiobeatsau.com/gfwlist +server=/ipods.com/127.0.0.1#5335 +ipset=/ipods.com/gfwlist +server=/ipodrocks.com.au/127.0.0.1#5335 +ipset=/ipodrocks.com.au/gfwlist +server=/hplatexknowledgecenter.com/127.0.0.1#5335 +ipset=/hplatexknowledgecenter.com/gfwlist +server=/ipodrip.ca/127.0.0.1#5335 +ipset=/ipodrip.ca/gfwlist +server=/ipodprices.com/127.0.0.1#5335 +ipset=/ipodprices.com/gfwlist +server=/modrinth.com/127.0.0.1#5335 +ipset=/modrinth.com/gfwlist +server=/sourcingforebay.net/127.0.0.1#5335 +ipset=/sourcingforebay.net/gfwlist +server=/allpornsites.net/127.0.0.1#5335 +ipset=/allpornsites.net/gfwlist +server=/ipod.rs/127.0.0.1#5335 +ipset=/ipod.rs/gfwlist +server=/ipod.pk/127.0.0.1#5335 +ipset=/ipod.pk/gfwlist +server=/justporn.com/127.0.0.1#5335 +ipset=/justporn.com/gfwlist +server=/ipod.hk/127.0.0.1#5335 +ipset=/ipod.hk/gfwlist +server=/ipod.gr/127.0.0.1#5335 +ipset=/ipod.gr/gfwlist +server=/ipod.fr/127.0.0.1#5335 +ipset=/ipod.fr/gfwlist +server=/gostosanovinha.com/127.0.0.1#5335 +ipset=/gostosanovinha.com/gfwlist +server=/thinkdifferent.us/127.0.0.1#5335 +ipset=/thinkdifferent.us/gfwlist +server=/coliriodemacho.com.br/127.0.0.1#5335 +ipset=/coliriodemacho.com.br/gfwlist +server=/ipod.de/127.0.0.1#5335 +ipset=/ipod.de/gfwlist +server=/pixiv.net/127.0.0.1#5335 +ipset=/pixiv.net/gfwlist +server=/fastly.net/127.0.0.1#5335 +ipset=/fastly.net/gfwlist +server=/iphone-cd.com/127.0.0.1#5335 +ipset=/iphone-cd.com/gfwlist +server=/canon.com.cy/127.0.0.1#5335 +ipset=/canon.com.cy/gfwlist +server=/vanish.ch/127.0.0.1#5335 +ipset=/vanish.ch/gfwlist +server=/yourmonsterbeats.com/127.0.0.1#5335 +ipset=/yourmonsterbeats.com/gfwlist +server=/sci.hubg.org/127.0.0.1#5335 +ipset=/sci.hubg.org/gfwlist +server=/workers.dev/127.0.0.1#5335 +ipset=/workers.dev/gfwlist +server=/bmw.no/127.0.0.1#5335 +ipset=/bmw.no/gfwlist +server=/cocksuckersguide.com/127.0.0.1#5335 +ipset=/cocksuckersguide.com/gfwlist +server=/foxsportsneworleans.com/127.0.0.1#5335 +ipset=/foxsportsneworleans.com/gfwlist +server=/camdolls.com/127.0.0.1#5335 +ipset=/camdolls.com/gfwlist +server=/steemit.com/127.0.0.1#5335 +ipset=/steemit.com/gfwlist +server=/ipod.com.au/127.0.0.1#5335 +ipset=/ipod.com.au/gfwlist +server=/eamirrorsedge.com/127.0.0.1#5335 +ipset=/eamirrorsedge.com/gfwlist +server=/ipod.co.uk/127.0.0.1#5335 +ipset=/ipod.co.uk/gfwlist +server=/ipod.co/127.0.0.1#5335 +ipset=/ipod.co/gfwlist +server=/igtv.com/127.0.0.1#5335 +ipset=/igtv.com/gfwlist +server=/91rb.net/127.0.0.1#5335 +ipset=/91rb.net/gfwlist +server=/fb.careers/127.0.0.1#5335 +ipset=/fb.careers/gfwlist +server=/sexfilm4free.com/127.0.0.1#5335 +ipset=/sexfilm4free.com/gfwlist +server=/volvobuses.se/127.0.0.1#5335 +ipset=/volvobuses.se/gfwlist +server=/volvopenta.de/127.0.0.1#5335 +ipset=/volvopenta.de/gfwlist +server=/ebuyheadphones.com/127.0.0.1#5335 +ipset=/ebuyheadphones.com/gfwlist +server=/mastercard.com.sg/127.0.0.1#5335 +ipset=/mastercard.com.sg/gfwlist +server=/ipod.ca/127.0.0.1#5335 +ipset=/ipod.ca/gfwlist +server=/palestineremix.com/127.0.0.1#5335 +ipset=/palestineremix.com/gfwlist +server=/mycams.com/127.0.0.1#5335 +ipset=/mycams.com/gfwlist +server=/etvonline.hk/127.0.0.1#5335 +ipset=/etvonline.hk/gfwlist +server=/swingexpert.nl/127.0.0.1#5335 +ipset=/swingexpert.nl/gfwlist +server=/battlefront2.com/127.0.0.1#5335 +ipset=/battlefront2.com/gfwlist +server=/appleclassicipod.com/127.0.0.1#5335 +ipset=/appleclassicipod.com/gfwlist +server=/gannettdigital.com/127.0.0.1#5335 +ipset=/gannettdigital.com/gfwlist +server=/thomsonreuters.com.ar/127.0.0.1#5335 +ipset=/thomsonreuters.com.ar/gfwlist +server=/aplleipods.com/127.0.0.1#5335 +ipset=/aplleipods.com/gfwlist +server=/s2stagehance.com/127.0.0.1#5335 +ipset=/s2stagehance.com/gfwlist +server=/comicscartoonporn.com/127.0.0.1#5335 +ipset=/comicscartoonporn.com/gfwlist +server=/gitlab-static.net/127.0.0.1#5335 +ipset=/gitlab-static.net/gfwlist +server=/bmw-connecteddrive.it/127.0.0.1#5335 +ipset=/bmw-connecteddrive.it/gfwlist +server=/iphonerip.net/127.0.0.1#5335 +ipset=/iphonerip.net/gfwlist +server=/1lib.limited/127.0.0.1#5335 +ipset=/1lib.limited/gfwlist +server=/miniofmonrovia.com/127.0.0.1#5335 +ipset=/miniofmonrovia.com/gfwlist +server=/wireguard.com/127.0.0.1#5335 +ipset=/wireguard.com/gfwlist +server=/newscdn.com.au/127.0.0.1#5335 +ipset=/newscdn.com.au/gfwlist +server=/linetv.tw/127.0.0.1#5335 +ipset=/linetv.tw/gfwlist +server=/hpcustomersupport.net/127.0.0.1#5335 +ipset=/hpcustomersupport.net/gfwlist +server=/iphonegermany.com/127.0.0.1#5335 +ipset=/iphonegermany.com/gfwlist +server=/adobecce.com/127.0.0.1#5335 +ipset=/adobecce.com/gfwlist +server=/durex.cl/127.0.0.1#5335 +ipset=/durex.cl/gfwlist +server=/iphonecases5.com/127.0.0.1#5335 +ipset=/iphonecases5.com/gfwlist +server=/intagrm.com/127.0.0.1#5335 +ipset=/intagrm.com/gfwlist +server=/iphonecase2013.com/127.0.0.1#5335 +ipset=/iphonecase2013.com/gfwlist +server=/iphone5s5case.com/127.0.0.1#5335 +ipset=/iphone5s5case.com/gfwlist +server=/mini.cl/127.0.0.1#5335 +ipset=/mini.cl/gfwlist +server=/xoom.us/127.0.0.1#5335 +ipset=/xoom.us/gfwlist +server=/bronto.com/127.0.0.1#5335 +ipset=/bronto.com/gfwlist +server=/discordstatus.com/127.0.0.1#5335 +ipset=/discordstatus.com/gfwlist +server=/sway-cdn.com/127.0.0.1#5335 +ipset=/sway-cdn.com/gfwlist +server=/bridgestone.co.id/127.0.0.1#5335 +ipset=/bridgestone.co.id/gfwlist +server=/cyber-bay.org/127.0.0.1#5335 +ipset=/cyber-bay.org/gfwlist +server=/megafilmporno.com/127.0.0.1#5335 +ipset=/megafilmporno.com/gfwlist +server=/forzaracingchampionship.com/127.0.0.1#5335 +ipset=/forzaracingchampionship.com/gfwlist +server=/wwwebay.net/127.0.0.1#5335 +ipset=/wwwebay.net/gfwlist +server=/arabysexy.com/127.0.0.1#5335 +ipset=/arabysexy.com/gfwlist +server=/vs-hls-pushb-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/vs-hls-pushb-uk-live.akamaized.net/gfwlist +server=/viu.com/127.0.0.1#5335 +ipset=/viu.com/gfwlist +server=/karupspc.com/127.0.0.1#5335 +ipset=/karupspc.com/gfwlist +server=/iphone.rs/127.0.0.1#5335 +ipset=/iphone.rs/gfwlist +server=/hitomi.la/127.0.0.1#5335 +ipset=/hitomi.la/gfwlist +server=/iphone.pt/127.0.0.1#5335 +ipset=/iphone.pt/gfwlist +server=/opensea.io/127.0.0.1#5335 +ipset=/opensea.io/gfwlist +server=/vipissy.com/127.0.0.1#5335 +ipset=/vipissy.com/gfwlist +server=/awsautoscaling.com/127.0.0.1#5335 +ipset=/awsautoscaling.com/gfwlist +server=/warroom.org/127.0.0.1#5335 +ipset=/warroom.org/gfwlist +server=/ikea.com.au/127.0.0.1#5335 +ipset=/ikea.com.au/gfwlist +server=/uchicago.edu/127.0.0.1#5335 +ipset=/uchicago.edu/gfwlist +server=/iphone.com.gr/127.0.0.1#5335 +ipset=/iphone.com.gr/gfwlist +server=/myminisexdoll.com/127.0.0.1#5335 +ipset=/myminisexdoll.com/gfwlist +server=/scholar.google.co.nz/127.0.0.1#5335 +ipset=/scholar.google.co.nz/gfwlist +server=/realitykings.com/127.0.0.1#5335 +ipset=/realitykings.com/gfwlist +server=/hulupurchase.com/127.0.0.1#5335 +ipset=/hulupurchase.com/gfwlist +server=/drebeatsbydreoutlet.com/127.0.0.1#5335 +ipset=/drebeatsbydreoutlet.com/gfwlist +server=/iphone.com.au/127.0.0.1#5335 +ipset=/iphone.com.au/gfwlist +server=/jpboy1069.net/127.0.0.1#5335 +ipset=/jpboy1069.net/gfwlist +server=/alphassl.com/127.0.0.1#5335 +ipset=/alphassl.com/gfwlist +server=/e-hentai.org/127.0.0.1#5335 +ipset=/e-hentai.org/gfwlist +server=/cdn77.com/127.0.0.1#5335 +ipset=/cdn77.com/gfwlist +server=/sonypicturesstudios.com/127.0.0.1#5335 +ipset=/sonypicturesstudios.com/gfwlist +server=/feacebook.com/127.0.0.1#5335 +ipset=/feacebook.com/gfwlist +server=/ampproject.org/127.0.0.1#5335 +ipset=/ampproject.org/gfwlist +server=/iphone-yh.com/127.0.0.1#5335 +ipset=/iphone-yh.com/gfwlist +server=/iphone-vip3.com/127.0.0.1#5335 +ipset=/iphone-vip3.com/gfwlist +server=/rabbitscams.sex/127.0.0.1#5335 +ipset=/rabbitscams.sex/gfwlist +server=/iphone-vip2.com/127.0.0.1#5335 +ipset=/iphone-vip2.com/gfwlist +server=/nentindo.net/127.0.0.1#5335 +ipset=/nentindo.net/gfwlist +server=/tubxporn.com/127.0.0.1#5335 +ipset=/tubxporn.com/gfwlist +server=/grooby.com/127.0.0.1#5335 +ipset=/grooby.com/gfwlist +server=/iphone-cn.com/127.0.0.1#5335 +ipset=/iphone-cn.com/gfwlist +server=/facfacebook.com/127.0.0.1#5335 +ipset=/facfacebook.com/gfwlist +server=/hf-iphone.com/127.0.0.1#5335 +ipset=/hf-iphone.com/gfwlist +server=/npr.org/127.0.0.1#5335 +ipset=/npr.org/gfwlist +server=/hebiphone.com/127.0.0.1#5335 +ipset=/hebiphone.com/gfwlist +server=/pornvibe.org/127.0.0.1#5335 +ipset=/pornvibe.org/gfwlist +server=/dgaqp.com/127.0.0.1#5335 +ipset=/dgaqp.com/gfwlist +server=/udtrucksmeena.com/127.0.0.1#5335 +ipset=/udtrucksmeena.com/gfwlist +server=/fundaiphone5s.com/127.0.0.1#5335 +ipset=/fundaiphone5s.com/gfwlist +server=/bestjapanesepornsites.com/127.0.0.1#5335 +ipset=/bestjapanesepornsites.com/gfwlist +server=/cloudflarepreview.com/127.0.0.1#5335 +ipset=/cloudflarepreview.com/gfwlist +server=/91porny.com/127.0.0.1#5335 +ipset=/91porny.com/gfwlist +server=/starbucks.de/127.0.0.1#5335 +ipset=/starbucks.de/gfwlist +server=/bowlroll.net/127.0.0.1#5335 +ipset=/bowlroll.net/gfwlist +server=/symcd.com/127.0.0.1#5335 +ipset=/symcd.com/gfwlist +server=/sneakerpage.net/127.0.0.1#5335 +ipset=/sneakerpage.net/gfwlist +server=/perfectgonzo.com/127.0.0.1#5335 +ipset=/perfectgonzo.com/gfwlist +server=/9anime.id/127.0.0.1#5335 +ipset=/9anime.id/gfwlist +server=/ntdtv.co.kr/127.0.0.1#5335 +ipset=/ntdtv.co.kr/gfwlist +server=/bloggrowup.com/127.0.0.1#5335 +ipset=/bloggrowup.com/gfwlist +server=/fbacebook.com/127.0.0.1#5335 +ipset=/fbacebook.com/gfwlist +server=/geek-squad-support.com/127.0.0.1#5335 +ipset=/geek-squad-support.com/gfwlist +server=/businessinsider.sg/127.0.0.1#5335 +ipset=/businessinsider.sg/gfwlist +server=/itunesstore.co/127.0.0.1#5335 +ipset=/itunesstore.co/gfwlist +server=/ipadmini.com.lk/127.0.0.1#5335 +ipset=/ipadmini.com.lk/gfwlist +server=/bbcverticals.com/127.0.0.1#5335 +ipset=/bbcverticals.com/gfwlist +server=/barefootnetworks.com/127.0.0.1#5335 +ipset=/barefootnetworks.com/gfwlist +server=/ipadair.fr/127.0.0.1#5335 +ipset=/ipadair.fr/gfwlist +server=/gettyimages.com.br/127.0.0.1#5335 +ipset=/gettyimages.com.br/gfwlist +server=/minimotoringrewards.com/127.0.0.1#5335 +ipset=/minimotoringrewards.com/gfwlist +server=/howtogetmo.co.uk/127.0.0.1#5335 +ipset=/howtogetmo.co.uk/gfwlist +server=/yandex.lv/127.0.0.1#5335 +ipset=/yandex.lv/gfwlist +server=/analsaga.com/127.0.0.1#5335 +ipset=/analsaga.com/gfwlist +server=/adultgeek.net/127.0.0.1#5335 +ipset=/adultgeek.net/gfwlist +server=/ipadair.com.br/127.0.0.1#5335 +ipset=/ipadair.com.br/gfwlist +server=/scholar.google.com.co/127.0.0.1#5335 +ipset=/scholar.google.com.co/gfwlist +server=/cloudflareresolve.com/127.0.0.1#5335 +ipset=/cloudflareresolve.com/gfwlist +server=/4tube.com/127.0.0.1#5335 +ipset=/4tube.com/gfwlist +server=/mini.co.za/127.0.0.1#5335 +ipset=/mini.co.za/gfwlist +server=/oxfordlawtrove.com/127.0.0.1#5335 +ipset=/oxfordlawtrove.com/gfwlist +server=/xacmbq.xyz/127.0.0.1#5335 +ipset=/xacmbq.xyz/gfwlist +server=/svpply.com/127.0.0.1#5335 +ipset=/svpply.com/gfwlist +server=/ipadair.cm/127.0.0.1#5335 +ipset=/ipadair.cm/gfwlist +server=/electronicarts.fr/127.0.0.1#5335 +ipset=/electronicarts.fr/gfwlist +server=/dukgo.com/127.0.0.1#5335 +ipset=/dukgo.com/gfwlist +server=/zlibcdn.com/127.0.0.1#5335 +ipset=/zlibcdn.com/gfwlist +server=/ipad.host/127.0.0.1#5335 +ipset=/ipad.host/gfwlist +server=/camvideoshub.com/127.0.0.1#5335 +ipset=/camvideoshub.com/gfwlist +server=/pornky.com/127.0.0.1#5335 +ipset=/pornky.com/gfwlist +server=/fbthirdpartypixel.org/127.0.0.1#5335 +ipset=/fbthirdpartypixel.org/gfwlist +server=/steamcdn-a.akamaihd.net/127.0.0.1#5335 +ipset=/steamcdn-a.akamaihd.net/gfwlist +server=/tiresplus.com/127.0.0.1#5335 +ipset=/tiresplus.com/gfwlist +server=/ebaynow.com/127.0.0.1#5335 +ipset=/ebaynow.com/gfwlist +server=/fcacebook.com/127.0.0.1#5335 +ipset=/fcacebook.com/gfwlist +server=/quovadisglobal.com/127.0.0.1#5335 +ipset=/quovadisglobal.com/gfwlist +server=/ebookforipad.com/127.0.0.1#5335 +ipset=/ebookforipad.com/gfwlist +server=/imac.rs/127.0.0.1#5335 +ipset=/imac.rs/gfwlist +server=/kindleproject.com/127.0.0.1#5335 +ipset=/kindleproject.com/gfwlist +server=/futureofbusinesssurvey.org/127.0.0.1#5335 +ipset=/futureofbusinesssurvey.org/gfwlist +server=/itunes.hk/127.0.0.1#5335 +ipset=/itunes.hk/gfwlist +server=/hpofficejetprinter.com/127.0.0.1#5335 +ipset=/hpofficejetprinter.com/gfwlist +server=/bbyurl.us/127.0.0.1#5335 +ipset=/bbyurl.us/gfwlist +server=/monsterbeatsbydre2015.com/127.0.0.1#5335 +ipset=/monsterbeatsbydre2015.com/gfwlist +server=/imac.gr/127.0.0.1#5335 +ipset=/imac.gr/gfwlist +server=/julesjordan.com/127.0.0.1#5335 +ipset=/julesjordan.com/gfwlist +server=/imac.co.nz/127.0.0.1#5335 +ipset=/imac.co.nz/gfwlist +server=/bgr.in/127.0.0.1#5335 +ipset=/bgr.in/gfwlist +server=/ma1lib.org/127.0.0.1#5335 +ipset=/ma1lib.org/gfwlist +server=/hentai-fun.com/127.0.0.1#5335 +ipset=/hentai-fun.com/gfwlist +server=/xxxvideoszoo.com/127.0.0.1#5335 +ipset=/xxxvideoszoo.com/gfwlist +server=/adobeplatinumclub.com/127.0.0.1#5335 +ipset=/adobeplatinumclub.com/gfwlist +server=/apple-imac.com/127.0.0.1#5335 +ipset=/apple-imac.com/gfwlist +server=/osapublishing.org/127.0.0.1#5335 +ipset=/osapublishing.org/gfwlist +server=/appstore.hk/127.0.0.1#5335 +ipset=/appstore.hk/gfwlist +server=/bmwgroupfs.com/127.0.0.1#5335 +ipset=/bmwgroupfs.com/gfwlist +server=/e122475.dscg.akamaiedge.net/127.0.0.1#5335 +ipset=/e122475.dscg.akamaiedge.net/gfwlist +server=/sex-young.com/127.0.0.1#5335 +ipset=/sex-young.com/gfwlist +server=/jmcomic1.mobi/127.0.0.1#5335 +ipset=/jmcomic1.mobi/gfwlist +server=/pvzheroes.com/127.0.0.1#5335 +ipset=/pvzheroes.com/gfwlist +server=/persagg.com/127.0.0.1#5335 +ipset=/persagg.com/gfwlist +server=/appsto.re/127.0.0.1#5335 +ipset=/appsto.re/gfwlist +server=/dungeonkeeper.cn/127.0.0.1#5335 +ipset=/dungeonkeeper.cn/gfwlist +server=/jafgrown.com/127.0.0.1#5335 +ipset=/jafgrown.com/gfwlist +server=/foxporns.com/127.0.0.1#5335 +ipset=/foxporns.com/gfwlist +server=/erotichdworld.com/127.0.0.1#5335 +ipset=/erotichdworld.com/gfwlist +server=/applestorepro.eu/127.0.0.1#5335 +ipset=/applestorepro.eu/gfwlist +server=/handjobhub.com/127.0.0.1#5335 +ipset=/handjobhub.com/gfwlist +server=/applestore.net/127.0.0.1#5335 +ipset=/applestore.net/gfwlist +server=/imtagram.com/127.0.0.1#5335 +ipset=/imtagram.com/gfwlist +server=/applestore.kr/127.0.0.1#5335 +ipset=/applestore.kr/gfwlist +server=/applestore.hk/127.0.0.1#5335 +ipset=/applestore.hk/gfwlist +server=/applestore.com.sn/127.0.0.1#5335 +ipset=/applestore.com.sn/gfwlist +server=/bmw-motorrad.co.kr/127.0.0.1#5335 +ipset=/bmw-motorrad.co.kr/gfwlist +server=/microsoftsilverlight.net/127.0.0.1#5335 +ipset=/microsoftsilverlight.net/gfwlist +server=/tiny4k.com/127.0.0.1#5335 +ipset=/tiny4k.com/gfwlist +server=/i-mobile.co.jp/127.0.0.1#5335 +ipset=/i-mobile.co.jp/gfwlist +server=/applestore.com.ph/127.0.0.1#5335 +ipset=/applestore.com.ph/gfwlist +server=/applestore.com.jo/127.0.0.1#5335 +ipset=/applestore.com.jo/gfwlist +server=/applestore.com.hr/127.0.0.1#5335 +ipset=/applestore.com.hr/gfwlist +server=/applestore.com.gr/127.0.0.1#5335 +ipset=/applestore.com.gr/gfwlist +server=/kkbox.com.tw/127.0.0.1#5335 +ipset=/kkbox.com.tw/gfwlist +server=/mtao.fun/127.0.0.1#5335 +ipset=/mtao.fun/gfwlist +server=/severeporn.com/127.0.0.1#5335 +ipset=/severeporn.com/gfwlist +server=/applestore.com/127.0.0.1#5335 +ipset=/applestore.com/gfwlist +server=/matrix.org/127.0.0.1#5335 +ipset=/matrix.org/gfwlist +server=/froogle.com/127.0.0.1#5335 +ipset=/froogle.com/gfwlist +server=/apisof.net/127.0.0.1#5335 +ipset=/apisof.net/gfwlist +server=/pornbrb.com/127.0.0.1#5335 +ipset=/pornbrb.com/gfwlist +server=/nikehightops.com/127.0.0.1#5335 +ipset=/nikehightops.com/gfwlist +server=/volvogroup.be/127.0.0.1#5335 +ipset=/volvogroup.be/gfwlist +server=/icloudmail.net/127.0.0.1#5335 +ipset=/icloudmail.net/gfwlist +server=/whatsapp.net/127.0.0.1#5335 +ipset=/whatsapp.net/gfwlist +server=/paypal.jp/127.0.0.1#5335 +ipset=/paypal.jp/gfwlist +server=/apple-store.net/127.0.0.1#5335 +ipset=/apple-store.net/gfwlist +server=/mypearsonenglish.ch/127.0.0.1#5335 +ipset=/mypearsonenglish.ch/gfwlist +server=/msocsp.com/127.0.0.1#5335 +ipset=/msocsp.com/gfwlist +server=/uusexdoll.com/127.0.0.1#5335 +ipset=/uusexdoll.com/gfwlist +server=/apple.xn--fiqs8s/127.0.0.1#5335 +ipset=/apple.xn--fiqs8s/gfwlist +server=/apple.xn--czr694b/127.0.0.1#5335 +ipset=/apple.xn--czr694b/gfwlist +server=/youtube.cat/127.0.0.1#5335 +ipset=/youtube.cat/gfwlist +server=/finish.ro/127.0.0.1#5335 +ipset=/finish.ro/gfwlist +server=/apple.tw/127.0.0.1#5335 +ipset=/apple.tw/gfwlist +server=/ikea.do/127.0.0.1#5335 +ipset=/ikea.do/gfwlist +server=/bayareabmw.com/127.0.0.1#5335 +ipset=/bayareabmw.com/gfwlist +server=/youtube.lk/127.0.0.1#5335 +ipset=/youtube.lk/gfwlist +server=/porn62.com/127.0.0.1#5335 +ipset=/porn62.com/gfwlist +server=/longtailvideo.com/127.0.0.1#5335 +ipset=/longtailvideo.com/gfwlist +server=/minibrossard.ca/127.0.0.1#5335 +ipset=/minibrossard.ca/gfwlist +server=/apple.tt/127.0.0.1#5335 +ipset=/apple.tt/gfwlist +server=/apple.so/127.0.0.1#5335 +ipset=/apple.so/gfwlist +server=/facebdok.com/127.0.0.1#5335 +ipset=/facebdok.com/gfwlist +server=/apple.sk/127.0.0.1#5335 +ipset=/apple.sk/gfwlist +server=/instagy.com/127.0.0.1#5335 +ipset=/instagy.com/gfwlist +server=/appledaily.hk/127.0.0.1#5335 +ipset=/appledaily.hk/gfwlist +server=/charlotte-anime.jp/127.0.0.1#5335 +ipset=/charlotte-anime.jp/gfwlist +server=/bmw-motorcycle.com/127.0.0.1#5335 +ipset=/bmw-motorcycle.com/gfwlist +server=/verpeliculasporno.gratis/127.0.0.1#5335 +ipset=/verpeliculasporno.gratis/gfwlist +server=/apple.rs/127.0.0.1#5335 +ipset=/apple.rs/gfwlist +server=/xxxvideo.vip/127.0.0.1#5335 +ipset=/xxxvideo.vip/gfwlist +server=/apple.pl/127.0.0.1#5335 +ipset=/apple.pl/gfwlist +server=/beatsforcheap-usa.com/127.0.0.1#5335 +ipset=/beatsforcheap-usa.com/gfwlist +server=/disney.co.il/127.0.0.1#5335 +ipset=/disney.co.il/gfwlist +server=/apple.net.gr/127.0.0.1#5335 +ipset=/apple.net.gr/gfwlist +server=/fanaken.com/127.0.0.1#5335 +ipset=/fanaken.com/gfwlist +server=/petitehdporn.com/127.0.0.1#5335 +ipset=/petitehdporn.com/gfwlist +server=/tg.dev/127.0.0.1#5335 +ipset=/tg.dev/gfwlist +server=/volvotrucks.co.na/127.0.0.1#5335 +ipset=/volvotrucks.co.na/gfwlist +server=/dynacw.co.jp/127.0.0.1#5335 +ipset=/dynacw.co.jp/gfwlist +server=/geeksquadforums.com/127.0.0.1#5335 +ipset=/geeksquadforums.com/gfwlist +server=/apple.lv/127.0.0.1#5335 +ipset=/apple.lv/gfwlist +server=/d100.net/127.0.0.1#5335 +ipset=/d100.net/gfwlist +server=/apple.lt/127.0.0.1#5335 +ipset=/apple.lt/gfwlist +server=/apple.jp/127.0.0.1#5335 +ipset=/apple.jp/gfwlist +server=/beatsbydresdanmark.net/127.0.0.1#5335 +ipset=/beatsbydresdanmark.net/gfwlist +server=/login-paypal.com/127.0.0.1#5335 +ipset=/login-paypal.com/gfwlist +server=/ultimaforever.com/127.0.0.1#5335 +ipset=/ultimaforever.com/gfwlist +server=/bigboobsonline.org/127.0.0.1#5335 +ipset=/bigboobsonline.org/gfwlist +server=/mediasama.com/127.0.0.1#5335 +ipset=/mediasama.com/gfwlist +server=/minitroisrivieres.ca/127.0.0.1#5335 +ipset=/minitroisrivieres.ca/gfwlist +server=/pearsoncred.com/127.0.0.1#5335 +ipset=/pearsoncred.com/gfwlist +server=/mypornvid.fun/127.0.0.1#5335 +ipset=/mypornvid.fun/gfwlist +server=/opengw.net/127.0.0.1#5335 +ipset=/opengw.net/gfwlist +server=/makeeu.com/127.0.0.1#5335 +ipset=/makeeu.com/gfwlist +server=/mybeatscheapbydre.com/127.0.0.1#5335 +ipset=/mybeatscheapbydre.com/gfwlist +server=/macbookair.kr/127.0.0.1#5335 +ipset=/macbookair.kr/gfwlist +server=/lp99.pw/127.0.0.1#5335 +ipset=/lp99.pw/gfwlist +server=/ieeeaps.org/127.0.0.1#5335 +ipset=/ieeeaps.org/gfwlist +server=/faptitans.com/127.0.0.1#5335 +ipset=/faptitans.com/gfwlist +server=/fecebook.net/127.0.0.1#5335 +ipset=/fecebook.net/gfwlist +server=/apple.co.mz/127.0.0.1#5335 +ipset=/apple.co.mz/gfwlist +server=/dotfacebook.net/127.0.0.1#5335 +ipset=/dotfacebook.net/gfwlist +server=/yinac.xyz/127.0.0.1#5335 +ipset=/yinac.xyz/gfwlist +server=/digitaloceanspaces.com/127.0.0.1#5335 +ipset=/digitaloceanspaces.com/gfwlist +server=/rewrite-anime.tv/127.0.0.1#5335 +ipset=/rewrite-anime.tv/gfwlist +server=/epochtimes.co.il/127.0.0.1#5335 +ipset=/epochtimes.co.il/gfwlist +server=/boyvid.com/127.0.0.1#5335 +ipset=/boyvid.com/gfwlist +server=/apple.co.cr/127.0.0.1#5335 +ipset=/apple.co.cr/gfwlist +server=/pornfinder.biz/127.0.0.1#5335 +ipset=/pornfinder.biz/gfwlist +server=/bridgestoneamericas.com/127.0.0.1#5335 +ipset=/bridgestoneamericas.com/gfwlist +server=/assetsadobe.com/127.0.0.1#5335 +ipset=/assetsadobe.com/gfwlist +server=/momami18.livedoor.blog/127.0.0.1#5335 +ipset=/momami18.livedoor.blog/gfwlist +server=/avxlive.icu/127.0.0.1#5335 +ipset=/avxlive.icu/gfwlist +server=/aboutfacebook.com/127.0.0.1#5335 +ipset=/aboutfacebook.com/gfwlist +server=/air-nike-shoes.com/127.0.0.1#5335 +ipset=/air-nike-shoes.com/gfwlist +server=/etviet.com/127.0.0.1#5335 +ipset=/etviet.com/gfwlist +server=/verisign.tw/127.0.0.1#5335 +ipset=/verisign.tw/gfwlist +server=/oxfordmedicine.com/127.0.0.1#5335 +ipset=/oxfordmedicine.com/gfwlist +server=/ruleporn.com/127.0.0.1#5335 +ipset=/ruleporn.com/gfwlist +server=/ebay.ca/127.0.0.1#5335 +ipset=/ebay.ca/gfwlist +server=/the-tls.co.uk/127.0.0.1#5335 +ipset=/the-tls.co.uk/gfwlist +server=/logitech.io/127.0.0.1#5335 +ipset=/logitech.io/gfwlist +server=/pornhoho.com/127.0.0.1#5335 +ipset=/pornhoho.com/gfwlist +server=/itunesu.com/127.0.0.1#5335 +ipset=/itunesu.com/gfwlist +server=/humblebundle.com/127.0.0.1#5335 +ipset=/humblebundle.com/gfwlist +server=/punishworld.com/127.0.0.1#5335 +ipset=/punishworld.com/gfwlist +server=/itunesradio.tv/127.0.0.1#5335 +ipset=/itunesradio.tv/gfwlist +server=/verisign.us/127.0.0.1#5335 +ipset=/verisign.us/gfwlist +server=/rumble.com/127.0.0.1#5335 +ipset=/rumble.com/gfwlist +server=/itunesradio.rio/127.0.0.1#5335 +ipset=/itunesradio.rio/gfwlist +server=/itunesradio.com/127.0.0.1#5335 +ipset=/itunesradio.com/gfwlist +server=/ituneslatino.com/127.0.0.1#5335 +ipset=/ituneslatino.com/gfwlist +server=/yahoo.com.gi/127.0.0.1#5335 +ipset=/yahoo.com.gi/gfwlist +server=/itunesiradio.com/127.0.0.1#5335 +ipset=/itunesiradio.com/gfwlist +server=/bmw-connecteddrive.si/127.0.0.1#5335 +ipset=/bmw-connecteddrive.si/gfwlist +server=/itunes.rio/127.0.0.1#5335 +ipset=/itunes.rio/gfwlist +server=/imgurinc.com/127.0.0.1#5335 +ipset=/imgurinc.com/gfwlist +server=/alphera.de/127.0.0.1#5335 +ipset=/alphera.de/gfwlist +server=/tubsexer.com/127.0.0.1#5335 +ipset=/tubsexer.com/gfwlist +server=/mini.pt/127.0.0.1#5335 +ipset=/mini.pt/gfwlist +server=/myfoxsanfran.com/127.0.0.1#5335 +ipset=/myfoxsanfran.com/gfwlist +server=/baraero.com/127.0.0.1#5335 +ipset=/baraero.com/gfwlist +server=/vklive.app/127.0.0.1#5335 +ipset=/vklive.app/gfwlist +server=/hpeprintcenter.com/127.0.0.1#5335 +ipset=/hpeprintcenter.com/gfwlist +server=/myfoxdfw.com/127.0.0.1#5335 +ipset=/myfoxdfw.com/gfwlist +server=/quantil.com/127.0.0.1#5335 +ipset=/quantil.com/gfwlist +server=/itunes.co.th/127.0.0.1#5335 +ipset=/itunes.co.th/gfwlist +server=/javporn.ws/127.0.0.1#5335 +ipset=/javporn.ws/gfwlist +server=/mmdnn.com/127.0.0.1#5335 +ipset=/mmdnn.com/gfwlist +server=/google.com.sb/127.0.0.1#5335 +ipset=/google.com.sb/gfwlist +server=/fi11av1.com/127.0.0.1#5335 +ipset=/fi11av1.com/gfwlist +server=/realtype.jp/127.0.0.1#5335 +ipset=/realtype.jp/gfwlist +server=/mini.com.mx/127.0.0.1#5335 +ipset=/mini.com.mx/gfwlist +server=/livesex.com/127.0.0.1#5335 +ipset=/livesex.com/gfwlist +server=/itun.es/127.0.0.1#5335 +ipset=/itun.es/gfwlist +server=/pixfs.net/127.0.0.1#5335 +ipset=/pixfs.net/gfwlist +server=/12joursdecadeauxdeitunes.com/127.0.0.1#5335 +ipset=/12joursdecadeauxdeitunes.com/gfwlist +server=/hk1lib.org/127.0.0.1#5335 +ipset=/hk1lib.org/gfwlist +server=/12diasderegalosdeitunes.hn/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.hn/gfwlist +server=/disneyredirects.com/127.0.0.1#5335 +ipset=/disneyredirects.com/gfwlist +server=/hairynature.com/127.0.0.1#5335 +ipset=/hairynature.com/gfwlist +server=/pornovideoshub.com/127.0.0.1#5335 +ipset=/pornovideoshub.com/gfwlist +server=/cheapbeatsbydr.com/127.0.0.1#5335 +ipset=/cheapbeatsbydr.com/gfwlist +server=/fecbooc.com/127.0.0.1#5335 +ipset=/fecbooc.com/gfwlist +server=/wsjshop.com/127.0.0.1#5335 +ipset=/wsjshop.com/gfwlist +server=/12diasderegalosdeitunes.cr/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.cr/gfwlist +server=/originalindianporn.com/127.0.0.1#5335 +ipset=/originalindianporn.com/gfwlist +server=/beatsbydrefrcasquepascher.com/127.0.0.1#5335 +ipset=/beatsbydrefrcasquepascher.com/gfwlist +server=/xxbrits.com/127.0.0.1#5335 +ipset=/xxbrits.com/gfwlist +server=/fetishshrine.com/127.0.0.1#5335 +ipset=/fetishshrine.com/gfwlist +server=/sinoinsider.com/127.0.0.1#5335 +ipset=/sinoinsider.com/gfwlist +server=/12diasderegalosdeitunes.cl/127.0.0.1#5335 +ipset=/12diasderegalosdeitunes.cl/gfwlist +server=/foxnews.com/127.0.0.1#5335 +ipset=/foxnews.com/gfwlist +server=/iloveprettylolimm.com/127.0.0.1#5335 +ipset=/iloveprettylolimm.com/gfwlist +server=/mylcloud.net/127.0.0.1#5335 +ipset=/mylcloud.net/gfwlist +server=/ingkacentres.com/127.0.0.1#5335 +ipset=/ingkacentres.com/gfwlist +server=/easportsfootballclub.com/127.0.0.1#5335 +ipset=/easportsfootballclub.com/gfwlist +server=/prepsure.com/127.0.0.1#5335 +ipset=/prepsure.com/gfwlist +server=/myicloud.net/127.0.0.1#5335 +ipset=/myicloud.net/gfwlist +server=/myferrariheadphones.com/127.0.0.1#5335 +ipset=/myferrariheadphones.com/gfwlist +server=/disneyplus.com.ssl.sc.omtrdc.net/127.0.0.1#5335 +ipset=/disneyplus.com.ssl.sc.omtrdc.net/gfwlist +server=/de1lib.org/127.0.0.1#5335 +ipset=/de1lib.org/gfwlist +server=/icloudsecure.net/127.0.0.1#5335 +ipset=/icloudsecure.net/gfwlist +server=/multporn.net/127.0.0.1#5335 +ipset=/multporn.net/gfwlist +server=/globalsign.be/127.0.0.1#5335 +ipset=/globalsign.be/gfwlist +server=/storesense.com/127.0.0.1#5335 +ipset=/storesense.com/gfwlist +server=/youtubego.com/127.0.0.1#5335 +ipset=/youtubego.com/gfwlist +server=/foxnews.org/127.0.0.1#5335 +ipset=/foxnews.org/gfwlist +server=/directv.com/127.0.0.1#5335 +ipset=/directv.com/gfwlist +server=/macbookpros.com/127.0.0.1#5335 +ipset=/macbookpros.com/gfwlist +server=/freebdsmxxx.org/127.0.0.1#5335 +ipset=/freebdsmxxx.org/gfwlist +server=/arzon.jp/127.0.0.1#5335 +ipset=/arzon.jp/gfwlist +server=/youtube.com.ee/127.0.0.1#5335 +ipset=/youtube.com.ee/gfwlist +server=/yahoo.com.fj/127.0.0.1#5335 +ipset=/yahoo.com.fj/gfwlist +server=/microad.jp/127.0.0.1#5335 +ipset=/microad.jp/gfwlist +server=/foxdigitalmovies.com/127.0.0.1#5335 +ipset=/foxdigitalmovies.com/gfwlist +server=/veet.at/127.0.0.1#5335 +ipset=/veet.at/gfwlist +server=/icloudnet.net/127.0.0.1#5335 +ipset=/icloudnet.net/gfwlist +server=/icloudbrowser.net/127.0.0.1#5335 +ipset=/icloudbrowser.net/gfwlist +server=/facebook.hu/127.0.0.1#5335 +ipset=/facebook.hu/gfwlist +server=/icloud.vn/127.0.0.1#5335 +ipset=/icloud.vn/gfwlist +server=/sexsex1.com/127.0.0.1#5335 +ipset=/sexsex1.com/gfwlist +server=/disneymagicmoments.co.il/127.0.0.1#5335 +ipset=/disneymagicmoments.co.il/gfwlist +server=/hotamateurblowjobs.com/127.0.0.1#5335 +ipset=/hotamateurblowjobs.com/gfwlist +server=/girlspoopingtube.com/127.0.0.1#5335 +ipset=/girlspoopingtube.com/gfwlist +server=/icloud.pt/127.0.0.1#5335 +ipset=/icloud.pt/gfwlist +server=/avstar03.me/127.0.0.1#5335 +ipset=/avstar03.me/gfwlist +server=/icloud.om/127.0.0.1#5335 +ipset=/icloud.om/gfwlist +server=/vrcams.io/127.0.0.1#5335 +ipset=/vrcams.io/gfwlist +server=/icloud.ie/127.0.0.1#5335 +ipset=/icloud.ie/gfwlist +server=/canon.dk/127.0.0.1#5335 +ipset=/canon.dk/gfwlist +server=/henti-night.com/127.0.0.1#5335 +ipset=/henti-night.com/gfwlist +server=/mastercard.co.jp/127.0.0.1#5335 +ipset=/mastercard.co.jp/gfwlist +server=/older-women-movies.com/127.0.0.1#5335 +ipset=/older-women-movies.com/gfwlist +server=/instawank.com/127.0.0.1#5335 +ipset=/instawank.com/gfwlist +server=/mi9.com.au/127.0.0.1#5335 +ipset=/mi9.com.au/gfwlist +server=/supportfacebook.com/127.0.0.1#5335 +ipset=/supportfacebook.com/gfwlist +server=/bmw-connecteddrive.de/127.0.0.1#5335 +ipset=/bmw-connecteddrive.de/gfwlist +server=/vrsmash.com/127.0.0.1#5335 +ipset=/vrsmash.com/gfwlist +server=/alljapanesepass.com/127.0.0.1#5335 +ipset=/alljapanesepass.com/gfwlist +server=/mask-h2.icloud.com/127.0.0.1#5335 +ipset=/mask-h2.icloud.com/gfwlist +server=/facecook.com/127.0.0.1#5335 +ipset=/facecook.com/gfwlist +server=/scp-wiki.net/127.0.0.1#5335 +ipset=/scp-wiki.net/gfwlist +server=/wholesalefine.com/127.0.0.1#5335 +ipset=/wholesalefine.com/gfwlist +server=/bmwi.ca/127.0.0.1#5335 +ipset=/bmwi.ca/gfwlist +server=/wholesale-exporter1.com/127.0.0.1#5335 +ipset=/wholesale-exporter1.com/gfwlist +server=/digicert-validation.com/127.0.0.1#5335 +ipset=/digicert-validation.com/gfwlist +server=/kyurem.com/127.0.0.1#5335 +ipset=/kyurem.com/gfwlist +server=/foxsports-chicago.com/127.0.0.1#5335 +ipset=/foxsports-chicago.com/gfwlist +server=/canon.com.hk/127.0.0.1#5335 +ipset=/canon.com.hk/gfwlist +server=/hellosmartbook.com/127.0.0.1#5335 +ipset=/hellosmartbook.com/gfwlist +server=/online-instagram.com/127.0.0.1#5335 +ipset=/online-instagram.com/gfwlist +server=/alphera.my/127.0.0.1#5335 +ipset=/alphera.my/gfwlist +server=/nervanasys.com/127.0.0.1#5335 +ipset=/nervanasys.com/gfwlist +server=/advancediddetection.com/127.0.0.1#5335 +ipset=/advancediddetection.com/gfwlist +server=/xboxplayanywhere.com/127.0.0.1#5335 +ipset=/xboxplayanywhere.com/gfwlist +server=/vimeo-staging2.com/127.0.0.1#5335 +ipset=/vimeo-staging2.com/gfwlist +server=/18comic.org/127.0.0.1#5335 +ipset=/18comic.org/gfwlist +server=/pornburger.com/127.0.0.1#5335 +ipset=/pornburger.com/gfwlist +server=/gofuckmenow.com/127.0.0.1#5335 +ipset=/gofuckmenow.com/gfwlist +server=/adidas.ie/127.0.0.1#5335 +ipset=/adidas.ie/gfwlist +server=/bmw.gr/127.0.0.1#5335 +ipset=/bmw.gr/gfwlist +server=/voashona.com/127.0.0.1#5335 +ipset=/voashona.com/gfwlist +server=/fcebookk.com/127.0.0.1#5335 +ipset=/fcebookk.com/gfwlist +server=/google.gy/127.0.0.1#5335 +ipset=/google.gy/gfwlist +server=/volvogroup.com/127.0.0.1#5335 +ipset=/volvogroup.com/gfwlist +server=/bloombergbreakaway.com/127.0.0.1#5335 +ipset=/bloombergbreakaway.com/gfwlist +server=/volvotrucks.ae/127.0.0.1#5335 +ipset=/volvotrucks.ae/gfwlist +server=/adultsextoys.com/127.0.0.1#5335 +ipset=/adultsextoys.com/gfwlist +server=/akiba-online.com/127.0.0.1#5335 +ipset=/akiba-online.com/gfwlist +server=/beibao.com/127.0.0.1#5335 +ipset=/beibao.com/gfwlist +server=/faccebookk.com/127.0.0.1#5335 +ipset=/faccebookk.com/gfwlist +server=/www-facebook.com/127.0.0.1#5335 +ipset=/www-facebook.com/gfwlist +server=/pearsonclinical.dk/127.0.0.1#5335 +ipset=/pearsonclinical.dk/gfwlist +server=/eanordic.com/127.0.0.1#5335 +ipset=/eanordic.com/gfwlist +server=/dynamics.com/127.0.0.1#5335 +ipset=/dynamics.com/gfwlist +server=/bmwshop.ca/127.0.0.1#5335 +ipset=/bmwshop.ca/gfwlist +server=/sulwerphoto.com/127.0.0.1#5335 +ipset=/sulwerphoto.com/gfwlist +server=/couriermail.com.au/127.0.0.1#5335 +ipset=/couriermail.com.au/gfwlist +server=/freebigmovies.com/127.0.0.1#5335 +ipset=/freebigmovies.com/gfwlist +server=/specialtyheadphones.com/127.0.0.1#5335 +ipset=/specialtyheadphones.com/gfwlist +server=/mastercard.ke/127.0.0.1#5335 +ipset=/mastercard.ke/gfwlist +server=/xbeegtube.com/127.0.0.1#5335 +ipset=/xbeegtube.com/gfwlist +server=/solostudioksale.com/127.0.0.1#5335 +ipset=/solostudioksale.com/gfwlist +server=/gotgayporn.com/127.0.0.1#5335 +ipset=/gotgayporn.com/gfwlist +server=/mini.es/127.0.0.1#5335 +ipset=/mini.es/gfwlist +server=/mini-egypt.com/127.0.0.1#5335 +ipset=/mini-egypt.com/gfwlist +server=/sneaker666.com/127.0.0.1#5335 +ipset=/sneaker666.com/gfwlist +server=/shoppinguheadphones.com/127.0.0.1#5335 +ipset=/shoppinguheadphones.com/gfwlist +server=/webtype.com/127.0.0.1#5335 +ipset=/webtype.com/gfwlist +server=/pinterest.com.mx/127.0.0.1#5335 +ipset=/pinterest.com.mx/gfwlist +server=/bmw-motorrad.sv/127.0.0.1#5335 +ipset=/bmw-motorrad.sv/gfwlist +server=/gallery-dump.club/127.0.0.1#5335 +ipset=/gallery-dump.club/gfwlist +server=/shop-headphones.net/127.0.0.1#5335 +ipset=/shop-headphones.net/gfwlist +server=/myrz.com/127.0.0.1#5335 +ipset=/myrz.com/gfwlist +server=/femscat.com/127.0.0.1#5335 +ipset=/femscat.com/gfwlist +server=/volvobuses.es/127.0.0.1#5335 +ipset=/volvobuses.es/gfwlist +server=/shoestop2.com/127.0.0.1#5335 +ipset=/shoestop2.com/gfwlist +server=/sanvaras.com/127.0.0.1#5335 +ipset=/sanvaras.com/gfwlist +server=/spoti.fi/127.0.0.1#5335 +ipset=/spoti.fi/gfwlist +server=/mini.com.mo/127.0.0.1#5335 +ipset=/mini.com.mo/gfwlist +server=/como-hackearfacebook.com/127.0.0.1#5335 +ipset=/como-hackearfacebook.com/gfwlist +server=/chloesworld.com/127.0.0.1#5335 +ipset=/chloesworld.com/gfwlist +server=/repsneakermall.com/127.0.0.1#5335 +ipset=/repsneakermall.com/gfwlist +server=/prostudiobeatscybersale.com/127.0.0.1#5335 +ipset=/prostudiobeatscybersale.com/gfwlist +server=/haori888.com/127.0.0.1#5335 +ipset=/haori888.com/gfwlist +server=/mini-bosnia.com/127.0.0.1#5335 +ipset=/mini-bosnia.com/gfwlist +server=/flatmates.com.au/127.0.0.1#5335 +ipset=/flatmates.com.au/gfwlist +server=/powerbeatsbydre.com/127.0.0.1#5335 +ipset=/powerbeatsbydre.com/gfwlist +server=/powerbeatsbydrdre.com/127.0.0.1#5335 +ipset=/powerbeatsbydrdre.com/gfwlist +server=/bamgrid.com/127.0.0.1#5335 +ipset=/bamgrid.com/gfwlist +server=/pocketbiketrader.com/127.0.0.1#5335 +ipset=/pocketbiketrader.com/gfwlist +server=/iporntv.net/127.0.0.1#5335 +ipset=/iporntv.net/gfwlist +server=/pillbeatsblackfridaysale.com/127.0.0.1#5335 +ipset=/pillbeatsblackfridaysale.com/gfwlist +server=/pickshoesclothes.com/127.0.0.1#5335 +ipset=/pickshoesclothes.com/gfwlist +server=/picknicekicks.net/127.0.0.1#5335 +ipset=/picknicekicks.net/gfwlist +server=/personeelsland.com/127.0.0.1#5335 +ipset=/personeelsland.com/gfwlist +server=/monsterbeatssalg.com/127.0.0.1#5335 +ipset=/monsterbeatssalg.com/gfwlist +server=/breitbart.com/127.0.0.1#5335 +ipset=/breitbart.com/gfwlist +server=/pugetsoundbmw.com/127.0.0.1#5335 +ipset=/pugetsoundbmw.com/gfwlist +server=/cmu.edu/127.0.0.1#5335 +ipset=/cmu.edu/gfwlist +server=/edx.org/127.0.0.1#5335 +ipset=/edx.org/gfwlist +server=/javprice.com/127.0.0.1#5335 +ipset=/javprice.com/gfwlist +server=/mastercard-email.com/127.0.0.1#5335 +ipset=/mastercard-email.com/gfwlist +server=/zee5.tv/127.0.0.1#5335 +ipset=/zee5.tv/gfwlist +server=/officialbeatsbydrestore.com/127.0.0.1#5335 +ipset=/officialbeatsbydrestore.com/gfwlist +server=/mega.nz/127.0.0.1#5335 +ipset=/mega.nz/gfwlist +server=/disquscdn.com/127.0.0.1#5335 +ipset=/disquscdn.com/gfwlist +server=/theclasshroom.com/127.0.0.1#5335 +ipset=/theclasshroom.com/gfwlist +server=/bmw.fi/127.0.0.1#5335 +ipset=/bmw.fi/gfwlist +server=/newlysprung.net/127.0.0.1#5335 +ipset=/newlysprung.net/gfwlist +server=/ficeboock.com/127.0.0.1#5335 +ipset=/ficeboock.com/gfwlist +server=/xdsummit.com/127.0.0.1#5335 +ipset=/xdsummit.com/gfwlist +server=/thetvdb.com/127.0.0.1#5335 +ipset=/thetvdb.com/gfwlist +server=/1lib.domains/127.0.0.1#5335 +ipset=/1lib.domains/gfwlist +server=/acgnmanhua.com/127.0.0.1#5335 +ipset=/acgnmanhua.com/gfwlist +server=/newbemany.com/127.0.0.1#5335 +ipset=/newbemany.com/gfwlist +server=/bmwmotorrad.com.ph/127.0.0.1#5335 +ipset=/bmwmotorrad.com.ph/gfwlist +server=/atkgallery.com/127.0.0.1#5335 +ipset=/atkgallery.com/gfwlist +server=/cheapbeatsbydre99.com/127.0.0.1#5335 +ipset=/cheapbeatsbydre99.com/gfwlist +server=/negozimonsterbeats.com/127.0.0.1#5335 +ipset=/negozimonsterbeats.com/gfwlist +server=/zohostatic.com/127.0.0.1#5335 +ipset=/zohostatic.com/gfwlist +server=/paypalnet.org/127.0.0.1#5335 +ipset=/paypalnet.org/gfwlist +server=/skyassets.com/127.0.0.1#5335 +ipset=/skyassets.com/gfwlist +server=/bmwmuseum.net/127.0.0.1#5335 +ipset=/bmwmuseum.net/gfwlist +server=/bmw-arts-design.com/127.0.0.1#5335 +ipset=/bmw-arts-design.com/gfwlist +server=/neborder.com/127.0.0.1#5335 +ipset=/neborder.com/gfwlist +server=/cool18.com/127.0.0.1#5335 +ipset=/cool18.com/gfwlist +server=/apple.eu/127.0.0.1#5335 +ipset=/apple.eu/gfwlist +server=/disney.co.th/127.0.0.1#5335 +ipset=/disney.co.th/gfwlist +server=/facecook.org/127.0.0.1#5335 +ipset=/facecook.org/gfwlist +server=/bioporno.com/127.0.0.1#5335 +ipset=/bioporno.com/gfwlist +server=/mini.rs/127.0.0.1#5335 +ipset=/mini.rs/gfwlist +server=/starbucks.es/127.0.0.1#5335 +ipset=/starbucks.es/gfwlist +server=/ms4dre.com/127.0.0.1#5335 +ipset=/ms4dre.com/gfwlist +server=/google.ae/127.0.0.1#5335 +ipset=/google.ae/gfwlist +server=/ccav69.me/127.0.0.1#5335 +ipset=/ccav69.me/gfwlist +server=/goldcoastbulletin.com.au/127.0.0.1#5335 +ipset=/goldcoastbulletin.com.au/gfwlist +server=/minidurham.com/127.0.0.1#5335 +ipset=/minidurham.com/gfwlist +server=/aishegw.com/127.0.0.1#5335 +ipset=/aishegw.com/gfwlist +server=/socdm.com/127.0.0.1#5335 +ipset=/socdm.com/gfwlist +server=/xxxymovies.com/127.0.0.1#5335 +ipset=/xxxymovies.com/gfwlist +server=/nikepromax.com/127.0.0.1#5335 +ipset=/nikepromax.com/gfwlist +server=/facebooksupplier.com/127.0.0.1#5335 +ipset=/facebooksupplier.com/gfwlist +server=/monstersdebea.com/127.0.0.1#5335 +ipset=/monstersdebea.com/gfwlist +server=/10xfotolia.com/127.0.0.1#5335 +ipset=/10xfotolia.com/gfwlist +server=/scatfinder.com/127.0.0.1#5335 +ipset=/scatfinder.com/gfwlist +server=/flbjc.net/127.0.0.1#5335 +ipset=/flbjc.net/gfwlist +server=/ebayeletro.com/127.0.0.1#5335 +ipset=/ebayeletro.com/gfwlist +server=/icsd.fiz-karlsruhe.de/127.0.0.1#5335 +ipset=/icsd.fiz-karlsruhe.de/gfwlist +server=/xbox360.com/127.0.0.1#5335 +ipset=/xbox360.com/gfwlist +server=/gayfuckporn.com/127.0.0.1#5335 +ipset=/gayfuckporn.com/gfwlist +server=/waa.tw/127.0.0.1#5335 +ipset=/waa.tw/gfwlist +server=/cloudflareaccess.com/127.0.0.1#5335 +ipset=/cloudflareaccess.com/gfwlist +server=/beatsbydremonsteraustralia.com/127.0.0.1#5335 +ipset=/beatsbydremonsteraustralia.com/gfwlist +server=/s-nbcnews.com/127.0.0.1#5335 +ipset=/s-nbcnews.com/gfwlist +server=/visasignature.co.kr/127.0.0.1#5335 +ipset=/visasignature.co.kr/gfwlist +server=/monsterbeatsru.com/127.0.0.1#5335 +ipset=/monsterbeatsru.com/gfwlist +server=/monsterbeatsonlinestoreuk.com/127.0.0.1#5335 +ipset=/monsterbeatsonlinestoreuk.com/gfwlist +server=/vfsco.dk/127.0.0.1#5335 +ipset=/vfsco.dk/gfwlist +server=/monsterbeatsok.com/127.0.0.1#5335 +ipset=/monsterbeatsok.com/gfwlist +server=/monsterbeatsnegozi.net/127.0.0.1#5335 +ipset=/monsterbeatsnegozi.net/gfwlist +server=/porngames.com/127.0.0.1#5335 +ipset=/porngames.com/gfwlist +server=/monsterbeatsitaly.com/127.0.0.1#5335 +ipset=/monsterbeatsitaly.com/gfwlist +server=/stunnel.org/127.0.0.1#5335 +ipset=/stunnel.org/gfwlist +server=/monsterbeatsfinland.com/127.0.0.1#5335 +ipset=/monsterbeatsfinland.com/gfwlist +server=/mastercard.kz/127.0.0.1#5335 +ipset=/mastercard.kz/gfwlist +server=/bmw-motorrad.bg/127.0.0.1#5335 +ipset=/bmw-motorrad.bg/gfwlist +server=/siam.org/127.0.0.1#5335 +ipset=/siam.org/gfwlist +server=/kicksnike1.com/127.0.0.1#5335 +ipset=/kicksnike1.com/gfwlist +server=/squarecloudservices.com/127.0.0.1#5335 +ipset=/squarecloudservices.com/gfwlist +server=/bmw-connecteddrive.ae/127.0.0.1#5335 +ipset=/bmw-connecteddrive.ae/gfwlist +server=/youyu.services/127.0.0.1#5335 +ipset=/youyu.services/gfwlist +server=/phimsexhentai.me/127.0.0.1#5335 +ipset=/phimsexhentai.me/gfwlist +server=/nginx.com/127.0.0.1#5335 +ipset=/nginx.com/gfwlist +server=/binancezh.sh/127.0.0.1#5335 +ipset=/binancezh.sh/gfwlist +server=/gonzo-movies.com/127.0.0.1#5335 +ipset=/gonzo-movies.com/gfwlist +server=/monsterbeatsbydrebilligde.com/127.0.0.1#5335 +ipset=/monsterbeatsbydrebilligde.com/gfwlist +server=/starwarsgalacticstarcruiser.com/127.0.0.1#5335 +ipset=/starwarsgalacticstarcruiser.com/gfwlist +server=/gaycock4u.com/127.0.0.1#5335 +ipset=/gaycock4u.com/gfwlist +server=/nikesbdunks.net/127.0.0.1#5335 +ipset=/nikesbdunks.net/gfwlist +server=/bandag.cc/127.0.0.1#5335 +ipset=/bandag.cc/gfwlist +server=/manhuagui.com/127.0.0.1#5335 +ipset=/manhuagui.com/gfwlist +server=/artoferotica.info/127.0.0.1#5335 +ipset=/artoferotica.info/gfwlist +server=/gaypornforyou.com/127.0.0.1#5335 +ipset=/gaypornforyou.com/gfwlist +server=/hentaigamesplanet.com/127.0.0.1#5335 +ipset=/hentaigamesplanet.com/gfwlist +server=/youtube.com.qa/127.0.0.1#5335 +ipset=/youtube.com.qa/gfwlist +server=/mzed.com/127.0.0.1#5335 +ipset=/mzed.com/gfwlist +server=/heavenlyhentai.com/127.0.0.1#5335 +ipset=/heavenlyhentai.com/gfwlist +server=/youtube.la/127.0.0.1#5335 +ipset=/youtube.la/gfwlist +server=/bmwworld.com/127.0.0.1#5335 +ipset=/bmwworld.com/gfwlist +server=/micstl.com/127.0.0.1#5335 +ipset=/micstl.com/gfwlist +server=/8muses.io/127.0.0.1#5335 +ipset=/8muses.io/gfwlist +server=/visapcsdirect.com/127.0.0.1#5335 +ipset=/visapcsdirect.com/gfwlist +server=/gettyimages.at/127.0.0.1#5335 +ipset=/gettyimages.at/gfwlist +server=/media-amazon.com/127.0.0.1#5335 +ipset=/media-amazon.com/gfwlist +server=/instagrm.com/127.0.0.1#5335 +ipset=/instagrm.com/gfwlist +server=/mairbeats.com/127.0.0.1#5335 +ipset=/mairbeats.com/gfwlist +server=/dtci.technology/127.0.0.1#5335 +ipset=/dtci.technology/gfwlist +server=/airwick.hu/127.0.0.1#5335 +ipset=/airwick.hu/gfwlist +server=/kickshatchannel.com/127.0.0.1#5335 +ipset=/kickshatchannel.com/gfwlist +server=/sacredhentai.com/127.0.0.1#5335 +ipset=/sacredhentai.com/gfwlist +server=/lifeselector.com/127.0.0.1#5335 +ipset=/lifeselector.com/gfwlist +server=/italiabeatsbydrdre.com/127.0.0.1#5335 +ipset=/italiabeatsbydrdre.com/gfwlist +server=/chinapower.csis.org/127.0.0.1#5335 +ipset=/chinapower.csis.org/gfwlist +server=/kijijiauto.ca/127.0.0.1#5335 +ipset=/kijijiauto.ca/gfwlist +server=/bmw-motorrad.si/127.0.0.1#5335 +ipset=/bmw-motorrad.si/gfwlist +server=/topcelebnudes.com/127.0.0.1#5335 +ipset=/topcelebnudes.com/gfwlist +server=/marketo.tv/127.0.0.1#5335 +ipset=/marketo.tv/gfwlist +server=/billmelater.info/127.0.0.1#5335 +ipset=/billmelater.info/gfwlist +server=/canon.net/127.0.0.1#5335 +ipset=/canon.net/gfwlist +server=/geforce.com.tw/127.0.0.1#5335 +ipset=/geforce.com.tw/gfwlist +server=/yomikyo.or.jp/127.0.0.1#5335 +ipset=/yomikyo.or.jp/gfwlist +server=/omghk.com/127.0.0.1#5335 +ipset=/omghk.com/gfwlist +server=/bridgestonenationalfleet.com/127.0.0.1#5335 +ipset=/bridgestonenationalfleet.com/gfwlist +server=/anb.org/127.0.0.1#5335 +ipset=/anb.org/gfwlist +server=/milftube.pro/127.0.0.1#5335 +ipset=/milftube.pro/gfwlist +server=/csis.org/127.0.0.1#5335 +ipset=/csis.org/gfwlist +server=/librarylovefest.com/127.0.0.1#5335 +ipset=/librarylovefest.com/gfwlist +server=/dlgarenanow-a.akamaihd.net/127.0.0.1#5335 +ipset=/dlgarenanow-a.akamaihd.net/gfwlist +server=/milfprime.com/127.0.0.1#5335 +ipset=/milfprime.com/gfwlist +server=/facebook-support.org/127.0.0.1#5335 +ipset=/facebook-support.org/gfwlist +server=/fifastreet3.com/127.0.0.1#5335 +ipset=/fifastreet3.com/gfwlist +server=/lexuemei.com/127.0.0.1#5335 +ipset=/lexuemei.com/gfwlist +server=/appbridge.ca/127.0.0.1#5335 +ipset=/appbridge.ca/gfwlist +server=/slobodnaevropa.mk/127.0.0.1#5335 +ipset=/slobodnaevropa.mk/gfwlist +server=/3dfuckhouse.com/127.0.0.1#5335 +ipset=/3dfuckhouse.com/gfwlist +server=/japaneselovelygirl.com/127.0.0.1#5335 +ipset=/japaneselovelygirl.com/gfwlist +server=/faronics.com.au/127.0.0.1#5335 +ipset=/faronics.com.au/gfwlist +server=/intelplay.com/127.0.0.1#5335 +ipset=/intelplay.com/gfwlist +server=/fuhouse.club/127.0.0.1#5335 +ipset=/fuhouse.club/gfwlist +server=/headphonezip.com/127.0.0.1#5335 +ipset=/headphonezip.com/gfwlist +server=/bexjt5wz.xyz/127.0.0.1#5335 +ipset=/bexjt5wz.xyz/gfwlist +server=/travelex.co.uk/127.0.0.1#5335 +ipset=/travelex.co.uk/gfwlist +server=/headphonesretailer.com/127.0.0.1#5335 +ipset=/headphonesretailer.com/gfwlist +server=/sysinternals.com/127.0.0.1#5335 +ipset=/sysinternals.com/gfwlist +server=/nike.us/127.0.0.1#5335 +ipset=/nike.us/gfwlist +server=/jquery.com/127.0.0.1#5335 +ipset=/jquery.com/gfwlist +server=/volvotrucks.sk/127.0.0.1#5335 +ipset=/volvotrucks.sk/gfwlist +server=/ebayde.com/127.0.0.1#5335 +ipset=/ebayde.com/gfwlist +server=/lesbianpornvideos.com/127.0.0.1#5335 +ipset=/lesbianpornvideos.com/gfwlist +server=/cloudinary.net/127.0.0.1#5335 +ipset=/cloudinary.net/gfwlist +server=/volvobuses.at/127.0.0.1#5335 +ipset=/volvobuses.at/gfwlist +server=/mythicgames.com/127.0.0.1#5335 +ipset=/mythicgames.com/gfwlist +server=/atlasdmt.com/127.0.0.1#5335 +ipset=/atlasdmt.com/gfwlist +server=/verisign.com.es/127.0.0.1#5335 +ipset=/verisign.com.es/gfwlist +server=/jdbstatic.com/127.0.0.1#5335 +ipset=/jdbstatic.com/gfwlist +server=/minid.no/127.0.0.1#5335 +ipset=/minid.no/gfwlist +server=/pornlegendsclub.com/127.0.0.1#5335 +ipset=/pornlegendsclub.com/gfwlist +server=/amatura.com/127.0.0.1#5335 +ipset=/amatura.com/gfwlist +server=/ballbustingtube.com/127.0.0.1#5335 +ipset=/ballbustingtube.com/gfwlist +server=/jav101.com/127.0.0.1#5335 +ipset=/jav101.com/gfwlist +server=/nationalaustraliaban.tt.omtrdc.net/127.0.0.1#5335 +ipset=/nationalaustraliaban.tt.omtrdc.net/gfwlist +server=/gmnetworks.net/127.0.0.1#5335 +ipset=/gmnetworks.net/gfwlist +server=/frishoes.com/127.0.0.1#5335 +ipset=/frishoes.com/gfwlist +server=/frcasquesbeats.com/127.0.0.1#5335 +ipset=/frcasquesbeats.com/gfwlist +server=/fr-beatsbydrestore.com/127.0.0.1#5335 +ipset=/fr-beatsbydrestore.com/gfwlist +server=/fox26.com/127.0.0.1#5335 +ipset=/fox26.com/gfwlist +server=/foxsports.com.ar/127.0.0.1#5335 +ipset=/foxsports.com.ar/gfwlist +server=/mastercardcenter.com/127.0.0.1#5335 +ipset=/mastercardcenter.com/gfwlist +server=/vimeo.com/127.0.0.1#5335 +ipset=/vimeo.com/gfwlist +server=/naver.net/127.0.0.1#5335 +ipset=/naver.net/gfwlist +server=/ebaka.ru/127.0.0.1#5335 +ipset=/ebaka.ru/gfwlist +server=/awsloft-stockholm.com/127.0.0.1#5335 +ipset=/awsloft-stockholm.com/gfwlist +server=/attinnovationspace.com/127.0.0.1#5335 +ipset=/attinnovationspace.com/gfwlist +server=/ts.la/127.0.0.1#5335 +ipset=/ts.la/gfwlist +server=/pinduck.com/127.0.0.1#5335 +ipset=/pinduck.com/gfwlist +server=/dreprobeats.com/127.0.0.1#5335 +ipset=/dreprobeats.com/gfwlist +server=/kicu.tv/127.0.0.1#5335 +ipset=/kicu.tv/gfwlist +server=/frescolib.org/127.0.0.1#5335 +ipset=/frescolib.org/gfwlist +server=/drebeatsaustralia-cheap.com/127.0.0.1#5335 +ipset=/drebeatsaustralia-cheap.com/gfwlist +server=/limer.tw/127.0.0.1#5335 +ipset=/limer.tw/gfwlist +server=/newscorpaustralia.com/127.0.0.1#5335 +ipset=/newscorpaustralia.com/gfwlist +server=/ak1.net/127.0.0.1#5335 +ipset=/ak1.net/gfwlist +server=/google.com.my/127.0.0.1#5335 +ipset=/google.com.my/gfwlist +server=/tryquinn.com/127.0.0.1#5335 +ipset=/tryquinn.com/gfwlist +server=/yandex.kz/127.0.0.1#5335 +ipset=/yandex.kz/gfwlist +server=/microsoftaffiliates.com/127.0.0.1#5335 +ipset=/microsoftaffiliates.com/gfwlist +server=/twgreatnews.com/127.0.0.1#5335 +ipset=/twgreatnews.com/gfwlist +server=/albagals.com/127.0.0.1#5335 +ipset=/albagals.com/gfwlist +server=/hentaiyes.com/127.0.0.1#5335 +ipset=/hentaiyes.com/gfwlist +server=/drebeatsaustralia-cheap.net/127.0.0.1#5335 +ipset=/drebeatsaustralia-cheap.net/gfwlist +server=/naughtyamerica.com/127.0.0.1#5335 +ipset=/naughtyamerica.com/gfwlist +server=/mini.com.gt/127.0.0.1#5335 +ipset=/mini.com.gt/gfwlist +server=/drebeats-monsteraustralia.com/127.0.0.1#5335 +ipset=/drebeats-monsteraustralia.com/gfwlist +server=/akami.net/127.0.0.1#5335 +ipset=/akami.net/gfwlist +server=/erogames.com/127.0.0.1#5335 +ipset=/erogames.com/gfwlist +server=/sectigo.com/127.0.0.1#5335 +ipset=/sectigo.com/gfwlist +server=/mengnan.shop/127.0.0.1#5335 +ipset=/mengnan.shop/gfwlist +server=/tx5254.com/127.0.0.1#5335 +ipset=/tx5254.com/gfwlist +server=/xbox.com/127.0.0.1#5335 +ipset=/xbox.com/gfwlist +server=/nintendodsi.com/127.0.0.1#5335 +ipset=/nintendodsi.com/gfwlist +server=/my20houston.com/127.0.0.1#5335 +ipset=/my20houston.com/gfwlist +server=/bmw-fleet.net/127.0.0.1#5335 +ipset=/bmw-fleet.net/gfwlist +server=/mortein.co.za/127.0.0.1#5335 +ipset=/mortein.co.za/gfwlist +server=/visa.ky/127.0.0.1#5335 +ipset=/visa.ky/gfwlist +server=/bmw-yemen.com/127.0.0.1#5335 +ipset=/bmw-yemen.com/gfwlist +server=/enanyang.my/127.0.0.1#5335 +ipset=/enanyang.my/gfwlist +server=/drdremonster-beats.com/127.0.0.1#5335 +ipset=/drdremonster-beats.com/gfwlist +server=/attdns.net/127.0.0.1#5335 +ipset=/attdns.net/gfwlist +server=/signal.art/127.0.0.1#5335 +ipset=/signal.art/gfwlist +server=/cuckoldplacetube.com/127.0.0.1#5335 +ipset=/cuckoldplacetube.com/gfwlist +server=/drdrebeatsretail2013.com/127.0.0.1#5335 +ipset=/drdrebeatsretail2013.com/gfwlist +server=/xindelu.com/127.0.0.1#5335 +ipset=/xindelu.com/gfwlist +server=/nhentai.com/127.0.0.1#5335 +ipset=/nhentai.com/gfwlist +server=/doodhwali.com/127.0.0.1#5335 +ipset=/doodhwali.com/gfwlist +server=/wankzvr.com/127.0.0.1#5335 +ipset=/wankzvr.com/gfwlist +server=/slutload.com/127.0.0.1#5335 +ipset=/slutload.com/gfwlist +server=/radian6.com/127.0.0.1#5335 +ipset=/radian6.com/gfwlist +server=/audible.com/127.0.0.1#5335 +ipset=/audible.com/gfwlist +server=/disneyworld-go.com/127.0.0.1#5335 +ipset=/disneyworld-go.com/gfwlist +server=/npm.community/127.0.0.1#5335 +ipset=/npm.community/gfwlist +server=/mini-connected.es/127.0.0.1#5335 +ipset=/mini-connected.es/gfwlist +server=/gyutto.com/127.0.0.1#5335 +ipset=/gyutto.com/gfwlist +server=/computer.org/127.0.0.1#5335 +ipset=/computer.org/gfwlist +server=/1010.com.hk/127.0.0.1#5335 +ipset=/1010.com.hk/gfwlist +server=/yourspeculumexam.com/127.0.0.1#5335 +ipset=/yourspeculumexam.com/gfwlist +server=/59mvmv.com/127.0.0.1#5335 +ipset=/59mvmv.com/gfwlist +server=/codei.sh/127.0.0.1#5335 +ipset=/codei.sh/gfwlist +server=/tferwq.com/127.0.0.1#5335 +ipset=/tferwq.com/gfwlist +server=/discountbeatsstore.com/127.0.0.1#5335 +ipset=/discountbeatsstore.com/gfwlist +server=/taylorfrancis.com/127.0.0.1#5335 +ipset=/taylorfrancis.com/gfwlist +server=/yoshisnewisland.com/127.0.0.1#5335 +ipset=/yoshisnewisland.com/gfwlist +server=/wikileaks.org/127.0.0.1#5335 +ipset=/wikileaks.org/gfwlist +server=/adidas.de/127.0.0.1#5335 +ipset=/adidas.de/gfwlist +server=/custombeatssbydreus.com/127.0.0.1#5335 +ipset=/custombeatssbydreus.com/gfwlist +server=/custombeatsdeals.com/127.0.0.1#5335 +ipset=/custombeatsdeals.com/gfwlist +server=/beatsbydreus.com/127.0.0.1#5335 +ipset=/beatsbydreus.com/gfwlist +server=/nintendo.fi/127.0.0.1#5335 +ipset=/nintendo.fi/gfwlist +server=/cuffiesaldi.com/127.0.0.1#5335 +ipset=/cuffiesaldi.com/gfwlist +server=/eamobile.com/127.0.0.1#5335 +ipset=/eamobile.com/gfwlist +server=/acgww.cyou/127.0.0.1#5335 +ipset=/acgww.cyou/gfwlist +server=/coolmonster.net/127.0.0.1#5335 +ipset=/coolmonster.net/gfwlist +server=/miniwindsor.com/127.0.0.1#5335 +ipset=/miniwindsor.com/gfwlist +server=/chihair-straightener.com/127.0.0.1#5335 +ipset=/chihair-straightener.com/gfwlist +server=/pearsonlongman.ch/127.0.0.1#5335 +ipset=/pearsonlongman.ch/gfwlist +server=/cheapsalemonster.com/127.0.0.1#5335 +ipset=/cheapsalemonster.com/gfwlist +server=/cheapnewbeatsbydre.com/127.0.0.1#5335 +ipset=/cheapnewbeatsbydre.com/gfwlist +server=/xbox360.co/127.0.0.1#5335 +ipset=/xbox360.co/gfwlist +server=/bobs-tube.com/127.0.0.1#5335 +ipset=/bobs-tube.com/gfwlist +server=/cheapmonsterbeatsheadsets.com/127.0.0.1#5335 +ipset=/cheapmonsterbeatsheadsets.com/gfwlist +server=/ea.tt.omtrdc.net/127.0.0.1#5335 +ipset=/ea.tt.omtrdc.net/gfwlist +server=/cheapheadphonessale.com/127.0.0.1#5335 +ipset=/cheapheadphonessale.com/gfwlist +server=/xxx4hindi.com/127.0.0.1#5335 +ipset=/xxx4hindi.com/gfwlist +server=/cheapdrdrebeatsca.com/127.0.0.1#5335 +ipset=/cheapdrdrebeatsca.com/gfwlist +server=/chuokoron.jp/127.0.0.1#5335 +ipset=/chuokoron.jp/gfwlist +server=/cheapdrdrebeats8.com/127.0.0.1#5335 +ipset=/cheapdrdrebeats8.com/gfwlist +server=/infocert.it/127.0.0.1#5335 +ipset=/infocert.it/gfwlist +server=/fox13news.com/127.0.0.1#5335 +ipset=/fox13news.com/gfwlist +server=/mini-vietnam.com/127.0.0.1#5335 +ipset=/mini-vietnam.com/gfwlist +server=/freexvideos.org/127.0.0.1#5335 +ipset=/freexvideos.org/gfwlist +server=/bridgestoneperformance.com/127.0.0.1#5335 +ipset=/bridgestoneperformance.com/gfwlist +server=/myfoxaustin.com/127.0.0.1#5335 +ipset=/myfoxaustin.com/gfwlist +server=/cheapbeatsheadphones.us/127.0.0.1#5335 +ipset=/cheapbeatsheadphones.us/gfwlist +server=/cheapbeatsheadphone2014.com/127.0.0.1#5335 +ipset=/cheapbeatsheadphone2014.com/gfwlist +server=/ilovexs.com/127.0.0.1#5335 +ipset=/ilovexs.com/gfwlist +server=/99thz.com/127.0.0.1#5335 +ipset=/99thz.com/gfwlist +server=/fteproxy.org/127.0.0.1#5335 +ipset=/fteproxy.org/gfwlist +server=/xxxbunker.com/127.0.0.1#5335 +ipset=/xxxbunker.com/gfwlist +server=/xnxxhd.biz/127.0.0.1#5335 +ipset=/xnxxhd.biz/gfwlist +server=/cheapbeatsbydreoutlets2013.com/127.0.0.1#5335 +ipset=/cheapbeatsbydreoutlets2013.com/gfwlist +server=/beatsheadphonesdealer.com/127.0.0.1#5335 +ipset=/beatsheadphonesdealer.com/gfwlist +server=/18tube.xxx/127.0.0.1#5335 +ipset=/18tube.xxx/gfwlist +server=/czechvideo.org/127.0.0.1#5335 +ipset=/czechvideo.org/gfwlist +server=/gfacecbook.com/127.0.0.1#5335 +ipset=/gfacecbook.com/gfwlist +server=/xhamster.com/127.0.0.1#5335 +ipset=/xhamster.com/gfwlist +server=/ipod.net/127.0.0.1#5335 +ipset=/ipod.net/gfwlist +server=/verizonmedia.com/127.0.0.1#5335 +ipset=/verizonmedia.com/gfwlist +server=/apple.jo/127.0.0.1#5335 +ipset=/apple.jo/gfwlist +server=/casquebeatspascher2013.com/127.0.0.1#5335 +ipset=/casquebeatspascher2013.com/gfwlist +server=/yourphysicalexam.com/127.0.0.1#5335 +ipset=/yourphysicalexam.com/gfwlist +server=/casquebeatsmer.net/127.0.0.1#5335 +ipset=/casquebeatsmer.net/gfwlist +server=/blpevents.com/127.0.0.1#5335 +ipset=/blpevents.com/gfwlist +server=/xbox.co/127.0.0.1#5335 +ipset=/xbox.co/gfwlist +server=/gentoo.org/127.0.0.1#5335 +ipset=/gentoo.org/gfwlist +server=/camonster.com/127.0.0.1#5335 +ipset=/camonster.com/gfwlist +server=/namethatpornad.com/127.0.0.1#5335 +ipset=/namethatpornad.com/gfwlist +server=/stxmosquitoproject.net/127.0.0.1#5335 +ipset=/stxmosquitoproject.net/gfwlist +server=/easylist.to/127.0.0.1#5335 +ipset=/easylist.to/gfwlist +server=/buyshoponly.com/127.0.0.1#5335 +ipset=/buyshoponly.com/gfwlist +server=/hentaiheadlines.com/127.0.0.1#5335 +ipset=/hentaiheadlines.com/gfwlist +server=/justfamilyporn.com/127.0.0.1#5335 +ipset=/justfamilyporn.com/gfwlist +server=/dailym.ai/127.0.0.1#5335 +ipset=/dailym.ai/gfwlist +server=/vodafone.it/127.0.0.1#5335 +ipset=/vodafone.it/gfwlist +server=/buybeatsheadphonesbydre.com/127.0.0.1#5335 +ipset=/buybeatsheadphonesbydre.com/gfwlist +server=/bmwusa.com/127.0.0.1#5335 +ipset=/bmwusa.com/gfwlist +server=/buybeatsbydre-uk.com/127.0.0.1#5335 +ipset=/buybeatsbydre-uk.com/gfwlist +server=/nintendo.co.jp/127.0.0.1#5335 +ipset=/nintendo.co.jp/gfwlist +server=/firestone.com.ar/127.0.0.1#5335 +ipset=/firestone.com.ar/gfwlist +server=/buy-from-shanghai.com/127.0.0.1#5335 +ipset=/buy-from-shanghai.com/gfwlist +server=/brands098.com/127.0.0.1#5335 +ipset=/brands098.com/gfwlist +server=/steam.cdn.on.net/127.0.0.1#5335 +ipset=/steam.cdn.on.net/gfwlist +server=/thegooglestore.com/127.0.0.1#5335 +ipset=/thegooglestore.com/gfwlist +server=/nokiantyres.com/127.0.0.1#5335 +ipset=/nokiantyres.com/gfwlist +server=/isfocus.net/127.0.0.1#5335 +ipset=/isfocus.net/gfwlist +server=/badgen.net/127.0.0.1#5335 +ipset=/badgen.net/gfwlist +server=/maturewomenanal.com/127.0.0.1#5335 +ipset=/maturewomenanal.com/gfwlist +server=/scatshop.com/127.0.0.1#5335 +ipset=/scatshop.com/gfwlist +server=/youtube.com.kw/127.0.0.1#5335 +ipset=/youtube.com.kw/gfwlist +server=/bookonsky.net/127.0.0.1#5335 +ipset=/bookonsky.net/gfwlist +server=/bloommicroventures.com/127.0.0.1#5335 +ipset=/bloommicroventures.com/gfwlist +server=/biitii.com/127.0.0.1#5335 +ipset=/biitii.com/gfwlist +server=/azatutyun.am/127.0.0.1#5335 +ipset=/azatutyun.am/gfwlist +server=/thecandidforum-voyeur.ru/127.0.0.1#5335 +ipset=/thecandidforum-voyeur.ru/gfwlist +server=/facebooks.com/127.0.0.1#5335 +ipset=/facebooks.com/gfwlist +server=/54647.io/127.0.0.1#5335 +ipset=/54647.io/gfwlist +server=/playparagon.com/127.0.0.1#5335 +ipset=/playparagon.com/gfwlist +server=/eebay.com/127.0.0.1#5335 +ipset=/eebay.com/gfwlist +server=/xn--ubt498knmf.com/127.0.0.1#5335 +ipset=/xn--ubt498knmf.com/gfwlist +server=/javfree.me/127.0.0.1#5335 +ipset=/javfree.me/gfwlist +server=/beatssingapores.com/127.0.0.1#5335 +ipset=/beatssingapores.com/gfwlist +server=/pythonhosted.org/127.0.0.1#5335 +ipset=/pythonhosted.org/gfwlist +server=/eurekaselect.com/127.0.0.1#5335 +ipset=/eurekaselect.com/gfwlist +server=/ocsp-certum.com/127.0.0.1#5335 +ipset=/ocsp-certum.com/gfwlist +server=/porncoil.com/127.0.0.1#5335 +ipset=/porncoil.com/gfwlist +server=/xbox360.org/127.0.0.1#5335 +ipset=/xbox360.org/gfwlist +server=/advertiserscommunity.com/127.0.0.1#5335 +ipset=/advertiserscommunity.com/gfwlist +server=/beatspromonsterjp.com/127.0.0.1#5335 +ipset=/beatspromonsterjp.com/gfwlist +server=/bmwfilms.com/127.0.0.1#5335 +ipset=/bmwfilms.com/gfwlist +server=/xero.porn/127.0.0.1#5335 +ipset=/xero.porn/gfwlist +server=/appledaily.com/127.0.0.1#5335 +ipset=/appledaily.com/gfwlist +server=/uselessjunk.com/127.0.0.1#5335 +ipset=/uselessjunk.com/gfwlist +server=/bcsecure01-a.akamaihd.net/127.0.0.1#5335 +ipset=/bcsecure01-a.akamaihd.net/gfwlist +server=/soasta-dswb.com/127.0.0.1#5335 +ipset=/soasta-dswb.com/gfwlist +server=/jav9999.com/127.0.0.1#5335 +ipset=/jav9999.com/gfwlist +server=/beatsofdre-usa.com/127.0.0.1#5335 +ipset=/beatsofdre-usa.com/gfwlist +server=/adulto.vip/127.0.0.1#5335 +ipset=/adulto.vip/gfwlist +server=/aznude.com/127.0.0.1#5335 +ipset=/aznude.com/gfwlist +server=/my3dhentai.com/127.0.0.1#5335 +ipset=/my3dhentai.com/gfwlist +server=/volvotrucks.ps/127.0.0.1#5335 +ipset=/volvotrucks.ps/gfwlist +server=/miiverse.com/127.0.0.1#5335 +ipset=/miiverse.com/gfwlist +server=/huobi.sc/127.0.0.1#5335 +ipset=/huobi.sc/gfwlist +server=/dokusho-ojikan.jp/127.0.0.1#5335 +ipset=/dokusho-ojikan.jp/gfwlist +server=/pinkteentube.net/127.0.0.1#5335 +ipset=/pinkteentube.net/gfwlist +server=/airgonetworks.com/127.0.0.1#5335 +ipset=/airgonetworks.com/gfwlist +server=/bestshoesale2014.net/127.0.0.1#5335 +ipset=/bestshoesale2014.net/gfwlist +server=/beatsheadphonestudio.com/127.0.0.1#5335 +ipset=/beatsheadphonestudio.com/gfwlist +server=/bmw-motorrad.in/127.0.0.1#5335 +ipset=/bmw-motorrad.in/gfwlist +server=/bestfreesexgames.com/127.0.0.1#5335 +ipset=/bestfreesexgames.com/gfwlist +server=/freesexyindians.com/127.0.0.1#5335 +ipset=/freesexyindians.com/gfwlist +server=/yahoo.so/127.0.0.1#5335 +ipset=/yahoo.so/gfwlist +server=/oninstagram.com/127.0.0.1#5335 +ipset=/oninstagram.com/gfwlist +server=/cambb.xxx/127.0.0.1#5335 +ipset=/cambb.xxx/gfwlist +server=/bmw-motorrad.es/127.0.0.1#5335 +ipset=/bmw-motorrad.es/gfwlist +server=/beatsheadphones2u.com/127.0.0.1#5335 +ipset=/beatsheadphones2u.com/gfwlist +server=/beatsheadphones1.com/127.0.0.1#5335 +ipset=/beatsheadphones1.com/gfwlist +server=/jupyter.org/127.0.0.1#5335 +ipset=/jupyter.org/gfwlist +server=/yahoo.fi/127.0.0.1#5335 +ipset=/yahoo.fi/gfwlist +server=/joox.com/127.0.0.1#5335 +ipset=/joox.com/gfwlist +server=/test-ipv6.com/127.0.0.1#5335 +ipset=/test-ipv6.com/gfwlist +server=/dajiyuan.com/127.0.0.1#5335 +ipset=/dajiyuan.com/gfwlist +server=/cygwin.com/127.0.0.1#5335 +ipset=/cygwin.com/gfwlist +server=/whynotbi.com/127.0.0.1#5335 +ipset=/whynotbi.com/gfwlist +server=/hulu.jp/127.0.0.1#5335 +ipset=/hulu.jp/gfwlist +server=/vrv.co/127.0.0.1#5335 +ipset=/vrv.co/gfwlist +server=/girlscv.com/127.0.0.1#5335 +ipset=/girlscv.com/gfwlist +server=/beatsfacstore.com/127.0.0.1#5335 +ipset=/beatsfacstore.com/gfwlist +server=/beatsearbudsheadphoness.com/127.0.0.1#5335 +ipset=/beatsearbudsheadphoness.com/gfwlist +server=/nyt.com/127.0.0.1#5335 +ipset=/nyt.com/gfwlist +server=/doujincg.blog.jp/127.0.0.1#5335 +ipset=/doujincg.blog.jp/gfwlist +server=/fontsinuse.com/127.0.0.1#5335 +ipset=/fontsinuse.com/gfwlist +server=/pplah.com/127.0.0.1#5335 +ipset=/pplah.com/gfwlist +server=/googleusercontent.com/127.0.0.1#5335 +ipset=/googleusercontent.com/gfwlist +server=/cepacol.ca/127.0.0.1#5335 +ipset=/cepacol.ca/gfwlist +server=/beatsdresalestore.com/127.0.0.1#5335 +ipset=/beatsdresalestore.com/gfwlist +server=/beatsdremonster-uk.com/127.0.0.1#5335 +ipset=/beatsdremonster-uk.com/gfwlist +server=/beatsdredreheadphones.com/127.0.0.1#5335 +ipset=/beatsdredreheadphones.com/gfwlist +server=/cnpmjs.org/127.0.0.1#5335 +ipset=/cnpmjs.org/gfwlist +server=/ipfs.runfission.com/127.0.0.1#5335 +ipset=/ipfs.runfission.com/gfwlist +server=/visa.co.th/127.0.0.1#5335 +ipset=/visa.co.th/gfwlist +server=/beatsdrecheap.com/127.0.0.1#5335 +ipset=/beatsdrecheap.com/gfwlist +server=/82mvmv.com/127.0.0.1#5335 +ipset=/82mvmv.com/gfwlist +server=/wwwhuluplus.com/127.0.0.1#5335 +ipset=/wwwhuluplus.com/gfwlist +server=/beatsdrdreneon.com/127.0.0.1#5335 +ipset=/beatsdrdreneon.com/gfwlist +server=/18yiren.tv/127.0.0.1#5335 +ipset=/18yiren.tv/gfwlist +server=/amazonfctours.com/127.0.0.1#5335 +ipset=/amazonfctours.com/gfwlist +server=/ss2.us/127.0.0.1#5335 +ipset=/ss2.us/gfwlist +server=/hentairead.vip/127.0.0.1#5335 +ipset=/hentairead.vip/gfwlist +server=/eater.com/127.0.0.1#5335 +ipset=/eater.com/gfwlist +server=/bmw.com.bo/127.0.0.1#5335 +ipset=/bmw.com.bo/gfwlist +server=/bridgestonecntc.com/127.0.0.1#5335 +ipset=/bridgestonecntc.com/gfwlist +server=/beatsdrdre-it.com/127.0.0.1#5335 +ipset=/beatsdrdre-it.com/gfwlist +server=/freehqtube.com/127.0.0.1#5335 +ipset=/freehqtube.com/gfwlist +server=/microsoftedge.com/127.0.0.1#5335 +ipset=/microsoftedge.com/gfwlist +server=/mini-kuwait.com/127.0.0.1#5335 +ipset=/mini-kuwait.com/gfwlist +server=/epochtimes.cz/127.0.0.1#5335 +ipset=/epochtimes.cz/gfwlist +server=/calvappd.me/127.0.0.1#5335 +ipset=/calvappd.me/gfwlist +server=/fundpaypal.com/127.0.0.1#5335 +ipset=/fundpaypal.com/gfwlist +server=/openstreetmap.org/127.0.0.1#5335 +ipset=/openstreetmap.org/gfwlist +server=/smokinmovies.com/127.0.0.1#5335 +ipset=/smokinmovies.com/gfwlist +server=/feceboock.com/127.0.0.1#5335 +ipset=/feceboock.com/gfwlist +server=/futhead.com/127.0.0.1#5335 +ipset=/futhead.com/gfwlist +server=/pornwatchers.com/127.0.0.1#5335 +ipset=/pornwatchers.com/gfwlist +server=/jav168.cc/127.0.0.1#5335 +ipset=/jav168.cc/gfwlist +server=/scholar.google.be/127.0.0.1#5335 +ipset=/scholar.google.be/gfwlist +server=/directvlebanontn.com/127.0.0.1#5335 +ipset=/directvlebanontn.com/gfwlist +server=/battlefield3.com/127.0.0.1#5335 +ipset=/battlefield3.com/gfwlist +server=/beatsbydrew.com/127.0.0.1#5335 +ipset=/beatsbydrew.com/gfwlist +server=/earlyob.com/127.0.0.1#5335 +ipset=/earlyob.com/gfwlist +server=/beatsbydrevipde.com/127.0.0.1#5335 +ipset=/beatsbydrevipde.com/gfwlist +server=/69xporn.com/127.0.0.1#5335 +ipset=/69xporn.com/gfwlist +server=/bstatic.com/127.0.0.1#5335 +ipset=/bstatic.com/gfwlist +server=/taboola.com/127.0.0.1#5335 +ipset=/taboola.com/gfwlist +server=/google.lk/127.0.0.1#5335 +ipset=/google.lk/gfwlist +server=/beatsbydresingaporesale.com/127.0.0.1#5335 +ipset=/beatsbydresingaporesale.com/gfwlist +server=/littlesexdolls.com/127.0.0.1#5335 +ipset=/littlesexdolls.com/gfwlist +server=/hponlineprinting.com/127.0.0.1#5335 +ipset=/hponlineprinting.com/gfwlist +server=/pokemonplatinum.com/127.0.0.1#5335 +ipset=/pokemonplatinum.com/gfwlist +server=/steamuserimages-a.akamaihd.net/127.0.0.1#5335 +ipset=/steamuserimages-a.akamaihd.net/gfwlist +server=/bmw-bahrain.com/127.0.0.1#5335 +ipset=/bmw-bahrain.com/gfwlist +server=/beatsbydreshop-uk.com/127.0.0.1#5335 +ipset=/beatsbydreshop-uk.com/gfwlist +server=/nikeby.com/127.0.0.1#5335 +ipset=/nikeby.com/gfwlist +server=/linkedin.sc.omtrdc.net/127.0.0.1#5335 +ipset=/linkedin.sc.omtrdc.net/gfwlist +server=/myfoxhurricane.com/127.0.0.1#5335 +ipset=/myfoxhurricane.com/gfwlist +server=/facebooklivestaging.net/127.0.0.1#5335 +ipset=/facebooklivestaging.net/gfwlist +server=/beatsbydrerealstore.com/127.0.0.1#5335 +ipset=/beatsbydrerealstore.com/gfwlist +server=/xxxbit.com/127.0.0.1#5335 +ipset=/xxxbit.com/gfwlist +server=/privilege.hk/127.0.0.1#5335 +ipset=/privilege.hk/gfwlist +server=/mastercard.it/127.0.0.1#5335 +ipset=/mastercard.it/gfwlist +server=/beatsbydreonlinesale-nz.com/127.0.0.1#5335 +ipset=/beatsbydreonlinesale-nz.com/gfwlist +server=/mozilla.community/127.0.0.1#5335 +ipset=/mozilla.community/gfwlist +server=/kismia.com/127.0.0.1#5335 +ipset=/kismia.com/gfwlist +server=/pxt.io/127.0.0.1#5335 +ipset=/pxt.io/gfwlist +server=/testonfox.com/127.0.0.1#5335 +ipset=/testonfox.com/gfwlist +server=/pussyboy.net/127.0.0.1#5335 +ipset=/pussyboy.net/gfwlist +server=/enfasmart.com/127.0.0.1#5335 +ipset=/enfasmart.com/gfwlist +server=/taste.com.au/127.0.0.1#5335 +ipset=/taste.com.au/gfwlist +server=/porndiscounts.com/127.0.0.1#5335 +ipset=/porndiscounts.com/gfwlist +server=/beatsbydrenorge1.net/127.0.0.1#5335 +ipset=/beatsbydrenorge1.net/gfwlist +server=/beatsbydrenls.com/127.0.0.1#5335 +ipset=/beatsbydrenls.com/gfwlist +server=/nikezoom.com/127.0.0.1#5335 +ipset=/nikezoom.com/gfwlist +server=/lilhumpers.com/127.0.0.1#5335 +ipset=/lilhumpers.com/gfwlist +server=/crypton.co.jp/127.0.0.1#5335 +ipset=/crypton.co.jp/gfwlist +server=/blzddistkr1-a.akamaihd.net/127.0.0.1#5335 +ipset=/blzddistkr1-a.akamaihd.net/gfwlist +server=/beatsbydreirelandsonline.com/127.0.0.1#5335 +ipset=/beatsbydreirelandsonline.com/gfwlist +server=/ign.jp/127.0.0.1#5335 +ipset=/ign.jp/gfwlist +server=/beatsbydreirelandsale.com/127.0.0.1#5335 +ipset=/beatsbydreirelandsale.com/gfwlist +server=/emcs.org/127.0.0.1#5335 +ipset=/emcs.org/gfwlist +server=/paypal-learning.com/127.0.0.1#5335 +ipset=/paypal-learning.com/gfwlist +server=/beatsbydrehut.com/127.0.0.1#5335 +ipset=/beatsbydrehut.com/gfwlist +server=/daylenerio.com/127.0.0.1#5335 +ipset=/daylenerio.com/gfwlist +server=/stackmod.blog/127.0.0.1#5335 +ipset=/stackmod.blog/gfwlist +server=/sextime.tv/127.0.0.1#5335 +ipset=/sextime.tv/gfwlist +server=/yeyuehuachao12.com/127.0.0.1#5335 +ipset=/yeyuehuachao12.com/gfwlist +server=/libsolutions.app/127.0.0.1#5335 +ipset=/libsolutions.app/gfwlist +server=/beatsbydredr.com/127.0.0.1#5335 +ipset=/beatsbydredr.com/gfwlist +server=/f95zone.to/127.0.0.1#5335 +ipset=/f95zone.to/gfwlist +server=/imagetwist.com/127.0.0.1#5335 +ipset=/imagetwist.com/gfwlist +server=/youtube.com.mt/127.0.0.1#5335 +ipset=/youtube.com.mt/gfwlist +server=/beatsjoy.com/127.0.0.1#5335 +ipset=/beatsjoy.com/gfwlist +server=/dropboxapi.com/127.0.0.1#5335 +ipset=/dropboxapi.com/gfwlist +server=/blogspot.ba/127.0.0.1#5335 +ipset=/blogspot.ba/gfwlist +server=/beatsbydredealsblackfriday.com/127.0.0.1#5335 +ipset=/beatsbydredealsblackfriday.com/gfwlist +server=/playporngame.com/127.0.0.1#5335 +ipset=/playporngame.com/gfwlist +server=/oxfordbibliographies.com/127.0.0.1#5335 +ipset=/oxfordbibliographies.com/gfwlist +server=/akamak.com/127.0.0.1#5335 +ipset=/akamak.com/gfwlist +server=/buhidoh.net/127.0.0.1#5335 +ipset=/buhidoh.net/gfwlist +server=/spotify.map.fastly.net/127.0.0.1#5335 +ipset=/spotify.map.fastly.net/gfwlist +server=/braintreegateway.tv/127.0.0.1#5335 +ipset=/braintreegateway.tv/gfwlist +server=/fadebook.com/127.0.0.1#5335 +ipset=/fadebook.com/gfwlist +server=/bmw-routes.com/127.0.0.1#5335 +ipset=/bmw-routes.com/gfwlist +server=/beatsbydreblackfriday2013.com/127.0.0.1#5335 +ipset=/beatsbydreblackfriday2013.com/gfwlist +server=/hnntube.com/127.0.0.1#5335 +ipset=/hnntube.com/gfwlist +server=/boypost.com/127.0.0.1#5335 +ipset=/boypost.com/gfwlist +server=/beatsbydre4usales.com/127.0.0.1#5335 +ipset=/beatsbydre4usales.com/gfwlist +server=/beatsbydre411.com/127.0.0.1#5335 +ipset=/beatsbydre411.com/gfwlist +server=/rsc.org/127.0.0.1#5335 +ipset=/rsc.org/gfwlist +server=/mrchewsasianbeaver.com/127.0.0.1#5335 +ipset=/mrchewsasianbeaver.com/gfwlist +server=/verisign.org/127.0.0.1#5335 +ipset=/verisign.org/gfwlist +server=/huluplus.com/127.0.0.1#5335 +ipset=/huluplus.com/gfwlist +server=/beatsbydre-mall.com/127.0.0.1#5335 +ipset=/beatsbydre-mall.com/gfwlist +server=/nextplus.com.hk/127.0.0.1#5335 +ipset=/nextplus.com.hk/gfwlist +server=/joinclubhouse.com/127.0.0.1#5335 +ipset=/joinclubhouse.com/gfwlist +server=/88square.com/127.0.0.1#5335 +ipset=/88square.com/gfwlist +server=/69gayporno.com/127.0.0.1#5335 +ipset=/69gayporno.com/gfwlist +server=/beatsbydre-beatsheadphone.com/127.0.0.1#5335 +ipset=/beatsbydre-beatsheadphone.com/gfwlist +server=/avh.world/127.0.0.1#5335 +ipset=/avh.world/gfwlist +server=/bdn.dev/127.0.0.1#5335 +ipset=/bdn.dev/gfwlist +server=/alphaporno.com/127.0.0.1#5335 +ipset=/alphaporno.com/gfwlist +server=/mastercard.nl/127.0.0.1#5335 +ipset=/mastercard.nl/gfwlist +server=/miniitalianjob.com/127.0.0.1#5335 +ipset=/miniitalianjob.com/gfwlist +server=/cuckoldfuck.com/127.0.0.1#5335 +ipset=/cuckoldfuck.com/gfwlist +server=/volvobuses.com.kw/127.0.0.1#5335 +ipset=/volvobuses.com.kw/gfwlist +server=/favjapaneseporn.com/127.0.0.1#5335 +ipset=/favjapaneseporn.com/gfwlist +server=/cbsivideo.com/127.0.0.1#5335 +ipset=/cbsivideo.com/gfwlist +server=/businessweek.com/127.0.0.1#5335 +ipset=/businessweek.com/gfwlist +server=/beatsbydrdre-store.com/127.0.0.1#5335 +ipset=/beatsbydrdre-store.com/gfwlist +server=/forgecdn.net/127.0.0.1#5335 +ipset=/forgecdn.net/gfwlist +server=/beatsbydrdre-online.com/127.0.0.1#5335 +ipset=/beatsbydrdre-online.com/gfwlist +server=/graph.org/127.0.0.1#5335 +ipset=/graph.org/gfwlist +server=/ikea.ua/127.0.0.1#5335 +ipset=/ikea.ua/gfwlist +server=/pokemonmysterydungeon.com/127.0.0.1#5335 +ipset=/pokemonmysterydungeon.com/gfwlist +server=/volvobuses.co.uk/127.0.0.1#5335 +ipset=/volvobuses.co.uk/gfwlist +server=/aga-expo.com/127.0.0.1#5335 +ipset=/aga-expo.com/gfwlist +server=/beatsaudiobydre.com/127.0.0.1#5335 +ipset=/beatsaudiobydre.com/gfwlist +server=/jfrog.org/127.0.0.1#5335 +ipset=/jfrog.org/gfwlist +server=/beatsaudifonos.com/127.0.0.1#5335 +ipset=/beatsaudifonos.com/gfwlist +server=/sexysexdoll.com/127.0.0.1#5335 +ipset=/sexysexdoll.com/gfwlist +server=/fetishfishcams.com/127.0.0.1#5335 +ipset=/fetishfishcams.com/gfwlist +server=/marioandluigidreamteam.com/127.0.0.1#5335 +ipset=/marioandluigidreamteam.com/gfwlist +server=/xn--hxtr4rozx.xn--czr694b/127.0.0.1#5335 +ipset=/xn--hxtr4rozx.xn--czr694b/gfwlist +server=/beats4.net/127.0.0.1#5335 +ipset=/beats4.net/gfwlist +server=/igsonar.com/127.0.0.1#5335 +ipset=/igsonar.com/gfwlist +server=/beats123.com/127.0.0.1#5335 +ipset=/beats123.com/gfwlist +server=/javfilms.com/127.0.0.1#5335 +ipset=/javfilms.com/gfwlist +server=/beats1.cc/127.0.0.1#5335 +ipset=/beats1.cc/gfwlist +server=/nineentertainmentco.com.au/127.0.0.1#5335 +ipset=/nineentertainmentco.com.au/gfwlist +server=/visa.mq/127.0.0.1#5335 +ipset=/visa.mq/gfwlist +server=/bmwmperformance.com/127.0.0.1#5335 +ipset=/bmwmperformance.com/gfwlist +server=/lordofultima.com/127.0.0.1#5335 +ipset=/lordofultima.com/gfwlist +server=/cloudflare.tv/127.0.0.1#5335 +ipset=/cloudflare.tv/gfwlist +server=/mini.bg/127.0.0.1#5335 +ipset=/mini.bg/gfwlist +server=/hugedildo.com/127.0.0.1#5335 +ipset=/hugedildo.com/gfwlist +server=/connectionsacademy.com/127.0.0.1#5335 +ipset=/connectionsacademy.com/gfwlist +server=/citasecuador.com/127.0.0.1#5335 +ipset=/citasecuador.com/gfwlist +server=/cartoonpornvideos.com/127.0.0.1#5335 +ipset=/cartoonpornvideos.com/gfwlist +server=/mini-abudhabi.com/127.0.0.1#5335 +ipset=/mini-abudhabi.com/gfwlist +server=/beats-bydreoutletssale.net/127.0.0.1#5335 +ipset=/beats-bydreoutletssale.net/gfwlist +server=/hibdontire.com/127.0.0.1#5335 +ipset=/hibdontire.com/gfwlist +server=/beats-bydreoutletsale.com/127.0.0.1#5335 +ipset=/beats-bydreoutletsale.com/gfwlist +server=/minimontroyal.com/127.0.0.1#5335 +ipset=/minimontroyal.com/gfwlist +server=/8111y.top/127.0.0.1#5335 +ipset=/8111y.top/gfwlist +server=/nikeshoxsale.com/127.0.0.1#5335 +ipset=/nikeshoxsale.com/gfwlist +server=/beats-bydrdre.net/127.0.0.1#5335 +ipset=/beats-bydrdre.net/gfwlist +server=/beats-by-dre-australia.com/127.0.0.1#5335 +ipset=/beats-by-dre-australia.com/gfwlist +server=/volvotrucks.dk/127.0.0.1#5335 +ipset=/volvotrucks.dk/gfwlist +server=/9zipai.net/127.0.0.1#5335 +ipset=/9zipai.net/gfwlist +server=/volvotrucks.fi/127.0.0.1#5335 +ipset=/volvotrucks.fi/gfwlist +server=/mini.ro/127.0.0.1#5335 +ipset=/mini.ro/gfwlist +server=/porn7.xxx/127.0.0.1#5335 +ipset=/porn7.xxx/gfwlist +server=/beatmonstersaustralia.net/127.0.0.1#5335 +ipset=/beatmonstersaustralia.net/gfwlist +server=/lxxlxx.com/127.0.0.1#5335 +ipset=/lxxlxx.com/gfwlist +server=/beatbydremonster.com/127.0.0.1#5335 +ipset=/beatbydremonster.com/gfwlist +server=/beatbydre2013.com/127.0.0.1#5335 +ipset=/beatbydre2013.com/gfwlist +server=/getws1.com/127.0.0.1#5335 +ipset=/getws1.com/gfwlist +server=/baxsound.com/127.0.0.1#5335 +ipset=/baxsound.com/gfwlist +server=/auricularesbeatsmarkt.com/127.0.0.1#5335 +ipset=/auricularesbeatsmarkt.com/gfwlist +server=/nudegfporn.com/127.0.0.1#5335 +ipset=/nudegfporn.com/gfwlist +server=/epochbuy.com/127.0.0.1#5335 +ipset=/epochbuy.com/gfwlist +server=/faceboock.com/127.0.0.1#5335 +ipset=/faceboock.com/gfwlist +server=/anandtech.com/127.0.0.1#5335 +ipset=/anandtech.com/gfwlist +server=/audiobeatsbydre.com/127.0.0.1#5335 +ipset=/audiobeatsbydre.com/gfwlist +server=/app-store.wang/127.0.0.1#5335 +ipset=/app-store.wang/gfwlist +server=/historyofdota.net/127.0.0.1#5335 +ipset=/historyofdota.net/gfwlist +server=/foxrelease.com/127.0.0.1#5335 +ipset=/foxrelease.com/gfwlist +server=/stepdaughter.love/127.0.0.1#5335 +ipset=/stepdaughter.love/gfwlist +server=/alphera-finance.co.in/127.0.0.1#5335 +ipset=/alphera-finance.co.in/gfwlist +server=/farfetch-contents.com/127.0.0.1#5335 +ipset=/farfetch-contents.com/gfwlist +server=/gay1069sex.com/127.0.0.1#5335 +ipset=/gay1069sex.com/gfwlist +server=/aws-iot-hackathon.com/127.0.0.1#5335 +ipset=/aws-iot-hackathon.com/gfwlist +server=/volvo-truck.nl/127.0.0.1#5335 +ipset=/volvo-truck.nl/gfwlist +server=/aanaan.com/127.0.0.1#5335 +ipset=/aanaan.com/gfwlist +server=/pearsonassessment.no/127.0.0.1#5335 +ipset=/pearsonassessment.no/gfwlist +server=/adobelogin.com/127.0.0.1#5335 +ipset=/adobelogin.com/gfwlist +server=/bridgestone-brand.com/127.0.0.1#5335 +ipset=/bridgestone-brand.com/gfwlist +server=/bmw-motorrad.com.do/127.0.0.1#5335 +ipset=/bmw-motorrad.com.do/gfwlist +server=/2drdrebeats.com/127.0.0.1#5335 +ipset=/2drdrebeats.com/gfwlist +server=/ultrayoungsex.com/127.0.0.1#5335 +ipset=/ultrayoungsex.com/gfwlist +server=/allpasswords.com/127.0.0.1#5335 +ipset=/allpasswords.com/gfwlist +server=/xn--4vq477m.com/127.0.0.1#5335 +ipset=/xn--4vq477m.com/gfwlist +server=/metcams.com/127.0.0.1#5335 +ipset=/metcams.com/gfwlist +server=/caribbeancom.com/127.0.0.1#5335 +ipset=/caribbeancom.com/gfwlist +server=/voaswahili.com/127.0.0.1#5335 +ipset=/voaswahili.com/gfwlist +server=/fanqianglu.com/127.0.0.1#5335 +ipset=/fanqianglu.com/gfwlist +server=/pearsonplaces.com.au/127.0.0.1#5335 +ipset=/pearsonplaces.com.au/gfwlist +server=/starwarsfallenorder.com/127.0.0.1#5335 +ipset=/starwarsfallenorder.com/gfwlist +server=/womenwill.mx/127.0.0.1#5335 +ipset=/womenwill.mx/gfwlist +server=/bizographics.com/127.0.0.1#5335 +ipset=/bizographics.com/gfwlist +server=/certum.pl/127.0.0.1#5335 +ipset=/certum.pl/gfwlist +server=/disneyplus.com/127.0.0.1#5335 +ipset=/disneyplus.com/gfwlist +server=/bluffyporn.com/127.0.0.1#5335 +ipset=/bluffyporn.com/gfwlist +server=/terrlficdates.com/127.0.0.1#5335 +ipset=/terrlficdates.com/gfwlist +server=/gameon-masters.com/127.0.0.1#5335 +ipset=/gameon-masters.com/gfwlist +server=/associates-amazon.com/127.0.0.1#5335 +ipset=/associates-amazon.com/gfwlist +server=/3xplanet.com/127.0.0.1#5335 +ipset=/3xplanet.com/gfwlist +server=/amzn.com/127.0.0.1#5335 +ipset=/amzn.com/gfwlist +server=/sex021.net/127.0.0.1#5335 +ipset=/sex021.net/gfwlist +server=/ulrichsweb.serialssolutions.com/127.0.0.1#5335 +ipset=/ulrichsweb.serialssolutions.com/gfwlist +server=/espn.api.edge.bamgrid.com/127.0.0.1#5335 +ipset=/espn.api.edge.bamgrid.com/gfwlist +server=/halfcanada.com/127.0.0.1#5335 +ipset=/halfcanada.com/gfwlist +server=/ebayboutique.com/127.0.0.1#5335 +ipset=/ebayboutique.com/gfwlist +server=/amazonpay.com/127.0.0.1#5335 +ipset=/amazonpay.com/gfwlist +server=/battlefield4.com/127.0.0.1#5335 +ipset=/battlefield4.com/gfwlist +server=/opencreate.org/127.0.0.1#5335 +ipset=/opencreate.org/gfwlist +server=/hentaivvz.com/127.0.0.1#5335 +ipset=/hentaivvz.com/gfwlist +server=/paypal-community.net/127.0.0.1#5335 +ipset=/paypal-community.net/gfwlist +server=/gvt5.com/127.0.0.1#5335 +ipset=/gvt5.com/gfwlist +server=/amazonimages.com/127.0.0.1#5335 +ipset=/amazonimages.com/gfwlist +server=/ipfs-gateway.cloud/127.0.0.1#5335 +ipset=/ipfs-gateway.cloud/gfwlist +server=/iwork.com/127.0.0.1#5335 +ipset=/iwork.com/gfwlist +server=/amazonbusiness.org/127.0.0.1#5335 +ipset=/amazonbusiness.org/gfwlist +server=/hentai-img.com/127.0.0.1#5335 +ipset=/hentai-img.com/gfwlist +server=/gendai.net/127.0.0.1#5335 +ipset=/gendai.net/gfwlist +server=/eubluecardvisa.com/127.0.0.1#5335 +ipset=/eubluecardvisa.com/gfwlist +server=/pornproxy.app/127.0.0.1#5335 +ipset=/pornproxy.app/gfwlist +server=/researchgate.net/127.0.0.1#5335 +ipset=/researchgate.net/gfwlist +server=/bestbuyethics.com/127.0.0.1#5335 +ipset=/bestbuyethics.com/gfwlist +server=/amazon.com.au/127.0.0.1#5335 +ipset=/amazon.com.au/gfwlist +server=/imageworks.com/127.0.0.1#5335 +ipset=/imageworks.com/gfwlist +server=/youtube.co.il/127.0.0.1#5335 +ipset=/youtube.co.il/gfwlist +server=/sony.sk/127.0.0.1#5335 +ipset=/sony.sk/gfwlist +server=/aboutamazon.in/127.0.0.1#5335 +ipset=/aboutamazon.in/gfwlist +server=/aboutamazon.de/127.0.0.1#5335 +ipset=/aboutamazon.de/gfwlist +server=/rthk.hk/127.0.0.1#5335 +ipset=/rthk.hk/gfwlist +server=/aboutamazon.com.au/127.0.0.1#5335 +ipset=/aboutamazon.com.au/gfwlist +server=/bloombergenvironment.com/127.0.0.1#5335 +ipset=/bloombergenvironment.com/gfwlist +server=/wfm.com/127.0.0.1#5335 +ipset=/wfm.com/gfwlist +server=/heydoga.com/127.0.0.1#5335 +ipset=/heydoga.com/gfwlist +server=/pearson.com.uy/127.0.0.1#5335 +ipset=/pearson.com.uy/gfwlist +server=/demfhz.xyz/127.0.0.1#5335 +ipset=/demfhz.xyz/gfwlist +server=/bridgestonecomercial.cl/127.0.0.1#5335 +ipset=/bridgestonecomercial.cl/gfwlist +server=/libsolutions.domains/127.0.0.1#5335 +ipset=/libsolutions.domains/gfwlist +server=/zohomeetups.com/127.0.0.1#5335 +ipset=/zohomeetups.com/gfwlist +server=/mastercard.com.vn/127.0.0.1#5335 +ipset=/mastercard.com.vn/gfwlist +server=/kindle.co.uk/127.0.0.1#5335 +ipset=/kindle.co.uk/gfwlist +server=/containersonaws.com/127.0.0.1#5335 +ipset=/containersonaws.com/gfwlist +server=/cloudfront.net/127.0.0.1#5335 +ipset=/cloudfront.net/gfwlist +server=/gaypornlinks.com/127.0.0.1#5335 +ipset=/gaypornlinks.com/gfwlist +server=/monsterbeatspascher.net/127.0.0.1#5335 +ipset=/monsterbeatspascher.net/gfwlist +server=/hulu.playback.edge.bamgrid.com/127.0.0.1#5335 +ipset=/hulu.playback.edge.bamgrid.com/gfwlist +server=/bcbits.com/127.0.0.1#5335 +ipset=/bcbits.com/gfwlist +server=/appl.com/127.0.0.1#5335 +ipset=/appl.com/gfwlist +server=/awseducate.com/127.0.0.1#5335 +ipset=/awseducate.com/gfwlist +server=/durex.jp/127.0.0.1#5335 +ipset=/durex.jp/gfwlist +server=/kinkbook.com/127.0.0.1#5335 +ipset=/kinkbook.com/gfwlist +server=/origin-a.akamaihd.net/127.0.0.1#5335 +ipset=/origin-a.akamaihd.net/gfwlist +server=/alfera.in/127.0.0.1#5335 +ipset=/alfera.in/gfwlist +server=/mhradio.org/127.0.0.1#5335 +ipset=/mhradio.org/gfwlist +server=/gmail.com/127.0.0.1#5335 +ipset=/gmail.com/gfwlist +server=/minidowntown.ca/127.0.0.1#5335 +ipset=/minidowntown.ca/gfwlist +server=/ikea.de/127.0.0.1#5335 +ipset=/ikea.de/gfwlist +server=/uun92.com/127.0.0.1#5335 +ipset=/uun92.com/gfwlist +server=/visa.com.ua/127.0.0.1#5335 +ipset=/visa.com.ua/gfwlist +server=/ebayclassifieds.org/127.0.0.1#5335 +ipset=/ebayclassifieds.org/gfwlist +server=/product.co.jp/127.0.0.1#5335 +ipset=/product.co.jp/gfwlist +server=/amazonses.com/127.0.0.1#5335 +ipset=/amazonses.com/gfwlist +server=/cheapbeatsdrestudios.com/127.0.0.1#5335 +ipset=/cheapbeatsdrestudios.com/gfwlist +server=/amazonaws.tv/127.0.0.1#5335 +ipset=/amazonaws.tv/gfwlist +server=/6japaneseporn.com/127.0.0.1#5335 +ipset=/6japaneseporn.com/gfwlist +server=/amazonaws-china.com/127.0.0.1#5335 +ipset=/amazonaws-china.com/gfwlist +server=/digital-rb.com/127.0.0.1#5335 +ipset=/digital-rb.com/gfwlist +server=/hopstop.tv/127.0.0.1#5335 +ipset=/hopstop.tv/gfwlist +server=/ymail.com/127.0.0.1#5335 +ipset=/ymail.com/gfwlist +server=/69flv.com/127.0.0.1#5335 +ipset=/69flv.com/gfwlist +server=/bootstrapcdn.com/127.0.0.1#5335 +ipset=/bootstrapcdn.com/gfwlist +server=/mastercard.ro/127.0.0.1#5335 +ipset=/mastercard.ro/gfwlist +server=/alibabacloud.com.sg/127.0.0.1#5335 +ipset=/alibabacloud.com.sg/gfwlist +server=/nintendoswitch.com/127.0.0.1#5335 +ipset=/nintendoswitch.com/gfwlist +server=/b-ok.asia/127.0.0.1#5335 +ipset=/b-ok.asia/gfwlist +server=/medrxiv.org/127.0.0.1#5335 +ipset=/medrxiv.org/gfwlist +server=/fetlife.com/127.0.0.1#5335 +ipset=/fetlife.com/gfwlist +server=/fzdshare.net/127.0.0.1#5335 +ipset=/fzdshare.net/gfwlist +server=/omscr.com/127.0.0.1#5335 +ipset=/omscr.com/gfwlist +server=/pearsonclinical.com.au/127.0.0.1#5335 +ipset=/pearsonclinical.com.au/gfwlist +server=/alibabacloud.co.in/127.0.0.1#5335 +ipset=/alibabacloud.co.in/gfwlist +server=/hptechventures.com/127.0.0.1#5335 +ipset=/hptechventures.com/gfwlist +server=/sonyclassics.com/127.0.0.1#5335 +ipset=/sonyclassics.com/gfwlist +server=/rexcha.com/127.0.0.1#5335 +ipset=/rexcha.com/gfwlist +server=/redditstatic.com/127.0.0.1#5335 +ipset=/redditstatic.com/gfwlist +server=/amateurwifevideos.com/127.0.0.1#5335 +ipset=/amateurwifevideos.com/gfwlist +server=/nikefootballgloves.com/127.0.0.1#5335 +ipset=/nikefootballgloves.com/gfwlist +server=/rimg.com.tw/127.0.0.1#5335 +ipset=/rimg.com.tw/gfwlist +server=/orbitera.com/127.0.0.1#5335 +ipset=/orbitera.com/gfwlist +server=/sex-ly.com/127.0.0.1#5335 +ipset=/sex-ly.com/gfwlist +server=/youtube.com.ar/127.0.0.1#5335 +ipset=/youtube.com.ar/gfwlist +server=/juggsjoy.com/127.0.0.1#5335 +ipset=/juggsjoy.com/gfwlist +server=/ntd.tv/127.0.0.1#5335 +ipset=/ntd.tv/gfwlist +server=/motolia.com/127.0.0.1#5335 +ipset=/motolia.com/gfwlist +server=/wife-home-videos.com/127.0.0.1#5335 +ipset=/wife-home-videos.com/gfwlist +server=/netname.com.br/127.0.0.1#5335 +ipset=/netname.com.br/gfwlist +server=/fptolia.com/127.0.0.1#5335 +ipset=/fptolia.com/gfwlist +server=/deviantclip.com/127.0.0.1#5335 +ipset=/deviantclip.com/gfwlist +server=/fotolia-noticias.com/127.0.0.1#5335 +ipset=/fotolia-noticias.com/gfwlist +server=/worldflipper.akamaized.net/127.0.0.1#5335 +ipset=/worldflipper.akamaized.net/gfwlist +server=/fonolia.com/127.0.0.1#5335 +ipset=/fonolia.com/gfwlist +server=/disneymeetingsandevents.com/127.0.0.1#5335 +ipset=/disneymeetingsandevents.com/gfwlist +server=/bridgestone-business-service.jp/127.0.0.1#5335 +ipset=/bridgestone-business-service.jp/gfwlist +server=/huffingtonpost.co.za/127.0.0.1#5335 +ipset=/huffingtonpost.co.za/gfwlist +server=/foftolia.com/127.0.0.1#5335 +ipset=/foftolia.com/gfwlist +server=/fiotolia.com/127.0.0.1#5335 +ipset=/fiotolia.com/gfwlist +server=/visa.com.bz/127.0.0.1#5335 +ipset=/visa.com.bz/gfwlist +server=/webex.co.nz/127.0.0.1#5335 +ipset=/webex.co.nz/gfwlist +server=/nexttv.com.tw/127.0.0.1#5335 +ipset=/nexttv.com.tw/gfwlist +server=/adobeccstatic.com/127.0.0.1#5335 +ipset=/adobeccstatic.com/gfwlist +server=/worldsecureemail.com/127.0.0.1#5335 +ipset=/worldsecureemail.com/gfwlist +server=/ettoday.net/127.0.0.1#5335 +ipset=/ettoday.net/gfwlist +server=/dirtyhomefuck.com/127.0.0.1#5335 +ipset=/dirtyhomefuck.com/gfwlist +server=/battlefrontii.com/127.0.0.1#5335 +ipset=/battlefrontii.com/gfwlist +server=/imagineecommerce.com/127.0.0.1#5335 +ipset=/imagineecommerce.com/gfwlist +server=/wiz-s.jp/127.0.0.1#5335 +ipset=/wiz-s.jp/gfwlist +server=/zee.com/127.0.0.1#5335 +ipset=/zee.com/gfwlist +server=/fuckingthreesome.com/127.0.0.1#5335 +ipset=/fuckingthreesome.com/gfwlist +server=/tx.me/127.0.0.1#5335 +ipset=/tx.me/gfwlist +server=/kidgrid.tv/127.0.0.1#5335 +ipset=/kidgrid.tv/gfwlist +server=/porno-erotica.com/127.0.0.1#5335 +ipset=/porno-erotica.com/gfwlist +server=/flyingjizz.com/127.0.0.1#5335 +ipset=/flyingjizz.com/gfwlist +server=/pornobrasileiro.xyz/127.0.0.1#5335 +ipset=/pornobrasileiro.xyz/gfwlist +server=/microsoft.md/127.0.0.1#5335 +ipset=/microsoft.md/gfwlist +server=/bestfreecams.club/127.0.0.1#5335 +ipset=/bestfreecams.club/gfwlist +server=/9nation.com.au/127.0.0.1#5335 +ipset=/9nation.com.au/gfwlist +server=/watersex.com/127.0.0.1#5335 +ipset=/watersex.com/gfwlist +server=/mailonline.co.uk/127.0.0.1#5335 +ipset=/mailonline.co.uk/gfwlist +server=/adobetechcomm.com/127.0.0.1#5335 +ipset=/adobetechcomm.com/gfwlist +server=/adobestock.com/127.0.0.1#5335 +ipset=/adobestock.com/gfwlist +server=/jinnaju.com/127.0.0.1#5335 +ipset=/jinnaju.com/gfwlist +server=/sci-hub.it.nf/127.0.0.1#5335 +ipset=/sci-hub.it.nf/gfwlist +server=/bmw-motorrad.tw/127.0.0.1#5335 +ipset=/bmw-motorrad.tw/gfwlist +server=/albeats.com/127.0.0.1#5335 +ipset=/albeats.com/gfwlist +server=/gaypornonly.com/127.0.0.1#5335 +ipset=/gaypornonly.com/gfwlist +server=/adobelanding.com/127.0.0.1#5335 +ipset=/adobelanding.com/gfwlist +server=/adobejanus.com/127.0.0.1#5335 +ipset=/adobejanus.com/gfwlist +server=/adultvideodump.com/127.0.0.1#5335 +ipset=/adultvideodump.com/gfwlist +server=/google.co.zm/127.0.0.1#5335 +ipset=/google.co.zm/gfwlist +server=/visa.com.ai/127.0.0.1#5335 +ipset=/visa.com.ai/gfwlist +server=/nytimes.com/127.0.0.1#5335 +ipset=/nytimes.com/gfwlist +server=/mastercard.com.bz/127.0.0.1#5335 +ipset=/mastercard.com.bz/gfwlist +server=/adobedemo.com/127.0.0.1#5335 +ipset=/adobedemo.com/gfwlist +server=/facebopk.com/127.0.0.1#5335 +ipset=/facebopk.com/gfwlist +server=/imacapplecomputer.com/127.0.0.1#5335 +ipset=/imacapplecomputer.com/gfwlist +server=/youtube.com/127.0.0.1#5335 +ipset=/youtube.com/gfwlist +server=/vhxqa4.com/127.0.0.1#5335 +ipset=/vhxqa4.com/gfwlist +server=/indianpornvideo.org/127.0.0.1#5335 +ipset=/indianpornvideo.org/gfwlist +server=/voachinese.com/127.0.0.1#5335 +ipset=/voachinese.com/gfwlist +server=/indianfuck2.com/127.0.0.1#5335 +ipset=/indianfuck2.com/gfwlist +server=/manoramayearbook.in/127.0.0.1#5335 +ipset=/manoramayearbook.in/gfwlist +server=/airtunes.com/127.0.0.1#5335 +ipset=/airtunes.com/gfwlist +server=/adobe.ly/127.0.0.1#5335 +ipset=/adobe.ly/gfwlist +server=/mymusclevideo.com/127.0.0.1#5335 +ipset=/mymusclevideo.com/gfwlist +server=/targetimg1.com/127.0.0.1#5335 +ipset=/targetimg1.com/gfwlist +server=/visa.com.pr/127.0.0.1#5335 +ipset=/visa.com.pr/gfwlist +server=/elderscrolls.com/127.0.0.1#5335 +ipset=/elderscrolls.com/gfwlist +server=/scholar.google.com.tr/127.0.0.1#5335 +ipset=/scholar.google.com.tr/gfwlist +server=/uun96.com/127.0.0.1#5335 +ipset=/uun96.com/gfwlist +server=/hbabit.com/127.0.0.1#5335 +ipset=/hbabit.com/gfwlist +server=/adobe-audience-finder.com/127.0.0.1#5335 +ipset=/adobe-audience-finder.com/gfwlist +server=/allpornsitespass.com/127.0.0.1#5335 +ipset=/allpornsitespass.com/gfwlist +server=/beatsoutletonlines.com/127.0.0.1#5335 +ipset=/beatsoutletonlines.com/gfwlist +server=/bybeatsdre.com/127.0.0.1#5335 +ipset=/bybeatsdre.com/gfwlist +server=/qualcomm-email.com/127.0.0.1#5335 +ipset=/qualcomm-email.com/gfwlist +server=/vod-dash-ww-live.akamaized.net/127.0.0.1#5335 +ipset=/vod-dash-ww-live.akamaized.net/gfwlist +server=/onxxxtube.com/127.0.0.1#5335 +ipset=/onxxxtube.com/gfwlist +server=/goldjizz.com/127.0.0.1#5335 +ipset=/goldjizz.com/gfwlist +server=/electronicarts.com/127.0.0.1#5335 +ipset=/electronicarts.com/gfwlist +server=/advertising.adobe.com/127.0.0.1#5335 +ipset=/advertising.adobe.com/gfwlist +server=/acer.com/127.0.0.1#5335 +ipset=/acer.com/gfwlist +server=/ikea.co.th/127.0.0.1#5335 +ipset=/ikea.co.th/gfwlist +server=/zsh.org/127.0.0.1#5335 +ipset=/zsh.org/gfwlist +server=/readmoo.com/127.0.0.1#5335 +ipset=/readmoo.com/gfwlist +server=/unpkg.com/127.0.0.1#5335 +ipset=/unpkg.com/gfwlist +server=/sqlite.org/127.0.0.1#5335 +ipset=/sqlite.org/gfwlist +server=/maddenseason.org/127.0.0.1#5335 +ipset=/maddenseason.org/gfwlist +server=/r-project.org/127.0.0.1#5335 +ipset=/r-project.org/gfwlist +server=/betterhdporn.com/127.0.0.1#5335 +ipset=/betterhdporn.com/gfwlist +server=/macappsto.re/127.0.0.1#5335 +ipset=/macappsto.re/gfwlist +server=/phantomjs.org/127.0.0.1#5335 +ipset=/phantomjs.org/gfwlist +server=/im-apps.net/127.0.0.1#5335 +ipset=/im-apps.net/gfwlist +server=/gayfuror.com/127.0.0.1#5335 +ipset=/gayfuror.com/gfwlist +server=/pornmonde.com/127.0.0.1#5335 +ipset=/pornmonde.com/gfwlist +server=/openai.com/127.0.0.1#5335 +ipset=/openai.com/gfwlist +server=/porncomixonline.net/127.0.0.1#5335 +ipset=/porncomixonline.net/gfwlist +server=/apple.bg/127.0.0.1#5335 +ipset=/apple.bg/gfwlist +server=/sunglassessale2014.com/127.0.0.1#5335 +ipset=/sunglassessale2014.com/gfwlist +server=/exploitedcollegegirls.com/127.0.0.1#5335 +ipset=/exploitedcollegegirls.com/gfwlist +server=/lua.org/127.0.0.1#5335 +ipset=/lua.org/gfwlist +server=/visasignaturehotels.com/127.0.0.1#5335 +ipset=/visasignaturehotels.com/gfwlist +server=/js.org/127.0.0.1#5335 +ipset=/js.org/gfwlist +server=/mastercard.co.ve/127.0.0.1#5335 +ipset=/mastercard.co.ve/gfwlist +server=/ebaysohos.com/127.0.0.1#5335 +ipset=/ebaysohos.com/gfwlist +server=/nuespournous.com/127.0.0.1#5335 +ipset=/nuespournous.com/gfwlist +server=/deepfreeze.com.br/127.0.0.1#5335 +ipset=/deepfreeze.com.br/gfwlist +server=/pypi.io/127.0.0.1#5335 +ipset=/pypi.io/gfwlist +server=/gnu.org/127.0.0.1#5335 +ipset=/gnu.org/gfwlist +server=/icloudmusic.net/127.0.0.1#5335 +ipset=/icloudmusic.net/gfwlist +server=/juicytwink.com/127.0.0.1#5335 +ipset=/juicytwink.com/gfwlist +server=/drdremonsterdre.com/127.0.0.1#5335 +ipset=/drdremonsterdre.com/gfwlist +server=/dditsadn.com/127.0.0.1#5335 +ipset=/dditsadn.com/gfwlist +server=/meetandfuck.games/127.0.0.1#5335 +ipset=/meetandfuck.games/gfwlist +server=/steamygamer.com/127.0.0.1#5335 +ipset=/steamygamer.com/gfwlist +server=/bdsmlr.com/127.0.0.1#5335 +ipset=/bdsmlr.com/gfwlist +server=/apache.org/127.0.0.1#5335 +ipset=/apache.org/gfwlist +server=/mini.com.mt/127.0.0.1#5335 +ipset=/mini.com.mt/gfwlist +server=/fox-corporation.com/127.0.0.1#5335 +ipset=/fox-corporation.com/gfwlist +server=/webex.com.au/127.0.0.1#5335 +ipset=/webex.com.au/gfwlist +server=/swoosh.tv/127.0.0.1#5335 +ipset=/swoosh.tv/gfwlist +server=/bmw-motorrad.ma/127.0.0.1#5335 +ipset=/bmw-motorrad.ma/gfwlist +server=/xda-cdn.com/127.0.0.1#5335 +ipset=/xda-cdn.com/gfwlist +server=/intelnet.component/127.0.0.1#5335 +ipset=/intelnet.component/gfwlist +server=/bukkake-jav.com/127.0.0.1#5335 +ipset=/bukkake-jav.com/gfwlist +server=/adult.toonsearch.net/127.0.0.1#5335 +ipset=/adult.toonsearch.net/gfwlist +server=/kav.tw/127.0.0.1#5335 +ipset=/kav.tw/gfwlist +server=/dealtime.com/127.0.0.1#5335 +ipset=/dealtime.com/gfwlist +server=/girlfriendvideos.com/127.0.0.1#5335 +ipset=/girlfriendvideos.com/gfwlist +server=/unity3d.com/127.0.0.1#5335 +ipset=/unity3d.com/gfwlist +server=/disp.cc/127.0.0.1#5335 +ipset=/disp.cc/gfwlist +server=/xn--yf1at58a.com/127.0.0.1#5335 +ipset=/xn--yf1at58a.com/gfwlist +server=/dlsitenews.com/127.0.0.1#5335 +ipset=/dlsitenews.com/gfwlist +server=/booksc.xyz/127.0.0.1#5335 +ipset=/booksc.xyz/gfwlist +server=/ampproject.com/127.0.0.1#5335 +ipset=/ampproject.com/gfwlist +server=/applecare.cc/127.0.0.1#5335 +ipset=/applecare.cc/gfwlist +server=/fstopimages.com/127.0.0.1#5335 +ipset=/fstopimages.com/gfwlist +server=/camelotherald.net/127.0.0.1#5335 +ipset=/camelotherald.net/gfwlist +server=/kernel.org/127.0.0.1#5335 +ipset=/kernel.org/gfwlist +server=/dropboxstatic.com/127.0.0.1#5335 +ipset=/dropboxstatic.com/gfwlist +server=/privilege.tw/127.0.0.1#5335 +ipset=/privilege.tw/gfwlist +server=/android.com/127.0.0.1#5335 +ipset=/android.com/gfwlist +server=/batsa.me/127.0.0.1#5335 +ipset=/batsa.me/gfwlist +server=/vanish.fr/127.0.0.1#5335 +ipset=/vanish.fr/gfwlist +server=/alphera.net/127.0.0.1#5335 +ipset=/alphera.net/gfwlist +server=/wifevideos.net/127.0.0.1#5335 +ipset=/wifevideos.net/gfwlist +server=/dremonsterbeatsoutlets.com/127.0.0.1#5335 +ipset=/dremonsterbeatsoutlets.com/gfwlist +server=/fox2news.com/127.0.0.1#5335 +ipset=/fox2news.com/gfwlist +server=/beatsnzsale.com/127.0.0.1#5335 +ipset=/beatsnzsale.com/gfwlist +server=/intel.sc/127.0.0.1#5335 +ipset=/intel.sc/gfwlist +server=/stackoverflowcareers.com/127.0.0.1#5335 +ipset=/stackoverflowcareers.com/gfwlist +server=/uun79.com/127.0.0.1#5335 +ipset=/uun79.com/gfwlist +server=/volvobuses.jo/127.0.0.1#5335 +ipset=/volvobuses.jo/gfwlist +server=/ecuatorianas.best/127.0.0.1#5335 +ipset=/ecuatorianas.best/gfwlist +server=/stackoverflow.co/127.0.0.1#5335 +ipset=/stackoverflow.co/gfwlist +server=/stackoverflow.blog/127.0.0.1#5335 +ipset=/stackoverflow.blog/gfwlist +server=/connectedcommerce.com/127.0.0.1#5335 +ipset=/connectedcommerce.com/gfwlist +server=/orsm.net/127.0.0.1#5335 +ipset=/orsm.net/gfwlist +server=/paypal-business.com/127.0.0.1#5335 +ipset=/paypal-business.com/gfwlist +server=/momoniji.com/127.0.0.1#5335 +ipset=/momoniji.com/gfwlist +server=/homegrownfreaks.net/127.0.0.1#5335 +ipset=/homegrownfreaks.net/gfwlist +server=/youtube.co.ke/127.0.0.1#5335 +ipset=/youtube.co.ke/gfwlist +server=/goodporn.to/127.0.0.1#5335 +ipset=/goodporn.to/gfwlist +server=/kindle.fr/127.0.0.1#5335 +ipset=/kindle.fr/gfwlist +server=/javher.com/127.0.0.1#5335 +ipset=/javher.com/gfwlist +server=/pypi.org/127.0.0.1#5335 +ipset=/pypi.org/gfwlist +server=/lustery.com/127.0.0.1#5335 +ipset=/lustery.com/gfwlist +server=/polymerproject.org/127.0.0.1#5335 +ipset=/polymerproject.org/gfwlist +server=/facebook-covid-19.com/127.0.0.1#5335 +ipset=/facebook-covid-19.com/gfwlist +server=/hairy-amateurs.com/127.0.0.1#5335 +ipset=/hairy-amateurs.com/gfwlist +server=/jetbrains.space/127.0.0.1#5335 +ipset=/jetbrains.space/gfwlist +server=/hinet.net/127.0.0.1#5335 +ipset=/hinet.net/gfwlist +server=/perl.org/127.0.0.1#5335 +ipset=/perl.org/gfwlist +server=/maya5.net/127.0.0.1#5335 +ipset=/maya5.net/gfwlist +server=/disney.nl/127.0.0.1#5335 +ipset=/disney.nl/gfwlist +server=/garena.tv/127.0.0.1#5335 +ipset=/garena.tv/gfwlist +server=/hentaizz.net/127.0.0.1#5335 +ipset=/hentaizz.net/gfwlist +server=/mongodb.com/127.0.0.1#5335 +ipset=/mongodb.com/gfwlist +server=/eroan.xyz/127.0.0.1#5335 +ipset=/eroan.xyz/gfwlist +server=/ikea.si/127.0.0.1#5335 +ipset=/ikea.si/gfwlist +server=/visa.co.ke/127.0.0.1#5335 +ipset=/visa.co.ke/gfwlist +server=/volvotrucks.by/127.0.0.1#5335 +ipset=/volvotrucks.by/gfwlist +server=/babylongirls.co.uk/127.0.0.1#5335 +ipset=/babylongirls.co.uk/gfwlist +server=/cairn.info/127.0.0.1#5335 +ipset=/cairn.info/gfwlist +server=/alphera.in/127.0.0.1#5335 +ipset=/alphera.in/gfwlist +server=/alpherafs.com.hk/127.0.0.1#5335 +ipset=/alpherafs.com.hk/gfwlist +server=/volvotrucks.fr/127.0.0.1#5335 +ipset=/volvotrucks.fr/gfwlist +server=/vscode-unpkg.net/127.0.0.1#5335 +ipset=/vscode-unpkg.net/gfwlist +server=/vfsforgit.org/127.0.0.1#5335 +ipset=/vfsforgit.org/gfwlist +server=/nexpart.tv/127.0.0.1#5335 +ipset=/nexpart.tv/gfwlist +server=/visualstudio.co.uk/127.0.0.1#5335 +ipset=/visualstudio.co.uk/gfwlist +server=/volvogroup.se/127.0.0.1#5335 +ipset=/volvogroup.se/gfwlist +server=/visualstudio.co/127.0.0.1#5335 +ipset=/visualstudio.co/gfwlist +server=/bmw-motorrad.cr/127.0.0.1#5335 +ipset=/bmw-motorrad.cr/gfwlist +server=/blacked.com/127.0.0.1#5335 +ipset=/blacked.com/gfwlist +server=/escape.com.au/127.0.0.1#5335 +ipset=/escape.com.au/gfwlist +server=/bag-glasses1.com/127.0.0.1#5335 +ipset=/bag-glasses1.com/gfwlist +server=/cloudflaretest.com/127.0.0.1#5335 +ipset=/cloudflaretest.com/gfwlist +server=/microsoftsilverlight.org/127.0.0.1#5335 +ipset=/microsoftsilverlight.org/gfwlist +server=/bill-safe.com/127.0.0.1#5335 +ipset=/bill-safe.com/gfwlist +server=/priceless.com/127.0.0.1#5335 +ipset=/priceless.com/gfwlist +server=/bmw.re/127.0.0.1#5335 +ipset=/bmw.re/gfwlist +server=/analtime.org/127.0.0.1#5335 +ipset=/analtime.org/gfwlist +server=/nikelives.com/127.0.0.1#5335 +ipset=/nikelives.com/gfwlist +server=/google.com.sa/127.0.0.1#5335 +ipset=/google.com.sa/gfwlist +server=/camelotherald.com/127.0.0.1#5335 +ipset=/camelotherald.com/gfwlist +server=/gay4tube.com/127.0.0.1#5335 +ipset=/gay4tube.com/gfwlist +server=/d29vzk4ow07wi7.cloudfront.net/127.0.0.1#5335 +ipset=/d29vzk4ow07wi7.cloudfront.net/gfwlist +server=/av-th.net/127.0.0.1#5335 +ipset=/av-th.net/gfwlist +server=/adobespark.com/127.0.0.1#5335 +ipset=/adobespark.com/gfwlist +server=/jfrog.com/127.0.0.1#5335 +ipset=/jfrog.com/gfwlist +server=/kijiji.ca/127.0.0.1#5335 +ipset=/kijiji.ca/gfwlist +server=/oxfordre.com/127.0.0.1#5335 +ipset=/oxfordre.com/gfwlist +server=/i69.com.tw/127.0.0.1#5335 +ipset=/i69.com.tw/gfwlist +server=/upornia.com/127.0.0.1#5335 +ipset=/upornia.com/gfwlist +server=/jjaaxyz.com/127.0.0.1#5335 +ipset=/jjaaxyz.com/gfwlist +server=/mcpeaceofmind.com/127.0.0.1#5335 +ipset=/mcpeaceofmind.com/gfwlist +server=/18novel.xyz/127.0.0.1#5335 +ipset=/18novel.xyz/gfwlist +server=/bridgestone.com.vn/127.0.0.1#5335 +ipset=/bridgestone.com.vn/gfwlist +server=/cbart.net/127.0.0.1#5335 +ipset=/cbart.net/gfwlist +server=/piapro.net/127.0.0.1#5335 +ipset=/piapro.net/gfwlist +server=/facebokc.com/127.0.0.1#5335 +ipset=/facebokc.com/gfwlist +server=/mastercad.com/127.0.0.1#5335 +ipset=/mastercad.com/gfwlist +server=/girl7942.com/127.0.0.1#5335 +ipset=/girl7942.com/gfwlist +server=/snap-telemetry.io/127.0.0.1#5335 +ipset=/snap-telemetry.io/gfwlist +server=/bidi.net.uk/127.0.0.1#5335 +ipset=/bidi.net.uk/gfwlist +server=/soundcloud.com/127.0.0.1#5335 +ipset=/soundcloud.com/gfwlist +server=/canon.rs/127.0.0.1#5335 +ipset=/canon.rs/gfwlist +server=/ebaycdn.net/127.0.0.1#5335 +ipset=/ebaycdn.net/gfwlist +server=/instagram.com/127.0.0.1#5335 +ipset=/instagram.com/gfwlist +server=/mastercard.ca/127.0.0.1#5335 +ipset=/mastercard.ca/gfwlist +server=/foxnewslatino.com/127.0.0.1#5335 +ipset=/foxnewslatino.com/gfwlist +server=/google.md/127.0.0.1#5335 +ipset=/google.md/gfwlist +server=/simcity.com/127.0.0.1#5335 +ipset=/simcity.com/gfwlist +server=/newslicensing.co.uk/127.0.0.1#5335 +ipset=/newslicensing.co.uk/gfwlist +server=/niketrainers.com/127.0.0.1#5335 +ipset=/niketrainers.com/gfwlist +server=/marvelspotlightplays.com/127.0.0.1#5335 +ipset=/marvelspotlightplays.com/gfwlist +server=/beatssaustraliabuy.com/127.0.0.1#5335 +ipset=/beatssaustraliabuy.com/gfwlist +server=/stackage.org/127.0.0.1#5335 +ipset=/stackage.org/gfwlist +server=/ebay.fr/127.0.0.1#5335 +ipset=/ebay.fr/gfwlist +server=/theleakbay.com/127.0.0.1#5335 +ipset=/theleakbay.com/gfwlist +server=/youtube.fr/127.0.0.1#5335 +ipset=/youtube.fr/gfwlist +server=/dogcumshot.net/127.0.0.1#5335 +ipset=/dogcumshot.net/gfwlist +server=/slidesharecdn.com/127.0.0.1#5335 +ipset=/slidesharecdn.com/gfwlist +server=/vagrantcloud.com/127.0.0.1#5335 +ipset=/vagrantcloud.com/gfwlist +server=/mcdelivery.com.tw/127.0.0.1#5335 +ipset=/mcdelivery.com.tw/gfwlist +server=/netflix.ca/127.0.0.1#5335 +ipset=/netflix.ca/gfwlist +server=/nijigen-daiaru.com/127.0.0.1#5335 +ipset=/nijigen-daiaru.com/gfwlist +server=/99re.com/127.0.0.1#5335 +ipset=/99re.com/gfwlist +server=/ebaystore.com/127.0.0.1#5335 +ipset=/ebaystore.com/gfwlist +server=/go-lang.com/127.0.0.1#5335 +ipset=/go-lang.com/gfwlist +server=/rajwaphq.com/127.0.0.1#5335 +ipset=/rajwaphq.com/gfwlist +server=/ieeer5.org/127.0.0.1#5335 +ipset=/ieeer5.org/gfwlist +server=/gettyimages.com/127.0.0.1#5335 +ipset=/gettyimages.com/gfwlist +server=/filipino-music.net/127.0.0.1#5335 +ipset=/filipino-music.net/gfwlist +server=/costcobusinessdelivery.com/127.0.0.1#5335 +ipset=/costcobusinessdelivery.com/gfwlist +server=/mini-connected.it/127.0.0.1#5335 +ipset=/mini-connected.it/gfwlist +server=/jwkcgd.xyz/127.0.0.1#5335 +ipset=/jwkcgd.xyz/gfwlist +server=/blzddist1-a.akamaihd.net/127.0.0.1#5335 +ipset=/blzddist1-a.akamaihd.net/gfwlist +server=/fasebokk.com/127.0.0.1#5335 +ipset=/fasebokk.com/gfwlist +server=/industrialtoys.com/127.0.0.1#5335 +ipset=/industrialtoys.com/gfwlist +server=/bloombergbna.com/127.0.0.1#5335 +ipset=/bloombergbna.com/gfwlist +server=/gitlab.io/127.0.0.1#5335 +ipset=/gitlab.io/gfwlist +server=/gitlab.com/127.0.0.1#5335 +ipset=/gitlab.com/gfwlist +server=/disney.com/127.0.0.1#5335 +ipset=/disney.com/gfwlist +server=/github-cloud.s3.amazonaws.com/127.0.0.1#5335 +ipset=/github-cloud.s3.amazonaws.com/gfwlist +server=/apexlegends.com/127.0.0.1#5335 +ipset=/apexlegends.com/gfwlist +server=/githubuniverse.com/127.0.0.1#5335 +ipset=/githubuniverse.com/gfwlist +server=/instantfapgay.com/127.0.0.1#5335 +ipset=/instantfapgay.com/gfwlist +server=/sankei.com/127.0.0.1#5335 +ipset=/sankei.com/gfwlist +server=/googlesource.com/127.0.0.1#5335 +ipset=/googlesource.com/gfwlist +server=/freecamstars.com/127.0.0.1#5335 +ipset=/freecamstars.com/gfwlist +server=/xnxxfap.info/127.0.0.1#5335 +ipset=/xnxxfap.info/gfwlist +server=/marvel10thanniversary.com/127.0.0.1#5335 +ipset=/marvel10thanniversary.com/gfwlist +server=/pypl.com/127.0.0.1#5335 +ipset=/pypl.com/gfwlist +server=/dnai.in/127.0.0.1#5335 +ipset=/dnai.in/gfwlist +server=/shoppercentre.com/127.0.0.1#5335 +ipset=/shoppercentre.com/gfwlist +server=/mini-connected.lt/127.0.0.1#5335 +ipset=/mini-connected.lt/gfwlist +server=/pki.google.com/127.0.0.1#5335 +ipset=/pki.google.com/gfwlist +server=/besttitstube.com/127.0.0.1#5335 +ipset=/besttitstube.com/gfwlist +server=/vfsco.ro/127.0.0.1#5335 +ipset=/vfsco.ro/gfwlist +server=/hsfacebook.com/127.0.0.1#5335 +ipset=/hsfacebook.com/gfwlist +server=/virtualrealporn.com/127.0.0.1#5335 +ipset=/virtualrealporn.com/gfwlist +server=/riot.net/127.0.0.1#5335 +ipset=/riot.net/gfwlist +server=/bmw-motorrad.com.br/127.0.0.1#5335 +ipset=/bmw-motorrad.com.br/gfwlist +server=/nude.hu/127.0.0.1#5335 +ipset=/nude.hu/gfwlist +server=/foxnewsmagazine.com/127.0.0.1#5335 +ipset=/foxnewsmagazine.com/gfwlist +server=/flutter.dev/127.0.0.1#5335 +ipset=/flutter.dev/gfwlist +server=/pearsonclinical.nl/127.0.0.1#5335 +ipset=/pearsonclinical.nl/gfwlist +server=/facebboook.com/127.0.0.1#5335 +ipset=/facebboook.com/gfwlist +server=/fedoraproject.org/127.0.0.1#5335 +ipset=/fedoraproject.org/gfwlist +server=/baltimorebmw.com/127.0.0.1#5335 +ipset=/baltimorebmw.com/gfwlist +server=/ieee-ies.org/127.0.0.1#5335 +ipset=/ieee-ies.org/gfwlist +server=/symantec.com/127.0.0.1#5335 +ipset=/symantec.com/gfwlist +server=/taipeitimes.com/127.0.0.1#5335 +ipset=/taipeitimes.com/gfwlist +server=/payserve.com/127.0.0.1#5335 +ipset=/payserve.com/gfwlist +server=/pornotube.blog.br/127.0.0.1#5335 +ipset=/pornotube.blog.br/gfwlist +server=/yahoo.it/127.0.0.1#5335 +ipset=/yahoo.it/gfwlist +server=/reactjs.org/127.0.0.1#5335 +ipset=/reactjs.org/gfwlist +server=/garotoesperto.com/127.0.0.1#5335 +ipset=/garotoesperto.com/gfwlist +server=/7mmtv.tv/127.0.0.1#5335 +ipset=/7mmtv.tv/gfwlist +server=/minispygear.com/127.0.0.1#5335 +ipset=/minispygear.com/gfwlist +server=/keezmovies.com/127.0.0.1#5335 +ipset=/keezmovies.com/gfwlist +server=/minidrivingexperienceusa.com/127.0.0.1#5335 +ipset=/minidrivingexperienceusa.com/gfwlist +server=/react.com/127.0.0.1#5335 +ipset=/react.com/gfwlist +server=/rockstargames.com/127.0.0.1#5335 +ipset=/rockstargames.com/gfwlist +server=/messengerdevelopers.com/127.0.0.1#5335 +ipset=/messengerdevelopers.com/gfwlist +server=/dollarfotoclub.com/127.0.0.1#5335 +ipset=/dollarfotoclub.com/gfwlist +server=/globalvoices.org/127.0.0.1#5335 +ipset=/globalvoices.org/gfwlist +server=/projecteuclid.org/127.0.0.1#5335 +ipset=/projecteuclid.org/gfwlist +server=/foxsports.com.bo/127.0.0.1#5335 +ipset=/foxsports.com.bo/gfwlist +server=/hbomaxcdn.com/127.0.0.1#5335 +ipset=/hbomaxcdn.com/gfwlist +server=/fasttext.cc/127.0.0.1#5335 +ipset=/fasttext.cc/gfwlist +server=/faciometrics.com/127.0.0.1#5335 +ipset=/faciometrics.com/gfwlist +server=/hentaispark.com/127.0.0.1#5335 +ipset=/hentaispark.com/gfwlist +server=/google.ro/127.0.0.1#5335 +ipset=/google.ro/gfwlist +server=/porn.com/127.0.0.1#5335 +ipset=/porn.com/gfwlist +server=/hlbelygl.com/127.0.0.1#5335 +ipset=/hlbelygl.com/gfwlist +server=/paydiant.com/127.0.0.1#5335 +ipset=/paydiant.com/gfwlist +server=/f8.com/127.0.0.1#5335 +ipset=/f8.com/gfwlist +server=/buck.build/127.0.0.1#5335 +ipset=/buck.build/gfwlist +server=/embedly.com/127.0.0.1#5335 +ipset=/embedly.com/gfwlist +server=/star-brasil.com/127.0.0.1#5335 +ipset=/star-brasil.com/gfwlist +server=/nikeoutletstore.com/127.0.0.1#5335 +ipset=/nikeoutletstore.com/gfwlist +server=/imstagram.com/127.0.0.1#5335 +ipset=/imstagram.com/gfwlist +server=/twitter.com/127.0.0.1#5335 +ipset=/twitter.com/gfwlist +server=/stackapps.com/127.0.0.1#5335 +ipset=/stackapps.com/gfwlist +server=/cispaletter.org/127.0.0.1#5335 +ipset=/cispaletter.org/gfwlist +server=/dotdeb.org/127.0.0.1#5335 +ipset=/dotdeb.org/gfwlist +server=/ubuntuforums.org/127.0.0.1#5335 +ipset=/ubuntuforums.org/gfwlist +server=/ubuntu.com/127.0.0.1#5335 +ipset=/ubuntu.com/gfwlist +server=/xn--yt8h.la/127.0.0.1#5335 +ipset=/xn--yt8h.la/gfwlist +server=/nintendoeurope.com/127.0.0.1#5335 +ipset=/nintendoeurope.com/gfwlist +server=/launchpadlibrarian.net/127.0.0.1#5335 +ipset=/launchpadlibrarian.net/gfwlist +server=/getbootstrap.com/127.0.0.1#5335 +ipset=/getbootstrap.com/gfwlist +server=/applecensorship.com/127.0.0.1#5335 +ipset=/applecensorship.com/gfwlist +server=/cloudflareapps.com/127.0.0.1#5335 +ipset=/cloudflareapps.com/gfwlist +server=/muji.us/127.0.0.1#5335 +ipset=/muji.us/gfwlist +server=/lanik.us/127.0.0.1#5335 +ipset=/lanik.us/gfwlist +server=/star-latam.com/127.0.0.1#5335 +ipset=/star-latam.com/gfwlist +server=/videosdemadurasx.com/127.0.0.1#5335 +ipset=/videosdemadurasx.com/gfwlist +server=/netflixdnstest6.com/127.0.0.1#5335 +ipset=/netflixdnstest6.com/gfwlist +server=/as-hp.ca/127.0.0.1#5335 +ipset=/as-hp.ca/gfwlist +server=/volvotrucks.com.ar/127.0.0.1#5335 +ipset=/volvotrucks.com.ar/gfwlist +server=/visual-arts.jp/127.0.0.1#5335 +ipset=/visual-arts.jp/gfwlist +server=/18exgfs.com/127.0.0.1#5335 +ipset=/18exgfs.com/gfwlist +server=/argotunnel.com/127.0.0.1#5335 +ipset=/argotunnel.com/gfwlist +server=/audiencenetwork.com/127.0.0.1#5335 +ipset=/audiencenetwork.com/gfwlist +server=/swift.org/127.0.0.1#5335 +ipset=/swift.org/gfwlist +server=/parkinfo.com/127.0.0.1#5335 +ipset=/parkinfo.com/gfwlist +server=/appleswift.com/127.0.0.1#5335 +ipset=/appleswift.com/gfwlist +server=/acebook.com/127.0.0.1#5335 +ipset=/acebook.com/gfwlist +server=/upmedia.mg/127.0.0.1#5335 +ipset=/upmedia.mg/gfwlist +server=/auroraoss.com/127.0.0.1#5335 +ipset=/auroraoss.com/gfwlist +server=/harpercollinsadvantage.com/127.0.0.1#5335 +ipset=/harpercollinsadvantage.com/gfwlist +server=/zohostatic.in/127.0.0.1#5335 +ipset=/zohostatic.in/gfwlist +server=/zeplin.dev/127.0.0.1#5335 +ipset=/zeplin.dev/gfwlist +server=/bsersd.xyz/127.0.0.1#5335 +ipset=/bsersd.xyz/gfwlist +server=/facebooknfl.com/127.0.0.1#5335 +ipset=/facebooknfl.com/gfwlist +server=/zendesk.com/127.0.0.1#5335 +ipset=/zendesk.com/gfwlist +server=/wpvip.com/127.0.0.1#5335 +ipset=/wpvip.com/gfwlist +server=/wordpress.tv/127.0.0.1#5335 +ipset=/wordpress.tv/gfwlist +server=/uun89.com/127.0.0.1#5335 +ipset=/uun89.com/gfwlist +server=/scholar.google.com.ph/127.0.0.1#5335 +ipset=/scholar.google.com.ph/gfwlist +server=/reutersagency.cn/127.0.0.1#5335 +ipset=/reutersagency.cn/gfwlist +server=/dailymail.co.uk/127.0.0.1#5335 +ipset=/dailymail.co.uk/gfwlist +server=/projectbaseline.com/127.0.0.1#5335 +ipset=/projectbaseline.com/gfwlist +server=/dditscdn.com/127.0.0.1#5335 +ipset=/dditscdn.com/gfwlist +server=/mastercard.com.au/127.0.0.1#5335 +ipset=/mastercard.com.au/gfwlist +server=/geeksquadservices.org/127.0.0.1#5335 +ipset=/geeksquadservices.org/gfwlist +server=/webflow.com/127.0.0.1#5335 +ipset=/webflow.com/gfwlist +server=/1xbet.cm/127.0.0.1#5335 +ipset=/1xbet.cm/gfwlist +server=/vercel.sh/127.0.0.1#5335 +ipset=/vercel.sh/gfwlist +server=/nijidoujin.com/127.0.0.1#5335 +ipset=/nijidoujin.com/gfwlist +server=/instagramhilecim.com/127.0.0.1#5335 +ipset=/instagramhilecim.com/gfwlist +server=/imgix.net/127.0.0.1#5335 +ipset=/imgix.net/gfwlist +server=/streamingporn.xyz/127.0.0.1#5335 +ipset=/streamingporn.xyz/gfwlist +server=/visa.cl/127.0.0.1#5335 +ipset=/visa.cl/gfwlist +server=/scholar.google.co.uk/127.0.0.1#5335 +ipset=/scholar.google.co.uk/gfwlist +server=/i-cable.com/127.0.0.1#5335 +ipset=/i-cable.com/gfwlist +server=/err.sh/127.0.0.1#5335 +ipset=/err.sh/gfwlist +server=/ctan.org/127.0.0.1#5335 +ipset=/ctan.org/gfwlist +server=/svp-team.com/127.0.0.1#5335 +ipset=/svp-team.com/gfwlist +server=/bingsettingssearch.trafficmanager.net/127.0.0.1#5335 +ipset=/bingsettingssearch.trafficmanager.net/gfwlist +server=/facebookmarketingpartner.com/127.0.0.1#5335 +ipset=/facebookmarketingpartner.com/gfwlist +server=/creditcardsbay.com/127.0.0.1#5335 +ipset=/creditcardsbay.com/gfwlist +server=/biguz.net/127.0.0.1#5335 +ipset=/biguz.net/gfwlist +server=/scholar.l.google.com/127.0.0.1#5335 +ipset=/scholar.l.google.com/gfwlist +server=/steam.naeu.qtlglb.com/127.0.0.1#5335 +ipset=/steam.naeu.qtlglb.com/gfwlist +server=/thescottishsun.co.uk/127.0.0.1#5335 +ipset=/thescottishsun.co.uk/gfwlist +server=/bmw.com/127.0.0.1#5335 +ipset=/bmw.com/gfwlist +server=/analamateursex.com/127.0.0.1#5335 +ipset=/analamateursex.com/gfwlist +server=/startpage.com/127.0.0.1#5335 +ipset=/startpage.com/gfwlist +server=/squarecapital.com/127.0.0.1#5335 +ipset=/squarecapital.com/gfwlist +server=/git.io/127.0.0.1#5335 +ipset=/git.io/gfwlist +server=/exporntoons.net/127.0.0.1#5335 +ipset=/exporntoons.net/gfwlist +server=/itripto.com/127.0.0.1#5335 +ipset=/itripto.com/gfwlist +server=/91porn.best/127.0.0.1#5335 +ipset=/91porn.best/gfwlist +server=/rplay.live/127.0.0.1#5335 +ipset=/rplay.live/gfwlist +server=/slideshare.com/127.0.0.1#5335 +ipset=/slideshare.com/gfwlist +server=/shorturl.at/127.0.0.1#5335 +ipset=/shorturl.at/gfwlist +server=/visa.co.in/127.0.0.1#5335 +ipset=/visa.co.in/gfwlist +server=/dl.begellhouse.com/127.0.0.1#5335 +ipset=/dl.begellhouse.com/gfwlist +server=/nyansa.com/127.0.0.1#5335 +ipset=/nyansa.com/gfwlist +server=/spaindisney.com/127.0.0.1#5335 +ipset=/spaindisney.com/gfwlist +server=/shop.app/127.0.0.1#5335 +ipset=/shop.app/gfwlist +server=/myshopify.com/127.0.0.1#5335 +ipset=/myshopify.com/gfwlist +server=/setapp.com/127.0.0.1#5335 +ipset=/setapp.com/gfwlist +server=/bellebound.com/127.0.0.1#5335 +ipset=/bellebound.com/gfwlist +server=/loli.net/127.0.0.1#5335 +ipset=/loli.net/gfwlist +server=/rb.gy/127.0.0.1#5335 +ipset=/rb.gy/gfwlist +server=/6neek.com/127.0.0.1#5335 +ipset=/6neek.com/gfwlist +server=/thebeatsheadphonesale.com/127.0.0.1#5335 +ipset=/thebeatsheadphonesale.com/gfwlist +server=/lqh0bon3.xyz/127.0.0.1#5335 +ipset=/lqh0bon3.xyz/gfwlist +server=/stackauth.com/127.0.0.1#5335 +ipset=/stackauth.com/gfwlist +server=/pacloudflare.com/127.0.0.1#5335 +ipset=/pacloudflare.com/gfwlist +server=/foxsmallbusinesscenter.org/127.0.0.1#5335 +ipset=/foxsmallbusinesscenter.org/gfwlist +server=/tnatryouts.com/127.0.0.1#5335 +ipset=/tnatryouts.com/gfwlist +server=/teenqueens.net/127.0.0.1#5335 +ipset=/teenqueens.net/gfwlist +server=/cdn-terapeak.com/127.0.0.1#5335 +ipset=/cdn-terapeak.com/gfwlist +server=/rolfoundation.org/127.0.0.1#5335 +ipset=/rolfoundation.org/gfwlist +server=/patreonusercontent.com/127.0.0.1#5335 +ipset=/patreonusercontent.com/gfwlist +server=/miniusa.com/127.0.0.1#5335 +ipset=/miniusa.com/gfwlist +server=/omaps.app/127.0.0.1#5335 +ipset=/omaps.app/gfwlist +server=/cloudimg.io/127.0.0.1#5335 +ipset=/cloudimg.io/gfwlist +server=/notion.so/127.0.0.1#5335 +ipset=/notion.so/gfwlist +server=/notion.com/127.0.0.1#5335 +ipset=/notion.com/gfwlist +server=/nintendo.com/127.0.0.1#5335 +ipset=/nintendo.com/gfwlist +server=/newsextv.com/127.0.0.1#5335 +ipset=/newsextv.com/gfwlist +server=/d33wubrfki0l68.cloudfront.net/127.0.0.1#5335 +ipset=/d33wubrfki0l68.cloudfront.net/gfwlist +server=/mpv.io/127.0.0.1#5335 +ipset=/mpv.io/gfwlist +server=/huffingtonpost.kr/127.0.0.1#5335 +ipset=/huffingtonpost.kr/gfwlist +server=/madvrlabs.llc/127.0.0.1#5335 +ipset=/madvrlabs.llc/gfwlist +server=/crl.microsoft.com/127.0.0.1#5335 +ipset=/crl.microsoft.com/gfwlist +server=/madvr.net/127.0.0.1#5335 +ipset=/madvr.net/gfwlist +server=/awayoutgame.com/127.0.0.1#5335 +ipset=/awayoutgame.com/gfwlist +server=/amazonbusinessblog.com/127.0.0.1#5335 +ipset=/amazonbusinessblog.com/gfwlist +server=/madvr.com/127.0.0.1#5335 +ipset=/madvr.com/gfwlist +server=/ebay-confirm.com/127.0.0.1#5335 +ipset=/ebay-confirm.com/gfwlist +server=/chunja19.net/127.0.0.1#5335 +ipset=/chunja19.net/gfwlist +server=/swiftcapital.com/127.0.0.1#5335 +ipset=/swiftcapital.com/gfwlist +server=/liberapay.com/127.0.0.1#5335 +ipset=/liberapay.com/gfwlist +server=/venezporn.com/127.0.0.1#5335 +ipset=/venezporn.com/gfwlist +server=/bustyangelique.com/127.0.0.1#5335 +ipset=/bustyangelique.com/gfwlist +server=/jwpltx.com/127.0.0.1#5335 +ipset=/jwpltx.com/gfwlist +server=/xxx-com.cfd/127.0.0.1#5335 +ipset=/xxx-com.cfd/gfwlist +server=/xxxner.com/127.0.0.1#5335 +ipset=/xxxner.com/gfwlist +server=/visa.co.uk/127.0.0.1#5335 +ipset=/visa.co.uk/gfwlist +server=/disney.pt/127.0.0.1#5335 +ipset=/disney.pt/gfwlist +server=/teslamotors.com/127.0.0.1#5335 +ipset=/teslamotors.com/gfwlist +server=/bowenpress.com/127.0.0.1#5335 +ipset=/bowenpress.com/gfwlist +server=/3dhentai.tv/127.0.0.1#5335 +ipset=/3dhentai.tv/gfwlist +server=/dlfacebook.com/127.0.0.1#5335 +ipset=/dlfacebook.com/gfwlist +server=/heroku-app.com/127.0.0.1#5335 +ipset=/heroku-app.com/gfwlist +server=/secomtrust.net/127.0.0.1#5335 +ipset=/secomtrust.net/gfwlist +server=/predictivetechnologies.com/127.0.0.1#5335 +ipset=/predictivetechnologies.com/gfwlist +server=/fabuye.top/127.0.0.1#5335 +ipset=/fabuye.top/gfwlist +server=/appleexpo.info/127.0.0.1#5335 +ipset=/appleexpo.info/gfwlist +server=/xxxland.net/127.0.0.1#5335 +ipset=/xxxland.net/gfwlist +server=/translatewiki.org/127.0.0.1#5335 +ipset=/translatewiki.org/gfwlist +server=/sexcelebrity.net/127.0.0.1#5335 +ipset=/sexcelebrity.net/gfwlist +server=/arcgis.com/127.0.0.1#5335 +ipset=/arcgis.com/gfwlist +server=/duckside.com/127.0.0.1#5335 +ipset=/duckside.com/gfwlist +server=/intel.eu/127.0.0.1#5335 +ipset=/intel.eu/gfwlist +server=/chatterbate.io/127.0.0.1#5335 +ipset=/chatterbate.io/gfwlist +server=/streetmeatasia.com/127.0.0.1#5335 +ipset=/streetmeatasia.com/gfwlist +server=/xxxhomefuck.com/127.0.0.1#5335 +ipset=/xxxhomefuck.com/gfwlist +server=/hotscope.tv/127.0.0.1#5335 +ipset=/hotscope.tv/gfwlist +server=/pornomasse.com/127.0.0.1#5335 +ipset=/pornomasse.com/gfwlist +server=/xvideosnovinha.com/127.0.0.1#5335 +ipset=/xvideosnovinha.com/gfwlist +server=/byjav.me/127.0.0.1#5335 +ipset=/byjav.me/gfwlist +server=/duckduckgo.com.tw/127.0.0.1#5335 +ipset=/duckduckgo.com.tw/gfwlist +server=/nike.com.br/127.0.0.1#5335 +ipset=/nike.com.br/gfwlist +server=/asiancamly.com/127.0.0.1#5335 +ipset=/asiancamly.com/gfwlist +server=/zlibcdn2.com/127.0.0.1#5335 +ipset=/zlibcdn2.com/gfwlist +server=/ahswingerporno.com/127.0.0.1#5335 +ipset=/ahswingerporno.com/gfwlist +server=/pornenix.com/127.0.0.1#5335 +ipset=/pornenix.com/gfwlist +server=/ddg.co/127.0.0.1#5335 +ipset=/ddg.co/gfwlist +server=/bondagesex-xxx.com/127.0.0.1#5335 +ipset=/bondagesex-xxx.com/gfwlist +server=/erodou.tousatu.fun/127.0.0.1#5335 +ipset=/erodou.tousatu.fun/gfwlist +server=/disqus.com/127.0.0.1#5335 +ipset=/disqus.com/gfwlist +server=/pornxxxweb.com/127.0.0.1#5335 +ipset=/pornxxxweb.com/gfwlist +server=/digitalocean.com/127.0.0.1#5335 +ipset=/digitalocean.com/gfwlist +server=/cloudconvert.com/127.0.0.1#5335 +ipset=/cloudconvert.com/gfwlist +server=/steam-chat.com/127.0.0.1#5335 +ipset=/steam-chat.com/gfwlist +server=/buymeacoff.ee/127.0.0.1#5335 +ipset=/buymeacoff.ee/gfwlist +server=/myfoxorlando.com/127.0.0.1#5335 +ipset=/myfoxorlando.com/gfwlist +server=/anyxxx.me/127.0.0.1#5335 +ipset=/anyxxx.me/gfwlist +server=/sexyfeet.tv/127.0.0.1#5335 +ipset=/sexyfeet.tv/gfwlist +server=/volvotrucks.ph/127.0.0.1#5335 +ipset=/volvotrucks.ph/gfwlist +server=/youtube.com.lv/127.0.0.1#5335 +ipset=/youtube.com.lv/gfwlist +server=/fonts.net/127.0.0.1#5335 +ipset=/fonts.net/gfwlist +server=/horsemecum.com/127.0.0.1#5335 +ipset=/horsemecum.com/gfwlist +server=/brightcove.services/127.0.0.1#5335 +ipset=/brightcove.services/gfwlist +server=/thri.xxx/127.0.0.1#5335 +ipset=/thri.xxx/gfwlist +server=/hrecords.jp/127.0.0.1#5335 +ipset=/hrecords.jp/gfwlist +server=/isiknowledge.com/127.0.0.1#5335 +ipset=/isiknowledge.com/gfwlist +server=/doom9.org/127.0.0.1#5335 +ipset=/doom9.org/gfwlist +server=/bahamut.akamaized.net/127.0.0.1#5335 +ipset=/bahamut.akamaized.net/gfwlist +server=/arphic.com.tw/127.0.0.1#5335 +ipset=/arphic.com.tw/gfwlist +server=/literotica.com/127.0.0.1#5335 +ipset=/literotica.com/gfwlist +server=/fabhairypussy.com/127.0.0.1#5335 +ipset=/fabhairypussy.com/gfwlist +server=/fbsbx.com/127.0.0.1#5335 +ipset=/fbsbx.com/gfwlist +server=/kaggle.io/127.0.0.1#5335 +ipset=/kaggle.io/gfwlist +server=/abcheadphones.com/127.0.0.1#5335 +ipset=/abcheadphones.com/gfwlist +server=/gamer-cds.cdn.hinet.net/127.0.0.1#5335 +ipset=/gamer-cds.cdn.hinet.net/gfwlist +server=/ikea.com.eg/127.0.0.1#5335 +ipset=/ikea.com.eg/gfwlist +server=/msads.net/127.0.0.1#5335 +ipset=/msads.net/gfwlist +server=/addtoany.com/127.0.0.1#5335 +ipset=/addtoany.com/gfwlist +server=/konachan.net/127.0.0.1#5335 +ipset=/konachan.net/gfwlist +server=/gscanada.info/127.0.0.1#5335 +ipset=/gscanada.info/gfwlist +server=/globalspec.com/127.0.0.1#5335 +ipset=/globalspec.com/gfwlist +server=/avstar3.com/127.0.0.1#5335 +ipset=/avstar3.com/gfwlist +server=/zoo-xnxx.com/127.0.0.1#5335 +ipset=/zoo-xnxx.com/gfwlist +server=/zh99.net/127.0.0.1#5335 +ipset=/zh99.net/gfwlist +server=/firefoxusercontent.com/127.0.0.1#5335 +ipset=/firefoxusercontent.com/gfwlist +server=/yepporn.com/127.0.0.1#5335 +ipset=/yepporn.com/gfwlist +server=/binance.us/127.0.0.1#5335 +ipset=/binance.us/gfwlist +server=/a-hentai.tv/127.0.0.1#5335 +ipset=/a-hentai.tv/gfwlist +server=/thomsonreuters.es/127.0.0.1#5335 +ipset=/thomsonreuters.es/gfwlist +server=/easportsactive.com/127.0.0.1#5335 +ipset=/easportsactive.com/gfwlist +server=/shenyun.com/127.0.0.1#5335 +ipset=/shenyun.com/gfwlist +server=/foxcanvasroom.com/127.0.0.1#5335 +ipset=/foxcanvasroom.com/gfwlist +server=/devsitetest.how/127.0.0.1#5335 +ipset=/devsitetest.how/gfwlist +server=/rule34video.com/127.0.0.1#5335 +ipset=/rule34video.com/gfwlist +server=/hkedcity.net/127.0.0.1#5335 +ipset=/hkedcity.net/gfwlist +server=/zohoschools.com/127.0.0.1#5335 +ipset=/zohoschools.com/gfwlist +server=/yavtube.com/127.0.0.1#5335 +ipset=/yavtube.com/gfwlist +server=/volvodefense.com/127.0.0.1#5335 +ipset=/volvodefense.com/gfwlist +server=/zzitube.com/127.0.0.1#5335 +ipset=/zzitube.com/gfwlist +server=/realdoll.com/127.0.0.1#5335 +ipset=/realdoll.com/gfwlist +server=/zqqpwz.com/127.0.0.1#5335 +ipset=/zqqpwz.com/gfwlist +server=/xboxgamepass.com/127.0.0.1#5335 +ipset=/xboxgamepass.com/gfwlist +server=/xemales.com/127.0.0.1#5335 +ipset=/xemales.com/gfwlist +server=/web-instagram.net/127.0.0.1#5335 +ipset=/web-instagram.net/gfwlist +server=/bridgestonela.com/127.0.0.1#5335 +ipset=/bridgestonela.com/gfwlist +server=/faebook.com/127.0.0.1#5335 +ipset=/faebook.com/gfwlist +server=/adult.contents.fc2.com/127.0.0.1#5335 +ipset=/adult.contents.fc2.com/gfwlist +server=/gayporn.pro/127.0.0.1#5335 +ipset=/gayporn.pro/gfwlist +server=/drdrefnac.com/127.0.0.1#5335 +ipset=/drdrefnac.com/gfwlist +server=/javtube.com/127.0.0.1#5335 +ipset=/javtube.com/gfwlist +server=/swag.live/127.0.0.1#5335 +ipset=/swag.live/gfwlist +server=/visiontimes.de/127.0.0.1#5335 +ipset=/visiontimes.de/gfwlist +server=/nikkeibp.co.jp/127.0.0.1#5335 +ipset=/nikkeibp.co.jp/gfwlist +server=/zhainanjidi.xyz/127.0.0.1#5335 +ipset=/zhainanjidi.xyz/gfwlist +server=/pearsonclinical.in/127.0.0.1#5335 +ipset=/pearsonclinical.in/gfwlist +server=/daddyslilangel.com/127.0.0.1#5335 +ipset=/daddyslilangel.com/gfwlist +server=/nikesoccercleats.com/127.0.0.1#5335 +ipset=/nikesoccercleats.com/gfwlist +server=/naughtyfootjobs.com/127.0.0.1#5335 +ipset=/naughtyfootjobs.com/gfwlist +server=/pornobengala.com/127.0.0.1#5335 +ipset=/pornobengala.com/gfwlist +server=/diamondgirlstudio.com/127.0.0.1#5335 +ipset=/diamondgirlstudio.com/gfwlist +server=/spyjinx.com/127.0.0.1#5335 +ipset=/spyjinx.com/gfwlist +server=/geek-squads.net/127.0.0.1#5335 +ipset=/geek-squads.net/gfwlist +server=/zerochan.net/127.0.0.1#5335 +ipset=/zerochan.net/gfwlist +server=/zen8ok.xyz/127.0.0.1#5335 +ipset=/zen8ok.xyz/gfwlist +server=/zazzybabes.com/127.0.0.1#5335 +ipset=/zazzybabes.com/gfwlist +server=/z00.world/127.0.0.1#5335 +ipset=/z00.world/gfwlist +server=/leagueoflegends.com/127.0.0.1#5335 +ipset=/leagueoflegends.com/gfwlist +server=/cashpassport.co.za/127.0.0.1#5335 +ipset=/cashpassport.co.za/gfwlist +server=/adulttime.com/127.0.0.1#5335 +ipset=/adulttime.com/gfwlist +server=/ospray.net/127.0.0.1#5335 +ipset=/ospray.net/gfwlist +server=/bigtitvenera.com/127.0.0.1#5335 +ipset=/bigtitvenera.com/gfwlist +server=/facebbook.com/127.0.0.1#5335 +ipset=/facebbook.com/gfwlist +server=/721av.com/127.0.0.1#5335 +ipset=/721av.com/gfwlist +server=/verisign.mobi/127.0.0.1#5335 +ipset=/verisign.mobi/gfwlist +server=/unravel2.com/127.0.0.1#5335 +ipset=/unravel2.com/gfwlist +server=/cf-ipfs.com/127.0.0.1#5335 +ipset=/cf-ipfs.com/gfwlist +server=/bmw-nigeria.com/127.0.0.1#5335 +ipset=/bmw-nigeria.com/gfwlist +server=/easportsactiveonline.com/127.0.0.1#5335 +ipset=/easportsactiveonline.com/gfwlist +server=/bmw.mu/127.0.0.1#5335 +ipset=/bmw.mu/gfwlist +server=/youramateurporn.com/127.0.0.1#5335 +ipset=/youramateurporn.com/gfwlist +server=/youporn.com/127.0.0.1#5335 +ipset=/youporn.com/gfwlist +server=/pornve.com/127.0.0.1#5335 +ipset=/pornve.com/gfwlist +server=/telesell.com/127.0.0.1#5335 +ipset=/telesell.com/gfwlist +server=/screw-my-wife.com/127.0.0.1#5335 +ipset=/screw-my-wife.com/gfwlist +server=/youngsex.video/127.0.0.1#5335 +ipset=/youngsex.video/gfwlist +server=/youngsex.sexy/127.0.0.1#5335 +ipset=/youngsex.sexy/gfwlist +server=/facebookhome.com/127.0.0.1#5335 +ipset=/facebookhome.com/gfwlist +server=/howfuck.me/127.0.0.1#5335 +ipset=/howfuck.me/gfwlist +server=/youngerbabes.com/127.0.0.1#5335 +ipset=/youngerbabes.com/gfwlist +server=/airhornbot.com/127.0.0.1#5335 +ipset=/airhornbot.com/gfwlist +server=/youjism.com/127.0.0.1#5335 +ipset=/youjism.com/gfwlist +server=/troisrivieresmini.com/127.0.0.1#5335 +ipset=/troisrivieresmini.com/gfwlist +server=/pornaffected.com/127.0.0.1#5335 +ipset=/pornaffected.com/gfwlist +server=/hardx.com/127.0.0.1#5335 +ipset=/hardx.com/gfwlist +server=/gbnews.uk/127.0.0.1#5335 +ipset=/gbnews.uk/gfwlist +server=/cup.com.hk/127.0.0.1#5335 +ipset=/cup.com.hk/gfwlist +server=/goshemalecams.com/127.0.0.1#5335 +ipset=/goshemalecams.com/gfwlist +server=/aod-pod-uk-live.akamaized.net/127.0.0.1#5335 +ipset=/aod-pod-uk-live.akamaized.net/gfwlist +server=/yinac5.top/127.0.0.1#5335 +ipset=/yinac5.top/gfwlist +server=/yieamnd.com/127.0.0.1#5335 +ipset=/yieamnd.com/gfwlist +server=/adobedtm.com/127.0.0.1#5335 +ipset=/adobedtm.com/gfwlist +server=/yhy.cool/127.0.0.1#5335 +ipset=/yhy.cool/gfwlist +server=/vfsco.cz/127.0.0.1#5335 +ipset=/vfsco.cz/gfwlist +server=/yespornpleasexxx.com/127.0.0.1#5335 +ipset=/yespornpleasexxx.com/gfwlist +server=/mastercard.com.cy/127.0.0.1#5335 +ipset=/mastercard.com.cy/gfwlist +server=/disney-portal.my.onetrust.com/127.0.0.1#5335 +ipset=/disney-portal.my.onetrust.com/gfwlist +server=/yespornfree.com/127.0.0.1#5335 +ipset=/yespornfree.com/gfwlist +server=/yes.xxx/127.0.0.1#5335 +ipset=/yes.xxx/gfwlist +server=/hentaiworld.eu/127.0.0.1#5335 +ipset=/hentaiworld.eu/gfwlist +server=/volvobuses.dk/127.0.0.1#5335 +ipset=/volvobuses.dk/gfwlist +server=/buyitnowshop.net/127.0.0.1#5335 +ipset=/buyitnowshop.net/gfwlist +server=/galegroup.com/127.0.0.1#5335 +ipset=/galegroup.com/gfwlist +server=/yazhouse8.com/127.0.0.1#5335 +ipset=/yazhouse8.com/gfwlist +server=/jessicaturner.com/127.0.0.1#5335 +ipset=/jessicaturner.com/gfwlist +server=/foxsports.gt/127.0.0.1#5335 +ipset=/foxsports.gt/gfwlist +server=/bmw-motorrad.ec/127.0.0.1#5335 +ipset=/bmw-motorrad.ec/gfwlist +server=/yatong.info/127.0.0.1#5335 +ipset=/yatong.info/gfwlist +server=/theteenhome.com/127.0.0.1#5335 +ipset=/theteenhome.com/gfwlist +server=/visa.gd/127.0.0.1#5335 +ipset=/visa.gd/gfwlist +server=/yadori.club/127.0.0.1#5335 +ipset=/yadori.club/gfwlist +server=/jasmin.com/127.0.0.1#5335 +ipset=/jasmin.com/gfwlist +server=/sumomo-ch.com/127.0.0.1#5335 +ipset=/sumomo-ch.com/gfwlist +server=/avwong.com/127.0.0.1#5335 +ipset=/avwong.com/gfwlist +server=/132288.cc/127.0.0.1#5335 +ipset=/132288.cc/gfwlist +server=/supremacy.net/127.0.0.1#5335 +ipset=/supremacy.net/gfwlist +server=/facebyook.com/127.0.0.1#5335 +ipset=/facebyook.com/gfwlist +server=/gaytopcams.com/127.0.0.1#5335 +ipset=/gaytopcams.com/gfwlist +server=/veet.co.uk/127.0.0.1#5335 +ipset=/veet.co.uk/gfwlist +server=/xxxvogue.net/127.0.0.1#5335 +ipset=/xxxvogue.net/gfwlist +server=/paypal-cardcash.com/127.0.0.1#5335 +ipset=/paypal-cardcash.com/gfwlist +server=/xxxvideo.blog.br/127.0.0.1#5335 +ipset=/xxxvideo.blog.br/gfwlist +server=/bigtitterrynova.com/127.0.0.1#5335 +ipset=/bigtitterrynova.com/gfwlist +server=/epochweekly.com/127.0.0.1#5335 +ipset=/epochweekly.com/gfwlist +server=/aimei133.com/127.0.0.1#5335 +ipset=/aimei133.com/gfwlist +server=/xx159.com.cn/127.0.0.1#5335 +ipset=/xx159.com.cn/gfwlist +server=/xxxsexocasero.com/127.0.0.1#5335 +ipset=/xxxsexocasero.com/gfwlist +server=/xxxsexcinema.com/127.0.0.1#5335 +ipset=/xxxsexcinema.com/gfwlist +server=/browserleaks.com/127.0.0.1#5335 +ipset=/browserleaks.com/gfwlist +server=/xxxpornhd.pro/127.0.0.1#5335 +ipset=/xxxpornhd.pro/gfwlist +server=/disneychannelroadtrip.com/127.0.0.1#5335 +ipset=/disneychannelroadtrip.com/gfwlist +server=/bethesda.net/127.0.0.1#5335 +ipset=/bethesda.net/gfwlist +server=/ausbeatsbydrdre.com/127.0.0.1#5335 +ipset=/ausbeatsbydrdre.com/gfwlist +server=/citizenlab.org/127.0.0.1#5335 +ipset=/citizenlab.org/gfwlist +server=/xxxmovies.fun/127.0.0.1#5335 +ipset=/xxxmovies.fun/gfwlist +server=/alphabet.fr/127.0.0.1#5335 +ipset=/alphabet.fr/gfwlist +server=/xxxmomporn.tube/127.0.0.1#5335 +ipset=/xxxmomporn.tube/gfwlist +server=/facebooksuppliers.com/127.0.0.1#5335 +ipset=/facebooksuppliers.com/gfwlist +server=/paypal-pages.com/127.0.0.1#5335 +ipset=/paypal-pages.com/gfwlist +server=/chickstagram.com/127.0.0.1#5335 +ipset=/chickstagram.com/gfwlist +server=/thepornlist.net/127.0.0.1#5335 +ipset=/thepornlist.net/gfwlist +server=/bloombergvault.com/127.0.0.1#5335 +ipset=/bloombergvault.com/gfwlist +server=/xfantazy.com/127.0.0.1#5335 +ipset=/xfantazy.com/gfwlist +server=/bonyu.cyou/127.0.0.1#5335 +ipset=/bonyu.cyou/gfwlist +server=/8muses.com/127.0.0.1#5335 +ipset=/8muses.com/gfwlist +server=/xxxfuckmom.com/127.0.0.1#5335 +ipset=/xxxfuckmom.com/gfwlist +server=/xxxforte.com/127.0.0.1#5335 +ipset=/xxxforte.com/gfwlist +server=/xxxflare.com/127.0.0.1#5335 +ipset=/xxxflare.com/gfwlist +server=/mastercard.ba/127.0.0.1#5335 +ipset=/mastercard.ba/gfwlist +server=/hitbdsm.com/127.0.0.1#5335 +ipset=/hitbdsm.com/gfwlist +server=/hardanalfucking.com/127.0.0.1#5335 +ipset=/hardanalfucking.com/gfwlist +server=/mistresskym.com/127.0.0.1#5335 +ipset=/mistresskym.com/gfwlist +server=/xxxbolivianas.com/127.0.0.1#5335 +ipset=/xxxbolivianas.com/gfwlist +server=/paypal.ca/127.0.0.1#5335 +ipset=/paypal.ca/gfwlist +server=/disney-discount.com/127.0.0.1#5335 +ipset=/disney-discount.com/gfwlist +server=/bijukujo.club/127.0.0.1#5335 +ipset=/bijukujo.club/gfwlist +server=/fb.me/127.0.0.1#5335 +ipset=/fb.me/gfwlist +server=/xxx-video.cfd/127.0.0.1#5335 +ipset=/xxx-video.cfd/gfwlist +server=/xxu.mobi/127.0.0.1#5335 +ipset=/xxu.mobi/gfwlist +server=/needforspeedstreetkings.com/127.0.0.1#5335 +ipset=/needforspeedstreetkings.com/gfwlist +server=/facebook123.org/127.0.0.1#5335 +ipset=/facebook123.org/gfwlist +server=/clips4sale.com/127.0.0.1#5335 +ipset=/clips4sale.com/gfwlist +server=/volvotrucks.co.zw/127.0.0.1#5335 +ipset=/volvotrucks.co.zw/gfwlist +server=/xxindianporn.com/127.0.0.1#5335 +ipset=/xxindianporn.com/gfwlist +server=/calgoncarbon.com/127.0.0.1#5335 +ipset=/calgoncarbon.com/gfwlist +server=/pjgirls.com/127.0.0.1#5335 +ipset=/pjgirls.com/gfwlist +server=/bahamut.com.tw/127.0.0.1#5335 +ipset=/bahamut.com.tw/gfwlist +server=/minivancouver.ca/127.0.0.1#5335 +ipset=/minivancouver.ca/gfwlist +server=/ngeo.com/127.0.0.1#5335 +ipset=/ngeo.com/gfwlist +server=/minigrandriver.com/127.0.0.1#5335 +ipset=/minigrandriver.com/gfwlist +server=/biologists.com/127.0.0.1#5335 +ipset=/biologists.com/gfwlist +server=/ikea.ie/127.0.0.1#5335 +ipset=/ikea.ie/gfwlist +server=/foxsports.net.br/127.0.0.1#5335 +ipset=/foxsports.net.br/gfwlist +server=/durex.us/127.0.0.1#5335 +ipset=/durex.us/gfwlist +server=/thechronicle.com.au/127.0.0.1#5335 +ipset=/thechronicle.com.au/gfwlist +server=/watchespn.com/127.0.0.1#5335 +ipset=/watchespn.com/gfwlist +server=/mirrormedia.com.tw/127.0.0.1#5335 +ipset=/mirrormedia.com.tw/gfwlist +server=/xvideos.la/127.0.0.1#5335 +ipset=/xvideos.la/gfwlist +server=/xvideo-jp.com/127.0.0.1#5335 +ipset=/xvideo-jp.com/gfwlist +server=/faesebook.com/127.0.0.1#5335 +ipset=/faesebook.com/gfwlist +server=/mini.fi/127.0.0.1#5335 +ipset=/mini.fi/gfwlist +server=/vine.co/127.0.0.1#5335 +ipset=/vine.co/gfwlist +server=/epinions.com/127.0.0.1#5335 +ipset=/epinions.com/gfwlist +server=/adultrental.com/127.0.0.1#5335 +ipset=/adultrental.com/gfwlist +server=/microsoftcloud.com/127.0.0.1#5335 +ipset=/microsoftcloud.com/gfwlist +server=/fanbox.cc/127.0.0.1#5335 +ipset=/fanbox.cc/gfwlist +server=/xpornblog.com/127.0.0.1#5335 +ipset=/xpornblog.com/gfwlist +server=/xpaja.net/127.0.0.1#5335 +ipset=/xpaja.net/gfwlist +server=/mr-tireman.jp/127.0.0.1#5335 +ipset=/mr-tireman.jp/gfwlist +server=/xnxxporn.fun/127.0.0.1#5335 +ipset=/xnxxporn.fun/gfwlist +server=/xnxxmovies.com/127.0.0.1#5335 +ipset=/xnxxmovies.com/gfwlist +server=/trithucvn.net/127.0.0.1#5335 +ipset=/trithucvn.net/gfwlist +server=/xnxxcomvideos.com/127.0.0.1#5335 +ipset=/xnxxcomvideos.com/gfwlist +server=/physicalexam.info/127.0.0.1#5335 +ipset=/physicalexam.info/gfwlist +server=/fank.ru/127.0.0.1#5335 +ipset=/fank.ru/gfwlist +server=/zert.ch/127.0.0.1#5335 +ipset=/zert.ch/gfwlist +server=/scholar.google.lv/127.0.0.1#5335 +ipset=/scholar.google.lv/gfwlist +server=/hentaitalk.com/127.0.0.1#5335 +ipset=/hentaitalk.com/gfwlist +server=/ebayads.com/127.0.0.1#5335 +ipset=/ebayads.com/gfwlist +server=/xmissy.nl/127.0.0.1#5335 +ipset=/xmissy.nl/gfwlist +server=/pokemonpicross.com/127.0.0.1#5335 +ipset=/pokemonpicross.com/gfwlist +server=/drdrebeatsdiscount.com/127.0.0.1#5335 +ipset=/drdrebeatsdiscount.com/gfwlist +server=/anudetube.com/127.0.0.1#5335 +ipset=/anudetube.com/gfwlist +server=/ibook.net/127.0.0.1#5335 +ipset=/ibook.net/gfwlist +server=/wholecitiesfoundation.org/127.0.0.1#5335 +ipset=/wholecitiesfoundation.org/gfwlist +server=/gvt0.com/127.0.0.1#5335 +ipset=/gvt0.com/gfwlist +server=/silversluts.com/127.0.0.1#5335 +ipset=/silversluts.com/gfwlist +server=/minghui.org/127.0.0.1#5335 +ipset=/minghui.org/gfwlist +server=/xdaddy.in/127.0.0.1#5335 +ipset=/xdaddy.in/gfwlist +server=/soccermatchpass.com/127.0.0.1#5335 +ipset=/soccermatchpass.com/gfwlist +server=/faceebook.com/127.0.0.1#5335 +ipset=/faceebook.com/gfwlist +server=/xchina.fun/127.0.0.1#5335 +ipset=/xchina.fun/gfwlist +server=/volvotrucks.ba/127.0.0.1#5335 +ipset=/volvotrucks.ba/gfwlist +server=/facrbook.com/127.0.0.1#5335 +ipset=/facrbook.com/gfwlist +server=/mastercard.sk/127.0.0.1#5335 +ipset=/mastercard.sk/gfwlist +server=/cheapnikeoutlet.com/127.0.0.1#5335 +ipset=/cheapnikeoutlet.com/gfwlist +server=/cbsimg.net/127.0.0.1#5335 +ipset=/cbsimg.net/gfwlist +server=/foxentertainment.com/127.0.0.1#5335 +ipset=/foxentertainment.com/gfwlist +server=/xbahis55.com/127.0.0.1#5335 +ipset=/xbahis55.com/gfwlist +server=/kissjav.com/127.0.0.1#5335 +ipset=/kissjav.com/gfwlist +server=/xanimeporn.tv/127.0.0.1#5335 +ipset=/xanimeporn.tv/gfwlist +server=/douyintt10.me/127.0.0.1#5335 +ipset=/douyintt10.me/gfwlist +server=/shemalepornonly.com/127.0.0.1#5335 +ipset=/shemalepornonly.com/gfwlist +server=/embl.org/127.0.0.1#5335 +ipset=/embl.org/gfwlist +server=/durex-slovenia.si/127.0.0.1#5335 +ipset=/durex-slovenia.si/gfwlist +server=/ntdtvla.com/127.0.0.1#5335 +ipset=/ntdtvla.com/gfwlist +server=/x3guide.com/127.0.0.1#5335 +ipset=/x3guide.com/gfwlist +server=/yjcontentdelivery.com/127.0.0.1#5335 +ipset=/yjcontentdelivery.com/gfwlist +server=/buypass.se/127.0.0.1#5335 +ipset=/buypass.se/gfwlist +server=/alpherafs.co.nz/127.0.0.1#5335 +ipset=/alpherafs.co.nz/gfwlist +server=/bestbuysgeeksquad.com/127.0.0.1#5335 +ipset=/bestbuysgeeksquad.com/gfwlist +server=/myteenwebcam.com/127.0.0.1#5335 +ipset=/myteenwebcam.com/gfwlist +server=/douya.org/127.0.0.1#5335 +ipset=/douya.org/gfwlist +server=/ginzasonypark.jp/127.0.0.1#5335 +ipset=/ginzasonypark.jp/gfwlist +server=/braintreepaymentsolutions.com/127.0.0.1#5335 +ipset=/braintreepaymentsolutions.com/gfwlist +server=/winning11.com/127.0.0.1#5335 +ipset=/winning11.com/gfwlist +server=/willyporn.com/127.0.0.1#5335 +ipset=/willyporn.com/gfwlist +server=/wifemovies.net/127.0.0.1#5335 +ipset=/wifemovies.net/gfwlist +server=/wifeloversporn.com/127.0.0.1#5335 +ipset=/wifeloversporn.com/gfwlist +server=/minimontrealcentre.ca/127.0.0.1#5335 +ipset=/minimontrealcentre.ca/gfwlist +server=/playmeow.com/127.0.0.1#5335 +ipset=/playmeow.com/gfwlist +server=/allmomsex.com/127.0.0.1#5335 +ipset=/allmomsex.com/gfwlist +server=/freegaypornfinder.com/127.0.0.1#5335 +ipset=/freegaypornfinder.com/gfwlist +server=/hpvirtualthin.com/127.0.0.1#5335 +ipset=/hpvirtualthin.com/gfwlist +server=/whitexxxtube.com/127.0.0.1#5335 +ipset=/whitexxxtube.com/gfwlist +server=/nike-dunksb.com/127.0.0.1#5335 +ipset=/nike-dunksb.com/gfwlist +server=/monstercheapbeatss.com/127.0.0.1#5335 +ipset=/monstercheapbeatss.com/gfwlist +server=/whentai.com/127.0.0.1#5335 +ipset=/whentai.com/gfwlist +server=/visa.com.pa/127.0.0.1#5335 +ipset=/visa.com.pa/gfwlist +server=/maskedsingerfox.com/127.0.0.1#5335 +ipset=/maskedsingerfox.com/gfwlist +server=/facebook-newsroom.com/127.0.0.1#5335 +ipset=/facebook-newsroom.com/gfwlist +server=/ebay-discoveries.com/127.0.0.1#5335 +ipset=/ebay-discoveries.com/gfwlist +server=/weknowporn.com/127.0.0.1#5335 +ipset=/weknowporn.com/gfwlist +server=/cfna.com/127.0.0.1#5335 +ipset=/cfna.com/gfwlist +server=/pornworld.to/127.0.0.1#5335 +ipset=/pornworld.to/gfwlist +server=/pinterest.nl/127.0.0.1#5335 +ipset=/pinterest.nl/gfwlist +server=/tospo-keiba.jp/127.0.0.1#5335 +ipset=/tospo-keiba.jp/gfwlist +server=/linkedin.com/127.0.0.1#5335 +ipset=/linkedin.com/gfwlist +server=/outletbeatsshop.com/127.0.0.1#5335 +ipset=/outletbeatsshop.com/gfwlist +server=/tvbs.com.tw/127.0.0.1#5335 +ipset=/tvbs.com.tw/gfwlist +server=/binancezh.co/127.0.0.1#5335 +ipset=/binancezh.co/gfwlist +server=/watchersweb.com/127.0.0.1#5335 +ipset=/watchersweb.com/gfwlist +server=/warddogs.com/127.0.0.1#5335 +ipset=/warddogs.com/gfwlist +server=/vrfdgswx.xyz/127.0.0.1#5335 +ipset=/vrfdgswx.xyz/gfwlist +server=/youtube.cr/127.0.0.1#5335 +ipset=/youtube.cr/gfwlist +server=/newsmaxtv.com/127.0.0.1#5335 +ipset=/newsmaxtv.com/gfwlist +server=/visa.com.kn/127.0.0.1#5335 +ipset=/visa.com.kn/gfwlist +server=/pornohutdeutsch.net/127.0.0.1#5335 +ipset=/pornohutdeutsch.net/gfwlist +server=/watchmygf.net/127.0.0.1#5335 +ipset=/watchmygf.net/gfwlist +server=/mini-connected.co.uk/127.0.0.1#5335 +ipset=/mini-connected.co.uk/gfwlist +server=/voyeurhouse.com/127.0.0.1#5335 +ipset=/voyeurhouse.com/gfwlist +server=/pornovenezolano.com.ve/127.0.0.1#5335 +ipset=/pornovenezolano.com.ve/gfwlist +server=/vomitkings.com/127.0.0.1#5335 +ipset=/vomitkings.com/gfwlist +server=/onesiterip.com/127.0.0.1#5335 +ipset=/onesiterip.com/gfwlist +server=/4kup.net/127.0.0.1#5335 +ipset=/4kup.net/gfwlist +server=/virtualpartyworld.com/127.0.0.1#5335 +ipset=/virtualpartyworld.com/gfwlist +server=/vintagexxxfilms.com/127.0.0.1#5335 +ipset=/vintagexxxfilms.com/gfwlist +server=/megatitsminka.com/127.0.0.1#5335 +ipset=/megatitsminka.com/gfwlist +server=/hycgm1324.shop/127.0.0.1#5335 +ipset=/hycgm1324.shop/gfwlist +server=/celebritynakeds.com/127.0.0.1#5335 +ipset=/celebritynakeds.com/gfwlist +server=/viet.sex/127.0.0.1#5335 +ipset=/viet.sex/gfwlist +server=/bmw-connecteddrive.com.mt/127.0.0.1#5335 +ipset=/bmw-connecteddrive.com.mt/gfwlist +server=/kenyasexparadise.com/127.0.0.1#5335 +ipset=/kenyasexparadise.com/gfwlist +server=/only-xxx.com/127.0.0.1#5335 +ipset=/only-xxx.com/gfwlist +server=/menhdv.com/127.0.0.1#5335 +ipset=/menhdv.com/gfwlist +server=/malayporn.site/127.0.0.1#5335 +ipset=/malayporn.site/gfwlist +server=/nike.shop/127.0.0.1#5335 +ipset=/nike.shop/gfwlist +server=/bookshome.net/127.0.0.1#5335 +ipset=/bookshome.net/gfwlist +server=/youtube.ca/127.0.0.1#5335 +ipset=/youtube.ca/gfwlist +server=/harpercollinschildrensbooks.co.uk/127.0.0.1#5335 +ipset=/harpercollinschildrensbooks.co.uk/gfwlist +server=/volvobuses.com.ar/127.0.0.1#5335 +ipset=/volvobuses.com.ar/gfwlist +server=/4ksex.me/127.0.0.1#5335 +ipset=/4ksex.me/gfwlist +server=/videosxxxnicaragua.top/127.0.0.1#5335 +ipset=/videosxxxnicaragua.top/gfwlist +server=/disney.co.za/127.0.0.1#5335 +ipset=/disney.co.za/gfwlist +server=/apress.com/127.0.0.1#5335 +ipset=/apress.com/gfwlist +server=/nikefactorystore.com/127.0.0.1#5335 +ipset=/nikefactorystore.com/gfwlist +server=/starwarsjedifallenorder.com/127.0.0.1#5335 +ipset=/starwarsjedifallenorder.com/gfwlist +server=/mcisco.com/127.0.0.1#5335 +ipset=/mcisco.com/gfwlist +server=/drebeatsoutletstore.com/127.0.0.1#5335 +ipset=/drebeatsoutletstore.com/gfwlist +server=/choicereviews.org/127.0.0.1#5335 +ipset=/choicereviews.org/gfwlist +server=/vanish.pt/127.0.0.1#5335 +ipset=/vanish.pt/gfwlist +server=/simg.jp/127.0.0.1#5335 +ipset=/simg.jp/gfwlist +server=/picsee.pro/127.0.0.1#5335 +ipset=/picsee.pro/gfwlist +server=/natgeomaps.com/127.0.0.1#5335 +ipset=/natgeomaps.com/gfwlist +server=/free18.net/127.0.0.1#5335 +ipset=/free18.net/gfwlist +server=/alphabet.com.pl/127.0.0.1#5335 +ipset=/alphabet.com.pl/gfwlist +server=/vercomicsporno.xxx/127.0.0.1#5335 +ipset=/vercomicsporno.xxx/gfwlist +server=/ftiecla.com/127.0.0.1#5335 +ipset=/ftiecla.com/gfwlist +server=/vaginalultrasound.info/127.0.0.1#5335 +ipset=/vaginalultrasound.info/gfwlist +server=/v7hds.com/127.0.0.1#5335 +ipset=/v7hds.com/gfwlist +server=/visaluxuryhotelcollection.com/127.0.0.1#5335 +ipset=/visaluxuryhotelcollection.com/gfwlist +server=/face-book.com/127.0.0.1#5335 +ipset=/face-book.com/gfwlist +server=/fnlondon.com/127.0.0.1#5335 +ipset=/fnlondon.com/gfwlist +server=/ikea.com.ru/127.0.0.1#5335 +ipset=/ikea.com.ru/gfwlist +server=/pearson.es/127.0.0.1#5335 +ipset=/pearson.es/gfwlist +server=/tgutube.com/127.0.0.1#5335 +ipset=/tgutube.com/gfwlist +server=/urasma.com/127.0.0.1#5335 +ipset=/urasma.com/gfwlist +server=/akaeai.com/127.0.0.1#5335 +ipset=/akaeai.com/gfwlist +server=/beautifulandbusty.com/127.0.0.1#5335 +ipset=/beautifulandbusty.com/gfwlist +server=/reutersmedia.net/127.0.0.1#5335 +ipset=/reutersmedia.net/gfwlist +server=/icloud.hu/127.0.0.1#5335 +ipset=/icloud.hu/gfwlist +server=/ibm.com/127.0.0.1#5335 +ipset=/ibm.com/gfwlist +server=/uncensoredsexparties.com/127.0.0.1#5335 +ipset=/uncensoredsexparties.com/gfwlist +server=/bridgestonetire.ca/127.0.0.1#5335 +ipset=/bridgestonetire.ca/gfwlist +server=/openssl.org/127.0.0.1#5335 +ipset=/openssl.org/gfwlist +server=/ujapanesesex.com/127.0.0.1#5335 +ipset=/ujapanesesex.com/gfwlist +server=/telegram.org/127.0.0.1#5335 +ipset=/telegram.org/gfwlist +server=/tytng189.com/127.0.0.1#5335 +ipset=/tytng189.com/gfwlist +server=/aple.com/127.0.0.1#5335 +ipset=/aple.com/gfwlist +server=/tomovie.net/127.0.0.1#5335 +ipset=/tomovie.net/gfwlist +server=/ius.io/127.0.0.1#5335 +ipset=/ius.io/gfwlist +server=/tushy.com/127.0.0.1#5335 +ipset=/tushy.com/gfwlist +server=/glyphsapp.com/127.0.0.1#5335 +ipset=/glyphsapp.com/gfwlist +server=/nikelunarglide.com/127.0.0.1#5335 +ipset=/nikelunarglide.com/gfwlist +server=/fxn.ws/127.0.0.1#5335 +ipset=/fxn.ws/gfwlist +server=/bmw.lt/127.0.0.1#5335 +ipset=/bmw.lt/gfwlist +server=/ebayforcharity.org/127.0.0.1#5335 +ipset=/ebayforcharity.org/gfwlist +server=/ebay-inc.net/127.0.0.1#5335 +ipset=/ebay-inc.net/gfwlist +server=/eracom.com.tw/127.0.0.1#5335 +ipset=/eracom.com.tw/gfwlist +server=/thesims3.com/127.0.0.1#5335 +ipset=/thesims3.com/gfwlist +server=/tubepornstars.com/127.0.0.1#5335 +ipset=/tubepornstars.com/gfwlist +server=/webkit.org/127.0.0.1#5335 +ipset=/webkit.org/gfwlist +server=/youtubegaming.com/127.0.0.1#5335 +ipset=/youtubegaming.com/gfwlist +server=/hcbdsm.com/127.0.0.1#5335 +ipset=/hcbdsm.com/gfwlist +server=/tubeorigin.com/127.0.0.1#5335 +ipset=/tubeorigin.com/gfwlist +server=/youtube.tv/127.0.0.1#5335 +ipset=/youtube.tv/gfwlist +server=/monsterbeatsbydreaustraliacheap.com/127.0.0.1#5335 +ipset=/monsterbeatsbydreaustraliacheap.com/gfwlist +server=/connaissancesfinancierespratiques.ca/127.0.0.1#5335 +ipset=/connaissancesfinancierespratiques.ca/gfwlist +server=/tiendabestbuy.com/127.0.0.1#5335 +ipset=/tiendabestbuy.com/gfwlist +server=/tubedupe.com/127.0.0.1#5335 +ipset=/tubedupe.com/gfwlist +server=/tubecaptain.com/127.0.0.1#5335 +ipset=/tubecaptain.com/gfwlist +server=/tube8zoo.com/127.0.0.1#5335 +ipset=/tube8zoo.com/gfwlist +server=/tube-pornomovs.com/127.0.0.1#5335 +ipset=/tube-pornomovs.com/gfwlist +server=/alphera.com.hk/127.0.0.1#5335 +ipset=/alphera.com.hk/gfwlist +server=/ftopx.com/127.0.0.1#5335 +ipset=/ftopx.com/gfwlist +server=/tiohentai.com/127.0.0.1#5335 +ipset=/tiohentai.com/gfwlist +server=/uug23.com/127.0.0.1#5335 +ipset=/uug23.com/gfwlist +server=/kbdxlesx.xyz/127.0.0.1#5335 +ipset=/kbdxlesx.xyz/gfwlist +server=/audiomonsterbeatsonline.com/127.0.0.1#5335 +ipset=/audiomonsterbeatsonline.com/gfwlist +server=/justhd.xyz/127.0.0.1#5335 +ipset=/justhd.xyz/gfwlist +server=/mastercard.dk/127.0.0.1#5335 +ipset=/mastercard.dk/gfwlist +server=/travelgirls.com/127.0.0.1#5335 +ipset=/travelgirls.com/gfwlist +server=/sexgame.com/127.0.0.1#5335 +ipset=/sexgame.com/gfwlist +server=/transangels.com/127.0.0.1#5335 +ipset=/transangels.com/gfwlist +server=/yahoo.be/127.0.0.1#5335 +ipset=/yahoo.be/gfwlist +server=/colegialasreales.com/127.0.0.1#5335 +ipset=/colegialasreales.com/gfwlist +server=/cbssvideo.com/127.0.0.1#5335 +ipset=/cbssvideo.com/gfwlist +server=/imac.eu/127.0.0.1#5335 +ipset=/imac.eu/gfwlist +server=/msftauth.net/127.0.0.1#5335 +ipset=/msftauth.net/gfwlist +server=/binancezh.top/127.0.0.1#5335 +ipset=/binancezh.top/gfwlist +server=/foxnewsrundown.com/127.0.0.1#5335 +ipset=/foxnewsrundown.com/gfwlist +server=/akamai-platform-staging.com/127.0.0.1#5335 +ipset=/akamai-platform-staging.com/gfwlist +server=/tophentaicomics.com/127.0.0.1#5335 +ipset=/tophentaicomics.com/gfwlist +server=/tophentai.biz/127.0.0.1#5335 +ipset=/tophentai.biz/gfwlist +server=/facebooktv.net/127.0.0.1#5335 +ipset=/facebooktv.net/gfwlist +server=/etherscan.io/127.0.0.1#5335 +ipset=/etherscan.io/gfwlist +server=/mingwatch.com/127.0.0.1#5335 +ipset=/mingwatch.com/gfwlist +server=/natgeokidsbooks.co.uk/127.0.0.1#5335 +ipset=/natgeokidsbooks.co.uk/gfwlist +server=/airwick.co.nz/127.0.0.1#5335 +ipset=/airwick.co.nz/gfwlist +server=/toperoticartsites.com/127.0.0.1#5335 +ipset=/toperoticartsites.com/gfwlist +server=/intel.uk/127.0.0.1#5335 +ipset=/intel.uk/gfwlist +server=/tokyomotion.net/127.0.0.1#5335 +ipset=/tokyomotion.net/gfwlist +server=/mariosupersluggers.com/127.0.0.1#5335 +ipset=/mariosupersluggers.com/gfwlist +server=/byspotify.com/127.0.0.1#5335 +ipset=/byspotify.com/gfwlist +server=/ebayon.net/127.0.0.1#5335 +ipset=/ebayon.net/gfwlist +server=/titsintops.com/127.0.0.1#5335 +ipset=/titsintops.com/gfwlist +server=/collabora.com/127.0.0.1#5335 +ipset=/collabora.com/gfwlist +server=/sonyentertainmentnetwork.com/127.0.0.1#5335 +ipset=/sonyentertainmentnetwork.com/gfwlist +server=/hentai24h.org/127.0.0.1#5335 +ipset=/hentai24h.org/gfwlist +server=/visa.com.au/127.0.0.1#5335 +ipset=/visa.com.au/gfwlist +server=/3dsexmovies.biz/127.0.0.1#5335 +ipset=/3dsexmovies.biz/gfwlist +server=/tinhduc.org/127.0.0.1#5335 +ipset=/tinhduc.org/gfwlist +server=/timo0.com/127.0.0.1#5335 +ipset=/timo0.com/gfwlist +server=/fbsbx.net/127.0.0.1#5335 +ipset=/fbsbx.net/gfwlist +server=/thumbnailseries.com/127.0.0.1#5335 +ipset=/thumbnailseries.com/gfwlist +server=/graneodin.com.mx/127.0.0.1#5335 +ipset=/graneodin.com.mx/gfwlist +server=/porndig.com/127.0.0.1#5335 +ipset=/porndig.com/gfwlist +server=/pornscum.com/127.0.0.1#5335 +ipset=/pornscum.com/gfwlist +server=/akamai-sucks.net/127.0.0.1#5335 +ipset=/akamai-sucks.net/gfwlist +server=/facebookporno.net/127.0.0.1#5335 +ipset=/facebookporno.net/gfwlist +server=/metartnetwork.com/127.0.0.1#5335 +ipset=/metartnetwork.com/gfwlist +server=/r34porn.net/127.0.0.1#5335 +ipset=/r34porn.net/gfwlist +server=/hairy-beauty.com/127.0.0.1#5335 +ipset=/hairy-beauty.com/gfwlist +server=/scoreclassics.com/127.0.0.1#5335 +ipset=/scoreclassics.com/gfwlist +server=/onionshare.org/127.0.0.1#5335 +ipset=/onionshare.org/gfwlist +server=/pscdn.co/127.0.0.1#5335 +ipset=/pscdn.co/gfwlist +server=/uncensoredhentai.xxx/127.0.0.1#5335 +ipset=/uncensoredhentai.xxx/gfwlist +server=/smyw.org/127.0.0.1#5335 +ipset=/smyw.org/gfwlist +server=/porn93.cc/127.0.0.1#5335 +ipset=/porn93.cc/gfwlist +server=/redino.tw/127.0.0.1#5335 +ipset=/redino.tw/gfwlist +server=/thehabibshow.com/127.0.0.1#5335 +ipset=/thehabibshow.com/gfwlist +server=/thefappening.wiki/127.0.0.1#5335 +ipset=/thefappening.wiki/gfwlist +server=/mini.de/127.0.0.1#5335 +ipset=/mini.de/gfwlist +server=/academic.eb.com/127.0.0.1#5335 +ipset=/academic.eb.com/gfwlist +server=/rsf.org/127.0.0.1#5335 +ipset=/rsf.org/gfwlist +server=/thebondagefiles.com/127.0.0.1#5335 +ipset=/thebondagefiles.com/gfwlist +server=/russianrape.org/127.0.0.1#5335 +ipset=/russianrape.org/gfwlist +server=/gaysonic.eu/127.0.0.1#5335 +ipset=/gaysonic.eu/gfwlist +server=/xxxpenguin.com/127.0.0.1#5335 +ipset=/xxxpenguin.com/gfwlist +server=/travelcontroller.com/127.0.0.1#5335 +ipset=/travelcontroller.com/gfwlist +server=/thaigirls100.net/127.0.0.1#5335 +ipset=/thaigirls100.net/gfwlist +server=/amsterdamhotescort.com/127.0.0.1#5335 +ipset=/amsterdamhotescort.com/gfwlist +server=/msnbc.com/127.0.0.1#5335 +ipset=/msnbc.com/gfwlist +server=/hpcpi.com/127.0.0.1#5335 +ipset=/hpcpi.com/gfwlist +server=/cartoonville.net/127.0.0.1#5335 +ipset=/cartoonville.net/gfwlist +server=/boyztube.com/127.0.0.1#5335 +ipset=/boyztube.com/gfwlist +server=/teenwebcamtube.com/127.0.0.1#5335 +ipset=/teenwebcamtube.com/gfwlist +server=/illusionchn.com/127.0.0.1#5335 +ipset=/illusionchn.com/gfwlist +server=/azatliq.org/127.0.0.1#5335 +ipset=/azatliq.org/gfwlist +server=/devilsfilm.com/127.0.0.1#5335 +ipset=/devilsfilm.com/gfwlist +server=/ic.ac.uk/127.0.0.1#5335 +ipset=/ic.ac.uk/gfwlist +server=/blowjobit.com/127.0.0.1#5335 +ipset=/blowjobit.com/gfwlist +server=/teen3x.mobi/127.0.0.1#5335 +ipset=/teen3x.mobi/gfwlist +server=/ciscofax.com/127.0.0.1#5335 +ipset=/ciscofax.com/gfwlist +server=/friendfeedmedia.com/127.0.0.1#5335 +ipset=/friendfeedmedia.com/gfwlist +server=/netflixdnstest7.com/127.0.0.1#5335 +ipset=/netflixdnstest7.com/gfwlist +server=/mirrorsedge2d.com/127.0.0.1#5335 +ipset=/mirrorsedge2d.com/gfwlist +server=/prastitutki.ru/127.0.0.1#5335 +ipset=/prastitutki.ru/gfwlist +server=/disneycruisebrasil.com/127.0.0.1#5335 +ipset=/disneycruisebrasil.com/gfwlist +server=/uk-exhibitionist.com/127.0.0.1#5335 +ipset=/uk-exhibitionist.com/gfwlist +server=/taxi69.com/127.0.0.1#5335 +ipset=/taxi69.com/gfwlist +server=/disney.id/127.0.0.1#5335 +ipset=/disney.id/gfwlist +server=/ovid.com/127.0.0.1#5335 +ipset=/ovid.com/gfwlist +server=/tabooporns.com/127.0.0.1#5335 +ipset=/tabooporns.com/gfwlist +server=/foxsports.sv/127.0.0.1#5335 +ipset=/foxsports.sv/gfwlist +server=/sxshentai.com/127.0.0.1#5335 +ipset=/sxshentai.com/gfwlist +server=/paysitesreviews.net/127.0.0.1#5335 +ipset=/paysitesreviews.net/gfwlist +server=/youtube.ie/127.0.0.1#5335 +ipset=/youtube.ie/gfwlist +server=/cloudimage.io/127.0.0.1#5335 +ipset=/cloudimage.io/gfwlist +server=/disneyaulani.com/127.0.0.1#5335 +ipset=/disneyaulani.com/gfwlist +server=/superhqporn.com/127.0.0.1#5335 +ipset=/superhqporn.com/gfwlist +server=/supergratisporno.com/127.0.0.1#5335 +ipset=/supergratisporno.com/gfwlist +server=/beatstoreusa.com/127.0.0.1#5335 +ipset=/beatstoreusa.com/gfwlist +server=/deviantart.com/127.0.0.1#5335 +ipset=/deviantart.com/gfwlist +server=/sunporno.com/127.0.0.1#5335 +ipset=/sunporno.com/gfwlist +server=/globalsign-media.com/127.0.0.1#5335 +ipset=/globalsign-media.com/gfwlist +server=/mediachinese.com/127.0.0.1#5335 +ipset=/mediachinese.com/gfwlist +server=/streamsex.com/127.0.0.1#5335 +ipset=/streamsex.com/gfwlist +server=/stileproject.com/127.0.0.1#5335 +ipset=/stileproject.com/gfwlist +server=/taiav.com/127.0.0.1#5335 +ipset=/taiav.com/gfwlist +server=/amateursvid.com/127.0.0.1#5335 +ipset=/amateursvid.com/gfwlist +server=/ikea.net/127.0.0.1#5335 +ipset=/ikea.net/gfwlist +server=/jennylist.xyz/127.0.0.1#5335 +ipset=/jennylist.xyz/gfwlist +server=/microsoft-ppe.com/127.0.0.1#5335 +ipset=/microsoft-ppe.com/gfwlist +server=/supplybestjerseys.com/127.0.0.1#5335 +ipset=/supplybestjerseys.com/gfwlist +server=/sshs.pw/127.0.0.1#5335 +ipset=/sshs.pw/gfwlist +server=/nexusmods.com/127.0.0.1#5335 +ipset=/nexusmods.com/gfwlist +server=/ebayclassifiedsgroup.org/127.0.0.1#5335 +ipset=/ebayclassifiedsgroup.org/gfwlist +server=/riot-games.com/127.0.0.1#5335 +ipset=/riot-games.com/gfwlist +server=/spectraltube.com/127.0.0.1#5335 +ipset=/spectraltube.com/gfwlist +server=/youtube.me/127.0.0.1#5335 +ipset=/youtube.me/gfwlist +server=/hbo.com.c.footprint.net/127.0.0.1#5335 +ipset=/hbo.com.c.footprint.net/gfwlist +server=/thehun.net/127.0.0.1#5335 +ipset=/thehun.net/gfwlist +server=/smutcam.com/127.0.0.1#5335 +ipset=/smutcam.com/gfwlist +server=/sksarab.top/127.0.0.1#5335 +ipset=/sksarab.top/gfwlist +server=/millymarks.com/127.0.0.1#5335 +ipset=/millymarks.com/gfwlist +server=/nike.hk/127.0.0.1#5335 +ipset=/nike.hk/gfwlist +server=/pki-poste.ch/127.0.0.1#5335 +ipset=/pki-poste.ch/gfwlist +server=/electrochem.org/127.0.0.1#5335 +ipset=/electrochem.org/gfwlist +server=/newsmax.com/127.0.0.1#5335 +ipset=/newsmax.com/gfwlist +server=/cashvideotube.com/127.0.0.1#5335 +ipset=/cashvideotube.com/gfwlist +server=/firestone.com.mx/127.0.0.1#5335 +ipset=/firestone.com.mx/gfwlist +server=/sisisl.com/127.0.0.1#5335 +ipset=/sisisl.com/gfwlist +server=/bloombergindices.com/127.0.0.1#5335 +ipset=/bloombergindices.com/gfwlist +server=/instagramq.com/127.0.0.1#5335 +ipset=/instagramq.com/gfwlist +server=/hpshooping.com/127.0.0.1#5335 +ipset=/hpshooping.com/gfwlist +server=/orl.ly/127.0.0.1#5335 +ipset=/orl.ly/gfwlist +server=/nikeshoemarket.com/127.0.0.1#5335 +ipset=/nikeshoemarket.com/gfwlist +server=/chromium.org/127.0.0.1#5335 +ipset=/chromium.org/gfwlist +server=/free-3d-porn.com/127.0.0.1#5335 +ipset=/free-3d-porn.com/gfwlist +server=/av1688.cc/127.0.0.1#5335 +ipset=/av1688.cc/gfwlist +server=/shittytube.com/127.0.0.1#5335 +ipset=/shittytube.com/gfwlist +server=/mini-bahrain.com/127.0.0.1#5335 +ipset=/mini-bahrain.com/gfwlist +server=/bloomberg.com.br/127.0.0.1#5335 +ipset=/bloomberg.com.br/gfwlist +server=/shithd.com/127.0.0.1#5335 +ipset=/shithd.com/gfwlist +server=/javmix.tv/127.0.0.1#5335 +ipset=/javmix.tv/gfwlist +server=/humoron.com/127.0.0.1#5335 +ipset=/humoron.com/gfwlist +server=/shemale-porn-galls.com/127.0.0.1#5335 +ipset=/shemale-porn-galls.com/gfwlist +server=/masterclass.com/127.0.0.1#5335 +ipset=/masterclass.com/gfwlist +server=/accuweather.com/127.0.0.1#5335 +ipset=/accuweather.com/gfwlist +server=/volvobuses.co.za/127.0.0.1#5335 +ipset=/volvobuses.co.za/gfwlist +server=/sexywetpussy.com/127.0.0.1#5335 +ipset=/sexywetpussy.com/gfwlist +server=/sexyteenssite.com/127.0.0.1#5335 +ipset=/sexyteenssite.com/gfwlist +server=/sexysites.com.ph/127.0.0.1#5335 +ipset=/sexysites.com.ph/gfwlist +server=/theepochtimes.com/127.0.0.1#5335 +ipset=/theepochtimes.com/gfwlist +server=/asredas.com/127.0.0.1#5335 +ipset=/asredas.com/gfwlist +server=/jav.land/127.0.0.1#5335 +ipset=/jav.land/gfwlist +server=/hot2048.com/127.0.0.1#5335 +ipset=/hot2048.com/gfwlist +server=/sexyfuckgames.com/127.0.0.1#5335 +ipset=/sexyfuckgames.com/gfwlist +server=/youtubeembeddedplayer.googleapis.com/127.0.0.1#5335 +ipset=/youtubeembeddedplayer.googleapis.com/gfwlist +server=/gladporn.com/127.0.0.1#5335 +ipset=/gladporn.com/gfwlist +server=/4ebaytraders.com/127.0.0.1#5335 +ipset=/4ebaytraders.com/gfwlist +server=/youtube.kz/127.0.0.1#5335 +ipset=/youtube.kz/gfwlist +server=/bmw-dubai.com/127.0.0.1#5335 +ipset=/bmw-dubai.com/gfwlist +server=/ac-pocketcamp.com/127.0.0.1#5335 +ipset=/ac-pocketcamp.com/gfwlist +server=/bmw.uz/127.0.0.1#5335 +ipset=/bmw.uz/gfwlist +server=/google.com.br/127.0.0.1#5335 +ipset=/google.com.br/gfwlist +server=/redtube.blog/127.0.0.1#5335 +ipset=/redtube.blog/gfwlist +server=/sexxxdoll.com/127.0.0.1#5335 +ipset=/sexxxdoll.com/gfwlist +server=/sexxhd.de/127.0.0.1#5335 +ipset=/sexxhd.de/gfwlist +server=/nike0594.com/127.0.0.1#5335 +ipset=/nike0594.com/gfwlist +server=/sexualhentai.net/127.0.0.1#5335 +ipset=/sexualhentai.net/gfwlist +server=/infowarsmedia.com/127.0.0.1#5335 +ipset=/infowarsmedia.com/gfwlist +server=/youwuss.com/127.0.0.1#5335 +ipset=/youwuss.com/gfwlist +server=/qr.ae/127.0.0.1#5335 +ipset=/qr.ae/gfwlist +server=/sapphicerotica.com/127.0.0.1#5335 +ipset=/sapphicerotica.com/gfwlist +server=/sexstoriespost.com/127.0.0.1#5335 +ipset=/sexstoriespost.com/gfwlist +server=/sexsimulator.com/127.0.0.1#5335 +ipset=/sexsimulator.com/gfwlist +server=/scholar.google.com.ar/127.0.0.1#5335 +ipset=/scholar.google.com.ar/gfwlist +server=/sexopornolive.com/127.0.0.1#5335 +ipset=/sexopornolive.com/gfwlist +server=/bmw-kuwait.com/127.0.0.1#5335 +ipset=/bmw-kuwait.com/gfwlist +server=/drbl.in/127.0.0.1#5335 +ipset=/drbl.in/gfwlist +server=/applecentre.com.au/127.0.0.1#5335 +ipset=/applecentre.com.au/gfwlist +server=/xhcdn.com/127.0.0.1#5335 +ipset=/xhcdn.com/gfwlist +server=/mearki.com/127.0.0.1#5335 +ipset=/mearki.com/gfwlist +server=/sexmix.net/127.0.0.1#5335 +ipset=/sexmix.net/gfwlist +server=/spiceworks.com/127.0.0.1#5335 +ipset=/spiceworks.com/gfwlist +server=/sexkorea.net/127.0.0.1#5335 +ipset=/sexkorea.net/gfwlist +server=/sexiranian.party/127.0.0.1#5335 +ipset=/sexiranian.party/gfwlist +server=/itunes12days.com/127.0.0.1#5335 +ipset=/itunes12days.com/gfwlist +server=/sexhotgames.com/127.0.0.1#5335 +ipset=/sexhotgames.com/gfwlist +server=/ebaystatic.com/127.0.0.1#5335 +ipset=/ebaystatic.com/gfwlist +server=/my45.com/127.0.0.1#5335 +ipset=/my45.com/gfwlist +server=/youtube-ui.l.google.com/127.0.0.1#5335 +ipset=/youtube-ui.l.google.com/gfwlist +server=/directvcinema.com/127.0.0.1#5335 +ipset=/directvcinema.com/gfwlist +server=/sexgames.cc/127.0.0.1#5335 +ipset=/sexgames.cc/gfwlist +server=/appledarwin.net/127.0.0.1#5335 +ipset=/appledarwin.net/gfwlist +server=/lolesports.com/127.0.0.1#5335 +ipset=/lolesports.com/gfwlist +server=/bioware.com/127.0.0.1#5335 +ipset=/bioware.com/gfwlist +server=/sexfilmeporno.com/127.0.0.1#5335 +ipset=/sexfilmeporno.com/gfwlist +server=/joanabliss.com/127.0.0.1#5335 +ipset=/joanabliss.com/gfwlist +server=/sexedanslepre.net/127.0.0.1#5335 +ipset=/sexedanslepre.net/gfwlist +server=/sexdug.com/127.0.0.1#5335 +ipset=/sexdug.com/gfwlist +server=/facebookappcenter.org/127.0.0.1#5335 +ipset=/facebookappcenter.org/gfwlist +server=/sexdolls.com/127.0.0.1#5335 +ipset=/sexdolls.com/gfwlist +server=/ieee-ims.org/127.0.0.1#5335 +ipset=/ieee-ims.org/gfwlist +server=/eromanga-ace.com/127.0.0.1#5335 +ipset=/eromanga-ace.com/gfwlist +server=/pinterest.th/127.0.0.1#5335 +ipset=/pinterest.th/gfwlist +server=/nikecompany.com/127.0.0.1#5335 +ipset=/nikecompany.com/gfwlist +server=/marvelpinball.com/127.0.0.1#5335 +ipset=/marvelpinball.com/gfwlist +server=/sexanimalvideos.com/127.0.0.1#5335 +ipset=/sexanimalvideos.com/gfwlist +server=/sexalarab.com/127.0.0.1#5335 +ipset=/sexalarab.com/gfwlist +server=/paily.org/127.0.0.1#5335 +ipset=/paily.org/gfwlist +server=/bmw.si/127.0.0.1#5335 +ipset=/bmw.si/gfwlist +server=/pinterest.tw/127.0.0.1#5335 +ipset=/pinterest.tw/gfwlist +server=/sex-hay.pro/127.0.0.1#5335 +ipset=/sex-hay.pro/gfwlist +server=/mpfinance.com/127.0.0.1#5335 +ipset=/mpfinance.com/gfwlist +server=/familypies.net/127.0.0.1#5335 +ipset=/familypies.net/gfwlist +server=/paypalx.com/127.0.0.1#5335 +ipset=/paypalx.com/gfwlist +server=/sex-gif.org/127.0.0.1#5335 +ipset=/sex-gif.org/gfwlist +server=/fortuneinsight.com/127.0.0.1#5335 +ipset=/fortuneinsight.com/gfwlist +server=/sessoamatorialeitaliano.com/127.0.0.1#5335 +ipset=/sessoamatorialeitaliano.com/gfwlist +server=/g-tvapp.com/127.0.0.1#5335 +ipset=/g-tvapp.com/gfwlist +server=/camcam.cc/127.0.0.1#5335 +ipset=/camcam.cc/gfwlist +server=/texttobuy.org/127.0.0.1#5335 +ipset=/texttobuy.org/gfwlist +server=/publicagentxxx.com/127.0.0.1#5335 +ipset=/publicagentxxx.com/gfwlist +server=/pokedex3d.com/127.0.0.1#5335 +ipset=/pokedex3d.com/gfwlist +server=/search.xxx/127.0.0.1#5335 +ipset=/search.xxx/gfwlist +server=/myfoxlosangeles.com/127.0.0.1#5335 +ipset=/myfoxlosangeles.com/gfwlist +server=/vanish.com.co/127.0.0.1#5335 +ipset=/vanish.com.co/gfwlist +server=/primevideo.com/127.0.0.1#5335 +ipset=/primevideo.com/gfwlist +server=/beatsstudiosite.com/127.0.0.1#5335 +ipset=/beatsstudiosite.com/gfwlist +server=/comodoca3.com/127.0.0.1#5335 +ipset=/comodoca3.com/gfwlist +server=/bextbuy.com/127.0.0.1#5335 +ipset=/bextbuy.com/gfwlist +server=/avhome.one/127.0.0.1#5335 +ipset=/avhome.one/gfwlist +server=/yingpianqu.com/127.0.0.1#5335 +ipset=/yingpianqu.com/gfwlist +server=/riotgames.co.kr/127.0.0.1#5335 +ipset=/riotgames.co.kr/gfwlist +server=/scorediscounts.club/127.0.0.1#5335 +ipset=/scorediscounts.club/gfwlist +server=/bigtithooker.com/127.0.0.1#5335 +ipset=/bigtithooker.com/gfwlist +server=/azattyk.org/127.0.0.1#5335 +ipset=/azattyk.org/gfwlist +server=/callhulu.com/127.0.0.1#5335 +ipset=/callhulu.com/gfwlist +server=/cartoon18.com/127.0.0.1#5335 +ipset=/cartoon18.com/gfwlist +server=/savitabhabhi.vip/127.0.0.1#5335 +ipset=/savitabhabhi.vip/gfwlist +server=/krakenjs.com/127.0.0.1#5335 +ipset=/krakenjs.com/gfwlist +server=/facegbok.com/127.0.0.1#5335 +ipset=/facegbok.com/gfwlist +server=/gaypornsky.com/127.0.0.1#5335 +ipset=/gaypornsky.com/gfwlist +server=/xoom.io/127.0.0.1#5335 +ipset=/xoom.io/gfwlist +server=/ebayshopping.org/127.0.0.1#5335 +ipset=/ebayshopping.org/gfwlist +server=/blogspot.com.eg/127.0.0.1#5335 +ipset=/blogspot.com.eg/gfwlist +server=/ruvideos.net/127.0.0.1#5335 +ipset=/ruvideos.net/gfwlist +server=/paypal-japan.com/127.0.0.1#5335 +ipset=/paypal-japan.com/gfwlist +server=/isexlove.tw/127.0.0.1#5335 +ipset=/isexlove.tw/gfwlist +server=/taylorandfrancis.com/127.0.0.1#5335 +ipset=/taylorandfrancis.com/gfwlist +server=/moreheadphones.com/127.0.0.1#5335 +ipset=/moreheadphones.com/gfwlist +server=/apple.ae/127.0.0.1#5335 +ipset=/apple.ae/gfwlist +server=/ebaymotors.com/127.0.0.1#5335 +ipset=/ebaymotors.com/gfwlist +server=/6e8xr2gk.me/127.0.0.1#5335 +ipset=/6e8xr2gk.me/gfwlist +server=/rule34pornvids.com/127.0.0.1#5335 +ipset=/rule34pornvids.com/gfwlist +server=/scholar.google.com.ua/127.0.0.1#5335 +ipset=/scholar.google.com.ua/gfwlist +server=/jdforum.net/127.0.0.1#5335 +ipset=/jdforum.net/gfwlist +server=/10bet.com/127.0.0.1#5335 +ipset=/10bet.com/gfwlist +server=/romantic-sex-video.com/127.0.0.1#5335 +ipset=/romantic-sex-video.com/gfwlist +server=/gimy.to/127.0.0.1#5335 +ipset=/gimy.to/gfwlist +server=/hentaicomic.ru/127.0.0.1#5335 +ipset=/hentaicomic.ru/gfwlist +server=/risextube.com/127.0.0.1#5335 +ipset=/risextube.com/gfwlist +server=/volvotrucks.si/127.0.0.1#5335 +ipset=/volvotrucks.si/gfwlist +server=/instagramium.com/127.0.0.1#5335 +ipset=/instagramium.com/gfwlist +server=/heroku.me/127.0.0.1#5335 +ipset=/heroku.me/gfwlist +server=/ikea.nl/127.0.0.1#5335 +ipset=/ikea.nl/gfwlist +server=/alphabet.be/127.0.0.1#5335 +ipset=/alphabet.be/gfwlist +server=/airwick.de/127.0.0.1#5335 +ipset=/airwick.de/gfwlist +server=/durex.cz/127.0.0.1#5335 +ipset=/durex.cz/gfwlist +server=/kirbysepicyarn.com/127.0.0.1#5335 +ipset=/kirbysepicyarn.com/gfwlist +server=/realsexdoll.com/127.0.0.1#5335 +ipset=/realsexdoll.com/gfwlist +server=/blizzard.nefficient.co.kr/127.0.0.1#5335 +ipset=/blizzard.nefficient.co.kr/gfwlist +server=/myfoxphoenix.com/127.0.0.1#5335 +ipset=/myfoxphoenix.com/gfwlist +server=/vzw.com/127.0.0.1#5335 +ipset=/vzw.com/gfwlist +server=/fetishdreamz.com/127.0.0.1#5335 +ipset=/fetishdreamz.com/gfwlist +server=/real-thaipussy.com/127.0.0.1#5335 +ipset=/real-thaipussy.com/gfwlist +server=/real-homemade-movies.com/127.0.0.1#5335 +ipset=/real-homemade-movies.com/gfwlist +server=/readerswivesonline.com/127.0.0.1#5335 +ipset=/readerswivesonline.com/gfwlist +server=/ebaycareers.com/127.0.0.1#5335 +ipset=/ebaycareers.com/gfwlist +server=/ogameblog.com/127.0.0.1#5335 +ipset=/ogameblog.com/gfwlist +server=/funimation.com/127.0.0.1#5335 +ipset=/funimation.com/gfwlist +server=/rbeopp.com/127.0.0.1#5335 +ipset=/rbeopp.com/gfwlist +server=/petiteamateurteen.com/127.0.0.1#5335 +ipset=/petiteamateurteen.com/gfwlist +server=/s.team/127.0.0.1#5335 +ipset=/s.team/gfwlist +server=/google.co.ck/127.0.0.1#5335 +ipset=/google.co.ck/gfwlist +server=/yourmomlovesanal.com/127.0.0.1#5335 +ipset=/yourmomlovesanal.com/gfwlist +server=/westerndigital.com/127.0.0.1#5335 +ipset=/westerndigital.com/gfwlist +server=/quipelements.com/127.0.0.1#5335 +ipset=/quipelements.com/gfwlist +server=/irribay.com/127.0.0.1#5335 +ipset=/irribay.com/gfwlist +server=/store-bridgestonesports.com/127.0.0.1#5335 +ipset=/store-bridgestonesports.com/gfwlist +server=/beijingnike.com/127.0.0.1#5335 +ipset=/beijingnike.com/gfwlist +server=/enjoyasianporn.com/127.0.0.1#5335 +ipset=/enjoyasianporn.com/gfwlist +server=/verisign.com.sg/127.0.0.1#5335 +ipset=/verisign.com.sg/gfwlist +server=/qombol.com/127.0.0.1#5335 +ipset=/qombol.com/gfwlist +server=/x.team/127.0.0.1#5335 +ipset=/x.team/gfwlist +server=/66wwmm.com/127.0.0.1#5335 +ipset=/66wwmm.com/gfwlist +server=/scatnetwork.com/127.0.0.1#5335 +ipset=/scatnetwork.com/gfwlist +server=/faceboks.com/127.0.0.1#5335 +ipset=/faceboks.com/gfwlist +server=/paypal.me/127.0.0.1#5335 +ipset=/paypal.me/gfwlist +server=/xanimeporn.com/127.0.0.1#5335 +ipset=/xanimeporn.com/gfwlist +server=/toutapp.com/127.0.0.1#5335 +ipset=/toutapp.com/gfwlist +server=/luxuretv.com/127.0.0.1#5335 +ipset=/luxuretv.com/gfwlist +server=/o365weve-dev.com/127.0.0.1#5335 +ipset=/o365weve-dev.com/gfwlist +server=/g1d1goob.xyz/127.0.0.1#5335 +ipset=/g1d1goob.xyz/gfwlist +server=/twitter.biz/127.0.0.1#5335 +ipset=/twitter.biz/gfwlist +server=/christymarks.com/127.0.0.1#5335 +ipset=/christymarks.com/gfwlist +server=/uproxy.org/127.0.0.1#5335 +ipset=/uproxy.org/gfwlist +server=/nikeplus.org/127.0.0.1#5335 +ipset=/nikeplus.org/gfwlist +server=/pheonix.money/127.0.0.1#5335 +ipset=/pheonix.money/gfwlist +server=/prostoporno.net/127.0.0.1#5335 +ipset=/prostoporno.net/gfwlist +server=/mastercard.no/127.0.0.1#5335 +ipset=/mastercard.no/gfwlist +server=/profreeporno.com/127.0.0.1#5335 +ipset=/profreeporno.com/gfwlist +server=/disneymagicmomentsme.com/127.0.0.1#5335 +ipset=/disneymagicmomentsme.com/gfwlist +server=/private.com/127.0.0.1#5335 +ipset=/private.com/gfwlist +server=/fbthirdpartypixel.com/127.0.0.1#5335 +ipset=/fbthirdpartypixel.com/gfwlist +server=/primematures.com/127.0.0.1#5335 +ipset=/primematures.com/gfwlist +server=/ciscopress.ch/127.0.0.1#5335 +ipset=/ciscopress.ch/gfwlist +server=/hentaiprn.com/127.0.0.1#5335 +ipset=/hentaiprn.com/gfwlist +server=/pricelesssydney.com/127.0.0.1#5335 +ipset=/pricelesssydney.com/gfwlist +server=/businessfocus.io/127.0.0.1#5335 +ipset=/businessfocus.io/gfwlist +server=/disneypeoplesurveys.com/127.0.0.1#5335 +ipset=/disneypeoplesurveys.com/gfwlist +server=/getscorecash.com/127.0.0.1#5335 +ipset=/getscorecash.com/gfwlist +server=/rakuten.com/127.0.0.1#5335 +ipset=/rakuten.com/gfwlist +server=/pornwhitelist.com/127.0.0.1#5335 +ipset=/pornwhitelist.com/gfwlist +server=/aucheapbeats.com/127.0.0.1#5335 +ipset=/aucheapbeats.com/gfwlist +server=/fox247.tv/127.0.0.1#5335 +ipset=/fox247.tv/gfwlist +server=/porntn.com/127.0.0.1#5335 +ipset=/porntn.com/gfwlist +server=/pornstarbyface.com/127.0.0.1#5335 +ipset=/pornstarbyface.com/gfwlist +server=/pornsocket.com/127.0.0.1#5335 +ipset=/pornsocket.com/gfwlist +server=/ebay.lt/127.0.0.1#5335 +ipset=/ebay.lt/gfwlist +server=/pornsitesnow.com/127.0.0.1#5335 +ipset=/pornsitesnow.com/gfwlist +server=/pornrips.cc/127.0.0.1#5335 +ipset=/pornrips.cc/gfwlist +server=/nineentertainment.com.au/127.0.0.1#5335 +ipset=/nineentertainment.com.au/gfwlist +server=/xn--ruq8a011kt6y.xn--hxt814e/127.0.0.1#5335 +ipset=/xn--ruq8a011kt6y.xn--hxt814e/gfwlist +server=/needforspeed.com/127.0.0.1#5335 +ipset=/needforspeed.com/gfwlist +server=/pornrabbit.com/127.0.0.1#5335 +ipset=/pornrabbit.com/gfwlist +server=/tellme.pw/127.0.0.1#5335 +ipset=/tellme.pw/gfwlist +server=/azure-dns.com/127.0.0.1#5335 +ipset=/azure-dns.com/gfwlist +server=/foxnewsopinion.com/127.0.0.1#5335 +ipset=/foxnewsopinion.com/gfwlist +server=/aspenpublishing.com/127.0.0.1#5335 +ipset=/aspenpublishing.com/gfwlist +server=/enemaporn.blogspot.com/127.0.0.1#5335 +ipset=/enemaporn.blogspot.com/gfwlist +server=/facedbook.com/127.0.0.1#5335 +ipset=/facedbook.com/gfwlist +server=/hiddenvoyeurspy.com/127.0.0.1#5335 +ipset=/hiddenvoyeurspy.com/gfwlist +server=/hkcitizenmedia.com/127.0.0.1#5335 +ipset=/hkcitizenmedia.com/gfwlist +server=/pornotron.net/127.0.0.1#5335 +ipset=/pornotron.net/gfwlist +server=/bridgestonesyb.com/127.0.0.1#5335 +ipset=/bridgestonesyb.com/gfwlist +server=/gayonthenet.net/127.0.0.1#5335 +ipset=/gayonthenet.net/gfwlist +server=/pornosfilmes.com/127.0.0.1#5335 +ipset=/pornosfilmes.com/gfwlist +server=/bmw.com.cy/127.0.0.1#5335 +ipset=/bmw.com.cy/gfwlist +server=/nvidia.nl/127.0.0.1#5335 +ipset=/nvidia.nl/gfwlist +server=/pornolandia.xxx/127.0.0.1#5335 +ipset=/pornolandia.xxx/gfwlist +server=/doi.org/127.0.0.1#5335 +ipset=/doi.org/gfwlist +server=/pornoirado.com/127.0.0.1#5335 +ipset=/pornoirado.com/gfwlist +server=/c0930.com/127.0.0.1#5335 +ipset=/c0930.com/gfwlist +server=/53worldsweeps.com/127.0.0.1#5335 +ipset=/53worldsweeps.com/gfwlist +server=/assoass.com/127.0.0.1#5335 +ipset=/assoass.com/gfwlist +server=/98916.tv/127.0.0.1#5335 +ipset=/98916.tv/gfwlist +server=/tpornstars.com/127.0.0.1#5335 +ipset=/tpornstars.com/gfwlist +server=/ikea.us/127.0.0.1#5335 +ipset=/ikea.us/gfwlist +server=/pornogids.net/127.0.0.1#5335 +ipset=/pornogids.net/gfwlist +server=/socalbmw.com/127.0.0.1#5335 +ipset=/socalbmw.com/gfwlist +server=/pornnut.com/127.0.0.1#5335 +ipset=/pornnut.com/gfwlist +server=/pornmaki.com/127.0.0.1#5335 +ipset=/pornmaki.com/gfwlist +server=/fuck-xxx-movies.com/127.0.0.1#5335 +ipset=/fuck-xxx-movies.com/gfwlist +server=/sourcingforebay.com.cn/127.0.0.1#5335 +ipset=/sourcingforebay.com.cn/gfwlist +server=/visa.co.jp/127.0.0.1#5335 +ipset=/visa.co.jp/gfwlist +server=/pornjizz.co/127.0.0.1#5335 +ipset=/pornjizz.co/gfwlist +server=/novojoy.com/127.0.0.1#5335 +ipset=/novojoy.com/gfwlist +server=/faceook.com/127.0.0.1#5335 +ipset=/faceook.com/gfwlist +server=/leagueoflegends.kr/127.0.0.1#5335 +ipset=/leagueoflegends.kr/gfwlist +server=/pornhd3x.tv/127.0.0.1#5335 +ipset=/pornhd3x.tv/gfwlist +server=/pornhd.com/127.0.0.1#5335 +ipset=/pornhd.com/gfwlist +server=/hkheadline.com/127.0.0.1#5335 +ipset=/hkheadline.com/gfwlist +server=/rushporn.xxx/127.0.0.1#5335 +ipset=/rushporn.xxx/gfwlist +server=/porngrabbz.com/127.0.0.1#5335 +ipset=/porngrabbz.com/gfwlist +server=/kum.com/127.0.0.1#5335 +ipset=/kum.com/gfwlist +server=/beatssales.com/127.0.0.1#5335 +ipset=/beatssales.com/gfwlist +server=/chinatimes.com/127.0.0.1#5335 +ipset=/chinatimes.com/gfwlist +server=/hackyourconsole.com/127.0.0.1#5335 +ipset=/hackyourconsole.com/gfwlist +server=/volvotrucks.pk/127.0.0.1#5335 +ipset=/volvotrucks.pk/gfwlist +server=/discord.gg/127.0.0.1#5335 +ipset=/discord.gg/gfwlist +server=/adobeprojectm.com/127.0.0.1#5335 +ipset=/adobeprojectm.com/gfwlist +server=/porngames.club/127.0.0.1#5335 +ipset=/porngames.club/gfwlist +server=/microsoft.lu/127.0.0.1#5335 +ipset=/microsoft.lu/gfwlist +server=/manorama.com/127.0.0.1#5335 +ipset=/manorama.com/gfwlist +server=/czechav.com/127.0.0.1#5335 +ipset=/czechav.com/gfwlist +server=/finenike.com/127.0.0.1#5335 +ipset=/finenike.com/gfwlist +server=/pornfactory.info/127.0.0.1#5335 +ipset=/pornfactory.info/gfwlist +server=/pinterest.in/127.0.0.1#5335 +ipset=/pinterest.in/gfwlist +server=/mini.ma/127.0.0.1#5335 +ipset=/mini.ma/gfwlist +server=/porndoe.com/127.0.0.1#5335 +ipset=/porndoe.com/gfwlist +server=/bmwsfl.com/127.0.0.1#5335 +ipset=/bmwsfl.com/gfwlist +server=/disney.ca/127.0.0.1#5335 +ipset=/disney.ca/gfwlist +server=/moapi.site/127.0.0.1#5335 +ipset=/moapi.site/gfwlist +server=/porndiamond.com/127.0.0.1#5335 +ipset=/porndiamond.com/gfwlist +server=/playapex.com/127.0.0.1#5335 +ipset=/playapex.com/gfwlist +server=/porndabster.com/127.0.0.1#5335 +ipset=/porndabster.com/gfwlist +server=/porncore.net/127.0.0.1#5335 +ipset=/porncore.net/gfwlist +server=/ulol.com/127.0.0.1#5335 +ipset=/ulol.com/gfwlist +server=/gcr.io/127.0.0.1#5335 +ipset=/gcr.io/gfwlist +server=/pornagent.xyz/127.0.0.1#5335 +ipset=/pornagent.xyz/gfwlist +server=/macossierra.com/127.0.0.1#5335 +ipset=/macossierra.com/gfwlist +server=/apple.ie/127.0.0.1#5335 +ipset=/apple.ie/gfwlist +server=/freeadultcomix.com/127.0.0.1#5335 +ipset=/freeadultcomix.com/gfwlist +server=/afewmomentswith.com/127.0.0.1#5335 +ipset=/afewmomentswith.com/gfwlist +server=/pearsonclinical.co.uk/127.0.0.1#5335 +ipset=/pearsonclinical.co.uk/gfwlist +server=/porn.xxx/127.0.0.1#5335 +ipset=/porn.xxx/gfwlist +server=/askfacebook.org/127.0.0.1#5335 +ipset=/askfacebook.org/gfwlist +server=/pussyspace.com/127.0.0.1#5335 +ipset=/pussyspace.com/gfwlist +server=/porn-gratis.info/127.0.0.1#5335 +ipset=/porn-gratis.info/gfwlist +server=/porn-comic.com/127.0.0.1#5335 +ipset=/porn-comic.com/gfwlist +server=/freeporno.asia/127.0.0.1#5335 +ipset=/freeporno.asia/gfwlist +server=/playyoungtube.com/127.0.0.1#5335 +ipset=/playyoungtube.com/gfwlist +server=/foxla.tv/127.0.0.1#5335 +ipset=/foxla.tv/gfwlist +server=/piratecams.com/127.0.0.1#5335 +ipset=/piratecams.com/gfwlist +server=/paradisehill.cc/127.0.0.1#5335 +ipset=/paradisehill.cc/gfwlist +server=/pinkdino.com/127.0.0.1#5335 +ipset=/pinkdino.com/gfwlist +server=/picacg2022.com/127.0.0.1#5335 +ipset=/picacg2022.com/gfwlist +server=/kindleoasis.org/127.0.0.1#5335 +ipset=/kindleoasis.org/gfwlist +server=/fuckmeplease.net/127.0.0.1#5335 +ipset=/fuckmeplease.net/gfwlist +server=/doujin-night.com/127.0.0.1#5335 +ipset=/doujin-night.com/gfwlist +server=/facebookmail.tv/127.0.0.1#5335 +ipset=/facebookmail.tv/gfwlist +server=/pervclips.com/127.0.0.1#5335 +ipset=/pervclips.com/gfwlist +server=/apple.co.nz/127.0.0.1#5335 +ipset=/apple.co.nz/gfwlist +server=/ikea.kr/127.0.0.1#5335 +ipset=/ikea.kr/gfwlist +server=/deutsche-pornos-kostenlos.xxx/127.0.0.1#5335 +ipset=/deutsche-pornos-kostenlos.xxx/gfwlist +server=/peopledreamfunding.com/127.0.0.1#5335 +ipset=/peopledreamfunding.com/gfwlist +server=/xtapes.to/127.0.0.1#5335 +ipset=/xtapes.to/gfwlist +server=/kijijiforbusiness.ca/127.0.0.1#5335 +ipset=/kijijiforbusiness.ca/gfwlist +server=/lifewire.com/127.0.0.1#5335 +ipset=/lifewire.com/gfwlist +server=/youtube.com.eg/127.0.0.1#5335 +ipset=/youtube.com.eg/gfwlist +server=/sweetadult-tube.com/127.0.0.1#5335 +ipset=/sweetadult-tube.com/gfwlist +server=/pasionmujeres.com/127.0.0.1#5335 +ipset=/pasionmujeres.com/gfwlist +server=/pancolle-movie.jp/127.0.0.1#5335 +ipset=/pancolle-movie.jp/gfwlist +server=/paidpornguide.com/127.0.0.1#5335 +ipset=/paidpornguide.com/gfwlist +server=/hhvm.com/127.0.0.1#5335 +ipset=/hhvm.com/gfwlist +server=/bitmex.com/127.0.0.1#5335 +ipset=/bitmex.com/gfwlist +server=/candypleasure.com/127.0.0.1#5335 +ipset=/candypleasure.com/gfwlist +server=/pelvicexam.info/127.0.0.1#5335 +ipset=/pelvicexam.info/gfwlist +server=/op7979.com/127.0.0.1#5335 +ipset=/op7979.com/gfwlist +server=/onlyfanspw.com/127.0.0.1#5335 +ipset=/onlyfanspw.com/gfwlist +server=/onlydudes.com/127.0.0.1#5335 +ipset=/onlydudes.com/gfwlist +server=/binance.vision/127.0.0.1#5335 +ipset=/binance.vision/gfwlist +server=/fscebook.com/127.0.0.1#5335 +ipset=/fscebook.com/gfwlist +server=/bmw-connecteddrive.kr/127.0.0.1#5335 +ipset=/bmw-connecteddrive.kr/gfwlist +server=/onejav.com/127.0.0.1#5335 +ipset=/onejav.com/gfwlist +server=/omorashi.org/127.0.0.1#5335 +ipset=/omorashi.org/gfwlist +server=/axbdoll.com.tw/127.0.0.1#5335 +ipset=/axbdoll.com.tw/gfwlist +server=/fandango.com/127.0.0.1#5335 +ipset=/fandango.com/gfwlist +server=/obutu.com/127.0.0.1#5335 +ipset=/obutu.com/gfwlist +server=/findyourlimits.com/127.0.0.1#5335 +ipset=/findyourlimits.com/gfwlist +server=/nintendostore.com/127.0.0.1#5335 +ipset=/nintendostore.com/gfwlist +server=/ebaycbt.co.kr/127.0.0.1#5335 +ipset=/ebaycbt.co.kr/gfwlist +server=/expertmaker.com/127.0.0.1#5335 +ipset=/expertmaker.com/gfwlist +server=/iyottube.com/127.0.0.1#5335 +ipset=/iyottube.com/gfwlist +server=/jiyu-kobo.co.jp/127.0.0.1#5335 +ipset=/jiyu-kobo.co.jp/gfwlist +server=/disney.ro/127.0.0.1#5335 +ipset=/disney.ro/gfwlist +server=/flickr.net/127.0.0.1#5335 +ipset=/flickr.net/gfwlist +server=/noveltrove.com/127.0.0.1#5335 +ipset=/noveltrove.com/gfwlist +server=/theopportunityproject.org/127.0.0.1#5335 +ipset=/theopportunityproject.org/gfwlist +server=/rarbgway.org/127.0.0.1#5335 +ipset=/rarbgway.org/gfwlist +server=/youtube.pk/127.0.0.1#5335 +ipset=/youtube.pk/gfwlist +server=/embl.it/127.0.0.1#5335 +ipset=/embl.it/gfwlist +server=/terapeak.ca/127.0.0.1#5335 +ipset=/terapeak.ca/gfwlist +server=/livejasminbabes.net/127.0.0.1#5335 +ipset=/livejasminbabes.net/gfwlist +server=/nichepornsites.com/127.0.0.1#5335 +ipset=/nichepornsites.com/gfwlist +server=/dragonagekeep.com/127.0.0.1#5335 +ipset=/dragonagekeep.com/gfwlist +server=/new-redtube.com/127.0.0.1#5335 +ipset=/new-redtube.com/gfwlist +server=/neswangy.net/127.0.0.1#5335 +ipset=/neswangy.net/gfwlist +server=/simplify.com/127.0.0.1#5335 +ipset=/simplify.com/gfwlist +server=/hdpornfree.xxx/127.0.0.1#5335 +ipset=/hdpornfree.xxx/gfwlist +server=/identrust.com/127.0.0.1#5335 +ipset=/identrust.com/gfwlist +server=/mini-connected.fi/127.0.0.1#5335 +ipset=/mini-connected.fi/gfwlist +server=/nakednews.com/127.0.0.1#5335 +ipset=/nakednews.com/gfwlist +server=/airiti.com/127.0.0.1#5335 +ipset=/airiti.com/gfwlist +server=/naijauncut.com/127.0.0.1#5335 +ipset=/naijauncut.com/gfwlist +server=/blogspot.bg/127.0.0.1#5335 +ipset=/blogspot.bg/gfwlist +server=/nomadproject.io/127.0.0.1#5335 +ipset=/nomadproject.io/gfwlist +server=/myyoungwifeisnude.com/127.0.0.1#5335 +ipset=/myyoungwifeisnude.com/gfwlist +server=/partylikeits1986.org/127.0.0.1#5335 +ipset=/partylikeits1986.org/gfwlist +server=/globalsign.eu/127.0.0.1#5335 +ipset=/globalsign.eu/gfwlist +server=/gaycamvideos.net/127.0.0.1#5335 +ipset=/gaycamvideos.net/gfwlist +server=/mysexygfs.com/127.0.0.1#5335 +ipset=/mysexygfs.com/gfwlist +server=/mysexgames.com/127.0.0.1#5335 +ipset=/mysexgames.com/gfwlist +server=/bmw-powertrain.com/127.0.0.1#5335 +ipset=/bmw-powertrain.com/gfwlist +server=/fox11.com/127.0.0.1#5335 +ipset=/fox11.com/gfwlist +server=/yahoo.com.sa/127.0.0.1#5335 +ipset=/yahoo.com.sa/gfwlist +server=/nurofen.co.nz/127.0.0.1#5335 +ipset=/nurofen.co.nz/gfwlist +server=/javporn.tech/127.0.0.1#5335 +ipset=/javporn.tech/gfwlist +server=/gannett.com/127.0.0.1#5335 +ipset=/gannett.com/gfwlist +server=/wimpmusic.com/127.0.0.1#5335 +ipset=/wimpmusic.com/gfwlist +server=/xn--q41am8x.com/127.0.0.1#5335 +ipset=/xn--q41am8x.com/gfwlist +server=/donpornogratis.com/127.0.0.1#5335 +ipset=/donpornogratis.com/gfwlist +server=/hentaimangaporn.com/127.0.0.1#5335 +ipset=/hentaimangaporn.com/gfwlist +server=/slack-imgs.com/127.0.0.1#5335 +ipset=/slack-imgs.com/gfwlist +server=/bestkinky.com/127.0.0.1#5335 +ipset=/bestkinky.com/gfwlist +server=/ero-labs.online/127.0.0.1#5335 +ipset=/ero-labs.online/gfwlist +server=/officialbeatsbydreshop.com/127.0.0.1#5335 +ipset=/officialbeatsbydreshop.com/gfwlist +server=/dyttapis.com/127.0.0.1#5335 +ipset=/dyttapis.com/gfwlist +server=/xboxgamestudios.com/127.0.0.1#5335 +ipset=/xboxgamestudios.com/gfwlist +server=/mrdeepfakes.com/127.0.0.1#5335 +ipset=/mrdeepfakes.com/gfwlist +server=/menatplay.com/127.0.0.1#5335 +ipset=/menatplay.com/gfwlist +server=/bizarresexuality.com/127.0.0.1#5335 +ipset=/bizarresexuality.com/gfwlist +server=/bloomberg.co.jp/127.0.0.1#5335 +ipset=/bloomberg.co.jp/gfwlist +server=/lethalhardcore.com/127.0.0.1#5335 +ipset=/lethalhardcore.com/gfwlist +server=/morazzia.com/127.0.0.1#5335 +ipset=/morazzia.com/gfwlist +server=/appleiphone.hu/127.0.0.1#5335 +ipset=/appleiphone.hu/gfwlist +server=/hotntubes.com/127.0.0.1#5335 +ipset=/hotntubes.com/gfwlist +server=/hentaisea.com/127.0.0.1#5335 +ipset=/hentaisea.com/gfwlist +server=/momshardcoreporn.com/127.0.0.1#5335 +ipset=/momshardcoreporn.com/gfwlist +server=/fantv.hk/127.0.0.1#5335 +ipset=/fantv.hk/gfwlist +server=/singtaousa.com/127.0.0.1#5335 +ipset=/singtaousa.com/gfwlist +server=/foxsports.com.uy/127.0.0.1#5335 +ipset=/foxsports.com.uy/gfwlist +server=/snowmiku.com/127.0.0.1#5335 +ipset=/snowmiku.com/gfwlist +server=/momsfuckingboys.net/127.0.0.1#5335 +ipset=/momsfuckingboys.net/gfwlist +server=/foxcareers.com/127.0.0.1#5335 +ipset=/foxcareers.com/gfwlist +server=/serverfault.com/127.0.0.1#5335 +ipset=/serverfault.com/gfwlist +server=/dentalhypotheses.com/127.0.0.1#5335 +ipset=/dentalhypotheses.com/gfwlist +server=/tasteofpremium.jp/127.0.0.1#5335 +ipset=/tasteofpremium.jp/gfwlist +server=/exotic-ghana.com/127.0.0.1#5335 +ipset=/exotic-ghana.com/gfwlist +server=/ebay25.com/127.0.0.1#5335 +ipset=/ebay25.com/gfwlist +server=/nna.jp/127.0.0.1#5335 +ipset=/nna.jp/gfwlist +server=/mixmaturesex.com/127.0.0.1#5335 +ipset=/mixmaturesex.com/gfwlist +server=/gtv1.org/127.0.0.1#5335 +ipset=/gtv1.org/gfwlist +server=/mitnaka.com/127.0.0.1#5335 +ipset=/mitnaka.com/gfwlist +server=/blogspot.no/127.0.0.1#5335 +ipset=/blogspot.no/gfwlist +server=/pin.it/127.0.0.1#5335 +ipset=/pin.it/gfwlist +server=/milfsover30.com/127.0.0.1#5335 +ipset=/milfsover30.com/gfwlist +server=/imperialbusiness.school/127.0.0.1#5335 +ipset=/imperialbusiness.school/gfwlist +server=/ftv.com.tw/127.0.0.1#5335 +ipset=/ftv.com.tw/gfwlist +server=/akamai-access.com/127.0.0.1#5335 +ipset=/akamai-access.com/gfwlist +server=/18comic.company/127.0.0.1#5335 +ipset=/18comic.company/gfwlist +server=/huobi.com/127.0.0.1#5335 +ipset=/huobi.com/gfwlist +server=/milfed.com/127.0.0.1#5335 +ipset=/milfed.com/gfwlist +server=/deepfreeze.com/127.0.0.1#5335 +ipset=/deepfreeze.com/gfwlist +server=/paypal-login.info/127.0.0.1#5335 +ipset=/paypal-login.info/gfwlist +server=/bestmallawards.com/127.0.0.1#5335 +ipset=/bestmallawards.com/gfwlist +server=/mantochichi.com/127.0.0.1#5335 +ipset=/mantochichi.com/gfwlist +server=/kfs.io/127.0.0.1#5335 +ipset=/kfs.io/gfwlist +server=/manga18.art/127.0.0.1#5335 +ipset=/manga18.art/gfwlist +server=/realclearlife.com/127.0.0.1#5335 +ipset=/realclearlife.com/gfwlist +server=/diao.asia/127.0.0.1#5335 +ipset=/diao.asia/gfwlist +server=/fatstube.com/127.0.0.1#5335 +ipset=/fatstube.com/gfwlist +server=/singtaonewscorp.com/127.0.0.1#5335 +ipset=/singtaonewscorp.com/gfwlist +server=/intel.cu/127.0.0.1#5335 +ipset=/intel.cu/gfwlist +server=/asminternational.org/127.0.0.1#5335 +ipset=/asminternational.org/gfwlist +server=/ikea.com.sa/127.0.0.1#5335 +ipset=/ikea.com.sa/gfwlist +server=/madchensex.com/127.0.0.1#5335 +ipset=/madchensex.com/gfwlist +server=/getprintersupports.com/127.0.0.1#5335 +ipset=/getprintersupports.com/gfwlist +server=/businessinsider.my/127.0.0.1#5335 +ipset=/businessinsider.my/gfwlist +server=/gettyimages.ca/127.0.0.1#5335 +ipset=/gettyimages.ca/gfwlist +server=/pugpig-dev.com/127.0.0.1#5335 +ipset=/pugpig-dev.com/gfwlist +server=/singtao.com/127.0.0.1#5335 +ipset=/singtao.com/gfwlist +server=/lovepartners.life/127.0.0.1#5335 +ipset=/lovepartners.life/gfwlist +server=/lovehomeporn.com/127.0.0.1#5335 +ipset=/lovehomeporn.com/gfwlist +server=/vk-cdn.net/127.0.0.1#5335 +ipset=/vk-cdn.net/gfwlist +server=/ltsports.com.tw/127.0.0.1#5335 +ipset=/ltsports.com.tw/gfwlist +server=/lolhentai.net/127.0.0.1#5335 +ipset=/lolhentai.net/gfwlist +server=/loholidayhk.com/127.0.0.1#5335 +ipset=/loholidayhk.com/gfwlist +server=/localxlist.org/127.0.0.1#5335 +ipset=/localxlist.org/gfwlist +server=/liveprivates.com/127.0.0.1#5335 +ipset=/liveprivates.com/gfwlist +server=/diamantewebcam.com/127.0.0.1#5335 +ipset=/diamantewebcam.com/gfwlist +server=/ikea.ru/127.0.0.1#5335 +ipset=/ikea.ru/gfwlist +server=/nintendo.es/127.0.0.1#5335 +ipset=/nintendo.es/gfwlist +server=/letsfuckme.net/127.0.0.1#5335 +ipset=/letsfuckme.net/gfwlist +server=/letsdoeit.com/127.0.0.1#5335 +ipset=/letsdoeit.com/gfwlist +server=/lemoncams.com/127.0.0.1#5335 +ipset=/lemoncams.com/gfwlist +server=/kindle.es/127.0.0.1#5335 +ipset=/kindle.es/gfwlist +server=/egmontbooks.co.uk/127.0.0.1#5335 +ipset=/egmontbooks.co.uk/gfwlist +server=/lazymike.com/127.0.0.1#5335 +ipset=/lazymike.com/gfwlist +server=/101boyvideos.com/127.0.0.1#5335 +ipset=/101boyvideos.com/gfwlist +server=/voyeurmonkey.com/127.0.0.1#5335 +ipset=/voyeurmonkey.com/gfwlist +server=/javprime.net/127.0.0.1#5335 +ipset=/javprime.net/gfwlist +server=/avstar01.me/127.0.0.1#5335 +ipset=/avstar01.me/gfwlist +server=/igi-global.com/127.0.0.1#5335 +ipset=/igi-global.com/gfwlist +server=/nyaa.si/127.0.0.1#5335 +ipset=/nyaa.si/gfwlist +server=/api-priconne-redive.cygames.jp/127.0.0.1#5335 +ipset=/api-priconne-redive.cygames.jp/gfwlist +server=/jetbrains.team/127.0.0.1#5335 +ipset=/jetbrains.team/gfwlist +server=/freefacebook.com/127.0.0.1#5335 +ipset=/freefacebook.com/gfwlist +server=/kostenlosepornoclips.com/127.0.0.1#5335 +ipset=/kostenlosepornoclips.com/gfwlist +server=/visa-news.jp/127.0.0.1#5335 +ipset=/visa-news.jp/gfwlist +server=/marveldimensionofheroes.com/127.0.0.1#5335 +ipset=/marveldimensionofheroes.com/gfwlist +server=/kir2kos.net/127.0.0.1#5335 +ipset=/kir2kos.net/gfwlist +server=/swjfo.com/127.0.0.1#5335 +ipset=/swjfo.com/gfwlist +server=/iaablog.com/127.0.0.1#5335 +ipset=/iaablog.com/gfwlist +server=/mastercard.co.nz/127.0.0.1#5335 +ipset=/mastercard.co.nz/gfwlist +server=/xdty.org/127.0.0.1#5335 +ipset=/xdty.org/gfwlist +server=/nakedgirls.biz/127.0.0.1#5335 +ipset=/nakedgirls.biz/gfwlist +server=/card.io/127.0.0.1#5335 +ipset=/card.io/gfwlist +server=/disney.fr/127.0.0.1#5335 +ipset=/disney.fr/gfwlist +server=/karupsha.com/127.0.0.1#5335 +ipset=/karupsha.com/gfwlist +server=/faronicswise.co.uk/127.0.0.1#5335 +ipset=/faronicswise.co.uk/gfwlist +server=/guim.co.uk/127.0.0.1#5335 +ipset=/guim.co.uk/gfwlist +server=/kairakudoujin.net/127.0.0.1#5335 +ipset=/kairakudoujin.net/gfwlist +server=/bmw.com.do/127.0.0.1#5335 +ipset=/bmw.com.do/gfwlist +server=/peerj.com/127.0.0.1#5335 +ipset=/peerj.com/gfwlist +server=/universitypressscholarship.com/127.0.0.1#5335 +ipset=/universitypressscholarship.com/gfwlist +server=/alphabet.co.hu/127.0.0.1#5335 +ipset=/alphabet.co.hu/gfwlist +server=/vrsumo.com/127.0.0.1#5335 +ipset=/vrsumo.com/gfwlist +server=/justfullporn.org/127.0.0.1#5335 +ipset=/justfullporn.org/gfwlist +server=/appsonebay.net/127.0.0.1#5335 +ipset=/appsonebay.net/gfwlist +server=/sankei-books.co.jp/127.0.0.1#5335 +ipset=/sankei-books.co.jp/gfwlist +server=/tenbyfotolia.com/127.0.0.1#5335 +ipset=/tenbyfotolia.com/gfwlist +server=/joinmaidez.com/127.0.0.1#5335 +ipset=/joinmaidez.com/gfwlist +server=/jpg4.biz/127.0.0.1#5335 +ipset=/jpg4.biz/gfwlist +server=/degruyter.com/127.0.0.1#5335 +ipset=/degruyter.com/gfwlist +server=/vuvuzela.io/127.0.0.1#5335 +ipset=/vuvuzela.io/gfwlist +server=/erolabs.cloud/127.0.0.1#5335 +ipset=/erolabs.cloud/gfwlist +server=/softbank.tv/127.0.0.1#5335 +ipset=/softbank.tv/gfwlist +server=/pixnet.pro/127.0.0.1#5335 +ipset=/pixnet.pro/gfwlist +server=/akadns6.net/127.0.0.1#5335 +ipset=/akadns6.net/gfwlist +server=/hentaihaven.com/127.0.0.1#5335 +ipset=/hentaihaven.com/gfwlist +server=/penthouse.com/127.0.0.1#5335 +ipset=/penthouse.com/gfwlist +server=/vanish.ro/127.0.0.1#5335 +ipset=/vanish.ro/gfwlist +server=/zwtvusa.com/127.0.0.1#5335 +ipset=/zwtvusa.com/gfwlist +server=/facebookconsultant.org/127.0.0.1#5335 +ipset=/facebookconsultant.org/gfwlist +server=/javhdfree.net/127.0.0.1#5335 +ipset=/javhdfree.net/gfwlist +server=/javhaven.com/127.0.0.1#5335 +ipset=/javhaven.com/gfwlist +server=/harperapps.com/127.0.0.1#5335 +ipset=/harperapps.com/gfwlist +server=/pussysexgames.com/127.0.0.1#5335 +ipset=/pussysexgames.com/gfwlist +server=/newbeatsblackfriday.com/127.0.0.1#5335 +ipset=/newbeatsblackfriday.com/gfwlist +server=/ggsrv.com/127.0.0.1#5335 +ipset=/ggsrv.com/gfwlist +server=/tube4world.com/127.0.0.1#5335 +ipset=/tube4world.com/gfwlist +server=/jav.place/127.0.0.1#5335 +ipset=/jav.place/gfwlist +server=/japon-girls.com/127.0.0.1#5335 +ipset=/japon-girls.com/gfwlist +server=/youtubego.in/127.0.0.1#5335 +ipset=/youtubego.in/gfwlist +server=/ita-do.com/127.0.0.1#5335 +ipset=/ita-do.com/gfwlist +server=/iranx.net/127.0.0.1#5335 +ipset=/iranx.net/gfwlist +server=/umagazine.com.hk/127.0.0.1#5335 +ipset=/umagazine.com.hk/gfwlist +server=/intescort.com/127.0.0.1#5335 +ipset=/intescort.com/gfwlist +server=/instabang.com/127.0.0.1#5335 +ipset=/instabang.com/gfwlist +server=/ipodtouch.com/127.0.0.1#5335 +ipset=/ipodtouch.com/gfwlist +server=/visa.lv/127.0.0.1#5335 +ipset=/visa.lv/gfwlist +server=/verisign.name/127.0.0.1#5335 +ipset=/verisign.name/gfwlist +server=/akamai.net/127.0.0.1#5335 +ipset=/akamai.net/gfwlist +server=/indianhiddencams.com/127.0.0.1#5335 +ipset=/indianhiddencams.com/gfwlist +server=/foxsports-world.com/127.0.0.1#5335 +ipset=/foxsports-world.com/gfwlist +server=/oculuscasino.net/127.0.0.1#5335 +ipset=/oculuscasino.net/gfwlist +server=/adobeawards.com/127.0.0.1#5335 +ipset=/adobeawards.com/gfwlist +server=/independentdubaiescorts.com/127.0.0.1#5335 +ipset=/independentdubaiescorts.com/gfwlist +server=/incestporn.xxx/127.0.0.1#5335 +ipset=/incestporn.xxx/gfwlist +server=/visaluxuryhotels.com.ar/127.0.0.1#5335 +ipset=/visaluxuryhotels.com.ar/gfwlist +server=/sciencedirect.com/127.0.0.1#5335 +ipset=/sciencedirect.com/gfwlist +server=/readthedocs.org/127.0.0.1#5335 +ipset=/readthedocs.org/gfwlist +server=/duckgo.com/127.0.0.1#5335 +ipset=/duckgo.com/gfwlist +server=/igotpornpics.com/127.0.0.1#5335 +ipset=/igotpornpics.com/gfwlist +server=/pcstore.com.tw/127.0.0.1#5335 +ipset=/pcstore.com.tw/gfwlist +server=/hypnotube.com/127.0.0.1#5335 +ipset=/hypnotube.com/gfwlist +server=/premiumfs.de/127.0.0.1#5335 +ipset=/premiumfs.de/gfwlist +server=/mastercardservices.com/127.0.0.1#5335 +ipset=/mastercardservices.com/gfwlist +server=/dmm.com/127.0.0.1#5335 +ipset=/dmm.com/gfwlist +server=/hussiepass.com/127.0.0.1#5335 +ipset=/hussiepass.com/gfwlist +server=/jinsilubanzhao.com/127.0.0.1#5335 +ipset=/jinsilubanzhao.com/gfwlist +server=/huangse.love/127.0.0.1#5335 +ipset=/huangse.love/gfwlist +server=/nextmedia.com.tw/127.0.0.1#5335 +ipset=/nextmedia.com.tw/gfwlist +server=/zoho.com/127.0.0.1#5335 +ipset=/zoho.com/gfwlist +server=/hottystop.com/127.0.0.1#5335 +ipset=/hottystop.com/gfwlist +server=/av4.us/127.0.0.1#5335 +ipset=/av4.us/gfwlist +server=/hotsexvideo.mobi/127.0.0.1#5335 +ipset=/hotsexvideo.mobi/gfwlist +server=/ebay-sales.com/127.0.0.1#5335 +ipset=/ebay-sales.com/gfwlist +server=/javrave.club/127.0.0.1#5335 +ipset=/javrave.club/gfwlist +server=/steam-api.com/127.0.0.1#5335 +ipset=/steam-api.com/gfwlist +server=/airwick.nl/127.0.0.1#5335 +ipset=/airwick.nl/gfwlist +server=/historyofdota.org/127.0.0.1#5335 +ipset=/historyofdota.org/gfwlist +server=/nikefoampositeshoes.com/127.0.0.1#5335 +ipset=/nikefoampositeshoes.com/gfwlist +server=/illusionfb.cn/127.0.0.1#5335 +ipset=/illusionfb.cn/gfwlist +server=/paypal-here.com/127.0.0.1#5335 +ipset=/paypal-here.com/gfwlist +server=/akamqi.com/127.0.0.1#5335 +ipset=/akamqi.com/gfwlist +server=/newsapi.com.au/127.0.0.1#5335 +ipset=/newsapi.com.au/gfwlist +server=/sexygirlspics.com/127.0.0.1#5335 +ipset=/sexygirlspics.com/gfwlist +server=/mcdonaldsparties.co.nz/127.0.0.1#5335 +ipset=/mcdonaldsparties.co.nz/gfwlist +server=/horsecumshot.net/127.0.0.1#5335 +ipset=/horsecumshot.net/gfwlist +server=/kuke.com/127.0.0.1#5335 +ipset=/kuke.com/gfwlist +server=/press.vin/127.0.0.1#5335 +ipset=/press.vin/gfwlist +server=/stepsiblingscaught.com/127.0.0.1#5335 +ipset=/stepsiblingscaught.com/gfwlist +server=/hidefporn.ws/127.0.0.1#5335 +ipset=/hidefporn.ws/gfwlist +server=/hernudepics.com/127.0.0.1#5335 +ipset=/hernudepics.com/gfwlist +server=/nypost.com/127.0.0.1#5335 +ipset=/nypost.com/gfwlist +server=/hentaiworldporn.com/127.0.0.1#5335 +ipset=/hentaiworldporn.com/gfwlist +server=/pureapk.com/127.0.0.1#5335 +ipset=/pureapk.com/gfwlist +server=/ucla.edu/127.0.0.1#5335 +ipset=/ucla.edu/gfwlist +server=/hgamer.pro/127.0.0.1#5335 +ipset=/hgamer.pro/gfwlist +server=/verisign.com.au/127.0.0.1#5335 +ipset=/verisign.com.au/gfwlist +server=/tube2017.com/127.0.0.1#5335 +ipset=/tube2017.com/gfwlist +server=/cock4stepmom.com/127.0.0.1#5335 +ipset=/cock4stepmom.com/gfwlist +server=/indazn.com/127.0.0.1#5335 +ipset=/indazn.com/gfwlist +server=/chatwhores.sex/127.0.0.1#5335 +ipset=/chatwhores.sex/gfwlist +server=/facebook-pmdcenter.com/127.0.0.1#5335 +ipset=/facebook-pmdcenter.com/gfwlist +server=/hulupremium.com/127.0.0.1#5335 +ipset=/hulupremium.com/gfwlist +server=/yahoo.com.sb/127.0.0.1#5335 +ipset=/yahoo.com.sb/gfwlist +server=/foxsports.com.mx/127.0.0.1#5335 +ipset=/foxsports.com.mx/gfwlist +server=/leagueoflegends.info/127.0.0.1#5335 +ipset=/leagueoflegends.info/gfwlist +server=/vkcache.com/127.0.0.1#5335 +ipset=/vkcache.com/gfwlist +server=/hentaihaven.io/127.0.0.1#5335 +ipset=/hentaihaven.io/gfwlist +server=/postini.com/127.0.0.1#5335 +ipset=/postini.com/gfwlist +server=/hentai-space.supertop-100.com/127.0.0.1#5335 +ipset=/hentai-space.supertop-100.com/gfwlist +server=/visa.com.ec/127.0.0.1#5335 +ipset=/visa.com.ec/gfwlist +server=/hentai-cosplays.com/127.0.0.1#5335 +ipset=/hentai-cosplays.com/gfwlist +server=/bmw-motorrad.ru/127.0.0.1#5335 +ipset=/bmw-motorrad.ru/gfwlist +server=/identrust.co.uk/127.0.0.1#5335 +ipset=/identrust.co.uk/gfwlist +server=/hdsex.pro/127.0.0.1#5335 +ipset=/hdsex.pro/gfwlist +server=/hotindianbabe.com/127.0.0.1#5335 +ipset=/hotindianbabe.com/gfwlist +server=/9anime.ws/127.0.0.1#5335 +ipset=/9anime.ws/gfwlist +server=/youtube.com.mx/127.0.0.1#5335 +ipset=/youtube.com.mx/gfwlist +server=/familyswap.xxx/127.0.0.1#5335 +ipset=/familyswap.xxx/gfwlist +server=/china-facebook.com/127.0.0.1#5335 +ipset=/china-facebook.com/gfwlist +server=/bikaa.xyz/127.0.0.1#5335 +ipset=/bikaa.xyz/gfwlist +server=/scholar.google.lu/127.0.0.1#5335 +ipset=/scholar.google.lu/gfwlist +server=/hentaivn.net/127.0.0.1#5335 +ipset=/hentaivn.net/gfwlist +server=/thepornguy.org/127.0.0.1#5335 +ipset=/thepornguy.org/gfwlist +server=/supermario.com/127.0.0.1#5335 +ipset=/supermario.com/gfwlist +server=/thetread.com/127.0.0.1#5335 +ipset=/thetread.com/gfwlist +server=/guysnightlife.com/127.0.0.1#5335 +ipset=/guysnightlife.com/gfwlist +server=/youtube.com.au/127.0.0.1#5335 +ipset=/youtube.com.au/gfwlist +server=/guaranitermal.com/127.0.0.1#5335 +ipset=/guaranitermal.com/gfwlist +server=/cheapheadsetmall.com/127.0.0.1#5335 +ipset=/cheapheadsetmall.com/gfwlist +server=/grabhentai.com/127.0.0.1#5335 +ipset=/grabhentai.com/gfwlist +server=/chrome.com/127.0.0.1#5335 +ipset=/chrome.com/gfwlist +server=/mastercard.co.kr/127.0.0.1#5335 +ipset=/mastercard.co.kr/gfwlist +server=/beeg.rest/127.0.0.1#5335 +ipset=/beeg.rest/gfwlist +server=/iphoneunlockimei.com/127.0.0.1#5335 +ipset=/iphoneunlockimei.com/gfwlist +server=/yourtv.com.au/127.0.0.1#5335 +ipset=/yourtv.com.au/gfwlist +server=/proquest.com/127.0.0.1#5335 +ipset=/proquest.com/gfwlist +server=/binance.charity/127.0.0.1#5335 +ipset=/binance.charity/gfwlist +server=/udfs.com/127.0.0.1#5335 +ipset=/udfs.com/gfwlist +server=/cambiaip.org/127.0.0.1#5335 +ipset=/cambiaip.org/gfwlist +server=/fflnk.net/127.0.0.1#5335 +ipset=/fflnk.net/gfwlist +server=/gaystarnews.com/127.0.0.1#5335 +ipset=/gaystarnews.com/gfwlist +server=/mastercard.rs/127.0.0.1#5335 +ipset=/mastercard.rs/gfwlist +server=/roloxxx.com/127.0.0.1#5335 +ipset=/roloxxx.com/gfwlist +server=/swtor.com/127.0.0.1#5335 +ipset=/swtor.com/gfwlist +server=/mariokart7.com/127.0.0.1#5335 +ipset=/mariokart7.com/gfwlist +server=/pornaf.com/127.0.0.1#5335 +ipset=/pornaf.com/gfwlist +server=/flatandfuckedmilfs.com/127.0.0.1#5335 +ipset=/flatandfuckedmilfs.com/gfwlist +server=/gaybeeg.info/127.0.0.1#5335 +ipset=/gaybeeg.info/gfwlist +server=/gamerotic.com/127.0.0.1#5335 +ipset=/gamerotic.com/gfwlist +server=/escandinavia-arg.com/127.0.0.1#5335 +ipset=/escandinavia-arg.com/gfwlist +server=/ox.ac.uk/127.0.0.1#5335 +ipset=/ox.ac.uk/gfwlist +server=/bdsmpornonly.com/127.0.0.1#5335 +ipset=/bdsmpornonly.com/gfwlist +server=/fuq.com/127.0.0.1#5335 +ipset=/fuq.com/gfwlist +server=/gameroom.com/127.0.0.1#5335 +ipset=/gameroom.com/gfwlist +server=/bloomsburycollections.com/127.0.0.1#5335 +ipset=/bloomsburycollections.com/gfwlist +server=/nonstopfap.com/127.0.0.1#5335 +ipset=/nonstopfap.com/gfwlist +server=/fuckingmatures.com/127.0.0.1#5335 +ipset=/fuckingmatures.com/gfwlist +server=/mini-windsor.ca/127.0.0.1#5335 +ipset=/mini-windsor.ca/gfwlist +server=/uplynk.com/127.0.0.1#5335 +ipset=/uplynk.com/gfwlist +server=/xn--hb4aw0g.com/127.0.0.1#5335 +ipset=/xn--hb4aw0g.com/gfwlist +server=/freelifetimefuckbook.com/127.0.0.1#5335 +ipset=/freelifetimefuckbook.com/gfwlist +server=/vfsco.co.uk/127.0.0.1#5335 +ipset=/vfsco.co.uk/gfwlist +server=/paypalprepagata.com/127.0.0.1#5335 +ipset=/paypalprepagata.com/gfwlist +server=/0plkijj.vip/127.0.0.1#5335 +ipset=/0plkijj.vip/gfwlist +server=/shopspeedtv.com/127.0.0.1#5335 +ipset=/shopspeedtv.com/gfwlist +server=/mastercard.jo/127.0.0.1#5335 +ipset=/mastercard.jo/gfwlist +server=/sipriyearbook.org/127.0.0.1#5335 +ipset=/sipriyearbook.org/gfwlist +server=/freejavbt.com/127.0.0.1#5335 +ipset=/freejavbt.com/gfwlist +server=/naver.com/127.0.0.1#5335 +ipset=/naver.com/gfwlist +server=/pinterest.ec/127.0.0.1#5335 +ipset=/pinterest.ec/gfwlist +server=/fitnakedgirls.com/127.0.0.1#5335 +ipset=/fitnakedgirls.com/gfwlist +server=/minicooper.ca/127.0.0.1#5335 +ipset=/minicooper.ca/gfwlist +server=/hbox.jp/127.0.0.1#5335 +ipset=/hbox.jp/gfwlist +server=/bmw.com.mk/127.0.0.1#5335 +ipset=/bmw.com.mk/gfwlist +server=/kijijiautos.ca/127.0.0.1#5335 +ipset=/kijijiautos.ca/gfwlist +server=/mini.gp/127.0.0.1#5335 +ipset=/mini.gp/gfwlist +server=/av6k.com/127.0.0.1#5335 +ipset=/av6k.com/gfwlist +server=/amlg.io/127.0.0.1#5335 +ipset=/amlg.io/gfwlist +server=/fapality.com/127.0.0.1#5335 +ipset=/fapality.com/gfwlist +server=/fansteek.com/127.0.0.1#5335 +ipset=/fansteek.com/gfwlist +server=/fanleakstoday.com/127.0.0.1#5335 +ipset=/fanleakstoday.com/gfwlist +server=/trustcor.ca/127.0.0.1#5335 +ipset=/trustcor.ca/gfwlist +server=/facebooc.com/127.0.0.1#5335 +ipset=/facebooc.com/gfwlist +server=/ext-twitch.tv/127.0.0.1#5335 +ipset=/ext-twitch.tv/gfwlist +server=/facebolk.com/127.0.0.1#5335 +ipset=/facebolk.com/gfwlist +server=/amateur-exhibitionist.org/127.0.0.1#5335 +ipset=/amateur-exhibitionist.org/gfwlist +server=/amebaownd.com/127.0.0.1#5335 +ipset=/amebaownd.com/gfwlist +server=/evaelfie.com/127.0.0.1#5335 +ipset=/evaelfie.com/gfwlist +server=/escortamsterdam1.com/127.0.0.1#5335 +ipset=/escortamsterdam1.com/gfwlist +server=/airwick.jp/127.0.0.1#5335 +ipset=/airwick.jp/gfwlist +server=/vhxqa1.com/127.0.0.1#5335 +ipset=/vhxqa1.com/gfwlist +server=/nintendo.tw/127.0.0.1#5335 +ipset=/nintendo.tw/gfwlist +server=/canon-europe.com/127.0.0.1#5335 +ipset=/canon-europe.com/gfwlist +server=/volvopenta.it/127.0.0.1#5335 +ipset=/volvopenta.it/gfwlist +server=/volvogroup.nl/127.0.0.1#5335 +ipset=/volvogroup.nl/gfwlist +server=/entensity.net/127.0.0.1#5335 +ipset=/entensity.net/gfwlist +server=/instagramdi.com/127.0.0.1#5335 +ipset=/instagramdi.com/gfwlist +server=/harpercollins.com/127.0.0.1#5335 +ipset=/harpercollins.com/gfwlist +server=/nubiles-casting.com/127.0.0.1#5335 +ipset=/nubiles-casting.com/gfwlist +server=/twtrdns.net/127.0.0.1#5335 +ipset=/twtrdns.net/gfwlist +server=/enema-porn.com/127.0.0.1#5335 +ipset=/enema-porn.com/gfwlist +server=/adultlister.com/127.0.0.1#5335 +ipset=/adultlister.com/gfwlist +server=/mylogiclab.com/127.0.0.1#5335 +ipset=/mylogiclab.com/gfwlist +server=/microsoft.pl/127.0.0.1#5335 +ipset=/microsoft.pl/gfwlist +server=/youtube.co.in/127.0.0.1#5335 +ipset=/youtube.co.in/gfwlist +server=/adidas.nl/127.0.0.1#5335 +ipset=/adidas.nl/gfwlist +server=/extreme-board.com/127.0.0.1#5335 +ipset=/extreme-board.com/gfwlist +server=/thewonderful101.com/127.0.0.1#5335 +ipset=/thewonderful101.com/gfwlist +server=/dumps69.com/127.0.0.1#5335 +ipset=/dumps69.com/gfwlist +server=/dswz88.xyz/127.0.0.1#5335 +ipset=/dswz88.xyz/gfwlist +server=/drunkentop.com/127.0.0.1#5335 +ipset=/drunkentop.com/gfwlist +server=/drtuber.com/127.0.0.1#5335 +ipset=/drtuber.com/gfwlist +server=/beautyescortsamsterdam.com/127.0.0.1#5335 +ipset=/beautyescortsamsterdam.com/gfwlist +server=/lawdata.com.tw/127.0.0.1#5335 +ipset=/lawdata.com.tw/gfwlist +server=/tvb.com/127.0.0.1#5335 +ipset=/tvb.com/gfwlist +server=/bossae.com/127.0.0.1#5335 +ipset=/bossae.com/gfwlist +server=/bmwofcentralpa.com/127.0.0.1#5335 +ipset=/bmwofcentralpa.com/gfwlist +server=/dirtyonline.com/127.0.0.1#5335 +ipset=/dirtyonline.com/gfwlist +server=/illusionn2.com/127.0.0.1#5335 +ipset=/illusionn2.com/gfwlist +server=/yy55.tv/127.0.0.1#5335 +ipset=/yy55.tv/gfwlist +server=/dirtyfarmer.com/127.0.0.1#5335 +ipset=/dirtyfarmer.com/gfwlist +server=/rbdigitalab.com/127.0.0.1#5335 +ipset=/rbdigitalab.com/gfwlist +server=/bmw-yeg.ca/127.0.0.1#5335 +ipset=/bmw-yeg.ca/gfwlist +server=/dhlestudio.com.co/127.0.0.1#5335 +ipset=/dhlestudio.com.co/gfwlist +server=/deasians.com/127.0.0.1#5335 +ipset=/deasians.com/gfwlist +server=/bmw-motorrad.sk/127.0.0.1#5335 +ipset=/bmw-motorrad.sk/gfwlist +server=/rapetube.me/127.0.0.1#5335 +ipset=/rapetube.me/gfwlist +server=/czechcasting.com/127.0.0.1#5335 +ipset=/czechcasting.com/gfwlist +server=/paypal.hk/127.0.0.1#5335 +ipset=/paypal.hk/gfwlist +server=/hifacebook.info/127.0.0.1#5335 +ipset=/hifacebook.info/gfwlist +server=/adcommerce.tv/127.0.0.1#5335 +ipset=/adcommerce.tv/gfwlist +server=/czechbiporn.com/127.0.0.1#5335 +ipset=/czechbiporn.com/gfwlist +server=/mybridgestoneeducation.com/127.0.0.1#5335 +ipset=/mybridgestoneeducation.com/gfwlist +server=/developers.facebook.com/127.0.0.1#5335 +ipset=/developers.facebook.com/gfwlist +server=/ebaydts.com/127.0.0.1#5335 +ipset=/ebaydts.com/gfwlist +server=/yandex.ua/127.0.0.1#5335 +ipset=/yandex.ua/gfwlist +server=/starwarsbattlefront2.com/127.0.0.1#5335 +ipset=/starwarsbattlefront2.com/gfwlist +server=/wmcloud.org/127.0.0.1#5335 +ipset=/wmcloud.org/gfwlist +server=/tegrazone.co/127.0.0.1#5335 +ipset=/tegrazone.co/gfwlist +server=/gvt7.com/127.0.0.1#5335 +ipset=/gvt7.com/gfwlist +server=/crabporn.com/127.0.0.1#5335 +ipset=/crabporn.com/gfwlist +server=/okazudouga.blog.jp/127.0.0.1#5335 +ipset=/okazudouga.blog.jp/gfwlist +server=/scholar.google.sk/127.0.0.1#5335 +ipset=/scholar.google.sk/gfwlist +server=/indiaipad.com/127.0.0.1#5335 +ipset=/indiaipad.com/gfwlist +server=/sportsfacebook.com/127.0.0.1#5335 +ipset=/sportsfacebook.com/gfwlist +server=/discountbeatsbydre-us.com/127.0.0.1#5335 +ipset=/discountbeatsbydre-us.com/gfwlist +server=/hentairead.com/127.0.0.1#5335 +ipset=/hentairead.com/gfwlist +server=/lapriere.jp/127.0.0.1#5335 +ipset=/lapriere.jp/gfwlist +server=/netlock.hu/127.0.0.1#5335 +ipset=/netlock.hu/gfwlist +server=/mastercardbiz.com/127.0.0.1#5335 +ipset=/mastercardbiz.com/gfwlist +server=/webofscience.com/127.0.0.1#5335 +ipset=/webofscience.com/gfwlist +server=/ch9.ms/127.0.0.1#5335 +ipset=/ch9.ms/gfwlist +server=/miamifintechfestival.com/127.0.0.1#5335 +ipset=/miamifintechfestival.com/gfwlist +server=/cc18.biz/127.0.0.1#5335 +ipset=/cc18.biz/gfwlist +server=/gaypornmenu.com/127.0.0.1#5335 +ipset=/gaypornmenu.com/gfwlist +server=/vfsco.jp/127.0.0.1#5335 +ipset=/vfsco.jp/gfwlist +server=/ilongman.com/127.0.0.1#5335 +ipset=/ilongman.com/gfwlist +server=/ieeeoes.org/127.0.0.1#5335 +ipset=/ieeeoes.org/gfwlist +server=/ebaylocationsdevacances.com/127.0.0.1#5335 +ipset=/ebaylocationsdevacances.com/gfwlist +server=/iotinactionevents.com/127.0.0.1#5335 +ipset=/iotinactionevents.com/gfwlist +server=/sonypicturesmuseum.com/127.0.0.1#5335 +ipset=/sonypicturesmuseum.com/gfwlist +server=/scatfap.com/127.0.0.1#5335 +ipset=/scatfap.com/gfwlist +server=/ebay.com.sg/127.0.0.1#5335 +ipset=/ebay.com.sg/gfwlist +server=/yahoo.com/127.0.0.1#5335 +ipset=/yahoo.com/gfwlist +server=/scholar.google.ru/127.0.0.1#5335 +ipset=/scholar.google.ru/gfwlist +server=/nikebetterworld.org/127.0.0.1#5335 +ipset=/nikebetterworld.org/gfwlist +server=/learnwithleague.com/127.0.0.1#5335 +ipset=/learnwithleague.com/gfwlist +server=/zakzak.co.jp/127.0.0.1#5335 +ipset=/zakzak.co.jp/gfwlist +server=/drdrebeats-usa.com/127.0.0.1#5335 +ipset=/drdrebeats-usa.com/gfwlist +server=/camstreams.tv/127.0.0.1#5335 +ipset=/camstreams.tv/gfwlist +server=/privacysimplified.com/127.0.0.1#5335 +ipset=/privacysimplified.com/gfwlist +server=/softether-download.com/127.0.0.1#5335 +ipset=/softether-download.com/gfwlist +server=/bigboobsandhotsex.com/127.0.0.1#5335 +ipset=/bigboobsandhotsex.com/gfwlist +server=/xboxone.co/127.0.0.1#5335 +ipset=/xboxone.co/gfwlist +server=/headphonesbeatsaudio.com/127.0.0.1#5335 +ipset=/headphonesbeatsaudio.com/gfwlist +server=/newpppp.com/127.0.0.1#5335 +ipset=/newpppp.com/gfwlist +server=/paypal-business.net/127.0.0.1#5335 +ipset=/paypal-business.net/gfwlist +server=/bdsmboard.org/127.0.0.1#5335 +ipset=/bdsmboard.org/gfwlist +server=/sex-av.com/127.0.0.1#5335 +ipset=/sex-av.com/gfwlist +server=/r10s.jp/127.0.0.1#5335 +ipset=/r10s.jp/gfwlist +server=/bmw.cl/127.0.0.1#5335 +ipset=/bmw.cl/gfwlist +server=/youtube.ma/127.0.0.1#5335 +ipset=/youtube.ma/gfwlist +server=/kkff2484.live/127.0.0.1#5335 +ipset=/kkff2484.live/gfwlist +server=/youtube.jo/127.0.0.1#5335 +ipset=/youtube.jo/gfwlist +server=/byjhd.com/127.0.0.1#5335 +ipset=/byjhd.com/gfwlist +server=/ebaylocal.net/127.0.0.1#5335 +ipset=/ebaylocal.net/gfwlist +server=/visa.com.my/127.0.0.1#5335 +ipset=/visa.com.my/gfwlist +server=/playstation.net/127.0.0.1#5335 +ipset=/playstation.net/gfwlist +server=/tver.jp/127.0.0.1#5335 +ipset=/tver.jp/gfwlist +server=/vercel-dns.com/127.0.0.1#5335 +ipset=/vercel-dns.com/gfwlist +server=/brazzers-xxx.net/127.0.0.1#5335 +ipset=/brazzers-xxx.net/gfwlist +server=/gynoexam.info/127.0.0.1#5335 +ipset=/gynoexam.info/gfwlist +server=/yours-customised.mini.com/127.0.0.1#5335 +ipset=/yours-customised.mini.com/gfwlist +server=/dojinwatch.com/127.0.0.1#5335 +ipset=/dojinwatch.com/gfwlist +server=/acgcf.com/127.0.0.1#5335 +ipset=/acgcf.com/gfwlist +server=/miniso.pk/127.0.0.1#5335 +ipset=/miniso.pk/gfwlist +server=/dcard.link/127.0.0.1#5335 +ipset=/dcard.link/gfwlist +server=/volvotruckcenter.no/127.0.0.1#5335 +ipset=/volvotruckcenter.no/gfwlist +server=/visa.com.do/127.0.0.1#5335 +ipset=/visa.com.do/gfwlist +server=/blacksonblondes.com/127.0.0.1#5335 +ipset=/blacksonblondes.com/gfwlist +server=/sonypicturestelevision.com/127.0.0.1#5335 +ipset=/sonypicturestelevision.com/gfwlist +server=/sexflashgame.org/127.0.0.1#5335 +ipset=/sexflashgame.org/gfwlist +server=/toppornsites.com/127.0.0.1#5335 +ipset=/toppornsites.com/gfwlist +server=/amateurporn.photos/127.0.0.1#5335 +ipset=/amateurporn.photos/gfwlist +server=/texture.com/127.0.0.1#5335 +ipset=/texture.com/gfwlist +server=/elitvip.ru/127.0.0.1#5335 +ipset=/elitvip.ru/gfwlist +server=/ikea.qa/127.0.0.1#5335 +ipset=/ikea.qa/gfwlist +server=/sextop.net/127.0.0.1#5335 +ipset=/sextop.net/gfwlist +server=/vtsociety.org/127.0.0.1#5335 +ipset=/vtsociety.org/gfwlist +server=/scholar.google.pt/127.0.0.1#5335 +ipset=/scholar.google.pt/gfwlist +server=/visaeurope.lu/127.0.0.1#5335 +ipset=/visaeurope.lu/gfwlist +server=/swisssign.org/127.0.0.1#5335 +ipset=/swisssign.org/gfwlist +server=/ikea.cl/127.0.0.1#5335 +ipset=/ikea.cl/gfwlist +server=/teslaenergy.services/127.0.0.1#5335 +ipset=/teslaenergy.services/gfwlist +server=/ggpht.com/127.0.0.1#5335 +ipset=/ggpht.com/gfwlist +server=/mastercardezsavings.com/127.0.0.1#5335 +ipset=/mastercardezsavings.com/gfwlist +server=/pximg.net/127.0.0.1#5335 +ipset=/pximg.net/gfwlist +server=/gettyimages.dk/127.0.0.1#5335 +ipset=/gettyimages.dk/gfwlist +server=/mini.com.hr/127.0.0.1#5335 +ipset=/mini.com.hr/gfwlist +server=/customizedbeatbydre.com/127.0.0.1#5335 +ipset=/customizedbeatbydre.com/gfwlist +server=/tickdata.com/127.0.0.1#5335 +ipset=/tickdata.com/gfwlist +server=/animepornhd.com/127.0.0.1#5335 +ipset=/animepornhd.com/gfwlist +server=/ibook.eu/127.0.0.1#5335 +ipset=/ibook.eu/gfwlist +server=/handbags-nike.com/127.0.0.1#5335 +ipset=/handbags-nike.com/gfwlist +server=/oculuscdn.com/127.0.0.1#5335 +ipset=/oculuscdn.com/gfwlist +server=/realamericanstories.net/127.0.0.1#5335 +ipset=/realamericanstories.net/gfwlist +server=/citylab.com/127.0.0.1#5335 +ipset=/citylab.com/gfwlist +server=/aptoide.com/127.0.0.1#5335 +ipset=/aptoide.com/gfwlist +server=/scholar.google.ae/127.0.0.1#5335 +ipset=/scholar.google.ae/gfwlist +server=/pricelesstoronto.ca/127.0.0.1#5335 +ipset=/pricelesstoronto.ca/gfwlist +server=/amateurs-gone-wild.com/127.0.0.1#5335 +ipset=/amateurs-gone-wild.com/gfwlist +server=/instagrem.com/127.0.0.1#5335 +ipset=/instagrem.com/gfwlist +server=/bmw.ie/127.0.0.1#5335 +ipset=/bmw.ie/gfwlist +server=/paypalprepagata.net/127.0.0.1#5335 +ipset=/paypalprepagata.net/gfwlist +server=/nhentai.xxx/127.0.0.1#5335 +ipset=/nhentai.xxx/gfwlist +server=/my-formosa.com/127.0.0.1#5335 +ipset=/my-formosa.com/gfwlist +server=/scholar.google.com.mx/127.0.0.1#5335 +ipset=/scholar.google.com.mx/gfwlist +server=/allinternal.com/127.0.0.1#5335 +ipset=/allinternal.com/gfwlist +server=/bisq.io/127.0.0.1#5335 +ipset=/bisq.io/gfwlist +server=/opgg-static.akamaized.net/127.0.0.1#5335 +ipset=/opgg-static.akamaized.net/gfwlist +server=/9cao9.com/127.0.0.1#5335 +ipset=/9cao9.com/gfwlist +server=/bmw.ua/127.0.0.1#5335 +ipset=/bmw.ua/gfwlist +server=/ioffergift.com/127.0.0.1#5335 +ipset=/ioffergift.com/gfwlist +server=/adultvirtualworlds.net/127.0.0.1#5335 +ipset=/adultvirtualworlds.net/gfwlist +server=/sexsexe1.com/127.0.0.1#5335 +ipset=/sexsexe1.com/gfwlist +server=/adultinfojpn.com/127.0.0.1#5335 +ipset=/adultinfojpn.com/gfwlist +server=/twimg.com/127.0.0.1#5335 +ipset=/twimg.com/gfwlist +server=/adultblogtoplist.com/127.0.0.1#5335 +ipset=/adultblogtoplist.com/gfwlist +server=/intellearningseries.com/127.0.0.1#5335 +ipset=/intellearningseries.com/gfwlist +server=/alphabet.ch/127.0.0.1#5335 +ipset=/alphabet.ch/gfwlist +server=/adult3dporno.com/127.0.0.1#5335 +ipset=/adult3dporno.com/gfwlist +server=/9xlove.xyz/127.0.0.1#5335 +ipset=/9xlove.xyz/gfwlist +server=/cnn.it/127.0.0.1#5335 +ipset=/cnn.it/gfwlist +server=/91cy.app/127.0.0.1#5335 +ipset=/91cy.app/gfwlist +server=/61jxbs42.xyz/127.0.0.1#5335 +ipset=/61jxbs42.xyz/gfwlist +server=/rsg.sc/127.0.0.1#5335 +ipset=/rsg.sc/gfwlist +server=/vfsco.in/127.0.0.1#5335 +ipset=/vfsco.in/gfwlist +server=/sg120.me/127.0.0.1#5335 +ipset=/sg120.me/gfwlist +server=/intel.jo/127.0.0.1#5335 +ipset=/intel.jo/gfwlist +server=/18pornsex.com/127.0.0.1#5335 +ipset=/18pornsex.com/gfwlist +server=/akamaitech.net/127.0.0.1#5335 +ipset=/akamaitech.net/gfwlist +server=/gale.com/127.0.0.1#5335 +ipset=/gale.com/gfwlist +server=/fox10phoenix.com/127.0.0.1#5335 +ipset=/fox10phoenix.com/gfwlist +server=/avstar07.me/127.0.0.1#5335 +ipset=/avstar07.me/gfwlist +server=/youtubekids.com/127.0.0.1#5335 +ipset=/youtubekids.com/gfwlist +server=/bmwusatires.com/127.0.0.1#5335 +ipset=/bmwusatires.com/gfwlist +server=/bloomberg.com/127.0.0.1#5335 +ipset=/bloomberg.com/gfwlist +server=/nikeb.com/127.0.0.1#5335 +ipset=/nikeb.com/gfwlist +server=/minispecialoffers.ca/127.0.0.1#5335 +ipset=/minispecialoffers.ca/gfwlist +server=/cw.com.tw/127.0.0.1#5335 +ipset=/cw.com.tw/gfwlist +server=/appleantilles.com/127.0.0.1#5335 +ipset=/appleantilles.com/gfwlist +server=/bigboobspov.com/127.0.0.1#5335 +ipset=/bigboobspov.com/gfwlist +server=/pokemonletsgoeevee.com/127.0.0.1#5335 +ipset=/pokemonletsgoeevee.com/gfwlist +server=/bmw-welt.tv/127.0.0.1#5335 +ipset=/bmw-welt.tv/gfwlist +server=/ebayparts.com/127.0.0.1#5335 +ipset=/ebayparts.com/gfwlist +server=/visa.com.uy/127.0.0.1#5335 +ipset=/visa.com.uy/gfwlist +server=/ikea.rs/127.0.0.1#5335 +ipset=/ikea.rs/gfwlist +server=/kubakuba1996.com/127.0.0.1#5335 +ipset=/kubakuba1996.com/gfwlist +server=/nikesb.com/127.0.0.1#5335 +ipset=/nikesb.com/gfwlist +server=/vkuseraudio.com/127.0.0.1#5335 +ipset=/vkuseraudio.com/gfwlist +server=/paypalobjects.com/127.0.0.1#5335 +ipset=/paypalobjects.com/gfwlist +server=/alphabet.info/127.0.0.1#5335 +ipset=/alphabet.info/gfwlist +server=/pinterest.vn/127.0.0.1#5335 +ipset=/pinterest.vn/gfwlist +server=/sitepoint.com/127.0.0.1#5335 +ipset=/sitepoint.com/gfwlist +server=/sci-hub.st/127.0.0.1#5335 +ipset=/sci-hub.st/gfwlist +server=/amateur-threesomes.com/127.0.0.1#5335 +ipset=/amateur-threesomes.com/gfwlist +server=/aomedia.org/127.0.0.1#5335 +ipset=/aomedia.org/gfwlist +server=/ea-anz-press.com/127.0.0.1#5335 +ipset=/ea-anz-press.com/gfwlist +server=/delvenetworks.com/127.0.0.1#5335 +ipset=/delvenetworks.com/gfwlist +server=/vk.link/127.0.0.1#5335 +ipset=/vk.link/gfwlist +server=/squirrelvpn.com/127.0.0.1#5335 +ipset=/squirrelvpn.com/gfwlist +server=/ebayinternetsalestax.com/127.0.0.1#5335 +ipset=/ebayinternetsalestax.com/gfwlist +server=/stheadline.com/127.0.0.1#5335 +ipset=/stheadline.com/gfwlist +server=/tiburon.com/127.0.0.1#5335 +ipset=/tiburon.com/gfwlist +server=/boyspornpics.com/127.0.0.1#5335 +ipset=/boyspornpics.com/gfwlist +server=/oecd-ilibrary.org/127.0.0.1#5335 +ipset=/oecd-ilibrary.org/gfwlist +server=/bmw-connecteddrive.fi/127.0.0.1#5335 +ipset=/bmw-connecteddrive.fi/gfwlist +server=/anfutong.com/127.0.0.1#5335 +ipset=/anfutong.com/gfwlist +server=/libsolutions.net/127.0.0.1#5335 +ipset=/libsolutions.net/gfwlist +server=/travelexmoneycard.com/127.0.0.1#5335 +ipset=/travelexmoneycard.com/gfwlist +server=/paypal-dynamic.com/127.0.0.1#5335 +ipset=/paypal-dynamic.com/gfwlist +server=/easyanticheat.net/127.0.0.1#5335 +ipset=/easyanticheat.net/gfwlist +server=/thepaypalshop.com/127.0.0.1#5335 +ipset=/thepaypalshop.com/gfwlist +server=/eaassets-a.akamaihd.net/127.0.0.1#5335 +ipset=/eaassets-a.akamaihd.net/gfwlist +server=/swisssign.com/127.0.0.1#5335 +ipset=/swisssign.com/gfwlist +server=/softbankworld.com/127.0.0.1#5335 +ipset=/softbankworld.com/gfwlist +server=/huffingtonpost.fr/127.0.0.1#5335 +ipset=/huffingtonpost.fr/gfwlist +server=/volvoce.com/127.0.0.1#5335 +ipset=/volvoce.com/gfwlist +server=/ascelibrary.org/127.0.0.1#5335 +ipset=/ascelibrary.org/gfwlist +server=/disney.co.kr/127.0.0.1#5335 +ipset=/disney.co.kr/gfwlist +server=/mytvsuper.com/127.0.0.1#5335 +ipset=/mytvsuper.com/gfwlist +server=/bestsexcam.com/127.0.0.1#5335 +ipset=/bestsexcam.com/gfwlist +server=/bestbuycoffeemakers.com/127.0.0.1#5335 +ipset=/bestbuycoffeemakers.com/gfwlist +server=/bmw-m-safetycar.com/127.0.0.1#5335 +ipset=/bmw-m-safetycar.com/gfwlist +server=/foxbusinessgo.com/127.0.0.1#5335 +ipset=/foxbusinessgo.com/gfwlist +server=/static-verizon.com/127.0.0.1#5335 +ipset=/static-verizon.com/gfwlist +server=/decorativemodels.com/127.0.0.1#5335 +ipset=/decorativemodels.com/gfwlist +server=/surflite.co/127.0.0.1#5335 +ipset=/surflite.co/gfwlist +server=/babble.com/127.0.0.1#5335 +ipset=/babble.com/gfwlist +server=/achievementanalytics.com/127.0.0.1#5335 +ipset=/achievementanalytics.com/gfwlist +server=/javfun.me/127.0.0.1#5335 +ipset=/javfun.me/gfwlist +server=/ebayauthenticate.com.cn/127.0.0.1#5335 +ipset=/ebayauthenticate.com.cn/gfwlist +server=/mini-grouparchive.com/127.0.0.1#5335 +ipset=/mini-grouparchive.com/gfwlist +server=/bmw.gp/127.0.0.1#5335 +ipset=/bmw.gp/gfwlist diff --git a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml new file mode 100644 index 00000000..a0b9f5c5 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml @@ -0,0 +1,43 @@ +log: + level: info +plugins: + - tag: lazy_cache + type: cache + args: + size: 8000 + lazy_cache_ttl: 86400 + + - tag: forward_google + type: forward + args: + concurrent: 2 + upstreams: + + - tag: main_sequence_disable_IPv6 + type: sequence + args: + - exec: $lazy_cache + - exec: prefer_ipv4 + - exec: $forward_google + - matches: + - qtype 28 65 + exec: reject 0 + + - tag: main_sequence_with_IPv6 + type: sequence + args: + - exec: $lazy_cache + - exec: $forward_google + + - tag: udp_server + type: udp_server + args: + entry: DNS_MODE + listen: 0.0.0.0:DNS_PORT + + - tag: tcp_server + type: tcp_server + args: + entry: DNS_MODE + listen: 0.0.0.0:DNS_PORT + diff --git a/luci-app-ssr-plus/root/etc/ssrplus/netflixip.list b/luci-app-ssr-plus/root/etc/ssrplus/netflixip.list new file mode 100644 index 00000000..445ff62f --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/netflixip.list @@ -0,0 +1,30 @@ +8.41.4.0/24 +23.23.189.144/28 +23.246.0.0/18 +34.195.253.0/25 +34.210.42.111/32 +37.77.184.0/21 +38.72.126.0/24 +45.57.0.0/17 +52.24.178.0/24 +52.35.140.0/24 +52.89.124.203/32 +54.148.37.5/32 +54.204.25.0/28 +54.213.167.0/24 +64.120.128.0/17 +66.197.128.0/17 +69.53.224.0/19 +103.87.204.0/22 +108.175.32.0/20 +185.2.220.0/22 +185.9.188.0/22 +192.173.64.0/18 +198.38.96.0/19 +198.45.48.0/20 +203.75.84.0/24 +203.198.13.0/24 +203.198.80.0/24 +207.45.72.0/22 +208.75.76.0/22 +210.0.153.0/24 diff --git a/luci-app-ssr-plus/root/etc/ssrplus/white.list b/luci-app-ssr-plus/root/etc/ssrplus/white.list new file mode 100644 index 00000000..9055fcb9 --- /dev/null +++ b/luci-app-ssr-plus/root/etc/ssrplus/white.list @@ -0,0 +1,7 @@ +bilibili.com +bilibili.cn +bilivideo.com +bilivideo.cn +biliapi.com +biliapi.net +apple.com \ No newline at end of file diff --git a/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus b/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus new file mode 100755 index 00000000..db3c33cc --- /dev/null +++ b/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus @@ -0,0 +1,137 @@ +#!/bin/sh + +if [ -e "/etc/config/ucitrack" ]; then + uci -q batch <<-EOF + delete ucitrack.@shadowsocksr[-1] + add ucitrack shadowsocksr + set ucitrack.@shadowsocksr[-1].init=shadowsocksr + commit ucitrack +EOF +fi + +uci -q batch <<-EOF + delete firewall.shadowsocksr + set firewall.shadowsocksr=include + set firewall.shadowsocksr.type=script + set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include + $(command -v fw4 >/dev/null 2>&1 || echo "set firewall.shadowsocksr.reload=1") + commit firewall +EOF + +rm -rf /etc/config/shadowsocksr-opkg /etc/ssrplus/*opkg +touch /etc/ssrplus/china_ssr.txt +touch /etc/ssrplus/deny.list +touch /etc/ssrplus/white.list +touch /etc/ssrplus/black.list +touch /etc/ssrplus/gfw_base.conf +touch /etc/ssrplus/gfw_list.conf +touch /etc/ssrplus/ad.conf +touch /etc/config/shadowsocksr + +if [ -s "/etc/config/shadowsocksr" ]; then + if uci -q get shadowsocksr.@server_subscribe[0].auto_update_time > /dev/null; then + uci -q delete shadowsocksr.@server_subscribe[0].auto_update_time + fi + + if ! uci -q get shadowsocksr.@server_subscribe[0].auto_update_week_time > /dev/null; then + uci -q set shadowsocksr.@server_subscribe[0].auto_update_week_time='*' + uci -q set shadowsocksr.@server_subscribe[0].auto_update_day_time='2' + uci -q set shadowsocksr.@server_subscribe[0].auto_update_min_time='0' + fi + + if ! uci -q get shadowsocksr.@server_subscribe[0].config_auto_update_mode > /dev/null; then + uci -q set shadowsocksr.@server_subscribe[0].config_auto_update_mode='0' + fi + + if ! uci -q get shadowsocksr.@server_subscribe[0].config_update_interval > /dev/null; then + uci -q set shadowsocksr.@server_subscribe[0].config_update_interval='60' + fi + + if ! uci -q get shadowsocksr.@server_subscribe[0].user_agent > /dev/null; then + uci -q set shadowsocksr.@server_subscribe[0].user_agent='v2rayN/9.99' + fi + + if ! uci -q get shadowsocksr.@server_subscribe[0].proxy > /dev/null; then + uci -q set shadowsocksr.@server_subscribe[0].proxy='1' + fi + + if ! uci -q get shadowsocksr.@global_xray_fragment[0] > /dev/null; then + uci -q add shadowsocksr global_xray_fragment + uci -q set shadowsocksr.@global_xray_fragment[0].fragment='0' + uci -q set shadowsocksr.@global_xray_fragment[0].noise='0' + fi + + if ! uci -q get shadowsocksr.@global[0].component_mirror > /dev/null; then + uci -q set shadowsocksr.@global[0].component_mirror='direct' + fi + + if ! uci -q get shadowsocksr.@global[0].filter_aaaa > /dev/null; then + legacy_filter_aaaa="$(uci -q get shadowsocksr.@global[0].mosdns_ipv6)" + uci -q set shadowsocksr.@global[0].filter_aaaa="${legacy_filter_aaaa:-1}" + fi + + legacy_dns_mode="$(uci -q get shadowsocksr.@global[0].pdnsd_enable)" + if [ "$legacy_dns_mode" = "2" ] || [ "$legacy_dns_mode" = "3" ]; then + uci -q set shadowsocksr.@global[0].pdnsd_enable='1' + fi + + if uci -q get shadowsocksr.@global[0].mosdns_ipv6 > /dev/null; then + uci -q delete shadowsocksr.@global[0].mosdns_ipv6 + fi + + if ! uci -q get shadowsocksr.@http_proxy[0] > /dev/null; then + uci -q add shadowsocksr http_proxy + uci -q set shadowsocksr.@http_proxy[0].server='nil' + uci -q set shadowsocksr.@http_proxy[0].local_port='3128' + uci -q set shadowsocksr.@http_proxy[0].http_auth='none' + fi + + ss_rust_bin="$(command -v ssserver 2>/dev/null)" + [ -n "$ss_rust_bin" ] || [ ! -x /usr/libexec/ssserver ] || ss_rust_bin="/usr/libexec/ssserver" + mihomo_bin="$(command -v mihomo 2>/dev/null)" + [ -n "$mihomo_bin" ] || [ ! -x /usr/libexec/mihomo ] || mihomo_bin="/usr/libexec/mihomo" + xray_bin="$(command -v xray 2>/dev/null)" + [ -n "$xray_bin" ] || [ ! -x /usr/libexec/xray ] || xray_bin="/usr/libexec/xray" + for section in $(uci -q show shadowsocksr | sed -n "s/^shadowsocksr\\.\\([^.=][^.=]*\\)=servers$/\\1/p"); do + node_type="$(uci -q get shadowsocksr.${section}.type)" + case "$node_type" in + ss|ss-libev) + if [ -n "$mihomo_bin" ]; then + uci -q set shadowsocksr.${section}.type='ss' + elif [ -n "$ss_rust_bin" ]; then + uci -q set shadowsocksr.${section}.type='ss-rust' + elif [ -n "$xray_bin" ]; then + uci -q set shadowsocksr.${section}.type='v2ray' + uci -q set shadowsocksr.${section}.v2ray_protocol='shadowsocks' + fi + ;; + v2ray) + if [ "$(uci -q get shadowsocksr.${section}.v2ray_protocol)" = "shadowsocks" ] && [ -n "$mihomo_bin" ]; then + uci -q set shadowsocksr.${section}.type='ss' + uci -q delete shadowsocksr.${section}.v2ray_protocol + fi + ;; + esac + done + + uci -q commit shadowsocksr + fi + +[ -s "/etc/config/shadowsocksr" ] || /etc/init.d/shadowsocksr reset + +sed -i "s/option type 'vmess'/option type 'v2ray'\n\toption v2ray_protocol 'vmess'/g" /etc/config/shadowsocksr +sed -i "s/option type 'vless'/option type 'v2ray'\n\toption v2ray_protocol 'vless'/g" /etc/config/shadowsocksr +sed -i "s/option encrypt_method_v2ray_ss/option encrypt_method_ss/g" /etc/config/shadowsocksr +sed -i "s/option xtls/option tls/g" /etc/config/shadowsocksr +sed -i "/option vless_flow/d" /etc/config/shadowsocksr +sed -i "/option fingerprint 'disable'/d" /etc/config/shadowsocksr + +if [ -s "/etc/uwsgi/vassals/luci-webui.ini" ];then + limit=$(cat /etc/uwsgi/vassals/luci-webui.ini | grep -Eo "limit-as.*"|grep -Eo "[0-9]+") + [ $limit -lt 5000 ] && sed -i '/limit-as/c\limit-as = 5000' /etc/uwsgi/vassals/luci-webui.ini && \ + /etc/init.d/uwsgi restart +fi + +rm -f /tmp/luci-indexcache /tmp/luci-indexcache.* +rm -rf /tmp/luci-modulecache/ +exit 0 diff --git a/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus.rej b/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus.rej new file mode 100644 index 00000000..69e055da --- /dev/null +++ b/luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus.rej @@ -0,0 +1,11 @@ +--- luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus ++++ luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus +@@ -43,5 +43,8 @@ if [ -s "/etc/uwsgi/vassals/luci-webui.ini" ];then + /etc/init.d/uwsgi restart + fi + ++grep -q ip-api.com /etc/ssrplus/black.list || ++ sed -i '$a ip-api.com' /etc/ssrplus/black.list ++ + rm -rf /tmp/luci-modulecache /tmp/luci-indexcache + exit 0 diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-monitor b/luci-app-ssr-plus/root/usr/bin/ssr-monitor new file mode 100755 index 00000000..d9732d25 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/bin/ssr-monitor @@ -0,0 +1,225 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# +. $IPKG_INSTROOT/etc/init.d/shadowsocksr +LOCK_FILE="/var/lock/ssr-monitor.lock" +[ -f "$LOCK_FILE" ] && exit 2 +touch "$LOCK_FILE" + +ps_list() { + if busybox ps -w >/dev/null 2>&1; then + busybox ps -w + else + busybox ps + fi +} + +match_proc_count() { + local pattern="$1" + ps_list | grep -E "$pattern" | grep -v grep | wc -l +} + +redir_tcp_running() { + local ssr_count + local ipt_count + ssr_count=$(match_proc_count 'ssr-retcp') + ipt_count=$(ps_list | grep 'ipt2socks' | grep -v grep | grep -E ' -T( |$)| --tcp-only( |$)' | wc -l) + echo $((ssr_count + ipt_count)) +} + +redir_udp_running() { + local ssr_count + local ipt_count + ssr_count=$(match_proc_count 'ssr-reudp') + ipt_count=$(ps_list | grep 'ipt2socks' | grep -v grep | grep -E ' -U( |$)| --udp-only( |$)' | wc -l) + echo $((ssr_count + ipt_count)) +} + +kill_matched_procs() { + local pattern="$1" + ps_list | grep -E "$pattern" | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 +} + +get_expected_threads() { + local threads + threads=$(uci_get_by_type global threads 0) + if [ "$threads" = "0" ] || [ -z "$threads" ]; then + threads=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null) + fi + + case "$threads" in + ''|*[!0-9]*) + threads=1 + ;; + esac + + [ "$threads" -lt 1 ] && threads=1 + echo "$threads" +} + +server_process_count=$1 +redir_tcp_process=$2 +redir_udp_process=$3 +kcp_process=$4 +local_process=$5 +pdnsd_process=$6 +if [ -z "$pdnsd_process" ]; then + pdnsd_process=0 +fi +i=0 +GLOBAL_SERVER=$(uci_get_by_type global global_server) +GLOBAL_TYPE=$(uci_get_by_name $GLOBAL_SERVER type) +EXPECTED_THREADS=$(get_expected_threads) +server=$(uci_get_by_name $GLOBAL_SERVER server) +kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port) +server_port=$(uci_get_by_name $GLOBAL_SERVER server_port) +password=$(uci_get_by_name $GLOBAL_SERVER kcp_password) +kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param) +[ "$password" != "" ] && password="--key "${password} + +while [ "1" == "1" ]; do #死循环 + sleep 000030s + #redir tcp + if [ "$redir_tcp_process" -gt 0 ]; then + icount=$(redir_tcp_running) + local tcp_expected="$redir_tcp_process" + if [ "$GLOBAL_TYPE" = "socks5" ]; then + tcp_expected="$EXPECTED_THREADS" + fi + if [ "$icount" -lt "$tcp_expected" ]; then + logger -t "$NAME" "ssrplus redir tcp error.restart!" + echolog "ssrplus redir tcp error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #redir udp + if [ "$redir_udp_process" -gt 0 ]; then + icount=$(redir_udp_running) + local udp_expected="$redir_udp_process" + if [ "$GLOBAL_TYPE" = "socks5" ]; then + udp_expected="$EXPECTED_THREADS" + fi + if [ "$icount" -lt "$udp_expected" ]; then + logger -t "$NAME" "ssrplus redir udp error.restart!" + echolog "ssrplus redir udp error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #server + if [ "$server_process_count" -gt 0 ]; then + icount=$(match_proc_count 'ssr-server|ss-server-|xray-server-') + if [ "$icount" -lt "$server_process_count" ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "ssrplus server error.restart!" + echolog "ssrplus server error.restart!" + kill_matched_procs 'ssr-server|ss-server-' + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #kcptun + if [ "$kcp_process" -gt 0 ]; then + icount=$(ps_list | grep kcptun-client | grep -v grep | wc -l) + if [ "$icount" -lt "$kcp_process" ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "ssrplus kcptun error.restart!" + echolog "ssrplus kcptun error.restart!" + killall -q -9 kcptun-client + (/usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &) + fi + fi + #localsocks + if [ "$local_process" -gt 0 ]; then + icount=$(match_proc_count 'ssr-local|ss-local|tuic-local') + if [ "$icount" -lt "$local_process" ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "global socks server error.restart!" + echolog "global socks server error.restart!" + kill_matched_procs 'ssr-local|ss-local|tuic-local' + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #dns2tcp + if [ "$pdnsd_process" -eq 1 ]; then + icount=$(ps_list | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | wc -l) + if [ "$icount" -lt 1 ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "dns2tcp tunnel error.restart!" + echolog "dns2tcp tunnel error.restart!" + dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53) + kill -9 $(ps_list | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + start_dns2tcp "$dnsserver" + fi + #mosdns + elif [ "$pdnsd_process" -eq 4 ]; then + icount=$(ps_list | grep $TMP_BIN_PATH/mosdns | grep -v grep | wc -l) + if [ "$icount" -lt 1 ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "mosdns tunnel error.restart!" + echolog "mosdns tunnel error.restart!" + dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53) + kill -9 $(ps_list | grep $TMP_BIN_PATH/mosdns | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + ln_start_bin $(first_type mosdns) mosdns start -c /etc/mosdns/config.yaml + fi + #chinadns-ng(proxy) + elif [ "$pdnsd_process" -eq 6 ]; then + icount=$(ps_list | grep -e ssrplus-dns -e "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | wc -l) + if [ "$icount" -lt 1 ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "chinadns-ng $dnsserver tunnel error.restart!" + echolog "chinadns-ng $dnsserver tunnel error.restart!" + dnsserver=$(uci_get_by_type global chinadns_ng_tunnel_forward 8.8.4.4:53) + kill -9 $(ps_list | grep "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + local chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)" + local chinadns_ng_dns="" + IFS=',' + for chinadns_ng_server in $dnsserver; do + local chinadns_ng_ip="${chinadns_ng_server%%:*}" + local chinadns_ng_port="${chinadns_ng_server##*:}" + [ "$chinadns_ng_ip" = "$chinadns_ng_port" ] && chinadns_ng_port="53" + chinadns_ng_tls_port="853" + case "$chinadns_ng_proto" in + "none") + chinadns_ng_server="${chinadns_ng_ip}#${chinadns_ng_port}" + ;; + "tls") + chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_tls_port}" + ;; + *) + chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_port}" + ;; + esac + chinadns_ng_dns="${chinadns_ng_dns} -t ${chinadns_ng_server}" + done + unset IFS + dnsserver="$chinadns_ng_dns" + ln_start_bin $(first_type chinadns-ng) chinadns-ng -b 127.0.0.1 -l $tmp_dns_port -l $dns_port -p 3 -d gfw $dnsserver -N --filter-qtype 64,65 -f -r --cache 4096 --cache-stale 86400 --cache-refresh 20 + fi + #built-in dns + elif [ "$pdnsd_process" -eq 7 ]; then + if ! is_builtin_dns_active; then + logger -t "$NAME" "builtin dns error.restart!" + echolog "builtin dns error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #chinadns-ng(china) + if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then + icount=$(ps_list | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | wc -l) + if [ "$icount" -lt 1 ]; then #如果进程挂掉就é‡å¯å®ƒ + logger -t "$NAME" "chinadns-ng tunnel error.restart!" + echolog "chinadns-ng tunnel error.restart!" + chinadns=$(uci_get_by_type global chinadns_forward) + wandns="$(ifstatus wan | jsonfilter -e '@["dns-server"][0]' || echo "119.29.29.29")" + case "$chinadns" in + "wan") chinadns="$wandns" ;; + ""|"wan_114") chinadns="$wandns,114.114.114.114" ;; + esac + kill -9 $(ps_list | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + ln_start_bin $(first_type chinadns-ng) chinadns-ng -l $china_dns_port -4 china -p 3 -c ${chinadns/:/#} -t 127.0.0.1#$dns_port -N -f -r + fi + fi +done diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-rules b/luci-app-ssr-plus/root/usr/bin/ssr-rules new file mode 100755 index 00000000..7cabb5b0 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/bin/ssr-rules @@ -0,0 +1,1938 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +. $IPKG_INSTROOT/etc/init.d/shadowsocksr + +# Detect firewall version and set appropriate tools +detect_firewall() { + check_run_environment + case "$USE_TABLES" in + nftables) + USE_NFT=1 + NFT="nft" + echolog "ssr-rules: Using nftables" + ;; + iptables) + USE_NFT=0 + IPT="iptables -t nat" # alias of iptables TCP + ipt="iptables -t mangle" # alias of iptables UDP + echolog "ssr-rules: Using iptables" + ;; + *) + echolog "ERROR: No supported firewall backend" + return 1 + ;; + esac + FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file +} + +# Initialize firewall detection +detect_firewall + +TAG="_SS_SPEC_RULE_" # comment tag + +# Initialize all global switch variables (for both NFT and IPT) +# These variables will be set in getopts parameter parsing +ENABLE_AUTO_UPDATE=0 +STOP_AUTO_UPDATE=0 +FORCE_UPDATE=0 +CHECK_STATUS=0 +RESTORE_RULES=0 +FLUSH_RULES=0 +CLEANUP_PERSISTENCE=0 +# ASCII code for SSRP.Use whatever,just not the same. +FWMARK="0x53535250" + +if [ "$USE_NFT" = "1" ]; then + # NFTables persistence directory + NFTABLES_RULES_DIR="/usr/share/nftables.d/ruleset-post" + NFTABLES_RULES_FILE="$NFTABLES_RULES_DIR/99-shadowsocksr.nft" + # Auto-update configuration + AUTO_UPDATE_INTERVAL=300 # auto-update check interval (seconds), 0 means disable +fi + +# Modified usage function +usage() { + cat <<-EOF + Usage: ssr-rules [options] + + Valid options are: + + -s ip address of shadowsocksr remote server + -l port number of shadowsocksr local server + -S ip address of shadowsocksr remote UDP server + -L port number of shadowsocksr local UDP server + -i a file content is bypassed ip list + -a lan ip of access control, need a prefix to + define access control mode + -b wan ip of will be bypassed + -w wan ip of will be forwarded + -B lan ip of will be bypassed proxy + -p lan ip of will be global proxy + -G lan ip of will be game mode proxy + -D proxy ports + -F shunt mode + -N shunt server IP + -M shunt proxy mode + -m Interface name + -I a file content is bypassed shunt ip list + -e extra options for iptables + -o apply the rules to the OUTPUT chain + -O apply the global rules to the OUTPUT chain + -u enable udprelay mode, TPROXY is required + -U enable udprelay mode, using different IP + and ports for TCP and UDP + -y disable all auxiliary UDP rules when UDP + transparent proxy is unavailable + -f flush the rules + -g gfwlist mode + -r router mode + -z all mode + + # New persistence management options (use different letters to avoid conflicts) + -A enable auto-update daemon + -K stop auto-update daemon + -P force update persistence + -C check rules status + -R restore rules from persistence file + -X cleanup persistence files on stop + + -h show this help message and exit + EOF + exit $1 +} + +loger() { + # 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug + logger -st ssr-rules[$$] -p$1 $2 +} + +# IP list normalization function (for comparison) +normalize_ip_list() { + echo "$1" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ $//' +} + +# Check if IP list has changed +check_ip_list_changed() { + local current_list="$1" + local last_list="$2" + local list_name="$3" + + local current_norm=$(normalize_ip_list "$current_list") + local last_norm=$(normalize_ip_list "$last_list") + + if [ "$current_norm" != "$last_norm" ]; then + loger 6 "$list_name changed: '$last_norm' -> '$current_norm'" + return 1 # changed + else + loger 6 "$list_name unchanged: '$current_norm'" + return 0 # unchanged + fi +} + +# Cleanup persistence and runtime module files +cleanup_persistence_files() { + if [ "$USE_NFT" != "1" ]; then + return 0 + fi + + # Remove persistence rule file + if [ -f "$NFTABLES_RULES_FILE" ]; then + rm -f "$NFTABLES_RULES_FILE" 2>/dev/null + loger 5 "Removed persistence file: $NFTABLES_RULES_FILE" + fi + + # Remove run mode file + if [ -f "/tmp/.ssr_run_mode" ]; then + rm -f "/tmp/.ssr_run_mode" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.ssr_run_mode" + fi + + # Remove TPROXY file + if [ -f "/tmp/.last_tproxy" ]; then + rm -f "/tmp/.last_tproxy" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_tproxy" + fi + + # Remove PROXY_PORTS file + if [ -f "/tmp/.last_proxy_ports" ]; then + rm -f "/tmp/.last_proxy_ports" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_proxy_ports" + fi + + # Remove WAN_BP_IP file + if [ -f "/tmp/.last_wan_bp_ip" ]; then + rm -f "/tmp/.last_wan_bp_ip" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_wan_bp_ip" + fi + + # Remove LAN_AC_IP file + if [ -f "/tmp/.last_lan_ac_ip" ]; then + rm -f "/tmp/.last_lan_ac_ip" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_lan_ac_ip" + fi + + # Remove LAN_BP_IP file + if [ -f "/tmp/.last_lan_bp_ip" ]; then + rm -f "/tmp/.last_lan_bp_ip" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_lan_bp_ip" + fi + + # Remove WAN_FW_IP file + if [ -f "/tmp/.last_wan_fw_ip" ]; then + rm -f "/tmp/.last_wan_fw_ip" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_wan_fw_ip" + fi + + # Remove LAN_FP_IP file + if [ -f "/tmp/.last_lan_fp_ip" ]; then + rm -f "/tmp/.last_lan_fp_ip" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_lan_fp_ip" + fi + + # Remove LAN_GM_IP file + if [ -f "/tmp/.last_lan_gm_ip" ]; then + rm -f "/tmp/.last_lan_gm_ip" 2>/dev/null + loger 5 "Removed run mode file: /tmp/.last_lan_gm_ip" + fi + + # Remove xhttp file state and hash files + if [ -f "/tmp/.last_xhttp_file" ]; then + rm -f "/tmp/.last_xhttp_file" 2>/dev/null + loger 5 "Removed xhttp file state: /tmp/.last_xhttp_file" + fi + if [ -f "/tmp/.last_xhttp_hash" ]; then + rm -f "/tmp/.last_xhttp_hash" 2>/dev/null + loger 5 "Removed xhttp hash file: /tmp/.last_xhttp_hash" + fi + + loger 5 "Persistence cleanup completed" + return 0 +} + +flush_r() { + if [ "$USE_NFT" = "1" ]; then + flush_nftables + else + flush_iptables_legacy + fi + return 0 +} + +flush_nftables() { + # Delete inet ss_spec table + if $NFT list table inet ss_spec >/dev/null 2>&1; then + # Delete all chains + local CHAINS=$($NFT list table inet ss_spec | awk '/chain [a-zA-Z0-9_-]+/ {print $2}' | sort -u) + for chain in $CHAINS; do + $NFT flush chain inet ss_spec $chain 2>/dev/null + $NFT delete chain inet ss_spec $chain 2>/dev/null + done + + # Delete all sets + local SETS=$($NFT list table inet ss_spec | awk '/set [a-zA-Z0-9_-]+/ {print $2}' | sort -u) + for setname in $SETS; do + $NFT flush set inet ss_spec $setname 2>/dev/null + $NFT delete set inet ss_spec $setname 2>/dev/null + done + + # Delete entire table + $NFT delete table inet ss_spec 2>/dev/null + fi + + # Delete ip ss_spec_mangle table (if exists) + if $NFT list table ip ss_spec_mangle >/dev/null 2>&1; then + # Delete all chains + local CHAINS=$($NFT list table ip ss_spec_mangle | awk '/chain [a-zA-Z0-9_-]+/ {print $2}' | sort -u) + for chain in $CHAINS; do + $NFT flush chain ip ss_spec_mangle $chain 2>/dev/null + $NFT delete chain ip ss_spec_mangle $chain 2>/dev/null + done + + # Delete all sets + local SETS=$($NFT list table ip ss_spec_mangle | awk '/set [a-zA-Z0-9_-]+/ {print $2}' | sort -u) + for setname in $SETS; do + $NFT flush set ip ss_spec_mangle $setname 2>/dev/null + $NFT delete set ip ss_spec_mangle $setname 2>/dev/null + done + # Delete entire table + $NFT delete table ip ss_spec_mangle 2>/dev/null + fi + + # Delete policy routing mark rules + if ip rule show | grep -Eq "fwmark ${FWMARK}.*lookup 999"; then + ip rule del fwmark ${FWMARK} table 999 2>/dev/null + fi + if ip route show table 999 | grep -Eq "^local.*dev lo"; then + ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null + fi + + # Optional: force delete all ss_spec related sets (even if table was accidentally deleted) + for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router \ + china fplan bplan gmlan whitelist blacklist gfwlist music; do + $NFT delete set inet ss_spec $setname 2>/dev/null + $NFT delete set ip ss_spec_mangle $setname 2>/dev/null + done + + # Reset firewall include file + [ -n "$FWI" ] && echo '#!/bin/sh' >"$FWI" + + # Cleanup persistence and runtime module files + if [ "$CLEANUP_PERSISTENCE" = "1" ]; then + cleanup_persistence_files + fi + + loger 6 "Memory rules flushed successfully" + + return 0 +} + +flush_iptables_legacy() { + flush_iptables() { + local ipt="iptables -t $1" + local DAT=$(iptables-save -t $1) + eval $(echo "$DAT" | grep "$TAG" | sed -e 's/^-A/$ipt -D/' -e 's/$/;/') + for chain in $(echo "$DAT" | awk '/^:SS_SPEC/{print $1}'); do + $ipt -F ${chain:1} 2>/dev/null && $ipt -X ${chain:1} + done + } + flush_iptables nat + flush_iptables mangle + if ip rule show | grep -Eq "fwmark ${FWMARK}.*lookup 999"; then + ip rule del fwmark ${FWMARK} table 999 2>/dev/null + fi + if ip route show table 999 | grep -Eq "^local.*dev lo"; then + ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null + fi + for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router \ + china fplan bplan gmlan whitelist blacklist gfwlist music; do + ipset -X $setname 2>/dev/null + done + [ -n "$FWI" ] && echo '#!/bin/sh' >$FWI + return 0 +} + +ipset_r() { + if [ "$USE_NFT" = "1" ]; then + ipset_nft + else + ipset_iptables + fi + return $? +} + +ipset_nft() { + # Create nftables table and sets + if ! $NFT list table inet ss_spec >/dev/null 2>&1; then + $NFT add table inet ss_spec 2>/dev/null + fi + + # Create necessary collections + for setname in china gmlan fplan bplan whitelist blacklist music; do + if ! $NFT list set inet ss_spec $setname >/dev/null 2>&1; then + $NFT add set inet ss_spec $setname '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null + else + $NFT flush set inet ss_spec $setname 2>/dev/null + fi + done + + # Bulk import china ip list safely (avoid huge single element limitation) + if [ -f "$IGNORE_LIST" ]; then + SKIP_INET=1 /usr/share/shadowsocksr/chinaipset.sh "$IGNORE_LIST" + fi + + # Bulk import xhttp ip list into nft whitelist (server + shunt) + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + $NFT add element inet ss_spec whitelist "{ $(tr '\n' ',' < "${xhttp_ip}" | sed 's/,$//') }" 2>/dev/null + fi + + # Add IP addresses to sets + for ip in $LAN_GM_IP; do + [ -n "$ip" ] && $NFT add element inet ss_spec gmlan "{ $ip }" 2>/dev/null + done + for ip in $LAN_FP_IP; do + [ -n "$ip" ] && $NFT add element inet ss_spec fplan "{ $ip }" 2>/dev/null + done + for ip in $LAN_BP_IP; do + [ -n "$ip" ] && $NFT add element inet ss_spec bplan "{ $ip }" 2>/dev/null + done + for ip in $WAN_BP_IP; do + [ -n "$ip" ] && $NFT add element inet ss_spec whitelist "{ $ip }" 2>/dev/null + done + for ip in $WAN_FW_IP; do + [ -n "$ip" ] && $NFT add element inet ss_spec blacklist "{ $ip }" 2>/dev/null + done + + # Create main chains for WAN access control + for chain in ss_spec_wan_fw ss_spec_wan_ac; do + if ! $NFT list chain inet ss_spec $chain >/dev/null 2>&1; then + $NFT add chain inet ss_spec $chain + fi + $NFT flush chain inet ss_spec $chain + done + + # Add basic rules + # BASIC RULES (exceptions first) — TCP + $NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp tcp dport 53 ip daddr 127.0.0.0/8 return + [ -n "$server" ] && $NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp tcp dport != 53 ip daddr "$server" return + + # Access control: blacklist -> whitelist -> fplan/bplan — TCP + $NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @blacklist jump ss_spec_wan_fw + $NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @whitelist return + $NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @fplan jump ss_spec_wan_fw + $NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @bplan return + + # Music unlocking support + if $NFT list set inet ss_spec music >/dev/null 2>&1; then + $NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp ip daddr @music return + fi + + # Set up mode-specific rules + case "$RUNMODE" in + router) + if ! $NFT list set inet ss_spec ss_spec_wan_ac >/dev/null 2>&1; then + $NFT add set inet ss_spec ss_spec_wan_ac '{ type ipv4_addr; flags interval; auto-merge; }' + else + $NFT flush set inet ss_spec ss_spec_wan_ac 2>/dev/null + fi + # Add special IP ranges to WAN AC set + for ip in $(gen_spec_iplist); do + [ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_wan_ac "{ $ip }" 2>/dev/null + done + + $NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @ss_spec_wan_ac return + $NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @china return + if $NFT list chain inet ss_spec ss_spec_wan_ac >/dev/null 2>&1; then + $NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw + $NFT add rule inet ss_spec ss_spec_wan_ac jump ss_spec_wan_fw + fi + ;; + gfw) + if ! $NFT list set inet ss_spec gfwlist >/dev/null 2>&1; then + $NFT add set inet ss_spec gfwlist '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null + fi + $NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @china return + $NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @gfwlist jump ss_spec_wan_fw + $NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw + ;; + all) + if $NFT list chain inet ss_spec ss_spec_wan_fw >/dev/null 2>&1; then + $NFT add rule inet ss_spec ss_spec_wan_ac jump ss_spec_wan_fw + fi + ;; + esac + + return $? +} + +ipset_iptables() { + [ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh "$IGNORE_LIST" + + $IPT -N SS_SPEC_WAN_AC 2>/dev/null + $IPT -F SS_SPEC_WAN_AC + $IPT -I SS_SPEC_WAN_AC -m mark --mark 255 -j RETURN + + $IPT -I SS_SPEC_WAN_AC -p tcp --dport 53 -d 127.0.0.0/8 -j RETURN + [ -n "$server" ] && $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d "$server" -j RETURN + + ipset -N gmlan hash:net 2>/dev/null + for ip in $LAN_GM_IP; do ipset -! add gmlan "$ip"; done + + case "$RUNMODE" in + router) + ipset -! -R <<-EOF || return 1 + create ss_spec_wan_ac hash:net + $(gen_spec_iplist | sed -e "s/^/add ss_spec_wan_ac /") + EOF + $IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW + ;; + gfw) + ipset -N gfwlist hash:net 2>/dev/null + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW + ;; + all) + $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW + ;; + esac + + ipset -N fplan hash:net 2>/dev/null + for ip in $LAN_FP_IP; do ipset -! add fplan "$ip"; done + $IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW + + ipset -N bplan hash:net 2>/dev/null + for ip in $LAN_BP_IP; do ipset -! add bplan "$ip"; done + $IPT -I SS_SPEC_WAN_AC -m set --match-set bplan src -j RETURN + + ipset -N whitelist hash:net 2>/dev/null + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + while IFS= read -r ip; do + [ -n "$ip" ] && ipset add whitelist "$ip" -exist + done < "$xhttp_ip" + fi + + ipset -N blacklist hash:net 2>/dev/null + $IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW + $IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN + + if [ $(ipset list music -name -quiet | grep music) ]; then + $IPT -I SS_SPEC_WAN_AC -m set --match-set music dst -j RETURN 2>/dev/null + fi + + for ip in $WAN_BP_IP; do ipset -! add whitelist "$ip"; done + for ip in $WAN_FW_IP; do ipset -! add blacklist "$ip"; done + return $? +} + +fw_rule() { + if [ "$USE_NFT" = "1" ]; then + fw_rule_nft + else + fw_rule_iptables + fi + return $? +} + +fw_rule_nft() { + # redirect/translation: when PROXY_PORTS present, redirect those tcp ports to local_port + if [ -n "$PROXY_PORTS" ]; then + PORTS_ARGS=$(echo "$PROXY_PORTS" | sed 's/-m multiport --dports //') + if [ -n "$PORTS_ARGS" ]; then + TCP_EXT_ARGS="meta l4proto tcp tcp dport { $PORTS_ARGS }" + TCP_RULE="meta l4proto tcp tcp dport { $PORTS_ARGS } counter redirect to :$local_port" + fi + else + TCP_EXT_ARGS="meta l4proto tcp" + # default: redirect everything except ssh(22) + TCP_RULE="meta l4proto tcp tcp dport != 22 counter redirect to :$local_port" + fi + # add TCP rule to fw chain if not exists (use -F exact match) + if ! $NFT list chain inet ss_spec ss_spec_wan_fw 2>/dev/null | grep -F -- "$TCP_RULE" >/dev/null 2>&1; then + if ! $NFT add rule inet ss_spec ss_spec_wan_fw $TCP_RULE 2>/dev/null; then + loger 3 "Can't redirect TCP, please check nftables." + return 1 + fi + fi + + return $? +} + +fw_rule_iptables() { + # Create TCP chain in NAT table + $IPT -N SS_SPEC_WAN_FW 2>/dev/null + $IPT -F SS_SPEC_WAN_FW + + for net in \ + 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \ + 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4 + do + $IPT -A SS_SPEC_WAN_FW -d "$net" -j RETURN + done + + $IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS -j REDIRECT --to-ports "$local_port" 2>/dev/null || { + loger 3 "Can't redirect TCP, please check the iptables." + exit 1 + } + + return $? +} + +ac_rule() { + if [ "$USE_NFT" = "1" ]; then + ac_rule_nft + else + ac_rule_iptables + fi + return $? +} + +ac_rule_nft() { + local MATCH_SET="" + + if [ -n "$LAN_AC_IP" ]; then + # Create LAN access control set if needed + if ! $NFT list set inet ss_spec ss_spec_lan_ac >/dev/null 2>&1; then + $NFT add set inet ss_spec ss_spec_lan_ac '{ type ipv4_addr; flags interval; }' 2>/dev/null + else + $NFT flush set inet ss_spec ss_spec_lan_ac 2>/dev/null + fi + + for ip in ${LAN_AC_IP#?}; do + [ -n "$ip" ] && $NFT add element inet ss_spec ss_spec_lan_ac "{ $ip }" 2>/dev/null + done + + case "${LAN_AC_IP%${LAN_AC_IP#?}}" in + w | W) + MATCH_SET="ip saddr @ss_spec_lan_ac" + ;; + b | B) + MATCH_SET="ip saddr != @ss_spec_lan_ac" + ;; + *) + loger 3 "Bad argument \`-a $LAN_AC_IP\`." + return 2 + ;; + esac + fi + + # Create ss_spec_prerouting tcp chain + if ! $NFT list chain inet ss_spec ss_spec_prerouting >/dev/null 2>&1; then + $NFT add chain inet ss_spec ss_spec_prerouting '{ type nat hook prerouting priority 0; policy accept; }' + fi + $NFT flush chain inet ss_spec ss_spec_prerouting 2>/dev/null + + # Exclude special local addresses + if $NFT list chain inet ss_spec ss_spec_prerouting >/dev/null 2>&1; then + for net in 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4; do + $NFT add rule inet ss_spec ss_spec_prerouting ip daddr $net return 2>/dev/null + done + fi + + # Temporarily comment IPV6 for future enablement + #if $NFT list chain inet ss_spec ss_spec_prerouting >/dev/null 2>&1; then + # for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 ::/128 ::ffff:0:0/96; do + # $NFT add rule inet ss_spec ss_spec_prerouting ip6 daddr $net return 2>/dev/null + # done + #fi + + # Build a rule in the prerouting hook chain that jumps to business chain with conditions + if [ -n "$PROXY_PORTS" ]; then + PORTS_ARGS=$(echo "$PROXY_PORTS" | sed 's/-m multiport --dports //') + if [ -n "$PORTS_ARGS" ]; then + TCP_EXT_ARGS="meta l4proto tcp tcp dport { $PORTS_ARGS }" + fi + else + TCP_EXT_ARGS="meta l4proto tcp" + fi + + # Block UDP port 443 when TPROXY not Enable + if [ -z "$TPROXY" ] && [ "$DISABLE_UDP_RULES" != "1" ]; then + # Add UDP 443 block rule + if [ -z "$Interface" ]; then + if [ -n "$MATCH_SET" ]; then + $NFT add rule inet ss_spec ss_spec_prerouting meta l4proto udp $MATCH_SET udp dport 443 drop comment "\"$TAG\"" 2>/dev/null + else + $NFT add rule inet ss_spec ss_spec_prerouting meta l4proto udp udp dport 443 drop comment "\"$TAG\"" 2>/dev/null + fi + else + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null) + if [ -n "$IFNAME" ]; then + if [ -n "$MATCH_SET" ]; then + $NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" meta l4proto udp $MATCH_SET udp dport 443 drop comment "\"$TAG\"" 2>/dev/null + else + $NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" meta l4proto udp udp dport 443 drop comment "\"$TAG\"" 2>/dev/null + fi + fi + done + fi + fi + if [ -z "$Interface" ]; then + # generic prerouting jump already exists (see ipset_nft), but if we have MATCH_SET_CONDITION we add a more specific rule + if [ -n "$MATCH_SET" ]; then + # add a more specific rule at the top of ss_spec_prerouting + $NFT add rule inet ss_spec ss_spec_prerouting $TCP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null + else + $NFT add rule inet ss_spec ss_spec_prerouting $TCP_EXT_ARGS jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null + fi + else + # For each Interface, find its actual ifname and add an iifname-limited prerouting rule + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null) + if [ -n "$IFNAME" ]; then + if [ -n "$MATCH_SET" ]; then + $NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" $TCP_EXT_ARGS $MATCH_SET jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null + else + $NFT add rule inet ss_spec ss_spec_prerouting meta iifname "$IFNAME" $TCP_EXT_ARGS jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null + fi + fi + done + fi + case "$OUTPUT" in + 1) + # Create ss_spec_output tcp chain + if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then + $NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }' + fi + $NFT flush chain inet ss_spec ss_spec_output 2>/dev/null + $NFT add rule inet ss_spec ss_spec_output meta mark 255 return 2>/dev/null + + # Exclude special local addresses + if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then + for net in 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4; do + $NFT add rule inet ss_spec ss_spec_output ip daddr $net return 2>/dev/null + done + fi + + # Temporarily comment IPV6 for future enablement + #if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then + # for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 ::/128 ::ffff:0:0/96; do + # $NFT add rule inet ss_spec ss_spec_output ip6 daddr $net return 2>/dev/null + # done + #fi + + # create output hook chain & route output traffic into router chain + $NFT add rule inet ss_spec ss_spec_output $TCP_EXT_ARGS jump ss_spec_wan_ac comment "\"$TAG\"" 2>/dev/null + ;; + 2) + # Create ss_spec_output tcp chain + if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then + $NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }' + fi + $NFT flush chain inet ss_spec ss_spec_output 2>/dev/null + $NFT add rule inet ss_spec ss_spec_output meta mark 255 return 2>/dev/null + + # Exclude special local addresses + if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then + for net in 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4; do + $NFT add rule inet ss_spec ss_spec_output ip daddr $net return 2>/dev/null + done + fi + + # router mode output chain: create ssr_gen_router set & router chain + $NFT add set inet ss_spec ssr_gen_router '{ type ipv4_addr; flags interval; }' 2>/dev/null + for ip in $(gen_spec_iplist); do + [ -n "$ip" ] && $NFT add element inet ss_spec ssr_gen_router "{ $ip }" 2>/dev/null + done + if ! $NFT list chain inet ss_spec ss_spec_router >/dev/null 2>&1; then + $NFT add chain inet ss_spec ss_spec_router 2>/dev/null + fi + $NFT flush chain inet ss_spec ss_spec_router 2>/dev/null + $NFT add rule inet ss_spec ss_spec_router meta mark 255 return 2>/dev/null + $NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return 2>/dev/null + $NFT add rule inet ss_spec ss_spec_router jump ss_spec_wan_fw 2>/dev/null + $NFT add rule inet ss_spec ss_spec_output $TCP_EXT_ARGS jump ss_spec_router comment "\"$TAG\"" 2>/dev/null + ;; + esac + return 0 +} + +ac_rule_iptables() { + local MATCH_SET="" + if [ -n "$LAN_AC_IP" ]; then + case "${LAN_AC_IP%${LAN_AC_IP#?}}" in + w | W) + MATCH_SET="-m set --match-set ss_spec_lan_ac src" + ;; + b | B) + MATCH_SET="-m set ! --match-set ss_spec_lan_ac src" + ;; + *) + loger 3 "Bad argument \`-a $LAN_AC_IP\`." + return 2 + ;; + esac + fi + ipset -! -R <<-EOF || return 1 + create ss_spec_lan_ac hash:net + $(for ip in ${LAN_AC_IP#?}; do echo "add ss_spec_lan_ac $ip"; done) + EOF + + # Block UDP port 443 when TPROXY not Enable + if [ -z "$TPROXY" ] && [ "$DISABLE_UDP_RULES" != "1" ]; then + # Add UDP 443 block rule + if [ -z "$Interface" ]; then + # Global rules + if [ -n "$MATCH_SET" ]; then + $ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET --dport 443 -j DROP -m comment --comment "$TAG" + else + $ipt -I PREROUTING 1 -p udp $EXT_ARGS --dport 443 -j DROP -m comment --comment "$TAG" + fi + else + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null) + if [ -n "$IFNAME" ]; then + if [ -n "$MATCH_SET" ]; then + $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET --dport 443 -j DROP -m comment --comment "$TAG" + else + $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS --dport 443 -j DROP -m comment --comment "$TAG" + fi + fi + done + fi + fi + if [ -z "$Interface" ]; then + # Global rules + if [ -n "$MATCH_SET" ]; then + $IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + else + $IPT -I PREROUTING 1 -p tcp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + fi + else + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null) + if [ -n "$IFNAME" ]; then + if [ -n "$MATCH_SET" ]; then + $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + else + $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + fi + fi + done + fi + + case "$OUTPUT" in + 1) + $IPT -I OUTPUT 1 -p tcp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + ;; + 2) + ipset -! -R <<-EOF || return 1 + create ssr_gen_router hash:net + $(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /") + EOF + $IPT -N SS_SPEC_ROUTER 2>/dev/null + $IPT -F SS_SPEC_ROUTER 2>/dev/null + $IPT -A SS_SPEC_ROUTER -m mark --mark 255 -j RETURN && \ + $IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \ + $IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW + $IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER + ;; + esac + return $? +} + +tp_rule() { + [ -n "$TPROXY" ] || return 0 + if [ "$USE_NFT" = "1" ]; then + tp_rule_nft + else + tp_rule_iptables + fi + return $? +} + +tp_rule_nft() { + # set up routing table for tproxy + if ! ip rule show | grep -Eq "fwmark ${FWMARK}.*lookup 999"; then + ip rule add fwmark ${FWMARK} table 999 priority 999 2>/dev/null + fi + + if ! ip route show table 999 | grep -Eq "^local.*dev lo"; then + ip route add local 0.0.0.0/0 dev lo table 999 2>/dev/null + fi + + # create mangle table and tproxy chain + if ! $NFT list table ip ss_spec_mangle >/dev/null 2>&1; then + $NFT add table ip ss_spec_mangle 2>/dev/null + fi + + local MATCH_SET="" + + if [ -n "$PROXY_PORTS" ]; then + PORTS_ARGS=$(echo "$PROXY_PORTS" | sed 's/-m multiport --dports //') + if [ -n "$PORTS_ARGS" ]; then + EXT_ARGS="udp dport { $PORTS_ARGS }" + else + EXT_ARGS="" + fi + fi + + if [ -n "$LAN_AC_IP" ]; then + # Create LAN access control set if needed + if ! $NFT list set ip ss_spec_mangle ss_spec_lan_ac >/dev/null 2>&1; then + $NFT add set ip ss_spec_mangle ss_spec_lan_ac '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null + else + $NFT flush set ip ss_spec_mangle ss_spec_lan_ac 2>/dev/null + fi + + for ip in ${LAN_AC_IP#?}; do + [ -n "$ip" ] && $NFT add element ip ss_spec_mangle ss_spec_lan_ac "{ $ip }" 2>/dev/null + done + + case "${LAN_AC_IP%${LAN_AC_IP#?}}" in + w | W) + MATCH_SET="ip saddr @ss_spec_lan_ac" + ;; + b | B) + MATCH_SET="ip saddr != @ss_spec_lan_ac" + ;; + *) + loger 3 "Bad argument \`-a $LAN_AC_IP\`." + return 2 + ;; + esac + fi + + # Create necessary collections + for setname in china gmlan fplan bplan whitelist; do + if ! $NFT list set ip ss_spec_mangle $setname >/dev/null 2>&1; then + $NFT add set ip ss_spec_mangle $setname '{ type ipv4_addr; flags interval; auto-merge; }' + else + $NFT flush set ip ss_spec_mangle $setname 2>/dev/null + fi + done + + # Bulk import china ip list safely (avoid huge single element limitation) + if [ -f "$IGNORE_LIST" ]; then + SKIP_INET=2 /usr/share/shadowsocksr/chinaipset.sh "$IGNORE_LIST" + fi + + # Bulk import xhttp ip list into nft whitelist (server + shunt) + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + $NFT add element ip ss_spec_mangle whitelist "{ $(tr '\n' ',' < "${xhttp_ip}" | sed 's/,$//') }" 2>/dev/null + fi + + # use priority mangle for compatibility with other rules + if ! $NFT list chain ip ss_spec_mangle ss_spec_tproxy >/dev/null 2>&1; then + $NFT add chain ip ss_spec_mangle ss_spec_tproxy 2>/dev/null + else + $NFT flush chain ip ss_spec_mangle ss_spec_tproxy 2>/dev/null + fi + + if $NFT list chain ip ss_spec_mangle ss_spec_tproxy >/dev/null 2>&1; then + for net in 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4; do + $NFT add rule ip ss_spec_mangle ss_spec_tproxy ip daddr $net return 2>/dev/null + done + fi + + # Temporarily comment IPV6 for future enablement + #if $NFT list chain ip ss_spec_mangle ss_spec_tproxy >/dev/null 2>&1; then + # for net in ::1/128 fe80::/10 fc00::/7 ff00::/8 fe80::/10 ::/128 ::ffff:0:0/96; do + # $NFT add rule ip ss_spec_mangle ss_spec_tproxy ip6 daddr $net return 2>/dev/null + # done + #fi + + # basic return rules in tproxy chain + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp dport 53 return 2>/dev/null + + # avoid redirecting to udp server address + if [ -n "$server" ]; then + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp dport != 53 ip daddr "$server" return 2>/dev/null + fi + + # if server != SERVER add SERVER to whitelist set (so tproxy won't touch it) + if [ -n "$server" ]; then + $NFT add rule ip ss_spec_mangle ss_spec_tproxy ip daddr "$server" return 2>/dev/null + fi + if [ -n "$SERVER" ] && [ "$server" != "$SERVER" ]; then + $NFT add element ip ss_spec_mangle whitelist "{ $SERVER }" 2>/dev/null + fi + + # access control and tproxy rules + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @bplan return 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip saddr @fplan counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null + + # Handle different run modes for nftables + case "$RUNMODE" in + router) + if ! $NFT list set ip ss_spec_mangle ss_spec_wan_ac >/dev/null 2>&1; then + $NFT add set ip ss_spec_mangle ss_spec_wan_ac '{ type ipv4_addr; flags interval; auto-merge; }' + else + $NFT flush set ip ss_spec_mangle ss_spec_wan_ac 2>/dev/null + fi + # Add special IP ranges to WAN AC set + for ip in $(gen_spec_iplist); do + [ -n "$ip" ] && $NFT add element ip ss_spec_mangle ss_spec_wan_ac "{ $ip }" 2>/dev/null + done + + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip daddr @ss_spec_wan_ac return 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip daddr @china return 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 80 counter drop comment "\"$TAG\"" 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 443 counter drop comment "\"$TAG\"" 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @gmlan ip daddr != @china counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip daddr != @ss_spec_wan_ac counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null + ;; + gfw) + if ! $NFT list set ip ss_spec_mangle gfwlist >/dev/null 2>&1; then + $NFT add set ip ss_spec_mangle gfwlist '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null + fi + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip daddr @china return 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 80 counter drop comment "\"$TAG\"" 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp udp dport 443 counter drop comment "\"$TAG\"" 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip daddr @gfwlist counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @gmlan ip daddr != @china counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null + ;; + all) + $NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null + ;; + esac + + # finally, ensure prerouting hook entry to jump to tproxy chain + if ! $NFT list chain ip ss_spec_mangle prerouting >/dev/null 2>&1; then + $NFT add chain ip ss_spec_mangle prerouting '{ type filter hook prerouting priority mangle; policy accept; }' + fi + + # add prerouting jump (idempotent) + if [ -z "$Interface" ]; then + # Global rules + if [ -n "$MATCH_SET" ]; then + $NFT add rule ip ss_spec_mangle prerouting meta l4proto udp $EXT_ARGS $MATCH_SET jump ss_spec_tproxy comment "\"$TAG\"" 2>/dev/null + else + $NFT add rule ip ss_spec_mangle prerouting meta l4proto udp $EXT_ARGS jump ss_spec_tproxy comment "\"$TAG\"" 2>/dev/null + fi + else + # Specific interface + for name in $Interface; do + IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null) + if [ -n "$IFNAME" ]; then + if [ -n "$MATCH_SET" ]; then + $NFT add rule ip ss_spec_mangle prerouting meta iifname "$IFNAME" meta l4proto udp $EXT_ARGS $MATCH_SET jump ss_spec_tproxy comment "\"$TAG\"" 2>/dev/null + else + $NFT add rule ip ss_spec_mangle prerouting meta iifname "$IFNAME" meta l4proto udp $EXT_ARGS jump ss_spec_tproxy comment "\"$TAG\"" 2>/dev/null + fi + fi + done + fi + + return $? +} + +tp_rule_iptables() { + # set up routing table for tproxy + if ! ip rule show | grep -Eq "fwmark ${FWMARK}.*lookup 999"; then + ip rule add fwmark ${FWMARK} table 999 priority 999 2>/dev/null + fi + + if ! ip route show table 999 | grep -Eq "^local.*dev lo"; then + ip route add local 0.0.0.0/0 dev lo table 999 2>/dev/null + fi + $ipt -N SS_SPEC_TPROXY 2>/dev/null + $ipt -F SS_SPEC_TPROXY + + $ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN + + local MATCH_SET="" + if [ -n "$LAN_AC_IP" ]; then + case "${LAN_AC_IP%${LAN_AC_IP#?}}" in + w | W) + MATCH_SET="-m set --match-set ss_spec_lan_ac src" + ;; + b | B) + MATCH_SET="-m set ! --match-set ss_spec_lan_ac src" + ;; + *) + loger 3 "Bad argument \`-a $LAN_AC_IP\`." + return 2 + ;; + esac + fi + ipset -! -R <<-EOF || return 1 + create ss_spec_lan_ac hash:net + $(for ip in ${LAN_AC_IP#?}; do echo "add ss_spec_lan_ac $ip"; done) + EOF + + for net in \ + 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \ + 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4 + do + $ipt -A SS_SPEC_TPROXY -p udp -d "$net" -j RETURN + done + [ -n "$SERVER" ] && $ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d "$SERVER" -j RETURN + [ -n "$SERVER" ] && [ "$server" != "$SERVER" ] && ipset -! add whitelist "$SERVER" + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + while IFS= read -r ip; do + [ -n "$ip" ] && ipset add whitelist "$ip" -exist + done < "$xhttp_ip" + fi + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK} + case "$RUNMODE" in + router) + ipset -! -R <<-EOF || return 1 + create ss_spec_wan_ac hash:net + $(gen_spec_iplist | sed -e "s/^/add ss_spec_wan_ac /") + EOF + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set ss_spec_wan_ac dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK} + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK} + ;; + gfw) + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set gfwlist dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK} + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK} + ;; + all) + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK} + ;; + esac + if [ -z "$Interface" ]; then + # Global rules + if [ -n "$MATCH_SET" ]; then + $ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY + else + $ipt -I PREROUTING 1 -p udp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_TPROXY + fi + else + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network."$name".ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network."$name".device 2>/dev/null) + if [ -n "$IFNAME" ]; then + if [ -n "$MATCH_SET" ]; then + $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY + else + $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_TPROXY + fi + fi + done + fi + return $? +} + +get_wan_ip() { + cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}" + $server + $SERVER + $WAN_BP_IP + EOF +} + +gen_spec_iplist() { + cat <<-EOF + 0.0.0.0/8 + 10.0.0.0/8 + 100.64.0.0/10 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.0.0.0/24 + 192.0.2.0/24 + 192.88.99.0/24 + 192.168.0.0/16 + 198.18.0.0/15 + 198.51.100.0/24 + 203.0.113.0/24 + 224.0.0.0/4 + 240.0.0.0/4 + 255.255.255.255 + $(get_wan_ip) + EOF +} + +gen_include() { + [ -n "$FWI" ] || return 0 + if [ "$USE_NFT" = "1" ]; then + gen_include_nft + else + gen_include_iptables + fi + return $? +} + +# Modified gen_include_nft to call persistence function +gen_include_nft() { + # Generate nftables include file for firewall4 + [ -n "$FWI" ] && echo '#!/bin/sh' >"$FWI" + cat <<-EOF >>"$FWI" + # Clear existing ss_spec tables + nft delete table inet ss_spec 2>/dev/null + nft delete table ip ss_spec 2>/dev/null + nft delete table ip ss_spec_mangle 2>/dev/null + + # Restore shadowsocks nftables rules from persistent file + if [ -f "/usr/share/nftables.d/ruleset-post/99-shadowsocksr.nft" ]; then + nft -f /usr/share/nftables.d/ruleset-post/99-shadowsocksr.nft + else + # Fallback: restore from current ruleset (filtered) + nft list ruleset | awk '/^table (inet|ip) ss_spec/{flag=1} /^table / && !/^table (inet|ip) ss_spec/{flag=0} flag' | nft -f - + fi + EOF + chmod +x "$FWI" +} + +gen_include_iptables() { + extract_rules() { + echo "*$1" + iptables-save -t $1 | grep SS_SPEC_ | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + echo 'COMMIT' + } + cat <<-EOF >>$FWI + iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c + iptables-restore -n <<-EOT + $(extract_rules nat) + $(extract_rules mangle) + EOT + EOF +} + +# Check nftables rules status +check_nftables_status() { + if [ "$USE_NFT" != "1" ]; then + echo "NFTables not in use" + return 0 + fi + + # Check if ss_spec tables exist + if ! $NFT list table inet ss_spec >/dev/null 2>&1 && \ + ! $NFT list table ip ss_spec_mangle >/dev/null 2>&1; then + echo "ss_spec tables missing in nftables" + return 1 + fi + + # Check if basic rules exist + if ! $NFT list table inet ss_spec 2>/dev/null | grep -q "chain.*ss_spec_wan_ac" || \ + ! $NFT list table inet ss_spec 2>/dev/null | grep -q "jump.*ss_spec_wan_fw"; then + echo "Basic SSR rules missing" + return 1 + fi + + echo "NFTables rules status: OK" + return 0 +} + +# Compare current rules with persistence rules +compare_rules() { + if [ "$USE_NFT" != "1" ]; then + return 1 # NFTables not used, need update + fi + + # If no persistence file, update persistence file + if [ ! -f "$NFTABLES_RULES_FILE" ]; then + loger 6 "No persistence file found, update needed" + return 1 # Need to update persistence file + fi + + # Check if ss_spec tables exist + if ! $NFT list table inet ss_spec >/dev/null 2>&1 && \ + ! $NFT list table ip ss_spec_mangle >/dev/null 2>&1; then + loger 6 "ss_spec tables missing, update needed" + return 1 # Need to update ss_spec table + fi + + # Generate temporary file for current rules + local rules_file=$(mktemp) + loger 7 "DEBUG: Temporary file path: $rules_file" + + # Export current rules to temporary file + $NFT list ruleset | awk ' + /^table (inet ss_spec|ip ss_spec_mangle)/ {flag=1} + /^table / && !/^table (inet ss_spec|ip ss_spec_mangle)/ {flag=0} + flag + ' > "$rules_file" 2>/dev/null + + # Check if current rules were exported successfully + if [ ! -s "$rules_file" ] || ! grep -q "table" "$rules_file" 2>/dev/null; then + loger 4 "Failed to export current rules" + rm -f "$rules_file" + return 1 # Export failed, need update + fi + + # Compare current rules with rules in persistence file + if ! cmp -s "$rules_file" "$NFTABLES_RULES_FILE"; then + loger 6 "Rules differ, update needed" + rm -f "$rules_file" + return 1 # Need update + fi + + rm -f "$rules_file" + loger 6 "Rules unchanged, no update needed" + return 0 # No update needed +} + +# Auto-update persistence rules +persist_nftables_rules() { + if [ "$USE_NFT" != "1" ]; then + return 0 + fi + + # Force update: skip comparison check and delete old file + if [ "$FORCE_UPDATE" = "1" ]; then + loger 6 "Force update requested, removing old persistence file" + rm -f "$NFTABLES_RULES_FILE" 2>/dev/null + # Otherwise, if persistence file exists, compare rules + elif [ -f "$NFTABLES_RULES_FILE" ]; then + if compare_rules; then + loger 6 "Rules unchanged, skipping persistence update" + return 0 + else + loger 6 "Rules changed, updating persistence" + fi + fi + + # Ensure directory exists + mkdir -p "$NFTABLES_RULES_DIR" 2>/dev/null + + # Generate nftables rule file + cat <<-'EOF' > "$NFTABLES_RULES_FILE" + #!/usr/sbin/nft -f + + # ShadowsocksR nftables rules + # Generated by ssr-rules script + EOF + + echo "# Auto-updated: $(date)" >> "$NFTABLES_RULES_FILE" + echo "# Runmode: ${RUNMODE:-router}" >> "$NFTABLES_RULES_FILE" + echo "# Server: $server, Port: $local_port" >> "$NFTABLES_RULES_FILE" + echo "# WAN_BP_IP: $WAN_BP_IP" >> "$NFTABLES_RULES_FILE" + echo "# LAN_AC_IP: $LAN_AC_IP" >> "$NFTABLES_RULES_FILE" + echo "# LAN_BP_IP: $LAN_BP_IP" >> "$NFTABLES_RULES_FILE" + echo "# WAN_FW_IP: $WAN_FW_IP" >> "$NFTABLES_RULES_FILE" + echo "# LAN_FP_IP: $LAN_FP_IP" >> "$NFTABLES_RULES_FILE" + echo "# LAN_GM_IP: $LAN_GM_IP" >> "$NFTABLES_RULES_FILE" + echo "" >> "$NFTABLES_RULES_FILE" + + local HAS_RULES=0 + + # Export each table separately + if $NFT list table inet ss_spec >/dev/null 2>&1; then + loger 6 "Exporting table inet ss_spec" + { + echo "" + echo "# inet ss_spec table for main rules" + $NFT list table inet ss_spec 2>/dev/null + } >> "$NFTABLES_RULES_FILE" + HAS_RULES=1 + fi + + if $NFT list table ip ss_spec_mangle >/dev/null 2>&1; then + loger 6 "Exporting table ip ss_spec_mangle" + { + echo "" + echo "# ip ss_spec_mangle table for TPROXY rules" + $NFT list table ip ss_spec_mangle 2>/dev/null + } >> "$NFTABLES_RULES_FILE" + HAS_RULES=1 + fi + + # Check if rules were exported successfully + if [ $HAS_RULES -eq 0 ] || [ ! -s "$NFTABLES_RULES_FILE" ] || ! grep -q "table" "$NFTABLES_RULES_FILE" 2>/dev/null; then + loger 4 "No ss_spec nftables rules found to persist" + rm -f "$NFTABLES_RULES_FILE" 2>/dev/null + return 1 + fi + + # Set file permissions + chmod 644 "$NFTABLES_RULES_FILE" 2>/dev/null + + # Log success information + local TABLES=$(grep "^table" "$NFTABLES_RULES_FILE" | awk '{print $2 " " $3}' | tr '\n' ',' | sed 's/,$//') + loger 5 "NFTables rules persisted to $NFTABLES_RULES_FILE (Tables: $TABLES)" + + return 0 +} + +# Auto-update daemon +start_auto_update_daemon() { + if [ "$USE_NFT" != "1" ] || [ "$AUTO_UPDATE_INTERVAL" = "0" ]; then + return 0 + fi + + loger 6 "Starting nftables rules auto-update daemon" + + # Stop already running daemon + stop_auto_update_daemon + + # Start daemon directly in background + ( + logger -t ssr-rules[daemon] "Auto-update daemon started - PID: $$" + echo $$ > "/var/run/ssr-rules-daemon.pid" + + while true; do + sleep "$AUTO_UPDATE_INTERVAL" + if [ -x "/usr/bin/ssr-rules" ]; then + # -C returns 0 if rules are OK, non-zero if need update + if /usr/bin/ssr-rules -C >/dev/null 2>&1; then + logger -t ssr-rules[daemon] "Rules status OK, no update needed" + else + logger -t ssr-rules[daemon] "Rules changed or missing, updating persistence" + if /usr/bin/ssr-rules -P >/dev/null 2>&1; then + logger -t ssr-rules[daemon] "Persistence rules updated successfully" + else + logger -t ssr-rules[daemon] "Failed to update persistence" + fi + fi + else + logger -t ssr-rules[daemon] "Script not found, exiting daemon" + exit 1 + fi + done + ) & + + local DAEMON_PID=$! + sleep 2 + + if kill -0 "$DAEMON_PID" 2>/dev/null; then + loger 6 "Auto-update daemon started with PID: $DAEMON_PID" + return 0 + else + loger 3 "Auto-update daemon failed to start" + return 1 + fi +} + +# Stop auto-update daemon function +stop_auto_update_daemon() { + local PID_FILE="/var/run/ssr-rules-daemon.pid" + + if [ -f "$PID_FILE" ]; then + local DAEMON_PID=$(cat "$PID_FILE" 2>/dev/null) + if [ -n "$DAEMON_PID" ] && kill -0 "$DAEMON_PID" 2>/dev/null; then + kill "$DAEMON_PID" 2>/dev/null + loger 6 "Stopped auto-update daemon (PID: $DAEMON_PID)" + fi + rm -f "$PID_FILE" 2>/dev/null + fi + + loger 6 "Auto-update daemon stopped" +} + +# Force update persistence rules function +force_update_persistence() { + if [ "$USE_NFT" != "1" ]; then + echo "NFTables not in use" + return 0 + fi + + # Remove existing rule file to ensure recreation + rm -f "$NFTABLES_RULES_FILE" 2>/dev/null + + # Call persistence function + if persist_nftables_rules; then + loger 5 "Persistence update completed successfully" + return 0 + else + loger 3 "Persistence update failed" + return 1 + fi +} + +# Restore rules from persistence file +restore_from_persistence() { + if [ "$USE_NFT" != "1" ]; then + loger 3 "NFTables not in use, cannot restore rules" + return 1 + fi + + if [ ! -f "$NFTABLES_RULES_FILE" ]; then + loger 4 "Persistence file not found: $NFTABLES_RULES_FILE" + return 1 + fi + + loger 6 "Restoring rules from persistence file" + + # Cleanup existing rules + flush_r + + # Restore rules from file + if $NFT -f "$NFTABLES_RULES_FILE" 2>/dev/null; then + loger 5 "Rules restored successfully from persistence file" + return 0 + else + loger 4 "Failed to restore rules from persistence file" + return 1 + fi +} + +while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUyfgrzAKPCRXh" arg; do + case "$arg" in + m) + Interface=$OPTARG + ;; + s) + server=$OPTARG + ;; + l) + local_port=$OPTARG + ;; + S) + SERVER=$OPTARG + ;; + L) + LOCAL_PORT=$OPTARG + ;; + i) + IGNORE_LIST=$OPTARG + ;; + e) + EXT_ARGS=$OPTARG + ;; + a) + LAN_AC_IP=$OPTARG + ;; + B) + LAN_BP_IP=$OPTARG + ;; + b) + WAN_BP_IP=$(for ip in $OPTARG; do echo "$ip"; done) + ;; + w) + WAN_FW_IP=$OPTARG + ;; + p) + LAN_FP_IP=$OPTARG + ;; + G) + LAN_GM_IP=$OPTARG + ;; + D) + PROXY_PORTS=$OPTARG + ;; + F) + SHUNT_PORT=$OPTARG + ;; + N) + SHUNT_IP=$OPTARG + ;; + M) + SHUNT_PROXY=$OPTARG + ;; + I) + SHUNT_LIST=$OPTARG + ;; + o) + OUTPUT=1 + ;; + O) + OUTPUT=2 + ;; + u) + TPROXY=1 + ;; + U) + TPROXY=2 + ;; + y) + DISABLE_UDP_RULES=1 + ;; + g) + RUNMODE=gfw + ;; + r) + RUNMODE=router + ;; + z) + RUNMODE=all + ;; + # New persistence management options + A) + ENABLE_AUTO_UPDATE=1 + ;; + K) + STOP_AUTO_UPDATE=1 + ;; + P) + FORCE_UPDATE=1 + ;; + C) + CHECK_STATUS=1 + ;; + R) + RESTORE_RULES=1 + ;; + X) + CLEANUP_PERSISTENCE=1 + ;; + f) + FLUSH_RULES=1 + ;; + h) + usage 0 + ;; + esac +done + +# First process options that need immediate exit +if [ "$CHECK_STATUS" = "1" ]; then + check_nftables_status + exit $? +fi + +if [ "$STOP_AUTO_UPDATE" = "1" ]; then + stop_auto_update_daemon + exit 0 +fi + +# Only -X option, cleanup and exit +if [ "$CLEANUP_PERSISTENCE" = "1" ] && [ "$FLUSH_RULES" != "1" ] && [ -z "$server" ] && [ -z "$local_port" ] && \ + [ "$FORCE_UPDATE" != "1" ] && [ "$RESTORE_RULES" != "1" ] && [ "$ENABLE_AUTO_UPDATE" != "1" ]; then + cleanup_persistence_files + exit $? +fi + +# Check if there are persistence management options only +PERSISTENCE_ONLY=0 +if [ -z "$server" ] && [ -z "$local_port" ] && [ "$FLUSH_RULES" != "1" ]; then + if [ "$FORCE_UPDATE" = "1" ] || [ "$RESTORE_RULES" = "1" ] || [ "$ENABLE_AUTO_UPDATE" = "1" ] || [ "$CLEANUP_PERSISTENCE" = "1" ]; then + PERSISTENCE_ONLY=1 + else + usage 2 + fi +fi + +# Handle persistence management options +if [ "$PERSISTENCE_ONLY" = "1" ]; then + if [ "$FORCE_UPDATE" = "1" ]; then + force_update_persistence + exit $? + fi + + if [ "$RESTORE_RULES" = "1" ]; then + restore_from_persistence + exit $? + fi + + if [ "$ENABLE_AUTO_UPDATE" = "1" ]; then + start_auto_update_daemon + exit $? + fi +fi + +# Force flush rules +if [ "$FLUSH_RULES" = "1" ]; then + flush_r + # If only -f option, then exit + if [ -z "$server" ] && [ -z "$local_port" ] && [ "$FORCE_UPDATE" != "1" ] && \ + [ "$RESTORE_RULES" != "1" ] && [ "$ENABLE_AUTO_UPDATE" != "1" ] && \ + [ "$CLEANUP_PERSISTENCE" != "1" ]; then + exit 0 + fi +fi + +# Restore rules from persistence file (before rule application) +if [ "$RESTORE_RULES" = "1" ]; then + restore_from_persistence + if [ $? -ne 0 ]; then + loger 3 "Failed to restore from persistence, continuing with rule application" + fi +fi + +# Run mode change +runmode_change() { + local mode_file="/tmp/.ssr_run_mode" + local new_mode="" + local old_mode="" + + # Get mode from parameters + if [ -n "$1" ]; then + new_mode="$1" + fi + + # Read previous run mode from file + if [ -f "$mode_file" ]; then + old_mode=$(cat "$mode_file" 2>/dev/null) + fi + + # Compare if mode changed + if [ "$old_mode" = "$new_mode" ] && [ -n "$old_mode" ]; then + # Mode unchanged + echo "$new_mode" > "$mode_file" # Update file timestamp + loger 6 "Runmode unchanged: $new_mode" + return 1 # Return 1 means unchanged + else + # Mode changed or first run + echo "$new_mode" > "$mode_file" + if [ -n "$old_mode" ]; then + loger 6 "Runmode changed from '$old_mode' to '$new_mode'" + else + loger 6 "Runmode set to '$new_mode'" + fi + return 0 # Return 0 means changed + fi +} + +# Main process +if [ -n "$local_port" ]; then + if ! echo "$local_port" | grep -qE '^[0-9]+$'; then + loger 3 "Invalid local port: $local_port" + exit 1 + fi + + case "$TPROXY" in + 1) + SERVER=$server + LOCAL_PORT=$local_port + ;; + 2) + : ${LOCAL_PORT:?"You must assign a port for the udp relay server."} + ;; + esac + + if [ "$USE_NFT" = "1" ]; then + # NFTables + # Save previous TPROXY state file + TPROXY_STATE_FILE="/tmp/.last_tproxy" + if [ -f "$TPROXY_STATE_FILE" ]; then + LAST_TPROXY=$(cat "$TPROXY_STATE_FILE") + else + LAST_TPROXY="" + fi + + # Save previous PROXY_PORTS state + PROXY_PORTS_STATE_FILE="/tmp/.last_proxy_ports" + if [ -f "$PROXY_PORTS_STATE_FILE" ]; then + LAST_PROXY_PORTS=$(cat "$PROXY_PORTS_STATE_FILE") + else + LAST_PROXY_PORTS="" + fi + + # Save previous WAN_BP_IP state + WAN_BP_IP_STATE_FILE="/tmp/.last_wan_bp_ip" + if [ -f "$WAN_BP_IP_STATE_FILE" ]; then + LAST_WAN_BP_IP=$(cat "$WAN_BP_IP_STATE_FILE") + else + LAST_WAN_BP_IP="" + fi + + # Save previous LAN_AC_IP state + LAN_AC_IP_STATE_FILE="/tmp/.last_lan_ac_ip" + if [ -f "$LAN_AC_IP_STATE_FILE" ]; then + LAST_LAN_AC_IP=$(cat "$LAN_AC_IP_STATE_FILE") + else + LAST_LAN_AC_IP="" + fi + + # Save previous LAN_BP_IP state + LAN_BP_IP_STATE_FILE="/tmp/.last_lan_bp_ip" + if [ -f "$LAN_BP_IP_STATE_FILE" ]; then + LAST_LAN_BP_IP=$(cat "$LAN_BP_IP_STATE_FILE") + else + LAST_LAN_BP_IP="" + fi + + # Save previous WAN_FW_IP state + WAN_FW_IP_STATE_FILE="/tmp/.last_wan_fw_ip" + if [ -f "$WAN_FW_IP_STATE_FILE" ]; then + LAST_WAN_FW_IP=$(cat "$WAN_FW_IP_STATE_FILE") + else + LAST_WAN_FW_IP="" + fi + + # Save previous LAN_FP_IP state + LAN_FP_IP_STATE_FILE="/tmp/.last_lan_fp_ip" + if [ -f "$LAN_FP_IP_STATE_FILE" ]; then + LAST_LAN_FP_IP=$(cat "$LAN_FP_IP_STATE_FILE") + else + LAST_LAN_FP_IP="" + fi + + # Save previous LAN_GM_IP state + LAN_GM_IP_STATE_FILE="/tmp/.last_lan_gm_ip" + if [ -f "$LAN_GM_IP_STATE_FILE" ]; then + LAST_LAN_GM_IP=$(cat "$LAN_GM_IP_STATE_FILE") + else + LAST_LAN_GM_IP="" + fi + + # Check for changes in the existence and content of the server XHTTP address file + XHTTP_FILE_STATE_FILE="/tmp/.last_xhttp_file" + XHTTP_FILE_HASH_FILE="/tmp/.last_xhttp_hash" + + # Get the current server XHTTP file status + XHTTP_FILE_EXISTS=0 + XHTTP_FILE_HASH="" + if [ -f "/etc/ssrplus/xhttp_address.txt" ]; then + XHTTP_FILE_EXISTS=1 + XHTTP_FILE_HASH=$(md5sum /etc/ssrplus/xhttp_address.txt 2>/dev/null | awk '{print $1}') + fi + + # Read the previous server XHTTP file status and hash + if [ -f "$XHTTP_FILE_STATE_FILE" ]; then + LAST_XHTTP_FILE_EXISTS=$(cat "$XHTTP_FILE_STATE_FILE") + else + LAST_XHTTP_FILE_EXISTS="" + fi + + if [ -f "$XHTTP_FILE_HASH_FILE" ]; then + LAST_XHTTP_FILE_HASH=$(cat "$XHTTP_FILE_HASH_FILE") + else + LAST_XHTTP_FILE_HASH="" + fi + + # STEP 1: Check if TPROXY has value (1 or 2) + if [ "$TPROXY" = "1" ] || [ "$TPROXY" = "2" ]; then + TPROXY_HAS_VALUE=1 + else + TPROXY_HAS_VALUE=0 + fi + + if [ "$LAST_TPROXY" = "1" ] || [ "$LAST_TPROXY" = "2" ]; then + LAST_HAS_VALUE=1 + else + LAST_HAS_VALUE=0 + fi + + # STEP 2: Check if PROXY_PORTS has value (non-empty string) + if [ -n "${PROXY_PORTS// }" ]; then + PROXY_HAS_VALUE=1 + else + PROXY_HAS_VALUE=0 + fi + + if [ -n "${LAST_PROXY_PORTS// }" ]; then + LAST_PROXY_HAS_VALUE=1 + else + LAST_PROXY_HAS_VALUE=0 + fi + + # STEP 2.5: Check if any IP list has changed + ANY_IP_LIST_CHANGED=0 + + # Check WAN_BP_IP + check_ip_list_changed "$WAN_BP_IP" "$LAST_WAN_BP_IP" "WAN_BP_IP" + if [ $? -eq 1 ]; then + ANY_IP_LIST_CHANGED=1 + fi + + # Check LAN_AC_IP + check_ip_list_changed "$LAN_AC_IP" "$LAST_LAN_AC_IP" "LAN_AC_IP" + if [ $? -eq 1 ]; then + ANY_IP_LIST_CHANGED=1 + fi + + # Check LAN_BP_IP + check_ip_list_changed "$LAN_BP_IP" "$LAST_LAN_BP_IP" "LAN_BP_IP" + if [ $? -eq 1 ]; then + ANY_IP_LIST_CHANGED=1 + fi + + # Check WAN_FW_IP + check_ip_list_changed "$WAN_FW_IP" "$LAST_WAN_FW_IP" "WAN_FW_IP" + if [ $? -eq 1 ]; then + ANY_IP_LIST_CHANGED=1 + fi + + # Check LAN_FP_IP + check_ip_list_changed "$LAN_FP_IP" "$LAST_LAN_FP_IP" "LAN_FP_IP" + if [ $? -eq 1 ]; then + ANY_IP_LIST_CHANGED=1 + fi + + # Check LAN_GM_IP + check_ip_list_changed "$LAN_GM_IP" "$LAST_LAN_GM_IP" "LAN_GM_IP" + if [ $? -eq 1 ]; then + ANY_IP_LIST_CHANGED=1 + fi + + # Check for changes in the existence of the server XHTTP address file. + if [ "$XHTTP_FILE_EXISTS" != "$LAST_XHTTP_FILE_EXISTS" ]; then + loger 6 "xhttp address file existence changed: '$LAST_XHTTP_FILE_EXISTS' -> '$XHTTP_FILE_EXISTS'" + ANY_IP_LIST_CHANGED=1 + fi + + # Check for XHTTP file content changes (compare hashes only when the file exists in both checks) + if [ "$XHTTP_FILE_EXISTS" = "1" ] && [ "$LAST_XHTTP_FILE_EXISTS" = "1" ]; then + if [ "$XHTTP_FILE_HASH" != "$LAST_XHTTP_FILE_HASH" ]; then + loger 6 "xhttp address file content changed (hash: '$LAST_XHTTP_FILE_HASH' -> '$XHTTP_FILE_HASH')" + ANY_IP_LIST_CHANGED=1 + else + loger 6 "xhttp address file content unchanged" + fi + elif [ "$XHTTP_FILE_EXISTS" = "0" ] && [ "$LAST_XHTTP_FILE_EXISTS" = "1" ]; then + loger 6 "xhttp address file deleted" + ANY_IP_LIST_CHANGED=1 + elif [ "$XHTTP_FILE_EXISTS" = "1" ] && [ "$LAST_XHTTP_FILE_EXISTS" = "0" ]; then + loger 6 "xhttp address file created" + ANY_IP_LIST_CHANGED=1 + fi + + # STEP 3: Determine if forced rebuild is needed + FORCE_RECREATE=0 + PERSISTENCE_EXISTS=0 + + # Trigger conditions: + # 1. TPROXY changes from empty ↔ has value + # 2. PROXY_PORTS changes from empty ↔ has value + # 3. Any IP list has changed + if [ "$TPROXY_HAS_VALUE" != "$LAST_HAS_VALUE" ] || \ + [ "$PROXY_HAS_VALUE" != "$LAST_PROXY_HAS_VALUE" ] || \ + [ "$ANY_IP_LIST_CHANGED" = "1" ]; then + FORCE_RECREATE=1 + loger 6 "TPROXY, PROXY_PORTS or any IP list changed → force rebuild rules" + rm -f "$NFTABLES_RULES_FILE" 2>/dev/null + else + # No FORCE_RECREATE triggered → check persistence file + if [ -f "$NFTABLES_RULES_FILE" ] && [ -s "$NFTABLES_RULES_FILE" ]; then + PERSISTENCE_EXISTS=1 + loger 6 "Persistence file exists: $NFTABLES_RULES_FILE" + else + PERSISTENCE_EXISTS=0 + loger 6 "Persistence file does not exist or empty" + fi + fi + + # STEP 4: Save current state + echo "$TPROXY" > "$TPROXY_STATE_FILE" + echo "$PROXY_PORTS" > "$PROXY_PORTS_STATE_FILE" + echo "$(normalize_ip_list "$WAN_BP_IP")" > "$WAN_BP_IP_STATE_FILE" + echo "$(normalize_ip_list "$LAN_AC_IP")" > "$LAN_AC_IP_STATE_FILE" + echo "$(normalize_ip_list "$LAN_BP_IP")" > "$LAN_BP_IP_STATE_FILE" + echo "$(normalize_ip_list "$WAN_FW_IP")" > "$WAN_FW_IP_STATE_FILE" + echo "$(normalize_ip_list "$LAN_FP_IP")" > "$LAN_FP_IP_STATE_FILE" + echo "$(normalize_ip_list "$LAN_GM_IP")" > "$LAN_GM_IP_STATE_FILE" + echo "$XHTTP_FILE_EXISTS" > "$XHTTP_FILE_STATE_FILE" + echo "$XHTTP_FILE_HASH" > "$XHTTP_FILE_HASH_FILE" + + # STEP 5: Check if run mode changed + if runmode_change "$RUNMODE"; then + MODE_CHANGED=1 + loger 6 "Runmode changed: MODE_CHANGED=1" + else + MODE_CHANGED=0 + loger 6 "Runmode unchanged: MODE_CHANGED=0" + fi + + # STEP 6: Mode changed and persistence exists → delete once + if [ "$MODE_CHANGED" = "1" ] && [ "$PERSISTENCE_EXISTS" = "1" ]; then + loger 6 "Mode changed → removing persistence file" + rm -f "$NFTABLES_RULES_FILE" + PERSISTENCE_EXISTS=0 + fi + + # STEP 7: FORCE_RECREATE priority → must rebuild rules + if [ "$FORCE_RECREATE" = "1" ]; then + loger 5 "Forced regeneration of NFTables rules" + if flush_r && ipset_r && fw_rule && ac_rule && tp_rule && gen_include; then + loger 5 "NFT rules applied successfully (forced rebuild)" + persist_nftables_rules + [ "$ENABLE_AUTO_UPDATE" = "1" ] && start_auto_update_daemon + exit 0 + else + loger 3 "NFT forced rebuild failed!" + exit 1 + fi + fi + + # STEP 8: Persistence exists → try restore + if [ "$PERSISTENCE_EXISTS" = "1" ]; then + # Restore rules + if restore_from_persistence; then + loger 5 "NFT rules restored from persistence" + gen_include + [ "$ENABLE_AUTO_UPDATE" = "1" ] && start_auto_update_daemon + exit 0 + else + loger 3 "Restore failed → fallback to full setup" + PERSISTENCE_EXISTS=0 + fi + fi + + # STEP 9: Persistence doesn't exist or restore failed → generate new rules + if flush_r && ipset_r && fw_rule && ac_rule && tp_rule && gen_include; then + loger 5 "NFTables rules applied successfully" + persist_nftables_rules + [ "$ENABLE_AUTO_UPDATE" = "1" ] && start_auto_update_daemon + exit 0 + else + loger 3 "NFTables setup failed!" + exit 1 + fi + else + # iptables + if flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include; then + loger 5 "iptables rules applied successfully" + exit 0 + else + loger 3 "iptables setup failed!" + exit 1 + fi + fi +fi diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-switch b/luci-app-ssr-plus/root/usr/bin/ssr-switch new file mode 100755 index 00000000..3aab3190 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/bin/ssr-switch @@ -0,0 +1,282 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +ORIG_ARG1="${1:-}" +ORIG_ARG2="${2:-}" +ORIG_ARG3="${3:-}" +[ -f /lib/functions.sh ] && . /lib/functions.sh +. $IPKG_INSTROOT/etc/init.d/shadowsocksr +LOCK_FILE="/var/lock/ssr-switch.lock" +PROBE_SID="" + +cycle_time=60 +switch_time=3 +probe_socks_port=10800 +direct_fail_count=0 +direct_fail_limit=3 +probe_url="$(uci_get_by_type server_subscribe url_test_url)" +[ -n "$probe_url" ] || probe_url="https://www.google.com/generate_204" +PROBE_INSTANCE_KEY="ssr-switch-probe-local" + +DEFAULT_SERVER="$(uci_get_by_type global global_server)" +CURRENT_SERVER="$DEFAULT_SERVER" +ENABLE_SERVER="nil" + +cleanup_probe_socks() { + ps_list | grep -v "grep" | grep -E "tcp-http-ssr-switch-local\\.json|ss-${PROBE_INSTANCE_KEY}/config\\.yaml|tuic-${PROBE_INSTANCE_KEY}/config\\.yaml" | awk '{print $1}' | xargs kill >/dev/null 2>&1 + sleep 1 + ps_list | grep -v "grep" | grep -E "tcp-http-ssr-switch-local\\.json|ss-${PROBE_INSTANCE_KEY}/config\\.yaml|tuic-${PROBE_INSTANCE_KEY}/config\\.yaml" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -f "$TMP_PATH/tcp-http-ssr-switch-local.json" 2>/dev/null + rm -rf "$TMP_PATH/ss-${PROBE_INSTANCE_KEY}" "$TMP_PATH/tuic-${PROBE_INSTANCE_KEY}" 2>/dev/null + rm -f /tmp/ssr-switch-probe.log 2>/dev/null +} + +start_probe_socks() { + local sid="$1" + local server_type + + server_type="$(uci_get_by_name "$sid" type)" + [ "$server_type" = "clash" ] && return 1 + [ "$server_type" = "tuic" ] && return 1 + [ "$server_type" = "socks5" ] && return 1 + + cleanup_probe_socks + LOCAL_SERVER="$sid" + local_config_file="$TMP_PATH/tcp-http-ssr-switch-local.json" + _local="2" + local_enable=0 + tmp_local_port= + mode="tcp,udp" + + if [ "$server_type" = "v2ray" ]; then + export SSR_SWITCH_PROBE=1 + gen_config_file "$LOCAL_SERVER" "$server_type" 4 0 "$probe_socks_port" >/tmp/ssr-switch-probe.log 2>&1 || return 1 + unset SSR_SWITCH_PROBE + local xray_bin + xray_bin="$(first_type xray)" + [ -x "$xray_bin" ] || return 1 + "$xray_bin" run -c "$local_config_file" >>/tmp/ssr-switch-probe.log 2>&1 & + else + export SSR_SWITCH_PROBE=1 + export SSR_SWITCH_PROBE_INSTANCE_KEY="$PROBE_INSTANCE_KEY" + start_local_with_port "$probe_socks_port" >/tmp/ssr-switch-probe.log 2>&1 || return 1 + unset SSR_SWITCH_PROBE_INSTANCE_KEY + unset SSR_SWITCH_PROBE + fi + + sleep 2 + return 0 +} + +probe_http_ok() { + case "$1" in + [1-5][0-9][0-9]) + return 0 + ;; + esac + return 1 +} + +check_direct_probe() { + local code + + code="$(curl -k -sS -L -o /dev/null \ + --connect-timeout "$switch_time" \ + --max-time "$switch_time" \ + -w '%{http_code}' \ + "$probe_url" 2>/dev/null || true)" + probe_http_ok "$code" +} + +check_proxy_via_socks() { + local try_count + local code + local proxy_host + + try_count="$(uci_get_by_type global switch_try_count 3)" + for i in $(seq 1 "$try_count"); do + for proxy_host in "127.0.0.1:$probe_socks_port" "[::1]:$probe_socks_port"; do + code="$(curl -k -sS -L -o /dev/null \ + --connect-timeout "$switch_time" \ + --max-time "$switch_time" \ + --socks5-hostname "$proxy_host" \ + -w '%{http_code}' \ + "$probe_url" 2>/dev/null || true)" + probe_http_ok "$code" && return 0 + done + sleep 1 + done + return 1 +} + +test_proxy() { + local sid="$1" + [ "$(uci_get_by_name "$sid" type)" = "clash" ] && return 1 + [ "$(uci_get_by_name "$sid" type)" = "tuic" ] && return 1 + start_probe_socks "$sid" || { + cleanup_probe_socks + return 1 + } + check_proxy_via_socks + local ret=$? + cleanup_probe_socks + return $ret +} + +search_proxy() { + local sid="$1" + [ "$(uci_get_by_name "$sid" switch_enable 0)" = "1" ] || return 1 + [ "$(uci_get_by_name "$sid" type)" = "clash" ] && return 1 + [ "$(uci_get_by_name "$sid" type)" = "tuic" ] && return 1 + [ "$sid" = "$CURRENT_SERVER" ] && return 1 + [ "$ENABLE_SERVER" != "nil" ] && return 0 + + if test_proxy "$sid"; then + ENABLE_SERVER="$sid" + return 0 + fi + return 1 +} + +select_proxy() { + config_load "$NAME" + ENABLE_SERVER="nil" + config_foreach search_proxy servers +} + +set_main_server() { + local sid="$1" + [ -n "$sid" ] || return 1 + uci set shadowsocksr.@global[0].global_server="$sid" + uci commit shadowsocksr + return 0 +} + +switch_proxy() { + set_main_server "$1" || return 1 + /etc/init.d/shadowsocksr restart "$1" + return 0 +} + +start() { + while [ "1" = "1" ]; do + sleep "0000$cycle_time" + run_once + done +} + +run_once() { + DEFAULT_SERVER="$(uci_get_by_type global global_server)" + [ "$DEFAULT_SERVER" = "nil" ] && { + direct_fail_count=0 + return 0 + } + [ "$(uci_get_by_name "$DEFAULT_SERVER" type)" = "clash" ] && { + direct_fail_count=0 + cleanup_probe_socks + return 0 + } + [ "$(uci_get_by_name "$DEFAULT_SERVER" type)" = "tuic" ] && { + direct_fail_count=0 + cleanup_probe_socks + return 0 + } + [ "$(uci_get_by_name "$DEFAULT_SERVER" kcp_enable 0)" = "1" ] && { + direct_fail_count=0 + cleanup_probe_socks + return 1 + } + + CURRENT_SERVER="$DEFAULT_SERVER" + + if check_direct_probe; then + direct_fail_count=0 + return 0 + fi + + direct_fail_count=$((direct_fail_count + 1)) + [ "$direct_fail_count" -lt "$direct_fail_limit" ] && return 0 + direct_fail_count=0 + + if test_proxy "$CURRENT_SERVER"; then + return 0 + fi + + echolog "Current server error, try to switch another server." + select_proxy + if [ "$ENABLE_SERVER" != "nil" ]; then + CURRENT_SERVER="$ENABLE_SERVER" + switch_proxy "$CURRENT_SERVER" + echolog "Switch to $(uci_get_by_name "$CURRENT_SERVER" alias) proxy!" + else + switch_proxy "$CURRENT_SERVER" + echolog "Try restart current server." + fi + return 0 +} + +probe_once() { + local sid="$1" + [ -n "$sid" ] || { + echo "missing_sid" + return 1 + } + cleanup_probe_socks + if ! start_probe_socks "$sid"; then + echo "probe_start:fail" + return 1 + fi + echo "probe_start:ok" + echo "probe:curl_ipv4" + curl -k -sS -L -o /dev/null \ + --connect-timeout "$switch_time" \ + --max-time "$switch_time" \ + --socks5-hostname "127.0.0.1:$probe_socks_port" \ + -w 'code=%{http_code}\n' \ + "$probe_url" 2>/dev/null || true + echo "probe:curl_ipv6" + curl -g -k -sS -L -o /dev/null \ + --connect-timeout "$switch_time" \ + --max-time "$switch_time" \ + --socks5-hostname "[::1]:$probe_socks_port" \ + -w 'code=%{http_code}\n' \ + "$probe_url" 2>/dev/null || true + cleanup_probe_socks + return 0 +} + +main() { + case "${ORIG_ARG1:-}" in + probe) + PROBE_SID="${ORIG_ARG2:-}" + probe_once "$PROBE_SID" + ;; + once) + run_once + ;; + start) + [ -n "$ORIG_ARG2" ] && cycle_time="$ORIG_ARG2" + [ -n "$ORIG_ARG3" ] && switch_time="$ORIG_ARG3" + [ -f "$LOCK_FILE" ] && exit 2 + touch "$LOCK_FILE" + start + ;; + *) + [ -n "$ORIG_ARG1" ] && cycle_time="$ORIG_ARG1" + [ -n "$ORIG_ARG2" ] && switch_time="$ORIG_ARG2" + [ -f "$LOCK_FILE" ] && exit 2 + touch "$LOCK_FILE" + start + ;; + esac +} + +if [ "${0##*/}" = "ssr-switch" ]; then + main "$@" +fi diff --git a/luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json b/luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json new file mode 100644 index 00000000..4b96a2dd --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/rpcd/acl.d/luci-app-ssr-plus.json @@ -0,0 +1,17 @@ +{ + "luci-app-ssr-plus": { + "description": "Grant UCI access for luci-app-ssr-plus", + "read": { + "file": { + "/etc/ssrplus/*": [ "read" ] + }, + "uci": ["shadowsocksr"] + }, + "write": { + "file": { + "/etc/ssrplus/*": [ "write" ] + }, + "uci": ["shadowsocksr"] + } + } +} diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/Country.mmdb b/luci-app-ssr-plus/root/usr/share/shadowsocksr/Country.mmdb new file mode 100644 index 00000000..6898cab5 Binary files /dev/null and b/luci-app-ssr-plus/root/usr/share/shadowsocksr/Country.mmdb differ diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh b/luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh new file mode 100755 index 00000000..48164d1c --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/chinaipset.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +. $IPKG_INSTROOT/etc/init.d/shadowsocksr + +check_run_environment + +# 设置 china_ip å˜é‡å¹¶æ£€æŸ¥æ–‡ä»¶æ˜¯å¦å­˜åœ¨ +china_ip="${1:-${china_ip:-/etc/ssrplus/china_ssr.txt}}" +[ -f "$china_ip" ] || exit 1 + +case "$USE_TABLES" in + nftables) + skip_inet="${SKIP_INET:-0}" + + case "$skip_inet" in + 1) + { + # ss_spec / inet (仅在表和 set 存在时添加) + if nft list set inet ss_spec china >/dev/null 2>&1; then + echo "add element inet ss_spec china {" + grep -vE '^\s*#|^\s*$' "$china_ip" | sed 's/^/ /;s/$/,/' + echo "}" + fi + } | nft -f - || exit 1 + ;; + 2) + { + # ss_spec_mangle / ip (仅在表和 set 存在时添加) + if nft list set ip ss_spec_mangle china >/dev/null 2>&1; then + echo "add element ip ss_spec_mangle china {" + grep -vE '^\s*#|^\s*$' "$china_ip" | sed 's/^/ /;s/$/,/' + echo "}" + fi + } | nft -f - || exit 1 + ;; + *) + echolog "chinaipset: invalid SKIP_INET=$skip_inet" + exit 1 + ;; + esac + ;; + iptables) + ipset -! flush china 2>/dev/null + ipset -! -R <<-EOF || exit 1 + create china hash:net + $(grep -vE '^\s*#|^\s*$' "$china_ip" | sed 's/^/add china /') + EOF + ;; + *) + echolog "ERROR: No supported firewall backend detected" + exit 1 + ;; +esac diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/clash_yaml.lua b/luci-app-ssr-plus/root/usr/share/shadowsocksr/clash_yaml.lua new file mode 100644 index 00000000..701bfacc --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/clash_yaml.lua @@ -0,0 +1,939 @@ +#!/usr/bin/lua + +require "nixio.fs" +require "luci.model.uci" + +local ok_lyaml, lyaml = pcall(require, "lyaml") +if not ok_lyaml then + io.stderr:write("lyaml_not_found\n") + os.exit(2) +end + +local uci = require "luci.model.uci".cursor() +local ok_jsonc, jsonc = pcall(require, "luci.jsonc") + +local function read_file(path) + local data = nixio.fs.readfile(path) + if not data or data == "" then + return nil + end + return data +end + +local function write_file(path, data) + return nixio.fs.writefile(path, data) +end + +local function load_yaml(path) + local raw = read_file(path) + if not raw then + return nil, "read_failed" + end + + local ok, parsed = pcall(lyaml.load, raw) + if not ok or type(parsed) ~= "table" then + return nil, "parse_failed" + end + + return parsed +end + +local function dump_yaml(path, data) + local ok, rendered = pcall(lyaml.dump, { data }) + if not ok or not rendered then + return nil, "dump_failed" + end + + write_file(path, rendered) + return true +end + +local function split_filter_words(text) + local items = {} + for part in tostring(text or ""):gmatch("[^/]+") do + if part ~= "" then + items[#items + 1] = part + end + end + return items +end + +local function trim(value) + return tostring(value or ""):gsub("^%s+", ""):gsub("%s+$", "") +end + +local function parse_csv_line(line) + local cols = {} + local cur = "" + local in_quote = false + local i = 1 + + while i <= #line do + local ch = line:sub(i, i) + if ch == '"' then + if in_quote and line:sub(i + 1, i + 1) == '"' then + cur = cur .. '"' + i = i + 1 + else + in_quote = not in_quote + end + elseif ch == "," and not in_quote then + cols[#cols + 1] = cur + cur = "" + else + cur = cur .. ch + end + i = i + 1 + end + + cols[#cols + 1] = cur + return cols +end + +local function read_clash_client_rules_csv(sid) + local rows = {} + sid = trim(sid) + if sid == "" then + return rows + end + + local csv_path = string.format("/etc/ssrplus/clash/%s.csv", sid) + local raw = read_file(csv_path) + if not raw or raw == "" then + return rows + end + + local first = true + for line in tostring(raw):gsub("\r", ""):gmatch("[^\n]+") do + local text = trim(line) + if text ~= "" then + if first and text:lower() == "enabled,client,policy,remarks,client_mac" then + first = false + else + local cols = parse_csv_line(line) + if #cols >= 4 then + rows[#rows + 1] = { + enabled = cols[1], + ip_addr = trim(cols[2] or ""), + policy_group = trim(cols[3] or ""), + remarks = trim(cols[4] or ""), + client_mac = trim(cols[5] or "") + } + end + end + end + end + + return rows +end + +local function has_proxy_sections(doc) + return type(doc.proxies) == "table" or type(doc["proxy-providers"]) == "table" +end + +local function validate(path) + local doc = load_yaml(path) + if not doc then + return false + end + return has_proxy_sections(doc) +end + +local function filter(path, filter_words) + local doc, err = load_yaml(path) + if not doc then + io.stderr:write(err or "parse_failed", "\n") + return false + end + + local words = split_filter_words(filter_words) + if #words == 0 then + return true + end + + local removed = {} + local proxies = {} + for _, proxy in ipairs(doc.proxies or {}) do + local name = tostring(proxy.name or "") + local matched = false + for _, word in ipairs(words) do + if name:find(word, 1, true) then + matched = true + removed[name] = true + break + end + end + if not matched then + proxies[#proxies + 1] = proxy + end + end + doc.proxies = proxies + + for _, group in ipairs(doc["proxy-groups"] or {}) do + if type(group.proxies) == "table" then + local kept = {} + for _, name in ipairs(group.proxies) do + if not removed[tostring(name)] then + kept[#kept + 1] = name + end + end + group.proxies = kept + end + end + + local count = 0 + for _ in pairs(removed) do + count = count + 1 + end + + dump_yaml(path, doc) + io.stdout:write(tostring(count), "\n") + return true +end + +local function deep_merge(dst, src) + if type(dst) ~= "table" or type(src) ~= "table" then + return src + end + + for k, v in pairs(src) do + if type(v) == "table" and type(dst[k]) == "table" then + dst[k] = deep_merge(dst[k], v) + else + dst[k] = v + end + end + + return dst +end + +local function strip_runtime_conflicts(doc) + doc.tun = nil + doc.listeners = nil + doc["redir-port"] = nil + doc["tproxy-port"] = nil + doc["socks-port"] = nil + doc["mixed-port"] = nil + doc.port = nil + doc["external-controller"] = nil + doc.secret = nil + doc["allow-lan"] = nil + if type(doc.dns) == "table" then + doc.dns["fake-ip-range"] = nil + doc.dns["fake-ip-filter"] = nil + end +end + +local function group_requires_candidates(group) + local gtype = tostring(group and group.type or ""):lower() + return gtype == "select" + or gtype == "fallback" + or gtype == "load-balance" + or gtype == "url-test" + or gtype == "relay" +end + +local function has_nonempty_sequence(value) + return type(value) == "table" and next(value) ~= nil +end + +local function fill_empty_proxy_groups(doc) + local changed = 0 + for _, group in ipairs(doc["proxy-groups"] or {}) do + if type(group) == "table" + and group_requires_candidates(group) + and not has_nonempty_sequence(group.proxies) + and not has_nonempty_sequence(group.use) + then + group.proxies = { "DIRECT" } + changed = changed + 1 + end + end + return changed +end + +local function strip_incompatible_script_rules(doc) + local kept = {} + local removed = 0 + local has_script_rule = false + + for _, rule in ipairs(doc.rules or {}) do + local text = tostring(rule or "") + if text:match("^SCRIPT,") then + removed = removed + 1 + else + kept[#kept + 1] = rule + if text:match("^SCRIPT,") then + has_script_rule = true + end + end + end + + if removed > 0 then + doc.rules = kept + end + + if not has_script_rule then + doc.script = nil + end + + return removed +end + +local function prepare(input_path, output_path) + local doc, err = load_yaml(input_path) + if not doc then + io.stderr:write(err or "parse_failed", "\n") + return false + end + if not has_proxy_sections(doc) then + io.stderr:write("missing_proxy_sections\n") + return false + end + + strip_runtime_conflicts(doc) + local filled_groups = fill_empty_proxy_groups(doc) + local stripped_rules = strip_incompatible_script_rules(doc) + local ok, rendered = pcall(lyaml.dump, { doc }) + if not ok or not rendered then + io.stderr:write("dump_failed\n") + return false + end + + write_file(output_path, rendered) + io.stdout:write(string.format("filled_groups=%d stripped_script_rules=%d\n", filled_groups, stripped_rules)) + return true +end + +local function merge(raw_path, overlay_path, output_path) + local raw_doc, raw_err = load_yaml(raw_path) + if not raw_doc then + io.stderr:write(raw_err or "parse_failed", "\n") + return false + end + + local overlay_doc, overlay_err = load_yaml(overlay_path) + if not overlay_doc then + io.stderr:write(overlay_err or "parse_failed", "\n") + return false + end + + strip_runtime_conflicts(raw_doc) + local filled_groups = fill_empty_proxy_groups(raw_doc) + local stripped_rules = strip_incompatible_script_rules(raw_doc) + local merged = deep_merge(raw_doc, overlay_doc) + local ok, rendered = pcall(lyaml.dump, { merged }) + if not ok or not rendered then + io.stderr:write("dump_failed\n") + return false + end + + write_file(output_path, rendered) + io.stdout:write(string.format("filled_groups=%d stripped_script_rules=%d\n", filled_groups, stripped_rules)) + return true +end + +local function append_client_policy_rules(runtime_path, sid) + local doc, err = load_yaml(runtime_path) + if not doc then + io.stderr:write(err or "parse_failed", "\n") + return false + end + + local valid_policies = {} + for _, proxy in ipairs(doc.proxies or {}) do + if type(proxy) == "table" and proxy.name and proxy.name ~= "" then + valid_policies[tostring(proxy.name)] = true + end + end + for _, group in ipairs(doc["proxy-groups"] or {}) do + if type(group) == "table" and group.name and group.name ~= "" then + valid_policies[tostring(group.name)] = true + end + end + + local custom_rules = {} + for _, section in ipairs(read_clash_client_rules_csv(sid)) do + if tostring(section.enabled or "0") == "1" then + local ip_addr = tostring(section.ip_addr or "") + local policy_group = tostring(section.policy_group or "") + if ip_addr ~= "" and policy_group ~= "" and valid_policies[policy_group] then + if not ip_addr:find("/", 1, true) then + ip_addr = ip_addr .. "/32" + end + custom_rules[#custom_rules + 1] = string.format("SRC-IP-CIDR,%s,%s", ip_addr, policy_group) + end + end + end + + if #custom_rules == 0 then + io.stdout:write("client_rules=0\n") + return true + end + + local existing_rules = {} + for _, rule in ipairs(doc.rules or {}) do + local text = tostring(rule or "") + if not text:match("^SRC%-IP%-CIDR,") then + existing_rules[#existing_rules + 1] = rule + end + end + + doc.rules = {} + for _, rule in ipairs(custom_rules) do + doc.rules[#doc.rules + 1] = rule + end + for _, rule in ipairs(existing_rules) do + doc.rules[#doc.rules + 1] = rule + end + + local ok, rendered = pcall(lyaml.dump, { doc }) + if not ok or not rendered then + io.stderr:write("dump_failed\n") + return false + end + + write_file(runtime_path, rendered) + io.stdout:write(string.format("client_rules=%d\n", #custom_rules)) + return true +end + +local function bool_enabled(value) + return value == "1" or value == 1 or value == true or value == "true" +end + +local function split_csv(value) + local items = {} + for part in tostring(value or ""):gmatch("[^,%s]+") do + items[#items + 1] = part + end + return items +end + +local function get_server_field(sid, option, default) + local value = uci:get("shadowsocksr", sid, option) + if value == nil or value == "" then + return default + end + return value +end + +local function get_filter_aaaa() + local value = uci:get_first("shadowsocksr", "global", "filter_aaaa", "1") + if value == nil or value == "" then + value = uci:get_first("shadowsocksr", "global", "mosdns_ipv6", "1") + end + return value +end + +local function build_tuic_runtime_doc(sid, local_port, socks_port, mode) + local server = get_server_field(sid, "server", "") + local server_port = tonumber(get_server_field(sid, "server_port", "0")) or 0 + local tuic_ip = get_server_field(sid, "tuic_ip", "") + local tls_host = get_server_field(sid, "tls_host", "") + local ipstack_prefer = get_server_field(sid, "ipstack_prefer", "") + local dns_mode = uci:get_first("shadowsocksr", "global", "pdnsd_enable", "0") + + local proxy = { + name = sid, + type = "tuic", + server = server, + port = server_port, + uuid = get_server_field(sid, "tuic_uuid", ""), + password = get_server_field(sid, "tuic_passwd", ""), + ["udp-relay-mode"] = get_server_field(sid, "udp_relay_mode", "native"), + ["congestion-controller"] = get_server_field(sid, "congestion_control", "cubic"), + ["skip-cert-verify"] = bool_enabled(get_server_field(sid, "insecure", "0")), + ["disable-sni"] = bool_enabled(get_server_field(sid, "disable_sni", "0")), + ["reduce-rtt"] = bool_enabled(get_server_field(sid, "zero_rtt_handshake", "0")) + } + + if tuic_ip ~= "" then + proxy.ip = tuic_ip + end + if tls_host ~= "" then + proxy.sni = tls_host + end + + local alpn = split_csv(get_server_field(sid, "tuic_alpn", "")) + if #alpn > 0 then + proxy.alpn = alpn + end + + local heartbeat = tonumber(get_server_field(sid, "heartbeat", "0")) + if heartbeat and heartbeat > 0 then + proxy["heartbeat-interval"] = heartbeat * 1000 + end + + local timeout = tonumber(get_server_field(sid, "timeout", "0")) + if timeout and timeout > 0 then + proxy["request-timeout"] = timeout * 1000 + end + + local max_udp_packet_size = tonumber(get_server_field(sid, "tuic_max_package_size", "0")) + if max_udp_packet_size and max_udp_packet_size > 0 then + proxy["max-udp-relay-packet-size"] = max_udp_packet_size + end + + if ipstack_prefer ~= "" then + proxy["ip-version"] = ipstack_prefer == "v6first" and "ipv6-prefer" or "ipv4-prefer" + end + + local listen_port = tonumber(local_port) + local socks_listen = tonumber(socks_port) + + local doc = { + ["allow-lan"] = true, + ["bind-address"] = "0.0.0.0", + mode = "rule", + ["log-level"] = "silent", + ["find-process-mode"] = "off", + ["unified-delay"] = true, + ["tcp-concurrent"] = true, + ["routing-mark"] = 255, + proxies = { proxy }, + ["proxy-groups"] = { + { + name = "PROXY", + type = "select", + proxies = { sid } + } + }, + rules = { "MATCH,PROXY" }, + tun = { enable = false }, + profile = { ["store-selected"] = true }, + dns = { + enable = dns_mode == "7", + ["enhanced-mode"] = "redir-host", + listen = "127.0.0.1:5335", + ipv6 = get_filter_aaaa() ~= "1" + } + } + + if mode == "socks" then + doc["socks-port"] = listen_port + else + doc["redir-port"] = listen_port + doc["tproxy-port"] = listen_port + if socks_listen and socks_listen > 0 then + doc["socks-port"] = socks_listen + end + end + + return doc +end + +local function generate_tuic_runtime(sid, output_path, local_port, socks_port, mode) + local doc = build_tuic_runtime_doc(sid, local_port, socks_port, mode) + local ok, rendered = pcall(lyaml.dump, { doc }) + if not ok or not rendered then + io.stderr:write("dump_failed\n") + return false + end + write_file(output_path, rendered) + return true +end + +local function parse_plugin_opts(value) + local result = {} + for part in tostring(value or ""):gmatch("[^;]+") do + local key, val = part:match("^%s*([^=]+)=?(.*)%s*$") + if key and key ~= "" then + result[key] = val or "" + end + end + return result +end + +local function split_host_port(value) + local text = tostring(value or "") + if text == "" then + return "", "" + end + local host, port = text:match("^%[(.-)%]:(%d+)$") + if host and port then + return host, port + end + host, port = text:match("^(.-):(%d+)$") + if host and port then + return host, port + end + return text, "" +end + +local function bool_default(value, default) + if value == nil or value == "" then + return default + end + return bool_enabled(value) +end + +local function number_or_nil(value) + if value == nil or value == "" then + return nil + end + return tonumber(value) +end + +local function string_or_nil(value) + if value == nil or value == "" then + return nil + end + return tostring(value) +end + +local function pick_plugin_opt(plugin_opts, ...) + for i = 1, select("#", ...) do + local key = select(i, ...) + local value = plugin_opts[key] + if value ~= nil and value ~= "" then + return value + end + end + return nil +end + +local function parse_plugin_headers(plugin_opts) + local headers = {} + local raw_headers = pick_plugin_opt(plugin_opts, "headers", "header") + + if raw_headers and ok_jsonc and jsonc then + local decoded = jsonc.parse(raw_headers) + if type(decoded) == "table" then + for key, value in pairs(decoded) do + headers[tostring(key)] = tostring(value) + end + end + end + + if raw_headers and next(headers) == nil then + for part in tostring(raw_headers):gmatch("[^|,]+") do + local key, value = part:match("^%s*([^=:]+)%s*[:=]%s*(.-)%s*$") + if key and key ~= "" and value and value ~= "" then + headers[key] = value + end + end + end + + for key, value in pairs(plugin_opts) do + local header_name = key:match("^headers[%.:](.+)$") + or key:match("^header[%.:](.+)$") + or key:match("^header_(.+)$") + if header_name and header_name ~= "" and value ~= "" then + headers[header_name] = value + end + end + + return next(headers) and headers or nil +end + +local function get_plugin_client_fingerprint(sid, plugin_opts) + return string_or_nil( + pick_plugin_opt( + plugin_opts, + "client-fingerprint", + "client_fingerprint", + "fingerprint" + ) or get_server_field(sid, "fingerprint", "") + ) +end + +local function normalize_plugin_name(plugin) + local value = tostring(plugin or ""):lower() + if value == "" or value == "none" then + return "" + end + if value == "simple-obfs" then + return "obfs-local" + end + if value == "obfs" then + return "obfs-local" + end + if value == "shadowtls" then + return "shadow-tls" + end + if value == "gost" then + return "gost-plugin" + end + if value == "kcp-tun" then + return "kcptun" + end + return value +end + +local function build_shadowsocks_plugin(proxy, sid) + local plugin = normalize_plugin_name(get_server_field(sid, "plugin", "")) + local plugin_opts = parse_plugin_opts(get_server_field(sid, "plugin_opts", "")) + + if plugin == "" then + return + end + + if plugin == "obfs-local" then + proxy.plugin = "obfs" + proxy["plugin-opts"] = { + mode = pick_plugin_opt(plugin_opts, "obfs", "mode") or "http", + host = string_or_nil(pick_plugin_opt(plugin_opts, "obfs-host", "obfs_host", "host")) + } + return + end + + if plugin == "v2ray-plugin" or plugin == "xray-plugin" then + proxy.plugin = "v2ray-plugin" + proxy["plugin-opts"] = { + mode = pick_plugin_opt(plugin_opts, "mode") or "websocket", + tls = bool_default(pick_plugin_opt(plugin_opts, "tls"), false), + fingerprint = string_or_nil(pick_plugin_opt(plugin_opts, "fingerprint")), + ["skip-cert-verify"] = bool_default(pick_plugin_opt(plugin_opts, "skip-cert-verify", "skip_cert_verify", "insecure"), false), + host = string_or_nil(pick_plugin_opt(plugin_opts, "host")), + path = string_or_nil(pick_plugin_opt(plugin_opts, "path")), + mux = bool_default(pick_plugin_opt(plugin_opts, "mux"), false), + headers = parse_plugin_headers(plugin_opts), + ["v2ray-http-upgrade"] = bool_default(pick_plugin_opt(plugin_opts, "v2ray-http-upgrade", "v2ray_http_upgrade"), false) + } + return + end + + if plugin == "gost-plugin" then + proxy.plugin = "gost-plugin" + proxy["plugin-opts"] = { + mode = pick_plugin_opt(plugin_opts, "mode") or "websocket", + tls = bool_default(pick_plugin_opt(plugin_opts, "tls"), false), + fingerprint = string_or_nil(pick_plugin_opt(plugin_opts, "fingerprint")), + ["skip-cert-verify"] = bool_default(pick_plugin_opt(plugin_opts, "skip-cert-verify", "skip_cert_verify", "insecure"), false), + host = string_or_nil(pick_plugin_opt(plugin_opts, "host")), + path = string_or_nil(pick_plugin_opt(plugin_opts, "path")), + mux = bool_default(pick_plugin_opt(plugin_opts, "mux"), false), + headers = parse_plugin_headers(plugin_opts) + } + return + end + + if plugin == "shadow-tls" then + local host, port = split_host_port(pick_plugin_opt(plugin_opts, "host") or "") + local version + if plugin_opts.v3 == "1" or plugin_opts.version == "3" then + version = 3 + elseif plugin_opts.v2 == "1" or plugin_opts.version == "2" then + version = 2 + elseif plugin_opts.v1 == "1" or plugin_opts.version == "1" then + version = 1 + end + proxy.plugin = "shadow-tls" + proxy["client-fingerprint"] = get_plugin_client_fingerprint(sid, plugin_opts) + proxy["plugin-opts"] = { + host = host ~= "" and host or nil, + port = number_or_nil(port), + password = string_or_nil(pick_plugin_opt(plugin_opts, "passwd", "password")), + version = version + } + return + end + + if plugin == "restls" then + proxy.plugin = "restls" + proxy["client-fingerprint"] = get_plugin_client_fingerprint(sid, plugin_opts) + proxy["plugin-opts"] = { + host = string_or_nil(pick_plugin_opt(plugin_opts, "host")), + password = string_or_nil(pick_plugin_opt(plugin_opts, "passwd", "password")), + ["version-hint"] = string_or_nil(pick_plugin_opt(plugin_opts, "version-hint", "version_hint")), + ["restls-script"] = string_or_nil(pick_plugin_opt(plugin_opts, "restls-script", "restls_script")) + } + return + end + + if plugin == "kcptun" then + proxy.plugin = "kcptun" + proxy["plugin-opts"] = { + key = string_or_nil(pick_plugin_opt(plugin_opts, "key", "passwd", "password")), + crypt = string_or_nil(pick_plugin_opt(plugin_opts, "crypt")), + mode = string_or_nil(pick_plugin_opt(plugin_opts, "mode")), + conn = number_or_nil(pick_plugin_opt(plugin_opts, "conn")), + autoexpire = number_or_nil(pick_plugin_opt(plugin_opts, "autoexpire")), + scavengettl = number_or_nil(pick_plugin_opt(plugin_opts, "scavengettl")), + mtu = number_or_nil(pick_plugin_opt(plugin_opts, "mtu")), + ratelimit = number_or_nil(pick_plugin_opt(plugin_opts, "ratelimit")), + sndwnd = number_or_nil(pick_plugin_opt(plugin_opts, "sndwnd")), + rcvwnd = number_or_nil(pick_plugin_opt(plugin_opts, "rcvwnd")), + datashard = number_or_nil(pick_plugin_opt(plugin_opts, "datashard")), + parityshard = number_or_nil(pick_plugin_opt(plugin_opts, "parityshard")), + dscp = number_or_nil(pick_plugin_opt(plugin_opts, "dscp")), + nocomp = bool_default(pick_plugin_opt(plugin_opts, "nocomp"), false), + acknodelay = bool_default(pick_plugin_opt(plugin_opts, "acknodelay"), false), + nodelay = number_or_nil(pick_plugin_opt(plugin_opts, "nodelay")), + interval = number_or_nil(pick_plugin_opt(plugin_opts, "interval")), + resend = number_or_nil(pick_plugin_opt(plugin_opts, "resend")), + sockbuf = number_or_nil(pick_plugin_opt(plugin_opts, "sockbuf")), + smuxver = number_or_nil(pick_plugin_opt(plugin_opts, "smuxver")), + smuxbuf = number_or_nil(pick_plugin_opt(plugin_opts, "smuxbuf")), + framesize = number_or_nil(pick_plugin_opt(plugin_opts, "framesize")), + streambuf = number_or_nil(pick_plugin_opt(plugin_opts, "streambuf")), + keepalive = number_or_nil(pick_plugin_opt(plugin_opts, "keepalive")) + } + return + end + + proxy.plugin = plugin + if next(plugin_opts) then + proxy["plugin-opts"] = plugin_opts + end +end + +local function build_kcptun_plugin(proxy, sid) + if not bool_enabled(get_server_field(sid, "kcp_enable", "0")) then + return + end + + proxy.plugin = "kcptun" + proxy.port = tonumber(get_server_field(sid, "kcp_port", "0")) or proxy.port + proxy["plugin-opts"] = { + key = get_server_field(sid, "kcp_password", ""), + mode = "fast", + mtu = 1350 + } +end + +local function build_shadowsocks_runtime_doc(sid, local_port, socks_port, mode) + local dns_mode = uci:get_first("shadowsocksr", "global", "pdnsd_enable", "0") + local server = get_server_field(sid, "server", "") + local server_port = tonumber(get_server_field(sid, "server_port", "0")) or 0 + local method = get_server_field(sid, "encrypt_method_ss", "none") + local password = get_server_field(sid, "password", "") + local proxy = { + name = sid, + type = "ss", + server = server, + port = server_port, + cipher = method, + password = password, + udp = true, + tfo = bool_enabled(get_server_field(sid, "fast_open", "0")) + } + + if get_server_field(sid, "type", "") == "ss" then + build_kcptun_plugin(proxy, sid) + end + if proxy.plugin == nil then + build_shadowsocks_plugin(proxy, sid) + end + + local doc = { + ["allow-lan"] = true, + ["bind-address"] = "0.0.0.0", + mode = "rule", + ["log-level"] = "silent", + ["find-process-mode"] = "off", + ["unified-delay"] = true, + ["tcp-concurrent"] = true, + ["routing-mark"] = 255, + proxies = { proxy }, + ["proxy-groups"] = { + { + name = "PROXY", + type = "select", + proxies = { sid } + } + }, + rules = { "MATCH,PROXY" }, + tun = { enable = false }, + profile = { ["store-selected"] = true }, + dns = { + enable = dns_mode == "7", + ["enhanced-mode"] = "redir-host", + listen = "127.0.0.1:5335", + ipv6 = get_filter_aaaa() ~= "1" + } + } + + local listen_port = tonumber(local_port) + local socks_listen = tonumber(socks_port) + if mode == "socks" then + doc["socks-port"] = listen_port + else + doc["redir-port"] = listen_port + doc["tproxy-port"] = listen_port + if socks_listen and socks_listen > 0 then + doc["socks-port"] = socks_listen + end + end + + return doc +end + +local function generate_shadowsocks_runtime(sid, output_path, local_port, socks_port, mode) + local doc = build_shadowsocks_runtime_doc(sid, local_port, socks_port, mode) + local ok, rendered = pcall(lyaml.dump, { doc }) + if not ok or not rendered then + io.stderr:write("dump_failed\n") + return false + end + write_file(output_path, rendered) + return true +end + +local function build_shadowsocks_server_doc(sid) + local server_port = tonumber(get_server_field(sid, "server_port", "0")) or 0 + local method = get_server_field(sid, "encrypt_method_ss", "aes-128-gcm") + local password = get_server_field(sid, "password", "") + local listener = { + name = sid, + type = "shadowsocks", + listen = "::", + port = server_port, + cipher = method, + password = password, + udp = true, + tfo = bool_enabled(get_server_field(sid, "fast_open", "0")) + } + + local plugin = normalize_plugin_name(get_server_field(sid, "plugin", "")) + if plugin == "obfs-local" then + local plugin_opts = parse_plugin_opts(get_server_field(sid, "plugin_opts", "")) + listener.obfs = plugin_opts.obfs or plugin_opts.mode or "http" + listener.obfs_opts = { + mode = plugin_opts.obfs or plugin_opts.mode or "http", + host = plugin_opts["obfs-host"] or plugin_opts.obfs_host or plugin_opts.host or nil + } + end + + return { + ["allow-lan"] = true, + ["bind-address"] = "*", + ["log-level"] = "silent", + ["find-process-mode"] = "off", + listeners = { listener } + } +end + +local function generate_shadowsocks_server(sid, output_path) + local doc = build_shadowsocks_server_doc(sid) + local ok, rendered = pcall(lyaml.dump, { doc }) + if not ok or not rendered then + io.stderr:write("dump_failed\n") + return false + end + write_file(output_path, rendered) + return true +end + +local action = arg[1] +if action == "validate" then + os.exit(validate(arg[2]) and 0 or 1) +elseif action == "filter" then + os.exit(filter(arg[2], arg[3]) and 0 or 1) +elseif action == "prepare" then + os.exit(prepare(arg[2], arg[3]) and 0 or 1) +elseif action == "merge" then + os.exit(merge(arg[2], arg[3], arg[4]) and 0 or 1) +elseif action == "append_client_policy_rules" then + os.exit(append_client_policy_rules(arg[2], arg[3]) and 0 or 1) +elseif action == "tuic" then + os.exit(generate_tuic_runtime(arg[2], arg[3], arg[4], arg[5], arg[6]) and 0 or 1) +elseif action == "ss" then + os.exit(generate_shadowsocks_runtime(arg[2], arg[3], arg[4], arg[5], arg[6]) and 0 or 1) +elseif action == "ss_server" then + os.exit(generate_shadowsocks_server(arg[2], arg[3]) and 0 or 1) +else + io.stderr:write("usage: clash_yaml.lua validate | filter | prepare | merge | append_client_policy_rules | tuic [socks_port] [mode] | ss [socks_port] [mode] | ss_server \n") + os.exit(1) +end diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua new file mode 100755 index 00000000..4ac2af5b --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua @@ -0,0 +1,1123 @@ +#!/usr/bin/lua + +require "luci.sys" +local ucursor = require "luci.model.uci".cursor() +local json = require "luci.jsonc" + +local server_section = arg[1] +local proto = arg[2] or "tcp" +local local_port = arg[3] or "0" +local socks_port = arg[4] or "0" + +local chain = arg[5] or "0" + +-- 辅助函数:拆分字符串(若 luci.util 未加载则定义) +local function split(str, pat) + local t = {} + local last = 1 + while true do + local pos = str:find(pat, last, true) + if not pos then break end + table.insert(t, str:sub(last, pos - 1)) + last = pos + 1 + end + table.insert(t, str:sub(last)) + return t +end + +local chain_local_port = split(chain, "/")[2] or "0" + +local server = ucursor:get_all("shadowsocksr", server_section) +local socks_server = ucursor:get_all("shadowsocksr", "@socks5_proxy[0]") or {} +local xray_fragment = ucursor:get_all("shadowsocksr", "@global_xray_fragment[0]") or {} +local xray_noise = ucursor:get_all("shadowsocksr", "@xray_noise_packets[0]") or {} +local default_node_local_port = ucursor:get_first("shadowsocksr", "global", "default_node_local_port", "1234") +local dns_mode = ucursor:get_first("shadowsocksr", "global", "pdnsd_enable", "0") +local dns_ipv4_only = ucursor:get_first("shadowsocksr", "global", "filter_aaaa") +if not dns_ipv4_only or dns_ipv4_only == "" then + dns_ipv4_only = ucursor:get_first("shadowsocksr", "global", "mosdns_ipv6", "1") +end +local builtin_dns_server = ucursor:get_first("shadowsocksr", "global", "tunnel_forward", "8.8.4.4:53") +local outbound_settings = nil +local xray_version = nil +local xray_version_val = 0 +local xray_builtin_dns = nil + +local node_id = server_section +local remarks = server.alias or "" +local b64decode = nixio.bin.b64decode +local b64encode = nixio.bin.b64encode +local effective_node_local_port = tonumber(server.local_port) or tonumber(default_node_local_port) or 1234 + +if server.type == "ss-rust" then + server.type = "ss" +end + +-- base64 è§£ç  +local function base64Decode(text) + local raw = text + if not text or text == "" then + return '' + end + text = text:gsub("%z", "") + text = text:gsub("%c", "") + text = text:gsub("%s", "") + text = text:gsub("_", "/") + text = text:gsub("-", "+") + text = text:gsub("=", "") + local mod4 = #text % 4 + text = text .. string.sub('====', mod4 + 1) + local result = b64decode(text) + if result then + return result:gsub("%z", "") + else + return raw + end +end + +-- base64 ç¼–ç  +local function base64Encode(text) + if not text or text == "" then + return '' + end + local result = b64encode(text) + if result then + result = result:gsub("%z", "") + return result + else + return text + end +end + +-- Hex ç¼–ç  +local function hexEncode(text) + if not text or text == "" then + return '' + end + local hex = '' + for i = 1, #text do + local byte = string.byte(text, i) + hex = hex .. string.format('%02X', byte) + end + return hex +end + +local function cleanEmptyTables(t) + if type(t) ~= "table" then return nil end + for k, v in pairs(t) do + if type(v) == "table" then + t[k] = cleanEmptyTables(v) + end + end + return next(t) and t or nil +end + +local function format_host(host) + host = tostring(host or "") + if host ~= "" and host:find(":", 1, true) and not host:match("^%[.*%]$") then + return "[" .. host .. "]" + end + return host +end + +local function format_host_port(host, port) + host = format_host(host) + if port == nil or port == "" then + return host + end + return host .. ":" .. tostring(port) +end + +-- ç¡®ä¿æ­£ç¡®åˆ¤æ–­ç¨‹åºæ˜¯å¦å­˜åœ¨ +local function is_finded(e) + return luci.sys.exec(string.format('type -t -p "%s" -p "/usr/libexec/%s" 2>/dev/null', e, e)) ~= "" +end + +-- èŽ·å– Xray ç‰ˆæœ¬å· +if is_finded("xray") then + local version = luci.sys.exec("xray version 2>&1") + if version and version ~= "" then + xray_version = version:match("Xray%s+([%d%.]+)") + end +end + +-- å°† Xray 版本å·è½¬æ¢ä¸ºæ•°å­— +if xray_version and xray_version ~= "" then + local major, minor, patch = + xray_version:match("(%d+)%.?(%d*)%.?(%d*)") + + major = tonumber(major) or 0 + minor = tonumber(minor) or 0 + patch = tonumber(patch) or 0 + + xray_version_val = major * 10000 + minor * 100 + patch +end + +function vmess_vless() + outbound_settings = { + vnext = { + { + address = server.server, + port = tonumber(server.server_port), + users = { + { + id = server.vmess_id, + alterId = (server.v2ray_protocol == "vmess" or not server.v2ray_protocol) and tonumber(server.alter_id) or nil, + security = (server.v2ray_protocol == "vmess" or not server.v2ray_protocol) and server.security or nil, + testpre = (server.v2ray_protocol == "vless" or not server.v2ray_protocol) and tonumber(server.preconns) or nil, + encryption = (server.v2ray_protocol == "vless" or (not server.v2ray_protocol and server.vless_encryption)) and (server.vless_encryption or "none") or nil, + flow = (server.v2ray_protocol == "vless" and (server.xtls == "1" or server.tls == "1" or server.reality == "1" + or (server.vless_encryption and server.vless_encryption ~= "" and server.vless_encryption ~= "none")) and ( + server.transport == "raw" or server.transport == "tcp" or server.transport == "xhttp" or server.transport == "splithttp") and ( + server.tls_flow and server.tls_flow ~= "none")) and server.tls_flow or nil + } + } + } + } + } +end +function trojan_shadowsocks() + outbound_settings = { + servers = { + { + address = server.server, + port = tonumber(server.server_port), + password = server.password, + method = ((server.v2ray_protocol == "shadowsocks") and server.encrypt_method_ss) or nil, + uot = (server.v2ray_protocol == "shadowsocks") and (server.uot == '1') or nil, + ivCheck = (server.v2ray_protocol == "shadowsocks") and (server.ivCheck == '1') or nil, + } + } + } +end +function socks_http() + outbound_settings = { + version = server.socks_ver or nil, + servers = { + { + address = server.server, + port = tonumber(server.server_port), + users = (server.auth_enable == "1") and { + { + user = server.username, + pass = server.password + } + } or nil + } + } + } +end +function wireguard() + -- å¤„ç† reserved 字段,支æŒé€—å·åˆ†éš”的数字或 Base64 ç¼–ç  + local reserved = nil + if server.reserved then + local bytes = {} + if not server.reserved:match("[^%d,]+") then + -- 纯数字和逗å·ï¼Œè§£æžä¸ºæ•°å­—列表 + server.reserved:gsub("%d+", function(b) + bytes[#bytes + 1] = tonumber(b) + end) + else + -- Base64 ç¼–ç çš„äºŒè¿›åˆ¶æ•°æ® + local result = base64Decode(server.reserved) + for i = 1, #result do + bytes[i] = result:byte(i) + end + end + reserved = #bytes > 0 and bytes or nil + end + + outbound_settings = { + secretKey = server.private_key, + address = server.local_addresses, + peers = { + { + publicKey = server.peer_pubkey, + preSharedKey = server.preshared_key, + endpoint = format_host_port(server.server, server.server_port), + keepAlive = tonumber(server.keepaliveperiod), + allowedIPs = (server.allowedips) or nil, + } + }, + noKernelTun = (server.kernelmode == "1") and true or false, + reserved = reserved, + mtu = tonumber(server.mtu) + } +end +function xray_hysteria2() + outbound_settings = { + version = (server.v2ray_protocol == "hysteria2") and 2 or nil, + address = server.server, + port = tonumber(server.server_port) + } +end +local outbound = {} +function outbound:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + return o +end +function outbound:handleIndex(index) + local switch = { + vmess = function() + vmess_vless() + end, + vless = function() + vmess_vless() + end, + trojan = function() + trojan_shadowsocks() + end, + shadowsocks = function() + trojan_shadowsocks() + end, + socks = function() + socks_http() + end, + http = function() + socks_http() + end, + wireguard = function() + wireguard() + end, + hysteria2 = function() + xray_hysteria2() + end + } + if switch[index] then + switch[index]() + end +end +local settings = outbound:new() +settings:handleIndex(server.v2ray_protocol) +local Xray = { + log = { + -- error = "/var/ssrplus.log", + -- loglevel = "debug", + -- dnsLog = true, + -- access = "/var/log/ssrplus-access.log", + -- error = "/var/log/ssrplus-error.log" + loglevel = "warning" + }, + + -- åˆå§‹åŒ– inbounds 表 + inbounds = {}, + + -- åˆå§‹åŒ– outbounds 表 + outbounds = {}, +} + +if server.type == "v2ray" and dns_mode == "7" and os.getenv("SSR_SWITCH_PROBE") ~= "1" then + local dns_host = builtin_dns_server:match("^([^:]+)") or "8.8.4.4" + local dns_port = tonumber(builtin_dns_server:match(":(%d+)$")) or 53 + + Xray.dns = { + queryStrategy = (dns_ipv4_only == "1") and "UseIPv4" or "UseIP", + servers = { + string.format("tcp://%s:%d", dns_host, dns_port) + } + } + + table.insert(Xray.inbounds, { + listen = "127.0.0.1", + port = 5335, + protocol = "dokodemo-door", + settings = { + address = dns_host, + port = dns_port, + network = "tcp,udp" + }, + tag = "builtin-dns-in" + }) + + xray_builtin_dns = { + address = dns_host, + port = dns_port + } +end + -- 传入连接 + -- 添加 dokodemo-door é…置,如果 local_port ä¸ä¸º 0 +if local_port ~= "0" then + table.insert(Xray.inbounds, { + -- listening + port = tonumber(local_port), + protocol = "dokodemo-door", + settings = {network = proto, followRedirect = true}, + sniffing = { + enabled = true, + destOverride = {"http", "tls", "quic"}, + metadataOnly = false, + domainsExcluded = { + "courier.push.apple.com", + "rbsxbxp-mim.vivox.com", + "rbsxbxp.www.vivox.com", + "rbsxbxp-ws.vivox.com", + "rbspsxp.www.vivox.com", + "rbspsxp-mim.vivox.com", + "rbspsxp-ws.vivox.com", + "rbswxp.www.vivox.com", + "rbswxp-mim.vivox.com", + "disp-rbspsp-5-1.vivox.com", + "disp-rbsxbp-5-1.vivox.com", + "proxy.rbsxbp.vivox.com", + "proxy.rbspsp.vivox.com", + "proxy.rbswp.vivox.com", + "rbswp.vivox.com", + "rbsxbp.vivox.com", + "rbspsp.vivox.com", + "rbspsp.www.vivox.com", + "rbswp.www.vivox.com", + "rbsxbp.www.vivox.com", + "rbsxbxp.vivox.com", + "rbspsxp.vivox.com", + "rbswxp.vivox.com", + "Mijia Cloud", + "dlg.io.mi.com" + } + } + }) +end + + -- å¼€å¯ socks ä»£ç† + -- 检查是å¦å¯ç”¨ socks ä»£ç† +if proto and proto:find("tcp") and socks_port ~= "0" then + table.insert(Xray.inbounds, { + -- socks + protocol = "socks", + port = tonumber(socks_port), + settings = { + auth = socks_server.socks5_auth or "noauth", + udp = true, + mixed = ((socks_server.socks5_mixed == '1') and true or false) or nil, + accounts = (socks_server.socks5_auth and socks_server.socks5_auth ~= "noauth") and { + { + user = socks_server.socks5_user, + pass = socks_server.socks5_pass + } + } or nil + } or nil + }) +end + +-- 传出连接 +Xray.outbounds = { + { + protocol = (server.v2ray_protocol == "hysteria2") and "hysteria" or server.v2ray_protocol, + settings = outbound_settings, + tag = (remarks ~= nil and remarks ~= "") and (node_id .. ":" .. remarks) or node_id, + -- 底层传输é…ç½® + streamSettings = (server.v2ray_protocol ~= "wireguard") and { + network = (server.v2ray_protocol == "hysteria2") and "hysteria" or (server.transport or "raw"), + security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil, + tlsSettings = (server.tls == '1') and { + -- tls + alpn = (server.tls_alpn and server.tls_alpn ~= "") and (function() + local alpn = {} + string.gsub(server.tls_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then + return alpn + else + return nil + end + end)() or nil, + fingerprint = server.fingerprint, + allowInsecure = (function() + if server.tls_CertSha and server.tls_CertSha ~= "" then return nil end + if os.date("%Y.%m.%d") < "2026.06.01" then + return server.insecure == "1" + end + return nil + end)(), + serverName = server.tls_host, + certificates = server.certificate and { + usage = "verify", + certificateFile = server.certpath + } or nil, + pinnedPeerCertSha256 = (function() + if xray_version_val < 260131 then return nil end + if not server.tls_CertSha then return "" end + return server.tls_CertSha + end)(), + verifyPeerCertByName = (function() + if xray_version_val < 260131 then return nil end + if not server.tls_CertByName then return "" end + return server.tls_CertByName + end)(), + echConfigList = (server.enable_ech == "1") and server.ech_config or nil, + echForceQuery = (server.enable_ech == "1") and (server.ech_ForceQuery or "full") or nil + } or nil, + xtlsSettings = (server.xtls == '1') and server.tls_host and { + -- xtls + allowInsecure = (server.insecure == "1") and true or nil, + serverName = server.tls_host, + minVersion = "1.3" + } or nil, + realitySettings = (server.reality == '1') and { + publicKey = server.reality_publickey, + shortId = server.reality_shortid or "", + spiderX = server.reality_spiderx or "", + fingerprint = server.fingerprint, + mldsa65Verify = (server.enable_mldsa65verify == '1') and server.reality_mldsa65verify or nil, + serverName = server.tls_host + } or nil, + rawSettings = ((server.transport == "raw" or server.transport == "tcp") + and (server.tcp_guise and server.tcp_guise ~= "none")) and { + -- tcp + header = { + type = server.tcp_guise, + request = (server.tcp_guise == "http") and { + path = server.http_path and (function() + local t, r = server.http_path, {} + if type(t) == "string" then t = {t} end + for _, v in ipairs(t) do + r[#r + 1] = (v == "" and "/" or v) + end + return r + end)() or {"/"}, + headers = (server.http_path or server.user_agent) and { + Host = (type(server.http_host) == "string") and {server.http_host} or server.http_host, + ["User-Agent"] = server.user_agent and {server.user_agent} or nil + } or nil + } or nil + } + } or nil, + kcpSettings = (server.transport == "kcp") and { + -- kcp + mtu = (server.mtu and server.mtu ~= "") and tonumber(server.mtu) or 1350, + tti = 50, + uplinkCapacity = 12, + downlinkCapacity = 100, + CwndMultiplier = 1, + MaxSendingWindow = 2 * 1024 * 1024 + } or nil, + wsSettings = (server.transport == "ws") and (server.ws_path or server.ws_host or server.tls_host) and { + -- ws + host = server.ws_host or server.tls_host or nil, + path = server.ws_path or "/", + headers = server.user_agent and { + ["User-Agent"] = server.user_agent + } or nil, + maxEarlyData = tonumber(server.ws_ed) or nil, + earlyDataHeaderName = server.ws_ed_header or nil, + heartbeatPeriod = tonumber(server.ws_heartbeatPeriod) or nil + } or nil, + httpupgradeSettings = (server.transport == "httpupgrade") and { + -- httpupgrade + host = (server.httpupgrade_host or server.tls_host) or nil, + path = server.httpupgrade_path or "", + headers = server.user_agent and { + ["User-Agent"] = server.user_agent + } or nil + } or nil, + xhttpSettings = (server.transport == "xhttp" or server.transport == "splithttp") and { + -- xhttp + mode = server.xhttp_mode or "auto", + host = (server.xhttp_host or server.tls_host) or nil, + path = server.xhttp_path or "/", + extra = (function() + local extra = {} + -- è§£æž xhttp_extra(Base64 ç¼–ç çš„ JSON) + if (server.enable_xhttp_extra == "1" and server.xhttp_extra) then + local ok, parsed = pcall(json.parse, base64Decode(server.xhttp_extra)) + if ok and type(parsed) == "table" then + extra = parsed.extra or parsed -- å– "extra" 节,若无则整个 parsed + end + end + -- å¤„ç† User-Agent + if server.user_agent and server.user_agent ~= "" then + extra.headers = extra.headers or {} + if not extra.headers["User-Agent"] and not extra.headers["user-agent"] then + extra.headers["User-Agent"] = server.user_agent + end + end + -- 递归清ç†ç©ºè¡¨ï¼ˆå¦‚空 headers 会被删除) + return cleanEmptyTables(extra) + end)() + } or nil, + httpSettings = (server.transport == "h2") and { + -- h2 + path = server.h2_path or "", + host = {server.h2_host} or nil, + read_idle_timeout = tonumber(server.read_idle_timeout) or nil, + health_check_timeout = tonumber(server.health_check_timeout) or nil + } or nil, + quicSettings = (server.transport == "quic") and { + -- quic + security = server.quic_security, + key = server.quic_key, + header = {type = server.quic_guise} + } or nil, + grpcSettings = (server.transport == "grpc") and { + -- grpc + serviceName = (server.serviceName and server.serviceName ~= "") and server.serviceName or nil, + multiMode = (server.grpc_mode == "multi") and true or nil, + idle_timeout = server.idle_timeout and (tonumber(server.idle_timeout) < 10 and 10 or tonumber(server.idle_timeout)) or nil, + health_check_timeout = server.health_check_timeout and tonumber(server.health_check_timeout) or nil, + permit_without_stream = (server.permit_without_stream == "1") and true or nil, + initial_windows_size = server.initial_windows_size and tonumber(server.initial_windows_size) or nil, + user_agent = server.user_agent + } or nil, + hysteriaSettings = (server.v2ray_protocol == "hysteria2") and { + -- hysteria2 + version = 2, + auth = server.hy2_auth + } or nil, + finalmask = (function() + local finalmask = {} + local PT = server.v2ray_protocol + local TP = server.transport + if server.transport == "kcp" then + local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", + dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local udp = {} + if server.kcp_guise and server.kcp_guise ~= "none" then + local g = { type = map[server.kcp_guise] } + if server.kcp_guise == "dns" and server.kcp_domain and server.kcp_domain ~= "" then + g.settings = { domain = server.kcp_domain } + end + udp[#udp+1] = g + end + local c = { type = (server.seed and server.seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + if server.seed and server.seed ~= "" then + c.settings = { password = server.seed } + end + udp[#udp+1] = c + finalmask.udp = udp + elseif PT == "hysteria2" then + if (server.flag_obfs == "1" and (server.obfs_type and server.obfs_type ~= "")) then + finalmask.udp = {{ + type = server.obfs_type, + settings = server.salamander and { + password = server.salamander + } or nil + }} + end + local up = tonumber(server.uplink_capacity) or 0 + local down = tonumber(server.downlink_capacity) or 0 + finalmask.quicParams = { + congestion = server.hy2_tcpcongestion or nil, + brutalUp = up > 0 and (up .. "mbps") or nil, + brutalDown = down > 0 and (down .. "mbps") or nil, + udpHop = (server.flag_port_hopping == "1") and { + ports = string.gsub(server.port_range, ":", "-"), + interval = (function(v) + if not v then return 30 end + if v:find("-", 1, true) then + local min, max = v:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + return min .. "-" .. max + end + return 30 + end + v = tonumber((v or "30"):match("^%d+")) + return (v and v >= 5) and v or 30 + end)(server.hopinterval) + } or nil, + initStreamReceiveWindow = (server.flag_quicparam == "1" and server.initstreamreceivewindow) and tonumber(server.initstreamreceivewindow) or nil, + maxStreamReceiveWindow = (server.flag_quicparam == "1" and server.maxstreamreceivewindow) and tonumber(server.maxstreamreceivewindow) or nil, + initConnectionReceiveWindow = (server.flag_quicparam == "1" and server.initconnreceivewindow) and tonumber(server.initconnreceivewindow) or nil, + maxConnectionReceiveWindow = (server.flag_quicparam == "1" and server.maxconnreceivewindow) and tonumber(server.maxconnreceivewindow) or nil, + maxIdleTimeout = (server.flag_quicparam == "1" and (function(t) + t = tonumber(tostring(t or "30"):match("^%d+")) + return (t and t >= 4 and t <= 120) and t or 30 + end)(server.maxidletimeout) or 30), + keepAlivePeriod = (server.flag_quicparam == "1" and server.keepaliveperiod) and tonumber(server.keepaliveperiod) or nil, + disablePathMTUDiscovery = (server.flag_quicparam == "1" and tostring(server.disablepathmtudiscovery) == "1") and true or nil + } + end + if xray_fragment.fragment == "1" and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then + local n_packets = xray_fragment.fragment_packets + local n_length = xray_fragment.fragment_length + local n_delay = xray_fragment.fragment_delay + local n_maxsplit = xray_fragment.fragment_maxSplit + --local domainstr = xray_noise.domainStrategy + finalmask.tcp = finalmask.tcp or {} + finalmask.tcp[#finalmask.tcp + 1] = { + type = "fragment", + settings = { + --domainStrategy = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and domainstr or nil, + packets = (n_packets and n_packets ~= "") and n_packets or nil, + length = (n_length and n_length ~= "") and n_length or nil, + delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay)), + maxSplit = (n_maxsplit and n_maxsplit ~= "") and n_maxsplit or nil + } + } + end + if xray_fragment.noise == "1" and (TP == "kcp" or (TP == "xhttp" and (server.tls_alpn == "h3" or server.tls_alpn == "h3,h2"))) then + if xray_noise.enabled == "1" then + local n_type = xray_noise.type + local n_delay = xray_noise.delay + local n_packet = xray_noise.packet + finalmask.udp = finalmask.udp or {} + finalmask.udp[#finalmask.udp + 1] = { + type = "noise", + settings = { + reset = 0, + noise = { + { + rand = (n_type == "rand") and (n_packet and (type(n_packet) == "string" and (n_packet:find("-")) and n_packet or tonumber(n_packet))) or nil, + type = (type(n_type) == "string" and n_type ~= "rand") and n_type or nil, + packet = (n_type ~= "rand") and ((n_packet and type(n_packet) == "string") and ((n_type == "hex" and hexEncode(n_packet)) or (n_type == "base64" and base64Encode(n_packet))) or n_packet) or nil, + delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay)) + } + } + } + } + end + end + if server.finalmask and server.finalmask ~= "" then + local ok, fm = pcall(json.parse, base64Decode(server.finalmask)) + if ok and type(fm) == "table" then + finalmask = fm + end + end + return cleanEmptyTables(finalmask) + end)(), + sockopt = { + mark = 255, + tcpFastOpen = (function() + if server.transport == "xhttp" then + return (server.fast_open == "1") and true or false + elseif server.v2ray_protocol == "hysteria2" then + return (server.fast_open == "1") and true or nil + else + return nil + end + end)(), -- XHTTP Tcp Fast Open + tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP + Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP + tcpcongestion = server.custom_tcpcongestion, -- 连接æœåŠ¡å™¨èŠ‚ç‚¹çš„ TCP 拥塞控制算法 + -- 出站的 dialerProxy(与 fragment 中的 tag ä¿æŒä¸€è‡´ï¼‰ + dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and + ((remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id) or nil + } + } or nil, + mux = (server.v2ray_protocol ~= "hysteria2" and server.v2ray_protocol ~= "wireguard") and { + -- mux + enabled = (server.mux == "1"), -- Mux + concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并å‘连接数 + xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并å‘连接数 + xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代ç†çš„ UDP/443 æµé‡å¤„ç†æ–¹å¼ + } or nil + } +} + +if xray_builtin_dns then + table.insert(Xray.outbounds, { + protocol = "dns", + tag = "builtin-dns-out", + settings = { + network = "tcp", + address = xray_builtin_dns.address, + port = xray_builtin_dns.port + } + }) + Xray.routing = Xray.routing or {} + Xray.routing.rules = Xray.routing.rules or {} + table.insert(Xray.routing.rules, { + type = "field", + inboundTag = { "builtin-dns-in" }, + outboundTag = "builtin-dns-out" + }) +end + +-- 添加带有 fragment 设置的 dialerproxy é…ç½® +if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.enabled ~= "0") then + local n_domainstrategy = xray_noise.domainStrategy + table.insert(Xray.outbounds, { + protocol = "freedom", + tag = (remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id, + settings = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and n_domainstrategy and n_domainstrategy ~= "" and { + domainStrategy = n_domainstrategy + } or nil, + streamSettings = { + sockopt = { + mark = 255, + tcpFastOpen = (function() + if server.transport == "xhttp" then + return (server.fast_open == "1") and true or false + elseif server.v2ray_protocol == "hysteria2" then + return (server.fast_open == "1") and true or nil + else + return nil + end + end)(), -- XHTTP Tcp Fast Open + tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP + Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP + tcpcongestion = server.custom_tcpcongestion -- 连接æœåŠ¡å™¨èŠ‚ç‚¹çš„ TCP 拥塞控制算法 + } + } + }) +end + +local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA" +local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384" +local trojan = { + log_level = 3, + run_type = (proto == "nat" or proto == "tcp") and "nat" or "client", + local_addr = "0.0.0.0", + local_port = tonumber(local_port), + remote_addr = server.server, + remote_port = tonumber(server.server_port), + udp_timeout = 60, + -- 传入连接 + password = {server.password}, + -- 传出连接 + ssl = { + verify = (server.insecure == "0") and true or false, + verify_hostname = (server.tls == "1") and true or false, + cert = (server.certificate) and server.certpath or nil, + cipher = cipher, + cipher_tls13 = cipher13, + sni = server.tls_host, + alpn = (server.tls == "1") and (function() + local alpn = {} + if server.tls_alpn and server.tls_alpn ~= "" then + string.gsub(server.tls_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + end + if #alpn > 0 then + return alpn + else + return nil + end + end)() or {"h2", "http/1.1"}, + curve = "", + reuse_session = true, + session_ticket = (server.tls_sessionTicket == "1") and true or false + }, + tcp = { + -- tcp + no_delay = true, + keep_alive = true, + reuse_port = true, + fast_open = (server.fast_open == "1") and true or false, + fast_open_qlen = 20 + } +} +local naiveproxy = { + proxy = (server.username and server.password and server.server and server.server_port) and "https://" .. server.username .. ":" .. server.password .. "@" .. format_host_port(server.server, server.server_port), + listen = (proto == "redir") and "redir" .. "://0.0.0.0:" .. tonumber(local_port) or "socks" .. "://0.0.0.0:" .. tonumber(local_port), + ["insecure-concurrency"] = tonumber(server.concurrency) or 1 +} +local ss = { + server = (server.kcp_enable == "1") and "127.0.0.1" or server.server, + server_port = tonumber(server.server_port), + local_address = "0.0.0.0", + local_port = tonumber(local_port), + mode = (proto == "tcp,udp") and "tcp_and_udp" or (proto .. "_only"), + password = server.password, + method = server.encrypt_method_ss, + timeout = tonumber(server.timeout), + fast_open = (server.fast_open == "1") and true or false, + reuse_port = true +} +local hysteria2 = { + server = ( + server.server_port and + ( + server.port_range and + (format_host_port(server.server, server.server_port) .. "," .. string.gsub(server.port_range, ":", "-")) + or + (format_host_port(server.server, server.server_port)) + ) + or + ( + server.port_range and + format_host(server.server) .. ":" .. string.gsub(server.port_range, ":", "-") + or + server.server and format_host_port(server.server, "443") + ) + ), + bandwidth = (server.uplink_capacity or server.downlink_capacity) and { + up = tonumber(server.uplink_capacity) and tonumber(server.uplink_capacity) .. " mbps" or nil, + down = tonumber(server.downlink_capacity) and tonumber(server.downlink_capacity) .. " mbps" or nil + } or nil, + socks5 = (proto:find("tcp") and tonumber(socks_port) and tonumber(socks_port) ~= 0) and { + listen = "0.0.0.0:" .. tonumber(socks_port), + disableUDP = false + } or nil, + transport = { + type = server.transport_protocol or "udp", + udp = server.port_range and (function() + local udp = {} + local t = server.hopinterval + if not t then return nil end + if t:find("-", 1, true) then + local min, max = t:match("^(%d+)%-(%d+)$") + min = tonumber(min) + max = tonumber(max) + if min and max then + min = (min >= 5) and min or 5 + max = (max >= min) and max or min + udp.minHopInterval = min .. "s" + udp.maxHopInterval = max .. "s" + return udp + end + end + t = tonumber((t or "30"):match("^%d+")) + t = (t and t >= 5) and t or 30 + udp.hopInterval = t .. "s" + return udp + end)() or nil + }, +--[[ + tcpTProxy = (proto:find("tcp") and local_port ~= "0") and { + listen = "0.0.0.0:" .. tonumber(local_port) + } or nil, +]]-- + tcpRedirect = (proto:find("tcp") and local_port ~= "0") and { + listen = "0.0.0.0:" .. tonumber(local_port) + } or nil, + udpTProxy = (proto:find("udp") and local_port ~= "0") and { + listen = "0.0.0.0:" .. tonumber(local_port) + } or nil, + obfs = (server.flag_obfs == "1") and { + type = server.obfs_type, + salamander = { password = server.salamander } + } or nil, + quic = (server.flag_quicparam == "1" ) and { + initStreamReceiveWindow = (server.initstreamreceivewindow and server.initstreamreceivewindow or nil), + maxStreamReceiveWindow = (server.maxstreamreceivewindow and server.maxstreamreceivewindow or nil), + initConnReceiveWindow = (server.initconnreceivewindow and server.initconnreceivewindow or nil), + maxConnReceiveWindow = (server.maxconnreceivewindow and server.maxconnreceivewindow or nil), + maxIdleTimeout = (tonumber(server.maxidletimeout) and tonumber(server.maxidletimeout) .. "s" or nil), + keepAlivePeriod = (tonumber(server.keepaliveperiod) and tonumber(server.keepaliveperiod) .. "s" or nil), + disablePathMTUDiscovery = (server.disablepathmtudiscovery == "1") and true or false + } or nil, + auth = server.hy2_auth, + tls = (server.tls_host and server.tls_host ~= "") and { + sni = server.tls_host, + alpn = (server.tls_alpn and server.tls_alpn ~= "") and (function() + local alpn = {} + string.gsub(server.tls_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then + return alpn + else + return nil + end + end)() or nil, + --sni = server.tls_host or (server.tls_host and server.tls_alpn) or nil, + insecure = (server.insecure == "1") and true or false, + pinSHA256 = server.pinsha256 or nil + } or { + sni = server.server, + alpn = (server.type == "hysteria2") and (function() + local alpn = {} + if server.tls_alpn and server.tls_alpn ~= "" then + string.gsub(server.tls_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + end + if #alpn > 0 then + return alpn + else + return nil + end + end)() or nil, + insecure = (server.insecure == "1") and true or false, + pinSHA256 = server.pinsha256 or nil + }, + fast_open = (server.fast_open == "1") and true or false, + lazy = (server.lazy_mode == "1") and true or false +} +local shadowtls = { + client = { + server_addr = server.server_port and format_host_port(server.server, server.server_port) or nil, + listen = "127.0.0.1:" .. tonumber(local_port), + tls_names = server.shadowtls_sni, + password = server.password + }, + v3 = (server.shadowtls_protocol == "v3") and true or false, + disable_nodelay = (server.disable_nodelay == "1") and true or false, + fastopen = (server.fastopen == "1") and true or false, + strict = (server.strict == "1") and true or false +} +local chain_sslocal = { + locals = local_port ~= "0" and { + { + local_address = "0.0.0.0", + local_port = (chain_local_port == "0" and effective_node_local_port or tonumber(chain_local_port)), + mode = (proto:find("tcp,udp") and "tcp_and_udp") or proto .. "_only", + protocol = "redir", + tcp_redir = "redirect", + --tcp_redir = "tproxy", + udp_redir = "tproxy" + }, + socks_port ~= "0" and { + protocol = "socks", + local_address = "0.0.0.0", + local_port = tonumber(socks_port) + } or nil + } or {{ + protocol = "socks", + local_address = "0.0.0.0", + local_port = tonumber(socks_port) + }}, + servers = { + { + server = "127.0.0.1", + server_port = (tonumber(local_port) == 0 and tonumber(chain_local_port) or tonumber(local_port)), + method = server.sslocal_method, + password = server.sslocal_password + } + } +} +local chain_vmess = { + inbounds = (local_port ~= "0") and { + { + port = (chain_local_port == "0" and effective_node_local_port or tonumber(chain_local_port)), + protocol = "dokodemo-door", + settings = { + network = proto, + followRedirect = true + }, + streamSettings = { + sockopt = {tproxy = "redirect"} + }, + sniffing = { + enable = true, + destOverride = {"http","tls"} + } + }, + (proto:find("tcp") and socks_port ~= "0") and { + protocol = "socks", + port = tonumber(socks_port) + } or nil + } or { protocol = "socks", port = tonumber(socks_port) }, + outbound = { + protocol = "vmess", + settings = { + vnext = {{ + address = "127.0.0.1", + port = (tonumber(local_port) == 0 and tonumber(chain_local_port) or tonumber(local_port)), + users = {{ + id = (server.vmess_uuid), + security = server.vmess_method, + level = 0 + }} + }} + } + } +} +local tuic = { + relay = { + server = server.server_port and format_host_port(server.server, server.server_port), + ip = server.tuic_ip, + uuid = server.tuic_uuid, + password = server.tuic_passwd, + certificates = server.certificate and { server.certpath } or nil, + udp_relay_mode = server.udp_relay_mode, + congestion_control = server.congestion_control, + heartbeat = server.heartbeat and tonumber(server.heartbeat) .. "s" or nil, + timeout = server.timeout and tonumber(server.timeout) .. "s" or nil, + gc_interval = server.gc_interval and tonumber(server.gc_interval) .. "s" or nil, + gc_lifetime = server.gc_lifetime and tonumber(server.gc_lifetime) .. "s" or nil, + alpn = (server.tuic_alpn and server.tuic_alpn ~= "") and (function() + local alpn = {} + string.gsub(server.tuic_alpn, '[^,]+', function(w) + table.insert(alpn, w) + end) + if #alpn > 0 then + return alpn + else + return nil + end + end)() or nil, + ipstack_prefer = (server.tuic_dual_stack == "1") and server.ipstack_prefer or nil, + skip_cert_verify = (server.insecure == "1" or server.insecure == true or server.insecure == "true"), + disable_sni = (server.disable_sni == "1") and true or false, + zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false, + send_window = tonumber(server.send_window), + receive_window = tonumber(server.receive_window) + }, + ["local"] = { + server = tonumber(socks_port) and "[::]:" .. (socks_port == "0" and local_port or tonumber(socks_port)), + dual_stack = (server.tuic_dual_stack == "1") and true or nil, + max_packet_size = tonumber(server.tuic_max_package_size) + } +} + +local config = {} +function config:new(o) + o = o or {} + setmetatable(o, self) + self.__index = self + return o +end +function config:handleIndex(index) + local switch = { + ss = function() + ss.protocol = socks_port + if server.enable_plugin == "1" and server.plugin and server.plugin ~= "none" then + if server.plugin == "custom" then + ss.plugin = server.custom_plugin + else + ss.plugin = server.plugin + end + ss.plugin_opts = server.plugin_opts or nil + end + print(json.stringify(ss, 1)) + end, + ssr = function() + ss.protocol = server.protocol + ss.protocol_param = server.protocol_param + ss.method = server.encrypt_method + ss.obfs = server.obfs + ss.obfs_param = server.obfs_param + print(json.stringify(ss, 1)) + end, + v2ray = function() + print(json.stringify(Xray, 1)) + end, + trojan = function() + print(json.stringify(trojan, 1)) + end, + naiveproxy = function() + print(json.stringify(naiveproxy, 1)) + end, + hysteria2 = function() + print(json.stringify(hysteria2, 1)) + end, + shadowtls = function() + local chain_switch = { + sslocal = function() + if (chain:find("chain")) then + print(json.stringify(chain_sslocal, 1)) + else + print(json.stringify(shadowtls, 1)) + end + end, + vmess = function() + if (chain:find("chain")) then + print(json.stringify(chain_vmess, 1)) + else + print(json.stringify(shadowtls, 1)) + end + end + } + local ChainType = server.chain_type + if chain_switch[ChainType] then + chain_switch[ChainType]() + end + end, + tuic = function() + print(json.stringify(tuic, 1)) + end + } + if switch[index] then + switch[index]() + end +end +local f = config:new() +f:handleIndex(server.type) diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh new file mode 100755 index 00000000..fa168826 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +. $IPKG_INSTROOT/etc/init.d/shadowsocksr + +check_run_environment + +case "$USE_TABLES" in + nftables) + nft_support=1 + echolog "gfw2ipset: Using nftables" + ;; + iptables) + nft_support=0 + echolog "gfw2ipset: Using iptables" + ;; + *) + echolog "ERROR: No supported firewall backend detected" + exit 1 + ;; +esac +mkdir -p $TMP_DNSMASQ_PATH + +run_mode=$(normalize_run_mode) + +cp -rf /etc/ssrplus/gfw_list.conf $TMP_DNSMASQ_PATH/ +cp -rf /etc/ssrplus/gfw_base.conf $TMP_DNSMASQ_PATH/ + +for conf_file in gfw_base.conf gfw_list.conf; do + conf="$TMP_DNSMASQ_PATH/$conf_file" + [ -f "$conf" ] || continue + + if [ "$run_mode" = "gfw" ]; then + if [ "$nft_support" = "1" ]; then + # gfw + nft:ipset → nftset + sed -i 's|ipset=/\([^/]*\)/\([^[:space:]]*\)|nftset=/\1/inet#ss_spec#\2|g' "$conf" + fi + else + # éž gfw:无æ¡ä»¶æ¸…ç†æ‰€æœ‰åˆ†æµå¼•用 + # sed -i '/^[[:space:]]*\(ipset=\|nftset=\)/d' "$conf" + sed -i '/^[[:space:]]*ipset=/d' "$conf" + fi +done + +# 此处使用 for æ–¹å¼è¯»å– 防止 /etc/ssrplus/ 目录下的 black.list white.list deny.list ç­‰2个或多个文件一行中存在空格 比如:# abc.com 而丢失:server +# Optimize: Batch filter using grep +for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do + if [ -s "$list_file" ]; then + # æ¸…ç†æ³¨é‡Šå’Œç©ºè¡Œ + grep -vE '^\s*#|^\s*$' "$list_file" | sed 's/\r//g' > "${list_file}.clean" + if [ -s "${list_file}.clean" ]; then + for target_file in "$TMP_DNSMASQ_PATH/gfw_list.conf" "$TMP_DNSMASQ_PATH/gfw_base.conf"; do + [ -f "$target_file" ] || continue + tmp_file="${target_file}.tmp" + awk -v list="${list_file}.clean" ' + BEGIN { + while ((getline line < list) > 0) { + gsub(/\r/, "", line) + if (line != "") { + domain[line] = 1 + # åŒæ—¶æ”¯æŒ *.domain + domain["*." line] = 1 + } + } + close(list) + } + { + # æå– server=/domain/xxx + if (match($0, /^server=\/([^\/]+)\//, m)) { + if (m[1] in domain) next + } + # æå– ipset=/domain/xxx + if (match($0, /^ipset=\/([^\/]+)\//, m)) { + if (m[1] in domain) next + } + print + } + ' "$target_file" > "$tmp_file" + mv "$tmp_file" "$target_file" + done + fi + rm -f "${list_file}.clean" + fi +done + +# 此处直接使用 cat 因为有 sed '/#/d' 删除了 æ•°æ® +if [ "$nft_support" = "1" ]; then + cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nnftset=\/&\/inet#ss_spec#blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf + cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nnftset=\/&\/inet#ss_spec#whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf +elif [ "$nft_support" = "0" ]; then + cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nipset=\/&\/blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf + cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nipset=\/&\/whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf +fi +cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf + +if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then + cp -f /etc/ssrplus/ad.conf "$TMP_DNSMASQ_PATH/" + if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then + for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do + if [ -s "$list_file" ]; then + # æ¸…ç†æ³¨é‡Š & 空行 + grep -vE '^\s*#|^\s*$' "$list_file" | sed 's/\r//g' > "${list_file}.clean" + if [ -s "${list_file}.clean" ]; then + tmp_file="$TMP_DNSMASQ_PATH/ad.conf.tmp" + awk -v list="${list_file}.clean" ' + BEGIN { + while ((getline line < list) > 0) { + gsub(/\r/, "", line) + if (line != "") { + domain[line] = 1 + # æ”¯æŒæ³›åŸŸå + domain["*." line] = 1 + } + } + close(list) + } + { + keep = 1 + # ç²¾ç¡®åŒ¹é… server=/domain/ + if (match($0, /^server=\/([^\/]+)\//, m)) { + if (m[1] in domain) keep = 0 + } + # ç²¾ç¡®åŒ¹é… ipset=/domain/ + if (match($0, /^ipset=\/([^\/]+)\//, m)) { + if (m[1] in domain) keep = 0 + } + if (keep) print + } + ' "$TMP_DNSMASQ_PATH/ad.conf" > "$tmp_file" + mv "$tmp_file" "$TMP_DNSMASQ_PATH/ad.conf" + fi + rm -f "${list_file}.clean" + fi + done + fi +else + rm -f "$TMP_DNSMASQ_PATH/ad.conf" +fi diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/shadowsocksr.config b/luci-app-ssr-plus/root/usr/share/shadowsocksr/shadowsocksr.config new file mode 100644 index 00000000..6d1d5ac1 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/shadowsocksr.config @@ -0,0 +1,67 @@ + +config global + option global_server 'nil' + option threads '0' + option run_mode 'router' + option dports '2' + option custom_ports '80,443' + option pdnsd_enable '1' + option filter_aaaa '1' + option tunnel_forward '8.8.4.4:53' + option monitor_enable '1' + option enable_switch '1' + option switch_time '667' + option switch_timeout '5' + option switch_try_count '3' + option default_node_local_port '1234' + option component_mirror 'direct' + option gfwlist_url 'https://fastly.jsdelivr.net/gh/YW5vbnltb3Vz/domain-list-community@release/gfwlist.txt' + option chnroute_url 'https://ispip.clang.cn/all_cn.txt' + option adblock_url 'https://anti-ad.net/anti-ad-for-dnsmasq.conf' + +config server_subscribe + option proxy '1' + option auto_update '1' + option config_auto_update_mode '0' + option config_update_interval '60' + option auto_update_week_time '*' + option auto_update_day_time '2' + option auto_update_min_time '0' + option url_test_url 'https://www.google.com/generate_204' + option user_agent 'v2rayN/9.99' + option filter_words '过期/套é¤/剩余/网å€/QQ群/官网/防失è”/回国' + +config access_control + option lan_ac_mode '0' + option router_proxy '1' + list wan_fw_ips '149.154.160.0/20' + list wan_fw_ips '67.198.55.0/24' + list wan_fw_ips '91.108.4.0/22' + list wan_fw_ips '91.108.56.0/22' + list wan_fw_ips '109.239.140.0/24' + list wan_fw_ips '8.8.8.8' + list wan_fw_ips '1.1.1.1' + list Interface 'lan' + +config socks5_proxy + option server 'nil' + option local_port '1080' + +config http_proxy + option server 'nil' + option local_port '3128' + option http_auth 'none' + +config server_global + option enable_server '0' + +config global_xray_fragment + option fragment '0' + option noise '0' + +config clash_client_group + option enabled '0' + option remarks '' + option ip_addr '' + option client_mac '' + option policy_group '' diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/ssrplusupdate.sh b/luci-app-ssr-plus/root/usr/share/shadowsocksr/ssrplusupdate.sh new file mode 100755 index 00000000..9c69b511 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/ssrplusupdate.sh @@ -0,0 +1,43 @@ +#!/bin/sh +LOCK_DIR="/var/run/ssrplusupdate.lock" +LOOP_STAMP="/var/run/ssrplusupdate.loop" +MODE="$(uci -q get shadowsocksr.@server_subscribe[0].config_auto_update_mode 2>/dev/null || echo 0)" + +mkdir "$LOCK_DIR" 2>/dev/null || exit 0 +trap 'rmdir "$LOCK_DIR" 2>/dev/null' EXIT INT TERM + +if [ "$1" = "loop" ]; then + [ "$(uci -q get shadowsocksr.@server_subscribe[0].auto_update 2>/dev/null || echo 0)" = "1" ] || exit 0 + [ "$MODE" = "1" ] || exit 0 + + INTERVAL="$(uci -q get shadowsocksr.@server_subscribe[0].config_update_interval 2>/dev/null || echo 60)" + case "$INTERVAL" in + ''|*[!0-9]*) + INTERVAL=60 + ;; + esac + [ "$INTERVAL" -gt 0 ] 2>/dev/null || INTERVAL=60 + + NOW="$(date +%s)" + LAST_RUN=0 + [ -f "$LOOP_STAMP" ] && LAST_RUN="$(cat "$LOOP_STAMP" 2>/dev/null || echo 0)" + case "$LAST_RUN" in + ''|*[!0-9]*) + LAST_RUN=0 + ;; + esac + + if [ $((NOW - LAST_RUN)) -lt $((INTERVAL * 60)) ]; then + exit 0 + fi +fi + +/usr/bin/lua /usr/share/shadowsocksr/update.lua +sleep 2s +/usr/share/shadowsocksr/chinaipset.sh /var/etc/ssrplus/china_ssr.txt +sleep 2s +/usr/bin/lua /usr/share/shadowsocksr/subscribe.lua + +if [ "$1" = "loop" ]; then + date +%s > "$LOOP_STAMP" +fi diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua b/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua new file mode 100755 index 00000000..05acd8b7 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua @@ -0,0 +1,2253 @@ +#!/usr/bin/lua + +------------------------------------------------ +-- This file is part of the luci-app-ssr-plus subscribe.lua +-- @author William Chan +------------------------------------------------ +require "luci.model.uci" +require "nixio" +require "luci.util" +require "luci.sys" +require "luci.jsonc" + +-- these global functions are accessed all the time by the event handler +-- so caching them is worth the effort +local tinsert = table.insert +local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub +local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify +local b64decode = nixio.bin.b64decode +local b64encode = nixio.bin.b64encode +local URL = require "url" +local cache = {} +local nodeResult = setmetatable({}, {__index = cache}) -- update result +local name = 'shadowsocksr' +local uciType = 'servers' +local ucic = require "luci.model.uci".cursor() +local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0') +local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1') +local allow_insecure = ucic:get_first(name, 'server_subscribe', 'allow_insecure', '0') +local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期/套é¤/剩余/网å€/QQ群/官网/防失è”/回国') +local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '') +local user_agent = ucic:get_first(name, 'server_subscribe', 'user_agent', 'v2rayN/9.99') +local local_clash_dir = "/etc/ssrplus/clash" +local target_subscribe_sid = tostring(arg and arg[1] or ""):gsub("^%s*(.-)%s*$", "%1") + +local has_ss_rust = luci.sys.exec('type -t -p sslocal 2>/dev/null || type -t -p ssserver 2>/dev/null') ~= "" +local has_xray = luci.sys.exec('type -t -p xray 2>/dev/null') ~= "" +local has_mihomo = luci.sys.exec('type -t -p mihomo -p /usr/libexec/mihomo 2>/dev/null') ~= "" + +local tuic_type = luci.sys.exec('type -t -p mihomo -p /usr/libexec/mihomo 2>/dev/null') ~= "" and "tuic" +local log = function(...) + print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " ")) +end + +local function preferred_ss_backend() + if has_mihomo then + return "ss" + end + if has_ss_rust then + return "ss-rust" + end + if has_xray then + return "v2ray" + end + return nil +end + +local encrypt_methods_ss = { + -- plain + "none", + "plain", + -- aead + "aes-128-gcm", + "aes-192-gcm", + "aes-256-gcm", + "chacha20-ietf-poly1305", + "xchacha20-ietf-poly1305", + -- aead 2022 + "2022-blake3-aes-128-gcm", + "2022-blake3-aes-256-gcm", + "2022-blake3-chacha20-poly1305" + --[[ stream + "table", + "rc4", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" ]]-- +} +-- 分割字符串 +local function split(full, sep) + if full == nil or type(full) ~= "string" then + -- print("Debug: split() received nil or non-string value") + return {} + end + full = full:gsub("%z", ""):gsub("^%s+", ""):gsub("%s+$", "") -- 去除首尾空白字符和\0 + if full == "" then + -- print("Debug: split() received empty string after trimming") + return {} + end + sep = sep or "," -- 默认分隔符 + local off, result = 1, {} + while true do + local nStart, nEnd = full:find(sep, off) + if not nEnd then + local res = ssub(full, off, slen(full)) + if #res > 0 then -- 过滤掉 \0 + tinsert(result, res) + end + break + else + tinsert(result, ssub(full, off, nStart - 1)) + off = nEnd + 1 + end + end + return result +end +-- urlencode +local function get_urlencode(c) + return sformat("%%%02X", sbyte(c)) +end + +local function urlEncode(szText) + local str = szText:gsub("([^0-9a-zA-Z ])", get_urlencode) + str = str:gsub(" ", "+") + return str +end + +local function get_urldecode(h) + return schar(tonumber(h, 16)) +end +local function UrlDecode(szText) + return szText:gsub("+", " "):gsub("%%(%x%x)", get_urldecode) +end + +-- trim +local function trim(text) + if not text or text == "" then + return "" + end + return (sgsub(text, "^%s*(.-)%s*$", "%1")) +end + +local function shell_quote(value) + value = tostring(value or "") + return "'" .. value:gsub("'", "'\\''") .. "'" +end + +local function nft_string_literal(value) + value = tostring(value or "") + value = value:gsub("\\", "\\\\"):gsub('"', '\\"') + return '"' .. value .. '"' +end + +local function escape_lua_pattern(value) + return tostring(value or ""):gsub("([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1") +end + +local function is_true_value(v) + if v == nil then + return false + end + if v == true then + return true + end + if type(v) == "string" then + local s = trim(string.lower(v)) + return s == "1" or s == "true" or s == "yes" or s == "on" + end + return false +end + +local function collect_subscribe_items() + local items = {} + + ucic:foreach(name, "server_subscribe_item", function(s) + if target_subscribe_sid ~= "" and s[".name"] ~= target_subscribe_sid then + return + end + + local url = trim(s.url or "") + if url == "" then + return + end + + if target_subscribe_sid == "" and not is_true_value(s.enabled or "1") then + return + end + + items[#items + 1] = { + sid = s[".name"], + alias = trim(s.alias or ""), + url = url + } + end) + + if #items > 0 then + return items + end + + if target_subscribe_sid ~= "" then + return items + end + + local legacy_urls = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {}) + for index, url in ipairs(legacy_urls or {}) do + url = trim(url) + if url ~= "" then + items[#items + 1] = { + sid = "legacy_" .. index, + alias = "Legacy " .. index, + url = url + } + end + end + + return items +end + +local subscribe_items = collect_subscribe_items() + +local function first_nonempty(tbl, keys) + for _, key in ipairs(keys) do + local value = tbl[key] + if value ~= nil and value ~= "" then + return value + end + end + return nil +end + +local function normalize_host(value) + value = trim(value or "") + if value == "" then + return value + end + if value:match("^%[.*%]$") then + return value:sub(2, -2) + end + return value +end + +local function parse_host_port(value, default_port) + value = trim(value or "") + if value == "" then + return nil, default_port + end + + local host, port = value:match("^%[(.*)%]:(%d+)$") + if host then + return normalize_host(host), port + end + + host, port = value:match("^(.-):(%d+)$") + if host and host ~= "" and not host:find(":", 1, true) then + return normalize_host(host), port + end + + if value:find(":", 1, true) then + return normalize_host(value), default_port + end + + return normalize_host(value), default_port +end +-- md5 +local function md5(content) + local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1') + -- assert(nixio.errno() == 0) + return trim(stdout) +end +-- base64 è§£ç  +local function base64Decode(text) + local raw = text + if not text or text == "" then + return '' + end + text = text:gsub("%z", "") + text = text:gsub("%c", "") + text = text:gsub("%s", "") + text = text:gsub("_", "/") + text = text:gsub("-", "+") + text = text:gsub("=", "") + local mod4 = #text % 4 + text = text .. string.sub('====', mod4 + 1) + local result = b64decode(text) + if result then + return result:gsub("%z", "") + else + return raw + end +end +-- base64 ç¼–ç  +local function base64Encode(text) + if not text or text == "" then + return '' + end + local result = b64encode(text) + if result then + result = result:gsub("%z", "") + return result + else + return text + end +end +-- 检查数组(table)中是å¦å­˜åœ¨æŸä¸ªå­—符值 +-- https://www.04007.cn/article/135.html +local function checkTabValue(tab) + local revtab = {} + for k,v in pairs(tab) do + revtab[v] = true + end + return revtab +end +-- JSON完整性检查 +local function isCompleteJSON(str) + -- 检查JSONæ ¼å¼ + if type(str) ~= "string" or str:match("^%s*$") then + return false + end + -- å°è¯•è§£æžJSON验è¯å®Œæ•´æ€§ + local success, _ = pcall(jsonParse, str) + return success +end + +local function isClashYAML(str) + if type(str) ~= "string" or str:match("^%s*$") then + return false + end + + for line in str:gmatch("[^\r\n]+") do + if line:match("^%s*proxies%s*:") or line:match("^%s*proxy%-providers%s*:") then + return true + end + end + + return false +end + +local function processClashSubscription(url) + local ok, parsed = pcall(URL.parse, url) + if not ok or not parsed or not parsed.host then + return nil + end + + local alias = "Clash_" .. parsed.host + local server_port = parsed.port or ((parsed.scheme == "http") and "80" or "443") + local result = { + type = "clash", + server = normalize_host(parsed.host), + server_port = server_port, + clash_url = url, + clash_user_agent = user_agent, + raw_alias = alias, + alias = alias + } + + local saved_alias = result.alias + result.alias = nil + result.hashkey = md5(jsonStringify(result) .. "_" .. (saved_alias or "")) + result.alias = saved_alias + return result +end + +local function yaml_quote(str) + str = tostring(str or "") + str = str:gsub("\\", "\\\\"):gsub('"', '\\"') + return '"' .. str .. '"' +end + +local function is_ip_literal(value) + if not value or value == "" then + return false + end + + if value:match("^%d+%.%d+%.%d+%.%d+$") then + return true + end + + return value:find(":", 1, true) ~= nil +end + +local function parseAnytlsShare(content) + local alias = "" + if content:find("#", 1, true) then + local idx = content:find("#", 1, true) + alias = UrlDecode(content:sub(idx + 1)) + content = content:sub(1, idx - 1) + end + + local main, query = content, "" + if content:find("%?", 1) then + local idx = content:find("%?", 1) + main = content:sub(1, idx - 1) + query = content:sub(idx + 1) + end + + local userinfo, hostinfo = main:match("^([^@]+)@(.+)$") + if not userinfo or not hostinfo then + return nil + end + + local password = UrlDecode(userinfo) + local server, port = hostinfo:match("^(.+):(%d+)$") + if not server or not port then + server = hostinfo + port = "443" + end + server = server:gsub("^%[", ""):gsub("%]$", "") + + local params = {} + for _, v in ipairs(split(query, "&")) do + local t = split(v, "=") + if #t > 1 then + params[string.lower(t[1])] = UrlDecode(t[2] or "") + end + end + + return { + name = (alias ~= "" and alias) or (server .. ":" .. port), + server = server, + port = tonumber(port), + password = password, + sni = (function() + local sni = params.sni or params.servername or "" + if is_ip_literal(sni) then + return "" + end + return sni + end)(), + allow_insecure = (params.insecure == "1" or params.allow_insecure == "1" or params.allowinsecure == "1"), + client_fingerprint = params.fp or params.fingerprint or "" + } +end + +local function buildAnytlsClashYaml(entries, group_name) + local lines = { + "mode: rule", + "log-level: silent", + "proxies:" + } + + for _, node in ipairs(entries) do + lines[#lines + 1] = " - name: " .. yaml_quote(node.name) + lines[#lines + 1] = " type: anytls" + lines[#lines + 1] = " server: " .. yaml_quote(node.server) + lines[#lines + 1] = " port: " .. tostring(node.port) + lines[#lines + 1] = " password: " .. yaml_quote(node.password) + if node.sni and node.sni ~= "" then + lines[#lines + 1] = " sni: " .. yaml_quote(node.sni) + end + if node.allow_insecure then + lines[#lines + 1] = " skip-cert-verify: true" + end + if node.client_fingerprint and node.client_fingerprint ~= "" then + lines[#lines + 1] = " client-fingerprint: " .. yaml_quote(node.client_fingerprint) + end + end + + lines[#lines + 1] = "proxy-groups:" + lines[#lines + 1] = " - name: " .. yaml_quote(group_name) + lines[#lines + 1] = " type: select" + lines[#lines + 1] = " proxies:" + for _, node in ipairs(entries) do + lines[#lines + 1] = " - " .. yaml_quote(node.name) + end + lines[#lines + 1] = "rules:" + lines[#lines + 1] = " - MATCH," .. group_name + + return table.concat(lines, "\n") .. "\n" +end + +local function processLocalClashSubscription(path, alias) + local result = { + type = "clash", + server = "127.0.0.1", + server_port = "0", + clash_path = path, + clash_user_agent = user_agent, + raw_alias = alias, + alias = alias + } + + local saved_alias = result.alias + result.alias = nil + result.hashkey = md5(jsonStringify(result) .. "_" .. (saved_alias or "")) + result.alias = saved_alias + return result +end +-- å¤„ç†æ•°æ® +local function processData(szType, content, cfgid) + local result = {type = szType, kcp_param = '--nocomp'} + -- 检查JSON的格å¼å¦‚ä¸å®Œæ•´ä¸¢å¼ƒ + if not (szType == "sip008" or szType == "ssd") then + if not isCompleteJSON(content) then + return nil + end + end + + if szType == "hysteria2" or szType == "hy2" then + local url = URL.parse("http://" .. content) + local params = url.query + + if not has_xray then + return nil + end + + result.type = "v2ray" + result.v2ray_protocol = "hysteria2" + if params.fm and params.fm ~= "" then + result.enable_finalmask = "1" + result.finalmask = base64Encode(params.fm) + end + if (params.security and params.security:lower() == "tls") + or (params.sni and params.sni ~= "") + or (params.alpn and params.alpn ~= "") + or (params.pcs or params.vcn) then + result.tls = "1" + if params.sni then + result.tls_host = params.sni + end + if params.alpn and params.alpn ~= "" then + local alpn = {} + for v in params.alpn:gmatch("[^,;|%s]+") do + table.insert(alpn, v) + end + if #alpn > 0 then + result.tls_alpn = table.concat(alpn, ",") + end + end + if params.pcs then + result.tls_CertSha = params.pcs + end + if params.vcn then + result.tls_CertByName = params.vcn + end + end + + local raw_alias = url.fragment and UrlDecode(url.fragment) or nil + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + result.server = normalize_host(url.host) + result.server_port = url.port or 443 + result.hy2_auth = url.user + + if params.mport then + result.flag_port_hopping = "1" + result.port_range = params.mport + end + result.uplink_capacity = tonumber((params.upmbps or ""):match("^(%d+)")) or nil + result.downlink_capacity = tonumber((params.downmbps or ""):match("^(%d+)")) or nil + if params.obfs and params.obfs ~= "none" then + result.flag_obfs = "1" + result.obfs_type = params.obfs + result.salamander = params["obfs-password"] or params["obfs_password"] + end + if params.allowInsecure or params.insecure then + local insecure = params.allowInsecure or params.insecure + if insecure == true or insecure == "1" or insecure == "true" then + result.insecure = "1" + end + end + if params.tfo then + -- å¤„ç† fast open 傿•° + result.fast_open = params.tfo + end + elseif szType == 'ssr' then + -- 去掉å‰åŽç©ºç™½å’Œ#注释 + local link = trim(content:gsub("#.*$", "")) + local dat = split(link, "/%?") + local host, port, rest + local hostinfo = dat[1] or '' + if hostinfo:find("^%[.*%]:") then + host, port, rest = hostinfo:match("^%[(.*)%]:(%d+):(.*)$") + else + host, port, rest = hostinfo:match("^(.-):(%d+):(.*)$") + end + + result.type = 'ssr' + local ssr_parts = split(rest or '', ':') + result.server = normalize_host(host or '') + result.server_port = port or '' + result.protocol = ssr_parts[1] or '' + result.encrypt_method = ssr_parts[2] or '' + result.obfs = ssr_parts[3] or '' + result.password = base64Decode(ssr_parts[4] or '') + + local params = {} + if dat[2] and dat[2] ~= '' then + for _, v in pairs(split(dat[2], '&')) do + local t = split(v, '=') + if t[1] and t[2] then + params[t[1]] = t[2] + end + end + end + + result.obfs_param = base64Decode(params.obfsparam or '') + result.protocol_param = base64Decode(params.protoparam or '') + + if params.tfo then + -- å¤„ç† fast open 傿•° + result.fast_open = params.tfo + end + + local group = base64Decode(params.group or '') + local remarks = base64Decode(params.remarks or '') + + -- 拼接 alias + local raw_alias = "" + if group ~= "" then + raw_alias = "[" .. group .. "] " + end + raw_alias = raw_alias .. remarks + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + elseif szType == "vmess" then + -- 去掉å‰åŽç©ºç™½å’Œæ³¨é‡Š + local link = trim(content:gsub("#.*$", "")) + + -- Base64 è§£ç  + local decoded = base64Decode(link) + if not decoded or decoded == "" then + return nil + end + + -- è§£æž JSON + local ok, info = pcall(jsonParse, decoded) + if not ok or type(info) ~= "table" then + return nil + end + + -- åŸºæœ¬ä¿¡æ¯ + result.type = 'v2ray' + result.v2ray_protocol = 'vmess' + result.server = info.add + result.server_port = info.port + result.alter_id = info.aid + result.vmess_id = info.id + result.raw_alias = info.ps -- 新增 + result.alias = info.ps -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + + -- 调整传输åè®® + if info.net == "tcp" then + info.net = "raw" + end + if info.net == "splithttp" then + info.net = "xhttp" + end + result.transport = info.net + + -- result.mux = 1 + -- result.concurrency = 8 + if info.net == 'ws' then + result.ws_host = info.host + result.ws_path = info.path + end + if info.net == 'httpupgrade' then + result.httpupgrade_host = info.host + result.httpupgrade_path = info.path + end + if info.net == 'xhttp' or info.net == 'splithttp' then + result.xhttp_mode = info.mode + result.xhttp_host = info.host + result.xhttp_path = info.path + -- 检查 extra 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if info.extra and info.extra ~= "" then + result.enable_xhttp_extra = "1" + result.xhttp_extra = base64Encode(info.extra) + end + -- å°è¯•è§£æž JSON æ•°æ® + local success, Data = pcall(jsonParse, info.extra or "") + if success and type(Data) == "table" then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") + else + -- 如果解æžå¤±è´¥ï¼Œæ¸…ç©ºä¸‹è½½åœ°å€ + result.download_address = nil + end + end + if info.net == 'h2' then + result.h2_host = info.host + result.h2_path = info.path + end + if info.net == 'raw' or info.net == 'tcp' then + result.tcp_guise = info.type or "none" + if result.tcp_guise == "http" then + result.http_host = info.host + result.http_path = info.path + end + end + if info.net == 'kcp' then + result.kcp_guise = info.type or "none" + if info.type and info.type == "dns" then + result.kcp_guise = info.host or "" + end + result.seed = params.seed + end + if info.net == 'grpc' then + if info.path then + result.serviceName = info.path + elseif info.serviceName then + result.serviceName = info.serviceName + end + end + if info.net == 'quic' then + result.quic_guise = info.type + result.quic_key = info.key + result.quic_security = info.security + end + if info.security then + result.security = info.security + end + if info.fm and info.fm ~= "" then + info.fm = UrlDecode(info.fm) + result.enable_finalmask = "1" + result.finalmask = base64Encode(info.fm) + end + if info.tls == "tls" or info.tls == "1" then + result.tls = "1" + result.fingerprint = info.fp + if info.alpn and info.alpn ~= "" then + local alpn = {} + for v in info.alpn:gmatch("[^,]+") do + table.insert(alpn, v) + end + if #alpn > 0 then + result.tls_alpn = table.concat(alpn, ",") -- ç¡®ä¿ä¸ºå­—符串 + end + end + if info.sni and info.sni ~= "" then + result.tls_host = info.sni + elseif info.host and info.host ~= "" then + result.tls_host = info.host + end + if info.ech and info.ech ~= "" then + result.enable_ech = "1" + result.ech_config = info.ech + end + if info.pcs and info.pcs ~= "" then + result.tls_CertSha = info.pcs + end + if info.vcn and info.vcn ~= "" then + result.tls_CertByName = info.vcn + end + -- 兼容 allowInsecure / allowlnsecure / skip-cert-verify + if info.allowInsecure or info.allowlnsecure or info.insecure or info["skip-cert-verify"] then + local insecure = info.allowInsecure or info.allowlnsecure or info.insecure or info["skip-cert-verify"] + if insecure == true or insecure == "1" or insecure == "true" then + result.insecure = "1" + end + end + else + result.tls = "0" + end + elseif szType == "ss" then + local idx_sp = content:find("#") or 0 + local alias = "" + if idx_sp > 0 then + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1):gsub("/%?", "?") + end + local raw_alias = UrlDecode(alias) + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + + -- 拆 base64 主体和 ? 傿•°éƒ¨åˆ† + local info = content + local find_index, query = info:match("^([^?]+)%??(.*)$") + --log("SS 节点格å¼:", find_index) + local params = {} + if query and query ~= "" then + for _, v in ipairs(split(query, '&')) do + local t = split(v, '=') + if #t >= 2 then + params[t[1]] = UrlDecode(t[2]) + end + end + end + + if params.tfo and params.tfo ~= "" then + -- å¤„ç† fast open 傿•° + result.fast_open = params.tfo + end + + local selected_ss_backend = preferred_ss_backend() + local xray_ss_mode = (selected_ss_backend == "v2ray") + + -- 如果最终无å¯ç”¨æ ¸å¿ƒï¼Œè·³è¿‡è¯¥è®¢é˜… + if selected_ss_backend == nil then + return nil + end + + if xray_ss_mode then + local url = URL.parse("http://" .. info) + local params = url.query + + result.type = "v2ray" + result.v2ray_protocol = "shadowsocks" + result.server = normalize_host(url.host) + result.server_port = url.port + + -- 判断 @ å‰éƒ¨åˆ†æ˜¯å¦ä¸º Base64 + local is_base64 = base64Decode(UrlDecode(url.user)) + if is_base64:find(":") then + -- æ–°æ ¼å¼ï¼šmethod:password + result.encrypt_method_ss, result.password = is_base64:match("^(.-):(.*)$") + else + -- æ—§æ ¼å¼ï¼šUUID ç›´æŽ¥ä½œä¸ºå¯†ç  + result.password = url.user + result.encrypt_method_ss = params.encryption or "none" + end + + if params.udp then + -- å¤„ç† udp 傿•° + result.uot = params.udp + end + + result.transport = params.type or "raw" + if result.transport == "tcp" then + result.transport = "raw" + end + if result.transport == "splithttp" then + result.transport = "xhttp" + end + result.tls = (params.security == "tls" or params.security == "xtls") and "1" or "0" + if params.alpn and params.alpn ~= "" then + local alpn = {} + for v in params.alpn:gmatch("[^,;|%s]+") do + table.insert(alpn, v) + end + if #alpn > 0 then + result.tls_alpn = table.concat(alpn, ",") -- ç¡®ä¿ä¸ºå­—符串 + end + end + if params.pcs and params.pcs ~= "" then + result.tls_CertSha = params.pcs + end + if params.vcn and params.vcn ~= "" then + result.tls_CertByName = params.vcn + end + result.tls_host = params.sni + result.tls_flow = (params.security == "tls" or params.security == "reality") and params.flow or nil + result.fingerprint = params.fp + result.reality = (params.security == "reality") and "1" or "0" + result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil + result.reality_shortid = params.sid + result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil + -- 检查 ech 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if params.ech and params.ech ~= "" then + result.enable_ech = "1" + result.ech_config = params.ech + end + -- 检查 finalmaskg 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if params.fm and params.fm ~= "" then + result.enable_finalmask = "1" + result.finalmask = base64Encode(params.fm) + end + -- 检查 pqv 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if params.pqv and params.pqv ~= "" then + result.enable_mldsa65verify = "1" + result.reality_mldsa65verify = params.pqv + end + if params.allowInsecure or params.insecure then + local insecure = params.allowInsecure or params.insecure + if insecure == true or insecure == "1" or insecure == "true" then + result.insecure = "1" + end + end + if result.transport == "ws" then + result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil + result.ws_path = params.path and UrlDecode(params.path) or "/" + elseif result.transport == "httpupgrade" then + result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil + result.httpupgrade_path = params.path and UrlDecode(params.path) or "/" + elseif result.transport == "xhttp" or result.transport == "splithttp" then + result.xhttp_mode = params.mode or "auto" + result.xhttp_host = params.host and UrlDecode(params.host) or nil + result.xhttp_path = params.path and UrlDecode(params.path) or "/" + -- 检查 extra 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if params.extra and params.extra ~= "" then + result.enable_xhttp_extra = "1" + result.xhttp_extra = base64Encode(params.extra) + end + -- å°è¯•è§£æž JSON æ•°æ® + local success, Data = pcall(jsonParse, params.extra or "") + if success and type(Data) == "table" then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") + else + -- 如果解æžå¤±è´¥ï¼Œæ¸…ç©ºä¸‹è½½åœ°å€ + result.download_address = nil + end + -- make it compatible with bullshit, "h2" transport is non-existent at all + elseif result.transport == "http" or result.transport == "h2" then + result.transport = "h2" + result.h2_host = params.host and UrlDecode(params.host) or nil + result.h2_path = params.path and UrlDecode(params.path) or nil + elseif result.transport == "kcp" then + result.kcp_guise = params.headerType or "none" + if params.headerType and params.headerType == "dns" then + result.kcp_domain = params.host or "" + end + result.seed = params.seed + elseif result.transport == "quic" then + result.quic_guise = params.headerType or "none" + result.quic_security = params.quicSecurity or "none" + result.quic_key = params.key + elseif result.transport == "grpc" then + result.serviceName = params.serviceName + result.grpc_mode = params.mode or "gun" + elseif result.transport == "tcp" or result.transport == "raw" then + result.tcp_guise = params.headerType or "none" + if result.tcp_guise == "http" then + result.tcp_host = params.host and UrlDecode(params.host) or nil + result.tcp_path = params.path and UrlDecode(params.path) or nil + end + end + else + local is_old_format = find_index:find("@") and not find_index:find("://.*@") + local old_base64, host_port, userinfo, server, port, method, password + + if is_old_format then + -- æ—§æ ¼å¼ï¼šbase64(method:pass)@host:port + old_base64, host_port = find_index:match("^([^@]+)@(.-)$") + log("SS 节点旧格å¼è§£æž:", old_base64) + if not old_base64 or not host_port then + log("SS 节点旧格å¼è§£æžå¤±è´¥:", find_index) + return nil + end + local decoded = base64Decode(UrlDecode(old_base64)) + if not decoded then + log("SS base64 è§£ç å¤±è´¥ï¼ˆæ—§æ ¼å¼ï¼‰:", old_base64) + return nil + end + userinfo = decoded + else + -- æ–°æ ¼å¼ï¼šbase64(method:pass@host:port) + local decoded = base64Decode(UrlDecode(find_index)) + if not decoded then + log("SS base64 è§£ç å¤±è´¥ï¼ˆæ–°æ ¼å¼ï¼‰:", find_index) + return nil + end + userinfo, host_port = decoded:match("^(.-)@(.-)$") + if not userinfo or not host_port then + log("SS è§£ç å†…容缺失 @ 分隔:", decoded) + return nil + end + end + + -- è§£æžåŠ å¯†æ–¹å¼å’Œå¯†ç ï¼ˆå…许密ç åŒ…å«å†’å·ï¼‰ + local meth_pass = userinfo:find(":") + if not meth_pass then + log("SS ç”¨æˆ·ä¿¡æ¯æ ¼å¼é”™è¯¯:", userinfo) + return nil + end + method = userinfo:sub(1, meth_pass - 1) + password = userinfo:sub(meth_pass + 1) + + -- åˆ¤æ–­å¯†ç æ˜¯å¦ç»è¿‡urlç¼–ç  + local function isURLEncodedPassword(pwd) + if not pwd:find("%%[0-9A-Fa-f][0-9A-Fa-f]") then + return false + end + local ok, decoded = pcall(UrlDecode, pwd) + return ok and urlEncode(decoded) == pwd + end + + local decoded = UrlDecode(password) + if isURLEncodedPassword(password) and decoded then + password = decoded + end + + -- è§£æžæœåŠ¡å™¨åœ°å€å’Œç«¯å£ï¼ˆå…¼å®¹ IPv6) + if host_port:find("^%[.*%]:%d+$") then + server, port = host_port:match("^%[(.*)%]:(%d+)$") + else + server, port = host_port:match("^(.-):(%d+)$") + end + if not server or not port then + log("SS 节点æœåŠ¡å™¨ä¿¡æ¯æ ¼å¼é”™è¯¯:", host_port) + return nil + end + + -- å¡«å…… result + result.type = selected_ss_backend + result.encrypt_method_ss = method + result.password = password + result.server = server + result.server_port = port + + -- æ’ä»¶å¤„ç† + if params.plugin then + local plugin_info = UrlDecode(params.plugin) + local idx_pn = plugin_info:find(";") + if idx_pn then + result.plugin = plugin_info:sub(1, idx_pn - 1) + result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info) + else + result.plugin = plugin_info + result.plugin_opts = "" + end + -- 部分机场下å‘çš„æ’ä»¶å为 simple-obfs,这里应该改为 obfs-local + if result.plugin == "simple-obfs" then + result.plugin = "obfs-local" + end + -- 如果æ’ä»¶ä¸ä¸º noneï¼Œç¡®ä¿ enable_plugin 为 1 + if result.plugin ~= "none" and result.plugin ~= "" then + result.enable_plugin = 1 + end + else + if params["shadow-tls"] then + -- ç‰¹åˆ«å¤„ç† shadow-tls 作为æ’ä»¶ + -- log("原始 shadow-tls 傿•°:", params["shadow-tls"]) + local decoded_tls = base64Decode(UrlDecode(params["shadow-tls"])) + --log("SS 节点 shadow-tls è§£ç åŽ:", decoded_tls or "nil") + if decoded_tls then + local ok, st = pcall(jsonParse, decoded_tls) + if ok and st then + result.plugin = "shadow-tls" + result.enable_plugin = 1 + local version_flag = "" + if st.version and tonumber(st.version) then + version_flag = string.format("v%s=1;", st.version) + end + + -- åˆæˆ plugin_opts æ ¼å¼ï¼šv%s=1;host=xxx;password=xxx + result.plugin_opts = string.format("%shost=%s;passwd=%s", + version_flag, + st.host or "", + st.password or "") + else + log("shadow-tls JSON è§£æžå¤±è´¥") + end + end + end + end + + -- 检查加密方法是å¦å—æ”¯æŒ + if not checkTabValue(encrypt_methods_ss)[method] then + -- 1202 å¹´äº†è¿˜ä¸æ”¯æŒ SS AEAD 的屑机场 + -- log("䏿”¯æŒçš„SS加密方法:", method) + result.server = nil + end + end + elseif szType == "sip008" then + local selected_ss_backend = preferred_ss_backend() + if not selected_ss_backend then + return nil + end + result.type = selected_ss_backend + if selected_ss_backend == "v2ray" then + result.v2ray_protocol = "shadowsocks" + end + result.server = content.server + result.server_port = content.server_port + result.password = content.password + result.encrypt_method_ss = content.method + result.plugin = content.plugin + result.plugin_opts = content.plugin_opts + result.raw_alias = content.remarks -- 新增 + result.alias = content.remarks -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + if not checkTabValue(encrypt_methods_ss)[content.method] then + result.server = nil + end + elseif szType == "ssd" then + local selected_ss_backend = preferred_ss_backend() + if not selected_ss_backend then + return nil + end + result.type = selected_ss_backend + if selected_ss_backend == "v2ray" then + result.v2ray_protocol = "shadowsocks" + end + result.server = content.server + result.server_port = content.port + result.password = content.password + result.encrypt_method_ss = content.method + result.plugin_opts = content.plugin_options + local raw_alias = "[" .. content.airport .. "] " .. content.remarks + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + if content.plugin == "simple-obfs" then + result.plugin = "obfs-local" + else + result.plugin = content.plugin + end + if not checkTabValue(encrypt_methods_ss)[content.encryption] then + result.server = nil + end + elseif szType == "trojan" then + -- æå–别å(如果存在) + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + local raw_alias = UrlDecode(alias) + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + + -- 分离和æå– password + local Info = content + local params = {} + if Info:find("@") then + local contents = split(Info, "@") + result.password = UrlDecode(contents[1]) + local port = "443" + Info = (contents[2] or ""):gsub("/%?", "?") + + -- 分离主机和 query 傿•°ï¼ˆkey=value&key2=value2) + local query = split(Info, "%?") + local host_port = query[1] + for _, v in pairs(split(query[2], '&')) do + local t = split(v, '=') + if #t > 1 then + params[string.lower(t[1])] = UrlDecode(t[2]) + end + end + + -- æå–æœåŠ¡å™¨åœ°å€å’Œç«¯å£ + result.server, result.server_port = parse_host_port(host_port, "443") + + -- 默认设置 + -- 按照官方的建议 默认验è¯sslè¯ä¹¦ + result.insecure = "0" + result.tls = "1" + + -- 处ç†å‚æ•° + if params.alpn and params.alpn ~= "" then + -- å¤„ç† alpn 傿•° + local alpn = {} + for v in params.alpn:gmatch("[^,;|%s]+") do + table.insert(alpn, v) + end + if #alpn > 0 then + result.tls_alpn = table.concat(alpn, ",") -- ç¡®ä¿ä¸ºå­—符串 + end + end + + do + local tls_host = first_nonempty(params, {"peer", "sni", "host"}) + if tls_host then + -- 未指定 peer/sni 时,兼容使用 host 作为 TLS Host + result.tls_host = tls_host + end + end + -- å¤„ç† insecure 傿•° + do + local insecure = first_nonempty(params, { + "allowInsecure", + "allowinsecure", + "allow_insecure", + "insecure", + "skip-cert-verify" + }) + if is_true_value(insecure) then + result.insecure = "1" + end + end + if params.tfo then + -- å¤„ç† fast open 傿•° + result.fast_open = params.tfo + end + else + result.server_port = port + end + + -- 自动决定模å¼ï¼ˆtrue=Xray, false=普通 Trojan) + if not has_xray then + return nil + end + + result.type = "v2ray" + result.v2ray_protocol = "trojan" + if params.fp then + -- å¤„ç† fingerprint 傿•° + result.fingerprint = params.fp + end + -- å¤„ç† ech 傿•° + if params.ech and params.ech ~= "" then + result.enable_ech = "1" + result.ech_config = params.ech + end + -- 检查 finalmaskg 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if params.fm and params.fm ~= "" then + result.enable_finalmask = "1" + result.finalmask = base64Encode(params.fm) + end + -- 处ç†ä¼ è¾“åè®® + result.transport = params.type or "raw" -- 默认传输å议为 raw + if result.transport == "tcp" then + result.transport = "raw" + end + if result.transport == "splithttp" then + result.transport = "xhttp" + end + if params.pcs and params.pcs ~= "" then + result.tls_CertSha = params.pcs + end + if params.vcn and params.vcn ~= "" then + result.tls_CertByName = params.vcn + end + if result.transport == "ws" then + result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil + result.ws_path = params.path and UrlDecode(params.path) or "/" + elseif result.transport == "httpupgrade" then + result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil + result.httpupgrade_path = params.path and UrlDecode(params.path) or "/" + elseif result.transport == "xhttp" or result.transport == "splithttp" then + result.xhttp_mode = params.mode or "auto" + result.xhttp_host = params.host and UrlDecode(params.host) or nil + result.xhttp_path = params.path and UrlDecode(params.path) or "/" + -- 检查 extra 傿•°æ˜¯å¦å­˜åœ¨ä¸”éžç©º + if params.extra and params.extra ~= "" then + result.enable_xhttp_extra = "1" + result.xhttp_extra = base64Encode(params.extra) + end + -- å°è¯•è§£æž JSON æ•°æ® + local success, Data = pcall(jsonParse, params.extra or "") + if success and type(Data) == "table" then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") + else + -- 如果解æžå¤±è´¥ï¼Œæ¸…ç©ºä¸‹è½½åœ°å€ + result.download_address = nil + end + elseif result.transport == "http" or result.transport == "h2" then + result.transport = "h2" + result.h2_host = params.host and UrlDecode(params.host) or nil + result.h2_path = params.path and UrlDecode(params.path) or nil + elseif result.transport == "kcp" then + result.kcp_guise = params.headerType or "none" + if params.headerType and params.headerType == "dns" then + result.kcp_domain = params.host or "" + end + result.seed = params.seed + elseif result.transport == "quic" then + result.quic_guise = params.headerType or "none" + result.quic_security = params.quicSecurity or "none" + result.quic_key = params.key + elseif result.transport == "grpc" then + result.serviceName = params.serviceName + result.grpc_mode = params.mode or "gun" + elseif result.transport == "tcp" or result.transport == "raw" then + result.tcp_guise = params.headerType and params.headerType ~= "" and params.headerType or "none" + if result.tcp_guise == "http" then + result.tcp_host = params.host and UrlDecode(params.host) or nil + result.tcp_path = params.path and UrlDecode(params.path) or nil + end + end + elseif szType == "vless" then + local url = URL.parse("http://" .. content) + local params = url.query + + local raw_alias = url.fragment and UrlDecode(url.fragment) or nil + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + result.type = "v2ray" + result.v2ray_protocol = "vless" + result.server = normalize_host(url.host) + result.server_port = url.port + result.vmess_id = url.user + result.vless_encryption = params.encryption or "none" + + -- 处ç†ä¼ è¾“类型 + result.transport = params.type or "raw" + if result.transport == "tcp" then + result.transport = "raw" + elseif result.transport == "splithttp" then + result.transport = "xhttp" + elseif result.transport == "http" then + result.transport = "h2" + end + + -- TLS / Reality 标志 + local security = params.security or "" + result.tls = (security == "tls" or security == "xtls") and "1" or "0" + result.reality = (security == "reality") and "1" or "0" + + -- 统一 TLS / Reality 公共字段 + result.tls_host = params.sni + result.fingerprint = params.fp + result.tls_flow = params.flow or nil + + -- å¤„ç† alpn 列表 + if params.alpn and params.alpn ~= "" then + local alpn = {} + for v in params.alpn:gmatch("[^,;|%s]+") do + table.insert(alpn, v) + end + if #alpn > 0 then + result.tls_alpn = table.concat(alpn, ",") -- ç¡®ä¿ä¸ºå­—符串 + end + end + + -- å¤„ç† insecure 傿•° + if params.allowInsecure or params.insecure then + local insecure = params.allowInsecure or params.insecure + if insecure == true or insecure == "1" or insecure == "true" then + result.insecure = "1" + end + end + + -- ECH 傿•°ï¼ˆTLS æ‰æœ‰ï¼‰ + if security == "tls" and params.ech and params.ech ~= "" then + result.enable_ech = "1" + result.ech_config = params.ech + end + + -- å¤„ç† finalmask 傿•° + if params.fm and params.fm ~= "" then + result.enable_finalmask = "1" + result.finalmask = base64Encode(params.fm) + end + + -- å¤„ç† pinsha256 傿•° + if params.pcs and params.pcs ~= "" then + result.tls_CertSha = params.pcs + end + + -- å¤„ç† Leaf Certificate Name 傿•° + if params.vcn and params.vcn ~= "" then + result.tls_CertByName = params.vcn + end + + -- Reality 傿•° + if security == "reality" then + result.reality_publickey = params.pbk and UrlDecode(params.pbk) or nil + result.reality_shortid = params.sid + result.reality_spiderx = params.spx and UrlDecode(params.spx) or nil + + -- PQV 验è¯å‚æ•° + if params.pqv and params.pqv ~= "" then + result.enable_mldsa65verify = "1" + result.reality_mldsa65verify = params.pqv + end + end + + -- å„ç§ä¼ è¾“类型 + if result.transport == "ws" then + result.ws_host = (result.tls ~= "1" and result.reality ~= "1") and (params.host and UrlDecode(params.host)) or nil + result.ws_path = params.path and UrlDecode(params.path) or "/" + elseif result.transport == "httpupgrade" then + result.httpupgrade_host = (result.tls ~= "1" and result.reality ~= "1") and (params.host and UrlDecode(params.host)) or nil + result.httpupgrade_path = params.path and UrlDecode(params.path) or "/" + elseif result.transport == "xhttp" then + result.xhttp_mode = params.mode or "auto" + result.xhttp_host = params.host and UrlDecode(params.host) or nil + result.xhttp_path = params.path and UrlDecode(params.path) or "/" + if params.tfo then + -- å¤„ç† fast open 傿•° + result.fast_open = params.tfo + end + if params.extra and params.extra ~= "" then + result.enable_xhttp_extra = "1" + result.xhttp_extra = base64Encode(params.extra) + end + local success, Data = pcall(jsonParse, params.extra or "") + if success and type(Data) == "table" then + local address = (Data.extra and Data.extra.downloadSettings and Data.extra.downloadSettings.address) + or (Data.downloadSettings and Data.downloadSettings.address) + result.download_address = (address and address ~= "") and address:gsub("^%[", ""):gsub("%]$", "") + else + result.download_address = nil + end + elseif result.transport == "h2" then + result.h2_host = params.host and UrlDecode(params.host) or nil + result.h2_path = params.path and UrlDecode(params.path) or nil + elseif result.transport == "kcp" then + result.kcp_guise = params.headerType or "none" + if params.headerType and params.headerType == "dns" then + result.kcp_domain = params.host or "" + end + result.seed = params.seed + elseif result.transport == "quic" then + result.quic_guise = params.headerType or "none" + result.quic_security = params.quicSecurity or "none" + result.quic_key = params.key + elseif result.transport == "grpc" then + result.serviceName = params.serviceName + result.grpc_mode = params.mode or "gun" + elseif result.transport == "raw" then + result.tcp_guise = params.headerType or "none" + if result.tcp_guise == "http" then + result.tcp_host = params.host and UrlDecode(params.host) or nil + result.tcp_path = params.path and UrlDecode(params.path) or nil + end + end + elseif szType == "tuic" then + if not tuic_type then + log("跳过 TUIC 节点:本地未安装 mihomo。") + return nil + end + + -- æå–别å(如果存在) + local alias = "" + if content:find("#") then + local idx_sp = content:find("#") + alias = content:sub(idx_sp + 1, -1) + content = content:sub(0, idx_sp - 1) + end + local raw_alias = UrlDecode(alias) + result.raw_alias = raw_alias -- 新增 + result.alias = raw_alias -- 临时赋值(åŽé¢ä¼šè¢«è¦†ç›–) + + -- 分离和æå– uuid å’Œ password + local Info = content + if Info:find("@") then + local contents = split(Info, "@") + local userinfo_raw = UrlDecode(contents[1] or "") -- 如有Urlç¼–ç è¿›è¡Œè§£ç  + if userinfo_raw:find(":") then + local userinfo = split(userinfo_raw, ":") + result.tuic_uuid = userinfo[1] + result.tuic_passwd = userinfo[2] + end + Info = (contents[2] or ""):gsub("/%?", "?") + end + + -- 分离主机和 query 傿•°ï¼ˆkey=value&key2=value2) + local query = split(Info, "%?") + local host_port = query[1] + local params = {} + for _, v in pairs(split(query[2], '&')) do + local t = split(v, '=') + if #t > 1 then + params[string.lower(t[1])] = UrlDecode(t[2]) + end + end + + -- æå–æœåŠ¡å™¨åœ°å€å’Œç«¯å£ + result.server, result.server_port = parse_host_port(host_port, "443") + + result.type = tuic_type + result.tuic_ip = params.ip or "" + result.udp_relay_mode = params.udp_relay_mode or "native" + result.congestion_control = params.congestion_control or "cubic" + result.heartbeat = params.heartbeat or "3" + result.timeout = params.timeout or "8" + result.gc_interval = params.gc_interval or "3" + result.gc_lifetime = params.gc_lifetime or "15" + result.send_window = params.send_window or "20971520" + result.receive_window = params.receive_window or "10485760" + result.tuic_max_package_size = params.max_packet_size or "1500" + + -- alpn 支æŒé€—å·æˆ–分å·åˆ†éš” + if params.alpn and params.alpn ~= "" then + local alpn = {} + for v in params.alpn:gmatch("[^,;|%s]+") do + table.insert(alpn, v) + end + if #alpn > 0 then + result.tls_alpn = table.concat(alpn, ",") -- ç¡®ä¿ä¸ºå­—符串 + end + end + + -- å¤„ç† disable_sni 傿•° + if params.disable_sni then + if params.disable_sni == "1" or params.disable_sni == "0" then + result.disable_sni = params.disable_sni + else + result.disable_sni = string.lower(params.disable_sni) == "true" and "1" or "0" + end + end + + -- å¤„ç† zero_rtt_handshake 傿•° + if params.zero_rtt_handshake then + if params.zero_rtt_handshake == "1" or params.zero_rtt_handshake == "0" then + result.zero_rtt_handshake = params.zero_rtt_handshake + else + result.zero_rtt_handshake = string.lower(params.zero_rtt_handshake) == "true" and "1" or "0" + end + end + + -- å¤„ç† dual_stack 傿•° + if params.dual_stack then + if params.dual_stack == "1" or params.dual_stack == "0" then + result.dual_stack = params.dual_stack + else + result.dual_stack = string.lower(params.dual_stack) == "true" and "1" or "0" + end + -- å¤„ç† ipstack_prefer 傿•° + if params.ipstack_prefer and params.ipstack_prefer ~= "" then + result.ipstack_prefer = params.ipstack_prefer + end + end + + -- 兼容 allowInsecure / allowlnsecure / insecure + if params.allowInsecure or params.allowlnsecure or params.insecure then + local insecure = params.allowInsecure or params.allowlnsecure or params.insecure + if insecure == true or insecure == "1" or insecure == "true" then + result.insecure = "1" + end + end + end + + if not result.type or result.type == "" or result.type == "0" then + return nil + end + + if not result.alias then + if result.server and result.server_port then + result.alias = result.server .. ':' .. result.server_port + else + result.alias = "NULL" + end + result.raw_alias = result.alias + end + -- alias ä¸å‚与 hashkey 计算 + local alias = result.alias + result.alias = nil + local switch_enable = result.switch_enable + result.switch_enable = nil + result.hashkey = md5(jsonStringify(result) .. "_" .. (alias or "")) + result.alias = alias + result.switch_enable = switch_enable + return result +end + +-- 计算ã€å‚¨å­˜å’Œè¯»å– md5 值 +-- 计算 md5 值 +local function md5_string(data) + -- 生æˆä¸´æ—¶æ–‡ä»¶å + local tmp = "/tmp/md5_tmp_" .. os.time() .. "_" .. math.random(1000,9999) -- os.time ä¿è¯æ¯ç§’唯一,但ä¸è¶³ä»¥é¿å…全部冲çªï¼›math.random(1000,9999) 增加文件å唯一性,é¿å…并呿—¶å†²çª + nixio.fs.writefile(tmp, data) -- 写入临时文件 + -- 执行 md5sum 命令 + local md5 = luci.sys.exec(string.format('md5sum "%s" 2>/dev/null | cut -d " " -f1', tmp)):gsub("%s+", "") + nixio.fs.remove(tmp) -- 删除临时文件 + return md5 +end + +-- 返回临时文件路径,用æ¥å­˜å‚¨è®¢é˜…çš„ MD5 值,以便判断订阅内容是å¦å‘生å˜åŒ–。 +local function get_md5_path(groupHash) + return "/tmp/sub_md5_" .. groupHash +end + +-- 读å–上次订阅时记录的 MD5 值,以便和当å‰å†…容的 MD5 进行对比,从而判断是å¦éœ€è¦æ›´æ–°èŠ‚ç‚¹åˆ—è¡¨ã€‚ +local function read_old_md5(groupHash) + local path = get_md5_path(groupHash) + if nixio.fs.access(path) then + return trim(nixio.fs.readfile(path) or "") + end + return "" +end + +-- 将订阅分组最新内容的 MD5 值ä¿å­˜åˆ°å¯¹åº”的临时文件中,以便下次更新时进行对比。 +local function write_new_md5(groupHash, md5) + nixio.fs.writefile(get_md5_path(groupHash), md5) +end + +-- curl +local function curl(url, user_agent) + -- æ¸…ç† URL 中的éšè—字符和å‰åŽç©ºç™½ + url = url:gsub("%s+$", ""):gsub("^%s+", ""):gsub("%z", ""):gsub("[\r\n]", "") + -- å¤„ç† user_agent 傿•° + local ua_opt = "" + if user_agent and user_agent ~= "" then + -- 转义åŒå¼•å·ï¼Œé˜²æ­¢ç ´å -A 傿•° + local safe_ua = user_agent:gsub("[\r\n]", ""):gsub('[\\"`$]', '\\%0') -- 安全转义 + ua_opt = '-A "' .. safe_ua .. '"' + end + -- 安全转义 URL:用å•引å·åŒ…裹,并转义内部的å•å¼•å· + local safe_url = "'" .. url:gsub("'", "'\\''") .. "'" + local cmd = string.format( + 'curl -sSL --http1.1 --connect-timeout 20 --max-time 30 --retry 3 -H "Accept-Encoding: identity" %s --insecure --location %s', + ua_opt, + safe_url + ) + -- 执行命令并获å–输出 + local stdout = luci.sys.exec(cmd) + stdout = trim(stdout) -- ç¡®ä¿ trim 函数存在 + local md5 = md5_string(stdout) -- ç¡®ä¿ md5_string 函数存在 + return stdout, md5 +end + +local function collect_wan_interfaces() + local ifaces = {} + local seen = {} + + local function add_iface(value) + value = trim(value or "") + if value == "" or value == "nil" or value:sub(1, 1) == "@" then + return + end + + if value:find("%s") then + for iface in value:gmatch("%S+") do + add_iface(iface) + end + return + end + + if not seen[value] then + seen[value] = true + ifaces[#ifaces + 1] = value + end + end + + local function add_iface_from_status(netif) + local raw = trim(luci.sys.exec(string.format( + "ubus -S call network.interface.%s status 2>/dev/null", + netif + ))) + if raw == "" then + return + end + + local status = jsonParse(raw) + if type(status) ~= "table" then + return + end + + add_iface(status.l3_device) + add_iface(status.device) + end + + add_iface_from_status("wan") + add_iface_from_status("wan6") + + if #ifaces == 0 then + add_iface(ucic:get("network", "wan", "device")) + add_iface(ucic:get("network", "wan", "ifname")) + add_iface(ucic:get("network", "wan6", "device")) + add_iface(ucic:get("network", "wan6", "ifname")) + end + + if #ifaces == 0 then + local route_output = luci.sys.exec("ip route show default 2>/dev/null") + for iface in route_output:gmatch("dev%s+(%S+)") do + add_iface(iface) + end + end + + if #ifaces == 0 then + local route6_output = luci.sys.exec("ip -6 route show default 2>/dev/null") + for iface in route6_output:gmatch("dev%s+(%S+)") do + add_iface(iface) + end + end + + return ifaces +end + +local function detect_subscribe_bypass_backend() + if luci.sys.call("nft list chain inet ss_spec ss_spec_output >/dev/null 2>&1") == 0 then + return "nftables" + end + + local ipt_output = luci.sys.exec("iptables -t nat -S OUTPUT 2>/dev/null") + if ipt_output:find("SS_SPEC_WAN_AC", 1, true) or ipt_output:find("SS_SPEC_ROUTER", 1, true) then + return "iptables" + end + + return nil +end + +local function create_direct_subscribe_bypass() + if proxy ~= "0" then + return nil + end + + local backend = detect_subscribe_bypass_backend() + if not backend then + log("直连订阅: 未检测到 SSR 路由器自身 OUTPUT 代ç†é“¾ï¼Œè·³è¿‡ä¸´æ—¶ç»•过规则。") + return nil + end + + local wan_ifaces = collect_wan_interfaces() + local targets = (#wan_ifaces > 0) and wan_ifaces or {false} + local tag = string.format("SSR_SUB_BYPASS_%d", tonumber(nixio.getpid()) or os.time()) + local manager = { + backend = backend, + tag = tag, + targets = targets, + added = false + } + + function manager:describe_target(target) + if target then + return target + end + return "all-output" + end + + function manager:apply_iptables_rule(target) + local cmd = { + "iptables -t nat -I OUTPUT 1" + } + + if target then + cmd[#cmd + 1] = "-o " .. shell_quote(target) + end + + cmd[#cmd + 1] = "-p tcp -m multiport --dports 80,443" + cmd[#cmd + 1] = "-m comment --comment " .. shell_quote(self.tag) + cmd[#cmd + 1] = "-j RETURN >/dev/null 2>&1" + + return luci.sys.call(table.concat(cmd, " ")) == 0 + end + + function manager:apply_nft_rule(target) + local rule = { + "nft insert rule inet ss_spec ss_spec_output" + } + + if target then + rule[#rule + 1] = "oifname " .. nft_string_literal(target) + end + + rule[#rule + 1] = "meta l4proto tcp tcp dport { 80, 443 }" + rule[#rule + 1] = "counter return" + rule[#rule + 1] = "comment " .. nft_string_literal(self.tag) + + return luci.sys.call(table.concat(rule, " ") .. " >/dev/null 2>&1") == 0 + end + + function manager:apply() + for index = #self.targets, 1, -1 do + local target = self.targets[index] + local ok + + if self.backend == "nftables" then + ok = self:apply_nft_rule(target) + else + ok = self:apply_iptables_rule(target) + end + + if ok then + self.added = true + log("直连订阅: 已添加临时绕过规则 -> " .. self.backend .. " / " .. self:describe_target(target)) + else + log("直连订阅: 添加临时绕过规则失败 -> " .. self.backend .. " / " .. self:describe_target(target)) + end + end + + if not self.added then + log("直连订阅: 临时绕过规则未生效,订阅请求ä»å¯èƒ½èµ°ä»£ç†ã€‚") + end + end + + function manager:cleanup_nft_rules() + local output = luci.sys.exec("nft -a list chain inet ss_spec ss_spec_output 2>/dev/null") + local pattern = 'comment "' .. escape_lua_pattern(self.tag) .. '".-# handle (%d+)' + local handles = {} + + for handle in output:gmatch(pattern) do + handles[#handles + 1] = handle + end + + for _, handle in ipairs(handles) do + luci.sys.call(string.format( + "nft delete rule inet ss_spec ss_spec_output handle %s >/dev/null 2>&1", + handle + )) + end + + return #handles + end + + function manager:cleanup_iptables_rules() + local removed = 0 + + for _, target in ipairs(self.targets) do + local cmd = { + "iptables -t nat -D OUTPUT" + } + + if target then + cmd[#cmd + 1] = "-o " .. shell_quote(target) + end + + cmd[#cmd + 1] = "-p tcp -m multiport --dports 80,443" + cmd[#cmd + 1] = "-m comment --comment " .. shell_quote(self.tag) + cmd[#cmd + 1] = "-j RETURN >/dev/null 2>&1" + + if luci.sys.call(table.concat(cmd, " ")) == 0 then + removed = removed + 1 + end + end + + return removed + end + + function manager:cleanup() + if not self.added then + return + end + + local removed + if self.backend == "nftables" then + removed = self:cleanup_nft_rules() + else + removed = self:cleanup_iptables_rules() + end + + log("直连订阅: 已清ç†ä¸´æ—¶ç»•过规则数é‡: " .. tostring(removed or 0)) + self.added = false + end + + return manager +end + +local function check_filer(result) + -- 过滤的关键è¯åˆ—表 + local filter_word = split(filter_words, "/") + -- ä¿ç•™çš„关键è¯åˆ—表 + local check_save = false + if save_words ~= nil and save_words ~= "" and save_words ~= "NULL" then + check_save = true + end + local save_word = split(save_words, "/") + + -- 检查结果 + local filter_result = false + local save_result = true + + -- 检查是å¦å­˜åœ¨è¿‡æ»¤å…³é”®è¯ + for i, v in pairs(filter_word) do + if tostring(result.alias):find(v, nil, true) then + filter_result = true + end + end + + -- æ£€æŸ¥æ˜¯å¦æ‰“开了ä¿ç•™å…³é”®è¯æ£€æŸ¥ï¼Œå¹¶ä¸”进行过滤 + if check_save == true then + for i, v in pairs(save_word) do + if tostring(result.alias):find(v, nil, true) then + save_result = false + end + end + else + save_result = false + end + + -- ä¸ç­‰æ—¶è¿”回 + if filter_result == true or save_result == true then + return true + else + return false + end +end + +-- 加载订阅未å˜åŒ–的节点用于防止被误删 +local function loadOldNodes(groupHash) + local nodes = {} + cache[groupHash] = {} + nodeResult[#nodeResult + 1] = nodes + local index = #nodeResult + + ucic:foreach(name, uciType, function(s) + if s.grouphashkey == groupHash and s.hashkey then + local section = setmetatable({}, {__index = s}) + nodes[s.hashkey] = section + cache[groupHash][s.hashkey] = section + end + end) +end + +local function get_section_ss_backend(section) + if not section then + return nil + end + if section.type == "ss" or section.type == "ss-libev" then + return "ss" + end + if section.type == "ss-rust" then + return "ss-rust" + end + if section.type == "v2ray" and section.v2ray_protocol == "shadowsocks" then + return "v2ray" + end + return nil +end + +local function group_needs_ss_backend_refresh(groupHash) + local preferred = preferred_ss_backend() + local has_ss_node = false + local needs_refresh = false + + if not preferred then + return false + end + + ucic:foreach(name, uciType, function(s) + if s.grouphashkey ~= groupHash then + return + end + + local current = get_section_ss_backend(s) + if current then + has_ss_node = true + if current ~= preferred then + needs_refresh = true + return false + end + end + end) + + return has_ss_node and needs_refresh +end + +local function preserve_unselected_groups(selected_hashes) + local preserved = {} + + ucic:foreach(name, uciType, function(s) + local groupHash = s.grouphashkey + if groupHash and groupHash ~= "" and not selected_hashes[groupHash] and not preserved[groupHash] then + preserved[groupHash] = true + loadOldNodes(groupHash) + end + end) +end + +local execute = function() + local updated = false + local selected_hashes = {} + + for _, item in ipairs(subscribe_items) do + selected_hashes[md5(item.url)] = true + end + + if target_subscribe_sid ~= "" then + preserve_unselected_groups(selected_hashes) + end + + for _, item in ipairs(subscribe_items) do + local url = item.url + local raw, new_md5 = curl(url, user_agent) + log("raw 长度: "..#raw) + local groupHash = md5(url) + local old_md5 = read_old_md5(groupHash) + + log("处ç†è®¢é˜…: " .. url) + log("groupHash: " .. groupHash) + log("old_md5: " .. tostring(old_md5)) + log("new_md5: " .. tostring(new_md5)) + + local backend_refresh = group_needs_ss_backend_refresh(groupHash) + if #raw == 0 then + log(url .. ': 获å–内容为空') + loadOldNodes(groupHash) + elseif old_md5 and new_md5 == old_md5 and not backend_refresh then + log("订阅未å˜åŒ–, 跳过无需更新的订阅: " .. url) + -- 防止 diff 阶段误删未更新订阅节点 + loadOldNodes(groupHash) + --ucic:foreach(name, uciType, function(s) + -- if s.grouphashkey == groupHash and s.hashkey then + -- cache[groupHash][s.hashkey] = s + -- tinsert(nodeResult[index], s) + -- end + --end) + else + if backend_refresh and old_md5 and new_md5 == old_md5 then + log("检测到 SS åŽç«¯å好å˜åŒ–,强制é‡å»ºè®¢é˜…节点: " .. url) + end + updated = true + -- ä¿å­˜æ›´æ–°åŽçš„ MD5 值到以 groupHash 为标识的临时文件中,用于下次订阅更新时进行对比 + write_new_md5(groupHash, new_md5) + + cache[groupHash] = {} + tinsert(nodeResult, {}) + local index = #nodeResult + local nodes, szType + local is_clash_subscription = false + + if isClashYAML(raw) then + is_clash_subscription = true + local result = processClashSubscription(url) + if result and not check_filer(result) and not cache[groupHash][result.hashkey] then + result.grouphashkey = groupHash + table.insert(nodeResult[index], result) + cache[groupHash][result.hashkey] = result + log('æˆåŠŸå¯¼å…¥ Clash 总节点: ' .. result.alias) + else + log('丢弃无效 Clash 总节点: ' .. url) + end + -- SSD ä¼¼ä¹Žæ˜¯è¿™ç§æ ¼å¼ ssd:// 开头的 + elseif raw:find('ssd://') then + szType = 'ssd' + local nEnd = select(2, raw:find('ssd://')) + nodes = base64Decode(raw:sub(nEnd + 1, #raw)) + nodes = jsonParse(nodes) + local extra = { + airport = nodes.airport, + port = nodes.port, + encryption = nodes.encryption, + password = nodes.password + } + local servers = {} + -- SS里é¢åŒ…ç€ å¹²è„†ç›´æŽ¥è¿™æ · + for _, server in ipairs(nodes.servers or {}) do + tinsert(servers, setmetatable(server, {__index = extra})) + end + nodes = servers + -- SS SIP008 直接使用 Json æ ¼å¼ + elseif jsonParse(raw) then + nodes = jsonParse(raw).servers or jsonParse(raw) + if nodes[1] and nodes[1].server and nodes[1].method then + szType = 'sip008' + end + -- å…¶ä»– base64 æ ¼å¼ + else + -- ssd å¤–çš„æ ¼å¼ + nodes = split(base64Decode(raw):gsub("\r\n", "\n"), "\n") + end + + if not is_clash_subscription and not szType and type(nodes) == "table" then + local anytls_nodes = {} + local normal_nodes = {} + for _, node in ipairs(nodes) do + local line = trim(node or "") + if line:match("^anytls://") then + local parsed = parseAnytlsShare(line:gsub("^anytls://", "")) + if parsed then + table.insert(anytls_nodes, parsed) + end + elseif line ~= "" then + table.insert(normal_nodes, node) + end + end + + if #anytls_nodes > 0 then + local parsed_url = URL.parse(url) + local alias = "Clash_" .. (parsed_url.host or groupHash) + local local_path = string.format("%s/%s.anytls.yaml", local_clash_dir, groupHash) + local yaml = buildAnytlsClashYaml(anytls_nodes, "Proxy") + nixio.fs.mkdirr(local_clash_dir) + nixio.fs.writefile(local_path, yaml) + + local result = processLocalClashSubscription(local_path, alias) + if result and not cache[groupHash][result.hashkey] then + result.grouphashkey = groupHash + table.insert(nodeResult[index], result) + cache[groupHash][result.hashkey] = result + log('æˆåŠŸå¯¼å…¥ AnyTLS 转 Clash 总节点: ' .. result.alias) + end + end + + nodes = normal_nodes + end + + -- 临时存储该订阅解æžå‡ºçš„节点(带原始别å) + local groupRawNodes = {} + + if not is_clash_subscription then + for _, v in ipairs(nodes) do + if v and not string.match(v, "^%s*$") then + xpcall(function() + local result + if szType then + result = processData(szType, v) + elseif not szType then + local node = trim(v) + -- 一些奇葩的链接用"&"ã€"<"当åš"&","#"å‰åŽå¸¦ç©ºæ ¼ + local link = node:gsub("&[a-zA-Z]+;", "&"):gsub("%s*#%s*", "#") + local dat = split(link, "://") + if dat and dat[1] and dat[2] then + local dat3 = "" + if dat[3] then + dat3 = "://" .. dat[3] + end + if dat[1] == 'ss' or dat[1] == 'trojan' or dat[1] == 'tuic' then + result = processData(dat[1], dat[2] .. dat3) + else + result = processData(dat[1], base64Decode(dat[2])) + end + end + else + log('跳过未知类型: ' .. szType) + end + -- log(result) + if result then + -- 中文åšåœ°å€çš„ ä¹Ÿæ²¡æœ‰äººæ‹¿ä¸­æ–‡åŸŸåæžï¼Œå°±ç®—ä¸­æ–‡åŸŸä¹Ÿæœ‰Puny Code SB 机场 + if not result.server or not result.server_port + or (result.type ~= "clash" and result.server == "127.0.0.1") + or result.alias == "NULL" + or check_filer(result) + or (result.type ~= "clash" and result.server:match("[^0-9a-zA-Z%-_%.%s]")) + or cache[groupHash][result.hashkey] then + log('丢弃无效节点: ' .. result.alias) + else + -- 暂存节点 + table.insert(groupRawNodes, result) + end + end + end, function(err) + log(string.format("è§£æžèŠ‚ç‚¹å‡ºé”™: %s\n原始数æ®: %s", tostring(err), tostring(v))) + end) + end + end + end + + -- 对该组节点进行别åç¼–å·ï¼šé‡å¤èŠ‚ç‚¹åŠ åŽç¼€ï¼Œå”¯ä¸€èŠ‚ç‚¹ä¸åŠ  + local freq = {} + for _, node in ipairs(groupRawNodes) do + local raw = node.raw_alias or "" + freq[raw] = (freq[raw] or 0) + 1 + end + local aliasCount = {} + for _, node in ipairs(groupRawNodes) do + local raw = node.raw_alias or "" + if freq[raw] > 1 then + local count = (aliasCount[raw] or 0) + 1 + aliasCount[raw] = count + node.alias = raw .. "_" .. count + else + node.alias = raw + end + -- 清ç†ä¸´æ—¶å­—段 + node.raw_alias = nil + -- 存入 nodeResult + node.grouphashkey = groupHash + table.insert(nodeResult[index], node) + cache[groupHash][node.hashkey] = node + end + + log('æˆåŠŸè§£æžèŠ‚ç‚¹æ•°é‡: ' .. #groupRawNodes) + end + end + -- 输出日志并判断是å¦éœ€è¦è¿›è¡Œ diff + if not updated then + log("订阅未å˜åŒ–,无需更新节点信æ¯ã€‚") + log('ä¿ç•™æ‰‹åŠ¨æ·»åŠ çš„èŠ‚ç‚¹ã€‚') + return + end + + -- diff 阶段 + if next(nodeResult) == nil then + log("更新失败,没有å¯ç”¨çš„节点信æ¯") + return + end + local add, del = 0, 0 + ucic:foreach(name, uciType, function(old) + if old.grouphashkey or old.hashkey then -- 没有 hash çš„ä¸å‚与删除 + if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then + ucic:delete(name, old['.name']) + del = del + 1 + else + local dat = nodeResult[old.grouphashkey][old.hashkey] + ucic:tset(name, old['.name'], dat) + -- 标记一下 + setmetatable(nodeResult[old.grouphashkey][old.hashkey], {__index = {_ignore = true}}) + end + else + if not old.alias then + if old.server or old.server_port then + old.alias = old.server .. ':' .. old.server_port + log('忽略手动添加的节点: ' .. old.alias) + else + ucic:delete(name, old['.name']) + end + else + log('忽略手动添加的节点: ' .. old.alias) + end + end + end) + -- 1615-1653 è¡Œä¸ºç”Ÿæˆ sid + -- è®°å½•å·²ä½¿ç”¨ç¼–å· + local used_sid = {} + local next_sid = 1 + -- 扫æå·²æœ‰ section + ucic:foreach(name, uciType, function(s) + local num = s[".name"]:match("^cfg(%x%x)") -- æå–两ä½å六进制åºå· + if num then + local n = tonumber(num, 16) + used_sid[n] = true + end + end) + -- 获å–下一个å¯ç”¨ç¼–å·ï¼ˆO(1)) + local function get_next_sid() + while used_sid[next_sid] do + next_sid = next_sid + 1 + end + used_sid[next_sid] = true + return next_sid + end + + local sid = ucic:add(name, uciType) + ucic:delete(name, sid) + for _, v in ipairs(nodeResult) do + for _, vv in ipairs(v) do + if not vv._ignore then + --local sid = ucic:add(name, uciType) + if sid then + local suffix = sid:sub(-4) + --ucic:delete(name, sid) + local id = get_next_sid() + local cfgid = string.format("cfg%02x%s", id, suffix) + local section = ucic:section(name, uciType, cfgid) + if section then + ucic:tset(name, section, vv) + ucic:set(name, section, "switch_enable", switch) + add = add + 1 + end + end + end + end + end + ucic:commit(name) + -- 如果原有æœåŠ¡å™¨èŠ‚ç‚¹å·²ç»ä¸è§äº†å°±å°è¯•æ¢ä¸ºç¬¬ä¸€ä¸ªèŠ‚ç‚¹ + local globalServer = ucic:get_first(name, 'global', 'global_server', '') + if globalServer ~= "nil" then + local firstServer = ucic:get_first(name, uciType) + if firstServer then + if not ucic:get(name, globalServer) then + luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &") + ucic:commit(name) + ucic:set(name, ucic:get_first(name, 'global'), 'global_server', firstServer) + ucic:commit(name) + log('当å‰ä¸»æœåŠ¡å™¨èŠ‚ç‚¹å·²è¢«åˆ é™¤ï¼Œæ­£åœ¨è‡ªåŠ¨æ›´æ¢ä¸ºç¬¬ä¸€ä¸ªèŠ‚ç‚¹ã€‚') + luci.sys.call("/etc/init.d/" .. name .. " start > /dev/null 2>&1 &") + else + log('ç»´æŒå½“å‰ä¸»æœåŠ¡å™¨èŠ‚ç‚¹ã€‚') + luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &") + end + else + log('没有æœåŠ¡å™¨èŠ‚ç‚¹äº†ï¼Œåœæ­¢æœåŠ¡') + luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &") + end + end + log('新增节点数é‡: ' .. add .. ', 删除节点数é‡: ' .. del) + log('订阅更新æˆåŠŸ') +end + +if subscribe_items and #subscribe_items > 0 then + if proxy == "1" then + log("当å‰è®¢é˜…模å¼: 通过代ç†è®¢é˜…") + else + log("当å‰è®¢é˜…模å¼: ä¸é€šè¿‡ä»£ç†è®¢é˜…") + end + local direct_bypass = create_direct_subscribe_bypass() + if direct_bypass then + direct_bypass:apply() + end + xpcall(execute, function(e) + log(e) + log(debug.traceback()) + log('å‘生错误, 正在å°è¯•æ¢å¤æœåŠ¡çŠ¶æ€') + local firstServer = ucic:get_first(name, uciType) + if firstServer then + luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &") -- ä¸åŠ &çš„è¯æ—¥å¿—会出现的更早 + log('é‡å¯æœåŠ¡æˆåŠŸ') + else + luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &") -- ä¸åŠ &çš„è¯æ—¥å¿—会出现的更早 + log('åœæ­¢æœåŠ¡æˆåŠŸ') + end + end) + if direct_bypass then + direct_bypass:cleanup() + end +end diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/update.lua b/luci-app-ssr-plus/root/usr/share/shadowsocksr/update.lua new file mode 100755 index 00000000..ede40fa5 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/update.lua @@ -0,0 +1,266 @@ +#!/usr/bin/lua + +------------------------------------------------ +-- This file is part of the luci-app-ssr-plus update.lua +-- By Mattraks +------------------------------------------------ +require "luci.sys" +require "luci.model.uci" +local icount = 0 +local args = arg[1] +local uci = require "luci.model.uci".cursor() + +-- 以下设置更新数æ®åº“至 DNSMASQ é…置路径 +-- èŽ·å– DNSMASQ é…ç½® ID +local DNSMASQ_UCI_CONFIG = uci:get_first("dhcp", "dnsmasq", ".name") + +-- èŽ·å– DNSMASQ 默认é…置文件 +local DNSMASQ_CONF_PATH = "/tmp/etc/dnsmasq.conf." .. DNSMASQ_UCI_CONFIG + +-- 检查 DNSMASQ é…置文件是å¦å­˜åœ¨ï¼Œå¦‚果存在则æå– conf-dir +for line in io.lines(DNSMASQ_CONF_PATH) do + local conf_dir = line:match("^conf%-dir=(.+)") + if conf_dir then + DNSMASQ_CONF_DIR = conf_dir:gsub("%s+", "") -- 去除空白字符 + break + end +end + +-- 设置 dnsmasq-ssrplus.d ç›®å½•è·¯å¾„ï¼Œå¹¶åŽ»é™¤è·¯å¾„æœ«å°¾çš„æ–œæ  +local TMP_DNSMASQ_PATH = DNSMASQ_CONF_DIR:match("^(.-)/?$") .. "/dnsmasq-ssrplus.d" + +local TMP_PATH = "/var/etc/ssrplus" +-- match comments/title/whitelist/ip address/excluded_domain +local comment_pattern = "^[!\\[@]+" +local ip_pattern = "^%d+%.%d+%.%d+%.%d+" +local domain_pattern = "([%w%-%_]+%.[%w%.%-%_]+)[%/%*]*" +local excluded_domain = { + "apple.com", "sina.cn", "sina.com.cn", "baidu.com", "byr.cn", "jlike.com", + "weibo.com", "zhongsou.com", "youdao.com", "sogou.com", "so.com", "soso.com", + "aliyun.com", "taobao.com", "jd.com", "qq.com" +} +-- gfwlist parameter +local mydnsip = '127.0.0.1' +local mydnsport = '5335' +local ipsetname = 'gfwlist' +local new_appledns = uci:get_first("shadowsocksr", "global", "apple_dns") +local bc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +-- base64decoding +local function base64_dec(data) + data = string.gsub(data, '[^' .. bc .. '=]', '') + return (data:gsub('.', function(x) + if (x == '=') then + return '' + end + local r, f = '', (bc:find(x) - 1) + for i = 6, 1, -1 do + r = r .. (f % 2 ^ i - f % 2 ^ (i - 1) > 0 and '1' or '0') + end + return r; + end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x) + if (#x ~= 8) then + return '' + end + local c = 0 + for i = 1, 8 do + c = c + (x:sub(i, i) == '1' and 2 ^ (8 - i) or 0) + end + return string.char(c) + end)) +end +-- check if domain is excluded +local function check_excluded_domain(value) + for _, domain in ipairs(excluded_domain) do + if value:find(domain) then + return true + end + end +end +-- gfwlist转ç è‡³dnsmasqæ ¼å¼ +local function generate_gfwlist(type) + local domains, domains_map = {}, {} + local out = io.open("/tmp/ssr-update." .. type, "w") + for line in io.lines("/tmp/ssr-update.tmp") do + if not (string.find(line, comment_pattern) or string.find(line, ip_pattern) or check_excluded_domain(line)) then + local start, finish, match = string.find(line, domain_pattern) + if start and not domains_map[match] then + domains_map[match] = true + table.insert(domains, match) + end + end + end + for _, domain in ipairs(domains) do + out:write(string.format("server=/%s/%s#%s\n", domain, mydnsip, mydnsport)) + out:write(string.format("ipset=/%s/%s\n", domain, ipsetname)) + end + out:close() + os.remove("/tmp/ssr-update.tmp") +end + +-- æ›´æ¢ Apple dns +local function generate_apple(type) + local domains, domains_map = {}, {} + local out = io.open("/tmp/ssr-update." .. type, "w") + for line in io.lines("/tmp/ssr-update.tmp") do + if not (string.find(line, comment_pattern)) then + local start, finish, match = string.find(line, domain_pattern) + if start and not domains_map[match] then + domains_map[match] = true + match = string.gsub(match, "%s", "") --从域å中去除所有空白字符 + table.insert(domains, match) + end + end + end + for _, domain in ipairs(domains) do + if new_appledns and new_appledns ~= "" then + out:write(string.format("server=/%s/%s\n", domain, new_appledns)) + end + end + out:close() + os.remove("/tmp/ssr-update.tmp") +end + +-- adblock转ç è‡³dnsmasqæ ¼å¼ +local function generate_adblock(type) + local domains, domains_map = {}, {} + local out = io.open("/tmp/ssr-update." .. type, "w") + for line in io.lines("/tmp/ssr-update.tmp") do + if not (string.find(line, comment_pattern)) then + local start, finish, match = string.find(line, domain_pattern) + if start and not domains_map[match] then + domains_map[match] = true + table.insert(domains, match) + end + end + end + for _, domain in ipairs(domains) do + out:write(string.format("address=/%s/\n", domain)) + end + out:close() + os.remove("/tmp/ssr-update.tmp") +end + +local log = function(...) + if args then + print("{ret=" .. table.concat({...}, ",retcount=") .. "}") + else + print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " ")) + end +end + +local function update(url, file, type, file2) + local Num = 1 + local refresh_cmd = "curl -sSL --insecure -o /tmp/ssr-update." .. type .. " " .. url + local sret = luci.sys.call(refresh_cmd) + if sret == 0 then + if type == "gfw_data" then + local gfwlist = io.open("/tmp/ssr-update." .. type, "r") + local decode = gfwlist:read("*a") + if not decode:find("google") then + decode = base64_dec(decode) + end + gfwlist:close() + -- 写回gfwlist + gfwlist = io.open("/tmp/ssr-update.tmp", "w") + gfwlist:write(decode) + gfwlist:close() + generate_gfwlist(type) + Num = 2 + end + if type == "apple_data" then + local apple = io.open("/tmp/ssr-update." .. type, "r") + local decode = apple:read("*a") + if not decode:find("apple") then + decode = base64_dec(decode) + end + apple:close() + -- 写回applechina + apple = io.open("/tmp/ssr-update.tmp", "w") + apple:write(decode) + apple:close() + if new_appledns and new_appledns ~= "" then + generate_apple(type) + end + end + if type == "ad_data" then + local adblock = io.open("/tmp/ssr-update." .. type, "r") + local decode = adblock:read("*a") + if decode:find("address=") then + adblock:close() + else + adblock:close() + -- 写回adblock + adblock = io.open("/tmp/ssr-update.tmp", "w") + adblock:write(decode) + adblock:close() + generate_adblock(type) + end + end + local new_md5 = luci.sys.exec("echo -n $([ -f '/tmp/ssr-update." .. type .. "' ] && md5sum /tmp/ssr-update." .. type .. " | awk '{print $1}')") + local old_md5 = luci.sys.exec("echo -n $([ -f '" .. file .. "' ] && md5sum " .. file .. " | awk '{print $1}')") + if new_md5 == old_md5 then + if args then + log(1) + else + log("ä½ å·²ç»æ˜¯æœ€æ–°æ•°æ®ï¼Œæ— éœ€æ›´æ–°ï¼") + end + else + icount = luci.sys.exec("cat /tmp/ssr-update." .. type .. " | wc -l") + luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file) + if file2 then + luci.sys.exec("cp -f /tmp/ssr-update." .. type .. " " .. file2) + end + if type == "gfw_data" or type == "ad_data" then + luci.sys.call("/usr/share/shadowsocksr/gfw2ipset.sh") + else + if luci.sys.call("command -v ipset >/dev/null 2>&1") == 0 then + luci.sys.call("/usr/share/shadowsocksr/chinaipset.sh " .. TMP_PATH .. "/china_ssr.txt") + end + end + if args then + log(0, tonumber(icount) / Num) + else + log("æ›´æ–°æˆåŠŸï¼ æ–°çš„æ€»è®°å½•æ•°ï¼š" .. tostring(tonumber(icount) / Num)) + end + end + else + if args then + log(-1) + else + log("更新失败ï¼") + end + end + os.remove("/tmp/ssr-update." .. type) +end + +if args then + if args == "gfw_data" then + update(uci:get_first("shadowsocksr", "global", "gfwlist_url"), "/etc/ssrplus/gfw_list.conf", args, TMP_DNSMASQ_PATH .. "/gfw_list.conf") + os.exit(0) + end + if args == "ip_data" then + update(uci:get_first("shadowsocksr", "global", "chnroute_url"), "/etc/ssrplus/china_ssr.txt", args, TMP_PATH .. "/china_ssr.txt") + os.exit(0) + end + if args == "apple_data" then + update(uci:get_first("shadowsocksr", "global", "apple_url"), "/etc/ssrplus/applechina.conf", args, TMP_DNSMASQ_PATH .. "/applechina.conf") + os.exit(0) + end + if args == "ad_data" then + update(uci:get_first("shadowsocksr", "global", "adblock_url"), "/etc/ssrplus/ad.conf", args, TMP_DNSMASQ_PATH .. "/ad.conf") + os.exit(0) + end +else + log("正在更新ã€GFW列表】数æ®åº“") + update(uci:get_first("shadowsocksr", "global", "gfwlist_url"), "/etc/ssrplus/gfw_list.conf", "gfw_data", TMP_DNSMASQ_PATH .. "/gfw_list.conf") + log("正在更新ã€å›½å†…IP段】数æ®åº“") + update(uci:get_first("shadowsocksr", "global", "chnroute_url"), "/etc/ssrplus/china_ssr.txt", "ip_data", TMP_PATH .. "/china_ssr.txt") + if uci:get_first("shadowsocksr", "global", "apple_optimization", "0") == "1" then + log("正在更新ã€Apple域å】数æ®åº“") + update(uci:get_first("shadowsocksr", "global", "apple_url"), "/etc/ssrplus/applechina.conf", "apple_data", TMP_DNSMASQ_PATH .. "/applechina.conf") + end + if uci:get_first("shadowsocksr", "global", "adblock", "0") == "1" then + log("正在更新ã€å¹¿å‘Šå±è”½ã€‘æ•°æ®åº“") + update(uci:get_first("shadowsocksr", "global", "adblock_url"), "/etc/ssrplus/ad.conf", "ad_data", TMP_DNSMASQ_PATH .. "/ad.conf") + end +end diff --git a/luci-app-ssr-plus/root/usr/share/shadowsocksr/update_components.sh b/luci-app-ssr-plus/root/usr/share/shadowsocksr/update_components.sh new file mode 100644 index 00000000..299e8180 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/shadowsocksr/update_components.sh @@ -0,0 +1,1428 @@ +#!/bin/sh + +set -u + +XRAY_RELEASE_PAGE="https://github.com/XTLS/Xray-core/releases/latest" +MIHOMO_RELEASE_PAGE="https://github.com/MetaCubeX/mihomo/releases/latest" +NAIVEPROXY_RELEASE_API="https://api.github.com/repos/klzgrad/naiveproxy/releases/latest" +XRAY_BINARY="/usr/bin/xray" +MIHOMO_BINARY="/usr/bin/mihomo" +NAIVEPROXY_BINARY="/usr/bin/naive" +COUNTRY_MMDB_URL="https://testingcf.jsdelivr.net/gh/alecthw/mmdb_china_ip_list@release/lite/Country.mmdb" +GEOSITE_URL="https://testingcf.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat" +GEOIP_DAT_URL="https://testingcf.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geoip.dat" +COUNTRY_MMDB_FILE="/usr/share/shadowsocksr/Country.mmdb" +GEOIP_DAT_FILE="/usr/share/v2ray/geoip.dat" +GEOSITE_DAT_FILE="/usr/share/v2ray/geosite.dat" +OPENCLASH_GEOSITE_FILE="/etc/openclash/GeoSite.dat" +OPENCLASH_GEOIP_DAT_FILE="/etc/openclash/geoip.dat" +OPENCLASH_GEOSITE_DAT_FILE="/etc/openclash/geosite.dat" + +log_kv() { + key="$1" + shift + printf '%s=%s\n' "$key" "$*" +} + +file_mtime() { + local path="$1" + [ -f "$path" ] || { + printf '%s' 'File Not Exist' + return 0 + } + date -r "$path" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || printf '%s' 'Unknown' +} + +file_size() { + local path="$1" + [ -f "$path" ] || { + printf '%s' '0' + return 0 + } + wc -c < "$path" 2>/dev/null | tr -d '[:space:]' +} + +resolve_existing_geo_file() { + local primary="$1" + local fallback="$2" + + if [ -f "$primary" ]; then + printf '%s' "$primary" + elif [ -n "$fallback" ] && [ -f "$fallback" ]; then + printf '%s' "$fallback" + else + printf '%s' "$primary" + fi +} + +resolve_geosite_file() { + resolve_existing_geo_file "$GEOSITE_DAT_FILE" "$OPENCLASH_GEOSITE_FILE" +} + +resolve_v2ray_geoip_file() { + resolve_existing_geo_file "$GEOIP_DAT_FILE" "$OPENCLASH_GEOIP_DAT_FILE" +} + +resolve_v2ray_geosite_file() { + resolve_existing_geo_file "$GEOSITE_DAT_FILE" "$OPENCLASH_GEOSITE_DAT_FILE" +} + +trim_version() { + printf '%s' "$1" | sed 's/^v//' +} + +get_component_mirror() { + if [ -n "${COMPONENT_MIRROR:-}" ]; then + echo "$COMPONENT_MIRROR" + return 0 + fi + uci -q get shadowsocksr.@global[0].component_mirror 2>/dev/null || echo "direct" +} + +mirror_wrap_url() { + local raw_url="$1" + local mirror + + mirror="$(get_component_mirror)" + case "$mirror" in + direct|"") + printf '%s' "$raw_url" + ;; + ghproxy) + printf 'https://mirror.ghproxy.com/%s' "$raw_url" + ;; + ghproxy_cc) + printf 'https://ghproxy.cc/%s' "$raw_url" + ;; + ghfast) + printf 'https://ghfast.top/%s' "$raw_url" + ;; + jsdelivr) + case "$raw_url" in + https://github.com/XTLS/Xray-core/releases/download/*) + printf '%s' "$raw_url" | sed 's#https://github.com/XTLS/Xray-core/releases/download/\(v[^/]*\)/\(.*\)#https://fastly.jsdelivr.net/gh/XTLS/Xray-core@\1/\2#' + ;; + https://github.com/MetaCubeX/mihomo/releases/download/*) + printf '%s' "$raw_url" | sed 's#https://github.com/MetaCubeX/mihomo/releases/download/\(v[^/]*\)/\(.*\)#https://fastly.jsdelivr.net/gh/MetaCubeX/mihomo@\1/\2#' + ;; + *) + printf '%s' "$raw_url" + ;; + esac + ;; + *) + printf '%s' "$raw_url" + ;; + esac +} + +version_gt() { + local left right first + + left="$(trim_version "${1:-}")" + right="$(trim_version "${2:-}")" + + [ -n "$left" ] || return 1 + [ -n "$right" ] || return 1 + [ "$left" = "$right" ] && return 1 + + first="$(printf '%s\n%s\n' "$left" "$right" | sort -V | tail -n 1)" + [ "$first" = "$left" ] +} + +naiveproxy_versions_equal() { + local left right + + left="$(trim_version "${1:-}")" + right="$(trim_version "${2:-}")" + [ -n "$left" ] || return 1 + [ -n "$right" ] || return 1 + [ "$left" = "$right" ] && return 0 + [ "${left%%-*}" = "${right%%-*}" ] +} + +get_openwrt_arch() { + local arch + + arch="" + if [ -r /etc/openwrt_release ]; then + arch="$(. /etc/openwrt_release 2>/dev/null; printf '%s' "${DISTRIB_ARCH:-}")" + fi + + if [ -z "$arch" ] && command -v opkg >/dev/null 2>&1; then + arch="$(opkg print-architecture 2>/dev/null | awk '$2 != "all" && $2 != "noarch" { print $2 }' | tail -n 1)" + fi + + if [ -z "$arch" ] && command -v uname >/dev/null 2>&1; then + arch="$(uname -m 2>/dev/null)" + fi + + printf '%s' "$arch" +} + +is_openwrt_env() { + [ -r /etc/openwrt_release ] || command -v opkg >/dev/null 2>&1 +} + +find_mihomo_binary() { + if command -v mihomo >/dev/null 2>&1; then + command -v mihomo + return 0 + fi + + for path in /usr/bin/mihomo /usr/libexec/mihomo /etc/ssrplus/bin/mihomo; do + if [ -x "$path" ]; then + printf '%s' "$path" + return 0 + fi + done + + return 1 +} + +find_naiveproxy_binary() { + if command -v naive >/dev/null 2>&1; then + command -v naive + return 0 + fi + + for path in /usr/bin/naive /usr/libexec/naive /etc/ssrplus/bin/naive; do + if [ -x "$path" ]; then + printf '%s' "$path" + return 0 + fi + done + + return 1 +} + +get_xray_current_version() { + if [ ! -x "$XRAY_BINARY" ]; then + return 1 + fi + + "$XRAY_BINARY" version 2>/dev/null | sed -n 's/^Xray[[:space:]]\+\([^[:space:]]\+\).*$/\1/p' | sed -n '1p' + return 0 +} + +get_mihomo_current_version() { + local binary + + binary="$(find_mihomo_binary)" || return 1 + "$binary" -v 2>/dev/null | sed -n 's/.* v\([0-9][0-9.]*\).*/\1/p' | sed -n '1p' + return 0 +} + +get_naiveproxy_current_version() { + local binary + + binary="$(find_naiveproxy_binary)" || return 1 + "$binary" --version 2>&1 | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?' | sed -n '1p' + return 0 +} + +map_xray_asset() { + case "$1" in + x86_64*|amd64*) + printf '%s' 'Xray-linux-64.zip' + ;; + i386*|i486*|i586*|i686*|x86*) + printf '%s' 'Xray-linux-32.zip' + ;; + aarch64*|arm64*) + printf '%s' 'Xray-linux-arm64-v8a.zip' + ;; + *armv7*|*cortex-a*|*neon*|*vfpv3*|*vfpv4*) + printf '%s' 'Xray-linux-arm32-v7a.zip' + ;; + *armv6*|*arm1176*) + printf '%s' 'Xray-linux-arm32-v6.zip' + ;; + *armv5*|*arm926*|*xscale*) + printf '%s' 'Xray-linux-arm32-v5.zip' + ;; + mips64el*|mips64le*) + printf '%s' 'Xray-linux-mips64le.zip' + ;; + mips64*) + printf '%s' 'Xray-linux-mips64.zip' + ;; + mipsel*|mips32el*|mips32le*) + printf '%s' 'Xray-linux-mips32le.zip' + ;; + mips*) + printf '%s' 'Xray-linux-mips32.zip' + ;; + riscv64*) + printf '%s' 'Xray-linux-riscv64.zip' + ;; + loongarch64*|loong64*) + printf '%s' 'Xray-linux-loong64.zip' + ;; + powerpc64*|ppc64*) + printf '%s' 'Xray-linux-ppc64.zip' + ;; + s390x*) + printf '%s' 'Xray-linux-s390x.zip' + ;; + *) + return 1 + ;; + esac +} + +require_cmd() { + command -v "$1" >/dev/null 2>&1 +} + +select_unzip_cmd() { + if require_cmd unzip; then + printf '%s' 'unzip -oq' + return 0 + fi + + if busybox unzip >/dev/null 2>&1; then + printf '%s' 'busybox unzip -o' + return 0 + fi + + return 1 +} + +select_gzip_cmd() { + if require_cmd gzip; then + printf '%s' 'gzip -dc' + return 0 + fi + + if busybox gzip >/dev/null 2>&1; then + printf '%s' 'busybox gzip -dc' + return 0 + fi + + return 1 +} + +select_xz_cmd() { + if require_cmd xz; then + printf '%s' 'xz -dc' + return 0 + fi + + if busybox xz >/dev/null 2>&1; then + printf '%s' 'busybox xz -dc' + return 0 + fi + + return 1 +} + +select_tar_cmd() { + if require_cmd tar; then + printf '%s' 'tar' + return 0 + fi + + if busybox tar --help >/dev/null 2>&1; then + printf '%s' 'busybox tar' + return 0 + fi + + return 1 +} + +select_wget_cmd() { + if require_cmd wget-ssl; then + printf '%s' 'wget-ssl' + return 0 + fi + + if require_cmd wget; then + printf '%s' 'wget' + return 0 + fi + + return 1 +} + +curl_effective_url() { + local target="$1" + local effective="" + local headers="" + local location="" + + headers="$(curl -kfsSI --http1.1 --connect-timeout 10 --retry 2 -A 'curl/8.0' -H 'Accept-Encoding: identity' "$target" 2>/dev/null || true)" + location="$(printf '%s\n' "$headers" | sed -n 's/^[Ll]ocation:[[:space:]]*//p' | sed 's/\r$//' | sed 's/[[:space:]]\+\[following\]$//' | sed -n '1p')" + [ -n "$location" ] && effective="$location" + [ -n "$effective" ] || effective="$(curl -kfsSL --http1.1 --connect-timeout 10 --retry 2 -A 'curl/8.0' -H 'Accept-Encoding: identity' -o /dev/null -w '%{url_effective}' "$target" 2>/dev/null || true)" + [ -n "$effective" ] || return 1 + + printf '%s' "$effective" +} + +wget_effective_url() { + local target="$1" + local wget_cmd output location + + wget_cmd="$(select_wget_cmd)" || return 1 + output="$($wget_cmd --server-response --max-redirect=0 --spider --timeout=20 --tries=3 --no-check-certificate "$target" 2>&1 || true)" + location="$(printf '%s\n' "$output" | sed -n 's/^[Ll]ocation:[[:space:]]*//p' | sed 's/\r$//' | sed 's/[[:space:]]\+\[following\]$//' | sed -n '1p')" + + if [ -n "$location" ]; then + printf '%s' "$location" + return 0 + fi + + printf '%s\n' "$output" | grep -qE 'HTTP/[0-9.]+ 200' || return 1 + printf '%s' "$target" +} + +effective_url() { + local target="$1" + local url="" + + url="$(curl_effective_url "$target" 2>/dev/null || true)" + [ -n "$url" ] || url="$(wget_effective_url "$target" 2>/dev/null || true)" + [ -n "$url" ] || return 1 + printf '%s' "$url" +} + +fetch_text() { + local url="$1" + local wget_cmd + + if curl -kfsSL --http1.1 --connect-timeout 10 --retry 2 -A 'curl/8.0' -H 'Accept: application/vnd.github+json' "$url" 2>/dev/null; then + return 0 + fi + + wget_cmd="$(select_wget_cmd)" || return 1 + "$wget_cmd" --header='Accept: application/vnd.github+json' --timeout=20 --tries=3 --no-check-certificate -O - "$url" 2>/dev/null +} + +download_file() { + local url="$1" + local output="$2" + local wget_cmd + + if curl -kfsSL --http1.1 --connect-timeout 10 --retry 2 -A 'curl/8.0' -H 'Accept-Encoding: identity' -o "$output" "$url" 2>/dev/null; then + return 0 + fi + + wget_cmd="$(select_wget_cmd)" || return 1 + "$wget_cmd" --no-check-certificate --timeout=20 --tries=3 -O "$output" "$url" >/dev/null 2>&1 +} + +geo_validate_download() { + local new_file="$1" + local current_file="$2" + local new_size current_size + + new_size="$(file_size "$new_file")" + [ "${new_size:-0}" -gt 0 ] 2>/dev/null || return 1 + + if [ -f "$current_file" ]; then + current_size="$(file_size "$current_file")" + [ "${new_size:-0}" -ge "${current_size:-0}" ] 2>/dev/null || return 1 + fi + + return 0 +} + +geo_safe_replace() { + local new_file="$1" + local current_file="$2" + local backup_file="$3" + + mkdir -p "$(dirname "$current_file")" || return 1 + [ -f "$current_file" ] && cp -fp "$current_file" "$backup_file" 2>/dev/null || true + + if ! cp -f "$new_file" "$current_file"; then + [ -f "$backup_file" ] && cp -f "$backup_file" "$current_file" 2>/dev/null || true + return 1 + fi + + return 0 +} + +geo_local_info() { + local geo="$1" + local file1="" + local file2="" + + case "$geo" in + country_mmdb) + file1="$COUNTRY_MMDB_FILE" + ;; + geosite) + file1="$(resolve_geosite_file)" + ;; + v2ray_geo) + file1="$(resolve_v2ray_geoip_file)" + file2="$(resolve_v2ray_geosite_file)" + ;; + *) + log_kv error 'unsupported_component' + return 1 + ;; + esac + + log_kv component "$geo" + log_kv installed "$([ -f "$file1" ] && echo 1 || echo 0)" + log_kv current_version "$(file_mtime "$file1")" + log_kv current_version_extra "$([ -n "$file2" ] && file_mtime "$file2" || echo '')" + log_kv latest_version '' + log_kv can_upgrade 0 + log_kv error '' +} + +geo_upgrade() { + local geo="$1" + local tmp_dir file_a url_a file_b url_b msg + + tmp_dir="$(mktemp -d /tmp/ssrplus-geo.XXXXXX)" + [ -n "$tmp_dir" ] && [ -d "$tmp_dir" ] || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Failed to create temp directory' + return 0 + } + trap "rm -rf '$tmp_dir'" EXIT INT TERM + + case "$geo" in + country_mmdb) + file_a="$COUNTRY_MMDB_FILE" + url_a="$(mirror_wrap_url "$COUNTRY_MMDB_URL")" + download_file "$url_a" "$tmp_dir/file_a" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Download failed' + return 0 + } + geo_validate_download "$tmp_dir/file_a" "$file_a" || { + log_kv component "$geo" + log_kv success 1 + log_kv current_version "$(file_mtime "$file_a")" + log_kv current_version_extra '' + log_kv latest_version "$(file_mtime "$file_a")" + log_kv can_upgrade 0 + log_kv message 'Already up to date' + return 0 + } + geo_safe_replace "$tmp_dir/file_a" "$file_a" "$tmp_dir/file_a.bak" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Install failed' + return 0 + } + msg='Upgrade completed' + ;; + geosite) + file_a="$(resolve_geosite_file)" + url_a="$(mirror_wrap_url "$GEOSITE_URL")" + download_file "$url_a" "$tmp_dir/file_a" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Download failed' + return 0 + } + geo_validate_download "$tmp_dir/file_a" "$file_a" || { + log_kv component "$geo" + log_kv success 1 + log_kv current_version "$(file_mtime "$file_a")" + log_kv current_version_extra '' + log_kv latest_version "$(file_mtime "$file_a")" + log_kv can_upgrade 0 + log_kv message 'Already up to date' + return 0 + } + geo_safe_replace "$tmp_dir/file_a" "$file_a" "$tmp_dir/file_a.bak" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Install failed' + return 0 + } + msg='Upgrade completed' + ;; + v2ray_geo) + file_a="$(resolve_v2ray_geoip_file)" + url_a="$(mirror_wrap_url "$GEOIP_DAT_URL")" + file_b="$(resolve_v2ray_geosite_file)" + url_b="$(mirror_wrap_url "$GEOSITE_URL")" + download_file "$url_a" "$tmp_dir/file_a" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Download failed' + return 0 + } + download_file "$url_b" "$tmp_dir/file_b" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Download failed' + return 0 + } + geo_validate_download "$tmp_dir/file_a" "$file_a" || { + log_kv component "$geo" + log_kv success 1 + log_kv current_version "$(file_mtime "$file_a")" + log_kv current_version_extra "$(file_mtime "$file_b")" + log_kv latest_version "$(file_mtime "$file_a")" + log_kv can_upgrade 0 + log_kv message 'Already up to date' + return 0 + } + geo_validate_download "$tmp_dir/file_b" "$file_b" || { + log_kv component "$geo" + log_kv success 1 + log_kv current_version "$(file_mtime "$file_a")" + log_kv current_version_extra "$(file_mtime "$file_b")" + log_kv latest_version "$(file_mtime "$file_a")" + log_kv can_upgrade 0 + log_kv message 'Already up to date' + return 0 + } + geo_safe_replace "$tmp_dir/file_a" "$file_a" "$tmp_dir/file_a.bak" || { + log_kv component "$geo" + log_kv success 0 + log_kv message 'Install failed' + return 0 + } + geo_safe_replace "$tmp_dir/file_b" "$file_b" "$tmp_dir/file_b.bak" || { + [ -f "$tmp_dir/file_a.bak" ] && cp -f "$tmp_dir/file_a.bak" "$file_a" 2>/dev/null || true + log_kv component "$geo" + log_kv success 0 + log_kv message 'Install failed' + return 0 + } + msg='Upgrade completed' + ;; + *) + log_kv component "$geo" + log_kv success 0 + log_kv message 'Unsupported component' + return 0 + ;; + esac + + log_kv component "$geo" + log_kv success 1 + log_kv current_version "$(file_mtime "$file_a")" + log_kv current_version_extra "$([ -n "${file_b:-}" ] && file_mtime "$file_b" || echo '')" + log_kv latest_version "$(file_mtime "$file_a")" + log_kv can_upgrade 0 + log_kv message "$msg" + return 0 +} + +get_xray_latest_tag() { + local location tag + + location="$(effective_url "$XRAY_RELEASE_PAGE")" || return 1 + tag="$(printf '%s' "$location" | sed -n 's#.*/tag/\(v[0-9][^/]*\)$#\1#p' | sed -n '1p')" + [ -n "$tag" ] || return 1 + printf '%s' "$tag" +} + +get_xray_latest_info() { + local tag version asset url arch + + arch="$(get_openwrt_arch)" + asset="$(map_xray_asset "$arch")" || return 2 + tag="$(get_xray_latest_tag)" || return 3 + version="$(trim_version "$tag")" + url="$(mirror_wrap_url "https://github.com/XTLS/Xray-core/releases/download/$tag/$asset")" + + [ -n "$tag" ] && [ -n "$version" ] && [ -n "$url" ] || return 4 + + log_kv arch "$arch" + log_kv asset "$asset" + log_kv latest_version "$version" + log_kv download_url "$url" + return 0 +} + +get_mihomo_latest_tag() { + local location tag + + location="$(effective_url "$MIHOMO_RELEASE_PAGE")" || return 1 + tag="$(printf '%s' "$location" | sed -n 's#.*/tag/\(v[0-9][^/]*\)$#\1#p' | sed -n '1p')" + [ -n "$tag" ] || return 1 + printf '%s' "$tag" +} + +map_mihomo_asset() { + local arch="$1" + local version="$2" + + case "$arch" in + x86_64*|amd64*) + printf 'mihomo-linux-amd64-compatible-v%s.gz' "$version" + ;; + i386*|i486*|i586*|i686*|x86*) + printf 'mihomo-linux-386-v%s.gz' "$version" + ;; + aarch64*|arm64*) + printf 'mihomo-linux-arm64-v%s.gz' "$version" + ;; + *armv7*|*cortex-a*|*neon*|*vfpv3*|*vfpv4*) + printf 'mihomo-linux-armv7-v%s.gz' "$version" + ;; + *armv6*|*arm1176*) + printf 'mihomo-linux-armv6-v%s.gz' "$version" + ;; + *armv5*|*arm926*|*xscale*) + printf 'mihomo-linux-armv5-v%s.gz' "$version" + ;; + mips64el*|mips64le*) + printf 'mihomo-linux-mips64le-v%s.gz' "$version" + ;; + mips64*) + printf 'mihomo-linux-mips64-v%s.gz' "$version" + ;; + mipsel*|mips32el*|mips32le*) + printf 'mihomo-linux-mipsle-softfloat-v%s.gz' "$version" + ;; + mips*) + printf 'mihomo-linux-mips-softfloat-v%s.gz' "$version" + ;; + riscv64*) + printf 'mihomo-linux-riscv64-v%s.gz' "$version" + ;; + loongarch64*|loong64*) + printf 'mihomo-linux-loong64-abi1-v%s.gz' "$version" + ;; + powerpc64le*|ppc64le*) + printf 'mihomo-linux-ppc64le-v%s.gz' "$version" + ;; + s390x*) + printf 'mihomo-linux-s390x-v%s.gz' "$version" + ;; + *) + return 1 + ;; + esac +} + +get_mihomo_latest_info() { + local arch tag version asset url + + arch="$(get_openwrt_arch)" + tag="$(get_mihomo_latest_tag)" || return 3 + version="$(trim_version "$tag")" + asset="$(map_mihomo_asset "$arch" "$version")" || return 2 + url="$(mirror_wrap_url "https://github.com/MetaCubeX/mihomo/releases/download/$tag/$asset")" + + log_kv arch "$arch" + log_kv asset "$asset" + log_kv latest_version "$version" + log_kv download_url "$url" + return 0 +} + +map_naiveproxy_linux_asset() { + case "$1" in + x86_64*|amd64*) + printf '%s' 'x64' + ;; + i386*|i486*|i586*|i686*|x86*) + printf '%s' 'x86' + ;; + aarch64*|arm64*) + printf '%s' 'arm64' + ;; + *armv7*|*cortex-a*|*neon*|*vfpv3*|*vfpv4*) + printf '%s' 'arm' + ;; + mips64el*|mips64le*) + printf '%s' 'mips64el' + ;; + mipsel*|mips32el*|mips32le*) + printf '%s' 'mipsel' + ;; + riscv64*) + printf '%s' 'riscv64' + ;; + loongarch64*|loong64*) + printf '%s' 'loong64' + ;; + *) + return 1 + ;; + esac +} + +normalize_naiveproxy_openwrt_arch() { + local arch="${1%%+*}" + printf '%s' "$arch" +} + +naiveproxy_openwrt_arch_candidates() { + local normalized + + normalized="$(normalize_naiveproxy_openwrt_arch "$1")" + printf '%s\n' "$normalized" + + case "$normalized" in + aarch64_*) + [ "$normalized" = "aarch64_generic" ] || printf '%s\n' 'aarch64_generic' + ;; + x86|i386|i486|i586|i686) + printf '%s\n' 'x86' + ;; + esac +} + +asset_list_has() { + local asset_list="$1" + local candidate="$2" + + printf '%s\n' "$asset_list" | grep -Fx "$candidate" >/dev/null 2>&1 +} + +select_naiveproxy_asset() { + local asset_list="$1" + local tag="$2" + local arch="$3" + local candidate linux_arch candidate_arch + + if is_openwrt_env; then + for candidate_arch in $(naiveproxy_openwrt_arch_candidates "$arch"); do + candidate="naiveproxy-${tag}-openwrt-${candidate_arch}-static.tar.xz" + if asset_list_has "$asset_list" "$candidate"; then + printf '%s' "$candidate" + return 0 + fi + + candidate="naiveproxy-${tag}-openwrt-${candidate_arch}.tar.xz" + if asset_list_has "$asset_list" "$candidate"; then + printf '%s' "$candidate" + return 0 + fi + done + fi + + linux_arch="$(map_naiveproxy_linux_asset "$arch" 2>/dev/null || true)" + if [ -n "$linux_arch" ]; then + candidate="naiveproxy-${tag}-linux-${linux_arch}.tar.xz" + if asset_list_has "$asset_list" "$candidate"; then + printf '%s' "$candidate" + return 0 + fi + fi + + return 1 +} + +get_naiveproxy_latest_info() { + local arch release_json tag version asset asset_list url + + arch="$(get_openwrt_arch)" + release_json="$(fetch_text "$NAIVEPROXY_RELEASE_API")" || return 3 + tag="$(printf '%s\n' "$release_json" | sed -n 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p' | sed -n '1p')" + [ -n "$tag" ] || return 3 + version="$(trim_version "$tag")" + asset_list="$(printf '%s\n' "$release_json" | sed -n 's/.*"name":[[:space:]]*"\([^"]*\.tar\.xz\)".*/\1/p')" + asset="$(select_naiveproxy_asset "$asset_list" "$tag" "$arch")" || return 4 + url="$(mirror_wrap_url "https://github.com/klzgrad/naiveproxy/releases/download/$tag/$asset")" + + log_kv arch "$arch" + log_kv asset "$asset" + log_kv latest_version "$version" + log_kv download_url "$url" + return 0 +} + +xray_info() { + local current installed latest_output latest_rc latest_version arch asset can_upgrade + + installed=0 + current="" + arch="$(get_openwrt_arch)" + asset="$(map_xray_asset "$arch" 2>/dev/null || true)" + if current="$(get_xray_current_version)" && [ -n "$current" ]; then + installed=1 + fi + + latest_output="$(get_xray_latest_info 2>/dev/null)" + latest_rc=$? + + log_kv component xray + log_kv installed "$installed" + log_kv current_version "$current" + log_kv arch "$arch" + log_kv asset "$asset" + + if [ $latest_rc -ne 0 ]; then + log_kv can_upgrade 0 + case "$latest_rc" in + 2) log_kv error 'unsupported_arch' ;; + 3) log_kv error 'fetch_failed' ;; + 4) log_kv error 'asset_not_found' ;; + *) log_kv error 'unknown_error' ;; + esac + return 0 + fi + + latest_version="$(printf '%s\n' "$latest_output" | sed -n 's/^latest_version=//p' | sed -n '1p')" + arch="$(printf '%s\n' "$latest_output" | sed -n 's/^arch=//p' | sed -n '1p')" + asset="$(printf '%s\n' "$latest_output" | sed -n 's/^asset=//p' | sed -n '1p')" + can_upgrade=0 + if [ -z "$current" ] || version_gt "$latest_version" "$current"; then + can_upgrade=1 + fi + + printf '%s\n' "$latest_output" | sed '/^download_url=/d' + log_kv can_upgrade "$can_upgrade" + log_kv error '' +} + +mihomo_info() { + local current installed latest_output latest_rc latest_version arch asset can_upgrade + + installed=0 + current="" + arch="$(get_openwrt_arch)" + if current="$(get_mihomo_current_version)" && [ -n "$current" ]; then + installed=1 + asset="$(map_mihomo_asset "$arch" "$current" 2>/dev/null || true)" + else + asset="" + fi + + latest_output="$(get_mihomo_latest_info 2>/dev/null)" + latest_rc=$? + + log_kv component mihomo + log_kv installed "$installed" + log_kv current_version "$current" + log_kv arch "$arch" + log_kv asset "$asset" + + if [ $latest_rc -ne 0 ]; then + log_kv can_upgrade 0 + case "$latest_rc" in + 2) log_kv error 'unsupported_arch' ;; + 3) log_kv error 'fetch_failed' ;; + 4) log_kv error 'asset_not_found' ;; + *) log_kv error 'unknown_error' ;; + esac + return 0 + fi + + latest_version="$(printf '%s\n' "$latest_output" | sed -n 's/^latest_version=//p' | sed -n '1p')" + arch="$(printf '%s\n' "$latest_output" | sed -n 's/^arch=//p' | sed -n '1p')" + asset="$(printf '%s\n' "$latest_output" | sed -n 's/^asset=//p' | sed -n '1p')" + can_upgrade=0 + if [ -z "$current" ] || version_gt "$latest_version" "$current"; then + can_upgrade=1 + fi + + printf '%s\n' "$latest_output" | sed '/^download_url=/d' + log_kv can_upgrade "$can_upgrade" + log_kv error '' +} + +naiveproxy_info() { + local current installed latest_output latest_rc latest_version arch asset can_upgrade + + installed=0 + current="" + arch="$(get_openwrt_arch)" + if current="$(get_naiveproxy_current_version)" && [ -n "$current" ]; then + installed=1 + fi + + latest_output="$(get_naiveproxy_latest_info 2>/dev/null)" + latest_rc=$? + + log_kv component naiveproxy + log_kv installed "$installed" + log_kv current_version "$current" + log_kv arch "$arch" + log_kv asset '' + + if [ $latest_rc -ne 0 ]; then + log_kv can_upgrade 0 + case "$latest_rc" in + 3) log_kv error 'fetch_failed' ;; + 4) log_kv error 'asset_not_found' ;; + *) log_kv error 'unknown_error' ;; + esac + return 0 + fi + + latest_version="$(printf '%s\n' "$latest_output" | sed -n 's/^latest_version=//p' | sed -n '1p')" + arch="$(printf '%s\n' "$latest_output" | sed -n 's/^arch=//p' | sed -n '1p')" + asset="$(printf '%s\n' "$latest_output" | sed -n 's/^asset=//p' | sed -n '1p')" + can_upgrade=0 + if [ -z "$current" ]; then + can_upgrade=1 + elif ! naiveproxy_versions_equal "$latest_version" "$current" && version_gt "$latest_version" "$current"; then + can_upgrade=1 + fi + + printf '%s\n' "$latest_output" | sed '/^download_url=/d' + log_kv can_upgrade "$can_upgrade" + log_kv error '' +} + +xray_local_info() { + local current installed arch asset + + installed=0 + current="" + arch="$(get_openwrt_arch)" + asset="$(map_xray_asset "$arch" 2>/dev/null || true)" + if current="$(get_xray_current_version)" && [ -n "$current" ]; then + installed=1 + fi + + log_kv component xray + log_kv installed "$installed" + log_kv current_version "$current" + log_kv latest_version '' + log_kv arch "$arch" + log_kv asset "$asset" + log_kv can_upgrade 0 + log_kv error '' +} + +mihomo_local_info() { + local current installed arch asset + + installed=0 + current="" + arch="$(get_openwrt_arch)" + if current="$(get_mihomo_current_version)" && [ -n "$current" ]; then + installed=1 + asset="$(map_mihomo_asset "$arch" "$current" 2>/dev/null || true)" + else + asset="" + fi + + log_kv component mihomo + log_kv installed "$installed" + log_kv current_version "$current" + log_kv latest_version '' + log_kv arch "$arch" + log_kv asset "$asset" + log_kv can_upgrade 0 + log_kv error '' +} + +naiveproxy_local_info() { + local current installed arch + + installed=0 + current="" + arch="$(get_openwrt_arch)" + if current="$(get_naiveproxy_current_version)" && [ -n "$current" ]; then + installed=1 + fi + + log_kv component naiveproxy + log_kv installed "$installed" + log_kv current_version "$current" + log_kv latest_version '' + log_kv arch "$arch" + log_kv asset '' + log_kv can_upgrade 0 + log_kv error '' +} + +xray_upgrade() { + local latest_output latest_rc latest_version download_url tmp_dir zip_file unzip_cmd backup_file current_before current_after + + latest_output="$(get_xray_latest_info 2>/dev/null)" + latest_rc=$? + if [ $latest_rc -ne 0 ]; then + log_kv success 0 + case "$latest_rc" in + 2) log_kv message 'Unsupported ARCH' ;; + 3) log_kv message 'Failed to fetch release metadata' ;; + 4) log_kv message 'Matching release asset not found' ;; + *) log_kv message 'Unknown error' ;; + esac + return 0 + fi + + if ! unzip_cmd="$(select_unzip_cmd)"; then + log_kv success 0 + log_kv message 'Missing unzip support' + return 0 + fi + + latest_version="$(printf '%s\n' "$latest_output" | sed -n 's/^latest_version=//p' | sed -n '1p')" + download_url="$(printf '%s\n' "$latest_output" | sed -n 's/^download_url=//p' | sed -n '1p')" + current_before="$(get_xray_current_version 2>/dev/null || true)" + if [ -n "$current_before" ] && ! version_gt "$latest_version" "$current_before"; then + log_kv success 1 + log_kv previous_version "$current_before" + log_kv current_version "$current_before" + log_kv latest_version "$latest_version" + log_kv message 'Already up to date' + return 0 + fi + + tmp_dir="$(mktemp -d /tmp/ssrplus-xray.XXXXXX)" + if [ -z "$tmp_dir" ] || [ ! -d "$tmp_dir" ]; then + log_kv success 0 + log_kv message 'Failed to create temp directory' + return 0 + fi + + zip_file="$tmp_dir/xray.zip" + backup_file="$tmp_dir/xray.backup" + + trap "rm -rf '$tmp_dir'" EXIT INT TERM + + if ! download_file "$download_url" "$zip_file"; then + log_kv success 0 + log_kv message 'Download failed' + return 0 + fi + + if ! sh -c "$unzip_cmd \"$zip_file\" -d \"$tmp_dir\" >/dev/null 2>&1"; then + log_kv success 0 + log_kv message 'Extract failed' + return 0 + fi + + if [ ! -f "$tmp_dir/xray" ]; then + log_kv success 0 + log_kv message 'xray binary not found in archive' + return 0 + fi + + chmod 0755 "$tmp_dir/xray" || true + if [ -x "$XRAY_BINARY" ]; then + cp -fp "$XRAY_BINARY" "$backup_file" 2>/dev/null || true + fi + + if ! cp -f "$tmp_dir/xray" "$XRAY_BINARY"; then + if [ -f "$backup_file" ]; then + cp -f "$backup_file" "$XRAY_BINARY" 2>/dev/null || true + fi + log_kv success 0 + log_kv message 'Install failed' + return 0 + fi + + chmod 0755 "$XRAY_BINARY" || true + current_after="$(get_xray_current_version 2>/dev/null || true)" + if [ -z "$current_after" ]; then + if [ -f "$backup_file" ]; then + cp -f "$backup_file" "$XRAY_BINARY" 2>/dev/null || true + chmod 0755 "$XRAY_BINARY" || true + fi + log_kv success 0 + log_kv message 'Installed binary failed to run' + return 0 + fi + + if [ -x /etc/init.d/shadowsocksr ]; then + /etc/init.d/shadowsocksr restart >/dev/null 2>&1 || true + fi + + log_kv success 1 + log_kv previous_version "$current_before" + log_kv current_version "$current_after" + log_kv latest_version "$latest_version" + log_kv message 'Upgrade completed' + return 0 +} + +mihomo_upgrade() { + local latest_output latest_rc latest_version download_url tmp_dir gz_file gzip_cmd backup_file current_before current_after target_binary extracted_binary + + latest_output="$(get_mihomo_latest_info 2>/dev/null)" + latest_rc=$? + if [ $latest_rc -ne 0 ]; then + log_kv success 0 + case "$latest_rc" in + 2) log_kv message 'Unsupported ARCH' ;; + 3) log_kv message 'Failed to fetch release metadata' ;; + 4) log_kv message 'Matching release asset not found' ;; + *) log_kv message 'Unknown error' ;; + esac + return 0 + fi + + if ! gzip_cmd="$(select_gzip_cmd)"; then + log_kv success 0 + log_kv message 'Missing gzip support' + return 0 + fi + + latest_version="$(printf '%s\n' "$latest_output" | sed -n 's/^latest_version=//p' | sed -n '1p')" + download_url="$(printf '%s\n' "$latest_output" | sed -n 's/^download_url=//p' | sed -n '1p')" + current_before="$(get_mihomo_current_version 2>/dev/null || true)" + if [ -n "$current_before" ] && ! version_gt "$latest_version" "$current_before"; then + log_kv success 1 + log_kv previous_version "$current_before" + log_kv current_version "$current_before" + log_kv latest_version "$latest_version" + log_kv message 'Already up to date' + return 0 + fi + + target_binary="$(find_mihomo_binary 2>/dev/null || true)" + [ -n "$target_binary" ] || target_binary="$MIHOMO_BINARY" + + tmp_dir="$(mktemp -d /tmp/ssrplus-mihomo.XXXXXX)" + if [ -z "$tmp_dir" ] || [ ! -d "$tmp_dir" ]; then + log_kv success 0 + log_kv message 'Failed to create temp directory' + return 0 + fi + + gz_file="$tmp_dir/mihomo.gz" + backup_file="$tmp_dir/mihomo.backup" + extracted_binary="$tmp_dir/mihomo" + + trap "rm -rf '$tmp_dir'" EXIT INT TERM + + if ! download_file "$download_url" "$gz_file"; then + log_kv success 0 + log_kv message 'Download failed' + return 0 + fi + + if ! sh -c "$gzip_cmd \"$gz_file\" > \"$extracted_binary\""; then + log_kv success 0 + log_kv message 'Extract failed' + return 0 + fi + + if [ ! -s "$extracted_binary" ]; then + log_kv success 0 + log_kv message 'mihomo binary not found in archive' + return 0 + fi + + mkdir -p "$(dirname "$target_binary")" || true + chmod 0755 "$extracted_binary" || true + if [ -x "$target_binary" ]; then + cp -fp "$target_binary" "$backup_file" 2>/dev/null || true + fi + + if ! cp -f "$extracted_binary" "$target_binary"; then + if [ -f "$backup_file" ]; then + cp -f "$backup_file" "$target_binary" 2>/dev/null || true + fi + log_kv success 0 + log_kv message 'Install failed' + return 0 + fi + + chmod 0755 "$target_binary" || true + if [ "$target_binary" != "$MIHOMO_BINARY" ] && [ ! -x "$MIHOMO_BINARY" ]; then + ln -sf "$target_binary" "$MIHOMO_BINARY" 2>/dev/null || true + fi + + current_after="$(get_mihomo_current_version 2>/dev/null || true)" + if [ -z "$current_after" ]; then + if [ -f "$backup_file" ]; then + cp -f "$backup_file" "$target_binary" 2>/dev/null || true + chmod 0755 "$target_binary" || true + fi + log_kv success 0 + log_kv message 'Installed binary failed to run' + return 0 + fi + + if [ -x /etc/init.d/shadowsocksr ]; then + /etc/init.d/shadowsocksr restart >/dev/null 2>&1 || true + fi + + log_kv success 1 + log_kv previous_version "$current_before" + log_kv current_version "$current_after" + log_kv latest_version "$latest_version" + log_kv message 'Upgrade completed' + return 0 +} + +naiveproxy_upgrade() { + local latest_output latest_rc latest_version download_url tmp_dir archive_file xz_cmd tar_cmd backup_file current_before current_after target_binary extracted_binary + + latest_output="$(get_naiveproxy_latest_info 2>/dev/null)" + latest_rc=$? + if [ $latest_rc -ne 0 ]; then + log_kv success 0 + case "$latest_rc" in + 3) log_kv message 'Failed to fetch release metadata' ;; + 4) log_kv message 'Matching release asset not found' ;; + *) log_kv message 'Unknown error' ;; + esac + return 0 + fi + + if ! xz_cmd="$(select_xz_cmd)"; then + log_kv success 0 + log_kv message 'Missing xz support' + return 0 + fi + + if ! tar_cmd="$(select_tar_cmd)"; then + log_kv success 0 + log_kv message 'Extract failed' + return 0 + fi + + latest_version="$(printf '%s\n' "$latest_output" | sed -n 's/^latest_version=//p' | sed -n '1p')" + download_url="$(printf '%s\n' "$latest_output" | sed -n 's/^download_url=//p' | sed -n '1p')" + current_before="$(get_naiveproxy_current_version 2>/dev/null || true)" + if [ -n "$current_before" ] && ! version_gt "$latest_version" "$current_before"; then + log_kv success 1 + log_kv previous_version "$current_before" + log_kv current_version "$current_before" + log_kv latest_version "$latest_version" + log_kv message 'Already up to date' + return 0 + fi + + target_binary="$(find_naiveproxy_binary 2>/dev/null || true)" + [ -n "$target_binary" ] || target_binary="$NAIVEPROXY_BINARY" + + tmp_dir="$(mktemp -d /tmp/ssrplus-naiveproxy.XXXXXX)" + if [ -z "$tmp_dir" ] || [ ! -d "$tmp_dir" ]; then + log_kv success 0 + log_kv message 'Failed to create temp directory' + return 0 + fi + + archive_file="$tmp_dir/naiveproxy.tar.xz" + backup_file="$tmp_dir/naive.backup" + extracted_binary="" + + trap "rm -rf '$tmp_dir'" EXIT INT TERM + + if ! download_file "$download_url" "$archive_file"; then + log_kv success 0 + log_kv message 'Download failed' + return 0 + fi + + mkdir -p "$tmp_dir/extract" || { + log_kv success 0 + log_kv message 'Failed to create temp directory' + return 0 + } + + if ! sh -c "cd \"$tmp_dir/extract\" && $xz_cmd \"$archive_file\" | $tar_cmd -xf - >/dev/null 2>&1"; then + log_kv success 0 + log_kv message 'Extract failed' + return 0 + fi + + extracted_binary="$(find "$tmp_dir/extract" -type f -name naive | sed -n '1p')" + if [ -z "$extracted_binary" ] || [ ! -s "$extracted_binary" ]; then + log_kv success 0 + log_kv message 'naive binary not found in archive' + return 0 + fi + + mkdir -p "$(dirname "$target_binary")" || true + chmod 0755 "$extracted_binary" || true + if [ -x "$target_binary" ]; then + cp -fp "$target_binary" "$backup_file" 2>/dev/null || true + fi + + if ! cp -f "$extracted_binary" "$target_binary"; then + if [ -f "$backup_file" ]; then + cp -f "$backup_file" "$target_binary" 2>/dev/null || true + fi + log_kv success 0 + log_kv message 'Install failed' + return 0 + fi + + chmod 0755 "$target_binary" || true + if [ "$target_binary" != "$NAIVEPROXY_BINARY" ] && [ ! -x "$NAIVEPROXY_BINARY" ]; then + ln -sf "$target_binary" "$NAIVEPROXY_BINARY" 2>/dev/null || true + fi + + current_after="$(get_naiveproxy_current_version 2>/dev/null || true)" + if [ -z "$current_after" ]; then + if [ -f "$backup_file" ]; then + cp -f "$backup_file" "$target_binary" 2>/dev/null || true + chmod 0755 "$target_binary" || true + fi + log_kv success 0 + log_kv message 'Installed binary failed to run' + return 0 + fi + + if [ -x /etc/init.d/shadowsocksr ]; then + /etc/init.d/shadowsocksr restart >/dev/null 2>&1 || true + fi + + log_kv success 1 + log_kv previous_version "$current_before" + log_kv current_version "$current_after" + log_kv latest_version "$latest_version" + log_kv message 'Upgrade completed' + return 0 +} + +case "${1:-}" in + xray_info) + xray_info + ;; + xray_local_info) + xray_local_info + ;; + xray_upgrade) + xray_upgrade + ;; + mihomo_info) + mihomo_info + ;; + mihomo_local_info) + mihomo_local_info + ;; + mihomo_upgrade) + mihomo_upgrade + ;; + naiveproxy_info) + naiveproxy_info + ;; + naiveproxy_local_info) + naiveproxy_local_info + ;; + naiveproxy_upgrade) + naiveproxy_upgrade + ;; + country_mmdb_info) + geo_local_info country_mmdb + ;; + country_mmdb_local_info) + geo_local_info country_mmdb + ;; + country_mmdb_upgrade) + geo_upgrade country_mmdb + ;; + geosite_info) + geo_local_info geosite + ;; + geosite_local_info) + geo_local_info geosite + ;; + geosite_upgrade) + geo_upgrade geosite + ;; + v2ray_geo_info) + geo_local_info v2ray_geo + ;; + v2ray_geo_local_info) + geo_local_info v2ray_geo + ;; + v2ray_geo_upgrade) + geo_upgrade v2ray_geo + ;; + *) + log_kv success 0 + log_kv message 'Usage: update_components.sh xray_info|xray_local_info|xray_upgrade|mihomo_info|mihomo_local_info|mihomo_upgrade|naiveproxy_info|naiveproxy_local_info|naiveproxy_upgrade|country_mmdb_info|country_mmdb_local_info|country_mmdb_upgrade|geosite_info|geosite_local_info|geosite_upgrade|v2ray_geo_info|v2ray_geo_local_info|v2ray_geo_upgrade' + return 1 2>/dev/null || exit 1 + ;; +esac diff --git a/luci-app-ssr-plus/root/usr/share/ucitrack/luci-app-ssr-plus.json b/luci-app-ssr-plus/root/usr/share/ucitrack/luci-app-ssr-plus.json new file mode 100644 index 00000000..5f4740d9 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/share/ucitrack/luci-app-ssr-plus.json @@ -0,0 +1,4 @@ +{ + "config": "shadowsocksr", + "init": "shadowsocksr" +} diff --git a/microsocks/Makefile b/microsocks/Makefile new file mode 100644 index 00000000..5d807291 --- /dev/null +++ b/microsocks/Makefile @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=microsocks +PKG_VERSION:=1.0.5 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/rofl0r/microsocks/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=939d1851a18a4c03f3cc5c92ff7a50eaf045da7814764b4cb9e26921db15abc8 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=lean + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/microsocks + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=Tiny, portable SOCKS5 server + URL:=https://github.com/rofl0r/microsocks + DEPENDS:=+libpthread +endef + +define Package/microsocks/description + A SOCKS5 service that you can run on your remote boxes to tunnel connections + through them, if for some reason SSH doesn't cut it for you. +endef + +define Package/microsocks/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/bin/microsocks $(1)/usr/bin/microsocks +endef + +$(eval $(call BuildPackage,microsocks)) diff --git a/mstpd/Config.in b/mstpd/Config.in new file mode 100644 index 00000000..84d51478 --- /dev/null +++ b/mstpd/Config.in @@ -0,0 +1,12 @@ +menu "Configuration" + depends on PACKAGE_mstpd + +config MSTPD_RTNL_RCV_BUFSIZE + int "Netlink receive buffer size" + default 262144 + +config MSTPD_RTNL_SND_BUFSIZE + int "Netlink send buffer size" + default 262144 + +endmenu diff --git a/mstpd/Makefile b/mstpd/Makefile new file mode 100644 index 00000000..4a124e66 --- /dev/null +++ b/mstpd/Makefile @@ -0,0 +1,58 @@ +# +# Copyright (C) 2019 Alexandru Ardelean +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mstpd +PKG_VERSION:=0.1.0 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/mstpd/mstpd/tar.gz/$(PKG_VERSION)? +PKG_HASH:=03d1ff4ca189d54322562cb2891888768af719d2c73ceafa5f1ca96133dffeb2 + +PKG_MAINTAINER:=Alexandru Ardelean +PKG_LICENSE:=GPL-2.0-or-later +PKG_LICENSE_FILES:=LICENSE + +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/mstpd + SECTION:=net + CATEGORY:=Network + TITLE:=Multiple Spanning Tree Protocol daemon + URL:=https://github.com/mstpd/mstpd +endef + +define Package/mstpd/description + Multiple Spanning Tree Protocol daemon. + Implements MSTP which is not implemented yet in the Linux kernel. +endef + +define Package/mstpd/config + source "$(SOURCE)/Config.in" +endef + +TARGET_CFLAGS += \ + -DRTNL_RCV_BUFSIZE=$(CONFIG_MSTPD_RTNL_RCV_BUFSIZE) \ + -DRTNL_SND_BUFSIZE=$(CONFIG_MSTPD_RTNL_SND_BUFSIZE) + +MAKE_VARS+=MODE=prod + +define Package/mstpd/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mstpd $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mstpctl $(1)/usr/sbin + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/etc/init.d/mstpd.init $(1)/etc/init.d/mstpd + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) ./files/sbin/bridge-stp $(1)/sbin +endef + +$(eval $(call BuildPackage,mstpd)) diff --git a/mstpd/files/etc/init.d/mstpd.init b/mstpd/files/etc/init.d/mstpd.init new file mode 100644 index 00000000..bade419e --- /dev/null +++ b/mstpd/files/etc/init.d/mstpd.init @@ -0,0 +1,124 @@ +#!/bin/sh /etc/rc.common + +# shellcheck disable=SC2034 # foo appears unused. Verify it or export it. + +START=25 +STOP=99 + +MSTPCTL="/usr/sbin/mstpctl" +MSTPD="/usr/sbin/mstpd" + +USE_PROCD=1 + +mstpd_get_bridges() { + "$MSTPCTL" showbridge | grep -v "^ " | cut -d " " -f 1 2>/dev/null +} + +# mstpd log levels +# LOG_LEVEL_NONE 0 +# LOG_LEVEL_ERROR 1 +# LOG_LEVEL_INFO 2 +# LOG_LEVEL_DEBUG 3 +# LOG_LEVEL_STATE_MACHINE_TRANSITION 4 +# LOG_LEVEL_MAX 100 + +config_bridge_port_mstpd() { + local config="$1" + local index=$2 # FIXME: maybe remove index later + local name=$3 + + [ -n "$index" -a -n "$name" ] || return 0 + + config_get br_index "$config" br_index + [ -n "$br_index" ] || return 0 + [ "$index" = "$br_index" ] || return 0 + + config_get port_name "$config" name + [ -n "$port_name" ] || return 0 + + for opt in bpduguard; do + config_get $opt "$config" $opt + eval optval=\$$opt + [ -z "$optval" ] || "$MSTPCTL" "set$opt" "$name" "$port_name" "$optval" + done +} + +config_bridge_mstpd() { + local config="$1" + local optval= + local name= + local enable= + local mstid=0 # for the moment, using only MSTID + + config_get index "$config" index + [ -n "$index" ] || return 1 + + # Get bridge name + config_get name "$config" name + [ -n "$name" ] || return 0 + + config_get enable "$config" enable + if [ "$enable" != "1" ] ; then + return 0 + fi + + list_contains MSTPD_PREINSTALLED_BRIDGES "$name" || \ + "$MSTPCTL" addbridge "$name" + # All options here have 'set$opt' equivalent calls in mstpd, + # hence this trick with the loop + for opt in maxage fdelay maxhops hello ageing forcevers txholdcount; do + config_get $opt "$config" "$opt" + eval optval=\$$opt + [ -z "$optval" ] || "$MSTPCTL" set$opt "$name" "$optval" + done + config_get treeprio "$config" treeprio + [ -z "$treeprio" ] || $MSTPCTL settreeprio "$name" "$mstid" "$treeprio" + config_foreach config_bridge_port_mstpd bridge_port "$index" "$name" + CONFIGURED_BRIDGES="$CONFIGURED_BRIDGES $name" + export CONFIGURED_BRIDGES +} + +start_service() { + procd_open_instance + procd_set_param command $MSTPD + procd_append_param command -v 2 + procd_append_param command -d # don't daemonize, procd will handle that for us + procd_append_param command -s # print to syslog + + # set auto respawn behavior + procd_set_param respawn + + # reload config on respawn + procd_open_trigger + procd_add_raw_trigger "instance.start" 2000 "/etc/init.d/mstpd" "reload" + procd_close_trigger + + procd_close_instance +} + +service_running() { + pgrep mstpd >/dev/null 2>&1 +} + +reload_service() { + if ! running ; then + start + return + fi + + unset CONFIGURED_BRIDGES + MSTPD_PREINSTALLED_BRIDGES="$(mstpd_get_bridges)" + export MSTPD_PREINSTALLED_BRIDGES + + config_load 'mstpd' + config_foreach config_bridge_mstpd bridge + + for bridge in $(mstpd_get_bridges) ; do + list_contains CONFIGURED_BRIDGES "$bridge" || \ + $MSTPCTL delbridge "$bridge" + done + # return 0 (success) here, otherwise, and endless restart loop will occur from procd + # because the last return code may be mstpctl failing + return 0 +} + diff --git a/mstpd/files/sbin/bridge-stp b/mstpd/files/sbin/bridge-stp new file mode 100644 index 00000000..7b2cbc04 --- /dev/null +++ b/mstpd/files/sbin/bridge-stp @@ -0,0 +1,9 @@ +#!/bin/sh + +# Dummy file ; don't do anything ; +# Returning success here, tells the kernel to allow +# a userspace module to handle STP states +# +# Meanwhile, procd will start mstpd, and all will be well + +exit 0 diff --git a/mstpd/patches/010-bsd.patch b/mstpd/patches/010-bsd.patch new file mode 100644 index 00000000..120a0dbd --- /dev/null +++ b/mstpd/patches/010-bsd.patch @@ -0,0 +1,17 @@ +--- a/hmac_md5.c ++++ b/hmac_md5.c +@@ -356,10 +356,10 @@ caddr_t digest; /* caller di + */ + + /* start out by storing key in pads */ +- bzero(k_ipad, sizeof k_ipad); +- bzero(k_opad, sizeof k_opad); +- bcopy(key, k_ipad, key_len); +- bcopy( key, k_opad, key_len); ++ memset(k_ipad, 0, sizeof k_ipad); ++ memset(k_opad, 0, sizeof k_opad); ++ memcpy(k_ipad, key, key_len); ++ memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for(i = 0; i < 64; ++i) diff --git a/naiveproxy/Makefile b/naiveproxy/Makefile new file mode 100644 index 00000000..5786bb59 --- /dev/null +++ b/naiveproxy/Makefile @@ -0,0 +1,108 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=naiveproxy +PKG_VERSION:=148.0.7778.96-6 +PKG_RELEASE:=1 + +# intel 80386 & riscv64 & cortex-a76 +ifeq ($(ARCH_PREBUILT),aarch64_cortex-a76) + ARCH_PREBUILT:=aarch64_generic +else ifeq ($(ARCH_PREBUILT),i386_pentium-mmx) + ARCH_PREBUILT:=x86 +else ifeq ($(ARCH_PREBUILT),i386_pentium4) + ARCH_PREBUILT:=x86 +else ifeq ($(ARCH_PREBUILT),riscv64_riscv64) + ARCH_PREBUILT:=riscv64 +endif + +ifeq ($(ARCH_PACKAGES),aarch64_cortex-a53) + PKG_HASH:=2cc643c0818a5b84a873ceb20132050b98dd9e6d7184bb4df47c054cc14e8b56 +else ifeq ($(ARCH_PACKAGES),aarch64_cortex-a72) + PKG_HASH:=f402da04a623aa67cde64ab86948bf5f91e0968ce12c007c575ebff94b9780e6 +else ifeq ($(ARCH_PACKAGES),aarch64_generic) + PKG_HASH:=088249b5bd8018396eda31ce4712e2304a6576528f996e597ed908bb44e5a69d +else ifeq ($(ARCH_PACKAGES),arm_arm1176jzf-s_vfp) + PKG_HASH:=c38b1b218420a817d340f99a7c719415cdff2c6f6dc1ab0d28b7245c20db7336 +else ifeq ($(ARCH_PACKAGES),arm_arm926ej-s) + PKG_HASH:=1bfb00c5c2aaa34e2802e172a13d06fd8edfa5dc3c3a9a92f898d02b43e01509 +else ifeq ($(ARCH_PACKAGES),arm_cortex-a15_neon-vfpv4) + PKG_HASH:=0aecbb0745f22535f649d28f6b1a7f0f15695af53efda3cf4d33a636858bb64b +else ifeq ($(ARCH_PACKAGES),arm_cortex-a5_vfpv4) + PKG_HASH:=fae5b1218eaeeb39b59b16a933092e91b01225bbea472e88ff02773d332d79fc +else ifeq ($(ARCH_PACKAGES),arm_cortex-a7) + PKG_HASH:=6ac9e3222de2cc079e3c6cd465d8922031e4970ff05c50d3726e8e08a2c80d75 +else ifeq ($(ARCH_PACKAGES),arm_cortex-a7_neon-vfpv4) + PKG_HASH:=ed7b3f9e4cf38eaa9e3451c36203c472a9adfefb134da5acd2b47caf7e8b4885 +else ifeq ($(ARCH_PACKAGES),arm_cortex-a7_vfpv4) + PKG_HASH:=10242073e2aa04b8f09deb7907183ec9933a8f5cc052206c8580a56ab5b68a0d +else ifeq ($(ARCH_PACKAGES),arm_cortex-a8_vfpv3) + PKG_HASH:=c090e56714dc71c49248c7ec54a95a295daf4f56b66ad889c51ff0eae2ceaadd +else ifeq ($(ARCH_PACKAGES),arm_cortex-a9) + PKG_HASH:=2aafcb1169336924ce22eef37fef72a2e3b0504c83effc5c18a030e2e79245f8 +else ifeq ($(ARCH_PACKAGES),arm_cortex-a9_neon) + PKG_HASH:=4f119877f9b9326b8648b3015f129ed27f0eab3c1bf14ad59f4bd34b41c1a7ab +else ifeq ($(ARCH_PACKAGES),arm_cortex-a9_vfpv3-d16) + PKG_HASH:=d47b762719889870d0ecb1b700fd444b840757c34845bd9008031bcbe564dada +else ifeq ($(ARCH_PACKAGES),arm_mpcore) + PKG_HASH:=04d609af80585520ecb96a512f203c375f2483b41256c5c220c6d687297619d1 +else ifeq ($(ARCH_PACKAGES),arm_xscale) + PKG_HASH:=b98fcc755b4e542965707cae3fd87fb01e5fded09c3279f54825d917f9f0c9e2 +else ifeq ($(ARCH_PACKAGES),mipsel_24kc) + PKG_HASH:=c7c3f3482818fea9d72598d17a03b065b9bd8bccfbe7c8226860a8ab68b12e22 +else ifeq ($(ARCH_PACKAGES),mipsel_mips32) + PKG_HASH:=733ef1bfb67b12111ff05df38c4ee0b14228589f48be5f1f967efe04cffd7ce2 +else ifeq ($(ARCH_PACKAGES),riscv64) + PKG_HASH:=3b9cea024b0d8c79927c463741845f1623be9544dd3b7767fc9d55b0d7c564f4 +else ifeq ($(ARCH_PACKAGES),x86) + PKG_HASH:=06e4c5595b2de9f3f0f6a347add46f72e213a6686be1abc3bc8efca876c4a07d +else ifeq ($(ARCH_PACKAGES),x86_64) + PKG_HASH:=5fce9437c84c2cec6322753c424c5f2f5621cc91d6aa3743650e6d7b54407a44 +else + PKG_HASH:=dummy +endif + +PKG_SOURCE:=naiveproxy-v$(PKG_VERSION)-openwrt-$(ARCH_PACKAGES).tar.xz +PKG_SOURCE_URL:=https://github.com/klzgrad/naiveproxy/releases/download/v$(PKG_VERSION)/ +PKG_BUILD_DIR:=$(BUILD_DIR)/naiveproxy-v$(PKG_VERSION)-openwrt-$(ARCH_PACKAGES) + +PKG_LICENSE:=BSD 3-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=sbwml + +include $(INCLUDE_DIR)/package.mk + +define Package/naiveproxy + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=Make a fortune quietly + URL:=https://github.com/klzgrad/naiveproxy + DEPENDS:=@(aarch64||arm||i386||mipsel||riscv64||x86_64) +libatomic +endef + +define Package/naiveproxy/description + NaïveProxy uses Chrome's network stack to camouflage traffic with strong + censorship resistance and low detectability. Reusing Chrome's stack also + ensures best practices in performance and security. +endef + +define Package/naiveproxy/conffiles +/etc/config/naiveproxy +endef + +define Build/Compile +endef + +define Package/naiveproxy/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/naive $(1)/usr/bin/naive + $(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d + $(INSTALL_CONF) $(CURDIR)/files/naiveproxy.config $(1)/etc/config/naiveproxy + $(INSTALL_BIN) $(CURDIR)/files/naiveproxy.init $(1)/etc/init.d/naiveproxy +endef + +$(eval $(call BuildPackage,naiveproxy)) diff --git a/naiveproxy/files/naiveproxy.config b/naiveproxy/files/naiveproxy.config new file mode 100644 index 00000000..439e30be --- /dev/null +++ b/naiveproxy/files/naiveproxy.config @@ -0,0 +1,6 @@ + +config naiveproxy 'config' + option enable '0' + option listen_addr '' + option server_addr '' + option extra_argument '' diff --git a/naiveproxy/files/naiveproxy.init b/naiveproxy/files/naiveproxy.init new file mode 100644 index 00000000..e483b48a --- /dev/null +++ b/naiveproxy/files/naiveproxy.init @@ -0,0 +1,47 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 ImmortalWrt + +. /lib/functions.sh +. /lib/functions/procd.sh + +USE_PROCD=1 + +START=99 +STOP=10 + +init_conf() { + config_load "naiveproxy" + config_get "enable" "config" "enable" "0" + config_get "listen_addr" "config" "listen_addr" + config_get "server_addr" "config" "server_addr" + config_get "extra_argument" "config" "extra_argument" +} + +start_service() { + init_conf + [ "${enable}" == "1" ] || return 0 + + procd_open_instance naiveproxy + + procd_set_param command naive + procd_append_param command --listen="${listen_addr}" + procd_append_param command --proxy="${server_addr}" + [ -n "${extra_argument}" ] && procd_append_param command "${extra_argument}" + + procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} + procd_set_param limits core="unlimited" + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_close_instance +} + +reload_service() +{ + stop + start +} + +service_triggers() { + procd_add_reload_trigger "naiveproxy" +} diff --git a/ooniprobe/Makefile b/ooniprobe/Makefile new file mode 100644 index 00000000..01f5fd04 --- /dev/null +++ b/ooniprobe/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (C) 2020-2021 CZ.NIC, z. s. p. o. (https://www.nic.cz/) +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ooniprobe +PKG_VERSION:=3.16.5 +PKG_RELEASE:=1 + +PKG_SOURCE:=probe-cli-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/ooni/probe-cli/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=198f7a3507482bfbf0fb24c24f34e17c9f5adbfdf5d8c63774ecd816708a4438 + +PKG_MAINTAINER:=Jan Pavlinec +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=LICENSE.md + +PKG_BUILD_DIR:=$(BUILD_DIR)/probe-cli-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/ooni/probe-cli + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/ooniprobe + SECTION:=net + CATEGORY:=Network + TITLE:=OONI probe-cli + URL:=https://ooni.org + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Package/ooniprobe/description + The next generation of OONI(Open Observatory of Network Interference) + Probe Command Line Interface. +endef + +$(eval $(call GoBinPackage,ooniprobe)) +$(eval $(call BuildPackage,ooniprobe)) diff --git a/ooniprobe/test.sh b/ooniprobe/test.sh new file mode 100644 index 00000000..9ecab82f --- /dev/null +++ b/ooniprobe/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +ooniprobe version | grep "$2" diff --git a/openwrt-bandix/Makefile b/openwrt-bandix/Makefile new file mode 100644 index 00000000..42f1d465 --- /dev/null +++ b/openwrt-bandix/Makefile @@ -0,0 +1,111 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=bandix +PKG_VERSION:=0.12.9 +PKG_RELEASE:=1 + +PKG_LICENSE:=Apache-2.0 +PKG_MAINTAINER:=timsaya + +include $(INCLUDE_DIR)/package.mk + +# 使用OpenWrtçš„Rust映射机制 +include $(TOPDIR)/feeds/packages/lang/rust/rust-values.mk + +# 二进制文件的文件åå’ŒURL +RUST_BANDIX_VERSION:=0.12.9 +RUST_BINARY_FILENAME:=bandix-$(RUST_BANDIX_VERSION)-$(RUSTC_TARGET_ARCH).tar.gz + + +# 修正下载地å€å®šä¹‰æ–¹å¼ +PKG_SOURCE:=$(RUST_BINARY_FILENAME) +PKG_SOURCE_URL:=https://github.com/timsaya/bandix/releases/download/v$(RUST_BANDIX_VERSION) + +# 修正二进制文件校验值 +ifeq ($(ARCH),aarch64) + PKG_HASH:=17803eeb6964187626e6af2e2b0a3b081d87a8017ff2b6505ba313b0c7b8ba7f +else ifeq ($(ARCH),arm) # update.sh skip this tag, do not delete this comment + # Ref https://github.com/openwrt/packages/blob/master/lang/rust/rust-values.mk + + ARM_CPU_TYPE:=arm-armel + ifeq ($(CONFIG_arm_v6)$(CONFIG_arm_v7),) + ARM_CPU_TYPE:=$(subst arm-,armv5te-,$(ARM_CPU_TYPE)) + else ifeq ($(CONFIG_arm_v7),y) + ARM_CPU_TYPE:=$(subst arm-,armv7-,$(ARM_CPU_TYPE)) + endif + + ifeq ($(CONFIG_HAS_FPU),y) + ARM_CPU_TYPE:=$(subst -armel,-armhf,$(ARM_CPU_TYPE)) + endif + + ifeq ($(ARM_CPU_TYPE),arm-armel) + PKG_HASH:=cbf9cf705218211e0a5cd1427049632aa40086831feee2994e9d4b7b2cf46ab4 + else ifeq ($(ARM_CPU_TYPE),arm-armhf) + PKG_HASH:=2901c5f98e77fce574bcaef1aa8c20acd58ca341f3f3bd5f3bc80d745946f632 + else ifeq ($(ARM_CPU_TYPE),armv5te-armel) + PKG_HASH:=390840c939cec718570cd8cbf50ed130fd02d7f75b80d74af251bd1ecd0f43a8 + else ifeq ($(ARM_CPU_TYPE),armv7-armel) + PKG_HASH:=965f9e88398f42cf5535612b58629b89c058db46afaf3c814929a7cfc9fa4e3b + else ifeq ($(ARM_CPU_TYPE),armv7-armhf) + PKG_HASH:=f47df37959f73b2188f89faf8c9a3217966ca4c1389f695886f263d28911e8fb + else + PKG_HASH:=dummy + endif +else ifeq ($(ARCH),mips) + PKG_HASH:=318587b09b37d1ab8af96466e5191ce32c4dbc92294f5c55826ebe1a88c7bcab +else ifeq ($(ARCH),mipsel) + PKG_HASH:=fd1b12b7cd2034aa8afa89901d0d38784528f10921b6c0f806dac9dcbf523085 +else ifeq ($(ARCH),powerpc64) + PKG_HASH:=24dab3f89f8930cb925ec1a20d73111e09bae7e6a87954b56a681395660f6ed4 +else ifeq ($(ARCH),riscv64) + PKG_HASH:=916bf42c60c49df5c3ee6f4a60ce542d2b080788445b9bf47f3322eb9a5b66cf +else ifeq ($(ARCH),x86_64) + PKG_HASH:=4909cf2e80861d082c4d4870950259d8c6f14e606f9dfa16c92514f178f3ae40 +else + PKG_HASH:=dummy +endif + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=Bandix - Network traffic monitoring tool + DEPENDS:=+zoneinfo-all +conntrack +iw +endef + +define Package/$(PKG_NAME)/description + Bandix core service for network traffic monitoring +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR)/bin + gzip -dc "$(DL_DIR)/$(PKG_SOURCE)" | tar -C $(PKG_BUILD_DIR)/bin --strip-components=1 -xf - + $(Build/Patch) +endef + +define Build/Compile + # nothing to do +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/bandix $(1)/usr/bin/ + + # 添加å¯åŠ¨è„šæœ¬å’Œé…置文件 + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_BIN) ./files/bandix.init $(1)/etc/init.d/bandix + + # 安装é…置文件 + $(INSTALL_DIR) $(1)/usr/share/bandix + $(INSTALL_CONF) ./files/bandix.config $(1)/etc/config/bandix + + # é…ç½® sysupgrade ä¿ç•™åˆ—表 + $(INSTALL_DIR) $(1)/lib/upgrade/keep.d + $(INSTALL_DATA) ./files/bandix.keep $(1)/lib/upgrade/keep.d/bandix +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/bandix +endef + +$(eval $(call BuildPackage,bandix)) diff --git a/openwrt-bandix/files/bandix.config b/openwrt-bandix/files/bandix.config new file mode 100644 index 00000000..0341c1e7 --- /dev/null +++ b/openwrt-bandix/files/bandix.config @@ -0,0 +1,41 @@ + +config bandix 'general' + option iface 'br-lan' + option port '8686' + option data_dir '/usr/share/bandix' + + option language 'auto' + option theme 'auto' + + option log_level 'info' + option tc_order 'default' + option tc_backend 'auto' + option netlink_priority '' + option tcx_anchor_ingress_id '' + option tcx_anchor_egress_id '' + + +config bandix 'traffic' + option enabled '0' + option speed_unit 'bytes' + option offline_timeout '120' + option traffic_realtime_window '600' + option traffic_flush_interval '600' + option traffic_enable_storage '0' + option traffic_export_url '' + option traffic_event_url '' + option traffic_additional_subnets '' + option traffic_exclude_iface_device '0' + option traffic_neighbor_flush_enable '0' + option traffic_neighbor_flush_interval '600' + + +config bandix 'connections' + option enabled '0' + + +config bandix 'dns' + option enabled '0' + option dns_max_records '10000' + option dns_enable_storage '0' + option dns_flush_interval '900' diff --git a/openwrt-bandix/files/bandix.init b/openwrt-bandix/files/bandix.init new file mode 100644 index 00000000..7cafa2df --- /dev/null +++ b/openwrt-bandix/files/bandix.init @@ -0,0 +1,160 @@ +#!/bin/sh /etc/rc.common + +START=99 +USE_PROCD=1 +PROG=/usr/bin/bandix + +service_triggers() { + procd_add_reload_trigger "bandix" +} + +reload_service() { + restart +} + +start_service() { + local iface + local port + local data_dir + local log_level + local tc_order + local tc_backend + local tc_priority + local netlink_priority + local tcx_anchor_ingress_id + local tcx_anchor_egress_id + local traffic_enabled + local traffic_realtime_window + local traffic_flush_interval + local traffic_enable_storage + local traffic_export_url + local traffic_event_url + local traffic_additional_subnets + local traffic_exclude_iface_device + local traffic_neighbor_flush_enable + local traffic_neighbor_flush_interval + local connections_enabled + local dns_enabled + local dns_max_records + local dns_enable_storage + local dns_flush_interval + + config_load 'bandix' + config_get iface 'general' 'iface' + config_get port 'general' 'port' + config_get data_dir 'general' 'data_dir' + config_get log_level 'general' 'log_level' + config_get tc_order 'general' 'tc_order' + config_get tc_backend 'general' 'tc_backend' + config_get tc_priority 'general' 'tc_priority' + config_get netlink_priority 'general' 'netlink_priority' + config_get tcx_anchor_ingress_id 'general' 'tcx_anchor_ingress_id' + config_get tcx_anchor_egress_id 'general' 'tcx_anchor_egress_id' + config_get_bool traffic_enabled 'traffic' 'enabled' + config_get traffic_realtime_window 'traffic' 'traffic_realtime_window' + config_get traffic_flush_interval 'traffic' 'traffic_flush_interval' + config_get_bool traffic_enable_storage 'traffic' 'traffic_enable_storage' + config_get traffic_export_url 'traffic' 'traffic_export_url' + config_get traffic_event_url 'traffic' 'traffic_event_url' + config_get traffic_additional_subnets 'traffic' 'traffic_additional_subnets' + config_get_bool traffic_exclude_iface_device 'traffic' 'traffic_exclude_iface_device' '0' + config_get_bool traffic_neighbor_flush_enable 'traffic' 'traffic_neighbor_flush_enable' '0' + config_get traffic_neighbor_flush_interval 'traffic' 'traffic_neighbor_flush_interval' '600' + config_get_bool connections_enabled 'connections' 'enabled' + config_get_bool dns_enabled 'dns' 'enabled' + config_get dns_max_records 'dns' 'dns_max_records' + config_get_bool dns_enable_storage 'dns' 'dns_enable_storage' + config_get dns_flush_interval 'dns' 'dns_flush_interval' + + + [ "$connections_enabled" != 1 ] && [ "$traffic_enabled" != 1 ] && [ "$dns_enabled" != 1 ] && return 1 + + # æž„å»ºåŸºç¡€å‘½ä»¤è¡Œå‚æ•° + local args="--iface $iface --port $port --data-dir $data_dir" + if [ -n "$log_level" ]; then + args="$args --log-level $log_level" + fi + if [ -z "$tc_order" ]; then + case "$tc_priority" in + 1) tc_order="first" ;; + 65535) tc_order="last" ;; + *) tc_order="default" ;; + esac + fi + [ -z "$tc_order" ] && tc_order="default" + if [ -n "$tc_order" ]; then + args="$args --tc-order $tc_order" + fi + [ -z "$tc_backend" ] && tc_backend="auto" + if [ -n "$tc_backend" ]; then + args="$args --tc-backend $tc_backend" + fi + if [ -n "$netlink_priority" ]; then + args="$args --netlink-priority $netlink_priority" + fi + if [ -n "$tcx_anchor_ingress_id" ]; then + args="$args --tcx-anchor-ingress-id $tcx_anchor_ingress_id" + fi + if [ -n "$tcx_anchor_egress_id" ]; then + args="$args --tcx-anchor-egress-id $tcx_anchor_egress_id" + fi + + # 添加æµé‡ç›‘æŽ§ç›¸å…³å‚æ•° + if [ "$traffic_enabled" -eq 1 ]; then + args="$args --enable-traffic" + fi + if [ -n "$traffic_realtime_window" ]; then + args="$args --traffic-realtime-window $traffic_realtime_window" + fi + if [ -n "$traffic_flush_interval" ]; then + args="$args --traffic-flush-interval $traffic_flush_interval" + fi + if [ "$traffic_enable_storage" -eq 1 ]; then + args="$args --traffic-enable-storage" + fi + if [ -n "$traffic_export_url" ]; then + args="$args --traffic-export-url $traffic_export_url" + fi + if [ -n "$traffic_event_url" ]; then + args="$args --traffic-event-url $traffic_event_url" + fi + if [ -n "$traffic_additional_subnets" ]; then + args="$args --traffic-additional-subnets $traffic_additional_subnets" + fi + if [ "$traffic_exclude_iface_device" -eq 1 ]; then + args="$args --traffic-exclude-iface-device" + fi + if [ "$traffic_neighbor_flush_enable" -eq 1 ]; then + args="$args --traffic-neighbor-flush-enable" + fi + if [ -n "$traffic_neighbor_flush_interval" ]; then + args="$args --traffic-neighbor-flush-interval $traffic_neighbor_flush_interval" + fi + + # æ·»åŠ è¿žæŽ¥ç»Ÿè®¡ç›‘æŽ§å‚æ•° + if [ "$connections_enabled" -eq 1 ]; then + args="$args --enable-connection" + fi + + # 添加 DNS ç›‘æŽ§å‚æ•° + if [ "$dns_enabled" -eq 1 ]; then + args="$args --enable-dns" + fi + if [ -n "$dns_max_records" ]; then + args="$args --dns-max-records $dns_max_records" + fi + if [ "$dns_enable_storage" -eq 1 ]; then + args="$args --dns-enable-storage" + fi + if [ -n "$dns_flush_interval" ]; then + args="$args --dns-flush-interval $dns_flush_interval" + fi + + procd_open_instance bandix + procd_set_param command $PROG $args + procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-60} ${respawn_retry:-3} + procd_set_param stderr 1 + procd_set_param stdout 1 + procd_set_param pidfile /var/run/bandix.pid + procd_close_instance +} diff --git a/openwrt-bandix/files/bandix.keep b/openwrt-bandix/files/bandix.keep new file mode 100644 index 00000000..a6d28543 --- /dev/null +++ b/openwrt-bandix/files/bandix.keep @@ -0,0 +1 @@ +/usr/share/bandix diff --git a/openwrt-bandix/update.sh b/openwrt-bandix/update.sh new file mode 100755 index 00000000..a028c217 --- /dev/null +++ b/openwrt-bandix/update.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# dependent: curl jq +# + +export CURDIR="$(cd "$(dirname "$0")"; pwd)" + +# func +github_getLatest() { + curl -sSL "https://api.github.com/repos/$1/$2/releases/latest" +} + +LATEST_INFO="$(github_getLatest timsaya bandix)" + +# version check +LATEST_VERSION="$(jq '.tag_name' -r <<< "$LATEST_INFO" | sed 's|^v||')" +[ -n "$LATEST_VERSION" ] || exit 1 +RUST_BANDIX_VERSION="$(sed -n 's|RUST_BANDIX_VERSION:=||p' "$CURDIR/Makefile")" +[ "$RUST_BANDIX_VERSION" != "$LATEST_VERSION" ] || exit 0 + +# update PKG_HASH +# 从 Makefile 中æå– $ARCH 并将它们按字符多寡é™åºæŽ’列, ç”¨äºŽè¿›è¡Œæ¨¡ç³ŠåŒ¹é… +ARCHS="$(sed -En '/ifeq \(\$\((ARCH|ARM_CPU_TYPE)\),.+\)$/{s|.+,([^\)]+).*|\1|;p}' "$CURDIR/Makefile" | sort -r)" +for (( i=0; i<$(jq -r '.assets | length' <<< "$LATEST_INFO"); i++ )); do + name=$(jq -r '.assets['$i'].name | select(contains("bandix"))' <<< "$LATEST_INFO") + [ -n "$name" ] || continue + browser_download_url=$(jq -r '.assets['$i'].browser_download_url' <<< "$LATEST_INFO") + digest_type=$(jq -r '.assets['$i'].digest' <<< "$LATEST_INFO" | cut -f1 -d':') + digest=$(jq -r '.assets['$i'].digest' <<< "$LATEST_INFO" | cut -f2 -d':') + + # 精简的 Github Assets name + arch="$(awk -F'-' '{ printf "%s-%s", $1, $NF }' <<< "$(sed "s|bandix-$LATEST_VERSION-||;s|\.tar\..*||" <<< "$name")")" + for ARCH in $ARCHS; do + # 使用从 Makefile 中æå–çš„ $ARCH 对精简的 Github Assets name è¿›è¡Œæ¨¡ç³ŠåŒ¹é… + ! grep -Eq "$(sed 's|-armel|-.*abi$|;s|-armhf|-.*abihf$|' <<< "$ARCH")" <<< "$arch" || break + unset ARCH + done + line="$(sed -En "/ifeq \(\\$\((ARCH|ARM_CPU_TYPE)\),$ARCH\)$/=" "$CURDIR/Makefile")" + [ -n "$line" ] || continue + + if [[ "$digest_type" != "sha256" ]]; then + digest="$(curl -fsSL "$browser_download_url" | sha256sum | awk '{print $1}')" + fi + sed -i "$((line + 1))s|\(PKG_HASH:=\).*|\1$digest|" "$CURDIR/Makefile" +done + +# update version +sed -i "s|\(PKG_VERSION:=\).*|\1$LATEST_VERSION|" "$CURDIR/Makefile" +sed -i "s|\(RUST_BANDIX_VERSION:=\).*|\1$LATEST_VERSION|" "$CURDIR/Makefile" diff --git a/pdnsd-alt/Makefile b/pdnsd-alt/Makefile new file mode 100644 index 00000000..3b66d14d --- /dev/null +++ b/pdnsd-alt/Makefile @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pdnsd +PKG_VERSION:=1.3.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/pdnsd/tar.gz/$(PKG_VERSION)? +PKG_HASH:=ce76cecc5238ab48c0a78baa8225ce896f204fe9bda61845eeaf70f551b17478 + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/pdnsd-alt + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE:=Proxy DNS Server + DEPENDS:=+libpthread +endef + +define Package/pdnsd-alt/description + pdnsd, is an IPv6 capable proxy DNS server with permanent caching (the cache + contents are written to hard disk on exit) that is designed to cope with + unreachable or down DNS servers (for example in dial-in networking). + + pdnsd can be used with applications that do dns lookups, eg on startup, and + can't be configured to change that behaviour, to prevent the often + minute-long hangs (or even crashes) that result from stalled dns queries. +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include + +CONFIGURE_ARGS += \ + --with-cachedir=/var/pdnsd \ + --with-target=Linux + +define Package/pdnsd-alt/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pdnsd $(1)/usr/sbin/pdnsd + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/pdnsd-ctl $(1)/usr/sbin/pdnsd-ctl + + #$(INSTALL_DIR) $(1)/etc + #$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/pdnsd.conf.sample $(1)/etc/pdnsd.conf + #$(INSTALL_DIR) $(1)/etc/init.d + #$(INSTALL_BIN) ./files/pdnsd.init $(1)/etc/init.d/pdnsd +endef + +$(eval $(call BuildPackage,pdnsd-alt)) + diff --git a/pdnsd-alt/files/pdnsd.init b/pdnsd-alt/files/pdnsd.init new file mode 100644 index 00000000..6db37992 --- /dev/null +++ b/pdnsd-alt/files/pdnsd.init @@ -0,0 +1,46 @@ +#!/bin/sh /etc/rc.common + +START=65 +NAME=pdnsd +DESC="proxy DNS server" + +DAEMON=/usr/sbin/pdnsd +PID_FILE=/var/run/$NAME.pid +CACHEDIR=/var/pdnsd +CACHE=$CACHEDIR/pdnsd.cache + +USER=nobody +GROUP=nogroup + +start() { + echo -n "Starting $DESC: $NAME" + + gen_cache + + $DAEMON --daemon -p $PID_FILE + echo " ." +} + +stop() { + echo -n "Stopping $DESC: $NAME" + kill `cat $PID_FILE` > /dev/null 2>&1 + rm -rf $PID_FILE + echo " ." +} + +restart() { + echo "Restarting $DESC: $NAME... " + stop + sleep 2 + start +} + +gen_cache() +{ + if ! test -f "$CACHE"; then + mkdir -p `dirname $CACHE` + dd if=/dev/zero of="$CACHE" bs=1 count=4 2> /dev/null + chown -R $USER.$GROUP $CACHEDIR + fi +} + diff --git a/pgyvpn/Makefile b/pgyvpn/Makefile new file mode 100644 index 00000000..7379e4fd --- /dev/null +++ b/pgyvpn/Makefile @@ -0,0 +1,116 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/target.mk + +ifeq ($(ARCH),arm) + ifneq ($(findstring $(CPU_SUBTYPE), neon neon-vfpv4 vfpv3),) + PKG_ARCH_PGYYPN:=arm_$(CPU_TYPE)_$(CPU_SUBTYPE)-$(LIBC)-unknown + else ifneq ($(findstring $(CPU_TYPE), cortex-a9),) + PKG_ARCH_PGYYPN:=arm_cortex-a9-$(LIBC)-unknown + else + PKG_ARCH_PGYYPN:=arm_cortex-a7-$(LIBC)-unknown + endif +endif +ifeq ($(ARCH),aarch64) + ifneq ($(findstring $(CPU_TYPE), cortex-a53 cortex-a72),) + PKG_ARCH_PGYYPN:=aarch64_$(CPU_TYPE)-$(LIBC)-unknown + else + PKG_ARCH_PGYYPN:=aarch64_generic-$(LIBC)-unknown + endif +endif +ifeq ($(ARCH),mips) + PKG_ARCH_PGYYPN:=mips_24kc-$(LIBC)-unknown +endif +ifeq ($(ARCH),mipsel) + ifneq ($(findstring $(CPU_TYPE), 24kec 74kc 1004kc),) + PKG_ARCH_PGYYPN:=$(ARCH)_$(CPU_TYPE)-$(LIBC)-unknown + else + PKG_ARCH_PGYYPN:=mipsel_24kc-$(LIBC)-unknown + endif +endif +ifeq ($(BOARD),x86) + ifeq ($(ARCH),x86_64) + PKG_ARCH_PGYYPN:=x86_64-$(LIBC)-unknown + else + PKG_ARCH_PGYYPN:=i386_pentium-mmx-$(LIBC)-unknown + endif +endif + +PKG_NAME:=pgyvpn +PKG_VERSION:=3.1.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=pgyvpnsvr +PKG_SOURCE_URL:=https://mirrors.oray.com/orayos/packages/$(PKG_NAME)/$(PKG_ARCH_PGYYPN)/$(PKG_VERSION)/bin +PKG_HASH:=skip + +PKG_FLAGS:=nonshared +PKG_MAINTAINER:=Oray + +include $(INCLUDE_DIR)/package.mk + +define Package/pgyvpn + SECTION:=net + CATEGORY:=Network + SUBMENU:=VPN + DEPENDS:=@(arm||aarch64||mips||mipsel||i386||x86_64) \ + +iptables +libc +libopenssl +librt \ + +libpthread +libstdcpp +kmod-tun + TITLE:=PuGongYing VPN, Fast networking + URL:=https://pgy.oray.com/ +endef + +define Package/pgyvpn/description + PuGongYing VPN is a product of Oray Company, support custom network, account security + system, traffic monitoring, cloud application access, virtual serial port, etc. +endef + +define Download/extra + FILE:=pgyvpn_oraysl + URL:=$(PKG_SOURCE_URL) + HASH:=skip +endef +$(eval $(call Download,extra)) + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + mv $(DL_DIR)/{pgyvpn_oraysl,pgyvpnsvr} $(PKG_BUILD_DIR) + chmod +x $(PKG_BUILD_DIR)/{pgyvpn_oraysl,pgyvpnsvr} +endef + +define Build/Compile + true +endef + +define Package/pgyvpn/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/share/pgyvpn + + $(CP) $(PKG_BUILD_DIR)/{pgyvpn_oraysl,pgyvpnsvr} $(1)/usr/sbin + $(INSTALL_BIN) ./files/etc/init.d/* $(1)/etc/init.d + $(INSTALL_CONF) ./files/etc/config/* $(1)/etc/config + $(INSTALL_BIN) ./files/etc/hotplug.d/iface/* $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) ./files/usr/share/pgyvpn/* $(1)/usr/share/pgyvpn +endef + +define Package/pgyvpn/preinst + #!/bin/sh + [ -z "$${IPKG_INSTROOT}" ] && { + pidof pgyvpnsvr > /dev/null && \ + test -f $${PKG_ROOT}etc/init.d/pgyvpn && \ + /etc/init.d/pgyvpn stop; true + } + exit 0 +endef + +define Package/pgyvpn/postinst + #!/bin/sh + [ -z "$${IPKG_INSTROOT}" ] && { + /etc/init.d/pgyvpn restart; true + } + exit 0 +endef + +$(eval $(call BuildPackage,pgyvpn)) diff --git a/pgyvpn/files/etc/config/pgyvpn b/pgyvpn/files/etc/config/pgyvpn new file mode 100644 index 00000000..e9b60db3 --- /dev/null +++ b/pgyvpn/files/etc/config/pgyvpn @@ -0,0 +1,20 @@ +config base 'base' + option filename '/usr/sbin/pgyvpnsvr' + option check_route_conflict '1' + option script_p2pinit '/usr/share/pgyvpn/p2pinit.sh' + option script_vncinit '/usr/share/pgyvpn/vncinit.sh' + option script_progress '/usr/share/pgyvpn/vpnprogress.sh' + +config secure 'secure' + option encrypt '0' + +config log 'log' + option path '/tmp/oray/pgyvpnsvr/log' + option mask '7' + +config oraysl 'oraysl' + option filename '/usr/sbin/pgyvpn_oraysl' + option logpath '/tmp/oray/pgyvpn_oraysl/log' + option statusfilename '/tmp/oray/pgyvpn_oraysl/status' + option pidfilename '/tmp/oray/pgyvpn_oraysl/pid' + diff --git a/pgyvpn/files/etc/hotplug.d/iface/pgyvpn b/pgyvpn/files/etc/hotplug.d/iface/pgyvpn new file mode 100755 index 00000000..4e3d3261 --- /dev/null +++ b/pgyvpn/files/etc/hotplug.d/iface/pgyvpn @@ -0,0 +1,5 @@ +#!/bin/sh + +[ "$INTERFACE" == "wan" -a "$ACTION" == "ifup" ] && { + /etc/init.d/pgyvpn restart +} diff --git a/pgyvpn/files/etc/init.d/pgyvpn b/pgyvpn/files/etc/init.d/pgyvpn new file mode 100755 index 00000000..8a9f48ec --- /dev/null +++ b/pgyvpn/files/etc/init.d/pgyvpn @@ -0,0 +1,150 @@ +#!/bin/sh /etc/rc.common + +. /lib/functions.sh + +START=62 +STOP=62 +USE_PROCD=1 + +write_log() +{ + echo $* + logger -t pgyvpn "$*" +} + +start_service() +{ + local res_def_path='/usr/share/pgyvpn' + local pgyvpn_filename + local username + local password + local check_route_conflict + local log_path + local log_mask + local local_ip + local local_mask + local use_encrypt + local script_p2pinit + local script_vncinit + local script_progress + local oraysl_filename + local oraysl_logpath + local oraysl_statusfilename + local oraysl_pidfilename + local login_status + local enable_status + + #read uci config + config_load pgyvpn + config_get login_status base login_status + config_get enable_status base enable_status + + if [ -z $enable_status ] || [ "$enable_status" == "0" ]; then + exit 0 + fi + + config_get pgyvpn_filename base filename '/usr/sbin/pgyvpnsvr' + config_get username base user '' + config_get password base pwd '' + config_get_bool check_route_conflict base check_route_conflict 0 + config_get log_path log path '/tmp/oray/pgyvpnsvr/log' + config_get log_mask log mask '0x77' + config_get_bool use_encrypt secure encrypt 0 + config_get script_p2pinit base script_p2pinit "$res_def_path/p2pinit.sh" + config_get script_vncinit base script_vncinit "$res_def_path/vncinit.sh" + config_get script_progress base script_progress "$res_def_path/vpnprogress.sh" + config_get oraysl_filename oraysl filename '/usr/sbin/pgyvpn_oraysl' + config_get oraysl_logpath oraysl logpath '/tmp/oray/pgyvpn_oraysl/log' + config_get oraysl_statusfilename oraysl statusfilename '/tmp/oray/pgyvpn_oraysl/status' + config_get oraysl_pidfilename oraysl pidfilename '/tmp/oray/pgyvpn_oraysl/pid' + local_ip=$(uci get network.lan.ipaddr 2> /dev/null) + local_mask=$(uci get network.lan.netmask 2> /dev/null) + + local host_name=$(uci get system.@system[0].hostname 2> /dev/null) + + #print config + write_log "pgyvpn app filename is $pgyvpn_filename" + write_log "username is $username" + write_log "log path is $log_path" + write_log "log mask is $log_mask" + write_log "local ip is $local_ip" + write_log "local mask is $local_mask" + write_log "script for p2p init is $script_p2pinit" + write_log "script for vnc init is $script_vncinit" + write_log "script for progress is $script_progress" + write_log "oraysl filename is $oraysl_filename" + write_log "oraysl log path is $oraysl_logpath" + write_log "oraysl status filename is $oraysl_statusfilename" + write_log "oraysl pid filename is $oraysl_pidfilename" + [ $use_encrypt -eq 1 ] && write_log 'use encrypt' || write_log 'no use encrypt' + + #make app command args + local cmd_arg='' + local api_address="pgyapi.oray.net" + cmd_arg="$cmd_arg --apiaddress $api_address --usehttps --rpc --autologinAsRpc" + #cmd_arg="$cmd_arg --apiaddress $api_address --usehttps --autologinAsRpc" + cmd_arg="$cmd_arg --logsize 4194304 --logpath $log_path --logmask $log_mask" + cmd_arg="$cmd_arg --orayslpath $oraysl_filename --oraysllogpath $oraysl_logpath --orayslstatusfilename $oraysl_statusfilename --orayslpidfilename $oraysl_pidfilename" + [ -n "$script_p2pinit" ] && cmd_arg="$cmd_arg -n $script_p2pinit" + [ -n "$script_vncinit" ] && cmd_arg="$cmd_arg -C $script_vncinit" + # [ -n "$script_progress" ] && cmd_arg="$cmd_arg -n $script_progress" + [ -n "$script_progress" ] && cmd_arg="$cmd_arg -N $script_progress" + [ -n "$local_ip" ] && cmd_arg="$cmd_arg --localip $local_ip" + [ -n "$local_mask" ] && cmd_arg="$cmd_arg --localmask $local_mask" + [ $use_encrypt -eq 1 ] && cmd_arg="$cmd_arg -r" + [ $check_route_conflict -ne 0 ] && cmd_arg="$cmd_arg --vipmask 255.255.255.255" + [ -n "$host_name" ] && cmd_arg="$cmd_arg --hostname $host_name" + + #start app + procd_open_instance + procd_set_param command $pgyvpn_filename $cmd_arg + [ -n "$username" ] && procd_append_param command --sn "$username" + [ -n "$password" ] && procd_append_param command --pwd "$password" + procd_set_param respawn + procd_close_instance + +} + +stop_service() +{ + #remove p2p firewall + iptables -w -t filter -F oray_vpn_p2p 2> /dev/null + while true; + do + iptables -w -t filter -D INPUT -j oray_vpn_p2p 2>/dev/null + [ $? -ne 0 ] && break + done + iptables -w -t filter -X oray_vpn_p2p 2> /dev/null + + #remove forward firewall + iptables -w -t filter -F oray_vpn_vnc 2> /dev/null + while true; + do + iptables -w -t filter -D INPUT -j oray_vpn_vnc 2>/dev/null + [ $? -ne 0 ] && break + done + + while true; + do + iptables -w -t filter -D FORWARD -j oray_vpn_vnc 2>/dev/null + [ $? -ne 0 ] && break + done + + while true; + do + iptables -w -t filter -D OUTPUT -j oray_vpn_vnc 2>/dev/null + [ $? -ne 0 ] && break + done + iptables -w -t filter -X oray_vpn_vnc 2> /dev/null + + #stop oraysl + killall pgyvpn_oraysl 2> /dev/null + + rm /tmp/pgyvpnsvr_mutex 2> /dev/null #delete mutex file + rm /tmp/pgyvpnsvr_rpc_mutex 2> /dev/null #delete rpc mutex file + + local oraysl_statusfilename + config_load pgyvpn + config_get oraysl_statusfilename oraysl statusfilename '/tmp/oray/pgyvpn_oraysl/status' + rm oraysl_statusfilename 2> /dev/null #delete oraysl status file +} diff --git a/pgyvpn/files/usr/share/pgyvpn/p2pinit.sh b/pgyvpn/files/usr/share/pgyvpn/p2pinit.sh new file mode 100755 index 00000000..01a170b2 --- /dev/null +++ b/pgyvpn/files/usr/share/pgyvpn/p2pinit.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +#删除oray_vpn_p2p表 +iptables -w -t filter -F oray_vpn_p2p +while true; +do + iptables -w -t filter -D INPUT -j oray_vpn_p2p 2>/dev/null + [ $? -ne 0 ] && break +done +iptables -w -t filter -X oray_vpn_p2p + +#建立oray_vpn_p2p表 +iptables -w -t filter -N oray_vpn_p2p +iptables -w -t filter -I oray_vpn_p2p -p udp --dport $2 -j ACCEPT +iptables -w -t filter -I oray_vpn_p2p -p udp --dport 1900 -j ACCEPT +iptables -w -t filter -I INPUT 1 -j oray_vpn_p2p diff --git a/pgyvpn/files/usr/share/pgyvpn/vncinit.sh b/pgyvpn/files/usr/share/pgyvpn/vncinit.sh new file mode 100755 index 00000000..e98aabed --- /dev/null +++ b/pgyvpn/files/usr/share/pgyvpn/vncinit.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +#删除oray_vpn_vnc表 +iptables -w -t filter -F oray_vpn_vnc +while true; +do + iptables -w -t filter -D INPUT -j oray_vpn_vnc 2>/dev/null + [ $? -ne 0 ] && break +done + +while true; +do + iptables -w -t filter -D FORWARD -j oray_vpn_vnc 2>/dev/null + [ $? -ne 0 ] && break +done + +while true; +do + iptables -w -t filter -D OUTPUT -j oray_vpn_vnc 2>/dev/null + [ $? -ne 0 ] && break +done +iptables -w -t filter -X oray_vpn_vnc + +#建立oray_vpn_vnc表 +iptables -w -t filter -N oray_vpn_vnc +iptables -w -t filter -I oray_vpn_vnc -i oray_vnc -o br-lan -j ACCEPT +iptables -w -t filter -I oray_vpn_vnc -o oray_vnc -i br-lan -j ACCEPT +iptables -w -t filter -I INPUT 1 -j oray_vpn_vnc +iptables -w -t filter -I OUTPUT 1 -j oray_vpn_vnc +iptables -w -t filter -I FORWARD 1 -j oray_vpn_vnc +iptables -w -t filter -I oray_vpn_vnc -i oray_vnc -j ACCEPT diff --git a/pgyvpn/files/usr/share/pgyvpn/vpnprogress.sh b/pgyvpn/files/usr/share/pgyvpn/vpnprogress.sh new file mode 100755 index 00000000..7edbceaa --- /dev/null +++ b/pgyvpn/files/usr/share/pgyvpn/vpnprogress.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +progress="$1" + +#connect status +echo $progress >/tmp/orayboxvpn_connect_status + +logger -t vpnprogress $progress + +#99: 表示 链接中 +# 1: 表示 已组网 +# 0: 表示 未组网 + +# æ˜¾ç¤ºç™»å½•é¡µé¢ +#4 -1: 表示 è´¦å·é”™è¯¯ +#-2: 表示 å¸å·å¯†ç ä¸ºç©º +#6 -3: 表示 æˆå‘˜æ•°ä¸è¶³ +#5 -4: 表示 登录失败 +#2 -5: 表示 æœåŠ¡è¿‡æœŸ +#1026 -8: 表示 ä¿®æ”¹å¯†ç  +#7 -9: 表示 æœåŠ¡è¢«ç¦ +#401 -10: 表示 授æƒè¢«ç¦ +#-1 -11: 表示 登录故障 这个è¦åŒºåˆ«ä¸€ä¸‹ç™»å½•失败(登录æˆåŠŸåŽæ–­å¼€) + + +# 显示登录æˆåŠŸ æœªç»„ç½‘é¡µé¢ +#-1 -6: 表示 移除网络 +#6 -7: 表示 状æ€å…³é—­ + +# err_code= +# vpn_status= +# login_status= + +if [ "$progress" == "connected" ] ;then ### 已组网 + vpn_status=1 +elif [ "$progress" == "tryconnect" ] ;then + logger -t vpnprogress $progress +elif [ "$progress" == "sn" ] ;then + vpn_status=99 + uci set pgyvpn.base.login_status=1 + uci set pgyvpn.base.vpnid=$2 + uci set pgyvpn.base.vpnpwd=$3 +elif [ "$progress" == "login_err" ] ;then + vpn_status=0 + err_code=$2 + if [ "$err_code" == "4" ] ;then + err_code=-1 + elif [ "$err_code" == "6" ] ;then + err_code=-3 + elif [ "$err_code" == "5" ] ;then + err_code=-4 + elif [ "$err_code" == "2" ] ;then + err_code=-5 + elif [ "$err_code" == "7" ] ;then + err_code=-9 + elif [ "$err_code" == "401" ] ;then + err_code=-10 + elif [ "$err_code" == "403" ] ;then + err_code=-10 + elif [ "$err_code" == "-1" ] ;then + err_code=-11 + fi + ### login failed can't disabled vpn service + + if [ "$err_code" == "-11" ] ;then + status=`uci get pgyvpn.base.login_status` + logger -t errcode $status + if [ "$status" != "1" ] ;then + uci set pgyvpn.base.enable_status=0 ### 下回ä¸å¯ç”¨ + /etc/init.d/pgyvpn stop > /dev/null + fi + elif [ "$err_code" != "-4" ] ;then + uci set pgyvpn.base.enable_status=0 ### 下回ä¸å¯ç”¨ + /etc/init.d/pgyvpn stop > /dev/null + fi + + + uci set pgyvpn.base.err_code=$err_code + +elif [ "$progress" == "not_in_group" ] ;then ### 未组网 + ## not_in_group is not a err + vpn_status=0 + err_code=0 + uci set pgyvpn.base.login_status=1 + +elif [ "$progress" == "disconnected" ] ;then + err_code=$2 + vpn_status=0 + if [ -n "$err_code" ] ;then + vpn_status=0 + if [ "$err_code" == "-1" ] ;then + err_code=-6 + elif [ "$err_code" == "6" ] ;then + err_code=-7 + elif [ "$err_code" == "1026" ] ;then + err_code=-8 + fi + uci set pgyvpn.base.err_code=$err_code + fi +fi + +if [ -n "$vpn_status" ] ;then + uci set pgyvpn.base.vpn_status=$vpn_status +fi + +if [ "$err_code" == "-5" ] || [ "$err_code" == "-9" ] || [ "$err_code" == "-8" ] ;then + uci set pgyvpn.base.login_status=0 + uci set pgyvpn.base.enable_status=0 +fi + +if [ "$vpn_status" == "1" ] || [ "$vpn_status" == "0" -a "$err_code" == "0" ] ;then + uci set pgyvpn.base.login_status=1 + uci set pgyvpn.base.enable_status=1 +fi + +uci commit diff --git a/phtunnel/Makefile b/phtunnel/Makefile new file mode 100644 index 00000000..f8bd4d27 --- /dev/null +++ b/phtunnel/Makefile @@ -0,0 +1,106 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/target.mk + +ifeq ($(ARCH),arm) + ifneq ($(findstring $(CPU_SUBTYPE), neon neon-vfpv4 vfpv3),) + PKG_ARCH_PHT:=arm_$(CPU_TYPE)_$(CPU_SUBTYPE)-$(LIBC)-unknown + else ifneq ($(findstring $(CPU_TYPE), cortex-a9),) + PKG_ARCH_PHT:=arm_cortex-a9-$(LIBC)-unknown + else + PKG_ARCH_PHT:=arm_cortex-a7-$(LIBC)-unknown + endif +endif +ifeq ($(ARCH),aarch64) + ifneq ($(findstring $(CPU_TYPE), cortex-a53 cortex-a72),) + PKG_ARCH_PHT:=aarch64_$(CPU_TYPE)-$(LIBC)-unknown + else + PKG_ARCH_PHT:=aarch64_generic-$(LIBC)-unknown + endif +endif +ifeq ($(ARCH),mips) + PKG_ARCH_PHT:=mips_24kc-$(LIBC)-unknown +endif +ifeq ($(ARCH),mipsel) + ifneq ($(findstring $(CPU_TYPE), 24kec 74kc 1004kc),) + PKG_ARCH_PHT:=$(ARCH)_$(CPU_TYPE)-$(LIBC)-unknown + else + PKG_ARCH_PHT:=mipsel_24kc-$(LIBC)-unknown + endif +endif +ifeq ($(BOARD),x86) + ifeq ($(ARCH),x86_64) + PKG_ARCH_PHT:=x86_64-$(LIBC)-unknown + else ifeq ($(CPU_TYPE),pentium4) + PKG_ARCH_PHT:=i386_pentium4-$(LIBC)-unknown + else + PKG_ARCH_PHT:=i386_pentium-mmx-$(LIBC)-unknown + endif +endif + +PKG_NAME:=phtunnel +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=phtunnel +PKG_SOURCE_URL:=https://mirrors.oray.com/orayos/packages/$(PKG_NAME)/$(PKG_ARCH_PHT)/$(PKG_VERSION)/bin +PKG_HASH:=skip + +PKG_FLAGS:=nonshared +PKG_MAINTAINER:=Oray + +include $(INCLUDE_DIR)/package.mk + +define Package/phtunnel + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + DEPENDS:=@(arm||aarch64||mips||mipsel||i386||x86_64) \ + +libc +libpthread +librt + TITLE:=HSK Intranet penetration + URL:=https://hsk.oray.com/ +endef + +define Package/phtunnel/description + PHTunnel is the core component of HSK intranet penetration, which can easily implement high-performance + reverse proxy applications, supports TCP, HTTP, HTTPS protocols, end-to-end TLS encrypted communication, + black and white list anti-black verification, etc. Through PHTunnel, external network devices can easily + penetrate various complex routes and firewalls to access devices on the internal network. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + mv $(DL_DIR)/$(PKG_SOURCE) $(PKG_BUILD_DIR) + chmod +x $(PKG_BUILD_DIR)/$(PKG_SOURCE) +endef + +define Build/Compile + true +endef + +define Package/phtunnel/conffiles +/etc/phtunnel.json +endef + +define Package/phtunnel/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DIR) $(1)/usr/sbin + + $(CP) $(PKG_BUILD_DIR)/phtunnel $(1)/usr/sbin + $(INSTALL_BIN) ./files/etc/init.d/* $(1)/etc/init.d + $(INSTALL_CONF) ./files/etc/config/* $(1)/etc/config + $(INSTALL_BIN) ./files/etc/hotplug.d/iface/* $(1)/etc/hotplug.d/iface +endef + +define Package/phtunnel/preinst + #!/bin/sh + [ -z "$${IPKG_INSTROOT}" ] && { + pidof phtunnel > /dev/null && \ + test -f $${PKG_ROOT}etc/init.d/phtunnel && \ + /etc/init.d/phtunnel stop; true + } + exit 0 +endef + +$(eval $(call BuildPackage,phtunnel)) diff --git a/phtunnel/files/etc/config/phtunnel b/phtunnel/files/etc/config/phtunnel new file mode 100644 index 00000000..27ed450f --- /dev/null +++ b/phtunnel/files/etc/config/phtunnel @@ -0,0 +1,6 @@ +config base 'base' + option enabled '0' + +config log 'log' + option path '/var/log/phtunnel.log' + diff --git a/phtunnel/files/etc/hotplug.d/iface/30-oray-phtunnel b/phtunnel/files/etc/hotplug.d/iface/30-oray-phtunnel new file mode 100755 index 00000000..02a31474 --- /dev/null +++ b/phtunnel/files/etc/hotplug.d/iface/30-oray-phtunnel @@ -0,0 +1,6 @@ +#!/bin/sh + +[ "$INTERFACE" == "wan" -a "$ACTION" == "ifup" ] && { + logger -t oray 'wan interface up and phtunnel restart' + /etc/init.d/phtunnel restart +} diff --git a/phtunnel/files/etc/init.d/phtunnel b/phtunnel/files/etc/init.d/phtunnel new file mode 100755 index 00000000..789fe40a --- /dev/null +++ b/phtunnel/files/etc/init.d/phtunnel @@ -0,0 +1,103 @@ +#!/bin/sh /etc/rc.common + +. /lib/functions.sh + +START=65 +STOP=65 + +USE_PROCD=1 + +#é€€å‡ºåŽæ¸…ç† +exit_clean() +{ + [ -f "$1" ] && rm $1 + [ -f "$2" ] && rm $2 + [ -f "$3" ] && rm $3 +} + +start_service() +{ + local enabled + local config_file + local log_path + local app_id + local app_key + local server_addr + local pid_file + local device_info + local cmd + local log_dir_path + + config_load phtunnel + config_get enabled base enabled '0' + [ "$enabled" == "0" ] && { + echo 'phtunnel is not enabled' + exit 1 + } + + config_get config_file base config_file '/etc/phtunnel.json' #é…置文件路径 + config_get app_id base app_id '' #appid + config_get app_key base app_key '' #appkey + config_get server_addr base server 'https://hsk-embed.oray.com' #æœåŠ¡å™¨åœ°å€ + config_get pid_file base pid_file '/tmp/phtunnel.pid' #pid文件ä½ç½® + config_get log_path log path '/var/log/oraybox/phtunnel.log' #日志ä½ç½® + + echo 'now start phtunnel' + + log_dir_path="${log_path%/*}" + [ ! -d "$log_dir_path" ] && mkdir -p $log_dir_path + + cmd="phtunnel -R 100 -c $config_file -l $log_path --rpc -p $pid_file" + [ -n "$app_id" -a -n "$app_key" ] && cmd="$cmd --appid "$app_id" --appkey $app_key" + [ -n "$server_addr" ] && cmd="$cmd -s $server_addr" + [ -n "$dev_info" ] && cmd="$cmd --deviceinfo 'mem:32; usb:on; cpu:mipsel'" + #echo $cmd + + procd_open_instance + procd_set_param command $cmd + procd_set_param respawn + procd_close_instance +} + +stop_service() +{ + echo 'now stop phtunnel' + + local enabled + local config_file + local pid_file + local log_path + config_load phtunnel + config_get enabled base enabled '0' + config_get config_file base config_file '/etc/phtunnel.json' #é…置文件路径 + config_get pid_file base pid_file '/tmp/phtunnel.pid' + config_get log_path log path '/var/log/oraybox/phtunnel.log' + + #获å–程åºçš„pid + local pid=$(cat "$pid_file" 2> /dev/null | grep 'pid=' | cut -d'=' -f2 2> /dev/null) + [ -z "$pid" ] && { + echo 'phtunnel pid is not found' + exit_clean $pid_file $log_path + return 0 + } + + #如果enabled为0(ç¦ç”¨),则删除é…置文件 + [ "$enabled" = "0" -a -f "$config_file" ] && rm $config_file + + #killç¨‹åº + kill "$pid" 2> /dev/null + for i in $(seq 1 4) + do + [ -d "/proc/$pid" ] || { + echo 'phtunnel processor is stopped' + exit_clean $pid_file $log_path + return 0 + } + echo "phtunnel processor is still alive(pid is $pid), wait 1 second" + sleep 1 + done + + echo "phtunnel processor is still alive(pid is $pid), kill it" + kill -9 $pid 2> /dev/null + exit_clean $pid_file $log_path +} diff --git a/polipo/Makefile b/polipo/Makefile new file mode 100644 index 00000000..52ccf6e2 --- /dev/null +++ b/polipo/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (C) 2007-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=polipo +PKG_VERSION:=1.1.1 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://www.pps.jussieu.fr/~jch/software/files/$(PKG_NAME)/ +PKG_HASH:=a259750793ab79c491d05fcee5a917faf7d9030fb5d15e05b3704e9c9e4ee015 + +PKG_CPE_ID:=cpe:/a:pps.jussieu:polipo + +include $(INCLUDE_DIR)/package.mk + +define Package/polipo + SUBMENU:=Web Servers/Proxies + SECTION:=net + CATEGORY:=Network + TITLE:=A caching web proxy + URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/polipo/ + MAINTAINER:=Gabriel Kerneis +endef + +define Package/polipo/description + Polipo is a small and fast caching web proxy (a web cache, an HTTP proxy, + a proxy server). While Polipo was designed to be used by one person or a + small group of people, there is nothing that prevents it from being used + by a larger group. +endef + +TARGET_CFLAGS += -DHAVE_IPv6 + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + polipo +endef + +define Package/polipo/conffiles +/etc/config/polipo +/etc/polipo/config +endef + +define Package/polipo/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/polipo $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/polipo + $(INSTALL_CONF) $(PKG_BUILD_DIR)/config.sample $(1)/etc/polipo/config + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/polipo.config $(1)/etc/config/polipo + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/polipo.init $(1)/etc/init.d/polipo +endef + +$(eval $(call BuildPackage,polipo)) diff --git a/polipo/files/polipo.config b/polipo/files/polipo.config new file mode 100644 index 00000000..47f4a575 --- /dev/null +++ b/polipo/files/polipo.config @@ -0,0 +1,42 @@ +# polipo daemon configuration +config 'polipo' 'daemon' + # daemonise polipo (fork in background) + option 'daemonise' '1' + # where polipo will store its process pid + option 'pidFile' '/var/run/polipo.pid' + +config 'polipo' 'general' + option 'enabled' '1' + # address on which polipo will listen, 0.0.0.0 means all addresses + option 'proxyAddress' '0.0.0.0' + # port on which polipo will listen, default is 8123 + #option 'proxyPort' '8123' + # list of allowed clients to connect + list 'allowedClients' '192.168.1.0/24' + #list 'allowedClients' '127.0.0.1' + #list 'allowedClients' '192.168.2.1' + # how much RAM memory should Polipo use (in bytes). + option 'chunkHighMark' '1048576' + # enable disk cache index and serverlist of integrated polipo web interface + #option 'disableIndexing' '0' + #option 'disableServersList' '0' + # disable loging to syslog + option 'logSyslog' '0' + # set log file location (disabled when not set) + #option 'logFile' '/mnt/usbdrive/polipo/log' + +config 'polipo' 'cache' + # disk cache location, you should always use external storage device + # (disabled when not set) + #option 'diskCacheRoot' '/mnt/usbdrive-p2/polipo/cache' + # disk cache cleanup settings + #option 'diskCacheUnlinkTime' '20d' + #option 'diskCacheTruncateTime' '5d' + #option 'diskCacheTruncateSize' '3145728' + # set to 1 if proxy is used by multiple users + #option 'cacheIsShared' '1' + +config 'polipo' 'pmm' + # poor man's multiplexing semgnet size to fetch + #option 'pmmSize' '8192' + diff --git a/polipo/files/polipo.init b/polipo/files/polipo.init new file mode 100644 index 00000000..3cd73d49 --- /dev/null +++ b/polipo/files/polipo.init @@ -0,0 +1,150 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008-2011 OpenWrt.org + +START=99 + +CFGFILE=/var/etc/polipo.conf + +start() { + config_load 'polipo' + + config_get_bool enabled "general" 'enabled' '0' + [ $enabled -gt 0 ] || return 1 + + mkdir -m 0755 -p /var/etc/ + echo '### AUTOGENERATED CONFIGURATION' > $CFGFILE + echo '### DO NOT EDIT' >> $CFGFILE + echo '### SEE /etc/config/polipo INSTEAD' >> $CFGFILE + echo '' >> $CFGFILE + + config_foreach polipo_config 'polipo' + + # handle values that are disabled when not defined or empty + echo "### VALUES THAT ARE DISABLED WHEN EMPTY" >> $CFGFILE + polipo_atom "cache" "diskCacheRoot" '"' "1" >> $CFGFILE + polipo_atom "general" "logFile" '"' "1" >> $CFGFILE + polipo_atom "general" "localDocumentRoot" '"' "1" >> $CFGFILE + + service_start /usr/sbin/polipo -c "$CFGFILE" +} + +stop() { + service_stop /usr/sbin/polipo -c "$CFGFILE" +} + +polipo_config() { + echo "### SECTION $1" >> $CFGFILE + + string_options='authCredentials authRealm dnsNameServer forbiddenFile + forbiddenUrl logFacility pidFile parentAuthCredentials parentProxy + proxyAddress proxyName redirector socksParentProxy socksProxyType + socksUserName uncachableFile' + + number_options='bigBufferSize chunkCriticalMark chunkHighMark chunkLowMark + diskCacheDirectoryPermissions diskCacheFilePermissions + diskCacheTruncateSize diskCacheWriteoutOnClose forbiddenRedirectCode + logFilePermissions logLevel maxDiskCacheEntrySize maxDiskEntries + maxObjectsWhenIdle maxPipelineTrain maxSideBuffering maxWriteoutWhenIdle + objectHashTableSize objectHighMark pmmFirstSize pmmSize proxyPort + publicObjectLowMark redirectorRedirectCode replyUnpipelineSize + serverMaxSlots serverSlots serverSlots1 maxAgeFraction' + + time_options='clientTimeout diskCacheTruncateTime diskCacheUnlinkTime + dnsGethostbynameTtl dnsMaxTimeout dnsNegativeTtl idleTime maxAge + maxConnectionAge maxConnectionRequests maxExpiresAge maxNoModifiedAge + replyUnpipelineTime serverExpireTime serverIdleTimeout serverTimeout + smallRequestTime' + + multistate_options='censorReferer dnsQueryIPv6 dnsUseGethostbyname + dontTrustVaryETag expectContinue pipelineAdditionalRequests + useTemporarySourceAddress relaxTransparency' + + boolean_options='cacheIsShared daemonise disableConfiguration disableIndexing + disableLocalInterface disableProxy disableServersList disableVia + dontCacheCookies dontCacheRedirects logSyslog mindlesslyCacheVary + preciseExpiry proxyOffline scrubLogs laxHttpParser' + + string_list_options='allowedClients censoredHeaders' + + number_list_options='allowedPorts tunnelAllowedPorts' + + for option in $string_options; do + polipo_atom "$1" "$option" '"' >> $CFGFILE + done + + for option in $number_options; do + polipo_atom "$1" "$option" >> $CFGFILE + done + + for option in $time_options; do + polipo_atom "$1" "$option" >> $CFGFILE + done + + for option in $multistate_options; do + polipo_atom "$1" "$option" >> $CFGFILE + done + + for option in $boolean_options; do + polipo_boolean "$1" "$option" >> $CFGFILE + done + + for option in $string_list_options; do + polipo_list "$1" "$option" '"' >> $CFGFILE + done + + for option in $number_list_options; do + polipo_list "$1" "$option" >> $CFGFILE + done +} + +polipo_atom() { + local SECTION=$1 + local OPTION=$2 + local QUOTE=$3 + local EMPTY_DISABLED=${4:-0} + + config_get _value "$SECTION" "$OPTION" + [ -n "$_value" -o "$EMPTY_DISABLED" -eq "1" ] && { + echo "$OPTION = ${QUOTE}${_value}${QUOTE}" + } +} + +polipo_boolean() { + local SECTION=$1 + local OPTION=$2 + + config_get_bool _value "$SECTION" "$OPTION" + [ -n "$_value" ] && { + [ "$_value" -eq "1" ] && _value="true" || _value="false" + echo "$OPTION = $_value" + } +} + +polipo_list() { + local SECTION=$1 + local OPTION=$2 + local QUOTE=$3 + + config_get _value "$SECTION" "$OPTION" + + [ "$SECTION" = general ] && [ "$OPTION" = allowedClients ] && { + case "$_value" in + *127.0.0.1*) : ;; + *) _value="127.0.0.1 $_value" ;; + esac + } + + [ -n "$_value" ] && { + echo -n "$OPTION = " + + local FIRST=1 + for entry in $_value; do + [ "$FIRST" -ne "1" ] && echo -n ", " || FIRST=0 + + echo -n "${QUOTE}${entry}${QUOTE}" + done + + echo '' + } +} + diff --git a/qBittorrent-static/Makefile b/qBittorrent-static/Makefile new file mode 100644 index 00000000..9a196381 --- /dev/null +++ b/qBittorrent-static/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2017-2020 +# +# This is free software, licensed under the GNU General Public License v2. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=qBittorrent-static +PKG_VERSION:=4.5.2_v2.0.8 +PKG_RELEASE=1 + +STRIP:=true + +ifeq ($(ARCH),x86_64) + PKG_ARCH:=x86_64 +endif + +ifeq ($(ARCH),arm64) + PKG_ARCH:=aarch64 +endif + +ifeq ($(ARCH),aarch64) + PKG_ARCH:=aarch64 +endif + +ifeq ($(ARCH),arm) + PKG_ARCH:=armv7 +endif + +include $(INCLUDE_DIR)/package.mk + +define Package/qBittorrent-static + SECTION:=net + CATEGORY:=Network + DEPENDS:=@(arm||aarch64||x86_64) + SUBMENU:=BitTorrent + TITLE:=bittorrent client programmed in C++ / Qt + URL:=https://www.qbittorrent.org/ +endef + +define Package/qBittorrent-static/description + qBittorrent is a bittorrent client programmed in C++ / Qt that uses + libtorrent (sometimes called libtorrent-rasterbar) by Arvid Norberg. + It aims to be a good alternative to all other bittorrent clients out + there. qBittorrent is fast, stable and provides unicode support as + well as many features. +endef + +define Download/qbittorrent + URL:=https://github.com/userdocs/qbittorrent-nox-static/releases/download/release-$(PKG_VERSION) + URL_FILE:=$(PKG_ARCH)-qbittorrent-nox + FILE:=qbittorrent-nox + HASH:=skip +endef + +define Build/Compile +endef + +define Package/qBittorrent-static/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(DL_DIR)/qbittorrent-nox $(1)/usr/bin +endef + +$(eval $(call Download,qbittorrent)) +$(eval $(call BuildPackage,qBittorrent-static)) diff --git a/qbittorrent/Makefile b/qbittorrent/Makefile new file mode 100644 index 00000000..14f47a02 --- /dev/null +++ b/qbittorrent/Makefile @@ -0,0 +1,84 @@ +# +# Copyright (C) 2017-2020 +# +# This is free software, licensed under the GNU General Public License v2. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=qbittorrent +PKG_VERSION:=5.2.1 +PKG_RELEASE=1 + +PKG_SOURCE:=qBittorrent-release-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/qbittorrent/qBittorrent/tar.gz/release-$(PKG_VERSION)? +PKG_HASH:=6288bfeeca1931ff1e1ca04d0e5f872e0d0b9d5df583ed41289cb9275ccac208 + +PKG_BUILD_DIR:=$(BUILD_DIR)/qBittorrent-release-$(PKG_VERSION) + +PKG_LICENSE:=GPL-2.0+ +PKG_LICENSE_FILES:=COPYING +PKG_CPE_ID:=cpe:/a:qbittorrent:qbittorrent + +PKG_BUILD_DEPENDS:=qt6tools/host + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/qbittorrent + SECTION:=net + CATEGORY:=Network + SUBMENU:=BitTorrent + DEPENDS:=+USE_GLIBC:librt +USE_GLIBC:libpthread +libgcc +libstdcpp \ + +rblibtorrent \ + +libQt6Core \ + +libQt6Network \ + +libQt6Sql \ + +libQt6Xml \ + +qt6-plugin-libqopensslbackend \ + +qt6-plugin-libqsqlite + TITLE:=bittorrent client programmed in C++ / Qt + URL:=https://www.qbittorrent.org/ + PROVIDES:=qBittorrent +endef + +define Package/qbittorrent/description + qBittorrent is a bittorrent client programmed in C++ / Qt that uses + libtorrent (sometimes called libtorrent-rasterbar) by Arvid Norberg. + It aims to be a good alternative to all other bittorrent clients out + there. qBittorrent is fast, stable and provides unicode support as + well as many features. +endef + +CMAKE_OPTIONS += \ + -DCMAKE_BUILD_TYPE=Release \ + -DQT6=ON \ + -DSTACKTRACE=OFF \ + -DWEBUI=ON \ + -DGUI=OFF \ + -DVERBOSE_CONFIGURE=ON \ + -DQT_ADDITIONAL_PACKAGES_PREFIX_PATH=$(STAGING_DIR_HOSTPKG) \ + -DCMAKE_CXX_FLAGS="$(TARGET_CXXFLAGS) -Wno-pedantic" + +ifdef CONFIG_USE_GLIBC + TARGET_LDFLAGS += -ldl -lrt -lpthread +endif + +define Package/qbittorrent/conffiles +/etc/config/qbittorrent +endef + +define Package/qbittorrent/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qbittorrent-nox $(1)/usr/bin + + $(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d $(1)/usr/share/qbittorrent + $(INSTALL_BIN) ./files/qbittorrent.init $(1)/etc/init.d/qbittorrent + $(INSTALL_CONF) ./files/qbittorrent.config $(1)/etc/config/qbittorrent + $(INSTALL_CONF) ./files/qBittorrent.conf.example $(1)/usr/share/qbittorrent/qBittorrent.conf.example +endef + +$(eval $(call BuildPackage,qbittorrent)) diff --git a/qbittorrent/files/qBittorrent.conf.example b/qbittorrent/files/qBittorrent.conf.example new file mode 100644 index 00000000..33095521 --- /dev/null +++ b/qbittorrent/files/qBittorrent.conf.example @@ -0,0 +1,67 @@ +[AutoRun] +enabled=false +program= + +[BitTorrent] +Session\DefaultSavePath=/tmp +Session\QueueingSystemEnabled=false + +[Core] +AutoDeleteAddedTorrentFile=Never + +[LegalNotice] +Accepted=true + +[Meta] +MigrationVersion=3 + +[Network] +Proxy\OnlyForTorrents=false + +[Preferences] +Advanced\RecheckOnCompletion=false +Advanced\trackerPort=9000 +Connection\ResolvePeerCountries=true +DynDNS\DomainName=changeme.dyndns.org +DynDNS\Enabled=false +DynDNS\Password= +DynDNS\Service=DynDNS +DynDNS\Username= +General\Locale=zh_CN +MailNotification\email= +MailNotification\enabled=false +MailNotification\password= +MailNotification\req_auth=true +MailNotification\req_ssl=false +MailNotification\sender=qBittorrent_notification@example.com +MailNotification\smtp_server=smtp.changeme.com +MailNotification\username= +WebUI\Address=* +WebUI\AlternativeUIEnabled=false +WebUI\AuthSubnetWhitelist=10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 +WebUI\AuthSubnetWhitelistEnabled=true +WebUI\BanDuration=3600 +WebUI\CSRFProtection=false +WebUI\ClickjackingProtection=false +WebUI\CustomHTTPHeaders= +WebUI\CustomHTTPHeadersEnabled=false +WebUI\HTTPS\CertificatePath= +WebUI\HTTPS\Enabled=false +WebUI\HTTPS\KeyPath= +WebUI\HostHeaderValidation=true +WebUI\LocalHostAuth=true +WebUI\MaxAuthenticationFailCount=20 +WebUI\Password_PBKDF2="@ByteArray(jitR5BGNNzYwj+fDyesHIg==:PzUTXosIj4MeWbd/42TEWE26dazmXMwZuTOIjcjD681eFq/PIdyu/6YAmoGl16ekasJDDAvnhgllDIXB+cfFHQ==)" +WebUI\Port=8080 +WebUI\ReverseProxySupportEnabled=false +WebUI\RootFolder= +WebUI\SecureCookie=true +WebUI\ServerDomains=* +WebUI\SessionTimeout=3600 +WebUI\TrustedReverseProxiesList= +WebUI\UseUPnP=true +WebUI\Username=admin + +[RSS] +AutoDownloader\DownloadRepacks=true +AutoDownloader\SmartEpisodeFilter=s(\\d+)e(\\d+), (\\d+)x(\\d+), "(\\d{4}[.\\-]\\d{1,2}[.\\-]\\d{1,2})", "(\\d{1,2}[.\\-]\\d{1,2}[.\\-]\\d{4})" diff --git a/qbittorrent/files/qbittorrent.config b/qbittorrent/files/qbittorrent.config new file mode 100644 index 00000000..327156ce --- /dev/null +++ b/qbittorrent/files/qbittorrent.config @@ -0,0 +1,6 @@ + +config qbittorrent 'config' + option enabled '0' + option port '8080' + option profile_dir '/etc/qbittorrent' + diff --git a/qbittorrent/files/qbittorrent.init b/qbittorrent/files/qbittorrent.init new file mode 100644 index 00000000..0186c378 --- /dev/null +++ b/qbittorrent/files/qbittorrent.init @@ -0,0 +1,39 @@ +#!/bin/sh /etc/rc.common + +START=99 +USE_PROCD=1 +PROG=/usr/bin/qbittorrent-nox + +get_config() { + config_get_bool enabled $1 enabled 1 + config_get port $1 port 8080 + config_get profile_dir $1 profile_dir "/etc/qbittorrent" +} + +start_service() { + config_load qbittorrent + config_foreach get_config qbittorrent + [ $enabled != 1 ] && return 1 + if [ ! -f "$profile_dir/qBittorrent/config/qBittorrent.conf" ]; then + mkdir -p $profile_dir/qBittorrent/config/ + cp /usr/share/qbittorrent/qBittorrent.conf.example $profile_dir/qBittorrent/config/qBittorrent.conf + fi + + rm -rf $profile_dir/qBittorrent/config/lockfile + + procd_open_instance + procd_set_param command $PROG + procd_append_param command --webui-port=$port --profile=$profile_dir + procd_set_param respawn + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "qbittorrent" +} + +reload_service() { + stop + sleep 1 + start +} diff --git a/qfirehose/Makefile b/qfirehose/Makefile new file mode 100644 index 00000000..76e99c2e --- /dev/null +++ b/qfirehose/Makefile @@ -0,0 +1,55 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qfirehose +PKG_VERSION:=1.4.9 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/nippynetworks/qfirehose/tar.gz/$(PKG_VERSION)? +PKG_HASH:=b7c04f9356823c6ee0f4ca152e8fd2015f34b95490cea68461a060993befadef + +PKG_MAINTAINER:=Oskari Rauta +PKG_LICENSE:= +PKG_LICENSE_FILES:=NOTICE + +include $(INCLUDE_DIR)/package.mk + +define Package/qfirehose + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Quectel Firehose Recovery application + URL:=https://github.com/nippynetworks/qfirehose +endef + +define Package/qfirehose/description + Utility that is able to flash firmwares on Quectel's modems. + Usage: qfirehose -f FW_PATH + + Warning. + + - Use of software is completely on your own risk. + Flashing wrong firmware or failed flash can brick your modem permanently. + Avoid flashing, if device works without issues and updated firmware does not contain new necessary changes. + Do not flash, if you are not willing to take this risk or do not know what you are doing. + + - After succesful flashing, you should use terminal to issue factory reset for modem settings with AT&F command. + + - mPCIe users (mostly): If modem has completely disappeared after succesful flashing, reason might be that some firmware updates + set default mode to USB3 which is unsupported by some mPCIe slots, in this case, you should connect it to USB + port using mPCIe -> USB adapter, even most of cheap chinese modules can reveal device. After this you should issue + a command to use USB2, which may vary between models, but on most Quectel modems is: AT+QUSBCFG="SS",0 + Changing value on end of AT command 0 to 1, selects USB3 instead. Refer to documents of your modem. +endef + +define Build/Configure + $(RM) $(PKG_BUILD_DIR)/QFirehose +endef + +MAKE_ARGS += linux + +define Package/qfirehose/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/QFirehose $(1)/usr/bin/qfirehose +endef + +$(eval $(call BuildPackage,qfirehose)) diff --git a/qiyougamebooster/Makefile b/qiyougamebooster/Makefile new file mode 100644 index 00000000..2ac2df38 --- /dev/null +++ b/qiyougamebooster/Makefile @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-only +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=qiyougamebooster +PKG_VERSION:=1.2.0 +PKG_RELEASE:=1 + +PKG_LICENSE:=Proprietary +PKG_MAINTAINER:=qiyouacc, Internet1235 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=QiYou Game Booster + DEPENDS:=@(aarch64||arm||mips||mipsel||i386||x86_64) +curl +ip-full +kmod-tun + URL:=https://www.qiyou.cn +endef + +define Package/$(PKG_NAME)/description + Play console games online with less lag and more stability + — now supporting PS, Switch, Xbox, PC, and mobile. +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/qiyougamebooster +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(CURDIR)/files/qiyougamebooster.sh $(1)/usr/bin/qiyougamebooster.sh + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(CURDIR)/files/qiyougamebooster.init $(1)/etc/init.d/qiyougamebooster + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) $(CURDIR)/files/qiyougamebooster.config $(1)/etc/config/qiyougamebooster +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/qiyougamebooster/files/qiyougamebooster.config b/qiyougamebooster/files/qiyougamebooster.config new file mode 100644 index 00000000..ce45363f --- /dev/null +++ b/qiyougamebooster/files/qiyougamebooster.config @@ -0,0 +1,3 @@ + +config qiyougamebooster 'config' + option enabled '0' diff --git a/qiyougamebooster/files/qiyougamebooster.init b/qiyougamebooster/files/qiyougamebooster.init new file mode 100644 index 00000000..f703097a --- /dev/null +++ b/qiyougamebooster/files/qiyougamebooster.init @@ -0,0 +1,37 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2007 OpenWrt.org + +USE_PROCD=1 +STOP=99 +START=99 + +CONF="qiyougamebooster" +PROG="/usr/bin/qiyougamebooster.sh" + +start_service() { + config_load "$CONF" + + local enabled + config_get_bool enabled "config" "enabled" "0" + [ "$enabled" -eq "1" ] || return 1 + + procd_open_instance "$CONF" + + procd_set_param command "$PROG" + procd_append_param command start + + procd_close_instance +} + +stop_service() { + $PROG stop +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "$CONF" +} diff --git a/qiyougamebooster/files/qiyougamebooster.sh b/qiyougamebooster/files/qiyougamebooster.sh new file mode 100644 index 00000000..b7289e04 --- /dev/null +++ b/qiyougamebooster/files/qiyougamebooster.sh @@ -0,0 +1,142 @@ +#!/bin/sh + +ACTION=$1 + +url="https://static.qiyou.cn/upgrade/ljb/plugin/qyplug.sh" +sh_file="/tmp/qyplug.sh" +ret_file="/tmp/qyplug.ret" +get_file="/tmp/qyplug.get" +pid_file="/tmp/qyplug.pid" +#get_qyplug="wget -q -T 30 \"${url}\" -O \"${sh_file}\" --no-check-certificate" +get_qyplug="curl -s -k -L -m 30 \"${url}\" -o \"${sh_file}\"" + +stop(){ + pid=`cat ${get_file} 2> /dev/null` + echo "qy_acc stop: ${pid}" + [ "${pid}" = "" ] || kill -9 ${pid} + rm -rf ${get_file} + + sleep 1 + + if [ -e /tmp/qyplug.sh ]; then + sh /tmp/qyplug.sh stop + rm -rf /tmp/qyplug.sh + fi + + sleep 2 + rm -rf ${ret_file} + + if [ -e /tmp/qy ]; then + cd /tmp/qy && ./init.sh stop + rm -rf /tmp/qy + fi +} + +start(){ + pid=$$ + echo ${pid} > ${get_file} + echo "qy_acc start: ${pid}" + + while true + do + rm -rf ${sh_file} ${ret_file} + + sh -c "${get_qyplug}" + if [ -e ${sh_file} ]; then + export QY_NOT_INSTALL=1 + sh ${sh_file} & + fi + + sleep 3 + [ ! -e ${ret_file} ] || break + sleep 30 + done + + rm -rf ${get_file} +} + +switch(){ + act=$1 + + if [ ! -d /tmp/qy ]; then + echo "没安装" + return + fi + + if [ "${act}" = "on" ]; then + cd /tmp/qy && ./init.sh &> /dev/null + elif [ "${act}" = "off" ]; then + cd /tmp/qy && ./init.sh stop &> /dev/null + fi +} + +status(){ + status=`cat ${ret_file} 2> /dev/null` + get=`cat ${get_file} 2> /dev/null` + pid=`cat ${pid_file} 2> /dev/null` + acc=`pidof qy_acc 2> /dev/null` + + if [ "${status}" = "succeeded" ]; then + if [ ! -d /tmp/qy ]; then + printf "NOT ENABLED" + elif [ "${acc}" = "" ]; then + printf "CLOSED" + elif [ -d /sys/class/net/tun31 ] || [ -d /sys/class/net/tun32 ]; then + printf "BOOSTING" + else + printf "RUNNING" + fi + return + fi + if [ "${status}" = "notsupport" ]; then + printf "NOT SUPPORTED" + return + fi + if [ "${status}" = "getpkgerr" ]; then + printf "DOWNLOADING" + return + fi + if [ "${get}" != "" ] && [ -e "/proc/${get}" ]; then + printf "INSTALLING" + return + fi + if [ "${pid}" != "" ] && [ -e "/proc/${pid}" ]; then + printf "INSTALLING" + return + fi + if [ ! -d /tmp/qy ]; then + printf "NOT ENABLED" + return + fi + printf "NOT RUNNING" +} + +version(){ + ver=`sed -n 's;^VERSION=;;p' /tmp/qy/etc/PKG_INFO 2> /dev/null` + printf "${ver}" +} + +case $ACTION in +stop) + stop + ;; +start) + stop + start + ;; +status) + status + ;; +enable) + switch on + ;; +disable) + switch off + ;; +version) + version + ;; +*) + start + ;; +esac diff --git a/qt6base/Makefile b/qt6base/Makefile new file mode 100644 index 00000000..9137be1a --- /dev/null +++ b/qt6base/Makefile @@ -0,0 +1,206 @@ +# +# Copyright (C) 2020 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=qt6base +PKG_VERSION:=6.11.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=qtbase-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/qt/qtbase/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=e20852bd45cdef5da5175f3634e285e03e2be7ca437f3d2b7e1a2af7321bca7a + +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/qtbase-$(PKG_VERSION) +PKG_BUILD_DIR:=$(BUILD_DIR)/qtbase-$(PKG_VERSION) + +PKG_BUILD_DEPENDS:=qt6base/host +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 +CMAKE_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/cmake.mk + +STRIP:=$(TARGET_CROSS)strip $(call qstrip,$(CONFIG_STRIP_ARGS)) + +define Package/libQt6/Default + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Qt6 + TITLE:=Qt6 + URL:=http://qt-project.org + DEPENDS:=@!arc +libatomic +libstdcpp +liburing +zlib +endef + +define Package/libQt6 + $(call Package/libQt6/Default) + HIDDEN:=1 +endef + +define Package/libQt6/install +endef + +TARGET_CFLAGS+= -I$(STAGING_DIR)/usr/include/libdrm +ifdef CONFIG_USE_GLIBC + ifeq ($(ARCH),x86_64) + TARGET_LDFLAGS+= -Wl,--sysroot=$(TOOLCHAIN_DIR) + endif +endif + +CMAKE_SHARED_LDFLAGS := $(filter-out -Wl$(comma)-Bsymbolic-functions,$(CMAKE_SHARED_LDFLAGS)) + +CMAKE_HOST_OPTIONS+= \ + -DBUILD_SHARED_LIBS=OFF \ + -DFEATURE_optimize_full=ON \ + -DFEATURE_glib=OFF \ + -DFEATURE_zstd=OFF \ + -DFEATURE_concurrent=OFF \ + -DFEATURE_dbus=ON \ + -DFEATURE_gui=OFF \ + -DFEATURE_network=ON \ + -DFEATURE_openssl=OFF \ + -DFEATURE_sql=OFF \ + -DFEATURE_testlib=OFF \ + -DFEATURE_xml=ON + +CMAKE_OPTIONS+= \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_SYSROOT=$(STAGING_DIR) \ + -DQT_HOST_PATH=$(STAGING_DIR_HOSTPKG) \ + -DINSTALL_PLUGINSDIR=/usr/lib/qt6plugins \ + -DQT_QMAKE_TARGET_MKSPEC=devices/linux-generic-g++ \ + -DQT_QMAKE_DEVICE_OPTIONS=CROSS_COMPILE="$(TARGET_CROSS);COMPILER_FLAGS=$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS);LINKER_FLAGS=$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \ + -DQT_BUILD_EXAMPLES=OFF \ + -DQT_BUILD_TESTS=OFF \ + -DQT_BUILD_TOOLS_WHEN_CROSSCOMPILING=OFF \ + -DINPUT_opengl=no \ + -DFEATURE_optimize_full=ON \ + -DFEATURE_system_zlib=ON \ + -DFEATURE_zstd=OFF \ + -DFEATURE_backtrace=OFF \ + -DFEATURE_system_doubleconversion=OFF \ + -DFEATURE_glib=OFF \ + -DFEATURE_icu=OFF \ + -DFEATURE_mimetype_database=ON \ + -DFEATURE_system_pcre2=ON \ + -DFEATURE_concurrent=$(if $(CONFIG_PACKAGE_libQt6Concurrent),ON,OFF) \ + -DFEATURE_dbus=$(if $(CONFIG_PACKAGE_libQt6DBus),ON,OFF) \ + -DFEATURE_gui=$(if $(CONFIG_PACKAGE_libQt6Gui),ON,OFF) \ + -DFEATURE_fontconfig=OFF \ + -DFEATURE_system_freetype=ON \ + -DFEATURE_accessibility=OFF \ + -DFEATURE_harfbuzz=OFF \ + -DFEATURE_gif=OFF \ + -DFEATURE_ico=OFF \ + -DFEATURE_jpeg=OFF \ + -DFEATURE_png=OFF \ + -DFEATURE_texthtmlparser=OFF \ + -DFEATURE_cssparser=OFF \ + -DFEATURE_textodfwriter=OFF \ + -DFEATURE_textmarkdownreader=OFF \ + -DFEATURE_textmarkdownwriter=OFF \ + -DFEATURE_sessionmanager=OFF \ + -DFEATURE_evdev=OFF \ + -DFEATURE_vnc=OFF \ + -DFEATURE_linuxfb=OFF \ + -DFEATURE_network=$(if $(CONFIG_PACKAGE_libQt6Network),ON,OFF) \ + -DFEATURE_openssl=ON \ + -DFEATURE_openssl_runtime=ON \ + -DFEATURE_ocsp=OFF \ + -DFEATURE_printsupport=$(if $(CONFIG_PACKAGE_libQt6PrintSupport),ON,OFF) \ + -DFEATURE_sql=$(if $(CONFIG_PACKAGE_libQt6Sql),ON,OFF) \ + -DFEATURE_sqlmodel=OFF \ + -DFEATURE_sql_sqlite=ON \ + -DFEATURE_system_sqlite=OFF \ + -DFEATURE_sql_db2=OFF \ + -DFEATURE_sql_ibase=OFF \ + -DFEATURE_sql_mysql=OFF \ + -DFEATURE_sql_oci=OFF \ + -DFEATURE_sql_odbc=OFF \ + -DFEATURE_sql_psql=OFF \ + -DFEATURE_testlib=$(if $(CONFIG_PACKAGE_libQt6Test),ON,OFF) \ + -DFEATURE_itemmodeltester=OFF \ + -DFEATURE_widgets=$(if $(CONFIG_PACKAGE_libQt6Widgets),ON,OFF) \ + -DFEATURE_commandlinkbutton=OFF \ + -DFEATURE_xml=$(if $(CONFIG_PACKAGE_libQt6Xml),ON,OFF) \ + -DFEATURE_tuiotouch=$(if $(CONFIG_PACKAGE_qt6-plugin-libqtuiotouchplugin),ON,OFF) + +define Package/libQt6/Default/install + $(INSTALL_DIR) $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libQt6$(2).so* $(1)/usr/lib/ +endef + +# 1: short name +# 2: dependencies on other qt6 libraries (short name) +# 3: dependencies on other packages +define DefineQt6Package + QT6BASE_LIBS+=$(1) + PKG_CONFIG_DEPENDS+=CONFIG_PACKAGE_libQt6$(1) + + define Package/libQt6$(1) + $(call Package/libQt6/Default) + TITLE+=$(1) Library + DEPENDS+=$(foreach lib,$(2),+libQt6$(lib)) $(3) + endef + + define Package/libQt6$(1)/description + This package provides the Qt6 $(1) v$(PKG_VERSION) library. + endef + + define Package/libQt6$(1)/install + $(call Package/libQt6/Default/install,$$(1),$(1)) + endef +endef + +$(eval $(call DefineQt6Package,Concurrent,Core,)) +$(eval $(call DefineQt6Package,Core,,+libpcre2-16)) +$(eval $(call DefineQt6Package,DBus,Core,)) +$(eval $(call DefineQt6Package,Gui,DBus,+libdrm +libfreetype)) +$(eval $(call DefineQt6Package,Network,Core,+libopenssl +krb5-libs)) +$(eval $(call DefineQt6Package,PrintSupport,Widgets,)) +$(eval $(call DefineQt6Package,Sql,Core,)) +$(eval $(call DefineQt6Package,Test,Core,)) +$(eval $(call DefineQt6Package,Widgets,Gui,)) +$(eval $(call DefineQt6Package,Xml,Core,)) + +define Package/qt6-plugin/Default/install + $(INSTALL_DIR) $(1)/usr/lib/qt6plugins/$(2)/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/qt6plugins/$(2)/libq$(3).so $(1)/usr/lib/qt6plugins/$(2)/ +endef + +# 1: plugin diretory +# 2: plugin name (short name) +# 3: dependencies on other qt6 libraries (short name) +define DefineQt6PluginPackage + QT6_PLUGINS+=$(2) + + define Package/qt6-plugin-libq$(2) + $(call Package/libQt6/Default) + TITLE+=Plugin libq$(2) + DEPENDS+=$(foreach lib,$(3),+libQt6$(lib)) + endef + + define Package/qt6-plugin-libq$(2)/install + $(call Package/qt6-plugin/Default/install,$$(1),$(1),$(2)) + endef +endef + +$(eval $(call DefineQt6PluginPackage,generic,tuiotouchplugin,Gui Network)) +$(eval $(call DefineQt6PluginPackage,networkinformation,networkmanager,DBus Network)) +$(eval $(call DefineQt6PluginPackage,platforms,minimal,Gui)) +$(eval $(call DefineQt6PluginPackage,platforms,offscreen,Gui)) +$(eval $(call DefineQt6PluginPackage,platformthemes,xdgdesktopportal,Gui)) +$(eval $(call DefineQt6PluginPackage,sqldrivers,sqlite,Sql)) +$(eval $(call DefineQt6PluginPackage,tls,certonlybackend,Network)) +$(eval $(call DefineQt6PluginPackage,tls,opensslbackend,Network)) +PKG_CONFIG_DEPENDS+=CONFIG_PACKAGE_qt6-plugin-libqtuiotouchplugin + +$(foreach lib,$(QT6BASE_LIBS),$(eval $(call BuildPackage,libQt6$(lib)))) +$(foreach lib,$(QT6_PLUGINS),$(eval $(call BuildPackage,qt6-plugin-libq$(lib)))) +$(eval $(call BuildPackage,libQt6)) +$(eval $(call HostBuild)) diff --git a/qt6base/patches/010-marco.patch b/qt6base/patches/010-marco.patch new file mode 100644 index 00000000..a6c03ccb --- /dev/null +++ b/qt6base/patches/010-marco.patch @@ -0,0 +1,12 @@ +--- a/src/corelib/plugin/qelfparser_p.cpp ++++ b/src/corelib/plugin/qelfparser_p.cpp +@@ -387,7 +387,9 @@ Q_DECL_UNUSED Q_DECL_COLD_FUNCTION static QDebug &operator<<(QDebug &d, ElfHeade + case EM_ALPHA: d << ", Alpha"; break; + case EM_68K: d << ", MC68000"; break; + case EM_ARM: d << ", ARM"; break; ++#ifdef EM_AARCH64 + case EM_AARCH64: d << ", AArch64"; break; ++#endif + #ifdef EM_BLACKFIN + case EM_BLACKFIN: d << ", Blackfin"; break; + #endif diff --git a/qt6tools/Makefile b/qt6tools/Makefile new file mode 100644 index 00000000..2271996b --- /dev/null +++ b/qt6tools/Makefile @@ -0,0 +1,50 @@ +# +# Copyright (C) 2019 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=qt6tools +PKG_VERSION:=6.11.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=qttools-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/qt/qttools/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=3b4df61a3941f937c24afda66bdd7e1cfe877eb467e61ac897e97bca3ea7347e + +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/qttools-$(PKG_VERSION) + +HOST_BUILD_DEPENDS:=qt6base/host +HOST_BUILD_PARALLEL:=1 +PKG_HOST_ONLY:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/qt6tools + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Qt6 + TITLE:=Qt6 Tools + URL:=http://qt-project.org + BUILDONLY:=1 +endef + +CMAKE_HOST_OPTIONS+= \ + -DINPUT_assistant=no \ + -DINPUT_designer=no \ + -DINPUT_clang=no \ + -DINPUT_distancefieldgenerator=no \ + -DINPUT_kmap2qmap=no \ + -DINPUT_pixeltool=no \ + -DINPUT_qdbus=no \ + -DINPUT_qev=no \ + -DINPUT_qtattributionsscanner=no \ + -DINPUT_qtplugininfo=no \ + -DINPUT_qtdiag=no + +$(eval $(call BuildPackage,qt6tools)) +$(eval $(call HostBuild)) diff --git a/qt6tools/patches/010-no-clang.patch b/qt6tools/patches/010-no-clang.patch new file mode 100644 index 00000000..1190300e --- /dev/null +++ b/qt6tools/patches/010-no-clang.patch @@ -0,0 +1,11 @@ +--- a/configure.cmake ++++ b/configure.cmake +@@ -6,7 +6,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/src/qdoc/cmake/QDocConfiguration.cmake) + + #### Tests + +-qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang) ++#qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang) + qt_find_package_extend_sbom(TARGETS WrapLibClang::WrapLibClang + PACKAGE_VERSION "${QT_LIB_CLANG_VERSION}" + LICENSE_EXPRESSION "Apache-2.0 WITH LLVM-exception" diff --git a/rblibtorrent/Makefile b/rblibtorrent/Makefile new file mode 100644 index 00000000..fda0bcd0 --- /dev/null +++ b/rblibtorrent/Makefile @@ -0,0 +1,66 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=rblibtorrent +PKG_VERSION:=2.0.12 +PKG_RELEASE:=1 + +PKG_SOURCE:=libtorrent-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/arvidn/libtorrent/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=475b5a9f1c9f62b0b9af2e53b1d77a8b7f002aec9d6db5de681bcd951bc30401 +PKG_BUILD_DIR:=$(BUILD_DIR)/libtorrent-$(PKG_VERSION) + +PKG_LICENSE:=BSD +PKG_LICENSE_FILES:=COPYING + +PKG_BUILD_FLAGS:=no-mips16 +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk +include ./boost-version.mk + +define Package/rblibtorrent + SECTION:=libs + CATEGORY:=Libraries + TITLE:=C++ bittorrent library by Rasterbar Software + URL:=https://www.libtorrent.org + DEPENDS:= \ + +libatomic +libc +libgcc +libopenssl +libstdcpp +USE_GLIBC:libpthread \ + +boost +boost-program_options \ + $(if $(filter y,$(NEED_BOOST_SYSTEM)),,+boost-system) + ABI_VERSION:=2.0 +endef + +define Package/rblibtorrent/description + Rasterbar libtorrent is a C++ library that aims to be a good alternative to + all the other bittorrent implementations around. It is a library and not a + full featured client, although it comes with a working example client. +endef + +TARGET_CFLAGS += $(FPIC) -ffunction-sections -fdata-sections +TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed + +CMAKE_OPTIONS += \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -Ddeprecated-functions=OFF \ + -Dlogging=OFF \ + -Dpython-bindings=OFF \ + -Dpython-egg-info=OFF + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/libtorrent $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libtorrent-rasterbar.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libtorrent-rasterbar.pc $(1)/usr/lib/pkgconfig/ +endef + +define Package/rblibtorrent/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib +endef + +$(eval $(call BuildPackage,rblibtorrent)) diff --git a/rblibtorrent/boost-version.mk b/rblibtorrent/boost-version.mk new file mode 100644 index 00000000..72beca47 --- /dev/null +++ b/rblibtorrent/boost-version.mk @@ -0,0 +1,12 @@ +# boost-version.mk +BOOST_MAKEFILE := $(firstword $(shell find -L $(TOPDIR) -type f -path "*/boost/Makefile")) + +BOOST_PKG_VERSION := $(shell grep '^PKG_VERSION:=' $(BOOST_MAKEFILE) | head -n1 | cut -d= -f2) + +BOOST_VER_MAJOR := $(word 1,$(subst ., ,$(BOOST_PKG_VERSION))) +BOOST_VER_MINOR := $(word 2,$(subst ., ,$(BOOST_PKG_VERSION))) +BOOST_VER_PATCH := $(word 3,$(subst ., ,$(BOOST_PKG_VERSION))) + +BOOST_VERSION_CODE := $(shell echo $$(($(BOOST_VER_MAJOR)*100000 + $(BOOST_VER_MINOR)*100 + $(BOOST_VER_PATCH)))) + +NEED_BOOST_SYSTEM := $(if $(shell [ $(BOOST_VERSION_CODE) -ge 108900 ] && echo y),y,n) diff --git a/rblibtorrent/src/deps/try_signal/CMakeLists.txt b/rblibtorrent/src/deps/try_signal/CMakeLists.txt new file mode 100644 index 00000000..945cd6c8 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 2.8.12) +project(try_signal) + +add_library(try_signal signal_error_code try_signal) +target_include_directories(try_signal PUBLIC .) + diff --git a/rblibtorrent/src/deps/try_signal/Jamfile b/rblibtorrent/src/deps/try_signal/Jamfile new file mode 100644 index 00000000..ec001a89 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/Jamfile @@ -0,0 +1,18 @@ +lib try_signal + : # sources + signal_error_code.cpp try_signal.cpp + : # requirements + : # default build + static + : # usage requirements + . + ; + +exe test : test.cpp : try_signal static ; +explicit test ; + +exe example : example.cpp : try_signal static ; +explicit example ; + +install stage_test : test : . ; + diff --git a/rblibtorrent/src/deps/try_signal/LICENSE b/rblibtorrent/src/deps/try_signal/LICENSE new file mode 100644 index 00000000..15230266 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2016, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/rblibtorrent/src/deps/try_signal/README.rst b/rblibtorrent/src/deps/try_signal/README.rst new file mode 100644 index 00000000..22cbe184 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/README.rst @@ -0,0 +1,53 @@ +try_signal +========== + +.. image:: https://travis-ci.org/arvidn/try_signal.svg?branch=master + :target: https://travis-ci.org/arvidn/try_signal + +.. image:: https://ci.appveyor.com/api/projects/status/le8jjroaai8081f1?svg=true + :target: https://ci.appveyor.com/project/arvidn/try-signal/branch/master + +The ``try_signal`` library provide a way to turn signals into C++ exceptions. +This is especially useful when performing disk I/O via memory mapped files, +where I/O errors are reported as ``SIGBUS`` and ``SIGSEGV`` or as structured +exceptions on windows. + +The function ``try_signal`` takes a function object that will be executed once. +If the function causes a signal (or structured exception) to be raised, it will +throw a C++ exception. Note that RAII may not be relied upon within this function. +It may not rely on destructors being called. Stick to simple operations like +memcopy. + +Example:: + + #include + #include + #include + #include "try_signal.hpp" + #include + #include + #include + + int main() try + { + int fd = open("test_file", O_RDWR); + void* map = mmap(nullptr, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + std::vector buf(1024); + std::iota(buf.begin(), buf.end(), 0); + + // disk full or access after EOF are reported as exceptions + sig::try_signal([&]{ + std::memcpy(map, buf.data(), buf.size()); + }); + + munmap(map, 1024); + close(fd); + return 0; + } + catch (std::exception const& e) + { + fprintf(stderr, "exited with exception: %s\n", e.what()); + return 1; + } + diff --git a/rblibtorrent/src/deps/try_signal/appveyor.yml b/rblibtorrent/src/deps/try_signal/appveyor.yml new file mode 100644 index 00000000..a185535a --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/appveyor.yml @@ -0,0 +1,50 @@ +version: "{build}" +branches: + only: + - master +os: Visual Studio 2015 +clone_depth: 1 +environment: + matrix: + - variant: debug + compiler: msvc-14.0 + model: 64 + - variant: debug + compiler: msvc-14.0 + model: 32 + - variant: release + compiler: msvc-14.0 + model: 64 + - variant: debug + compiler: gcc + model: 32 + - variant: debug + compiler: gcc + model: 64 + - variant: release + compiler: gcc + model: 32 + +install: +- set ROOT_DIRECTORY=%CD% +- set BOOST_ROOT=c:\Libraries\boost_1_67_0 +- set BOOST_BUILD_PATH=%BOOST_ROOT%\tools\build +- echo %BOOST_ROOT% +- echo %BOOST_BUILD_PATH% +- set PATH=%PATH%;%BOOST_BUILD_PATH%\src\engine\bin.ntx86 +- ps: '"using msvc : 14.0 ;`nusing gcc : : : -std=c++11 ;" | Set-Content $env:HOMEDRIVE\$env:HOMEPATH\user-config.jam' +- type %HOMEDRIVE%%HOMEPATH%\user-config.jam +- set PATH=c:\msys64\mingw32\bin;%PATH% +- g++ --version +- python --version +- echo %ROOT_DIRECTORY% +- cd %BOOST_BUILD_PATH%\src\engine +- build.bat >nul +- cd %ROOT_DIRECTORY% + +build_script: +# examples +- b2.exe warnings=all warnings-as-errors=on -j2 %compiler% address-model=%model% variant=%variant% stage_test + +test_script: +- test diff --git a/rblibtorrent/src/deps/try_signal/example.cpp b/rblibtorrent/src/deps/try_signal/example.cpp new file mode 100644 index 00000000..703b8178 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/example.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include "try_signal.hpp" +#include +#include +#include + +int main() try +{ + int fd = open("test_file", O_RDWR); + void* map = mmap(nullptr, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + std::vector buf(1024); + std::iota(buf.begin(), buf.end(), 0); + + // disk full or access after EOF are reported as exceptions + sig::try_signal([&]{ + std::memcpy(map, buf.data(), buf.size()); + }); + + munmap(map, 1024); + close(fd); + return 0; +} +catch (std::exception const& e) +{ + fprintf(stderr, "exited with exception: %s\n", e.what()); + return 1; +} + diff --git a/rblibtorrent/src/deps/try_signal/project-root.jam b/rblibtorrent/src/deps/try_signal/project-root.jam new file mode 100644 index 00000000..e69de29b diff --git a/rblibtorrent/src/deps/try_signal/signal_error_code.cpp b/rblibtorrent/src/deps/try_signal/signal_error_code.cpp new file mode 100644 index 00000000..ae016cf8 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/signal_error_code.cpp @@ -0,0 +1,209 @@ +/* + +Copyright (c) 2016, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include + +#include "signal_error_code.hpp" + +namespace { + + struct signal_error_category : std::error_category + { + const char* name() const noexcept override + { return "signal"; } + std::string message(int ev) const noexcept override + { +#define SIGNAL_CASE(x) case sig::errors::error_code_enum:: x: return #x; + switch (ev) + { + SIGNAL_CASE(abort) + SIGNAL_CASE(alarm) + SIGNAL_CASE(arithmetic_exception) + SIGNAL_CASE(hangup) + SIGNAL_CASE(illegal) + SIGNAL_CASE(interrupt) + SIGNAL_CASE(kill) + SIGNAL_CASE(pipe) + SIGNAL_CASE(quit) + case sig::errors::error_code_enum::segmentation: return "segmentation fault"; + SIGNAL_CASE(terminate) + SIGNAL_CASE(user1) + SIGNAL_CASE(user2) + SIGNAL_CASE(child) + SIGNAL_CASE(cont) + SIGNAL_CASE(stop) + SIGNAL_CASE(terminal_stop) + SIGNAL_CASE(terminal_in) + SIGNAL_CASE(terminal_out) + SIGNAL_CASE(bus) +#ifdef SIGPOLL + SIGNAL_CASE(poll) +#endif + SIGNAL_CASE(profiler) + SIGNAL_CASE(system_call) + SIGNAL_CASE(trap) + SIGNAL_CASE(urgent_data) + SIGNAL_CASE(virtual_timer) + SIGNAL_CASE(cpu_limit) + SIGNAL_CASE(file_size_limit) + default: return "unknown"; + } +#undef SIGNAL_CASE + } + std::error_condition default_error_condition(int ev) const noexcept override + { return {ev, *this}; } + }; +} // anonymous namespace + +namespace sig { +namespace errors { + + std::error_code make_error_code(error_code_enum e) + { + return {e, sig_category()}; + } + + std::error_condition make_error_condition(error_code_enum e) + { + return {e, sig_category()}; + } + +} // namespace errors + +std::error_category& sig_category() +{ + static signal_error_category signal_category; + return signal_category; +} + +#ifdef _WIN32 + +namespace { + sig::errors::error_code_enum map_exception_code(int const ev) + { + switch (ev) + { + case seh_errors::error_code_enum::access_violation: + case seh_errors::error_code_enum::array_bounds_exceeded: + case seh_errors::error_code_enum::guard_page: + case seh_errors::error_code_enum::stack_overflow: + case seh_errors::error_code_enum::flt_stack_check: + case seh_errors::error_code_enum::in_page_error: + return sig::errors::segmentation; + case seh_errors::error_code_enum::breakpoint: + case seh_errors::error_code_enum::single_step: + return sig::errors::trap; + case seh_errors::error_code_enum::datatype_misalignment: + return sig::errors::bus; + case seh_errors::error_code_enum::flt_denormal_operand: + case seh_errors::error_code_enum::flt_divide_by_zero: + case seh_errors::error_code_enum::flt_inexact_result: + case seh_errors::error_code_enum::flt_invalid_operation: + case seh_errors::error_code_enum::flt_overflow: + case seh_errors::error_code_enum::flt_underflow: + case seh_errors::error_code_enum::int_divide_by_zero: + case seh_errors::error_code_enum::int_overflow: + return sig::errors::arithmetic_exception; + case seh_errors::error_code_enum::illegal_instruction: + case seh_errors::error_code_enum::invalid_disposition: + case seh_errors::error_code_enum::priv_instruction: + case seh_errors::error_code_enum::noncontinuable_exception: + case seh_errors::error_code_enum::status_unwind_consolidate: + return sig::errors::illegal; + case seh_errors::error_code_enum::invalid_handle: + return sig::errors::pipe; + default: + return sig::errors::illegal; + } + } + + struct seh_error_category : std::error_category + { + const char* name() const noexcept override + { return "SEH"; } + std::string message(int ev) const noexcept override + { +#define SIGNAL_CASE(x) case sig::seh_errors::error_code_enum:: x: return #x; + switch (ev) + { + SIGNAL_CASE(access_violation) + SIGNAL_CASE(array_bounds_exceeded) + SIGNAL_CASE(guard_page) + SIGNAL_CASE(stack_overflow) + SIGNAL_CASE(flt_stack_check) + SIGNAL_CASE(in_page_error) + SIGNAL_CASE(breakpoint) + SIGNAL_CASE(single_step) + SIGNAL_CASE(datatype_misalignment) + SIGNAL_CASE(flt_denormal_operand) + SIGNAL_CASE(flt_divide_by_zero) + SIGNAL_CASE(flt_inexact_result) + SIGNAL_CASE(flt_invalid_operation) + SIGNAL_CASE(flt_overflow) + SIGNAL_CASE(flt_underflow) + SIGNAL_CASE(int_divide_by_zero) + SIGNAL_CASE(int_overflow) + SIGNAL_CASE(illegal_instruction) + SIGNAL_CASE(invalid_disposition) + SIGNAL_CASE(priv_instruction) + SIGNAL_CASE(noncontinuable_exception) + SIGNAL_CASE(status_unwind_consolidate) + SIGNAL_CASE(invalid_handle) + default: return "unknown"; + } +#undef SIGNAL_CASE + } + std::error_condition default_error_condition(int ev) const noexcept override + { return std::error_condition(map_exception_code(ev), sig_category()); } + }; +} // anonymous namespace + +namespace seh_errors { + + std::error_code make_error_code(error_code_enum e) + { + return {static_cast(e), seh_category()}; + } + +} // namespace errors + +std::error_category& seh_category() +{ + static seh_error_category seh_category; + return seh_category; +} + +#endif + +} // namespace sig + diff --git a/rblibtorrent/src/deps/try_signal/signal_error_code.hpp b/rblibtorrent/src/deps/try_signal/signal_error_code.hpp new file mode 100644 index 00000000..91ea9478 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/signal_error_code.hpp @@ -0,0 +1,162 @@ +/* + +Copyright (c) 2016, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef SIGNAL_ERROR_CODE_HPP_INCLUDED +#define SIGNAL_ERROR_CODE_HPP_INCLUDED + +#include +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +#ifdef __GNUC__ +#include +#else +#include +#endif +#endif + +namespace sig { +namespace errors { + +#ifdef _WIN32 +#define SIG_ENUM(name, sig) name, +#else +#define SIG_ENUM(name, sig) name = sig, +#endif + + enum error_code_enum: int + { + SIG_ENUM(abort, SIGABRT) + SIG_ENUM(alarm, SIGALRM) + SIG_ENUM(arithmetic_exception, SIGFPE) + SIG_ENUM(hangup, SIGHUP) + SIG_ENUM(illegal, SIGILL) + SIG_ENUM(interrupt, SIGINT) + SIG_ENUM(kill, SIGKILL) + SIG_ENUM(pipe, SIGPIPE) + SIG_ENUM(quit, SIGQUIT) + SIG_ENUM(segmentation, SIGSEGV) + SIG_ENUM(terminate, SIGTERM) + SIG_ENUM(user1, SIGUSR1) + SIG_ENUM(user2, SIGUSR2) + SIG_ENUM(child, SIGCHLD) + SIG_ENUM(cont, SIGCONT) + SIG_ENUM(stop, SIGSTOP) + SIG_ENUM(terminal_stop, SIGTSTP) + SIG_ENUM(terminal_in, SIGTTIN) + SIG_ENUM(terminal_out, SIGTTOU) + SIG_ENUM(bus, SIGBUS) +#ifdef SIGPOLL + SIG_ENUM(poll, SIGPOLL) +#endif + SIG_ENUM(profiler, SIGPROF) + SIG_ENUM(system_call, SIGSYS) + SIG_ENUM(trap, SIGTRAP) + SIG_ENUM(urgent_data, SIGURG) + SIG_ENUM(virtual_timer, SIGVTALRM) + SIG_ENUM(cpu_limit, SIGXCPU) + SIG_ENUM(file_size_limit, SIGXFSZ) + }; + +#undef SIG_ENUM + + std::error_code make_error_code(error_code_enum e); + std::error_condition make_error_condition(error_code_enum e); + +} // namespace errors + +std::error_category& sig_category(); + +#ifdef _WIN32 +namespace seh_errors { + + // standard error codes are "int", the win32 exceptions are DWORD (i.e. + // unsigned int). We coerce them into int here for compatibility, and we're + // not concerned about their arithmetic + enum error_code_enum: int + { + access_violation = int(EXCEPTION_ACCESS_VIOLATION), + array_bounds_exceeded = int(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), + guard_page = int(EXCEPTION_GUARD_PAGE), + stack_overflow = int(EXCEPTION_STACK_OVERFLOW), + flt_stack_check = int(EXCEPTION_FLT_STACK_CHECK), + in_page_error = int(EXCEPTION_IN_PAGE_ERROR), + breakpoint = int(EXCEPTION_BREAKPOINT), + single_step = int(EXCEPTION_SINGLE_STEP), + datatype_misalignment = int(EXCEPTION_DATATYPE_MISALIGNMENT), + flt_denormal_operand = int(EXCEPTION_FLT_DENORMAL_OPERAND), + flt_divide_by_zero = int(EXCEPTION_FLT_DIVIDE_BY_ZERO), + flt_inexact_result = int(EXCEPTION_FLT_INEXACT_RESULT), + flt_invalid_operation = int(EXCEPTION_FLT_INVALID_OPERATION), + flt_overflow = int(EXCEPTION_FLT_OVERFLOW), + flt_underflow = int(EXCEPTION_FLT_UNDERFLOW), + int_divide_by_zero = int(EXCEPTION_INT_DIVIDE_BY_ZERO), + int_overflow = int(EXCEPTION_INT_OVERFLOW), + illegal_instruction = int(EXCEPTION_ILLEGAL_INSTRUCTION), + invalid_disposition = int(EXCEPTION_INVALID_DISPOSITION), + priv_instruction = int(EXCEPTION_PRIV_INSTRUCTION), + noncontinuable_exception = int(EXCEPTION_NONCONTINUABLE_EXCEPTION), + status_unwind_consolidate = int(STATUS_UNWIND_CONSOLIDATE), + invalid_handle = int(EXCEPTION_INVALID_HANDLE), + }; + + std::error_code make_error_code(error_code_enum e); +} + +std::error_category& seh_category(); + +#endif // _WIN32 + +} // namespace sig + +namespace std +{ +template<> +struct is_error_code_enum : std::true_type {}; + +template<> +struct is_error_condition_enum : std::true_type {}; + +#ifdef _WIN32 +template<> +struct is_error_code_enum : std::true_type {}; +#endif + +} // namespace std + +#endif + diff --git a/rblibtorrent/src/deps/try_signal/test.cpp b/rblibtorrent/src/deps/try_signal/test.cpp new file mode 100644 index 00000000..b8c67c8e --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/test.cpp @@ -0,0 +1,47 @@ +#include +#include +#include // for memcpy + +#include "try_signal.hpp" + +int main() +{ + char const buf[] = "test...test"; + char dest[sizeof(buf)]; + + { + sig::try_signal([&]{ + std::memcpy(dest, buf, sizeof(buf)); + }); + if (!std::equal(buf, buf + sizeof(buf), dest)) { + fprintf(stderr, "ERROR: buffer not copied correctly\n"); + return 1; + } + } + + try { + void* invalid_pointer = nullptr; + sig::try_signal([&]{ + std::memcpy(dest, buf, sizeof(buf)); + std::memcpy(dest, invalid_pointer, sizeof(buf)); + }); + } + catch (std::system_error const& e) + { + if (e.code() != std::error_condition(sig::errors::segmentation)) { + fprintf(stderr, "ERROR: expected segmentaiton violation error\n"); + } + else { + fprintf(stderr, "OK\n"); + } + fprintf(stderr, "exited with expected system_error exception: %s\n", e.what()); + + // we expect this to happen, so return 0 + return e.code() == std::error_condition(sig::errors::segmentation) ? 0 : 1; + } + + // return non-zero here because we don't expect this + fprintf(stderr, "ERROR: expected exit through exception\n"); + return 1; +} + diff --git a/rblibtorrent/src/deps/try_signal/try_signal.cpp b/rblibtorrent/src/deps/try_signal/try_signal.cpp new file mode 100644 index 00000000..be5cd8d2 --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/try_signal.cpp @@ -0,0 +1,144 @@ +/* + +Copyright (c) 2016, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include +#include +#include +#include + +#include "try_signal.hpp" + +#if !defined _WIN32 +// linux + +namespace sig { +namespace detail { + +namespace { +thread_local sigjmp_buf* jmpbuf = nullptr; +} + +std::atomic_flag once = ATOMIC_FLAG_INIT; + +scoped_jmpbuf::scoped_jmpbuf(sigjmp_buf* ptr) +{ + _previous_ptr = jmpbuf; + jmpbuf = ptr; + std::atomic_signal_fence(std::memory_order_release); +} + +scoped_jmpbuf::~scoped_jmpbuf() { jmpbuf = _previous_ptr; } + +void handler(int const signo, siginfo_t*, void*) +{ + std::atomic_signal_fence(std::memory_order_acquire); + if (jmpbuf) + siglongjmp(*jmpbuf, signo); + + // this signal was not caused within the scope of a try_signal object, + // invoke the default handler + signal(signo, SIG_DFL); + raise(signo); +} + +void setup_handler() +{ + struct sigaction sa; + sa.sa_sigaction = &sig::detail::handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, nullptr); + sigaction(SIGBUS, &sa, nullptr); +} + +} // detail namespace +} // sig namespace + +#elif __GNUC__ +// mingw + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +namespace sig { +namespace detail { + +thread_local jmp_buf* jmpbuf = nullptr; + +long CALLBACK handler(EXCEPTION_POINTERS* pointers) +{ + std::atomic_signal_fence(std::memory_order_acquire); + if (jmpbuf) + longjmp(*jmpbuf, pointers->ExceptionRecord->ExceptionCode); + return EXCEPTION_CONTINUE_SEARCH; +} + +scoped_handler::scoped_handler(jmp_buf* ptr) +{ + _previous_ptr = jmpbuf; + jmpbuf = ptr; + std::atomic_signal_fence(std::memory_order_release); + _handle = AddVectoredExceptionHandler(1, sig::detail::handler); +} +scoped_handler::~scoped_handler() +{ + RemoveVectoredExceptionHandler(_handle); + jmpbuf = _previous_ptr; +} + +} // detail namespace +} // sig namespace + +#else +// windows + +#include // for EXCEPTION_* + +namespace sig { +namespace detail { + + // these are the kinds of SEH exceptions we'll translate into C++ exceptions + bool catch_error(int const code) + { + return code == EXCEPTION_IN_PAGE_ERROR + || code == EXCEPTION_ACCESS_VIOLATION + || code == EXCEPTION_ARRAY_BOUNDS_EXCEEDED; + } +} // detail namespace +} // namespace sig + +#endif // _WIN32 + + diff --git a/rblibtorrent/src/deps/try_signal/try_signal.hpp b/rblibtorrent/src/deps/try_signal/try_signal.hpp new file mode 100644 index 00000000..557d92bb --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/try_signal.hpp @@ -0,0 +1,49 @@ +/* + +Copyright (c) 2017, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TRY_SIGNAL_HPP_INCLUDED +#define TRY_SIGNAL_HPP_INCLUDED + +#if !defined _WIN32 +// linux +#include "try_signal_posix.hpp" +#elif __GNUC__ +// mingw +#include "try_signal_mingw.hpp" +#else +// windows +#include "try_signal_msvc.hpp" +#endif + + +#endif // TRY_SIGNAL_HPP_INCLUDED + diff --git a/rblibtorrent/src/deps/try_signal/try_signal_mingw.hpp b/rblibtorrent/src/deps/try_signal/try_signal_mingw.hpp new file mode 100644 index 00000000..e4db043e --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/try_signal_mingw.hpp @@ -0,0 +1,78 @@ +/* + +Copyright (c) 2017, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TRY_SIGNAL_MINGW_HPP_INCLUDED +#define TRY_SIGNAL_MINGW_HPP_INCLUDED + +#include "signal_error_code.hpp" + +#include // for jmp_buf + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +namespace sig { +namespace detail { + +struct scoped_handler +{ + scoped_handler(jmp_buf* ptr); + ~scoped_handler(); + scoped_handler(scoped_handler const&) = delete; + scoped_handler& operator=(scoped_handler const&) = delete; +private: + void* _handle; + jmp_buf* _previous_ptr; +}; + +} // detail namespace + +template +void try_signal(Fun&& f) +{ + jmp_buf buf; + int const code = setjmp(buf); + // set the thread local jmpbuf pointer, and make sure it's cleared when we + // leave the scope + sig::detail::scoped_handler scope(&buf); + if (code != 0) + throw std::system_error(std::error_code(code, seh_category())); + + f(); +} + +} // sig namespace + +#endif + diff --git a/rblibtorrent/src/deps/try_signal/try_signal_msvc.hpp b/rblibtorrent/src/deps/try_signal/try_signal_msvc.hpp new file mode 100644 index 00000000..04cc62df --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/try_signal_msvc.hpp @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2017, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TRY_SIGNAL_MSVC_HPP_INCLUDED +#define TRY_SIGNAL_MSVC_HPP_INCLUDED + +#include "signal_error_code.hpp" + +namespace sig { +namespace detail { + +bool catch_error(int const code); + +} // detail namespace + +template +void try_signal(Fun&& f) +{ + __try + { + f(); + } + __except (detail::catch_error(GetExceptionCode())) + { + throw std::system_error(std::error_code(GetExceptionCode(), seh_category())); + } +} + +} // sig namespace + +#endif + diff --git a/rblibtorrent/src/deps/try_signal/try_signal_posix.hpp b/rblibtorrent/src/deps/try_signal/try_signal_posix.hpp new file mode 100644 index 00000000..2c4615de --- /dev/null +++ b/rblibtorrent/src/deps/try_signal/try_signal_posix.hpp @@ -0,0 +1,82 @@ +/* + +Copyright (c) 2017, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TRY_SIGNAL_POSIX_HPP_INCLUDED +#define TRY_SIGNAL_POSIX_HPP_INCLUDED + +#include "signal_error_code.hpp" +#include // for sigjmp_buf +#include + +namespace sig { + +namespace detail { + +extern std::atomic_flag once; + +struct scoped_jmpbuf +{ + explicit scoped_jmpbuf(sigjmp_buf* ptr); + ~scoped_jmpbuf(); + scoped_jmpbuf(scoped_jmpbuf const&) = delete; + scoped_jmpbuf& operator=(scoped_jmpbuf const&) = delete; +private: + sigjmp_buf* _previous_ptr; +}; + +void handler(int const signo, siginfo_t* si, void*); +void setup_handler(); + +} // detail namespace + +template +void try_signal(Fun&& f) +{ + if (sig::detail::once.test_and_set() == false) { + sig::detail::setup_handler(); + } + + sigjmp_buf buf; + int const sig = sigsetjmp(buf, 1); + // set the thread local jmpbuf pointer, and make sure it's cleared when we + // leave the scope + sig::detail::scoped_jmpbuf scope(&buf); + if (sig != 0) + throw std::system_error(static_cast(sig)); + + f(); +} + +} + +#endif + diff --git a/redsocks2/Makefile b/redsocks2/Makefile new file mode 100644 index 00000000..9f2949f6 --- /dev/null +++ b/redsocks2/Makefile @@ -0,0 +1,48 @@ + +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=redsocks2 +PKG_VERSION:=0.73 +PKG_RELEASE:=1 + +PKG_SOURCE:=redsocks-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/redsocks/tar.gz/release-$(PKG_VERSION)? +PKG_HASH:=0c9a50b6039cd9fe078a3da5fb5317e38fe52ec59fba7fa9abdf3b002471ebfd +PKG_BUILD_DIR:=$(BUILD_DIR)/redsocks-release-$(PKG_VERSION) + +PKG_MAINTAINER:=semigodking +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILE:=LICENSE + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/redsocks2 + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=Redirect TCP connection to proxy server + URL:=https://github.com/kenzok8/redsocks + DEPENDS:=+libevent2 +libopenssl +endef + +define Package/redsocks2/description + This is a modified version of original redsocks. + Transparent redirector of any TCP/UDP connection to proxy. +endef + +MAKE_VARS += DISABLE_SHADOWSOCKS=true + +define Package/redsocks2/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/redsocks2 $(1)/usr/sbin + $(INSTALL_DIR) $(1)/etc/redsocks2 + $(INSTALL_DATA) ./files/redsocks2.template $(1)/etc/redsocks2/config.template +endef + +$(eval $(call BuildPackage,redsocks2)) diff --git a/redsocks2/files/redsocks2.template b/redsocks2/files/redsocks2.template new file mode 100644 index 00000000..ba494267 --- /dev/null +++ b/redsocks2/files/redsocks2.template @@ -0,0 +1,33 @@ +base { + log_debug = off; + redirector = iptables; + reuseport = on; +} +redsocks { + local_ip = 192.168.1.1; + local_port = 1081; + ip = 192.168.1.1; + port = 9050; + type = socks5; // I use socks5 proxy for GFW'ed IP + autoproxy = 1; // I want autoproxy feature enabled on this section. + // timeout is meaningful when 'autoproxy' is non-zero. + // It specified timeout value when trying to connect to destination + // directly. Default is 10 seconds. When it is set to 0, default + // timeout value will be used. + // NOTE: decreasing the timeout value may lead increase of chance for + // normal IP to be misjudged. + timeout = 13; + //type = http-connect; + //login = username; + //password = passwd; +} +tcpdns { + // Transform UDP DNS requests into TCP DNS requests. + // You can also redirect connections to external TCP DNS server to + // REDSOCKS transparent proxy via iptables. + local_ip = 192.168.1.1; // Local server to act as DNS server + local_port = 1053; // UDP port to receive UDP DNS requests + tcpdns1 = 8.8.4.4; // DNS server that supports TCP DNS requests + tcpdns2 = 8.8.8.8; // DNS server that supports TCP DNS requests + timeout = 4; // Timeout value for TCP DNS requests +} diff --git a/rosy-file-server/Makefile b/rosy-file-server/Makefile new file mode 100644 index 00000000..c1a097d0 --- /dev/null +++ b/rosy-file-server/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2019 rosysong@rosinson.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rosy-file-server +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-2.0 + +PKG_MAINTAINER:=Rosy Song + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/rosy-file-server + SUBMENU:=File Transfer + SECTION:=net + CATEGORY:=Network + TITLE:=Rosy File Server over HTTP + PKGARCH:=all +endef + +define Package/rosy-file-server/description + This package is a configuration management for luci-app-rosy-file-server. +endef + +define Package/rosy-file-server/conffiles +/etc/config/rosy-file-server +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/rosy-file-server/install + $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config + $(INSTALL_BIN) ./files/rosyfs.init $(1)/etc/init.d/rosyfs + $(INSTALL_CONF) ./files/rosyfs.config $(1)/etc/config/rosyfs +endef + +$(eval $(call BuildPackage,rosy-file-server)) diff --git a/rosy-file-server/files/rosyfs.config b/rosy-file-server/files/rosyfs.config new file mode 100644 index 00000000..53ad71ad --- /dev/null +++ b/rosy-file-server/files/rosyfs.config @@ -0,0 +1,13 @@ +# +# Copyright (C) 2019 rosysong@rosinson.com +# + +config rosyfs default + + # Web title + option title 'Rosy File Server' + + # Path to share + option target '/www' + + option disabled '0' diff --git a/rosy-file-server/files/rosyfs.init b/rosy-file-server/files/rosyfs.init new file mode 100755 index 00000000..ebcd19db --- /dev/null +++ b/rosy-file-server/files/rosyfs.init @@ -0,0 +1,29 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2019 rosysong@rosinson.com +# + +START=99 +USE_PROCD=1 +SHARE_PATH=/www/rosyfs-share + +service_triggers() { + procd_add_reload_trigger rosyfs +} + +start_service() { + config_load rosyfs + config_get disabled default disabled '0' + config_get target default target '' + + [ $disabled -eq 1 ] && return + + [ -n "$target" -a ! "$(readlink $SHARE_PATH)" = "$target" ] && { + rm -f $SHARE_PATH + ln -s $target $SHARE_PATH + } +} + +stop_service() { + rm -f $SHARE_PATH +} diff --git a/shadow-tls/Makefile b/shadow-tls/Makefile new file mode 100644 index 00000000..2b70c4e5 --- /dev/null +++ b/shadow-tls/Makefile @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/package.mk + +PKG_NAME:=shadow-tls +PKG_VERSION:=0.2.25 +PKG_RELEASE:=1 + +RELEASE_HEAD:=$(PKG_NAME) +RELEASE_FOOT:=unknown-linux-musl +ifeq ($(ARCH),aarch64) + PKG_ARCH:=$(RELEASE_HEAD)-aarch64-$(RELEASE_FOOT) + PKG_HASH:=3295476b37f549a68906519d3eaecb74bf3b6eaf9094cebb16ee84f0151373c6 +else ifeq ($(ARCH),arm) + ifeq ($(CONFIG_CPU_TYPE),cortex-a7) + PKG_ARCH:=$(RELEASE_HEAD)-armv7-$(RELEASE_FOOT)eabihf + PKG_HASH:=e6f918a072557c50fd0ea950af9a156a9b102af72c1d010ff85d08d13006c54f + else ifeq ($(CONFIG_CPU_TYPE),cortex-a9) + PKG_ARCH:=$(RELEASE_HEAD)-armv7-$(RELEASE_FOOT)eabihf + PKG_HASH:=e6f918a072557c50fd0ea950af9a156a9b102af72c1d010ff85d08d13006c54f + else + PKG_ARCH:=$(RELEASE_HEAD)-arm-$(RELEASE_FOOT)eabi + PKG_HASH:=b6743bc60e1727972ece0fd5acf3a931e5be05cedee6f637e7e3d8c5b8d58f16 + endif +else ifeq ($(ARCH),x86_64) + PKG_ARCH:=$(RELEASE_HEAD)-x86_64-$(RELEASE_FOOT) + PKG_HASH:=a173f5f2d57f45211b68e10ceeddc15b1791077b914fa89747bc705fddc71532 +else + PKG_SOURCE:=dummy + PKG_HASH:=dummy +endif + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +define Download/shadow-tls + URL:=https://github.com/ihciah/shadow-tls/releases/download/v$(PKG_VERSION) + URL_FILE:=$(PKG_ARCH) + FILE:=$(PKG_ARCH) + HASH:=$(PKG_HASH) +endef + +define Package/shadow-tls + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=A proxy to expose real tls handshake to the firewall. + URL:=https://github.com/ihciah/shadow-tls + DEPENDS:=@USE_MUSL @(aarch64||arm||x86_64) @!(TARGET_x86_geode||TARGET_x86_legacy) +endef + +define Build/Prepare + $(call Build/Prepare/Default) +ifneq ($(CONFIG_PACKAGE_shadow-tls),) + $(call Download,shadow-tls) +endif +endef + +define Build/Compile +endef + +define Package/shadow-tls/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(DL_DIR)/$(PKG_ARCH) $(1)/usr/bin/shadow-tls +endef + +$(eval $(call BuildPackage,shadow-tls)) diff --git a/shadowsocks-libev/Makefile b/shadowsocks-libev/Makefile new file mode 100644 index 00000000..0d586097 --- /dev/null +++ b/shadowsocks-libev/Makefile @@ -0,0 +1,98 @@ +# +# Copyright (C) 2017-2020 Yousong Zhou +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +# Checklist when bumping versions +# +# - update cipher list by checking src/crypto.c:crypto_init() +# - check if default mode has changed from being tcp_only +# +PKG_NAME:=shadowsocks-libev +PKG_VERSION:=3.3.6 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev.git +PKG_SOURCE_DATE:=2026-02-09 +PKG_SOURCE_VERSION:=c5e8788013a37afe54ea1c2b7c03395cccc663cf +PKG_MIRROR_HASH:=96d0b486a0c8dbb2acf2af56534f6c765565c127c3695c98b5157b24993a4839 + +PKG_MAINTAINER:=Yousong Zhou + +PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE_FILES:=LICENSE +PKG_CPE_ID:=cpe:/a:shadowsocks:shadowsocks-libev + +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 lto + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +CMAKE_OPTIONS += \ + -DWITH_STATIC=OFF \ + -DWITH_EMBEDDED_SRC=ON \ + -DWITH_DOC_MAN=OFF \ + -DWITH_DOC_HTML=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=OFF \ + -DENABLE_CONNMARKTOS=OFF \ + -DENABLE_NFTABLES=OFF + +define Package/shadowsocks-libev/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + URL:=https://github.com/shadowsocks/shadowsocks-libev + DEPENDS:=+libev +libmbedtls +libpthread +libsodium +libcares +libpcre2 +endef + +define Package/shadowsocks-libev-ss-local + $(call Package/shadowsocks-libev/Default) + TITLE:=shadowsocks-libev ss-local +endef + +define Package/shadowsocks-libev-ss-redir + $(call Package/shadowsocks-libev/Default) + TITLE:=shadowsocks-libev ss-redir +endef + +define Package/shadowsocks-libev-ss-tunnel + $(call Package/shadowsocks-libev/Default) + TITLE:=shadowsocks-libev ss-tunnel +endef + +define Package/shadowsocks-libev-ss-server + $(call Package/shadowsocks-libev/Default) + TITLE:=shadowsocks-libev ss-server +endef + +define Package/shadowsocks-libev-ss-local/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ss-local $(1)/usr/bin +endef + +define Package/shadowsocks-libev-ss-redir/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ss-redir $(1)/usr/bin +endef + +define Package/shadowsocks-libev-ss-tunnel/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ss-tunnel $(1)/usr/bin +endef + +define Package/shadowsocks-libev-ss-server/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ss-server $(1)/usr/bin +endef + +$(eval $(call BuildPackage,shadowsocks-libev-ss-local)) +$(eval $(call BuildPackage,shadowsocks-libev-ss-redir)) +$(eval $(call BuildPackage,shadowsocks-libev-ss-tunnel)) +$(eval $(call BuildPackage,shadowsocks-libev-ss-server)) diff --git a/shadowsocks-libev/patches/101-Fix-mishandling-of-incoming-socket-buffer.-It-must-b.patch b/shadowsocks-libev/patches/101-Fix-mishandling-of-incoming-socket-buffer.-It-must-b.patch new file mode 100644 index 00000000..1c164a95 --- /dev/null +++ b/shadowsocks-libev/patches/101-Fix-mishandling-of-incoming-socket-buffer.-It-must-b.patch @@ -0,0 +1,141 @@ +From 8be7a7cb00b9540e9be05d409191b0bc1ba424f0 Mon Sep 17 00:00:00 2001 +From: notsure2 +Date: Mon, 11 Dec 2023 09:15:47 +0200 +Subject: [PATCH] Fix mishandling of incoming socket buffer. It must be set on + the listening socket not the accepted socket. + +--- + src/local.c | 16 ++++++++-------- + src/redir.c | 16 ++++++++-------- + src/server.c | 16 ++++++++-------- + src/tunnel.c | 16 ++++++++-------- + 4 files changed, 32 insertions(+), 32 deletions(-) + +--- a/src/local.c ++++ b/src/local.c +@@ -205,6 +205,14 @@ create_and_bind(const char *addr, const + } + } + ++ if (tcp_incoming_sndbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); ++ } ++ ++ if (tcp_incoming_rcvbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); ++ } ++ + s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); + if (s == 0) { + /* We managed to bind successfully! */ +@@ -1406,14 +1414,6 @@ accept_cb(EV_P_ ev_io *w, int revents) + setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); + #endif + +- if (tcp_incoming_sndbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); +- } +- +- if (tcp_incoming_rcvbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); +- } +- + server_t *server = new_server(serverfd); + server->listener = listener; + +--- a/src/redir.c ++++ b/src/redir.c +@@ -201,6 +201,14 @@ create_and_bind(const char *addr, const + LOGI("tcp tproxy mode enabled"); + } + ++ if (tcp_incoming_sndbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); ++ } ++ ++ if (tcp_incoming_rcvbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); ++ } ++ + s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); + if (s == 0) { + /* We managed to bind successfully! */ +@@ -759,14 +767,6 @@ accept_cb(EV_P_ ev_io *w, int revents) + setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); + #endif + +- if (tcp_incoming_sndbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); +- } +- +- if (tcp_incoming_rcvbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); +- } +- + int index = rand() % listener->remote_num; + struct sockaddr *remote_addr = listener->remote_addr[index]; + +--- a/src/server.c ++++ b/src/server.c +@@ -620,6 +620,14 @@ create_and_bind(const char *host, const + } + } + ++ if (tcp_incoming_sndbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); ++ } ++ ++ if (tcp_incoming_rcvbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); ++ } ++ + // Enable out-of-tree mptcp + if (mptcp == 1) { + int i = 0; +@@ -1769,14 +1777,6 @@ accept_cb(EV_P_ ev_io *w, int revents) + setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); + #endif + +- if (tcp_incoming_sndbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); +- } +- +- if (tcp_incoming_rcvbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); +- } +- + setnonblocking(serverfd); + + server_t *server = new_server(serverfd, listener); +--- a/src/tunnel.c ++++ b/src/tunnel.c +@@ -166,6 +166,14 @@ create_and_bind(const char *addr, const + } + } + ++ if (tcp_incoming_sndbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); ++ } ++ ++ if (tcp_incoming_rcvbuf > 0) { ++ setsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); ++ } ++ + s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); + if (s == 0) { + /* We managed to bind successfully! */ +@@ -725,14 +733,6 @@ accept_cb(EV_P_ ev_io *w, int revents) + setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); + #endif + +- if (tcp_incoming_sndbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int)); +- } +- +- if (tcp_incoming_rcvbuf > 0) { +- setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int)); +- } +- + int index = rand() % listener->remote_num; + struct sockaddr *remote_addr = listener->remote_addr[index]; + diff --git a/shadowsocks-libev/patches/102-deprecate-load16-be-replace-with-ntohs.patch b/shadowsocks-libev/patches/102-deprecate-load16-be-replace-with-ntohs.patch new file mode 100644 index 00000000..2e0879fb --- /dev/null +++ b/shadowsocks-libev/patches/102-deprecate-load16-be-replace-with-ntohs.patch @@ -0,0 +1,115 @@ +From f4ee43fa27e00a573d90a8cac68f12655570bbf7 Mon Sep 17 00:00:00 2001 +From: lwb1978 <86697442+lwb1978@users.noreply.github.com> +Date: Tue, 4 Feb 2025 15:51:17 +0800 +Subject: [PATCH] Deprecate load16_be() function in favor to ntohs() function + +--- + src/aead.c | 2 +- + src/local.c | 6 +++--- + src/server.c | 2 +- + src/udprelay.c | 2 +- + src/utils.c | 8 -------- + src/utils.h | 1 - + 6 files changed, 6 insertions(+), 15 deletions(-) + +diff --git a/src/aead.c b/src/aead.c +index 73349da64..e5d9b01e7 100644 +--- a/src/aead.c ++++ b/src/aead.c +@@ -605,7 +605,7 @@ aead_chunk_decrypt(cipher_ctx_t *ctx, uint8_t *p, uint8_t *c, uint8_t *n, + return CRYPTO_ERROR; + assert(*plen == CHUNK_SIZE_LEN); + +- mlen = load16_be(len_buf); ++ mlen = ntohs(*(uint16_t*)len_buf); + mlen = mlen & CHUNK_SIZE_MASK; + + if (mlen == 0) +diff --git a/src/local.c b/src/local.c +index fa1ca7b31..76d46de17 100644 +--- a/src/local.c ++++ b/src/local.c +@@ -382,7 +382,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) + abuf->len += in_addr_len + 2; + + if (acl || verbose) { +- uint16_t p = load16_be(buf->data + request_len + in_addr_len); ++ uint16_t p = ntohs(*(uint16_t*)(buf->data + request_len + in_addr_len)); + if (!inet_ntop(AF_INET, (const void *)(buf->data + request_len), + ip, INET_ADDRSTRLEN)) { + LOGI("inet_ntop(AF_INET): %s", strerror(errno)); +@@ -400,7 +400,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) + abuf->len += name_len + 2; + + if (acl || verbose) { +- uint16_t p = load16_be(buf->data + request_len + 1 + name_len); ++ uint16_t p = ntohs(*(uint16_t*)(buf->data + request_len + 1 + name_len)); + memcpy(host, buf->data + request_len + 1, name_len); + host[name_len] = '\0'; + sprintf(port, "%d", p); +@@ -414,7 +414,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) + abuf->len += in6_addr_len + 2; + + if (acl || verbose) { +- uint16_t p = load16_be(buf->data + request_len + in6_addr_len); ++ uint16_t p = ntohs(*(uint16_t*)(buf->data + request_len + in6_addr_len)); + if (!inet_ntop(AF_INET6, (const void *)(buf->data + request_len), + ip, INET6_ADDRSTRLEN)) { + LOGI("inet_ntop(AF_INET6): %s", strerror(errno)); +diff --git a/src/server.c b/src/server.c +index 73b65996d..be8c6ffcf 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -1129,7 +1129,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) + return; + } + +- port = ntohs(load16_be(server->buf->data + offset)); ++ port = *(uint16_t*)(server->buf->data + offset); + + offset += 2; + +diff --git a/src/udprelay.c b/src/udprelay.c +index 5de38830a..f6a5a7c25 100644 +--- a/src/udprelay.c ++++ b/src/udprelay.c +@@ -316,7 +316,7 @@ parse_udprelay_header(const char *buf, const size_t buf_len, + } + + if (port != NULL) { +- sprintf(port, "%d", load16_be(buf + offset)); ++ sprintf(port, "%d", ntohs(*(uint16_t*)(buf + offset))); + } + offset += 2; + +diff --git a/src/utils.c b/src/utils.c +index d3ff2aba6..c7a5f0aa6 100644 +--- a/src/utils.c ++++ b/src/utils.c +@@ -571,14 +571,6 @@ get_default_conf(void) + #endif + } + +-uint16_t +-load16_be(const void *s) +-{ +- const uint8_t *in = (const uint8_t *)s; +- return ((uint16_t)in[0] << 8) +- | ((uint16_t)in[1]); +-} +- + int + get_mptcp(int enable) + { +diff --git a/src/utils.h b/src/utils.h +index 1df24c166..c20506da9 100644 +--- a/src/utils.h ++++ b/src/utils.h +@@ -249,7 +249,6 @@ void *ss_realloc(void *ptr, size_t new_size); + + int ss_is_ipv6addr(const char *addr); + char *get_default_conf(void); +-uint16_t load16_be(const void *s); + int get_mptcp(int enable); + + #endif // _UTILS_H diff --git a/shadowsocks-rust/Makefile b/shadowsocks-rust/Makefile new file mode 100644 index 00000000..e0e8e32d --- /dev/null +++ b/shadowsocks-rust/Makefile @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017-2020 Yousong Zhou +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=shadowsocks-rust +PKG_VERSION:=1.24.0 +PKG_RELEASE:=1 + +PKG_SOURCE_HEADER:=shadowsocks-v$(PKG_VERSION) +PKG_SOURCE_BODY:=unknown-linux-musl +PKG_SOURCE_FOOTER:=tar.xz + +ifeq ($(filter $(ARCH),mips mipsel),) + PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-rust/releases/download/v$(PKG_VERSION)/ +else + PKG_SOURCE_URL:=https://github.com/sbwml/shadowsocks-rust-mips/releases/download/v$(PKG_VERSION)/ +endif + +ifeq ($(ARCH),aarch64) + PKG_SOURCE:=$(PKG_SOURCE_HEADER).aarch64-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER) + PKG_HASH:=e00b6551f40bb2d61adb2503909e0df6550c022372c812f3f34350510797ef2f +else ifeq ($(ARCH),arm) + # Referred to golang/golang-values.mk + ARM_CPU_FEATURES:=$(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE)))) + ifeq ($(ARM_CPU_FEATURES),) + PKG_SOURCE:=$(PKG_SOURCE_HEADER).arm-$(PKG_SOURCE_BODY)eabi.$(PKG_SOURCE_FOOTER) + PKG_HASH:=b00694ac484eaf994408c874c70e1d3392d1654cf3d9391ddf2b589bbee9106c + else + PKG_SOURCE:=$(PKG_SOURCE_HEADER).arm-$(PKG_SOURCE_BODY)eabihf.$(PKG_SOURCE_FOOTER) + PKG_HASH:=db56c8e64ce3651907c31fe6a585a68e4c4576c8379f50d82be31d79ba8d00ad + endif +else ifeq ($(ARCH),i386) + PKG_SOURCE:=$(PKG_SOURCE_HEADER).i686-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER) + PKG_HASH:=a9aabb4209a8f29afabddb2aaaa8a38d8f604fd0075250d61bd594bb10ae38c7 +else ifeq ($(ARCH),x86_64) + PKG_SOURCE:=$(PKG_SOURCE_HEADER).x86_64-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER) + PKG_HASH:=0d84f5f350ec99396867d718f146fc3810975b2a7cd06192f158d96bdef460e7 +else ifeq ($(ARCH),mips) + PKG_SOURCE:=$(PKG_SOURCE_HEADER).mips-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER) + PKG_HASH:=40319c20934121e8d5df90e54cd2b41e064a3487f180f6924ac42ba3cbcebe4f +else ifeq ($(ARCH),mipsel) + PKG_SOURCE:=$(PKG_SOURCE_HEADER).mipsel-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER) + PKG_HASH:=d51792a5b4f6a28bb2e8b07e2f39a60535d1ede9d1973a257c5751a991e26ac8 +# Set the default value to make OpenWrt Package Checker happy +else + PKG_SOURCE:=dummy + PKG_HASH:=dummy +endif + +PKG_MAINTAINER:=Tianling Shen +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk + +TAR_CMD:=$(HOST_TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) + +define Package/shadowsocks-rust/Default + define Package/shadowsocks-rust-$(1) + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=shadowsocks-rust $(1) + URL:=https://github.com/shadowsocks/shadowsocks-rust + DEPENDS:=@(aarch64||arm||i386||mips||mipsel||x86_64) @!(TARGET_x86_geode||TARGET_x86_legacy) + endef + + define Package/shadowsocks-rust-$(1)/install + $$(INSTALL_DIR) $$(1)/usr/bin + $$(INSTALL_BIN) $$(PKG_BUILD_DIR)/$(1) $$(1)/usr/bin + endef +endef + +SHADOWSOCKS_COMPONENTS:=sslocal ssmanager ssserver ssurl ssservice +define shadowsocks-rust/templates + $(foreach component,$(SHADOWSOCKS_COMPONENTS), + $(call Package/shadowsocks-rust/Default,$(component)) + ) +endef +$(eval $(call shadowsocks-rust/templates)) + +define Build/Compile +endef + +$(foreach component,$(SHADOWSOCKS_COMPONENTS), \ + $(eval $(call BuildPackage,shadowsocks-rust-$(component))) \ +) diff --git a/shadowsocksr-libev/Makefile b/shadowsocksr-libev/Makefile new file mode 100644 index 00000000..694261db --- /dev/null +++ b/shadowsocksr-libev/Makefile @@ -0,0 +1,84 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=shadowsocksr-libev +PKG_VERSION:=2.5.10 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/shadowsocksr-libev/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=7699d420bea841f6314a7b9d5c5fa996e02139812c79d39bbc4f786c65c4fffc + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 +PKG_BUILD_PARALLEL:=1 +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/shadowsocksr-libev/Default + define Package/shadowsocksr-libev-ssr-$(1) + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=shadowsocksr-libev ssr-$(1) + URL:=https://github.com/kenzok8/shadowsocksr-libev + DEPENDS:=+libev +libsodium +libopenssl +libpthread +libpcre2 +libudns +zlib +libopenssl-legacy + endef + + define Package/shadowsocksr-libev-ssr-$(1)/install + $$(INSTALL_DIR) $$(1)/usr/bin + $$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/usr/bin/ss-$(1) $$(1)/usr/bin/ssr-$(1) + endef +endef + +SHADOWSOCKSR_COMPONENTS:=check local nat redir server +define shadowsocksr-libev/templates + $(foreach component,$(SHADOWSOCKSR_COMPONENTS), + $(call Package/shadowsocksr-libev/Default,$(component)) + ) +endef +$(eval $(call shadowsocksr-libev/templates)) + +define Build/Prepare + $(call Build/Prepare/Default) + # Patch configure: use pcre2 instead of pcre1 (OpenWrt 24.10 only provides pcre2) + sed -i \ + -e 's/pcre-config/pcre2-config/g' \ + -e 's/PCRE_CONFIG --libs/PCRE_CONFIG --libs8/g' \ + -e 's/pcre_exec/pcre2_match_8/g' \ + -e '/for ac_lib in/{s/ pcre;/ pcre2-8;/}' \ + -e 's/pcre\.h/pcre2.h/g' \ + -e 's/pcre\/pcre\.h/pcre2\/pcre2.h/g' \ + $(PKG_BUILD_DIR)/configure +endef + +define Build/Compile + $(call Build/Compile/Default) + $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/ss-check $(CURDIR)/src/server/check.c +endef + +define Build/Install + $(call Build/Install/Default) + $(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ss-check $(PKG_INSTALL_DIR)/usr/bin/ss-check +endef + +CONFIGURE_ARGS += \ + --disable-documentation \ + --disable-ssp \ + --disable-assert \ + --enable-system-shared-lib \ + --with-pcre=$(STAGING_DIR)/usr + +TARGET_CFLAGS += -flto +TARGET_CFLAGS += -Wno-error=use-after-free +TARGET_CPPFLAGS += -DPCRE2_CODE_UNIT_WIDTH=8 +TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed + +$(foreach component,$(SHADOWSOCKSR_COMPONENTS), \ + $(eval $(call BuildPackage,shadowsocksr-libev-ssr-$(component))) \ +) diff --git a/shadowsocksr-libev/patches/0002-Revert-verify_simple-and-auth_simple.patch b/shadowsocksr-libev/patches/0002-Revert-verify_simple-and-auth_simple.patch new file mode 100644 index 00000000..c2374161 --- /dev/null +++ b/shadowsocksr-libev/patches/0002-Revert-verify_simple-and-auth_simple.patch @@ -0,0 +1,20 @@ +--- a/src/obfs/obfs.c ++++ b/src/obfs/obfs.c +@@ -88,7 +88,7 @@ obfs_class *new_obfs_class(const char *p + plugin->client_decode = tls12_ticket_auth_client_decode; + + return plugin; +- /*} else if (strcmp(plugin_name, "verify_simple") == 0) { ++ } else if (strcmp(plugin_name, "verify_simple") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs_class)); + plugin->init_data = init_data; + plugin->new_obfs = verify_simple_new_obfs; +@@ -115,7 +115,7 @@ obfs_class *new_obfs_class(const char *p + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + +- return plugin;*/ ++ return plugin; + } else if (strcmp(plugin_name, "auth_sha1") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs_class)); + plugin->init_data = auth_simple_init_data; diff --git a/shadowsocksr-libev/patches/0003-Refine-Usage.patch b/shadowsocksr-libev/patches/0003-Refine-Usage.patch new file mode 100644 index 00000000..1d8d7f29 --- /dev/null +++ b/shadowsocksr-libev/patches/0003-Refine-Usage.patch @@ -0,0 +1,37 @@ +--- a/src/utils.c ++++ b/src/utils.c +@@ -258,8 +258,6 @@ usage() + { + printf("\n"); + printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO); +- printf( +- " maintained by Max Lv and Linus Yang \n\n"); + printf(" usage:\n\n"); + #ifdef MODULE_LOCAL + printf(" ss-local\n"); +@@ -299,6 +297,25 @@ usage() + " The default cipher is rc4-md5.\n"); + printf("\n"); + printf( ++ " -o Obfs of your remote server: plain,\n"); ++ printf( ++ " http_simple, http_post and tls1.2_ticket_auth.\n"); ++ printf( ++ " -g Obfs-Param of your remote server.\n"); ++ printf( ++ " -O Protocol of your remote server: origin,\n"); ++ printf( ++ " auth_sha1, auth_sha1_v2, auth_sha1_v4,\n"); ++ printf( ++ " auth_aes128_md5, auth_aes128_sha1,\n"); ++ printf( ++ " auth_chain_a, auth_chain_b, auth_chain_c,\n"); ++ printf( ++ " auth_chain_d, auth_chain_e and auth_chain_f.\n"); ++ printf( ++ " -G Protocol-Param of your remote server.\n"); ++ printf("\n"); ++ printf( + " [-a ] Run as another user.\n"); + printf( + " [-f ] The file path to store pid.\n"); diff --git a/shadowsocksr-libev/patches/103-Add-TPROXY-support-for-TCP-ssr-redir.patch b/shadowsocksr-libev/patches/103-Add-TPROXY-support-for-TCP-ssr-redir.patch new file mode 100644 index 00000000..cded4114 --- /dev/null +++ b/shadowsocksr-libev/patches/103-Add-TPROXY-support-for-TCP-ssr-redir.patch @@ -0,0 +1,152 @@ +--- a/completions/bash/ss-redir ++++ b/completions/bash/ss-redir +@@ -2,7 +2,7 @@ _ss_redir() + { + local cur prev opts ciphers + ciphers='rc4-md5 table rc4 aes-128-cfb aes-192-cfb aes-256-cfb aes-128-ctr aes-192-ctr aes-256-ctr bf-cfb camellia-128-cfb camellia-192-cfb camellia-256-cfb cast5-cfb des-cfb idea-cfb rc2-cfb seed-cfb salsa20 chacha20 and chacha20-ietf' +- opts='-s -b -p -k -f -t -m -c -a -n -u -U -v -h -A --mtu --help --mptcp -l' ++ opts='-s -b -p -k -f -t -m -c -a -n -u -U -T -v -h -A --mtu --help --mptcp -l' + cur=${COMP_WORDS[COMP_CWORD]} + prev="${COMP_WORDS[COMP_CWORD-1]}" + case "$prev" in +--- a/src/jconf.c ++++ b/src/jconf.c +@@ -338,7 +338,11 @@ read_jconf(const char *file) + check_json_value_type(value, json_boolean, + "invalid config file: option 'ipv6_first' must be a boolean"); + conf.ipv6_first = value->u.boolean; +- } ++ } else if (strcmp(name, "tcp_tproxy") == 0) { ++ check_json_value_type(value, json_boolean, ++ "invalid config file: option 'tcp_tproxy' must be a boolean"); ++ conf.tcp_tproxy = value->u.boolean; ++ } + } + } + } else { +--- a/src/jconf.h ++++ b/src/jconf.h +@@ -105,6 +105,7 @@ typedef struct { + int mtu; + int mptcp; + int ipv6_first; ++ int tcp_tproxy; + } jconf_t; + + jconf_t *read_jconf(const char *file); +--- a/src/redir.c ++++ b/src/redir.c +@@ -71,6 +71,14 @@ + #define IP6T_SO_ORIGINAL_DST 80 + #endif + ++#ifndef IP_TRANSPARENT ++#define IP_TRANSPARENT 19 ++#endif ++ ++#ifndef IPV6_TRANSPARENT ++#define IPV6_TRANSPARENT 75 ++#endif ++ + #include "includeobfs.h" // I don't want to modify makefile + #include "jconf.h" + +@@ -114,21 +114,23 @@ + static listen_ctx_t *current_profile; + static struct cork_dllist all_connections; + ++static int tcp_tproxy = 0; /* use tproxy instead of redirect (for tcp) */ ++ + int + getdestaddr(int fd, struct sockaddr_storage *destaddr) + { + socklen_t socklen = sizeof(*destaddr); + int error = 0; + +- error = getsockopt(fd, SOL_IPV6, IP6T_SO_ORIGINAL_DST, destaddr, &socklen); +- if (error) { // Didn't find a proper way to detect IP version. +-#if defined(__FreeBSD__) +- error = getsockname(fd, (struct sockaddr *)destaddr, &socklen); +-#else +- error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen); +-#endif +- if (error) { +- return -1; ++ if (tcp_tproxy) { ++ error = getsockname(fd, (void *)destaddr, &socklen); ++ } else { ++ error = getsockopt(fd, SOL_IPV6, IP6T_SO_ORIGINAL_DST, destaddr, &socklen); ++ if (error) { // Didn't find a proper way to detect IP version. ++ error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen); ++ if (error) { ++ return -1; ++ } + } + } + return 0; +@@ -164,6 +174,23 @@ create_and_bind(const char *addr, const + if (err == 0) { + LOGI("tcp port reuse enabled"); + } ++ ++ if (tcp_tproxy) { ++ int level = 0, optname = 0; ++ if (rp->ai_family == AF_INET) { ++ level = IPPROTO_IP; ++ optname = IP_TRANSPARENT; ++ } else { ++ level = IPPROTO_IPV6; ++ optname = IPV6_TRANSPARENT; ++ } ++ ++ if (setsockopt(listen_sock, level, optname, &opt, sizeof(opt)) != 0) { ++ ERROR("setsockopt IP_TRANSPARENT"); ++ exit(EXIT_FAILURE); ++ } ++ LOGI("tcp tproxy mode enabled"); ++ } + + s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); + if (s == 0) { +@@ -1094,7 +1121,7 @@ main(int argc, char **argv) + + USE_TTY(); + +- while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUvA6" ++ while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUTvA6" + "O:o:G:g:", + long_options, &option_index)) != -1) { + switch (c) { +@@ -1169,6 +1196,9 @@ main(int argc, char **argv) + case 'U': + mode = UDP_ONLY; + break; ++ case 'T': ++ tcp_tproxy = 1; ++ break; + case 'v': + verbose = 1; + break; +@@ -1255,6 +1285,9 @@ main(int argc, char **argv) + if (mode == TCP_ONLY) { + mode = conf->mode; + } ++ if (tcp_tproxy == 0) { ++ tcp_tproxy = conf->tcp_tproxy; ++ } + if (mtu == 0) { + mtu = conf->mtu; + } +--- a/src/utils.c ++++ b/src/utils.c +@@ -342,6 +342,10 @@ usage() + #endif + printf( + " [-U] Enable UDP relay and disable TCP relay.\n"); ++#ifdef MODULE_REDIR ++ printf( ++ " [-T] Use tproxy instead of redirect (for tcp).\n"); ++#endif + #ifdef MODULE_REMOTE + printf( + " [-6] Resovle hostname to IPv6 address first.\n"); diff --git a/shadowsocksr-libev/src/server/Makefile.am b/shadowsocksr-libev/src/server/Makefile.am new file mode 100644 index 00000000..3ae8bc27 --- /dev/null +++ b/shadowsocksr-libev/src/server/Makefile.am @@ -0,0 +1,55 @@ +VERSION_INFO = 2:0:0 + +AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations -fno-strict-aliasing -std=gnu99 -D_GNU_SOURCE +AM_CFLAGS += $(PTHREAD_CFLAGS) +if !USE_SYSTEM_SHARED_LIB +AM_CFLAGS += -I$(top_srcdir)/libev +AM_CFLAGS += -I$(top_srcdir)/libudns +AM_CFLAGS += -I$(top_srcdir)/libsodium/src/libsodium/include +endif +AM_CFLAGS += -I$(top_srcdir)/libipset/include +AM_CFLAGS += -I$(top_srcdir)/libcork/include +AM_CFLAGS += $(LIBPCRE_CFLAGS) + +SS_COMMON_LIBS = $(top_builddir)/libipset/libipset.la \ + $(top_builddir)/libcork/libcork.la \ + $(INET_NTOP_LIB) $(LIBPCRE_LIBS) +if USE_SYSTEM_SHARED_LIB +SS_COMMON_LIBS += -lev -lsodium -lm +else +SS_COMMON_LIBS += $(top_builddir)/libev/libev.la \ + $(top_builddir)/libsodium/src/libsodium/libsodium.la +endif + +bin_PROGRAMS = ss-server ss-check + +sni_src = http.c \ + tls.c \ + rule.c + +ss_check_SOURCES = check.c + +ss_server_SOURCES = utils.c \ + netutils.c \ + jconf.c \ + json.c \ + encrypt.c \ + udprelay.c \ + cache.c \ + acl.c \ + resolv.c \ + server.c \ + $(sni_src) + + +ss_check_LDADD = $(SS_COMMON_LIBS) +ss_server_LDADD = $(SS_COMMON_LIBS) + +if USE_SYSTEM_SHARED_LIB +ss_server_LDADD += -ludns +else +ss_server_LDADD += $(top_builddir)/libudns/libudns.la +endif + +ss_check_CFLAGS = $(AM_CFLAGS) +ss_server_CFLAGS = $(AM_CFLAGS) -DMODULE_REMOTE diff --git a/shadowsocksr-libev/src/server/Makefile.in b/shadowsocksr-libev/src/server/Makefile.in new file mode 100644 index 00000000..17dad959 --- /dev/null +++ b/shadowsocksr-libev/src/server/Makefile.in @@ -0,0 +1,919 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@USE_SYSTEM_SHARED_LIB_FALSE@am__append_1 = -I$(top_srcdir)/libev \ +@USE_SYSTEM_SHARED_LIB_FALSE@ -I$(top_srcdir)/libudns \ +@USE_SYSTEM_SHARED_LIB_FALSE@ -I$(top_srcdir)/libsodium/src/libsodium/include +@USE_SYSTEM_SHARED_LIB_TRUE@am__append_2 = -lev -lsodium -lm +@USE_SYSTEM_SHARED_LIB_FALSE@am__append_3 = $(top_builddir)/libev/libev.la \ +@USE_SYSTEM_SHARED_LIB_FALSE@ $(top_builddir)/libsodium/src/libsodium/libsodium.la + +bin_PROGRAMS = ss-server$(EXEEXT) ss-check$(EXEEXT) +@USE_SYSTEM_SHARED_LIB_TRUE@am__append_4 = -ludns +@USE_SYSTEM_SHARED_LIB_FALSE@am__append_5 = $(top_builddir)/libudns/libudns.la +subdir = server +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/ax_tls.m4 $(top_srcdir)/m4/inet_ntop.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/pcre2.m4 \ + $(top_srcdir)/m4/polarssl.m4 \ + $(top_srcdir)/m4/stack-protector.m4 $(top_srcdir)/m4/zlib.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_ss_check_OBJECTS = ss_check-check.$(OBJEXT) +ss_check_OBJECTS = $(am_ss_check_OBJECTS) +am__DEPENDENCIES_1 = +am__DEPENDENCIES_2 = $(top_builddir)/libipset/libipset.la \ + $(top_builddir)/libcork/libcork.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__append_3) +ss_check_DEPENDENCIES = $(am__DEPENDENCIES_2) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +ss_check_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_check_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__objects_1 = ss_server-http.$(OBJEXT) ss_server-tls.$(OBJEXT) \ + ss_server-rule.$(OBJEXT) +am_ss_server_OBJECTS = ss_server-utils.$(OBJEXT) \ + ss_server-netutils.$(OBJEXT) ss_server-jconf.$(OBJEXT) \ + ss_server-json.$(OBJEXT) ss_server-encrypt.$(OBJEXT) \ + ss_server-udprelay.$(OBJEXT) ss_server-cache.$(OBJEXT) \ + ss_server-acl.$(OBJEXT) ss_server-resolv.$(OBJEXT) \ + ss_server-server.$(OBJEXT) $(am__objects_1) +ss_server_OBJECTS = $(am_ss_server_OBJECTS) +ss_server_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ + $(am__append_5) +ss_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_server_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/auto/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(ss_check_SOURCES) $(ss_server_SOURCES) +DIST_SOURCES = $(ss_check_SOURCES) $(ss_server_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/auto/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GZIP = @GZIP@ +INET_NTOP_LIB = @INET_NTOP_LIB@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBPCRE = @LIBPCRE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MV = @MV@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCRE_CONFIG = @PCRE_CONFIG@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XMLTO = @XMLTO@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pcre_pcreh = @pcre_pcreh@ +pcreh = @pcreh@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +VERSION_INFO = 2:0:0 +AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations \ + -fno-strict-aliasing -std=gnu99 -D_GNU_SOURCE \ + $(PTHREAD_CFLAGS) $(am__append_1) \ + -I$(top_srcdir)/libipset/include \ + -I$(top_srcdir)/libcork/include $(LIBPCRE_CFLAGS) +SS_COMMON_LIBS = $(top_builddir)/libipset/libipset.la \ + $(top_builddir)/libcork/libcork.la $(INET_NTOP_LIB) \ + $(LIBPCRE_LIBS) $(am__append_2) $(am__append_3) +sni_src = http.c \ + tls.c \ + rule.c + +ss_check_SOURCES = check.c +ss_server_SOURCES = utils.c \ + netutils.c \ + jconf.c \ + json.c \ + encrypt.c \ + udprelay.c \ + cache.c \ + acl.c \ + resolv.c \ + server.c \ + $(sni_src) + +ss_check_LDADD = $(SS_COMMON_LIBS) +ss_server_LDADD = $(SS_COMMON_LIBS) $(am__append_4) $(am__append_5) +ss_check_CFLAGS = $(AM_CFLAGS) +ss_server_CFLAGS = $(AM_CFLAGS) -DMODULE_REMOTE +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign server/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign server/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +ss-check$(EXEEXT): $(ss_check_OBJECTS) $(ss_check_DEPENDENCIES) $(EXTRA_ss_check_DEPENDENCIES) + @rm -f ss-check$(EXEEXT) + $(AM_V_CCLD)$(ss_check_LINK) $(ss_check_OBJECTS) $(ss_check_LDADD) $(LIBS) + +ss-server$(EXEEXT): $(ss_server_OBJECTS) $(ss_server_DEPENDENCIES) $(EXTRA_ss_server_DEPENDENCIES) + @rm -f ss-server$(EXEEXT) + $(AM_V_CCLD)$(ss_server_LINK) $(ss_server_OBJECTS) $(ss_server_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_check-check.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-acl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-cache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-encrypt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-jconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-json.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-netutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-resolv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-rule.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-server.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-tls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-udprelay.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-utils.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +ss_check-check.o: check.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -MT ss_check-check.o -MD -MP -MF $(DEPDIR)/ss_check-check.Tpo -c -o ss_check-check.o `test -f 'check.c' || echo '$(srcdir)/'`check.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_check-check.Tpo $(DEPDIR)/ss_check-check.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check.c' object='ss_check-check.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -c -o ss_check-check.o `test -f 'check.c' || echo '$(srcdir)/'`check.c + +ss_check-check.obj: check.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -MT ss_check-check.obj -MD -MP -MF $(DEPDIR)/ss_check-check.Tpo -c -o ss_check-check.obj `if test -f 'check.c'; then $(CYGPATH_W) 'check.c'; else $(CYGPATH_W) '$(srcdir)/check.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_check-check.Tpo $(DEPDIR)/ss_check-check.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check.c' object='ss_check-check.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_check_CFLAGS) $(CFLAGS) -c -o ss_check-check.obj `if test -f 'check.c'; then $(CYGPATH_W) 'check.c'; else $(CYGPATH_W) '$(srcdir)/check.c'; fi` + +ss_server-utils.o: utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-utils.o -MD -MP -MF $(DEPDIR)/ss_server-utils.Tpo -c -o ss_server-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-utils.Tpo $(DEPDIR)/ss_server-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='ss_server-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c + +ss_server-utils.obj: utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-utils.obj -MD -MP -MF $(DEPDIR)/ss_server-utils.Tpo -c -o ss_server-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-utils.Tpo $(DEPDIR)/ss_server-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='ss_server-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` + +ss_server-netutils.o: netutils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-netutils.o -MD -MP -MF $(DEPDIR)/ss_server-netutils.Tpo -c -o ss_server-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-netutils.Tpo $(DEPDIR)/ss_server-netutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_server-netutils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c + +ss_server-netutils.obj: netutils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-netutils.obj -MD -MP -MF $(DEPDIR)/ss_server-netutils.Tpo -c -o ss_server-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-netutils.Tpo $(DEPDIR)/ss_server-netutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_server-netutils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi` + +ss_server-jconf.o: jconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-jconf.o -MD -MP -MF $(DEPDIR)/ss_server-jconf.Tpo -c -o ss_server-jconf.o `test -f 'jconf.c' || echo '$(srcdir)/'`jconf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-jconf.Tpo $(DEPDIR)/ss_server-jconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jconf.c' object='ss_server-jconf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-jconf.o `test -f 'jconf.c' || echo '$(srcdir)/'`jconf.c + +ss_server-jconf.obj: jconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-jconf.obj -MD -MP -MF $(DEPDIR)/ss_server-jconf.Tpo -c -o ss_server-jconf.obj `if test -f 'jconf.c'; then $(CYGPATH_W) 'jconf.c'; else $(CYGPATH_W) '$(srcdir)/jconf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-jconf.Tpo $(DEPDIR)/ss_server-jconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jconf.c' object='ss_server-jconf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-jconf.obj `if test -f 'jconf.c'; then $(CYGPATH_W) 'jconf.c'; else $(CYGPATH_W) '$(srcdir)/jconf.c'; fi` + +ss_server-json.o: json.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-json.o -MD -MP -MF $(DEPDIR)/ss_server-json.Tpo -c -o ss_server-json.o `test -f 'json.c' || echo '$(srcdir)/'`json.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-json.Tpo $(DEPDIR)/ss_server-json.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json.c' object='ss_server-json.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-json.o `test -f 'json.c' || echo '$(srcdir)/'`json.c + +ss_server-json.obj: json.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-json.obj -MD -MP -MF $(DEPDIR)/ss_server-json.Tpo -c -o ss_server-json.obj `if test -f 'json.c'; then $(CYGPATH_W) 'json.c'; else $(CYGPATH_W) '$(srcdir)/json.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-json.Tpo $(DEPDIR)/ss_server-json.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json.c' object='ss_server-json.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-json.obj `if test -f 'json.c'; then $(CYGPATH_W) 'json.c'; else $(CYGPATH_W) '$(srcdir)/json.c'; fi` + +ss_server-encrypt.o: encrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-encrypt.o -MD -MP -MF $(DEPDIR)/ss_server-encrypt.Tpo -c -o ss_server-encrypt.o `test -f 'encrypt.c' || echo '$(srcdir)/'`encrypt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-encrypt.Tpo $(DEPDIR)/ss_server-encrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='encrypt.c' object='ss_server-encrypt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-encrypt.o `test -f 'encrypt.c' || echo '$(srcdir)/'`encrypt.c + +ss_server-encrypt.obj: encrypt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-encrypt.obj -MD -MP -MF $(DEPDIR)/ss_server-encrypt.Tpo -c -o ss_server-encrypt.obj `if test -f 'encrypt.c'; then $(CYGPATH_W) 'encrypt.c'; else $(CYGPATH_W) '$(srcdir)/encrypt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-encrypt.Tpo $(DEPDIR)/ss_server-encrypt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='encrypt.c' object='ss_server-encrypt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-encrypt.obj `if test -f 'encrypt.c'; then $(CYGPATH_W) 'encrypt.c'; else $(CYGPATH_W) '$(srcdir)/encrypt.c'; fi` + +ss_server-udprelay.o: udprelay.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-udprelay.o -MD -MP -MF $(DEPDIR)/ss_server-udprelay.Tpo -c -o ss_server-udprelay.o `test -f 'udprelay.c' || echo '$(srcdir)/'`udprelay.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-udprelay.Tpo $(DEPDIR)/ss_server-udprelay.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='udprelay.c' object='ss_server-udprelay.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-udprelay.o `test -f 'udprelay.c' || echo '$(srcdir)/'`udprelay.c + +ss_server-udprelay.obj: udprelay.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-udprelay.obj -MD -MP -MF $(DEPDIR)/ss_server-udprelay.Tpo -c -o ss_server-udprelay.obj `if test -f 'udprelay.c'; then $(CYGPATH_W) 'udprelay.c'; else $(CYGPATH_W) '$(srcdir)/udprelay.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-udprelay.Tpo $(DEPDIR)/ss_server-udprelay.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='udprelay.c' object='ss_server-udprelay.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-udprelay.obj `if test -f 'udprelay.c'; then $(CYGPATH_W) 'udprelay.c'; else $(CYGPATH_W) '$(srcdir)/udprelay.c'; fi` + +ss_server-cache.o: cache.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-cache.o -MD -MP -MF $(DEPDIR)/ss_server-cache.Tpo -c -o ss_server-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-cache.Tpo $(DEPDIR)/ss_server-cache.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cache.c' object='ss_server-cache.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c + +ss_server-cache.obj: cache.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-cache.obj -MD -MP -MF $(DEPDIR)/ss_server-cache.Tpo -c -o ss_server-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-cache.Tpo $(DEPDIR)/ss_server-cache.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cache.c' object='ss_server-cache.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` + +ss_server-acl.o: acl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-acl.o -MD -MP -MF $(DEPDIR)/ss_server-acl.Tpo -c -o ss_server-acl.o `test -f 'acl.c' || echo '$(srcdir)/'`acl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-acl.Tpo $(DEPDIR)/ss_server-acl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acl.c' object='ss_server-acl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-acl.o `test -f 'acl.c' || echo '$(srcdir)/'`acl.c + +ss_server-acl.obj: acl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-acl.obj -MD -MP -MF $(DEPDIR)/ss_server-acl.Tpo -c -o ss_server-acl.obj `if test -f 'acl.c'; then $(CYGPATH_W) 'acl.c'; else $(CYGPATH_W) '$(srcdir)/acl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-acl.Tpo $(DEPDIR)/ss_server-acl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acl.c' object='ss_server-acl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-acl.obj `if test -f 'acl.c'; then $(CYGPATH_W) 'acl.c'; else $(CYGPATH_W) '$(srcdir)/acl.c'; fi` + +ss_server-resolv.o: resolv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-resolv.o -MD -MP -MF $(DEPDIR)/ss_server-resolv.Tpo -c -o ss_server-resolv.o `test -f 'resolv.c' || echo '$(srcdir)/'`resolv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-resolv.Tpo $(DEPDIR)/ss_server-resolv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='resolv.c' object='ss_server-resolv.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-resolv.o `test -f 'resolv.c' || echo '$(srcdir)/'`resolv.c + +ss_server-resolv.obj: resolv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-resolv.obj -MD -MP -MF $(DEPDIR)/ss_server-resolv.Tpo -c -o ss_server-resolv.obj `if test -f 'resolv.c'; then $(CYGPATH_W) 'resolv.c'; else $(CYGPATH_W) '$(srcdir)/resolv.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-resolv.Tpo $(DEPDIR)/ss_server-resolv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='resolv.c' object='ss_server-resolv.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-resolv.obj `if test -f 'resolv.c'; then $(CYGPATH_W) 'resolv.c'; else $(CYGPATH_W) '$(srcdir)/resolv.c'; fi` + +ss_server-server.o: server.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-server.o -MD -MP -MF $(DEPDIR)/ss_server-server.Tpo -c -o ss_server-server.o `test -f 'server.c' || echo '$(srcdir)/'`server.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-server.Tpo $(DEPDIR)/ss_server-server.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server.c' object='ss_server-server.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-server.o `test -f 'server.c' || echo '$(srcdir)/'`server.c + +ss_server-server.obj: server.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-server.obj -MD -MP -MF $(DEPDIR)/ss_server-server.Tpo -c -o ss_server-server.obj `if test -f 'server.c'; then $(CYGPATH_W) 'server.c'; else $(CYGPATH_W) '$(srcdir)/server.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-server.Tpo $(DEPDIR)/ss_server-server.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='server.c' object='ss_server-server.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-server.obj `if test -f 'server.c'; then $(CYGPATH_W) 'server.c'; else $(CYGPATH_W) '$(srcdir)/server.c'; fi` + +ss_server-http.o: http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.o -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_server-http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c + +ss_server-http.obj: http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.obj -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_server-http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi` + +ss_server-tls.o: tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-tls.o -MD -MP -MF $(DEPDIR)/ss_server-tls.Tpo -c -o ss_server-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-tls.Tpo $(DEPDIR)/ss_server-tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_server-tls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c + +ss_server-tls.obj: tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-tls.obj -MD -MP -MF $(DEPDIR)/ss_server-tls.Tpo -c -o ss_server-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-tls.Tpo $(DEPDIR)/ss_server-tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_server-tls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi` + +ss_server-rule.o: rule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-rule.o -MD -MP -MF $(DEPDIR)/ss_server-rule.Tpo -c -o ss_server-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-rule.Tpo $(DEPDIR)/ss_server-rule.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_server-rule.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c + +ss_server-rule.obj: rule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-rule.obj -MD -MP -MF $(DEPDIR)/ss_server-rule.Tpo -c -o ss_server-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-rule.Tpo $(DEPDIR)/ss_server-rule.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_server-rule.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/shadowsocksr-libev/src/server/README.md b/shadowsocksr-libev/src/server/README.md new file mode 100644 index 00000000..ef6a20e3 --- /dev/null +++ b/shadowsocksr-libev/src/server/README.md @@ -0,0 +1,3 @@ +# server + +`ss-server` and `ss-check` from https://github.com/ywb94/shadowsocks-libev diff --git a/shadowsocksr-libev/src/server/acl.c b/shadowsocksr-libev/src/server/acl.c new file mode 100644 index 00000000..60d4b727 --- /dev/null +++ b/shadowsocksr-libev/src/server/acl.c @@ -0,0 +1,597 @@ +/* + * acl.c - Manage the ACL (Access Control List) + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#include +#include + +#include "rule.h" +#include "utils.h" +#include "cache.h" +#include "acl.h" + +static struct ip_set white_list_ipv4; +static struct ip_set white_list_ipv6; + +static struct ip_set black_list_ipv4; +static struct ip_set black_list_ipv6; + +static struct cork_dllist black_list_rules; +static struct cork_dllist white_list_rules; + +static int acl_mode = BLACK_LIST; + +static struct cache *block_list; + +static struct ip_set outbound_block_list_ipv4; +static struct ip_set outbound_block_list_ipv6; +static struct cork_dllist outbound_block_list_rules; + +#ifdef __linux__ + +#include +#include + +#define NO_FIREWALL_MODE 0 +#define IPTABLES_MODE 1 +#define FIREWALLD_MODE 2 + +static FILE *shell_stdin; +static int mode = NO_FIREWALL_MODE; + +static char chain_name[64]; +static char *iptables_init_chain = + "iptables -N %s; iptables -F %s; iptables -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; +static char *iptables_remove_chain = + "iptables -D OUTPUT -p tcp --tcp-flags RST RST -j %s; iptables -F %s; iptables -X %s"; +static char *iptables_add_rule = "iptables -A %s -d %s -j DROP"; +static char *iptables_remove_rule = "iptables -D %s -d %s -j DROP"; + +static char *ip6tables_init_chain = + "ip6tables -N %s; ip6tables -F %s; ip6tables -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; +static char *ip6tables_remove_chain = + "ip6tables -D OUTPUT -p tcp --tcp-flags RST RST -j %s; ip6tables -F %s; ip6tables -X %s"; +static char *ip6tables_add_rule = "ip6tables -A %s -d %s -j DROP"; +static char *ip6tables_remove_rule = "ip6tables -D %s -d %s -j DROP"; + +static char *firewalld_init_chain = + "firewall-cmd --direct --add-chain ipv4 filter %s; \ + firewall-cmd --direct --passthrough ipv4 -F %s; \ + firewall-cmd --direct --passthrough ipv4 -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; +static char *firewalld_remove_chain = + "firewall-cmd --direct --passthrough ipv4 -D OUTPUT -p tcp --tcp-flags RST RST -j %s; \ + firewall-cmd --direct --passthrough ipv4 -F %s; \ + firewall-cmd --direct --remove-chain ipv4 filter %s"; +static char *firewalld_add_rule = "firewall-cmd --direct --passthrough ipv4 -A %s -d %s -j DROP"; +static char *firewalld_remove_rule = "firewall-cmd --direct --passthrough ipv4 -D %s -d %s -j DROP"; + +static char *firewalld6_init_chain = + "firewall-cmd --direct --add-chain ipv6 filter %s; \ + firewall-cmd --direct --passthrough ipv6 -F %s; \ + firewall-cmd --direct --passthrough ipv6 -A OUTPUT -p tcp --tcp-flags RST RST -j %s"; +static char *firewalld6_remove_chain = + "firewall-cmd --direct --passthrough ipv6 -D OUTPUT -p tcp --tcp-flags RST RST -j %s; \ + firewall-cmd --direct --passthrough ipv6 -F %s; \ + firewall-cmd --direct --remove-chain ipv6 filter %s"; +static char *firewalld6_add_rule = "firewall-cmd --direct --passthrough ipv6 -A %s -d %s -j DROP"; +static char *firewalld6_remove_rule = "firewall-cmd --direct --passthrough ipv6 -D %s -d %s -j DROP"; + +static int +run_cmd(const char *cmd) +{ + int ret = 0; + char cmdstring[256]; + + sprintf(cmdstring, "%s\n", cmd); + size_t len = strlen(cmdstring); + + if (shell_stdin != NULL) { + ret = fwrite(cmdstring, 1, len, shell_stdin); + fflush(shell_stdin); + } + + return ret == len; +} + +static int +init_firewall() +{ + int ret = 0; + char cli[256]; + FILE *fp; + + if (getuid() != 0) + return -1; + + sprintf(cli, "firewall-cmd --version 2>&1"); + fp = popen(cli, "r"); + + if (fp == NULL) + return -1; + + if (pclose(fp) == 0) { + mode = FIREWALLD_MODE; + } else { + /* Check whether we have permission to operate iptables. + * Note that checking `iptables --version` is insufficient: + * eg, running within a child user namespace. + */ + sprintf(cli, "iptables -L 2>&1"); + fp = popen(cli, "r"); + if (fp == NULL) + return -1; + if (pclose(fp) == 0) + mode = IPTABLES_MODE; + } + + sprintf(chain_name, "SHADOWSOCKS_LIBEV_%d", getpid()); + + if (mode == FIREWALLD_MODE) { + sprintf(cli, firewalld6_init_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + sprintf(cli, firewalld_init_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + } else if (mode == IPTABLES_MODE) { + sprintf(cli, ip6tables_init_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + sprintf(cli, iptables_init_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + } + + shell_stdin = popen("/bin/sh", "w"); + + return ret; +} + +static int +reset_firewall() +{ + int ret = 0; + char cli[256]; + + if (getuid() != 0) + return -1; + + if (mode == IPTABLES_MODE) { + sprintf(cli, ip6tables_remove_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + sprintf(cli, iptables_remove_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + } else if (mode == FIREWALLD_MODE) { + sprintf(cli, firewalld6_remove_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + sprintf(cli, firewalld_remove_chain, chain_name, chain_name, chain_name); + ret |= system(cli); + } + + if (shell_stdin != NULL) { + run_cmd("exit 0"); + pclose(shell_stdin); + } + + return ret; +} + +static int +set_firewall_rule(char *addr, int add) +{ + char cli[256]; + struct cork_ip ip; + + if (getuid() != 0) + return -1; + + if (cork_ip_init(&ip, addr)) + return -1; + + if (add) { + if (mode == IPTABLES_MODE) + sprintf(cli, ip.version == 4 ? iptables_add_rule : ip6tables_add_rule, + chain_name, addr); + else if (mode == FIREWALLD_MODE) + sprintf(cli, ip.version == 4 ? firewalld_add_rule : firewalld6_add_rule, + chain_name, addr); + return run_cmd(cli); + } else { + if (mode == IPTABLES_MODE) + sprintf(cli, ip.version == 4 ? iptables_remove_rule : ip6tables_remove_rule, + chain_name, addr); + else if (mode == FIREWALLD_MODE) + sprintf(cli, ip.version == 4 ? firewalld_remove_rule : firewalld6_remove_rule, + chain_name, addr); + return run_cmd(cli); + } + + return 0; +} + +static void +free_firewall_rule(void *key, void *element) +{ + if (key == NULL) + return; + char *addr = (char *)key; + set_firewall_rule(addr, 0); + ss_free(element); +} + +#endif + +void +init_block_list(int firewall) +{ + // Initialize cache +#ifdef __linux__ + if (firewall) + init_firewall(); + else + mode = NO_FIREWALL_MODE; + cache_create(&block_list, 256, free_firewall_rule); +#else + cache_create(&block_list, 256, NULL); +#endif +} + +void +free_block_list() +{ +#ifdef __linux__ + if (mode != NO_FIREWALL_MODE) + reset_firewall(); +#endif + cache_clear(block_list, 0); // Remove all items +} + +int +remove_from_block_list(char *addr) +{ + size_t addr_len = strlen(addr); + return cache_remove(block_list, addr, addr_len); +} + +void +clear_block_list() +{ + cache_clear(block_list, 3600); // Clear items older than 1 hour +} + +int +check_block_list(char *addr) +{ + size_t addr_len = strlen(addr); + + if (cache_key_exist(block_list, addr, addr_len)) { + int *count = NULL; + cache_lookup(block_list, addr, addr_len, &count); + + if (count != NULL && *count > MAX_TRIES) + return 1; + } + + return 0; +} + +int +update_block_list(char *addr, int err_level) +{ + size_t addr_len = strlen(addr); + + if (cache_key_exist(block_list, addr, addr_len)) { + int *count = NULL; + cache_lookup(block_list, addr, addr_len, &count); + if (count != NULL) { + if (*count > MAX_TRIES) + return 1; + (*count) += err_level; + } + } else if (err_level > 0) { + int *count = (int *)ss_malloc(sizeof(int)); + *count = 1; + cache_insert(block_list, addr, addr_len, count); +#ifdef __linux__ + if (mode != NO_FIREWALL_MODE) + set_firewall_rule(addr, 1); +#endif + } + + return 0; +} + +static void +parse_addr_cidr(const char *str, char *host, int *cidr) +{ + int ret = -1, n = 0; + char *pch; + + pch = strchr(str, '/'); + while (pch != NULL) { + n++; + ret = pch - str; + pch = strchr(pch + 1, '/'); + } + if (ret == -1) { + strcpy(host, str); + *cidr = -1; + } else { + memcpy(host, str, ret); + host[ret] = '\0'; + *cidr = atoi(str + ret + 1); + } +} + +char * +trimwhitespace(char *str) +{ + char *end; + + // Trim leading space + while (isspace(*str)) + str++; + + if (*str == 0) // All spaces? + return str; + + // Trim trailing space + end = str + strlen(str) - 1; + while (end > str && isspace(*end)) + end--; + + // Write new null terminator + *(end + 1) = 0; + + return str; +} + +int +init_acl(const char *path) +{ + // initialize ipset + ipset_init_library(); + + ipset_init(&white_list_ipv4); + ipset_init(&white_list_ipv6); + ipset_init(&black_list_ipv4); + ipset_init(&black_list_ipv6); + ipset_init(&outbound_block_list_ipv4); + ipset_init(&outbound_block_list_ipv6); + + cork_dllist_init(&black_list_rules); + cork_dllist_init(&white_list_rules); + cork_dllist_init(&outbound_block_list_rules); + + struct ip_set *list_ipv4 = &black_list_ipv4; + struct ip_set *list_ipv6 = &black_list_ipv6; + struct cork_dllist *rules = &black_list_rules; + + FILE *f = fopen(path, "r"); + if (f == NULL) { + LOGE("Invalid acl path."); + return -1; + } + + char buf[257]; + while (!feof(f)) + if (fgets(buf, 256, f)) { + // Trim the newline + int len = strlen(buf); + if (len > 0 && buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } + + char *line = trimwhitespace(buf); + + // Skip comments + if (line[0] == '#') { + continue; + } + + if (strlen(line) == 0) { + continue; + } + + if (strcmp(line, "[outbound_block_list]") == 0) { + list_ipv4 = &outbound_block_list_ipv4; + list_ipv6 = &outbound_block_list_ipv6; + rules = &outbound_block_list_rules; + continue; + } else if (strcmp(line, "[black_list]") == 0 + || strcmp(line, "[bypass_list]") == 0) { + list_ipv4 = &black_list_ipv4; + list_ipv6 = &black_list_ipv6; + rules = &black_list_rules; + continue; + } else if (strcmp(line, "[white_list]") == 0 + || strcmp(line, "[proxy_list]") == 0) { + list_ipv4 = &white_list_ipv4; + list_ipv6 = &white_list_ipv6; + rules = &white_list_rules; + continue; + } else if (strcmp(line, "[reject_all]") == 0 + || strcmp(line, "[bypass_all]") == 0) { + acl_mode = WHITE_LIST; + continue; + } else if (strcmp(line, "[accept_all]") == 0 + || strcmp(line, "[proxy_all]") == 0) { + acl_mode = BLACK_LIST; + continue; + } + + char host[257]; + int cidr; + parse_addr_cidr(line, host, &cidr); + + struct cork_ip addr; + int err = cork_ip_init(&addr, host); + if (!err) { + if (addr.version == 4) { + if (cidr >= 0) { + ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr); + } else { + ipset_ipv4_add(list_ipv4, &(addr.ip.v4)); + } + } else if (addr.version == 6) { + if (cidr >= 0) { + ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr); + } else { + ipset_ipv6_add(list_ipv6, &(addr.ip.v6)); + } + } + } else { + rule_t *rule = new_rule(); + accept_rule_arg(rule, line); + init_rule(rule); + add_rule(rules, rule); + } + } + + fclose(f); + + return 0; +} + +void +free_rules(struct cork_dllist *rules) +{ + struct cork_dllist_item *iter; + while ((iter = cork_dllist_head(rules)) != NULL) { + rule_t *rule = cork_container_of(iter, rule_t, entries); + remove_rule(rule); + } +} + +void +free_acl(void) +{ + ipset_done(&black_list_ipv4); + ipset_done(&black_list_ipv6); + ipset_done(&white_list_ipv4); + ipset_done(&white_list_ipv6); + + free_rules(&black_list_rules); + free_rules(&white_list_rules); +} + +int +get_acl_mode(void) +{ + return acl_mode; +} + +/* + * Return 0, if not match. + * Return 1, if match black list. + * Return -1, if match white list. + */ +int +acl_match_host(const char *host) +{ + struct cork_ip addr; + int ret = 0; + int err = cork_ip_init(&addr, host); + + if (err) { + int host_len = strlen(host); + if (lookup_rule(&black_list_rules, host, host_len) != NULL) + ret = 1; + else if (lookup_rule(&white_list_rules, host, host_len) != NULL) + ret = -1; + return ret; + } + + if (addr.version == 4) { + if (ipset_contains_ipv4(&black_list_ipv4, &(addr.ip.v4))) + ret = 1; + else if (ipset_contains_ipv4(&white_list_ipv4, &(addr.ip.v4))) + ret = -1; + } else if (addr.version == 6) { + if (ipset_contains_ipv6(&black_list_ipv6, &(addr.ip.v6))) + ret = 1; + else if (ipset_contains_ipv6(&white_list_ipv6, &(addr.ip.v6))) + ret = -1; + } + + return ret; +} + +int +acl_add_ip(const char *ip) +{ + struct cork_ip addr; + int err = cork_ip_init(&addr, ip); + if (err) { + return -1; + } + + if (addr.version == 4) { + ipset_ipv4_add(&black_list_ipv4, &(addr.ip.v4)); + } else if (addr.version == 6) { + ipset_ipv6_add(&black_list_ipv6, &(addr.ip.v6)); + } + + return 0; +} + +int +acl_remove_ip(const char *ip) +{ + struct cork_ip addr; + int err = cork_ip_init(&addr, ip); + if (err) { + return -1; + } + + if (addr.version == 4) { + ipset_ipv4_remove(&black_list_ipv4, &(addr.ip.v4)); + } else if (addr.version == 6) { + ipset_ipv6_remove(&black_list_ipv6, &(addr.ip.v6)); + } + + return 0; +} + +/* + * Return 0, if not match. + * Return 1, if match black list. + */ +int +outbound_block_match_host(const char *host) +{ + struct cork_ip addr; + int ret = 0; + int err = cork_ip_init(&addr, host); + + if (err) { + int host_len = strlen(host); + if (lookup_rule(&outbound_block_list_rules, host, host_len) != NULL) + ret = 1; + return ret; + } + + if (addr.version == 4) { + if (ipset_contains_ipv4(&outbound_block_list_ipv4, &(addr.ip.v4))) + ret = 1; + } else if (addr.version == 6) { + if (ipset_contains_ipv6(&outbound_block_list_ipv6, &(addr.ip.v6))) + ret = 1; + } + + return ret; +} diff --git a/shadowsocksr-libev/src/server/acl.h b/shadowsocksr-libev/src/server/acl.h new file mode 100644 index 00000000..d6f18b80 --- /dev/null +++ b/shadowsocksr-libev/src/server/acl.h @@ -0,0 +1,53 @@ +/* + * acl.h - Define the ACL interface + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _ACL_H +#define _ACL_H + +#define BLACK_LIST 0 +#define WHITE_LIST 1 + +#define MAX_TRIES 64 +#define MALICIOUS 8 +#define SUSPICIOUS 4 +#define BAD 2 +#define MALFORMED 1 + +int init_acl(const char *path); +void free_acl(void); +void clear_block_list(void); + +int acl_match_host(const char *ip); +int acl_add_ip(const char *ip); +int acl_remove_ip(const char *ip); + +int get_acl_mode(void); + +void init_block_list(int firewall); +void free_block_list(); +int check_block_list(char *addr); +int update_block_list(char *addr, int err_level); +int remove_from_block_list(char *addr); + +int outbound_block_match_host(const char *host); + +#endif // _ACL_H diff --git a/shadowsocksr-libev/src/server/auth.c b/shadowsocksr-libev/src/server/auth.c new file mode 100644 index 00000000..a36257a9 --- /dev/null +++ b/shadowsocksr-libev/src/server/auth.c @@ -0,0 +1,993 @@ + +#include "auth.h" + +static int auth_simple_pack_unit_size = 2000; +typedef int (*hmac_with_key_func)(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len); +typedef int (*hash_func)(char *auth, char *msg, int msg_len); + +typedef struct auth_simple_global_data { + uint8_t local_client_id[8]; + uint32_t connection_id; +}auth_simple_global_data; + +typedef struct auth_simple_local_data { + int has_sent_header; + char * recv_buffer; + int recv_buffer_size; + uint32_t recv_id; + uint32_t pack_id; + char * salt; + uint8_t * user_key; + char uid[4]; + int user_key_len; + hmac_with_key_func hmac; + hash_func hash; + int hash_len; +}auth_simple_local_data; + +void auth_simple_local_data_init(auth_simple_local_data* local) { + local->has_sent_header = 0; + local->recv_buffer = (char*)malloc(16384); + local->recv_buffer_size = 0; + local->recv_id = 1; + local->pack_id = 1; + local->salt = ""; + local->user_key = 0; + local->user_key_len = 0; + local->hmac = 0; + local->hash = 0; + local->hash_len = 0; + local->salt = ""; +} + +void * auth_simple_init_data() { + auth_simple_global_data *global = (auth_simple_global_data*)malloc(sizeof(auth_simple_global_data)); + rand_bytes(global->local_client_id, 8); + rand_bytes((uint8_t*)&global->connection_id, 4); + global->connection_id &= 0xFFFFFF; + return global; +} + +obfs * auth_simple_new_obfs() { + obfs * self = new_obfs(); + self->l_data = malloc(sizeof(auth_simple_local_data)); + auth_simple_local_data_init((auth_simple_local_data*)self->l_data); + return self; +} + +obfs * auth_aes128_md5_new_obfs() { + obfs * self = new_obfs(); + self->l_data = malloc(sizeof(auth_simple_local_data)); + auth_simple_local_data_init((auth_simple_local_data*)self->l_data); + ((auth_simple_local_data*)self->l_data)->hmac = ss_md5_hmac_with_key; + ((auth_simple_local_data*)self->l_data)->hash = ss_md5_hash_func; + ((auth_simple_local_data*)self->l_data)->hash_len = 16; + ((auth_simple_local_data*)self->l_data)->salt = "auth_aes128_md5"; + return self; +} + +obfs * auth_aes128_sha1_new_obfs() { + obfs * self = new_obfs(); + self->l_data = malloc(sizeof(auth_simple_local_data)); + auth_simple_local_data_init((auth_simple_local_data*)self->l_data); + ((auth_simple_local_data*)self->l_data)->hmac = ss_sha1_hmac_with_key; + ((auth_simple_local_data*)self->l_data)->hash = ss_sha1_hash_func; + ((auth_simple_local_data*)self->l_data)->hash_len = 20; + ((auth_simple_local_data*)self->l_data)->salt = "auth_aes128_sha1"; + return self; +} + +void auth_simple_dispose(obfs *self) { + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + if (local->recv_buffer != NULL) { + free(local->recv_buffer); + local->recv_buffer = NULL; + } + if (local->user_key != NULL) { + free(local->user_key); + local->user_key = NULL; + } + free(local); + self->l_data = NULL; + dispose_obfs(self); +} + +int auth_simple_pack_data(char *data, int datalength, char *outdata) { + unsigned char rand_len = (xorshift128plus() & 0xF) + 1; + int out_size = rand_len + datalength + 6; + outdata[0] = out_size >> 8; + outdata[1] = out_size; + outdata[2] = rand_len; + memmove(outdata + rand_len + 2, data, datalength); + fillcrc32((unsigned char *)outdata, out_size); + return out_size; +} + +void memintcopy_lt(void *mem, uint32_t val) { + ((uint8_t *)mem)[0] = val; + ((uint8_t *)mem)[1] = val >> 8; + ((uint8_t *)mem)[2] = val >> 16; + ((uint8_t *)mem)[3] = val >> 24; +} + +int auth_simple_pack_auth_data(auth_simple_global_data *global, char *data, int datalength, char *outdata) { + unsigned char rand_len = (xorshift128plus() & 0xF) + 1; + int out_size = rand_len + datalength + 6 + 12; + outdata[0] = out_size >> 8; + outdata[1] = out_size; + outdata[2] = rand_len; + ++global->connection_id; + if (global->connection_id > 0xFF000000) { + rand_bytes(global->local_client_id, 8); + rand_bytes((uint8_t*)&global->connection_id, 4); + global->connection_id &= 0xFFFFFF; + } + time_t t = time(NULL); + memintcopy_lt(outdata + rand_len + 2, t); + memmove(outdata + rand_len + 2 + 4, global->local_client_id, 4); + memintcopy_lt(outdata + rand_len + 2 + 8, global->connection_id); + memmove(outdata + rand_len + 2 + 12, data, datalength); + fillcrc32((unsigned char *)outdata, out_size); + return out_size; +} + +int auth_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 64); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + if (len > 0 && local->has_sent_header == 0) { + int head_size = get_head_size(plaindata, datalength, 30); + if (head_size > datalength) + head_size = datalength; + pack_len = auth_simple_pack_auth_data((auth_simple_global_data *)self->server.g_data, data, head_size, buffer); + buffer += pack_len; + data += head_size; + len -= head_size; + local->has_sent_header = 1; + } + while ( len > auth_simple_pack_unit_size ) { + pack_len = auth_simple_pack_data(data, auth_simple_pack_unit_size, buffer); + buffer += pack_len; + data += auth_simple_pack_unit_size; + len -= auth_simple_pack_unit_size; + } + if (len > 0) { + pack_len = auth_simple_pack_data(data, len, buffer); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int auth_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + return -1; + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + while (local->recv_buffer_size > 2) { + int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; + if (length >= 8192 || length < 7) { + free(out_buffer); + local->recv_buffer_size = 0; + return -1; + } + if (length > local->recv_buffer_size) + break; + + int crc = crc32((unsigned char*)recv_buffer, length); + if (crc != -1) { + free(out_buffer); + local->recv_buffer_size = 0; + return -1; + } + int data_size = length - recv_buffer[2] - 6; + memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + + +int auth_sha1_pack_data(char *data, int datalength, char *outdata) { + unsigned char rand_len = (xorshift128plus() & 0xF) + 1; + int out_size = rand_len + datalength + 6; + outdata[0] = out_size >> 8; + outdata[1] = out_size; + outdata[2] = rand_len; + memmove(outdata + rand_len + 2, data, datalength); + filladler32((unsigned char *)outdata, out_size); + return out_size; +} + +int auth_sha1_pack_auth_data(auth_simple_global_data *global, server_info *server, char *data, int datalength, char *outdata) { + unsigned char rand_len = (xorshift128plus() & 0x7F) + 1; + int data_offset = rand_len + 4 + 2; + int out_size = data_offset + datalength + 12 + OBFS_HMAC_SHA1_LEN; + fillcrc32to((unsigned char *)server->key, server->key_len, (unsigned char *)outdata); + outdata[4] = out_size >> 8; + outdata[5] = out_size; + outdata[6] = rand_len; + ++global->connection_id; + if (global->connection_id > 0xFF000000) { + rand_bytes(global->local_client_id, 8); + rand_bytes((uint8_t*)&global->connection_id, 4); + global->connection_id &= 0xFFFFFF; + } + time_t t = time(NULL); + memintcopy_lt(outdata + data_offset, t); + memmove(outdata + data_offset + 4, global->local_client_id, 4); + memintcopy_lt(outdata + data_offset + 8, global->connection_id); + memmove(outdata + data_offset + 12, data, datalength); + char hash[ONETIMEAUTH_BYTES * 2]; + ss_sha1_hmac(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, server->iv); + memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); + return out_size; +} + +int auth_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 256); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + if (len > 0 && local->has_sent_header == 0) { + int head_size = get_head_size(plaindata, datalength, 30); + if (head_size > datalength) + head_size = datalength; + pack_len = auth_sha1_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, data, head_size, buffer); + buffer += pack_len; + data += head_size; + len -= head_size; + local->has_sent_header = 1; + } + while ( len > auth_simple_pack_unit_size ) { + pack_len = auth_sha1_pack_data(data, auth_simple_pack_unit_size, buffer); + buffer += pack_len; + data += auth_simple_pack_unit_size; + len -= auth_simple_pack_unit_size; + } + if (len > 0) { + pack_len = auth_sha1_pack_data(data, len, buffer); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int auth_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + return -1; + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + while (local->recv_buffer_size > 2) { + int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; + if (length >= 8192 || length < 7) { + free(out_buffer); + local->recv_buffer_size = 0; + return -1; + } + if (length > local->recv_buffer_size) + break; + + if (checkadler32((unsigned char*)recv_buffer, length) == 0) { + free(out_buffer); + local->recv_buffer_size = 0; + return -1; + } + int pos = recv_buffer[2] + 2; + int data_size = length - pos - 4; + memmove(buffer, recv_buffer + pos, data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int auth_sha1_v2_pack_data(char *data, int datalength, char *outdata) { + unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; + int out_size = rand_len + datalength + 6; + outdata[0] = out_size >> 8; + outdata[1] = out_size; + if (rand_len < 128) + { + outdata[2] = rand_len; + } + else + { + outdata[2] = 0xFF; + outdata[3] = rand_len >> 8; + outdata[4] = rand_len; + } + memmove(outdata + rand_len + 2, data, datalength); + filladler32((unsigned char *)outdata, out_size); + return out_size; +} + +int auth_sha1_v2_pack_auth_data(auth_simple_global_data *global, server_info *server, char *data, int datalength, char *outdata) { + unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; + int data_offset = rand_len + 4 + 2; + int out_size = data_offset + datalength + 12 + OBFS_HMAC_SHA1_LEN; + const char* salt = "auth_sha1_v2"; + int salt_len = strlen(salt); + unsigned char *crc_salt = (unsigned char*)malloc(salt_len + server->key_len); + memcpy(crc_salt, salt, salt_len); + memcpy(crc_salt + salt_len, server->key, server->key_len); + fillcrc32to(crc_salt, salt_len + server->key_len, (unsigned char *)outdata); + free(crc_salt); + outdata[4] = out_size >> 8; + outdata[5] = out_size; + if (rand_len < 128) + { + outdata[6] = rand_len; + } + else + { + outdata[6] = 0xFF; + outdata[7] = rand_len >> 8; + outdata[8] = rand_len; + } + ++global->connection_id; + if (global->connection_id > 0xFF000000) { + rand_bytes(global->local_client_id, 8); + rand_bytes((uint8_t*)&global->connection_id, 4); + global->connection_id &= 0xFFFFFF; + } + memmove(outdata + data_offset, global->local_client_id, 8); + memintcopy_lt(outdata + data_offset + 8, global->connection_id); + memmove(outdata + data_offset + 12, data, datalength); + char hash[ONETIMEAUTH_BYTES * 2]; + ss_sha1_hmac(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, server->iv); + memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); + return out_size; +} + +int auth_sha1_v2_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 4096); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + if (len > 0 && local->has_sent_header == 0) { + int head_size = get_head_size(plaindata, datalength, 30); + if (head_size > datalength) + head_size = datalength; + pack_len = auth_sha1_v2_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, data, head_size, buffer); + buffer += pack_len; + data += head_size; + len -= head_size; + local->has_sent_header = 1; + } + while ( len > auth_simple_pack_unit_size ) { + pack_len = auth_sha1_v2_pack_data(data, auth_simple_pack_unit_size, buffer); + buffer += pack_len; + data += auth_simple_pack_unit_size; + len -= auth_simple_pack_unit_size; + } + if (len > 0) { + pack_len = auth_sha1_v2_pack_data(data, len, buffer); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int auth_sha1_v2_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + return -1; + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + char error = 0; + while (local->recv_buffer_size > 2) { + int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; + if (length >= 8192 || length < 7) { + local->recv_buffer_size = 0; + error = 1; + break; + } + if (length > local->recv_buffer_size) + break; + + if (checkadler32((unsigned char*)recv_buffer, length) == 0) { + local->recv_buffer_size = 0; + error = 1; + break; + } + int pos = recv_buffer[2]; + if (pos < 255) + { + pos += 2; + } + else + { + pos = ((recv_buffer[3] << 8) | recv_buffer[4]) + 2; + } + int data_size = length - pos - 4; + memmove(buffer, recv_buffer + pos, data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len; + if (error == 0) { + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + } else { + len = -1; + } + free(out_buffer); + return len; +} + +int auth_sha1_v4_pack_data(char *data, int datalength, char *outdata) { + unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; + int out_size = rand_len + datalength + 8; + outdata[0] = out_size >> 8; + outdata[1] = out_size; + uint32_t crc_val = crc32((unsigned char*)outdata, 2); + outdata[2] = crc_val; + outdata[3] = crc_val >> 8; + if (rand_len < 128) + { + outdata[4] = rand_len; + } + else + { + outdata[4] = 0xFF; + outdata[5] = rand_len >> 8; + outdata[6] = rand_len; + } + memmove(outdata + rand_len + 4, data, datalength); + filladler32((unsigned char *)outdata, out_size); + return out_size; +} + +int auth_sha1_v4_pack_auth_data(auth_simple_global_data *global, server_info *server, char *data, int datalength, char *outdata) { + unsigned int rand_len = (datalength > 1300 ? 0 : datalength > 400 ? (xorshift128plus() & 0x7F) : (xorshift128plus() & 0x3FF)) + 1; + int data_offset = rand_len + 4 + 2; + int out_size = data_offset + datalength + 12 + OBFS_HMAC_SHA1_LEN; + const char* salt = "auth_sha1_v4"; + int salt_len = strlen(salt); + unsigned char *crc_salt = (unsigned char*)malloc(salt_len + server->key_len + 2); + crc_salt[0] = outdata[0] = out_size >> 8; + crc_salt[1] = outdata[1] = out_size; + + memcpy(crc_salt + 2, salt, salt_len); + memcpy(crc_salt + salt_len + 2, server->key, server->key_len); + fillcrc32to(crc_salt, salt_len + server->key_len + 2, (unsigned char *)outdata + 2); + free(crc_salt); + if (rand_len < 128) + { + outdata[6] = rand_len; + } + else + { + outdata[6] = 0xFF; + outdata[7] = rand_len >> 8; + outdata[8] = rand_len; + } + ++global->connection_id; + if (global->connection_id > 0xFF000000) { + rand_bytes(global->local_client_id, 8); + rand_bytes((uint8_t*)&global->connection_id, 4); + global->connection_id &= 0xFFFFFF; + } + time_t t = time(NULL); + memintcopy_lt(outdata + data_offset, t); + memmove(outdata + data_offset + 4, global->local_client_id, 4); + memintcopy_lt(outdata + data_offset + 8, global->connection_id); + memmove(outdata + data_offset + 12, data, datalength); + char hash[ONETIMEAUTH_BYTES * 2]; + ss_sha1_hmac(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, server->iv); + memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); + return out_size; +} + +int auth_sha1_v4_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 4096); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + if (len > 0 && local->has_sent_header == 0) { + int head_size = get_head_size(plaindata, datalength, 30); + if (head_size > datalength) + head_size = datalength; + pack_len = auth_sha1_v4_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, data, head_size, buffer); + buffer += pack_len; + data += head_size; + len -= head_size; + local->has_sent_header = 1; + } + while ( len > auth_simple_pack_unit_size ) { + pack_len = auth_sha1_v4_pack_data(data, auth_simple_pack_unit_size, buffer); + buffer += pack_len; + data += auth_simple_pack_unit_size; + len -= auth_simple_pack_unit_size; + } + if (len > 0) { + pack_len = auth_sha1_v4_pack_data(data, len, buffer); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int auth_sha1_v4_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + return -1; + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + char error = 0; + while (local->recv_buffer_size > 4) { + uint32_t crc_val = crc32((unsigned char*)recv_buffer, 2); + if ((((uint32_t)recv_buffer[3] << 8) | recv_buffer[2]) != (crc_val & 0xffff)) { + local->recv_buffer_size = 0; + error = 1; + break; + } + int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; + if (length >= 8192 || length < 7) { + local->recv_buffer_size = 0; + error = 1; + break; + } + if (length > local->recv_buffer_size) + break; + + if (checkadler32((unsigned char*)recv_buffer, length) == 0) { + local->recv_buffer_size = 0; + error = 1; + break; + } + int pos = recv_buffer[4]; + if (pos < 255) + { + pos += 4; + } + else + { + pos = (((int)recv_buffer[5] << 8) | recv_buffer[6]) + 4; + } + int data_size = length - pos - 4; + memmove(buffer, recv_buffer + pos, data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len; + if (error == 0) { + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + } else { + len = -1; + } + free(out_buffer); + return len; +} + + +int auth_aes128_sha1_pack_data(char *data, int datalength, char *outdata, auth_simple_local_data *local, server_info *server) { + unsigned int rand_len = (datalength > 1200 ? 0 : local->pack_id > 4 ? (xorshift128plus() & 0x20) : datalength > 900 ? (xorshift128plus() & 0x80) : (xorshift128plus() & 0x200)) + 1; + int out_size = rand_len + datalength + 8; + memcpy(outdata + rand_len + 4, data, datalength); + outdata[0] = out_size; + outdata[1] = out_size >> 8; + uint8_t key_len = local->user_key_len + 4; + uint8_t *key = (uint8_t*)malloc(key_len); + memcpy(key, local->user_key, local->user_key_len); + memintcopy_lt(key + key_len - 4, local->pack_id); + + { + uint8_t rnd_data[rand_len]; + rand_bytes(rnd_data, rand_len); + memcpy(outdata + 4, rnd_data, rand_len); + } + + { + char hash[20]; + local->hmac(hash, outdata, 2, key, key_len); + memcpy(outdata + 2, hash, 2); + } + + if (rand_len < 128) + { + outdata[4] = rand_len; + } + else + { + outdata[4] = 0xFF; + outdata[5] = rand_len; + outdata[6] = rand_len >> 8; + } + ++local->pack_id; + + { + char hash[20]; + local->hmac(hash, outdata, out_size - 4, key, key_len); + memcpy(outdata + out_size - 4, hash, 4); + } + free(key); + + return out_size; +} + +int auth_aes128_sha1_pack_auth_data(auth_simple_global_data *global, server_info *server, auth_simple_local_data *local, char *data, int datalength, char *outdata) { + unsigned int rand_len = (datalength > 400 ? (xorshift128plus() & 0x200) : (xorshift128plus() & 0x400)); + int data_offset = rand_len + 16 + 4 + 4 + 7; + int out_size = data_offset + datalength + 4; + + char encrypt[24]; + char encrypt_data[16]; + + uint8_t *key = (uint8_t*)malloc(server->iv_len + server->key_len); + uint8_t key_len = server->iv_len + server->key_len; + memcpy(key, server->iv, server->iv_len); + memcpy(key + server->iv_len, server->key, server->key_len); + + { + uint8_t rnd_data[rand_len]; + rand_bytes(rnd_data, rand_len); + memcpy(outdata + data_offset - rand_len, rnd_data, rand_len); + } + + ++global->connection_id; + if (global->connection_id > 0xFF000000) { + rand_bytes(global->local_client_id, 8); + rand_bytes((uint8_t*)&global->connection_id, 4); + global->connection_id &= 0xFFFFFF; + } + time_t t = time(NULL); + memintcopy_lt(encrypt, t); + memcpy(encrypt + 4, global->local_client_id, 4); + memintcopy_lt(encrypt + 8, global->connection_id); + encrypt[12] = out_size; + encrypt[13] = out_size >> 8; + encrypt[14] = rand_len; + encrypt[15] = rand_len >> 8; + + { + + if (local->user_key == NULL) { + if(server->param != NULL && server->param[0] != 0) { + char *param = server->param; + char *delim = strchr(param, ':'); + if(delim != NULL) { + char uid_str[16] = {}; + strncpy(uid_str, param, delim - param); + char key_str[128]; + strcpy(key_str, delim + 1); + long uid_long = strtol(uid_str, NULL, 10); + memintcopy_lt(local->uid, uid_long); + + char hash[21] = {0}; + local->hash(hash, key_str, strlen(key_str)); + + local->user_key_len = local->hash_len; + local->user_key = (uint8_t*)malloc(local->user_key_len); + memcpy(local->user_key, hash, local->hash_len); + } + } + if (local->user_key == NULL) { + rand_bytes((uint8_t *)local->uid, 4); + + local->user_key_len = server->key_len; + local->user_key = (uint8_t*)malloc(local->user_key_len); + memcpy(local->user_key, server->key, local->user_key_len); + } + } + + char encrypt_key_base64[256] = {0}; + unsigned char encrypt_key[local->user_key_len]; + memcpy(encrypt_key, local->user_key, local->user_key_len); + base64_encode(encrypt_key, local->user_key_len, encrypt_key_base64); + + int base64_len; + base64_len = (local->user_key_len + 2) / 3 * 4; + memcpy(encrypt_key_base64 + base64_len, local->salt, strlen(local->salt)); + + char enc_key[16]; + int enc_key_len = base64_len + strlen(local->salt); + bytes_to_key_with_size(encrypt_key_base64, enc_key_len, (uint8_t*)enc_key, 16); + ss_aes_128_cbc(encrypt, encrypt_data, enc_key); + memcpy(encrypt + 4, encrypt_data, 16); + memcpy(encrypt, local->uid, 4); + } + + { + char hash[20]; + local->hmac(hash, encrypt, 20, key, key_len); + memcpy(encrypt + 20, hash, 4); + } + + { + uint8_t rnd[1]; + rand_bytes(rnd, 1); + memcpy(outdata, rnd, 1); + char hash[20]; + local->hmac(hash, (char *)rnd, 1, key, key_len); + memcpy(outdata + 1, hash, 6); + } + + memcpy(outdata + 7, encrypt, 24); + memcpy(outdata + data_offset, data, datalength); + + { + char hash[20]; + local->hmac(hash, outdata, out_size - 4, local->user_key, local->user_key_len); + memmove(outdata + out_size - 4, hash, 4); + } + free(key); + + return out_size; +} + +int auth_aes128_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 4096); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + if (len > 0 && local->has_sent_header == 0) { + int head_size = 1200; + if (head_size > datalength) + head_size = datalength; + pack_len = auth_aes128_sha1_pack_auth_data((auth_simple_global_data *)self->server.g_data, &self->server, local, data, head_size, buffer); + buffer += pack_len; + data += head_size; + len -= head_size; + local->has_sent_header = 1; + } + while ( len > auth_simple_pack_unit_size ) { + pack_len = auth_aes128_sha1_pack_data(data, auth_simple_pack_unit_size, buffer, local, &self->server); + buffer += pack_len; + data += auth_simple_pack_unit_size; + len -= auth_simple_pack_unit_size; + } + if (len > 0) { + pack_len = auth_aes128_sha1_pack_data(data, len, buffer, local, &self->server); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int auth_aes128_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + //server_info *server = (server_info*)&self->server; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + return -1; + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + int key_len = local->user_key_len + 4; + uint8_t *key = (uint8_t*)malloc(key_len); + memcpy(key, local->user_key, local->user_key_len); + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + char error = 0; + while (local->recv_buffer_size > 4) { + memintcopy_lt(key + key_len - 4, local->recv_id); + + { + char hash[20]; + local->hmac(hash, (char*)recv_buffer, 2, key, key_len); + + if (memcmp(hash, recv_buffer + 2, 2)) { + local->recv_buffer_size = 0; + error = 1; + break; + } + } + + int length = ((int)recv_buffer[1] << 8) + recv_buffer[0]; + if (length >= 8192 || length < 8) { + local->recv_buffer_size = 0; + error = 1; + break; + } + if (length > local->recv_buffer_size) + break; + + { + char hash[20]; + local->hmac(hash, (char *)recv_buffer, length - 4, key, key_len); + if (memcmp(hash, recv_buffer + length - 4, 4)) + { + local->recv_buffer_size = 0; + error = 1; + break; + } + } + + ++local->recv_id; + int pos = recv_buffer[4]; + if (pos < 255) + { + pos += 4; + } + else + { + pos = (((int)recv_buffer[6] << 8) | recv_buffer[5]) + 4; + } + int data_size = length - pos - 4; + memmove(buffer, recv_buffer + pos, data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len; + if (error == 0) { + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + } else { + len = -1; + } + free(out_buffer); + free(key); + return len; +} + +int auth_aes128_sha1_client_udp_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength + 8); + + if (local->user_key == NULL) { + if(self->server.param != NULL && self->server.param[0] != 0) { + char *param = self->server.param; + char *delim = strchr(param, ':'); + if(delim != NULL) { + char uid_str[16] = {}; + strncpy(uid_str, param, delim - param); + char key_str[128]; + strcpy(key_str, delim + 1); + long uid_long = strtol(uid_str, NULL, 10); + memintcopy_lt(local->uid, uid_long); + + char hash[21] = {0}; + local->hash(hash, key_str, strlen(key_str)); + + local->user_key_len = local->hash_len; + local->user_key = (uint8_t*)malloc(local->user_key_len); + memcpy(local->user_key, hash, local->hash_len); + } + } + if (local->user_key == NULL) { + rand_bytes((uint8_t *)local->uid, 4); + + local->user_key_len = self->server.key_len; + local->user_key = (uint8_t*)malloc(local->user_key_len); + memcpy(local->user_key, self->server.key, local->user_key_len); + } + } + + int outlength = datalength + 8; + memmove(out_buffer, plaindata, datalength); + memmove(out_buffer + datalength, local->uid, 4); + + { + char hash[20]; + local->hmac(hash, out_buffer, outlength - 4, local->user_key, local->user_key_len); + memmove(out_buffer + outlength - 4, hash, 4); + } + + if (*capacity < outlength) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = outlength * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, outlength); + + free(out_buffer); + return outlength; +} + +int auth_aes128_sha1_client_udp_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity) { + if (datalength <= 4) + return 0; + + char *plaindata = *pplaindata; + auth_simple_local_data *local = (auth_simple_local_data*)self->l_data; + + char hash[20]; + local->hmac(hash, plaindata, datalength - 4, self->server.key, self->server.key_len); + + if (memcmp(hash, plaindata + datalength - 4, 4)) + { + return 0; + } + + return datalength - 4; +} diff --git a/shadowsocksr-libev/src/server/auth.h b/shadowsocksr-libev/src/server/auth.h new file mode 100644 index 00000000..f7730df5 --- /dev/null +++ b/shadowsocksr-libev/src/server/auth.h @@ -0,0 +1,30 @@ +/* + * auth.h - Define shadowsocksR server's buffers and callbacks + * + * Copyright (C) 2015 - 2016, Break Wa11 + */ + +#ifndef _AUTH_H +#define _AUTH_H + +void * auth_simple_init_data(); +obfs * auth_simple_new_obfs(); +void auth_simple_dispose(obfs *self); + +int auth_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int auth_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + + +int auth_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int auth_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + +int auth_sha1_v2_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int auth_sha1_v2_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + +int auth_sha1_v4_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int auth_sha1_v4_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + +int auth_aes128_sha1_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int auth_aes128_sha1_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + +#endif // _AUTH_H diff --git a/shadowsocksr-libev/src/server/base64.c b/shadowsocksr-libev/src/server/base64.c new file mode 100644 index 00000000..7cf9552f --- /dev/null +++ b/shadowsocksr-libev/src/server/base64.c @@ -0,0 +1,119 @@ +#include "base64.h" + +/* BASE 64 encode table */ +static const char base64en[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +#define BASE64_PAD '=' + +#define BASE64DE_FIRST '+' +#define BASE64DE_LAST 'z' + +/* ASCII order for BASE 64 decode, -1 in unused character */ +static const signed char base64de[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* '+', ',', '-', '.', '/', */ + -1, -1, -1, 62, -1, -1, -1, 63, + /* '0', '1', '2', '3', '4', '5', '6', '7', */ + 52, 53, 54, 55, 56, 57, 58, 59, + /* '8', '9', ':', ';', '<', '=', '>', '?', */ + 60, 61, -1, -1, -1, -1, -1, -1, + /* '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', */ + -1, 0, 1, 2, 3, 4, 5, 6, + /* 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', */ + 7, 8, 9, 10, 11, 12, 13, 14, + /* 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', */ + 15, 16, 17, 18, 19, 20, 21, 22, + /* 'X', 'Y', 'Z', '[', '\', ']', '^', '_', */ + 23, 24, 25, -1, -1, -1, -1, -1, + /* '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', */ + -1, 26, 27, 28, 29, 30, 31, 32, + /* 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', */ + 33, 34, 35, 36, 37, 38, 39, 40, + /* 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', */ + 41, 42, 43, 44, 45, 46, 47, 48, + /* 'x', 'y', 'z', */ + 49, 50, 51, +}; + +int +base64_encode(const unsigned char *in, unsigned int inlen, char *out) +{ + unsigned int i, j; + + for (i = j = 0; i < inlen; i++) { + int s = i % 3; /* from 6/gcd(6, 8) */ + + switch (s) { + case 0: + out[j++] = base64en[(in[i] >> 2) & 0x3F]; + continue; + case 1: + out[j++] = base64en[((in[i-1] & 0x3) << 4) + ((in[i] >> 4) & 0xF)]; + continue; + case 2: + out[j++] = base64en[((in[i-1] & 0xF) << 2) + ((in[i] >> 6) & 0x3)]; + out[j++] = base64en[in[i] & 0x3F]; + } + } + + /* move back */ + i -= 1; + + /* check the last and add padding */ + if ((i % 3) == 0) { + out[j++] = base64en[(in[i] & 0x3) << 4]; + out[j++] = BASE64_PAD; + out[j++] = BASE64_PAD; + } else if ((i % 3) == 1) { + out[j++] = base64en[(in[i] & 0xF) << 2]; + out[j++] = BASE64_PAD; + } + + return BASE64_OK; +} + +int +base64_decode(const char *in, unsigned int inlen, unsigned char *out) +{ + unsigned int i, j; + + for (i = j = 0; i < inlen; i++) { + int c; + int s = i % 4; /* from 8/gcd(6, 8) */ + + if (in[i] == '=') + return BASE64_OK; + + if (in[i] < BASE64DE_FIRST || in[i] > BASE64DE_LAST || + (c = base64de[(int)in[i]]) == -1) + return BASE64_INVALID; + + switch (s) { + case 0: + out[j] = ((unsigned int)c << 2) & 0xFF; + continue; + case 1: + out[j++] += ((unsigned int)c >> 4) & 0x3; + + /* if not last char with padding */ + if (i < (inlen - 3) || in[inlen - 2] != '=') + out[j] = ((unsigned int)c & 0xF) << 4; + continue; + case 2: + out[j++] += ((unsigned int)c >> 2) & 0xF; + + /* if not last char with padding */ + if (i < (inlen - 2) || in[inlen - 1] != '=') + out[j] = ((unsigned int)c & 0x3) << 6; + continue; + case 3: + out[j++] += (unsigned char)c; + } + } + + return BASE64_OK; +} diff --git a/shadowsocksr-libev/src/server/base64.h b/shadowsocksr-libev/src/server/base64.h new file mode 100644 index 00000000..6432ba37 --- /dev/null +++ b/shadowsocksr-libev/src/server/base64.h @@ -0,0 +1,16 @@ +#ifndef __BASE64_H__ +#define __BASE64_H__ + +enum {BASE64_OK = 0, BASE64_INVALID}; + +#define BASE64_ENCODE_OUT_SIZE(s) (((s) + 2) / 3 * 4) +#define BASE64_DECODE_OUT_SIZE(s) (((s)) / 4 * 3) + +int +base64_encode(const unsigned char *in, unsigned int inlen, char *out); + +int +base64_decode(const char *in, unsigned int inlen, unsigned char *out); + + +#endif /* __BASE64_H__ */ diff --git a/shadowsocksr-libev/src/server/cache.c b/shadowsocksr-libev/src/server/cache.c new file mode 100644 index 00000000..c1a2995b --- /dev/null +++ b/shadowsocksr-libev/src/server/cache.c @@ -0,0 +1,308 @@ +/* + * cache.c - Manage the connection cache for UDPRELAY + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +/* + * Original Author: Oliver Lorenz (ol), olli@olorenz.org, https://olorenz.org + * License: This is licensed under the same terms as uthash itself + */ + +#include +#include + +#include "cache.h" +#include "utils.h" + +#ifdef __MINGW32__ +#include "win32.h" +#endif + +/** Creates a new cache object + * + * @param dst + * Where the newly allocated cache object will be stored in + * + * @param capacity + * The maximum number of elements this cache object can hold + * + * @return EINVAL if dst is NULL, ENOMEM if malloc fails, 0 otherwise + */ +int +cache_create(struct cache **dst, const size_t capacity, + void (*free_cb)(void *key, void *element)) +{ + struct cache *new = NULL; + + if (!dst) { + return EINVAL; + } + + if ((new = malloc(sizeof(*new))) == NULL) { + return ENOMEM; + } + + new->max_entries = capacity; + new->entries = NULL; + new->free_cb = free_cb; + *dst = new; + return 0; +} + +/** Frees an allocated cache object + * + * @param cache + * The cache object to free + * + * @param keep_data + * Whether to free contained data or just delete references to it + * + * @return EINVAL if cache is NULL, 0 otherwise + */ +int +cache_delete(struct cache *cache, int keep_data) +{ + struct cache_entry *entry, *tmp; + + if (!cache) { + return EINVAL; + } + + if (keep_data) { + HASH_CLEAR(hh, cache->entries); + } else { + HASH_ITER(hh, cache->entries, entry, tmp){ + HASH_DEL(cache->entries, entry); + if (entry->data != NULL) { + if (cache->free_cb) { + cache->free_cb(entry->key, entry->data); + } else { + ss_free(entry->data); + } + } + ss_free(entry->key); + ss_free(entry); + } + } + + ss_free(cache); + return 0; +} + +/** Clear old cache object + * + * @param cache + * The cache object to clear + * + * @param age + * Clear only objects older than the age (sec) + * + * @return EINVAL if cache is NULL, 0 otherwise + */ +int +cache_clear(struct cache *cache, ev_tstamp age) +{ + struct cache_entry *entry, *tmp; + + if (!cache) { + return EINVAL; + } + + ev_tstamp now = ev_time(); + + HASH_ITER(hh, cache->entries, entry, tmp){ + if (now - entry->ts > age) { + HASH_DEL(cache->entries, entry); + if (entry->data != NULL) { + if (cache->free_cb) { + cache->free_cb(entry->key, entry->data); + } else { + ss_free(entry->data); + } + } + ss_free(entry->key); + ss_free(entry); + } + } + + return 0; +} + +/** Removes a cache entry + * + * @param cache + * The cache object + * + * @param key + * The key of the entry to remove + * + * @param key_len + * The length of key + * + * @return EINVAL if cache is NULL, 0 otherwise + */ +int +cache_remove(struct cache *cache, char *key, size_t key_len) +{ + struct cache_entry *tmp; + + if (!cache || !key) { + return EINVAL; + } + + HASH_FIND(hh, cache->entries, key, key_len, tmp); + + if (tmp) { + HASH_DEL(cache->entries, tmp); + if (tmp->data != NULL) { + if (cache->free_cb) { + cache->free_cb(tmp->key, tmp->data); + } else { + ss_free(tmp->data); + } + } + ss_free(tmp->key); + ss_free(tmp); + } + + return 0; +} + +/** Checks if a given key is in the cache + * + * @param cache + * The cache object + * + * @param key + * The key to look-up + * + * @param key_len + * The length of key + * + * @param result + * Where to store the result if key is found. + * + * A warning: Even though result is just a pointer, + * you have to call this function with a **ptr, + * otherwise this will blow up in your face. + * + * @return EINVAL if cache is NULL, 0 otherwise + */ +int +cache_lookup(struct cache *cache, char *key, size_t key_len, void *result) +{ + struct cache_entry *tmp = NULL; + char **dirty_hack = result; + + if (!cache || !key || !result) { + return EINVAL; + } + + HASH_FIND(hh, cache->entries, key, key_len, tmp); + if (tmp) { + HASH_DELETE(hh, cache->entries, tmp); + tmp->ts = ev_time(); + HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); + *dirty_hack = tmp->data; + } else { + *dirty_hack = result = NULL; + } + + return 0; +} + +int +cache_key_exist(struct cache *cache, char *key, size_t key_len) +{ + struct cache_entry *tmp = NULL; + + if (!cache || !key) { + return 0; + } + + HASH_FIND(hh, cache->entries, key, key_len, tmp); + if (tmp) { + HASH_DELETE(hh, cache->entries, tmp); + tmp->ts = ev_time(); + HASH_ADD_KEYPTR(hh, cache->entries, tmp->key, key_len, tmp); + return 1; + } else { + return 0; + } + + return 0; +} + +/** Inserts a given pair into the cache + * + * @param cache + * The cache object + * + * @param key + * The key that identifies + * + * @param key_len + * The length of key + * + * @param data + * Data associated with + * + * @return EINVAL if cache is NULL, ENOMEM if malloc fails, 0 otherwise + */ +int +cache_insert(struct cache *cache, char *key, size_t key_len, void *data) +{ + struct cache_entry *entry = NULL; + struct cache_entry *tmp_entry = NULL; + + if (!cache) { + return EINVAL; + } + + if ((entry = malloc(sizeof(*entry))) == NULL) { + return ENOMEM; + } + + entry->key = ss_malloc(key_len + 1); + memcpy(entry->key, key, key_len); + entry->key[key_len] = 0; + + entry->data = data; + entry->ts = ev_time(); + HASH_ADD_KEYPTR(hh, cache->entries, entry->key, key_len, entry); + + if (HASH_COUNT(cache->entries) >= cache->max_entries) { + HASH_ITER(hh, cache->entries, entry, tmp_entry){ + HASH_DELETE(hh, cache->entries, entry); + if (entry->data != NULL) { + if (cache->free_cb) { + cache->free_cb(entry->key, entry->data); + } else { + ss_free(entry->data); + } + } + ss_free(entry->key); + ss_free(entry); + break; + } + } + + return 0; +} diff --git a/shadowsocksr-libev/src/server/cache.h b/shadowsocksr-libev/src/server/cache.h new file mode 100644 index 00000000..0ec98f55 --- /dev/null +++ b/shadowsocksr-libev/src/server/cache.h @@ -0,0 +1,62 @@ +/* + * cache.h - Define the cache manager interface + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +/* + * Original Author: Oliver Lorenz (ol), olli@olorenz.org, https://olorenz.org + * License: This is licensed under the same terms as uthash itself + */ + +#ifndef _CACHE_ +#define _CACHE_ + +#include "uthash.h" +#include "ev.h" + +/** + * A cache entry + */ +struct cache_entry { + char *key; /** +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define __DEBUG__ +#ifdef __DEBUG__ +#define DEBUG(format,...) printf("File: "__FILE__", Line: %05d: "format"/n", __LINE__, ##__VA_ARGS__) +#else +#define DEBUG(format,...) +#endif + +static sigjmp_buf jmpbuf; +static void alarm_func() +{ + siglongjmp(jmpbuf, 1); +} + +static struct hostent *timeGethostbyname(const char *domain, int timeout) +{ + struct hostent *ipHostent = NULL; + signal(SIGALRM, alarm_func); + if(sigsetjmp(jmpbuf, 1) != 0) + { + alarm(0);//timout + signal(SIGALRM, SIG_IGN); + return NULL; + } + alarm(timeout);//setting alarm + ipHostent = gethostbyname(domain); + signal(SIGALRM, SIG_IGN); + return ipHostent; +} + + +#define MY_HTTP_DEFAULT_PORT 80 +#define BUFFER_SIZE 1024 +#define HTTP_POST "POST /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n"\ + "Content-Type:application/x-www-form-urlencoded\r\nContent-Length: %d\r\n\r\n%s" +#define HTTP_GET "GET /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n\r\n" + +static int http_parse_url(const char *url,char *host,char *file,int *port) +{ + char *ptr1,*ptr2; + int len = 0; + if(!url || !host || !file || !port){ + return 1; + } + + ptr1 = (char *)url; + + if(!strncmp(ptr1,"http://",strlen("http://"))){ + ptr1 += strlen("http://"); + }else{ + return 1; + } + + ptr2 = strchr(ptr1,'/'); + if(ptr2){ + len = strlen(ptr1) - strlen(ptr2); + memcpy(host,ptr1,len); + host[len] = '\0'; + if(*(ptr2 + 1)){ + memcpy(file,ptr2 + 1,strlen(ptr2) - 1 ); + file[strlen(ptr2) - 1] = '\0'; + } + }else{ + memcpy(host,ptr1,strlen(ptr1)); + host[strlen(ptr1)] = '\0'; + } + //get host and ip + ptr1 = strchr(host,':'); + if(ptr1){ + *ptr1++ = '\0'; + *port = atoi(ptr1); + }else{ + *port = MY_HTTP_DEFAULT_PORT; + } + + return 0; +} + + +static int http_tcpclient_recv(int socket,char *lpbuff){ + int recvnum = 0; + + recvnum = recv(socket, lpbuff,BUFFER_SIZE*4,0); + + return recvnum; +} + +static int http_tcpclient_send(int socket,char *buff,int size){ + int sent=0,tmpres=0; + + while(sent < size){ + tmpres = send(socket,buff+sent,size-sent,0); + if(tmpres == -1){ + return 1; + } + sent += tmpres; + } + return sent; +} + + + + + +int http_get(const char *url,int socket_fd) +{ + char lpbuf[BUFFER_SIZE*4] = {'\0'}; + + char host_addr[BUFFER_SIZE] = {'\0'}; + char file[BUFFER_SIZE] = {'\0'}; + int port = 0; + + + if(!url){ + DEBUG(" failed!\n"); + return 1; + } + + if(http_parse_url(url,host_addr,file,&port)){ + DEBUG("http_parse_url failed!\n"); + return 1; + } + DEBUG("url: %s\thost_addr : %s\tfile:%s\t,%d\n",url,host_addr,file,port); + + + if(socket_fd < 0){ + DEBUG("http_tcpclient_create failed\n"); + return 1; + } + + sprintf(lpbuf,HTTP_GET,file,host_addr,port); + + if(http_tcpclient_send(socket_fd,lpbuf,strlen(lpbuf)) < 0){ + DEBUG("http_tcpclient_send failed..\n"); + return 1; + } + DEBUG("request:\n%s\n",lpbuf); + + if(http_tcpclient_recv(socket_fd,lpbuf) <= 0){ + DEBUG("http_tcpclient_recv failed\n"); + close(socket_fd); + return 1; + } + DEBUG("rec:\n%s\n",lpbuf); + close(socket_fd); + + //return http_parse_result(lpbuf); +return 0; +} + + + +int main(int argc, char *argv[]) +{ + int fd,http_flag=0,http_ret=1; + struct sockaddr_in addr; + struct hostent *host; + struct timeval timeo = {3, 0}; + socklen_t len = sizeof(timeo); + + char http_url[100]="http://"; + + + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (argc >= 4) + timeo.tv_sec = atoi(argv[3]); + if (argc>=5) + http_flag=1; + + if((host=timeGethostbyname(argv[1],timeo.tv_sec)) == NULL) { + DEBUG("gethostbyname err\n"); + return 1; + } + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len) == -1) + { + + DEBUG("setsockopt send err\n"); + return 1; + } + + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, len) == -1) + { + + DEBUG("setsockopt recv err\n"); + return 1; + } + + addr.sin_family = AF_INET; + addr.sin_addr = *((struct in_addr *)host->h_addr); + //addr.sin_addr.s_addr = inet_addr(argv[1]); + addr.sin_port = htons(atoi(argv[2])); +if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) + { + if (errno == EINPROGRESS) + { + DEBUG("timeout err\n"); + return 1; + } + DEBUG("connect err\n"); + return 1; + } +if(http_flag==0) +{ + close(fd); + return 0; +} +strcat(http_url,argv[1]); +http_ret=http_get(http_url,fd); +if(http_ret==1) +{ +DEBUG("recv err"); + return 1; +} +else +{ +DEBUG("recv ok"); + + return 0; +} + +} \ No newline at end of file diff --git a/shadowsocksr-libev/src/server/common.h b/shadowsocksr-libev/src/server/common.h new file mode 100644 index 00000000..000f084e --- /dev/null +++ b/shadowsocksr-libev/src/server/common.h @@ -0,0 +1,58 @@ +/* + * common.h - Provide global definitions + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _COMMON_H +#define _COMMON_H + +#define DEFAULT_CONF_PATH "/etc/shadowsocks-libev/config.json" + +#ifndef SOL_TCP +#define SOL_TCP IPPROTO_TCP +#endif + +#if defined(MODULE_TUNNEL) || defined(MODULE_REDIR) +#define MODULE_LOCAL +#endif + +int init_udprelay(const char *server_host, const char *server_port, +#ifdef MODULE_LOCAL + const struct sockaddr *remote_addr, const int remote_addr_len, +#ifdef MODULE_TUNNEL + const ss_addr_t tunnel_addr, +#endif +#endif + int mtu, int method, int auth, int timeout, const char *iface, const char *protocol, const char *protocol_param); + +void free_udprelay(void); + +#ifdef ANDROID +int protect_socket(int fd); +int send_traffic_stat(uint64_t tx, uint64_t rx); +#endif + +#define STAGE_ERROR -1 /* Error detected */ +#define STAGE_INIT 0 /* Initial stage */ +#define STAGE_HANDSHAKE 1 /* Handshake with client */ +#define STAGE_PARSE 2 /* Parse the header */ +#define STAGE_RESOLVE 4 /* Resolve the hostname */ +#define STAGE_STREAM 5 /* Stream between client and server */ + +#endif // _COMMON_H diff --git a/shadowsocksr-libev/src/server/crc32.c b/shadowsocksr-libev/src/server/crc32.c new file mode 100644 index 00000000..6d328d23 --- /dev/null +++ b/shadowsocksr-libev/src/server/crc32.c @@ -0,0 +1,97 @@ +static uint32_t crc32_table[256] = {0}; + +void init_crc32_table(void) { + uint32_t c, i, j; + if (crc32_table[0] == 0) { + for (i = 0; i < 256; i++) { + c = i; + for (j = 0; j < 8; j++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc32_table[i] = c; + } + } +} + +uint32_t crc32(unsigned char *buffer, unsigned int size) { + uint32_t crc = 0xFFFFFFFF; + unsigned int i; + for (i = 0; i < size; i++) { + crc = crc32_table[(crc ^ buffer[i]) & 0xFF] ^ (crc >> 8); + } + return crc ^ 0xFFFFFFFF; +} + +void fillcrc32to(unsigned char *buffer, unsigned int size, unsigned char *outbuffer) { + uint32_t crc = 0xFFFFFFFF; + unsigned int i; + for (i = 0; i < size; i++) { + crc = crc32_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8); + } + crc ^= 0xFFFFFFFF; + outbuffer[0] = crc; + outbuffer[1] = crc >> 8; + outbuffer[2] = crc >> 16; + outbuffer[3] = crc >> 24; +} + +void fillcrc32(unsigned char *buffer, unsigned int size) { + uint32_t crc = 0xFFFFFFFF; + unsigned int i; + size -= 4; + for (i = 0; i < size; i++) { + crc = crc32_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8); + } + buffer += size; + buffer[0] = crc; + buffer[1] = crc >> 8; + buffer[2] = crc >> 16; + buffer[3] = crc >> 24; +} + +void adler32_short(unsigned char *buffer, unsigned int size, uint32_t *a, uint32_t *b) { + for (int i = 0; i < size; i++) { + *a += buffer[i]; + *b += *a; + } + *a %= 65521; + *b %= 65521; +} + +#define NMAX 5552 +uint32_t adler32(unsigned char *buffer, unsigned int size) { + uint32_t a = 1; + uint32_t b = 0; + while ( size >= NMAX ) { + adler32_short(buffer, NMAX, &a, &b); + buffer += NMAX; + size -= NMAX; + } + adler32_short(buffer, size, &a, &b); + return (b << 16) + a; +} +#undef NMAX + +void filladler32(unsigned char *buffer, unsigned int size) { + size -= 4; + uint32_t checksum = adler32(buffer, size); + buffer += size; + buffer[0] = checksum; + buffer[1] = checksum >> 8; + buffer[2] = checksum >> 16; + buffer[3] = checksum >> 24; +} + +int checkadler32(unsigned char *buffer, unsigned int size) { + size -= 4; + uint32_t checksum = adler32(buffer, size); + buffer += size; + return checksum == (((uint32_t)buffer[3] << 24) + | ((uint32_t)buffer[2] << 16) + | ((uint32_t)buffer[1] << 8) + | (uint32_t)buffer[0]); +} + diff --git a/shadowsocksr-libev/src/server/encrypt.c b/shadowsocksr-libev/src/server/encrypt.c new file mode 100644 index 00000000..37dd5cdf --- /dev/null +++ b/shadowsocksr-libev/src/server/encrypt.c @@ -0,0 +1,1645 @@ +/* + * encrypt.c - Manage the global encryptor + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(USE_CRYPTO_OPENSSL) + +#include +#include +#include +#include + +#elif defined(USE_CRYPTO_POLARSSL) + +#include +#include +#include +#include +#include +#include +#define CIPHER_UNSUPPORTED "unsupported" + +#include +#ifdef _WIN32 +#include +#include +#else +#include +#endif + +#elif defined(USE_CRYPTO_MBEDTLS) + +#include +#include +#include +#include +#include +#define CIPHER_UNSUPPORTED "unsupported" + +#include +#ifdef _WIN32 +#include +#include +#else +#include +#endif + +#endif + +#include + +#ifndef __MINGW32__ +#include +#endif + +#include "cache.h" +#include "encrypt.h" +#include "utils.h" + +#define OFFSET_ROL(p, o) ((uint64_t)(*(p + o)) << (8 * o)) + +static uint8_t *enc_table; +static uint8_t *dec_table; +static uint8_t enc_key[MAX_KEY_LENGTH]; +static int enc_key_len; +static int enc_iv_len; +static int enc_method; + +static struct cache *iv_cache; + +#ifdef DEBUG +static void +dump(char *tag, char *text, int len) +{ + int i; + printf("%s: ", tag); + for (i = 0; i < len; i++) + printf("0x%02x ", (uint8_t)text[i]); + printf("\n"); +} + +#endif + +static const char *supported_ciphers[CIPHER_NUM] = { + "table", + "rc4", + "rc4-md5-6", + "rc4-md5", + "aes-128-cfb", + "aes-192-cfb", + "aes-256-cfb", + "aes-128-ctr", + "aes-192-ctr", + "aes-256-ctr", + "bf-cfb", + "camellia-128-cfb", + "camellia-192-cfb", + "camellia-256-cfb", + "cast5-cfb", + "des-cfb", + "idea-cfb", + "rc2-cfb", + "seed-cfb", + "salsa20", + "chacha20", + "chacha20-ietf" +}; + +#ifdef USE_CRYPTO_POLARSSL +static const char *supported_ciphers_polarssl[CIPHER_NUM] = { + "table", + "ARC4-128", + "ARC4-128", + "ARC4-128", + "AES-128-CFB128", + "AES-192-CFB128", + "AES-256-CFB128", + "AES-128-CTR", + "AES-192-CTR", + "AES-256-CTR", + "BLOWFISH-CFB64", + "CAMELLIA-128-CFB128", + "CAMELLIA-192-CFB128", + "CAMELLIA-256-CFB128", + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + "salsa20", + "chacha20", + "chacha20-ietf" +}; +#endif + +#ifdef USE_CRYPTO_MBEDTLS +static const char *supported_ciphers_mbedtls[CIPHER_NUM] = { + "table", + "ARC4-128", + "ARC4-128", + "ARC4-128", + "AES-128-CFB128", + "AES-192-CFB128", + "AES-256-CFB128", + "AES-128-CTR", + "AES-192-CTR", + "AES-256-CTR", + "BLOWFISH-CFB64", + "CAMELLIA-128-CFB128", + "CAMELLIA-192-CFB128", + "CAMELLIA-256-CFB128", + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + "salsa20", + "chacha20", + "chacha20-ietf" +}; +#endif + +#ifdef USE_CRYPTO_APPLECC +static const CCAlgorithm supported_ciphers_applecc[CIPHER_NUM] = { + kCCAlgorithmInvalid, + kCCAlgorithmRC4, + kCCAlgorithmRC4, + kCCAlgorithmRC4, + kCCAlgorithmAES, + kCCAlgorithmAES, + kCCAlgorithmAES, + kCCAlgorithmAES, + kCCAlgorithmAES, + kCCAlgorithmAES, + kCCAlgorithmBlowfish, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmCAST, + kCCAlgorithmDES, + kCCAlgorithmInvalid, + kCCAlgorithmRC2, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid +}; + +static const CCMode supported_modes_applecc[CIPHER_NUM] = { + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCModeRC4, + kCCModeRC4, + kCCModeCFB, + kCCModeCFB, + kCCModeCFB, + kCCModeCTR, + kCCModeCTR, + kCCModeCTR, + kCCModeCFB, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCModeCFB, + kCCModeCFB, + kCCModeCFB, + kCCModeCFB, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid, + kCCAlgorithmInvalid +}; +#endif + +static const int supported_ciphers_iv_size[CIPHER_NUM] = { + 0, 0, 6, 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 8, 8, 8, 8, 16, 8, 8, 12 +}; + +static const int supported_ciphers_key_size[CIPHER_NUM] = { + 0, 16, 16, 16, 16, 24, 32, 16, 24, 32, 16, 16, 24, 32, 16, 8, 16, 16, 16, 32, 32, 32 +}; + +static int +safe_memcmp(const void *s1, const void *s2, size_t n) +{ + const unsigned char *_s1 = (const unsigned char *)s1; + const unsigned char *_s2 = (const unsigned char *)s2; + int ret = 0; + size_t i; + for (i = 0; i < n; i++) + ret |= _s1[i] ^ _s2[i]; + return !!ret; +} + +int +balloc(buffer_t *ptr, size_t capacity) +{ + sodium_memzero(ptr, sizeof(buffer_t)); + ptr->array = ss_malloc(capacity); + ptr->capacity = capacity; + return capacity; +} + +int +brealloc(buffer_t *ptr, size_t len, size_t capacity) +{ + if (ptr == NULL) + return -1; + size_t real_capacity = max(len, capacity); + if (ptr->capacity < real_capacity) { + ptr->array = ss_realloc(ptr->array, real_capacity); + ptr->capacity = real_capacity; + } + return real_capacity; +} + +void +bfree(buffer_t *ptr) +{ + if (ptr == NULL) + return; + ptr->idx = 0; + ptr->len = 0; + ptr->capacity = 0; + if (ptr->array != NULL) { + ss_free(ptr->array); + } +} + +static int +crypto_stream_xor_ic(uint8_t *c, const uint8_t *m, uint64_t mlen, + const uint8_t *n, uint64_t ic, const uint8_t *k, + int method) +{ + switch (method) { + case SALSA20: + return crypto_stream_salsa20_xor_ic(c, m, mlen, n, ic, k); + case CHACHA20: + return crypto_stream_chacha20_xor_ic(c, m, mlen, n, ic, k); + case CHACHA20IETF: + return crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, n, (uint32_t)ic, k); + } + // always return 0 + return 0; +} + +static int +random_compare(const void *_x, const void *_y, uint32_t i, + uint64_t a) +{ + uint8_t x = *((uint8_t *)_x); + uint8_t y = *((uint8_t *)_y); + return a % (x + i) - a % (y + i); +} + +static void +merge(uint8_t *left, int llength, uint8_t *right, + int rlength, uint32_t salt, uint64_t key) +{ + uint8_t *ltmp = (uint8_t *)malloc(llength * sizeof(uint8_t)); + uint8_t *rtmp = (uint8_t *)malloc(rlength * sizeof(uint8_t)); + + uint8_t *ll = ltmp; + uint8_t *rr = rtmp; + + uint8_t *result = left; + + memcpy(ltmp, left, llength * sizeof(uint8_t)); + memcpy(rtmp, right, rlength * sizeof(uint8_t)); + + while (llength > 0 && rlength > 0) { + if (random_compare(ll, rr, salt, key) <= 0) { + *result = *ll; + ++ll; + --llength; + } else { + *result = *rr; + ++rr; + --rlength; + } + ++result; + } + + if (llength > 0) { + while (llength > 0) { + *result = *ll; + ++result; + ++ll; + --llength; + } + } else { + while (rlength > 0) { + *result = *rr; + ++result; + ++rr; + --rlength; + } + } + + ss_free(ltmp); + ss_free(rtmp); +} + +static void +merge_sort(uint8_t array[], int length, + uint32_t salt, uint64_t key) +{ + uint8_t middle; + uint8_t *left, *right; + int llength; + + if (length <= 1) { + return; + } + + middle = length / 2; + + llength = length - middle; + + left = array; + right = array + llength; + + merge_sort(left, llength, salt, key); + merge_sort(right, middle, salt, key); + merge(left, llength, right, middle, salt, key); +} + +int +enc_get_iv_len() +{ + return enc_iv_len; +} + +uint8_t* enc_get_key() +{ + return enc_key; +} + +int enc_get_key_len() +{ + return enc_key_len; +} + +unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md) +{ +#if defined(USE_CRYPTO_OPENSSL) + return MD5(d, n, md); +#elif defined(USE_CRYPTO_POLARSSL) + static unsigned char m[16]; + if (md == NULL) { + md = m; + } + md5(d, n, md); + return md; +#elif defined(USE_CRYPTO_MBEDTLS) + static unsigned char m[16]; + if (md == NULL) { + md = m; + } + mbedtls_md5(d, n, md); + return md; +#endif +} + +void +enc_table_init(const char *pass) +{ + uint32_t i; + uint64_t key = 0; + uint8_t *digest; + + enc_table = ss_malloc(256); + dec_table = ss_malloc(256); + + digest = enc_md5((const uint8_t *)pass, strlen(pass), NULL); + + for (i = 0; i < 8; i++) + key += OFFSET_ROL(digest, i); + + for (i = 0; i < 256; ++i) + enc_table[i] = i; + for (i = 1; i < 1024; ++i) + merge_sort(enc_table, 256, i, key); + for (i = 0; i < 256; ++i) + // gen decrypt table from encrypt table + dec_table[enc_table[i]] = i; +} + +int +cipher_iv_size(const cipher_t *cipher) +{ +#if defined(USE_CRYPTO_OPENSSL) + if (cipher->info == NULL) + return cipher->iv_len; + else + return EVP_CIPHER_iv_length(cipher->info); +#elif defined(USE_CRYPTO_POLARSSL) || defined(USE_CRYPTO_MBEDTLS) + if (cipher == NULL) { + return 0; + } + return cipher->info->iv_size; +#endif +} + +int +cipher_key_size(const cipher_t *cipher) +{ +#if defined(USE_CRYPTO_OPENSSL) + if (cipher->info == NULL) + return cipher->key_len; + else + return EVP_CIPHER_key_length(cipher->info); +#elif defined(USE_CRYPTO_POLARSSL) + if (cipher == NULL) { + return 0; + } + /* Override PolarSSL 32 bit default key size with sane 128 bit default */ + if (cipher->info->base != NULL && POLARSSL_CIPHER_ID_BLOWFISH == + cipher->info->base->cipher) { + return 128 / 8; + } + return cipher->info->key_length / 8; +#elif defined(USE_CRYPTO_MBEDTLS) + /* + * Semi-API changes (technically public, morally private) + * Renamed a few headers to include _internal in the name. Those headers are + * not supposed to be included by users. + * Changed md_info_t into an opaque structure (use md_get_xxx() accessors). + * Changed pk_info_t into an opaque structure. + * Changed cipher_base_t into an opaque structure. + */ + if (cipher == NULL) { + return 0; + } + /* From Version 1.2.7 released 2013-04-13 Default Blowfish keysize is now 128-bits */ + return cipher->info->key_bitlen / 8; +#endif +} + +void +bytes_to_key_with_size(const char *pass, size_t len, uint8_t *md, size_t md_size) +{ + uint8_t result[128]; + enc_md5((const unsigned char *)pass, len, result); + memcpy(md, result, 16); + int i = 16; + for (; i < md_size; i += 16) { + memcpy(result + 16, pass, len); + enc_md5(result, 16 + len, result); + memcpy(md + i, result, 16); + } +} + +int +bytes_to_key(const cipher_t *cipher, const digest_type_t *md, + const uint8_t *pass, uint8_t *key) +{ + size_t datal; + datal = strlen((const char *)pass); + +#if defined(USE_CRYPTO_OPENSSL) + + MD5_CTX c; + unsigned char md_buf[MAX_MD_SIZE]; + int nkey; + int addmd; + unsigned int i, j, mds; + + mds = 16; + nkey = cipher_key_size(cipher); + if (pass == NULL) + return nkey; + memset(&c, 0, sizeof(MD5_CTX)); + + for (j = 0, addmd = 0; j < nkey; addmd++) { + MD5_Init(&c); + if (addmd) { + MD5_Update(&c, md_buf, mds); + } + MD5_Update(&c, pass, datal); + MD5_Final(md_buf, &c); + + for (i = 0; i < mds; i++, j++) { + if (j >= nkey) + break; + key[j] = md_buf[i]; + } + } + + return nkey; + +#elif defined(USE_CRYPTO_POLARSSL) + md_context_t c; + unsigned char md_buf[MAX_MD_SIZE]; + int nkey; + int addmd; + unsigned int i, j, mds; + + nkey = cipher_key_size(cipher); + mds = md_get_size(md); + memset(&c, 0, sizeof(md_context_t)); + + if (pass == NULL) + return nkey; + if (md_init_ctx(&c, md)) + return 0; + + for (j = 0, addmd = 0; j < nkey; addmd++) { + md_starts(&c); + if (addmd) { + md_update(&c, md_buf, mds); + } + md_update(&c, pass, datal); + md_finish(&c, md_buf); + + for (i = 0; i < mds; i++, j++) { + if (j >= nkey) + break; + key[j] = md_buf[i]; + } + } + + md_free_ctx(&c); + return nkey; + +#elif defined(USE_CRYPTO_MBEDTLS) + + mbedtls_md_context_t c; + unsigned char md_buf[MAX_MD_SIZE]; + int nkey; + int addmd; + unsigned int i, j, mds; + + nkey = cipher_key_size(cipher); + mds = mbedtls_md_get_size(md); + memset(&c, 0, sizeof(mbedtls_md_context_t)); + + if (pass == NULL) + return nkey; + if (mbedtls_md_setup(&c, md, 1)) + return 0; + + for (j = 0, addmd = 0; j < nkey; addmd++) { + mbedtls_md_starts(&c); + if (addmd) { + mbedtls_md_update(&c, md_buf, mds); + } + mbedtls_md_update(&c, pass, datal); + mbedtls_md_finish(&c, &(md_buf[0])); + + for (i = 0; i < mds; i++, j++) { + if (j >= nkey) + break; + key[j] = md_buf[i]; + } + } + + mbedtls_md_free(&c); + return nkey; +#endif +} + +int +rand_bytes(uint8_t *output, int len) +{ + randombytes_buf(output, len); + // always return success + return 0; +} + +const cipher_kt_t * +get_cipher_type(int method) +{ + if (method <= TABLE || method >= CIPHER_NUM) { + LOGE("get_cipher_type(): Illegal method"); + return NULL; + } + + if (method == RC4_MD5 || method == RC4_MD5_6) { + method = RC4; + } + + if (method >= SALSA20) { + return NULL; + } + + const char *ciphername = supported_ciphers[method]; +#if defined(USE_CRYPTO_OPENSSL) + return EVP_get_cipherbyname(ciphername); +#elif defined(USE_CRYPTO_POLARSSL) + const char *polarname = supported_ciphers_polarssl[method]; + if (strcmp(polarname, CIPHER_UNSUPPORTED) == 0) { + LOGE("Cipher %s currently is not supported by PolarSSL library", + ciphername); + return NULL; + } + return cipher_info_from_string(polarname); +#elif defined(USE_CRYPTO_MBEDTLS) + const char *mbedtlsname = supported_ciphers_mbedtls[method]; + if (strcmp(mbedtlsname, CIPHER_UNSUPPORTED) == 0) { + LOGE("Cipher %s currently is not supported by mbed TLS library", + ciphername); + return NULL; + } + return mbedtls_cipher_info_from_string(mbedtlsname); +#endif +} + +const digest_type_t * +get_digest_type(const char *digest) +{ + if (digest == NULL) { + LOGE("get_digest_type(): Digest name is null"); + return NULL; + } + +#if defined(USE_CRYPTO_OPENSSL) + return EVP_get_digestbyname(digest); +#elif defined(USE_CRYPTO_POLARSSL) + return md_info_from_string(digest); +#elif defined(USE_CRYPTO_MBEDTLS) + return mbedtls_md_info_from_string(digest); +#endif +} + +void +cipher_context_init(cipher_ctx_t *ctx, int method, int enc) +{ + if (method <= TABLE || method >= CIPHER_NUM) { + LOGE("cipher_context_init(): Illegal method"); + return; + } + + if (method >= SALSA20) { + enc_iv_len = supported_ciphers_iv_size[method]; + return; + } + + const char *ciphername = supported_ciphers[method]; +#if defined(USE_CRYPTO_APPLECC) + cipher_cc_t *cc = &ctx->cc; + cc->cryptor = NULL; + cc->cipher = supported_ciphers_applecc[method]; + if (cc->cipher == kCCAlgorithmInvalid) { + cc->valid = kCCContextInvalid; + } else { + cc->valid = kCCContextValid; + if (cc->cipher == kCCAlgorithmRC4) { + cc->mode = supported_modes_applecc[method]; + cc->padding = ccNoPadding; + } else { + cc->mode = supported_modes_applecc[method]; + if (cc->mode == kCCModeCTR) { + cc->padding = ccNoPadding; + } else { + cc->padding = ccPKCS7Padding; + } + } + return; + } +#endif + + const cipher_kt_t *cipher = get_cipher_type(method); + +#if defined(USE_CRYPTO_OPENSSL) + ctx->evp = EVP_CIPHER_CTX_new(); + cipher_evp_t *evp = ctx->evp; + + if (cipher == NULL) { + LOGE("Cipher %s not found in OpenSSL library", ciphername); + FATAL("Cannot initialize cipher"); + } + if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { + LOGE("Cannot initialize cipher %s", ciphername); + exit(EXIT_FAILURE); + } + if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { + EVP_CIPHER_CTX_cleanup(evp); + LOGE("Invalid key length: %d", enc_key_len); + exit(EXIT_FAILURE); + } + if (method > RC4_MD5) { + EVP_CIPHER_CTX_set_padding(evp, 1); + } +#elif defined(USE_CRYPTO_POLARSSL) + ctx->evp = (cipher_evp_t *)ss_malloc(sizeof(cipher_evp_t)); + cipher_evp_t *evp = ctx->evp; + + if (cipher == NULL) { + LOGE("Cipher %s not found in PolarSSL library", ciphername); + FATAL("Cannot initialize PolarSSL cipher"); + } + if (cipher_init_ctx(evp, cipher) != 0) { + FATAL("Cannot initialize PolarSSL cipher context"); + } +#elif defined(USE_CRYPTO_MBEDTLS) + ctx->evp = (cipher_evp_t *)ss_malloc(sizeof(cipher_evp_t)); + cipher_evp_t *evp = ctx->evp; + + if (cipher == NULL) { + LOGE("Cipher %s not found in mbed TLS library", ciphername); + FATAL("Cannot initialize mbed TLS cipher"); + } + mbedtls_cipher_init(evp); + if (mbedtls_cipher_setup(evp, cipher) != 0) { + FATAL("Cannot initialize mbed TLS cipher context"); + } +#endif +} + +void +cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, + int enc) +{ + const unsigned char *true_key; + + if (iv == NULL) { + LOGE("cipher_context_set_iv(): IV is null"); + return; + } + + if (!enc) { + memcpy(ctx->iv, iv, iv_len); + } + + if (enc_method >= SALSA20) { + return; + } + + if (enc_method == RC4_MD5 || enc_method == RC4_MD5_6) { + unsigned char key_iv[32]; + memcpy(key_iv, enc_key, 16); + memcpy(key_iv + 16, iv, iv_len); + true_key = enc_md5(key_iv, 16 + iv_len, NULL); + iv_len = 0; + } else { + true_key = enc_key; + } + +#ifdef USE_CRYPTO_APPLECC + cipher_cc_t *cc = &ctx->cc; + if (cc->valid == kCCContextValid) { + memcpy(cc->iv, iv, iv_len); + memcpy(cc->key, true_key, enc_key_len); + cc->iv_len = iv_len; + cc->key_len = enc_key_len; + cc->encrypt = enc ? kCCEncrypt : kCCDecrypt; + if (cc->cryptor != NULL) { + CCCryptorRelease(cc->cryptor); + cc->cryptor = NULL; + } + + CCCryptorStatus ret; + ret = CCCryptorCreateWithMode( + cc->encrypt, + cc->mode, + cc->cipher, + cc->padding, + cc->iv, cc->key, cc->key_len, + NULL, 0, 0, kCCModeOptionCTR_BE, + &cc->cryptor); + if (ret != kCCSuccess) { + if (cc->cryptor != NULL) { + CCCryptorRelease(cc->cryptor); + cc->cryptor = NULL; + } + FATAL("Cannot set CommonCrypto key and IV"); + } + return; + } +#endif + + cipher_evp_t *evp = ctx->evp; + if (evp == NULL) { + LOGE("cipher_context_set_iv(): Cipher context is null"); + return; + } +#if defined(USE_CRYPTO_OPENSSL) + if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) { + EVP_CIPHER_CTX_cleanup(evp); + FATAL("Cannot set key and IV"); + } +#elif defined(USE_CRYPTO_POLARSSL) + // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead. + if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { + cipher_free_ctx(evp); + FATAL("Cannot set PolarSSL cipher key"); + } +#if POLARSSL_VERSION_NUMBER >= 0x01030000 + if (cipher_set_iv(evp, iv, iv_len) != 0) { + cipher_free_ctx(evp); + FATAL("Cannot set PolarSSL cipher IV"); + } + if (cipher_reset(evp) != 0) { + cipher_free_ctx(evp); + FATAL("Cannot finalize PolarSSL cipher context"); + } +#else + if (cipher_reset(evp, iv) != 0) { + cipher_free_ctx(evp); + FATAL("Cannot set PolarSSL cipher IV"); + } +#endif +#elif defined(USE_CRYPTO_MBEDTLS) + if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { + mbedtls_cipher_free(evp); + FATAL("Cannot set mbed TLS cipher key"); + } + + if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) { + mbedtls_cipher_free(evp); + FATAL("Cannot set mbed TLS cipher IV"); + } + if (mbedtls_cipher_reset(evp) != 0) { + mbedtls_cipher_free(evp); + FATAL("Cannot finalize mbed TLS cipher context"); + } +#endif + +#ifdef DEBUG + dump("IV", (char *)iv, iv_len); +#endif +} + +void +cipher_context_release(cipher_ctx_t *ctx) +{ + if (enc_method >= SALSA20) { + return; + } + +#ifdef USE_CRYPTO_APPLECC + cipher_cc_t *cc = &ctx->cc; + if (cc->cryptor != NULL) { + CCCryptorRelease(cc->cryptor); + cc->cryptor = NULL; + } + if (cc->valid == kCCContextValid) { + return; + } +#endif + +#if defined(USE_CRYPTO_OPENSSL) + EVP_CIPHER_CTX_free(ctx->evp); +#elif defined(USE_CRYPTO_POLARSSL) +// NOTE: cipher_free_ctx deprecated in PolarSSL 1.3.11 + cipher_free_ctx(ctx->evp); + ss_free(ctx->evp); +#elif defined(USE_CRYPTO_MBEDTLS) +// NOTE: cipher_free_ctx deprecated + mbedtls_cipher_free(ctx->evp); + ss_free(ctx->evp); +#endif +} + +static int +cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, size_t *olen, + const uint8_t *input, size_t ilen) +{ +#ifdef USE_CRYPTO_APPLECC + cipher_cc_t *cc = &ctx->cc; + if (cc->valid == kCCContextValid) { + CCCryptorStatus ret; + ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, + ilen, olen); + return (ret == kCCSuccess) ? 1 : 0; + } +#endif + cipher_evp_t *evp = ctx->evp; +#if defined(USE_CRYPTO_OPENSSL) + int err = 0, tlen = *olen; + err = EVP_CipherUpdate(evp, (uint8_t *)output, &tlen, + (const uint8_t *)input, ilen); + *olen = tlen; + return err; +#elif defined(USE_CRYPTO_POLARSSL) + return !cipher_update(evp, (const uint8_t *)input, ilen, + (uint8_t *)output, olen); +#elif defined(USE_CRYPTO_MBEDTLS) + return !mbedtls_cipher_update(evp, (const uint8_t *)input, ilen, + (uint8_t *)output, olen); +#endif +} +int ss_md5_hmac(char *auth, char *msg, int msg_len, uint8_t *iv) +{ + uint8_t hash[MD5_BYTES]; + uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; + memcpy(auth_key, iv, enc_iv_len); + memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); + +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_md5(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#else + md5_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#endif + + memcpy(auth, hash, MD5_BYTES); + + return 0; +} + +int ss_md5_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len) +{ + uint8_t hash[MD5_BYTES]; + +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_md5(), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#else + md5_hmac(auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#endif + + memcpy(auth, hash, MD5_BYTES); + + return 0; +} + +int ss_md5_hash_func(char *auth, char *msg, int msg_len) +{ + uint8_t hash[MD5_BYTES]; + +#if defined(USE_CRYPTO_OPENSSL) + MD5((uint8_t *)msg, msg_len, (uint8_t *)hash); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), (uint8_t *)msg, msg_len, (uint8_t *)hash); +#else + md5((uint8_t *)msg, msg_len, (uint8_t *)hash); +#endif + + memcpy(auth, hash, MD5_BYTES); + + return 0; +} + +int ss_sha1_hmac(char *auth, char *msg, int msg_len, uint8_t *iv) +{ + uint8_t hash[SHA1_BYTES]; + uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; + memcpy(auth_key, iv, enc_iv_len); + memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); + +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#else + sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#endif + + memcpy(auth, hash, SHA1_BYTES); + + return 0; +} + +int ss_sha1_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len) +{ + uint8_t hash[SHA1_BYTES]; + +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_sha1(), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#else + sha1_hmac(auth_key, key_len, (uint8_t *)msg, msg_len, (uint8_t *)hash); +#endif + + memcpy(auth, hash, SHA1_BYTES); + + return 0; +} + +int ss_sha1_hash_func(char *auth, char *msg, int msg_len) +{ + uint8_t hash[SHA1_BYTES]; +#if defined(USE_CRYPTO_OPENSSL) + SHA1((uint8_t *)msg, msg_len, (uint8_t *)hash); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), (uint8_t *)msg, msg_len, (uint8_t *)hash); +#else + sha1((uint8_t *)msg, msg_len, (uint8_t *)hash); +#endif + + memcpy(auth, hash, SHA1_BYTES); + + return 0; +} + +int ss_aes_128_cbc(char *encrypt, char *out_data, char *key) +{ + unsigned char iv[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +#if defined(USE_CRYPTO_OPENSSL) + AES_KEY aes; + AES_set_encrypt_key((unsigned char*)key, 128, &aes); + AES_cbc_encrypt((const unsigned char *)encrypt, (unsigned char *)out_data, 16, &aes, iv, AES_ENCRYPT); + +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_aes_context aes; + + unsigned char output[16]; + + mbedtls_aes_setkey_enc( &aes, (unsigned char *)key, 128 ); + mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, 16, iv, (unsigned char *)encrypt, output ); + + memcpy(out_data, output, 16); +#else + + aes_context aes; + + unsigned char output[16]; + + aes_setkey_enc( &aes, (unsigned char *)key, 128 ); + aes_crypt_cbc( &aes, AES_ENCRYPT, 16, iv, (unsigned char *)encrypt, output ); + + memcpy(out_data, output, 16); +#endif + + return 0; +} + +int ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity) +{ + uint8_t hash[ONETIMEAUTH_BYTES * 2]; + uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; + memcpy(auth_key, iv, enc_iv_len); + memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); + + brealloc(buf, ONETIMEAUTH_BYTES + buf->len, capacity); + +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type( + MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, + (uint8_t *)hash); +#else + sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash); +#endif + + memcpy(buf->array + buf->len, hash, ONETIMEAUTH_BYTES); + buf->len += ONETIMEAUTH_BYTES; + + return 0; +} + +int +ss_onetimeauth_verify(buffer_t *buf, uint8_t *iv) +{ + uint8_t hash[ONETIMEAUTH_BYTES * 2]; + uint8_t auth_key[MAX_IV_LENGTH + MAX_KEY_LENGTH]; + memcpy(auth_key, iv, enc_iv_len); + memcpy(auth_key + enc_iv_len, enc_key, enc_key_len); + size_t len = buf->len - ONETIMEAUTH_BYTES; + +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type( + MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash); +#else + sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash); +#endif + + return safe_memcmp(buf->array + len, hash, ONETIMEAUTH_BYTES); +} + +int +ss_encrypt_all(buffer_t *plain, int method, int auth, size_t capacity) +{ + if (method > TABLE) { + cipher_ctx_t evp; + cipher_context_init(&evp, method, 1); + + size_t iv_len = enc_iv_len; + int err = 1; + + static buffer_t tmp = { 0, 0, 0, NULL }; + brealloc(&tmp, iv_len + plain->len, capacity); + buffer_t *cipher = &tmp; + cipher->len = plain->len; + + uint8_t iv[MAX_IV_LENGTH]; + + rand_bytes(iv, iv_len); + cipher_context_set_iv(&evp, iv, iv_len, 1); + memcpy(cipher->array, iv, iv_len); + + if (auth) { + ss_onetimeauth(plain, iv, capacity); + cipher->len = plain->len; + } + + if (method >= SALSA20) { + crypto_stream_xor_ic((uint8_t *)(cipher->array + iv_len), + (const uint8_t *)plain->array, (uint64_t)(plain->len), + (const uint8_t *)iv, + 0, enc_key, method); + } else { + err = cipher_context_update(&evp, (uint8_t *)(cipher->array + iv_len), + &cipher->len, (const uint8_t *)plain->array, + plain->len); + } + + if (!err) { + bfree(plain); + cipher_context_release(&evp); + return -1; + } + +#ifdef DEBUG + dump("PLAIN", plain->array, plain->len); + dump("CIPHER", cipher->array + iv_len, cipher->len); +#endif + + cipher_context_release(&evp); + + brealloc(plain, iv_len + cipher->len, capacity); + memcpy(plain->array, cipher->array, iv_len + cipher->len); + plain->len = iv_len + cipher->len; + + return 0; + } else { + char *begin = plain->array; + char *ptr = plain->array; + while (ptr < begin + plain->len) { + *ptr = (char)enc_table[(uint8_t)*ptr]; + ptr++; + } + return 0; + } +} + +int +ss_encrypt(buffer_t *plain, enc_ctx_t *ctx, size_t capacity) +{ + if (ctx != NULL) { + static buffer_t tmp = { 0, 0, 0, NULL }; + + int err = 1; + size_t iv_len = 0; + if (!ctx->init) { + iv_len = enc_iv_len; + } + + brealloc(&tmp, iv_len + plain->len, capacity); + buffer_t *cipher = &tmp; + cipher->len = plain->len; + + if (!ctx->init) { + cipher_context_set_iv(&ctx->evp, ctx->evp.iv, iv_len, 1); + memcpy(cipher->array, ctx->evp.iv, iv_len); + ctx->counter = 0; + ctx->init = 1; + } + + if (enc_method >= SALSA20) { + int padding = ctx->counter % SODIUM_BLOCK_SIZE; + brealloc(cipher, iv_len + (padding + cipher->len) * 2, capacity); + if (padding) { + brealloc(plain, plain->len + padding, capacity); + memmove(plain->array + padding, plain->array, plain->len); + sodium_memzero(plain->array, padding); + } + crypto_stream_xor_ic((uint8_t *)(cipher->array + iv_len), + (const uint8_t *)plain->array, + (uint64_t)(plain->len + padding), + (const uint8_t *)ctx->evp.iv, + ctx->counter / SODIUM_BLOCK_SIZE, enc_key, + enc_method); + ctx->counter += plain->len; + if (padding) { + memmove(cipher->array + iv_len, + cipher->array + iv_len + padding, cipher->len); + } + } else { + err = + cipher_context_update(&ctx->evp, + (uint8_t *)(cipher->array + iv_len), + &cipher->len, (const uint8_t *)plain->array, + plain->len); + if (!err) { + return -1; + } + } + +#ifdef DEBUG + dump("PLAIN", plain->array, plain->len); + dump("CIPHER", cipher->array + iv_len, cipher->len); +#endif + + brealloc(plain, iv_len + cipher->len, capacity); + memcpy(plain->array, cipher->array, iv_len + cipher->len); + plain->len = iv_len + cipher->len; + + return 0; + } else { + char *begin = plain->array; + char *ptr = plain->array; + while (ptr < begin + plain->len) { + *ptr = (char)enc_table[(uint8_t)*ptr]; + ptr++; + } + return 0; + } +} + +int +ss_decrypt_all(buffer_t *cipher, int method, int auth, size_t capacity) +{ + if (method > TABLE) { + size_t iv_len = enc_iv_len; + int ret = 1; + + if (cipher->len <= iv_len) { + return -1; + } + + cipher_ctx_t evp; + cipher_context_init(&evp, method, 0); + + static buffer_t tmp = { 0, 0, 0, NULL }; + brealloc(&tmp, cipher->len, capacity); + buffer_t *plain = &tmp; + plain->len = cipher->len - iv_len; + + uint8_t iv[MAX_IV_LENGTH]; + memcpy(iv, cipher->array, iv_len); + cipher_context_set_iv(&evp, iv, iv_len, 0); + + if (method >= SALSA20) { + crypto_stream_xor_ic((uint8_t *)plain->array, + (const uint8_t *)(cipher->array + iv_len), + (uint64_t)(cipher->len - iv_len), + (const uint8_t *)iv, 0, enc_key, method); + } else { + ret = cipher_context_update(&evp, (uint8_t *)plain->array, &plain->len, + (const uint8_t *)(cipher->array + iv_len), + cipher->len - iv_len); + } + + if (auth || (plain->array[0] & ONETIMEAUTH_FLAG)) { + if (plain->len > ONETIMEAUTH_BYTES) { + ret = !ss_onetimeauth_verify(plain, iv); + if (ret) { + plain->len -= ONETIMEAUTH_BYTES; + } + } else { + ret = 0; + } + } + + if (!ret) { + bfree(cipher); + cipher_context_release(&evp); + return -1; + } + +#ifdef DEBUG + dump("PLAIN", plain->array, plain->len); + dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); +#endif + + cipher_context_release(&evp); + + brealloc(cipher, plain->len, capacity); + memcpy(cipher->array, plain->array, plain->len); + cipher->len = plain->len; + + return 0; + } else { + char *begin = cipher->array; + char *ptr = cipher->array; + while (ptr < begin + cipher->len) { + *ptr = (char)dec_table[(uint8_t)*ptr]; + ptr++; + } + return 0; + } +} + +int +ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity) +{ + if (ctx != NULL) { + static buffer_t tmp = { 0, 0, 0, NULL }; + + size_t iv_len = 0; + int err = 1; + + brealloc(&tmp, cipher->len, capacity); + buffer_t *plain = &tmp; + plain->len = cipher->len; + + if (!ctx->init) { + uint8_t iv[MAX_IV_LENGTH]; + iv_len = enc_iv_len; + plain->len -= iv_len; + + memcpy(iv, cipher->array, iv_len); + cipher_context_set_iv(&ctx->evp, iv, iv_len, 0); + ctx->counter = 0; + ctx->init = 1; + + if (enc_method > RC4) { + if (cache_key_exist(iv_cache, (char *)iv, iv_len)) { + bfree(cipher); + return -1; + } else { + cache_insert(iv_cache, (char *)iv, iv_len, NULL); + } + } + } + + if (enc_method >= SALSA20) { + int padding = ctx->counter % SODIUM_BLOCK_SIZE; + brealloc(plain, (plain->len + padding) * 2, capacity); + + if (padding) { + brealloc(cipher, cipher->len + padding, capacity); + memmove(cipher->array + iv_len + padding, cipher->array + iv_len, + cipher->len - iv_len); + sodium_memzero(cipher->array + iv_len, padding); + } + crypto_stream_xor_ic((uint8_t *)plain->array, + (const uint8_t *)(cipher->array + iv_len), + (uint64_t)(cipher->len - iv_len + padding), + (const uint8_t *)ctx->evp.iv, + ctx->counter / SODIUM_BLOCK_SIZE, enc_key, + enc_method); + ctx->counter += cipher->len - iv_len; + if (padding) { + memmove(plain->array, plain->array + padding, plain->len); + } + } else { + err = cipher_context_update(&ctx->evp, (uint8_t *)plain->array, &plain->len, + (const uint8_t *)(cipher->array + iv_len), + cipher->len - iv_len); + } + + if (!err) { + bfree(cipher); + return -1; + } + +#ifdef DEBUG + dump("PLAIN", plain->array, plain->len); + dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); +#endif + + brealloc(cipher, plain->len, capacity); + memcpy(cipher->array, plain->array, plain->len); + cipher->len = plain->len; + + return 0; + } else { + char *begin = cipher->array; + char *ptr = cipher->array; + while (ptr < begin + cipher->len) { + *ptr = (char)dec_table[(uint8_t)*ptr]; + ptr++; + } + return 0; + } +} + +void +enc_ctx_init(int method, enc_ctx_t *ctx, int enc) +{ + sodium_memzero(ctx, sizeof(enc_ctx_t)); + cipher_context_init(&ctx->evp, method, enc); + + if (enc) { + rand_bytes(ctx->evp.iv, enc_iv_len); + } +} + +void +enc_key_init(int method, const char *pass) +{ + if (method <= TABLE || method >= CIPHER_NUM) { + LOGE("enc_key_init(): Illegal method"); + return; + } + + // Initialize cache + cache_create(&iv_cache, 256, NULL); + +#if defined(USE_CRYPTO_OPENSSL) + OpenSSL_add_all_algorithms(); +#else + cipher_kt_t cipher_info; +#endif + + cipher_t cipher; + memset(&cipher, 0, sizeof(cipher_t)); + + // Initialize sodium for random generator + if (sodium_init() == -1) { + FATAL("Failed to initialize sodium"); + } + + if (method == SALSA20 || method == CHACHA20 || method == CHACHA20IETF) { +#if defined(USE_CRYPTO_OPENSSL) + cipher.info = NULL; + cipher.key_len = supported_ciphers_key_size[method]; + cipher.iv_len = supported_ciphers_iv_size[method]; +#endif +#if defined(USE_CRYPTO_POLARSSL) + cipher.info = &cipher_info; + cipher.info->base = NULL; + cipher.info->key_length = supported_ciphers_key_size[method] * 8; + cipher.info->iv_size = supported_ciphers_iv_size[method]; +#endif +#if defined(USE_CRYPTO_MBEDTLS) + // XXX: key_length changed to key_bitlen in mbed TLS 2.0.0 + cipher.info = &cipher_info; + cipher.info->base = NULL; + cipher.info->key_bitlen = supported_ciphers_key_size[method] * 8; + cipher.info->iv_size = supported_ciphers_iv_size[method]; +#endif + } else { + cipher.info = (cipher_kt_t *)get_cipher_type(method); + } + + if (cipher.info == NULL && cipher.key_len == 0) { + do { +#if defined(USE_CRYPTO_POLARSSL) && defined(USE_CRYPTO_APPLECC) + if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { + cipher_info.base = NULL; + cipher_info.key_length = supported_ciphers_key_size[method] * 8; + cipher_info.iv_size = supported_ciphers_iv_size[method]; + cipher.info = (cipher_kt_t *)&cipher_info; + break; + } +#endif +#if defined(USE_CRYPTO_MBEDTLS) && defined(USE_CRYPTO_APPLECC) + // XXX: key_length changed to key_bitlen in mbed TLS 2.0.0 + if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { + cipher_info.base = NULL; + cipher_info.key_bitlen = supported_ciphers_key_size[method] * 8; + cipher_info.iv_size = supported_ciphers_iv_size[method]; + cipher.info = (cipher_kt_t *)&cipher_info; + break; + } +#endif + LOGE("Cipher %s not found in crypto library", supported_ciphers[method]); + FATAL("Cannot initialize cipher"); + } while (0); + } + + const digest_type_t *md = get_digest_type("MD5"); + if (md == NULL) { + FATAL("MD5 Digest not found in crypto library"); + } + + enc_key_len = bytes_to_key(&cipher, md, (const uint8_t *)pass, enc_key); + + if (enc_key_len == 0) { + FATAL("Cannot generate key and IV"); + } + if (method == RC4_MD5 || method == RC4_MD5_6) { + enc_iv_len = supported_ciphers_iv_size[method]; + } else { + enc_iv_len = cipher_iv_size(&cipher); + } + enc_method = method; +} + +int +enc_init(const char *pass, const char *method) +{ + int m = TABLE; + if (method != NULL) { + for (m = TABLE; m < CIPHER_NUM; m++) + if (strcmp(method, supported_ciphers[m]) == 0) { + break; + } + if (m >= CIPHER_NUM) { + LOGE("Invalid cipher name: %s, use rc4-md5 instead", method); + m = RC4_MD5; + } + } + if (m == TABLE) { + enc_table_init(pass); + } else { + enc_key_init(m, pass); + } + return m; +} + +int +ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity) +{ + int i, j, k; + ssize_t blen = buf->len; + uint32_t cidx = chunk->idx; + + brealloc(chunk->buf, chunk->len + blen, capacity); + brealloc(buf, chunk->len + blen, capacity); + + for (i = 0, j = 0, k = 0; i < blen; i++) { + chunk->buf->array[cidx++] = buf->array[k++]; + + if (cidx == CLEN_BYTES) { + uint16_t clen = ntohs(*((uint16_t *)chunk->buf->array)); + brealloc(chunk->buf, clen + AUTH_BYTES, capacity); + chunk->len = clen; + } + + if (cidx == chunk->len + AUTH_BYTES) { + // Compare hash + uint8_t hash[ONETIMEAUTH_BYTES * 2]; + uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)]; + + uint32_t c = htonl(chunk->counter); + memcpy(key, ctx->evp.iv, enc_iv_len); + memcpy(key + enc_iv_len, &c, sizeof(uint32_t)); +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), + (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), + (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash); +#else + sha1_hmac(key, enc_iv_len + sizeof(uint32_t), + (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash); +#endif + + if (safe_memcmp(hash, chunk->buf->array + CLEN_BYTES, ONETIMEAUTH_BYTES) != 0) { + return 0; + } + + // Copy chunk back to buffer + memmove(buf->array + j + chunk->len, buf->array + k, blen - i - 1); + memcpy(buf->array + j, chunk->buf->array + AUTH_BYTES, chunk->len); + + // Reset the base offset + j += chunk->len; + k = j; + cidx = 0; + chunk->counter++; + } + } + + buf->len = j; + chunk->idx = cidx; + return 1; +} + +int +ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity) +{ + ssize_t blen = buf->len; + uint16_t chunk_len = htons((uint16_t)blen); + uint8_t hash[ONETIMEAUTH_BYTES * 2]; + uint8_t key[MAX_IV_LENGTH + sizeof(uint32_t)]; + uint32_t c = htonl(*counter); + + brealloc(buf, AUTH_BYTES + blen, capacity); + memcpy(key, ctx->evp.iv, enc_iv_len); + memcpy(key + enc_iv_len, &c, sizeof(uint32_t)); +#if defined(USE_CRYPTO_OPENSSL) + HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash, NULL); +#elif defined(USE_CRYPTO_MBEDTLS) + mbedtls_md_hmac(mbedtls_md_info_from_type( + MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash); +#else + sha1_hmac(key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash); +#endif + + memmove(buf->array + AUTH_BYTES, buf->array, blen); + memcpy(buf->array + CLEN_BYTES, hash, ONETIMEAUTH_BYTES); + memcpy(buf->array, &chunk_len, CLEN_BYTES); + + *counter = *counter + 1; + buf->len = blen + AUTH_BYTES; + + return 0; +} diff --git a/shadowsocksr-libev/src/server/encrypt.h b/shadowsocksr-libev/src/server/encrypt.h new file mode 100644 index 00000000..3bb7940a --- /dev/null +++ b/shadowsocksr-libev/src/server/encrypt.h @@ -0,0 +1,222 @@ +/* + * encrypt.h - Define the enryptor's interface + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _ENCRYPT_H +#define _ENCRYPT_H + +#ifndef __MINGW32__ +#include +#else + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +#endif + +#include +#include +#include +#include + +#if defined(USE_CRYPTO_OPENSSL) + +#include +#include +#include +typedef EVP_CIPHER cipher_kt_t; +typedef EVP_CIPHER_CTX cipher_evp_t; +typedef EVP_MD digest_type_t; +#define MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH +#define MAX_IV_LENGTH EVP_MAX_IV_LENGTH +#define MAX_MD_SIZE EVP_MAX_MD_SIZE + +#elif defined(USE_CRYPTO_POLARSSL) + +#include +#include +typedef cipher_info_t cipher_kt_t; +typedef cipher_context_t cipher_evp_t; +typedef md_info_t digest_type_t; +#define MAX_KEY_LENGTH 64 +#define MAX_IV_LENGTH POLARSSL_MAX_IV_LENGTH +#define MAX_MD_SIZE POLARSSL_MD_MAX_SIZE + +#elif defined(USE_CRYPTO_MBEDTLS) + +#include +#include +typedef mbedtls_cipher_info_t cipher_kt_t; +typedef mbedtls_cipher_context_t cipher_evp_t; +typedef mbedtls_md_info_t digest_type_t; +#define MAX_KEY_LENGTH 64 +#define MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH +#define MAX_MD_SIZE MBEDTLS_MD_MAX_SIZE + +/* we must have MBEDTLS_CIPHER_MODE_CFB defined */ +#if !defined(MBEDTLS_CIPHER_MODE_CFB) +#error Cipher Feedback mode a.k.a CFB not supported by your mbed TLS. +#endif + +#endif + +#ifdef USE_CRYPTO_APPLECC + +#include + +#define kCCAlgorithmInvalid UINT32_MAX +#define kCCContextValid 0 +#define kCCContextInvalid -1 + +typedef struct { + CCCryptorRef cryptor; + int valid; + CCOperation encrypt; + CCAlgorithm cipher; + CCMode mode; + CCPadding padding; + uint8_t iv[MAX_IV_LENGTH]; + uint8_t key[MAX_KEY_LENGTH]; + size_t iv_len; + size_t key_len; +} cipher_cc_t; + +#endif + +typedef struct { + cipher_evp_t *evp; +#ifdef USE_CRYPTO_APPLECC + cipher_cc_t cc; +#endif + uint8_t iv[MAX_IV_LENGTH]; +} cipher_ctx_t; + +typedef struct { + cipher_kt_t *info; + size_t iv_len; + size_t key_len; +} cipher_t; + +#ifdef HAVE_STDINT_H +#include +#elif HAVE_INTTYPES_H +#include +#endif + +#define SODIUM_BLOCK_SIZE 64 + +enum crpher_index { + NONE = -1, + TABLE = 0, + RC4, + RC4_MD5_6, + RC4_MD5, + AES_128_CFB, + AES_192_CFB, + AES_256_CFB, + AES_128_CTR, + AES_192_CTR, + AES_256_CTR, + BF_CFB, + CAMELLIA_128_CFB, + CAMELLIA_192_CFB, + CAMELLIA_256_CFB, + CAST5_CFB, + DES_CFB, + IDEA_CFB, + RC2_CFB, + SEED_CFB, + SALSA20, + CHACHA20, + CHACHA20IETF, + CIPHER_NUM, +}; + +#define ONETIMEAUTH_FLAG 0x10 +#define ADDRTYPE_MASK 0xEF + +#define ONETIMEAUTH_BYTES 10U +#define MD5_BYTES 16U +#define SHA1_BYTES 20U +#define CLEN_BYTES 2U +#define AUTH_BYTES (ONETIMEAUTH_BYTES + CLEN_BYTES) + +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) + +typedef struct buffer { + size_t idx; + size_t len; + size_t capacity; + char *array; +} buffer_t; + +typedef struct chunk { + uint32_t idx; + uint32_t len; + uint32_t counter; + buffer_t *buf; +} chunk_t; + +typedef struct enc_ctx { + uint8_t init; + uint64_t counter; + cipher_ctx_t evp; +} enc_ctx_t; + +void bytes_to_key_with_size(const char *pass, size_t len, uint8_t *md, size_t md_size); + +int ss_encrypt_all(buffer_t *plaintext, int method, int auth, size_t capacity); +int ss_decrypt_all(buffer_t *ciphertext, int method, int auth, size_t capacity); +int ss_encrypt(buffer_t *plaintext, enc_ctx_t *ctx, size_t capacity); +int ss_decrypt(buffer_t *ciphertext, enc_ctx_t *ctx, size_t capacity); + +void enc_ctx_init(int method, enc_ctx_t *ctx, int enc); +int enc_init(const char *pass, const char *method); +int enc_get_iv_len(void); +uint8_t* enc_get_key(void); +int enc_get_key_len(void); +void cipher_context_release(cipher_ctx_t *evp); +unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md); + +int ss_md5_hmac(char *auth, char *msg, int msg_len, uint8_t *iv); +int ss_md5_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len); +int ss_md5_hash_func(char *auth, char *msg, int msg_len); +int ss_sha1_hmac(char *auth, char *msg, int msg_len, uint8_t *iv); +int ss_sha1_hmac_with_key(char *auth, char *msg, int msg_len, uint8_t *auth_key, int key_len); +int ss_sha1_hash_func(char *auth, char *msg, int msg_len); +int ss_aes_128_cbc(char *encrypt, char *out_data, char *key); +int ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity); +int ss_onetimeauth_verify(buffer_t *buf, uint8_t *iv); + +int ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity); +int ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity); + +int balloc(buffer_t *ptr, size_t capacity); +int brealloc(buffer_t *ptr, size_t len, size_t capacity); +void bfree(buffer_t *ptr); + +#endif // _ENCRYPT_H diff --git a/shadowsocksr-libev/src/server/http.c b/shadowsocksr-libev/src/server/http.c new file mode 100644 index 00000000..3bd4a322 --- /dev/null +++ b/shadowsocksr-libev/src/server/http.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2011 and 2012, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include /* malloc() */ +#include /* strncpy() */ +#include /* strncasecmp() */ +#include /* isblank() */ + +#include "http.h" +#include "protocol.h" + +#define SERVER_NAME_LEN 256 + +static int parse_http_header(const char *, size_t, char **); +static int get_header(const char *, const char *, int, char **); +static int next_header(const char **, int *); + +static const protocol_t http_protocol_st = { + .default_port = 80, + .parse_packet = &parse_http_header, +}; +const protocol_t *const http_protocol = &http_protocol_st; + +/* + * Parses a HTTP request for the Host: header + * + * Returns: + * >=0 - length of the hostname and updates *hostname + * caller is responsible for freeing *hostname + * -1 - Incomplete request + * -2 - No Host header included in this request + * -3 - Invalid hostname pointer + * -4 - malloc failure + * < -4 - Invalid HTTP request + * + */ +static int +parse_http_header(const char *data, size_t data_len, char **hostname) +{ + int result, i; + + if (hostname == NULL) + return -3; + + if (data_len == 0) + return -1; + + result = get_header("Host:", data, data_len, hostname); + if (result < 0) + return result; + + /* + * if the user specifies the port in the request, it is included here. + * Host: example.com:80 + * so we trim off port portion + */ + for (i = result - 1; i >= 0; i--) + if ((*hostname)[i] == ':') { + (*hostname)[i] = '\0'; + result = i; + break; + } + + return result; +} + +static int +get_header(const char *header, const char *data, int data_len, char **value) +{ + int len, header_len; + + header_len = strlen(header); + + /* loop through headers stopping at first blank line */ + while ((len = next_header(&data, &data_len)) != 0) + if (len > header_len && strncasecmp(header, data, header_len) == 0) { + /* Eat leading whitespace */ + while (header_len < len && isblank(data[header_len])) + header_len++; + + *value = malloc(len - header_len + 1); + if (*value == NULL) + return -4; + + strncpy(*value, data + header_len, len - header_len); + (*value)[len - header_len] = '\0'; + + return len - header_len; + } + + /* If there is no data left after reading all the headers then we do not + * have a complete HTTP request, there must be a blank line */ + if (data_len == 0) + return -1; + + return -2; +} + +static int +next_header(const char **data, int *len) +{ + int header_len; + + /* perhaps we can optimize this to reuse the value of header_len, rather + * than scanning twice. + * Walk our data stream until the end of the header */ + while (*len > 2 && (*data)[0] != '\r' && (*data)[1] != '\n') { + (*len)--; + (*data)++; + } + + /* advanced past the pair */ + *data += 2; + *len -= 2; + + /* Find the length of the next header */ + header_len = 0; + while (*len > header_len + 1 + && (*data)[header_len] != '\r' + && (*data)[header_len + 1] != '\n') + header_len++; + + return header_len; +} diff --git a/shadowsocksr-libev/src/server/http.h b/shadowsocksr-libev/src/server/http.h new file mode 100644 index 00000000..914815ae --- /dev/null +++ b/shadowsocksr-libev/src/server/http.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 and 2012, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef HTTP_H +#define HTTP_H + +#include +#include "protocol.h" + +const protocol_t *const http_protocol; + +#endif diff --git a/shadowsocksr-libev/src/server/http_simple.c b/shadowsocksr-libev/src/server/http_simple.c new file mode 100644 index 00000000..cee15c52 --- /dev/null +++ b/shadowsocksr-libev/src/server/http_simple.c @@ -0,0 +1,626 @@ + +#include "http_simple.h" + +static char* g_useragent[] = { + "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0", + "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/44.0", + "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", + "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/27.0.1453.93 Chrome/27.0.1453.93 Safari/537.36", + "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0", + "Mozilla/5.0 (compatible; WOW64; MSIE 10.0; Windows NT 6.2)", + "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C)", + "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko", + "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/BuildID) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", + "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", +}; + +static int g_useragent_index = -1; + +typedef struct http_simple_local_data { + int has_sent_header; + int has_recv_header; + char *encode_buffer; + int host_matched; + char *recv_buffer; + int recv_buffer_size; +}http_simple_local_data; + +void http_simple_local_data_init(http_simple_local_data* local) { + local->has_sent_header = 0; + local->has_recv_header = 0; + local->encode_buffer = NULL; + + local->recv_buffer = malloc(0); + local->recv_buffer_size = 0; + + local->host_matched = 0; + + if (g_useragent_index == -1) { + g_useragent_index = xorshift128plus() % (sizeof(g_useragent) / sizeof(*g_useragent)); + } +} + +obfs * http_simple_new_obfs() { + obfs * self = new_obfs(); + self->l_data = malloc(sizeof(http_simple_local_data)); + http_simple_local_data_init((http_simple_local_data*)self->l_data); + return self; +} + +void http_simple_dispose(obfs *self) { + http_simple_local_data *local = (http_simple_local_data*)self->l_data; + if (local->encode_buffer != NULL) { + free(local->encode_buffer); + local->encode_buffer = NULL; + } + free(local); + dispose_obfs(self); +} + +char http_simple_hex(char c) { + if (c < 10) return c + '0'; + return c - 10 + 'a'; +} + +int get_data_from_http_header(char *data, char **outdata) { + char *delim = "\r\n"; + char *delim_hex = "%"; + int outlength = 0; + + char *buf = *outdata; + char *p_line; + p_line = strtok(data, delim); + + //while(p_line) + { + char *p_hex; + + p_hex = strtok(p_line, delim_hex); + + while((p_hex = strtok(NULL, delim_hex))) + { + char hex = 0; + + if(strlen(p_hex) <= 0) + { + continue; + } + + if(strlen(p_hex) > 2) + { + char *c_hex = (char*)malloc(2); + memcpy(c_hex, p_hex, 2); + hex = (char)strtol(c_hex, NULL, 16); + free(c_hex); + } + else + { + hex = (char)strtol(p_hex, NULL, 16); + } + + outlength += 1; + buf = (char*)realloc(buf, outlength); + buf[outlength - 1] = hex; + } + + //p_line = strtok(p_line, delim); + } + *outdata = buf; + return outlength; +} + +void get_host_from_http_header(char *data, char **host) { + char* data_begin = strstr(data, "Host: "); + + if(data_begin == NULL) + { + return; + } + + data_begin += 6; + char* data_end = strstr(data_begin, "\r\n"); + char* data_end_port = strstr(data_begin, ":"); + + int host_length = 0; + + if(data_end_port != NULL) + { + host_length = data_end_port - data_begin; + } + else + { + host_length = data_end - data_begin; + } + + if(host_length <= 0) + { + return; + } + + memset(*host, 0x00, 1024); + memcpy(*host, data_begin, host_length); +} + +void http_simple_encode_head(http_simple_local_data *local, char *data, int datalength) { + if (local->encode_buffer == NULL) { + local->encode_buffer = (char*)malloc(datalength * 3 + 1); + } + int pos = 0; + for (; pos < datalength; ++pos) { + local->encode_buffer[pos * 3] = '%'; + local->encode_buffer[pos * 3 + 1] = http_simple_hex(((unsigned char)data[pos] >> 4)); + local->encode_buffer[pos * 3 + 2] = http_simple_hex(data[pos] & 0xF); + } + local->encode_buffer[pos * 3] = 0; +} + +int http_simple_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { + char *encryptdata = *pencryptdata; + http_simple_local_data *local = (http_simple_local_data*)self->l_data; + if (local->has_sent_header) { + return datalength; + } + char hosts[1024]; + char * phost[128]; + int host_num = 0; + int pos; + char hostport[128]; + int head_size = self->server.head_len + (xorshift128plus() & 0x3F); + int outlength; + char * out_buffer = (char*)malloc(datalength + 2048); + char * body_buffer = NULL; + if (head_size > datalength) + head_size = datalength; + http_simple_encode_head(local, encryptdata, head_size); + if (self->server.param && strlen(self->server.param) == 0) + self->server.param = NULL; + strncpy(hosts, self->server.param ? self->server.param : self->server.host, sizeof hosts); + phost[host_num++] = hosts; + for (pos = 0; hosts[pos]; ++pos) { + if (hosts[pos] == ',') { + phost[host_num++] = &hosts[pos + 1]; + hosts[pos] = 0; + } else if (hosts[pos] == '#') { + char * body_pointer = &hosts[pos + 1]; + char * p; + int trans_char = 0; + p = body_buffer = (char*)malloc(2048); + for ( ; *body_pointer; ++body_pointer) { + if (*body_pointer == '\\') { + trans_char = 1; + continue; + } else if (*body_pointer == '\n') { + *p = '\r'; + *++p = '\n'; + continue; + } + if (trans_char) { + if (*body_pointer == '\\' ) { + *p = '\\'; + } else if (*body_pointer == 'n' ) { + *p = '\r'; + *++p = '\n'; + } else { + *p = '\\'; + *p = *body_pointer; + } + trans_char = 0; + } else { + *p = *body_pointer; + } + ++p; + } + *p = 0; + hosts[pos] = 0; + break; + } + } + host_num = xorshift128plus() % host_num; + if (self->server.port == 80) + sprintf(hostport, "%s", phost[host_num]); + else + sprintf(hostport, "%s:%d", phost[host_num], self->server.port); + if (body_buffer) { + sprintf(out_buffer, + "GET /%s HTTP/1.1\r\n" + "Host: %s\r\n" + "%s\r\n\r\n", + local->encode_buffer, + hostport, + body_buffer); + } else { + sprintf(out_buffer, + "GET /%s HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: %s\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + "Accept-Language: en-US,en;q=0.8\r\n" + "Accept-Encoding: gzip, deflate\r\n" + "DNT: 1\r\n" + "Connection: keep-alive\r\n" + "\r\n", + local->encode_buffer, + hostport, + g_useragent[g_useragent_index] + ); + } + //LOGI("http header: %s", out_buffer); + outlength = strlen(out_buffer); + memmove(out_buffer + outlength, encryptdata + head_size, datalength - head_size); + outlength += datalength - head_size; + local->has_sent_header = 1; + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + memmove(encryptdata, out_buffer, outlength); + free(out_buffer); + if (body_buffer != NULL) + free(body_buffer); + if (local->encode_buffer != NULL) { + free(local->encode_buffer); + local->encode_buffer = NULL; + } + return outlength; +} + +int http_simple_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { + char *encryptdata = *pencryptdata; + http_simple_local_data *local = (http_simple_local_data*)self->l_data; + if (local->has_sent_header) { + return datalength; + } + int outlength; + char * out_buffer = (char*)malloc(datalength + 2048); + + time_t now; + struct tm *tm_now; + char datetime[200]; + + time(&now); + tm_now = localtime(&now); + strftime(datetime, 200, "%a, %d %b %Y %H:%M:%S GMT", tm_now); + + sprintf(out_buffer, + "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nContent-Type: text/html\r\nDate: " + "%s" + "\r\nServer: nginx\r\nVary: Accept-Encoding\r\n\r\n", + datetime); + + outlength = strlen(out_buffer); + memmove(out_buffer + outlength, encryptdata, datalength); + outlength += datalength; + + local->has_sent_header = 1; + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + memmove(encryptdata, out_buffer, outlength); + free(out_buffer); + return outlength; +} + +int http_simple_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { + char *encryptdata = *pencryptdata; + http_simple_local_data *local = (http_simple_local_data*)self->l_data; + *needsendback = 0; + if (local->has_recv_header) { + return datalength; + } + char* data_begin = strstr(encryptdata, "\r\n\r\n"); + if (data_begin) { + int outlength; + data_begin += 4; + local->has_recv_header = 1; + outlength = datalength - (data_begin - encryptdata); + memmove(encryptdata, data_begin, outlength); + return outlength; + } else { + return 0; + } +} + +int http_simple_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { + char *encryptdata = *pencryptdata; + http_simple_local_data *local = (http_simple_local_data*)self->l_data; + *needsendback = 0; + if (local->has_recv_header) { + return datalength; + } + + if(datalength != 0) + { + local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size + datalength); + memmove(local->recv_buffer + local->recv_buffer_size, encryptdata, datalength); + local->recv_buffer_size += datalength; + + int outlength = local->recv_buffer_size; + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + memcpy(encryptdata, local->recv_buffer, local->recv_buffer_size); + } + + if(local->recv_buffer_size > 10) + { + if(strstr(local->recv_buffer, "GET /") == local->recv_buffer || strstr(local->recv_buffer, "POST /") == local->recv_buffer) + { + if(local->recv_buffer_size > 65536) + { + free(local->recv_buffer); + local->recv_buffer = malloc(0); + local->recv_buffer_size = 0; + local->has_sent_header = 1; + local->has_recv_header = 1; + LOGE("http_simple: over size"); + return -1; + } + } + else + { + free(local->recv_buffer); + local->recv_buffer = malloc(0); + local->recv_buffer_size = 0; + local->has_sent_header = 1; + local->has_recv_header = 1; + LOGE("http_simple: not match begin"); + return -1; + } + } + else + { + LOGE("http_simple: too short"); + local->has_sent_header = 1; + local->has_recv_header = 1; + return -1; + } + + char* data_begin = strstr(encryptdata, "\r\n\r\n"); + if (data_begin) { + int outlength; + char *ret_buf = (char*)malloc(*capacity); + memset(ret_buf, 0x00, *capacity); + int ret_buf_len = 0; + ret_buf_len = get_data_from_http_header(encryptdata, &ret_buf); + + if (self->server.param && strlen(self->server.param) == 0) + { + self->server.param = NULL; + } + else + { + if(local->host_matched == 0) + { + char *host = (char*)malloc(1024); + get_host_from_http_header(local->recv_buffer, &host); + char hosts[1024]; + char * phost[128]; + int host_num = 0; + int pos = 0; + int is_match = 0; + char * body_buffer = NULL; + strncpy(hosts, self->server.param, sizeof hosts); + phost[host_num++] = hosts; + + for (pos = 0; hosts[pos]; ++pos) { + if (hosts[pos] == ',') { + phost[host_num++] = &hosts[pos + 1]; + hosts[pos] = 0; + } else if (hosts[pos] == '#') { + char * body_pointer = &hosts[pos + 1]; + char * p; + int trans_char = 0; + p = body_buffer = (char*)malloc(2048); + for ( ; *body_pointer; ++body_pointer) { + if (*body_pointer == '\\') { + trans_char = 1; + continue; + } else if (*body_pointer == '\n') { + *p = '\r'; + *++p = '\n'; + continue; + } + if (trans_char) { + if (*body_pointer == '\\' ) { + *p = '\\'; + } else if (*body_pointer == 'n' ) { + *p = '\r'; + *++p = '\n'; + } else { + *p = '\\'; + *p = *body_pointer; + } + trans_char = 0; + } else { + *p = *body_pointer; + } + ++p; + } + *p = 0; + hosts[pos] = 0; + break; + } + } + + + for(pos = 0; pos < host_num; pos++) + { + if(strcmp(phost[pos], host) == 0) + { + is_match = 1; + local->host_matched = 1; + } + } + + if(is_match == 0) + { + free(local->recv_buffer); + local->recv_buffer = malloc(0); + local->recv_buffer_size = 0; + local->has_sent_header = 1; + local->has_recv_header = 1; + LOGE("http_simple: not match host, host: %s", host); + return -1; + } + + free(host); + } + } + + if(ret_buf_len <= 0) + { + return -1; + } + + data_begin += 4; + local->has_recv_header = 1; + + ret_buf = (char*)realloc(ret_buf, ret_buf_len + datalength - (data_begin - encryptdata)); + outlength = ret_buf_len + datalength - (data_begin - encryptdata); + + memcpy(ret_buf + ret_buf_len, data_begin, datalength - (data_begin - encryptdata)); + + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + + memcpy(encryptdata, ret_buf, outlength); + free(ret_buf); + return outlength; + } else { + return 0; + } +} + +void boundary(char result[]) +{ + char *str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + int i,lstr; + char ss[3] = {0}; + lstr = strlen(str); + srand((unsigned int)time((time_t *)NULL)); + for(i = 0; i < 32; ++i) + { + sprintf(ss, "%c", str[(rand()%lstr)]); + strcat(result, ss); + } +} + +int http_post_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { + char *encryptdata = *pencryptdata; + http_simple_local_data *local = (http_simple_local_data*)self->l_data; + if (local->has_sent_header) { + return datalength; + } + char hosts[1024]; + char * phost[128]; + int host_num = 0; + int pos; + char hostport[128]; + int head_size = self->server.head_len + (xorshift128plus() & 0x3F); + int outlength; + char * out_buffer = (char*)malloc(datalength + 2048); + char * body_buffer = NULL; + if (head_size > datalength) + head_size = datalength; + http_simple_encode_head(local, encryptdata, head_size); + if (self->server.param && strlen(self->server.param) == 0) + self->server.param = NULL; + strncpy(hosts, self->server.param ? self->server.param : self->server.host, sizeof hosts); + phost[host_num++] = hosts; + for (pos = 0; hosts[pos]; ++pos) { + if (hosts[pos] == ',') { + phost[host_num++] = &hosts[pos + 1]; + hosts[pos] = 0; + } else if (hosts[pos] == '#') { + char * body_pointer = &hosts[pos + 1]; + char * p; + int trans_char = 0; + p = body_buffer = (char*)malloc(2048); + for ( ; *body_pointer; ++body_pointer) { + if (*body_pointer == '\\') { + trans_char = 1; + continue; + } else if (*body_pointer == '\n') { + *p = '\r'; + *++p = '\n'; + continue; + } + if (trans_char) { + if (*body_pointer == '\\' ) { + *p = '\\'; + } else if (*body_pointer == 'n' ) { + *p = '\r'; + *++p = '\n'; + } else { + *p = '\\'; + *p = *body_pointer; + } + trans_char = 0; + } else { + *p = *body_pointer; + } + ++p; + } + *p = 0; + hosts[pos] = 0; + break; + } + } + host_num = xorshift128plus() % host_num; + if (self->server.port == 80) + sprintf(hostport, "%s", phost[host_num]); + else + sprintf(hostport, "%s:%d", phost[host_num], self->server.port); + if (body_buffer) { + sprintf(out_buffer, + "POST /%s HTTP/1.1\r\n" + "Host: %s\r\n" + "%s\r\n\r\n", + local->encode_buffer, + hostport, + body_buffer); + } else { + char result[33] = {0}; + boundary(result); + sprintf(out_buffer, + "POST /%s HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: %s\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" + "Accept-Language: en-US,en;q=0.8\r\n" + "Accept-Encoding: gzip, deflate\r\n" + "Content-Type: multipart/form-data; boundary=%s\r\n" + "DNT: 1\r\n" + "Connection: keep-alive\r\n" + "\r\n", + local->encode_buffer, + hostport, + g_useragent[g_useragent_index], + result + ); + } + //LOGI("http header: %s", out_buffer); + outlength = strlen(out_buffer); + memmove(out_buffer + outlength, encryptdata + head_size, datalength - head_size); + outlength += datalength - head_size; + local->has_sent_header = 1; + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + memmove(encryptdata, out_buffer, outlength); + free(out_buffer); + if (body_buffer != NULL) + free(body_buffer); + if (local->encode_buffer != NULL) { + free(local->encode_buffer); + local->encode_buffer = NULL; + } + return outlength; +} diff --git a/shadowsocksr-libev/src/server/http_simple.h b/shadowsocksr-libev/src/server/http_simple.h new file mode 100644 index 00000000..cce24cc1 --- /dev/null +++ b/shadowsocksr-libev/src/server/http_simple.h @@ -0,0 +1,21 @@ +/* + * http_simple.h - Define shadowsocksR server's buffers and callbacks + * + * Copyright (C) 2015 - 2016, Break Wa11 + */ + +#ifndef _HTTP_SIMPLE_H +#define _HTTP_SIMPLE_H + +obfs * http_simple_new_obfs(); +void http_simple_dispose(obfs *self); + +int http_simple_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); +int http_simple_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); + +int http_post_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); + +int http_simple_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); +int http_simple_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); + +#endif // _HTTP_SIMPLE_H diff --git a/shadowsocksr-libev/src/server/jconf.c b/shadowsocksr-libev/src/server/jconf.c new file mode 100644 index 00000000..494aa5f4 --- /dev/null +++ b/shadowsocksr-libev/src/server/jconf.c @@ -0,0 +1,260 @@ +/* + * jconf.c - Parse the JSON format config file + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#include +#include +#include +#include +#include + +#include "utils.h" +#include "jconf.h" +#include "json.h" +#include "string.h" + +#include + +#define check_json_value_type(value, expected_type, message) \ + do { \ + if ((value)->type != (expected_type)) \ + FATAL((message)); \ + } while(0) + +static char * +to_string(const json_value *value) +{ + if (value->type == json_string) { + return ss_strndup(value->u.string.ptr, value->u.string.length); + } else if (value->type == json_integer) { + return strdup(ss_itoa(value->u.integer)); + } else if (value->type == json_null) { + return "null"; + } else { + LOGE("%d", value->type); + FATAL("Invalid config format."); + } + return 0; +} + +void +free_addr(ss_addr_t *addr) +{ + ss_free(addr->host); + ss_free(addr->port); +} + +void +parse_addr(const char *str, ss_addr_t *addr) +{ + int ipv6 = 0, ret = -1, n = 0; + char *pch; + + struct cork_ip ip; + if (cork_ip_init(&ip, str) != -1) { + addr->host = strdup(str); + addr->port = NULL; + return; + } + + pch = strchr(str, ':'); + while (pch != NULL) { + n++; + ret = pch - str; + pch = strchr(pch + 1, ':'); + } + if (n > 1) { + ipv6 = 1; + if (str[ret - 1] != ']') { + ret = -1; + } + } + + if (ret == -1) { + if (ipv6) { + addr->host = ss_strndup(str + 1, strlen(str) - 2); + } else { + addr->host = strdup(str); + } + addr->port = NULL; + } else { + if (ipv6) { + addr->host = ss_strndup(str + 1, ret - 2); + } else { + addr->host = ss_strndup(str, ret); + } + addr->port = strdup(str + ret + 1); + } +} + +jconf_t * +read_jconf(const char *file) +{ + static jconf_t conf; + + memset(&conf, 0, sizeof(jconf_t)); + + char *buf; + json_value *obj; + + FILE *f = fopen(file, "rb"); + if (f == NULL) { + FATAL("Invalid config path."); + } + + fseek(f, 0, SEEK_END); + long pos = ftell(f); + fseek(f, 0, SEEK_SET); + + if (pos >= MAX_CONF_SIZE) { + FATAL("Too large config file."); + } + + buf = ss_malloc(pos + 1); + if (buf == NULL) { + FATAL("No enough memory."); + } + + int nread = fread(buf, pos, 1, f); + if (!nread) { + FATAL("Failed to read the config file."); + } + fclose(f); + + buf[pos] = '\0'; // end of string + + json_settings settings = { 0UL, 0, NULL, NULL, NULL }; + char error_buf[512]; + obj = json_parse_ex(&settings, buf, pos, error_buf); + + if (obj == NULL) { + FATAL(error_buf); + } + + if (obj->type == json_object) { + unsigned int i, j; + for (i = 0; i < obj->u.object.length; i++) { + char *name = obj->u.object.values[i].name; + json_value *value = obj->u.object.values[i].value; + if (strcmp(name, "server") == 0) { + if (value->type == json_array) { + for (j = 0; j < value->u.array.length; j++) { + if (j >= MAX_REMOTE_NUM) { + break; + } + json_value *v = value->u.array.values[j]; + char *addr_str = to_string(v); + parse_addr(addr_str, conf.remote_addr + j); + ss_free(addr_str); + conf.remote_num = j + 1; + } + } else if (value->type == json_string) { + conf.remote_addr[0].host = to_string(value); + conf.remote_addr[0].port = NULL; + conf.remote_num = 1; + } + } else if (strcmp(name, "port_password") == 0) { + if (value->type == json_object) { + for (j = 0; j < value->u.object.length; j++) { + if (j >= MAX_PORT_NUM) { + break; + } + json_value *v = value->u.object.values[j].value; + if (v->type == json_string) { + conf.port_password[j].port = ss_strndup(value->u.object.values[j].name, + value->u.object.values[j].name_length); + conf.port_password[j].password = to_string(v); + conf.port_password_num = j + 1; + } + } + } + } else if (strcmp(name, "server_port") == 0) { + conf.remote_port = to_string(value); + } else if (strcmp(name, "local_address") == 0) { + conf.local_addr = to_string(value); + } else if (strcmp(name, "local_port") == 0) { + conf.local_port = to_string(value); + } else if (strcmp(name, "password") == 0) { + conf.password = to_string(value); + } else if (strcmp(name, "protocol") == 0) { // SSR + conf.protocol = to_string(value); + } else if (strcmp(name, "protocol_param") == 0) { // SSR + conf.protocol_param = to_string(value); + } else if (strcmp(name, "method") == 0) { + conf.method = to_string(value); + } else if (strcmp(name, "obfs") == 0) { // SSR + conf.obfs = to_string(value); + } else if (strcmp(name, "obfs_param") == 0) { // SSR + conf.obfs_param = to_string(value); + } else if (strcmp(name, "timeout") == 0) { + conf.timeout = to_string(value); + } else if (strcmp(name, "user") == 0) { + conf.user = to_string(value); + } else if (strcmp(name, "fast_open") == 0) { + check_json_value_type(value, json_boolean, + "invalid config file: option 'fast_open' must be a boolean"); + conf.fast_open = value->u.boolean; + } else if (strcmp(name, "auth") == 0) { + check_json_value_type(value, json_boolean, + "invalid config file: option 'auth' must be a boolean"); + conf.auth = value->u.boolean; + } else if (strcmp(name, "nofile") == 0) { + check_json_value_type(value, json_integer, + "invalid config file: option 'nofile' must be an integer"); + conf.nofile = value->u.integer; + } else if (strcmp(name, "nameserver") == 0) { + conf.nameserver = to_string(value); + } else if (strcmp(name, "tunnel_address") == 0) { + conf.tunnel_address = to_string(value); + } else if (strcmp(name, "mode") == 0) { + char *mode_str = to_string(value); + + if (strcmp(mode_str, "tcp_only") == 0) + conf.mode = TCP_ONLY; + else if (strcmp(mode_str, "tcp_and_udp") == 0) + conf.mode = TCP_AND_UDP; + else if (strcmp(mode_str, "udp_only") == 0) + conf.mode = UDP_ONLY; + else + LOGI("ignore unknown mode: %s, use tcp_only as fallback", + mode_str); + ss_free(mode_str); + } else if (strcmp(name, "mtu") == 0) { + check_json_value_type(value, json_integer, + "invalid config file: option 'mtu' must be an integer"); + conf.mtu = value->u.integer; + } else if (strcmp(name, "mptcp") == 0) { + check_json_value_type(value, json_boolean, + "invalid config file: option 'mptcp' must be a boolean"); + conf.mptcp = value->u.boolean; + } else if (strcmp(name, "ipv6_first") == 0) { + check_json_value_type(value, json_boolean, + "invalid config file: option 'ipv6_first' must be a boolean"); + conf.ipv6_first = value->u.boolean; + } + } + } else { + FATAL("Invalid config file"); + } + + ss_free(buf); + json_value_free(obj); + return &conf; +} diff --git a/shadowsocksr-libev/src/server/jconf.h b/shadowsocksr-libev/src/server/jconf.h new file mode 100644 index 00000000..9a7e5e33 --- /dev/null +++ b/shadowsocksr-libev/src/server/jconf.h @@ -0,0 +1,78 @@ +/* + * jconf.h - Define the config data structure + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _JCONF_H +#define _JCONF_H + +#define MAX_PORT_NUM 1024 +#define MAX_REMOTE_NUM 10 +#define MAX_CONF_SIZE 128 * 1024 +#define MAX_DNS_NUM 4 +#define MAX_CONNECT_TIMEOUT 10 +#define MAX_REQUEST_TIMEOUT 60 +#define MIN_UDP_TIMEOUT 10 + +#define TCP_ONLY 0 +#define TCP_AND_UDP 1 +#define UDP_ONLY 3 + +typedef struct { + char *host; + char *port; +} ss_addr_t; + +typedef struct { + char *port; + char *password; +} ss_port_password_t; + +typedef struct { + int remote_num; + ss_addr_t remote_addr[MAX_REMOTE_NUM]; + int port_password_num; + ss_port_password_t port_password[MAX_PORT_NUM]; + char *remote_port; + char *local_addr; + char *local_port; + char *password; + char *protocol; // SSR + char *protocol_param; // SSR + char *method; + char *obfs; // SSR + char *obfs_param; // SSR + char *timeout; + char *user; + int auth; + int fast_open; + int nofile; + char *nameserver; + char *tunnel_address; + int mode; + int mtu; + int mptcp; + int ipv6_first; +} jconf_t; + +jconf_t *read_jconf(const char *file); +void parse_addr(const char *str, ss_addr_t *addr); +void free_addr(ss_addr_t *addr); + +#endif // _JCONF_H diff --git a/shadowsocksr-libev/src/server/json.c b/shadowsocksr-libev/src/server/json.c new file mode 100644 index 00000000..18e95ef7 --- /dev/null +++ b/shadowsocksr-libev/src/server/json.c @@ -0,0 +1,1002 @@ +/* vim: set et ts=3 sw=3 sts=3 ft=c: + * + * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. + * https://github.com/udp/json-parser + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "json.h" +#include "utils.h" + +#ifdef _MSC_VER +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#endif + +#ifdef __cplusplus +const struct _json_value json_value_none; /* zero-d by ctor */ +#else +const struct _json_value json_value_none = { NULL, 0, { 0 }, { NULL } }; +#endif + +#include +#include +#include +#include + +typedef unsigned short json_uchar; + +static unsigned char +hex_value(json_char c) +{ + if (isdigit((uint8_t)c)) { + return c - '0'; + } + + switch (c) { + case 'a': + case 'A': + return 0x0A; + case 'b': + case 'B': + return 0x0B; + case 'c': + case 'C': + return 0x0C; + case 'd': + case 'D': + return 0x0D; + case 'e': + case 'E': + return 0x0E; + case 'f': + case 'F': + return 0x0F; + default: + return 0xFF; + } +} + +typedef struct { + unsigned long used_memory; + + unsigned int uint_max; + unsigned long ulong_max; + + json_settings settings; + int first_pass; +} json_state; + +static void * +default_alloc(size_t size, int zero, void *user_data) +{ + return zero ? calloc(1, size) : ss_malloc(size); +} + +static void +default_free(void *ptr, void *user_data) +{ + ss_free(ptr); +} + +static void * +json_alloc(json_state *state, unsigned long size, int zero) +{ + if ((state->ulong_max - state->used_memory) < size) { + return 0; + } + + if (state->settings.max_memory + && (state->used_memory += size) > state->settings.max_memory) { + return 0; + } + + return state->settings.mem_alloc(size, zero, state->settings.user_data); +} + +static int +new_value(json_state *state, json_value **top, json_value **root, + json_value **alloc, json_type type) +{ + json_value *value; + int values_size; + + if (!state->first_pass) { + value = *top = *alloc; + *alloc = (*alloc)->_reserved.next_alloc; + + if (!*root) { + *root = value; + } + + switch (value->type) { + case json_array: + + if (!(value->u.array.values = (json_value **)json_alloc + (state, value->u.array.length * + sizeof(json_value *), 0))) { + return 0; + } + + value->u.array.length = 0; + break; + + case json_object: + + values_size = sizeof(*value->u.object.values) * + value->u.object.length; + + if (!((*(void **)&value->u.object.values) = json_alloc + (state, + values_size + + ((size_t)value->u. + object.values), + 0))) { + return 0; + } + + value->_reserved.object_mem = (*(char **)&value->u.object.values) + + values_size; + + value->u.object.length = 0; + break; + + case json_string: + + if (!(value->u.string.ptr = (json_char *)json_alloc + (state, + (value->u.string.length + + 1) * sizeof(json_char), 0))) { + return 0; + } + + value->u.string.length = 0; + break; + + default: + break; + } + + return 1; + } + + value = (json_value *)json_alloc(state, sizeof(json_value), 1); + + if (!value) { + return 0; + } + + if (!*root) { + *root = value; + } + + value->type = type; + value->parent = *top; + + if (*alloc) { + (*alloc)->_reserved.next_alloc = value; + } + + *alloc = *top = value; + + return 1; +} + +#define e_off \ + ((int)(i - cur_line_begin)) + +#define whitespace \ +case '\n': \ + ++cur_line; cur_line_begin = i; \ +case ' ': \ +case '\t': \ +case '\r' + +#define string_add(b) \ + do { if (!state.first_pass) { string[string_length] = b; \ + } ++string_length; } while (0) + +static const long + flag_next = 1 << 0, + flag_reproc = 1 << 1, + flag_need_comma = 1 << 2, + flag_seek_value = 1 << 3, + flag_escaped = 1 << 4, + flag_string = 1 << 5, + flag_need_colon = 1 << 6, + flag_done = 1 << 7, + flag_num_negative = 1 << 8, + flag_num_zero = 1 << 9, + flag_num_e = 1 << 10, + flag_num_e_got_sign = 1 << 11, + flag_num_e_negative = 1 << 12, + flag_line_comment = 1 << 13, + flag_block_comment = 1 << 14; + +json_value * +json_parse_ex(json_settings *settings, + const json_char *json, + size_t length, + char *error_buf) +{ + json_char error[json_error_max]; + int cur_line; + const json_char *cur_line_begin, *i, *end; + json_value *top, *root, *alloc = 0; + json_state state = { 0UL, 0U, 0UL, { 0UL, 0, NULL, NULL, NULL }, 0 }; + long flags; + long num_digits = 0, num_e = 0; + json_int_t num_fraction = 0; + + /* Skip UTF-8 BOM + */ + if (length >= 3 && ((unsigned char)json[0]) == 0xEF + && ((unsigned char)json[1]) == 0xBB + && ((unsigned char)json[2]) == 0xBF) { + json += 3; + length -= 3; + } + + error[0] = '\0'; + end = (json + length); + + memcpy(&state.settings, settings, sizeof(json_settings)); + + if (!state.settings.mem_alloc) { + state.settings.mem_alloc = default_alloc; + } + + if (!state.settings.mem_free) { + state.settings.mem_free = default_free; + } + + memset(&state.uint_max, 0xFF, sizeof(state.uint_max)); + memset(&state.ulong_max, 0xFF, sizeof(state.ulong_max)); + + state.uint_max -= 8; /* limit of how much can be added before next check */ + state.ulong_max -= 8; + + for (state.first_pass = 1; state.first_pass >= 0; --state.first_pass) { + json_uchar uchar; + unsigned char uc_b1, uc_b2, uc_b3, uc_b4; + json_char *string = 0; + unsigned int string_length = 0; + + top = root = 0; + flags = flag_seek_value; + + cur_line = 1; + cur_line_begin = json; + + for (i = json;; ++i) { + json_char b = (i == end ? 0 : *i); + + if (flags & flag_string) { + if (!b) { + sprintf(error, "Unexpected EOF in string (at %d:%d)", + cur_line, e_off); + goto e_failed; + } + + if (string_length > state.uint_max) { + goto e_overflow; + } + + if (flags & flag_escaped) { + flags &= ~flag_escaped; + + switch (b) { + case 'b': + string_add('\b'); + break; + case 'f': + string_add('\f'); + break; + case 'n': + string_add('\n'); + break; + case 'r': + string_add('\r'); + break; + case 't': + string_add('\t'); + break; + case 'u': + + if (end - i < 4 || + (uc_b1 = hex_value(*++i)) == 0xFF || + (uc_b2 = hex_value(*++i)) == 0xFF + || (uc_b3 = hex_value(*++i)) == 0xFF || + (uc_b4 = hex_value(*++i)) == 0xFF) { + sprintf(error, + "Invalid character value `%c` (at %d:%d)", + b, cur_line, e_off); + goto e_failed; + } + + uc_b1 = uc_b1 * 16 + uc_b2; + uc_b2 = uc_b3 * 16 + uc_b4; + + uchar = ((json_char)uc_b1) * 256 + uc_b2; + + if (sizeof(json_char) >= sizeof(json_uchar) || + (uc_b1 == 0 && uc_b2 <= 0x7F)) { + string_add((json_char)uchar); + break; + } + + if (uchar <= 0x7FF) { + if (state.first_pass) { + string_length += 2; + } else { + string[string_length++] = 0xC0 | + ((uc_b2 & + 0xC0) >> + 6) | + ((uc_b1 & 0x7) << 2); + string[string_length++] = 0x80 | + (uc_b2 & 0x3F); + } + + break; + } + + if (state.first_pass) { + string_length += 3; + } else { + string[string_length++] = 0xE0 | + ((uc_b1 & 0xF0) >> 4); + string[string_length++] = 0x80 | + ((uc_b1 & + 0xF) << + 2) | + ((uc_b2 & 0xC0) >> 6); + string[string_length++] = 0x80 | (uc_b2 & 0x3F); + } + + break; + + default: + string_add(b); + } + + continue; + } + + if (b == '\\') { + flags |= flag_escaped; + continue; + } + + if (b == '"') { + if (!state.first_pass) { + string[string_length] = 0; + } + + flags &= ~flag_string; + string = 0; + + switch (top->type) { + case json_string: + + top->u.string.length = string_length; + flags |= flag_next; + + break; + + case json_object: + + if (state.first_pass) { + (*(json_char **)&top->u.object.values) += + string_length + 1; + } else { + top->u.object.values[top->u.object.length].name + = (json_char *)top->_reserved.object_mem; + + top->u.object.values[top->u.object.length]. + name_length + = string_length; + + (*(json_char **)&top->_reserved.object_mem) += + string_length + 1; + } + + flags |= flag_seek_value | flag_need_colon; + continue; + + default: + break; + } + } else { + string_add(b); + continue; + } + } + + if (state.settings.settings & json_enable_comments) { + if (flags & (flag_line_comment | flag_block_comment)) { + if (flags & flag_line_comment) { + if (b == '\r' || b == '\n' || !b) { + flags &= ~flag_line_comment; + --i; /* so null can be reproc'd */ + } + + continue; + } + + if (flags & flag_block_comment) { + if (!b) { + sprintf(error, + "%d:%d: Unexpected EOF in block comment", + cur_line, e_off); + goto e_failed; + } + + if (b == '*' && i < (end - 1) && i[1] == '/') { + flags &= ~flag_block_comment; + ++i; /* skip closing sequence */ + } + + continue; + } + } else if (b == '/') { + if (!(flags & (flag_seek_value | flag_done)) && top->type != + json_object) { + sprintf(error, "%d:%d: Comment not allowed here", + cur_line, e_off); + goto e_failed; + } + + if (++i == end) { + sprintf(error, "%d:%d: EOF unexpected", cur_line, + e_off); + goto e_failed; + } + + switch (b = *i) { + case '/': + flags |= flag_line_comment; + continue; + + case '*': + flags |= flag_block_comment; + continue; + + default: + sprintf(error, + "%d:%d: Unexpected `%c` in comment opening sequence", cur_line, e_off, + b); + goto e_failed; + } + } + } + + if (flags & flag_done) { + if (!b) { + break; + } + + switch (b) { +whitespace: + continue; + + default: + sprintf(error, "%d:%d: Trailing garbage: `%c`", cur_line, + e_off, b); + goto e_failed; + } + } + + if (flags & flag_seek_value) { + switch (b) { +whitespace: + continue; + + case ']': + + if (top->type == json_array) { + flags = + (flags & + ~(flag_need_comma | flag_seek_value)) | flag_next; + } else { + sprintf(error, "%d:%d: Unexpected ]", cur_line, e_off); + goto e_failed; + } + + break; + + default: + + if (flags & flag_need_comma) { + if (b == ',') { + flags &= ~flag_need_comma; + continue; + } else { + sprintf(error, "%d:%d: Expected , before %c", + cur_line, e_off, b); + goto e_failed; + } + } + + if (flags & flag_need_colon) { + if (b == ':') { + flags &= ~flag_need_colon; + continue; + } else { + sprintf(error, "%d:%d: Expected : before %c", + cur_line, e_off, b); + goto e_failed; + } + } + + flags &= ~flag_seek_value; + + switch (b) { + case '{': + + if (!new_value(&state, &top, &root, &alloc, + json_object)) { + goto e_alloc_failure; + } + + continue; + + case '[': + + if (!new_value(&state, &top, &root, &alloc, + json_array)) { + goto e_alloc_failure; + } + + flags |= flag_seek_value; + continue; + + case '"': + + if (!new_value(&state, &top, &root, &alloc, + json_string)) { + goto e_alloc_failure; + } + + flags |= flag_string; + + string = top->u.string.ptr; + string_length = 0; + + continue; + + case 't': + + if ((end - i) < 3 || *(++i) != 'r' || *(++i) != 'u' || + *(++i) != 'e') { + goto e_unknown_value; + } + + if (!new_value(&state, &top, &root, &alloc, + json_boolean)) { + goto e_alloc_failure; + } + + top->u.boolean = 1; + + flags |= flag_next; + break; + + case 'f': + + if ((end - i) < 4 || *(++i) != 'a' || *(++i) != 'l' || + *(++i) != 's' || *(++i) != 'e') { + goto e_unknown_value; + } + + if (!new_value(&state, &top, &root, &alloc, + json_boolean)) { + goto e_alloc_failure; + } + + flags |= flag_next; + break; + + case 'n': + + if ((end - i) < 3 || *(++i) != 'u' || *(++i) != 'l' || + *(++i) != 'l') { + goto e_unknown_value; + } + + if (!new_value(&state, &top, &root, &alloc, + json_null)) { + goto e_alloc_failure; + } + + flags |= flag_next; + break; + + default: + + if (isdigit((uint8_t)b) || b == '-') { + if (!new_value(&state, &top, &root, &alloc, + json_integer)) { + goto e_alloc_failure; + } + + if (!state.first_pass) { + while (isdigit((uint8_t)b) || b == '+' || b == + '-' + || b == 'e' || b == 'E' || b == '.') { + if ((++i) == end) { + b = 0; + break; + } + + b = *i; + } + + flags |= flag_next | flag_reproc; + break; + } + + flags &= ~(flag_num_negative | flag_num_e | + flag_num_e_got_sign | + flag_num_e_negative | + flag_num_zero); + + num_digits = 0; + num_fraction = 0; + num_e = 0; + + if (b != '-') { + flags |= flag_reproc; + break; + } + + flags |= flag_num_negative; + continue; + } else { + sprintf(error, + "%d:%d: Unexpected %c when seeking value", + cur_line, e_off, b); + goto e_failed; + } + } + } + } else { + switch (top->type) { + case json_object: + + switch (b) { +whitespace: + continue; + + case '"': + + if (flags & flag_need_comma) { + sprintf(error, "%d:%d: Expected , before \"", + cur_line, e_off); + goto e_failed; + } + + flags |= flag_string; + + string = (json_char *)top->_reserved.object_mem; + string_length = 0; + + break; + + case '}': + + flags = (flags & ~flag_need_comma) | flag_next; + break; + + case ',': + + if (flags & flag_need_comma) { + flags &= ~flag_need_comma; + break; + } + + default: + + sprintf(error, "%d:%d: Unexpected `%c` in object", + cur_line, e_off, b); + goto e_failed; + } + + break; + + case json_integer: + case json_double: + + if (isdigit((uint8_t)b)) { + ++num_digits; + + if (top->type == json_integer || flags & flag_num_e) { + if (!(flags & flag_num_e)) { + if (flags & flag_num_zero) { + sprintf(error, + "%d:%d: Unexpected `0` before `%c`", + cur_line, e_off, b); + goto e_failed; + } + + if (num_digits == 1 && b == '0') { + flags |= flag_num_zero; + } + } else { + flags |= flag_num_e_got_sign; + num_e = (num_e * 10) + (b - '0'); + continue; + } + + top->u.integer = (top->u.integer * 10) + (b - '0'); + continue; + } + + num_fraction = (num_fraction * 10) + (b - '0'); + continue; + } + + if (b == '+' || b == '-') { + if ((flags & flag_num_e) && + !(flags & flag_num_e_got_sign)) { + flags |= flag_num_e_got_sign; + + if (b == '-') { + flags |= flag_num_e_negative; + } + + continue; + } + } else if (b == '.' && top->type == json_integer) { + if (!num_digits) { + sprintf(error, "%d:%d: Expected digit before `.`", + cur_line, e_off); + goto e_failed; + } + + top->type = json_double; + top->u.dbl = (double)top->u.integer; + + num_digits = 0; + continue; + } + + if (!(flags & flag_num_e)) { + if (top->type == json_double) { + if (!num_digits) { + sprintf(error, + "%d:%d: Expected digit after `.`", + cur_line, e_off); + goto e_failed; + } + + top->u.dbl += ((double)num_fraction) / + (pow(10, (double)num_digits)); + } + + if (b == 'e' || b == 'E') { + flags |= flag_num_e; + + if (top->type == json_integer) { + top->type = json_double; + top->u.dbl = (double)top->u.integer; + } + + num_digits = 0; + flags &= ~flag_num_zero; + + continue; + } + } else { + if (!num_digits) { + sprintf(error, "%d:%d: Expected digit after `e`", + cur_line, e_off); + goto e_failed; + } + + top->u.dbl *= + pow(10, + (double)((flags & + flag_num_e_negative) ? -num_e : num_e)); + } + + if (flags & flag_num_negative) { + if (top->type == json_integer) { + top->u.integer = -top->u.integer; + } else { + top->u.dbl = -top->u.dbl; + } + } + + flags |= flag_next | flag_reproc; + break; + + default: + break; + } + } + + if (flags & flag_reproc) { + flags &= ~flag_reproc; + --i; + } + + if (flags & flag_next) { + flags = (flags & ~flag_next) | flag_need_comma; + + if (!top->parent) { + /* root value done */ + + flags |= flag_done; + continue; + } + + if (top->parent->type == json_array) { + flags |= flag_seek_value; + } + + if (!state.first_pass) { + json_value *parent = top->parent; + + switch (parent->type) { + case json_object: + + parent->u.object.values + [parent->u.object.length].value = top; + + break; + + case json_array: + + parent->u.array.values + [parent->u.array.length] = top; + + break; + + default: + break; + } + } + + if ((++top->parent->u.array.length) > state.uint_max) { + goto e_overflow; + } + + top = top->parent; + + continue; + } + } + + alloc = root; + } + + return root; + +e_unknown_value: + + sprintf(error, "%d:%d: Unknown value", cur_line, e_off); + goto e_failed; + +e_alloc_failure: + + strcpy(error, "Memory allocation failure"); + goto e_failed; + +e_overflow: + + sprintf(error, "%d:%d: Too long (caught overflow)", cur_line, e_off); + goto e_failed; + +e_failed: + + if (error_buf) { + if (*error) { + strcpy(error_buf, error); + } else { + strcpy(error_buf, "Unknown error"); + } + } + + if (state.first_pass) { + alloc = root; + } + + while (alloc) { + top = alloc->_reserved.next_alloc; + state.settings.mem_free(alloc, state.settings.user_data); + alloc = top; + } + + if (!state.first_pass) { + json_value_free_ex(&state.settings, root); + } + + return 0; +} + +json_value * +json_parse(const json_char *json, size_t length) +{ + json_settings settings = { 0UL, 0, NULL, NULL, NULL }; + return json_parse_ex(&settings, json, length, 0); +} + +void +json_value_free_ex(json_settings *settings, json_value *value) +{ + json_value *cur_value; + + if (!value) { + return; + } + + value->parent = 0; + + while (value) { + switch (value->type) { + case json_array: + + if (!value->u.array.length) { + settings->mem_free(value->u.array.values, settings->user_data); + break; + } + + value = value->u.array.values[--value->u.array.length]; + continue; + + case json_object: + + if (!value->u.object.length) { + settings->mem_free(value->u.object.values, settings->user_data); + break; + } + + value = value->u.object.values[--value->u.object.length].value; + continue; + + case json_string: + + settings->mem_free(value->u.string.ptr, settings->user_data); + break; + + default: + break; + } + + cur_value = value; + value = value->parent; + settings->mem_free(cur_value, settings->user_data); + } +} + +void +json_value_free(json_value *value) +{ + json_settings settings = { 0UL, 0, NULL, NULL, NULL }; + settings.mem_free = default_free; + json_value_free_ex(&settings, value); +} diff --git a/shadowsocksr-libev/src/server/json.h b/shadowsocksr-libev/src/server/json.h new file mode 100644 index 00000000..016fc5a7 --- /dev/null +++ b/shadowsocksr-libev/src/server/json.h @@ -0,0 +1,249 @@ +/* vim: set et ts=3 sw=3 sts=3 ft=c: + * + * Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved. + * https://github.com/udp/json-parser + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _JSON_H +#define _JSON_H + +#ifndef json_char +#define json_char char +#endif + +#ifndef json_int_t +#ifndef _MSC_VER +#include +#define json_int_t int64_t +#else +#define json_int_t __int64 +#endif +#endif + +#include + +#ifdef __cplusplus + +#include + +extern "C" +{ +#endif + +typedef struct { + unsigned long max_memory; + int settings; + + /* Custom allocator support (leave null to use malloc/free) + */ + + void * (*mem_alloc)(size_t, int zero, void *user_data); + void (*mem_free)(void *, void *user_data); + + void *user_data; /* will be passed to mem_alloc and mem_free */ +} json_settings; + +#define json_enable_comments 0x01 + +typedef enum { + json_none, + json_object, + json_array, + json_integer, + json_double, + json_string, + json_boolean, + json_null +} json_type; + +extern const struct _json_value json_value_none; + +typedef struct _json_value { + struct _json_value *parent; + + json_type type; + + union { + int boolean; + json_int_t integer; + double dbl; + + struct { + unsigned int length; + json_char *ptr; /* null terminated */ + } string; + + struct { + unsigned int length; + + struct { + json_char *name; + unsigned int name_length; + + struct _json_value *value; + } *values; + +#if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin() const + { + return values; + } + decltype(values) end() const + { + return values + length; + } +#endif + } object; + + struct { + unsigned int length; + struct _json_value **values; + +#if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin() const + { + return values; + } + decltype(values) end() const + { + return values + length; + } +#endif + } array; + } u; + + union { + struct _json_value *next_alloc; + void *object_mem; + } _reserved; + + /* Some C++ operator sugar */ + +#ifdef __cplusplus + +public: + + inline _json_value(){ + memset(this, 0, sizeof(_json_value)); + } + + inline const struct _json_value &operator [] (int index) const { + if (type != json_array || index < 0 + || ((unsigned int)index) >= u.array.length) { + return json_value_none; + } + + return *u.array.values[index]; + } + + inline const struct _json_value &operator [] (const char *index) const { + if (type != json_object) { + return json_value_none; + } + + for (unsigned int i = 0; i < u.object.length; ++i) + if (!strcmp(u.object.values[i].name, index)) { + return *u.object.values[i].value; + } + + return json_value_none; + } + + inline operator const char * () const + { + switch (type) { + case json_string: + return u.string.ptr; + + default: + return ""; + } + } + + inline operator + json_int_t() const + { + switch (type) { + case json_integer: + return u.integer; + + case json_double: + return (json_int_t)u.dbl; + + default: + return 0; + } + } + + inline operator + bool() const + { + if (type != json_boolean) { + return false; + } + + return u.boolean != 0; + } + + inline operator double () const + { + switch (type) { + case json_integer: + return (double)u.integer; + + case json_double: + return u.dbl; + + default: + return 0; + } + } + +#endif +} json_value; + +json_value *json_parse(const json_char *json, + size_t length); + +#define json_error_max 128 +json_value *json_parse_ex(json_settings *settings, + const json_char *json, + size_t length, + char *error); + +void json_value_free(json_value *); + +/* Not usually necessary, unless you used a custom mem_alloc and now want to + * use a custom mem_free. + */ +void json_value_free_ex(json_settings *settings, + json_value *); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/shadowsocksr-libev/src/server/list.c b/shadowsocksr-libev/src/server/list.c new file mode 100644 index 00000000..dde085d8 --- /dev/null +++ b/shadowsocksr-libev/src/server/list.c @@ -0,0 +1,370 @@ +#include "list.h" + +/// 文件:list_impl.c +/// 功能:实现链表的基本æ“作 +/// 作者:bluewind +/// å®Œæˆæ—¶é—´ï¼š2011.5.29 +/// 修改时间:2011.5.31, 2011.7.2 +/// 修改备注:在头节点处添加一个空节点,å¯ä»¥ä¼˜åŒ–添加ã€åˆ é™¤èŠ‚ç‚¹ä»£ç  +/// 冿¬¡ä¿®æ”¹ï¼Œé“¾è¡¨å¢žåŠ èŠ‚ç‚¹æ•°æ®data_size,é™åˆ¶æ•°æ®å¤§å°ï¼Œä¿®æ”¹äº† +/// 添加å¤åˆ¶æ•°æ®ä»£ç ï¼Œä¿®æ­£é‡å¤æ·»åŠ èŠ‚ç‚¹åŽé‡Šæ”¾èŠ‚ç‚¹çš„Bugï¼Œæ·»åŠ äº†å‰ +/// æ’ã€æŽ’åºå’Œé历功能,7.3 添加tailå°¾æŒ‡é’ˆï¼Œæ”¹è¿›åŽæ’法性能,并改å +/// -------------------------------------------------------------- + +void swap_data(Node n1, Node n2); + +/// -------------------------------------------------------------- +// 函数å:list_init +// 功能: 链表åˆå§‹åŒ– +// 傿•°ï¼š æ—  +// 返回值:已åˆå§‹åŒ–链表指针 +// 备注: 链表本身动æ€åˆ†é…,由list_destroy函数管ç†é‡Šæ”¾ +/// -------------------------------------------------------------- +List list_init(unsigned int data_size) +{ + List list = (List) malloc(sizeof(struct clist)); + if(list != NULL) //å†…å­˜åˆ†é…æˆåŠŸ + { + list->head = (Node) malloc(sizeof(node)); //为头节点分é…内存 + if(list->head) //å†…å­˜åˆ†é…æˆåŠŸ + { + list->head->data = NULL; //åˆå§‹åŒ–头节点 + list->head->next = NULL; + list->data_size = data_size; + list->tail = list->head; + list->size = 0; + + list->add_back = list_add_back; //åˆå§‹åŒ–æˆå‘˜å‡½æ•° + list->add_front = list_add_front; + list->delete_node = list_delete_node; + list->delete_at = list_delete_at; + list->modify_at = list_modify_at; + list->have_same = list_have_same; + list->have_same_cmp = list_have_same_cmp; + list->foreach = list_foreach; + list->clear = list_clear; + list->sort = list_sort; + list->destroy = list_destroy; + } + } + return list; +} + +/// -------------------------------------------------------------- +// 函数å:list_add_back +// 功能: 添加链表结点 (åŽæ’法) +// 傿•°ï¼š l--链表指针,data--é“¾è¡¨æ•°æ®æŒ‡é’ˆï¼Œå¯ä¸ºä»»æ„类型 +// 返回值:int型,为1表示添加æˆåŠŸï¼Œä¸º0表示添加失败 +// 备注: 如果链表本身为空或是分é…节点内存失败,将返回0 +/// -------------------------------------------------------------- +int list_add_back(List l, void *data) +{ + Node new_node = (Node) malloc(sizeof(node)); + + if(l != NULL && new_node != NULL) //链表本身ä¸ä¸ºç©ºï¼Œä¸”内存申请æˆåŠŸ + { + new_node->data = malloc(l->data_size); + memcpy(new_node->data, data, l->data_size); + new_node->next = NULL; + + l->tail->next = new_node; //添加节点 + l->tail = new_node; //记录尾节点ä½ç½® + l->size ++; //链表元素总数加1 + + return 1; + } + + return 0; +} + +/// -------------------------------------------------------------- +// 函数å:list_add_front +// 功能: 添加链表结点 (剿’法) +// 傿•°ï¼š l--链表指针,data--é“¾è¡¨æ•°æ®æŒ‡é’ˆï¼Œå¯ä¸ºä»»æ„类型 +// 返回值:int型,为1表示添加æˆåŠŸï¼Œä¸º0表示添加失败 +// 备注: 如果链表本身为空或是分é…节点内存失败,将返回0 +/// -------------------------------------------------------------- +int list_add_front(List l, void *data) +{ + Node new_node = (Node) malloc(sizeof(node)); + + if(l != NULL && new_node != NULL) + { + new_node->data = malloc(l->data_size); + memcpy(new_node->data, data, l->data_size); + new_node->next = l->head->next; + + l->head->next = new_node; + if(!l->size) //记录尾指针ä½ç½® + l->tail = new_node; + l->size ++; + + return 1; + } + + return 0; +} + +/// -------------------------------------------------------------- +// 函数å:list_delete_node +// 功能:删除链表结点 +// 傿•°ï¼šl--链表指针,data--é“¾è¡¨æ•°æ®æŒ‡é’ˆï¼Œå¯ä¸ºä»»æ„类型 +// *pfunc为指å‘一个数æ®ç±»åž‹æ¯”较的函数指针 +// 返回值:int型,为1表示删除æˆåŠŸï¼Œä¸º0è¡¨ç¤ºæ²¡æœ‰æ‰¾åˆ°åŒ¹é…æ•°æ® +// 备注:*pfunc函数接å£å‚æ•°ndata为节点数æ®ï¼Œdata为比较数æ®ï¼Œè¿”å›žä¸ºçœŸè¡¨ç¤ºåŒ¹é…æ•°æ® +/// -------------------------------------------------------------- +int list_delete_node(List l, void *data, int (*pfunc)(void *ndata, void *data)) +{ + if(l != NULL) + { + Node prev = l->head; //å‰ä¸€ä¸ªèŠ‚ç‚¹ + Node curr = l->head->next; //当å‰èŠ‚ç‚¹ + + while(curr != NULL) + { + if(pfunc(curr->data, data)) //å¦‚æžœæ‰¾åˆ°åŒ¹é…æ•°æ® + { + if(curr == l->tail) //如果是删除尾节点 + l->tail = prev; + + prev->next = prev->next->next; //修改å‰èŠ‚ç‚¹next指针指å‘下下个节点 + + free(curr->data); //é‡Šæ”¾èŠ‚ç‚¹æ•°æ® + free(curr); //释放节点 + + l->size--; //链表元素总数å‡1 + return 1; //返回真值 + } + prev = prev->next; //æ²¡æœ‰æ‰¾åˆ°åŒ¹é…æ—¶ç§»åЍå‰èŠ‚ç‚¹å’Œå½“å‰èŠ‚ç‚¹ + curr = curr->next; + } + } + + return 0; //æ²¡æœ‰æ‰¾åˆ°åŒ¹é…æ•°æ® +} + +/// -------------------------------------------------------------- +// 函数å:list_delete_at +// 功能: 修改链表节点元素值 +// 傿•°ï¼š l--链表指针,index--索引值, 范围(0 -- size-1) +// 返回值:int型,为1表示删除æˆåŠŸï¼Œä¸º0表示删除失败 +// 备注: 如果链表本身为空或是indexä¸ºéžæ³•值,将返回0 +/// -------------------------------------------------------------- +int list_delete_at(List l, unsigned int index) +{ + unsigned int cindex = 0; + + if(l != NULL && index >= 0 && index < l->size) + { + Node prev = l->head; //å‰ä¸€ä¸ªèŠ‚ç‚¹ + Node curr = l->head->next; //当å‰èŠ‚ç‚¹ + + while(cindex != index) + { + prev = prev->next; + curr = curr->next; + cindex ++; + } + + if(index == (l->size) - 1) + l->tail = prev; + + prev->next = prev->next->next; + free(curr->data); + free(curr); + l->size --; + + return 1; + } + + return 0; +} + +/// -------------------------------------------------------------- +// 函数å:list_modify_at +// 功能: 修改链表节点元素值 +// 傿•°ï¼š l--链表指针,index--索引值, 范围(0 -- size-1) +// data--é“¾è¡¨æ•°æ®æŒ‡é’ˆ +// 返回值:int型,为1表示修改æˆåŠŸï¼Œä¸º0表示修改失败 +// 备注: 如果链表本身为空或是indexä¸ºéžæ³•值,将返回0 +/// -------------------------------------------------------------- +int list_modify_at(List l, unsigned int index, void *new_data) +{ + unsigned int cindex = 0; + + if(l != NULL && index >= 0 && index < l->size ) //éžç©ºé“¾è¡¨ï¼Œå¹¶ä¸”indexå€¼åˆæ³• + { + Node curr = l->head->next; + while(cindex != index) + { + curr = curr->next; + cindex ++; + } + memcpy(curr->data, new_data, l->data_size); + return 1; + } + + return 0; +} + +/// -------------------------------------------------------------- +// 函数å:list_sort +// 功能: é“¾è¡¨æŽ’åº +// 傿•°ï¼š l--链表指针,*pfunc为指å‘一个数æ®ç±»åž‹æ¯”较的函数指针 +// 返回值:无 +// 备注: 使用简å•é€‰æ‹©æŽ’åºæ³•ï¼Œç›¸æ¯”å†’æ³¡æ³•æ¯æ¬¡äº¤æ¢ï¼Œæ•ˆçŽ‡é«˜ä¸€ç‚¹ +/// -------------------------------------------------------------- +void list_sort(List l, compare pfunc) +{ + if(l != NULL) + { + Node min, icurr, jcurr; + + icurr = l->head->next; + while(icurr) + { + min = icurr; //记录最å°å€¼ + jcurr = icurr->next; //内循环指å‘下一个节点 + while(jcurr) + { + if(pfunc(min->data, jcurr->data)) //如果找到n+1到最åŽä¸€ä¸ªå…ƒç´ æœ€å°å€¼ + min = jcurr; //记录下最å°å€¼çš„ä½ç½® + + jcurr = jcurr->next; + } + + if(min != icurr) //当最å°å€¼ä½ç½®å’Œn+1元素ä½ç½®ä¸ç›¸åŒæ—¶ + { + swap_data(min, icurr); //æ‰è¿›è¡Œäº¤æ¢ï¼Œå‡å°‘äº¤æ¢æ¬¡æ•° + } + + icurr = icurr->next; + } + } +} + +void swap_data(Node n1, Node n2) +{ + void *temp; + + temp = n2->data; + n2->data = n1->data; + n1->data = temp; +} + + +int list_have_same(List l, void *data, int (*pfunc)(void *ndata, void *data)) +{ + if(l != NULL) + { + Node curr; + + for(curr = l->head->next; curr != NULL; curr = curr->next) + { + if(pfunc(curr->data, data)) + { + return 1; + } + } + } + + return 0; +} + +int list_have_same_cmp(List l, void *data) +{ + if(l != NULL) + { + Node curr; + + for(curr = l->head->next; curr != NULL; curr = curr->next) + { + if(memcmp(curr->data, data, l->data_size)) + { + return 1; + } + } + } + + return 0; +} + +/// -------------------------------------------------------------- +// 函数å:list_foreach +// 功能: é历链表元素 +// 傿•°ï¼š l--链表指针,doit为指å‘ä¸€ä¸ªå¤„ç†æ•°æ®çš„函数指针 +// 返回值:无 +// 备注: doit申明为void (*dofunc)(void *ndata)原型 +/// -------------------------------------------------------------- +void list_foreach(List l, dofunc doit) +{ + if(l != NULL) + { + Node curr; + + for(curr = l->head->next; curr != NULL; curr = curr->next) + { + doit(curr->data); + } + } +} + +/// -------------------------------------------------------------- +// 函数å:list_clear +// 功能: 清空链表元素 +// 傿•°ï¼š l--链表指针 +// 返回值:无 +// 备注: 没有使用先Destroyå†Init链表的办法,直接实现 +/// -------------------------------------------------------------- +void list_clear(List l) +{ + if(l != NULL) + { + Node temp; + Node curr = l->head->next; + + while(curr != NULL) + { + temp = curr->next; + + free(curr->data); //é‡Šæ”¾èŠ‚ç‚¹å’Œæ•°æ® + free(curr); + + curr = temp; + } + + l->size = 0; //é‡ç½®é“¾è¡¨æ•°æ® + l->head->next = NULL; + l->tail = l->head; + } +} + +/// -------------------------------------------------------------- +// 函数å:list_destroy +// 功能: 释放链表 +// 傿•°ï¼š l--链表指针 +// 返回值:空链表指针 +/// -------------------------------------------------------------- +List list_destroy(List l) +{ + if(l != NULL) + { + Node temp; + + while(l->head) + { + temp = l->head->next; + + if(l->head->data != NULL) //如果是头节点就ä¸é‡Šæ”¾æ•°æ®ç©ºé—´ + free(l->head->data); //先释放节点数æ®(但是节点数æ®é‡Œä¹Ÿæœ‰æŒ‡é’ˆï¼Ÿ) + free(l->head); //å†é‡Šæ”¾èŠ‚ç‚¹ + + l->head = temp; + } + + free(l); //释放链表本身å ç”¨ç©ºé—´ + l = NULL; + } + + return l; +} diff --git a/shadowsocksr-libev/src/server/list.h b/shadowsocksr-libev/src/server/list.h new file mode 100644 index 00000000..ab49720a --- /dev/null +++ b/shadowsocksr-libev/src/server/list.h @@ -0,0 +1,61 @@ +#ifndef LIST_H_H +#define LIST_H_H + +#include +#include +#include + +typedef struct clist *List; + +typedef int (*compare)(void *ndata, void *data); +typedef void (*dofunc)(void *ndata); + +typedef int (*lpf0)(List l, void *data); +typedef int (*lpf1)(List l, void *data, compare pfunc); +typedef List (*lpf2)(List l); +typedef void (*lpf3)(List l); +typedef void (*lpf4)(List l, dofunc pfunc); +typedef int (*lpf5)(List l, unsigned int index, void *new_data); +typedef void (*lpf6)(List l, compare pfunc); +typedef int (*lpf7)(List l, unsigned int index); + +typedef struct cnode +{ + void *data; + struct cnode *next; +}node, *Node; + +typedef struct clist +{ + Node head; + Node tail; + unsigned int size; + unsigned int data_size; + lpf0 add_back; + lpf0 add_front; + lpf1 delete_node; + lpf1 have_same; + lpf0 have_same_cmp; + lpf4 foreach; + lpf3 clear; + lpf2 destroy; + lpf5 modify_at; + lpf6 sort; + lpf7 delete_at; +}list; + +//åˆå§‹åŒ–链表 +List list_init(unsigned int data_size); +int list_add_back(List l, void *data); +int list_add_front(List l, void *data); +int list_delete_node(List l, void *data, compare pfunc); +int list_delete_at(List l, unsigned int index); +int list_modify_at(List l, unsigned int index, void *new_data); +int list_have_same(List l, void *data, compare pfunc); +int list_have_same_cmp(List l, void *data); +void list_foreach(List l, dofunc doit); +void list_sort(List l, compare pfunc); +void list_clear(List l); +//释放链表 +List list_destroy(List l); +#endif diff --git a/shadowsocksr-libev/src/server/netutils.c b/shadowsocksr-libev/src/server/netutils.c new file mode 100644 index 00000000..3a32b4d0 --- /dev/null +++ b/shadowsocksr-libev/src/server/netutils.c @@ -0,0 +1,297 @@ +/* + * netutils.c - Network utilities + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __MINGW32__ +#include "win32.h" +#define sleep(n) Sleep(1000 * (n)) +#else +#include +#include +#include +#include +#endif + +#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) +#include +#include +#define SET_INTERFACE +#endif + +#include "netutils.h" +#include "utils.h" + +#ifndef SO_REUSEPORT +#define SO_REUSEPORT 15 +#endif + +extern int verbose; + +static const char valid_label_bytes[] = + "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; + +#if defined(MODULE_LOCAL) +extern int keep_resolving; +#endif + +int +set_reuseport(int socket) +{ + int opt = 1; + return setsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)); +} + +size_t +get_sockaddr_len(struct sockaddr *addr) +{ + if (addr->sa_family == AF_INET) { + return sizeof(struct sockaddr_in); + } else if (addr->sa_family == AF_INET6) { + return sizeof(struct sockaddr_in6); + } + return 0; +} + +#ifdef SET_INTERFACE +int +setinterface(int socket_fd, const char *interface_name) +{ + struct ifreq interface; + memset(&interface, 0, sizeof(struct ifreq)); + strncpy(interface.ifr_name, interface_name, IFNAMSIZ); + int res = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, &interface, + sizeof(struct ifreq)); + return res; +} + +#endif + +int +bind_to_address(int socket_fd, const char *host) +{ + if (host != NULL) { + struct cork_ip ip; + struct sockaddr_storage storage; + memset(&storage, 0, sizeof(struct sockaddr_storage)); + if (cork_ip_init(&ip, host) != -1) { + if (ip.version == 4) { + struct sockaddr_in *addr = (struct sockaddr_in *)&storage; + dns_pton(AF_INET, host, &addr->sin_addr); + addr->sin_family = AF_INET; + return bind(socket_fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)); + } else if (ip.version == 6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; + dns_pton(AF_INET6, host, &addr->sin6_addr); + addr->sin6_family = AF_INET6; + return bind(socket_fd, (struct sockaddr *)addr, sizeof(struct sockaddr_in6)); + } + } + } + return -1; +} + +ssize_t +get_sockaddr(char *host, char *port, + struct sockaddr_storage *storage, int block, + int ipv6first) +{ + struct cork_ip ip; + if (cork_ip_init(&ip, host) != -1) { + if (ip.version == 4) { + struct sockaddr_in *addr = (struct sockaddr_in *)storage; + addr->sin_family = AF_INET; + dns_pton(AF_INET, host, &(addr->sin_addr)); + if (port != NULL) { + addr->sin_port = htons(atoi(port)); + } + } else if (ip.version == 6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; + addr->sin6_family = AF_INET6; + dns_pton(AF_INET6, host, &(addr->sin6_addr)); + if (port != NULL) { + addr->sin6_port = htons(atoi(port)); + } + } + return 0; + } else { + struct addrinfo hints; + struct addrinfo *result, *rp; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ + hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ + + int err, i; + + for (i = 1; i < 8; i++) { + err = getaddrinfo(host, port, &hints, &result); +#if defined(MODULE_LOCAL) + if (!keep_resolving) + break; +#endif + if ((!block || !err)) { + break; + } else { + sleep(pow(2, i)); + LOGE("failed to resolve server name, wait %.0f seconds", pow(2, i)); + } + } + + if (err != 0) { + LOGE("getaddrinfo: %s", gai_strerror(err)); + return -1; + } + + int prefer_af = ipv6first ? AF_INET6 : AF_INET; + for (rp = result; rp != NULL; rp = rp->ai_next) + if (rp->ai_family == prefer_af) { + if (rp->ai_family == AF_INET) + memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in)); + else if (rp->ai_family == AF_INET6) + memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in6)); + break; + } + + if (rp == NULL) { + for (rp = result; rp != NULL; rp = rp->ai_next) { + if (rp->ai_family == AF_INET) + memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in)); + else if (rp->ai_family == AF_INET6) + memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in6)); + break; + } + } + + if (rp == NULL) { + LOGE("failed to resolve remote addr"); + return -1; + } + + freeaddrinfo(result); + return 0; + } + + return -1; +} + +int +sockaddr_cmp(struct sockaddr_storage *addr1, + struct sockaddr_storage *addr2, socklen_t len) +{ + struct sockaddr_in *p1_in = (struct sockaddr_in *)addr1; + struct sockaddr_in *p2_in = (struct sockaddr_in *)addr2; + struct sockaddr_in6 *p1_in6 = (struct sockaddr_in6 *)addr1; + struct sockaddr_in6 *p2_in6 = (struct sockaddr_in6 *)addr2; + if (p1_in->sin_family < p2_in->sin_family) + return -1; + if (p1_in->sin_family > p2_in->sin_family) + return 1; + /* compare ip4 */ + if (p1_in->sin_family == AF_INET) { + /* just order it, ntohs not required */ + if (p1_in->sin_port < p2_in->sin_port) + return -1; + if (p1_in->sin_port > p2_in->sin_port) + return 1; + return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); + } else if (p1_in6->sin6_family == AF_INET6) { + /* just order it, ntohs not required */ + if (p1_in6->sin6_port < p2_in6->sin6_port) + return -1; + if (p1_in6->sin6_port > p2_in6->sin6_port) + return 1; + return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, + INET6_SIZE); + } else { + /* eek unknown type, perform this comparison for sanity. */ + return memcmp(addr1, addr2, len); + } +} + +int +sockaddr_cmp_addr(struct sockaddr_storage *addr1, + struct sockaddr_storage *addr2, socklen_t len) +{ + struct sockaddr_in *p1_in = (struct sockaddr_in *)addr1; + struct sockaddr_in *p2_in = (struct sockaddr_in *)addr2; + struct sockaddr_in6 *p1_in6 = (struct sockaddr_in6 *)addr1; + struct sockaddr_in6 *p2_in6 = (struct sockaddr_in6 *)addr2; + if (p1_in->sin_family < p2_in->sin_family) + return -1; + if (p1_in->sin_family > p2_in->sin_family) + return 1; + /* compare ip4 */ + if (p1_in->sin_family == AF_INET) { + return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); + } else if (p1_in6->sin6_family == AF_INET6) { + return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, + INET6_SIZE); + } else { + /* eek unknown type, perform this comparison for sanity. */ + return memcmp(addr1, addr2, len); + } +} + +int +validate_hostname(const char *hostname, const int hostname_len) +{ + if (hostname == NULL) + return 0; + + if (hostname_len < 1 || hostname_len > 255) + return 0; + + if (hostname[0] == '.') + return 0; + + const char *label = hostname; + while (label < hostname + hostname_len) { + size_t label_len = hostname_len - (label - hostname); + char *next_dot = strchr(label, '.'); + if (next_dot != NULL) + label_len = next_dot - label; + + if (label + label_len > hostname + hostname_len) + return 0; + + if (label_len > 63 || label_len < 1) + return 0; + + if (label[0] == '-' || label[label_len - 1] == '-') + return 0; + + if (strspn(label, valid_label_bytes) < label_len) + return 0; + + label += label_len + 1; + } + + return 1; +} diff --git a/shadowsocksr-libev/src/server/netutils.h b/shadowsocksr-libev/src/server/netutils.h new file mode 100644 index 00000000..07255923 --- /dev/null +++ b/shadowsocksr-libev/src/server/netutils.h @@ -0,0 +1,98 @@ +/* + * netutils.h - Network utilities + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _NETUTILS_H +#define _NETUTILS_H + +#if defined(__linux__) +#include +#elif !defined(__MINGW32__) +#include +#endif + +// only enable TCP_FASTOPEN on linux +#if defined(__linux__) +#include +/* conditional define for TCP_FASTOPEN */ +#ifndef TCP_FASTOPEN +#define TCP_FASTOPEN 23 +#endif +/* conditional define for MSG_FASTOPEN */ +#ifndef MSG_FASTOPEN +#define MSG_FASTOPEN 0x20000000 +#endif +#elif !defined(__APPLE__) +#ifdef TCP_FASTOPEN +#undef TCP_FASTOPEN +#endif +#endif + +/* Backward compatibility for MPTCP_ENABLED between kernel 3 & 4 */ +#ifndef MPTCP_ENABLED +#ifdef TCP_CC_INFO +#define MPTCP_ENABLED 42 +#else +#define MPTCP_ENABLED 26 +#endif +#endif + +/** byte size of ip4 address */ +#define INET_SIZE 4 +/** byte size of ip6 address */ +#define INET6_SIZE 16 + +size_t get_sockaddr_len(struct sockaddr *addr); +ssize_t get_sockaddr(char *host, char *port, + struct sockaddr_storage *storage, int block, + int ipv6first); +int set_reuseport(int socket); + +#ifdef SET_INTERFACE +int setinterface(int socket_fd, const char *interface_name); +#endif + +int bind_to_address(int socket_fd, const char *address); + +/** + * Compare two sockaddrs. Imposes an ordering on the addresses. + * Compares address and port. + * @param addr1: address 1. + * @param addr2: address 2. + * @param len: lengths of addr. + * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. + */ +int sockaddr_cmp(struct sockaddr_storage *addr1, + struct sockaddr_storage *addr2, socklen_t len); + +/** + * Compare two sockaddrs. Compares address, not the port. + * @param addr1: address 1. + * @param addr2: address 2. + * @param len: lengths of addr. + * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. + */ +int sockaddr_cmp_addr(struct sockaddr_storage *addr1, + struct sockaddr_storage *addr2, socklen_t len); + +int validate_hostname(const char *hostname, const int hostname_len); + +#endif diff --git a/shadowsocksr-libev/src/server/obfs.c b/shadowsocksr-libev/src/server/obfs.c new file mode 100644 index 00000000..5c885bfe --- /dev/null +++ b/shadowsocksr-libev/src/server/obfs.c @@ -0,0 +1,205 @@ +#include +#include + +#include "utils.h" +#include "obfs.h" + +int rand_bytes(uint8_t *output, int len); +#define OBFS_HMAC_SHA1_LEN 10 + +#include "obfsutil.c" +#include "crc32.c" +#include "base64.c" +#include "http_simple.c" +#include "tls1.2_ticket.c" +#include "verify.c" +#include "auth.c" + +void * init_data() { + return malloc(1); +} + +obfs * new_obfs() { + obfs * self = (obfs*)malloc(sizeof(obfs)); + self->l_data = NULL; + return self; +} + +void set_server_info(obfs *self, server_info *server) { + memmove(&self->server, server, sizeof(server_info)); +} + +void get_server_info(obfs *self, server_info *server) { + memmove(server, &self->server, sizeof(server_info)); +} + +void dispose_obfs(obfs *self) { + free(self); +} + +obfs_class * new_obfs_class(char *plugin_name) +{ + if (plugin_name == NULL) + return NULL; + if (strcmp(plugin_name, "origin") == 0) + return NULL; + if (strcmp(plugin_name, "plain") == 0) + return NULL; + init_crc32_table(); + init_shift128plus(); + if (strcmp(plugin_name, "http_simple") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = init_data; + plugin->new_obfs = http_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = http_simple_dispose; + + plugin->client_encode = http_simple_client_encode; + plugin->client_decode = http_simple_client_decode; + + plugin->server_encode = http_simple_server_encode; + plugin->server_decode = http_simple_server_decode; + + return plugin; + } else if (strcmp(plugin_name, "http_post") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = init_data; + plugin->new_obfs = http_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = http_simple_dispose; + + plugin->client_encode = http_post_client_encode; + plugin->client_decode = http_simple_client_decode; + + plugin->server_encode = http_simple_server_encode; + plugin->server_decode = http_simple_server_decode; + + return plugin; + } else if (strcmp(plugin_name, "tls1.2_ticket_auth") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = tls12_ticket_auth_init_data; + plugin->new_obfs = tls12_ticket_auth_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = tls12_ticket_auth_dispose; + + plugin->client_encode = tls12_ticket_auth_client_encode; + plugin->client_decode = tls12_ticket_auth_client_decode; + + plugin->server_encode = tls12_ticket_auth_server_encode; + plugin->server_decode = tls12_ticket_auth_server_decode; + + return plugin; + } else if (strcmp(plugin_name, "verify_simple") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = init_data; + plugin->new_obfs = verify_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = verify_simple_dispose; + + plugin->client_pre_encrypt = verify_simple_client_pre_encrypt; + plugin->client_post_decrypt = verify_simple_client_post_decrypt; + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + + plugin->server_pre_encrypt = verify_simple_server_pre_encrypt; + plugin->server_post_decrypt = verify_simple_server_post_decrypt; + plugin->server_udp_pre_encrypt = NULL; + plugin->server_udp_post_decrypt = NULL; + + return plugin; + } else if (strcmp(plugin_name, "auth_simple") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = auth_simple_init_data; + plugin->new_obfs = auth_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = auth_simple_dispose; + + plugin->client_pre_encrypt = auth_simple_client_pre_encrypt; + plugin->client_post_decrypt = auth_simple_client_post_decrypt; + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + + return plugin; + } else if (strcmp(plugin_name, "auth_sha1") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = auth_simple_init_data; + plugin->new_obfs = auth_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = auth_simple_dispose; + + plugin->client_pre_encrypt = auth_sha1_client_pre_encrypt; + plugin->client_post_decrypt = auth_sha1_client_post_decrypt; + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + + return plugin; + } else if (strcmp(plugin_name, "auth_sha1_v2") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = auth_simple_init_data; + plugin->new_obfs = auth_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = auth_simple_dispose; + + plugin->client_pre_encrypt = auth_sha1_v2_client_pre_encrypt; + plugin->client_post_decrypt = auth_sha1_v2_client_post_decrypt; + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + + return plugin; + } else if (strcmp(plugin_name, "auth_sha1_v4") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = auth_simple_init_data; + plugin->new_obfs = auth_simple_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = auth_simple_dispose; + + plugin->client_pre_encrypt = auth_sha1_v4_client_pre_encrypt; + plugin->client_post_decrypt = auth_sha1_v4_client_post_decrypt; + plugin->client_udp_pre_encrypt = NULL; + plugin->client_udp_post_decrypt = NULL; + + return plugin; + } else if (strcmp(plugin_name, "auth_aes128_md5") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = auth_simple_init_data; + plugin->new_obfs = auth_aes128_md5_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = auth_simple_dispose; + + plugin->client_pre_encrypt = auth_aes128_sha1_client_pre_encrypt; + plugin->client_post_decrypt = auth_aes128_sha1_client_post_decrypt; + plugin->client_udp_pre_encrypt = auth_aes128_sha1_client_udp_pre_encrypt; + plugin->client_udp_post_decrypt = auth_aes128_sha1_client_udp_post_decrypt; + + return plugin; + } else if (strcmp(plugin_name, "auth_aes128_sha1") == 0) { + obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs)); + plugin->init_data = auth_simple_init_data; + plugin->new_obfs = auth_aes128_sha1_new_obfs; + plugin->get_server_info = get_server_info; + plugin->set_server_info = set_server_info; + plugin->dispose = auth_simple_dispose; + + plugin->client_pre_encrypt = auth_aes128_sha1_client_pre_encrypt; + plugin->client_post_decrypt = auth_aes128_sha1_client_post_decrypt; + plugin->client_udp_pre_encrypt = auth_aes128_sha1_client_udp_pre_encrypt; + plugin->client_udp_post_decrypt = auth_aes128_sha1_client_udp_post_decrypt; + + return plugin; + } + LOGE("Load obfs '%s' failed", plugin_name); + return NULL; +} + +void free_obfs_class(obfs_class *plugin) { + free(plugin); +} diff --git a/shadowsocksr-libev/src/server/obfs.h b/shadowsocksr-libev/src/server/obfs.h new file mode 100644 index 00000000..74c60c9a --- /dev/null +++ b/shadowsocksr-libev/src/server/obfs.h @@ -0,0 +1,100 @@ +/* + * obfs.h - Define shadowsocksR server's buffers and callbacks + * + * Copyright (C) 2015 - 2016, Break Wa11 + */ + +#ifndef _OBFS_H +#define _OBFS_H + +#include +#include + +typedef struct server_info { + char host[64]; + uint16_t port; + char *param; + void *g_data; + uint8_t *iv; + size_t iv_len; + uint8_t *recv_iv; + size_t recv_iv_len; + uint8_t *key; + size_t key_len; + int head_len; + size_t tcp_mss; +}server_info; + +typedef struct obfs { + server_info server; + void *l_data; +}obfs; + +typedef struct obfs_class { + void * (*init_data)(); + obfs * (*new_obfs)(); + void (*get_server_info)(obfs *self, server_info *server); + void (*set_server_info)(obfs *self, server_info *server); + void (*dispose)(obfs *self); + + int (*client_pre_encrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*client_encode)(obfs *self, + char **pencryptdata, + int datalength, + size_t* capacity); + int (*client_decode)(obfs *self, + char **pencryptdata, + int datalength, + size_t* capacity, + int *needsendback); + int (*client_post_decrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*client_udp_pre_encrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*client_udp_post_decrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*server_pre_encrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*server_post_decrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*server_udp_pre_encrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*server_udp_post_decrypt)(obfs *self, + char **pplaindata, + int datalength, + size_t* capacity); + int (*server_encode)(obfs *self, + char **pencryptdata, + int datalength, + size_t* capacity); + int (*server_decode)(obfs *self, + char **pencryptdata, + int datalength, + size_t* capacity, + int *needsendback); +}obfs_class; + +obfs_class * new_obfs_class(char *plugin_name); +void free_obfs_class(obfs_class *plugin); + +void set_server_info(obfs *self, server_info *server); +void get_server_info(obfs *self, server_info *server); +obfs * new_obfs(); +void dispose_obfs(obfs *self); + +#endif // _OBFS_H diff --git a/shadowsocksr-libev/src/server/obfsutil.c b/shadowsocksr-libev/src/server/obfsutil.c new file mode 100644 index 00000000..d00959b9 --- /dev/null +++ b/shadowsocksr-libev/src/server/obfsutil.c @@ -0,0 +1,36 @@ +int get_head_size(char *plaindata, int size, int def_size) { + if (plaindata == NULL || size < 2) + return def_size; + int head_type = plaindata[0] & 0x7; + if (head_type == 1) + return 7; + if (head_type == 4) + return 19; + if (head_type == 3) + return 4 + plaindata[1]; + return def_size; +} + +static int shift128plus_init_flag = 0; +static uint64_t shift128plus_s[2] = {0x10000000, 0xFFFFFFFF}; + +void init_shift128plus(void) { + if (shift128plus_init_flag == 0) { + shift128plus_init_flag = 1; + uint32_t seed = time(NULL); + shift128plus_s[0] = seed | 0x100000000L; + shift128plus_s[1] = ((uint64_t)seed << 32) | 0x1; + } +} + +uint64_t xorshift128plus(void) { + uint64_t x = shift128plus_s[0]; + uint64_t const y = shift128plus_s[1]; + shift128plus_s[0] = y; + x ^= x << 23; // a + x ^= x >> 17; // b + x ^= y ^ (y >> 26); // c + shift128plus_s[1] = x; + return x + y; +} + diff --git a/shadowsocksr-libev/src/server/protocol.h b/shadowsocksr-libev/src/server/protocol.h new file mode 100644 index 00000000..eaa866e7 --- /dev/null +++ b/shadowsocksr-libev/src/server/protocol.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef PROTOCOL_H +#define PROTOCOL_H + +typedef struct protocol { + const int default_port; + int(*const parse_packet)(const char *, size_t, char **); +} protocol_t; + +#endif diff --git a/shadowsocksr-libev/src/server/resolv.c b/shadowsocksr-libev/src/server/resolv.c new file mode 100644 index 00000000..f580d06d --- /dev/null +++ b/shadowsocksr-libev/src/server/resolv.c @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2014, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef __MINGW32__ +#include "win32.h" +#else +#include +#include +#include +#include +#endif + +#include "resolv.h" +#include "utils.h" +#include "netutils.h" + +/* + * Implement DNS resolution interface using libudns + */ + +struct ResolvQuery { + void (*client_cb)(struct sockaddr *, void *); + void (*client_free_cb)(void *); + void *client_cb_data; + struct dns_query *queries[2]; + size_t response_count; + struct sockaddr **responses; + uint16_t port; +}; + +extern int verbose; + +static struct ev_io resolv_io_watcher; +static struct ev_timer resolv_timeout_watcher; +static const int MODE_IPV4_ONLY = 0; +static const int MODE_IPV6_ONLY = 1; +static const int MODE_IPV4_FIRST = 2; +static const int MODE_IPV6_FIRST = 3; +static int resolv_mode = 0; + +static void resolv_sock_cb(struct ev_loop *, struct ev_io *, int); +static void resolv_timeout_cb(struct ev_loop *, struct ev_timer *, int); +static void dns_query_v4_cb(struct dns_ctx *, struct dns_rr_a4 *, void *); +static void dns_query_v6_cb(struct dns_ctx *, struct dns_rr_a6 *, void *); +static void dns_timer_setup_cb(struct dns_ctx *, int, void *); +static void process_client_callback(struct ResolvQuery *); +static inline int all_queries_are_null(struct ResolvQuery *); +static struct sockaddr *choose_ipv4_first(struct ResolvQuery *); +static struct sockaddr *choose_ipv6_first(struct ResolvQuery *); +static struct sockaddr *choose_any(struct ResolvQuery *); + +int +resolv_init(struct ev_loop *loop, char **nameservers, int nameserver_num, int ipv6first) +{ + if (ipv6first) + resolv_mode = MODE_IPV6_FIRST; + else + resolv_mode = MODE_IPV4_FIRST; + + struct dns_ctx *ctx = &dns_defctx; + if (nameservers == NULL) { + /* Nameservers not specified, use system resolver config */ + dns_init(ctx, 0); + } else { + dns_reset(ctx); + + for (int i = 0; i < nameserver_num; i++) { + char *server = nameservers[i]; + dns_add_serv(ctx, server); + } + } + + int sockfd = dns_open(ctx); + if (sockfd < 0) { + FATAL("Failed to open DNS resolver socket"); + } + + if (nameserver_num == 1 && nameservers != NULL) { + if (strncmp("127.0.0.1", nameservers[0], 9) == 0 + || strncmp("::1", nameservers[0], 3) == 0) { + if (verbose) { + LOGI("bind UDP resolver to %s", nameservers[0]); + } + if (bind_to_address(sockfd, nameservers[0]) == -1) + ERROR("bind_to_address"); + } + } + +#ifdef __MINGW32__ + setnonblocking(sockfd); +#else + int flags = fcntl(sockfd, F_GETFL, 0); + fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); +#endif + + ev_io_init(&resolv_io_watcher, resolv_sock_cb, sockfd, EV_READ); + resolv_io_watcher.data = ctx; + + ev_io_start(loop, &resolv_io_watcher); + + ev_timer_init(&resolv_timeout_watcher, resolv_timeout_cb, 0.0, 0.0); + resolv_timeout_watcher.data = ctx; + + dns_set_tmcbck(ctx, dns_timer_setup_cb, loop); + + return sockfd; +} + +void +resolv_shutdown(struct ev_loop *loop) +{ + struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; + + ev_io_stop(loop, &resolv_io_watcher); + + if (ev_is_active(&resolv_timeout_watcher)) { + ev_timer_stop(loop, &resolv_timeout_watcher); + } + + dns_close(ctx); +} + +struct ResolvQuery * +resolv_query(const char *hostname, void (*client_cb)(struct sockaddr *, void *), + void (*client_free_cb)(void *), void *client_cb_data, + uint16_t port) +{ + struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; + + /* + * Wrap udns's call back in our own + */ + struct ResolvQuery *cb_data = ss_malloc(sizeof(struct ResolvQuery)); + if (cb_data == NULL) { + LOGE("Failed to allocate memory for DNS query callback data."); + return NULL; + } + memset(cb_data, 0, sizeof(struct ResolvQuery)); + + cb_data->client_cb = client_cb; + cb_data->client_free_cb = client_free_cb; + cb_data->client_cb_data = client_cb_data; + memset(cb_data->queries, 0, sizeof(cb_data->queries)); + cb_data->response_count = 0; + cb_data->responses = NULL; + cb_data->port = port; + + /* Submit A and AAAA queries */ + if (resolv_mode != MODE_IPV6_ONLY) { + cb_data->queries[0] = dns_submit_a4(ctx, + hostname, 0, + dns_query_v4_cb, cb_data); + if (cb_data->queries[0] == NULL) { + LOGE("Failed to submit DNS query: %s", + dns_strerror(dns_status(ctx))); + } + } + + if (resolv_mode != MODE_IPV4_ONLY) { + cb_data->queries[1] = dns_submit_a6(ctx, + hostname, 0, + dns_query_v6_cb, cb_data); + if (cb_data->queries[1] == NULL) { + LOGE("Failed to submit DNS query: %s", + dns_strerror(dns_status(ctx))); + } + } + + if (all_queries_are_null(cb_data)) { + if (cb_data->client_free_cb != NULL) { + cb_data->client_free_cb(cb_data->client_cb_data); + } + ss_free(cb_data); + } + + return cb_data; +} + +void +resolv_cancel(struct ResolvQuery *query_handle) +{ + struct ResolvQuery *cb_data = (struct ResolvQuery *)query_handle; + struct dns_ctx *ctx = (struct dns_ctx *)resolv_io_watcher.data; + + for (int i = 0; i < sizeof(cb_data->queries) / sizeof(cb_data->queries[0]); + i++) + if (cb_data->queries[i] != NULL) { + dns_cancel(ctx, cb_data->queries[i]); + ss_free(cb_data->queries[i]); + } + + if (cb_data->client_free_cb != NULL) { + cb_data->client_free_cb(cb_data->client_cb_data); + } + + ss_free(cb_data); +} + +/* + * DNS UDP socket activity callback + */ +static void +resolv_sock_cb(struct ev_loop *loop, struct ev_io *w, int revents) +{ + struct dns_ctx *ctx = (struct dns_ctx *)w->data; + + if (revents & EV_READ) { + dns_ioevent(ctx, ev_now(loop)); + } +} + +/* + * Wrapper for client callback we provide to udns + */ +static void +dns_query_v4_cb(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data) +{ + struct ResolvQuery *cb_data = (struct ResolvQuery *)data; + + if (result == NULL) { + if (verbose) { + LOGI("IPv4 resolv: %s", dns_strerror(dns_status(ctx))); + } + } else if (result->dnsa4_nrr > 0) { + struct sockaddr **new_responses = ss_realloc(cb_data->responses, + (cb_data->response_count + + result->dnsa4_nrr) * + sizeof(struct sockaddr *)); + if (new_responses == NULL) { + LOGE("Failed to allocate memory for additional DNS responses"); + } else { + cb_data->responses = new_responses; + + for (int i = 0; i < result->dnsa4_nrr; i++) { + struct sockaddr_in *sa = + (struct sockaddr_in *)ss_malloc(sizeof(struct sockaddr_in)); + sa->sin_family = AF_INET; + sa->sin_port = cb_data->port; + sa->sin_addr = result->dnsa4_addr[i]; + + cb_data->responses[cb_data->response_count] = + (struct sockaddr *)sa; + if (cb_data->responses[cb_data->response_count] == NULL) { + LOGE( + "Failed to allocate memory for DNS query result address"); + } else { + cb_data->response_count++; + } + } + } + } + + ss_free(result); + cb_data->queries[0] = NULL; /* mark A query as being completed */ + + /* Once all queries have completed, call client callback */ + if (all_queries_are_null(cb_data)) { + return process_client_callback(cb_data); + } +} + +static void +dns_query_v6_cb(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data) +{ + struct ResolvQuery *cb_data = (struct ResolvQuery *)data; + + if (result == NULL) { + if (verbose) { + LOGI("IPv6 resolv: %s", dns_strerror(dns_status(ctx))); + } + } else if (result->dnsa6_nrr > 0) { + struct sockaddr **new_responses = ss_realloc(cb_data->responses, + (cb_data->response_count + + result->dnsa6_nrr) * + sizeof(struct sockaddr *)); + if (new_responses == NULL) { + LOGE("Failed to allocate memory for additional DNS responses"); + } else { + cb_data->responses = new_responses; + + for (int i = 0; i < result->dnsa6_nrr; i++) { + struct sockaddr_in6 *sa = + (struct sockaddr_in6 *)ss_malloc(sizeof(struct sockaddr_in6)); + sa->sin6_family = AF_INET6; + sa->sin6_port = cb_data->port; + sa->sin6_addr = result->dnsa6_addr[i]; + + cb_data->responses[cb_data->response_count] = + (struct sockaddr *)sa; + if (cb_data->responses[cb_data->response_count] == NULL) { + LOGE( + "Failed to allocate memory for DNS query result address"); + } else { + cb_data->response_count++; + } + } + } + } + + ss_free(result); + cb_data->queries[1] = NULL; /* mark AAAA query as being completed */ + + /* Once all queries have completed, call client callback */ + if (all_queries_are_null(cb_data)) { + return process_client_callback(cb_data); + } +} + +/* + * Called once all queries have been completed + */ +static void +process_client_callback(struct ResolvQuery *cb_data) +{ + struct sockaddr *best_address = NULL; + + if (resolv_mode == MODE_IPV4_FIRST) { + best_address = choose_ipv4_first(cb_data); + } else if (resolv_mode == MODE_IPV6_FIRST) { + best_address = choose_ipv6_first(cb_data); + } else { + best_address = choose_any(cb_data); + } + + cb_data->client_cb(best_address, cb_data->client_cb_data); + + for (int i = 0; i < cb_data->response_count; i++) + ss_free(cb_data->responses[i]); + + ss_free(cb_data->responses); + if (cb_data->client_free_cb != NULL) { + cb_data->client_free_cb(cb_data->client_cb_data); + } + ss_free(cb_data); +} + +static struct sockaddr * +choose_ipv4_first(struct ResolvQuery *cb_data) +{ + for (int i = 0; i < cb_data->response_count; i++) + if (cb_data->responses[i]->sa_family == AF_INET) { + return cb_data->responses[i]; + } + + return choose_any(cb_data); +} + +static struct sockaddr * +choose_ipv6_first(struct ResolvQuery *cb_data) +{ + for (int i = 0; i < cb_data->response_count; i++) + if (cb_data->responses[i]->sa_family == AF_INET6) { + return cb_data->responses[i]; + } + + return choose_any(cb_data); +} + +static struct sockaddr * +choose_any(struct ResolvQuery *cb_data) +{ + if (cb_data->response_count >= 1) { + return cb_data->responses[0]; + } + + return NULL; +} + +/* + * DNS timeout callback + */ +static void +resolv_timeout_cb(struct ev_loop *loop, struct ev_timer *w, int revents) +{ + struct dns_ctx *ctx = (struct dns_ctx *)w->data; + + if (revents & EV_TIMER) { + dns_timeouts(ctx, 30, ev_now(loop)); + } +} + +/* + * Callback to setup DNS timeout callback + */ +static void +dns_timer_setup_cb(struct dns_ctx *ctx, int timeout, void *data) +{ + struct ev_loop *loop = (struct ev_loop *)data; + + if (ev_is_active(&resolv_timeout_watcher)) { + ev_timer_stop(loop, &resolv_timeout_watcher); + } + + if (ctx != NULL && timeout >= 0) { + ev_timer_set(&resolv_timeout_watcher, timeout, 0.0); + ev_timer_start(loop, &resolv_timeout_watcher); + } +} + +static inline int +all_queries_are_null(struct ResolvQuery *cb_data) +{ + int result = 1; + + for (int i = 0; i < sizeof(cb_data->queries) / sizeof(cb_data->queries[0]); + i++) + result = result && cb_data->queries[i] == NULL; + + return result; +} diff --git a/shadowsocksr-libev/src/server/resolv.h b/shadowsocksr-libev/src/server/resolv.h new file mode 100644 index 00000000..05529223 --- /dev/null +++ b/shadowsocksr-libev/src/server/resolv.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef RESOLV_H +#define RESOLV_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef __MINGW32__ +#include "win32.h" +#else +#include +#endif + +struct ResolvQuery; + +int resolv_init(struct ev_loop *, char **, int, int); +struct ResolvQuery *resolv_query(const char *, void (*)(struct sockaddr *, + void *), void (*)( + void *), void *, uint16_t); +void resolv_cancel(struct ResolvQuery *); +void resolv_shutdown(struct ev_loop *); + +#endif diff --git a/shadowsocksr-libev/src/server/rule.c b/shadowsocksr-libev/src/server/rule.c new file mode 100644 index 00000000..41ba5e7d --- /dev/null +++ b/shadowsocksr-libev/src/server/rule.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2011 and 2012, Dustin Lundquist + * Copyright (c) 2011 Manuel Kasper + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#ifdef __MINGW32__ +extern void ss_error(const char *s); +#endif + +#include "rule.h" +#include "utils.h" + +static void free_rule(rule_t *); + +rule_t * +new_rule() +{ + rule_t *rule; + + rule = calloc(1, sizeof(rule_t)); + if (rule == NULL) { + ERROR("malloc"); + return NULL; + } + + return rule; +} + +int +accept_rule_arg(rule_t *rule, const char *arg) +{ + if (rule->pattern == NULL) { + rule->pattern = strdup(arg); + if (rule->pattern == NULL) { + ERROR("strdup failed"); + return -1; + } + } else { + LOGE("Unexpected table rule argument: %s", arg); + return -1; + } + + return 1; +} + +void +add_rule(struct cork_dllist *rules, rule_t *rule) +{ + cork_dllist_add(rules, &rule->entries); +} + +int +init_rule(rule_t *rule) +{ + if (rule->pattern_re == NULL) { + int errornumber; + PCRE2_SIZE erroroffset; + rule->pattern_re = pcre2_compile( + (PCRE2_SPTR)rule->pattern, /* the pattern */ + PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */ + 0, /* default options */ + &errornumber, /* for error number */ + &erroroffset, /* for error offset */ + NULL); /* use default compile context */ + + if (rule->pattern_re == NULL) { + PCRE2_UCHAR errbuffer[512]; + pcre2_get_error_message(errornumber, errbuffer, sizeof(errbuffer)); + LOGE("PCRE2 regex compilation failed at offset %d: %s\n", (int)erroroffset, + errbuffer); + return 0; + } + + rule->pattern_re_match_data = pcre2_match_data_create_from_pattern(rule->pattern_re, NULL); + + if (rule->pattern_re_match_data == NULL) { + ERROR("PCRE2: the memory for the block could not be obtained"); + return 0; + } + } + + return 1; +} + +rule_t * +lookup_rule(const struct cork_dllist *rules, const char *name, size_t name_len) +{ + struct cork_dllist_item *curr, *next; + + if (name == NULL) { + name = ""; + name_len = 0; + } + + cork_dllist_foreach_void(rules, curr, next) { + rule_t *rule = cork_container_of(curr, rule_t, entries); + if (pcre2_match( + rule->pattern_re, /* the compiled pattern */ + (PCRE2_SPTR)name, /* the subject string */ + name_len, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + rule->pattern_re_match_data, /* block for storing the result */ + NULL /* use default match context */ + ) >= 0) + return rule; + } + + return NULL; +} + +void +remove_rule(rule_t *rule) +{ + cork_dllist_remove(&rule->entries); + free_rule(rule); +} + +static void +free_rule(rule_t *rule) +{ + if (rule == NULL) + return; + + ss_free(rule->pattern); + if (rule->pattern_re != NULL) { + pcre2_code_free(rule->pattern_re); /* data and the compiled pattern. */ + rule->pattern_re = NULL; + } + if (rule->pattern_re_match_data != NULL) { + pcre2_match_data_free(rule->pattern_re_match_data); /* Release memory used for the match */ + rule->pattern_re_match_data = NULL; + } + ss_free(rule); +} diff --git a/shadowsocksr-libev/src/server/rule.h b/shadowsocksr-libev/src/server/rule.h new file mode 100644 index 00000000..84a89af6 --- /dev/null +++ b/shadowsocksr-libev/src/server/rule.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 and 2012, Dustin Lundquist + * Copyright (c) 2011 Manuel Kasper + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef RULE_H +#define RULE_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/* + * The PCRE2_CODE_UNIT_WIDTH macro must be defined before including pcre2.h. + * For a program that uses only one code unit width, setting it to 8, 16, or 32 + * makes it possible to use generic function names such as pcre2_compile(). Note + * that just changing 8 to 16 (for example) is not sufficient to convert this + * program to process 16-bit characters. Even in a fully 16-bit environment, where + * string-handling functions such as strcmp() and printf() work with 16-bit + * characters, the code for handling the table of named substrings will still need + * to be modified. + */ +/* we only need to support ASCII chartable, thus set it to 8 */ +#define PCRE2_CODE_UNIT_WIDTH 8 + +#include + +typedef struct rule { + char *pattern; + + /* Runtime fields */ + pcre2_code *pattern_re; + pcre2_match_data *pattern_re_match_data; + + struct cork_dllist_item entries; +} rule_t; + +void add_rule(struct cork_dllist *, rule_t *); +int init_rule(rule_t *); +rule_t *lookup_rule(const struct cork_dllist *, const char *, size_t); +void remove_rule(rule_t *); +rule_t *new_rule(); +int accept_rule_arg(rule_t *, const char *); + +#endif diff --git a/shadowsocksr-libev/src/server/server.c b/shadowsocksr-libev/src/server/server.c new file mode 100644 index 00000000..65b0e42a --- /dev/null +++ b/shadowsocksr-libev/src/server/server.c @@ -0,0 +1,2209 @@ +/* + * server.c - Provide shadowsocks service + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __MINGW32__ +#include +#include +#include +#include +#include +#include +#endif + +#include +#include + +#ifdef __MINGW32__ +#include "win32.h" +#endif + +#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) +#include +#include +#define SET_INTERFACE +#endif + +#include "netutils.h" +#include "utils.h" +#include "acl.h" +#include "server.h" + +#include "obfs.c" // I don't want to modify makefile + +#ifndef EAGAIN +#define EAGAIN EWOULDBLOCK +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK EAGAIN +#endif + +#ifndef BUF_SIZE +#define BUF_SIZE 2048 +#endif + +#ifndef SSMAXCONN +#define SSMAXCONN 1024 +#endif + +#ifndef UPDATE_INTERVAL +#define UPDATE_INTERVAL 30 +#endif + +static void signal_cb(EV_P_ ev_signal *w, int revents); +static void accept_cb(EV_P_ ev_io *w, int revents); +static void server_send_cb(EV_P_ ev_io *w, int revents); +static void server_recv_cb(EV_P_ ev_io *w, int revents); +static void remote_recv_cb(EV_P_ ev_io *w, int revents); +static void remote_send_cb(EV_P_ ev_io *w, int revents); +static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents); +static void block_list_clear_cb(EV_P_ ev_timer *watcher, int revents); + +static remote_t *new_remote(int fd); +static server_t *new_server(int fd, listen_ctx_t *listener); +static remote_t *connect_to_remote(EV_P_ struct addrinfo *res, + server_t *server); + +static void free_remote(remote_t *remote); +static void close_and_free_remote(EV_P_ remote_t *remote); +static void free_server(server_t *server); +static void close_and_free_server(EV_P_ server_t *server); +static void server_resolve_cb(struct sockaddr *addr, void *data); +static void query_free_cb(void *data); + +static size_t parse_header_len(const char atyp, const char *data, size_t offset); +static int is_header_complete(const buffer_t *buf); + +int verbose = 0; + +static int acl = 0; +static int mode = TCP_ONLY; +static int auth = 0; +static int ipv6first = 0; + +static int protocol_compatible = 0;//SSR +static int obfs_compatible = 0;//SSR + +static int fast_open = 0; +#ifdef HAVE_SETRLIMIT +static int nofile = 0; +#endif +static int remote_conn = 0; +static int server_conn = 0; + +static char *bind_address = NULL; +static char *server_port = NULL; +static char *manager_address = NULL; +uint64_t tx = 0; +uint64_t rx = 0; +ev_timer stat_update_watcher; +ev_timer block_list_watcher; + +static struct cork_dllist connections; + +static void +stat_update_cb(EV_P_ ev_timer *watcher, int revents) +{ + struct sockaddr_un svaddr, claddr; + int sfd = -1; + size_t msgLen; + char resp[BUF_SIZE]; + + if (verbose) { + LOGI("update traffic stat: tx: %" PRIu64 " rx: %" PRIu64 "", tx, rx); + } + + snprintf(resp, BUF_SIZE, "stat: {\"%s\":%" PRIu64 "}", server_port, tx + rx); + msgLen = strlen(resp) + 1; + + ss_addr_t ip_addr = { .host = NULL, .port = NULL }; + parse_addr(manager_address, &ip_addr); + + if (ip_addr.host == NULL || ip_addr.port == NULL) { + sfd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (sfd == -1) { + ERROR("stat_socket"); + return; + } + + memset(&claddr, 0, sizeof(struct sockaddr_un)); + claddr.sun_family = AF_UNIX; + snprintf(claddr.sun_path, sizeof(claddr.sun_path), "/tmp/shadowsocks.%s", server_port); + + unlink(claddr.sun_path); + + if (bind(sfd, (struct sockaddr *)&claddr, sizeof(struct sockaddr_un)) == -1) { + ERROR("stat_bind"); + close(sfd); + return; + } + + memset(&svaddr, 0, sizeof(struct sockaddr_un)); + svaddr.sun_family = AF_UNIX; + strncpy(svaddr.sun_path, manager_address, sizeof(svaddr.sun_path) - 1); + + if (sendto(sfd, resp, strlen(resp) + 1, 0, (struct sockaddr *)&svaddr, + sizeof(struct sockaddr_un)) != msgLen) { + ERROR("stat_sendto"); + close(sfd); + return; + } + + unlink(claddr.sun_path); + } else { + struct sockaddr_storage storage; + memset(&storage, 0, sizeof(struct sockaddr_storage)); + if (get_sockaddr(ip_addr.host, ip_addr.port, &storage, 0, ipv6first) == -1) { + ERROR("failed to parse the manager addr"); + return; + } + + sfd = socket(storage.ss_family, SOCK_DGRAM, 0); + + if (sfd == -1) { + ERROR("stat_socket"); + return; + } + + size_t addr_len = get_sockaddr_len((struct sockaddr *)&storage); + if (sendto(sfd, resp, strlen(resp) + 1, 0, (struct sockaddr *)&storage, + addr_len) != msgLen) { + ERROR("stat_sendto"); + close(sfd); + return; + } + } + + close(sfd); +} + +static void +free_connections(struct ev_loop *loop) +{ + struct cork_dllist_item *curr, *next; + cork_dllist_foreach_void(&connections, curr, next) { + server_t *server = cork_container_of(curr, server_t, entries); + remote_t *remote = server->remote; + close_and_free_server(loop, server); + close_and_free_remote(loop, remote); + } +} + +static size_t +parse_header_len(const char atyp, const char *data, size_t offset) +{ + size_t len = 0; + if ((atyp & ADDRTYPE_MASK) == 1) { + // IP V4 + len += sizeof(struct in_addr); + } else if ((atyp & ADDRTYPE_MASK) == 3) { + // Domain name + uint8_t name_len = *(uint8_t *)(data + offset); + len += name_len + 1; + } else if ((atyp & ADDRTYPE_MASK) == 4) { + // IP V6 + len += sizeof(struct in6_addr); + } else { + return 0; + } + len += 2; + return len; +} + +static int +is_header_complete(const buffer_t *buf) +{ + size_t header_len = 0; + size_t buf_len = buf->len; + + char atyp = buf->array[header_len]; + + // 1 byte for atyp + header_len++; + + if ((atyp & ADDRTYPE_MASK) == 1) { + // IP V4 + header_len += sizeof(struct in_addr); + } else if ((atyp & ADDRTYPE_MASK) == 3) { + // Domain name + // domain len + len of domain + if (buf_len < header_len + 1) + return 0; + uint8_t name_len = *(uint8_t *)(buf->array + header_len); + header_len += name_len + 1; + } else if ((atyp & ADDRTYPE_MASK) == 4) { + // IP V6 + header_len += sizeof(struct in6_addr); + } else { + return -1; + } + + // len of port + header_len += 2; + + // size of ONETIMEAUTH_BYTES + if (auth || (atyp & ONETIMEAUTH_FLAG)) { + header_len += ONETIMEAUTH_BYTES; + } + + return buf_len >= header_len ? 1 : 0; +} + +static char * +get_peer_name(int fd) +{ + static char peer_name[INET6_ADDRSTRLEN] = { 0 }; + struct sockaddr_storage addr; + socklen_t len = sizeof(struct sockaddr_storage); + memset(&addr, 0, len); + memset(peer_name, 0, INET6_ADDRSTRLEN); + int err = getpeername(fd, (struct sockaddr *)&addr, &len); + if (err == 0) { + if (addr.ss_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + dns_ntop(AF_INET, &s->sin_addr, peer_name, INET_ADDRSTRLEN); + } else if (addr.ss_family == AF_INET6) { + struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; + dns_ntop(AF_INET6, &s->sin6_addr, peer_name, INET6_ADDRSTRLEN); + } + } else { + return NULL; + } + return peer_name; +} + +#ifdef __linux__ +static void +set_linger(int fd) +{ + struct linger so_linger; + memset(&so_linger, 0, sizeof(struct linger)); + so_linger.l_onoff = 1; + so_linger.l_linger = 0; + setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); +} +#endif + +static void +reset_addr(int fd) +{ + char *peer_name; + peer_name = get_peer_name(fd); + if (peer_name != NULL) { + remove_from_block_list(peer_name); + } +} + +static void +report_addr(int fd, int err_level) +{ +#ifdef __linux__ + set_linger(fd); +#endif + + char *peer_name; + peer_name = get_peer_name(fd); + if (peer_name != NULL) { + LOGE("failed to handshake with %s", peer_name); + update_block_list(peer_name, err_level); + } +} + +int +setfastopen(int fd) +{ + int s = 0; +#ifdef TCP_FASTOPEN + if (fast_open) { +#ifdef __APPLE__ + int opt = 1; +#else + int opt = 5; +#endif + s = setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &opt, sizeof(opt)); + + if (s == -1) { + if (errno == EPROTONOSUPPORT || errno == ENOPROTOOPT) { + LOGE("fast open is not supported on this platform"); + fast_open = 0; + } else { + ERROR("setsockopt"); + } + } + } +#endif + return s; +} + +#ifndef __MINGW32__ +int +setnonblocking(int fd) +{ + int flags; + if (-1 == (flags = fcntl(fd, F_GETFL, 0))) { + flags = 0; + } + return fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +#endif + +int +create_and_bind(const char *host, const char *port, int mptcp) +{ + struct addrinfo hints; + struct addrinfo *result, *rp, *ipv4v6bindall; + int s, listen_sock; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ + hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ + hints.ai_protocol = IPPROTO_TCP; + + for (int i = 1; i < 8; i++) { + s = getaddrinfo(host, port, &hints, &result); + if (s == 0) { + break; + } else { + sleep(pow(2, i)); + LOGE("failed to resolve server name, wait %.0f seconds", pow(2, i)); + } + } + + if (s != 0) { + LOGE("getaddrinfo: %s", gai_strerror(s)); + return -1; + } + + rp = result; + + /* + * On Linux, with net.ipv6.bindv6only = 0 (the default), getaddrinfo(NULL) with + * AI_PASSIVE returns 0.0.0.0 and :: (in this order). AI_PASSIVE was meant to + * return a list of addresses to listen on, but it is impossible to listen on + * 0.0.0.0 and :: at the same time, if :: implies dualstack mode. + */ + if (!host) { + ipv4v6bindall = result; + + /* Loop over all address infos found until a IPV6 address is found. */ + while (ipv4v6bindall) { + if (ipv4v6bindall->ai_family == AF_INET6) { + rp = ipv4v6bindall; /* Take first IPV6 address available */ + break; + } + ipv4v6bindall = ipv4v6bindall->ai_next; /* Get next address info, if any */ + } + } + + for (/*rp = result*/; rp != NULL; rp = rp->ai_next) { + listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (listen_sock == -1) { + continue; + } + + if (rp->ai_family == AF_INET6) { + int ipv6only = host ? 1 : 0; + setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)); + } + + int opt = 1; + setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); +#ifdef SO_NOSIGPIPE + setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); +#endif + int err = set_reuseport(listen_sock); + if (err == 0) { + LOGI("tcp port reuse enabled"); + } + + if (mptcp == 1) { + int err = setsockopt(listen_sock, SOL_TCP, MPTCP_ENABLED, &opt, sizeof(opt)); + if (err == -1) { + ERROR("failed to enable multipath TCP"); + } + } + + s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); + if (s == 0) { + /* We managed to bind successfully! */ + break; + } else { + ERROR("bind"); + } + + close(listen_sock); + } + + if (rp == NULL) { + LOGE("Could not bind"); + return -1; + } + + freeaddrinfo(result); + + return listen_sock; +} + +static remote_t * +connect_to_remote(EV_P_ struct addrinfo *res, + server_t *server) +{ + int sockfd; +#ifdef SET_INTERFACE + const char *iface = server->listen_ctx->iface; +#endif + + if (acl) { + char ipstr[INET6_ADDRSTRLEN]; + memset(ipstr, 0, INET6_ADDRSTRLEN); + + if (res->ai_addr->sa_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in *)res->ai_addr; + dns_ntop(AF_INET, &s->sin_addr, ipstr, INET_ADDRSTRLEN); + } else if (res->ai_addr->sa_family == AF_INET6) { + struct sockaddr_in6 *s = (struct sockaddr_in6 *)res->ai_addr; + dns_ntop(AF_INET6, &s->sin6_addr, ipstr, INET6_ADDRSTRLEN); + } + + if (outbound_block_match_host(ipstr) == 1) { + if (verbose) + LOGI("outbound blocked %s", ipstr); + return NULL; + } + } + + // initialize remote socks + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd == -1) { + ERROR("socket"); + close(sockfd); + return NULL; + } + + int opt = 1; + setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); +#ifdef SO_NOSIGPIPE + setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); +#endif + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + // setup remote socks + + if (setnonblocking(sockfd) == -1) + ERROR("setnonblocking"); + + if (bind_address != NULL) + if (bind_to_address(sockfd, bind_address) == -1) { + ERROR("bind_to_address"); + close(sockfd); + return NULL; + } + +#ifdef SET_INTERFACE + if (iface) { + if (setinterface(sockfd, iface) == -1) { + ERROR("setinterface"); + close(sockfd); + return NULL; + } + } +#endif + + remote_t *remote = new_remote(sockfd); + +#ifdef TCP_FASTOPEN + if (fast_open) { +#ifdef __APPLE__ + ((struct sockaddr_in *)(res->ai_addr))->sin_len = sizeof(struct sockaddr_in); + sa_endpoints_t endpoints; + memset((char *)&endpoints, 0, sizeof(endpoints)); + endpoints.sae_dstaddr = res->ai_addr; + endpoints.sae_dstaddrlen = res->ai_addrlen; + + struct iovec iov; + iov.iov_base = server->buf->array + server->buf->idx; + iov.iov_len = server->buf->len; + size_t len; + int s = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, CONNECT_DATA_IDEMPOTENT, + &iov, 1, &len, NULL); + if (s == 0) { + s = len; + } +#else + ssize_t s = sendto(sockfd, server->buf->array + server->buf->idx, + server->buf->len, MSG_FASTOPEN, res->ai_addr, + res->ai_addrlen); +#endif + if (s == -1) { + if (errno == CONNECT_IN_PROGRESS || errno == EAGAIN + || errno == EWOULDBLOCK) { + // The remote server doesn't support tfo or it's the first connection to the server. + // It will automatically fall back to conventional TCP. + } else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || + errno == ENOPROTOOPT) { + // Disable fast open as it's not supported + fast_open = 0; + LOGE("fast open is not supported on this platform"); + } else { + ERROR("sendto"); + } + } else if (s <= server->buf->len) { + server->buf->idx += s; + server->buf->len -= s; + } else { + server->buf->idx = 0; + server->buf->len = 0; + } + } +#endif + + if (!fast_open) { + int r = connect(sockfd, res->ai_addr, res->ai_addrlen); + + if (r == -1 && errno != CONNECT_IN_PROGRESS) { + ERROR("connect"); + close_and_free_remote(EV_A_ remote); + return NULL; + } + } + + return remote; +} + +static void +server_recv_cb(EV_P_ ev_io *w, int revents) +{ + server_ctx_t *server_recv_ctx = (server_ctx_t *)w; + server_t *server = server_recv_ctx->server; + remote_t *remote = NULL; + + int len = server->buf->len; + buffer_t *buf = server->buf; + + if (server->stage > STAGE_PARSE) { + remote = server->remote; + buf = remote->buf; + len = 0; + + ev_timer_again(EV_A_ & server->recv_ctx->watcher); + } + + if (len > BUF_SIZE) { + ERROR("out of recv buffer"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + + ssize_t r = recv(server->fd, buf->array + len, BUF_SIZE - len, 0); + + if (r == 0) { + // connection closed + if (verbose) { + LOGI("server_recv close the connection"); + } + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } else if (r == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // no data + // continue to wait for recv + return; + } else { + ERROR("server recv"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + + tx += r; + + if (server->stage == STAGE_ERROR) { + server->buf->len = 0; + server->buf->idx = 0; + return; + } + + // handle incomplete header part 1 + if (server->stage == STAGE_INIT) { + buf->len += r; + if (buf->len <= enc_get_iv_len() + 1) { + // wait for more + return; + } + } else { + buf->len = r; + } + + // SSR beg + + if (server->obfs_plugin) { + obfs_class *obfs_plugin = server->obfs_plugin; + if (obfs_plugin->server_decode) { + int needsendback = 0; + + if(obfs_compatible == 1) + { + char *back_buf = (char*)malloc(sizeof(buffer_t)); + memcpy(back_buf, buf, sizeof(buffer_t)); + buf->len = obfs_plugin->server_decode(server->obfs, &buf->array, buf->len, &buf->capacity, &needsendback); + + if ((int)buf->len < 0) + { + LOGE("obfs_compatible"); + memcpy(buf, back_buf, sizeof(buffer_t)); + free(back_buf); + server->obfs_compatible_state = 1; + } + } + else + { + buf->len = obfs_plugin->server_decode(server->obfs, &buf->array, buf->len, &buf->capacity, &needsendback); + if ((int)buf->len < 0) { + LOGE("server_decode"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + + if (needsendback) { + size_t capacity = BUF_SIZE; + char *sendback_buf = (char*)malloc(capacity); + obfs_class *obfs_plugin = server->obfs_plugin; + if (obfs_plugin->server_encode) { + int len = obfs_plugin->server_encode(server->obfs, &sendback_buf, 0, &capacity); + send(server->fd, sendback_buf, len, 0); + } + free(sendback_buf); + return; + } + } + } + + int err = ss_decrypt(buf, server->d_ctx, BUF_SIZE); + + if (err) { + report_addr(server->fd, MALICIOUS); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + + if (server->protocol_plugin) { + obfs_class *protocol_plugin = server->protocol_plugin; + if (protocol_plugin->server_post_decrypt) { + + if(protocol_compatible == 1) + { + char *back_buf = (char*)malloc(sizeof(buffer_t)); + memcpy(back_buf, buf, sizeof(buffer_t)); + buf->len = protocol_plugin->server_post_decrypt(server->protocol, &buf->array, buf->len, &buf->capacity); + + if ((int)buf->len < 0) { + LOGE("protocol_compatible"); + memcpy(buf, back_buf, sizeof(buffer_t)); + free(back_buf); + server->protocol_compatible_state = 1; + } + if ( buf->len == 0 ) + { + LOGE("protocol_compatible"); + memcpy(buf, back_buf, sizeof(buffer_t)); + free(back_buf); + server->protocol_compatible_state = 1; + } + } + else + { + buf->len = protocol_plugin->server_post_decrypt(server->protocol, &buf->array, buf->len, &buf->capacity); + if ((int)buf->len < 0) { + LOGE("server_post_decrypt"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + if ( buf->len == 0 ) + { + LOGE("server_post_decrypt"); + return; + } + } + } + } + // SSR end + + // handle incomplete header part 2 + if (server->stage == STAGE_INIT) { + int ret = is_header_complete(server->buf); + if (ret == 1) { + bfree(server->header_buf); + ss_free(server->header_buf); + server->stage = STAGE_PARSE; + } else if (ret == -1) { + server->stage = STAGE_ERROR; + report_addr(server->fd, MALFORMED); + server->buf->len = 0; + server->buf->idx = 0; + return; + } else { + server->stage = STAGE_HANDSHAKE; + } + } + + if (server->stage == STAGE_HANDSHAKE) { + size_t header_len = server->header_buf->len; + brealloc(server->header_buf, server->buf->len + header_len, BUF_SIZE); + memcpy(server->header_buf->array + header_len, + server->buf->array, server->buf->len); + server->header_buf->len = server->buf->len + header_len; + + int ret = is_header_complete(server->buf); + + if (ret == 1) { + brealloc(server->buf, server->header_buf->len, BUF_SIZE); + memcpy(server->buf->array, server->header_buf->array, server->header_buf->len); + server->buf->len = server->header_buf->len; + bfree(server->header_buf); + ss_free(server->header_buf); + server->stage = STAGE_PARSE; + } else { + if (ret == -1) + server->stage = STAGE_ERROR; + server->buf->len = 0; + server->buf->idx = 0; + return; + } + } + + // handshake and transmit data + if (server->stage == STAGE_STREAM) { + if (server->auth && !ss_check_hash(remote->buf, server->chunk, server->d_ctx, BUF_SIZE)) { + LOGE("hash error"); + report_addr(server->fd, BAD); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + + int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); + if (s == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // no data, wait for send + remote->buf->idx = 0; + ev_io_stop(EV_A_ & server_recv_ctx->io); + ev_io_start(EV_A_ & remote->send_ctx->io); + } else { + ERROR("server_recv_send"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + } + } else if (s < remote->buf->len) { + remote->buf->len -= s; + remote->buf->idx = s; + ev_io_stop(EV_A_ & server_recv_ctx->io); + ev_io_start(EV_A_ & remote->send_ctx->io); + } + return; + } else if (server->stage == STAGE_PARSE) { + /* + * Shadowsocks TCP Relay Header: + * + * +------+----------+----------+----------------+ + * | ATYP | DST.ADDR | DST.PORT | HMAC-SHA1 | + * +------+----------+----------+----------------+ + * | 1 | Variable | 2 | 10 | + * +------+----------+----------+----------------+ + * + * If ATYP & ONETIMEAUTH_FLAG(0x10) != 0, Authentication (HMAC-SHA1) is enabled. + * + * The key of HMAC-SHA1 is (IV + KEY) and the input is the whole header. + * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). + */ + + /* + * Shadowsocks Request's Chunk Authentication for TCP Relay's payload + * (No chunk authentication for response's payload): + * + * +------+-----------+-------------+------+ + * | LEN | HMAC-SHA1 | DATA | ... + * +------+-----------+-------------+------+ + * | 2 | 10 | Variable | ... + * +------+-----------+-------------+------+ + * + * The key of HMAC-SHA1 is (IV + CHUNK ID) + * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). + */ + + int offset = 0; + int need_query = 0; + char atyp = server->buf->array[offset++]; + char host[257] = { 0 }; + uint16_t port = 0; + struct addrinfo info; + struct sockaddr_storage storage; + memset(&info, 0, sizeof(struct addrinfo)); + memset(&storage, 0, sizeof(struct sockaddr_storage)); + + if (auth || (atyp & ONETIMEAUTH_FLAG)) { + size_t header_len = parse_header_len(atyp, server->buf->array, offset); + size_t len = server->buf->len; + + if (header_len == 0 || len < offset + header_len + ONETIMEAUTH_BYTES) { + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } + + server->buf->len = offset + header_len + ONETIMEAUTH_BYTES; + if (ss_onetimeauth_verify(server->buf, server->d_ctx->evp.iv)) { + report_addr(server->fd, BAD); + close_and_free_server(EV_A_ server); + return; + } + + server->buf->len = len; + server->auth = 1; + } + + // get remote addr and port + if ((atyp & ADDRTYPE_MASK) == 1) { + // IP V4 + struct sockaddr_in *addr = (struct sockaddr_in *)&storage; + size_t in_addr_len = sizeof(struct in_addr); + addr->sin_family = AF_INET; + if (server->buf->len >= in_addr_len + 3) { + addr->sin_addr = *(struct in_addr *)(server->buf->array + offset); + dns_ntop(AF_INET, (const void *)(server->buf->array + offset), + host, INET_ADDRSTRLEN); + offset += in_addr_len; + } else { + LOGE("invalid header with addr type %d", atyp); + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } + addr->sin_port = *(uint16_t *)(server->buf->array + offset); + info.ai_family = AF_INET; + info.ai_socktype = SOCK_STREAM; + info.ai_protocol = IPPROTO_TCP; + info.ai_addrlen = sizeof(struct sockaddr_in); + info.ai_addr = (struct sockaddr *)addr; + } else if ((atyp & ADDRTYPE_MASK) == 3) { + // Domain name + uint8_t name_len = *(uint8_t *)(server->buf->array + offset); + if (name_len + 4 <= server->buf->len) { + memcpy(host, server->buf->array + offset + 1, name_len); + offset += name_len + 1; + } else { + LOGE("invalid name length: %d", name_len); + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } + if (acl && outbound_block_match_host(host) == 1) { + if (verbose) + LOGI("outbound blocked %s", host); + close_and_free_server(EV_A_ server); + return; + } + struct cork_ip ip; + if (cork_ip_init(&ip, host) != -1) { + info.ai_socktype = SOCK_STREAM; + info.ai_protocol = IPPROTO_TCP; + if (ip.version == 4) { + struct sockaddr_in *addr = (struct sockaddr_in *)&storage; + dns_pton(AF_INET, host, &(addr->sin_addr)); + addr->sin_port = *(uint16_t *)(server->buf->array + offset); + addr->sin_family = AF_INET; + info.ai_family = AF_INET; + info.ai_addrlen = sizeof(struct sockaddr_in); + info.ai_addr = (struct sockaddr *)addr; + } else if (ip.version == 6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; + dns_pton(AF_INET6, host, &(addr->sin6_addr)); + addr->sin6_port = *(uint16_t *)(server->buf->array + offset); + addr->sin6_family = AF_INET6; + info.ai_family = AF_INET6; + info.ai_addrlen = sizeof(struct sockaddr_in6); + info.ai_addr = (struct sockaddr *)addr; + } + } else { + if (!validate_hostname(host, name_len)) { + LOGE("invalid host name"); + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } + need_query = 1; + } + } else if ((atyp & ADDRTYPE_MASK) == 4) { + // IP V6 + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; + size_t in6_addr_len = sizeof(struct in6_addr); + addr->sin6_family = AF_INET6; + if (server->buf->len >= in6_addr_len + 3) { + addr->sin6_addr = *(struct in6_addr *)(server->buf->array + offset); + dns_ntop(AF_INET6, (const void *)(server->buf->array + offset), + host, INET6_ADDRSTRLEN); + offset += in6_addr_len; + } else { + LOGE("invalid header with addr type %d", atyp); + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } + addr->sin6_port = *(uint16_t *)(server->buf->array + offset); + info.ai_family = AF_INET6; + info.ai_socktype = SOCK_STREAM; + info.ai_protocol = IPPROTO_TCP; + info.ai_addrlen = sizeof(struct sockaddr_in6); + info.ai_addr = (struct sockaddr *)addr; + } + + if (offset == 1) { + LOGE("invalid header with addr type %d", atyp); + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } + + port = (*(uint16_t *)(server->buf->array + offset)); + + offset += 2; + + if (server->auth) { + offset += ONETIMEAUTH_BYTES; + } + + if (server->buf->len < offset) { + report_addr(server->fd, MALFORMED); + close_and_free_server(EV_A_ server); + return; + } else { + server->buf->len -= offset; + memmove(server->buf->array, server->buf->array + offset, server->buf->len); + } + + if (verbose) { + if ((atyp & ADDRTYPE_MASK) == 4) + LOGI("connect to [%s]:%d", host, ntohs(port)); + else + LOGI("connect to %s:%d", host, ntohs(port)); + } + + if (server->auth && !ss_check_hash(server->buf, server->chunk, server->d_ctx, BUF_SIZE)) { + LOGE("hash error"); + report_addr(server->fd, BAD); + close_and_free_server(EV_A_ server); + return; + } + + + if (!need_query) { + remote_t *remote = connect_to_remote(EV_A_ &info, server); + + if (remote == NULL) { + LOGE("connect error"); + close_and_free_server(EV_A_ server); + return; + } else { + server->remote = remote; + remote->server = server; + + // XXX: should handle buffer carefully + if (server->buf->len > 0) { + memcpy(remote->buf->array, server->buf->array, server->buf->len); + remote->buf->len = server->buf->len; + remote->buf->idx = 0; + server->buf->len = 0; + server->buf->idx = 0; + } + + // waiting on remote connected event + ev_io_stop(EV_A_ & server_recv_ctx->io); + ev_io_start(EV_A_ & remote->send_ctx->io); + } + } else { + query_t *query = (query_t *)ss_malloc(sizeof(query_t)); + query->server = server; + snprintf(query->hostname, 256, "%s", host); + + server->stage = STAGE_RESOLVE; + server->query = resolv_query(host, server_resolve_cb, + query_free_cb, query, port); + + ev_io_stop(EV_A_ & server_recv_ctx->io); + } + + return; + } + // should not reach here + FATAL("server context error"); +} + +static void +server_send_cb(EV_P_ ev_io *w, int revents) +{ + server_ctx_t *server_send_ctx = (server_ctx_t *)w; + server_t *server = server_send_ctx->server; + remote_t *remote = server->remote; + + if (remote == NULL) { + LOGE("invalid server"); + close_and_free_server(EV_A_ server); + return; + } + + if (server->buf->len == 0) { + // close and free + if (verbose) { + LOGI("server_send close the connection"); + } + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } else { + // has data to send + ssize_t s = send(server->fd, server->buf->array + server->buf->idx, + server->buf->len, 0); + if (s == -1) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { + ERROR("server_send_send"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + } + return; + } else if (s < server->buf->len) { + // partly sent, move memory, wait for the next time to send + server->buf->len -= s; + server->buf->idx += s; + return; + } else { + // all sent out, wait for reading + server->buf->len = 0; + server->buf->idx = 0; + ev_io_stop(EV_A_ & server_send_ctx->io); + if (remote != NULL) { + ev_io_start(EV_A_ & remote->recv_ctx->io); + return; + } else { + LOGE("invalid remote"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + } +} + +static void +block_list_clear_cb(EV_P_ ev_timer *watcher, int revents) +{ + clear_block_list(); +} + +static void +server_timeout_cb(EV_P_ ev_timer *watcher, int revents) +{ + server_ctx_t *server_ctx + = cork_container_of(watcher, server_ctx_t, watcher); + server_t *server = server_ctx->server; + remote_t *remote = server->remote; + + if (verbose) { + LOGI("TCP connection timeout"); + } + + if (server->stage < STAGE_PARSE) { + if (verbose) { + size_t len = server->stage ? + server->header_buf->len : server->buf->len; +#ifdef __MINGW32__ + LOGI("incomplete header: %u", len); +#else + LOGI("incomplete header: %zu", len); +#endif + } + report_addr(server->fd, SUSPICIOUS); + } + + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); +} + +static void +query_free_cb(void *data) +{ + if (data != NULL) { + ss_free(data); + } +} + +static void +server_resolve_cb(struct sockaddr *addr, void *data) +{ + query_t *query = (query_t *)data; + server_t *server = query->server; + struct ev_loop *loop = server->listen_ctx->loop; + + server->query = NULL; + + if (addr == NULL) { + LOGE("unable to resolve %s", query->hostname); + close_and_free_server(EV_A_ server); + } else { + if (verbose) { + LOGI("successfully resolved %s", query->hostname); + } + + struct addrinfo info; + memset(&info, 0, sizeof(struct addrinfo)); + info.ai_socktype = SOCK_STREAM; + info.ai_protocol = IPPROTO_TCP; + info.ai_addr = addr; + + if (addr->sa_family == AF_INET) { + info.ai_family = AF_INET; + info.ai_addrlen = sizeof(struct sockaddr_in); + } else if (addr->sa_family == AF_INET6) { + info.ai_family = AF_INET6; + info.ai_addrlen = sizeof(struct sockaddr_in6); + } + + remote_t *remote = connect_to_remote(EV_A_ &info, server); + + if (remote == NULL) { + close_and_free_server(EV_A_ server); + } else { + server->remote = remote; + remote->server = server; + + // XXX: should handle buffer carefully + if (server->buf->len > 0) { + memcpy(remote->buf->array, server->buf->array + server->buf->idx, + server->buf->len); + remote->buf->len = server->buf->len; + remote->buf->idx = 0; + server->buf->len = 0; + server->buf->idx = 0; + } + + // listen to remote connected event + ev_io_start(EV_A_ & remote->send_ctx->io); + } + } +} + +static void +remote_recv_cb(EV_P_ ev_io *w, int revents) +{ + remote_ctx_t *remote_recv_ctx = (remote_ctx_t *)w; + remote_t *remote = remote_recv_ctx->remote; + server_t *server = remote->server; + + if (server == NULL) { + LOGE("invalid server"); + close_and_free_remote(EV_A_ remote); + return; + } + + ev_timer_again(EV_A_ & server->recv_ctx->watcher); + + ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); + + if (r == 0) { + // connection closed + if (verbose) { + LOGI("remote_recv close the connection"); + } + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } else if (r == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // no data + // continue to wait for recv + return; + } else { + ERROR("remote recv"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + + rx += r; + + server->buf->len = r; + + // SSR beg + server_info _server_info; + if (server->obfs_plugin) { + server->obfs_plugin->get_server_info(server->obfs, &_server_info); + _server_info.head_len = get_head_size(server->buf->array, server->buf->len, 30); + server->obfs_plugin->set_server_info(server->obfs, &_server_info); + } + + if (server->protocol_plugin && server->obfs_compatible_state == 0) { + obfs_class *protocol_plugin = server->protocol_plugin; + if (protocol_plugin->server_pre_encrypt) { + server->buf->len = protocol_plugin->server_pre_encrypt(server->protocol, &server->buf->array, server->buf->len, &server->buf->capacity); + } + } + + int err = ss_encrypt(server->buf, server->e_ctx, BUF_SIZE); + + if (err) { + LOGE("invalid password or cipher"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + + if (server->obfs_plugin && server->obfs_compatible_state == 0) { + obfs_class *obfs_plugin = server->obfs_plugin; + if (obfs_plugin->server_encode) { + server->buf->len = obfs_plugin->server_encode(server->obfs, &server->buf->array, server->buf->len, &server->buf->capacity); + } + } + // SSR end + + int s = send(server->fd, server->buf->array, server->buf->len, 0); + + if (s == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // no data, wait for send + server->buf->idx = 0; + ev_io_stop(EV_A_ & remote_recv_ctx->io); + ev_io_start(EV_A_ & server->send_ctx->io); + } else { + ERROR("remote_recv_send"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } else if (s < server->buf->len) { + server->buf->len -= s; + server->buf->idx = s; + ev_io_stop(EV_A_ & remote_recv_ctx->io); + ev_io_start(EV_A_ & server->send_ctx->io); + } + + // Disable TCP_NODELAY after the first response are sent + if (!remote->recv_ctx->connected) { + int opt = 0; + setsockopt(server->fd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); + setsockopt(remote->fd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); + remote->recv_ctx->connected = 1; + } +} + +static void +remote_send_cb(EV_P_ ev_io *w, int revents) +{ + remote_ctx_t *remote_send_ctx = (remote_ctx_t *)w; + remote_t *remote = remote_send_ctx->remote; + server_t *server = remote->server; + + if (server == NULL) { + LOGE("invalid server"); + close_and_free_remote(EV_A_ remote); + return; + } + + if (!remote_send_ctx->connected) { + struct sockaddr_storage addr; + socklen_t len = sizeof(struct sockaddr_storage); + memset(&addr, 0, len); + int r = getpeername(remote->fd, (struct sockaddr *)&addr, &len); + if (r == 0) { + if (verbose) { + LOGI("remote connected"); + } + remote_send_ctx->connected = 1; + + // Clear the state of this address in the block list + reset_addr(server->fd); + + if (remote->buf->len == 0) { + server->stage = STAGE_STREAM; + ev_io_stop(EV_A_ & remote_send_ctx->io); + ev_io_start(EV_A_ & server->recv_ctx->io); + ev_io_start(EV_A_ & remote->recv_ctx->io); + return; + } + } else { + ERROR("getpeername"); + // not connected + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + + if (remote->buf->len == 0) { + // close and free + if (verbose) { + LOGI("remote_send close the connection"); + } + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } else { + // has data to send + ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, + remote->buf->len, 0); + if (s == -1) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { + ERROR("remote_send_send"); + // close and free + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + } + return; + } else if (s < remote->buf->len) { + // partly sent, move memory, wait for the next time to send + remote->buf->len -= s; + remote->buf->idx += s; + return; + } else { + // all sent out, wait for reading + remote->buf->len = 0; + remote->buf->idx = 0; + ev_io_stop(EV_A_ & remote_send_ctx->io); + if (server != NULL) { + ev_io_start(EV_A_ & server->recv_ctx->io); + if (server->stage != STAGE_STREAM) { + server->stage = STAGE_STREAM; + ev_io_start(EV_A_ & remote->recv_ctx->io); + } + } else { + LOGE("invalid server"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + } + return; + } + } +} + +static remote_t * +new_remote(int fd) +{ + if (verbose) { + remote_conn++; + } + + remote_t *remote; + + remote = ss_malloc(sizeof(remote_t)); + remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->buf = ss_malloc(sizeof(buffer_t)); + remote->fd = fd; + remote->recv_ctx->remote = remote; + remote->recv_ctx->connected = 0; + remote->send_ctx->remote = remote; + remote->send_ctx->connected = 0; + remote->server = NULL; + + ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); + ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); + + balloc(remote->buf, BUF_SIZE); + + return remote; +} + +static void +free_remote(remote_t *remote) +{ + if (remote->server != NULL) { + remote->server->remote = NULL; + } + if (remote->buf != NULL) { + bfree(remote->buf); + ss_free(remote->buf); + } + ss_free(remote->recv_ctx); + ss_free(remote->send_ctx); + ss_free(remote); +} + +static void +close_and_free_remote(EV_P_ remote_t *remote) +{ + if (remote != NULL) { + ev_io_stop(EV_A_ & remote->send_ctx->io); + ev_io_stop(EV_A_ & remote->recv_ctx->io); + close(remote->fd); + free_remote(remote); + if (verbose) { + remote_conn--; + LOGI("current remote connection: %d", remote_conn); + } + } +} + +static server_t * +new_server(int fd, listen_ctx_t *listener) +{ + if (verbose) { + server_conn++; + } + + server_t *server; + server = ss_malloc(sizeof(server_t)); + + memset(server, 0, sizeof(server_t)); + + server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); + server->send_ctx = ss_malloc(sizeof(server_ctx_t)); + server->buf = ss_malloc(sizeof(buffer_t)); + server->header_buf = ss_malloc(sizeof(buffer_t)); + server->fd = fd; + server->recv_ctx->server = server; + server->recv_ctx->connected = 0; + server->send_ctx->server = server; + server->send_ctx->connected = 0; + server->stage = STAGE_INIT; + server->query = NULL; + server->listen_ctx = listener; + server->remote = NULL; + + if (listener->method) { + server->e_ctx = ss_malloc(sizeof(enc_ctx_t)); + server->d_ctx = ss_malloc(sizeof(enc_ctx_t)); + enc_ctx_init(listener->method, server->e_ctx, 1); + enc_ctx_init(listener->method, server->d_ctx, 0); + } else { + server->e_ctx = NULL; + server->d_ctx = NULL; + } + + int request_timeout = min(MAX_REQUEST_TIMEOUT, listener->timeout) + + rand() % MAX_REQUEST_TIMEOUT; + + ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); + ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); + ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, + request_timeout, listener->timeout); + + balloc(server->buf, BUF_SIZE); + balloc(server->header_buf, BUF_SIZE); + + server->chunk = (chunk_t *)malloc(sizeof(chunk_t)); + memset(server->chunk, 0, sizeof(chunk_t)); + server->chunk->buf = ss_malloc(sizeof(buffer_t)); + memset(server->chunk->buf, 0, sizeof(buffer_t)); + + cork_dllist_add(&connections, &server->entries); + + return server; +} + +static void +free_server(server_t *server) +{ + cork_dllist_remove(&server->entries); + + if (server->chunk != NULL) { + if (server->chunk->buf != NULL) { + bfree(server->chunk->buf); + ss_free(server->chunk->buf); + } + ss_free(server->chunk); + } + if (server->remote != NULL) { + server->remote->server = NULL; + } + if (server->e_ctx != NULL) { + cipher_context_release(&server->e_ctx->evp); + ss_free(server->e_ctx); + } + if (server->d_ctx != NULL) { + cipher_context_release(&server->d_ctx->evp); + ss_free(server->d_ctx); + } + if (server->buf != NULL) { + bfree(server->buf); + ss_free(server->buf); + } + if (server->header_buf != NULL) { + bfree(server->header_buf); + ss_free(server->header_buf); + } + + ss_free(server->recv_ctx); + ss_free(server->send_ctx); + ss_free(server); +} + +static void +close_and_free_server(EV_P_ server_t *server) +{ + if (server != NULL) { + if (server->query != NULL) { + resolv_cancel(server->query); + server->query = NULL; + } + ev_io_stop(EV_A_ & server->send_ctx->io); + ev_io_stop(EV_A_ & server->recv_ctx->io); + ev_timer_stop(EV_A_ & server->recv_ctx->watcher); + close(server->fd); + free_server(server); + if (verbose) { + server_conn--; + LOGI("current server connection: %d", server_conn); + } + } +} + +static void +signal_cb(EV_P_ ev_signal *w, int revents) +{ + if (revents & EV_SIGNAL) { + switch (w->signum) { + case SIGINT: + case SIGTERM: + ev_unloop(EV_A_ EVUNLOOP_ALL); + } + } +} + +static void +accept_cb(EV_P_ ev_io *w, int revents) +{ + listen_ctx_t *listener = (listen_ctx_t *)w; + int serverfd = accept(listener->fd, NULL, NULL); + if (serverfd == -1) { + ERROR("accept"); + return; + } + + char *peer_name = get_peer_name(serverfd); + if (peer_name != NULL) { + int in_white_list = 0; + if (acl) { + if ((get_acl_mode() == BLACK_LIST && acl_match_host(peer_name) == 1) + || (get_acl_mode() == WHITE_LIST && acl_match_host(peer_name) >= 0)) { + LOGE("Access denied from %s", peer_name); + close(serverfd); + return; + } else if (acl_match_host(peer_name) == -1) { + in_white_list = 1; + } + } + if (!in_white_list && check_block_list(peer_name)) { + LOGE("block all requests from %s", peer_name); +#ifdef __linux__ + set_linger(serverfd); +#endif + close(serverfd); + return; + } + } + + int opt = 1; + setsockopt(serverfd, SOL_TCP, TCP_NODELAY, &opt, sizeof(opt)); +#ifdef SO_NOSIGPIPE + setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); +#endif + setnonblocking(serverfd); + + if (verbose) { + LOGI("accept a connection"); + } + + server_t *server = new_server(serverfd, listener); + + // SSR beg + server->obfs_plugin = new_obfs_class(server->listen_ctx->obfs_name); + if (server->obfs_plugin) { + server->obfs = server->obfs_plugin->new_obfs(); + server->obfs_compatible_state = 0; + } + server->protocol_plugin = new_obfs_class(server->listen_ctx->protocol_name); + if (server->protocol_plugin) { + server->protocol = server->protocol_plugin->new_obfs(); + server->protocol_compatible_state = 0; + } + server_info _server_info; + memset(&_server_info, 0, sizeof(server_info)); + _server_info.param = server->listen_ctx->obfs_param; + if(server->obfs_plugin) + _server_info.g_data = server->obfs_plugin->init_data(); + _server_info.head_len = 7; + _server_info.iv = server->e_ctx->evp.iv; + _server_info.iv_len = enc_get_iv_len(); + _server_info.key = enc_get_key(); + _server_info.key_len = enc_get_key_len(); + _server_info.tcp_mss = 1460; + + if (server->obfs_plugin) + server->obfs_plugin->set_server_info(server->obfs, &_server_info); + + _server_info.param = server->listen_ctx->protocol_param; + if (server->protocol_plugin) + _server_info.g_data = server->protocol_plugin->init_data(); + + if (server->protocol_plugin) + server->protocol_plugin->set_server_info(server->protocol, &_server_info); + // SSR end + + ev_io_start(EV_A_ & server->recv_ctx->io); + ev_timer_start(EV_A_ & server->recv_ctx->watcher); +} + +int +main(int argc, char **argv) +{ + int i, c; + int pid_flags = 0; + int mptcp = 0; + int firewall = 0; + int mtu = 0; + char *user = NULL; + char *password = NULL; + char *timeout = NULL; + char *protocol = NULL; // SSR + char *protocol_param = NULL; // SSR + char *method = NULL; + char *obfs = NULL; // SSR + char *obfs_param = NULL; // SSR + char *pid_path = NULL; + char *conf_path = NULL; + char *iface = NULL; + + int server_num = 0; + const char *server_host[MAX_REMOTE_NUM]; + + char *nameservers[MAX_DNS_NUM + 1]; + int nameserver_num = 0; + + int option_index = 0; + static struct option long_options[] = { + { "fast-open", no_argument, 0, 0 }, + { "acl", required_argument, 0, 0 }, + { "manager-address", required_argument, 0, 0 }, + { "mtu", required_argument, 0, 0 }, + { "help", no_argument, 0, 0 }, +#ifdef __linux__ + { "mptcp", no_argument, 0, 0 }, + { "firewall", no_argument, 0, 0 }, +#endif + { 0, 0, 0, 0 } + }; + + opterr = 0; + + USE_TTY(); + + while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:b:c:i:d:a:n:O:o:G:g:huUvA6", + long_options, &option_index)) != -1) { + switch (c) { + case 0: + if (option_index == 0) { + fast_open = 1; + } else if (option_index == 1) { + LOGI("initializing acl..."); + acl = !init_acl(optarg); + } else if (option_index == 2) { + manager_address = optarg; + } else if (option_index == 3) { + mtu = atoi(optarg); + LOGI("set MTU to %d", mtu); + } else if (option_index == 4) { + usage(); + exit(EXIT_SUCCESS); + } else if (option_index == 5) { + mptcp = 1; + LOGI("enable multipath TCP"); + } else if (option_index == 6) { + firewall = 1; + LOGI("enable firewall rules"); + } + break; + case 's': + if (server_num < MAX_REMOTE_NUM) { + server_host[server_num++] = optarg; + } + break; + case 'b': + bind_address = optarg; + break; + case 'p': + server_port = optarg; + break; + case 'k': + password = optarg; + break; + case 'f': + pid_flags = 1; + pid_path = optarg; + break; + case 't': + timeout = optarg; + break; + // SSR beg + case 'O': + protocol = optarg; + break; + case 'm': + method = optarg; + break; + case 'o': + obfs = optarg; + break; + case 'G': + protocol_param = optarg; + break; + case 'g': + obfs_param = optarg; + break; + // SSR end + case 'c': + conf_path = optarg; + break; + case 'i': + iface = optarg; + break; + case 'd': + if (nameserver_num < MAX_DNS_NUM) { + nameservers[nameserver_num++] = optarg; + } + break; + case 'a': + user = optarg; + break; +#ifdef HAVE_SETRLIMIT + case 'n': + nofile = atoi(optarg); + break; +#endif + case 'u': + mode = TCP_AND_UDP; + break; + case 'U': + mode = UDP_ONLY; + break; + case 'v': + verbose = 1; + break; + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 'A': + auth = 1; + break; + case '6': + ipv6first = 1; + break; + case '?': + // The option character is not recognized. + LOGE("Unrecognized option: %s", optarg); + opterr = 1; + break; + } + } + + if (opterr) { + usage(); + exit(EXIT_FAILURE); + } + + if (argc == 1) { + if (conf_path == NULL) { + conf_path = DEFAULT_CONF_PATH; + } + } + + if (conf_path != NULL) { + jconf_t *conf = read_jconf(conf_path); + if (server_num == 0) { + server_num = conf->remote_num; + for (i = 0; i < server_num; i++) + server_host[i] = conf->remote_addr[i].host; + } + if (server_port == NULL) { + server_port = conf->remote_port; + } + if (password == NULL) { + password = conf->password; + } + // SSR beg + if (protocol == NULL) { + protocol = conf->protocol; + LOGI("protocol %s", protocol); + } + if (protocol_param == NULL) { + protocol_param = conf->protocol_param; + LOGI("protocol_param %s", obfs_param); + } + if (method == NULL) { + method = conf->method; + LOGI("method %s", method); + } + if (obfs == NULL) { + obfs = conf->obfs; + LOGI("obfs %s", obfs); + } + if (obfs_param == NULL) { + obfs_param = conf->obfs_param; + LOGI("obfs_param %s", obfs_param); + } + // SSR end + if (timeout == NULL) { + timeout = conf->timeout; + } + if (user == NULL) { + user = conf->user; + } + if (auth == 0) { + auth = conf->auth; + } + if (mode == TCP_ONLY) { + mode = conf->mode; + } + if (mtu == 0) { + mtu = conf->mtu; + } + if (mptcp == 0) { + mptcp = conf->mptcp; + } +#ifdef TCP_FASTOPEN + if (fast_open == 0) { + fast_open = conf->fast_open; + } +#endif +#ifdef HAVE_SETRLIMIT + if (nofile == 0) { + nofile = conf->nofile; + } +#endif + if (conf->nameserver != NULL) { + nameservers[nameserver_num++] = conf->nameserver; + } + if (ipv6first == 0) { + ipv6first = conf->ipv6_first; + } + } + + //_compatible + if(strlen(protocol)>11) + { + char *text; + text = (char*)malloc(12); + memcpy(text, protocol + strlen(protocol) - 11, 12); + + if(strcmp(text, "_compatible") == 0) + { + free(text); + text = (char*)malloc(strlen(protocol) - 11); + memcpy(text, protocol, strlen(protocol) - 11); + int length = strlen(protocol) - 11; + free(protocol); + obfs = (char*)malloc(length); + memset(protocol, 0x00, length); + memcpy(protocol, text, length); + LOGI("protocol compatible enable, %s", protocol); + free(text); + protocol_compatible = 1; + } + } + + if(strlen(obfs)>11) + { + char *text; + text = (char*)malloc(12); + memcpy(text, obfs + strlen(obfs) - 11, 12); + + if(strcmp(text, "_compatible") == 0) + { + free(text); + text = (char*)malloc(strlen(obfs) - 11); + memcpy(text, obfs, strlen(obfs) - 11); + int length = strlen(obfs) - 11; + free(obfs); + obfs = (char*)malloc(length); + memset(obfs, 0x00, length); + memcpy(obfs, text, length); + LOGI("obfs compatible enable, %s", obfs); + free(text); + obfs_compatible = 1; + } + } + + + if (server_num == 0) { + server_host[server_num++] = NULL; + } + + if (server_num == 0 || server_port == NULL || password == NULL) { + usage(); + exit(EXIT_FAILURE); + } + + if (protocol && strcmp(protocol, "verify_sha1") == 0) { + auth = 1; + protocol = NULL; + } + + if (method == NULL) { + method = "rc4-md5"; + } + + if (timeout == NULL) { + timeout = "60"; + } + +#ifdef HAVE_SETRLIMIT + /* + * no need to check the return value here since we will show + * the user an error message if setrlimit(2) fails + */ + if (nofile > 1024) { + if (verbose) { + LOGI("setting NOFILE to %d", nofile); + } + set_nofile(nofile); + } +#endif + + if (pid_flags) { + USE_SYSLOG(argv[0]); + daemonize(pid_path); + } + + if (ipv6first) { + LOGI("resolving hostname to IPv6 address first"); + } + + if (fast_open == 1) { +#ifdef TCP_FASTOPEN + LOGI("using tcp fast open"); +#else + LOGE("tcp fast open is not supported by this environment"); + fast_open = 0; +#endif + } + + if (auth) { + LOGI("onetime authentication enabled"); + } + + if (mode != TCP_ONLY) { + LOGI("UDP relay enabled"); + } + + if (mode == UDP_ONLY) { + LOGI("TCP relay disabled"); + } + +#ifdef __MINGW32__ + winsock_init(); +#else + // ignore SIGPIPE + signal(SIGPIPE, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + signal(SIGABRT, SIG_IGN); +#endif + + struct ev_signal sigint_watcher; + struct ev_signal sigterm_watcher; + ev_signal_init(&sigint_watcher, signal_cb, SIGINT); + ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM); + ev_signal_start(EV_DEFAULT, &sigint_watcher); + ev_signal_start(EV_DEFAULT, &sigterm_watcher); + + // setup keys + LOGI("initializing ciphers... %s", method); + int m = enc_init(password, method); + + // initialize ev loop + struct ev_loop *loop = EV_DEFAULT; + + // setup udns + if (nameserver_num == 0) { +#ifdef __MINGW32__ + nameservers[nameserver_num++] = "8.8.8.8"; + resolv_init(loop, nameservers, nameserver_num, ipv6first); +#else + resolv_init(loop, NULL, 0, ipv6first); +#endif + } else { + resolv_init(loop, nameservers, nameserver_num, ipv6first); + } + + for (int i = 0; i < nameserver_num; i++) + LOGI("using nameserver: %s", nameservers[i]); + + // initialize listen context + listen_ctx_t listen_ctx_list[server_num]; + + // bind to each interface + while (server_num > 0) { + int index = --server_num; + const char *host = server_host[index]; + + if (mode != UDP_ONLY) { + // Bind to port + int listenfd; + listenfd = create_and_bind(host, server_port, mptcp); + if (listenfd == -1) { + FATAL("bind() error"); + } + if (listen(listenfd, SSMAXCONN) == -1) { + FATAL("listen() error"); + } + setfastopen(listenfd); + setnonblocking(listenfd); + listen_ctx_t *listen_ctx = &listen_ctx_list[index]; + + // Setup proxy context + listen_ctx->timeout = atoi(timeout); + listen_ctx->fd = listenfd; + listen_ctx->method = m; + listen_ctx->iface = iface; + + // SSR beg + listen_ctx->protocol_name = protocol; + listen_ctx->protocol_param = protocol_param; + listen_ctx->method = m; + listen_ctx->obfs_name = obfs; + listen_ctx->obfs_param = obfs_param; + listen_ctx->list_protocol_global = malloc(sizeof(void *)); + listen_ctx->list_obfs_global = malloc(sizeof(void *)); + memset(listen_ctx->list_protocol_global, 0, sizeof(void *)); + memset(listen_ctx->list_obfs_global, 0, sizeof(void *)); + // SSR end + + listen_ctx->loop = loop; + + ev_io_init(&listen_ctx->io, accept_cb, listenfd, EV_READ); + ev_io_start(loop, &listen_ctx->io); + } + + // Setup UDP + if (mode != TCP_ONLY) { + init_udprelay(server_host[index], server_port, mtu, m, + auth, atoi(timeout), iface, protocol, protocol_param); + } + + if (host && strcmp(host, ":") > 0) + LOGI("listening at [%s]:%s", host, server_port); + else + LOGI("listening at %s:%s", host ? host : "*", server_port); + } + + if (manager_address != NULL) { + ev_timer_init(&stat_update_watcher, stat_update_cb, UPDATE_INTERVAL, UPDATE_INTERVAL); + ev_timer_start(EV_DEFAULT, &stat_update_watcher); + } + + ev_timer_init(&block_list_watcher, block_list_clear_cb, UPDATE_INTERVAL, UPDATE_INTERVAL); + ev_timer_start(EV_DEFAULT, &block_list_watcher); + + // setuid + if (user != NULL && ! run_as(user)) { + FATAL("failed to switch user"); + } + +#ifndef __MINGW32__ + if (geteuid() == 0){ + LOGI("running from root user"); + } else if (firewall) { + LOGE("firewall setup requires running from root user"); + exit(-1); + } +#endif + + // init block list + init_block_list(firewall); + + // Init connections + cork_dllist_init(&connections); + + // start ev loop + ev_run(loop, 0); + + if (verbose) { + LOGI("closed gracefully"); + } + + // Free block list + free_block_list(); + + if (manager_address != NULL) { + ev_timer_stop(EV_DEFAULT, &stat_update_watcher); + } + ev_timer_stop(EV_DEFAULT, &block_list_watcher); + + // Clean up + for (int i = 0; i <= server_num; i++) { + listen_ctx_t *listen_ctx = &listen_ctx_list[i]; + if (mode != UDP_ONLY) { + ev_io_stop(loop, &listen_ctx->io); + close(listen_ctx->fd); + } + } + + if (mode != UDP_ONLY) { + free_connections(loop); + } + + if (mode != TCP_ONLY) { + free_udprelay(); + } + + resolv_shutdown(loop); + +#ifdef __MINGW32__ + winsock_cleanup(); +#endif + + ev_signal_stop(EV_DEFAULT, &sigint_watcher); + ev_signal_stop(EV_DEFAULT, &sigterm_watcher); + + return 0; +} diff --git a/shadowsocksr-libev/src/server/server.h b/shadowsocksr-libev/src/server/server.h new file mode 100644 index 00000000..4cd3cf6b --- /dev/null +++ b/shadowsocksr-libev/src/server/server.h @@ -0,0 +1,115 @@ +/* + * server.h - Define shadowsocks server's buffers and callbacks + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _SERVER_H +#define _SERVER_H + +#include +#include +#include + +#include "encrypt.h" +#include "jconf.h" +#include "resolv.h" +#include "obfs.h" +#include "protocol.h" + +#include "common.h" + +typedef struct listen_ctx { + ev_io io; + int fd; + int timeout; + int method; + char *iface; + struct ev_loop *loop; + + // SSR + char *protocol_name; + char *protocol_param; + char *obfs_name; + char *obfs_param; + void **list_protocol_global; + void **list_obfs_global; +} listen_ctx_t; + +typedef struct server_ctx { + ev_io io; + ev_timer watcher; + int connected; + struct server *server; +} server_ctx_t; + +typedef struct server { + int fd; + int stage; + buffer_t *buf; + ssize_t buf_capacity; + buffer_t *header_buf; + + int auth; + struct chunk *chunk; + + struct enc_ctx *e_ctx; + struct enc_ctx *d_ctx; + struct server_ctx *recv_ctx; + struct server_ctx *send_ctx; + struct listen_ctx *listen_ctx; + struct remote *remote; + + struct ResolvQuery *query; + + struct cork_dllist_item entries; + + // SSR + obfs *protocol; + obfs *obfs; + obfs_class *protocol_plugin; + obfs_class *obfs_plugin; + int obfs_compatible_state; + int protocol_compatible_state; +} server_t; + +typedef struct query { + server_t *server; + char hostname[257]; +} query_t; + +typedef struct remote_ctx { + ev_io io; + int connected; + struct remote *remote; +} remote_ctx_t; + +typedef struct remote { + int fd; + buffer_t *buf; + ssize_t buf_capacity; + struct remote_ctx *recv_ctx; + struct remote_ctx *send_ctx; + struct server *server; + + // SSR + int remote_index; +} remote_t; + +#endif // _SERVER_H diff --git a/shadowsocksr-libev/src/server/tls.c b/shadowsocksr-libev/src/server/tls.c new file mode 100644 index 00000000..5c422160 --- /dev/null +++ b/shadowsocksr-libev/src/server/tls.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2011 and 2012, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This is a minimal TLS implementation intended only to parse the server name + * extension. This was created based primarily on Wireshark dissection of a + * TLS handshake and RFC4366. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include /* malloc() */ +#include /* strncpy() */ + +#ifndef __MINGW32__ +#include +#else +#include +#endif + +#include "tls.h" +#include "protocol.h" +#include "utils.h" + +#define SERVER_NAME_LEN 256 +#define TLS_HEADER_LEN 5 +#define TLS_HANDSHAKE_CONTENT_TYPE 0x16 +#define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 0x01 + +#ifndef MIN +#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +#endif + +extern int verbose; + +static int parse_tls_header(const char *, size_t, char **); +static int parse_extensions(const char *, size_t, char **); +static int parse_server_name_extension(const char *, size_t, char **); + +static const protocol_t tls_protocol_st = { + .default_port = 443, + .parse_packet = &parse_tls_header, +}; +const protocol_t *const tls_protocol = &tls_protocol_st; + +/* Parse a TLS packet for the Server Name Indication extension in the client + * hello handshake, returning the first servername found (pointer to static + * array) + * + * Returns: + * >=0 - length of the hostname and updates *hostname + * caller is responsible for freeing *hostname + * -1 - Incomplete request + * -2 - No Host header included in this request + * -3 - Invalid hostname pointer + * -4 - malloc failure + * < -4 - Invalid TLS client hello + */ +static int +parse_tls_header(const char *data, size_t data_len, char **hostname) +{ + char tls_content_type; + char tls_version_major; + char tls_version_minor; + size_t pos = TLS_HEADER_LEN; + size_t len; + + if (hostname == NULL) + return -3; + + /* Check that our TCP payload is at least large enough for a TLS header */ + if (data_len < TLS_HEADER_LEN) + return -1; + + /* SSL 2.0 compatible Client Hello + * + * High bit of first byte (length) and content type is Client Hello + * + * See RFC5246 Appendix E.2 + */ + if (data[0] & 0x80 && data[2] == 1) { + if (verbose) + LOGI("Received SSL 2.0 Client Hello which can not support SNI."); + return -2; + } + + tls_content_type = data[0]; + if (tls_content_type != TLS_HANDSHAKE_CONTENT_TYPE) { + if (verbose) + LOGI("Request did not begin with TLS handshake."); + return -5; + } + + tls_version_major = data[1]; + tls_version_minor = data[2]; + if (tls_version_major < 3) { + if (verbose) + LOGI("Received SSL %d.%d handshake which can not support SNI.", + tls_version_major, tls_version_minor); + + return -2; + } + + /* TLS record length */ + len = ((unsigned char)data[3] << 8) + + (unsigned char)data[4] + TLS_HEADER_LEN; + data_len = MIN(data_len, len); + + /* Check we received entire TLS record length */ + if (data_len < len) + return -1; + + /* + * Handshake + */ + if (pos + 1 > data_len) { + return -5; + } + if (data[pos] != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) { + if (verbose) + LOGI("Not a client hello"); + + return -5; + } + + /* Skip past fixed length records: + * 1 Handshake Type + * 3 Length + * 2 Version (again) + * 32 Random + * to Session ID Length + */ + pos += 38; + + /* Session ID */ + if (pos + 1 > data_len) + return -5; + len = (unsigned char)data[pos]; + pos += 1 + len; + + /* Cipher Suites */ + if (pos + 2 > data_len) + return -5; + len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1]; + pos += 2 + len; + + /* Compression Methods */ + if (pos + 1 > data_len) + return -5; + len = (unsigned char)data[pos]; + pos += 1 + len; + + if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) { + if (verbose) + LOGI("Received SSL 3.0 handshake without extensions"); + return -2; + } + + /* Extensions */ + if (pos + 2 > data_len) + return -5; + len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1]; + pos += 2; + + if (pos + len > data_len) + return -5; + return parse_extensions(data + pos, len, hostname); +} + +static int +parse_extensions(const char *data, size_t data_len, char **hostname) +{ + size_t pos = 0; + size_t len; + + /* Parse each 4 bytes for the extension header */ + while (pos + 4 <= data_len) { + /* Extension Length */ + len = ((unsigned char)data[pos + 2] << 8) + + (unsigned char)data[pos + 3]; + + /* Check if it's a server name extension */ + if (data[pos] == 0x00 && data[pos + 1] == 0x00) { + /* There can be only one extension of each type, so we break + * our state and move p to beinnging of the extension here */ + if (pos + 4 + len > data_len) + return -5; + return parse_server_name_extension(data + pos + 4, len, hostname); + } + pos += 4 + len; /* Advance to the next extension header */ + } + /* Check we ended where we expected to */ + if (pos != data_len) + return -5; + + return -2; +} + +static int +parse_server_name_extension(const char *data, size_t data_len, + char **hostname) +{ + size_t pos = 2; /* skip server name list length */ + size_t len; + + while (pos + 3 < data_len) { + len = ((unsigned char)data[pos + 1] << 8) + + (unsigned char)data[pos + 2]; + + if (pos + 3 + len > data_len) + return -5; + + switch (data[pos]) { /* name type */ + case 0x00: /* host_name */ + *hostname = malloc(len + 1); + if (*hostname == NULL) { + ERROR("malloc() failure"); + return -4; + } + + strncpy(*hostname, data + pos + 3, len); + + (*hostname)[len] = '\0'; + + return len; + default: + if (verbose) + LOGI("Unknown server name extension name type: %d", + data[pos]); + } + pos += 3 + len; + } + /* Check we ended where we expected to */ + if (pos != data_len) + return -5; + + return -2; +} diff --git a/shadowsocksr-libev/src/server/tls.h b/shadowsocksr-libev/src/server/tls.h new file mode 100644 index 00000000..39989131 --- /dev/null +++ b/shadowsocksr-libev/src/server/tls.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 and 2012, Dustin Lundquist + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef TLS_H +#define TLS_H + +#include "protocol.h" + +const protocol_t *const tls_protocol; + +#endif diff --git a/shadowsocksr-libev/src/server/tls1.2_ticket.c b/shadowsocksr-libev/src/server/tls1.2_ticket.c new file mode 100644 index 00000000..88970c09 --- /dev/null +++ b/shadowsocksr-libev/src/server/tls1.2_ticket.c @@ -0,0 +1,609 @@ + +#include "tls1.2_ticket.h" +#include "list.c" + +typedef struct tls12_ticket_auth_global_data { + uint8_t local_client_id[32]; + List client_data; + time_t startup_time; +}tls12_ticket_auth_global_data; + +typedef struct tls12_ticket_auth_local_data { + int handshake_status; + char *send_buffer; + int send_buffer_size; + char *recv_buffer; + int recv_buffer_size; +}tls12_ticket_auth_local_data; + +void tls12_ticket_auth_local_data_init(tls12_ticket_auth_local_data* local) { + local->handshake_status = 0; + local->send_buffer = malloc(0); + local->send_buffer_size = 0; + local->recv_buffer = malloc(0); + local->recv_buffer_size = 0; +} + +void * tls12_ticket_auth_init_data() { + tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)malloc(sizeof(tls12_ticket_auth_global_data)); + rand_bytes(global->local_client_id, 32); + global->client_data = list_init(22); + global->startup_time = time(NULL); + return global; +} + +obfs * tls12_ticket_auth_new_obfs() { + obfs * self = new_obfs(); + self->l_data = malloc(sizeof(tls12_ticket_auth_local_data)); + tls12_ticket_auth_local_data_init((tls12_ticket_auth_local_data*)self->l_data); + return self; +} + +void tls12_ticket_auth_dispose(obfs *self) { + tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; + if (local->send_buffer != NULL) { + free(local->send_buffer); + local->send_buffer = NULL; + } + if (local->recv_buffer != NULL) { + free(local->recv_buffer); + local->recv_buffer = NULL; + } + free(local); + dispose_obfs(self); +} + +int tls12_ticket_pack_auth_data(tls12_ticket_auth_global_data *global, server_info *server, char *outdata) { + int out_size = 32; + time_t t = time(NULL); + outdata[0] = t >> 24; + outdata[1] = t >> 16; + outdata[2] = t >> 8; + outdata[3] = t; + rand_bytes((uint8_t*)outdata + 4, 18); + + uint8_t *key = (uint8_t*)malloc(server->key_len + 32); + char hash[ONETIMEAUTH_BYTES * 2]; + memcpy(key, server->key, server->key_len); + memcpy(key + server->key_len, global->local_client_id, 32); + ss_sha1_hmac_with_key(hash, outdata, out_size - OBFS_HMAC_SHA1_LEN, key, server->key_len + 32); + free(key); + memcpy(outdata + out_size - OBFS_HMAC_SHA1_LEN, hash, OBFS_HMAC_SHA1_LEN); + return out_size; +} + +void tls12_ticket_auth_pack_data(char *encryptdata, int datalength, int start, int len, char *out_buffer, int outlength) { + out_buffer[outlength] = 0x17; + out_buffer[outlength + 1] = 0x3; + out_buffer[outlength + 2] = 0x3; + out_buffer[outlength + 3] = len >> 8; + out_buffer[outlength + 4] = len; + memcpy(out_buffer + outlength + 5, encryptdata + start, len); +} + +int tls12_ticket_auth_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { + char *encryptdata = *pencryptdata; + tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; + tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; + char * out_buffer = NULL; + + if (local->handshake_status == 8) { + if (datalength < 1024) { + if (*capacity < datalength + 5) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (datalength + 5) * 2); + encryptdata = *pencryptdata; + } + memmove(encryptdata + 5, encryptdata, datalength); + encryptdata[0] = 0x17; + encryptdata[1] = 0x3; + encryptdata[2] = 0x3; + encryptdata[3] = datalength >> 8; + encryptdata[4] = datalength; + return datalength + 5; + } else { + out_buffer = (char*)malloc(datalength + 2048); + int start = 0; + int outlength = 0; + int len; + while (datalength - start > 2048) { + len = xorshift128plus() % 4096 + 100; + if (len > datalength - start) + len = datalength - start; + tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); + outlength += len + 5; + start += len; + } + if (datalength - start > 0) { + len = datalength - start; + tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); + outlength += len + 5; + } + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + memcpy(encryptdata, out_buffer, outlength); + free(out_buffer); + return outlength; + } + } + local->send_buffer = (char*)realloc(local->send_buffer, local->send_buffer_size + datalength + 5); + memcpy(local->send_buffer + local->send_buffer_size + 5, encryptdata, datalength); + local->send_buffer[local->send_buffer_size] = 0x17; + local->send_buffer[local->send_buffer_size + 1] = 0x3; + local->send_buffer[local->send_buffer_size + 2] = 0x3; + local->send_buffer[local->send_buffer_size + 3] = datalength >> 8; + local->send_buffer[local->send_buffer_size + 4] = datalength; + local->send_buffer_size += datalength + 5; + + if (local->handshake_status == 0) { +#define CSTR_DECL(name, len, str) const char* name = str; const int len = sizeof(str) - 1; + CSTR_DECL(tls_data0, tls_data0_len, "\x00\x1c\xc0\x2b\xc0\x2f\xcc\xa9\xcc\xa8\xcc\x14\xcc\x13\xc0\x0a\xc0\x14\xc0\x09\xc0\x13\x00\x9c\x00\x35\x00\x2f\x00\x0a\x01\x00" + ); + CSTR_DECL(tls_data1, tls_data1_len, "\xff\x01\x00\x01\x00" + ); + CSTR_DECL(tls_data2, tls_data2_len, "\x00\x17\x00\x00\x00\x23\x00\xd0"); + CSTR_DECL(tls_data3, tls_data3_len, "\x00\x0d\x00\x16\x00\x14\x06\x01\x06\x03\x05\x01\x05\x03\x04\x01\x04\x03\x03\x01\x03\x03\x02\x01\x02\x03\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x12\x00\x00\x75\x50\x00\x00\x00\x0b\x00\x02\x01\x00\x00\x0a\x00\x06\x00\x04\x00\x17\x00\x18" + //"00150066000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" // padding + ); + uint8_t tls_data[2048]; + int tls_data_len = 0; + memcpy(tls_data, tls_data1, tls_data1_len); + tls_data_len += tls_data1_len; + + char hosts[1024]; + char * phost[128]; + int host_num = 0; + int pos; + + char sni[256] = {0}; + if (self->server.param && strlen(self->server.param) == 0) + self->server.param = NULL; + strncpy(hosts, self->server.param ? self->server.param : self->server.host, sizeof hosts); + phost[host_num++] = hosts; + for (pos = 0; hosts[pos]; ++pos) { + if (hosts[pos] == ',') { + phost[host_num++] = &hosts[pos + 1]; + } + } + host_num = xorshift128plus() % host_num; + + sprintf(sni, "%s", phost[host_num]); + int sni_len = strlen(sni); + if (sni_len > 0 && sni[sni_len - 1] >= '0' && sni[sni_len - 1] <= '9') + sni_len = 0; + tls_data[tls_data_len] = '\0'; + tls_data[tls_data_len + 1] = '\0'; + tls_data[tls_data_len + 2] = (sni_len + 5) >> 8; + tls_data[tls_data_len + 3] = (sni_len + 5); + tls_data[tls_data_len + 4] = (sni_len + 3) >> 8; + tls_data[tls_data_len + 5] = (sni_len + 3); + tls_data[tls_data_len + 6] = '\0'; + tls_data[tls_data_len + 7] = sni_len >> 8; + tls_data[tls_data_len + 8] = sni_len; + memcpy(tls_data + tls_data_len + 9, sni, sni_len); + tls_data_len += 9 + sni_len; + memcpy(tls_data + tls_data_len, tls_data2, tls_data2_len); + tls_data_len += tls_data2_len; + rand_bytes(tls_data + tls_data_len, 208); + tls_data_len += 208; + memcpy(tls_data + tls_data_len, tls_data3, tls_data3_len); + tls_data_len += tls_data3_len; + + datalength = 11 + 32 + 1 + 32 + tls_data0_len + 2 + tls_data_len; + out_buffer = (char*)malloc(datalength); + char *pdata = out_buffer + datalength - tls_data_len; + int len = tls_data_len; + memcpy(pdata, tls_data, tls_data_len); + pdata[-1] = tls_data_len; + pdata[-2] = tls_data_len >> 8; + pdata -= 2; len += 2; + memcpy(pdata - tls_data0_len, tls_data0, tls_data0_len); + pdata -= tls_data0_len; len += tls_data0_len; + memcpy(pdata - 32, global->local_client_id, 32); + pdata -= 32; len += 32; + pdata[-1] = 0x20; + pdata -= 1; len += 1; + tls12_ticket_pack_auth_data(global, &self->server, pdata - 32); + pdata -= 32; len += 32; + pdata[-1] = 0x3; + pdata[-2] = 0x3; // tls version + pdata -= 2; len += 2; + pdata[-1] = len; + pdata[-2] = len >> 8; + pdata[-3] = 0; + pdata[-4] = 1; + pdata -= 4; len += 4; + + pdata[-1] = len; + pdata[-2] = len >> 8; + pdata -= 2; len += 2; + pdata[-1] = 0x1; + pdata[-2] = 0x3; // tls version + pdata -= 2; len += 2; + pdata[-1] = 0x16; // tls handshake + pdata -= 1; len += 1; + + local->handshake_status = 1; + } else if (datalength == 0) { + datalength = local->send_buffer_size + 43; + out_buffer = (char*)malloc(datalength); + char *pdata = out_buffer; + memcpy(pdata, "\x14\x03\x03\x00\x01\x01", 6); + pdata += 6; + memcpy(pdata, "\x16\x03\x03\x00\x20", 5); + pdata += 5; + rand_bytes((uint8_t*)pdata, 22); + pdata += 22; + + uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); + char hash[ONETIMEAUTH_BYTES * 2]; + memcpy(key, self->server.key, self->server.key_len); + memcpy(key + self->server.key_len, global->local_client_id, 32); + ss_sha1_hmac_with_key(hash, out_buffer, pdata - out_buffer, key, self->server.key_len + 32); + free(key); + memcpy(pdata, hash, OBFS_HMAC_SHA1_LEN); + + pdata += OBFS_HMAC_SHA1_LEN; + memcpy(pdata, local->send_buffer, local->send_buffer_size); + free(local->send_buffer); + local->send_buffer = NULL; + + local->handshake_status = 8; + } else { + return 0; + } + if (*capacity < datalength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = datalength * 2); + encryptdata = *pencryptdata; + } + memmove(encryptdata, out_buffer, datalength); + free(out_buffer); + return datalength; +} + +int tls12_ticket_auth_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity) { + char *encryptdata = *pencryptdata; + tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; + tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; + char * out_buffer = NULL; + + if (local->handshake_status == 8) { + if (datalength < 1024) { + if (*capacity < datalength + 5) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (datalength + 5) * 2); + encryptdata = *pencryptdata; + } + memmove(encryptdata + 5, encryptdata, datalength); + encryptdata[0] = 0x17; + encryptdata[1] = 0x3; + encryptdata[2] = 0x3; + encryptdata[3] = datalength >> 8; + encryptdata[4] = datalength; + return datalength + 5; + } else { + out_buffer = (char*)malloc(datalength + 2048); + int start = 0; + int outlength = 0; + int len; + while (datalength - start > 2048) { + len = xorshift128plus() % 4096 + 100; + if (len > datalength - start) + len = datalength - start; + tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); + outlength += len + 5; + start += len; + } + if (datalength - start > 0) { + len = datalength - start; + tls12_ticket_auth_pack_data(encryptdata, datalength, start, len, out_buffer, outlength); + outlength += len + 5; + } + if (*capacity < outlength) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = outlength * 2); + encryptdata = *pencryptdata; + } + memcpy(encryptdata, out_buffer, outlength); + free(out_buffer); + return outlength; + } + } + + local->handshake_status = 3; + + out_buffer = (char*)malloc(43 + 86); + int data_len = 0; + char *p_data = out_buffer + 86; + + memcpy(p_data - 10, "\xc0\x2f\x00\x00\x05\xff\x01\x00\x01\x00", 10); + p_data -= 10;data_len += 10; + + memcpy(p_data - 32, global->local_client_id, 32); + p_data -= 32;data_len += 32; + + p_data[-1] = 0x20; + p_data -= 1;data_len += 1; + + tls12_ticket_pack_auth_data(global, &self->server, p_data - 32); + p_data -= 32;data_len += 32; + + p_data[-1] = 0x3; + p_data[-2] = 0x3; // tls version + p_data -= 2;data_len += 2; + + p_data[-1] = data_len; + p_data[-2] = data_len >> 8; + p_data[-3] = 0x00; + p_data[-4] = 0x02; + p_data -= 4; data_len += 4; + + p_data[-1] = data_len; + p_data[-2] = data_len >> 8; + p_data[-3] = 0x03; + p_data[-4] = 0x03; + p_data[-5] = 0x16; + p_data -= 5; data_len += 5; + + memcpy(out_buffer, p_data, data_len); + char *pdata = out_buffer + 86; + + memcpy(pdata, "\x14\x03\x03\x00\x01\x01", 6); + pdata += 6; + memcpy(pdata, "\x16\x03\x03\x00\x20", 5); + pdata += 5; + rand_bytes((uint8_t*)pdata, 22); + pdata += 22; + + uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); + char hash[ONETIMEAUTH_BYTES * 2]; + memcpy(key, self->server.key, self->server.key_len); + memcpy(key + self->server.key_len, global->local_client_id, 32); + ss_sha1_hmac_with_key(hash, out_buffer, 43 + 86, key, self->server.key_len + 32); + free(key); + memcpy(pdata, hash, OBFS_HMAC_SHA1_LEN); + + memmove(encryptdata, out_buffer, 43 + 86); + free(out_buffer); + return 43 + 86; +} + +int tls12_ticket_auth_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { + char *encryptdata = *pencryptdata; + tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; + tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; + + *needsendback = 0; + + if (local->handshake_status == 8) { + local->recv_buffer_size += datalength; + local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size); + memcpy(local->recv_buffer + local->recv_buffer_size - datalength, encryptdata, datalength); + datalength = 0; + while (local->recv_buffer_size > 5) { + if (local->recv_buffer[0] != 0x17) + return -1; + int size = ((int)(unsigned char)local->recv_buffer[3] << 8) + (unsigned char)local->recv_buffer[4]; + if (size + 5 > local->recv_buffer_size) + break; + if (*capacity < datalength + size) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (datalength + size) * 2); + encryptdata = *pencryptdata; + } + memcpy(encryptdata + datalength, local->recv_buffer + 5, size); + datalength += size; + local->recv_buffer_size -= 5 + size; + memmove(local->recv_buffer, local->recv_buffer + 5 + size, local->recv_buffer_size); + } + return datalength; + } + if (datalength < 11 + 32 + 1 + 32) { + return -1; + } + + uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); + char hash[ONETIMEAUTH_BYTES * 2]; + memcpy(key, self->server.key, self->server.key_len); + memcpy(key + self->server.key_len, global->local_client_id, 32); + ss_sha1_hmac_with_key(hash, encryptdata + 11, 22, key, self->server.key_len + 32); + free(key); + + if (memcmp(encryptdata + 33, hash, OBFS_HMAC_SHA1_LEN)) { + return -1; + } + + *needsendback = 1; + return 0; +} + +int tls12_ticket_auth_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback) { + char *encryptdata = *pencryptdata; + tls12_ticket_auth_local_data *local = (tls12_ticket_auth_local_data*)self->l_data; + tls12_ticket_auth_global_data *global = (tls12_ticket_auth_global_data*)self->server.g_data; + + *needsendback = 0; + + if (local->handshake_status == 8) { + if(datalength != 0) + { + local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size + datalength); + memmove(local->recv_buffer + local->recv_buffer_size, encryptdata, datalength); + local->recv_buffer_size += datalength; + } + datalength = 0; + + while (local->recv_buffer_size > 5) { + if (local->recv_buffer[0] != 0x17 || local->recv_buffer[1] != 0x03 || local->recv_buffer[2] != 0x03) + { + LOGE("server_decode data error, wrong tls version 3"); + return -1; + } + int size = ((int)(unsigned char)local->recv_buffer[3] << 8) + (unsigned char)local->recv_buffer[4]; + if (size + 5 > local->recv_buffer_size) + break; + if (*capacity < local->recv_buffer_size + size) { + *pencryptdata = (char*)realloc(*pencryptdata, *capacity = (local->recv_buffer_size + size) * 2); + encryptdata = *pencryptdata; + } + memcpy(encryptdata + datalength, local->recv_buffer + 5, size); + datalength += size; + local->recv_buffer_size -= 5 + size; + memmove(local->recv_buffer, local->recv_buffer + 5 + size, local->recv_buffer_size); + } + return datalength; + } + + if (local->handshake_status == 3) { + + char *verify = encryptdata; + + if(datalength < 43) + { + LOGE("server_decode data error, too short:%d", (int)datalength); + return -1; + } + + if(encryptdata[0] != 0x14 || encryptdata[1] != 0x03 || encryptdata[2] != 0x03 || encryptdata[3] != 0x00 || encryptdata[4] != 0x01 || encryptdata[5] != 0x01) + { + LOGE("server_decode data error, wrong tls version"); + return -1; + } + + encryptdata += 6; + + if(encryptdata[0] != 0x16 || encryptdata[1] != 0x03 || encryptdata[2] != 0x03 || encryptdata[3] != 0x00 || encryptdata[4] != 0x20) + { + LOGE("server_decode data error, wrong tls version 2"); + return -1; + } + + uint8_t *key = (uint8_t*)malloc(self->server.key_len + 32); + char hash[ONETIMEAUTH_BYTES * 2]; + memcpy(key, self->server.key, self->server.key_len); + memcpy(key + self->server.key_len, global->local_client_id, 32); + ss_sha1_hmac_with_key(hash, verify, 33, key, self->server.key_len + 32); + free(key); + + if (memcmp(verify + 33, hash, OBFS_HMAC_SHA1_LEN) != 0) { + LOGE("server_decode data error, hash Mismatch %d",(int)memcmp(verify + 33, hash, OBFS_HMAC_SHA1_LEN)); + return -1; + } + + local->recv_buffer_size = datalength - 43; + local->recv_buffer = (char*)realloc(local->recv_buffer, local->recv_buffer_size); + memmove(local->recv_buffer, encryptdata + 37, datalength - 43); + + local->handshake_status = 8; + return tls12_ticket_auth_server_decode(self, pencryptdata, 0, capacity, needsendback); + } + + local->handshake_status = 2; + if(encryptdata[0] != 0x16 || encryptdata[1] != 0x03 || encryptdata[2] != 0x01) + { + return -1; + } + + encryptdata += 3; + + { + int size = ((int)(unsigned char)encryptdata[0] << 8) + (unsigned char)encryptdata[1]; + if(size != datalength - 5) + { + LOGE("tls_auth wrong tls head size"); + return -1; + } + } + + encryptdata += 2; + + if(encryptdata[0] != 0x01 || encryptdata[1] != 0x00) + { + LOGE("tls_auth not client hello message"); + return -1; + } + + encryptdata += 2; + + { + int size = ((int)(unsigned char)encryptdata[0] << 8) + (unsigned char)encryptdata[1]; + if(size != datalength - 9) + { + LOGE("tls_auth wrong message size"); + return -1; + } + } + + encryptdata += 2; + + if(encryptdata[0] != 0x03 || encryptdata[1] != 0x03) + { + LOGE("tls_auth wrong tls version"); + return -1; + } + + encryptdata += 2; + + char *verifyid = encryptdata; + + encryptdata += 32; + + int sessionid_len = encryptdata[0]; + if(sessionid_len < 32) + { + LOGE("tls_auth wrong sessionid_len"); + return -1; + } + + char *sessionid = encryptdata + 1; + memcpy(global->local_client_id , sessionid, sessionid_len); + + uint8_t *key = (uint8_t*)malloc(self->server.key_len + sessionid_len); + char hash[ONETIMEAUTH_BYTES * 2]; + memcpy(key, self->server.key, self->server.key_len); + memcpy(key + self->server.key_len, global->local_client_id, sessionid_len); + ss_sha1_hmac_with_key(hash, verifyid, 22, key, self->server.key_len + sessionid_len); + free(key); + + encryptdata += (sessionid_len + 1); + + long utc_time = ((int)(unsigned char)verifyid[0] << 24) + ((int)(unsigned char)verifyid[1] << 16) + ((int)(unsigned char)verifyid[2] << 8) + (unsigned char)verifyid[3]; + time_t t = time(NULL); + + + if (self->server.param && strlen(self->server.param) == 0) + { + self->server.param = NULL; + } + + int max_time_dif = 0; + int time_dif = utc_time - t; + if(self->server.param) + { + max_time_dif = atoi(self->server.param); + } + + if(max_time_dif > 0 && (time_dif < -max_time_dif || time_dif > max_time_dif || utc_time - global->startup_time < -max_time_dif / 2)) + { + LOGE("tls_auth wrong time"); + return -1; + } + + if (memcmp(verifyid + 22, hash, OBFS_HMAC_SHA1_LEN)) { + LOGE("tls_auth wrong sha1"); + return -1; + } + + int search_result = global->client_data->have_same_cmp(global->client_data, verifyid); + if(search_result != 0) + { + LOGE("replay attack detect!"); + return -1; + } + + global->client_data->add_back(global->client_data, verifyid); + + encryptdata += 48; + + *needsendback = 1; + + return 0; +} diff --git a/shadowsocksr-libev/src/server/tls1.2_ticket.h b/shadowsocksr-libev/src/server/tls1.2_ticket.h new file mode 100644 index 00000000..10a57c90 --- /dev/null +++ b/shadowsocksr-libev/src/server/tls1.2_ticket.h @@ -0,0 +1,20 @@ +/* + * http_simple.h - Define shadowsocksR server's buffers and callbacks + * + * Copyright (C) 2015 - 2016, Break Wa11 + */ + +#ifndef _TLS1_2_TICKET_H +#define _TLS1_2_TICKET_H + +void * tls12_ticket_auth_init_data(); +obfs * tls12_ticket_auth_new_obfs(); +void tls12_ticket_auth_dispose(obfs *self); + +int tls12_ticket_auth_client_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); +int tls12_ticket_auth_client_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); + +int tls12_ticket_auth_server_encode(obfs *self, char **pencryptdata, int datalength, size_t* capacity); +int tls12_ticket_auth_server_decode(obfs *self, char **pencryptdata, int datalength, size_t* capacity, int *needsendback); + +#endif // _TLS1_2_TICKET_H diff --git a/shadowsocksr-libev/src/server/udprelay.c b/shadowsocksr-libev/src/server/udprelay.c new file mode 100644 index 00000000..d9251eea --- /dev/null +++ b/shadowsocksr-libev/src/server/udprelay.c @@ -0,0 +1,1452 @@ +/* + * udprelay.c - Setup UDP relay for both client and server + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __MINGW32__ +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) +#include +#include +#define SET_INTERFACE +#endif + +#ifdef __MINGW32__ +#include "win32.h" +#endif + +#include +#include + +#include "utils.h" +#include "netutils.h" +#include "cache.h" +#include "udprelay.h" + +#ifdef MODULE_REMOTE +#define MAX_UDP_CONN_NUM 512 +#else +#define MAX_UDP_CONN_NUM 256 +#endif + +#ifdef MODULE_REMOTE +#ifdef MODULE_ +#error "MODULE_REMOTE and MODULE_LOCAL should not be both defined" +#endif +#endif + +#ifndef EAGAIN +#define EAGAIN EWOULDBLOCK +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK EAGAIN +#endif + +static void server_recv_cb(EV_P_ ev_io *w, int revents); +static void remote_recv_cb(EV_P_ ev_io *w, int revents); +static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents); + +static char *hash_key(const int af, const struct sockaddr_storage *addr); +#ifdef MODULE_REMOTE +static void query_resolve_cb(struct sockaddr *addr, void *data); +#endif +static void close_and_free_remote(EV_P_ remote_ctx_t *ctx); +static remote_ctx_t *new_remote(int fd, server_ctx_t *server_ctx); + +#ifdef ANDROID +extern uint64_t tx; +extern uint64_t rx; +extern int vpn; +#endif + +extern int verbose; +#ifdef MODULE_REMOTE +extern uint64_t tx; +extern uint64_t rx; +#endif + +static int packet_size = DEFAULT_PACKET_SIZE; +static int buf_size = DEFAULT_PACKET_SIZE * 2; +static int server_num = 0; +static server_ctx_t *server_ctx_list[MAX_REMOTE_NUM] = { NULL }; + +#ifndef __MINGW32__ +static int +setnonblocking(int fd) +{ + int flags; + if (-1 == (flags = fcntl(fd, F_GETFL, 0))) { + flags = 0; + } + return fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +#endif + +#if defined(MODULE_REMOTE) && defined(SO_BROADCAST) +static int +set_broadcast(int socket_fd) +{ + int opt = 1; + return setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)); +} + +#endif + +#ifdef SO_NOSIGPIPE +static int +set_nosigpipe(int socket_fd) +{ + int opt = 1; + return setsockopt(socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); +} + +#endif + +#ifdef MODULE_REDIR + +#ifndef IP_TRANSPARENT +#define IP_TRANSPARENT 19 +#endif + +#ifndef IP_RECVORIGDSTADDR +#define IP_RECVORIGDSTADDR 20 +#endif + +static int +get_dstaddr(struct msghdr *msg, struct sockaddr_storage *dstaddr) +{ + struct cmsghdr *cmsg; + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVORIGDSTADDR) { + memcpy(dstaddr, CMSG_DATA(cmsg), sizeof(struct sockaddr_in)); + dstaddr->ss_family = AF_INET; + return 0; + } else if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IP_RECVORIGDSTADDR) { + memcpy(dstaddr, CMSG_DATA(cmsg), sizeof(struct sockaddr_in6)); + dstaddr->ss_family = AF_INET6; + return 0; + } + } + + return 1; +} + +#endif + +#define HASH_KEY_LEN sizeof(struct sockaddr_storage) + sizeof(int) +static char * +hash_key(const int af, const struct sockaddr_storage *addr) +{ + size_t addr_len = sizeof(struct sockaddr_storage); + static char key[HASH_KEY_LEN]; + + memset(key, 0, HASH_KEY_LEN); + memcpy(key, &af, sizeof(int)); + memcpy(key + sizeof(int), (const uint8_t *)addr, addr_len); + + return key; +} + +#if defined(MODULE_REDIR) || defined(MODULE_REMOTE) +static int +construct_udprealy_header(const struct sockaddr_storage *in_addr, + char *addr_header) +{ + int addr_header_len = 0; + if (in_addr->ss_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)in_addr; + size_t addr_len = sizeof(struct in_addr); + addr_header[addr_header_len++] = 1; + memcpy(addr_header + addr_header_len, &addr->sin_addr, addr_len); + addr_header_len += addr_len; + memcpy(addr_header + addr_header_len, &addr->sin_port, 2); + addr_header_len += 2; + } else if (in_addr->ss_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)in_addr; + size_t addr_len = sizeof(struct in6_addr); + addr_header[addr_header_len++] = 4; + memcpy(addr_header + addr_header_len, &addr->sin6_addr, addr_len); + addr_header_len += addr_len; + memcpy(addr_header + addr_header_len, &addr->sin6_port, 2); + addr_header_len += 2; + } else { + return 0; + } + return addr_header_len; +} + +#endif + +static int +parse_udprealy_header(const char *buf, const size_t buf_len, + char *host, char *port, struct sockaddr_storage *storage) +{ + const uint8_t atyp = *(uint8_t *)buf; + int offset = 1; + + // get remote addr and port + if ((atyp & ADDRTYPE_MASK) == 1) { + // IP V4 + size_t in_addr_len = sizeof(struct in_addr); + if (buf_len >= in_addr_len + 3) { + if (storage != NULL) { + struct sockaddr_in *addr = (struct sockaddr_in *)storage; + addr->sin_family = AF_INET; + addr->sin_addr = *(struct in_addr *)(buf + offset); + addr->sin_port = *(uint16_t *)(buf + offset + in_addr_len); + } + if (host != NULL) { + dns_ntop(AF_INET, (const void *)(buf + offset), + host, INET_ADDRSTRLEN); + } + offset += in_addr_len; + } + } else if ((atyp & ADDRTYPE_MASK) == 3) { + // Domain name + uint8_t name_len = *(uint8_t *)(buf + offset); + if (name_len + 4 <= buf_len) { + if (storage != NULL) { + char tmp[257] = { 0 }; + struct cork_ip ip; + memcpy(tmp, buf + offset + 1, name_len); + if (cork_ip_init(&ip, tmp) != -1) { + if (ip.version == 4) { + struct sockaddr_in *addr = (struct sockaddr_in *)storage; + dns_pton(AF_INET, tmp, &(addr->sin_addr)); + addr->sin_port = *(uint16_t *)(buf + offset + 1 + name_len); + addr->sin_family = AF_INET; + } else if (ip.version == 6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; + dns_pton(AF_INET, tmp, &(addr->sin6_addr)); + addr->sin6_port = *(uint16_t *)(buf + offset + 1 + name_len); + addr->sin6_family = AF_INET6; + } + } + } + if (host != NULL) { + memcpy(host, buf + offset + 1, name_len); + } + offset += 1 + name_len; + } + } else if ((atyp & ADDRTYPE_MASK) == 4) { + // IP V6 + size_t in6_addr_len = sizeof(struct in6_addr); + if (buf_len >= in6_addr_len + 3) { + if (storage != NULL) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; + addr->sin6_family = AF_INET6; + addr->sin6_addr = *(struct in6_addr *)(buf + offset); + addr->sin6_port = *(uint16_t *)(buf + offset + in6_addr_len); + } + if (host != NULL) { + dns_ntop(AF_INET6, (const void *)(buf + offset), + host, INET6_ADDRSTRLEN); + } + offset += in6_addr_len; + } + } + + if (offset == 1) { + LOGE("[udp] invalid header with addr type %d", atyp); + return 0; + } + + if (port != NULL) { + sprintf(port, "%d", ntohs(*(uint16_t *)(buf + offset))); + } + offset += 2; + + return offset; +} + +static char * +get_addr_str(const struct sockaddr *sa) +{ + static char s[SS_ADDRSTRLEN]; + memset(s, 0, SS_ADDRSTRLEN); + char addr[INET6_ADDRSTRLEN] = { 0 }; + char port[PORTSTRLEN] = { 0 }; + uint16_t p; + + switch (sa->sa_family) { + case AF_INET: + dns_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), + addr, INET_ADDRSTRLEN); + p = ntohs(((struct sockaddr_in *)sa)->sin_port); + sprintf(port, "%d", p); + break; + + case AF_INET6: + dns_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), + addr, INET6_ADDRSTRLEN); + p = ntohs(((struct sockaddr_in *)sa)->sin_port); + sprintf(port, "%d", p); + break; + + default: + strncpy(s, "Unknown AF", SS_ADDRSTRLEN); + } + + int addr_len = strlen(addr); + int port_len = strlen(port); + memcpy(s, addr, addr_len); + memcpy(s + addr_len + 1, port, port_len); + s[addr_len] = ':'; + + return s; +} + +int +create_remote_socket(int ipv6) +{ + int remote_sock; + + if (ipv6) { + // Try to bind IPv6 first + struct sockaddr_in6 addr; + memset(&addr, 0, sizeof(struct sockaddr_in6)); + addr.sin6_family = AF_INET6; + addr.sin6_addr = in6addr_any; + addr.sin6_port = 0; + remote_sock = socket(AF_INET6, SOCK_DGRAM, 0); + if (remote_sock == -1) { + ERROR("[udp] cannot create socket"); + return -1; + } + if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) { + FATAL("[udp] cannot bind remote"); + return -1; + } + } else { + // Or else bind to IPv4 + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = 0; + remote_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (remote_sock == -1) { + ERROR("[udp] cannot create socket"); + return -1; + } + + if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) { + FATAL("[udp] cannot bind remote"); + return -1; + } + } + return remote_sock; +} + +int +create_server_socket(const char *host, const char *port) +{ + struct addrinfo hints; + struct addrinfo *result, *rp, *ipv4v6bindall; + int s, server_sock; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ + hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */ + hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ + hints.ai_protocol = IPPROTO_UDP; + + s = getaddrinfo(host, port, &hints, &result); + if (s != 0) { + LOGE("[udp] getaddrinfo: %s", gai_strerror(s)); + return -1; + } + + rp = result; + + /* + * On Linux, with net.ipv6.bindv6only = 0 (the default), getaddrinfo(NULL) with + * AI_PASSIVE returns 0.0.0.0 and :: (in this order). AI_PASSIVE was meant to + * return a list of addresses to listen on, but it is impossible to listen on + * 0.0.0.0 and :: at the same time, if :: implies dualstack mode. + */ + if (!host) { + ipv4v6bindall = result; + + /* Loop over all address infos found until a IPV6 address is found. */ + while (ipv4v6bindall) { + if (ipv4v6bindall->ai_family == AF_INET6) { + rp = ipv4v6bindall; /* Take first IPV6 address available */ + break; + } + ipv4v6bindall = ipv4v6bindall->ai_next; /* Get next address info, if any */ + } + } + + for (/*rp = result*/; rp != NULL; rp = rp->ai_next) { + server_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (server_sock == -1) { + continue; + } + + if (rp->ai_family == AF_INET6) { + int ipv6only = host ? 1 : 0; + setsockopt(server_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only)); + } + + int opt = 1; + setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); +#ifdef SO_NOSIGPIPE + set_nosigpipe(server_sock); +#endif + int err = set_reuseport(server_sock); + if (err == 0) { + LOGI("udp port reuse enabled"); + } +#ifdef IP_TOS + // Set QoS flag + int tos = 46; + setsockopt(server_sock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); +#endif + +#ifdef MODULE_REDIR + if (setsockopt(server_sock, SOL_IP, IP_TRANSPARENT, &opt, sizeof(opt))) { + ERROR("[udp] setsockopt IP_TRANSPARENT"); + exit(EXIT_FAILURE); + } + if (setsockopt(server_sock, IPPROTO_IP, IP_RECVORIGDSTADDR, &opt, sizeof(opt))) { + FATAL("[udp] setsockopt IP_RECVORIGDSTADDR"); + } +#endif + + s = bind(server_sock, rp->ai_addr, rp->ai_addrlen); + if (s == 0) { + /* We managed to bind successfully! */ + break; + } else { + ERROR("[udp] bind"); + } + + close(server_sock); + } + + if (rp == NULL) { + LOGE("[udp] cannot bind"); + return -1; + } + + freeaddrinfo(result); + + return server_sock; +} + +remote_ctx_t * +new_remote(int fd, server_ctx_t *server_ctx) +{ + remote_ctx_t *ctx = ss_malloc(sizeof(remote_ctx_t)); + memset(ctx, 0, sizeof(remote_ctx_t)); + + ctx->fd = fd; + ctx->server_ctx = server_ctx; + + ev_io_init(&ctx->io, remote_recv_cb, fd, EV_READ); + ev_timer_init(&ctx->watcher, remote_timeout_cb, server_ctx->timeout, + server_ctx->timeout); + + return ctx; +} + +server_ctx_t * +new_server_ctx(int fd) +{ + server_ctx_t *ctx = ss_malloc(sizeof(server_ctx_t)); + memset(ctx, 0, sizeof(server_ctx_t)); + + ctx->fd = fd; + + ev_io_init(&ctx->io, server_recv_cb, fd, EV_READ); + + return ctx; +} + +#ifdef MODULE_REMOTE +struct query_ctx * +new_query_ctx(char *buf, size_t len) +{ + struct query_ctx *ctx = ss_malloc(sizeof(struct query_ctx)); + memset(ctx, 0, sizeof(struct query_ctx)); + ctx->buf = ss_malloc(sizeof(buffer_t)); + balloc(ctx->buf, len); + memcpy(ctx->buf->array, buf, len); + ctx->buf->len = len; + return ctx; +} + +void +close_and_free_query(EV_P_ struct query_ctx *ctx) +{ + if (ctx != NULL) { + if (ctx->query != NULL) { + resolv_cancel(ctx->query); + ctx->query = NULL; + } + if (ctx->buf != NULL) { + bfree(ctx->buf); + ss_free(ctx->buf); + } + ss_free(ctx); + } +} + +#endif + +void +close_and_free_remote(EV_P_ remote_ctx_t *ctx) +{ + if (ctx != NULL) { + ev_timer_stop(EV_A_ & ctx->watcher); + ev_io_stop(EV_A_ & ctx->io); + close(ctx->fd); + ss_free(ctx); + } +} + +static void +remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) +{ + remote_ctx_t *remote_ctx + = cork_container_of(watcher, remote_ctx_t, watcher); + + if (verbose) { + LOGI("[udp] connection timeout"); + } + + char *key = hash_key(remote_ctx->af, &remote_ctx->src_addr); + cache_remove(remote_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN); +} + +#ifdef MODULE_REMOTE +static void +query_resolve_cb(struct sockaddr *addr, void *data) +{ + struct query_ctx *query_ctx = (struct query_ctx *)data; + struct ev_loop *loop = query_ctx->server_ctx->loop; + + if (verbose) { + LOGI("[udp] udns resolved"); + } + + query_ctx->query = NULL; + + if (addr == NULL) { + LOGE("[udp] udns returned an error"); + } else { + remote_ctx_t *remote_ctx = query_ctx->remote_ctx; + int cache_hit = 0; + + // Lookup in the conn cache + if (remote_ctx == NULL) { + char *key = hash_key(AF_UNSPEC, &query_ctx->src_addr); + cache_lookup(query_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)&remote_ctx); + } + + if (remote_ctx == NULL) { + int remotefd = create_remote_socket(addr->sa_family == AF_INET6); + if (remotefd != -1) { + setnonblocking(remotefd); +#ifdef SO_BROADCAST + set_broadcast(remotefd); +#endif +#ifdef SO_NOSIGPIPE + set_nosigpipe(remotefd); +#endif +#ifdef IP_TOS + // Set QoS flag + int tos = 46; + setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); +#endif +#ifdef SET_INTERFACE + if (query_ctx->server_ctx->iface) { + if (setinterface(remotefd, query_ctx->server_ctx->iface) == -1) + ERROR("setinterface"); + } +#endif + remote_ctx = new_remote(remotefd, query_ctx->server_ctx); + remote_ctx->src_addr = query_ctx->src_addr; + remote_ctx->server_ctx = query_ctx->server_ctx; + remote_ctx->addr_header_len = query_ctx->addr_header_len; + memcpy(remote_ctx->addr_header, query_ctx->addr_header, + query_ctx->addr_header_len); + } else { + ERROR("[udp] bind() error"); + } + } else { + cache_hit = 1; + } + + if (remote_ctx != NULL) { + memcpy(&remote_ctx->dst_addr, addr, sizeof(struct sockaddr_storage)); + + size_t addr_len = get_sockaddr_len(addr); + int s = sendto(remote_ctx->fd, query_ctx->buf->array, query_ctx->buf->len, + 0, addr, addr_len); + + if (s == -1) { + ERROR("[udp] sendto_remote"); + if (!cache_hit) { + close_and_free_remote(EV_A_ remote_ctx); + } + } else { + if (!cache_hit) { + // Add to conn cache + char *key = hash_key(AF_UNSPEC, &remote_ctx->src_addr); + cache_insert(query_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx); + ev_io_start(EV_A_ & remote_ctx->io); + ev_timer_start(EV_A_ & remote_ctx->watcher); + } + } + } + } + + // clean up + close_and_free_query(EV_A_ query_ctx); +} + +#endif + +static void +remote_recv_cb(EV_P_ ev_io *w, int revents) +{ + ssize_t r; + remote_ctx_t *remote_ctx = (remote_ctx_t *)w; + server_ctx_t *server_ctx = remote_ctx->server_ctx; + + // server has been closed + if (server_ctx == NULL) { + LOGE("[udp] invalid server"); + close_and_free_remote(EV_A_ remote_ctx); + return; + } + + struct sockaddr_storage src_addr; + socklen_t src_addr_len = sizeof(struct sockaddr_storage); + memset(&src_addr, 0, src_addr_len); + + buffer_t *buf = ss_malloc(sizeof(buffer_t)); + balloc(buf, buf_size); + + // recv + r = recvfrom(remote_ctx->fd, buf->array, buf_size, 0, (struct sockaddr *)&src_addr, &src_addr_len); + + if (r == -1) { + // error on recv + // simply drop that packet + ERROR("[udp] remote_recv_recvfrom"); + goto CLEAN_UP; + } else if (r > packet_size) { + LOGE("[udp] remote_recv_recvfrom fragmentation"); + goto CLEAN_UP; + } + + buf->len = r; + +#ifdef MODULE_LOCAL + int err = ss_decrypt_all(buf, server_ctx->method, 0, buf_size); + if (err) { + // drop the packet silently + goto CLEAN_UP; + } + + //SSR beg + if (server_ctx->protocol_plugin) { + obfs_class *protocol_plugin = server_ctx->protocol_plugin; + if (protocol_plugin->client_udp_post_decrypt) { + buf->len = protocol_plugin->client_udp_post_decrypt(server_ctx->protocol, &buf->array, buf->len, &buf->capacity); + if ((int)buf->len < 0) { + LOGE("client_udp_post_decrypt"); + close_and_free_remote(EV_A_ remote_ctx); + return; + } + if ( buf->len == 0 ) + return; + } + } + // SSR end + +#ifdef MODULE_REDIR + struct sockaddr_storage dst_addr; + memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); + int len = parse_udprealy_header(buf->array, buf->len, NULL, NULL, &dst_addr); + + if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) { + LOGI("[udp] ss-redir does not support domain name"); + goto CLEAN_UP; + } + + if (verbose) { + char src[SS_ADDRSTRLEN]; + char dst[SS_ADDRSTRLEN]; + strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); + strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); + LOGI("[udp] recv %s via %s", dst, src); + } +#else + int len = parse_udprealy_header(buf->array, buf->len, NULL, NULL, NULL); +#endif + + if (len == 0) { + LOGI("[udp] error in parse header"); + // error in parse header + goto CLEAN_UP; + } + + // server may return using a different address type other than the type we + // have used during sending +#if defined(MODULE_TUNNEL) || defined(MODULE_REDIR) + // Construct packet + buf->len -= len; + memmove(buf->array, buf->array + len, buf->len); +#else +#ifdef ANDROID + rx += buf->len; +#endif + // Construct packet + brealloc(buf, buf->len + 3, buf_size); + memmove(buf->array + 3, buf->array, buf->len); + memset(buf->array, 0, 3); + buf->len += 3; +#endif + +#endif + +#ifdef MODULE_REMOTE + + rx += buf->len; + + char addr_header_buf[512]; + char *addr_header = remote_ctx->addr_header; + int addr_header_len = remote_ctx->addr_header_len; + + if (remote_ctx->af == AF_INET || remote_ctx->af == AF_INET6) { + addr_header_len = construct_udprealy_header(&src_addr, addr_header_buf); + addr_header = addr_header_buf; + } + + // Construct packet + brealloc(buf, buf->len + addr_header_len, buf_size); + memmove(buf->array + addr_header_len, buf->array, buf->len); + memcpy(buf->array, addr_header, addr_header_len); + buf->len += addr_header_len; + + int err = ss_encrypt_all(buf, server_ctx->method, 0, buf_size); + if (err) { + // drop the packet silently + goto CLEAN_UP; + } + +#endif + + if (buf->len > packet_size) { + LOGE("[udp] remote_recv_sendto fragmentation"); + goto CLEAN_UP; + } + + size_t remote_src_addr_len = get_sockaddr_len((struct sockaddr *)&remote_ctx->src_addr); + +#ifdef MODULE_REDIR + + size_t remote_dst_addr_len = get_sockaddr_len((struct sockaddr *)&dst_addr); + + int src_fd = socket(remote_ctx->src_addr.ss_family, SOCK_DGRAM, 0); + if (src_fd < 0) { + ERROR("[udp] remote_recv_socket"); + goto CLEAN_UP; + } + int opt = 1; + if (setsockopt(src_fd, SOL_IP, IP_TRANSPARENT, &opt, sizeof(opt))) { + ERROR("[udp] remote_recv_setsockopt"); + close(src_fd); + goto CLEAN_UP; + } + if (setsockopt(src_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { + ERROR("[udp] remote_recv_setsockopt"); + close(src_fd); + goto CLEAN_UP; + } +#ifdef IP_TOS + // Set QoS flag + int tos = 46; + setsockopt(src_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); +#endif + if (bind(src_fd, (struct sockaddr *)&dst_addr, remote_dst_addr_len) != 0) { + ERROR("[udp] remote_recv_bind"); + close(src_fd); + goto CLEAN_UP; + } + + int s = sendto(src_fd, buf->array, buf->len, 0, + (struct sockaddr *)&remote_ctx->src_addr, remote_src_addr_len); + if (s == -1) { + ERROR("[udp] remote_recv_sendto"); + close(src_fd); + goto CLEAN_UP; + } + close(src_fd); + +#else + + int s = sendto(server_ctx->fd, buf->array, buf->len, 0, + (struct sockaddr *)&remote_ctx->src_addr, remote_src_addr_len); + if (s == -1) { + ERROR("[udp] remote_recv_sendto"); + goto CLEAN_UP; + } + +#endif + + // handle the UDP packet successfully, + // triger the timer + ev_timer_again(EV_A_ & remote_ctx->watcher); + +CLEAN_UP: + + bfree(buf); + ss_free(buf); +} + +static void +server_recv_cb(EV_P_ ev_io *w, int revents) +{ + server_ctx_t *server_ctx = (server_ctx_t *)w; + struct sockaddr_storage src_addr; + memset(&src_addr, 0, sizeof(struct sockaddr_storage)); + + buffer_t *buf = ss_malloc(sizeof(buffer_t)); + balloc(buf, buf_size); + + socklen_t src_addr_len = sizeof(struct sockaddr_storage); + unsigned int offset = 0; + +#ifdef MODULE_REDIR + char control_buffer[64] = { 0 }; + struct msghdr msg; + memset(&msg, 0, sizeof(struct msghdr)); + struct iovec iov[1]; + struct sockaddr_storage dst_addr; + memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); + + msg.msg_name = &src_addr; + msg.msg_namelen = src_addr_len; + msg.msg_control = control_buffer; + msg.msg_controllen = sizeof(control_buffer); + + iov[0].iov_base = buf->array; + iov[0].iov_len = buf_size; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + buf->len = recvmsg(server_ctx->fd, &msg, 0); + if (buf->len == -1) { + ERROR("[udp] server_recvmsg"); + goto CLEAN_UP; + } else if (buf->len > packet_size) { + ERROR("[udp] UDP server_recv_recvmsg fragmentation"); + goto CLEAN_UP; + } + + if (get_dstaddr(&msg, &dst_addr)) { + LOGE("[udp] unable to get dest addr"); + goto CLEAN_UP; + } + + src_addr_len = msg.msg_namelen; +#else + ssize_t r; + r = recvfrom(server_ctx->fd, buf->array, buf_size, + 0, (struct sockaddr *)&src_addr, &src_addr_len); + + if (r == -1) { + // error on recv + // simply drop that packet + ERROR("[udp] server_recv_recvfrom"); + goto CLEAN_UP; + } else if (r > packet_size) { + ERROR("[udp] server_recv_recvfrom fragmentation"); + goto CLEAN_UP; + } + + buf->len = r; +#endif + +#ifdef MODULE_REMOTE + tx += buf->len; + + int err = ss_decrypt_all(buf, server_ctx->method, server_ctx->auth, buf_size); + if (err) { + // drop the packet silently + goto CLEAN_UP; + } +#endif + +#ifdef MODULE_LOCAL +#if !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR) +#ifdef ANDROID + tx += buf->len; +#endif + uint8_t frag = *(uint8_t *)(buf->array + 2); + offset += 3; +#endif +#endif + + /* + * + * SOCKS5 UDP Request + * +----+------+------+----------+----------+----------+ + * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | + * +----+------+------+----------+----------+----------+ + * | 2 | 1 | 1 | Variable | 2 | Variable | + * +----+------+------+----------+----------+----------+ + * + * SOCKS5 UDP Response + * +----+------+------+----------+----------+----------+ + * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | + * +----+------+------+----------+----------+----------+ + * | 2 | 1 | 1 | Variable | 2 | Variable | + * +----+------+------+----------+----------+----------+ + * + * shadowsocks UDP Request (before encrypted) + * +------+----------+----------+----------+-------------+ + * | ATYP | DST.ADDR | DST.PORT | DATA | HMAC-SHA1 | + * +------+----------+----------+----------+-------------+ + * | 1 | Variable | 2 | Variable | 10 | + * +------+----------+----------+----------+-------------+ + * + * If ATYP & ONETIMEAUTH_FLAG(0x10) != 0, Authentication (HMAC-SHA1) is enabled. + * + * The key of HMAC-SHA1 is (IV + KEY) and the input is the whole packet. + * The output of HMAC-SHA is truncated to 10 bytes (leftmost bits). + * + * shadowsocks UDP Response (before encrypted) + * +------+----------+----------+----------+ + * | ATYP | DST.ADDR | DST.PORT | DATA | + * +------+----------+----------+----------+ + * | 1 | Variable | 2 | Variable | + * +------+----------+----------+----------+ + * + * shadowsocks UDP Request and Response (after encrypted) + * +-------+--------------+ + * | IV | PAYLOAD | + * +-------+--------------+ + * | Fixed | Variable | + * +-------+--------------+ + * + */ + +#ifdef MODULE_REDIR + if (verbose) { + char src[SS_ADDRSTRLEN]; + char dst[SS_ADDRSTRLEN]; + strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); + strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); + LOGI("[udp] redir to %s from %s", dst, src); + } + + char addr_header[512] = { 0 }; + int addr_header_len = construct_udprealy_header(&dst_addr, addr_header); + + if (addr_header_len == 0) { + LOGE("[udp] failed to parse tproxy addr"); + goto CLEAN_UP; + } + + // reconstruct the buffer + brealloc(buf, buf->len + addr_header_len, buf_size); + memmove(buf->array + addr_header_len, buf->array, buf->len); + memcpy(buf->array, addr_header, addr_header_len); + buf->len += addr_header_len; + +#elif MODULE_TUNNEL + + char addr_header[512] = { 0 }; + char *host = server_ctx->tunnel_addr.host; + char *port = server_ctx->tunnel_addr.port; + uint16_t port_num = (uint16_t)atoi(port); + uint16_t port_net_num = htons(port_num); + int addr_header_len = 0; + + struct cork_ip ip; + if (cork_ip_init(&ip, host) != -1) { + if (ip.version == 4) { + // send as IPv4 + struct in_addr host_addr; + memset(&host_addr, 0, sizeof(struct in_addr)); + int host_len = sizeof(struct in_addr); + + if (dns_pton(AF_INET, host, &host_addr) == -1) { + FATAL("IP parser error"); + } + addr_header[addr_header_len++] = 1; + memcpy(addr_header + addr_header_len, &host_addr, host_len); + addr_header_len += host_len; + } else if (ip.version == 6) { + // send as IPv6 + struct in6_addr host_addr; + memset(&host_addr, 0, sizeof(struct in6_addr)); + int host_len = sizeof(struct in6_addr); + + if (dns_pton(AF_INET6, host, &host_addr) == -1) { + FATAL("IP parser error"); + } + addr_header[addr_header_len++] = 4; + memcpy(addr_header + addr_header_len, &host_addr, host_len); + addr_header_len += host_len; + } else { + FATAL("IP parser error"); + } + } else { + // send as domain + int host_len = strlen(host); + + addr_header[addr_header_len++] = 3; + addr_header[addr_header_len++] = host_len; + memcpy(addr_header + addr_header_len, host, host_len); + addr_header_len += host_len; + } + memcpy(addr_header + addr_header_len, &port_net_num, 2); + addr_header_len += 2; + + // reconstruct the buffer + brealloc(buf, buf->len + addr_header_len, buf_size); + memmove(buf->array + addr_header_len, buf->array, buf->len); + memcpy(buf->array, addr_header, addr_header_len); + buf->len += addr_header_len; + +#else + + char host[257] = { 0 }; + char port[64] = { 0 }; + struct sockaddr_storage dst_addr; + memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); + + int addr_header_len = parse_udprealy_header(buf->array + offset, buf->len - offset, + host, port, &dst_addr); + if (addr_header_len == 0) { + // error in parse header + goto CLEAN_UP; + } + + char *addr_header = buf->array + offset; +#endif + +#ifdef MODULE_LOCAL + char *key = hash_key(server_ctx->remote_addr->sa_family, &src_addr); +#else + char *key = hash_key(dst_addr.ss_family, &src_addr); +#endif + + struct cache *conn_cache = server_ctx->conn_cache; + + remote_ctx_t *remote_ctx = NULL; + cache_lookup(conn_cache, key, HASH_KEY_LEN, (void *)&remote_ctx); + + if (remote_ctx != NULL) { + if (sockaddr_cmp(&src_addr, &remote_ctx->src_addr, sizeof(src_addr))) { + remote_ctx = NULL; + } + } + + // reset the timer + if (remote_ctx != NULL) { + ev_timer_again(EV_A_ & remote_ctx->watcher); + } + + if (remote_ctx == NULL) { + if (verbose) { +#ifdef MODULE_REDIR + char src[SS_ADDRSTRLEN]; + char dst[SS_ADDRSTRLEN]; + strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); + strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); + LOGI("[udp] cache miss: %s <-> %s", dst, src); +#else + LOGI("[udp] cache miss: %s:%s <-> %s", host, port, + get_addr_str((struct sockaddr *)&src_addr)); +#endif + } + } else { + if (verbose) { +#ifdef MODULE_REDIR + char src[SS_ADDRSTRLEN]; + char dst[SS_ADDRSTRLEN]; + strcpy(src, get_addr_str((struct sockaddr *)&src_addr)); + strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr)); + LOGI("[udp] cache hit: %s <-> %s", dst, src); +#else + LOGI("[udp] cache hit: %s:%s <-> %s", host, port, + get_addr_str((struct sockaddr *)&src_addr)); +#endif + } + } + +#ifdef MODULE_LOCAL + +#if !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR) + if (frag) { + LOGE("[udp] drop a message since frag is not 0, but %d", frag); + goto CLEAN_UP; + } +#endif + + const struct sockaddr *remote_addr = server_ctx->remote_addr; + const int remote_addr_len = server_ctx->remote_addr_len; + + if (remote_ctx == NULL) { + // Bind to any port + int remotefd = create_remote_socket(remote_addr->sa_family == AF_INET6); + if (remotefd < 0) { + ERROR("[udp] udprelay bind() error"); + goto CLEAN_UP; + } + setnonblocking(remotefd); + +#ifdef SO_NOSIGPIPE + set_nosigpipe(remotefd); +#endif +#ifdef IP_TOS + // Set QoS flag + int tos = 46; + setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); +#endif +#ifdef SET_INTERFACE + if (server_ctx->iface) { + if (setinterface(remotefd, server_ctx->iface) == -1) + ERROR("setinterface"); + } +#endif + +#ifdef ANDROID + if (vpn) { + if (protect_socket(remotefd) == -1) { + ERROR("protect_socket"); + close(remotefd); + goto CLEAN_UP; + } + } +#endif + + // Init remote_ctx + remote_ctx = new_remote(remotefd, server_ctx); + remote_ctx->src_addr = src_addr; + remote_ctx->af = remote_addr->sa_family; + remote_ctx->addr_header_len = addr_header_len; + memcpy(remote_ctx->addr_header, addr_header, addr_header_len); + + // Add to conn cache + cache_insert(conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx); + + // Start remote io + ev_io_start(EV_A_ & remote_ctx->io); + ev_timer_start(EV_A_ & remote_ctx->watcher); + } + + if (offset > 0) { + buf->len -= offset; + memmove(buf->array, buf->array + offset, buf->len); + } + + if (server_ctx->auth) { + buf->array[0] |= ONETIMEAUTH_FLAG; + } + + // SSR beg + if (server_ctx->protocol_plugin) { + obfs_class *protocol_plugin = server_ctx->protocol_plugin; + if (protocol_plugin->client_udp_pre_encrypt) { + buf->len = protocol_plugin->client_udp_pre_encrypt(server_ctx->protocol, &buf->array, buf->len, &buf->capacity); + } + } + //SSR end + + int err = ss_encrypt_all(buf, server_ctx->method, server_ctx->auth, buf->len); + + if (err) { + // drop the packet silently + goto CLEAN_UP; + } + + if (buf->len > packet_size) { + LOGE("[udp] server_recv_sendto fragmentation"); + goto CLEAN_UP; + } + + int s = sendto(remote_ctx->fd, buf->array, buf->len, 0, remote_addr, remote_addr_len); + + if (s == -1) { + ERROR("[udp] server_recv_sendto"); + } + +#else + + int cache_hit = 0; + int need_query = 0; + + if (buf->len - addr_header_len > packet_size) { + LOGE("[udp] server_recv_sendto fragmentation"); + goto CLEAN_UP; + } + + if (remote_ctx != NULL) { + cache_hit = 1; + // detect destination mismatch + if (remote_ctx->addr_header_len != addr_header_len + || memcmp(addr_header, remote_ctx->addr_header, addr_header_len) != 0) { + if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) { + need_query = 1; + } + } else { + memcpy(&dst_addr, &remote_ctx->dst_addr, sizeof(struct sockaddr_storage)); + } + } else { + if (dst_addr.ss_family == AF_INET || dst_addr.ss_family == AF_INET6) { + int remotefd = create_remote_socket(dst_addr.ss_family == AF_INET6); + if (remotefd != -1) { + setnonblocking(remotefd); +#ifdef SO_BROADCAST + set_broadcast(remotefd); +#endif +#ifdef SO_NOSIGPIPE + set_nosigpipe(remotefd); +#endif +#ifdef IP_TOS + // Set QoS flag + int tos = 46; + setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); +#endif +#ifdef SET_INTERFACE + if (server_ctx->iface) { + if (setinterface(remotefd, server_ctx->iface) == -1) + ERROR("setinterface"); + } +#endif + remote_ctx = new_remote(remotefd, server_ctx); + remote_ctx->src_addr = src_addr; + remote_ctx->server_ctx = server_ctx; + remote_ctx->addr_header_len = addr_header_len; + memcpy(remote_ctx->addr_header, addr_header, addr_header_len); + memcpy(&remote_ctx->dst_addr, &dst_addr, sizeof(struct sockaddr_storage)); + } else { + ERROR("[udp] bind() error"); + goto CLEAN_UP; + } + } + } + + if (remote_ctx != NULL && !need_query) { + size_t addr_len = get_sockaddr_len((struct sockaddr *)&dst_addr); + int s = sendto(remote_ctx->fd, buf->array + addr_header_len, + buf->len - addr_header_len, 0, + (struct sockaddr *)&dst_addr, addr_len); + + if (s == -1) { + ERROR("[udp] sendto_remote"); + if (!cache_hit) { + close_and_free_remote(EV_A_ remote_ctx); + } + } else { + if (!cache_hit) { + // Add to conn cache + remote_ctx->af = dst_addr.ss_family; + char *key = hash_key(remote_ctx->af, &remote_ctx->src_addr); + cache_insert(server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx); + + ev_io_start(EV_A_ & remote_ctx->io); + ev_timer_start(EV_A_ & remote_ctx->watcher); + } + } + } else { + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + + struct query_ctx *query_ctx = new_query_ctx(buf->array + addr_header_len, + buf->len - addr_header_len); + query_ctx->server_ctx = server_ctx; + query_ctx->addr_header_len = addr_header_len; + query_ctx->src_addr = src_addr; + memcpy(query_ctx->addr_header, addr_header, addr_header_len); + + if (need_query) { + query_ctx->remote_ctx = remote_ctx; + } + + struct ResolvQuery *query = resolv_query(host, query_resolve_cb, + NULL, query_ctx, htons(atoi(port))); + if (query == NULL) { + ERROR("[udp] unable to create DNS query"); + close_and_free_query(EV_A_ query_ctx); + goto CLEAN_UP; + } + query_ctx->query = query; + } +#endif + +CLEAN_UP: + bfree(buf); + ss_free(buf); +} + +void +free_cb(void *key, void *element) +{ + remote_ctx_t *remote_ctx = (remote_ctx_t *)element; + + if (verbose) { + LOGI("[udp] one connection freed"); + } + + close_and_free_remote(EV_DEFAULT, remote_ctx); +} + +int +init_udprelay(const char *server_host, const char *server_port, +#ifdef MODULE_LOCAL + const struct sockaddr *remote_addr, const int remote_addr_len, +#ifdef MODULE_TUNNEL + const ss_addr_t tunnel_addr, +#endif +#endif + int mtu, int method, int auth, int timeout, const char *iface, const char *protocol, const char *protocol_param) +{ + // Initialize ev loop + struct ev_loop *loop = EV_DEFAULT; + + // Initialize MTU + if (mtu > 0) { + packet_size = mtu - 1 - 28 - 2 - 64; + buf_size = packet_size * 2; + } + + // Initialize cache + struct cache *conn_cache; + cache_create(&conn_cache, MAX_UDP_CONN_NUM, free_cb); + + // //////////////////////////////////////////////// + // Setup server context + + // Bind to port + int serverfd = create_server_socket(server_host, server_port); + if (serverfd < 0) { + FATAL("[udp] bind() error"); + } + setnonblocking(serverfd); + if (protocol != NULL && strcmp(protocol, "verify_sha1") == 0) { + auth = 1; + protocol = NULL; + } + + server_ctx_t *server_ctx = new_server_ctx(serverfd); +#ifdef MODULE_REMOTE + server_ctx->loop = loop; +#endif + server_ctx->auth = auth; + server_ctx->timeout = max(timeout, MIN_UDP_TIMEOUT); + server_ctx->method = method; + server_ctx->iface = iface; + server_ctx->conn_cache = conn_cache; +#ifdef MODULE_LOCAL + server_ctx->remote_addr = remote_addr; + server_ctx->remote_addr_len = remote_addr_len; + //SSR beg + server_ctx->protocol_plugin = new_obfs_class((char *)protocol); + if (server_ctx->protocol_plugin) { + server_ctx->protocol = server_ctx->protocol_plugin->new_obfs(); + server_ctx->protocol_global = server_ctx->protocol_plugin->init_data(); + } + + server_info _server_info; + memset(&_server_info, 0, sizeof(server_info)); + strcpy(_server_info.host, inet_ntoa(((struct sockaddr_in*)remote_addr)->sin_addr)); + _server_info.port = ((struct sockaddr_in*)remote_addr)->sin_port; + _server_info.port = _server_info.port >> 8 | _server_info.port << 8; + _server_info.g_data = server_ctx->protocol_global; + _server_info.param = (char *)protocol_param; + _server_info.key = enc_get_key(); + _server_info.key_len = enc_get_key_len(); + + if (server_ctx->protocol_plugin) + server_ctx->protocol_plugin->set_server_info(server_ctx->protocol, &_server_info); + //SSR end +#ifdef MODULE_TUNNEL + server_ctx->tunnel_addr = tunnel_addr; +#endif +#endif + + ev_io_start(loop, &server_ctx->io); + + server_ctx_list[server_num++] = server_ctx; + + return 0; +} + +void +free_udprelay() +{ + struct ev_loop *loop = EV_DEFAULT; + while (server_num-- > 0) { + server_ctx_t *server_ctx = server_ctx_list[server_num]; + +#ifdef MODULE_LOCAL + //SSR beg + if (server_ctx->protocol_plugin) { + server_ctx->protocol_plugin->dispose(server_ctx->protocol); + server_ctx->protocol = NULL; + free_obfs_class(server_ctx->protocol_plugin); + server_ctx->protocol_plugin = NULL; + } + //SSR end +#endif + + ev_io_stop(loop, &server_ctx->io); + close(server_ctx->fd); + cache_delete(server_ctx->conn_cache, 0); + ss_free(server_ctx); + server_ctx_list[server_num] = NULL; + } +} diff --git a/shadowsocksr-libev/src/server/udprelay.h b/shadowsocksr-libev/src/server/udprelay.h new file mode 100644 index 00000000..89876d4f --- /dev/null +++ b/shadowsocksr-libev/src/server/udprelay.h @@ -0,0 +1,95 @@ +/* + * udprelay.h - Define UDP relay's buffers and callbacks + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef _UDPRELAY_H +#define _UDPRELAY_H + +#include +#include + +#include "encrypt.h" +#include "jconf.h" +#include "obfs.h" + +#ifdef MODULE_REMOTE +#include "resolv.h" +#endif + +#include "cache.h" + +#include "common.h" + +#define MAX_UDP_PACKET_SIZE (65507) + +#define DEFAULT_PACKET_SIZE 1397 // 1492 - 1 - 28 - 2 - 64 = 1397, the default MTU for UDP relay + +typedef struct server_ctx { + ev_io io; + int fd; + int method; + int auth; + int timeout; + const char *iface; + struct cache *conn_cache; +#ifdef MODULE_LOCAL + const struct sockaddr *remote_addr; + int remote_addr_len; +#ifdef MODULE_TUNNEL + ss_addr_t tunnel_addr; +#endif +#endif +#ifdef MODULE_REMOTE + struct ev_loop *loop; +#endif + // SSR + obfs *protocol; + obfs_class *protocol_plugin; + void *protocol_global; +} server_ctx_t; + +#ifdef MODULE_REMOTE +typedef struct query_ctx { + struct ResolvQuery *query; + struct sockaddr_storage src_addr; + buffer_t *buf; + int addr_header_len; + char addr_header[384]; + struct server_ctx *server_ctx; + struct remote_ctx *remote_ctx; +} query_ctx_t; +#endif + +typedef struct remote_ctx { + ev_io io; + ev_timer watcher; + int af; + int fd; + int addr_header_len; + char addr_header[384]; + struct sockaddr_storage src_addr; +#ifdef MODULE_REMOTE + struct sockaddr_storage dst_addr; +#endif + struct server_ctx *server_ctx; +} remote_ctx_t; + +#endif // _UDPRELAY_H diff --git a/shadowsocksr-libev/src/server/uthash.h b/shadowsocksr-libev/src/server/uthash.h new file mode 100644 index 00000000..45d1f9fc --- /dev/null +++ b/shadowsocksr-libev/src/server/uthash.h @@ -0,0 +1,1074 @@ +/* +Copyright (c) 2003-2016, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.0.1 + +#include /* memcmp,strlen */ +#include /* ptrdiff_t */ +#include /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#elif defined(__BORLANDC__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#define DECLTYPE(x) +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif +#ifndef uthash_memcmp +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + struct UT_hash_handle *_hs_iter = &(head)->hh; \ + (add)->hh.tbl = (head)->hh.tbl; \ + do { \ + if (cmpfcn(DECLTYPE(head) ELMT_FROM_HH((head)->hh.tbl, _hs_iter), add) > 0) \ + break; \ + } while ((_hs_iter = _hs_iter->next)); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = _hs_iter->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter->prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + _hs_iter->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + (head) = (add); \ + HASH_MAKE_TABLE(hh, head); \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], &(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + HASH_FSCK(hh, head); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + unsigned _hd_bkt; \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev != NULL) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,(unsigned)uthash_strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield[0],(unsigned)uthash_strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count; \ + char *_prev; \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %u, actual %u\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %u, actual %u\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen=(unsigned)keylen; \ + const unsigned char *_hb_key=(const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key=(const unsigned char*)(key); \ + hashv = 2166136261U; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i!=0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch((keylen) & 3U) { \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (uthash_memcmp((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head != NULL) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if ((head.count >= ((head.expand_mult+1U) * HASH_BKT_CAPACITY_THRESH)) \ + && ((addhh)->tbl->noexpand != 1U)) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2UL * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1U)) + \ + (((tbl->num_items & ((tbl->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { _he_newbkt->hh_head->hh_prev = \ + _he_thh; } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2U; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1U) : 0U; \ + if (tbl->ineff_expands > 1U) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) { break; } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0U) || ((_hs_qsize > 0U) && (_hs_q != NULL))) {\ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0U) || (_hs_q == NULL) ) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next != NULL) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next != NULL) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL){ \ + _hs_tail->next = NULL; \ + } \ + if ( _hs_nmerges <= 1U ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src != NULL) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { _last_elt_hh->next = _elt; } \ + if (dst == NULL) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head != NULL) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + ((head != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/shadowsocksr-libev/src/server/utils.c b/shadowsocksr-libev/src/server/utils.c new file mode 100644 index 00000000..14a60c7f --- /dev/null +++ b/shadowsocksr-libev/src/server/utils.c @@ -0,0 +1,448 @@ +/* + * utils.c - Misc utilities + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#ifndef __MINGW32__ +#include +#include +#endif + +#include +#include + +#include "utils.h" + +#ifdef HAVE_SETRLIMIT +#include +#include +#endif + +#define INT_DIGITS 19 /* enough for 64 bit integer */ + +#ifdef LIB_ONLY +FILE *logfile; +#endif + +#ifdef HAS_SYSLOG +int use_syslog = 0; +#endif + +#ifndef __MINGW32__ +void +ERROR(const char *s) +{ + char *msg = strerror(errno); + LOGE("%s: %s", s, msg); +} + +#endif + +int use_tty = 1; + +char * +ss_itoa(int i) +{ + /* Room for INT_DIGITS digits, - and '\0' */ + static char buf[INT_DIGITS + 2]; + char *p = buf + INT_DIGITS + 1; /* points to terminating '\0' */ + if (i >= 0) { + do { + *--p = '0' + (i % 10); + i /= 10; + } while (i != 0); + return p; + } else { /* i < 0 */ + do { + *--p = '0' - (i % 10); + i /= 10; + } while (i != 0); + *--p = '-'; + } + return p; +} + +int +ss_isnumeric(const char *s) { + if (!s || !*s) + return 0; + while (isdigit(*s)) + ++s; + return *s == '\0'; +} + +/* + * setuid() and setgid() for a specified user. + */ +int +run_as(const char *user) +{ +#ifndef __MINGW32__ + if (user[0]) { + /* Convert user to a long integer if it is a non-negative number. + * -1 means it is a user name. */ + long uid = -1; + if (ss_isnumeric(user)) { + errno = 0; + char *endptr; + uid = strtol(user, &endptr, 10); + if (errno || endptr == user) + uid = -1; + } + +#ifdef HAVE_GETPWNAM_R + struct passwd pwdbuf, *pwd; + memset(&pwdbuf, 0, sizeof(struct passwd)); + size_t buflen; + int err; + + for (buflen = 128;; buflen *= 2) { + char buf[buflen]; /* variable length array */ + + /* Note that we use getpwnam_r() instead of getpwnam(), + * which returns its result in a statically allocated buffer and + * cannot be considered thread safe. */ + err = uid >= 0 ? getpwuid_r((uid_t)uid, &pwdbuf, buf, buflen, &pwd) + : getpwnam_r(user, &pwdbuf, buf, buflen, &pwd); + + if (err == 0 && pwd) { + /* setgid first, because we may not be allowed to do it anymore after setuid */ + if (setgid(pwd->pw_gid) != 0) { + LOGE( + "Could not change group id to that of run_as user '%s': %s", + pwd->pw_name, strerror(errno)); + return 0; + } + + if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { + LOGE("Could not change supplementary groups for user '%s'.", pwd->pw_name); + return 0; + } + + if (setuid(pwd->pw_uid) != 0) { + LOGE( + "Could not change user id to that of run_as user '%s': %s", + pwd->pw_name, strerror(errno)); + return 0; + } + break; + } else if (err != ERANGE) { + if (err) { + LOGE("run_as user '%s' could not be found: %s", user, + strerror(err)); + } else { + LOGE("run_as user '%s' could not be found.", user); + } + return 0; + } else if (buflen >= 16 * 1024) { + /* If getpwnam_r() seems defective, call it quits rather than + * keep on allocating ever larger buffers until we crash. */ + LOGE( + "getpwnam_r() requires more than %u bytes of buffer space.", + (unsigned)buflen); + return 0; + } + /* Else try again with larger buffer. */ + } +#else + /* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */ + struct passwd *pwd; + + if (!(pwd = uid >=0 ? getpwuid((uid_t)uid) : getpwnam(user))) { + LOGE("run_as user %s could not be found.", user); + return 0; + } + /* setgid first, because we may not allowed to do it anymore after setuid */ + if (setgid(pwd->pw_gid) != 0) { + LOGE("Could not change group id to that of run_as user '%s': %s", + pwd->pw_name, strerror(errno)); + return 0; + } + if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { + LOGE("Could not change supplementary groups for user '%s'.", pwd->pw_name); + return 0; + } + if (setuid(pwd->pw_uid) != 0) { + LOGE("Could not change user id to that of run_as user '%s': %s", + pwd->pw_name, strerror(errno)); + return 0; + } +#endif + } + +#endif // __MINGW32__ + return 1; +} + +char * +ss_strndup(const char *s, size_t n) +{ + size_t len = strlen(s); + char *ret; + + if (len <= n) { + return strdup(s); + } + + ret = ss_malloc(n + 1); + strncpy(ret, s, n); + ret[n] = '\0'; + return ret; +} + +void +FATAL(const char *msg) +{ + LOGE("%s", msg); + exit(-1); +} + +void * +ss_malloc(size_t size) +{ + void *tmp = malloc(size); + if (tmp == NULL) + exit(EXIT_FAILURE); + return tmp; +} + +void * +ss_realloc(void *ptr, size_t new_size) +{ + void *new = realloc(ptr, new_size); + if (new == NULL) { + free(ptr); + ptr = NULL; + exit(EXIT_FAILURE); + } + return new; +} + +void +usage() +{ + printf("\n"); + printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO); + printf( + " maintained by Max Lv and Linus Yang \n\n"); + printf(" usage:\n\n"); +#ifdef MODULE_LOCAL + printf(" ss-local\n"); +#elif MODULE_REMOTE + printf(" ss-server\n"); +#elif MODULE_TUNNEL + printf(" ss-tunnel\n"); +#elif MODULE_REDIR + printf(" ss-redir\n"); +#elif MODULE_MANAGER + printf(" ss-manager\n"); +#endif + printf("\n"); + printf( + " -s Host name or IP address of your remote server.\n"); + printf( + " -p Port number of your remote server.\n"); + printf( + " -l Port number of your local server.\n"); + printf( + " -k Password of your remote server.\n"); + printf( + " -m Encrypt method: table, rc4, rc4-md5,\n"); + printf( + " aes-128-cfb, aes-192-cfb, aes-256-cfb,\n"); + printf( + " aes-128-ctr, aes-192-ctr, aes-256-ctr,\n"); + printf( + " bf-cfb, camellia-128-cfb, camellia-192-cfb,\n"); + printf( + " camellia-256-cfb, cast5-cfb, des-cfb,\n"); + printf( + " idea-cfb, rc2-cfb, seed-cfb, salsa20,\n"); + printf( + " chacha20 and chacha20-ietf.\n"); + printf( + " The default cipher is rc4-md5.\n"); + printf("\n"); + printf( + " [-a ] Run as another user.\n"); + printf( + " [-f ] The file path to store pid.\n"); + printf( + " [-t ] Socket timeout in seconds.\n"); + printf( + " [-c ] The path to config file.\n"); +#ifdef HAVE_SETRLIMIT + printf( + " [-n ] Max number of open files.\n"); +#endif +#ifndef MODULE_REDIR + printf( + " [-i ] Network interface to bind.\n"); +#endif + printf( + " [-b ] Local address to bind.\n"); + printf("\n"); + printf( + " [-u] Enable UDP relay.\n"); +#ifdef MODULE_REDIR + printf( + " TPROXY is required in redir mode.\n"); +#endif + printf( + " [-U] Enable UDP relay and disable TCP relay.\n"); + printf( + " [-A] Enable onetime authentication.\n"); +#ifdef MODULE_REMOTE + printf( + " [-6] Resovle hostname to IPv6 address first.\n"); +#endif + printf("\n"); +#ifdef MODULE_TUNNEL + printf( + " [-L :] Destination server address and port\n"); + printf( + " for local port forwarding.\n"); +#endif +#ifdef MODULE_REMOTE + printf( + " [-d ] Name servers for internal DNS resolver.\n"); +#endif +#if defined(MODULE_REMOTE) || defined(MODULE_LOCAL) + printf( + " [--fast-open] Enable TCP fast open.\n"); + printf( + " with Linux kernel > 3.7.0.\n"); + printf( + " [--acl ] Path to ACL (Access Control List).\n"); +#endif +#if defined(MODULE_REMOTE) || defined(MODULE_MANAGER) + printf( + " [--manager-address ] UNIX domain socket address.\n"); +#endif +#ifdef MODULE_MANAGER + printf( + " [--executable ] Path to the executable of ss-server.\n"); +#endif + printf( + " [--mtu ] MTU of your network interface.\n"); +#ifdef __linux__ + printf( + " [--mptcp] Enable Multipath TCP on MPTCP Kernel.\n"); +#ifdef MODULE_REMOTE + printf( + " [--firewall] Setup firewall rules for auto blocking.\n"); +#endif +#endif + printf("\n"); + printf( + " [-v] Verbose mode.\n"); + printf( + " [-h, --help] Print this message.\n"); + printf("\n"); +} + +void +daemonize(const char *path) +{ +#ifndef __MINGW32__ + /* Our process ID and Session ID */ + pid_t pid, sid; + + /* Fork off the parent process */ + pid = fork(); + if (pid < 0) { + exit(EXIT_FAILURE); + } + + /* If we got a good PID, then + * we can exit the parent process. */ + if (pid > 0) { + FILE *file = fopen(path, "w"); + if (file == NULL) { + FATAL("Invalid pid file\n"); + } + + fprintf(file, "%d", (int)pid); + fclose(file); + exit(EXIT_SUCCESS); + } + + /* Change the file mode mask */ + umask(0); + + /* Open any logs here */ + + /* Create a new SID for the child process */ + sid = setsid(); + if (sid < 0) { + /* Log the failure */ + exit(EXIT_FAILURE); + } + + /* Change the current working directory */ + if ((chdir("/")) < 0) { + /* Log the failure */ + exit(EXIT_FAILURE); + } + + /* Close out the standard file descriptors */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +#endif +} + +#ifdef HAVE_SETRLIMIT +int +set_nofile(int nofile) +{ + struct rlimit limit = { nofile, nofile }; /* set both soft and hard limit */ + + if (nofile <= 0) { + FATAL("nofile must be greater than 0\n"); + } + + if (setrlimit(RLIMIT_NOFILE, &limit) < 0) { + if (errno == EPERM) { + LOGE( + "insufficient permission to change NOFILE, not starting as root?"); + return -1; + } else if (errno == EINVAL) { + LOGE("invalid nofile, decrease nofile and try again"); + return -1; + } else { + LOGE("setrlimit failed: %s", strerror(errno)); + return -1; + } + } + + return 0; +} + +#endif diff --git a/shadowsocksr-libev/src/server/utils.h b/shadowsocksr-libev/src/server/utils.h new file mode 100644 index 00000000..0fb7f5a2 --- /dev/null +++ b/shadowsocksr-libev/src/server/utils.h @@ -0,0 +1,232 @@ +/* + * utils.h - Misc utilities + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#if defined(USE_CRYPTO_OPENSSL) + +#include +#define USING_CRYPTO OPENSSL_VERSION_TEXT + +#elif defined(USE_CRYPTO_POLARSSL) +#include +#define USING_CRYPTO POLARSSL_VERSION_STRING_FULL + +#elif defined(USE_CRYPTO_MBEDTLS) +#include +#define USING_CRYPTO MBEDTLS_VERSION_STRING_FULL + +#endif + +#ifndef _UTILS_H +#define _UTILS_H + +#include +#include +#include +#include + +#define PORTSTRLEN 16 +#define SS_ADDRSTRLEN (INET6_ADDRSTRLEN + PORTSTRLEN + 1) + +#ifdef ANDROID + +#include + +#define USE_TTY() +#define USE_SYSLOG(ident) +#define LOGI(...) \ + ((void)__android_log_print(ANDROID_LOG_DEBUG, "shadowsocks", \ + __VA_ARGS__)) +#define LOGE(...) \ + ((void)__android_log_print(ANDROID_LOG_ERROR, "shadowsocks", \ + __VA_ARGS__)) + +#else + +#define STR(x) # x +#define TOSTR(x) STR(x) + +#ifdef LIB_ONLY + +extern FILE *logfile; + +#define TIME_FORMAT "%Y-%m-%d %H:%M:%S" + +#define USE_TTY() + +#define USE_SYSLOG(ident) + +#define USE_LOGFILE(ident) \ + do { \ + if (ident != NULL) { logfile = fopen(ident, "w+"); } } \ + while (0) + +#define CLOSE_LOGFILE \ + do { \ + if (logfile != NULL) { fclose(logfile); } } \ + while (0) + +#define LOGI(format, ...) \ + do { \ + if (logfile != NULL) { \ + time_t now = time(NULL); \ + char timestr[20]; \ + strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ + fprintf(logfile, " %s INFO: " format "\n", timestr, ## __VA_ARGS__); \ + fflush(logfile); } \ + } \ + while (0) + +#define LOGE(format, ...) \ + do { \ + if (logfile != NULL) { \ + time_t now = time(NULL); \ + char timestr[20]; \ + strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ + fprintf(logfile, " %s ERROR: " format "\n", timestr, \ + ## __VA_ARGS__); \ + fflush(logfile); } \ + } \ + while (0) + +#elif defined(_WIN32) + +#define TIME_FORMAT "%Y-%m-%d %H:%M:%S" + +#define USE_TTY() + +#define USE_SYSLOG(ident) + +#define LOGI(format, ...) \ + do { \ + time_t now = time(NULL); \ + char timestr[20]; \ + strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ + fprintf(stderr, " %s INFO: " format "\n", timestr, ## __VA_ARGS__); \ + fflush(stderr); } \ + while (0) + +#define LOGE(format, ...) \ + do { \ + time_t now = time(NULL); \ + char timestr[20]; \ + strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ + fprintf(stderr, " %s ERROR: " format "\n", timestr, ## __VA_ARGS__); \ + fflush(stderr); } \ + while (0) + +#else + +#include + +extern int use_tty; +#define USE_TTY() \ + do { \ + use_tty = isatty(STDERR_FILENO); \ + } while (0) \ + +#define HAS_SYSLOG +extern int use_syslog; + +#define TIME_FORMAT "%F %T" + +#define USE_SYSLOG(ident) \ + do { \ + use_syslog = 1; \ + openlog((ident), LOG_CONS | LOG_PID, 0); } \ + while (0) + +#define LOGI(format, ...) \ + do { \ + if (use_syslog) { \ + syslog(LOG_INFO, format, ## __VA_ARGS__); \ + } else { \ + time_t now = time(NULL); \ + char timestr[20]; \ + strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ + if (use_tty) { \ + fprintf(stderr, "\e[01;32m %s INFO: \e[0m" format "\n", timestr, \ + ## __VA_ARGS__); \ + } else { \ + fprintf(stderr, " %s INFO: " format "\n", timestr, \ + ## __VA_ARGS__); \ + } \ + } \ + } \ + while (0) + +#define LOGE(format, ...) \ + do { \ + if (use_syslog) { \ + syslog(LOG_ERR, format, ## __VA_ARGS__); \ + } else { \ + time_t now = time(NULL); \ + char timestr[20]; \ + strftime(timestr, 20, TIME_FORMAT, localtime(&now)); \ + if (use_tty) { \ + fprintf(stderr, "\e[01;35m %s ERROR: \e[0m" format "\n", timestr, \ + ## __VA_ARGS__); \ + } else { \ + fprintf(stderr, " %s ERROR: " format "\n", timestr, \ + ## __VA_ARGS__); \ + } \ + } } \ + while (0) + +#endif +/* _WIN32 */ + +#endif + +#ifdef __MINGW32__ + +#ifdef ERROR +#undef ERROR +#endif +#define ERROR(s) ss_error(s) + +#else + +void ERROR(const char *s); + +#endif + +char *ss_itoa(int i); +int ss_isnumeric(const char *s); +int run_as(const char *user); +void FATAL(const char *msg); +void usage(void); +void daemonize(const char *path); +char *ss_strndup(const char *s, size_t n); +#ifdef HAVE_SETRLIMIT +int set_nofile(int nofile); +#endif + +void *ss_malloc(size_t size); +void *ss_realloc(void *ptr, size_t new_size); + +#define ss_free(ptr) \ + do { \ + free(ptr); \ + ptr = NULL; \ + } while (0) + +#endif // _UTILS_H diff --git a/shadowsocksr-libev/src/server/verify.c b/shadowsocksr-libev/src/server/verify.c new file mode 100644 index 00000000..9e7393dd --- /dev/null +++ b/shadowsocksr-libev/src/server/verify.c @@ -0,0 +1,188 @@ + +#include "verify.h" + +static int verify_simple_pack_unit_size = 2000; + +typedef struct verify_simple_local_data { + char * recv_buffer; + int recv_buffer_size; +}verify_simple_local_data; + +void verify_simple_local_data_init(verify_simple_local_data* local) { + local->recv_buffer = (char*)malloc(16384); + local->recv_buffer_size = 0; +} + +obfs * verify_simple_new_obfs() { + obfs * self = new_obfs(); + self->l_data = malloc(sizeof(verify_simple_local_data)); + verify_simple_local_data_init((verify_simple_local_data*)self->l_data); + return self; +} + +void verify_simple_dispose(obfs *self) { + verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; + if (local->recv_buffer != NULL) { + free(local->recv_buffer); + local->recv_buffer = NULL; + } + free(local); + self->l_data = NULL; + dispose_obfs(self); +} + +int verify_simple_pack_data(char *data, int datalength, char *outdata) { + unsigned char rand_len = (xorshift128plus() & 0xF) + 1; + int out_size = rand_len + datalength + 6; + outdata[0] = out_size >> 8; + outdata[1] = out_size; + outdata[2] = rand_len; + memmove(outdata + rand_len + 2, data, datalength); + fillcrc32((unsigned char *)outdata, out_size); + return out_size; +} + +int verify_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { + char *plaindata = *pplaindata; + //verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 32); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + while ( len > verify_simple_pack_unit_size ) { + pack_len = verify_simple_pack_data(data, verify_simple_pack_unit_size, buffer); + buffer += pack_len; + data += verify_simple_pack_unit_size; + len -= verify_simple_pack_unit_size; + } + if (len > 0) { + pack_len = verify_simple_pack_data(data, len, buffer); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int verify_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { + char *plaindata = *pplaindata; + verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + return -1; + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + while (local->recv_buffer_size > 2) { + int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; + if (length >= 8192 || length < 7) { + free(out_buffer); + local->recv_buffer_size = 0; + return -1; + } + if (length > local->recv_buffer_size) + break; + + int crc = crc32((unsigned char*)recv_buffer, length); + if (crc != -1) { + free(out_buffer); + local->recv_buffer_size = 0; + return -1; + } + int data_size = length - recv_buffer[2] - 6; + memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int verify_simple_server_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { + char *plaindata = *pplaindata; + //verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; + char * out_buffer = (char*)malloc(datalength * 2 + 32); + char * buffer = out_buffer; + char * data = plaindata; + int len = datalength; + int pack_len; + while ( len > verify_simple_pack_unit_size ) { + pack_len = verify_simple_pack_data(data, verify_simple_pack_unit_size, buffer); + buffer += pack_len; + data += verify_simple_pack_unit_size; + len -= verify_simple_pack_unit_size; + } + if (len > 0) { + pack_len = verify_simple_pack_data(data, len, buffer); + buffer += pack_len; + } + len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} + +int verify_simple_server_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) { + char *plaindata = *pplaindata; + verify_simple_local_data *local = (verify_simple_local_data*)self->l_data; + uint8_t * recv_buffer = (uint8_t *)local->recv_buffer; + if (local->recv_buffer_size + datalength > 16384) + { + LOGE("verify_simple: wrong buf length %d", local->recv_buffer_size + datalength); + return -1; + } + memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength); + local->recv_buffer_size += datalength; + + char * out_buffer = (char*)malloc(local->recv_buffer_size); + char * buffer = out_buffer; + while (local->recv_buffer_size > 2) { + int length = ((int)recv_buffer[0] << 8) | recv_buffer[1]; + if (length >= 8192 || length < 7) { + free(out_buffer); + local->recv_buffer_size = 0; + LOGE("verify_simple: wrong length %d", length); + return -1; + } + if (length > local->recv_buffer_size) + break; + + int crc = crc32((unsigned char*)recv_buffer, length); + if (crc != -1) { + free(out_buffer); + local->recv_buffer_size = 0; + LOGE("verify_simple: wrong crc"); + return -1; + } + int data_size = length - recv_buffer[2] - 6; + memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size); + buffer += data_size; + memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length); + } + int len = buffer - out_buffer; + if (*capacity < len) { + *pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2); + plaindata = *pplaindata; + } + memmove(plaindata, out_buffer, len); + free(out_buffer); + return len; +} diff --git a/shadowsocksr-libev/src/server/verify.h b/shadowsocksr-libev/src/server/verify.h new file mode 100644 index 00000000..57c6ff99 --- /dev/null +++ b/shadowsocksr-libev/src/server/verify.h @@ -0,0 +1,19 @@ +/* + * verify.h - Define shadowsocksR server's buffers and callbacks + * + * Copyright (C) 2015 - 2016, Break Wa11 + */ + +#ifndef _VERIFY_H +#define _VERIFY_H + +obfs * verify_simple_new_obfs(); +void verify_simple_dispose(obfs *self); + +int verify_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int verify_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + +int verify_simple_server_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); +int verify_simple_server_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t* capacity); + +#endif // _VERIFY_H diff --git a/simple-obfs/Makefile b/simple-obfs/Makefile new file mode 100644 index 00000000..4dd49366 --- /dev/null +++ b/simple-obfs/Makefile @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Copyright (C) 2017-2019 Jian Chang +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=simple-obfs +PKG_VERSION:=0.0.11 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/simple-obfs/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=b5f1de228bbc3fcb7b2e1160c4736e9eb47978bd92b7bb3f0948f6a06bc979f0 + +PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Jian Chang + +PKG_BUILD_DEPENDS:=libev +PKG_FIXUP:=autoreconf +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/simple-obfs/template + SECTION:=net + CATEGORY:=Network + TITLE:=A simple obfuscating tool + URL:=https://github.com/kenzok8/simple-obfs + DEPENDS:=+libpthread +libev +endef + +define Package/simple-obfs-client + $(call Package/simple-obfs/template) + TITLE+= (client) + PROVIDES:=simple-obfs +endef + +define Package/simple-obfs-server + $(call Package/simple-obfs/template) + TITLE+= (server) +endef + +define Package/simple-obfs/description + Simple-obfs is a simple obfusacting tool, designed as plugin server of shadowsocks. +endef + +Package/simple-obfs-client/description = $(Package/simple-obfs/description) +Package/simple-obfs-server/description = $(Package/simple-obfs/description) + +CONFIGURE_ARGS += \ + --disable-ssp \ + --disable-documentation \ + --disable-assert + +define Package/simple-obfs-client/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/obfs-local $(1)/usr/bin/ +endef + +define Package/simple-obfs-server/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/obfs-server $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,simple-obfs-client)) +$(eval $(call BuildPackage,simple-obfs-server)) diff --git a/simple-obfs/README-maintenance.md b/simple-obfs/README-maintenance.md new file mode 100644 index 00000000..4da4d1d8 --- /dev/null +++ b/simple-obfs/README-maintenance.md @@ -0,0 +1,57 @@ +# simple-obfs 维护说明(维护模å¼ï¼‰ + +## 当å‰å®šä½ + +simple-obfs å·²é•¿æœŸåœæ›´ã€‚当å‰ä»“库策略是: + +- 以 **兼容性维护** 为主(ä¿è¯æ–°å·¥å…·é“¾å¯ç¼–译) +- ä¸åšå¤§è§„模功能迭代 +- 优先ä¿è¯æ‰“包å¯å¤çŽ°ã€æž„建稳定 + +## 关键设计 + +### 1) ç‰ˆæœ¬æ¥æº + +- 上游基础:`simple-obfs v0.0.7` +- 本仓库å‘布:`v0.0.9`ï¼ˆä»…åšæž„建å¯å¤çŽ°å¢žå¼ºï¼‰ + +### 2) libcork å¤„ç† + +历å²é—®é¢˜ï¼š`v0.0.7` çš„ `libcork` 是 submodule gitlink,tarball ä¸å«å­æ¨¡å—内容,导致构建中 autoreconf/Makefile 链路失败。 + +当剿–¹æ¡ˆï¼š + +- 在 `kenzok8/simple-obfs v0.0.9` 中直接 **vendor libcork æºç ** +- 打包阶段ä¸å†åœ¨çº¿ `git clone` libcork +- OpenWrt 包仅使用固定 tarball + hash + +收益: + +- 构建å¯å¤çް +- å‡å°‘ CI 网络ä¾èµ– +- é™ä½Žâ€œå¶å‘å¤±è´¥â€æ¦‚率 + +## 打包规范 + +`Makefile` 关键字段: + +- `PKG_VERSION:=0.0.9` +- `PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/simple-obfs/tar.gz/v$(PKG_VERSION)?` +- `PKG_HASH:=f9c05de42608691dad77c707504ad855191cd26ccd7095a0b3d4be939055111e` +- `PKG_FIXUP:=autoreconf` + +## 排错è¦ç‚¹ + +1. 先看 `logs/package/feeds/packages_ci/simple-obfs/compile.txt` +2. 常è§å¤±è´¥å…³é”®è¯ï¼š + - `No targets specified and no makefile found` + - `required file 'libcork/Makefile.in' not found` +3. 优先确认: + - 版本和 hash 是å¦ä¸€è‡´ + - 是å¦è¯¯å›žé€€åˆ°æ—§ç‰ˆï¼ˆv0.0.7) + +## 未æ¥è·¯çº¿ï¼ˆå»ºè®®ï¼‰ + +- simple-obfs ä¿æŒå…¼å®¹åŒ…å®šä½ +- 新能力优先放到更活跃的替代方案 +- è‹¥è¦ç»§ç»­ç»´æŠ¤ï¼Œä»…åšæœ€å°å…¼å®¹è¡¥ä¸ï¼ˆå·¥å…·é“¾/警告) diff --git a/sing-box/Makefile b/sing-box/Makefile new file mode 100644 index 00000000..e2717f60 --- /dev/null +++ b/sing-box/Makefile @@ -0,0 +1,170 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022-2023 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sing-box +PKG_VERSION:=1.13.12 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=08f3f7295130b76a60c1cb6565b89da6c4ce98d7bdea8852973a5d2e3c6de3b7 + +PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_CONFIG_DEPENDS:= \ + CONFIG_SING_BOX_TINY_BUILD_ACME \ + CONFIG_SING_BOX_TINY_BUILD_CLASH_API \ + CONFIG_SING_BOX_TINY_BUILD_DHCP \ + CONFIG_SING_BOX_TINY_BUILD_EMBEDDED_TOR \ + CONFIG_SING_BOX_TINY_BUILD_GRPC \ + CONFIG_SING_BOX_TINY_BUILD_GVISOR \ + CONFIG_SING_BOX_TINY_BUILD_QUIC \ + CONFIG_SING_BOX_TINY_BUILD_TAILSCALE \ + CONFIG_SING_BOX_TINY_BUILD_UTLS \ + CONFIG_SING_BOX_TINY_BUILD_V2RAY_API \ + CONFIG_SING_BOX_TINY_BUILD_WIREGUARD + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/sagernet/sing-box +GO_PKG_BUILD_PKG:=$(GO_PKG)/cmd/sing-box +GO_PKG_LDFLAGS_X:=$(GO_PKG)/constant.Version=$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/sing-box/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=The universal proxy platform + URL:=https://sing-box.sagernet.org/ + DEPENDS:=+ca-bundle +kmod-inet-diag + USERID:=sing-box=5566:sing-box=5566 +endef + +define Package/sing-box + $(call Package/sing-box/Default) + TITLE+= (full version) + DEPENDS+= +kmod-netlink-diag +kmod-tun + CONFLICTS:=sing-box-tiny + VARIANT:=full + DEFAULT_VARIANT:=1 +endef + +define Package/sing-box/description + Sing-box is a universal proxy platform which supports hysteria, SOCKS, Shadowsocks, + ShadowTLS, Tor, trojan, VLess, VMess, WireGuard and so on. +endef + +define Package/sing-box/config + depends on $(subst @,,$(GO_ARCH_DEPENDS)) +endef + +define Package/sing-box-tiny + $(call Package/sing-box/Default) + TITLE+= (tiny/custom version) + PROVIDES:=sing-box + VARIANT:=tiny +endef + +Package/sing-box-tiny/description:=$(Package/sing-box/description) + +define Package/sing-box-tiny/config + $(call Package/sing-box/config) + + if PACKAGE_sing-box-tiny + config SING_BOX_TINY_BUILD_ACME + bool "Build with ACME TLS certificate issuer support" + + config SING_BOX_TINY_BUILD_CLASH_API + bool "Build with Clash API support" + default y + + config SING_BOX_TINY_BUILD_DHCP + bool "Build with DHCP support" + + config SING_BOX_TINY_BUILD_EMBEDDED_TOR + bool "Build with embedded Tor support" + depends on BROKEN + + config SING_BOX_TINY_BUILD_GRPC + bool "Build with standard gPRC support" + help + Standard gRPC has good compatibility but poor performance. + + config SING_BOX_TINY_BUILD_GVISOR + bool "Build with gVisor support" + default y if aarch64||arm||i386||x86_64 + + config SING_BOX_TINY_BUILD_QUIC + bool "Build with QUIC support" + default y + help + Required by HTTP3 DNS transports, Naive inbound, + Hysteria inbound / outbound, and v2ray QUIC transport. + + config SING_BOX_TINY_BUILD_TAILSCALE + bool "Build with Tailscale support" + + config SING_BOX_TINY_BUILD_UTLS + bool "Build with uTLS support" + default y + + config SING_BOX_TINY_BUILD_V2RAY_API + bool "Build with V2Ray API support" + + config SING_BOX_TINY_BUILD_WIREGUARD + bool "Build with WireGuard support" + default y if aarch64||arm||i386||x86_64 + endif +endef + +ifeq ($(BUILD_VARIANT),full) + GO_PKG_TAGS:=with_acme,with_clash_api,with_dhcp,with_gvisor,with_quic,with_tailscale,with_utls,with_wireguard +else + GO_PKG_TAGS:=$(subst $(space),$(comma),$(strip \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_ACME),with_acme) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_CLASH_API),with_clash_api) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_DHCP),with_dhcp) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_EMBEDDED_TOR),with_embedded_tor) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_GRPC),with_grpc) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_GVISOR),with_gvisor) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_QUIC),with_quic) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_TAILSCALE),with_tailscale) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_UTLS),with_utls) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_V2RAY_API),with_v2ray_api) \ + $(if $(CONFIG_SING_BOX_TINY_BUILD_WIREGUARD),with_wireguard) \ + )) +endif + +define Package/sing-box/conffiles +/etc/config/sing-box +/etc/sing-box/ +endef + +Package/sing-box-tiny/conffiles=$(Package/sing-box/conffiles) + +define Package/sing-box/install + $(call GoPackage/Package/Install/Bin,$(1)) + + $(INSTALL_DIR) $(1)/etc/sing-box + $(INSTALL_DATA) $(PKG_BUILD_DIR)/release/config/config.json $(1)/etc/sing-box + + $(INSTALL_DIR) $(1)/etc/config/ + $(INSTALL_CONF) ./files/sing-box.conf $(1)/etc/config/sing-box + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/sing-box.init $(1)/etc/init.d/sing-box +endef + +Package/sing-box-tiny/install=$(Package/sing-box/install) + +$(eval $(call BuildPackage,sing-box)) +$(eval $(call BuildPackage,sing-box-tiny)) diff --git a/sing-box/files/sing-box.conf b/sing-box/files/sing-box.conf new file mode 100644 index 00000000..a6489b07 --- /dev/null +++ b/sing-box/files/sing-box.conf @@ -0,0 +1,10 @@ + +config sing-box 'main' + option enabled '0' + option user 'root' + option conffile '/etc/sing-box/config.json' + option workdir '/usr/share/sing-box' +# list ifaces 'wan' +# list ifaces 'wan6' + option log_stderr '1' + option log_stdout '0' diff --git a/sing-box/files/sing-box.init b/sing-box/files/sing-box.init new file mode 100644 index 00000000..ecc22b58 --- /dev/null +++ b/sing-box/files/sing-box.init @@ -0,0 +1,55 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 +START=99 + +script=$(readlink "$initscript") +NAME="$(basename ${script:-$initscript})" +PROG="/usr/bin/sing-box" + +start_service() { + config_load "$NAME" + + local enabled user group conffile workdir ifaces + local log_stdout log_stderr + config_get_bool enabled "main" "enabled" "0" + [ "$enabled" -eq "1" ] || return 0 + + config_get user "main" "user" "root" + config_get conffile "main" "conffile" + config_get ifaces "main" "ifaces" + config_get workdir "main" "workdir" "/usr/share/sing-box" + config_get_bool log_stdout "main" "log_stdout" "0" + config_get_bool log_stderr "main" "log_stderr" "1" + + mkdir -p "$workdir" + local group="$(id -ng $user)" + chown $user:$group "$workdir" + + procd_open_instance "$NAME.main" + procd_set_param command "$PROG" run -c "$conffile" -D "$workdir" + + # Use root user if you want to use the TUN mode. + procd_set_param user "$user" + procd_set_param file "$conffile" + [ -z "$ifaces" ] || procd_set_param netdev $ifaces + procd_set_param stdout "$log_stdout" + procd_set_param stderr "$log_stderr" + procd_set_param limits core="unlimited" + procd_set_param limits nofile="1000000 1000000" + procd_set_param respawn + + procd_close_instance +} + +service_triggers() { + local ifaces + config_load "$NAME" + config_get ifaces "main" "ifaces" + procd_open_trigger + for iface in $ifaces; do + procd_add_interface_trigger "interface.*.up" $iface /etc/init.d/$NAME restart + done + procd_close_trigger + procd_add_reload_trigger "$NAME" +} diff --git a/smartdns/Makefile b/smartdns/Makefile new file mode 100644 index 00000000..4bc3812c --- /dev/null +++ b/smartdns/Makefile @@ -0,0 +1,140 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Copyright (c) 2018-2023 Nick Peng (pymumu@gmail.com) + +include $(TOPDIR)/rules.mk + +PKG_NAME:=smartdns +PKG_VERSION:=48 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/pymumu/smartdns/tar.gz/Release$(PKG_VERSION)? +PKG_HASH:=84cd4ff3effe195a24fa5c10f2d72068d7debdbe2babce0fb3255b52e72d8c30 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-Release$(PKG_VERSION) + +PKG_MAINTAINER:=Nick Peng +PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE_FILES:=LICENSE + +PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_smartdns-ui +PKG_BUILD_DEPENDS:=PACKAGE_smartdns-ui:node/host PACKAGE_smartdns-ui:rust-bindgen/host +PKG_BUILD_PARALLEL:=1 + +RUST_PKG_FEATURES:=build-release +RUST_PKG_LOCKED:=0 + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/rust/rust-package.mk + +MAKE_PATH:=src +MAKE_VARS+= VER=$(PKG_VERSION) + +define Package/smartdns/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + TITLE:=smartdns + URL:=https://www.github.com/pymumu/smartdns/ +endef + +define Package/smartdns + $(call Package/smartdns/Default) + TITLE+= server + DEPENDS:=+i386:libatomic +libopenssl +endef + +define Package/smartdns/description +SmartDNS is a local DNS server which accepts DNS query requests from local network clients, +gets DNS query results from multiple upstream DNS servers concurrently, and returns the fastest IP to clients. +Unlike dnsmasq's all-servers, smartdns returns the fastest IP, and encrypt DNS queries with DoT or DoH. +endef + +define Package/smartdns-ui + $(call Package/smartdns/Default) + TITLE+= dashboard + DEPENDS:=+smartdns $(RUST_ARCH_DEPENDS) @!(TARGET_x86_geode||TARGET_x86_legacy) +endef + +define Package/smartdns-ui/description +A dashboard ui for smartdns server. +endef + +define Package/smartdns/conffiles +/etc/config/smartdns +/etc/smartdns/address.conf +/etc/smartdns/blacklist-ip.conf +/etc/smartdns/custom.conf +/etc/smartdns/domain-block.list +/etc/smartdns/domain-forwarding.list +endef + +define Download/smartdns-webui + PROTO:=git + URL:=https://github.com/pymumu/smartdns-webui.git + SOURCE_DATE:=2025-09-18 + SOURCE_VERSION:=c322303eac2ebee389f4a72a002163552e552f74 + MIRROR_HASH:=b239f3d994e05ad08356bf1be629cd84c2bfc6706997aafea881284cacc29545 + SUBDIR:=smartdns-webui-$$$$(subst -,.,$$$$(SOURCE_DATE))~$$$$(call version_abbrev,$$$$(SOURCE_VERSION)) + FILE:=$$(SUBDIR).tar.zst +endef + +define Build/Prepare + $(call Build/Prepare/Default) + +ifneq ($(CONFIG_PACKAGE_smartdns-ui),) + $(eval $(call Download,smartdns-webui)) + $(eval $(Download/smartdns-webui)) + mkdir -p $(PKG_BUILD_DIR)/smartdns-webui + zstdcat $(DL_DIR)/$(FILE) | tar -C $(PKG_BUILD_DIR)/smartdns-webui $(TAR_OPTIONS) --strip-components=1 +endif +endef + +define Build/Compile + $(call Build/Compile/Default) + +ifneq ($(CONFIG_PACKAGE_smartdns-ui),) + ( \ + pushd $(PKG_BUILD_DIR) ; \ + pushd smartdns-webui ; \ + npm install ; \ + npm run build ; \ + popd ; \ + pushd plugin/smartdns-ui ; \ + $(CARGO_PKG_CONFIG_VARS) \ + MAKEFLAGS="$(PKG_JOBS)" \ + TARGET_CFLAGS="$(filter-out -O%,$(TARGET_CFLAGS)) $(RUSTC_CFLAGS)" \ + BINDGEN_EXTRA_CLANG_ARGS="--sysroot=$(TOOLCHAIN_ROOT_DIR)" \ + cargo build -v --profile $(CARGO_PKG_PROFILE) \ + $(if $(strip $(RUST_PKG_FEATURES)),--features "$(strip $(RUST_PKG_FEATURES))") \ + $(if $(filter --jobserver%,$(PKG_JOBS)),,-j1) \ + $(CARGO_PKG_ARGS) ; \ + popd ; \ + popd ; \ + ) +endif +endef + +define Package/smartdns/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/smartdns $(1)/etc/smartdns/domain-set $(1)/etc/smartdns/conf.d/ + $(INSTALL_DIR) $(1)/etc/smartdns/ip-set $(1)/etc/smartdns/download + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/smartdns $(1)/usr/sbin/smartdns + $(INSTALL_BIN) $(PKG_BUILD_DIR)/package/openwrt/files/etc/init.d/smartdns $(1)/etc/init.d/smartdns + $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/address.conf $(1)/etc/smartdns/address.conf + $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/blacklist-ip.conf $(1)/etc/smartdns/blacklist-ip.conf + $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/custom.conf $(1)/etc/smartdns/custom.conf + $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/domain-block.list $(1)/etc/smartdns/domain-block.list + $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/domain-forwarding.list $(1)/etc/smartdns/domain-forwarding.list + $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/files/etc/config/smartdns $(1)/etc/config/smartdns +endef + +define Package/smartdns-ui/install + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/share/smartdns + $(CP) $(PKG_BUILD_DIR)/plugin/smartdns-ui/target/$(RUSTC_TARGET_ARCH)/$(CARGO_PKG_PROFILE)/libsmartdns_ui.so $(1)/usr/lib/smartdns_ui.so + $(CP) $(PKG_BUILD_DIR)/smartdns-webui/out $(1)/usr/share/smartdns/wwwroot +endef + +$(eval $(call BuildPackage,smartdns)) +$(eval $(call BuildPackage,smartdns-ui)) diff --git a/sqm-scripts-extra/Makefile b/sqm-scripts-extra/Makefile new file mode 100644 index 00000000..28e6ccb5 --- /dev/null +++ b/sqm-scripts-extra/Makefile @@ -0,0 +1,47 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sqm-scripts-extra +PKG_VERSION:=2016-06-08 +PKG_RELEASE:=1 +PKG_LICENSE:=GPLv2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE).tar.xz +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE) + +include $(INCLUDE_DIR)/package.mk + +define Package/sqm-scripts-extra + SECTION:=net + CATEGORY:=Base system + DEPENDS:=+sqm-scripts + TITLE:=SQM Scripts - additional experimental scripts for testing + PKGARCH:=all + MAINTAINER:=Kevin Darbyshire-Bryant , \ + Sebastian Moeller +endef + +define Package/sqm-scripts-extra/description + A set of experimental scripts for sqm-scripts QoS package. The contents of this package may + change as new qdiscs like 'cake' are developed and tested. +endef + +define Package/sqm-scripts-extra/download +endef + +define Build/Prepare +endef + +define Build/Compile +endef + +define Package/sqm-scripts-extra/install + $(INSTALL_DIR) $(1)/usr/lib/sqm + $(INSTALL_DATA) ./src/* $(1)/usr/lib/sqm/ +endef + +$(eval $(call BuildPackage,sqm-scripts-extra)) + diff --git a/sqm-scripts-extra/src/test_LAN_dual-isolate__piece_of_cake.qos b/sqm-scripts-extra/src/test_LAN_dual-isolate__piece_of_cake.qos new file mode 100644 index 00000000..4f1380d6 --- /dev/null +++ b/sqm-scripts-extra/src/test_LAN_dual-isolate__piece_of_cake.qos @@ -0,0 +1,102 @@ +#!/bin/sh +################################################################################ +# test_LAN_triple-isolate__piece_of_cake.qos (Cero3 Shaper) +# +# Abstract: +# This is a one band cake and ipv6 enabled shaping script for Ethernet +# gateways. This exists for the purpose of testing cake's different isolation +# options, specifically the non-directional triple-isolate feature that promises +# to finally tackle the bit-torrent hole in simple.qos. +# This specific version is supposed to be used on LAN interfaces: +# the script's ingress direction equals the internet/WAN upload direction +# the script's egress direction equals the internet/WAN download direction +# +# NOTE: Shaping on a LAN interface only affects machines connected via that +# LAN interface, so typically WIFI/WLAN traffic will not be shaped! +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + + +# this will only work with cake as qdisc... +QDISC=cake + + +# to keep this as simple as possible we ignore the *_CAKE_OPTS from defaults.sh +INGRESS_CAKE_OPTS="besteffort dual-srchost" +EGRESS_CAKE_OPTS="besteffort dual-dsthost" + + +egress() { + sqm_debug "egress" + $TC qdisc del dev $IFACE root 2>/dev/null + $TC qdisc add dev $IFACE root $( get_stab_string ) cake bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} +} + + +ingress() { + sqm_debug "ingress" + $TC qdisc del dev $IFACE handle ffff: ingress 2>/dev/null + $TC qdisc add dev $IFACE handle ffff: ingress + $TC qdisc del dev $DEV root 2>/dev/null + $TC qdisc add dev $DEV root $( get_stab_string ) cake bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_start() { + + #sm: flip upload and download bandwith so that the GUI values reflect directionality in regard to the ISP + #sm: NOTE this is ugly and should be performed in defaults.sh or functions.sh if at all + #sm: but for quick and dirty testing this should do + local ORIG_UPLINK=${UPLINK} + local ORIG_DOWNLINK=${DOWNLINK} + UPLINK=${ORIG_DOWNLINK} + DOWNLINK=${ORIG_UPLINK} + + + [ -n "$IFACE" ] || return 1 + do_modules + verify_qdisc $QDISC "cake" || return 1 + sqm_debug "Starting ${SCRIPT}" + + [ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} ) + + + if [ "${UPLINK}" -ne 0 ]; + then + egress + sqm_debug "egress shaping activated" + else + sqm_debug "egress shaping deactivated" + $TC qdisc del dev ${IFACE} root 2> /dev/null + fi + if [ "${DOWNLINK}" -ne 0 ]; + then + verify_qdisc ingress "ingress" || return 1 + ingress + sqm_debug "ingress shaping activated" + else + sqm_debug "ingress shaping deactivated" + $TC qdisc del dev ${DEV} root 2> /dev/null + $TC qdisc del dev ${IFACE} ingress 2> /dev/null + fi + return 0 +} diff --git a/sqm-scripts-extra/src/test_LAN_dual-isolate__piece_of_cake.qos.help b/sqm-scripts-extra/src/test_LAN_dual-isolate__piece_of_cake.qos.help new file mode 100644 index 00000000..616b5e4f --- /dev/null +++ b/sqm-scripts-extra/src/test_LAN_dual-isolate__piece_of_cake.qos.help @@ -0,0 +1,12 @@ +test_LAN_dual-isolate__piece_of_cake.qos (Cero3 Shaper) + +Abstract: +This is a one band cake and ipv6 enabled shaping script for Ethernet gateways. +This exists for the purpose of testing cake's different isolation options, +specifically the non-directional dual-[src|dst]host feature that promises to finally +tackle the bit-torrent hole in simple.qos. +This specific version is supposed to be used on LAN interfaces: + the script's ingress direction equals the internet/WAN upload direction + the script's egress direction equals the internet/WAN download direction +NOTE: Shaping on a LAN interface only affects machines connected via that +LAN interface, so typically WIFI/WLAN traffic will not be shaped! diff --git a/sqm-scripts-extra/src/test_LAN_triple-isolate__piece_of_cake.qos b/sqm-scripts-extra/src/test_LAN_triple-isolate__piece_of_cake.qos new file mode 100644 index 00000000..761b27de --- /dev/null +++ b/sqm-scripts-extra/src/test_LAN_triple-isolate__piece_of_cake.qos @@ -0,0 +1,102 @@ +#!/bin/sh +################################################################################ +# test_LAN_triple-isolate__piece_of_cake.qos (Cero3 Shaper) +# +# Abstract: +# This is a one band cake and ipv6 enabled shaping script for Ethernet +# gateways. This exists for the purpose of testing cake's different isolation +# options, specifically the non-directional triple-isolate feature that promises +# to finally tackle the bit-torrent hole in simple.qos. +# This specific version is supposed to be used on LAN interfaces: +# the script's ingress direction equals the internet/WAN upload direction +# the script's egress direction equals the internet/WAN download direction +# +# NOTE: Shaping on a LAN interface only affects machines connected via that +# LAN interface, so typically WIFI/WLAN traffic will not be shaped! +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + + +# this will only work with cake as qdisc... +QDISC=cake + + +# to keep this as simple as possible we ignore the *_CAKE_OPTS from defaults.sh +INGRESS_CAKE_OPTS="besteffort triple-isolate" +EGRESS_CAKE_OPTS="besteffort triple-isolate" + + +egress() { + sqm_debug "egress" + $TC qdisc del dev $IFACE root 2>/dev/null + $TC qdisc add dev $IFACE root $( get_stab_string ) cake bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} +} + + +ingress() { + sqm_debug "ingress" + $TC qdisc del dev $IFACE handle ffff: ingress 2>/dev/null + $TC qdisc add dev $IFACE handle ffff: ingress + $TC qdisc del dev $DEV root 2>/dev/null + $TC qdisc add dev $DEV root $( get_stab_string ) cake bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_start() { + + #sm: flip upload and download bandwith so that the GUI values reflect directionality in regard to the ISP + #sm: NOTE this is ugly and should be performed in defaults.sh or functions.sh if at all + #sm: but for quick and dirty testing this should do + local ORIG_UPLINK=${UPLINK} + local ORIG_DOWNLINK=${DOWNLINK} + UPLINK=${ORIG_DOWNLINK} + DOWNLINK=${ORIG_UPLINK} + + + [ -n "$IFACE" ] || return 1 + do_modules + verify_qdisc $QDISC "cake" || return 1 + sqm_debug "Starting ${SCRIPT}" + + [ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} ) + + + if [ "${UPLINK}" -ne 0 ]; + then + egress + sqm_debug "egress shaping activated" + else + sqm_debug "egress shaping deactivated" + $TC qdisc del dev ${IFACE} root 2> /dev/null + fi + if [ "${DOWNLINK}" -ne 0 ]; + then + verify_qdisc ingress "ingress" || return 1 + ingress + sqm_debug "ingress shaping activated" + else + sqm_debug "ingress shaping deactivated" + $TC qdisc del dev ${DEV} root 2> /dev/null + $TC qdisc del dev ${IFACE} ingress 2> /dev/null + fi + return 0 +} diff --git a/sqm-scripts-extra/src/test_LAN_triple-isolate__piece_of_cake.qos.help b/sqm-scripts-extra/src/test_LAN_triple-isolate__piece_of_cake.qos.help new file mode 100644 index 00000000..a3501dc1 --- /dev/null +++ b/sqm-scripts-extra/src/test_LAN_triple-isolate__piece_of_cake.qos.help @@ -0,0 +1,12 @@ +test_LAN_triple-isolate__piece_of_cake.qos (Cero3 Shaper) + +Abstract: +This is a one band cake and ipv6 enabled shaping script for Ethernet gateways. +This exists for the purpose of testing cake's different isolation options, +specifically the non-directional triple-isolate feature that promises to finally +tackle the bit-torrent hole in simple.qos. +This specific version is supposed to be used on LAN interfaces: + the script's ingress direction equals the internet/WAN upload direction + the script's egress direction equals the internet/WAN download direction +NOTE: Shaping on a LAN interface only affects machines connected via that +LAN interface, so typically WIFI/WLAN traffic will not be shaped! diff --git a/sqm-scripts-extra/src/test_WAN_dual-isolate__piece_of_cake.qos b/sqm-scripts-extra/src/test_WAN_dual-isolate__piece_of_cake.qos new file mode 100644 index 00000000..87eaebff --- /dev/null +++ b/sqm-scripts-extra/src/test_WAN_dual-isolate__piece_of_cake.qos @@ -0,0 +1,89 @@ +#!/bin/sh +################################################################################ +# test_WAN_dual-isolate__piece_of_cake.qos (Cero3 Shaper) +# +# Abstract: +# This is a one band cake and ipv6 enabled shaping script for Ethernet +# gateways. This exists for the purpose of testing cake's different isolation +# options, specifically the directional dual-[src|dst]host feature that promises +# to finally tackle the bit-torrent hole in simple.qos. +# This specific version is supposed to be used on WAN interfaces: +# the script's ingress direction equals the internet/WAN download direction +# the script's egress direction equals the internet/WAN upload direction +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + + +# this will only work with cake as qdisc... +QDISC=cake + + +# to keep this as simple as possible we ignore the *_CAKE_OPTS from defaults.sh +INGRESS_CAKE_OPTS="besteffort dual-dsthost" +EGRESS_CAKE_OPTS="besteffort dual-srchost" + + +egress() { + sqm_debug "egress" + $TC qdisc del dev $IFACE root 2>/dev/null + $TC qdisc add dev $IFACE root $( get_stab_string ) cake bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} +} + + +ingress() { + sqm_debug "ingress" + $TC qdisc del dev $IFACE handle ffff: ingress 2>/dev/null + $TC qdisc add dev $IFACE handle ffff: ingress + $TC qdisc del dev $DEV root 2>/dev/null + $TC qdisc add dev $DEV root $( get_stab_string ) cake bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_start() { + [ -n "$IFACE" ] || return 1 + do_modules + verify_qdisc $QDISC "cake" || return 1 + sqm_debug "Starting ${SCRIPT}" + + [ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} ) + + + if [ "${UPLINK}" -ne 0 ]; + then + egress + sqm_debug "egress shaping activated" + else + sqm_debug "egress shaping deactivated" + $TC qdisc del dev ${IFACE} root 2> /dev/null + fi + if [ "${DOWNLINK}" -ne 0 ]; + then + verify_qdisc ingress "ingress" || return 1 + ingress + sqm_debug "ingress shaping activated" + else + sqm_debug "ingress shaping deactivated" + $TC qdisc del dev ${DEV} root 2> /dev/null + $TC qdisc del dev ${IFACE} ingress 2> /dev/null + fi + return 0 +} diff --git a/sqm-scripts-extra/src/test_WAN_dual-isolate__piece_of_cake.qos.help b/sqm-scripts-extra/src/test_WAN_dual-isolate__piece_of_cake.qos.help new file mode 100644 index 00000000..c239917c --- /dev/null +++ b/sqm-scripts-extra/src/test_WAN_dual-isolate__piece_of_cake.qos.help @@ -0,0 +1,10 @@ +test_WAN_dual-isolate__piece_of_cake.qos (Cero3 Shaper) + +Abstract: +This is a one band cake and ipv6 enabled shaping script for Ethernet gateways. +This exists for the purpose of testing cake's different isolation options, +specifically the directional dual-[src|dst]host feature that promises to finally +tackle the bit-torrent hole in simple.qos. +This specific version is supposed to be used on WAN interfaces: + the script's ingress direction equals the internet/WAN download direction + the script's egress direction equals the internet/WAN upload direction diff --git a/sqm-scripts-extra/src/test_WAN_triple-isolate__piece_of_cake.qos b/sqm-scripts-extra/src/test_WAN_triple-isolate__piece_of_cake.qos new file mode 100644 index 00000000..5f0d7d7e --- /dev/null +++ b/sqm-scripts-extra/src/test_WAN_triple-isolate__piece_of_cake.qos @@ -0,0 +1,89 @@ +#!/bin/sh +################################################################################ +# test_WAN_triple-isolate__piece_of_cake.qos (Cero3 Shaper) +# +# Abstract: +# This is a one band cake and ipv6 enabled shaping script for Ethernet +# gateways. This exists for the purpose of testing cake's different isolation +# options, specifically the non-directional triple-isolate feature that promises +# to finally tackle the bit-torrent hole in simple.qos. +# This specific version is supposed to be used on WAN interfaces: +# the script's ingress direction equals the internet/WAN download direction +# the script's egress direction equals the internet/WAN upload direction +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + + +# this will only work with cake as qdisc... +QDISC=cake + + +# to keep this as simple as possible we ignore the *_CAKE_OPTS from defaults.sh +INGRESS_CAKE_OPTS="besteffort triple-isolate" +EGRESS_CAKE_OPTS="besteffort triple-isolate" + + +egress() { + sqm_debug "egress" + $TC qdisc del dev $IFACE root 2>/dev/null + $TC qdisc add dev $IFACE root $( get_stab_string ) cake bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} +} + + +ingress() { + sqm_debug "ingress" + $TC qdisc del dev $IFACE handle ffff: ingress 2>/dev/null + $TC qdisc add dev $IFACE handle ffff: ingress + $TC qdisc del dev $DEV root 2>/dev/null + $TC qdisc add dev $DEV root $( get_stab_string ) cake bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_start() { + [ -n "$IFACE" ] || return 1 + do_modules + verify_qdisc $QDISC "cake" || return 1 + sqm_debug "Starting ${SCRIPT}" + + [ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} ) + + + if [ "${UPLINK}" -ne 0 ]; + then + egress + sqm_debug "egress shaping activated" + else + sqm_debug "egress shaping deactivated" + $TC qdisc del dev ${IFACE} root 2> /dev/null + fi + if [ "${DOWNLINK}" -ne 0 ]; + then + verify_qdisc ingress "ingress" || return 1 + ingress + sqm_debug "ingress shaping activated" + else + sqm_debug "ingress shaping deactivated" + $TC qdisc del dev ${DEV} root 2> /dev/null + $TC qdisc del dev ${IFACE} ingress 2> /dev/null + fi + return 0 +} diff --git a/sqm-scripts-extra/src/test_WAN_triple-isolate__piece_of_cake.qos.help b/sqm-scripts-extra/src/test_WAN_triple-isolate__piece_of_cake.qos.help new file mode 100644 index 00000000..72df5099 --- /dev/null +++ b/sqm-scripts-extra/src/test_WAN_triple-isolate__piece_of_cake.qos.help @@ -0,0 +1,10 @@ +test_WAN_triple-isolate__piece_of_cake.qos (Cero3 Shaper) + +Abstract: +This is a one band cake and ipv6 enabled shaping script for Ethernet gateways. +This exists for the purpose of testing cake's different isolation options, +specifically the non-directional triple-isolate feature that promises to finally +tackle the bit-torrent hole in simple.qos. +This specific version is supposed to be used on WAN interfaces: + the script's ingress direction equals the internet/WAN download direction + the script's egress direction equals the internet/WAN upload direction diff --git a/sqm-scripts-extra/src/test_triple_isolated_llt_cake.qos b/sqm-scripts-extra/src/test_triple_isolated_llt_cake.qos new file mode 100644 index 00000000..df17b393 --- /dev/null +++ b/sqm-scripts-extra/src/test_triple_isolated_llt_cake.qos @@ -0,0 +1,82 @@ +#!/bin/sh +################################################################################ +# test_triple_isolated_llt_cake.qos +# One bin cake shaper for ethernet gateways +# using cake qdisc with triple-isolate and diffserv-llt (Latency-Loss-Tradeoff) +# +################################################################################ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# Copyright (C) 2012-2016 +# Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller +# +################################################################################ + +. ${SQM_LIB_DIR}/defaults.sh + +################################################################################ + + +# this will only work with cake as qdisc... +QDISC=cake + + +# to keep this as simple as possible we ignore the *_CAKE_OPTS from defaults.sh +INGRESS_CAKE_OPTS="diffserv-llt triple-isolate" +EGRESS_CAKE_OPTS="diffserv-llt triple-isolate" + + +egress() { + sqm_debug "egress" + $TC qdisc del dev $IFACE root 2>/dev/null + $TC qdisc add dev $IFACE root $( get_stab_string ) cake bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS} +} + + +ingress() { + sqm_debug "ingress" + $TC qdisc del dev $IFACE handle ffff: ingress 2>/dev/null + $TC qdisc add dev $IFACE handle ffff: ingress + $TC qdisc del dev $DEV root 2>/dev/null + $TC qdisc add dev $DEV root $( get_stab_string ) cake bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS} + + $IP link set dev $DEV up + + # redirect all IP packets arriving in $IFACE to ifb0 + + $TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \ + match u32 0 0 flowid 1:1 action mirred egress redirect dev $DEV +} + +sqm_start() { + [ -n "$IFACE" ] || return 1 + do_modules + verify_qdisc $QDISC "cake" || return 1 + sqm_debug "Starting ${SCRIPT}" + + [ -z "$DEV" ] && DEV=$( get_ifb_for_if ${IFACE} ) + + + if [ "${UPLINK}" -ne 0 ]; + then + egress + sqm_debug "egress shaping activated" + else + sqm_debug "egress shaping deactivated" + $TC qdisc del dev ${IFACE} root 2> /dev/null + fi + if [ "${DOWNLINK}" -ne 0 ]; + then + verify_qdisc ingress "ingress" || return 1 + ingress + sqm_debug "ingress shaping activated" + else + sqm_debug "ingress shaping deactivated" + $TC qdisc del dev ${DEV} root 2> /dev/null + $TC qdisc del dev ${IFACE} ingress 2> /dev/null + fi + return 0 +} diff --git a/sqm-scripts-extra/src/test_triple_isolated_llt_cake.qos.help b/sqm-scripts-extra/src/test_triple_isolated_llt_cake.qos.help new file mode 100644 index 00000000..06ffdad7 --- /dev/null +++ b/sqm-scripts-extra/src/test_triple_isolated_llt_cake.qos.help @@ -0,0 +1,3 @@ +Cake qdisc with triple-isolate and diffserv-llt (Latency-Loss-Tradeoff) +options as the shaper and fq_codel as leaf qdisc. This script requires +that cake is selected as qdisc. diff --git a/ssocks/Makefile b/ssocks/Makefile new file mode 100644 index 00000000..f9b9b0fe --- /dev/null +++ b/ssocks/Makefile @@ -0,0 +1,77 @@ +# +# Copyright (C) 2017-2018 Jian Chang +# +# Copyright (C) 2021 ImmortalWrt +# +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ssocks +PKG_VERSION:=0.0.16 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/ssocks/tar.gz/$(PKG_VERSION)? +PKG_HASH:=ade7f3eaa5e8cc5951a3afbc4d68dfd2a6e2d49d65599708af5865c50c7b9809 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ssocks/template + SECTION:=net + CATEGORY:=Network + TITLE:=sSocks + URL:=https://github.com/kenzok8/ssocks + DEPENDS:=+libopenssl +endef + +define Package/ssocks + $(call Package/ssocks/template) + TITLE+= Relay +endef + +define Package/ssocksd + $(call Package/ssocks/template) + TITLE+= Server +endef + +define Package/ssocks/description/template + sSocks is a package which contains: a socks5 server implements RFC 1928 (SOCKS V5) and + RFC 1929 (Authentication for SOCKS V5), a reverse socks server and client, a netcat like tool + and a socks5 relay. +endef + +Package/ssocks/description = $(Package/ssocks/description/template) +Package/ssocksd/description = $(Package/ssocks/description/template) + +define Build/Install + true +endef + +define Package/ssocks/install/template + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(2) $(1)/usr/bin/ +endef + +define Package/ssocks/install + $(call Package/ssocks/install/template,$(1),ssocks) +endef + +define Package/ssocksd/install + $(call Package/ssocks/install/template,$(1),ssocksd) +endef + +$(eval $(call BuildPackage,ssocks)) +$(eval $(call BuildPackage,ssocksd)) + + diff --git a/tcping/Makefile b/tcping/Makefile new file mode 100644 index 00000000..5205bd97 --- /dev/null +++ b/tcping/Makefile @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tcping +PKG_VERSION:=0.4 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/tcping/tar.gz/$(PKG_VERSION)? +PKG_HASH:=6512779e5a6b466e2be7c4daf02b5aad89aaeed7898314a6614d46f804bc1b54 + +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILE:=license.txt + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/tcping + SECTION:=net + CATEGORY:=Network + TITLE:=tcping measures the latency of a tcp-connection (IPv4/IPv6 support) + URL:=https://github.com/kenzok8/tcping +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) CC="$(TARGET_CC)" CFLAGS="$(TARGET_CFLAGS) -Wall" LDFLAGS="$(TARGET_LDFLAGS)" +endef + +define Package/tcping/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/tcping $(1)/usr/sbin +endef + +$(eval $(call BuildPackage,tcping)) diff --git a/tests/test_shadowsocks_libev_workflow.py b/tests/test_shadowsocks_libev_workflow.py new file mode 100644 index 00000000..aaeeebc3 --- /dev/null +++ b/tests/test_shadowsocks_libev_workflow.py @@ -0,0 +1,66 @@ +from pathlib import Path +import unittest + + +ROOT = Path(__file__).resolve().parents[1] +WORKFLOW = ROOT / ".github" / "workflows" / "Auto update v2.yml" +MAKEFILE = ROOT / "shadowsocks-libev" / "Makefile" + + +class ShadowsocksLibevWorkflowTest(unittest.TestCase): + def test_hash_uses_openwrt_sdk_download_and_check(self): + workflow = WORKFLOW.read_text() + + self.assertIn("ss_libev_hash", workflow) + self.assertIn("openwrt/sdk:x86_64-24.10.4", workflow) + self.assertIn("./scripts/feeds update ss_libev_hash", workflow) + self.assertIn("./scripts/feeds install -p ss_libev_hash -f shadowsocks-libev", workflow) + self.assertIn("make package/feeds/ss_libev_hash/shadowsocks-libev/download", workflow) + self.assertIn("make package/feeds/ss_libev_hash/shadowsocks-libev/check", workflow) + self.assertIn("DOWNLOAD_MIRROR=0", workflow) + self.assertIn('sha256sum "$ARCHIVE_PATH"', workflow) + self.assertIn( + "PKG_MIRROR_HASH:=0000000000000000000000000000000000000000000000000000000000000000", + workflow, + ) + shadowsocks_job = workflow.split("job_auto_update_shadowsocks_libev:", 1)[1] + self.assertNotIn("git archive", shadowsocks_job) + self.assertNotIn("TAR_TIMESTAMP", shadowsocks_job) + self.assertNotIn("zstd -T0", shadowsocks_job) + + def test_same_version_still_recomputes_hash(self): + workflow = WORKFLOW.read_text() + + same_version_block = ( + 'if [ "$OLD_VER" = "$NEW_VER" ] && [ "$OLD_COMMIT" = "$NEW_COMMIT" ]; then\n' + ' echo "status=failure"' + ) + self.assertNotIn(same_version_block, workflow) + self.assertIn('echo "old_hash=$OLD_HASH" >> $GITHUB_OUTPUT', workflow) + + + def test_current_hash_matches_openwrt_check_log(self): + makefile = MAKEFILE.read_text() + + self.assertIn( + "PKG_MIRROR_HASH:=96d0b486a0c8dbb2acf2af56534f6c765565c127c3695c98b5157b24993a4839", + makefile, + ) + + def test_hash_artifacts_stay_outside_git_workspace(self): + workflow = WORKFLOW.read_text() + + self.assertIn('HASH_WORK_DIR="$RUNNER_TEMP/shadowsocks-libev-hash"', workflow) + self.assertIn('-v "$HASH_WORK_DIR:/hashwork"', workflow) + self.assertNotIn('"$WORK_DIR/shadowsocks-libev-hash.txt"', workflow) + self.assertNotIn('"$WORK_DIR/shadowsocks-libev_make_download.log"', workflow) + + def test_commit_only_when_shadowsocks_makefile_changed(self): + workflow = WORKFLOW.read_text().split("job_auto_update_shadowsocks_libev:", 1)[1] + + self.assertIn('git diff --quiet -- shadowsocks-libev/Makefile', workflow) + self.assertNotIn('if [ -n "$(git status --porcelain)" ]; then', workflow) + + +if __name__ == "__main__": + unittest.main() diff --git a/tor-fw-helper/Makefile b/tor-fw-helper/Makefile new file mode 100644 index 00000000..f0a6d438 --- /dev/null +++ b/tor-fw-helper/Makefile @@ -0,0 +1,78 @@ +# +# Copyright (C) 2018 Jeffery To +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tor-fw-helper +PKG_VERSION:=0.3 +PKG_RELEASE:=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://git.torproject.org/tor-fw-helper.git +PKG_SOURCE_VERSION:=481599ee37dd3135c9e17d1df4810f36b4de4e3d +PKG_SOURCE_DATE:=20150805 +PKG_MIRROR_HASH:=f22d1400bec6b62636bd59cb3a51befc9cddbacccb790a758694c589cb2bc032 + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Jeffery To + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=git.torproject.org/tor-fw-helper.git + +include $(INCLUDE_DIR)/package.mk +include ../../lang/golang/golang-package.mk + +define Package/tor-fw-helper/Default + TITLE:=Firewall helper for tor + URL:=https://gitweb.torproject.org/tor-fw-helper.git/ + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Package/tor-fw-helper +$(call Package/tor-fw-helper/Default) + SECTION:=net + CATEGORY:=Network +endef + +define Package/golang-torproject-tor-fw-helper-dev +$(call Package/tor-fw-helper/Default) +$(call GoPackage/GoSubMenu) + TITLE+= (source files) + PKGARCH:=all +endef + +define Package/tor-fw-helper/Default/description +tor-fw-helper is a helper to automatically configuring port forwarding +for tor, using UPnP or NAT-PMP NAT traversal. + +This is a tor-fw-helper rewrite in Go that functions as a drop in +replacement for the original C code. +endef + +define Package/tor-fw-helper/description +$(call Package/tor-fw-helper/Default/description) + +This package contains the main helper program. +endef + +define Package/golang-torproject-tor-fw-helper-dev/description +$(call Package/tor-fw-helper/Default/description) + +This package provides the source files for the helper program. +endef + +GO_PKG_BUILD_VARS += GO111MODULE=auto + +$(eval $(call GoBinPackage,tor-fw-helper)) +$(eval $(call BuildPackage,tor-fw-helper)) + +$(eval $(call GoSrcPackage,golang-torproject-tor-fw-helper-dev)) +$(eval $(call BuildPackage,golang-torproject-tor-fw-helper-dev)) diff --git a/trojan-go/Makefile b/trojan-go/Makefile new file mode 100644 index 00000000..6539cc9b --- /dev/null +++ b/trojan-go/Makefile @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=trojan-go +PKG_VERSION:=0.10.13 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/trojan-go/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=40296268e473fea8538464e4e55d1daaa6735ac396a9c02d17d988032dd79d99 + +PKG_LICENSE:=GPL-3.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/p4gefau1t/trojan-go +GO_PKG_BUILD_PKG:=$(GO_PKG) +GO_PKG_LDFLAGS_X:= \ + $(GO_PKG)/constant.Version=$(PKG_VERSION) \ + $(GO_PKG)/constant.Commit=v$(PKG_VERSION) +GO_PKG_TAGS:=full + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/trojan-go + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=A Trojan proxy written in Go + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle + URL:=https://github.com/kenzok8/trojan-go +endef + +define Package/trojan-go/description + Trojan features multiple protocols over TLS to avoid both + active/passive detections and ISP QoS limitations. +endef + +$(eval $(call GoBinPackage,trojan-go)) +$(eval $(call BuildPackage,trojan-go)) diff --git a/trojan-plus/Makefile b/trojan-plus/Makefile new file mode 100644 index 00000000..f5069a71 --- /dev/null +++ b/trojan-plus/Makefile @@ -0,0 +1,61 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=trojan-plus +PKG_VERSION:=10.0.3 +PKG_RELEASE:=3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/trojan-plus/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=0240f5b4d2a37074ab33b414a8b60d5f5b4778bd226586a2bd9a5c87a12896ed + +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=openssl + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Trojan-Plus-Group + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +TARGET_CXXFLAGS += -Wall -Wextra +TARGET_CXXFLAGS += $(FPIC) + +# LTO +TARGET_CXXFLAGS += -flto +TARGET_LDFLAGS += -flto + +# CXX standard +TARGET_CXXFLAGS += -std=c++11 +TARGET_CXXFLAGS := $(filter-out -O%,$(TARGET_CXXFLAGS)) -O3 +TARGET_CXXFLAGS += -ffunction-sections -fdata-sections +TARGET_LDFLAGS += -Wl,--gc-sections + +CMAKE_OPTIONS += \ + -DENABLE_MYSQL=OFF \ + -DENABLE_NAT=ON \ + -DENABLE_REUSE_PORT=ON \ + -DENABLE_SSL_KEYLOG=ON \ + -DENABLE_TLS13_CIPHERSUITES=ON \ + -DFORCE_TCP_FASTOPEN=OFF \ + -DSYSTEMD_SERVICE=OFF \ + -DOPENSSL_USE_STATIC_LIBS=FALSE \ + -DBoost_DEBUG=ON \ + -DBoost_NO_BOOST_CMAKE=ON + +define Package/trojan-plus + SECTION:=net + CATEGORY:=Network + TITLE:=An unidentifiable mechanism that helps you bypass GFW. It's compatible with original trojan with experimental features. + URL:=https://github.com/kenzok8/trojan-plus + DEPENDS:= \ + +libpthread +libstdcpp +libopenssl \ + +boost +boost-system +boost-program_options +endef + +define Package/trojan-plus/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/trojan $(1)/usr/sbin/trojan-plus +endef + +$(eval $(call BuildPackage,trojan-plus)) diff --git a/trojan/Makefile b/trojan/Makefile new file mode 100644 index 00000000..de4db3a8 --- /dev/null +++ b/trojan/Makefile @@ -0,0 +1,68 @@ +# +# Copyright (C) 2018-2019 wongsyrone +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=trojan +PKG_VERSION:=1.17.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=Trojan-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/trojan/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=e6772fed325301760e7150ddd483faa77af9046a2aeedbdb51278b4d6d9ae33f + +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=openssl + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=GreaterFire + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +TARGET_CXXFLAGS += -Wall -Wextra +TARGET_CXXFLAGS += $(FPIC) + +# LTO +TARGET_CXXFLAGS += -flto +TARGET_LDFLAGS += -flto + +# CXX standard +TARGET_CXXFLAGS += -std=c++11 +TARGET_CXXFLAGS := $(filter-out -O%,$(TARGET_CXXFLAGS)) -O3 +TARGET_CXXFLAGS += -ffunction-sections -fdata-sections +TARGET_LDFLAGS += -Wl,--gc-sections + +CMAKE_OPTIONS += \ + -DENABLE_MYSQL=OFF \ + -DENABLE_NAT=ON \ + -DENABLE_REUSE_PORT=ON \ + -DENABLE_SSL_KEYLOG=ON \ + -DENABLE_TLS13_CIPHERSUITES=ON \ + -DFORCE_TCP_FASTOPEN=OFF \ + -DSYSTEMD_SERVICE=OFF \ + -DOPENSSL_USE_STATIC_LIBS=FALSE \ + -DBoost_DEBUG=ON \ + -DBoost_NO_BOOST_CMAKE=ON + +define Package/trojan + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=An unidentifiable mechanism that helps you bypass GFW + URL:=https://github.com/kenzok8/trojan + DEPENDS:= \ + +libpthread +libstdcpp +libopenssl \ + +boost +boost-system +boost-program_options +boost-date_time +endef + +define Package/trojan/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/trojan $(1)/usr/sbin/trojan +endef + +$(eval $(call BuildPackage,trojan)) diff --git a/tuic-client/Makefile b/tuic-client/Makefile new file mode 100644 index 00000000..b3192c44 --- /dev/null +++ b/tuic-client/Makefile @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2025 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tuic-client +PKG_VERSION:=1.8.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/Itsusinn/tuic/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=1d0a9a538bc1b4fec42d499f417c2ef1c3f4092be00ad3731cd9d0963e111df2 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +PKG_MAINTAINER:=Tianling Shen +PKG_LICENSE:=GPL-3.0-only +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk +PKG_BUILD_DEPENDS:=rust/host +PKG_BUILD_PARALLEL:=1 + +include $(TOPDIR)/feeds/packages/lang/rust/rust-package.mk + +TAR_OPTIONS += --strip-components 1 +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) + +define Package/tuic-client + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=TUIC proxy protocol client + URL:=https://github.com/Itsusinn/tuic + DEPENDS:=@(aarch64||arm||mips||mipsel||x86_64||i386||i686||riscv64||loongarch64) +endef + +define Package/tuic-client/description + Delicately-TUICed 0-RTT proxy protocol client. +endef + +define Select/Features +$(strip \ + $(if $(findstring x86_64,$(RUSTC_TARGET_ARCH)),--features jemallocator) \ + $(if $(findstring aarch64,$(RUSTC_TARGET_ARCH)),--features jemallocator) \ + $(if $(or \ + $(findstring arm,$(RUSTC_TARGET_ARCH)), \ + $(findstring mips,$(RUSTC_TARGET_ARCH)), \ + $(findstring mipsel,$(RUSTC_TARGET_ARCH)), \ + $(findstring i686,$(RUSTC_TARGET_ARCH)), \ + $(findstring i386,$(RUSTC_TARGET_ARCH)), \ + $(findstring riscv64,$(RUSTC_TARGET_ARCH)), \ + $(findstring loongarch64,$(RUSTC_TARGET_ARCH)) \ + ),--no-default-features --features ring) \ +) +endef + +define Build/Compile + ( \ + pushd $(PKG_BUILD_DIR) ; \ + $(CARGO_PKG_CONFIG_VARS) \ + cargo build --release \ + -p tuic-client \ + --target $(RUSTC_TARGET_ARCH) \ + $(call Select/Features) ; \ + popd ; \ + ) +endef + +define Package/tuic-client/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/target/$(RUSTC_TARGET_ARCH)/release/tuic-client $(1)/usr/bin/ +endef + +$(eval $(call RustBinPackage,tuic-client)) +$(eval $(call BuildPackage,tuic-client)) diff --git a/ucl/Makefile b/ucl/Makefile new file mode 100644 index 00000000..762d1ab4 --- /dev/null +++ b/ucl/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2019-2020 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucl +PKG_VERSION:=1.04.1 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Xingwang Liao +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=COPYING + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/ucl/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=634b03734d93160d2da0e617d9d450e95603ac6205d887dc2b7f75680bbfadaa + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +HOST_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk + +HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST) + +HOST_CFLAGS += -std=gnu89 +TARGET_CFLAGS += -std=gnu89 + +CONFIGURE_ARGS += \ + --enable-static \ + --enable-shared \ + --disable-asm + +define Package/libucl + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Portable lossless data compression library + URL:=https://github.com/kenzok8/ucl +endef + +define Package/libucl/description +UCL is a portable lossless data compression library written in ANSI C. UCL +implements a number of compression algorithms that achieve an excellent +compression ratio while allowing *very* fast decompression. Decompression +requires no additional memory. +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/ucl + $(CP) $(PKG_INSTALL_DIR)/usr/include/ucl/ucl{,conf}.h $(1)/usr/include/ucl/ + + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libucl.{a,so*} $(1)/usr/lib/ +endef + +define Package/libucl/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libucl.so.* $(1)/usr/lib/ +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,libucl)) diff --git a/upx-static/Makefile b/upx-static/Makefile new file mode 100755 index 00000000..6574e1c2 --- /dev/null +++ b/upx-static/Makefile @@ -0,0 +1,98 @@ + +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) kenzok8 + +include $(TOPDIR)/rules.mk + +PKG_NAME:=upx-static +PKG_VERSION:=5.1.1 +PKG_RELEASE:=1 +PKG_SOURCE_VERSION:=v5.1.1 + +# Map OpenWrt $(ARCH) to UPX pre-built binary arch name. +# NOTE: OpenWrt uses "aarch64", UPX tarball uses "arm64". +UPX_ARCH:=$(ARCH) +ifeq ($(findstring x86_64,$(ARCH)),x86_64) + UPX_ARCH:=amd64 +else ifeq ($(findstring i386,$(ARCH)),i386) + UPX_ARCH:=i386 +else ifeq ($(findstring aarch64,$(ARCH)),aarch64) + UPX_ARCH:=arm64 +else ifeq ($(findstring arm,$(ARCH)),arm) + UPX_ARCH:=arm +else ifeq ($(findstring armeb,$(ARCH)),armeb) + UPX_ARCH:=armeb +else ifeq ($(findstring mipsel,$(ARCH)),mipsel) + UPX_ARCH:=mipsel +else ifeq ($(findstring mips,$(ARCH)),mips) + UPX_ARCH:=mips +else ifeq ($(findstring powerpc,$(ARCH)),powerpc) + UPX_ARCH:=powerpc +else ifeq ($(findstring powerpc64,$(ARCH)),powerpc64) + UPX_ARCH:=powerpc64le +else ifeq ($(findstring riscv64,$(ARCH)),riscv64) + UPX_ARCH:=riscv64 +endif + +PKG_SOURCE:=upx-$(PKG_VERSION)-$(UPX_ARCH)_linux.tar.xz +PKG_SOURCE_URL:=https://github.com/upx/upx/releases/download/$(PKG_SOURCE_VERSION) + +# AUTO-GENERATED HASHES BEGIN +ifeq ($(UPX_ARCH),amd64) + PKG_HASH:=1ff660454227861e00772f743f66b900072116b9dc24f6ee28b97cce88a7828a +else ifeq ($(UPX_ARCH),i386) + PKG_HASH:=54242a7f1fa05ecc254c83fac89437987af19492f0b27a3def1cdcf4746f8053 +else ifeq ($(UPX_ARCH),arm64) + PKG_HASH:=a307c2c821eeab47607ba5c232408b22ab884cca13884682508b98f7308b8443 +else ifeq ($(UPX_ARCH),arm) + PKG_HASH:=0d0ac4c2fd367ccf595522487db118a7ef07e31146ff3cebefe4b34381a00a78 +else ifeq ($(UPX_ARCH),armeb) + PKG_HASH:=46bcea55c16eb420df8567025b75bda6516ef1cb4b0b4e232a4a28f55f0add6c +else ifeq ($(UPX_ARCH),mipsel) + PKG_HASH:=6e2c901c927be893141fa680ff4b86c3ac48d8390e6505db2fcf3a7ccd0c599b +else ifeq ($(UPX_ARCH),mips) + PKG_HASH:=15d3949dd620a86ebff7622201c1b81b00677face68ab7d179b9e72b003759c9 +else ifeq ($(UPX_ARCH),powerpc) + PKG_HASH:=81bb6703ee02bd8b0664a8265fd607dccac606976c958d09333c4ed038aea2bf +else ifeq ($(UPX_ARCH),powerpc64le) + PKG_HASH:=d8789d959f0a2fdd07890ebb332173a9b076cb6db2cb1fb22a2699ffd9f884c6 +else ifeq ($(UPX_ARCH),riscv64) + PKG_HASH:=8dec678ddcafb61837ecd59810f6ad89dfd30edd84333441aff44e088d4b7898 +else + $(error Unsupported UPX_ARCH '$(UPX_ARCH)' for upx-static) +endif +# AUTO-GENERATED HASHES END + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SUBMENU:=Compression + SECTION:=utils + CATEGORY:=Utilities + TITLE:=UPX - The Ultimate Packer for eXecutables + URL:=https://upx.github.io +endef + +define Package/$(PKG_NAME)/description + UPX is a free, portable, extendable, high-performance executable + packer for several executable formats. This package installs the + statically-linked pre-built binary from the official upstream release. +endef + +define Build/Prepare + rm -rf $(PKG_BUILD_DIR) + mkdir -p $(PKG_BUILD_DIR) + tar -xJf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip-components=1 +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/upx $(1)/bin/upx +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/upx/Makefile b/upx/Makefile new file mode 100644 index 00000000..dd897a47 --- /dev/null +++ b/upx/Makefile @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=upx +PKG_VERSION:=5.1.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-src.tar.xz +PKG_SOURCE_URL:=https://github.com/upx/upx/releases/download/v$(PKG_VERSION) +PKG_HASH:=8eb914115b306fd9fd2110bd3d27ddb8ae7c5a03bb965f7d10f046a3a4ff9dfe + +PKG_LICENSE:=GPL-2.0-or-later +PKG_LICENSE_FILES:=COPYING LICENSE +PKG_MAINTAINER:=Tianling Shen + +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)-src +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-src +CMAKE_BINARY_SUBDIR:=openwrt-build + +PKG_BUILD_FLAGS:=no-mips16 + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/upx + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Compression + TITLE:=The Ultimate Packer for eXecutables + URL:=https://upx.github.io + DEPENDS:=+libstdcpp +endef + +CMAKE_OPTS:= \ + -DUPX_CONFIG_DISABLE_GITREV=ON \ + -DUPX_CONFIG_DISABLE_SELF_PACK_TEST=ON +CMAKE_HOST_OPTIONS+= $(CMAKE_OPTS) +CMAKE_OPTIONS+= $(CMAKE_OPTS) + +define Package/upx/description + UPX is an advanced executable file compressor. UPX will typically + reduce the file size of programs and DLLs by around 50%-70%, thus + reducing disk space, network load times, download times and + other distribution and storage costs. +endef + +define Package/upx/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/upx $(1)/usr/bin/ +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,upx)) diff --git a/uugamebooster/Makefile b/uugamebooster/Makefile new file mode 100644 index 00000000..4076942d --- /dev/null +++ b/uugamebooster/Makefile @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=uugamebooster +PKG_VERSION:=12.1.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(ARCH).tar.gz +PKG_SOURCE_URL:=https://uurouter.gdl.netease.com/uuplugin/openwrt-$(ARCH)/v$(PKG_VERSION)/uu.tar.gz? +ifeq ($(ARCH),aarch64) + PKG_HASH:=f140dc99af5a67367e63c811ba5b555c748dea32c3b11c6b5bde6afc25ac960c +else ifeq ($(ARCH),arm) + PKG_HASH:=d531ff8ccb8b14abbac2d46d8cf1697114c981b059b9fb88adc19322be1ec2af +else ifeq ($(ARCH),mipsel) + PKG_HASH:=c9003945872a106fd46207afb130a6741ee832bdc3273e2257f35a092cfd966a +else ifeq ($(ARCH),x86_64) + PKG_HASH:=1dd419ac166b124f8d83e4075a65b6547ba589f976894065ce551a66313a6e84 +endif + +PKG_LICENSE:=Proprietary + +include $(INCLUDE_DIR)/package.mk + +STRIP:=true + +TAR_CMD=$(HOST_TAR) -C $(1)/ $(TAR_OPTIONS) + +define Package/uugamebooster + SECTION:=net + CATEGORY:=Network + DEPENDS:=@(aarch64||arm||mipsel||x86_64) +kmod-tun + TITLE:=NetEase UU Game Booster + URL:=https://uu.163.com +endef + +define Package/uugamebooster/description + NetEase's UU Game Booster Accelerates Triple-A Gameplay and Market. +endef + +define Build/Compile +endef + +define Package/uugamebooster/conffiles +/.uuplugin_uuid +/usr/share/uugamebooster/uu.conf +endef + +define Package/uugamebooster/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/uuplugin $(1)/usr/bin/uugamebooster + $(INSTALL_BIN) $(PKG_BUILD_DIR)/xtables-nft-multi $(1)/usr/bin/xtables-nft-multi + + $(INSTALL_DIR) $(1)/usr/share/uugamebooster + $(INSTALL_CONF) $(PKG_BUILD_DIR)/uu.conf $(1)/usr/share/uugamebooster/uu.conf + + $(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d + $(INSTALL_CONF) $(CURDIR)/files/uugamebooster.config $(1)/etc/config/uugamebooster + $(INSTALL_BIN) $(CURDIR)/files/uugamebooster.init $(1)/etc/init.d/uugamebooster +endef + +$(eval $(call BuildPackage,uugamebooster)) diff --git a/uugamebooster/files/uugamebooster.config b/uugamebooster/files/uugamebooster.config new file mode 100644 index 00000000..09016777 --- /dev/null +++ b/uugamebooster/files/uugamebooster.config @@ -0,0 +1,4 @@ + +config uugamebooster 'config' + option enabled '0' + diff --git a/uugamebooster/files/uugamebooster.init b/uugamebooster/files/uugamebooster.init new file mode 100755 index 00000000..ed517955 --- /dev/null +++ b/uugamebooster/files/uugamebooster.init @@ -0,0 +1,37 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 Tianling Shen + +USE_PROCD=1 +START=99 + +CONF="uugamebooster" +PROG="/usr/bin/uugamebooster" + +UU_CONF="/usr/share/uugamebooster/uu.conf" + +start_service() { + config_load "$CONF" + local enabled + config_get_bool enabled "config" "enabled" "0" + [ "$enabled" -eq "1" ] || return 1 + + procd_open_instance "$CONF" + + procd_set_param command "$PROG" "$UU_CONF" + + procd_set_param limits core="unlimited" + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_close_instance +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "$CONF" +} diff --git a/uugamebooster/update.sh b/uugamebooster/update.sh new file mode 100755 index 00000000..b668479b --- /dev/null +++ b/uugamebooster/update.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +set -x + +export CURDIR="$(cd "$(dirname $0)"; pwd)" + +VERSION="$(curl -fsSL "https://router.uu.163.com/api/plugin?type=openwrt-aarch64" | jq -r ".url" | awk -F '/' '{print $6}' | tr -d 'v')" || exit 1 +PKG_VERSION="$(awk -F "PKG_VERSION:=" '{print $2}' "$CURDIR/Makefile" | xargs)" +[ "$PKG_VERSION" != "$VERSION" ] || exit 0 + +for ARCH in "aarch64" "arm" "mipsel" "x86_64"; do + FILE_INFO="$(curl -fsSL "https://router.uu.163.com/api/plugin?type=openwrt-$ARCH")" + FILE_MD5="$(echo "$FILE_INFO" | jq -r ".md5")" + FILE_VER="$(echo "$FILE_INFO" | jq -r ".url" | awk -F '/' '{print $6}' | tr -d 'v')" + if [ "$FILE_VER" != "$VERSION" ]; then + echo -e "Version mismatch. Expected version: $VERSION, got $FILE_VER." + exit 1 + else + curl -fsSL "http://uurouter.gdl.netease.com/uuplugin/openwrt-$ARCH/v$VERSION/uu.tar.gz" -o "$CURDIR/uu-$ARCH.tar.gz" + ACTUAL_MD5="$(md5sum "$CURDIR/uu-$ARCH.tar.gz" | awk '{print $1}')" + if [ "$ACTUAL_MD5" != "$FILE_MD5" ]; then + echo -e "HASH mismatch. Expected md5: $FILE_MD5, got $ACTUAL_MD5." + else + FILE_HASH="$(sha256sum "$CURDIR/uu-$ARCH.tar.gz" | awk '{print $1}')" + HASH_LINE="$(($(sed -n -e "/(\$(ARCH),$ARCH)/=" "$CURDIR/Makefile") + 1))" + sed -i "${HASH_LINE}s/PKG_HASH:=.*/PKG_HASH:=$FILE_HASH/" "$CURDIR/Makefile" + fi + rm -f "$CURDIR/uu-$ARCH.tar.gz" + fi +done + +sed -i "s,PKG_VERSION:=.*,PKG_VERSION:=$VERSION,g" "$CURDIR/Makefile" diff --git a/v2ray-core/Makefile b/v2ray-core/Makefile new file mode 100644 index 00000000..489a891a --- /dev/null +++ b/v2ray-core/Makefile @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=v2ray-core +PKG_VERSION:=5.51.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/v2fly/v2ray-core/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=7316dd294af15b9c92ba7db09fb274aacec919d18e45a594305c8d8b020bcb50 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/v2fly/v2ray-core/v5 +GO_PKG_BUILD_PKG:=$(GO_PKG)/main +GO_PKG_LDFLAGS_X:= \ + $(GO_PKG).build=OpenWrt \ + $(GO_PKG).version=$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/v2ray/template + TITLE:=A platform for building proxies to bypass network restrictions + SECTION:=net + CATEGORY:=Network + URL:=https://www.v2fly.org +endef + +define Package/v2ray-core + $(call Package/v2ray/template) + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/v2ray-extra + $(call Package/v2ray/template) + TITLE+= (extra resources) + DEPENDS:=v2ray-core + PKGARCH:=all +endef + +define Package/v2ray/description + Project V is a set of network tools that help you to build your own computer network. + It secures your network connections and thus protects your privacy. +endef + +define Package/v2ray-core/description + $(call Package/v2ray/description) +endef + +define Package/v2ray-extra/description + $(call Package/v2ray/description) + + This includes extra resources for v2ray-core. +endef + +define Package/v2ray-core/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/main $(1)/usr/bin/v2ray +endef + +define Package/v2ray-extra/install + $(INSTALL_DIR) $(1)/usr/share/v2ray/ + $(CP) $(PKG_BUILD_DIR)/release/extra/* $(1)/usr/share/v2ray/ +endef + +$(eval $(call BuildPackage,v2ray-core)) +$(eval $(call BuildPackage,v2ray-extra)) diff --git a/v2ray-geodata/Makefile b/v2ray-geodata/Makefile new file mode 100644 index 00000000..622bf49c --- /dev/null +++ b/v2ray-geodata/Makefile @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021-2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=v2ray-geodata +PKG_RELEASE:=1 + +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +include $(INCLUDE_DIR)/package.mk + +GEOIP_VER:=202605120112 +GEOIP_FILE:=geoip.dat.$(GEOIP_VER) +define Download/geoip + URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/ + URL_FILE:=geoip.dat + FILE:=$(GEOIP_FILE) + HASH:=e9002979e0df72bce1c8751ff70725386594c551db684b7a232935b8b2bb8aa2 +endef + +GEOSITE_VER:=20260527110433 +GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) +define Download/geosite + URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ + URL_FILE:=dlc.dat + FILE:=$(GEOSITE_FILE) + HASH:=50a1f17d12f1d44495ddea7d32a8c5d852ccefe848cf375f5adff22346b68cef +endef + +GEOSITE_IRAN_VER:=202605250156 +GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER) +define Download/geosite-ir + URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/ + URL_FILE:=iran.dat + FILE:=$(GEOSITE_IRAN_FILE) + HASH:=2ae051203f836c859169a46c81b2ce177b608c2a95897c47db5e3cce446cdea9 +endef + +define Package/v2ray-geodata/template + SECTION:=net + CATEGORY:=Network + SUBMENU:=IP Addresses and Names + URL:=https://www.v2fly.org + PKGARCH:=all +endef + +define Package/v2ray-geoip + $(call Package/v2ray-geodata/template) + TITLE:=GeoIP List for V2Ray + PROVIDES:=@v2ray-geodata @xray-geodata @xray-geoip + VERSION:=$(GEOIP_VER)-r$(PKG_RELEASE) + LICENSE:=CC-BY-SA-4.0 +endef + +define Package/v2ray-geosite + $(call Package/v2ray-geodata/template) + TITLE:=Geosite List for V2Ray + PROVIDES:=@v2ray-geodata @xray-geodata @xray-geosite + VERSION:=$(GEOSITE_VER)-r$(PKG_RELEASE) + LICENSE:=MIT +endef + +define Package/v2ray-geosite-ir + $(call Package/v2ray-geodata/template) + TITLE:=Iran Geosite List for V2Ray + PROVIDES:=@xray-geosite-ir + VERSION:=$(GEOSITE_IRAN_VER)-r$(PKG_RELEASE) + LICENSE:=MIT +endef + +define Build/Prepare + $(call Build/Prepare/Default) +ifneq ($(CONFIG_PACKAGE_v2ray-geoip),) + $(call Download,geoip) +endif +ifneq ($(CONFIG_PACKAGE_v2ray-geosite),) + $(call Download,geosite) +endif +ifneq ($(CONFIG_PACKAGE_v2ray-geosite-ir),) + $(call Download,geosite-ir) +endif +endef + +define Build/Compile +endef + +define Package/v2ray-geoip/install + $(INSTALL_DIR) $(1)/usr/share/v2ray $(1)/usr/share/xray + $(INSTALL_DATA) $(DL_DIR)/$(GEOIP_FILE) $(1)/usr/share/v2ray/geoip.dat + $(LN) ../v2ray/geoip.dat $(1)/usr/share/xray/geoip.dat +endef + +define Package/v2ray-geosite/install + $(INSTALL_DIR) $(1)/usr/share/v2ray $(1)/usr/share/xray + $(INSTALL_DATA) $(DL_DIR)/$(GEOSITE_FILE) $(1)/usr/share/v2ray/geosite.dat + $(LN) ../v2ray/geosite.dat $(1)/usr/share/xray/geosite.dat +endef + +define Package/v2ray-geosite-ir/install + $(INSTALL_DIR) $(1)/usr/share/v2ray $(1)/usr/share/xray + $(INSTALL_DATA) $(DL_DIR)/$(GEOSITE_IRAN_FILE) $(1)/usr/share/v2ray/iran.dat + $(LN) ../v2ray/iran.dat $(1)/usr/share/xray/iran.dat +endef + +$(eval $(call BuildPackage,v2ray-geoip)) +$(eval $(call BuildPackage,v2ray-geosite)) +$(eval $(call BuildPackage,v2ray-geosite-ir)) diff --git a/v2ray-plugin/Makefile b/v2ray-plugin/Makefile new file mode 100644 index 00000000..c56df49e --- /dev/null +++ b/v2ray-plugin/Makefile @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2020 SharerMax +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=v2ray-plugin +PKG_VERSION:=5.49.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/teddysun/v2ray-plugin/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=7a634a79d9715a899d52366949e09443376715ec86f76cbcfc8b6fb3af0cef53 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=madeye + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/teddysun/v2ray-plugin +GO_PKG_LDFLAGS_X:=main.VERSION=v$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/v2ray-plugin + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=SIP003 plugin for shadowsocks, based on v2ray + URL:=https://github.com/teddysun/v2ray-plugin + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +$(eval $(call GoBinPackage,v2ray-plugin)) +$(eval $(call BuildPackage,v2ray-plugin)) diff --git a/v2raya/Makefile b/v2raya/Makefile new file mode 100644 index 00000000..162de65e --- /dev/null +++ b/v2raya/Makefile @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=v2rayA +PKG_VERSION:=2.2.7.5 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=d0daccace51572d730fb710f7df190beed47d51ec1091d2fba38719b9417b385 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service + +PKG_LICENSE:=AGPL-3.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/v2rayA/v2rayA +GO_PKG_LDFLAGS_X:= \ + $(GO_PKG)/conf.Version=$(PKG_VERSION) \ + $(GO_PKG)/core/iptables.TproxyNotSkipBr=true + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +TAR_OPTIONS+= --strip-components 1 +TAR_CMD=$(HOST_TAR) -C $(1)/.. $(TAR_OPTIONS) + +define Package/v2raya + TITLE:=A Linux web GUI client of Project V + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + DEPENDS:=$(GO_ARCH_DEPENDS) \ + +ca-bundle \ + +kmod-nft-tproxy \ + +xray-core + URL:=https://v2raya.org +endef + +define Package/v2raya/description + v2rayA is a V2Ray Linux client supporting global transparent proxy, + compatible with SS, SSR, Trojan(trojan-go), PingTunnel protocols. +endef + +define Package/v2raya/conffiles +/etc/v2raya/ +/etc/config/v2raya +endef + +WEB_FILE:=$(PKG_NAME)-web-$(PKG_VERSION).tar.gz +define Download/v2raya-web + URL:=https://github.com/v2rayA/v2rayA/releases/download/v$(PKG_VERSION)/ + URL_FILE:=web.tar.gz + FILE:=$(WEB_FILE) + HASH:=89bff9248a9cba8b7bda6e1202ac565dbca377319423868835235deddbfb182a +endef + +define Build/Prepare + $(call Build/Prepare/Default) + + ( \ + mkdir -p $(PKG_BUILD_DIR)/server/router/web ; \ + gzip -dc $(DL_DIR)/$(WEB_FILE) | $(HOST_TAR) -C $(PKG_BUILD_DIR)/server/router/web $(TAR_OPTIONS) ; \ + ) +endef + +define Package/v2raya/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/v2rayA $(1)/usr/bin/v2raya + + $(INSTALL_DIR) $(1)/etc/config/ + $(INSTALL_CONF) $(CURDIR)/files/v2raya.config $(1)/etc/config/v2raya + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) $(CURDIR)/files/v2raya.init $(1)/etc/init.d/v2raya +endef + +$(eval $(call Download,v2raya-web)) +$(eval $(call GoBinPackage,v2raya)) +$(eval $(call BuildPackage,v2raya)) diff --git a/v2raya/files/v2raya.config b/v2raya/files/v2raya.config new file mode 100644 index 00000000..66b66b24 --- /dev/null +++ b/v2raya/files/v2raya.config @@ -0,0 +1,44 @@ + +config v2raya 'config' + option enabled '0' + + # Listening address + option address '0.0.0.0:2017' + + # Make sure your IPv6 network works fine before you turn it on. + # Optional values: auto, on, off. + option ipv6_support 'auto' + + # Experimental feature. Make sure you have installed nftables. + # Optional values: auto, on, off. + option nftables_support 'auto' + + # Optional values: trace, debug, info, warn or error + option log_level 'info' + + # Maximum number of days to keep log files + option log_max_days '3' + + option log_disable_color '1' + + option log_disable_timestamp '0' + + # Executable v2ray binary path. Auto-detect if put it empty + option v2ray_bin '' + + # Additional v2ray config directory, files in it will be combined with config generated by v2rayA + option v2ray_confdir '' + + # The executable file to run in the transparent proxy life-cycle. + # v2rayA will pass in the --transparent-type (tproxy, redirect) + # and --stage (pre-start, post-start, pre-stop, post-stop) arguments. + option transparent_hook '' + + # The executable file to run in the v2ray-core life-cycle. + # v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument. + option core_hook '' + + # The executable file to run in the v2ray-core life-cycle. + # v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument. + option plugin_manager '' + diff --git a/v2raya/files/v2raya.init b/v2raya/files/v2raya.init new file mode 100755 index 00000000..1e55a187 --- /dev/null +++ b/v2raya/files/v2raya.init @@ -0,0 +1,75 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 Tianling Shen + +USE_PROCD=1 +START=99 + +CONF="v2raya" +PROG="/usr/bin/v2raya" + +is_enabled() { + local enabled + config_get_bool enabled "$1" "$2" "${3:-0}" + if [ "$enabled" -eq "1" ]; then + return 0 + else + return 1 + fi +} + +append_env() { + procd_append_param env "V2RAYA_$(echo "$1" | tr "[a-z]" "[A-Z]")"="$2" +} + +append_env_arg() { + local value + config_get value "$1" "$2" $3 + [ -n "$value" ] && append_env "$2" "$value" +} + +append_env_bool() { + is_enabled "$1" "$2" && append_env "$2" "true" +} + +start_service() { + config_load "$CONF" + + is_enabled "config" "enabled" || return 1 + + procd_open_instance "$CONF" + procd_set_param command "$PROG" + procd_set_param env XDG_DATA_HOME="/usr/share" + + append_env "config" "/etc/v2raya" + append_env "log_file" "/var/log/v2raya/v2raya.log" + + append_env_arg "config" "address" "0.0.0.0:2017" + append_env_arg "config" "ipv6_support" "auto" + append_env_arg "config" "nftables_support" "auto" + append_env_arg "config" "log_level" "info" + append_env_arg "config" "log_max_days" "3" + append_env_arg "config" "v2ray_bin" + append_env_arg "config" "v2ray_confdir" + append_env_arg "config" "transparent_hook" + append_env_arg "config" "core_hook" + append_env_arg "config" "plugin_manager" + append_env_bool "config" "log_disable_color" + append_env_bool "config" "log_disable_timestamp" + + procd_set_param limits core="unlimited" + procd_set_param limits nofile="1000000 1000000" + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_close_instance +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "$CONF" +} diff --git a/verysync/Makefile b/verysync/Makefile new file mode 100644 index 00000000..3a82e1fd --- /dev/null +++ b/verysync/Makefile @@ -0,0 +1,64 @@ +# SPDX-Identifier-License: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +ifeq ($(ARCH),aarch64) + PKG_ARCH_VERYSYNC:=arm64 + PKG_HASH_VERYSYNC:=66bce5e9725969c4aa9ec057830f5197156526b2a2ff8ae92ae155cd4665fd8b +else ifeq ($(ARCH),arm) + PKG_ARCH_VERYSYNC:=arm + PKG_HASH_VERYSYNC:=33a1831fa26910a57a5fdf82ed2ba8ccf58bab41e10b989e546cfaf69371fccc +else ifeq ($(ARCH),i386) + PKG_ARCH_VERYSYNC:=386 + PKG_HASH_VERYSYNC:=976210bf42da9b5a39ee8d41cce3b4edc3c1d9045192617a5b4b063f8182af74 +else ifeq ($(ARCH),mips) + PKG_ARCH_VERYSYNC:=mips + PKG_HASH_VERYSYNC:=7362b933f561ebaa63d6c660971799ff153d0317e4d70812982f3cfbd678ba65 +else ifeq ($(ARCH),mipsel) + PKG_ARCH_VERYSYNC:=mipsle + PKG_HASH_VERYSYNC:=2ed1feee9b5ea6cd3a39e4c5d556b8b29629d194f91b077ac2f7573f5733fb2e +else ifeq ($(ARCH),powerpc64) + PKG_ARCH_VERYSYNC:=ppc64 + PKG_HASH_VERYSYNC:=3e2c8bb40812fec7db80b27b196746c6ba66684e4d882aa35284c3eba1de86ba +else ifeq ($(ARCH),x86_64) + PKG_ARCH_VERYSYNC:=amd64 + PKG_HASH_VERYSYNC:=340ef24c27e4aa4df5a52824c63f8fb407947e75174673d94c18df4a8664287b +else ifeq ($(ARCH),riscv64) + PKG_ARCH_VERYSYNC:=riscv64 + PKG_HASH_VERYSYNC:=348669525a5ef80b70ab3570d8bfc558bafdbbad6954fc2eeb3d55ab972be864 +else ifeq ($(ARCH),loongarch64) + PKG_ARCH_VERYSYNC:=loong64 + PKG_HASH_VERYSYNC:=c70ea700ebaad77c2d98ac9580191bd1bfaae4b0a5590382e29ffb8b73ab3550 +endif + +PKG_NAME:=verysync +PKG_VERSION:=2.21.3 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-linux-$(PKG_ARCH_VERYSYNC)-v$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://dl.verysync.com/releases/v$(PKG_VERSION)/ \ + http://dl-cn.verysync.com/releases/v$(PKG_VERSION)/ +PKG_HASH:=$(PKG_HASH_VERYSYNC) +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-linux-$(PKG_ARCH_VERYSYNC)-v$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/verysync + SECTION:=net + CATEGORY:=Network + TITLE:=A efficient data transmission tool + URL:=http://www.verysync.com + DEPENDS:=@(aarch64||arm||i386||mips||mipsel||powerpc64||x86_64||riscv64||loongarch64) +endef + +define Build/Compile +endef + +define Package/verysync/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/verysync $(1)/usr/bin/verysync +endef + +$(eval $(call BuildPackage,verysync)) diff --git a/vncrepeater/Makefile b/vncrepeater/Makefile new file mode 100644 index 00000000..3e232bc1 --- /dev/null +++ b/vncrepeater/Makefile @@ -0,0 +1,69 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=vncrepeater +PKG_VERSION:=0.14 +PKG_RELEASE:=2 +PKG_MAINTAINER:=Jirka Spicak +PKG_LICENSE:=GPL-2.0 + + +PKG_SOURCE:=repeater014.zip +PKG_SOURCE_URL:=http://jtko.mbnet.fi/uvncrepeater +PKG_HASH:=79178e9baa9cac05f26e43f742933958707cb5c0632c51a5706b13922f3bb5b0 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/vncrepeater + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libstdcpp + TITLE:=UltraVNC repeater for Linux + URL:=http://www.uvnc.com/addons/repeater.html +endef + +define Package/vncrepeater/conffiles +/etc/vncrepeater.conf +endef + +define Package/vncrepeater/description + Viewer can be behind Nat router or directly connected to the internet + instead of forwarding serveral ports, you only need to forward 1 port. + If the PC that runs the Repeater has access to the local DNS server, + you can use your local DNS names instead of 10.10.10.12. + This could be handy when you have a dynamic DHCP server allocating + ip adresses for your PC. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(PKG_UNPACK) + $(CP) $(PKG_BUILD_DIR)/../Ver014/* $(PKG_BUILD_DIR)/ + rm -rf $(PKG_BUILD_DIR)/../Ver014/ + $(Build/Patch) +endef + +define Build/Compile + $(call Build/Compile/Default, \ + CC="$(TARGET_CXX)" \ + CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) -fno-rtti" \ + repeater \ + ) +endef + +define Package/vncrepeater/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/repeater $(1)/usr/sbin/$(PKG_NAME) + $(INSTALL_DIR) $(1)/etc + $(CP) $(PKG_BUILD_DIR)/uvncrepeater.ini $(1)/etc/vncrepeater.conf +endef + +$(eval $(call BuildPackage,vncrepeater)) diff --git a/vncrepeater/patches/001-uclibcxx_linking.patch b/vncrepeater/patches/001-uclibcxx_linking.patch new file mode 100644 index 00000000..1fef93cd --- /dev/null +++ b/vncrepeater/patches/001-uclibcxx_linking.patch @@ -0,0 +1,39 @@ +--- a/Makefile ++++ b/Makefile +@@ -1,27 +1,28 @@ + CFLAGS=-Wall + repeater: repeater.o repeaterproc.o openbsd_stringfuncs.o iniparser.o readini.o repeaterutil.o repeaterevents.o +- g++ $(CFLAGS) -o repeater repeater.o repeaterproc.o openbsd_stringfuncs.o iniparser.o readini.o repeaterutil.o repeaterevents.o ++ $(CC) $(CFLAGS) -o repeater repeater.o repeaterproc.o openbsd_stringfuncs.o iniparser.o readini.o repeaterutil.o repeaterevents.o $(LDFLAGS) + + repeater.o: repeater.cpp +- g++ $(CFLAGS) -c repeater.cpp ++ $(CC) $(CFLAGS) -c repeater.cpp + + repeaterproc.o: repeaterproc.cpp +- g++ $(CFLAGS) -c repeaterproc.cpp ++ $(CC) $(CFLAGS) -c repeaterproc.cpp + + openbsd_stringfuncs.o: openbsd_stringfuncs.cpp +- g++ $(CFLAGS) -c openbsd_stringfuncs.cpp ++ $(CC) $(CFLAGS) -c openbsd_stringfuncs.cpp + + iniparser.o: iniparser.cpp +- g++ $(CFLAGS) -c iniparser.cpp ++ $(CC) $(CFLAGS) -c iniparser.cpp + + readini.o: readini.cpp +- g++ $(CFLAGS) -c readini.cpp ++ $(CC) $(CFLAGS) -c readini.cpp + + repeaterutil.o: repeaterutil.cpp +- g++ $(CFLAGS) -c repeaterutil.cpp ++ $(CC) $(CFLAGS) -c repeaterutil.cpp + + repeaterevents.o: repeaterevents.cpp +- g++ $(CFLAGS) -c repeaterevents.cpp ++ $(CC) $(CFLAGS) -c repeaterevents.cpp + + clean: + rm -f *.o repeater ++ diff --git a/vncrepeater/patches/002-cfg-path.patch b/vncrepeater/patches/002-cfg-path.patch new file mode 100644 index 00000000..85a92c8f --- /dev/null +++ b/vncrepeater/patches/002-cfg-path.patch @@ -0,0 +1,38 @@ +--- a/repeater.cpp ++++ b/repeater.cpp +@@ -593,7 +593,9 @@ static bool checkIdCode(char *IdCode) + static long parseId(char *IdCode) + { + unsigned int ii; +- int retVal; ++ //PFaf 20101122: Minor correction due to compiler warning ++ //int retVal; ++ long retVal; + + debug(LEVEL_3, "parseId(): IdCode = %s\n", IdCode); + +@@ -998,9 +1000,13 @@ static bool isServerAddressAllowed(char + allow = false; + + //server 0 == denied +- if ((srvAddr.a == 0) || (srvAddr.b == 0) || (srvAddr.c == 0) || (srvAddr.d == 0)) ++ //Fix by PFaf - 20101122 ++ //Server address can be X.0.0.Y i.e. 10.0.0.1 ++ //since these are valid addresses, so we should not exclude them. ++ //Only exclude addresses that start or end with zeros (0). ++ //if ((srvAddr.a == 0) || (srvAddr.b == 0) || (srvAddr.c == 0) || (srvAddr.d == 0)) ++ if ((srvAddr.a == 0) || (srvAddr.d == 0)) + allow = false; +- + + //allowed so far ? + if (allow) +@@ -1983,7 +1989,7 @@ int main(int argc, char **argv) + struct sigaction saInt; + + //ini file default +- char defaultIniFilePathAndName[] = "/etc/uvncrepeater.ini"; ++ char defaultIniFilePathAndName[] = "/etc/vncrepeater.conf"; + char tmpBuf[MAX_PATH]; + bool memoryOk; + diff --git a/vpn-policy-routing/Makefile b/vpn-policy-routing/Makefile new file mode 100644 index 00000000..f5ac8333 --- /dev/null +++ b/vpn-policy-routing/Makefile @@ -0,0 +1,68 @@ +# Copyright 2017-2018 Stan Grishin (stangri@melmac.net) +# This is free software, licensed under the GNU General Public License v3. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=vpn-policy-routing +PKG_VERSION:=0.3.2 +PKG_RELEASE:=20 +PKG_LICENSE:=GPL-3.0-or-later +PKG_MAINTAINER:=Stan Grishin + +include $(INCLUDE_DIR)/package.mk + +define Package/vpn-policy-routing + SECTION:=net + CATEGORY:=Network + TITLE:=VPN Policy-Based Routing Service + URL:=https://docs.openwrt.melmac.net/vpn-policy-routing/ + DEPENDS:=+jshn +ipset +iptables +resolveip +kmod-ipt-ipset +iptables-mod-ipopt +ip-full + PKGARCH:=all +endef + +define Package/vpn-policy-routing/description +This service allows policy-based routing for L2TP, Openconnect, OpenVPN, PPTP and Wireguard tunnels and WAN interface. +Policies can specify domains, local IPs/subnets and ports, as well as remote IPs/subnets and ports. +endef + +define Package/vpn-policy-routing/conffiles +/etc/config/vpn-policy-routing +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/vpn-policy-routing/install + $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/hotplug.d/firewall $(1)/etc/ + $(INSTALL_BIN) ./files/vpn-policy-routing.init $(1)/etc/init.d/vpn-policy-routing + $(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/vpn-policy-routing + $(INSTALL_CONF) ./files/vpn-policy-routing.conf $(1)/etc/config/vpn-policy-routing + $(INSTALL_DATA) ./files/vpn-policy-routing.firewall.hotplug $(1)/etc/hotplug.d/firewall/99-vpn-policy-routing + $(INSTALL_DATA) ./files/vpn-policy-routing.aws.user $(1)/etc/vpn-policy-routing.aws.user + $(INSTALL_DATA) ./files/vpn-policy-routing.netflix.user $(1)/etc/vpn-policy-routing.netflix.user +endef + +define Package/vpn-policy-routing/postinst + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/vpn-policy-routing enable + fi + exit 0 +endef + +define Package/vpn-policy-routing/prerm + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + echo "Stopping service and removing rc.d symlink for vpn-policy-routing" + /etc/init.d/vpn-policy-routing stop || true + /etc/init.d/vpn-policy-routing disable || true + fi + exit 0 +endef + +$(eval $(call BuildPackage,vpn-policy-routing)) diff --git a/vpn-policy-routing/files/README.md b/vpn-policy-routing/files/README.md new file mode 100644 index 00000000..98d7efc6 --- /dev/null +++ b/vpn-policy-routing/files/README.md @@ -0,0 +1,3 @@ +# README + +README has been moved to [https://docs.openwrt.melmac.net/vpn-policy-routing/](https://docs.openwrt.melmac.net/vpn-policy-routing/). diff --git a/vpn-policy-routing/files/vpn-policy-routing.aws.user b/vpn-policy-routing/files/vpn-policy-routing.aws.user new file mode 100644 index 00000000..a00770be --- /dev/null +++ b/vpn-policy-routing/files/vpn-policy-routing.aws.user @@ -0,0 +1,19 @@ +#!/bin/sh +# This file is heavily based on code from https://github.com/Xentrk/netflix-vpn-bypass/blob/master/IPSET_Netflix.sh + +TARGET_IPSET='wan' + +TARGET_URL="https://ip-ranges.amazonaws.com/ip-ranges.json" +TARGET_FNAME="/var/vpn-policy-routing_tmp_aws_ip_ranges" + +_ret=1 + +if [ ! -s "$TARGET_FNAME" ]; then + curl "$TARGET_URL" 2>/dev/null | grep "ip_prefix" | sed 's/^.*\"ip_prefix\": \"//; s/\",//' > "$TARGET_FNAME" +fi +if [ -s "$TARGET_FNAME" ]; then + awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_FNAME" | ipset restore -! && _ret=0 +fi +rm -f "$TARGET_FNAME" + +return $_ret diff --git a/vpn-policy-routing/files/vpn-policy-routing.conf b/vpn-policy-routing/files/vpn-policy-routing.conf new file mode 100644 index 00000000..ed6f01cd --- /dev/null +++ b/vpn-policy-routing/files/vpn-policy-routing.conf @@ -0,0 +1,30 @@ +config vpn-policy-routing 'config' + option enabled '0' + option verbosity '2' + option strict_enforcement '1' + option src_ipset '0' + option dest_ipset '0' + option resolver_ipset 'dnsmasq.ipset' + option ipv6_enabled '0' + list ignored_interface 'vpnserver wgserver' + option boot_timeout '30' + option iptables_rule_option 'append' + option procd_reload_delay '1' + option webui_enable_column '0' + option webui_protocol_column '0' + option webui_chain_column '0' + option webui_show_ignore_target '0' + option webui_sorting '1' + list webui_supported_protocol 'tcp' + list webui_supported_protocol 'udp' + list webui_supported_protocol 'tcp udp' + list webui_supported_protocol 'icmp' + list webui_supported_protocol 'all' + +config include + option path '/etc/vpn-policy-routing.netflix.user' + option enabled 0 + +config include + option path '/etc/vpn-policy-routing.aws.user' + option enabled 0 diff --git a/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug b/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug new file mode 100755 index 00000000..3932b2b6 --- /dev/null +++ b/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug @@ -0,0 +1,6 @@ +#!/bin/sh + +[ "$ACTION" = "reload" ] || exit 0 + +logger -t "vpn-policy-routing" "Reloading vpn-policy-routing due to $ACTION of firewall" +/etc/init.d/vpn-policy-routing reload diff --git a/vpn-policy-routing/files/vpn-policy-routing.init b/vpn-policy-routing/files/vpn-policy-routing.init new file mode 100755 index 00000000..09506982 --- /dev/null +++ b/vpn-policy-routing/files/vpn-policy-routing.init @@ -0,0 +1,1247 @@ +#!/bin/sh /etc/rc.common +# Copyright 2017-2020 Stan Grishin (stangri@melmac.net) +# shellcheck disable=SC2039,SC1091,SC2018,SC2019 +PKG_VERSION='dev-test' + +# sysctl net.ipv4.conf.default.rp_filter=1 +# sysctl net.ipv4.conf.all.rp_filter=1 + +# shellcheck disable=SC2034 +START=94 +# shellcheck disable=SC2034 +USE_PROCD=1 + +if type extra_command 1>/dev/null 2>&1; then + extra_command 'support' "Generates output required to troubleshoot routing issues + Use '-d' option for more detailed output + Use '-p' option to automatically upload data under VPR paste.ee account + WARNING: while paste.ee uploads are unlisted, they are still publicly available + List domain names after options to include their lookup in report" + extra_command 'version' 'Show version information' +else +# shellcheck disable=SC2034 + EXTRA_COMMANDS='support version' +# shellcheck disable=SC2034 + EXTRA_HELP=" support Generates output required to troubleshoot routing issues + Use '-d' option for more detailed output + Use '-p' option to automatically upload data under VPR paste.ee account + WARNING: while paste.ee uploads are unlisted, they are still publicly available + List domain names after options to include their lookup in report" +fi + +readonly packageName='vpn-policy-routing' +readonly serviceName="$packageName $PKG_VERSION" +readonly PIDFile="/var/run/${packageName}.pid" +readonly jsonFile="/var/run/${packageName}.json" +readonly dnsmasqFile="/var/dnsmasq.d/${packageName}" +readonly sharedMemoryOutput="/dev/shm/$packageName-output" +readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m' +readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m' +readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m' +readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m' +readonly _ERROR_='\033[0;31mERROR\033[0m' +readonly _WARNING_='\033[0;33mWARNING\033[0m' + +gatewaySummary=''; errorSummary=''; warningSummary=''; +serviceEnabled=''; verbosity=''; strictMode=''; +wanTableID=''; wanMark=''; fwMask=''; +ipv6Enabled=''; srcIpset=''; destIpset=''; resolverIpset=''; +wanIface4=''; wanIface6=''; ifaceMark=''; ifaceTableID=''; +ifAll=''; ifSupported=''; ignoredIfaces=''; supportedIfaces=''; icmpIface=''; +wanGW4=''; wanGW6=''; bootTimeout=''; insertOption=''; +webuiChainColumn=''; webuiShowIgnore=''; dnsmasqIpsetSupported=''; +procdReloadDelay=''; +usedChainsList='PREROUTING' +ipsetSupported='true' +configLoaded='false' + +version() { echo "$PKG_VERSION"; } +create_lock() { [ -e "$PIDFile" ] && return 1; touch "$PIDFile"; } +remove_lock() { [ -e "$PIDFile" ] && rm -f "$PIDFile"; } +trap remove_lock EXIT +output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; } +output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; } +output_fail() { s=1; output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; } +output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; } +str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; } +str_replace() { echo "${1//$2/$3}"; } +str_contains() { [ -n "$2" ] && [ "${1//$2}" != "$1" ]; } +str_contains_word() { echo "$1" | grep -q -w "$2"; } +str_to_lower() { echo "$1" | tr 'A-Z' 'a-z'; } +str_extras_to_underscore() { echo "$1" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_'; } +str_extras_to_space() { echo "$1" | tr ';{}' ' '; } + +output() { +# Can take a single parameter (text) to be output at any verbosity +# Or target verbosity level and text to be output at specifc verbosity + local msg memmsg logmsg + if [ $# -ne 1 ]; then + if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi + fi + [ -t 1 ] && printf "%b" "$1" + msg="${1//$serviceName /service }"; + if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then + [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")" + logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')" + logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")" + rm -f "$sharedMemoryOutput" + else + printf "%b" "$msg" >> "$sharedMemoryOutput" + fi +} +is_present() { command -v "$1" >/dev/null 2>&1; } +is_installed() { [ -s "/usr/lib/opkg/info/${1}.control" ]; } +is_variant_installed() { [ "$(echo /usr/lib/opkg/info/"${1}"*.control)" != "/usr/lib/opkg/info/${1}*.control" ]; } + +build_ifAll() { ifAll="${ifAll}${1} "; } +build_ifSupported() { is_supported_interface "$1" && ifSupported="${ifSupported}${1} "; } +vpr_find_iface() { + local iface i param="$2" + [ "$param" = 'wan6' ] || param='wan' + "network_find_${param}" iface + is_tunnel "$iface" && unset iface + if [ -z "$iface" ]; then + for i in $ifAll; do + if "is_${param}" "$i"; then break; else unset i; fi + done + fi + eval "$1"='${iface:-$i}' +} +vpr_get_gateway() { + local iface="$2" dev="$3" gw + network_get_gateway gw "$iface" + if [ -z "$gw" ] || [ "$gw" = '0.0.0.0' ]; then + gw="$(ip -4 a list dev "$dev" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')" + fi + eval "$1"='$gw' +} +vpr_get_gateway6() { + local iface="$2" dev="$3" gw + network_get_gateway6 gw "$iface" + if [ -z "$gw" ] || [ "$gw" = '::/0' ] || [ "$gw" = '::0/0' ] || [ "$gw" = '::' ]; then + gw="$(ip -6 a list dev "$dev" 2>/dev/null | grep inet6 | awk '{print $2}')" + fi + eval "$1"='$gw' +} +is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; } +is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; } +is_ovpn() { local dev; dev=$(uci -q get network."$1".ifname); [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; } +is_pptp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "pptp" ]; } +is_tor() { [ "$(str_to_lower "$1")" = "tor" ]; } +is_tor_running() { + local ret=0 + if [ -s "/etc/tor/torrc" ]; then + json_load "$(ubus call service list "{ 'name': 'tor' }")" + json_select 'tor'; json_select 'instances'; json_select 'instance1'; + json_get_var ret 'running'; json_cleanup + fi + if [ "$ret" = "0" ]; then return 1; else return 0; fi +} +is_wg() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:9}" = "wireguard" ]; } +is_tunnel() { is_l2tp "$1" || is_oc "$1" || is_ovpn "$1" || is_pptp "$1" || is_tor "$1" || is_wg "$1"; } +is_wan() { [ "$1" = "$wanIface4" ] || { [ "${1##wan}" != "$1" ] && [ "${1##wan6}" = "$1" ]; } || [ "${1%%wan}" != "$1" ]; } +is_wan6() { [ -n "$wanIface6" ] && [ "$1" = "$wanIface6" ] || [ "${1/#wan6}" != "$1" ] || [ "${1/%wan6}" != "$1" ]; } +is_ignored_interface() { str_contains_word "$ignoredIfaces" "$1"; } +is_supported_interface() { str_contains_word "$supportedIfaces" "$1" || { ! is_ignored_interface "$1" && { is_wan "$1" || is_wan6 "$1" || is_tunnel "$1"; }; }; } +is_mac_address() { expr "$1" : '[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]$' >/dev/null; } +is_ipv4() { expr "$1" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; } +is_ipv6() { ! is_mac_address "$1" && str_contains "$1" ":"; } +is_family_mismatch() { ( is_netmask "${1//!}" && is_ipv6 "${2//!}" ) || ( is_ipv6 "${1//!}" && is_netmask "${2//!}" ); } +is_ipv6_link_local() { [ "${1:0:4}" = "fe80" ]; } +is_ipv6_unique_local() { [ "${1:0:2}" = "fc" ] || [ "${1:0:2}" = "fd" ]; } +is_ipv6_global() { [ "${1:0:4}" = "2001" ]; } +# is_ipv6_global() { is_ipv6 "$1" && ! is_ipv6_link_local "$1" && ! is_ipv6_link_local "$1"; } +is_netmask() { local ip="${1%/*}"; [ "$ip" != "$1" ] && is_ipv4 "$ip"; } +is_domain() { str_contains "$1" '[a-zA-Z]'; } +is_phys_dev() { [ "${1:0:1}" = "@" ] && ip l show | grep -E -q "^\\d+\\W+${1:1}"; } +is_turris() { /bin/ubus -S call system board | /bin/grep 'Turris' | /bin/grep -q '15.05'; } +is_chaos_calmer() { ubus -S call system board | grep -q 'Chaos Calmer'; } +dnsmasq_kill() { killall -q -HUP dnsmasq; } +dnsmasq_restart() { output 3 'Restarting DNSMASQ '; if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then output_okn; else output_failn; fi; } +is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; } +is_supported_iface_dev() { + for n in $ifSupported; do + if [ "$1" = "$(uci -q get "network.${n}.ifname" || echo "$n")" ] || \ + [ "$1" = "$(uci -q get "network.${n}.proto")-${n}" ] ; then return 0; fi + done + return 1 +} +is_supported_protocol () { grep -o '^[^#]*' /etc/protocols | grep -w -v '0' | grep . | awk '{print $1}' | grep -q "$1"; } +append_chains_targets() { + local chain iface name + config_get name "$1" 'name' 'blank' + config_get chain "$1" 'chain' 'PREROUTING' + config_get iface "$1" 'interface' + if ! str_contains_word "$usedChainsList" "$chain"; then + usedChainsList="$usedChainsList $chain" + if [ "$chain" != 'PREROUTING' ] && [ "$webuiChainColumn" != '1' ]; then + warningSummary="${warningSummary}$_WARNING_: Chain '$chain' is used by a policy '$name', but a WebUI setting to show chains column (webui_chain_column) is disabled!\\n" + fi + fi + if [ "$iface" = 'ignore' ] && ! str_contains_word "$supportedIfaces" 'ignore'; then + supportedIfaces="$supportedIfaces ignore" + if [ "$webuiShowIgnore" != '1' ]; then + warningSummary="${warningSummary}$_WARNING_: The 'ignore' target is used by a policy '$name', but a WebUI setting to show 'ignore' target (webui_show_ignore_target) is disabled!\\n" + fi + fi +} + +load_package_config() { + [ "$configLoaded" = 'false' ] || return 0 + + config_load "$packageName" + config_get_bool serviceEnabled 'config' 'enabled' 0 + config_get_bool strictMode 'config' 'strict_enforcement' 1 + config_get_bool ipv6Enabled 'config' 'ipv6_enabled' 0 + config_get_bool srcIpset 'config' 'src_ipset' 0 + config_get_bool destIpset 'config' 'dest_ipset' 0 + config_get resolverIpset 'config' 'resolver_ipset' 'dnsmasq.ipset' + config_get verbosity 'config' 'verbosity' '2' + config_get wanTableID 'config' 'wan_tid' '201' + config_get wanMark 'config' 'wan_mark' '0x010000' + config_get fwMask 'config' 'fw_mask' '0xff0000' + config_get icmpIface 'config' 'icmp_interface' + config_get ignoredIfaces 'config' 'ignored_interface' + config_get supportedIfaces 'config' 'supported_interface' + config_get bootTimeout 'config' 'boot_timeout' '30' + config_get insertOption 'config' 'iptables_rule_option' 'append' + config_get procdReloadDelay 'config' 'procd_reload_delay' '0' + config_get_bool webuiChainColumn 'config' 'webui_chain_column' '0' + config_get_bool webuiShowIgnore 'config' 'webui_show_ignore_target' '0' + config_foreach append_chains_targets 'policy' + + if [ -z "${verbosity##*[!0-9]*}" ] || [ "$verbosity" -lt 0 ] || [ "$verbosity" -gt 2 ]; then + verbosity=2 + fi + + . /lib/functions/network.sh + . /usr/share/libubox/jshn.sh + mkdir -p "${PIDFile%/*}" + mkdir -p "${jsonFile%/*}" + mkdir -p "${dnsmasqFile%/*}" + + if [ -n "$icmpIface" ] && ! str_contains_word "$usedChainsList" 'OUTPUT'; then + usedChainsList="$usedChainsList OUTPUT" + fi + + case $insertOption in + insert|-i|-I) insertOption='-I';; + append|-a|-A|*) insertOption='-A';; + esac + + [ "$resolverIpset" = 'dnsmasq.ipset' ] && dnsmasqIpsetSupported='true' + if dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'; then + unset dnsmasqIpsetSupported + if [ -n "$dnsmasqIpsetSupported" ]; then + errorSummary="${errorSummary}${_ERROR_}: Resolver ipset support (dnsmasq.ipset) is enabled in $packageName, but DNSMASQ ipsets are not supported on this system!\\n" + fi + fi + if ! ipset help hash:net >/dev/null 2>&1; then + unset ipsetSupported + if [ -n "$dnsmasqIpsetSupported" ]; then + errorSummary="${errorSummary}${_ERROR_}: DNSMASQ ipsets are supported, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" + unset dnsmasqIpsetSupported + fi + if [ "$destIpset" -ne 0 ]; then + errorSummary="${errorSummary}${_ERROR_}: Destination ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" + destIpset=0 + fi + if [ "$srcIpset" -ne 0 ]; then + errorSummary="${errorSummary}${_ERROR_}: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" + srcIpset=0 + fi + fi + if ! ipset help hash:mac >/dev/null 2>&1; then + if [ "$srcIpset" -ne 0 ]; then + errorSummary="${errorSummary}${_ERROR_}: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:mac' type!\\n" + srcIpset=0 + fi + fi + + configLoaded='true' +} + +is_enabled() { + load_package_config + if [ "$serviceEnabled" -eq 0 ]; then + if [ "$1" = 'on_start' ]; then + errorSummary="${errorSummary}${_ERROR_}: ${packageName} is currently disabled.\\n" + errorSummary="${errorSummary}Enable ${packageName} from WebUI or run the following commands:\\n" + errorSummary="${errorSummary}uci set $packageName.config.enabled='1'; uci commit $packageName;\\n" + fi + return 1 + fi +} + +load_network() { + if [ -z "$ifAll" ]; then + config_load 'network' + config_foreach build_ifAll 'interface' + fi + vpr_find_iface wanIface4 'wan' + [ "$ipv6Enabled" -ne 0 ] && vpr_find_iface wanIface6 'wan6' + [ -n "$wanIface4" ] && network_get_gateway wanGW4 "$wanIface4" + [ -n "$wanIface6" ] && network_get_gateway6 wanGW6 "$wanIface6" + wanGW="${wanGW4:-$wanGW6}" + unset ifSupported + config_load 'network' + config_foreach build_ifSupported 'interface' +} + +is_wan_up() { + local sleepCount=1 + load_network + while [ -z "$wanGW" ] ; do + load_network + if [ $((sleepCount)) -gt $((bootTimeout)) ] || [ -n "$wanGW" ]; then break; fi + output "$serviceName waiting for wan gateway...\\n" + sleep 1 + network_flush_cache + sleepCount=$((sleepCount+1)) + done + if [ -n "$wanGW" ]; then + return 0 + else + errorSummary="${errorSummary}${_ERROR_}: ${serviceName} failed to discover WAN gateway!\\n" + return 1 + fi +} + +ipt_cleanup() { + local i + for i in PREROUTING FORWARD INPUT OUTPUT; do + while iptables -t mangle -D $i -m mark --mark 0x0/0xff0000 -j VPR_${i} >/dev/null 2>&1; do : ; done + done + for i in PREROUTING FORWARD INPUT OUTPUT; do + while iptables -t mangle -D $i -j VPR_${i} >/dev/null 2>&1; do : ; done + done +} + +# shellcheck disable=SC2086 +ipt() { + local d failFlagIpv4=1 failFlagIpv6=1 + for d in "${*//-A/-D}" "${*//-I/-D}" "${*//-N/-F}" "${*//-N/-X}"; do + [ "$d" != "$*" ] && { iptables $d >/dev/null 2>&1; ip6tables $d >/dev/null 2>&1; } + done + + d="$*"; iptables $d >/dev/null 2>&1 && failFlagIpv4=0; + if [ "$ipv6Enabled" -gt 0 ]; then ip6tables $d >/dev/null 2>&1 && failFlagIpv6=0; fi + + [ "$failFlagIpv4" -eq 0 ] || [ "$failFlagIpv6" -eq 0 ] +} + +# shellcheck disable=SC2086 +ips() { + local command="$1" ipset="${2//-/_}" param="$3" comment="$4" appendix failFlag=0 + if str_contains "$ipset" '_ip'; then + ipset="${ipset//_ip}"; appendix='_ip'; + elif str_contains "$ipset" '_mac'; then + ipset="${ipset//_mac}"; appendix='_mac'; + fi + + case "$command" in + add_dnsmasq) + [ "$resolverIpset" = "dnsmasq.ipset" ] || return 1 + if [ -z "$dnsmasqIpsetSupported" ]; then + warningSummary="${warningSummary}${_WARNING_}: The 'resolver_ipset' is set to 'dnsmasq.ipset', but DNSMASQ ipsets are not supported on this system!\\n" + failFlag=1 + elif [ "$ipv6Enabled" -ne 0 ]; then + echo "ipset=/${param}/${ipset},${ipset}6 # $comment" >> "$dnsmasqFile" || failFlag=1 + else + echo "ipset=/${param}/${ipset} # $comment" >> "$dnsmasqFile" || failFlag=1 + fi + ;; + add) + if [ -z "$appendix" ] && [ "$destIpset" -eq 0 ]; then return 1; fi + if [ -n "$appendix" ] && [ "$srcIpset" -eq 0 ]; then return 1; fi + if [ "$ipv6Enabled" -ne 0 ] && [ "$appendix" != "_mac" ]; then + ipset -q -! $command "${ipset}6${appendix}" $param comment "$comment" || failFlag=1 + fi + ipset -q -! $command "${ipset}${appendix}" $param comment "$comment" || failFlag=1 + ;; + create) + if [ "$ipv6Enabled" -ne 0 ] && [ "$appendix" != "_mac" ]; then + ipset -q -! "$command" "${ipset}6${appendix}" $param family inet6 || failFlag=1 + fi + ipset -q -! "$command" "${ipset}${appendix}" $param || failFlag=1 + ;; + destroy|flush) + ipset -q -! "$command" "${ipset}6${appendix}" 2>/dev/null || failFlag=1 + ipset -q -! "$command" "${ipset}${appendix}" 2>/dev/null || failFlag=1 + return 0 + ;; + esac + return $failFlag +} + +insert_tor_policy() { + local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto chain + proto="$(str_to_lower "$7")" + chain="${8:-PREROUTING}" + if [ -n "${laddr}${lport}${rport}" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'src_addr', 'src_port' and 'dest_port' for policy '$comment'\\n" + fi + if [ -n "$proto" ] && [ "$proto" != "all" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy '$comment'\\n" + fi + if [ "$chain" != "PREROUTING" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'chain' or set 'chain' to 'PREROUTING' for policy '$comment'\\n" + fi + ips 'add' "${iface}" "$raddr" "${comment}: $raddr" || processPolicyError="${processPolicyError}${_ERROR_}: ipset 'add' $iface $raddr\\n" + return 0 +} + +insert_policy() { + local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto chain + local mark param i valueNeg value dest ipInsertOption="-A" + proto="$(str_to_lower "$7")" + chain="${8:-PREROUTING}" + mark=$(eval echo "\$mark_${iface//-/_}") + if [ "$ipv6Enabled" -eq 0 ] && ( is_ipv6 "$laddr" || is_ipv6 "$raddr" ); then + processPolicyError="${processPolicyError}${_ERROR_}: Skipping IPv6 policy '$comment' as IPv6 support is disabled\\n" + return 1 + fi + + if [ -n "$mark" ]; then + dest="-g VPR_MARK${mark}" + elif [ "$iface" = "ignore" ]; then + dest="-j RETURN" + else + processPolicyError="${processPolicyError}${_ERROR_}: Unknown fw_mark for ${iface}\\n" + return 0 + fi + + if [ -z "$proto" ]; then + if [ -n "$lport" ] || [ -n "$rport" ]; then + proto='tcp udp' + else + proto='all' + fi + fi + + if is_family_mismatch "$laddr" "$raddr"; then + processPolicyError="${processPolicyError}${_ERROR_}: Mismatched IP family between '$laddr' and '$raddr' in policy '$comment'\\n" + return 0 + fi + + for i in $proto; do + if [ "$i" = 'all' ]; then + param="-t mangle ${ipInsertOption} VPR_${chain} $dest" + elif ! is_supported_protocol "$i"; then + processPolicyError="${processPolicyError}${_ERROR_}: Unknown protocol '$i' in policy '$comment'\\n" + return 0 + else + param="-t mangle ${ipInsertOption} VPR_${chain} $dest -p $i" + fi + + if [ -n "$laddr" ]; then + if [ "${laddr:0:1}" = "!" ]; then + valueNeg='!'; value="${laddr:1}" + else + unset valueNeg; value="$laddr"; + fi + if is_phys_dev "$value"; then + param="$param $valueNeg -m physdev --physdev-in ${value:1}" + elif is_mac_address "$value"; then + param="$param -m mac $valueNeg --mac-source $value" + else + param="$param $valueNeg -s $value" + fi + fi + + if [ -n "$lport" ]; then + if [ "${lport:0:1}" = "!" ]; then + valueNeg='!'; value="${lport:1}" + else + unset valueNeg; value="$lport"; + fi + param="$param -m multiport $valueNeg --sport ${value//-/:}" + fi + + if [ -n "$raddr" ]; then + if [ "${raddr:0:1}" = "!" ]; then + valueNeg='!'; value="${raddr:1}" + else + unset valueNeg; value="$raddr"; + fi + param="$param $valueNeg -d $value" + fi + + if [ -n "$rport" ]; then + if [ "${rport:0:1}" = "!" ]; then + valueNeg='!'; value="${rport:1}" + else + unset valueNeg; value="$rport"; + fi + param="$param -m multiport $valueNeg --dport ${value//-/:}" + fi + + [ -n "$comment" ] && param="$param -m comment --comment $(str_extras_to_underscore "$comment")" + ipt "$param" || processPolicyError="${processPolicyError}${_ERROR_}: iptables $param\\n" + done + return 0 +} + +r_process_policy(){ + local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto="$7" chain="$8" resolved_laddr resolved_raddr i ipsFailFlag + if str_contains "$laddr" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$laddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done + return 0 + elif str_contains "$lport" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$lport"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$i" "$raddr" "$rport" "$proto" "$chain"; done + return 0 + elif str_contains "$raddr" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$raddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$i" "$rport" "$proto" "$chain"; done + return 0 + elif str_contains "$rport" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$rport"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$i" "$proto" "$chain"; done + return 0 + fi + + # start non-recursive processing + # process TOR, netmask, physical device and mac-address separately, so we don't send them to resolveip + if is_tor "$iface"; then + insert_tor_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" + elif is_phys_dev "$laddr"; then + insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" + elif [ -n "$laddr" ] && [ -z "${lport}${raddr}${rport}" ] && [ "$chain" = 'PREROUTING' ]; then + if is_mac_address "$laddr"; then + if [ -n "$proto" ] && [ "$proto" != 'all' ] && [ "$srcIpset" -ne 0 ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy: '$comment', mac-address: '$laddr'\\n" + fi + ips 'add' "${iface}_mac" "$laddr" "${comment}: $laddr" || ipsFailFlag=1 + else + if [ -n "$proto" ] && [ "$proto" != "all" ] && [ "$srcIpset" -ne 0 ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy: '$comment', source: '$laddr'\\n" + fi + ips 'add' "${iface}_ip" "$laddr" "${comment}: $laddr" || ipsFailFlag=1 + fi + elif [ -n "$raddr" ] && [ -z "${laddr}${lport}${rport}" ] && [ "$chain" = 'PREROUTING' ]; then + if [ -n "$proto" ] && [ "$proto" != 'all' ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy: '$comment', destination: '$raddr'\\n" + fi + if is_domain "$raddr"; then + ips 'add_dnsmasq' "${iface}" "$raddr" "${comment}" || ipsFailFlag=1 + else + ips 'add' "${iface}" "$raddr" "${comment}: $raddr" || ipsFailFlag=1 + fi + else + ipsFailFlag=1 + fi + [ -n "$ipsFailFlag" ] || return 0; + if is_mac_address "$laddr"; then + insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" + elif is_netmask "$laddr" || is_netmask "$raddr"; then + insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" + else + [ -n "$laddr" ] && resolved_laddr="$(resolveip "$laddr")" + [ -n "$raddr" ] && resolved_raddr="$(resolveip "$raddr")" + if [ -n "$resolved_laddr" ] && [ "$resolved_laddr" != "$laddr" ]; then + for i in $resolved_laddr; do [ -n "$i" ] && r_process_policy "$comment $laddr" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done + elif [ -n "$resolved_raddr" ] && [ "$resolved_raddr" != "$raddr" ]; then + for i in $resolved_raddr; do [ -n "$i" ] && r_process_policy "$comment $raddr" "$iface" "$laddr" "$lport" "$i" "$rport" "$proto" "$chain"; done + else + insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" + fi + fi +} + +process_policy(){ + local name comment iface laddr lport raddr rport param mark processPolicyError processPolicyWarning proto chain enabled + config_get comment "$1" 'comment' + config_get name "$1" 'name' 'blank' + config_get iface "$1" 'interface' + config_get laddr "$1" 'src_addr' + config_get lport "$1" 'src_port' + config_get raddr "$1" 'dest_addr' + config_get rport "$1" 'dest_port' + config_get proto "$1" 'proto' + config_get chain "$1" 'chain' 'PREROUTING' + config_get_bool enabled "$1" 'enabled' 1 + + [ "$enabled" -gt 0 ] || return 0 + proto="$(str_to_lower "$proto")" + [ "$proto" = 'auto' ] && unset proto + + comment="${comment:-$name}" + output 2 "Routing '$comment' via $iface " + + if [ -z "$comment" ]; then + errorSummary="${errorSummary}${_ERROR_}: Policy name is empty\\n" + output_fail; return 1; + fi + if [ -z "${laddr}${lport}${raddr}${rport}" ]; then + errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' missing all IPs/ports\\n" + output_fail; return 1; + fi + if [ -z "$iface" ]; then + errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' has no assigned interface\\n" + output_fail; return 1; + fi + if ! is_supported_interface "$iface"; then + errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' has unknown interface: '${iface}'\\n" + output_fail; return 1; + fi + + lport="${lport// / }"; lport="${lport// /,}"; lport="${lport//,\!/ !}"; + rport="${rport// / }"; rport="${rport// /,}"; rport="${rport//,\!/ !}"; + r_process_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" + if [ -n "$processPolicyWarning" ]; then + warningSummary="${warningSummary}${processPolicyWarning}\\n" + fi + if [ -n "$processPolicyError" ]; then + output_fail + errorSummary="${errorSummary}${processPolicyError}\\n" + else + output_ok + fi +} + +table_destroy(){ + local tid="$1" iface="$2" mark="$3" + if [ -n "$tid" ] && [ -n "$iface" ] && [ -n "$mark" ]; then + ipt -t mangle -F "VPR_MARK${mark}" + ipt -t mangle -X "VPR_MARK${mark}" + ip -4 rule del fwmark "$mark" table "$tid" >/dev/null 2>&1 + ip -6 rule del fwmark "$mark" table "$tid" >/dev/null 2>&1 + ip -4 rule del table "$tid" >/dev/null 2>&1 + ip -6 rule del table "$tid" >/dev/null 2>&1 + ip -4 route flush table "$tid" >/dev/null 2>&1 + ip -6 route flush table "$tid" >/dev/null 2>&1 + ips 'flush' "${iface}"; ips 'destroy' "${iface}"; + ips 'flush' "${iface}_ip"; ips 'destroy' "${iface}_ip"; + ips 'flush' "${iface}_mac"; ips 'destroy' "${iface}_mac"; + ip -4 route flush cache + ip -6 route flush cache + sed -i "/$iface/d" /etc/iproute2/rt_tables + return 0 + else + return 1 + fi +} + +# shellcheck disable=SC2086 +table_create(){ + local tid="$1" mark="$2" iface="$3" gw4="$4" dev="$5" gw6="$6" dev6="$7" dscp s=0 i ipv4_error=0 ipv6_error=1 + + if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then + return 1 + fi + + table_destroy "$tid" "$iface" "$mark" + + if [ -n "$gw4" ] || [ "$strictMode" -ne 0 ]; then + echo "$tid" "$iface" >> /etc/iproute2/rt_tables + if [ -z "$gw4" ]; then + ip -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1 + else + ip -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1 + fi +# ip -4 route list table main | grep -v 'br-lan' | while read -r i; do + ip -4 route list table main | while read -r i; do + idev="$(echo "$i" | grep -Eso 'dev [^ ]*' | awk '{print $2}')" + if ! is_supported_iface_dev "$idev"; then + ip -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1 + fi + done + ip -4 route flush cache || ipv4_error=1 + ip -4 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1 + ipt -t mangle -N "VPR_MARK${mark}" || ipv4_error=1 + ipt -t mangle -A "VPR_MARK${mark}" -j MARK --set-xmark "${mark}/${fwMask}" || ipv4_error=1 + ipt -t mangle -A "VPR_MARK${mark}" -j RETURN || ipv4_error=1 + fi + + if [ "$ipv6Enabled" -ne 0 ]; then + ipv6_error=0 + if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strictMode" -ne 0 ]; then + if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then + ip -6 route add unreachable default table "$tid" || ipv6_error=1 + else + ip -6 route list table main | grep " dev $dev6 " | while read -r i; do + ip -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1 + done + fi + ip -6 route flush cache || ipv6_error=1 + ip -6 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv6_error=1 + fi + fi + + if [ $ipv4_error -eq 0 ] || [ $ipv6_error -eq 0 ]; then + dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)" + if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then + ipt -t mangle -I VPR_PREROUTING -m dscp --dscp "${dscp}" -g "VPR_MARK${mark}" || s=1 + fi + if [ -n "$ipsetSupported" ] && { [ -n "$dnsmasqIpsetSupported" ] || [ "$destIpset" -ne 0 ]; }; then + if ips 'create' "${iface}" 'hash:net comment' && ips 'flush' "${iface}"; then + for i in $usedChainsList; do + ipt -t mangle -I VPR_${i} -m set --match-set "${iface}" dst -g "VPR_MARK${mark}" || s=1 + if [ "$ipv6Enabled" -ne 0 ]; then ipt -t mangle -I VPR_${i} -m set --match-set "${iface}6" dst -g "VPR_MARK${mark}" || s=1; fi + done + else + s=1 + fi + fi + if [ -n "$ipsetSupported" ] && [ "$srcIpset" -ne 0 ]; then + if ips 'create' "${iface}_ip" 'hash:net comment' && ips 'flush' "${iface}_ip"; then + ipt -t mangle -I VPR_PREROUTING -m set --match-set "${iface}_ip" src -g "VPR_MARK${mark}" || s=1 + if [ "$ipv6Enabled" -ne 0 ]; then ipt -t mangle -I VPR_PREROUTING -m set --match-set "${iface}6_ip" src -g "VPR_MARK${mark}" || s=1; fi + else + s=1 + fi + if ips 'create' "${iface}_mac" 'hash:mac comment' && ips 'flush' "${iface}_mac"; then + ipt -t mangle -I VPR_PREROUTING -m set --match-set "${iface}_mac" src -g "VPR_MARK${mark}" || s=1 + else + s=1 + fi + fi + if [ "$iface" = "$icmpIface" ]; then + ipt -t mangle -I VPR_OUTPUT -p icmp -g "VPR_MARK${mark}" || s=1 + fi + else + s=1 + fi + + return $s +} + +process_interface(){ + local gw4 gw6 dev dev6 s=0 dscp iface="$1" action="$2" displayText + + is_supported_interface "$iface" || return 0 + is_wan6 "$iface" && return 0 + [ $((ifaceMark)) -gt $((fwMask)) ] && return 1 + + network_get_device dev "$iface" + [ -z "$dev" ] && config_get dev "$iface" 'ifname' + if is_wan "$iface" && [ -n "$wanIface6" ]; then + network_get_device dev6 "$wanIface6" + [ -z "$dev6" ] && config_get dev6 "$wanIface6" 'ifname' + fi + [ -z "$dev6" ] && dev6="$dev" + + [ -z "$ifaceTableID" ] && ifaceTableID="$wanTableID"; [ -z "$ifaceMark" ] && ifaceMark="$wanMark"; + + case "$action" in + destroy) + table_destroy "${ifaceTableID}" "${iface}" "${ifaceMark}" + ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))"; + ;; + create) + eval "mark_${iface//-/_}"='$ifaceMark' + eval "tid_${iface//-/_}"='$ifaceTableID' + table_destroy "${ifaceTableID}" "${iface}" + vpr_get_gateway gw4 "$iface" "$dev" + vpr_get_gateway6 gw6 "$iface" "$dev6" + if [ "$iface" = "$dev" ]; then + displayText="${iface}/${gw4:-0.0.0.0}" + else + displayText="${iface}/${dev}/${gw4:-0.0.0.0}" + fi + [ "$ipv6Enabled" -ne 0 ] && displayText="${displayText}/${gw6:-::/0}" + output 2 "Creating table '$displayText' " + is_default_dev "$dev" && displayText="${displayText} ${__OK__}" + if table_create "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6"; then + gatewaySummary="${gatewaySummary}${displayText}\\n" + output_ok + else + errorSummary="${errorSummary}${_ERROR_}: Failed to set up '$displayText'\\n" + output_fail + fi + ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))"; + ;; + esac + return $s +} + +process_tor_interface(){ + local s=0 iface="$1" action="$2" displayText + case "$action" in + destroy) + for i in PREROUTING FORWARD INPUT OUTPUT; do + ipt -t nat -D "${i}" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" + ipt -t nat -F "VPR_${i}"; ipt -t nat -X "VPR_${i}"; + done + ;; + create) + output 2 "Creating TOR redirects " + dnsPort="$(grep -m1 DNSPort /etc/tor/torrc | awk -F: '{print $2}')" + transPort="$(grep -m1 TransPort /etc/tor/torrc | awk -F: '{print $2}')" + dnsPort="${dnsPort:-9053}"; transPort="${transPort:-9040}"; + for i in $usedChainsList; do + ipt -t nat -N "VPR_${i}" + ipt -t nat "$insertOption" "$i" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" + done + if ips 'create' "${iface}" 'hash:net comment' && ips 'flush' "${iface}"; then + for i in $usedChainsList; do + ipt -t nat -I "VPR_${i}" -p udp -m udp --dport 53 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$dnsPort" -m comment --comment "TorDNS-UDP" || s=1 + ipt -t nat -I "VPR_${i}" -p tcp -m tcp --dport 80 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTP-TCP" || s=1 + ipt -t nat -I "VPR_${i}" -p udp -m udp --dport 80 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTP-UDP" || s=1 + ipt -t nat -I "VPR_${i}" -p tcp -m tcp --dport 443 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTPS-TCP" || s=1 + ipt -t nat -I "VPR_${i}" -p udp -m udp --dport 443 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTPS-UDP" || s=1 + done + else + s=1 + fi + displayText="${iface}/53->${dnsPort}/80,443->${transPort}" + if [ "$s" -eq "0" ]; then + gatewaySummary="${gatewaySummary}${displayText}\\n" + output_ok + else + errorSummary="${errorSummary}${_ERROR_}: Failed to set up '$displayText'\\n" + output_fail + fi + ;; + esac + return $s +} + +convert_config(){ + local i src_ipset dest_ipset resolver_ipset + [ -s "/etc/config/${packageName}" ] || return 0 + grep -q "ignored_interfaces" "/etc/config/${packageName}" && sed -i 's/ignored_interfaces/ignored_interface/g' "/etc/config/${packageName}" + grep -q "supported_interfaces" "/etc/config/${packageName}" && sed -i 's/supported_interfaces/supported_interface/g' "/etc/config/${packageName}" + grep -q "local_addresses" "/etc/config/${packageName}" && sed -i 's/local_addresses/local_address/g' "/etc/config/${packageName}" + grep -q "local_ports" "/etc/config/${packageName}" && sed -i 's/local_ports/local_port/g' "/etc/config/${packageName}" + grep -q "remote_addresses" "/etc/config/${packageName}" && sed -i 's/remote_addresses/remote_address/g' "/etc/config/${packageName}" + grep -q "remote_ports" "/etc/config/${packageName}" && sed -i 's/remote_ports/remote_port/g' "/etc/config/${packageName}" + grep -q "ipset_enabled" "/etc/config/${packageName}" && sed -i 's/ipset_enabled/dest_ipset/g' "/etc/config/${packageName}" + grep -q "dnsmasq_enabled" "/etc/config/${packageName}" && sed -i 's/dnsmasq_enabled/resolver_ipset/g' "/etc/config/${packageName}" + grep -q "enable_control" "/etc/config/${packageName}" && sed -i 's/enable_control/webui_enable_column/g' "/etc/config/${packageName}" + grep -q "proto_control" "/etc/config/${packageName}" && sed -i 's/proto_control/webui_protocol_column/g' "/etc/config/${packageName}" + grep -q "chain_control" "/etc/config/${packageName}" && sed -i 's/chain_control/webui_chain_column/g' "/etc/config/${packageName}" + grep -q "sort_control" "/etc/config/${packageName}" && sed -i 's/sort_control/webui_sorting/g' "/etc/config/${packageName}" + grep -q "local_address" "/etc/config/${packageName}" && sed -i 's/local_address/src_addr/g' "/etc/config/${packageName}" + grep -q "local_port" "/etc/config/${packageName}" && sed -i 's/local_port/src_port/g' "/etc/config/${packageName}" + grep -q "remote_address" "/etc/config/${packageName}" && sed -i 's/remote_address/dest_addr/g' "/etc/config/${packageName}" + grep -q "remote_port" "/etc/config/${packageName}" && sed -i 's/remote_port/dest_port/g' "/etc/config/${packageName}" + grep -q "local_ipset" "/etc/config/${packageName}" && sed -i 's/local_ipset/src_ipset/g' "/etc/config/${packageName}" + grep -q "remote_ipset" "/etc/config/${packageName}" && sed -i 's/remote_ipset/dest_ipset/g' "/etc/config/${packageName}" + dest_ipset="$(uci -q get $packageName.config.dest_ipset)" + src_ipset="$(uci -q get $packageName.config.src_ipset)" + resolver_ipset="$(uci -q get $packageName.config.resolver_ipset)" + + if [ -n "$dest_ipset" ] && [ "$dest_ipset" != "0" ] && [ "$dest_ipset" != "1" ]; then + uci set "$packageName".config.dest_ipset='0' + if [ -z "$resolver_ipset" ]; then + uci set "$packageName".config.resolver_ipset='dnsmasq.ipset' + fi + uci commit "$packageName" + fi + if [ -n "$src_ipset" ] && [ "$src_ipset" != "0" ] && [ "$src_ipset" != "1" ]; then + uci set "$packageName".config.src_ipset='1' + uci commit "$packageName" + fi + if [ -z "$(uci -q get $packageName.config.webui_supported_protocol)" ]; then + uci add_list "$packageName".config.webui_supported_protocol='tcp' + uci add_list "$packageName".config.webui_supported_protocol='udp' + uci add_list "$packageName".config.webui_supported_protocol='tcp udp' + uci add_list "$packageName".config.webui_supported_protocol='icmp' + uci add_list "$packageName".config.webui_supported_protocol='all' + uci commit "$packageName" + fi + for i in append_local_rules append_src_rules \ + append_remote_rules append_dest_rules; do + if [ -n "$(uci -q get $packageName.config.$i)" ]; then + warningSummary="${warningSummary}$_WARNING_: $i setting is not supported in ${serviceName}.\\n" + fi + done + for i in udp_proto_enabled forward_chain_enabled input_chain_enabled \ + output_chain_enabled iprule_enabled; do + if [ "$(uci -q get $packageName.config.$i)" = "1" ]; then + warningSummary="${warningSummary}$_WARNING_: $i setting is not supported in ${serviceName}.\\n" + fi + done +} + +check_config(){ local en; config_get_bool en "$1" 'enabled' 1; [ "$en" -gt 0 ] && _cfg_enabled=0; } +is_config_enabled(){ + local cfg="$1" _cfg_enabled=1 + [ -n "$1" ] || return 1 + config_load "$packageName" + config_foreach check_config "$cfg" + return "$_cfg_enabled" +} + +process_user_file(){ + local path enabled shellBin="${SHELL:-/bin/ash}" + config_get_bool enabled "$1" 'enabled' 1 + config_get path "$1" 'path' + [ "$enabled" -gt 0 ] || return 0 + if [ ! -s "$path" ]; then + errorSummary="${errorSummary}${_ERROR_}: Custom user file '$path' not found or empty!\\n" + output_fail + return 1 + fi + if ! $shellBin -n "$path"; then + errorSummary="${errorSummary}${_ERROR_}: Syntax error in custom user file '$path'!\\n" + output_fail + return 1 + fi + output 2 "Running $path " +# shellcheck disable=SC1090 + if ! . "$path"; then + errorSummary="${errorSummary}${_ERROR_}: Error running custom user file '$path'!\\n" + if grep -q -w 'curl' "$path" && ! is_present 'curl'; then + errorSummary="${errorSummary}${_ERROR_}: Use of 'curl' is detected in custom user file '$path', but 'curl' isn't installed!\\n" + errorSummary="${errorSummary}${_ERROR_}: If 'curl' is needed, install it with 'opkg update; opkg install curl;' command in CLI.\\n" + fi + output_fail + return 1 + else + output_ok + return 0 + fi +} + +start_service() { + local dnsmasqStoredHash dnsmasqNewHash i modprobeStatus=0 + convert_config + is_enabled 'on_start' || return 1 + is_wan_up || return 1 + if create_lock; then + if [ -s "$dnsmasqFile" ]; then + dnsmasqStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" + rm -f "$dnsmasqFile" + fi + + for i in xt_set ip_set ip_set_hash_ip; do + modprobe "$i" >/dev/null 2>/dev/null || modprobeStatus=$((modprobeStatus + 1)) + done + + if [ "$modprobeStatus" -gt 0 ] && ! is_chaos_calmer; then + errorSummary="${errorSummary}${_ERROR_}: Failed to load kernel modules\\n" + fi + + for i in $usedChainsList; do + ipt -t mangle -N "VPR_${i}" + ipt -t mangle "$insertOption" "$i" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" + done + + output 1 'Processing Interfaces ' + config_load 'network'; config_foreach process_interface 'interface' 'create'; + process_tor_interface 'tor' 'destroy'; is_tor_running && process_tor_interface 'tor' 'create'; + output 1 '\n' + if is_config_enabled 'policy'; then + output 1 'Processing Policies ' + config_load "$packageName"; config_foreach process_policy 'policy'; + output 1 '\n' + fi + if is_config_enabled 'include'; then + output 1 'Processing User File(s) ' + config_load "$packageName"; config_foreach process_user_file 'include'; + output 1 '\n' + fi + + if [ -s "$dnsmasqFile" ]; then + dnsmasqNewHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" + fi + [ "$dnsmasqNewHash" != "$dnsmasqStoredHash" ] && dnsmasq_restart + + if [ -z "$gatewaySummary" ]; then + errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway!\\n" + fi + procd_open_instance "main" + procd_set_param command /bin/true + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_open_data + json_add_array 'status' + json_add_object '' + [ -n "$gatewaySummary" ] && json_add_string gateway "$gatewaySummary" + [ -n "$errorSummary" ] && json_add_string error "$errorSummary" + [ -n "$warningSummary" ] && json_add_string warning "$warningSummary" + if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then + json_add_string mode "strict" + fi + json_close_object + json_close_array + procd_close_data + procd_close_instance + remove_lock + else + output "$serviceName: another instance of ${packageName} is currently running " + output_failn + return 1 + fi +} + +tmpfs() { + local action="$1" param="$2" value="$3" +# shellcheck disable=SC2034 + local gateway error warning mode i + if [ -s "$jsonFile" ]; then + json_load_file "$jsonFile" 2>/dev/null + json_select 'status' 2>/dev/null + for i in gateway error warning mode; do + json_get_var $i "$i" 2>/dev/null + done + fi + case "$action" in + get) + printf "%b" "$(eval echo "\$$param")"; return;; + add) + eval "$param"='$(eval echo "\$$param")${value}';; + del) + case "$param" in + all) + unset gateway error warning mode;; + *) + unset "$param";; + esac + ;; + set) + eval "$param"='$value';; + esac + json_init + json_add_object 'status' + json_add_string version "$PKG_VERSION" + for i in gateway error warning mode; do + json_add_string "$i" "$(eval echo "\$$i")" + done + json_close_object + json_dump > "$jsonFile" + sync +} + +service_started() { + tmpfs set 'gateway' "$gatewaySummary" + tmpfs set 'error' "$errorSummary" + tmpfs set 'warning' "$warningSummary" + if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then + tmpfs set 'mode' 'strict' + fi + [ -n "$gatewaySummary" ] && output "$serviceName started with gateways:\\n${gatewaySummary}" + [ -n "$errorSummary" ] && output "${errorSummary}" + [ -n "$warningSummary" ] && output "${warningSummary}" + if [ -n "$errorSummary" ]; then + return 2 + elif [ -n "$warningSummary" ]; then + return 1 + else + return 0 + fi +} + +stop_service() { + local i + iptables -t mangle -L | grep -q VPR_PREROUTING || return 0 + if create_lock; then + load_package_config + for i in PREROUTING FORWARD INPUT OUTPUT; do + ipt -t mangle -D "${i}" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" + ipt -t mangle -F "VPR_${i}"; ipt -t mangle -X "VPR_${i}"; + done + config_load 'network'; config_foreach process_interface 'interface' 'destroy'; + process_tor_interface 'tor' 'destroy' + unset ifaceTableID; unset ifaceMark; + if [ -s "$dnsmasqFile" ]; then + rm -f "$dnsmasqFile" + dnsmasq_restart + fi + if [ "$serviceEnabled" -ne 0 ]; then + output "$serviceName stopped "; output_okn; + fi + remove_lock + else + output "$serviceName: another instance of ${packageName} is currently running "; output_failn; + return 1 + fi +} + +# shellcheck disable=SC2119 +service_triggers() { + local n + is_enabled || return 1 + + if [ "$procdReloadDelay" -gt 0 ] && [ "$procdReloadDelay" -lt 100 ]; then +# shellcheck disable=SC2034 + PROCD_RELOAD_DELAY=$(( procdReloadDelay * 1000 )) + fi + + procd_open_validate + validate_config + validate_policy + validate_include + procd_close_validate + + procd_open_trigger + procd_add_reload_trigger 'openvpn' + if type procd_add_service_trigger 1>/dev/null 2>&1; then + procd_add_service_trigger "service.restart" "firewall" /etc/init.d/${packageName} reload + fi + procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload + for n in $ifSupported; do procd_add_reload_interface_trigger "$n"; procd_add_interface_trigger "interface.*" "$n" /etc/init.d/${packageName} reload; done; + procd_close_trigger + + output 3 "$serviceName monitoring interfaces: $ifSupported"; output_okn; +} + +status_service() { support "$@"; } +support() { + local dist vers out id s param status set_d set_p tableCount i=0 dev dev6 j + readonly _SEPARATOR_='============================================================' + is_enabled + + json_load "$(ubus call system board)"; json_select release; json_get_var dist distribution; json_get_var vers version + if [ -n "$wanIface4" ]; then + network_get_gateway wanGW4 "$wanIface4" + dev="$(uci -q get network."${wanIface4}".ifname)" + fi + if [ -n "$wanIface6" ]; then + dev6="$(uci -q get network."${wanIface6}".ifname)" + wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}') + [ "$wanGW6" = "default" ] && wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}') + fi + while [ "${1:0:1}" = "-" ]; do param="${1//-/}"; eval "set_$param=1"; shift; done + [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" + status="$serviceName running on $dist $vers." + [ -n "$wanIface4" ] && status="$status WAN (IPv4): ${wanIface4}/${dev}/${wanGW4:-0.0.0.0}." + [ -n "$wanIface6" ] && status="$status WAN (IPv6): ${wanIface6}/${dev6}/${wanGW6:-::/0}." + { + echo "$status" + echo "$_SEPARATOR_" + dnsmasq --version 2>/dev/null | sed '/^$/,$d' + if [ -n "$1" ]; then + echo "$_SEPARATOR_" + echo "Resolving domains" + for i in $1; do + echo "$i: $(resolveip "$i" | tr '\n' ' ')" + done + fi + + echo "$_SEPARATOR_" + echo "Routes/IP Rules" + tableCount=$(ip rule list | grep -c 'fwmark') || tableCount=0 + if [ -n "$set_d" ]; then route; else route | grep '^default'; fi + if [ -n "$set_d" ]; then ip rule list; fi + i=0; while [ $i -lt $tableCount ]; do + echo "" + echo "IPv4 Table $((wanTableID + i)): $(ip -4 route show table $((wanTableID + i)))" + echo "IPv4 Table $((wanTableID + i)) Rules:" + ip -4 rule list table "$((wanTableID + i))" + i=$((i + 1)) + done + + if [ "$ipv6Enabled" -ne 0 ]; then + i=0; while [ $i -lt $tableCount ]; do + ip -6 route show table $((wanTableID + i)) | while read -r param; do + echo "IPv6 Table $((wanTableID + i)): $param" + done + i=$((i + 1)) + done + fi + + for j in Mangle NAT; do + if [ -z "$set_d" ]; then + for i in $usedChainsList; do + if iptables -v -t "$(str_to_lower $j)" -S "VPR_${i}" 1>/dev/null 2>&1; then + echo "$_SEPARATOR_" + echo "$j IP Table: $i" + iptables -v -t "$(str_to_lower $j)" -S "VPR_${i}" + if [ "$ipv6Enabled" -ne 0 ]; then + echo "$_SEPARATOR_" + echo "$j IPv6 Table: $i" + ip6tables -v -t "$(str_to_lower $j)" -S "VPR_${i}" + fi + fi + done + else + echo "$_SEPARATOR_" + echo "$j IP Table" + iptables -L -t "$(str_to_lower $j)" + if [ "$ipv6Enabled" -ne 0 ]; then + echo "$_SEPARATOR_" + echo "$j IPv6 Table" + ip6tables -L -t "$(str_to_lower $j)" + fi + fi + i=0; ifaceMark="$wanMark"; + while [ $i -lt $tableCount ]; do + if iptables -v -t "$(str_to_lower $j)" -S "VPR_MARK${ifaceMark}" 1>/dev/null 2>&1; then + echo "$_SEPARATOR_" + echo "$j IP Table MARK Chain: VPR_MARK${ifaceMark}" + iptables -v -t "$(str_to_lower $j)" -S "VPR_MARK${ifaceMark}" + ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))"; + fi + i=$((i + 1)) + done + done + + echo "$_SEPARATOR_" + echo "Current ipsets" + ipset save + if [ -s "$dnsmasqFile" ]; then + echo "$_SEPARATOR_" + echo "DNSMASQ ipsets" + cat "$dnsmasqFile" + fi + echo "$_SEPARATOR_" + } | tee -a /var/${packageName}-support + if [ -n "$set_p" ]; then + printf "%b" "Pasting to paste.ee... " + if is_present 'curl' && is_variant_installed 'libopenssl' && is_installed 'ca-bundle'; then + json_init; json_add_string "description" "${packageName}-support" + json_add_array "sections"; json_add_object '0' + json_add_string "name" "$(uci -q get system.@system[0].hostname)" + json_add_string "contents" "$(cat /var/${packageName}-support)" + json_close_object; json_close_array; payload=$(json_dump) + out=$(curl -s -k "https://api.paste.ee/v1/pastes" -X "POST" -H "Content-Type: application/json" -H "X-Auth-Token:uVOJt6pNqjcEWu7qiuUuuxWQafpHhwMvNEBviRV2B" -d "$payload") + json_load "$out"; json_get_var id id; json_get_var s success + [ "$s" = "1" ] && printf "%b" "https://paste.ee/p/$id $__OK__\\n" || printf "%b" "$__FAIL__\\n" + [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" + else + printf "%b" "$__FAIL__\\n" + printf "%b" "$_ERROR_: curl, libopenssl or ca-bundle were not found!\\nRun 'opkg update; opkg install curl libopenssl ca-bundle' to install them.\\n" + fi + else + printf "%b" "Your support details have been logged to '/var/${packageName}-support'. $__OK__\\n" + fi +} + +# shellcheck disable=SC2120 +validate_config() { + uci_validate_section "${packageName}" config "${1}" \ + 'enabled:bool:0' \ + 'strict_enforcement:bool:1' \ + 'ipv6_enabled:bool:0' \ + 'src_ipset:bool:0' \ + 'dest_ipset:bool:0' \ + 'resolver_ipset::or("", "none", "dnsmasq.ipset")' \ + 'verbosity:range(0,2):1' \ + 'wan_tid:integer:201' \ + 'wan_fw_mark:hex(8)' \ + 'fw_mask:hex(8)' \ + 'icmp_interface:string' \ + 'ignored_interface:list(string)' \ + 'supported_interface:list(string)' \ + 'boot_timeout:integer:30' \ + 'iptables_rule_option:or("", "append", "insert")' \ + 'procd_reload_delay:integer:0' \ + 'webui_enable_column:bool:0' \ + 'webui_protocol_column:bool:0' \ + 'webui_supported_protocol:list(string)' \ + 'webui_chain_column:bool:0' \ + 'webui_sorting:bool:1' \ + 'webui_show_ignore_target:bool:0' +} + +# shellcheck disable=SC2120 +validate_policy() { + uci_validate_section "${packageName}" policy "${1}" \ + 'name:string' \ + 'enabled:bool:0' \ + 'interface:network' \ + 'proto:or(string)' \ + 'chain:or("", "PREROUTING", "FORWARD", "INPUT", "OUTPUT")' \ + 'src_addr:list(neg(or(host,network,macaddr)))' \ + 'src_port:list(neg(or(portrange, string)))' \ + 'dest_addr:list(neg(host))' \ + 'dest_port:list(neg(or(portrange, string)))' +} + +# shellcheck disable=SC2120 +validate_include() { + uci_validate_section "${packageName}" include "${1}" \ + 'path:string' \ + 'enabled:bool:0' +} diff --git a/vpn-policy-routing/files/vpn-policy-routing.netflix.user b/vpn-policy-routing/files/vpn-policy-routing.netflix.user new file mode 100644 index 00000000..02335c4b --- /dev/null +++ b/vpn-policy-routing/files/vpn-policy-routing.netflix.user @@ -0,0 +1,37 @@ +#!/bin/sh +# This file is heavily based on code from https://github.com/Xentrk/netflix-vpn-bypass/blob/master/IPSET_Netflix.sh +# Credits to https://forum.openwrt.org/u/dscpl for api.hackertarget.com code. +# Credits to https://github.com/kkeker and https://github.com/tophirsch for api.bgpview.io code. + +TARGET_IPSET='wan' +TARGET_ASN='2906' +TARGET_FNAME="/var/vpn-policy-routing_tmp_AS${TARGET_ASN}" +#DB_SOURCE='ipinfo.io' +#DB_SOURCE='api.hackertarget.com' +DB_SOURCE='api.bgpview.io' + +_ret=1 + +if [ ! -s "$TARGET_FNAME" ]; then + if [ "$DB_SOURCE" = "ipinfo.io" ]; then + TARGET_URL="https://ipinfo.io/AS${TARGET_ASN}" + curl "$TARGET_URL" 2>/dev/null | grep -E "a href.*${TARGET_ASN}\/" | grep -v ":" | sed "s/^.*//" > "$TARGET_FNAME" + fi + + if [ "$DB_SOURCE" = "api.hackertarget.com" ]; then + TARGET_URL="https://api.hackertarget.com/aslookup/?q=AS${TARGET_ASN}" + curl "$TARGET_URL" 2>/dev/null | sed '1d' > "$TARGET_FNAME" + fi + + if [ "$DB_SOURCE" = "api.bgpview.io" ]; then + TARGET_URL="https://api.bgpview.io/asn/${TARGET_ASN}/prefixes" + curl -s "$TARGET_URL" 2>/dev/null | jsonfilter -e '@.data.ipv4_prefixes[*].prefix' > "$TARGET_FNAME" + fi +fi + +if [ -s "$TARGET_FNAME" ]; then + awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_FNAME" | ipset restore -! && _ret=0 +fi +rm -f "$TARGET_FNAME" + +return $_ret diff --git a/vpn-policy-routing/test.sh b/vpn-policy-routing/test.sh new file mode 100644 index 00000000..45469ed9 --- /dev/null +++ b/vpn-policy-routing/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +/etc/init.d/"$1" version 2>&1 | grep "$2" diff --git a/vpnbypass/Makefile b/vpnbypass/Makefile new file mode 100644 index 00000000..618ca6a6 --- /dev/null +++ b/vpnbypass/Makefile @@ -0,0 +1,75 @@ +# Copyright 2017-2018 Stan Grishin (stangri@melmac.net) +# This is free software, licensed under the GNU General Public License v3. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=vpnbypass +PKG_VERSION:=1.3.1 +PKG_RELEASE:=10 +PKG_LICENSE:=GPL-3.0-or-later +PKG_MAINTAINER:=Stan Grishin + +include $(INCLUDE_DIR)/package.mk + +define Package/vpnbypass + SECTION:=net + CATEGORY:=Network + TITLE:=VPN Bypass Service + DEPENDS:=+ipset +iptables + PKGARCH:=all +endef + +define Package/vpnbypass/description +This service can be used to enable simple VPN split tunnelling. +Supports accessing domains, IP ranges outside of your VPN tunnel. +Also supports dedicating local ports/IP ranges for direct +internet access (outside of your VPN tunnel). +Please see the README for further information. +endef + +define Package/vpnbypass/conffiles +/etc/config/vpnbypass +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR)/files/ + $(CP) ./files/vpnbypass.init $(PKG_BUILD_DIR)/files/vpnbypass.init + sed -i "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(PKG_BUILD_DIR)/files/vpnbypass.init +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/vpnbypass/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/vpnbypass.init $(1)/etc/init.d/vpnbypass + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/vpnbypass.conf $(1)/etc/config/vpnbypass + $(INSTALL_DIR) $(1)/etc/hotplug.d/firewall + $(INSTALL_DATA) ./files/vpnbypass.hotplug $(1)/etc/hotplug.d/firewall/94-vpnbypass +endef + +define Package/vpnbypass/postinst + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/vpnbypass enable + fi + exit 0 +endef + +define Package/vpnbypass/prerm + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + echo "Stopping service and removing rc.d symlink for vpnbypass" + /etc/init.d/vpnbypass stop || true + /etc/init.d/vpnbypass disable || true + fi + exit 0 +endef + +$(eval $(call BuildPackage,vpnbypass)) diff --git a/vpnbypass/files/README.md b/vpnbypass/files/README.md new file mode 100644 index 00000000..50fdb8c9 --- /dev/null +++ b/vpnbypass/files/README.md @@ -0,0 +1,100 @@ + +# VPN Bypass + +[![HitCount](http://hits.dwyl.com/stangri/openwrt/vpnbypass.svg)](http://hits.dwyl.com/stangri/openwrt/vpnbypass) + +A simple [procd](https://openwrt.org/docs/techref/procd)-based ```vpnbypass``` service for OpenWrt/LEDE Project. This is useful if your router accesses Internet through a VPN client/tunnel, but you want specific traffic (ports, IP ranges, domains or local IP ranges) to be routed outside of this tunnel. + +## Features + +- Define local ports so traffic to them is routed outside of the VPN tunnel (by default it routes Plex Media Server traffic (port 32400) outside of the VPN tunnel). +- Define IPs/subnets in local networks so their traffic is routed outside the VPN tunnel (by default it routes traffic from 192.168.1.81-192.168.1.87 outside the VPN tunnel). +- Define remote IP ranges that are accessed outside the VPN tunnel (by default, LogmeIn Hamachi traffic (25.0.0.0/8) is routed outside the VPN tunnel). +- Creates list of domain names which should be accessed outside the VPN tunnel (useful for Netflix, Hulu, etc). +- Does not reside in RAM -- creates `iptables` rules which are automatically updated on WAN up/down events. +- A companion package (`luci-app-vpnbypass`) is provided so all features may be configured from the Web UI. +- Proudly made in Canada, using locally-sourced electrons. + +## Screenshot (luci-app-vpnbypass) + +![screenshot](https://cdn.jsdelivr.net/gh/stangri/openwrt_packages/screenshots/vpnbypass/screenshot02.png "screenshot") + +## Requirements + +This service requires the following packages to be installed on your router: ```ipset``` and ```iptables```. Additionally, if you want to use the Domain Bypass feature, you need to install ```dnsmasq-full``` (```dnsmasq-full``` requires you uninstall ```dnsmasq``` first). + +To fully satisfy the requirements for both IP/Port VPN Bypass and Domain Bypass features connect via ssh to your router and run the following commands: + +```sh +opkg update; opkg remove dnsmasq; opkg install ipset iptables dnsmasq-full +``` + +To satisfy the requirements for just IP/Port VPN Bypass connect to your router via ssh and run the following commands: + +```sh +opkg update; opkg install ipset iptables +``` + +### Unmet dependencies + +If you are running a development (trunk/snapshot) build of OpenWrt/LEDE Project on your router and your build is outdated (meaning that packages of the same revision/commit hash are no longer available and when you try to satisfy the [requirements](#requirements) you get errors), please flash either current LEDE release image or current development/snapshot image. + +## How to install + + +Please ensure that the [requirements](#requirements) are satisfied and install ```vpnbypass``` and ```luci-app-vpnbypass``` from the Web UI or connect to your router via ssh and run the following commands: + +```sh +opkg update +opkg install vpnbypass luci-app-vpnbypass +``` + +If these packages are not found in the official feed/repo for your version of OpenWrt/LEDE Project, you will need to add a custom repo to your router following instructions on [GitHub](https://github.com/stangri/openwrt_packages/blob/master/README.md#on-your-router)/[jsDelivr](https://cdn.jsdelivr.net/gh/stangri/openwrt_packages/README.md#on-your-router) first. + +These packages have been designed to be backwards compatible with OpenWrt 19.07, OpenWrt 18.06, LEDE Project 17.01 and OpenWrt 15.05. However, on systems older than OpenWrt 18.06.6 and/or a system which has deviated too far (or haven't been updated to keep in-sync) with official OpenWrt release you may get a message about missing ```luci-compat``` dependency, which (and only which) you can safely ignore and force-install the luci app using ```opkg install --force-depends``` command instead of ```opkg install```. + +## Default Settings + +The default configuration ships with the service disabled, use the Web UI to enable/start the service or run ```uci set vpnbypass.config.enabled=1; uci commit vpnbypass;```. It routes Plex Media Server traffic (port 32400) and LogmeIn Hamachi traffic (25.0.0.0/8) outside of the VPN tunnel. Internet traffic from local IPs `192.168.1.81-192.168.1.87` is also routed outside the VPN tunnel. You can safely delete these example rules if they do not apply to you. + +## Documentation / Discussion + +Please head to [OpenWrt Forum](https://forum.openwrt.org/t/vpn-bypass-split-tunneling-service-luci-ui/1106) for discussions of this service. + +### Bypass Domains Format/Syntax + +Domain lists should be in the following format/syntax: ```/domain1.com/domain2.com/vpnbypass```. Please do not forget the leading ```/``` and trailing ```/vpnbypass```. There is no validation if you enter something incorrectly -- it simply will not work. Please see [Notes/Known Issues](#notesknown-issues) if you wish to edit this setting manually, without using the Web UI. + +## What's New + +1.3.0: + +- No longer depends on hardcoded WAN interface name (```wan```) works with other interface names (like ```wwan```). +- Table ID, IPSET name and FW_MARK as well as FW_MASK can be defined in config file. +- Uses iptables, not ip rules for handling local IPs/ranges. +- More reliable creation/destruction of VPNBYPASS iptables chain. +- Updated Web UI enables, starts and stops the service. + +## Notes/Known Issues + +1. Domains to be accessed outside of VPN tunnel are handled by dnsmasq and thus are not defined in ```/etc/config/vpnpass```, but rather in ```/etc/config/dhcp```. To add/delete/edit domains you can use VPN Bypass Web UI or you can edit ```/etc/config/dhcp``` manually or run the following commands: + +```sh +uci add_list dhcp.@dnsmasq[-1].ipset='/github.com/plex.tv/google.com/vpnbypass' +uci add_list dhcp.@dnsmasq[-1].ipset='/hulu.com/netflix.com/nhl.com/vpnbypass' +uci commit dhcp +/etc/init.d/dnsmasq restart +``` + +This feature requires ```dnsmasq-full``` to work. See the [Requirements](#requirements) section for more details. diff --git a/vpnbypass/files/vpnbypass.conf b/vpnbypass/files/vpnbypass.conf new file mode 100644 index 00000000..0768e865 --- /dev/null +++ b/vpnbypass/files/vpnbypass.conf @@ -0,0 +1,5 @@ +config vpnbypass 'config' + option enabled '0' + list localport '32400' + list localsubnet '192.168.1.81/29' + list remotesubnet '25.0.0.0/8' diff --git a/vpnbypass/files/vpnbypass.hotplug b/vpnbypass/files/vpnbypass.hotplug new file mode 100644 index 00000000..a2874f97 --- /dev/null +++ b/vpnbypass/files/vpnbypass.hotplug @@ -0,0 +1,2 @@ +#!/bin/sh +[ "$ACTION" = "reload" ] && /etc/init.d/vpnbypass reload diff --git a/vpnbypass/files/vpnbypass.init b/vpnbypass/files/vpnbypass.init new file mode 100644 index 00000000..67f3a6e6 --- /dev/null +++ b/vpnbypass/files/vpnbypass.init @@ -0,0 +1,138 @@ +#!/bin/sh /etc/rc.common +# Copyright 2017-2020 Stan Grishin (stangri@melmac.net) +# shellcheck disable=SC2039,SC1091,SC2086 +PKG_VERSION='dev-test' + +# shellcheck disable=SC2034 +START=94 +# shellcheck disable=SC2034 +USE_PROCD=1 + +# shellcheck disable=SC2034 +EXTRA_COMMANDS="version" +EXTRA_HELP=" version Print version information" +version() { echo "$PKG_VERSION"; } + +readonly __ERROR__='\033[0;31mERROR\033[0m' + +# shellcheck disable=SC2034 +serviceEnabled=0 +verbosity=2 +TID='200' +IPSET='vpnbypass' +FW_MARK='0x010000' +FW_MASK='0xff0000' +wan_if4='' +wan_gw='' + +readonly packageName='vpnbypass' +readonly serviceName="$packageName $PKG_VERSION" +readonly sharedMemoryOutput="/dev/shm/$packageName-output" + +output() { +# Can take a single parameter (text) to be output at any verbosity +# Or target verbosity level and text to be output at specifc verbosity + local msg memmsg logmsg + if [ $# -ne 1 ]; then + if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi + fi + [ -t 1 ] && printf "%b" "$1" + msg="${1//$serviceName /service }"; + if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then + [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")" + logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')" + logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")" + rm -f "$sharedMemoryOutput" + else + printf "%b" "$msg" >> "$sharedMemoryOutput" + fi +} +load_package_config() { + config_load "$packageName" + config_get_bool serviceEnabled 'config' 'enabled' 1 + config_get verbosity 'config' 'verbosity' '2' + if [ -z "${verbosity##*[!0-9]*}" ] || [ "$verbosity" -lt 0 ] || [ "$verbosity" -gt 2 ]; then + verbosity=1 + fi + . /lib/functions/network.sh +} + +is_enabled() { + local sleepCount=1 + load_package_config + while : ; do + network_find_wan wan_if4 + [ "$serviceEnabled" -gt 0 ] || return 1 + [ -n "$wan_if4" ] && network_get_gateway wan_gw "$wan_if4" + if [ $sleepCount -ge 25 ] || [ -n "$wan_gw" ]; then break; fi + output "$serviceName waiting for wan gateway...\\n" + sleep 2; network_flush_cache; let "sleepCount+=1"; + done + [ -n "$wan_gw" ] && return 0 + output "$__ERROR__: $serviceName failed to discover WAN gateway.\\n"; return 1; +} + +is_ovpn() { local dev; dev=$(uci -q get network."$1".ifname); if [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; then return 0; else return 1; fi; } +is_wan() { if [ -n "$wan_if4" ] && [ "$1" = "$wan_if4" ]; then return 0; else return 1; fi; } +is_supported_interface() { if is_wan "$1" || is_ovpn "$1"; then return 0; else return 1; fi; } + +ipt() { + local d; + d="${*//-A/-D}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 + d="${*//-I/-D}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 + d="${*//-N/-F}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 + d="${*//-N/-X}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 + d="$*"; iptables $d >/dev/null 2>&1 || output "\\n$__ERROR__: iptables $d\\n" +} + +start_service() { + local ll lports rports routes ranges + is_enabled || return 1 + config_get lports 'config' 'localport' + config_get rports 'config' 'remoteport' + config_get routes 'config' 'remotesubnet' + config_get ranges 'config' 'localsubnet' + + procd_open_instance "main" + procd_set_param command /bin/true + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_close_instance + + ipt -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS >/dev/null 2>&1 + { ipt -t mangle -N VPNBYPASS; ipt -t mangle -A PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS; } >/dev/null 2>&1 + ipt -t mangle -A VPNBYPASS -m set --match-set $IPSET dst -j MARK --set-mark ${FW_MARK}/${FW_MASK} >/dev/null 2>&1 + ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; + ipset -q flush "$IPSET"; ipset -q destroy "$IPSET"; + ip route flush table "$TID"; ip route flush cache; + ip route add default via "$wan_gw" table "$TID"; ip route flush cache; + ipset -q -exist create "$IPSET" hash:ip; ipset -q flush "$IPSET" + ip rule add fwmark "$FW_MARK" table "$TID" + { modprobe xt_set; modprobe ip_set; modprobe ip_set_hash_ip; } >/dev/null 2>&1 + for ll in ${ranges}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -s "$ll"; done + for ll in ${lports}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --sport "${ll//-/:}"; done + for ll in ${routes}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -d "$ll"; done + for ll in ${rports}; do ipt -t mangle -I VPNBYPASS 1 -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --dport "${ll//-/:}"; done + output "$serviceName started with TID: $TID; FW_MARK: $FW_MARK\\n" +} + +stop_service() { + load_package_config + ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; + ipset -q flush "$IPSET"; ipset -q destroy "$IPSET"; + ip route flush table "$TID"; ip route flush cache; + ipt -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS >/dev/null 2>&1 + { ipt -t mangle -F VPNBYPASS; ipt -t mangle -X VPNBYPASS; } >/dev/null 2>&1 + output "$serviceName stopped\\n" +} + +service_triggers_load_interface() { is_supported_interface "$1" && ifaces="${ifaces}${1} "; } +service_triggers() { + local ifaces n + config_load network; config_foreach service_triggers_load_interface 'interface'; + procd_add_reload_trigger 'firewall' 'openvpn' 'vpnbypass' + procd_open_trigger + for n in $ifaces; do procd_add_reload_interface_trigger "$n"; procd_add_interface_trigger "interface.*" "$n" /etc/init.d/vpnbypass reload; done; + output "$serviceName monitoring interfaces: $ifaces\\n" + procd_close_trigger +} diff --git a/vpnbypass/test.sh b/vpnbypass/test.sh new file mode 100644 index 00000000..e51c4805 --- /dev/null +++ b/vpnbypass/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +/etc/init.d/"$1" version 2>&1 | grep "$2" \ No newline at end of file diff --git a/xray-core/Makefile b/xray-core/Makefile new file mode 100644 index 00000000..481e0342 --- /dev/null +++ b/xray-core/Makefile @@ -0,0 +1,50 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=xray-core +PKG_VERSION:=26.3.27 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=992a4997e6bb846d11469435d687f99ef812fcde1e0a009bb8e95189ea20331d + +PKG_MAINTAINER:=Tianling Shen +PKG_LICENSE:=MPL-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DIR:=$(BUILD_DIR)/Xray-core-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/xtls/xray-core +GO_PKG_LDFLAGS:=-s -w +GO_PKG_BUILD_PKG:=$(GO_PKG)/main +GO_PKG_LDFLAGS_X:= \ + $(GO_PKG)/core.build=OpenWrt \ + $(GO_PKG)/core.version=$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/xray-core + TITLE:=A platform for building proxies to bypass network restrictions + SECTION:=net + CATEGORY:=Network + URL:=https://xtls.github.io + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/xray-core/description + Xray, Penetrates Everything. It helps you to build your own computer network. + It secures your network connections and thus protects your privacy. +endef + +define Package/xray-core/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/main $(1)/usr/bin/xray +endef + +$(eval $(call BuildPackage,xray-core)) diff --git a/xray-plugin/Makefile b/xray-plugin/Makefile new file mode 100644 index 00000000..64666a1a --- /dev/null +++ b/xray-plugin/Makefile @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=xray-plugin +PKG_VERSION:=1.8.24 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/teddysun/xray-plugin/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=1150968f8791df884ce0ab5b2dbc870496088c90b5ffcc7f21497075aab7b1b5 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_BUILD_FLAGS:=no-mips16 + +GO_PKG:=github.com/teddysun/xray-plugin + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/xray-plugin + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=SIP003 plugin for Shadowsocks, based on Xray + URL:=https://github.com/teddysun/xray-plugin + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +$(eval $(call GoBinPackage,xray-plugin)) +$(eval $(call BuildPackage,xray-plugin))