diff --git a/UnblockNeteaseMusic-Go/Makefile b/UnblockNeteaseMusic-Go/Makefile new file mode 100644 index 000000000..c329b0ac0 --- /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 $(TOPDIR)/feeds/packages/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 000000000..bea3f7b04 --- /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 000000000..73e2fa6ec --- /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 000000000..6bd769c11 --- /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 000000000..3aa24d705 --- /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 000000000..ad2e8db7e --- /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 000000000..23e5b3ab9 --- /dev/null +++ b/UnblockNeteaseMusic/Makefile @@ -0,0 +1,52 @@ +# SPDX-Identifier-License: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=UnblockNeteaseMusic +PKG_BASE_VERSION:=0.27.0 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/UnblockNeteaseMusic/server.git +PKG_SOURCE_DATE:=2022-10-09 +PKG_SOURCE_VERSION:=253dc89329ebd16ff22175d9d0ab9382ed8aaccc +PKG_MIRROR_HASH:=c2ed5f269c1935575c57ed5489504ef37f453b2a512209bf0762a55fc3eb4b29 + +PKG_VERSION:=$(PKG_BASE_VERSION)-$(PKG_SOURCE_DATE)-$(call version_abbrev,$(PKG_SOURCE_VERSION)) + +PKG_LICENSE:=LGPL-3.0-only +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +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 Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + xzcat $(DL_DIR)/$(PKG_SOURCE) | $(TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS) +endef + +define Build/Configure + echo -e $(PKG_BASE_VERSION) > $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/core_ver + echo -e $(PKG_SOURCE_VERSION) > $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/local_ver +endef + +define Build/Compile +endef + +define Package/UnblockNeteaseMusic/install + $(INSTALL_DIR) $(1)/usr/share/UnblockNeteaseMusic + $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/* $(1)/usr/share/UnblockNeteaseMusic +endef + +$(eval $(call BuildPackage,UnblockNeteaseMusic)) diff --git a/amule/Makefile b/amule/Makefile new file mode 100644 index 000000000..89841fe1c --- /dev/null +++ b/amule/Makefile @@ -0,0 +1,109 @@ +# +# Copyright (C) 2007-2009 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:=aMule +PKG_VERSION:=2.3.3 +PKG_RELEASE:=3 +PKG_REV=4b87b20 + + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-r$(PKG_REV).tar.bz2 +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=$(PKG_REV) +PKG_SOURCE_URL:=https://github.com/amule-project/amule.git +PKG_MIRROR_HASH:=102c4cb3dd2858db06fff19c5e2d0b65c6731b366f45df2adcd40fd0cd0fec47 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=libgd libcryptopp + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/amule/config +config AMULE_CRYPTOPP_STATIC_LINKING + bool "Link libcryptopp statically" + default n +endef + +define Package/amule + SUBMENU:=P2P + SECTION:=net + CATEGORY:=Network + TITLE:=A multi-platform eMule-like ed2k client + URL:=http://www.amule.org/ + DEPENDS:=+libpng +libpthread +libncurses +libreadline +libwxbase +libupnp +libbfd \ + $(ICONV_DEPENDS) $(INTL_DEPENDS) +!AMULE_CRYPTOPP_STATIC_LINKING:libcryptopp +endef + +CONFIGURE_ARGS+= \ + --disable-static \ + --disable-rpath \ + --with-gnu-ld \ + --disable-ccache \ + --disable-optimize \ + --disable-profile \ + --disable-monolithic \ + --enable-amule-daemon \ + --enable-amulecmd \ + --enable-webserver \ + --disable-amule-gui \ + --disable-cas \ + --disable-wxcas \ + --disable-ed2k \ + --disable-alc \ + --disable-alcc \ + --disable-fileview \ + --disable-plasmamule \ + --without-wxdebug \ + --enable-dlp \ + --enable-upnp \ + --with-zlib="$(STAGING_DIR)/usr" \ + --with-gdlib-prefix="$(STAGING_DIR)/usr" \ + --with-libpng-prefix="$(STAGING_DIR)/usr" \ + --with-wx-prefix="$(STAGING_DIR)/usr" \ + --with-crypto-prefix="$(STAGING_DIR)/usr" \ + --with-libiconv-prefix="$(ICONV_PREFIX)" \ + --with-libintl-prefix="$(INTL_PREFIX)" \ + --with-libupnp-prefix="$(STAGING_DIR)/usr" \ + --without-x \ + --disable-debug + +TARGET_LDFLAGS += $(if $(ICONV_FULL),-liconv) + +define Build/Configure + cd $(PKG_BUILD_DIR) && sh ./autogen.sh + $(call Build/Configure/Default) +endef + +ifeq ($(CONFIG_AMULE_CRYPTOPP_STATIC_LINKING),y) + SED_CMD:=sed +else + SED_CMD:=true +endif + +define Build/Compile + $(SED_CMD) -i 's;^CRYPTOPP_LIBS.*;CRYPTOPP_LIBS \= "$(STAGING_DIR)/usr/lib/libcryptopp.a";g' \ + $(PKG_BUILD_DIR)/src/Makefile + $(MAKE) -C $(PKG_BUILD_DIR) \ + HOSTCC="$(HOSTCC)" \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + all +endef + +define Package/amule/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_DIR) $(1)/usr/share/amule/webserver + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/amule{cmd,d} $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/webserver/src/amuleweb $(1)/usr/bin/ + $(CP) $(PKG_BUILD_DIR)/src/webserver/default $(1)/usr/share/amule/webserver + +endef + +$(eval $(call BuildPackage,amule)) diff --git a/amule/patches/0001-fix-API-mismatch-with-crypto-6.0.0.patch b/amule/patches/0001-fix-API-mismatch-with-crypto-6.0.0.patch new file mode 100644 index 000000000..84f64f8b9 --- /dev/null +++ b/amule/patches/0001-fix-API-mismatch-with-crypto-6.0.0.patch @@ -0,0 +1,25 @@ +From 46ecaeadff4c07b8fd98cf41e27605895328ce0a Mon Sep 17 00:00:00 2001 +From: W_Y_CPP <383152993@qq.com> +Date: Thu, 2 Dec 2021 00:46:12 -0800 +Subject: [PATCH] fix API mismatch with crypto++ 6.0.0 + +--- + src/ClientCreditsList.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ClientCreditsList.cpp b/src/ClientCreditsList.cpp +index d61e8d4..b02e162 100644 +--- a/src/ClientCreditsList.cpp ++++ b/src/ClientCreditsList.cpp +@@ -312,7 +312,7 @@ void CClientCreditsList::InitalizeCrypting() + // calculate and store public key + CryptoPP::RSASSA_PKCS1v15_SHA_Verifier pubkey(*static_cast(m_pSignkey)); + CryptoPP::ArraySink asink(m_abyMyPublicKey, 80); +- pubkey.DEREncode(asink); ++ pubkey.GetMaterial().Save(asink); + m_nMyPublicKeyLen = asink.TotalPutLength(); + asink.MessageEnd(); + } catch (const CryptoPP::Exception& e) { +-- +2.17.1 + diff --git a/amule/patches/0002-fix-byte-type-error.patch b/amule/patches/0002-fix-byte-type-error.patch new file mode 100644 index 000000000..da60d22ac --- /dev/null +++ b/amule/patches/0002-fix-byte-type-error.patch @@ -0,0 +1,2285 @@ +From 3817cad41242b0cf376e6e69da22f32ae8f32355 Mon Sep 17 00:00:00 2001 +From: W_Y_CPP <383152993@qq.com> +Date: Thu, 2 Dec 2021 00:51:00 -0800 +Subject: [PATCH] fix byte type error + +--- + src/BarShader.cpp | 2 +- + src/BaseClient.cpp | 28 +++++++++--------- + src/BitVector.h | 2 +- + src/ClientCredits.cpp | 4 +-- + src/ClientCredits.h | 8 +++--- + src/ClientCreditsList.cpp | 14 ++++----- + src/ClientCreditsList.h | 8 +++--- + src/ClientList.cpp | 2 +- + src/ClientTCPSocket.cpp | 8 +++--- + src/ClientTCPSocket.h | 6 ++-- + src/ClientUDPSocket.cpp | 4 +-- + src/ClientUDPSocket.h | 4 +-- + src/DownloadClient.cpp | 18 ++++++------ + src/DownloadQueue.cpp | 8 +++--- + src/EMSocket.cpp | 6 ++-- + src/EMSocket.h | 6 ++-- + src/EncryptedDatagramSocket.cpp | 10 +++---- + src/EncryptedStreamSocket.cpp | 10 +++---- + src/FileArea.cpp | 10 +++---- + src/FileArea.h | 8 +++--- + src/FileLock.h | 2 +- + src/GapList.h | 2 +- + src/IPFilterScanner.cpp | 2 +- + src/KnownFile.cpp | 12 ++++---- + src/KnownFile.h | 2 +- + src/MemFile.cpp | 8 +++--- + src/MemFile.h | 10 +++---- + src/MuleCollection.cpp | 2 +- + src/MuleColour.h | 18 ++++++------ + src/MuleUDPSocket.cpp | 2 +- + src/MuleUDPSocket.h | 2 +- + src/OtherFunctions.cpp | 32 ++++++++++----------- + src/Packet.cpp | 36 ++++++++++++------------ + src/Packet.h | 26 ++++++++--------- + src/Parser.cpp | 2 +- + src/PartFile.cpp | 6 ++-- + src/PartFile.h | 2 +- + src/PartFileConvert.cpp | 2 +- + src/PrefsUnifiedDlg.cpp | 2 +- + src/RLE.cpp | 4 +-- + src/SHA.cpp | 18 ++++++------ + src/SHA.h | 4 +-- + src/SHAHashSet.h | 8 +++--- + src/SafeFile.cpp | 2 +- + src/Scanner.cpp | 2 +- + src/SearchList.cpp | 4 +-- + src/SearchList.h | 2 +- + src/ServerList.cpp | 4 +-- + src/ServerSocket.cpp | 2 +- + src/ServerSocket.h | 2 +- + src/ServerUDPSocket.cpp | 10 +++---- + src/ServerUDPSocket.h | 2 +- + src/Statistics.cpp | 2 +- + src/Tag.cpp | 4 +-- + src/Tag.h | 12 ++++---- + src/ThreadTasks.cpp | 4 +-- + src/UploadBandwidthThrottler.cpp | 2 +- + src/UploadClient.cpp | 10 +++---- + src/kademlia/kademlia/Kademlia.cpp | 2 +- + src/kademlia/kademlia/Search.cpp | 2 +- + src/kademlia/kademlia/SearchManager.cpp | 4 +-- + src/kademlia/net/KademliaUDPListener.cpp | 2 +- + src/libs/common/StringFunctions.cpp | 4 +-- + src/libs/ec/cpp/ECSocket.cpp | 12 ++++---- + src/libs/ec/cpp/ECTag.cpp | 4 +-- + src/updownclient.h | 36 ++++++++++++------------ + src/utils/aLinkCreator/src/md4.cpp | 8 +++--- + src/utils/aLinkCreator/src/md4.h | 2 +- + src/utils/fileview/KadFiles.cpp | 4 +-- + 69 files changed, 257 insertions(+), 257 deletions(-) + +diff --git a/src/BarShader.cpp b/src/BarShader.cpp +index 047f90d..9ddfd51 100644 +--- a/src/BarShader.cpp ++++ b/src/BarShader.cpp +@@ -124,7 +124,7 @@ void CBarShader::FillRange(uint64 start, uint64 end, const CMuleColour& colour) + } + + // precision for small files: end must be increased by one +- // think of each byte as a visible block, then start points to ++ // think of each uint8_t as a visible block, then start points to + // the beginning of its block, but end points to the END of its block + end++; + +diff --git a/src/BaseClient.cpp b/src/BaseClient.cpp +index cf1093a..aa77e69 100644 +--- a/src/BaseClient.cpp ++++ b/src/BaseClient.cpp +@@ -361,7 +361,7 @@ void CUpDownClient::ClearHelloProperties() + m_bUnicodeSupport = false; + } + +-bool CUpDownClient::ProcessHelloPacket(const byte* pachPacket, uint32 nSize) ++bool CUpDownClient::ProcessHelloPacket(const uint8_t* pachPacket, uint32 nSize) + { + const CMemFile data(pachPacket,nSize); + uint8 hashsize = data.ReadUInt8(); +@@ -459,7 +459,7 @@ void CUpDownClient::Safe_Delete() + } + + +-bool CUpDownClient::ProcessHelloAnswer(const byte* pachPacket, uint32 nSize) ++bool CUpDownClient::ProcessHelloAnswer(const uint8_t* pachPacket, uint32 nSize) + { + const CMemFile data(pachPacket,nSize); + bool bIsMule = ProcessHelloTypePacket(data); +@@ -840,7 +840,7 @@ void CUpDownClient::SendMuleInfoPacket(bool bAnswer, bool OSInfo) + } + } + +-bool CUpDownClient::ProcessMuleInfoPacket(const byte* pachPacket, uint32 nSize) ++bool CUpDownClient::ProcessMuleInfoPacket(const uint8_t* pachPacket, uint32 nSize) + { + uint8 protocol_version; + +@@ -1173,7 +1173,7 @@ void CUpDownClient::SendHelloTypePacket(CMemFile* data) + } + + +-void CUpDownClient::ProcessMuleCommentPacket(const byte* pachPacket, uint32 nSize) ++void CUpDownClient::ProcessMuleCommentPacket(const uint8_t* pachPacket, uint32 nSize) + { + if (!m_reqfile) { + throw CInvalidPacket(wxT("Comment packet for unknown file")); +@@ -1977,7 +1977,7 @@ void CUpDownClient::RequestSharedFileList() + } + + +-void CUpDownClient::ProcessSharedFileList(const byte* pachPacket, uint32 nSize, wxString& pszDirectory) ++void CUpDownClient::ProcessSharedFileList(const uint8_t* pachPacket, uint32 nSize, wxString& pszDirectory) + { + if (m_iFileListRequested > 0) { + m_iFileListRequested--; +@@ -2103,7 +2103,7 @@ void CUpDownClient::SendSignaturePacket() + } + } + //end v2 +- byte achBuffer[250]; ++ uint8_t achBuffer[250]; + + uint8 siglen = theApp->clientcredits->CreateSignature(credits, achBuffer, 250, ChallengeIP, byChaIPKind ); + wxCHECK2(siglen != 0, return); +@@ -2124,7 +2124,7 @@ void CUpDownClient::SendSignaturePacket() + } + + +-void CUpDownClient::ProcessPublicKeyPacket(const byte* pachPacket, uint32 nSize) ++void CUpDownClient::ProcessPublicKeyPacket(const uint8_t* pachPacket, uint32 nSize) + { + theApp->clientlist->AddTrackClient(this); + +@@ -2160,7 +2160,7 @@ void CUpDownClient::ProcessPublicKeyPacket(const byte* pachPacket, uint32 nSize) + } + + +-void CUpDownClient::ProcessSignaturePacket(const byte* pachPacket, uint32 nSize) ++void CUpDownClient::ProcessSignaturePacket(const uint8_t* pachPacket, uint32 nSize) + { + // here we spread the good guys from the bad ones ;) + +@@ -2248,7 +2248,7 @@ void CUpDownClient::SendSecIdentStatePacket() + } + + +-void CUpDownClient::ProcessSecIdentStatePacket(const byte* pachPacket, uint32 nSize) ++void CUpDownClient::ProcessSecIdentStatePacket(const uint8_t* pachPacket, uint32 nSize) + { + if ( nSize != 5 ) { + return; +@@ -2344,7 +2344,7 @@ void CUpDownClient::SendPublicIPRequest() + } + } + +-void CUpDownClient::ProcessPublicIPAnswer(const byte* pbyData, uint32 uSize) ++void CUpDownClient::ProcessPublicIPAnswer(const uint8_t* pbyData, uint32 uSize) + { + if (uSize != 4) { + throw wxString(wxT("Wrong Packet size on Public IP answer")); +@@ -2527,7 +2527,7 @@ bool CUpDownClient::SendChatMessage(const wxString& message) + + /* Kad stuff */ + +-void CUpDownClient::SetBuddyID(const byte* pucBuddyID) ++void CUpDownClient::SetBuddyID(const uint8_t* pucBuddyID) + { + if( pucBuddyID == NULL ){ + md4clr(m_achBuddyID); +@@ -2722,7 +2722,7 @@ void CUpDownClient::ProcessChatMessage(wxString message) + m_strCaptchaChallenge = captcha.GetCaptchaText(); + m_nChatCaptchaState = CA_CHALLENGESENT; + m_cCaptchasSent++; +- CMemFile fileAnswer((byte*) memstr.GetOutputStreamBuffer()->GetBufferStart(), memstr.GetLength()); ++ CMemFile fileAnswer((uint8_t*) memstr.GetOutputStreamBuffer()->GetBufferStart(), memstr.GetLength()); + CPacket* packet = new CPacket(fileAnswer, OP_EMULEPROT, OP_CHATCAPTCHAREQ); + theStats::AddUpOverheadOther(packet->GetPacketSize()); + AddLogLineN(CFormat(wxT("sent Captcha %s (%d)")) % m_strCaptchaChallenge % packet->GetPacketSize()); +@@ -2756,7 +2756,7 @@ void CUpDownClient::ProcessChatMessage(wxString message) + m_cCaptchasSent = 0; + m_strCaptchaChallenge.Clear(); + CPacket* packet = new CPacket(OP_CHATCAPTCHARES, 1, OP_EMULEPROT, false); +- byte statusResponse = 0; // status response ++ uint8_t statusResponse = 0; // status response + packet->CopyToDataBuffer(0, &statusResponse, 1); + theStats::AddUpOverheadOther(packet->GetPacketSize()); + SafeSendPacket(packet); +@@ -2766,7 +2766,7 @@ void CUpDownClient::ProcessChatMessage(wxString message) + m_strCaptchaChallenge.Clear(); + m_strCaptchaPendingMsg.Clear(); + CPacket* packet = new CPacket(OP_CHATCAPTCHARES, 1, OP_EMULEPROT, false); +- byte statusResponse = (m_cCaptchasSent < 3) ? 1 : 2; // status response ++ uint8_t statusResponse = (m_cCaptchasSent < 3) ? 1 : 2; // status response + packet->CopyToDataBuffer(0, &statusResponse, 1); + theStats::AddUpOverheadOther(packet->GetPacketSize()); + SafeSendPacket(packet); +diff --git a/src/BitVector.h b/src/BitVector.h +index 9576a11..f4f2474 100644 +--- a/src/BitVector.h ++++ b/src/BitVector.h +@@ -113,7 +113,7 @@ public: + bool foundFalse = false; + uint32 lastByte = m_bytes; + if (m_bits & 7) { +- // uneven: check bits of last byte individually ++ // uneven: check bits of last uint8_t individually + lastByte--; + for (uint32 i = m_bits & 0xfffffff8; !foundFalse && i < m_bits; i++) { + foundFalse = !get(i); +diff --git a/src/ClientCredits.cpp b/src/ClientCredits.cpp +index 2804292..6439ac8 100644 +--- a/src/ClientCredits.cpp ++++ b/src/ClientCredits.cpp +@@ -195,7 +195,7 @@ void CClientCredits::Verified(uint32 dwForIP) + memcpy(m_pCredits->abySecureIdent, m_abyPublicKey, m_nPublicKeyLen); + if (GetDownloadedTotal() > 0){ + // for security reason, we have to delete all prior credits here +- // in order to save this client, set 1 byte ++ // in order to save this client, set 1 uint8_t + m_pCredits->downloaded = 1; + m_pCredits->uploaded = 1; + AddDebugLogLineN( logCredits, wxT("Credits deleted due to new SecureIdent") ); +@@ -205,7 +205,7 @@ void CClientCredits::Verified(uint32 dwForIP) + } + + +-bool CClientCredits::SetSecureIdent(const byte* pachIdent, uint8 nIdentLen) ++bool CClientCredits::SetSecureIdent(const uint8_t* pachIdent, uint8 nIdentLen) + { // verified Public key cannot change, use only if there is not public key yet + if (MAXPUBKEYSIZE < nIdentLen || m_pCredits->nKeySize != 0 ) { + return false; +diff --git a/src/ClientCredits.h b/src/ClientCredits.h +index ae194c2..b89f7c5 100644 +--- a/src/ClientCredits.h ++++ b/src/ClientCredits.h +@@ -45,7 +45,7 @@ public: + uint32 nLastSeen; + uint16 nReserved3; + uint8 nKeySize; +- byte abySecureIdent[MAXPUBKEYSIZE]; ++ uint8_t abySecureIdent[MAXPUBKEYSIZE]; + }; + + enum EIdentState{ +@@ -65,7 +65,7 @@ public: + ~CClientCredits(); + + const CMD4Hash& GetKey() const {return m_pCredits->key;} +- const byte* GetSecureIdent() const {return m_abyPublicKey;} ++ const uint8_t* GetSecureIdent() const {return m_abyPublicKey;} + uint8 GetSecIDKeyLen() const {return m_nPublicKeyLen;} + const CreditStruct* GetDataStruct() const {return m_pCredits;} + void ClearWaitStartTime(); +@@ -75,7 +75,7 @@ public: + uint64 GetDownloadedTotal() const; + float GetScoreRatio(uint32 dwForIP, bool cryptoavail); + void SetLastSeen(); +- bool SetSecureIdent(const byte* pachIdent, uint8 nIdentLen); // Public key cannot change, use only if there is not public key yet ++ bool SetSecureIdent(const uint8_t* pachIdent, uint8 nIdentLen); // Public key cannot change, use only if there is not public key yet + uint32 m_dwCryptRndChallengeFor; + uint32 m_dwCryptRndChallengeFrom; + EIdentState GetCurrentIdentState(uint32 dwForIP) const; // can be != m_identState +@@ -89,7 +89,7 @@ private: + EIdentState m_identState; + void InitalizeIdent(); + CreditStruct* m_pCredits; +- byte m_abyPublicKey[80]; // even keys which are not verified will be stored here, and - if verified - copied into the struct ++ uint8_t m_abyPublicKey[80]; // even keys which are not verified will be stored here, and - if verified - copied into the struct + uint8 m_nPublicKeyLen; + uint32 m_dwIdentIP; + uint32 m_dwSecureWaitTime; +diff --git a/src/ClientCreditsList.cpp b/src/ClientCreditsList.cpp +index 3bea9fe..d61e8d4 100644 +--- a/src/ClientCreditsList.cpp ++++ b/src/ClientCreditsList.cpp +@@ -326,7 +326,7 @@ void CClientCreditsList::InitalizeCrypting() + } + + +-uint8 CClientCreditsList::CreateSignature(CClientCredits* pTarget, byte* pachOutput, uint8 nMaxSize, uint32 ChallengeIP, uint8 byChaIPKind, void* sigkey) ++uint8 CClientCreditsList::CreateSignature(CClientCredits* pTarget, uint8_t* pachOutput, uint8 nMaxSize, uint32 ChallengeIP, uint8 byChaIPKind, void* sigkey) + { + CryptoPP::RSASSA_PKCS1v15_SHA_Signer* signer = + static_cast(sigkey); +@@ -345,7 +345,7 @@ uint8 CClientCreditsList::CreateSignature(CClientCredits* pTarget, byte* pachOut + try { + CryptoPP::SecByteBlock sbbSignature(signer->SignatureLength()); + CryptoPP::AutoSeededX917RNG rng; +- byte abyBuffer[MAXPUBKEYSIZE+9]; ++ uint8_t abyBuffer[MAXPUBKEYSIZE+9]; + uint32 keylen = pTarget->GetSecIDKeyLen(); + memcpy(abyBuffer,pTarget->GetSecureIdent(),keylen); + // 4 additional bytes random data send from this client +@@ -373,7 +373,7 @@ uint8 CClientCreditsList::CreateSignature(CClientCredits* pTarget, byte* pachOut + } + + +-bool CClientCreditsList::VerifyIdent(CClientCredits* pTarget, const byte* pachSignature, uint8 nInputSize, uint32 dwForIP, uint8 byChaIPKind) ++bool CClientCreditsList::VerifyIdent(CClientCredits* pTarget, const uint8_t* pachSignature, uint8 nInputSize, uint32 dwForIP, uint8 byChaIPKind) + { + wxASSERT( pTarget ); + wxASSERT( pachSignature ); +@@ -383,10 +383,10 @@ bool CClientCreditsList::VerifyIdent(CClientCredits* pTarget, const byte* pachSi + } + bool bResult; + try { +- CryptoPP::StringSource ss_Pubkey((byte*)pTarget->GetSecureIdent(),pTarget->GetSecIDKeyLen(),true,0); ++ CryptoPP::StringSource ss_Pubkey((uint8_t*)pTarget->GetSecureIdent(),pTarget->GetSecIDKeyLen(),true,0); + CryptoPP::RSASSA_PKCS1v15_SHA_Verifier pubkey(ss_Pubkey); + // 4 additional bytes random data send from this client +5 bytes v2 +- byte abyBuffer[MAXPUBKEYSIZE+9]; ++ uint8_t abyBuffer[MAXPUBKEYSIZE+9]; + memcpy(abyBuffer,m_abyMyPublicKey,m_nMyPublicKeyLen); + uint32 challenge = pTarget->m_dwCryptRndChallengeFor; + wxASSERT ( challenge != 0 ); +@@ -455,7 +455,7 @@ bool CClientCreditsList::Debug_CheckCrypting(){ + CryptoPP::RSASSA_PKCS1v15_SHA_Signer priv(rng, 384); + CryptoPP::RSASSA_PKCS1v15_SHA_Verifier pub(priv); + +- byte abyPublicKey[80]; ++ uint8_t abyPublicKey[80]; + CryptoPP::ArraySink asink(abyPublicKey, 80); + pub.DEREncode(asink); + int8 PublicKeyLen = asink.TotalPutLength(); +@@ -467,7 +467,7 @@ bool CClientCreditsList::Debug_CheckCrypting(){ + newcredits.SetSecureIdent(m_abyMyPublicKey,m_nMyPublicKeyLen); + newcredits.m_dwCryptRndChallengeFrom = challenge; + // create signature with fake priv key +- byte pachSignature[200]; ++ uint8_t pachSignature[200]; + memset(pachSignature,0,200); + uint8 sigsize = CreateSignature(&newcredits,pachSignature,200,0,false, &priv); + +diff --git a/src/ClientCreditsList.h b/src/ClientCreditsList.h +index 3b3aa6c..70b3c31 100644 +--- a/src/ClientCreditsList.h ++++ b/src/ClientCreditsList.h +@@ -39,13 +39,13 @@ public: + ~CClientCreditsList(); + + // return signature size, 0 = Failed | use sigkey param for debug only +- uint8 CreateSignature(CClientCredits* pTarget, byte* pachOutput, uint8 nMaxSize, uint32 ChallengeIP, uint8 byChaIPKind, void* sigkey = NULL); +- bool VerifyIdent(CClientCredits* pTarget, const byte* pachSignature, uint8 nInputSize, uint32 dwForIP, uint8 byChaIPKind); ++ uint8 CreateSignature(CClientCredits* pTarget, uint8_t* pachOutput, uint8 nMaxSize, uint32 ChallengeIP, uint8 byChaIPKind, void* sigkey = NULL); ++ bool VerifyIdent(CClientCredits* pTarget, const uint8_t* pachSignature, uint8 nInputSize, uint32 dwForIP, uint8 byChaIPKind); + + CClientCredits* GetCredit(const CMD4Hash& key); + void Process(); + uint8 GetPubKeyLen() const {return m_nMyPublicKeyLen;} +- const byte* GetPublicKey() const {return m_abyMyPublicKey;} ++ const uint8_t* GetPublicKey() const {return m_abyMyPublicKey;} + bool CryptoAvailable() const; + void SaveList(); + protected: +@@ -61,7 +61,7 @@ private: + uint32 m_nLastSaved; + // A void* to avoid having to include the large CryptoPP.h file + void* m_pSignkey; +- byte m_abyMyPublicKey[80]; ++ uint8_t m_abyMyPublicKey[80]; + uint8 m_nMyPublicKeyLen; + }; + +diff --git a/src/ClientList.cpp b/src/ClientList.cpp +index f26cce4..9b8b7ec 100644 +--- a/src/ClientList.cpp ++++ b/src/ClientList.cpp +@@ -923,7 +923,7 @@ bool CClientList::IncomingBuddy(Kademlia::CContact* contact, Kademlia::CUInt128* + CUpDownClient* pNewClient = new CUpDownClient(contact->GetTCPPort(), contact->GetIPAddress(), 0, 0, NULL, false, true ); + pNewClient->SetKadPort(contact->GetUDPPort()); + pNewClient->SetKadState(KS_INCOMING_BUDDY); +- byte ID[16]; ++ uint8_t ID[16]; + contact->GetClientID().ToByteArray(ID); + pNewClient->SetUserHash(CMD4Hash(ID)); + buddyID->ToByteArray(ID); +diff --git a/src/ClientTCPSocket.cpp b/src/ClientTCPSocket.cpp +index 73e5d21..ccd6016 100644 +--- a/src/ClientTCPSocket.cpp ++++ b/src/ClientTCPSocket.cpp +@@ -298,7 +298,7 @@ void CClientTCPSocket::Safe_Delete_Client() + } + + +-bool CClientTCPSocket::ProcessPacket(const byte* buffer, uint32 size, uint8 opcode) ++bool CClientTCPSocket::ProcessPacket(const uint8_t* buffer, uint32 size, uint8 opcode) + { + #ifdef __PACKET_RECV_DUMP__ + //printf("Rec: OPCODE %x \n",opcode); +@@ -1016,7 +1016,7 @@ bool CClientTCPSocket::ProcessPacket(const byte* buffer, uint32 size, uint8 opco + } + + +-bool CClientTCPSocket::ProcessExtPacket(const byte* buffer, uint32 size, uint8 opcode) ++bool CClientTCPSocket::ProcessExtPacket(const uint8_t* buffer, uint32 size, uint8 opcode) + { + #ifdef __PACKET_RECV_DUMP__ + //printf("Rec: OPCODE %x \n",opcode); +@@ -1637,7 +1637,7 @@ bool CClientTCPSocket::ProcessExtPacket(const byte* buffer, uint32 size, uint8 o + break; + } + CUInt128 fileid = data.ReadUInt128(); +- byte fileid2[16]; ++ uint8_t fileid2[16]; + fileid.ToByteArray(fileid2); + const CMD4Hash fileHash(fileid2); + if (theApp->sharedfiles->GetFileByID(fileHash) == NULL) { +@@ -1816,7 +1816,7 @@ bool CClientTCPSocket::ProcessExtPacket(const byte* buffer, uint32 size, uint8 o + return true; + } + +-bool CClientTCPSocket::ProcessED2Kv2Packet(const byte* buffer, uint32 size, uint8 opcode) ++bool CClientTCPSocket::ProcessED2Kv2Packet(const uint8_t* buffer, uint32 size, uint8 opcode) + { + #ifdef __PACKET_RECV_DUMP__ + //printf("Rec: OPCODE %x ED2Kv2\n",opcode); +diff --git a/src/ClientTCPSocket.h b/src/ClientTCPSocket.h +index ba65265..5476663 100644 +--- a/src/ClientTCPSocket.h ++++ b/src/ClientTCPSocket.h +@@ -78,9 +78,9 @@ protected: + private: + CUpDownClient* m_client; + +- bool ProcessPacket(const byte* packet, uint32 size, uint8 opcode); +- bool ProcessExtPacket(const byte* packet, uint32 size, uint8 opcode); +- bool ProcessED2Kv2Packet(const byte* packet, uint32 size, uint8 opcode); ++ bool ProcessPacket(const uint8_t* packet, uint32 size, uint8 opcode); ++ bool ProcessExtPacket(const uint8_t* packet, uint32 size, uint8 opcode); ++ bool ProcessED2Kv2Packet(const uint8_t* packet, uint32 size, uint8 opcode); + void ResetTimeOutTimer(); + void SetClient(CUpDownClient* client); + +diff --git a/src/ClientUDPSocket.cpp b/src/ClientUDPSocket.cpp +index 924363a..0619304 100644 +--- a/src/ClientUDPSocket.cpp ++++ b/src/ClientUDPSocket.cpp +@@ -75,7 +75,7 @@ void CClientUDPSocket::OnReceive(int errorCode) + } + + +-void CClientUDPSocket::OnPacketReceived(uint32 ip, uint16 port, byte* buffer, size_t length) ++void CClientUDPSocket::OnPacketReceived(uint32 ip, uint16 port, uint8_t* buffer, size_t length) + { + wxCHECK_RET(length >= 2, wxT("Invalid packet.")); + +@@ -137,7 +137,7 @@ void CClientUDPSocket::OnPacketReceived(uint32 ip, uint16 port, byte* buffer, si + } + + +-void CClientUDPSocket::ProcessPacket(byte* packet, int16 size, int8 opcode, uint32 host, uint16 port) ++void CClientUDPSocket::ProcessPacket(uint8_t* packet, int16 size, int8 opcode, uint32 host, uint16 port) + { + switch (opcode) { + case OP_REASKCALLBACKUDP: { +diff --git a/src/ClientUDPSocket.h b/src/ClientUDPSocket.h +index 162acaa..d894a32 100644 +--- a/src/ClientUDPSocket.h ++++ b/src/ClientUDPSocket.h +@@ -37,8 +37,8 @@ protected: + void OnReceive(int errorCode); + + private: +- void OnPacketReceived(uint32 ip, uint16 port, byte* buffer, size_t length); +- void ProcessPacket(byte* packet, int16 size, int8 opcode, uint32 host, uint16 port); ++ void OnPacketReceived(uint32 ip, uint16 port, uint8_t* buffer, size_t length); ++ void ProcessPacket(uint8_t* packet, int16 size, int8 opcode, uint32 host, uint16 port); + }; + + #endif // CLIENTUDPSOCKET_H +diff --git a/src/DownloadClient.cpp b/src/DownloadClient.cpp +index c364f74..37f81a8 100644 +--- a/src/DownloadClient.cpp ++++ b/src/DownloadClient.cpp +@@ -568,7 +568,7 @@ void CUpDownClient::SetDownloadState(uint8 byNewState) + } + /* eMule 0.30c implementation, i give it a try (Creteil) END ... */ + +-void CUpDownClient::ProcessHashSet(const byte* packet, uint32 size) ++void CUpDownClient::ProcessHashSet(const uint8_t* packet, uint32 size) + { + if ((!m_reqfile) || md4cmp(packet,m_reqfile->GetFileHash().GetHash())) { + throw wxString(wxT("Wrong fileid sent (ProcessHashSet)")); +@@ -830,7 +830,7 @@ The requests will still not exceed 180k, but may be smaller to + fill a gap. + */ + +-void CUpDownClient::ProcessBlockPacket(const byte* packet, uint32 size, bool packed, bool largeblocks) ++void CUpDownClient::ProcessBlockPacket(const uint8_t* packet, uint32 size, bool packed, bool largeblocks) + { + // Ignore if no data required + if (!(GetDownloadState() == DS_DOWNLOADING || GetDownloadState() == DS_NONEEDEDPARTS)) { +@@ -930,7 +930,7 @@ void CUpDownClient::ProcessBlockPacket(const byte* packet, uint32 size, bool pac + return; + } + // Write to disk (will be buffered in part file class) +- lenWritten = m_reqfile->WriteToBuffer( size - header_size, (byte*)(packet + header_size), nStartPos, nEndPos, cur_block->block, this); ++ lenWritten = m_reqfile->WriteToBuffer( size - header_size, (uint8_t*)(packet + header_size), nStartPos, nEndPos, cur_block->block, this); + } else { + // Packed + wxASSERT( (long int)size > 0 ); +@@ -942,10 +942,10 @@ void CUpDownClient::ProcessBlockPacket(const byte* packet, uint32 size, bool pac + if (lenUnzipped > (BLOCKSIZE + 300)) { + lenUnzipped = (BLOCKSIZE + 300); + } +- byte *unzipped = new byte[lenUnzipped]; ++ uint8_t *unzipped = new uint8_t[lenUnzipped]; + + // Try to unzip the packet +- int result = unzip(cur_block, (byte*)(packet + header_size), (size - header_size), &unzipped, &lenUnzipped); ++ int result = unzip(cur_block, (uint8_t*)(packet + header_size), (size - header_size), &unzipped, &lenUnzipped); + + // no block can be uncompressed to >2GB, 'lenUnzipped' is obviously erroneous. + if (result == Z_OK && ((int)lenUnzipped >= 0)) { +@@ -1046,7 +1046,7 @@ void CUpDownClient::ProcessBlockPacket(const byte* packet, uint32 size, bool pac + } + } + +-int CUpDownClient::unzip(Pending_Block_Struct *block, byte *zipped, uint32 lenZipped, byte **unzipped, uint32 *lenUnzipped, int iRecursion) ++int CUpDownClient::unzip(Pending_Block_Struct *block, uint8_t *zipped, uint32 lenZipped, uint8_t **unzipped, uint32 *lenUnzipped, int iRecursion) + { + int err = Z_DATA_ERROR; + +@@ -1112,7 +1112,7 @@ int CUpDownClient::unzip(Pending_Block_Struct *block, byte *zipped, uint32 lenZi + newLength = lenZipped * 2; + } + // Copy any data that was successfully unzipped to new array +- byte *temp = new byte[newLength]; ++ uint8_t *temp = new uint8_t[newLength]; + wxASSERT( zS->total_out - block->totalUnzipped <= newLength ); + memcpy(temp, (*unzipped), (zS->total_out - block->totalUnzipped)); + delete [] (*unzipped); +@@ -1601,7 +1601,7 @@ void CUpDownClient::SendAICHRequest(CPartFile* pForFile, uint16 nPart){ + SafeSendPacket(packet); + } + +-void CUpDownClient::ProcessAICHAnswer(const byte* packet, uint32 size) ++void CUpDownClient::ProcessAICHAnswer(const uint8_t* packet, uint32 size) + { + if (m_fAICHRequested == FALSE){ + throw wxString(wxT("Received unrequested AICH Packet")); +@@ -1643,7 +1643,7 @@ void CUpDownClient::ProcessAICHAnswer(const byte* packet, uint32 size) + } + + +-void CUpDownClient::ProcessAICHRequest(const byte* packet, uint32 size) ++void CUpDownClient::ProcessAICHRequest(const uint8_t* packet, uint32 size) + { + if (size != 16 + 2 + CAICHHash::GetHashSize()) { + throw wxString(wxT("Received AICH Request Packet with wrong size")); +diff --git a/src/DownloadQueue.cpp b/src/DownloadQueue.cpp +index 7033cd1..6128fe2 100644 +--- a/src/DownloadQueue.cpp ++++ b/src/DownloadQueue.cpp +@@ -1114,7 +1114,7 @@ void CDownloadQueue::ProcessLocalRequests() + if (iSize > 0) { + // create one 'packet' which contains all buffered OP_GETSOURCES ED2K packets to be sent with one TCP frame + // server credits: (16+4)*regularfiles + (16+4+8)*largefiles +1 +- CScopedPtr packet(new CPacket(new byte[iSize], dataTcpFrame.GetLength(), true, false)); ++ CScopedPtr packet(new CPacket(new uint8_t[iSize], dataTcpFrame.GetLength(), true, false)); + dataTcpFrame.Seek(0, wxFromStart); + dataTcpFrame.Read(packet->GetPacket(), iSize); + uint32 size = packet->GetPacketSize(); +@@ -1591,7 +1591,7 @@ void CDownloadQueue::KademliaSearchFile(uint32_t searchID, const Kademlia::CUInt + //ctemp->SetServerIP(serverip); + //ctemp->SetServerPort(serverport); + ctemp->SetKadPort(udp); +- byte cID[16]; ++ uint8_t cID[16]; + pcontactID->ToByteArray(cID); + ctemp->SetUserHash(CMD4Hash(cID)); + break; +@@ -1609,7 +1609,7 @@ void CDownloadQueue::KademliaSearchFile(uint32_t searchID, const Kademlia::CUInt + // from this firewalled source, the compare method will match them. + ctemp->SetSourceFrom(SF_KADEMLIA); + ctemp->SetKadPort(udp); +- byte cID[16]; ++ uint8_t cID[16]; + pcontactID->ToByteArray(cID); + ctemp->SetUserHash(CMD4Hash(cID)); + pbuddyID->ToByteArray(cID); +@@ -1634,7 +1634,7 @@ void CDownloadQueue::KademliaSearchFile(uint32_t searchID, const Kademlia::CUInt + ctemp->SetSourceFrom(SF_KADEMLIA); + ctemp->SetKadPort(udp); + ctemp->SetIP(ED2KID); // need to set the IP address, which cannot be used for TCP but for UDP +- byte cID[16]; ++ uint8_t cID[16]; + pcontactID->ToByteArray(cID); + ctemp->SetUserHash(CMD4Hash(cID)); + } +diff --git a/src/EMSocket.cpp b/src/EMSocket.cpp +index 3ccaa7e..e3e45a0 100644 +--- a/src/EMSocket.cpp ++++ b/src/EMSocket.cpp +@@ -199,7 +199,7 @@ void CEMSocket::OnReceive(int nErrorCode) + } + + uint32 readMax; +- byte *buf; ++ uint8_t *buf; + if (pendingHeaderSize < PACKET_HEADER_SIZE) { + delete[] pendingPacket; + pendingPacket = NULL; +@@ -213,7 +213,7 @@ void CEMSocket::OnReceive(int nErrorCode) + OnError(ERR_TOOBIG); + return; + } +- pendingPacket = new byte[readMax + 1]; ++ pendingPacket = new uint8_t[readMax + 1]; + buf = pendingPacket; + } else { + buf = pendingPacket + pendingPacketSize; +@@ -529,7 +529,7 @@ SocketSentBytes CEMSocket::Send(uint32 maxNumberOfBytesToSend, uint32 minFragSiz + sent = 0; + delete curPacket; + +- CryptPrepareSendData((byte*)sendbuffer, sendblen); ++ CryptPrepareSendData((uint8_t*)sendbuffer, sendblen); + } + + // At this point we've got a packet to send in sendbuffer. Try to send it. Loop until entire packet +diff --git a/src/EMSocket.h b/src/EMSocket.h +index 4d00361..4866aa5 100644 +--- a/src/EMSocket.h ++++ b/src/EMSocket.h +@@ -99,15 +99,15 @@ private: + bool pendingOnReceive; + + // Download partial header +- byte pendingHeader[PACKET_HEADER_SIZE]; ++ uint8_t pendingHeader[PACKET_HEADER_SIZE]; + uint32 pendingHeaderSize; + + // Download partial packet +- byte* pendingPacket; ++ uint8_t* pendingPacket; + uint32 pendingPacketSize; + + // Upload control +- byte* sendbuffer; ++ uint8_t* sendbuffer; + uint32 sendblen; + uint32 sent; + +diff --git a/src/EncryptedDatagramSocket.cpp b/src/EncryptedDatagramSocket.cpp +index 842686f..73de612 100644 +--- a/src/EncryptedDatagramSocket.cpp ++++ b/src/EncryptedDatagramSocket.cpp +@@ -42,7 +42,7 @@ + + - Additional Comments: + - For obvious reasons the UDP handshake is actually no handshake. If a different Encryption method (or better a different Key) is to be used this has to be negotiated in a TCP connection +- - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header byte. This is a compromise, turning in complete randomness (and nice design) but gaining a lower CPU usage ++ - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header uint8_t. This is a compromise, turning in complete randomness (and nice design) but gaining a lower CPU usage + - Kad/Ed2k Marker are only indicators, which possibility could be tried first, and should not be trusted + + ****************************** Server Packets +@@ -66,7 +66,7 @@ + + - Additional Comments: + - For obvious reasons the UDP handshake is actually no handshake. If a different Encryption method (or better a different Key) is to be used this has to be negotiated in a TCP connection +- - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header byte. This is a compromise, turning in complete randomness (and nice design) but gaining a lower CPU usage ++ - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header uint8_t. This is a compromise, turning in complete randomness (and nice design) but gaining a lower CPU usage + + ****************************** KAD Packets + +@@ -86,7 +86,7 @@ + + - Additional Comments: + - For obvious reasons the UDP handshake is actually no handshake. If a different Encryption method (or better a different Key) is to be used this has to be negotiated in a TCP connection +- - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header byte. This is a compromise, turning in complete randomness (and nice design) but gaining a lower CPU usage ++ - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header uint8_t. This is a compromise, turning in complete randomness (and nice design) but gaining a lower CPU usage + - Kad/Ed2k Marker are only indicators, which possibility could be tried first, and should not be trusted + */ + +@@ -309,7 +309,7 @@ int CEncryptedDatagramSocket::EncryptSendClient(uint8_t **buf, int bufLen, const + + sendbuffer.SetKey(md5, true); + +- // create the semi random byte encryption header ++ // create the semi random uint8_t encryption header + uint8_t semiRandomNotProtocolMarker = 0; + int i; + for (i = 0; i < 128; i++) { +@@ -444,7 +444,7 @@ int CEncryptedDatagramSocket::EncryptSendServer(uint8_t** ppbyBuf, int nBufLen, + CRC4EncryptableBuffer sendbuffer; + sendbuffer.SetKey(md5, true); + +- // create the semi random byte encryption header ++ // create the semi random uint8_t encryption header + uint8_t bySemiRandomNotProtocolMarker = 0; + int i; + +diff --git a/src/EncryptedStreamSocket.cpp b/src/EncryptedStreamSocket.cpp +index da579ce..9fb5acc 100644 +--- a/src/EncryptedStreamSocket.cpp ++++ b/src/EncryptedStreamSocket.cpp +@@ -180,7 +180,7 @@ void CEncryptedStreamSocket::SetConnectionEncryption(bool bEnabled, const uint8_ + /* Internals, common to base class */ + + // unfortunately sending cannot be made transparent for the derived class, because of WSA_WOULDBLOCK +-// together with the fact that each byte must pass the keystream only once ++// together with the fact that each uint8_t must pass the keystream only once + int CEncryptedStreamSocket::Write(const void* lpBuf, uint32_t nBufLen) + { + //printf("Starting write for %s\n", (const char*) unicode2char(GetPeer())); +@@ -403,7 +403,7 @@ void CEncryptedStreamSocket::StartNegotiation(bool bOutgoing) + + m_cryptDHA.Randomize((CryptoPP::AutoSeededRandomPool&)GetRandomPool(), DHAGREEMENT_A_BITS); // our random a + wxASSERT( m_cryptDHA.MinEncodedSize() <= DHAGREEMENT_A_BITS / 8 ); +- CryptoPP::Integer cryptDHPrime((byte*)dh768_p, PRIMESIZE_BYTES); // our fixed prime ++ CryptoPP::Integer cryptDHPrime((uint8_t*)dh768_p, PRIMESIZE_BYTES); // our fixed prime + // calculate g^a % p + CryptoPP::Integer cryptDHGexpAmodP = a_exp_b_mod_c(CryptoPP::Integer(2), m_cryptDHA, cryptDHPrime); + wxASSERT( m_cryptDHA.MinEncodedSize() <= PRIMESIZE_BYTES ); +@@ -590,8 +590,8 @@ int CEncryptedStreamSocket::Negotiate(const uint8* pBuffer, uint32 nLen) + wxASSERT( !m_cryptDHA.IsZero() ); + uint8_t aBuffer[PRIMESIZE_BYTES + 1]; + m_pfiReceiveBuffer.Read(aBuffer, PRIMESIZE_BYTES); +- CryptoPP::Integer cryptDHAnswer((byte*)aBuffer, PRIMESIZE_BYTES); +- CryptoPP::Integer cryptDHPrime((byte*)dh768_p, PRIMESIZE_BYTES); // our fixed prime ++ CryptoPP::Integer cryptDHAnswer((uint8_t*)aBuffer, PRIMESIZE_BYTES); ++ CryptoPP::Integer cryptDHPrime((uint8_t*)dh768_p, PRIMESIZE_BYTES); // our fixed prime + CryptoPP::Integer cryptResult = a_exp_b_mod_c(cryptDHAnswer, m_cryptDHA, cryptDHPrime); + + m_cryptDHA = 0; +@@ -694,7 +694,7 @@ int CEncryptedStreamSocket::SendNegotiatingData(const void* lpBuf, uint32_t nBuf + } + + if (nBufLen - nStartCryptFromByte > 0) { +- //printf("Crypting negotiation data on %s starting on byte %i\n", (const char*) unicode2char(GetPeer()), nStartCryptFromByte); ++ //printf("Crypting negotiation data on %s starting on uint8_t %i\n", (const char*) unicode2char(GetPeer()), nStartCryptFromByte); + //DumpMem(lpBuf, nBufLen, wxT("Pre-encryption:")); + m_pfiSendBuffer.RC4Crypt((uint8*)lpBuf + nStartCryptFromByte, pBuffer + nStartCryptFromByte, nBufLen - nStartCryptFromByte); + //DumpMem(pBuffer, nBufLen, wxT("Post-encryption:")); +diff --git a/src/FileArea.cpp b/src/FileArea.cpp +index 8a018b9..da0204b 100644 +--- a/src/FileArea.cpp ++++ b/src/FileArea.cpp +@@ -230,7 +230,7 @@ void CFileArea::ReadAt(CFileAutoClose& file, uint64 offset, size_t count) + void *p = mmap(NULL, m_length, PROT_READ, MAP_SHARED, file.fd(), offStart); + if (p != MAP_FAILED) { + m_file = &file; +- m_mmap_buffer = (byte*) p; ++ m_mmap_buffer = (uint8_t*) p; + m_buffer = m_mmap_buffer + (offset - offStart); + + // add to list to catch errors correctly +@@ -240,7 +240,7 @@ void CFileArea::ReadAt(CFileAutoClose& file, uint64 offset, size_t count) + } + file.Unlock(); + #endif +- m_buffer = new byte[count]; ++ m_buffer = new uint8_t[count]; + file.ReadAt(m_buffer, offset, count); + } + +@@ -257,7 +257,7 @@ void CFileArea::StartWriteAt(CFileAutoClose& file, uint64 offset, size_t count) + if (p != MAP_FAILED) + { + m_file = &file; +- m_mmap_buffer = (byte*) p; ++ m_mmap_buffer = (uint8_t*) p; + m_buffer = m_mmap_buffer + (offset - offStart); + + // add to list to catch errors correctly +@@ -266,13 +266,13 @@ void CFileArea::StartWriteAt(CFileAutoClose& file, uint64 offset, size_t count) + } + file.Unlock(); + } +- m_buffer = new byte[count]; ++ m_buffer = new uint8_t[count]; + } + #else + void CFileArea::StartWriteAt(CFileAutoClose&, uint64, size_t count) + { + Close(); +- m_buffer = new byte[count]; ++ m_buffer = new uint8_t[count]; + } + #endif + +diff --git a/src/FileArea.h b/src/FileArea.h +index 4006151..17c6dee 100644 +--- a/src/FileArea.h ++++ b/src/FileArea.h +@@ -22,7 +22,7 @@ + #ifndef FILEAREA_H + #define FILEAREA_H + +-#include "Types.h" // Needed for byte ++#include "Types.h" // Needed for uint8_t + + class CFileAreaSigHandler; + class CFileAutoClose; +@@ -78,7 +78,7 @@ public: + * Get buffer that contains data readed or to write. + * @return allocated buffer or NULL if not initialized + */ +- byte *GetBuffer() const { return m_buffer; }; ++ uint8_t *GetBuffer() const { return m_buffer; }; + + /** + * Report error pending +@@ -97,11 +97,11 @@ private: + * If mapped points inside m_mmap_buffer area otherwise + * point to an allocated buffer to be freed. + */ +- byte *m_buffer; ++ uint8_t *m_buffer; + /** + * Pointer to memory mapped area or NULL if not mapped. + */ +- byte *m_mmap_buffer; ++ uint8_t *m_mmap_buffer; + /** + * Length of the mapped region, currently used only for munmap. + */ +diff --git a/src/FileLock.h b/src/FileLock.h +index 9758bdd..6a8a171 100644 +--- a/src/FileLock.h ++++ b/src/FileLock.h +@@ -91,7 +91,7 @@ private: + + /** Locks or unlocks the lock-file, returning true on success. */ + bool SetLock(bool doLock) { +- // lock/unlock first byte in the file ++ // lock/unlock first uint8_t in the file + OVERLAPPED ov; + ov.Offset = ov.OffsetHigh = 0; + BOOL ret; +diff --git a/src/GapList.h b/src/GapList.h +index 41c4af7..490180f 100644 +--- a/src/GapList.h ++++ b/src/GapList.h +@@ -52,7 +52,7 @@ private: + incomplete, + unknown + }; +- std::vector m_partsComplete; ++ std::vector m_partsComplete; + + // get size of any part + uint32 GetPartSize(uint16 part) const { return part == m_iPartCount - 1 ? m_sizeLastPart : PARTSIZE; } +diff --git a/src/IPFilterScanner.cpp b/src/IPFilterScanner.cpp +index 7cd5ae0..b81df8e 100644 +--- a/src/IPFilterScanner.cpp ++++ b/src/IPFilterScanner.cpp +@@ -1771,7 +1771,7 @@ YY_BUFFER_STATE yyip_scan_string (yyconst char * yystr ) + + /** Setup the input buffer state to scan the given bytes. The next call to yyiplex() will + * scan from a @e copy of @a bytes. +- * @param bytes the byte buffer to scan ++ * @param bytes the uint8_t buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. +diff --git a/src/KnownFile.cpp b/src/KnownFile.cpp +index 0e39630..6c5c389 100644 +--- a/src/KnownFile.cpp ++++ b/src/KnownFile.cpp +@@ -358,7 +358,7 @@ void CKnownFile::SetFileSize(uint64 nFileSize) + //Hash[ 1]: 31D6CFE0D16AE931B73C59D7E0C089C0 *special part hash* + // + // +- //File size: 1*PARTSIZE + 1 byte ++ //File size: 1*PARTSIZE + 1 uint8_t + //File hash: 2F620AE9D462CBB6A59FE8401D2B3D23 + //Nr. hashs: 2 + //Hash[ 0]: 121795F0BEDE02DDC7C5426D0995F53F +@@ -382,7 +382,7 @@ void CKnownFile::SetFileSize(uint64 nFileSize) + //Hash[ 3]: 31D6CFE0D16AE931B73C59D7E0C089C0 *special part hash* + // + // +- //File size: 3*PARTSIZE + 1 byte ++ //File size: 3*PARTSIZE + 1 uint8_t + //File hash: 797ED552F34380CAFF8C958207E40355 + //Nr. hashs: 4 + //Hash[ 0]: FC7FD02CCD6987DCF1421F4C0AF94FB8 +@@ -788,8 +788,8 @@ void CKnownFile::CreateHashFromHashlist(const ArrayOfCMD4Hash& hashes, CMD4Hash* + { + wxCHECK_RET(hashes.size(), wxT("No input to hash from in CreateHashFromHashlist")); + +- std::vector buffer(hashes.size() * MD4HASH_LENGTH); +- std::vector::iterator it = buffer.begin(); ++ std::vector buffer(hashes.size() * MD4HASH_LENGTH); ++ std::vector::iterator it = buffer.begin(); + + for (size_t i = 0; i < hashes.size(); ++i) { + it = STLCopy_n(hashes[i].GetHash(), MD4HASH_LENGTH, it); +@@ -811,7 +811,7 @@ void CKnownFile::CreateHashFromFile(CFileAutoClose& file, uint64 offset, uint32 + } + + +-void CKnownFile::CreateHashFromInput(const byte* input, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut ) ++void CKnownFile::CreateHashFromInput(const uint8_t* input, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut ) + { + wxASSERT_MSG(Output || pShaHashOut, wxT("Nothing to do in CreateHashFromInput")); + { wxCHECK_RET(input, wxT("No input to hash from in CreateHashFromInput")); } +@@ -820,7 +820,7 @@ void CKnownFile::CreateHashFromInput(const byte* input, uint32 Length, CMD4Hash* + CMemFile data(input, Length); + + uint32 Required = Length; +- byte X[64*128]; ++ uint8_t X[64*128]; + + uint32 posCurrentEMBlock = 0; + uint32 nIACHPos = 0; +diff --git a/src/KnownFile.h b/src/KnownFile.h +index 0ef7559..ae78715 100644 +--- a/src/KnownFile.h ++++ b/src/KnownFile.h +@@ -333,7 +333,7 @@ protected: + CPath m_filePath; + + static void CreateHashFromFile(class CFileAutoClose& file, uint64 offset, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut); +- static void CreateHashFromInput(const byte* input, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut); ++ static void CreateHashFromInput(const uint8_t* input, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut); + + mutable bool m_bCommentLoaded; + uint16 m_iPartCount; +diff --git a/src/MemFile.cpp b/src/MemFile.cpp +index 4632bf4..4a01388 100644 +--- a/src/MemFile.cpp ++++ b/src/MemFile.cpp +@@ -38,7 +38,7 @@ CMemFile::CMemFile(unsigned int growthRate) + } + + +-CMemFile::CMemFile(byte* buffer, size_t bufferSize) ++CMemFile::CMemFile(uint8_t* buffer, size_t bufferSize) + { + MULE_VALIDATE_PARAMS(buffer, wxT("CMemFile: Attempted to attach invalid buffer.")); + +@@ -51,11 +51,11 @@ CMemFile::CMemFile(byte* buffer, size_t bufferSize) + m_readonly = false; + } + +-CMemFile::CMemFile(const byte* buffer, size_t bufferSize) ++CMemFile::CMemFile(const uint8_t* buffer, size_t bufferSize) + { + MULE_VALIDATE_PARAMS(buffer, wxT("CMemFile: Attempted to attach invalid buffer.")); + +- m_buffer = const_cast(buffer); ++ m_buffer = const_cast(buffer); + m_BufferSize = bufferSize; + m_fileSize = bufferSize; + m_growthRate = 0; +@@ -115,7 +115,7 @@ void CMemFile::enlargeBuffer(size_t size) + newsize = size; + } + +- byte *tmp = (byte*)realloc(m_buffer, newsize); ++ uint8_t *tmp = (uint8_t*)realloc(m_buffer, newsize); + if (tmp) { + m_buffer = tmp; + m_BufferSize = newsize; +diff --git a/src/MemFile.h b/src/MemFile.h +index c4f5508..67d487a 100644 +--- a/src/MemFile.h ++++ b/src/MemFile.h +@@ -86,10 +86,10 @@ public: + * + * The buffer is _not_ freed by CMemFile upon destruction. + * +- * If the buffer is a const byte*, the memfile is read-only. ++ * If the buffer is a const uint8_t*, the memfile is read-only. + */ +- CMemFile(byte* buffer, size_t bufferSize); +- CMemFile(const byte* buffer, size_t bufferSize); ++ CMemFile(uint8_t* buffer, size_t bufferSize); ++ CMemFile(const uint8_t* buffer, size_t bufferSize); + + /** Destructor. */ + virtual ~CMemFile(); +@@ -132,7 +132,7 @@ public: + virtual void ResetData(); + + // Sometimes it's useful to get the buffer and do stuff with it. +- byte* GetRawBuffer() const { return m_buffer; } ++ uint8_t* GetRawBuffer() const { return m_buffer; } + + protected: + /** @see CFileDataIO::doRead */ +@@ -167,7 +167,7 @@ private: + //! read-only mark. + bool m_readonly; + //! The actual buffer. +- byte* m_buffer; ++ uint8_t* m_buffer; + }; + + #endif // MEMFILE_H +diff --git a/src/MuleCollection.cpp b/src/MuleCollection.cpp +index 6c36f0b..a131740 100644 +--- a/src/MuleCollection.cpp ++++ b/src/MuleCollection.cpp +@@ -50,7 +50,7 @@ intType CMuleCollection::ReadInt(std::ifstream& infile) + { + intType integer = 0; + infile.read(reinterpret_cast(&integer),sizeof(intType)); +- // TODO: byte-sex ++ // TODO: uint8_t-sex + return integer; + } + +diff --git a/src/MuleColour.h b/src/MuleColour.h +index 1a983dd..ff54897 100644 +--- a/src/MuleColour.h ++++ b/src/MuleColour.h +@@ -40,7 +40,7 @@ public: + + CMuleColour() { Init(); Set(0,0,0); } + CMuleColour(const wxColour& colour) { Init(); Set(colour.Red(), colour.Green(), colour.Blue()); } +- CMuleColour(byte r, byte g, byte b) { Init(); Set(r,g,b); } ++ CMuleColour(uint8_t r, uint8_t g, uint8_t b) { Init(); Set(r,g,b); } + CMuleColour(unsigned long rgb) + { + Init(); +@@ -61,13 +61,13 @@ public: + + ~CMuleColour() { } + +- void Set(byte red, byte green, byte blue) { m_red = red; m_green = green; m_blue = blue; } ++ void Set(uint8_t red, uint8_t green, uint8_t blue) { m_red = red; m_green = green; m_blue = blue; } + +- inline byte Red() const { return m_red; } +- inline byte Green() const { return m_green; } +- inline byte Blue() const { return m_blue; } ++ inline uint8_t Red() const { return m_red; } ++ inline uint8_t Green() const { return m_green; } ++ inline uint8_t Blue() const { return m_blue; } + +- const CMuleColour& Blend(byte percentage, ColourComponent flags = (ColourComponent)(COLOUR_R | COLOUR_G | COLOUR_B) ) ++ const CMuleColour& Blend(uint8_t percentage, ColourComponent flags = (ColourComponent)(COLOUR_R | COLOUR_G | COLOUR_B) ) + { + unsigned int red = (unsigned int)(Red() * ((flags & COLOUR_R) ? ((float)percentage/(float)100) : (float)1)); + unsigned int green = (unsigned int)(Green() * ((flags & COLOUR_G) ? ((float)percentage/(float)100) : (float)1)); +@@ -99,9 +99,9 @@ public: + const wxBrush& GetBrush(int style = wxSOLID) const; + + private: +- byte m_red; +- byte m_green; +- byte m_blue; ++ uint8_t m_red; ++ uint8_t m_green; ++ uint8_t m_blue; + + mutable wxPen* m_cachedpen; + mutable wxBrush* m_cachedbrush; +diff --git a/src/MuleUDPSocket.cpp b/src/MuleUDPSocket.cpp +index a666c93..6f09a59 100644 +--- a/src/MuleUDPSocket.cpp ++++ b/src/MuleUDPSocket.cpp +@@ -180,7 +180,7 @@ void CMuleUDPSocket::OnReceive(int errorCode) + AddDebugLogLineN(logMuleUDP, (m_name + wxT(": Packet received (")) + << addr.IPAddress() << wxT(":") << port << wxT("): ") + << length << wxT("b")); +- OnPacketReceived(ip, port, (byte*)buffer, length); ++ OnPacketReceived(ip, port, (uint8_t*)buffer, length); + } + } + +diff --git a/src/MuleUDPSocket.h b/src/MuleUDPSocket.h +index c9cb023..1740c7a 100644 +--- a/src/MuleUDPSocket.h ++++ b/src/MuleUDPSocket.h +@@ -131,7 +131,7 @@ protected: + * @param buffer The data that has been received. + * @param length The length of the data buffer. + */ +- virtual void OnPacketReceived(uint32 ip, uint16 port, byte* buffer, size_t length) = 0; ++ virtual void OnPacketReceived(uint32 ip, uint16 port, uint8_t* buffer, size_t length) = 0; + + + /** See ThrottledControlSocket::SendControlData */ +diff --git a/src/OtherFunctions.cpp b/src/OtherFunctions.cpp +index 3c58aa2..8b84a90 100644 +--- a/src/OtherFunctions.cpp ++++ b/src/OtherFunctions.cpp +@@ -61,7 +61,7 @@ wxString CastItoXBytes( uint64 count ) + { + + if (count < 1024) +- return CFormat(wxT("%u ")) % count + wxPLURAL("byte", "bytes", count) ; ++ return CFormat(wxT("%u ")) % count + wxPLURAL("uint8_t", "bytes", count) ; + else if (count < 1048576) + return CFormat(wxT("%u ")) % (count >> 10) + _("kB") ; + else if (count < 1073741824) +@@ -92,7 +92,7 @@ wxString CastItoIShort(uint64 count) + wxString CastItoSpeed(uint32 bytes) + { + if (bytes < 1024) +- return CFormat(wxT("%u ")) % bytes + wxPLURAL("byte/sec", "bytes/sec", bytes); ++ return CFormat(wxT("%u ")) % bytes + wxPLURAL("uint8_t/sec", "bytes/sec", bytes); + else if (bytes < 1048576) + return CFormat(wxT("%.2f ")) % (bytes / 1024.0) + _("kB/s"); + else +@@ -284,14 +284,14 @@ static wxChar base16Lookup[BASE16_LOOKUP_MAX][2] = { + }; + + +-// Returns a BASE16 encoded byte array ++// Returns a BASE16 encoded uint8_t array + // + // [In] +-// buffer: Pointer to byte array ++// buffer: Pointer to uint8_t array + // bufLen: Lenght of buffer array + // + // [Return] +-// wxString object with BASE16 encoded byte array ++// wxString object with BASE16 encoded uint8_t array + wxString EncodeBase16(const unsigned char* buffer, unsigned int bufLen) + { + wxString Base16Buff; +@@ -305,15 +305,15 @@ wxString EncodeBase16(const unsigned char* buffer, unsigned int bufLen) + } + + +-// Decodes a BASE16 string into a byte array ++// Decodes a BASE16 string into a uint8_t array + // + // [In] + // base16Buffer: String containing BASE16 + // base16BufLen: Lenght BASE16 coded string's length + // + // [Out] +-// buffer: byte array containing decoded string +-unsigned int DecodeBase16(const wxString &base16Buffer, unsigned int base16BufLen, byte *buffer) ++// buffer: uint8_t array containing decoded string ++unsigned int DecodeBase16(const wxString &base16Buffer, unsigned int base16BufLen, uint8_t *buffer) + { + if (base16BufLen & 1) { + return 0; +@@ -323,7 +323,7 @@ unsigned int DecodeBase16(const wxString &base16Buffer, unsigned int base16BufLe + for(unsigned int i = 0; i < base16BufLen; ++i) { + int lookup = toupper(base16Buffer[i]) - wxT('0'); + // Check to make sure that the given word falls inside a valid range +- byte word = (lookup < 0 || lookup >= BASE16_LOOKUP_MAX) ? ++ uint8_t word = (lookup < 0 || lookup >= BASE16_LOOKUP_MAX) ? + 0xFF : base16Lookup[lookup][1]; + unsigned idx = i >> 1; + buffer[idx] = (i & 1) ? // odd or even? +@@ -334,14 +334,14 @@ unsigned int DecodeBase16(const wxString &base16Buffer, unsigned int base16BufLe + } + + +-// Returns a BASE32 encoded byte array ++// Returns a BASE32 encoded uint8_t array + // + // [In] +-// buffer: Pointer to byte array ++// buffer: Pointer to uint8_t array + // bufLen: Lenght of buffer array + // + // [Return] +-// wxString object with BASE32 encoded byte array ++// wxString object with BASE32 encoded uint8_t array + wxString EncodeBase32(const unsigned char* buffer, unsigned int bufLen) + { + wxString Base32Buff; +@@ -349,7 +349,7 @@ wxString EncodeBase32(const unsigned char* buffer, unsigned int bufLen) + unsigned char word; + + for(i = 0, index = 0; i < bufLen;) { +- // Is the current word going to span a byte boundary? ++ // Is the current word going to span a uint8_t boundary? + if (index > 3) { + word = (buffer[i] & (0xFF >> index)); + index = (index + 5) % 8; +@@ -372,14 +372,14 @@ wxString EncodeBase32(const unsigned char* buffer, unsigned int bufLen) + } + + +-// Decodes a BASE32 string into a byte array ++// Decodes a BASE32 string into a uint8_t array + // + // [In] + // base32Buffer: String containing BASE32 + // base32BufLen: Lenght BASE32 coded string's length + // + // [Out] +-// buffer: byte array containing decoded string ++// buffer: uint8_t array containing decoded string + // [Return] + // nDecodeLen: + unsigned int DecodeBase32(const wxString &base32Buffer, unsigned int base32BufLen, unsigned char *buffer) +@@ -414,7 +414,7 @@ unsigned int DecodeBase32(const wxString &base32Buffer, unsigned int base32BufLe + nCount += 5; + if (nCount >= 8) + { +- *buffer++ = (byte)( nBits >> (nCount - 8) ); ++ *buffer++ = (uint8_t)( nBits >> (nCount - 8) ); + nCount -= 8; + } + nBits <<= 5; +diff --git a/src/Packet.cpp b/src/Packet.cpp +index d0e93b4..3e0f774 100644 +--- a/src/Packet.cpp ++++ b/src/Packet.cpp +@@ -47,12 +47,12 @@ CPacket::CPacket(CPacket &p) + memcpy(head, p.head, sizeof head); + tempbuffer = NULL; + if (p.completebuffer) { +- completebuffer = new byte[size + 10];; ++ completebuffer = new uint8_t[size + 10];; + pBuffer = completebuffer + sizeof(Header_Struct); + } else { + completebuffer = NULL; + if (p.pBuffer) { +- pBuffer = new byte[size]; ++ pBuffer = new uint8_t[size]; + } else { + pBuffer = NULL; + } +@@ -77,7 +77,7 @@ CPacket::CPacket(uint8 protocol) + } + + // only used for receiving packets +-CPacket::CPacket(byte* rawHeader, byte *buf) ++CPacket::CPacket(uint8_t* rawHeader, uint8_t *buf) + { + memset(head, 0, sizeof head); + Header_Struct* header = reinterpret_cast(rawHeader); +@@ -104,7 +104,7 @@ CPacket::CPacket(const CMemFile& datafile, uint8 protocol, uint8 ucOpcode) + m_bFromPF = false; + memset(head, 0, sizeof head); + tempbuffer = NULL; +- completebuffer = new byte[size + sizeof(Header_Struct)/*Why this 4?*/]; ++ completebuffer = new uint8_t[size + sizeof(Header_Struct)/*Why this 4?*/]; + pBuffer = completebuffer + sizeof(Header_Struct); + + // Write contents of MemFile to buffer (while keeping original position in file) +@@ -126,7 +126,7 @@ CPacket::CPacket(int8 in_opcode, uint32 in_size, uint8 protocol, bool bFromPF) + memset(head, 0, sizeof head); + tempbuffer = NULL; + if (in_size) { +- completebuffer = new byte[in_size + sizeof(Header_Struct) + 4 /*Why this 4?*/]; ++ completebuffer = new uint8_t[in_size + sizeof(Header_Struct) + 4 /*Why this 4?*/]; + pBuffer = completebuffer + sizeof(Header_Struct); + memset(completebuffer, 0, in_size + sizeof(Header_Struct) + 4 /*Why this 4?*/); + } else { +@@ -136,7 +136,7 @@ CPacket::CPacket(int8 in_opcode, uint32 in_size, uint8 protocol, bool bFromPF) + } + + // only used for splitted packets! +-CPacket::CPacket(byte* pPacketPart, uint32 nSize, bool bLast, bool bFromPF) ++CPacket::CPacket(uint8_t* pPacketPart, uint32 nSize, bool bLast, bool bFromPF) + { + size = nSize - sizeof(Header_Struct); + opcode = 0; +@@ -166,7 +166,7 @@ CPacket::~CPacket() + } + } + +-uint32 CPacket::GetPacketSizeFromHeader(const byte* rawHeader) ++uint32 CPacket::GetPacketSizeFromHeader(const uint8_t* rawHeader) + { + const Header_Struct* header = reinterpret_cast(rawHeader); + uint32 size = ENDIAN_SWAP_32(header->packetlength); +@@ -175,13 +175,13 @@ uint32 CPacket::GetPacketSizeFromHeader(const byte* rawHeader) + return size - 1; + } + +-void CPacket::CopyToDataBuffer(unsigned int offset, const byte* data, unsigned int n) ++void CPacket::CopyToDataBuffer(unsigned int offset, const uint8_t* data, unsigned int n) + { + wxASSERT(offset + n <= size + 1); + memcpy(pBuffer + offset, data, n); + } + +-byte* CPacket::GetPacket() { ++uint8_t* CPacket::GetPacket() { + if (completebuffer) { + if (!m_bSplitted) { + memcpy(completebuffer, GetHeader(), sizeof(Header_Struct)); +@@ -192,19 +192,19 @@ byte* CPacket::GetPacket() { + delete [] tempbuffer; + tempbuffer = NULL; + } +- tempbuffer = new byte[size + sizeof(Header_Struct) + 4 /* why this 4?*/]; ++ tempbuffer = new uint8_t[size + sizeof(Header_Struct) + 4 /* why this 4?*/]; + memcpy(tempbuffer , GetHeader(), sizeof(Header_Struct)); + memcpy(tempbuffer + sizeof(Header_Struct), pBuffer , size); + return tempbuffer; + } + } + +-byte* CPacket::DetachPacket() { ++uint8_t* CPacket::DetachPacket() { + if (completebuffer) { + if (!m_bSplitted) { + memcpy(completebuffer, GetHeader(), sizeof(Header_Struct)); + } +- byte* result = completebuffer; ++ uint8_t* result = completebuffer; + completebuffer = pBuffer = NULL; + return result; + } else{ +@@ -212,16 +212,16 @@ byte* CPacket::DetachPacket() { + delete[] tempbuffer; + tempbuffer = NULL; + } +- tempbuffer = new byte[size+sizeof(Header_Struct)+4 /* Why this 4?*/]; ++ tempbuffer = new uint8_t[size+sizeof(Header_Struct)+4 /* Why this 4?*/]; + memcpy(tempbuffer,GetHeader(),sizeof(Header_Struct)); + memcpy(tempbuffer+sizeof(Header_Struct),pBuffer,size); +- byte* result = tempbuffer; ++ uint8_t* result = tempbuffer; + tempbuffer = 0; + return result; + } + } + +-byte* CPacket::GetHeader() { ++uint8_t* CPacket::GetHeader() { + wxASSERT( !m_bSplitted ); + + Header_Struct* header = reinterpret_cast(head); +@@ -232,7 +232,7 @@ byte* CPacket::GetHeader() { + return head; + } + +-byte* CPacket::GetUDPHeader() { ++uint8_t* CPacket::GetUDPHeader() { + wxASSERT( !m_bSplitted ); + + memset(head, 0, 6); +@@ -249,7 +249,7 @@ void CPacket::PackPacket() + wxASSERT(!m_bSplitted); + + uLongf newsize = size + 300; +- byte* output = new byte[newsize]; ++ uint8_t* output = new uint8_t[newsize]; + + uint16 result = compress2(output, &newsize, pBuffer, size, Z_BEST_COMPRESSION); + +@@ -287,7 +287,7 @@ bool CPacket::UnPackPacket(uint32 uMaxDecompressedSize) { + nNewSize = uMaxDecompressedSize; + } + +- byte* unpack = new byte[nNewSize]; ++ uint8_t* unpack = new uint8_t[nNewSize]; + uLongf unpackedsize = nNewSize; + uint16 result = uncompress(unpack, &unpackedsize, pBuffer, size); + +diff --git a/src/Packet.h b/src/Packet.h +index 3e0fe71..407d345 100644 +--- a/src/Packet.h ++++ b/src/Packet.h +@@ -41,19 +41,19 @@ class CPacket { + public: + CPacket(CPacket &p); + CPacket(uint8 protocol); +- CPacket(byte* header, byte *buf); // only used for receiving packets ++ CPacket(uint8_t* header, uint8_t *buf); // only used for receiving packets + CPacket(const CMemFile& datafile, uint8 protocol, uint8 ucOpcode); + CPacket(int8 in_opcode, uint32 in_size, uint8 protocol, bool bFromPF = true); +- CPacket(byte* pPacketPart, uint32 nSize, bool bLast, bool bFromPF = true); // only used for splitted packets! ++ CPacket(uint8_t* pPacketPart, uint32 nSize, bool bLast, bool bFromPF = true); // only used for splitted packets! + + ~CPacket(); + +- byte* GetHeader(); +- byte* GetUDPHeader(); +- byte* GetPacket(); +- byte* DetachPacket(); ++ uint8_t* GetHeader(); ++ uint8_t* GetUDPHeader(); ++ uint8_t* GetPacket(); ++ uint8_t* DetachPacket(); + uint32 GetRealPacketSize() const { return size + 6; } +- static uint32 GetPacketSizeFromHeader(const byte* rawHeader); ++ static uint32 GetPacketSizeFromHeader(const uint8_t* rawHeader); + bool IsSplitted() { return m_bSplitted; } + bool IsLastSplitted() { return m_bLastSplitted; } + void PackPacket(); +@@ -66,9 +66,9 @@ public: + uint32 GetPacketSize() const { return size; } + uint8 GetProtocol() const { return prot; } + void SetProtocol(uint8 p) { prot = p; } +- const byte* GetDataBuffer(void) const { return pBuffer; } ++ const uint8_t* GetDataBuffer(void) const { return pBuffer; } + void Copy16ToDataBuffer(const void* data); +- void CopyToDataBuffer(unsigned int offset, const byte* data, unsigned int n); ++ void CopyToDataBuffer(unsigned int offset, const uint8_t* data, unsigned int n); + void CopyUInt32ToDataBuffer(uint32 data, unsigned int offset = 0); + + private: +@@ -82,10 +82,10 @@ private: + bool m_bLastSplitted; + bool m_bPacked; + bool m_bFromPF; +- byte head[6]; +- byte* tempbuffer; +- byte* completebuffer; +- byte* pBuffer; ++ uint8_t head[6]; ++ uint8_t* tempbuffer; ++ uint8_t* completebuffer; ++ uint8_t* pBuffer; + }; + + #endif // PACKET_H +diff --git a/src/Parser.cpp b/src/Parser.cpp +index 4d78feb..74f3e89 100644 +--- a/src/Parser.cpp ++++ b/src/Parser.cpp +@@ -929,7 +929,7 @@ yytnamerr (char *yyres, const char *yystr) + + /* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not ++ including the terminating null uint8_t. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during +diff --git a/src/PartFile.cpp b/src/PartFile.cpp +index ad2768f..1a4ef88 100644 +--- a/src/PartFile.cpp ++++ b/src/PartFile.cpp +@@ -123,7 +123,7 @@ public: + uint64 end; // This is the end offset of the data + Requested_Block_Struct *block; // This is the requested block that this data relates to + +- PartFileBufferedData(CFileAutoClose& file, byte * data, uint64 _start, uint64 _end, Requested_Block_Struct *_block) ++ PartFileBufferedData(CFileAutoClose& file, uint8_t * data, uint64 _start, uint64 _end, Requested_Block_Struct *_block) + : start(_start), end(_end), block(_block) + { + area.StartWriteAt(file, start, end-start+1); +@@ -881,7 +881,7 @@ bool CPartFile::SavePartFile(bool Initial) + for (CGapList::const_iterator it = m_gaplist.begin(); it != m_gaplist.end(); ++it) { + wxString tagName = CFormat(wxT(" %u")) % i_pos; + +- // gap start = first missing byte but gap ends = first non-missing byte ++ // gap start = first missing uint8_t but gap ends = first non-missing uint8_t + // in edonkey but I think its easier to user the real limits + tagName[0] = FT_GAPSTART; + CTagIntSized(tagName, it.start(), IsLargeFile() ? 64 : 32).WriteTagToFile( &file ); +@@ -2863,7 +2863,7 @@ int CPartFile::GetCommonFilePenalty() + // Kry - transize is 32bits, no packet can be more than that (this is + // compressed size). Even 32bits is too much imho.As for the return size, + // look at the lenData below. +-uint32 CPartFile::WriteToBuffer(uint32 transize, byte* data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient* client) ++uint32 CPartFile::WriteToBuffer(uint32 transize, uint8_t* data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient* client) + { + // Increment transferred bytes counter for this file + transferred += transize; +diff --git a/src/PartFile.h b/src/PartFile.h +index ed22213..5c8f3d5 100644 +--- a/src/PartFile.h ++++ b/src/PartFile.h +@@ -162,7 +162,7 @@ public: + int getPartfileStatusRang() const; + + // Barry - Added as replacement for BlockReceived to buffer data before writing to disk +- uint32 WriteToBuffer(uint32 transize, byte *data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient* client); ++ uint32 WriteToBuffer(uint32 transize, uint8_t *data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient* client); + void FlushBuffer(bool fromAICHRecoveryDataAvailable = false); + + // Barry - Added to prevent list containing deleted blocks on shutdown +diff --git a/src/PartFileConvert.cpp b/src/PartFileConvert.cpp +index 8427f31..ce96e49 100644 +--- a/src/PartFileConvert.cpp ++++ b/src/PartFileConvert.cpp +@@ -389,7 +389,7 @@ ConvStatus CPartFileConvert::performConvertToeMule(const CPath& fileName) + + CPath::RemoveFile(newfilename.RemoveExt()); + if (!oldfile.FileExists()) { +- // data file does not exist. well, then create a 0 byte big one ++ // data file does not exist. well, then create a 0 uint8_t big one + CFile datafile; + ret = datafile.Create(newfilename.RemoveExt()); + } else if (s_pfconverting->removeSource) { +diff --git a/src/PrefsUnifiedDlg.cpp b/src/PrefsUnifiedDlg.cpp +index 66842fd..3cee7c2 100644 +--- a/src/PrefsUnifiedDlg.cpp ++++ b/src/PrefsUnifiedDlg.cpp +@@ -1152,7 +1152,7 @@ void PrefsUnifiedDlg::OnScrollBarChange( wxScrollEvent& event ) + case IDC_FILEBUFFERSIZE: + id = IDC_FILEBUFFERSIZE_STATIC; + // Yes, it seems odd to add the singular form here, but other languages might need to know the number to select the appropriate translation +- label = CFormat(wxPLURAL("File Buffer Size: %d byte", "File Buffer Size: %d bytes", event.GetPosition() * 15000)) % (event.GetPosition() * 15000); ++ label = CFormat(wxPLURAL("File Buffer Size: %d uint8_t", "File Buffer Size: %d bytes", event.GetPosition() * 15000)) % (event.GetPosition() * 15000); + break; + + case IDC_QUEUESIZE: +diff --git a/src/RLE.cpp b/src/RLE.cpp +index ae5642f..1d95b35 100644 +--- a/src/RLE.cpp ++++ b/src/RLE.cpp +@@ -123,7 +123,7 @@ const uint8 *RLE_Data::Decode(const uint8 *buff, int len) + j += seqLen; + i += 3; + } else { +- // This is a single byte. ++ // This is a single uint8_t. + if (j < m_len) { + decBuf[j] = buff[i]; + } +@@ -180,7 +180,7 @@ const uint8 * RLE_Data::Encode(const uint8 *data, int inlen, int &outlen, bool & + // + // now RLE + // +- // In worst case 2-byte sequence is encoded as 3. So, data can grow by 50%. ++ // In worst case 2-uint8_t sequence is encoded as 3. So, data can grow by 50%. + uint8 * enc_buff = new uint8[m_len * 3/2 + 1]; + int i = 0, j = 0; + while ( i != m_len ) { +diff --git a/src/SHA.cpp b/src/SHA.cpp +index 2d831a8..eb44fbc 100644 +--- a/src/SHA.cpp ++++ b/src/SHA.cpp +@@ -58,8 +58,8 @@ + --------------------------------------------------------------------------- + Issue Date: 30/11/2002 + +- This is a byte oriented version of SHA1 that operates on arrays of bytes +- stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor ++ This is a uint8_t oriented version of SHA1 that operates on arrays of bytes ++ stored in memory. It runs at 22 cycles per uint8_t on a Pentium P4 processor + */ + + #include "SHA.h" +@@ -78,8 +78,8 @@ CSHA::CSHA() + It may well fail, in which case the definitions will need to be set by + editing at the points marked **** EDIT HERE IF NECESSARY **** below. + */ +-#define SHA_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +-#define SHA_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ ++#define SHA_LITTLE_ENDIAN 1234 /* uint8_t 0 is least significant (i386) */ ++#define SHA_BIG_ENDIAN 4321 /* uint8_t 0 is most significant (mc68k) */ + + #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) + +@@ -93,7 +93,7 @@ CSHA::CSHA() + + #define SHA1_MASK (SHA1_BLOCK_SIZE - 1) + +-/* reverse byte order in 32-bit words */ ++/* reverse uint8_t order in 32-bit words */ + + #define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) + #define parity(x,y,z) ((x) ^ (y) ^ (z)) +@@ -213,15 +213,15 @@ void CSHA::Finish(CAICHHash& Hash) + uint32 i = (uint32)(m_nCount[0] & SHA1_MASK); + + /* mask out the rest of any partial 32-bit word and then set */ +- /* the next byte to 0x80. On big-endian machines any bytes in */ ++ /* the next uint8_t to 0x80. On big-endian machines any bytes in */ + /* the buffer will be at the top end of 32 bit words, on little */ + /* endian machines they will be at the bottom. Hence the AND */ + /* and OR masks above are reversed for little endian systems */ +- /* Note that we can always add the first padding byte at this */ ++ /* Note that we can always add the first padding uint8_t at this */ + /* because the buffer always contains at least one empty slot */ + m_nBuffer[i >> 2] = (m_nBuffer[i >> 2] & mask[i & 3]) | bits[i & 3]; + +- /* we need 9 or more empty positions, one for the padding byte */ ++ /* we need 9 or more empty positions, one for the padding uint8_t */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if(i > SHA1_BLOCK_SIZE - 9) +@@ -236,7 +236,7 @@ void CSHA::Finish(CAICHHash& Hash) + while(i < 14) /* and zero pad all but last two positions */ + m_nBuffer[i++] = 0; + +- /* assemble the eight byte counter in in big-endian format */ ++ /* assemble the eight uint8_t counter in in big-endian format */ + m_nBuffer[14] = swap_b32((m_nCount[1] << 3) | (m_nCount[0] >> 29)); + m_nBuffer[15] = swap_b32(m_nCount[0] << 3); + +diff --git a/src/SHA.h b/src/SHA.h +index 8854c44..7749e26 100644 +--- a/src/SHA.h ++++ b/src/SHA.h +@@ -58,8 +58,8 @@ + --------------------------------------------------------------------------- + Issue Date: 30/11/2002 + +- This is a byte oriented version of SHA1 that operates on arrays of bytes +- stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor ++ This is a uint8_t oriented version of SHA1 that operates on arrays of bytes ++ stored in memory. It runs at 22 cycles per uint8_t on a Pentium P4 processor + */ + + #ifndef __SHA_H__ +diff --git a/src/SHAHashSet.h b/src/SHAHashSet.h +index 6746417..e3d7ea1 100644 +--- a/src/SHAHashSet.h ++++ b/src/SHAHashSet.h +@@ -104,12 +104,12 @@ class CUpDownClient; + class CAICHHash + { + private: +- byte m_abyBuffer[HASHSIZE]; ++ uint8_t m_abyBuffer[HASHSIZE]; + + public: + CAICHHash() { memset(m_abyBuffer, 0, HASHSIZE); } + CAICHHash(CFileDataIO* file) { Read(file); } +- CAICHHash(byte* data) { Read(data); } ++ CAICHHash(uint8_t* data) { Read(data); } + CAICHHash(const CAICHHash& k1) { *this = k1; } + ~CAICHHash() {} + CAICHHash& operator=(const CAICHHash& k1) +@@ -124,9 +124,9 @@ public: + friend bool operator!=(const CAICHHash& k1,const CAICHHash& k2) { return !(k1 == k2); } + void Read(CFileDataIO* file); + void Write(CFileDataIO* file) const; +- void Read(byte* data) { memcpy(m_abyBuffer, data, HASHSIZE); } ++ void Read(uint8_t* data) { memcpy(m_abyBuffer, data, HASHSIZE); } + wxString GetString() const; +- byte* GetRawHash() { return m_abyBuffer; } ++ uint8_t* GetRawHash() { return m_abyBuffer; } + static uint32 GetHashSize() { return HASHSIZE;} + unsigned int DecodeBase32(const wxString &base32); + }; +diff --git a/src/SafeFile.cpp b/src/SafeFile.cpp +index 5b0cfad..5a75b7a 100644 +--- a/src/SafeFile.cpp ++++ b/src/SafeFile.cpp +@@ -396,7 +396,7 @@ CTag *CFileDataIO::ReadTag(bool bOptACP) const + { + CTag *retVal = NULL; + wxString name; +- byte type = 0; ++ uint8_t type = 0; + try { + type = ReadUInt8(); + name = ReadString(false); +diff --git a/src/Scanner.cpp b/src/Scanner.cpp +index 35478ac..9117aa5 100644 +--- a/src/Scanner.cpp ++++ b/src/Scanner.cpp +@@ -1761,7 +1761,7 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) + + /** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. +- * @param bytes the byte buffer to scan ++ * @param bytes the uint8_t buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. +diff --git a/src/SearchList.cpp b/src/SearchList.cpp +index 32b28e9..647f296 100644 +--- a/src/SearchList.cpp ++++ b/src/SearchList.cpp +@@ -470,7 +470,7 @@ void CSearchList::OnGlobalSearchTimer(CTimerEvent& WXUNUSED(evt)) + } + + +-void CSearchList::ProcessSharedFileList(const byte* in_packet, uint32 size, ++void CSearchList::ProcessSharedFileList(const uint8_t* in_packet, uint32 size, + CUpDownClient* sender, bool *moreResultsAvailable, const wxString& directory) + { + wxCHECK_RET(sender, wxT("No sender in search-results from client.")); +@@ -967,7 +967,7 @@ void CSearchList::KademliaSearchKeyword(uint32_t searchID, const Kademlia::CUInt + EUtf8Str eStrEncode = utf8strRaw; + + CMemFile temp(250); +- byte fileid[16]; ++ uint8_t fileid[16]; + fileID->ToByteArray(fileid); + temp.WriteHash(CMD4Hash(fileid)); + +diff --git a/src/SearchList.h b/src/SearchList.h +index 35b0fc6..414411b 100644 +--- a/src/SearchList.h ++++ b/src/SearchList.h +@@ -126,7 +126,7 @@ public: + * @param moreResultsAvailable Set to a value specifying if more results are available. + * @param directory The directory containing the shared files. + */ +- void ProcessSharedFileList(const byte* packet, uint32 size, CUpDownClient* sender, bool* moreResultsAvailable, const wxString& directory); ++ void ProcessSharedFileList(const uint8_t* packet, uint32 size, CUpDownClient* sender, bool* moreResultsAvailable, const wxString& directory); + + /** + * Processes a search-result sent via TCP from the local server. All results are added. +diff --git a/src/ServerList.cpp b/src/ServerList.cpp +index f2e14e0..8c52634 100644 +--- a/src/ServerList.cpp ++++ b/src/ServerList.cpp +@@ -112,7 +112,7 @@ bool CServerList::LoadServerMet(const CPath& path) + try { + Notify_ServerFreeze(); + +- byte version = servermet.ReadUInt8(); ++ uint8_t version = servermet.ReadUInt8(); + + if (version != 0xE0 && version != MET_HEADER) { + AddLogLineC(CFormat(_("Server.met file corrupt, found invalid versiontag: 0x%x, size %i")) % version % sizeof(version)); +@@ -290,7 +290,7 @@ void CServerList::ServerStats() + // if it doesn't get responsed, we don't count it as error but continue with a normal ping + ping_server->SetCryptPingReplyPending(true); + uint32 nPacketLen = 4 + (uint8)(rand() % 16); // max padding 16 bytes +- CScopedArray pRawPacket(nPacketLen); ++ CScopedArray pRawPacket(nPacketLen); + uint32 dwChallenge = (rand() << 17) | (rand() << 2) | (rand() & 0x03); + if (dwChallenge == 0) { + dwChallenge++; +diff --git a/src/ServerSocket.cpp b/src/ServerSocket.cpp +index f0e32e6..5d7755f 100644 +--- a/src/ServerSocket.cpp ++++ b/src/ServerSocket.cpp +@@ -226,7 +226,7 @@ void CServerSocket::OnReceive(int nErrorCode) + m_dwLastTransmission = GetTickCount(); + } + +-bool CServerSocket::ProcessPacket(const byte* packet, uint32 size, int8 opcode) ++bool CServerSocket::ProcessPacket(const uint8_t* packet, uint32 size, int8 opcode) + { + try { + AddDebugLogLineN( logServer, wxT("Processing Server Packet: ") ); +diff --git a/src/ServerSocket.h b/src/ServerSocket.h +index 155e824..57c6b01 100644 +--- a/src/ServerSocket.h ++++ b/src/ServerSocket.h +@@ -65,7 +65,7 @@ public: + uint32 GetServerIP() const; + + private: +- bool ProcessPacket(const byte* packet, uint32 size, int8 opcode); ++ bool ProcessPacket(const uint8_t* packet, uint32 size, int8 opcode); + void SetConnectionState(sint8 newstate); + CServerConnect* serverconnect; + sint8 connectionstate; +diff --git a/src/ServerUDPSocket.cpp b/src/ServerUDPSocket.cpp +index 4e840c0..2a8e0de 100644 +--- a/src/ServerUDPSocket.cpp ++++ b/src/ServerUDPSocket.cpp +@@ -60,12 +60,12 @@ CServerUDPSocket::CServerUDPSocket(amuleIPV4Address &address, const CProxyData * + } + + +-void CServerUDPSocket::OnPacketReceived(uint32 serverip, uint16 serverport, byte* buffer, size_t length) ++void CServerUDPSocket::OnPacketReceived(uint32 serverip, uint16 serverport, uint8_t* buffer, size_t length) + { + wxCHECK_RET(length >= 2, wxT("Invalid packet.")); + + size_t nPayLoadLen = length; +- byte* pBuffer = buffer; ++ uint8_t* pBuffer = buffer; + CServer* pServer = theApp->serverlist->GetServerByIPUDP(serverip, serverport, true); + if (pServer && thePrefs::IsServerCryptLayerUDPEnabled() && + ((pServer->GetServerKeyUDP() != 0 && pServer->SupportsObfuscationUDP()) || (pServer->GetCryptPingReplyPending() && pServer->GetChallenge() != 0))) +@@ -238,7 +238,7 @@ void CServerUDPSocket::ProcessPacket(CMemFile& packet, uint8 opcode, uint32 ip, + // eserver 16.45+ supports a new OP_SERVER_DESC_RES answer, if the OP_SERVER_DESC_REQ contains a uint32 + // challenge, the server returns additional info with OP_SERVER_DESC_RES. To properly distinguish the + // old and new OP_SERVER_DESC_RES answer, the challenge has to be selected carefully. The first 2 bytes +- // of the challenge (in network byte order) MUST NOT be a valid string-len-int16! ++ // of the challenge (in network uint8_t order) MUST NOT be a valid string-len-int16! + CPacket* sendpacket = new CPacket(OP_SERVER_DESC_REQ, 4, OP_EDONKEYPROT); + uint32 uDescReqChallenge = ((uint32)GetRandomUint16() << 16) + INV_SERV_DESC_LEN; // 0xF0FF = an 'invalid' string length. + update->SetDescReqChallenge(uDescReqChallenge); +@@ -263,7 +263,7 @@ void CServerUDPSocket::ProcessPacket(CMemFile& packet, uint8 opcode, uint32 ip, + // new packet: + // + // NOTE: To properly distinguish between the two packets which are both useing the same opcode... +- // the first two bytes of (in network byte order) have to be an invalid at least. ++ // the first two bytes of (in network uint8_t order) have to be an invalid at least. + + uint16 Len = packet.ReadUInt16(); + +@@ -365,7 +365,7 @@ void CServerUDPSocket::SendPacket(CPacket* packet, CServer* host, bool delPacket + // We might need to encrypt the packet for this server. + if (!rawpacket && thePrefs::IsServerCryptLayerUDPEnabled() && host->GetServerKeyUDP() != 0 && host->SupportsObfuscationUDP()) { + uint16 uRawPacketSize = packet->GetPacketSize() + 2; +- byte* pRawPacket = new byte[uRawPacketSize]; ++ uint8_t* pRawPacket = new uint8_t[uRawPacketSize]; + memcpy(pRawPacket, packet->GetUDPHeader(), 2); + memcpy(pRawPacket + 2, packet->GetDataBuffer(), packet->GetPacketSize()); + +diff --git a/src/ServerUDPSocket.h b/src/ServerUDPSocket.h +index 6caed5d..a7acfea 100644 +--- a/src/ServerUDPSocket.h ++++ b/src/ServerUDPSocket.h +@@ -44,7 +44,7 @@ public: + virtual void OnReceiveError(int errorCode, uint32 ip, uint16 port); + + private: +- void OnPacketReceived(uint32 ip, uint16 port, byte* buffer, size_t length); ++ void OnPacketReceived(uint32 ip, uint16 port, uint8_t* buffer, size_t length); + void ProcessPacket(CMemFile& packet, uint8 opcode, uint32 ip, uint16 port); + void SendQueue(); + +diff --git a/src/Statistics.cpp b/src/Statistics.cpp +index 23ce7a2..d8896a8 100644 +--- a/src/Statistics.cpp ++++ b/src/Statistics.cpp +@@ -403,7 +403,7 @@ void CStatistics::RecordHistory() + // running average computations, use differences (delta bytes/ delta time), and + // for long uptimes the difference between two timestamps can lose too much + // accuracy because the large mantissa causes less significant bits to be dropped +- // (same for the difference between two cumulative byte counts). [We don't store ++ // (same for the difference between two cumulative uint8_t counts). [We don't store + // these values as integers because they will be used in floating point calculations, + // and we want to perform the conversion only once). Therefore timestamps and + // Kbyte counts are stored in the history as doubles, while computed values use +diff --git a/src/Tag.cpp b/src/Tag.cpp +index 2e7e0c8..29475c4 100644 +--- a/src/Tag.cpp ++++ b/src/Tag.cpp +@@ -286,7 +286,7 @@ uint32 CTag::GetBlobSize() const + } + + +-const byte* CTag::GetBlob() const ++const uint8_t* CTag::GetBlob() const + { + CHECK_TAG_TYPE(IsBlob(), Blob); + +@@ -302,7 +302,7 @@ uint32 CTag::GetBsobSize() const + } + + +-const byte* CTag::GetBsob() const ++const uint8_t* CTag::GetBsob() const + { + CHECK_TAG_TYPE(IsBsob(), Bsob); + +diff --git a/src/Tag.h b/src/Tag.h +index eb5ae25..a57f00a 100644 +--- a/src/Tag.h ++++ b/src/Tag.h +@@ -70,10 +70,10 @@ public: + + const CMD4Hash& GetHash() const; + +- const byte* GetBlob() const; ++ const uint8_t* GetBlob() const; + uint32 GetBlobSize() const; + +- const byte* GetBsob() const; ++ const uint8_t* GetBsob() const; + uint32 GetBsobSize() const; + + CTag* CloneTag() { return new CTag(*this); } +@@ -268,11 +268,11 @@ public: + class CTagBsob : public CTag + { + public: +- CTagBsob(const wxString& name, const byte* value, uint8 nSize) ++ CTagBsob(const wxString& name, const uint8_t* value, uint8 nSize) + : CTag(name) + { + m_uType = TAGTYPE_BSOB; +- m_pData = new byte[nSize]; ++ m_pData = new uint8_t[nSize]; + memcpy(m_pData, value, nSize); + m_nSize = nSize; + } +@@ -281,11 +281,11 @@ public: + class CTagBlob : public CTag + { + public: +- CTagBlob(const wxString& name, const byte* value, uint8 nSize) ++ CTagBlob(const wxString& name, const uint8_t* value, uint8 nSize) + : CTag(name) + { + m_uType = TAGTYPE_BLOB; +- m_pData = new byte[nSize]; ++ m_pData = new uint8_t[nSize]; + memcpy(m_pData, value, nSize); + m_nSize = nSize; + } +diff --git a/src/ThreadTasks.cpp b/src/ThreadTasks.cpp +index 327ab7e..2a43d00 100644 +--- a/src/ThreadTasks.cpp ++++ b/src/ThreadTasks.cpp +@@ -42,7 +42,7 @@ + #endif + + //! This hash represents the value for an empty MD4 hashing +-const byte g_emptyMD4Hash[16] = { ++const uint8_t g_emptyMD4Hash[16] = { + 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, + 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }; + +@@ -383,7 +383,7 @@ bool CAICHSyncTask::ConvertToKnown2ToKnown264() + CAICHHash aichHash(&oldfile); + uint32 nHashCount = oldfile.ReadUInt16(); + +- CScopedArray buffer(nHashCount * CAICHHash::GetHashSize()); ++ CScopedArray buffer(nHashCount * CAICHHash::GetHashSize()); + + oldfile.Read(buffer.get(), nHashCount * CAICHHash::GetHashSize()); + newfile.Write(aichHash.GetRawHash(), CAICHHash::GetHashSize()); +diff --git a/src/UploadBandwidthThrottler.cpp b/src/UploadBandwidthThrottler.cpp +index 67ebabf..17bcaba 100644 +--- a/src/UploadBandwidthThrottler.cpp ++++ b/src/UploadBandwidthThrottler.cpp +@@ -294,7 +294,7 @@ void* UploadBandwidthThrottler::Entry() + uint32 sleepTime; + if (bytesToSpend < 1) { + // We have sent more than allowed in last cycle so we have to wait now +- // until we can send at least 1 byte. ++ // until we can send at least 1 uint8_t. + sleepTime = std::max((-bytesToSpend + 1) * 1000 / allowedDataRate + 2, // add 2 ms to allow for rounding inaccuracies + extraSleepTime); + } else { +diff --git a/src/UploadClient.cpp b/src/UploadClient.cpp +index a74ab92..5c7522a 100644 +--- a/src/UploadClient.cpp ++++ b/src/UploadClient.cpp +@@ -206,7 +206,7 @@ void CUpDownClient::CreateNextBlockPackage() + // correctly treated as plain CKnownFile. + CPartFile* srcPartFile = srcfile->IsPartFile() ? static_cast(srcfile) : NULL; + +- // THIS EndOffset points BEHIND the last byte requested ++ // THIS EndOffset points BEHIND the last uint8_t requested + // (other than the offsets used in the PartFile code) + if (currentblock->EndOffset > srcfile->GetFileSize()) { + throw wxString(CFormat(wxT("Asked for data up to %d beyond end of file (%d)")) +@@ -282,7 +282,7 @@ void CUpDownClient::CreateNextBlockPackage() + } + + +-void CUpDownClient::CreateStandardPackets(const byte* buffer, uint32 togo, Requested_Block_Struct* currentblock) ++void CUpDownClient::CreateStandardPackets(const uint8_t* buffer, uint32 togo, Requested_Block_Struct* currentblock) + { + uint32 nPacketSize; + +@@ -330,10 +330,10 @@ void CUpDownClient::CreateStandardPackets(const byte* buffer, uint32 togo, Reque + } + + +-void CUpDownClient::CreatePackedPackets(const byte* buffer, uint32 togo, Requested_Block_Struct* currentblock) ++void CUpDownClient::CreatePackedPackets(const uint8_t* buffer, uint32 togo, Requested_Block_Struct* currentblock) + { + uLongf newsize = togo+300; +- CScopedArray output(newsize); ++ CScopedArray output(newsize); + uint16 result = compress2(output.get(), &newsize, buffer, togo, 9); + if (result != Z_OK || togo <= newsize){ + CreateStandardPackets(buffer, togo, currentblock); +@@ -836,7 +836,7 @@ void CUpDownClient::SetUploadFileID(const CMD4Hash& new_id) + SetUploadFileID(uploadingfile); // This will update queue count on old and new file. + } + +-void CUpDownClient::ProcessRequestPartsPacket(const byte* pachPacket, uint32 nSize, bool largeblocks) { ++void CUpDownClient::ProcessRequestPartsPacket(const uint8_t* pachPacket, uint32 nSize, bool largeblocks) { + + CMemFile data(pachPacket, nSize); + +diff --git a/src/kademlia/kademlia/Kademlia.cpp b/src/kademlia/kademlia/Kademlia.cpp +index f0f657b..70ca262 100644 +--- a/src/kademlia/kademlia/Kademlia.cpp ++++ b/src/kademlia/kademlia/Kademlia.cpp +@@ -499,7 +499,7 @@ bool CKademlia::IsRunningInLANMode() + #include "../../CryptoPP_Inc.h" + void KadGetKeywordHash(const wxString& rstrKeyword, Kademlia::CUInt128* pKadID) + { +- byte Output[16]; ++ uint8_t Output[16]; + + #ifdef __WEAK_CRYPTO__ + CryptoPP::Weak::MD4 md4_hasher; +diff --git a/src/kademlia/kademlia/Search.cpp b/src/kademlia/kademlia/Search.cpp +index e60a354..0177caa 100644 +--- a/src/kademlia/kademlia/Search.cpp ++++ b/src/kademlia/kademlia/Search.cpp +@@ -509,7 +509,7 @@ void CSearch::StorePacket() + } else { + if (m_searchTermsDataSize == 0) { + searchTerms.WriteUInt8(0); +- // We send this extra byte to flag we handle large files. ++ // We send this extra uint8_t to flag we handle large files. + searchTerms.WriteUInt8(0); + } else { + // Set to 2 to flag we handle large files. +diff --git a/src/kademlia/kademlia/SearchManager.cpp b/src/kademlia/kademlia/SearchManager.cpp +index e7f25d4..34200d5 100644 +--- a/src/kademlia/kademlia/SearchManager.cpp ++++ b/src/kademlia/kademlia/SearchManager.cpp +@@ -234,8 +234,8 @@ void CSearchManager::GetWords(const wxString& str, WordList *words, bool allowDu + while (tkz.HasMoreTokens()) { + current_word = tkz.GetNextToken(); + // TODO: We'd need a safe way to determine if a sequence which contains only 3 chars is a real word. +- // Currently we do this by evaluating the UTF-8 byte count. This will work well for Western locales, +- // AS LONG AS the min. byte count is 3(!). If the byte count is once changed to 2, this will not ++ // Currently we do this by evaluating the UTF-8 uint8_t count. This will work well for Western locales, ++ // AS LONG AS the min. uint8_t count is 3(!). If the uint8_t count is once changed to 2, this will not + // work properly any longer because there are a lot of Western characters which need 2 bytes in UTF-8. + // Maybe we need to evaluate the Unicode character values itself whether the characters are located + // in code ranges where single characters are known to represent words. +diff --git a/src/kademlia/net/KademliaUDPListener.cpp b/src/kademlia/net/KademliaUDPListener.cpp +index e11dd5e..16e91c7 100644 +--- a/src/kademlia/net/KademliaUDPListener.cpp ++++ b/src/kademlia/net/KademliaUDPListener.cpp +@@ -1668,7 +1668,7 @@ void CKademliaUDPListener::SendLegacyChallenge(uint32_t ip, uint16_t port, const + } + + #if 0 +-void CKademliaUDPListener::DebugClientOutput(const wxString& place, uint32 kad_ip, uint32 port, const byte* data, int len) ++void CKademliaUDPListener::DebugClientOutput(const wxString& place, uint32 kad_ip, uint32 port, const uint8_t* data, int len) + { + uint32 ip = wxUINT32_SWAP_ALWAYS(kad_ip); + printf("Error on %s received from: %s\n",(const char*)unicode2char(place),(const char*)unicode2char(Uint32_16toStringIP_Port(ip,port))); +diff --git a/src/libs/common/StringFunctions.cpp b/src/libs/common/StringFunctions.cpp +index 3710760..ba1f755 100644 +--- a/src/libs/common/StringFunctions.cpp ++++ b/src/libs/common/StringFunctions.cpp +@@ -48,7 +48,7 @@ Unicode2CharBuf unicode2char(const wxChar* s) + } + // Failed. Try to convert as much as possible. + size_t len = wxStrlen(s); +- size_t maxlen = len * 4; // Allow for an encoding of up to 4 byte per char. ++ size_t maxlen = len * 4; // Allow for an encoding of up to 4 uint8_t per char. + wxCharBuffer buf(maxlen + 1); // This is wasteful, but the string is used temporary anyway. + char * data = buf.data(); + for (size_t i = 0, pos = 0; i < len; i++) { +@@ -64,7 +64,7 @@ Unicode2CharBuf unicode2char(const wxChar* s) + } + + +-static byte base16Chars[17] = "0123456789ABCDEF"; ++static uint8_t base16Chars[17] = "0123456789ABCDEF"; + + wxString URLEncode(const wxString& sIn) + { +diff --git a/src/libs/ec/cpp/ECSocket.cpp b/src/libs/ec/cpp/ECSocket.cpp +index a0283cc..22da25c 100644 +--- a/src/libs/ec/cpp/ECSocket.cpp ++++ b/src/libs/ec/cpp/ECSocket.cpp +@@ -66,12 +66,12 @@ struct utf8_table { + + static const struct utf8_table utf8_table[] = + { +- {0x80, 0x00, 0*6, 0x7F, 0, /* 1 byte sequence */}, +- {0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 byte sequence */}, +- {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, /* 3 byte sequence */}, +- {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */}, +- {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */}, +- {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */}, ++ {0x80, 0x00, 0*6, 0x7F, 0, /* 1 uint8_t sequence */}, ++ {0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 uint8_t sequence */}, ++ {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, /* 3 uint8_t sequence */}, ++ {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 uint8_t sequence */}, ++ {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 uint8_t sequence */}, ++ {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 uint8_t sequence */}, + {0, 0, 0, 0, 0, /* end of table */} + }; + +diff --git a/src/libs/ec/cpp/ECTag.cpp b/src/libs/ec/cpp/ECTag.cpp +index 7ba9e3a..255f3ac 100644 +--- a/src/libs/ec/cpp/ECTag.cpp ++++ b/src/libs/ec/cpp/ECTag.cpp +@@ -118,7 +118,7 @@ CECTag::CECTag(ec_tagname_t name, const EC_IPv4_t& data) : m_tagName(name) + /** + * Creates a new CECTag instance, which contains a MD4 hash. + * +- * This function takes care to store hash in network byte order. ++ * This function takes care to store hash in network uint8_t order. + * + * @param name TAG name + * @param data The CMD4Hash class containing the MD4 hash. +@@ -1007,7 +1007,7 @@ void CECTag::DebugPrint(int level, bool print_empty) const + case EC_TAGTYPE_UINT128: + // Using any non-inline function from UInt128.h would break linkage + // of remote apps otherwise not using CUInt128. So just fall through +- // and display the value as a byte-stream. Since the value is sent ++ // and display the value as a uint8_t-stream. Since the value is sent + // big-endian on the network, the visual result is correct, except + // for the intervening spaces... + //s2 = GetInt128Data().ToHexString(); break; +diff --git a/src/updownclient.h b/src/updownclient.h +index 2930df4..7dac1e9 100644 +--- a/src/updownclient.h ++++ b/src/updownclient.h +@@ -202,7 +202,7 @@ public: + + void ClearDownloadBlockRequests(); + void RequestSharedFileList(); +- void ProcessSharedFileList(const byte* pachPacket, uint32 nSize, wxString& pszDirectory); ++ void ProcessSharedFileList(const uint8_t* pachPacket, uint32 nSize, wxString& pszDirectory); + void SendSharedDirectories(); + void SendSharedFilesOfDirectory(const wxString& strReqDir); + +@@ -212,13 +212,13 @@ public: + + uint8 GetClientSoft() const { return m_clientSoft; } + void ReGetClientSoft(); +- bool ProcessHelloAnswer(const byte* pachPacket, uint32 nSize); +- bool ProcessHelloPacket(const byte* pachPacket, uint32 nSize); ++ bool ProcessHelloAnswer(const uint8_t* pachPacket, uint32 nSize); ++ bool ProcessHelloPacket(const uint8_t* pachPacket, uint32 nSize); + void SendHelloAnswer(); + bool SendHelloPacket(); + void SendMuleInfoPacket(bool bAnswer, bool OSInfo = false); +- bool ProcessMuleInfoPacket(const byte* pachPacket, uint32 nSize); +- void ProcessMuleCommentPacket(const byte* pachPacket, uint32 nSize); ++ bool ProcessMuleInfoPacket(const uint8_t* pachPacket, uint32 nSize); ++ void ProcessMuleCommentPacket(const uint8_t* pachPacket, uint32 nSize); + bool Compare(const CUpDownClient* tocomp, bool bIgnoreUserhash = false) const; + void SetLastSrcReqTime() { m_dwLastSourceRequest = ::GetTickCount(); } + void SetLastSrcAnswerTime() { m_dwLastSourceAnswer = ::GetTickCount(); } +@@ -234,17 +234,17 @@ public: + + bool SafeSendPacket(CPacket* packet); + +- void ProcessRequestPartsPacket(const byte* pachPacket, uint32 nSize, bool largeblocks); ++ void ProcessRequestPartsPacket(const uint8_t* pachPacket, uint32 nSize, bool largeblocks); + void ProcessRequestPartsPacketv2(const CMemFile& data); + + void SendPublicKeyPacket(); + void SendSignaturePacket(); +- void ProcessPublicKeyPacket(const byte* pachPacket, uint32 nSize); +- void ProcessSignaturePacket(const byte* pachPacket, uint32 nSize); ++ void ProcessPublicKeyPacket(const uint8_t* pachPacket, uint32 nSize); ++ void ProcessSignaturePacket(const uint8_t* pachPacket, uint32 nSize); + uint8 GetSecureIdentState(); + + void SendSecIdentStatePacket(); +- void ProcessSecIdentStatePacket(const byte* pachPacket, uint32 nSize); ++ void ProcessSecIdentStatePacket(const uint8_t* pachPacket, uint32 nSize); + + uint8 GetInfoPacketsReceived() const { return m_byInfopacketsReceived; } + void InfoPacketsReceived(); +@@ -340,12 +340,12 @@ public: + bool AskForDownload(); + void SendStartupLoadReq(); + void SendFileRequest(); +- void ProcessHashSet(const byte* packet, uint32 size); ++ void ProcessHashSet(const uint8_t* packet, uint32 size); + bool AddRequestForAnotherFile(CPartFile* file); + bool DeleteFileRequest(CPartFile* file); + void DeleteAllFileRequests(); + void SendBlockRequests(); +- void ProcessBlockPacket(const byte* packet, uint32 size, bool packed, bool largeblocks); ++ void ProcessBlockPacket(const uint8_t* packet, uint32 size, bool packed, bool largeblocks); + uint16 GetAvailablePartCount() const; + + bool SwapToAnotherFile(bool bIgnoreNoNeeded, bool ignoreSuspensions, bool bRemoveCompletely, CPartFile* toFile = NULL); +@@ -389,14 +389,14 @@ public: + bool IsSupportingAICH() const {return m_fSupportsAICH & 0x01;} + void SendAICHRequest(CPartFile* pForFile, uint16 nPart); + bool IsAICHReqPending() const {return m_fAICHRequested; } +- void ProcessAICHAnswer(const byte* packet, uint32 size); +- void ProcessAICHRequest(const byte* packet, uint32 size); ++ void ProcessAICHAnswer(const uint8_t* packet, uint32 size); ++ void ProcessAICHRequest(const uint8_t* packet, uint32 size); + void ProcessAICHFileHash(CMemFile* data, const CPartFile* file); + + EUtf8Str GetUnicodeSupport() const; + + // Barry - Process zip file as it arrives, don't need to wait until end of block +- int unzip(Pending_Block_Struct *block, byte *zipped, uint32 lenZipped, byte **unzipped, uint32 *lenUnzipped, int iRecursion = 0); ++ int unzip(Pending_Block_Struct *block, uint8_t *zipped, uint32 lenZipped, uint8_t **unzipped, uint32 *lenUnzipped, int iRecursion = 0); + void UpdateDisplayedInfo(bool force = false); + int GetFileListRequested() const { return m_iFileListRequested; } + void SetFileListRequested(int iFileListRequested) { m_iFileListRequested = iFileListRequested; } +@@ -413,7 +413,7 @@ public: + + const wxString& GetClientOSInfo() const { return m_sClientOSInfo; } + +- void ProcessPublicIPAnswer(const byte* pbyData, uint32 uSize); ++ void ProcessPublicIPAnswer(const uint8_t* pbyData, uint32 uSize); + void SendPublicIPRequest(); + + /** +@@ -473,8 +473,8 @@ public: + + /* Kad buddy support */ + // ID +- const byte* GetBuddyID() const { return m_achBuddyID; } +- void SetBuddyID(const byte* m_achTempBuddyID); ++ const uint8_t* GetBuddyID() const { return m_achBuddyID; } ++ void SetBuddyID(const uint8_t* m_achTempBuddyID); + bool HasValidBuddyID() const { return m_bBuddyIDValid; } + /* IP */ + void SetBuddyIP( uint32 val ) { m_nBuddyIP = val; } +@@ -789,7 +789,7 @@ private: + ESourceFrom m_nSourceFrom; + + /* Kad Stuff */ +- byte m_achBuddyID[16]; ++ uint8_t m_achBuddyID[16]; + bool m_bBuddyIDValid; + uint32 m_nBuddyIP; + uint16 m_nBuddyPort; +diff --git a/src/utils/aLinkCreator/src/md4.cpp b/src/utils/aLinkCreator/src/md4.cpp +index 52c7b7f..595fc19 100644 +--- a/src/utils/aLinkCreator/src/md4.cpp ++++ b/src/utils/aLinkCreator/src/md4.cpp +@@ -43,7 +43,7 @@ + #include "bithelp.h" + + +-/// BIG ENDIAN byte reversing ++/// BIG ENDIAN uint8_t reversing + #if wxBYTE_ORDER == wxBIG_ENDIAN + // Note: this code is harmless on little-endian machines. + void MD4::byteReverse(unsigned char *buf, unsigned longs) +@@ -106,7 +106,7 @@ void MD4::MD4Update(struct MD4Context *ctx, unsigned char const *buf, + len -= t; + } + +- // Process data in 64-byte chunks ++ // Process data in 64-uint8_t chunks + while (len >= 64) + { + memcpy(ctx->in, buf, 64); +@@ -121,7 +121,7 @@ void MD4::MD4Update(struct MD4Context *ctx, unsigned char const *buf, + } + + +-/// Final wrapup - pad to 64-byte boundary with the bit pattern ++/// Final wrapup - pad to 64-uint8_t boundary with the bit pattern + /// 1 0* (64-bit count of bits processed, MSB-first) + void MD4::MD4Final(struct MD4Context *ctx, unsigned char* digest) + { +@@ -132,7 +132,7 @@ void MD4::MD4Final(struct MD4Context *ctx, unsigned char* digest) + count = (ctx->bits[0] >> 3) & 0x3F; + + // Set the first char of padding to 0x80. +- //This is safe since there is always at least one byte free ++ //This is safe since there is always at least one uint8_t free + p = ctx->in + count; + *p++ = 0x80; + +diff --git a/src/utils/aLinkCreator/src/md4.h b/src/utils/aLinkCreator/src/md4.h +index c54167e..ebda1e2 100644 +--- a/src/utils/aLinkCreator/src/md4.h ++++ b/src/utils/aLinkCreator/src/md4.h +@@ -77,7 +77,7 @@ class MD4 + + size_t calcBufSize(size_t filesize); + +- // Needed to reverse byte order on BIG ENDIAN machines ++ // Needed to reverse uint8_t order on BIG ENDIAN machines + #if wxBYTE_ORDER == wxBIG_ENDIAN + + void byteReverse(unsigned char *buf, unsigned longs); +diff --git a/src/utils/fileview/KadFiles.cpp b/src/utils/fileview/KadFiles.cpp +index a2ded24..c1e497e 100644 +--- a/src/utils/fileview/KadFiles.cpp ++++ b/src/utils/fileview/KadFiles.cpp +@@ -52,7 +52,7 @@ void DecodeLoadIndexDat(const CFileDataIO& file) + #include "../../CryptoPP_Inc.h" + void KadGetKeywordHash(const wxString& rstrKeyword, Kademlia::CUInt128* pKadID) + { +- byte Output[16]; ++ uint8_t Output[16]; + #ifdef CRYPTOPP_ENABLE_NAMESPACE_WEAK + CryptoPP::Weak::MD4 md4_hasher; + #else +@@ -62,7 +62,7 @@ void KadGetKeywordHash(const wxString& rstrKeyword, Kademlia::CUInt128* pKadID) + // This should be safe - we assume rstrKeyword is ANSI anyway. + Unicode2CharBuf ansi_buffer(unicode2UTF8(rstrKeyword)); + +- md4_hasher.CalculateDigest(Output, (const byte *) (const char *) ansi_buffer, strlen(ansi_buffer)); ++ md4_hasher.CalculateDigest(Output, (const uint8_t *) (const char *) ansi_buffer, strlen(ansi_buffer)); + + pKadID->SetValueBE(Output); + } +-- +2.17.1 + diff --git a/amule/patches/0003-fix-set_terminate.patch b/amule/patches/0003-fix-set_terminate.patch new file mode 100644 index 000000000..924a001e9 --- /dev/null +++ b/amule/patches/0003-fix-set_terminate.patch @@ -0,0 +1,25 @@ +From dcc605e06e106b05bc5e756eeeeb17abbc1a6e5c Mon Sep 17 00:00:00 2001 +From: W_Y_CPP <383152993@qq.com> +Date: Wed, 1 Dec 2021 23:13:08 -0800 +Subject: [PATCH] fix set_terminate + +--- + src/libs/common/MuleDebug.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libs/common/MuleDebug.cpp b/src/libs/common/MuleDebug.cpp +index 5d8d758..14206f9 100644 +--- a/src/libs/common/MuleDebug.cpp ++++ b/src/libs/common/MuleDebug.cpp +@@ -24,7 +24,7 @@ + // + + #include // Needed for std::abort() +- ++#include + #ifdef HAVE_CONFIG_H + # include "config.h" // Needed for HAVE_CXXABI and HAVE_EXECINFO + #endif +-- +2.17.1 + diff --git a/amule/patches/001-amule-dlp.patch b/amule/patches/001-amule-dlp.patch new file mode 100644 index 000000000..5a37a27a6 --- /dev/null +++ b/amule/patches/001-amule-dlp.patch @@ -0,0 +1,1548 @@ +diff -Naur a/configure.ac b/configure.ac +--- a/configure.ac 2016-10-06 19:01:54.000000000 +0800 ++++ b/configure.ac 2016-10-14 12:33:51.660347919 +0800 +@@ -89,6 +89,14 @@ + KDE_CONFIG_OPTIONS + QT_CONFIG_OPTIONS + ++#Dynamic Leecher Protection - Bill Lee ++AC_ARG_ENABLE( ++ [dlp], ++ [AS_HELP_STRING( ++ [--disable-dlp], ++ [Do not compile DLP.])], ++ [ENABLE_DLP=$enableval], [ENABLE_DLP=yes]) ++ + # Default is yes, because they're most likely compatible. + # However, this is only used when cross-compiling. + AC_ARG_WITH( +@@ -457,6 +465,8 @@ + AM_CONDITIONAL(GENERATE_FLEX_HEADER, test x$HAVE_FLEX_EXTENDED = xyes) + AM_CONDITIONAL(INSTALL_SKINS, test MULE_IS_ENABLED_ANY([monolithic, amule-gui])) + AM_CONDITIONAL(PLASMAMULE, test MULE_IS_ENABLED([plasmamule])) ++#Dynamic Leech Protection - Bill Lee ++AM_CONDITIONAL(ENABLE_DLP, test x$ENABLE_DLP = xyes) + + AM_CONDITIONAL([COMPILE_LIB_COMMON], [test MULE_IS_ENABLED_ANY([monolithic, amule-daemon, amulecmd, webserver, amule-gui, fileview])]) + AM_CONDITIONAL([COMPILE_LIB_EC], [test MULE_IS_ENABLED_ANY([monolithic, amule-daemon, amulecmd, webserver, amule-gui])]) +diff -Naur a/po/zh_CN.po b/po/zh_CN.po +--- a/po/zh_CN.po 2016-10-06 19:01:54.000000000 +0800 ++++ b/po/zh_CN.po 2016-10-14 12:33:51.662347964 +0800 +@@ -5,6 +5,7 @@ + # xiaoqiao <29551030@qq.com>, 2007, 2008. + # JimHu , 2009. + # Xiaoqiao , 2010. ++# Bill Lee , 2010, 2011. + # Yi Qi ,2011. + # + msgid "" +@@ -467,6 +468,12 @@ + msgid "http://kademlia.scs.cs.nyu.edu\n" + msgstr "http://kademlia.scs.cs.nyu.edu\n" + ++msgid "\nDynamic Leech Protection\n" ++msgstr "\n动态吸血保护\n" ++ ++msgid " Homepage: http://amule-dlp.googlecode.com \n" ++msgstr " 主页:http://amule-dlp.googlecode.com \n" ++ + #: src/amuleDlg.cpp:512 src/KadDlg.cpp:193 src/PartFile.cpp:918 + #: src/PartFile.cpp:926 src/PrefsUnifiedDlg.cpp:629 + #: src/PrefsUnifiedDlg.cpp:734 src/PrefsUnifiedDlg.cpp:847 +@@ -3856,6 +3863,9 @@ + msgid "Click on this button to update the nodes list from URL ..." + msgstr "按此更新节点列表自网址..." + ++msgid "DLP Info" ++msgstr "动态反吸血信息" ++ + #: src/muuli_wdr.cpp:2649 + msgid "Nodes (0)" + msgstr "节点(0)" +@@ -7682,6 +7692,48 @@ + #~ "\n" + #~ "此外,浏览器设定已经被重设为系统默认值。如有必要,请重新配置浏览器选项。\n" + ++msgid "Dynamic Leecher Protection Options" ++msgstr "动态反吸血保护选项" ++ ++msgid "Reload antiLeech" ++msgstr "重新装载 antiLeech" ++ ++msgid "Check bad modstring" ++msgstr "根据 Mod 名字检测吸血驴" ++ ++msgid "Check bad username" ++msgstr "根据用户名字检测吸血驴" ++ ++msgid "Check bad userhash" ++msgstr "检测错误的用户哈希值" ++ ++msgid "Check bad hello tag" ++msgstr "根据握手标签(HelloTag)检测吸血驴" ++ ++msgid "Check bad info tag" ++msgstr "根据 InfoTag 检测吸血驴" ++ ++msgid "Check ghost mod" ++msgstr "检测幽灵客户端(Ghost Mod)" ++ ++#~ msgid "Ban VeryCD easyMule2" ++#~ msgstr "屏蔽 VeryCD easyMule2" ++ ++msgid "Ban eMule VeryCD mod(Please consider carefully whether to use)" ++msgstr "屏蔽 VeryCD eMule(请慎重考虑是否使用)" ++ ++#~ msgid "Ban VeryCD miniMule" ++#~ msgstr "屏蔽 VeryCD miniMule" ++ ++msgid "Trying to load antiLeech..." ++msgstr "尝试加载 antiLeech..." ++ ++msgid "No antiLeech available!" ++msgstr "未找到 antiLeech!" ++ ++msgid "Succeed loading antiLeech! Version: %d" ++msgstr "成功加载 antiLeech! 版本: %d" ++ + #~ msgid "Fetching status..." + #~ msgstr "正在获取状态..." + +diff -Naur a/src/BaseClient.cpp b/src/BaseClient.cpp +--- a/src/BaseClient.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/BaseClient.cpp 2016-10-14 12:35:45.793953665 +0800 +@@ -1,4 +1,3 @@ +-// + // This file is part of the aMule Project. + // + // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) +@@ -23,6 +22,11 @@ + // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + // + ++//Dynamic Leech Protect - Bill Lee ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif ++ + #include + #include + #include +@@ -83,10 +87,8 @@ + #include "kademlia/kademlia/UDPFirewallTester.h" + #include "kademlia/routing/RoutingZone.h" + +- + //#define __PACKET_DEBUG__ + +- + // some client testing variables + static wxString crash_name = wxT("[Invalid User Name]"); + static wxString empty_name = wxT("[Empty User Name]"); +@@ -290,6 +292,10 @@ + m_cMessagesReceived = 0; + m_cMessagesSent = 0; + ++ #ifdef AMULE_DLP ++ dlp_nonofficialopcodes = false; //Dynamic Leecher Protect ++ #endif ++ + } + + +@@ -635,6 +641,15 @@ + m_fSharedDirectories = 1; + dwEmuleTags |= 4; + break; ++ //Bill Lee start ++ //Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ default: //if tag isn't those above, it may be used by leecher. ++ theDLP->CheckHelloTag(this, temptag.GetNameID()); ++ dlp_nonofficialopcodes = true; //to detect Ghost Mod ++ break; ++ //Bill Lee end ++ #endif + } + } + +@@ -717,6 +732,11 @@ + Kademlia::CKademlia::Bootstrap(wxUINT32_SWAP_ALWAYS(GetIP()), GetKadPort()); + } + ++ //Dynamic Leecher Protection - Bill Lee ++ #ifdef AMULE_DLP ++ theDLP->DLPCheck(this); ++ #endif ++ + return bIsMule; + } + +@@ -966,6 +986,14 @@ + % GetClientFullInfo() + ); + ++ //Bill Lee start ++ //Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ theDLP->CheckInfoTag(this, temptag.GetNameID()); ++ dlp_nonofficialopcodes = true; ++ #endif ++ //Bill Lee end ++ + break; + } + } +@@ -1003,6 +1031,11 @@ + m_byInfopacketsReceived |= IP_EMULEPROTPACK; + } + ++ //Dynamic Leecher Protection - Added by Bill Lee ++ #ifdef AMULE_DLP ++ theDLP->DLPCheck(this); ++ #endif ++ + return (protocol_version == 0xFF); // This was a OS_Info? + } + +@@ -2302,7 +2335,7 @@ + } + + +-#ifdef __DEBUG__ ++#if defined (__DEBUG__) || defined (AMULE_DLP) + wxString CUpDownClient::GetClientFullInfo() + { + if (m_clientVerString.IsEmpty()) { +diff -Naur a/src/CString_wx.h b/src/CString_wx.h +--- a/src/CString_wx.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/CString_wx.h 2016-10-14 12:33:51.664348010 +0800 +@@ -0,0 +1,59 @@ ++/** ++ * Author: Bill Lee ++ * License: GNU GPL ++ */ ++//--------------------- ++#ifndef CSTRING_WX_H ++#define CSTRING_WX_H ++ ++//#include ++#include ++ ++class CString : public wxString{ ++ public: ++ CString(){} ++ CString(wxChar c, size_t n=1): wxString(c, n){} ++ CString(const wxChar* str): wxString(str){} ++ CString(const wxString& str): wxString(str){} ++ CString(const CString& str): wxString(str){} ++ //--------------------- ++ CString& operator=(const wxChar* str){ ++ wxString::operator=(str); ++ return *this; ++ } ++ //operator*() from wxString; ++ size_t GetLength()const{ return Length(); } ++ wxChar GetAt(size_t nIndex)const{ return GetChar(nIndex); } ++ //IsEmpty() from wxString; ++ CString& TrimLeft(wxChar c){ ++ size_t pos = find_first_not_of(c); ++ if(pos == 0) ++ return *this; ++ erase(0, pos); ++ return *this; ++ } ++ CString& TrimRight(wxChar c){ ++ size_t pos = find_last_not_of(c) + 1; ++ if(pos == Length()) ++ return *this; ++ erase(pos, Length() - pos); ++ return *this; ++ } ++ CString Trim(){ ++ CString ret(*this); ++ ret.wxString::Trim(false); /* wxString::Trim(bool fromright = true) */ ++ ret.wxString::Trim(true); ++ return ret; ++ } ++ //Find(wxChar) and Find(wxChar*) from wxString; ++ int Find(const CString& str)const{ return wxString::Find(str.c_str()); } ++ int ReverseFind(const wxChar c)const{ return wxString::Find(c, true); } ++ int ReverseFind(const wxChar* str)const{ return rfind(str); } ++ int ReverseFind(const CString& str)const{ return rfind(str); } ++ CString Right(size_t len)const{ return wxString::Right(len); } ++ CString Left(size_t len)const{ return wxString::Left(len); } ++ CString Mid(size_t first, size_t count = wxSTRING_MAXLEN)const{ ++ return wxString::Mid(first, count); ++ } ++}; ++#endif +diff -Naur a/src/DLP.cpp b/src/DLP.cpp +--- a/src/DLP.cpp 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/DLP.cpp 2016-10-14 12:33:51.664348010 +0800 +@@ -0,0 +1,190 @@ ++// Copyright (C) 2011 Bill Lee ++// ++// This program 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 2 of the License, or ++// (at your option) any later version. ++// ++// This program 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, write to the Free Software ++// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++// ++#include "Logger.h" ++ ++#include "DLP.h" ++#include "antiLeech.h" ++#include /* Needed for wxDynamicLibrary */ ++ ++#include "DLPPref.h" ++#include "Preferences.h" // Needed for CPreferences ++#include "amule.h" // Needed for theApp ++ ++#include /* Needed for wxStandardPaths */ ++ ++#define PRE_CHECK(tag) if( (!c->IsBanned()) && antiLeech && (thePrefs::GetDLPCheckMask() & tagn) ) ++ ++void DLP::CheckHelloTag(CUpDownClient* c, UINT tagn){ ++ PRE_CHECK(PF_HELLOTAG){ ++ const wxChar* dlp_result = antiLeech->DLPCheckHelloTag(tagn); ++ if(dlp_result != NULL) { ++ wxString ret; ++ ret.Printf(_("[HelloTag %s] %s"), dlp_result, c->GetClientFullInfo().c_str()); ++ //ret.Printf(_("[HelloTag %s] %s"), dlp_result, c->GetClientShortInfo().c_str()); ++ c->Ban(); ++ theApp->AddDLPMessageLine(ret); ++ } ++ } ++} ++ ++void DLP::CheckInfoTag(CUpDownClient* c, UINT tagn){ ++ PRE_CHECK(PF_INFOTAG){ ++ const wxChar* dlp_result = antiLeech->DLPCheckInfoTag(tagn); ++ if(dlp_result != NULL) { ++ wxString ret; ++ ret.Printf(_("[InfoTag %s] %s"), dlp_result, c->GetClientFullInfo().c_str()); ++ //ret.Printf(_("[InfoTag %s] %s"), dlp_result, c->GetClientShortInfo().c_str()); ++ c->Ban(); ++ theApp->AddDLPMessageLine(ret); ++ } ++ } ++} ++ ++bool DLP::DLPCheck(CUpDownClient* c){ ++ const wxChar* tmp = NULL; ++ wxString ret; ++ ++ unsigned int prefs = thePrefs::GetDLPCheckMask(); ++ ++ CString modver(c->GetClientModString()); ++ CString clientver(c->GetClientVerString()); ++ CString uname(c->GetUserName()); ++ CString uhash(wxString(c->GetUserHash().EncodeSTL().c_str(), wxConvUTF8)); ++ ++ //CheckGhostMod ++ if(prefs & PF_GHOSTMOD) { ++ if(c->HasNonOfficialOpCodes() && (modver.IsEmpty())) { ++ ret = _("GhostMod"); ++ tmp = ret.c_str(); //char pointer ++ } ++ } ++ ++ // Check bad modstring ++ if ((prefs & PF_MODSTRING) && (tmp == NULL)) { ++ if((tmp = antiLeech->DLPCheckModstring_Soft(modver.c_str(), clientver.c_str())) == NULL) ++ tmp = antiLeech->DLPCheckModstring_Hard(modver.c_str(), clientver.c_str()); ++ } ++ /* ++ if ((prefs & PF_USERHASH) && (tmp == NULL)) { ++ // not finished ++ } ++ */ ++ // Check bad username ++ if ((prefs & PF_USERNAME) && (tmp == NULL)) { ++ if ((tmp = antiLeech->DLPCheckNameAndHashAndMod(uname, uhash, modver)) == NULL){ ++ if( (tmp = antiLeech->DLPCheckUsername_Hard(uname.c_str())) == NULL ) ++ tmp = antiLeech->DLPCheckUsername_Soft(uname.c_str()); ++ } ++ } ++ ++ ++ // Check VeryCD eMule ++ if ((prefs & PF_VERYCDEMULE) && (tmp == NULL)) { ++ if(modver.Find(wxT("VeryCD")) != wxNOT_FOUND){ ++ ret = _("VeryCD Mod"); ++ tmp = ret.c_str(); ++ } ++ } ++ ++ if (tmp != NULL) { ++ ret = tmp; ++ wxString wxInfo; ++ wxInfo.Printf(wxT("[%s] %s"), ret.c_str(), c->GetClientFullInfo().c_str()); ++ //wxInfo.Printf(wxT("[%s] %s"), ret.c_str(), c->GetClientShortInfo().c_str()); ++ c->Ban(); ++ theApp->AddDLPMessageLine(wxInfo); ++ return true; ++ } ++ ++ return false; ++ ++} ++ ++int DLP::ReloadAntiLeech(){ ++ //Unloading ++ AddLogLineN( _("Checking if there is a antiLeech working...")); ++ if(antiLeechLib.IsLoaded()){ ++ Destoryer fn = (Destoryer)(antiLeechLib.GetSymbol( wxT("destoryAntiLeechInstant"))); ++ wxASSERT(fn); ++ AddLogLineN( _("Unload previous antiLeech...")); ++ fn(antiLeech); ++ antiLeech = NULL; ++ antiLeechLib.Unload(); ++ } ++ else ++ AddLogLineN( _("No working antiLeech exists.")); ++ //Get lib's location ++ wxStandardPathsBase &spb(wxStandardPaths::Get()); ++#ifdef __WXMSW__ ++ wxString dataDir(spb.GetPluginsDir()); ++#elif defined(__WXMAC__) ++ wxString dataDir(spb.GetDataDir()); ++#else ++ wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule")); ++#endif ++ wxString localName = wxDynamicLibrary::CanonicalizeName(wxT("antiLeech")); ++ wxString systemwideFile(JoinPaths(dataDir, localName)); ++ //wxString userFile(theApp->ConfigDir + localName); ++ wxString userFile(thePrefs::GetConfigDir() + localName); ++ wxString fallbackFile(wxT("antiLeech")); ++ //Try to load lib; ++ AddLogLineN( _("Trying to load antiLeech...")); ++ if( !LoadFrom(userFile) ){ ++ if( !LoadFrom(systemwideFile) ){ ++ if( !LoadFrom(fallbackFile) ){ ++ AddLogLineC( _("No antiLeech available!")); ++ return 1; //Not found ++ } ++ } ++ } ++ //Searching symbol "createAntiLeechInstant" ++ Creator fn = (Creator)(antiLeechLib.GetSymbol( wxT("createAntiLeechInstant") )); ++ if(!fn){ ++ antiLeechLib.Unload(); ++ AddLogLineC( _("antiLeech found, but it seems not to be a valid antiLeech!")); ++ return 2; //Found, but isn't antiLeech ++ } ++ //Try to create antiLeech ++ antiLeech = fn(); ++ if(antiLeech){ ++ wxString logline; ++ logline.Printf(_("Succeed loading antiLeech! Version: %d"), antiLeech->GetDLPVersion()); ++ AddLogLineC( logline); ++ return 0; ++ } ++ //else ++ antiLeechLib.Unload(); ++ AddLogLineC( _("FAIL! An error occur when setting up antiLeech.")); ++ return 3; //Fail to create antiLeech instant ++ ++} ++ ++DLP::~DLP(){ ++ if(antiLeechLib.IsLoaded()){ ++ Destoryer fn = (Destoryer)(antiLeechLib.GetSymbol( wxT("destoryAntiLeechInstant"))); ++ wxASSERT(fn); ++ AddLogLineN( _("Unload previous antiLeech...")); ++ fn(antiLeech); ++ //antiLeech = NULL; ++ //antiLeechLib.Unload(); ++ } ++} ++ ++bool DLP::LoadFrom(wxString& file){ ++ antiLeechLib.Load(file); ++ return antiLeechLib.IsLoaded(); ++} +diff -Naur a/src/DLP.h b/src/DLP.h +--- a/src/DLP.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/DLP.h 2016-10-14 12:33:51.665348032 +0800 +@@ -0,0 +1,45 @@ ++// Copyright (C) 2011 Bill Lee ++// ++// This program 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 2 of the License, or ++// (at your option) any later version. ++// ++// This program 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, write to the Free Software ++// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++// ++ ++class IantiLeech; //forward declaretion ++ ++#include "updownclient.h" // Needed for CUpDownClient ++#include "antiLeech_wx.h" ++ ++#include ++ ++class DLP ++{ ++public: ++ DLP() : antiLeech(NULL) { ReloadAntiLeech(); } ++ ~DLP(); ++ ++ void CheckHelloTag(CUpDownClient*, UINT tagnumber); ++ void CheckInfoTag(CUpDownClient*, UINT tagnumber); ++ bool DLPCheck(CUpDownClient*); ++ ++ int ReloadAntiLeech(); ++ ++private: ++ typedef IantiLeech* (*Creator)(); ++ typedef int (*Destoryer)(IantiLeech*); ++ ++ wxDynamicLibrary antiLeechLib; ++ IantiLeech* antiLeech; ++ ++ bool LoadFrom(wxString& file); ++}; +diff -Naur a/src/DLPPref.h b/src/DLPPref.h +--- a/src/DLPPref.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/DLPPref.h 2016-10-14 12:33:51.665348032 +0800 +@@ -0,0 +1,15 @@ ++#ifndef ANTILEECH_AMULE_H ++#define ANTILEECH_AMULE_H ++ ++/* Define DLPCheck prefs arg */ ++#define PF_MODSTRING 0x1 ++#define PF_USERHASH 0x2 ++#define PF_USERNAME 0x4 ++#define PF_HELLOTAG 0x8 ++#define PF_INFOTAG 0x10 ++#define PF_VERYCDEMULE 0x20 ++//#define PF_EASYMULE 0x40 ++//#define PF_MINIMULE 0x80 ++#define PF_GHOSTMOD 0x100 ++ ++#endif +diff -Naur a/src/DownloadQueue.cpp b/src/DownloadQueue.cpp +--- a/src/DownloadQueue.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/DownloadQueue.cpp 2016-10-14 12:33:51.665348032 +0800 +@@ -623,6 +623,15 @@ + return; + } + ++ //Dynamic Leecher Protect - Bill Lee ++ #ifdef AMULE_DLP ++ if ( source->IsBanned() ){ ++ source->Safe_Delete(); ++ return; ++ } ++ #endif ++ //Bill Lee end ++ + // Filter sources which are known to be dead/useless + if ( theApp->clientlist->IsDeadSource( source ) || sender->IsDeadSource(source) ) { + source->Safe_Delete(); +diff -Naur a/src/ExternalConn.cpp b/src/ExternalConn.cpp +--- a/src/ExternalConn.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/ExternalConn.cpp 2016-10-14 12:33:51.666348055 +0800 +@@ -57,6 +57,9 @@ + #include "kademlia/kademlia/UDPFirewallTester.h" + #include "Statistics.h" + ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif + + //-------------------- File_Encoder -------------------- + +@@ -1384,6 +1387,15 @@ + } + } + break; ++ //Dynamic Leech Protect - Bill Lee ++ #ifdef AMULE_DLP ++ case EC_OP_ANTILEECH_RELOAD: ++ if( theDLP->ReloadAntiLeech() ) ++ response = new CECPacket(EC_OP_FAILED); ++ else ++ response = new CECPacket(EC_OP_NOOP); ++ break; ++ #endif + // + // Status requests + // +diff -Naur a/src/Logger.cpp b/src/Logger.cpp +--- a/src/Logger.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Logger.cpp 2016-10-14 12:40:22.827322335 +0800 +@@ -297,6 +297,8 @@ + } + + CLogger theLogger; ++//Dynamic Leech Protect - persmule ++CLogger dlpLogger; + + BEGIN_EVENT_TABLE(CLogger, wxEvtHandler) + EVT_MULE_LOGGING(CLogger::OnLoggingEvent) +diff -Naur a/src/Logger.h b/src/Logger.h +--- a/src/Logger.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Logger.h 2016-10-14 12:41:14.694519856 +0800 +@@ -310,6 +310,8 @@ + }; + + extern CLogger theLogger; ++//Dynamic Leech Protect - persmule ++extern CLogger dlpLogger; + + /** + * This class forwards log-lines from wxWidgets to CLogger. +@@ -456,5 +458,8 @@ + #define AddLogLineF(string) theLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false) + #endif + ++//Dynamic Leech Protect - persmule ++#define DlpAddLogLine(string) dlpLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false) ++ + #endif + // File_checked_for_headers +diff -Naur a/src/LoggerConsole.cpp b/src/LoggerConsole.cpp +--- a/src/LoggerConsole.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/LoggerConsole.cpp 2016-10-14 12:41:54.805446813 +0800 +@@ -85,6 +85,8 @@ + } + + CLogger theLogger; ++//Dynamic Leech Protect - persmule ++CLogger dlpLogger; + + BEGIN_EVENT_TABLE(CLogger, wxEvtHandler) + END_EVENT_TABLE() +diff -Naur a/src/Makefile.am b/src/Makefile.am +--- a/src/Makefile.am 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Makefile.am 2016-10-14 12:33:51.666348055 +0800 +@@ -179,6 +179,13 @@ + kademlia/routing/RoutingZone.cpp + + ++#Dynamic Leecher Protection - Bill Lee ++if ENABLE_DLP ++core_sources += \ ++ DLP.cpp ++AM_CPPFLAGS += -DAMULE_DLP ++endif ++ + gui_sources = \ + amule-gui.cpp \ + amuleDlg.cpp \ +diff -Naur a/src/Preferences.cpp b/src/Preferences.cpp +--- a/src/Preferences.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Preferences.cpp 2016-10-14 12:33:51.667348078 +0800 +@@ -51,6 +51,11 @@ + + #include "UserEvents.h" + ++#ifdef AMULE_DLP ++#include "DLPPref.h" ++#include "antiLeech.h" ++#endif ++ + #ifndef AMULE_DAEMON + #include + #include "muuli_wdr.h" +@@ -344,6 +349,19 @@ + wxWindow* m_widget; + }; + ++/* Dynamic Leecher Protection */ ++#ifdef AMULE_DLP ++bool CPreferences::s_DLPCheckModString; ++bool CPreferences::s_DLPCheckUsername; ++bool CPreferences::s_DLPCheckUserHash; ++bool CPreferences::s_DLPCheckHelloTag; ++bool CPreferences::s_DLPCheckInfoTag; ++//bool CPreferences::s_DLPCheckEasyMule; ++bool CPreferences::s_DLPCheckVeryCDMod; ++//bool CPreferences::s_DLPCheckminiMule; //Added by Bill Lee ++bool CPreferences::s_DLPCheckGhostMod; ++unsigned int CPreferences::s_DLPCheckMask; ++#endif + + /** Cfg class for wxStrings. */ + class Cfg_Str : public Cfg_Tmpl +@@ -953,6 +971,11 @@ + s_userhash[5] = 14; + s_userhash[14] = 111; + ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ CalcDLPCheckMask(); ++ #endif ++ + #ifndef CLIENT_GUI + LoadPreferences(); + ReloadSharedFolders(); +@@ -1062,6 +1085,20 @@ + NewCfgItem( IDC_NETWORKKAD, (new Cfg_Bool( wxT("/eMule/ConnectToKad"), s_ConnectToKad, true )) ); + NewCfgItem( IDC_NETWORKED2K, ( new Cfg_Bool( wxT("/eMule/ConnectToED2K"), s_ConnectToED2K, true ) )); + ++ /** ++ * Dynamic Leecher Protection ++ **/ ++ #ifdef AMULE_DLP ++ NewCfgItem(IDC_CHECKMODSTRING, (new Cfg_Bool( wxT("/DLP/CheckModString"), s_DLPCheckModString, true ))); ++ NewCfgItem(IDC_CHECKUSERNAME, (new Cfg_Bool( wxT("/DLP/CheckUsername"), s_DLPCheckUsername, true ))); ++ NewCfgItem(IDC_CHECKUSERHASH, (new Cfg_Bool( wxT("/DLP/CheckUserHash"), s_DLPCheckUserHash, true ))); ++ NewCfgItem(IDC_CHECKHELLOTAG, (new Cfg_Bool( wxT("/DLP/CheckHelloTag"), s_DLPCheckHelloTag, true ))); ++ NewCfgItem(IDC_CHECKINFOTAG, (new Cfg_Bool( wxT("/DLP/CheckInfoTag"), s_DLPCheckInfoTag, true ))); ++ //NewCfgItem(IDC_CHECKEASYMULE, (new Cfg_Bool( wxT("/DLP/CheckEasyMule"), s_DLPCheckEasyMule, true ))); //Modified by Bill Lee ++ NewCfgItem(IDC_CHECKVERYCDMOD, (new Cfg_Bool( wxT("/DLP/CheckVeryCDMod"), s_DLPCheckVeryCDMod, false ))); ++ //NewCfgItem(IDC_CHECKMINIMULE, (new Cfg_Bool( wxT("/DLP/CheckminiMule"), s_DLPCheckminiMule, true))); //Added by Bill Lee ++ NewCfgItem(IDC_CHECKGHOSTMOD, (new Cfg_Bool( wxT("/DLP/CheckGhostMod"), s_DLPCheckGhostMod, true ))); //Added by Bill Lee. ++ #endif + + /** + * Files +@@ -1471,6 +1508,11 @@ + } + + SavePreferences(); ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ CalcDLPCheckMask(); ++ #endif + + #ifndef CLIENT_GUI + CTextFile sdirfile; +@@ -1483,6 +1525,21 @@ + #endif + } + ++#ifdef AMULE_DLP ++void CPreferences::CalcDLPCheckMask() ++{ ++ s_DLPCheckMask = 0; ++ if (s_DLPCheckModString) s_DLPCheckMask |= PF_MODSTRING; ++ if (s_DLPCheckUsername) s_DLPCheckMask |= PF_USERNAME; ++ if (s_DLPCheckUserHash) s_DLPCheckMask |= PF_USERHASH; ++ if (s_DLPCheckHelloTag) s_DLPCheckMask |= PF_HELLOTAG; ++ if (s_DLPCheckInfoTag) s_DLPCheckMask |= PF_INFOTAG; ++ if (s_DLPCheckGhostMod) s_DLPCheckMask |= PF_GHOSTMOD; ++ //if (s_DLPCheckEasyMule) s_DLPCheckMask |= PF_EASYMULE; ++ if (s_DLPCheckVeryCDMod) s_DLPCheckMask |= PF_VERYCDEMULE; ++ //if (s_DLPCheckminiMule) s_DLPCheckMask |= PF_MINIMULE; //Added by Bill Lee ++} ++#endif + + CPreferences::~CPreferences() + { +diff -Naur a/src/Preferences.h b/src/Preferences.h +--- a/src/Preferences.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/Preferences.h 2016-10-14 12:33:51.667348078 +0800 +@@ -579,6 +579,11 @@ + // Sleep + static bool GetPreventSleepWhileDownloading() { return s_preventSleepWhileDownloading; } + static void SetPreventSleepWhileDownloading(bool status) { s_preventSleepWhileDownloading = status; } ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ static unsigned int GetDLPCheckMask() {return s_DLPCheckMask;} ++ #endif + protected: + static int32 GetRecommendedMaxConnections(); + +@@ -599,6 +604,11 @@ + private: + void LoadPreferences(); + void SavePreferences(); ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ void CalcDLPCheckMask(); ++ #endif + + protected: + static wxString s_configDir; +@@ -813,6 +823,20 @@ + // Stats server + static wxString s_StatsServerName; + static wxString s_StatsServerURL; ++ ++ // Dynamic Leecher Protection ++ #ifdef AMULE_DLP ++ static bool s_DLPCheckModString; ++ static bool s_DLPCheckUsername; ++ static bool s_DLPCheckUserHash; ++ static bool s_DLPCheckHelloTag; ++ static bool s_DLPCheckInfoTag; ++ //static bool s_DLPCheckEasyMule; ++ static bool s_DLPCheckVeryCDMod; ++ //static bool s_DLPCheckminiMule; //Added by Bill Lee ++ static bool s_DLPCheckGhostMod; //Added by Bill Lee ++ static unsigned int s_DLPCheckMask; ++ #endif + }; + + +diff -Naur a/src/PrefsUnifiedDlg.cpp b/src/PrefsUnifiedDlg.cpp +--- a/src/PrefsUnifiedDlg.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/PrefsUnifiedDlg.cpp 2016-10-14 12:33:51.668348101 +0800 +@@ -53,6 +53,11 @@ + #include "UserEvents.h" + #include "PlatformSpecific.h" // Needed for PLATFORMSPECIFIC_CAN_PREVENT_SLEEP_MODE + ++//Dynamic Leech Protect - Bill Lee ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif ++ + BEGIN_EVENT_TABLE(PrefsUnifiedDlg,wxDialog) + // Events + #define USEREVENTS_EVENT(ID, NAME, VARS) \ +@@ -114,6 +119,11 @@ + EVT_CHOICE(IDC_COLORSELECTOR, PrefsUnifiedDlg::OnColorCategorySelected) + EVT_LIST_ITEM_SELECTED(ID_PREFSLISTCTRL,PrefsUnifiedDlg::OnPrefsPageChange) + ++ //Dynamic Leech Protect - Bill Lee ++ #ifdef AMULE_DLP ++ EVT_BUTTON(IDC_RELOADANTILEECH, PrefsUnifiedDlg::OnButtonReloadAntiLeech) ++ #endif ++ + EVT_INIT_DIALOG(PrefsUnifiedDlg::OnInitDialog) + + EVT_COMMAND_SCROLL(IDC_SLIDER, PrefsUnifiedDlg::OnScrollBarChange) +@@ -187,6 +197,9 @@ + { wxTRANSLATE("Online Signature"), PreferencesOnlineSigTab, 21 }, + { wxTRANSLATE("Advanced"), PreferencesaMuleTweaksTab, 12 }, + { wxTRANSLATE("Events"), PreferencesEventsTab, 5 } ++#ifdef AMULE_DLP ++ ,{ wxTRANSLATE("DLP"), PreferencesDLPTab, 5} ++#endif + #ifdef __DEBUG__ + ,{ wxTRANSLATE("Debugging"), PreferencesDebug, 25 } + #endif +@@ -1076,6 +1089,21 @@ + theApp->ipfilter->Update( CastChild( IDC_IPFILTERURL, wxTextCtrl )->GetValue() ); + } + ++//Bill Lee ++#ifdef AMULE_DLP ++void PrefsUnifiedDlg::OnButtonReloadAntiLeech(wxCommandEvent& WXUNUSED(event)){ ++ #ifndef CLIENT_GUI ++ if( theDLP->ReloadAntiLeech() ) ++ wxMessageBox(_("Cannot load antiLeech!"), _("Message"), wxOK | wxICON_EXCLAMATION, this); ++ else ++ wxMessageBox(_("Succeed loading antiLeech!"), _("Message"), wxOK | wxICON_INFORMATION, this); ++ #else ++ AddLogLineN(_("Reload antiLeech from remote GUI has not been implemented.")); ++ wxMessageBox(_("Sorry, it has not been implemented yet!")); ++ #endif ++} ++#endif ++ + + void PrefsUnifiedDlg::OnPrefsPageChange(wxListEvent& event) + { +diff -Naur a/src/PrefsUnifiedDlg.h b/src/PrefsUnifiedDlg.h +--- a/src/PrefsUnifiedDlg.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/PrefsUnifiedDlg.h 2016-10-14 12:33:51.668348101 +0800 +@@ -124,6 +124,9 @@ + void OnUserEventSelected(wxListEvent& event); + void OnLanguageChoice(wxCommandEvent &event); + void CreateEventPanels(const int idx, const wxString& vars, wxWindow* parent); ++ #ifdef AMULE_DLP ++ void OnButtonReloadAntiLeech(wxCommandEvent &event); /* Dynamic Leech Protect - Bill Lee */ ++ #endif + + void OnInitDialog( wxInitDialogEvent& evt ); + +diff -Naur a/src/ServerWnd.cpp b/src/ServerWnd.cpp +--- a/src/ServerWnd.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/ServerWnd.cpp 2016-10-14 12:33:51.668348101 +0800 +@@ -46,6 +46,7 @@ + EVT_BUTTON(ID_BTN_RESET, CServerWnd::OnBnClickedResetLog) + EVT_BUTTON(ID_BTN_RESET_SERVER, CServerWnd::OnBnClickedResetServerLog) + EVT_SPLITTER_SASH_POS_CHANGED(ID_SRV_SPLITTER,CServerWnd::OnSashPositionChanged) ++ EVT_BUTTON(ID_BTN_RESET_DLP, CServerWnd::OnBnClickedResetDLPLog) + END_EVENT_TABLE() + + +@@ -152,6 +153,11 @@ + theApp->GetServerLog(true); // Reset it + } + ++void CServerWnd::OnBnClickedResetDLPLog(wxCommandEvent& WXUNUSED(evt)) ++{ ++ wxTextCtrl* cv= CastByID( ID_DLPINFO, this, wxTextCtrl ); ++ cv->Clear(); ++} + + void CServerWnd::UpdateED2KInfo() + { +diff -Naur a/src/ServerWnd.h b/src/ServerWnd.h +--- a/src/ServerWnd.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/ServerWnd.h 2016-10-14 12:33:51.668348101 +0800 +@@ -50,6 +50,7 @@ + void OnBnClickedUpdateservermetfromurl(wxCommandEvent& evt); + void OnBnClickedResetLog(wxCommandEvent& evt); + void OnBnClickedResetServerLog(wxCommandEvent& evt); ++ void OnBnClickedResetDLPLog(wxCommandEvent& evt); + + DECLARE_EVENT_TABLE() + }; +diff -Naur a/src/TextClient.cpp b/src/TextClient.cpp +--- a/src/TextClient.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/TextClient.cpp 2016-10-14 12:33:51.669348124 +0800 +@@ -73,6 +73,7 @@ + CMD_ID_RELOAD_SHARED, + CMD_ID_RELOAD_IPFILTER_LOCAL, + CMD_ID_RELOAD_IPFILTER_NET, ++ CMD_ID_RELOAD_ANTILEECH, /* Only used internally - Dynamic Leech Protect - Bill Lee */ + CMD_ID_SET_IPFILTER_ON, + CMD_ID_SET_IPFILTER_OFF, + CMD_ID_SET_IPFILTER_CLIENTS_ON, +@@ -106,7 +107,6 @@ + CMD_ID_DOWNLOAD, + // IDs for deprecated commands + CMD_ID_SET_IPFILTER +- + }; + + // method to create a SearchFile +@@ -240,6 +240,12 @@ + case CMD_ID_DISCONNECT_KAD: + request_list.push_back(new CECPacket(EC_OP_KAD_STOP)); + break; ++ //Dynamic Leech Protect - Bill Lee ++ #ifdef AMULE_DLP ++ case CMD_ID_RELOAD_ANTILEECH: ++ request_list.push_back(new CECPacket(EC_OP_ANTILEECH_RELOAD)); ++ break; ++ #endif + + case CMD_ID_RELOAD_SHARED: + request_list.push_back(new CECPacket(EC_OP_SHAREDFILES_RELOAD)); +@@ -903,6 +909,9 @@ + tmp2->AddCommand(wxT("Net"), CMD_ID_RELOAD_IPFILTER_NET, wxTRANSLATE("Update IP filtering table from URL."), + wxTRANSLATE("If URL is omitted the URL from the preferences is used."), CMD_PARAM_OPTIONAL); + ++ #ifdef AMULE_DLP ++ tmp->AddCommand(wxT("AntiLeech"), CMD_ID_RELOAD_ANTILEECH, wxTRANSLATE("Reloads antiLeech."), wxEmptyString, CMD_PARAM_NEVER); //Bill Lee ++ #endif + tmp = m_commands.AddCommand(wxT("Connect"), CMD_ID_CONNECT, wxTRANSLATE("Connect to the network."), + wxTRANSLATE("This will connect to all networks that are enabled in Preferences.\nYou may also optionally specify a server address in IP:Port form, to connect to\nthat server only. The IP must be a dotted decimal IPv4 address,\nor a resolvable DNS name."), CMD_PARAM_OPTIONAL); + tmp->AddCommand(wxT("ED2K"), CMD_ID_CONNECT_ED2K, wxTRANSLATE("Connect to eD2k only."), wxEmptyString, CMD_PARAM_NEVER); +diff -Naur a/src/UploadQueue.cpp b/src/UploadQueue.cpp +--- a/src/UploadQueue.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/UploadQueue.cpp 2016-10-14 12:33:51.669348124 +0800 +@@ -390,6 +390,11 @@ + return; + } + ++ //Dynamic Leecher Protect - Bill Lee ++ #if defined AMULE_DLP && defined __DEBUG__ ++ AddLogLineN(client->GetClientFullInfo()); ++ #endif ++ + client->AddAskedCount(); + client->SetLastUpRequest(); + +diff -Naur a/src/amule-gui.cpp b/src/amule-gui.cpp +--- a/src/amule-gui.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amule-gui.cpp 2016-10-14 12:33:51.669348124 +0800 +@@ -333,6 +333,21 @@ + return CamuleApp::GetLog(reset); + } + ++#ifdef AMULE_DLP ++void CamuleGuiApp::AddDLPMessageLine(const wxString &msg) ++{ ++ wxString message; ++ time_t rawtime; ++ struct tm *timeinfo; ++ char tbuf[101]; ++ time(&rawtime); ++ timeinfo = localtime(&rawtime); ++ strftime(tbuf, 100, "%Y-%m-%d %X: ", timeinfo); ++ ++ message = wxString(tbuf, wxConvUTF8) + msg; ++ amuledlg->AddDLPMessageLine(message); ++} ++#endif + + wxString CamuleGuiApp::GetServerLog(bool reset) + { +diff -Naur a/src/amule.cpp b/src/amule.cpp +--- a/src/amule.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amule.cpp 2016-10-14 12:33:51.670348146 +0800 +@@ -23,7 +23,6 @@ + // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + // + +- + #include "amule.h" // Interface declarations. + + #include +@@ -90,6 +89,11 @@ + #include // Do_not_auto_remove + #endif + ++//Dynamic Leecher Protection - Bill Lee ++#ifdef AMULE_DLP ++#include "DLP.h" ++#endif ++ + #ifndef AMULE_DAEMON + #ifdef __WXMAC__ + #include // Do_not_auto_remove +@@ -520,6 +524,11 @@ + uploadqueue = new CUploadQueue(); + ipfilter = new CIPFilter(); + ++ //DLP initialization - Bill Lee ++ #ifdef AMULE_DLP ++ theDLP = new DLP(); ++ #endif ++ + // Creates all needed listening sockets + wxString msg; + if (!ReinitializeNetwork(&msg)) { +@@ -2062,3 +2071,8 @@ + DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE) + DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE) + // File_checked_for_headers ++ ++//Dynamic Leech Protect - Bill Lee ++#ifdef AMULE_DLP ++DLP* theDLP; ++#endif +diff -Naur a/src/amule.h b/src/amule.h +--- a/src/amule.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amule.h 2016-10-14 12:42:22.776093625 +0800 +@@ -135,6 +135,8 @@ + bool m_geometryEnabled; + wxString m_geometryString; + wxString m_logFile; ++ //Dynamic Leech Protect - persmule ++ wxString m_dlplogFile; + wxString m_appName; + wxString m_PidFile; + +@@ -410,6 +412,7 @@ + wxString GetLog(bool reset = false); + wxString GetServerLog(bool reset = false); + void AddServerMessageLine(wxString &msg); ++ void AddDLPMessageLine(const wxString &msg); + DECLARE_EVENT_TABLE() + }; + +@@ -573,6 +576,8 @@ + + virtual int ShowAlert(wxString msg, wxString title, int flags); + ++ void AddDLPMessageLine(const wxString &msg); ++ + DECLARE_EVENT_TABLE() + }; + +@@ -583,3 +588,8 @@ + + #endif // AMULE_H + // File_checked_for_headers ++ ++#ifdef AMULE_DLP ++class DLP; //forward declaretion ++extern DLP* theDLP; ++#endif +diff -Naur a/src/amuleAppCommon.cpp b/src/amuleAppCommon.cpp +--- a/src/amuleAppCommon.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuleAppCommon.cpp 2016-10-14 12:44:08.981552362 +0800 +@@ -65,6 +65,9 @@ + m_configFile = wxT("amule.conf"); + m_logFile = wxT("logfile"); + ++ //Dynamic Leech Protect - persmule ++ m_dlplogFile = wxT("antileech.log"); ++ + if (IsDaemon()) { + m_appName = wxT("aMuleD"); + } else { +@@ -443,6 +446,21 @@ + return false; + } + ++ // Open the dlp log file - Dynamic Leech Protect - persmule ++ if (!IsRemoteGui()){ ++ CPath dlplogfileName = CPath(thePrefs::GetConfigDir() + m_dlplogFile); ++ if (dlplogfileName.FileExists()) { ++ CPath::BackupFile(dlplogfileName, wxT(".bak")); ++ } ++ ++ if (!dlpLogger.OpenLogfile(dlplogfileName.GetRaw())) { ++ // use std err as last resolt to indicate problem ++ fputs("ERROR: unable to open dlp log file\n", stderr); ++ // failure to open log is serious problem ++ return false; ++ } ++ } ++ + // Load Preferences + CPreferences::BuildItemList(thePrefs::GetConfigDir()); + CPreferences::LoadAllItems( wxConfigBase::Get() ); +diff -Naur a/src/amuleDlg.cpp b/src/amuleDlg.cpp +--- a/src/amuleDlg.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuleDlg.cpp 2016-10-14 12:44:47.637582726 +0800 +@@ -315,7 +315,7 @@ + wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook); + wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook); + +- wxASSERT(logs_notebook->GetPageCount() == 4); ++ wxASSERT(logs_notebook->GetPageCount() == 5); + wxASSERT(networks_notebook->GetPageCount() == 2); + + for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) { +@@ -507,7 +507,12 @@ + _("Part of aMule is based on \n") << + _("Kademlia: Peer-to-peer routing based on the XOR metric.\n") << + _(" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n") << +- _("http://kademlia.scs.cs.nyu.edu\n"); ++ _("http://kademlia.scs.cs.nyu.edu\n") << ++ _("\nDynamic Leech Protection\n") << ++ _(" Homepage: http://amule-dlp.googlecode.com \n") << ++ _(" Copyright (C) 2002-2007 Xtreme-Mod \n") << ++ _(" Copyright (C) 2009 greensea \n") << ++ _(" Copyright (C) 2009-2011 Bill Lee \n"); + + if (m_is_safe_state) { + wxMessageBox(msg, _("Message"), wxOK | wxICON_INFORMATION, this); +@@ -659,8 +664,24 @@ + } + cv->ShowPosition(cv->GetLastPosition()-1); + } ++ //Dynamic Leech Protect - persmule ++ DlpAddLogLine(msg); + } + ++#ifdef AMULE_DLP ++void CamuleDlg::AddDLPMessageLine(const wxString& msg) /* modified by Bill Lee */ ++{ ++ wxTextCtrl* cv = CastByID( ID_DLPINFO, m_serverwnd, wxTextCtrl ); ++ if(cv) { ++ if (msg.Length() > 500) { ++ cv->AppendText(msg.Left(500) + wxT("\n")); ++ } else { ++ cv->AppendText(msg + wxT("\n")); ++ } ++ cv->ShowPosition(cv->GetLastPosition()-1); ++ } ++} ++#endif + + void CamuleDlg::ShowConnectionState(bool skinChanged) + { +@@ -1456,7 +1477,9 @@ + if (thePrefs::GetNetworkKademlia()) { + logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name); + } +- ++ ++ logs_notebook->AddPage(m_logpages[4].page, m_logpages[4].name); ++ + // Set the main window. + // If we have both networks active, activate a notebook to select between them. + // If only one is active, show the window directly without a surrounding one tab notebook. +diff -Naur a/src/amuleDlg.h b/src/amuleDlg.h +--- a/src/amuleDlg.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuleDlg.h 2016-10-14 12:33:51.671348169 +0800 +@@ -114,6 +114,9 @@ + + void AddLogLine(const wxString& line); + void AddServerMessageLine(wxString& message); ++ #ifdef AMULE_DLP ++ void AddDLPMessageLine(const wxString& msg); /* Modified by Bill Lee */ ++ #endif + void ResetLog(int id); + + void ShowUserCount(const wxString& info = wxEmptyString); +@@ -231,7 +234,7 @@ + WX_DECLARE_STRING_HASH_MAP(wxZipEntry*, ZipCatalog); + ZipCatalog cat; + +- PageType m_logpages[4]; ++ PageType m_logpages[5]; + PageType m_networkpages[2]; + + bool LoadGUIPrefs(bool override_pos, bool override_size); +diff -Naur a/src/amuled.cpp b/src/amuled.cpp +--- a/src/amuled.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/amuled.cpp 2016-10-14 12:45:23.506600119 +0800 +@@ -749,4 +749,10 @@ + return 0; // That's neither yes nor no, ok, cancel + } + ++void CamuleDaemonApp::AddDLPMessageLine(const wxString &msg) ++{ ++ //Dynamic Leech Protect - persmule ++ DlpAddLogLine(msg); ++} ++ + // File_checked_for_headers +diff -Naur a/src/antiLeech.h b/src/antiLeech.h +--- a/src/antiLeech.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/antiLeech.h 2016-10-14 12:33:51.672348192 +0800 +@@ -0,0 +1,48 @@ ++#ifndef ANTILEECH_H ++#define ANTILEECH_H ++ ++ ++#pragma once ++ ++#include "antiLeech_wx.h" ++#include "CString_wx.h" ++ ++class IantiLeech ++{ ++public: ++ virtual ~IantiLeech(){}; /* Bill Lee: Not be used currently */ ++ //BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD,LPVOID); ++ virtual DWORD GetDLPVersion() = 0; ++ //old versions to keep compatible ++ /* //drop old version support ++ virtual LPCTSTR DLPCheckModstring(LPCTSTR modversion, LPCTSTR clientversion); ++ virtual LPCTSTR DLPCheckUsername(LPCTSTR username); ++ virtual LPCTSTR DLPCheckNameAndHash(CString username, CString& userhash); ++ */ ++ //new versions ++ virtual LPCTSTR DLPCheckModstring_Hard(LPCTSTR modversion, LPCTSTR clientversion) = 0; ++ virtual LPCTSTR DLPCheckModstring_Soft(LPCTSTR modversion, LPCTSTR clientversion) = 0; ++ virtual LPCTSTR DLPCheckUsername_Hard(LPCTSTR username) = 0; ++ virtual LPCTSTR DLPCheckUsername_Soft(LPCTSTR username) = 0; ++ virtual LPCTSTR DLPCheckNameAndHashAndMod(const CString& username, const CString& userhash, const CString& modversion) = 0; ++ virtual LPCTSTR DLPCheckMessageSpam(LPCTSTR messagetext) = 0; ++ ++ ++ virtual LPCTSTR DLPCheckUserhash(const PBYTE userhash) = 0; ++ ++ ++ virtual LPCTSTR DLPCheckHelloTag(UINT tagnumber) = 0; ++ virtual LPCTSTR DLPCheckInfoTag(UINT tagnumber) = 0; ++ ++ //void TestFunc(); ++ ++//Bill Lee: no need in interface abstract class ++//private: ++// static bool IsTypicalHex (const CString& addon); ++}; ++ ++//Bill Lee: never call delete on IantiLeech, use destoryAntiLeechInstat instead. ++extern "C" IantiLeech* createAntiLeechInstant(); ++extern "C" int destoryAntiLeechInstant(IantiLeech*); ++ ++#endif +diff -Naur a/src/antiLeech_wx.h b/src/antiLeech_wx.h +--- a/src/antiLeech_wx.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/src/antiLeech_wx.h 2016-10-14 12:33:51.672348192 +0800 +@@ -0,0 +1,49 @@ ++#ifndef ANTILEECH_WX_H ++#define ANTILEECH_WX_H ++ ++#include ++#include ++ ++#define LPCTSTR const wxChar* ++#define BOOL bool ++//#define _T(var) wxT(var) //defined in wxWidgets ++#define DWORD wxUint32 ++#define UINT wxUint16 ++#define WINAPI ++#define HINSTANCE ++#define LPVOID void* ++#define PBYTE unsigned char* ++#define TCHAR wxChar ++#define _TINT wxInt32 ++ ++#define StrCmpI _tcsicmp ++ ++#define _istdigit(var) iswdigit(var) ++#define _istcntrl(var) iswcntrl(var) ++#define _istpunct(var) iswpunct(var) ++#define _istspace(var) iswspace(var) ++#define _istxdigit(var) iswxdigit(var) ++inline float _tstof(const wchar_t* str){ ++ wchar_t** ptail = NULL; ++ return wcstof(str, ptail); ++} ++//This function is not used. by Orzogc Lee ++//But I think there is no need to removing, linker will remove it. ++/* ++inline void tolowers(wxChar* str){ ++ int i = 0; ++ do{ ++ str[i] = towlower(str[i]); ++ }while(str[++i]); ++} ++*/ ++#define _tcsstr(haystack, needle) wcsstr(haystack, needle) ++#define _tcslen(var) wcslen(var) ++#define StrStr(a, b) wcsstr(a, b) ++ ++LPCTSTR StrStrI(LPCTSTR haystack, LPCTSTR needle); ++//Bill Lee: I think inlining this function make no senses, because it is a very large operation. ++ ++#define _tcsicmp(a, b) wcscasecmp(a, b) ++ ++#endif +diff -Naur a/src/libs/ec/abstracts/ECCodes.abstract b/src/libs/ec/abstracts/ECCodes.abstract +--- a/src/libs/ec/abstracts/ECCodes.abstract 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/libs/ec/abstracts/ECCodes.abstract 2016-10-14 12:33:51.672348192 +0800 +@@ -148,6 +148,8 @@ + + EC_OP_FRIEND 0x57 + ++EC_OP_ANTILEECH_RELOAD 0x80 ++ + [/Section] + + [Section Content] +diff -Naur a/src/libs/ec/cpp/ECCodes.h b/src/libs/ec/cpp/ECCodes.h +--- a/src/libs/ec/cpp/ECCodes.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/libs/ec/cpp/ECCodes.h 2016-10-14 12:33:51.673348215 +0800 +@@ -121,7 +121,8 @@ + EC_OP_CLIENT_SWAP_TO_ANOTHER_FILE = 0x54, + EC_OP_SHARED_FILE_SET_COMMENT = 0x55, + EC_OP_SERVER_SET_STATIC_PRIO = 0x56, +- EC_OP_FRIEND = 0x57 ++ EC_OP_FRIEND = 0x57, ++ EC_OP_ANTILEECH_RELOAD = 0x80 + }; + + enum ECTagNames { +@@ -556,6 +557,7 @@ + case 0x55: return wxT("EC_OP_SHARED_FILE_SET_COMMENT"); + case 0x56: return wxT("EC_OP_SERVER_SET_STATIC_PRIO"); + case 0x57: return wxT("EC_OP_FRIEND"); ++ case 0x80 : return wxT("EC_OP_ANTILEECH_RELOAD"); + default: return CFormat(wxT("unknown %d 0x%x")) % arg % arg; + } + } +diff -Naur a/src/libs/ec/java/ECCodes.java b/src/libs/ec/java/ECCodes.java +--- a/src/libs/ec/java/ECCodes.java 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/libs/ec/java/ECCodes.java 2016-10-14 12:33:51.673348215 +0800 +@@ -112,6 +112,7 @@ + public final static byte EC_OP_SHARED_FILE_SET_COMMENT = 0x55; + public final static byte EC_OP_SERVER_SET_STATIC_PRIO = 0x56; + public final static byte EC_OP_FRIEND = 0x57; ++public final static byte EC_OP_ANTILEECH_RELOAD = 0x80 ; + + public final static short EC_TAG_STRING = 0x0000; + public final static short EC_TAG_PASSWD_HASH = 0x0001; +diff -Naur a/src/muuli_wdr.cpp b/src/muuli_wdr.cpp +--- a/src/muuli_wdr.cpp 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/muuli_wdr.cpp 2016-10-14 12:33:51.676348283 +0800 +@@ -1769,6 +1769,51 @@ + return item0; + } + ++#ifdef AMULE_DLP ++wxSizer *PreferencesDLPTab( wxWindow *parent, bool call_fit, bool set_sizer ) ++{ ++ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); ++ ++ wxButton* btnReload = new wxButton( parent, IDC_RELOADANTILEECH, _("Reload antiLeech"), wxDefaultPosition, wxDefaultSize, 0 ); //Bill Lee ++ ++ wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Dynamic Leecher Protection Options") ); ++ wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL ); ++ ++ wxCheckBox *item4 = new wxCheckBox( parent, IDC_CHECKMODSTRING, _("Check bad modstring"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item5 = new wxCheckBox( parent, IDC_CHECKUSERNAME, _("Check bad username"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item5, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item6 = new wxCheckBox( parent, IDC_CHECKUSERHASH, _("Check bad userhash"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item6, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item7 = new wxCheckBox( parent, IDC_CHECKHELLOTAG, _("Check bad hello tag"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item7, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item8 = new wxCheckBox( parent, IDC_CHECKINFOTAG, _("Check bad info tag"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item8, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item9 = new wxCheckBox( parent, IDC_CHECKGHOSTMOD, _("Check ghost mod"), wxDefaultPosition, wxDefaultSize, 0); ++ item1->Add( item9, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxCheckBox *item10 = new wxCheckBox( parent, IDC_CHECKVERYCDMOD, _("Ban eMule VeryCD mod(Please consider carefully whether to use)"), wxDefaultPosition, wxDefaultSize, 0 ); //Modified by Bill Lee ++ item1->Add( item10, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ item0->Add( btnReload, 0, wxGROW|wxALL, 5); //Bill Lee ++ item0->Add( item1, 0, wxGROW|wxALL, 5 ); ++ ++ if (set_sizer) ++ { ++ parent->SetSizer( item0 ); ++ if (call_fit) ++ item0->SetSizeHints( parent ); ++ } ++ ++ return item0; ++} ++#endif ++ + wxSizer *PreferencesFilesTab( wxWindow *parent, bool call_fit, bool set_sizer ) + { + wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); +@@ -2587,6 +2632,42 @@ + return item0; + } + ++wxSizer *DLPInfoLog( wxWindow *parent, bool call_fit, bool set_sizer ) ++{ ++ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL ); ++ ++ wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL ); ++ ++ wxStaticBitmap *item2 = new wxStaticBitmap( parent, -1, amuleDlgImages( 3 ), wxDefaultPosition, wxDefaultSize ); ++ item2->SetToolTip( _("Display DLP log") ); ++ item1->Add( item2, 0, wxALIGN_CENTER|wxALL, 5 ); ++ ++ wxStaticText *item3 = new wxStaticText( parent, -1, _("DLP Info"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item1->Add( item3, 0, wxALIGN_CENTER|wxALL, 5 ); ++ ++ item0->Add( item1, 0, wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ wxBoxSizer *item4 = new wxBoxSizer( wxHORIZONTAL ); ++ ++ CMuleTextCtrl *item5 = new CMuleTextCtrl( parent, ID_DLPINFO, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxVSCROLL ); ++ item4->Add( item5, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL, 5 ); ++ ++ wxButton *item6 = new wxButton( parent, ID_BTN_RESET_DLP, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 ); ++ item6->SetToolTip( _("Click this button to reset the log.") ); ++ item4->Add( item6, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); ++ ++ item0->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 ); ++ ++ if (set_sizer) ++ { ++ parent->SetSizer( item0 ); ++ if (call_fit) ++ item0->SetSizeHints( parent ); ++ } ++ ++ return item0; ++} ++ + wxSizer *serverListDlgDown( wxWindow *parent, bool call_fit, bool set_sizer ) + { + wxStaticBox *item1 = new wxStaticBox( parent, -1, wxT("") ); +@@ -2602,7 +2683,7 @@ + wxPanel *item4 = new wxPanel( item3, -1 ); + aMuleLog( item4, FALSE ); + item3->AddPage( item4, _("aMule Log") ); +- ++ + wxPanel *item5 = new wxPanel( item3, -1 ); + ServerInfoLog( item5, FALSE ); + item3->AddPage( item5, _("Server Info") ); +@@ -2614,6 +2695,10 @@ + wxPanel *item7 = new wxPanel( item3, -1 ); + Kad_Info( item7, FALSE ); + item3->AddPage( item7, _("Kad Info") ); ++ ++ wxPanel *item8 = new wxPanel( item3, -1); ++ DLPInfoLog( item8, FALSE); ++ item3->AddPage(item8, _("DLP Info")); + + item0->Add( item2, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 ); + +diff -Naur a/src/muuli_wdr.h b/src/muuli_wdr.h +--- a/src/muuli_wdr.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/muuli_wdr.h 2016-10-14 12:33:51.676348283 +0800 +@@ -335,6 +335,10 @@ + #define ID_BTN_RESET_SERVER 10240 + wxSizer *ServerInfoLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); + ++#define ID_DLPINFO 22001 ++#define ID_BTN_RESET_DLP 22002 ++wxSizer *DLPInfoLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); ++ + #define ID_LOGVIEW 10241 + #define ID_BTN_RESET 10242 + wxSizer *aMuleLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); +@@ -424,6 +428,21 @@ + #define ID_DEBUGCATS 10307 + wxSizer *PreferencesDebug( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); + ++/* Dynamic Leecher Protection */ ++#define IDC_CHECKMODSTRING 11001 ++#define IDC_CHECKUSERNAME 11002 ++#define IDC_CHECKUSERHASH 11003 ++#define IDC_CHECKHELLOTAG 11004 ++#define IDC_CHECKINFOTAG 11005 ++#define IDC_CHECKEASYMULE 11006 ++#define IDC_CHECKVERYCDMOD 11007 ++#define IDC_CHECKMINIMULE 11008 ++#define IDC_CHECKGHOSTMOD 11009 ++#ifdef AMULE_DLP ++#define IDC_RELOADANTILEECH 11010 //Bill Lee ++wxSizer *PreferencesDLPTab( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE ); ++#endif ++ + extern wxSizer *IDC_CURJOB; + #define IDC_CONV_PB_LABEL 10308 + #define IDC_CONV_PROZENT 10309 +diff -Naur a/src/updownclient.h b/src/updownclient.h +--- a/src/updownclient.h 2016-10-06 19:01:54.000000000 +0800 ++++ b/src/updownclient.h 2016-10-14 12:37:03.224728226 +0800 +@@ -408,7 +408,13 @@ + bool GetSentCancelTransfer() const { return m_fSentCancelTransfer; } + void SetSentCancelTransfer(bool bVal) { m_fSentCancelTransfer = bVal; } + +- DEBUG_ONLY( wxString GetClientFullInfo(); ) ++#if defined (__DEBUG__) || defined (AMULE_DLP) ++ /* ++ * This function is essential for dlp to produce ban log. ++ * So I decide to retain it when dlp is enabled. ++ */ ++ wxString GetClientFullInfo(); ++#endif + wxString GetClientShortInfo(); + + const wxString& GetClientOSInfo() const { return m_sClientOSInfo; } +@@ -581,7 +587,10 @@ + bool ShouldReceiveCryptUDPPackets() const; + + bool HasDisabledSharedFiles() const { return m_fNoViewSharedFiles; } +- ++ #ifdef AMULE_DLP ++ bool HasNonOfficialOpCodes() const { return dlp_nonofficialopcodes; } //Dynamic Leecher Protection - Bill Lee ++ #endif ++ + private: + + CClientCredits *credits; +@@ -842,6 +851,10 @@ + #ifdef __DEBUG__ + wxString connection_reason; + #endif ++ ++ #ifdef AMULE_DLP ++ bool dlp_nonofficialopcodes; //Dynamic Leecher Protect - Bill Lee ++ #endif + }; + + diff --git a/amule/patches/003_enable_upnp_cross_compile.patch b/amule/patches/003_enable_upnp_cross_compile.patch new file mode 100644 index 000000000..462e490c0 --- /dev/null +++ b/amule/patches/003_enable_upnp_cross_compile.patch @@ -0,0 +1,23 @@ +diff -Naur a/m4/libupnp.m4 b/m4/libupnp.m4 +--- a/m4/libupnp.m4 2016-10-06 19:01:54.000000000 +0800 ++++ b/m4/libupnp.m4 2016-10-11 07:36:39.198318574 +0800 +@@ -52,7 +52,6 @@ + [export PKG_CONFIG_PATH=$withval/lib/pkgconfig]) + + dnl Check for libupnp >= MIN_LIBUPNP_VERSION +- AS_IF([test $cross_compiling = no], [ + AC_MSG_CHECKING([for libupnp version >= MIN_LIBUPNP_VERSION]) + AS_IF([test -n "$PKG_CONFIG"], [ + AS_IF([$PKG_CONFIG libupnp --exists], [ +@@ -79,11 +78,6 @@ + ]) + AC_MSG_RESULT([$result$resultstr]) + libupnp_error="libupnp >= MIN_LIBUPNP_VERSION not found$resultstr" +- ], [ +-dnl Currently cross-compilation with libupnp is not supported. +- result=no +- libupnp_error="cross compiling" +- ]) + + dnl Execute the right action. + AS_IF([test ${result:-no} = yes], [$2], [$3]) diff --git a/amule/patches/004_file_name_conversion.patch b/amule/patches/004_file_name_conversion.patch new file mode 100644 index 000000000..2c511d0ce --- /dev/null +++ b/amule/patches/004_file_name_conversion.patch @@ -0,0 +1,78 @@ +diff --git a/src/amule.h b/src/amule.h +index f25702f..240c02d 100644 +--- a/src/amule.h ++++ b/src/amule.h +@@ -553,6 +553,13 @@ class CamuleDaemonApp : public CamuleApp + int OnExit(); + + virtual int InitGui(bool geometry_enable, wxString &geometry_string); ++ // The GTK wxApps sets its file name conversion properly ++ // in wxApp::Initialize(), while wxAppConsole::Initialize() ++ // does not, leaving wxConvFile being set to wxConvLibc. File ++ // name conversion should be set otherwise amuled will abort to ++ // handle non-ASCII file names which monolithic amule can handle. ++ // This function are overrided to perform this. ++ virtual bool Initialize(int& argc_, wxChar **argv_); + + #ifdef AMULED_APPTRAITS + struct sigaction m_oldSignalChildAction; +diff --git a/src/amuled.cpp b/src/amuled.cpp +index 486da59..86e1ff8 100644 +--- a/src/amuled.cpp ++++ b/src/amuled.cpp +@@ -704,6 +704,41 @@ int CamuleDaemonApp::InitGui(bool ,wxString &) + return 0; + } + ++bool CamuleDaemonApp::Initialize(int& argc_, wxChar **argv_) ++{ ++ if ( !wxAppConsole::Initialize(argc_, argv_) ) { ++ return false; ++ } ++ ++#ifdef __UNIX__ ++ wxString encName; ++#if wxUSE_INTL ++ // if a non default locale is set, ++ // assume that the user wants his ++ // filenames in this locale too ++ encName = wxLocale::GetSystemEncodingName().Upper(); ++ ++ // But don't consider ASCII in this case. ++ if ( !encName.empty() ) { ++ if ( encName == wxT("US-ASCII") ) { ++ // This means US-ASCII when returned ++ // from GetEncodingFromName(). ++ encName.clear(); ++ } ++ } ++#endif // wxUSE_INTL ++ ++ // in this case, UTF-8 is used by default. ++ if ( encName.empty() ) { ++ encName = wxT("UTF-8"); ++ } ++ ++ static wxConvBrokenFileNames fileconv(encName); ++ wxConvFileName = &fileconv; ++#endif // __UNIX__ ++ ++ return true; ++} + + int CamuleDaemonApp::OnExit() + { +diff --git a/src/libs/common/Path.cpp b/src/libs/common/Path.cpp +index 28152a2..5efefd0 100644 +--- a/src/libs/common/Path.cpp ++++ b/src/libs/common/Path.cpp +@@ -229,7 +229,8 @@ CPath::CPath(const wxString& filename) + } + + wxCharBuffer fn = filename2char(filename); +- if (fn.data()) { ++ // add fn.length() for wx 3.x ++ if (fn.data()) { + // Filename is valid in the current locale. This means that + // it either originated from a (wx)system-call, or from a + // user with a properly setup system. diff --git a/amule/patches/005_best_keyword_kad_search.patch b/amule/patches/005_best_keyword_kad_search.patch new file mode 100644 index 000000000..c450a9f8e --- /dev/null +++ b/amule/patches/005_best_keyword_kad_search.patch @@ -0,0 +1,174 @@ +diff --git a/src/SearchList.cpp b/src/SearchList.cpp +index 32b28e9..342a18f 100644 +--- a/src/SearchList.cpp ++++ b/src/SearchList.cpp +@@ -75,7 +75,7 @@ void ParsedSearchExpression(const CSearchExpr* pexpr) + int iOpNot = 0; + + for (unsigned int i = 0; i < pexpr->m_aExpr.GetCount(); i++) { +- wxString str(pexpr->m_aExpr[i]); ++ const wxString& str = pexpr->m_aExpr[i]; + if (str == SEARCHOPTOK_AND) { + iOpAnd++; + } else if (str == SEARCHOPTOK_OR) { +@@ -108,6 +108,25 @@ void ParsedSearchExpression(const CSearchExpr* pexpr) + + // optimize search expression, if no OR nor NOT specified + if (iOpAnd > 0 && iOpOr == 0 && iOpNot == 0) { ++ // figure out if we can use a better keyword than the one the user selected ++ // for example most user will search like this "The oxymoronaccelerator 2", which would ask the node which indexes "the" ++ // This causes higher traffic for such nodes and makes them a viable target to attackers, while the kad result should be ++ // the same or even better if we ask the node which indexes the rare keyword "oxymoronaccelerator", so we try to rearrange ++ // keywords and generally assume that the longer keywords are rarer ++ if (/*thePrefs::GetRearrangeKadSearchKeywords() &&*/ !s_strCurKadKeyword.IsEmpty()) { ++ for (unsigned int i = 0; i < pexpr->m_aExpr.GetCount(); i++) { ++ if (pexpr->m_aExpr[i] != SEARCHOPTOK_AND) { ++ if (pexpr->m_aExpr[i] != s_strCurKadKeyword ++ && pexpr->m_aExpr[i].find_first_of(Kademlia::CSearchManager::GetInvalidKeywordChars()) == wxString::npos ++ && pexpr->m_aExpr[i].Find('"') != 0 // no quoted expressions as keyword ++ && pexpr->m_aExpr[i].length() >= 3 ++ && s_strCurKadKeyword.length() < pexpr->m_aExpr[i].length()) ++ { ++ s_strCurKadKeyword = pexpr->m_aExpr[i]; ++ } ++ } ++ } ++ } + wxString strAndTerms; + for (unsigned int i = 0; i < pexpr->m_aExpr.GetCount(); i++) { + if (pexpr->m_aExpr[i] != SEARCHOPTOK_AND) { +@@ -285,7 +304,7 @@ void CSearchList::RemoveResults(long searchID) + } + + +-wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, const CSearchParams& params) ++wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, CSearchParams& params) + { + // Check that we can actually perform the specified desired search. + if ((type == KadSearch) && !Kademlia::CKademlia::IsRunning()) { +@@ -306,6 +325,16 @@ wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, const CS + m_resultType.Clear(); + } + ++ if (type == KadSearch) { ++ Kademlia::WordList words; ++ Kademlia::CSearchManager::GetWords(params.searchString, &words); ++ if (!words.empty()) { ++ params.strKeyword = words.front(); ++ } else { ++ return _("No keyword for Kad search - aborting"); ++ } ++ } ++ + bool supports64bit = type == KadSearch ? true : theApp->serverconnect->GetCurrentServer() != NULL && (theApp->serverconnect->GetCurrentServer()->GetTCPFlags() & SRV_TCPFLG_LARGEFILES); + bool packetUsing64bit; + +@@ -332,8 +361,7 @@ wxString CSearchList::StartNewSearch(uint32* searchID, SearchType type, const CS + + // searchstring will get tokenized there + // The tab must be created with the Kad search ID, so searchID is updated. +- Kademlia::CSearch* search = Kademlia::CSearchManager::PrepareFindKeywords( +- params.searchString, data->GetLength(), data->GetRawBuffer(), *searchID); ++ Kademlia::CSearch* search = Kademlia::CSearchManager::PrepareFindKeywords(params.strKeyword, data->GetLength(), data->GetRawBuffer(), *searchID); + + *searchID = search->GetSearchID(); + m_currentSearch = *searchID; +@@ -632,7 +660,7 @@ void CSearchList::StopSearch(bool globalOnly) + } + + +-CSearchList::CMemFilePtr CSearchList::CreateSearchData(const CSearchParams& params, SearchType WXUNUSED(type), bool supports64bit, bool& packetUsing64bit) ++CSearchList::CMemFilePtr CSearchList::CreateSearchData(CSearchParams& params, SearchType type, bool supports64bit, bool& packetUsing64bit) + { + // Count the number of used parameters + unsigned int parametercount = 0; +@@ -659,14 +687,16 @@ CSearchList::CMemFilePtr CSearchList::CreateSearchData(const CSearchParams& para + _astrParserErrors.Empty(); + _SearchExpr.m_aExpr.Empty(); + ++ s_strCurKadKeyword.Clear(); ++ if (type == KadSearch) { ++ wxASSERT( !params.strKeyword.IsEmpty() ); ++ s_strCurKadKeyword = params.strKeyword; ++ } ++ + LexInit(params.searchString); + int iParseResult = yyparse(); + LexFree(); + +-#ifdef __DEBUG__ +- AddLogLineNS(CFormat(wxT("Search parsing result for \"%s\": %i")) +- % params.searchString % iParseResult); +-#endif + if (_astrParserErrors.GetCount() > 0) { + for (unsigned int i=0; i < _astrParserErrors.GetCount(); ++i) { + AddLogLineNS(CFormat(wxT("Error %u: %s\n")) % i % _astrParserErrors[i]); +@@ -681,21 +711,13 @@ CSearchList::CMemFilePtr CSearchList::CreateSearchData(const CSearchParams& para + return CMemFilePtr(NULL); + } + +- #ifdef __DEBUG__ +- wxString mes(wxT("Search expression:")); +- for (unsigned int i = 0; i < _SearchExpr.m_aExpr.GetCount(); i++) { +- mes << wxT(" ") << _SearchExpr.m_aExpr[i]; ++ if (type == KadSearch && s_strCurKadKeyword != params.strKeyword) { ++ AddDebugLogLineN(logSearch, CFormat(wxT("Keyword was rearranged, using '%s' instead of '%s'")) % s_strCurKadKeyword % params.strKeyword); ++ params.strKeyword = s_strCurKadKeyword; + } +- AddLogLineNS(mes); +- AddLogLineNS(CFormat(wxT("Expression count: %i")) % _SearchExpr.m_aExpr.GetCount()); +- #endif + + parametercount += _SearchExpr.m_aExpr.GetCount(); + +- #ifdef __DEBUG__ +- AddLogLineNS(CFormat(wxT("Parameters: %i")) % parametercount); +- #endif +- + /* Leave the unicode comment there, please... */ + CSearchExprTarget target(data.get(), true /*I assume everyone is unicoded */ ? utf8strRaw : utf8strNone, supports64bit, packetUsing64bit); + +diff --git a/src/SearchList.h b/src/SearchList.h +index 35b0fc6..6db7508 100644 +--- a/src/SearchList.h ++++ b/src/SearchList.h +@@ -64,6 +64,8 @@ class CSearchList : public wxEvtHandler + + //! The actual string to search for. + wxString searchString; ++ //! The keyword selected for Kad search ++ wxString strKeyword; + //! The type of files to search for (may be empty), one of ED2KFTSTR_* + wxString typeText; + //! The filename extension. May be empty. +@@ -90,7 +92,7 @@ class CSearchList : public wxEvtHandler + * @param params The search parameters, see CSearchParams. + * @return An empty string on success, otherwise an error-message. + */ +- wxString StartNewSearch(uint32* searchID, SearchType type, const CSearchParams& params); ++ wxString StartNewSearch(uint32* searchID, SearchType type, CSearchParams& params); + + /** Stops the current search (global or Kad), if any is in progress. */ + void StopSearch(bool globalOnly = false); +@@ -189,7 +191,7 @@ class CSearchList : public wxEvtHandler + typedef std::auto_ptr CMemFilePtr; + + /** Create a basic search-packet for the given search-type. */ +- CMemFilePtr CreateSearchData(const CSearchParams& params, SearchType type, bool supports64bit, bool& packetUsing64bit); ++ CMemFilePtr CreateSearchData(CSearchParams& params, SearchType type, bool supports64bit, bool& packetUsing64bit); + + + //! Timer used for global search intervals. +diff --git a/src/kademlia/kademlia/SearchManager.cpp b/src/kademlia/kademlia/SearchManager.cpp +index e7f25d4..f9ee924 100644 +--- a/src/kademlia/kademlia/SearchManager.cpp ++++ b/src/kademlia/kademlia/SearchManager.cpp +@@ -127,7 +127,7 @@ CSearch* CSearchManager::PrepareFindKeywords(const wxString& keyword, uint32_t s + + wxString wstrKeyword = s->m_words.front(); + +- AddLogLineNS(CFormat(_("Keyword for search: %s")) % wstrKeyword); ++ AddDebugLogLineN(logSearch, CFormat(wxT("Keyword for search: %s")) % wstrKeyword); + + // Kry - I just decided to assume everyone is unicoded + // GonoszTopi - seconded diff --git a/amule/patches/006_update-libupnp.patch b/amule/patches/006_update-libupnp.patch new file mode 100644 index 000000000..a66c33bad --- /dev/null +++ b/amule/patches/006_update-libupnp.patch @@ -0,0 +1,365 @@ +diff -Naur a/m4/libupnp.m4 b/m4/libupnp.m4 +--- a/m4/libupnp.m4 2016-10-06 18:49:44.000000000 +0800 ++++ b/m4/libupnp.m4 2019-12-11 22:13:19.008225399 +0800 +@@ -45,11 +45,16 @@ + + dnl Test for --with-libupnp-prefix + AC_ARG_WITH( +- [libupnp-prefix], +- [AS_HELP_STRING( ++ [libupnp-prefix],[ ++ AS_HELP_STRING( + [--with-libupnp-prefix=PREFIX], +- [UPnP library location])], +- [export PKG_CONFIG_PATH=$withval/lib/pkgconfig]) ++ [UPnP library location])],[ ++ AS_IF([test -d "$withval/lib64/pkgconfig"],[ ++ export PKG_CONFIG_PATH=$withval/lib64/pkgconfig ++ ],[ ++ export PKG_CONFIG_PATH=$withval/lib/pkgconfig ++ ]) ++ ]) + + dnl Check for libupnp >= MIN_LIBUPNP_VERSION + AS_IF([test $cross_compiling = no], [ +diff -Naur a/src/UPnPBase.cpp b/src/UPnPBase.cpp +--- a/src/UPnPBase.cpp 2016-10-06 18:49:44.000000000 +0800 ++++ b/src/UPnPBase.cpp 2019-12-11 22:15:04.536768532 +0800 +@@ -1127,7 +1127,11 @@ + + + // This function is static ++#if UPNP_VERSION >= 10800 ++int CUPnPControlPoint::Callback(Upnp_EventType_e EventType, const void *Event, void * /*Cookie*/) ++#else + int CUPnPControlPoint::Callback(Upnp_EventType EventType, void *Event, void * /*Cookie*/) ++#endif + { + std::ostringstream msg; + std::ostringstream msg2; +@@ -1149,24 +1153,47 @@ + msg2<< "UPNP_DISCOVERY_SEARCH_RESULT: "; + // UPnP Discovery + upnpDiscovery: ++#if UPNP_VERSION >= 10800 ++ UpnpDiscovery *d_event = (UpnpDiscovery *)Event; ++#else + struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)Event; ++#endif + IXML_Document *doc = NULL; ++#if UPNP_VERSION >= 10800 ++ int errCode = UpnpDiscovery_get_ErrCode(d_event); ++ if (errCode != UPNP_E_SUCCESS) { ++ msg << UpnpGetErrorMessage(errCode) << "."; ++#else + int ret; + if (d_event->ErrCode != UPNP_E_SUCCESS) { + msg << UpnpGetErrorMessage(d_event->ErrCode) << "."; ++#endif + AddDebugLogLineC(logUPnP, msg); + } + // Get the XML tree device description in doc ++#if UPNP_VERSION >= 10800 ++ const char *location = UpnpDiscovery_get_Location_cstr(d_event); ++ int ret = UpnpDownloadXmlDoc(location, &doc); ++#else + ret = UpnpDownloadXmlDoc(d_event->Location, &doc); ++#endif + if (ret != UPNP_E_SUCCESS) { + msg << "Error retrieving device description from " << ++#if UPNP_VERSION >= 10800 ++ location << ": " << ++#else + d_event->Location << ": " << ++#endif + UpnpGetErrorMessage(ret) << + "(" << ret << ")."; + AddDebugLogLineC(logUPnP, msg); + } else { + msg2 << "Retrieving device description from " << ++#if UPNP_VERSION >= 10800 ++ location << "."; ++#else + d_event->Location << "."; ++#endif + AddDebugLogLineN(logUPnP, msg2); + } + if (doc) { +@@ -1194,8 +1221,14 @@ + AddDebugLogLineC(logUPnP, msg); + } + // Add the root device to our list ++#if UPNP_VERSION >= 10800 ++ int expires = UpnpDiscovery_get_Expires(d_event); ++ upnpCP->AddRootDevice(rootDevice, urlBase, ++ location, expires); ++#else + upnpCP->AddRootDevice(rootDevice, urlBase, + d_event->Location, d_event->Expires); ++#endif + } + // Free the XML doc tree + IXML::Document::Free(doc); +@@ -1216,28 +1249,62 @@ + case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { + //fprintf(stderr, "Callback: UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE\n"); + // UPnP Device Removed ++#if UPNP_VERSION >= 10800 ++ UpnpDiscovery *dab_event = (UpnpDiscovery *)Event; ++ int errCode = UpnpDiscovery_get_ErrCode(dab_event); ++ if (errCode != UPNP_E_SUCCESS) { ++#else + struct Upnp_Discovery *dab_event = (struct Upnp_Discovery *)Event; + if (dab_event->ErrCode != UPNP_E_SUCCESS) { ++#endif + msg << "error(UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE): " << ++#if UPNP_VERSION >= 10800 ++ UpnpGetErrorMessage(errCode) << ++#else + UpnpGetErrorMessage(dab_event->ErrCode) << ++#endif + "."; + AddDebugLogLineC(logUPnP, msg); + } ++#if UPNP_VERSION >= 10800 ++ std::string devType = UpnpDiscovery_get_DeviceType_cstr(dab_event); ++#else + std::string devType = dab_event->DeviceType; ++#endif + // Check for an InternetGatewayDevice and removes it from the list ++ + std::transform(devType.begin(), devType.end(), devType.begin(), tolower); ++ + if (stdStringIsEqualCI(devType, UPnP::Device::IGW)) { ++#if UPNP_VERSION >= 10800 ++ const char *deviceID = ++ UpnpDiscovery_get_DeviceID_cstr(dab_event); ++ upnpCP->RemoveRootDevice(deviceID); ++#else + upnpCP->RemoveRootDevice(dab_event->DeviceId); ++#endif + } + break; + } + case UPNP_EVENT_RECEIVED: { + //fprintf(stderr, "Callback: UPNP_EVENT_RECEIVED\n"); + // Event reveived ++#if UPNP_VERSION >= 10800 ++ UpnpEvent *e_event = (UpnpEvent *)Event; ++ int eventKey = UpnpEvent_get_EventKey(e_event); ++ IXML_Document *changedVariables = ++ UpnpEvent_get_ChangedVariables(e_event); ++ const std::string sid = UpnpEvent_get_SID_cstr(e_event); ++#else + struct Upnp_Event *e_event = (struct Upnp_Event *)Event; + const std::string Sid = e_event->Sid; ++#endif + // Parses the event ++#if UPNP_VERSION >= 10800 ++ upnpCP->OnEventReceived(sid, eventKey, changedVariables); ++#else + upnpCP->OnEventReceived(Sid, e_event->EventKey, e_event->ChangedVariables); ++#endif + break; + } + case UPNP_EVENT_SUBSCRIBE_COMPLETE: +@@ -1252,24 +1319,42 @@ + //fprintf(stderr, "Callback: UPNP_EVENT_RENEWAL_COMPLETE\n"); + msg << "error(UPNP_EVENT_RENEWAL_COMPLETE): "; + upnpEventRenewalComplete: ++#if UPNP_VERSION >= 10800 ++ UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; ++ int errCode = UpnpEventSubscribe_get_ErrCode(es_event); ++ if (errCode != UPNP_E_SUCCESS) { ++#else + struct Upnp_Event_Subscribe *es_event = + (struct Upnp_Event_Subscribe *)Event; + if (es_event->ErrCode != UPNP_E_SUCCESS) { ++#endif + msg << "Error in Event Subscribe Callback"; ++#if UPNP_VERSION >= 10800 ++ UPnP::ProcessErrorMessage(msg.str(), errCode, NULL, NULL); ++#else + UPnP::ProcessErrorMessage( + msg.str(), es_event->ErrCode, NULL, NULL); ++#endif + } else { + #if 0 ++#if UPNP_VERSION >= 10800 ++ ++ const UpnpString *publisherUrl = ++ UpnpEventSubscribe_get_PublisherUrl(es_event); ++ const char *sid = UpnpEvent_get_SID_cstr(es_event); ++ int timeOut = UpnpEvent_get_TimeOut(es_event); ++ TvCtrlPointHandleSubscribeUpdate( ++ publisherUrl, sid, timeOut); ++#else + TvCtrlPointHandleSubscribeUpdate( + GET_UPNP_STRING(es_event->PublisherUrl), + es_event->Sid, + es_event->TimeOut ); + #endif ++#endif + } +- + break; + } +- + case UPNP_EVENT_AUTORENEWAL_FAILED: + //fprintf(stderr, "Callback: UPNP_EVENT_AUTORENEWAL_FAILED\n"); + msg << "error(UPNP_EVENT_AUTORENEWAL_FAILED): "; +@@ -1280,29 +1365,56 @@ + msg << "error(UPNP_EVENT_SUBSCRIPTION_EXPIRED): "; + msg2 << "UPNP_EVENT_SUBSCRIPTION_EXPIRED: "; + upnpEventSubscriptionExpired: ++#if UPNP_VERSION >= 10800 ++ UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; ++#else + struct Upnp_Event_Subscribe *es_event = + (struct Upnp_Event_Subscribe *)Event; ++#endif + Upnp_SID newSID; + memset(newSID, 0, sizeof(Upnp_SID)); + int TimeOut = 1801; ++#if UPNP_VERSION >= 10800 ++ const char *publisherUrl = ++ UpnpEventSubscribe_get_PublisherUrl_cstr(es_event); ++#endif + int ret = UpnpSubscribe( + upnpCP->m_UPnPClientHandle, ++#if UPNP_VERSION >= 10800 ++ publisherUrl, ++#else + GET_UPNP_STRING(es_event->PublisherUrl), ++#endif + &TimeOut, + newSID); + if (ret != UPNP_E_SUCCESS) { + msg << "Error Subscribing to EventURL"; ++#if UPNP_VERSION >= 10800 ++ int errCode = UpnpEventSubscribe_get_ErrCode(es_event); ++#endif + UPnP::ProcessErrorMessage( ++#if UPNP_VERSION >= 10800 ++ msg.str(), errCode, NULL, NULL); ++#else + msg.str(), es_event->ErrCode, NULL, NULL); ++#endif + } else { + ServiceMap::iterator it = ++#if UPNP_VERSION >= 10800 ++ upnpCP->m_ServiceMap.find(publisherUrl); ++#else + upnpCP->m_ServiceMap.find(GET_UPNP_STRING(es_event->PublisherUrl)); ++#endif + if (it != upnpCP->m_ServiceMap.end()) { + CUPnPService &service = *(it->second); + service.SetTimeout(TimeOut); + service.SetSID(newSID); + msg2 << "Re-subscribed to EventURL '" << ++#if UPNP_VERSION >= 10800 ++ publisherUrl << ++#else + GET_UPNP_STRING(es_event->PublisherUrl) << ++#endif + "' with SID == '" << + newSID << "'."; + AddDebugLogLineC(logUPnP, msg2); +@@ -1321,17 +1433,34 @@ + case UPNP_CONTROL_ACTION_COMPLETE: { + //fprintf(stderr, "Callback: UPNP_CONTROL_ACTION_COMPLETE\n"); + // This is here if we choose to do this asynchronously ++#if UPNP_VERSION >= 10800 ++ UpnpActionComplete *a_event = (UpnpActionComplete *)Event; ++ int errCode = UpnpActionComplete_get_ErrCode(a_event); ++ IXML_Document *actionResult = ++ UpnpActionComplete_get_ActionResult(a_event); ++ if (errCode != UPNP_E_SUCCESS) { ++#else + struct Upnp_Action_Complete *a_event = + (struct Upnp_Action_Complete *)Event; + if (a_event->ErrCode != UPNP_E_SUCCESS) { ++#endif + UPnP::ProcessErrorMessage( + "UpnpSendActionAsync", ++#if UPNP_VERSION >= 10800 ++ errCode, NULL, ++ actionResult); ++#else + a_event->ErrCode, NULL, + a_event->ActionResult); ++#endif + } else { + // Check the response document + UPnP::ProcessActionResponse( ++#if UPNP_VERSION >= 10800 ++ actionResult, ++#else + a_event->ActionResult, ++#endif + ""); + } + /* No need for any processing here, just print out results. +@@ -1342,22 +1471,43 @@ + case UPNP_CONTROL_GET_VAR_COMPLETE: { + //fprintf(stderr, "Callback: UPNP_CONTROL_GET_VAR_COMPLETE\n"); + msg << "error(UPNP_CONTROL_GET_VAR_COMPLETE): "; ++#if UPNP_VERSION >= 10800 ++ UpnpStateVarComplete *sv_event = (UpnpStateVarComplete *)Event; ++ int errCode = UpnpStateVarComplete_get_ErrCode(sv_event); ++ if (errCode != UPNP_E_SUCCESS) { ++#else + struct Upnp_State_Var_Complete *sv_event = + (struct Upnp_State_Var_Complete *)Event; + if (sv_event->ErrCode != UPNP_E_SUCCESS) { ++#endif + msg << "m_UpnpGetServiceVarStatusAsync"; + UPnP::ProcessErrorMessage( ++#if UPNP_VERSION >= 10800 ++ msg.str(), errCode, NULL, NULL); ++#else + msg.str(), sv_event->ErrCode, NULL, NULL); ++#endif + } else { + #if 0 + // Warning: The use of UpnpGetServiceVarStatus and + // UpnpGetServiceVarStatusAsync is deprecated by the + // UPnP forum. ++#if UPNP_VERSION >= 10800 ++ const char *ctrlUrl = ++ UpnpStateVarComplete_get_CtrlUrl(sv_event); ++ const char *stateVarName = ++ UpnpStateVarComplete_get_StateVarName(sv_event); ++ const DOMString currentVal = ++ UpnpStateVarComplete_get_CurrentVal(sv_event); ++ TvCtrlPointHandleGetVar( ++ ctrlUrl, stateVarName, currentVal); ++#else + TvCtrlPointHandleGetVar( + sv_event->CtrlUrl, + sv_event->StateVarName, + sv_event->CurrentVal ); + #endif ++#endif + } + break; + } +diff -Naur a/src/UPnPBase.h b/src/UPnPBase.h +--- a/src/UPnPBase.h 2016-10-06 18:49:44.000000000 +0800 ++++ b/src/UPnPBase.h 2019-12-11 22:16:28.165063153 +0800 +@@ -489,9 +489,15 @@ + + // Callback function + static int Callback( ++ #if UPNP_VERSION >= 10800 ++ Upnp_EventType_e EventType, ++ const void *Event, ++ void *Cookie); ++ #else + Upnp_EventType EventType, + void* Event, + void* Cookie); ++ #endif + + private: + void OnEventReceived( diff --git a/amule/patches/007-binutils.patch b/amule/patches/007-binutils.patch new file mode 100644 index 000000000..600a47620 --- /dev/null +++ b/amule/patches/007-binutils.patch @@ -0,0 +1,19 @@ +--- a/src/libs/common/MuleDebug.cpp 2016-10-06 18:49:44.000000000 +0800 ++++ b/src/libs/common/MuleDebug.cpp 2021-06-17 02:16:40.000000000 +0800 +@@ -268,14 +268,14 @@ + return; + } + +- bfd_vma vma = bfd_get_section_vma(abfd, section); ++ bfd_vma vma = bfd_section_vma(section); + + unsigned long address = (unsigned long)_address; + if (address < vma) { + return; + } + +- bfd_size_type size = bfd_section_size(abfd, section); ++ bfd_size_type size = bfd_section_size(section); + if (address > (vma + size)) { + return; + } diff --git a/amule/patches/008-upnp2.patch b/amule/patches/008-upnp2.patch new file mode 100644 index 000000000..20592509c --- /dev/null +++ b/amule/patches/008-upnp2.patch @@ -0,0 +1,16 @@ +diff --git a/src/UPnPBase.cpp b/src/UPnPBase.cpp +index 46ac7451e..dd244e5b0 100644 +--- a/src/UPnPBase.cpp ++++ b/src/UPnPBase.cpp +@@ -828,9 +828,9 @@ + int ret; + char *ipAddress = NULL; + unsigned short port = 0; +- ret = UpnpInit(ipAddress, udpPort); ++ ret = UpnpInit2(0, udpPort); + if (ret != UPNP_E_SUCCESS) { +- msg << "error(UpnpInit): Error code "; ++ msg << "error(UpnpInit2): Error code "; + goto error; + } + port = UpnpGetServerPort(); diff --git a/baidupcs-web/Makefile b/baidupcs-web/Makefile new file mode 100644 index 000000000..4dfdf9ff7 --- /dev/null +++ b/baidupcs-web/Makefile @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=baidupcs-web +PKG_VERSION:=3.7.4-nnew +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/Erope/BaiduPCS-Go/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=6efd1c5e4cf5cf876204bed246c70ea0212ad078d4eb7703d7f1179b39551d1d +PKG_BUILD_DIR:=$(BUILD_DIR)/BaiduPCS-Go-$(PKG_VERSION) + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=golang/host go-rice/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/Erope/BaiduPCS-Go +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/baidupcs-web + SECTION:=net + CATEGORY:=Network + SUBMENU:=Download Manager + TITLE:=A web controller for BaiduPCS-Go + URL:=https://github.com/Erope/BaiduPCS-Go + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Build/Compile + ( \ + pushd "$(PKG_BUILD_DIR)/internal/pcsweb" ; \ + rice embed-go ; \ + popd ; \ + $(call GoPackage/Build/Compile) ; \ + ) +endef + +define Package/baidupcs-web/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/BaiduPCS-Go $(1)/usr/bin/baidupcs-web +endef + +$(eval $(call GoBinPackage,baidupcs-web)) +$(eval $(call BuildPackage,baidupcs-web)) diff --git a/dnsforwarder/Makefile b/dnsforwarder/Makefile new file mode 100644 index 000000000..05e7370a0 --- /dev/null +++ b/dnsforwarder/Makefile @@ -0,0 +1,61 @@ +# +# 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:=dnsforwarder +PKG_VERSION:=6.1.15 +PKG_RELEASE:=11 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/1715173329/dnsforwarder.git +PKG_SOURCE_DATE:=2018-06-26 +PKG_SOURCE_VERSION:=587e61ae4d75dc976f538088b715a3c8ee26c144 +PKG_MIRROR_HASH:=7c141040ae384d254d90b3c3ee502d87330c9fdcd201ff29a669336a27b176d4 + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Dennis + +PKG_FIXUP:=autoreconf +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/dnsforwarder + SECTION:=net + CATEGORY:=Network + TITLE:=A simple DNS forwarder + URL:=https://github.com/holmium/dnsforwarder + DEPENDS:=+coreutils +coreutils-base64 +dnsmasq-full +libpthread +wget-ssl +endef + +define Package/dnsforwarder/description + Forwarding queries to customized domains (and their subdomains) to specified servers + over a specified protocol (UDP or TCP). non-standard ports are supported. +endef + +CONFIGURE_ARGS+= --enable-downloader=wget + +define Package/dnsforwarder/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/dnsforwarder $(1)/usr/bin/dnsforwarder + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) files/etc/config/dnsforwarder $(1)/etc/config/dnsforwarder + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) files/etc/init.d/dnsforwarder $(1)/etc/init.d/dnsforwarder + + $(INSTALL_DIR) $(1)/etc/dnsforwarder + $(INSTALL_CONF) files/etc/dnsforwarder/gfw.txt $(1)/etc/dnsforwarder/gfw.txt + $(INSTALL_DIR) $(1)/usr/share/dnsforwarder + $(INSTALL_BIN) files/usr/share/dnsforwarder/gfwlist.sh $(1)/usr/share/dnsforwarder/gfwlist.sh +endef + +$(eval $(call BuildPackage,dnsforwarder)) diff --git a/dnsforwarder/files/etc/config/dnsforwarder b/dnsforwarder/files/etc/config/dnsforwarder new file mode 100644 index 000000000..da025f7a8 --- /dev/null +++ b/dnsforwarder/files/etc/config/dnsforwarder @@ -0,0 +1,79 @@ + +config arguments + option enabled '0' + option addr '127.0.0.1:5053' + +config config + option cache 'true' + option cache_size '102400' + option cache_ignore 'false' + option gfw 'true' + list block_ip '74.125.127.102' + list block_ip '74.125.155.102' + list block_ip '74.125.39.102' + list block_ip '74.125.39.113' + list block_ip '209.85.229.138' + list block_ip '128.121.126.139' + list block_ip '159.106.121.75' + list block_ip '169.132.13.103' + list block_ip '192.67.198.6' + list block_ip '202.106.1.2' + list block_ip '202.181.7.85' + list block_ip '203.161.230.171' + list block_ip '203.98.7.65' + list block_ip '207.12.88.98' + list block_ip '208.56.31.43' + list block_ip '209.145.54.50' + list block_ip '209.220.30.174' + list block_ip '209.36.73.33' + list block_ip '211.94.66.147' + list block_ip '213.169.251.35' + list block_ip '216.221.188.182' + list block_ip '216.234.179.13' + list block_ip '243.185.187.39' + list block_ip '37.61.54.158' + list block_ip '4.36.66.178' + list block_ip '46.82.174.68' + list block_ip '59.24.3.173' + list block_ip '64.33.88.161' + list block_ip '64.33.99.47' + list block_ip '64.66.163.251' + list block_ip '65.104.202.252' + list block_ip '65.160.219.113' + list block_ip '66.45.252.237' + list block_ip '69.55.52.253' + list block_ip '72.14.205.104' + list block_ip '72.14.205.99' + list block_ip '78.16.49.15' + list block_ip '8.7.198.45' + list block_ip '93.46.8.89' + list block_ip '37.61.54.158' + list block_ip '243.185.187.39' + list block_ip '190.93.247.4' + list block_ip '190.93.246.4' + list block_ip '190.93.245.4' + list block_ip '190.93.244.4' + list block_ip '65.49.2.178' + list block_ip '189.163.17.5' + list block_ip '23.89.5.60' + list block_ip '49.2.123.56' + list block_ip '54.76.135.1' + list block_ip '77.4.7.92' + list block_ip '118.5.49.6' + list block_ip '159.24.3.173' + list block_ip '188.5.4.96' + list block_ip '197.4.4.12' + list block_ip '220.250.64.24' + list block_ip '243.185.187.30' + list block_ip '249.129.46.48' + list block_ip '253.157.14.165' + option block_ipv6 'false' + list cache_control 'tossp.com $orig' + list cache_control '* fixed 3600' + option log 'false' + list udp_group '9.9.9.9,119.29.29.29,223.5.5.5,114.114.114.114 * on' + option block_negative_resp 'true' + list udp_local '0.0.0.0:5053' + list udp_local '[::0]:5053' + option domain_statistic 'false' + diff --git a/dnsforwarder/files/etc/dnsforwarder/gfw.txt b/dnsforwarder/files/etc/dnsforwarder/gfw.txt new file mode 100644 index 000000000..0bd285173 --- /dev/null +++ b/dnsforwarder/files/etc/dnsforwarder/gfw.txt @@ -0,0 +1,5605 @@ +# GenerationAt 2018-12-09 23:29:36 +protocol tcp +server 8.8.8.8,8.8.4.4,1.1.1.1,1.0.0.1,208.67.222.222,208.67.220.220,209.244.0.3,209.244.0.4,8.26.56.26,8.20.247.20,156.154.70.1,156.154.71.1,199.85.126.10 +proxy no + + +030buy.com +0rz.tw +1-apple.com.tw +10.tt +1000giri.net +100ke.org +10conditionsoflove.com +10musume.com +123rf.com +12bet.com +12vpn.com +12vpn.net +138.com +141hongkong.com +141jj.com +141tube.com +1688.com.au +173ng.com +177pic.info +17t17p.com +18board.com +18board.info +18onlygirls.com +18p2p.com +18virginsex.com +1949er.org +1984bbs.com +1984bbs.org +1989report.hkja.org.hk +1991way.com +1998cdp.org +1bao.org +1dumb.com +1e100.net +1eew.com +1mobile.com +1mobile.tw +1pondo.tv +2-hand.info +2000fun.com +2008xianzhang.info +2017.hk +21andy.com +21pron.com +21sextury.com +228.net.tw +233abc.com +24hrs.ca +24smile.org +25u.com +2lipstube.com +2shared.com +2waky.com +3-a.net +30boxes.com +315lz.com +32red.com +36rain.com +3a5a.com +3arabtv.com +3boys2girls.com +3d-game.com +3proxy.ru +3ren.ca +3tui.net +466453.com +4bluestones.biz +4chan.com +4dq.com +4everproxy.com +4irc.com +4mydomain.com +4pu.com +4rbtv.com +4shared.com +4sqi.net +51.ca +51jav.org +51luoben.com +5278.cc +56cun04.jigsy.com +5aimiku.com +5i01.com +5isotoi5.org +5maodang.com +63i.com +64museum.org +64tianwang.com +64wiki.com +66.ca +666kb.com +6park.com +6parker.com +7capture.com +7cow.com +8-d.com +85cc.net +85cc.us +85st.com +881903.com +888.com +888poker.com +89-64.org +89.64.charter.constitutionalism.solutions +8news.com.tw +8z1.net +9001700.com +908taiwan.org +91porn.com +91vps.club +92ccav.com +991.com +99btgc01.com +99cn.info +9bis.com +9bis.net +a-normal-day.com +a248.e.akamai.net +a5.com.ru +aamacau.com +abc.com +abc.net.au +abc.pp.ru +abc.xyz +abchinese.com +abclite.net +abematv.akamaized.net +abitno.linpie.com +ablwang.com +aboluowang.com +aboutgfw.com +abs.edu +ac.jiruan.net +accim.org +aceros-de-hispania.com +acevpn.com +acg18.me +acgkj.com +acmedia365.com +acmetoy.com +acnw.com.au +actfortibet.org +actimes.com.au +activpn.com +aculo.us +adcex.com +addictedtocoffee.de +adelaidebbs.com +admin.recaptcha.net +admob.com +adpl.org.hk +ads-twitter.com +adsense.com +adult-sex-games.com +adult.friendfinder.com +adultfriendfinder.com +adultkeep.net +advanscene.com +advertfan.com +ae.hao123.com +ae.org +aenhancers.com +af.mil +afantibbs.com +agnesb.fr +agoogleaday.com +agro.hk +ai-kan.net +ai-wen.net +ai.binwang.me +ai.google +aiph.net +airasia.com +airconsole.com +airvpn.org +aisex.com +aiss.anws.gov.tw +ait.org.tw +aiweiwei.com +aiweiweiblog.com +akademiye.org +akamaihd.net +akiba-online.com +akiba-web.com +akow.org +al-islam.com +al-qimmah.net +alabout.com +alanhou.com +alarab.qa +alasbarricadas.org +alexlur.org +alforattv.net +alhayat.com +alicejapan.co.jp +aliengu.com +alkasir.com +allcoin.com +allconnected.co +alldrawnsex.com +allervpn.com +allfinegirls.com +allgirlmassage.com +allgirlsallowed.org +allgravure.com +alliance.org.hk +allinfa.com +alljackpotscasino.com +allmovie.com +allowed.org +almasdarnews.com +almostmy.com +alphaporno.com +alternate-tools.com +alternativeto.net +altrec.com +alvinalexander.com +alwaysdata.com +alwaysdata.net +alwaysvpn.com +am730.com.hk +amazon.co.jp +amazon.com +ameblo.jp +americangreencard.com +americanunfinished.com +amiblockedornot.com +amigobbs.net +amitabhafoundation.us +amnesty.org +amnesty.org.hk +amnesty.tw +amnestyusa.org +amnyemachen.org +amoiist.com +ampproject.org +amtb-taipei.org +anchorfree.com +ancsconf.org +andfaraway.net +android-x86.org +android.com +androidify.com +androidplus.co +andygod.com +angelfire.com +angularjs.org +animecrazy.net +animeshippuuden.com +aniscartujo.com +annatam.com +anobii.com +anontext.com +anonymise.us +anonymitynetwork.com +anonymizer.com +anpopo.com +answering-islam.org +anthonycalzadilla.com +anti1984.com +antichristendom.com +antiwave.net +anyporn.com +anysex.com +aobo.com.au +aofriend.com +aofriend.com.au +aojiao.org +aolchannels.aol.com +aomiwang.com +apartmentratings.com +apartments.com +apetube.com +api-secure.recaptcha.net +api-verify.recaptcha.net +api.ai +api.dropboxapi.com +api.linksalpha.com +api.proxlet.com +api.pureapk.com +api.recaptcha.net +apiary.io +apidocs.linksalpha.com +apigee.com +apk-dl.com +apkdler.com +apkmirror.com +apkmonk.com +apkplz.com +apkpure.com +aplusvpn.com +app.box.com +app.heywire.com +app.smartmailcloud.com +app.tutanota.com +appdownloader.net +appledaily.com +appledaily.com.hk +appledaily.com.tw +appshopper.com +appsocks.net +appspot.com +appsto.re +aptoide.com +ar.hao123.com +archive.fo +archive.is +archive.li +archive.org +archive.today +archives.gov +archives.gov.tw +arctosia.com +areca-backup.org +arena.taipei +arethusa.su +arlingtoncemetery.mil +army.mil +art4tibet1998.org +artofpeacefoundation.org +artsy.net +asacp.org +asahichinese.com +asdfg.jp +asg.to +asia-gaming.com +asiaharvest.org +asianews.it +asiansexdiary.com +asianspiss.com +asianwomensfilm.de +asiatgp.com +asiatoday.us +askstudent.com +askynz.net +assembla.com +assimp.org +astrill.com +atc.org.au +atchinese.com +atdmt.com +atgfw.org +athenaeizou.com +atlanta168.com +atlaspost.com +atnext.com +authorizeddns.net +authorizeddns.org +authorizeddns.us +autodraw.com +av-e-body.com +av.com +av.movie +av.nightlife141.com +avaaz.org +avbody.tv +avcity.tv +avcool.com +avdb.in +avdb.tv +avfantasy.com +avgle.com +avidemux.org +avmo.pw +avmoo.com +avmoo.net +avmoo.pw +avoision.com +avyahoo.com +axureformac.com +azerbaycan.tv +azerimix.com +azubu.tv +azurewebsites.net +b0ne.com +babynet.com.hk +backchina.com +backpackers.com.tw +backtotiananmen.com +badiucao.com +badjojo.com +badoo.com +bahamut.com.tw +baidu.jp +baijie.org +bailandaily.com +baixing.me +bakgeekhome.tk +banana-vpn.com +bandwagonhost.com +bangbrosnetwork.com +bangchen.net +bangyoulater.com +bankmobilevibe.com +bannedbook.org +bannednews.org +banorte.com +baramangaonline.com +barenakedislam.com +barnabu.co.uk +bartvpn.com +bash-hackers.org +bastillepost.com +bayvoice.net +bb-chat.tv +bb.ttv.com.tw +bbc.co.uk +bbc.com +bbc.in +bbcchinese.com +bbchat.tv +bbci.co.uk +bbg.gov +bbkz.com +bbnradio.org +bbs-tw.com +bbs.brockbbs.com +bbs.cantonese.asia +bbs.ecstart.com +bbs.hanminzu.org +bbs.hasi.wang +bbs.huasing.org +bbs.junglobal.net +bbs.kimy.com.tw +bbs.morbell.com +bbs.mychat.to +bbs.netbig.com +bbs.ozchinese.com +bbs.qmzdd.com +bbs.sina.com +bbs.skykiwi.com +bbs.sou-tong.org +bbs.tuitui.info +bbsdigest.com +bbsfeed.com +bbsland.com +bbsmo.com +bbsone.com +bbtoystore.com +bcast.co.nz +bcc.com.tw +bcchinese.net +bcex.ca +bcmorning.com +bdsmvideos.net +beaconevents.com +bebo.com +beeg.com +beevpn.com +behance.net +behindkink.com +beijing1989.com +beijingspring.com +beijingzx.org +belamionline.com +bell.wiki +bemywife.cc +beric.me +berlintwitterwall.com +berm.co.nz +bestforchina.org +bestgore.com +bestpornstardb.com +bestvpn.com +bestvpnanalysis.com +bestvpnserver.com +bestvpnservice.com +bestvpnusa.com +bet365.com +betfair.com +betternet.co +bettervpn.com +bettween.com +betvictor.com +bewww.net +beyondfirewall.com +bfnn.org +bfsh.hk +bgvpn.com +bianlei.com +biantailajiao.com +biantailajiao.in +biblesforamerica.org +bibox.com +bic2011.org +big.one +bigfools.com +bigjapanesesex.com +bigmoney.biz +bignews.org +bigsound.org +biliworld.com +billypan.com +binance.com +binux.me +bipic.net +bird.so +bit-z.com +bit.do +bit.ly +bitc.bme.emory.edu +bitcointalk.org +bitcoinworld.com +bitfinex.com +bitinka.com.ar +bitmex.com +bitshare.com +bitsnoop.com +bitvise.com +bizhat.com +bjnewlife.org +bjs.org +bjzc.org +bl-doujinsouko.com +blacklogic.com +blackvpn.com +blewpass.com +blinkx.com +blinw.com +blip.tv +blockcn.com +blockless.com +blog.calibre-ebook.com +blog.cnyes.com +blog.daum.net +blog.de +blog.exblog.co.jp +blog.excite.co.jp +blog.expofutures.com +blog.fizzik.com +blog.foolsmountain.com +blog.fuckgfw233.org +blog.goo.ne.jp +blog.google +blog.inoreader.com +blog.istef.info +blog.jackjia.com +blog.jp +blog.kangye.org +blog.lester850.info +blog.martinoei.com +blog.pathtosharepoint.com +blog.pentalogic.net +blog.qooza.hk +blog.ranxiang.com +blog.sina.com.tw +blog.sogoo.org +blog.soylent.com +blog.syx86.cn +blog.syx86.com +blog.taragana.com +blog.tiney.com +blog.xuite.net +blog.youthwant.com.tw +blog.youxu.info +blogblog.com +blogcatalog.com +blogcity.me +blogdns.org +blogger.com +blogimg.jp +bloglines.com +bloglovin.com +blogs.icerocket.com +blogs.libraryinformationtechnology.com +blogs.tampabay.com +blogs.yahoo.co.jp +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.net +blogtd.org +bloodshed.net +bloomberg.cn +bloomberg.com +bloomberg.de +bloombergview.com +bloomfortune.com +blueangellive.com +bmfinn.com +bnews.co +bnrmetal.com +boardreader.com +bod.asia +bodog88.com +bolehvpn.net +bolin.netfirms.com +bonbonme.com +bonbonsex.com +bonfoundation.org +bongacams.com +boobstagram.com +book.com.tw +book.zi5.me +bookepub.com +books.com.tw +booktopia.com.au +boomssr.com +bot.nu +botanwang.com +bowenpress.com +boxpn.com +boxun.com +boxun.tv +boxunblog.com +boxunclub.com +boyangu.com +boyfriendtv.com +boysfood.com +boysmaster.com +br.hao123.com +br.st +brainyquote.com +brandonhutchinson.com +braumeister.org +bravotube.net +brazzers.com +break.com +breakgfw.com +breaking911.com +breakingtweets.com +breakwall.net +briefdream.com +briian.com +brizzly.com +brkmd.com +broadbook.com +broadpressinc.com +brucewang.net +brutaltgp.com +bt2mag.com +bt95.com +btaia.com +btbtav.com +btcbank.bank +btctrade.im +btdigg.org +btku.me +btku.org +btspread.com +btsynckeys.com +budaedu.org +buddhanet.com.tw +buddhistchannel.tv +buffered.com +bullog.org +bullogger.com +bunbunhk.com +busayari.com +businessinsider.com +businessweek.com +busu.org +busytrade.com +buugaa.com +buy.yahoo.com.tw +buzzhand.com +buzzhand.net +buzzorange.com +bvpn.com +bwh1.net +bwsj.hk +bx.in.th +bx.tl +bynet.co.il +c-est-simple.com +c-spanvideo.org +c100tibet.org +c1522.mooo.com +c2cx.com +cablegatesearch.net +cachinese.com +cacnw.com +cactusvpn.com +cafepress.com +cahr.org.tw +calameo.com +calebelston.com +calgarychinese.ca +calgarychinese.com +calgarychinese.net +cam4.com +cam4.jp +cam4.sg +camfrog.com +cams.com +cams.org.sg +canadameet.com +canalporno.com +canyu.org +cao.im +caobian.info +caochangqing.com +cap.org.hk +carabinasypistolas.com +cardinalkungfoundation.org +carfax.com +cari.com.my +caribbeancom.com +carmotorshow.com +cartoonmovement.com +casadeltibetbcn.org +casatibet.org.mx +casino.williamhill.com +casinobellini.com +casinoking.com +casinoriva.com +castbox.fm +catch22.net +catchgod.com +catfightpayperview.xxx +catholic.org.hk +catholic.org.tw +cathvoice.org.tw +cattt.com +cbc.ca +cbs.ntu.edu.tw +cbsnews.com +cbtc.org.hk +cccat.cc +cccat.co +ccdtr.org +cchere.com +ccim.org +cclife.ca +cclife.org +cclifefl.org +ccthere.com +cctmweb.net +cctongbao.com +ccue.ca +ccue.com +ccvoice.ca +ccw.org.tw +cdbook.org +cdcparty.com +cdef.org +cdig.info +cdjp.org +cdn-apple.com +cdn-images.mailchimp.com +cdn.assets.lfpcontent.com +cdn.helixstudios.net +cdn.printfriendly.com +cdn.seatguru.com +cdn.softlayer.net +cdn1.lp.saboom.com +cdnews.com.tw +cdninstagram.com +cdp1989.org +cdp1998.org +cdp2006.org +cdpa.url.tw +cdpeu.org +cdpusa.org +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 +cfhks.org.hk +cfos.de +cftfc.com +cgdepot.org +cgst.edu +ch.shvoong.com +change.org +changeip.name +changeip.net +changeip.org +changp.com +changsa.net +channel8news.sg +chaoex.com +chapm25.com +chatnook.com +chaturbate.com +chengmingmag.com +chenguangcheng.com +chenpokong.com +chenpokong.net +chenshan20042005.wordpress.com +cherrysave.com +chhongbi.org +chicagoncmtv.com +china-mmm.jp.net +china-mmm.net +china-mmm.sa.com +china-review.com.ua +china-week.com +china.hket.com +china.ucanews.com +china101.com +china18.org +china21.com +china21.org +china5000.us +chinaaffairs.org +chinaaid.me +chinaaid.net +chinaaid.org +chinaaid.us +chinachange.org +chinachannel.hk +chinacitynews.be +chinacomments.org +chinadialogue.net +chinadigitaltimes.net +chinaelections.org +chinaeweekly.com +chinafreepress.org +chinagate.com +chinageeks.org +chinagfw.org +chinagonet.com +chinagreenparty.org +chinahorizon.org +chinahush.com +chinainperspective.com +chinainterimgov.org +chinalaborwatch.org +chinalawandpolicy.com +chinalawtranslate.com +chinamule.com +chinamz.org +chinapost.com.tw +chinapress.com.my +chinarightsia.org +chinasmile.net +chinasocialdemocraticparty.com +chinasoul.org +chinasucks.net +chinatimes.com +chinatopsex.com +chinatown.com.au +chinatweeps.com +chinaview.wordpress.com +chinaway.org +chinaworker.info +chinaxchina.com +chinayouth.org.hk +chinayuanmin.org +chinese-hermit.net +chinese-leaders.org +chinese-memorial.org +chinese.donga.com +chinese.engadget.com +chinese.irib.ir +chinese.soifind.com +chinesedaily.com +chinesedailynews.com +chinesedemocracy.com +chinesegay.org +chinesen.de +chinesenews.net.au +chinesepen.org +chinesetalks.net +chineseupress.com +chingcheong.com +chinman.net +chithu.org +chn.chosun.com +chobit.cc +chrdnet.com +christianfreedom.org +christianstudy.com +christiantimes.org.hk +christusrex.org +chrlawyers.hk +chrome.com +chromecast.com +chromeexperiments.com +chromercise.com +chromestatus.com +chromium.org +chuang-yen.org +chubold.com +chubun.com +chuizi.net +churchinhongkong.org +chushigangdrug.ch +cienen.com +cineastentreff.de +cipfg.org +circlethebayfortibet.org +cirosantilli.com +citizencn.com +citizenlab.org +citizenscommission.hk +citizensradio.org +city365.ca +city9x.com +citypopulation.de +citytalk.tw +civicparty.hk +civildisobediencemovement.org +civilhrfront.org +civiliangunner.com +civilmedia.tw +ck101.com +cl.d0z.net +clarionproject.org +classicalguitarblog.net +clb.org.hk +cldr.unicode.org +cleansite.biz +cleansite.info +cleansite.us +clearharmony.net +clearsurance.com +clearwisdom.net +clementine-player.org +cling.omy.sg +clinica-tibet.ru +clipfish.de +cloakpoint.com +cloud.mail.ru +club1069.com +cmcn.org +cmi.org.tw +cmp.hku.hk +cms.gov +cmule.com +cmule.org +cmx.im +cn-proxy.com +cn.calameo.com +cn.dayabook.com +cn.fmnnow.com +cn.freeones.com +cn.giganews.com +cn.ibtimes.com +cn.nytstyle.com +cn.sandscotaicentral.com +cn.shafaqna.com +cn.streetvoice.com +cn.thegay.com +cn.uncyclopedia.wikia.com +cn.uptodown.com +cn.voa.mobi +cn2.streetvoice.com +cn6.eu +cna.com.tw +cnabc.com +cnbbnews.wordpress.com +cnd.org +cnex.org.cn +cnineu.com +cnn.com +cnnews.chosun.com +cnpolitics.org +cnproxy.com +co.ng.mil +coat.co.jp +cochina.co +cochina.org +code1984.com +codeshare.io +codeskulptor.org +coin2co.in +coinegg.com +coinex.com +coingi.com +coinrail.co.kr +cointobe.com +coinut.com +collateralmurder.com +collateralmurder.org +com.google +comefromchina.com +comic-mega.me +commandarms.com +commentshk.com +communistcrimes.org +community.windy.com +communitychoicecu.com +compileheart.com +compress.to +connect.facebook.net +conoha.jp +contactmagazine.net +contests.twilio.com +convio.net +coobay.com +coolaler.com +coolder.com +coolloud.org.tw +coolncute.com +coolstuffinc.com +corumcollege.com +cos-moe.com +cosmic.monar.ch +cosplayjav.pl +costco.com +cotweet.com +coursehero.com +cpj.org +cq99.us +crackle.com +crazys.cc +crazyshit.com +crbug.com +crchina.org +crd-net.org +creaders.net +creadersnet.com +creativelab5.com +crisisresponse.google +cristyli.com +crocotube.com +crossfire.co.kr +crossthewall.net +crossvpn.net +crrev.com +crucial.com +csdparty.com +css.pixnet.in +csuchen.de +csw.org.uk +ct.org.tw +ctao.org +ctfriend.net +cthlo.github.io +ctitv.com.tw +cts.com.tw +cuhkacs.org +cuihua.org +cuiweiping.net +culture.tw +cumlouder.com +curvefish.com +cusu.hk +cutscenes.net +cw.com.tw +cyberghost.natado.com +cyberghostvpn.com +cynscribe.com +cytode.us +d-fukyu.com +d100.net +d1b183sg0nvnuh.cloudfront.net +d1c37gjwa26taa.cloudfront.net +d2bay.com +d2pass.com +d3c33hcgiwev3.cloudfront.net +d3rhr7kgmtrq1v.cloudfront.net +dabr.co.uk +dabr.eu +dabr.me +dabr.mobi +dadazim.com +dadi360.com +dafabet.com +dafagood.com +dafahao.com +dafoh.org +daftporn.com +dagelijksestandaard.nl +daidostup.ru +dailidaili.com +dailymotion.com +dailynews.sina.com +daiphapinfo.net +dajiyuan.com +dajiyuan.de +dajiyuan.eu +dajusha.baywords.com +dalailama-archives.org +dalailama.com +dalailama.mn +dalailama.ru +dalailama.usc.edu +dalailama80.org +dalailamacenter.org +dalailamafellows.org +dalailamafilm.com +dalailamafoundation.org +dalailamahindi.com +dalailamainaustralia.org +dalailamajapanese.com +dalailamaprotesters.info +dalailamaquotes.org +dalailamatrust.org +dalailamavisit.org.nz +dalailamaworld.com +dalianmeng.org +daliulian.org +danbooru.donmai.us +danke4china.net +danwei.org +daodu14.jigsy.com +daolan.net +daozhongxing.org +darktech.org +darktoy.net +darpa.mil +dastrassi.org +data-vocabulary.org +data.flurry.com +data.gov.tw +david-kilgour.com +dawangidc.com +daxa.cn +daylife.com +db.tt +dbc.hk +dcard.tw +dcmilitary.com +ddc.com.tw +ddhw.info +ddns.info +ddns.me.uk +ddns.mobi +ddns.ms +ddns.name +ddns.net +ddns.us +de-sci.org +deaftone.com +debug.com +deck.ly +decodet.co +deepmind.com +deezer.com +definebabe.com +deja.com +delcamp.net +delicious.com +demo.opera-mini.net +democrats.org +depositphotos.com +derekhsu.homeip.net +desc.se +design.google +desipro.de +dessci.com +destiny.xfiles.to +destroy-china.jp +deutsche-welle.de +developers.box.net +devio.us +devpn.com +dfas.mil +dfn.org +dharamsalanet.com +dharmakara.net +dhcp.biz +diaoyuislands.org +dictionary.goo.ne.jp +difangwenge.org +digiland.tw +digisfera.com +digitalnomadsproject.org +diigo.com +dilber.se +dingchin.com.tw +dipity.com +directcreative.com +discoins.com +discordapp.com +discordapp.net +discuss.com.hk +discuss4u.com +dish.com +disp.cc +disqus.com +dit-inc.us +dizhidizhi.com +dizhuzhishang.com +djangosnippets.org +djorz.com +dl-laby.jp +dl.box.net +dlsite.com +dlyoutube.com +dm530.net +dmcdn.net +dmm.co.jp +dns-dns.com +dns-stuff.com +dns04.com +dns05.com +dns1.us +dns2.us +dns2go.com +dnscrypt.org +dnset.com +dnsrd.com +dnssec.net +dnvod.tv +doctorvoice.org +dogfartnetwork.com +dojin.com +dok-forum.net +dolc.de +dolf.org.hk +dollf.com +domain.club.tw +domainhelp.search.com +domains.google +domaintoday.com.au +dongtaiwang.com +dongtaiwang.net +dongyangjing.com +dontfilter.us +dontmovetochina.com +dorjeshugden.com +dotplane.com +dotsub.com +dotvpn.com +doub.io +dougscripts.com +douhokanko.net +doujincafe.com +dowei.org +download.aircrack-ng.org +download.cnet.com +download.ithome.com.tw +dphk.org +dpp.org.tw +dpr.info +dragonex.io +dragonsprings.org +dreamamateurs.com +drepung.org +drgan.net +drmingxia.org +dropbooks.tv +dropbox.com +dropboxusercontent.com +drsunacademy.com +drtuber.com +dscn.info +dsmtp.com +dstk.dk +dtdns.net +dtiblog.com +dtic.mil +dtwang.org +duanzhihu.com +duck.com +duckdns.org +duckduckgo-owned-server.yahoo.net +duckduckgo.com +duckload.com +duckmylife.com +duga.jp +duihua.org +duihuahrjournal.org +dumb1.com +dunyabulteni.net +duoweitimes.com +duping.net +duplicati.com +dupola.com +dupola.net +dushi.ca +dvdpac.com +dvorak.org +dw-world.com +dw-world.de +dw.com +dw.de +dwnews.com +dwnews.net +dynamic-dns.net +dynamicdns.biz +dynamicdns.co.uk +dynamicdns.me.uk +dynamicdns.org.uk +dynawebinc.com +dyndns-ip.com +dyndns-pics.com +dyndns.org +dyndns.pro +dynssl.com +dynu.com +dynu.net +dynupdate.no-ip.com +dzze.com +e-classical.com.tw +e-gold.com +e-hentai.org +e-hentaidb.com +e-info.org.tw +e-traderland.net +e-zone.com.hk +e123.hk +earlytibet.com +earthcam.com +earthvpn.com +eastern-ark.com +easternlightning.org +eastturkestan.com +eastturkistan-gov.org +eastturkistancc.org +eastturkistangovernmentinexile.us +easyca.ca +easypic.com +ebony-beauty.com +ebook.hyread.com.tw +ebookbrowse.com +ebookee.com +ebtcbank.com +ecfa.org.tw +echofon.com +ecimg.tw +ecministry.net +economist.com +ecsm.vs.com +edgecastcdn.net +edicypages.com +edmontonchina.cn +edmontonservice.com +edns.biz +edoors.com +edubridge.com +edupro.org +eeas.europa.eu +eesti.ee +eevpn.com +efcc.org.hk +effers.com +efksoft.com +efukt.com +eic-av.com +eireinikotaerukai.com +eisbb.com +eksisozluk.com +electionsmeter.com +elgoog.im +elpais.com +eltondisney.com +emaga.com +emanna.com +embr.in +emilylau.org.hk +empfil.com +emule-ed2k.com +emulefans.com +emuparadise.me +en.favotter.net +en.hao123.com +enanyang.my +enewstree.com +enfal.de +engagedaily.org +englishforeveryone.org +englishfromengland.co.uk +englishpen.org +enlighten.org.tw +entermap.com +entnt.com +environment.google +epa.gov.tw +epac.to +episcopalchurch.org +epochhk.com +epochtimes-bg.com +epochtimes-romania.com +epochtimes.co.il +epochtimes.co.kr +epochtimes.com +epochtimes.cz +epochtimes.de +epochtimes.fr +epochtimes.ie +epochtimes.it +epochtimes.jp +epochtimes.ru +epochtimes.se +epochtimestr.com +epochweek.com +epochweekly.com +eporner.com +equinenow.com +erabaru.net +eracom.com.tw +eraysoft.com.tr +erepublik.com +erights.net +eriversoft.com +erktv.com +ernestmandel.org +erodaizensyu.com +erodoujinlog.com +erodoujinworld.com +eromanga-kingdom.com +eromangadouzin.com +eromon.net +eroprofile.com +eroticsaloon.net +eslite.com +esmtp.biz +esurance.com +etaa.org.au +etadult.com +etaiwannews.com +etcd.io +etherdelta.com +etizer.org +etokki.com +etools.ncol.com +etowns.net +etowns.org +ettoday.net +etvonline.hk +eu.org +eucasino.com +eulam.com +eurekavpt.com +evchk.wikia.com +evschool.net +exblog.jp +exchristian.hk +exmo.com +exmormon.org +expatshield.com +expecthim.com +expekt.com +experts-univers.com +exploader.net +expressvpn.com +exrates.me +extmatrix.com +extremetube.com +exx.com +eyevio.jp +eyny.com +ezpc.tk +ezpeer.com +ezua.com +fa.gov.tw +facebook.br +facebook.com +facebook.design +facebook.hu +facebook.in +facebook.nl +facebook.se +facebookquotes4u.com +faceless.me +facesofnyfw.com +facesoftibetanselfimmolators.info +fail.hk +faith100.org +faithfuleye.com +faiththedog.info +fakku.net +falsefire.com +falun-co.org +falun-ny.net +falun.caltech.edu +falunart.org +falunasia.info +falunau.org +falunaz.net +falundafa-dc.org +falundafa-florida.org +falundafa-nc.org +falundafa-pa.net +falundafa-sacramento.org +falundafa.org +falundafaindia.org +falundafamuseum.org +falungong.club +falungong.de +falungong.org.uk +falunhr.org +faluninfo.de +faluninfo.net +falunpilipinas.net +falunworld.net +familyfed.org +famunion.com +fan-qiang.com +fangbinxing.com +fangeming.com +fangeqiang.com +fanglizhi.info +fangmincn.org +fangong.forums-free.com +fangong.org +fangongheike.com +fanhaodang.com +fanqiang.tk +fanqianghou.com +fanqiangyakexi.net +fanqiangzhe.com +fanswong.com +fanyue.info +fapdu.com +faproxy.com +faqserv.com +fartit.com +farwestchina.com +fast.wistia.com +fastpic.ru +fastssh.com +faststone.org +fatbtc.com +favstar.fm +fawanghuihui.org +faydao.com +fb.com +fb.me +fbaddins.com +fbcdn.net +fbsbx.com +fbworkmail.com +fc2.com +fc2blog.net +fc2china.com +fc2cn.com +fda.gov.tw +fdc64.de +fdc64.org +fdc89.jp +feedburner.com +feeds.fileforum.com +feelssh.com +feer.com +feifeiss.com +feitian-california.org +feitianacademy.org +feministteacher.com +fengzhenghu.com +fengzhenghu.net +fevernet.com +ff.im +fffff.at +fflick.com +ffvpn.com +fgmtv.net +fgmtv.org +fhreports.net +figprayer.com +fileflyer.com +files2me.com +fileserve.com +filesor.com +fillthesquare.org +filmingfortibet.org +filmy.olabloga.pl +filthdump.com +financetwitter.com +finchvpn.com +findmespot.com +findyoutube.com +findyoutube.net +fingerdaily.com +finler.net +firearmsworld.net +firebaseio.com +fireofliberty.org +firetweet.io +firstfivefollowers.com +flagsonline.it +flecheinthepeche.fr +fleshbot.com +fleursdeslettres.com +flgg.us +flgjustice.org +flickr.com +flickrhivemind.net +flickriver.com +fling.com +flipboard.com +flipkart.com +flitto.com +flnet.org +flog.tw +flyvpn.com +flyzy2005.com +fnac.be +fnac.com +fochk.org +focustaiwan.tw +focusvpn.com +fofg-europe.net +fofg.org +fofldfradio.org +fooooo.com +footwiball.com +foreignpolicy.com +forum.baby-kingdom.com +forum.cyberctm.com +forum.idsam.com +forum.my903.com +forum.mymaji.com +forum.omy.sg +forum.palmislife.com +forum.setty.com.tw +forum.sina.com.hk +forum.slime.com.tw +forum.tvb.com +forum.xinbao.de +forum4hk.com +fotile.me +fourface.nodesnoop.com +fourthinternational.org +foxdie.us +foxgay.com +foxsub.com +foxtang.com +fpmt-osel.org +fpmt.org +fpmt.tw +fpmtmexico.org +fq.wikia.com +fqok.org +fqrouter.com +franklc.com +freakshare.com +free-gate.org +free-hada-now.org +free-proxy.cz +free-ss.site +free-ssh.com +free.fr +free4u.com.ar +freealim.com +freebrowser.org +freechal.com +freechina.net +freechina.news +freechinaforum.org +freechinaweibo.com +freeddns.com +freeddns.org +freedomchina.info +freedomcollection.org +freedomhouse.org +freedominfonetweb.wordpress.com +freedomsherald.org +freeforums.org +freefq.com +freefuckvids.com +freegao.com +freeilhamtohti.org +freekwonpyong.org +freelotto.com +freeman2.com +freemoren.com +freemorenews.com +freemuse.org +freenet-china.org +freenetproject.org +freenewscn.com +freeopenvpn.com +freeoz.org +freessh.us +freetcp.com +freetibet.net +freetibet.org +freetibetanheroes.org +freeviewmovies.com +freevpn.me +freevpn.nl +freewallpaper4.me +freewebs.com +freewechat.com +freeweibo.com +freewww.biz +freewww.info +freexinwen.com +freeyellow.com +freeyoutubeproxy.net +friendfeed-media.com +friendfeed.com +friends-of-tibet.org +friendsoftibet.org +fring.com +fringenetwork.com +from-pr.com +from-sd.com +fromchinatousa.net +frommel.net +frontlinedefenders.org +frootvpn.com +fscked.org +fsurf.com +ftchinese.com +ftp1.biz +ftpserver.biz +ftv.com.tw +fucd.com +fuckcnnic.net +fuckgfw.org +fullerconsideration.com +fulue.com +funf.tw +funkyimg.com +funp.com +fuq.com +furbo.org +furhhdl.org +furinkan.com +furl.net +futurechinaforum.org +futuremessage.org +fux.com +fuyin.net +fuyindiantai.org +fuyu.org.tw +fw.cm +fxcm-chinese.com +fxnetworks.com +fzh999.com +fzh999.net +fzlm.com +g-area.org +g-queen.com +g.co +g6hentai.com +gabocorp.com +gaeproxy.com +gaforum.org +galaxymacau.com +galenwu.com +galstars.net +game735.com +gamebase.com.tw +gamejolt.com +gamer.com.tw +gamez.com.tw +gamousa.com +ganges.com +gaoming.net +gaopi.net +gaozhisheng.net +gaozhisheng.org +gardennetworks.com +gardennetworks.org +gartlive.com +gate-project.com +gate.io +gatecoin.com +gather.com +gatherproxy.com +gati.org.tw +gaybubble.com +gaycn.net +gayhub.com +gaymap.cc +gaymenring.com +gaytube.com +gaywatch.com +gazotube.com +gcc.org.hk +gclooney.com +gcmasia.com +gcpnews.com +gcr.io +gdbt.net +gdzf.org +geek-art.net +geekerhome.com +geekheart.info +gekikame.com +gelbooru.com +geocities.co.jp +geocities.com +geocities.jp +gerefoundation.org +get.app +get.how +get.page +getastrill.com +getchu.com +getcloak.com +getfoxyproxy.org +getfreedur.com +getgom.com +geti2p.net +getiton.com +getjetso.com +getlantern.org +getmdl.io +getoutline.org +getsocialscope.com +getsync.com +gettrials.com +gettyimages.com +getuploader.com +gfbv.de +gfgold.com.hk +gfsale.com +gfw.org.ua +gfw.press +ggpht.com +ggssl.com +ghostpath.com +ghut.org +giantessnight.com +gifree.com +giga-web.jp +gigporno.ru +girlbanker.com +gist.github.com +git.io +github.com +githubusercontent.com +gizlen.net +gjczz.com +glass8.eu +global.bing.com +globaljihad.net +globalmediaoutreach.com +globalmuseumoncommunism.org +globalrescue.net +globaltm.org +globalvoices.org +globalvoicesonline.org +globalvpn.net +glock.com +gloryhole.com +glorystar.me +gluckman.com +glype.com +gmail.com +gmbd.cn +gmhz.org +gmll.org +gmodules.com +gmozomg.izihost.org +gnci.org.hk +go-pki.com +go.nesnode.com +go141.com +goagent.biz +goagent.codeplex.com +goagentplus.com +gobet.cc +godfootsteps.org +godns.work +godoc.org +godsdirectcontact.co.uk +godsdirectcontact.org +godsdirectcontact.org.tw +godsimmediatecontact.com +gogotunnel.com +gohappy.com.tw +gojet.krtco.com.tw +gokbayrak.com +golang.org +goldbet.com +goldbetsports.com +goldeneyevault.com +goldenfrog.com +goldjizz.com +goldstep.net +goldwave.com +gongm.in +gongmeng.info +gongminliliang.com +gongwt.com +goo.gl +gooday.xyz +gooddns.info +goodreaders.com +goodreads.com +goodtv.com.tw +goodtv.tv +goofind.com +google.ad +google.ae +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.calstate.edu +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.dj +google.dk +google.dm +google.dz +google.ee +google.es +google.fi +google.fm +google.fr +google.ga +google.ge +google.gg +google.gl +google.gm +google.gp +google.gr +google.gy +google.hn +google.hr +google.ht +google.hu +google.ie +google.im +google.iq +google.is +google.it +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.ne +google.nl +google.no +google.nr +google.nu +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.vg +google.vu +google.ws +googleapis.cn +googleapis.com +googleapps.com +googlearth.com +googleartproject.com +googleblog.com +googlebot.com +googlechinawebmaster.com +googlecode.com +googlecommerce.com +googledomains.com +googledrive.com +googleearth.com +googlegroups.com +googlehosted.com +googleideas.com +googleinsidesearch.com +googlelabs.com +googlemail.com +googlemashups.com +googlepagecreator.com +googleplay.com +googleplus.com +googlescholar.com +googlesile.com +googlesource.com +googleusercontent.com +googlevideo.com +googleweblight.com +googlezip.net +gopetition.com +goproxing.net +goregrish.com +gospelherald.com +got-game.org +gotdns.ch +gotgeeks.com +gotrusted.com +gotw.ca +gov.taipei +gov.tw +gr8domain.biz +gr8name.biz +grammaly.com +grandtrial.org +grangorz.org +graphis.ne.jp +graphql.org +greasespot.net +great-firewall.com +great-roc.org +greatfire.org +greatfire.us7.list-manage.com +greatfirewall.biz +greatfirewallofchina.net +greatfirewallofchina.org +greatroc.org +greatroc.tw +greatzhonghua.org +greenfieldbookstore.com.hk +greenparty.org.tw +greenpeace.com.tw +greenpeace.org +greenreadings.com +greenvpn.net +greenvpn.org +grotty-monday.com +groups.google.cn +grow.google +gs-discuss.com +gsp.target.com +gstatic.com +gtricks.com +gts-vpn.com +gu-chu-sum.org +guaguass.com +guaguass.org +guancha.org +guaneryu.com +guangming.com.my +guardster.com +guishan.org +gumroad.com +gun-world.net +gunsamerica.com +gunsandammo.com +guo.media +guruonline.hk +gutteruncensored.com +gvlib.com +gvm.com.tw +gvt0.com +gvt1.com +gvt3.com +gwtproject.org +gyalwarinpoche.com +gyatsostudio.com +gzm.tv +gzone-anime.info +h-china.org +h-moe.com +h1n1china.org +h528.com +h5dm.com +h5galgame.me +hacg.club +hacg.in +hacg.li +hacg.me +hacg.red +hacken.cc +hacker.org +hackthatphone.net +hahaxixi.github.io +hahlo.com +hakkatv.org.tw +handcraftedsoftware.org +hanunyi.com +hao.news +haoel.github.io +happy-vpn.com +haproxy.org +hardsextube.com +harunyahya.com +hautelook.com +hautelookcdn.com +have8.com +hbo.com +hclips.com +hd.stheadline.com +hdlt.me +hdtvb.net +hdzog.com +heartyit.com +heavy-r.com +hec.su +hecaitou.net +hechaji.com +heeact.edu.tw +hegre-art.com +heix.pp.ru +helloandroid.com +helloqueer.com +helloss.pw +hellotxt.com +hellouk.org +help.linksalpha.com +helpeachpeople.com +helplinfen.com +helpster.de +helpzhuling.org +hentai.to +hentaitube.tv +hentaivideoworld.com +heqinglian.net +heungkongdiscuss.com +hexieshe.com +hexieshe.xyz +hexxeh.net +heyzo.com +hgseav.com +hhdcb3office.org +hhthesakyatrizin.org +hi-on.org.tw +hidden-advent.org +hide.me +hidecloud.com +hidein.net +hideipvpn.com +hideman.net +hideme.nl +hidemy.name +hidemyass.com +hidemycomp.com +higfw.com +highpeakspureearth.com +highrockmedia.com +hihiforum.com +hihistory.net +hiitch.com +hikinggfw.org +hilive.tv +himalayan-foundation.org +himalayanglacier.com +himemix.com +himemix.net +hitbtc.com +hitomi.la +hiwifi.com +hizb-ut-tahrir.info +hizb-ut-tahrir.org +hizbuttahrir.org +hjclub.info +hk-pub.com +hk.frienddy.com +hk.geocities.com +hk.gradconnection.com +hk.hao123img.com +hk.jiepang.com +hk.knowledge.yahoo.com +hk.myblog.yahoo.com +hk.news.yahoo.com +hk.rd.yahoo.com +hk.search.yahoo.com +hk.video.news.yahoo.com +hk.yahoo.com +hk01.com +hk32168.com +hka8964.wordpress.com +hkacg.com +hkacg.net +hkanews.wordpress.com +hkatvnews.com +hkbc.net +hkbf.org +hkbookcity.com +hkchurch.org +hkci.org.hk +hkcmi.edu +hkcnews.com +hkcoc.com +hkcoc.weather.com.hk +hkdailynews.com.hk +hkday.net +hkdf.org +hkej.com +hkepc.com +hkfaa.com +hkfreezone.com +hkfront.org +hkgolden.com +hkgreenradio.org +hkheadline.com +hkheadline.comblog +hkhkhk.com +hkhrc.org.hk +hkhrm.org.hk +hkip.org.uk +hkjc.com +hkjp.org +hklft.com +hklts.org.hk +hkptu.org +hkreporter.com +hkreporter.loved.hk +hkupop.hku.hk +hkusu.net +hkvwet.com +hkwcc.org.hk +hkzone.org +hmonghot.com +hmv.co.jp +hmvdigital.ca +hmvdigital.com +hnjhj.com +hnntube.com +hola.com +hola.org +holymountaincn.com +holyspiritspeaks.org +home.sina.com +home.so-net.net.tw +homedepot.com +homeperversion.com +homeservershow.com +hongkongfp.com +hongmeimei.com +hongzhi.li +hootsuite.com +hoovers.com +hopedialogue.org +hopto.org +hornygamer.com +hornytrip.com +hotav.tv +hotels.cn +hotfrog.com.tw +hotgoo.com +hotpornshow.com +hotpot.hk +hotshame.com +hotspotshield.com +hotvpn.com +hougaige.com +howtoforge.com +hoxx.com +hpa.gov.tw +hqcdp.org +hqjapanesesex.com +hqmovies.com +hqsbnet.wordpress.com +hqsbonline.wordpress.com +hrcchina.org +hrcir.com +hrea.org +hrichina.org +hrtsea.com +hrw.org +hrweb.org +hsjp.net +hsselite.com +hst.net.tw +hstern.net +hstt.net +ht.ly +htkou.net +htl.li +html5rocks.com +https443.net +https443.org +hua-yue.net +huaglad.com +huanghuagang.org +huangyiyu.com +huaren.us +huaren4us.com +huashangnews.com +huaxia-news.com +huaxiabao.org +huaxin.ph +huayuworld.org +hudatoriq.web.id +hudson.org +huffingtonpost.com +hugoroy.eu +huhaitai.com +huhamhire.com +huiyi.in +hulkshare.com +hulu.com +huluim.com +humanrightsbriefing.org +hung-ya.com +hungerstrikeforaids.org +huobi.com +huobi.pro +huobipro.com +huping.net +hurgokbayrak.com +hurriyet.com.tr +hustlercash.com +hut2.ru +hutianyi.net +hutong9.net +huyandex.com +hwadzan.tw +hwayue.org.tw +hwinfo.com +hxwk.org +hxwq.org +hybrid-analysis.com +hyperrate.com +i-cable.com +i-part.com.tw +i-scmp.com +i.lithium.com +i1.hk +i2p2.de +i2runner.com +i818hk.com +iam.soy +iamtopone.com +iask.bz +iask.ca +iav19.com +ibiblio.org +iblist.com +iblogserv-f.net +ibros.org +ibvpn.com +icams.com +ice.audionow.com +icij.org +icl-fi.org +icoco.com +iconpaper.org +icu-project.org +id.hao123.com +id.heroku.com +iddddg.com +idemocracy.asia +identi.ca +idiomconnection.com +idouga.com +idreamx.com +idv.tw +ieasy5.com +ied2k.net +ienergy1.com +if.ttt +ifan.cz.cc +ifanqiang.com +ifcss.org +ifjc.org +ifreewares.com +ift.tt +igcd.net +igfw.net +igfw.tech +igmg.de +ignitedetroit.net +igoogle.com +igotmail.com.tw +igvita.com +ihakka.net +ihao.org +iicns.com +iipdigital.usembassy.gov +ikstar.com +ikwb.com +illusionfactory.com +ilove80.be +ilovelongtoes.com +im.tv +im88.tw +imageab.com +imagefap.com +imageflea.com +images-gaytube.com +images.comico.tw +imageshack.us +imagevenue.com +imagezilla.net +imb.org +imdb.com +img.dlsite.jp +img.ly +imgchili.net +imgmega.com +imgur.com +imkev.com +imlive.com +immigration.gov.tw +immoral.jp +impact.org.au +impp.mn +in-disguise.com +in99.org +incapdns.net +incloak.com +incredibox.fr +indiandefensenews.in +indiemerch.com +info-graf.fr +initiativesforchina.org +inkui.com +inmediahk.net +innermongolia.org +inote.tw +insecam.org +insidevoa.com +instagram.com +instanthq.com +institut-tibetain.org +international-news.newsmagazine.asia +internet.org +internetdefenseleague.org +internetfreedom.org +internetpopculture.com +inthenameofconfuciusmovie.com +investigating.wordpress.com +inxian.com +iownyour.biz +iownyour.org +ipalter.com +ipfire.org +ipfs.io +iphone4hongkong.com +iphonehacks.com +iphonetaiwan.org +iphonix.fr +ipicture.ru +ipjetable.net +ipobar.com +ipoock.com +iportal.me +ippotv.com +ipredator.se +iptv.com.tw +iptvbin.com +ipvanish.com +iredmail.org +ironbigfools.compython.net +ironpython.net +ironsocket.com +is-a-hunter.com +is.gd +isaacmao.com +isasecret.com +isgreat.org +islahhaber.net +islam.org.hk +islamawareness.net +islamhouse.com +islamicity.com +islamicpluralism.org +islamtoday.net +ismaelan.com +ismalltits.com +ismprofessional.net +isohunt.com +israbox.com +issuu.com +istars.co.nz +istiqlalhewer.com +istockphoto.com +isunaffairs.com +isuntv.com +itaboo.info +itaiwan.gov.tw +italiatibet.org +itasoftware.com +itemdb.com +ithelp.ithome.com.tw +its.caltech.edu +itsaol.com +itshidden.com +itsky.it +itweet.net +iu45.com +iuhrdf.org +iuksky.com +ivacy.com +iverycd.com +ivpn.net +ixquick.com +ixxx.com +iyouport.com +izaobao.us +izles.net +izlesem.org +j.mp +ja.wikipedia.org +jamaat.org +jamyangnorbu.com +jandyx.com +janwongphoto.com +japan-whores.com +japanfirst.asianfreeforum.com +japantimes.co.jp +jav.com +jav101.com +jav2be.com +jav68.tv +javakiba.org +javbus.com +javfor.me +javhd.com +javhip.com +javhub.net +javhuge.com +javlibrary.com +javmobile.net +javmoo.com +javmoo.xyz +javseen.com +javtag.com +javzoo.com +jbtalks.cc +jbtalks.com +jbtalks.my +jcpenney.com +jdwsy.com +jeanyim.com +jetos.com +jex.com +jfqu36.club +jfqu37.xyz +jgoodies.com +jiangweiping.com +jiaoyou8.com +jiehua.cz +jieshibaobao.com +jigglegifs.com +jigong1024.com +jihadintel.meforum.org +jihadology.net +jiji.com +jims.net +jinbushe.org +jingpin.org +jingsim.org +jinpianwang.com +jinroukong.com +jinx.com +jitouch.com +jizzthis.com +jjgirls.com +jkb.cc +jkforum.net +jkub.com +jma.go.jp +jmscult.com +joachims.org +jobnewera.wordpress.com +jobso.tv +journalchretien.net +journalofdemocracy.org +joymiihub.com +joyourself.com +jp.hao123.com +jpl.nasa.gov +jpopforum.net +jtvnw.net +jubushoushen.com +juhuaren.com +jukujo-club.com +juliepost.com +juliereyc.com +junauza.com +june4commemoration.org +junefourth-20.net +jungleheart.com +juoaa.com +justdied.com +justfreevpn.com +justicefortenzin.org +justpaste.it +justtristan.com +juyuange.org +juziyue.com +jwmusic.org +jyxf.net +k-doujin.net +ka-wai.com +kagyu.org +kagyu.org.za +kagyumonlam.org +kagyunews.com.hk +kagyuoffice.org +kagyuoffice.org.tw +kaiyuan.de +kakao.com +kalachakralugano.org +kankan.today +kannewyork.com +kanshifang.com +kantie.org +kanzhongguo.com +kanzhongguo.eu +kaotic.com +karayou.com +karkhung.com +karmapa-teachings.org +karmapa.org +kawaiikawaii.jp +kawase.com +kb.monitorware.com +kba-tx.org +kcoolonline.com +kebrum.com +kechara.com +keepandshare.com +keezmovies.com +kendatire.com +kendincos.net +kenengba.com +keontech.net +kepard.com +kex.com +keycdn.com +khabdha.org +khatrimaza.org +khmusic.com.tw +kichiku-doujinko.com +kik.com +killwall.com +kindleren.com +kineox.free.fr +kingdomsalvation.org +kinghost.com +kingstone.com.tw +kink.com +kinmen.org.tw +kinmen.travel +kir.jp +kissbbao.cn +kiwi.kz +kk-whys.co.jp +kkbox.com +kknews.cc +kmuh.org.tw +knowledgerush.com +kobo.com +kobobooks.com +kodingen.com +kompozer.net +konachan.com +kone.com +koolsolutions.com +koornk.com +koranmandarin.com +korenan2.com +ksdl.org +ksnews.com.tw +kspcoin.com +ktzhk.com +kucoin.com +kui.name +kun.im +kurashsultan.com +kurtmunger.com +kusocity.com +kwcg.ca +kwongwah.com.my +kxsw.life +kyofun.com +kyohk.net +kyoyue.com +kyzyhello.com +kzeng.info +la-forum.org +labiennale.org +ladbrokes.com +lagranepoca.com +lalulalu.com +lama.com.tw +lamayeshe.com +lamnia.co.uk +lamrim.com +lanterncn.cn +lantosfoundation.org +laod.cn +laogai.org +laomiu.com +laoyang.info +laptoplockdown.com +laqingdan.net +larsgeorge.com +lastcombat.com +lastfm.es +latelinenews.com +latibet.org +lbank.info +ld.hao123img.com +le-vpn.com +leafyvpn.net +lecloud.net +leeao.com.cn +lefora.com +left21.hk +legalporno.com +legaltech.law.com +legsjapan.com +leirentv.ca +leisurecafe.ca +leisurepro.com +lematin.ch +lemonde.fr +lenwhite.com +lerosua.org +lers.google +lesoir.be +letou.com +letscorp.net +lflink.com +lflinkup.com +lflinkup.net +lflinkup.org +lhakar.org +lhasocialwork.org +liangyou.net +liangzhichuanmei.com +lianyue.net +liaowangxizang.net +liberal.org.hk +libertytimes.com.tw +library.usc.cuhk.edu.hk +lidecheng.com +lifemiles.com +lighten.org.tw +lightnovel.cn +like.com +limiao.net +line-apps.com +line-scdn.net +line.me +line.naver.jp +linear-abematv.akamaized.net +linglingfa.com +lingvodics.com +link-o-rama.com +linkideo.com +linkuswell.com +linux.org.hk +linuxtoy.org +lionsroar.com +lipuman.com +liquidvpn.com +listentoyoutube.com +listorious.com +lists.w3.org +liu-xiaobo.org +liudejun.com +liuhanyu.com +liujianshu.com +liuxiaobo.net +liuxiaotong.com +livecoin.net +livedoor.jp +liveleak.com +livestation.com +livestream.com +livevideo.com +livingonline.us +livingstream.com +liwangyang.com +lizhizhuangbi.com +lkcn.net +llss.me +load.to +lobsangwangyal.com +localdomain.ws +localpresshk.com +lockestek.com +logbot.net +login.target.com +logiqx.com +londonchinese.ca +longhair.hk +longmusic.com +longtermly.net +longtoes.com +lookpic.com +looktoronto.com +lotsawahouse.org +lotuslight.org.hk +lotuslight.org.tw +lovetvshow.com +lpsg.com +lrfz.com +lrip.org +lsd.org.hk +lsforum.net +lsm.org +lsmchinese.org +lsmkorean.org +lsmradio.com +lsmwebcast.com +lsxszzg.com +ltn.com.tw +luke54.com +luke54.org +lupm.org +lushstories.com +luxebc.com +lvhai.org +lvv2.com +lyfhk.net +lzmtnews.org +m-team.cc +m.hkgalden.com +m.me +m.plixi.com +m.slandr.net +ma.hao123.com +macgamestore.com +macrovpn.com +macts.com.tw +mad-ar.ch +madewithcode.com +madonna-av.com +madrau.com +madthumbs.com +magazines.sina.com.tw +magic-net.info +mahabodhi.org +maiio.net +mail-archive.com +maildns.xyz +maiplus.com +maizhong.org +makemymood.com +makkahnewspaper.com +makzhou.warehouse333.com +malaysiakini.com +mamingzhe.com +manchukuo.net +mangafox.com +mangafox.me +maniash.com +manicur4ik.ru +mansion.com +mansionpoker.com +manta.com +maplew.com +marc.info +marguerite.su +martau.com +martincartoons.com +martsangkagyuofficial.org +maruta.be +marxist.com +marxist.net +marxists.org +mash.to +maskedip.com +mastodon.host +matainja.com +material.io +mathable.io +mathiew-badimon.com +matome-plus.com +matome-plus.net +matsushimakaede.com +mattwilcox.net +maturejp.com +maxing.jp +mayimayi.com +mcadforums.com +mcaf.ee +mcfog.com +mcreasite.com +md-t.org +me.youthwant.com.tw +meansys.com +media.nu.nl +media.org.hk +mediachinese.com +mediafire.com +mediafreakcity.com +medium.com +meetav.com +meetup.com +mefeedia.com +mefound.com +mega.nz +megaproxy.com +megarotic.com +megavideo.com +megurineluka.com +meirixiaochao.com +meltoday.com +meme.yahoo.com +memehk.com +memorybbs.com +memri.org +memrijttm.org +mercyprophet.org +meridian-trust.org +meripet.biz +meripet.com +merit-times.com.tw +meshrep.com +mesotw.com +messenger.com +metacafe.com +metarthunter.com +meteorshowersonline.com +metrohk.com.hk +metrolife.ca +metroradio.com.hk +meyou.jp +meyul.com +mfxmedia.com +mgoon.com +mgstage.com +mh4u.org +mhradio.org +michaelanti.com +michaelmarketl.com +microvpn.com +middle-way.net +mihk.hk +mihr.com +mihua.org +mike.cz.cc +mikesoltys.com +milph.net +milsurps.com +mimiai.net +mimivip.com +mimivv.com +mindrolling.org +minghui-a.org +minghui-b.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 +mingpaotor.com +mingpaovan.com +mingshengbao.com +minhhue.net +miniforum.org +ministrybooks.org +minzhuhua.net +minzhuzhanxian.com +minzhuzhongguo.org +miroguide.com +mirrorbooks.com +mist.vip +mitao.com.tw +mitbbs.com +mitbbsau.com +mixero.com +mixpod.com +mixx.com +mizzmona.com +mjib.gov.tw +mjlsh.usc.cuhk.edu.hk +mk5000.com +mlcool.com +mlzs.work +mm-cg.com +mmaaxx.com +mmmca.com +mnewstv.com +mo.nightlife141.com +mobatek.net +mobile01.com +mobileways.de +moby.to +mobypicture.com +moeaic.gov.tw +moeerolibrary.com +mofa.gov.tw +mofaxiehui.com +mofos.com +mog.com +mohu.club +mohu.ml +mol.gov.tw +molihua.org +mondex.org +money-link.com.tw +moneyhome.biz +monitorchina.org +monster.com +moodyz.com +moonbbs.com +moonbingo.com +morningsun.org +moroneta.com +mos.ru +motherless.com +motiyun.com +motor4ik.ru +mousebreaker.com +movements.org +moviefap.com +mp3buscador.com +mp3ye.eu +mpettis.com +mpfinance.com +mpinews.com +mponline.hk +mqxd.org +mrbasic.com +mrbonus.com +mrface.com +mrslove.com +mrtweet.com +msa-it.org +msguancha.com +msha.gov +mswe1.org +mthruf.com +mtw.tl +muchosucko.com +mullvad.net +multiply.com +multiproxy.org +multiupload.com +mummysgold.com +murmur.tw +musicade.net +muslimvideo.com +muzi.com +muzi.net +muzu.tv +mvdis.gov.tw +mvg.jp +mx.hao123.com +mx981.com +my-formosa.com +my-private-network.co.uk +my-proxy.com +my.mail.ru +my.opera.com +my.pcloud.com +my03.com +myactimes.com +myanniu.com +myaudiocast.com +myav.com.tw +mybbs.us +mybet.com +myca168.com +mycanadanow.com +mychinamyhome.com +mychinanet.com +mychinanews.com +mychinese.news +mycnnews.com +mycould.com +mydad.info +myddns.com +myeasytv.com +myeclipseide.com +myforum.com.hk +myforum.com.uk +myfreecams.com +myfreepaysite.com +myfreshnet.com +myftp.info +myftp.name +myiphide.com +mykomica.org +mylftv.com +mymediarom.com +mymoe.moe +mymom.info +mymusic.net.tw +mynetav.net +mynetav.org +mynumber.org +myparagliding.com +mypicture.info +mypop3.net +mypop3.org +mypopescu.com +myradio.hk +myreadingmanga.info +mysecondarydns.com +myshare.url.com.tw +mysinablog.com +mysite.verizon.net +myspace.com +myspacecdn.com +mytalkbox.com +mytizi.com +mywww.biz +myz.info +naacoalition.org +naitik.net +nakido.com +nakuz.com +nalandabodhi.org +nalandawest.org +namgyal.org +namgyalmonastery.org +namsisi.com +nanyang.com +nanyangpost.com +nanzao.com +naol.ca +naol.cc +nat.gov.tw +nat.moe +national-lottery.co.uk +nationsonline.org +nationwide.com +naughtyamerica.com +navyfamily.navy.mil +navyreserve.navy.mil +naweeklytimes.com +nbtvpn.com +nccwatch.org.tw +nch.com.tw +ncn.org +nde.de +ndr.de +ned.org +nekoslovakia.net +nemesis2.qx.net +neo-miracle.com +nepusoku.com +net-fits.pro +netbirds.com +netcolony.com +netflix.com +netme.cc +netsneak.com +network54.com +networkedblogs.com +networktunnel.net +neverforget8964.org +new-3lunch.net +new-akiba.com +new96.ca +newcenturymc.com +newcenturynews.com +newchen.com +newgrounds.com +newipnow.com +newlandmagazine.com.au +newnews.ca +news.cnyes.com +news.hk.msn.com +news.hkpeanut.com +news.msn.com.tw +news.nationalgeographic.com +news.now.com +news.omy.sg +news.seehua.com +news.sina.com.hk +news.sina.com.tw +news.sinchew.com.my +news.singtao.ca +news.tvb.com +news.tvbs.com.tw +news.yahoo.com +news100.com.tw +newsancai.com +newschinacomment.org +newscn.org +newsdetox.ca +newsdh.com +newspeak.cc +newstamago.com +newstapa.org +newstarnet.com +newtaiwan.com.tw +newtalk.tw +newyorktimes.com +nexon.com +next11.co.jp +nextmag.com.tw +nextmedia.com +nexton-net.jp +nexttv.com.tw +nf.id.au +nfjtyd.com +nflxext.com +nflximg.com +nflximg.net +nflxso.net +nflxvideo.net +nga.mil +ngensis.com +nhentai.net +nhi.gov.tw +nhk-ondemand.jp +nic.cz.cc +nic.google +nic.gov +nicovideo.jp +nighost.org +nikkei.com +ninecommentaries.com +ninjacloak.com +ninjaproxy.ninja +nintendium.com +ninth.biz +niusnews.com +njactb.org +njuice.com +nko.navy.mil +nlfreevpn.com +no-ip.org +nobel.se +nobelprize.org +nobodycanstop.us +nofile.io +nokogiri.org +nokola.com +noodlevpn.com +norbulingka.org +nordstrom.com +nordstromimage.com +nordstromrack.com +nordvpn.com +notify.dropboxapi.com +nottinghampost.com +novelasia.com +now.com +now.im +nownews.com +nowtorrents.com +noypf.com +npa.go.jp +npa.gov.tw +npnt.me +nps.gov +nradio.me +nrk.no +ns01.biz +ns01.info +ns01.us +ns02.biz +ns02.info +ns02.us +ns1.name +ns2.name +ns3.name +nsc.gov.tw +ntbk.gov.tw +ntbna.gov.tw +ntbt.gov.tw +ntd.tv +ntdtv.ca +ntdtv.co.kr +ntdtv.com +ntdtv.cz +ntdtv.org +ntdtv.ru +ntdtvla.com +ntrfun.com +ntsna.gov.tw +nubiles.net +nuexpo.com +nukistream.com +nurgo-software.com +nusatrip.com +nutaku.net +nuuvem.com +nuvid.com +nuzcom.com +nvdst.com +nvquan.org +nvtongzhisheng.org +nwtca.org +ny.stgloballink.com +ny.visiontimes.com +nyaa.eu +nydus.ca +nylon-angel.com +nylonstockingsonline.com +nyt.com +nytchina.com +nytcn.me +nytco.com +nyti.ms +nytimes.com +nytimes.map.fastly.net +nytimg.com +nytstyle.com +nzchinese.com +nzchinese.net.nz +observechina.net +obutu.com +ocaspro.com +occupytiananmen.com +oclp.hk +ocreampies.com +ocry.com +october-review.org +oculus.com +oculuscdn.com +oex.com +offbeatchina.com +officeoftibet.com +ofile.org +ogaoga.org +ogate.org +oikos.com.tw +oiktv.com +oizoblog.com +ok.ru +okayfreedom.com +okex.com +okk.tw +old-cat.net +old.honeynet.org +old.nabble.com +olumpo.com +olympicwatch.org +omgili.com +omni7.jp +omnitalk.com +omnitalk.org +on.cc +on2.com +onapp.com +onedrive.live.com +onedumb.com +onejav.com +onion.city +online.recoveryversion.org +onlinecha.com +onlineyoutube.com +onlytweets.com +onmoon.com +onmoon.net +onmypc.biz +onmypc.info +onmypc.net +onmypc.org +onmypc.us +onthehunt.com +ontrac.com +oopsforum.com +open.com.hk +openallweb.com +opendemocracy.net +opendn.xyz +openervpn.in +openid.net +openleaks.org +openvpn.net +openwebster.com +openwrt.org.cn +opml.radiotime.com +opus-gaming.com +organcare.org.tw +organharvestinvestigation.net +organiccrap.com +orgasm.com +orgfree.com +orient-doll.com +orientaldaily.com.my +orn.jp +orzistic.org +osfoora.com +otcbtc.com +otnd.org +otto.de +otzo.com +ourdearamy.com +ourhobby.com +oursogo.com +oursteps.com.au +oursweb.net +ourtv.hk +overplay.net +oversea.istarshine.com +ow.ly +owl.li +oyax.com +oyghan.com +ozchinese.com +ozvoice.org +ozxw.com +ozyoyo.com +pachosting.com +pacificpoker.com +packages.debian.org +packetix.net +pacopacomama.com +padmanet.com +page.bid.yahoo.com +page2rss.com +pagodabox.com +palacemoon.com +paldengyal.com +paljorpublications.com +paltalk.com +panamapapers.sueddeutsche.de +pandapow.co +pandapow.net +pandavpn-jp.com +pandora.com +pandora.tv +panluan.net +panoramio.com +pao-pao.net +paper.li +paperb.us +paradisehill.cc +paradisepoker.com +parkansky.com +partycasino.com +partypoker.com +passion.com +passiontimes.hk +paste.ee +pastebin.com +pastie.org +pbs.org +pbwiki.com +pbworks.com +pbxes.com +pbxes.org +pcanywhere.net +pcc.gov.tw +pcdvd.com.tw +pchome.com.tw +pcij.org +pcstore.com.tw +pct.org.tw +pdetails.com +pdproxy.com +pds.nasa.gov +peace.ca +peacefire.org +peacehall.com +pearlher.org +peeasian.com +pekingduck.org +pemulihan.or.id +pen.io +penchinese.com +penchinese.net +pengyulong.com +penisbot.com +penthouse.com +pentoy.hk +peoplebookcafe.com +peoplenews.tw +peopo.org +percy.in +perfectgirls.net +perfectvpn.net +periscope.tv +persecutionblog.com +persiankitty.com +pfd.org.hk +phapluan.org +phayul.com +philborges.com +philly.com +phmsociety.org +phncdn.com +phobos.apple.com +phosphation13.rssing.com +photodharma.net +photofocus.com +phuquocservices.com +picacomic.com +picacomiccn.com +picasaweb.com +picidae.net +picturedip.com +pictures.playboy.com +picturesocial.com +pimg.tw +pin-cong.com +pin6.com +ping.fm +pinimg.com +pinkrod.com +pinoy-n.com +pinterest.at +pinterest.co.kr +pinterest.co.uk +pinterest.com +pinterest.de +pinterest.dk +pinterest.fr +pinterest.jp +pinterest.nl +pinterest.se +pioneer-worker.forums-free.com +pipii.tv +piposay.com +piraattilahti.org +piring.com +pixelqi.com +pixiv.net +pixnet.net +pk.com +pki.goog +placemix.com +playboy.com +playboyplus.com +player.fm +playno1.com +playpcesor.com +plays.com.tw +plm.org.hk +plunder.com +plurk.com +plus28.com +plusbb.com +pmatehunter.com +pmates.com +po2b.com +pobieramy.top +podictionary.com +pokerstars.com +pokerstars.net +politicalchina.org +politicalconsultation.org +politiscales.net +poloniex.com +polymer-project.org +polymerhk.com +popo.tw +popvote.hk +popyard.com +popyard.org +porn.com +porn2.com +porn5.com +pornbase.org +pornerbros.com +pornhd.com +pornhost.com +pornhub.com +pornhubdeutsch.net +pornmm.net +pornoxo.com +pornrapidshare.com +pornsharing.com +pornsocket.com +pornstarclub.com +porntube.com +porntubenews.com +porntvblog.com +pornvisit.com +port25.biz +portablevpn.nl +poskotanews.com +post01.com +post76.com +post852.com +postadult.com +postimg.org +potvpn.com +power.com +powerapple.com +powercx.com +powerphoto.org +prayforchina.net +premeforwindows7.com +premproxy.com +presentationzen.com +presidentlee.tw +prestige-av.com +pride.google +prisoneralert.com +pritunl.com +privacybox.de +private.com +privateinternetaccess.com +privatepaste.com +privatetunnel.com +privatevpn.com +procopytips.com +prosiben.de +protonvpn.com +provideocoalition.com +provpnaccounts.com +proxfree.com +proxifier.com +proxomitron.info +proxpn.com +proxyanonimo.es +proxydns.com +proxylist.org.uk +proxynetwork.org.uk +proxypy.net +proxyroad.com +proxytunnel.net +proyectoclubes.com +prozz.net +psblog.name +pscp.tv +psiphon.ca +psiphon.civisec.org +psiphon3.com +psiphontoday.com +pts.org.tw +ptt.cc +pttvan.org +pubu.com.tw +puffinbrowser.com +puffstore.com +pullfolio.com +pulse.yahoo.com +punyu.com +pure18.com +pureconcepts.net +pureinsight.org +purepdf.com +purevpn.com +purplelotus.org +pursuestar.com +pushchinawall.com +pussyspace.com +putihome.org +putlocker.com +putty.org +puuko.com +pwned.com +python.com +python.com.tw +pythonhackers.com +pytorch.org +qanote.com +qgirl.com.tw +qhigh.com +qi-gong.me +qiandao.today +qiangyou.org +qidian.ca +qienkuen.org +qiwen.lu +qixianglu.cn +qkshare.com +qoos.com +qpoe.com +qq.co.za +qstatus.com +qtrac.eu +qtweeter.com +quannengshen.org +quantumbooter.net +questvisual.com +quitccp.net +quitccp.org +quora.com +quran.com +quranexplorer.com +qusi8.net +qvodzy.org +qxbbs.org +r18.com +ra.gg +radicalparty.org +radiko.jp +radioaustralia.net.au +radiohilight.net +radiovaticana.org +radiovncr.com +rael.org +raggedbanner.com +raidcall.com.tw +raidtalk.com.tw +rainbowplan.org +raindrop.io +raizoji.or.jp +ramcity.com.au +rangwang.biz +rangzen.com +rangzen.net +rangzen.org +ranyunfei.com +rapbull.net +rapidgator.net +rapidmoviez.com +rapidvpn.com +raremovie.cc +raremovie.net +raw.githubusercontent.com +rawgit.com +rawgithub.com +razyboard.com +rcam.target.com +rcinet.ca +rconversation.blogs.com +rd.com +rdio.com +read01.com +read100.com +readingtimes.com.tw +readmoo.com +readydown.com +realcourage.org +realforum.zkiz.com +realitykings.com +realraptalk.com +realsexpass.com +rebatesrule.net +recordhistory.org +recovery.org.tw +recoveryversion.com.tw +red-lang.org +redballoonsolidarity.org +redchinacn.net +redchinacn.org +redd.it +reddit.com +redditmedia.com +redditstatic.com +redhotlabs.com +redtube.com +referer.us +reflectivecode.com +registry.google +relaxbbs.com +relay.com.tw +releaseinternational.org +religioustolerance.org +renminbao.com +renyurenquan.org +research.jmsc.hku.hk +resilio.com +retweeteffect.com +retweetist.com +retweetrank.com +reuters.com +reutersmedia.net +revleft.com +revver.com +rfa.org +rfachina.com +rfalive1.akacast.akamaistream.net +rfamobile.org +rfaweb.org +rferl.org +rfi.fr +rfi.my +rightbtc.com +rigpa.org +riku.me +rileyguide.com +riseup.net +ritouki.jp +ritter.vg +rixcloud.com +rixcloud.us +rlwlw.com +rmjdw.com +rmjdw132.info +roadshow.hk +roboforex.com +robustnessiskey.com +rocket-inc.net +rocksdb.org +rojo.com +rolia.net +ronjoneswriter.com +roodo.com +rosechina.net +rotten.com +rsdlmonitor.com +rsf-chinese.org +rsf.org +rsgamen.org +rssmeme.com +rtalabel.org +rthk.hk +rthk.org.hk +rthklive2-lh.akamaihd.net +rti.org.tw +rtycminnesota.org +ruanyifeng.com +rukor.org +runbtx.com +rushbee.com +ruten.com.tw +rutube.ru +ruyiseek.com +rxhj.net +s-cute.com +s-dragon.org +s1.nudezz.com +s1heng.com +s1s1s1.com +s3-ap-northeast-1.amazonaws.com +s3-ap-southeast-2.amazonaws.com +s3.amazonaws.com +s8forum.com +sa.hao123.com +sacks.com +sacom.hk +sadistic-v.com +sadpanda.us +safervpn.com +safety.google +saintyculture.com +saiq.me +sakuralive.com +sakya.org +salvation.org.hk +samair.ru +sambhota.org +sanmin.com.tw +sapikachu.net +saveliuxiaobo.com +savemedia.com +savethedate.foo +savetibet.de +savetibet.fr +savetibet.nl +savetibet.org +savetibet.ru +savetibetstore.org +savevid.com +say2.info +sbme.me +sbs.com.au +scache.vzw.com +scache1.vzw.com +scache2.vzw.com +scasino.com +schema.org +sciencenets.com +scieron.com +scmp.com +scmpchinese.com +scramble.io +scribd.com +scriptspot.com +seapuff.com +search.aol.com +search.disconnect.me +search.xxx +search.yahoo.co.jp +searchtruth.com +secretchina.com +secretgarden.no +secretsline.biz +secure.hustler.com +secure.logmein.com +secure.raxcdn.com +securetunnel.com +securityinabox.org +securitykiss.com +seed4.me +seesmic.com +seevpn.com +seezone.net +sejie.com +sellclassics.com +sendsmtp.com +sendspace.com +servehttp.com +serveuser.com +serveusers.com +services.googleapis.cn +services.googleapis.com +sesawe.net +sesawe.org +sethwklein.net +setn.com +settv.com.tw +sevenload.com +sex-11.com +sex.com +sex3.com +sex8.cc +sexandsubmission.com +sexbot.com +sexhu.com +sexhuang.com +sexidude.com +sexinsex.net +sextvx.com +sexxxy.biz +sf.net +sfileydy.com +sfshibao.com +sftindia.org +sftuk.org +shadeyouvpn.com +shadow.ma +shadowsky.xyz +shadowsocks-r.com +shadowsocks.asia +shadowsocks.be +shadowsocks.com +shadowsocks.com.hk +shadowsocks.org +shadowsocks9.com +shambalapost.com +shambhalasun.com +shangfang.org +shapeservices.com +share.dmhy.org +share.ovi.com +share.youthwant.com.tw +sharebee.com +sharecool.org +sharpdaily.com.hk +sharpdaily.hk +sharpdaily.tw +shat-tibet.com +shattered.io +sheikyermami.com +shellfire.de +shenshou.org +shenyun.com +shenyunperformingarts.org +shenzhoufilm.com +sherabgyaltsen.com +shiatv.net +shicheng.org +shiksha.com +shinychan.com +shipcamouflage.com +shireyishunjian.com +shitaotv.org +shixiao.org +shizhao.org +shkspr.mobi +shodanhq.com +shooshtime.com +shop2000.com.tw +shopping.com +showbiz.omy.sg +showhaotu.com +showtime.jp +shutterstock.com +shwchurch.org +shwchurch3.com +siddharthasintent.org +sidelinesnews.com +sidelinessportseatery.com +sierrafriendsoftibet.org +sijihuisuo.club +sijihuisuo.com +sikaozhe1997.github.io +silkbook.com +simbolostwitter.com +simplecd.org +simpleproductivityblog.com +sinchew.com.my +singaporepools.com.sg +singfortibet.com +singpao.com.hk +singtao.com +singtaousa.com +sino-monthly.com +sinoants.com +sinocast.com +sinocism.com +sinomontreal.ca +sinonet.ca +sinopitt.info +sinoquebec.com +sipml5.org +sis.xxx +sis001.com +sis001.us +site2unblock.com +site90.net +sitebro.tw +sitekreator.com +siteks.uk.to +sitemaps.org +sixth.biz +sjrt.org +sjum.cn +sketchappsources.com +skimtube.com +skybet.com +skyking.com.tw +skyvegas.com +skyxvpn.com +slacker.com +slaytizle.com +sleazydream.com +slheng.com +slickvpn.com +slideshare.net +slinkset.com +slutload.com +slutmoonbeam.com +slyip.com +slyip.net +sm-miracle.com +smartdnsproxy.com +smarthide.com +smchbooks.com +smh.com.au +smhric.org +smith.edu +smyxy.org +snapchat.com +snaptu.com +sndcdn.com +sneakme.net +snowlionpub.com +sobees.com +soc.mil +socialwhale.com +socks-proxy.net +sockscap64.com +sockslist.net +socrec.org +sod.co.jp +sodatea.github.io +softether-download.com +softether.co.jp +softether.org +softwarebychuck.com +softwaredownload.gitbooks.io +sogclub.com +sogrady.me +soh.tw +sohcradio.com +sohfrance.org +sokamonline.com +sokmil.com +solarsystem.nasa.gov +solidaritetibet.org +solidfiles.com +somee.com +songjianjun.com +sonicbbs.cc +sonidodelaesperanza.org +sopcast.com +sopcast.org +sorazone.net +sorting-algorithms.com +sos.org +sosreader.com +sostibet.org +soubory.com +soul-plus.net +soulcaliburhentai.net +soumo.info +soundcloud.com +soundofhope.kr +soundofhope.org +soup.io +soupofmedia.com +sourceforge.net +sourcewadio.com +southnews.com.tw +sowers.org.hk +soylentnews.org +spankbang.com +spankingtube.com +spankwire.com +spb.com +speakerdeck.com +specxinzl.jigsy.com +speedify.com +spem.at +spencertipping.com +spendee.com +spicevpn.com +spideroak.com +spike.com +sports.williamhill.com +spotflux.com +spotify.com +spreadshirt.es +spring4u.info +springboardplatform.com +sprite.org +sproutcore.com +sproxy.info +squirly.info +srcf.ucam.org +srocket.us +ss-link.com +ss.carryzhou.com +ss.levyhsu.com +ss.pythonic.life +ss7.vzw.com +ssglobal.co +ssglobal.me +ssh91.com +ssl.webpack.de +ssl443.org +sspanel.net +sspro.ml +ssr.tools +ssrshare.com +sss.camp +sstmlt.moe +sstmlt.net +stackoverflow.com +stage64.hk +standupfortibet.org +stanford.edu +starfishfx.com +starp2p.com +startpage.com +startuplivingchina.com +stat.gov.tw +static-economist.com +static.comico.tw +static.shemalez.com +static01.nyt.com +staticflickr.com +statueofdemocracy.org +stc.com.sa +steamcommunity.com +steel-storm.com +steganos.com +steganos.net +stepchina.com +stephaniered.com +sthoo.com +stickam.com +stickeraction.com +stileproject.com +sto.cc +stoporganharvesting.org +stoptibetcrisis.net +storagenewsletter.com +store.steampowered.com +stories.google +storify.com +storm.mg +stormmediagroup.com +stoweboyd.com +stranabg.com +straplessdildo.com +streamingthe.net +streema.com +strikingly.com +strongvpn.com +strongwindpress.com +student.tw +studentsforafreetibet.org +stumbleupon.com +stupidvideos.com +subacme.rerouted.org +successfn.com +sugarsync.com +sugobbs.com +sugumiru18.com +suissl.com +sujiatun.wordpress.com +sukebei.nyaa.si +sulian.me +summify.com +sumrando.com +sun1911.com +sunmedia.ca +sunporno.com +sunskyforum.com +sunta.com.tw +sunvpn.net +sunwinism.joinbbs.net +suoluo.org +supchina.com +superfreevpn.com +superokayama.com +superpages.com +supervpn.net +superzooi.com +suppig.net +suprememastertv.com +surfeasy.com +surfeasy.com.au +suroot.com +surrenderat20.net +sustainability.google +suyangg.com +svsfx.com +swagbucks.com +swissvpn.net +switch1.jp +switchvpn.net +sydneytoday.com +sylfoundation.org +syncback.com +synergyse.com +sysresccd.org +sytes.net +szbbs.net +szetowah.org.hk +t-g.com +t.co +t.me +t.orzdream.com +t35.com +t66y.com +taa-usa.org +taaze.tw +tabtter.jp +tacc.cwb.gov.tw +tacem.org +taconet.com.tw +taedp.org.tw +tafm.org +tagwa.org.au +tagwalk.com +tahr.org.tw +taipei.gov.tw +taipeisociety.org +taiwan-sex.com +taiwanbible.com +taiwancon.com +taiwandaily.net +taiwandc.org +taiwanjobs.gov.tw +taiwanjustice.com +taiwanjustice.net +taiwankiss.com +taiwannation.50webs.com +taiwannation.com +taiwannation.com.tw +taiwanncf.org.tw +taiwannews.com.tw +taiwantp.net +taiwantt.org.tw +taiwanus.net +taiwanyes.com +taiwanyes.ning.com +talk853.com +talkboxapp.com +talkonly.net +tamiaode.tk +tanc.org +tangben.com +tangren.us +taoism.net +taolun.info +tapanwap.com +tapatalk.com +tarr.uspto.gov +tascn.com.au +taup.net +taweet.com +tbcollege.org +tbi.org.hk +tbicn.org +tbjyt.org +tbpic.info +tbrc.org +tbs-rainbow.org +tbsec.org +tbskkinabalu.page.tl +tbsmalaysia.org +tbsn.org +tbsseattle.org +tbssqh.org +tbswd.org +tbtemple.org.uk +tbthouston.org +tccwonline.org +tcewf.org +tchrd.org +tcnynj.org +tcpspeed.co +tcpspeed.com +tcsofbc.org +tcsovi.org +tdm.com.mo +teachparentstech.org +teamamericany.com +tech2.in.com +techviz.net +teck.in +teco-hk.org +teco-mo.org +teddysun.com +teeniefuck.net +teensinasia.com +telecomspace.com +telegram.dog +telegram.me +telegram.org +telegramdownload.com +telegraph.co.uk +telesco.pe +tellme.pw +tenacy.com +tensorflow.org +tenzinpalmo.com +terminus2049.github.io +tew.org +textnow.me +th.hao123.com +thaicn.com +thb.gov.tw +theatrum-belli.com +thebcomplex.com +theblemish.com +thebobs.com +thebodyshop-usa.com +thecenter.mit.edu +thechinabeat.org +thedalailamamovie.com +thedw.us +thefacebook.com +thefrontier.hk +thegioitinhoc.vn +thegly.com +thehots.info +thehousenews.com +thehun.net +theinitium.com +thenewslens.com +thepiratebay.org +theportalwiki.com +thereallove.kr +therock.net.nz +thespeeder.com +thestandnews.com +thetibetcenter.org +thetibetconnection.org +thetibetmuseum.org +thetibetpost.com +thetinhat.com +thetrotskymovie.com +thevivekspot.com +thewgo.org +theync.com +thinkingtaiwan.com +thinkwithgoogle.com +thisav.com +thlib.org +thomasbernhard.org +thongdreams.com +threatchaos.com +throughnightsfire.com +thumbzilla.com +thywords.com +thywords.com.tw +tiananmenduizhi.com +tiananmenmother.org +tiananmenuniv.com +tiananmenuniv.net +tiandixing.org +tianhuayuan.com +tianlawoffice.com +tianti.io +tiantibooks.org +tianyantong.org.cn +tianzhu.org +tibet-envoy.eu +tibet-foundation.org +tibet-house-trust.co.uk +tibet-info.net +tibet-initiative.de +tibet-munich.de +tibet.a.se +tibet.at +tibet.ca +tibet.com +tibet.fr +tibet.net +tibet.nu +tibet.org +tibet.org.tw +tibet.sk +tibet.to +tibet3rdpole.org +tibetaction.net +tibetaid.org +tibetalk.com +tibetan-alliance.org +tibetan.fr +tibetanaidproject.org +tibetanarts.org +tibetanbuddhistinstitute.org +tibetancommunity.org +tibetancommunityuk.net +tibetanculture.org +tibetanfeministcollective.org +tibetanjournal.com +tibetanlanguage.org +tibetanliberation.org +tibetanpaintings.com +tibetanphotoproject.com +tibetanpoliticalreview.org +tibetanreview.net +tibetansports.org +tibetanwomen.org +tibetanyouth.org +tibetanyouthcongress.org +tibetcharity.dk +tibetcharity.in +tibetchild.org +tibetcity.com +tibetcollection.com +tibetcorps.org +tibetexpress.net +tibetfocus.com +tibetfund.org +tibetgermany.com +tibetgermany.de +tibethaus.com +tibetheritagefund.org +tibethouse.jp +tibethouse.org +tibethouse.us +tibetinfonet.net +tibetjustice.org +tibetkomite.dk +tibetlibre.free.fr +tibetmuseum.org +tibetnetwork.org +tibetoffice.ch +tibetoffice.com.au +tibetoffice.eu +tibetoffice.org +tibetonline.com +tibetonline.tv +tibetoralhistory.org +tibetpolicy.eu +tibetrelieffund.co.uk +tibetsites.com +tibetsociety.com +tibetsun.com +tibetsupportgroup.org +tibetswiss.ch +tibettelegraph.com +tibettimes.net +tibetwrites.org +ticket.com.tw +tigervpn.com +tiltbrush.com +timdir.com +time.com +times.hinet.net +timesofindia.indiatimes.com +timsah.com +tineye.com +tintuc101.com +tiny.cc +tinychat.com +tinypaste.com +tipo.gov.tw +tistory.com +tkcs-collins.com +tl.gd +tma.co.jp +tmagazine.com +tmdfish.com +tmi.me +tmpp.org +tn1.shemalez.com +tn2.shemalez.com +tn3.shemalez.com +tnaflix.com +tngrnow.com +tngrnow.net +tnp.org +to-porno.com +togetter.com +toh.info +tokyo-247.com +tokyo-hot.com +tokyo-porn-tube.com +tokyocn.com +tongil.or.kr +tono-oka.jp +tonyyan.net +toodoc.com +toonel.net +top.tv +top81.ws +topbtc.com +topic.youthwant.com.tw +topnews.in +toppornsites.com +topshareware.com +topsy.com +toptip.ca +tor.blingblingsquad.net +tor.cn.uptodown.com +tor.updatestar.com +tora.to +torcn.com +torguard.net +torproject.org +torrentprivacy.com +torrentproject.se +torrenty.org +torrentz.eu +torvpn.com +tosh.comedycentral.com +totalvpn.com +toutiaoabc.com +towngain.com +toypark.in +toythieves.com +toytractorshow.com +tparents.org +tpi.org.tw +tracfone.com +traffichaus.com +trans.wenweipo.com +transparency.org +treemall.com.tw +trendsmap.com +trialofccp.org +trickip.net +trickip.org +trimondi.de +trouw.nl +trt.net.tr +trtc.com.tw +truebuddha-md.org +trulyergonomic.com +truth101.co.tv +truthontour.org +truveo.com +tryheart.jp +tsctv.net +tsdr.uspto.gov +tsemtulku.com +tsquare.tv +tsu.org.tw +tsunagarumon.com +tt-rss.org +tt1069.com +tttan.com +ttvnw.net +tu8964.com +tubaholic.com +tube.com +tube8.com +tube911.com +tubecup.com +tubegals.com +tubeislam.com +tubepornclassic.com +tubestack.com +tubewolf.com +tui.orzdream.com +tuibeitu.net +tuidang.net +tuidang.org +tuidang.se +tuitwit.com +tumblr.com +tumutanzi.com +tumview.com +tunein.com +tunnelbear.com +tunnelr.com +tuo8.blue +tuo8.cc +tuo8.club +tuo8.fit +tuo8.hk +tuo8.in +tuo8.ninja +tuo8.org +tuo8.pw +tuo8.red +tuo8.space +turansam.org +turbobit.net +turbohide.com +turbotwitter.com +turntable.fm +tushycash.com +tuvpn.com +tuzaijidi.com +tv.com +tvants.com +tvboxnow.com +tvider.com +tvmost.com.hk +tvplayvideos.com +tvunetworks.com +tw-blog.com +tw-npo.org +tw.answers.yahoo.com +tw.bid.yahoo.com +tw.gigacircle.com +tw.hao123.com +tw.jiepang.com +tw.knowledge.yahoo.com +tw.mall.yahoo.com +tw.mobi.yahoo.com +tw.money.yahoo.com +tw.myblog.yahoo.com +tw.news.yahoo.com +tw.streetvoice.com +tw.tomonews.net +tw.voa.mobi +tw.yahoo.com +tw01.org +twaitter.com +twapperkeeper.com +twaud.io +twavi.com +twbbs.net.tw +twbbs.org +twbbs.tw +twblogger.com +tweepguide.com +tweeplike.me +tweepmag.com +tweepml.org +tweetbackup.com +tweetboard.com +tweetboner.biz +tweetcs.com +tweetdeck.com +tweetedtimes.com +tweetmylast.fm +tweetphoto.com +tweetrans.com +tweetree.com +tweets.seraph.me +tweettunnel.com +tweetwally.com +tweetymail.com +tweez.net +twelve.today +twerkingbutt.com +twftp.org +twgreatdaily.com +twibase.com +twibble.de +twibbon.com +twibs.com +twicountry.org +twicsy.com +twiends.com +twifan.com +twiffo.com +twiggit.org +twilightsex.com +twilog.org +twimbow.com +twimg.com +twimg.edgesuite.net +twindexx.com +twip.me +twipple.jp +twishort.com +twistar.cc +twister.net.co +twisterio.com +twisternow.com +twistory.net +twit2d.com +twitbrowser.net +twitcause.com +twitch.tv +twitchcdn.net +twitgether.com +twitgoo.com +twitiq.com +twitlonger.com +twitmania.com +twitoaster.com +twitonmsn.com +twitpic.com +twitstat.com +twittbot.net +twitter.com +twitter.jp +twitter4j.org +twittercounter.com +twitterfeed.com +twittergadget.com +twitterkr.com +twittermail.com +twitterrific.com +twittertim.es +twitthat.com +twitturk.com +twitturly.com +twitvid.com +twitzap.com +twiyia.com +twnorth.org.tw +twskype.com +twstar.net +twt.tl +twtkr.com +twtr2src.ogaoga.org +twtrland.com +twttr.com +twurl.nl +twyac.org +txxx.com +tycool.com +typepad.com +u9un.com +ub0.cc +ubddns.org +uberproxy.net +uc-japan.org +ucdc1998.org +uchicago.edu +uderzo.it +udn.com +udn.com.tw +udnbkk.com +uforadio.com.tw +ufreevpn.com +ug.m.wikipedia.org +ugo.com +uhdwallpapers.org +uhrp.org +uighur.narod.ru +uighur.nl +uighurbiz.net +ukcdp.co.uk +ukliferadio.co.uk +uku.im +ulike.net +ulop.net +ultravpn.fr +ultraxs.com +umich.edu +unblock-us.com +unblock.cn.com +unblockdmm.com +unblocker.yt +unblocksit.es +uncyclomedia.org +uncyclopedia.hk +uncyclopedia.tw +underwoodammo.com +unholyknight.com +uni.cc +unification.net +unification.org.tw +unirule.cloud +unitedsocialpress.com +unix100.com +unknownspace.org +unodedos.com +unpo.org +unseen.is +untraceable.us +uocn.org +upcoming.yahoo.com +updates.tdesktop.com +upholdjustice.org +upload4u.info +uploaded.net +uploaded.to +uploadstation.com +upmedia.mg +upornia.com +uproxy.org +upwill.org +ur7s.com +uraban.me +urbansurvival.com +urchin.com +urlborg.com +urlparser.com +us.to +usacn.com +usaip.eu +userapi.nytlog.com +users.skynet.be +usfk.mil +ushuarencity.echainhost.com +usinfo.state.gov +usma.edu +usmc.mil +usmgtcg.ning.com +usno.navy.mil +usocctn.com +ustream.tv +usunitednews.com +usus.cc +utopianpal.com +uu-gg.com +uvwxyz.xyz +uwants.com +uwants.net +uyghur-j.org +uyghur.co.uk +uyghuramerican.org +uyghurcanadiansociety.org +uyghurcongress.org +uyghurensemble.co.uk +uyghurpen.org +uyghurpress.com +uyghurstudies.org +uygur.fc2web.com +uygur.org +uymaarip.com +v2ex.com +v2ray.com +van001.com +van698.com +vanemu.cn +vanilla-jp.com +vanpeople.com +vansky.com +vatn.org +vcf-online.org +vcfbuilder.org +vds.rightster.com +vegas.williamhill.com +vegasred.com +velkaepocha.sk +venbbs.com +venchina.com +venetianmacao.com +ventureswell.com +veoh.com +vermonttibet.org +versavpn.com +verybs.com +vevo.com +vft.com.tw +viber.com +vica.info +victimsofcommunism.org +vid.me +vidble.com +video.aol.ca +video.aol.co.uk +video.aol.com +video.ap.org +video.fdbox.com +video.foxbusiness.com +video.pbs.org +video.yahoo.com +videobam.com +videodetective.com +videomega.tv +videomo.com +videopediaworld.com +videopress.com +vidinfo.org +vietdaikynguyen.com +vijayatemple.org +vimeo.com +vimperator.org +vincnd.com +vine.co +vinniev.com +vip-enterprise.com +virtualrealporn.com +visibletweets.com +vital247.org +viu.com +viu.tv +vivahentai4u.net +vivatube.com +vivthomas.com +vizvaz.com +vjav.com +vjmedia.com.hk +vllcs.org +vlog.xuite.net +vmixcore.com +vmpsoft.com +vn.hao123.com +vnet.link +voa-11.akacast.akamaistream.net +voacantonese.com +voachinese.com +voachineseblog.com +voagd.com +voanews.com +voatibetan.com +voatibetanenglish.com +vocativ.com +vocn.tv +vod-abematv.akamaized.net +vod.wwe.com +vot.org +vovo2000.com +voxer.com +voy.com +vpn.ac +vpn.cjb.net +vpn.cmu.edu +vpn.sv.cmu.edu +vpn4all.com +vpnaccount.org +vpnaccounts.com +vpnbook.com +vpncomparison.org +vpncoupons.com +vpncup.com +vpndada.com +vpnfan.com +vpnfire.com +vpnfires.biz +vpnforgame.net +vpngate.jp +vpngate.net +vpngratis.net +vpnhq.com +vpninja.net +vpnintouch.com +vpnintouch.net +vpnjack.com +vpnmaster.com +vpnmentor.com +vpnpick.com +vpnpop.com +vpnpronet.com +vpnreactor.com +vpnreviewz.com +vpnsecure.me +vpnshazam.com +vpnshieldapp.com +vpnsp.com +vpntraffic.com +vpntunnel.com +vpnuk.info +vpnunlimitedapp.com +vpnvip.com +vpnworldwide.com +vporn.com +vpser.net +vraiesagesse.net +vrmtr.com +vrsmash.com +vtunnel.com +vuku.cc +w.idaiwan.com +w3schools.com +waffle1999.com +wahas.com +waigaobu.com +waikeung.org +wailaike.net +waiwaier.com +wallmama.com +wallornot.org +wallpapercasa.com +wallproxy.com +waltermartin.com +waltermartin.org +wanderinghorse.net +wangafu.net +wangjinbo.org +wanglixiong.com +wango.org +wangruoshui.net +want-daily.com +wanz-factory.com +wapedia.mobi +warbler.iconfactory.net +waselpro.com +washeng.net +watch8x.com +watchinese.com +watchmygf.net +wattpad.com +wav.tv +waveprotocol.org +waymo.com +wda.gov.tw +wdf5.com +wearehairy.com +wearn.com +web.dev +web2project.net +webbang.net +webevader.org +webfreer.com +webjb.org +weblagu.com +webmproject.org +webrtc.org +webrush.net +webs-tv.net +website.informer.com +websitepulse.com +webwarper.net +webworkerdaily.com +weekmag.info +wefightcensorship.org +wefong.com +wego.here.com +weiboleak.com +weiboscope.jmsc.hku.hk +weihuo.org +weijingsheng.org +weiming.info +weiquanwang.org +weisuo.ws +welovecock.com +wemigrate.org +wengewang.com +wengewang.org +wenhui.ch +wenxuecity.com +wenyunchao.com +wenzhao.ca +westca.com +westernshugdensociety.org +westernwolves.com +westkit.net +westpoint.edu +wetplace.com +wetpussygames.com +wexiaobo.org +wezhiyong.org +wezone.net +wforum.com +wha.la +whatblocked.com +whatbrowser.org +whatsapp.com +whatsapp.net +whatsonweibo.com +wheatseeds.org +wheelockslatin.com +whereiswerner.com +wheretowatch.com +whippedass.com +whitebear.freebearblog.org +whodns.xyz +whoer.net +whotalking.com +whylover.com +whyx.org +widevine.com +wikaba.com +wiki.cnitter.com +wiki.esu.im +wiki.gamerp.jp +wiki.jqueryui.com +wiki.keso.cn +wiki.moegirl.org +wiki.oauth.net +wiki.phonegap.com +wikileaks-forum.com +wikileaks.ch +wikileaks.com +wikileaks.de +wikileaks.eu +wikileaks.lu +wikileaks.org +wikileaks.pl +wikilivres.info +wikimapia.org +wikiwiki.jp +wildammo.com +williamhill.com +willw.net +windowsphoneme.com +windscribe.com +wingamestore.com +wingy.site +winning11.com +winwhispers.info +wire.com +wiredbytes.com +wiredpen.com +wisdompubs.org +wisevid.com +withgoogle.com +withyoutube.com +witnessleeteaching.com +witopia.net +wizcrafts.net +wjbk.org +wlcnew.jigsy.com +wlx.sowiki.net +wn.com +wnacg.com +wnacg.org +wo.tc +wo3ttt.wordpress.com +woeser.com +woesermiddle-way.net +wokar.org +wolfax.com +woolyss.com +woopie.jp +woopie.tv +wordpress.com +workatruna.com +workerdemo.org.hk +workerempowerment.org +workersthebig.net +worldcat.org +worldjournal.com +worldvpn.net +wow-life.net +wow.com +wowgirls.com +wowlegacy.ml +wowporn.com +wowrk.com +woxinghuiguo.com +woyaolian.org +wozy.in +wp.com +wpoforum.com +wqyd.org +wrchina.org +wretch.cc +writer.zoho.com +wsgzao.github.io +wsj.com +wsj.net +wsjhk.com +wtbn.org +wtfpeople.com +wuerkaixi.com +wufafangwen.com +wufi.org.tw +wuguoguang.com +wujie.net +wujieliulan.com +wukangrui.net +wuu.wikipedia.org +wuw.red +wuyanblog.com +wwitv.com +www.abclite.net +www.ajsands.com +www.americorps.gov +www.antd.org +www.aolnews.com +www.businessinsider.com.au +www.citizenlab.org +www.cmoinc.org +www.cool18.com +www.dmm.com +www.dwheeler.com +www.eastturkistan.net +www.ftchinese.com +www.gmiddle.com +www.gmiddle.net +www.hustlercash.com +www.idlcoyote.com +www.imdb.com +www.kindleren.com +www.klip.me +www.lamenhu.com +www.lib.virginia.edu +www.linksalpha.com +www.m-sport.co.uk +www.metro.taipei +www.monlamit.org +www.moztw.org +www.nbc.com +www.orchidbbs.com +www.owind.com +www.oxid.it +www.powerpointninja.com +www.s4miniarchive.com +www.sciencemag.org +www.shadowsocks.com +www.shwchurch.org +www.skype.com +www.tablesgenerator.com +www.taiwanonline.cc +www.taup.org.tw +www.thechinastory.org +www.wan-press.org +www.wangruowang.org +www.websnapr.com +www.zensur.freerk.com +www1.american.edu +www1.biz +www2.ohchr.org +www2.rocketbbs.com +wwwhost.biz +wzyboy.im +x-art.com +x-berry.com +x-wall.org +x.company +x1949x.com +x24hr.com +x365x.com +xa.yimg.com +xanga.com +xbabe.com +xbookcn.com +xbtce.com +xcafe.in +xcity.jp +xcritic.com +xda-developers.com +xerotica.com +xfinity.com +xfm.pp.ru +xgmyd.com +xhamster.com +xianba.net +xianchawang.net +xianjian.tw +xianqiao.net +xiaobaiwu.com +xiaochuncnjp.com +xiaod.in +xiaohexie.com +xiaolan.me +xiaoma.org +xiezhua.com +xihua.es +xijie.wordpress.com +xing.com +xinhuanet.org +xinmiao.com.hk +xinqimeng.over-blog.com +xinsheng.net +xinshijue.com +xinyubbs.net +xiongpian.com +xiuren.org +xizang-zhiye.org +xjp.cc +xjtravelguide.com +xkiwi.tk +xlfmtalk.com +xlfmwz.info +xm.com +xml-training-guide.com +xmovies.com +xn--4gq171p.com +xn--czq75pvv1aj5c.org +xn--i2ru8q2qg.com +xn--ngstr-lra8j.com +xn--oiq.cc +xn--p8j9a0d9c9a.xn--q9jyb4c +xnxx.com +xpdo.net +xpenology.com +xpud.org +xrentdvd.com +xskywalker.com +xskywalker.net +xtube.com +xuchao.net +xuchao.org +xuehua.us +xuzhiyong.net +xvideo.cc +xvideos.com +xvideos.es +xxbbx.com +xxlmovies.com +xxuz.com +xxx.com +xxx.xxx +xxxfuckmom.com +xxxx.com.au +xxxy.biz +xxxy.info +xxxymovies.com +xys.dxiong.com +xys.org +xysblogs.org +xyy69.com +xyy69.info +yahoo.com.hk +yakbutterblues.com +yam.com +yam.org.tw +yanghengjun.com +yangjianli.com +yasni.co.uk +yayabay.com +ydy.com +yeahteentube.com +yecl.net +yeelou.com +yeeyi.com +yegle.net +yes-news.com +yes.xxx +yes123.com.tw +yesasia.com +yesasia.com.hk +yespornplease.com +yeyeclub.com +ygto.com +yhcw.net +yibada.com +yibaochina.com +yidio.com +yilubbs.com +yingsuoss.com +yinlei.org +yipub.com +yizhihongxing.com +yobit.net +yobt.com +yobt.tv +yogichen.org +yolasite.com +yomiuri.co.jp +yong.hu +yorkbbs.ca +youdontcare.com +youjizz.com +youmaker.com +youngpornvideos.com +youngspiration.hk +youpai.org +youporn.com +youporngay.com +your-freedom.net +yourepeat.com +yourlisten.com +yourlust.com +yourprivatevpn.com +yourtrap.com +yousendit.com +youshun12.com +youthnetradio.org +youtu.be +youtube-nocookie.com +youtube.com +youtubecn.com +youtubeeducation.com +youtubegaming.com +youversion.com +youwin.com +youxu.info +yt.be +ytht.net +ytimg.com +ytn.co.kr +yuanming.net +yuanzhengtang.org +yulghun.com +yunchao.net +yuntipub.com +yuvutu.com +yvesgeleyn.com +ywpw.com +yx51.net +yyii.org +yzzk.com +zacebook.com +zalmos.com +zannel.com +zaobao.com +zaobao.com.sg +zaozon.com +zapto.org +zattoo.com +zb.com +zdnet.com.tw +zello.com +zengjinyan.org +zenmate.com +zenmate.com.ru +zeronet.io +zeutch.com +zfreet.com +zgsddh.com +zgzcjj.net +zh-yue.wikipedia.org +zh.bitterwinter.org +zh.ecdm.wikia.com +zh.m.wikipedia.org +zh.pokerstrategy.com +zh.pttpedia.wikia.com +zh.uncyclopedia.wikia.com +zh.wikinews.org +zh.wikipedia.org +zh.wikisource.org +zhanbin.net +zhangboli.net +zhangtianliang.com +zhanlve.org +zhao.1984.city +zhao.jinhai.de +zhenghui.org +zhengjian.org +zhengwunet.org +zhenlibu.info +zhenlibu1984.com +zhenxiang.biz +zhinengluyou.com +zhongguo.ca +zhongguorenquan.org +zhongguotese.net +zhongmeng.org +zhoushuguang.com +zhreader.com +zhuangbi.me +zhuanxing.cn +zhuatieba.com +zhuichaguoji.org +ziddu.com +zillionk.com +zim.vn +zinio.com +ziporn.com +zippyshare.com +zkaip.com +zmw.cn +zodgame.us +zomobo.net +zonaeuropa.com +zonghexinwen.com +zonghexinwen.net +zoogvpn.com +zootool.com +zoozle.net +zorrovpn.com +zozotown.com +zpn.im +zspeeder.me +zsrhao.com +zuo.la +zuobiao.me +zuola.com +zvereff.com +zynaima.com +zynamics.com +zyns.com +zyzc9.com +zzcartoon.com +zzcloud.me +zzux.com diff --git a/dnsforwarder/files/etc/init.d/dnsforwarder b/dnsforwarder/files/etc/init.d/dnsforwarder new file mode 100755 index 000000000..5cfceb8d4 --- /dev/null +++ b/dnsforwarder/files/etc/init.d/dnsforwarder @@ -0,0 +1,260 @@ +#!/bin/sh /etc/rc.common + +START=60 + +EXTRA_COMMANDS="makeconfig makegfwlist health" + +CRON_FILE=/etc/crontabs/root +PID_PATH=/var/run/dnsforwarder +PID_FILE=${PID_PATH}/dns.pid +DNSFORWARDER_CONF=/tmp/dnsforwarder.conf + +add_cron() +{ + sed -i '/dnsforwarder/d' $CRON_FILE + echo '*/5 * * * * /etc/init.d/dnsforwarder health' >> $CRON_FILE + echo '0 1 * * 0 /etc/init.d/dnsforwarder makegfwlist' >> $CRON_FILE + crontab $CRON_FILE +} + +del_cron() +{ + sed -i '/dnsforwarder/d' $CRON_FILE + /etc/init.d/cron restart +} + +fixturboacc(){ + dns=$(uci get turboacc.config.dns_caching 2>/dev/null) + if [ $dns -eq 1 ]; then + uci set turboacc.config.dns_caching=0 && uci commit turboacc + /etc/init.d/turboacc restart + fi +} + +makelist() { + [ -z "$2" ] && return + local i + local t="$1"; shift + for i in "$@" + do + echo "$t $i" + done +} + +health(){ + rm /var/log/dnsforwarder.log.* 2>/dev/null + local pid=$(cat ${PID_FILE} 2>/dev/null) + if [ -n "${pid}" -a -d /proc/$pid ]; then + echo "[health] process exists ${pid}" + else + echo "[health] Dnsforwarder is not running ${pid}" + start + fi +} + + +makegfwlist(){ + local GFW_FILE='/etc/dnsforwarder/gfw.txt' + local GFW_TMP_FILE='/tmp/dnsforwarder-gfw.old' + local TSTIME=`date '+%Y-%m-%d %H:%M:%S'` + touch ${GFW_TMP_FILE} + cat /etc/config/gfw.list 2>/dev/null > /tmp/edf.ts + cat /etc/dnsmasq.ssr/gfw_base.conf 2>/dev/null | awk -F '/' '{print $2}' | sed 's/^.//g' >> /tmp/edf.ts + cat /etc/dnsmasq.ssr/gfw_list.conf 2>/dev/null | awk -F '/' '{print $2}' | sed 's/^.//g' >> /tmp/edf.ts + sort /tmp/edf.ts | uniq > /tmp/edf.ts + /usr/share/dnsforwarder/gfwlist.sh -i -l -o /tmp/dnsforwarder-gfw.tmp --extra-domain-file /tmp/edf.ts + if [ $? != 0 ]; then + echo 'Failed to fetch gfwlist' + logger -t Failed to fetch gfwlist + return 2 + fi + local gfw=$(cat /tmp/dnsforwarder-gfw.tmp) + echo "# GenerationAt TS_BUILD_TIME" > ${GFW_TMP_FILE}.new + echo "protocol tcp" >> ${GFW_TMP_FILE}.new + echo "server 8.8.8.8,8.8.4.4,1.1.1.1,1.0.0.1,208.67.222.222,208.67.220.220,209.244.0.3,209.244.0.4,8.26.56.26,8.20.247.20,156.154.70.1,156.154.71.1,199.85.126.10" >> ${GFW_TMP_FILE}.new + echo -e 'proxy no\n\n\n' >> ${GFW_TMP_FILE}.new + echo "${gfw}" >> ${GFW_TMP_FILE}.new + if [ "`cat ${GFW_TMP_FILE}.new | md5sum`" == "`cat ${GFW_TMP_FILE} | md5sum`" ]; then + printf "[\e[32m%s\e[0m]\n" "hold" + else + cp ${GFW_TMP_FILE}.new ${GFW_TMP_FILE} + cp ${GFW_TMP_FILE} ${GFW_FILE} + sed -i "s/TS_BUILD_TIME/${TSTIME}/g" ${GFW_FILE} + printf "[\e[33m%s\e[0m]" "PID" + restart + fi +} + +makeconfig () { + config_load dnsforwarder + + local log=$(uci get dnsforwarder.@config[0].log 2>/dev/null) + local log_size=$(uci get dnsforwarder.@config[0].log_size 2>/dev/null) + + local gfw=$(uci get dnsforwarder.@config[0].gfw 2>/dev/null) + + local udp_local=$(uci -d ',' get dnsforwarder.@config[0].udp_local 2>/dev/null) + local udp_local_list=$(uci get dnsforwarder.@config[0].udp_local 2>/dev/null) + local tcp_group=$(uci get dnsforwarder.@config[0].tcp_group 2>/dev/null) + local udp_group=$(uci get dnsforwarder.@config[0].udp_group 2>/dev/null) + local group_file=$(uci get dnsforwarder.@config[0].group_file 2>/dev/null) + local block_ip=$(uci -d ',' get dnsforwarder.@config[0].block_ip 2>/dev/null) + local ip_substituting=$(uci -d ',' get dnsforwarder.@config[0].ip_substituting 2>/dev/null) + local block_negative_resp=$(uci get dnsforwarder.@config[0].block_negative_resp 2>/dev/null) + local append_host=$(uci get dnsforwarder.@config[0].append_host 2>/dev/null) + local block_ipv6=$(uci get dnsforwarder.@config[0].block_ipv6 2>/dev/null) + + local cache=$(uci get dnsforwarder.@config[0].cache 2>/dev/null) + local cache_size=$(uci get dnsforwarder.@config[0].cache_size 2>/dev/null) + local cache_ignore=$(uci get dnsforwarder.@config[0].cache_ignore 2>/dev/null) + local cache_control=$(uci get dnsforwarder.@config[0].cache_control 2>/dev/null) + + local domain_statistic=$(uci get dnsforwarder.@config[0].domain_statistic 2>/dev/null) + local udp_local_addr=$(uci get dnsforwarder.@arguments[0].addr 2>/dev/null) + udp_local_addr=${udp_local_addr/:/#} + + echo "LogOn ${log}" > $DNSFORWARDER_CONF + if [ $log = "true" ]; then + rm /var/log/dnsforwarder.log.* 2>/dev/null + echo '' > /var/log/dnsforwarder.log + echo "LogFileThresholdLength ${log_size}" >> $DNSFORWARDER_CONF + echo "LogFileFolder /var/log" >> $DNSFORWARDER_CONF + fi + + [ -n "$udp_local" ] && echo "UDPLocal ${udp_local}" >> $DNSFORWARDER_CONF + [ -n "$udp_local_addr" ] && eval "makelist 'server=' $udp_local_addr" > /tmp/dnsmasq.dnsforwarder.conf + sed -i "s/ //g" /tmp/dnsmasq.dnsforwarder.conf + + eval "makelist 'TCPGroup' $tcp_group" >> $DNSFORWARDER_CONF + eval "makelist 'UDPGroup' $udp_group" >> $DNSFORWARDER_CONF + eval "makelist 'GroupFile' $group_file" >> $DNSFORWARDER_CONF + + if [ $gfw = "true" ]; then + echo 'GroupFile /etc/dnsforwarder/gfw.txt' >> $DNSFORWARDER_CONF + fi + + echo "BlockIP ${block_ip}" >> $DNSFORWARDER_CONF + eval "makelist 'IPSubstituting' $ip_substituting" >> $DNSFORWARDER_CONF + echo "BlockNegativeResponse ${block_negative_resp}" >> $DNSFORWARDER_CONF + eval "makelist 'AppendHosts' $append_host" >> $DNSFORWARDER_CONF + echo "BlockIpv6WhenIpv4Exists ${block_ipv6}" >> $DNSFORWARDER_CONF + + echo "UseCache ${cache}" >> $DNSFORWARDER_CONF + if [ $cache = "true" ]; then + echo "CacheSize ${cache_size}" >> $DNSFORWARDER_CONF + echo "MemoryCache false" >> $DNSFORWARDER_CONF + echo "CacheFile /tmp/dnsforwarder.cache" >> $DNSFORWARDER_CONF + echo "IgnoreTTL ${cache_ignore}" >> $DNSFORWARDER_CONF + eval "makelist 'CacheControl' $cache_control" >> $DNSFORWARDER_CONF + echo "ReloadCache true" >> $DNSFORWARDER_CONF + echo "OverwriteCache true" >> $DNSFORWARDER_CONF + fi + echo "DomainStatistic ${domain_statistic}" >> $DNSFORWARDER_CONF + if [ $domain_statistic = "true" ]; then + touch /tmp/dnsforwarder-statistic.html + mkdir -p /root/.dnsforwarder + rm /root/.dnsforwarder/statistic.html 2 > /dev/null + ln -s /tmp/dnsforwarder-statistic.html /root/.dnsforwarder/statistic.html + local domain_statistic_tag='' + echo "DomainStatisticTempletFile /tmp/dnsforwarder-statistic.html" >> $DNSFORWARDER_CONF + echo "StatisticInsertionPosition ${domain_statistic_tag}" >> $DNSFORWARDER_CONF + echo "StatisticUpdateInterval 60" >> $DNSFORWARDER_CONF + echo "${domain_statistic_tag}" > /tmp/dnsforwarder-statistic.html + fi +} + +start() +{ + echo luci for dnsforwarder + local vt_enabled=$(uci get dnsforwarder.@arguments[0].enabled 2>/dev/null) + if [ $vt_enabled = 0 ]; then + echo dnsforwarder is not enabled + exit + fi + makeconfig + fixturboacc + dnsforwarder -f $DNSFORWARDER_CONF -d + sleep 10 + mkdir -p ${PID_PATH} + pid=$(ps | awk '$5 ~ /\[dnsforwarder\]/ {print $1}') + echo "dnsforwarder running pid is ${pid}" + logger -t The pid of dnsforwarder is ${PID_FILE} ${pid} + echo ${pid} > ${PID_FILE} + /etc/init.d/dnsforwarder enable + local dnsmasq=$(uci get dnsforwarder.@arguments[0].dnsmasq 2>/dev/null) + local addr=$(uci get dnsforwarder.@arguments[0].addr 2>/dev/null) + [ -n "${addr}" ] && addr=${addr/:/#} + + if [ "${dnsmasq}" = "1" ]; then + uci delete dhcp.@dnsmasq[0].server 2>/dev/null + # uci add_list dhcp.@dnsmasq[0].server=$addr + uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null + uci set dhcp.@dnsmasq[0].noresolv=1 + uci set dhcp.@dnsmasq[0].serversfile=/tmp/dnsmasq.dnsforwarder.conf + uci commit dhcp + /etc/init.d/dnsmasq restart + fi + local dnsmasq_server_addr=$(uci get dhcp.@dnsmasq[0].server 2>/dev/null) + if [ -n "${dnsmasq_server_addr}" ]; then + uci set dhcp.@dnsmasq[0].noresolv=1 + uci commit dhcp + /etc/init.d/dnsmasq restart + fi + add_cron +} + +stop() +{ + del_cron + logger -t stopping dnsforwarder + local addr=$(uci get dnsforwarder.@arguments[0].addr 2>/dev/null) + local dnsmasq=$(uci get dnsforwarder.@arguments[0].dnsmasq 2>/dev/null) + addr=${addr/:/#} + if [ "${dnsmasq}" = "1" ]; then + uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null + fi + uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto 2>/dev/null + uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null + uci delete dhcp.@dnsmasq[0].serversfile 2>/dev/null + uci commit dhcp + /etc/init.d/dnsmasq restart + [ -e ${PID_FILE} ] && { + pid=$(cat ${PID_FILE}) + logger -t killing dnsforwarder pid ${pid} + echo killing dnsforwarder pid ${pid} + kill ${pid} + rm -f ${PID_FILE} + } || { + logger -t Cannot find dnsforwarder pid file + } +} + +restart() +{ + pid=$(cat ${PID_FILE} 2>/dev/null) + echo Dnsforwarder pid file is ${pid} + [ -n "$pid" ] && { + echo stopping pid ${pid} + logger -t There is dnsforwarder pid ${pid} + stop + } || { + logger -t Dnsforwarder is not running + } + sleep 7 + local vt_enabled=$(uci get dnsforwarder.@arguments[0].enabled 2>/dev/null) + echo dnsforwarder status is ${vt_enabled} + logger -t Dnsforwarder is initializing enabled is ${vt_enabled} + if [ ${vt_enabled} = 1 ]; then + [ -n "$pid" ] && { + logger -t There is dnsforwarder pid ${pid} + stop + } || { + logger -t Dnsforwarder is not running + } + + logger -t Restarting dnsforwarder + start + else + /etc/init.d/dnsforwarder disable + fi +} diff --git a/dnsforwarder/files/usr/share/dnsforwarder/gfwlist.sh b/dnsforwarder/files/usr/share/dnsforwarder/gfwlist.sh new file mode 100755 index 000000000..7bcbaec7d --- /dev/null +++ b/dnsforwarder/files/usr/share/dnsforwarder/gfwlist.sh @@ -0,0 +1,313 @@ +#/bin/sh + +# Name: gfwlist2dnsmasq.sh +# Desription: A shell script which convert gfwlist into dnsmasq rules. +# Version: 0.8.0 (2017.12.25) +# Author: Cokebar Chi +# Website: https://github.com/cokebar + +_green() { + printf '\033[1;31;32m' + printf -- "%b" "$1" + printf '\033[0m' +} + +_red() { + printf '\033[1;31;31m' + printf -- "%b" "$1" + printf '\033[0m' +} + +_yellow() { + printf '\033[1;31;33m' + printf -- "%b" "$1" + printf '\033[0m' +} + +usage() { + cat <<-EOF + +Name: gfwlist2dnsmasq.sh +Desription: A shell script which convert gfwlist into dnsmasq rules. +Version: 0.8.0 (2017.12.25) +Author: Cokebar Chi +Website: https://github.com/cokebar + +Usage: sh gfwlist2dnsmasq.sh [options] -o FILE +Valid options are: + -d, --dns + DNS IP address for the GfwList Domains (Default: 127.0.0.1) + -p, --port + DNS Port for the GfwList Domains (Default: 5353) + -s, --ipset + Ipset name for the GfwList domains + (If not given, ipset rules will not be generated.) + -o, --output + /path/to/output_filename + -i, --insecure + Force bypass certificate validation (insecure) + -l, --domain-list + Convert Gfwlist into domain list instead of dnsmasq rules + (If this option is set, DNS IP/Port & ipset are not needed) + --exclude-domain-file + Delete specific domains in the result from a domain list text file + Please put one domain per line + --extra-domain-file + Include extra domains to the result from a domain list text file + This file will be processed after the exclude-domain-file + Please put one domain per line + -h, --help + Usage +EOF + exit $1 +} + +clean_and_exit(){ + # Clean up temp files + printf 'Cleaning up... ' + rm -rf $TMP_DIR + _green 'Done\n\n' + [ $1 -eq 0 ] && _green 'Job Finished.\n\n' || _red 'Exit with Error code '$1'.\n' + exit $1 +} + +check_depends(){ + which sed base64 curl >/dev/null + if [ $? != 0 ]; then + _red 'Error: Missing Dependency.\nPlease check whether you have the following binaries on you system:\nwhich, sed, base64, curl.\n' + exit 3 + fi + + SYS_KERNEL=`uname -s` + if [ $SYS_KERNEL = "Darwin" -o $SYS_KERNEL = "FreeBSD" ]; then + BASE64_DECODE='base64 -D' + SED_ERES='sed -E' + else + BASE64_DECODE='base64 -d' + SED_ERES='sed -r' + fi +} + +get_args(){ + OUT_TYPE='DNSMASQ_RULES' + DNS_IP='127.0.0.1' + DNS_PORT='5353' + IPSET_NAME='' + FILE_FULLPATH='' + CURL_EXTARG='' + WITH_IPSET=0 + EXTRA_DOMAIN_FILE='' + EXCLUDE_DOMAIN_FILE='' + IPV4_PATTERN='^((2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)\.){3}(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)$' + IPV6_PATTERN='^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?$' + + while [ ${#} -gt 0 ]; do + case "${1}" in + --help | -h) + usage 0 + ;; + --domain-list | -l) + OUT_TYPE='DOMAIN_LIST' + ;; + --insecure | -i) + CURL_EXTARG='--insecure' + ;; + --dns | -d) + DNS_IP="$2" + shift + ;; + --port | -p) + DNS_PORT="$2" + shift + ;; + --ipset | -s) + IPSET_NAME="$2" + shift + ;; + --output | -o) + OUT_FILE="$2" + shift + ;; + --extra-domain-file) + EXTRA_DOMAIN_FILE="$2" + shift + ;; + --exclude-domain-file) + EXCLUDE_DOMAIN_FILE="$2" + shift + ;; + *) + _red "Invalid argument: $1" + usage 1 + ;; + esac + shift 1 + done + + # Check path & file name + if [ -z $OUT_FILE ]; then + _red 'Error: Please specify the path to the output file(using -o/--output argument).\n' + exit 1 + else + if [ -z ${OUT_FILE##*/} ]; then + _red 'Error: '$OUT_FILE' is a path, not a file.\n' + exit 1 + else + if [ ${OUT_FILE}a != ${OUT_FILE%/*}a ] && [ ! -d ${OUT_FILE%/*} ]; then + _red 'Error: Folder do not exist: '${OUT_FILE%/*}'\n' + exit 1 + fi + fi + fi + + if [ $OUT_TYPE = 'DNSMASQ_RULES' ]; then + # Check DNS IP + IPV4_TEST=$(echo $DNS_IP | grep -E $IPV4_PATTERN) + IPV6_TEST=$(echo $DNS_IP | grep -E $IPV6_PATTERN) + if [ "$IPV4_TEST" != "$DNS_IP" -a "$IPV6_TEST" != "$DNS_IP" ]; then + _red 'Error: Please enter a valid DNS server IP address.\n' + exit 1 + fi + + # Check DNS port + if [ $DNS_PORT -lt 1 -o $DNS_PORT -gt 65535 ]; then + _red 'Error: Please enter a valid DNS server port.\n' + exit 1 + fi + + # Check ipset name + if [ -z $IPSET_NAME ]; then + WITH_IPSET=0 + else + IPSET_TEST=$(echo $IPSET_NAME | grep -E '^\w+$') + if [ "$IPSET_TEST" != "$IPSET_NAME" ]; then + _red 'Error: Please enter a valid IP set name.\n' + exit 1 + else + WITH_IPSET=1 + fi + fi + fi + + if [ ! -z $EXTRA_DOMAIN_FILE ] && [ ! -f $EXTRA_DOMAIN_FILE ]; then + _yellow 'WARNING:\nExtra domain file does not exist, ignored.\n\n' + EXTRA_DOMAIN_FILE='' + fi + + if [ ! -z $EXCLUDE_DOMAIN_FILE ] && [ ! -f $EXCLUDE_DOMAIN_FILE ]; then + _yellow 'WARNING:\nExclude domain file does not exist, ignored.\n\n' + EXCLUDE_DOMAIN_FILE='' + fi +} + + + +process(){ + # Set Global Var + BASE_URL='https://github.com/gfwlist/gfwlist/raw/master/gfwlist.txt' + TMP_DIR=`mktemp -d /tmp/gfwlist2dnsmasq.XXXXXX` + BASE64_FILE="$TMP_DIR/base64.txt" + GFWLIST_FILE="$TMP_DIR/gfwlist.txt" + DOMAIN_TEMP_FILE="$TMP_DIR/gfwlist2domain.tmp" + DOMAIN_FILE="$TMP_DIR/gfwlist2domain.txt" + CONF_TMP_FILE="$TMP_DIR/gfwlist.conf.tmp" + OUT_TMP_FILE="$TMP_DIR/gfwlist.out.tmp" + + # Fetch GfwList and decode it into plain text + printf 'Fetching GfwList... ' + local tscurl='curl -L --connect-timeout 5 -m 300 --retry 3 --retry-delay 1' + $tscurl $CURL_EXTARG -o$BASE64_FILE $BASE_URL \ + || $tscurl $CURL_EXTARG -o$BASE64_FILE https://gitlab.com/gfwlist/gfwlist/raw/master/gfwlist.txt \ + || $tscurl $CURL_EXTARG -o$BASE64_FILE https://git.tuxfamily.org/gfwlist/gfwlist.git/plain/gfwlist.txt \ + || $tscurl $CURL_EXTARG -o$BASE64_FILE https://pagure.io/gfwlist/raw/master/f/gfwlist.txt \ + || $tscurl $CURL_EXTARG -o$BASE64_FILE http://repo.or.cz/gfwlist.git/blob_plain/HEAD:/gfwlist.txt \ + || $tscurl $CURL_EXTARG -o$BASE64_FILE https://bitbucket.org/gfwlist/gfwlist/raw/HEAD/gfwlist.txt \ + || $tscurl $CURL_EXTARG -o$BASE64_FILE $BASE_URL + if [ $? != 0 ]; then + _red '\nFailed to fetch gfwlist.txt. Please check your Internet connection.\n' + clean_and_exit 2 + fi + $BASE64_DECODE $BASE64_FILE > $GFWLIST_FILE || ( _red 'Failed to decode gfwlist.txt. Quit.\n'; clean_and_exit 2 ) + _green 'Done.\n\n' + + # Convert + IGNORE_PATTERN='^\!|\[|^@@|(https?://){0,1}[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' + HEAD_FILTER_PATTERN='s#^(\|\|?)?(https?://)?##g' + TAIL_FILTER_PATTERN='s#/.*$|%2F.*$##g' + DOMAIN_PATTERN='([a-zA-Z0-9][-a-zA-Z0-9]*(\.[a-zA-Z0-9][-a-zA-Z0-9]*)+)' + HANDLE_WILDCARD_PATTERN='s#^(([a-zA-Z0-9]*\*[-a-zA-Z0-9]*)?(\.))?([a-zA-Z0-9][-a-zA-Z0-9]*(\.[a-zA-Z0-9][-a-zA-Z0-9]*)+)(\*)?#\4#g' + + printf 'Converting GfwList to ' && _green $OUT_TYPE && printf ' ...\n' + _yellow '\nWARNING:\nThe following lines in GfwList contain regex, and might be ignored:\n\n' + cat $GFWLIST_FILE | grep -n '^/.*$' + _yellow "\nThis script will try to convert some of the regex rules. But you should know this may not be a equivalent conversion.\nIf there's regex rules which this script do not deal with, you should add the domain manually to the list.\n\n" + grep -vE $IGNORE_PATTERN $GFWLIST_FILE | $SED_ERES $HEAD_FILTER_PATTERN | $SED_ERES $TAIL_FILTER_PATTERN | grep -E $DOMAIN_PATTERN | $SED_ERES $HANDLE_WILDCARD_PATTERN > $DOMAIN_TEMP_FILE + + printf 'google.com\ngoogle.ad\ngoogle.ae\ngoogle.com.af\ngoogle.com.ag\ngoogle.com.ai\ngoogle.al\ngoogle.am\ngoogle.co.ao\ngoogle.com.ar\ngoogle.as\ngoogle.at\ngoogle.com.au\ngoogle.az\ngoogle.ba\ngoogle.com.bd\ngoogle.be\ngoogle.bf\ngoogle.bg\ngoogle.com.bh\ngoogle.bi\ngoogle.bj\ngoogle.com.bn\ngoogle.com.bo\ngoogle.com.br\ngoogle.bs\ngoogle.bt\ngoogle.co.bw\ngoogle.by\ngoogle.com.bz\ngoogle.ca\ngoogle.cd\ngoogle.cf\ngoogle.cg\ngoogle.ch\ngoogle.ci\ngoogle.co.ck\ngoogle.cl\ngoogle.cm\ngoogle.cn\ngoogle.com.co\ngoogle.co.cr\ngoogle.com.cu\ngoogle.cv\ngoogle.com.cy\ngoogle.cz\ngoogle.de\ngoogle.dj\ngoogle.dk\ngoogle.dm\ngoogle.com.do\ngoogle.dz\ngoogle.com.ec\ngoogle.ee\ngoogle.com.eg\ngoogle.es\ngoogle.com.et\ngoogle.fi\ngoogle.com.fj\ngoogle.fm\ngoogle.fr\ngoogle.ga\ngoogle.ge\ngoogle.gg\ngoogle.com.gh\ngoogle.com.gi\ngoogle.gl\ngoogle.gm\ngoogle.gp\ngoogle.gr\ngoogle.com.gt\ngoogle.gy\ngoogle.com.hk\ngoogle.hn\ngoogle.hr\ngoogle.ht\ngoogle.hu\ngoogle.co.id\ngoogle.ie\ngoogle.co.il\ngoogle.im\ngoogle.co.in\ngoogle.iq\ngoogle.is\ngoogle.it\ngoogle.je\ngoogle.com.jm\ngoogle.jo\ngoogle.co.jp\ngoogle.co.ke\ngoogle.com.kh\ngoogle.ki\ngoogle.kg\ngoogle.co.kr\ngoogle.com.kw\ngoogle.kz\ngoogle.la\ngoogle.com.lb\ngoogle.li\ngoogle.lk\ngoogle.co.ls\ngoogle.lt\ngoogle.lu\ngoogle.lv\ngoogle.com.ly\ngoogle.co.ma\ngoogle.md\ngoogle.me\ngoogle.mg\ngoogle.mk\ngoogle.ml\ngoogle.com.mm\ngoogle.mn\ngoogle.ms\ngoogle.com.mt\ngoogle.mu\ngoogle.mv\ngoogle.mw\ngoogle.com.mx\ngoogle.com.my\ngoogle.co.mz\ngoogle.com.na\ngoogle.com.nf\ngoogle.com.ng\ngoogle.com.ni\ngoogle.ne\ngoogle.nl\ngoogle.no\ngoogle.com.np\ngoogle.nr\ngoogle.nu\ngoogle.co.nz\ngoogle.com.om\ngoogle.com.pa\ngoogle.com.pe\ngoogle.com.pg\ngoogle.com.ph\ngoogle.com.pk\ngoogle.pl\ngoogle.pn\ngoogle.com.pr\ngoogle.ps\ngoogle.pt\ngoogle.com.py\ngoogle.com.qa\ngoogle.ro\ngoogle.ru\ngoogle.rw\ngoogle.com.sa\ngoogle.com.sb\ngoogle.sc\ngoogle.se\ngoogle.com.sg\ngoogle.sh\ngoogle.si\ngoogle.sk\ngoogle.com.sl\ngoogle.sn\ngoogle.so\ngoogle.sm\ngoogle.sr\ngoogle.st\ngoogle.com.sv\ngoogle.td\ngoogle.tg\ngoogle.co.th\ngoogle.com.tj\ngoogle.tk\ngoogle.tl\ngoogle.tm\ngoogle.tn\ngoogle.to\ngoogle.com.tr\ngoogle.tt\ngoogle.com.tw\ngoogle.co.tz\ngoogle.com.ua\ngoogle.co.ug\ngoogle.co.uk\ngoogle.com.uy\ngoogle.co.uz\ngoogle.com.vc\ngoogle.co.ve\ngoogle.vg\ngoogle.co.vi\ngoogle.com.vn\ngoogle.vu\ngoogle.ws\ngoogle.rs\ngoogle.co.za\ngoogle.co.zm\ngoogle.co.zw\ngoogle.cat\n' >> $DOMAIN_TEMP_FILE + printf 'Google search domains... ' && _green 'Added\n' + + # Add blogspot domains + printf 'blogspot.ca\nblogspot.co.uk\nblogspot.com\nblogspot.com.ar\nblogspot.com.au\nblogspot.com.br\nblogspot.com.by\nblogspot.com.co\nblogspot.com.cy\nblogspot.com.ee\nblogspot.com.eg\nblogspot.com.es\nblogspot.com.mt\nblogspot.com.ng\nblogspot.com.tr\nblogspot.com.uy\nblogspot.de\nblogspot.gr\nblogspot.in\nblogspot.mx\nblogspot.ch\nblogspot.fr\nblogspot.ie\nblogspot.it\nblogspot.pt\nblogspot.ro\nblogspot.sg\nblogspot.be\nblogspot.no\nblogspot.se\nblogspot.jp\nblogspot.in\nblogspot.ae\nblogspot.al\nblogspot.am\nblogspot.ba\nblogspot.bg\nblogspot.ch\nblogspot.cl\nblogspot.cz\nblogspot.dk\nblogspot.fi\nblogspot.gr\nblogspot.hk\nblogspot.hr\nblogspot.hu\nblogspot.ie\nblogspot.is\nblogspot.kr\nblogspot.li\nblogspot.lt\nblogspot.lu\nblogspot.md\nblogspot.mk\nblogspot.my\nblogspot.nl\nblogspot.no\nblogspot.pe\nblogspot.qa\nblogspot.ro\nblogspot.ru\nblogspot.se\nblogspot.sg\nblogspot.si\nblogspot.sk\nblogspot.sn\nblogspot.tw\nblogspot.ug\nblogspot.cat\n' >> $DOMAIN_TEMP_FILE + printf 'Blogspot domains... ' && _green 'Added\n' + + # Add twimg.edgesuite.net + printf 'twimg.edgesuite.net\n' >> $DOMAIN_TEMP_FILE + printf 'twimg.edgesuite.net... ' && _green 'Added\n' + + # Delete exclude domains + if [ ! -z $EXCLUDE_DOMAIN_FILE ]; then + for line in $(cat $EXCLUDE_DOMAIN_FILE) + do + cat $DOMAIN_TEMP_FILE | grep -vF -f $EXCLUDE_DOMAIN_FILE > $DOMAIN_FILE + done + printf 'Domains in exclude domain file '$EXCLUDE_DOMAIN_FILE'... ' && _green 'Deleted\n' + else + cat $DOMAIN_TEMP_FILE > $DOMAIN_FILE + fi + + # Add extra domains + if [ ! -z $EXTRA_DOMAIN_FILE ]; then + cat $EXTRA_DOMAIN_FILE >> $DOMAIN_FILE + printf 'Extra domain file '$EXTRA_DOMAIN_FILE'... ' && _green 'Added\n' + fi + + if [ $OUT_TYPE = 'DNSMASQ_RULES' ]; then + # Convert domains into dnsmasq rules + if [ $WITH_IPSET -eq 1 ]; then + _green 'Ipset rules included.' + sort -u $DOMAIN_FILE | $SED_ERES 's#(.+)#server=/\1/'$DNS_IP'\#'$DNS_PORT'\ + ipset=/\1/'$IPSET_NAME'#g' > $CONF_TMP_FILE + else + _green 'Ipset rules not included.' + sort -u $DOMAIN_FILE | $SED_ERES 's#(.+)#server=/\1/'$DNS_IP'\#'$DNS_PORT'#g' > $CONF_TMP_FILE + fi + + # Generate output file + echo '# dnsmasq rules generated by gfwlist' > $OUT_TMP_FILE + echo "# Last Updated on $(date "+%Y-%m-%d %H:%M:%S")" >> $OUT_TMP_FILE + echo '# ' >> $OUT_TMP_FILE + cat $CONF_TMP_FILE >> $OUT_TMP_FILE + cp $OUT_TMP_FILE $OUT_FILE + else + sort -u $DOMAIN_FILE > $OUT_TMP_FILE + fi + + cp $OUT_TMP_FILE $OUT_FILE + printf '\nConverting GfwList to '$OUT_TYPE'... ' && _green 'Done\n\n' + + # Clean up + clean_and_exit 0 +} + +main() { + if [ -z "$1" ]; then + usage 0 + else + check_depends + get_args "$@" + _green '\nJob Started.\n\n' + process + fi +} + +main "$@" diff --git a/gmediarender/Makefile b/gmediarender/Makefile new file mode 100644 index 000000000..88549c63a --- /dev/null +++ b/gmediarender/Makefile @@ -0,0 +1,50 @@ +# +# Copyright (C) 2020 coolsnowwolf@gmail.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=gmediarender +PKG_VERSION:=2021-03-15 +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/hzeller/gmrender-resurrect.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=4ac7d8914dc089651ae9d6c421ecda8f4d0ab5e3 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MIRROR_HASH:=08e8e60b8734131acd5d667c40a9a7e9d8bc7e86f59b4972d177e653608a1215 + +PKG_FIXUP:=autoreconf +PKG_INSTALL=1 +PKG_REMOVE_FILES:=autogen.sh aclocal.m4 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/gmediarender + SECTION:=multimedia + CATEGORY:=Multimedia + DEPENDS:= +gstreamer1 +libgstreamer1 +gstreamer1-libs +glib2 +libupnp + TITLE:=A Headless UPnP Renderer +endef + +define Package/gmediarender/description + gmediarender implements the server component that provides UPnP + controllers a means to render media content (audio, video and images) + from a UPnP media server. +endef + +CONFIGURE_ARGS+= \ + CFLAGS="$(TARGET_CFLAGS) -std=gnu99" --with-build-cc="$(HOSTCC)" \ + --prefix="\usr" + +define Package/gmediarender/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,gmediarender)) diff --git a/go-aliyundrive-webdav/Makefile b/go-aliyundrive-webdav/Makefile new file mode 100644 index 000000000..5413b5921 --- /dev/null +++ b/go-aliyundrive-webdav/Makefile @@ -0,0 +1,55 @@ +# SPDX-Identifier-License: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=go-aliyundrive-webdav +PKG_VERSION:=1.1.1 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/LinkLeong/go-aliyundrive-webdav/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=967472971586bc9c62d1579a780e52431eaf37e54f2fe1b180c9a52db2304874 + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=go-aliyun-webdav +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/go-aliyundrive-webdav + SECTION:=net + CATEGORY:=Network + SUBMENU:=File Transfer + TITLE:=A WebDav server for AliyunDrive + URL:=https://github.com/LinkLeong/go-aliyundrive-webdav + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + + +define Package/go-aliyundrive-webdav/conffiles +/etc/config/go-aliyundrive-webdav +endef + +define Package/go-aliyundrive-webdav/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/go-aliyun-webdav $(1)/usr/bin/go-aliyundrive-webdav + + $(INSTALL_DIR) $(1)/etc/config/ + $(INSTALL_CONF) $(CURDIR)/files/go-aliyundrive-webdav.config $(1)/etc/config/go-aliyundrive-webdav + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) $(CURDIR)/files/go-aliyundrive-webdav.init $(1)/etc/init.d/go-aliyundrive-webdav +endef + +$(eval $(call GoBinPackage,go-aliyundrive-webdav)) +$(eval $(call BuildPackage,go-aliyundrive-webdav)) diff --git a/go-aliyundrive-webdav/files/go-aliyundrive-webdav.config b/go-aliyundrive-webdav/files/go-aliyundrive-webdav.config new file mode 100644 index 000000000..d6ed4edde --- /dev/null +++ b/go-aliyundrive-webdav/files/go-aliyundrive-webdav.config @@ -0,0 +1,23 @@ + + +config go-aliyundrive-webdav 'config' + option enabled '0' + + # Listening port + option port '8085' + + # Refresh token + option rt '' + + # Mounting directory + option path '/' + + # Webdav auth username, default: admin + option user 'admin' + + # Webdav auth password, default: 123456 + option pwd '123456' + + # Enable detailed logging + option verbose '0' + diff --git a/go-aliyundrive-webdav/files/go-aliyundrive-webdav.init b/go-aliyundrive-webdav/files/go-aliyundrive-webdav.init new file mode 100755 index 000000000..9eff96e2e --- /dev/null +++ b/go-aliyundrive-webdav/files/go-aliyundrive-webdav.init @@ -0,0 +1,50 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 Tianling Shen + +USE_PROCD=1 +START=99 + +CONF="go-aliyundrive-webdav" +PROG="/usr/bin/go-aliyundrive-webdav" + +start_service() { + config_load "$CONF" + + local enabled + config_get_bool enabled "config" "enabled" + [ "$enabled" -eq "1" ] || return 1 + + local port rt path user pwd verbose + config_get port "config" "port" + config_get rt "config" "rt" + config_get path "config" "path" + config_get user "config" "user" + config_get pwd "config" "pwd" + config_get_bool verbose "config" "verbose" + + procd_open_instance "$CONF" + + procd_set_param command "$PROG" + + procd_append_param command "-rt" "$rt" + procd_append_param command "-port" "$port" + procd_append_param command "-path" "$path" + procd_append_param command "-user" "$user" + procd_append_param command "-pwd" "$pwd" + [ "$verbose" -eq "0" ] || procd_append_param command "-v" + + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param respawn + + procd_close_instance +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "go-aliyundrive-webdav" +} diff --git a/luci-app-unblockneteasemusic/Makefile b/luci-app-unblockneteasemusic/Makefile new file mode 100644 index 000000000..2b80a8d4d --- /dev/null +++ b/luci-app-unblockneteasemusic/Makefile @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2019-2022 Tianling Shen + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for UnblockNeteaseMusic (JavaScript) +LUCI_DEPENDS:=+dnsmasq-full +node \ + @(PACKAGE_libustream-mbedtls||PACKAGE_libustream-openssl||PACKAGE_libustream-wolfssl) +LUCI_PKGARCH:=all + +PKG_NAME:=luci-app-unblockneteasemusic +PKG_VERSION:=3.1 +PKG_RELEASE:=4 + +PKG_MAINTAINER:=Tianling Shen + +define Package/luci-app-unblockneteasemusic/conffiles +/etc/config/unblockneteasemusic +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-unblockneteasemusic/htdocs/luci-static/resources/view/unblockneteasemusic/config.js b/luci-app-unblockneteasemusic/htdocs/luci-static/resources/view/unblockneteasemusic/config.js new file mode 100644 index 000000000..133c9f6e8 --- /dev/null +++ b/luci-app-unblockneteasemusic/htdocs/luci-static/resources/view/unblockneteasemusic/config.js @@ -0,0 +1,358 @@ +/* SPDX-License-Identifier: GPL-3.0-only + * + * Copyright (C) 2022-2023 ImmortalWrt.org + */ + +'use strict'; +'require form'; +'require fs'; +'require network'; +'require poll'; +'require rpc'; +'require uci'; +'require ui'; +'require view'; + +var CBIStaticList = form.DynamicList.extend({ + __name__: 'CBI.StaticList', + + renderWidget: function(/* ... */) { + var dl = form.DynamicList.prototype.renderWidget.apply(this, arguments); + dl.querySelector('.add-item ul > li[data-value="-"]').remove(); + return dl; + } +}); + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); + +function getServiceStatus() { + return L.resolveDefault(callServiceList('unblockneteasemusic'), {}).then(function (res) { + var isRunning = false; + try { + isRunning = res['unblockneteasemusic']['instances']['unblockneteasemusic']['running']; + } catch (e) { } + return isRunning; + }); +} + +function renderStatus(isRunning) { + var spanTemp = '%s %s'; + var renderHTML; + if (isRunning) { + renderHTML = spanTemp.format('green', _('UnblockNeteaseMusic'), _('运行中')); + } else { + renderHTML = spanTemp.format('red', _('UnblockNeteaseMusic'), _('未运行')); + } + + return renderHTML; +} + +function uploadCertificate(type, filename, ev) { + return ui.uploadFile('/usr/share/unblockneteasemusic/' + filename, ev.target) + .then(L.bind(function(btn, res) { + btn.firstChild.data = _('检查 %s 中...').format(type); + + if (res.size <= 0) { + ui.addNotification(null, E('p', _('上传的 %s 为空。').format(tyupe))); + return fs.remove('/usr/share/unblockneteasemusic/' + filename); + } + + ui.addNotification(null, E('p', _('您的 %s 已成功上传。大小:%sB。').format(type, res.size))); + }, this, ev.target)) + .catch(function(e) { ui.addNotification(null, E('p', e.message)) }) + .finally(L.bind(function(btn, input) { + btn.firstChild.data = _('上传...'); + }, this, ev.target)); +} + +return view.extend({ + load: function() { + return Promise.all([ + uci.load('unblockneteasemusic'), + network.getHostHints() + ]); + }, + + render: function(data) { + var m, s, o; + + m = new form.Map('unblockneteasemusic', _('解除网易云音乐播放限制'), + _('原理:采用 [Bilibili/JOOX/酷狗/酷我/咪咕/pyncmd/QQ/Youtube] 等音源,替换网易云音乐 无版权/收费 歌曲链接
' + + '具体使用方法参见:GitHub @UnblockNeteaseMusic/luci-app-unblockneteasemusic')); + + 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); + }); + }); + + return E('div', { class: 'cbi-section', id: 'status_bar' }, [ + E('p', { id: 'service_status' }, _('收集数据中...')) + ]); + } + + s = m.section(form.NamedSection, 'config', 'unblockneteasemusic'); + + o = s.option(form.Flag, 'enable', _('启用服务')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(CBIStaticList, 'music_source', _('音源接口'), + _('留空以使用默认音源。')); + o.value('bilibili', _('Bilibili 音乐')); + o.value('joox', _('JOOX 音乐')); + o.value('kugou', _('酷狗音乐')); + o.value('kuwo', _('酷我音乐')); + o.value('migu', _('咪咕音乐')); + o.value('pyncmd', _('网易云音乐(pyncmd)')); + o.value('qq', _('QQ 音乐')); + o.value('youtube', _('Youtube 音乐')); + o.value('youtubedl', _('Youtube 音乐(youtube-dl)')); + o.value('ytdlp', _('Youtube 音乐(yt-dlp)')); + o.value('ytdownload', _('Youtube 音乐(ytdownload)')); + + o = s.option(form.Value, 'joox_cookie', _('JOOX Cookie'), + _('在 joox.com 获取,需要 wmid 和 session_key 值。')); + o.placeholder = 'wmid=; session_key='; + o.rmempty = false; + o.depends({'music_source': 'joox', '!contains': true}); + + o = s.option(form.Value, 'migu_cookie', _('Migu Cookie'), + _('通过抓包手机客户端请求获取,需要 aversionid 值。')); + o.depends({'music_source': 'migu', '!contains': true}); + + o = s.option(form.Value, 'qq_cookie', _('QQ Cookie'), + _('在 y.qq.com 获取,需要 uin 和 qm_keyst 值。')); + o.placeholder = 'uin=; qm_keyst='; + o.rmempty = false; + o.depends({'music_source': 'qq', '!contains': true}); + + o = s.option(form.Value, 'youtube_key', _('Youtube API Key'), + _('API Key 申请地址:https://developers.google.com/youtube/v3/getting-started#before-you-start')); + o.depends({'music_source': 'youtube', '!contains': true}); + + o = s.option(form.Flag, 'follow_source_order', _('顺序查询'), + _('默认为并行查询并返回第一个结果,开启后将严格按照配置音源的顺序进行查询。')) + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.Flag, 'search_album', _('附加专辑名'), + _('在其他音源搜索歌曲时携带专辑名称(默认搜索条件 歌曲名 - 歌手,启用后搜索条件 歌曲名 - 歌手 专辑名)。')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.Flag, 'local_vip', _('启用本地 VIP'), + _('启用后,可以使用去广告、个性换肤、鲸云音效等本地功能。')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.Flag, 'enable_flac', _('启用无损音质'), + _('目前仅支持酷狗、酷我、咪咕、pyncmd、QQ 音源。')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.Flag, 'disable_upgrade_check', _('禁用更新检查'), + _('禁止客户端检查更新,全平台支持。')); + o.default = o.enabled; + o.rmempty = false; + + o = s.option(form.ListValue, 'replace_music_source', _('音源替换'), + _('当音乐音质低于指定数值时,尝试强制使用其他平台的高音质版本进行替换。')); + o.value('dont_replace', _('不强制替换音乐音源')); + o.value('lower_than_192kbps', _('当音质低于 192 Kbps(中)时')); + o.value('lower_than_320kbps', _('当音质低于 320 Kbps(高)时')); + o.value('lower_than_999kbps', _('当音质低于 999 Kbps(无损)时')); + o.value('replace_all', _('替换所有音乐音源')); + o.default = 'dont_replace'; + o.rmempty = false; + + o = s.option(form.Flag, 'auto_update', _('启用自动更新'), + _('启用后,每天将定时自动检查最新版本并更新。')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.ListValue, 'update_time', '检查更新时间', + _('设定每天自动检查更新时间。')); + for (var i = 0; i < 24; i++) + o.value(i, i + ':00'); + o.default = '3'; + o.depends('auto_update', '1'); + + o = s.option(form.Button, '_download_cert', _('CA 根证书'), + _('Linux / iOS / MacOSX 在信任根证书后方可正常使用。')); + o.inputstyle = 'apply'; + o.inputtitle = _('下载 ca.crt'); + o.onclick = function() { + return fs.read_direct('/usr/share/unblockneteasemusic/core/ca.crt', 'blob').then(function(blob) { + var url = window.URL.createObjectURL(blob); + var link = E('a', { 'style': 'display:none', 'href': url, 'download': 'ca.crt' }); + + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + }).catch(function(err) { + ui.addNotification(null, E('p', [ _('下载文件失败:%s。').format(err.message) ])); + }); + } + + o = s.option(form.Flag, 'advanced_mode', _('启用进阶设置'), + _('非必要不推荐使用。')); + o.default = o.disabled, + o.rmempty = false; + + o = s.option(form.ListValue, 'log_level', _('日志等级')); + o.value('debug', _('调试')); + o.value('info', _('信息(默认)')); + o.value('silent', _('静默')); + o.default = 'info'; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'http_port', _('HTTP 监听端口')); + o.datatype = 'port'; + o.default = '5200'; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'https_port', _('HTTPS 监听端口')); + o.datatype = 'port'; + o.default = '5201'; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'endpoint_url', _('EndPoint'), + _('音源地址反代(包装)。')); + o.default = 'https://music.163.com'; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'cnrelay', _('UNM Bridge 服务器'), + _('使用 UnblockNeteaseMusic 中继桥(bridge)以获取音源信息。')); + o.placeholder = 'http(s)://host:port' + o.depends('advanced_mode', '1'); + + o = s.option(form.ListValue, 'hijack_ways', _('劫持方法')); + o.value('dont_hijack', _('不开启劫持')); + o.value('use_ipset', _('使用 IPSet 劫持')); + o.value('use_hosts', _('使用 Hosts 劫持')); + o.default = 'dont_hijack'; + o.rmempty = false; + o.depends('advanced_mode', '1'); + o.onchange = function(ev, section_id, value) { + if (!section_id || !value) + return null; + + var ele_http_port = this.map.findElement('id', 'widget.cbid.unblockneteasemusic.%s.http_port'.format(section_id)); + var ele_https_port = this.map.findElement('id', 'widget.cbid.unblockneteasemusic.%s.https_port'.format(section_id)); + + if (value === 'use_hosts') { + ele_http_port.value = '80'; + ele_http_port.disabled = true; + + ele_https_port.value = '443'; + ele_https_port.disabled = true; + } else if (ele_http_port.disabled || ele_https_port.disabled) { + L.resolveDefault(this.map.data.loaded.unblockneteasemusic).then((res) => { + ele_http_port.disabled = null; + ele_http_port.value = res.config.http_port || '5200'; + + ele_https_port.disabled = null; + ele_https_port.value = res.config.https_port || '5201'; + }); + } + } + + o = s.option(form.Flag, 'keep_core_when_upgrade', _('升级时保留核心程序')); + o.default = o.disabled; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Flag, 'pub_access', _('部署到公网'), + _('默认仅放行局域网请求,如需提供公开访问请勾选此选项。')); + o.default = o.disabled; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Flag, 'strict_mode', _('启用严格模式'), + _('若将服务部署到公网,则强烈建议使用严格模式,此模式下仅放行网易云音乐所属域名的请求。
注意:该模式下不能使用全局代理。')); + o.default = o.disabled; + o.rmempty = false; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'netease_server_ip', _('网易云服务器 IP')); + o.datatype = 'ipaddr'; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'proxy_server_ip', _('代理服务器地址'), + _('使用代理服务器获取音乐信息。')); + o.placeholder = 'http(s)://host:port'; + o.depends('advanced_mode', '1'); + + o = s.option(form.Value, 'self_issue_cert_crt', _('自签发证书公钥位置')); + o.value('/usr/share/unblockneteasemusic/core/server.crt', _('内置公钥')); + o.value('/usr/share/unblockneteasemusic/server.crt'); + o.default = '/usr/share/unblockneteasemusic/core/server.crt'; + o.datatype = 'file'; + o.depends('advanced_mode', '1'); + + o = s.option(form.Button, '_upload_cert', _('上传公钥')); + o.inputstyle = 'action'; + o.inputtitle = _('上传...'); + o.depends('self_issue_cert_crt', '/usr/share/unblockneteasemusic/server.crt'); + o.onclick = L.bind(uploadCertificate, this, _('公钥'), 'server.crt'); + o.modalonly = true; + + o = s.option(form.Value, 'self_issue_cert_key', _('自签发证书私钥位置')); + o.value('/usr/share/unblockneteasemusic/core/server.key', _('内置私钥')); + o.value('/usr/share/unblockneteasemusic/server.key'); + o.default = '/usr/share/unblockneteasemusic/core/server.key'; + o.datatype = 'file' + o.depends('advanced_mode', '1'); + + o = s.option(form.Button, '_upload_key', _('上传私钥')); + o.inputstyle = 'action'; + o.inputtitle = _('上传...'); + o.depends('self_issue_cert_key', '/usr/share/unblockneteasemusic/server.key'); + o.onclick = L.bind(uploadCertificate, this, _('私钥'), 'server.key'); + o.modalonly = true; + + s = m.section(form.TableSection, 'acl_rule', _('例外客户端规则'), + _('可以为局域网客户端分别设置不同的例外模式。')); + s.addremove = true; + s.anonymous = true; + s.sortable = true; + + o = s.option(form.Flag, 'enable', _('启用')); + o.default = o.enabled; + o.rmempty = false; + + o = s.option(form.Value, 'ip_addr', _('IP 地址')); + o.datatype = 'ip4addr'; + for (var i of Object.entries(data[1].hosts)) + for (var v in i[1].ipaddrs) + if (i[1].ipaddrs[v]) { + var ip_addr = i[1].ipaddrs[v], ip_host = i[1].name; + o.value(ip_addr, ip_host ? String.format('%s (%s)', ip_host, ip_addr) : ip_addr) + } + o.rmempty = false; + + o = s.option(form.ListValue, 'filter_mode', _('规则')); + o.value('disable_all', _('不代理 HTTP 和 HTTPS')); + o.value('disable_http', _('不代理 HTTP')); + o.value('disable_https', _('不代理 HTTPS')); + o.default = 'disable_all'; + o.rmempty = false; + + return m.render(); + } +}); diff --git a/luci-app-unblockneteasemusic/htdocs/luci-static/resources/view/unblockneteasemusic/status.js b/luci-app-unblockneteasemusic/htdocs/luci-static/resources/view/unblockneteasemusic/status.js new file mode 100644 index 000000000..941427374 --- /dev/null +++ b/luci-app-unblockneteasemusic/htdocs/luci-static/resources/view/unblockneteasemusic/status.js @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: GPL-3.0-only + * + * Copyright (C) 2022 ImmortalWrt.org + */ + +'use strict'; +'require dom'; +'require form'; +'require fs'; +'require poll'; +'require rpc'; +'require ui'; +'require view'; + +return view.extend({ + render: function() { + var m, s, o; + + var unm_helper = '/usr/share/unblockneteasemusic/update.sh'; + + m = new form.Map('unblockneteasemusic'); + + s = m.section(form.NamedSection, 'config', 'unblockneteasemusic', _('核心管理')); + s.anonymous = true; + + o = s.option(form.DummyValue, '_core_version', _('核心版本')); + o.cfgvalue = function() { + var _this = this; + var spanTemp = '
%s
'; + + return fs.exec(unm_helper, [ 'check_version' ]).then(function(res) { + if (res.code === 0) + _this.default = String.format(spanTemp, 'green', res.stdout.trim()); + else if (res.code === 2) + _this.default = String.format(spanTemp, 'red', _('未安装')); + else { + ui.addNotification(null, E('p', [ _('获取版本信息失败:%s。').format(res) ])); + _this.default = String.format(spanTemp, 'red', _('未知错误')); + } + + return null; + }).catch(function(err) { + ui.addNotification(null, E('p', [ _('未知错误:%s。').format(err) ])); + _this.default = String.format(spanTemp, 'red', _('未知错误')); + + return null; + }); + } + o.rawhtml = true; + + o = s.option(form.Button, '_remove_core', _('删除核心'), + _('删除核心后,需手动点击下面的按钮重新下载,有助于解决版本冲突问题。')); + o.inputstyle = 'remove'; + o.onclick = function() { + var _this = this; + + return fs.exec(unm_helper, [ 'remove_core' ]).then(function(res) { + _this.description = '删除完毕。' + return _this.map.reset(); + }).catch(function(err) { + ui.addNotification(null, E('p', [ _('未知错误:%s。').format(err) ])); + _this.description = '删除失败。' + return _this.map.reset(); + }); + } + + o = s.option(form.Button, '_update_core', _('更新核心'), + _('更新完毕后会自动在后台重启插件,无需手动重启。')); + o.inputstyle = 'action'; + o.onclick = function() { + var _this = this; + + return fs.exec(unm_helper, [ 'update_core' ]).then(function (res) { + if (res.code === 0) + _this.description = _('更新成功。'); + else if (res.code === 1) + _this.description = _('更新失败。'); + else if (res.code === 2) + _this.description = _('更新程序正在运行中。'); + else if (res.code === 3) + _this.description = _('当前已是最新版本。'); + + return _this.map.reset(); + }).catch(function (err) { + ui.addNotification(null, E('p', [ _('未知错误:%s。').format(err) ])); + _this.description = _('更新失败。'); + return _this.map.reset(); + }); + } + + o = s.option(form.Button, '_debug_log', _('调试报告'), + _('若您遇到使用上的问题,请点此打印调试报告,并将其附在您的 issue 中。')); + o.inputstyle = 'action'; + o.inputtitle = _('打印报告'); + o.onclick = function() { + var log_modal = ui.showModal(_('打印调试报告'), [ + E('p', { 'class': 'spinning' }, + _('正在打印调试报告中...')) + ]); + + return fs.exec_direct('/usr/bin/unm-debug', 'text').then(function (res) { + log_modal.removeChild(log_modal.lastChild); + + if (res) { + log_modal.appendChild(E('p', _('提交 issue 时,您只需附上最后的链接,无需提供整个输出。'))); + log_modal.appendChild(E('textarea', { + 'id': 'content_debugLog', + 'class': 'cbi-input-textarea', + 'style': 'font-size:13px; resize: none', + 'readonly': 'readonly', + 'wrap': 'soft', + 'rows': '30' + }, [ res.trim() ]) + ); + } else { + log_modal.appendChild(E('p', _('错误'))); + log_modal.appendChild(E('pre', { 'class': 'errors' }, [ _('无法打印调试报告。') ])); + } + + var log_element = document.getElementById('content_debugLog') || null; + if (log_element) + log_element.scrollTop = log_element.scrollHeight; + + log_modal.appendChild(E('div', { 'class': 'right' }, [ + log_element ? E('button', { + 'class': 'btn cbi-button-action', + 'click': ui.createHandlerFn(this, function() { + var links = log_element.value.match(/https:\/\/(litter.catbox.moe|transfer.sh)\/.*.txt/g); + + var textarea = document.createElement('textarea'); + document.body.appendChild(textarea); + + textarea.style.position = 'absolute'; + textarea.style.clip = 'rect(0 0 0 0)'; + textarea.value = links ? links.join('\n'): log_element.value; + textarea.select() + + document.execCommand('copy', true); + document.body.removeChild(textarea); + }) + }, _('复制')) : '', + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('关闭')) + ])); + + return null; + }).catch(function (err) { + ui.addNotification(null, E('p', _('无法打印调试报告:%s。').format(err))); + ui.hideModal(); + + return null; + }); + } + + o = s.option(form.DummyValue, '_logview'); + o.render = function() { + /* Thanks to luci-app-aria2 */ + var css = ' \ + #log_textarea { \ + padding: 10px; \ + text-align: left; \ + } \ + #log_textarea pre { \ + padding: .5rem; \ + word-break: break-all; \ + margin: 0; \ + } \ + .description { \ + background-color: #33ccff; \ + }'; + + var log_textarea = E('div', { 'id': 'log_textarea' }, + E('img', { + 'src': L.resource(['icons/loading.gif']), + 'alt': _('Loading'), + 'style': 'vertical-align:middle' + }, _('Collecting data...')) + ); + + poll.add(L.bind(function() { + return fs.read('/tmp/unblockneteasemusic.log', 'text') + .then(function(res) { + var log = E('pre', { 'wrap': 'pre' }, [ + res.trim() || _('当前无日志。') + ]); + + dom.content(log_textarea, log); + }).catch(function(err) { + if (err.toString().includes('NotFoundError')) + var log = E('pre', { 'wrap': 'pre' }, [ + _('日志文件不存在。') + ]); + else + var log = E('pre', { 'wrap': 'pre' }, [ + _('未知错误:%s。').format(err) + ]); + + dom.content(log_textarea, log); + }); + })); + + return E([ + E('style', [ css ]), + E('div', {'class': 'cbi-map'}, [ + E('h3', {'name': 'content'}, _('运行日志')), + E('div', {'class': 'cbi-section'}, [ + log_textarea, + E('div', {'style': 'text-align:right'}, + E('small', {}, _('每 %s 秒刷新。').format(L.env.pollinterval)) + ) + ]) + ]) + ]); + } + + return m.render(); + }, + + handleSaveApply: null, + handleSave: null, + handleReset: null +}); diff --git a/luci-app-unblockneteasemusic/root/etc/config/unblockneteasemusic b/luci-app-unblockneteasemusic/root/etc/config/unblockneteasemusic new file mode 100644 index 000000000..5d61391b3 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/etc/config/unblockneteasemusic @@ -0,0 +1,12 @@ + +config unblockneteasemusic 'config' + option enable '0' + option music_source '' + option follow_source_order '0' + option local_vip '0' + option enable_flac '0' + option disable_upgrade_check '1' + option replace_music_source 'dont_replace' + option auto_update '1' + option update_time '3' + option advanced_mode '0' diff --git a/luci-app-unblockneteasemusic/root/etc/init.d/unblockneteasemusic b/luci-app-unblockneteasemusic/root/etc/init.d/unblockneteasemusic new file mode 100755 index 000000000..fa8e78a07 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/etc/init.d/unblockneteasemusic @@ -0,0 +1,242 @@ +#!/bin/sh /etc/rc.common +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2019-2023 Tianling Shen + +USE_PROCD=1 + +START=99 +STOP=10 + +NAME="unblockneteasemusic" +UPGRADE_CONF="/lib/upgrade/keep.d/$NAME" + +RULES_UC="/usr/share/$NAME/rules/default.uc" +RULES_NFT="/etc/nftables.d/90-$NAME-rules.nft" + +is_enabled() { + local enabled + config_get_bool enabled "$1" "$2" "${3:-0}" + if [ "$enabled" -eq "1" ]; then + return 0 + else + return 1 + fi +} + +append_param() { + procd_append_param command "$1" $2 +} + +append_param_arg() { + local value + config_get value "$1" "$2" $4 + [ -n "$value" ] && append_param "$3" "$value" +} + +append_param_env() { + local value + config_get value "$1" "$2" $4 + [ -n "$value" ] && procd_append_param env "$3"="$value" +} + +append_param_boolenv() { + is_enabled "$1" "$2" "$4" && procd_append_param env "$3"="true" +} + +append_filter_client() { + local cfg="$1" + + is_enabled "$cfg" "enable" || return 1 + + local ip_addr filter_mode + config_get ip_addr "$cfg" "ip_addr" + config_get filter_mode "$cfg" "filter_mode" + [ -n "$ip_addr" -a -n "$filter_mode" ] || return 1 + + case "${filter_mode}" in + "disable_http") + acl_http_addr="${acl_http_addr:+$acl_http_addr\n}${ip_addr}" + ;; + "disable_https") + acl_https_addr="${acl_https_addr:+$acl_https_addr\n}${ip_addr}" + ;; + "disable_all") + acl_http_addr="${acl_http_addr:+$acl_http_addr\n}${ip_addr}" + acl_https_addr="${acl_https_addr:+$acl_https_addr\n}${ip_addr}" + ;; + esac +} + +start_service() { + config_load "$NAME" + is_enabled "config" "enable" || return 1 + + local update_time + config_get update_time "config" "update_time" "3" + sed -i "/$NAME/d" /etc/crontabs/root + is_enabled "config" "auto_update" && echo "0 ${update_time} * * * /usr/share/$NAME/update.sh update_core" >> "/etc/crontabs/root" + echo "*/5 * * * * /usr/share/$NAME/log_check.sh" >> "/etc/crontabs/root" + /etc/init.d/cron restart + + [ ! -s "/usr/share/$NAME/core/app.js" ] && { rm -f "/usr/share/$NAME/local_ver"; sh "/usr/share/$NAME/update.sh" "update_core_non_restart"; } + [ ! -s "/usr/share/$NAME/core/app.js" ] && { echo "Core Not Found, please download it before starting." >> "/tmp/$NAME.log"; exit 1; } + + procd_open_instance "$NAME" + procd_set_param command node "/usr/share/$NAME/core/app.js" + append_param "-a" "0.0.0.0" + + local http_port https_port hijack_ways + config_get http_port "config" "http_port" "5200" + config_get https_port "config" "https_port" "5201" + config_get hijack_ways "config" "hijack_ways" "use_ipset" + append_param "-p" "${http_port}":"${https_port}" + + json_init + if is_enabled "config" "pub_access"; then + json_add_int o_pub_access "1" + else + json_add_int o_pub_access "0" + fi + json_add_int o_http_port "${http_port}" + json_add_int o_https_port "${https_port}" + json_add_string o_hijack_ways "${hijack_ways}" + + append_param_arg "config" "music_source" "-o" + append_param_arg "config" "cnrelay" "-c" + append_param_arg "config" "endpoint_url" "-e" "https://music.163.com" + append_param_arg "config" "netease_server_ip" "-f" + append_param_arg "config" "proxy_server_ip" "-u" + is_enabled "config" "strict_mode" && append_param "-s" + + local log_level + config_get log_level "config" "log_level" "info" + procd_set_param env LOG_FILE="/tmp/$NAME.log" + procd_append_param env LOG_LEVEL="$log_level" + + append_param_env "config" "joox_cookie" "JOOX_COOKIE" + append_param_env "config" "migu_cookie" "MIGU_COOKIE" + append_param_env "config" "qq_cookie" "QQ_COOKIE" + append_param_env "config" "youtube_key" "YOUTUBE_KEY" + append_param_env "config" "self_issue_cert_crt" "SIGN_CERT" "/usr/share/$NAME/core/server.crt" + append_param_env "config" "self_issue_cert_key" "SIGN_KEY" "/usr/share/$NAME/core/server.key" + + append_param_boolenv "config" "follow_source_order" "FOLLOW_SOURCE_ORDER" + append_param_boolenv "config" "search_album" "SEARCH_ALBUM" + append_param_boolenv "config" "enable_flac" "ENABLE_FLAC" + append_param_boolenv "config" "local_vip" "ENABLE_LOCAL_VIP" + append_param_boolenv "config" "disable_upgrade_check" "DISABLE_UPGRADE_CHECK" + case "$(config_get "config" "replace_music_source")" in + "lower_than_192kbps") procd_append_param env MIN_BR="192000" ;; + "lower_than_320kbps") procd_append_param env MIN_BR="320000" ;; + "lower_than_999kbps") procd_append_param env MIN_BR="600000" ;; + "replace_all") procd_append_param env MIN_BR="9999999" ;; + esac + + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param respawn + + local lan_addr="$(uci -q get network.lan.ipaddr)" + if [ "${hijack_ways}" = "use_ipset" ]; then + mkdir -p "/tmp/dnsmasq.d" + rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf" + cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf" + dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac + nftset=/.music.163.com/inet#fw4#neteasemusic + nftset=/interface.music.163.com/inet#fw4#neteasemusic + nftset=/interface3.music.163.com/inet#fw4#neteasemusic + nftset=/apm.music.163.com/inet#fw4#neteasemusic + nftset=/apm3.music.163.com/inet#fw4#neteasemusic + nftset=/clientlog.music.163.com/inet#fw4#neteasemusic + nftset=/clientlog3.music.163.com/inet#fw4#neteasemusic + EOF + /etc/init.d/dnsmasq reload + + config_foreach append_filter_client "acl_rule" + + local netease_music_ips="$(uclient-fetch -qO- "http://httpdns.n.netease.com/httpdns/v2/d?domain=music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com" |jsonfilter -e '@.data.*.ip.*')" + local netease_music_ips2="$(uclient-fetch -qO- "https://music.httpdns.c.163.com/d" --post-data="music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com" |jsonfilter -e '@.dns.*["ips"].*')" + local neteasemusic_addr="$(echo -e "${netease_music_ips}\n${netease_music_ips2}" | sort -u | awk '{print $1}')" + + json_add_string o_acl_http_addr "$(echo -e "${acl_http_addr}" | sort -u | awk '{print $1}')" + json_add_string o_acl_https_addr "$(echo -e "${acl_https_addr}" | sort -u | awk '{print $1}')" + json_add_string o_neteasemusic_addr "$neteasemusic_addr" + elif [ "${hijack_ways}" = "use_hosts" ]; then + mkdir -p "/tmp/dnsmasq.d" + rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf" + cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf" + dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac + address=/music.163.com/${lan_addr} + address=/interface.music.163.com/${lan_addr} + address=/interface3.music.163.com/${lan_addr} + address=/apm.music.163.com/${lan_addr} + address=/apm3.music.163.com/${lan_addr} + address=/clientlog.music.163.com/${lan_addr} + address=/clientlog3.music.163.com/${lan_addr} + address=/music.httpdns.c.163.com/0.0.0.0 + EOF + /etc/init.d/dnsmasq reload + + ip route add "223.252.199.10" dev lo + fi + + local nft_tmp="/tmp/$NAME" + json_dump -i > "$nft_tmp.json" + if utpl -F "$nft_tmp.json" -S "$RULES_UC" > "$nft_tmp.nft" && ! cmp -s "$nft_tmp.nft" "$RULES_NFT"; then + echo "table inet chk {include \"$nft_tmp.nft\";}" > "$nft_tmp.nft.chk" + ! nft -f "$nft_tmp.nft.chk" -c || { mv -f "$nft_tmp.nft" "$RULES_NFT"; fw4 reload; } + fi + rm -f "$nft_tmp.json" "$nft_tmp.nft" "$nft_tmp.nft.chk" + + procd_close_instance +} + +stop_service() { + config_load "$NAME" + + sed -i "/$NAME/d" "/etc/crontabs/root" + /etc/init.d/cron restart + + rm -f "${UPGRADE_CONF}" + is_enabled "config" "keep_core_when_upgrade" && { + echo "/usr/share/$NAME/core/" >> "${UPGRADE_CONF}" + echo "/usr/share/$NAME/local_ver" >> "${UPGRADE_CONF}" + } + + local self_issue_cert_crt self_issue_cert_key + config_get "self_issue_cert_crt" "config" "self_issue_cert_crt" + config_get "self_issue_cert_key" "config" "self_issue_cert_key" + { [ -f "${self_issue_cert_crt}" ] && [ -f "${self_issue_cert_key}" ]; } && { + echo "${self_issue_cert_crt}" >> "${UPGRADE_CONF}" + echo "${self_issue_cert_key}" >> "${UPGRADE_CONF}" + } + + local chain settable + for chain in "netease_cloud_music_redir" "netease_cloud_music"; do + nft flush chain inet fw4 "$chain" 2>"/dev/null" + done + for settable in "acl_neteasemusic_http" "acl_neteasemusic_https" "local_addr" "neteasemusic"; do + nft flush set inet fw4 "$settable" 2>"/dev/null" + done + + rm -f "$RULES_NFT" + fw4 reload + + + rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf" + /etc/init.d/dnsmasq reload + + ip route del "223.252.199.10" 2>"/dev/null" + + rm -f "/tmp/$NAME.log" +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "$NAME" +} diff --git a/luci-app-unblockneteasemusic/root/etc/uci-defaults/luci-unblockneteasemusic b/luci-app-unblockneteasemusic/root/etc/uci-defaults/luci-unblockneteasemusic new file mode 100644 index 000000000..6e01e6792 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/etc/uci-defaults/luci-unblockneteasemusic @@ -0,0 +1,22 @@ +#!/bin/sh + +if [ "$(uci -q get unblockneteasemusic.config.music_source)" = "default" ]; then + uci -q delete "unblockneteasemusic.config.music_source" + uci -q commit "unblockneteasemusic" +fi + +if [ "$(uci -q get unblockneteasemusic.config.hijack_ways)" = "use_hosts" ]; then + [ "$(uci -q get "unblockneteasemusic.config.http_port")" = "80" ] || { + uci -q set "unblockneteasemusic.config.http_port"="80" + uci -q set "unblockneteasemusic.config.https_port"="443" + uci -q commit "unblockneteasemusic" + } +fi + +uci -q batch <<-EOF >"/dev/null" + delete ucitrack.@unblockneteasemusic[-1] + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/luci-app-unblockneteasemusic/root/usr/bin/unm-debug b/luci-app-unblockneteasemusic/root/usr/bin/unm-debug new file mode 100755 index 000000000..b70bfd16d --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/bin/unm-debug @@ -0,0 +1,16 @@ +#!/bin/sh +# Copyright (C) 2021-2022 Tianling Shen + +command -v "curl" >"/dev/null" || { echo -e "curl is not found."; exit 1; } + +mkdir -p "/tmp" +/usr/share/unblockneteasemusic/debugging.sh 2>&1 | tee "/tmp/unm-debugging-output.txt" + +catbox_link="$(curl -fsS -F "reqtype=fileupload" -F "time=72h" -F "fileToUpload=@/tmp/unm-debugging-output.txt" "https://litterbox.catbox.moe/resources/internals/api.php")" +transfer_link="$(curl -fsS --upload-file "/tmp/unm-debugging-output.txt" "https://transfer.sh/unm-debugging-output.txt")" +echo -e "\n" +echo -e "Log is available at:" +echo -e "$catbox_link" +echo -e "$transfer_link" + +rm -f "/tmp/unm-debugging-output.txt" diff --git a/luci-app-unblockneteasemusic/root/usr/share/luci/menu.d/luci-app-unblockneteasemusic.json b/luci-app-unblockneteasemusic/root/usr/share/luci/menu.d/luci-app-unblockneteasemusic.json new file mode 100644 index 000000000..0ff75418b --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/luci/menu.d/luci-app-unblockneteasemusic.json @@ -0,0 +1,29 @@ +{ + "admin/services/unblockneteasemusic": { + "title": "解除网易云音乐播放限制", + "order": 50, + "action": { + "type": "firstchild" + }, + "depends": { + "acl": [ "luci-app-unblockneteasemusic" ], + "uci": { "unblockneteasemusic": true } + } + }, + "admin/services/unblockneteasemusic/config": { + "title": "基本设定", + "order": 10, + "action": { + "type": "view", + "path": "unblockneteasemusic/config" + } + }, + "admin/services/unblockneteasemusic/status": { + "title": "状态信息", + "order": 20, + "action": { + "type": "view", + "path": "unblockneteasemusic/status" + } + } +} diff --git a/luci-app-unblockneteasemusic/root/usr/share/rpcd/acl.d/luci-app-unblockneteasemusic.json b/luci-app-unblockneteasemusic/root/usr/share/rpcd/acl.d/luci-app-unblockneteasemusic.json new file mode 100644 index 000000000..5864f32d9 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/rpcd/acl.d/luci-app-unblockneteasemusic.json @@ -0,0 +1,25 @@ +{ + "luci-app-unblockneteasemusic": { + "description": "Grant access to UnblockNeteaseMusic configuration", + "read": { + "file": { + "/etc/init.d/unblockneteasemusic": [ "exec" ], + "/tmp/unblockneteasemusic.log": [ "read" ], + "/usr/bin/unm-debug": [ "exec" ], + "/usr/share/unblockneteasemusic/update.sh": [ "exec" ], + "/usr/share/unblockneteasemusic/core/ca.crt": [ "read" ] + }, + "ubus": { + "service": [ "list" ] + }, + "uci": [ "unblockneteasemusic" ] + }, + "write": { + "file": { + "/usr/share/unblockneteasemusic/server.crt": [ "write" ], + "/usr/share/unblockneteasemusic/server.key": [ "write" ] + }, + "uci": [ "unblockneteasemusic" ] + } + } +} diff --git a/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/debugging.sh b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/debugging.sh new file mode 100755 index 000000000..cdc8996c7 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/debugging.sh @@ -0,0 +1,104 @@ +#!/bin/sh +# Copyright (C) 2021-2022 Tianling Shen + +. /lib/functions.sh + +NAME="unblockneteasemusic" + +command -v "curl" >"/dev/null" || { echo -e "curl is not found."; exit 1; } + +echo -e "Launching luci-app-unblockneteasmusic Debugging Tool..." +echo -e "\n" + +echo -e "OpenWrt info:" +ubus call system board || cat "/etc/openwrt_release" +echo -e "\n" + +echo -e "uclient-fetch info:" +opkg info uclient-fetch +opkg info libustream-* +uclient-fetch -O- 'https://api.github.com/repos/UnblockNeteaseMusic/server/commits?sha=enhanced&path=precompiled' | jsonfilter -e '@[0].sha' || echo -e "Failed to connect to GitHub with uclient-fetch." +echo -e "\n" + +echo -e "Node.js info:" +opkg info node +echo -e "Node.js is placed at $(command -v node || echo "Not Found")" +echo -e "Node.js version: $(node -v 2>"/dev/null" || echo "Not Found")" +echo -e "\n" + +echo -e "luci-app-unblockneteasmusic info:" +opkg info "luci-app-unblockneteasemusic" +ls -lh "/etc/config/$NAME" "/etc/init.d/$NAME" "/usr/share/$NAME" +cat "/etc/config/$NAME" | sed -e "s,joox_cookie .*,joox_cookie 'set',g" \ + -e "s,migu_cookie .*,migu_cookie 'set',g" \ + -e "s,qq_cookie .*,qq_cookie 'set',g" \ + -e "s,youtube_key .*,youtube_key 'set',g" \ + -e "s,proxy_server_ip .*,proxy_server_ip 'set',g" +echo -e "\n" + +echo -e "UnblockNeteaseMusic Node.js info:" +echo -e "Git HEAD version: $(cat "/usr/share/$NAME/core_local_ver" 2>"/dev/null" || echo "Not Found")" +echo -e "Core version: $(node "/usr/share/$NAME/core/app.js" -v 2>"/dev/null" || echo "Not Found")" +ls -lh "/usr/share/$NAME/core" 2>"/dev/null" +echo -e "\n" + +echo -e "Netease networking info:" +curl -fsv "http://music.163.com/song/media/outer/url?id=641644.mp3" 2>&1 | grep "Location" || echo -e "Cannot connect to NeteaseMusic." +curl -sSL "http://httpdns.n.netease.com/httpdns/v2/d?domain=music.163.com" || echo -e "Cannot connect to Netease HTTPDNS." +config_load "$NAME" +config_get custom_proxy "config" "proxy_server_ip" +[ -n "$custom_proxy" ] && { curl -sL -x "$custom_proxy" "http://music.163.com/song/media/outer/url?id=641644.mp3" 2>&1 | grep "Location" || echo -e "Cannot connect to NeteaseMusic via proxy."; } +echo -e "\n" + +echo -e "Port status:" +config_get unm_port "config" "http_port" "5200" +config_get unm_ports "config" "https_port" "5201" +[ "$(config_get "config" "hijack_ways")" = "use_hosts" ] && { unm_port="80"; unm_ports="443"; } +netstat -tlpen | grep "$unm_port" || echo -e "No instance found on port $unm_port." +netstat -tlpen | grep "$unm_ports" || echo -e "No instance found on port $unm_ports." +echo -e "\n" + +echo -e "PROCD running info:" +running_stat="$(ubus call service list '{"name": "unblockneteasemusic", "verbose": true}' | \ + sed -e 's,"JOOX_COOKIE".*","JOOX_COOKIE": "set",g' \ + -e 's,"MIGU_COOKIE".*","MIGU_COOKIE": "set",g' \ + -e 's,"QQ_COOKIE".*","QQ_COOKIE": "set",g' \ + -e 's,"YOUTUBE_KEY".*","YOUTUBE_KEY": "set",g')" +[ "$(echo -e "$running_stat" | jsonfilter -e "@.$NAME.instances.$NAME.running")" == "true" ] || is_stopped=1 +echo -e "$running_stat" + +echo -e "\n" + +[ -n "$is_stopped" ] || { + echo -e "Firewall info:" + [ -e "/etc/nftables.d/90-$NAME-rules.nft" ] || echo -e 'netease_cloud_music nft rule file not found.' + echo -e "" + nft list set inet fw4 "acl_neteasemusic_http" 2>&1 + echo -e "" + nft list set inet fw4 "acl_neteasemusic_https" 2>&1 + echo -e "" + nft list set inet fw4 "local_addr" 2>&1 + echo -e "" + nft list set inet fw4 "neteasemusic" 2>&1 + echo -e "" + nft list chain inet fw4 "input_wan" | grep "unblockneteasemusic-http-" 2>"/dev/null" || echo -e 'Http Port pub access rule not found.' + echo -e "" + nft list chain inet fw4 "input_wan" | grep "unblockneteasemusic-https-" 2>"/dev/null" || echo -e 'Https Port pub access rule not found.' + echo -e "" + nft list chain inet fw4 "netease_cloud_music" 2>&1 + echo -e "" + nft list chain inet fw4 "netease_cloud_music_redir" 2>&1 + echo -e "" + cat "/tmp/dnsmasq.d/dnsmasq-$NAME.conf" + echo -e "\n" + + echo -e "Testing source replacing..." + lan_ip="$(uci -q get "network.lan.ipaddr" || echo "127.0.0.1")" + + curl -sSL -X "POST" "https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=" --data "params=bf3kf%2BOyalbxNS%2FeHAXquH8D2nt2YrhBzww4zy5rj2H%2BeAhdOIaGh4HHHzcoREFcu9Ve35LUgc%2BGE1YJD1HxrJ87ucm5zK%2FFn1lLvHFv1A8ZAuyU1afjG28s2Xja6zpfg00T0EcCeqkK61OpTfAaqw%3D%3D&encSecKey=6bab0dfa7ee3b292f9263a7af466636731cdbbd1d8747c9178c17477e70be899b7788c4a4e315c9fdb8c6e787603db6f9dff62c356f164d35b16b7f2d9ad5ede3cc7336130605521a8f916d308ce86b15c32b81c883ae2ba9c244444d91e1683be93fa0ea3e2a85207c9d693b86b5bb31adb002dd56c0bbcce9c73ec3bf5c105" + echo -e "" + curl -ksSL -X "POST" -x "http://$lan_ip:$unm_port" "https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=" --data "params=bf3kf%2BOyalbxNS%2FeHAXquH8D2nt2YrhBzww4zy5rj2H%2BeAhdOIaGh4HHHzcoREFcu9Ve35LUgc%2BGE1YJD1HxrJ87ucm5zK%2FFn1lLvHFv1A8ZAuyU1afjG28s2Xja6zpfg00T0EcCeqkK61OpTfAaqw%3D%3D&encSecKey=6bab0dfa7ee3b292f9263a7af466636731cdbbd1d8747c9178c17477e70be899b7788c4a4e315c9fdb8c6e787603db6f9dff62c356f164d35b16b7f2d9ad5ede3cc7336130605521a8f916d308ce86b15c32b81c883ae2ba9c244444d91e1683be93fa0ea3e2a85207c9d693b86b5bb31adb002dd56c0bbcce9c73ec3bf5c105" + echo -e "" +} + +cat "/tmp/$NAME.log" 2>"/dev/null" || echo -e "Log is not avaiable." diff --git a/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/log_check.sh b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/log_check.sh new file mode 100755 index 000000000..b236138c1 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/log_check.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-3.0-only +# Copyright (C) 2019-2022 Tianling Shen + +NAME="unblockneteasemusic" + +log_max_size="4" #使用KB计算 +log_file="/tmp/$NAME.log" + +log_size="$(expr $(ls -l "${log_file}" | awk -F ' ' '{print $5}') / "1024")" +[ "${log_size}" -lt "${log_max_size}" ] || echo "" > "${log_file}" diff --git a/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/chain.uc b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/chain.uc new file mode 100644 index 000000000..ee477c1f1 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/chain.uc @@ -0,0 +1,30 @@ +{% + +let http_port = o_http_port; +let https_port = o_https_port; +let pub_access = o_pub_access; +let hijack_ways = o_hijack_ways; + +%} + +{% if (pub_access == 1): %} +chain input_wan { + tcp dport {{ http_port }} counter accept comment "!fw4: unblockneteasemusic-http-pub-access" + tcp dport {{ https_port }} counter accept comment "!fw4: unblockneteasemusic-https-pub-access" +} +{% endif %} + +{% if (hijack_ways == "use_ipset"): %} +chain netease_cloud_music { + type nat hook prerouting priority -1; policy accept; + meta l4proto tcp ip daddr @neteasemusic jump netease_cloud_music_redir; +} + +chain netease_cloud_music_redir { + ip daddr @local_addr return; + ip saddr @acl_neteasemusic_http accept; + ip saddr @acl_neteasemusic_https accept; + tcp dport 80 counter redirect to :{{ http_port }}; + tcp dport 443 counter redirect to :{{ https_port }}; +} +{% endif %} diff --git a/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/default.uc b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/default.uc new file mode 100644 index 000000000..be6fb9ee1 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/default.uc @@ -0,0 +1,9 @@ +{% + +let hijack_ways = o_hijack_ways; +if (hijack_ways == "use_ipset") { + include("set.uc"); +} +include("chain.uc"); + +%} diff --git a/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/set.uc b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/set.uc new file mode 100644 index 000000000..b5895c849 --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/rules/set.uc @@ -0,0 +1,73 @@ +{% + +let o_local_bypass = " + 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.31.196.0/24 + 192.52.193.0/24 + 192.88.99.0/24 + 192.168.0.0/16 + 192.175.48.0/24 + 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 +"; + +let set_suffix = { + "acl_neteasemusic_http": { + str: o_acl_http_addr, + }, + "acl_neteasemusic_https": { + str: o_acl_https_addr, + }, + "local_addr": { + str: o_local_bypass, + }, + "neteasemusic": { + str: o_neteasemusic_addr, + }, +}; + +function set_elements_parse(res, str) { + for (let addr in split(str, /[ \t\n]/)) { + addr = trim(addr); + if (!addr) continue; + push(res, addr); + } +} + +function set_elements(suf) { + let obj = set_suffix[suf]; + let res = []; + let addr; + + let str = obj["str"]; + if (str) { + set_elements_parse(res, str); + } + + return res; +} +%} + +{% for (let suf in set_suffix): %} +set {{ suf }} { + type ipv4_addr; + flags interval; +{% let elems = set_elements(suf); if (length(elems)): %} + elements = { +{% for (let i = 0; i < length(elems); i++): %} + {{ elems[i] }}{% if (i < length(elems) - 1): %},{% endif %}{% print("\n") %} +{% endfor %} + } +{% endif %} +} +{% endfor %} diff --git a/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/update.sh b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/update.sh new file mode 100755 index 000000000..e8c108ede --- /dev/null +++ b/luci-app-unblockneteasemusic/root/usr/share/unblockneteasemusic/update.sh @@ -0,0 +1,104 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-3.0-only +# Copyright (C) 2019-2023 Tianling Shen + +NAME="unblockneteasemusic" +LOCK="/tmp/$NAME.update_core.lock" + +check_core_if_already_running() { + if [ -e "$LOCK" ]; then + echo -e "\nA task is already running." >> "/tmp/$NAME.log" + exit 2 + else + touch "$LOCK" + fi +} + +clean_log(){ + echo "" > "/tmp/$NAME.log" +} + +check_core_latest_version() { + core_latest_ver="$(uclient-fetch -qO- 'https://api.github.com/repos/UnblockNeteaseMusic/server/commits?sha=enhanced&path=precompiled' | jsonfilter -e '@[0].sha')" + [ -n "${core_latest_ver}" ] || { echo -e "\nFailed to check latest core version, please try again later." >> "/tmp/$NAME.log"; rm -f "$LOCK"; exit 1; } + if [ ! -e "/usr/share/$NAME/core_local_ver" ]; then + clean_log + echo -e "Local version: NOT FOUND, latest version: ${core_latest_ver}." >> "/tmp/$NAME.log" + update_core + else + if [ "$(cat /usr/share/$NAME/core_local_ver)" != "${core_latest_ver}" ]; then + clean_log + echo -e "Local version: $(cat /usr/share/$NAME/core_local_ver 2>"/dev/null"), latest version: ${core_latest_ver}." >> "/tmp/$NAME.log" + update_core + else + echo -e "\nLocal version: $(cat /usr/share/$NAME/core_local_ver 2>"/dev/null"), latest version: ${core_latest_ver}." >> "/tmp/$NAME.log" + echo -e "You're already using the latest version." >> "/tmp/$NAME.log" + rm -f "$LOCK" + exit 3 + fi + fi +} + +update_core() { + echo -e "Updating core..." >> "/tmp/$NAME.log" + + mkdir -p "/usr/share/$NAME/core" + rm -rf "/usr/share/$NAME/core"/* + + for file in $(uclient-fetch -qO- "https://api.github.com/repos/UnblockNeteaseMusic/server/contents/precompiled" | jsonfilter -e '@[*].path') + do + uclient-fetch "https://fastly.jsdelivr.net/gh/UnblockNeteaseMusic/server@$core_latest_ver/$file" -qO "/usr/share/$NAME/core/${file##*/}" + [ -s "/usr/share/$NAME/core/${file##*/}" ] || { + echo -e "Failed to download ${file##*/}." >> "/tmp/$NAME.log" + rm -f "$LOCK" + exit 1 + } + done + + for cert in "ca.crt" "server.crt" "server.key" + do + uclient-fetch "https://fastly.jsdelivr.net/gh/UnblockNeteaseMusic/server@enhanced/${cert}" -qO "/usr/share/$NAME/core/${cert}" + [ -s "/usr/share/$NAME/core/${cert}" ] || { + echo -e "Failed to download ${cert}." >> "/tmp/$NAME.log" + rm -f "$LOCK" + exit 1 + } + done + + echo -e "${core_latest_ver}" > "/usr/share/$NAME/core_local_ver" + [ -n "${non_restart}" ] || /etc/init.d/"$NAME" restart + + echo -e "Succeeded in updating core." > "/tmp/$NAME.log" + echo -e "Current core version: ${core_latest_ver}.\n" >> "/tmp/$NAME.log" + rm -f "$LOCK" +} + +case "$1" in + "check_version") + if [ ! -e "/usr/share/$NAME/core_local_ver" ] || [ ! -e "/usr/share/$NAME/core/app.js" ]; then + echo -e "Not installed." + exit 2 + else + version="$(node "/usr/share/$NAME/core/app.js" -v)" + commit="$(cat "/usr/share/$NAME/core_local_ver" | head -c7)" + echo "$version ($commit)" + exit 0 + fi + ;; + "update_core") + check_core_if_already_running + check_core_latest_version + ;; + "update_core_non_restart") + non_restart=1 + check_core_if_already_running + check_core_latest_version + ;; + "remove_core") + /etc/init.d/"$NAME" stop + rm -rf "/usr/share/$NAME/core" "/usr/share/$NAME/core_local_ver" "$LOCK" + ;; + *) + echo -e "Usage: $0/update.sh check_version | update_core | remove_core" + ;; +esac diff --git a/miniupnpd/Makefile b/miniupnpd/Makefile new file mode 100644 index 000000000..3d713fba2 --- /dev/null +++ b/miniupnpd/Makefile @@ -0,0 +1,80 @@ +# +# 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:=miniupnpd +PKG_VERSION:=2.0.20170421 +PKG_RELEASE:=3 + +PKG_SOURCE_URL:=http://miniupnp.tuxfamily.org/files +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_HASH:=9677aeccadf73b4bf8bb9d832c32b5da8266b4d58eed888f3fd43d7656405643 + +PKG_MAINTAINER:=Markus Stenberg +PKG_LICENSE:=BSD-3-Clause + +include $(INCLUDE_DIR)/package.mk + +define Package/miniupnpd + SECTION:=net + CATEGORY:=Network + DEPENDS:=+iptables +libip4tc +libuuid + TITLE:=Lightweight UPnP IGD, NAT-PMP & PCP daemon + SUBMENU:=Firewall + URL:=http://miniupnp.free.fr/ +endef + +define Package/miniupnpd/config +config MINIUPNPD_IGDv2 + bool + default n + prompt "Enable IGDv2" +endef + +define Package/miniupnpd/conffiles +/etc/config/upnpd +endef + +define Package/miniupnpd/postinst +#!/bin/sh + +if [ -z "$$IPKG_INSTROOT" ]; then + ( . /etc/uci-defaults/99-miniupnpd ) + rm -f /etc/uci-defaults/99-miniupnpd +fi + +exit 0 +endef + +define Build/Prepare + $(call Build/Prepare/Default) + echo "OpenWrt" | tr \(\)\ _ >$(PKG_BUILD_DIR)/os.openwrt +endef + +MAKE_FLAGS += \ + TARGET_OPENWRT=1 TEST=0 \ + LIBS="" \ + CC="$(TARGET_CC) -DIPTABLES_143 \ + -lip4tc -luuid" \ + CONFIG_OPTIONS="--portinuse --leasefile \ + $(if $(CONFIG_MINIUPNPD_IGDv2),--igd2)" \ + -f Makefile.linux \ + miniupnpd + + +define Package/miniupnpd/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config $(1)/etc/uci-defaults $(1)/etc/hotplug.d/iface $(1)/usr/share/miniupnpd + $(INSTALL_BIN) $(PKG_BUILD_DIR)/miniupnpd $(1)/usr/sbin/miniupnpd + $(INSTALL_BIN) ./files/miniupnpd.init $(1)/etc/init.d/miniupnpd + $(INSTALL_CONF) ./files/upnpd.config $(1)/etc/config/upnpd + $(INSTALL_DATA) ./files/miniupnpd.hotplug $(1)/etc/hotplug.d/iface/50-miniupnpd + $(INSTALL_DATA) ./files/miniupnpd.defaults $(1)/etc/uci-defaults/99-miniupnpd + $(INSTALL_DATA) ./files/firewall.include $(1)/usr/share/miniupnpd/firewall.include +endef + +$(eval $(call BuildPackage,miniupnpd)) diff --git a/miniupnpd/files/firewall.include b/miniupnpd/files/firewall.include new file mode 100644 index 000000000..0eb96d7cc --- /dev/null +++ b/miniupnpd/files/firewall.include @@ -0,0 +1,57 @@ +#!/bin/sh +# miniupnpd integration for firewall3 + +IP6TABLES=/usr/sbin/ip6tables + +iptables -t filter -N MINIUPNPD 2>/dev/null +iptables -t nat -N MINIUPNPD 2>/dev/null +iptables -t nat -N MINIUPNPD-POSTROUTING 2>/dev/null + +[ -x $IP6TABLES ] && $IP6TABLES -t filter -N MINIUPNPD 2>/dev/null + +. /lib/functions/network.sh + +ADDED=0 + +add_extzone_rules() { + local ext_zone=$1 + + [ -z "$ext_zone" ] && return + + # IPv4 - due to NAT, need to add both to nat and filter table + iptables -t filter -I zone_${ext_zone}_forward -j MINIUPNPD + iptables -t nat -I zone_${ext_zone}_prerouting -j MINIUPNPD + iptables -t nat -I zone_${ext_zone}_postrouting -j MINIUPNPD-POSTROUTING + + # IPv6 if available - filter only + [ -x $IP6TABLES ] && { + $IP6TABLES -t filter -I zone_${ext_zone}_forward -j MINIUPNPD + } + ADDED=$(($ADDED + 1)) +} + +# By default, user configuration is king. + +for ext_iface in $(uci -q get upnpd.config.external_iface); do + add_extzone_rules $(fw3 -q network "$ext_iface") +done + +add_extzone_rules $(uci -q get upnpd.config.external_zone) + +[ ! $ADDED = 0 ] && exit 0 + + +# If really nothing is available, resort to network_find_wan{,6} and +# assume external interfaces all have same firewall zone. + +# (This heuristic may fail horribly, in case of e.g. multihoming, so +# please set external_zone in that case!) + +network_find_wan wan_iface +network_find_wan6 wan6_iface + +for ext_iface in $wan_iface $wan6_iface; do + # fw3 -q network fails on sub-interfaces => map to device first + network_get_device ext_device $ext_iface + add_extzone_rules $(fw3 -q device "$ext_device") +done diff --git a/miniupnpd/files/miniupnpd.defaults b/miniupnpd/files/miniupnpd.defaults new file mode 100644 index 000000000..7271389d3 --- /dev/null +++ b/miniupnpd/files/miniupnpd.defaults @@ -0,0 +1,13 @@ +#!/bin/sh + +uci -q batch <<-EOT + delete firewall.miniupnpd + set firewall.miniupnpd=include + set firewall.miniupnpd.type=script + set firewall.miniupnpd.path=/usr/share/miniupnpd/firewall.include + set firewall.miniupnpd.family=any + set firewall.miniupnpd.reload=1 + commit firewall +EOT + +exit 0 diff --git a/miniupnpd/files/miniupnpd.hotplug b/miniupnpd/files/miniupnpd.hotplug new file mode 100644 index 000000000..320437e87 --- /dev/null +++ b/miniupnpd/files/miniupnpd.hotplug @@ -0,0 +1,39 @@ +#!/bin/sh + +/etc/init.d/miniupnpd enabled || exit 0 + +. /lib/functions/service.sh + +# If miniupnpd is not running: +# - check on _any_ event (even updates may contribute to network_find_wan*) + +# If miniupnpd _is_ running: +# - check only on ifup (otherwise lease updates etc would cause +# miniupnpd state loss) + +[ ! "$ACTION" = "ifup" ] && service_check /usr/sbin/miniupnpd && exit 0 + +tmpconf="/var/etc/miniupnpd.conf" +extiface=$(uci get upnpd.config.external_iface) +extzone=$(uci get upnpd.config.external_zone) + +. /lib/functions/network.sh + +for iface in $(uci get upnpd.config.internal_iface); do + network_get_device device $iface + [ "$DEVICE" = "$device" ] && /etc/init.d/miniupnpd restart && exit 0 +done + + +if [ -z "$extiface" ] ; then + # manual external zone (if dynamically find interfaces + # belonging to it) overrides network_find_wan* + if [ -n "$extzone" ] ; then + ifname=$(fw3 -q zone $extzone | head -1) + fi + [ -n "$extiface" ] || network_find_wan extiface + [ -n "$extiface" ] || network_find_wan6 extiface +fi + +[ -n "$ifname" ] || network_get_device ifname ${extiface} +grep -q "ext_ifname=$ifname" $tmpconf || /etc/init.d/miniupnpd restart diff --git a/miniupnpd/files/miniupnpd.init b/miniupnpd/files/miniupnpd.init new file mode 100644 index 000000000..c2b57e81a --- /dev/null +++ b/miniupnpd/files/miniupnpd.init @@ -0,0 +1,219 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2014 OpenWrt.org + +START=94 +STOP=15 + +USE_PROCD=1 +PROG=/usr/sbin/miniupnpd + +upnpd_get_port_range() { + local _var="$1"; shift + local _val + + config_get _val "$@" + + case "$_val" in + [0-9]*[:-][0-9]*) + export -n -- "${_var}_start=${_val%%[:-]*}" + export -n -- "${_var}_end=${_val##*[:-]}" + ;; + [0-9]*) + export -n -- "${_var}_start=$_val" + export -n -- "${_var}_end=" + ;; + esac +} + +conf_rule_add() { + local cfg="$1" + local tmpconf="$2" + local action external_port_start external_port_end int_addr + local internal_port_start internal_port_end + + config_get action "$cfg" action "deny" # allow or deny + upnpd_get_port_range "ext" "$cfg" ext_ports "0-65535" # external ports: x, x-y, x:y + config_get int_addr "$cfg" int_addr "0.0.0.0/0" # ip or network and subnet mask (internal) + upnpd_get_port_range "int" "$cfg" int_ports "0-65535" # internal ports: x, x-y, x:y or range + + # Make a single IP IP/32 so that miniupnpd.conf can use it. + case "$int_addr" in + */*) ;; + *) int_addr="$int_addr/32" ;; + esac + + echo "${action} ${ext_start}${ext_end:+-}${ext_end} ${int_addr} ${int_start}${int_end:+-}${int_end}" >>$tmpconf +} + +upnpd_write_bool() { + local opt="$1" + local def="${2:-0}" + local alt="$3" + local val + + config_get_bool val config "$opt" "$def" + if [ "$val" -eq 0 ]; then + echo "${alt:-$opt}=no" >> $tmpconf + else + echo "${alt:-$opt}=yes" >> $tmpconf + fi +} + +boot() { + return +} + +upnpd() { + config_load "upnpd" + local extiface intiface upload download logging secure enabled natpmp + local extip port usesysuptime conffile serial_number model_number + local uuid notify_interval presentation_url enable_upnp + local upnp_lease_file clean_ruleset_threshold clean_ruleset_interval + local ipv6_listening_ip enabled + + config_get_bool enabled config enabled 1 + + [ "$enabled" -gt 0 ] || return 1 + + config_get extiface config external_iface + config_get extzone config external_zone + config_get intiface config internal_iface + config_get extip config external_ip + config_get port config port 5000 + config_get upload config upload + config_get download config download + config_get_bool logging config log_output 0 + config_get conffile config config_file + config_get serial_number config serial_number + config_get model_number config model_number + config_get uuid config uuid + config_get notify_interval config notify_interval + config_get presentation_url config presentation_url + config_get upnp_lease_file config upnp_lease_file + config_get clean_ruleset_threshold config clean_ruleset_threshold + config_get clean_ruleset_interval config clean_ruleset_interval + config_get ipv6_listening_ip config ipv6_listening_ip + + local args + + . /lib/functions/network.sh + + local ifname + + # manual external interface overrides everything + if [ -z "$extiface" ] ; then + # manual external zone (if dynamically find interfaces + # belonging to it) overrides network_find_wan* + if [ -n "$extzone" ] ; then + ifname=$(fw3 -q zone $extzone | head -1) + fi + [ -n "$extiface" ] || network_find_wan extiface + [ -n "$extiface" ] || network_find_wan6 extiface + fi + + [ -n "$ifname" ] || network_get_device ifname ${extiface} + + if [ -n "$conffile" ]; then + args="-f $conffile" + else + local tmpconf="/var/etc/miniupnpd.conf" + args="-f $tmpconf" + mkdir -p /var/etc + + echo "ext_ifname=$ifname" >$tmpconf + + [ -n "$extip" ] && \ + echo "ext_ip=$extip" >>$tmpconf + + local iface + for iface in ${intiface:-lan}; do + local device + network_get_device device "$iface" && { + echo "listening_ip=$device" >>$tmpconf + } + done + + [ "$port" != "auto" ] && \ + echo "port=$port" >>$tmpconf + + config_load "upnpd" + upnpd_write_bool enable_natpmp 1 + upnpd_write_bool enable_upnp 1 + upnpd_write_bool secure_mode 1 + upnpd_write_bool pcp_allow_thirdparty 0 + upnpd_write_bool system_uptime 1 + + [ -n "$upnp_lease_file" ] && \ + echo "lease_file=$upnp_lease_file" >>$tmpconf + + [ -n "$upload" -a -n "$download" ] && { + echo "bitrate_down=$(($download * 1024 * 8))" >>$tmpconf + echo "bitrate_up=$(($upload * 1024 * 8))" >>$tmpconf + } + + [ -n "${presentation_url}" ] && \ + echo "presentation_url=${presentation_url}" >>$tmpconf + + [ -n "${notify_interval}" ] && \ + echo "notify_interval=${notify_interval}" >>$tmpconf + + [ -n "${clean_ruleset_threshold}" ] && \ + echo "clean_ruleset_threshold=${clean_ruleset_threshold}" >>$tmpconf + + [ -n "${clean_ruleset_interval}" ] && \ + echo "clean_ruleset_interval=${clean_ruleset_interval}" >>$tmpconf + + [ -n "${ipv6_listening_ip}" ] && \ + echo "ipv6_listening_ip=${ipv6_listening_ip}" >>$tmpconf + + [ -z "$uuid" ] && { + uuid="$(cat /proc/sys/kernel/random/uuid)" + uci set upnpd.config.uuid=$uuid + uci commit upnpd + } + + [ "$uuid" = "nocli" ] || \ + echo "uuid=$uuid" >>$tmpconf + + [ -n "${serial_number}" ] && \ + echo "serial=${serial_number}" >>$tmpconf + + [ -n "${model_number}" ] && \ + echo "model_number=${model_number}" >>$tmpconf + + config_foreach conf_rule_add perm_rule "$tmpconf" + fi + + + if [ -n "$ifname" ]; then + # start firewall + iptables -L MINIUPNPD >/dev/null 2>/dev/null || fw3 reload + else + logger -t "upnp daemon" "external interface not found, not starting" + fi + + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn + procd_append_param command -f "$tmpconf" + [ "$log_output" = "1" ] && procd_append_param command -d + procd_close_instance +} + +stop_service() { + iptables -t nat -F MINIUPNPD 2>/dev/null + iptables -t filter -F MINIUPNPD 2>/dev/null + + [ -x /usr/sbin/ip6tables ] && { + ip6tables -t filter -F MINIUPNPD 2>/dev/null + } +} + +start_service() { + config_load "upnpd" + config_foreach upnpd "upnpd" +} + +service_triggers() { + procd_add_reload_trigger "upnpd" +} diff --git a/miniupnpd/files/upnpd.config b/miniupnpd/files/upnpd.config new file mode 100644 index 000000000..9a65bfa63 --- /dev/null +++ b/miniupnpd/files/upnpd.config @@ -0,0 +1,27 @@ +config upnpd config + option enabled 0 + option enable_natpmp 1 + option enable_upnp 1 + option secure_mode 1 + option log_output 0 + option download 1024 + option upload 512 + #by default, looked up dynamically from ubus + #option external_iface wan + option internal_iface lan + option port 5000 + option upnp_lease_file /var/upnp.leases + +config perm_rule + option action allow + option ext_ports 1024-65535 + option int_addr 0.0.0.0/0 # Does not override secure_mode + option int_ports 1024-65535 + option comment "Allow high ports" + +config perm_rule + option action deny + option ext_ports 0-65535 + option int_addr 0.0.0.0/0 + option int_ports 0-65535 + option comment "Default deny" diff --git a/miniupnpd/patches/100-no-daemon.patch b/miniupnpd/patches/100-no-daemon.patch new file mode 100644 index 000000000..42c2cccc5 --- /dev/null +++ b/miniupnpd/patches/100-no-daemon.patch @@ -0,0 +1,25 @@ +--- a/miniupnpd.c ++++ b/miniupnpd.c +@@ -1727,21 +1727,7 @@ init(int argc, char * * argv, struct runtime_vars * v) + } + } + +- if(debug_flag) +- { +- pid = getpid(); +- } +- else +- { +-#ifdef USE_DAEMON +- if(daemon(0, 0)<0) { +- perror("daemon()"); +- } +- pid = getpid(); +-#else +- pid = daemonize(); +-#endif +- } ++ pid = getpid(); + + openlog_option = LOG_PID|LOG_CONS; + if(debug_flag) diff --git a/miniupnpd/patches/101-no-ssl-uuid.patch b/miniupnpd/patches/101-no-ssl-uuid.patch new file mode 100644 index 000000000..81cea1046 --- /dev/null +++ b/miniupnpd/patches/101-no-ssl-uuid.patch @@ -0,0 +1,23 @@ +We do not need to autodetect SSL/UUID; SSL we do not support, UUID we always do. + +--- a/Makefile.linux ++++ b/Makefile.linux +@@ -153,14 +153,18 @@ LDLIBS += $(shell $(PKG_CONFIG) --static + LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libnetfilter_conntrack) + endif # ($(TEST),1) + ++ifeq ($(TARGET_OPENWRT),) ++# n/a - we don't enable https server for IGD v2 anyway in OpenWrt + LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libssl) + ++# n/a - we hardcodedly support libuuid + TEST := $(shell $(PKG_CONFIG) --exists uuid && echo 1) + ifeq ($(TEST),1) + LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l uuid) + else + $(info please install uuid-dev package / libuuid) + endif # ($(TEST),1) ++endif + + TESTUPNPDESCGENOBJS = testupnpdescgen.o upnpdescgen.o + diff --git a/miniupnpd/patches/102-ipv6-ext-port.patch b/miniupnpd/patches/102-ipv6-ext-port.patch new file mode 100644 index 000000000..806c7fd5a --- /dev/null +++ b/miniupnpd/patches/102-ipv6-ext-port.patch @@ -0,0 +1,10 @@ +--- a/pcpserver.c ++++ b/pcpserver.c +@@ -982,6 +982,7 @@ static int CreatePCPMap_NAT(pcp_info_t * + timestamp); + if (r < 0) + return PCP_ERR_NO_RESOURCES; ++ pcp_msg_info->ext_port = pcp_msg_info->int_port; + return PCP_SUCCESS; + } + diff --git a/miniupnpd/patches/103-no-ipv6-autodetection.patch b/miniupnpd/patches/103-no-ipv6-autodetection.patch new file mode 100644 index 000000000..50d5a392b --- /dev/null +++ b/miniupnpd/patches/103-no-ipv6-autodetection.patch @@ -0,0 +1,27 @@ +The miniupnpd makefile tries to autodetect iptables capabilities. +This will incorrectly detect capabilities such as ipv6 support even though it is disabled for the target build. + +As the OpenWRT buildsystem already passes the right compile flags, we can skip the autodetection. + + +--- a/netfilter/Makefile ++++ b/netfilter/Makefile +@@ -38,8 +38,6 @@ endif + endif + endif + +-LIBS += /lib/libip4tc.so /lib/libip6tc.so +- + all: iptcrdr.o testiptcrdr iptpinhole.o \ + testiptcrdr_peer testiptcrdr_dscp test_nfct_get + # testiptpinhole +--- a/Makefile.linux ++++ b/Makefile.linux +@@ -73,7 +73,6 @@ CPPFLAGS += -DIPTABLES_143 + endif + + CFLAGS += $(shell $(PKG_CONFIG) --cflags libiptc) +-LDLIBS += $(shell $(PKG_CONFIG) --static --libs-only-l libiptc) + LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L libiptc) + LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-other libiptc) + else diff --git a/miniupnpd/patches/104-always-libuuid.patch b/miniupnpd/patches/104-always-libuuid.patch new file mode 100644 index 000000000..d6c077042 --- /dev/null +++ b/miniupnpd/patches/104-always-libuuid.patch @@ -0,0 +1,20 @@ +As it turns out, the 'magic' libuuid/bsd uuid check just checks +outside buildtree altogether for the uuid_generate. So we just +hardcode it. + +--- a/genconfig.sh ++++ b/genconfig.sh +@@ -367,12 +367,7 @@ case $FW in + esac + + # UUID API +-if grep uuid_create /usr/include/uuid.h > /dev/null 2>&1 ; then +- echo "#define BSD_UUID" >> ${CONFIGFILE} +-fi +-if grep uuid_generate /usr/include/uuid/uuid.h > /dev/null 2>&1 ; then +- echo "#define LIB_UUID" >> ${CONFIGFILE} +-fi ++echo "#define LIB_UUID" >> ${CONFIGFILE} + + # set V6SOCKETS_ARE_V6ONLY to 0 if it was not set above + if [ -z "$V6SOCKETS_ARE_V6ONLY" ] ; then diff --git a/miniupnpd/patches/105-build-with-kernel-5.4.patch b/miniupnpd/patches/105-build-with-kernel-5.4.patch new file mode 100644 index 000000000..acd1604d4 --- /dev/null +++ b/miniupnpd/patches/105-build-with-kernel-5.4.patch @@ -0,0 +1,90 @@ +--- a/netfilter/iptcrdr.c ++++ b/netfilter/iptcrdr.c +@@ -1116,9 +1116,13 @@ addnatrule(int proto, unsigned short epo + } else { + match = get_udp_match(eport, 0); + } +- e->nfcache = NFC_IP_DST_PT; ++#ifdef NFC_UNKNOWN ++ e->nfcache = NFC_UNKNOWN; ++#endif + target = get_dnat_target(iaddr, iport); +- e->nfcache |= NFC_UNKNOWN; ++#ifdef NFC_IP_DST_PT ++ e->nfcache |= NFC_IP_DST_PT; ++#endif + tmp = realloc(e, sizeof(struct ipt_entry) + + match->u.match_size + + target->u.target_size); +@@ -1186,9 +1190,13 @@ addmasqueraderule(int proto, + } else { + match = get_udp_match(0, iport); + } +- e->nfcache = NFC_IP_DST_PT; ++#ifdef NFC_UNKNOWN ++ e->nfcache = NFC_UNKNOWN; ++#endif + target = get_masquerade_target(eport); +- e->nfcache |= NFC_UNKNOWN; ++#ifdef NFC_IP_DST_PT ++ e->nfcache |= NFC_IP_DST_PT; ++#endif + tmp = realloc(e, sizeof(struct ipt_entry) + + match->u.match_size + + target->u.target_size); +@@ -1266,9 +1274,16 @@ addpeernatrule(int proto, + } else { + match = get_udp_match(rport, iport); + } +- e->nfcache = NFC_IP_DST_PT | NFC_IP_SRC_PT; ++#ifdef NFC_UNKNOWN ++ e->nfcache = NFC_UNKNOWN; ++#endif + target = get_snat_target(eaddr, eport); +- e->nfcache |= NFC_UNKNOWN; ++#ifdef NFC_IP_DST_PT ++ e->nfcache |= NFC_IP_DST_PT; ++#endif ++#ifdef NFC_IP_SRC_PT ++ e->nfcache |= NFC_IP_SRC_PT; ++#endif + tmp = realloc(e, sizeof(struct ipt_entry) + + match->u.match_size + + target->u.target_size); +@@ -1337,9 +1352,16 @@ addpeerdscprule(int proto, unsigned char + } else { + match = get_udp_match(rport, iport); + } +- e->nfcache = NFC_IP_DST_PT | NFC_IP_SRC_PT; ++#ifdef NFC_UNKNOWN ++ e->nfcache = NFC_UNKNOWN; ++#endif + target = get_dscp_target(dscp); +- e->nfcache |= NFC_UNKNOWN; ++#ifdef NFC_IP_DST_PT ++ e->nfcache |= NFC_IP_DST_PT; ++#endif ++#ifdef NFC_IP_SRC_PT ++ e->nfcache |= NFC_IP_SRC_PT; ++#endif + tmp = realloc(e, sizeof(struct ipt_entry) + + match->u.match_size + + target->u.target_size); +@@ -1420,11 +1442,15 @@ add_filter_rule(int proto, const char * + } else { + match = get_udp_match(iport,0); + } +- e->nfcache = NFC_IP_DST_PT; + e->ip.dst.s_addr = inet_addr(iaddr); + e->ip.dmsk.s_addr = INADDR_NONE; ++#ifdef NFC_UNKNOWN ++ e->nfcache = NFC_UNKNOWN; ++#endif + target = get_accept_target(); +- e->nfcache |= NFC_UNKNOWN; ++#ifdef NFC_IP_DST_PT ++ e->nfcache |= NFC_IP_DST_PT; ++#endif + tmp = realloc(e, sizeof(struct ipt_entry) + + match->u.match_size + + target->u.target_size); diff --git a/miniupnpd/patches/106-spam-syslog-ignoring.patch b/miniupnpd/patches/106-spam-syslog-ignoring.patch new file mode 100644 index 000000000..1e755ea92 --- /dev/null +++ b/miniupnpd/patches/106-spam-syslog-ignoring.patch @@ -0,0 +1,13 @@ +--- a/minissdp.c 2017-04-21 19:24:23.000000000 +0800 ++++ b/minissdp.c 2021-06-22 07:01:24.000000000 +0800 +@@ -865,8 +865,8 @@ + lan_addr = get_lan_for_peer(sender); + if(lan_addr == NULL) + { +- syslog(LOG_WARNING, "SSDP packet sender %s not from a LAN, ignoring", +- sender_str); ++ /* syslog(LOG_WARNING, "SSDP packet sender %s not from a LAN, ignoring", ++ sender_str); */ + return; + } + diff --git a/msd_lite/Makefile b/msd_lite/Makefile new file mode 100644 index 000000000..cdbb8d7a9 --- /dev/null +++ b/msd_lite/Makefile @@ -0,0 +1,51 @@ +# +# 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:=msd_lite +PKG_VERSION:=1.10 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-04-17 +PKG_SOURCE_URL:=https://github.com/rozhuk-im/msd_lite.git +PKG_SOURCE_VERSION:=e254782c0f2199f5351cc7dae1d0be3ebaa5a7f0 +PKG_MIRROR_HASH:=dc6d9d4e3cc498238460a0599008713d97882020fe514f46156c0fec8d87fdc6 + +PKG_LICENSE:=BSD-2-Clause +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/msd_lite + SECTION:=net + CATEGORY:=Network + TITLE:=Multi Stream daemon Lite + URL:=https://github.com/rozhuk-im/msd_litea + DEPENDS:= +libpthread +endef + +define Package/msd_lite/description +Program for IP TV streaming on the network via HTTP +endef + +define Package/msd_lite/conffiles +/etc/msd_lite/msd_lite.conf +endef + +CMAKE_OPTIONS += \ + -DCONFDIR=/etc/msd_lite + +define Package/msd_lite/install + $(INSTALL_DIR) $(1)/etc/msd_lite $(1)/usr/bin + $(INSTALL_CONF) $(PKG_BUILD_DIR)/conf/msd_lite.conf $(1)/etc/msd_lite/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/msd_lite $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,msd_lite)) diff --git a/msd_lite/patches/001-ignore-install.patch b/msd_lite/patches/001-ignore-install.patch new file mode 100644 index 000000000..09a72bfb3 --- /dev/null +++ b/msd_lite/patches/001-ignore-install.patch @@ -0,0 +1,11 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -234,7 +234,7 @@ + ##################### INSTALLATION ##################################### + + # Configs +-install(CODE "FILE(MAKE_DIRECTORY ${CONFDIR})") ++#install(CODE "FILE(MAKE_DIRECTORY ${CONFDIR})") + + install_if_not_exists(conf/msd_lite.conf ${CONFDIR} "msd_lite.conf" ".sample") + diff --git a/mwan3/Makefile b/mwan3/Makefile new file mode 100644 index 000000000..f4d03e63d --- /dev/null +++ b/mwan3/Makefile @@ -0,0 +1,68 @@ +# +# 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:=mwan3 +PKG_VERSION:=2.8.8 +PKG_RELEASE:=2 +PKG_MAINTAINER:=Florian Eckert +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/mwan3 + SECTION:=net + CATEGORY:=Network + SUBMENU:=Routing and Redirection + DEPENDS:= \ + +ip \ + +ipset \ + +iptables \ + +iptables-mod-conntrack-extra \ + +iptables-mod-ipopt \ + +jshn + TITLE:=Multiwan hotplug script with connection tracking support + MAINTAINER:=Florian Eckert + PKGARCH:=all +endef + +define Package/mwan3/description +Hotplug script which makes configuration of multiple WAN interfaces simple +and manageable. With loadbalancing/failover support for up to 250 wan +interfaces, connection tracking and an easy to manage traffic ruleset. +endef + +define Package/mwan3/conffiles +/etc/config/mwan3 +/etc/mwan3.user +endef + +define Build/Compile +endef + +define Package/mwan3/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/rpcd restart +fi +exit 0 +endef + +define Package/mwan3/postrm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/rpcd restart +fi +exit 0 +endef + +define Package/mwan3/install +$(CP) ./files/* $(1) +endef + +$(eval $(call BuildPackage,mwan3)) diff --git a/mwan3/files/etc/config/mwan3 b/mwan3/files/etc/config/mwan3 new file mode 100644 index 000000000..22c9c6d80 --- /dev/null +++ b/mwan3/files/etc/config/mwan3 @@ -0,0 +1,23 @@ + +config globals 'globals' + option mmx_mask '0x3F00' + option rtmon_interval '5' + +config member 'wan_m1_w3' + option interface 'wan' + option metric '1' + option weight '3' + +config policy 'balanced' + option last_resort 'default' + list use_member 'wan_m1_w3' + +config rule 'https' + option sticky '1' + option dest_port '443' + option proto 'tcp' + option use_policy 'balanced' + +config rule 'default_rule' + option dest_ip '0.0.0.0/0' + option use_policy 'balanced' diff --git a/mwan3/files/etc/hotplug.d/iface/15-mwan3 b/mwan3/files/etc/hotplug.d/iface/15-mwan3 new file mode 100644 index 000000000..5bfbd2462 --- /dev/null +++ b/mwan3/files/etc/hotplug.d/iface/15-mwan3 @@ -0,0 +1,94 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh +. /usr/share/libubox/jshn.sh + +[ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1 +[ -n "$INTERFACE" ] || exit 2 + +if [ "$ACTION" == "ifup" ]; then + [ -n "$DEVICE" ] || exit 3 +fi + +config_load mwan3 +config_get_bool enabled globals 'enabled' '0' +[ ${enabled} -gt 0 ] || exit 0 + +mwan3_lock "$ACTION" "$INTERFACE" +mwan3_init +mwan3_set_connected_iptables +mwan3_set_custom_ipset +mwan3_unlock "$ACTION" "$INTERFACE" + +config_get enabled $INTERFACE enabled 0 +config_get initial_state $INTERFACE initial_state "online" +[ "$enabled" == "1" ] || exit 0 + +if [ "$ACTION" == "ifup" ]; then + config_get family $INTERFACE family ipv4 + if [ "$family" = "ipv4" ]; then + ubus call network.interface.${INTERFACE}_4 status &>/dev/null + if [ "$?" -eq "0" ]; then + network_get_ipaddr src_ip ${INTERFACE}_4 + else + network_get_ipaddr src_ip ${INTERFACE} + fi + [ -n "$src_ip" ] || src_ip="0.0.0.0" + elif [ "$family" = "ipv6" ]; then + ubus call network.interface.${INTERFACE}_6 status &>/dev/null + if [ "$?" -eq "0" ]; then + network_get_ipaddr6 src_ip ${INTERFACE}_6 + else + network_get_ipaddr6 src_ip ${INTERFACE} + fi + [ -n "$src_ip" ] || src_ip="::" + fi +fi + +if [ "$initial_state" = "offline" ]; then + json_load "$(ubus call mwan3 status '{"section":"interfaces"}')" + json_select "interfaces" + json_select "${INTERFACE}" + json_get_var running running + json_get_var status status +else + status=online + running=1 +fi + +mwan3_lock "$ACTION" "$INTERFACE" +$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})" + +case "$ACTION" in + ifup) + mwan3_set_general_rules + mwan3_set_general_iptables + mwan3_create_iface_iptables $INTERFACE $DEVICE + mwan3_create_iface_rules $INTERFACE $DEVICE + mwan3_create_iface_route $INTERFACE $DEVICE + if [ ${running} -eq 1 -a "${status}" = "online" ]; then + $LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})" + mwan3_set_iface_hotplug_state $INTERFACE "online" + mwan3_track $INTERFACE $DEVICE "online" "$src_ip" + else + $LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})" + mwan3_set_iface_hotplug_state $INTERFACE "offline" + mwan3_track $INTERFACE $DEVICE "offline" "$src_ip" + fi + mwan3_set_policies_iptables + mwan3_set_user_rules + ;; + ifdown) + mwan3_set_iface_hotplug_state $INTERFACE "offline" + mwan3_delete_iface_ipset_entries $INTERFACE + mwan3_track_signal $INTERFACE $DEVICE + mwan3_set_policies_iptables + mwan3_set_user_rules + ;; +esac + +mwan3_unlock "$ACTION" "$INTERFACE" + +exit 0 diff --git a/mwan3/files/etc/hotplug.d/iface/16-mwan3 b/mwan3/files/etc/hotplug.d/iface/16-mwan3 new file mode 100644 index 000000000..c243d55ff --- /dev/null +++ b/mwan3/files/etc/hotplug.d/iface/16-mwan3 @@ -0,0 +1,22 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh + +config_load mwan3 +config_get_bool enabled globals 'enabled' '0' +[ ${enabled} -gt 0 ] || exit 0 + +if [ "$ACTION" == "ifup" ]; then + mwan3_lock "$ACTION" "mwan3rtmon" + mwan3_rtmon + mwan3_unlock "$ACTION" "mwan3rtmon" +fi + +config_get enabled $INTERFACE enabled 0 +[ "${enabled}" = "0" ] || { + mwan3_flush_conntrack "$INTERFACE" "$ACTION" +} + +exit 0 diff --git a/mwan3/files/etc/hotplug.d/iface/16-mwan3-user b/mwan3/files/etc/hotplug.d/iface/16-mwan3-user new file mode 100644 index 000000000..9372c736e --- /dev/null +++ b/mwan3/files/etc/hotplug.d/iface/16-mwan3-user @@ -0,0 +1,16 @@ +#!/bin/sh + +[ -f "/etc/mwan3.user" ] && { + . /lib/functions.sh + + config_load mwan3 + config_get_bool enabled globals 'enabled' '0' + [ ${enabled} -gt 0 ] || exit 0 + + config_get enabled "$INTERFACE" enabled 0 + [ "${enabled}" = "1" ] || exit 0 + env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \ + /bin/sh /etc/mwan3.user +} + +exit 0 diff --git a/mwan3/files/etc/init.d/mwan3 b/mwan3/files/etc/init.d/mwan3 new file mode 100755 index 000000000..af750e55e --- /dev/null +++ b/mwan3/files/etc/init.d/mwan3 @@ -0,0 +1,28 @@ +#!/bin/sh /etc/rc.common + +START=19 +USE_PROCD=1 + +boot() { + . /lib/config/uci.sh + uci_toggle_state mwan3 globals enabled "1" + mwan3_boot=1 + rc_procd start_service +} + +reload_service() { + /usr/sbin/mwan3 restart +} + +start_service() { + [ -n "${mwan3_boot}" ] && return 0 + /usr/sbin/mwan3 start +} + +stop_service() { + /usr/sbin/mwan3 stop +} + +service_triggers() { + procd_add_reload_trigger 'mwan3' +} diff --git a/mwan3/files/etc/mwan3.user b/mwan3/files/etc/mwan3.user new file mode 100644 index 000000000..39989ab9b --- /dev/null +++ b/mwan3/files/etc/mwan3.user @@ -0,0 +1,16 @@ +#!/bin/sh +# +# This file is interpreted as shell script. +# Put your custom mwan3 action here, they will +# be executed with each netifd hotplug interface event +# on interfaces for which mwan3 is enabled. +# +# There are three main environment variables that are passed to this script. +# +# $ACTION +# Is called by netifd and mwan3track +# Is called by netifd and mwan3track +# Is only called by mwan3track if tracking was successful +# Is only called by mwan3track if tracking has failed +# $INTERFACE Name of the interface which went up or down (e.g. "wan" or "wwan") +# $DEVICE Physical device name which interface went up or down (e.g. "eth0" or "wwan0") diff --git a/mwan3/files/etc/uci-defaults/mwan3-migrate-flush_conntrack b/mwan3/files/etc/uci-defaults/mwan3-migrate-flush_conntrack new file mode 100644 index 000000000..1691efa2d --- /dev/null +++ b/mwan3/files/etc/uci-defaults/mwan3-migrate-flush_conntrack @@ -0,0 +1,26 @@ +#!/bin/sh + +. /lib/functions.sh + +mwan3_migrate_flush_conntrack() { + local iface="$1" + + config_get value "${iface}" flush_conntrack + case $value in + always) + uci_remove mwan3 "$iface" flush_conntrack + uci_add_list mwan3 "$iface" flush_conntrack ifup + uci_add_list mwan3 "$iface" flush_conntrack ifdown + ;; + never) + uci_remove mwan3 "$iface" flush_conntrack + ;; + esac + + uci_commit mwan3 +} + +config_load mwan3 +config_foreach mwan3_migrate_flush_conntrack interface + +exit 0 diff --git a/mwan3/files/lib/mwan3/common.sh b/mwan3/files/lib/mwan3/common.sh new file mode 100644 index 000000000..1af129919 --- /dev/null +++ b/mwan3/files/lib/mwan3/common.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +get_uptime() { + local uptime=$(cat /proc/uptime) + echo "${uptime%%.*}" +} diff --git a/mwan3/files/lib/mwan3/mwan3.sh b/mwan3/files/lib/mwan3/mwan3.sh new file mode 100644 index 000000000..64b07d658 --- /dev/null +++ b/mwan3/files/lib/mwan3/mwan3.sh @@ -0,0 +1,1207 @@ +#!/bin/sh + +IP4="ip -4" +IP6="ip -6" +IPS="ipset" +IPT4="iptables -t mangle -w" +IPT6="ip6tables -t mangle -w" +LOG="logger -t mwan3[$$] -p" +CONNTRACK_FILE="/proc/net/nf_conntrack" +IPv6_REGEX="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,7}:|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" +IPv6_REGEX="${IPv6_REGEX}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" +IPv6_REGEX="${IPv6_REGEX}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" +IPv6_REGEX="${IPv6_REGEX}fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|" +IPv6_REGEX="${IPv6_REGEX}::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|" +IPv6_REGEX="${IPv6_REGEX}([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])" + +MWAN3_STATUS_DIR="/var/run/mwan3" +MWAN3TRACK_STATUS_DIR="/var/run/mwan3track" +MWAN3_INTERFACE_MAX="" +DEFAULT_LOWEST_METRIC=256 +MMX_MASK="" +MMX_DEFAULT="" +MMX_BLACKHOLE="" +MM_BLACKHOLE="" + +MMX_UNREACHABLE="" +MM_UNREACHABLE="" + +# return true(=0) if has any mwan3 interface enabled +# otherwise return false +mwan3_rtmon_ipv4() +{ + local tid=1 + local idx=0 + local ret=1 + local tbl="" + mkdir -p /tmp/mwan3rtmon + ($IP4 route list table main | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.main + while uci get mwan3.@interface[$idx] >/dev/null 2>&1 ; do + idx=$((idx+1)) + tid=$idx + [ "$(uci get mwan3.@interface[$((idx-1))].family)" = "ipv4" ] && { + tbl=$($IP4 route list table $tid) + if echo "$tbl" | grep -q ^default; then + (echo "$tbl" | grep -v "^default\|linkdown" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv4.$tid + cat /tmp/mwan3rtmon/ipv4.$tid | grep -v -x -F -f /tmp/mwan3rtmon/ipv4.main | while read line; do + $IP4 route del table $tid $line + done + cat /tmp/mwan3rtmon/ipv4.main | grep -v -x -F -f /tmp/mwan3rtmon/ipv4.$tid | while read line; do + $IP4 route add table $tid $line + done + fi + } + if [ "$(uci get mwan3.@interface[$((idx-1))].enabled)" = "1" ]; then + ret=0 + fi + done + rm -f /tmp/mwan3rtmon/ipv4.* + return $ret +} + +# return true(=0) if has any mwan3 interface enabled +# otherwise return false +mwan3_rtmon_ipv6() +{ + local tid=1 + local idx=0 + local ret=1 + local tbl="" + mkdir -p /tmp/mwan3rtmon + ($IP6 route list table main | grep -v "^default\|^::/0\|^fe80::/64\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.main + while uci get mwan3.@interface[$idx] >/dev/null 2>&1 ; do + idx=$((idx+1)) + tid=$idx + [ "$(uci get mwan3.@interface[$((idx-1))].family)" = "ipv6" ] && { + tbl=$($IP6 route list table $tid) + if echo "$tbl" | grep -q "^default\|^::/0"; then + (echo "$tbl" | grep -v "^default\|^::/0\|^unreachable" | sort -n; echo empty fixup) >/tmp/mwan3rtmon/ipv6.$tid + cat /tmp/mwan3rtmon/ipv6.$tid | grep -v -x -F -f /tmp/mwan3rtmon/ipv6.main | while read line; do + $IP6 route del table $tid $line + done + cat /tmp/mwan3rtmon/ipv6.main | grep -v -x -F -f /tmp/mwan3rtmon/ipv6.$tid | while read line; do + $IP6 route add table $tid $line + done + fi + } + if [ "$(uci get mwan3.@interface[$((idx-1))].enabled)" = "1" ]; then + ret=0 + fi + done + rm -f /tmp/mwan3rtmon/ipv6.* + return $ret +} + +# counts how many bits are set to 1 +# n&(n-1) clears the lowest bit set to 1 +mwan3_count_one_bits() +{ + local count n + count=0 + n=$(($1)) + while [ "$n" -gt "0" ]; do + n=$((n&(n-1))) + count=$((count+1)) + done + echo $count +} + +# maps the 1st parameter so it only uses the bits allowed by the bitmask (2nd parameter) +# which means spreading the bits of the 1st parameter to only use the bits that are set to 1 in the 2nd parameter +# 0 0 0 0 0 1 0 1 (0x05) 1st parameter +# 1 0 1 0 1 0 1 0 (0xAA) 2nd parameter +# 1 0 1 result +mwan3_id2mask() +{ + local bit_msk bit_val result + bit_val=0 + result=0 + for bit_msk in $(seq 0 31); do + if [ $((($2>>bit_msk)&1)) = "1" ]; then + if [ $((($1>>bit_val)&1)) = "1" ]; then + result=$((result|(1< "${MWAN3_STATUS_DIR}/mmx_mask" + $LOG notice "Using firewall mask ${MMX_MASK}" + + bitcnt=$(mwan3_count_one_bits MMX_MASK) + mmdefault=$(((1< /dev/null; then + $IPT -N mwan3_ifaces_in + fi + + if ! $IPT -S mwan3_connected &> /dev/null; then + $IPT -N mwan3_connected + $IPS -! create mwan3_connected list:set + $IPT -A mwan3_connected \ + -m set --match-set mwan3_connected dst \ + -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + fi + + if ! $IPT -S mwan3_rules &> /dev/null; then + $IPT -N mwan3_rules + fi + + if ! $IPT -S mwan3_hook &> /dev/null; then + $IPT -N mwan3_hook + # do not mangle ipv6 ra service + if [ "$IPT" = "$IPT6" ]; then + $IPT6 -A mwan3_hook \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 133 \ + -j RETURN + $IPT6 -A mwan3_hook \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 134 \ + -j RETURN + $IPT6 -A mwan3_hook \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 135 \ + -j RETURN + $IPT6 -A mwan3_hook \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 136 \ + -j RETURN + $IPT6 -A mwan3_hook \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 137 \ + -j RETURN + # do not mangle outgoing echo request + $IPT6 -A mwan3_hook \ + -m set --match-set mwan3_source_v6 src \ + -p ipv6-icmp \ + -m icmp6 --icmpv6-type 128 \ + -j RETURN + + fi + $IPT -A mwan3_hook \ + -j CONNMARK --restore-mark --nfmask $MMX_MASK --ctmask $MMX_MASK + $IPT -A mwan3_hook \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_ifaces_in + $IPT -A mwan3_hook \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_connected + $IPT -A mwan3_hook \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_rules + $IPT -A mwan3_hook \ + -j CONNMARK --save-mark --nfmask $MMX_MASK --ctmask $MMX_MASK + $IPT -A mwan3_hook \ + -m mark ! --mark $MMX_DEFAULT/$MMX_MASK \ + -j mwan3_connected + fi + + if ! $IPT -S PREROUTING | grep mwan3_hook &> /dev/null; then + $IPT -A PREROUTING -j mwan3_hook + fi + + if ! $IPT -S OUTPUT | grep mwan3_hook &> /dev/null; then + $IPT -A OUTPUT -j mwan3_hook + fi + done +} + +mwan3_create_iface_iptables() +{ + local id family + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + $IPS -! create mwan3_connected list:set + + if ! $IPT4 -S mwan3_ifaces_in &> /dev/null; then + $IPT4 -N mwan3_ifaces_in + fi + + if ! $IPT4 -S mwan3_iface_in_$1 &> /dev/null; then + $IPT4 -N mwan3_iface_in_$1 + fi + + $IPT4 -F mwan3_iface_in_$1 + $IPT4 -A mwan3_iface_in_$1 \ + -i $2 \ + -m set --match-set mwan3_connected src \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "default" \ + -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + $IPT4 -A mwan3_iface_in_$1 \ + -i $2 \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "$1" \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + $IPT4 -D mwan3_ifaces_in \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_iface_in_$1 &> /dev/null + $IPT4 -A mwan3_ifaces_in \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_iface_in_$1 + fi + + if [ "$family" == "ipv6" ]; then + $IPS -! create mwan3_connected_v6 hash:net family inet6 + + if ! $IPT6 -S mwan3_ifaces_in &> /dev/null; then + $IPT6 -N mwan3_ifaces_in + fi + + if ! $IPT6 -S mwan3_iface_in_$1 &> /dev/null; then + $IPT6 -N mwan3_iface_in_$1 + fi + + $IPT6 -F mwan3_iface_in_$1 + $IPT6 -A mwan3_iface_in_$1 -i $2 \ + -m set --match-set mwan3_connected_v6 src \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "default" \ + -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + $IPT6 -A mwan3_iface_in_$1 -i $2 -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "$1" \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + $IPT6 -D mwan3_ifaces_in \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_iface_in_$1 &> /dev/null + $IPT6 -A mwan3_ifaces_in \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_iface_in_$1 + fi +} + +mwan3_delete_iface_iptables() +{ + config_get family $1 family ipv4 + + if [ "$family" == "ipv4" ]; then + + $IPT4 -D mwan3_ifaces_in \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_iface_in_$1 &> /dev/null + $IPT4 -F mwan3_iface_in_$1 &> /dev/null + $IPT4 -X mwan3_iface_in_$1 &> /dev/null + fi + + if [ "$family" == "ipv6" ]; then + + $IPT6 -D mwan3_ifaces_in \ + -m mark --mark 0x0/$MMX_MASK \ + -j mwan3_iface_in_$1 &> /dev/null + $IPT6 -F mwan3_iface_in_$1 &> /dev/null + $IPT6 -X mwan3_iface_in_$1 &> /dev/null + fi +} + +mwan3_create_iface_route() +{ + local id route_args metric + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + if ubus call network.interface.${1}_4 status &>/dev/null; then + network_get_gateway route_args ${1}_4 + else + network_get_gateway route_args $1 + fi + + if [ -n "$route_args" -a "$route_args" != "0.0.0.0" ]; then + route_args="via $route_args" + else + route_args="" + fi + + network_get_metric metric $1 + if [ -n "$metric" -a "$metric" != "0" ]; then + route_args="$route_args metric $metric" + fi + + $IP4 route flush table $id + $IP4 route add table $id default $route_args dev $2 + mwan3_rtmon_ipv4 + fi + + if [ "$family" == "ipv6" ]; then + if ubus call network.interface.${1}_6 status &>/dev/null; then + network_get_gateway6 route_args ${1}_6 + else + network_get_gateway6 route_args $1 + fi + + if [ -n "$route_args" -a "$route_args" != "::" ]; then + route_args="via $route_args" + else + route_args="" + fi + + network_get_metric metric $1 + if [ -n "$metric" -a "$metric" != "0" ]; then + route_args="$route_args metric $metric" + fi + + $IP6 route flush table $id + $IP6 route add table $id default $route_args dev $2 + mwan3_rtmon_ipv6 + fi +} + +mwan3_delete_iface_route() +{ + local id + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + $IP4 route flush table $id + fi + + if [ "$family" == "ipv6" ]; then + $IP6 route flush table $id + fi +} + +mwan3_create_iface_rules() +{ + local id family + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP4 rule del pref $(($id+1000)) + done + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP4 rule del pref $(($id+2000)) + done + + $IP4 rule add pref $(($id+1000)) iif $2 lookup $id + $IP4 rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup $id + fi + + if [ "$family" == "ipv6" ]; then + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP6 rule del pref $(($id+1000)) + done + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP6 rule del pref $(($id+2000)) + done + + $IP6 rule add pref $(($id+1000)) iif $2 lookup $id + $IP6 rule add pref $(($id+2000)) fwmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK lookup $id + fi +} + +mwan3_delete_iface_rules() +{ + local id family + + config_get family $1 family ipv4 + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + if [ "$family" == "ipv4" ]; then + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP4 rule del pref $(($id+1000)) + done + + while [ -n "$($IP4 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP4 rule del pref $(($id+2000)) + done + fi + + if [ "$family" == "ipv6" ]; then + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+1000)):'"')" ]; do + $IP6 rule del pref $(($id+1000)) + done + + while [ -n "$($IP6 rule list | awk '$1 == "'$(($id+2000)):'"')" ]; do + $IP6 rule del pref $(($id+2000)) + done + fi +} + +mwan3_delete_iface_ipset_entries() +{ + local id setname entry + + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + for setname in $(ipset -n list | grep ^mwan3_sticky_); do + for entry in $(ipset list $setname | grep "$(echo $(mwan3_id2mask id MMX_MASK) | awk '{ printf "0x%08x", $1; }')" | cut -d ' ' -f 1); do + $IPS del $setname $entry + done + done +} + +mwan3_rtmon() +{ + pid="$(pgrep -f mwan3rtmon)" + if [ "${pid}" != "" ]; then + kill -USR1 "${pid}" + else + [ -x /usr/sbin/mwan3rtmon ] && /usr/sbin/mwan3rtmon & + fi +} + +mwan3_track() +{ + local track_ip track_ips pid + + mwan3_list_track_ips() + { + track_ips="$track_ips $1" + } + config_list_foreach $1 track_ip mwan3_list_track_ips + + for pid in $(pgrep -f "mwan3track $1 $2"); do + kill -TERM "$pid" > /dev/null 2>&1 + sleep 1 + kill -KILL "$pid" > /dev/null 2>&1 + done + if [ -n "$track_ips" ]; then + [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track "$1" "$2" "$3" "$4" $track_ips & + fi +} + +mwan3_track_signal() +{ + local pid + + pid="$(pgrep -f "mwan3track $1 $2")" + [ "${pid}" != "" ] && { + kill -USR1 "${pid}" + } +} + +mwan3_set_policy() +{ + local iface_count id iface family metric probability weight device + + config_get iface $1 interface + config_get metric $1 metric 1 + config_get weight $1 weight 1 + + [ -n "$iface" ] || return 0 + network_get_device device $iface + [ "$metric" -gt $DEFAULT_LOWEST_METRIC ] && $LOG warn "Member interface $iface has >$DEFAULT_LOWEST_METRIC metric. Not appending to policy" && return 0 + + mwan3_get_iface_id id $iface + + [ -n "$id" ] || return 0 + + config_get family $iface family ipv4 + + if [ "$family" == "ipv4" ]; then + + if [ "$(mwan3_get_iface_hotplug_state $iface)" = "online" ]; then + if [ "$metric" -lt "$lowest_metric_v4" ]; then + + total_weight_v4=$weight + $IPT4 -F mwan3_policy_$policy + $IPT4 -A mwan3_policy_$policy \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "$iface $weight $weight" \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + lowest_metric_v4=$metric + + elif [ "$metric" -eq "$lowest_metric_v4" ]; then + + total_weight_v4=$(($total_weight_v4+$weight)) + probability=$(($weight*1000/$total_weight_v4)) + + if [ "$probability" -lt 10 ]; then + probability="0.00$probability" + elif [ $probability -lt 100 ]; then + probability="0.0$probability" + elif [ $probability -lt 1000 ]; then + probability="0.$probability" + else + probability="1" + fi + + probability="-m statistic --mode random --probability $probability" + + $IPT4 -I mwan3_policy_$policy \ + -m mark --mark 0x0/$MMX_MASK $probability \ + -m comment --comment "$iface $weight $total_weight_v4" \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + fi + else + [ -n "$device" ] && { + $IPT4 -S mwan3_policy_$policy | grep -q '.*--comment ".* [0-9]* [0-9]*"' || \ + $IPT4 -I mwan3_policy_$policy \ + -o $device \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "out $iface $device" \ + -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + } + fi + fi + + if [ "$family" == "ipv6" ]; then + + if [ "$(mwan3_get_iface_hotplug_state $iface)" = "online" ]; then + if [ "$metric" -lt "$lowest_metric_v6" ]; then + + total_weight_v6=$weight + $IPT6 -F mwan3_policy_$policy + $IPT6 -A mwan3_policy_$policy \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "$iface $weight $weight" \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + + lowest_metric_v6=$metric + + elif [ "$metric" -eq "$lowest_metric_v6" ]; then + + total_weight_v6=$(($total_weight_v6+$weight)) + probability=$(($weight*1000/$total_weight_v6)) + + if [ "$probability" -lt 10 ]; then + probability="0.00$probability" + elif [ $probability -lt 100 ]; then + probability="0.0$probability" + elif [ $probability -lt 1000 ]; then + probability="0.$probability" + else + probability="1" + fi + + probability="-m statistic --mode random --probability $probability" + + $IPT6 -I mwan3_policy_$policy \ + -m mark --mark 0x0/$MMX_MASK \ + $probability \ + -m comment --comment "$iface $weight $total_weight_v6" \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + fi + else + [ -n "$device" ] && { + $IPT6 -S mwan3_policy_$policy | grep -q '.*--comment ".* [0-9]* [0-9]*"' || \ + $IPT6 -I mwan3_policy_$policy \ + -o $device \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "out $iface $device" \ + -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + } + fi + fi +} + +mwan3_create_policies_iptables() +{ + local last_resort lowest_metric_v4 lowest_metric_v6 total_weight_v4 total_weight_v6 policy IPT + + policy="$1" + + config_get last_resort $1 last_resort unreachable + + if [ "$1" != $(echo "$1" | cut -c1-15) ]; then + $LOG warn "Policy $1 exceeds max of 15 chars. Not setting policy" && return 0 + fi + + for IPT in "$IPT4" "$IPT6"; do + + if ! $IPT -S mwan3_policy_$1 &> /dev/null; then + $IPT -N mwan3_policy_$1 + fi + + $IPT -F mwan3_policy_$1 + + case "$last_resort" in + blackhole) + $IPT -A mwan3_policy_$1 \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "blackhole" \ + -j MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK + ;; + default) + $IPT -A mwan3_policy_$1 \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "default" \ + -j MARK --set-xmark $MMX_DEFAULT/$MMX_MASK + ;; + *) + $IPT -A mwan3_policy_$1 \ + -m mark --mark 0x0/$MMX_MASK \ + -m comment --comment "unreachable" \ + -j MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK + ;; + esac + done + + lowest_metric_v4=$DEFAULT_LOWEST_METRIC + total_weight_v4=0 + + lowest_metric_v6=$DEFAULT_LOWEST_METRIC + total_weight_v6=0 + + config_list_foreach $1 use_member mwan3_set_policy +} + +mwan3_set_policies_iptables() +{ + config_foreach mwan3_create_policies_iptables policy +} + +mwan3_set_sticky_iptables() +{ + local id iface + + for iface in $($IPT4 -S $policy | cut -s -d'"' -f2 | awk '{print $1}'); do + + if [ "$iface" == "$1" ]; then + + mwan3_get_iface_id id $1 + + [ -n "$id" ] || return 0 + + for IPT in "$IPT4" "$IPT6"; do + if [ -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" ]; then + $IPT -I mwan3_rule_$rule \ + -m mark --mark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK \ + -m set ! --match-set mwan3_sticky_$rule src,src \ + -j MARK --set-xmark 0x0/$MMX_MASK + $IPT -I mwan3_rule_$rule \ + -m mark --mark 0/$MMX_MASK \ + -j MARK --set-xmark $(mwan3_id2mask id MMX_MASK)/$MMX_MASK + fi + done + fi + done +} + +mwan3_set_user_iptables_rule() +{ + local ipset family proto policy src_ip src_port src_iface src_dev + local sticky dest_ip dest_port use_policy timeout rule policy IPT + local global_logging rule_logging loglevel + + rule="$1" + + config_get sticky $1 sticky 0 + config_get timeout $1 timeout 600 + config_get ipset $1 ipset + config_get proto $1 proto all + config_get src_ip $1 src_ip + config_get src_iface $1 src_iface + network_get_device src_dev $src_iface + config_get src_port $1 src_port + config_get dest_ip $1 dest_ip + config_get dest_port $1 dest_port + config_get use_policy $1 use_policy + config_get family $1 family any + + [ -z "$dest_ip" ] && unset dest_ip + [ -z "$src_ip" ] && unset src_ip + [ -z "$ipset" ] && unset ipset + [ -z "$src_port" ] && unset src_port + [ -z "$dest_port" ] && unset dest_port + [ "$proto" != 'tcp' ] && [ "$proto" != 'udp' ] && { + [ -n "$src_port" ] && { + $LOG warn "src_port set to '$src_port' but proto set to '$proto' not tcp or udp. src_port will be ignored" + } + [ -n "$dest_port" ] && { + $LOG warn "dest_port set to '$dest_port' but proto set to '$proto' not tcp or udp. dest_port will be ignored" + } + unset src_port + unset dest_port + } + + config_get rule_logging $1 logging 0 + config_get global_logging globals logging 0 + config_get loglevel globals loglevel notice + + if [ "$1" != $(echo "$1" | cut -c1-15) ]; then + $LOG warn "Rule $1 exceeds max of 15 chars. Not setting rule" && return 0 + fi + + if [ -n "$ipset" ]; then + ipset="-m set --match-set $ipset dst" + fi + + if [ -n "$use_policy" ]; then + if [ "$use_policy" == "default" ]; then + policy="MARK --set-xmark $MMX_DEFAULT/$MMX_MASK" + elif [ "$use_policy" == "unreachable" ]; then + policy="MARK --set-xmark $MMX_UNREACHABLE/$MMX_MASK" + elif [ "$use_policy" == "blackhole" ]; then + policy="MARK --set-xmark $MMX_BLACKHOLE/$MMX_MASK" + else + if [ "$sticky" -eq 1 ]; then + + policy="mwan3_policy_$use_policy" + + for IPT in "$IPT4" "$IPT6"; do + if ! $IPT -S $policy &> /dev/null; then + $IPT -N $policy + fi + + if ! $IPT -S mwan3_rule_$1 &> /dev/null; then + $IPT -N mwan3_rule_$1 + fi + + $IPT -F mwan3_rule_$1 + done + + $IPS -! create mwan3_sticky_v4_$rule \ + hash:ip,mark markmask $MMX_MASK \ + timeout $timeout + $IPS -! create mwan3_sticky_v6_$rule \ + hash:ip,mark markmask $MMX_MASK \ + timeout $timeout family inet6 + $IPS -! create mwan3_sticky_$rule list:set + $IPS -! add mwan3_sticky_$rule mwan3_sticky_v4_$rule + $IPS -! add mwan3_sticky_$rule mwan3_sticky_v6_$rule + + config_foreach mwan3_set_sticky_iptables interface + + for IPT in "$IPT4" "$IPT6"; do + $IPT -A mwan3_rule_$1 \ + -m mark --mark 0/$MMX_MASK \ + -j $policy + $IPT -A mwan3_rule_$1 \ + -m mark ! --mark 0xfc00/0xfc00 \ + -j SET --del-set mwan3_sticky_$rule src,src + $IPT -A mwan3_rule_$1 \ + -m mark ! --mark 0xfc00/0xfc00 \ + -j SET --add-set mwan3_sticky_$rule src,src + done + + policy="mwan3_rule_$1" + else + policy="mwan3_policy_$use_policy" + + for IPT in "$IPT4" "$IPT6"; do + if ! $IPT -S $policy &> /dev/null; then + $IPT -N $policy + fi + done + + fi + fi + for IPT in "$IPT4" "$IPT6"; do + [ "$family" == "ipv4" ] && [ "$IPT" == "$IPT6" ] && continue + [ "$family" == "ipv6" ] && [ "$IPT" == "$IPT4" ] && continue + [ "$global_logging" = "1" ] && [ "$rule_logging" = "1" ] && { + $IPT -A mwan3_rules \ + -p $proto \ + ${src_ip:+-s} $src_ip \ + ${src_dev:+-i} $src_dev \ + ${dest_ip:+-d} $dest_ip\ + $ipset \ + ${src_port:+-m} ${src_port:+multiport} ${src_port:+--sports} $src_port \ + ${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \ + -m mark --mark 0/$MMX_MASK \ + -m comment --comment "$1" \ + -j LOG --log-level "$loglevel" --log-prefix "MWAN3($1)" &> /dev/null + } + + $IPT -A mwan3_rules \ + -p $proto \ + ${src_ip:+-s} $src_ip \ + ${src_dev:+-i} $src_dev \ + ${dest_ip:+-d} $dest_ip\ + $ipset \ + ${src_port:+-m} ${src_port:+multiport} ${src_port:+--sports} $src_port \ + ${dest_port:+-m} ${dest_port:+multiport} ${dest_port:+--dports} $dest_port \ + -m mark --mark 0/$MMX_MASK \ + -j $policy &> /dev/null + done + fi +} + +mwan3_set_user_rules() +{ + local IPT + + for IPT in "$IPT4" "$IPT6"; do + + if ! $IPT -S mwan3_rules &> /dev/null; then + $IPT -N mwan3_rules + fi + + $IPT -F mwan3_rules + done + + config_foreach mwan3_set_user_iptables_rule rule +} + +mwan3_set_iface_hotplug_state() { + local iface=$1 + local state=$2 + + echo -n $state > $MWAN3_STATUS_DIR/iface_state/$iface +} + +mwan3_get_iface_hotplug_state() { + local iface=$1 + + cat $MWAN3_STATUS_DIR/iface_state/$iface 2>/dev/null || echo "offline" +} + +mwan3_report_iface_status() +{ + local device result track_ips tracking IP IPT + + mwan3_get_iface_id id $1 + network_get_device device $1 + config_get enabled "$1" enabled 0 + config_get family "$1" family ipv4 + + if [ "$family" == "ipv4" ]; then + IP="$IP4" + IPT="$IPT4" + fi + + if [ "$family" == "ipv6" ]; then + IP="$IP6" + IPT="$IPT6" + fi + + if [ -z "$id" -o -z "$device" ]; then + result="offline" + elif [ -n "$($IP rule | awk '$1 == "'$(($id+1000)):'"')" ] && \ + [ -n "$($IP rule | awk '$1 == "'$(($id+2000)):'"')" ] && \ + [ -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" ] && \ + [ -n "$($IP route list table $id default dev $device 2> /dev/null)" ]; then + result="$(mwan3_get_iface_hotplug_state $1)" + elif [ -n "$($IP rule | awk '$1 == "'$(($id+1000)):'"')" ] || \ + [ -n "$($IP rule | awk '$1 == "'$(($id+2000)):'"')" ] || \ + [ -n "$($IPT -S mwan3_iface_in_$1 2> /dev/null)" ] || \ + [ -n "$($IP route list table $id default dev $device 2> /dev/null)" ]; then + result="error" + elif [ "$enabled" == "1" ]; then + result="offline" + else + result="disabled" + fi + + mwan3_list_track_ips() + { + track_ips="$1 $track_ips" + } + config_list_foreach $1 track_ip mwan3_list_track_ips + + if [ -n "$track_ips" ]; then + if [ -n "$(pgrep -f "mwan3track $1 $device")" ]; then + tracking="active" + else + tracking="down" + fi + else + tracking="not enabled" + fi + + echo " interface $1 is $result and tracking is $tracking" +} + +mwan3_report_policies() +{ + local ipt="$1" + local policy="$2" + + local percent total_weight weight iface + + total_weight=$($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | head -1 | awk '{print $3}') + + if [ ! -z "${total_weight##*[!0-9]*}" ]; then + for iface in $($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '{print $1}'); do + weight=$($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}') + percent=$(($weight*100/$total_weight)) + echo " $iface ($percent%)" + done + else + echo " $($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')" + fi +} + +mwan3_report_policies_v4() +{ + local policy + + for policy in $($IPT4 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + echo "$policy:" | sed 's/mwan3_policy_//' + mwan3_report_policies "$IPT4" "$policy" + done +} + +mwan3_report_policies_v6() +{ + local policy + + for policy in $($IPT6 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + echo "$policy:" | sed 's/mwan3_policy_//' + mwan3_report_policies "$IPT6" "$policy" + done +} + +mwan3_report_connected_v4() +{ + local address + + if [ -n "$($IPT4 -S mwan3_connected 2> /dev/null)" ]; then + $IPS -o save list mwan3_connected_v4 | grep add | cut -d " " -f 3 + fi +} + +mwan3_report_connected_v6() +{ + local address + + if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then + $IPS -o save list mwan3_connected_v6 | grep add | cut -d " " -f 3 + fi +} + +mwan3_report_rules_v4() +{ + if [ -n "$($IPT4 -S mwan3_rules 2> /dev/null)" ]; then + $IPT4 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /' + fi +} + +mwan3_report_rules_v6() +{ + if [ -n "$($IPT6 -S mwan3_rules 2> /dev/null)" ]; then + $IPT6 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /' + fi +} + +mwan3_flush_conntrack() +{ + local interface="$1" + local action="$2" + + handle_flush() { + local flush_conntrack="$1" + local action="$2" + + if [ "$action" = "$flush_conntrack" ]; then + echo f > ${CONNTRACK_FILE} + $LOG info "Connection tracking flushed for interface '$interface' on action '$action'" + fi + } + + if [ -e "$CONNTRACK_FILE" ]; then + config_list_foreach "$interface" flush_conntrack handle_flush "$action" + fi +} + +mwan3_track_clean() +{ + rm -rf "$MWAN3_STATUS_DIR/${1}" &> /dev/null + [ -d "$MWAN3_STATUS_DIR" ] && { + if [ -z "$(ls -A "$MWAN3_STATUS_DIR")" ]; then + rm -rf "$MWAN3_STATUS_DIR" + fi + } +} diff --git a/mwan3/files/usr/libexec/rpcd/mwan3 b/mwan3/files/usr/libexec/rpcd/mwan3 new file mode 100755 index 000000000..33e3e0284 --- /dev/null +++ b/mwan3/files/usr/libexec/rpcd/mwan3 @@ -0,0 +1,230 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh +. /usr/share/libubox/jshn.sh +. /lib/mwan3/common.sh + +MWAN3TRACK_STATUS_DIR="/var/run/mwan3track" + +IPS="ipset" +IPT4="iptables -t mangle -w" +IPT6="ip6tables -t mangle -w" + +report_connected_v4() { + local address + + if [ -n "$($IPT4 -S mwan3_connected 2> /dev/null)" ]; then + for address in $($IPS -o save list mwan3_connected_v4 | grep add | cut -d " " -f 3); do + json_add_string "" "${address}" + done + fi +} + +report_connected_v6() { + local address + + if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then + for address in $($IPS -o save list mwan3_connected_v6 | grep add | cut -d " " -f 3); do + json_add_string "" "${address}" + done + fi +} + +report_policies() { + local ipt="$1" + local policy="$2" + + local percent total_weight weight iface + + total_weight=$($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | head -1 | awk '{print $3}') + + for iface in $($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '{print $1}'); do + weight=$($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}') + percent=$(($weight*100/$total_weight)) + json_add_object + json_add_string interface "$iface" + json_add_int percent "$percent" + json_close_object + done +} + +report_policies_v4() { + local policy + + for policy in $($IPT4 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + json_add_array "${policy##*mwan3_policy_}" + report_policies "$IPT4" "$policy" + json_close_array + done +} + +report_policies_v6() { + local policy + + for policy in $($IPT6 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + json_add_array "${policy##*mwan3_policy_}" + report_policies "$IPT6" "$policy" + json_close_array + done +} + +get_mwan3_status() { + local iface="${1}" + local iface_select="${2}" + local running="0" + local age=0 + local online=0 + local offline=0 + local up="0" + local enabled pid device time_p time_n time_u time_d status + + network_get_device device $1 + + if [ "${iface}" = "${iface_select}" ] || [ "${iface_select}" = "" ]; then + pid="$(pgrep -f "mwan3track $iface $device")" + if [ "${pid}" != "" ]; then + running="1" + fi + + time_p="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TIME")" + [ -z "${time_p}" ] || { + time_n="$(get_uptime)" + let age=time_n-time_p + } + + time_u="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/ONLINE")" + [ -z "${time_u}" ] || [ "${time_u}" = "0" ] || { + time_n="$(get_uptime)" + let online=time_n-time_u + } + + time_d="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/OFFLINE")" + [ -z "${time_d}" ] || [ "${time_d}" = "0" ] || { + time_n="$(get_uptime)" + let offline=time_n-time_d + } + + local uptime="0" + + config_get enabled "$iface" enabled 0 + network_get_uptime uptime "$iface" + network_is_up "$iface" && up="1" + + if [ -f "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS" ]; then + status="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS")" + else + status="unknown" + fi + + json_add_object "${iface}" + json_add_int age "$age" + json_add_int online "${online}" + json_add_int offline "${offline}" + json_add_int uptime "${uptime}" + json_add_int "score" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/SCORE")" + json_add_int "lost" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOST")" + json_add_int "turn" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TURN")" + json_add_string "status" "${status}" + json_add_boolean "enabled" "${enabled}" + json_add_boolean "running" "${running}" + json_add_boolean "up" "${up}" + json_add_array "track_ip" + for file in $MWAN3TRACK_STATUS_DIR/${iface}/*; do + track="${file#*/TRACK_}" + if [ "${track}" != "${file}" ]; then + json_add_object + json_add_string ip "${track}" + json_add_string status "$(cat "${file}")" + json_add_int latency "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LATENCY_${track}")" + json_add_int packetloss "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOSS_${track}")" + json_close_object + fi + done + json_close_array + json_close_object + fi +} + +main () { + + case "$1" in + list) + json_init + json_add_object "status" + json_add_string "section" "x" + json_add_string "interface" "x" + json_add_string "policies" "x" + json_close_object + json_dump + ;; + call) + case "$2" in + status) + local section iface + read input; + json_load "$input" + json_get_var section section + json_get_var iface interface + + config_load mwan3 + json_init + case "$section" in + interfaces) + json_add_object interfaces + config_foreach get_mwan3_status interface "${iface}" + json_close_object + ;; + connected) + json_add_object connected + json_add_array ipv4 + report_connected_v4 + json_close_array + json_add_array ipv6 + report_connected_v6 + json_close_array + json_close_object + ;; + policies) + json_add_object policies + json_add_object ipv4 + report_policies_v4 + json_close_object + json_add_object ipv6 + report_policies_v6 + json_close_object + json_close_object + ;; + *) + # interfaces + json_add_object interfaces + config_foreach get_mwan3_status interface + json_close_object + # connected + json_add_object connected + json_add_array ipv4 + report_connected_v4 + json_close_array + json_add_array ipv6 + report_connected_v6 + json_close_array + json_close_object + # policies + json_add_object policies + json_add_object ipv4 + report_policies_v4 + json_close_object + json_add_object ipv6 + report_policies_v6 + json_close_object + json_close_object + ;; + esac + json_dump + ;; + esac + ;; + esac +} + +main "$@" diff --git a/mwan3/files/usr/sbin/mwan3 b/mwan3/files/usr/sbin/mwan3 new file mode 100755 index 000000000..a854dfda2 --- /dev/null +++ b/mwan3/files/usr/sbin/mwan3 @@ -0,0 +1,213 @@ +#!/bin/sh + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh +. /lib/functions/network.sh +. /lib/mwan3/mwan3.sh + +help() +{ + cat < Load rules and routes for specific interface + ifdown Unload rules and routes for specific interface + interfaces Show interfaces status + policies Show currently active policy + connected Show directly connected networks + rules Show active rules + status Show all status + +EOF +} + +ifdown() +{ + if [ -z "$1" ]; then + echo "Error: Expecting interface. Usage: mwan3 ifdown " && exit 0 + fi + + if [ -n "$2" ]; then + echo "Error: Too many arguments. Usage: mwan3 ifdown " && exit 0 + fi + + ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface + + kill $(pgrep -f "mwan3track $1 $2") &> /dev/null + mwan3_track_clean $1 +} + +ifup() +{ + local device enabled up l3_device status + + config_load mwan3 + config_get_bool enabled globals 'enabled' 0 + [ ${enabled} -gt 0 ] || { + echo "The service mwan3 is global disabled." + echo "Please execute \"/etc/init.d/mwan3 start\" first." + exit 1 + } + + if [ -z "$1" ]; then + echo "Expecting interface. Usage: mwan3 ifup " && exit 0 + fi + + if [ -n "$2" ]; then + echo "Too many arguments. Usage: mwan3 ifup " && exit 0 + fi + + status=$(ubus -S call network.interface.$1 status) + [ -n "$status" ] && { + json_load "$status" + json_get_vars up l3_device + } + + config_get enabled "$1" enabled 0 + + if [ "$up" = "1" ] \ + && [ -n "$l3_device" ] \ + && [ "$enabled" = "1" ]; then + ACTION=ifup INTERFACE=$1 DEVICE=$l3_device /sbin/hotplug-call iface + fi +} + +interfaces() +{ + config_load mwan3 + + echo "Interface status:" + config_foreach mwan3_report_iface_status interface + echo -e +} + +policies() +{ + echo "Current ipv4 policies:" + mwan3_report_policies_v4 + echo -e + echo "Current ipv6 policies:" + mwan3_report_policies_v6 + echo -e +} + +connected() +{ + echo "Directly connected ipv4 networks:" + mwan3_report_connected_v4 + echo -e + echo "Directly connected ipv6 networks:" + mwan3_report_connected_v6 + echo -e +} + +rules() +{ + echo "Active ipv4 user rules:" + mwan3_report_rules_v4 + echo -e + echo "Active ipv6 user rules:" + mwan3_report_rules_v6 + echo -e +} + +status() +{ + interfaces + policies + connected + rules +} + +start() +{ + local enabled + + uci_toggle_state mwan3 globals enabled "1" + + config_load mwan3 + config_foreach ifup interface +} + +stop() +{ + local ipset route rule table IP IPT pid + + mwan3_lock "command" "mwan3" + + for pid in $(pgrep -f "mwan3rtmon"); do + kill -TERM "$pid" > /dev/null 2>&1 + sleep 1 + kill -KILL "$pid" > /dev/null 2>&1 + done + + for pid in $(pgrep -f "mwan3track"); do + kill -TERM "$pid" > /dev/null 2>&1 + sleep 1 + kill -KILL "$pid" > /dev/null 2>&1 + done + + config_load mwan3 + config_foreach mwan3_track_clean interface + + for IP in "$IP4" "$IP6"; do + + for route in $(seq 1 $MWAN3_INTERFACE_MAX); do + $IP route flush table $route &> /dev/null + done + + for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do + $IP rule del pref $rule &> /dev/null + done + done + + for IPT in "$IPT4" "$IPT6"; do + + $IPT -D PREROUTING -j mwan3_hook &> /dev/null + $IPT -D OUTPUT -j mwan3_hook &> /dev/null + + for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do + $IPT -F $table &> /dev/null + done + + for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do + $IPT -X $table &> /dev/null + done + done + + for ipset in $($IPS -n list | grep mwan3_); do + $IPS -q destroy $ipset + done + + for ipset in $($IPS -n list | grep mwan3 | grep -E '_v4|_v6'); do + $IPS -q destroy $ipset + done + + mwan3_unlock "command" "mwan3" + + mwan3_lock_clean + rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR + + uci_toggle_state mwan3 globals enabled "0" +} + +restart() { + stop + start +} + +case "$1" in + ifup|ifdown|interfaces|policies|connected|rules|status|start|stop|restart) + mwan3_init + $* + ;; + *) + help + ;; +esac + +exit 0 diff --git a/mwan3/files/usr/sbin/mwan3rtmon b/mwan3/files/usr/sbin/mwan3rtmon new file mode 100755 index 000000000..9165de554 --- /dev/null +++ b/mwan3/files/usr/sbin/mwan3rtmon @@ -0,0 +1,38 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/mwan3/mwan3.sh + +LOG="logger -t $(basename "$0")[$$] -p" + +clean_up() { + $LOG notice "Stopping mwan3rtmon..." + exit 0 +} + +rtchange() { + $LOG info "Detect rtchange event." +} + +main() { + local rtmon_interval + trap clean_up TERM + trap rtchange USR1 + + config_load mwan3 + config_get rtmon_interval globals rtmon_interval '5' + + sleep 3 + while true; do + mwan3_lock "service" "mwan3rtmon" + mwan3_rtmon_ipv4 || mwan3_rtmon_ipv6 + ret=$? + mwan3_unlock "service" "mwan3rtmon" + [ "$ret" = "0" ] || break + [ "$rtmon_interval" = "0" ] && break + sleep "$rtmon_interval" & + wait + done +} + +main "$@" diff --git a/mwan3/files/usr/sbin/mwan3track b/mwan3/files/usr/sbin/mwan3track new file mode 100755 index 000000000..e112475ce --- /dev/null +++ b/mwan3/files/usr/sbin/mwan3track @@ -0,0 +1,293 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/mwan3/common.sh + +LOG="logger -t $(basename "$0")[$$] -p" +INTERFACE="" +DEVICE="" +PING="/bin/ping" + +IFDOWN_EVENT=0 + +clean_up() { + $LOG notice "Stopping mwan3track for interface \"${INTERFACE}\"" + exit 0 +} + +if_down() { + $LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})" + IFDOWN_EVENT=1 +} + +validate_track_method() { + case "$1" in + ping) + which ping 1>/dev/null 2>&1 || { + $LOG warn "Missing ping. Please install iputils-ping package or enable ping util and recompile busybox." + return 1 + } + ;; + arping) + which arping 1>/dev/null 2>&1 || { + $LOG warn "Missing arping. Please install iputils-arping package." + return 1 + } + ;; + httping) + which httping 1>/dev/null 2>&1 || { + $LOG warn "Missing httping. Please install httping package." + return 1 + } + [ -n "$2" -a "$2" != "0.0.0.0" -a "$2" != "::" ] || { + $LOG warn "Cannot determine source IP for the interface which is required by httping." + return 1 + } + ;; + nping-*) + which nping 1>/dev/null 2>&1 || { + $LOG warn "Missing nping. Please install nping package." + return 1 + } + ;; + *) + $LOG warn "Unsupported tracking method: $track_method" + return 2 + ;; + esac +} + +main() { + local reliability count timeout interval failure_interval + local recovery_interval down up size + local keep_failure_interval check_quality failure_latency + local recovery_latency failure_loss recovery_loss + local max_ttl httping_ssl + + [ -z "$5" ] && echo "Error: should not be started manually" && exit 0 + + INTERFACE=$1 + DEVICE=$2 + STATUS=$3 + SRC_IP=$4 + mkdir -p /var/run/mwan3track/$1 + trap clean_up TERM + trap if_down USR1 + + config_load mwan3 + config_get track_method $1 track_method ping + config_get_bool httping_ssl $1 httping_ssl 0 + validate_track_method $track_method $SRC_IP || { + track_method=ping + if validate_track_method $track_method; then + $LOG warn "Using ping to track interface $INTERFACE avaliability" + else + $LOG err "No track method avaliable" + exit 1 + fi + } + config_get reliability $1 reliability 1 + config_get count $1 count 1 + config_get timeout $1 timeout 4 + config_get interval $1 interval 10 + config_get down $1 down 5 + config_get up $1 up 5 + config_get size $1 size 56 + config_get max_ttl $1 max_ttl 60 + config_get failure_interval $1 failure_interval $interval + config_get_bool keep_failure_interval $1 keep_failure_interval 0 + config_get recovery_interval $1 recovery_interval $interval + config_get_bool check_quality $1 check_quality 0 + config_get failure_latency $1 failure_latency 1000 + config_get recovery_latency $1 recovery_latency 500 + config_get failure_loss $1 failure_loss 40 + config_get recovery_loss $1 recovery_loss 10 + + local score=$(($down+$up)) + local track_ips=$(echo $* | cut -d ' ' -f 5-99) + local host_up_count=0 + local lost=0 + local sleep_time=0 + local turn=0 + local result + local ping_protocol=4 + local ping_result + local ping_result_raw + local ping_status + local loss=0 + local latency=0 + + if [ "$STATUS" = "offline" ]; then + echo "offline" > /var/run/mwan3track/$1/STATUS + echo "0" > /var/run/mwan3track/$1/ONLINE + echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE + score=0 + else + echo "online" > /var/run/mwan3track/$1/STATUS + echo "0" > /var/run/mwan3track/$1/OFFLINE + echo "$(get_uptime)" > /var/run/mwan3track/$1/ONLINE + env -i ACTION="connected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface + fi + while true; do + + sleep_time=$interval + + for track_ip in $track_ips; do + if [ $host_up_count -lt $reliability ]; then + case "$track_method" in + ping) + # pinging IPv6 hosts with an interface is troublesome + # https://bugs.openwrt.org/index.php?do=details&task_id=2897 + # so get the IP address of the interface and use that instead + if echo $track_ip | grep -q ':'; then + ADDR=$(ip -6 addr ls dev "$DEVICE" | sed -ne '/\/128/d' -e 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p' | head -n1) + [ -z "$ADDR" ] && ADDR=$(ip -6 addr ls dev "$DEVICE" | sed -ne 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p') + ping_protocol=6 + fi + if [ $check_quality -eq 0 ]; then + $PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null + result=$? + else + ping_result_raw="$($PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null)" + ping_status=$? + ping_result=$(echo "$ping_result_raw" | tail -n2) + loss="$(echo "$ping_result" | grep "packet loss" | cut -d "," -f3 | awk '{print $1}' | sed -e 's/%//')" + if [ "$ping_status" -ne 0 ] || [ "$loss" -eq 100 ]; then + latency=999999 + loss=100 + else + latency="$(echo "$ping_result" | grep -E 'rtt|round-trip' | cut -d "=" -f2 | cut -d "/" -f2 | cut -d "." -f1)" + fi + fi + ;; + arping) + arping -I $DEVICE -c $count -w $timeout -q $track_ip &> /dev/null + result=$? + ;; + httping) + if [ "$httping_ssl" -eq 1 ]; then + httping -y $SRC_IP -c $count -t $timeout -q "https://$track_ip" &> /dev/null + else + httping -y $SRC_IP -c $count -t $timeout -q "http://$track_ip" &> /dev/null + fi + result=$? + ;; + nping-tcp) + result=$(nping -e $DEVICE -c $count $track_ip --tcp | grep Lost | awk '{print $12}') + ;; + nping-udp) + result=$(nping -e $DEVICE -c $count $track_ip --udp | grep Lost | awk '{print $12}') + ;; + nping-icmp) + result=$(nping -e $DEVICE -c $count $track_ip --icmp | grep Lost | awk '{print $12}') + ;; + nping-arp) + result=$(nping -e $DEVICE -c $count $track_ip --arp | grep Lost | awk '{print $12}') + ;; + esac + if [ $check_quality -eq 0 ]; then + if [ $result -eq 0 ]; then + let host_up_count++ + echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip} + if [ $score -le $up ]; then + $LOG info "Check ($track_method) success for target \"$track_ip\" on interface $1 ($2)" + fi + else + let lost++ + echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip} + if [ $score -gt $up ]; then + $LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $1 ($2)" + fi + fi + else + if [ "$loss" -ge "$failure_loss" -o "$latency" -ge "$failure_latency" ]; then + let lost++ + echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip} + echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip} + echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip} + + if [ $score -gt $up ]; then + $LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $1 ($2)" + fi + elif [ "$loss" -le "$recovery_loss" -a "$latency" -le "$recovery_latency" ]; then + let host_up_count++ + echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip} + echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip} + echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip} + + if [ $score -le $up ]; then + $LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $1 ($2)" + fi + else + echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip} + fi + fi + else + echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip} + fi + done + + if [ $host_up_count -lt $reliability ]; then + let score-- + + if [ $score -lt $up ]; then + score=0 + [ ${keep_failure_interval} -eq 1 ] && { + sleep_time=$failure_interval + } + else + sleep_time=$failure_interval + fi + + if [ $score -eq $up ]; then + echo "offline" > /var/run/mwan3track/$1/STATUS + env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface + score=0 + fi + else + if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then + $LOG info "Lost $(($lost*$count)) ping(s) on interface $1 ($2)" + fi + + let score++ + lost=0 + + if [ $score -gt $up ]; then + echo "online" > /var/run/mwan3track/$1/STATUS + score=$(($down+$up)) + elif [ $score -le $up ]; then + sleep_time=$recovery_interval + fi + + if [ $score -eq $up ]; then + $LOG notice "Interface $1 ($2) is online" + echo "online" > /var/run/mwan3track/$1/STATUS + env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface + exit 0 + fi + fi + + let turn++ + mkdir -p "/var/run/mwan3track/${1}" + echo "${lost}" > /var/run/mwan3track/$1/LOST + echo "${score}" > /var/run/mwan3track/$1/SCORE + echo "${turn}" > /var/run/mwan3track/$1/TURN + echo "$(get_uptime)" > /var/run/mwan3track/$1/TIME + + host_up_count=0 + sleep "${sleep_time}" & + wait + + if [ "${IFDOWN_EVENT}" -eq 1 ]; then + echo "offline" > /var/run/mwan3track/$1/STATUS + echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE + echo "0" > /var/run/mwan3track/$1/ONLINE + $LOG notice "Interface $1 ($2) is offline" + env -i ACTION="disconnected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface + score=0 + IFDOWN_EVENT=0 + fi + done +} + +main "$@" diff --git a/nps/Makefile b/nps/Makefile new file mode 100644 index 000000000..b1e82e80f --- /dev/null +++ b/nps/Makefile @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=nps +PKG_VERSION:=0.26.10 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/ehang-io/nps/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=1b2fe9d251f55105d65027a1cee464f65d2f6ab3bd4a20e4655e5135db68aee7 + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINTER:=Tianling Shen + +PKG_CONFIG_DEPENDS:= \ + CONFIG_NPC_COMPRESS_UPX \ + CONFIG_NPS_COMPRESS_UPX + +PKG_BUILD_DEPENDS:=golang/host upx/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=ehang.io/nps +GO_PKG_BUILD_PKG:=ehang.io/nps/cmd/... +GO_PKG_LDFLAGS:=-s -w + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/nps/template + SECTION:=net + CATEGORY:=Network + TITLE:=A intranet penetration proxy server ($(1)) + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle + URL:=https://ehang-io.github.io/nps +endef + +Package/npc = $(call Package/nps/template,client) +Package/nps = $(call Package/nps/template,server) + +define Package/nps/description/template + NPS is a lightweight, high-performance, powerful intranet penetration proxy server, + with a powerful web management terminal. +endef + +Package/npc/description = $(Package/nps/description/template) +Package/nps/description = $(Package/nps/description/template) + +define Package/npc/config + config NPC_COMPRESS_UPX + bool "Compress executable files with UPX" + depends on !mips64 + default n +endef + +define Package/nps/config + config NPS_COMPRESS_UPX + bool "Compress executable files with UPX" + depends on !mips64 + default n +endef + +define Build/Compile + $(call GoPackage/Build/Compile) +ifeq ($(CONFIG_NPC_COMPRESS_UPX),y) + $(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/npc +endif +ifeq ($(CONFIG_NPS_COMPRESS_UPX),y) + $(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/nps +endif +endef + +define Package/nps/install/template + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(2) $(1)/usr/bin/$(2) +endef + +Package/npc/install = $(call Package/nps/install/template,$(1),npc) +Package/nps/install = $(call Package/nps/install/template,$(1),nps) + +$(eval $(call GoBinPackage,npc)) +$(eval $(call GoBinPackage,nps)) +$(eval $(call BuildPackage,npc)) +$(eval $(call BuildPackage,nps)) diff --git a/nps/patches/100-remove-useless-sdk-in-npc.patch b/nps/patches/100-remove-useless-sdk-in-npc.patch new file mode 100644 index 000000000..b96542fc4 --- /dev/null +++ b/nps/patches/100-remove-useless-sdk-in-npc.patch @@ -0,0 +1,4 @@ +diff --git a/cmd/npc/sdk.go b/cmd/npc/sdk.go.bak +similarity index 100% +rename from cmd/npc/sdk.go +rename to cmd/npc/sdk.go.bak diff --git a/qBittorrent-static/Makefile b/qBittorrent-static/Makefile new file mode 100644 index 000000000..51cd6f5ec --- /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.4.5_v2.0.7 +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 000000000..e474347dc --- /dev/null +++ b/qBittorrent/Makefile @@ -0,0 +1,95 @@ +# +# 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:=4.4.5 +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:=70c2128b44fe4df4dfc8afc765a304d70cf1b042b5214bcc855d8b3bbc9ccf36 + +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:=qttools + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 +PKG_USE_MIPS16:=0 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/qbittorrent + SECTION:=net + CATEGORY:=Network + SUBMENU:=BitTorrent + DEPENDS:=+libgcc +libstdcpp \ + +rblibtorrent \ + +libopenssl \ + +qt5-core \ + +qt5-network \ + +qt5-sql \ + +qt5-xml \ + +zlib + 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=OFF \ + -DSTACKTRACE=OFF \ + -DWEBUI=ON \ + -DGUI=OFF \ + -DVERBOSE_CONFIGURE=ON + +# The pcre2 is compiled with support for mips16 +ifdef CONFIG_USE_MIPS16 + TARGET_CFLAGS += -minterlink-mips16 +endif + +# Support the glibc +ifdef CONFIG_USE_GLIBC + TARGET_LDFLAGS += -ldl -lrt -lpthread +endif + +TARGET_CFLAGS += -std=c++17 -ffunction-sections -fdata-sections -flto +TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed -flto + +# The pentium-mmx with lto will build failed on qt6 +ifeq ($(ARCH),i386) + ifneq ($(findstring pentium-mmx,$(CONFIG_CPU_TYPE)),) + TARGET_CFLAGS := $(filter-out -flto,$(TARGET_CFLAGS)) + TARGET_LDFLAGS := $(filter-out -flto,$(TARGET_LDFLAGS)) + endif +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 +endef + +$(eval $(call BuildPackage,qbittorrent)) diff --git a/qtbase/Makefile b/qtbase/Makefile new file mode 100644 index 000000000..86ac2509e --- /dev/null +++ b/qtbase/Makefile @@ -0,0 +1,200 @@ +# +# Copyright (C) 2020 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=qtbase +PKG_BASE:=5.15 +PKG_BUGFIX:=6 +PKG_VERSION:=$(PKG_BASE).$(PKG_BUGFIX) +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-everywhere-opensource-src-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:= \ + http://master.qt.io/archive/qt/$(PKG_BASE)/$(PKG_VERSION)/submodules \ + http://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/$(PKG_BASE)/$(PKG_VERSION)/submodules \ + http://qt.mirror.constant.com/archive/qt/$(PKG_BASE)/$(PKG_VERSION)/submodules +PKG_HASH:=396bc6b0d773ac6a7c691a4c3d901999f571e3e7033d7fd6f65e4ef2b6eb7340 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-everywhere-src-$(PKG_VERSION) + +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 +PKG_CPE_ID:=cpe:/a:qt:qt + +include $(INCLUDE_DIR)/package.mk + +define Package/qtbase/Default + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Qt5 + TITLE:=qtbase + URL:=http://qt-project.org + DEPENDS:=+libgcc +libstdcpp @!LINUX_2_6_36 +endef + +define Package/qtbase/description + This package provides the Qt5 libraries. + + Qt is a cross-platform application development framework for desktop, embedded and mobile. + Supported Platforms include Linux, OS X, Windows, VxWorks, QNX, Android, iOS, BlackBerry, + Sailfish OS and others. + + Qt is not a programming language on its own. It is a framework written in C++. + + This package provides the following run-time libraries: + - core + - network + - xml +endef + +define Package/qtbase + $(call Package/qtbase/Default) + TITLE+=all libs + DEPENDS+=$(QTBASE_DEPENDS) +endef + +define Package/qtbase/install + true +endef + +define Package/qtbase/config + config QT5_INCLUDE_ATOMIC + bool "Depends on libatomic" + default y if !(arm_v7 || ARCH_64BIT || TARGET_x86) + default n + help + Check this options to add the libatomic to the dependences. + - You'd better to confirm whether your compiler need the external libatomic. + Otherwise, it is not recommended to modify this option mannually. + + menu "Select Qtbase Libraries" + comment "Qtbase Libraries" + + $(foreach lib,$(QTBASE_LIBS), + config PACKAGE_qt5-$(lib) + prompt "Qtbase $(lib) library." + default m if ALL + ) + endmenu +endef + +PKG_CONFIG_DEPENDS = CONFIG_QT5_INCLUDE_ATOMIC + +EXTRA_CFLAGS += $(FPIC) -ffunction-sections -fdata-sections -flto +EXTRA_LDFLAGS += -Wl,--gc-sections,--as-needed + +CONFIGURE_ARGS = \ + -sysroot $(STAGING_DIR) \ + -hostprefix $(STAGING_DIR_HOSTPKG) \ + -extprefix $(STAGING_DIR)/usr \ + -prefix /usr \ + -archdatadir /usr/share/Qt \ + -datadir /usr/share/Qt \ + -device linux-generic-g++ \ + -device-option CROSS_COMPILE="$(TARGET_CROSS)" \ + -device-option COMPILER_FLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \ + -device-option LINKER_FLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \ + -confirm-license \ + -opensource \ + -release \ + -shared \ + -strip \ + -no-rpath \ + -no-use-gold-linker \ + -ltcg \ + -mimetype-database \ + -openssl-linked \ + -qt-doubleconversion \ + -system-pcre \ + -system-zlib \ + $(if $(findstring i386,$(ARCH)),-no-sse2 -no-sse4.1) \ + -no-angle \ + -no-cups \ + -no-dbus \ + -no-directfb \ + -no-dtls\ + -no-egl \ + -no-eglfs \ + -no-freetype \ + -no-gbm \ + -no-glib \ + -no-gtk \ + -no-gui \ + -no-harfbuzz \ + -no-iconv \ + -no-icu \ + -no-kms \ + -no-libjpeg \ + -no-libmd4c \ + -no-libpng \ + -no-libudev \ + -no-mtdev \ + -no-opengl \ + -no-opengles3 \ + -no-openvg \ + -no-pch \ + -no-slog2 \ + -sql-sqlite \ + -no-trace \ + -no-tslib \ + -no-vulkan \ + -no-widgets \ + -no-xcb \ + -no-xkbcommon \ + -no-zstd \ + -no-compile-examples \ + -no-feature-concurrent \ + -no-feature-gssapi \ + -no-feature-testlib \ + -make libs \ + -nomake examples \ + -nomake tests \ + -nomake tools \ + -v + + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) +endef + +define Build/InstallDev + $(MAKE) -C $(PKG_BUILD_DIR) install +endef + +define Package/qtbase/Default/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/lib/libQt5$(shell echo $(2) | sed -e 's/\b[[:alpha:]]/\u&/g').so* $(1)/usr/lib +endef + +define DefineQtbaseLibrary + QTBASE_DEPENDS+=+qt5-$(1) + + QTBASE_LIBS+=$(1) + + define Package/qt5-$(1) + $(call Package/qtbase/Default) + TITLE+=$(1) + DEPENDS+=$(foreach lib,$(2),+qt5-$(lib)) $(3) + HIDDEN:=1 + endef + + define Package/qt5-$(1)/description + This package contains the qt5 $(1) library. + endef + + define Package/qt5-$(1)/install + $(call Package/qtbase/Default/install,$$(1),$(1)) + endef +endef + +$(eval $(call DefineQtbaseLibrary,core,,+QT5_INCLUDE_ATOMIC:libatomic +libpcre2-16 +zlib)) +$(eval $(call DefineQtbaseLibrary,network,core,+libopenssl +zlib)) +$(eval $(call DefineQtbaseLibrary,xml,core,)) +$(eval $(call DefineQtbaseLibrary,sql,core)) + +$(foreach lib,$(QTBASE_LIBS),$(eval $(call BuildPackage,qt5-$(lib)))) +$(eval $(call BuildPackage,qtbase)) diff --git a/qttools/Makefile b/qttools/Makefile new file mode 100644 index 000000000..4c31318dd --- /dev/null +++ b/qttools/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:=qttools +PKG_BASE:=5.15 +PKG_BUGFIX:=6 +PKG_VERSION:=$(PKG_BASE).$(PKG_BUGFIX) +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-everywhere-opensource-src-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:= \ + http://master.qt.io/archive/qt/$(PKG_BASE)/$(PKG_VERSION)/submodules \ + http://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/$(PKG_BASE)/$(PKG_VERSION)/submodules \ + http://qt.mirror.constant.com/archive/qt/$(PKG_BASE)/$(PKG_VERSION)/submodules +PKG_HASH:=2c1486ab7e6dad76fb34642cd4f91d533e5dfeec0ee527129c2c2ed4ab283c3b + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-everywhere-src-$(PKG_VERSION) + +PKG_BUILD_PARALLEL:=1 +PKG_BUILD_DEPENDS:=qtbase + +include $(INCLUDE_DIR)/package.mk + +define Package/qttools + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Qt5 + TITLE:=qttools + URL:=http://qt-project.org + BUILDONLY:=1 +endef + +define Build/Configure + cd $(PKG_BUILD_DIR) && qmake -o Makefile qttools.pro +endef + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) +endef + +define Build/InstallDev + $(MAKE) -C $(PKG_BUILD_DIR) install +endef + +$(eval $(call BuildPackage,qttools)) diff --git a/rblibtorrent/Makefile b/rblibtorrent/Makefile new file mode 100644 index 000000000..252328f7f --- /dev/null +++ b/rblibtorrent/Makefile @@ -0,0 +1,62 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=rblibtorrent +PKG_VERSION:=1.2.17 +PKG_RELEASE=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/arvidn/libtorrent.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=2d34455ad2b828d3da23634f7de93fafded5442d +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_MIRROR_HASH:=3fa86163d370584f747d34737a556a5426fd5eb4ce1ba1dc594dce3357594d90 + +PKG_LICENSE:=BSD +PKG_LICENSE_FILES:=COPYING + +PKG_USE_MIPS16:=0 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/rblibtorrent + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Rasterbar BitTorrent library + URL:=https://www.libtorrent.org/ + DEPENDS:=+libgcc +libstdcpp +libopenssl +boost +boost-system +boost-chrono +boost-random +libatomic + MAINTAINER:=Arvid Norberg +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 += $(if $(CONFIG_SOFT_FLOAT),-DBOOST_NO_FENV_H) -fPIC -ffunction-sections -fdata-sections -flto +EXTRA_CXXFLAGS += $(if $(CONFIG_GCC_VERSION_4_8),-std=gnu++11,-std=gnu++17) +TARGET_LDFLAGS += -lstdc++ -Wl,--gc-sections,--as-needed -flto + +CMAKE_OPTIONS += \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_STANDARD=17 \ + -DBUILD_SHARED_LIBS=ON \ + -Ddeprecated-functions=ON \ + -Dencryption=ON \ + -Diconv=ON \ + -Dstatic_runtime=ON \ + -Dlogging=OFF + +define Build/InstallDev + $(INSTALL_DIR) $(1) + $(CP) $(PKG_INSTALL_DIR)/* $(1) +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/tcpping/Makefile b/tcpping/Makefile new file mode 100644 index 000000000..3ac81e5c8 --- /dev/null +++ b/tcpping/Makefile @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tcpping +PKG_VERSION:=0.2 +PKG_RELEASE=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/coolsnowwolf/tcping +PKG_SOURCE_DATE:=2020-09-19 +PKG_SOURCE_VERSION:=d890cc1bd8e3951390ceeff1ccb092a5d802850c +PKG_MIRROR_HASH:=018554a80e8a9d8fedd39821f35aa02c7c763fd42213761fba9b21c2533e1ab8 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/tcpping + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libnet-1.2.x +libpcap + TITLE:=TCP Ping Tool +endef + +define Package/tcpping/description + Ping look-alike that uses TCP SYN packets to + get around firewalls and ICMP blackholes. +endef + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/lib/libnet-1.2.x/include -L$(STAGING_DIR)/usr/lib/libnet-1.2.x/lib" \ + INSTALL_PROG=":" +endef + +define Package/tcpping/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/tcpping $(1)/usr/bin/tcpping +endef + +$(eval $(call BuildPackage,tcpping)) diff --git a/uugamebooster/Makefile b/uugamebooster/Makefile new file mode 100644 index 000000000..57ae3cc8e --- /dev/null +++ b/uugamebooster/Makefile @@ -0,0 +1,85 @@ +# +# Copyright (C) 2021 KFERMercer +# +# This is free software, licensed under the GNU General Public License v3. +# + +# +# to get the latest version & md5 checksum: +# curl -L -s -k -H "Accept:text/plain" "http://router.uu.163.com/api/plugin?type=openwrt-$(UU_ARCH)" +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=uugamebooster +PKG_VERSION:=v3.6.2 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +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 + +ifeq ($(ARCH),arm) + UU_ARCH:=arm + PKG_MD5SUM:=ee720928879208091c509c685f21db05 +endif + +ifeq ($(ARCH),aarch64) + UU_ARCH:=aarch64 + PKG_MD5SUM:=279ec2a24f2765669aee8f57cb47e30d +endif + +ifeq ($(ARCH),mipsel) + UU_ARCH:=mipsel + PKG_MD5SUM:=d2176e47a783e0be9bbecbceb606470b +endif + +ifeq ($(ARCH),x86_64) + UU_ARCH:=x86_64 + PKG_MD5SUM:=3656d9cedbe369be7adc059248a9d4bd +endif + +PKG_SOURCE_URL:=https://uu.gdl.netease.com/uuplugin/openwrt-$(UU_ARCH)/$(PKG_VERSION)/uu.tar.gz? +PKG_SOURCE:=$(PKG_NAME)-$(UU_ARCH)-$(PKG_VERSION).tar.gz + +STRIP:=true + +UNTAR_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/$(PKG_NAME)-$(UU_ARCH)-bin + +define Build/Prepare + mkdir -vp $(UNTAR_DIR) + tar -zxvf $(DL_DIR)/$(PKG_SOURCE) -C $(UNTAR_DIR) +endef + +define Build/Compile +endef + +define Package/uugamebooster/conffiles +/root/.uuplugin_uuid +endef + +define Package/uugamebooster/install + # $(INSTALL_DIR) $(1)/etc/init.d + # $(INSTALL_BIN) ./files/uugamebooster.init $(1)/etc/init.d/uuplugin + + $(INSTALL_DIR) $(1)/usr/share/uugamebooster + $(INSTALL_BIN) $(UNTAR_DIR)/uuplugin $(1)/usr/share/uugamebooster/uuplugin + $(INSTALL_CONF) $(UNTAR_DIR)/uu.conf $(1)/usr/share/uugamebooster/uu.conf + + # not finish yet: + # $(INSTALL_DIR) $(1)/usr/bin + # $(INSTALL_BIN) ./files/uugamebooster-update $(1)/usr/bin/uugamebooster + # $(LN) $(1)/usr/bin/uugamebooster/uugamebooster-update $(1)/usr/bin/uugamebooster-update +endef + +$(eval $(call BuildPackage,uugamebooster)) diff --git a/uugamebooster/files/uugamebooster-update b/uugamebooster/files/uugamebooster-update new file mode 100755 index 000000000..8e0780588 --- /dev/null +++ b/uugamebooster/files/uugamebooster-update @@ -0,0 +1,18 @@ +#!/bin/sh + +# Return: 0 means update flag is set. +check_update() { + if [ -f "/usr/bin/uugamebooster/uu.update" ];then + return 0 + else + return 1 + fi +} + +check_update +if [ "$?" != "0" ];then + exit 0 + return +fi + +exit 0 diff --git a/verysync/Makefile b/verysync/Makefile index 202f0bad7..73cb575b8 100644 --- a/verysync/Makefile +++ b/verysync/Makefile @@ -1,68 +1,58 @@ +# SPDX-Identifier-License: GPL-3.0-only # -# Copyright (C) 2015-2016 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v3. -# +# Copyright (C) 2021 ImmortalWrt.org include $(TOPDIR)/rules.mk -ifeq ($(ARCH),x86_64) - PKG_ARCH_VERYSYNC:=amd64 -endif -ifeq ($(ARCH),mipsel) - PKG_ARCH_VERYSYNC:=mipsle -endif -ifeq ($(ARCH),mips) - PKG_ARCH_VERYSYNC:=mips -endif -ifeq ($(ARCH),i386) - PKG_ARCH_VERYSYNC:=386 -endif -ifeq ($(ARCH),arm) - PKG_ARCH_VERYSYNC:=arm -endif ifeq ($(ARCH),aarch64) - PKG_ARCH_VERYSYNC:=arm64 -endif -ifeq ($(ARCH),powerpc64) - PKG_ARCH_VERYSYNC:=ppc64 + PKG_ARCH_VERYSYNC:=arm64 + PKG_HASH_VERYSYNC:=113b1098434c9657e51d95a86f70436ff55db291cca1094bc65e911642424367 +else ifeq ($(ARCH),arm) + PKG_ARCH_VERYSYNC:=arm + PKG_HASH_VERYSYNC:=6eb2a8e41dcdaacfecc20c13ef6b7805176dad6a410d38bf65a962bc0f7f8554 +else ifeq ($(ARCH),i386) + PKG_ARCH_VERYSYNC:=386 + PKG_HASH_VERYSYNC:=d84b71cc7ef0db95bf0f6dc3d38884b3856cc36ae1ac1f430c35cdd033cc7c16 +else ifeq ($(ARCH),mips) + PKG_ARCH_VERYSYNC:=mips + PKG_HASH_VERYSYNC:=54d8fe303e3b51ae5078fe74e69ab64d102334e55ee257d9eec7aef13a21d911 +else ifeq ($(ARCH),mipsel) + PKG_ARCH_VERYSYNC:=mipsle + PKG_HASH_VERYSYNC:=7edc4eae4a1941d8a52fce2506d599af6f207498a3d8cabe819f023d0df15e2f +else ifeq ($(ARCH),powerpc64) + PKG_ARCH_VERYSYNC:=ppc64 + PKG_HASH_VERYSYNC:=c89e670b31123b240fc5e4be15cb7e836e8584b5a955efea5fca5b4f9d009ea1 +else ifeq ($(ARCH),x86_64) + PKG_ARCH_VERYSYNC:=amd64 + PKG_HASH_VERYSYNC:=6214cd485bfc40a8c53a3c53e900a0fa2e629d5137345f3ad2195bd9e0f47fba endif PKG_NAME:=verysync -PKG_VERSION:=v2.13.2 -PKG_RELEASE:=1 -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE:=$(PKG_NAME)-linux-$(PKG_ARCH_VERYSYNC)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=http://dl.verysync.com/releases/$(PKG_VERSION)/ -PKG_HASH:=skip +PKG_VERSION:=2.14.0 +PKG_RELEASE:=$(AUTORELEASE) + +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/$(PKG_NAME) - SECTION:=net - CATEGORY:=Network - TITLE:=A efficient data transmission tool - DEPENDS:= - URL:=http://www.verysync.com -endef - -define Package/$(PKG_NAME)/description - Verysync is a efficient data transmission tool. -endef - -define Build/Prepare - tar -xzvf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) -endef - -define Build/Configure +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) endef define Build/Compile endef -define Package/$(PKG_NAME)/install +define Package/verysync/install $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME)-linux-$(PKG_ARCH_VERYSYNC)-$(PKG_VERSION)/verysync $(1)/usr/bin/verysync + $(INSTALL_BIN) $(PKG_BUILD_DIR)/verysync $(1)/usr/bin/verysync endef -$(eval $(call BuildPackage,$(PKG_NAME))) +$(eval $(call BuildPackage,verysync))